Mailing List Archive

[MINIOS] Various address-space fixes.
# HG changeset patch
# User kaf24@firebug.cl.cam.ac.uk
# 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@cam.ac.uk>
Signed-off-by: Aravindh Puthiyaparambil
<aravindh.puthiyaparambil@unisys.com>
---
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@lists.xensource.com
http://lists.xensource.com/xen-changelog