xref: /kvm-unit-tests/x86/msr.c (revision 50273266f8b5a09bd718a72b58c22cfeef7554d3)
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 {
237d36db35SAvi Kivity 	{ .index = 0x00000174, .name = "IA32_SYSENTER_CS",
247d36db35SAvi Kivity 	  .val_pairs = {{ .valid = 1, .value = 0x1234, .expected = 0x1234}}
257d36db35SAvi Kivity 	},
267d36db35SAvi Kivity 	{ .index = 0x00000175, .name = "MSR_IA32_SYSENTER_ESP",
278feb8cfbSSean Christopherson 	  .val_pairs = {{ .valid = 1, .value = addr_ul, .expected = addr_ul}}
287d36db35SAvi Kivity 	},
297d36db35SAvi Kivity 	{ .index = 0x00000176, .name = "IA32_SYSENTER_EIP",
308feb8cfbSSean Christopherson 	  .val_pairs = {{ .valid = 1, .value = addr_ul, .expected = addr_ul}}
317d36db35SAvi Kivity 	},
327d36db35SAvi Kivity 	{ .index = 0x000001a0, .name = "MSR_IA32_MISC_ENABLE",
337d36db35SAvi Kivity 	  // reserved: 1:2, 4:6, 8:10, 13:15, 17, 19:21, 24:33, 35:63
347d36db35SAvi Kivity 	  .val_pairs = {{ .valid = 1, .value = 0x400c51889, .expected = 0x400c51889}}
357d36db35SAvi Kivity 	},
367d36db35SAvi Kivity 	{ .index = 0x00000277, .name = "MSR_IA32_CR_PAT",
377d36db35SAvi Kivity 	  .val_pairs = {{ .valid = 1, .value = 0x07070707, .expected = 0x07070707}}
387d36db35SAvi Kivity 	},
392ac205f8SSean Christopherson #ifdef __x86_64__
407d36db35SAvi Kivity 	{ .index = 0xc0000100, .name = "MSR_FS_BASE",
417d36db35SAvi Kivity 	  .val_pairs = {{ .valid = 1, .value = addr_64, .expected = addr_64}}
427d36db35SAvi Kivity 	},
437d36db35SAvi Kivity 	{ .index = 0xc0000101, .name = "MSR_GS_BASE",
447d36db35SAvi Kivity 	  .val_pairs = {{ .valid = 1, .value = addr_64, .expected = addr_64}}
457d36db35SAvi Kivity 	},
467d36db35SAvi Kivity 	{ .index = 0xc0000102, .name = "MSR_KERNEL_GS_BASE",
477d36db35SAvi Kivity 	  .val_pairs = {{ .valid = 1, .value = addr_64, .expected = addr_64}}
487d36db35SAvi Kivity 	},
497d36db35SAvi Kivity 	{ .index = 0xc0000080, .name = "MSR_EFER",
507d36db35SAvi Kivity 	  .val_pairs = {{ .valid = 1, .value = 0xD00, .expected = 0xD00}}
517d36db35SAvi Kivity 	},
527d36db35SAvi Kivity 	{ .index = 0xc0000082, .name = "MSR_LSTAR",
537d36db35SAvi Kivity 	  .val_pairs = {{ .valid = 1, .value = addr_64, .expected = addr_64}}
547d36db35SAvi Kivity 	},
557d36db35SAvi Kivity 	{ .index = 0xc0000083, .name = "MSR_CSTAR",
567d36db35SAvi Kivity 	  .val_pairs = {{ .valid = 1, .value = addr_64, .expected = addr_64}}
577d36db35SAvi Kivity 	},
587d36db35SAvi Kivity 	{ .index = 0xc0000084, .name = "MSR_SYSCALL_MASK",
597d36db35SAvi Kivity 	  .val_pairs = {{ .valid = 1, .value = 0xffffffff, .expected = 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;
70*50273266SSean Christopherson 
717d36db35SAvi Kivity 	for (i = 0; i < sizeof(msr_info)/sizeof(msr_info[0]) ; i++) {
72*50273266SSean Christopherson 		if (msr_info[i].index == msr_index)
737d36db35SAvi Kivity 			return i;
747d36db35SAvi Kivity 	}
757d36db35SAvi Kivity 	return -1;
767d36db35SAvi Kivity }
777d36db35SAvi Kivity 
787d36db35SAvi Kivity static void test_msr_rw(int msr_index, unsigned long long input, unsigned long long expected)
797d36db35SAvi Kivity {
80a73d6ae4SSean Christopherson 	unsigned long long r, orig;
817d36db35SAvi Kivity 	int index;
82797d79a2SThomas Huth 	const char *sptr;
83*50273266SSean 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 	}
90a73d6ae4SSean Christopherson 	orig = rdmsr(msr_index);
917d36db35SAvi Kivity 	wrmsr(msr_index, input);
927d36db35SAvi Kivity 	r = rdmsr(msr_index);
93a73d6ae4SSean Christopherson 	wrmsr(msr_index, orig);
947d36db35SAvi Kivity 	if (expected != r) {
95d26193a0SRoman Bolshakov 		printf("testing %s: output = %#" PRIx32 ":%#" PRIx32
96d26193a0SRoman Bolshakov 		       " expected = %#" PRIx32 ":%#" PRIx32 "\n", sptr,
97b006d7ebSAndrew Jones 		       (u32)(r >> 32), (u32)r, (u32)(expected >> 32), (u32)expected);
987d36db35SAvi Kivity 	}
99a299895bSThomas Huth 	report(expected == r, "%s", sptr);
1007d36db35SAvi Kivity }
1017d36db35SAvi Kivity 
1027d36db35SAvi Kivity int main(int ac, char **av)
1037d36db35SAvi Kivity {
1047d36db35SAvi Kivity 	int i, j;
1057d36db35SAvi Kivity 	for (i = 0 ; i < sizeof(msr_info) / sizeof(msr_info[0]); i++) {
1067d36db35SAvi Kivity 		for (j = 0; j < sizeof(msr_info[i].val_pairs) / sizeof(msr_info[i].val_pairs[0]); j++) {
1077d36db35SAvi Kivity 			if (msr_info[i].val_pairs[j].valid) {
1087d36db35SAvi Kivity 				test_msr_rw(msr_info[i].index, msr_info[i].val_pairs[j].value, msr_info[i].val_pairs[j].expected);
1097d36db35SAvi Kivity 			} else {
1107d36db35SAvi Kivity 				break;
1117d36db35SAvi Kivity 			}
1127d36db35SAvi Kivity 		}
1137d36db35SAvi Kivity 	}
1147d36db35SAvi Kivity 
115f3cdd159SJan Kiszka 	return report_summary();
1167d36db35SAvi Kivity }
117