* [PATCH v3 0/2] x86/sev: Fix AP Jump Table handling for SNP guests @ 2022-04-22 13:56 Michael Roth 2022-04-22 13:56 ` [PATCH v3 1/2] x86/sev: Add missing __init annotations to SEV init routines Michael Roth 2022-04-22 13:56 ` [PATCH v3 2/2] x86/sev: Get the AP jump table address from secrets page Michael Roth 0 siblings, 2 replies; 8+ messages in thread From: Michael Roth @ 2022-04-22 13:56 UTC (permalink / raw) To: linux-kernel Cc: Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen, x86, H . Peter Anvin, Kees Cook, Kirill A . Shutemov, Tony Luck, Nick Desaulniers, Kuppuswamy Sathyanarayanan, Tom Lendacky, Venu Busireddy, Joerg Roedel, Tianyu Lan This series is based on tip/master (commit 1912a07f8a) SNP guests should only retrieve the AP Jump Table address from the secrets page, not via a GHCB request as with SEV-ES guests. This series reworks the handling accordingly, and fixes up some __init annotations for some of the SEV routines touched by that rework. v3: - Address missing __init annotations (Boris) v2: - add handling for memremap()/ioremap() failures (Boris) - don't mix function calls with declarations (Boris) arch/x86/include/asm/sev.h | 35 +++++++++++++++++++++++++++++++++++ arch/x86/kernel/sev.c | 80 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-------------------------- arch/x86/realmode/init.c | 2 +- drivers/virt/coco/sev-guest/sev-guest.h | 35 ----------------------------------- 4 files changed, 90 insertions(+), 62 deletions(-) ^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH v3 1/2] x86/sev: Add missing __init annotations to SEV init routines 2022-04-22 13:56 [PATCH v3 0/2] x86/sev: Fix AP Jump Table handling for SNP guests Michael Roth @ 2022-04-22 13:56 ` Michael Roth 2022-04-27 11:56 ` [tip: x86/sev] " tip-bot2 for Michael Roth 2022-04-22 13:56 ` [PATCH v3 2/2] x86/sev: Get the AP jump table address from secrets page Michael Roth 1 sibling, 1 reply; 8+ messages in thread From: Michael Roth @ 2022-04-22 13:56 UTC (permalink / raw) To: linux-kernel Cc: Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen, x86, H . Peter Anvin, Kees Cook, Kirill A . Shutemov, Tony Luck, Nick Desaulniers, Kuppuswamy Sathyanarayanan, Tom Lendacky, Venu Busireddy, Joerg Roedel, Tianyu Lan, Borislav Petkov Currently get_secrets_page() is only reachable from the following call chain: __init snp_init_platform_device(): get_secrets_page() so mark it as __init as well. This is also needed since it calls early_memremap(), which is also an __init routine. Similarly, get_jump_table_addr() is only reachable from the following call chain: __init setup_real_mode(): sme_sev_setup_real_mode(): sev_es_setup_ap_jump_table(): get_jump_table_addr() so mark get_jump_table_addr() and everything up that call chain as __init as well. This is also needed since future patches will add a call to get_secrets_page(), which needs to be __init due to the reasons stated above. Suggested-by: Borislav Petkov <bp@suse.de> Signed-off-by: Michael Roth <michael.roth@amd.com> --- arch/x86/kernel/sev.c | 6 +++--- arch/x86/realmode/init.c | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/arch/x86/kernel/sev.c b/arch/x86/kernel/sev.c index 2fa87a07ab30..b7fd1915560d 100644 --- a/arch/x86/kernel/sev.c +++ b/arch/x86/kernel/sev.c @@ -558,7 +558,7 @@ void noinstr __sev_es_nmi_complete(void) __sev_put_ghcb(&state); } -static u64 get_jump_table_addr(void) +static u64 __init get_jump_table_addr(void) { struct ghcb_state state; unsigned long flags; @@ -1077,7 +1077,7 @@ void snp_set_wakeup_secondary_cpu(void) apic->wakeup_secondary_cpu = wakeup_cpu_via_vmgexit; } -int sev_es_setup_ap_jump_table(struct real_mode_header *rmh) +int __init sev_es_setup_ap_jump_table(struct real_mode_header *rmh) { u16 startup_cs, startup_ip; phys_addr_t jump_table_pa; @@ -2171,7 +2171,7 @@ static struct platform_device sev_guest_device = { .id = -1, }; -static u64 get_secrets_page(void) +static u64 __init get_secrets_page(void) { u64 pa_data = boot_params.cc_blob_address; struct cc_blob_sev_info info; diff --git a/arch/x86/realmode/init.c b/arch/x86/realmode/init.c index c5e29db02a46..41d7669a97ad 100644 --- a/arch/x86/realmode/init.c +++ b/arch/x86/realmode/init.c @@ -67,7 +67,7 @@ void __init reserve_real_mode(void) memblock_reserve(0, SZ_1M); } -static void sme_sev_setup_real_mode(struct trampoline_header *th) +static void __init sme_sev_setup_real_mode(struct trampoline_header *th) { #ifdef CONFIG_AMD_MEM_ENCRYPT if (cc_platform_has(CC_ATTR_HOST_MEM_ENCRYPT)) -- 2.25.1 ^ permalink raw reply [flat|nested] 8+ messages in thread
* [tip: x86/sev] x86/sev: Add missing __init annotations to SEV init routines 2022-04-22 13:56 ` [PATCH v3 1/2] x86/sev: Add missing __init annotations to SEV init routines Michael Roth @ 2022-04-27 11:56 ` tip-bot2 for Michael Roth 0 siblings, 0 replies; 8+ messages in thread From: tip-bot2 for Michael Roth @ 2022-04-27 11:56 UTC (permalink / raw) To: linux-tip-commits; +Cc: Borislav Petkov, Michael Roth, x86, linux-kernel The following commit has been merged into the x86/sev branch of tip: Commit-ID: 75d359ec4141b013727022a663762931f69e6510 Gitweb: https://git.kernel.org/tip/75d359ec4141b013727022a663762931f69e6510 Author: Michael Roth <michael.roth@amd.com> AuthorDate: Fri, 22 Apr 2022 08:56:23 -05:00 Committer: Borislav Petkov <bp@suse.de> CommitterDate: Wed, 27 Apr 2022 13:31:36 +02:00 x86/sev: Add missing __init annotations to SEV init routines Currently, get_secrets_page() is only reachable from the following call chain: __init snp_init_platform_device(): get_secrets_page() so mark it as __init as well. This is also needed since it calls early_memremap(), which is also an __init routine. Similarly, get_jump_table_addr() is only reachable from the following call chain: __init setup_real_mode(): sme_sev_setup_real_mode(): sev_es_setup_ap_jump_table(): get_jump_table_addr() so mark get_jump_table_addr() and everything up that call chain as __init as well. This is also needed since future patches will add a call to get_secrets_page(), which needs to be __init due to the reasons stated above. Suggested-by: Borislav Petkov <bp@suse.de> Signed-off-by: Michael Roth <michael.roth@amd.com> Signed-off-by: Borislav Petkov <bp@suse.de> Link: https://lore.kernel.org/r/20220422135624.114172-2-michael.roth@amd.com --- arch/x86/kernel/sev.c | 6 +++--- arch/x86/realmode/init.c | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/arch/x86/kernel/sev.c b/arch/x86/kernel/sev.c index 2fa87a0..b7fd191 100644 --- a/arch/x86/kernel/sev.c +++ b/arch/x86/kernel/sev.c @@ -558,7 +558,7 @@ void noinstr __sev_es_nmi_complete(void) __sev_put_ghcb(&state); } -static u64 get_jump_table_addr(void) +static u64 __init get_jump_table_addr(void) { struct ghcb_state state; unsigned long flags; @@ -1077,7 +1077,7 @@ void snp_set_wakeup_secondary_cpu(void) apic->wakeup_secondary_cpu = wakeup_cpu_via_vmgexit; } -int sev_es_setup_ap_jump_table(struct real_mode_header *rmh) +int __init sev_es_setup_ap_jump_table(struct real_mode_header *rmh) { u16 startup_cs, startup_ip; phys_addr_t jump_table_pa; @@ -2171,7 +2171,7 @@ static struct platform_device sev_guest_device = { .id = -1, }; -static u64 get_secrets_page(void) +static u64 __init get_secrets_page(void) { u64 pa_data = boot_params.cc_blob_address; struct cc_blob_sev_info info; diff --git a/arch/x86/realmode/init.c b/arch/x86/realmode/init.c index c5e29db..41d7669 100644 --- a/arch/x86/realmode/init.c +++ b/arch/x86/realmode/init.c @@ -67,7 +67,7 @@ void __init reserve_real_mode(void) memblock_reserve(0, SZ_1M); } -static void sme_sev_setup_real_mode(struct trampoline_header *th) +static void __init sme_sev_setup_real_mode(struct trampoline_header *th) { #ifdef CONFIG_AMD_MEM_ENCRYPT if (cc_platform_has(CC_ATTR_HOST_MEM_ENCRYPT)) ^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH v3 2/2] x86/sev: Get the AP jump table address from secrets page 2022-04-22 13:56 [PATCH v3 0/2] x86/sev: Fix AP Jump Table handling for SNP guests Michael Roth 2022-04-22 13:56 ` [PATCH v3 1/2] x86/sev: Add missing __init annotations to SEV init routines Michael Roth @ 2022-04-22 13:56 ` Michael Roth 2022-04-22 15:15 ` Tom Lendacky 2022-04-27 11:56 ` [tip: x86/sev] " tip-bot2 for Brijesh Singh 1 sibling, 2 replies; 8+ messages in thread From: Michael Roth @ 2022-04-22 13:56 UTC (permalink / raw) To: linux-kernel Cc: Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen, x86, H . Peter Anvin, Kees Cook, Kirill A . Shutemov, Tony Luck, Nick Desaulniers, Kuppuswamy Sathyanarayanan, Tom Lendacky, Venu Busireddy, Joerg Roedel, Tianyu Lan, Brijesh Singh From: Brijesh Singh <brijesh.singh@amd.com> The GHCB specification section 2.7 states that when SEV-SNP is enabled, a hypervisor must provide the AP jump table physical address through the SNP secrets pages. Fixes: 0afb6b660a6b ("x86/sev: Use SEV-SNP AP creation to start secondary CPUs") Signed-off-by: Brijesh Singh <brijesh.singh@amd.com> [ mroth: improve error handling when ioremap()/memremap() return NULL ] [ mroth: don't mix function calls with declarations ] [ mroth: add missing __init ] Signed-off-by: Michael Roth <michael.roth@amd.com> --- arch/x86/include/asm/sev.h | 35 ++++++++++++ arch/x86/kernel/sev.c | 76 +++++++++++++++++-------- drivers/virt/coco/sev-guest/sev-guest.h | 35 ------------ 3 files changed, 87 insertions(+), 59 deletions(-) diff --git a/arch/x86/include/asm/sev.h b/arch/x86/include/asm/sev.h index 6e3dda4f82b5..19514524f0f8 100644 --- a/arch/x86/include/asm/sev.h +++ b/arch/x86/include/asm/sev.h @@ -99,6 +99,41 @@ struct sev_guest_platform_data { u64 secrets_gpa; }; +/* + * The secrets page contains 96-bytes of reserved field that can be used by + * the guest OS. The guest OS uses the area to save the message sequence + * number for each VMPCK. + * + * See the GHCB spec section Secret page layout for the format for this area. + */ +struct secrets_os_area { + u32 msg_seqno_0; + u32 msg_seqno_1; + u32 msg_seqno_2; + u32 msg_seqno_3; + u64 ap_jump_table_pa; + u8 rsvd[40]; + u8 guest_usage[32]; +} __packed; + +#define VMPCK_KEY_LEN 32 + +/* See the SNP spec version 0.9 for secrets page format */ +struct snp_secrets_page_layout { + u32 version; + u32 imien : 1, + rsvd1 : 31; + u32 fms; + u32 rsvd2; + u8 gosvw[16]; + u8 vmpck0[VMPCK_KEY_LEN]; + u8 vmpck1[VMPCK_KEY_LEN]; + u8 vmpck2[VMPCK_KEY_LEN]; + u8 vmpck3[VMPCK_KEY_LEN]; + struct secrets_os_area os_area; + u8 rsvd3[3840]; +} __packed; + #ifdef CONFIG_AMD_MEM_ENCRYPT extern struct static_key_false sev_es_enable_key; extern void __sev_es_ist_enter(struct pt_regs *regs); diff --git a/arch/x86/kernel/sev.c b/arch/x86/kernel/sev.c index b7fd1915560d..166375084b1f 100644 --- a/arch/x86/kernel/sev.c +++ b/arch/x86/kernel/sev.c @@ -558,6 +558,55 @@ void noinstr __sev_es_nmi_complete(void) __sev_put_ghcb(&state); } +static u64 __init get_secrets_page(void) +{ + u64 pa_data = boot_params.cc_blob_address; + struct cc_blob_sev_info info; + void *map; + + /* + * The CC blob contains the address of the secrets page, check if the + * blob is present. + */ + if (!pa_data) + return 0; + + map = early_memremap(pa_data, sizeof(info)); + if (!map) { + pr_err("Unable to locate SNP secrets page: failed to map the Confidential Computing blob.\n"); + return 0; + } + memcpy(&info, map, sizeof(info)); + early_memunmap(map, sizeof(info)); + + /* smoke-test the secrets page passed */ + if (!info.secrets_phys || info.secrets_len != PAGE_SIZE) + return 0; + + return info.secrets_phys; +} + +static u64 __init get_snp_jump_table_addr(void) +{ + struct snp_secrets_page_layout *layout; + u64 pa, addr; + + pa = get_secrets_page(); + if (!pa) + return 0; + + layout = (__force void *)ioremap_encrypted(pa, PAGE_SIZE); + if (!layout) { + pr_err("Unable to locate AP jump table address: failed to map the SNP secrets page.\n"); + return 0; + } + + addr = layout->os_area.ap_jump_table_pa; + iounmap(layout); + + return addr; +} + static u64 __init get_jump_table_addr(void) { struct ghcb_state state; @@ -565,6 +614,9 @@ static u64 __init get_jump_table_addr(void) struct ghcb *ghcb; u64 ret = 0; + if (cc_platform_has(CC_ATTR_GUEST_SEV_SNP)) + return get_snp_jump_table_addr(); + local_irq_save(flags); ghcb = __sev_get_ghcb(&state); @@ -2171,30 +2223,6 @@ static struct platform_device sev_guest_device = { .id = -1, }; -static u64 __init get_secrets_page(void) -{ - u64 pa_data = boot_params.cc_blob_address; - struct cc_blob_sev_info info; - void *map; - - /* - * The CC blob contains the address of the secrets page, check if the - * blob is present. - */ - if (!pa_data) - return 0; - - map = early_memremap(pa_data, sizeof(info)); - memcpy(&info, map, sizeof(info)); - early_memunmap(map, sizeof(info)); - - /* smoke-test the secrets page passed */ - if (!info.secrets_phys || info.secrets_len != PAGE_SIZE) - return 0; - - return info.secrets_phys; -} - static int __init snp_init_platform_device(void) { struct sev_guest_platform_data data; diff --git a/drivers/virt/coco/sev-guest/sev-guest.h b/drivers/virt/coco/sev-guest/sev-guest.h index d39bdd013765..21bda26fdb95 100644 --- a/drivers/virt/coco/sev-guest/sev-guest.h +++ b/drivers/virt/coco/sev-guest/sev-guest.h @@ -60,39 +60,4 @@ struct snp_guest_msg { u8 payload[4000]; } __packed; -/* - * The secrets page contains 96-bytes of reserved field that can be used by - * the guest OS. The guest OS uses the area to save the message sequence - * number for each VMPCK. - * - * See the GHCB spec section Secret page layout for the format for this area. - */ -struct secrets_os_area { - u32 msg_seqno_0; - u32 msg_seqno_1; - u32 msg_seqno_2; - u32 msg_seqno_3; - u64 ap_jump_table_pa; - u8 rsvd[40]; - u8 guest_usage[32]; -} __packed; - -#define VMPCK_KEY_LEN 32 - -/* See the SNP spec version 0.9 for secrets page format */ -struct snp_secrets_page_layout { - u32 version; - u32 imien : 1, - rsvd1 : 31; - u32 fms; - u32 rsvd2; - u8 gosvw[16]; - u8 vmpck0[VMPCK_KEY_LEN]; - u8 vmpck1[VMPCK_KEY_LEN]; - u8 vmpck2[VMPCK_KEY_LEN]; - u8 vmpck3[VMPCK_KEY_LEN]; - struct secrets_os_area os_area; - u8 rsvd3[3840]; -} __packed; - #endif /* __VIRT_SEVGUEST_H__ */ -- 2.25.1 ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v3 2/2] x86/sev: Get the AP jump table address from secrets page 2022-04-22 13:56 ` [PATCH v3 2/2] x86/sev: Get the AP jump table address from secrets page Michael Roth @ 2022-04-22 15:15 ` Tom Lendacky 2022-04-22 15:40 ` Michael Roth 2022-04-27 11:56 ` [tip: x86/sev] " tip-bot2 for Brijesh Singh 1 sibling, 1 reply; 8+ messages in thread From: Tom Lendacky @ 2022-04-22 15:15 UTC (permalink / raw) To: Michael Roth, linux-kernel Cc: Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen, x86, H . Peter Anvin, Kees Cook, Kirill A . Shutemov, Tony Luck, Nick Desaulniers, Kuppuswamy Sathyanarayanan, Venu Busireddy, Joerg Roedel, Tianyu Lan, Brijesh Singh On 4/22/22 08:56, Michael Roth wrote: > From: Brijesh Singh <brijesh.singh@amd.com> > > The GHCB specification section 2.7 states that when SEV-SNP is enabled, > a hypervisor must provide the AP jump table physical address through I missed this on the first version. It's not the hypervisor, but the guest BIOS that directly provides the AP jump table physical address, in our case OVMF sets the address in the SNP secrets page. This allows communication between UEFI/BIOS and OS without hypervisor involvement. > the SNP secrets pages. > > Fixes: 0afb6b660a6b ("x86/sev: Use SEV-SNP AP creation to start secondary CPUs") > Signed-off-by: Brijesh Singh <brijesh.singh@amd.com> > [ mroth: improve error handling when ioremap()/memremap() return NULL ] > [ mroth: don't mix function calls with declarations ] > [ mroth: add missing __init ] > Signed-off-by: Michael Roth <michael.roth@amd.com> With the commit message change: Reviewed-by: Tom Lendacky <thomas.lendacky@amd.com> ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v3 2/2] x86/sev: Get the AP jump table address from secrets page 2022-04-22 15:15 ` Tom Lendacky @ 2022-04-22 15:40 ` Michael Roth 2022-04-22 17:27 ` Tom Lendacky 0 siblings, 1 reply; 8+ messages in thread From: Michael Roth @ 2022-04-22 15:40 UTC (permalink / raw) To: Tom Lendacky Cc: linux-kernel, Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen, x86, H . Peter Anvin, Kees Cook, Kirill A . Shutemov, Tony Luck, Nick Desaulniers, Kuppuswamy Sathyanarayanan, Venu Busireddy, Joerg Roedel, Tianyu Lan, Brijesh Singh On Fri, Apr 22, 2022 at 10:15:08AM -0500, Tom Lendacky wrote: > On 4/22/22 08:56, Michael Roth wrote: > > From: Brijesh Singh <brijesh.singh@amd.com> > > > > The GHCB specification section 2.7 states that when SEV-SNP is enabled, > > a hypervisor must provide the AP jump table physical address through > > I missed this on the first version. It's not the hypervisor, but the guest > BIOS that directly provides the AP jump table physical address, in our case > OVMF sets the address in the SNP secrets page. This allows communication > between UEFI/BIOS and OS without hypervisor involvement. How about this wording for the commit message? The GHCB specification section 2.7 states that when SEV-SNP is enabled, a guest should not rely on the hypervisor to provide the address of the AP jump table. Instead, if a guest BIOS wants provide an AP jump table, it should record the address in the SNP secrets page so the guest operating system can obtain it directly from there. Fix this on the guest kernel side by having SNP guests use the AP jump table address published in the secrets page rather than issuing a GHCB request to get it. > > > the SNP secrets pages. > > > > Fixes: 0afb6b660a6b ("x86/sev: Use SEV-SNP AP creation to start secondary CPUs") > > Signed-off-by: Brijesh Singh <brijesh.singh@amd.com> > > [ mroth: improve error handling when ioremap()/memremap() return NULL ] > > [ mroth: don't mix function calls with declarations ] > > [ mroth: add missing __init ] > > Signed-off-by: Michael Roth <michael.roth@amd.com> > > With the commit message change: > > Reviewed-by: Tom Lendacky <thomas.lendacky@amd.com> ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v3 2/2] x86/sev: Get the AP jump table address from secrets page 2022-04-22 15:40 ` Michael Roth @ 2022-04-22 17:27 ` Tom Lendacky 0 siblings, 0 replies; 8+ messages in thread From: Tom Lendacky @ 2022-04-22 17:27 UTC (permalink / raw) To: Michael Roth Cc: linux-kernel, Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen, x86, H . Peter Anvin, Kees Cook, Kirill A . Shutemov, Tony Luck, Nick Desaulniers, Kuppuswamy Sathyanarayanan, Venu Busireddy, Joerg Roedel, Tianyu Lan, Brijesh Singh On 4/22/22 10:40, Michael Roth wrote: > On Fri, Apr 22, 2022 at 10:15:08AM -0500, Tom Lendacky wrote: >> On 4/22/22 08:56, Michael Roth wrote: >>> From: Brijesh Singh <brijesh.singh@amd.com> >>> >>> The GHCB specification section 2.7 states that when SEV-SNP is enabled, >>> a hypervisor must provide the AP jump table physical address through >> >> I missed this on the first version. It's not the hypervisor, but the guest >> BIOS that directly provides the AP jump table physical address, in our case >> OVMF sets the address in the SNP secrets page. This allows communication >> between UEFI/BIOS and OS without hypervisor involvement. > > How about this wording for the commit message? > > The GHCB specification section 2.7 states that when SEV-SNP is enabled, > a guest should not rely on the hypervisor to provide the address of the > AP jump table. Instead, if a guest BIOS wants provide an AP jump table, > it should record the address in the SNP secrets page so the guest > operating system can obtain it directly from there. > > Fix this on the guest kernel side by having SNP guests use the AP jump > table address published in the secrets page rather than issuing a GHCB > request to get it. That sounds good to me. Thanks, Tom > >> >>> the SNP secrets pages. >>> >>> Fixes: 0afb6b660a6b ("x86/sev: Use SEV-SNP AP creation to start secondary CPUs") >>> Signed-off-by: Brijesh Singh <brijesh.singh@amd.com> >>> [ mroth: improve error handling when ioremap()/memremap() return NULL ] >>> [ mroth: don't mix function calls with declarations ] >>> [ mroth: add missing __init ] >>> Signed-off-by: Michael Roth <michael.roth@amd.com> >> >> With the commit message change: >> >> Reviewed-by: Tom Lendacky <thomas.lendacky@amd.com> ^ permalink raw reply [flat|nested] 8+ messages in thread
* [tip: x86/sev] x86/sev: Get the AP jump table address from secrets page 2022-04-22 13:56 ` [PATCH v3 2/2] x86/sev: Get the AP jump table address from secrets page Michael Roth 2022-04-22 15:15 ` Tom Lendacky @ 2022-04-27 11:56 ` tip-bot2 for Brijesh Singh 1 sibling, 0 replies; 8+ messages in thread From: tip-bot2 for Brijesh Singh @ 2022-04-27 11:56 UTC (permalink / raw) To: linux-tip-commits Cc: Brijesh Singh, Michael Roth, Borislav Petkov, x86, linux-kernel The following commit has been merged into the x86/sev branch of tip: Commit-ID: c2106a231c2ba36ff9af50cdf2867b9a5f8150a6 Gitweb: https://git.kernel.org/tip/c2106a231c2ba36ff9af50cdf2867b9a5f8150a6 Author: Brijesh Singh <brijesh.singh@amd.com> AuthorDate: Fri, 22 Apr 2022 08:56:24 -05:00 Committer: Borislav Petkov <bp@suse.de> CommitterDate: Wed, 27 Apr 2022 13:31:38 +02:00 x86/sev: Get the AP jump table address from secrets page The GHCB specification section 2.7 states that when SEV-SNP is enabled, a guest should not rely on the hypervisor to provide the address of the AP jump table. Instead, if a guest BIOS wants to provide an AP jump table, it should record the address in the SNP secrets page so the guest operating system can obtain it directly from there. Fix this on the guest kernel side by having SNP guests use the AP jump table address published in the secrets page rather than issuing a GHCB request to get it. [ mroth: - Improve error handling when ioremap()/memremap() return NULL - Don't mix function calls with declarations - Add missing __init - Tweak commit message ] Fixes: 0afb6b660a6b ("x86/sev: Use SEV-SNP AP creation to start secondary CPUs") Signed-off-by: Brijesh Singh <brijesh.singh@amd.com> Signed-off-by: Michael Roth <michael.roth@amd.com> Signed-off-by: Borislav Petkov <bp@suse.de> Link: https://lore.kernel.org/r/20220422135624.114172-3-michael.roth@amd.com --- arch/x86/include/asm/sev.h | 35 +++++++++++- arch/x86/kernel/sev.c | 76 ++++++++++++++++-------- drivers/virt/coco/sev-guest/sev-guest.h | 35 +----------- 3 files changed, 87 insertions(+), 59 deletions(-) diff --git a/arch/x86/include/asm/sev.h b/arch/x86/include/asm/sev.h index 6e3dda4..1951452 100644 --- a/arch/x86/include/asm/sev.h +++ b/arch/x86/include/asm/sev.h @@ -99,6 +99,41 @@ struct sev_guest_platform_data { u64 secrets_gpa; }; +/* + * The secrets page contains 96-bytes of reserved field that can be used by + * the guest OS. The guest OS uses the area to save the message sequence + * number for each VMPCK. + * + * See the GHCB spec section Secret page layout for the format for this area. + */ +struct secrets_os_area { + u32 msg_seqno_0; + u32 msg_seqno_1; + u32 msg_seqno_2; + u32 msg_seqno_3; + u64 ap_jump_table_pa; + u8 rsvd[40]; + u8 guest_usage[32]; +} __packed; + +#define VMPCK_KEY_LEN 32 + +/* See the SNP spec version 0.9 for secrets page format */ +struct snp_secrets_page_layout { + u32 version; + u32 imien : 1, + rsvd1 : 31; + u32 fms; + u32 rsvd2; + u8 gosvw[16]; + u8 vmpck0[VMPCK_KEY_LEN]; + u8 vmpck1[VMPCK_KEY_LEN]; + u8 vmpck2[VMPCK_KEY_LEN]; + u8 vmpck3[VMPCK_KEY_LEN]; + struct secrets_os_area os_area; + u8 rsvd3[3840]; +} __packed; + #ifdef CONFIG_AMD_MEM_ENCRYPT extern struct static_key_false sev_es_enable_key; extern void __sev_es_ist_enter(struct pt_regs *regs); diff --git a/arch/x86/kernel/sev.c b/arch/x86/kernel/sev.c index b7fd191..1663750 100644 --- a/arch/x86/kernel/sev.c +++ b/arch/x86/kernel/sev.c @@ -558,6 +558,55 @@ void noinstr __sev_es_nmi_complete(void) __sev_put_ghcb(&state); } +static u64 __init get_secrets_page(void) +{ + u64 pa_data = boot_params.cc_blob_address; + struct cc_blob_sev_info info; + void *map; + + /* + * The CC blob contains the address of the secrets page, check if the + * blob is present. + */ + if (!pa_data) + return 0; + + map = early_memremap(pa_data, sizeof(info)); + if (!map) { + pr_err("Unable to locate SNP secrets page: failed to map the Confidential Computing blob.\n"); + return 0; + } + memcpy(&info, map, sizeof(info)); + early_memunmap(map, sizeof(info)); + + /* smoke-test the secrets page passed */ + if (!info.secrets_phys || info.secrets_len != PAGE_SIZE) + return 0; + + return info.secrets_phys; +} + +static u64 __init get_snp_jump_table_addr(void) +{ + struct snp_secrets_page_layout *layout; + u64 pa, addr; + + pa = get_secrets_page(); + if (!pa) + return 0; + + layout = (__force void *)ioremap_encrypted(pa, PAGE_SIZE); + if (!layout) { + pr_err("Unable to locate AP jump table address: failed to map the SNP secrets page.\n"); + return 0; + } + + addr = layout->os_area.ap_jump_table_pa; + iounmap(layout); + + return addr; +} + static u64 __init get_jump_table_addr(void) { struct ghcb_state state; @@ -565,6 +614,9 @@ static u64 __init get_jump_table_addr(void) struct ghcb *ghcb; u64 ret = 0; + if (cc_platform_has(CC_ATTR_GUEST_SEV_SNP)) + return get_snp_jump_table_addr(); + local_irq_save(flags); ghcb = __sev_get_ghcb(&state); @@ -2171,30 +2223,6 @@ static struct platform_device sev_guest_device = { .id = -1, }; -static u64 __init get_secrets_page(void) -{ - u64 pa_data = boot_params.cc_blob_address; - struct cc_blob_sev_info info; - void *map; - - /* - * The CC blob contains the address of the secrets page, check if the - * blob is present. - */ - if (!pa_data) - return 0; - - map = early_memremap(pa_data, sizeof(info)); - memcpy(&info, map, sizeof(info)); - early_memunmap(map, sizeof(info)); - - /* smoke-test the secrets page passed */ - if (!info.secrets_phys || info.secrets_len != PAGE_SIZE) - return 0; - - return info.secrets_phys; -} - static int __init snp_init_platform_device(void) { struct sev_guest_platform_data data; diff --git a/drivers/virt/coco/sev-guest/sev-guest.h b/drivers/virt/coco/sev-guest/sev-guest.h index d39bdd0..21bda26 100644 --- a/drivers/virt/coco/sev-guest/sev-guest.h +++ b/drivers/virt/coco/sev-guest/sev-guest.h @@ -60,39 +60,4 @@ struct snp_guest_msg { u8 payload[4000]; } __packed; -/* - * The secrets page contains 96-bytes of reserved field that can be used by - * the guest OS. The guest OS uses the area to save the message sequence - * number for each VMPCK. - * - * See the GHCB spec section Secret page layout for the format for this area. - */ -struct secrets_os_area { - u32 msg_seqno_0; - u32 msg_seqno_1; - u32 msg_seqno_2; - u32 msg_seqno_3; - u64 ap_jump_table_pa; - u8 rsvd[40]; - u8 guest_usage[32]; -} __packed; - -#define VMPCK_KEY_LEN 32 - -/* See the SNP spec version 0.9 for secrets page format */ -struct snp_secrets_page_layout { - u32 version; - u32 imien : 1, - rsvd1 : 31; - u32 fms; - u32 rsvd2; - u8 gosvw[16]; - u8 vmpck0[VMPCK_KEY_LEN]; - u8 vmpck1[VMPCK_KEY_LEN]; - u8 vmpck2[VMPCK_KEY_LEN]; - u8 vmpck3[VMPCK_KEY_LEN]; - struct secrets_os_area os_area; - u8 rsvd3[3840]; -} __packed; - #endif /* __VIRT_SEVGUEST_H__ */ ^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2022-04-27 11:56 UTC | newest] Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2022-04-22 13:56 [PATCH v3 0/2] x86/sev: Fix AP Jump Table handling for SNP guests Michael Roth 2022-04-22 13:56 ` [PATCH v3 1/2] x86/sev: Add missing __init annotations to SEV init routines Michael Roth 2022-04-27 11:56 ` [tip: x86/sev] " tip-bot2 for Michael Roth 2022-04-22 13:56 ` [PATCH v3 2/2] x86/sev: Get the AP jump table address from secrets page Michael Roth 2022-04-22 15:15 ` Tom Lendacky 2022-04-22 15:40 ` Michael Roth 2022-04-22 17:27 ` Tom Lendacky 2022-04-27 11:56 ` [tip: x86/sev] " tip-bot2 for Brijesh Singh
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®