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>
Grant tables for FreeBSD.
Signed-off-by: Kip Macy <kmacy@fsmware.com>
Signed-off-by: Keir Fraser <keir@xensource.com>
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)