[PATCH v4 03/24] x86/sev: Use MSR protocol only for early SVSM PVALIDATE call

Ard Biesheuvel posted 24 patches 3 months ago
There is a newer version of this series
[PATCH v4 03/24] x86/sev: Use MSR protocol only for early SVSM PVALIDATE call
Posted by Ard Biesheuvel 3 months ago
From: Ard Biesheuvel <ardb@kernel.org>

The early page state change API performs an SVSM call to PVALIDATE each
page when running under a SVSM, and this involves either a GHCB page
based call or a call based on the MSR protocol.

The GHCB page based variant involves VA to PA translation of the GHCB
address, and this is best avoided in the startup code, where virtual
addresses are ambiguous (1:1 or kernel virtual).

As this is the last remaining occurrence of svsm_perform_call_protocol()
in the startup code, switch to the MSR protocol exclusively in this
particular case, so that the GHCB based plumbing can be moved out of the
startup code entirely in a subsequent patch.

Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
---
 arch/x86/boot/compressed/sev.c     | 20 --------------------
 arch/x86/boot/startup/sev-shared.c |  4 +++-
 2 files changed, 3 insertions(+), 21 deletions(-)

diff --git a/arch/x86/boot/compressed/sev.c b/arch/x86/boot/compressed/sev.c
index fd1b67dfea22..b71c1ab6a282 100644
--- a/arch/x86/boot/compressed/sev.c
+++ b/arch/x86/boot/compressed/sev.c
@@ -50,31 +50,11 @@ u64 svsm_get_caa_pa(void)
 	return boot_svsm_caa_pa;
 }
 
-int svsm_perform_call_protocol(struct svsm_call *call);
-
 u8 snp_vmpl;
 
 /* Include code for early handlers */
 #include "../../boot/startup/sev-shared.c"
 
-int svsm_perform_call_protocol(struct svsm_call *call)
-{
-	struct ghcb *ghcb;
-	int ret;
-
-	if (boot_ghcb)
-		ghcb = boot_ghcb;
-	else
-		ghcb = NULL;
-
-	do {
-		ret = ghcb ? svsm_perform_ghcb_protocol(ghcb, call)
-			   : svsm_perform_msr_protocol(call);
-	} while (ret == -EAGAIN);
-
-	return ret;
-}
-
 static bool sev_snp_enabled(void)
 {
 	return sev_status & MSR_AMD64_SEV_SNP_ENABLED;
diff --git a/arch/x86/boot/startup/sev-shared.c b/arch/x86/boot/startup/sev-shared.c
index 992abfa50508..1bb4b522dfaa 100644
--- a/arch/x86/boot/startup/sev-shared.c
+++ b/arch/x86/boot/startup/sev-shared.c
@@ -753,7 +753,9 @@ static void __head svsm_pval_4k_page(unsigned long paddr, bool validate)
 	call.rax = SVSM_CORE_CALL(SVSM_CORE_PVALIDATE);
 	call.rcx = pc_pa;
 
-	ret = svsm_perform_call_protocol(&call);
+	do {
+		ret = svsm_perform_msr_protocol(&call);
+	} while (ret == -EAGAIN);
 	if (ret)
 		sev_es_terminate(SEV_TERM_SET_LINUX, GHCB_TERM_PVALIDATE);
 
-- 
2.50.0.727.gbf7dc18ff4-goog
Re: [PATCH v4 03/24] x86/sev: Use MSR protocol only for early SVSM PVALIDATE call
Posted by Tom Lendacky 2 months, 4 weeks ago
On 7/9/25 03:08, Ard Biesheuvel wrote:
> From: Ard Biesheuvel <ardb@kernel.org>
> 
> The early page state change API performs an SVSM call to PVALIDATE each
> page when running under a SVSM, and this involves either a GHCB page
> based call or a call based on the MSR protocol.
> 
> The GHCB page based variant involves VA to PA translation of the GHCB
> address, and this is best avoided in the startup code, where virtual
> addresses are ambiguous (1:1 or kernel virtual).
> 
> As this is the last remaining occurrence of svsm_perform_call_protocol()
> in the startup code, switch to the MSR protocol exclusively in this
> particular case, so that the GHCB based plumbing can be moved out of the
> startup code entirely in a subsequent patch.
> 
> Signed-off-by: Ard Biesheuvel <ardb@kernel.org>

Reviewed-by: Tom Lendacky <thomas.lendacky@amd.com>

With some comments below.

> ---
>  arch/x86/boot/compressed/sev.c     | 20 --------------------
>  arch/x86/boot/startup/sev-shared.c |  4 +++-
>  2 files changed, 3 insertions(+), 21 deletions(-)
> 
> diff --git a/arch/x86/boot/compressed/sev.c b/arch/x86/boot/compressed/sev.c
> index fd1b67dfea22..b71c1ab6a282 100644
> --- a/arch/x86/boot/compressed/sev.c
> +++ b/arch/x86/boot/compressed/sev.c
> @@ -50,31 +50,11 @@ u64 svsm_get_caa_pa(void)
>  	return boot_svsm_caa_pa;
>  }
>  
> -int svsm_perform_call_protocol(struct svsm_call *call);
> -
>  u8 snp_vmpl;
>  
>  /* Include code for early handlers */
>  #include "../../boot/startup/sev-shared.c"
>  
> -int svsm_perform_call_protocol(struct svsm_call *call)
> -{
> -	struct ghcb *ghcb;
> -	int ret;
> -
> -	if (boot_ghcb)
> -		ghcb = boot_ghcb;
> -	else
> -		ghcb = NULL;
> -
> -	do {
> -		ret = ghcb ? svsm_perform_ghcb_protocol(ghcb, call)
> -			   : svsm_perform_msr_protocol(call);
> -	} while (ret == -EAGAIN);
> -
> -	return ret;
> -}
> -
>  static bool sev_snp_enabled(void)
>  {
>  	return sev_status & MSR_AMD64_SEV_SNP_ENABLED;
> diff --git a/arch/x86/boot/startup/sev-shared.c b/arch/x86/boot/startup/sev-shared.c
> index 992abfa50508..1bb4b522dfaa 100644
> --- a/arch/x86/boot/startup/sev-shared.c
> +++ b/arch/x86/boot/startup/sev-shared.c
> @@ -753,7 +753,9 @@ static void __head svsm_pval_4k_page(unsigned long paddr, bool validate)
>  	call.rax = SVSM_CORE_CALL(SVSM_CORE_PVALIDATE);
>  	call.rcx = pc_pa;
>  
> -	ret = svsm_perform_call_protocol(&call);
> +	do {
> +		ret = svsm_perform_msr_protocol(&call);
> +	} while (ret == -EAGAIN);

There's no comment here, like in the previous change, about why we are
using this method directly. Can one be added?

Also, this makes the second place where this do-while call to the MSR
protocol is used, maybe a common function would be good to have now.

Thanks,
Tom

>  	if (ret)
>  		sev_es_terminate(SEV_TERM_SET_LINUX, GHCB_TERM_PVALIDATE);
>