ia64/xen-unstable

changeset 4590:35357e323f14

bitkeeper revision 1.1338 (4266317ezHysqYzH_WRvfueqwU4i4Q)

Grant tables for FreeBSD.
Signed-off-by: Kip Macy <kmacy@fsmware.com>
Signed-off-by: Keir Fraser <keir@xensource.com>
author kaf24@firebug.cl.cam.ac.uk
date Wed Apr 20 10:39:58 2005 +0000 (2005-04-20)
parents 6b0edacf8b40
children 1803018b3b05 d10fe13887d7
files .rootkeys freebsd-5.3-xen-sparse/conf/files.i386-xen freebsd-5.3-xen-sparse/i386-xen/i386-xen/gnttab.c freebsd-5.3-xen-sparse/i386-xen/i386-xen/machdep.c freebsd-5.3-xen-sparse/i386-xen/i386-xen/pmap.c freebsd-5.3-xen-sparse/i386-xen/include/gnttab.h freebsd-5.3-xen-sparse/i386-xen/include/hypervisor-ifs.h freebsd-5.3-xen-sparse/i386-xen/include/hypervisor.h freebsd-5.3-xen-sparse/i386-xen/include/xenpmap.h freebsd-5.3-xen-sparse/i386-xen/xen/blkfront/xb_blkfront.c
line diff
     1.1 --- a/.rootkeys	Wed Apr 20 10:36:34 2005 +0000
     1.2 +++ b/.rootkeys	Wed Apr 20 10:39:58 2005 +0000
     1.3 @@ -71,6 +71,7 @@ 423e7e885ZJMOinNI0XzQE4EgL0N8g freebsd-5
     1.4  423e7e88B5vxFblc-MlhxKk9e4ieBw freebsd-5.3-xen-sparse/i386-xen/i386-xen/evtchn.c
     1.5  423e7e88z_BrFu1O71-Ya4pXJpjAPQ freebsd-5.3-xen-sparse/i386-xen/i386-xen/exception.s
     1.6  423e7e88uDvAZLmABMkqOpmemyVRyw freebsd-5.3-xen-sparse/i386-xen/i386-xen/genassym.c
     1.7 +4266317eeOLpvRxIjmOYQVlL4WWQsg freebsd-5.3-xen-sparse/i386-xen/i386-xen/gnttab.c
     1.8  423e7e88yr5NFQudubMnkvdb_y-Gtg freebsd-5.3-xen-sparse/i386-xen/i386-xen/hypervisor.c
     1.9  423e7e88Y-e-4RRf9nrgkVn5PXUv3Q freebsd-5.3-xen-sparse/i386-xen/i386-xen/i686_mem.c
    1.10  423e7e88b8m2cuGtOxVvs4Sok4Vk7Q freebsd-5.3-xen-sparse/i386-xen/i386-xen/initcpu.c
    1.11 @@ -95,6 +96,7 @@ 423e7e8aVYTynjpZsJxUsFSlIDhpJw freebsd-5
    1.12  423e7e8avrrUxDugrwq_GJp499DkJw freebsd-5.3-xen-sparse/i386-xen/include/ctrl_if.h
    1.13  423e7e8apY1r9Td-S0eZITNZZbfNTQ freebsd-5.3-xen-sparse/i386-xen/include/evtchn.h
    1.14  423e7e8aL9DsObEegCwtILrF6SWcAQ freebsd-5.3-xen-sparse/i386-xen/include/frame.h
    1.15 +4266317eOVvN00XdcqRfDRFIrbqgvg freebsd-5.3-xen-sparse/i386-xen/include/gnttab.h
    1.16  423e7e8btv8Gojq50ggnP5A1Dkc4kA freebsd-5.3-xen-sparse/i386-xen/include/hypervisor-ifs.h
    1.17  423e7e8buhTLVFLZ33-5s8-UdADSZg freebsd-5.3-xen-sparse/i386-xen/include/hypervisor.h
    1.18  423e7e8bnHT1kMD-FPC7zHZR7l3VXw freebsd-5.3-xen-sparse/i386-xen/include/md_var.h
     2.1 --- a/freebsd-5.3-xen-sparse/conf/files.i386-xen	Wed Apr 20 10:36:34 2005 +0000
     2.2 +++ b/freebsd-5.3-xen-sparse/conf/files.i386-xen	Wed Apr 20 10:39:58 2005 +0000
     2.3 @@ -202,18 +202,19 @@ i386/i386/perfmon.c		optional	perfmon	pr
     2.4  i386-xen/i386-xen/pmap.c	standard
     2.5  i386-xen/i386-xen/support.s	standard
     2.6  i386-xen/i386-xen/swtch.s	standard
     2.7 -i386-xen/i386-xen/sys_machdep.c		standard
     2.8 +i386-xen/i386-xen/sys_machdep.c	standard
     2.9  i386-xen/i386-xen/trap.c	standard
    2.10  i386/i386/tsc.c			standard
    2.11 -i386-xen/i386-xen/vm_machdep.c		standard
    2.12 +i386-xen/i386-xen/vm_machdep.c	standard
    2.13  i386-xen/i386-xen/clock.c	standard
    2.14  
    2.15  # xen specific arch-dep files
    2.16  i386-xen/i386-xen/hypervisor.c	standard
    2.17  i386-xen/i386-xen/xen_machdep.c	standard
    2.18 -i386-xen/i386-xen/xen_bus.c		standard
    2.19 -i386-xen/i386-xen/evtchn.c		standard
    2.20 -i386-xen/i386-xen/ctrl_if.c		standard
    2.21 +i386-xen/i386-xen/xen_bus.c	standard
    2.22 +i386-xen/i386-xen/evtchn.c	standard
    2.23 +i386-xen/i386-xen/ctrl_if.c	standard
    2.24 +i386-xen/i386-xen/gnttab.c	standard
    2.25  
    2.26  
    2.27  i386/isa/asc.c			count		asc
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/freebsd-5.3-xen-sparse/i386-xen/i386-xen/gnttab.c	Wed Apr 20 10:39:58 2005 +0000
     3.3 @@ -0,0 +1,367 @@
     3.4 +/******************************************************************************
     3.5 + * gnttab.c
     3.6 + * 
     3.7 + * Two sets of functionality:
     3.8 + * 1. Granting foreign access to our memory reservation.
     3.9 + * 2. Accessing others' memory reservations via grant references.
    3.10 + * (i.e., mechanisms for both sender and recipient of grant references)
    3.11 + * 
    3.12 + * Copyright (c) 2005, Christopher Clark
    3.13 + * Copyright (c) 2004, K A Fraser
    3.14 + */
    3.15 +
    3.16 +#include "opt_pmap.h"
    3.17 +#include <sys/param.h>
    3.18 +#include <sys/systm.h>
    3.19 +#include <sys/bus.h>
    3.20 +#include <sys/conf.h>
    3.21 +#include <sys/module.h>
    3.22 +#include <sys/kernel.h>
    3.23 +#include <sys/lock.h>
    3.24 +#include <sys/malloc.h>
    3.25 +#include <sys/mman.h>
    3.26 +#include <vm/vm.h>
    3.27 +#include <vm/vm_extern.h>
    3.28 +#include <vm/pmap.h>
    3.29 +#include <vm/vm_kern.h>
    3.30 +
    3.31 +#include <machine/gnttab.h>
    3.32 +#include <machine/pmap.h>
    3.33 +
    3.34 +#include <machine/hypervisor-ifs.h>
    3.35 +
    3.36 +#define cmpxchg(a, b, c) atomic_cmpset_int((volatile u_int *)(a),(b),(c))
    3.37 +
    3.38 +
    3.39 +/* REP NOP (PAUSE) is a good thing to insert into busy-wait loops. */
    3.40 +static inline void rep_nop(void)
    3.41 +{
    3.42 +    __asm__ __volatile__ ( "rep;nop" : : : "memory" );
    3.43 +}
    3.44 +#define cpu_relax() rep_nop()
    3.45 +
    3.46 +#if 1
    3.47 +#define ASSERT(_p) \
    3.48 +    if ( !(_p) ) { printk("Assertion '%s': line %d, file %s\n", \
    3.49 +    #_p , __LINE__, __FILE__); *(int*)0=0; }
    3.50 +#else
    3.51 +#define ASSERT(_p) ((void)0)
    3.52 +#endif
    3.53 +
    3.54 +#define WPRINTK(fmt, args...) \
    3.55 +    printk("xen_grant: " fmt, ##args)
    3.56 +
    3.57 +static grant_ref_t gnttab_free_list[NR_GRANT_ENTRIES];
    3.58 +static grant_ref_t gnttab_free_head;
    3.59 +
    3.60 +static grant_entry_t *shared;
    3.61 +#if 0
    3.62 +/* /proc/xen/grant */
    3.63 +static struct proc_dir_entry *grant_pde;
    3.64 +#endif
    3.65 +
    3.66 +/*
    3.67 + * Lock-free grant-entry allocator
    3.68 + */
    3.69 +
    3.70 +static inline int
    3.71 +get_free_entry(void)
    3.72 +{
    3.73 +    grant_ref_t fh, nfh = gnttab_free_head;
    3.74 +    do { if ( unlikely((fh = nfh) == NR_GRANT_ENTRIES) ) return -1; }
    3.75 +    while ( unlikely((nfh = cmpxchg(&gnttab_free_head, fh,
    3.76 +                                    gnttab_free_list[fh])) != fh) );
    3.77 +    return fh;
    3.78 +}
    3.79 +
    3.80 +static inline void
    3.81 +put_free_entry(grant_ref_t ref)
    3.82 +{
    3.83 +    grant_ref_t fh, nfh = gnttab_free_head;
    3.84 +    do { gnttab_free_list[ref] = fh = nfh; wmb(); }
    3.85 +    while ( unlikely((nfh = cmpxchg(&gnttab_free_head, fh, ref)) != fh) );
    3.86 +}
    3.87 +
    3.88 +/*
    3.89 + * Public grant-issuing interface functions
    3.90 + */
    3.91 +
    3.92 +int
    3.93 +gnttab_grant_foreign_access(domid_t domid, unsigned long frame, int readonly)
    3.94 +{
    3.95 +    int ref;
    3.96 +    
    3.97 +    if ( unlikely((ref = get_free_entry()) == -1) )
    3.98 +        return -ENOSPC;
    3.99 +
   3.100 +    shared[ref].frame = frame;
   3.101 +    shared[ref].domid = domid;
   3.102 +    wmb();
   3.103 +    shared[ref].flags = GTF_permit_access | (readonly ? GTF_readonly : 0);
   3.104 +
   3.105 +    return ref;
   3.106 +}
   3.107 +
   3.108 +void
   3.109 +gnttab_grant_foreign_access_ref(grant_ref_t ref, domid_t domid, 
   3.110 +				unsigned long frame, int readonly)
   3.111 +{
   3.112 +    shared[ref].frame = frame;
   3.113 +    shared[ref].domid = domid;
   3.114 +    wmb();
   3.115 +    shared[ref].flags = GTF_permit_access | (readonly ? GTF_readonly : 0);
   3.116 +}
   3.117 +
   3.118 +
   3.119 +int
   3.120 +gnttab_query_foreign_access(grant_ref_t ref)
   3.121 +{
   3.122 +    uint16_t nflags;
   3.123 +
   3.124 +    nflags = shared[ref].flags;
   3.125 +
   3.126 +    return (nflags & (GTF_reading|GTF_writing));
   3.127 +}
   3.128 +
   3.129 +void
   3.130 +gnttab_end_foreign_access(grant_ref_t ref, int readonly)
   3.131 +{
   3.132 +    uint16_t flags, nflags;
   3.133 +
   3.134 +    nflags = shared[ref].flags;
   3.135 +    do {
   3.136 +        if ( (flags = nflags) & (GTF_reading|GTF_writing) )
   3.137 +            printk("WARNING: g.e. still in use!\n");
   3.138 +    }
   3.139 +    while ( (nflags = cmpxchg(&shared[ref].flags, flags, 0)) != flags );
   3.140 +
   3.141 +    put_free_entry(ref);
   3.142 +}
   3.143 +
   3.144 +int
   3.145 +gnttab_grant_foreign_transfer(domid_t domid, unsigned long pfn)
   3.146 +{
   3.147 +    int ref;
   3.148 +
   3.149 +    if ( unlikely((ref = get_free_entry()) == -1) )
   3.150 +        return -ENOSPC;
   3.151 +
   3.152 +    shared[ref].frame = pfn;
   3.153 +    shared[ref].domid = domid;
   3.154 +    wmb();
   3.155 +    shared[ref].flags = GTF_accept_transfer;
   3.156 +
   3.157 +    return ref;
   3.158 +}
   3.159 +
   3.160 +void
   3.161 +gnttab_grant_foreign_transfer_ref(grant_ref_t ref, domid_t domid, 
   3.162 +				  unsigned long pfn)
   3.163 +{
   3.164 +    shared[ref].frame = pfn;
   3.165 +    shared[ref].domid = domid;
   3.166 +    wmb();
   3.167 +    shared[ref].flags = GTF_accept_transfer;
   3.168 +}
   3.169 +
   3.170 +unsigned long
   3.171 +gnttab_end_foreign_transfer(grant_ref_t ref)
   3.172 +{
   3.173 +    unsigned long frame = 0;
   3.174 +    uint16_t           flags;
   3.175 +
   3.176 +    flags = shared[ref].flags;
   3.177 +    ASSERT(flags == (GTF_accept_transfer | GTF_transfer_committed));
   3.178 +
   3.179 +    /*
   3.180 +     * If a transfer is committed then wait for the frame address to appear.
   3.181 +     * Otherwise invalidate the grant entry against future use.
   3.182 +     */
   3.183 +    if ( likely(flags != GTF_accept_transfer) ||
   3.184 +         (cmpxchg(&shared[ref].flags, flags, 0) != GTF_accept_transfer) )
   3.185 +        while ( unlikely((frame = shared[ref].frame) == 0) )
   3.186 +            cpu_relax();
   3.187 +
   3.188 +    put_free_entry(ref);
   3.189 +
   3.190 +    return frame;
   3.191 +}
   3.192 +
   3.193 +void
   3.194 +gnttab_free_grant_references(uint16_t count, grant_ref_t head)
   3.195 +{
   3.196 +    /* TODO: O(N)...? */
   3.197 +    grant_ref_t to_die = 0, next = head;
   3.198 +    int i;
   3.199 +
   3.200 +    for ( i = 0; i < count; i++ )
   3.201 +        to_die = next;
   3.202 +        next = gnttab_free_list[next];
   3.203 +        put_free_entry( to_die );
   3.204 +}
   3.205 +
   3.206 +int
   3.207 +gnttab_alloc_grant_references(uint16_t count, grant_ref_t *head, 
   3.208 +			      grant_ref_t *terminal)
   3.209 +{
   3.210 +    int i;
   3.211 +    grant_ref_t h = gnttab_free_head;
   3.212 +
   3.213 +    for ( i = 0; i < count; i++ )
   3.214 +        if ( unlikely(get_free_entry() == -1) )
   3.215 +            goto not_enough_refs;
   3.216 +
   3.217 +    *head = h;
   3.218 +    *terminal = gnttab_free_head;
   3.219 +
   3.220 +    return 0;
   3.221 +
   3.222 +not_enough_refs:
   3.223 +    gnttab_free_head = h;
   3.224 +    return -ENOSPC;
   3.225 +}
   3.226 +
   3.227 +int
   3.228 +gnttab_claim_grant_reference(grant_ref_t *private_head, grant_ref_t  terminal )
   3.229 +{
   3.230 +    grant_ref_t g;
   3.231 +    if ( unlikely((g = *private_head) == terminal) )
   3.232 +        return -ENOSPC;
   3.233 +    *private_head = gnttab_free_list[g];
   3.234 +    return g;
   3.235 +}
   3.236 +
   3.237 +void
   3.238 +gnttab_release_grant_reference( grant_ref_t *private_head,
   3.239 +                                grant_ref_t  release )
   3.240 +{
   3.241 +    gnttab_free_list[release] = *private_head;
   3.242 +    *private_head = release;
   3.243 +}
   3.244 +#ifdef notyet
   3.245 +static int 
   3.246 +grant_ioctl(struct cdev *dev, u_long cmd, caddr_t data, 
   3.247 +	    int flag, struct thread *td)
   3.248 +{
   3.249 +
   3.250 +    int                     ret;
   3.251 +    privcmd_hypercall_t     hypercall;
   3.252 +
   3.253 +    /* XXX Need safety checks here if using for anything other
   3.254 +     *     than debugging */
   3.255 +    return -ENOSYS;
   3.256 +
   3.257 +    if ( cmd != IOCTL_PRIVCMD_HYPERCALL )
   3.258 +        return -ENOSYS;
   3.259 +
   3.260 +    if ( copy_from_user(&hypercall, (void *)data, sizeof(hypercall)) )
   3.261 +        return -EFAULT;
   3.262 +
   3.263 +    if ( hypercall.op != __HYPERVISOR_grant_table_op )
   3.264 +        return -ENOSYS;
   3.265 +
   3.266 +    /* hypercall-invoking asm taken from privcmd.c */
   3.267 +    __asm__ __volatile__ (
   3.268 +        "pushl %%ebx; pushl %%ecx; pushl %%edx; pushl %%esi; pushl %%edi; "
   3.269 +        "movl  4(%%eax),%%ebx ;"
   3.270 +        "movl  8(%%eax),%%ecx ;"
   3.271 +        "movl 12(%%eax),%%edx ;"
   3.272 +        "movl 16(%%eax),%%esi ;"
   3.273 +        "movl 20(%%eax),%%edi ;"
   3.274 +        "movl   (%%eax),%%eax ;"
   3.275 +        TRAP_INSTR "; "
   3.276 +        "popl %%edi; popl %%esi; popl %%edx; popl %%ecx; popl %%ebx"
   3.277 +        : "=a" (ret) : "0" (&hypercall) : "memory" );
   3.278 +
   3.279 +    return ret;
   3.280 +
   3.281 +}
   3.282 +
   3.283 +static struct cdevsw gnttab_cdevsw = {
   3.284 +    d_ioctl:  grant_ioctl,
   3.285 +};
   3.286 +
   3.287 +static int 
   3.288 +grant_read(char *page, char **start, off_t off,
   3.289 +	   int count, int *eof, void *data)
   3.290 +{
   3.291 +    int             len;
   3.292 +    unsigned int    i;
   3.293 +    grant_entry_t  *gt;
   3.294 +
   3.295 +    gt = (grant_entry_t *)shared;
   3.296 +    len = 0;
   3.297 +
   3.298 +    for ( i = 0; i < NR_GRANT_ENTRIES; i++ )
   3.299 +        /* TODO: safety catch here until this can handle >PAGE_SIZE output */
   3.300 +        if (len > (PAGE_SIZE - 200))
   3.301 +        {
   3.302 +            len += sprintf( page + len, "Truncated.\n");
   3.303 +            break;
   3.304 +        }
   3.305 +
   3.306 +        if ( gt[i].flags )
   3.307 +            len += sprintf( page + len,
   3.308 +                    "Grant: ref (0x%x) flags (0x%hx) dom (0x%hx) frame (0x%x)\n", 
   3.309 +                    i,
   3.310 +                    gt[i].flags,
   3.311 +                    gt[i].domid,
   3.312 +                    gt[i].frame );
   3.313 +
   3.314 +    *eof = 1;
   3.315 +    return len;
   3.316 +}
   3.317 +
   3.318 +static int 
   3.319 +grant_write(struct file *file, const char __user *buffer,
   3.320 +	    unsigned long count, void *data)
   3.321 +{
   3.322 +    /* TODO: implement this */
   3.323 +    return -ENOSYS;
   3.324 +}
   3.325 +#endif
   3.326 +static int 
   3.327 +gnttab_init(void *unused)
   3.328 +{
   3.329 +    gnttab_setup_table_t setup;
   3.330 +    unsigned long        frames[NR_GRANT_FRAMES];
   3.331 +    int                  i;
   3.332 +
   3.333 +    setup.dom        = DOMID_SELF;
   3.334 +    setup.nr_frames  = NR_GRANT_FRAMES;
   3.335 +    setup.frame_list = frames;
   3.336 +
   3.337 +    if (HYPERVISOR_grant_table_op(GNTTABOP_setup_table, &setup, 1) != 0)
   3.338 +        panic("grant table setup failed\n");
   3.339 +    if (setup.status != 0)
   3.340 +        panic("non-zero status in grant table setup\n");
   3.341 +    shared = (grant_entry_t *)kmem_alloc_nofault(kernel_map, NR_GRANT_FRAMES);
   3.342 +
   3.343 +    for (i = 0; i < NR_GRANT_FRAMES; i++) 
   3.344 +	pmap_kenter_ma((vm_offset_t)(shared + (i*PAGE_SIZE)), frames[i] << PAGE_SHIFT);
   3.345 +
   3.346 +    for ( i = 0; i < NR_GRANT_ENTRIES; i++ )
   3.347 +        gnttab_free_list[i] = i + 1;
   3.348 +#if 0
   3.349 +    /*
   3.350 +     *  /proc/xen/grant : used by libxc to access grant tables
   3.351 +     */
   3.352 +    if ( (grant_pde = create_xen_proc_entry("grant", 0600)) == NULL )
   3.353 +    {
   3.354 +        WPRINTK("Unable to create grant xen proc entry\n");
   3.355 +        return -1;
   3.356 +    }
   3.357 +
   3.358 +    grant_file_ops.read   = grant_pde->proc_fops->read;
   3.359 +    grant_file_ops.write  = grant_pde->proc_fops->write;
   3.360 +
   3.361 +    grant_pde->proc_fops  = &grant_file_ops;
   3.362 +
   3.363 +    grant_pde->read_proc  = &grant_read;
   3.364 +    grant_pde->write_proc = &grant_write;
   3.365 +#endif
   3.366 +    printk("Grant table initialized\n");
   3.367 +    return 0;
   3.368 +}
   3.369 +
   3.370 +SYSINIT(gnttab, SI_SUB_PSEUDO, SI_ORDER_FIRST, gnttab_init, NULL);
     4.1 --- a/freebsd-5.3-xen-sparse/i386-xen/i386-xen/machdep.c	Wed Apr 20 10:36:34 2005 +0000
     4.2 +++ b/freebsd-5.3-xen-sparse/i386-xen/i386-xen/machdep.c	Wed Apr 20 10:39:58 2005 +0000
     4.3 @@ -1387,6 +1387,7 @@ initvalues(start_info_t *startinfo)
     4.4  { 
     4.5      int i;
     4.6  #ifdef WRITABLE_PAGETABLES
     4.7 +    XENPRINTF("using writable pagetables\n");
     4.8      HYPERVISOR_vm_assist(VMASST_CMD_enable, VMASST_TYPE_writable_pagetables);
     4.9  #endif
    4.10  
    4.11 @@ -1457,7 +1458,7 @@ initvalues(start_info_t *startinfo)
    4.12  
    4.13      /* allocate remainder of NKPT pages */
    4.14      for (i = 0; i < NKPT-1; i++, tmpindex++)
    4.15 -	PT_SET_VA(((unsigned long *)startinfo->pt_base) + KPTDI + i + 1, (tmpindex << PAGE_SHIFT)| PG_M | PG_RW | PG_V | PG_A, TRUE);
    4.16 +	PD_SET_VA(((unsigned long *)startinfo->pt_base) + KPTDI + i + 1, (tmpindex << PAGE_SHIFT)| PG_M | PG_RW | PG_V | PG_A, TRUE);
    4.17      tmpindex += NKPT-1;
    4.18      PT_UPDATES_FLUSH();
    4.19  
     5.1 --- a/freebsd-5.3-xen-sparse/i386-xen/i386-xen/pmap.c	Wed Apr 20 10:36:34 2005 +0000
     5.2 +++ b/freebsd-5.3-xen-sparse/i386-xen/i386-xen/pmap.c	Wed Apr 20 10:39:58 2005 +0000
     5.3 @@ -381,9 +381,10 @@ pmap_bootstrap(firstaddr, loadaddr)
     5.4  	 * CMAP1/CMAP2 are used for zeroing and copying pages.
     5.5  	 * CMAP3 is used for the idle process page zeroing.
     5.6  	 */
     5.7 -	SYSMAP(caddr_t, CMAP1, CADDR1, 1)
     5.8 -	SYSMAP(caddr_t, CMAP2, CADDR2, 1)
     5.9 -	SYSMAP(caddr_t, CMAP3, CADDR3, 1)
    5.10 +	SYSMAP(caddr_t, CMAP1, CADDR1, 1);
    5.11 +	SYSMAP(caddr_t, CMAP2, CADDR2, 1);
    5.12 +	SYSMAP(caddr_t, CMAP3, CADDR3, 1);
    5.13 +
    5.14  	PT_CLEAR_VA(CMAP3, TRUE);
    5.15  
    5.16  	mtx_init(&CMAPCADDR12_lock, "CMAPCADDR12", NULL, MTX_DEF);
    5.17 @@ -416,7 +417,7 @@ pmap_bootstrap(firstaddr, loadaddr)
    5.18  	PT_CLEAR_VA(CMAP2, FALSE);
    5.19  
    5.20  	for (i = 0; i < NKPT; i++)
    5.21 -		PT_CLEAR_VA(&PTD[i], FALSE);
    5.22 +		PD_CLEAR_VA(&PTD[i], FALSE);
    5.23  	PT_UPDATES_FLUSH();
    5.24  #ifdef XEN_UNNEEDED
    5.25  	/* Turn on PG_G on kernel page(s) */
    5.26 @@ -962,6 +963,19 @@ pmap_kenter(vm_offset_t va, vm_paddr_t p
    5.27  }
    5.28  
    5.29  /*
    5.30 + * Add a wired page to the kva.
    5.31 + * Note: not SMP coherent.
    5.32 + */
    5.33 +PMAP_INLINE void 
    5.34 +pmap_kenter_ma(vm_offset_t va, vm_paddr_t ma)
    5.35 +{
    5.36 +	pt_entry_t *pte;
    5.37 +
    5.38 +	pte = vtopte(va);
    5.39 +	PT_SET_VA_MA(pte, ma | PG_RW | PG_V | pgeflag, TRUE);
    5.40 +}
    5.41 +
    5.42 +/*
    5.43   * Remove a page from the kernel pagetables.
    5.44   * Note: not SMP coherent.
    5.45   */
     6.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.2 +++ b/freebsd-5.3-xen-sparse/i386-xen/include/gnttab.h	Wed Apr 20 10:39:58 2005 +0000
     6.3 @@ -0,0 +1,71 @@
     6.4 +/******************************************************************************
     6.5 + * gnttab.h
     6.6 + * 
     6.7 + * Two sets of functionality:
     6.8 + * 1. Granting foreign access to our memory reservation.
     6.9 + * 2. Accessing others' memory reservations via grant references.
    6.10 + * (i.e., mechanisms for both sender and recipient of grant references)
    6.11 + * 
    6.12 + * Copyright (c) 2004, K A Fraser
    6.13 + * Copyright (c) 2005, Christopher Clark
    6.14 + */
    6.15 +
    6.16 +#ifndef __ASM_GNTTAB_H__
    6.17 +#define __ASM_GNTTAB_H__
    6.18 +
    6.19 +#include <machine/hypervisor.h>
    6.20 +#include <machine/hypervisor-ifs.h>
    6.21 +
    6.22 +/* NR_GRANT_FRAMES must be less than or equal to that configured in Xen */
    6.23 +#define NR_GRANT_FRAMES 4
    6.24 +#define NR_GRANT_ENTRIES (NR_GRANT_FRAMES * PAGE_SIZE / sizeof(grant_entry_t))
    6.25 +
    6.26 +int
    6.27 +gnttab_grant_foreign_access(
    6.28 +    domid_t domid, unsigned long frame, int readonly);
    6.29 +
    6.30 +void
    6.31 +gnttab_end_foreign_access(
    6.32 +    grant_ref_t ref, int readonly);
    6.33 +
    6.34 +int
    6.35 +gnttab_grant_foreign_transfer(
    6.36 +    domid_t domid, unsigned long pfn);
    6.37 +
    6.38 +unsigned long
    6.39 +gnttab_end_foreign_transfer(
    6.40 +    grant_ref_t ref);
    6.41 +
    6.42 +int
    6.43 +gnttab_query_foreign_access( 
    6.44 +    grant_ref_t ref );
    6.45 +
    6.46 +/*
    6.47 + * operations on reserved batches of grant references
    6.48 + */
    6.49 +int
    6.50 +gnttab_alloc_grant_references(
    6.51 +    uint16_t count, grant_ref_t *pprivate_head, grant_ref_t *private_terminal );
    6.52 +
    6.53 +void
    6.54 +gnttab_free_grant_references(
    6.55 +    uint16_t count, grant_ref_t private_head );
    6.56 +
    6.57 +int
    6.58 +gnttab_claim_grant_reference( grant_ref_t *pprivate_head, grant_ref_t terminal
    6.59 +);
    6.60 +
    6.61 +void
    6.62 +gnttab_release_grant_reference(
    6.63 +    grant_ref_t *private_head, grant_ref_t release );
    6.64 +
    6.65 +void
    6.66 +gnttab_grant_foreign_access_ref(
    6.67 +    grant_ref_t ref, domid_t domid, unsigned long frame, int readonly);
    6.68 +
    6.69 +void
    6.70 +gnttab_grant_foreign_transfer_ref(
    6.71 +    grant_ref_t, domid_t domid, unsigned long pfn);
    6.72 +
    6.73 +
    6.74 +#endif /* __ASM_GNTTAB_H__ */
     7.1 --- a/freebsd-5.3-xen-sparse/i386-xen/include/hypervisor-ifs.h	Wed Apr 20 10:36:34 2005 +0000
     7.2 +++ b/freebsd-5.3-xen-sparse/i386-xen/include/hypervisor-ifs.h	Wed Apr 20 10:39:58 2005 +0000
     7.3 @@ -11,6 +11,7 @@
     7.4  #define u32 uint32_t
     7.5  #define u64 uint64_t
     7.6  
     7.7 +#define CONFIG_XEN_BLKDEV_GRANT
     7.8  #include <machine/xen-public/xen.h>
     7.9  #include <machine/xen-public/io/domain_controller.h>
    7.10  #include <machine/xen-public/io/netif.h>
    7.11 @@ -19,6 +20,7 @@
    7.12  #include <machine/xen-public/event_channel.h>
    7.13  #include <machine/xen-public/sched_ctl.h>
    7.14  #include <machine/xen-public/physdev.h>
    7.15 +#include <machine/xen-public/grant_table.h>
    7.16  #undef  blkif_sector_t			/* XXX pre-processor didn't do the */
    7.17  #define blkif_sector_t uint64_t		/* right thing */
    7.18  
     8.1 --- a/freebsd-5.3-xen-sparse/i386-xen/include/hypervisor.h	Wed Apr 20 10:36:34 2005 +0000
     8.2 +++ b/freebsd-5.3-xen-sparse/i386-xen/include/hypervisor.h	Wed Apr 20 10:39:58 2005 +0000
     8.3 @@ -38,7 +38,8 @@ typedef struct { unsigned long pte_low, 
     8.4   * Assembler stubs for hyper-calls.
     8.5   */
     8.6  
     8.7 -static inline int HYPERVISOR_set_trap_table(trap_info_t *table)
     8.8 +static inline int 
     8.9 +HYPERVISOR_set_trap_table(trap_info_t *table)
    8.10  {
    8.11      int ret;
    8.12      __asm__ __volatile__ (
    8.13 @@ -83,7 +84,8 @@ HYPERVISOR_mmuext_op(
    8.14  
    8.15  
    8.16  
    8.17 -static inline int HYPERVISOR_set_gdt(unsigned long *frame_list, int entries)
    8.18 +static inline int 
    8.19 +HYPERVISOR_set_gdt(unsigned long *frame_list, int entries)
    8.20  {
    8.21      int ret;
    8.22      __asm__ __volatile__ (
    8.23 @@ -95,7 +97,8 @@ static inline int HYPERVISOR_set_gdt(uns
    8.24      return ret;
    8.25  }
    8.26  
    8.27 -static inline int HYPERVISOR_stack_switch(unsigned long ss, unsigned long esp)
    8.28 +static inline int 
    8.29 +HYPERVISOR_stack_switch(unsigned long ss, unsigned long esp)
    8.30  {
    8.31      int ret;
    8.32      __asm__ __volatile__ (
    8.33 @@ -106,7 +109,8 @@ static inline int HYPERVISOR_stack_switc
    8.34      return ret;
    8.35  }
    8.36  
    8.37 -static inline int HYPERVISOR_set_callbacks(
    8.38 +static inline int 
    8.39 +HYPERVISOR_set_callbacks(
    8.40      unsigned long event_selector, unsigned long event_address,
    8.41      unsigned long failsafe_selector, unsigned long failsafe_address)
    8.42  {
    8.43 @@ -120,7 +124,8 @@ static inline int HYPERVISOR_set_callbac
    8.44      return ret;
    8.45  }
    8.46  
    8.47 -static inline int HYPERVISOR_fpu_taskswitch(void)
    8.48 +static inline int 
    8.49 +HYPERVISOR_fpu_taskswitch(void)
    8.50  {
    8.51      int ret;
    8.52      __asm__ __volatile__ (
    8.53 @@ -130,7 +135,8 @@ static inline int HYPERVISOR_fpu_taskswi
    8.54      return ret;
    8.55  }
    8.56  
    8.57 -static inline int HYPERVISOR_yield(void)
    8.58 +static inline int 
    8.59 +HYPERVISOR_yield(void)
    8.60  {
    8.61      int ret;
    8.62      __asm__ __volatile__ (
    8.63 @@ -141,7 +147,8 @@ static inline int HYPERVISOR_yield(void)
    8.64      return ret;
    8.65  }
    8.66  
    8.67 -static inline int HYPERVISOR_block(void)
    8.68 +static inline int 
    8.69 +HYPERVISOR_block(void)
    8.70  {
    8.71      int ret;
    8.72      __asm__ __volatile__ (
    8.73 @@ -152,7 +159,8 @@ static inline int HYPERVISOR_block(void)
    8.74      return ret;
    8.75  }
    8.76  
    8.77 -static inline int HYPERVISOR_shutdown(void)
    8.78 +static inline int 
    8.79 +HYPERVISOR_shutdown(void)
    8.80  {
    8.81      int ret;
    8.82      __asm__ __volatile__ (
    8.83 @@ -164,7 +172,8 @@ static inline int HYPERVISOR_shutdown(vo
    8.84      return ret;
    8.85  }
    8.86  
    8.87 -static inline int HYPERVISOR_reboot(void)
    8.88 +static inline int 
    8.89 +HYPERVISOR_reboot(void)
    8.90  {
    8.91      int ret;
    8.92      __asm__ __volatile__ (
    8.93 @@ -176,7 +185,8 @@ static inline int HYPERVISOR_reboot(void
    8.94      return ret;
    8.95  }
    8.96  
    8.97 -static inline int HYPERVISOR_suspend(unsigned long srec)
    8.98 +static inline int 
    8.99 +HYPERVISOR_suspend(unsigned long srec)
   8.100  {
   8.101      int ret;
   8.102      /* NB. On suspend, control software expects a suspend record in %esi. */
   8.103 @@ -189,7 +199,8 @@ static inline int HYPERVISOR_suspend(uns
   8.104      return ret;
   8.105  }
   8.106  
   8.107 -static inline long HYPERVISOR_set_timer_op(uint64_t timeout)
   8.108 +static inline long 
   8.109 +HYPERVISOR_set_timer_op(uint64_t timeout)
   8.110  {
   8.111      int ret;
   8.112      unsigned long timeout_hi = (unsigned long)(timeout>>32);
   8.113 @@ -202,7 +213,8 @@ static inline long HYPERVISOR_set_timer_
   8.114      return ret;
   8.115  }
   8.116  
   8.117 -static inline int HYPERVISOR_dom0_op(dom0_op_t *dom0_op)
   8.118 +static inline int 
   8.119 +HYPERVISOR_dom0_op(dom0_op_t *dom0_op)
   8.120  {
   8.121      int ret;
   8.122      dom0_op->interface_version = DOM0_INTERFACE_VERSION;
   8.123 @@ -214,7 +226,8 @@ static inline int HYPERVISOR_dom0_op(dom
   8.124      return ret;
   8.125  }
   8.126  
   8.127 -static inline int HYPERVISOR_set_debugreg(int reg, unsigned long value)
   8.128 +static inline int 
   8.129 +HYPERVISOR_set_debugreg(int reg, unsigned long value)
   8.130  {
   8.131      int ret;
   8.132      __asm__ __volatile__ (
   8.133 @@ -225,7 +238,8 @@ static inline int HYPERVISOR_set_debugre
   8.134      return ret;
   8.135  }
   8.136  
   8.137 -static inline unsigned long HYPERVISOR_get_debugreg(int reg)
   8.138 +static inline unsigned long 
   8.139 +HYPERVISOR_get_debugreg(int reg)
   8.140  {
   8.141      unsigned long ret;
   8.142      __asm__ __volatile__ (
   8.143 @@ -236,7 +250,8 @@ static inline unsigned long HYPERVISOR_g
   8.144      return ret;
   8.145  }
   8.146  
   8.147 -static inline int HYPERVISOR_update_descriptor(
   8.148 +static inline int 
   8.149 +HYPERVISOR_update_descriptor(
   8.150      unsigned long pa, unsigned long word1, unsigned long word2)
   8.151  {
   8.152      int ret;
   8.153 @@ -248,7 +263,8 @@ static inline int HYPERVISOR_update_desc
   8.154      return ret;
   8.155  }
   8.156  
   8.157 -static inline int HYPERVISOR_set_fast_trap(int idx)
   8.158 +static inline int 
   8.159 +HYPERVISOR_set_fast_trap(int idx)
   8.160  {
   8.161      int ret;
   8.162      __asm__ __volatile__ (
   8.163 @@ -259,9 +275,10 @@ static inline int HYPERVISOR_set_fast_tr
   8.164      return ret;
   8.165  }
   8.166  
   8.167 -static inline int HYPERVISOR_dom_mem_op(unsigned int   op,
   8.168 -					unsigned long *pages,
   8.169 -					unsigned long  nr_pages)
   8.170 +static inline int 
   8.171 +HYPERVISOR_dom_mem_op(unsigned int   op,
   8.172 +		      unsigned long *pages,
   8.173 +		      unsigned long  nr_pages)
   8.174  {
   8.175      int ret;
   8.176      __asm__ __volatile__ (
   8.177 @@ -271,7 +288,8 @@ static inline int HYPERVISOR_dom_mem_op(
   8.178      return ret;
   8.179  }
   8.180  
   8.181 -static inline int HYPERVISOR_multicall(void *call_list, int nr_calls)
   8.182 +static inline int 
   8.183 +HYPERVISOR_multicall(void *call_list, int nr_calls)
   8.184  {
   8.185      int ret;
   8.186      __asm__ __volatile__ (
   8.187 @@ -282,7 +300,8 @@ static inline int HYPERVISOR_multicall(v
   8.188      return ret;
   8.189  }
   8.190  
   8.191 -static inline int HYPERVISOR_update_va_mapping(
   8.192 +static inline int 
   8.193 +HYPERVISOR_update_va_mapping(
   8.194      unsigned long page_nr, unsigned long new_val, unsigned long flags)
   8.195  {
   8.196      int ret;
   8.197 @@ -300,7 +319,8 @@ static inline int HYPERVISOR_update_va_m
   8.198      return ret;
   8.199  }
   8.200  
   8.201 -static inline int HYPERVISOR_event_channel_op(void *op)
   8.202 +static inline int 
   8.203 +HYPERVISOR_event_channel_op(void *op)
   8.204  {
   8.205      int ret;
   8.206      __asm__ __volatile__ (
   8.207 @@ -311,7 +331,8 @@ static inline int HYPERVISOR_event_chann
   8.208      return ret;
   8.209  }
   8.210  
   8.211 -static inline int HYPERVISOR_xen_version(int cmd)
   8.212 +static inline int 
   8.213 +HYPERVISOR_xen_version(int cmd)
   8.214  {
   8.215      int ret;
   8.216      __asm__ __volatile__ (
   8.217 @@ -322,7 +343,8 @@ static inline int HYPERVISOR_xen_version
   8.218      return ret;
   8.219  }
   8.220  
   8.221 -static inline int HYPERVISOR_console_io(int cmd, int count, char *str)
   8.222 +static inline int 
   8.223 +HYPERVISOR_console_io(int cmd, int count, char *str)
   8.224  {
   8.225      int ret;
   8.226      __asm__ __volatile__ (
   8.227 @@ -333,36 +355,62 @@ static inline int HYPERVISOR_console_io(
   8.228      return ret;
   8.229  }
   8.230  
   8.231 -static __inline int HYPERVISOR_console_write(char *str, int count)
   8.232 +static inline int 
   8.233 +HYPERVISOR_console_write(char *str, int count)
   8.234  {
   8.235      return HYPERVISOR_console_io(CONSOLEIO_write, count, str); 
   8.236  }
   8.237  
   8.238 -static inline int HYPERVISOR_physdev_op(void *physdev_op)
   8.239 +static inline int 
   8.240 +HYPERVISOR_physdev_op(void *physdev_op)
   8.241  {
   8.242      int ret;
   8.243 +    unsigned long ign;
   8.244 +
   8.245      __asm__ __volatile__ (
   8.246          TRAP_INSTR
   8.247 -        : "=a" (ret) : "0" (__HYPERVISOR_physdev_op),
   8.248 -        "b" (physdev_op) : "memory" );
   8.249 +        : "=a" (ret), "=b" (ign) 
   8.250 +        : "0" (__HYPERVISOR_physdev_op), "1" (physdev_op) 
   8.251 +	: "memory" );
   8.252  
   8.253      return ret;
   8.254  }
   8.255  
   8.256 -static inline int HYPERVISOR_update_va_mapping_otherdomain(
   8.257 -    unsigned long page_nr, pte_t new_val, unsigned long flags, domid_t domid)
   8.258 +static inline int
   8.259 +HYPERVISOR_grant_table_op(
   8.260 +    unsigned int cmd, void *uop, unsigned int count)
   8.261  {
   8.262      int ret;
   8.263 +    unsigned long ign1, ign2, ign3;
   8.264 +
   8.265      __asm__ __volatile__ (
   8.266          TRAP_INSTR
   8.267 -        : "=a" (ret) : "0" (__HYPERVISOR_update_va_mapping_otherdomain), 
   8.268 -        "b" (page_nr), "c" ((new_val).pte_low), "d" (flags), "S" (domid) :
   8.269 +        : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3)
   8.270 +        : "0" (__HYPERVISOR_grant_table_op), "1" (cmd), "2" (uop), "3" (count)
   8.271 +        : "memory" );
   8.272 +
   8.273 +    return ret;
   8.274 +}
   8.275 +
   8.276 +static inline int 
   8.277 +HYPERVISOR_update_va_mapping_otherdomain(
   8.278 +    unsigned long va, pte_t new_val, unsigned long flags, domid_t domid)
   8.279 +{
   8.280 +    int ret;
   8.281 +    unsigned long ign1, ign2, ign3, ign4;
   8.282 +	
   8.283 +    __asm__ __volatile__ (
   8.284 +        TRAP_INSTR
   8.285 +        : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3), "=S" (ign4)
   8.286 +        : "0" (__HYPERVISOR_update_va_mapping_otherdomain),
   8.287 +          "1" (va), "2" ((new_val).pte_low), "3" (flags), "4" (domid) :
   8.288          "memory" );
   8.289 -    
   8.290 +
   8.291      return ret;
   8.292  } 
   8.293  
   8.294 -static inline int HYPERVISOR_vm_assist(unsigned int cmd, unsigned int type)
   8.295 +static inline int 
   8.296 +HYPERVISOR_vm_assist(unsigned int cmd, unsigned int type)
   8.297  {
   8.298      int ret;
   8.299      __asm__ __volatile__ (
     9.1 --- a/freebsd-5.3-xen-sparse/i386-xen/include/xenpmap.h	Wed Apr 20 10:36:34 2005 +0000
     9.2 +++ b/freebsd-5.3-xen-sparse/i386-xen/include/xenpmap.h	Wed Apr 20 10:39:58 2005 +0000
     9.3 @@ -60,6 +60,14 @@ void pmap_ref(pt_entry_t *pte, unsigned 
     9.4  #endif
     9.5  
     9.6  #define ALWAYS_SYNC 0
     9.7 +#define PT_DEBUG
     9.8 +
     9.9 +#ifdef PT_DEBUG
    9.10 +#define PT_LOG() printk("WP PT_SET %s:%d\n", __FILE__, __LINE__) 
    9.11 +#else
    9.12 +#define PT_LOG()
    9.13 +#endif
    9.14 +
    9.15  #define pmap_valid_entry(E)           ((E) & PG_V) /* is PDE or PTE valid? */
    9.16  
    9.17  #define	PT_GET(_ptp)						\
    9.18 @@ -68,15 +76,18 @@ void pmap_ref(pt_entry_t *pte, unsigned 
    9.19  #ifdef WRITABLE_PAGETABLES
    9.20  #define PT_SET_VA(_ptp,_npte,sync) do {				\
    9.21          PMAP_REF((_ptp), xpmap_ptom(_npte));                    \
    9.22 -        *(_ptp) = xpmap_ptom((_npte));                            \
    9.23 +        PT_LOG();                                               \
    9.24 +        *(_ptp) = xpmap_ptom((_npte));                          \
    9.25  } while (/*CONSTCOND*/0)
    9.26 -#define PT_SET_VA_MA(_ptp,_npte,sync) do {		    \
    9.27 +#define PT_SET_VA_MA(_ptp,_npte,sync) do {		        \
    9.28          PMAP_REF((_ptp), (_npte));                              \
    9.29 -        *(_ptp) = (_npte);                                          \
    9.30 +        PT_LOG();                                               \
    9.31 +        *(_ptp) = (_npte);                                      \
    9.32  } while (/*CONSTCOND*/0)
    9.33  #define PT_CLEAR_VA(_ptp, sync) do {				\
    9.34          PMAP_REF((pt_entry_t *)(_ptp), 0);                      \
    9.35 -        *(_ptp) = 0;                                              \
    9.36 +        PT_LOG();                                               \
    9.37 +        *(_ptp) = 0;                                            \
    9.38  } while (/*CONSTCOND*/0)
    9.39  
    9.40  #define PD_SET_VA(_ptp,_npte,sync) do {				\
    9.41 @@ -85,7 +96,7 @@ void pmap_ref(pt_entry_t *pte, unsigned 
    9.42  			    xpmap_ptom((_npte))); 		\
    9.43  	if (sync || ALWAYS_SYNC) xen_flush_queue();     	\
    9.44  } while (/*CONSTCOND*/0)
    9.45 -#define PD_SET_VA_MA(_ptp,_npte,sync) do {		    \
    9.46 +#define PD_SET_VA_MA(_ptp,_npte,sync) do {		        \
    9.47          PMAP_REF((_ptp), (_npte));                              \
    9.48  	xen_queue_pt_update((pt_entry_t *)vtomach((_ptp)), (_npte)); \
    9.49  	if (sync || ALWAYS_SYNC) xen_flush_queue();		\
    9.50 @@ -105,9 +116,9 @@ void pmap_ref(pt_entry_t *pte, unsigned 
    9.51  			    xpmap_ptom(_npte)); 		\
    9.52  	if (sync || ALWAYS_SYNC) xen_flush_queue();		\
    9.53  } while (/*CONSTCOND*/0)
    9.54 -#define PT_SET_VA_MA(_ptp,_npte,sync) do {		    \
    9.55 +#define PT_SET_VA_MA(_ptp,_npte,sync) do {		        \
    9.56          PMAP_REF((_ptp), (_npte));                              \
    9.57 -	xen_queue_pt_update((pt_entry_t *)vtomach(_ptp), _npte); \
    9.58 +	xen_queue_pt_update((pt_entry_t *)vtomach(_ptp), _npte);\
    9.59  	if (sync || ALWAYS_SYNC) xen_flush_queue();		\
    9.60  } while (/*CONSTCOND*/0)
    9.61  #define PT_CLEAR_VA(_ptp, sync) do {				\
    10.1 --- a/freebsd-5.3-xen-sparse/i386-xen/xen/blkfront/xb_blkfront.c	Wed Apr 20 10:36:34 2005 +0000
    10.2 +++ b/freebsd-5.3-xen-sparse/i386-xen/xen/blkfront/xb_blkfront.c	Wed Apr 20 10:39:58 2005 +0000
    10.3 @@ -46,12 +46,19 @@
    10.4  #include <machine/ctrl_if.h>
    10.5  #include <machine/xenfunc.h>
    10.6  
    10.7 +
    10.8 +
    10.9 +#ifdef CONFIG_XEN_BLKDEV_GRANT
   10.10 +#include <machine/gnttab.h>
   10.11 +#endif
   10.12 +
   10.13  /* prototypes */
   10.14  struct xb_softc;
   10.15  static void xb_startio(struct xb_softc *sc);
   10.16  static void xb_vbdinit(void);
   10.17  static void blkif_control_send(blkif_request_t *req, blkif_response_t *rsp);
   10.18  static void blkif_ctrlif_rx(ctrl_msg_t *msg, unsigned long id);
   10.19 +static void blkif_control_probe_send(blkif_request_t *req, blkif_response_t *rsp, unsigned long address);
   10.20  
   10.21  struct xb_softc {
   10.22      device_t		  xb_dev;
   10.23 @@ -104,6 +111,14 @@ static blkif_front_ring_t   blk_ring;
   10.24  
   10.25  #define BLK_RING_SIZE __RING_SIZE((blkif_sring_t *)0, PAGE_SIZE)
   10.26  
   10.27 +#ifdef CONFIG_XEN_BLKDEV_GRANT
   10.28 +static domid_t rdomid = 0;
   10.29 +static grant_ref_t gref_head, gref_terminal;
   10.30 +#define MAXIMUM_OUTSTANDING_BLOCK_REQS \
   10.31 +    (BLKIF_MAX_SEGMENTS_PER_REQUEST * BLKIF_RING_SIZE)
   10.32 +#endif
   10.33 +
   10.34 +
   10.35  static unsigned long rec_ring_free;		
   10.36  blkif_request_t rec_ring[BLK_RING_SIZE];
   10.37  
   10.38 @@ -151,8 +166,9 @@ ADD_ID_TO_FREELIST( unsigned long id )
   10.39      rec_ring_free = id;
   10.40  }
   10.41  
   10.42 -static inline void translate_req_to_pfn(blkif_request_t *xreq,
   10.43 -                                        blkif_request_t *req)
   10.44 +static inline void 
   10.45 +translate_req_to_pfn(blkif_request_t *xreq,
   10.46 +		     blkif_request_t *req)
   10.47  {
   10.48      int i;
   10.49  
   10.50 @@ -163,7 +179,11 @@ static inline void translate_req_to_pfn(
   10.51      xreq->sector_number = req->sector_number;
   10.52  
   10.53      for ( i = 0; i < req->nr_segments; i++ ){
   10.54 +#ifdef CONFIG_XEN_BLKDEV_GRANT
   10.55 +        xreq->frame_and_sects[i] = req->frame_and_sects[i];
   10.56 +#else
   10.57          xreq->frame_and_sects[i] = xpmap_mtop(req->frame_and_sects[i]);
   10.58 +#endif
   10.59      }
   10.60  }
   10.61  
   10.62 @@ -179,7 +199,11 @@ static inline void translate_req_to_mfn(
   10.63      xreq->sector_number = req->sector_number;
   10.64  
   10.65      for ( i = 0; i < req->nr_segments; i++ ){
   10.66 +#ifdef CONFIG_XEN_BLKDEV_GRANT
   10.67 +        xreq->frame_and_sects[i] = req->frame_and_sects[i];
   10.68 +#else
   10.69          xreq->frame_and_sects[i] = xpmap_ptom(req->frame_and_sects[i]);
   10.70 +#endif
   10.71      }
   10.72  }
   10.73  
   10.74 @@ -340,6 +364,9 @@ xb_startio(struct xb_softc *sc)
   10.75      int			s, queued = 0;
   10.76      unsigned long id;
   10.77      unsigned int fsect, lsect;
   10.78 +#ifdef CONFIG_XEN_BLKDEV_GRANT
   10.79 +    int ref;
   10.80 +#endif
   10.81  
   10.82      
   10.83      if (unlikely(blkif_state != BLKIF_STATE_CONNECTED))
   10.84 @@ -396,12 +423,26 @@ xb_startio(struct xb_softc *sc)
   10.85      	req->nr_segments  = 1;	/* not doing scatter/gather since buffer
   10.86      				 * chaining is not supported.
   10.87  				 */
   10.88 +#ifdef CONFIG_XEN_BLKDEV_GRANT
   10.89 +            /* install a grant reference. */
   10.90 +            ref = gnttab_claim_grant_reference(&gref_head, gref_terminal);
   10.91 +            KASSERT( ref != -ENOSPC, ("grant_reference failed") );
   10.92 +
   10.93 +            gnttab_grant_foreign_access_ref(
   10.94 +                        ref,
   10.95 +                        rdomid,
   10.96 +                        buffer_ma >> PAGE_SHIFT,
   10.97 +                        req->operation & 1 ); /* ??? */
   10.98 +
   10.99 +            req->frame_and_sects[0] =
  10.100 +                (((uint32_t) ref) << 16) | (fsect << 3) | lsect;
  10.101 +#else
  10.102  	/*
  10.103  	 * upper bits represent the machine address of the buffer and the
  10.104  	 * lower bits is the number of sectors to be read/written.
  10.105  	 */
  10.106  	req->frame_and_sects[0] = buffer_ma | (fsect << 3) | lsect; 
  10.107 -
  10.108 +#endif
  10.109  	/* Keep a private copy so we can reissue requests when recovering. */
  10.110  	translate_req_to_pfn( &rec_ring[id], req);
  10.111  
  10.112 @@ -503,9 +544,14 @@ xb_vbdinit(void)
  10.113      memset(&req, 0, sizeof(req)); 
  10.114      req.operation = BLKIF_OP_PROBE;
  10.115      req.nr_segments = 1;
  10.116 +#ifdef CONFIG_XEN_BLKDEV_GRANT
  10.117 +    blkif_control_probe_send(&req, &rsp,
  10.118 +                             (unsigned long)(vtomach(buf)));
  10.119 +    
  10.120 +#else
  10.121      req.frame_and_sects[0] = vtomach(buf) | 7;
  10.122      blkif_control_send(&req, &rsp);
  10.123 -    
  10.124 +#endif
  10.125      if ( rsp.status <= 0 ) {
  10.126          printk("xb_identify: Could not identify disks (%d)\n", rsp.status);
  10.127      	free(buf, M_DEVBUF);
  10.128 @@ -526,6 +572,22 @@ xb_vbdinit(void)
  10.129  
  10.130  /*****************************  COMMON CODE  *******************************/
  10.131  
  10.132 +#ifdef CONFIG_XEN_BLKDEV_GRANT
  10.133 +static void 
  10.134 +blkif_control_probe_send(blkif_request_t *req, blkif_response_t *rsp,
  10.135 +                              unsigned long address)
  10.136 +{
  10.137 +    int ref = gnttab_claim_grant_reference(&gref_head, gref_terminal);
  10.138 +    KASSERT( ref != -ENOSPC, ("couldn't get grant reference") );
  10.139 +
  10.140 +    gnttab_grant_foreign_access_ref( ref, rdomid, address >> PAGE_SHIFT, 0 );
  10.141 +
  10.142 +    req->frame_and_sects[0] = (((uint32_t) ref) << 16) | 7;
  10.143 +
  10.144 +    blkif_control_send(req, rsp);
  10.145 +}
  10.146 +#endif
  10.147 +
  10.148  void 
  10.149  blkif_control_send(blkif_request_t *req, blkif_response_t *rsp)
  10.150  {
  10.151 @@ -713,6 +775,10 @@ blkif_connect(blkif_fe_interface_status_
  10.152  
  10.153      blkif_evtchn = status->evtchn;
  10.154      blkif_irq    = bind_evtchn_to_irq(blkif_evtchn);
  10.155 +#ifdef CONFIG_XEN_BLKDEV_GRANT
  10.156 +    rdomid       = status->domid;
  10.157 +#endif
  10.158 +
  10.159  
  10.160      err = intr_add_handler("xbd", blkif_irq, 
  10.161  			   (driver_intr_t *)xb_response_intr, NULL,
  10.162 @@ -875,6 +941,14 @@ xb_init(void *unused)
  10.163  
  10.164      printk("[XEN] Initialising virtual block device driver\n");
  10.165  
  10.166 +#ifdef CONFIG_XEN_BLKDEV_GRANT
  10.167 +    if ( 0 > gnttab_alloc_grant_references( MAXIMUM_OUTSTANDING_BLOCK_REQS,
  10.168 +                                            &gref_head, &gref_terminal ))
  10.169 +        return;
  10.170 +    printk("Blkif frontend is using grant tables.\n");
  10.171 +#endif
  10.172 +
  10.173 +
  10.174      rec_ring_free = 0;
  10.175      for (i = 0; i < BLK_RING_SIZE; i++) {
  10.176  	rec_ring[i].id = i+1;
  10.177 @@ -899,13 +973,21 @@ blkdev_resume(void)
  10.178  }
  10.179  #endif
  10.180  
  10.181 -/* XXXXX THIS IS A TEMPORARY FUNCTION UNTIL WE GET GRANT TABLES */
  10.182 -
  10.183  void 
  10.184  blkif_completion(blkif_request_t *req)
  10.185  {
  10.186      int i;
  10.187  
  10.188 +#ifdef CONFIG_XEN_BLKDEV_GRANT
  10.189 +    grant_ref_t gref;
  10.190 +
  10.191 +    for ( i = 0; i < req->nr_segments; i++ )
  10.192 +    {
  10.193 +        gref = blkif_gref_from_fas(req->frame_and_sects[i]);
  10.194 +        gnttab_release_grant_reference(&gref_head, gref);
  10.195 +    }
  10.196 +#else
  10.197 +    /* This is a hack to get the dirty logging bits set */
  10.198      switch ( req->operation )
  10.199      {
  10.200      case BLKIF_OP_READ:
  10.201 @@ -917,7 +999,7 @@ blkif_completion(blkif_request_t *req)
  10.202  	}
  10.203  	break;
  10.204      }
  10.205 -    
  10.206 +#endif    
  10.207  }
  10.208  MTX_SYSINIT(ioreq, &blkif_io_lock, "BIO LOCK", MTX_SPIN | MTX_NOWITNESS); /* XXX how does one enroll a lock? */
  10.209  SYSINIT(xbdev, SI_SUB_PSEUDO, SI_ORDER_ANY, xb_init, NULL)