Commit df3f7a6e authored by Baoquan He's avatar Baoquan He Committed by Joerg Roedel

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: default avatarBaoquan He <bhe@redhat.com>
Signed-off-by: default avatarJoerg Roedel <jroedel@suse.de>
parent e01d1913
...@@ -121,6 +121,7 @@ struct iommu_dev_data { ...@@ -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) ...@@ -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) ...@@ -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, ...@@ -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 = { ...@@ -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,
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment