[svsm-devel] [EXTERNAL] Extended Interrupt Information

Jon Lange jlange at microsoft.com
Wed May 7 22:49:17 CEST 2025


Correct.  The #HV doorbell info is 256 bytes total, with 64 bytes dedicated to each VMPL.  The first four bytes of each 64 bytes have identical formats across VMPLs, but the vmpl[123]_irq fields are only meaningful in the area associated with VMPL 0.  The next 28 bytes (pending interrupt vector bitmap) also have identical formats across VMPLs.  The last 32 bytes of each 64 bytes are reserved in case we need to define new per-VMPL information in the future.

-Jon

-----Original Message-----
From: Melody (Huibo) Wang <huibo.wang at amd.com> 
Sent: Wednesday, May 7, 2025 1:44 PM
To: Jon Lange <jlange at microsoft.com>
Cc: Lendacky, Thomas <Thomas.Lendacky at amd.com>; Jörg Rödel <joro at 8bytes.org>; svsm-devel at coconut-svsm.dev
Subject: Re: [EXTERNAL] Extended Interrupt Information

Hi Jon,

I am updating the GHCB spec with Alternate Injection info. 

Regarding this paragraph in the AI spec: "To indicate separate interrupt sources for each VMPL, the #HV doorbell page is further extended to define the first 256 bytes. Bytes 0-31 contain interrupt information associated with VMPL0 itself." 

So this is 256 bytes in total (!) and the first 4 bytes - PendingEvent and InjectionInfo - are included in those 256 bytes, correct?

The layout is NOT PendingEvent, InjectionInfo, 256 more bytes for a total of 260 bytes, right?

IOW, the first 4 bytes are part of the SVSM interrupt information, which is how I did it in my test program.

Sorry but I would like to absolutely make sure this is crystal clear in the GHCB spec so that there are no ambiguities.

Thanks a lot!

Melody



On 5/5/2025 3:31 PM, Melody (Huibo) Wang wrote:
> Thanks for confirming, it helps. :)
> 
> Thanks,
> Melody
> 
> On 5/5/2025 3:19 PM, Jon Lange wrote:
>> I believe your definitions are correct.
>>
>> -Jon
>>
>> -----Original Message-----
>> From: Melody (Huibo) Wang <huibo.wang at amd.com>
>> Sent: Sunday, May 4, 2025 1:28 PM
>> To: Jon Lange <jlange at microsoft.com>
>> Cc: Lendacky, Thomas <Thomas.Lendacky at amd.com>; Jörg Rödel 
>> <joro at 8bytes.org>; svsm-devel at coconut-svsm.dev
>> Subject: [EXTERNAL] Extended Interrupt Information
>>
>> Hi Jon,
>>
>> I have written a small C program that implements the new #HV doorbell page with extended interrupt information. 
>>
>> Could you please confirm that my reading of the spec is correct, especially fields layout and order? 
>>
>> #include <errno.h>
>> #include <stdio.h>
>> #include <stdlib.h>
>> #include <string.h>
>> #include <assert.h>
>>
>> #define PAGE_SIZE		4096
>>
>> #define DIV_ROUND_UP(n,d)	(((n) + (d) - 1) / (d))
>>
>> #define BITS_PER_TYPE(type)	(sizeof(type) * 8)
>> #define BITS_TO_LONGS(nr)	DIV_ROUND_UP(nr, BITS_PER_TYPE(long))
>>
>> #define DECLARE_BITMAP(name,bits) \
>> 	unsigned long name[BITS_TO_LONGS(bits)]
>>
>> typedef unsigned char u8;
>> typedef unsigned short u16;
>>
>> /*
>>  * Hypervisor doorbell page:
>>  *
>>  * Used when restricted injection is enabled for a VM. One page in 
>> size that
>>  * is shared between the guest and hypervisor to communicate 
>> exception and
>>  * interrupt events.
>>  */
>> struct ext_irq_desc {
>> 	/* first 16-bit word */
>> 	struct {
>> 		u16 si_vector:		8,
>> 		    nmi:		1,
>> 		    mce:		1,
>> 		    trigger_mode:	1,
>> 		    reserved1:		3,
>> 		    multi_interrupts:	1,
>> 		    reserved2:		1;
>> 	} word0;
>>
>> 	/* Second 16-bit word */
>> 	struct {
>> 		u16 reserved5:		15,
>> 		    interrupt_vector:	1;
>> 	} word1;
>>
>> 	/*
>> 	 * Set the corresponding vmpl?_irq bit in inj_info after setting
>> 	 * multiple bits here.
>> 	 */
>>         u16 interrupt_bit_vector[14];
>>
>> 	/*
>> 	 * Reserved for future use.
>> 	 * TODO: Code should check them and fail if set.
>> 	 */
>>         u8 reserved6[32];
>> } __attribute__((packed));
>>
>> struct hvdb {
>> 	/* first 16-bit word PendingEvent */
>> 	struct {
>> 		/* Non-maskable event indicators */
>> 		u16 reserved1:          8,
>> 		nmi:                    1,
>> 		mce:                    1,
>> 		reserved2:              5,
>> 		no_further_signal:      1;
>> 	} pending_event;
>>
>> 	/* Second 16-bit word InjectionInfo */
>> 	union {
>> 		struct {
>> 			u16 no_eoi_required:	1,
>> 			    reserved3:		7,
>> 			    vmpl1_irq:		1,
>> 			    vmpl2_irq:		1,
>> 			    vmpl3_irq:		1,
>> 			    reserved4:		4;
>> 		} inj_info;
>> 		u16 injection_info;
>> 	};
>>
>> 	/* IRQ info associated with the SVSM itself */
>> 	/* XXX: code should enforce bytes [32-63] are zero */
>> 	u8 svsm_irq_info[64 - 4];
>>
>> 	/* VMPL[1-3] extended IRQ descriptors */
>>         struct ext_irq_desc irqs[3];
>>
>>         /* Remainder of the page is for software use */
>>         u8 reserved[PAGE_SIZE - 256]; } __attribute__((packed));
>>
>> int main(void)
>> {
>> 	struct hvdb h = { };
>>
>> 	assert(sizeof(struct ext_irq_desc) == 64);
>>
>> 	printf("sizeof(struct ext_irq_desc): %zu\n", sizeof(struct 
>> ext_irq_desc));
>>
>> 	h.inj_info.no_eoi_required = 1;
>> 	h.inj_info.vmpl3_irq = 1;
>>
>> 	printf("injection_info: 0x%x\n", h.injection_info);
>>
>> 	return 0;
>> }
>>
>>
>> Thanks,
>> Melody
> 



More information about the Svsm-devel mailing list