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