Skip to content

Commit

Permalink
iommu/vt-d: Differentiate relaxable and non relaxable RMRRs
Browse files Browse the repository at this point in the history
Now we have a new IOMMU_RESV_DIRECT_RELAXABLE reserved memory
region type, let's report USB and GFX RMRRs as relaxable ones.

We introduce a new device_rmrr_is_relaxable() helper to check
whether the rmrr belongs to the relaxable category.

This allows to have a finer reporting at IOMMU API level of
reserved memory regions. This will be exploitable by VFIO to
define the usable IOVA range and detect potential conflicts
between the guest physical address space and host reserved
regions.

Signed-off-by: Eric Auger <eric.auger@redhat.com>
Reviewed-by: Lu Baolu <baolu.lu@linux.intel.com>
Signed-off-by: Joerg Roedel <jroedel@suse.de>
  • Loading branch information
Eric Auger authored and Joerg Roedel committed Jun 12, 2019
1 parent adfd373 commit 1c5c59f
Showing 1 changed file with 39 additions and 15 deletions.
54 changes: 39 additions & 15 deletions drivers/iommu/intel-iommu.c
Original file line number Diff line number Diff line change
Expand Up @@ -2890,6 +2890,35 @@ static bool device_has_rmrr(struct device *dev)
return false;
}

/**
* device_rmrr_is_relaxable - Test whether the RMRR of this device
* is relaxable (ie. is allowed to be not enforced under some conditions)
* @dev: device handle
*
* We assume that PCI USB devices with RMRRs have them largely
* for historical reasons and that the RMRR space is not actively used post
* boot. This exclusion may change if vendors begin to abuse it.
*
* The same exception is made for graphics devices, with the requirement that
* any use of the RMRR regions will be torn down before assigning the device
* to a guest.
*
* Return: true if the RMRR is relaxable, false otherwise
*/
static bool device_rmrr_is_relaxable(struct device *dev)
{
struct pci_dev *pdev;

if (!dev_is_pci(dev))
return false;

pdev = to_pci_dev(dev);
if (IS_USB_DEVICE(pdev) || IS_GFX_DEVICE(pdev))
return true;
else
return false;
}

/*
* There are a couple cases where we need to restrict the functionality of
* devices associated with RMRRs. The first is when evaluating a device for
Expand All @@ -2904,25 +2933,16 @@ static bool device_has_rmrr(struct device *dev)
* We therefore prevent devices associated with an RMRR from participating in
* the IOMMU API, which eliminates them from device assignment.
*
* In both cases we assume that PCI USB devices with RMRRs have them largely
* for historical reasons and that the RMRR space is not actively used post
* boot. This exclusion may change if vendors begin to abuse it.
*
* The same exception is made for graphics devices, with the requirement that
* any use of the RMRR regions will be torn down before assigning the device
* to a guest.
* In both cases, devices which have relaxable RMRRs are not concerned by this
* restriction. See device_rmrr_is_relaxable comment.
*/
static bool device_is_rmrr_locked(struct device *dev)
{
if (!device_has_rmrr(dev))
return false;

if (dev_is_pci(dev)) {
struct pci_dev *pdev = to_pci_dev(dev);

if (IS_USB_DEVICE(pdev) || IS_GFX_DEVICE(pdev))
return false;
}
if (device_rmrr_is_relaxable(dev))
return false;

return true;
}
Expand Down Expand Up @@ -5424,16 +5444,20 @@ static void intel_iommu_get_resv_regions(struct device *device,
for_each_active_dev_scope(rmrr->devices, rmrr->devices_cnt,
i, i_dev) {
struct iommu_resv_region *resv;
enum iommu_resv_type type;
size_t length;

if (i_dev != device &&
!is_downstream_to_pci_bridge(device, i_dev))
continue;

length = rmrr->end_address - rmrr->base_address + 1;

type = device_rmrr_is_relaxable(device) ?
IOMMU_RESV_DIRECT_RELAXABLE : IOMMU_RESV_DIRECT;

resv = iommu_alloc_resv_region(rmrr->base_address,
length, prot,
IOMMU_RESV_DIRECT);
length, prot, type);
if (!resv)
break;

Expand Down

0 comments on commit 1c5c59f

Please sign in to comment.