Enhanced SMT Protection (ESMTP) protects an SEV-SNP guest from sibling
side channels by requiring that, while a vCPU is in guest mode, its SMT
sibling thread is either idle in host mode or executing a vCPU the guest
has declared to be a legal sibling.

Add an "esmtp" property to request and use it to advertize this feature
for KVM to write it into the launch-time VMSAs.

Sample command-line:
  -object 
sev-snp-guest,id=sev0,policy=0xb0000,cbitpos=51,reduced-phys-bits=1,esmtp=on

Signed-off-by: Pratik R. Sampat <[email protected]>
---
 qapi/qom.json     |  9 ++++++++-
 target/i386/sev.c | 15 +++++++++++++++
 target/i386/sev.h |  1 +
 3 files changed, 24 insertions(+), 1 deletion(-)

diff --git a/qapi/qom.json b/qapi/qom.json
index 4a9b7f908844..010c5cc2bb82 100644
--- a/qapi/qom.json
+++ b/qapi/qom.json
@@ -1119,6 +1119,12 @@
 # @tsc-frequency: set secure TSC frequency.  Only valid if Secure TSC
 #     is enabled (default: zero) (since 11.1)
 #
+# @esmtp: Enable Enhanced SMT Protection support for the guest.  Adds
+#     corresponding VMSA feature bit to KVM_SEV_INIT2 vmsa_features so
+#     the host applies it to each vCPU's VMSA.  Opt-in feature as it
+#     provides additional protection but with runtime overhead.
+#     (default: false) (since 11.2)
+#
 # Since: 9.1
 ##
 { 'struct': 'SevSnpGuestProperties',
@@ -1132,7 +1138,8 @@
             '*host-data': 'str',
             '*vcek-disabled': 'bool',
             '*secure-tsc': 'bool',
-            '*tsc-frequency': 'uint32' } }
+            '*tsc-frequency': 'uint32',
+            '*esmtp': 'bool' } }
 
 ##
 # @TdxGuestProperties:
diff --git a/target/i386/sev.c b/target/i386/sev.c
index cc16c6b07123..0b5767057175 100644
--- a/target/i386/sev.c
+++ b/target/i386/sev.c
@@ -3255,6 +3255,18 @@ sev_snp_guest_set_tsc_frequency(Object *obj, Visitor *v, 
const char *name,
     SEV_SNP_GUEST(obj)->tsc_khz = value / 1000;
 }
 
+static bool
+sev_snp_guest_get_esmtp(Object *obj, Error **errp)
+{
+    return is_sev_feature_set(SEV_COMMON(obj), SVM_SEV_FEAT_ESMTP);
+}
+
+static void
+sev_snp_guest_set_esmtp(Object *obj, bool value, Error **errp)
+{
+    sev_set_feature(SEV_COMMON(obj), SVM_SEV_FEAT_ESMTP, value);
+}
+
 static void
 sev_snp_guest_class_init(ObjectClass *oc, const void *data)
 {
@@ -3296,6 +3308,9 @@ sev_snp_guest_class_init(ObjectClass *oc, const void 
*data)
     object_class_property_add(oc, "tsc-frequency", "uint32",
                               sev_snp_guest_get_tsc_frequency,
                               sev_snp_guest_set_tsc_frequency, NULL, NULL);
+    object_class_property_add_bool(oc, "esmtp",
+                                   sev_snp_guest_get_esmtp,
+                                   sev_snp_guest_set_esmtp);
 }
 
 static void
diff --git a/target/i386/sev.h b/target/i386/sev.h
index 7725f92e1959..6b4128dea4ae 100644
--- a/target/i386/sev.h
+++ b/target/i386/sev.h
@@ -49,6 +49,7 @@ bool sev_snp_enabled(void);
 #define SVM_SEV_FEAT_SNP_ACTIVE     BIT(0)
 #define SVM_SEV_FEAT_DEBUG_SWAP     BIT(5)
 #define SVM_SEV_FEAT_SECURE_TSC     BIT(9)
+#define SVM_SEV_FEAT_ESMTP          BIT(17)
 
 typedef struct SevKernelLoaderContext {
     char *setup_data;
-- 
2.43.0


Reply via email to