Skip to content

Commit 964bbdf

Browse files
committed
Merge tag 'x86_sev_for_v6.10_rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull x86 SEV updates from Borislav Petkov: - Small cleanups and improvements * tag 'x86_sev_for_v6.10_rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: x86/sev: Make the VMPL0 checking more straight forward x86/sev: Rename snp_init() in boot/compressed/sev.c x86/sev: Shorten struct name snp_secrets_page_layout to snp_secrets_page
2 parents a1907cc + e2f4c8c commit 964bbdf

File tree

4 files changed

+113
-120
lines changed

4 files changed

+113
-120
lines changed

arch/x86/boot/compressed/sev.c

Lines changed: 95 additions & 102 deletions
Original file line numberDiff line numberDiff line change
@@ -335,26 +335,6 @@ void do_boot_stage2_vc(struct pt_regs *regs, unsigned long exit_code)
335335
sev_es_terminate(SEV_TERM_SET_GEN, GHCB_SEV_ES_GEN_REQ);
336336
}
337337

338-
static void enforce_vmpl0(void)
339-
{
340-
u64 attrs;
341-
int err;
342-
343-
/*
344-
* RMPADJUST modifies RMP permissions of a lesser-privileged (numerically
345-
* higher) privilege level. Here, clear the VMPL1 permission mask of the
346-
* GHCB page. If the guest is not running at VMPL0, this will fail.
347-
*
348-
* If the guest is running at VMPL0, it will succeed. Even if that operation
349-
* modifies permission bits, it is still ok to do so currently because Linux
350-
* SNP guests are supported only on VMPL0 so VMPL1 or higher permission masks
351-
* changing is a don't-care.
352-
*/
353-
attrs = 1;
354-
if (rmpadjust((unsigned long)&boot_ghcb_page, RMP_PG_SIZE_4K, attrs))
355-
sev_es_terminate(SEV_TERM_SET_LINUX, GHCB_TERM_NOT_VMPL0);
356-
}
357-
358338
/*
359339
* SNP_FEATURES_IMPL_REQ is the mask of SNP features that will need
360340
* guest side implementation for proper functioning of the guest. If any
@@ -413,6 +393,85 @@ void snp_check_features(void)
413393
}
414394
}
415395

396+
/* Search for Confidential Computing blob in the EFI config table. */
397+
static struct cc_blob_sev_info *find_cc_blob_efi(struct boot_params *bp)
398+
{
399+
unsigned long cfg_table_pa;
400+
unsigned int cfg_table_len;
401+
int ret;
402+
403+
ret = efi_get_conf_table(bp, &cfg_table_pa, &cfg_table_len);
404+
if (ret)
405+
return NULL;
406+
407+
return (struct cc_blob_sev_info *)efi_find_vendor_table(bp, cfg_table_pa,
408+
cfg_table_len,
409+
EFI_CC_BLOB_GUID);
410+
}
411+
412+
/*
413+
* Initial set up of SNP relies on information provided by the
414+
* Confidential Computing blob, which can be passed to the boot kernel
415+
* by firmware/bootloader in the following ways:
416+
*
417+
* - via an entry in the EFI config table
418+
* - via a setup_data structure, as defined by the Linux Boot Protocol
419+
*
420+
* Scan for the blob in that order.
421+
*/
422+
static struct cc_blob_sev_info *find_cc_blob(struct boot_params *bp)
423+
{
424+
struct cc_blob_sev_info *cc_info;
425+
426+
cc_info = find_cc_blob_efi(bp);
427+
if (cc_info)
428+
goto found_cc_info;
429+
430+
cc_info = find_cc_blob_setup_data(bp);
431+
if (!cc_info)
432+
return NULL;
433+
434+
found_cc_info:
435+
if (cc_info->magic != CC_BLOB_SEV_HDR_MAGIC)
436+
sev_es_terminate(SEV_TERM_SET_GEN, GHCB_SNP_UNSUPPORTED);
437+
438+
return cc_info;
439+
}
440+
441+
/*
442+
* Indicate SNP based on presence of SNP-specific CC blob. Subsequent checks
443+
* will verify the SNP CPUID/MSR bits.
444+
*/
445+
static bool early_snp_init(struct boot_params *bp)
446+
{
447+
struct cc_blob_sev_info *cc_info;
448+
449+
if (!bp)
450+
return false;
451+
452+
cc_info = find_cc_blob(bp);
453+
if (!cc_info)
454+
return false;
455+
456+
/*
457+
* If a SNP-specific Confidential Computing blob is present, then
458+
* firmware/bootloader have indicated SNP support. Verifying this
459+
* involves CPUID checks which will be more reliable if the SNP
460+
* CPUID table is used. See comments over snp_setup_cpuid_table() for
461+
* more details.
462+
*/
463+
setup_cpuid_table(cc_info);
464+
465+
/*
466+
* Pass run-time kernel a pointer to CC info via boot_params so EFI
467+
* config table doesn't need to be searched again during early startup
468+
* phase.
469+
*/
470+
bp->cc_blob_address = (u32)(unsigned long)cc_info;
471+
472+
return true;
473+
}
474+
416475
/*
417476
* sev_check_cpu_support - Check for SEV support in the CPU capabilities
418477
*
@@ -463,7 +522,7 @@ void sev_enable(struct boot_params *bp)
463522
bp->cc_blob_address = 0;
464523

465524
/*
466-
* Do an initial SEV capability check before snp_init() which
525+
* Do an initial SEV capability check before early_snp_init() which
467526
* loads the CPUID page and the same checks afterwards are done
468527
* without the hypervisor and are trustworthy.
469528
*
@@ -478,7 +537,7 @@ void sev_enable(struct boot_params *bp)
478537
* Setup/preliminary detection of SNP. This will be sanity-checked
479538
* against CPUID/MSR values later.
480539
*/
481-
snp = snp_init(bp);
540+
snp = early_snp_init(bp);
482541

