[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [RFC PATCH] pvh: Introduce SIF_HVM_GHCB for SEV-ES/SNP guests



Le 28/12/2025 à 13:54, Teddy Astie a écrit :
> Under SEV, the pagetables needs to be post-processed to add the C-bit
> (to make the mapping encrypted). The guest is expected to query the C-bit
> through CPUID. However, under SEV-ES and SEV-SNP modes, this instruction
> now triggers #VC instead. The guest would need to setup a IDT very early
> and instead use the early-GHCB protocol to emulate CPUID, which is
> complicated.
>
> Alternatively, we can signal to the guest that it is a SEV-ES/SNP through
> start_info structure, which is visible to the guest early on. All SEV-ES/SNP
> guests have the GHCB MSR available, which can be trivially [1] used to get the
> C-bit and proceed with the initialization avoiding CPUID instruction.
>
> We integrate that to the PVH ABI and expect all SEV-enabled domain builders
> to honor this flag for simplifying the PVH entry point logic of guests.
>
> [1] Initial GHCB MSR value contains the C-bit. The guest can trivially read 
> this
> MSR and skip CPUID logic.
>
> Signed-off-by: Teddy Astie <teddy.astie@xxxxxxxxxx>
> ---
> Actually, C-bit itself cannot be a part of ABI as it is hardware-dependant
> (and even firmware configuration dependant).
> ---
>   docs/misc/pvh.pandoc     | 5 +++++
>   xen/include/public/xen.h | 2 ++
>   2 files changed, 7 insertions(+)
>
> diff --git a/docs/misc/pvh.pandoc b/docs/misc/pvh.pandoc
> index 3e18789d36..6453ee21eb 100644
> --- a/docs/misc/pvh.pandoc
> +++ b/docs/misc/pvh.pandoc
> @@ -44,6 +44,11 @@ using HVMPARAMS, just like it's done on HVM guests.
>   The setup of the hypercall page is also performed in the same way
>   as HVM guests, using the hypervisor cpuid leaves and msr ranges.
>
> +## SEV-ES/SNP guests ##
> +
> +The domain builder must set `SIF_HVM_GHCB` in start_info if the guest uses
> +SEV-ES or SEV-SNP technologies; i.e requires the use of GHCB protocol.
> +
>   ## AP startup ##
>
>   AP startup can be performed using hypercalls or the local APIC if present.
> diff --git a/xen/include/public/xen.h b/xen/include/public/xen.h
> index 7f15204c38..9b84df573b 100644
> --- a/xen/include/public/xen.h
> +++ b/xen/include/public/xen.h
> @@ -890,6 +890,8 @@ typedef struct start_info start_info_t;
>   #define SIF_MOD_START_PFN (1<<3)  /* Is mod_start a PFN? */
>   #define SIF_VIRT_P2M_4TOOLS (1<<4) /* Do Xen tools understand a virt. 
> mapped */
>                                      /* P->M making the 3 level tree 
> obsolete? */
> +#define SIF_HVM_GHCB      (1<<5)   /* Domain is SEV-ES/SNP guest that 
> requires */
> +                                   /* use of GHCB. */
>   #define SIF_PM_MASK       (0xFF<<8) /* reserve 1 byte for xen-pm options */
>
>   /*

As requested, here is how it could be used for Linux (the patch also
contains plain SEV support).

We check here for SEV-ES with

mov 8(%ebx), %edx (start_info->flags)
bt $5, %edx       (SIF_HVM_GHCB)

If checked, we then read GHCB MSR and extract C-bit from it and skip the
CPUID checks.
---
Subject: [RFC PATCH] pvh: Add SEV/SEV-ES support for PVH boot

When running as a SEV guest with PVH entrypoint, we need
to fixup the page tables to add the C-bit. Otherwise, the
transition to long mode fails as the pagetables are invalid
under SEV.

Signed-off-by: Teddy Astie <teddy.astie@xxxxxxxxxx>
---
  arch/x86/platform/pvh/head.S | 74 ++++++++++++++++++++++++++++++++++++
  include/xen/interface/xen.h  |  2 +
  2 files changed, 76 insertions(+)

diff --git a/arch/x86/platform/pvh/head.S b/arch/x86/platform/pvh/head.S
index 1d78e5631bb8..2b4d58350346 100644
--- a/arch/x86/platform/pvh/head.S
+++ b/arch/x86/platform/pvh/head.S
@@ -91,6 +91,64 @@ SYM_CODE_START(pvh_start_xen)

        leal rva(early_stack_end)(%ebp), %esp

+#ifdef CONFIG_AMD_MEM_ENCRYPT
+       /* Check SIF_HVM_GHCB flag in start_info informing us on SEV-ES/SNP */
+       mov 8(%ebx), %edx
+       bt $5, %edx
+       jnc .no_ghcb
+
+       /* Get C-bit through GHCB MSR. */
+       movl $MSR_AMD64_SEV_ES_GHCB, %ecx
+       rdmsr
+       /* C-bit is in EAX[31:24] */
+       shr $24, %eax
+       mov %eax, %ebx
+       jmp .sev_prepare_pgt
+
+.no_ghcb:
+       /* Check CPUID highest leaf */
+       mov $0x80000000, %eax
+       cpuid
+       cmp $0x8000001f, %eax
+       jb .skip_sev_prepare_pgt
+
+       /* Check for SEV support */
+       mov $0x8000001f, %eax
+       cpuid
+       bt $1, %eax
+       jnc .skip_sev_prepare_pgt
+
+.sev_prepare_pgt:
+       /* Check if SEV is enabled */
+       mov $MSR_AMD64_SEV, %ecx
+       rdmsr
+       bt $MSR_AMD64_SEV_ENABLED_BIT, %eax
+       jnc .skip_sev_prepare_pgt
+
+       mov %ebx, %ecx
+       and $0x3f, %ecx /* Get C-bit position */
+       sub $0x20, %ecx
+       mov $1, %eax
+       shl %cl, %eax
+
+       leal rva(pvh_init_top_pgt)(%ebp), %esi
+       call set_pgtable_cbit
+
+       leal rva(pvh_level3_ident_pgt)(%ebp), %esi
+       call set_pgtable_cbit
+
+       leal rva(pvh_level3_kernel_pgt)(%ebp), %esi
+       call set_pgtable_cbit
+
+       leal rva(pvh_level2_ident_pgt)(%ebp), %esi
+       call set_pgtable_cbit
+
+       leal rva(pvh_level2_kernel_pgt)(%ebp), %esi
+       call set_pgtable_cbit
+
+.skip_sev_prepare_pgt:
+#endif
+
        /* Enable PAE mode. */
        mov %cr4, %eax
        orl $X86_CR4_PAE, %eax
@@ -223,6 +281,22 @@ SYM_CODE_START(pvh_start_xen)
  #endif
  SYM_CODE_END(pvh_start_xen)

+#ifdef CONFIG_AMD_MEM_ENCRYPT
+SYM_FUNC_START_LOCAL(set_pgtable_cbit)
+       .code32
+       mov $512, %ecx
+       xor %edx, %edx
+.L2:
+       testl $_PAGE_PRESENT, 0(%esi,%edx,8)
+       jz .L3
+       or %eax, 4(%esi,%edx,8)
+.L3:
+       inc %edx
+       loop .L2
+       RET
+SYM_FUNC_END(set_pgtable_cbit)
+#endif
+
        .section ".init.data","aw"
        .balign 8
  SYM_DATA_START_LOCAL(gdt)
diff --git a/include/xen/interface/xen.h b/include/xen/interface/xen.h
index 0ca23eca2a9c..c1a4e3dca0a3 100644
--- a/include/xen/interface/xen.h
+++ b/include/xen/interface/xen.h
@@ -654,6 +654,8 @@ struct start_info {
  #define SIF_MOD_START_PFN   (1<<3)  /* Is mod_start a PFN? */
  #define SIF_VIRT_P2M_4TOOLS (1<<4)  /* Do Xen tools understand a virt.
mapped */
                                    /* P->M making the 3 level tree obsolete? */
+#define SIF_HVM_GHCB        (1<<5)  /* Domain is SEV-ES/SNP guest so
require */
+                                    /* use of GHCB protocol. */
  #define SIF_PM_MASK       (0xFF<<8) /* reserve 1 byte for xen-pm
options */

  /*
--
2.52.0




--
Teddy Astie | Vates XCP-ng Developer

XCP-ng & Xen Orchestra - Vates solutions

web: https://vates.tech





 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.