From nobody Mon Jun 20 15:36:29 2022 X-Original-To: dev-commits-src-all@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 9040C86C7C5; Mon, 20 Jun 2022 15:36:29 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4LRYf532lCz4mt6; Mon, 20 Jun 2022 15:36:29 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1655739389; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=dRWrFbOLw7PlUv2GQJEnamKCN+CW3YmSqSWsPUg00r8=; b=lnmyR2pH6HtAjCSceTaf/Xgtt2uZYAAzN9ATmsb8QhnPk21efryMZ7T4CtIaDFbUq7Ffu1 ZBoWILBO+S+sMc4zheOjS8NpBnCLPw7vZNSjDHzgH4vQsf28XPQbwUQeDUCBUt4Y/naGrA 3YWt33bMfVbb7+ifU39kB3wj9An2GojrZFrAgp7GhE2WBJ42tX05eQrV3iXrKG+Ptxagix Z9z833dA16M4nitXvV56GglBcgnTtS5KKejnXHDM17mDDecIs1OiJ0RiZ793npz9aZ6yNM K1E4aDOKvN4b0w3wnKn7EXUm2SikSVQ1rhvY51Y4OgIKmj8wRqwXVrW8796tyQ== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 454151FFE2; Mon, 20 Jun 2022 15:36:29 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.16.1/8.16.1) with ESMTP id 25KFaT9n031533; Mon, 20 Jun 2022 15:36:29 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 25KFaTRe031532; Mon, 20 Jun 2022 15:36:29 GMT (envelope-from git) Date: Mon, 20 Jun 2022 15:36:29 GMT Message-Id: <202206201536.25KFaTRe031532@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: Emmanuel Vadot Subject: git: f195c503ad63 - stable/13 - vmm: add tunable to trap WBINVD List-Id: Commit messages for all branches of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-dev-commits-src-all@freebsd.org X-BeenThere: dev-commits-src-all@freebsd.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: manu X-Git-Repository: src X-Git-Refname: refs/heads/stable/13 X-Git-Reftype: branch X-Git-Commit: f195c503ad63c35b83cbaf6e8df2fe3fc203442e Auto-Submitted: auto-generated ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1655739389; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=dRWrFbOLw7PlUv2GQJEnamKCN+CW3YmSqSWsPUg00r8=; b=aXWEFnYaqptTEYz4Ter1qG1lF+xYj3Ma6MTzbiU/TyO+Sct9Peys6ZhxlLJkxW07vFJL/l 8m6weZVFvJcprk7eu15jEFJqLHX4uZ1MHJVsgDocmrHM1n1PAJ1pfftKihqAd5/uV5r2YU C6ELgSKOlYZzt3zVCL9I2Ebr75OfrLCqy7MsjlqCk1EilxzmJo0qG2AwhmDWsW40n2GMMM nIny3TtwAjM0asZkQ18SGUAxaQsHkHqWSp7NUIefA9NybxWReC9ksoDyRrwFN+MgN0wlCP SbNOZUdcqO/vUSQKShp7xy2Mh01d6qLTEMSDu+sOxf5vJu9gwO3fDvLhR0UPBQ== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1655739389; a=rsa-sha256; cv=none; b=Jof/ZVNeKjv/pMaF9Sw9ZAUC829JzeLPxnsWNIKZyrw/YpXniF+YO3sP/6fnVANnXzj2SK N7VNaH5rZoFnZ9vrbAPv4EcJ7Xh9vLtpDha6TP+TRv7fWy0AgE4iBTOaHs0S5GKy8/0bqi NTiOrlDUgamn6ntBXSEMWB3qVrBREHrrxIjEz5mXf2vA03Z2QZkpXywfwm1wGBFU/cnbXz QY2UEhFgpnBSHbHcrkY4qhcf37jURZXQ5dUj5Y6pcedWI+OvxllKeUDLR6x/cl78fh2Ij0 ghtTl7CeXFyuans4/uTNxluUmMEnHH9W/0tF5YqK2WXiOxqr5qQeIKvCqea5WA== ARC-Authentication-Results: i=1; mx1.freebsd.org; none X-ThisMailContainsUnwantedMimeParts: N The branch stable/13 has been updated by manu: URL: https://cgit.FreeBSD.org/src/commit/?id=f195c503ad63c35b83cbaf6e8df2fe3fc203442e commit f195c503ad63c35b83cbaf6e8df2fe3fc203442e Author: Corvin Köhne AuthorDate: 2022-05-30 08:02:52 +0000 Commit: Emmanuel Vadot CommitDate: 2022-06-20 15:05:36 +0000 vmm: add tunable to trap WBINVD x86 is cache coherent. However, there are special cases where cache coherency isn't ensured (e.g. when switching the caching mode). In these cases, WBINVD can be used. WBINVD writes all cache lines back into main memory and invalidates the whole cache. Due to the invalidation of the whole cache, WBINVD is a very heavy instruction and degrades the performance on all cores. So, we should minimize the use of WBINVD as much as possible. In a virtual environment, the WBINVD call is mostly useless. The guest isn't able to break cache coherency because he can't switch the physical cache mode. When using pci passthrough WBINVD might be useful. Nevertheless, trapping and ignoring WBINVD is an unsafe operation. For that reason, we implement it as tunable. Reviewed by: jhb Sponsored by: Beckhoff Automation GmbH & Co. KG MFC after: 1 week Differential Revision: https://reviews.freebsd.org/D35253 (cherry picked from commit 3ba952e1a2179c232402c82d5c7587159b15a8dd) --- sys/amd64/include/vmm.h | 1 + sys/amd64/vmm/amd/svm.c | 8 ++++++++ sys/amd64/vmm/amd/vmcb.h | 1 + sys/amd64/vmm/intel/vmx.c | 18 ++++++++++++++++++ sys/amd64/vmm/vmm.c | 10 ++++++++++ 5 files changed, 38 insertions(+) diff --git a/sys/amd64/include/vmm.h b/sys/amd64/include/vmm.h index d7d1509248f1..ce61e16522aa 100644 --- a/sys/amd64/include/vmm.h +++ b/sys/amd64/include/vmm.h @@ -467,6 +467,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); #endif /* KERNEL */ #ifdef _KERNEL diff --git a/sys/amd64/vmm/amd/svm.c b/sys/amd64/vmm/amd/svm.c index fbf11ec84084..3b119c722934 100644 --- a/sys/amd64/vmm/amd/svm.c +++ b/sys/amd64/vmm/amd/svm.c @@ -506,6 +506,10 @@ vmcb_init(struct svm_softc *sc, int vcpu, uint64_t iopm_base_pa, svm_enable_intercept(sc, vcpu, VMCB_CTRL2_INTCPT, VMCB_INTCPT_CLGI); svm_enable_intercept(sc, vcpu, VMCB_CTRL2_INTCPT, VMCB_INTCPT_SKINIT); svm_enable_intercept(sc, vcpu, VMCB_CTRL2_INTCPT, VMCB_INTCPT_ICEBP); + if (vcpu_trap_wbinvd(sc->vm, vcpu)) { + svm_enable_intercept(sc, vcpu, VMCB_CTRL2_INTCPT, + VMCB_INTCPT_WBINVD); + } /* * From section "Canonicalization and Consistency Checks" in APMv2 @@ -1552,6 +1556,10 @@ 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_WBINVD: + /* ignore WBINVD */ + handled = 1; + break; default: vmm_stat_incr(svm_sc->vm, vcpu, VMEXIT_UNKNOWN, 1); break; diff --git a/sys/amd64/vmm/amd/vmcb.h b/sys/amd64/vmm/amd/vmcb.h index feea3e149205..847e1f6ad476 100644 --- a/sys/amd64/vmm/amd/vmcb.h +++ b/sys/amd64/vmm/amd/vmcb.h @@ -149,6 +149,7 @@ #define VMCB_EXIT_CLGI 0x85 #define VMCB_EXIT_SKINIT 0x86 #define VMCB_EXIT_ICEBP 0x88 +#define VMCB_EXIT_WBINVD 0x89 #define VMCB_EXIT_MONITOR 0x8A #define VMCB_EXIT_MWAIT 0x8B #define VMCB_EXIT_NPF 0x400 diff --git a/sys/amd64/vmm/intel/vmx.c b/sys/amd64/vmm/intel/vmx.c index e7ced1b2c3fa..62d9c64847d6 100644 --- a/sys/amd64/vmm/intel/vmx.c +++ b/sys/amd64/vmm/intel/vmx.c @@ -168,6 +168,10 @@ static int cap_pause_exit; SYSCTL_INT(_hw_vmm_vmx_cap, OID_AUTO, pause_exit, CTLFLAG_RD, &cap_pause_exit, 0, "PAUSE triggers a VM-exit"); +static int cap_wbinvd_exit; +SYSCTL_INT(_hw_vmm_vmx_cap, OID_AUTO, wbinvd_exit, CTLFLAG_RD, &cap_wbinvd_exit, + 0, "WBINVD triggers a VM-exit"); + static int cap_rdpid; SYSCTL_INT(_hw_vmm_vmx_cap, OID_AUTO, rdpid, CTLFLAG_RD, &cap_rdpid, 0, "Guests are allowed to use RDPID"); @@ -777,6 +781,12 @@ vmx_modinit(int ipinum) 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); + /* * Check support for RDPID and/or RDTSCP. * @@ -1117,6 +1127,10 @@ vmx_init(struct vm *vm, pmap_t pmap) error += vmwrite(VMCS_EPTP, vmx->eptp); error += vmwrite(VMCS_PIN_BASED_CTLS, pinbased_ctls); error += vmwrite(VMCS_PRI_PROC_BASED_CTLS, procbased_ctls); + if (vcpu_trap_wbinvd(vm, i)) { + KASSERT(cap_wbinvd_exit, ("WBINVD trap not available")); + procbased_ctls2 |= PROCBASED2_WBINVD_EXITING; + } error += vmwrite(VMCS_SEC_PROC_BASED_CTLS, procbased_ctls2); error += vmwrite(VMCS_EXIT_CTLS, exit_ctls); error += vmwrite(VMCS_ENTRY_CTLS, entry_ctls); @@ -2776,6 +2790,10 @@ 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_WBINVD: + /* ignore WBINVD */ + handled = HANDLED; + break; default: SDT_PROBE4(vmm, vmx, exit, unknown, vmx, vcpu, vmexit, reason); diff --git a/sys/amd64/vmm/vmm.c b/sys/amd64/vmm/vmm.c index 3d6fca939498..f6ed99a6efbf 100644 --- a/sys/amd64/vmm/vmm.c +++ b/sys/amd64/vmm/vmm.c @@ -265,6 +265,10 @@ SYSCTL_INT(_hw_vmm, OID_AUTO, trace_guest_exceptions, CTLFLAG_RDTUN, &trace_guest_exceptions, 0, "Trap into hypervisor on all guest exceptions and reflect them back"); +static int trap_wbinvd; +SYSCTL_INT(_hw_vmm, OID_AUTO, trap_wbinvd, CTLFLAG_RDTUN, &trap_wbinvd, 0, + "WBINVD triggers a VM-exit"); + static void vm_free_memmap(struct vm *vm, int ident); static bool sysmem_mapping(struct vm *vm, struct mem_map *mm); static void vcpu_notify_event_locked(struct vcpu *vcpu, bool lapic_intr); @@ -341,6 +345,12 @@ 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) {