[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20250515111000.GBaCXLiEi0_bG1qVzx@fat_crate.local>
Date: Thu, 15 May 2025 13:10:00 +0200
From: Borislav Petkov <bp@...en8.de>
To: Ard Biesheuvel <ardb+git@...gle.com>
Cc: linux-kernel@...r.kernel.org, linux-efi@...r.kernel.org, x86@...nel.org,
Ard Biesheuvel <ardb@...nel.org>, Ingo Molnar <mingo@...nel.org>,
Dionna Amalie Glaze <dionnaglaze@...gle.com>,
Kevin Loughlin <kevinloughlin@...gle.com>,
Tom Lendacky <thomas.lendacky@....com>
Subject: Re: [RFT PATCH v3 01/21] x86/sev: Separate MSR and GHCB based
snp_cpuid() via a callback
On Mon, May 12, 2025 at 09:08:36PM +0200, Ard Biesheuvel wrote:
> From: Ard Biesheuvel <ardb@...nel.org>
>
> There are two distinct callers of snp_cpuid(): one where the MSR
> protocol is always used, and one where the GHCB page based interface is
> always used.
Yeah, let's stick to the nomenclature, pls: you have a GHCB protocol and a MSR
protocol. We call both protocols. :)
> The snp_cpuid() logic does not care about the distinction, which only
> matters at a lower level. But the fact that it supports both interfaces
> means that the GHCB page based logic is pulled into the early startup
> code where PA to VA conversions are problematic, given that it runs from
> the 1:1 mapping of memory.
>
> So keep snp_cpuid() itself in the startup code, but factor out the
> hypervisor calls via a callback, so that the GHCB page handling can be
> moved out.
>
> Code refactoring only - no functional change intended.
>
> Signed-off-by: Ard Biesheuvel <ardb@...nel.org>
> ---
> arch/x86/boot/startup/sev-shared.c | 58 ++++----------------
> arch/x86/coco/sev/vc-shared.c | 49 ++++++++++++++++-
> arch/x86/include/asm/sev.h | 3 +-
> 3 files changed, 61 insertions(+), 49 deletions(-)
...
> @@ -484,21 +447,21 @@ snp_cpuid_get_validated_func(struct cpuid_leaf *leaf)
> return false;
> }
>
> -static void snp_cpuid_hv(struct ghcb *ghcb, struct es_em_ctxt *ctxt, struct cpuid_leaf *leaf)
> +static void snp_cpuid_hv_no_ghcb(void *ctx, struct cpuid_leaf *leaf)
Uff, those suffixes make my head hurt. So this is the MSR prot CPUID. Let's
call it this way:
snp_cpuid_msr_prot()
and the other one
snp_cpuid_ghcb_prot()
All clear this way.
> {
> - if (sev_cpuid_hv(ghcb, ctxt, leaf))
> + if (__sev_cpuid_hv_msr(leaf))
__sev_cpuid_msr_prot
> sev_es_terminate(SEV_TERM_SET_LINUX, GHCB_TERM_CPUID_HV);
> }
>
> static int __heada
Let's zap that ugly linebreak.
> -snp_cpuid_postprocess(struct ghcb *ghcb, struct es_em_ctxt *ctxt,
> - struct cpuid_leaf *leaf)
> +snp_cpuid_postprocess(void (*cpuid_hv)(void *ctx, struct cpuid_leaf *),
Let's call that just "cpuid" now that it can be different things and it is
a pointer.
> + void *ctx, struct cpuid_leaf *leaf)
> {
> struct cpuid_leaf leaf_hv = *leaf;
>
> switch (leaf->fn) {
> case 0x1:
> - snp_cpuid_hv(ghcb, ctxt, &leaf_hv);
> + cpuid_hv(ctx, &leaf_hv);
>
> /* initial APIC ID */
> leaf->ebx = (leaf_hv.ebx & GENMASK(31, 24)) | (leaf->ebx & GENMASK(23, 0));
> @@ -517,7 +480,7 @@ snp_cpuid_postprocess(struct ghcb *ghcb, struct es_em_ctxt *ctxt,
> break;
> case 0xB:
> leaf_hv.subfn = 0;
> - snp_cpuid_hv(ghcb, ctxt, &leaf_hv);
> + cpuid_hv(ctx, &leaf_hv);
>
> /* extended APIC ID */
> leaf->edx = leaf_hv.edx;
> @@ -565,7 +528,7 @@ snp_cpuid_postprocess(struct ghcb *ghcb, struct es_em_ctxt *ctxt,
> }
> break;
> case 0x8000001E:
> - snp_cpuid_hv(ghcb, ctxt, &leaf_hv);
> + cpuid_hv(ctx, &leaf_hv);
>
> /* extended APIC ID */
> leaf->eax = leaf_hv.eax;
> @@ -587,7 +550,8 @@ snp_cpuid_postprocess(struct ghcb *ghcb, struct es_em_ctxt *ctxt,
> * should be treated as fatal by caller.
> */
> int __head
And that ugly linebreak too pls.
...
Here's a diff ontop with my changes. I think it looks a lot saner now and one
can really differentiate which is which.
Could more cleanup be done? Ofc. But that for later patches.
Thx.
---
diff --git a/arch/x86/boot/startup/sev-shared.c b/arch/x86/boot/startup/sev-shared.c
index 408e064a80d9..992abfa50508 100644
--- a/arch/x86/boot/startup/sev-shared.c
+++ b/arch/x86/boot/startup/sev-shared.c
@@ -319,7 +319,7 @@ static int __sev_cpuid_hv(u32 fn, int reg_idx, u32 *reg)
return 0;
}
-static int __sev_cpuid_hv_msr(struct cpuid_leaf *leaf)
+static int __sev_cpuid_msr_prot(struct cpuid_leaf *leaf)
{
int ret;
@@ -447,21 +447,20 @@ snp_cpuid_get_validated_func(struct cpuid_leaf *leaf)
return false;
}
-static void snp_cpuid_hv_no_ghcb(void *ctx, struct cpuid_leaf *leaf)
+static void snp_cpuid_msr_prot(void *ctx, struct cpuid_leaf *leaf)
{
- if (__sev_cpuid_hv_msr(leaf))
+ if (__sev_cpuid_msr_prot(leaf))
sev_es_terminate(SEV_TERM_SET_LINUX, GHCB_TERM_CPUID_HV);
}
-static int __head
-snp_cpuid_postprocess(void (*cpuid_hv)(void *ctx, struct cpuid_leaf *),
- void *ctx, struct cpuid_leaf *leaf)
+static int __head snp_cpuid_postprocess(void (*cpuid)(void *ctx, struct cpuid_leaf *),
+ void *ctx, struct cpuid_leaf *leaf)
{
struct cpuid_leaf leaf_hv = *leaf;
switch (leaf->fn) {
case 0x1:
- cpuid_hv(ctx, &leaf_hv);
+ cpuid(ctx, &leaf_hv);
/* initial APIC ID */
leaf->ebx = (leaf_hv.ebx & GENMASK(31, 24)) | (leaf->ebx & GENMASK(23, 0));
@@ -480,7 +479,7 @@ snp_cpuid_postprocess(void (*cpuid_hv)(void *ctx, struct cpuid_leaf *),
break;
case 0xB:
leaf_hv.subfn = 0;
- cpuid_hv(ctx, &leaf_hv);
+ cpuid(ctx, &leaf_hv);
/* extended APIC ID */
leaf->edx = leaf_hv.edx;
@@ -528,7 +527,7 @@ snp_cpuid_postprocess(void (*cpuid_hv)(void *ctx, struct cpuid_leaf *),
}
break;
case 0x8000001E:
- cpuid_hv(ctx, &leaf_hv);
+ cpuid(ctx, &leaf_hv);
/* extended APIC ID */
leaf->eax = leaf_hv.eax;
@@ -549,9 +548,8 @@ snp_cpuid_postprocess(void (*cpuid_hv)(void *ctx, struct cpuid_leaf *),
* Returns -EOPNOTSUPP if feature not enabled. Any other non-zero return value
* should be treated as fatal by caller.
*/
-int __head
-snp_cpuid(void (*cpuid_hv)(void *ctx, struct cpuid_leaf *),
- void *ctx, struct cpuid_leaf *leaf)
+int __head snp_cpuid(void (*cpuid)(void *ctx, struct cpuid_leaf *), void *ctx,
+ struct cpuid_leaf *leaf)
{
const struct snp_cpuid_table *cpuid_table = snp_cpuid_get_table();
@@ -585,7 +583,7 @@ snp_cpuid(void (*cpuid_hv)(void *ctx, struct cpuid_leaf *),
return 0;
}
- return snp_cpuid_postprocess(cpuid_hv, ctx, leaf);
+ return snp_cpuid_postprocess(cpuid, ctx, leaf);
}
/*
@@ -612,14 +610,14 @@ void __head do_vc_no_ghcb(struct pt_regs *regs, unsigned long exit_code)
leaf.fn = fn;
leaf.subfn = subfn;
- ret = snp_cpuid(snp_cpuid_hv_no_ghcb, NULL, &leaf);
+ ret = snp_cpuid(snp_cpuid_msr_prot, NULL, &leaf);
if (!ret)
goto cpuid_done;
if (ret != -EOPNOTSUPP)
goto fail;
- if (__sev_cpuid_hv_msr(&leaf))
+ if (__sev_cpuid_msr_prot(&leaf))
goto fail;
cpuid_done:
diff --git a/arch/x86/coco/sev/vc-shared.c b/arch/x86/coco/sev/vc-shared.c
index b4688f69102e..776cb90be530 100644
--- a/arch/x86/coco/sev/vc-shared.c
+++ b/arch/x86/coco/sev/vc-shared.c
@@ -409,7 +409,7 @@ static enum es_result vc_handle_ioio(struct ghcb *ghcb, struct es_em_ctxt *ctxt)
return ret;
}
-static int __sev_cpuid_hv_ghcb(struct ghcb *ghcb, struct es_em_ctxt *ctxt, struct cpuid_leaf *leaf)
+static int __sev_cpuid_ghcb_prot(struct ghcb *ghcb, struct es_em_ctxt *ctxt, struct cpuid_leaf *leaf)
{
u32 cr4 = native_read_cr4();
int ret;
@@ -447,11 +447,11 @@ struct cpuid_ctx {
struct es_em_ctxt *ctxt;
};
-static void snp_cpuid_hv_ghcb(void *p, struct cpuid_leaf *leaf)
+static void snp_cpuid_ghcb_prot(void *p, struct cpuid_leaf *leaf)
{
struct cpuid_ctx *ctx = p;
- if (__sev_cpuid_hv_ghcb(ctx->ghcb, ctx->ctxt, leaf))
+ if (__sev_cpuid_ghcb_prot(ctx->ghcb, ctx->ctxt, leaf))
sev_es_terminate(SEV_TERM_SET_LINUX, GHCB_TERM_CPUID_HV);
}
@@ -464,7 +464,7 @@ static int vc_handle_cpuid_snp(struct ghcb *ghcb, struct es_em_ctxt *ctxt)
leaf.fn = regs->ax;
leaf.subfn = regs->cx;
- ret = snp_cpuid(snp_cpuid_hv_ghcb, &ctx, &leaf);
+ ret = snp_cpuid(snp_cpuid_ghcb_prot, &ctx, &leaf);
if (!ret) {
regs->ax = leaf.eax;
regs->bx = leaf.ebx;
--
Regards/Gruss,
Boris.
https://people.kernel.org/tglx/notes-about-netiquette
Powered by blists - more mailing lists