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] Improved handling of non-RAM pages. Deal with RAM holes.

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] Improved handling of non-RAM pages. Deal with RAM holes.
From: BitKeeper Bot <riel@xxxxxxxxxxx>
Date: Thu, 14 Apr 2005 20:49:01 +0000
Delivery-date: Thu, 14 Apr 2005 21:03:09 +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.1159.256.93, 2005/04/14 21:49:01+01:00, kaf24@xxxxxxxxxxxxxxxxxxxx

        Improved handling of non-RAM pages. Deal with RAM holes.
        Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx>



 arch/x86/memory.c      |   80 +++++++++++++++++++++++++++++++++----------------
 common/grant_table.c   |    2 -
 include/asm-x86/page.h |    9 -----
 3 files changed, 57 insertions(+), 34 deletions(-)


diff -Nru a/xen/arch/x86/memory.c b/xen/arch/x86/memory.c
--- a/xen/arch/x86/memory.c     2005-04-14 17:03:17 -04:00
+++ b/xen/arch/x86/memory.c     2005-04-14 17:03:17 -04:00
@@ -101,6 +101,7 @@
 #include <asm/uaccess.h>
 #include <asm/domain_page.h>
 #include <asm/ldt.h>
+#include <asm/e820.h>
 
 #ifdef VERBOSE
 #define MEM_LOG(_f, _a...)                           \
@@ -168,7 +169,8 @@
 
 void arch_init_memory(void)
 {
-    unsigned long i;
+    unsigned long i, j, pfn, nr_pfns;
+    struct pfn_info *page;
 
     /*
      * We are rather picky about the layout of 'struct pfn_info'. The
@@ -203,8 +205,8 @@
 
     /*
      * Initialise our DOMID_IO domain.
-     * This domain owns no pages but is considered a special case when
-     * mapping I/O pages, as the mappings occur at the priv of the caller.
+     * This domain owns I/O pages that are within the range of the pfn_info
+     * array. Mappings occur at the priv of the caller.
      */
     dom_io = alloc_domain_struct();
     atomic_set(&dom_io->refcnt, 1);
@@ -213,11 +215,40 @@
     /* M2P table is mappable read-only by privileged domains. */
     for ( i = 0; i < 1024; 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. */
-        frame_table[m2p_start_mfn+i].u.inuse.type_info = PGT_gdt_page | 1;
-        frame_table[m2p_start_mfn+i].u.inuse.domain    = dom_xen;
+       /* Ensure it's mapped read-only by guests (use GDT type). */
+        page = &frame_table[m2p_start_mfn+i];
+        page->count_info        = PGC_allocated | 1;
+        page->u.inuse.type_info = PGT_gdt_page | PGT_validated | 1;
+        page->u.inuse.domain    = dom_xen;
+    }
+
+    /* First 1MB of RAM is historically marked as I/O. */
+    for ( i = 0; i < 0x100; i++ )
+    {
+        page = &frame_table[i];
+        page->count_info        = PGC_allocated | 1;
+        page->u.inuse.type_info = PGT_writable_page | PGT_validated | 1;
+        page->u.inuse.domain    = dom_io;
+    }
+ 
+    /* Any non-RAM areas in the e820 map are considered to be for I/O. */
+    for ( i = 0; i < e820.nr_map; i++ )
+    {
+        if ( e820.map[i].type == E820_RAM )
+            continue;
+        pfn = e820.map[i].addr >> PAGE_SHIFT;
+        nr_pfns = (e820.map[i].size +
+                   (e820.map[i].addr & ~PAGE_MASK) +
+                   ~PAGE_MASK) >> PAGE_SHIFT;
+        for ( j = 0; j < nr_pfns; j++ )
+        {
+            if ( !pfn_valid(pfn+j) )
+                continue;
+            page = &frame_table[pfn+j];
+            page->count_info        = PGC_allocated | 1;
+            page->u.inuse.type_info = PGT_writable_page | PGT_validated | 1;
+            page->u.inuse.domain    = dom_io;
+        }
     }
 }
 