483542
/* Now repeat the checks with the SNP CPUID table. */
484543

@@ -509,7 +568,20 @@ void sev_enable(struct boot_params *bp)
509568
if (!(get_hv_features() & GHCB_HV_FT_SNP))
510569
sev_es_terminate(SEV_TERM_SET_GEN, GHCB_SNP_UNSUPPORTED);
511570

512-
enforce_vmpl0();
571+
/*
572+
* Enforce running at VMPL0.
573+
*
574+
* RMPADJUST modifies RMP permissions of a lesser-privileged (numerically
575+
* higher) privilege level. Here, clear the VMPL1 permission mask of the
576+
* GHCB page. If the guest is not running at VMPL0, this will fail.
577+
*
578+
* If the guest is running at VMPL0, it will succeed. Even if that operation
579+
* modifies permission bits, it is still ok to do so currently because Linux
580+
* SNP guests running at VMPL0 only run at VMPL0, so VMPL1 or higher
581+
* permission mask changes are a don't-care.
582+
*/
583+
if (rmpadjust((unsigned long)&boot_ghcb_page, RMP_PG_SIZE_4K, 1))
584+
sev_es_terminate(SEV_TERM_SET_LINUX, GHCB_TERM_NOT_VMPL0);
513585
}
514586

515587
if (snp && !(sev_status & MSR_AMD64_SEV_SNP_ENABLED))
@@ -535,85 +607,6 @@ u64 sev_get_status(void)
535607
return m.q;
536608
}
537609

