diff mbox series

[1/1] iommu/arm-smmu: Add SID information to context fault log

Message ID 20190415080734.6843-1-vivek.gautam@codeaurora.org (mailing list archive)
State New, archived
Headers show
Series [1/1] iommu/arm-smmu: Add SID information to context fault log | expand

Commit Message

Vivek Gautam April 15, 2019, 8:07 a.m. UTC
Extract the SID and add the information to context fault log.
This is specially useful in a distributed smmu architecture
where multiple masters are connected to smmu. SID information
helps to quickly identify the faulting master device.

Signed-off-by: Vivek Gautam <vivek.gautam@codeaurora.org>
---
 drivers/iommu/arm-smmu-regs.h |  4 ++++
 drivers/iommu/arm-smmu.c      | 14 ++++++++++++--
 2 files changed, 16 insertions(+), 2 deletions(-)

Comments

Marc Gonzalez April 15, 2019, 8:54 a.m. UTC | #1
Trimming CC list for very minor suggestions (feel free to ignore).

On 15/04/2019 10:07, Vivek Gautam wrote:

> Extract the SID and add the information to context fault log.
> This is specially useful in a distributed smmu architecture
> where multiple masters are connected to smmu. SID information
> helps to quickly identify the faulting master device.

I find it slightly clearer to keep acronyms capitalized, such as SMMU.


> @@ -575,7 +575,10 @@ static irqreturn_t arm_smmu_context_fault(int irq, void *dev)
>  	struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain);
>  	struct arm_smmu_cfg *cfg = &smmu_domain->cfg;
>  	struct arm_smmu_device *smmu = smmu_domain->smmu;
> +	void __iomem *gr1_base = ARM_SMMU_GR1(smmu);
>  	void __iomem *cb_base;
> +	u32 cbfrsynra;
> +	u16 sid;
>  
>  	cb_base = ARM_SMMU_CB(smmu, cfg->cbndx);
>  	fsr = readl_relaxed(cb_base + ARM_SMMU_CB_FSR);
> @@ -586,9 +589,16 @@ static irqreturn_t arm_smmu_context_fault(int irq, void *dev)
>  	fsynr = readl_relaxed(cb_base + ARM_SMMU_CB_FSYNR0);
>  	iova = readq_relaxed(cb_base + ARM_SMMU_CB_FAR);
>  
> +	cbfrsynra = readl_relaxed(gr1_base +
> +				  ARM_SMMU_GR1_CBFRSYNRA(cfg->cbndx));

I find it slightly clearer to write

	void __iomem *reg;
	...
	reg = ARM_SMMU_GR1(smmu) + ARM_SMMU_GR1_CBFRSYNRA(cfg->cbndx);
	cbfrsynra = readl_relaxed(reg);

Regards.
Robin Murphy April 15, 2019, 9:41 a.m. UTC | #2
On 15/04/2019 09:07, Vivek Gautam wrote:
> Extract the SID and add the information to context fault log.
> This is specially useful in a distributed smmu architecture
> where multiple masters are connected to smmu. SID information
> helps to quickly identify the faulting master device.

Hmm, given how it's UNKNOWN for translation faults, which are arguably 
the most likely context fault, I reckon it probably makes more sense to 
just dump the raw register value for the user to interpret, as we do for 
fsr/fsynr.

Robin.

