ia64/xen-unstable

changeset 491:ceae0c6af93b

bitkeeper revision 1.259.1.1 (3f045a1aTKC1vRJU2nif7VHOWTRJ1g)

New physical disk access control stuff.
author sos22@labyrinth.cl.cam.ac.uk
date Thu Jul 03 16:30:18 2003 +0000 (2003-07-03)
parents c6258eb58cde
children e8a16b3d27cb
files .rootkeys tools/internal/Makefile tools/internal/physdev.h tools/internal/xi_phys_grant.c tools/internal/xi_phys_probe.c tools/internal/xi_phys_revoke.c xen/common/domain.c xen/drivers/block/xen_block.c xen/drivers/block/xen_physdisk.c xen/include/hypervisor-ifs/block.h xen/include/xeno/sched.h xenolinux-2.4.21-sparse/arch/xeno/drivers/block/Makefile xenolinux-2.4.21-sparse/arch/xeno/drivers/block/xl_block.c xenolinux-2.4.21-sparse/arch/xeno/drivers/block/xl_physdisk_proc.c xenolinux-2.4.21-sparse/arch/xeno/drivers/block/xl_physdisk_proc.c~ xenolinux-2.4.21-sparse/drivers/block/ll_rw_blk.c
line diff
     1.1 --- a/.rootkeys	Tue Jul 01 14:17:01 2003 +0000
     1.2 +++ b/.rootkeys	Thu Jul 03 16:30:18 2003 +0000
     1.3 @@ -103,12 +103,16 @@ 3eb781fdc539MQQm47rYRCCR3N5i-Q tools/int
     1.4  3ee609b3Yr4aggmLSKmhiIzT8-nURA tools/internal/dom0_ops.h
     1.5  3eb781fddjylXbsepjppUyIXa5lcaQ tools/internal/hypervisor_defs.h
     1.6  3eb781fdKiQbgozBsgs_zzJQ9ubehw tools/internal/mem_defs.h
     1.7 +3f04589dFbtsbWWwAXq3I92UiAogCg tools/internal/physdev.h
     1.8  3ec61e1bJCeJJu0SsptmDpA1xKvwvw tools/internal/rpm.spec
     1.9  3eb781fdgbSkh2O6JQS-65Dz4n0ItQ tools/internal/xi_build.c
    1.10  3eb781fdW1SAyiaC4mTsXq_9fRHh-A tools/internal/xi_create.c
    1.11  3eb781fdcJ0fF7rWfzAOArW-x4-gwA tools/internal/xi_destroy.c
    1.12  3ec43c5dmQxGDvgJJXbV1yLxT30Y1A tools/internal/xi_helper
    1.13  3eb83c3bZeECmphOKOJxSu4Lo1LpBw tools/internal/xi_list
    1.14 +3f0458aaXhD8BQAggO81gv30RQ-ifA tools/internal/xi_phys_grant.c
    1.15 +3f0458aaJHmlzkDwf0qxEzAcjX55sg tools/internal/xi_phys_probe.c
    1.16 +3f0458aaVAbFSwptQbQAnDOiZlwQ3w tools/internal/xi_phys_revoke.c
    1.17  3eb781fd8oRfPgH7qTh7xvgmwD6NgA tools/internal/xi_start.c
    1.18  3eb781fd0Eo9K1jEFCSAVzO51i_ngg tools/internal/xi_stop.c
    1.19  3eb781fd7211MZsLxJSiuy7W4KnJXg tools/internal/xi_vifinit
    1.20 @@ -194,6 +198,7 @@ 3ddb79beME_0abStePF6fU8XLuQnWw xen/drive
    1.21  3ddb79beNQVrdGyoI4njXhgAjD6a4A xen/drivers/block/genhd.c
    1.22  3ddb79beyWwLRP_BiM2t1JKgr_plEw xen/drivers/block/ll_rw_blk.c
    1.23  3e4a8cb7RhubVgsPwO7cK0pgAN8WCQ xen/drivers/block/xen_block.c
    1.24 +3f045882spujO81dMl-fYWGiZ8WcPw xen/drivers/block/xen_physdisk.c
    1.25  3e5d129asHNyZOjBKTkqs-9AFzxemA xen/drivers/block/xen_segment.c
    1.26  3e9c248afxxsnAzIt2na7Ej24yNFzg xen/drivers/cdrom/Makefile
    1.27  3e9c248ajUkn2W3n4vgm72Hp2ftZ8A xen/drivers/cdrom/cdrom.c
    1.28 @@ -481,6 +486,8 @@ 3e5a4e65iHEuC5sjFhj42XALYbLVRw xenolinux
    1.29  3e5a4e65pP5spJErBW69pJxSSdK9RA xenolinux-2.4.21-sparse/arch/xeno/drivers/block/xl_block.c
    1.30  3e67f822FOPwqHiaRKbrskgWgoNL5g xenolinux-2.4.21-sparse/arch/xeno/drivers/block/xl_block.h
    1.31  3e677190SjkzJIvFifRVeYpIZOCtYA xenolinux-2.4.21-sparse/arch/xeno/drivers/block/xl_ide.c
    1.32 +3f045897EIYU5l5jxFBpeF1Z0ZOTwA xenolinux-2.4.21-sparse/arch/xeno/drivers/block/xl_physdisk_proc.c
    1.33 +3f045a16wW57GFQ3r3Ta2cJOo1ierQ xenolinux-2.4.21-sparse/arch/xeno/drivers/block/xl_physdisk_proc.c~
    1.34  3e677193nOKKTLJzcAu4SYdbZaia8g xenolinux-2.4.21-sparse/arch/xeno/drivers/block/xl_scsi.c
    1.35  3e676eb5RXnHzSHgA1BvM0B1aIm4qg xenolinux-2.4.21-sparse/arch/xeno/drivers/block/xl_segment.c
    1.36  3e5d129aDldt6geU2-2SzBae34sQzg xenolinux-2.4.21-sparse/arch/xeno/drivers/block/xl_segment_proc.c
     2.1 --- a/tools/internal/Makefile	Tue Jul 01 14:17:01 2003 +0000
     2.2 +++ b/tools/internal/Makefile	Thu Jul 03 16:30:18 2003 +0000
     2.3 @@ -4,13 +4,18 @@ XI_START = xi_start
     2.4  XI_STOP = xi_stop
     2.5  XI_DESTROY = xi_destroy
     2.6  XI_BUILD = xi_build
     2.7 +XI_PHYS_GRANT = xi_phys_grant
     2.8 +XI_PHYS_REVOKE = xi_phys_revoke
     2.9  
    2.10 -all: $(XI_CREATE).o $(XI_START).o $(XI_STOP).o $(XI_DESTROY).o $(XI_BUILD).o
    2.11 +all: $(XI_CREATE).o $(XI_START).o $(XI_STOP).o $(XI_DESTROY).o $(XI_BUILD).o \
    2.12 +	$(XI_PHYS_GRANT).o $(XI_PHYS_REVOKE).o
    2.13  	$(CC) -o $(XI_CREATE) $(XI_CREATE).o
    2.14  	$(CC) -o $(XI_BUILD) $(XI_BUILD).o
    2.15  	$(CC) -o $(XI_START) $(XI_START).o
    2.16  	$(CC) -o $(XI_STOP) $(XI_STOP).o
    2.17  	$(CC) -o $(XI_DESTROY) $(XI_DESTROY).o
    2.18 +	$(CC) -o $(XI_PHYS_GRANT) $(XI_PHYS_GRANT).o
    2.19 +	$(CC) -o $(XI_PHYS_REVOKE) $(XI_PHYS_REVOKE).o
    2.20  
    2.21  $(XI_CREATE).o: $(XI_CREATE).c dom0_defs.h dom0_ops.h hypervisor_defs.h mem_defs.h
    2.22  	$(CC) -c $(XI_CREATE).c 
    2.23 @@ -27,8 +32,14 @@ internal_domain_build.o: internal_domain
    2.24  $(XI_DESTROY).o: $(XI_DESTROY).c dom0_ops.h dom0_defs.h
    2.25  	$(CC) -c $(XI_DESTROY).c 
    2.26  
    2.27 +$(XI_PHYS_GRANT).o: $(XI_PHYS_GRANT).c physdev.h
    2.28 +	$(CC) -c $(XI_PHYS_GRANT).c 
    2.29 +
    2.30 +$(XI_PHYS_REVOKE).o: $(XI_PHYS_REVOKE).c physdev.h
    2.31 +	$(CC) -c $(XI_PHYS_REVOKE).c 
    2.32 +
    2.33  install: all
    2.34 -	cp -a xi_list xi_vifinit xi_helper $(XI_CREATE) $(XI_BUILD) $(XI_START) $(XI_STOP) $(XI_DESTROY) ../../../install/bin
    2.35 +	cp -a xi_list xi_vifinit xi_helper $(XI_CREATE) $(XI_BUILD) $(XI_START) $(XI_STOP) $(XI_DESTROY) $(XI_PHYSDEV_GRANT) $(XI_PHYS_REVOKE) ../../../install/bin
    2.36  	chmod 755 ../../../install/bin/xi_list
    2.37  	chmod 755 ../../../install/bin/xi_vifinit
    2.38  	chmod 755 ../../../install/bin/xi_helper
    2.39 @@ -42,5 +53,5 @@ rpm: all
    2.40  	rm -rf staging
    2.41  
    2.42  clean:
    2.43 -	$(RM) *.o *.rpm $(XI_CREATE) $(XI_START) $(XI_STOP) $(XI_DESTROY) $(XI_BUILD)
    2.44 +	$(RM) *.o *.rpm $(XI_CREATE) $(XI_START) $(XI_STOP) $(XI_DESTROY) $(XI_BUILD) $(XI_PHYSDEV_GRANT)
    2.45  
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/tools/internal/physdev.h	Thu Jul 03 16:30:18 2003 +0000
     3.3 @@ -0,0 +1,26 @@
     3.4 +#define XEN_BLOCK_PHYSDEV_GRANT 10 /* grant access to range of disk blocks */
     3.5 +#define XEN_BLOCK_PHYSDEV_REVOKE 11 /* revoke access to range of disk blocks */
     3.6 +#define XEN_BLOCK_PHYSDEV_PROBE 12 /* probe for a domain's physdev
     3.7 +				      accesses */
     3.8 +
     3.9 +typedef struct xp_disk
    3.10 +{
    3.11 +  int mode;
    3.12 +  int domain;
    3.13 +  unsigned short device;
    3.14 +  unsigned long start_sect;
    3.15 +  unsigned long n_sectors;
    3.16 +} xp_disk_t;
    3.17 +
    3.18 +#define PHYSDISK_MAX_ACES_PER_REQUEST 254
    3.19 +typedef struct {
    3.20 +  int n_aces;
    3.21 +  int domain;
    3.22 +  int start_ind;
    3.23 +  struct {
    3.24 +    unsigned short device;
    3.25 +    unsigned long start_sect;
    3.26 +    unsigned long n_sectors;
    3.27 +    unsigned mode;
    3.28 +  } entries[PHYSDISK_MAX_ACES_PER_REQUEST];
    3.29 +} physdisk_probebuf_t;
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/tools/internal/xi_phys_grant.c	Thu Jul 03 16:30:18 2003 +0000
     4.3 @@ -0,0 +1,43 @@
     4.4 +#include <unistd.h>
     4.5 +#include <stdio.h>
     4.6 +#include <errno.h>
     4.7 +#include <sys/fcntl.h>
     4.8 +
     4.9 +#include "physdev.h"
    4.10 +
    4.11 +int main(int argc, char *argv[])
    4.12 +{
    4.13 +  xp_disk_t buf;
    4.14 +  int fd;
    4.15 +
    4.16 +  if (argc != 6) {
    4.17 +    fprintf(stderr, "Usage: xi_physdev_grant <r/rw> <domain> <device> <start sector> <n_sectors>\n");
    4.18 +    return 1;
    4.19 +  }
    4.20 +
    4.21 +  buf.mode = 0;
    4.22 +  if (argv[1][0] == 'r')
    4.23 +    buf.mode |= 1;
    4.24 +  else if (argv[1][0] == 'w')
    4.25 +    buf.mode |= 2;
    4.26 +  if (argv[1][1] == 'r')
    4.27 +    buf.mode |= 1;
    4.28 +  else if (argv[1][1] == 'w')
    4.29 +    buf.mode |= 2;
    4.30 +  
    4.31 +  buf.domain = atol(argv[2]);
    4.32 +  buf.device = atol(argv[3]);
    4.33 +  buf.start_sect = atol(argv[4]);
    4.34 +  buf.n_sectors = atol(argv[5]);
    4.35 +
    4.36 +  fd = open("/proc/xeno/dom0/phd", O_WRONLY);
    4.37 +  if (fd < 0) {
    4.38 +    fprintf(stderr, "Can\'t open /proc/xeno/dom0/phd: %s.\n", strerror(errno));
    4.39 +    return 1;
    4.40 +  }
    4.41 +
    4.42 +  write(fd, &buf, sizeof(buf));
    4.43 +  close(fd);
    4.44 +
    4.45 +  return 0;
    4.46 +}
     5.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.2 +++ b/tools/internal/xi_phys_probe.c	Thu Jul 03 16:30:18 2003 +0000
     5.3 @@ -0,0 +1,48 @@
     5.4 +#include <stdio.h>
     5.5 +#include <sys/fcntl.h>
     5.6 +#include <errno.h>
     5.7 +#include <unistd.h>
     5.8 +#include <string.h>
     5.9 +
    5.10 +#include "physdev.h"
    5.11 +
    5.12 +int main(int argc, char *argv[])
    5.13 +{
    5.14 +  physdisk_probebuf_t buf;
    5.15 +  int fd;
    5.16 +  int x;
    5.17 +
    5.18 +  if (argc != 2) {
    5.19 +    fprintf(stderr, "Usage: xi_phys_probe <domain_nr>\n");
    5.20 +    return 1;
    5.21 +  }
    5.22 +
    5.23 +  fd = open("/proc/xeno/dom0/phd", O_RDONLY);
    5.24 +  if (fd < 0) {
    5.25 +    fprintf(stderr, "Can\'t open /proc/xeno/dom0/phd: %s.\n",
    5.26 +	    strerror(errno));
    5.27 +    return 1;
    5.28 +  }
    5.29 +
    5.30 +  memset(&buf, 0, sizeof(buf));
    5.31 +  buf.n_aces = PHYSDISK_MAX_ACES_PER_REQUEST;
    5.32 +  while (buf.n_aces == PHYSDISK_MAX_ACES_PER_REQUEST ||
    5.33 +	 buf.n_aces == 0) {
    5.34 +    buf.n_aces = PHYSDISK_MAX_ACES_PER_REQUEST;
    5.35 +    buf.domain = atol(argv[1]);
    5.36 +    read(fd, &buf, sizeof(buf));
    5.37 +    if (!buf.n_aces)
    5.38 +      break;
    5.39 +
    5.40 +    printf("Found %d ACEs\n", buf.n_aces);
    5.41 +
    5.42 +    for (x = 0; x < buf.n_aces; x++) {
    5.43 +      printf("%x:[%x,%x) : %x\n", buf.entries[x].device,
    5.44 +	     buf.entries[x].start_sect,
    5.45 +	     buf.entries[x].start_sect  + buf.entries[x].n_sectors,
    5.46 +	     buf.entries[x].mode);
    5.47 +    }
    5.48 +    buf.start_ind += buf.n_aces;
    5.49 +  }
    5.50 +  return 0;
    5.51 +}
     6.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.2 +++ b/tools/internal/xi_phys_revoke.c	Thu Jul 03 16:30:18 2003 +0000
     6.3 @@ -0,0 +1,33 @@
     6.4 +#include <unistd.h>
     6.5 +#include <errno.h>
     6.6 +#include <stdio.h>
     6.7 +#include <sys/fcntl.h>
     6.8 +
     6.9 +#include "physdev.h"
    6.10 +
    6.11 +int main(int argc, char *argv[])
    6.12 +{
    6.13 +  xp_disk_t buf;
    6.14 +  int fd;
    6.15 +
    6.16 +  if (argc != 5) {
    6.17 +    fprintf(stderr, "Usage: xi_physdev_revoke <domain> <device> <start sector> <n_sectors>\n");
    6.18 +    return 1;
    6.19 +  }
    6.20 +
    6.21 +  buf.domain = atol(argv[1]);
    6.22 +  buf.device = atol(argv[2]);
    6.23 +  buf.start_sect = atol(argv[3]);
    6.24 +  buf.n_sectors = atol(argv[4]);
    6.25 +
    6.26 +  fd = open("/proc/xeno/dom0/phd", O_WRONLY);
    6.27 +  if (fd < 0) {
    6.28 +    fprintf(stderr, "Can\'t open /proc/xeno/dom0/phd: %s.\n", strerror(errno));
    6.29 +    return 1;
    6.30 +  }
    6.31 +
    6.32 +  write(fd, &buf, sizeof(buf));
    6.33 +  close(fd);
    6.34 +
    6.35 +  return 0;
    6.36 +}
     7.1 --- a/xen/common/domain.c	Tue Jul 01 14:17:01 2003 +0000
     7.2 +++ b/xen/common/domain.c	Thu Jul 03 16:30:18 2003 +0000
     7.3 @@ -52,6 +52,7 @@ struct task_struct *do_newdomain(unsigne
     7.4  
     7.5      spin_lock_init(&p->blk_ring_lock);
     7.6      spin_lock_init(&p->page_lock);
     7.7 +    spin_lock_init(&p->physdev_lock);
     7.8  
     7.9      p->shared_info = (void *)get_free_page(GFP_KERNEL);
    7.10      memset(p->shared_info, 0, PAGE_SIZE);
    7.11 @@ -62,6 +63,8 @@ struct task_struct *do_newdomain(unsigne
    7.12  
    7.13      init_blkdev_info(p);
    7.14  
    7.15 +    INIT_LIST_HEAD(&p->physdisk_aces);
    7.16 +
    7.17      SET_GDT_ENTRIES(p, DEFAULT_GDT_ENTRIES);
    7.18      SET_GDT_ADDRESS(p, DEFAULT_GDT_ADDRESS);
    7.19  
    7.20 @@ -303,6 +306,9 @@ void release_task(struct task_struct *p)
    7.21       */
    7.22      destroy_blkdev_info(p);
    7.23  
    7.24 +    /* Free up the physdisk access control info */
    7.25 +    destroy_physdisk_aces(p);
    7.26 +
    7.27      /* Free all memory associated with this domain. */
    7.28      free_page((unsigned long)p->mm.perdomain_pt);
    7.29      UNSHARE_PFN(virt_to_page(p->shared_info));
     8.1 --- a/xen/drivers/block/xen_block.c	Tue Jul 01 14:17:01 2003 +0000
     8.2 +++ b/xen/drivers/block/xen_block.c	Thu Jul 03 16:30:18 2003 +0000
     8.3 @@ -104,6 +104,9 @@ static void dispatch_probe_seg(struct ta
     8.4  static void dispatch_debug_block_io(struct task_struct *p, int index);
     8.5  static void dispatch_create_segment(struct task_struct *p, int index);
     8.6  static void dispatch_delete_segment(struct task_struct *p, int index);
     8.7 +static void dispatch_grant_physdev(struct task_struct *p, int index);
     8.8 +static void dispatch_revoke_physdev(struct task_struct *p, int index);
     8.9 +static void dispatch_probe_physdev(struct task_struct *p, int index);
    8.10  static void make_response(struct task_struct *p, unsigned long id, 
    8.11                            unsigned short op, unsigned long st);
    8.12  
    8.13 @@ -396,6 +399,18 @@ static int do_block_io_op_domain(struct 
    8.14  	    dispatch_delete_segment(p, i);
    8.15  	    break;
    8.16  
    8.17 +	case XEN_BLOCK_PHYSDEV_GRANT:
    8.18 +  	    dispatch_grant_physdev(p, i);
    8.19 +	    break;
    8.20 +
    8.21 +	case XEN_BLOCK_PHYSDEV_REVOKE:
    8.22 + 	    dispatch_revoke_physdev(p, i);
    8.23 +	    break;
    8.24 +
    8.25 +	case XEN_BLOCK_PHYSDEV_PROBE:
    8.26 + 	    dispatch_probe_physdev(p, i);
    8.27 +	    break;
    8.28 +
    8.29  	default:
    8.30              DPRINTK("error: unknown block io operation [%d]\n",
    8.31                      blk_ring->ring[i].req.operation);
    8.32 @@ -414,6 +429,115 @@ static void dispatch_debug_block_io(stru
    8.33      DPRINTK("dispatch_debug_block_io: unimplemented\n"); 
    8.34  }
    8.35  
    8.36 +static void dispatch_probe_physdev(struct task_struct *p, int index)
    8.37 +{
    8.38 +    blk_ring_t *blk_ring = p->blk_ring_base;
    8.39 +    unsigned long flags, buffer;
    8.40 +    physdisk_probebuf_t *buf;
    8.41 +    int result;
    8.42 +
    8.43 +    if ( p->domain != 0 )
    8.44 +    {
    8.45 +        result = 1;
    8.46 +        goto out;
    8.47 +    }
    8.48 +
    8.49 +    buffer = blk_ring->ring[index].req.buffer_and_sects[0] & ~0x1FF;
    8.50 +
    8.51 +    spin_lock_irqsave(&p->page_lock, flags);
    8.52 +    if ( !__buffer_is_valid(p, buffer, sizeof(*buf), 1) )
    8.53 +    {
    8.54 +        spin_unlock_irqrestore(&p->page_lock, flags);
    8.55 +        result = 1;
    8.56 +        goto out;
    8.57 +    }
    8.58 +    __lock_buffer(buffer, sizeof(*buf), 1);
    8.59 +    spin_unlock_irqrestore(&p->page_lock, flags);
    8.60 +
    8.61 +    buf = phys_to_virt(buffer);
    8.62 +    result = xen_physdisk_probe(buf);
    8.63 +
    8.64 +    unlock_buffer(p, buffer, sizeof(*buf), 1);
    8.65 +
    8.66 + out:
    8.67 +    make_response(p, blk_ring->ring[index].req.id, 
    8.68 +                  XEN_BLOCK_PHYSDEV_PROBE, result); 
    8.69 +}
    8.70 +
    8.71 +static void dispatch_grant_physdev(struct task_struct *p, int index)
    8.72 +{
    8.73 +    blk_ring_t *blk_ring = p->blk_ring_base;
    8.74 +    unsigned long flags, buffer;
    8.75 +    xp_disk_t *xpd;
    8.76 +    int result;
    8.77 +
    8.78 +    if ( p->domain != 0 )
    8.79 +    {
    8.80 +        DPRINTK("dispatch_grant_physdev called by dom%d\n", p->domain);
    8.81 +        result = 1;
    8.82 +        goto out;
    8.83 +    }
    8.84 +
    8.85 +    buffer = blk_ring->ring[index].req.buffer_and_sects[0] & ~0x1FF;
    8.86 +
    8.87 +    spin_lock_irqsave(&p->page_lock, flags);
    8.88 +    if ( !__buffer_is_valid(p, buffer, sizeof(xv_disk_t), 1) )
    8.89 +    {
    8.90 +        DPRINTK("Bad buffer in dispatch_grant_physdev\n");
    8.91 +        spin_unlock_irqrestore(&p->page_lock, flags);
    8.92 +        result = 1;
    8.93 +        goto out;
    8.94 +    }
    8.95 +    __lock_buffer(buffer, sizeof(xv_disk_t), 1);
    8.96 +    spin_unlock_irqrestore(&p->page_lock, flags);
    8.97 +
    8.98 +    xpd = phys_to_virt(buffer);
    8.99 +    result = xen_physdisk_grant(xpd);
   8.100 +
   8.101 +    unlock_buffer(p, buffer, sizeof(xp_disk_t), 1);
   8.102 +
   8.103 + out:
   8.104 +    make_response(p, blk_ring->ring[index].req.id, 
   8.105 +                  XEN_BLOCK_PHYSDEV_GRANT, result); 
   8.106 +}
   8.107 +  
   8.108 +static void dispatch_revoke_physdev(struct task_struct *p, int index)
   8.109 +{
   8.110 +    blk_ring_t *blk_ring = p->blk_ring_base;
   8.111 +    unsigned long flags, buffer;
   8.112 +    xp_disk_t *xpd;
   8.113 +    int result;
   8.114 +
   8.115 +    if ( p->domain != 0 )
   8.116 +    {
   8.117 +        DPRINTK("dispatch_grant_physdev called by dom%d\n", p->domain);
   8.118 +        result = 1;
   8.119 +        goto out;
   8.120 +    }
   8.121 +
   8.122 +    buffer = blk_ring->ring[index].req.buffer_and_sects[0] & ~0x1FF;
   8.123 +
   8.124 +    spin_lock_irqsave(&p->page_lock, flags);
   8.125 +    if ( !__buffer_is_valid(p, buffer, sizeof(xv_disk_t), 1) )
   8.126 +    {
   8.127 +        DPRINTK("Bad buffer in dispatch_grant_physdev\n");
   8.128 +        spin_unlock_irqrestore(&p->page_lock, flags);
   8.129 +        result = 1;
   8.130 +        goto out;
   8.131 +    }
   8.132 +    __lock_buffer(buffer, sizeof(xv_disk_t), 1);
   8.133 +    spin_unlock_irqrestore(&p->page_lock, flags);
   8.134 +
   8.135 +    xpd = phys_to_virt(buffer);
   8.136 +    result = xen_physdisk_revoke(xpd);
   8.137 +
   8.138 +    unlock_buffer(p, buffer, sizeof(xp_disk_t), 1);
   8.139 +
   8.140 + out:
   8.141 +    make_response(p, blk_ring->ring[index].req.id, 
   8.142 +                  XEN_BLOCK_PHYSDEV_REVOKE, result); 
   8.143 +}
   8.144 +
   8.145  static void dispatch_create_segment(struct task_struct *p, int index)
   8.146  {
   8.147      blk_ring_t *blk_ring = p->blk_ring_base;
   8.148 @@ -593,6 +717,12 @@ static void dispatch_rw_block_io(struct 
   8.149  	        DPRINTK("bad device\n");
   8.150  	        goto bad_descriptor;
   8.151  	    }
   8.152 +	    if (p->domain != 0 &&
   8.153 +		!xen_physdisk_access_okay(&phys_seg, p, operation)) {
   8.154 +	      DPRINTK("access denied\n");
   8.155 +	      /* XXX not quite right, but close enough. */
   8.156 +	      goto bad_descriptor;
   8.157 +	    }
   8.158              new_segs = 1;
   8.159          }
   8.160          
     9.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     9.2 +++ b/xen/drivers/block/xen_physdisk.c	Thu Jul 03 16:30:18 2003 +0000
     9.3 @@ -0,0 +1,301 @@
     9.4 +#include <xeno/sched.h>
     9.5 +#include <xeno/list.h>
     9.6 +#include <xeno/blkdev.h>
     9.7 +#include <xeno/sched.h>
     9.8 +#include <xeno/slab.h>
     9.9 +#include <asm/domain_page.h>
    9.10 +#include <asm/io.h>
    9.11 +#include <xeno/segment.h>
    9.12 +
    9.13 +#define MAX(a,b) ((a) > (b) ? (a) : (b))
    9.14 +
    9.15 +#if 0
    9.16 +#define DPRINTK printk
    9.17 +#else
    9.18 +#define DPRINTK(...)
    9.19 +#endif
    9.20 +
    9.21 +/* The idea is that, for each sector of each disk, each domain has two
    9.22 +   bits, saying whether they can read the sector or write it.  That
    9.23 +   would take too much memory, so instead each process has a list of
    9.24 +   (device, start, end, mode) quads which say what it has access to,
    9.25 +   and we fake the logical view on top of that. */
    9.26 +struct physdisk_ace {
    9.27 +  struct list_head list;
    9.28 +
    9.29 +  unsigned short device;
    9.30 +  unsigned long start_sect;
    9.31 +  unsigned long n_sectors;
    9.32 +#define PHYSDISK_MODE_R 1
    9.33 +#define PHYSDISK_MODE_W 2
    9.34 +  int mode;
    9.35 +};
    9.36 +
    9.37 +/* Operation is a blkdev constant i.e. READ, WRITE, ... */
    9.38 +/* Must be called with p->physdev_lock held. */
    9.39 +static struct physdisk_ace *find_ace(const struct task_struct *p,
    9.40 +				     unsigned short dev,
    9.41 +				     unsigned long sect,
    9.42 +				     int operation)
    9.43 +{
    9.44 +  struct list_head *cur_ace_head;
    9.45 +  struct physdisk_ace *cur_ace;
    9.46 +
    9.47 +  list_for_each(cur_ace_head, &p->physdisk_aces) {
    9.48 +    cur_ace = list_entry(cur_ace_head, struct physdisk_ace,
    9.49 +			 list);
    9.50 +    DPRINTK("Is [%lx, %lx) good for %lx?\n",
    9.51 +	    cur_ace->start_sect, cur_ace->start_sect + cur_ace->n_sectors,
    9.52 +	    sect);
    9.53 +    if (sect >= cur_ace->start_sect &&
    9.54 +	sect < cur_ace->start_sect + cur_ace->n_sectors &&
    9.55 +	dev == cur_ace->device &&
    9.56 +	((operation == READ && (cur_ace->mode & PHYSDISK_MODE_R)) ||
    9.57 +	 (operation == WRITE && (cur_ace->mode & PHYSDISK_MODE_W)))) {
    9.58 +      DPRINTK("Yes.\n");
    9.59 +      return cur_ace;
    9.60 +    } else {
    9.61 +      DPRINTK("No.\n");
    9.62 +    }
    9.63 +  }
    9.64 +  return NULL;
    9.65 +}
    9.66 +
    9.67 +/* Hold the lock on entry, it remains held on exit. */
    9.68 +/* XXX we call kmalloc and kfree with GFP_KERNEL and a spinlock held
    9.69 +   in here.  That wouldn't be allowed under Linux, but, from reading
    9.70 +   the source, it seems to be okay under Xen... */
    9.71 +static void xen_physdisk_revoke_access(unsigned short dev,
    9.72 +				       unsigned long start_sect,
    9.73 +				       unsigned long n_sectors,
    9.74 +				       struct task_struct *p)
    9.75 +{
    9.76 +  /* Find every ace which intersects [start_sect, start_sect +
    9.77 +     n_sectors] and either remove it completely or truncate it
    9.78 +     down. */
    9.79 +  struct list_head *cur_ace_head;
    9.80 +  struct physdisk_ace *cur_ace, *new_ace;
    9.81 +  unsigned long kill_zone_end, ace_end;
    9.82 +
    9.83 +  kill_zone_end = start_sect + n_sectors;
    9.84 +  list_for_each(cur_ace_head, &p->physdisk_aces) {
    9.85 +    cur_ace = list_entry(cur_ace_head, struct physdisk_ace,
    9.86 +			 list);
    9.87 +    ace_end = cur_ace->start_sect + cur_ace->n_sectors;
    9.88 +    if (cur_ace->start_sect > kill_zone_end ||
    9.89 +	ace_end < start_sect)
    9.90 +      continue;
    9.91 +    
    9.92 +    if (cur_ace->start_sect >= start_sect &&
    9.93 +	ace_end < kill_zone_end) {
    9.94 +      /* ace entirely within kill zone -> kill it */
    9.95 +      list_del(cur_ace_head);
    9.96 +      cur_ace_head = cur_ace_head->next;
    9.97 +      kfree(cur_ace);
    9.98 +    } else if (ace_end < kill_zone_end) {
    9.99 +      /* ace start before kill start, ace end in kill zone, 
   9.100 +	 move ace end. */
   9.101 +      cur_ace->n_sectors = start_sect - cur_ace->start_sect;
   9.102 +    } else if (cur_ace->start_sect >= start_sect) {
   9.103 +      /* ace start after kill start, ace end outside kill zone,
   9.104 +	 move ace start. */
   9.105 +      cur_ace->start_sect = kill_zone_end;
   9.106 +      cur_ace->n_sectors = ace_end - cur_ace->start_sect;
   9.107 +    } else {
   9.108 +      /* The fun one: the kill zone entirely includes the ace. */
   9.109 +      /* Cut the current ace down to just the bit before the kzone,
   9.110 +	 create a new ace for the bit just after it. */
   9.111 +      new_ace = kmalloc(sizeof(*cur_ace), GFP_KERNEL);
   9.112 +      new_ace->device = dev;
   9.113 +      new_ace->start_sect = kill_zone_end;
   9.114 +      new_ace->n_sectors = ace_end - kill_zone_end;
   9.115 +      new_ace->mode = cur_ace->mode;
   9.116 +
   9.117 +      cur_ace->n_sectors = start_sect - cur_ace->start_sect;
   9.118 +
   9.119 +      list_add(&new_ace->list, cur_ace_head);
   9.120 +      cur_ace_head = new_ace->list.next;
   9.121 +    }
   9.122 +  }
   9.123 +}
   9.124 +
   9.125 +/* Hold the lock on entry, it remains held on exit. */
   9.126 +static int xen_physdisk_grant_access(unsigned short dev,
   9.127 +				     unsigned long start_sect,
   9.128 +				     unsigned long n_sectors,
   9.129 +				     int mode,
   9.130 +				     struct task_struct *p)
   9.131 +{
   9.132 +  struct physdisk_ace *cur_ace;
   9.133 +
   9.134 +  /* Make sure it won't overlap with any existing ACEs. */
   9.135 +  /* XXX this isn't quite right if the domain already has read access
   9.136 +     and we try to grant write access, or vice versa. */
   9.137 +  xen_physdisk_revoke_access(dev, start_sect, n_sectors, p);
   9.138 +  
   9.139 +  cur_ace = kmalloc(sizeof(*cur_ace), GFP_KERNEL);
   9.140 +  cur_ace->device = dev;
   9.141 +  cur_ace->start_sect = start_sect;
   9.142 +  cur_ace->n_sectors = n_sectors;
   9.143 +  cur_ace->mode = mode;
   9.144 +
   9.145 +  list_add_tail(&cur_ace->list, &p->physdisk_aces);
   9.146 +
   9.147 +  return 0;
   9.148 +}
   9.149 +
   9.150 +static void xen_physdisk_probe_access(physdisk_probebuf_t *buf,
   9.151 +				      struct task_struct *p)
   9.152 +{
   9.153 +  int max_aces;
   9.154 +  int n_aces;
   9.155 +  struct list_head *cur_ace_head;
   9.156 +  struct physdisk_ace *cur_ace;
   9.157 +  int x;
   9.158 +
   9.159 +  max_aces = buf->n_aces;
   9.160 +  n_aces = 0;
   9.161 +  list_for_each(cur_ace_head, &p->physdisk_aces) {
   9.162 +    if (x < buf->start_ind) {
   9.163 +      x++;
   9.164 +      continue;
   9.165 +    }
   9.166 +    cur_ace = list_entry(cur_ace_head, struct physdisk_ace,
   9.167 +			 list);
   9.168 +    buf->entries[n_aces].device = cur_ace->device;
   9.169 +    buf->entries[n_aces].start_sect = cur_ace->start_sect;
   9.170 +    buf->entries[n_aces].n_sectors = cur_ace->n_sectors;
   9.171 +    buf->entries[n_aces].mode = cur_ace->mode;
   9.172 +    n_aces++;
   9.173 +    if (n_aces >= max_aces)
   9.174 +      break;
   9.175 +  }
   9.176 +  buf->n_aces = n_aces;
   9.177 +  printk("Found a total of %x aces (max %x).\n", n_aces, max_aces);
   9.178 +}
   9.179 +
   9.180 +int xen_physdisk_grant(xp_disk_t *xpd_in)
   9.181 +{
   9.182 +  struct task_struct *p;
   9.183 +  xp_disk_t *xpd = map_domain_mem(virt_to_phys(xpd_in));
   9.184 +  int res;
   9.185 +
   9.186 +  p = current;
   9.187 +  DPRINTK("Have current.\n");
   9.188 +  DPRINTK("Target domain %x\n", xpd->domain);
   9.189 +
   9.190 +  do {
   9.191 +    p = p->next_task;
   9.192 +  } while (p != current && p->domain != xpd->domain);
   9.193 +  if (p->domain != xpd->domain) {
   9.194 +    DPRINTK("Bad domain! No biscuit!\n");
   9.195 +    res = 1;
   9.196 +    goto out;
   9.197 +  }
   9.198 +  spin_lock(&p->physdev_lock);
   9.199 +  res = xen_physdisk_grant_access(xpd->device,
   9.200 +				  xpd->start_sect,
   9.201 +				  xpd->n_sectors,
   9.202 +				  xpd->mode,
   9.203 +				  p);
   9.204 +  spin_unlock(&p->physdev_lock);
   9.205 +
   9.206 + out:
   9.207 +  unmap_domain_mem(xpd);
   9.208 +  return res;
   9.209 +}
   9.210 +
   9.211 +int xen_physdisk_revoke(xp_disk_t *xpd_in)
   9.212 +{
   9.213 +  struct task_struct *p;
   9.214 +  xp_disk_t *xpd = map_domain_mem(virt_to_phys(xpd_in));
   9.215 +  int res;
   9.216 +
   9.217 +  p = current;
   9.218 +
   9.219 +  do {
   9.220 +    p = p->next_task;
   9.221 +  } while (p != current && p->domain != xpd->domain);
   9.222 +  if (p->domain != xpd->domain) {
   9.223 +    res = 1;
   9.224 +    goto out;
   9.225 +  }
   9.226 +  spin_lock(&p->physdev_lock);
   9.227 +  xen_physdisk_revoke_access(xpd->device,
   9.228 +			     xpd->start_sect,
   9.229 +			     xpd->n_sectors,
   9.230 +			     p);
   9.231 +  spin_unlock(&p->physdev_lock);
   9.232 +  res = 0;
   9.233 + out:
   9.234 +  unmap_domain_mem(xpd);
   9.235 +  return res;
   9.236 +}
   9.237 +
   9.238 +int xen_physdisk_probe(physdisk_probebuf_t *buf_in)
   9.239 +{
   9.240 +  struct task_struct *p;
   9.241 +  physdisk_probebuf_t *buf = map_domain_mem(virt_to_phys(buf_in));
   9.242 +  int res;
   9.243 +
   9.244 +  p = current;
   9.245 +  do {
   9.246 +    p = p->next_task;
   9.247 +  } while (p != current && p->domain != buf->domain);
   9.248 +  if (p->domain != buf->domain) {
   9.249 +    res = 1;
   9.250 +    goto out;
   9.251 +  }
   9.252 +  printk("initially %x aces.\n", buf->n_aces);
   9.253 +  spin_lock(&p->physdev_lock);
   9.254 +  xen_physdisk_probe_access(buf, p);
   9.255 +  spin_unlock(&p->physdev_lock);
   9.256 +  printk("%x aces.\n", buf->n_aces);
   9.257 +  res = 0;
   9.258 + out:
   9.259 +  unmap_domain_mem(buf);
   9.260 +  return res;
   9.261 +}
   9.262 +
   9.263 +int xen_physdisk_access_okay(phys_seg_t *pseg, struct task_struct *p,
   9.264 +			     int operation)
   9.265 +{
   9.266 +  struct physdisk_ace *cur_ace;
   9.267 +  unsigned long sect;
   9.268 +
   9.269 +  DPRINTK("Checking access for domain %d, start sect %d, length %d.\n",
   9.270 +	  p->domain, pseg->sector_number, pseg->nr_sects);
   9.271 +
   9.272 +  for (sect = pseg->sector_number;
   9.273 +       sect < pseg->sector_number + pseg->nr_sects;
   9.274 +       ) {
   9.275 +    /* XXX this would be a lot faster if the aces were sorted on start
   9.276 +       address.  Also in revoke_access. */
   9.277 +    spin_lock(&p->physdev_lock);
   9.278 +    cur_ace = find_ace(p, pseg->dev, sect, operation);
   9.279 +    spin_unlock(&p->physdev_lock);
   9.280 +    if (!cur_ace) {
   9.281 +      /* Default closed. */
   9.282 +      return 0;
   9.283 +    }
   9.284 +    sect += MAX(cur_ace->n_sectors, pseg->nr_sects + pseg->sector_number - sect);
   9.285 +  }
   9.286 +  return 1;
   9.287 +}
   9.288 +
   9.289 +void destroy_physdisk_aces(struct task_struct *p)
   9.290 +{
   9.291 +  struct list_head *cur_ace_head, *next_head;
   9.292 +  struct physdisk_ace *cur_ace;
   9.293 +
   9.294 +  spin_lock(&p->physdev_lock); /* We never release this again. */
   9.295 +
   9.296 +  for (cur_ace_head = p->physdisk_aces.next;
   9.297 +       cur_ace_head != &p->physdisk_aces;
   9.298 +       cur_ace_head = next_head) {
   9.299 +    cur_ace = list_entry(cur_ace_head, struct physdisk_ace,
   9.300 +			 list);
   9.301 +    next_head = cur_ace_head->next;
   9.302 +    kfree(cur_ace);
   9.303 +  }
   9.304 +}
    10.1 --- a/xen/include/hypervisor-ifs/block.h	Tue Jul 01 14:17:01 2003 +0000
    10.2 +++ b/xen/include/hypervisor-ifs/block.h	Thu Jul 03 16:30:18 2003 +0000
    10.3 @@ -47,6 +47,10 @@
    10.4  #define XEN_BLOCK_SEG_CREATE   7  /* create segment (vhd) */
    10.5  #define XEN_BLOCK_SEG_DELETE   8  /* delete segment (vhd) */
    10.6  #define XEN_BLOCK_PROBE_SEG    9  /* get vhd config from hypervisor */
    10.7 +#define XEN_BLOCK_PHYSDEV_GRANT 10 /* grant access to range of disk blocks */
    10.8 +#define XEN_BLOCK_PHYSDEV_REVOKE 11 /* revoke access to range of disk blocks */
    10.9 +#define XEN_BLOCK_PHYSDEV_PROBE 12 /* probe for a domain's physdev
   10.10 +				      accesses */
   10.11  
   10.12  /* NB. Ring size must be small enough for sizeof(blk_ring_t) <= PAGE_SIZE. */
   10.13  #define BLK_RING_SIZE        64
   10.14 @@ -139,4 +143,26 @@ typedef struct xv_disk
   10.15    xv_extent_t extents[XEN_MAX_DISK_COUNT];    /* arbitrary reuse of constant */
   10.16  } xv_disk_t;
   10.17  
   10.18 +typedef struct xp_disk
   10.19 +{
   10.20 +  int mode;
   10.21 +  int domain;
   10.22 +  unsigned short device;
   10.23 +  unsigned long start_sect;
   10.24 +  unsigned long n_sectors;
   10.25 +} xp_disk_t;
   10.26 +
   10.27 +#define PHYSDISK_MAX_ACES_PER_REQUEST 254
   10.28 +typedef struct {
   10.29 +  int n_aces;
   10.30 +  int domain;
   10.31 +  int start_ind;
   10.32 +  struct {
   10.33 +    unsigned short device;
   10.34 +    unsigned long start_sect;
   10.35 +    unsigned long n_sectors;
   10.36 +    unsigned mode;
   10.37 +  } entries[PHYSDISK_MAX_ACES_PER_REQUEST];
   10.38 +} physdisk_probebuf_t;
   10.39 +
   10.40  #endif
    11.1 --- a/xen/include/xeno/sched.h	Tue Jul 01 14:17:01 2003 +0000
    11.2 +++ b/xen/include/xeno/sched.h	Thu Jul 03 16:30:18 2003 +0000
    11.3 @@ -133,6 +133,11 @@ struct task_struct
    11.4      unsigned int blk_resp_prod; /* (private version of) response producer */
    11.5      struct list_head blkdev_list;
    11.6      spinlock_t blk_ring_lock;
    11.7 +    struct list_head physdisk_aces; /* physdisk_ace structures
    11.8 +				       describing what bits of disk
    11.9 +				       the process can do raw access
   11.10 +				       to. */
   11.11 +    spinlock_t physdev_lock;
   11.12      segment_t *segment_list[XEN_MAX_SEGMENTS];                        /* xvd */
   11.13  
   11.14      /* VM */
    12.1 --- a/xenolinux-2.4.21-sparse/arch/xeno/drivers/block/Makefile	Tue Jul 01 14:17:01 2003 +0000
    12.2 +++ b/xenolinux-2.4.21-sparse/arch/xeno/drivers/block/Makefile	Thu Jul 03 16:30:18 2003 +0000
    12.3 @@ -1,3 +1,3 @@
    12.4  O_TARGET := blk.o
    12.5 -obj-y := xl_block.o xl_ide.o xl_scsi.o xl_segment.o xl_segment_proc.o
    12.6 +obj-y := xl_block.o xl_ide.o xl_scsi.o xl_segment.o xl_segment_proc.o xl_physdisk_proc.o
    12.7  include $(TOPDIR)/Rules.make
    13.1 --- a/xenolinux-2.4.21-sparse/arch/xeno/drivers/block/xl_block.c	Tue Jul 01 14:17:01 2003 +0000
    13.2 +++ b/xenolinux-2.4.21-sparse/arch/xeno/drivers/block/xl_block.c	Thu Jul 03 16:30:18 2003 +0000
    13.3 @@ -307,6 +307,9 @@ static int hypervisor_request(unsigned l
    13.4      {
    13.5      case XEN_BLOCK_SEG_CREATE:
    13.6      case XEN_BLOCK_SEG_DELETE:
    13.7 +    case XEN_BLOCK_PHYSDEV_GRANT:
    13.8 +    case XEN_BLOCK_PHYSDEV_REVOKE:
    13.9 +    case XEN_BLOCK_PHYSDEV_PROBE:
   13.10      case XEN_BLOCK_PROBE_BLK:
   13.11      case XEN_BLOCK_PROBE_SEG:
   13.12          if ( RING_FULL ) return 1;
   13.13 @@ -478,6 +481,9 @@ static void xlblk_response_int(int irq, 
   13.14          case XEN_BLOCK_SEG_DELETE:
   13.15          case XEN_BLOCK_PROBE_SEG:
   13.16          case XEN_BLOCK_PROBE_BLK:
   13.17 +	case XEN_BLOCK_PHYSDEV_GRANT:
   13.18 +	case XEN_BLOCK_PHYSDEV_REVOKE:
   13.19 +	case XEN_BLOCK_PHYSDEV_PROBE:
   13.20              if ( bret->status )
   13.21                  printk(KERN_ALERT "Bad return from blkdev control request\n");
   13.22              xlblk_control_msg_pending = 0;
    14.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    14.2 +++ b/xenolinux-2.4.21-sparse/arch/xeno/drivers/block/xl_physdisk_proc.c	Thu Jul 03 16:30:18 2003 +0000
    14.3 @@ -0,0 +1,94 @@
    14.4 +#include <linux/kernel.h>
    14.5 +#include <linux/module.h>
    14.6 +#include <linux/fs.h>
    14.7 +#include <asm/errno.h>
    14.8 +#include <linux/slab.h>
    14.9 +#include <asm/hypervisor-ifs/block.h>
   14.10 +#include <asm/uaccess.h>
   14.11 +#include <linux/proc_fs.h>
   14.12 +
   14.13 +static struct proc_dir_entry *phd;
   14.14 +
   14.15 +extern int xenolinux_control_msg(int operration, char *buffer, int size);
   14.16 +
   14.17 +static ssize_t proc_read_phd(struct file * file, char * buff, size_t size, loff_t * off)
   14.18 +{
   14.19 +  physdisk_probebuf_t *buf;
   14.20 +  int res;
   14.21 +
   14.22 +  if (size != sizeof(physdisk_probebuf_t))
   14.23 +    return -EINVAL;
   14.24 +
   14.25 +  buf = kmalloc(sizeof(physdisk_probebuf_t), GFP_KERNEL);
   14.26 +  if (!buf)
   14.27 +    return -ENOMEM;
   14.28 +
   14.29 +  if (copy_from_user(buf, buff, size)) {
   14.30 +    kfree(buf);
   14.31 +    return -EFAULT;
   14.32 +  }
   14.33 +
   14.34 +  printk("max aces 1 %x\n", buf->n_aces);
   14.35 +
   14.36 +  res = xenolinux_control_msg(XEN_BLOCK_PHYSDEV_PROBE, (void *)buf,
   14.37 +			      sizeof(physdisk_probebuf_t));
   14.38 +
   14.39 +  printk("max aces %x\n", buf->n_aces);
   14.40 +
   14.41 +  if (res)
   14.42 +    res = -EINVAL;
   14.43 +  else {
   14.44 +    res = sizeof(physdisk_probebuf_t);
   14.45 +    if (copy_to_user(buff, buf, sizeof(physdisk_probebuf_t))) {
   14.46 +      res = -EFAULT;
   14.47 +    }
   14.48 +  }
   14.49 +  kfree(buf);
   14.50 +  return res;
   14.51 +}
   14.52 +
   14.53 +static int proc_write_phd(struct file *file, const char *buffer,
   14.54 +			  size_t count, loff_t *ignore)
   14.55 +{
   14.56 +  char *local;
   14.57 +  int res;
   14.58 +
   14.59 +  if (count != sizeof(xp_disk_t))
   14.60 +    return -EINVAL;
   14.61 +
   14.62 +  local = kmalloc(count + 1, GFP_KERNEL);
   14.63 +  if (!local)
   14.64 +    return -ENOMEM;
   14.65 +  if (copy_from_user(local, buffer, count)) {
   14.66 +    res = -EFAULT;
   14.67 +    goto out;
   14.68 +  }
   14.69 +  local[count] = 0;
   14.70 +
   14.71 +  res = xenolinux_control_msg(XEN_BLOCK_PHYSDEV_GRANT, local, count);
   14.72 +  if (res == 0)
   14.73 +    res = count;
   14.74 +  else
   14.75 +    res = -EINVAL;
   14.76 + out:
   14.77 +  kfree(local);
   14.78 +  return res;
   14.79 +}
   14.80 +
   14.81 +static struct file_operations proc_phd_fops = {
   14.82 +  read : proc_read_phd,
   14.83 +  write : proc_write_phd
   14.84 +};
   14.85 +
   14.86 +int __init xlphysdisk_proc_init(void)
   14.87 +{
   14.88 +  phd = create_proc_entry("xeno/dom0/phd", 0644, NULL);
   14.89 +  if (!phd) {
   14.90 +    panic("Can\'t create phd proc entry!\n");
   14.91 +  }
   14.92 +  phd->data = NULL;
   14.93 +  phd->proc_fops = &proc_phd_fops;
   14.94 +  phd->owner = THIS_MODULE;
   14.95 +
   14.96 +  return 0;
   14.97 +}
    15.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    15.2 +++ b/xenolinux-2.4.21-sparse/arch/xeno/drivers/block/xl_physdisk_proc.c~	Thu Jul 03 16:30:18 2003 +0000
    15.3 @@ -0,0 +1,94 @@
    15.4 +#include <linux/kernel.h>
    15.5 +#include <linux/module.h>
    15.6 +#include <linux/fs.h>
    15.7 +#include <asm/errno.h>
    15.8 +#include <linux/slab.h>
    15.9 +#include <asm/hypervisor-ifs/block.h>
   15.10 +#include <asm/uaccess.h>
   15.11 +#include <linux/proc_fs.h>
   15.12 +
   15.13 +static struct proc_dir_entry *phd;
   15.14 +
   15.15 +extern int xenolinux_control_msg(int operration, char *buffer, int size);
   15.16 +
   15.17 +static ssize_t proc_read_phd(struct file * file, char * buff, size_t size, loff_t * off)
   15.18 +{
   15.19 +  physdisk_probebuf_t *buf;
   15.20 +  int res;
   15.21 +
   15.22 +  if (size != sizeof(physdisk_probebuf_t))
   15.23 +    return -EINVAL;
   15.24 +
   15.25 +  buf = kmalloc(sizeof(physdisk_probebuf_t), GFP_KERNEL);
   15.26 +  if (!buf)
   15.27 +    return -ENOMEM;
   15.28 +
   15.29 +  if (copy_from_user(buf, buff, size)) {
   15.30 +    kfree(buf);
   15.31 +    return -EFAULT;
   15.32 +  }
   15.33 +
   15.34 +  printk("max aces %x\n", buf->n_aces);
   15.35 +
   15.36 +  res = xenolinux_control_msg(XEN_BLOCK_PHYSDEV_PROBE, (void *)buf,
   15.37 +			      sizeof(physdisk_probebuf_t));
   15.38 +
   15.39 +  printk("max aces %x\n", buf->n_aces);
   15.40 +
   15.41 +  if (res)
   15.42 +    res = -EINVAL;
   15.43 +  else {
   15.44 +    res = sizeof(physdisk_probebuf_t);
   15.45 +    if (copy_to_user(buff, buf, sizeof(physdisk_probebuf_t))) {
   15.46 +      res = -EFAULT;
   15.47 +    }
   15.48 +  }
   15.49 +  kfree(buf);
   15.50 +  return res;
   15.51 +}
   15.52 +
   15.53 +static int proc_write_phd(struct file *file, const char *buffer,
   15.54 +			  size_t count, loff_t *ignore)
   15.55 +{
   15.56 +  char *local;
   15.57 +  int res;
   15.58 +
   15.59 +  if (count != sizeof(xp_disk_t))
   15.60 +    return -EINVAL;
   15.61 +
   15.62 +  local = kmalloc(count + 1, GFP_KERNEL);
   15.63 +  if (!local)
   15.64 +    return -ENOMEM;
   15.65 +  if (copy_from_user(local, buffer, count)) {
   15.66 +    res = -EFAULT;
   15.67 +    goto out;
   15.68 +  }
   15.69 +  local[count] = 0;
   15.70 +
   15.71 +  res = xenolinux_control_msg(XEN_BLOCK_PHYSDEV_GRANT, local, count);
   15.72 +  if (res == 0)
   15.73 +    res = count;
   15.74 +  else
   15.75 +    res = -EINVAL;
   15.76 + out:
   15.77 +  kfree(local);
   15.78 +  return res;
   15.79 +}
   15.80 +
   15.81 +static struct file_operations proc_phd_fops = {
   15.82 +  read : proc_read_phd,
   15.83 +  write : proc_write_phd
   15.84 +};
   15.85 +
   15.86 +int __init xlphysdisk_proc_init(void)
   15.87 +{
   15.88 +  phd = create_proc_entry("xeno/dom0/phd", 0644, NULL);
   15.89 +  if (!phd) {
   15.90 +    panic("Can\'t create phd proc entry!\n");
   15.91 +  }
   15.92 +  phd->data = NULL;
   15.93 +  phd->proc_fops = &proc_phd_fops;
   15.94 +  phd->owner = THIS_MODULE;
   15.95 +
   15.96 +  return 0;
   15.97 +}
    16.1 --- a/xenolinux-2.4.21-sparse/drivers/block/ll_rw_blk.c	Tue Jul 01 14:17:01 2003 +0000
    16.2 +++ b/xenolinux-2.4.21-sparse/drivers/block/ll_rw_blk.c	Thu Jul 03 16:30:18 2003 +0000
    16.3 @@ -1505,6 +1505,7 @@ int __init blk_dev_init(void)
    16.4      xlblk_init();
    16.5      xlseg_init();
    16.6      xlseg_proc_init();
    16.7 +    xlphysdisk_proc_init();
    16.8  #endif
    16.9  
   16.10  	return 0;