@@ -298,13 +329,7 @@
 {
     struct pfn_info *page = &frame_table[page_nr];
 
-    if ( unlikely(!pfn_is_ram(page_nr)) )
-    {
-        MEM_LOG("Pfn %08lx is not RAM", page_nr);
-        return 0;
-    }
-
-    if ( unlikely(!get_page(page, d)) )
+    if ( unlikely(!pfn_valid(page_nr)) || unlikely(!get_page(page, d)) )
     {
         MEM_LOG("Could not get page ref for pfn %08lx", page_nr);
         return 0;
@@ -410,20 +435,25 @@
         return 0;
     }
 
-    if ( unlikely(!pfn_is_ram(pfn)) )
+    if ( unlikely(!pfn_valid(pfn)) ||
+         unlikely(page->u.inuse.domain == dom_io) )
     {
-        /* Revert to caller privileges if FD == DOMID_IO. */
+        /* DOMID_IO reverts to caller for privilege checks. */
         if ( d == dom_io )
             d = current;
 
-        if ( IS_PRIV(d) )
-            return 1;
+        if ( (!IS_PRIV(d)) &&
+             (!IS_CAPABLE_PHYSDEV(d) || !domain_iomem_in_pfn(d, pfn)) )
+        {
+            MEM_LOG("Non-privileged attempt to map I/O space %08lx", pfn);
+            return 0;
+        }
 
-        if ( IS_CAPABLE_PHYSDEV(d) )
-            return domain_iomem_in_pfn(d, pfn);
+        /* No reference counting for out-of-range I/O pages. */
+        if ( !pfn_valid(pfn) )
+            return 1;
 
-        MEM_LOG("Non-privileged attempt to map I/O space %08lx", pfn);
-        return 0;
+        d = dom_io;
     }
 
     return ((l1v & _PAGE_RW) ?
@@ -468,7 +498,7 @@
     struct pfn_info *page = &frame_table[pfn];
     struct domain   *e;
 
-    if ( !(l1v & _PAGE_PRESENT) || !pfn_is_ram(pfn) )
+    if ( !(l1v & _PAGE_PRESENT) || !pfn_valid(pfn) )
         return;
 
     e = page->u.inuse.domain;
@@ -1114,7 +1144,7 @@
         gntref = (grant_ref_t)((val & 0xFF00) | ((ptr >> 2) & 0x00FF));
         
         if ( unlikely(IS_XEN_HEAP_FRAME(page)) ||
-             unlikely(!pfn_is_ram(pfn)) ||
+             unlikely(!pfn_valid(pfn)) ||
              unlikely((e = find_domain_by_id(domid)) == NULL) )
         {
             MEM_LOG("Bad frame (%08lx) or bad domid (%d).\n", pfn, domid);
diff -Nru a/xen/common/grant_table.c b/xen/common/grant_table.c
--- a/xen/common/grant_table.c  2005-04-14 17:03:17 -04:00
+++ b/xen/common/grant_table.c  2005-04-14 17:03:17 -04:00
@@ -169,7 +169,7 @@
 
         /* rmb(); */ /* not on x86 */
         frame = sha->frame;
-        if ( unlikely(!pfn_is_ram(frame)) || 
+        if ( unlikely(!pfn_valid(frame)) || 
              unlikely(!((flags & GNTMAP_readonly) ? 
                         get_page(&frame_table[frame], rd) : 
                         get_page_and_type(&frame_table[frame], rd, 
diff -Nru a/xen/include/asm-x86/page.h b/xen/include/asm-x86/page.h
--- a/xen/include/asm-x86/page.h        2005-04-14 17:03:17 -04:00
+++ b/xen/include/asm-x86/page.h        2005-04-14 17:03:17 -04:00
@@ -105,14 +105,7 @@
 #define pfn_to_page(_pfn)       (frame_table + (_pfn))
 #define phys_to_page(kaddr)     (frame_table + ((kaddr) >> PAGE_SHIFT))
 #define virt_to_page(kaddr)    (frame_table + (__pa(kaddr) >> PAGE_SHIFT))
-#define VALID_PAGE(page)       ((page - frame_table) < max_mapnr)
-
-/*
- * NB. We don't currently track I/O holes in the physical RAM space.
- * For now we guess that I/O devices will be mapped in the first 1MB
- * (e.g., VGA buffers) or beyond the end of physical RAM.
- */
-#define pfn_is_ram(_pfn)        (((_pfn) > 0x100) && ((_pfn) < max_page))
+#define pfn_valid(_pfn)         ((_pfn) < max_page)
 
 /* High table entries are reserved by the hypervisor. */
 #define DOMAIN_ENTRIES_PER_L2_PAGETABLE            \

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

<Prev in Thread] Current Thread [Next in Thread>