commit:     c296975a0b99af5c25ecb10e3de4fb573ff5ddc7
Author:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
AuthorDate: Sun Feb 23 19:53:57 2025 +0000
Commit:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
CommitDate: Sun Feb 23 19:53:57 2025 +0000
URL:        https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=c296975a

Add two KVM patches to fix regression

Bug: https://bugzilla.kernel.org/show_bug.cgi?id=219787
Bug: https://bugs.gentoo.org/950113

KVM: x86: Snapshot the host's DEBUGCTL in common x86
KVM: SVM: Manually zero/restore DEBUGCTL if LBR virtualization is disabled
Signed-off-by: Mike Pagano <mpagano <AT> gentoo.org>

 0000_README                                       |  8 ++
 1750_KVM-x86-Snapshot-hosts-DEBUGCTL.patch        | 95 +++++++++++++++++++++++
 1751_KVM-SVM-Manually-zero-restore-DEBUGCTL.patch | 69 ++++++++++++++++
 3 files changed, 172 insertions(+)

diff --git a/0000_README b/0000_README
index 60c36739..6a580881 100644
--- a/0000_README
+++ b/0000_README
@@ -75,6 +75,14 @@ Patch:  
1740_x86-insn-decoder-test-allow-longer-symbol-names.patch
 From:   
https://gitlab.com/cki-project/kernel-ark/-/commit/8d4a52c3921d278f27241fc0c6949d8fdc13a7f5
 Desc:   x86/insn_decoder_test: allow longer symbol-names
 
+Patch:  1750_KVM-x86-Snapshot-hosts-DEBUGCTL.patch  
+From:   https://bugzilla.kernel.org/show_bug.cgi?id=219787
+Desc:   KVM: x86: Snapshot the host's DEBUGCTL in common x86
+
+Patch:  1751_KVM-SVM-Manually-zero-restore-DEBUGCTL.patch
+From:   https://bugzilla.kernel.org/show_bug.cgi?id=219787
+Desc:   KVM: SVM: Manually zero/restore DEBUGCTL if LBR virtualization is 
disabled
+
 Patch:  2000_BT-Check-key-sizes-only-if-Secure-Simple-Pairing-enabled.patch
 From:   
https://lore.kernel.org/linux-bluetooth/[email protected]/raw
 Desc:   Bluetooth: Check key sizes only when Secure Simple Pairing is enabled. 
See bug #686758

