Re: swiotlb-xen cleanups

2019-08-26 Thread Stefano Stabellini
On Fri, 16 Aug 2019, Christoph Hellwig wrote:
> Hi Xen maintainers and friends,
> 
> please take a look at this series that cleans up the parts of swiotlb-xen
> that deal with non-coherent caches.

Hi Christoph,

I just wanted to let you know that your series is on my radar, but I
have been swamped the last few days. I hope to get to it by the end of
the week.

Cheers,

Stefano


[PATCH 0/2] OMAP IOMMU fixes to go with 5.4 OMAP IOMMU changes

2019-08-26 Thread Suman Anna via iommu
Hi Tony,

The following 2 patches need to go along with the recent "iommu/omap: misc
fixes" series [1] that is currently staged [2] for a 5.4 merge and available
in linux-next. That series added runtime pm callbacks in preparation for
the ti-sysc migration, but without adding the necessary platform data
callbacks for the existing functional MMUs on OMAP3, OMAP4 and OMAP5 SoCs.
These 2 patches add the same to maintain the functionality (l3_noc errors
are the visible symptom while enabling the MMUs without these patches).

OMAP4 and OMAP5 would also need another set of fixes related to the
breakage caused by the switch to clkctrl clocks as seen in [3].

These patches do have a dependency on the staged patches, so either you
submit a pull-request towards 5.4-rc2 using 5.4-rc1 baseline, or let
Joerg pick these through the arm/omap IOMMU branch for 5.4-rc1 itself.

Sakari/Laurent,
Appreciate it if you can check the OMAP3 ISP functionality on latest
linux-next with the second patch. I have verified the ISP MMU programming
only through an unit-test.

Tero,
I will be submitting another patch against OMAP IOMMU driver to skip the
pdata callbacks for ti-sysc in the next couple of days.

regards
Suman

[1] 
https://lore.kernel.org/linux-iommu/20190809153730.gf12...@8bytes.org/T/#mec99f8e8ed351689f4fcc76f4f000f9144a02b51
[2] 
https://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu.git/log/?h=arm/omap
[3] https://patchwork.kernel.org/patch/11082125/#22829477

Suman Anna (2):
  ARM: OMAP2+: Plug in device_enable/idle ops for IOMMUs
  ARM: OMAP2+: Add pdata for OMAP3 ISP IOMMU

 arch/arm/mach-omap2/pdata-quirks.c | 11 +++
 1 file changed, 11 insertions(+)

-- 
2.22.0

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


[PATCH 1/2] ARM: OMAP2+: Plug in device_enable/idle ops for IOMMUs

