Skip to content

Commit 274c221

Browse files
hegdevasantjoergroedel
authored andcommitted
iommu/amd: Handle PPR log overflow
Some ATS-capable peripherals can issue requests to the processor to service peripheral page requests using PCIe PRI (the Page Request Interface). IOMMU supports PRI using PPR log buffer. IOMMU writes PRI request to PPR log buffer and sends PPR interrupt to host. When there is no space in the PPR log buffer (PPR log overflow) it will set PprOverflow bit in 'MMIO Offset 2020h IOMMU Status Register'. When this happens PPR log needs to be restarted as specified in IOMMU spec [1] section 2.6.2. When handling the event it just resumes the PPR log without resizing (similar to the way event and GA log overflow is handled). Failing to handle PPR overflow means device may not work properly as IOMMU stops processing new PPR events from device. [1] https://www.amd.com/system/files/TechDocs/48882_3.07_PUB.pdf Reviewed-by: Jerry Snitselaar <[email protected]> Reviewed-by: Suravee Suthikulpanit <[email protected]> Reviewed-by: Joao Martins <[email protected]> Signed-off-by: Vasant Hegde <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Joerg Roedel <[email protected]>
1 parent 386ae59 commit 274c221

File tree

4 files changed

+22
-1
lines changed

4 files changed

+22
-1
lines changed

drivers/iommu/amd/amd_iommu.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ irqreturn_t amd_iommu_int_handler(int irq, void *data);
1616
void amd_iommu_apply_erratum_63(struct amd_iommu *iommu, u16 devid);
1717
void amd_iommu_restart_event_logging(struct amd_iommu *iommu);
1818
void amd_iommu_restart_ga_log(struct amd_iommu *iommu);
19+
void amd_iommu_restart_ppr_log(struct amd_iommu *iommu);
1920
int amd_iommu_init_devices(void);
2021
void amd_iommu_uninit_devices(void);
2122
void amd_iommu_init_notifier(void);

drivers/iommu/amd/amd_iommu_types.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,9 @@
124124
#define MMIO_STATUS_EVT_INT_MASK BIT(1)
125125
#define MMIO_STATUS_COM_WAIT_INT_MASK BIT(2)
126126
#define MMIO_STATUS_EVT_RUN_MASK BIT(3)
127+
#define MMIO_STATUS_PPR_OVERFLOW_MASK BIT(5)
127128
#define MMIO_STATUS_PPR_INT_MASK BIT(6)
129+
#define MMIO_STATUS_PPR_RUN_MASK BIT(7)
128130
#define MMIO_STATUS_GALOG_RUN_MASK BIT(8)
129131
#define MMIO_STATUS_GALOG_OVERFLOW_MASK BIT(9)
130132
#define MMIO_STATUS_GALOG_INT_MASK BIT(10)

drivers/iommu/amd/init.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -799,6 +799,17 @@ void amd_iommu_restart_ga_log(struct amd_iommu *iommu)
799799
MMIO_STATUS_GALOG_OVERFLOW_MASK);
800800
}
801801

802+
/*
803+
* This function restarts ppr logging in case the IOMMU experienced
804+
* PPR log overflow.
805+
*/
806+
void amd_iommu_restart_ppr_log(struct amd_iommu *iommu)
807+
{
808+
amd_iommu_restart_log(iommu, "PPR", CONTROL_PPRINT_EN,
809+
CONTROL_PPRLOG_EN, MMIO_STATUS_PPR_RUN_MASK,
810+
MMIO_STATUS_PPR_OVERFLOW_MASK);
811+
}
812+
802813
/*
803814
* This function resets the command buffer if the IOMMU stopped fetching
804815
* commands from it.

drivers/iommu/amd/iommu.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -844,6 +844,7 @@ amd_iommu_set_pci_msi_domain(struct device *dev, struct amd_iommu *iommu) { }
844844
#define AMD_IOMMU_INT_MASK \
845845
(MMIO_STATUS_EVT_OVERFLOW_MASK | \
846846
MMIO_STATUS_EVT_INT_MASK | \
847+
MMIO_STATUS_PPR_OVERFLOW_MASK | \
847848
MMIO_STATUS_PPR_INT_MASK | \
848849
MMIO_STATUS_GALOG_OVERFLOW_MASK | \
849850
MMIO_STATUS_GALOG_INT_MASK)
@@ -863,11 +864,17 @@ irqreturn_t amd_iommu_int_thread(int irq, void *data)
863864
iommu_poll_events(iommu);
864865
}
865866

866-
if (status & MMIO_STATUS_PPR_INT_MASK) {
867+
if (status & (MMIO_STATUS_PPR_INT_MASK |
868+
MMIO_STATUS_PPR_OVERFLOW_MASK)) {
867869
pr_devel("Processing IOMMU PPR Log\n");
868870
iommu_poll_ppr_log(iommu);
869871
}
870872

873+
if (status & MMIO_STATUS_PPR_OVERFLOW_MASK) {
874+
pr_info_ratelimited("IOMMU PPR log overflow\n");
875+
amd_iommu_restart_ppr_log(iommu);
876+
}
877+
871878
#ifdef CONFIG_IRQ_REMAP
872879
if (status & (MMIO_STATUS_GALOG_INT_MASK |
873880
MMIO_STATUS_GALOG_OVERFLOW_MASK)) {

0 commit comments

Comments
 (0)