ia64/xen-unstable
changeset 926:0a901de56d7c
bitkeeper revision 1.588 (3fafd2ccYgSbWe9z2kLiH-DeviUaIA)
Merge labyrinth.cl.cam.ac.uk:/auto/groups/xeno/BK/xeno.bk
into labyrinth.cl.cam.ac.uk:/local/scratch/smh22/xeno.bk
Merge labyrinth.cl.cam.ac.uk:/auto/groups/xeno/BK/xeno.bk
into labyrinth.cl.cam.ac.uk:/local/scratch/smh22/xeno.bk
author | smh22@labyrinth.cl.cam.ac.uk |
---|---|
date | Mon Nov 10 18:02:52 2003 +0000 (2003-11-10) |
parents | 4f30a5c41876 4aba3a48d64f |
children | 95c8edd31ea0 |
files | BitKeeper/etc/ignore tools/internal/Makefile tools/internal/xi_phys_grant.c xen/drivers/block/xen_block.c xen/drivers/block/xen_vbd.c xen/drivers/ide/ide-xeno.c xen/drivers/scsi/sd.c xen/include/hypervisor-ifs/block.h xen/include/hypervisor-ifs/vbd.h xen/include/xeno/vbd.h xenolinux-2.4.22-sparse/arch/xeno/drivers/block/xl_block.c xenolinux-2.4.22-sparse/arch/xeno/drivers/dom0/dom0_core.c |
line diff
1.1 --- a/BitKeeper/etc/ignore Mon Nov 10 17:53:50 2003 +0000 1.2 +++ b/BitKeeper/etc/ignore Mon Nov 10 18:02:52 2003 +0000 1.3 @@ -483,3 +483,8 @@ xen/common/debug.c~ 1.4 xen/common/debug.o 1.5 tools/internal/xi_restore_linux 1.6 tools/internal/xi_save_linux 1.7 +tools/internal/xi_vbd_add 1.8 +tools/internal/xi_vbd_create 1.9 +tools/internal/xi_vbd_info 1.10 +tools/internal/xi_vbd_list 1.11 +xen/drivers/scsi/BusLogic.o
2.1 --- a/tools/internal/Makefile Mon Nov 10 17:53:50 2003 +0000 2.2 +++ b/tools/internal/Makefile Mon Nov 10 18:02:52 2003 +0000 2.3 @@ -10,6 +10,7 @@ OBJS = $(patsubst %.c,%.o,$(SRCS)) 2.4 TARGETS = xi_create xi_start xi_stop xi_destroy xi_build 2.5 TARGETS += xi_phys_grant xi_list xi_save_linux xi_restore_linux 2.6 TARGETS += xi_sched_global xi_sched_domain xi_usage xi_vif_params 2.7 +TARGETS += xi_vbd_create xi_vbd_add xi_vbd_list xi_vbd_info 2.8 INSTALL = $(TARGETS) xi_vifinit xi_helper 2.9 2.10 all: check-for-zlib $(TARGETS)
3.1 --- a/tools/internal/xi_phys_grant.c Mon Nov 10 17:53:50 2003 +0000 3.2 +++ b/tools/internal/xi_phys_grant.c Mon Nov 10 18:02:52 2003 +0000 3.3 @@ -30,13 +30,13 @@ int main(int argc, char *argv[]) 3.4 vdevice = device + atoi(argv[6]); 3.5 3.6 op.cmd = BLOCK_IO_OP_VBD_CREATE; 3.7 - op.u.create_info.domain = domain; 3.8 - op.u.create_info.vdevice = vdevice; 3.9 - op.u.create_info.mode = 0; 3.10 + op.u.create_params.domain = domain; 3.11 + op.u.create_params.vdevice = vdevice; 3.12 + op.u.create_params.mode = 0; 3.13 if ( strchr(argv[1], 'r') ) 3.14 - op.u.create_info.mode |= VBD_MODE_R; 3.15 + op.u.create_params.mode |= VBD_MODE_R; 3.16 if ( strchr(argv[1], 'w') ) 3.17 - op.u.create_info.mode |= VBD_MODE_W; 3.18 + op.u.create_params.mode |= VBD_MODE_W; 3.19 3.20 ret = do_block_io_op(&op); 3.21 3.22 @@ -48,12 +48,12 @@ int main(int argc, char *argv[]) 3.23 3.24 3.25 op.cmd = BLOCK_IO_OP_VBD_ADD; 3.26 - op.u.add_info.domain = domain; 3.27 - op.u.add_info.vdevice = vdevice; 3.28 + op.u.add_params.domain = domain; 3.29 + op.u.add_params.vdevice = vdevice; 3.30 3.31 - op.u.add_info.extent.device = device; 3.32 - op.u.add_info.extent.start_sector = atol(argv[4]); 3.33 - op.u.add_info.extent.nr_sectors = atol(argv[5]); 3.34 + op.u.add_params.extent.device = device; 3.35 + op.u.add_params.extent.start_sector = atol(argv[4]); 3.36 + op.u.add_params.extent.nr_sectors = atol(argv[5]); 3.37 3.38 ret = do_block_io_op(&op); 3.39
4.1 --- a/xen/drivers/block/xen_block.c Mon Nov 10 17:53:50 2003 +0000 4.2 +++ b/xen/drivers/block/xen_block.c Mon Nov 10 18:02:52 2003 +0000 4.3 @@ -73,7 +73,6 @@ static void unlock_buffer(struct task_st 4.4 static void io_schedule(unsigned long unused); 4.5 static int do_block_io_op_domain(struct task_struct *p, int max_to_do); 4.6 static void dispatch_rw_block_io(struct task_struct *p, int index); 4.7 -static void dispatch_probe(struct task_struct *p, int index); 4.8 static void dispatch_debug_block_io(struct task_struct *p, int index); 4.9 static void make_response(struct task_struct *p, unsigned long id, 4.10 unsigned short op, unsigned long st); 4.11 @@ -241,31 +240,35 @@ long do_block_io_op(block_io_op_t *u_blo 4.12 break; 4.13 4.14 case BLOCK_IO_OP_VBD_CREATE: 4.15 - /* create a new VBD for a given domain; caller must be privileged */ 4.16 - if(!IS_PRIV(p)) 4.17 - return -EPERM; 4.18 - ret = vbd_create(&op.u.create_info); 4.19 + /* create a new VBD */ 4.20 + ret = vbd_create(&op.u.create_params); 4.21 break; 4.22 4.23 case BLOCK_IO_OP_VBD_ADD: 4.24 - /* add an extent to a VBD; caller must be privileged */ 4.25 - if(!IS_PRIV(p)) 4.26 - return -EPERM; 4.27 - ret = vbd_add(&op.u.add_info); 4.28 + /* add an extent to a VBD */ 4.29 + ret = vbd_add(&op.u.add_params); 4.30 break; 4.31 4.32 case BLOCK_IO_OP_VBD_REMOVE: 4.33 - /* remove an extent from a VBD; caller must be privileged */ 4.34 - if(!IS_PRIV(p)) 4.35 - return -EPERM; 4.36 - ret = vbd_remove(&op.u.remove_info); 4.37 + /* remove an extent from a VBD */ 4.38 + ret = vbd_remove(&op.u.remove_params); 4.39 break; 4.40 4.41 case BLOCK_IO_OP_VBD_DELETE: 4.42 - /* delete a VBD; caller must be privileged */ 4.43 - if(!IS_PRIV(p)) 4.44 - return -EPERM; 4.45 - ret = vbd_delete(&op.u.delete_info); 4.46 + /* delete a VBD */ 4.47 + ret = vbd_delete(&op.u.delete_params); 4.48 + break; 4.49 + 4.50 + case BLOCK_IO_OP_VBD_PROBE: 4.51 + /* query VBD information for self or others (or all) */ 4.52 + ret = vbd_probe(&op.u.probe_params); 4.53 + if(ret == 0) 4.54 + copy_to_user(u_block_io_op, &op, sizeof(op)); 4.55 + break; 4.56 + 4.57 + case BLOCK_IO_OP_VBD_INFO: 4.58 + /* query information about a particular VBD */ 4.59 + ret = vbd_info(&op.u.info_params); 4.60 break; 4.61 4.62 default: 4.63 @@ -403,10 +406,6 @@ static int do_block_io_op_domain(struct 4.64 dispatch_rw_block_io(p, i); 4.65 break; 4.66 4.67 - case XEN_BLOCK_PROBE: 4.68 - dispatch_probe(p, i); 4.69 - break; 4.70 - 4.71 case XEN_BLOCK_DEBUG: 4.72 dispatch_debug_block_io(p, i); 4.73 break; 4.74 @@ -429,55 +428,6 @@ static void dispatch_debug_block_io(stru 4.75 DPRINTK("dispatch_debug_block_io: unimplemented\n"); 4.76 } 4.77 4.78 - 4.79 -static void dispatch_probe(struct task_struct *p, int index) 4.80 -{ 4.81 - extern void ide_probe_devices(xen_disk_info_t *xdi); 4.82 - extern void scsi_probe_devices(xen_disk_info_t *xdi); 4.83 - extern void vbd_probe_devices(xen_disk_info_t *xdi, struct task_struct *p); 4.84 - 4.85 - blk_ring_t *blk_ring = p->blk_ring_base; 4.86 - xen_disk_info_t *xdi; 4.87 - unsigned long flags, buffer; 4.88 - int rc = 0; 4.89 - 4.90 - buffer = blk_ring->ring[index].req.buffer_and_sects[0] & ~0x1FF; 4.91 - 4.92 - spin_lock_irqsave(&p->page_lock, flags); 4.93 - if ( !__buffer_is_valid(p, buffer, sizeof(xen_disk_info_t), 1) ) 4.94 - { 4.95 - DPRINTK("Bad buffer in dispatch_probe_blk\n"); 4.96 - spin_unlock_irqrestore(&p->page_lock, flags); 4.97 - rc = 1; 4.98 - goto out; 4.99 - } 4.100 - 4.101 - __lock_buffer(buffer, sizeof(xen_disk_info_t), 1); 4.102 - spin_unlock_irqrestore(&p->page_lock, flags); 4.103 - 4.104 - /* 4.105 - ** XXX SMH: all three of the below probe functions /append/ their 4.106 - ** info to the xdi array; i.e. they assume that all earlier slots 4.107 - ** are correctly filled, and that xdi->count points to the first 4.108 - ** free entry in the array. All kinda gross but it'll do for now. 4.109 - */ 4.110 - xdi = map_domain_mem(buffer); 4.111 - xdi->count = 0; 4.112 - 4.113 - if(IS_PRIV(p)) { 4.114 - /* privileged domains always get access to the 'real' devices */ 4.115 - ide_probe_devices(xdi); 4.116 - scsi_probe_devices(xdi); 4.117 - } 4.118 - vbd_probe_devices(xdi, p); 4.119 - unmap_domain_mem(xdi); 4.120 - 4.121 - unlock_buffer(p, buffer, sizeof(xen_disk_info_t), 1); 4.122 - 4.123 - out: 4.124 - make_response(p, blk_ring->ring[index].req.id, XEN_BLOCK_PROBE, rc); 4.125 -} 4.126 - 4.127 static void dispatch_rw_block_io(struct task_struct *p, int index) 4.128 { 4.129 extern void ll_rw_block(int rw, int nr, struct buffer_head * bhs[]);
5.1 --- a/xen/drivers/block/xen_vbd.c Mon Nov 10 17:53:50 2003 +0000 5.2 +++ b/xen/drivers/block/xen_vbd.c Mon Nov 10 18:02:52 2003 +0000 5.3 @@ -14,6 +14,15 @@ 5.4 #include <asm/current.h> 5.5 #include <asm/domain_page.h> 5.6 5.7 +/* 5.8 +** XXX SMH: the below probe functions /append/ their info to the 5.9 +** xdi array; i.e. they assume that all earlier slots are correctly 5.10 +** filled, and that xdi->count points to the first free entry in 5.11 +** the array. All kinda gross but it'll do for now. 5.12 +*/ 5.13 +extern int ide_probe_devices(xen_disk_info_t *xdi); 5.14 +extern int scsi_probe_devices(xen_disk_info_t *xdi); 5.15 + 5.16 5.17 #if 0 5.18 #define DPRINTK(_f, _a...) printk( _f , ## _a ) 5.19 @@ -27,29 +36,32 @@ 5.20 5.21 /* 5.22 ** Create a new VBD; all this involves is adding an entry to the domain's 5.23 -** vbd hash table. 5.24 +** vbd hash table; caller must be privileged. 5.25 */ 5.26 -long vbd_create(vbd_create_t *create_info) 5.27 +long vbd_create(vbd_create_t *create_params) 5.28 { 5.29 struct task_struct *p; 5.30 vbd_t *new_vbd, *v; 5.31 int h; 5.32 5.33 - p = find_domain_by_id(create_info->domain); 5.34 + if(!IS_PRIV(current)) 5.35 + return -EPERM; 5.36 + 5.37 + p = find_domain_by_id(create_params->domain); 5.38 5.39 if (!p) { 5.40 printk("vbd_create attempted for non-existent domain %d\n", 5.41 - create_info->domain); 5.42 + create_params->domain); 5.43 return -EINVAL; 5.44 } 5.45 5.46 new_vbd = kmalloc(sizeof(vbd_t), GFP_KERNEL); 5.47 - new_vbd->vdevice = create_info->vdevice; 5.48 - new_vbd->mode = create_info->mode; 5.49 + new_vbd->vdevice = create_params->vdevice; 5.50 + new_vbd->mode = create_params->mode; 5.51 new_vbd->extents = (xen_extent_le_t *)NULL; 5.52 new_vbd->next = (vbd_t *)NULL; 5.53 5.54 - h = HSH(create_info->vdevice); 5.55 + h = HSH(create_params->vdevice); 5.56 if(p->vbdtab[h]) { 5.57 for(v = p->vbdtab[h]; v->next; v = v->next) 5.58 ; 5.59 @@ -65,25 +77,28 @@ long vbd_create(vbd_create_t *create_inf 5.60 ** Add an extent to an existing VBD; fails if the VBD doesn't exist. 5.61 ** Doesn't worry about overlapping extents (e.g. merging etc) for now. 5.62 */ 5.63 -long vbd_add(vbd_add_t *add_info) 5.64 +long vbd_add(vbd_add_t *add_params) 5.65 { 5.66 struct task_struct *p; 5.67 xen_extent_le_t *x, *xele; 5.68 vbd_t *v; 5.69 int h; 5.70 5.71 - p = find_domain_by_id(add_info->domain); 5.72 + if(!IS_PRIV(current)) 5.73 + return -EPERM; 5.74 + 5.75 + p = find_domain_by_id(add_params->domain); 5.76 5.77 if (!p) { 5.78 printk("vbd_add attempted for non-existent domain %d\n", 5.79 - add_info->domain); 5.80 + add_params->domain); 5.81 return -EINVAL; 5.82 } 5.83 5.84 - h = HSH(add_info->vdevice); 5.85 + h = HSH(add_params->vdevice); 5.86 5.87 for(v = p->vbdtab[h]; v; v = v->next) 5.88 - if(v->vdevice == add_info->vdevice) 5.89 + if(v->vdevice == add_params->vdevice) 5.90 break; 5.91 5.92 if(!v) { 5.93 @@ -92,9 +107,9 @@ long vbd_add(vbd_add_t *add_info) 5.94 } 5.95 5.96 xele = kmalloc(sizeof(xen_extent_le_t), GFP_KERNEL); 5.97 - xele->extent.device = add_info->extent.device; 5.98 - xele->extent.start_sector = add_info->extent.start_sector; 5.99 - xele->extent.nr_sectors = add_info->extent.nr_sectors; 5.100 + xele->extent.device = add_params->extent.device; 5.101 + xele->extent.start_sector = add_params->extent.start_sector; 5.102 + xele->extent.nr_sectors = add_params->extent.nr_sectors; 5.103 xele->next = (xen_extent_le_t *)NULL; 5.104 5.105 if(!v->extents) { 5.106 @@ -109,12 +124,157 @@ long vbd_add(vbd_add_t *add_info) 5.107 return 0; 5.108 } 5.109 5.110 -long vbd_remove(vbd_remove_t *remove_info) 5.111 +long vbd_remove(vbd_remove_t *remove_params) 5.112 { 5.113 + if(!IS_PRIV(current)) 5.114 + return -EPERM; 5.115 + 5.116 + return -ENOSYS; 5.117 +} 5.118 + 5.119 +long vbd_delete(vbd_delete_t *delete_params) 5.120 +{ 5.121 + if(!IS_PRIV(current)) 5.122 + return -EPERM; 5.123 + 5.124 return -ENOSYS; 5.125 } 5.126 5.127 -long vbd_delete(vbd_delete_t *delete_info) 5.128 + 5.129 +/* 5.130 + * vbd_probe_devices: 5.131 + * 5.132 + * add the virtual block devices for this domain to a xen_disk_info_t; 5.133 + * we assume xdi->count points to the first unused place in the array. 5.134 + */ 5.135 +static int vbd_probe_devices(xen_disk_info_t *xdi, struct task_struct *p) 5.136 +{ 5.137 + xen_extent_le_t *x; 5.138 + xen_disk_t cur_disk; 5.139 + vbd_t *v; 5.140 + int i, ret; 5.141 + 5.142 + for(i = 0; i < VBD_HTAB_SZ; i++) { 5.143 + 5.144 + for(v = p->vbdtab[i]; v; v = v->next) { 5.145 + 5.146 + /* SMH: don't ever expect this to happen, hence verbose printk */ 5.147 + if ( xdi->count == xdi->max ) { 5.148 + printk("vbd_probe_devices: out of space for probe.\n"); 5.149 + return -ENOMEM; 5.150 + } 5.151 + 5.152 + cur_disk.device = v->vdevice; 5.153 + cur_disk.info = XD_FLAG_VIRT | XD_TYPE_DISK; 5.154 + if(!VBD_CAN_WRITE(v)) 5.155 + cur_disk.info |= XD_FLAG_RO; 5.156 + cur_disk.capacity = 0 ; 5.157 + for(x = v->extents; x; x = x->next) 5.158 + cur_disk.capacity += x->extent.nr_sectors; 5.159 + cur_disk.domain = p->domain; 5.160 + 5.161 + /* Now copy into relevant part of user-space buffer */ 5.162 + if((ret = copy_to_user(xdi->disks + xdi->count, &cur_disk, 5.163 + sizeof(xen_disk_t))) < 0) { 5.164 + printk("vbd_probe_devices: copy_to_user failed [rc=%d]\n", 5.165 + ret); 5.166 + return ret; 5.167 + } 5.168 + 5.169 + 5.170 + xdi->count++; 5.171 + } 5.172 + } 5.173 + 5.174 + return 0; 5.175 +} 5.176 + 5.177 + 5.178 +/* 5.179 +** Return information about the VBDs available for a given domain, 5.180 +** or for all domains; in the general case the 'domain' argument 5.181 +** will be 0 which means "information about the caller"; otherwise 5.182 +** the 'domain' argument will specify either a given domain, or 5.183 +** all domains ("VBD_PROBE_ALL") -- both of these cases require the 5.184 +** caller to be privileged. 5.185 +*/ 5.186 +long vbd_probe(vbd_probe_t *probe_params) 5.187 +{ 5.188 + struct task_struct *p = NULL; 5.189 + int ret; 5.190 + 5.191 + if(probe_params->domain) { 5.192 + 5.193 + /* we can only probe for ourselves unless we're privileged */ 5.194 + if(probe_params->domain != current->domain && !IS_PRIV(current)) 5.195 + return -EPERM; 5.196 + 5.197 + if(probe_params->domain != VBD_PROBE_ALL) { 5.198 + 5.199 + p = find_domain_by_id(probe_params->domain); 5.200 + 5.201 + if (!p) { 5.202 + printk("vbd_probe attempted for non-existent domain %d\n", 5.203 + probe_params->domain); 5.204 + return -EINVAL; 5.205 + } 5.206 + 5.207 + } 5.208 + 5.209 + } else 5.210 + /* default is to probe for ourselves */ 5.211 + p = current; 5.212 + 5.213 + 5.214 + if(!p || IS_PRIV(p)) { 5.215 + 5.216 + /* privileged domains always get access to the 'real' devices */ 5.217 + if((ret = ide_probe_devices(&probe_params->xdi))) { 5.218 + printk("vbd_probe: error %d in probing ide devices\n", ret); 5.219 + return ret; 5.220 + } 5.221 + if((ret = scsi_probe_devices(&probe_params->xdi))) { 5.222 + printk("vbd_probe: error %d in probing scsi devices\n", ret); 5.223 + return ret; 5.224 + } 5.225 + } 5.226 + 5.227 + 5.228 + if(!p) { 5.229 + 5.230 + u_long flags; 5.231 + 5.232 + read_lock_irqsave (&tasklist_lock, flags); 5.233 + 5.234 + p = &idle0_task; 5.235 + while ( (p = p->next_task) != &idle0_task ) { 5.236 + if (!is_idle_task(p)) { 5.237 + if((ret = vbd_probe_devices(&probe_params->xdi, p))) { 5.238 + printk("vbd_probe: error %d in probing virtual devices\n", 5.239 + ret); 5.240 + read_unlock_irqrestore(&tasklist_lock, flags); 5.241 + return ret; 5.242 + } 5.243 + } 5.244 + } 5.245 + 5.246 + read_unlock_irqrestore(&tasklist_lock, flags); 5.247 + 5.248 + } else { 5.249 + 5.250 + /* probe for disks and VBDs for just 'p' */ 5.251 + if((ret = vbd_probe_devices(&probe_params->xdi, p))) { 5.252 + printk("vbd_probe: error %d in probing virtual devices\n", ret); 5.253 + return ret; 5.254 + } 5.255 + 5.256 + } 5.257 + 5.258 + 5.259 + return 0; 5.260 +} 5.261 + 5.262 +long vbd_info(vbd_info_t *info_params) 5.263 { 5.264 return -ENOSYS; 5.265 } 5.266 @@ -173,40 +333,7 @@ int vbd_translate(phys_seg_t * pseg, int 5.267 } 5.268 5.269 5.270 -/* 5.271 - * vbd_probe_devices: 5.272 - * 5.273 - * add the virtual block devices for this domain to a xen_disk_info_t; 5.274 - * we assume xdi->count points to the first unused place in the array. 5.275 - */ 5.276 -void vbd_probe_devices(xen_disk_info_t *xdi, struct task_struct *p) 5.277 -{ 5.278 - xen_extent_le_t *x; 5.279 - vbd_t *v; 5.280 - int i; 5.281 - 5.282 - /* XXX SMH: should allow priv domains to probe vbds for other doms XXX */ 5.283 - 5.284 - for(i = 0; i < VBD_HTAB_SZ; i++) { 5.285 - for(v = p->vbdtab[i]; v; v = v->next) { 5.286 - 5.287 - xdi->disks[xdi->count].device = v->vdevice; 5.288 - xdi->disks[xdi->count].info = XD_FLAG_VIRT | XD_TYPE_DISK; 5.289 - 5.290 - if(!VBD_CAN_WRITE(v)) 5.291 - xdi->disks[xdi->count].info |= XD_FLAG_RO; 5.292 - 5.293 - xdi->disks[xdi->count].capacity = 0; 5.294 - for(x = v->extents; x; x = x->next) 5.295 - xdi->disks[xdi->count].capacity += x->extent.nr_sectors; 5.296 - xdi->count++; 5.297 - } 5.298 - } 5.299 - 5.300 - return; 5.301 -} 5.302 5.303 5.304 5.305 5.306 -
6.1 --- a/xen/drivers/ide/ide-xeno.c Mon Nov 10 17:53:50 2003 +0000 6.2 +++ b/xen/drivers/ide/ide-xeno.c Mon Nov 10 18:02:52 2003 +0000 6.3 @@ -24,14 +24,14 @@ static kdev_t ide_devs[NR_IDE_DEVS] = { 6.4 6.5 6.6 6.7 -void ide_probe_devices(xen_disk_info_t* xdi) 6.8 +int ide_probe_devices(xen_disk_info_t* xdi) 6.9 { 6.10 - int loop; 6.11 + int loop, ret = 0; 6.12 unsigned int unit; 6.13 - unsigned long capacity; 6.14 - unsigned short device, type; 6.15 + unsigned short type; 6.16 ide_drive_t *drive; 6.17 - 6.18 + xen_disk_t cur_disk; 6.19 + 6.20 for ( loop = 0; loop < MAX_HWIFS; loop++ ) 6.21 { 6.22 ide_hwif_t *hwif = &ide_hwifs[loop]; 6.23 @@ -42,33 +42,42 @@ void ide_probe_devices(xen_disk_info_t* 6.24 drive = &hwif->drives[unit]; 6.25 6.26 if ( !drive->present ) continue; 6.27 + 6.28 + 6.29 + /* SMH: don't ever expect this to happen, hence verbose printk */ 6.30 + if ( xdi->count == xdi->max ) { 6.31 + printk("ide_probe_devices: out of space for probe.\n"); 6.32 + return -ENOMEM; 6.33 + } 6.34 + 6.35 6.36 + 6.37 + /* SMH: we export 'raw' linux device numbers to domain 0 */ 6.38 + cur_disk.device = ide_devs[(loop * MAX_DRIVES) + unit]; 6.39 + 6.40 /* 6.41 ** NB: we use the ide 'media' field (ide_disk, ide_cdrom, etc) 6.42 ** as our 'type' field (XD_TYPE_DISK, XD_TYPE_CDROM, etc). 6.43 ** Hence must ensure these are kept in sync. 6.44 */ 6.45 - 6.46 - /* SMH: we export 'raw' linux device numbers to domain 0 */ 6.47 - device = ide_devs[(loop * MAX_DRIVES) + unit]; 6.48 - type = drive->media; 6.49 - capacity = current_capacity(drive); 6.50 - 6.51 - xdi->disks[xdi->count].device = device; 6.52 - xdi->disks[xdi->count].info = type; 6.53 - 6.54 + cur_disk.info = (type = drive->media); 6.55 if(type == XD_TYPE_CDROM) 6.56 - xdi->disks[xdi->count].info |= XD_FLAG_RO; 6.57 + cur_disk.info |= XD_FLAG_RO; 6.58 6.59 - xdi->disks[xdi->count].capacity = capacity; 6.60 - xdi->count++; 6.61 + cur_disk.capacity = current_capacity(drive); 6.62 + cur_disk.domain = 0; /* 'physical' disks belong to domain 0 6.63 6.64 - printk("Device %d: IDE-XENO (%s) capacity %ldkB (%ldMB)\n", 6.65 - xdi->count, (type == XD_TYPE_DISK) ? "disk" : 6.66 - ((type == XD_TYPE_CDROM) ? "cdrom" : "unknown"), 6.67 - capacity>>1, capacity>>11); 6.68 + /* Now copy into relevant part of user-space buffer */ 6.69 + if((ret = copy_to_user(xdi->disks + xdi->count, &cur_disk, 6.70 + sizeof(xen_disk_t))) < 0) { 6.71 + printk("ide_probe_devices: copy_to_user failed [rc=%d]\n", 6.72 + ret); 6.73 + return ret; 6.74 + } 6.75 + 6.76 + xdi->count++; 6.77 } 6.78 } 6.79 6.80 - return; 6.81 + return ret; 6.82 }
7.1 --- a/xen/drivers/scsi/sd.c Mon Nov 10 17:53:50 2003 +0000 7.2 +++ b/xen/drivers/scsi/sd.c Mon Nov 10 18:02:52 2003 +0000 7.3 @@ -1336,32 +1336,39 @@ static kdev_t scsi_devs[NR_SCSI_DEVS] = 7.4 }; 7.5 7.6 7.7 -void scsi_probe_devices(xen_disk_info_t *xdi) 7.8 +int scsi_probe_devices(xen_disk_info_t *xdi) 7.9 { 7.10 Scsi_Disk *sd; 7.11 - int i; 7.12 - unsigned short device; 7.13 - unsigned long capacity; 7.14 + xen_disk_t cur_disk; 7.15 + int i, ret; 7.16 7.17 for ( sd = rscsi_disks, i = 0; i < sd_template.dev_max; i++, sd++ ) 7.18 { 7.19 if ( sd->device == NULL ) continue; 7.20 7.21 - /* SMH: we export 'raw' linux device numbers to domain 0 */ 7.22 - device = scsi_devs[i]; 7.23 - capacity = sd->capacity; 7.24 + /* SMH: don't ever expect this to happen, hence verbose printk */ 7.25 + if ( xdi->count == xdi->max ) { 7.26 + printk("scsi_probe_devices: out of space for probe.\n"); 7.27 + return -ENOMEM; 7.28 + } 7.29 7.30 - /* XXX SMH: if make generic, need to properly determine 'type' */ 7.31 - xdi->disks[xdi->count].device = device; 7.32 - xdi->disks[xdi->count].info = XD_TYPE_DISK; 7.33 - xdi->disks[xdi->count].capacity = capacity; 7.34 - xdi->count++; 7.35 - 7.36 - printk("Device %d: SCSI-XENO (disk) capacity %ldkB (%ldMB)\n", 7.37 - xdi->count, capacity>>1, capacity>>11); 7.38 + /* SMH: we export 'raw' linux device numbers to domain 0 */ 7.39 + cur_disk.device = scsi_devs[i]; 7.40 + cur_disk.info = XD_TYPE_DISK; // XXX SMH: should determine properly 7.41 + cur_disk.capacity = sd->capacity; 7.42 + cur_disk.domain = 0; // 'physical' disks belong to dom0 7.43 + 7.44 + /* Now copy into relevant part of user-space buffer */ 7.45 + if((ret = copy_to_user(xdi->disks + xdi->count, &cur_disk, 7.46 + sizeof(xen_disk_t))) < 0) { 7.47 + printk("scsi_probe_devices: copy_to_user failed [rc=%d]\n", ret); 7.48 + return ret; 7.49 + } 7.50 + 7.51 + xdi->count++; 7.52 } 7.53 7.54 - return; 7.55 + return 0; 7.56 } 7.57 7.58
8.1 --- a/xen/include/hypervisor-ifs/block.h Mon Nov 10 17:53:50 2003 +0000 8.2 +++ b/xen/include/hypervisor-ifs/block.h Mon Nov 10 18:02:52 2003 +0000 8.3 @@ -20,8 +20,7 @@ 8.4 #define XEN_BLOCK_WRITE 1 8.5 #define XEN_BLOCK_READA 2 8.6 #define XEN_BLOCK_SPECIAL 4 8.7 -#define XEN_BLOCK_PROBE 5 /* get config from hypervisor */ 8.8 -#define XEN_BLOCK_DEBUG 6 /* debug */ 8.9 +#define XEN_BLOCK_DEBUG 5 /* debug */ 8.10 8.11 /* NB. Ring size must be small enough for sizeof(blk_ring_t) <= PAGE_SIZE. */ 8.12 #define BLK_RING_SIZE 64 8.13 @@ -65,7 +64,6 @@ typedef struct blk_ring_st 8.14 * Information about the real and virtual disks we have; used during 8.15 * guest device probing. 8.16 */ 8.17 -#define XEN_MAX_DISK_COUNT 64 8.18 8.19 /* XXX SMH: below types chosen to align with ide_xxx types in ide.h */ 8.20 #define XD_TYPE_FLOPPY 0x00 8.21 @@ -81,19 +79,23 @@ typedef struct blk_ring_st 8.22 #define XD_FLAG_RO 0x40 8.23 #define XD_FLAG_VIRT 0x80 8.24 #define XD_READONLY(_x) ((_x) & XD_FLAG_RO) 8.25 -#define XD_VIRTUAL(_x) ((_x) & XF_FLAG_VIRT) 8.26 +#define XD_VIRTUAL(_x) ((_x) & XD_FLAG_VIRT) 8.27 8.28 typedef struct xen_disk 8.29 { 8.30 unsigned short device; /* device number (opaque 16 bit val) */ 8.31 unsigned short info; /* device type and flags */ 8.32 unsigned long capacity; /* size in terms of #512 byte sectors */ 8.33 + unsigned int domain; /* if a VBD, domain this 'belongs to' */ 8.34 } xen_disk_t; 8.35 8.36 typedef struct xen_disk_info 8.37 { 8.38 - int count; 8.39 - xen_disk_t disks[XEN_MAX_DISK_COUNT]; 8.40 + /* IN variables */ 8.41 + int max; // maximumum number of disks to report 8.42 + xen_disk_t *disks; // pointer to array of disk info 8.43 + /* OUT variables */ 8.44 + int count; // how many disks we have info about 8.45 } xen_disk_info_t; 8.46 8.47 #endif
9.1 --- a/xen/include/hypervisor-ifs/vbd.h Mon Nov 10 17:53:50 2003 +0000 9.2 +++ b/xen/include/hypervisor-ifs/vbd.h Mon Nov 10 18:02:52 2003 +0000 9.3 @@ -13,7 +13,8 @@ 9.4 #define BLOCK_IO_OP_VBD_ADD 4 /* add an extent to a given VBD */ 9.5 #define BLOCK_IO_OP_VBD_REMOVE 5 /* remove an extent from a given VBD */ 9.6 #define BLOCK_IO_OP_VBD_DELETE 6 /* delete a VBD */ 9.7 - 9.8 +#define BLOCK_IO_OP_VBD_PROBE 7 /* query VBD information for a domain */ 9.9 +#define BLOCK_IO_OP_VBD_INFO 8 /* query info about a particular VBD */ 9.10 9.11 typedef struct _xen_extent { 9.12 u16 device; 9.13 @@ -32,29 +33,41 @@ typedef struct _xen_extent { 9.14 9.15 9.16 typedef struct _vbd_create { 9.17 - unsigned domain; 9.18 - u16 vdevice; 9.19 - u16 mode; 9.20 + unsigned domain; // create VBD for this domain 9.21 + u16 vdevice; // 16 bit id domain will refer to VBD as 9.22 + u16 mode; // OR of { VBD_MODE_R , VBD_MODE_W } 9.23 } vbd_create_t; 9.24 9.25 typedef struct _vbd_add { 9.26 - unsigned domain; 9.27 - u16 vdevice; 9.28 - xen_extent_t extent; 9.29 + unsigned domain; // domain in question 9.30 + u16 vdevice; // 16 bit id domain refers to VBD as 9.31 + xen_extent_t extent; // the extent to add to this VBD 9.32 } vbd_add_t; 9.33 9.34 typedef struct _vbd_remove { 9.35 - unsigned domain; 9.36 - u16 vdevice; 9.37 - xen_extent_t extent; 9.38 + unsigned domain; // domain in question 9.39 + u16 vdevice; // 16 bit id domain refers to VBD as 9.40 + xen_extent_t extent; // the extent to remove from this VBD 9.41 } vbd_remove_t; 9.42 9.43 9.44 -typedef struct _vbd_delete { 9.45 - unsigned domain; 9.46 - u16 vdevice; 9.47 +typedef struct _vbd_delete { 9.48 + unsigned domain; // domain in question 9.49 + u16 vdevice; // 16 bit id domain refers to VBD as 9.50 } vbd_delete_t; 9.51 9.52 +#define VBD_PROBE_ALL 0xFFFFFFFF 9.53 +typedef struct _vbd_probe { 9.54 + unsigned domain; // domain in question or VBD_PROBE_ALL 9.55 + xen_disk_info_t xdi; // where's our space for VBD/disk info 9.56 +} vbd_probe_t; 9.57 + 9.58 +typedef struct _vbd_info { 9.59 + unsigned domain; // domain in question 9.60 + u16 vdevice; // 16 bit id domain refers to VBD as 9.61 + u16 nextents; // max no. of extents to return info for 9.62 + xen_extent_t *extents; // pointer to space for list of extents 9.63 +} vbd_info_t; 9.64 9.65 9.66 typedef struct block_io_op_st 9.67 @@ -65,10 +78,12 @@ typedef struct block_io_op_st 9.68 /* no entry for BLOCK_IO_OP_SIGNAL */ 9.69 /* no entry for BLOCK_IO_OP_RESET */ 9.70 unsigned long ring_mfn; 9.71 - vbd_create_t create_info; 9.72 - vbd_add_t add_info; 9.73 - vbd_remove_t remove_info; 9.74 - vbd_delete_t delete_info; 9.75 + vbd_create_t create_params; 9.76 + vbd_add_t add_params; 9.77 + vbd_remove_t remove_params; 9.78 + vbd_delete_t delete_params; 9.79 + vbd_probe_t probe_params; 9.80 + vbd_info_t info_params; 9.81 } 9.82 u; 9.83 } block_io_op_t;
10.1 --- a/xen/include/xeno/vbd.h Mon Nov 10 17:53:50 2003 +0000 10.2 +++ b/xen/include/xeno/vbd.h Mon Nov 10 18:02:52 2003 +0000 10.3 @@ -30,10 +30,12 @@ typedef struct _vbd { 10.4 10.5 #define VBD_HTAB_SZ 16 // no. of entries in the vbd hash table. 10.6 10.7 -long vbd_create(vbd_create_t *create_info); 10.8 -long vbd_add(vbd_add_t *add_info); 10.9 -long vbd_remove(vbd_remove_t *remove_info); 10.10 -long vbd_delete(vbd_delete_t *delete_info); 10.11 +long vbd_create(vbd_create_t *create_params); 10.12 +long vbd_add(vbd_add_t *add_params); 10.13 +long vbd_remove(vbd_remove_t *remove_params); 10.14 +long vbd_delete(vbd_delete_t *delete_params); 10.15 +long vbd_probe(vbd_probe_t *probe_params); 10.16 +long vbd_info(vbd_info_t *info_params); 10.17 10.18 10.19 /* Describes a [partial] disk extent (part of a block io request) */
11.1 --- a/xenolinux-2.4.22-sparse/arch/xeno/drivers/block/xl_block.c Mon Nov 10 17:53:50 2003 +0000 11.2 +++ b/xenolinux-2.4.22-sparse/arch/xeno/drivers/block/xl_block.c Mon Nov 10 18:02:52 2003 +0000 11.3 @@ -22,8 +22,14 @@ static unsigned int state = STATE_SUSPEN 11.4 static blk_ring_t *blk_ring; 11.5 static unsigned int resp_cons; /* Response consumer for comms ring. */ 11.6 static unsigned int req_prod; /* Private request producer. */ 11.7 -static xen_disk_info_t xlblk_disk_info; 11.8 + 11.9 +#define XDI_MAX 64 11.10 +static xen_disk_info_t xlblk_disk_info; /* information about our disks/VBDs */ 11.11 + 11.12 +#if 0 11.13 static int xlblk_control_msg_pending; 11.14 +#endif 11.15 + 11.16 11.17 /* We plug the I/O ring if the driver is suspended or if the ring is full. */ 11.18 #define RING_PLUGGED ((BLK_RING_INC(req_prod) == resp_cons) || \ 11.19 @@ -247,11 +253,13 @@ static int hypervisor_request(unsigned l 11.20 11.21 switch ( operation ) 11.22 { 11.23 +#if 0 11.24 case XEN_BLOCK_PROBE: 11.25 if ( RING_PLUGGED ) return 1; 11.26 sector_number = 0; 11.27 DISABLE_SCATTERGATHER(); 11.28 break; 11.29 +#endif 11.30 11.31 case XEN_BLOCK_READ: 11.32 case XEN_BLOCK_WRITE: 11.33 @@ -430,9 +438,11 @@ static void xlblk_response_int(int irq, 11.34 } 11.35 break; 11.36 11.37 +#if 0 11.38 case XEN_BLOCK_PROBE: 11.39 xlblk_control_msg_pending = bret->status; 11.40 break; 11.41 +#endif 11.42 11.43 default: 11.44 BUG(); 11.45 @@ -447,6 +457,7 @@ static void xlblk_response_int(int irq, 11.46 } 11.47 11.48 11.49 +#if 0 11.50 /* Send a synchronous message to Xen. */ 11.51 int xenolinux_control_msg(int operation, char *buffer, int size) 11.52 { 11.53 @@ -472,13 +483,14 @@ int xenolinux_control_msg(int operation, 11.54 11.55 return xlblk_control_msg_pending ? -EINVAL : 0; 11.56 } 11.57 +#endif 11.58 11.59 11.60 static void reset_xlblk_interface(void) 11.61 { 11.62 block_io_op_t op; 11.63 11.64 - xlblk_control_msg_pending = 0; 11.65 +// xlblk_control_msg_pending = 0; 11.66 nr_pending = 0; 11.67 11.68 op.cmd = BLOCK_IO_OP_RESET; 11.69 @@ -500,6 +512,7 @@ static void reset_xlblk_interface(void) 11.70 int __init xlblk_init(void) 11.71 { 11.72 int error; 11.73 + block_io_op_t op; 11.74 11.75 reset_xlblk_interface(); 11.76 11.77 @@ -511,11 +524,19 @@ int __init xlblk_init(void) 11.78 goto fail; 11.79 } 11.80 11.81 + /* Setup our [empty] disk information structure */ 11.82 + xlblk_disk_info.max = XDI_MAX; 11.83 + xlblk_disk_info.disks = kmalloc(XDI_MAX * sizeof(xen_disk_t), GFP_KERNEL); 11.84 + xlblk_disk_info.count = 0; 11.85 + 11.86 /* Probe for disk information. */ 11.87 - memset(&xlblk_disk_info, 0, sizeof(xlblk_disk_info)); 11.88 - error = xenolinux_control_msg(XEN_BLOCK_PROBE, 11.89 - (char *)&xlblk_disk_info, 11.90 - sizeof(xen_disk_info_t)); 11.91 + memset(&op, 0, sizeof(op)); 11.92 + op.cmd = BLOCK_IO_OP_VBD_PROBE; 11.93 + op.u.probe_params.domain = 0; 11.94 + memcpy(&op.u.probe_params.xdi, &xlblk_disk_info, sizeof(xlblk_disk_info)); 11.95 + 11.96 + error = HYPERVISOR_block_io_op(&op); 11.97 + 11.98 if ( error ) 11.99 { 11.100 printk(KERN_ALERT "Could not probe disks (%d)\n", error); 11.101 @@ -523,6 +544,9 @@ int __init xlblk_init(void) 11.102 goto fail; 11.103 } 11.104 11.105 + /* copy back the [updated] count parameter */ 11.106 + xlblk_disk_info.count = op.u.probe_params.xdi.count; 11.107 + 11.108 /* Pass the information to our virtual block device susbystem. */ 11.109 xlvbd_init(&xlblk_disk_info); 11.110
12.1 --- a/xenolinux-2.4.22-sparse/arch/xeno/drivers/dom0/dom0_core.c Mon Nov 10 17:53:50 2003 +0000 12.2 +++ b/xenolinux-2.4.22-sparse/arch/xeno/drivers/dom0/dom0_core.c Mon Nov 10 18:02:52 2003 +0000 12.3 @@ -65,41 +65,6 @@ static int privcmd_ioctl(struct inode *i 12.4 } 12.5 break; 12.6 12.7 - case IOCTL_PRIVCMD_BLKMSG: 12.8 - { 12.9 - privcmd_blkmsg_t blkmsg; 12.10 - char *kbuf; 12.11 - int ret; 12.12 - 12.13 - if ( copy_from_user(&blkmsg, (void *)data, sizeof(blkmsg)) ) 12.14 - return -EFAULT; 12.15 - 12.16 - if ( blkmsg.buf_size > PAGE_SIZE ) 12.17 - return -EINVAL; 12.18 - 12.19 - if ( (kbuf = kmalloc(blkmsg.buf_size, GFP_KERNEL)) == NULL ) 12.20 - return -ENOMEM; 12.21 - 12.22 - if ( copy_from_user(kbuf, blkmsg.buf, blkmsg.buf_size) ) { 12.23 - kfree(kbuf); 12.24 - return -EFAULT; 12.25 - } 12.26 - 12.27 - ret = xenolinux_control_msg((int)blkmsg.op, kbuf, blkmsg.buf_size); 12.28 - if ( ret != 0 ) { 12.29 - kfree(kbuf); 12.30 - return ret; 12.31 - } 12.32 - 12.33 - if ( copy_to_user(blkmsg.buf, kbuf, blkmsg.buf_size) ) { 12.34 - kfree(kbuf); 12.35 - return -EFAULT; 12.36 - } 12.37 - 12.38 - kfree(kbuf); 12.39 - } 12.40 - break; 12.41 - 12.42 default: 12.43 ret = -EINVAL; 12.44 break;