> Signed-off-by: Vivek Gautam <vivek.gautam@codeaurora.org>
> ---
>   drivers/iommu/arm-smmu-regs.h |  4 ++++
>   drivers/iommu/arm-smmu.c      | 14 ++++++++++++--
>   2 files changed, 16 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/iommu/arm-smmu-regs.h b/drivers/iommu/arm-smmu-regs.h
> index a1226e4ab5f8..e5be0344b610 100644
> --- a/drivers/iommu/arm-smmu-regs.h
> +++ b/drivers/iommu/arm-smmu-regs.h
> @@ -147,6 +147,10 @@ enum arm_smmu_s2cr_privcfg {
>   #define CBAR_IRPTNDX_SHIFT		24
>   #define CBAR_IRPTNDX_MASK		0xff
>   
> +#define ARM_SMMU_GR1_CBFRSYNRA(n)	(0x400 + ((n) << 2))
> +#define CBFRSYNRA_V2_SID_MASK		0xffff
> +#define CBFRSYNRA_V1_SID_MASK		0x7fff
> +
>   #define ARM_SMMU_GR1_CBA2R(n)		(0x800 + ((n) << 2))
>   #define CBA2R_RW64_32BIT		(0 << 0)
>   #define CBA2R_RW64_64BIT		(1 << 0)
> diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
> index 045d93884164..aa3426dc68d0 100644
> --- a/drivers/iommu/arm-smmu.c
> +++ b/drivers/iommu/arm-smmu.c
> @@ -575,7 +575,10 @@ static irqreturn_t arm_smmu_context_fault(int irq, void *dev)
>   	struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain);
>   	struct arm_smmu_cfg *cfg = &smmu_domain->cfg;
>   	struct arm_smmu_device *smmu = smmu_domain->smmu;
> +	void __iomem *gr1_base = ARM_SMMU_GR1(smmu);
>   	void __iomem *cb_base;
> +	u32 cbfrsynra;
> +	u16 sid;
>   
>   	cb_base = ARM_SMMU_CB(smmu, cfg->cbndx);
>   	fsr = readl_relaxed(cb_base + ARM_SMMU_CB_FSR);
> @@ -586,9 +589,16 @@ static irqreturn_t arm_smmu_context_fault(int irq, void *dev)
>   	fsynr = readl_relaxed(cb_base + ARM_SMMU_CB_FSYNR0);
>   	iova = readq_relaxed(cb_base + ARM_SMMU_CB_FAR);
>   
> +	cbfrsynra = readl_relaxed(gr1_base +
> +				  ARM_SMMU_GR1_CBFRSYNRA(cfg->cbndx));
> +	if (smmu->version > ARM_SMMU_V1)
> +		sid = cbfrsynra & CBFRSYNRA_V2_SID_MASK;
> +	else
> +		sid = cbfrsynra & CBFRSYNRA_V1_SID_MASK;
> +
>   	dev_err_ratelimited(smmu->dev,
> -	"Unhandled context fault: fsr=0x%x, iova=0x%08lx, fsynr=0x%x, cb=%d\n",
> -			    fsr, iova, fsynr, cfg->cbndx);
> +	"Unhandled context fault: fsr=0x%x, iova=0x%08lx, fsynr=0x%x, cb=%d sid = %u\n",
> +			    fsr, iova, fsynr, cfg->cbndx, sid);
>   
>   	writel(fsr, cb_base + ARM_SMMU_CB_FSR);
>   	return IRQ_HANDLED;
>
Vivek Gautam April 15, 2019, 12:04 p.m. UTC | #3
Hi Marc,


On 4/15/2019 2:24 PM, Marc Gonzalez wrote:
> Trimming CC list for very minor suggestions (feel free to ignore)

Thanks for the review. Please find my responses inline below.

>
> On 15/04/2019 10:07, Vivek Gautam wrote:
>
>> Extract the SID and add the information to context fault log.
>> This is specially useful in a distributed smmu architecture
>> where multiple masters are connected to smmu. SID information
>> helps to quickly identify the faulting master device.
> I find it slightly clearer to keep acronyms capitalized, such as SMMU.

Sure, will change it.
>
>
>> @@ -575,7 +575,10 @@ static irqreturn_t arm_smmu_context_fault(int irq, void *dev)
>>   	struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain);
>>   	struct arm_smmu_cfg *cfg = &smmu_domain->cfg;
>>   	struct arm_smmu_device *smmu = smmu_domain->smmu;
>> +	void __iomem *gr1_base = ARM_SMMU_GR1(smmu);
>>   	void __iomem *cb_base;
>> +	u32 cbfrsynra;
>> +	u16 sid;
>>   
>>   	cb_base = ARM_SMMU_CB(smmu, cfg->cbndx);
>>   	fsr = readl_relaxed(cb_base + ARM_SMMU_CB_FSR);
>> @@ -586,9 +589,16 @@ static irqreturn_t arm_smmu_context_fault(int irq, void *dev)
>>   	fsynr = readl_relaxed(cb_base + ARM_SMMU_CB_FSYNR0);
>>   	iova = readq_relaxed(cb_base + ARM_SMMU_CB_FAR);
>>   
>> +	cbfrsynra = readl_relaxed(gr1_base +
>> +				  ARM_SMMU_GR1_CBFRSYNRA(cfg->cbndx));
> I find it slightly clearer to write
>
> 	void __iomem *reg;
> 	...
> 	reg = ARM_SMMU_GR1(smmu) + ARM_SMMU_GR1_CBFRSYNRA(cfg->cbndx);
> 	cbfrsynra = readl_relaxed(reg);