2019-08-26 Thread Suman Anna via iommu
The OMAP IOMMU driver requires the device_enable/idle platform
data ops on all the IOMMU devices to be able to enable and disable
the clocks after commit db8918f61d51 ("iommu/omap: streamline
enable/disable through runtime pm callbacks"). Plug in these
pdata ops for all the existing IOMMUs through pdata quirks to
maintain functionality.

Signed-off-by: Suman Anna 
---
 arch/arm/mach-omap2/pdata-quirks.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/arch/arm/mach-omap2/pdata-quirks.c 
b/arch/arm/mach-omap2/pdata-quirks.c
index 6c6f8fce854e..dbe8d9718f70 100644
--- a/arch/arm/mach-omap2/pdata-quirks.c
+++ b/arch/arm/mach-omap2/pdata-quirks.c
@@ -89,6 +89,8 @@ static struct iommu_platform_data omap3_iommu_pdata = {
.reset_name = "mmu",
.assert_reset = omap_device_assert_hardreset,
.deassert_reset = omap_device_deassert_hardreset,
+   .device_enable = omap_device_enable,
+   .device_idle = omap_device_idle,
 };
 
 static int omap3_sbc_t3730_twl_callback(struct device *dev,
@@ -424,6 +426,8 @@ static struct iommu_platform_data omap4_iommu_pdata = {
.reset_name = "mmu_cache",
.assert_reset = omap_device_assert_hardreset,
.deassert_reset = omap_device_deassert_hardreset,
+   .device_enable = omap_device_enable,
+   .device_idle = omap_device_idle,
 };
 #endif
 
-- 
2.22.0

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


[PATCH 2/2] ARM: OMAP2+: Add pdata for OMAP3 ISP IOMMU

2019-08-26 Thread Suman Anna via iommu
The OMAP3 ISP IOMMU does not have any reset lines, so it didn't
need any pdata previously. The OMAP IOMMU driver now requires the
platform data ops for device_enable/idle on all the IOMMU devices
after commit db8918f61d51 ("iommu/omap: streamline enable/disable
through runtime pm callbacks") to enable/disable the clocks properly
and maintain the reference count and the omap_hwmod state machine.
So, add these callbacks through iommu pdata quirks for the OMAP3
ISP IOMMU.

Signed-off-by: Suman Anna 
---
 arch/arm/mach-omap2/pdata-quirks.c | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/arch/arm/mach-omap2/pdata-quirks.c 
b/arch/arm/mach-omap2/pdata-quirks.c
index dbe8d9718f70..3d597fb962e9 100644
--- a/arch/arm/mach-omap2/pdata-quirks.c
+++ b/arch/arm/mach-omap2/pdata-quirks.c
@@ -93,6 +93,11 @@ static struct iommu_platform_data omap3_iommu_pdata = {
.device_idle = omap_device_idle,
 };
 
+static struct iommu_platform_data omap3_iommu_isp_pdata = {
+   .device_enable = omap_device_enable,
+   .device_idle = omap_device_idle,
+};
+
 static int omap3_sbc_t3730_twl_callback(struct device *dev,
   unsigned gpio,
   unsigned ngpio)
@@ -621,6 +626,8 @@ static struct of_dev_auxdata omap_auxdata_lookup[] = {
 #ifdef CONFIG_ARCH_OMAP3
OF_DEV_AUXDATA("ti,omap2-iommu", 0x5d00, "5d00.mmu",
   _iommu_pdata),
+   OF_DEV_AUXDATA("ti,omap2-iommu", 0x480bd400, "480bd400.mmu",
+  _iommu_isp_pdata),
OF_DEV_AUXDATA("ti,omap3-smartreflex-core", 0x480cb000,
   "480cb000.smartreflex", _sr_pdata[OMAP_SR_CORE]),
OF_DEV_AUXDATA("ti,omap3-smartreflex-mpu-iva", 0x480c9000,
-- 
2.22.0

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


RE: [RFC PATCH] virtio_ring: Use DMA API if guest memory is encrypted

2019-08-26 Thread Ram Pai
On Tue, Aug 13, 2019 at 08:45:37AM -0700, Ram Pai wrote:
> On Wed, Aug 14, 2019 at 12:24:39AM +1000, David Gibson wrote:
> > On Tue, Aug 13, 2019 at 03:26:17PM +0200, Christoph Hellwig wrote:
> > > On Mon, Aug 12, 2019 at 07:51:56PM +1000, David Gibson wrote:
> > > > AFAICT we already kind of abuse this for the VIRTIO_F_IOMMU_PLATFORM,
> > > > because to handle for cases where it *is* a device limitation, we
> > > > assume that if the hypervisor presents VIRTIO_F_IOMMU_PLATFORM then
> > > > the guest *must* select it.
> > > > 
> > > > What we actually need here is for the hypervisor to present
> > > > VIRTIO_F_IOMMU_PLATFORM as available, but not required.  Then we need
> > > > a way for the platform core code to communicate to the virtio driver
> > > > that *it* requires the IOMMU to be used, so that the driver can select
> > > > or not the feature bit on that basis.
> > > 
> > > I agree with the above, but that just brings us back to the original
> > > issue - the whole bypass of the DMA OPS should be an option that the
> > > device can offer, not the other way around.  And we really need to
> > > fix that root cause instead of doctoring around it.
> > 
> > I'm not exactly sure what you mean by "device" in this context.  Do
> > you mean the hypervisor (qemu) side implementation?
> > 
> > You're right that this was the wrong way around to begin with, but as
> > well as being hard to change now, I don't see how it really addresses
> > the current problem.  The device could default to IOMMU and allow
> > bypass, but the driver would still need to get information from the
> > platform to know that it *can't* accept that option in the case of a
> > secure VM.  Reversed sense, but the same basic problem.
> > 
> > The hypervisor does not, and can not be aware of the secure VM
> > restrictions - only the guest side platform code knows that.
> 
> This statement is almost entirely right. I will rephrase it to make it
> entirely right.   
> 
> The hypervisor does not, and can not be aware of the secure VM
> requirement that it needs to do some special processing that has nothing
> to do with DMA address translation - only the guest side platform code
> know that.
> 
> BTW: I do not consider 'bounce buffering' as 'DMA address translation'.
> DMA address translation, translates CPU address to DMA address.  Bounce
> buffering moves the data from one buffer at a given CPU address to
> another buffer at a different CPU address.  Unfortunately the current
> DMA ops conflates the two.  The need to do 'DMA address translation' 
> is something the device can enforce.  But the need to do bounce
> buffering, is something that the device should not be aware and should be
> entirely a decision made locally by the kernel/driver in the secure VM.


Christoph,

Since we have not heard back from you, I am not sure where you
stand on this issue now.   One of the three things are
possible..

(a) our above explaination did not make sense and hence
you decided to ignore it.
(b) our above above made some sense and need more time to think 
and respond.
(c) you totally forgot about this.


I hope it is (b). We want a solution that works for all, and your inputs 
are important to us.


Thanks,
RP



Re: [PATCH v5 00/19] Shared virtual address IOMMU and VT-d support

2019-08-26 Thread Jacob Pan
Hi Joerg and all,

Just wondering if you have more comments for this version. Since
the complete vSVA patchset is quite large, my hope is that we can make
incremental progress with smaller sets.

My plans are:
1. vSVA IOMMU APIs and VT-d support of PCI devices (this patchset)
2. Page request service
3. mdev support
4. code merge with Jean's generic sva_bind() APIs

For this set, we don't need PRS related patches (1-4). I included
them because they are in Jean's common API repo. Could you review 5-19
and consider for v5.4? This will make further submissions much easier.

Thanks,

Jacob

On Thu, 15 Aug 2019 13:13:06 -0700
Jacob Pan  wrote:

> Shared virtual address (SVA), a.k.a, Shared virtual memory (SVM) on
> Intel platforms allow address space sharing between device DMA and
> applications. SVA can reduce programming complexity and enhance
> security. This series is intended to enable SVA virtualization, i.e.
> shared guest application address space and physical device DMA
> address. Only IOMMU portion of the changes are included in this
> series. Additional support is needed in VFIO and QEMU (will be
> submitted separately) to complete this functionality.
> 
> To make incremental changes and reduce the size of each patchset.
> This series does not inlcude support for page request services.
> 
> In VT-d implementation, PASID table is per device and maintained in
> the host. Guest PASID table is shadowed in VMM where virtual IOMMU is
> emulated.
> 
> .-.  .---.
> |   vIOMMU|  | Guest process CR3, FL only|
> | |  '---'
> ./
> | PASID Entry |--- PASID cache flush -
> '-'   |
> | |   V
> | |CR3 in GPA
> '-'
> Guest
> --| Shadow |--|
>   vv  v
> Host
> .-.  .--.
> |   pIOMMU|  | Bind FL for GVA-GPA  |
> | |  '--'
> ./  |
> | PASID Entry | V (Nested xlate)
> '\.--.
> | |   |SL for GPA-HPA, default domain|
> | |   '--'
> '-'
> Where:
>  - FL = First level/stage one page tables
>  - SL = Second level/stage two page tables
> 
> 
> This work is based on collaboration with other developers on the IOMMU
> mailing list. Notably,
> 
> [1] Common APIs git://linux-arm.org/linux-jpb.git sva/api
> 
> [2] [RFC PATCH 2/6] drivers core: Add I/O ASID allocator by
> Jean-Philippe Brucker
> https://www.spinics.net/lists/iommu/msg30639.html
> 
> [3] [RFC PATCH 0/5] iommu: APIs for paravirtual PASID allocation by
> Lu Baolu https://lkml.org/lkml/2018/11/12/1921
> 
> [4] [PATCH v5 00/23] IOMMU and VT-d driver support for Shared Virtual
> Address (SVA)
> https://lwn.net/Articles/754331/
> 
> There are roughly three parts:
> 1. Generic PASID allocator [1] with extension to support custom
> allocator 2. IOMMU cache invalidation passdown from guest to host
> 3. Guest PASID bind for nested translation
> 
> All generic IOMMU APIs are reused from [1] with minor tweaks. With
> this patchset, guest SVA without page request works on VT-d. PRS
> patches will come next as we try to avoid large patchset that is hard
> to review. The patches for basic SVA support (w/o PRS) starts:
> [PATCH v5 05/19] iommu: Introduce attach/detach_pasid_table API
> 
> It is worth noting that unlike sMMU nested stage setup, where PASID
> table is owned by the guest, VT-d PASID table is owned by the host,
> individual PASIDs are bound instead of the PASID table.
> 
> This series is based on the new VT-d 3.0 Specification
> (https://software.intel.com/sites/default/files/managed/c5/15/vt-directed-io-spec.pdf).
> This is different than the older series in [4] which was based on the
> older specification that does not have scalable mode.
> 
> 
> ChangeLog:
>   - V5
> Rebased on v5.3-rc4 which has some of the IOMMU fault APIs
> merged. Addressed v4 review comments from Eric Auger, Baolu Lu, and
>   Jonathan Cameron. Specific changes are as follows:
> - Refined custom IOASID allocator to support multiple
> vIOMMU, hotplug cases.
> - Extracted vendor data from IOMMU guest PASID bind data,
> for VT-d will support all necessary guest PASID entry fields for PASID
>   bind.
> - Support non-identity host-guest PASID mapping
> - Exception handling in various cases
> 
>   - V4
> - Redesigned IOASID allocator such that it can support
> custom allocators with shared helper functions. Use separate XArray
> to store IOASIDs per allocator. Took advice from Eric Auger
> to have default allocator use the generic allocator structure.
> Combined into one patch in 

[PATCH v1] iommu/vt-d: remove global page flush support

2019-08-26 Thread Jacob Pan
Global pages support is removed from VT-d spec 3.0. Since global pages G
flag only affects first-level paging structures and because DMA request
with PASID are only supported by VT-d spec. 3.0 and onward, we can
safely remove global pages support.

For kernel shared virtual address IOTLB invalidation, PASID
granularity and page selective within PASID will be used. There is
no global granularity supported. Without this fix, IOTLB invalidation
will cause invalid descriptor error in the queued invalidation (QI)
interface.

Fixes: 1c4f88b7f1f9 ("iommu/vt-d: Shared virtual address in scalable
mode")
Reported-by: Sanjay K Kumar 
Signed-off-by: Jacob Pan 
---
 drivers/iommu/intel-svm.c   | 36 +++-
 include/linux/intel-iommu.h |  3 ---
 2 files changed, 15 insertions(+), 24 deletions(-)

diff --git a/drivers/iommu/intel-svm.c b/drivers/iommu/intel-svm.c
index 780de0caafe8..9b159132405d 100644
--- a/drivers/iommu/intel-svm.c
+++ b/drivers/iommu/intel-svm.c
@@ -100,24 +100,19 @@ int intel_svm_finish_prq(struct intel_iommu *iommu)
 }
 
 static void intel_flush_svm_range_dev (struct intel_svm *svm, struct 
intel_svm_dev *sdev,
-  unsigned long address, unsigned long 
pages, int ih, int gl)
+   unsigned long address, unsigned long pages, int 
ih)
 {
struct qi_desc desc;
 
-   if (pages == -1) {
-   /* For global kernel pages we have to flush them in *all* PASIDs
-* because that's the only option the hardware gives us. Despite
-* the fact that they are actually only accessible through one. 
*/
-   if (gl)
-   desc.qw0 = QI_EIOTLB_PASID(svm->pasid) |
-   QI_EIOTLB_DID(sdev->did) |
-   QI_EIOTLB_GRAN(QI_GRAN_ALL_ALL) |
-   QI_EIOTLB_TYPE;
-   else
-   desc.qw0 = QI_EIOTLB_PASID(svm->pasid) |
-   QI_EIOTLB_DID(sdev->did) |
-   QI_EIOTLB_GRAN(QI_GRAN_NONG_PASID) |
-   QI_EIOTLB_TYPE;
+   /*
+* Do PASID granu IOTLB invalidation if page selective capability is
+* not available.
+*/
+   if (pages == -1 || !cap_pgsel_inv(svm->iommu->cap)) {
+   desc.qw0 = QI_EIOTLB_PASID(svm->pasid) |
+   QI_EIOTLB_DID(sdev->did) |
+   QI_EIOTLB_GRAN(QI_GRAN_NONG_PASID) |
+   QI_EIOTLB_TYPE;
desc.qw1 = 0;
} else {
int mask = ilog2(__roundup_pow_of_two(pages));
@@ -127,7 +122,6 @@ static void intel_flush_svm_range_dev (struct intel_svm 
*svm, struct intel_svm_d
QI_EIOTLB_GRAN(QI_GRAN_PSI_PASID) |
QI_EIOTLB_TYPE;
desc.qw1 = QI_EIOTLB_ADDR(address) |
-   QI_EIOTLB_GL(gl) |
QI_EIOTLB_IH(ih) |
QI_EIOTLB_AM(mask);
}
@@ -162,13 +156,13 @@ static void intel_flush_svm_range_dev (struct intel_svm 
*svm, struct intel_svm_d
 }
 
 static void intel_flush_svm_range(struct intel_svm *svm, unsigned long address,
- unsigned long pages, int ih, int gl)
+   unsigned long pages, int ih)
 {
struct intel_svm_dev *sdev;
 
rcu_read_lock();
list_for_each_entry_rcu(sdev, >devs, list)
-   intel_flush_svm_range_dev(svm, sdev, address, pages, ih, gl);
+   intel_flush_svm_range_dev(svm, sdev, address, pages, ih);
rcu_read_unlock();
 }
 
@@ -180,7 +174,7 @@ static void intel_invalidate_range(struct mmu_notifier *mn,
struct intel_svm *svm = container_of(mn, struct intel_svm, notifier);
 
intel_flush_svm_range(svm, start,
- (end - start + PAGE_SIZE - 1) >> VTD_PAGE_SHIFT, 
0, 0);
+ (end - start + PAGE_SIZE - 1) >> VTD_PAGE_SHIFT, 
0);
 }
 
 static void intel_mm_release(struct mmu_notifier *mn, struct mm_struct *mm)
@@ -203,7 +197,7 @@ static void intel_mm_release(struct mmu_notifier *mn, 
struct mm_struct *mm)
rcu_read_lock();
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, !svm->mm);
+   intel_flush_svm_range_dev(svm, sdev, 0, -1, 0);
}
rcu_read_unlock();
 
@@ -425,7 +419,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, 

Re: [PATCH] media: staging: tegra-vde: Disable building with COMPILE_TEST

2019-08-26 Thread Dmitry Osipenko
26.08.2019 18:18, Dmitry Osipenko пишет:
> Hello Yue,
> 
> 26.08.2019 16:31, YueHaibing пишет:
>> If COMPILE_TEST is y and IOMMU_SUPPORT is n, selecting TEGRA_VDE
>> to m will set IOMMU_IOVA to m, this fails the building of
>> TEGRA_HOST1X and DRM_TEGRA which is y like this:
>>
>> drivers/gpu/host1x/cdma.o: In function `host1x_cdma_init':
>> cdma.c:(.text+0x66c): undefined reference to `alloc_iova'
>> cdma.c:(.text+0x698): undefined reference to `__free_iova'
>>
>> drivers/gpu/drm/tegra/drm.o: In function `tegra_drm_unload':
>> drm.c:(.text+0xeb0): undefined reference to `put_iova_domain'
>> drm.c:(.text+0xeb4): undefined reference to `iova_cache_put'
>>
>> Reported-by: Hulk Robot 
>> Fixes: 6b2265975239 ("media: staging: tegra-vde: Fix build error")
>> Fixes: b301f8de1925 ("media: staging: media: tegra-vde: Add IOMMU support")
>> Signed-off-by: YueHaibing 
>> ---
>>  drivers/staging/media/tegra-vde/Kconfig | 4 ++--
>>  1 file changed, 2 insertions(+), 2 deletions(-)
>>
>> diff --git a/drivers/staging/media/tegra-vde/Kconfig 
>> b/drivers/staging/media/tegra-vde/Kconfig
>> index ba49ea5..a41d30c 100644
>> --- a/drivers/staging/media/tegra-vde/Kconfig
>> +++ b/drivers/staging/media/tegra-vde/Kconfig
>> @@ -1,9 +1,9 @@
>>  # SPDX-License-Identifier: GPL-2.0
>>  config TEGRA_VDE
>>  tristate "NVIDIA Tegra Video Decoder Engine driver"
>> -depends on ARCH_TEGRA || COMPILE_TEST
>> +depends on ARCH_TEGRA
>>  select DMA_SHARED_BUFFER
>> -select IOMMU_IOVA if (IOMMU_SUPPORT || COMPILE_TEST)
>> +select IOMMU_IOVA if IOMMU_SUPPORT
>>  select SRAM
>>  help
>>  Say Y here to enable support for the NVIDIA Tegra video decoder
>>
> 
> What about this variant:
> 
>   select IOMMU_IOVA if (IOMMU_SUPPORT && !COMPILE_TEST)
> 
> which should fix the building and preserve compile-testing.
> 
> It shouldn't matter at all whether IOVA is enabled or not for
> compile-testing of the driver.
> 

Ah, actually this won't work if TEGRA_VDE=y and IOMMU_IOVA=m. I'm still
not sure that disabling compile-testing is a good solution, maybe
DRM_TEGRA and TEGRA_HOST1X should be fixed instead. Although, I'm fine
with both variants.

Acked-by: Dmitry Osipenko 


Re: [PATCH] media: staging: tegra-vde: Disable building with COMPILE_TEST

2019-08-26 Thread Dmitry Osipenko
Hello Yue,

26.08.2019 16:31, YueHaibing пишет:
> If COMPILE_TEST is y and IOMMU_SUPPORT is n, selecting TEGRA_VDE
> to m will set IOMMU_IOVA to m, this fails the building of
> TEGRA_HOST1X and DRM_TEGRA which is y like this:
> 
> drivers/gpu/host1x/cdma.o: In function `host1x_cdma_init':
> cdma.c:(.text+0x66c): undefined reference to `alloc_iova'
> cdma.c:(.text+0x698): undefined reference to `__free_iova'
> 
> drivers/gpu/drm/tegra/drm.o: In function `tegra_drm_unload':
> drm.c:(.text+0xeb0): undefined reference to `put_iova_domain'
> drm.c:(.text+0xeb4): undefined reference to `iova_cache_put'
> 
> Reported-by: Hulk Robot 
> Fixes: 6b2265975239 ("media: staging: tegra-vde: Fix build error")
> Fixes: b301f8de1925 ("media: staging: media: tegra-vde: Add IOMMU support")
> Signed-off-by: YueHaibing 
> ---
>  drivers/staging/media/tegra-vde/Kconfig | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/staging/media/tegra-vde/Kconfig 
> b/drivers/staging/media/tegra-vde/Kconfig
> index ba49ea5..a41d30c 100644
> --- a/drivers/staging/media/tegra-vde/Kconfig
> +++ b/drivers/staging/media/tegra-vde/Kconfig
> @@ -1,9 +1,9 @@
>  # SPDX-License-Identifier: GPL-2.0
>  config TEGRA_VDE
>   tristate "NVIDIA Tegra Video Decoder Engine driver"
> - depends on ARCH_TEGRA || COMPILE_TEST
> + depends on ARCH_TEGRA
>   select DMA_SHARED_BUFFER
> - select IOMMU_IOVA if (IOMMU_SUPPORT || COMPILE_TEST)
> + select IOMMU_IOVA if IOMMU_SUPPORT
>   select SRAM
>   help
>   Say Y here to enable support for the NVIDIA Tegra video decoder
> 

What about this variant:

select IOMMU_IOVA if (IOMMU_SUPPORT && !COMPILE_TEST)

which should fix the building and preserve compile-testing.

It shouldn't matter at all whether IOVA is enabled or not for
compile-testing of the driver.


[PATCH] vmd: Stop overriding dma_map_ops

2019-08-26 Thread Christoph Hellwig
With a little tweak to the intel-iommu code we should be able to work
around the VMD mess for the requester IDs without having to create giant
amounts of boilerplate DMA ops wrapping code.  The other advantage of
this scheme is that we can respect the real DMA masks for the actual
devices, and I bet it will only be a matter of time until we'll see the
first DMA challeneged NVMe devices.

The only downside is that we can't offer vmd as a module given that
intel-iommu calls into it.  But the driver only has about 700 lines
of code, so this should not be a major issue.

This also removes the leftover bits of the X86_DEV_DMA_OPS dma_map_ops
registry.

Signed-off-by: Christoph Hellwig 
---
 arch/x86/Kconfig   |   3 -
 arch/x86/include/asm/device.h  |  10 ---
 arch/x86/include/asm/pci.h |   2 +
 arch/x86/pci/common.c  |  38 -
 drivers/iommu/intel-iommu.c|  33 +---
 drivers/pci/controller/Kconfig |   6 +-
 drivers/pci/controller/vmd.c   | 139 +
 7 files changed, 27 insertions(+), 204 deletions(-)

diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 222855cc0158..35597dae38b7 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -2905,9 +2905,6 @@ config HAVE_ATOMIC_IOMAP
def_bool y
depends on X86_32
 
-config X86_DEV_DMA_OPS
-   bool
-
 source "drivers/firmware/Kconfig"
 
 source "arch/x86/kvm/Kconfig"
diff --git a/arch/x86/include/asm/device.h b/arch/x86/include/asm/device.h
index a8f6c809d9b1..3e6c75a6d070 100644
--- a/arch/x86/include/asm/device.h
+++ b/arch/x86/include/asm/device.h
@@ -11,16 +11,6 @@ struct dev_archdata {
 #endif
 };
 
-#if defined(CONFIG_X86_DEV_DMA_OPS) && defined(CONFIG_PCI_DOMAINS)
-struct dma_domain {
-   struct list_head node;
-   const struct dma_map_ops *dma_ops;
-   int domain_nr;
-};
-void add_dma_domain(struct dma_domain *domain);
-void del_dma_domain(struct dma_domain *domain);
-#endif
-
 struct pdev_archdata {
 };
 
diff --git a/arch/x86/include/asm/pci.h b/arch/x86/include/asm/pci.h
index e662f987dfa2..f740246ea812 100644
--- a/arch/x86/include/asm/pci.h
+++ b/arch/x86/include/asm/pci.h
@@ -73,6 +73,8 @@ static inline bool is_vmd(struct pci_bus *bus)
 #endif
 }
 
+struct device *to_vmd_dev(struct device *dev);
+
 /* Can be used to override the logic in pci_scan_bus for skipping
already-configured bus numbers - to be used for buggy BIOSes
or architectures with incomplete PCI setup by the loader */
diff --git a/arch/x86/pci/common.c b/arch/x86/pci/common.c
index 9acab6ac28f5..d2ac803b6c00 100644
--- a/arch/x86/pci/common.c
+++ b/arch/x86/pci/common.c
@@ -625,43 +625,6 @@ unsigned int pcibios_assign_all_busses(void)
return (pci_probe & PCI_ASSIGN_ALL_BUSSES) ? 1 : 0;
 }
 
-#if defined(CONFIG_X86_DEV_DMA_OPS) && defined(CONFIG_PCI_DOMAINS)
-static LIST_HEAD(dma_domain_list);
-static DEFINE_SPINLOCK(dma_domain_list_lock);
-
-void add_dma_domain(struct dma_domain *domain)
-{
-   spin_lock(_domain_list_lock);
-   list_add(>node, _domain_list);
-   spin_unlock(_domain_list_lock);
-}
-EXPORT_SYMBOL_GPL(add_dma_domain);
-
-void del_dma_domain(struct dma_domain *domain)
-{
-   spin_lock(_domain_list_lock);
-   list_del(>node);
-   spin_unlock(_domain_list_lock);
-}
-EXPORT_SYMBOL_GPL(del_dma_domain);
-
-static void set_dma_domain_ops(struct pci_dev *pdev)
-{
-   struct dma_domain *domain;
-
-   spin_lock(_domain_list_lock);
-   list_for_each_entry(domain, _domain_list, node) {
-   if (pci_domain_nr(pdev->bus) == domain->domain_nr) {
-   pdev->dev.dma_ops = domain->dma_ops;
-   break;
-   }
-   }
-   spin_unlock(_domain_list_lock);
-}
-#else
-static void set_dma_domain_ops(struct pci_dev *pdev) {}
-#endif
-
 static void set_dev_domain_options(struct pci_dev *pdev)
 {
if (is_vmd(pdev->bus))
@@ -697,7 +660,6 @@ int pcibios_add_device(struct pci_dev *dev)
pa_data = data->next;
memunmap(data);
}
-   set_dma_domain_ops(dev);
set_dev_domain_options(dev);
return 0;
 }
diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c
index 12d094d08c0a..e8e876605d6a 100644
--- a/drivers/iommu/intel-iommu.c
+++ b/drivers/iommu/intel-iommu.c
@@ -3416,9 +3416,14 @@ static struct dmar_domain 
*get_private_domain_for_dev(struct device *dev)
return domain;
 }
 
