Commit 82576aa8 authored by Geert Uytterhoeven's avatar Geert Uytterhoeven Committed by Joerg Roedel
Browse files

iommu/ipmmu-vmsa: Prepare to handle 40-bit error addresses



On R-Car Gen3, the faulting virtual address is a 40-bit address, and
comprised of two registers.  Read the upper address part, and combine
both parts, when running on a 64-bit system.

Signed-off-by: default avatarGeert Uytterhoeven <geert+renesas@glider.be>
Reviewed-by: default avatarSimon Horman <horms+renesas@verge.net.au>
Reviewed-by: default avatarYoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
Tested-by: default avatarYoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
Signed-off-by: default avatarJoerg Roedel <jroedel@suse.de>
parent 80eaa9f5
Loading
Loading
Loading
Loading
+9 −6
Original line number Diff line number Diff line
@@ -186,7 +186,8 @@ static struct ipmmu_vmsa_device *to_ipmmu(struct device *dev)
#define IMMAIR_ATTR_IDX_WBRWA		1
#define IMMAIR_ATTR_IDX_DEV		2

#define IMEAR				0x0030
#define IMELAR				0x0030	/* IMEAR on R-Car Gen2 */
#define IMEUAR				0x0034	/* R-Car Gen3 only */

#define IMPCTR				0x0200
#define IMPSTR				0x0208
@@ -522,14 +523,16 @@ static irqreturn_t ipmmu_domain_irq(struct ipmmu_vmsa_domain *domain)
{
	const u32 err_mask = IMSTR_MHIT | IMSTR_ABORT | IMSTR_PF | IMSTR_TF;
	struct ipmmu_vmsa_device *mmu = domain->mmu;
	unsigned long iova;
	u32 status;
	u32 iova;

	status = ipmmu_ctx_read_root(domain, IMSTR);
	if (!(status & err_mask))
		return IRQ_NONE;

	iova = ipmmu_ctx_read_root(domain, IMEAR);
	iova = ipmmu_ctx_read_root(domain, IMELAR);
	if (IS_ENABLED(CONFIG_64BIT))
		iova |= (u64)ipmmu_ctx_read_root(domain, IMEUAR) << 32;

	/*
	 * Clear the error status flags. Unlike traditional interrupt flag
@@ -541,10 +544,10 @@ static irqreturn_t ipmmu_domain_irq(struct ipmmu_vmsa_domain *domain)

	/* Log fatal errors. */
	if (status & IMSTR_MHIT)
		dev_err_ratelimited(mmu->dev, "Multiple TLB hits @0x%08x\n",
		dev_err_ratelimited(mmu->dev, "Multiple TLB hits @0x%lx\n",
				    iova);
	if (status & IMSTR_ABORT)
		dev_err_ratelimited(mmu->dev, "Page Table Walk Abort @0x%08x\n",
		dev_err_ratelimited(mmu->dev, "Page Table Walk Abort @0x%lx\n",
				    iova);

	if (!(status & (IMSTR_PF | IMSTR_TF)))
@@ -560,7 +563,7 @@ static irqreturn_t ipmmu_domain_irq(struct ipmmu_vmsa_domain *domain)
		return IRQ_HANDLED;

	dev_err_ratelimited(mmu->dev,
			    "Unhandled fault: status 0x%08x iova 0x%08x\n",
			    "Unhandled fault: status 0x%08x iova 0x%lx\n",
			    status, iova);

	return IRQ_HANDLED;