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"

Reply via email to