summaryrefslogtreecommitdiff
path: root/usr/src/uts/intel
diff options
context:
space:
mode:
authorAndy Fiddaman <illumos@fiddaman.net>2022-08-17 20:44:42 +0000
committerAndy Fiddaman <illumos@fiddaman.net>2022-11-05 13:48:21 +0000
commit4f3f3e9a1dee62c031fa67cfe64e11d6dd3fab1b (patch)
treec7ada529531e7e297db67acf08e1a325f79ec107 /usr/src/uts/intel
parentcfed4d7055842c539437036c634e7fe84d10977d (diff)
downloadillumos-joyent-4f3f3e9a1dee62c031fa67cfe64e11d6dd3fab1b.tar.gz
14763 bhyve upstream sync 2022 August
Reviewed by: Patrick Mooney <pmooney@pfmooney.com> Approved by: Robert Mustacchi <rm@fingolfin.org>
Diffstat (limited to 'usr/src/uts/intel')
-rw-r--r--usr/src/uts/intel/io/vmm/amd/amdvi_hw.c7
-rw-r--r--usr/src/uts/intel/io/vmm/amd/svm.c10
-rw-r--r--usr/src/uts/intel/io/vmm/amd/vmcb.h1
-rw-r--r--usr/src/uts/intel/io/vmm/intel/vmx.c20
-rw-r--r--usr/src/uts/intel/io/vmm/sys/vmm_kernel.h1
-rw-r--r--usr/src/uts/intel/io/vmm/vmm.c14
6 files changed, 45 insertions, 8 deletions
diff --git a/usr/src/uts/intel/io/vmm/amd/amdvi_hw.c b/usr/src/uts/intel/io/vmm/amd/amdvi_hw.c
index 33a2557492..c217b19112 100644
--- a/usr/src/uts/intel/io/vmm/amd/amdvi_hw.c
+++ b/usr/src/uts/intel/io/vmm/amd/amdvi_hw.c
@@ -418,7 +418,7 @@ amdvi_cmd_inv_intr_map(struct amdvi_softc *softc,
static void
amdvi_inv_domain(struct amdvi_softc *softc, uint16_t domain_id)
{
- struct amdvi_cmd *cmd;
+ struct amdvi_cmd *cmd __diagused;
cmd = amdvi_get_cmd_tail(softc);
KASSERT(cmd != NULL, ("Cmd is NULL"));
@@ -439,13 +439,14 @@ amdvi_inv_domain(struct amdvi_softc *softc, uint16_t domain_id)
static bool
amdvi_cmp_wait(struct amdvi_softc *softc)
{
- struct amdvi_ctrl *ctrl;
+#ifdef AMDVI_DEBUG_CMD
+ struct amdvi_ctrl *ctrl = softc->ctrl;
+#endif
const uint64_t VERIFY = 0xA5A5;
volatile uint64_t *read;
int i;
bool status;
- ctrl = softc->ctrl;
read = &softc->cmp_data;
*read = 0;
amdvi_cmd_cmp(softc, VERIFY);
diff --git a/usr/src/uts/intel/io/vmm/amd/svm.c b/usr/src/uts/intel/io/vmm/amd/svm.c
index f4f01ea4b6..a20a844030 100644
--- a/usr/src/uts/intel/io/vmm/amd/svm.c
+++ b/usr/src/uts/intel/io/vmm/amd/svm.c
@@ -378,6 +378,10 @@ vmcb_init(struct svm_softc *sc, int vcpu, uint64_t iopm_base_pa,
svm_enable_intercept(sc, vcpu, VMCB_CTRL2_INTCPT, VMCB_INTCPT_STGI);
svm_enable_intercept(sc, vcpu, VMCB_CTRL2_INTCPT, VMCB_INTCPT_CLGI);
svm_enable_intercept(sc, vcpu, VMCB_CTRL2_INTCPT, VMCB_INTCPT_SKINIT);
+ if (vcpu_trap_wbinvd(sc->vm, vcpu) != 0) {
+ svm_enable_intercept(sc, vcpu, VMCB_CTRL2_INTCPT,
+ VMCB_INTCPT_WBINVD);
+ }
/*
* The ASID will be set to a non-zero value just before VMRUN.
@@ -1448,7 +1452,6 @@ svm_vmexit(struct svm_softc *svm_sc, int vcpu, struct vm_exit *vmexit)
(void) vm_suspend(svm_sc->vm, VM_SUSPEND_TRIPLEFAULT);
handled = 1;
break;
- case VMCB_EXIT_INVD:
case VMCB_EXIT_INVLPGA:
/* privileged invalidation instructions */
vm_inject_ud(svm_sc->vm, vcpu);
@@ -1464,6 +1467,11 @@ svm_vmexit(struct svm_softc *svm_sc, int vcpu, struct vm_exit *vmexit)
vm_inject_ud(svm_sc->vm, vcpu);
handled = 1;
break;
+ case VMCB_EXIT_INVD:
+ case VMCB_EXIT_WBINVD:
+ /* ignore exit */
+ handled = 1;
+ break;
case VMCB_EXIT_VMMCALL:
/* No handlers make use of VMMCALL for now */
vm_inject_ud(svm_sc->vm, vcpu);
diff --git a/usr/src/uts/intel/io/vmm/amd/vmcb.h b/usr/src/uts/intel/io/vmm/amd/vmcb.h
index 7a57979d56..91e00193bf 100644
--- a/usr/src/uts/intel/io/vmm/amd/vmcb.h
+++ b/usr/src/uts/intel/io/vmm/amd/vmcb.h
@@ -172,6 +172,7 @@ struct svm_softc;
#define VMCB_EXIT_STGI 0x84
#define VMCB_EXIT_CLGI 0x85
#define VMCB_EXIT_SKINIT 0x86
+#define VMCB_EXIT_WBINVD 0x89
#define VMCB_EXIT_MONITOR 0x8A
#define VMCB_EXIT_MWAIT 0x8B
#define VMCB_EXIT_NPF 0x400
diff --git a/usr/src/uts/intel/io/vmm/intel/vmx.c b/usr/src/uts/intel/io/vmm/intel/vmx.c
index c16fe1f1d4..e42455a0f3 100644
--- a/usr/src/uts/intel/io/vmm/intel/vmx.c
+++ b/usr/src/uts/intel/io/vmm/intel/vmx.c
@@ -188,6 +188,9 @@ static int vmx_initialized;
/* PAUSE triggers a VM-exit */
static int cap_pause_exit;
+/* WBINVD triggers a VM-exit */
+static int cap_wbinvd_exit;
+
/* Monitor trap flag */
static int cap_monitor_trap;
@@ -548,6 +551,11 @@ vmx_init(void)
PROCBASED_PAUSE_EXITING, 0,
&tmp) == 0);
+ cap_wbinvd_exit = (vmx_set_ctlreg(MSR_VMX_PROCBASED_CTLS2,
+ MSR_VMX_PROCBASED_CTLS2,
+ PROCBASED2_WBINVD_EXITING, 0,
+ &tmp) == 0);
+
cap_invpcid = (vmx_set_ctlreg(MSR_VMX_PROCBASED_CTLS2,
MSR_VMX_PROCBASED_CTLS2, PROCBASED2_ENABLE_INVPCID, 0,
&tmp) == 0);
@@ -819,7 +827,12 @@ vmx_vminit(struct vm *vm)
vmcs_write(VMCS_EPTP, vmx->eptp);
vmcs_write(VMCS_PIN_BASED_CTLS, pin_ctls);
vmcs_write(VMCS_PRI_PROC_BASED_CTLS, proc_ctls);
- vmcs_write(VMCS_SEC_PROC_BASED_CTLS, proc2_ctls);
+
+ uint32_t use_proc2_ctls = proc2_ctls;
+ if (cap_wbinvd_exit && vcpu_trap_wbinvd(vm, i) != 0)
+ use_proc2_ctls |= PROCBASED2_WBINVD_EXITING;
+ vmcs_write(VMCS_SEC_PROC_BASED_CTLS, use_proc2_ctls);
+
vmcs_write(VMCS_EXIT_CTLS, exit_ctls);
vmcs_write(VMCS_ENTRY_CTLS, entry_ctls);
vmcs_write(VMCS_MSR_BITMAP, msr_bitmap_pa);
@@ -2530,6 +2543,11 @@ vmx_exit_process(struct vmx *vmx, int vcpu, struct vm_exit *vmexit)
SDT_PROBE3(vmm, vmx, exit, vminsn, vmx, vcpu, vmexit);
vmexit->exitcode = VM_EXITCODE_VMINSN;
break;
+ case EXIT_REASON_INVD:
+ case EXIT_REASON_WBINVD:
+ /* ignore exit */
+ handled = HANDLED;
+ break;
default:
SDT_PROBE4(vmm, vmx, exit, unknown,
vmx, vcpu, vmexit, reason);
diff --git a/usr/src/uts/intel/io/vmm/sys/vmm_kernel.h b/usr/src/uts/intel/io/vmm/sys/vmm_kernel.h
index c5c7d7889e..1ef2d48adf 100644
--- a/usr/src/uts/intel/io/vmm/sys/vmm_kernel.h
+++ b/usr/src/uts/intel/io/vmm/sys/vmm_kernel.h
@@ -358,6 +358,7 @@ void vm_copyout(struct vm *vm, int vcpuid, const void *kaddr,
struct vm_copyinfo *copyinfo, size_t len);
int vcpu_trace_exceptions(struct vm *vm, int vcpuid);
+int vcpu_trap_wbinvd(struct vm *vm, int vcpuid);
void vm_inject_ud(struct vm *vm, int vcpuid);
void vm_inject_gp(struct vm *vm, int vcpuid);
diff --git a/usr/src/uts/intel/io/vmm/vmm.c b/usr/src/uts/intel/io/vmm/vmm.c
index 44f1ee5ca2..136c38c5ab 100644
--- a/usr/src/uts/intel/io/vmm/vmm.c
+++ b/usr/src/uts/intel/io/vmm/vmm.c
@@ -286,10 +286,13 @@ SYSCTL_NODE(_hw, OID_AUTO, vmm, CTLFLAG_RW | CTLFLAG_MPSAFE, NULL,
* Halt the guest if all vcpus are executing a HLT instruction with
* interrupts disabled.
*/
-static int halt_detection_enabled = 1;
+int halt_detection_enabled = 1;
/* Trap into hypervisor on all guest exceptions and reflect them back */
-static int trace_guest_exceptions;
+int trace_guest_exceptions;
+
+/* Trap WBINVD and ignore it */
+int trap_wbinvd = 1;
static void vm_free_memmap(struct vm *vm, int ident);
static bool sysmem_mapping(struct vm *vm, struct mem_map *mm);
@@ -403,10 +406,15 @@ vcpu_init(struct vm *vm, int vcpu_id, bool create)
int
vcpu_trace_exceptions(struct vm *vm, int vcpuid)
{
-
return (trace_guest_exceptions);
}
+int
+vcpu_trap_wbinvd(struct vm *vm, int vcpuid)
+{
+ return (trap_wbinvd);
+}
+
struct vm_exit *
vm_exitinfo(struct vm *vm, int cpuid)
{