xref: /kvm-unit-tests/x86/msr.c (revision 9295327c32a986af62ee6cdb3da5844abfbe5acd)
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