-/* Check if the dev needs to go through non-identity map and unmap process.*/
-static bool iommu_need_mapping(struct device *dev)
+/*
+ * Check if the dev needs to go through non-identity map and unmap process.
+ * Also where needed replace dev with the actual device used for the mapping
+ * process.
+ */
+static bool iommu_need_mapping(struct device **devp)
 {
+   struct device *dev = *devp;
int ret;
 
if (iommu_dummy(dev))
@@ -3456,6 +3461,14 @@ static bool iommu_need_mapping(struct device *dev)

Re: [PATCH v4 01/14] dt-bindings: Add binding for MT2712 MIPI-CSI2

2019-08-26 Thread Sakari Ailus
On Mon, Jun 10, 2019 at 04:58:02PM +0900, Tomasz Figa wrote:
> On Mon, Jun 10, 2019 at 4:51 PM CK Hu  wrote:
> >
> > Hi, Tomasz:
> >
> > On Mon, 2019-06-10 at 12:32 +0900, Tomasz Figa wrote:
> > > Hi CK, Stu,
> > >
> > > On Mon, Jun 10, 2019 at 11:34 AM CK Hu  wrote:
> > > >
> > > > Hi, Stu:
> > > >
> > > > "mediatek,mt2712-mipicsi" and "mediatek,mt2712-mipicsi-common" have many
> > > > common part with "mediatek,mt8183-seninf", and I've a discussion in [1],
> > > > so I would like these two to be merged together.
> > > >
> > > > [1] https://patchwork.kernel.org/patch/10979131/
> > > >
> > >
> > > Thanks CK for spotting this.
> > >
> > > I also noticed that the driver in fact handles two hardware blocks at
> > > the same time - SenInf and CamSV. Unless the architecture is very
> > > different from MT8183, I'd suggest splitting it.
> > >
> > > On a general note, the MT8183 SenInf driver has received several
> > > rounds of review comments already, but I couldn't find any comments
> > > posted for this one.
> > >
> > > Given the two aspects above and also based on my quick look at code
> > > added by this series, I'd recommend adding MT2712 support on top of
> > > the MT8183 series.
> >
> > In [1], "mediatek,mt8183-seninf" use one device to control multiple csi
> > instance, so it duplicate many register definition. In [2], one
> > "mediatek,mt2712-mipicsi" device control one csi instance, so there are
> > multiple device and the register definition does not duplicate.
> 
> I guess we didn't catch that in the review yet. It should be fixed.
> 
> > You
> > recommend adding MT2712 support on top of the MT8183 series, do you mean
> > that "mediatek,mt2712-mipicsi" should use one device to control multiple
> > csi instance and duplicate the register setting?
> 
> There are some aspects of MT8183 series that are done better than the
> MT2712 series, but apparently there are also some better aspects in
> MT2712. We should take the best aspects of both series. :)

Stu: Are the two devices similar enough or not; does this look like a
feasible approach to you?

-- 
Sakari Ailus


Re: [PATCH v2 01/11] asm-generic: add dma_zone_size

2019-08-26 Thread Nicolas Saenz Julienne
On Mon, 2019-08-26 at 09:09 +0200, Christoph Hellwig wrote:
> On Tue, Aug 20, 2019 at 04:58:09PM +0200, Nicolas Saenz Julienne wrote:
> > Some architectures have platform specific DMA addressing limitations.
> > This will allow for hardware description code to provide the constraints
> > in a generic manner, so as for arch code to properly setup it's memory
> > zones and DMA mask.
> 
> I know this just spreads the arm code, but I still kinda hate it.

Rob's main concern was finding a way to pass the constraint from HW definition
to arch without widening fdt's architecture specific function surface. I'd say
it's fair to argue that having a generic mechanism makes sense as it'll now
traverse multiple archs and subsystems.

I get adding globals like this is not very appealing, yet I went with it as it
was the easier to integrate with arm's code. Any alternative suggestions?

> MAX_DMA_ADDRESS is such an oddly defined concepts.  We have the mm
> code that uses it to start allocating after the dma zones, but
> I think that would better be done using a function returning
> 1 << max(zone_dma_bits, 32) or so.  Then we have about a handful
> of drivers using it that all seem rather bogus, and one of which
> I think are usable on arm64.

Is it safe to assume DMA limitations will always be a power of 2? I ask as RPi4
kinda isn't: ZONE_DMA is 0x3c00 bytes big, I'm approximating the zone mask
to 30 as [0x3c00 0x3fff] isn't defined as memory so it's unlikely that
we´ll encounter buffers there. But I don't know how it could affect mm
initialization code.

This also rules out 'zone_dma_bits' as a mechanism to pass ZONE_DMA's size from
HW definition code to arch's.



signature.asc
Description: This is a digitally signed message part


[PATCH] media: staging: tegra-vde: Disable building with COMPILE_TEST

2019-08-26 Thread YueHaibing
If COMPILE_TEST is y and IOMMU_SUPPORT is n, selecting TEGRA_VDE
to m will set IOMMU_IOVA to m, this fails the building of
TEGRA_HOST1X and DRM_TEGRA which is y like this:

drivers/gpu/host1x/cdma.o: In function `host1x_cdma_init':
cdma.c:(.text+0x66c): undefined reference to `alloc_iova'
cdma.c:(.text+0x698): undefined reference to `__free_iova'

drivers/gpu/drm/tegra/drm.o: In function `tegra_drm_unload':
drm.c:(.text+0xeb0): undefined reference to `put_iova_domain'
drm.c:(.text+0xeb4): undefined reference to `iova_cache_put'

Reported-by: Hulk Robot 
Fixes: 6b2265975239 ("media: staging: tegra-vde: Fix build error")
Fixes: b301f8de1925 ("media: staging: media: tegra-vde: Add IOMMU support")
Signed-off-by: YueHaibing 
---
 drivers/staging/media/tegra-vde/Kconfig | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/staging/media/tegra-vde/Kconfig 
b/drivers/staging/media/tegra-vde/Kconfig
index ba49ea5..a41d30c 100644
--- a/drivers/staging/media/tegra-vde/Kconfig
+++ b/drivers/staging/media/tegra-vde/Kconfig
@@ -1,9 +1,9 @@
 # SPDX-License-Identifier: GPL-2.0
 config TEGRA_VDE
tristate "NVIDIA Tegra Video Decoder Engine driver"
-   depends on ARCH_TEGRA || COMPILE_TEST
+   depends on ARCH_TEGRA
select DMA_SHARED_BUFFER
-   select IOMMU_IOVA if (IOMMU_SUPPORT || COMPILE_TEST)
+   select IOMMU_IOVA if IOMMU_SUPPORT
select SRAM
help
Say Y here to enable support for the NVIDIA Tegra video decoder
-- 
2.7.4




[PATCH 2/6] arm-nommu: remove the unused pgprot_dmacoherent define

2019-08-26 Thread Christoph Hellwig
Signed-off-by: Christoph Hellwig 
---
 arch/arm/include/asm/pgtable-nommu.h | 1 -
 1 file changed, 1 deletion(-)

diff --git a/arch/arm/include/asm/pgtable-nommu.h 
b/arch/arm/include/asm/pgtable-nommu.h
index 0b1f6799a32e..d0de24f06724 100644
--- a/arch/arm/include/asm/pgtable-nommu.h
+++ b/arch/arm/include/asm/pgtable-nommu.h
@@ -62,7 +62,6 @@ typedef pte_t *pte_addr_t;
  */
 #define pgprot_noncached(prot) (prot)
 #define pgprot_writecombine(prot) (prot)
-#define pgprot_dmacoherent(prot) (prot)
 #define pgprot_device(prot)(prot)
 
 
-- 
2.20.1



[PATCH 6/6] MIPS: document mixing "slightly different CCAs"

2019-08-26 Thread Christoph Hellwig
Based on an email from Paul Burton, quoting section 4.8 "Cacheability and
Coherency Attributes and Access Types" of "MIPS Architecture Volume 1:
Introduction to the MIPS32 Architecture" (MD00080, revision 6.01).

Signed-off-by: Christoph Hellwig 
---
 arch/mips/Kconfig | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index fc88f68ea1ee..aff1cadeea43 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -1119,6 +1119,13 @@ config DMA_PERDEV_COHERENT
 
 config DMA_NONCOHERENT
bool
+   #
+   # MIPS allows mixing "slightly different" Cacheability and Coherency
+   # Attribute bits.  It is believed that the uncached access through
+   # KSEG1 and the implementation specific "uncached accelerated" used
+   # by pgprot_writcombine can be mixed, and the latter sometimes provides
+   # significant advantages.
+   #
select ARCH_HAS_DMA_WRITE_COMBINE
select ARCH_HAS_SYNC_DMA_FOR_DEVICE
select ARCH_HAS_UNCACHED_SEGMENT
-- 
2.20.1



[PATCH 3/6] dma-mapping: remove arch_dma_mmap_pgprot

2019-08-26 Thread Christoph Hellwig
arch_dma_mmap_pgprot is used for two things:

 1) to override the "normal" uncached page attributes for mapping
memory coherent to devices that can't snoop the CPU caches
 2) to provide the special DMA_ATTR_WRITE_COMBINE semantics on older
arm systems and some mips platforms

Replace one with the pgprot_dmacoherent macro that is already provided
by arm and much simpler to use, and lift the DMA_ATTR_WRITE_COMBINE
handling to common code with an explicit arch opt-in.

Signed-off-by: Christoph Hellwig 
Acked-by: Geert Uytterhoeven 
---
 arch/arm/Kconfig   |  2 +-
 arch/arm/mm/dma-mapping.c  |  6 --
 arch/arm64/Kconfig |  1 -
 arch/arm64/include/asm/pgtable.h   |  4 
 arch/arm64/mm/dma-mapping.c|  6 --
 arch/m68k/Kconfig  |  1 -
 arch/m68k/include/asm/pgtable_mm.h |  3 +++
 arch/m68k/kernel/dma.c |  3 +--
 arch/mips/Kconfig  |  2 +-
 arch/mips/mm/dma-noncoherent.c |  8 
 include/linux/dma-noncoherent.h| 13 +++--
 kernel/dma/Kconfig | 12 +---
 kernel/dma/mapping.c   |  8 +---
 13 files changed, 35 insertions(+), 34 deletions(-)

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 24360211534a..217083caeabd 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -8,7 +8,7 @@ config ARM
select ARCH_HAS_DEBUG_VIRTUAL if MMU
select ARCH_HAS_DEVMEM_IS_ALLOWED
select ARCH_HAS_DMA_COHERENT_TO_PFN if SWIOTLB
-   select ARCH_HAS_DMA_MMAP_PGPROT if SWIOTLB
+   select ARCH_HAS_DMA_WRITE_COMBINE if !ARM_DMA_MEM_BUFFERABLE
select ARCH_HAS_ELF_RANDOMIZE
select ARCH_HAS_FORTIFY_SOURCE
select ARCH_HAS_KEEPINITRD
diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
index d42557ee69c2..d27b12f61737 100644
--- a/arch/arm/mm/dma-mapping.c
+++ b/arch/arm/mm/dma-mapping.c
@@ -2402,12 +2402,6 @@ long arch_dma_coherent_to_pfn(struct device *dev, void 
*cpu_addr,
return dma_to_pfn(dev, dma_addr);
 }
 
