[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [PATCH 2/8] x86/EPT: simplification and cleanup



- drop rsvd*_ prefixes from fields not really reserved anymore
- replace odd uses of <expr> ? 1 : 0
- drop pointless variables from ept_set_entry()
- streamline IOMMU mirroring code in ept_set_entry()
- don't open code is_epte_valid() (and properly use it when dumping)
- streamline entry cloning in ept_split_super_page()
- compact dumping code and output

Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx>

--- a/xen/arch/x86/mm/p2m-ept.c
+++ b/xen/arch/x86/mm/p2m-ept.c
@@ -182,14 +182,13 @@ static int ept_split_super_page(struct p
     {
         ept_entry_t *epte = table + i;
 
-        epte->epte = 0;
-        epte->emt = ept_entry->emt;
-        epte->ipat = ept_entry->ipat;
-        epte->sp = (level > 1) ? 1 : 0;
-        epte->access = ept_entry->access;
-        epte->sa_p2mt = ept_entry->sa_p2mt;
-        epte->mfn = ept_entry->mfn + i * trunk;
-        epte->rsvd2_snp = ( iommu_enabled && iommu_snoop ) ? 1 : 0;
+        *epte = *ept_entry;
+        epte->sp = (level > 1);
+        epte->mfn += i * trunk;
+        epte->snp = (iommu_enabled && iommu_snoop);
+        ASSERT(!epte->rsvd1);
+        ASSERT(!epte->avail1);
+        ASSERT(!epte->avail3);
 
         ept_p2m_type_to_flags(epte, epte->sa_p2mt, epte->access);
 
@@ -281,8 +280,6 @@ ept_set_entry(struct p2m_domain *p2m, un
 {
     ept_entry_t *table, *ept_entry = NULL;
     unsigned long gfn_remainder = gfn;
-    unsigned long offset = 0;
-    u32 index;
     int i, target = order / EPT_TABLE_ORDER;
     int rv = 0;
     int ret = 0;
@@ -324,13 +321,10 @@ ept_set_entry(struct p2m_domain *p2m, un
 
     ASSERT(ret != GUEST_TABLE_POD_PAGE || i != target);
 
-    index = gfn_remainder >> (i * EPT_TABLE_ORDER);
-    offset = gfn_remainder & ((1UL << (i * EPT_TABLE_ORDER)) - 1);
-
-    ept_entry = table + index;
+    ept_entry = table + (gfn_remainder >> (i * EPT_TABLE_ORDER));
 
     /* In case VT-d uses same page table, this flag is needed by VT-d */ 
-    vtd_pte_present = is_epte_present(ept_entry) ? 1 : 0;
+    vtd_pte_present = is_epte_present(ept_entry);
 
     /*
      * If we're here with i > target, we must be at a leaf node, and
@@ -364,7 +358,7 @@ ept_set_entry(struct p2m_domain *p2m, un
                                                 direct_mmio);
 
             new_entry.ipat = ipat;
-            new_entry.sp = order ? 1 : 0;
+            new_entry.sp = !!order;
             new_entry.sa_p2mt = p2mt;
             new_entry.access = p2ma;
             new_entry.rsvd2_snp = (iommu_enabled && iommu_snoop);
@@ -406,17 +400,14 @@ ept_set_entry(struct p2m_domain *p2m, un
         /* We just installed the pages we need. */
         ASSERT(i == target);
 
-        index = gfn_remainder >> (i * EPT_TABLE_ORDER);
-        offset = gfn_remainder & ((1UL << (i * EPT_TABLE_ORDER)) - 1);
-
-        ept_entry = table + index;
+        ept_entry = table + (gfn_remainder >> (i * EPT_TABLE_ORDER));
 
         new_entry.emt = epte_get_entry_emt(d, gfn, mfn, &ipat, direct_mmio);
         new_entry.ipat = ipat;
-        new_entry.sp = i ? 1 : 0;
+        new_entry.sp = !!i;
         new_entry.sa_p2mt = p2mt;
         new_entry.access = p2ma;
-        new_entry.rsvd2_snp = (iommu_enabled && iommu_snoop);
+        new_entry.snp = (iommu_enabled && iommu_snoop);
 
         /* the caller should take care of the previous page */
         new_entry.mfn = mfn_x(mfn);
@@ -445,36 +436,20 @@ out:
         ept_sync_domain(p2m);
 
     /* For non-nested p2m, may need to change VT-d page table.*/
-    if ( rv && !p2m_is_nestedp2m(p2m) && iommu_enabled &&
-         need_iommu(p2m->domain) && need_modify_vtd_table )
+    if ( rv && !p2m_is_nestedp2m(p2m) && need_iommu(d) &&
+         need_modify_vtd_table )
     {
         if ( iommu_hap_pt_share )
-            iommu_pte_flush(d, gfn, (u64*)ept_entry, order, vtd_pte_present);
+            iommu_pte_flush(d, gfn, &ept_entry->epte, order, vtd_pte_present);
         else
         {
             if ( p2mt == p2m_ram_rw )
-            {
-                if ( order > 0 )
-                {
-                    for ( i = 0; i < (1 << order); i++ )
-                        iommu_map_page(
-                            p2m->domain, gfn - offset + i, mfn_x(mfn) - offset 
+ i,
-                            IOMMUF_readable | IOMMUF_writable);
-                }
-                else if ( !order )
-                    iommu_map_page(
-                        p2m->domain, gfn, mfn_x(mfn), IOMMUF_readable | 
IOMMUF_writable);
-            }
+                for ( i = 0; i < (1 << order); i++ )
+                    iommu_map_page(d, gfn + i, mfn_x(mfn) + i,
+                                   IOMMUF_readable | IOMMUF_writable);
             else
-            {
-                if ( order > 0 )
-                {
-                    for ( i = 0; i < (1 << order); i++ )
-                        iommu_unmap_page(p2m->domain, gfn - offset + i);
-                }
-                else if ( !order )
-                    iommu_unmap_page(p2m->domain, gfn);
-            }
+                for ( i = 0; i < (1 << order); i++ )
+                    iommu_unmap_page(d, gfn + i);
         }
     }
 
@@ -558,9 +533,7 @@ static mfn_t ept_get_entry(struct p2m_do
             goto out;
     }
 
-    /* Need to check for all-zeroes because typecode 0 is p2m_ram and an
-     * entirely empty entry shouldn't have RAM type. */
-    if ( ept_entry->epte != 0 && ept_entry->sa_p2mt != p2m_invalid )
+    if ( is_epte_valid(ept_entry) )
     {
         *t = ept_entry->sa_p2mt;
         *a = ept_entry->access;
@@ -750,12 +723,9 @@ static void ept_dump_p2m_table(unsigned 
 {
     struct domain *d;
     ept_entry_t *table, *ept_entry;
-    mfn_t mfn;
     int order;
     int i;
-    int is_pod;
     int ret = 0;
-    unsigned long index;
     unsigned long gfn, gfn_remainder;
     unsigned long record_counter = 0;
     struct p2m_domain *p2m;
@@ -768,12 +738,11 @@ static void ept_dump_p2m_table(unsigned 
 
         p2m = p2m_get_hostp2m(d);
         ept = &p2m->ept;
-        printk("\ndomain%d EPT p2m table: \n", d->domain_id);
+        printk("\ndomain%d EPT p2m table:\n", d->domain_id);
 
-        for ( gfn = 0; gfn <= p2m->max_mapped_pfn; gfn += (1 << order) )
+        for ( gfn = 0; gfn <= p2m->max_mapped_pfn; gfn += 1UL << order )
         {
             gfn_remainder = gfn;
-            mfn = _mfn(INVALID_MFN);
             table = map_domain_page(pagetable_get_pfn(p2m_get_pagetable(p2m)));
 
             for ( i = ept_get_wl(ept); i > 0; i-- )
@@ -784,25 +753,18 @@ static void ept_dump_p2m_table(unsigned 
             }
 
             order = i * EPT_TABLE_ORDER;
-
-            if ( ret == GUEST_TABLE_MAP_FAILED )
-                goto out;
-
-            index = gfn_remainder >> order;
-            ept_entry = table + index;
-            if ( ept_entry->sa_p2mt != p2m_invalid )
+            ept_entry = table + (gfn_remainder >> order);
+            if ( ret != GUEST_TABLE_MAP_FAILED && is_epte_valid(ept_entry) )
             {
-                ( ept_entry->sa_p2mt == p2m_populate_on_demand ) ? 
-                ( mfn = _mfn(INVALID_MFN), is_pod = 1 ) :
-                ( mfn = _mfn(ept_entry->mfn), is_pod = 0 );
-
-                printk("gfn: %-16lx  mfn: %-16lx  order: %2d  is_pod: %d\n",
-                       gfn, mfn_x(mfn), order, is_pod);
+                if ( ept_entry->sa_p2mt == p2m_populate_on_demand )
+                    printk("gfn: %13lx order: %2d PoD\n", gfn, order);
+                else
+                    printk("gfn: %13lx order: %2d mfn: %13lx\n",
+                           gfn, order, ept_entry->mfn + 0UL);
 
                 if ( !(record_counter++ % 100) )
                     process_pending_softirqs();
             }
-out:
             unmap_domain_page(table);
         }
     }
--- a/xen/include/asm-x86/hvm/vmx/vmx.h
+++ b/xen/include/asm-x86/hvm/vmx/vmx.h
@@ -39,13 +39,13 @@ typedef union {
         sp          :   1,  /* bit 7 - Is this a superpage? */
         rsvd1       :   2,  /* bits 9:8 - Reserved for future use */
         avail1      :   1,  /* bit 10 - Software available 1 */
-        rsvd2_snp   :   1,  /* bit 11 - Used for VT-d snoop control
-                               in shared EPT/VT-d usage */
+        snp         :   1,  /* bit 11 - VT-d snoop control in shared
+                               EPT/VT-d usage */
         mfn         :   40, /* bits 51:12 - Machine physical frame number */
         sa_p2mt     :   6,  /* bits 57:52 - Software available 2 */
         access      :   4,  /* bits 61:58 - p2m_access_t */
-        rsvd3_tm    :   1,  /* bit 62 - Used for VT-d transient-mapping
-                               hint in shared EPT/VT-d usage */
+        tm          :   1,  /* bit 62 - VT-d transient-mapping hint in
+                               shared EPT/VT-d usage */
         avail3      :   1;  /* bit 63 - Software available 3 */
     };
     u64 epte;


Attachment: EPT-simplify.patch
Description: Text document

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.