diff options
Diffstat (limited to '0054-x86-svm-Fix-asymmetry-with-AMD-DR-MASK-context-switc.patch')
-rw-r--r-- | 0054-x86-svm-Fix-asymmetry-with-AMD-DR-MASK-context-switc.patch | 104 |
1 files changed, 0 insertions, 104 deletions
diff --git a/0054-x86-svm-Fix-asymmetry-with-AMD-DR-MASK-context-switc.patch b/0054-x86-svm-Fix-asymmetry-with-AMD-DR-MASK-context-switc.patch deleted file mode 100644 index af72c9a..0000000 --- a/0054-x86-svm-Fix-asymmetry-with-AMD-DR-MASK-context-switc.patch +++ /dev/null @@ -1,104 +0,0 @@ -From 3f8b444072fd8615288d9d11e53fbf0b6a8a7750 Mon Sep 17 00:00:00 2001 -From: Andrew Cooper <andrew.cooper3@citrix.com> -Date: Tue, 26 Sep 2023 20:03:36 +0100 -Subject: [PATCH 54/55] x86/svm: Fix asymmetry with AMD DR MASK context - switching - -The handling of MSR_DR{0..3}_MASK is asymmetric between PV and HVM guests. - -HVM guests context switch in based on the guest view of DBEXT, whereas PV -guest switch in base on the host capability. Both guest types leave the -context dirty for the next vCPU. - -This leads to the following issue: - - * PV or HVM vCPU has debugging active (%dr7 + mask) - * Switch out deactivates %dr7 but leaves other state stale in hardware - * HVM vCPU with debugging activate but can't see DBEXT is switched in - * Switch in loads %dr7 but leaves the mask MSRs alone - -Now, the HVM vCPU is operating in the context of the prior vCPU's mask MSR, -and furthermore in a case where it genuinely expects there to be no masking -MSRs. - -As a stopgap, adjust the HVM path to switch in/out the masks based on host -capabilities rather than guest visibility (i.e. like the PV path). Adjustment -of the of the intercepts still needs to be dependent on the guest visibility -of DBEXT. - -This is part of XSA-444 / CVE-2023-34327 - -Fixes: c097f54912d3 ("x86/SVM: support data breakpoint extension registers") -Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com> -(cherry picked from commit 5d54282f984bb9a7a65b3d12208584f9fdf1c8e1) ---- - xen/arch/x86/hvm/svm/svm.c | 24 ++++++++++++++++++------ - xen/arch/x86/traps.c | 5 +++++ - 2 files changed, 23 insertions(+), 6 deletions(-) - -diff --git a/xen/arch/x86/hvm/svm/svm.c b/xen/arch/x86/hvm/svm/svm.c -index e8f50e7c5e..fd32600ae3 100644 ---- a/xen/arch/x86/hvm/svm/svm.c -+++ b/xen/arch/x86/hvm/svm/svm.c -@@ -339,6 +339,10 @@ static void svm_save_dr(struct vcpu *v) - v->arch.hvm.flag_dr_dirty = 0; - vmcb_set_dr_intercepts(vmcb, ~0u); - -+ /* -+ * The guest can only have changed the mask MSRs if we previous dropped -+ * intercepts. Re-read them from hardware. -+ */ - if ( v->domain->arch.cpuid->extd.dbext ) - { - svm_intercept_msr(v, MSR_AMD64_DR0_ADDRESS_MASK, MSR_INTERCEPT_RW); -@@ -370,17 +374,25 @@ static void __restore_debug_registers(struct vmcb_struct *vmcb, struct vcpu *v) - - ASSERT(v == current); - -- if ( v->domain->arch.cpuid->extd.dbext ) -+ /* -+ * Both the PV and HVM paths leave stale DR_MASK values in hardware on -+ * context-switch-out. If we're activating %dr7 for the guest, we must -+ * sync the DR_MASKs too, whether or not the guest can see them. -+ */ -+ if ( boot_cpu_has(X86_FEATURE_DBEXT) ) - { -- svm_intercept_msr(v, MSR_AMD64_DR0_ADDRESS_MASK, MSR_INTERCEPT_NONE); -- svm_intercept_msr(v, MSR_AMD64_DR1_ADDRESS_MASK, MSR_INTERCEPT_NONE); -- svm_intercept_msr(v, MSR_AMD64_DR2_ADDRESS_MASK, MSR_INTERCEPT_NONE); -- svm_intercept_msr(v, MSR_AMD64_DR3_ADDRESS_MASK, MSR_INTERCEPT_NONE); -- - wrmsrl(MSR_AMD64_DR0_ADDRESS_MASK, v->arch.msrs->dr_mask[0]); - wrmsrl(MSR_AMD64_DR1_ADDRESS_MASK, v->arch.msrs->dr_mask[1]); - wrmsrl(MSR_AMD64_DR2_ADDRESS_MASK, v->arch.msrs->dr_mask[2]); - wrmsrl(MSR_AMD64_DR3_ADDRESS_MASK, v->arch.msrs->dr_mask[3]); -+ -+ if ( v->domain->arch.cpuid->extd.dbext ) -+ { -+ svm_intercept_msr(v, MSR_AMD64_DR0_ADDRESS_MASK, MSR_INTERCEPT_NONE); -+ svm_intercept_msr(v, MSR_AMD64_DR1_ADDRESS_MASK, MSR_INTERCEPT_NONE); -+ svm_intercept_msr(v, MSR_AMD64_DR2_ADDRESS_MASK, MSR_INTERCEPT_NONE); -+ svm_intercept_msr(v, MSR_AMD64_DR3_ADDRESS_MASK, MSR_INTERCEPT_NONE); -+ } - } - - write_debugreg(0, v->arch.dr[0]); -diff --git a/xen/arch/x86/traps.c b/xen/arch/x86/traps.c -index e65cc60041..06c4f3868b 100644 ---- a/xen/arch/x86/traps.c -+++ b/xen/arch/x86/traps.c -@@ -2281,6 +2281,11 @@ void activate_debugregs(const struct vcpu *curr) - if ( curr->arch.dr7 & DR7_ACTIVE_MASK ) - write_debugreg(7, curr->arch.dr7); - -+ /* -+ * Both the PV and HVM paths leave stale DR_MASK values in hardware on -+ * context-switch-out. If we're activating %dr7 for the guest, we must -+ * sync the DR_MASKs too, whether or not the guest can see them. -+ */ - if ( boot_cpu_has(X86_FEATURE_DBEXT) ) - { - wrmsrl(MSR_AMD64_DR0_ADDRESS_MASK, curr->arch.msrs->dr_mask[0]); --- -2.42.0 - |