Module Name: src
Committed By: maxv
Date: Sat Apr 27 08:16:19 UTC 2019
Modified Files:
src/sys/dev/nvmm/x86: nvmm_x86_vmx.c nvmm_x86_vmxfunc.S
Log Message:
Optimize nvmm-intel, use inlined GCC assembly rather than function calls.
To generate a diff of this commit:
cvs rdiff -u -r1.27 -r1.28 src/sys/dev/nvmm/x86/nvmm_x86_vmx.c
cvs rdiff -u -r1.2 -r1.3 src/sys/dev/nvmm/x86/nvmm_x86_vmxfunc.S
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/dev/nvmm/x86/nvmm_x86_vmx.c
diff -u src/sys/dev/nvmm/x86/nvmm_x86_vmx.c:1.27 src/sys/dev/nvmm/x86/nvmm_x86_vmx.c:1.28
--- src/sys/dev/nvmm/x86/nvmm_x86_vmx.c:1.27 Wed Apr 24 18:19:28 2019
+++ src/sys/dev/nvmm/x86/nvmm_x86_vmx.c Sat Apr 27 08:16:19 2019
@@ -1,4 +1,4 @@
-/* $NetBSD: nvmm_x86_vmx.c,v 1.27 2019/04/24 18:19:28 maxv Exp $ */
+/* $NetBSD: nvmm_x86_vmx.c,v 1.28 2019/04/27 08:16:19 maxv Exp $ */
/*
* Copyright (c) 2018 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_vmx.c,v 1.27 2019/04/24 18:19:28 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nvmm_x86_vmx.c,v 1.28 2019/04/27 08:16:19 maxv Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -56,13 +56,6 @@ __KERNEL_RCSID(0, "$NetBSD: nvmm_x86_vmx
int _vmx_vmxon(paddr_t *pa);
int _vmx_vmxoff(void);
-int _vmx_invept(uint64_t op, void *desc);
-int _vmx_invvpid(uint64_t op, void *desc);
-int _vmx_vmread(uint64_t op, uint64_t *val);
-int _vmx_vmwrite(uint64_t op, uint64_t val);
-int _vmx_vmptrld(paddr_t *pa);
-int _vmx_vmptrst(paddr_t *pa);
-int _vmx_vmclear(paddr_t *pa);
int vmx_vmlaunch(uint64_t *gprs);
int vmx_vmresume(uint64_t *gprs);
@@ -74,34 +67,113 @@ int vmx_vmresume(uint64_t *gprs);
if (__predict_false(_vmx_vmxoff() != 0)) { \
panic("%s: VMXOFF failed", __func__); \
}
-#define vmx_invept(a, b) \
- if (__predict_false(_vmx_invept(a, b) != 0)) { \
- panic("%s: INVEPT failed", __func__); \
- }
-#define vmx_invvpid(a, b) \
- if (__predict_false(_vmx_invvpid(a, b) != 0)) { \
- panic("%s: INVVPID failed", __func__); \
- }
-#define vmx_vmread(a, b) \
- if (__predict_false(_vmx_vmread(a, b) != 0)) { \
- panic("%s: VMREAD failed", __func__); \
- }
-#define vmx_vmwrite(a, b) \
- if (__predict_false(_vmx_vmwrite(a, b) != 0)) { \
- panic("%s: VMWRITE failed", __func__); \
- }
-#define vmx_vmptrld(a) \
- if (__predict_false(_vmx_vmptrld(a) != 0)) { \
- panic("%s: VMPTRLD failed", __func__); \
- }
-#define vmx_vmptrst(a) \
- if (__predict_false(_vmx_vmptrst(a) != 0)) { \
- panic("%s: VMPTRST failed", __func__); \
- }
-#define vmx_vmclear(a) \
- if (__predict_false(_vmx_vmclear(a) != 0)) { \
- panic("%s: VMCLEAR failed", __func__); \
- }
+
+struct ept_desc {
+ uint64_t eptp;
+ uint64_t mbz;
+} __packed;
+
+struct vpid_desc {
+ uint64_t vpid;
+ uint64_t addr;
+} __packed;
+
+static inline void
+vmx_invept(uint64_t op, struct ept_desc *desc)
+{
+ asm volatile (
+ "invept %[desc],%[op];"
+ "jz vmx_insn_failvalid;"
+ "jc vmx_insn_failinvalid;"
+ :
+ : [desc] "m" (*desc), [op] "r" (op)
+ : "memory", "cc"
+ );
+}
+
+static inline void
+vmx_invvpid(uint64_t op, struct vpid_desc *desc)
+{
+ asm volatile (
+ "invvpid %[desc],%[op];"
+ "jz vmx_insn_failvalid;"
+ "jc vmx_insn_failinvalid;"
+ :
+ : [desc] "m" (*desc), [op] "r" (op)
+ : "memory", "cc"
+ );
+}
+
+static inline uint64_t
+vmx_vmread(uint64_t field)
+{
+ uint64_t value;
+
+ asm volatile (
+ "vmread %[field],%[value];"
+ "jz vmx_insn_failvalid;"
+ "jc vmx_insn_failinvalid;"
+ : [value] "=r" (value)
+ : [field] "r" (field)
+ : "cc"
+ );
+
+ return value;
+}
+
+static inline void
+vmx_vmwrite(uint64_t field, uint64_t value)
+{
+ asm volatile (
+ "vmwrite %[value],%[field];"
+ "jz vmx_insn_failvalid;"
+ "jc vmx_insn_failinvalid;"
+ :
+ : [field] "r" (field), [value] "r" (value)
+ : "cc"
+ );
+}
+
+static inline paddr_t
+vmx_vmptrst(void)
+{
+ paddr_t pa;
+
+ asm volatile (
+ "vmptrst %[pa];"
+ :
+ : [pa] "m" (*(paddr_t *)&pa)
+ : "memory"
+ );
+
+ return pa;
+}
+
+static inline void
+vmx_vmptrld(paddr_t *pa)
+{
+ asm volatile (
+ "vmptrld %[pa];"
+ "jz vmx_insn_failvalid;"
+ "jc vmx_insn_failinvalid;"
+ :
+ : [pa] "m" (*pa)
+ : "memory", "cc"
+ );
+}
+
+static inline void
+vmx_vmclear(paddr_t *pa)
+{
+ asm volatile (
+ "vmclear %[pa];"
+ "jz vmx_insn_failvalid;"
+ "jc vmx_insn_failinvalid;"
+ :
+ : [pa] "m" (*pa)
+ : "memory", "cc"
+ );
+}
#define MSR_IA32_FEATURE_CONTROL 0x003A
#define IA32_FEATURE_CONTROL_LOCK __BIT(0)
@@ -526,16 +598,6 @@ struct msr_entry {
uint64_t val;
} __packed;
-struct ept_desc {
- uint64_t eptp;
- uint64_t mbz;
-} __packed;
-
-struct vpid_desc {
- uint64_t vpid;
- uint64_t addr;
-} __packed;
-
#define VPID_MAX 0xFFFF
/* Make sure we never run out of VPIDs. */
@@ -805,7 +867,7 @@ vmx_vmcs_enter(struct nvmm_cpu *vcpu)
if (cpudata->vmcs_refcnt > 1) {
#ifdef DIAGNOSTIC
KASSERT(kpreempt_disabled());
- vmx_vmptrst(&oldpa);
+ oldpa = vmx_vmptrst();
KASSERT(oldpa == cpudata->vmcs_pa);
#endif
return;
@@ -835,12 +897,10 @@ static void
vmx_vmcs_leave(struct nvmm_cpu *vcpu)
{
struct vmx_cpudata *cpudata = vcpu->cpudata;
- paddr_t oldpa __diagused;
KASSERT(kpreempt_disabled());
#ifdef DIAGNOSTIC
- vmx_vmptrst(&oldpa);
- KASSERT(oldpa == cpudata->vmcs_pa);
+ KASSERT(vmx_vmptrst() == cpudata->vmcs_pa);
#endif
KASSERT(cpudata->vmcs_refcnt > 0);
cpudata->vmcs_refcnt--;
@@ -857,12 +917,10 @@ static void
vmx_vmcs_destroy(struct nvmm_cpu *vcpu)
{
struct vmx_cpudata *cpudata = vcpu->cpudata;
- paddr_t oldpa __diagused;
KASSERT(kpreempt_disabled());
#ifdef DIAGNOSTIC
- vmx_vmptrst(&oldpa);
- KASSERT(oldpa == cpudata->vmcs_pa);
+ KASSERT(vmx_vmptrst() == cpudata->vmcs_pa);
#endif
KASSERT(cpudata->vmcs_refcnt == 1);
cpudata->vmcs_refcnt--;
@@ -879,7 +937,7 @@ vmx_event_waitexit_enable(struct nvmm_cp
struct vmx_cpudata *cpudata = vcpu->cpudata;
uint64_t ctls1;
- vmx_vmread(VMCS_PROCBASED_CTLS, &ctls1);
+ ctls1 = vmx_vmread(VMCS_PROCBASED_CTLS);
if (nmi) {
// XXX INT_STATE_NMI?
@@ -899,7 +957,7 @@ vmx_event_waitexit_disable(struct nvmm_c
struct vmx_cpudata *cpudata = vcpu->cpudata;
uint64_t ctls1;
- vmx_vmread(VMCS_PROCBASED_CTLS, &ctls1);
+ ctls1 = vmx_vmread(VMCS_PROCBASED_CTLS);
if (nmi) {
ctls1 &= ~PROC_CTLS_NMI_WINDOW_EXITING;
@@ -950,7 +1008,7 @@ vmx_vcpu_inject(struct nvmm_machine *mac
if (event->vector == 2) {
type = INTR_TYPE_NMI;
}
- vmx_vmread(VMCS_GUEST_INTERRUPTIBILITY, &intstate);
+ intstate = vmx_vmread(VMCS_GUEST_INTERRUPTIBILITY);
if (type == INTR_TYPE_NMI) {
if (cpudata->nmi_window_exit) {
ret = EAGAIN;
@@ -958,7 +1016,7 @@ vmx_vcpu_inject(struct nvmm_machine *mac
}
vmx_event_waitexit_enable(vcpu, true);
} else {
- vmx_vmread(VMCS_GUEST_RFLAGS, &rflags);
+ rflags = vmx_vmread(VMCS_GUEST_RFLAGS);
if ((rflags & PSL_I) == 0 ||
(intstate & (INT_STATE_STI|INT_STATE_MOVSS)) != 0) {
vmx_event_waitexit_enable(vcpu, false);
@@ -1041,10 +1099,10 @@ vmx_inkernel_advance(void)
* Matters for guest-ring3, because it can execute 'cpuid' under a
* debugger.
*/
- vmx_vmread(VMCS_EXIT_INSTRUCTION_LENGTH, &inslen);
- vmx_vmread(VMCS_GUEST_RIP, &rip);
+ inslen = vmx_vmread(VMCS_EXIT_INSTRUCTION_LENGTH);
+ rip = vmx_vmread(VMCS_GUEST_RIP);
vmx_vmwrite(VMCS_GUEST_RIP, rip + inslen);
- vmx_vmread(VMCS_GUEST_INTERRUPTIBILITY, &intstate);
+ intstate = vmx_vmread(VMCS_GUEST_INTERRUPTIBILITY);
vmx_vmwrite(VMCS_GUEST_INTERRUPTIBILITY,
intstate & ~(INT_STATE_STI|INT_STATE_MOVSS));
}
@@ -1055,7 +1113,7 @@ vmx_exit_exc_nmi(struct nvmm_machine *ma
{
uint64_t qual;
- vmx_vmread(VMCS_EXIT_INTR_INFO, &qual);
+ qual = vmx_vmread(VMCS_EXIT_INTR_INFO);
if ((qual & INTR_INFO_VALID) == 0) {
goto error;
@@ -1091,7 +1149,7 @@ vmx_inkernel_handle_cpuid(struct nvmm_cp
cpudata->gprs[NVMM_X64_GPR_RDX] &= nvmm_cpuid_00000001.edx;
/* CPUID2_OSXSAVE depends on CR4. */
- vmx_vmread(VMCS_GUEST_CR4, &cr4);
+ cr4 = vmx_vmread(VMCS_GUEST_CR4);
if (!(cr4 & CR4_OSXSAVE)) {
cpudata->gprs[NVMM_X64_GPR_RCX] &= ~CPUID2_OSXSAVE;
}
@@ -1207,7 +1265,7 @@ vmx_exit_hlt(struct nvmm_machine *mach,
uint64_t rflags;
if (cpudata->int_window_exit) {
- vmx_vmread(VMCS_GUEST_RFLAGS, &rflags);
+ rflags = vmx_vmread(VMCS_GUEST_RFLAGS);
if (rflags & PSL_I) {
vmx_event_waitexit_disable(vcpu, false);
}
@@ -1258,7 +1316,7 @@ vmx_inkernel_handle_cr0(struct nvmm_mach
KASSERT(gpr < 16);
if (gpr == NVMM_X64_GPR_RSP) {
- vmx_vmread(VMCS_GUEST_RSP, &gpr);
+ gpr = vmx_vmread(VMCS_GUEST_RSP);
} else {
gpr = cpudata->gprs[gpr];
}
@@ -1276,8 +1334,8 @@ vmx_inkernel_handle_cr0(struct nvmm_mach
*/
if (cr0 & CR0_PG) {
- vmx_vmread(VMCS_ENTRY_CTLS, &ctls1);
- vmx_vmread(VMCS_GUEST_IA32_EFER, &efer);
+ ctls1 = vmx_vmread(VMCS_ENTRY_CTLS);
+ efer = vmx_vmread(VMCS_GUEST_IA32_EFER);
if (efer & EFER_LME) {
ctls1 |= ENTRY_CTLS_LONG_MODE;
efer |= EFER_LMA;
@@ -1310,7 +1368,7 @@ vmx_inkernel_handle_cr4(struct nvmm_mach
KASSERT(gpr < 16);
if (gpr == NVMM_X64_GPR_RSP) {
- vmx_vmread(VMCS_GUEST_RSP, &gpr);
+ gpr = vmx_vmread(VMCS_GUEST_RSP);
} else {
gpr = cpudata->gprs[gpr];
}
@@ -1348,7 +1406,7 @@ vmx_inkernel_handle_cr8(struct nvmm_mach
if (write) {
if (gpr == NVMM_X64_GPR_RSP) {
- vmx_vmread(VMCS_GUEST_RSP, &cpudata->gcr8);
+ cpudata->gcr8 = vmx_vmread(VMCS_GUEST_RSP);
} else {
cpudata->gcr8 = cpudata->gprs[gpr];
}
@@ -1371,7 +1429,7 @@ vmx_exit_cr(struct nvmm_machine *mach, s
uint64_t qual;
int ret;
- vmx_vmread(VMCS_EXIT_QUALIFICATION, &qual);
+ qual = vmx_vmread(VMCS_EXIT_QUALIFICATION);
switch (__SHIFTOUT(qual, VMX_QUAL_CR_NUM)) {
case 0:
@@ -1417,8 +1475,8 @@ vmx_exit_io(struct nvmm_machine *mach, s
{
uint64_t qual, info, inslen, rip;
- vmx_vmread(VMCS_EXIT_QUALIFICATION, &qual);
- vmx_vmread(VMCS_EXIT_INSTRUCTION_INFO, &info);
+ qual = vmx_vmread(VMCS_EXIT_QUALIFICATION);
+ info = vmx_vmread(VMCS_EXIT_INSTRUCTION_INFO);
exit->reason = NVMM_EXIT_IO;
@@ -1456,8 +1514,8 @@ vmx_exit_io(struct nvmm_machine *mach, s
exit->u.io.seg = NVMM_X64_SEG_ES;
}
- vmx_vmread(VMCS_EXIT_INSTRUCTION_LENGTH, &inslen);
- vmx_vmread(VMCS_GUEST_RIP, &rip);
+ inslen = vmx_vmread(VMCS_EXIT_INSTRUCTION_LENGTH);
+ rip = vmx_vmread(VMCS_GUEST_RIP);
exit->u.io.npc = rip + inslen;
}
@@ -1477,7 +1535,7 @@ vmx_inkernel_handle_msr(struct nvmm_mach
switch (exit->u.msr.type) {
case NVMM_EXIT_MSR_RDMSR:
if (exit->u.msr.msr == MSR_CR_PAT) {
- vmx_vmread(VMCS_GUEST_IA32_PAT, &val);
+ val = vmx_vmread(VMCS_GUEST_IA32_PAT);
cpudata->gprs[NVMM_X64_GPR_RAX] = (val & 0xFFFFFFFF);
cpudata->gprs[NVMM_X64_GPR_RDX] = (val >> 32);
goto handled;
@@ -1564,8 +1622,8 @@ vmx_exit_msr(struct nvmm_machine *mach,
}
exit->reason = NVMM_EXIT_MSR;
- vmx_vmread(VMCS_EXIT_INSTRUCTION_LENGTH, &inslen);
- vmx_vmread(VMCS_GUEST_RIP, &rip);
+ inslen = vmx_vmread(VMCS_EXIT_INSTRUCTION_LENGTH);
+ rip = vmx_vmread(VMCS_GUEST_RIP);
exit->u.msr.npc = rip + inslen;
}
@@ -1609,10 +1667,10 @@ vmx_exit_epf(struct nvmm_machine *mach,
uint64_t perm;
gpaddr_t gpa;
- vmx_vmread(VMCS_GUEST_PHYSICAL_ADDRESS, &gpa);
+ gpa = vmx_vmread(VMCS_GUEST_PHYSICAL_ADDRESS);
exit->reason = NVMM_EXIT_MEMORY;
- vmx_vmread(VMCS_EXIT_QUALIFICATION, &perm);
+ perm = vmx_vmread(VMCS_EXIT_QUALIFICATION);
if (perm & VMX_EPT_VIOLATION_WRITE)
exit->u.mem.prot = PROT_WRITE;
else if (perm & VMX_EPT_VIOLATION_EXECUTE)
@@ -1753,7 +1811,7 @@ vmx_htlb_catchup(struct nvmm_cpu *vcpu,
return;
}
- vmx_vmread(VMCS_EPTP, &ept_desc.eptp);
+ ept_desc.eptp = vmx_vmread(VMCS_EPTP);
ept_desc.mbz = 0;
vmx_invept(vmx_ept_flush_op, &ept_desc);
kcpuset_clear(cpudata->htlb_want_flush, hcpu);
@@ -1772,7 +1830,7 @@ vmx_htlb_flush(struct vmx_machdata *mach
kcpuset_copy(cpudata->htlb_want_flush, kcpuset_running);
- vmx_vmread(VMCS_EPTP, &ept_desc.eptp);
+ ept_desc.eptp = vmx_vmread(VMCS_EPTP);
ept_desc.mbz = 0;
vmx_invept(vmx_ept_flush_op, &ept_desc);
@@ -1855,7 +1913,7 @@ vmx_vcpu_run(struct nvmm_machine *mach,
launched = true;
- vmx_vmread(VMCS_EXIT_REASON, &exitcode);
+ exitcode = vmx_vmread(VMCS_EXIT_REASON);
exitcode &= __BITS(15,0);
switch (exitcode) {
@@ -1945,16 +2003,15 @@ vmx_vcpu_run(struct nvmm_machine *mach,
cpudata->vmcs_launched = launched;
- vmx_vmread(VMCS_TSC_OFFSET, &cpudata->gtsc);
- cpudata->gtsc += rdtsc();
+ cpudata->gtsc = vmx_vmread(VMCS_TSC_OFFSET) + rdtsc();
vmx_vcpu_guest_misc_leave(vcpu);
vmx_vcpu_guest_dbregs_leave(vcpu);
exit->exitstate[NVMM_X64_EXITSTATE_CR8] = cpudata->gcr8;
- vmx_vmread(VMCS_GUEST_RFLAGS,
- &exit->exitstate[NVMM_X64_EXITSTATE_RFLAGS]);
- vmx_vmread(VMCS_GUEST_INTERRUPTIBILITY, &intstate);
+ exit->exitstate[NVMM_X64_EXITSTATE_RFLAGS] =
+ vmx_vmread(VMCS_GUEST_RFLAGS);
+ intstate = vmx_vmread(VMCS_GUEST_INTERRUPTIBILITY);
exit->exitstate[NVMM_X64_EXITSTATE_INT_SHADOW] =
(intstate & (INT_STATE_STI|INT_STATE_MOVSS)) != 0;
exit->exitstate[NVMM_X64_EXITSTATE_INT_WINDOW_EXIT] =
@@ -2087,14 +2144,14 @@ vmx_vcpu_setstate_seg(const struct nvmm_
static void
vmx_vcpu_getstate_seg(struct nvmm_x64_state_seg *segs, int idx)
{
- uint64_t selector, base, limit, attrib = 0;
+ uint64_t selector = 0, attrib = 0, base, limit;
if (idx != NVMM_X64_SEG_GDT && idx != NVMM_X64_SEG_IDT) {
- vmx_vmread(vmx_guest_segs[idx].selector, &selector);
- vmx_vmread(vmx_guest_segs[idx].attrib, &attrib);
+ selector = vmx_vmread(vmx_guest_segs[idx].selector);
+ attrib = vmx_vmread(vmx_guest_segs[idx].attrib);
}
- vmx_vmread(vmx_guest_segs[idx].limit, &limit);
- vmx_vmread(vmx_guest_segs[idx].base, &base);
+ limit = vmx_vmread(vmx_guest_segs[idx].limit);
+ base = vmx_vmread(vmx_guest_segs[idx].base);
segs[idx].selector = selector;
segs[idx].limit = limit;
@@ -2118,22 +2175,22 @@ vmx_state_tlb_flush(const struct nvmm_x6
uint64_t cr0, cr3, cr4, efer;
if (flags & NVMM_X64_STATE_CRS) {
- vmx_vmread(VMCS_GUEST_CR0, &cr0);
+ cr0 = vmx_vmread(VMCS_GUEST_CR0);
if ((cr0 ^ state->crs[NVMM_X64_CR_CR0]) & CR0_TLB_FLUSH) {
return true;
}
- vmx_vmread(VMCS_GUEST_CR3, &cr3);
+ cr3 = vmx_vmread(VMCS_GUEST_CR3);
if (cr3 != state->crs[NVMM_X64_CR_CR3]) {
return true;
}
- vmx_vmread(VMCS_GUEST_CR4, &cr4);
+ cr4 = vmx_vmread(VMCS_GUEST_CR4);
if ((cr4 ^ state->crs[NVMM_X64_CR_CR4]) & CR4_TLB_FLUSH) {
return true;
}
}
if (flags & NVMM_X64_STATE_MSRS) {
- vmx_vmread(VMCS_GUEST_IA32_EFER, &efer);
+ efer = vmx_vmread(VMCS_GUEST_IA32_EFER);
if ((efer ^
state->msrs[NVMM_X64_MSR_EFER]) & EFER_TLB_FLUSH) {
return true;
@@ -2234,7 +2291,7 @@ vmx_vcpu_setstate(struct nvmm_cpu *vcpu,
cpudata->gtsc_want_update = true;
/* ENTRY_CTLS_LONG_MODE must match EFER_LMA. */
- vmx_vmread(VMCS_ENTRY_CTLS, &ctls1);
+ ctls1 = vmx_vmread(VMCS_ENTRY_CTLS);
if (state->msrs[NVMM_X64_MSR_EFER] & EFER_LMA) {
ctls1 |= ENTRY_CTLS_LONG_MODE;
} else {
@@ -2244,7 +2301,7 @@ vmx_vcpu_setstate(struct nvmm_cpu *vcpu,
}
if (flags & NVMM_X64_STATE_INTR) {
- vmx_vmread(VMCS_GUEST_INTERRUPTIBILITY, &intstate);
+ intstate = vmx_vmread(VMCS_GUEST_INTERRUPTIBILITY);
intstate &= ~(INT_STATE_STI|INT_STATE_MOVSS);
if (state->intr.int_shadow) {
intstate |= INT_STATE_MOVSS;
@@ -2308,16 +2365,16 @@ vmx_vcpu_getstate(struct nvmm_cpu *vcpu,
if (flags & NVMM_X64_STATE_GPRS) {
memcpy(state->gprs, cpudata->gprs, sizeof(state->gprs));
- vmx_vmread(VMCS_GUEST_RIP, &state->gprs[NVMM_X64_GPR_RIP]);
- vmx_vmread(VMCS_GUEST_RSP, &state->gprs[NVMM_X64_GPR_RSP]);
- vmx_vmread(VMCS_GUEST_RFLAGS, &state->gprs[NVMM_X64_GPR_RFLAGS]);
+ state->gprs[NVMM_X64_GPR_RIP] = vmx_vmread(VMCS_GUEST_RIP);
+ state->gprs[NVMM_X64_GPR_RSP] = vmx_vmread(VMCS_GUEST_RSP);
+ state->gprs[NVMM_X64_GPR_RFLAGS] = vmx_vmread(VMCS_GUEST_RFLAGS);
}
if (flags & NVMM_X64_STATE_CRS) {
- vmx_vmread(VMCS_GUEST_CR0, &state->crs[NVMM_X64_CR_CR0]);
+ state->crs[NVMM_X64_CR_CR0] = vmx_vmread(VMCS_GUEST_CR0);
state->crs[NVMM_X64_CR_CR2] = cpudata->gcr2;
- vmx_vmread(VMCS_GUEST_CR3, &state->crs[NVMM_X64_CR_CR3]);
- vmx_vmread(VMCS_GUEST_CR4, &state->crs[NVMM_X64_CR_CR4]);
+ state->crs[NVMM_X64_CR_CR3] = vmx_vmread(VMCS_GUEST_CR3);
+ state->crs[NVMM_X64_CR_CR4] = vmx_vmread(VMCS_GUEST_CR4);
state->crs[NVMM_X64_CR_CR8] = cpudata->gcr8;
state->crs[NVMM_X64_CR_XCR0] = cpudata->gxcr0;
@@ -2329,7 +2386,7 @@ vmx_vcpu_getstate(struct nvmm_cpu *vcpu,
if (flags & NVMM_X64_STATE_DRS) {
memcpy(state->drs, cpudata->drs, sizeof(state->drs));
- vmx_vmread(VMCS_GUEST_DR7, &state->drs[NVMM_X64_DR_DR7]);
+ state->drs[NVMM_X64_DR_DR7] = vmx_vmread(VMCS_GUEST_DR7);
}
if (flags & NVMM_X64_STATE_MSRS) {
@@ -2343,23 +2400,21 @@ vmx_vcpu_getstate(struct nvmm_cpu *vcpu,
cpudata->gmsr[VMX_MSRLIST_SFMASK].val;
state->msrs[NVMM_X64_MSR_KERNELGSBASE] =
cpudata->gmsr[VMX_MSRLIST_KERNELGSBASE].val;
-
- vmx_vmread(VMCS_GUEST_IA32_EFER,
- &state->msrs[NVMM_X64_MSR_EFER]);
- vmx_vmread(VMCS_GUEST_IA32_PAT,
- &state->msrs[NVMM_X64_MSR_PAT]);
- vmx_vmread(VMCS_GUEST_IA32_SYSENTER_CS,
- &state->msrs[NVMM_X64_MSR_SYSENTER_CS]);
- vmx_vmread(VMCS_GUEST_IA32_SYSENTER_ESP,
- &state->msrs[NVMM_X64_MSR_SYSENTER_ESP]);
- vmx_vmread(VMCS_GUEST_IA32_SYSENTER_EIP,
- &state->msrs[NVMM_X64_MSR_SYSENTER_EIP]);
-
+ state->msrs[NVMM_X64_MSR_EFER] =
+ vmx_vmread(VMCS_GUEST_IA32_EFER);
+ state->msrs[NVMM_X64_MSR_PAT] =
+ vmx_vmread(VMCS_GUEST_IA32_PAT);
+ state->msrs[NVMM_X64_MSR_SYSENTER_CS] =
+ vmx_vmread(VMCS_GUEST_IA32_SYSENTER_CS);
+ state->msrs[NVMM_X64_MSR_SYSENTER_ESP] =
+ vmx_vmread(VMCS_GUEST_IA32_SYSENTER_ESP);
+ state->msrs[NVMM_X64_MSR_SYSENTER_EIP] =
+ vmx_vmread(VMCS_GUEST_IA32_SYSENTER_EIP);
state->msrs[NVMM_X64_MSR_TSC] = cpudata->gtsc;
}
if (flags & NVMM_X64_STATE_INTR) {
- vmx_vmread(VMCS_GUEST_INTERRUPTIBILITY, &intstate);
+ intstate = vmx_vmread(VMCS_GUEST_INTERRUPTIBILITY);
state->intr.int_shadow =
(intstate & (INT_STATE_STI|INT_STATE_MOVSS)) != 0;
state->intr.int_window_exiting = cpudata->int_window_exit;
@@ -2413,7 +2468,7 @@ vmx_asid_free(struct nvmm_cpu *vcpu)
size_t oct, bit;
uint64_t asid;
- vmx_vmread(VMCS_VPID, &asid);
+ asid = vmx_vmread(VMCS_VPID);
oct = asid / 8;
bit = asid % 8;
Index: src/sys/dev/nvmm/x86/nvmm_x86_vmxfunc.S
diff -u src/sys/dev/nvmm/x86/nvmm_x86_vmxfunc.S:1.2 src/sys/dev/nvmm/x86/nvmm_x86_vmxfunc.S:1.3
--- src/sys/dev/nvmm/x86/nvmm_x86_vmxfunc.S:1.2 Wed Apr 24 18:45:15 2019
+++ src/sys/dev/nvmm/x86/nvmm_x86_vmxfunc.S Sat Apr 27 08:16:19 2019
@@ -1,4 +1,4 @@
-/* $NetBSD: nvmm_x86_vmxfunc.S,v 1.2 2019/04/24 18:45:15 maxv Exp $ */
+/* $NetBSD: nvmm_x86_vmxfunc.S,v 1.3 2019/04/27 08:16:19 maxv Exp $ */
/*
* Copyright (c) 2018 The NetBSD Foundation, Inc.
@@ -73,120 +73,6 @@ ENTRY(_vmx_vmxoff)
retq
END(_vmx_vmxoff)
-/*
- * %rdi = op
- * %rsi = *descriptor
- */
-ENTRY(_vmx_invept)
- invept (%rsi),%rdi
- jz .Linvept_failvalid
- jc .Linvept_failinvalid
- xorq %rax,%rax
- retq
-.Linvept_failvalid:
- movq $-1,%rax
- retq
-.Linvept_failinvalid:
- movq $-2,%rax
- retq
-END(_vmx_invept)
-
-/*
- * %rdi = op
- * %rsi = *descriptor
- */
-ENTRY(_vmx_invvpid)
- invvpid (%rsi),%rdi
- jz .Linvvpid_failvalid
- jc .Linvvpid_failinvalid
- xorq %rax,%rax
- retq
-.Linvvpid_failvalid:
- movq $-1,%rax
- retq
-.Linvvpid_failinvalid:
- movq $-2,%rax
- retq
-END(_vmx_invvpid)
-
-/*
- * %rdi = op
- * %rsi = *val
- */
-ENTRY(_vmx_vmread)
- vmread %rdi,(%rsi)
- jz .Lvmread_failvalid
- jc .Lvmread_failinvalid
- xorq %rax,%rax
- retq
-.Lvmread_failvalid:
- movq $-1,%rax
- retq
-.Lvmread_failinvalid:
- movq $-2,%rax
- retq
-END(_vmx_vmread)
-
-/*
- * %rdi = op
- * %rsi = val
- */
-ENTRY(_vmx_vmwrite)
- vmwrite %rsi,%rdi
- jz .Lvmwrite_failvalid
- jc .Lvmwrite_failinvalid
- xorq %rax,%rax
- retq
-.Lvmwrite_failvalid:
- movq $-1,%rax
- retq
-.Lvmwrite_failinvalid:
- movq $-2,%rax
- retq
-END(_vmx_vmwrite)
-
-/*
- * %rdi = *pa
- */
-ENTRY(_vmx_vmptrld)
- vmptrld (%rdi)
- jz .Lfail_vmptrld
- jc .Lfail_vmptrld
- xorq %rax,%rax
- retq
-.Lfail_vmptrld:
- movq $-1,%rax
- retq
-END(_vmx_vmptrld)
-
-/*
- * %rdi = *pa
- */
-ENTRY(_vmx_vmptrst)
- vmptrst (%rdi)
- jz .Lfail_vmptrst
- jc .Lfail_vmptrst
- xorq %rax,%rax
- retq
-.Lfail_vmptrst:
- movq $-1,%rax
- retq
-END(_vmx_vmptrst)
-
-/*
- * %rdi = pa
- */
-ENTRY(_vmx_vmclear)
- vmclear (%rdi)
- jz .Lfail_vmclear
- jc .Lfail_vmclear
- xorq %rax,%rax
- retq
-.Lfail_vmclear:
- movq $-1,%rax
- retq
-END(_vmx_vmclear)
-
/* redef */
#define VMCS_HOST_RSP 0x00006C14
@@ -355,3 +241,20 @@ ENTRY(vmx_resume_rip)
xorq %rax,%rax
retq
END(vmx_resume_rip)
+
+ENTRY(vmx_insn_failvalid)
+ movq $.Lvmx_validstr,%rdi
+ call _C_LABEL(panic)
+END(vmx_insn_failvalid)
+
+ENTRY(vmx_insn_failinvalid)
+ movq $.Lvmx_invalidstr,%rdi
+ call _C_LABEL(panic)
+END(vmx_insn_failinvalid)
+
+ .section ".rodata"
+
+.Lvmx_validstr:
+ .string "VMX fail valid\0"
+.Lvmx_invalidstr:
+ .string "VMX fail invalid\0"