When setting up IOMMU page table in nested mode, the host (v1) table
is managed by the hypervisor, while the guest (v2) table is managed by
the guest kernel. In this case, IOMMU driver needs to program IOMMU device
table entry (DTE) using the set_dte_entry() helper function with guest
table information (i.e. gcr3 table, glx, max pasid), which is stored
in the user domain.
There is no functional change.
Signed-off-by: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>
---
drivers/iommu/amd/amd_iommu.h | 1 +
drivers/iommu/amd/iommu.c | 9 ++++++---
2 files changed, 7 insertions(+), 3 deletions(-)
@@ -16,6 +16,7 @@ extern void iommu_feature_disable(struct amd_iommu *iommu, u8 bit);
extern u8 __iomem * __init iommu_map_mmio_space(u64 address, u64 end);
extern void set_dte_entry(struct amd_iommu *iommu, u16 devid,
struct protection_domain *domain,
+ struct protection_domain *udomain,
u64 *gcr3_tbl,
bool ats, bool ppr);
extern int iommu_flush_dte(struct amd_iommu *iommu, u16 devid);
@@ -1591,9 +1591,11 @@ static void set_dte_entry_v2(struct amd_iommu *iommu,
void set_dte_entry(struct amd_iommu *iommu, u16 devid,
struct protection_domain *domain,
+ struct protection_domain *udomain,
u64 *gcr3_tbl,
bool ats, bool ppr)
{
+ struct protection_domain *dom;
u64 pte_root = 0;
u64 flags = 0;
u32 old_domid;
@@ -1624,7 +1626,8 @@ void set_dte_entry(struct amd_iommu *iommu, u16 devid,
pte_root |= 1ULL << DEV_ENTRY_PPR;
}
- set_dte_entry_v2(iommu, domain, gcr3_tbl, &pte_root, &flags);
+ dom = udomain ? udomain : domain;
+ set_dte_entry_v2(iommu, dom, gcr3_tbl, &pte_root, &flags);
if ((domain->flags & PD_IOMMUV2_MASK) &&
amd_iommu_gpt_level == PAGE_MODE_5_LEVEL) {
@@ -1688,7 +1691,7 @@ static void do_attach(struct iommu_dev_data *dev_data,
domain->dev_cnt += 1;
/* Update device table */
- set_dte_entry(iommu, dev_data->devid, domain, domain->gcr3_tbl,
+ set_dte_entry(iommu, dev_data->devid, domain, NULL, domain->gcr3_tbl,
ats, dev_data->iommu_v2);
clone_aliases(iommu, dev_data->dev);
@@ -1967,7 +1970,7 @@ static void update_device_table(struct protection_domain *domain)
if (!iommu)
continue;
- set_dte_entry(iommu, dev_data->devid, domain, domain->gcr3_tbl,
+ set_dte_entry(iommu, dev_data->devid, domain, NULL, domain->gcr3_tbl,
dev_data->ats.enabled, dev_data->iommu_v2);
clone_aliases(iommu, dev_data->dev);
}