WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

[Xen-changelog] Fix page-table initialisation (MPT, linear mappings, an

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] Fix page-table initialisation (MPT, linear mappings, and mapcache).
From: BitKeeper Bot <riel@xxxxxxxxxxx>
Date: Thu, 02 Jun 2005 16:47:08 +0000
Delivery-date: Thu, 02 Jun 2005 17:01:41 +0000
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: Xen Development List <xen-devel@xxxxxxxxxxxxxxxxxxx>
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
ChangeSet 1.1640, 2005/06/02 17:47:08+01:00, kaf24@xxxxxxxxxxxxxxxxxxxx

        Fix page-table initialisation (MPT, linear mappings, and mapcache).
        In particular, we were mapping garbage pages into the idle page
        directory which caused bogus unflushable mappings to get speculatively
        loaded into the TLB (nasty crashes).
        Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx>



 arch/x86/x86_32/domain_page.c        |   10 +---
 arch/x86/x86_32/mm.c                 |   85 +++++++++++++++--------------------
 include/asm-x86/x86_32/domain_page.h |    3 -
 3 files changed, 44 insertions(+), 54 deletions(-)


diff -Nru a/xen/arch/x86/x86_32/domain_page.c 
b/xen/arch/x86/x86_32/domain_page.c
--- a/xen/arch/x86/x86_32/domain_page.c 2005-06-02 13:02:32 -04:00
+++ b/xen/arch/x86/x86_32/domain_page.c 2005-06-02 13:02:32 -04:00
@@ -29,13 +29,11 @@
 static void flush_all_ready_maps(void)
 {
     l1_pgentry_t *cache = mapcache;
+    unsigned int i;
 
-    /* A bit skanky -- depends on having an aligned PAGE_SIZE set of PTEs. */
-    do {
-        if ( (l1e_get_flags(*cache) & READY_FOR_TLB_FLUSH) )
-            *cache = l1e_empty();
-    }
-    while ( ((unsigned long)(++cache) & ~PAGE_MASK) != 0 );
+    for ( i = 0; i < MAPCACHE_ENTRIES; i++ )
+        if ( (l1e_get_flags(cache[i]) & READY_FOR_TLB_FLUSH) )
+            cache[i] = l1e_empty();
 }
 
 
