2 #include <sys/malloc.h>
3 #include <sys/thread.h>
8 #include <machine/cputypes.h>
9 #include <machine/md_var.h>
10 #include <machine/specialreg.h>
15 static int svm_available = 0;
16 static int svm_enabled = 0;
18 //static int svm_rvi_available = 0;
19 //static int svm_vmcb_caching_available = 0;
21 static vm_offset_t vm_hsave_va[MAXCPU];
24 * svm_init() - Identify AMD SVM support.
26 * Called in early boot. Detects AMD SVM support and extended features.
28 static int svm_init(void) {
31 /* Not fully implemented and will break vkernel64 bootstrap */
34 /* SVM is identified by CPUID */
35 if ((amd_feature2 & AMDID2_SVM) == 0)
38 /* Processor may support SVM, but it may be disabled. */
39 vm_cr = rdmsr(MSR_AMD_VM_CR);
40 if (vm_cr & MSR_AMD_VM_CR_SVMDIS)
49 * svm_enable() - Called to enable SVM extensions on every processor.
51 static int svm_enable(void) {
55 vm_paddr_t vm_hsave_pa;
60 KKASSERT(svm_enabled == 0);
62 /* Set EFER.SVME and allocate a VM Host Save Area on every cpu */
64 for (i = 0; i < ncpus; i++) {
67 efer = rdmsr(MSR_EFER);
69 wrmsr(MSR_EFER, efer);
71 vm_hsave_va[i] = (vm_offset_t) contigmalloc(4096, M_TEMP,
75 vm_hsave_pa = vtophys(vm_hsave_va[i]);
76 wrmsr(MSR_AMD_VM_HSAVE_PA, vm_hsave_pa);
78 lwkt_migratecpu(origcpu);
86 * svm_disable() - Called to disable SVM extensions on every processor.
88 static int svm_disable(void) {
93 /* XXX Wait till no vmms are running? */
95 KKASSERT(svm_enabled == 1);
98 for (i = 0; i < ncpus; i++) {
101 wrmsr(MSR_AMD_VM_HSAVE_PA, 0);
103 contigfree((void *) vm_hsave_va[i], 4096, M_TEMP);
106 efer = rdmsr(MSR_EFER);
108 wrmsr(MSR_EFER, efer);
110 lwkt_migratecpu(origcpu);
118 * svm_vminit() - Prepare current thread for VMRUN.
120 * Allocates a VMCB for the current thread and flags the thread to return
121 * to usermode via svm_vmrun().
123 static int svm_vminit(struct guest_options *options) {
130 static int svm_vmdestroy(void) {
135 * svm_vmrun() - Execute VMRUN on a prepared VMCB for a thread.
137 * Called while a thread is returning to userspace, after being flagged as
138 * a VMM thread. svm_vmrun() continues in a loop around VMRUN/#VMEXIT
139 * handling until we are no longer a VMM thread.
141 static int svm_vmrun(void) {
145 static struct vmm_ctl ctl_svm = {
148 .enable = svm_enable,
149 .disable = svm_disable,
150 .vminit = svm_vminit,
151 .vmdestroy = svm_vmdestroy,