Re: [PATCH 1/2] dma-mapping: add a dma_ops_bypass flag to struct device

2020-03-24 Thread Alexey Kardashevskiy



On 24/03/2020 18:54, Christoph Hellwig wrote:
> On Tue, Mar 24, 2020 at 02:05:54PM +1100, Alexey Kardashevskiy wrote:
>> This is for persistent memory which you can DMA to/from but yet it does
>> not appear in the system as a normal memory and therefore requires
>> special handling anyway (O_DIRECT or DAX, I do not know the exact
>> mechanics). All other devices in the system should just run as usual,
>> i.e. use 1:1 mapping if possible.
> 
> On other systems (x86 and arm) pmem as long as it is page backed does
> not require any special handling.  This must be some weird way powerpc
> fucked up again, and I suspect you'll have to suffer from it.


It does not matter if it is backed by pages or not, the problem may also
appear if we wanted for example p2p PCI via IOMMU (between PHBs) and
MMIO might be mapped way too high in the system address space and make
1:1 impossible.


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


Re: [PATCH 1/3] iommu/vt-d: Remove redundant IOTLB flush

2020-03-24 Thread Lu Baolu

On 2020/3/24 23:31, Jacob Pan wrote:

On Sat, 21 Mar 2020 09:32:45 +0800
Lu Baolu  wrote:


On 2020/3/21 0:20, Jacob Pan wrote:

On Fri, 20 Mar 2020 21:45:26 +0800
Lu Baolu  wrote:
   

On 2020/3/20 12:32, Jacob Pan wrote:

IOTLB flush already included in the PASID tear down process. There
is no need to flush again.

It seems that intel_pasid_tear_down_entry() doesn't flush the pasid
based device TLB?
  

I saw this code in intel_pasid_tear_down_entry(). Isn't the last
line flush the devtlb? Not in guest of course since the passdown
tlb flush is inclusive.

pasid_cache_invalidation_with_pasid(iommu, did, pasid);
iotlb_invalidation_with_pasid(iommu, did, pasid);

/* Device IOTLB doesn't need to be flushed in caching mode.
*/ if (!cap_caching_mode(iommu->cap))
devtlb_invalidation_with_pasid(iommu, dev, pasid);
   

But devtlb_invalidation_with_pasid() doesn't do the right thing, it
flushes the device tlb, instead of pasid-based device tlb.


Hmm, you are right. But the function name is misleading, pasid argument
is not used, is there a reason why?
This is used for PASID based device IOTLB flush, right?



Yes. I will fix and put your patch after it.

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


Re: [PATCH 2/2] iommu/vt-d: Replace intel SVM APIs with generic SVA APIs

2020-03-24 Thread Jacob Pan
On Fri, 20 Mar 2020 10:29:55 +0100
Jean-Philippe Brucker  wrote:

