summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
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.patch175
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
+