Skip to content

Commit 61928ba

Browse files
ssuthiku-amdjoergroedel
authored andcommitted
iommu/amd: Define per-IOMMU iopf_queue
AMD IOMMU hardware supports PCI Peripheral Paging Request (PPR) using a PPR log, which is a circular buffer containing requests from downstream end-point devices. There is one PPR log per IOMMU instance. Therefore, allocate an iopf_queue per IOMMU instance during driver initialization, and free the queue during driver deinitialization. Also rename enable_iommus_v2() -> enable_iommus_ppr() to reflect its usage. And add amd_iommu_gt_ppr_supported() check before enabling PPR log. Signed-off-by: Suravee Suthikulpanit <[email protected]> Co-developed-by: Vasant Hegde <[email protected]> Signed-off-by: Vasant Hegde <[email protected]> Reviewed-by: Jason Gunthorpe <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Joerg Roedel <[email protected]>
1 parent 25efbb0 commit 61928ba

File tree

4 files changed

+55
-2
lines changed

4 files changed

+55
-2
lines changed

drivers/iommu/amd/amd_iommu.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,10 @@ extern int amd_iommu_gpt_level;
4646

4747
bool amd_iommu_pasid_supported(void);
4848

49+
/* IOPF */
50+
int amd_iommu_iopf_init(struct amd_iommu *iommu);
51+
void amd_iommu_iopf_uninit(struct amd_iommu *iommu);
52+
4953
/* GCR3 setup */
5054
int amd_iommu_set_gcr3(struct iommu_dev_data *dev_data,
5155
ioasid_t pasid, unsigned long gcr3);

drivers/iommu/amd/amd_iommu_types.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -762,6 +762,10 @@ struct amd_iommu {
762762
/* DebugFS Info */
763763
struct dentry *debugfs;
764764
#endif
765+
766+
/* IOPF support */
767+
struct iopf_queue *iopf_queue;
768+
unsigned char iopfq_name[32];
765769
};
766770

767771
static inline struct amd_iommu *dev_to_amd_iommu(struct device *dev)

drivers/iommu/amd/init.c

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1639,6 +1639,7 @@ static void __init free_iommu_one(struct amd_iommu *iommu)
16391639
amd_iommu_free_ppr_log(iommu);
16401640
free_ga_log(iommu);
16411641
iommu_unmap_mmio_space(iommu);
1642+
amd_iommu_iopf_uninit(iommu);
16421643
}
16431644

16441645
static void __init free_iommu_all(void)
@@ -2108,6 +2109,16 @@ static int __init iommu_init_pci(struct amd_iommu *iommu)
21082109
if (ret)
21092110
return ret;
21102111

2112+
/*
2113+
* Allocate per IOMMU IOPF queue here so that in attach device path,
2114+
* PRI capable device can be added to IOPF queue
2115+
*/
2116+
if (amd_iommu_gt_ppr_supported()) {
2117+
ret = amd_iommu_iopf_init(iommu);
2118+
if (ret)
2119+
return ret;
2120+
}
2121+
21112122
iommu_device_register(&iommu->iommu, &amd_iommu_ops, NULL);
21122123

21132124
return pci_enable_device(iommu->dev);
@@ -2793,10 +2804,13 @@ static void early_enable_iommus(void)
27932804
}
27942805
}
27952806

2796-
static void enable_iommus_v2(void)
2807+
static void enable_iommus_ppr(void)
27972808
{
27982809
struct amd_iommu *iommu;
27992810

2811+
if (!amd_iommu_gt_ppr_supported())
2812+
return;
2813+
28002814
for_each_iommu(iommu)
28012815
amd_iommu_enable_ppr_log(iommu);
28022816
}
@@ -3134,7 +3148,7 @@ static int amd_iommu_enable_interrupts(void)
31343148
* PPR and GA log interrupt for all IOMMUs.
31353149
*/
31363150
enable_iommus_vapic();
3137-
enable_iommus_v2();
3151+
enable_iommus_ppr();
31383152

31393153
out:
31403154
return ret;

drivers/iommu/amd/ppr.c

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,3 +108,34 @@ void amd_iommu_poll_ppr_log(struct amd_iommu *iommu)
108108
/* TODO: PPR Handler will be added when we add IOPF support */
109109
}
110110
}
111+
112+
/**************************************************************
113+
*
114+
* IOPF handling stuff
115+
*/
116+
117+
/* Setup per-IOMMU IOPF queue if not exist. */
118+
int amd_iommu_iopf_init(struct amd_iommu *iommu)
119+
{
120+
int ret = 0;
121+
122+
if (iommu->iopf_queue)
123+
return ret;
124+
125+
snprintf(iommu->iopfq_name, sizeof(iommu->iopfq_name),
126+
"amdiommu-%#x-iopfq",
127+
PCI_SEG_DEVID_TO_SBDF(iommu->pci_seg->id, iommu->devid));
128+
129+
iommu->iopf_queue = iopf_queue_alloc(iommu->iopfq_name);
130+
if (!iommu->iopf_queue)
131+
ret = -ENOMEM;
132+
133+
return ret;
134+
}
135+
136+
/* Destroy per-IOMMU IOPF queue if no longer needed. */
137+
void amd_iommu_iopf_uninit(struct amd_iommu *iommu)
138+
{
139+
iopf_queue_free(iommu->iopf_queue);
140+
iommu->iopf_queue = NULL;
141+
}

0 commit comments

Comments
 (0)