On Sun, 14 Jun 2026 at 20:09, Michael S. Tsirkin <[email protected]> wrote:
>
> From: Sairaj Kodilkar <[email protected]>
>
> When MMIO 0x18[IntCapXTEn]=1, interrupts originating from the IOMMU itself are
> sent based on the programming in XT IOMMU Interrupt Control Registers in MMIO
> 0x170-0x180 instead of the programming in the IOMMU's MSI capability 
> registers.
> The guest programs these registers with appropriate vector and destination
> ID instead of writing to PCI MSI capability.
>
> Current AMD vIOMMU is capable of generating interrupts only through PCI
> MSI capability and does not care about xt mode. Because of this AMD
> vIOMMU cannot generate event log interrupts when the guest has enabled
> xt mode.
>
> Introduce a new flag "intcapxten" which is set when guest writes control
> register [IntCapXTEn] (bit 51) and use vector and destination field in
> the XT MMIO register (0x170) to support XT mode.

Hi; Coverity points out a use of an uninitialized struct field here
(CID 1660056):

> +static void amdvi_build_xt_msi_msg(AMDVIState *s, MSIMessage *msg)
> +{
> +    union mmio_xt_intr xt_reg;
> +    struct X86IOMMUIrq irq;

Here we declare irq, without a struct initializer...

> +
> +    xt_reg.val = amdvi_readq(s, AMDVI_MMIO_XT_GEN_INTR);
> +
> +    irq.vector = xt_reg.vector;
> +    irq.delivery_mode = xt_reg.delivery_mode;
> +    irq.dest_mode = xt_reg.destination_mode;
> +    irq.dest = (xt_reg.destination_hi << 24) | xt_reg.destination_lo;
> +    irq.trigger_mode = 0;
> +    irq.redir_hint = 0;

...and here we fill in some but not all of its fields...

> +
> +    x86_iommu_irq_to_msi_message(&irq, msg);

...and here we call a function which (among other things) does this:
   msg.__not_used = irq->msi_addr_last_bits;

which will read the uninitialized msi_addr_last_bits field.

Bonus extra bug report:

+union mmio_xt_intr {
+    uint64_t val;
+    struct {
+        uint64_t rsvd_1:2,
+                 destination_mode:1,
+                 rsvd_2:5,
+                 destination_lo:24,
+                 vector:8,
+                 delivery_mode:1,
+                 rsvd_3:15,
+                 destination_hi:8;
+    };
+};

Please don't use bitfields like this -- this is not portable to big
endian hosts. Use the extract64() function instead, or the FIELD macros.

I suggest something like (untested):

(at top level in a source file or header; the numbers are
start-bit and length, check these as I may have made typos)

FIELD(XT_GEN_INTR, DEST_MODE, 2, 1)
FIELD(XT_GEN_INTR, DEST_LO, 24, 8)
FIELD(XT_GEN_INTR, VECTOR, 32, 8)
FIELD(XT_GEN_INTR, DELIVERY_MODE, 33, 1)
FIELD(XT_GEN_INTR, DEST_HI, 49, 8)

and then in the function you can do:

   uint64_t xtreg = amdvi_readq(s, AMDVI_MMIO_XT_GEN_INTR);
   X86IOMMUIrq irq = {
       .vector = FIELD_EX64(xtreg, XT_GEN_INTR, VECTOR),
       .delivery_mode = FIELD_EX64(xtreg, XT_GEN_INTR, DELIVERY_MODE),
       .dest_mode = FIELD_EX64(xtreg, XT_GEN_INTR, DEST_MODE),
       .dest = (FIELD_X64(xtreg, XT_GEN_INTR, DEST_HI) << 24) |
FIELD_EX64(xtreg, XT_GEN_INTR, DEST_LO),
   };

which gives you a struct initializer and you can rely on the
whole struct being initialized.

> +}

thanks
-- PMM

Reply via email to