Re: [PATCH v13 10/10] iommu/arm-smmu-v3: Add stall support for platform devices

2021-03-26 Thread Auger Eric
Hi Jean,

On 3/2/21 10:26 AM, Jean-Philippe Brucker wrote:
> The SMMU provides a Stall model for handling page faults in platform
> devices. It is similar to PCIe PRI, but doesn't require devices to have
> their own translation cache. Instead, faulting transactions are parked
> and the OS is given a chance to fix the page tables and retry the
> transaction.
> 
> Enable stall for devices that support it (opt-in by firmware). When an
> event corresponds to a translation error, call the IOMMU fault handler.
> If the fault is recoverable, it will call us back to terminate or
> continue the stall.
> 
> To use stall device drivers need to enable IOMMU_DEV_FEAT_IOPF, which
> initializes the fault queue for the device.
> 
> Tested-by: Zhangfei Gao 
> Reviewed-by: Jonathan Cameron 
> Signed-off-by: Jean-Philippe Brucker 
Reviewed-by: Eric Auger 

Thanks

Eric
> ---
>  drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h   |  43 
>  .../iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c   |  59 +-
>  drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c   | 196 +-
>  3 files changed, 283 insertions(+), 15 deletions(-)
> 
> diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h 
> b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
> index 7b15b7580c6e..59af0bbd2f7b 100644
> --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
> +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
> @@ -354,6 +354,13 @@
>  #define CMDQ_PRI_1_GRPID GENMASK_ULL(8, 0)
>  #define CMDQ_PRI_1_RESP  GENMASK_ULL(13, 12)
>  
> +#define CMDQ_RESUME_0_RESP_TERM  0UL
> +#define CMDQ_RESUME_0_RESP_RETRY 1UL
> +#define CMDQ_RESUME_0_RESP_ABORT 2UL
> +#define CMDQ_RESUME_0_RESP   GENMASK_ULL(13, 12)
> +#define CMDQ_RESUME_0_SIDGENMASK_ULL(63, 32)
> +#define CMDQ_RESUME_1_STAG   GENMASK_ULL(15, 0)
> +
>  #define CMDQ_SYNC_0_CS   GENMASK_ULL(13, 12)
>  #define CMDQ_SYNC_0_CS_NONE  0
>  #define CMDQ_SYNC_0_CS_IRQ   1
> @@ -370,6 +377,25 @@
>  
>  #define EVTQ_0_IDGENMASK_ULL(7, 0)
>  
> +#define EVT_ID_TRANSLATION_FAULT 0x10
> +#define EVT_ID_ADDR_SIZE_FAULT   0x11
> +#define EVT_ID_ACCESS_FAULT  0x12
> +#define EVT_ID_PERMISSION_FAULT  0x13
> +
> +#define EVTQ_0_SSV   (1UL << 11)
> +#define EVTQ_0_SSID  GENMASK_ULL(31, 12)
> +#define EVTQ_0_SID   GENMASK_ULL(63, 32)
> +#define EVTQ_1_STAG  GENMASK_ULL(15, 0)
> +#define EVTQ_1_STALL (1UL << 31)
> +#define EVTQ_1_PnU   (1UL << 33)
> +#define EVTQ_1_InD   (1UL << 34)
> +#define EVTQ_1_RnW   (1UL << 35)
> +#define EVTQ_1_S2(1UL << 39)
> +#define EVTQ_1_CLASS GENMASK_ULL(41, 40)
> +#define EVTQ_1_TT_READ   (1UL << 44)
> +#define EVTQ_2_ADDR  GENMASK_ULL(63, 0)
> +#define EVTQ_3_IPA   GENMASK_ULL(51, 12)
> +
>  /* PRI queue */
>  #define PRIQ_ENT_SZ_SHIFT4
>  #define PRIQ_ENT_DWORDS  ((1 << PRIQ_ENT_SZ_SHIFT) >> 3)
> @@ -464,6 +490,13 @@ struct arm_smmu_cmdq_ent {
>   enum pri_resp   resp;
>   } pri;
>  
> + #define CMDQ_OP_RESUME  0x44
> + struct {
> + u32 sid;
> + u16 stag;
> + u8  resp;
> + } resume;
> +
>   #define CMDQ_OP_CMD_SYNC0x46
>   struct {
>   u64 msiaddr;
> @@ -522,6 +555,7 @@ struct arm_smmu_cmdq_batch {
>  
>  struct arm_smmu_evtq {
>   struct arm_smmu_queue   q;
> + struct iopf_queue   *iopf;
>   u32 max_stalls;
>  };
>  
> @@ -659,7 +693,9 @@ struct arm_smmu_master {
>   struct arm_smmu_stream  *streams;
>   unsigned intnum_streams;
>   boolats_enabled;
> + boolstall_enabled;
>   boolsva_enabled;
> + booliopf_enabled;
>   struct list_headbonds;
>   unsigned intssid_bits;
>  };
> @@ -678,6 +714,7 @@ struct arm_smmu_domain {
>  
>   struct io_pgtable_ops   *pgtbl_ops;
>   boolnon_strict;
> + boolstall_enabled;
>   atomic_tnr_ats_masters;
>  
>   enum arm_smmu_domain_stage  stage;
> @@ -719,6 +756,7 @@ bool arm_smmu_master_sva_supported(struct arm_smmu_master 
> *master);
>  bool arm_smmu_master_sva_enabled(struct arm_smmu_master *master);
>  int arm_smmu_master_enable_sva(struct arm_smmu_master *master);
>  int arm_smmu_master_disable_sva(struct 

Re: [PATCH v13 10/10] iommu/arm-smmu-v3: Add stall support for platform devices

2021-03-19 Thread Auger Eric
Hi Jean,

On 3/2/21 10:26 AM, Jean-Philippe Brucker wrote:
> The SMMU provides a Stall model for handling page faults in platform
> devices. It is similar to PCIe PRI, but doesn't require devices to have
> their own translation cache. Instead, faulting transactions are parked
> and the OS is given a chance to fix the page tables and retry the
> transaction.
> 
> Enable stall for devices that support it (opt-in by firmware). When an
> event corresponds to a translation error, call the IOMMU fault handler.
> If the fault is recoverable, it will call us back to terminate or
> continue the stall.
> 
> To use stall device drivers need to enable IOMMU_DEV_FEAT_IOPF, which
> initializes the fault queue for the device.
> 
> Tested-by: Zhangfei Gao 
> Reviewed-by: Jonathan Cameron 
> Signed-off-by: Jean-Philippe Brucker 
Reviewed-by: Eric Auger 

Thanks

Eric

> ---
>  drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h   |  43 
>  .../iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c   |  59 +-
>  drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c   | 196 +-
>  3 files changed, 283 insertions(+), 15 deletions(-)
> 
> diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h 
> b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
> index 7b15b7580c6e..59af0bbd2f7b 100644
> --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
> +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
> @@ -354,6 +354,13 @@
>  #define CMDQ_PRI_1_GRPID GENMASK_ULL(8, 0)
>  #define CMDQ_PRI_1_RESP  GENMASK_ULL(13, 12)
>  
> +#define CMDQ_RESUME_0_RESP_TERM  0UL
> +#define CMDQ_RESUME_0_RESP_RETRY 1UL
> +#define CMDQ_RESUME_0_RESP_ABORT 2UL
> +#define CMDQ_RESUME_0_RESP   GENMASK_ULL(13, 12)
> +#define CMDQ_RESUME_0_SIDGENMASK_ULL(63, 32)
> +#define CMDQ_RESUME_1_STAG   GENMASK_ULL(15, 0)
> +
>  #define CMDQ_SYNC_0_CS   GENMASK_ULL(13, 12)
>  #define CMDQ_SYNC_0_CS_NONE  0
>  #define CMDQ_SYNC_0_CS_IRQ   1
> @@ -370,6 +377,25 @@
>  
>  #define EVTQ_0_IDGENMASK_ULL(7, 0)
>  
> +#define EVT_ID_TRANSLATION_FAULT 0x10
> +#define EVT_ID_ADDR_SIZE_FAULT   0x11
> +#define EVT_ID_ACCESS_FAULT  0x12
> +#define EVT_ID_PERMISSION_FAULT  0x13
> +
> +#define EVTQ_0_SSV   (1UL << 11)
> +#define EVTQ_0_SSID  GENMASK_ULL(31, 12)
> +#define EVTQ_0_SID   GENMASK_ULL(63, 32)
> +#define EVTQ_1_STAG  GENMASK_ULL(15, 0)
> +#define EVTQ_1_STALL (1UL << 31)
> +#define EVTQ_1_PnU   (1UL << 33)
> +#define EVTQ_1_InD   (1UL << 34)
> +#define EVTQ_1_RnW   (1UL << 35)
> +#define EVTQ_1_S2(1UL << 39)
> +#define EVTQ_1_CLASS GENMASK_ULL(41, 40)
> +#define EVTQ_1_TT_READ   (1UL << 44)
> +#define EVTQ_2_ADDR  GENMASK_ULL(63, 0)
> +#define EVTQ_3_IPA   GENMASK_ULL(51, 12)
> +
>  /* PRI queue */
>  #define PRIQ_ENT_SZ_SHIFT4
>  #define PRIQ_ENT_DWORDS  ((1 << PRIQ_ENT_SZ_SHIFT) >> 3)
> @@ -464,6 +490,13 @@ struct arm_smmu_cmdq_ent {
>   enum pri_resp   resp;
>   } pri;
>  
> + #define CMDQ_OP_RESUME  0x44
> + struct {
> + u32 sid;
> + u16 stag;
> + u8  resp;
> + } resume;
> +
>   #define CMDQ_OP_CMD_SYNC0x46
>   struct {
>   u64 msiaddr;
> @@ -522,6 +555,7 @@ struct arm_smmu_cmdq_batch {
>  
>  struct arm_smmu_evtq {
>   struct arm_smmu_queue   q;
> + struct iopf_queue   *iopf;
>   u32 max_stalls;
>  };
>  
> @@ -659,7 +693,9 @@ struct arm_smmu_master {
>   struct arm_smmu_stream  *streams;
>   unsigned intnum_streams;
>   boolats_enabled;
> + boolstall_enabled;
>   boolsva_enabled;
> + booliopf_enabled;
>   struct list_headbonds;
>   unsigned intssid_bits;
>  };
> @@ -678,6 +714,7 @@ struct arm_smmu_domain {
>  
>   struct io_pgtable_ops   *pgtbl_ops;
>   boolnon_strict;
> + boolstall_enabled;
>   atomic_tnr_ats_masters;
>  
>   enum arm_smmu_domain_stage  stage;
> @@ -719,6 +756,7 @@ bool arm_smmu_master_sva_supported(struct arm_smmu_master 
> *master);
>  bool arm_smmu_master_sva_enabled(struct arm_smmu_master *master);
>  int arm_smmu_master_enable_sva(struct arm_smmu_master *master);
>  int arm_smmu_master_disable_sva(struct 

[PATCH v13 10/10] iommu/arm-smmu-v3: Add stall support for platform devices

2021-03-02 Thread Jean-Philippe Brucker
The SMMU provides a Stall model for handling page faults in platform
devices. It is similar to PCIe PRI, but doesn't require devices to have
their own translation cache. Instead, faulting transactions are parked
and the OS is given a chance to fix the page tables and retry the
transaction.

Enable stall for devices that support it (opt-in by firmware). When an
event corresponds to a translation error, call the IOMMU fault handler.
If the fault is recoverable, it will call us back to terminate or
continue the stall.

To use stall device drivers need to enable IOMMU_DEV_FEAT_IOPF, which
initializes the fault queue for the device.

Tested-by: Zhangfei Gao 
Reviewed-by: Jonathan Cameron 
Signed-off-by: Jean-Philippe Brucker 
---
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h   |  43 
 .../iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c   |  59 +-
 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c   | 196 +-
 3 files changed, 283 insertions(+), 15 deletions(-)

diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h 
b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
index 7b15b7580c6e..59af0bbd2f7b 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h
@@ -354,6 +354,13 @@
 #define CMDQ_PRI_1_GRPID   GENMASK_ULL(8, 0)
 #define CMDQ_PRI_1_RESPGENMASK_ULL(13, 12)
 
+#define CMDQ_RESUME_0_RESP_TERM0UL
+#define CMDQ_RESUME_0_RESP_RETRY   1UL
+#define CMDQ_RESUME_0_RESP_ABORT   2UL
+#define CMDQ_RESUME_0_RESP GENMASK_ULL(13, 12)
+#define CMDQ_RESUME_0_SID  GENMASK_ULL(63, 32)
+#define CMDQ_RESUME_1_STAG GENMASK_ULL(15, 0)
+
 #define CMDQ_SYNC_0_CS GENMASK_ULL(13, 12)
 #define CMDQ_SYNC_0_CS_NONE0
 #define CMDQ_SYNC_0_CS_IRQ 1
@@ -370,6 +377,25 @@
 
 #define EVTQ_0_ID  GENMASK_ULL(7, 0)
 
+#define EVT_ID_TRANSLATION_FAULT   0x10
+#define EVT_ID_ADDR_SIZE_FAULT 0x11
+#define EVT_ID_ACCESS_FAULT0x12
+#define EVT_ID_PERMISSION_FAULT0x13
+
+#define EVTQ_0_SSV (1UL << 11)
+#define EVTQ_0_SSIDGENMASK_ULL(31, 12)
+#define EVTQ_0_SID GENMASK_ULL(63, 32)
+#define EVTQ_1_STAGGENMASK_ULL(15, 0)
+#define EVTQ_1_STALL   (1UL << 31)
+#define EVTQ_1_PnU (1UL << 33)
+#define EVTQ_1_InD (1UL << 34)
+#define EVTQ_1_RnW (1UL << 35)
+#define EVTQ_1_S2  (1UL << 39)
+#define EVTQ_1_CLASS   GENMASK_ULL(41, 40)
+#define EVTQ_1_TT_READ (1UL << 44)
+#define EVTQ_2_ADDRGENMASK_ULL(63, 0)
+#define EVTQ_3_IPA GENMASK_ULL(51, 12)
+
 /* PRI queue */
 #define PRIQ_ENT_SZ_SHIFT  4
 #define PRIQ_ENT_DWORDS((1 << PRIQ_ENT_SZ_SHIFT) >> 3)
@@ -464,6 +490,13 @@ struct arm_smmu_cmdq_ent {
enum pri_resp   resp;
} pri;
 
+   #define CMDQ_OP_RESUME  0x44
+   struct {
+   u32 sid;
+   u16 stag;
+   u8  resp;
+   } resume;
+
#define CMDQ_OP_CMD_SYNC0x46
struct {
u64 msiaddr;
@@ -522,6 +555,7 @@ struct arm_smmu_cmdq_batch {
 
 struct arm_smmu_evtq {
struct arm_smmu_queue   q;
+   struct iopf_queue   *iopf;
u32 max_stalls;
 };
 
@@ -659,7 +693,9 @@ struct arm_smmu_master {
struct arm_smmu_stream  *streams;
unsigned intnum_streams;
boolats_enabled;
+   boolstall_enabled;
boolsva_enabled;
+   booliopf_enabled;
struct list_headbonds;
unsigned intssid_bits;
 };
@@ -678,6 +714,7 @@ struct arm_smmu_domain {
 
struct io_pgtable_ops   *pgtbl_ops;
boolnon_strict;
+   boolstall_enabled;
atomic_tnr_ats_masters;
 
enum arm_smmu_domain_stage  stage;
@@ -719,6 +756,7 @@ bool arm_smmu_master_sva_supported(struct arm_smmu_master 
*master);
 bool arm_smmu_master_sva_enabled(struct arm_smmu_master *master);
 int arm_smmu_master_enable_sva(struct arm_smmu_master *master);
 int arm_smmu_master_disable_sva(struct arm_smmu_master *master);
+bool arm_smmu_master_iopf_supported(struct arm_smmu_master *master);
 struct iommu_sva *arm_smmu_sva_bind(struct device *dev, struct mm_struct *mm,
void *drvdata);
 void