xref: /xnu-8020.140.41/tests/hvtest_x86_guest.c (revision 27b03b360a988dfd3dfdf34262bb0042026747cc)
1 // Do not include system headers in this file. Code in this file needs to be
2 // self-contained, as it runs in a VM.
3 #include "hvtest_x86_guest.h"
4 #include <stdbool.h>
5 #include <stdatomic.h>
6 
7 #define VMCALL(x) __asm__("vmcall" : : "a" ((x)) :)
8 
9 void
simple_long_mode_vcpu_entry(uint64_t arg)10 simple_long_mode_vcpu_entry(uint64_t arg)
11 {
12 	VMCALL(arg + 0x23456);
13 
14 	while (true) {
15 	}
16 }
17 
18 void
smp_vcpu_entry(uint64_t arg)19 smp_vcpu_entry(uint64_t arg)
20 {
21 	// Performing this atomic operation on the same memory on all VCPUs confirms
22 	// that they are running in the same IPA space, and that the space is
23 	// shareable.
24 	atomic_uint *count = (atomic_uint *)arg;
25 
26 	VMCALL(atomic_fetch_add_explicit(count, 1,
27 	    memory_order_relaxed));
28 
29 	while (true) {
30 	}
31 }
32 
33 __unused static inline uint64_t
rdmsr(uint64_t msr)34 rdmsr(uint64_t msr)
35 {
36 	uint32_t idx = (uint32_t)msr;
37 	uint32_t outhi, outlo;
38 
39 	__asm__("rdmsr" : "=d"(outhi), "=a"(outlo) : "c"(idx));
40 
41 	return ((uint64_t)outhi << 32) | outlo;
42 }
43 
44 static inline void
wrmsr(uint64_t msr,uint64_t value)45 wrmsr(uint64_t msr, uint64_t value)
46 {
47 	uint32_t idx = (uint32_t)msr;
48 	uint32_t inhi = (uint32_t)((value & 0xffffffff00000000UL) >> 32);
49 	uint32_t inlo = (uint32_t)(value & 0xffffffffUL);
50 
51 	__asm__("wrmsr" : : "d"(inhi),"a"(inlo),"c"(idx));
52 }
53 
54 void
native_msr_vcpu_entry(uint64_t arg __unused)55 native_msr_vcpu_entry(uint64_t arg __unused)
56 {
57 	wrmsr(MSR_IA32_STAR, 0x123456789abcdef0);
58 	wrmsr(MSR_IA32_LSTAR, 0x123456789abc);
59 	wrmsr(MSR_IA32_CSTAR, 0x123456789abc);
60 
61 	wrmsr(MSR_IA32_FMASK, 0x123456789abcdef0);
62 
63 	wrmsr(MSR_IA32_TSC_AUX, 0x123);
64 
65 	wrmsr(MSR_IA32_SYSENTER_CS, 0xffff);
66 	wrmsr(MSR_IA32_SYSENTER_ESP, 0x123456789abc);
67 	wrmsr(MSR_IA32_SYSENTER_EIP, 0x123456789abc);
68 
69 	wrmsr(MSR_IA32_FS_BASE, 0x123456789abc);
70 	wrmsr(MSR_IA32_GS_BASE, 0x123456789abc);
71 	wrmsr(MSR_IA32_KERNEL_GS_BASE, 0x123456789abc);
72 
73 	VMCALL(0x23456);
74 
75 	while (true) {
76 	}
77 }
78