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; 97d36db35SAvi Kivity 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 197d36db35SAvi Kivity 207d36db35SAvi Kivity struct msr_info msr_info[] = 217d36db35SAvi Kivity { 227d36db35SAvi Kivity { .index = 0x0000001b, .name = "MSR_IA32_APICBASE", 237d36db35SAvi Kivity .val_pairs = { 247d36db35SAvi Kivity { .valid = 1, .value = 0x0000000056789900, .expected = 0x0000000056789900}, 257d36db35SAvi Kivity { .valid = 1, .value = 0x0000000056789D01, .expected = 0x0000000056789D01}, 267d36db35SAvi Kivity } 277d36db35SAvi Kivity }, 287d36db35SAvi Kivity { .index = 0x00000174, .name = "IA32_SYSENTER_CS", 297d36db35SAvi Kivity .val_pairs = {{ .valid = 1, .value = 0x1234, .expected = 0x1234}} 307d36db35SAvi Kivity }, 317d36db35SAvi Kivity { .index = 0x00000175, .name = "MSR_IA32_SYSENTER_ESP", 327d36db35SAvi Kivity .val_pairs = {{ .valid = 1, .value = addr_64, .expected = addr_64}} 337d36db35SAvi Kivity }, 347d36db35SAvi Kivity { .index = 0x00000176, .name = "IA32_SYSENTER_EIP", 357d36db35SAvi Kivity .val_pairs = {{ .valid = 1, .value = addr_64, .expected = addr_64}} 367d36db35SAvi Kivity }, 377d36db35SAvi Kivity { .index = 0x000001a0, .name = "MSR_IA32_MISC_ENABLE", 387d36db35SAvi Kivity // reserved: 1:2, 4:6, 8:10, 13:15, 17, 19:21, 24:33, 35:63 397d36db35SAvi Kivity .val_pairs = {{ .valid = 1, .value = 0x400c51889, .expected = 0x400c51889}} 407d36db35SAvi Kivity }, 417d36db35SAvi Kivity { .index = 0x00000277, .name = "MSR_IA32_CR_PAT", 427d36db35SAvi Kivity .val_pairs = {{ .valid = 1, .value = 0x07070707, .expected = 0x07070707}} 437d36db35SAvi Kivity }, 447d36db35SAvi Kivity { .index = 0xc0000100, .name = "MSR_FS_BASE", 457d36db35SAvi Kivity .val_pairs = {{ .valid = 1, .value = addr_64, .expected = addr_64}} 467d36db35SAvi Kivity }, 477d36db35SAvi Kivity { .index = 0xc0000101, .name = "MSR_GS_BASE", 487d36db35SAvi Kivity .val_pairs = {{ .valid = 1, .value = addr_64, .expected = addr_64}} 497d36db35SAvi Kivity }, 507d36db35SAvi Kivity { .index = 0xc0000102, .name = "MSR_KERNEL_GS_BASE", 517d36db35SAvi Kivity .val_pairs = {{ .valid = 1, .value = addr_64, .expected = addr_64}} 527d36db35SAvi Kivity }, 531389b749SJason Wang #ifdef __x86_64__ 547d36db35SAvi Kivity { .index = 0xc0000080, .name = "MSR_EFER", 557d36db35SAvi Kivity .val_pairs = {{ .valid = 1, .value = 0xD00, .expected = 0xD00}} 567d36db35SAvi Kivity }, 571389b749SJason Wang #endif 587d36db35SAvi Kivity { .index = 0xc0000082, .name = "MSR_LSTAR", 597d36db35SAvi Kivity .val_pairs = {{ .valid = 1, .value = addr_64, .expected = addr_64}} 607d36db35SAvi Kivity }, 617d36db35SAvi Kivity { .index = 0xc0000083, .name = "MSR_CSTAR", 627d36db35SAvi Kivity .val_pairs = {{ .valid = 1, .value = addr_64, .expected = addr_64}} 637d36db35SAvi Kivity }, 647d36db35SAvi Kivity { .index = 0xc0000084, .name = "MSR_SYSCALL_MASK", 657d36db35SAvi Kivity .val_pairs = {{ .valid = 1, .value = 0xffffffff, .expected = 0xffffffff}} 667d36db35SAvi Kivity }, 677d36db35SAvi Kivity 687d36db35SAvi Kivity // MSR_IA32_DEBUGCTLMSR needs svm feature LBRV 697d36db35SAvi Kivity // MSR_VM_HSAVE_PA only AMD host 707d36db35SAvi Kivity }; 717d36db35SAvi Kivity 727d36db35SAvi Kivity static int find_msr_info(int msr_index) 737d36db35SAvi Kivity { 747d36db35SAvi Kivity int i; 757d36db35SAvi Kivity for (i = 0; i < sizeof(msr_info)/sizeof(msr_info[0]) ; i++) { 767d36db35SAvi Kivity if (msr_info[i].index == msr_index) { 777d36db35SAvi Kivity return i; 787d36db35SAvi Kivity } 797d36db35SAvi Kivity } 807d36db35SAvi Kivity return -1; 817d36db35SAvi Kivity } 827d36db35SAvi Kivity 837d36db35SAvi Kivity 847d36db35SAvi Kivity int nr_passed, nr_tests; 857d36db35SAvi Kivity 867d36db35SAvi Kivity static void report(const char *name, int passed) 877d36db35SAvi Kivity { 887d36db35SAvi Kivity ++nr_tests; 897d36db35SAvi Kivity if (passed) 907d36db35SAvi Kivity ++nr_passed; 917d36db35SAvi Kivity printf("%s: %s\n", name, passed ? "PASS" : "FAIL"); 927d36db35SAvi Kivity } 937d36db35SAvi Kivity 947d36db35SAvi Kivity static void test_msr_rw(int msr_index, unsigned long long input, unsigned long long expected) 957d36db35SAvi Kivity { 967d36db35SAvi Kivity unsigned long long r = 0; 977d36db35SAvi Kivity int index; 987d36db35SAvi Kivity char *sptr; 997d36db35SAvi Kivity if ((index = find_msr_info(msr_index)) != -1) { 1007d36db35SAvi Kivity sptr = msr_info[index].name; 1017d36db35SAvi Kivity } else { 1027d36db35SAvi Kivity printf("couldn't find name for msr # 0x%x, skipping\n", msr_index); 1037d36db35SAvi Kivity return; 1047d36db35SAvi Kivity } 1057d36db35SAvi Kivity wrmsr(msr_index, input); 1067d36db35SAvi Kivity r = rdmsr(msr_index); 1077d36db35SAvi Kivity if (expected != r) { 1087d36db35SAvi Kivity printf("testing %s: output = 0x%x:0x%x expected = 0x%x:0x%x\n", sptr, r >> 32, r, expected >> 32, expected); 1097d36db35SAvi Kivity } 1107d36db35SAvi Kivity report(sptr, expected == r); 1117d36db35SAvi Kivity } 1127d36db35SAvi Kivity 113d1bdd07cSAvi Kivity static void test_syscall_lazy_load(void) 114d1bdd07cSAvi Kivity { 115*d3db85a3SMichael S. Tsirkin #ifdef __x86_64__ 116d1bdd07cSAvi Kivity extern void syscall_target(); 117d1bdd07cSAvi Kivity u16 cs = read_cs(), ss = read_ss(); 118d1bdd07cSAvi Kivity ulong tmp; 119d1bdd07cSAvi Kivity 120d1bdd07cSAvi Kivity wrmsr(MSR_EFER, rdmsr(MSR_EFER) | EFER_SCE); 121d1bdd07cSAvi Kivity wrmsr(MSR_LSTAR, (ulong)syscall_target); 122d1bdd07cSAvi Kivity wrmsr(MSR_STAR, (uint64_t)cs << 32); 123d1bdd07cSAvi Kivity asm volatile("pushf; syscall; syscall_target: popf" : "=c"(tmp) : : "r11"); 124d1bdd07cSAvi Kivity write_ss(ss); 125d1bdd07cSAvi Kivity // will crash horribly if broken 126d1bdd07cSAvi Kivity report("MSR_*STAR eager loading", true); 127*d3db85a3SMichael S. Tsirkin #endif 128d1bdd07cSAvi Kivity } 129d1bdd07cSAvi Kivity 1307d36db35SAvi Kivity int main(int ac, char **av) 1317d36db35SAvi Kivity { 1327d36db35SAvi Kivity int i, j; 1337d36db35SAvi Kivity for (i = 0 ; i < sizeof(msr_info) / sizeof(msr_info[0]); i++) { 1347d36db35SAvi Kivity for (j = 0; j < sizeof(msr_info[i].val_pairs) / sizeof(msr_info[i].val_pairs[0]); j++) { 1357d36db35SAvi Kivity if (msr_info[i].val_pairs[j].valid) { 1367d36db35SAvi Kivity test_msr_rw(msr_info[i].index, msr_info[i].val_pairs[j].value, msr_info[i].val_pairs[j].expected); 1377d36db35SAvi Kivity } else { 1387d36db35SAvi Kivity break; 1397d36db35SAvi Kivity } 1407d36db35SAvi Kivity } 1417d36db35SAvi Kivity } 1427d36db35SAvi Kivity 143d1bdd07cSAvi Kivity test_syscall_lazy_load(); 144d1bdd07cSAvi Kivity 1457d36db35SAvi Kivity printf("%d tests, %d failures\n", nr_tests, nr_tests - nr_passed); 1467d36db35SAvi Kivity 1477d36db35SAvi Kivity return nr_passed == nr_tests ? 0 : 1; 1487d36db35SAvi Kivity } 1497d36db35SAvi Kivity 150