Skip to content

Commit 799613d

Browse files
ashkalramdroth
authored andcommitted
KVM: SEV: Add SEV-SNP CipherTextHiding support
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 a new off-by-default kvm-amd module parameter to enable ciphertext hiding and allow the admin to configure the SEV-ES and SEV-SNP ASID ranges. Simply cap the maximum SEV-SNP ASID as appropriate, i.e. don't reject loading KVM or disable ciphertest hiding for a too-big value, as KVM's general approach for module params is to sanitize inputs based on hardware/kernel support, not burn the world down. This also allows the admin to use -1u to assign all SEV-ES/SNP ASIDs to SNP without needing dedicated handling in KVM. Suggested-by: Sean Christopherson <seanjc@google.com> Signed-off-by: Ashish Kalra <ashish.kalra@amd.com> Co-developed-by: Sean Christopherson <seanjc@google.com> Link: https://lore.kernel.org/r/95abc49edfde36d4fb791570ea2a4be6ad95fd0d.1755721927.git.ashish.kalra@amd.com Signed-off-by: Sean Christopherson <seanjc@google.com> (cherry picked from commit 6c7c620) Signed-off-by: Michael Roth <michael.roth@amd.com>
1 parent 65e2f4f commit 799613d

2 files changed

Lines changed: 52 additions & 1 deletion

File tree

‎Documentation/admin-guide/kernel-parameters.txt‎

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2894,6 +2894,27 @@
28942894
(enabled). Disable by KVM if hardware lacks support
28952895
for NPT.
28962896

2897+
kvm-amd.ciphertext_hiding_asids=
2898+
[KVM,AMD] Ciphertext hiding prevents disallowed accesses
2899+
to SNP private memory from reading ciphertext. Instead,
2900+
reads will see constant default values (0xff).
2901+
2902+
If ciphertext hiding is enabled, the joint SEV-ES and
2903+
SEV-SNP ASID space is partitioned into separate SEV-ES
2904+
and SEV-SNP ASID ranges, with the SEV-SNP range being
2905+
[1..max_snp_asid] and the SEV-ES range being
2906+
(max_snp_asid..min_sev_asid), where min_sev_asid is
2907+
enumerated by CPUID.0x.8000_001F[EDX].
2908+
2909+
A non-zero value enables SEV-SNP ciphertext hiding and
2910+
adjusts the ASID ranges for SEV-ES and SEV-SNP guests.
2911+
KVM caps the number of SEV-SNP ASIDs at the maximum
2912+
possible value, e.g. specifying -1u will assign all
2913+
joint SEV-ES and SEV-SNP ASIDs to SEV-SNP. Note,
2914+
assigning all joint ASIDs to SEV-SNP, i.e. configuring
2915+
max_snp_asid == min_sev_asid-1, will effectively make
2916+
SEV-ES unusable.
2917+
28972918
kvm-arm.mode=
28982919
[KVM,ARM,EARLY] Select one of KVM/arm64's modes of
28992920
operation.

‎arch/x86/kvm/svm/sev.c‎

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,9 @@ static bool sev_es_debug_swap_enabled = true;
5959
module_param_named(debug_swap, sev_es_debug_swap_enabled, bool, 0444);
6060
static u64 sev_supported_vmsa_features;
6161

62+
static unsigned int nr_ciphertext_hiding_asids;
63+
module_param_named(ciphertext_hiding_asids, nr_ciphertext_hiding_asids, uint, 0444);
64+
6265
#define AP_RESET_HOLD_NONE 0
6366
#define AP_RESET_HOLD_NAE_EVENT 1
6467
#define AP_RESET_HOLD_MSR_PROTO 2
@@ -200,6 +203,9 @@ static int sev_asid_new(struct kvm_sev_info *sev, unsigned long vm_type)
200203
/*
201204
* The min ASID can end up larger than the max if basic SEV support is
202205
* effectively disabled by disallowing use of ASIDs for SEV guests.
206+
* Similarly for SEV-ES guests the min ASID can end up larger than the
207+
* max when ciphertext hiding is enabled, effectively disabling SEV-ES
208+
* support.
203209
*/
204210
if (min_asid > max_asid)
205211
return -ENOTTY;
@@ -3029,10 +3035,32 @@ void __init sev_hardware_setup(void)
30293035
out:
30303036
if (sev_enabled) {
30313037
init_args.probe = true;
3038+
3039+
if (sev_is_snp_ciphertext_hiding_supported())
3040+
init_args.max_snp_asid = min(nr_ciphertext_hiding_asids,
3041+
min_sev_asid - 1);
3042+
30323043
if (sev_platform_init(&init_args))
30333044
sev_supported = sev_es_supported = sev_snp_supported = false;
30343045
else if (sev_snp_supported)
30353046
sev_snp_supported = is_sev_snp_initialized();
3047+
3048+
if (sev_snp_supported)
3049+
nr_ciphertext_hiding_asids = init_args.max_snp_asid;
3050+
3051+
/*
3052+
* If ciphertext hiding is enabled, the joint SEV-ES/SEV-SNP
3053+
* ASID range is partitioned into separate SEV-ES and SEV-SNP
3054+
* ASID ranges, with the SEV-SNP range being [1..max_snp_asid]
3055+
* and the SEV-ES range being (max_snp_asid..max_sev_es_asid].
3056+
* Note, SEV-ES may effectively be disabled if all ASIDs from
3057+
* the joint range are assigned to SEV-SNP.
3058+
*/
3059+
if (nr_ciphertext_hiding_asids) {
3060+
max_snp_asid = nr_ciphertext_hiding_asids;
3061+
min_sev_es_asid = max_snp_asid + 1;
3062+
pr_info("SEV-SNP ciphertext hiding enabled\n");
3063+
}
30363064
}
30373065

30383066
if (boot_cpu_has(X86_FEATURE_SEV))
@@ -3043,7 +3071,9 @@ void __init sev_hardware_setup(void)
30433071
min_sev_asid, max_sev_asid);
30443072
if (boot_cpu_has(X86_FEATURE_SEV_ES))
30453073
pr_info("SEV-ES %s (ASIDs %u - %u)\n",
3046-
str_enabled_disabled(sev_es_supported),
3074+
sev_es_supported ? min_sev_es_asid <= max_sev_es_asid ? "enabled" :
3075+
"unusable" :
3076+
"disabled",
30473077
min_sev_es_asid, max_sev_es_asid);
30483078
if (boot_cpu_has(X86_FEATURE_SEV_SNP))
30493079
pr_info("SEV-SNP %s (ASIDs %u - %u)\n",

0 commit comments

Comments
 (0)