I would actually argue here, to go with the flow of how this function 
declares the variables, for the simple case of symmetry.
Let me know what do you think.

Thanks & regards
Vivek


>
> Regards.
Vivek Gautam April 15, 2019, 12:05 p.m. UTC | #4
On 4/15/2019 3:11 PM, Robin Murphy wrote:
> On 15/04/2019 09:07, Vivek Gautam wrote:
>> Extract the SID and add the information to context fault log.
>> This is specially useful in a distributed smmu architecture
>> where multiple masters are connected to smmu. SID information
>> helps to quickly identify the faulting master device.
>
> Hmm, given how it's UNKNOWN for translation faults, which are arguably 
> the most likely context fault, I reckon it probably makes more sense 
> to just dump the raw register value for the user to interpret, as we 
> do for fsr/fsynr.


Thanks Robin. Sure will update it to dump the raw register value.

Regards
Vivek

>
> Robin.
>
>> Signed-off-by: Vivek Gautam <vivek.gautam@codeaurora.org>
>> ---
>>   drivers/iommu/arm-smmu-regs.h |  4 ++++
>>   drivers/iommu/arm-smmu.c      | 14 ++++++++++++--
>>   2 files changed, 16 insertions(+), 2 deletions(-)
>>
>> diff --git a/drivers/iommu/arm-smmu-regs.h 
>> b/drivers/iommu/arm-smmu-regs.h
>> index a1226e4ab5f8..e5be0344b610 100644
>> --- a/drivers/iommu/arm-smmu-regs.h
>> +++ b/drivers/iommu/arm-smmu-regs.h
>> @@ -147,6 +147,10 @@ enum arm_smmu_s2cr_privcfg {
>>   #define CBAR_IRPTNDX_SHIFT        24
>>   #define CBAR_IRPTNDX_MASK        0xff
>>   +#define ARM_SMMU_GR1_CBFRSYNRA(n)    (0x400 + ((n) << 2))
>> +#define CBFRSYNRA_V2_SID_MASK        0xffff
>> +#define CBFRSYNRA_V1_SID_MASK        0x7fff
>> +
>>   #define ARM_SMMU_GR1_CBA2R(n)        (0x800 + ((n) << 2))
>>   #define CBA2R_RW64_32BIT        (0 << 0)
>>   #define CBA2R_RW64_64BIT        (1 << 0)
>> diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
>> index 045d93884164..aa3426dc68d0 100644
>> --- a/drivers/iommu/arm-smmu.c
>> +++ b/drivers/iommu/arm-smmu.c
>> @@ -575,7 +575,10 @@ static irqreturn_t arm_smmu_context_fault(int 
>> irq, void *dev)
>>       struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain);
>>       struct arm_smmu_cfg *cfg = &smmu_domain->cfg;
>>       struct arm_smmu_device *smmu = smmu_domain->smmu;
>> +    void __iomem *gr1_base = ARM_SMMU_GR1(smmu);
>>       void __iomem *cb_base;
>> +    u32 cbfrsynra;
>> +    u16 sid;
>>         cb_base = ARM_SMMU_CB(smmu, cfg->cbndx);
>>       fsr = readl_relaxed(cb_base + ARM_SMMU_CB_FSR);
>> @@ -586,9 +589,16 @@ static irqreturn_t arm_smmu_context_fault(int 
>> irq, void *dev)
>>       fsynr = readl_relaxed(cb_base + ARM_SMMU_CB_FSYNR0);
>>       iova = readq_relaxed(cb_base + ARM_SMMU_CB_FAR);
>>   +    cbfrsynra = readl_relaxed(gr1_base +
>> +                  ARM_SMMU_GR1_CBFRSYNRA(cfg->cbndx));
>> +    if (smmu->version > ARM_SMMU_V1)
>> +        sid = cbfrsynra & CBFRSYNRA_V2_SID_MASK;
>> +    else
>> +        sid = cbfrsynra & CBFRSYNRA_V1_SID_MASK;
>> +
>>       dev_err_ratelimited(smmu->dev,
>> -    "Unhandled context fault: fsr=0x%x, iova=0x%08lx, fsynr=0x%x, 
>> cb=%d\n",
>> -                fsr, iova, fsynr, cfg->cbndx);
>> +    "Unhandled context fault: fsr=0x%x, iova=0x%08lx, fsynr=0x%x, 
>> cb=%d sid = %u\n",
>> +                fsr, iova, fsynr, cfg->cbndx, sid);
>>         writel(fsr, cb_base + ARM_SMMU_CB_FSR);
>>       return IRQ_HANDLED;
>>
diff mbox series