-pgprot_t arch_dma_mmap_pgprot(struct device *dev, pgprot_t prot,
-   unsigned long attrs)
-{
-   return __get_dma_pgprot(attrs, prot);
-}
-
 void *arch_dma_alloc(struct device *dev, size_t size, dma_addr_t *dma_handle,
gfp_t gfp, unsigned long attrs)
 {
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 3adcec05b1f6..dab9dda34206 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -13,7 +13,6 @@ config ARM64
select ARCH_HAS_DEBUG_VIRTUAL
select ARCH_HAS_DEVMEM_IS_ALLOWED
select ARCH_HAS_DMA_COHERENT_TO_PFN
-   select ARCH_HAS_DMA_MMAP_PGPROT
select ARCH_HAS_DMA_PREP_COHERENT
select ARCH_HAS_ACPI_TABLE_UPGRADE if ACPI
select ARCH_HAS_ELF_RANDOMIZE
diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
index e09760ece844..6700371227d1 100644
--- a/arch/arm64/include/asm/pgtable.h
+++ b/arch/arm64/include/asm/pgtable.h
@@ -435,6 +435,10 @@ static inline pmd_t pmd_mkdevmap(pmd_t pmd)
__pgprot_modify(prot, PTE_ATTRINDX_MASK, PTE_ATTRINDX(MT_NORMAL_NC) | 
PTE_PXN | PTE_UXN)
 #define pgprot_device(prot) \
__pgprot_modify(prot, PTE_ATTRINDX_MASK, PTE_ATTRINDX(MT_DEVICE_nGnRE) 
| PTE_PXN | PTE_UXN)
+#define pgprot_dmacoherent(prot) \
+   __pgprot_modify(prot, PTE_ATTRINDX_MASK, \
+   PTE_ATTRINDX(MT_NORMAL_NC) | PTE_PXN | PTE_UXN)
+
 #define __HAVE_PHYS_MEM_ACCESS_PROT
 struct file;
 extern pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn,
diff --git a/arch/arm64/mm/dma-mapping.c b/arch/arm64/mm/dma-mapping.c
index bd2b039f43a6..676efcda51e6 100644
--- a/arch/arm64/mm/dma-mapping.c
+++ b/arch/arm64/mm/dma-mapping.c
@@ -11,12 +11,6 @@
 
 #include 
 
-pgprot_t arch_dma_mmap_pgprot(struct device *dev, pgprot_t prot,
-   unsigned long attrs)
-{
-   return pgprot_writecombine(prot);
-}
-
 void arch_sync_dma_for_device(struct device *dev, phys_addr_t paddr,
size_t size, enum dma_data_direction dir)
 {
diff --git a/arch/m68k/Kconfig b/arch/m68k/Kconfig
index c518d695c376..a9e564306d3e 100644
--- a/arch/m68k/Kconfig
+++ b/arch/m68k/Kconfig
@@ -4,7 +4,6 @@ config M68K
default y
select ARCH_32BIT_OFF_T
select ARCH_HAS_BINFMT_FLAT
-   select ARCH_HAS_DMA_MMAP_PGPROT if MMU && !COLDFIRE
select ARCH_HAS_DMA_PREP_COHERENT if HAS_DMA && MMU && !COLDFIRE
select ARCH_HAS_SYNC_DMA_FOR_DEVICE if HAS_DMA
select ARCH_MIGHT_HAVE_PC_PARPORT if ISA
diff --git a/arch/m68k/include/asm/pgtable_mm.h 
b/arch/m68k/include/asm/pgtable_mm.h
index fe3ddd73a0cc..fde4534b974f 100644
--- a/arch/m68k/include/asm/pgtable_mm.h
+++ b/arch/m68k/include/asm/pgtable_mm.h
@@ -169,6 +169,9 @@ static inline void update_mmu_cache(struct vm_area_struct 
*vma,
? (__pgprot((pgprot_val(prot) & _CACHEMASK040) | _PAGE_NOCACHE_S))  
\
: (prot)))
 
+pgprot_t 

[PATCH 1/6] unicore32: remove the unused pgprot_dmacoherent define

2019-08-26 Thread Christoph Hellwig
Signed-off-by: Christoph Hellwig 
---
 arch/unicore32/include/asm/pgtable.h | 2 --
 1 file changed, 2 deletions(-)

diff --git a/arch/unicore32/include/asm/pgtable.h 
b/arch/unicore32/include/asm/pgtable.h
index 9492aa304f03..126e961a8cb0 100644
--- a/arch/unicore32/include/asm/pgtable.h
+++ b/arch/unicore32/include/asm/pgtable.h
@@ -198,8 +198,6 @@ static inline pte_t pte_mkspecial(pte_t pte) { return pte; }
__pgprot(pgprot_val(prot) & ~PTE_CACHEABLE)
 #define pgprot_writecombine(prot)  \
__pgprot(pgprot_val(prot) & ~PTE_CACHEABLE)
-#define pgprot_dmacoherent(prot)   \
-   __pgprot(pgprot_val(prot) & ~PTE_CACHEABLE)
 
 #define pmd_none(pmd)  (!pmd_val(pmd))
 #define pmd_present(pmd)   (pmd_val(pmd) & PMD_PRESENT)
-- 
2.20.1



[PATCH 5/6] arm64: document the choice of page attributes for pgprot_dmacoherent

2019-08-26 Thread Christoph Hellwig
Based on an email from Will Deacon.

Signed-off-by: Christoph Hellwig 
Acked-by: Will Deacon 
Acked-by: Mark Rutland 
---
 arch/arm64/include/asm/pgtable.h | 8 
 1 file changed, 8 insertions(+)

diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
index 6700371227d1..fd40fb05eb51 100644
--- a/arch/arm64/include/asm/pgtable.h
+++ b/arch/arm64/include/asm/pgtable.h
@@ -435,6 +435,14 @@ static inline pmd_t pmd_mkdevmap(pmd_t pmd)
__pgprot_modify(prot, PTE_ATTRINDX_MASK, PTE_ATTRINDX(MT_NORMAL_NC) | 
PTE_PXN | PTE_UXN)
 #define pgprot_device(prot) \
__pgprot_modify(prot, PTE_ATTRINDX_MASK, PTE_ATTRINDX(MT_DEVICE_nGnRE) 
| PTE_PXN | PTE_UXN)
+/*
+ * DMA allocations for non-coherent devices use what the Arm architecture calls
+ * "Normal non-cacheable" memory, which permits speculation, unaligned accesses
+ * and merging of writes.  This is different from "Device-nGnR[nE]" memory 
which
+ * is intended for MMIO and thus forbids speculation, preserves access size,
+ * requires strict alignment and can also force write responses to come from 
the
+ * endpoint.
+ */
 #define pgprot_dmacoherent(prot) \
__pgprot_modify(prot, PTE_ATTRINDX_MASK, \
PTE_ATTRINDX(MT_NORMAL_NC) | PTE_PXN | PTE_UXN)
-- 
2.20.1



[PATCH 4/6] dma-mapping: make dma_atomic_pool_init self-contained

2019-08-26 Thread Christoph Hellwig
The memory allocated for the atomic pool needs to have the same
mapping attributes that we use for remapping, so use
pgprot_dmacoherent instead of open coding it.  Also deduct a
suitable zone to allocate the memory from based on the presence
of the DMA zones.

Signed-off-by: Christoph Hellwig 
---
 arch/arc/mm/dma.c   |  6 --
 arch/arm64/mm/dma-mapping.c |  6 --
 arch/csky/mm/dma-mapping.c  |  6 --
 arch/nds32/kernel/dma.c |  6 --
 include/linux/dma-mapping.h |  1 -
 kernel/dma/remap.c  | 17 ++---
 6 files changed, 14 insertions(+), 28 deletions(-)

diff --git a/arch/arc/mm/dma.c b/arch/arc/mm/dma.c
index 62c210e7ee4c..ff4a5752f8cc 100644
--- a/arch/arc/mm/dma.c
+++ b/arch/arc/mm/dma.c
@@ -104,9 +104,3 @@ void arch_setup_dma_ops(struct device *dev, u64 dma_base, 
u64 size,
dev_info(dev, "use %sncoherent DMA ops\n",
 dev->dma_coherent ? "" : "non");
 }
-
-static int __init atomic_pool_init(void)
-{
-   return dma_atomic_pool_init(GFP_KERNEL, pgprot_noncached(PAGE_KERNEL));
-}
-postcore_initcall(atomic_pool_init);
diff --git a/arch/arm64/mm/dma-mapping.c b/arch/arm64/mm/dma-mapping.c
index 676efcda51e6..a1d05f669f67 100644
--- a/arch/arm64/mm/dma-mapping.c
+++ b/arch/arm64/mm/dma-mapping.c
@@ -28,12 +28,6 @@ void arch_dma_prep_coherent(struct page *page, size_t size)
__dma_flush_area(page_address(page), size);
 }
 
-static int __init arm64_dma_init(void)
-{
-   return dma_atomic_pool_init(GFP_DMA32, __pgprot(PROT_NORMAL_NC));
-}
-arch_initcall(arm64_dma_init);
-
 #ifdef CONFIG_IOMMU_DMA
 void arch_teardown_dma_ops(struct device *dev)
 {
diff --git a/arch/csky/mm/dma-mapping.c b/arch/csky/mm/dma-mapping.c
index 80783bb71c5c..602a60d47a94 100644
--- a/arch/csky/mm/dma-mapping.c
+++ b/arch/csky/mm/dma-mapping.c
@@ -14,12 +14,6 @@
 #include 
 #include 
 
-static int __init atomic_pool_init(void)
-{
-   return dma_atomic_pool_init(GFP_KERNEL, pgprot_noncached(PAGE_KERNEL));
-}
-postcore_initcall(atomic_pool_init);
-
 void arch_dma_prep_coherent(struct page *page, size_t size)
 {
if (PageHighMem(page)) {
diff --git a/arch/nds32/kernel/dma.c b/arch/nds32/kernel/dma.c
index 490e3720d694..4206d4b6c8ce 100644
--- a/arch/nds32/kernel/dma.c
+++ b/arch/nds32/kernel/dma.c
@@ -80,9 +80,3 @@ void arch_dma_prep_coherent(struct page *page, size_t size)
 {
cache_op(page_to_phys(page), size, cpu_dma_wbinval_range);
 }
-
-static int __init atomic_pool_init(void)
-{
-   return dma_atomic_pool_init(GFP_KERNEL, pgprot_noncached(PAGE_KERNEL));
-}
-postcore_initcall(atomic_pool_init);
diff --git a/include/linux/dma-mapping.h b/include/linux/dma-mapping.h
index f7d1eea32c78..48ebe8295987 100644
--- a/include/linux/dma-mapping.h
+++ b/include/linux/dma-mapping.h
@@ -624,7 +624,6 @@ void *dma_common_pages_remap(struct page **pages, size_t 
size,
const void *caller);
 void dma_common_free_remap(void *cpu_addr, size_t size, unsigned long 
vm_flags);
 
-int __init dma_atomic_pool_init(gfp_t gfp, pgprot_t prot);
 bool dma_in_atomic_pool(void *start, size_t size);
 void *dma_alloc_from_pool(size_t size, struct page **ret_page, gfp_t flags);
 bool dma_free_from_pool(void *start, size_t size);
diff --git a/kernel/dma/remap.c b/kernel/dma/remap.c
index ffe78f0b2fe4..838123f79639 100644
--- a/kernel/dma/remap.c
+++ b/kernel/dma/remap.c
@@ -105,7 +105,16 @@ static int __init early_coherent_pool(char *p)
 }
 early_param("coherent_pool", early_coherent_pool);
 
-int __init dma_atomic_pool_init(gfp_t gfp, pgprot_t prot)
+static gfp_t dma_atomic_pool_gfp(void)
+{
+   if (IS_ENABLED(CONFIG_ZONE_DMA))
+   return GFP_DMA;
+   if (IS_ENABLED(CONFIG_ZONE_DMA32))
+   return GFP_DMA32;
+   return GFP_KERNEL;
+}
+
+static int __init dma_atomic_pool_init(void)
 {
unsigned int pool_size_order = get_order(atomic_pool_size);
unsigned long nr_pages = atomic_pool_size >> PAGE_SHIFT;
@@ -117,7 +126,7 @@ int __init dma_atomic_pool_init(gfp_t gfp, pgprot_t prot)
page = dma_alloc_from_contiguous(NULL, nr_pages,
 pool_size_order, false);
else
-   page = alloc_pages(gfp, pool_size_order);
+   page = alloc_pages(dma_atomic_pool_gfp(), pool_size_order);
if (!page)
goto out;
 
@@ -128,7 +137,8 @@ int __init dma_atomic_pool_init(gfp_t gfp, pgprot_t prot)
goto free_page;
 
addr = dma_common_contiguous_remap(page, atomic_pool_size, VM_USERMAP,
-  prot, __builtin_return_address(0));
+  pgprot_dmacoherent(PAGE_KERNEL),
+  __builtin_return_address(0));
if (!addr)
goto destroy_genpool;
 
@@ -155,6 +165,7 @@ int __init dma_atomic_pool_init(gfp_t gfp, pgprot_t prot)
atomic_pool_size / 1024);
   

cleanup the dma_pgprot handling v2

2019-08-26 Thread Christoph Hellwig
Hi all,

this series replaces the arch_dma_mmap_pgprot hooks with the
simpler pgprot_dmacoherent as used by the arm code already and
cleans up various bits around that area.

Changes since v1:
 - improve the new arm64 comment
 - keep the special DMA_ATTR_WRITE_COMBINE handling for mips and
   document it


Re: [PATCH] iommu/vt-d: remove global page flush support

2019-08-26 Thread Jacob Pan
On Fri, 23 Aug 2019 10:23:07 +0200
Joerg Roedel  wrote:

> Hi Jacob,
> 
> On Tue, Aug 20, 2019 at 02:21:08PM -0700, Jacob Pan wrote:
> > Global pages support is removed from VT-d spec 3.0. Since global
> > pages G flag only affects first-level paging structures and because
> > DMA request with PASID are only supported by VT-d spec. 3.0 and
> > onward, we can safely remove global pages support.
> > 
> > For kernel shared virtual address IOTLB invalidation, PASID
> > granularity and page selective within PASID will be used. There is
> > no global granularity supported. Without this fix, IOTLB
> > invalidation will cause invalid descriptor error in the queued
> > invalidation (QI) interface.
> > 
> > Reported-by:   Sanjay K Kumar 
> > Signed-off-by: Jacob Pan 
> > ---
> >  drivers/iommu/intel-svm.c   | 36
> > +++- include/linux/intel-iommu.h |
> > 3 --- 2 files changed, 15 insertions(+), 24 deletions(-)  
> 
> Does not cleanly apply to v5.3-rc5, can you please rebase it and
> re-send? Also, is this v5.3 stuff (in that case please add a Fixes
> tag) or can it wait for v5.4?
> 
I will rebase and send out again later today. Since it fixes fault in
HW and in QEMU vIOMMU that is in development, it would be great to be
included in v5.3. I will add a fixes tag.

Thanks,

Jacob

> Regards,
> 
>   Joerg

[Jacob Pan]


[PATCH 11/11] arm64: use asm-generic/dma-mapping.h

2019-08-26 Thread Christoph Hellwig
Now that the Xen special cases are gone nothing worth mentioning is
left in the arm64  file, so switch to use the
asm-generic version instead.

Signed-off-by: Christoph Hellwig 
Acked-by: Will Deacon 
---
 arch/arm64/include/asm/Kbuild|  1 +
 arch/arm64/include/asm/dma-mapping.h | 22 --
 arch/arm64/mm/dma-mapping.c  |  1 +
 3 files changed, 2 insertions(+), 22 deletions(-)
 delete mode 100644 arch/arm64/include/asm/dma-mapping.h

diff --git a/arch/arm64/include/asm/Kbuild b/arch/arm64/include/asm/Kbuild
index c52e151afab0..98a5405c8558 100644
--- a/arch/arm64/include/asm/Kbuild
+++ b/arch/arm64/include/asm/Kbuild
@@ -4,6 +4,7 @@ generic-y += delay.h
 generic-y += div64.h
 generic-y += dma.h
 generic-y += dma-contiguous.h
+generic-y += dma-mapping.h
 generic-y += early_ioremap.h
 generic-y += emergency-restart.h
 generic-y += hw_irq.h
diff --git a/arch/arm64/include/asm/dma-mapping.h 
b/arch/arm64/include/asm/dma-mapping.h
deleted file mode 100644
index 67243255a858..
--- a/arch/arm64/include/asm/dma-mapping.h
+++ /dev/null
@@ -1,22 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * Copyright (C) 2012 ARM Ltd.
- */
-#ifndef __ASM_DMA_MAPPING_H
-#define __ASM_DMA_MAPPING_H
-
-#ifdef __KERNEL__
-
-#include 
-#include 
-
-#include 
-#include 
-
-static inline const struct dma_map_ops *get_arch_dma_ops(struct bus_type *bus)
-{
-   return NULL;
-}
-
-#endif /* __KERNEL__ */
-#endif /* __ASM_DMA_MAPPING_H */
diff --git a/arch/arm64/mm/dma-mapping.c b/arch/arm64/mm/dma-mapping.c
index 4b244a037349..6578abcfbbc7 100644
--- a/arch/arm64/mm/dma-mapping.c
+++ b/arch/arm64/mm/dma-mapping.c
@@ -8,6 +8,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 
 #include 
-- 
2.20.1



[PATCH 08/11] swiotlb-xen: simplify cache maintainance

2019-08-26 Thread Christoph Hellwig
Now that we know we always have the dma-noncoherent.h helpers available
if we are on an architecture with support for non-coherent devices,
we can just call them directly, and remove the calls to the dma-direct
routines, including the fact that we call the dma_direct_map_page
routines but ignore the value returned from it.  Instead we now have
Xen wrappers for the arch_sync_dma_for_{device,cpu} helpers that call
the special Xen versions of those routines for foreign pages.

Note that the new helpers get the physical address passed in addition
to the dma address to avoid another translation for the local cache
maintainance.  The pfn_valid checks remain on the dma address as in
the old code, even if that looks a little funny.

Signed-off-by: Christoph Hellwig 
---
 arch/arm/xen/mm.c| 64 ++
 arch/x86/include/asm/xen/page-coherent.h | 11 
 drivers/xen/swiotlb-xen.c| 20 +++
 include/xen/arm/page-coherent.h  | 69 ++--
 4 files changed, 31 insertions(+), 133 deletions(-)

diff --git a/arch/arm/xen/mm.c b/arch/arm/xen/mm.c
index b7d53415532b..7096652f5a1e 100644
--- a/arch/arm/xen/mm.c
+++ b/arch/arm/xen/mm.c
@@ -61,63 +61,33 @@ static void dma_cache_maint(dma_addr_t handle, size_t size, 
u32 op)
} while (size);
 }
 
