ia64/xen-unstable

changeset 16151:46a7c9a15b0f

x86, vt-d: Fail PCI device assignment if device already assigned.
Signed-off-by: Weidong Han <weidong.han@intel.com>
author Keir Fraser <keir@xensource.com>
date Thu Oct 18 10:24:50 2007 +0100 (2007-10-18)
parents 2173fe77dcd2
children 07063bca8a10
files xen/arch/x86/domctl.c xen/arch/x86/hvm/vmx/vtd/intel-iommu.c xen/include/asm-x86/iommu.h
line diff
     1.1 --- a/xen/arch/x86/domctl.c	Thu Oct 18 09:59:20 2007 +0100
     1.2 +++ b/xen/arch/x86/domctl.c	Thu Oct 18 10:24:50 2007 +0100
     1.3 @@ -531,10 +531,10 @@ long arch_do_domctl(
     1.4          struct hvm_iommu *hd;
     1.5          u8 bus, devfn;
     1.6  
     1.7 -        if (!vtd_enabled)
     1.8 +        ret = -EINVAL;
     1.9 +        if ( !vtd_enabled )
    1.10              break;
    1.11  
    1.12 -        ret = -EINVAL;
    1.13          if ( unlikely((d = get_domain_by_id(domctl->domain)) == NULL) ) {
    1.14              gdprintk(XENLOG_ERR,
    1.15                  "XEN_DOMCTL_assign_device: get_domain_by_id() failed\n"); 
    1.16 @@ -543,6 +543,10 @@ long arch_do_domctl(
    1.17          hd = domain_hvm_iommu(d);
    1.18          bus = (domctl->u.assign_device.machine_bdf >> 16) & 0xff;
    1.19          devfn = (domctl->u.assign_device.machine_bdf >> 8) & 0xff;
    1.20 +
    1.21 +        if ( device_assigned(bus, devfn) )
    1.22 +            break;
    1.23 +
    1.24          ret = assign_device(d, bus, devfn);
    1.25          gdprintk(XENLOG_ERR, "XEN_DOMCTL_assign_device: bdf = %x:%x:%x\n",
    1.26              bus, PCI_SLOT(devfn), PCI_FUNC(devfn));
     2.1 --- a/xen/arch/x86/hvm/vmx/vtd/intel-iommu.c	Thu Oct 18 09:59:20 2007 +0100
     2.2 +++ b/xen/arch/x86/hvm/vmx/vtd/intel-iommu.c	Thu Oct 18 10:24:50 2007 +0100
     2.3 @@ -1813,6 +1813,21 @@ int iommu_setup(void)
     2.4      return -EIO;
     2.5  }
     2.6  
     2.7 +/*
     2.8 + * If the device isn't owned by dom0, it means it already
     2.9 + * has been assigned to other domain, or it's not exist.
    2.10 + */
    2.11 +int device_assigned(u8 bus, u8 devfn)
    2.12 +{
    2.13 +    struct pci_dev *pdev;
    2.14 +
    2.15 +    for_each_pdev( dom0, pdev )
    2.16 +        if ( (pdev->bus == bus ) && (pdev->devfn == devfn) )
    2.17 +            return 0;
    2.18 +
    2.19 +    return 1;
    2.20 +}
    2.21 +
    2.22  int assign_device(struct domain *d, u8 bus, u8 devfn)
    2.23  {
    2.24      struct hvm_iommu *hd  = domain_hvm_iommu(d);
     3.1 --- a/xen/include/asm-x86/iommu.h	Thu Oct 18 09:59:20 2007 +0100
     3.2 +++ b/xen/include/asm-x86/iommu.h	Thu Oct 18 10:24:50 2007 +0100
     3.3 @@ -69,6 +69,7 @@ struct iommu {
     3.4  int iommu_setup(void);
     3.5  int iommu_domain_init(struct domain *d);
     3.6  void iommu_domain_destroy(struct domain *d);
     3.7 +int device_assigned(u8 bus, u8 devfn);
     3.8  int assign_device(struct domain *d, u8 bus, u8 devfn);
     3.9  int iommu_map_page(struct domain *d, dma_addr_t gfn, dma_addr_t mfn);
    3.10  int iommu_unmap_page(struct domain *d, dma_addr_t gfn);