Re: [PATCH v12 03/10] iommu: Separate IOMMU_DEV_FEAT_IOPF from IOMMU_DEV_FEAT_SVA

2021-01-31 Thread Auger Eric
Hi Jean,

On 1/27/21 4:43 PM, Jean-Philippe Brucker wrote:
> Some devices manage I/O Page Faults (IOPF) themselves instead of relying
> on PCIe PRI or Arm SMMU stall. Allow their drivers to enable SVA without
> mandating IOMMU-managed IOPF. The other device drivers now need to first
> enable IOMMU_DEV_FEAT_IOPF before enabling IOMMU_DEV_FEAT_SVA. Enabling
> IOMMU_DEV_FEAT_IOPF on its own doesn't have any effect visible to the
> device driver, it is used in combination with other features.
> 
> Signed-off-by: Jean-Philippe Brucker 
Reviewed-by: Eric Auger 

Eric

> ---
> Cc: Arnd Bergmann 
> Cc: David Woodhouse 
> Cc: Greg Kroah-Hartman 
> Cc: Joerg Roedel 
> Cc: Lu Baolu 
> Cc: Will Deacon 
> Cc: Zhangfei Gao 
> Cc: Zhou Wang 
> ---
>  include/linux/iommu.h | 20 +---
>  1 file changed, 17 insertions(+), 3 deletions(-)
> 
> diff --git a/include/linux/iommu.h b/include/linux/iommu.h
> index b7ea11fc1a93..00348e4c3c26 100644
> --- a/include/linux/iommu.h
> +++ b/include/linux/iommu.h
> @@ -156,10 +156,24 @@ struct iommu_resv_region {
>   enum iommu_resv_typetype;
>  };
>  
> -/* Per device IOMMU features */
> +/**
> + * enum iommu_dev_features - Per device IOMMU features
> + * @IOMMU_DEV_FEAT_AUX: Auxiliary domain feature
> + * @IOMMU_DEV_FEAT_SVA: Shared Virtual Addresses
> + * @IOMMU_DEV_FEAT_IOPF: I/O Page Faults such as PRI or Stall. Generally
> + *enabling %IOMMU_DEV_FEAT_SVA requires
> + *%IOMMU_DEV_FEAT_IOPF, but some devices manage I/O Page
> + *Faults themselves instead of relying on the IOMMU. When
> + *supported, this feature must be enabled before and
> + *disabled after %IOMMU_DEV_FEAT_SVA.
> + *
> + * Device drivers query whether a feature is supported using
> + * iommu_dev_has_feature(), and enable it using iommu_dev_enable_feature().
> + */
>  enum iommu_dev_features {
> - IOMMU_DEV_FEAT_AUX, /* Aux-domain feature */
> - IOMMU_DEV_FEAT_SVA, /* Shared Virtual Addresses */
> + IOMMU_DEV_FEAT_AUX,
> + IOMMU_DEV_FEAT_SVA,
> + IOMMU_DEV_FEAT_IOPF,
>  };
>  
>  #define IOMMU_PASID_INVALID  (-1U)
> 

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


Re: [PATCH v12 02/10] iommu/arm-smmu-v3: Use device properties for pasid-num-bits

2021-01-31 Thread Auger Eric
Hi,

On 1/27/21 4:43 PM, Jean-Philippe Brucker wrote:
> The pasid-num-bits property shouldn't need a dedicated fwspec field,
> it's a job for device properties. Add properties for IORT, and access
> the number of PASID bits using device_property_read_u32().
> 
> Suggested-by: Robin Murphy 
> Acked-by: Jonathan Cameron 
> Signed-off-by: Jean-Philippe Brucker 
Reviewed-by: Eric Auger 

Eric

