From da6d0af41d66e8c54c430454e534499c289ba47b Mon Sep 17 00:00:00 2001 From: Thomas Huth Date: Wed, 2 Aug 2023 15:57:23 +0200 Subject: [PATCH] include/hw/i386/x86-iommu: Fix struct X86IOMMU_MSIMessage for big endian hosts The first bitfield here is supposed to be used as a 64-bit equivalent to the "uint64_t msi_addr" in the union. To make this work correctly on big endian hosts, too, the __addr_hi field has to be part of the bitfield, and the the bitfield members must be declared with "uint64_t" instead of "uint32_t" - otherwise the values are placed in the wrong bytes on big endian hosts. Same applies to the 32-bit "msi_data" field: __resved1 must be part of the bitfield, and the members must be declared with "uint32_t" instead of "uint16_t". Signed-off-by: Thomas Huth Message-Id: <20230802135723.178083-7-thuth@redhat.com> Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin Reviewed-by: Peter Xu (cherry picked from commit e1e56c07d1fa24aa37a7e89e6633768fc8ea8705) Signed-off-by: Michael Tokarev --- include/hw/i386/x86-iommu.h | 50 +++++++++++++++++++------------------ 1 file changed, 26 insertions(+), 24 deletions(-) diff --git a/include/hw/i386/x86-iommu.h b/include/hw/i386/x86-iommu.h index 7637edb430..02dc2fe9ee 100644 --- a/include/hw/i386/x86-iommu.h +++ b/include/hw/i386/x86-iommu.h @@ -88,40 +88,42 @@ struct X86IOMMU_MSIMessage { union { struct { #if HOST_BIG_ENDIAN - uint32_t __addr_head:12; /* 0xfee */ - uint32_t dest:8; - uint32_t __reserved:8; - uint32_t redir_hint:1; - uint32_t dest_mode:1; - uint32_t __not_used:2; + uint64_t __addr_hi:32; + uint64_t __addr_head:12; /* 0xfee */ + uint64_t dest:8; + uint64_t __reserved:8; + uint64_t redir_hint:1; + uint64_t dest_mode:1; + uint64_t __not_used:2; #else - uint32_t __not_used:2; - uint32_t dest_mode:1; - uint32_t redir_hint:1; - uint32_t __reserved:8; - uint32_t dest:8; - uint32_t __addr_head:12; /* 0xfee */ + uint64_t __not_used:2; + uint64_t dest_mode:1; + uint64_t redir_hint:1; + uint64_t __reserved:8; + uint64_t dest:8; + uint64_t __addr_head:12; /* 0xfee */ + uint64_t __addr_hi:32; #endif - uint32_t __addr_hi; } QEMU_PACKED; uint64_t msi_addr; }; union { struct { #if HOST_BIG_ENDIAN - uint16_t trigger_mode:1; - uint16_t level:1; - uint16_t __resved:3; - uint16_t delivery_mode:3; - uint16_t vector:8; + uint32_t __resved1:16; + uint32_t trigger_mode:1; + uint32_t level:1; + uint32_t __resved:3; + uint32_t delivery_mode:3; + uint32_t vector:8; #else - uint16_t vector:8; - uint16_t delivery_mode:3; - uint16_t __resved:3; - uint16_t level:1; - uint16_t trigger_mode:1; + uint32_t vector:8; + uint32_t delivery_mode:3; + uint32_t __resved:3; + uint32_t level:1; + uint32_t trigger_mode:1; + uint32_t __resved1:16; #endif - uint16_t __resved1; } QEMU_PACKED; uint32_t msi_data; };