* [PATCH v8 1/2] KVM: SEV: Introduce new min,max sev_es and sev_snp asid variables
2025-08-20 14:50 [PATCH v8 0/2] Add SEV-SNP CipherTextHiding feature support Ashish Kalra
@ 2025-08-20 14:51 ` Ashish Kalra
2025-08-20 14:51 ` [PATCH v8 2/2] KVM: SEV: Add SEV-SNP CipherTextHiding support Ashish Kalra
1 sibling, 0 replies; 4+ messages in thread
From: Ashish Kalra @ 2025-08-20 14:51 UTC (permalink / raw)
To: corbet, seanjc, pbonzini, tglx, mingo, bp, dave.hansen, x86, hpa,
thomas.lendacky, herbert
Cc: akpm, rostedt, paulmck, michael.roth, linux-doc, kvm
From: Ashish Kalra <ashish.kalra@amd.com>
Introduce new min, max sev_es_asid and sev_snp_asid variables.
The new {min,max}_{sev_es,snp}_asid variables along with existing
{min,max}_sev_asid variable simplifies partitioning of the
SEV and SEV-ES+ ASID space.
Suggested-by: Sean Christopherson <seanjc@google.com>
Reviewed-by: Tom Lendacky <thomas.lendacky@amd.com>
Signed-off-by: Ashish Kalra <ashish.kalra@amd.com>
---
arch/x86/kvm/svm/sev.c | 36 +++++++++++++++++++++++++++---------
1 file changed, 27 insertions(+), 9 deletions(-)
diff --git a/arch/x86/kvm/svm/sev.c b/arch/x86/kvm/svm/sev.c
index 0635bd71c10e..cd9ce100627e 100644
--- a/arch/x86/kvm/svm/sev.c
+++ b/arch/x86/kvm/svm/sev.c
@@ -85,6 +85,10 @@ static DECLARE_RWSEM(sev_deactivate_lock);
static DEFINE_MUTEX(sev_bitmap_lock);
unsigned int max_sev_asid;
static unsigned int min_sev_asid;
+static unsigned int max_sev_es_asid;
+static unsigned int min_sev_es_asid;
+static unsigned int max_snp_asid;
+static unsigned int min_snp_asid;
static unsigned long sev_me_mask;
static unsigned int nr_asids;
static unsigned long *sev_asid_bitmap;
@@ -173,20 +177,31 @@ static void sev_misc_cg_uncharge(struct kvm_sev_info *sev)
misc_cg_uncharge(type, sev->misc_cg, 1);
}
-static int sev_asid_new(struct kvm_sev_info *sev)
+static int sev_asid_new(struct kvm_sev_info *sev, unsigned long vm_type)
{
/*
* SEV-enabled guests must use asid from min_sev_asid to max_sev_asid.
* SEV-ES-enabled guest can use from 1 to min_sev_asid - 1.
- * Note: min ASID can end up larger than the max if basic SEV support is
- * effectively disabled by disallowing use of ASIDs for SEV guests.
*/
- unsigned int min_asid = sev->es_active ? 1 : min_sev_asid;
- unsigned int max_asid = sev->es_active ? min_sev_asid - 1 : max_sev_asid;
- unsigned int asid;
+ unsigned int min_asid, max_asid, asid;
bool retry = true;
int ret;
+ if (vm_type == KVM_X86_SNP_VM) {
+ min_asid = min_snp_asid;
+ max_asid = max_snp_asid;
+ } else if (sev->es_active) {
+ min_asid = min_sev_es_asid;
+ max_asid = max_sev_es_asid;
+ } else {
+ min_asid = min_sev_asid;
+ max_asid = max_sev_asid;
+ }
+
+ /*
+ * The min ASID can end up larger than the max if basic SEV support is
+ * effectively disabled by disallowing use of ASIDs for SEV guests.
+ */
if (min_asid > max_asid)
return -ENOTTY;
@@ -440,7 +455,7 @@ static int __sev_guest_init(struct kvm *kvm, struct kvm_sev_cmd *argp,
if (vm_type == KVM_X86_SNP_VM)
sev->vmsa_features |= SVM_SEV_FEAT_SNP_ACTIVE;
- ret = sev_asid_new(sev);
+ ret = sev_asid_new(sev, vm_type);
if (ret)
goto e_no_asid;
@@ -3038,6 +3053,9 @@ void __init sev_hardware_setup(void)
if (min_sev_asid == 1)
goto out;
+ min_sev_es_asid = min_snp_asid = 1;
+ max_sev_es_asid = max_snp_asid = min_sev_asid - 1;
+
sev_es_asid_count = min_sev_asid - 1;
WARN_ON_ONCE(misc_cg_set_capacity(MISC_CG_RES_SEV_ES, sev_es_asid_count));
sev_es_supported = true;
@@ -3061,11 +3079,11 @@ void __init sev_hardware_setup(void)
if (boot_cpu_has(X86_FEATURE_SEV_ES))
pr_info("SEV-ES %s (ASIDs %u - %u)\n",
str_enabled_disabled(sev_es_supported),
- min_sev_asid > 1 ? 1 : 0, min_sev_asid - 1);
+ min_sev_es_asid, max_sev_es_asid);
if (boot_cpu_has(X86_FEATURE_SEV_SNP))
pr_info("SEV-SNP %s (ASIDs %u - %u)\n",
str_enabled_disabled(sev_snp_supported),
- min_sev_asid > 1 ? 1 : 0, min_sev_asid - 1);
+ min_snp_asid, max_snp_asid);
sev_enabled = sev_supported;
sev_es_enabled = sev_es_supported;
--
2.34.1
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH v8 2/2] KVM: SEV: Add SEV-SNP CipherTextHiding support
2025-08-20 14:50 [PATCH v8 0/2] Add SEV-SNP CipherTextHiding feature support Ashish Kalra
2025-08-20 14:51 ` [PATCH v8 1/2] KVM: SEV: Introduce new min,max sev_es and sev_snp asid variables Ashish Kalra
@ 2025-08-20 14:51 ` Ashish Kalra
2025-08-20 14:58 ` Sean Christopherson
1 sibling, 1 reply; 4+ messages in thread
From: Ashish Kalra @ 2025-08-20 14:51 UTC (permalink / raw)
To: corbet, seanjc, pbonzini, tglx, mingo, bp, dave.hansen, x86, hpa,
thomas.lendacky, herbert
Cc: akpm, rostedt, paulmck, michael.roth, linux-doc, kvm
From: Ashish Kalra <ashish.kalra@amd.com>
Ciphertext hiding prevents host accesses from reading the ciphertext of
SNP guest private memory. Instead of reading ciphertext, the host reads
will see constant default values (0xff).
The SEV ASID space is split into SEV and SEV-ES/SEV-SNP ASID ranges.
Enabling ciphertext hiding further splits the SEV-ES/SEV-SNP ASID space
into separate ASID ranges for SEV-ES and SEV-SNP guests.
Add new module parameter to the KVM module to enable ciphertext hiding
support and a user configurable system-wide maximum SNP ASID value. If
the module parameter value is '-1' then the complete SEV-ES/SEV-SNP
ASID space is allocated to SEV-SNP guests.
Suggested-by: Sean Christopherson <seanjc@google.com>
Signed-off-by: Ashish Kalra <ashish.kalra@amd.com>
---
.../admin-guide/kernel-parameters.txt | 18 ++++++++
arch/x86/kvm/svm/sev.c | 44 ++++++++++++++++++-
2 files changed, 61 insertions(+), 1 deletion(-)
diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
index 729728280438..403fb346fc85 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -2957,6 +2957,24 @@
(enabled). Disable by KVM if hardware lacks support
for NPT.
+ kvm-amd.ciphertext_hiding_asids=
+ [KVM,AMD] Ciphertext hiding prevents host accesses from reading
+ the ciphertext of SNP guest private memory. Instead of reading
+ ciphertext, the host will see constant default values (0xff).
+ The SEV ASID space is split into SEV and joint SEV-ES and SEV-SNP
+ ASID space. Ciphertext hiding further partitions the joint
+ SEV-ES/SEV-SNP ASID space into separate SEV-ES and SEV-SNP ASID
+ ranges with the SEV-SNP ASID range starting at 1. For SEV-ES/
+ SEV-SNP guests the maximum ASID available is MIN_SEV_ASID - 1
+ where MIN_SEV_ASID value is discovered by CPUID Fn8000_001F[EDX].
+
+ Format: { <unsigned int> | -1 }
+ A non-zero value enables SEV-SNP ciphertext hiding feature and sets
+ the ASID range available for SEV-SNP guests.
+ A Value of -1 assigns all ASIDs available in the joint SEV-ES
+ and SEV-SNP ASID range to SNP guests, effectively disabling
+ SEV-ES.
+
kvm-arm.mode=
[KVM,ARM,EARLY] Select one of KVM/arm64's modes of
operation.
diff --git a/arch/x86/kvm/svm/sev.c b/arch/x86/kvm/svm/sev.c
index cd9ce100627e..d3a3d017b361 100644
--- a/arch/x86/kvm/svm/sev.c
+++ b/arch/x86/kvm/svm/sev.c
@@ -59,6 +59,10 @@ static bool sev_es_debug_swap_enabled = true;
module_param_named(debug_swap, sev_es_debug_swap_enabled, bool, 0444);
static u64 sev_supported_vmsa_features;
+static int ciphertext_hiding_asids;
+module_param(ciphertext_hiding_asids, int, 0444);
+MODULE_PARM_DESC(ciphertext_hiding_asids, " Enable ciphertext hiding for SEV-SNP guests and specify the number of ASIDs to use ('-1' to utilize all available SEV-SNP ASIDs");
+
#define AP_RESET_HOLD_NONE 0
#define AP_RESET_HOLD_NAE_EVENT 1
#define AP_RESET_HOLD_MSR_PROTO 2
@@ -201,6 +205,9 @@ static int sev_asid_new(struct kvm_sev_info *sev, unsigned long vm_type)
/*
* The min ASID can end up larger than the max if basic SEV support is
* effectively disabled by disallowing use of ASIDs for SEV guests.
+ * Similarly for SEV-ES guests the min ASID can end up larger than the
+ * max when ciphertext hiding is enabled, effectively disabling SEV-ES
+ * support.
*/
if (min_asid > max_asid)
return -ENOTTY;
@@ -2955,6 +2962,32 @@ static bool is_sev_snp_initialized(void)
return initialized;
}
+static bool check_and_enable_sev_snp_ciphertext_hiding(void)
+{
+ if (!ciphertext_hiding_asids)
+ return false;
+
+ if (!sev_is_snp_ciphertext_hiding_supported()) {
+ pr_warn("Module parameter ciphertext_hiding_asids specified but ciphertext hiding not supported\n");
+ return false;
+ }
+
+ /* Do sanity check on user-defined ciphertext_hiding_asids */
+ if (ciphertext_hiding_asids == -1) {
+ ciphertext_hiding_asids = min_sev_asid - 1;
+ } else if ((unsigned int)ciphertext_hiding_asids >= min_sev_asid) {
+ pr_warn("Module parameter ciphertext_hiding_asids (%d) invalid or exceeds or equals minimum SEV ASID (%u)\n",
+ ciphertext_hiding_asids, min_sev_asid);
+ return false;
+ }
+
+ max_snp_asid = ciphertext_hiding_asids;
+ min_sev_es_asid = max_snp_asid + 1;
+ pr_info("SEV-SNP ciphertext hiding enabled\n");
+
+ return true;
+}
+
void __init sev_hardware_setup(void)
{
unsigned int eax, ebx, ecx, edx, sev_asid_count, sev_es_asid_count;
@@ -3064,6 +3097,13 @@ void __init sev_hardware_setup(void)
out:
if (sev_enabled) {
init_args.probe = true;
+ /*
+ * The ciphertext hiding feature partitions the joint SEV-ES/SEV-SNP
+ * ASID range into separate SEV-ES and SEV-SNP ASID ranges with
+ * the SEV-SNP ASID starting at 1.
+ */
+ if (check_and_enable_sev_snp_ciphertext_hiding())
+ init_args.max_snp_asid = max_snp_asid;
if (sev_platform_init(&init_args))
sev_supported = sev_es_supported = sev_snp_supported = false;
else if (sev_snp_supported)
@@ -3078,7 +3118,9 @@ void __init sev_hardware_setup(void)
min_sev_asid, max_sev_asid);
if (boot_cpu_has(X86_FEATURE_SEV_ES))
pr_info("SEV-ES %s (ASIDs %u - %u)\n",
- str_enabled_disabled(sev_es_supported),
+ sev_es_supported ? min_sev_es_asid <= max_sev_es_asid ? "enabled" :
+ "unusable" :
+ "disabled",
min_sev_es_asid, max_sev_es_asid);
if (boot_cpu_has(X86_FEATURE_SEV_SNP))
pr_info("SEV-SNP %s (ASIDs %u - %u)\n",
--
2.34.1
^ permalink raw reply related [flat|nested] 4+ messages in thread