ia64/xen-unstable

changeset 1339:a89fcff21552

bitkeeper revision 1.879.3.1 (4097a6f8Q5eWNArSydr2Qh2tZnFF4w)

Support for selectively granting IO resource privileges. Domains
that access physical devices now don't need to be fully privileged.
author mwilli2@equilibrium.research.intel-research.net
date Tue May 04 14:21:44 2004 +0000 (2004-05-04)
parents db0162779602
children 9e1ef2196d83
files tools/examples/xc_dom_create.py tools/xc/lib/xc.h tools/xc/lib/xc_linux_build.c tools/xc/lib/xc_netbsd_build.c tools/xc/py/Xc.c xen/arch/i386/irq.c xen/arch/i386/process.c xen/arch/i386/traps.c xen/common/physdev.c xen/include/asm-i386/processor.h xen/include/xen/sched.h
line diff
     1.1 --- a/tools/examples/xc_dom_create.py	Thu Apr 29 15:36:38 2004 +0000
     1.2 +++ b/tools/examples/xc_dom_create.py	Tue May 04 14:21:44 2004 +0000
     1.3 @@ -239,12 +239,8 @@ def make_domain():
     1.4  	xc.domain_destroy ( dom=id )
     1.5  	sys.exit()
     1.6  
     1.7 -    # will the domain have IO privileges?
     1.8 -    if pci_device_list != []: io_priv = True
     1.9 -    else:                     io_priv = False
    1.10 -
    1.11      if restore:
    1.12 -        ret = eval('xc.%s_restore ( dom=id, state_file=state_file, progress=1, io_priv=%d )' % (builder_fn, io_priv))
    1.13 +        ret = eval('xc.%s_restore ( dom=id, state_file=state_file, progress=1 )' % builder_fn )
    1.14          if ret < 0:
    1.15              print "Error restoring domain"
    1.16              print "Return code = " + str(ret)
    1.17 @@ -252,7 +248,7 @@ def make_domain():
    1.18              sys.exit()
    1.19      else:
    1.20  
    1.21 -        ret = eval('xc.%s_build ( dom=id, image=image, ramdisk=ramdisk, cmdline=cmdline, control_evtchn=xend_response["remote_port"], io_priv=%d )' % (builder_fn, io_priv) )
    1.22 +        ret = eval('xc.%s_build ( dom=id, image=image, ramdisk=ramdisk, cmdline=cmdline, control_evtchn=xend_response["remote_port"] )' % builder_fn )
    1.23          if ret < 0:
    1.24              print "Error building Linux guest OS: "
    1.25              print "Return code = " + str(ret)
     2.1 --- a/tools/xc/lib/xc.h	Thu Apr 29 15:36:38 2004 +0000
     2.2 +++ b/tools/xc/lib/xc.h	Tue May 04 14:21:44 2004 +0000
     2.3 @@ -74,15 +74,13 @@ int xc_linux_build(int xc_handle,
     2.4                     const char *image_name,
     2.5                     const char *ramdisk_name,
     2.6                     const char *cmdline,
     2.7 -                   unsigned int control_evtchn,
     2.8 -                   int io_priv);
     2.9 +                   unsigned int control_evtchn);
    2.10  
    2.11  int xc_netbsd_build(int xc_handle,
    2.12                      u64 domid,
    2.13                      const char *image_name,
    2.14                      const char *cmdline,
    2.15 -                    unsigned int control_evtchn,
    2.16 -                    int io_priv);
    2.17 +                    unsigned int control_evtchn);
    2.18  
    2.19  int xc_bvtsched_global_set(int xc_handle,
    2.20                             unsigned long ctx_allow);
     3.1 --- a/tools/xc/lib/xc_linux_build.c	Thu Apr 29 15:36:38 2004 +0000
     3.2 +++ b/tools/xc/lib/xc_linux_build.c	Tue May 04 14:21:44 2004 +0000
     3.3 @@ -73,8 +73,7 @@ static int setup_guestos(int xc_handle,
     3.4                           dom0_builddomain_t *builddomain, 
     3.5                           const char *cmdline,
     3.6                           unsigned long shared_info_frame,
     3.7 -                         unsigned int control_evtchn,
     3.8 -                         int io_priv)
     3.9 +                         unsigned int control_evtchn)
    3.10  {
    3.11      l1_pgentry_t *vl1tab=NULL, *vl1e=NULL;
    3.12      l2_pgentry_t *vl2tab=NULL, *vl2e=NULL;
    3.13 @@ -270,7 +269,7 @@ static int setup_guestos(int xc_handle,
    3.14      memset(start_info, 0, sizeof(*start_info));
    3.15      start_info->nr_pages     = nr_pages;
    3.16      start_info->shared_info  = shared_info_frame << PAGE_SHIFT;
    3.17 -    start_info->flags        = io_priv ? SIF_PRIVILEGED : 0;
    3.18 +    start_info->flags        = 0;
    3.19      start_info->pt_base      = vpt_start;
    3.20      start_info->nr_pt_frames = nr_pt_pages;
    3.21      start_info->mfn_list     = vphysmap_start;
    3.22 @@ -383,8 +382,7 @@ int xc_linux_build(int xc_handle,
    3.23                     const char *image_name,
    3.24                     const char *ramdisk_name,
    3.25                     const char *cmdline,
    3.26 -                   unsigned int control_evtchn,
    3.27 -                   int io_priv)
    3.28 +                   unsigned int control_evtchn)
    3.29  {
    3.30      dom0_op_t launch_op, op;
    3.31      int initrd_fd = -1;
    3.32 @@ -442,7 +440,7 @@ int xc_linux_build(int xc_handle,
    3.33                         &vstartinfo_start, &vkern_entry,
    3.34                         &launch_op.u.builddomain, cmdline,
    3.35                         op.u.getdomaininfo.shared_info_frame,
    3.36 -                       control_evtchn, io_priv) < 0 )
    3.37 +                       control_evtchn) < 0 )
    3.38      {
    3.39          ERROR("Error constructing guest OS");
    3.40          goto error_out;
     4.1 --- a/tools/xc/lib/xc_netbsd_build.c	Thu Apr 29 15:36:38 2004 +0000
     4.2 +++ b/tools/xc/lib/xc_netbsd_build.c	Tue May 04 14:21:44 2004 +0000
     4.3 @@ -62,8 +62,7 @@ static int setup_guestos(int xc_handle,
     4.4                           dom0_builddomain_t *builddomain, 
     4.5                           const char *cmdline,
     4.6                           unsigned long shared_info_frame,
     4.7 -                         unsigned int control_evtchn,
     4.8 -                         int io_priv)
     4.9 +                         unsigned int control_evtchn)
    4.10  {
    4.11      l1_pgentry_t *vl1tab=NULL, *vl1e=NULL;
    4.12      l2_pgentry_t *vl2tab=NULL, *vl2e=NULL;
    4.13 @@ -177,7 +176,7 @@ static int setup_guestos(int xc_handle,
    4.14      start_info->mod_len     = symtab_len;
    4.15      start_info->nr_pages    = tot_pages;
    4.16      start_info->shared_info = shared_info_frame << PAGE_SHIFT;
    4.17 -    start_info->flags       = io_priv ? SIF_PRIVILEGED : 0;
    4.18 +    start_info->flags       = 0;
    4.19      start_info->domain_controller_evtchn = control_evtchn;
    4.20      strncpy(start_info->cmd_line, cmdline, MAX_CMDLINE);
    4.21      start_info->cmd_line[MAX_CMDLINE-1] = '\0';
    4.22 @@ -214,8 +213,7 @@ int xc_netbsd_build(int xc_handle,
    4.23                      u64 domid,
    4.24                      const char *image_name,
    4.25                      const char *cmdline,
    4.26 -                    unsigned int control_evtchn,
    4.27 -                    int io_priv)
    4.28 +                    unsigned int control_evtchn)
    4.29  {
    4.30      dom0_op_t launch_op, op;
    4.31      unsigned long load_addr;
    4.32 @@ -265,7 +263,7 @@ int xc_netbsd_build(int xc_handle,
    4.33                         &virt_startinfo_addr,
    4.34                         &load_addr, &launch_op.u.builddomain, cmdline,
    4.35                         op.u.getdomaininfo.shared_info_frame,
    4.36 -                       control_evtchn, io_priv) < 0 )
    4.37 +                       control_evtchn) < 0 )
    4.38      {
    4.39          ERROR("Error constructing guest OS");
    4.40          goto error_out;
     5.1 --- a/tools/xc/py/Xc.c	Thu Apr 29 15:36:38 2004 +0000
     5.2 +++ b/tools/xc/py/Xc.c	Tue May 04 14:21:44 2004 +0000
     5.3 @@ -228,19 +228,18 @@ static PyObject *pyxc_linux_build(PyObje
     5.4  
     5.5      u64   dom;
     5.6      char *image, *ramdisk = NULL, *cmdline = "";
     5.7 -    int   control_evtchn, io_priv = 0;
     5.8 +    int   control_evtchn;
     5.9  
    5.10      static char *kwd_list[] = { "dom", "control_evtchn", 
    5.11 -                                "image", "ramdisk", "cmdline", "io_priv",
    5.12 -				NULL };
    5.13 +                                "image", "ramdisk", "cmdline", NULL };
    5.14  
    5.15 -    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "Lis|ssi", kwd_list, 
    5.16 +    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "Lis|ss", kwd_list, 
    5.17                                        &dom, &control_evtchn, 
    5.18 -                                      &image, &ramdisk, &cmdline, &io_priv) )
    5.19 +                                      &image, &ramdisk, &cmdline) )
    5.20          return NULL;
    5.21  
    5.22      if ( xc_linux_build(xc->xc_handle, dom, image, 
    5.23 -                        ramdisk, cmdline, control_evtchn, io_priv) != 0 )
    5.24 +                        ramdisk, cmdline, control_evtchn) != 0 )
    5.25          return PyErr_SetFromErrno(xc_error);
    5.26      
    5.27      Py_INCREF(zero);
    5.28 @@ -255,19 +254,18 @@ static PyObject *pyxc_netbsd_build(PyObj
    5.29  
    5.30      u64   dom;
    5.31      char *image, *ramdisk = NULL, *cmdline = "";
    5.32 -    int   control_evtchn, io_priv = 0;
    5.33 +    int   control_evtchn;
    5.34  
    5.35      static char *kwd_list[] = { "dom", "control_evtchn",
    5.36 -                                "image", "ramdisk", "cmdline", "io_priv",
    5.37 -				NULL };
    5.38 +                                "image", "ramdisk", "cmdline", NULL };
    5.39  
    5.40      if ( !PyArg_ParseTupleAndKeywords(args, kwds, "Lis|ssi", kwd_list, 
    5.41                                        &dom, &control_evtchn,
    5.42 -                                      &image, &ramdisk, &cmdline, &io_priv) )
    5.43 +                                      &image, &ramdisk, &cmdline) )
    5.44          return NULL;
    5.45  
    5.46      if ( xc_netbsd_build(xc->xc_handle, dom, image, 
    5.47 -                         cmdline, control_evtchn, io_priv) != 0 )
    5.48 +                         cmdline, control_evtchn) != 0 )
    5.49          return PyErr_SetFromErrno(xc_error);
    5.50      
    5.51      Py_INCREF(zero);
    5.52 @@ -1162,8 +1160,7 @@ static PyMethodDef pyxc_methods[] = {
    5.53        " dom     [long]:     Identifier of domain to build into.\n"
    5.54        " image   [str]:      Name of kernel image file. May be gzipped.\n"
    5.55        " ramdisk [str, n/a]: Name of ramdisk file, if any.\n"
    5.56 -      " cmdline [str, n/a]: Kernel parameters, if any.\n"
    5.57 -      " io_priv [boolean]:  Does the domain have IO privileges?\n\n"
    5.58 +      " cmdline [str, n/a]: Kernel parameters, if any.\n\n"
    5.59        "Returns: [int] 0 on success; -1 on error.\n" },
    5.60  
    5.61      { "netbsd_build", 
    5.62 @@ -1172,15 +1169,14 @@ static PyMethodDef pyxc_methods[] = {
    5.63        "Build a new NetBSD guest OS.\n"
    5.64        " dom     [long]:     Identifier of domain to build into.\n"
    5.65        " image   [str]:      Name of kernel image file. May be gzipped.\n"
    5.66 -      " cmdline [str, n/a]: Kernel parameters, if any.\n"
    5.67 -      " io_priv [boolean]:  Does the domain have IO privileges?\n\n"
    5.68 +      " cmdline [str, n/a]: Kernel parameters, if any.\n\n"
    5.69        "Returns: [int] 0 on success; -1 on error.\n" },
    5.70  
    5.71      { "bvtsched_global_set",
    5.72        (PyCFunction)pyxc_bvtsched_global_set,
    5.73        METH_VARARGS | METH_KEYWORDS, "\n"
    5.74        "Set global tuning parameters for Borrowed Virtual Time scheduler.\n"
    5.75 -      " ctx_allow [int]: Minimal guaranteed quantum (I think!).\n\n"
    5.76 +      " ctx_allow [int]: Minimal guaranteed quantum.\n\n"
    5.77        "Returns: [int] 0 on success; -1 on error.\n" },
    5.78  
    5.79      { "bvtsched_global_get",
    5.80 @@ -1195,10 +1191,10 @@ static PyMethodDef pyxc_methods[] = {
    5.81        METH_VARARGS | METH_KEYWORDS, "\n"
    5.82        "Set per-domain tuning parameters for Borrowed Virtual Time scheduler.\n"
    5.83        " dom    [long]: Identifier of domain to be tuned.\n"
    5.84 -      " mcuadv [int]:  Internal BVT parameter.\n"
    5.85 -      " warp   [int]:  Internal BVT parameter.\n"
    5.86 -      " warpl  [int]:  Internal BVT parameter.\n"
    5.87 -      " warpu  [int]:  Internal BVT parameter.\n\n"
    5.88 +      " mcuadv [int]:  Proportional to the inverse of the domain's weight.\n"
    5.89 +      " warp   [int]:  How far to warp domain's EVT on unblock.\n"
    5.90 +      " warpl  [int]:  How long the domain can run warped.\n"
    5.91 +      " warpu  [int]:  How long before the domain can warp again.\n\n"
    5.92        "Returns: [int] 0 on success; -1 on error.\n" },
    5.93  
    5.94      { "bvtsched_domain_get",
     6.1 --- a/xen/arch/i386/irq.c	Thu Apr 29 15:36:38 2004 +0000
     6.2 +++ b/xen/arch/i386/irq.c	Tue May 04 14:21:44 2004 +0000
     6.3 @@ -1001,7 +1001,7 @@ int pirq_guest_bind(struct task_struct *
     6.4      irq_guest_action_t *action;
     6.5      int rc = 0;
     6.6  
     6.7 -    if ( !IS_PRIV(p) )
     6.8 +    if ( !IS_CAPABLE_PHYSDEV(p) )
     6.9          return -EPERM;
    6.10  
    6.11      spin_lock_irqsave(&desc->lock, flags);
     7.1 --- a/xen/arch/i386/process.c	Thu Apr 29 15:36:38 2004 +0000
     7.2 +++ b/xen/arch/i386/process.c	Tue May 04 14:21:44 2004 +0000
     7.3 @@ -227,12 +227,14 @@ void new_thread(struct task_struct *p,
     7.4  			: /* no output */ \
     7.5  			:"r" (thread->debugreg[register]))
     7.6  
     7.7 +
     7.8  void switch_to(struct task_struct *prev_p, struct task_struct *next_p)
     7.9  {
    7.10      struct thread_struct *next = &next_p->thread;
    7.11      struct tss_struct *tss = init_tss + smp_processor_id();
    7.12      execution_context_t *stack_ec = get_execution_context();
    7.13 -
    7.14 +    int i;
    7.15 +    
    7.16      __cli();
    7.17  
    7.18      /* Switch guest general-register state. */
    7.19 @@ -280,6 +282,58 @@ void switch_to(struct task_struct *prev_
    7.20          }
    7.21      }
    7.22  
    7.23 +    if ( ( prev_p->io_bitmap != NULL ) || ( next_p->io_bitmap != NULL ) ) {
    7.24 +        if ( next_p->io_bitmap != NULL ) {
    7.25 +            /* Copy in the appropriate parts of the IO bitmap.  We use the
    7.26 +             * selector to copy only the interesting parts of the bitmap. */
    7.27 +
    7.28 +            u64 old_sel = ~0ULL; /* IO bitmap selector for previous task. */
    7.29 +
    7.30 +            if ( prev_p->io_bitmap != NULL)
    7.31 +            {
    7.32 +                old_sel = prev_p->io_bitmap_sel;
    7.33 +
    7.34 +                /* Replace any areas of the IO bitmap that had bits cleared. */
    7.35 +                for ( i = 0; i < sizeof(prev_p->io_bitmap_sel) * 8; i++ )
    7.36 +                    if ( !test_bit(i, &prev_p->io_bitmap_sel) )
    7.37 +                        memcpy(&tss->io_bitmap[i * IOBMP_SELBIT_LWORDS],
    7.38 +                               &next_p->io_bitmap[i * IOBMP_SELBIT_LWORDS],
    7.39 +                               IOBMP_SELBIT_LWORDS * sizeof(unsigned long));
    7.40 +            }
    7.41 +
    7.42 +            /* Copy in any regions of the new task's bitmap that have bits
    7.43 +             * clear and we haven't already dealt with. */
    7.44 +            for ( i = 0; i < sizeof(prev_p->io_bitmap_sel) * 8; i++ )
    7.45 +            {
    7.46 +                if ( test_bit(i, &old_sel)
    7.47 +                     && !test_bit(i, &next_p->io_bitmap_sel) )
    7.48 +                    memcpy(&tss->io_bitmap[i * IOBMP_SELBIT_LWORDS],
    7.49 +                           &next_p->io_bitmap[i * IOBMP_SELBIT_LWORDS],
    7.50 +                           IOBMP_SELBIT_LWORDS * sizeof(unsigned long));
    7.51 +            }
    7.52 +
    7.53 +            tss->bitmap = IO_BITMAP_OFFSET;
    7.54 +
    7.55 +	} else {
    7.56 +            /* In this case, we're switching FROM a task with IO port access,
    7.57 +             * to a task that doesn't use the IO bitmap.  We set any TSS bits
    7.58 +             * that might have been cleared, ready for future use. */
    7.59 +            for ( i = 0; i < sizeof(prev_p->io_bitmap_sel) * 8; i++ )
    7.60 +                if ( !test_bit(i, &prev_p->io_bitmap_sel) )
    7.61 +                    memset(&tss->io_bitmap[i * IOBMP_SELBIT_LWORDS],
    7.62 +                           0xFF, IOBMP_SELBIT_LWORDS * sizeof(unsigned long));
    7.63 +
    7.64 +            /*
    7.65 +             * a bitmap offset pointing outside of the TSS limit
    7.66 +             * causes a nicely controllable SIGSEGV if a process
    7.67 +             * tries to use a port IO instruction. The first
    7.68 +             * sys_ioperm() call sets up the bitmap properly.
    7.69 +             */
    7.70 +            tss->bitmap = INVALID_IO_BITMAP_OFFSET;
    7.71 +	}
    7.72 +    }
    7.73 +    
    7.74 +    
    7.75      /* Switch page tables. */
    7.76      write_ptbase(&next_p->mm);
    7.77      tlb_clocktick();
     8.1 --- a/xen/arch/i386/traps.c	Thu Apr 29 15:36:38 2004 +0000
     8.2 +++ b/xen/arch/i386/traps.c	Tue May 04 14:21:44 2004 +0000
     8.3 @@ -657,7 +657,7 @@ static void set_task_gate(unsigned int n
     8.4  
     8.5  void set_tss_desc(unsigned int n, void *addr)
     8.6  {
     8.7 -    _set_tssldt_desc(gdt_table+__TSS(n), (int)addr, 235, 0x89);
     8.8 +    _set_tssldt_desc(gdt_table+__TSS(n), (int)addr, 8299, 0x89);
     8.9  }
    8.10  
    8.11  void __init trap_init(void)
     9.1 --- a/xen/common/physdev.c	Thu Apr 29 15:36:38 2004 +0000
     9.2 +++ b/xen/common/physdev.c	Tue May 04 14:21:44 2004 +0000
     9.3 @@ -126,7 +126,7 @@ int physdev_pci_access_modify(
     9.4  {
     9.5      struct task_struct *p;
     9.6      struct pci_dev *pdev;
     9.7 -    int rc = 0;
     9.8 +    int i, j, rc = 0;
     9.9   
    9.10      if ( !IS_PRIV(current) )
    9.11          BUG();
    9.12 @@ -146,7 +146,7 @@ int physdev_pci_access_modify(
    9.13          return -ESRCH;
    9.14  
    9.15      /* Make the domain privileged. */
    9.16 -    set_bit(PF_PRIVILEGED, &p->flags);
    9.17 +    set_bit(PF_PHYSDEV, &p->flags);
    9.18  
    9.19      /* Grant write access to the specified device. */
    9.20      if ( (pdev = pci_find_slot(bus, PCI_DEVFN(dev, func))) == NULL )
    9.21 @@ -164,6 +164,55 @@ int physdev_pci_access_modify(
    9.22      if ( pdev->hdr_type != PCI_HEADER_TYPE_NORMAL )
    9.23          INFO("XXX can't give access to bridge devices yet\n");
    9.24  
    9.25 +    /* Now, setup access to the IO ports and memory regions for the device. */
    9.26 +
    9.27 +    if ( p->io_bitmap == NULL )
    9.28 +    {
    9.29 +        p->io_bitmap = kmalloc(IO_BITMAP_BYTES, GFP_KERNEL);
    9.30 +        if ( p->io_bitmap == NULL )
    9.31 +        {
    9.32 +            rc = -ENOMEM;
    9.33 +            goto out;
    9.34 +        }
    9.35 +        memset(p->io_bitmap, 0xFF, IO_BITMAP_BYTES);
    9.36 +
    9.37 +        p->io_bitmap_sel = ~0ULL;
    9.38 +    }
    9.39 +
    9.40 +    for ( i = 0; i < DEVICE_COUNT_RESOURCE; i++ )
    9.41 +    {
    9.42 +        struct resource *r = &pdev->resource[i];
    9.43 +        
    9.44 +        if ( r->flags & IORESOURCE_IO )
    9.45 +        {
    9.46 +            /* Give the domain access to the IO ports it needs.  Currently,
    9.47 +             * this will allow all processes in that domain access to those
    9.48 +             * ports as well.  This will do for now, since driver domains don't
    9.49 +             * run untrusted processes! */
    9.50 +            INFO("Giving domain %llu IO resources (%lx - %lx) "
    9.51 +                 "for device %s\n", dom, r->start, r->end, pdev->slot_name);
    9.52 +            for ( j = r->start; j < r->end + 1; j++ )
    9.53 +            {
    9.54 +                clear_bit(j, p->io_bitmap);
    9.55 +                /* Record that we cleared a bit using bit n of the selector:
    9.56 +                 * n = (j / (4 bytes in a word * 8 bits in a byte))
    9.57 +                 *     / number of words per selector bit
    9.58 +                 */
    9.59 +                clear_bit((j / (8 * 4)) / IOBMP_SELBIT_LWORDS,
    9.60 +                          &p->io_bitmap_sel);
    9.61 +            }
    9.62 +        }
    9.63 +        else if ( r->flags & IORESOURCE_MEM )
    9.64 +        {
    9.65 +            /* allow domain to map IO memory for this device */
    9.66 +            INFO("Giving domain %llu memory resources (%lx - %lx) "
    9.67 +                 "for device %s\n", dom, r->start, r->end, pdev->slot_name);
    9.68 +            for ( j = r->start; j < r->end + 1; j += PAGE_SIZE )
    9.69 +                SHARE_PFN_WITH_DOMAIN(frame_table + (j >> PAGE_SHIFT), p);
    9.70 +        }
    9.71 +    }
    9.72 +
    9.73 +
    9.74   out:
    9.75      put_task_struct(p);
    9.76      return rc;
    9.77 @@ -180,8 +229,8 @@ inline static int check_dev_acc (struct 
    9.78  
    9.79      *pdev = NULL;
    9.80  
    9.81 -    if ( !IS_PRIV(p) )
    9.82 -        return -EPERM; /* no pci acces permission */
    9.83 +     if ( !IS_CAPABLE_PHYSDEV(p) )
    9.84 +         return -EPERM; /* no pci access permission */
    9.85  
    9.86      if ( bus > PCI_BUSMAX || dev > PCI_DEVMAX || func > PCI_FUNCMAX )
    9.87          return -EINVAL;
    9.88 @@ -651,5 +700,7 @@ void physdev_init_dom0(struct task_struc
    9.89                     dev->slot_name);
    9.90          }
    9.91      }
    9.92 +
    9.93 +    set_bit(PF_PHYSDEV, &p->flags);
    9.94  }
    9.95  
    10.1 --- a/xen/include/asm-i386/processor.h	Thu Apr 29 15:36:38 2004 +0000
    10.2 +++ b/xen/include/asm-i386/processor.h	Tue May 04 14:21:44 2004 +0000
    10.3 @@ -287,9 +287,12 @@ extern unsigned int mca_pentium_flag;
    10.4  #define TASK_UNMAPPED_BASE	(TASK_SIZE / 3)
    10.5  
    10.6  /*
    10.7 - * Size of io_bitmap in longwords: 32 is ports 0-0x3ff.
    10.8 + * Size of io_bitmap in longwords:
    10.9 + * For Xen we support the full 8kbyte IO bitmap but use the io_bitmap_sel field
   10.10 + * of the task_struct to avoid a full 8kbyte copy when switching to / from
   10.11 + * domains with bits cleared.
   10.12   */
   10.13 -#define IO_BITMAP_SIZE	32
   10.14 +#define IO_BITMAP_SIZE	2048
   10.15  #define IO_BITMAP_BYTES (IO_BITMAP_SIZE * 4)
   10.16  #define IO_BITMAP_OFFSET offsetof(struct tss_struct,io_bitmap)
   10.17  #define INVALID_IO_BITMAP_OFFSET 0x8000
   10.18 @@ -429,7 +432,7 @@ long set_fast_trap(struct task_struct *p
   10.19  	0,0,0,0,0,0, /* ds,fs,gs */				\
   10.20  	0,0, /* ldt */						\
   10.21  	0, INVALID_IO_BITMAP_OFFSET, /* tace, bitmap */		\
   10.22 -	{~0, } /* ioperm */					\
   10.23 +	{ [0 ... IO_BITMAP_SIZE] = ~0UL }, /* ioperm */         \
   10.24  }
   10.25  
   10.26  struct mm_struct {
    11.1 --- a/xen/include/xen/sched.h	Thu Apr 29 15:36:38 2004 +0000
    11.2 +++ b/xen/include/xen/sched.h	Tue May 04 14:21:44 2004 +0000
    11.3 @@ -44,11 +44,13 @@ extern struct mm_struct init_mm;
    11.4  #define PF_IDLETASK     4 /* Is this one of the per-CPU idle domains?    */
    11.5  #define PF_PRIVILEGED   5 /* Is this domain privileged?                  */
    11.6  #define PF_CONSOLEWRITEBUG 6 /* Has this domain used the obsolete console? */
    11.7 +#define PF_PHYSDEV      7 /* May this domain do IO to physical devices? */
    11.8  
    11.9  #include <xen/vif.h>
   11.10  #include <xen/vbd.h>
   11.11  
   11.12  #define IS_PRIV(_p) (test_bit(PF_PRIVILEGED, &(_p)->flags))
   11.13 +#define IS_CAPABLE_PHYSDEV(_p) (test_bit(PF_PHYSDEV, &(_p)->flags))
   11.14  
   11.15  struct task_struct;
   11.16  
   11.17 @@ -174,6 +176,14 @@ struct task_struct
   11.18      spinlock_t       pcidev_lock;
   11.19      struct list_head pcidev_list;
   11.20  
   11.21 +    /* The following IO bitmap stuff is x86-dependent. */
   11.22 +    u64 io_bitmap_sel; /* Selector to tell us which part of the IO bitmap are
   11.23 +                        * "interesting" (i.e. have clear bits) */
   11.24 +
   11.25 +    /* Handy macro - number of bytes of the IO bitmap, per selector bit. */
   11.26 +#define IOBMP_SELBIT_LWORDS ( IO_BITMAP_SIZE / 64 )
   11.27 +    unsigned long *io_bitmap; /* Pointer to task's IO bitmap or NULL */
   11.28 +
   11.29      unsigned long flags;
   11.30  
   11.31      atomic_t refcnt;