iommu/amd: Set the pgsize_bitmap correctly
BugLink: https://bugs.launchpad.net/bugs/2097301
[ Upstream commit 7a41dcb52f9de6079621fc31c3b84c7fc290934b ]
When using io_pgtable the correct pgsize_bitmap is stored in the cfg, both
v1_alloc_pgtable() and v2_alloc_pgtable() set it correctly.
This fixes a bug where the v2 pgtable had the wrong pgsize as
protection_domain_init_v2() would set it and then do_iommu_domain_alloc()
immediately resets it.
Remove the confusing ops.pgsize_bitmap since that is not used if the
driver sets domain.pgsize_bitmap.
Fixes: 134288158a ("iommu/amd: Add domain_alloc_user based domain allocation")
Reviewed-by: Vasant Hegde <vasant.hegde@amd.com>
Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
Link: https://lore.kernel.org/r/3-v2-831cdc4d00f3+1a315-amd_iopgtbl_jgg@nvidia.com
Signed-off-by: Joerg Roedel <jroedel@suse.de>
Signed-off-by: Sasha Levin <sashal@kernel.org>
[diewald: keep GCR3 table logic in place due to missing changes from
commit fb575d17813f iommu/amd: Refactor protection_domain helper
functions and related commits]
Signed-off-by: Manuel Diewald <manuel.diewald@canonical.com>
Signed-off-by: Koichiro Den <koichiro.den@canonical.com>
This commit is contained in:
committed by
Mehmet Basaran
parent
6c93150c15
commit
941843ba47
@@ -2077,31 +2077,11 @@ static void protection_domain_free(struct protection_domain *domain)
|
||||
kfree(domain);
|
||||
}
|
||||
|
||||
static int protection_domain_init_v1(struct protection_domain *domain)
|
||||
{
|
||||
domain->pd_mode = PD_MODE_V1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int protection_domain_init_v2(struct protection_domain *domain)
|
||||
{
|
||||
domain->flags |= PD_GIOV_MASK;
|
||||
domain->pd_mode = PD_MODE_V2;
|
||||
|
||||
domain->domain.pgsize_bitmap = AMD_IOMMU_PGSIZES_V2;
|
||||
|
||||
if (setup_gcr3_table(domain, 1))
|
||||
return -ENOMEM;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct protection_domain *protection_domain_alloc(unsigned int type)
|
||||
{
|
||||
struct io_pgtable_ops *pgtbl_ops;
|
||||
struct protection_domain *domain;
|
||||
int pgtable;
|
||||
int ret;
|
||||
|
||||
domain = kzalloc(sizeof(*domain), GFP_KERNEL);
|
||||
if (!domain)
|
||||
@@ -2135,18 +2115,18 @@ static struct protection_domain *protection_domain_alloc(unsigned int type)
|
||||
|
||||
switch (pgtable) {
|
||||
case AMD_IOMMU_V1:
|
||||
ret = protection_domain_init_v1(domain);
|
||||
domain->pd_mode = PD_MODE_V1;
|
||||
break;
|
||||
case AMD_IOMMU_V2:
|
||||
ret = protection_domain_init_v2(domain);
|
||||
domain->flags |= PD_GIOV_MASK;
|
||||
domain->pd_mode = PD_MODE_V2;
|
||||
|
||||
if (setup_gcr3_table(domain, 1))
|
||||
goto out_err;
|
||||
break;
|
||||
default:
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
if (ret)
|
||||
goto out_err;
|
||||
}
|
||||
|
||||
pgtbl_ops = alloc_io_pgtable_ops(pgtable, &domain->iop.pgtbl_cfg, domain);
|
||||
if (!pgtbl_ops)
|
||||
@@ -2202,10 +2182,10 @@ static struct iommu_domain *do_iommu_domain_alloc(unsigned int type,
|
||||
domain->domain.geometry.aperture_start = 0;
|
||||
domain->domain.geometry.aperture_end = dma_max_address();
|
||||
domain->domain.geometry.force_aperture = true;
|
||||
domain->domain.pgsize_bitmap = domain->iop.iop.cfg.pgsize_bitmap;
|
||||
|
||||
if (iommu) {
|
||||
domain->domain.type = type;
|
||||
domain->domain.pgsize_bitmap = iommu->iommu.ops->pgsize_bitmap;
|
||||
domain->domain.ops = iommu->iommu.ops->default_domain_ops;
|
||||
|
||||
if (dirty_tracking)
|
||||
@@ -2619,7 +2599,6 @@ const struct iommu_ops amd_iommu_ops = {
|
||||
.device_group = amd_iommu_device_group,
|
||||
.get_resv_regions = amd_iommu_get_resv_regions,
|
||||
.is_attach_deferred = amd_iommu_is_attach_deferred,
|
||||
.pgsize_bitmap = AMD_IOMMU_PGSIZES,
|
||||
.def_domain_type = amd_iommu_def_domain_type,
|
||||
.default_domain_ops = &(const struct iommu_domain_ops) {
|
||||
.attach_dev = amd_iommu_attach_device,
|
||||
|
||||
Reference in New Issue
Block a user