538-
/* Search for Confidential Computing blob in the EFI config table. */
539-
static struct cc_blob_sev_info *find_cc_blob_efi(struct boot_params *bp)
540-
{
541-
unsigned long cfg_table_pa;
542-
unsigned int cfg_table_len;
543-
int ret;
544-
545-
ret = efi_get_conf_table(bp, &cfg_table_pa, &cfg_table_len);
546-
if (ret)
547-
return NULL;
548-
549-
return (struct cc_blob_sev_info *)efi_find_vendor_table(bp, cfg_table_pa,
550-
cfg_table_len,
551-
EFI_CC_BLOB_GUID);
552-
}
553-
554-
/*
555-
* Initial set up of SNP relies on information provided by the
556-
* Confidential Computing blob, which can be passed to the boot kernel
557-
* by firmware/bootloader in the following ways:
558-
*
559-
* - via an entry in the EFI config table
560-
* - via a setup_data structure, as defined by the Linux Boot Protocol
561-
*
562-
* Scan for the blob in that order.
563-
*/
564-
static struct cc_blob_sev_info *find_cc_blob(struct boot_params *bp)
565-
{
566-
struct cc_blob_sev_info *cc_info;
567-
568-
cc_info = find_cc_blob_efi(bp);
569-
if (cc_info)
570-
goto found_cc_info;
571-
572-
cc_info = find_cc_blob_setup_data(bp);
573-
if (!cc_info)
574-
return NULL;
575-
576-
found_cc_info:
577-
if (cc_info->magic != CC_BLOB_SEV_HDR_MAGIC)
578-
sev_es_terminate(SEV_TERM_SET_GEN, GHCB_SNP_UNSUPPORTED);
579-
580-
return cc_info;
581-
}
582-
583-
/*
584-
* Indicate SNP based on presence of SNP-specific CC blob. Subsequent checks
585-
* will verify the SNP CPUID/MSR bits.
586-
*/
587-
bool snp_init(struct boot_params *bp)
588-
{
589-
struct cc_blob_sev_info *cc_info;
590-
591-
if (!bp)
592-
return false;
593-
594-
cc_info = find_cc_blob(bp);
595-
if (!cc_info)
596-
return false;
597-
598-
/*
599-
* If a SNP-specific Confidential Computing blob is present, then
600-
* firmware/bootloader have indicated SNP support. Verifying this
601-
* involves CPUID checks which will be more reliable if the SNP
602-
* CPUID table is used. See comments over snp_setup_cpuid_table() for
603-
* more details.
604-
*/
605-
setup_cpuid_table(cc_info);
606-
607-
/*
608-
* Pass run-time kernel a pointer to CC info via boot_params so EFI
609-
* config table doesn't need to be searched again during early startup
610-
* phase.
611-
*/
612-
bp->cc_blob_address = (u32)(unsigned long)cc_info;
613-
614-
return true;
615-
}
616-
617610
void sev_prep_identity_maps(unsigned long top_level_pgt)
618611
{
619612
/*

arch/x86/include/asm/sev.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ struct secrets_os_area {
140140
#define VMPCK_KEY_LEN 32
141141

142142
/* See the SNP spec version 0.9 for secrets page format */
143-
struct snp_secrets_page_layout {
143+
struct snp_secrets_page {
144144
u32 version;
145145
u32 imien : 1,
146146
rsvd1 : 31;

arch/x86/kernel/sev.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -648,7 +648,7 @@ static u64 __init get_secrets_page(void)
648648

649649
static u64 __init get_snp_jump_table_addr(void)
650650
{
651-
struct snp_secrets_page_layout *layout;
651+
struct snp_secrets_page *secrets;
652652
void __iomem *mem;
653653
u64 pa, addr;
654654

@@ -662,9 +662,9 @@ static u64 __init get_snp_jump_table_addr(void)
662662
return 0;
663663
}
664664

665-
layout = (__force struct snp_secrets_page_layout *)mem;
665+
secrets = (__force struct snp_secrets_page *)mem;
666666

667-
addr = layout->os_area.ap_jump_table_pa;
667+
addr = secrets->os_area.ap_jump_table_pa;
668668
iounmap(mem);
669669

670670
return addr;

drivers/virt/coco/sev-guest/sev-guest.c

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ struct snp_guest_dev {
5959
*/
6060
struct snp_guest_msg secret_request, secret_response;
6161

62-
struct snp_secrets_page_layout *layout;
62+
struct snp_secrets_page *secrets;
6363
struct snp_req_data input;
6464
union {
6565
struct snp_report_req report;
@@ -743,26 +743,26 @@ static const struct file_operations snp_guest_fops = {
743743
.unlocked_ioctl = snp_guest_ioctl,
744744
};
745745

746-
static u8 *get_vmpck(int id, struct snp_secrets_page_layout *layout, u32 **seqno)
746+
static u8 *get_vmpck(int id, struct snp_secrets_page *secrets, u32 **seqno)
747747
{
748748
u8 *key = NULL;
749749

750750
switch (id) {
751751
case 0:
752-
*seqno = &layout->os_area.msg_seqno_0;
753-
key = layout->vmpck0;
752+
*seqno = &secrets->os_area.msg_seqno_0;
753+
key = secrets->vmpck0;
754754
break;
755755
case 1:
756-
*seqno = &layout->os_area.msg_seqno_1;
757-
key = layout->vmpck1;
756+
*seqno = &secrets->os_area.msg_seqno_1;
757+
key = secrets->vmpck1;
758758
break;
759759
case 2:
760-
*seqno = &layout->os_area.msg_seqno_2;
761-
key = layout->vmpck2;
760+
*seqno = &secrets->os_area.msg_seqno_2;
761+
key = secrets->vmpck2;
762762
break;
763763
case 3:
764-
*seqno = &layout->os_area.msg_seqno_3;
765-
key = layout->vmpck3;
764+
*seqno = &secrets->os_area.msg_seqno_3;
765+
key = secrets->vmpck3;
766766
break;
767767
default:
768768
break;
@@ -897,8 +897,8 @@ static void unregister_sev_tsm(void *data)
897897

898898
static int __init sev_guest_probe(struct platform_device *pdev)
899899
{
900-
struct snp_secrets_page_layout *layout;
901900
struct sev_guest_platform_data *data;
901+
struct snp_secrets_page *secrets;
902902
struct device *dev = &pdev->dev;
903903
struct snp_guest_dev *snp_dev;
904904
struct miscdevice *misc;
@@ -916,15 +916,15 @@ static int __init sev_guest_probe(struct platform_device *pdev)
916916
if (!mapping)
917917
return -ENODEV;
918918

919-
layout = (__force void *)mapping;
919+
secrets = (__force void *)mapping;
920920

921921
ret = -ENOMEM;
922922
snp_dev = devm_kzalloc(&pdev->dev, sizeof(struct snp_guest_dev), GFP_KERNEL);
923923
if (!snp_dev)
924924
goto e_unmap;
925925

926926
ret = -EINVAL;
927-
snp_dev->vmpck = get_vmpck(vmpck_id, layout, &snp_dev->os_area_msg_seqno);
927+
snp_dev->vmpck = get_vmpck(vmpck_id, secrets, &snp_dev->os_area_msg_seqno);
928928
if (!snp_dev->vmpck) {
929929
dev_err(dev, "invalid vmpck id %d\n", vmpck_id);
930930
goto e_unmap;
@@ -938,7 +938,7 @@ static int __init sev_guest_probe(struct platform_device *pdev)
938938

939939
platform_set_drvdata(pdev, snp_dev);
940940
snp_dev->dev = dev;
941-
snp_dev->layout = layout;
941+
snp_dev->secrets = secrets;
942942

943943
/* Allocate the shared page used for the request and response message. */
944944
snp_dev->request = alloc_shared_pages(dev, sizeof(struct snp_guest_msg));

0 commit comments

Comments
 (0)