From nobody Mon May 30 09:18:46 2022 X-Original-To: dev-commits-src-main@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 DCEB81B54895; Mon, 30 May 2022 09:18:46 +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 4LBVFy5KqXz4cC6; Mon, 30 May 2022 09:18:46 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1653902326; 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=zFA3khgY4pc2CTpnfDbADIDH5OeLbk5QWQfY9wbqKKM=; b=oWldVnw+3nisR8lX22bfNoYqv472a1lTzDPvFO1wVAjVSmVCHg6MCkne6H8PWI2lM1vE/J olrSztzrdvXZ1JAe0qLuP4aRRQnv+XtCyG7FsOyBEwuWhQ8V8EiBK7m5Rld6c1ceJhRv4N XkJbIAm/6gGMcAzDfJON2rvQwycA8PMYiLGSI5lBY/xTZY7FpbZdjnlOHqiEcWSRtJQ3A1 Zd3UGVSlnXXBW1XQg4s4zqlLIGXm+ZPXX3zcDfCVPG1qHNNq7/ew4XuEw6BwkWIYbsJvPA eWah0rF0Vj9YqHUsBOQjqmvxrnIwkKlrcHF8+3Z7g5fduXoS9x+lxrpUynmftA== 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 8C3F114924; Mon, 30 May 2022 09:18:46 +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 24U9IkFK032805; Mon, 30 May 2022 09:18:46 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 24U9Iki5032804; Mon, 30 May 2022 09:18:46 GMT (envelope-from git) Date: Mon, 30 May 2022 09:18:46 GMT Message-Id: <202205300918.24U9Iki5032804@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Emmanuel Vadot Subject: git: 3ba952e1a217 - main - vmm: add tunable to trap WBINVD List-Id: Commit messages for the main branch of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-main List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-dev-commits-src-main@freebsd.org X-BeenThere: dev-commits-src-main@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/main X-Git-Reftype: branch X-Git-Commit: 3ba952e1a2179c232402c82d5c7587159b15a8dd Auto-Submitted: auto-generated ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1653902326; 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=zFA3khgY4pc2CTpnfDbADIDH5OeLbk5QWQfY9wbqKKM=; b=EX+odQCivVm6WXTUMwjyXJbopU/iH/B0ZhtGX0O90kbFhBvCSN3JWrbfGxNXNzvyHjV+Xi szwZjNlGbIvgHxsHy303pABrqnnEX7I36uUsNfD4QpRHwLrEJikp6FkOptalrymebHRiT4 s2ls2tKDPb4hsYWQjh29Y4EYgGqHCc2zcHH12bKsrnAWEVju8WarauCer+tmelVzHaiJ2P WUX9pj90LdxRjKGHE10TQnYSZSxaMydgE7PEyi4xu1RqFbo7fvmIiJrwr3lWp1sknA6+8Q jPBry5X++YT00BvRdbOOCjBknle38P6yWk23+2AsBIyLIZPOH5N8vgetqqJdhQ== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1653902326; a=rsa-sha256; cv=none; b=awVg39ZgKOVArpSvGwYAELGcEE3PCFIW8B4Z1NnQIC4EAdQ5X8bbD0GVP4/OVj9XZ2T0CF EEN2GZ8MtjxaL152MXdSssp0DyCJQMmnwAV+aub+wQldxrwH5AlbN3AkelK6rDuv5C8V/b jY75LO1teAtnoQOhMgjJMTaYP7rfmXsrTqypRtfXTrcl97QP8WwtMgv5w2qRKFnW2TPNHg RrHNT1XR/UUURlt8+ki4T8VDOcvHuQbfTor72GSp+NNrnm1F30t+T4vA331aSSfKP7YPna H4/t1ZNXi3XQb37wGyZdgllQsnWnyJ6Co8cJ8Vy7+CWqhxxzDujH9hv2Rv9UyA== ARC-Authentication-Results: i=1; mx1.freebsd.org; none X-ThisMailContainsUnwantedMimeParts: N The branch main has been updated by manu: URL: https://cgit.FreeBSD.org/src/commit/?id=3ba952e1a2179c232402c82d5c7587159b15a8dd commit 3ba952e1a2179c232402c82d5c7587159b15a8dd Author: Corvin Köhne AuthorDate: 2022-05-30 08:02:52 +0000 Commit: Emmanuel Vadot CommitDate: 2022-05-30 08:04:22 +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 --- 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 57e941fc6145..a00494c98021 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 72ff227587aa..edb3653aff70 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 45125cb92a7e..2375dc0e13c4 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) {