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

2018-02-13 Thread Jean-Philippe Brucker
Hi,

On 13/02/18 01:46, Xu Zaibo wrote:
> Hi,
> 
> On 2018/2/13 2:33, Jean-Philippe Brucker wrote:
>> The SMMU provides a Stall model for handling page faults in platform
>> devices. It is similar to PCI 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.
>>
>> Note that this patch tweaks the iommu_fault_event and page_response_msg to
>> extend the fault id field. Stall uses 16 bits of IDs whereas PCI PRI only
>> uses 9.
> For PCIe devices without ATC,  can they use this Stall model?

Unfortunately no, Stall it is incompatible with PCI. Timing constraints in
PCI prevent from stalling transactions in the IOMMU.

Thanks,
Jean
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


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

2018-02-12 Thread Xu Zaibo

Hi,

On 2018/2/13 2:33, Jean-Philippe Brucker wrote:

The SMMU provides a Stall model for handling page faults in platform
devices. It is similar to PCI 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.

Note that this patch tweaks the iommu_fault_event and page_response_msg to
extend the fault id field. Stall uses 16 bits of IDs whereas PCI PRI only
uses 9.

For PCIe devices without ATC,  can they use this Stall model?

Thanks.

Xu Zaibo

Signed-off-by: Jean-Philippe Brucker 
---
  drivers/iommu/arm-smmu-v3.c | 175 +++-
  include/linux/iommu.h   |   4 +-
  2 files changed, 173 insertions(+), 6 deletions(-)

diff --git a/drivers/iommu/arm-smmu-v3.c b/drivers/iommu/arm-smmu-v3.c
index 2430b2140f8d..8b9f5dd06be0 100644
--- a/drivers/iommu/arm-smmu-v3.c
+++ b/drivers/iommu/arm-smmu-v3.c
@@ -338,6 +338,15 @@
  #define CMDQ_PRI_1_RESP_FAIL  (1UL << CMDQ_PRI_1_RESP_SHIFT)
  #define CMDQ_PRI_1_RESP_SUCC  (2UL << CMDQ_PRI_1_RESP_SHIFT)
  
+#define CMDQ_RESUME_0_SID_SHIFT		32

+#define CMDQ_RESUME_0_SID_MASK 0xUL
+#define CMDQ_RESUME_0_ACTION_SHIFT 12
+#define CMDQ_RESUME_0_ACTION_TERM  (0UL << CMDQ_RESUME_0_ACTION_SHIFT)
+#define CMDQ_RESUME_0_ACTION_RETRY (1UL << CMDQ_RESUME_0_ACTION_SHIFT)
+#define CMDQ_RESUME_0_ACTION_ABORT (2UL << CMDQ_RESUME_0_ACTION_SHIFT)
+#define CMDQ_RESUME_1_STAG_SHIFT   0
+#define CMDQ_RESUME_1_STAG_MASK0xUL
+
  #define CMDQ_SYNC_0_CS_SHIFT  12
  #define CMDQ_SYNC_0_CS_NONE   (0UL << CMDQ_SYNC_0_CS_SHIFT)
  #define CMDQ_SYNC_0_CS_IRQ(1UL << CMDQ_SYNC_0_CS_SHIFT)
@@ -358,6 +367,31 @@
  #define EVTQ_0_ID_SHIFT   0
  #define EVTQ_0_ID_MASK0xffUL
  
+#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_SSID_SHIFT  12
+#define EVTQ_0_SSID_MASK   0xfUL
+#define EVTQ_0_SID_SHIFT   32
+#define EVTQ_0_SID_MASK0xUL
+#define EVTQ_1_STAG_SHIFT  0
+#define EVTQ_1_STAG_MASK   0xUL
+#define EVTQ_1_STALL   (1UL << 31)
+#define EVTQ_1_PRIV(1UL << 33)
+#define EVTQ_1_EXEC(1UL << 34)
+#define EVTQ_1_READ(1UL << 35)
+#define EVTQ_1_S2  (1UL << 39)
+#define EVTQ_1_CLASS_SHIFT 40
+#define EVTQ_1_CLASS_MASK  0x3UL
+#define EVTQ_1_TT_READ (1UL << 44)
+#define EVTQ_2_ADDR_SHIFT  0
+#define EVTQ_2_ADDR_MASK   0xUL
+#define EVTQ_3_IPA_SHIFT   12
+#define EVTQ_3_IPA_MASK0xffUL
+
  /* PRI queue */
  #define PRIQ_ENT_DWORDS   2
  #define PRIQ_MAX_SZ_SHIFT 8
@@ -472,6 +506,13 @@ struct arm_smmu_cmdq_ent {
enum pri_resp   resp;
} pri;
  
+		#define CMDQ_OP_RESUME		0x44

+   struct {
+   u32 sid;
+   u16 stag;
+   enum page_response_code resp;
+   } resume;
+
#define CMDQ_OP_CMD_SYNC0x46
struct {
u32 msidata;
@@ -545,6 +586,8 @@ struct arm_smmu_strtab_ent {
boolassigned;
struct arm_smmu_s1_cfg  *s1_cfg;
struct arm_smmu_s2_cfg  *s2_cfg;
+
+   boolcan_stall;
  };
  
  struct arm_smmu_strtab_cfg {

@@ -904,6 +947,21 @@ static int arm_smmu_cmdq_build_cmd(u64 *cmd, struct 
arm_smmu_cmdq_ent *ent)
return -EINVAL;
}
break;
+   case CMDQ_OP_RESUME:
+   cmd[0] |= (u64)ent->resume.sid << CMDQ_RESUME_0_SID_SHIFT;
+   cmd[1] |= ent->resume.stag << CMDQ_RESUME_1_STAG_SHIFT;
+   switch (ent->resume.resp) {
+   case IOMMU_PAGE_RESP_INVALID:
+   case IOMMU_PAGE_RESP_FAILURE:
+   cmd[0] |= CMDQ_RESUME_0_ACTION_ABORT;
+   break;
+   case IOMMU_PAGE_RESP_SUCCESS:
+   cmd[0] |= CMDQ_RESUME_0_ACTION_RETRY;
+   break;
+   default:
+