aboutsummaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorThomas Huth <thuth@redhat.com>2023-08-02 15:57:19 +0200
committerMichael Tokarev <mjt@tls.msk.ru>2023-08-04 19:14:46 +0300
commitb3c94ecf3c36fde253759cd0a3dc85da1afce007 (patch)
treee1cbc6d2aa871ae432c3e90ab5ad4c16400d847b /include
parentbc5740e1783ceb14897548bbc5250e62ea0549d5 (diff)
downloadqemu-b3c94ecf3c36fde253759cd0a3dc85da1afce007.zip
qemu-b3c94ecf3c36fde253759cd0a3dc85da1afce007.tar.gz
qemu-b3c94ecf3c36fde253759cd0a3dc85da1afce007.tar.bz2
hw/i386/intel_iommu: Fix endianness problems related to VTD_IR_TableEntry
The code already tries to do some endianness handling here, but currently fails badly: - While it already swaps the data when logging errors / tracing, it fails to byteswap the value before e.g. accessing entry->irte.present - entry->irte.source_id is swapped with le32_to_cpu(), though this is a 16-bit value - The whole union is apparently supposed to be swapped via the 64-bit data[2] array, but the struct is a mixture between 32 bit values (the first 8 bytes) and 64 bit values (the second 8 bytes), so this cannot work as expected. Fix it by converting the struct to two proper 64-bit bitfields, and by swapping the values only once for everybody right after reading the data from memory. Signed-off-by: Thomas Huth <thuth@redhat.com> Message-Id: <20230802135723.178083-3-thuth@redhat.com> Reviewed-by: Michael S. Tsirkin <mst@redhat.com> Signed-off-by: Michael S. Tsirkin <mst@redhat.com> Reviewed-by: Peter Xu <peterx@redhat.com> (cherry picked from commit 642ba89672279fbdd14016a90da239c85e845d18) Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
Diffstat (limited to 'include')
-rw-r--r--include/hw/i386/intel_iommu.h50
1 files changed, 26 insertions, 24 deletions
diff --git a/include/hw/i386/intel_iommu.h b/include/hw/i386/intel_iommu.h
index 89dcbc5..7fa0a69 100644
--- a/include/hw/i386/intel_iommu.h
+++ b/include/hw/i386/intel_iommu.h
@@ -178,37 +178,39 @@ enum {
union VTD_IR_TableEntry {
struct {
#if HOST_BIG_ENDIAN
- uint32_t __reserved_1:8; /* Reserved 1 */
- uint32_t vector:8; /* Interrupt Vector */
- uint32_t irte_mode:1; /* IRTE Mode */
- uint32_t __reserved_0:3; /* Reserved 0 */
- uint32_t __avail:4; /* Available spaces for software */
- uint32_t delivery_mode:3; /* Delivery Mode */
- uint32_t trigger_mode:1; /* Trigger Mode */
- uint32_t redir_hint:1; /* Redirection Hint */
- uint32_t dest_mode:1; /* Destination Mode */
- uint32_t fault_disable:1; /* Fault Processing Disable */
- uint32_t present:1; /* Whether entry present/available */
+ uint64_t dest_id:32; /* Destination ID */
+ uint64_t __reserved_1:8; /* Reserved 1 */
+ uint64_t vector:8; /* Interrupt Vector */
+ uint64_t irte_mode:1; /* IRTE Mode */
+ uint64_t __reserved_0:3; /* Reserved 0 */
+ uint64_t __avail:4; /* Available spaces for software */
+ uint64_t delivery_mode:3; /* Delivery Mode */
+ uint64_t trigger_mode:1; /* Trigger Mode */
+ uint64_t redir_hint:1; /* Redirection Hint */
+ uint64_t dest_mode:1; /* Destination Mode */
+ uint64_t fault_disable:1; /* Fault Processing Disable */
+ uint64_t present:1; /* Whether entry present/available */
#else
- uint32_t present:1; /* Whether entry present/available */
- uint32_t fault_disable:1; /* Fault Processing Disable */
- uint32_t dest_mode:1; /* Destination Mode */
- uint32_t redir_hint:1; /* Redirection Hint */
- uint32_t trigger_mode:1; /* Trigger Mode */
- uint32_t delivery_mode:3; /* Delivery Mode */
- uint32_t __avail:4; /* Available spaces for software */
- uint32_t __reserved_0:3; /* Reserved 0 */
- uint32_t irte_mode:1; /* IRTE Mode */
- uint32_t vector:8; /* Interrupt Vector */
- uint32_t __reserved_1:8; /* Reserved 1 */
+ uint64_t present:1; /* Whether entry present/available */
+ uint64_t fault_disable:1; /* Fault Processing Disable */
+ uint64_t dest_mode:1; /* Destination Mode */
+ uint64_t redir_hint:1; /* Redirection Hint */
+ uint64_t trigger_mode:1; /* Trigger Mode */
+ uint64_t delivery_mode:3; /* Delivery Mode */
+ uint64_t __avail:4; /* Available spaces for software */
+ uint64_t __reserved_0:3; /* Reserved 0 */
+ uint64_t irte_mode:1; /* IRTE Mode */
+ uint64_t vector:8; /* Interrupt Vector */
+ uint64_t __reserved_1:8; /* Reserved 1 */
+ uint64_t dest_id:32; /* Destination ID */
#endif
- uint32_t dest_id; /* Destination ID */
- uint16_t source_id; /* Source-ID */
#if HOST_BIG_ENDIAN
uint64_t __reserved_2:44; /* Reserved 2 */
uint64_t sid_vtype:2; /* Source-ID Validation Type */
uint64_t sid_q:2; /* Source-ID Qualifier */
+ uint64_t source_id:16; /* Source-ID */
#else
+ uint64_t source_id:16; /* Source-ID */
uint64_t sid_q:2; /* Source-ID Qualifier */
uint64_t sid_vtype:2; /* Source-ID Validation Type */
uint64_t __reserved_2:44; /* Reserved 2 */