Skip to content

Commit 2379f34

Browse files
hegdevasantjoergroedel
authored andcommitted
iommu/amd: Refactor IOMMU interrupt handling logic for Event, PPR, and GA logs
The AMD IOMMU has three log buffers (i.e. Event, PPR, and GA). The IOMMU driver processes these log entries when it receive an IOMMU interrupt. Then, it needs to clear the corresponding interrupt status bits. Also, when an overflow occurs, it needs to handle the log overflow by clearing the specific overflow status bit and restart the log. Since, logic for handling these logs is the same, refactor the code into a helper function called amd_iommu_handle_irq(), which handles the steps described. Then, reuse it for all types of log. Reviewed-by: Suravee Suthikulpanit <[email protected]> Signed-off-by: Vasant Hegde<[email protected]> Reviewed-by: Jerry Snitselaar <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Joerg Roedel <[email protected]>
1 parent 274c221 commit 2379f34

File tree

2 files changed

+53
-43
lines changed

2 files changed

+53
-43
lines changed

drivers/iommu/amd/amd_iommu.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@
1212
#include "amd_iommu_types.h"
1313

1414
irqreturn_t amd_iommu_int_thread(int irq, void *data);
15+
irqreturn_t amd_iommu_int_thread_evtlog(int irq, void *data);
16+
irqreturn_t amd_iommu_int_thread_pprlog(int irq, void *data);
17+
irqreturn_t amd_iommu_int_thread_galog(int irq, void *data);
1518
irqreturn_t amd_iommu_int_handler(int irq, void *data);
1619
void amd_iommu_apply_erratum_63(struct amd_iommu *iommu, u16 devid);
1720
void amd_iommu_restart_event_logging(struct amd_iommu *iommu);

drivers/iommu/amd/iommu.c

Lines changed: 50 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -841,57 +841,27 @@ static inline void
841841
amd_iommu_set_pci_msi_domain(struct device *dev, struct amd_iommu *iommu) { }
842842
#endif /* !CONFIG_IRQ_REMAP */
843843

844-
#define AMD_IOMMU_INT_MASK \
845-
(MMIO_STATUS_EVT_OVERFLOW_MASK | \
846-
MMIO_STATUS_EVT_INT_MASK | \
847-
MMIO_STATUS_PPR_OVERFLOW_MASK | \
848-
MMIO_STATUS_PPR_INT_MASK | \
849-
MMIO_STATUS_GALOG_OVERFLOW_MASK | \
850-
MMIO_STATUS_GALOG_INT_MASK)
851-
852-
irqreturn_t amd_iommu_int_thread(int irq, void *data)
844+
static void amd_iommu_handle_irq(void *data, const char *evt_type,
845+
u32 int_mask, u32 overflow_mask,
846+
void (*int_handler)(struct amd_iommu *),
847+
void (*overflow_handler)(struct amd_iommu *))
853848
{
854849
struct amd_iommu *iommu = (struct amd_iommu *) data;
855850
u32 status = readl(iommu->mmio_base + MMIO_STATUS_OFFSET);
851+
u32 mask = int_mask | overflow_mask;
856852

857-
while (status & AMD_IOMMU_INT_MASK) {
853+
while (status & mask) {
858854
/* Enable interrupt sources again */
859-
writel(AMD_IOMMU_INT_MASK,
860-
iommu->mmio_base + MMIO_STATUS_OFFSET);
861-
862-
if (status & MMIO_STATUS_EVT_INT_MASK) {
863-
pr_devel("Processing IOMMU Event Log\n");
864-
iommu_poll_events(iommu);
865-
}
866-
867-
if (status & (MMIO_STATUS_PPR_INT_MASK |
868-
MMIO_STATUS_PPR_OVERFLOW_MASK)) {
869-
pr_devel("Processing IOMMU PPR Log\n");
870-
iommu_poll_ppr_log(iommu);
871-
}
872-
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-
878-
#ifdef CONFIG_IRQ_REMAP
879-
if (status & (MMIO_STATUS_GALOG_INT_MASK |
880-
MMIO_STATUS_GALOG_OVERFLOW_MASK)) {
881-
pr_devel("Processing IOMMU GA Log\n");
882-
iommu_poll_ga_log(iommu);
883-
}
855+
writel(mask, iommu->mmio_base + MMIO_STATUS_OFFSET);
884856

885-
if (status & MMIO_STATUS_GALOG_OVERFLOW_MASK) {
886-
pr_info_ratelimited("IOMMU GA Log overflow\n");
887-
amd_iommu_restart_ga_log(iommu);
857+
if (int_handler) {
858+
pr_devel("Processing IOMMU (ivhd%d) %s Log\n",
859+
iommu->index, evt_type);
860+
int_handler(iommu);
888861
}
889-
#endif
890862

891-
if (status & MMIO_STATUS_EVT_OVERFLOW_MASK) {
892-
pr_info_ratelimited("IOMMU event log overflow\n");
893-
amd_iommu_restart_event_logging(iommu);
894-
}
863+
if ((status & overflow_mask) && overflow_handler)
864+
overflow_handler(iommu);
895865

896866
/*
897867
* Hardware bug: ERBT1312
@@ -908,6 +878,43 @@ irqreturn_t amd_iommu_int_thread(int irq, void *data)
908878
*/
909879
status = readl(iommu->mmio_base + MMIO_STATUS_OFFSET);
910880
}
881+
}
882+
883+
irqreturn_t amd_iommu_int_thread_evtlog(int irq, void *data)
884+
{
885+
amd_iommu_handle_irq(data, "Evt", MMIO_STATUS_EVT_INT_MASK,
886+
MMIO_STATUS_EVT_OVERFLOW_MASK,
887+
iommu_poll_events, amd_iommu_restart_event_logging);
888+
889+
return IRQ_HANDLED;
890+
}
891+
892+
irqreturn_t amd_iommu_int_thread_pprlog(int irq, void *data)
893+
{
894+
amd_iommu_handle_irq(data, "PPR", MMIO_STATUS_PPR_INT_MASK,
895+
MMIO_STATUS_PPR_OVERFLOW_MASK,
896+
iommu_poll_ppr_log, amd_iommu_restart_ppr_log);
897+
898+
return IRQ_HANDLED;
899+
}
900+
901+
irqreturn_t amd_iommu_int_thread_galog(int irq, void *data)
902+
{
903+
#ifdef CONFIG_IRQ_REMAP
904+
amd_iommu_handle_irq(data, "GA", MMIO_STATUS_GALOG_INT_MASK,
905+
MMIO_STATUS_GALOG_OVERFLOW_MASK,
906+
iommu_poll_ga_log, amd_iommu_restart_ga_log);
907+
#endif
908+
909+
return IRQ_HANDLED;
910+
}
911+
912+
irqreturn_t amd_iommu_int_thread(int irq, void *data)
913+
{
914+
amd_iommu_int_thread_evtlog(irq, data);
915+
amd_iommu_int_thread_pprlog(irq, data);
916+
amd_iommu_int_thread_galog(irq, data);
917+
911918
return IRQ_HANDLED;
912919
}
913920

0 commit comments

Comments
 (0)