Re: swiotlb-xen cleanups
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
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
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
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
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
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
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
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
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
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
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
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
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
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"
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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"
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
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
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
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
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
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'
Looks good: Reviewed-by: Christoph Hellwig
Re: [PATCH v2 10/11] arm64: edit zone_dma_bits to fine tune dma-direct min mask
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
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
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
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
Looks good, Reviewed-by: Christoph Hellwig