054f904
From: Jan Beulich <jbeulich@suse.com>
054f904
Subject: AMD/IOMMU: convert amd_iommu_pte from struct to union
054f904
054f904
This is to add a "raw" counterpart to the bitfield equivalent. Take the
054f904
opportunity and
054f904
 - convert fields to bool / unsigned int,
054f904
 - drop the naming of the reserved field,
054f904
 - shorten the names of the ignored ones.
054f904
054f904
This is part of XSA-347.
054f904
054f904
Signed-off-by: Jan Beulich <jbeulich@suse.com>
054f904
Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
054f904
Reviewed-by: Paul Durrant <paul@xen.org>
054f904
054f904
--- a/xen/drivers/passthrough/amd/iommu-defs.h
054f904
+++ b/xen/drivers/passthrough/amd/iommu-defs.h
054f904
@@ -451,20 +451,23 @@ union amd_iommu_x2apic_control {
054f904
 #define IOMMU_PAGE_TABLE_U32_PER_ENTRY	(IOMMU_PAGE_TABLE_ENTRY_SIZE / 4)
054f904
 #define IOMMU_PAGE_TABLE_ALIGNMENT	4096
054f904
 
054f904
-struct amd_iommu_pte {
054f904
-    uint64_t pr:1;
054f904
-    uint64_t ignored0:4;
054f904
-    uint64_t a:1;
054f904
-    uint64_t d:1;
054f904
-    uint64_t ignored1:2;
054f904
-    uint64_t next_level:3;
054f904
-    uint64_t mfn:40;
054f904
-    uint64_t reserved:7;
054f904
-    uint64_t u:1;
054f904
-    uint64_t fc:1;
054f904
-    uint64_t ir:1;
054f904
-    uint64_t iw:1;
054f904
-    uint64_t ignored2:1;
054f904
+union amd_iommu_pte {
054f904
+    uint64_t raw;
054f904
+    struct {
054f904
+        bool pr:1;
054f904
+        unsigned int ign0:4;
054f904
+        bool a:1;
054f904
+        bool d:1;
054f904
+        unsigned int ign1:2;
054f904
+        unsigned int next_level:3;
054f904
+        uint64_t mfn:40;
054f904
+        unsigned int :7;
054f904
+        bool u:1;
054f904
+        bool fc:1;
054f904
+        bool ir:1;
054f904
+        bool iw:1;
054f904
+        unsigned int ign2:1;
054f904
+    };
054f904
 };
054f904
 
054f904
 /* Paging modes */
054f904
--- a/xen/drivers/passthrough/amd/iommu_map.c
054f904
+++ b/xen/drivers/passthrough/amd/iommu_map.c
054f904
@@ -34,7 +34,7 @@ static unsigned int pfn_to_pde_idx(unsig
054f904
 static unsigned int clear_iommu_pte_present(unsigned long l1_mfn,
054f904
                                             unsigned long dfn)
054f904
 {
054f904
-    struct amd_iommu_pte *table, *pte;
054f904
+    union amd_iommu_pte *table, *pte;
054f904
     unsigned int flush_flags;
054f904
 
054f904
     table = map_domain_page(_mfn(l1_mfn));
054f904
@@ -48,7 +48,7 @@ static unsigned int clear_iommu_pte_pres
054f904
     return flush_flags;
054f904
 }
054f904
 
054f904
-static unsigned int set_iommu_pde_present(struct amd_iommu_pte *pte,
054f904
+static unsigned int set_iommu_pde_present(union amd_iommu_pte *pte,
054f904
                                           unsigned long next_mfn,
054f904
                                           unsigned int next_level, bool iw,
054f904
                                           bool ir)
054f904
@@ -83,7 +83,7 @@ static unsigned int set_iommu_pte_presen
054f904
                                           int pde_level,
054f904
                                           bool iw, bool ir)
054f904
 {
054f904
-    struct amd_iommu_pte *table, *pde;
054f904
+    union amd_iommu_pte *table, *pde;
054f904
     unsigned int flush_flags;
054f904
 
054f904
     table = map_domain_page(_mfn(pt_mfn));
054f904
@@ -174,7 +174,7 @@ void iommu_dte_set_guest_cr3(struct amd_
054f904
 static int iommu_pde_from_dfn(struct domain *d, unsigned long dfn,
054f904
                               unsigned long pt_mfn[], bool map)
054f904
 {
054f904
-    struct amd_iommu_pte *pde, *next_table_vaddr;
054f904
+    union amd_iommu_pte *pde, *next_table_vaddr;
054f904
     unsigned long  next_table_mfn;
054f904
     unsigned int level;
054f904
     struct page_info *table;
054f904
@@ -448,7 +448,7 @@ int __init amd_iommu_quarantine_init(str
054f904
     unsigned long end_gfn =
054f904
         1ul << (DEFAULT_DOMAIN_ADDRESS_WIDTH - PAGE_SHIFT);
054f904
     unsigned int level = amd_iommu_get_paging_mode(end_gfn);
054f904
-    struct amd_iommu_pte *table;
054f904
+    union amd_iommu_pte *table;
054f904
 
054f904
     if ( hd->arch.root_table )
054f904
     {
054f904
@@ -479,7 +479,7 @@ int __init amd_iommu_quarantine_init(str
054f904
 
054f904
         for ( i = 0; i < PTE_PER_TABLE_SIZE; i++ )
054f904
         {
054f904
-            struct amd_iommu_pte *pde = &table[i];
054f904
+            union amd_iommu_pte *pde = &table[i];
054f904
 
054f904
             /*
054f904
              * PDEs are essentially a subset of PTEs, so this function
054f904
--- a/xen/drivers/passthrough/amd/pci_amd_iommu.c
054f904
+++ b/xen/drivers/passthrough/amd/pci_amd_iommu.c
054f904
@@ -387,7 +387,7 @@ static void deallocate_next_page_table(s
054f904
 
054f904
 static void deallocate_page_table(struct page_info *pg)
054f904
 {
054f904
-    struct amd_iommu_pte *table_vaddr;
054f904
+    union amd_iommu_pte *table_vaddr;
054f904
     unsigned int index, level = PFN_ORDER(pg);
054f904
 
054f904
     PFN_ORDER(pg) = 0;
054f904
@@ -402,7 +402,7 @@ static void deallocate_page_table(struct
054f904
 
054f904
     for ( index = 0; index < PTE_PER_TABLE_SIZE; index++ )
054f904
     {
054f904
-        struct amd_iommu_pte *pde = &table_vaddr[index];
054f904
+        union amd_iommu_pte *pde = &table_vaddr[index];
054f904
 
054f904
         if ( pde->mfn && pde->next_level && pde->pr )
054f904
         {
054f904
@@ -554,7 +554,7 @@ static void amd_dump_p2m_table_level(str
054f904
                                      paddr_t gpa, int indent)
054f904
 {
054f904
     paddr_t address;
054f904
-    struct amd_iommu_pte *table_vaddr;
054f904
+    const union amd_iommu_pte *table_vaddr;
054f904
     int index;
054f904
 
054f904
     if ( level < 1 )
054f904
@@ -570,7 +570,7 @@ static void amd_dump_p2m_table_level(str
054f904
 
054f904
     for ( index = 0; index < PTE_PER_TABLE_SIZE; index++ )
054f904
     {
054f904
-        struct amd_iommu_pte *pde = &table_vaddr[index];
054f904
+        const union amd_iommu_pte *pde = &table_vaddr[index];
054f904
 
054f904
         if ( !(index % 2) )
054f904
             process_pending_softirqs();