ia64/xen-unstable

changeset 18199:b9edc4627944

vtd: Move dom0 RMRR check to intel_iommu_remove_device()

If put dom0 RMRR check in domain_context_unmap_one(), the devices with
RMRR cannot be assigned to other domain, becuase
domain_context_unmap_one() won't unmap context for them, and dom0
always owns them. This patch moves the check to intel_iommu_remove_device()
which is only called by dom0 hypercall. This not only guarantees
keeping RMRR mappings for dom0 during its booting, but also won't
impact device assignment.

Signed-off-by: Weidong Han <weidong.han@intel.com>
author Keir Fraser <keir.fraser@citrix.com>
date Wed Jul 30 09:25:07 2008 +0100 (2008-07-30)
parents eba86724cc07
children 8c8505e8e4e3
files xen/drivers/passthrough/vtd/iommu.c
line diff
     1.1 --- a/xen/drivers/passthrough/vtd/iommu.c	Wed Jul 30 09:23:47 2008 +0100
     1.2 +++ b/xen/drivers/passthrough/vtd/iommu.c	Wed Jul 30 09:25:07 2008 +0100
     1.3 @@ -1302,10 +1302,6 @@ static int domain_context_unmap_one(
     1.4      struct context_entry *context, *context_entries;
     1.5      unsigned long flags;
     1.6      u64 maddr;
     1.7 -    struct acpi_rmrr_unit *rmrr;
     1.8 -    u16 bdf;
     1.9 -    int i;
    1.10 -    unsigned int is_rmrr_device = 0;
    1.11  
    1.12      maddr = bus_to_context_maddr(iommu, bus);
    1.13      context_entries = (struct context_entry *)map_vtd_domain_page(maddr);
    1.14 @@ -1318,25 +1314,11 @@ static int domain_context_unmap_one(
    1.15      }
    1.16  
    1.17      spin_lock_irqsave(&iommu->lock, flags);
    1.18 -    if ( domain->domain_id == 0 )
    1.19 -    {
    1.20 -        for_each_rmrr_device ( rmrr, bdf, i )
    1.21 -        {
    1.22 -            if ( PCI_BUS(bdf) == bus && PCI_DEVFN2(bdf) == devfn )
    1.23 -            {
    1.24 -                is_rmrr_device = 1;
    1.25 -                break;
    1.26 -            }
    1.27 -        }
    1.28 -    }
    1.29 -    if ( !is_rmrr_device )
    1.30 -    {
    1.31 -        context_clear_present(*context);
    1.32 -        context_clear_entry(*context);
    1.33 -        iommu_flush_cache_entry(context);
    1.34 -        iommu_flush_context_domain(iommu, domain_iommu_domid(domain), 0);
    1.35 -        iommu_flush_iotlb_dsi(iommu, domain_iommu_domid(domain), 0);
    1.36 -    }
    1.37 +    context_clear_present(*context);
    1.38 +    context_clear_entry(*context);
    1.39 +    iommu_flush_cache_entry(context);
    1.40 +    iommu_flush_context_domain(iommu, domain_iommu_domid(domain), 0);
    1.41 +    iommu_flush_iotlb_dsi(iommu, domain_iommu_domid(domain), 0);
    1.42      unmap_vtd_domain_page(context_entries);
    1.43      spin_unlock_irqrestore(&iommu->lock, flags);
    1.44  
    1.45 @@ -1619,8 +1601,26 @@ static int intel_iommu_add_device(struct
    1.46  
    1.47  static int intel_iommu_remove_device(struct pci_dev *pdev)
    1.48  {
    1.49 +    struct acpi_rmrr_unit *rmrr;
    1.50 +    u16 bdf;
    1.51 +    int i;
    1.52 +
    1.53      if ( !pdev->domain )
    1.54          return -EINVAL;
    1.55 +
    1.56 +    /* If the device belongs to dom0, and it has RMRR, don't remove it
    1.57 +     * from dom0, because BIOS may use RMRR at booting time.
    1.58 +     */
    1.59 +    if ( pdev->domain->domain_id == 0 )
    1.60 +    {
    1.61 +        for_each_rmrr_device ( rmrr, bdf, i )
    1.62 +        {
    1.63 +            if ( PCI_BUS(bdf) == pdev->bus &&
    1.64 +                 PCI_DEVFN2(bdf) == pdev->devfn )
    1.65 +                return 0;
    1.66 +        }
    1.67 +    }
    1.68 +
    1.69      return domain_context_unmap(pdev->domain, pdev->bus, pdev->devfn);
    1.70  }
    1.71