ia64/xen-unstable

changeset 925:4aba3a48d64f

bitkeeper revision 1.580.1.1 (3fafd2c85ofrHsrmRaYOxYp49iwWOA)

new vbd probe world
author smh22@labyrinth.cl.cam.ac.uk
date Mon Nov 10 18:02:48 2003 +0000 (2003-11-10)
parents a950d8f629c1
children 0a901de56d7c
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 10:21:41 2003 +0000
     1.2 +++ b/BitKeeper/etc/ignore	Mon Nov 10 18:02:48 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 10:21:41 2003 +0000
     2.2 +++ b/tools/internal/Makefile	Mon Nov 10 18:02:48 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 10:21:41 2003 +0000
     3.2 +++ b/tools/internal/xi_phys_grant.c	Mon Nov 10 18:02:48 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 10:21:41 2003 +0000
     4.2 +++ b/xen/drivers/block/xen_block.c	Mon Nov 10 18:02:48 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 10:21:41 2003 +0000
     5.2 +++ b/xen/drivers/block/xen_vbd.c	Mon Nov 10 18:02:48 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_info) 
   5.120 +long vbd_delete(vbd_delete_t *delete_params) 
   5.121 +{
   5.122 +    if(!IS_PRIV(current))
   5.123 +	return -EPERM; 
   5.124 +
   5.125 +    return -ENOSYS; 
   5.126 +}
   5.127 +
   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 10:21:41 2003 +0000
     6.2 +++ b/xen/drivers/ide/ide-xeno.c	Mon Nov 10 18:02:48 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 +	    cur_disk.info   = (type = drive->media); 
    6.54 +	    if(type == XD_TYPE_CDROM) 
    6.55 +		cur_disk.info |= XD_FLAG_RO; 
    6.56  
    6.57 -	    if(type == XD_TYPE_CDROM) 
    6.58 -		xdi->disks[xdi->count].info |= XD_FLAG_RO; 
    6.59 +	    cur_disk.capacity = current_capacity(drive);
    6.60 +	    cur_disk.domain   = 0; /* 'physical' disks belong to domain 0 
    6.61  
    6.62 -            xdi->disks[xdi->count].capacity = capacity;
    6.63 +	    /* Now copy into relevant part of user-space buffer */
    6.64 +	    if((ret = copy_to_user(xdi->disks + xdi->count, &cur_disk, 
    6.65 +				   sizeof(xen_disk_t))) < 0) { 
    6.66 +		printk("ide_probe_devices: copy_to_user failed [rc=%d]\n", 
    6.67 +		       ret); 
    6.68 +		return ret; 
    6.69 +	    } 
    6.70 +		
    6.71              xdi->count++;
    6.72 -
    6.73 -            printk("Device %d: IDE-XENO (%s) capacity %ldkB (%ldMB)\n",
    6.74 -                   xdi->count, (type == XD_TYPE_DISK) ? "disk" : 
    6.75 -		   ((type == XD_TYPE_CDROM) ? "cdrom" : "unknown"), 
    6.76 -		   capacity>>1, capacity>>11);
    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 10:21:41 2003 +0000
     7.2 +++ b/xen/drivers/scsi/sd.c	Mon Nov 10 18:02:48 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 10:21:41 2003 +0000
     8.2 +++ b/xen/include/hypervisor-ifs/block.h	Mon Nov 10 18:02:48 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 10:21:41 2003 +0000
     9.2 +++ b/xen/include/hypervisor-ifs/vbd.h	Mon Nov 10 18:02:48 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 10:21:41 2003 +0000
    10.2 +++ b/xen/include/xeno/vbd.h	Mon Nov 10 18:02:48 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 10:21:41 2003 +0000
    11.2 +++ b/xenolinux-2.4.22-sparse/arch/xeno/drivers/block/xl_block.c	Mon Nov 10 18:02:48 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 10:21:41 2003 +0000
    12.2 +++ b/xenolinux-2.4.22-sparse/arch/xeno/drivers/dom0/dom0_core.c	Mon Nov 10 18:02:48 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;