ia64/xen-unstable

changeset 3985:f7c31440d003

bitkeeper revision 1.1236.9.1 (4227c12cJQxFhBUYk0ojkmnooUw0jQ)

Grant tables work on data structures.
author cwc22@centipede.cl.cam.ac.uk
date Fri Mar 04 02:00:12 2005 +0000 (2005-03-04)
parents 86b610094dd0
children d400d2b7feaf
files .rootkeys linux-2.6.10-xen-sparse/arch/xen/kernel/gnttab.c linux-2.6.10-xen-sparse/include/asm-xen/gnttab.h linux-2.6.10-xen-sparse/include/asm-xen/hypervisor.h tools/libxc/Makefile tools/libxc/xc.h tools/libxc/xc_gnttab.c tools/libxc/xc_vmx_build.c xen/common/grant_table.c xen/include/public/grant_table.h xen/include/xen/grant_table.h
line diff
     1.1 --- a/.rootkeys	Thu Feb 24 11:11:57 2005 +0000
     1.2 +++ b/.rootkeys	Fri Mar 04 02:00:12 2005 +0000
     1.3 @@ -542,6 +542,7 @@ 3fbba6dbEVkVMX0JuDFzap9jeaucGA tools/lib
     1.4  3fbba6dbasJQV-MVElDC0DGSHMiL5w tools/libxc/xc_domain.c
     1.5  40278d99BLsfUv3qxv0I8C1sClZ0ow tools/libxc/xc_elf.h
     1.6  403e0977Bjsm_e82pwvl9VvaJxh8Gg tools/libxc/xc_evtchn.c
     1.7 +4227c129ZKjJPNYooHVzBCyinf7Y6Q tools/libxc/xc_gnttab.c
     1.8  40e03333Eegw8czSWvHsbKxrRZJjRA tools/libxc/xc_io.c
     1.9  40e03333vrWGbLAhyJjXlqCHaJt7eA tools/libxc/xc_io.h
    1.10  3fbba6dbNCU7U6nsMYiXzKkp3ztaJg tools/libxc/xc_linux_build.c
     2.1 --- a/linux-2.6.10-xen-sparse/arch/xen/kernel/gnttab.c	Thu Feb 24 11:11:57 2005 +0000
     2.2 +++ b/linux-2.6.10-xen-sparse/arch/xen/kernel/gnttab.c	Fri Mar 04 02:00:12 2005 +0000
     2.3 @@ -6,6 +6,7 @@
     2.4   * 2. Accessing others' memory reservations via grant references.
     2.5   * (i.e., mechanisms for both sender and recipient of grant references)
     2.6   * 
     2.7 + * Copyright (c) 2005, Christopher Clark
     2.8   * Copyright (c) 2004, K A Fraser
     2.9   */
    2.10  
    2.11 @@ -14,6 +15,9 @@
    2.12  #include <linux/sched.h>
    2.13  #include <asm/pgtable.h>
    2.14  #include <asm/fixmap.h>
    2.15 +#include <asm/uaccess.h>
    2.16 +#include <asm-xen/xen_proc.h>
    2.17 +#include <asm-xen/linux-public/privcmd.h>
    2.18  #include <asm-xen/gnttab.h>
    2.19  
    2.20  #ifndef set_fixmap_ma
    2.21 @@ -28,8 +32,13 @@
    2.22  #define ASSERT(_p) ((void)0)
    2.23  #endif
    2.24  
    2.25 +#define WPRINTK(fmt, args...) \
    2.26 +    printk(KERN_WARNING "xen_grant: " fmt, ##args)
    2.27 +
    2.28 +
    2.29  EXPORT_SYMBOL(gnttab_grant_foreign_access);
    2.30  EXPORT_SYMBOL(gnttab_end_foreign_access);
    2.31 +EXPORT_SYMBOL(gnttab_query_foreign_access);
    2.32  EXPORT_SYMBOL(gnttab_grant_foreign_transfer);
    2.33  EXPORT_SYMBOL(gnttab_end_foreign_transfer);
    2.34  
    2.35 @@ -39,6 +48,10 @@ static grant_ref_t gnttab_free_head;
    2.36  
    2.37  static grant_entry_t *shared;
    2.38  
    2.39 +/* /proc/xen/grant */
    2.40 +static struct proc_dir_entry *grant_pde;
    2.41 +
    2.42 +
    2.43  /*
    2.44   * Lock-free grant-entry allocator
    2.45   */
    2.46 @@ -84,9 +97,18 @@ gnttab_grant_foreign_access(
    2.47      return ref;
    2.48  }
    2.49  
    2.50 +int
    2.51 +gnttab_query_foreign_access( grant_ref_t ref )
    2.52 +{
    2.53 +    u16 nflags;
    2.54 +
    2.55 +    nflags = shared[ref].flags;
    2.56 +
    2.57 +    return ( nflags & (GTF_reading|GTF_writing) );
    2.58 +}
    2.59 +
    2.60  void
    2.61 -gnttab_end_foreign_access(
    2.62 -    grant_ref_t ref, int readonly)
    2.63 +gnttab_end_foreign_access( grant_ref_t ref, int readonly )
    2.64  {
    2.65      u16 flags, nflags;
    2.66  
    2.67 @@ -141,7 +163,72 @@ gnttab_end_foreign_transfer(
    2.68      return frame;
    2.69  }
    2.70  
    2.71 -void __init gnttab_init(void)
    2.72 +static int grant_ioctl(struct inode *inode, struct file *file,
    2.73 +                       unsigned int cmd, unsigned long data)
    2.74 +{
    2.75 +    int                     ret;
    2.76 +    privcmd_hypercall_t     hypercall;
    2.77 +                                                                                        
    2.78 +    if ( cmd != IOCTL_PRIVCMD_HYPERCALL )
    2.79 +        return -ENOSYS;
    2.80 +
    2.81 +    if ( copy_from_user(&hypercall, (void *)data, sizeof(hypercall)) )
    2.82 +        return -EFAULT;
    2.83 +
    2.84 +    if ( hypercall.op != __HYPERVISOR_grant_table_op )
    2.85 +        return -ENOSYS;
    2.86 +
    2.87 +    /* hypercall-invoking asm taken from privcmd.c */
    2.88 +    __asm__ __volatile__ (
    2.89 +        "pushl %%ebx; pushl %%ecx; pushl %%edx; pushl %%esi; pushl %%edi; "
    2.90 +        "movl  4(%%eax),%%ebx ;"
    2.91 +        "movl  8(%%eax),%%ecx ;"
    2.92 +        "movl 12(%%eax),%%edx ;"
    2.93 +        "movl 16(%%eax),%%esi ;"
    2.94 +        "movl 20(%%eax),%%edi ;"
    2.95 +        "movl   (%%eax),%%eax ;"
    2.96 +        TRAP_INSTR "; "
    2.97 +        "popl %%edi; popl %%esi; popl %%edx; popl %%ecx; popl %%ebx"
    2.98 +        : "=a" (ret) : "0" (&hypercall) : "memory" );
    2.99 +                                                                                    
   2.100 +    return ret;
   2.101 +}
   2.102 +
   2.103 +static struct file_operations grant_file_ops = {
   2.104 +    ioctl:  grant_ioctl,
   2.105 +};
   2.106 +
   2.107 +static int grant_read(char *page, char **start, off_t off,
   2.108 +                      int count, int *eof, void *data)
   2.109 +{
   2.110 +    int             len;
   2.111 +    unsigned int    i;
   2.112 +    grant_entry_t  *gt;
   2.113 +
   2.114 +    gt = (grant_entry_t *)shared;
   2.115 +    len = 0;
   2.116 +
   2.117 +    for ( i = 0; i < NR_GRANT_REFS; i++ )
   2.118 +        if ( gt[i].flags )
   2.119 +            len += sprintf( page + len,
   2.120 +                    "Grant: ref (0x%x) flags (0x%hx) dom (0x%hx) frame (0x%x)\n", 
   2.121 +                    i,
   2.122 +                    gt[i].flags,
   2.123 +                    gt[i].domid,
   2.124 +                    gt[i].frame );
   2.125 +
   2.126 +    *eof = 1;
   2.127 +    return len;
   2.128 +}
   2.129 +
   2.130 +static int grant_write(struct file *file, const char __user *buffer,
   2.131 +                       unsigned long count, void *data)
   2.132 +{
   2.133 +    /* TODO: implement this */
   2.134 +    return -ENOSYS;
   2.135 +}
   2.136 +
   2.137 +static int __init gnttab_init(void)
   2.138  {
   2.139      gnttab_setup_table_t setup;
   2.140      unsigned long        frame;
   2.141 @@ -160,4 +247,25 @@ void __init gnttab_init(void)
   2.142  
   2.143      set_fixmap_ma(FIX_GNTTAB, frame << PAGE_SHIFT);
   2.144      shared = (grant_entry_t *)fix_to_virt(FIX_GNTTAB);
   2.145 +
   2.146 +    /*
   2.147 +     *  /proc/xen/grant : used by libxc to access grant tables
   2.148 +     */
   2.149 +    if ( (grant_pde = create_xen_proc_entry("grant", 0600)) == NULL )
   2.150 +    {
   2.151 +        WPRINTK("Unable to create grant xen proc entry\n");
   2.152 +        return -1;
   2.153 +    }
   2.154 +
   2.155 +    grant_file_ops.read   = grant_pde->proc_fops->read;
   2.156 +    grant_file_ops.write  = grant_pde->proc_fops->write;
   2.157 +
   2.158 +    grant_pde->proc_fops  = &grant_file_ops;
   2.159 +
   2.160 +    grant_pde->read_proc  = &grant_read;
   2.161 +    grant_pde->write_proc = &grant_write;
   2.162 +
   2.163 +    return 0;
   2.164  }
   2.165 +
   2.166 +__initcall(gnttab_init);
     3.1 --- a/linux-2.6.10-xen-sparse/include/asm-xen/gnttab.h	Thu Feb 24 11:11:57 2005 +0000
     3.2 +++ b/linux-2.6.10-xen-sparse/include/asm-xen/gnttab.h	Fri Mar 04 02:00:12 2005 +0000
     3.3 @@ -32,4 +32,8 @@ unsigned long
     3.4  gnttab_end_foreign_transfer(
     3.5      grant_ref_t ref);
     3.6  
     3.7 +int
     3.8 +gnttab_query_foreign_access( 
     3.9 +    grant_ref_t ref );
    3.10 +
    3.11  #endif /* __ASM_GNTTAB_H__ */
     4.1 --- a/linux-2.6.10-xen-sparse/include/asm-xen/hypervisor.h	Thu Feb 24 11:11:57 2005 +0000
     4.2 +++ b/linux-2.6.10-xen-sparse/include/asm-xen/hypervisor.h	Fri Mar 04 02:00:12 2005 +0000
     4.3 @@ -536,7 +536,7 @@ HYPERVISOR_grant_table_op(
     4.4      __asm__ __volatile__ (
     4.5          TRAP_INSTR
     4.6          : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3)
     4.7 -	: "0" (__HYPERVISOR_grant_table_op), "1" (cmd), "2" (count), "3" (uop)
     4.8 +	: "0" (__HYPERVISOR_grant_table_op), "1" (cmd), "2" (uop), "3" (count)
     4.9  	: "memory" );
    4.10  
    4.11      return ret;
     5.1 --- a/tools/libxc/Makefile	Thu Feb 24 11:11:57 2005 +0000
     5.2 +++ b/tools/libxc/Makefile	Fri Mar 04 02:00:12 2005 +0000
     5.3 @@ -20,6 +20,7 @@ SRCS     += xc_atropos.c
     5.4  SRCS     += xc_bvtsched.c
     5.5  SRCS     += xc_domain.c
     5.6  SRCS     += xc_evtchn.c
     5.7 +SRCS     += xc_gnttab.c
     5.8  SRCS     += xc_io.c
     5.9  SRCS     += xc_linux_build.c
    5.10  SRCS     += xc_plan9_build.c
     6.1 --- a/tools/libxc/xc.h	Thu Feb 24 11:11:57 2005 +0000
     6.2 +++ b/tools/libxc/xc.h	Fri Mar 04 02:00:12 2005 +0000
     6.3 @@ -395,4 +395,61 @@ void *xc_map_foreign_batch(int xc_handle
     6.4  int xc_get_pfn_list(int xc_handle, u32 domid, unsigned long *pfn_buf, 
     6.5  		    unsigned long max_pfns);
     6.6  
     6.7 +/*\
     6.8 + *  GRANT TABLE FUNCTIONS
     6.9 +\*/ 
    6.10 +
    6.11 +/**
    6.12 + * This function opens a handle to the more restricted grant table hypervisor
    6.13 + * interface. This may be used where the standard interface is not
    6.14 + * available because the domain is not privileged.
    6.15 + * This function can  be called multiple times within a single process.
    6.16 + * Multiple processes can have an open hypervisor interface at the same time.
    6.17 + *
    6.18 + * Each call to this function should have a corresponding call to
    6.19 + * xc_grant_interface_close().
    6.20 + *
    6.21 + * This function can fail if a Xen-enabled kernel is not currently running.
    6.22 + *
    6.23 + * @return a handle to the hypervisor grant table interface or -1 on failure
    6.24 + */
    6.25 +int xc_grant_interface_open(void);
    6.26 +
    6.27 +/**
    6.28 + * This function closes an open grant table hypervisor interface.
    6.29 + *
    6.30 + * This function can fail if the handle does not represent an open interface or
    6.31 + * if there were problems closing the interface.
    6.32 + *
    6.33 + * @parm xc_handle a handle to an open grant table hypervisor interface
    6.34 + * @return 0 on success, -1 otherwise.
    6.35 + */
    6.36 +int xc_grant_interface_close(int xc_handle);
    6.37 +
    6.38 +int xc_gnttab_map_grant_ref(int         xc_handle,
    6.39 +                            memory_t    host_virt_addr,
    6.40 +                            u32         dom,
    6.41 +                            u16         ref,
    6.42 +                            u16         flags,
    6.43 +                            s16        *handle,
    6.44 +                            memory_t   *dev_bus_addr);
    6.45 +
    6.46 +int xc_gnttab_unmap_grant_ref(int       xc_handle,
    6.47 +                              memory_t  host_virt_addr,
    6.48 +                              memory_t  dev_bus_addr,
    6.49 +                              u16       handle,
    6.50 +                              s16      *status);
    6.51 +
    6.52 +int xc_gnttab_setup_table(int        xc_handle,
    6.53 +                          u32        dom,
    6.54 +                          u16        nr_frames,
    6.55 +                          s16       *status,
    6.56 +                          memory_t **frame_list);
    6.57 +
    6.58 +/* Grant debug builds only: */
    6.59 +int xc_gnttab_dump_table(int        xc_handle,
    6.60 +                         u32        dom,
    6.61 +                         s16       *status);
    6.62 +
    6.63 +
    6.64  #endif /* __XC_H__ */
     7.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.2 +++ b/tools/libxc/xc_gnttab.c	Fri Mar 04 02:00:12 2005 +0000
     7.3 @@ -0,0 +1,143 @@
     7.4 +/******************************************************************************
     7.5 + * xc_gnttab.c
     7.6 + * 
     7.7 + * API for manipulating and accessing grant tables
     7.8 + * 
     7.9 + * Copyright (c) 2005 Christopher Clark
    7.10 + * based on xc_evtchn.c Copyright (c) 2004, K A Fraser.
    7.11 + */
    7.12 +
    7.13 +#include "xc_private.h"
    7.14 +#include "xen/grant_table.h"
    7.15 +
    7.16 +static int
    7.17 +do_gnttab_op( int xc_handle,
    7.18 +              unsigned long cmd,
    7.19 +              gnttab_op_t *op,
    7.20 +              unsigned long count )
    7.21 +{
    7.22 +    int ret = -1;
    7.23 +    privcmd_hypercall_t hypercall;
    7.24 +
    7.25 +    hypercall.op     = __HYPERVISOR_grant_table_op;
    7.26 +    hypercall.arg[0] = cmd;
    7.27 +    hypercall.arg[1] = (unsigned long)(op);
    7.28 +    hypercall.arg[2] = count;
    7.29 +
    7.30 +    if ( mlock(op, sizeof(*op)) != 0 )
    7.31 +    {
    7.32 +        PERROR("Could not lock memory for Xen hypercall");
    7.33 +        goto out1;
    7.34 +    }
    7.35 +
    7.36 +    if ( (ret = do_xen_hypercall(xc_handle, &hypercall)) < 0 )
    7.37 +    {
    7.38 +        printf("do_gnttab_op: hypercall returned error %d\n", ret);
    7.39 +        goto out2;
    7.40 +    }
    7.41 +
    7.42 + out2: (void)munlock(op, sizeof(*op));
    7.43 + out1: return ret;
    7.44 +}
    7.45 +
    7.46 +
    7.47 +int xc_gnttab_map_grant_ref(int         xc_handle,
    7.48 +                            memory_t    host_virt_addr,
    7.49 +                            u32         dom,
    7.50 +                            u16         ref,
    7.51 +                            u16         flags,
    7.52 +                            s16        *handle,
    7.53 +                            memory_t   *dev_bus_addr)
    7.54 +{
    7.55 +    gnttab_op_t     op;
    7.56 +    int             rc;
    7.57 +
    7.58 +    op.u.map_grant_ref.host_virt_addr = host_virt_addr;
    7.59 +    op.u.map_grant_ref.dom            = (domid_t)dom;
    7.60 +    op.u.map_grant_ref.ref            = ref;
    7.61 +    op.u.map_grant_ref.flags          = flags;
    7.62 + 
    7.63 +    if ( (rc = do_gnttab_op(xc_handle, GNTTABOP_map_grant_ref, &op, 1)) == 0 )
    7.64 +    {
    7.65 +        *handle         = op.u.map_grant_ref.handle;
    7.66 +        *dev_bus_addr   = op.u.map_grant_ref.dev_bus_addr;
    7.67 +    }
    7.68 +
    7.69 +    return rc;
    7.70 +}
    7.71 +
    7.72 +
    7.73 +int xc_gnttab_unmap_grant_ref(int       xc_handle,
    7.74 +                              memory_t  host_virt_addr,
    7.75 +                              memory_t  dev_bus_addr,
    7.76 +                              u16       handle,
    7.77 +                              s16      *status)
    7.78 +{
    7.79 +    gnttab_op_t     op;
    7.80 +    int             rc;
    7.81 +
    7.82 +    op.u.unmap_grant_ref.host_virt_addr = host_virt_addr;
    7.83 +    op.u.unmap_grant_ref.dev_bus_addr   = dev_bus_addr;
    7.84 +    op.u.unmap_grant_ref.handle         = handle;
    7.85 + 
    7.86 +    if ( (rc = do_gnttab_op(xc_handle, GNTTABOP_unmap_grant_ref, &op, 1)) == 0 )
    7.87 +        *status = op.u.unmap_grant_ref.status;
    7.88 +
    7.89 +    return rc;
    7.90 +}
    7.91 +
    7.92 +int xc_gnttab_setup_table(int        xc_handle,
    7.93 +                          u32        dom,
    7.94 +                          u16        nr_frames,
    7.95 +                          s16       *status,
    7.96 +                          memory_t **frame_list)
    7.97 +{
    7.98 +    gnttab_op_t     op;
    7.99 +    int             rc;
   7.100 +    int             i;
   7.101 +
   7.102 +    op.u.setup_table.dom        = (domid_t)dom;
   7.103 +    op.u.setup_table.nr_frames  = nr_frames;
   7.104 + 
   7.105 +    if ( (rc = do_gnttab_op(xc_handle, GNTTABOP_setup_table, &op, 1)) == 0 )
   7.106 +    {
   7.107 +        *status = op.u.setup_table.status;
   7.108 +        for ( i = 0; i < nr_frames; i++ )
   7.109 +        {
   7.110 +            (*frame_list)[i] = op.u.setup_table.frame_list[i];
   7.111 +        }
   7.112 +    }
   7.113 +
   7.114 +    return rc;
   7.115 +}
   7.116 +
   7.117 +int xc_gnttab_dump_table(int        xc_handle,
   7.118 +                         u32        dom,
   7.119 +                         s16       *status)
   7.120 +{
   7.121 +    gnttab_op_t     op;
   7.122 +    int             rc;
   7.123 +
   7.124 +    op.u.dump_table.dom = (domid_t)dom;
   7.125 + 
   7.126 +    printf("xc_gnttab_dump_table: domain %d\n", dom);
   7.127 +
   7.128 +    if ( (rc = do_gnttab_op(xc_handle, GNTTABOP_dump_table, &op, 1)) == 0 )
   7.129 +        *status = op.u.dump_table.status;
   7.130 +
   7.131 +    return rc;
   7.132 +}
   7.133 +
   7.134 +int xc_grant_interface_open(void)
   7.135 +{
   7.136 +    int fd = open("/proc/xen/grant", O_RDWR);
   7.137 +    if ( fd == -1 )
   7.138 +        PERROR("Could not obtain handle on grant command interface");
   7.139 +    return fd;
   7.140 +
   7.141 +}
   7.142 +
   7.143 +int xc_grant_interface_close(int xc_grant_handle)
   7.144 +{
   7.145 +    return close(xc_grant_handle);
   7.146 +}
     8.1 --- a/tools/libxc/xc_vmx_build.c	Thu Feb 24 11:11:57 2005 +0000
     8.2 +++ b/tools/libxc/xc_vmx_build.c	Fri Mar 04 02:00:12 2005 +0000
     8.3 @@ -465,10 +465,10 @@ int vmx_identify(void)
     8.4  {
     8.5      int eax, ecx;
     8.6  
     8.7 -    __asm__ __volatile__ ("cpuid" 
     8.8 +    __asm__ __volatile__ ("pushl %%ebx; cpuid; popl %%ebx" 
     8.9  			  : "=a" (eax), "=c" (ecx) 
    8.10  			  : "0" (1) 
    8.11 -			  : "bx", "dx");
    8.12 +			  : "dx");
    8.13      if (!(ecx & VMX_FEATURE_FLAG)) {
    8.14          return -1;
    8.15      }
     9.1 --- a/xen/common/grant_table.c	Thu Feb 24 11:11:57 2005 +0000
     9.2 +++ b/xen/common/grant_table.c	Fri Mar 04 02:00:12 2005 +0000
     9.3 @@ -110,6 +110,8 @@ static void
     9.4          (void)__put_user(GNTST_no_device_space, &uop->handle);
     9.5          return;
     9.6      }
     9.7 +    DPRINTK("Mapping grant ref (%hu) for domain (%hu) with flags (%x)\n",
     9.8 +            ref, dom, flags);
     9.9  
    9.10      act = &rd->grant_table->active[ref];
    9.11      sha = &rd->grant_table->shared[ref];
    9.12 @@ -324,6 +326,8 @@ static void
    9.13          (void)__put_user(GNTST_bad_domain, &uop->status);
    9.14          return;
    9.15      }
    9.16 +    DPRINTK("Unmapping grant ref (%hu) for domain (%hu) with handle (%hu)\n",
    9.17 +            ref, dom, handle);
    9.18  
    9.19      act = &rd->grant_table->active[ref];
    9.20      sha = &rd->grant_table->shared[ref];
    9.21 @@ -423,7 +427,7 @@ gnttab_setup_table(
    9.22      {
    9.23          ASSERT(d->grant_table != NULL);
    9.24          (void)put_user(GNTST_okay, &uop->status);
    9.25 -        (void)put_user(virt_to_phys(d->grant_table) >> PAGE_SHIFT,
    9.26 +        (void)put_user(virt_to_phys(d->grant_table->shared) >> PAGE_SHIFT,
    9.27                         &uop->frame_list[0]);
    9.28      }
    9.29  
    9.30 @@ -431,14 +435,99 @@ gnttab_setup_table(
    9.31      return 0;
    9.32  }
    9.33  
    9.34 +#ifdef GRANT_DEBUG
    9.35 +static int
    9.36 +gnttab_dump_table(gnttab_dump_table_t *uop)
    9.37 +{
    9.38 +    grant_table_t        *gt;
    9.39 +    gnttab_dump_table_t   op;
    9.40 +    struct domain        *d;
    9.41 +    u32                   shared_mfn;
    9.42 +    active_grant_entry_t *act;
    9.43 +    grant_entry_t         sha_copy;
    9.44 +    grant_mapping_t      *maptrack;
    9.45 +    int                   i;
    9.46 +
    9.47 +
    9.48 +    if ( unlikely(copy_from_user(&op, uop, sizeof(op)) != 0) )
    9.49 +    {
    9.50 +        DPRINTK("Fault while reading gnttab_dump_table_t.\n");
    9.51 +        return -EFAULT;
    9.52 +    }
    9.53 +
    9.54 +    if ( op.dom == DOMID_SELF )
    9.55 +    {
    9.56 +        op.dom = current->domain->id;
    9.57 +    }
    9.58 +
    9.59 +    if ( unlikely((d = find_domain_by_id(op.dom)) == NULL) )
    9.60 +    {
    9.61 +        DPRINTK("Bad domid %d.\n", op.dom);
    9.62 +        (void)put_user(GNTST_bad_domain, &uop->status);
    9.63 +        return 0;
    9.64 +    }
    9.65 +
    9.66 +    ASSERT(d->grant_table != NULL);
    9.67 +    gt = d->grant_table;
    9.68 +    (void)put_user(GNTST_okay, &uop->status);
    9.69 +
    9.70 +    shared_mfn = virt_to_phys(d->grant_table->shared);
    9.71 +
    9.72 +    DPRINTK("Grant table for dom (%hu) MFN (%x)\n",
    9.73 +            op.dom, shared_mfn);
    9.74 +
    9.75 +    spin_lock(&gt->lock);
    9.76 +
    9.77 +    ASSERT(d->grant_table->active != NULL);
    9.78 +    ASSERT(d->grant_table->shared != NULL);
    9.79 +
    9.80 +    for ( i = 0; i < NR_GRANT_ENTRIES; i++ )
    9.81 +    {
    9.82 +        act      = &gt->active[i];
    9.83 +        sha_copy =  gt->shared[i];
    9.84 +
    9.85 +        if ( act->pin || act->domid || act->frame ||
    9.86 +             sha_copy.flags || sha_copy.domid || sha_copy.frame )
    9.87 +        {
    9.88 +            DPRINTK("Grant: dom (%hu) ACTIVE (%d) pin:(%x) dom:(%hu) frame:(%u)\n",
    9.89 +                    op.dom, i, act->pin, act->domid, act->frame);
    9.90 +            DPRINTK("Grant: dom (%hu) SHARED (%d) flags:(%hx) dom:(%hu) frame:(%u)\n",
    9.91 +                    op.dom, i, sha_copy.flags, sha_copy.domid, sha_copy.frame);
    9.92 +
    9.93 +        }
    9.94 +
    9.95 +    }
    9.96 +
    9.97 +    ASSERT(d->grant_table->maptrack != NULL);
    9.98 +
    9.99 +    for ( i = 0; i < NR_MAPTRACK_ENTRIES; i++ )
   9.100 +    {
   9.101 +        maptrack = &gt->maptrack[i];
   9.102 +
   9.103 +        if ( maptrack->ref_and_flags & MAPTRACK_GNTMAP_MASK )
   9.104 +        {
   9.105 +            DPRINTK("Grant: dom (%hu) MAP (%d) ref:(%hu) flags:(%x) dom:(%hu)\n",
   9.106 +                    op.dom, i,
   9.107 +                    maptrack->ref_and_flags >> MAPTRACK_REF_SHIFT,
   9.108 +                    maptrack->ref_and_flags & MAPTRACK_GNTMAP_MASK,
   9.109 +                    maptrack->domid);
   9.110 +        }
   9.111 +    }
   9.112 +
   9.113 +    spin_unlock(&gt->lock);
   9.114 +
   9.115 +    put_domain(d);
   9.116 +    return 0;
   9.117 +}
   9.118 +#endif
   9.119 +
   9.120  long 
   9.121  do_grant_table_op(
   9.122      unsigned int cmd, void *uop, unsigned int count)
   9.123  {
   9.124      long rc;
   9.125  
   9.126 -    /* XXX stubbed out XXX */
   9.127 -    return -ENOSYS;
   9.128 +    DPRINTK("Grant: table operation (%u) count: (%u)\n", cmd, count);
   9.129  
   9.130      if ( count > 512 )
   9.131          return -EINVAL;
   9.132 @@ -462,6 +551,11 @@ do_grant_table_op(
   9.133      case GNTTABOP_setup_table:
   9.134          rc = gnttab_setup_table((gnttab_setup_table_t *)uop, count);
   9.135          break;
   9.136 +#ifdef GRANT_DEBUG
   9.137 +    case GNTTABOP_dump_table:
   9.138 +        rc = gnttab_dump_table((gnttab_dump_table_t *)uop);
   9.139 +        break;
   9.140 +#endif
   9.141      default:
   9.142          rc = -ENOSYS;
   9.143          break;
   9.144 @@ -607,6 +701,72 @@ grant_table_create(
   9.145      return -ENOMEM;
   9.146  }
   9.147  
   9.148 +static void
   9.149 +gnttab_release_all_mappings(grant_table_t *gt)
   9.150 +{
   9.151 +    grant_mapping_t        *map;
   9.152 +    domid_t                 dom;
   9.153 +    grant_ref_t             ref;
   9.154 +    u16                     handle, i;
   9.155 +    struct domain          *ld, *rd;
   9.156 +    unsigned long           frame;
   9.157 +    active_grant_entry_t   *act;
   9.158 +    grant_entry_t          *sha;
   9.159 +
   9.160 +    ld = current->domain;
   9.161 +
   9.162 +    for ( handle = 0; handle < NR_MAPTRACK_ENTRIES; handle++ )
   9.163 +    {
   9.164 +        map = &gt->maptrack[handle];
   9.165 +                                                                                        
   9.166 +        if ( map->ref_and_flags & MAPTRACK_GNTMAP_MASK )
   9.167 +        {
   9.168 +            dom = map->domid;
   9.169 +            ref = map->ref_and_flags >> MAPTRACK_REF_SHIFT;
   9.170 +
   9.171 +            DPRINTK("Grant release (%hu) ref:(%hu) flags:(%x) dom:(%hu)\n",
   9.172 +                    handle, ref,
   9.173 +                    map->ref_and_flags & MAPTRACK_GNTMAP_MASK, dom);
   9.174 +
   9.175 +            if ( unlikely((rd = find_domain_by_id(dom)) == NULL) ||
   9.176 +                 unlikely(ld == rd) )
   9.177 +            {
   9.178 +                if ( rd != NULL )
   9.179 +                    put_domain(rd);
   9.180 +                /* TODO: need to be able to handle domains destroyed
   9.181 +                 *       with active mappings.
   9.182 +                 */
   9.183 +                DPRINTK("Grant release: Could not find domain %d\n", dom);
   9.184 +                continue;
   9.185 +            }
   9.186 +
   9.187 +            act = &rd->grant_table->active[ref];
   9.188 +            sha = &rd->grant_table->shared[ref];
   9.189 +
   9.190 +            spin_lock(&rd->grant_table->lock);
   9.191 +
   9.192 +            frame = act->frame;
   9.193 +
   9.194 +            for ( i = ((act->pin & GNTPIN_hstw_mask) >> GNTPIN_hstw_shift) +
   9.195 +                      ((act->pin & GNTPIN_devw_mask) >> GNTPIN_devw_shift);
   9.196 +                  i > 0; i-- )
   9.197 +            {
   9.198 +                put_page_type(&frame_table[frame]);
   9.199 +            }
   9.200 +            act->pin = 0;
   9.201 +
   9.202 +            put_page(&frame_table[frame]);
   9.203 +
   9.204 +            clear_bit(_GTF_reading, &sha->flags);
   9.205 +            clear_bit(_GTF_writing, &sha->flags);
   9.206 +
   9.207 +            spin_unlock(&rd->grant_table->lock);
   9.208 +
   9.209 +            put_domain(rd);
   9.210 +        }
   9.211 +    }
   9.212 +}
   9.213 +
   9.214  void
   9.215  grant_table_destroy(
   9.216      struct domain *d)
   9.217 @@ -615,6 +775,9 @@ grant_table_destroy(
   9.218  
   9.219      if ( (t = d->grant_table) != NULL )
   9.220      {
   9.221 +        if ( t->maptrack != NULL )
   9.222 +            gnttab_release_all_mappings(t);
   9.223 +
   9.224          /* Free memory relating to this grant table. */
   9.225          d->grant_table = NULL;
   9.226          free_xenheap_page((unsigned long)t->shared);
   9.227 @@ -629,6 +792,7 @@ grant_table_init(
   9.228      void)
   9.229  {
   9.230      /* Nothing. */
   9.231 +    DPRINTK("Grant table init\n");
   9.232  }
   9.233  
   9.234  /*
    10.1 --- a/xen/include/public/grant_table.h	Thu Feb 24 11:11:57 2005 +0000
    10.2 +++ b/xen/include/public/grant_table.h	Fri Mar 04 02:00:12 2005 +0000
    10.3 @@ -207,6 +207,19 @@ typedef struct {
    10.4  } PACKED gnttab_setup_table_t; /* 16 bytes */
    10.5  
    10.6  /*
    10.7 + * GNTTABOP_dump_table: Dump the contents of the grant table to the
    10.8 + * xen console. Debugging use only.
    10.9 + */
   10.10 +#define GNTTABOP_dump_table           3
   10.11 +typedef struct {
   10.12 +    /* IN parameters. */
   10.13 +    domid_t     dom;                  /*  0 */
   10.14 +    /* OUT parameters. */
   10.15 +    s16         status;               /* 2: GNTST_* */
   10.16 +} PACKED gnttab_dump_table_t; /* 4 bytes */
   10.17 +
   10.18 +
   10.19 +/*
   10.20   * Bitfield values for update_pin_status.flags.
   10.21   */
   10.22   /* Map the grant entry for access by I/O devices. */
   10.23 @@ -247,5 +260,15 @@ typedef struct {
   10.24      "permission denied"                         \
   10.25  }
   10.26          
   10.27 +                                                                                       
   10.28 +typedef struct {
   10.29 +    union {                           /*  0 */
   10.30 +        gnttab_map_grant_ref_t    map_grant_ref;
   10.31 +        gnttab_unmap_grant_ref_t  unmap_grant_ref;
   10.32 +        gnttab_setup_table_t      setup_table;
   10.33 +        gnttab_dump_table_t       dump_table;
   10.34 +        u8                        __dummy[24];
   10.35 +    } PACKED u;
   10.36 +} PACKED gnttab_op_t; /* 32 bytes */
   10.37  
   10.38  #endif /* __XEN_PUBLIC_GRANT_TABLE_H__ */
    11.1 --- a/xen/include/xen/grant_table.h	Thu Feb 24 11:11:57 2005 +0000
    11.2 +++ b/xen/include/xen/grant_table.h	Fri Mar 04 02:00:12 2005 +0000
    11.3 @@ -27,6 +27,8 @@
    11.4  #include <xen/config.h>
    11.5  #include <public/grant_table.h>
    11.6  
    11.7 +#define GRANT_DEBUG 1
    11.8 +
    11.9  /* Active grant entry - used for shadowing GTF_permit_access grants. */
   11.10  typedef struct {
   11.11      u32           pin;    /* Reference count information.  */