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

Teddy Astie posted 1 patch 1 week, 2 days ago
docs/misc/pvh.pandoc     | 5 +++++
xen/include/public/xen.h | 2 ++
2 files changed, 7 insertions(+)
[RFC PATCH] pvh: Introduce SIF_HVM_GHCB for SEV-ES/SNP guests
Posted by Teddy Astie 1 week, 2 days ago
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@vates.tech>
---
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 */
 
 /*
-- 
2.52.0



--
Teddy Astie | Vates XCP-ng Developer

XCP-ng & Xen Orchestra - Vates solutions

web: https://vates.tech
Re: [RFC PATCH] pvh: Introduce SIF_HVM_GHCB for SEV-ES/SNP guests
Posted by Jan Beulich 1 week, 2 days ago
On 28.12.2025 13:49, Teddy Astie wrote:
> 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.

But isn't this going to be needed for plain HVM anyway?

> --- 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. */

Naming-wise, do we really want to tie this to AMD (and hence exclude other
vendors, or require yet another bit to be allocated later)?

Jan
Re: [RFC PATCH] pvh: Introduce SIF_HVM_GHCB for SEV-ES/SNP guests
Posted by Teddy Astie 1 week, 1 day ago
Le 29/12/2025 à 09:24, Jan Beulich a écrit :
> On 28.12.2025 13:49, Teddy Astie wrote:
>> 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.
> 
> But isn't this going to be needed for plain HVM anyway?
> 

This hint is only relevant for PVH entry point. The other guest boot 
paths can still rely on other mechanisms, e.g UEFI boot doesn't rely on 
the IDT approach and relies instead on the UEFI firmware to provide the 
early GHCB handler for the OS.

 From a Linux implementation standpoint, as PVH entry-point doesn't live 
in compressed/ boot code of Linux, the early-GHCB handlers 
(do_vc_no_ghcb and do_boot_stage2_vc) don't exist from there; so we 
either need to reimplement in non-compressed code or use another approach.

>> --- 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. */
> 
> Naming-wise, do we really want to tie this to AMD (and hence exclude other
> vendors, or require yet another bit to be allocated later)?
> 

This is SEV-ES/SNP only, I don't think the same bit can be reused for 
another technology (unless it also uses the GHCB MSR). As the guest 
can't even check if it is Intel or AMD CPU at this point (if running 
under SEV-ES or SEV-SNP).

> Jan
> 

Teddy


--
Teddy Astie | Vates XCP-ng Developer

XCP-ng & Xen Orchestra - Vates solutions

web: https://vates.tech
Re: [RFC PATCH] pvh: Introduce SIF_HVM_GHCB for SEV-ES/SNP guests
Posted by Jan Beulich 1 week, 1 day ago
On 29.12.2025 13:39, Teddy Astie wrote:
> Le 29/12/2025 à 09:24, Jan Beulich a écrit :
>> On 28.12.2025 13:49, Teddy Astie wrote:
>>> --- 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. */
>>
>> Naming-wise, do we really want to tie this to AMD (and hence exclude other
>> vendors, or require yet another bit to be allocated later)?
> 
> This is SEV-ES/SNP only, I don't think the same bit can be reused for 
> another technology (unless it also uses the GHCB MSR). As the guest 
> can't even check if it is Intel or AMD CPU at this point (if running 
> under SEV-ES or SEV-SNP).

If it was just telling AMD from Intel, that would be possible. There are
a few well-known differences in how certain instructions behave [1]. But
here you aren't after telling apart the vendors; you want to know whether
you're (fundamentally) on SVM or VT-x.

Of course I have to admit that I find it quite irritating that in order
to execute CPUID one has to have a #VC handler properly set up. This
inverses the typical flow of events. Did they really not think of some
replacement for at least the most basic information?

Jan

[1] Of course, such details can change going forward. Vendors did alter
the behavior of certain insns in the past.

Re: [RFC PATCH] pvh: Introduce SIF_HVM_GHCB for SEV-ES/SNP guests
Posted by Teddy Astie 1 day, 18 hours ago
Le 29/12/2025 à 15:16, Jan Beulich a écrit :
> On 29.12.2025 13:39, Teddy Astie wrote:
>> Le 29/12/2025 à 09:24, Jan Beulich a écrit :
>>> On 28.12.2025 13:49, Teddy Astie wrote:
>>>> --- 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. */
>>>
>>> Naming-wise, do we really want to tie this to AMD (and hence exclude other
>>> vendors, or require yet another bit to be allocated later)?
>>
>> This is SEV-ES/SNP only, I don't think the same bit can be reused for
>> another technology (unless it also uses the GHCB MSR). As the guest
>> can't even check if it is Intel or AMD CPU at this point (if running
>> under SEV-ES or SEV-SNP).
> 
> If it was just telling AMD from Intel, that would be possible. There are
> a few well-known differences in how certain instructions behave [1]. But
> here you aren't after telling apart the vendors; you want to know whether
> you're (fundamentally) on SVM or VT-x.
> 
> Of course I have to admit that I find it quite irritating that in order
> to execute CPUID one has to have a #VC handler properly set up. This
> inverses the typical flow of events. Did they really not think of some
> replacement for at least the most basic information?
> 

Yes, but only with more information beforehand.

Regarding the #VC approach, the negociation example also state this
 > The above example is just one way to perform the GHCB negotiation for 
an SEV-ES guest. For example, you could use the GHCBInfo = 0x004 CPUID 
Request to obtain actual values for the CPUID instructions executed by 
the guest. Or you could use the GHCBInfo = 0x002 Request for SEV 
Information if MSR 0xc001_0130 does not contain the GHCBInfo = 0x001 SEV 
Information.

But that only works as long as you know GHCB MSR is available; which you 
may be able to check through SEV_STATUS MSR; but this MSR is only 
meaningful on CPUs that supports SEV (APM says the hypervisor cannot 
intercept these MSRs). This proposal aims to give this information to 
the guest through the start_info structure.

Under SEV-ES/SNP, the hypervisor cannot fake EFER MSR which in this case 
may have forced guest-visible EFER:SVME, it could be a way to check for 
SEV-ES for but it's quite hacky and fragile.
(I still need to test this though)

> Jan
> 
> [1] Of course, such details can change going forward. Vendors did alter
> the behavior of certain insns in the past.
> 


--
Teddy Astie | Vates XCP-ng Developer

XCP-ng & Xen Orchestra - Vates solutions

web: https://vates.tech