Skip to content

Commit 386ae59

Browse files
hegdevasantjoergroedel
authored andcommitted
iommu/amd: Generalize log overflow handling
Each IOMMU has three log buffers (Event, GA and PPR log). Once a buffer becomes full, IOMMU generates an interrupt with the corresponding overflow status bit, and stop processing the log. To handle an overflow, the IOMMU driver needs to disable the log, clear the overflow status bit, and re-enable the log. This procedure is same among all types of log buffer except it uses different overflow status bit and enabling bit. Hence, to consolidate the log buffer restarting logic, introduce a helper function amd_iommu_restart_log(), which caller can specify parameters specific for each type of log buffer. Also rename MMIO_STATUS_EVT_OVERFLOW_INT_MASK as MMIO_STATUS_EVT_OVERFLOW_MASK. 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 d269ab6 commit 386ae59

File tree

3 files changed

+36
-22
lines changed

3 files changed

+36
-22
lines changed

drivers/iommu/amd/amd_iommu_types.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,9 +120,10 @@
120120
#define PASID_MASK 0x0000ffff
121121

122122
/* MMIO status bits */
123-
#define MMIO_STATUS_EVT_OVERFLOW_INT_MASK BIT(0)
123+
#define MMIO_STATUS_EVT_OVERFLOW_MASK BIT(0)
124124
#define MMIO_STATUS_EVT_INT_MASK BIT(1)
125125
#define MMIO_STATUS_COM_WAIT_INT_MASK BIT(2)
126+
#define MMIO_STATUS_EVT_RUN_MASK BIT(3)
126127
#define MMIO_STATUS_PPR_INT_MASK BIT(6)
127128
#define MMIO_STATUS_GALOG_RUN_MASK BIT(8)
128129
#define MMIO_STATUS_GALOG_OVERFLOW_MASK BIT(9)

drivers/iommu/amd/init.c

Lines changed: 32 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -752,38 +752,51 @@ static int __init alloc_command_buffer(struct amd_iommu *iommu)
752752
return iommu->cmd_buf ? 0 : -ENOMEM;
753753
}
754754

755+
/*
756+
* Interrupt handler has processed all pending events and adjusted head
757+
* and tail pointer. Reset overflow mask and restart logging again.
758+
*/
759+
static void amd_iommu_restart_log(struct amd_iommu *iommu, const char *evt_type,
760+
u8 cntrl_intr, u8 cntrl_log,
761+
u32 status_run_mask, u32 status_overflow_mask)
762+
{
763+
u32 status;
764+
765+
status = readl(iommu->mmio_base + MMIO_STATUS_OFFSET);
766+
if (status & status_run_mask)
767+
return;
768+
769+
pr_info_ratelimited("IOMMU %s log restarting\n", evt_type);
770+
771+
iommu_feature_disable(iommu, cntrl_log);
772+
iommu_feature_disable(iommu, cntrl_intr);
773+
774+
writel(status_overflow_mask, iommu->mmio_base + MMIO_STATUS_OFFSET);
775+
776+
iommu_feature_enable(iommu, cntrl_intr);
777+
iommu_feature_enable(iommu, cntrl_log);
778+
}
779+
755780
/*
756781
* This function restarts event logging in case the IOMMU experienced
757782
* an event log buffer overflow.
758783
*/
759784
void amd_iommu_restart_event_logging(struct amd_iommu *iommu)
760785
{
761-
iommu_feature_disable(iommu, CONTROL_EVT_LOG_EN);
762-
iommu_feature_enable(iommu, CONTROL_EVT_LOG_EN);
786+
amd_iommu_restart_log(iommu, "Event", CONTROL_EVT_INT_EN,
787+
CONTROL_EVT_LOG_EN, MMIO_STATUS_EVT_RUN_MASK,
788+
MMIO_STATUS_EVT_OVERFLOW_MASK);
763789
}
764790

765791
/*
766792
* This function restarts event logging in case the IOMMU experienced
767-
* an GA log overflow.
793+
* GA log overflow.
768794
*/
769795
void amd_iommu_restart_ga_log(struct amd_iommu *iommu)
770796
{
771-
u32 status;
772-
773-
status = readl(iommu->mmio_base + MMIO_STATUS_OFFSET);
774-
if (status & MMIO_STATUS_GALOG_RUN_MASK)
775-
return;
776-
777-
pr_info_ratelimited("IOMMU GA Log restarting\n");
778-
779-
iommu_feature_disable(iommu, CONTROL_GALOG_EN);
780-
iommu_feature_disable(iommu, CONTROL_GAINT_EN);
781-
782-
writel(MMIO_STATUS_GALOG_OVERFLOW_MASK,
783-
iommu->mmio_base + MMIO_STATUS_OFFSET);
784-
785-
iommu_feature_enable(iommu, CONTROL_GAINT_EN);
786-
iommu_feature_enable(iommu, CONTROL_GALOG_EN);
797+
amd_iommu_restart_log(iommu, "GA", CONTROL_GAINT_EN,
798+
CONTROL_GALOG_EN, MMIO_STATUS_GALOG_RUN_MASK,
799+
MMIO_STATUS_GALOG_OVERFLOW_MASK);
787800
}
788801

789802
/*

drivers/iommu/amd/iommu.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -842,7 +842,7 @@ amd_iommu_set_pci_msi_domain(struct device *dev, struct amd_iommu *iommu) { }
842842
#endif /* !CONFIG_IRQ_REMAP */
843843

844844
#define AMD_IOMMU_INT_MASK \
845-
(MMIO_STATUS_EVT_OVERFLOW_INT_MASK | \
845+
(MMIO_STATUS_EVT_OVERFLOW_MASK | \
846846
MMIO_STATUS_EVT_INT_MASK | \
847847
MMIO_STATUS_PPR_INT_MASK | \
848848
MMIO_STATUS_GALOG_OVERFLOW_MASK | \
@@ -881,7 +881,7 @@ irqreturn_t amd_iommu_int_thread(int irq, void *data)
881881
}
882882
#endif
883883

884-
if (status & MMIO_STATUS_EVT_OVERFLOW_INT_MASK) {
884+
if (status & MMIO_STATUS_EVT_OVERFLOW_MASK) {
885885
pr_info_ratelimited("IOMMU event log overflow\n");
886886
amd_iommu_restart_event_logging(iommu);
887887
}

0 commit comments

Comments
 (0)