17d36db35SAvi Kivity /* msr tests */ 27d36db35SAvi Kivity 37d36db35SAvi Kivity #include "libcflat.h" 4850479e3SJason Wang #include "processor.h" 5d1bdd07cSAvi Kivity #include "msr.h" 67d36db35SAvi Kivity 77d36db35SAvi Kivity struct msr_info { 87d36db35SAvi Kivity int index; 9797d79a2SThomas Huth const char *name; 107d36db35SAvi Kivity struct tc { 117d36db35SAvi Kivity int valid; 127d36db35SAvi Kivity unsigned long long value; 137d36db35SAvi Kivity unsigned long long expected; 147d36db35SAvi Kivity } val_pairs[20]; 157d36db35SAvi Kivity }; 167d36db35SAvi Kivity 177d36db35SAvi Kivity 187d36db35SAvi Kivity #define addr_64 0x0000123456789abcULL 198feb8cfbSSean Christopherson #define addr_ul (unsigned long)addr_64 207d36db35SAvi Kivity 217d36db35SAvi Kivity struct msr_info msr_info[] = 227d36db35SAvi Kivity { 238ca534cdSSean Christopherson { .index = MSR_IA32_SYSENTER_CS, .name = "MSR_IA32_SYSENTER_CS", 24*9295327cSSean Christopherson .val_pairs = {{ .valid = 1, .value = 0x1234 }} 257d36db35SAvi Kivity }, 268ca534cdSSean Christopherson { .index = MSR_IA32_SYSENTER_ESP, .name = "MSR_IA32_SYSENTER_ESP", 27*9295327cSSean Christopherson .val_pairs = {{ .valid = 1, .value = addr_ul }} 287d36db35SAvi Kivity }, 298ca534cdSSean Christopherson { .index = MSR_IA32_SYSENTER_EIP, .name = "MSR_IA32_SYSENTER_EIP", 30*9295327cSSean Christopherson .val_pairs = {{ .valid = 1, .value = addr_ul }} 317d36db35SAvi Kivity }, 328ca534cdSSean Christopherson { .index = MSR_IA32_MISC_ENABLE, .name = "MSR_IA32_MISC_ENABLE", 337d36db35SAvi Kivity // reserved: 1:2, 4:6, 8:10, 13:15, 17, 19:21, 24:33, 35:63 34*9295327cSSean Christopherson .val_pairs = {{ .valid = 1, .value = 0x400c51889 }} 357d36db35SAvi Kivity }, 368ca534cdSSean Christopherson { .index = MSR_IA32_CR_PAT, .name = "MSR_IA32_CR_PAT", 37*9295327cSSean Christopherson .val_pairs = {{ .valid = 1, .value = 0x07070707 }} 387d36db35SAvi Kivity }, 392ac205f8SSean Christopherson #ifdef __x86_64__ 408ca534cdSSean Christopherson { .index = MSR_FS_BASE, .name = "MSR_FS_BASE", 41*9295327cSSean Christopherson .val_pairs = {{ .valid = 1, .value = addr_64 }} 427d36db35SAvi Kivity }, 438ca534cdSSean Christopherson { .index = MSR_GS_BASE, .name = "MSR_GS_BASE", 44*9295327cSSean Christopherson .val_pairs = {{ .valid = 1, .value = addr_64 }} 457d36db35SAvi Kivity }, 468ca534cdSSean Christopherson { .index = MSR_KERNEL_GS_BASE, .name = "MSR_KERNEL_GS_BASE", 47*9295327cSSean Christopherson .val_pairs = {{ .valid = 1, .value = addr_64 }} 487d36db35SAvi Kivity }, 498ca534cdSSean Christopherson { .index = MSR_EFER, .name = "MSR_EFER", 50*9295327cSSean Christopherson .val_pairs = {{ .valid = 1, .value = 0xD00 }} 517d36db35SAvi Kivity }, 528ca534cdSSean Christopherson { .index = MSR_LSTAR, .name = "MSR_LSTAR", 53*9295327cSSean Christopherson .val_pairs = {{ .valid = 1, .value = addr_64 }} 547d36db35SAvi Kivity }, 558ca534cdSSean Christopherson { .index = MSR_CSTAR, .name = "MSR_CSTAR", 56*9295327cSSean Christopherson .val_pairs = {{ .valid = 1, .value = addr_64 }} 577d36db35SAvi Kivity }, 588ca534cdSSean Christopherson { .index = MSR_SYSCALL_MASK, .name = "MSR_SYSCALL_MASK", 59*9295327cSSean Christopherson .val_pairs = {{ .valid = 1, .value = 0xffffffff }} 607d36db35SAvi Kivity }, 61ff2525d7SSean Christopherson #endif 627d36db35SAvi Kivity 637d36db35SAvi Kivity // MSR_IA32_DEBUGCTLMSR needs svm feature LBRV 647d36db35SAvi Kivity // MSR_VM_HSAVE_PA only AMD host 657d36db35SAvi Kivity }; 667d36db35SAvi Kivity 677d36db35SAvi Kivity static int find_msr_info(int msr_index) 687d36db35SAvi Kivity { 697d36db35SAvi Kivity int i; 7050273266SSean Christopherson 717d36db35SAvi Kivity for (i = 0; i < sizeof(msr_info)/sizeof(msr_info[0]) ; i++) { 7250273266SSean Christopherson if (msr_info[i].index == msr_index) 737d36db35SAvi Kivity return i; 747d36db35SAvi Kivity } 757d36db35SAvi Kivity return -1; 767d36db35SAvi Kivity } 777d36db35SAvi Kivity 78*9295327cSSean Christopherson static void test_msr_rw(int msr_index, unsigned long long val) 797d36db35SAvi Kivity { 80a73d6ae4SSean Christopherson unsigned long long r, orig; 817d36db35SAvi Kivity int index; 82797d79a2SThomas Huth const char *sptr; 8350273266SSean Christopherson 847d36db35SAvi Kivity if ((index = find_msr_info(msr_index)) != -1) { 857d36db35SAvi Kivity sptr = msr_info[index].name; 867d36db35SAvi Kivity } else { 87fd6aada0SRadim Krčmář printf("couldn't find name for msr # %#x, skipping\n", msr_index); 887d36db35SAvi Kivity return; 897d36db35SAvi Kivity } 90*9295327cSSean Christopherson 91a73d6ae4SSean Christopherson orig = rdmsr(msr_index); 92*9295327cSSean Christopherson wrmsr(msr_index, val); 937d36db35SAvi Kivity r = rdmsr(msr_index); 94a73d6ae4SSean Christopherson wrmsr(msr_index, orig); 95*9295327cSSean Christopherson if (r != val) { 96d26193a0SRoman Bolshakov printf("testing %s: output = %#" PRIx32 ":%#" PRIx32 97d26193a0SRoman Bolshakov " expected = %#" PRIx32 ":%#" PRIx32 "\n", sptr, 98*9295327cSSean Christopherson (u32)(r >> 32), (u32)r, (u32)(val >> 32), (u32)val); 997d36db35SAvi Kivity } 100*9295327cSSean Christopherson report(val == r, "%s", sptr); 1017d36db35SAvi Kivity } 1027d36db35SAvi Kivity 1037d36db35SAvi Kivity int main(int ac, char **av) 1047d36db35SAvi Kivity { 1057d36db35SAvi Kivity int i, j; 106e7054ad1SSean Christopherson for (i = 0 ; i < ARRAY_SIZE(msr_info); i++) { 107e7054ad1SSean Christopherson for (j = 0; j < ARRAY_SIZE(msr_info[i].val_pairs); j++) { 1087d36db35SAvi Kivity if (msr_info[i].val_pairs[j].valid) { 109*9295327cSSean Christopherson test_msr_rw(msr_info[i].index, msr_info[i].val_pairs[j].value); 1107d36db35SAvi Kivity } else { 1117d36db35SAvi Kivity break; 1127d36db35SAvi Kivity } 1137d36db35SAvi Kivity } 1147d36db35SAvi Kivity } 1157d36db35SAvi Kivity 116f3cdd159SJan Kiszka return report_summary(); 1177d36db35SAvi Kivity } 118