> Hi Jacob,
> 
> I think this step is really useful and the patch looks good overall,
> thanks for doing this. Some commments inline
> 
> On Mon, Feb 24, 2020 at 03:26:37PM -0800, Jacob Pan wrote:
> > This patch is an initial step to replace Intel SVM code with the
> > following IOMMU SVA ops:
> > intel_svm_bind_mm() => iommu_sva_bind_device()
> > intel_svm_unbind_mm() => iommu_sva_unbind_device()
> > intel_svm_is_pasid_valid() => iommu_sva_get_pasid()
> > 
> > The features below will continue to work but are not included in
> > this patch in that they are handled mostly within the IOMMU
> > subsystem.
> > - IO page fault
> > - mmu notifier
> > 
> > Consolidation of the above will come after merging generic IOMMU sva
> > code[1]. There should not be any changes needed for SVA users such
> > as accelerator device drivers during this time.
> > 
> > [1] http://jpbrucker.net/sva/
> > 
> > Signed-off-by: Jacob Pan 
> > ---
> >  drivers/iommu/intel-iommu.c |   3 ++
> >  drivers/iommu/intel-svm.c   | 123
> > 
> > include/linux/intel-iommu.h |   7 +++ include/linux/intel-svm.h
> > |  85 -- 4 files changed, 78
> > insertions(+), 140 deletions(-)
> > 
> > diff --git a/drivers/iommu/intel-iommu.c
> > b/drivers/iommu/intel-iommu.c index 5eca6e10d2a4..ccfa5adfd06d
> > 100644 --- a/drivers/iommu/intel-iommu.c
> > +++ b/drivers/iommu/intel-iommu.c
> > @@ -6475,6 +6475,9 @@ const struct iommu_ops intel_iommu_ops = {
> > .cache_invalidate   = intel_iommu_sva_invalidate,
> > .sva_bind_gpasid= intel_svm_bind_gpasid,
> > .sva_unbind_gpasid  = intel_svm_unbind_gpasid,
> > +   .sva_bind   = intel_svm_bind,
> > +   .sva_unbind = intel_svm_unbind,
> > +   .sva_get_pasid  = intel_svm_get_pasid,
> >  #endif
> >  };
> >  
> > diff --git a/drivers/iommu/intel-svm.c b/drivers/iommu/intel-svm.c
> > index 1d7a95372f8c..35d949513728 100644
> > --- a/drivers/iommu/intel-svm.c
> > +++ b/drivers/iommu/intel-svm.c
> > @@ -516,13 +516,14 @@ int intel_svm_unbind_gpasid(struct device
> > *dev, int pasid) return ret;
> >  }
> >  
> > -int intel_svm_bind_mm(struct device *dev, int *pasid, int flags,
> > struct svm_dev_ops *ops) +/* Caller must hold pasid_mutex, mm
> > reference */ +static int intel_svm_bind_mm(struct device *dev, int
> > flags, struct svm_dev_ops *ops,
> > + struct mm_struct *mm, struct intel_svm_dev
> > **sd) {
> > struct intel_iommu *iommu = intel_svm_device_to_iommu(dev);
> > struct device_domain_info *info;
> > struct intel_svm_dev *sdev;
> > struct intel_svm *svm = NULL;
> > -   struct mm_struct *mm = NULL;
> > int pasid_max;
> > int ret;
> >  
> > @@ -539,16 +540,15 @@ int intel_svm_bind_mm(struct device *dev, int
> > *pasid, int flags, struct svm_dev_ } else
> > pasid_max = 1 << 20;
> >  
> > +   /* Bind supervisor PASID shuld have mm = NULL */  
> 
> should
> 
> > if (flags & SVM_FLAG_SUPERVISOR_MODE) {
> > -   if (!ecap_srs(iommu->ecap))
> > +   if (!ecap_srs(iommu->ecap) || mm) {
> > +   pr_err("Supervisor PASID with user
> > provided mm.\n"); return -EINVAL;
> > -   } else if (pasid) {
> > -   mm = get_task_mm(current);
> > -   BUG_ON(!mm);
> > +   }
> > }
> >  
> > -   mutex_lock(_mutex);
> > -   if (pasid && !(flags & SVM_FLAG_PRIVATE_PASID)) {
> > +   if (!(flags & SVM_FLAG_PRIVATE_PASID)) {
> > struct intel_svm *t;
> >  
> > list_for_each_entry(t, _svm_list, list) {
> > @@ -586,9 +586,7 @@ int intel_svm_bind_mm(struct device *dev, int
> > *pasid, int flags, struct svm_dev_ sdev->dev = dev;
> >  
> > ret = intel_iommu_enable_pasid(iommu, dev);
> > -   if (ret || !pasid) {
> > -   /* If they don't actually want to assign a PASID,
> > this is
> > -* just an enabling check/preparation. */
> > +   if (ret) {
> > kfree(sdev);
> > goto out;
> > }
> > @@ -688,18 +686,17 @@ int intel_svm_bind_mm(struct device *dev, int
> > *pasid, int flags, struct svm_dev_ }
> > }
> > list_add_rcu(>list, >devs);
> > -
> > - success:
> > -   *pasid = svm->pasid;
> > +success:
> > +   sdev->pasid = svm->pasid;
> > +   sdev->sva.dev = dev;
> > +   if (sd)
> > +   *sd = sdev;  
> 
> One thing that might be missing: calling bind() multiple times with
> the same (dev, mm) pair should take references to the svm struct, so
> device drivers can call unbind() on it that many times.
> 
> > ret = 0;
> >   out:
> > -   mutex_unlock(_mutex);
> > -   if (mm)
> > -   mmput(mm);
> > return ret;
> >  }
> > -EXPORT_SYMBOL_GPL(intel_svm_bind_mm);
> >  
> > +/* Caller must hold pasid_mutex */
> >  int intel_svm_unbind_mm(struct device *dev, int pasid)
> >  {
> > struct intel_svm_dev *sdev;
> > @@ -707,7 +704,6 @@ int 

Re: [PATCH 1/3] iommu/vt-d: Remove redundant IOTLB flush

2020-03-24 Thread Jacob Pan
On Sat, 21 Mar 2020 09:32:45 +0800
Lu Baolu  wrote:

> On 2020/3/21 0:20, Jacob Pan wrote:
> > On Fri, 20 Mar 2020 21:45:26 +0800
> > Lu Baolu  wrote:
> >   
> >> On 2020/3/20 12:32, Jacob Pan wrote:  
> >>> IOTLB flush already included in the PASID tear down process. There
> >>> is no need to flush again.  
> >>
> >> It seems that intel_pasid_tear_down_entry() doesn't flush the pasid
> >> based device TLB?
> >>  
> > I saw this code in intel_pasid_tear_down_entry(). Isn't the last
> > line flush the devtlb? Not in guest of course since the passdown
> > tlb flush is inclusive.
> > 
> > pasid_cache_invalidation_with_pasid(iommu, did, pasid);
> > iotlb_invalidation_with_pasid(iommu, did, pasid);
> > 
> > /* Device IOTLB doesn't need to be flushed in caching mode.
> > */ if (!cap_caching_mode(iommu->cap))
> > devtlb_invalidation_with_pasid(iommu, dev, pasid);
> >   
> 
> But devtlb_invalidation_with_pasid() doesn't do the right thing, it
> flushes the device tlb, instead of pasid-based device tlb.
> 
Hmm, you are right. But the function name is misleading, pasid argument
is not used, is there a reason why?
This is used for PASID based device IOTLB flush, right?

> static void
> devtlb_invalidation_with_pasid(struct intel_iommu *iommu,
> struct device *dev, int pasid)
> {
>  struct device_domain_info *info;
>  u16 sid, qdep, pfsid;
> 
>  info = dev->archdata.iommu;
>  if (!info || !info->ats_enabled)
>  return;
> 
>  sid = info->bus << 8 | info->devfn;
>  qdep = info->ats_qdep;
>  pfsid = info->pfsid;
> 
>  qi_flush_dev_iotlb(iommu, sid, pfsid, qdep, 0, 64 - 
> VTD_PAGE_SHIFT);
> }
> 
> Best regards,
> baolu
> 
> >> Best regards,
> >> baolu
> >>  
> >>>
> >>> Cc: Lu Baolu 
> >>> Signed-off-by: Jacob Pan 
> >>> ---
> >>>drivers/iommu/intel-svm.c | 6 ++
> >>>1 file changed, 2 insertions(+), 4 deletions(-)
> >>>
> >>> diff --git a/drivers/iommu/intel-svm.c b/drivers/iommu/intel-svm.c
> >>> index 8f42d717d8d7..1483f1845762 100644
> >>> --- a/drivers/iommu/intel-svm.c
> >>> +++ b/drivers/iommu/intel-svm.c
> >>> @@ -268,10 +268,9 @@ static void intel_mm_release(struct
> >>> mmu_notifier *mn, struct mm_struct *mm)
> >>>* *has* to handle gracefully without affecting other
> >>> processes. */
> >>>   rcu_read_lock();
> >>> - list_for_each_entry_rcu(sdev, >devs, list) {
> >>> + list_for_each_entry_rcu(sdev, >devs, list)
> >>>   intel_pasid_tear_down_entry(svm->iommu,
> >>> sdev->dev, svm->pasid);
> >>> - intel_flush_svm_range_dev(svm, sdev, 0, -1, 0);
> >>> - }
> >>> +
> >>>   rcu_read_unlock();
> >>>
> >>>}
> >>> @@ -731,7 +730,6 @@ int intel_svm_unbind_mm(struct device *dev,
> >>> int pasid)
> >>>* large and has to be physically
> >>> contiguous. So it's
> >>>* hard to be as defensive as we might
> >>> like. */ intel_pasid_tear_down_entry(iommu, dev, svm->pasid);
> >>> - intel_flush_svm_range_dev(svm, sdev, 0,
> >>> -1, 0); kfree_rcu(sdev, rcu);
> >>>
> >>>   if (list_empty(>devs)) {
> >>>  
> > 
> > [Jacob Pan]
> >   

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


Re: arm-smmu-v3 high cpu usage for NVMe

2020-03-24 Thread John Garry

On 24/03/2020 12:07, Robin Murphy wrote:

On 2020-03-24 11:55 am, John Garry wrote:

On 24/03/2020 10:43, Marc Zyngier wrote:

On Tue, 24 Mar 2020 09:18:10 +
John Garry  wrote:


On 23/03/2020 09:16, Marc Zyngier wrote:

+ Julien, Mark

Hi Marc,


Time to enable pseudo-NMIs in the PMUv3 driver...


Do you know if there is any plan for this?
There was. Julien Thierry has a bunch of patches for that [1], but 
they > needs

reviving.


So those patches still apply cleanly (apart from the kvm patch, which
I can skip, I suppose) and build, so I can try this I figure. Is
there anything else which I should ensure or know about? Apart from
enable CONFIG_ARM64_PSUEDO_NMI.

You need to make sure that your firmware sets SCR_EL3.FIQ to 1. My D05
has it set to 0, preventing me from being able to use the feature
(hint, nudge...;-).


Yeah, apparently it's set on our D06CS board, but I just need to 
double check the FW version with our FW guy.


Hopefully you saw the help for CONFIG_ARM64_PSUEDO_NMI already, but 
since it's not been called out:


   This high priority configuration for interrupts needs to be
   explicitly enabled by setting the kernel parameter
   "irqchip.gicv3_pseudo_nmi" to 1.


Yeah, I saw that by chance somewhere else previously.



FWIW I believe is is still on the plan for someone here to dust off the 
PMU pNMI patches at some point.


Cool. Well I can try to experiment with what Julien had at v4 for now.

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

Re: arm-smmu-v3 high cpu usage for NVMe

2020-03-24 Thread Robin Murphy

On 2020-03-24 11:55 am, John Garry wrote:

On 24/03/2020 10:43, Marc Zyngier wrote:

On Tue, 24 Mar 2020 09:18:10 +
John Garry  wrote:


On 23/03/2020 09:16, Marc Zyngier wrote:

+ Julien, Mark

Hi Marc,


Time to enable pseudo-NMIs in the PMUv3 driver...


Do you know if there is any plan for this?
There was. Julien Thierry has a bunch of patches for that [1], but 
they > needs

reviving.


So those patches still apply cleanly (apart from the kvm patch, which
I can skip, I suppose) and build, so I can try this I figure. Is
there anything else which I should ensure or know about? Apart from
enable CONFIG_ARM64_PSUEDO_NMI.

You need to make sure that your firmware sets SCR_EL3.FIQ to 1. My D05
has it set to 0, preventing me from being able to use the feature
(hint, nudge...;-).


Yeah, apparently it's set on our D06CS board, but I just need to double 
check the FW version with our FW guy.


Hopefully you saw the help for CONFIG_ARM64_PSUEDO_NMI already, but 
since it's not been called out:


  This high priority configuration for interrupts needs to be
  explicitly enabled by setting the kernel parameter
  "irqchip.gicv3_pseudo_nmi" to 1.

FWIW I believe is is still on the plan for someone here to dust off the 
PMU pNMI patches at some point.


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

Re: arm-smmu-v3 high cpu usage for NVMe

2020-03-24 Thread John Garry

On 24/03/2020 10:43, Marc Zyngier wrote:

On Tue, 24 Mar 2020 09:18:10 +
John Garry  wrote:


On 23/03/2020 09:16, Marc Zyngier wrote:

+ Julien, Mark

Hi Marc,


Time to enable pseudo-NMIs in the PMUv3 driver...


Do you know if there is any plan for this?

There was. Julien Thierry has a bunch of patches for that [1], but they > needs
reviving.


So those patches still apply cleanly (apart from the kvm patch, which
I can skip, I suppose) and build, so I can try this I figure. Is
there anything else which I should ensure or know about? Apart from
enable CONFIG_ARM64_PSUEDO_NMI.

You need to make sure that your firmware sets SCR_EL3.FIQ to 1. My D05
has it set to 0, preventing me from being able to use the feature
(hint, nudge...;-).


Yeah, apparently it's set on our D06CS board, but I just need to double 
check the FW version with our FW guy.


As for D05, there has not been a FW update there in quite a long time 
and no plans for it. Sorry.


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


[RFC PATCH v2 4/4] iommu/of: get rid of fsl-mc specific code

2020-03-24 Thread laurentiu . tudor
From: Laurentiu Tudor 

Changing the way we configure dma for fsl-mc devices allows
us to get rid of our fsl-mc specific code in the generic
of iommu code.

Signed-off-by: Laurentiu Tudor 
---
 drivers/iommu/of_iommu.c | 20 
 1 file changed, 20 deletions(-)

diff --git a/drivers/iommu/of_iommu.c b/drivers/iommu/of_iommu.c
index 20738aacac89..332072ada474 100644
--- a/drivers/iommu/of_iommu.c
+++ b/drivers/iommu/of_iommu.c
@@ -15,7 +15,6 @@
 #include 
 #include 
 #include 
-#include 
 
 #define NO_IOMMU   1
 
@@ -139,23 +138,6 @@ static int of_pci_iommu_init(struct pci_dev *pdev, u16 
alias, void *data)
return err;
 }
 
-static int of_fsl_mc_iommu_init(struct fsl_mc_device *mc_dev,
-   struct device_node *master_np)
-{
-   struct of_phandle_args iommu_spec = { .args_count = 1 };
-   int err;
-
-   err = of_map_rid(master_np, mc_dev->icid, "iommu-map",
-"iommu-map-mask", _spec.np,
-iommu_spec.args);
-   if (err)
-   return err == -ENODEV ? NO_IOMMU : err;
-
-   err = of_iommu_xlate(_dev->dev, _spec);
-   of_node_put(iommu_spec.np);
-   return err;
-}
-
 const struct iommu_ops *of_iommu_configure(struct device *dev,
   struct device_node *master_np)
 {
@@ -188,8 +170,6 @@ const struct iommu_ops *of_iommu_configure(struct device 
*dev,
pci_request_acs();
err = pci_for_each_dma_alias(to_pci_dev(dev),
 of_pci_iommu_init, );
-   } else if (dev_is_fsl_mc(dev)) {
-   err = of_fsl_mc_iommu_init(to_fsl_mc_device(dev), master_np);
} else {
struct of_phandle_args iommu_spec;
int idx = 0;
-- 
2.17.1

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


[RFC PATCH v2 3/4] bus: fsl-mc: Add ACPI support for fsl-mc

2020-03-24 Thread laurentiu . tudor
From: Makarand Pawagi 

ACPI support is added in the fsl-mc driver. Driver will parse
MC DSDT table to extract memory and other resorces.

Interrupt (GIC ITS) information will be extracted from MADT table
by drivers/irqchip/irq-gic-v3-its-fsl-mc-msi.c.

IORT table will be parsed to configure DMA.

Signed-off-by: Makarand Pawagi 
---
 drivers/bus/fsl-mc/fsl-mc-bus.c | 35 ++-
 drivers/irqchip/irq-gic-v3-its-fsl-mc-msi.c | 69 -
 2 files changed, 87 insertions(+), 17 deletions(-)

diff --git a/drivers/bus/fsl-mc/fsl-mc-bus.c b/drivers/bus/fsl-mc/fsl-mc-bus.c
index a3d25c1d4ff8..fbd248597e88 100644
--- a/drivers/bus/fsl-mc/fsl-mc-bus.c
+++ b/drivers/bus/fsl-mc/fsl-mc-bus.c
@@ -952,7 +952,7 @@ static int fsl_mc_bus_probe(struct platform_device *pdev)
phys_addr_t mc_portal_phys_addr;
u32 mc_portal_size;
struct mc_version mc_version;
-   struct resource res;
+   struct resource *plat_res;
 
mc = devm_kzalloc(>dev, sizeof(*mc), GFP_KERNEL);
if (!mc)
@@ -963,16 +963,9 @@ static int fsl_mc_bus_probe(struct platform_device *pdev)
/*
 * Get physical address of MC portal for the root DPRC:
 */
-   error = of_address_to_resource(pdev->dev.of_node, 0, );
-   if (error < 0) {
-   dev_err(>dev,
-   "of_address_to_resource() failed for %pOF\n",
-   pdev->dev.of_node);
-   return error;
-   }
-
-   mc_portal_phys_addr = res.start;
-   mc_portal_size = resource_size();
+   plat_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+   mc_portal_phys_addr = plat_res->start;
+   mc_portal_size = resource_size(plat_res);
error = fsl_create_mc_io(>dev, mc_portal_phys_addr,
 mc_portal_size, NULL,
 FSL_MC_IO_ATOMIC_CONTEXT_PORTAL, _io);
@@ -989,11 +982,13 @@ static int fsl_mc_bus_probe(struct platform_device *pdev)
dev_info(>dev, "MC firmware version: %u.%u.%u\n",
 mc_version.major, mc_version.minor, mc_version.revision);
 
-   error = get_mc_addr_translation_ranges(>dev,
-  >translation_ranges,
-  >num_translation_ranges);
-   if (error < 0)
-   goto error_cleanup_mc_io;
+   if (dev_of_node(>dev)) {
+   error = get_mc_addr_translation_ranges(>dev,
+   >translation_ranges,
+   >num_translation_ranges);
+   if (error < 0)
+   goto error_cleanup_mc_io;
+   }
 
error = dprc_get_container_id(mc_io, 0, _id);
if (error < 0) {
@@ -1020,6 +1015,7 @@ static int fsl_mc_bus_probe(struct platform_device *pdev)
goto error_cleanup_mc_io;
 
mc->root_mc_bus_dev = mc_bus_dev;
+   mc_bus_dev->dev.fwnode = pdev->dev.fwnode;
return 0;
 
 error_cleanup_mc_io:
@@ -1053,11 +1049,18 @@ static const struct of_device_id 
fsl_mc_bus_match_table[] = {
 
 MODULE_DEVICE_TABLE(of, fsl_mc_bus_match_table);
 
+static const struct acpi_device_id fsl_mc_bus_acpi_match_table[] = {
+   {"NXP0008", 0 },
+   { }
+};
+MODULE_DEVICE_TABLE(acpi, fsl_mc_bus_acpi_match_table);
+
 static struct platform_driver fsl_mc_bus_driver = {
.driver = {
   .name = "fsl_mc_bus",
   .pm = NULL,
   .of_match_table = fsl_mc_bus_match_table,
+  .acpi_match_table = fsl_mc_bus_acpi_match_table,
   },
.probe = fsl_mc_bus_probe,
.remove = fsl_mc_bus_remove,
diff --git a/drivers/irqchip/irq-gic-v3-its-fsl-mc-msi.c 
b/drivers/irqchip/irq-gic-v3-its-fsl-mc-msi.c
index 606efa64adff..6d67834722c9 100644
--- a/drivers/irqchip/irq-gic-v3-its-fsl-mc-msi.c
+++ b/drivers/irqchip/irq-gic-v3-its-fsl-mc-msi.c
@@ -4,9 +4,11 @@
  *
  * Copyright (C) 2015-2016 Freescale Semiconductor, Inc.
  * Author: German Rivera 
+ * Copyright 2020 NXP
  *
  */
 
+#include 
 #include 
 #include 
 #include 
@@ -66,7 +68,65 @@ static const struct of_device_id its_device_id[] = {
{},
 };
 
-static int __init its_fsl_mc_msi_init(void)
+static int __init its_fsl_mc_msi_init_one(struct fwnode_handle *handle,
+ const char *name)
+{
+   struct irq_domain *parent;
+   struct irq_domain *mc_msi_domain;
+
+   parent = irq_find_matching_fwnode(handle, DOMAIN_BUS_NEXUS);
+   if (!parent || !msi_get_domain_info(parent)) {
+   pr_err("%s: Unable to locate ITS domain\n", name);
+   return -ENXIO;
+   }
+
+   mc_msi_domain = fsl_mc_msi_create_irq_domain(handle,
+
_fsl_mc_msi_domain_info,
+parent);
+   if (!mc_msi_domain)
+   

[RFC PATCH v2 0/4] bus: fsl-mc: Add ACPI support for fsl-mc

2020-03-24 Thread laurentiu . tudor
From: Laurentiu Tudor 

This patch adds ACPI support for the fsl-mc bus driver. First 2 patches
are prerequsite that remove dependencies on device tree. Third patch
adds the actual ACPI support and the final one drops some fsl-mc
specific code in the generic device tree handling code.

Changes in v2:
 - add missing of_xlate call in custom .dma_configure (patch 1)
 - added a cover letter

Diana Craciun (1):
  irqchip/fsl-mc: Change the way the IRQ domain is set for MC devices

Laurentiu Tudor (2):
  bus: fsl-mc: add custom .dma_configure implementation
  iommu/of: get rid of fsl-mc specific code

Makarand Pawagi (1):
  bus: fsl-mc: Add ACPI support for fsl-mc

 drivers/bus/fsl-mc/fsl-mc-bus.c | 85 -
 drivers/bus/fsl-mc/fsl-mc-msi.c | 11 ++-
 drivers/iommu/of_iommu.c| 20 -
 drivers/irqchip/irq-gic-v3-its-fsl-mc-msi.c | 69 -
 4 files changed, 145 insertions(+), 40 deletions(-)

-- 
2.17.1

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


[RFC PATCH v2 2/4] irqchip/fsl-mc: Change the way the IRQ domain is set for MC devices

2020-03-24 Thread laurentiu . tudor
From: Diana Craciun 

In ACPI the MC bus is represented as a platform device and a named
component in the IORT table. The mc-bus devices are discovered
dynamically at runtime but they share the same fwnode with the parent
platfom device. This patch changes the way the IRQ domain is searched
for the MC devices: it takes the fwnode reference from the parent and
uses the fwnode reference to find the MC IRQ domain.

Signed-off-by: Diana Craciun 
---
 drivers/bus/fsl-mc/fsl-mc-msi.c | 11 +--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/drivers/bus/fsl-mc/fsl-mc-msi.c b/drivers/bus/fsl-mc/fsl-mc-msi.c
index 8b9c66d7c4ff..1e2e97329781 100644
--- a/drivers/bus/fsl-mc/fsl-mc-msi.c
+++ b/drivers/bus/fsl-mc/fsl-mc-msi.c
@@ -182,16 +182,23 @@ int fsl_mc_find_msi_domain(struct device *mc_platform_dev,
 {
struct irq_domain *msi_domain;
struct device_node *mc_of_node = mc_platform_dev->of_node;
+   struct fwnode_handle *fwnode;
 
-   msi_domain = of_msi_get_domain(mc_platform_dev, mc_of_node,
-  DOMAIN_BUS_FSL_MC_MSI);
+   msi_domain = dev_get_msi_domain(mc_platform_dev);
if (!msi_domain) {
pr_err("Unable to find fsl-mc MSI domain for %pOF\n",
   mc_of_node);
 
return -ENOENT;
}
+   fwnode = msi_domain->fwnode;
+   msi_domain = irq_find_matching_fwnode(fwnode, DOMAIN_BUS_FSL_MC_MSI);
+   if (!msi_domain) {
+   pr_err("Unable to find fsl-mc MSI domain for %pOF\n",
+  mc_of_node);
 
+   return -ENOENT;
+   }
*mc_msi_domain = msi_domain;
return 0;
 }
-- 
2.17.1

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


[RFC PATCH v2 1/4] bus: fsl-mc: add custom .dma_configure implementation

2020-03-24 Thread laurentiu . tudor
From: Laurentiu Tudor 

The devices on this bus are not discovered by way of device tree
but by queries to the firmware. It makes little sense to trick the
generic of layer into thinking that these devices are of related so
that we can get our dma configuration. Instead of doing that, add
our custom dma configuration implementation.

Signed-off-by: Laurentiu Tudor 
---
 drivers/bus/fsl-mc/fsl-mc-bus.c | 50 -
 1 file changed, 49 insertions(+), 1 deletion(-)

diff --git a/drivers/bus/fsl-mc/fsl-mc-bus.c b/drivers/bus/fsl-mc/fsl-mc-bus.c
index a0f8854acb3a..a3d25c1d4ff8 100644
--- a/drivers/bus/fsl-mc/fsl-mc-bus.c
+++ b/drivers/bus/fsl-mc/fsl-mc-bus.c
@@ -18,6 +18,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "fsl-mc-private.h"
 
@@ -130,11 +131,58 @@ static int fsl_mc_bus_uevent(struct device *dev, struct 
kobj_uevent_env *env)
 static int fsl_mc_dma_configure(struct device *dev)
 {
struct device *dma_dev = dev;
+   struct iommu_fwspec *fwspec;
+   const struct iommu_ops *iommu_ops;
+   struct fsl_mc_device *mc_dev = to_fsl_mc_device(dev);
+   int ret;
+   u32 icid;
+
+   /* Skip DMA setup for devices that are not DMA masters */
+   if (dev->type == _mc_bus_dpmcp_type ||
+   dev->type == _mc_bus_dpbp_type ||
+   dev->type == _mc_bus_dpcon_type ||
+   dev->type == _mc_bus_dpio_type)
+   return 0;
 
while (dev_is_fsl_mc(dma_dev))
dma_dev = dma_dev->parent;
 
-   return of_dma_configure(dev, dma_dev->of_node, 0);
+   fwspec = dev_iommu_fwspec_get(dma_dev);
+   if (!fwspec)
+   return -ENODEV;
+   iommu_ops = iommu_ops_from_fwnode(fwspec->iommu_fwnode);
+   if (!iommu_ops)
+   return -ENODEV;
+
+   ret = iommu_fwspec_init(dev, fwspec->iommu_fwnode, iommu_ops);
+   if (ret)
+   return ret;
+
+   if (iommu_ops->of_xlate) {
+   struct of_phandle_args iommu_spec = {
+   .np = fwspec->iommu_fwnode->dev->of_node,
+   .args[0] = mc_dev->icid,
+   .args_count = 1
+   };
+
+   ret = iommu_ops->of_xlate(dev, _spec);
+   if (ret) {
+   iommu_fwspec_free(dev);
+   return ret;
+   }
+   }
+
+   if (!device_iommu_mapped(dev)) {
+   ret = iommu_probe_device(dev);
+   if (ret) {
+   iommu_fwspec_free(dev);
+   return ret;
+   }
+   }
+
+   arch_setup_dma_ops(dev, 0, *dma_dev->dma_mask + 1, iommu_ops, true);
+
+   return 0;
 }
 
 static ssize_t modalias_show(struct device *dev, struct device_attribute *attr,
-- 
2.17.1

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


Re: arm-smmu-v3 high cpu usage for NVMe

2020-03-24 Thread Marc Zyngier
On Tue, 24 Mar 2020 09:18:10 +
John Garry  wrote:

> On 23/03/2020 09:16, Marc Zyngier wrote:
> 
> + Julien, Mark
> 
> Hi Marc,
> 
> >>> Time to enable pseudo-NMIs in the PMUv3 driver...
> >>>
> >>
> >> Do you know if there is any plan for this?
> > 
> > There was. Julien Thierry has a bunch of patches for that [1], but they > 
> > needs
> > reviving.
> > 
> 
> So those patches still apply cleanly (apart from the kvm patch, which
> I can skip, I suppose) and build, so I can try this I figure. Is
> there anything else which I should ensure or know about? Apart from
> enable CONFIG_ARM64_PSUEDO_NMI.

You need to make sure that your firmware sets SCR_EL3.FIQ to 1. My D05
has it set to 0, preventing me from being able to use the feature
(hint, nudge... ;-).

M.
-- 
Jazz is not dead. It just smells funny...
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH v3 10/15] iommu/arm-smmu: Use accessor functions for iommu private data

2020-03-24 Thread Joerg Roedel
Hey Robin,

On Mon, Mar 23, 2020 at 04:02:33PM +, Robin Murphy wrote:
> Yikes, this ends up pretty ugly, and I'd prefer not have this much
> complexity hidden in macros that were intended just to be convenient
> shorthand. Would you mind pulling in the patch below as a precursor?

Sure thing, but your mail-client seemed to have fiddled with the patch
so that is is unusable to me. I tried to fix it up, but it still doesn't
apply. Can you please re-send it to me either via git-send-email or just
as a mime-attachement?

> Other than that, the rest of the series looks OK at a glance. We should also
> move fwspec->ops to dev_iommu, as those are "IOMMU API" data rather than
> "firmware" data, but let's consider that separately as this series is
> already long enough.

Yes, moving ops out of fwspec is next on the list, and moving the
iommu_group pointer into dev_iommu.

Regards,

Joerg

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


Re: arm-smmu-v3 high cpu usage for NVMe

2020-03-24 Thread John Garry

On 23/03/2020 09:16, Marc Zyngier wrote:

+ Julien, Mark

Hi Marc,


Time to enable pseudo-NMIs in the PMUv3 driver...



Do you know if there is any plan for this?


There was. Julien Thierry has a bunch of patches for that [1], but they 
needs

reviving.



So those patches still apply cleanly (apart from the kvm patch, which I 
can skip, I suppose) and build, so I can try this I figure. Is there 
anything else which I should ensure or know about? Apart from enable 
CONFIG_ARM64_PSUEDO_NMI.


A quickly taken perf annotate and report is at the tip here: 
https://github.com/hisilicon/kernel-dev/commits/private-topic-nvme-5.6-profiling 





In the meantime, maybe I can do some trickery by putting the
local_irq_restore() in a separate function, outside
arm_smmu_cmdq_issue_cmdlist(), to get a fair profile for that same
function.




Scratch that :)


I don't see how you can improve the profiling without compromising
the locking in this case...



Cheers,
John

[1] https://patchwork.kernel.org/cover/11047407/
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [EXT] Re: [PATCH RFC] iommu/virtio: Use page size bitmap supported by endpoint

2020-03-24 Thread Jean-Philippe Brucker
On Mon, Mar 23, 2020 at 05:25:17PM +, Bharat Bhushan wrote:
> Hi Jean,
> 
> > -Original Message-
> > From: Jean-Philippe Brucker 
> > Sent: Monday, March 23, 2020 3:30 PM
> > To: Bharat Bhushan 
> > Cc: j...@8bytes.org; m...@redhat.com; jasow...@redhat.com;
> > virtualizat...@lists.linux-foundation.org; iommu@lists.linux-foundation.org;
> > eric.au...@redhat.com
> > Subject: [EXT] Re: [PATCH RFC] iommu/virtio: Use page size bitmap supported 
> > by
> > endpoint
> > 
> > External Email
> > 
> > --
> > Hi Bharat,
> > 
> > Please add the IOMMU list on your next posting
> 
> iommu@lists.linux-foundation.org is there, any other mailing list we need to 
> add?

I added that address when replying :) It doesn't look like your patch
reached the list:
https://lore.kernel.org/linux-iommu/20200323095943.GA2038940@myrica/T/
But virtualization and iommu lists are enough.

Thanks,
Jean

> 
> > 
> > On Mon, Mar 23, 2020 at 02:11:08PM +0530, Bharat Bhushan wrote:
> > > Different endpoint can support different page size, probe endpoint if
> > > it supports specific page size otherwise use global page sizes.
> > >
> > > Signed-off-by: Bharat Bhushan 
> > > ---
> > >  drivers/iommu/virtio-iommu.c  | 24 
> > >  include/uapi/linux/virtio_iommu.h |  6 ++
> > >  2 files changed, 26 insertions(+), 4 deletions(-)
> > >
> > > diff --git a/drivers/iommu/virtio-iommu.c
> > > b/drivers/iommu/virtio-iommu.c index cce329d71fba..e69347ca4ee6 100644
> > > --- a/drivers/iommu/virtio-iommu.c
> > > +++ b/drivers/iommu/virtio-iommu.c
> > > @@ -78,6 +78,7 @@ struct viommu_endpoint {
> > >   struct viommu_dev   *viommu;
> > >   struct viommu_domain*vdomain;
> > >   struct list_headresv_regions;
> > > + u64 pgsize_bitmap;
> > >  };
> > >
> > >  struct viommu_request {
> > > @@ -415,6 +416,14 @@ static int viommu_replay_mappings(struct
> > viommu_domain *vdomain)
> > >   return ret;
> > >  }
> > >
> > > +static int viommu_set_pgsize_bitmap(struct viommu_endpoint *vdev,
> > > + struct virtio_iommu_probe_pgsize_mask *mask)
> > > +
> > > +{
> > > + vdev->pgsize_bitmap = mask->pgsize_bitmap;
> > 
> > We need to read this through le64_to_cpu(). Also check that the length of 
> > the field
> > provided by the device is >= sizeof(mask) (like
> > viommu_add_resv_mem() does)
> 
> Will take care of all the comments in next verions
> 
> Thank
> -Bharat
> 
> > 
> > > + return 0;
> > > +}
> > > +
> > >  static int viommu_add_resv_mem(struct viommu_endpoint *vdev,
> > >  struct virtio_iommu_probe_resv_mem *mem,
> > >  size_t len)
> > > @@ -494,11 +503,13 @@ static int viommu_probe_endpoint(struct viommu_dev
> > *viommu, struct device *dev)
> > >   while (type != VIRTIO_IOMMU_PROBE_T_NONE &&
> > >  cur < viommu->probe_size) {
> > >   len = le16_to_cpu(prop->length) + sizeof(*prop);
> > > -
> > >   switch (type) {
> > >   case VIRTIO_IOMMU_PROBE_T_RESV_MEM:
> > >   ret = viommu_add_resv_mem(vdev, (void *)prop, len);
> > >   break;
> > > + case VIRTIO_IOMMU_PROBE_T_PAGE_SIZE_MASK:
> > > + ret = viommu_set_pgsize_bitmap(vdev, (void *)prop);
> > > + break;
> > >   default:
> > >   dev_err(dev, "unknown viommu prop 0x%x\n", type);
> > >   }
> > > @@ -607,16 +618,21 @@ static struct iommu_domain
> > *viommu_domain_alloc(unsigned type)
> > >   return >domain;
> > >  }
> > >
> > > -static int viommu_domain_finalise(struct viommu_dev *viommu,
> > > +static int viommu_domain_finalise(struct viommu_endpoint *vdev,
> > > struct iommu_domain *domain)
> > >  {
> > >   int ret;
> > >   struct viommu_domain *vdomain = to_viommu_domain(domain);
> > > + struct viommu_dev *viommu = vdev->viommu;
> > >
> > >   vdomain->viommu = viommu;
> > >   vdomain->map_flags  = viommu->map_flags;
> > >
> > > - domain->pgsize_bitmap   = viommu->pgsize_bitmap;
> > > + if (vdev->pgsize_bitmap)
> > > + domain->pgsize_bitmap = vdev->pgsize_bitmap;
> > > + else
> > > + domain->pgsize_bitmap   = viommu->pgsize_bitmap;
> > > +
> > 
> > nit: it could be nicer to initialize vdev->pgsize_bitmap in add_device(), 
> > override it
> > in probe_endpoint(), and just copy it here.
> > 
> > >   domain->geometry= viommu->geometry;
> > >
> > >   ret = ida_alloc_range(>domain_ids, viommu->first_domain, @@
> > > -657,7 +673,7 @@ static int viommu_attach_dev(struct iommu_domain
> > *domain, struct device *dev)
> > >* Properly initialize the domain now that we know which viommu
> > >* owns it.
> > >*/
> > > - ret = viommu_domain_finalise(vdev->viommu, domain);
> > > + ret = viommu_domain_finalise(vdev, domain);
> > 
> 

Re: [PATCH 1/2] dma-mapping: add a dma_ops_bypass flag to struct device

2020-03-24 Thread Christoph Hellwig
On Tue, Mar 24, 2020 at 12:00:09PM +0530, Aneesh Kumar K.V wrote:
> dma_addr_t dma_direct_map_page(struct device *dev, struct page *page,
>   unsigned long offset, size_t size, enum dma_data_direction dir,
>   unsigned long attrs)
> {
>   phys_addr_t phys = page_to_phys(page) + offset;
>   dma_addr_t dma_addr = phys_to_dma(dev, phys);
> 
>   if (unlikely(!dma_capable(dev, dma_addr, size, true))) {
>   return iommu_map(dev, phys, size, dir, attrs);
> 
>   return DMA_MAPPING_ERROR;

If powerpc hardware / firmware people really come up with crap that
stupid you'll have to handle it yourself and will always pay the
indirect call penality.
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH 1/2] dma-mapping: add a dma_ops_bypass flag to struct device

2020-03-24 Thread Christoph Hellwig
On Tue, Mar 24, 2020 at 02:05:54PM +1100, Alexey Kardashevskiy wrote:
> This is for persistent memory which you can DMA to/from but yet it does
> not appear in the system as a normal memory and therefore requires
> special handling anyway (O_DIRECT or DAX, I do not know the exact
> mechanics). All other devices in the system should just run as usual,
> i.e. use 1:1 mapping if possible.

On other systems (x86 and arm) pmem as long as it is page backed does
not require any special handling.  This must be some weird way powerpc
fucked up again, and I suspect you'll have to suffer from it.
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [PATCH 1/2] dma-mapping: add a dma_ops_bypass flag to struct device

2020-03-24 Thread Christoph Hellwig
On Tue, Mar 24, 2020 at 02:37:59PM +1100, Alexey Kardashevskiy wrote:
> dma_alloc_direct() and dma_map_direct() do the same thing now which is
> good, did I miss anything else?

dma_alloc_direct looks at coherent_dma_mask, dma_map_direct looks
at dma_mask.
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu


Re: [EXT] Re: [PATCH RFC] iommu/virtio: Use page size bitmap supported by endpoint

2020-03-24 Thread Jean-Philippe Brucker
On Mon, Mar 23, 2020 at 06:04:37PM +, Bharat Bhushan wrote:
> > > -static int viommu_domain_finalise(struct viommu_dev *viommu,
> > > +static int viommu_domain_finalise(struct viommu_endpoint *vdev,
> > > struct iommu_domain *domain)
> > >  {
> > >   int ret;
> > >   struct viommu_domain *vdomain = to_viommu_domain(domain);
> > > + struct viommu_dev *viommu = vdev->viommu;
> > >
> > >   vdomain->viommu = viommu;
> > >   vdomain->map_flags  = viommu->map_flags;
> > >
> > > - domain->pgsize_bitmap   = viommu->pgsize_bitmap;
> > > + if (vdev->pgsize_bitmap)
> > > + domain->pgsize_bitmap = vdev->pgsize_bitmap;
> > > + else
> > > + domain->pgsize_bitmap   = viommu->pgsize_bitmap;
> > > +
> > 
> > nit: it could be nicer to initialize vdev->pgsize_bitmap in add_device(),
> 
> To what size we should initialize in add_device, PAGE_SIZE?

No to viommu->pgsize_bitmap

Thanks,
Jean

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


Re: [PATCH 1/2] dma-mapping: add a dma_ops_bypass flag to struct device

2020-03-24 Thread Aneesh Kumar K.V
Alexey Kardashevskiy  writes:

> On 24/03/2020 04:22, Christoph Hellwig wrote:
>> On Mon, Mar 23, 2020 at 09:07:38PM +0530, Aneesh Kumar K.V wrote:
>>>
>>> This is what I was trying, but considering I am new to DMA subsystem, I
>>> am not sure I got all the details correct. The idea is to look at the
>>> cpu addr and see if that can be used in direct map fashion(is
>>> bus_dma_limit the right restriction here?) if not fallback to dynamic
>>> IOMMU mapping.
>> 
>> I don't think we can throw all these complications into the dma
>> mapping code.  At some point I also wonder what the point is,
>> especially for scatterlist mappings, where the iommu can coalesce.
>
> This is for persistent memory which you can DMA to/from but yet it does
> not appear in the system as a normal memory and therefore requires
> special handling anyway (O_DIRECT or DAX, I do not know the exact
> mechanics). All other devices in the system should just run as usual,
> i.e. use 1:1 mapping if possible.

This is O_DIRECT with a user buffer that is actually mmap from a dax
mounted file system.

What we really need is something that will falback to iommu_map_page
based on dma_addr. ie. Something equivalent to current
dma_direct_map_page(), but instead of fallback to swiotlb_map page we
should fallback to iommu_map_page().

Something like?

dma_addr_t dma_direct_map_page(struct device *dev, struct page *page,
unsigned long offset, size_t size, enum dma_data_direction dir,
unsigned long attrs)
{
phys_addr_t phys = page_to_phys(page) + offset;
dma_addr_t dma_addr = phys_to_dma(dev, phys);

if (unlikely(!dma_capable(dev, dma_addr, size, true))) {
return iommu_map(dev, phys, size, dir, attrs);

return DMA_MAPPING_ERROR;
}


...


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