Patch

diff --git a/drivers/iommu/arm-smmu-regs.h b/drivers/iommu/arm-smmu-regs.h
index a1226e4ab5f8..e5be0344b610 100644
--- a/drivers/iommu/arm-smmu-regs.h
+++ b/drivers/iommu/arm-smmu-regs.h
@@ -147,6 +147,10 @@  enum arm_smmu_s2cr_privcfg {
 #define CBAR_IRPTNDX_SHIFT		24
 #define CBAR_IRPTNDX_MASK		0xff
 
+#define ARM_SMMU_GR1_CBFRSYNRA(n)	(0x400 + ((n) << 2))
+#define CBFRSYNRA_V2_SID_MASK		0xffff
+#define CBFRSYNRA_V1_SID_MASK		0x7fff
+
 #define ARM_SMMU_GR1_CBA2R(n)		(0x800 + ((n) << 2))
 #define CBA2R_RW64_32BIT		(0 << 0)
 #define CBA2R_RW64_64BIT		(1 << 0)
diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
index 045d93884164..aa3426dc68d0 100644
--- a/drivers/iommu/arm-smmu.c
+++ b/drivers/iommu/arm-smmu.c
@@ -575,7 +575,10 @@  static irqreturn_t arm_smmu_context_fault(int irq, void *dev)
 	struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain);
 	struct arm_smmu_cfg *cfg = &smmu_domain->cfg;
 	struct arm_smmu_device *smmu = smmu_domain->smmu;
+	void __iomem *gr1_base = ARM_SMMU_GR1(smmu);
 	void __iomem *cb_base;
+	u32 cbfrsynra;
+	u16 sid;
 
 	cb_base = ARM_SMMU_CB(smmu, cfg->cbndx);
 	fsr = readl_relaxed(cb_base + ARM_SMMU_CB_FSR);
@@ -586,9 +589,16 @@  static irqreturn_t arm_smmu_context_fault(int irq, void *dev)
 	fsynr = readl_relaxed(cb_base + ARM_SMMU_CB_FSYNR0);
 	iova = readq_relaxed(cb_base + ARM_SMMU_CB_FAR);
 
+	cbfrsynra = readl_relaxed(gr1_base +
+				  ARM_SMMU_GR1_CBFRSYNRA(cfg->cbndx));
+	if (smmu->version > ARM_SMMU_V1)
+		sid = cbfrsynra & CBFRSYNRA_V2_SID_MASK;
+	else
+		sid = cbfrsynra & CBFRSYNRA_V1_SID_MASK;
+
 	dev_err_ratelimited(smmu->dev,
-	"Unhandled context fault: fsr=0x%x, iova=0x%08lx, fsynr=0x%x, cb=%d\n",
-			    fsr, iova, fsynr, cfg->cbndx);
+	"Unhandled context fault: fsr=0x%x, iova=0x%08lx, fsynr=0x%x, cb=%d sid = %u\n",
+			    fsr, iova, fsynr, cfg->cbndx, sid);
 
 	writel(fsr, cb_base + ARM_SMMU_CB_FSR);
 	return IRQ_HANDLED;