Skip to content

Commit 6c7c620

Browse files
ashkalrasean-jc
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 <[email protected]> Signed-off-by: Ashish Kalra <[email protected]> Co-developed-by: Sean Christopherson <[email protected]> Link: https://lore.kernel.org/r/95abc49edfde36d4fb791570ea2a4be6ad95fd0d.1755721927.git.ashish.kalra@amd.com Signed-off-by: Sean Christopherson <[email protected]>
1 parent d7fc7d9 commit 6c7c620

File tree

2 files changed

+52
-1
lines changed

2 files changed

+52
-1
lines changed

Documentation/admin-guide/kernel-parameters.txt

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

2960+
kvm-amd.ciphertext_hiding_asids=
2961+
[KVM,AMD] Ciphertext hiding prevents disallowed accesses
2962+
to SNP private memory from reading ciphertext. Instead,
2963+
reads will see constant default values (0xff).
2964+
2965+
If ciphertext hiding is enabled, the joint SEV-ES and
2966+
SEV-SNP ASID space is partitioned into separate SEV-ES
2967+
and SEV-SNP ASID ranges, with the SEV-SNP range being
2968+
[1..max_snp_asid] and the SEV-ES range being
2969+
(max_snp_asid..min_sev_asid), where min_sev_asid is
2970+
enumerated by CPUID.0x.8000_001F[EDX].
2971+
2972+
A non-zero value enables SEV-SNP ciphertext hiding and
2973+
adjusts the ASID ranges for SEV-ES and SEV-SNP guests.
2974+
KVM caps the number of SEV-SNP ASIDs at the maximum
2975+
possible value, e.g. specifying -1u will assign all
2976+
joint SEV-ES and SEV-SNP ASIDs to SEV-SNP. Note,
2977+
assigning all joint ASIDs to SEV-SNP, i.e. configuring
2978+
max_snp_asid == min_sev_asid-1, will effectively make
2979+
SEV-ES unusable.
2980+
29602981
kvm-arm.mode=
29612982
[KVM,ARM,EARLY] Select one of KVM/arm64's modes of
29622983
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
@@ -201,6 +204,9 @@ static int sev_asid_new(struct kvm_sev_info *sev, unsigned long vm_type)
201204
/*
202205
* The min ASID can end up larger than the max if basic SEV support is
203206
* effectively disabled by disallowing use of ASIDs for SEV guests.
207+
* Similarly for SEV-ES guests the min ASID can end up larger than the
208+
* max when ciphertext hiding is enabled, effectively disabling SEV-ES
209+
* support.
204210
*/
205211
if (min_asid > max_asid)
206212
return -ENOTTY;
@@ -3068,10 +3074,32 @@ void __init sev_hardware_setup(void)
30683074
out:
30693075
if (sev_enabled) {
30703076
init_args.probe = true;
3077+
3078+
if (sev_is_snp_ciphertext_hiding_supported())
3079+
init_args.max_snp_asid = min(nr_ciphertext_hiding_asids,
3080+
min_sev_asid - 1);
3081+
30713082
if (sev_platform_init(&init_args))
30723083
sev_supported = sev_es_supported = sev_snp_supported = false;
30733084
else if (sev_snp_supported)
30743085
sev_snp_supported = is_sev_snp_initialized();
3086+
3087+
if (sev_snp_supported)
3088+
nr_ciphertext_hiding_asids = init_args.max_snp_asid;
3089+
3090+
/*
3091+
* If ciphertext hiding is enabled, the joint SEV-ES/SEV-SNP
3092+
* ASID range is partitioned into separate SEV-ES and SEV-SNP
3093+
* ASID ranges, with the SEV-SNP range being [1..max_snp_asid]
3094+
* and the SEV-ES range being (max_snp_asid..max_sev_es_asid].
3095+
* Note, SEV-ES may effectively be disabled if all ASIDs from
3096+
* the joint range are assigned to SEV-SNP.
3097+
*/
3098+
if (nr_ciphertext_hiding_asids) {
3099+
max_snp_asid = nr_ciphertext_hiding_asids;
3100+
min_sev_es_asid = max_snp_asid + 1;
3101+
pr_info("SEV-SNP ciphertext hiding enabled\n");
3102+
}
30753103
}
30763104

30773105
if (boot_cpu_has(X86_FEATURE_SEV))
@@ -3082,7 +3110,9 @@ void __init sev_hardware_setup(void)
30823110
min_sev_asid, max_sev_asid);
30833111
if (boot_cpu_has(X86_FEATURE_SEV_ES))
30843112
pr_info("SEV-ES %s (ASIDs %u - %u)\n",
3085-
str_enabled_disabled(sev_es_supported),
3113+
sev_es_supported ? min_sev_es_asid <= max_sev_es_asid ? "enabled" :
3114+
"unusable" :
3115+
"disabled",
30863116
min_sev_es_asid, max_sev_es_asid);
30873117
if (boot_cpu_has(X86_FEATURE_SEV_SNP))
30883118
pr_info("SEV-SNP %s (ASIDs %u - %u)\n",

0 commit comments

Comments
 (0)