#include <asm/pkru.h>
 #include <asm/trapnr.h>
 #include <asm/fpu/xcr.h>
+#include <asm/debugreg.h>
 
 #include "mmu.h"
 #include "x86.h"
 /* enable/disable SEV-ES support */
 static bool sev_es_enabled = true;
 module_param_named(sev_es, sev_es_enabled, bool, 0444);
+
+/* enable/disable SEV-ES DebugSwap support */
+static bool sev_es_debug_swap_enabled = true;
+module_param_named(debug_swap, sev_es_debug_swap_enabled, bool, 0444);
 #else
 #define sev_enabled false
 #define sev_es_enabled false
+#define sev_es_debug_swap_enabled false
 #endif /* CONFIG_KVM_AMD_SEV */
 
 static u8 sev_enc_bit;
        save->xss  = svm->vcpu.arch.ia32_xss;
        save->dr6  = svm->vcpu.arch.dr6;
 
+       if (sev_es_debug_swap_enabled)
+               save->sev_features |= SVM_SEV_FEAT_DEBUG_SWAP;
+
        pr_debug("Virtual Machine Save Area (VMSA):\n");
        print_hex_dump_debug("", DUMP_PREFIX_NONE, 16, 1, save, sizeof(*save), false);
 
 
        sev_enabled = sev_supported;
        sev_es_enabled = sev_es_supported;
+       if (!sev_es_enabled || !cpu_feature_enabled(X86_FEATURE_DEBUG_SWAP) ||
+           !cpu_feature_enabled(X86_FEATURE_NO_NESTED_DATA_BP))
+               sev_es_debug_swap_enabled = false;
 #endif
 }
 
        svm_set_intercept(svm, TRAP_CR8_WRITE);
 
        vmcb->control.intercepts[INTERCEPT_DR] = 0;
-       vmcb_set_intercept(&vmcb->control, INTERCEPT_DR7_READ);
-       vmcb_set_intercept(&vmcb->control, INTERCEPT_DR7_WRITE);
-       recalc_intercepts(svm);
+       if (!sev_es_debug_swap_enabled) {
+               vmcb_set_intercept(&vmcb->control, INTERCEPT_DR7_READ);
+               vmcb_set_intercept(&vmcb->control, INTERCEPT_DR7_WRITE);
+               recalc_intercepts(svm);
+       }
 
        /* Can't intercept XSETBV, HV can't modify XCR0 directly */
        svm_clr_intercept(svm, INTERCEPT_XSETBV);
        hostsa->xcr0 = xgetbv(XCR_XFEATURE_ENABLED_MASK);
        hostsa->pkru = read_pkru();
        hostsa->xss = host_xss;
+
+       /*
+        * If DebugSwap is enabled, debug registers are loaded but NOT saved by
+        * the CPU (Type-B). If DebugSwap is disabled/unsupported, the CPU both
+        * saves and loads debug registers (Type-A).
+        */
+       if (sev_es_debug_swap_enabled) {
+               hostsa->dr0 = native_get_debugreg(0);
+               hostsa->dr1 = native_get_debugreg(1);
+               hostsa->dr2 = native_get_debugreg(2);
+               hostsa->dr3 = native_get_debugreg(3);
+               hostsa->dr0_addr_mask = amd_get_dr_addr_mask(0);
+               hostsa->dr1_addr_mask = amd_get_dr_addr_mask(1);
+               hostsa->dr2_addr_mask = amd_get_dr_addr_mask(2);
+               hostsa->dr3_addr_mask = amd_get_dr_addr_mask(3);
+       }
 }
 
 void sev_vcpu_deliver_sipi_vector(struct kvm_vcpu *vcpu, u8 vector)