Skip to content

Commit ff18c4e

Browse files
garyrhookawilliam
authored andcommitted
iommu/amd: Set the device table entry PPR bit for IOMMU V2 devices
The AMD IOMMU specification Rev 3.00 (December 2016) introduces a new Enhanced PPR Handling Support (EPHSup) bit in the MMIO register offset 0030h (IOMMU Extended Feature Register). When EPHSup=1, the IOMMU hardware requires the PPR bit of the device table entry (DTE) to be set in order to support PPR for a particular endpoint device. Please see https://support.amd.com/TechDocs/48882_IOMMU.pdf for this revision of the AMD IOMMU specification. Signed-off-by: Gary R Hook <[email protected]> Signed-off-by: Alex Williamson <[email protected]>
1 parent f9fc049 commit ff18c4e

File tree

2 files changed

+17
-5
lines changed

2 files changed

+17
-5
lines changed

drivers/iommu/amd_iommu.c

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1817,7 +1817,8 @@ static bool dma_ops_domain(struct protection_domain *domain)
18171817
return domain->flags & PD_DMA_OPS_MASK;
18181818
}
18191819

1820-
static void set_dte_entry(u16 devid, struct protection_domain *domain, bool ats)
1820+
static void set_dte_entry(u16 devid, struct protection_domain *domain,
1821+
bool ats, bool ppr)
18211822
{
18221823
u64 pte_root = 0;
18231824
u64 flags = 0;
@@ -1834,6 +1835,13 @@ static void set_dte_entry(u16 devid, struct protection_domain *domain, bool ats)
18341835
if (ats)
18351836
flags |= DTE_FLAG_IOTLB;
18361837

1838+
if (ppr) {
1839+
struct amd_iommu *iommu = amd_iommu_rlookup_table[devid];
1840+
1841+
if (iommu_feature(iommu, FEATURE_EPHSUP))
1842+
pte_root |= 1ULL << DEV_ENTRY_PPR;
1843+
}
1844+
18371845
if (domain->flags & PD_IOMMUV2_MASK) {
18381846
u64 gcr3 = iommu_virt_to_phys(domain->gcr3_tbl);
18391847
u64 glx = domain->glx;
@@ -1896,9 +1904,9 @@ static void do_attach(struct iommu_dev_data *dev_data,
18961904
domain->dev_cnt += 1;
18971905

18981906
/* Update device table */
1899-
set_dte_entry(dev_data->devid, domain, ats);
1907+
set_dte_entry(dev_data->devid, domain, ats, dev_data->iommu_v2);
19001908
if (alias != dev_data->devid)
1901-
set_dte_entry(alias, domain, ats);
1909+
set_dte_entry(alias, domain, ats, dev_data->iommu_v2);
19021910

19031911
device_flush_dte(dev_data);
19041912
}
@@ -2277,13 +2285,15 @@ static void update_device_table(struct protection_domain *domain)
22772285
struct iommu_dev_data *dev_data;
22782286

22792287
list_for_each_entry(dev_data, &domain->dev_list, list) {
2280-
set_dte_entry(dev_data->devid, domain, dev_data->ats.enabled);
2288+
set_dte_entry(dev_data->devid, domain, dev_data->ats.enabled,
2289+
dev_data->iommu_v2);
22812290

22822291
if (dev_data->devid == dev_data->alias)
22832292
continue;
22842293

22852294
/* There is an alias, update device table entry for it */
2286-
set_dte_entry(dev_data->alias, domain, dev_data->ats.enabled);
2295+
set_dte_entry(dev_data->alias, domain, dev_data->ats.enabled,
2296+
dev_data->iommu_v2);
22872297
}
22882298
}
22892299

drivers/iommu/amd_iommu_types.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@
9898
#define FEATURE_HE (1ULL<<8)
9999
#define FEATURE_PC (1ULL<<9)
100100
#define FEATURE_GAM_VAPIC (1ULL<<21)
101+
#define FEATURE_EPHSUP (1ULL<<50)
101102

102103
#define FEATURE_PASID_SHIFT 32
103104
#define FEATURE_PASID_MASK (0x1fULL << FEATURE_PASID_SHIFT)
@@ -192,6 +193,7 @@
192193
/* macros and definitions for device table entries */
193194
#define DEV_ENTRY_VALID 0x00
194195
#define DEV_ENTRY_TRANSLATION 0x01
196+
#define DEV_ENTRY_PPR 0x34
195197
#define DEV_ENTRY_IR 0x3d
196198
#define DEV_ENTRY_IW 0x3e
197199
#define DEV_ENTRY_NO_PAGE_FAULT 0x62

0 commit comments

Comments
 (0)