diff options
| author | Michael Roth <michael.roth@amd.com> | 2022-02-24 10:56:18 -0600 |
|---|---|---|
| committer | Borislav Petkov <bp@suse.de> | 2022-04-07 16:47:11 +0200 |
| commit | b190a043c49af4587f5e157053f909192820522a (patch) | |
| tree | 1cb7b0e4fe544e2d9506fe8bad441bd535eea461 /arch/x86/kernel/sev.c | |
| parent | 76f61e1e89b32f3e5d639f1b57413a919066da06 (diff) | |
| download | linux-b190a043c49af4587f5e157053f909192820522a.tar.gz linux-b190a043c49af4587f5e157053f909192820522a.tar.bz2 linux-b190a043c49af4587f5e157053f909192820522a.zip | |
x86/sev: Add SEV-SNP feature detection/setup
Initial/preliminary detection of SEV-SNP is done via the Confidential
Computing blob. Check for it prior to the normal SEV/SME feature
initialization, and add some sanity checks to confirm it agrees with
SEV-SNP CPUID/MSR bits.
Signed-off-by: Michael Roth <michael.roth@amd.com>
Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
Signed-off-by: Borislav Petkov <bp@suse.de>
Link: https://lore.kernel.org/r/20220307213356.2797205-39-brijesh.singh@amd.com
Diffstat (limited to 'arch/x86/kernel/sev.c')
| -rw-r--r-- | arch/x86/kernel/sev.c | 64 |
1 files changed, 64 insertions, 0 deletions
diff --git a/arch/x86/kernel/sev.c b/arch/x86/kernel/sev.c index 0c2bf39c4a8f..692da7b29127 100644 --- a/arch/x86/kernel/sev.c +++ b/arch/x86/kernel/sev.c @@ -1974,3 +1974,67 @@ fail: while (true) halt(); } + +/* + * Initial set up of SNP relies on information provided by the + * Confidential Computing blob, which can be passed to the kernel + * in the following ways, depending on how it is booted: + * + * - when booted via the boot/decompress kernel: + * - via boot_params + * + * - when booted directly by firmware/bootloader (e.g. CONFIG_PVH): + * - via a setup_data entry, as defined by the Linux Boot Protocol + * + * Scan for the blob in that order. + */ +static __init struct cc_blob_sev_info *find_cc_blob(struct boot_params *bp) +{ + struct cc_blob_sev_info *cc_info; + + /* Boot kernel would have passed the CC blob via boot_params. */ + if (bp->cc_blob_address) { + cc_info = (struct cc_blob_sev_info *)(unsigned long)bp->cc_blob_address; + goto found_cc_info; + } + + /* + * If kernel was booted directly, without the use of the + * boot/decompression kernel, the CC blob may have been passed via + * setup_data instead. + */ + cc_info = find_cc_blob_setup_data(bp); + if (!cc_info) + return NULL; + +found_cc_info: + if (cc_info->magic != CC_BLOB_SEV_HDR_MAGIC) + snp_abort(); + + return cc_info; +} + +bool __init snp_init(struct boot_params *bp) +{ + struct cc_blob_sev_info *cc_info; + + if (!bp) + return false; + + cc_info = find_cc_blob(bp); + if (!cc_info) + return false; + + /* + * The CC blob will be used later to access the secrets page. Cache + * it here like the boot kernel does. + */ + bp->cc_blob_address = (u32)(unsigned long)cc_info; + + return true; +} + +void __init snp_abort(void) +{ + sev_es_terminate(SEV_TERM_SET_GEN, GHCB_SNP_UNSUPPORTED); +} |
