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

[Xen-changelog] [MINIOS] Various address-space fixes.



# HG changeset patch
# User kaf24@xxxxxxxxxxxxxxxxxxxx
# Node ID b3b5f3ff2100d5a497583f2b2dbdce1399623dcf
# Parent  2c0cd4075d1cdebf53dbeeb22b6a443dd2dc2405
[MINIOS] Various address-space fixes.

1. Make Mini-OS start from 0x0.
2. Fixes the pagetable builder to handle half full, but already mapped
pt frames.=20
3. Add a bounds check to ensure than Mini-OS does not try to use Xen
virtual space.

Signed-off-by: Grzegorz Milos <gm281@xxxxxxxxx>
Signed-off-by: Aravindh Puthiyaparambil
<aravindh.puthiyaparambil@xxxxxxxxxx>
---
 extras/mini-os/include/mm.h      |   21 +++------
 extras/mini-os/minios-x86_32.lds |    2 
 extras/mini-os/minios-x86_64.lds |    2 
 extras/mini-os/mm.c              |   90 +++++++++++++++++++++++++++++++++------
 extras/mini-os/x86_32.S          |    4 -
 extras/mini-os/x86_64.S          |    4 -
 6 files changed, 91 insertions(+), 32 deletions(-)

diff -r 2c0cd4075d1c -r b3b5f3ff2100 extras/mini-os/include/mm.h
--- a/extras/mini-os/include/mm.h       Wed May 31 07:41:33 2006 +0100
+++ b/extras/mini-os/include/mm.h       Wed May 31 07:43:06 2006 +0100
@@ -53,7 +53,7 @@
 #define PADDR_BITS              32
 #define PADDR_MASK              (~0UL)
 
-#define UNMAPPED_PT_FRAMES        1
+#define NOT_L1_FRAMES           1
 #define PRIpte "08lx"
 typedef unsigned long pgentry_t;
 
@@ -71,7 +71,12 @@ typedef unsigned long pgentry_t;
 
 #define L2_MASK  ((1UL << L3_PAGETABLE_SHIFT) - 1)
 
-#define UNMAPPED_PT_FRAMES        2
+/*
+ * If starting from virtual address greater than 0xc0000000,
+ * this value will be 2 to account for final mid-level page
+ * directory which is always mapped in at this location.
+ */
+#define NOT_L1_FRAMES           3
 #define PRIpte "016llx"
 typedef uint64_t pgentry_t;
 
@@ -94,20 +99,10 @@ typedef uint64_t pgentry_t;
 #define PADDR_MASK              ((1UL << PADDR_BITS)-1)
 #define VADDR_MASK              ((1UL << VADDR_BITS)-1)
 
-/* Get physical address of page mapped by pte (paddr_t). */
-#define l1e_get_paddr(x)           \
-    ((unsigned long)(((x) & (PADDR_MASK&PAGE_MASK))))
-#define l2e_get_paddr(x)           \
-    ((unsigned long)(((x) & (PADDR_MASK&PAGE_MASK))))
-#define l3e_get_paddr(x)           \
-    ((unsigned long)(((x) & (PADDR_MASK&PAGE_MASK))))
-#define l4e_get_paddr(x)           \
-    ((unsigned long)(((x) & (PADDR_MASK&PAGE_MASK))))
-
 #define L2_MASK  ((1UL << L3_PAGETABLE_SHIFT) - 1)
 #define L3_MASK  ((1UL << L4_PAGETABLE_SHIFT) - 1)
 
-#define UNMAPPED_PT_FRAMES        3
+#define NOT_L1_FRAMES           3
 #define PRIpte "016lx"
 typedef unsigned long pgentry_t;
 