> ---
>  include/linux/iommu.h   |  2 --
>  drivers/acpi/arm64/iort.c   | 13 +++--
>  drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c |  3 ++-
>  drivers/iommu/of_iommu.c|  5 -
>  4 files changed, 9 insertions(+), 14 deletions(-)
> 
> diff --git a/include/linux/iommu.h b/include/linux/iommu.h
> index bdf3f34a4457..b7ea11fc1a93 100644
> --- a/include/linux/iommu.h
> +++ b/include/linux/iommu.h
> @@ -571,7 +571,6 @@ struct iommu_group *fsl_mc_device_group(struct device 
> *dev);
>   * @ops: ops for this device's IOMMU
>   * @iommu_fwnode: firmware handle for this device's IOMMU
>   * @flags: IOMMU_FWSPEC_* flags
> - * @num_pasid_bits: number of PASID bits supported by this device
>   * @num_ids: number of associated device IDs
>   * @ids: IDs which this device may present to the IOMMU
>   */
> @@ -579,7 +578,6 @@ struct iommu_fwspec {
>   const struct iommu_ops  *ops;
>   struct fwnode_handle*iommu_fwnode;
>   u32 flags;
> - u32 num_pasid_bits;
>   unsigned intnum_ids;
>   u32 ids[];
>  };
> diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c
> index d4eac6d7e9fb..c9a8bbb74b09 100644
> --- a/drivers/acpi/arm64/iort.c
> +++ b/drivers/acpi/arm64/iort.c
> @@ -968,15 +968,16 @@ static int iort_pci_iommu_init(struct pci_dev *pdev, 
> u16 alias, void *data)
>  static void iort_named_component_init(struct device *dev,
> struct acpi_iort_node *node)
>  {
> + struct property_entry props[2] = {};
>   struct acpi_iort_named_component *nc;
> - struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
> -
> - if (!fwspec)
> - return;
>  
>   nc = (struct acpi_iort_named_component *)node->node_data;
> - fwspec->num_pasid_bits = FIELD_GET(ACPI_IORT_NC_PASID_BITS,
> -nc->node_flags);
> + props[0] = PROPERTY_ENTRY_U32("pasid-num-bits",
> +   FIELD_GET(ACPI_IORT_NC_PASID_BITS,
> + nc->node_flags));
> +
> + if (device_add_properties(dev, props))
> + dev_warn(dev, "Could not add device properties\n");
>  }
>  
>  static int iort_nc_iommu_map(struct device *dev, struct acpi_iort_node *node)
> diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c 
> b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
> index baebaac34a83..88dd9feb32f4 100644
> --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
> +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
> @@ -2392,7 +2392,8 @@ static struct iommu_device 
> *arm_smmu_probe_device(struct device *dev)
>   }
>   }
>  
> - master->ssid_bits = min(smmu->ssid_bits, fwspec->num_pasid_bits);
> + device_property_read_u32(dev, "pasid-num-bits", >ssid_bits);
> + master->ssid_bits = min(smmu->ssid_bits, master->ssid_bits);
>  
>   /*
>* Note that PASID must be enabled before, and disabled after ATS:
> diff --git a/drivers/iommu/of_iommu.c b/drivers/iommu/of_iommu.c
> index e505b9130a1c..a9d2df001149 100644
> --- a/drivers/iommu/of_iommu.c
> +++ b/drivers/iommu/of_iommu.c
> @@ -210,11 +210,6 @@ const struct iommu_ops *of_iommu_configure(struct device 
> *dev,
>of_pci_iommu_init, );
>   } else {
>   err = of_iommu_configure_device(master_np, dev, id);
> -
> - fwspec = dev_iommu_fwspec_get(dev);
> - if (!err && fwspec)
> - of_property_read_u32(master_np, "pasid-num-bits",
> -  >num_pasid_bits);
>   }
>  
>   /*
> 

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


Re: [PATCH v12 08/10] dt-bindings: document stall property for IOMMU masters

2021-01-31 Thread Auger Eric
Hi Jean-Philippe,

On 1/27/21 4:43 PM, Jean-Philippe Brucker wrote:
> On ARM systems, some platform devices behind an IOMMU may support stall,
> which is the ability to recover from page faults. Let the firmware tell us
> when a device supports stall.
> 
> Reviewed-by: Rob Herring 
> Signed-off-by: Jean-Philippe Brucker 
Reviewed-by: Eric Auger 

Eric
> ---
>  .../devicetree/bindings/iommu/iommu.txt| 18 ++
>  1 file changed, 18 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/iommu/iommu.txt 
> b/Documentation/devicetree/bindings/iommu/iommu.txt
> index 3c36334e4f94..26ba9e530f13 100644
> --- a/Documentation/devicetree/bindings/iommu/iommu.txt
> +++ b/Documentation/devicetree/bindings/iommu/iommu.txt
> @@ -92,6 +92,24 @@ Optional properties:
>tagging DMA transactions with an address space identifier. By default,
>this is 0, which means that the device only has one address space.
>  
> +- dma-can-stall: When present, the master can wait for a transaction to
> +  complete for an indefinite amount of time. Upon translation fault some
> +  IOMMUs, instead of aborting the translation immediately, may first
> +  notify the driver and keep the transaction in flight. This allows the OS
> +  to inspect the fault and, for example, make physical pages resident
> +  before updating the mappings and completing the transaction. Such IOMMU
> +  accepts a limited number of simultaneous stalled transactions before
> +  having to either put back-pressure on the master, or abort new faulting
> +  transactions.
> +
> +  Firmware has to opt-in stalling, because most buses and masters don't
> +  support it. In particular it isn't compatible with PCI, where
> +  transactions have to complete before a time limit. More generally it
> +  won't work in systems and masters that haven't been designed for
> +  stalling. For example the OS, in order to handle a stalled transaction,
> +  may attempt to retrieve pages from secondary storage in a stalled
> +  domain, leading to a deadlock.
> +
>  
>  Notes:
>  ==
> 

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


Re: [PATCH v5 06/27] dt-bindings: mediatek: Add binding for mt8192 IOMMU

2021-01-31 Thread Yong Wu
On Fri, 2021-01-29 at 20:45 +0900, Tomasz Figa wrote:
> On Mon, Jan 25, 2021 at 4:34 PM Yong Wu  wrote:
> >
> > On Mon, 2021-01-25 at 13:18 +0900, Tomasz Figa wrote:
> > > On Wed, Jan 20, 2021 at 4:08 PM Yong Wu  wrote:
> > > >
> > > > On Wed, 2021-01-20 at 13:15 +0900, Tomasz Figa wrote:
> > > > > On Wed, Jan 13, 2021 at 3:45 PM Yong Wu  wrote:
> > > > > >
> > > > > > On Wed, 2021-01-13 at 14:30 +0900, Tomasz Figa wrote:
> > > > > > > On Thu, Dec 24, 2020 at 8:35 PM Yong Wu  
> > > > > > > wrote:
> > > > > > > >
> > > > > > > > On Wed, 2020-12-23 at 17:18 +0900, Tomasz Figa wrote:
> > > > > > > > > On Wed, Dec 09, 2020 at 04:00:41PM +0800, Yong Wu wrote:
> > > > > > > > > > This patch adds decriptions for mt8192 IOMMU and SMI.
> > > > > > > > > >
> > > > > > > > > > mt8192 also is MTK IOMMU gen2 which uses ARM 
> > > > > > > > > > Short-Descriptor translation
> > > > > > > > > > table format. The M4U-SMI HW diagram is as below:
> > > > > > > > > >
> > > > > > > > > >   EMI
> > > > > > > > > >|
> > > > > > > > > >   M4U
> > > > > > > > > >|
> > > > > > > > > >   
> > > > > > > > > >SMI Common
> > > > > > > > > >   
> > > > > > > > > >|
> > > > > > > > > >   +---+--+--+--+---+
> > > > > > > > > >   |   |  |  |   .. |   |
> > > > > > > > > >   |   |  |  |  |   |
> > > > > > > > > > larb0   larb1  larb2  larb4 ..  larb19   larb20
> > > > > > > > > > disp0   disp1   mdpvdec   IPE  IPE
> > > > > > > > > >
> > > > > > > > > > All the connections are HW fixed, SW can NOT adjust it.
> > > > > > > > > >
> > > > > > > > > > mt8192 M4U support 0~16GB iova range. we preassign 
> > > > > > > > > > different engines
> > > > > > > > > > into different iova ranges:
> > > > > > > > > >
> > > > > > > > > > domain-id  module iova-range  larbs
> > > > > > > > > >0   disp0 ~ 4G  larb0/1
> > > > > > > > > >1   vcodec  4G ~ 8G larb4/5/7
> > > > > > > > > >2   cam/mdp 8G ~ 12G 
> > > > > > > > > > larb2/9/11/13/14/16/17/18/19/20
> > > > > > > > >
> > > > > > > > > Why do we preassign these addresses in DT? Shouldn't it be a 
> > > > > > > > > user's or
> > > > > > > > > integrator's decision to split the 16 GB address range into 
> > > > > > > > > sub-ranges
> > > > > > > > > and define which larbs those sub-ranges are shared with?
> > > > > > > >
> > > > > > > > The problem is that we can't split the 16GB range with the larb 
> > > > > > > > as unit.
> > > > > > > > The example is the below ccu0(larb13 port9/10) is a independent
> > > > > > > > range(domain), the others ports in larb13 is in another domain.
> > > > > > > >
> > > > > > > > disp/vcodec/cam/mdp don't have special iova requirement, they 
> > > > > > > > could
> > > > > > > > access any range. vcodec also can locate 8G~12G. it don't care 
> > > > > > > > about
> > > > > > > > where its iova locate. here I preassign like this following 
> > > > > > > > with our
> > > > > > > > internal project setting.
> > > > > > >
> > > > > > > Let me try to understand this a bit more. Given the split you're
> > > > > > > proposing, is there actually any isolation enforced between 
> > > > > > > particular
> > > > > > > domains? For example, if I program vcodec to with a DMA address 
> > > > > > > from
> > > > > > > the 0-4G range, would the IOMMU actually generate a fault, even if
> > > > > > > disp had some memory mapped at that address?
> > > > > >
> > > > > > In this case. we will get fault in current SW setting.
> > > > > >
> > > > >
> > > > > Okay, thanks.
> > > > >
> > > > > > >
> > > > > > > >
> > > > > > > > Why set this in DT?, this is only for simplifying the code. 
> > > > > > > > Assume we
> > > > > > > > put it in the platform data. We have up to 32 larbs, each larb 
> > > > > > > > has up to
> > > > > > > > 32 ports, each port may be in different iommu domains. we 
> > > > > > > > should have a
> > > > > > > > big array for this..however we only use a macro to get the 
> > > > > > > > domain in the
> > > > > > > > DT method.
> > > > > > > >
> > > > > > > > When replying this mail, I happen to see there is a 
> > > > > > > > "dev->dev_range_map"
> > > > > > > > which has "dma-range" information, I think I could use this 
> > > > > > > > value to get
> > > > > > > > which domain the device belong to. then no need put domid in 
> > > > > > > > DT. I will
> > > > > > > > test this.
> > > > > > >
> > > > > > > My feeling is that the only part that needs to be enforced 
> > > > > > > statically
> > > > > > > is the reserved IOVA range for CCUs. The other ranges should be
> > > > > > > determined dynamically, 

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

2021-01-31 Thread Zhou Wang
On 2021/1/27 23:43, 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 
> ---
>  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   | 189 +-
>  3 files changed, 276 insertions(+), 15 deletions(-)
> 

[...]

> @@ -1033,8 +1076,7 @@ int arm_smmu_write_ctx_desc(struct arm_smmu_domain 
> *smmu_domain, int ssid,
>   FIELD_PREP(CTXDESC_CD_0_ASID, cd->asid) |
>   CTXDESC_CD_0_V;
>  
> - /* STALL_MODEL==0b10 && CD.S==0 is ILLEGAL */
> - if (smmu->features & ARM_SMMU_FEAT_STALL_FORCE)
> + if (smmu_domain->stall_enabled)

