iommu/vt-d: Add set domain DOMAIN_ATTR_NESTING attr
This adds the Intel VT-d specific callback of setting DOMAIN_ATTR_NESTING domain attribution. It is necessary to let the VT-d driver know that the domain represents a virtual machine which requires the IOMMU hardware to support nested translation mode. Return success if the IOMMU hardware suports nested mode, otherwise failure. Signed-off-by: Yi Sun <yi.y.sun@linux.intel.com> Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com> Signed-off-by: Joerg Roedel <jroedel@suse.de>
This commit is contained in:
parent
a1948f2e0a
commit
2cd1311a26
|
@ -315,6 +315,12 @@ static int hw_pass_through = 1;
|
|||
*/
|
||||
#define DOMAIN_FLAG_USE_FIRST_LEVEL BIT(2)
|
||||
|
||||
/*
|
||||
* Domain represents a virtual machine which demands iommu nested
|
||||
* translation mode support.
|
||||
*/
|
||||
#define DOMAIN_FLAG_NESTING_MODE BIT(3)
|
||||
|
||||
#define for_each_domain_iommu(idx, domain) \
|
||||
for (idx = 0; idx < g_num_of_iommus; idx++) \
|
||||
if (domain->iommu_refcnt[idx])
|
||||
|
@ -5640,6 +5646,24 @@ static inline bool iommu_pasid_support(void)
|
|||
return ret;
|
||||
}
|
||||
|
||||
static inline bool nested_mode_support(void)
|
||||
{
|
||||
struct dmar_drhd_unit *drhd;
|
||||
struct intel_iommu *iommu;
|
||||
bool ret = true;
|
||||
|
||||
rcu_read_lock();
|
||||
for_each_active_iommu(iommu, drhd) {
|
||||
if (!sm_supported(iommu) || !ecap_nest(iommu->ecap)) {
|
||||
ret = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
rcu_read_unlock();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static bool intel_iommu_capable(enum iommu_cap cap)
|
||||
{
|
||||
if (cap == IOMMU_CAP_CACHE_COHERENCY)
|
||||
|
@ -6018,10 +6042,42 @@ static bool intel_iommu_is_attach_deferred(struct iommu_domain *domain,
|
|||
return dev->archdata.iommu == DEFER_DEVICE_DOMAIN_INFO;
|
||||
}
|
||||
|
||||
static int
|
||||
intel_iommu_domain_set_attr(struct iommu_domain *domain,
|
||||
enum iommu_attr attr, void *data)
|
||||
{
|
||||
struct dmar_domain *dmar_domain = to_dmar_domain(domain);
|
||||
unsigned long flags;
|
||||
int ret = 0;
|
||||
|
||||
if (domain->type != IOMMU_DOMAIN_UNMANAGED)
|
||||
return -EINVAL;
|
||||
|
||||
switch (attr) {
|
||||
case DOMAIN_ATTR_NESTING:
|
||||
spin_lock_irqsave(&device_domain_lock, flags);
|
||||
if (nested_mode_support() &&
|
||||
list_empty(&dmar_domain->devices)) {
|
||||
dmar_domain->flags |= DOMAIN_FLAG_NESTING_MODE;
|
||||
dmar_domain->flags &= ~DOMAIN_FLAG_USE_FIRST_LEVEL;
|
||||
} else {
|
||||
ret = -ENODEV;
|
||||
}
|
||||
spin_unlock_irqrestore(&device_domain_lock, flags);
|
||||
break;
|
||||
default:
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
const struct iommu_ops intel_iommu_ops = {
|
||||
.capable = intel_iommu_capable,
|
||||
.domain_alloc = intel_iommu_domain_alloc,
|
||||
.domain_free = intel_iommu_domain_free,
|
||||
.domain_set_attr = intel_iommu_domain_set_attr,
|
||||
.attach_dev = intel_iommu_attach_device,
|
||||
.detach_dev = intel_iommu_detach_device,
|
||||
.aux_attach_dev = intel_iommu_aux_attach_device,
|
||||
|
|
Loading…
Reference in New Issue