[RFT PATCH v3 01/21] x86/sev: Separate MSR and GHCB based snp_cpuid() via a callback

Ard Biesheuvel posted 21 patches 9 months ago
There is a newer version of this series
[RFT PATCH v3 01/21] x86/sev: Separate MSR and GHCB based snp_cpuid() via a callback
Posted by Ard Biesheuvel 9 months ago
From: Ard Biesheuvel <ardb@kernel.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.

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@kernel.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(-)

diff --git a/arch/x86/boot/startup/sev-shared.c b/arch/x86/boot/startup/sev-shared.c
index 7a706db87b93..408e064a80d9 100644
--- a/arch/x86/boot/startup/sev-shared.c
+++ b/arch/x86/boot/startup/sev-shared.c
@@ -342,44 +342,7 @@ static int __sev_cpuid_hv_msr(struct cpuid_leaf *leaf)
 	return ret;
 }
 
-static int __sev_cpuid_hv_ghcb(struct ghcb *ghcb, struct es_em_ctxt *ctxt, struct cpuid_leaf *leaf)
-{
-	u32 cr4 = native_read_cr4();
-	int ret;
-
-	ghcb_set_rax(ghcb, leaf->fn);
-	ghcb_set_rcx(ghcb, leaf->subfn);
-
-	if (cr4 & X86_CR4_OSXSAVE)
-		/* Safe to read xcr0 */
-		ghcb_set_xcr0(ghcb, xgetbv(XCR_XFEATURE_ENABLED_MASK));
-	else
-		/* xgetbv will cause #UD - use reset value for xcr0 */
-		ghcb_set_xcr0(ghcb, 1);
-
-	ret = sev_es_ghcb_hv_call(ghcb, ctxt, SVM_EXIT_CPUID, 0, 0);
-	if (ret != ES_OK)
-		return ret;
-
-	if (!(ghcb_rax_is_valid(ghcb) &&
-	      ghcb_rbx_is_valid(ghcb) &&
-	      ghcb_rcx_is_valid(ghcb) &&
-	      ghcb_rdx_is_valid(ghcb)))
-		return ES_VMM_ERROR;
 
-	leaf->eax = ghcb->save.rax;
-	leaf->ebx = ghcb->save.rbx;
-	leaf->ecx = ghcb->save.rcx;
-	leaf->edx = ghcb->save.rdx;
-
-	return ES_OK;
-}
-
-static int sev_cpuid_hv(struct ghcb *ghcb, struct es_em_ctxt *ctxt, struct cpuid_leaf *leaf)
-{
-	return ghcb ? __sev_cpuid_hv_ghcb(ghcb, ctxt, leaf)
-		    : __sev_cpuid_hv_msr(leaf);
-}
 
 /*
  * This may be called early while still running on the initial identity
@@ -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)
 {
-	if (sev_cpuid_hv(ghcb, ctxt, leaf))
+	if (__sev_cpuid_hv_msr(leaf))
 		sev_es_terminate(SEV_TERM_SET_LINUX, GHCB_TERM_CPUID_HV);
 }
 
 static int __head
-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 *),
+		      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
-snp_cpuid(struct ghcb *ghcb, struct es_em_ctxt *ctxt, struct cpuid_leaf *leaf)
+snp_cpuid(void (*cpuid_hv)(void *ctx, struct cpuid_leaf *),
+	  void *ctx, struct cpuid_leaf *leaf)
 {
 	const struct snp_cpuid_table *cpuid_table = snp_cpuid_get_table();
 
@@ -621,7 +585,7 @@ snp_cpuid(struct ghcb *ghcb, struct es_em_ctxt *ctxt, struct cpuid_leaf *leaf)
 			return 0;
 	}
 
-	return snp_cpuid_postprocess(ghcb, ctxt, leaf);
+	return snp_cpuid_postprocess(cpuid_hv, ctx, leaf);
 }
 
 /*
@@ -648,7 +612,7 @@ void __head do_vc_no_ghcb(struct pt_regs *regs, unsigned long exit_code)
 	leaf.fn = fn;
 	leaf.subfn = subfn;
 
-	ret = snp_cpuid(NULL, NULL, &leaf);
+	ret = snp_cpuid(snp_cpuid_hv_no_ghcb, NULL, &leaf);
 	if (!ret)
 		goto cpuid_done;
 
diff --git a/arch/x86/coco/sev/vc-shared.c b/arch/x86/coco/sev/vc-shared.c
index 2c0ab0fdc060..b4688f69102e 100644
--- a/arch/x86/coco/sev/vc-shared.c
+++ b/arch/x86/coco/sev/vc-shared.c
@@ -409,15 +409,62 @@ 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)
+{
+	u32 cr4 = native_read_cr4();
+	int ret;
+
+	ghcb_set_rax(ghcb, leaf->fn);
+	ghcb_set_rcx(ghcb, leaf->subfn);
+
+	if (cr4 & X86_CR4_OSXSAVE)
+		/* Safe to read xcr0 */
+		ghcb_set_xcr0(ghcb, xgetbv(XCR_XFEATURE_ENABLED_MASK));
+	else
+		/* xgetbv will cause #UD - use reset value for xcr0 */
+		ghcb_set_xcr0(ghcb, 1);
+
+	ret = sev_es_ghcb_hv_call(ghcb, ctxt, SVM_EXIT_CPUID, 0, 0);
+	if (ret != ES_OK)
+		return ret;
+
+	if (!(ghcb_rax_is_valid(ghcb) &&
+	      ghcb_rbx_is_valid(ghcb) &&
+	      ghcb_rcx_is_valid(ghcb) &&
+	      ghcb_rdx_is_valid(ghcb)))
+		return ES_VMM_ERROR;
+
+	leaf->eax = ghcb->save.rax;
+	leaf->ebx = ghcb->save.rbx;
+	leaf->ecx = ghcb->save.rcx;
+	leaf->edx = ghcb->save.rdx;
+
+	return ES_OK;
+}
+
+struct cpuid_ctx {
+	struct ghcb *ghcb;
+	struct es_em_ctxt *ctxt;
+};
+
+static void snp_cpuid_hv_ghcb(void *p, struct cpuid_leaf *leaf)
+{
+	struct cpuid_ctx *ctx = p;
+
+	if (__sev_cpuid_hv_ghcb(ctx->ghcb, ctx->ctxt, leaf))
+		sev_es_terminate(SEV_TERM_SET_LINUX, GHCB_TERM_CPUID_HV);
+}
+
 static int vc_handle_cpuid_snp(struct ghcb *ghcb, struct es_em_ctxt *ctxt)
 {
+	struct cpuid_ctx ctx = { ghcb, ctxt };
 	struct pt_regs *regs = ctxt->regs;
 	struct cpuid_leaf leaf;
 	int ret;
 
 	leaf.fn = regs->ax;
 	leaf.subfn = regs->cx;
-	ret = snp_cpuid(ghcb, ctxt, &leaf);
+	ret = snp_cpuid(snp_cpuid_hv_ghcb, &ctx, &leaf);
 	if (!ret) {
 		regs->ax = leaf.eax;
 		regs->bx = leaf.ebx;
diff --git a/arch/x86/include/asm/sev.h b/arch/x86/include/asm/sev.h
index 6158893786d6..f50a606be4f1 100644
--- a/arch/x86/include/asm/sev.h
+++ b/arch/x86/include/asm/sev.h
@@ -533,7 +533,8 @@ struct cpuid_leaf {
 	u32 edx;
 };
 
-int snp_cpuid(struct ghcb *ghcb, struct es_em_ctxt *ctxt, struct cpuid_leaf *leaf);
+int snp_cpuid(void (*cpuid_hv)(void *ctx, struct cpuid_leaf *),
+	      void *ctx, struct cpuid_leaf *leaf);
 
 void __noreturn sev_es_terminate(unsigned int set, unsigned int reason);
 enum es_result sev_es_ghcb_hv_call(struct ghcb *ghcb,
-- 
2.49.0.1045.g170613ef41-goog
Re: [RFT PATCH v3 01/21] x86/sev: Separate MSR and GHCB based snp_cpuid() via a callback
Posted by Borislav Petkov 8 months, 4 weeks ago
On Mon, May 12, 2025 at 09:08:36PM +0200, Ard Biesheuvel wrote:
> From: Ard Biesheuvel <ardb@kernel.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@kernel.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
Re: [RFT PATCH v3 01/21] x86/sev: Separate MSR and GHCB based snp_cpuid() via a callback
Posted by Ard Biesheuvel 8 months, 4 weeks ago
On Thu, 15 May 2025 at 12:10, Borislav Petkov <bp@alien8.de> wrote:
>
> On Mon, May 12, 2025 at 09:08:36PM +0200, Ard Biesheuvel wrote:
> > From: Ard Biesheuvel <ardb@kernel.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@kernel.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.
>

Thanks, I'll fold that in.
Re: [RFT PATCH v3 01/21] x86/sev: Separate MSR and GHCB based snp_cpuid() via a callback
Posted by Ingo Molnar 8 months, 4 weeks ago
* Ard Biesheuvel <ardb+git@google.com> wrote:

> +	if (cr4 & X86_CR4_OSXSAVE)
> +		/* Safe to read xcr0 */
> +		ghcb_set_xcr0(ghcb, xgetbv(XCR_XFEATURE_ENABLED_MASK));
> +	else
> +		/* xgetbv will cause #UD - use reset value for xcr0 */
> +		ghcb_set_xcr0(ghcb, 1);

Just a couple of style nits here - this new __sev_cpuid_hv_ghcb() 
function should follow the existing SEV* (and general x86) style:

 - When mentioning instruction mnemonics, please capitalize them, such 
   as XGETBV here.

 - Same goes for registers, such as XCR0.

 - Finally, if a comment line turns a branch into a multi-line 
   statement, curly braces are needed, even if it's technically still a 
   single statement per the C syntax which eliminates comments at the 
   preprocessor level.

Thanks,

	Ingo
Re: [RFT PATCH v3 01/21] x86/sev: Separate MSR and GHCB based snp_cpuid() via a callback
Posted by Ard Biesheuvel 8 months, 4 weeks ago
On Thu, 15 May 2025 at 08:22, Ingo Molnar <mingo@kernel.org> wrote:
>
>
> * Ard Biesheuvel <ardb+git@google.com> wrote:
>
> > +     if (cr4 & X86_CR4_OSXSAVE)
> > +             /* Safe to read xcr0 */
> > +             ghcb_set_xcr0(ghcb, xgetbv(XCR_XFEATURE_ENABLED_MASK));
> > +     else
> > +             /* xgetbv will cause #UD - use reset value for xcr0 */
> > +             ghcb_set_xcr0(ghcb, 1);
>
> Just a couple of style nits here - this new __sev_cpuid_hv_ghcb()
> function

__sev_cpuid_hv_ghcb() is just being moved from one source file to
another - I didn't change a single line, and so I don't think tweaking
the style is appropriate for this patch.
Re: [RFT PATCH v3 01/21] x86/sev: Separate MSR and GHCB based snp_cpuid() via a callback
Posted by Ingo Molnar 8 months, 4 weeks ago
* Ard Biesheuvel <ardb@kernel.org> wrote:

> On Thu, 15 May 2025 at 08:22, Ingo Molnar <mingo@kernel.org> wrote:
> >
> >
> > * Ard Biesheuvel <ardb+git@google.com> wrote:
> >
> > > +     if (cr4 & X86_CR4_OSXSAVE)
> > > +             /* Safe to read xcr0 */
> > > +             ghcb_set_xcr0(ghcb, xgetbv(XCR_XFEATURE_ENABLED_MASK));
> > > +     else
> > > +             /* xgetbv will cause #UD - use reset value for xcr0 */
> > > +             ghcb_set_xcr0(ghcb, 1);
> >
> > Just a couple of style nits here - this new __sev_cpuid_hv_ghcb()
> > function
> 
> __sev_cpuid_hv_ghcb() is just being moved from one source file to
> another - I didn't change a single line, and so I don't think tweaking
> the style is appropriate for this patch.

Yeah, fair enough - in fact changing anything in a pure-movement patch 
would be counterproductive.

Thanks,

	Ingo