diff options
Diffstat (limited to '0064-x86-vmx-implement-VMExit-based-guest-Bus-Lock-detect.patch')
-rw-r--r-- | 0064-x86-vmx-implement-VMExit-based-guest-Bus-Lock-detect.patch | 175 |
1 files changed, 175 insertions, 0 deletions
diff --git a/0064-x86-vmx-implement-VMExit-based-guest-Bus-Lock-detect.patch b/0064-x86-vmx-implement-VMExit-based-guest-Bus-Lock-detect.patch new file mode 100644 index 0000000..cebb501 --- /dev/null +++ b/0064-x86-vmx-implement-VMExit-based-guest-Bus-Lock-detect.patch @@ -0,0 +1,175 @@ +From 83f12e4eafdc4b034501adf4847a09a1293fdf8b Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Roger=20Pau=20Monn=C3=A9?= <roger.pau@citrix.com> +Date: Tue, 21 Mar 2023 13:40:41 +0100 +Subject: [PATCH 64/89] x86/vmx: implement VMExit based guest Bus Lock + detection +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Add support for enabling guest Bus Lock Detection on Intel systems. +Such detection works by triggering a vmexit, which ought to be enough +of a pause to prevent a guest from abusing of the Bus Lock. + +Add an extra Xen perf counter to track the number of Bus Locks detected. +This is done because Bus Locks can also be reported by setting the bit +26 in the exit reason field, so also account for those. + +Note EXIT_REASON_BUS_LOCK VMExits will always have bit 26 set in +exit_reason, and hence the performance counter doesn't need to be +increased for EXIT_REASON_BUS_LOCK handling. + +Suggested-by: Andrew Cooper <andrew.cooper3@citrix.com> +Signed-off-by: Roger Pau Monné <roger.pau@citrix.com> +Reviewed-by: Kevin Tian <kevin.tian@intel.com> +master commit: f7d07619d2ae0382e2922e287fbfbb27722f3f0b +master date: 2022-12-19 11:22:43 +0100 +--- + xen/arch/x86/hvm/vmx/vmcs.c | 4 +++- + xen/arch/x86/hvm/vmx/vmx.c | 15 +++++++++++++++ + xen/arch/x86/hvm/vmx/vvmx.c | 3 ++- + xen/arch/x86/include/asm/hvm/vmx/vmcs.h | 3 +++ + xen/arch/x86/include/asm/hvm/vmx/vmx.h | 2 ++ + xen/arch/x86/include/asm/perfc_defn.h | 4 +++- + 6 files changed, 28 insertions(+), 3 deletions(-) + +diff --git a/xen/arch/x86/hvm/vmx/vmcs.c b/xen/arch/x86/hvm/vmx/vmcs.c +index 84dbb88d33..a0d5e8d6ab 100644 +--- a/xen/arch/x86/hvm/vmx/vmcs.c ++++ b/xen/arch/x86/hvm/vmx/vmcs.c +@@ -209,6 +209,7 @@ static void __init vmx_display_features(void) + P(cpu_has_vmx_virt_exceptions, "Virtualisation Exceptions"); + P(cpu_has_vmx_pml, "Page Modification Logging"); + P(cpu_has_vmx_tsc_scaling, "TSC Scaling"); ++ P(cpu_has_vmx_bus_lock_detection, "Bus Lock Detection"); + #undef P + + if ( !printed ) +@@ -318,7 +319,8 @@ static int vmx_init_vmcs_config(bool bsp) + SECONDARY_EXEC_ENABLE_VM_FUNCTIONS | + SECONDARY_EXEC_ENABLE_VIRT_EXCEPTIONS | + SECONDARY_EXEC_XSAVES | +- SECONDARY_EXEC_TSC_SCALING); ++ SECONDARY_EXEC_TSC_SCALING | ++ SECONDARY_EXEC_BUS_LOCK_DETECTION); + if ( _vmx_misc_cap & VMX_MISC_VMWRITE_ALL ) + opt |= SECONDARY_EXEC_ENABLE_VMCS_SHADOWING; + if ( opt_vpid_enabled ) +diff --git a/xen/arch/x86/hvm/vmx/vmx.c b/xen/arch/x86/hvm/vmx/vmx.c +index 861f91f2af..d0f0f2e429 100644 +--- a/xen/arch/x86/hvm/vmx/vmx.c ++++ b/xen/arch/x86/hvm/vmx/vmx.c +@@ -4084,6 +4084,12 @@ void vmx_vmexit_handler(struct cpu_user_regs *regs) + return; + } + ++ if ( unlikely(exit_reason & VMX_EXIT_REASONS_BUS_LOCK) ) ++ { ++ perfc_incr(buslock); ++ exit_reason &= ~VMX_EXIT_REASONS_BUS_LOCK; ++ } ++ + /* XXX: This looks ugly, but we need a mechanism to ensure + * any pending vmresume has really happened + */ +@@ -4593,6 +4599,15 @@ void vmx_vmexit_handler(struct cpu_user_regs *regs) + vmx_handle_descriptor_access(exit_reason); + break; + ++ case EXIT_REASON_BUS_LOCK: ++ /* ++ * Nothing to do: just taking a vmexit should be enough of a pause to ++ * prevent a VM from crippling the host with bus locks. Note ++ * EXIT_REASON_BUS_LOCK will always have bit 26 set in exit_reason, and ++ * hence the perf counter is already increased. ++ */ ++ break; ++ + case EXIT_REASON_VMX_PREEMPTION_TIMER_EXPIRED: + case EXIT_REASON_INVPCID: + /* fall through */ +diff --git a/xen/arch/x86/hvm/vmx/vvmx.c b/xen/arch/x86/hvm/vmx/vvmx.c +index 5f54451475..2095c1e612 100644 +--- a/xen/arch/x86/hvm/vmx/vvmx.c ++++ b/xen/arch/x86/hvm/vmx/vvmx.c +@@ -2405,7 +2405,7 @@ void nvmx_idtv_handling(void) + * be reinjected, otherwise, pass to L1. + */ + __vmread(VM_EXIT_REASON, &reason); +- if ( reason != EXIT_REASON_EPT_VIOLATION ? ++ if ( (uint16_t)reason != EXIT_REASON_EPT_VIOLATION ? + !(nvmx->intr.intr_info & INTR_INFO_VALID_MASK) : + !nvcpu->nv_vmexit_pending ) + { +@@ -2486,6 +2486,7 @@ int nvmx_n2_vmexit_handler(struct cpu_user_regs *regs, + case EXIT_REASON_EPT_VIOLATION: + case EXIT_REASON_EPT_MISCONFIG: + case EXIT_REASON_EXTERNAL_INTERRUPT: ++ case EXIT_REASON_BUS_LOCK: + /* pass to L0 handler */ + break; + case VMX_EXIT_REASONS_FAILED_VMENTRY: +diff --git a/xen/arch/x86/include/asm/hvm/vmx/vmcs.h b/xen/arch/x86/include/asm/hvm/vmx/vmcs.h +index 75f9928abf..f3df5113d4 100644 +--- a/xen/arch/x86/include/asm/hvm/vmx/vmcs.h ++++ b/xen/arch/x86/include/asm/hvm/vmx/vmcs.h +@@ -267,6 +267,7 @@ extern u32 vmx_vmentry_control; + #define SECONDARY_EXEC_ENABLE_VIRT_EXCEPTIONS 0x00040000 + #define SECONDARY_EXEC_XSAVES 0x00100000 + #define SECONDARY_EXEC_TSC_SCALING 0x02000000 ++#define SECONDARY_EXEC_BUS_LOCK_DETECTION 0x40000000 + extern u32 vmx_secondary_exec_control; + + #define VMX_EPT_EXEC_ONLY_SUPPORTED 0x00000001 +@@ -346,6 +347,8 @@ extern u64 vmx_ept_vpid_cap; + (vmx_secondary_exec_control & SECONDARY_EXEC_XSAVES) + #define cpu_has_vmx_tsc_scaling \ + (vmx_secondary_exec_control & SECONDARY_EXEC_TSC_SCALING) ++#define cpu_has_vmx_bus_lock_detection \ ++ (vmx_secondary_exec_control & SECONDARY_EXEC_BUS_LOCK_DETECTION) + + #define VMCS_RID_TYPE_MASK 0x80000000 + +diff --git a/xen/arch/x86/include/asm/hvm/vmx/vmx.h b/xen/arch/x86/include/asm/hvm/vmx/vmx.h +index 8eedf59155..03995701a1 100644 +--- a/xen/arch/x86/include/asm/hvm/vmx/vmx.h ++++ b/xen/arch/x86/include/asm/hvm/vmx/vmx.h +@@ -159,6 +159,7 @@ static inline void pi_clear_sn(struct pi_desc *pi_desc) + * Exit Reasons + */ + #define VMX_EXIT_REASONS_FAILED_VMENTRY 0x80000000 ++#define VMX_EXIT_REASONS_BUS_LOCK (1u << 26) + + #define EXIT_REASON_EXCEPTION_NMI 0 + #define EXIT_REASON_EXTERNAL_INTERRUPT 1 +@@ -219,6 +220,7 @@ static inline void pi_clear_sn(struct pi_desc *pi_desc) + #define EXIT_REASON_PML_FULL 62 + #define EXIT_REASON_XSAVES 63 + #define EXIT_REASON_XRSTORS 64 ++#define EXIT_REASON_BUS_LOCK 74 + /* Remember to also update VMX_PERF_EXIT_REASON_SIZE! */ + + /* +diff --git a/xen/arch/x86/include/asm/perfc_defn.h b/xen/arch/x86/include/asm/perfc_defn.h +index 509afc516b..6fce21e85a 100644 +--- a/xen/arch/x86/include/asm/perfc_defn.h ++++ b/xen/arch/x86/include/asm/perfc_defn.h +@@ -6,7 +6,7 @@ PERFCOUNTER_ARRAY(exceptions, "exceptions", 32) + + #ifdef CONFIG_HVM + +-#define VMX_PERF_EXIT_REASON_SIZE 65 ++#define VMX_PERF_EXIT_REASON_SIZE 75 + #define VMEXIT_NPF_PERFC 143 + #define SVM_PERF_EXIT_REASON_SIZE (VMEXIT_NPF_PERFC + 1) + PERFCOUNTER_ARRAY(vmexits, "vmexits", +@@ -128,4 +128,6 @@ PERFCOUNTER(pauseloop_exits, "vmexits from Pause-Loop Detection") + PERFCOUNTER(iommu_pt_shatters, "IOMMU page table shatters") + PERFCOUNTER(iommu_pt_coalesces, "IOMMU page table coalesces") + ++PERFCOUNTER(buslock, "Bus Locks Detected") ++ + /*#endif*/ /* __XEN_PERFC_DEFN_H__ */ +-- +2.40.0 + |