-static void __xen_dma_page_dev_to_cpu(struct device *hwdev, dma_addr_t handle,
-   size_t size, enum dma_data_direction dir)
+/*
+ * Dom0 is mapped 1:1, and while the Linux page can span across multiple Xen
+ * pages, it is not possible for it to contain a mix of local and foreign Xen
+ * pages.  Calling pfn_valid on a foreign mfn will always return false, so if
+ * pfn_valid returns true the pages is local and we can use the native
+ * dma-direct functions, otherwise we call the Xen specific version.
+ */
+void xen_dma_sync_for_cpu(struct device *dev, dma_addr_t handle,
+   phys_addr_t paddr, size_t size, enum dma_data_direction dir)
 {
-   if (dir != DMA_TO_DEVICE)
+   if (pfn_valid(PFN_DOWN(handle)))
+   arch_sync_dma_for_cpu(dev, paddr, size, dir);
+   else if (dir != DMA_TO_DEVICE)
dma_cache_maint(handle, size, GNTTAB_CACHE_INVAL);
 }
 
-static void __xen_dma_page_cpu_to_dev(struct device *hwdev, dma_addr_t handle,
-   size_t size, enum dma_data_direction dir)
+void xen_dma_sync_for_device(struct device *dev, dma_addr_t handle,
+   phys_addr_t paddr, size_t size, enum dma_data_direction dir)
 {
-   if (dir == DMA_FROM_DEVICE)
+   if (pfn_valid(PFN_DOWN(handle)))
+   arch_sync_dma_for_device(dev, paddr, size, dir);
+   else if (dir == DMA_FROM_DEVICE)
dma_cache_maint(handle, size, GNTTAB_CACHE_INVAL);
else
dma_cache_maint(handle, size, GNTTAB_CACHE_CLEAN);
 }
 
-void __xen_dma_map_page(struct device *hwdev, struct page *page,
-dma_addr_t dev_addr, unsigned long offset, size_t size,
-enum dma_data_direction dir, unsigned long attrs)
-{
-   if (dev_is_dma_coherent(hwdev))
-   return;
-   if (attrs & DMA_ATTR_SKIP_CPU_SYNC)
-   return;
-
-   __xen_dma_page_cpu_to_dev(hwdev, dev_addr, size, dir);
-}
-
-void __xen_dma_unmap_page(struct device *hwdev, dma_addr_t handle,
-   size_t size, enum dma_data_direction dir,
-   unsigned long attrs)
-
-{
-   if (dev_is_dma_coherent(hwdev))
-   return;
-   if (attrs & DMA_ATTR_SKIP_CPU_SYNC)
-   return;
-
-   __xen_dma_page_dev_to_cpu(hwdev, handle, size, dir);
-}
-
-void __xen_dma_sync_single_for_cpu(struct device *hwdev,
-   dma_addr_t handle, size_t size, enum dma_data_direction dir)
-{
-   if (dev_is_dma_coherent(hwdev))
-   return;
-   __xen_dma_page_dev_to_cpu(hwdev, handle, size, dir);
-}
-
-void __xen_dma_sync_single_for_device(struct device *hwdev,
-   dma_addr_t handle, size_t size, enum dma_data_direction dir)
-{
-   if (dev_is_dma_coherent(hwdev))
-   return;
-   __xen_dma_page_cpu_to_dev(hwdev, handle, size, dir);
-}
-
 bool xen_arch_need_swiotlb(struct device *dev,
   phys_addr_t phys,
   dma_addr_t dev_addr)
diff --git a/arch/x86/include/asm/xen/page-coherent.h 
b/arch/x86/include/asm/xen/page-coherent.h
index 8ee33c5edded..c9c8398a31ff 100644
--- a/arch/x86/include/asm/xen/page-coherent.h
+++ b/arch/x86/include/asm/xen/page-coherent.h
@@ -2,17 +2,6 @@
 #ifndef _ASM_X86_XEN_PAGE_COHERENT_H
 #define _ASM_X86_XEN_PAGE_COHERENT_H
 
