[svsm-devel] Extended Interrupt Information

Melody (Huibo) Wang huibo.wang at amd.com
Sun May 4 22:27:56 CEST 2025


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