iommu/amd: Use is_attach_deferred call-back
Implement call-back is_attach_deferred and use it to defer the domain attach from iommu driver init to device driver init when iommu is pre-enabled in kdump kernel. Signed-off-by: Baoquan He <bhe@redhat.com> Signed-off-by: Joerg Roedel <jroedel@suse.de>
This commit is contained in:
parent
e01d1913b0
commit
df3f7a6e8e
1 changed files with 22 additions and 1 deletions
|
@ -121,6 +121,7 @@ struct iommu_dev_data {
|
||||||
PPR completions */
|
PPR completions */
|
||||||
u32 errata; /* Bitmap for errata to apply */
|
u32 errata; /* Bitmap for errata to apply */
|
||||||
bool use_vapic; /* Enable device to use vapic mode */
|
bool use_vapic; /* Enable device to use vapic mode */
|
||||||
|
bool defer_attach;
|
||||||
|
|
||||||
struct ratelimit_state rs; /* Ratelimit IOPF messages */
|
struct ratelimit_state rs; /* Ratelimit IOPF messages */
|
||||||
};
|
};
|
||||||
|
@ -371,12 +372,17 @@ static u16 get_alias(struct device *dev)
|
||||||
static struct iommu_dev_data *find_dev_data(u16 devid)
|
static struct iommu_dev_data *find_dev_data(u16 devid)
|
||||||
{
|
{
|
||||||
struct iommu_dev_data *dev_data;
|
struct iommu_dev_data *dev_data;
|
||||||
|
struct amd_iommu *iommu = amd_iommu_rlookup_table[devid];
|
||||||
|
|
||||||
dev_data = search_dev_data(devid);
|
dev_data = search_dev_data(devid);
|
||||||
|
|
||||||
if (dev_data == NULL)
|
if (dev_data == NULL) {
|
||||||
dev_data = alloc_dev_data(devid);
|
dev_data = alloc_dev_data(devid);
|
||||||
|
|
||||||
|
if (translation_pre_enabled(iommu))
|
||||||
|
dev_data->defer_attach = true;
|
||||||
|
}
|
||||||
|
|
||||||
return dev_data;
|
return dev_data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2477,11 +2483,18 @@ static struct iommu_group *amd_iommu_device_group(struct device *dev)
|
||||||
static struct protection_domain *get_domain(struct device *dev)
|
static struct protection_domain *get_domain(struct device *dev)
|
||||||
{
|
{
|
||||||
struct protection_domain *domain;
|
struct protection_domain *domain;
|
||||||
|
struct iommu_domain *io_domain;
|
||||||
|
|
||||||
if (!check_device(dev))
|
if (!check_device(dev))
|
||||||
return ERR_PTR(-EINVAL);
|
return ERR_PTR(-EINVAL);
|
||||||
|
|
||||||
domain = get_dev_data(dev)->domain;
|
domain = get_dev_data(dev)->domain;
|
||||||
|
if (domain == NULL && get_dev_data(dev)->defer_attach) {
|
||||||
|
get_dev_data(dev)->defer_attach = false;
|
||||||
|
io_domain = iommu_get_domain_for_dev(dev);
|
||||||
|
domain = to_pdomain(io_domain);
|
||||||
|
attach_device(dev, domain);
|
||||||
|
}
|
||||||
if (!dma_ops_domain(domain))
|
if (!dma_ops_domain(domain))
|
||||||
return ERR_PTR(-EBUSY);
|
return ERR_PTR(-EBUSY);
|
||||||
|
|
||||||
|
@ -3372,6 +3385,13 @@ static void amd_iommu_apply_resv_region(struct device *dev,
|
||||||
WARN_ON_ONCE(reserve_iova(&dma_dom->iovad, start, end) == NULL);
|
WARN_ON_ONCE(reserve_iova(&dma_dom->iovad, start, end) == NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool amd_iommu_is_attach_deferred(struct iommu_domain *domain,
|
||||||
|
struct device *dev)
|
||||||
|
{
|
||||||
|
struct iommu_dev_data *dev_data = dev->archdata.iommu;
|
||||||
|
return dev_data->defer_attach;
|
||||||
|
}
|
||||||
|
|
||||||
const struct iommu_ops amd_iommu_ops = {
|
const struct iommu_ops amd_iommu_ops = {
|
||||||
.capable = amd_iommu_capable,
|
.capable = amd_iommu_capable,
|
||||||
.domain_alloc = amd_iommu_domain_alloc,
|
.domain_alloc = amd_iommu_domain_alloc,
|
||||||
|
@ -3388,6 +3408,7 @@ const struct iommu_ops amd_iommu_ops = {
|
||||||
.get_resv_regions = amd_iommu_get_resv_regions,
|
.get_resv_regions = amd_iommu_get_resv_regions,
|
||||||
.put_resv_regions = amd_iommu_put_resv_regions,
|
.put_resv_regions = amd_iommu_put_resv_regions,
|
||||||
.apply_resv_region = amd_iommu_apply_resv_region,
|
.apply_resv_region = amd_iommu_apply_resv_region,
|
||||||
|
.is_attach_deferred = amd_iommu_is_attach_deferred,
|
||||||
.pgsize_bitmap = AMD_IOMMU_PGSIZES,
|
.pgsize_bitmap = AMD_IOMMU_PGSIZES,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue