Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c43fce4e authored by Alex Williamson's avatar Alex Williamson Committed by Joerg Roedel
Browse files

iommu/vt-d: Ratelimit fault handler



Fault rates can easily overwhelm the console and make the system
unresponsive.  Ratelimit to allow an opportunity for maintenance.

Signed-off-by: default avatarAlex Williamson <alex.williamson@redhat.com>
Fixes: 0ac2491f ('x86, dmar: move page fault handling code to dmar.c')
Signed-off-by: default avatarJoerg Roedel <jroedel@suse.de>
parent 9735a227
Loading
Loading
Loading
Loading
+22 −11
Original line number Diff line number Diff line
@@ -1602,10 +1602,17 @@ irqreturn_t dmar_fault(int irq, void *dev_id)
	int reg, fault_index;
	u32 fault_status;
	unsigned long flag;
	bool ratelimited;
	static DEFINE_RATELIMIT_STATE(rs,
				      DEFAULT_RATELIMIT_INTERVAL,
				      DEFAULT_RATELIMIT_BURST);

	/* Disable printing, simply clear the fault when ratelimited */
	ratelimited = !__ratelimit(&rs);

	raw_spin_lock_irqsave(&iommu->register_lock, flag);
	fault_status = readl(iommu->reg + DMAR_FSTS_REG);
	if (fault_status)
	if (fault_status && !ratelimited)
		pr_err("DRHD: handling fault status reg %x\n", fault_status);

	/* TBD: ignore advanced fault log currently */
@@ -1627,6 +1634,7 @@ irqreturn_t dmar_fault(int irq, void *dev_id)
		if (!(data & DMA_FRCD_F))
			break;

		if (!ratelimited) {
			fault_reason = dma_frcd_fault_reason(data);
			type = dma_frcd_type(data);

@@ -1637,12 +1645,15 @@ irqreturn_t dmar_fault(int irq, void *dev_id)
			guest_addr = dmar_readq(iommu->reg + reg +
					fault_index * PRIMARY_FAULT_REG_LEN);
			guest_addr = dma_frcd_page_addr(guest_addr);
		}

		/* clear the fault */
		writel(DMA_FRCD_F, iommu->reg + reg +
			fault_index * PRIMARY_FAULT_REG_LEN + 12);

		raw_spin_unlock_irqrestore(&iommu->register_lock, flag);

		if (!ratelimited)
			dmar_fault_do_one(iommu, type, fault_reason,
					  source_id, guest_addr);