@@ -405,32 +405,72 @@ static const struct iommu_flush_ops arm_smmu_s2_tlb_ops_v1 = {
405
405
.tlb_add_page = arm_smmu_tlb_add_page_s2_v1 ,
406
406
};
407
407
408
+
409
+ void arm_smmu_read_context_fault_info (struct arm_smmu_device * smmu , int idx ,
410
+ struct arm_smmu_context_fault_info * cfi )
411
+ {
412
+ cfi -> iova = arm_smmu_cb_readq (smmu , idx , ARM_SMMU_CB_FAR );
413
+ cfi -> fsr = arm_smmu_cb_read (smmu , idx , ARM_SMMU_CB_FSR );
414
+ cfi -> fsynr = arm_smmu_cb_read (smmu , idx , ARM_SMMU_CB_FSYNR0 );
415
+ cfi -> cbfrsynra = arm_smmu_gr1_read (smmu , ARM_SMMU_GR1_CBFRSYNRA (idx ));
416
+ }
417
+
418
+ void arm_smmu_print_context_fault_info (struct arm_smmu_device * smmu , int idx ,
419
+ const struct arm_smmu_context_fault_info * cfi )
420
+ {
421
+ dev_dbg (smmu -> dev ,
422
+ "Unhandled context fault: fsr=0x%x, iova=0x%08lx, fsynr=0x%x, cbfrsynra=0x%x, cb=%d\n" ,
423
+ cfi -> fsr , cfi -> iova , cfi -> fsynr , cfi -> cbfrsynra , idx );
424
+
425
+ dev_err (smmu -> dev , "FSR = %08x [%s%sFormat=%u%s%s%s%s%s%s%s%s], SID=0x%x\n" ,
426
+ cfi -> fsr ,
427
+ (cfi -> fsr & ARM_SMMU_CB_FSR_MULTI ) ? "MULTI " : "" ,
428
+ (cfi -> fsr & ARM_SMMU_CB_FSR_SS ) ? "SS " : "" ,
429
+ (u32 )FIELD_GET (ARM_SMMU_CB_FSR_FORMAT , cfi -> fsr ),
430
+ (cfi -> fsr & ARM_SMMU_CB_FSR_UUT ) ? " UUT" : "" ,
431
+ (cfi -> fsr & ARM_SMMU_CB_FSR_ASF ) ? " ASF" : "" ,
432
+ (cfi -> fsr & ARM_SMMU_CB_FSR_TLBLKF ) ? " TLBLKF" : "" ,
433
+ (cfi -> fsr & ARM_SMMU_CB_FSR_TLBMCF ) ? " TLBMCF" : "" ,
434
+ (cfi -> fsr & ARM_SMMU_CB_FSR_EF ) ? " EF" : "" ,
435
+ (cfi -> fsr & ARM_SMMU_CB_FSR_PF ) ? " PF" : "" ,
436
+ (cfi -> fsr & ARM_SMMU_CB_FSR_AFF ) ? " AFF" : "" ,
437
+ (cfi -> fsr & ARM_SMMU_CB_FSR_TF ) ? " TF" : "" ,
438
+ cfi -> cbfrsynra );
439
+
440
+ dev_err (smmu -> dev , "FSYNR0 = %08x [S1CBNDX=%u%s%s%s%s%s%s PLVL=%u]\n" ,
441
+ cfi -> fsynr ,
442
+ (u32 )FIELD_GET (ARM_SMMU_CB_FSYNR0_S1CBNDX , cfi -> fsynr ),
443
+ (cfi -> fsynr & ARM_SMMU_CB_FSYNR0_AFR ) ? " AFR" : "" ,
444
+ (cfi -> fsynr & ARM_SMMU_CB_FSYNR0_PTWF ) ? " PTWF" : "" ,
445
+ (cfi -> fsynr & ARM_SMMU_CB_FSYNR0_NSATTR ) ? " NSATTR" : "" ,
446
+ (cfi -> fsynr & ARM_SMMU_CB_FSYNR0_IND ) ? " IND" : "" ,
447
+ (cfi -> fsynr & ARM_SMMU_CB_FSYNR0_PNU ) ? " PNU" : "" ,
448
+ (cfi -> fsynr & ARM_SMMU_CB_FSYNR0_WNR ) ? " WNR" : "" ,
449
+ (u32 )FIELD_GET (ARM_SMMU_CB_FSYNR0_PLVL , cfi -> fsynr ));
450
+ }
451
+
408
452
static irqreturn_t arm_smmu_context_fault (int irq , void * dev )
409
453
{
410
- u32 fsr , fsynr , cbfrsynra ;
411
- unsigned long iova ;
454
+ struct arm_smmu_context_fault_info cfi ;
412
455
struct arm_smmu_domain * smmu_domain = dev ;
413
456
struct arm_smmu_device * smmu = smmu_domain -> smmu ;
457
+ static DEFINE_RATELIMIT_STATE (rs , DEFAULT_RATELIMIT_INTERVAL ,
458
+ DEFAULT_RATELIMIT_BURST ) ;
414
459
int idx = smmu_domain -> cfg .cbndx ;
415
460
int ret ;
416
461
417
- fsr = arm_smmu_cb_read (smmu , idx , ARM_SMMU_CB_FSR );
418
- if (!(fsr & ARM_SMMU_CB_FSR_FAULT ))
419
- return IRQ_NONE ;
462
+ arm_smmu_read_context_fault_info (smmu , idx , & cfi );
420
463
421
- fsynr = arm_smmu_cb_read (smmu , idx , ARM_SMMU_CB_FSYNR0 );
422
- iova = arm_smmu_cb_readq (smmu , idx , ARM_SMMU_CB_FAR );
423
- cbfrsynra = arm_smmu_gr1_read (smmu , ARM_SMMU_GR1_CBFRSYNRA (idx ));
464
+ if (!(cfi .fsr & ARM_SMMU_CB_FSR_FAULT ))
465
+ return IRQ_NONE ;
424
466
425
- ret = report_iommu_fault (& smmu_domain -> domain , NULL , iova ,
426
- fsynr & ARM_SMMU_CB_FSYNR0_WNR ? IOMMU_FAULT_WRITE : IOMMU_FAULT_READ );
467
+ ret = report_iommu_fault (& smmu_domain -> domain , NULL , cfi . iova ,
468
+ cfi . fsynr & ARM_SMMU_CB_FSYNR0_WNR ? IOMMU_FAULT_WRITE : IOMMU_FAULT_READ );
427
469
428
- if (ret == - ENOSYS )
429
- dev_err_ratelimited (smmu -> dev ,
430
- "Unhandled context fault: fsr=0x%x, iova=0x%08lx, fsynr=0x%x, cbfrsynra=0x%x, cb=%d\n" ,
431
- fsr , iova , fsynr , cbfrsynra , idx );
470
+ if (ret == - ENOSYS && __ratelimit (& rs ))
471
+ arm_smmu_print_context_fault_info (smmu , idx , & cfi );
432
472
433
- arm_smmu_cb_write (smmu , idx , ARM_SMMU_CB_FSR , fsr );
473
+ arm_smmu_cb_write (smmu , idx , ARM_SMMU_CB_FSR , cfi . fsr );
434
474
return IRQ_HANDLED ;
435
475
}
436
476
0 commit comments