-#include 
-#include 
-
-static inline void xen_dma_map_page(struct device *hwdev, struct page *page,
-dma_addr_t dev_addr, unsigned long offset, size_t size,
-enum dma_data_direction dir, unsigned long attrs) { }
-
-static inline void xen_dma_unmap_page(struct device *hwdev, dma_addr_t handle,
-   size_t 

[PATCH 07/11] swiotlb-xen: use the same foreign page check everywhere

2019-08-26 Thread Christoph Hellwig
xen_dma_map_page uses a different and more complicated check for foreign
pages than the other three cache maintainance helpers.  Switch it to the
simpler pfn_valid method a well, and document the scheme with a single
improved comment in xen_dma_map_page.

Signed-off-by: Christoph Hellwig 
---
 include/xen/arm/page-coherent.h | 31 +--
 1 file changed, 9 insertions(+), 22 deletions(-)

diff --git a/include/xen/arm/page-coherent.h b/include/xen/arm/page-coherent.h
index 0e244f4fec1a..07c104dbc21f 100644
--- a/include/xen/arm/page-coherent.h
+++ b/include/xen/arm/page-coherent.h
@@ -41,23 +41,17 @@ static inline void xen_dma_map_page(struct device *hwdev, 
struct page *page,
 dma_addr_t dev_addr, unsigned long offset, size_t size,
 enum dma_data_direction dir, unsigned long attrs)
 {
-   unsigned long page_pfn = page_to_xen_pfn(page);
-   unsigned long dev_pfn = XEN_PFN_DOWN(dev_addr);
-   unsigned long compound_pages =
-   (1<

[PATCH 09/11] swiotlb-xen: remove page-coherent.h

2019-08-26 Thread Christoph Hellwig
The only thing left of page-coherent.h is two functions implemented by
the architecture for non-coherent DMA support that are never called for
fully coherent architectures.  Just move the prototypes for those to
swiotlb-xen.h instead.

Signed-off-by: Christoph Hellwig 
---
 arch/arm/include/asm/xen/page-coherent.h   |  2 --
 arch/arm64/include/asm/xen/page-coherent.h |  2 --
 arch/x86/include/asm/xen/page-coherent.h   | 11 ---
 drivers/xen/swiotlb-xen.c  |  3 ---
 include/Kbuild |  1 -
 include/xen/arm/page-coherent.h| 10 --
 include/xen/swiotlb-xen.h  |  6 ++
 7 files changed, 6 insertions(+), 29 deletions(-)
 delete mode 100644 arch/arm/include/asm/xen/page-coherent.h
 delete mode 100644 arch/arm64/include/asm/xen/page-coherent.h
 delete mode 100644 arch/x86/include/asm/xen/page-coherent.h
 delete mode 100644 include/xen/arm/page-coherent.h

diff --git a/arch/arm/include/asm/xen/page-coherent.h 
b/arch/arm/include/asm/xen/page-coherent.h
deleted file mode 100644
index 27e984977402..
--- a/arch/arm/include/asm/xen/page-coherent.h
+++ /dev/null
@@ -1,2 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#include 
diff --git a/arch/arm64/include/asm/xen/page-coherent.h 
b/arch/arm64/include/asm/xen/page-coherent.h
deleted file mode 100644
index 27e984977402..
--- a/arch/arm64/include/asm/xen/page-coherent.h
+++ /dev/null
@@ -1,2 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#include 
diff --git a/arch/x86/include/asm/xen/page-coherent.h 
b/arch/x86/include/asm/xen/page-coherent.h
deleted file mode 100644
index c9c8398a31ff..
--- a/arch/x86/include/asm/xen/page-coherent.h
+++ /dev/null
@@ -1,11 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef _ASM_X86_XEN_PAGE_COHERENT_H
-#define _ASM_X86_XEN_PAGE_COHERENT_H
-
-static inline void xen_dma_sync_single_for_cpu(struct device *hwdev,
-   dma_addr_t handle, size_t size, enum dma_data_direction dir) { }
-
-static inline void xen_dma_sync_single_for_device(struct device *hwdev,
-   dma_addr_t handle, size_t size, enum dma_data_direction dir) { }
-
-#endif /* _ASM_X86_XEN_PAGE_COHERENT_H */
diff --git a/drivers/xen/swiotlb-xen.c b/drivers/xen/swiotlb-xen.c
index a642e284f1e2..95911ff9c11c 100644
--- a/drivers/xen/swiotlb-xen.c
+++ b/drivers/xen/swiotlb-xen.c
@@ -35,9 +35,6 @@
 #include 
 #include 
 
-#include 
-#include 
-
 #include 
 /*
  * Used to do a quick range check in swiotlb_tbl_unmap_single and
diff --git a/include/Kbuild b/include/Kbuild
index c38f0d46b267..cce5cf6abf89 100644
--- a/include/Kbuild
+++ b/include/Kbuild
@@ -1189,7 +1189,6 @@ header-test-  += video/vga.h
 header-test-   += video/w100fb.h
 header-test-   += xen/acpi.h
 header-test-   += xen/arm/hypercall.h
-header-test-   += xen/arm/page-coherent.h
 header-test-   += xen/arm/page.h
 header-test-   += xen/balloon.h
 header-test-   += xen/events.h
diff --git a/include/xen/arm/page-coherent.h b/include/xen/arm/page-coherent.h
deleted file mode 100644
index 635492d41ebe..
--- a/include/xen/arm/page-coherent.h
+++ /dev/null
@@ -1,10 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef _XEN_ARM_PAGE_COHERENT_H
-#define _XEN_ARM_PAGE_COHERENT_H
-
-void xen_dma_sync_for_cpu(struct device *dev, dma_addr_t handle,
-   phys_addr_t paddr, size_t size, enum dma_data_direction dir);
-void xen_dma_sync_for_device(struct device *dev, dma_addr_t handle,
-   phys_addr_t paddr, size_t size, enum dma_data_direction dir);
-
-#endif /* _XEN_ARM_PAGE_COHERENT_H */
diff --git a/include/xen/swiotlb-xen.h b/include/xen/swiotlb-xen.h
index 5e4b83f83dbc..a7c642872568 100644
--- a/include/xen/swiotlb-xen.h
+++ b/include/xen/swiotlb-xen.h
@@ -2,8 +2,14 @@
 #ifndef __LINUX_SWIOTLB_XEN_H
 #define __LINUX_SWIOTLB_XEN_H
 
+#include 
 #include 
 
+void xen_dma_sync_for_cpu(struct device *dev, dma_addr_t handle,
+   phys_addr_t paddr, size_t size, enum dma_data_direction dir);
+void xen_dma_sync_for_device(struct device *dev, dma_addr_t handle,
+   phys_addr_t paddr, size_t size, enum dma_data_direction dir);
+
 extern int xen_swiotlb_init(int verbose, bool early);
 extern const struct dma_map_ops xen_swiotlb_dma_ops;
 
-- 
2.20.1



swiotlb-xen cleanups v2

2019-08-26 Thread Christoph Hellwig
Hi Xen maintainers and friends,

please take a look at this series that cleans up the parts of swiotlb-xen
that deal with non-coherent caches.

Changes since v1:
 - rewrite dma_cache_maint to be much simpler
 - improve various comments and commit logs
 - remove page-coherent.h entirely


[PATCH 10/11] swiotlb-xen: merge xen_unmap_single into xen_swiotlb_unmap_page

2019-08-26 Thread Christoph Hellwig
No need for a no-op wrapper.

Signed-off-by: Christoph Hellwig 
---
 drivers/xen/swiotlb-xen.c | 15 ---
 1 file changed, 4 insertions(+), 11 deletions(-)

diff --git a/drivers/xen/swiotlb-xen.c b/drivers/xen/swiotlb-xen.c
index 95911ff9c11c..384304a77020 100644
--- a/drivers/xen/swiotlb-xen.c
+++ b/drivers/xen/swiotlb-xen.c
@@ -414,9 +414,8 @@ static dma_addr_t xen_swiotlb_map_page(struct device *dev, 
struct page *page,
  * After this call, reads by the cpu to the buffer are guaranteed to see
  * whatever the device wrote there.
  */
-static void xen_unmap_single(struct device *hwdev, dma_addr_t dev_addr,
-size_t size, enum dma_data_direction dir,
-unsigned long attrs)
+static void xen_swiotlb_unmap_page(struct device *hwdev, dma_addr_t dev_addr,
+   size_t size, enum dma_data_direction dir, unsigned long attrs)
 {
phys_addr_t paddr = xen_bus_to_phys(dev_addr);
 
@@ -430,13 +429,6 @@ static void xen_unmap_single(struct device *hwdev, 
dma_addr_t dev_addr,
swiotlb_tbl_unmap_single(hwdev, paddr, size, dir, attrs);
 }
 
-static void xen_swiotlb_unmap_page(struct device *hwdev, dma_addr_t dev_addr,
-   size_t size, enum dma_data_direction dir,
-   unsigned long attrs)
-{
-   xen_unmap_single(hwdev, dev_addr, size, dir, attrs);
-}
-
 static void
 xen_swiotlb_sync_single_for_cpu(struct device *dev, dma_addr_t dma_addr,
size_t size, enum dma_data_direction dir)
@@ -477,7 +469,8 @@ xen_swiotlb_unmap_sg(struct device *hwdev, struct 
scatterlist *sgl, int nelems,
BUG_ON(dir == DMA_NONE);
 
for_each_sg(sgl, sg, nelems, i)
-   xen_unmap_single(hwdev, sg->dma_address, sg_dma_len(sg), dir, 
attrs);
+   xen_swiotlb_unmap_page(hwdev, sg->dma_address, sg_dma_len(sg),
+   dir, attrs);
 
 }
 
-- 
2.20.1



[PATCH 03/11] xen/arm: simplify dma_cache_maint

2019-08-26 Thread Christoph Hellwig
Calculate the required operation in the caller, and pass it directly
instead of recalculating it for each page, and use simple arithmetics
to get from the physical address to Xen page size aligned chunks.

Signed-off-by: Christoph Hellwig 
---
 arch/arm/xen/mm.c | 62 +--
 1 file changed, 22 insertions(+), 40 deletions(-)

diff --git a/arch/arm/xen/mm.c b/arch/arm/xen/mm.c
index 90574d89d0d4..14210ebdea1a 100644
--- a/arch/arm/xen/mm.c
+++ b/arch/arm/xen/mm.c
@@ -35,64 +35,46 @@ unsigned long xen_get_swiotlb_free_pages(unsigned int order)
return __get_free_pages(flags, order);
 }
 
-enum dma_cache_op {
-   DMA_UNMAP,
-   DMA_MAP,
-};
 static bool hypercall_cflush = false;
 
-/* functions called by SWIOTLB */
-
-static void dma_cache_maint(dma_addr_t handle, unsigned long offset,
-   size_t size, enum dma_data_direction dir, enum dma_cache_op op)
+/* buffers in highmem or foreign pages cannot cross page boundaries */
+static void dma_cache_maint(dma_addr_t handle, size_t size, u32 op)
 {
struct gnttab_cache_flush cflush;
-   unsigned long xen_pfn;
-   size_t left = size;
 
-   xen_pfn = (handle >> XEN_PAGE_SHIFT) + offset / XEN_PAGE_SIZE;
-   offset %= XEN_PAGE_SIZE;
+   cflush.a.dev_bus_addr = handle & XEN_PAGE_MASK;
+   cflush.offset = xen_offset_in_page(handle);
+   cflush.op = op;
 
do {
-   size_t len = left;
-   
-   /* buffers in highmem or foreign pages cannot cross page
-* boundaries */
-   if (len + offset > XEN_PAGE_SIZE)
-   len = XEN_PAGE_SIZE - offset;
-
-   cflush.op = 0;
-   cflush.a.dev_bus_addr = xen_pfn << XEN_PAGE_SHIFT;
-   cflush.offset = offset;
-   cflush.length = len;
-
-   if (op == DMA_UNMAP && dir != DMA_TO_DEVICE)
-   cflush.op = GNTTAB_CACHE_INVAL;
-   if (op == DMA_MAP) {
-   if (dir == DMA_FROM_DEVICE)
-   cflush.op = GNTTAB_CACHE_INVAL;
-   else
-   cflush.op = GNTTAB_CACHE_CLEAN;
-   }
-   if (cflush.op)
-   HYPERVISOR_grant_table_op(GNTTABOP_cache_flush, 
, 1);
+   if (size + cflush.offset > XEN_PAGE_SIZE)
+   cflush.length = XEN_PAGE_SIZE - cflush.offset;
+   else
+   cflush.length = size;
+
+   HYPERVISOR_grant_table_op(GNTTABOP_cache_flush, , 1);
+
+   handle += cflush.length;
+   size -= cflush.length;
 
-   offset = 0;
-   xen_pfn++;
-   left -= len;
-   } while (left);
+   cflush.offset = 0;
+   } while (size);
 }
 
 static void __xen_dma_page_dev_to_cpu(struct device *hwdev, dma_addr_t handle,
size_t size, enum dma_data_direction dir)
 {
-   dma_cache_maint(handle & PAGE_MASK, handle & ~PAGE_MASK, size, dir, 
DMA_UNMAP);
+   if (dir != DMA_TO_DEVICE)
+   dma_cache_maint(handle, size, GNTTAB_CACHE_INVAL);
 }
 
 static void __xen_dma_page_cpu_to_dev(struct device *hwdev, dma_addr_t handle,
size_t size, enum dma_data_direction dir)
 {
-   dma_cache_maint(handle & PAGE_MASK, handle & ~PAGE_MASK, size, dir, 
DMA_MAP);
+   if (dir == DMA_FROM_DEVICE)
+   dma_cache_maint(handle, size, GNTTAB_CACHE_INVAL);
+   else
+   dma_cache_maint(handle, size, GNTTAB_CACHE_CLEAN);
 }
 
 void __xen_dma_map_page(struct device *hwdev, struct page *page,
-- 
2.20.1



[PATCH 05/11] xen: remove the exports for xen_{create,destroy}_contiguous_region

2019-08-26 Thread Christoph Hellwig
These routines are only used by swiotlb-xen, which cannot be modular.

Signed-off-by: Christoph Hellwig 
---
 arch/arm/xen/mm.c | 2 --
 arch/x86/xen/mmu_pv.c | 2 --
 2 files changed, 4 deletions(-)

diff --git a/arch/arm/xen/mm.c b/arch/arm/xen/mm.c
index 9b3a6c0ca681..b7d53415532b 100644
--- a/arch/arm/xen/mm.c
+++ b/arch/arm/xen/mm.c
@@ -155,13 +155,11 @@ int xen_create_contiguous_region(phys_addr_t pstart, 
unsigned int order,
*dma_handle = pstart;
return 0;
 }
-EXPORT_SYMBOL_GPL(xen_create_contiguous_region);
 
 void xen_destroy_contiguous_region(phys_addr_t pstart, unsigned int order)
 {
return;
 }
-EXPORT_SYMBOL_GPL(xen_destroy_contiguous_region);
 
 int __init xen_mm_init(void)
 {
diff --git a/arch/x86/xen/mmu_pv.c b/arch/x86/xen/mmu_pv.c
index 26e8b326966d..c8dbee62ec2a 100644
--- a/arch/x86/xen/mmu_pv.c
+++ b/arch/x86/xen/mmu_pv.c
@@ -2625,7 +2625,6 @@ int xen_create_contiguous_region(phys_addr_t pstart, 
unsigned int order,
*dma_handle = virt_to_machine(vstart).maddr;
return success ? 0 : -ENOMEM;
 }
-EXPORT_SYMBOL_GPL(xen_create_contiguous_region);
 
 void xen_destroy_contiguous_region(phys_addr_t pstart, unsigned int order)
 {
@@ -2660,7 +2659,6 @@ void xen_destroy_contiguous_region(phys_addr_t pstart, 
unsigned int order)
 
spin_unlock_irqrestore(_reservation_lock, flags);
 }
-EXPORT_SYMBOL_GPL(xen_destroy_contiguous_region);
 
 static noinline void xen_flush_tlb_all(void)
 {
-- 
2.20.1



[PATCH 06/11] swiotlb-xen: always use dma-direct helpers to alloc coherent pages

2019-08-26 Thread Christoph Hellwig
x86 currently calls alloc_pages, but using dma-direct works as well
there, with the added benefit of using the CMA pool if available.
The biggest advantage is of course to remove a pointless bit of
architecture specific code.

Signed-off-by: Christoph Hellwig 
---
 arch/x86/include/asm/xen/page-coherent.h | 16 
 drivers/xen/swiotlb-xen.c|  7 +++
 include/xen/arm/page-coherent.h  | 12 
 3 files changed, 3 insertions(+), 32 deletions(-)

diff --git a/arch/x86/include/asm/xen/page-coherent.h 
b/arch/x86/include/asm/xen/page-coherent.h
index 116777e7f387..8ee33c5edded 100644
--- a/arch/x86/include/asm/xen/page-coherent.h
+++ b/arch/x86/include/asm/xen/page-coherent.h
@@ -5,22 +5,6 @@
 #include 
 #include 
 
-static inline void *xen_alloc_coherent_pages(struct device *hwdev, size_t size,
-   dma_addr_t *dma_handle, gfp_t flags,
-   unsigned long attrs)
-{
-   void *vstart = (void*)__get_free_pages(flags, get_order(size));
-   *dma_handle = virt_to_phys(vstart);
-   return vstart;
-}
-
-static inline void xen_free_coherent_pages(struct device *hwdev, size_t size,
-   void *cpu_addr, dma_addr_t dma_handle,
-   unsigned long attrs)
-{
-   free_pages((unsigned long) cpu_addr, get_order(size));
-}
-
 static inline void xen_dma_map_page(struct device *hwdev, struct page *page,
 dma_addr_t dev_addr, unsigned long offset, size_t size,
 enum dma_data_direction dir, unsigned long attrs) { }
diff --git a/drivers/xen/swiotlb-xen.c b/drivers/xen/swiotlb-xen.c
index b8808677ae1d..f9dd4cb6e4b3 100644
--- a/drivers/xen/swiotlb-xen.c
+++ b/drivers/xen/swiotlb-xen.c
@@ -299,8 +299,7 @@ xen_swiotlb_alloc_coherent(struct device *hwdev, size_t 
size,
 * address. In fact on ARM virt_to_phys only works for kernel direct
 * mapped RAM memory. Also see comment below.
 */
-   ret = xen_alloc_coherent_pages(hwdev, size, dma_handle, flags, attrs);
-
+   ret = dma_direct_alloc(hwdev, size, dma_handle, flags, attrs);
if (!ret)
return ret;
 
@@ -319,7 +318,7 @@ xen_swiotlb_alloc_coherent(struct device *hwdev, size_t 
size,
else {
if (xen_create_contiguous_region(phys, order,
 fls64(dma_mask), dma_handle) 
!= 0) {
-   xen_free_coherent_pages(hwdev, size, ret, 
(dma_addr_t)phys, attrs);
+   dma_direct_free(hwdev, size, ret, (dma_addr_t)phys, 
attrs);
return NULL;
}
SetPageXenRemapped(virt_to_page(ret));
@@ -351,7 +350,7 @@ xen_swiotlb_free_coherent(struct device *hwdev, size_t 
size, void *vaddr,
TestClearPageXenRemapped(virt_to_page(vaddr)))
xen_destroy_contiguous_region(phys, order);
 
-   xen_free_coherent_pages(hwdev, size, vaddr, (dma_addr_t)phys, attrs);
+   dma_direct_free(hwdev, size, vaddr, (dma_addr_t)phys, attrs);
 }
 
 /*
diff --git a/include/xen/arm/page-coherent.h b/include/xen/arm/page-coherent.h
index a840d6949a87..0e244f4fec1a 100644
--- a/include/xen/arm/page-coherent.h
+++ b/include/xen/arm/page-coherent.h
@@ -16,18 +16,6 @@ void __xen_dma_sync_single_for_cpu(struct device *hwdev,
 void __xen_dma_sync_single_for_device(struct device *hwdev,
dma_addr_t handle, size_t size, enum dma_data_direction dir);
 
-static inline void *xen_alloc_coherent_pages(struct device *hwdev, size_t size,
-   dma_addr_t *dma_handle, gfp_t flags, unsigned long attrs)
-{
-   return dma_direct_alloc(hwdev, size, dma_handle, flags, attrs);
-}
-
-static inline void xen_free_coherent_pages(struct device *hwdev, size_t size,
-   void *cpu_addr, dma_addr_t dma_handle, unsigned long attrs)
-{
-   dma_direct_free(hwdev, size, cpu_addr, dma_handle, attrs);
-}
-
 static inline void xen_dma_sync_single_for_cpu(struct device *hwdev,
dma_addr_t handle, size_t size, enum dma_data_direction dir)
 {
-- 
2.20.1



[PATCH 04/11] xen/arm: remove xen_dma_ops

2019-08-26 Thread Christoph Hellwig
arm and arm64 can just use xen_swiotlb_dma_ops directly like x86, no
need for a pointer indirection.

Signed-off-by: Christoph Hellwig 
Reviewed-by: Julien Grall 
---
 arch/arm/mm/dma-mapping.c| 3 ++-
 arch/arm/xen/mm.c| 4 
 arch/arm64/mm/dma-mapping.c  | 3 ++-
 include/xen/arm/hypervisor.h | 2 --
 4 files changed, 4 insertions(+), 8 deletions(-)

diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
index 738097396445..2661cad36359 100644
--- a/arch/arm/mm/dma-mapping.c
+++ b/arch/arm/mm/dma-mapping.c
@@ -35,6 +35,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "dma.h"
 #include "mm.h"
@@ -2360,7 +2361,7 @@ void arch_setup_dma_ops(struct device *dev, u64 dma_base, 
u64 size,
 
 #ifdef CONFIG_XEN
if (xen_initial_domain())
-   dev->dma_ops = xen_dma_ops;
+   dev->dma_ops = _swiotlb_dma_ops;
 #endif
dev->archdata.dma_ops_setup = true;
 }
diff --git a/arch/arm/xen/mm.c b/arch/arm/xen/mm.c
index 14210ebdea1a..9b3a6c0ca681 100644
--- a/arch/arm/xen/mm.c
+++ b/arch/arm/xen/mm.c
@@ -163,16 +163,12 @@ void xen_destroy_contiguous_region(phys_addr_t pstart, 
unsigned int order)
 }
 EXPORT_SYMBOL_GPL(xen_destroy_contiguous_region);
 
-const struct dma_map_ops *xen_dma_ops;
-EXPORT_SYMBOL(xen_dma_ops);
-
 int __init xen_mm_init(void)
 {
struct gnttab_cache_flush cflush;
if (!xen_initial_domain())
return 0;
xen_swiotlb_init(1, false);
-   xen_dma_ops = _swiotlb_dma_ops;
 
cflush.op = 0;
cflush.a.dev_bus_addr = 0;
diff --git a/arch/arm64/mm/dma-mapping.c b/arch/arm64/mm/dma-mapping.c
index bd2b039f43a6..4b244a037349 100644
--- a/arch/arm64/mm/dma-mapping.c
+++ b/arch/arm64/mm/dma-mapping.c
@@ -8,6 +8,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 
@@ -64,6 +65,6 @@ void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 
size,
 
 #ifdef CONFIG_XEN
if (xen_initial_domain())
-   dev->dma_ops = xen_dma_ops;
+   dev->dma_ops = _swiotlb_dma_ops;
 #endif
 }
diff --git a/include/xen/arm/hypervisor.h b/include/xen/arm/hypervisor.h
index 2982571f7cc1..43ef24dd030e 100644
--- a/include/xen/arm/hypervisor.h
+++ b/include/xen/arm/hypervisor.h
@@ -19,8 +19,6 @@ static inline enum paravirt_lazy_mode 
paravirt_get_lazy_mode(void)
return PARAVIRT_LAZY_NONE;
 }
 
-extern const struct dma_map_ops *xen_dma_ops;
-
 #ifdef CONFIG_XEN
 void __init xen_early_init(void);
 #else
-- 
2.20.1



[PATCH 01/11] xen/arm: use dma-noncoherent.h calls for xen-swiotlb cache maintainance

2019-08-26 Thread Christoph Hellwig
Reuse the arm64 code that uses the dma-direct/swiotlb helpers for DMA
non-coherent devices.

Signed-off-by: Christoph Hellwig 
---
 arch/arm/include/asm/device.h  |  3 -
 arch/arm/include/asm/xen/page-coherent.h   | 93 --
 arch/arm/mm/dma-mapping.c  |  8 +-
 arch/arm64/include/asm/xen/page-coherent.h | 75 -
 drivers/xen/swiotlb-xen.c  | 49 +---
 include/xen/arm/page-coherent.h| 80 +++
 6 files changed, 83 insertions(+), 225 deletions(-)

diff --git a/arch/arm/include/asm/device.h b/arch/arm/include/asm/device.h
index f6955b55c544..c675bc0d5aa8 100644
--- a/arch/arm/include/asm/device.h
+++ b/arch/arm/include/asm/device.h
@@ -14,9 +14,6 @@ struct dev_archdata {
 #endif
 #ifdef CONFIG_ARM_DMA_USE_IOMMU
struct dma_iommu_mapping*mapping;
-#endif
-#ifdef CONFIG_XEN
-   const struct dma_map_ops *dev_dma_ops;
 #endif
unsigned int dma_coherent:1;
unsigned int dma_ops_setup:1;
diff --git a/arch/arm/include/asm/xen/page-coherent.h 
b/arch/arm/include/asm/xen/page-coherent.h
index 2c403e7c782d..27e984977402 100644
--- a/arch/arm/include/asm/xen/page-coherent.h
+++ b/arch/arm/include/asm/xen/page-coherent.h
@@ -1,95 +1,2 @@
 /* SPDX-License-Identifier: GPL-2.0 */
-#ifndef _ASM_ARM_XEN_PAGE_COHERENT_H
-#define _ASM_ARM_XEN_PAGE_COHERENT_H
-
-#include 
-#include 
 #include 
-
-static inline const struct dma_map_ops *xen_get_dma_ops(struct device *dev)
-{
-   if (dev && dev->archdata.dev_dma_ops)
-   return dev->archdata.dev_dma_ops;
-   return get_arch_dma_ops(NULL);
-}
-
-static inline void *xen_alloc_coherent_pages(struct device *hwdev, size_t size,
-   dma_addr_t *dma_handle, gfp_t flags, unsigned long attrs)
-{
-   return xen_get_dma_ops(hwdev)->alloc(hwdev, size, dma_handle, flags, 
attrs);
-}
-
-static inline void xen_free_coherent_pages(struct device *hwdev, size_t size,
-   void *cpu_addr, dma_addr_t dma_handle, unsigned long attrs)
-{
-   xen_get_dma_ops(hwdev)->free(hwdev, size, cpu_addr, dma_handle, attrs);
-}
-
-static inline void xen_dma_map_page(struct device *hwdev, struct page *page,
-dma_addr_t dev_addr, unsigned long offset, size_t size,
-enum dma_data_direction dir, unsigned long attrs)
-{
-   unsigned long page_pfn = page_to_xen_pfn(page);
-   unsigned long dev_pfn = XEN_PFN_DOWN(dev_addr);
-   unsigned long compound_pages =
-   (1unmap_page)
-   xen_get_dma_ops(hwdev)->unmap_page(hwdev, handle, size, 
dir, attrs);
-   } else
-   __xen_dma_unmap_page(hwdev, handle, size, dir, attrs);
-}
-
-static inline void xen_dma_sync_single_for_cpu(struct device *hwdev,
-   dma_addr_t handle, size_t size, enum dma_data_direction dir)
-{
-   unsigned long pfn = PFN_DOWN(handle);
-   if (pfn_valid(pfn)) {
-   if (xen_get_dma_ops(hwdev)->sync_single_for_cpu)
-   xen_get_dma_ops(hwdev)->sync_single_for_cpu(hwdev, 
handle, size, dir);
-   } else
-   __xen_dma_sync_single_for_cpu(hwdev, handle, size, dir);
-}
-
-static inline void xen_dma_sync_single_for_device(struct device *hwdev,
-   dma_addr_t handle, size_t size, enum dma_data_direction dir)
-{
-   unsigned long pfn = PFN_DOWN(handle);
-   if (pfn_valid(pfn)) {
-   if (xen_get_dma_ops(hwdev)->sync_single_for_device)
-   xen_get_dma_ops(hwdev)->sync_single_for_device(hwdev, 
handle, size, dir);
-   } else
-   __xen_dma_sync_single_for_device(hwdev, handle, size, dir);
-}
-
-#endif /* _ASM_ARM_XEN_PAGE_COHERENT_H */
diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
index d42557ee69c2..738097396445 100644
--- a/arch/arm/mm/dma-mapping.c
+++ b/arch/arm/mm/dma-mapping.c
@@ -1132,10 +1132,6 @@ static const struct dma_map_ops 
*arm_get_dma_map_ops(bool coherent)
 * 32-bit DMA.
 * Use the generic dma-direct / swiotlb ops code in that case, as that
 * handles 

[PATCH 02/11] xen/arm: use dev_is_dma_coherent

2019-08-26 Thread Christoph Hellwig
Use the dma-noncoherent dev_is_dma_coherent helper instead of the home
grown variant.  Note that both are always initialized to the same
value in arch_setup_dma_ops.

Signed-off-by: Christoph Hellwig 
Reviewed-by: Julien Grall 
---
 arch/arm/include/asm/dma-mapping.h   |  6 --
 arch/arm/xen/mm.c| 12 ++--
 arch/arm64/include/asm/dma-mapping.h |  9 -
 3 files changed, 6 insertions(+), 21 deletions(-)

diff --git a/arch/arm/include/asm/dma-mapping.h 
b/arch/arm/include/asm/dma-mapping.h
index dba9355e2484..bdd80ddbca34 100644
--- a/arch/arm/include/asm/dma-mapping.h
+++ b/arch/arm/include/asm/dma-mapping.h
@@ -91,12 +91,6 @@ static inline dma_addr_t virt_to_dma(struct device *dev, 
void *addr)
 }
 #endif
 
-/* do not use this function in a driver */
-static inline bool is_device_dma_coherent(struct device *dev)
-{
-   return dev->archdata.dma_coherent;
-}
-
 /**
  * arm_dma_alloc - allocate consistent memory for DMA
  * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
diff --git a/arch/arm/xen/mm.c b/arch/arm/xen/mm.c
index d33b77e9add3..90574d89d0d4 100644
--- a/arch/arm/xen/mm.c
+++ b/arch/arm/xen/mm.c
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0-only
 #include 
-#include 
+#include 
 #include 
 #include 
 #include 
@@ -99,7 +99,7 @@ void __xen_dma_map_page(struct device *hwdev, struct page 
*page,
 dma_addr_t dev_addr, unsigned long offset, size_t size,
 enum dma_data_direction dir, unsigned long attrs)
 {
-   if (is_device_dma_coherent(hwdev))
+   if (dev_is_dma_coherent(hwdev))
return;
if (attrs & DMA_ATTR_SKIP_CPU_SYNC)
return;
@@ -112,7 +112,7 @@ void __xen_dma_unmap_page(struct device *hwdev, dma_addr_t 
handle,
unsigned long attrs)
 
 {
-   if (is_device_dma_coherent(hwdev))
+   if (dev_is_dma_coherent(hwdev))
return;
if (attrs & DMA_ATTR_SKIP_CPU_SYNC)
return;
@@ -123,7 +123,7 @@ void __xen_dma_unmap_page(struct device *hwdev, dma_addr_t 
handle,
 void __xen_dma_sync_single_for_cpu(struct device *hwdev,
dma_addr_t handle, size_t size, enum dma_data_direction dir)
 {
-   if (is_device_dma_coherent(hwdev))
+   if (dev_is_dma_coherent(hwdev))
return;
__xen_dma_page_dev_to_cpu(hwdev, handle, size, dir);
 }
@@ -131,7 +131,7 @@ void __xen_dma_sync_single_for_cpu(struct device *hwdev,
 void __xen_dma_sync_single_for_device(struct device *hwdev,
dma_addr_t handle, size_t size, enum dma_data_direction dir)
 {
-   if (is_device_dma_coherent(hwdev))
+   if (dev_is_dma_coherent(hwdev))
return;
__xen_dma_page_cpu_to_dev(hwdev, handle, size, dir);
 }
@@ -159,7 +159,7 @@ bool xen_arch_need_swiotlb(struct device *dev,
 * memory and we are not able to flush the cache.
 */
return (!hypercall_cflush && (xen_pfn != bfn) &&
-   !is_device_dma_coherent(dev));
+   !dev_is_dma_coherent(dev));
 }
 
 int xen_create_contiguous_region(phys_addr_t pstart, unsigned int order,
diff --git a/arch/arm64/include/asm/dma-mapping.h 
b/arch/arm64/include/asm/dma-mapping.h
index bdcb0922a40c..67243255a858 100644
--- a/arch/arm64/include/asm/dma-mapping.h
+++ b/arch/arm64/include/asm/dma-mapping.h
@@ -18,14 +18,5 @@ static inline const struct dma_map_ops 
*get_arch_dma_ops(struct bus_type *bus)
return NULL;
 }
 
-/*
- * Do not use this function in a driver, it is only provided for
- * arch/arm/mm/xen.c, which is used by arm64 as well.
- */
-static inline bool is_device_dma_coherent(struct device *dev)
-{
-   return dev->dma_coherent;
-}
-
 #endif /* __KERNEL__ */
 #endif /* __ASM_DMA_MAPPING_H */
-- 
2.20.1



Re: [PATCH v2 09/11] dma-direct: turn ARCH_ZONE_DMA_BITS into a variable

2019-08-26 Thread Michael Ellerman
Nicolas Saenz Julienne  writes:
> diff --git a/arch/powerpc/include/asm/page.h b/arch/powerpc/include/asm/page.h
> index 0d52f57fca04..73668a21ae78 100644
> --- a/arch/powerpc/include/asm/page.h
> +++ b/arch/powerpc/include/asm/page.h
> @@ -319,13 +319,4 @@ struct vm_area_struct;
>  #endif /* __ASSEMBLY__ */
>  #include 
>  
> -/*
> - * Allow 30-bit DMA for very limited Broadcom wifi chips on many powerbooks.

This comment got lost.

> diff --git a/arch/powerpc/mm/mem.c b/arch/powerpc/mm/mem.c
> index 9191a66b3bc5..2a69f87585df 100644
> --- a/arch/powerpc/mm/mem.c
> +++ b/arch/powerpc/mm/mem.c
> @@ -237,9 +238,14 @@ void __init paging_init(void)
>   printk(KERN_DEBUG "Memory hole size: %ldMB\n",
>  (long int)((top_of_ram - total_ram) >> 20));
>  
> + if (IS_ENABLED(CONFIG_PPC32))

Can you please propagate it here?

> + zone_dma_bits = 30;
> + else
> + zone_dma_bits = 31;
> +

cheers


Re: [PATCH v2 10/11] arm64: edit zone_dma_bits to fine tune dma-direct min mask

2019-08-26 Thread Nicolas Saenz Julienne
On Mon, 2019-08-26 at 09:06 +0200, Christoph Hellwig wrote:
> On Tue, Aug 20, 2019 at 04:58:18PM +0200, Nicolas Saenz Julienne wrote:
> > -   if (IS_ENABLED(CONFIG_ZONE_DMA))
> > +   if (IS_ENABLED(CONFIG_ZONE_DMA)) {
> > arm64_dma_phys_limit = max_zone_dma_phys();
> > +   zone_dma_bits = ilog2((arm64_dma_phys_limit - 1) &
> > GENMASK_ULL(31, 0)) + 1;
>
Hi Christoph,
thanks for the rewiews.

> This adds a way too long line.

I know, I couldn't find a way to split the operation without making it even
harder to read. I'll find a solution.

> I also find the use of GENMASK_ULL
> horribly obsfucating, but I know that opinion is't shared by everyone.

Don't have any preference so I'll happily change it. Any suggestions? Using the
explicit 0xULL seems hard to read, how about SZ_4GB - 1?



signature.asc
Description: This is a digitally signed message part


Re: [Xen-devel] [PATCH 01/11] xen/arm: use dma-noncoherent.h calls for xen-swiotlb cache maintainance

2019-08-26 Thread Christoph Hellwig
On Mon, Aug 19, 2019 at 12:45:17PM +0100, Julien Grall wrote:
> On 8/16/19 2:00 PM, Christoph Hellwig wrote:
>> +static inline void xen_dma_map_page(struct device *hwdev, struct page *page,
>> + dma_addr_t dev_addr, unsigned long offset, size_t size,
>> + enum dma_data_direction dir, unsigned long attrs)
>> +{
>> +unsigned long page_pfn = page_to_xen_pfn(page);
>> +unsigned long dev_pfn = XEN_PFN_DOWN(dev_addr);
>> +unsigned long compound_pages =
>> +(1<> +bool local = (page_pfn <= dev_pfn) &&
>> +(dev_pfn - page_pfn < compound_pages);
>> +
>
> The Arm version as a comment here. Could we retain it?

I've added it in this patch, altough the rewrites later on mean it will
go away in favour of a new comment elsewhere anyway.


[PATCH 1/1] Revert "iommu/vt-d: Avoid duplicated pci dma alias consideration"

2019-08-26 Thread Lu Baolu
This reverts commit 557529494d79f3f1fadd486dd18d2de0b19be4da.

Commit 557529494d79f ("iommu/vt-d: Avoid duplicated pci dma alias
consideration") aimed to address a NULL pointer deference issue
happened when a thunderbolt device driver returned unexpectedly.

Unfortunately, this change breaks a previous pci quirk added by
commit cc346a4714a59 ("PCI: Add function 1 DMA alias quirk for
Marvell devices"), as the result, devices like Marvell 88SE9128
SATA controller doesn't work anymore.

We will continue to try to find the real culprit mentioned in
557529494d79f, but for now we should revert it to fix current
breakage.

Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=204627
Cc: Stijn Tintel 
Cc: Petr Vandrovec 
Reported-by: Stijn Tintel 
Reported-by: Petr Vandrovec 
Signed-off-by: Lu Baolu 
---
 drivers/iommu/intel-iommu.c | 55 +++--
 1 file changed, 53 insertions(+), 2 deletions(-)

diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c
index 12d094d08c0a..c4e0e4a9ee9e 100644
--- a/drivers/iommu/intel-iommu.c
+++ b/drivers/iommu/intel-iommu.c
@@ -339,6 +339,8 @@ static void domain_exit(struct dmar_domain *domain);
 static void domain_remove_dev_info(struct dmar_domain *domain);
 static void dmar_remove_one_dev_info(struct device *dev);
 static void __dmar_remove_one_dev_info(struct device_domain_info *info);
+static void domain_context_clear(struct intel_iommu *iommu,
+struct device *dev);
 static int domain_detach_iommu(struct dmar_domain *domain,
   struct intel_iommu *iommu);
 static bool device_is_rmrr_locked(struct device *dev);
@@ -2105,9 +2107,26 @@ static int domain_context_mapping_one(struct dmar_domain 
*domain,
return ret;
 }
 
+struct domain_context_mapping_data {
+   struct dmar_domain *domain;
+   struct intel_iommu *iommu;
+   struct pasid_table *table;
+};
+
+static int domain_context_mapping_cb(struct pci_dev *pdev,
+u16 alias, void *opaque)
+{
+   struct domain_context_mapping_data *data = opaque;
+
+   return domain_context_mapping_one(data->domain, data->iommu,
+ data->table, PCI_BUS_NUM(alias),
+ alias & 0xff);
+}
+
 static int
 domain_context_mapping(struct dmar_domain *domain, struct device *dev)
 {
+   struct domain_context_mapping_data data;
struct pasid_table *table;
struct intel_iommu *iommu;
u8 bus, devfn;
@@ -2117,7 +2136,17 @@ domain_context_mapping(struct dmar_domain *domain, 
struct device *dev)
return -ENODEV;
 
table = intel_pasid_get_table(dev);
-   return domain_context_mapping_one(domain, iommu, table, bus, devfn);
+
+   if (!dev_is_pci(dev))
+   return domain_context_mapping_one(domain, iommu, table,
+ bus, devfn);
+
+   data.domain = domain;
+   data.iommu = iommu;
+   data.table = table;
+
+   return pci_for_each_dma_alias(to_pci_dev(dev),
+ _context_mapping_cb, );
 }
 
 static int domain_context_mapped_cb(struct pci_dev *pdev,
@@ -4759,6 +4788,28 @@ int __init intel_iommu_init(void)
return ret;
 }
 
+static int domain_context_clear_one_cb(struct pci_dev *pdev, u16 alias, void 
*opaque)
+{
+   struct intel_iommu *iommu = opaque;
+
+   domain_context_clear_one(iommu, PCI_BUS_NUM(alias), alias & 0xff);
+   return 0;
+}
+
+/*
+ * NB - intel-iommu lacks any sort of reference counting for the users of
+ * dependent devices.  If multiple endpoints have intersecting dependent
+ * devices, unbinding the driver from any one of them will possibly leave
+ * the others unable to operate.
+ */
+static void domain_context_clear(struct intel_iommu *iommu, struct device *dev)
+{
+   if (!iommu || !dev || !dev_is_pci(dev))
+   return;
+
+   pci_for_each_dma_alias(to_pci_dev(dev), _context_clear_one_cb, 
iommu);
+}
+
 static void __dmar_remove_one_dev_info(struct device_domain_info *info)
 {
struct dmar_domain *domain;
@@ -4779,7 +4830,7 @@ static void __dmar_remove_one_dev_info(struct 
device_domain_info *info)
PASID_RID2PASID);
 
iommu_disable_dev_iotlb(info);
-   domain_context_clear_one(iommu, info->bus, info->devfn);
+   domain_context_clear(iommu, info->dev);
intel_pasid_free_table(info->dev);
}
 
-- 
2.17.1



Re: [RFC PATCH] iommu/vt-d: Fix IOMMU field not populated on device hot re-plug

2019-08-26 Thread Lu Baolu

Hi Janusz,

On 8/26/19 4:15 PM, Janusz Krzysztofik wrote:

Hi Lu,

On Friday, August 23, 2019 3:51:11 AM CEST Lu Baolu wrote:

Hi,

On 8/22/19 10:29 PM, Janusz Krzysztofik wrote:

When a perfectly working i915 device is hot unplugged (via sysfs) and
hot re-plugged again, its dev->archdata.iommu field is not populated
again with an IOMMU pointer.  As a result, the device probe fails on
DMA mapping error during scratch page setup.

It looks like that happens because devices are not detached from their
MMUIO bus before they are removed on device unplug.  Then, when an
already registered device/IOMMU association is identified by the
reinstantiated device's bus and function IDs on IOMMU bus re-attach
attempt, the device's archdata is not populated with IOMMU information
and the bad happens.

I'm not sure if this is a proper fix but it works for me so at least it
confirms correctness of my analysis results, I believe.  So far I
haven't been able to identify a good place where the possibly missing
IOMMU bus detach on device unplug operation could be added.


Which kernel version are you testing with? Does it contain below commit?

commit 458b7c8e0dde12d140e3472b80919cbb9ae793f4
Author: Lu Baolu 
Date:   Thu Aug 1 11:14:58 2019 +0800


I was using an internal branch based on drm-tip which didn't contain this
commit yet.  Fortunately it has been already merged into drm-tip over last
weekend and has effectively fixed the issue.


Thanks for testing this.

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


Re: [RFC PATCH] iommu/vt-d: Fix IOMMU field not populated on device hot re-plug

2019-08-26 Thread Janusz Krzysztofik
Hi Lu,

On Friday, August 23, 2019 3:51:11 AM CEST Lu Baolu wrote:
> Hi,
> 
> On 8/22/19 10:29 PM, Janusz Krzysztofik wrote:
> > When a perfectly working i915 device is hot unplugged (via sysfs) and
> > hot re-plugged again, its dev->archdata.iommu field is not populated
> > again with an IOMMU pointer.  As a result, the device probe fails on
> > DMA mapping error during scratch page setup.
> > 
> > It looks like that happens because devices are not detached from their
> > MMUIO bus before they are removed on device unplug.  Then, when an
> > already registered device/IOMMU association is identified by the
> > reinstantiated device's bus and function IDs on IOMMU bus re-attach
> > attempt, the device's archdata is not populated with IOMMU information
> > and the bad happens.
> > 
> > I'm not sure if this is a proper fix but it works for me so at least it
> > confirms correctness of my analysis results, I believe.  So far I
> > haven't been able to identify a good place where the possibly missing
> > IOMMU bus detach on device unplug operation could be added.
> 
> Which kernel version are you testing with? Does it contain below commit?
> 
> commit 458b7c8e0dde12d140e3472b80919cbb9ae793f4
> Author: Lu Baolu 
> Date:   Thu Aug 1 11:14:58 2019 +0800

I was using an internal branch based on drm-tip which didn't contain this 
commit yet.  Fortunately it has been already merged into drm-tip over last 
weekend and has effectively fixed the issue.

Thanks,
Janusz

>  iommu/vt-d: Detach domain when move device out of group
> 
>  When removing a device from an iommu group, the domain should
>  be detached from the device. Otherwise, the stale domain info
>  will still be cached by the driver and the driver will refuse
>  to attach any domain to the device again.
> 
>  Cc: Ashok Raj 
>  Cc: Jacob Pan 
>  Cc: Kevin Tian 
>  Fixes: b7297783c2bb6 ("iommu/vt-d: Remove duplicated code for 
> device hotplug")
>  Reported-and-tested-by: Vlad Buslov 
>  Suggested-by: Robin Murphy 
>  Link: https://lkml.org/lkml/2019/7/26/1133
>  Signed-off-by: Lu Baolu 
>  Signed-off-by: Joerg Roedel 
> 
> Best regards,
> Lu Baolu
> 
> > 
> > Signed-off-by: Janusz Krzysztofik 
> > ---
> >   drivers/iommu/intel-iommu.c | 3 +++
> >   1 file changed, 3 insertions(+)
> > 
> > diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c
> > index 12d094d08c0a..7cdcd0595408 100644
> > --- a/drivers/iommu/intel-iommu.c
> > +++ b/drivers/iommu/intel-iommu.c
> > @@ -2477,6 +2477,9 @@ static struct dmar_domain 
*dmar_insert_one_dev_info(struct intel_iommu *iommu,
> > if (info2) {
> > found  = info2->domain;
> > info2->dev = dev;
> > +
> > +   if (dev && !dev->archdata.iommu)
> > +   dev->archdata.iommu = info2;
> > }
> > }
> >   
> > 
> 




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


Re: [PATCH v2 2/2] dma-contiguous: Use fallback alloc_pages for single pages

2019-08-26 Thread Christoph Hellwig
On Mon, Aug 26, 2019 at 11:05:00AM +0900, Masahiro Yamada wrote:
> This is included in v5.3-rc6
> so I tested it.

So there is no allocation failure, but you get I/O errors later?

Does the device use a device-private CMA area?  Does it work with Linux
5.2 if CONFIG_DMA_CMA is disabled?


Re: convert microblaze to the generic dma remap allocator

2019-08-26 Thread Michal Simek
Hi,

On 26. 08. 19 9:02, Christoph Hellwig wrote:
> On Wed, Aug 14, 2019 at 04:03:46PM +0200, Christoph Hellwig wrote:
>> Hi Michal,
>>
>> can you take a look at this patch that moves microblaze over to the
>> generic DMA remap allocator?  I've been trying to slowly get all
>> architectures over to the generic code, and microblaze is one that
>> seems very straightfoward to convert.
> 
> Michal, any chance you could look over this series?
> 

let me take a look.

M


-- 
Michal Simek, Ing. (M.Eng), OpenPGP -> KeyID: FE3D1F91
w: www.monstr.eu p: +42-0-721842854
Maintainer of Linux kernel - Xilinx Microblaze
Maintainer of Linux kernel - Xilinx Zynq ARM and ZynqMP ARM64 SoCs
U-Boot custodian - Xilinx Microblaze/Zynq/ZynqMP/Versal SoCs




signature.asc
Description: OpenPGP digital signature
___
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

Re: [PATCH v2 01/11] asm-generic: add dma_zone_size

2019-08-26 Thread Christoph Hellwig
On Tue, Aug 20, 2019 at 04:58:09PM +0200, Nicolas Saenz Julienne wrote:
> Some architectures have platform specific DMA addressing limitations.
> This will allow for hardware description code to provide the constraints
> in a generic manner, so as for arch code to properly setup it's memory
> zones and DMA mask.

I know this just spreads the arm code, but I still kinda hate it.

MAX_DMA_ADDRESS is such an oddly defined concepts.  We have the mm
code that uses it to start allocating after the dma zones, but
I think that would better be done using a function returning
1 << max(zone_dma_bits, 32) or so.  Then we have about a handful
of drivers using it that all seem rather bogus, and one of which
I think are usable on arm64.


Re: [PATCH v2 11/11] mm: refresh ZONE_DMA and ZONE_DMA32 comments in 'enum zone_type'

2019-08-26 Thread Christoph Hellwig
Looks good:

Reviewed-by: Christoph Hellwig 


Re: [PATCH v2 10/11] arm64: edit zone_dma_bits to fine tune dma-direct min mask

2019-08-26 Thread Christoph Hellwig
On Tue, Aug 20, 2019 at 04:58:18PM +0200, Nicolas Saenz Julienne wrote:
> - if (IS_ENABLED(CONFIG_ZONE_DMA))
> + if (IS_ENABLED(CONFIG_ZONE_DMA)) {
>   arm64_dma_phys_limit = max_zone_dma_phys();
> + zone_dma_bits = ilog2((arm64_dma_phys_limit - 1) & 
> GENMASK_ULL(31, 0)) + 1;

This adds a way too long line.  I also find the use of GENMASK_ULL
horribly obsfucating, but I know that opinion is't shared by everyone.


Re: [PATCH v2 09/11] dma-direct: turn ARCH_ZONE_DMA_BITS into a variable

2019-08-26 Thread Christoph Hellwig
Looks good,

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


Re: convert microblaze to the generic dma remap allocator

2019-08-26 Thread Christoph Hellwig
On Wed, Aug 14, 2019 at 04:03:46PM +0200, Christoph Hellwig wrote:
> Hi Michal,
> 
> can you take a look at this patch that moves microblaze over to the
> generic DMA remap allocator?  I've been trying to slowly get all
> architectures over to the generic code, and microblaze is one that
> seems very straightfoward to convert.

Michal, any chance you could look over this series?


Re: [V3, 2/2] media: i2c: Add Omnivision OV02A10 camera sensor driver

2019-08-26 Thread Tomasz Figa
On Wed, Aug 21, 2019 at 8:05 PM Sakari Ailus
 wrote:
>
> Hi Tomasz,
>
> On Wed, Aug 21, 2019 at 07:30:38PM +0900, Tomasz Figa wrote:
[snip]
> > Is it really correct to enable the clock before the regulators?
> >
> > According to the datasheet, it should be:
> >  - PD pin HIGH,
> >  - nRST pin LOW,
> >  - DVDDIO and AVDD28 power up and stabilize,
> >  - clock enabled,
> >  - min 5 ms delay,
> >  - PD pin LOW,
> >  - min 4 ms delay,
> >  - nRST pin HIGH,
> >  - min 5 ms delay,
> >  - I2C interface ready.
> >
> > > +
> > > +   /* Note: set 0 is high, set 1 is low */
> >
> > Why is that? If there is some inverter on the way that should be handled
> > outside of this driver. (GPIO DT bindings have flags for this purpose.
> >
> > If the pins are nRESET and nPOWERDOWN in the hardware datasheet, we should
> > call them like this in the driver too (+/- the lowercase and underscore
> > convention).
> >
> > According to the datasheet, the reset pin is called RST and inverted, so we 
> > should
> > call it n_rst, but the powerdown signal, called PD, is not inverted, so pd
> > would be the right name.
>
> For what it's worth sensors generally have xshutdown (or reset) pin that is
> active high. Looking at the code, it is not the case here. It's a bit odd
> since the usual arrangement saves power when the camera is not in use; it's
> not a lot but still. Oh well.
>

I guess we could drive powerdown low after disabling the regulators
and clocks, but that wouldn't work for the cases where the regulators
are actually shared with something else, especially if that is not
related to the same camera module.

> ...
>
> > > +static struct i2c_driver ov02a10_i2c_driver = {
> > > +   .driver = {
> > > +   .name = "ov02a10",
> > > +   .pm = _pm_ops,
> > > +   .of_match_table = ov02a10_of_match,
> >
> > Please use of_match_ptr() wrapper.
>
> Not really needed; the driver does expect regulators, GPIOs etc., but by
> leaving out of_match_ptr(), the driver will also probe on ACPI based
> systems.

Good point, I always keep forgetting about the ability to probe OF
drivers from ACPI. Then we also need to remove the #if
IS_ENABLED(CONFIG_OF) from ov02a10_of_match.

Best regards,
Tomasz


Re: [PATCH v3] iommu: revisit iommu_insert_resv_region() implementation

2019-08-26 Thread Christoph Hellwig
Looks good,

Reviewed-by: Christoph Hellwig