diff -r 2c0cd4075d1c -r b3b5f3ff2100 extras/mini-os/minios-x86_32.lds
--- a/extras/mini-os/minios-x86_32.lds  Wed May 31 07:41:33 2006 +0100
+++ b/extras/mini-os/minios-x86_32.lds  Wed May 31 07:43:06 2006 +0100
@@ -3,7 +3,7 @@ ENTRY(_start)
 ENTRY(_start)
 SECTIONS
 {
-  . = 0xC0000000;
+  . = 0x0;
   _text = .;                   /* Text and read-only data */
   .text : {
        *(.text)
diff -r 2c0cd4075d1c -r b3b5f3ff2100 extras/mini-os/minios-x86_64.lds
--- a/extras/mini-os/minios-x86_64.lds  Wed May 31 07:41:33 2006 +0100
+++ b/extras/mini-os/minios-x86_64.lds  Wed May 31 07:43:06 2006 +0100
@@ -3,7 +3,7 @@ ENTRY(_start)
 ENTRY(_start)
 SECTIONS
 {
-  . = 0xFFFFFFFF80000000;
+  . = 0x0;
   _text = .;                   /* Text and read-only data */
   .text : {
        *(.text)
diff -r 2c0cd4075d1c -r b3b5f3ff2100 extras/mini-os/mm.c
--- a/extras/mini-os/mm.c       Wed May 31 07:41:33 2006 +0100
+++ b/extras/mini-os/mm.c       Wed May 31 07:43:06 2006 +0100
@@ -375,7 +375,7 @@ void new_pt_frame(unsigned long *pt_pfn,
     struct mmuext_op pin_request;
     
     DEBUG("Allocating new L%d pt frame for pt_pfn=%lx, "
-           "prev_l_mfn=%lx, offset=%lx\n", 
+           "prev_l_mfn=%lx, offset=%lx", 
            level, *pt_pfn, prev_l_mfn, offset);
 
     /* We need to clear the page, otherwise we might fail to map it
@@ -442,12 +442,64 @@ void new_pt_frame(unsigned long *pt_pfn,
     mmu_updates[0].ptr = ((pgentry_t)prev_l_mfn << PAGE_SHIFT) + 
sizeof(pgentry_t) * offset;
     mmu_updates[0].val = (pgentry_t)pfn_to_mfn(*pt_pfn) << PAGE_SHIFT | prot_t;
     if(HYPERVISOR_mmu_update(mmu_updates, 1, NULL, DOMID_SELF) < 0) 
-    {            
+    {
        printk("ERROR: mmu_update failed\n");
        do_exit();
     }
 
     *pt_pfn += 1;
+}
+
+/* Checks if a pagetable frame is needed (if weren't allocated by Xen) */
+static int need_pt_frame(unsigned long virt_address, int level)
+{
+    unsigned long hyp_virt_start = HYPERVISOR_VIRT_START;
+#if defined(__x86_64__)
+    unsigned long hyp_virt_end = HYPERVISOR_VIRT_END;
+#else
+    unsigned long hyp_virt_end = 0xffffffff;
+#endif
+
+    /* In general frames will _not_ be needed if they were already
+       allocated to map the hypervisor into our VA space */
+#if defined(__x86_64__)
+    if(level == L3_FRAME)
+    {
+        if(l4_table_offset(virt_address) >= 
+           l4_table_offset(hyp_virt_start) &&
+           l4_table_offset(virt_address) <= 
+           l4_table_offset(hyp_virt_end))
+            return 0;
+        return 1;
+    } else
+#endif
+
+#if defined(__x86_64__) || defined(CONFIG_X86_PAE)
+    if(level == L2_FRAME)
+    {
+#if defined(__x86_64__)
+        if(l4_table_offset(virt_address) >= 
+           l4_table_offset(hyp_virt_start) &&
+           l4_table_offset(virt_address) <= 
+           l4_table_offset(hyp_virt_end))
+#endif
+            if(l3_table_offset(virt_address) >= 
+               l3_table_offset(hyp_virt_start) &&
+               l3_table_offset(virt_address) <= 
+               l3_table_offset(hyp_virt_end))
+                return 0;
+
+        return 1;
+    } else 
+#endif /* defined(__x86_64__) || defined(CONFIG_X86_PAE) */
+
+    /* Always need l1 frames */
+    if(level == L1_FRAME)
+        return 1;
+
+    printk("ERROR: Unknown frame level %d, hypervisor %llx,%llx\n", 
+        level, hyp_virt_start, hyp_virt_end);
+    return -1;
 }
 
 void build_pagetable(unsigned long *start_pfn, unsigned long *max_pfn)
@@ -460,11 +512,21 @@ void build_pagetable(unsigned long *star
     unsigned long offset;
     int count = 0;
 
-    pfn_to_map = (start_info.nr_pt_frames - UNMAPPED_PT_FRAMES) * 
L1_PAGETABLE_ENTRIES;
+    pfn_to_map = (start_info.nr_pt_frames - NOT_L1_FRAMES) * 
L1_PAGETABLE_ENTRIES;
+
+    if (*max_pfn >= virt_to_pfn(HYPERVISOR_VIRT_START))
+    {
+        printk("WARNING: Mini-OS trying to use Xen virtual space. "
+               "Truncating memory from %dMB to ",
+               ((unsigned long)pfn_to_virt(*max_pfn) - (unsigned 
long)&_text)>>20);
+        *max_pfn = virt_to_pfn(HYPERVISOR_VIRT_START - PAGE_SIZE);
+        printk("%dMB\n",
+               ((unsigned long)pfn_to_virt(*max_pfn) - (unsigned 
long)&_text)>>20);
+    }
 
     start_address = (unsigned long)pfn_to_virt(pfn_to_map);
     end_address = (unsigned long)pfn_to_virt(*max_pfn);
-    
+
     /* We worked out the virtual memory range to map, now mapping loop */
     printk("Mapping memory range 0x%lx - 0x%lx\n", start_address, end_address);
 
@@ -477,8 +539,9 @@ void build_pagetable(unsigned long *star
         offset = l4_table_offset(start_address);
         /* Need new L3 pt frame */
         if(!(start_address & L3_MASK)) 
-            new_pt_frame(&pt_pfn, mfn, offset, L3_FRAME);
-        
+            if(need_pt_frame(start_address, L3_FRAME)) 
+                new_pt_frame(&pt_pfn, mfn, offset, L3_FRAME);
+
         page = tab[offset];
         mfn = pte_to_mfn(page);
         tab = to_virt(mfn_to_pfn(mfn) << PAGE_SHIFT);
@@ -486,8 +549,9 @@ void build_pagetable(unsigned long *star
 #if defined(__x86_64__) || defined(CONFIG_X86_PAE)
         offset = l3_table_offset(start_address);
         /* Need new L2 pt frame */
-        if(!(start_address & L2_MASK)) 
-            new_pt_frame(&pt_pfn, mfn, offset, L2_FRAME);
+        if(!(start_address & L2_MASK))
+            if(need_pt_frame(start_address, L2_FRAME))
+                new_pt_frame(&pt_pfn, mfn, offset, L2_FRAME);
 
         page = tab[offset];
         mfn = pte_to_mfn(page);
@@ -495,16 +559,16 @@ void build_pagetable(unsigned long *star
 #endif
         offset = l2_table_offset(start_address);        
         /* Need new L1 pt frame */
-        if(!(start_address & L1_MASK)) 
-            new_pt_frame(&pt_pfn, mfn, offset, L1_FRAME);
-       
+        if(!(start_address & L1_MASK))
+            if(need_pt_frame(start_address, L1_FRAME)) 
+                new_pt_frame(&pt_pfn, mfn, offset, L1_FRAME);
+
         page = tab[offset];
         mfn = pte_to_mfn(page);
         offset = l1_table_offset(start_address);
 
         mmu_updates[count].ptr = ((pgentry_t)mfn << PAGE_SHIFT) + 
sizeof(pgentry_t) * offset;
-        mmu_updates[count].val = 
-            (pgentry_t)pfn_to_mfn(pfn_to_map++) << PAGE_SHIFT | L1_PROT;
+        mmu_updates[count].val = (pgentry_t)pfn_to_mfn(pfn_to_map++) << 
PAGE_SHIFT | L1_PROT;
         count++;
         if (count == L1_PAGETABLE_ENTRIES || pfn_to_map == *max_pfn)
         {
diff -r 2c0cd4075d1c -r b3b5f3ff2100 extras/mini-os/x86_32.S
--- a/extras/mini-os/x86_32.S   Wed May 31 07:41:33 2006 +0100
+++ b/extras/mini-os/x86_32.S   Wed May 31 07:43:06 2006 +0100
@@ -4,8 +4,8 @@
 .section __xen_guest
        .ascii  "GUEST_OS=Mini-OS"
        .ascii  ",XEN_VER=xen-3.0"
-       .ascii  ",VIRT_BASE=0xc0000000" /* &_text from minios_x86_32.lds */
-       .ascii  ",ELF_PADDR_OFFSET=0xc0000000"
+       .ascii  ",VIRT_BASE=0x0" /* &_text from minios_x86_32.lds */
+       .ascii  ",ELF_PADDR_OFFSET=0x0"
        .ascii  ",HYPERCALL_PAGE=0x2"
 #ifdef CONFIG_X86_PAE
        .ascii  ",PAE=yes"
diff -r 2c0cd4075d1c -r b3b5f3ff2100 extras/mini-os/x86_64.S
--- a/extras/mini-os/x86_64.S   Wed May 31 07:41:33 2006 +0100
+++ b/extras/mini-os/x86_64.S   Wed May 31 07:43:06 2006 +0100
@@ -4,8 +4,8 @@
 .section __xen_guest
        .ascii  "GUEST_OS=Mini-OS"
        .ascii  ",XEN_VER=xen-3.0"
-       .ascii  ",VIRT_BASE=0xffffffff80000000" /* &_text from 
minios_x86_64.lds */
-       .ascii  ",ELF_PADDR_OFFSET=0xffffffff80000000"
+       .ascii  ",VIRT_BASE=0x0" /* &_text from minios_x86_64.lds */
+       .ascii  ",ELF_PADDR_OFFSET=0x0"
        .ascii  ",HYPERCALL_PAGE=0x2"
        .ascii  ",LOADER=generic"
        .byte   0

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


 


Rackspace

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