On 3/22/23 17:47, Borislav Petkov wrote:
On Tue, Mar 21, 2023 at 07:40:08PM +0000, Usama Arif wrote:
From: David Woodhouse <dwmw@xxxxxxxxxxxx>
Enable parallel bringup for SEV-ES guests. The APs can't actually
execute the CPUID instruction directly during early startup, but they
can make the GHCB call directly instead, just as the VC trap handler
would do.
Thanks to Sabin for talking me through the way this works.
Suggested-by: Sabin Rapan <sabrapan@xxxxxxxxxx>
Signed-off-by: David Woodhouse <dwmw@xxxxxxxxxxxx>
Signed-off-by: Usama Arif <usama.arif@xxxxxxxxxxxxx>
Reviewed-by: Tom Lendacky <thomas.lendacky@xxxxxxx>
---
arch/x86/coco/core.c | 5 ++++
arch/x86/include/asm/coco.h | 1 +
arch/x86/include/asm/sev-common.h | 3 +++
arch/x86/include/asm/smp.h | 5 +++-
arch/x86/kernel/head_64.S | 30 ++++++++++++++++++++++++
arch/x86/kernel/smpboot.c | 39 ++++++++++++++++++++++++++-----
6 files changed, 76 insertions(+), 7 deletions(-)
How's the below (totally untested yet but it builds) instead after
applying those two prerequisites:
https://lore.kernel.org/r/20230318115634.9392-1-bp@xxxxxxxxx
---
...
diff --git a/arch/x86/kernel/sev.c b/arch/x86/kernel/sev.c
index ce371f62167b..96ff63cb5622 100644
--- a/arch/x86/kernel/sev.c
+++ b/arch/x86/kernel/sev.c
@@ -1142,6 +1142,24 @@ void snp_set_wakeup_secondary_cpu(void)
apic->wakeup_secondary_cpu = wakeup_cpu_via_vmgexit;
}
+u32 sev_get_cpuid_0b(void)
Maybe call this sev_early_get_cpuid_0b() or such to imply that the MSR
protocol is being used and only retrieving / returning edx.
Also, since it is a function now and can be used at any point, the current
GHCB MSR should be saved on entry and restored on exit.
Thanks,
Tom
+{
+ u32 eax, edx;
+
+ /* Request CPUID 0xB_EDX through GHCB protocol */
+ native_wrmsr(MSR_AMD64_SEV_ES_GHCB,
+ (GHCB_CPUID_REQ_EDX << 30) | GHCB_MSR_CPUID_REQ,
+ 0xb);
+ VMGEXIT();
+
+ native_rdmsr(MSR_AMD64_SEV_ES_GHCB, eax, edx);
+
+ if ((eax & GHCB_MSR_INFO_MASK) == GHCB_MSR_CPUID_RESP)
+ return edx;
+
+ return 0;
+}
+
int __init sev_es_setup_ap_jump_table(struct real_mode_header *rmh)
{
u16 startup_cs, startup_ip;