direct-io.hg

changeset 2449:875c25208085

bitkeeper revision 1.1159.1.130 (413dab6fQ1jHzBNKBK5rX_nzCQLANA)

Make writable pagetables a domain creation option.
author cl349@freefall.cl.cam.ac.uk
date Tue Sep 07 12:37:03 2004 +0000 (2004-09-07)
parents 46859bdc5411
children 7809f000f2f0 426891ca6a6f
files tools/libxc/xc.h tools/libxc/xc_domain.c tools/libxc/xc_linux_build.c xen/arch/x86/domain.c xen/common/dom0_ops.c xen/include/hypervisor-ifs/dom0_ops.h
line diff
     1.1 --- a/tools/libxc/xc.h	Tue Sep 07 09:59:39 2004 +0000
     1.2 +++ b/tools/libxc/xc.h	Tue Sep 07 12:37:03 2004 +0000
     1.3 @@ -230,6 +230,11 @@ int xc_domain_setmaxmem(int xc_handle,
     1.4                              u32 domid, 
     1.5                              unsigned int max_memkb);
     1.6  
     1.7 +int xc_domain_setvmassist(int xc_handle,
     1.8 +                          u32 domid, 
     1.9 +                          unsigned int cmd,
    1.10 +                          unsigned int type);
    1.11 +
    1.12  
    1.13  void *xc_map_foreign_range(int xc_handle, u32 dom,
    1.14                              int size, int prot,
     2.1 --- a/tools/libxc/xc_domain.c	Tue Sep 07 09:59:39 2004 +0000
     2.2 +++ b/tools/libxc/xc_domain.c	Tue Sep 07 12:37:03 2004 +0000
     2.3 @@ -256,3 +256,15 @@ int xc_domain_setmaxmem(int xc_handle,
     2.4      return do_dom0_op(xc_handle, &op);
     2.5  }
     2.6  
     2.7 +int xc_domain_setvmassist(int xc_handle,
     2.8 +                          u32 domid, 
     2.9 +                          unsigned int cmd,
    2.10 +                          unsigned int type)
    2.11 +{
    2.12 +    dom0_op_t op;
    2.13 +    op.cmd = DOM0_SETDOMAINVMASSIST;
    2.14 +    op.u.setdomainvmassist.domain = (domid_t)domid;
    2.15 +    op.u.setdomainvmassist.cmd = cmd;
    2.16 +    op.u.setdomainvmassist.type = type;
    2.17 +    return do_dom0_op(xc_handle, &op);
    2.18 +}
     3.1 --- a/tools/libxc/xc_linux_build.c	Tue Sep 07 09:59:39 2004 +0000
     3.2 +++ b/tools/libxc/xc_linux_build.c	Tue Sep 07 12:37:03 2004 +0000
     3.3 @@ -14,12 +14,19 @@
     3.4  #define round_pgup(_p)    (((_p)+(PAGE_SIZE-1))&PAGE_MASK)
     3.5  #define round_pgdown(_p)  ((_p)&PAGE_MASK)
     3.6  
     3.7 +struct domain_setup_info
     3.8 +{
     3.9 +    unsigned long v_start;
    3.10 +    unsigned long v_kernstart;
    3.11 +    unsigned long v_kernend;
    3.12 +    unsigned long v_kernentry;
    3.13 +
    3.14 +    unsigned int use_writable_pagetables;
    3.15 +};
    3.16 +
    3.17  static int parseelfimage(char *elfbase, 
    3.18                           unsigned long elfsize,
    3.19 -                         unsigned long *pvirtstart,
    3.20 -                         unsigned long *pkernstart,
    3.21 -                         unsigned long *pkernend,
    3.22 -                         unsigned long *pkernentry);
    3.23 +                         struct domain_setup_info *dsi);
    3.24  static int loadelfimage(char *elfbase, void *pmh, unsigned long *parray,
    3.25                          unsigned long vstart);
    3.26  
    3.27 @@ -77,7 +84,7 @@ static int setup_guestos(int xc_handle,
    3.28                           const char *cmdline,
    3.29                           unsigned long shared_info_frame,
    3.30                           unsigned int control_evtchn,
    3.31 -			 unsigned long flags)
    3.32 +                         unsigned long flags)
    3.33  {
    3.34      l1_pgentry_t *vl1tab=NULL, *vl1e=NULL;
    3.35      l2_pgentry_t *vl2tab=NULL, *vl2e=NULL;
    3.36 @@ -95,10 +102,7 @@ static int setup_guestos(int xc_handle,
    3.37      unsigned long ppt_alloc;
    3.38      unsigned long *physmap, *physmap_e, physmap_pfn;
    3.39  
    3.40 -    unsigned long v_start;
    3.41 -    unsigned long vkern_start;
    3.42 -    unsigned long vkern_entry;
    3.43 -    unsigned long vkern_end;
    3.44 +    struct domain_setup_info dsi;
    3.45      unsigned long vinitrd_start;
    3.46      unsigned long vinitrd_end;
    3.47      unsigned long vphysmap_start;
    3.48 @@ -111,12 +115,17 @@ static int setup_guestos(int xc_handle,
    3.49      unsigned long vpt_end;
    3.50      unsigned long v_end;
    3.51  
    3.52 -    rc = parseelfimage(image, image_size, &v_start,
    3.53 -                       &vkern_start, &vkern_end, &vkern_entry);
    3.54 +    memset(&dsi, 0, sizeof(struct domain_setup_info));
    3.55 +
    3.56 +    rc = parseelfimage(image, image_size, &dsi);
    3.57      if ( rc != 0 )
    3.58          goto error_out;
    3.59 -    
    3.60 -    if ( (v_start & (PAGE_SIZE-1)) != 0 )
    3.61 +
    3.62 +    if (dsi.use_writable_pagetables)
    3.63 +        xc_domain_setvmassist(xc_handle, dom, VMASST_CMD_enable,
    3.64 +                              VMASST_TYPE_writable_pagetables);
    3.65 +
    3.66 +    if ( (dsi.v_start & (PAGE_SIZE-1)) != 0 )
    3.67      {
    3.68          PERROR("Guest OS must load to a page boundary.\n");
    3.69          goto error_out;
    3.70 @@ -131,7 +140,7 @@ static int setup_guestos(int xc_handle,
    3.71       */
    3.72      for ( nr_pt_pages = 2; ; nr_pt_pages++ )
    3.73      {
    3.74 -        vinitrd_start    = round_pgup(vkern_end);
    3.75 +        vinitrd_start    = round_pgup(dsi.v_kernend);
    3.76          vinitrd_end      = vinitrd_start + initrd_len;
    3.77          vphysmap_start   = round_pgup(vinitrd_end);
    3.78          vphysmap_end     = vphysmap_start + (nr_pages * sizeof(unsigned long));
    3.79 @@ -144,7 +153,7 @@ static int setup_guestos(int xc_handle,
    3.80          v_end            = (vstack_end + (1<<22)-1) & ~((1<<22)-1);
    3.81          if ( (v_end - vstack_end) < (512 << 10) )
    3.82              v_end += 1 << 22; /* Add extra 4MB to get >= 512kB padding. */
    3.83 -        if ( (((v_end - v_start + ((1<<L2_PAGETABLE_SHIFT)-1)) >> 
    3.84 +        if ( (((v_end - dsi.v_start + ((1<<L2_PAGETABLE_SHIFT)-1)) >> 
    3.85                 L2_PAGETABLE_SHIFT) + 1) <= nr_pt_pages )
    3.86              break;
    3.87      }
    3.88 @@ -157,20 +166,20 @@ static int setup_guestos(int xc_handle,
    3.89             " Start info:    %08lx->%08lx\n"
    3.90             " Boot stack:    %08lx->%08lx\n"
    3.91             " TOTAL:         %08lx->%08lx\n",
    3.92 -           vkern_start, vkern_end, 
    3.93 +           dsi.v_kernstart, dsi.v_kernend, 
    3.94             vinitrd_start, vinitrd_end,
    3.95             vphysmap_start, vphysmap_end,
    3.96             vpt_start, vpt_end,
    3.97             vstartinfo_start, vstartinfo_end,
    3.98             vstack_start, vstack_end,
    3.99 -           v_start, v_end);
   3.100 -    printf(" ENTRY ADDRESS: %08lx\n", vkern_entry);
   3.101 +           dsi.v_start, v_end);
   3.102 +    printf(" ENTRY ADDRESS: %08lx\n", dsi.v_kernentry);
   3.103  
   3.104 -    if ( (v_end - v_start) > (nr_pages * PAGE_SIZE) )
   3.105 +    if ( (v_end - dsi.v_start) > (nr_pages * PAGE_SIZE) )
   3.106      {
   3.107          printf("Initial guest OS requires too much space\n"
   3.108                 "(%luMB is greater than %luMB limit)\n",
   3.109 -               (v_end-v_start)>>20, (nr_pages<<PAGE_SHIFT)>>20);
   3.110 +               (v_end-dsi.v_start)>>20, (nr_pages<<PAGE_SHIFT)>>20);
   3.111          goto error_out;
   3.112      }
   3.113  
   3.114 @@ -189,13 +198,13 @@ static int setup_guestos(int xc_handle,
   3.115          goto error_out;
   3.116      }
   3.117  
   3.118 -    loadelfimage(image, pm_handle, page_array, v_start);
   3.119 +    loadelfimage(image, pm_handle, page_array, dsi.v_start);
   3.120  
   3.121      /* Load the initial ramdisk image. */
   3.122      if ( initrd_len != 0 )
   3.123      {
   3.124 -        for ( i = (vinitrd_start - v_start); 
   3.125 -              i < (vinitrd_end - v_start); i += PAGE_SIZE )
   3.126 +        for ( i = (vinitrd_start - dsi.v_start); 
   3.127 +              i < (vinitrd_end - dsi.v_start); i += PAGE_SIZE )
   3.128          {
   3.129              char page[PAGE_SIZE];
   3.130              if ( gzread(initrd_gfd, page, PAGE_SIZE) == -1 )
   3.131 @@ -212,7 +221,7 @@ static int setup_guestos(int xc_handle,
   3.132          goto error_out;
   3.133  
   3.134      /* First allocate page for page dir. */
   3.135 -    ppt_alloc = (vpt_start - v_start) >> PAGE_SHIFT;
   3.136 +    ppt_alloc = (vpt_start - dsi.v_start) >> PAGE_SHIFT;
   3.137      l2tab = page_array[ppt_alloc++] << PAGE_SHIFT;
   3.138      ctxt->pt_base = l2tab;
   3.139  
   3.140 @@ -220,8 +229,8 @@ static int setup_guestos(int xc_handle,
   3.141      if ( (vl2tab = map_pfn_writeable(pm_handle, l2tab >> PAGE_SHIFT)) == NULL )
   3.142          goto error_out;
   3.143      memset(vl2tab, 0, PAGE_SIZE);
   3.144 -    vl2e = &vl2tab[l2_table_offset(v_start)];
   3.145 -    for ( count = 0; count < ((v_end-v_start)>>PAGE_SHIFT); count++ )
   3.146 +    vl2e = &vl2tab[l2_table_offset(dsi.v_start)];
   3.147 +    for ( count = 0; count < ((v_end-dsi.v_start)>>PAGE_SHIFT); count++ )
   3.148      {    
   3.149          if ( ((unsigned long)vl1e & (PAGE_SIZE-1)) == 0 )
   3.150          {
   3.151 @@ -232,13 +241,13 @@ static int setup_guestos(int xc_handle,
   3.152                                               l1tab >> PAGE_SHIFT)) == NULL )
   3.153                  goto error_out;
   3.154              memset(vl1tab, 0, PAGE_SIZE);
   3.155 -            vl1e = &vl1tab[l1_table_offset(v_start + (count<<PAGE_SHIFT))];
   3.156 +            vl1e = &vl1tab[l1_table_offset(dsi.v_start + (count<<PAGE_SHIFT))];
   3.157              *vl2e++ = l1tab | L2_PROT;
   3.158          }
   3.159  
   3.160          *vl1e = (page_array[count] << PAGE_SHIFT) | L1_PROT;
   3.161 -        if ( (count >= ((vpt_start-v_start)>>PAGE_SHIFT)) && 
   3.162 -             (count <  ((vpt_end  -v_start)>>PAGE_SHIFT)) )
   3.163 +        if ( (count >= ((vpt_start-dsi.v_start)>>PAGE_SHIFT)) && 
   3.164 +             (count <  ((vpt_end  -dsi.v_start)>>PAGE_SHIFT)) )
   3.165              *vl1e &= ~_PAGE_RW;
   3.166          vl1e++;
   3.167      }
   3.168 @@ -246,7 +255,7 @@ static int setup_guestos(int xc_handle,
   3.169      unmap_pfn(pm_handle, vl2tab);
   3.170  
   3.171      /* Write the phys->machine and machine->phys table entries. */
   3.172 -    physmap_pfn = (vphysmap_start - v_start) >> PAGE_SHIFT;
   3.173 +    physmap_pfn = (vphysmap_start - dsi.v_start) >> PAGE_SHIFT;
   3.174      physmap = physmap_e = 
   3.175          map_pfn_writeable(pm_handle, page_array[physmap_pfn++]);
   3.176      for ( count = 0; count < nr_pages; count++ )
   3.177 @@ -274,7 +283,7 @@ static int setup_guestos(int xc_handle,
   3.178          goto error_out;
   3.179  
   3.180      start_info = map_pfn_writeable(
   3.181 -        pm_handle, page_array[(vstartinfo_start-v_start)>>PAGE_SHIFT]);
   3.182 +        pm_handle, page_array[(vstartinfo_start-dsi.v_start)>>PAGE_SHIFT]);
   3.183      memset(start_info, 0, sizeof(*start_info));
   3.184      start_info->nr_pages     = nr_pages;
   3.185      start_info->shared_info  = shared_info_frame << PAGE_SHIFT;
   3.186 @@ -309,7 +318,7 @@ static int setup_guestos(int xc_handle,
   3.187      free(page_array);
   3.188  
   3.189      *pvsi = vstartinfo_start;
   3.190 -    *pvke = vkern_entry;
   3.191 +    *pvke = dsi.v_kernentry;
   3.192  
   3.193      return 0;
   3.194  
   3.195 @@ -551,10 +560,7 @@ static inline int is_loadable_phdr(Elf_P
   3.196  
   3.197  static int parseelfimage(char *elfbase, 
   3.198                           unsigned long elfsize,
   3.199 -                         unsigned long *pvirtstart,
   3.200 -                         unsigned long *pkernstart,
   3.201 -                         unsigned long *pkernend,
   3.202 -                         unsigned long *pkernentry)
   3.203 +                         struct domain_setup_info *dsi)
   3.204  {
   3.205      Elf_Ehdr *ehdr = (Elf_Ehdr *)elfbase;
   3.206      Elf_Phdr *phdr;
   3.207 @@ -643,13 +649,16 @@ static int parseelfimage(char *elfbase,
   3.208          return -EINVAL;
   3.209      }
   3.210  
   3.211 -    *pvirtstart = kernstart;
   3.212 +    dsi->v_start = kernstart;
   3.213      if ( (p = strstr(guestinfo, "VIRT_BASE=")) != NULL )
   3.214 -        *pvirtstart = strtoul(p+10, &p, 0);
   3.215 +        dsi->v_start = strtoul(p+10, &p, 0);
   3.216  
   3.217 -    *pkernstart = kernstart;
   3.218 -    *pkernend   = kernend;
   3.219 -    *pkernentry = ehdr->e_entry;
   3.220 +    if ( (p = strstr(guestinfo, "PT_MODE_WRITABLE")) != NULL )
   3.221 +        dsi->use_writable_pagetables = 1;
   3.222 +
   3.223 +    dsi->v_kernstart = kernstart;
   3.224 +    dsi->v_kernend   = kernend;
   3.225 +    dsi->v_kernentry = ehdr->e_entry;
   3.226  
   3.227      return 0;
   3.228  }
     4.1 --- a/xen/arch/x86/domain.c	Tue Sep 07 09:59:39 2004 +0000
     4.2 +++ b/xen/arch/x86/domain.c	Tue Sep 07 12:37:03 2004 +0000
     4.3 @@ -601,6 +601,10 @@ int construct_dom0(struct domain *p,
     4.4      if ( rc != 0 )
     4.5          return rc;
     4.6  
     4.7 +    /* Set up domain options */
     4.8 +    if ( dsi.use_writable_pagetables )
     4.9 +        vm_assist(p, VMASST_CMD_enable, VMASST_TYPE_writable_pagetables);
    4.10 +
    4.11      if ( (dsi.v_start & (PAGE_SIZE-1)) != 0 )
    4.12      {
    4.13          printk("Initial guest OS must load to a page boundary.\n");
    4.14 @@ -769,10 +773,6 @@ int construct_dom0(struct domain *p,
    4.15              l1start = l1tab = (l1_pgentry_t *)l2_pgentry_to_phys(*l2tab);
    4.16      }
    4.17  
    4.18 -    /* Set up domain options */
    4.19 -    if (dsi.use_writable_pagetables)
    4.20 -        vm_assist(p, VMASST_CMD_enable, VMASST_TYPE_writable_pagetables);
    4.21 -
    4.22      /* Set up shared-info area. */
    4.23      update_dom_time(p->shared_info);
    4.24      p->shared_info->domain_time = 0;
     5.1 --- a/xen/common/dom0_ops.c	Tue Sep 07 09:59:39 2004 +0000
     5.2 +++ b/xen/common/dom0_ops.c	Tue Sep 07 12:37:03 2004 +0000
     5.3 @@ -654,6 +654,21 @@ long do_dom0_op(dom0_op_t *u_dom0_op)
     5.4      }
     5.5      break;
     5.6  
     5.7 +    case DOM0_SETDOMAINVMASSIST:
     5.8 +    {
     5.9 +        struct domain *d; 
    5.10 +        ret = -ESRCH;
    5.11 +        d = find_domain_by_id( op->u.setdomainmaxmem.domain );
    5.12 +        if ( d != NULL )
    5.13 +        {
    5.14 +	    vm_assist(d, op->u.setdomainvmassist.cmd,
    5.15 +                      op->u.setdomainvmassist.type);
    5.16 +            put_domain(d);
    5.17 +            ret = 0;
    5.18 +        }
    5.19 +    }
    5.20 +    break;
    5.21 +
    5.22      default:
    5.23          ret = arch_do_dom0_op(op,u_dom0_op);
    5.24  
     6.1 --- a/xen/include/hypervisor-ifs/dom0_ops.h	Tue Sep 07 09:59:39 2004 +0000
     6.2 +++ b/xen/include/hypervisor-ifs/dom0_ops.h	Tue Sep 07 12:37:03 2004 +0000
     6.3 @@ -341,6 +341,15 @@ typedef struct {
     6.4      MEMORY_PADDING;
     6.5  } PACKED dom0_getpageframeinfo2_t; /* 24 bytes */
     6.6  
     6.7 +#define DOM0_SETDOMAINVMASSIST   30
     6.8 +typedef struct {
     6.9 +    /* IN variables. */
    6.10 +    domid_t      domain;              /*  0 */
    6.11 +    u16          __pad0;
    6.12 +    u32          cmd;                 /*  4: vm_assist cmd */
    6.13 +    u32          type;                /*  8: vm_assist cmd */
    6.14 +} PACKED dom0_setdomainvmassist_t; /* 12 bytes */
    6.15 +
    6.16  typedef struct {
    6.17      u32 cmd;                          /* 0 */
    6.18      u32 interface_version;            /* 4 */ /* DOM0_INTERFACE_VERSION */
    6.19 @@ -371,6 +380,7 @@ typedef struct {
    6.20  	dom0_setdomaininitialmem_t setdomaininitialmem;
    6.21  	dom0_setdomainmaxmem_t   setdomainmaxmem;
    6.22  	dom0_getpageframeinfo2_t getpageframeinfo2;
    6.23 +	dom0_setdomainvmassist_t setdomainvmassist;
    6.24      } PACKED u;
    6.25  } PACKED dom0_op_t; /* 80 bytes */
    6.26