@samitouri / QOSamiQemu / commits / 51ac358fde

target/i386: SEV: Add support for enabling debug-swap SEV feature

Add support for enabling debug-swap VMSA SEV feature in SEV-ES and SEV-SNP guests through a new "debug-swap" boolean property on SEV guest objects. Though the boolean property is available for plain SEV guests, check_sev_features() has a check that rejects attempts to enable any SEV feature for a plain SEV guest. Though this SEV feature is called "Debug virtualization" in the APM, KVM calls this "debug swap" so use the same name for consistency. Sample command-line: -machine q35,confidential-guest-support=sev0 \ -object sev-snp-guest,id=sev0,cbitpos=51,reduced-phys-bits=1,debug-swap=on Restrict debug-swap to SEV-SNP guests at this time due to a compatibility issue with SEV-ES pflash devices. Signed-off-by: Naveen N Rao (AMD) <naveen@kernel.org> Link: https://lore.kernel.org/r/416e7b156e49f95958f8c5c8549b48a88c1995fc.1779281646.git.naveen@kernel.org Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>

Naveen N Rao (AMD) committed May 20, 2026 at 18:57 UTC 51ac358fdeab4e84b0ba8a3e38123eba7054e50d
3 files changed +33 -1
qapi/qom.json
+6 -1
@@ -1017,6 +1017,10 @@
1017 # designated guest firmware page for measured boot with -kernel
1018 # (default: false) (since 6.2)
1019 #
1020 +# @debug-swap: enable virtualization of debug registers,
1021 +# only supported on SEV-ES and SEV-SNP guests
1022 +# (default: false) (since 11.1)
1023 +#
1024 # Features:
1025 #
1026 # @confidential-guest-reset: If present, the hypervisor supports
@@ -1028,7 +1032,8 @@
1032 'data': { '*sev-device': 'str',
1033 '*cbitpos': 'uint32',
1034 'reduced-phys-bits': 'uint32',
1031 - '*kernel-hashes': 'bool' },
1035 + '*kernel-hashes': 'bool',
1036 + '*debug-swap': 'bool' },
1037 'features': ['confidential-guest-reset']}
1038
1039 ##
target/i386/sev.c
+26
@@ -324,6 +324,11 @@ sev_set_guest_state(SevCommonState *sev_common, SevState new_state)
324 sev_common->state = new_state;
325 }
326
327 +static bool is_sev_feature_set(SevCommonState *sev_common, uint64_t feature)
328 +{
329 + return !!(sev_common->sev_features & feature);
330 +}
331 +
332 static void sev_set_feature(SevCommonState *sev_common, uint64_t feature, bool set)
333 {
334 if (set) {
@@ -523,6 +528,12 @@ static int check_sev_features(SevCommonState *sev_common, uint64_t sev_features,
528 __func__);
529 return -1;
530 }
531 + if (sev_features && sev_es_enabled() && !sev_snp_enabled()) {
532 + error_setg(errp,
533 + "%s: SEV features are not supported with SEV-ES at this time",
534 + __func__);
535 + return -1;
536 + }
537 if (sev_features && !sev_es_enabled()) {
538 error_setg(errp,
539 "%s: SEV features require either SEV-ES or SEV-SNP to be enabled",
@@ -2797,6 +2808,16 @@ static int cgs_set_guest_policy(ConfidentialGuestPolicyType policy_type,
2808 return 0;
2809 }
2810
2811 +static bool sev_common_get_debug_swap(Object *obj, Error **errp)
2812 +{
2813 + return is_sev_feature_set(SEV_COMMON(obj), SVM_SEV_FEAT_DEBUG_SWAP);
2814 +}
2815 +
2816 +static void sev_common_set_debug_swap(Object *obj, bool value, Error **errp)
2817 +{
2818 + sev_set_feature(SEV_COMMON(obj), SVM_SEV_FEAT_DEBUG_SWAP, value);
2819 +}
2820 +
2821 static void
2822 sev_common_class_init(ObjectClass *oc, const void *data)
2823 {
@@ -2822,6 +2843,11 @@ sev_common_class_init(ObjectClass *oc, const void *data)
2843 sev_common_set_kernel_hashes);
2844 object_class_property_set_description(oc, "kernel-hashes",
2845 "add kernel hashes to guest firmware for measured Linux boot");
2846 + object_class_property_add_bool(oc, "debug-swap",
2847 + sev_common_get_debug_swap,
2848 + sev_common_set_debug_swap);
2849 + object_class_property_set_description(oc, "debug-swap",
2850 + "enable virtualization of debug registers");
2851 }
2852
2853 static void
target/i386/sev.h
+1
@@ -47,6 +47,7 @@ bool sev_snp_enabled(void);
47 #define SEV_SNP_POLICY_DBG 0x80000
48
49 #define SVM_SEV_FEAT_SNP_ACTIVE BIT(0)
50 +#define SVM_SEV_FEAT_DEBUG_SWAP BIT(5)
51
52 typedef struct SevKernelLoaderContext {
53 char *setup_data;