Could we add ssid checking here? like: if (smmu_domain->stall_enabled && ssid).
The reason is if not CD.S will also be set when ssid is 0, which is not needed.

Best,
Zhou

>   val |= CTXDESC_CD_0_S;
>   }
>  
> @@ -1278,7 +1320,7 @@ static void arm_smmu_write_strtab_ent(struct 
> arm_smmu_master *master, u32 sid,
>FIELD_PREP(STRTAB_STE_1_STRW, strw));
>  
>   if (smmu->features & ARM_SMMU_FEAT_STALLS &&
> -!(smmu->features & ARM_SMMU_FEAT_STALL_FORCE))
> + !master->stall_enabled)
>   dst[1] |= cpu_to_le64(STRTAB_STE_1_S1STALLD);
>  
>   val |= (s1_cfg->cdcfg.cdtab_dma & STRTAB_STE_0_S1CTXPTR_MASK) |

[...]

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


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

2021-01-31 Thread Auger Eric
Hi Jean,

Some rather minor comments§questions below that may not justify a respin.

On 1/27/21 4:43 PM, 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 
> ---
>  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   | 189 +-
>  3 files changed, 276 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 

Re: [PATCH v12 06/10] iommu: Add a page fault handler

2021-01-31 Thread Auger Eric
Hi Jean,
On 1/27/21 4:43 PM, Jean-Philippe Brucker wrote:
> Some systems allow devices to handle I/O Page Faults in the core mm. For
> example systems implementing the PCIe PRI extension or Arm SMMU stall
> model. Infrastructure for reporting these recoverable page faults was
> added to the IOMMU core by commit 0c830e6b3282 ("iommu: Introduce device
> fault report API"). Add a page fault handler for host SVA.
> 
> IOMMU driver can now instantiate several fault workqueues and link them
> to IOPF-capable devices. Drivers can choose between a single global
> workqueue, one per IOMMU device, one per low-level fault queue, one per
> domain, etc.
> 
> When it receives a fault event, most commonly in an IRQ handler, the
> IOMMU driver reports the fault using iommu_report_device_fault(), which
> calls the registered handler. The page fault handler then calls the mm
> fault handler, and reports either success or failure with
> iommu_page_response(). After the handler succeeds, the hardware retries
> the access.
> 
> The iopf_param pointer could be embedded into iommu_fault_param. But
> putting iopf_param into the iommu_param structure allows us not to care
> about ordering between calls to iopf_queue_add_device() and
> iommu_register_device_fault_handler().
> 
> Reviewed-by: Jonathan Cameron 
> Signed-off-by: Jean-Philippe Brucker 
Reviewed-by: Eric Auger 

Thanks

Eric

> ---
>  drivers/iommu/Makefile|   1 +
>  drivers/iommu/iommu-sva-lib.h |  53 
>  include/linux/iommu.h |   2 +
>  drivers/iommu/io-pgfault.c| 461 ++
>  4 files changed, 517 insertions(+)
>  create mode 100644 drivers/iommu/io-pgfault.c
> 
> diff --git a/drivers/iommu/Makefile b/drivers/iommu/Makefile
> index 61bd30cd8369..60fafc23dee6 100644
> --- a/drivers/iommu/Makefile
> +++ b/drivers/iommu/Makefile
> @@ -28,3 +28,4 @@ obj-$(CONFIG_S390_IOMMU) += s390-iommu.o
>  obj-$(CONFIG_HYPERV_IOMMU) += hyperv-iommu.o
>  obj-$(CONFIG_VIRTIO_IOMMU) += virtio-iommu.o
>  obj-$(CONFIG_IOMMU_SVA_LIB) += iommu-sva-lib.o
> +obj-$(CONFIG_IOMMU_SVA_LIB) += io-pgfault.o
> diff --git a/drivers/iommu/iommu-sva-lib.h b/drivers/iommu/iommu-sva-lib.h
> index b40990aef3fd..031155010ca8 100644
> --- a/drivers/iommu/iommu-sva-lib.h
> +++ b/drivers/iommu/iommu-sva-lib.h
> @@ -12,4 +12,57 @@ int iommu_sva_alloc_pasid(struct mm_struct *mm, ioasid_t 
> min, ioasid_t max);
>  void iommu_sva_free_pasid(struct mm_struct *mm);
>  struct mm_struct *iommu_sva_find(ioasid_t pasid);
>  
> +/* I/O Page fault */
> +struct device;
> +struct iommu_fault;
> +struct iopf_queue;
> +
> +#ifdef CONFIG_IOMMU_SVA_LIB
> +int iommu_queue_iopf(struct iommu_fault *fault, void *cookie);
> +
> +int iopf_queue_add_device(struct iopf_queue *queue, struct device *dev);
> +int iopf_queue_remove_device(struct iopf_queue *queue,
> +  struct device *dev);
> +int iopf_queue_flush_dev(struct device *dev);
> +struct iopf_queue *iopf_queue_alloc(const char *name);
> +void iopf_queue_free(struct iopf_queue *queue);
> +int iopf_queue_discard_partial(struct iopf_queue *queue);
> +
> +#else /* CONFIG_IOMMU_SVA_LIB */
> +static inline int iommu_queue_iopf(struct iommu_fault *fault, void *cookie)
> +{
> + return -ENODEV;
> +}
> +
> +static inline int iopf_queue_add_device(struct iopf_queue *queue,
> + struct device *dev)
> +{
> + return -ENODEV;
> +}
> +
> +static inline int iopf_queue_remove_device(struct iopf_queue *queue,
> +struct device *dev)
> +{
> + return -ENODEV;
> +}
> +
> +static inline int iopf_queue_flush_dev(struct device *dev)
> +{
> + return -ENODEV;
> +}
> +
> +static inline struct iopf_queue *iopf_queue_alloc(const char *name)
> +{
> + return NULL;
> +}
> +
> +static inline void iopf_queue_free(struct iopf_queue *queue)
> +{
> +}
> +
> +static inline int iopf_queue_discard_partial(struct iopf_queue *queue)
> +{
> + return -ENODEV;
> +}
> +#endif /* CONFIG_IOMMU_SVA_LIB */
>  #endif /* _IOMMU_SVA_LIB_H */
> diff --git a/include/linux/iommu.h b/include/linux/iommu.h
> index 00348e4c3c26..edc9be443a74 100644
> --- a/include/linux/iommu.h
> +++ b/include/linux/iommu.h
> @@ -366,6 +366,7 @@ struct iommu_fault_param {
>   * struct dev_iommu - Collection of per-device IOMMU data
>   *
>   * @fault_param: IOMMU detected device fault reporting data
> + * @iopf_param:   I/O Page Fault queue and data
>   * @fwspec:   IOMMU fwspec data
>   * @iommu_dev:IOMMU device this device is linked to
>   * @priv: IOMMU Driver private data
> @@ -376,6 +377,7 @@ struct iommu_fault_param {
>  struct dev_iommu {
>   struct mutex lock;
>   struct iommu_fault_param*fault_param;
> + struct iopf_device_param*iopf_param;
>   struct iommu_fwspec *fwspec;
>   struct iommu_device *iommu_dev;
>   void*priv;
> diff --git a/drivers/iommu/io-pgfault.c 

Re: [PATCH 1/1] iommu/vt-d: Add qi_submit trace event

2021-01-31 Thread Dirk Gouders
Lu Baolu  writes:

> This adds a new trace event to track the submissions of requests to the
> invalidation queue. This event will provide the information like:
> - IOMMU name
> - Invalidation type
> - Descriptor raw data
>
> A sample output like:
> | qi_submit: iotlb_inv dmar1: 0x100e2 0x0 0x0 0x0
> | qi_submit: dev_tlb_inv dmar1: 0x13 0x7001 0x0 0x0
> | qi_submit: iotlb_inv dmar2: 0x800f2 0xf9a5 0x0 0x0
>
> This will be helpful for queued invalidation related debugging.
>
> Signed-off-by: Lu Baolu 

While compiling current linux-next for some other test I noticed a
compiler error because of this patch:

drivers/iommu/intel/dmar.c: In function ‘qi_submit_sync’:
drivers/iommu/intel/dmar.c:1311:3: error: implicit declaration of function 
‘trace_qi_submit’ [-Werror=implicit-function-declaration]
 1311 |   trace_qi_submit(iommu, desc[i].qw0, desc[i].qw1,
  |   ^~~
cc1: some warnings being treated as errors

On my machine CONFIG_INTEL_IOMMU is not set so
#include  cannot provide the prototype for
that function.

Dirk

> ---
>  drivers/iommu/intel/dmar.c |  3 +++
>  include/trace/events/intel_iommu.h | 37 ++
>  2 files changed, 40 insertions(+)
>
> diff --git a/drivers/iommu/intel/dmar.c b/drivers/iommu/intel/dmar.c
> index 004feaed3c72..bd51f33642e0 100644
> --- a/drivers/iommu/intel/dmar.c
> +++ b/drivers/iommu/intel/dmar.c
> @@ -31,6 +31,7 @@
>  #include 
>  #include 
>  #include 
> +#include 
>  
>  #include "../irq_remapping.h"
>  
> @@ -1307,6 +1308,8 @@ int qi_submit_sync(struct intel_iommu *iommu, struct 
> qi_desc *desc,
>   offset = ((index + i) % QI_LENGTH) << shift;
>   memcpy(qi->desc + offset, [i], 1 << shift);
>   qi->desc_status[(index + i) % QI_LENGTH] = QI_IN_USE;
> + trace_qi_submit(iommu, desc[i].qw0, desc[i].qw1,
> + desc[i].qw2, desc[i].qw3);
>   }
>   qi->desc_status[wait_index] = QI_IN_USE;
>  
> diff --git a/include/trace/events/intel_iommu.h 
> b/include/trace/events/intel_iommu.h
> index 112bd06487bf..aad2ff0c1e2e 100644
> --- a/include/trace/events/intel_iommu.h
> +++ b/include/trace/events/intel_iommu.h
> @@ -135,6 +135,43 @@ DEFINE_EVENT(dma_map_sg, bounce_map_sg,
>struct scatterlist *sg),
>   TP_ARGS(dev, index, total, sg)
>  );
> +
> +TRACE_EVENT(qi_submit,
> + TP_PROTO(struct intel_iommu *iommu, u64 qw0, u64 qw1, u64 qw2, u64 qw3),
> +
> + TP_ARGS(iommu, qw0, qw1, qw2, qw3),
> +
> + TP_STRUCT__entry(
> + __field(u64, qw0)
> + __field(u64, qw1)
> + __field(u64, qw2)
> + __field(u64, qw3)
> + __string(iommu, iommu->name)
> + ),
> +
> + TP_fast_assign(
> + __assign_str(iommu, iommu->name);
> + __entry->qw0 = qw0;
> + __entry->qw1 = qw1;
> + __entry->qw2 = qw2;
> + __entry->qw3 = qw3;
> + ),
> +
> + TP_printk("%s %s: 0x%llx 0x%llx 0x%llx 0x%llx",
> +   __print_symbolic(__entry->qw0 & 0xf,
> +{ QI_CC_TYPE,"cc_inv" },
> +{ QI_IOTLB_TYPE, "iotlb_inv" },
> +{ QI_DIOTLB_TYPE,"dev_tlb_inv" },
> +{ QI_IEC_TYPE,   "iec_inv" },
> +{ QI_IWD_TYPE,   "inv_wait" },
> +{ QI_EIOTLB_TYPE,"p_iotlb_inv" },
> +{ QI_PC_TYPE,"pc_inv" },
> +{ QI_DEIOTLB_TYPE,   "p_dev_tlb_inv" },
> +{ QI_PGRP_RESP_TYPE, "page_grp_resp" }),
> + __get_str(iommu),
> + __entry->qw0, __entry->qw1, __entry->qw2, __entry->qw3
> + )
> +);
>  #endif /* _TRACE_INTEL_IOMMU_H */
>  
>  /* This part must be outside protection */
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu