1 /* msr tests */ 2 3 #include "libcflat.h" 4 #include "processor.h" 5 6 struct msr_info { 7 int index; 8 char *name; 9 struct tc { 10 int valid; 11 unsigned long long value; 12 unsigned long long expected; 13 } val_pairs[20]; 14 }; 15 16 17 #define addr_64 0x0000123456789abcULL 18 19 struct msr_info msr_info[] = 20 { 21 { .index = 0x0000001b, .name = "MSR_IA32_APICBASE", 22 .val_pairs = { 23 { .valid = 1, .value = 0x0000000056789900, .expected = 0x0000000056789900}, 24 { .valid = 1, .value = 0x0000000056789D01, .expected = 0x0000000056789D01}, 25 } 26 }, 27 { .index = 0x00000174, .name = "IA32_SYSENTER_CS", 28 .val_pairs = {{ .valid = 1, .value = 0x1234, .expected = 0x1234}} 29 }, 30 { .index = 0x00000175, .name = "MSR_IA32_SYSENTER_ESP", 31 .val_pairs = {{ .valid = 1, .value = addr_64, .expected = addr_64}} 32 }, 33 { .index = 0x00000176, .name = "IA32_SYSENTER_EIP", 34 .val_pairs = {{ .valid = 1, .value = addr_64, .expected = addr_64}} 35 }, 36 { .index = 0x000001a0, .name = "MSR_IA32_MISC_ENABLE", 37 // reserved: 1:2, 4:6, 8:10, 13:15, 17, 19:21, 24:33, 35:63 38 .val_pairs = {{ .valid = 1, .value = 0x400c51889, .expected = 0x400c51889}} 39 }, 40 { .index = 0x00000277, .name = "MSR_IA32_CR_PAT", 41 .val_pairs = {{ .valid = 1, .value = 0x07070707, .expected = 0x07070707}} 42 }, 43 { .index = 0xc0000100, .name = "MSR_FS_BASE", 44 .val_pairs = {{ .valid = 1, .value = addr_64, .expected = addr_64}} 45 }, 46 { .index = 0xc0000101, .name = "MSR_GS_BASE", 47 .val_pairs = {{ .valid = 1, .value = addr_64, .expected = addr_64}} 48 }, 49 { .index = 0xc0000102, .name = "MSR_KERNEL_GS_BASE", 50 .val_pairs = {{ .valid = 1, .value = addr_64, .expected = addr_64}} 51 }, 52 #ifdef __x86_64__ 53 { .index = 0xc0000080, .name = "MSR_EFER", 54 .val_pairs = {{ .valid = 1, .value = 0xD00, .expected = 0xD00}} 55 }, 56 #endif 57 { .index = 0xc0000082, .name = "MSR_LSTAR", 58 .val_pairs = {{ .valid = 1, .value = addr_64, .expected = addr_64}} 59 }, 60 { .index = 0xc0000083, .name = "MSR_CSTAR", 61 .val_pairs = {{ .valid = 1, .value = addr_64, .expected = addr_64}} 62 }, 63 { .index = 0xc0000084, .name = "MSR_SYSCALL_MASK", 64 .val_pairs = {{ .valid = 1, .value = 0xffffffff, .expected = 0xffffffff}} 65 }, 66 67 // MSR_IA32_DEBUGCTLMSR needs svm feature LBRV 68 // MSR_VM_HSAVE_PA only AMD host 69 }; 70 71 static int find_msr_info(int msr_index) 72 { 73 int i; 74 for (i = 0; i < sizeof(msr_info)/sizeof(msr_info[0]) ; i++) { 75 if (msr_info[i].index == msr_index) { 76 return i; 77 } 78 } 79 return -1; 80 } 81 82 83 int nr_passed, nr_tests; 84 85 static void report(const char *name, int passed) 86 { 87 ++nr_tests; 88 if (passed) 89 ++nr_passed; 90 printf("%s: %s\n", name, passed ? "PASS" : "FAIL"); 91 } 92 93 static void test_msr_rw(int msr_index, unsigned long long input, unsigned long long expected) 94 { 95 unsigned long long r = 0; 96 int index; 97 char *sptr; 98 if ((index = find_msr_info(msr_index)) != -1) { 99 sptr = msr_info[index].name; 100 } else { 101 printf("couldn't find name for msr # 0x%x, skipping\n", msr_index); 102 return; 103 } 104 wrmsr(msr_index, input); 105 r = rdmsr(msr_index); 106 if (expected != r) { 107 printf("testing %s: output = 0x%x:0x%x expected = 0x%x:0x%x\n", sptr, r >> 32, r, expected >> 32, expected); 108 } 109 report(sptr, expected == r); 110 } 111 112 int main(int ac, char **av) 113 { 114 int i, j; 115 for (i = 0 ; i < sizeof(msr_info) / sizeof(msr_info[0]); i++) { 116 for (j = 0; j < sizeof(msr_info[i].val_pairs) / sizeof(msr_info[i].val_pairs[0]); j++) { 117 if (msr_info[i].val_pairs[j].valid) { 118 test_msr_rw(msr_info[i].index, msr_info[i].val_pairs[j].value, msr_info[i].val_pairs[j].expected); 119 } else { 120 break; 121 } 122 } 123 } 124 125 printf("%d tests, %d failures\n", nr_tests, nr_tests - nr_passed); 126 127 return nr_passed == nr_tests ? 0 : 1; 128 } 129 130