direct-io.hg

changeset 1349:d7147f016bfd

bitkeeper revision 1.891.1.2 (409a27a0RDtp-Kha-G7LNG9wsTO1_Q)

Merge scramble.cl.cam.ac.uk:/auto/groups/xeno/BK/xeno-unstable.bk
into scramble.cl.cam.ac.uk:/local/scratch/kaf24/xen-nonpriv-io.bk
author kaf24@scramble.cl.cam.ac.uk
date Thu May 06 11:55:12 2004 +0000 (2004-05-06)
parents de3970272f43 f290b4d93576
children 5e7d0e24bcca
files xen/common/memory.c xen/common/physdev.c xenolinux-2.4.26-sparse/arch/xen/mm/ioremap.c
line diff
     1.1 --- a/xen/common/memory.c	Thu May 06 10:26:17 2004 +0000
     1.2 +++ b/xen/common/memory.c	Thu May 06 11:55:12 2004 +0000
     1.3 @@ -410,6 +410,7 @@ static int get_page_from_l1e(l1_pgentry_
     1.4  {
     1.5      unsigned long l1v = l1_pgentry_val(l1e);
     1.6      unsigned long pfn = l1_pgentry_to_pagenr(l1e);
     1.7 +    extern int domain_iomem_in_pfn(struct task_struct *p, unsigned long pfn);
     1.8  
     1.9      if ( !(l1v & _PAGE_PRESENT) )
    1.10          return 1;
    1.11 @@ -423,7 +424,11 @@ static int get_page_from_l1e(l1_pgentry_
    1.12      if ( unlikely(!pfn_is_ram(pfn)) )
    1.13      {
    1.14          if ( IS_PRIV(current) )
    1.15 -            return 1;
    1.16 +            return 1;	
    1.17 +
    1.18 +	if ( IS_CAPABLE_PHYSDEV(current) )
    1.19 +            return domain_iomem_in_pfn(current, pfn);
    1.20 +
    1.21          MEM_LOG("Non-privileged attempt to map I/O space %08lx", pfn);
    1.22          return 0;
    1.23      }
     2.1 --- a/xen/common/physdev.c	Thu May 06 10:26:17 2004 +0000
     2.2 +++ b/xen/common/physdev.c	Thu May 06 11:55:12 2004 +0000
     2.3 @@ -202,22 +202,55 @@ int physdev_pci_access_modify(
     2.4                            &p->io_bitmap_sel);
     2.5              }
     2.6          }
     2.7 -        else if ( r->flags & IORESOURCE_MEM )
     2.8 -        {
     2.9 -            /* allow domain to map IO memory for this device */
    2.10 -            INFO("Giving domain %llu memory resources (%lx - %lx) "
    2.11 -                 "for device %s\n", dom, r->start, r->end, pdev->slot_name);
    2.12 -            for ( j = r->start; j < r->end + 1; j += PAGE_SIZE )
    2.13 -                SHARE_PFN_WITH_DOMAIN(frame_table + (j >> PAGE_SHIFT), p);
    2.14 -        }
    2.15 -    }
    2.16  
    2.17 -
    2.18 +        /* rights to IO memory regions are checked when the domain maps them */
    2.19 +	}
    2.20   out:
    2.21      put_task_struct(p);
    2.22      return rc;
    2.23  }
    2.24  
    2.25 +/* Check if a domain controls a device with IO memory within frame @pfn.
    2.26 + * Returns: 1 if the domain should be allowed to map @pfn, 0 otherwise.  */
    2.27 +int domain_iomem_in_pfn(struct task_struct *p, unsigned long pfn)
    2.28 +{
    2.29 +    int ret = 0;
    2.30 +    struct list_head *l;
    2.31 +
    2.32 +    VERBOSE_INFO("Checking if physdev-capable domain %llu needs access to "
    2.33 +                 "pfn %08lx\n", p->domain, pfn);
    2.34 +    
    2.35 +    spin_lock(&p->pcidev_lock);
    2.36 +
    2.37 +    list_for_each(l, &p->pcidev_list)
    2.38 +    {
    2.39 +        int i;
    2.40 +        phys_dev_t *phys_dev = list_entry(l, phys_dev_t, node);
    2.41 +        struct pci_dev *pci_dev = phys_dev->dev;
    2.42 +
    2.43 +        for ( i = 0; (i < DEVICE_COUNT_RESOURCE) && (ret == 0); i++ )
    2.44 +        {
    2.45 +            struct resource *r = &pci_dev->resource[i];
    2.46 +            
    2.47 +            if ( r->flags & IORESOURCE_MEM )
    2.48 +                if ( (r->start >> PAGE_SHIFT) == pfn
    2.49 +                     || (r->end >> PAGE_SHIFT) == pfn
    2.50 +                     || ((r->start >> PAGE_SHIFT < pfn)
    2.51 +                         && (r->end >> PAGE_SHIFT > pfn)) )
    2.52 +                    ret = 1;
    2.53 +        }
    2.54 +
    2.55 +        if ( ret != 0 ) break;
    2.56 +    }
    2.57 +    
    2.58 +    spin_unlock(&p->pcidev_lock);
    2.59 +
    2.60 +    VERBOSE_INFO("Domain %llu %s mapping of pfn %08lx\n",
    2.61 +                 p->domain, ret ? "allowed" : "disallowed", pfn);
    2.62 +
    2.63 +    return ret;
    2.64 +}
    2.65 +
    2.66  /* check if a domain has general access to a device */
    2.67  inline static int check_dev_acc (struct task_struct *p,
    2.68                                   int bus, int dev, int func,
    2.69 @@ -235,8 +268,7 @@ inline static int check_dev_acc (struct 
    2.70      if ( bus > PCI_BUSMAX || dev > PCI_DEVMAX || func > PCI_FUNCMAX )
    2.71          return -EINVAL;
    2.72  
    2.73 -    VERBOSE_INFO("a=%c b=%x d=%x f=%x ", (acc == ACC_READ) ? 'R' : 'W',
    2.74 -                 mask, bus, dev, func);
    2.75 +    VERBOSE_INFO("b=%x d=%x f=%x ", bus, dev, func);
    2.76  
    2.77      /* check target device */
    2.78      target_devfn = PCI_DEVFN(dev, func);
    2.79 @@ -296,8 +328,8 @@ static int do_base_address_access(phys_d
    2.80          /* We could set *val to some value but the guest may well be in trouble
    2.81           * anyway if this write fails.  Hopefully the printk will give us a
    2.82           * clue what went wrong. */
    2.83 -        printk("Guest attempting sub-dword %s to BASE_ADDRESS %d\n", 
    2.84 -             (acc == ACC_READ) ? "read" : "write", idx);
    2.85 +        printk("Guest %llu attempting sub-dword %s to BASE_ADDRESS %d\n",
    2.86 +               pdev->owner->domain, (acc == ACC_READ) ? "read" : "write", idx);
    2.87          
    2.88          return -EPERM;
    2.89      }
    2.90 @@ -328,7 +360,7 @@ static int do_base_address_access(phys_d
    2.91              }
    2.92          }
    2.93          VERBOSE_INFO("fixed pci write: %02x:%02x:%02x reg=0x%02x len=0x%02x"
    2.94 -                     " val=0x%08x %lx\n", 
    2.95 +                     " val=0x%08x %x\n", 
    2.96                       dev->bus->number, PCI_SLOT(dev->devfn), 
    2.97                       PCI_FUNC(dev->devfn), reg, len, *val, pdev->state);
    2.98      }
    2.99 @@ -365,7 +397,7 @@ static int do_base_address_access(phys_d
   2.100              }
   2.101          }
   2.102          VERBOSE_INFO("fixed pci read: %02x:%02x:%02x reg=0x%02x len=0x%02x"
   2.103 -                     " val=0x%08x %lx\n", 
   2.104 +                     " val=0x%08x %x\n", 
   2.105                       dev->bus->number, PCI_SLOT(dev->devfn), 
   2.106                       PCI_FUNC(dev->devfn), reg, len, *val, pdev->state);
   2.107      }
   2.108 @@ -422,9 +454,9 @@ static int do_rom_address_access(phys_de
   2.109              }
   2.110          }
   2.111          VERBOSE_INFO("fixed pci write: %02x:%02x:%02x reg=0x%02x len=0x%02x"
   2.112 -                     " val=0x%08x %lx\n", 
   2.113 +                     " val=0x%08x %x\n", 
   2.114                       dev->bus->number, PCI_SLOT(dev->devfn), 
   2.115 -                     PCI_FUNC(dev->devfn), reg, len, *val, pdev->state);
   2.116 +                     PCI_FUNC(dev->devfn), PCI_ROM_ADDRESS, len, *val, pdev->state);
   2.117      }
   2.118      else if ( acc == ACC_READ )
   2.119      {
   2.120 @@ -442,9 +474,9 @@ static int do_rom_address_access(phys_de
   2.121              *val = *val | (orig_val & 0x1);
   2.122          }
   2.123          VERBOSE_INFO("fixed pci read: %02x:%02x:%02x reg=0x%02x len=0x%02x"
   2.124 -                     " val=0x%08x %lx\n", 
   2.125 +                     " val=0x%08x %x\n", 
   2.126                       dev->bus->number, PCI_SLOT(dev->devfn), 
   2.127 -                     PCI_FUNC(dev->devfn), reg, len, *val, pdev->state);
   2.128 +                     PCI_FUNC(dev->devfn), PCI_ROM_ADDRESS, len, *val, pdev->state);
   2.129      }
   2.130  
   2.131      return ret;
     3.1 --- a/xenolinux-2.4.26-sparse/arch/xen/mm/ioremap.c	Thu May 06 10:26:17 2004 +0000
     3.2 +++ b/xenolinux-2.4.26-sparse/arch/xen/mm/ioremap.c	Thu May 06 11:55:12 2004 +0000
     3.3 @@ -178,10 +178,6 @@ void * __ioremap(unsigned long machine_a
     3.4      unsigned long offset, last_addr;
     3.5      pgprot_t prot;
     3.6  
     3.7 -    /* Only privileged Xenolinux can make unchecked pagetable updates. */
     3.8 -    if ( !(start_info.flags & SIF_PRIVILEGED) )
     3.9 -        return NULL;
    3.10 -
    3.11      /* Don't allow wraparound or zero size */
    3.12      last_addr = machine_addr + size - 1;
    3.13      if (!size || last_addr < machine_addr)