diff --git a/1750_KVM-x86-Snapshot-hosts-DEBUGCTL.patch 
b/1750_KVM-x86-Snapshot-hosts-DEBUGCTL.patch
new file mode 100644
index 00000000..0265460c
--- /dev/null
+++ b/1750_KVM-x86-Snapshot-hosts-DEBUGCTL.patch
@@ -0,0 +1,95 @@
+From d8595d6256fd46ece44b3433954e8545a0d199b8 Mon Sep 17 00:00:00 2001
+From: Sean Christopherson <[email protected]>
+Date: Fri, 21 Feb 2025 07:45:22 -0800
+Subject: [PATCH 1/2] KVM: x86: Snapshot the host's DEBUGCTL in common x86
+
+Move KVM's snapshot of DEBUGCTL to kvm_vcpu_arch and take the snapshot in
+common x86, so that SVM can also use the snapshot.
+
+Opportunistically change the field to a u64.  While bits 63:32 are reserved
+on AMD, not mentioned at all in Intel's SDM, and managed as an "unsigned
+long" by the kernel, DEBUGCTL is an MSR and therefore a 64-bit value.
+
+Cc: [email protected]
+Signed-off-by: Sean Christopherson <[email protected]>
+---
+ arch/x86/include/asm/kvm_host.h | 1 +
+ arch/x86/kvm/vmx/vmx.c          | 8 ++------
+ arch/x86/kvm/vmx/vmx.h          | 2 --
+ arch/x86/kvm/x86.c              | 1 +
+ 4 files changed, 4 insertions(+), 8 deletions(-)
+
+diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
+index 0b7af5902ff7..32ae3aa50c7e 100644
+--- a/arch/x86/include/asm/kvm_host.h
++++ b/arch/x86/include/asm/kvm_host.h
+@@ -780,6 +780,7 @@ struct kvm_vcpu_arch {
+       u32 pkru;
+       u32 hflags;
+       u64 efer;
++      u64 host_debugctl;
+       u64 apic_base;
+       struct kvm_lapic *apic;    /* kernel irqchip context */
+       bool load_eoi_exitmap_pending;
+diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c
+index 6c56d5235f0f..3b92f893b239 100644
+--- a/arch/x86/kvm/vmx/vmx.c
++++ b/arch/x86/kvm/vmx/vmx.c
+@@ -1514,16 +1514,12 @@ void vmx_vcpu_load_vmcs(struct kvm_vcpu *vcpu, int cpu,
+  */
+ void vmx_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
+ {
+-      struct vcpu_vmx *vmx = to_vmx(vcpu);
+-
+       if (vcpu->scheduled_out && !kvm_pause_in_guest(vcpu->kvm))
+               shrink_ple_window(vcpu);
+ 
+       vmx_vcpu_load_vmcs(vcpu, cpu, NULL);
+ 
+       vmx_vcpu_pi_load(vcpu, cpu);
+-
+-      vmx->host_debugctlmsr = get_debugctlmsr();
+ }
+ 
+ void vmx_vcpu_put(struct kvm_vcpu *vcpu)
+@@ -7458,8 +7454,8 @@ fastpath_t vmx_vcpu_run(struct kvm_vcpu *vcpu, bool 
force_immediate_exit)
+       }
+ 
+       /* MSR_IA32_DEBUGCTLMSR is zeroed on vmexit. Restore it if needed */
+-      if (vmx->host_debugctlmsr)
+-              update_debugctlmsr(vmx->host_debugctlmsr);
++      if (vcpu->arch.host_debugctl)
++              update_debugctlmsr(vcpu->arch.host_debugctl);
+ 
+ #ifndef CONFIG_X86_64
+       /*
+diff --git a/arch/x86/kvm/vmx/vmx.h b/arch/x86/kvm/vmx/vmx.h
+index 8b111ce1087c..951e44dc9d0e 100644
+--- a/arch/x86/kvm/vmx/vmx.h
++++ b/arch/x86/kvm/vmx/vmx.h
+@@ -340,8 +340,6 @@ struct vcpu_vmx {
+       /* apic deadline value in host tsc */
+       u64 hv_deadline_tsc;
+ 
+-      unsigned long host_debugctlmsr;
+-
+       /*
+        * Only bits masked by msr_ia32_feature_control_valid_bits can be set in
+        * msr_ia32_feature_control. FEAT_CTL_LOCKED is always included
+diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
+index 02159c967d29..5c6fd0edc41f 100644
+--- a/arch/x86/kvm/x86.c
++++ b/arch/x86/kvm/x86.c
+@@ -4968,6 +4968,7 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
+ 
+       /* Save host pkru register if supported */
+       vcpu->arch.host_pkru = read_pkru();
++      vcpu->arch.host_debugctl = get_debugctlmsr();
+ 
+       /* Apply any externally detected TSC adjustments (due to suspend) */
+       if (unlikely(vcpu->arch.tsc_offset_adjustment)) {
+
+base-commit: 0ad2507d5d93f39619fc42372c347d6006b64319
+-- 
+2.48.1.658.g4767266eb4-goog
+

diff --git a/1751_KVM-SVM-Manually-zero-restore-DEBUGCTL.patch 
b/1751_KVM-SVM-Manually-zero-restore-DEBUGCTL.patch
new file mode 100644
index 00000000..e3ce9fe4
--- /dev/null
+++ b/1751_KVM-SVM-Manually-zero-restore-DEBUGCTL.patch
@@ -0,0 +1,69 @@
+From d02de0dfc6fd10f7bc4f7067fb9765c24948c737 Mon Sep 17 00:00:00 2001
+From: Sean Christopherson <[email protected]>
+Date: Fri, 21 Feb 2025 08:16:36 -0800
+Subject: [PATCH 2/2] KVM: SVM: Manually zero/restore DEBUGCTL if LBR
+ virtualization is disabled
+
+Manually zero DEBUGCTL prior to VMRUN if the host's value is non-zero and
+LBR virtualization is disabled, as hardware only context switches DEBUGCTL
+if LBR virtualization is fully enabled.  Running the guest with the host's
+value has likely been mildly problematic for quite some time, e.g. it will
+result in undesirable behavior if host is running with BTF=1.
+
+But the bug became fatal with the introduction of Bus Lock Trap ("Detect"
+in kernel paralance) support for AMD (commit 408eb7417a92
+("x86/bus_lock: Add support for AMD")), as a bus lock in the guest will
+trigger an unexpected #DB.
+
+Note, KVM could suppress the bus lock #DB, i.e. simply resume the guest
+without injecting a #DB, but that wouldn't address things like BTF.  And
+it appears that AMD CPUs incorrectly clear DR6_BUS_LOCK (it's active low)
+when delivering a #DB that is NOT a bus lock trap, and BUS_LOCK_DETECT is
+enabled in DEBUGCTL.
+
+Reported-by: [email protected]
+Reported-by: [email protected]
+Closes: https://bugzilla.kernel.org/show_bug.cgi?id=219787
+Closes: 
https://lore.kernel.org/all/[email protected]%2F
+Cc: Ravi Bangoria <[email protected]>
+Cc: [email protected]
+Signed-off-by: Sean Christopherson <[email protected]>
+---
+ arch/x86/kvm/svm/svm.c | 14 ++++++++++++++
+ 1 file changed, 14 insertions(+)
+
+diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c
+index a713c803a3a3..a50ca1f17e31 100644
+--- a/arch/x86/kvm/svm/svm.c
++++ b/arch/x86/kvm/svm/svm.c
+@@ -4253,6 +4253,16 @@ static __no_kcsan fastpath_t svm_vcpu_run(struct 
kvm_vcpu *vcpu,
+       clgi();
+       kvm_load_guest_xsave_state(vcpu);
+ 
++      /*
++       * Hardware only context switches DEBUGCTL if LBR virtualization is
++       * enabled.  Manually zero DEBUGCTL if necessary (and restore it after)
++       * VM-Exit, as running with the host's DEBUGCTL can negatively affect
++       * guest state and can even be fatal, e.g. due to bus lock detect.
++       */
++      if (vcpu->arch.host_debugctl &&
++          !(svm->vmcb->control.virt_ext & LBR_CTL_ENABLE_MASK))
++              update_debugctlmsr(0);
++
+       kvm_wait_lapic_expire(vcpu);
+ 
+       /*
+@@ -4280,6 +4290,10 @@ static __no_kcsan fastpath_t svm_vcpu_run(struct 
kvm_vcpu *vcpu,
+       if (unlikely(svm->vmcb->control.exit_code == SVM_EXIT_NMI))
+               kvm_before_interrupt(vcpu, KVM_HANDLING_NMI);
+ 
++      if (vcpu->arch.host_debugctl &&
++          !(svm->vmcb->control.virt_ext & LBR_CTL_ENABLE_MASK))
++              update_debugctlmsr(vcpu->arch.host_debugctl);
++
+       kvm_load_host_xsave_state(vcpu);
+       stgi();
+ 
+-- 
+2.48.1.658.g4767266eb4-goog
+

Reply via email to