ia64/xen-unstable

changeset 10224:b3b5f3ff2100

[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>
author kaf24@firebug.cl.cam.ac.uk
date Wed May 31 07:43:06 2006 +0100 (2006-05-31)
parents 2c0cd4075d1c
children fbcb603288bb
files extras/mini-os/include/mm.h extras/mini-os/minios-x86_32.lds extras/mini-os/minios-x86_64.lds extras/mini-os/mm.c extras/mini-os/x86_32.S extras/mini-os/x86_64.S
line diff
     1.1 --- a/extras/mini-os/include/mm.h	Wed May 31 07:41:33 2006 +0100
     1.2 +++ b/extras/mini-os/include/mm.h	Wed May 31 07:43:06 2006 +0100
     1.3 @@ -53,7 +53,7 @@
     1.4  #define PADDR_BITS              32
     1.5  #define PADDR_MASK              (~0UL)
     1.6  
     1.7 -#define UNMAPPED_PT_FRAMES        1
     1.8 +#define NOT_L1_FRAMES           1
     1.9  #define PRIpte "08lx"
    1.10  typedef unsigned long pgentry_t;
    1.11  
    1.12 @@ -71,7 +71,12 @@ typedef unsigned long pgentry_t;
    1.13  
    1.14  #define L2_MASK  ((1UL << L3_PAGETABLE_SHIFT) - 1)
    1.15  
    1.16 -#define UNMAPPED_PT_FRAMES        2
    1.17 +/*
    1.18 + * If starting from virtual address greater than 0xc0000000,
    1.19 + * this value will be 2 to account for final mid-level page
    1.20 + * directory which is always mapped in at this location.
    1.21 + */
    1.22 +#define NOT_L1_FRAMES           3
    1.23  #define PRIpte "016llx"
    1.24  typedef uint64_t pgentry_t;
    1.25  
    1.26 @@ -94,20 +99,10 @@ typedef uint64_t pgentry_t;
    1.27  #define PADDR_MASK              ((1UL << PADDR_BITS)-1)
    1.28  #define VADDR_MASK              ((1UL << VADDR_BITS)-1)
    1.29  
    1.30 -/* Get physical address of page mapped by pte (paddr_t). */
    1.31 -#define l1e_get_paddr(x)           \
    1.32 -    ((unsigned long)(((x) & (PADDR_MASK&PAGE_MASK))))
    1.33 -#define l2e_get_paddr(x)           \
    1.34 -    ((unsigned long)(((x) & (PADDR_MASK&PAGE_MASK))))
    1.35 -#define l3e_get_paddr(x)           \
    1.36 -    ((unsigned long)(((x) & (PADDR_MASK&PAGE_MASK))))
    1.37 -#define l4e_get_paddr(x)           \
    1.38 -    ((unsigned long)(((x) & (PADDR_MASK&PAGE_MASK))))
    1.39 -
    1.40  #define L2_MASK  ((1UL << L3_PAGETABLE_SHIFT) - 1)
    1.41  #define L3_MASK  ((1UL << L4_PAGETABLE_SHIFT) - 1)
    1.42  
    1.43 -#define UNMAPPED_PT_FRAMES        3
    1.44 +#define NOT_L1_FRAMES           3
    1.45  #define PRIpte "016lx"
    1.46  typedef unsigned long pgentry_t;
    1.47  
     2.1 --- a/extras/mini-os/minios-x86_32.lds	Wed May 31 07:41:33 2006 +0100
     2.2 +++ b/extras/mini-os/minios-x86_32.lds	Wed May 31 07:43:06 2006 +0100
     2.3 @@ -3,7 +3,7 @@ OUTPUT_ARCH(i386)
     2.4  ENTRY(_start)
     2.5  SECTIONS
     2.6  {
     2.7 -  . = 0xC0000000;
     2.8 +  . = 0x0;
     2.9    _text = .;			/* Text and read-only data */
    2.10    .text : {
    2.11  	*(.text)
     3.1 --- a/extras/mini-os/minios-x86_64.lds	Wed May 31 07:41:33 2006 +0100
     3.2 +++ b/extras/mini-os/minios-x86_64.lds	Wed May 31 07:43:06 2006 +0100
     3.3 @@ -3,7 +3,7 @@ OUTPUT_ARCH(i386:x86-64)
     3.4  ENTRY(_start)
     3.5  SECTIONS
     3.6  {
     3.7 -  . = 0xFFFFFFFF80000000;
     3.8 +  . = 0x0;
     3.9    _text = .;			/* Text and read-only data */
    3.10    .text : {
    3.11  	*(.text)
     4.1 --- a/extras/mini-os/mm.c	Wed May 31 07:41:33 2006 +0100
     4.2 +++ b/extras/mini-os/mm.c	Wed May 31 07:43:06 2006 +0100
     4.3 @@ -375,7 +375,7 @@ void new_pt_frame(unsigned long *pt_pfn,
     4.4      struct mmuext_op pin_request;
     4.5      
     4.6      DEBUG("Allocating new L%d pt frame for pt_pfn=%lx, "
     4.7 -           "prev_l_mfn=%lx, offset=%lx\n", 
     4.8 +           "prev_l_mfn=%lx, offset=%lx", 
     4.9             level, *pt_pfn, prev_l_mfn, offset);
    4.10  
    4.11      /* We need to clear the page, otherwise we might fail to map it
    4.12 @@ -442,7 +442,7 @@ void new_pt_frame(unsigned long *pt_pfn,
    4.13      mmu_updates[0].ptr = ((pgentry_t)prev_l_mfn << PAGE_SHIFT) + sizeof(pgentry_t) * offset;
    4.14      mmu_updates[0].val = (pgentry_t)pfn_to_mfn(*pt_pfn) << PAGE_SHIFT | prot_t;
    4.15      if(HYPERVISOR_mmu_update(mmu_updates, 1, NULL, DOMID_SELF) < 0) 
    4.16 -    {            
    4.17 +    {
    4.18         printk("ERROR: mmu_update failed\n");
    4.19         do_exit();
    4.20      }
    4.21 @@ -450,6 +450,58 @@ void new_pt_frame(unsigned long *pt_pfn,
    4.22      *pt_pfn += 1;
    4.23  }
    4.24  
    4.25 +/* Checks if a pagetable frame is needed (if weren't allocated by Xen) */
    4.26 +static int need_pt_frame(unsigned long virt_address, int level)
    4.27 +{
    4.28 +    unsigned long hyp_virt_start = HYPERVISOR_VIRT_START;
    4.29 +#if defined(__x86_64__)
    4.30 +    unsigned long hyp_virt_end = HYPERVISOR_VIRT_END;
    4.31 +#else
    4.32 +    unsigned long hyp_virt_end = 0xffffffff;
    4.33 +#endif
    4.34 +
    4.35 +    /* In general frames will _not_ be needed if they were already
    4.36 +       allocated to map the hypervisor into our VA space */
    4.37 +#if defined(__x86_64__)
    4.38 +    if(level == L3_FRAME)
    4.39 +    {
    4.40 +        if(l4_table_offset(virt_address) >= 
    4.41 +           l4_table_offset(hyp_virt_start) &&
    4.42 +           l4_table_offset(virt_address) <= 
    4.43 +           l4_table_offset(hyp_virt_end))
    4.44 +            return 0;
    4.45 +        return 1;
    4.46 +    } else
    4.47 +#endif
    4.48 +
    4.49 +#if defined(__x86_64__) || defined(CONFIG_X86_PAE)
    4.50 +    if(level == L2_FRAME)
    4.51 +    {
    4.52 +#if defined(__x86_64__)
    4.53 +        if(l4_table_offset(virt_address) >= 
    4.54 +           l4_table_offset(hyp_virt_start) &&
    4.55 +           l4_table_offset(virt_address) <= 
    4.56 +           l4_table_offset(hyp_virt_end))
    4.57 +#endif
    4.58 +            if(l3_table_offset(virt_address) >= 
    4.59 +               l3_table_offset(hyp_virt_start) &&
    4.60 +               l3_table_offset(virt_address) <= 
    4.61 +               l3_table_offset(hyp_virt_end))
    4.62 +                return 0;
    4.63 +
    4.64 +        return 1;
    4.65 +    } else 
    4.66 +#endif /* defined(__x86_64__) || defined(CONFIG_X86_PAE) */
    4.67 +
    4.68 +    /* Always need l1 frames */
    4.69 +    if(level == L1_FRAME)
    4.70 +        return 1;
    4.71 +
    4.72 +    printk("ERROR: Unknown frame level %d, hypervisor %llx,%llx\n", 
    4.73 +        level, hyp_virt_start, hyp_virt_end);
    4.74 +    return -1;
    4.75 +}
    4.76 +
    4.77  void build_pagetable(unsigned long *start_pfn, unsigned long *max_pfn)
    4.78  {
    4.79      unsigned long start_address, end_address;
    4.80 @@ -460,11 +512,21 @@ void build_pagetable(unsigned long *star
    4.81      unsigned long offset;
    4.82      int count = 0;
    4.83  
    4.84 -    pfn_to_map = (start_info.nr_pt_frames - UNMAPPED_PT_FRAMES) * L1_PAGETABLE_ENTRIES;
    4.85 +    pfn_to_map = (start_info.nr_pt_frames - NOT_L1_FRAMES) * L1_PAGETABLE_ENTRIES;
    4.86 +
    4.87 +    if (*max_pfn >= virt_to_pfn(HYPERVISOR_VIRT_START))
    4.88 +    {
    4.89 +        printk("WARNING: Mini-OS trying to use Xen virtual space. "
    4.90 +               "Truncating memory from %dMB to ",
    4.91 +               ((unsigned long)pfn_to_virt(*max_pfn) - (unsigned long)&_text)>>20);
    4.92 +        *max_pfn = virt_to_pfn(HYPERVISOR_VIRT_START - PAGE_SIZE);
    4.93 +        printk("%dMB\n",
    4.94 +               ((unsigned long)pfn_to_virt(*max_pfn) - (unsigned long)&_text)>>20);
    4.95 +    }
    4.96  
    4.97      start_address = (unsigned long)pfn_to_virt(pfn_to_map);
    4.98      end_address = (unsigned long)pfn_to_virt(*max_pfn);
    4.99 -    
   4.100 +
   4.101      /* We worked out the virtual memory range to map, now mapping loop */
   4.102      printk("Mapping memory range 0x%lx - 0x%lx\n", start_address, end_address);
   4.103  
   4.104 @@ -477,8 +539,9 @@ void build_pagetable(unsigned long *star
   4.105          offset = l4_table_offset(start_address);
   4.106          /* Need new L3 pt frame */
   4.107          if(!(start_address & L3_MASK)) 
   4.108 -            new_pt_frame(&pt_pfn, mfn, offset, L3_FRAME);
   4.109 -        
   4.110 +            if(need_pt_frame(start_address, L3_FRAME)) 
   4.111 +                new_pt_frame(&pt_pfn, mfn, offset, L3_FRAME);
   4.112 +
   4.113          page = tab[offset];
   4.114          mfn = pte_to_mfn(page);
   4.115          tab = to_virt(mfn_to_pfn(mfn) << PAGE_SHIFT);
   4.116 @@ -486,8 +549,9 @@ void build_pagetable(unsigned long *star
   4.117  #if defined(__x86_64__) || defined(CONFIG_X86_PAE)
   4.118          offset = l3_table_offset(start_address);
   4.119          /* Need new L2 pt frame */
   4.120 -        if(!(start_address & L2_MASK)) 
   4.121 -            new_pt_frame(&pt_pfn, mfn, offset, L2_FRAME);
   4.122 +        if(!(start_address & L2_MASK))
   4.123 +            if(need_pt_frame(start_address, L2_FRAME))
   4.124 +                new_pt_frame(&pt_pfn, mfn, offset, L2_FRAME);
   4.125  
   4.126          page = tab[offset];
   4.127          mfn = pte_to_mfn(page);
   4.128 @@ -495,16 +559,16 @@ void build_pagetable(unsigned long *star
   4.129  #endif
   4.130          offset = l2_table_offset(start_address);        
   4.131          /* Need new L1 pt frame */
   4.132 -        if(!(start_address & L1_MASK)) 
   4.133 -            new_pt_frame(&pt_pfn, mfn, offset, L1_FRAME);
   4.134 -       
   4.135 +        if(!(start_address & L1_MASK))
   4.136 +            if(need_pt_frame(start_address, L1_FRAME)) 
   4.137 +                new_pt_frame(&pt_pfn, mfn, offset, L1_FRAME);
   4.138 +
   4.139          page = tab[offset];
   4.140          mfn = pte_to_mfn(page);
   4.141          offset = l1_table_offset(start_address);
   4.142  
   4.143          mmu_updates[count].ptr = ((pgentry_t)mfn << PAGE_SHIFT) + sizeof(pgentry_t) * offset;
   4.144 -        mmu_updates[count].val = 
   4.145 -            (pgentry_t)pfn_to_mfn(pfn_to_map++) << PAGE_SHIFT | L1_PROT;
   4.146 +        mmu_updates[count].val = (pgentry_t)pfn_to_mfn(pfn_to_map++) << PAGE_SHIFT | L1_PROT;
   4.147          count++;
   4.148          if (count == L1_PAGETABLE_ENTRIES || pfn_to_map == *max_pfn)
   4.149          {
     5.1 --- a/extras/mini-os/x86_32.S	Wed May 31 07:41:33 2006 +0100
     5.2 +++ b/extras/mini-os/x86_32.S	Wed May 31 07:43:06 2006 +0100
     5.3 @@ -4,8 +4,8 @@
     5.4  .section __xen_guest
     5.5  	.ascii	"GUEST_OS=Mini-OS"
     5.6  	.ascii	",XEN_VER=xen-3.0"
     5.7 -	.ascii	",VIRT_BASE=0xc0000000" /* &_text from minios_x86_32.lds */
     5.8 -	.ascii	",ELF_PADDR_OFFSET=0xc0000000"
     5.9 +	.ascii	",VIRT_BASE=0x0" /* &_text from minios_x86_32.lds */
    5.10 +	.ascii	",ELF_PADDR_OFFSET=0x0"
    5.11  	.ascii	",HYPERCALL_PAGE=0x2"
    5.12  #ifdef CONFIG_X86_PAE
    5.13  	.ascii	",PAE=yes"
     6.1 --- a/extras/mini-os/x86_64.S	Wed May 31 07:41:33 2006 +0100
     6.2 +++ b/extras/mini-os/x86_64.S	Wed May 31 07:43:06 2006 +0100
     6.3 @@ -4,8 +4,8 @@
     6.4  .section __xen_guest
     6.5  	.ascii	"GUEST_OS=Mini-OS"
     6.6  	.ascii	",XEN_VER=xen-3.0"
     6.7 -	.ascii	",VIRT_BASE=0xffffffff80000000" /* &_text from minios_x86_64.lds */
     6.8 -	.ascii	",ELF_PADDR_OFFSET=0xffffffff80000000"
     6.9 +	.ascii	",VIRT_BASE=0x0" /* &_text from minios_x86_64.lds */
    6.10 +	.ascii	",ELF_PADDR_OFFSET=0x0"
    6.11  	.ascii	",HYPERCALL_PAGE=0x2"
    6.12  	.ascii	",LOADER=generic"
    6.13  	.byte	0