diff -Nru a/xen/arch/x86/x86_32/mm.c b/xen/arch/x86/x86_32/mm.c
--- a/xen/arch/x86/x86_32/mm.c  2005-06-02 13:02:32 -04:00
+++ b/xen/arch/x86/x86_32/mm.c  2005-06-02 13:02:32 -04:00
@@ -59,8 +59,9 @@
 void __init paging_init(void)
 {
     void *ioremap_pt;
-    unsigned long v,v2,i;
+    unsigned long v;
     struct pfn_info *pg;
+    int i, mapcache_order;
 
 #ifdef CONFIG_X86_PAE
     printk("PAE enabled, limit: %d GB\n", MACHPHYS_MBYTES);
@@ -70,64 +71,56 @@
 
     idle0_exec_domain.arch.monitor_table = mk_pagetable(__pa(idle_pg_table));
 
-    /* Allocate and map the machine-to-phys table and create read-only
-     * mapping of MPT for guest-OS use.  Without PAE we'll end up with
-     * one 4MB page, with PAE we'll allocate 2MB pages depending on
-     * the amout of memory installed, but at least 4MB to cover 4GB
-     * address space.  This is needed to make PCI I/O memory address
-     * lookups work in guests. -- kraxel */
-    mpt_size = max_page * 4;
-    if (mpt_size < 4*1024*1024)
+    /*
+     * Allocate and map the machine-to-phys table and create read-only mapping 
+     * of MPT for guest-OS use.  Without PAE we'll end up with one 4MB page, 
+     * with PAE we'll allocate 2MB pages depending on the amount of memory 
+     * installed, but at least 4MB to cover 4GB address space.  This is needed 
+     * to make PCI I/O memory address lookups work in guests.
+     */
+    if ( (mpt_size = max_page * 4) < (4*1024*1024) )
         mpt_size = 4*1024*1024;
-    for (v  = RDWR_MPT_VIRT_START, v2 = RO_MPT_VIRT_START;
-         v != RDWR_MPT_VIRT_END && mpt_size > (v - RDWR_MPT_VIRT_START);
-         v += (1 << L2_PAGETABLE_SHIFT), v2 += (1 << L2_PAGETABLE_SHIFT)) {
+    for ( i = 0; i < (mpt_size >> L2_PAGETABLE_SHIFT); i++ )
+    {
         if ( (pg = alloc_domheap_pages(NULL, PAGETABLE_ORDER)) == NULL )
             panic("Not enough memory to bootstrap Xen.\n");
-        idle_pg_table_l2[l2_linear_offset(v)] =
+        idle_pg_table_l2[l2_linear_offset(RDWR_MPT_VIRT_START) + i] =
             l2e_from_page(pg, __PAGE_HYPERVISOR | _PAGE_PSE);
-        idle_pg_table_l2[l2_linear_offset(v2)] =
+        idle_pg_table_l2[l2_linear_offset(RO_MPT_VIRT_START) + i] =
             l2e_from_page(pg, (__PAGE_HYPERVISOR | _PAGE_PSE) & ~_PAGE_RW);
     }
     memset((void *)RDWR_MPT_VIRT_START, 0x55, mpt_size);
 
-    /* Xen 2/4MB mappings can all be GLOBAL. */
+    /* Xen PSE mappings can all be GLOBAL. */
     if ( cpu_has_pge )
     {
-        for ( v = HYPERVISOR_VIRT_START; v; v += (1 << L2_PAGETABLE_SHIFT) ) {
-            if (!l2e_get_flags(idle_pg_table_l2[l2_linear_offset(v)]) & 
_PAGE_PSE)
+        for ( v = HYPERVISOR_VIRT_START; v; v += (1 << L2_PAGETABLE_SHIFT) )
+        {
+            if ( (l2e_get_flags(idle_pg_table_l2[l2_linear_offset(v)]) &
+                  (_PAGE_PSE|_PAGE_PRESENT)) != (_PAGE_PSE|_PAGE_PRESENT) )
                 continue;
-            if (v >= RO_MPT_VIRT_START && v < RO_MPT_VIRT_END)
+            if ( (v >= RO_MPT_VIRT_START) && (v < RO_MPT_VIRT_END) )
                 continue;
-            l2e_add_flags(idle_pg_table_l2[l2_linear_offset(v)],
-                          _PAGE_GLOBAL);
+            l2e_add_flags(idle_pg_table_l2[l2_linear_offset(v)], _PAGE_GLOBAL);
         }
     }
 
-    /* Create page table(s) for ioremap(). */
-    for (v = IOREMAP_VIRT_START; v != IOREMAP_VIRT_END; v += (1 << 
L2_PAGETABLE_SHIFT)) {
+    /* Create page tables for ioremap(). */
+    for ( i = 0; i < (IOREMAP_MBYTES >> (L2_PAGETABLE_SHIFT - 20)); i++ )
+    {
         ioremap_pt = (void *)alloc_xenheap_page();
         clear_page(ioremap_pt);
-        idle_pg_table_l2[l2_linear_offset(v)] =
+        idle_pg_table_l2[l2_linear_offset(IOREMAP_VIRT_START) + i] =
             l2e_from_page(virt_to_page(ioremap_pt), __PAGE_HYPERVISOR);
     }
 
     /* Set up mapping cache for domain pages. */
-    mapcache = (l1_pgentry_t*)alloc_xenheap_pages(10-PAGETABLE_ORDER);
-    for (v = MAPCACHE_VIRT_START, i = 0;
-         v != MAPCACHE_VIRT_END;
-         v += (1 << L2_PAGETABLE_SHIFT), i++) {
-        clear_page(mapcache + i*L1_PAGETABLE_ENTRIES);
-        idle_pg_table_l2[l2_linear_offset(v)] =
-            l2e_from_page(virt_to_page(mapcache + i*L1_PAGETABLE_ENTRIES),
-                            __PAGE_HYPERVISOR);
-    }
-
-    for (v = LINEAR_PT_VIRT_START; v != LINEAR_PT_VIRT_END; v += (1 << 
L2_PAGETABLE_SHIFT)) {
-        idle_pg_table_l2[l2_linear_offset(v)] =
-            l2e_from_page(virt_to_page(idle_pg_table_l2 + 
((v-RDWR_MPT_VIRT_START) >> PAGETABLE_ORDER)),
-                            __PAGE_HYPERVISOR);
-    }
+    mapcache_order = get_order(MAPCACHE_MBYTES << (20 - PAGETABLE_ORDER));
+    mapcache = (l1_pgentry_t *)alloc_xenheap_pages(mapcache_order);
+    memset(mapcache, 0, PAGE_SIZE << mapcache_order);
+    for ( i = 0; i < (MAPCACHE_MBYTES >> (L2_PAGETABLE_SHIFT - 20)); i++ )
+        idle_pg_table_l2[l2_linear_offset(MAPCACHE_VIRT_START) + i] =
+            l2e_from_page(virt_to_page(mapcache) + i, __PAGE_HYPERVISOR);
 }
 
 void __init zap_low_mappings(l2_pgentry_t *base)
@@ -148,7 +141,8 @@
 
 void subarch_init_memory(struct domain *dom_xen)
 {
-    unsigned long i, v, m2p_start_mfn;
+    unsigned long m2p_start_mfn;
+    int i;
 
     /*
      * We are rather picky about the layout of 'struct pfn_info'. The
@@ -164,21 +158,18 @@
                offsetof(struct pfn_info, count_info),
                offsetof(struct pfn_info, u.inuse._domain),
                sizeof(struct pfn_info));
-        for ( ; ; )
-            __asm__ __volatile__ ( "hlt" );
+        BUG();
     }
 
     /* M2P table is mappable read-only by privileged domains. */
-    for (v  = RDWR_MPT_VIRT_START;
-         v != RDWR_MPT_VIRT_END && mpt_size > (v - RDWR_MPT_VIRT_START);
-         v += (1 << L2_PAGETABLE_SHIFT)) {
+    for ( i = 0; i < (mpt_size >> L2_PAGETABLE_SHIFT); i++ )
+    {
         m2p_start_mfn = l2e_get_pfn(
-            idle_pg_table_l2[l2_linear_offset(v)]);
+            idle_pg_table_l2[l2_linear_offset(RDWR_MPT_VIRT_START) + i]);
         for ( i = 0; i < L2_PAGETABLE_ENTRIES; i++ )
         {
             frame_table[m2p_start_mfn+i].count_info = PGC_allocated | 1;
-            /* gdt to make sure it's only mapped read-only by non-privileged
-               domains. */
+            /* Ensure it's only mapped read-only by domains. */
             frame_table[m2p_start_mfn+i].u.inuse.type_info = PGT_gdt_page | 1;
             page_set_owner(&frame_table[m2p_start_mfn+i], dom_xen);
         }
diff -Nru a/xen/include/asm-x86/x86_32/domain_page.h 
b/xen/include/asm-x86/x86_32/domain_page.h
--- a/xen/include/asm-x86/x86_32/domain_page.h  2005-06-02 13:02:32 -04:00
+++ b/xen/include/asm-x86/x86_32/domain_page.h  2005-06-02 13:02:32 -04:00
@@ -11,7 +11,8 @@
 #include <xen/sched.h>
 
 extern l1_pgentry_t *mapcache;
-#define MAPCACHE_ENTRIES        1024
+#define MAPCACHE_ORDER    10
+#define MAPCACHE_ENTRIES  (1 << MAPCACHE_ORDER)
 
 /*
  * Maps a given physical address, returning corresponding virtual address.

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] Fix page-table initialisation (MPT, linear mappings, and mapcache)., BitKeeper Bot <=