Commit 6eedb59c authored by Suravee Suthikulpanit's avatar Suravee Suthikulpanit Committed by Joerg Roedel

iommu/amd: Remove amd_iommu_domain_get_pgtable

Since the IO page table root and mode parameters have been moved into
the struct amd_io_pg, the function is no longer needed. Therefore,
remove it along with the struct domain_pgtable.
Signed-off-by: default avatarSuravee Suthikulpanit <suravee.suthikulpanit@amd.com>
Link: https://lore.kernel.org/r/20201215073705.123786-9-suravee.suthikulpanit@amd.comSigned-off-by: default avatarJoerg Roedel <jroedel@suse.de>
parent e42ba063
...@@ -110,6 +110,8 @@ static inline ...@@ -110,6 +110,8 @@ static inline
void amd_iommu_domain_set_pt_root(struct protection_domain *domain, u64 root) void amd_iommu_domain_set_pt_root(struct protection_domain *domain, u64 root)
{ {
atomic64_set(&domain->iop.pt_root, root); atomic64_set(&domain->iop.pt_root, root);
domain->iop.root = (u64 *)(root & PAGE_MASK);
domain->iop.mode = root & 7; /* lowest 3 bits encode pgtable mode */
} }
static inline static inline
...@@ -144,8 +146,6 @@ extern unsigned long iommu_unmap_page(struct protection_domain *dom, ...@@ -144,8 +146,6 @@ extern unsigned long iommu_unmap_page(struct protection_domain *dom,
extern u64 *fetch_pte(struct protection_domain *domain, extern u64 *fetch_pte(struct protection_domain *domain,
unsigned long address, unsigned long address,
unsigned long *page_size); unsigned long *page_size);
extern void amd_iommu_domain_get_pgtable(struct protection_domain *domain,
struct domain_pgtable *pgtable);
extern void amd_iommu_domain_set_pgtable(struct protection_domain *domain, extern void amd_iommu_domain_set_pgtable(struct protection_domain *domain,
u64 *root, int mode); u64 *root, int mode);
#endif #endif
...@@ -519,12 +519,6 @@ struct protection_domain { ...@@ -519,12 +519,6 @@ struct protection_domain {
unsigned dev_iommu[MAX_IOMMUS]; /* per-IOMMU reference count */ unsigned dev_iommu[MAX_IOMMUS]; /* per-IOMMU reference count */
}; };
/* For decocded pt_root */
struct domain_pgtable {
int mode;
u64 *root;
};
/* /*
* Structure where we save information about one hardware AMD IOMMU in the * Structure where we save information about one hardware AMD IOMMU in the
* system. * system.
......
...@@ -178,30 +178,27 @@ static bool increase_address_space(struct protection_domain *domain, ...@@ -178,30 +178,27 @@ static bool increase_address_space(struct protection_domain *domain,
unsigned long address, unsigned long address,
gfp_t gfp) gfp_t gfp)
{ {
struct domain_pgtable pgtable;
unsigned long flags; unsigned long flags;
bool ret = true; bool ret = true;
u64 *pte; u64 *pte;
spin_lock_irqsave(&domain->lock, flags); spin_lock_irqsave(&domain->lock, flags);
amd_iommu_domain_get_pgtable(domain, &pgtable); if (address <= PM_LEVEL_SIZE(domain->iop.mode))
if (address <= PM_LEVEL_SIZE(pgtable.mode))
goto out; goto out;
ret = false; ret = false;
if (WARN_ON_ONCE(pgtable.mode == PAGE_MODE_6_LEVEL)) if (WARN_ON_ONCE(domain->iop.mode == PAGE_MODE_6_LEVEL))
goto out; goto out;
pte = (void *)get_zeroed_page(gfp); pte = (void *)get_zeroed_page(gfp);
if (!pte) if (!pte)
goto out; goto out;
*pte = PM_LEVEL_PDE(pgtable.mode, iommu_virt_to_phys(pgtable.root)); *pte = PM_LEVEL_PDE(domain->iop.mode, iommu_virt_to_phys(domain->iop.root));
pgtable.root = pte; domain->iop.root = pte;
pgtable.mode += 1; domain->iop.mode += 1;
amd_iommu_update_and_flush_device_table(domain); amd_iommu_update_and_flush_device_table(domain);
amd_iommu_domain_flush_complete(domain); amd_iommu_domain_flush_complete(domain);
...@@ -209,7 +206,7 @@ static bool increase_address_space(struct protection_domain *domain, ...@@ -209,7 +206,7 @@ static bool increase_address_space(struct protection_domain *domain,
* Device Table needs to be updated and flushed before the new root can * Device Table needs to be updated and flushed before the new root can
* be published. * be published.
*/ */
amd_iommu_domain_set_pgtable(domain, pte, pgtable.mode); amd_iommu_domain_set_pgtable(domain, pte, domain->iop.mode);
ret = true; ret = true;
...@@ -226,29 +223,23 @@ static u64 *alloc_pte(struct protection_domain *domain, ...@@ -226,29 +223,23 @@ static u64 *alloc_pte(struct protection_domain *domain,
gfp_t gfp, gfp_t gfp,
bool *updated) bool *updated)
{ {
struct domain_pgtable pgtable;
int level, end_lvl; int level, end_lvl;
u64 *pte, *page; u64 *pte, *page;
BUG_ON(!is_power_of_2(page_size)); BUG_ON(!is_power_of_2(page_size));
amd_iommu_domain_get_pgtable(domain, &pgtable); while (address > PM_LEVEL_SIZE(domain->iop.mode)) {
while (address > PM_LEVEL_SIZE(pgtable.mode)) {
/* /*
* Return an error if there is no memory to update the * Return an error if there is no memory to update the
* page-table. * page-table.
*/ */
if (!increase_address_space(domain, address, gfp)) if (!increase_address_space(domain, address, gfp))
return NULL; return NULL;
/* Read new values to check if update was successful */
amd_iommu_domain_get_pgtable(domain, &pgtable);
} }
level = pgtable.mode - 1; level = domain->iop.mode - 1;
pte = &pgtable.root[PM_LEVEL_INDEX(level, address)]; pte = &domain->iop.root[PM_LEVEL_INDEX(level, address)];
address = PAGE_SIZE_ALIGN(address, page_size); address = PAGE_SIZE_ALIGN(address, page_size);
end_lvl = PAGE_SIZE_LEVEL(page_size); end_lvl = PAGE_SIZE_LEVEL(page_size);
...@@ -324,19 +315,16 @@ u64 *fetch_pte(struct protection_domain *domain, ...@@ -324,19 +315,16 @@ u64 *fetch_pte(struct protection_domain *domain,
unsigned long address, unsigned long address,
unsigned long *page_size) unsigned long *page_size)
{ {
struct domain_pgtable pgtable;
int level; int level;
u64 *pte; u64 *pte;
*page_size = 0; *page_size = 0;
amd_iommu_domain_get_pgtable(domain, &pgtable); if (address > PM_LEVEL_SIZE(domain->iop.mode))
if (address > PM_LEVEL_SIZE(pgtable.mode))
return NULL; return NULL;
level = pgtable.mode - 1; level = domain->iop.mode - 1;
pte = &pgtable.root[PM_LEVEL_INDEX(level, address)]; pte = &domain->iop.root[PM_LEVEL_INDEX(level, address)];
*page_size = PTE_LEVEL_PAGE_SIZE(level); *page_size = PTE_LEVEL_PAGE_SIZE(level);
while (level > 0) { while (level > 0) {
......
...@@ -138,15 +138,6 @@ static struct protection_domain *to_pdomain(struct iommu_domain *dom) ...@@ -138,15 +138,6 @@ static struct protection_domain *to_pdomain(struct iommu_domain *dom)
return container_of(dom, struct protection_domain, domain); return container_of(dom, struct protection_domain, domain);
} }
void amd_iommu_domain_get_pgtable(struct protection_domain *domain,
struct domain_pgtable *pgtable)
{
u64 pt_root = atomic64_read(&domain->iop.pt_root);
pgtable->root = (u64 *)(pt_root & PAGE_MASK);
pgtable->mode = pt_root & 7; /* lowest 3 bits encode pgtable mode */
}
static struct iommu_dev_data *alloc_dev_data(u16 devid) static struct iommu_dev_data *alloc_dev_data(u16 devid)
{ {
struct iommu_dev_data *dev_data; struct iommu_dev_data *dev_data;
...@@ -1483,7 +1474,6 @@ static void clear_dte_entry(u16 devid) ...@@ -1483,7 +1474,6 @@ static void clear_dte_entry(u16 devid)
static void do_attach(struct iommu_dev_data *dev_data, static void do_attach(struct iommu_dev_data *dev_data,
struct protection_domain *domain) struct protection_domain *domain)
{ {
struct domain_pgtable pgtable;
struct amd_iommu *iommu; struct amd_iommu *iommu;
bool ats; bool ats;
...@@ -1499,7 +1489,6 @@ static void do_attach(struct iommu_dev_data *dev_data, ...@@ -1499,7 +1489,6 @@ static void do_attach(struct iommu_dev_data *dev_data,
domain->dev_cnt += 1; domain->dev_cnt += 1;
/* Update device table */ /* Update device table */
amd_iommu_domain_get_pgtable(domain, &pgtable);
set_dte_entry(dev_data->devid, domain, set_dte_entry(dev_data->devid, domain,
ats, dev_data->iommu_v2); ats, dev_data->iommu_v2);
clone_aliases(dev_data->pdev); clone_aliases(dev_data->pdev);
...@@ -1826,10 +1815,7 @@ void amd_iommu_update_and_flush_device_table(struct protection_domain *domain) ...@@ -1826,10 +1815,7 @@ void amd_iommu_update_and_flush_device_table(struct protection_domain *domain)
void amd_iommu_domain_update(struct protection_domain *domain) void amd_iommu_domain_update(struct protection_domain *domain)
{ {
struct domain_pgtable pgtable;
/* Update device table */ /* Update device table */
amd_iommu_domain_get_pgtable(domain, &pgtable);
amd_iommu_update_and_flush_device_table(domain); amd_iommu_update_and_flush_device_table(domain);
/* Flush domain TLB(s) and wait for completion */ /* Flush domain TLB(s) and wait for completion */
...@@ -2079,12 +2065,10 @@ static int amd_iommu_map(struct iommu_domain *dom, unsigned long iova, ...@@ -2079,12 +2065,10 @@ static int amd_iommu_map(struct iommu_domain *dom, unsigned long iova,
gfp_t gfp) gfp_t gfp)
{ {
struct protection_domain *domain = to_pdomain(dom); struct protection_domain *domain = to_pdomain(dom);
struct domain_pgtable pgtable;
int prot = 0; int prot = 0;
int ret; int ret;
amd_iommu_domain_get_pgtable(domain, &pgtable); if (domain->iop.mode == PAGE_MODE_NONE)
if (pgtable.mode == PAGE_MODE_NONE)
return -EINVAL; return -EINVAL;
if (iommu_prot & IOMMU_READ) if (iommu_prot & IOMMU_READ)
...@@ -2104,10 +2088,8 @@ static size_t amd_iommu_unmap(struct iommu_domain *dom, unsigned long iova, ...@@ -2104,10 +2088,8 @@ static size_t amd_iommu_unmap(struct iommu_domain *dom, unsigned long iova,
struct iommu_iotlb_gather *gather) struct iommu_iotlb_gather *gather)
{ {
struct protection_domain *domain = to_pdomain(dom); struct protection_domain *domain = to_pdomain(dom);
struct domain_pgtable pgtable;
amd_iommu_domain_get_pgtable(domain, &pgtable); if (domain->iop.mode == PAGE_MODE_NONE)
if (pgtable.mode == PAGE_MODE_NONE)
return 0; return 0;
return iommu_unmap_page(domain, iova, page_size); return iommu_unmap_page(domain, iova, page_size);
...@@ -2118,11 +2100,9 @@ static phys_addr_t amd_iommu_iova_to_phys(struct iommu_domain *dom, ...@@ -2118,11 +2100,9 @@ static phys_addr_t amd_iommu_iova_to_phys(struct iommu_domain *dom,
{ {
struct protection_domain *domain = to_pdomain(dom); struct protection_domain *domain = to_pdomain(dom);
unsigned long offset_mask, pte_pgsize; unsigned long offset_mask, pte_pgsize;
struct domain_pgtable pgtable;
u64 *pte, __pte; u64 *pte, __pte;
amd_iommu_domain_get_pgtable(domain, &pgtable); if (domain->iop.mode == PAGE_MODE_NONE)
if (pgtable.mode == PAGE_MODE_NONE)
return iova; return iova;
pte = fetch_pte(domain, iova, &pte_pgsize); pte = fetch_pte(domain, iova, &pte_pgsize);
...@@ -2492,11 +2472,9 @@ static u64 *__get_gcr3_pte(u64 *root, int level, u32 pasid, bool alloc) ...@@ -2492,11 +2472,9 @@ static u64 *__get_gcr3_pte(u64 *root, int level, u32 pasid, bool alloc)
static int __set_gcr3(struct protection_domain *domain, u32 pasid, static int __set_gcr3(struct protection_domain *domain, u32 pasid,
unsigned long cr3) unsigned long cr3)
{ {
struct domain_pgtable pgtable;
u64 *pte; u64 *pte;
amd_iommu_domain_get_pgtable(domain, &pgtable); if (domain->iop.mode != PAGE_MODE_NONE)
if (pgtable.mode != PAGE_MODE_NONE)
return -EINVAL; return -EINVAL;
pte = __get_gcr3_pte(domain->gcr3_tbl, domain->glx, pasid, true); pte = __get_gcr3_pte(domain->gcr3_tbl, domain->glx, pasid, true);
...@@ -2510,11 +2488,9 @@ static int __set_gcr3(struct protection_domain *domain, u32 pasid, ...@@ -2510,11 +2488,9 @@ static int __set_gcr3(struct protection_domain *domain, u32 pasid,
static int __clear_gcr3(struct protection_domain *domain, u32 pasid) static int __clear_gcr3(struct protection_domain *domain, u32 pasid)
{ {
struct domain_pgtable pgtable;
u64 *pte; u64 *pte;
amd_iommu_domain_get_pgtable(domain, &pgtable); if (domain->iop.mode != PAGE_MODE_NONE)
if (pgtable.mode != PAGE_MODE_NONE)
return -EINVAL; return -EINVAL;
pte = __get_gcr3_pte(domain->gcr3_tbl, domain->glx, pasid, false); pte = __get_gcr3_pte(domain->gcr3_tbl, domain->glx, pasid, false);
......
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