ia64/xen-unstable

changeset 2448:46859bdc5411

bitkeeper revision 1.1159.1.129 (413d868bPMWkW0lZg_MuAYIrmx7XDQ)

Make writable pagetables a domain creation option.
author cl349@freefall.cl.cam.ac.uk
date Tue Sep 07 09:59:39 2004 +0000 (2004-09-07)
parents 924a0fb0c200
children 875c25208085
files linux-2.6.8.1-xen-sparse/arch/xen/i386/kernel/head.S linux-2.6.8.1-xen-sparse/arch/xen/i386/kernel/setup.c xen/arch/x86/domain.c xen/common/domain.c xen/common/elf.c xen/common/kernel.c xen/include/asm-x86/mm.h xen/include/xen/elf.h xen/include/xen/lib.h xen/include/xen/sched.h
line diff
     1.1 --- a/linux-2.6.8.1-xen-sparse/arch/xen/i386/kernel/head.S	Mon Sep 06 19:21:55 2004 +0000
     1.2 +++ b/linux-2.6.8.1-xen-sparse/arch/xen/i386/kernel/head.S	Tue Sep 07 09:59:39 2004 +0000
     1.3 @@ -1,9 +1,15 @@
     1.4 +
     1.5 +#include <linux/config.h>
     1.6  
     1.7  .section __xen_guest
     1.8 -	.asciz "GUEST_OS=linux,GUEST_VER=2.6,XEN_VER=2.0"
     1.9 +	.ascii	"GUEST_OS=linux,GUEST_VER=2.6,XEN_VER=2.0"
    1.10 +	.ascii	",LOADER=generic"
    1.11 +#ifdef CONFIG_XEN_WRITABLE_PAGETABLES
    1.12 +	.ascii	",PT_MODE_WRITABLE"
    1.13 +#endif
    1.14 +	.byte	0
    1.15  
    1.16  .text
    1.17 -#include <linux/config.h>
    1.18  #include <linux/threads.h>
    1.19  #include <linux/linkage.h>
    1.20  #include <asm/segment.h>
     2.1 --- a/linux-2.6.8.1-xen-sparse/arch/xen/i386/kernel/setup.c	Mon Sep 06 19:21:55 2004 +0000
     2.2 +++ b/linux-2.6.8.1-xen-sparse/arch/xen/i386/kernel/setup.c	Tue Sep 07 09:59:39 2004 +0000
     2.3 @@ -1295,10 +1295,6 @@ void __init setup_arch(char **cmdline_p)
     2.4  
     2.5  	HYPERVISOR_vm_assist(VMASST_CMD_enable,
     2.6  			     VMASST_TYPE_4gb_segments);
     2.7 -#ifdef CONFIG_XEN_WRITABLE_PAGETABLES
     2.8 -	HYPERVISOR_vm_assist(VMASST_CMD_enable,
     2.9 -			     VMASST_TYPE_writable_pagetables);
    2.10 -#endif
    2.11  
    2.12  	pm_idle = xen_cpu_idle;
    2.13  
     3.1 --- a/xen/arch/x86/domain.c	Mon Sep 06 19:21:55 2004 +0000
     3.2 +++ b/xen/arch/x86/domain.c	Tue Sep 07 09:59:39 2004 +0000
     3.3 @@ -557,10 +557,7 @@ int construct_dom0(struct domain *p,
     3.4       * *_start address are page-aligned, except v_start (and v_end) which are 
     3.5       * superpage-aligned.
     3.6       */
     3.7 -    unsigned long v_start;
     3.8 -    unsigned long vkern_start;
     3.9 -    unsigned long vkern_entry;
    3.10 -    unsigned long vkern_end;
    3.11 +    struct domain_setup_info dsi;
    3.12      unsigned long vinitrd_start;
    3.13      unsigned long vinitrd_end;
    3.14      unsigned long vphysmap_start;
    3.15 @@ -584,6 +581,8 @@ int construct_dom0(struct domain *p,
    3.16      if ( test_bit(DF_CONSTRUCTED, &p->flags) ) 
    3.17          BUG();
    3.18  
    3.19 +    memset(&dsi, 0, sizeof(struct domain_setup_info));
    3.20 +
    3.21      printk("*** LOADING DOMAIN 0 ***\n");
    3.22  
    3.23      /*
    3.24 @@ -598,12 +597,11 @@ int construct_dom0(struct domain *p,
    3.25       * We'll have to revisit this if we ever support PAE (64GB).
    3.26       */
    3.27  
    3.28 -    rc = parseelfimage(image_start, image_len, &v_start,
    3.29 -                       &vkern_start, &vkern_end, &vkern_entry);
    3.30 +    rc = parseelfimage(image_start, image_len, &dsi);
    3.31      if ( rc != 0 )
    3.32          return rc;
    3.33  
    3.34 -    if ( (v_start & (PAGE_SIZE-1)) != 0 )
    3.35 +    if ( (dsi.v_start & (PAGE_SIZE-1)) != 0 )
    3.36      {
    3.37          printk("Initial guest OS must load to a page boundary.\n");
    3.38          return -EINVAL;
    3.39 @@ -618,7 +616,7 @@ int construct_dom0(struct domain *p,
    3.40       */
    3.41      for ( nr_pt_pages = 2; ; nr_pt_pages++ )
    3.42      {
    3.43 -        vinitrd_start    = round_pgup(vkern_end);
    3.44 +        vinitrd_start    = round_pgup(dsi.v_kernend);
    3.45          vinitrd_end      = vinitrd_start + initrd_len;
    3.46          vphysmap_start   = round_pgup(vinitrd_end);
    3.47          vphysmap_end     = vphysmap_start + (nr_pages * sizeof(unsigned long));
    3.48 @@ -631,7 +629,7 @@ int construct_dom0(struct domain *p,
    3.49          v_end            = (vstack_end + (1<<22)-1) & ~((1<<22)-1);
    3.50          if ( (v_end - vstack_end) < (512 << 10) )
    3.51              v_end += 1 << 22; /* Add extra 4MB to get >= 512kB padding. */
    3.52 -        if ( (((v_end - v_start + ((1<<L2_PAGETABLE_SHIFT)-1)) >> 
    3.53 +        if ( (((v_end - dsi.v_start + ((1<<L2_PAGETABLE_SHIFT)-1)) >> 
    3.54                 L2_PAGETABLE_SHIFT) + 1) <= nr_pt_pages )
    3.55              break;
    3.56      }
    3.57 @@ -651,20 +649,20 @@ int construct_dom0(struct domain *p,
    3.58             " Start info:    %08lx->%08lx\n"
    3.59             " Boot stack:    %08lx->%08lx\n"
    3.60             " TOTAL:         %08lx->%08lx\n",
    3.61 -           vkern_start, vkern_end, 
    3.62 +           dsi.v_kernstart, dsi.v_kernend, 
    3.63             vinitrd_start, vinitrd_end,
    3.64             vphysmap_start, vphysmap_end,
    3.65             vpt_start, vpt_end,
    3.66             vstartinfo_start, vstartinfo_end,
    3.67             vstack_start, vstack_end,
    3.68 -           v_start, v_end);
    3.69 -    printk(" ENTRY ADDRESS: %08lx\n", vkern_entry);
    3.70 +           dsi.v_start, v_end);
    3.71 +    printk(" ENTRY ADDRESS: %08lx\n", dsi.v_kernentry);
    3.72  
    3.73 -    if ( (v_end - v_start) > (nr_pages * PAGE_SIZE) )
    3.74 +    if ( (v_end - dsi.v_start) > (nr_pages * PAGE_SIZE) )
    3.75      {
    3.76          printk("Initial guest OS requires too much space\n"
    3.77                 "(%luMB is greater than %luMB limit)\n",
    3.78 -               (v_end-v_start)>>20, (nr_pages<<PAGE_SHIFT)>>20);
    3.79 +               (v_end-dsi.v_start)>>20, (nr_pages<<PAGE_SHIFT)>>20);
    3.80          return -ENOMEM;
    3.81      }
    3.82  
    3.83 @@ -672,7 +670,7 @@ int construct_dom0(struct domain *p,
    3.84       * Protect the lowest 1GB of memory. We use a temporary mapping there
    3.85       * from which we copy the kernel and ramdisk images.
    3.86       */
    3.87 -    if ( v_start < (1<<30) )
    3.88 +    if ( dsi.v_start < (1<<30) )
    3.89      {
    3.90          printk("Initial loading isn't allowed to lowest 1GB of memory.\n");
    3.91          return -EINVAL;
    3.92 @@ -691,7 +689,7 @@ int construct_dom0(struct domain *p,
    3.93          p->tot_pages++; p->max_pages++;
    3.94      }
    3.95  
    3.96 -    mpt_alloc = (vpt_start - v_start) + alloc_start;
    3.97 +    mpt_alloc = (vpt_start - dsi.v_start) + alloc_start;
    3.98  
    3.99      SET_GDT_ENTRIES(p, DEFAULT_GDT_ENTRIES);
   3.100      SET_GDT_ADDRESS(p, DEFAULT_GDT_ADDRESS);
   3.101 @@ -715,9 +713,9 @@ int construct_dom0(struct domain *p,
   3.102          mk_l2_pgentry(__pa(p->mm.perdomain_pt) | __PAGE_HYPERVISOR);
   3.103      p->mm.pagetable = mk_pagetable((unsigned long)l2start);
   3.104  
   3.105 -    l2tab += l2_table_offset(v_start);
   3.106 +    l2tab += l2_table_offset(dsi.v_start);
   3.107      mfn = alloc_start >> PAGE_SHIFT;
   3.108 -    for ( count = 0; count < ((v_end-v_start)>>PAGE_SHIFT); count++ )
   3.109 +    for ( count = 0; count < ((v_end-dsi.v_start)>>PAGE_SHIFT); count++ )
   3.110      {
   3.111          if ( !((unsigned long)l1tab & (PAGE_SIZE-1)) )
   3.112          {
   3.113 @@ -726,7 +724,7 @@ int construct_dom0(struct domain *p,
   3.114              *l2tab++ = mk_l2_pgentry((unsigned long)l1start | L2_PROT);
   3.115              clear_page(l1tab);
   3.116              if ( count == 0 )
   3.117 -                l1tab += l1_table_offset(v_start);
   3.118 +                l1tab += l1_table_offset(dsi.v_start);
   3.119          }
   3.120          *l1tab++ = mk_l1_pgentry((mfn << PAGE_SHIFT) | L1_PROT);
   3.121          
   3.122 @@ -762,7 +760,7 @@ int construct_dom0(struct domain *p,
   3.123              page->u.inuse.type_info &= ~PGT_type_mask;
   3.124              page->u.inuse.type_info |= PGT_l1_page_table;
   3.125  	    page->u.inuse.type_info |= 
   3.126 -		((v_start>>L2_PAGETABLE_SHIFT)+(count-1))<<PGT_va_shift;
   3.127 +		((dsi.v_start>>L2_PAGETABLE_SHIFT)+(count-1))<<PGT_va_shift;
   3.128  
   3.129              get_page(page, p); /* an extra ref because of readable mapping */
   3.130          }
   3.131 @@ -771,6 +769,10 @@ int construct_dom0(struct domain *p,
   3.132              l1start = l1tab = (l1_pgentry_t *)l2_pgentry_to_phys(*l2tab);
   3.133      }
   3.134  
   3.135 +    /* Set up domain options */
   3.136 +    if (dsi.use_writable_pagetables)
   3.137 +        vm_assist(p, VMASST_CMD_enable, VMASST_TYPE_writable_pagetables);
   3.138 +
   3.139      /* Set up shared-info area. */
   3.140      update_dom_time(p->shared_info);
   3.141      p->shared_info->domain_time = 0;
   3.142 @@ -804,7 +806,7 @@ int construct_dom0(struct domain *p,
   3.143      {
   3.144          mfn = pfn + (alloc_start>>PAGE_SHIFT);
   3.145  #ifndef NDEBUG
   3.146 -#define REVERSE_START ((v_end - v_start) >> PAGE_SHIFT)
   3.147 +#define REVERSE_START ((v_end - dsi.v_start) >> PAGE_SHIFT)
   3.148          if ( pfn > REVERSE_START )
   3.149              mfn = (alloc_end>>PAGE_SHIFT) - (pfn - REVERSE_START);
   3.150  #endif
   3.151 @@ -854,7 +856,7 @@ int construct_dom0(struct domain *p,
   3.152      shadow_mode_enable(&p->mm, SHM_test); 
   3.153  #endif
   3.154  
   3.155 -    new_thread(p, vkern_entry, vstack_end, vstartinfo_start);
   3.156 +    new_thread(p, dsi.v_kernentry, vstack_end, vstartinfo_start);
   3.157  
   3.158      return 0;
   3.159  }
     4.1 --- a/xen/common/domain.c	Mon Sep 06 19:21:55 2004 +0000
     4.2 +++ b/xen/common/domain.c	Tue Sep 07 09:59:39 2004 +0000
     4.3 @@ -308,3 +308,25 @@ int final_setup_guestos(struct domain *p
     4.4          xfree(c);
     4.5      return rc;
     4.6  }
     4.7 +
     4.8 +long vm_assist(struct domain *p, unsigned int cmd, unsigned int type)
     4.9 +{
    4.10 +    if ( type > MAX_VMASST_TYPE )
    4.11 +        return -EINVAL;
    4.12 +
    4.13 +    switch ( cmd )
    4.14 +    {
    4.15 +    case VMASST_CMD_enable:
    4.16 +        set_bit(type, &p->vm_assist);
    4.17 +        if (vm_assist_info[type].enable)
    4.18 +            (*vm_assist_info[type].enable)(p);
    4.19 +        return 0;
    4.20 +    case VMASST_CMD_disable:
    4.21 +        clear_bit(type, &p->vm_assist);
    4.22 +        if (vm_assist_info[type].disable)
    4.23 +            (*vm_assist_info[type].disable)(p);
    4.24 +        return 0;
    4.25 +    }
    4.26 +
    4.27 +    return -ENOSYS;
    4.28 +}
     5.1 --- a/xen/common/elf.c	Mon Sep 06 19:21:55 2004 +0000
     5.2 +++ b/xen/common/elf.c	Tue Sep 07 09:59:39 2004 +0000
     5.3 @@ -18,10 +18,7 @@ static inline int is_loadable_phdr(Elf_P
     5.4  
     5.5  int parseelfimage(char *elfbase, 
     5.6                    unsigned long elfsize,
     5.7 -                  unsigned long *pvirtstart,
     5.8 -                  unsigned long *pkernstart,
     5.9 -                  unsigned long *pkernend,
    5.10 -                  unsigned long *pkernentry)
    5.11 +                  struct domain_setup_info *dsi)
    5.12  {
    5.13      Elf_Ehdr *ehdr = (Elf_Ehdr *)elfbase;
    5.14      Elf_Phdr *phdr;
    5.15 @@ -109,13 +106,16 @@ int parseelfimage(char *elfbase,
    5.16          return -EINVAL;
    5.17      }
    5.18  
    5.19 -    *pvirtstart = kernstart;
    5.20 +    dsi->v_start = kernstart;
    5.21      if ( (p = strstr(guestinfo, "VIRT_BASE=")) != NULL )
    5.22 -        *pvirtstart = simple_strtoul(p+10, &p, 0);
    5.23 +        dsi->v_start = simple_strtoul(p+10, &p, 0);
    5.24  
    5.25 -    *pkernstart = kernstart;
    5.26 -    *pkernend   = kernend;
    5.27 -    *pkernentry = ehdr->e_entry;
    5.28 +    if ( (p = strstr(guestinfo, "PT_MODE_WRITABLE")) != NULL )
    5.29 +        dsi->use_writable_pagetables = 1;
    5.30 +
    5.31 +    dsi->v_kernstart = kernstart;
    5.32 +    dsi->v_kernend   = kernend;
    5.33 +    dsi->v_kernentry = ehdr->e_entry;
    5.34  
    5.35      return 0;
    5.36  }
     6.1 --- a/xen/common/kernel.c	Mon Sep 06 19:21:55 2004 +0000
     6.2 +++ b/xen/common/kernel.c	Tue Sep 07 09:59:39 2004 +0000
     6.3 @@ -365,24 +365,7 @@ long do_xen_version(int cmd)
     6.4  
     6.5  long do_vm_assist(unsigned int cmd, unsigned int type)
     6.6  {
     6.7 -    if ( type > MAX_VMASST_TYPE )
     6.8 -        return -EINVAL;
     6.9 -
    6.10 -    switch ( cmd )
    6.11 -    {
    6.12 -    case VMASST_CMD_enable:
    6.13 -        set_bit(type, &current->vm_assist);
    6.14 -        if (vm_assist_info[type].enable)
    6.15 -            (*vm_assist_info[type].enable)();
    6.16 -        return 0;
    6.17 -    case VMASST_CMD_disable:
    6.18 -        clear_bit(type, &current->vm_assist);
    6.19 -        if (vm_assist_info[type].disable)
    6.20 -            (*vm_assist_info[type].disable)();
    6.21 -        return 0;
    6.22 -    }
    6.23 -
    6.24 -    return -ENOSYS;
    6.25 +    return vm_assist(current, cmd, type);
    6.26  }
    6.27  
    6.28  long do_ni_hypercall(void)
     7.1 --- a/xen/include/asm-x86/mm.h	Mon Sep 06 19:21:55 2004 +0000
     7.2 +++ b/xen/include/asm-x86/mm.h	Tue Sep 07 09:59:39 2004 +0000
     7.3 @@ -363,8 +363,8 @@ int memguard_is_guarded(void *p);
     7.4  
     7.5  
     7.6  typedef struct {
     7.7 -    void	(*enable)(void);
     7.8 -    void	(*disable)(void);
     7.9 +    void	(*enable)(struct domain *);
    7.10 +    void	(*disable)(struct domain *);
    7.11  } vm_assist_info_t;
    7.12  extern vm_assist_info_t vm_assist_info[];
    7.13  
     8.1 --- a/xen/include/xen/elf.h	Mon Sep 06 19:21:55 2004 +0000
     8.2 +++ b/xen/include/xen/elf.h	Tue Sep 07 09:59:39 2004 +0000
     8.3 @@ -525,8 +525,6 @@ typedef struct {
     8.4  #endif
     8.5  
     8.6  extern int loadelfimage(char *);
     8.7 -extern int parseelfimage(
     8.8 -    char *, unsigned long, unsigned long *,
     8.9 -    unsigned long *, unsigned long *, unsigned long *);
    8.10 +extern int parseelfimage(char *, unsigned long, struct domain_setup_info *);
    8.11  
    8.12  #endif /* __XEN_ELF_H__ */
     9.1 --- a/xen/include/xen/lib.h	Mon Sep 06 19:21:55 2004 +0000
     9.2 +++ b/xen/include/xen/lib.h	Tue Sep 07 09:59:39 2004 +0000
     9.3 @@ -14,10 +14,13 @@
     9.4  #define reserve_bootmem(_p,_l) \
     9.5  printk("Memory Reservation 0x%lx, %lu bytes\n", (_p), (_l))
     9.6  
     9.7 +struct domain;
     9.8 +
     9.9  /* kernel.c */
    9.10  #define printk printf
    9.11  void printf(const char *format, ...);
    9.12  void panic(const char *format, ...);
    9.13 +long vm_assist(struct domain *, unsigned int, unsigned int);
    9.14  
    9.15  /* vsprintf.c */
    9.16  extern int sprintf(char * buf, const char * fmt, ...)
    10.1 --- a/xen/include/xen/sched.h	Mon Sep 06 19:21:55 2004 +0000
    10.2 +++ b/xen/include/xen/sched.h	Tue Sep 07 09:59:39 2004 +0000
    10.3 @@ -146,6 +146,16 @@ struct domain
    10.4      atomic_t pausecnt;
    10.5  };
    10.6  
    10.7 +struct domain_setup_info
    10.8 +{
    10.9 +    unsigned long v_start;
   10.10 +    unsigned long v_kernstart;
   10.11 +    unsigned long v_kernend;
   10.12 +    unsigned long v_kernentry;
   10.13 +
   10.14 +    unsigned int use_writable_pagetables;
   10.15 +};
   10.16 +
   10.17  #include <asm/uaccess.h> /* for KERNEL_DS */
   10.18  
   10.19  extern struct domain idle0_task;