From: mwilli2@equilibrium.research.intel-research.net Date: Thu, 6 May 2004 11:18:49 +0000 (+0000) Subject: bitkeeper revision 1.887.1.1 (409a1f19c2yUU_JXMKfMgBliLnj32Q) X-Git-Tag: archive/raspbian/4.8.0-1+rpi1~1^2~18221^2~3^2~1 X-Git-Url: https://dgit.raspbian.org/?a=commitdiff_plain;h=224a3b68f873f25092cc799435977e6775f3e2fc;p=xen.git bitkeeper revision 1.887.1.1 (409a1f19c2yUU_JXMKfMgBliLnj32Q) Fix IO memory mapping controls for driver domains. --- diff --git a/xen/common/memory.c b/xen/common/memory.c index ed2e5b6e17..0e986119db 100644 --- a/xen/common/memory.c +++ b/xen/common/memory.c @@ -410,6 +410,7 @@ static int get_page_from_l1e(l1_pgentry_t l1e) { unsigned long l1v = l1_pgentry_val(l1e); unsigned long pfn = l1_pgentry_to_pagenr(l1e); + extern int domain_iomem_in_pfn(struct task_struct *p, unsigned long pfn); if ( !(l1v & _PAGE_PRESENT) ) return 1; @@ -423,7 +424,11 @@ static int get_page_from_l1e(l1_pgentry_t l1e) if ( unlikely(!pfn_is_ram(pfn)) ) { if ( IS_PRIV(current) ) - return 1; + return 1; + + if ( IS_CAPABLE_PHYSDEV(current) ) + return domain_iomem_in_pfn(current, pfn); + MEM_LOG("Non-privileged attempt to map I/O space %08lx", pfn); return 0; } diff --git a/xen/common/physdev.c b/xen/common/physdev.c index 91322992db..d15183cb6e 100644 --- a/xen/common/physdev.c +++ b/xen/common/physdev.c @@ -202,20 +202,53 @@ int physdev_pci_access_modify( &p->io_bitmap_sel); } } - else if ( r->flags & IORESOURCE_MEM ) + + /* rights to IO memory regions are checked when the domain maps them */ + } + out: + put_task_struct(p); + return rc; +} + +/* Check if a domain controls a device with IO memory within frame @pfn. + * Returns: 1 if the domain should be allowed to map @pfn, 0 otherwise. */ +int domain_iomem_in_pfn(struct task_struct *p, unsigned long pfn) +{ + int ret = 0; + struct list_head *l; + + VERBOSE_INFO("Checking if physdev-capable domain %llu needs access to " + "pfn %08lx\n", p->domain, pfn); + + spin_lock(&p->pcidev_lock); + + list_for_each(l, &p->pcidev_list) + { + int i; + phys_dev_t *phys_dev = list_entry(l, phys_dev_t, node); + struct pci_dev *pci_dev = phys_dev->dev; + + for ( i = 0; (i < DEVICE_COUNT_RESOURCE) && (ret == 0); i++ ) { - /* allow domain to map IO memory for this device */ - INFO("Giving domain %llu memory resources (%lx - %lx) " - "for device %s\n", dom, r->start, r->end, pdev->slot_name); - for ( j = r->start; j < r->end + 1; j += PAGE_SIZE ) - SHARE_PFN_WITH_DOMAIN(frame_table + (j >> PAGE_SHIFT), p); + struct resource *r = &pci_dev->resource[i]; + + if ( r->flags & IORESOURCE_MEM ) + if ( (r->start >> PAGE_SHIFT) == pfn + || (r->end >> PAGE_SHIFT) == pfn + || ((r->start >> PAGE_SHIFT < pfn) + && (r->end >> PAGE_SHIFT > pfn)) ) + ret = 1; } + + if ( ret != 0 ) break; } + + spin_unlock(&p->pcidev_lock); + VERBOSE_INFO("Domain %llu %s mapping of pfn %08lx\n", + p->domain, ret ? "allowed" : "disallowed", pfn); - out: - put_task_struct(p); - return rc; + return ret; } /* check if a domain has general access to a device */ @@ -235,8 +268,7 @@ inline static int check_dev_acc (struct task_struct *p, if ( bus > PCI_BUSMAX || dev > PCI_DEVMAX || func > PCI_FUNCMAX ) return -EINVAL; - VERBOSE_INFO("a=%c b=%x d=%x f=%x ", (acc == ACC_READ) ? 'R' : 'W', - mask, bus, dev, func); + VERBOSE_INFO("b=%x d=%x f=%x ", bus, dev, func); /* check target device */ target_devfn = PCI_DEVFN(dev, func); @@ -296,8 +328,8 @@ static int do_base_address_access(phys_dev_t *pdev, int acc, int idx, /* We could set *val to some value but the guest may well be in trouble * anyway if this write fails. Hopefully the printk will give us a * clue what went wrong. */ - printk("Guest attempting sub-dword %s to BASE_ADDRESS %d\n", - (acc == ACC_READ) ? "read" : "write", idx); + printk("Guest %llu attempting sub-dword %s to BASE_ADDRESS %d\n", + pdev->owner->domain, (acc == ACC_READ) ? "read" : "write", idx); return -EPERM; } @@ -328,7 +360,7 @@ static int do_base_address_access(phys_dev_t *pdev, int acc, int idx, } } VERBOSE_INFO("fixed pci write: %02x:%02x:%02x reg=0x%02x len=0x%02x" - " val=0x%08x %lx\n", + " val=0x%08x %x\n", dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn), reg, len, *val, pdev->state); } @@ -365,7 +397,7 @@ static int do_base_address_access(phys_dev_t *pdev, int acc, int idx, } } VERBOSE_INFO("fixed pci read: %02x:%02x:%02x reg=0x%02x len=0x%02x" - " val=0x%08x %lx\n", + " val=0x%08x %x\n", dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn), reg, len, *val, pdev->state); } @@ -422,9 +454,9 @@ static int do_rom_address_access(phys_dev_t *pdev, int acc, int len, u32 *val) } } VERBOSE_INFO("fixed pci write: %02x:%02x:%02x reg=0x%02x len=0x%02x" - " val=0x%08x %lx\n", + " val=0x%08x %x\n", dev->bus->number, PCI_SLOT(dev->devfn), - PCI_FUNC(dev->devfn), reg, len, *val, pdev->state); + PCI_FUNC(dev->devfn), PCI_ROM_ADDRESS, len, *val, pdev->state); } else if ( acc == ACC_READ ) { @@ -442,9 +474,9 @@ static int do_rom_address_access(phys_dev_t *pdev, int acc, int len, u32 *val) *val = *val | (orig_val & 0x1); } VERBOSE_INFO("fixed pci read: %02x:%02x:%02x reg=0x%02x len=0x%02x" - " val=0x%08x %lx\n", + " val=0x%08x %x\n", dev->bus->number, PCI_SLOT(dev->devfn), - PCI_FUNC(dev->devfn), reg, len, *val, pdev->state); + PCI_FUNC(dev->devfn), PCI_ROM_ADDRESS, len, *val, pdev->state); } return ret; diff --git a/xenolinux-2.4.26-sparse/arch/xen/mm/ioremap.c b/xenolinux-2.4.26-sparse/arch/xen/mm/ioremap.c index 07524e01aa..9d12acfb50 100644 --- a/xenolinux-2.4.26-sparse/arch/xen/mm/ioremap.c +++ b/xenolinux-2.4.26-sparse/arch/xen/mm/ioremap.c @@ -183,10 +183,6 @@ void * __ioremap(unsigned long machine_addr, unsigned long offset, last_addr; pgprot_t prot; - /* Only privileged Xenolinux can make unchecked pagetable updates. */ - if ( !(start_info.flags & SIF_PRIVILEGED) ) - return NULL; - /* Don't allow wraparound or zero size */ last_addr = machine_addr + size - 1; if (!size || last_addr < machine_addr)