ia64/xen-unstable

changeset 530:4ebe3235a8f3

bitkeeper revision 1.294 (3f0a9f16gdwvRs89xXMLxr3DvV1dgg)

Switch from using magic messages to map domain memory to using
a magic ioctl.

There's something very weird in this code: if userspace forgets to
unmap the memory, the next time it's called, it crashes. It looks
like the old code had the same bug, so I'm going to pretend it isn't
there for a little while.
author sos22@labyrinth.cl.cam.ac.uk
date Tue Jul 08 10:38:14 2003 +0000 (2003-07-08)
parents 25c290356870
children 49232d5003e6
files tools/internal/xi_build.c xen/include/hypervisor-ifs/dom0_ops.h xenolinux-2.4.21-sparse/arch/xeno/drivers/dom0/dom0_core.c
line diff
     1.1 --- a/tools/internal/xi_build.c	Mon Jul 07 15:36:18 2003 +0000
     1.2 +++ b/tools/internal/xi_build.c	Tue Jul 08 10:38:14 2003 +0000
     1.3 @@ -12,6 +12,7 @@
     1.4  #include <sys/types.h>
     1.5  #include <sys/stat.h>
     1.6  #include <stdlib.h>
     1.7 +#include <sys/ioctl.h>
     1.8  
     1.9  #include "hypervisor_defs.h"
    1.10  #include "dom0_ops.h"
    1.11 @@ -47,23 +48,23 @@ static void dbstatus(char * msg)
    1.12  /* clean up domain's memory allocations */
    1.13  static void dom_mem_cleanup(dom_mem_t * dom_mem)
    1.14  {
    1.15 -    char mem_path[MAX_PATH];
    1.16 -    int mem_fd;
    1.17 +    int fd;
    1.18 +    struct dom0_unmapdommem_args argbuf;
    1.19  
    1.20 -    /* open the domain's /proc mem interface */
    1.21 -    sprintf(mem_path, "%s%s%s%s%d%s%s", "/proc/", PROC_XENO_ROOT, "/", 
    1.22 -            PROC_DOM_PREFIX, dom_mem->domain, "/", PROC_DOM_MEM);
    1.23 -
    1.24 -    mem_fd = open(mem_path, O_WRONLY);
    1.25 -    if(mem_fd < 0){
    1.26 +    fd = open("/proc/xeno/dom0_cmd", O_WRONLY);
    1.27 +    if(fd < 0){
    1.28          perror(PERR_STRING);
    1.29      }
    1.30      
    1.31 -    if(write(mem_fd, (dom_mem_t *)dom_mem, sizeof(dom_mem_t)) < 0){
    1.32 -	dbstatus("Error unmapping domain's memory.\n");
    1.33 +    argbuf.vaddr = dom_mem->vaddr;
    1.34 +    argbuf.start_pfn = dom_mem->start_pfn;
    1.35 +    argbuf.tot_pages = dom_mem->tot_pages;
    1.36 +
    1.37 +    if (ioctl(fd, IOCTL_DOM0_UNMAPDOMMEM, &argbuf) < 0) {
    1.38 +        dbstatus("Error unmapping domain's memory.\n");
    1.39      }
    1.40  
    1.41 -    close(mem_fd);
    1.42 +    close(fd);
    1.43  }
    1.44  
    1.45  /* ask dom0 to export domains memory through /proc */
    1.46 @@ -121,21 +122,30 @@ static unsigned long get_vaddr(unsigned 
    1.47  static int map_dom_mem(unsigned long pfn, int pages, int dom, 
    1.48                         dom_mem_t * dom_mem)
    1.49  {
    1.50 -
    1.51 -    if(setup_dom_memmap(pfn, pages, dom)){
    1.52 -        perror(PERR_STRING);
    1.53 -        return -1;
    1.54 -    }
    1.55 +  struct dom0_mapdommem_args argbuf;
    1.56 +  int fd;
    1.57  
    1.58 -    dom_mem->domain = dom;
    1.59 -    dom_mem->start_pfn = pfn;
    1.60 -    dom_mem->tot_pages = pages;
    1.61 -    if((dom_mem->vaddr = get_vaddr(dom)) == 0){
    1.62 -        dberr("Error mapping dom memory.");
    1.63 -        return -1;
    1.64 -    }
    1.65 -    
    1.66 -    return 0;
    1.67 +  argbuf.domain = dom;
    1.68 +  argbuf.start_pfn = pfn;
    1.69 +  argbuf.tot_pages = pages;
    1.70 +  
    1.71 +  fd = open("/proc/xeno/dom0_cmd", O_RDWR);
    1.72 +  if (fd < 0) {
    1.73 +    perror("openning /proc/xeno/dom0_cmd");
    1.74 +    return -1;
    1.75 +  }
    1.76 +  
    1.77 +  dom_mem->domain = dom;
    1.78 +  dom_mem->start_pfn = pfn;
    1.79 +  dom_mem->tot_pages = pages;
    1.80 +  dom_mem->vaddr = ioctl(fd, IOCTL_DOM0_MAPDOMMEM, &argbuf);
    1.81 +
    1.82 +  if (dom_mem->vaddr == -1) {
    1.83 +    perror("mapping domain memory");
    1.84 +    return -1;
    1.85 +  }
    1.86 +
    1.87 +  return 0;
    1.88  }
    1.89  
    1.90  /* open kernel image and do some sanity checks */
    1.91 @@ -220,7 +230,7 @@ static dom_meminfo_t *setup_guestos(int 
    1.92      pgt_updates = (page_update_request_t *)dom_mem->vaddr;
    1.93      alloc_index = dom_mem->tot_pages - 1;
    1.94  
    1.95 -    memset(meminfo, 0, sizeof(meminfo));
    1.96 +    memset(meminfo, 0, sizeof(*meminfo));
    1.97  
    1.98      memcpy(page_array, (void *)dom_mem->vaddr, dom_mem->tot_pages * 4);
    1.99  
     2.1 --- a/xen/include/hypervisor-ifs/dom0_ops.h	Mon Jul 07 15:36:18 2003 +0000
     2.2 +++ b/xen/include/hypervisor-ifs/dom0_ops.h	Tue Jul 08 10:38:14 2003 +0000
     2.3 @@ -24,8 +24,6 @@
     2.4  #define MAX_CMD_LEN       256
     2.5  #define MAX_DOMAIN_NAME    16
     2.6  
     2.7 -#define IOCTL_DOM0_CREATEDOMAIN _IOC(_IOC_NONE, 'x', 0, 0)
     2.8 -
     2.9  typedef struct dom0_newdomain_st 
    2.10  {
    2.11      unsigned int domain;    // return parameter
    2.12 @@ -114,12 +112,31 @@ typedef struct dom0_op_st
    2.13  } dom0_op_t;
    2.14  #endif
    2.15  
    2.16 -/* Arguments to the CREATEDOMAIN ioctl on /proc/xeno/dom0_cmd.
    2.17 -   Probably belongs in a Linux include file somewhere... */
    2.18 +/* These really belong in a Linux header file somewhere.
    2.19 +   XXX.
    2.20 +*/
    2.21 +#define IOCTL_DOM0_CREATEDOMAIN _IOC(_IOC_READ, 'x', 0, sizeof(struct dom0_createdomain_args))
    2.22 +#define IOCTL_DOM0_MAPDOMMEM _IOC(_IOC_READ, 'x', 1, sizeof(struct dom0_mapdommem_args))
    2.23 +#define IOCTL_DOM0_UNMAPDOMMEM _IOC(_IOC_READ, 'x', 2, sizeof(struct dom0_unmapdommem_args))
    2.24 +
    2.25  struct dom0_createdomain_args
    2.26  {
    2.27    unsigned int kb_mem;
    2.28    const char *name;
    2.29  };
    2.30  
    2.31 +struct dom0_mapdommem_args
    2.32 +{
    2.33 +  unsigned int domain;
    2.34 +  unsigned start_pfn;
    2.35 +  unsigned tot_pages;  
    2.36 +};
    2.37 +
    2.38 +struct dom0_unmapdommem_args
    2.39 +{
    2.40 +  unsigned long vaddr;
    2.41 +  unsigned long start_pfn;
    2.42 +  unsigned long tot_pages;
    2.43 +};
    2.44 +
    2.45  #endif
     3.1 --- a/xenolinux-2.4.21-sparse/arch/xeno/drivers/dom0/dom0_core.c	Mon Jul 07 15:36:18 2003 +0000
     3.2 +++ b/xenolinux-2.4.21-sparse/arch/xeno/drivers/dom0/dom0_core.c	Tue Jul 08 10:38:14 2003 +0000
     3.3 @@ -157,6 +157,8 @@ static ssize_t dom_mem_write(struct file
     3.4  {
     3.5      dom_mem_t mem_data;
     3.6      
     3.7 +    printk("dom_mem_write called: Shouldn't happen.\n");
     3.8 +
     3.9      copy_from_user(&mem_data, (dom_mem_t *)buff, sizeof(dom_mem_t));
    3.10      
    3.11      if(direct_disc_unmap(mem_data.vaddr, mem_data.start_pfn, 
    3.12 @@ -178,6 +180,9 @@ static ssize_t dom_mem_read(struct file 
    3.13  
    3.14      /* remap the range using xen specific routines */
    3.15  
    3.16 +    printk("Calling direct_mmap with pfn %x, tot pages %x.\n",
    3.17 +	   mem_data->pfn, mem_data->tot_pages);
    3.18 +
    3.19      addr = direct_mmap(mem_data->pfn << PAGE_SHIFT, mem_data->tot_pages << PAGE_SHIFT, prot, MAP_DISCONT, mem_data->tot_pages);
    3.20      
    3.21      copy_to_user((unsigned long *)buff, &addr, sizeof(addr));
    3.22 @@ -204,6 +209,7 @@ static int dom_map_mem(unsigned int dom,
    3.23              /* check if there is already an entry for mem and if so
    3.24               * remove it.
    3.25               */
    3.26 +	    /* XXX does this not leak the memdata? */
    3.27              remove_proc_entry("mem", pd);
    3.28  
    3.29              /* create new entry with parameters describing what to do
    3.30 @@ -265,6 +271,10 @@ static int dom0_cmd_write(struct file *f
    3.31      {
    3.32          ret = dom_map_mem(op.u.dommem.domain, op.u.dommem.start_pfn, 
    3.33                            op.u.dommem.tot_pages); 
    3.34 +      /* This is now an ioctl, and shouldn't be being written to
    3.35 +	 the command file. */
    3.36 +	//      printk("map_dom_mem dom0_cmd used!\n");
    3.37 +	//      ret = -EOPNOTSUPP;
    3.38      }
    3.39      else if ( op.cmd == DO_PGUPDATES )
    3.40      {
    3.41 @@ -387,20 +397,16 @@ static int handle_dom0_cmd_createdomain(
    3.42    dom0_op_t op;
    3.43    int ret;
    3.44  
    3.45 -  if (copy_from_user(&argbuf, (void *)data, sizeof(argbuf))) {
    3.46 -    printk("fault getting argbuf.\n");
    3.47 +  if (copy_from_user(&argbuf, (void *)data, sizeof(argbuf)))
    3.48      return -EFAULT;
    3.49 -  }
    3.50  
    3.51    op.cmd = DOM0_CREATEDOMAIN;
    3.52    op.u.newdomain.domain = -666;
    3.53    op.u.newdomain.memory_kb = argbuf.kb_mem;
    3.54    op.u.newdomain.num_vifs = 0; /* Not used anymore, I hope... */
    3.55    namelen = strnlen_user(argbuf.name, MAX_DOMAIN_NAME);
    3.56 -  if (copy_from_user(op.u.newdomain.name, argbuf.name, namelen + 1)) {
    3.57 -    printk("Fault getting domain name\n");
    3.58 +  if (copy_from_user(op.u.newdomain.name, argbuf.name, namelen + 1))
    3.59      return -EFAULT;
    3.60 -  }
    3.61  
    3.62    /* Error checking?  The old code deosn't appear to do any, and I
    3.63       can't see where the return values are documented... */
    3.64 @@ -423,6 +429,42 @@ static int handle_dom0_cmd_createdomain(
    3.65    return ret;
    3.66  }
    3.67  
    3.68 +static unsigned long handle_dom0_cmd_mapdommem(unsigned long data)
    3.69 +{
    3.70 +  struct dom0_mapdommem_args argbuf;
    3.71 +  unsigned long addr;
    3.72 +
    3.73 +  if (copy_from_user(&argbuf, (void *)data, sizeof(argbuf)))
    3.74 +    return -EFAULT;
    3.75 +  /* This seems to be assuming that the root of the page table is in
    3.76 +     the first frame of the new domain's physical memory? */
    3.77 +  /* XXX do I really mean this? */
    3.78 +  /* XXX what happens if userspace forgets to do the unmap? */
    3.79 +  printk("direct_maping w/ start pfn %x, tot_pages %x.\n",
    3.80 +	 argbuf.start_pfn, argbuf.tot_pages);
    3.81 +
    3.82 +  addr = direct_mmap(argbuf.start_pfn << PAGE_SHIFT,
    3.83 +		     argbuf.tot_pages << PAGE_SHIFT,
    3.84 +		     PAGE_SHARED,
    3.85 +		     MAP_DISCONT,
    3.86 +		     argbuf.tot_pages);
    3.87 +
    3.88 +  printk("Picked vaddr %x.\n", addr);
    3.89 +
    3.90 +  return addr;
    3.91 +}
    3.92 +
    3.93 +static int handle_dom0_cmd_unmapdommem(unsigned long data)
    3.94 +{
    3.95 +  struct dom0_unmapdommem_args argbuf;
    3.96 +
    3.97 +  if (copy_from_user(&argbuf, (void *)data, sizeof(argbuf)))
    3.98 +    return -EFAULT;
    3.99 +
   3.100 +  return direct_disc_unmap(argbuf.vaddr, argbuf.start_pfn,
   3.101 +			   argbuf.tot_pages);
   3.102 +}
   3.103 +
   3.104  static int dom0_cmd_ioctl(struct inode *inode, struct file *file,
   3.105  			  unsigned int cmd, unsigned long data)
   3.106  {
   3.107 @@ -430,6 +472,10 @@ static int dom0_cmd_ioctl(struct inode *
   3.108    switch (cmd) {
   3.109    case IOCTL_DOM0_CREATEDOMAIN:
   3.110      return handle_dom0_cmd_createdomain(data);
   3.111 +  case IOCTL_DOM0_MAPDOMMEM:
   3.112 +    return handle_dom0_cmd_mapdommem(data);
   3.113 +  case IOCTL_DOM0_UNMAPDOMMEM:
   3.114 +    return handle_dom0_cmd_unmapdommem(data);
   3.115    default:
   3.116      printk("Unknown dom0_cmd ioctl!\n");
   3.117      return -EINVAL;