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