Re: [PATCH v3] of_device: removed #include that caused a recursion in included headers

2020-04-22 Thread kbuild test robot
Hi Hadar,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on sparc/master]
[also build test ERROR on stm32/stm32-next linus/master v5.7-rc2 next-20200422]
[cannot apply to sparc-next/master]
[if your patch is applied to the wrong git tree, please drop us a note to help
improve the system. BTW, we also suggest to use '--base' option to specify the
base tree in git format-patch, please see https://stackoverflow.com/a/37406982]

url:
https://github.com/0day-ci/linux/commits/Hadar-Gat/of_device-removed-include-that-caused-a-recursion-in-included-headers/20200423-040844
base:   https://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc.git master
config: arm64-defconfig (attached as .config)
compiler: aarch64-linux-gcc (GCC) 9.3.0
reproduce:
wget 
https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O 
~/bin/make.cross
chmod +x ~/bin/make.cross
# save the attached .config to linux build tree
COMPILER_INSTALL_PATH=$HOME/0day GCC_VERSION=9.3.0 make.cross 
ARCH=arm64 

If you fix the issue, kindly add following tag as appropriate
Reported-by: kbuild test robot 

All errors (new ones prefixed by >>):

   drivers/firmware/ti_sci.c: In function 'ti_sci_probe':
>> drivers/firmware/ti_sci.c:3520:9: error: implicit declaration of function 
>> 'of_platform_populate' [-Werror=implicit-function-declaration]
3520 |  return of_platform_populate(dev->of_node, NULL, NULL, dev);
 | ^~~~
   drivers/firmware/ti_sci.c: In function 'ti_sci_remove':
>> drivers/firmware/ti_sci.c:3536:2: error: implicit declaration of function 
>> 'of_platform_depopulate' [-Werror=implicit-function-declaration]
3536 |  of_platform_depopulate(dev);
 |  ^~
   cc1: some warnings being treated as errors
--
   drivers/firmware/tegra/bpmp.c: In function 'tegra_bpmp_get':
>> drivers/firmware/tegra/bpmp.c:51:9: error: implicit declaration of function 
>> 'of_find_device_by_node'; did you mean 'bus_find_device_by_fwnode'? 
>> [-Werror=implicit-function-declaration]
  51 |  pdev = of_find_device_by_node(np);
 | ^~
 | bus_find_device_by_fwnode
   drivers/firmware/tegra/bpmp.c:51:7: warning: assignment to 'struct 
platform_device *' from 'int' makes pointer from integer without a cast 
[-Wint-conversion]
  51 |  pdev = of_find_device_by_node(np);
 |   ^
   drivers/firmware/tegra/bpmp.c: In function 'tegra_bpmp_probe':
>> drivers/firmware/tegra/bpmp.c:759:8: error: implicit declaration of function 
>> 'of_platform_default_populate' [-Werror=implicit-function-declaration]
 759 |  err = of_platform_default_populate(pdev->dev.of_node, NULL, 
&pdev->dev);
 |^~~~
   cc1: some warnings being treated as errors
--
   drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c: In function 
'sun8i_dw_hdmi_find_connector_pdev':
>> drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c:115:9: error: implicit declaration of 
>> function 'of_find_device_by_node'; did you mean 
>> 'of_find_i2c_device_by_node'? [-Werror=implicit-function-declaration]
 115 |  pdev = of_find_device_by_node(remote);
 | ^~
 | of_find_i2c_device_by_node
   drivers/gpu/drm/sun4i/sun8i_dw_hdmi.c:115:7: warning: assignment to 'struct 
platform_device *' from 'int' makes pointer from integer without a cast 
[-Wint-conversion]
 115 |  pdev = of_find_device_by_node(remote);
 |   ^
   cc1: some warnings being treated as errors

vim +/of_platform_populate +3520 drivers/firmware/ti_sci.c

aa276781a64a5f Nishanth Menon 2016-10-18  3385  
aa276781a64a5f Nishanth Menon 2016-10-18  3386  static int ti_sci_probe(struct 
platform_device *pdev)
aa276781a64a5f Nishanth Menon 2016-10-18  3387  {
aa276781a64a5f Nishanth Menon 2016-10-18  3388  struct device *dev = 
&pdev->dev;
aa276781a64a5f Nishanth Menon 2016-10-18  3389  const struct 
of_device_id *of_id;
aa276781a64a5f Nishanth Menon 2016-10-18  3390  const struct 
ti_sci_desc *desc;
aa276781a64a5f Nishanth Menon 2016-10-18  3391  struct ti_sci_xfer 
*xfer;
aa276781a64a5f Nishanth Menon 2016-10-18  3392  struct ti_sci_info 
*info = NULL;
aa276781a64a5f Nishanth Menon 2016-10-18  3393  struct 
ti_sci_xfers_info *minfo;
aa276781a64a5f Nishanth Menon 2016-10-18  3394  struct mbox_client *cl;
aa276781a64a5f Nishanth Menon 2016-10-18  3395  int ret = -EINVAL;
aa276781a64a5f Nishanth Menon 2016-10-18  3396  int i;
912cffb4ed8612 Nishanth Menon 2016-10-18  3397  int reboot = 0;
e69a35531589a2 Nishanth Menon 2018-08-28  3398 

Re: [PATCH 0/7] x86: tag application address space for devices

2020-04-22 Thread Fenghua Yu
On Mon, Mar 30, 2020 at 12:33:01PM -0700, Fenghua Yu wrote:
> Typical hardware devices require a driver stack to translate application
> buffers to hardware addresses, and a kernel-user transition to notify the
> hardware of new work. What if both the translation and transition overhead
> could be eliminated? This is what Shared Virtual Address (SVA) and ENQCMD
> enabled hardware like Data Streaming Accelerator (DSA) aims to achieve.
> Applications map portals in their local-address-space and directly submit
> work to them using a new instruction.
> 
Hi, maintainers,

Any comment on this series?

Thanks.

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


Re: [PATCH] iommu/arm-smmu: Demote error messages to debug in shutdown callback

2020-04-22 Thread Doug Anderson
Hi,

On Tue, Mar 31, 2020 at 12:53 AM Sai Prakash Ranjan
 wrote:
>
> Hi Will,
>
> On 2020-03-31 13:14, Will Deacon wrote:
> > On Tue, Mar 31, 2020 at 01:06:11PM +0530, Sai Prakash Ranjan wrote:
> >> On 2020-03-30 23:54, Doug Anderson wrote:
> >> > On Sat, Mar 28, 2020 at 12:35 AM Sai Prakash Ranjan
> >> >  wrote:
> >> > >
> >> > > > Of course the fact that in practice we'll *always* see the warning
> >> > > > because there's no way to tear down the default DMA domains, and even
> >> > > > if all devices *have* been nicely quiesced there's no way to tell, is
> >> > > > certainly less than ideal. Like I say, it's not entirely clear-cut
> >> > > > either way...
> >> > > >
> >> > >
> >> > > Thanks for these examples, good to know these scenarios in case we
> >> > > come
> >> > > across these.
> >> > > However, if we see these error/warning messages appear everytime then
> >> > > what will be
> >> > > the credibility of these messages? We will just ignore these messages
> >> > > when
> >> > > these issues you mention actually appears because we see them
> >> > > everytime
> >> > > on
> >> > > reboot or shutdown.
> >> >
> >> > I would agree that if these messages are expected to be seen every
> >> > time, there's no way to fix them, and they're not indicative of any
> >> > problem then something should be done.  Seeing something printed at
> >> > "dev_error" level with an exclamation point (!) at the end makes me
> >> > feel like this is something that needs immediate action on my part.
> >> >
> >> > If we really can't do better but feel that the messages need to be
> >> > there, at least make them dev_info and less scary like:
> >> >
> >> >   arm-smmu 1500.iommu: turning off; DMA should be quiesced before
> >> > now
> >> >
> >> > ...that would still give you a hint in the logs that if you saw a DMA
> >> > transaction after the message that it was a bug but also wouldn't
> >> > sound scary to someone who wasn't seeing any other problems.
> >> >
> >>
> >> We can do this if Robin is OK?
> >
> > It would be nice if you could figure out which domains are still live
> > when
> > the SMMU is being shut down in your case and verify that it *is* infact
> > benign before we start making the message more friendly. As Robin said
> > earlier, rogue DMA is a real nightmare to debug.
> >
>
> I could see this error message for all the clients of apps_smmu.
> I checked manually enabling bypass and removing iommus dt property
> for each client of apps_smmu.

Any update on the status here?  If I'm reading the conversation above,
Robin said: "we'll *always* see the warning because there's no way to
tear down the default DMA domains, and even if all devices *have* been
nicely quiesced there's no way to tell".  Did I understand that
properly?  If so, it seems like it's fully expected to see this
message on every reboot and it doesn't necessarily signify anything
bad.

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


[PATCH] iommu: Free fwspec with the dev_iommu object

2020-04-22 Thread Jean-Philippe Brucker
Kmemleak reports that iommu_fwspec is leaked during device probe
deferral. For example:

1. The first device probe allocates a dev_iommu and a fwspec, then
   returns with -EPROBE_DEFER (because the IOMMU hasn't been probed
   yet).

2. The IOMMU driver registers the IOMMU on the PCI bus, which calls
   iommu_probe_device(). However at this point the device doesn't have
   IOMMU ops associated, so add_device() fails and iommu_probe_device()
   calls dev_iommu_free(), which leaks the fwspec allocated in 1.

3. The deferred device probe allocates a new dev_iommu and fwspec,
   before calling iommu_probe_device() which succeeds this time.

Fix this leak by freeing the fwspec in dev_iommu_free().

Fixes: 72acd9df18f1 ("iommu: Move iommu_fwspec to struct dev_iommu")
Signed-off-by: Jean-Philippe Brucker 
---
 drivers/iommu/iommu.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index 2b471419e26c3..54757c404866c 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -170,6 +170,7 @@ static struct dev_iommu *dev_iommu_get(struct device *dev)
 
 static void dev_iommu_free(struct device *dev)
 {
+   iommu_fwspec_free(dev);
kfree(dev->iommu);
dev->iommu = NULL;
 }
-- 
2.26.0

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


[PATCH] iommu/amd: Fix legacy interrupt remapping for x2APIC-enabled system

2020-04-22 Thread Suravee Suthikulpanit
Currently, system fails to boot because the legacy interrupt remapping
mode does not enable 128-bit IRTE (GA), which is required for x2APIC
support.

Fix by using AMD_IOMMU_GUEST_IR_LEGACY_GA mode when booting with
kernel option amd_iommu_intr=legacy instead. The initialization
logic will check GASup and automatically fallback to using
AMD_IOMMU_GUEST_IR_LEGACY if GA mode is not supported.

Fixes: 3928aa3f5775 ("iommu/amd: Detect and enable guest vAPIC support")
Signed-off-by: Suravee Suthikulpanit 
---
 drivers/iommu/amd_iommu_init.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/iommu/amd_iommu_init.c b/drivers/iommu/amd_iommu_init.c
index 6be3853..2b9a67e 100644
--- a/drivers/iommu/amd_iommu_init.c
+++ b/drivers/iommu/amd_iommu_init.c
@@ -2936,7 +2936,7 @@ static int __init parse_amd_iommu_intr(char *str)
 {
for (; *str; ++str) {
if (strncmp(str, "legacy", 6) == 0) {
-   amd_iommu_guest_ir = AMD_IOMMU_GUEST_IR_LEGACY;
+   amd_iommu_guest_ir = AMD_IOMMU_GUEST_IR_LEGACY_GA;
break;
}
if (strncmp(str, "vapic", 5) == 0) {
-- 
1.8.3.1

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


Re: [PATCH v3] of_device: removed #include that caused a recursion in included headers

2020-04-22 Thread Liviu Dudau
On Mon, Apr 20, 2020 at 06:04:29PM +0300, Hadar Gat wrote:
> Both of_platform.h and of_device.h were included each other.
> In of_device.h, removed unneeded #include to of_platform.h
> and added include to of_platform.h in the files that needs it.
> 
> Signed-off-by: Hadar Gat 
> Reported-by: kbuild test robot 
> Acked-by: Jonathan Cameron  #for-iio
> Acked-by: Stephen Boyd  # clk
> ---
> v3: add include to of_platform.h in more files. (reported due other builds)
> v2: add include to of_platform.h in more files. (reported due other builds)
> 
>  arch/sparc/kernel/pci.c   | 1 +
>  arch/sparc/kernel/pci_sabre.c | 1 +
>  arch/sparc/kernel/pci_schizo.c| 1 +
>  arch/sparc/kernel/sbus.c  | 1 +
>  arch/sparc/mm/io-unit.c   | 1 +
>  arch/sparc/mm/iommu.c | 1 +
>  drivers/base/platform.c   | 1 +
>  drivers/bus/imx-weim.c| 1 +
>  drivers/bus/vexpress-config.c | 1 +

For drivers/bus/vexpress-config.c:

Acked-by: Liviu Dudau 

Best regards,
Liviu

>  drivers/clk/mediatek/clk-mt7622-aud.c | 1 +
>  drivers/dma/at_hdmac.c| 1 +
>  drivers/dma/stm32-dmamux.c| 1 +
>  drivers/dma/ti/dma-crossbar.c | 1 +
>  drivers/gpu/drm/msm/adreno/a6xx_gmu.c | 1 +
>  drivers/gpu/drm/msm/hdmi/hdmi.c   | 1 +
>  drivers/gpu/drm/msm/msm_drv.c | 1 +
>  drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c   | 1 +
>  drivers/gpu/drm/sun4i/sun4i_tcon.c| 1 +
>  drivers/iio/adc/stm32-adc-core.c  | 1 +
>  drivers/iio/adc/stm32-dfsdm-adc.c | 1 +
>  drivers/iio/adc/stm32-dfsdm-core.c| 1 +
>  drivers/iommu/tegra-smmu.c| 1 +
>  drivers/media/platform/coda/coda-common.c | 1 +
>  drivers/memory/atmel-ebi.c| 1 +
>  drivers/mfd/palmas.c  | 1 +
>  drivers/mfd/ssbi.c| 1 +
>  drivers/mtd/nand/raw/omap2.c  | 1 +
>  drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c | 1 +
>  drivers/net/ethernet/ti/cpsw.c| 1 +
>  drivers/phy/tegra/xusb.c  | 1 +
>  drivers/pinctrl/freescale/pinctrl-imx1-core.c | 1 +
>  drivers/pinctrl/nomadik/pinctrl-nomadik.c | 1 +
>  drivers/soc/samsung/exynos-pmu.c  | 1 +
>  drivers/soc/sunxi/sunxi_sram.c| 1 +
>  include/linux/of_device.h | 2 --
>  lib/genalloc.c| 1 +
>  36 files changed, 35 insertions(+), 2 deletions(-)
> 
> diff --git a/arch/sparc/kernel/pci.c b/arch/sparc/kernel/pci.c
> index 5ed4382..89ea658 100644
> --- a/arch/sparc/kernel/pci.c
> +++ b/arch/sparc/kernel/pci.c
> @@ -21,6 +21,7 @@
>  #include 
>  #include 
>  #include 
> +#include 
>  
>  #include 
>  #include 
> diff --git a/arch/sparc/kernel/pci_sabre.c b/arch/sparc/kernel/pci_sabre.c
> index 3c38ca4..16761d0 100644
> --- a/arch/sparc/kernel/pci_sabre.c
> +++ b/arch/sparc/kernel/pci_sabre.c
> @@ -14,6 +14,7 @@
>  #include 
>  #include 
>  #include 
> +#include 
>  
>  #include 
>  #include 
> diff --git a/arch/sparc/kernel/pci_schizo.c b/arch/sparc/kernel/pci_schizo.c
> index 421aba0..733f069 100644
> --- a/arch/sparc/kernel/pci_schizo.c
> +++ b/arch/sparc/kernel/pci_schizo.c
> @@ -12,6 +12,7 @@
>  #include 
>  #include 
>  #include 
> +#include 
>  #include 
>  
>  #include 
> diff --git a/arch/sparc/kernel/sbus.c b/arch/sparc/kernel/sbus.c
> index 32141e1..2f4051f 100644
> --- a/arch/sparc/kernel/sbus.c
> +++ b/arch/sparc/kernel/sbus.c
> @@ -15,6 +15,7 @@
>  #include 
>  #include 
>  #include 
> +#include 
>  #include 
>  
>  #include 
> diff --git a/arch/sparc/mm/io-unit.c b/arch/sparc/mm/io-unit.c
> index 289276b..5638399 100644
> --- a/arch/sparc/mm/io-unit.c
> +++ b/arch/sparc/mm/io-unit.c
> @@ -15,6 +15,7 @@
>  #include 
>  #include 
>  #include 
> +#include 
>  
>  #include 
>  #include 
> diff --git a/arch/sparc/mm/iommu.c b/arch/sparc/mm/iommu.c
> index b00dde1..9cbb2e7 100644
> --- a/arch/sparc/mm/iommu.c
> +++ b/arch/sparc/mm/iommu.c
> @@ -16,6 +16,7 @@
>  #include 
>  #include 
>  #include 
> +#include 
>  
>  #include 
>  #include 
> diff --git a/drivers/base/platform.c b/drivers/base/platform.c
> index 520..f549274b 100644
> --- a/drivers/base/platform.c
> +++ b/drivers/base/platform.c
> @@ -12,6 +12,7 @@
>  #include 
>  #include 
>  #include 
> +#include 
>  #include 
>  #include 
>  #include 
> diff --git a/drivers/bus/imx-weim.c b/drivers/bus/imx-weim.c
> index 28bb65a..8c786da 100644
> --- a/drivers/bus/imx-weim.c
> +++ b/drivers/bus/imx-weim.c
> @@ -11,6 +11,7 @@
>  #include 
>  #include 
>  #include 
> +#include 
>  #include 
>  #include 
>  #include 
> diff --git a/driv

[PATCH v3 4/4] iommu/vt-d: Remove redundant IOTLB flush

2020-04-22 Thread Lu Baolu
IOTLB flush already included in the PASID tear down and the page request
drain process. There is no need to flush again.

Signed-off-by: Jacob Pan 
Signed-off-by: Lu Baolu 
---
 drivers/iommu/intel-svm.c | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/drivers/iommu/intel-svm.c b/drivers/iommu/intel-svm.c
index 2534641ef707..543109fe2003 100644
--- a/drivers/iommu/intel-svm.c
+++ b/drivers/iommu/intel-svm.c
@@ -212,7 +212,6 @@ static void intel_mm_release(struct mmu_notifier *mn, 
struct mm_struct *mm)
list_for_each_entry_rcu(sdev, &svm->devs, list) {
intel_pasid_tear_down_entry(svm->iommu, sdev->dev, svm->pasid);
intel_svm_drain_prq(sdev->dev, svm->pasid);
-   intel_flush_svm_range_dev(svm, sdev, 0, -1, 0);
}
rcu_read_unlock();
 
@@ -406,7 +405,6 @@ int intel_svm_unbind_gpasid(struct device *dev, int pasid)
list_del_rcu(&sdev->list);
intel_pasid_tear_down_entry(iommu, dev, svm->pasid);
intel_svm_drain_prq(dev, svm->pasid);
-   intel_flush_svm_range_dev(svm, sdev, 0, -1, 0);
kfree_rcu(sdev, rcu);
 
if (list_empty(&svm->devs)) {
@@ -645,7 +643,6 @@ int intel_svm_unbind_mm(struct device *dev, int pasid)
 * hard to be as defensive as we might like. */
intel_pasid_tear_down_entry(iommu, dev, svm->pasid);
intel_svm_drain_prq(dev, svm->pasid);
-   intel_flush_svm_range_dev(svm, sdev, 0, -1, 0);
kfree_rcu(sdev, rcu);
 
if (list_empty(&svm->devs)) {
-- 
2.17.1

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


[PATCH v3 1/4] iommu/vt-d: Multiple descriptors per qi_submit_sync()

2020-04-22 Thread Lu Baolu
Current qi_submit_sync() only supports single invalidation descriptor
per submission and appends wait descriptor after each submission to
poll the hardware completion. This extends the qi_submit_sync() helper
to support multiple descriptors, and add an option so that the caller
could specify the Page-request Drain (PD) bit in the wait descriptor.

Signed-off-by: Jacob Pan 
Signed-off-by: Lu Baolu 
---
 drivers/iommu/dmar.c| 63 +
 drivers/iommu/intel-pasid.c |  4 +-
 drivers/iommu/intel-svm.c   |  6 +--
 drivers/iommu/intel_irq_remapping.c |  2 +-
 include/linux/intel-iommu.h |  9 -
 5 files changed, 52 insertions(+), 32 deletions(-)

diff --git a/drivers/iommu/dmar.c b/drivers/iommu/dmar.c
index d9dc787feef7..61d049e91f84 100644
--- a/drivers/iommu/dmar.c
+++ b/drivers/iommu/dmar.c
@@ -1157,12 +1157,11 @@ static inline void reclaim_free_desc(struct q_inval *qi)
}
 }
 
-static int qi_check_fault(struct intel_iommu *iommu, int index)
+static int qi_check_fault(struct intel_iommu *iommu, int index, int wait_index)
 {
u32 fault;
int head, tail;
struct q_inval *qi = iommu->qi;
-   int wait_index = (index + 1) % QI_LENGTH;
int shift = qi_shift(iommu);
 
if (qi->desc_status[wait_index] == QI_ABORT)
@@ -1225,17 +1224,21 @@ static int qi_check_fault(struct intel_iommu *iommu, 
int index)
 }
 
 /*
- * Submit the queued invalidation descriptor to the remapping
- * hardware unit and wait for its completion.
+ * Function to submit invalidation descriptors of all types to the queued
+ * invalidation interface(QI). Multiple descriptors can be submitted at a
+ * time, a wait descriptor will be appended to each submission to ensure
+ * hardware has completed the invalidation before return. Wait descriptors
+ * can be part of the submission but it will not be polled for completion.
  */
-int qi_submit_sync(struct qi_desc *desc, struct intel_iommu *iommu)
+int qi_submit_sync(struct intel_iommu *iommu, struct qi_desc *desc,
+  unsigned int count, unsigned long options)
 {
-   int rc;
struct q_inval *qi = iommu->qi;
-   int offset, shift, length;
struct qi_desc wait_desc;
int wait_index, index;
unsigned long flags;
+   int offset, shift;
+   int rc, i;
 
if (!qi)
return 0;
@@ -1244,32 +1247,41 @@ int qi_submit_sync(struct qi_desc *desc, struct 
intel_iommu *iommu)
rc = 0;
 
raw_spin_lock_irqsave(&qi->q_lock, flags);
-   while (qi->free_cnt < 3) {
+   /*
+* Check if we have enough empty slots in the queue to submit,
+* the calculation is based on:
+* # of desc + 1 wait desc + 1 space between head and tail
+*/
+   while (qi->free_cnt < count + 2) {
raw_spin_unlock_irqrestore(&qi->q_lock, flags);
cpu_relax();
raw_spin_lock_irqsave(&qi->q_lock, flags);
}
 
index = qi->free_head;
-   wait_index = (index + 1) % QI_LENGTH;
+   wait_index = (index + count) % QI_LENGTH;
shift = qi_shift(iommu);
-   length = 1 << shift;
 
-   qi->desc_status[index] = qi->desc_status[wait_index] = QI_IN_USE;
+   for (i = 0; i < count; i++) {
+   offset = ((index + i) % QI_LENGTH) << shift;
+   memcpy(qi->desc + offset, &desc[i], 1 << shift);
+   qi->desc_status[(index + i) % QI_LENGTH] = QI_IN_USE;
+   }
+   qi->desc_status[wait_index] = QI_IN_USE;
 
-   offset = index << shift;
-   memcpy(qi->desc + offset, desc, length);
wait_desc.qw0 = QI_IWD_STATUS_DATA(QI_DONE) |
QI_IWD_STATUS_WRITE | QI_IWD_TYPE;
+   if (options & QI_OPT_WAIT_DRAIN)
+   wait_desc.qw0 |= QI_IWD_PRQ_DRAIN;
wait_desc.qw1 = virt_to_phys(&qi->desc_status[wait_index]);
wait_desc.qw2 = 0;
wait_desc.qw3 = 0;
 
offset = wait_index << shift;
-   memcpy(qi->desc + offset, &wait_desc, length);
+   memcpy(qi->desc + offset, &wait_desc, 1 << shift);
 
-   qi->free_head = (qi->free_head + 2) % QI_LENGTH;
-   qi->free_cnt -= 2;
+   qi->free_head = (qi->free_head + count + 1) % QI_LENGTH;
+   qi->free_cnt -= count + 1;
 
/*
 * update the HW tail register indicating the presence of
@@ -1285,7 +1297,7 @@ int qi_submit_sync(struct qi_desc *desc, struct 
intel_iommu *iommu)
 * a deadlock where the interrupt context can wait indefinitely
 * for free slots in the queue.
 */
-   rc = qi_check_fault(iommu, index);
+   rc = qi_check_fault(iommu, index, wait_index);
if (rc)
break;
 
@@ -1294,7 +1306,8 @@ int qi_submit_sync(struct qi_desc *desc, struct 
intel_iommu *iommu)
raw_spin_lock(&qi->q_lock);
}
 
-   qi->desc_status[index] = QI_DONE;
+   

[PATCH v3 3/4] iommu/vt-d: Add page request draining support

2020-04-22 Thread Lu Baolu
When a PASID is stopped or terminated, there can be pending PRQs
(requests that haven't received responses) in remapping hardware.
This adds the interface to drain page requests and call it when a
PASID is terminated.

Signed-off-by: Jacob Pan 
Signed-off-by: Liu Yi L 
Signed-off-by: Lu Baolu 
---
 drivers/iommu/intel-svm.c   | 103 ++--
 include/linux/intel-iommu.h |   4 ++
 2 files changed, 102 insertions(+), 5 deletions(-)

diff --git a/drivers/iommu/intel-svm.c b/drivers/iommu/intel-svm.c
index 83dc4319f661..2534641ef707 100644
--- a/drivers/iommu/intel-svm.c
+++ b/drivers/iommu/intel-svm.c
@@ -23,6 +23,7 @@
 #include "intel-pasid.h"
 
 static irqreturn_t prq_event_thread(int irq, void *d);
+static void intel_svm_drain_prq(struct device *dev, int pasid);
 
 #define PRQ_ORDER 0
 
@@ -66,6 +67,8 @@ int intel_svm_enable_prq(struct intel_iommu *iommu)
dmar_writeq(iommu->reg + DMAR_PQT_REG, 0ULL);
dmar_writeq(iommu->reg + DMAR_PQA_REG, virt_to_phys(iommu->prq) | 
PRQ_ORDER);
 
+   init_completion(&iommu->prq_complete);
+
return 0;
 }
 
@@ -208,6 +211,7 @@ static void intel_mm_release(struct mmu_notifier *mn, 
struct mm_struct *mm)
rcu_read_lock();
list_for_each_entry_rcu(sdev, &svm->devs, list) {
intel_pasid_tear_down_entry(svm->iommu, sdev->dev, svm->pasid);
+   intel_svm_drain_prq(sdev->dev, svm->pasid);
intel_flush_svm_range_dev(svm, sdev, 0, -1, 0);
}
rcu_read_unlock();
@@ -401,12 +405,8 @@ int intel_svm_unbind_gpasid(struct device *dev, int pasid)
if (!sdev->users) {
list_del_rcu(&sdev->list);
intel_pasid_tear_down_entry(iommu, dev, svm->pasid);
+   intel_svm_drain_prq(dev, svm->pasid);
intel_flush_svm_range_dev(svm, sdev, 0, -1, 0);
-   /* TODO: Drain in flight PRQ for the PASID since it
-* may get reused soon, we don't want to
-* confuse with its previous life.
-* intel_svm_drain_prq(dev, pasid);
-*/
kfree_rcu(sdev, rcu);
 
if (list_empty(&svm->devs)) {
@@ -644,6 +644,7 @@ 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_svm_drain_prq(dev, svm->pasid);
intel_flush_svm_range_dev(svm, sdev, 0, -1, 0);
kfree_rcu(sdev, rcu);
 
@@ -722,6 +723,92 @@ static bool is_canonical_address(u64 addr)
return (((saddr << shift) >> shift) == saddr);
 }
 
+/**
+ * intel_svm_drain_prq:
+ *
+ * Drain all pending page requests and responses related to a specific
+ * pasid in both software and hardware.
+ */
+static void intel_svm_drain_prq(struct device *dev, int pasid)
+{
+   struct device_domain_info *info;
+   struct dmar_domain *domain;
+   struct intel_iommu *iommu;
+   struct qi_desc desc[3];
+   struct pci_dev *pdev;
+   int head, tail;
+   u16 sid, did;
+   int qdep;
+
+   info = get_domain_info(dev);
+   if (WARN_ON(!info || !dev_is_pci(dev)))
+   return;
+
+   if (!info->ats_enabled)
+   return;
+
+   iommu = info->iommu;
+   domain = info->domain;
+   pdev = to_pci_dev(dev);
+   sid = PCI_DEVID(info->bus, info->devfn);
+   did = domain->iommu_did[iommu->seq_id];
+   qdep = pci_ats_queue_depth(pdev);
+
+   memset(desc, 0, sizeof(desc));
+   desc[0].qw0 = QI_IWD_STATUS_DATA(QI_DONE) |
+   QI_IWD_FENCE |
+   QI_IWD_TYPE;
+   desc[1].qw0 = QI_EIOTLB_PASID(pasid) |
+   QI_EIOTLB_DID(did) |
+   QI_EIOTLB_GRAN(QI_GRAN_NONG_PASID) |
+   QI_EIOTLB_TYPE;
+   desc[2].qw0 = QI_DEV_EIOTLB_PASID(pasid) |
+   QI_DEV_EIOTLB_SID(sid) |
+   QI_DEV_EIOTLB_QDEP(qdep) |
+   QI_DEIOTLB_TYPE |
+   QI_DEV_IOTLB_PFSID(info->pfsid);
+
+   /*
+* Submit an invalidation wait descriptor with fence and page request
+* drain flags set to invalidation queue. This ensures that all requests
+* submitted to the invalidation queue ahead of this wait descriptor are
+* processed and completed, and all already issued page requests from
+* the device are put in the page request queue.
+*/
+   qi_submit_sync(iommu, desc, 1, QI_OPT_WAIT_DRAIN);
+
+   /*
+* Check and wait until all pending page requests in the queue are
+* handled by the intr thread.
+*/
+prq_retry:
+   tai

[PATCH v3 0/4] iommu/vt-d: Add page request draining support

2020-04-22 Thread Lu Baolu
When a PASID is stopped or terminated, there can be pending PRQs
(requests that haven't received responses) in the software and
remapping hardware. The pending page requests must be drained
so that the pasid could be reused. The chapter 7.10 in the VT-d
specification specifies the software steps to drain pending page
requests and responses.

This includes two parts:
 - PATCH 1/4 ~ 2/4: refactor the qi_submit_sync() to support multiple
   descriptors per submission which will be used in the following
   patch.
 - PATCH 3/4 ~ 4/4: add page request drain support after a pasid entry
   is torn down.

Please help to review.

Best regards,
baolu

Change log:
 v2->v3:
  - Address Kevin's review comments
- Squash the first 2 patches together;
- The prq thread is serialized, no need to consider reentrance;
- Ensure no new-coming prq before drain prq in queue;
- Handle page request overflow case.

 v1->v2:
  - Fix race between multiple prq handling threads.


Lu Baolu (4):
  iommu/vt-d: Multiple descriptors per qi_submit_sync()
  iommu/vt-d: debugfs: Add support to show inv queue internals
  iommu/vt-d: Add page request draining support
  iommu/vt-d: Remove redundant IOTLB flush

 drivers/iommu/dmar.c|  63 +---
 drivers/iommu/intel-iommu-debugfs.c |  62 +++
 drivers/iommu/intel-pasid.c |   4 +-
 drivers/iommu/intel-svm.c   | 112 +---
 drivers/iommu/intel_irq_remapping.c |   2 +-
 include/linux/intel-iommu.h |  13 +++-
 6 files changed, 216 insertions(+), 40 deletions(-)

-- 
2.17.1

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


[PATCH v3 2/4] iommu/vt-d: debugfs: Add support to show inv queue internals

2020-04-22 Thread Lu Baolu
Export invalidation queue internals of each iommu device through the
debugfs.

Example of such dump on a Skylake machine:

$ sudo cat /sys/kernel/debug/iommu/intel/invalidation_queue
Invalidation queue on IOMMU: dmar1
 Base: 0x1672c9000  Head: 80Tail: 80
Index   qw0 qw1 status
0   0004
1   000200250001672be804
2   0011
3   000200250001672be80c
4   00d2
5   000200250001672be814
6   0014
7   000200250001672be81c
8   0014
9   000200250001672be824

Signed-off-by: Lu Baolu 
---
 drivers/iommu/intel-iommu-debugfs.c | 62 +
 1 file changed, 62 insertions(+)

diff --git a/drivers/iommu/intel-iommu-debugfs.c 
b/drivers/iommu/intel-iommu-debugfs.c
index 3eb1fe240fb0..e3089865b8f3 100644
--- a/drivers/iommu/intel-iommu-debugfs.c
+++ b/drivers/iommu/intel-iommu-debugfs.c
@@ -372,6 +372,66 @@ static int domain_translation_struct_show(struct seq_file 
*m, void *unused)
 }
 DEFINE_SHOW_ATTRIBUTE(domain_translation_struct);
 
+static void invalidation_queue_entry_show(struct seq_file *m,
+ struct intel_iommu *iommu)
+{
+   int index, shift = qi_shift(iommu);
+   struct qi_desc *desc;
+   int offset;
+
+   if (ecap_smts(iommu->ecap))
+   seq_puts(m, 
"Index\t\tqw0\t\t\tqw1\t\t\tqw2\t\t\tqw3\t\t\tstatus\n");
+   else
+   seq_puts(m, "Index\t\tqw0\t\t\tqw1\t\t\tstatus\n");
+
+   for (index = 0; index < QI_LENGTH; index++) {
+   offset = index << shift;
+   desc = iommu->qi->desc + offset;
+   if (ecap_smts(iommu->ecap))
+   seq_printf(m, 
"%5d\t%016llx\t%016llx\t%016llx\t%016llx\t%016x\n",
+  index, desc->qw0, desc->qw1,
+  desc->qw2, desc->qw3,
+  iommu->qi->desc_status[index]);
+   else
+   seq_printf(m, "%5d\t%016llx\t%016llx\t%016x\n",
+  index, desc->qw0, desc->qw1,
+  iommu->qi->desc_status[index]);
+   }
+}
+
+static int invalidation_queue_show(struct seq_file *m, void *unused)
+{
+   struct dmar_drhd_unit *drhd;
+   struct intel_iommu *iommu;
+   unsigned long flags;
+   struct q_inval *qi;
+   int shift;
+
+   rcu_read_lock();
+   for_each_active_iommu(iommu, drhd) {
+   qi = iommu->qi;
+   shift = qi_shift(iommu);
+
+   if (!qi || !ecap_qis(iommu->ecap))
+   continue;
+
+   seq_printf(m, "Invalidation queue on IOMMU: %s\n", iommu->name);
+
+   raw_spin_lock_irqsave(&qi->q_lock, flags);
+   seq_printf(m, " Base: 0x%llx\tHead: %lld\tTail: %lld\n",
+  virt_to_phys(qi->desc),
+  dmar_readq(iommu->reg + DMAR_IQH_REG) >> shift,
+  dmar_readq(iommu->reg + DMAR_IQT_REG) >> shift);
+   invalidation_queue_entry_show(m, iommu);
+   raw_spin_unlock_irqrestore(&qi->q_lock, flags);
+   seq_putc(m, '\n');
+   }
+   rcu_read_unlock();
+
+   return 0;
+}
+DEFINE_SHOW_ATTRIBUTE(invalidation_queue);
+
 #ifdef CONFIG_IRQ_REMAP
 static void ir_tbl_remap_entry_show(struct seq_file *m,
struct intel_iommu *iommu)
@@ -490,6 +550,8 @@ void __init intel_iommu_debugfs_init(void)
debugfs_create_file("domain_translation_struct", 0444,
intel_iommu_debug, NULL,
&domain_translation_struct_fops);
+   debugfs_create_file("invalidation_queue", 0444, intel_iommu_debug,
+   NULL, &invalidation_queue_fops);
 #ifdef CONFIG_IRQ_REMAP
debugfs_create_file("ir_translation_struct", 0444, intel_iommu_debug,
NULL, &ir_translation_struct_fops);
-- 
2.17.1

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