Re: [PATCH v2 13/40] vfio: Add support for Shared Virtual Addressing
Hi, On 2018/5/25 17:47, Jean-Philippe Brucker wrote: On 25/05/18 03:39, Xu Zaibo wrote: Hi, On 2018/5/24 23:04, Jean-Philippe Brucker wrote: On 24/05/18 13:35, Xu Zaibo wrote: Right, sva_init() must be called once for any device that intends to use bind(). For the second process though, group->sva_enabled will be true so we won't call sva_init() again, only bind(). Well, while I create mediated devices based on one parent device to support multiple processes(a new process will create a new 'vfio_group' for the corresponding mediated device, and 'sva_enabled' cannot work any more), in fact, *sva_init and *sva_shutdown are basically working on parent device, so, as a result, I just only need sva initiation and shutdown on the parent device only once. So I change the two as following: @@ -551,8 +565,18 @@ int iommu_sva_device_init(struct device *dev, unsigned long features, if (features & ~IOMMU_SVA_FEAT_IOPF) return -EINVAL; +/* If already exists, do nothing */ +mutex_lock(>iommu_param->lock); +if (dev->iommu_param->sva_param) { +mutex_unlock(>iommu_param->lock); +return 0; +} +mutex_unlock(>iommu_param->lock); if (features & IOMMU_SVA_FEAT_IOPF) { ret = iommu_register_device_fault_handler(dev, iommu_queue_iopf, @@ -621,6 +646,14 @@ int iommu_sva_device_shutdown(struct device *dev) if (!domain) return -ENODEV; +/* If any other process is working on the device, shut down does nothing. */ +mutex_lock(>iommu_param->lock); +if (!list_empty(>iommu_param->sva_param->mm_list)) { +mutex_unlock(>iommu_param->lock); +return 0; +} +mutex_unlock(>iommu_param->lock); I don't think iommu-sva.c is the best place for this, it's probably better to implement an intermediate layer (the mediating driver), that calls iommu_sva_device_init() and iommu_sva_device_shutdown() once. Then vfio-pci would still call these functions itself, but for mdev the mediating driver keeps a refcount of groups, and calls device_shutdown() only when freeing the last mdev. A device driver (non mdev in this example) expects to be able to free all its resources after sva_device_shutdown() returns. Imagine the mm_list isn't empty (mm_exit() is running late), and instead of waiting in unbind_dev_all() below, we return 0 immediately. Then the calling driver frees its resources, and the mm_exit callback along with private data passed to bind() disappear. If a mm_exit() is still running in parallel, then it will try to access freed data and corrupt memory. So in this function if mm_list isn't empty, the only thing we can do is wait. I still don't understand why we should 'unbind_dev_all', is it possible to do a 'unbind_dev_pasid'? Not in sva_device_shutdown(), it needs to clean up everything. For example you want to physically unplug the device, or assign it to a VM. To prevent any leak sva_device_shutdown() needs to remove all bonds. In theory there shouldn't be any, since either the driver did unbind_dev(), or all process exited. This is a safety net. Then we can do other things instead of waiting that user may not like. :) They may not like it, but it's for their own good :) At the moment we're waiting that: * All exit_mm() callback for this device have finished. If we don't wait then the caller will free the private data passed to bind and the mm_exit() callback while they are still being used. * All page requests targeting this device are dealt with. If we don't wait then some requests, that are lingering in the IOMMU PRI queue, may hit the next contexts bound to this device, possibly in a different VM. It may not be too risky (though probably exploitable in some way), but is incredibly messy. All of this is bounded in time, and normally should be over pretty fast unless the device driver's exit_mm() does something strange. If the driver did the right thing, there shouldn't be any wait here (although there may be one in unbind_dev() for the same reasons - prevent use after free). I guess there may be some misunderstandings :). From the current patches, '/iommu_sva_device_shutdown/' is called by '/vfio_iommu_sva_shutdown/', which is mainly used by '/vfio_iommu_type1_detach_group/' that is finally called by processes' release of vfio facilitiy automatically or called by 'VFIO_GROUP_UNSET_CONTAINER' manually in the processes. So, just image that 2 processes is working on the device with IOPF feature, and the 2 do the following to enable SVA: /1.open("/dev/vfio/vfio") ;// // // 2.open the group of the devcie by calling open("/dev/vfio/x"), but now, // // I think the second processes will fail to open the group because current VFIO thinks that one group only can be used by one process/vm, at present, I use mediated device to create more groups on the parent device to support multiple processes;// / // /3.VFIO_GROUP_SET_CONTAINER;/ /
Re: [PATCH v2 03/40] iommu/sva: Manage process address spaces
On Fri, May 25, 2018 at 09:39:59AM +0100, Jonathan Cameron wrote: > Date: Fri, 25 May 2018 09:39:59 +0100 > From: Jonathan Cameron> To: Ilias Apalodimas > CC: Jean-Philippe Brucker , > "xieyishe...@huawei.com" , "k...@vger.kernel.org" > , "linux-...@vger.kernel.org" > , "xuza...@huawei.com" , > Will Deacon , "ok...@codeaurora.org" > , "linux...@kvack.org" , > "yi.l@intel.com" , "ashok@intel.com" > , "t...@semihalf.com" , > "j...@8bytes.org" , "robdcl...@gmail.com" > , "bhara...@xilinx.com" , > "linux-a...@vger.kernel.org" , > "liudongdo...@huawei.com" , "rfr...@cavium.com" > , "devicet...@vger.kernel.org" > , "kevin.t...@intel.com" > , Jacob Pan , > "alex.william...@redhat.com" , > "rgum...@xilinx.com" , "thunder.leiz...@huawei.com" > , "linux-arm-ker...@lists.infradead.org" > , "shunyong.y...@hxt-semitech.com" > , "dw...@infradead.org" > , "liub...@huawei.com" , > "jcro...@codeaurora.org" , > "iommu@lists.linux-foundation.org" , > Robin Murphy , "christian.koe...@amd.com" > , "nwatt...@codeaurora.org" > , "baolu...@linux.intel.com" > , liguo...@hisilicon.com, > kenneth-lee-2...@foxmail.com > Subject: Re: [PATCH v2 03/40] iommu/sva: Manage process address spaces > Message-ID: <20180525093959.4...@huawei.com> > > +CC Kenneth Lee > > On Fri, 25 May 2018 09:33:11 +0300 > Ilias Apalodimas wrote: > > > On Thu, May 24, 2018 at 04:04:39PM +0100, Jean-Philippe Brucker wrote: > > > On 24/05/18 12:50, Ilias Apalodimas wrote: > > > >> Interesting, I hadn't thought about this use-case before. At first I > > > >> thought you were talking about mdev devices assigned to VMs, but I > > > >> think > > > >> you're referring to mdevs assigned to userspace drivers instead? Out of > > > >> curiosity, is it only theoretical or does someone actually need this? > > > > > > > > There has been some non upstreamed efforts to have mdev and produce > > > > userspace > > > > drivers. Huawei is using it on what they call "wrapdrive" for crypto > > > > devices and > > > > we did a proof of concept for ethernet interfaces. At the time we > > > > choose not to > > > > involve the IOMMU for the reason you mentioned, but having it there > > > > would be > > > > good. > > > > > > I'm guessing there were good reasons to do it that way but I wonder, is > > > it not simpler to just have the kernel driver create a /dev/foo, with a > > > standard ioctl/mmap/poll interface? Here VFIO adds a layer of > > > indirection, and since the mediating driver has to implement these > > > operations already, what is gained? > > The best reason i can come up with is "common code". You already have one > > API > > doing that for you so we replicate it in a /dev file? > > The mdev approach still needs extentions to support what we tried to do (i.e > > mdev bus might need yo have access on iommu_ops), but as far as i undestand > > it's > > a possible case. Hi, Jean, Please allow me to share my understanding here: https://zhuanlan.zhihu.com/p/35489035 The reason we do not use the /dev/foo scheme is that the devices to be shared are programmable accelerators. We cannot fix up the kernel driver for them. > > > > > > Thanks, > > > Jean > > -- -Kenneth Lee (Hisilicon) ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
Re: [PATCH v2 07/40] iommu: Add a page fault handler
On Thu, 24 May 2018 12:44:38 +0100 Jean-Philippe Bruckerwrote: > On 23/05/18 00:35, Jacob Pan wrote: > +/* Insert *before* the last fault */ > +list_move(>head, >faults); > +} > + > >>> If you already sorted the group list with last fault at the end, > >>> why do you need a separate entry to track the last fault? > >> > >> Not sure I understand your question, sorry. Do you mean why the > >> iopf_group.last_fault? Just to avoid one more kzalloc. > >> > > kind of :) what i thought was that why can't the last_fault > > naturally be the last entry in your group fault list? then there is > > no need for special treatment in terms of allocation of the last > > fault. just my preference. > > But we need a kzalloc for the last fault anyway, so I thought I'd just > piggy-back on the group allocation. And if I don't add the last fault > at the end of group->faults, then it's iopf_handle_group that requires > special treatment. I'm still not sure I understood your question > though, could you send me a patch that does it? > > + > +queue->flush(queue->flush_arg, dev); > + > +/* > + * No need to clear the partial list. All PRGs > containing the PASID that > + * needs to be decommissioned are whole (the device > driver made sure of > + * it before this function was called). They have been > submitted to the > + * queue by the above flush(). > + */ > >>> So you are saying device driver need to make sure LPIG PRQ is > >>> submitted in the flush call above such that partial list is > >>> cleared? > >> > >> Not exactly, it's the IOMMU driver that makes sure all LPIG in its > >> queues are submitted by the above flush call. In more details the > >> flow is: > >> > >> * Either device driver calls unbind()/sva_device_shutdown(), or the > >> process exits. > >> * If the device driver called, then it already told the device to > >> stop using the PASID. Otherwise we use the mm_exit() callback to > >> tell the device driver to stop using the PASID. Sorry I still need more clarification. For the PASID termination initiated by vfio unbind, I don't see device driver given a chance to stop PASID. Seems just call __iommu_sva_unbind_device() which already assume device stopped issuing DMA with the PASID. So it is the vfio unbind caller responsible for doing driver callback to stop DMA on a given PASID? > >> * In either case, when receiving a stop request from the driver, > >> the device sends the LPIGs to the IOMMU queue. > >> * Then, the flush call above ensures that the IOMMU reports the > >> LPIG with iommu_report_device_fault. > >> * While submitting all LPIGs for this PASID to the work queue, > >> ipof_queue_fault also picked up all partial faults, so the partial > >> list is clean. > >> > >> Maybe I should improve this comment? > >> > > thanks for explaining. LPIG submission is done by device > > asynchronously w.r.t. driver stopping/decommission PASID. > > Hmm, it should really be synchronous, otherwise there is no way to > know when the PASID can be decommissioned. We need a guarantee such > as the one in 6.20.1 of the PCIe spec, "Managing PASID TLP Prefix > Usage": > > "When the stop request mechanism indicates completion, the Function > has: > * Completed all Non-Posted Requests associated with this PASID. > * Flushed to the host all Posted Requests addressing host memory in > all TCs that were used by the PASID." > > That's in combination with "The function shall [...] finish > transmitting any multi-page Page Request Messages for this PASID > (i.e. send the Page Request Message with the L bit Set)." from the > ATS spec. > I am not contesting on the device side, what I meant was from the host IOMMU driver perspective, LPIG is received via IOMMU host queue, therefore asynchronous. Not sure about ARM, but on VT-d LPIG submission could meet queue full condition. So per VT-d spec, iommu will generate a successful auto response to the device. At this point, assume we already stopped the given PASID on the device, there might not be another LPIG sent for the device. Therefore, you could have a partial list. I think we can just drop the requests in the partial list for that PASID until the PASID gets re-allocated. > (If I remember correctly a PRI Page Request is a Posted Request.) Only > after this stop request completes can the driver call unbind(), or > return from exit_mm(). Then we know that if there was a LPIG for that > PASID, it is in the IOMMU's PRI queue (or already completed) once we > call flush(). > agreed. > > so if we were to use this > > flow on vt-d, which does not stall page request queue, then we > > should use the iommu model specific flush() callback to ensure LPIG > > is received? There could be queue full condition and retry. I am > > just trying to
Re: [PATCH v6 0/7] vfio/type1: Add support for valid iova list management
On Fri, 25 May 2018 08:45:36 + Shameerali Kolothum Thodiwrote: > Yes, the above changes related to list empty cases looks fine to me. Thanks Shameer, applied to my next branch with the discussed fixes for v4.18 (modulo patch 4/7 which Joerg already pushed for v4.17). Thanks, Alex ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
Re: [PATCH 1/7] core, dma-direct: add a flag 32-bit dma limits
On Fri, May 25, 2018 at 04:50:12PM +0200, Greg Kroah-Hartman wrote: > On Fri, May 25, 2018 at 04:35:06PM +0200, Christoph Hellwig wrote: > > Various PCI bridges (VIA PCI, Xilinx PCIe) limit DMA to only 32-bits > > even if the device itself supports more. Add a single bit flag to > > struct device (to be moved into the dma extension once we around it) > > "once we around it"? I don't understand, sorry. Should be "once we get around it", which in proper grammar should probably be "once we get to it". Anyway, the point is that right now struct device is bloated with a lot of fields for dma/iommu purposes and we need to clean this up. It's been on my TODO list for a while. ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
Re: [PATCH 1/7] core, dma-direct: add a flag 32-bit dma limits
On Fri, May 25, 2018 at 04:35:06PM +0200, Christoph Hellwig wrote: > Various PCI bridges (VIA PCI, Xilinx PCIe) limit DMA to only 32-bits > even if the device itself supports more. Add a single bit flag to > struct device (to be moved into the dma extension once we around it) "once we around it"? I don't understand, sorry. > to flag such devices and reject larger DMA to them. > > Signed-off-by: Christoph Hellwig> --- > include/linux/device.h | 3 +++ > lib/dma-direct.c | 6 ++ > 2 files changed, 9 insertions(+) For the patch, no objection from me: Reviewed-by: Greg Kroah-Hartman ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
[PATCH 7/7] x86: switch the VIA 32-bit DMA quirk to use the struct device flag
Instead of globally disabling > 32bit DMA using the arch_dma_supported hook walk the PCI bus under the actually affected bridge and mark every device with the dma_32bit_limit flag. This also gets rid of the arch_dma_supported hook entirely. Signed-off-by: Christoph Hellwig--- arch/x86/include/asm/dma-mapping.h | 3 --- arch/x86/kernel/pci-dma.c | 27 ++- include/linux/dma-mapping.h| 11 --- 3 files changed, 10 insertions(+), 31 deletions(-) diff --git a/arch/x86/include/asm/dma-mapping.h b/arch/x86/include/asm/dma-mapping.h index 89ce4bfd241f..eb4e1352e403 100644 --- a/arch/x86/include/asm/dma-mapping.h +++ b/arch/x86/include/asm/dma-mapping.h @@ -30,9 +30,6 @@ static inline const struct dma_map_ops *get_arch_dma_ops(struct bus_type *bus) return dma_ops; } -int arch_dma_supported(struct device *dev, u64 mask); -#define arch_dma_supported arch_dma_supported - bool arch_dma_alloc_attrs(struct device **dev, gfp_t *gfp); #define arch_dma_alloc_attrs arch_dma_alloc_attrs diff --git a/arch/x86/kernel/pci-dma.c b/arch/x86/kernel/pci-dma.c index b5cbef974bd1..0d6fd0d1c14f 100644 --- a/arch/x86/kernel/pci-dma.c +++ b/arch/x86/kernel/pci-dma.c @@ -15,7 +15,7 @@ #include #include -static int forbid_dac __read_mostly; +static bool disable_dac_quirk __read_mostly; const struct dma_map_ops *dma_ops = _direct_ops; EXPORT_SYMBOL(dma_ops); @@ -129,7 +129,7 @@ static __init int iommu_setup(char *p) if (!strncmp(p, "nodac", 5)) pr_warn("nodac option ignored.\n"); if (!strncmp(p, "usedac", 6)) { - forbid_dac = -1; + disable_dac_quirk = true; return 1; } #ifdef CONFIG_SWIOTLB @@ -154,19 +154,6 @@ static __init int iommu_setup(char *p) } early_param("iommu", iommu_setup); -int arch_dma_supported(struct device *dev, u64 mask) -{ -#ifdef CONFIG_PCI - if (mask > 0x && forbid_dac > 0) { - dev_info(dev, "PCI: Disallowing DAC for device\n"); - return 0; - } -#endif - - return 1; -} -EXPORT_SYMBOL(arch_dma_supported); - static int __init pci_iommu_init(void) { struct iommu_table_entry *p; @@ -190,11 +177,17 @@ rootfs_initcall(pci_iommu_init); #ifdef CONFIG_PCI /* Many VIA bridges seem to corrupt data for DAC. Disable it here */ +static int via_no_dac_cb(struct pci_dev *pdev, void *data) +{ + pdev->dev.dma_32bit_limit = true; + return 0; +} + static void via_no_dac(struct pci_dev *dev) { - if (forbid_dac == 0) { + if (!disable_dac_quirk) { dev_info(>dev, "disabling DAC on VIA PCI bridge\n"); - forbid_dac = 1; + pci_walk_bus(dev->subordinate, via_no_dac_cb, NULL); } } DECLARE_PCI_FIXUP_CLASS_FINAL(PCI_VENDOR_ID_VIA, PCI_ANY_ID, diff --git a/include/linux/dma-mapping.h b/include/linux/dma-mapping.h index f8ab1c0f589e..0249bce7c5e7 100644 --- a/include/linux/dma-mapping.h +++ b/include/linux/dma-mapping.h @@ -572,14 +572,6 @@ static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr) return 0; } -/* - * This is a hack for the legacy x86 forbid_dac and iommu_sac_force. Please - * don't use this in new code. - */ -#ifndef arch_dma_supported -#define arch_dma_supported(dev, mask) (1) -#endif - static inline void dma_check_mask(struct device *dev, u64 mask) { if (sme_active() && (mask < (((u64)sme_get_me_mask() << 1) - 1))) @@ -592,9 +584,6 @@ static inline int dma_supported(struct device *dev, u64 mask) if (!ops) return 0; - if (!arch_dma_supported(dev, mask)) - return 0; - if (!ops->dma_supported) return 1; return ops->dma_supported(dev, mask); -- 2.17.0 ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
[PATCH 6/7] x86: remove the explicit nodac and allowdac option
This is something drivers should decide (modulo chipset quirks like for VIA), which as far as I can tell is how things have been handled for the last 15 years. Note that we keep the usedac option for now, as it is used in the wild to override the too generic VIA quirk. Signed-off-by: Christoph Hellwig--- Documentation/x86/x86_64/boot-options.txt | 5 - arch/x86/kernel/pci-dma.c | 4 ++-- 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/Documentation/x86/x86_64/boot-options.txt b/Documentation/x86/x86_64/boot-options.txt index 341588ec4e29..8d109ef67ab6 100644 --- a/Documentation/x86/x86_64/boot-options.txt +++ b/Documentation/x86/x86_64/boot-options.txt @@ -236,11 +236,6 @@ IOMMU (input/output memory management unit) nomergeDon't do scatter-gather (SG) merging. noaperture Ask the IOMMU not to touch the aperture for AGP. noagp Don't initialize the AGP driver and use full aperture. -allowdac Allow double-address cycle (DAC) mode, i.e. DMA >4GB. - DAC is used with 32-bit PCI to push a 64-bit address in - two cycles. When off all DMA over >4GB is forced through - an IOMMU or software bounce buffering. -nodac Forbid DAC mode, i.e. DMA >4GB. panic Always panic when IOMMU overflows. calgaryUse the Calgary IOMMU if it is available diff --git a/arch/x86/kernel/pci-dma.c b/arch/x86/kernel/pci-dma.c index 91dff954b745..b5cbef974bd1 100644 --- a/arch/x86/kernel/pci-dma.c +++ b/arch/x86/kernel/pci-dma.c @@ -125,9 +125,9 @@ static __init int iommu_setup(char *p) if (!strncmp(p, "forcesac", 8)) pr_warn("forcesac option ignored.\n"); if (!strncmp(p, "allowdac", 8)) - forbid_dac = 0; + pr_warn("allowdac option ignored.\n"); if (!strncmp(p, "nodac", 5)) - forbid_dac = 1; + pr_warn("nodac option ignored.\n"); if (!strncmp(p, "usedac", 6)) { forbid_dac = -1; return 1; -- 2.17.0 ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
[PATCH 5/7] x86: remove the experimental forcesac boot option
Limiting the dma mask to avoid PCI (pre-PCIe) DAC cycles while paying the huge overhead of an IOMMU is rather pointless, and this seriously gets in the way of dma mapping work. Signed-off-by: Christoph Hellwig--- .../admin-guide/kernel-parameters.txt | 1 - Documentation/x86/x86_64/boot-options.txt | 4 +--- arch/x86/kernel/pci-dma.c | 21 +-- drivers/net/ethernet/sfc/efx.c| 5 ++--- drivers/net/ethernet/sfc/falcon/efx.c | 5 ++--- 5 files changed, 6 insertions(+), 30 deletions(-) diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt index f2040d46f095..cc0ac035b8fe 100644 --- a/Documentation/admin-guide/kernel-parameters.txt +++ b/Documentation/admin-guide/kernel-parameters.txt @@ -1705,7 +1705,6 @@ nopanic merge nomerge - forcesac soft pt [x86, IA-64] nobypass[PPC/POWERNV] diff --git a/Documentation/x86/x86_64/boot-options.txt b/Documentation/x86/x86_64/boot-options.txt index 153b3a57fba2..341588ec4e29 100644 --- a/Documentation/x86/x86_64/boot-options.txt +++ b/Documentation/x86/x86_64/boot-options.txt @@ -208,7 +208,7 @@ IOMMU (input/output memory management unit) Kernel boot message: "PCI-DMA: Using Calgary IOMMU" iommu=[][,noagp][,off][,force][,noforce][,leak[=] - [,memaper[=]][,merge][,forcesac][,fullflush][,nomerge] + [,memaper[=]][,merge][,fullflush][,nomerge] [,noaperture][,calgary] General iommu options: @@ -235,8 +235,6 @@ IOMMU (input/output memory management unit) (experimental). nomergeDon't do scatter-gather (SG) merging. noaperture Ask the IOMMU not to touch the aperture for AGP. -forcesac Force single-address cycle (SAC) mode for masks <40bits - (experimental). noagp Don't initialize the AGP driver and use full aperture. allowdac Allow double-address cycle (DAC) mode, i.e. DMA >4GB. DAC is used with 32-bit PCI to push a 64-bit address in diff --git a/arch/x86/kernel/pci-dma.c b/arch/x86/kernel/pci-dma.c index 77625b60a510..91dff954b745 100644 --- a/arch/x86/kernel/pci-dma.c +++ b/arch/x86/kernel/pci-dma.c @@ -20,8 +20,6 @@ static int forbid_dac __read_mostly; const struct dma_map_ops *dma_ops = _direct_ops; EXPORT_SYMBOL(dma_ops); -static int iommu_sac_force __read_mostly; - #ifdef CONFIG_IOMMU_DEBUG int panic_on_overflow __read_mostly = 1; int force_iommu __read_mostly = 1; @@ -125,7 +123,7 @@ static __init int iommu_setup(char *p) if (!strncmp(p, "nomerge", 7)) iommu_merge = 0; if (!strncmp(p, "forcesac", 8)) - iommu_sac_force = 1; + pr_warn("forcesac option ignored.\n"); if (!strncmp(p, "allowdac", 8)) forbid_dac = 0; if (!strncmp(p, "nodac", 5)) @@ -165,23 +163,6 @@ int arch_dma_supported(struct device *dev, u64 mask) } #endif - /* Tell the device to use SAC when IOMMU force is on. This - allows the driver to use cheaper accesses in some cases. - - Problem with this is that if we overflow the IOMMU area and - return DAC as fallback address the device may not handle it - correctly. - - As a special case some controllers have a 39bit address - mode that is as efficient as 32bit (aic79xx). Don't force - SAC for these. Assume all masks <= 40 bits are of this - type. Normally this doesn't make any difference, but gives - more gentle handling of IOMMU overflow. */ - if (iommu_sac_force && (mask >= DMA_BIT_MASK(40))) { - dev_info(dev, "Force SAC with mask %Lx\n", mask); - return 0; - } - return 1; } EXPORT_SYMBOL(arch_dma_supported); diff --git a/drivers/net/ethernet/sfc/efx.c b/drivers/net/ethernet/sfc/efx.c index a4ebd8715494..661828e8fdcf 100644 --- a/drivers/net/ethernet/sfc/efx.c +++ b/drivers/net/ethernet/sfc/efx.c @@ -1289,9 +1289,8 @@ static int efx_init_io(struct efx_nic *efx) pci_set_master(pci_dev); - /* Set the PCI DMA mask. Try all possibilities from our -* genuine mask down to 32 bits, because some architectures -* (e.g. x86_64 with iommu_sac_force set) will allow 40 bit + /* Set the PCI DMA mask. Try all possibilities from our genuine mask +* down to 32 bits, because some architectures will allow 40 bit * masks event though they reject 46 bit masks. */ while (dma_mask > 0x7fffUL) { diff --git a/drivers/net/ethernet/sfc/falcon/efx.c b/drivers/net/ethernet/sfc/falcon/efx.c index 3d6c91e96589..dd5530a4f8c8 100644 ---
[PATCH 4/7] x86: remove a stray reference to pci-nommu.c
This is just the minimal workaround. The file file is mostly either stale and/or duplicative of Documentation/admin-guide/kernel-parameters.txt, but that is much more work than I'm willing to do right now. Signed-off-by: Christoph Hellwig--- Documentation/x86/x86_64/boot-options.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Documentation/x86/x86_64/boot-options.txt b/Documentation/x86/x86_64/boot-options.txt index b297c48389b9..153b3a57fba2 100644 --- a/Documentation/x86/x86_64/boot-options.txt +++ b/Documentation/x86/x86_64/boot-options.txt @@ -187,9 +187,9 @@ PCI IOMMU (input/output memory management unit) - Currently four x86-64 PCI-DMA mapping implementations exist: + Multiple x86-64 PCI-DMA mapping implementations exist, for example: - 1. : use no hardware/software IOMMU at all + 1. : use no hardware/software IOMMU at all (e.g. because you have < 3 GB memory). Kernel boot message: "PCI-DMA: Disabling IOMMU" -- 2.17.0 ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
[PATCH 2/7] ia64: remove the dead iommu_sac_force variable
Looks like copy and paste from x86 that never actually got used. Signed-off-by: Christoph Hellwig--- arch/ia64/kernel/pci-dma.c | 19 --- 1 file changed, 19 deletions(-) diff --git a/arch/ia64/kernel/pci-dma.c b/arch/ia64/kernel/pci-dma.c index b5df084c0af4..50b6ad282a90 100644 --- a/arch/ia64/kernel/pci-dma.c +++ b/arch/ia64/kernel/pci-dma.c @@ -18,8 +18,6 @@ dma_addr_t bad_dma_address __read_mostly; EXPORT_SYMBOL(bad_dma_address); -static int iommu_sac_force __read_mostly; - int no_iommu __read_mostly; #ifdef CONFIG_IOMMU_DEBUG int force_iommu __read_mostly = 1; @@ -61,23 +59,6 @@ int iommu_dma_supported(struct device *dev, u64 mask) if (mask < DMA_BIT_MASK(24)) return 0; - /* Tell the device to use SAC when IOMMU force is on. This - allows the driver to use cheaper accesses in some cases. - - Problem with this is that if we overflow the IOMMU area and - return DAC as fallback address the device may not handle it - correctly. - - As a special case some controllers have a 39bit address - mode that is as efficient as 32bit (aic79xx). Don't force - SAC for these. Assume all masks <= 40 bits are of this - type. Normally this doesn't make any difference, but gives - more gentle handling of IOMMU overflow. */ - if (iommu_sac_force && (mask >= DMA_BIT_MASK(40))) { - dev_info(dev, "Force SAC with mask %llx\n", mask); - return 0; - } - return 1; } EXPORT_SYMBOL(iommu_dma_supported); -- 2.17.0 ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
[PATCH 3/7] ia64: remove iommu_dma_supported
The generic dma_direct_supported helper already used by intel-iommu on x86 does a better job than the ia64 reimplementation. Signed-off-by: Christoph Hellwig--- arch/ia64/kernel/pci-dma.c | 13 - drivers/iommu/intel-iommu.c | 2 -- 2 files changed, 15 deletions(-) diff --git a/arch/ia64/kernel/pci-dma.c b/arch/ia64/kernel/pci-dma.c index 50b6ad282a90..3c2884bef3d4 100644 --- a/arch/ia64/kernel/pci-dma.c +++ b/arch/ia64/kernel/pci-dma.c @@ -51,18 +51,6 @@ iommu_dma_init(void) return; } -int iommu_dma_supported(struct device *dev, u64 mask) -{ - /* Copied from i386. Doesn't make much sense, because it will - only work for pci_alloc_coherent. - The caller just has to use GFP_DMA in this case. */ - if (mask < DMA_BIT_MASK(24)) - return 0; - - return 1; -} -EXPORT_SYMBOL(iommu_dma_supported); - void __init pci_iommu_alloc(void) { dma_ops = _dma_ops; @@ -71,7 +59,6 @@ void __init pci_iommu_alloc(void) intel_dma_ops.sync_sg_for_cpu = machvec_dma_sync_sg; intel_dma_ops.sync_single_for_device = machvec_dma_sync_single; intel_dma_ops.sync_sg_for_device = machvec_dma_sync_sg; - intel_dma_ops.dma_supported = iommu_dma_supported; /* * The order of these functions is important for diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c index 749d8f235346..5e0bef3754d1 100644 --- a/drivers/iommu/intel-iommu.c +++ b/drivers/iommu/intel-iommu.c @@ -3841,9 +3841,7 @@ const struct dma_map_ops intel_dma_ops = { .map_page = intel_map_page, .unmap_page = intel_unmap_page, .mapping_error = intel_mapping_error, -#ifdef CONFIG_X86 .dma_supported = dma_direct_supported, -#endif }; static inline int iommu_domain_cache_init(void) -- 2.17.0 ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
refactor 32-bit dma limit quirks
Hi all, x86 currently has some quirks to force lower dma masks. They are mostly useful for certain VIA systems that otherwise corrupt data, but otherwise don't make much sense given that the modern DMA APIs do the right thing automatically. This series dumps a few of these old kernel command lines (including their not really working version on ia64), and moves the VIA quirk to a flag in struct device so that it can be apply generically. This will be needed to support Xylinx root ports with a similar issue that show up in common RISC-V boards. ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
[PATCH 1/7] core, dma-direct: add a flag 32-bit dma limits
Various PCI bridges (VIA PCI, Xilinx PCIe) limit DMA to only 32-bits even if the device itself supports more. Add a single bit flag to struct device (to be moved into the dma extension once we around it) to flag such devices and reject larger DMA to them. Signed-off-by: Christoph Hellwig--- include/linux/device.h | 3 +++ lib/dma-direct.c | 6 ++ 2 files changed, 9 insertions(+) diff --git a/include/linux/device.h b/include/linux/device.h index 477956990f5e..fa317e45f5e6 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -904,6 +904,8 @@ struct dev_links_info { * @offline: Set after successful invocation of bus type's .offline(). * @of_node_reused: Set if the device-tree node is shared with an ancestor * device. + * @dma_32bit_limit: bridge limited to 32bit DMA even if the device itself + * indicates support for a higher limit in the dma_mask field. * * At the lowest level, every device in a Linux system is represented by an * instance of struct device. The device structure contains the information @@ -992,6 +994,7 @@ struct device { booloffline_disabled:1; booloffline:1; boolof_node_reused:1; + booldma_32bit_limit:1; }; static inline struct device *kobj_to_dev(struct kobject *kobj) diff --git a/lib/dma-direct.c b/lib/dma-direct.c index bbfb229aa067..0151a7b2bc87 100644 --- a/lib/dma-direct.c +++ b/lib/dma-direct.c @@ -165,6 +165,12 @@ int dma_direct_supported(struct device *dev, u64 mask) if (mask < DMA_BIT_MASK(32)) return 0; #endif + /* +* Various PCI/PCIe bridges have broken support for > 32bit DMA even +* if the device itself might support it. +*/ + if (dev->dma_32bit_limit && mask > DMA_BIT_MASK(32)) + return 0; return 1; } -- 2.17.0 ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
RE: [PATCH v2 39/40] iommu/arm-smmu-v3: Add support for PRI
> > For PCI devices that support it, enable the PRI capability and handle PRI Page > Requests with the generic fault handler. It is enabled on demand by > iommu_sva_device_init(). > > Signed-off-by: Jean-Philippe Brucker> > --- > v1->v2: > * Terminate the page request and disable PRI if no handler is registered > * Enable and disable PRI in sva_device_init/shutdown, instead of > add/remove_device > --- > drivers/iommu/arm-smmu-v3.c | 192 +++--- > -- > 1 file changed, 145 insertions(+), 47 deletions(-) > > diff --git a/drivers/iommu/arm-smmu-v3.c b/drivers/iommu/arm-smmu-v3.c > index 6cb69ace371b..0edbb8d19579 100644 > --- a/drivers/iommu/arm-smmu-v3.c > +++ b/drivers/iommu/arm-smmu-v3.c > @@ -248,6 +248,7 @@ > #define STRTAB_STE_1_S1COR GENMASK_ULL(5, 4) > #define STRTAB_STE_1_S1CSH GENMASK_ULL(7, 6) > > +#define STRTAB_STE_1_PPAR(1UL << 18) > #define STRTAB_STE_1_S1STALLD(1UL << 27) > > #define STRTAB_STE_1_EATSGENMASK_ULL(29, 28) > @@ -309,6 +310,9 @@ > #define CMDQ_PRI_0_SID GENMASK_ULL(63, 32) > #define CMDQ_PRI_1_GRPID GENMASK_ULL(8, 0) > #define CMDQ_PRI_1_RESP GENMASK_ULL(13, 12) > +#define CMDQ_PRI_1_RESP_FAILURE > FIELD_PREP(CMDQ_PRI_1_RESP, 0UL) > +#define CMDQ_PRI_1_RESP_INVALID > FIELD_PREP(CMDQ_PRI_1_RESP, 1UL) > +#define CMDQ_PRI_1_RESP_SUCCESS > FIELD_PREP(CMDQ_PRI_1_RESP, 2UL) > > #define CMDQ_RESUME_0_SIDGENMASK_ULL(63, 32) > #define CMDQ_RESUME_0_ACTION_RETRY (1UL << 12) > @@ -383,12 +387,6 @@ module_param_named(disable_ats_check, > disable_ats_check, bool, S_IRUGO); > MODULE_PARM_DESC(disable_ats_check, > "By default, the SMMU checks whether each incoming transaction > marked as translated is allowed by the stream configuration. This option > disables the check."); > > -enum pri_resp { > - PRI_RESP_DENY = 0, > - PRI_RESP_FAIL = 1, > - PRI_RESP_SUCC = 2, > -}; > - > enum arm_smmu_msi_index { > EVTQ_MSI_INDEX, > GERROR_MSI_INDEX, > @@ -471,7 +469,7 @@ struct arm_smmu_cmdq_ent { > u32 sid; > u32 ssid; > u16 grpid; > - enum pri_resp resp; > + enum page_response_code resp; > } pri; > > #define CMDQ_OP_RESUME 0x44 > @@ -556,6 +554,7 @@ struct arm_smmu_strtab_ent { > struct arm_smmu_s2_cfg *s2_cfg; > > boolcan_stall; > + boolprg_resp_needs_ssid; > }; > > struct arm_smmu_strtab_cfg { > @@ -907,14 +906,18 @@ static int arm_smmu_cmdq_build_cmd(u64 *cmd, > struct arm_smmu_cmdq_ent *ent) > cmd[0] |= FIELD_PREP(CMDQ_PRI_0_SID, ent->pri.sid); > cmd[1] |= FIELD_PREP(CMDQ_PRI_1_GRPID, ent->pri.grpid); > switch (ent->pri.resp) { > - case PRI_RESP_DENY: > - case PRI_RESP_FAIL: > - case PRI_RESP_SUCC: > + case IOMMU_PAGE_RESP_FAILURE: > + cmd[1] |= CMDQ_PRI_1_RESP_FAILURE; > + break; > + case IOMMU_PAGE_RESP_INVALID: > + cmd[1] |= CMDQ_PRI_1_RESP_INVALID; > + break; > + case IOMMU_PAGE_RESP_SUCCESS: > + cmd[1] |= CMDQ_PRI_1_RESP_SUCCESS; > break; > default: > return -EINVAL; > } > - cmd[1] |= FIELD_PREP(CMDQ_PRI_1_RESP, ent->pri.resp); > break; > case CMDQ_OP_RESUME: > cmd[0] |= FIELD_PREP(CMDQ_RESUME_0_SID, ent- > >resume.sid); @@ -1114,8 +1117,15 @@ static int > arm_smmu_page_response(struct device *dev, > cmd.resume.sid = sid; > cmd.resume.stag = resp->page_req_group_id; > cmd.resume.resp = resp->resp_code; > + } else if (master->can_fault) { > + cmd.opcode = CMDQ_OP_PRI_RESP; > + cmd.substream_valid = resp->pasid_present && > + master->ste.prg_resp_needs_ssid; > + cmd.pri.sid = sid; > + cmd.pri.ssid= resp->pasid; > + cmd.pri.grpid = resp->page_req_group_id; > + cmd.pri.resp= resp->resp_code; > } else { > - /* TODO: put PRI response here */ > return -ENODEV; > } > > @@ -1236,6 +1246,9 @@ static void arm_smmu_write_strtab_ent(struct > arm_smmu_device *smmu, u32 sid, >FIELD_PREP(STRTAB_STE_1_S1CSH, > ARM_SMMU_SH_ISH) | >FIELD_PREP(STRTAB_STE_1_STRW, strw)); > > + if (ste->prg_resp_needs_ssid)
Re: [PATCH] drm/rockchip: vop: fix irq disabled after vop driver probed
Hi Marc, Am Freitag, 25. Mai 2018, 13:07:02 CEST schrieb Marc Zyngier: > [Thanks Robin for pointing me to that patch.] > > Hi Heiko, > > On 24/05/18 23:06, Heiko Stübner wrote: > > From: Sandy Huang> > > > The vop irq is shared between vop and iommu and irq probing in the > > iommu driver moved to the probe function recently. This can in some > > cases lead to a stall if the irq is triggered while the vop driver > > still has it disabled. > > > > But there is no real need to disable the irq, as the vop can simply > > also track its enabled state and ignore irqs in that case. > > > > So remove the enable/disable handling and add appropriate condition > > to the irq handler. > > > > Signed-off-by: Sandy Huang > > [added an actual commit message] > > Signed-off-by: Heiko Stuebner > > --- > > Hi Ezequiel, > > > > this patch came from a discussion I had with Rockchip people over the > > iommu changes and resulting issues back in april, but somehow was > > forgotten and not posted to the lists. Correcting that now. > > > > So removing the enable/disable voodoo on the shared interrupt is > > the preferred way. > > > > drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 13 ++--- > > 1 file changed, 7 insertions(+), 7 deletions(-) > > > > diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c > > b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c > > index 510cdf0..61493d4 100644 > > --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c > > +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c > > @@ -549,8 +549,6 @@ static int vop_enable(struct drm_crtc *crtc) > > > > spin_unlock(>reg_lock); > > > > - enable_irq(vop->irq); > > - > > drm_crtc_vblank_on(crtc); > > > > return 0; > > @@ -596,8 +594,6 @@ static void vop_crtc_atomic_disable(struct drm_crtc > > *crtc, > > > > vop_dsp_hold_valid_irq_disable(vop); > > > > - disable_irq(vop->irq); > > - > > vop->is_enabled = false; > > > > /* > > @@ -1168,6 +1164,13 @@ static irqreturn_t vop_isr(int irq, void *data) > > int ret = IRQ_NONE; > > > > /* > > +* since the irq is shared with iommu, iommu irq is enabled before vop > > +* enable, so before vop enable we do nothing. > > +*/ > > + if (!vop->is_enabled) > > + return IRQ_NONE; > > + > > What guarantee do we have that the IOMMU will actually service that > interrupt? Can't we get into a situation where the interrupt gets > ignored by both drivers and subsequently disabled by the core irq code > as being spurious? > > From what I understood of the way things are plugged together on the > rockchip platforms, each individual VOP is behind a single IOMMU, hence > there there is hardly any point in handling IOMMU interrupts if the VOP > is off. Yeah, which is probably the reason that patch fell through the cracks initially. I resurrected it from the internal discussion because of the issue described below. > But I'm missing the actual reason behind this patch. Could you enlighten me? Recently the iommu driver moved the irq request from the iommu enablement to its probe function. With that change Ezequiel got various stalls, see https://lkml.org/lkml/2018/5/24/1347 Heiko ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
Re: [RFC PATCH v2 00/12] get rid of GFP_ZONE_TABLE/BAD
On Thu, May 24, 2018 at 05:29:43PM +0200, Michal Hocko wrote: > > ie if we had more, > > could we solve our pain by making them more generic? > > Well, if you have more you will consume more bits in the struct pages, > right? Not necessarily ... the zone number is stored in the struct page currently, so either two or three bits are used right now. In my proposal, one can infer the zone of a page from its PFN, except for ZONE_MOVABLE. So we could trim down to just one bit per struct page for 32-bit machines while using 3 bits on 64-bit machines, where there is plenty of space. > > it more-or-less sucks that the devices with 28-bit DMA limits are forced > > to allocate from the low 16MB when they're perfectly capable of using the > > low 256MB. > > Do we actually care all that much about those? If yes then we should > probably follow the ZONE_DMA (x86) path and use a CMA region for them. > I mean most devices should be good with very limited addressability or > below 4G, no? Sure. One other thing I meant to mention was the media devices (TV capture cards and so on) which want a vmalloc_32() allocation. On 32-bit machines right now, we allocate from LOWMEM, when we really should be allocating from the 1GB-4GB region. 32-bit machines generally don't have a ZONE_DMA32 today. ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
Re: [PATCH v2 7/8] iommu: Remove IOMMU_OF_DECLARE
On Thu, May 24, 2018 at 12:50:23PM -0500, Rob Herring wrote: > Now that we use the driver core to stop deferred probe for missing > drivers, IOMMU_OF_DECLARE can be removed. > > This is slightly less optimal than having a list of built-in drivers in > that we'll now defer probe twice before giving up. This shouldn't have a > significant impact on boot times as past discussions about deferred > probe have given no evidence of deferred probe having a substantial > impact. > > Cc: Will Deacon> Cc: Robin Murphy > Cc: Joerg Roedel > Cc: Marek Szyprowski > Cc: Kukjin Kim > Cc: Krzysztof Kozlowski > Cc: Rob Clark > Cc: Heiko Stuebner > Cc: Frank Rowand > Cc: linux-arm-ker...@lists.infradead.org > Cc: iommu@lists.linux-foundation.org > Cc: linux-samsung-...@vger.kernel.org > Cc: linux-arm-...@vger.kernel.org > Cc: linux-rockc...@lists.infradead.org > Cc: devicet...@vger.kernel.org > Signed-off-by: Rob Herring > --- > drivers/iommu/arm-smmu-v3.c| 2 -- > drivers/iommu/arm-smmu.c | 7 --- > drivers/iommu/exynos-iommu.c | 2 -- > drivers/iommu/ipmmu-vmsa.c | 3 --- > drivers/iommu/msm_iommu.c | 2 -- > drivers/iommu/of_iommu.c | 19 +-- > drivers/iommu/qcom_iommu.c | 2 -- > drivers/iommu/rockchip-iommu.c | 2 -- > include/linux/of_iommu.h | 4 > 9 files changed, 1 insertion(+), 42 deletions(-) > > diff --git a/drivers/iommu/arm-smmu-v3.c b/drivers/iommu/arm-smmu-v3.c > index 1d647104bccc..22bdabd3d8e0 100644 > --- a/drivers/iommu/arm-smmu-v3.c > +++ b/drivers/iommu/arm-smmu-v3.c > @@ -2915,8 +2915,6 @@ static struct platform_driver arm_smmu_driver = { > }; > module_platform_driver(arm_smmu_driver); > > -IOMMU_OF_DECLARE(arm_smmuv3, "arm,smmu-v3"); > - > MODULE_DESCRIPTION("IOMMU API for ARM architected SMMUv3 implementations"); > MODULE_AUTHOR("Will Deacon "); > MODULE_LICENSE("GPL v2"); > diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c > index 69e7c60792a8..9dd7cbaa3b0c 100644 > --- a/drivers/iommu/arm-smmu.c > +++ b/drivers/iommu/arm-smmu.c > @@ -2211,13 +2211,6 @@ static struct platform_driver arm_smmu_driver = { > }; > module_platform_driver(arm_smmu_driver); > > -IOMMU_OF_DECLARE(arm_smmuv1, "arm,smmu-v1"); > -IOMMU_OF_DECLARE(arm_smmuv2, "arm,smmu-v2"); > -IOMMU_OF_DECLARE(arm_mmu400, "arm,mmu-400"); > -IOMMU_OF_DECLARE(arm_mmu401, "arm,mmu-401"); > -IOMMU_OF_DECLARE(arm_mmu500, "arm,mmu-500"); > -IOMMU_OF_DECLARE(cavium_smmuv2, "cavium,smmu-v2"); > - > MODULE_DESCRIPTION("IOMMU API for ARM architected SMMU implementations"); > MODULE_AUTHOR("Will Deacon "); > MODULE_LICENSE("GPL v2"); For the SMMU drivers: Acked-by: Will Deacon Will ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
Re: [PATCH] drm/rockchip: vop: fix irq disabled after vop driver probed
[Thanks Robin for pointing me to that patch.] Hi Heiko, On 24/05/18 23:06, Heiko Stübner wrote: > From: Sandy Huang> > The vop irq is shared between vop and iommu and irq probing in the > iommu driver moved to the probe function recently. This can in some > cases lead to a stall if the irq is triggered while the vop driver > still has it disabled. > > But there is no real need to disable the irq, as the vop can simply > also track its enabled state and ignore irqs in that case. > > So remove the enable/disable handling and add appropriate condition > to the irq handler. > > Signed-off-by: Sandy Huang > [added an actual commit message] > Signed-off-by: Heiko Stuebner > --- > Hi Ezequiel, > > this patch came from a discussion I had with Rockchip people over the > iommu changes and resulting issues back in april, but somehow was > forgotten and not posted to the lists. Correcting that now. > > So removing the enable/disable voodoo on the shared interrupt is > the preferred way. > > drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 13 ++--- > 1 file changed, 7 insertions(+), 7 deletions(-) > > diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c > b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c > index 510cdf0..61493d4 100644 > --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c > +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c > @@ -549,8 +549,6 @@ static int vop_enable(struct drm_crtc *crtc) > > spin_unlock(>reg_lock); > > - enable_irq(vop->irq); > - > drm_crtc_vblank_on(crtc); > > return 0; > @@ -596,8 +594,6 @@ static void vop_crtc_atomic_disable(struct drm_crtc *crtc, > > vop_dsp_hold_valid_irq_disable(vop); > > - disable_irq(vop->irq); > - > vop->is_enabled = false; > > /* > @@ -1168,6 +1164,13 @@ static irqreturn_t vop_isr(int irq, void *data) > int ret = IRQ_NONE; > > /* > + * since the irq is shared with iommu, iommu irq is enabled before vop > + * enable, so before vop enable we do nothing. > + */ > + if (!vop->is_enabled) > + return IRQ_NONE; > + What guarantee do we have that the IOMMU will actually service that interrupt? Can't we get into a situation where the interrupt gets ignored by both drivers and subsequently disabled by the core irq code as being spurious? From what I understood of the way things are plugged together on the rockchip platforms, each individual VOP is behind a single IOMMU, hence there there is hardly any point in handling IOMMU interrupts if the VOP is off. But I'm missing the actual reason behind this patch. Could you enlighten me? Thanks, M. -- Jazz is not dead. It just smells funny... ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
Re: [PATCH v2 13/40] vfio: Add support for Shared Virtual Addressing
On 25/05/18 03:39, Xu Zaibo wrote: > Hi, > > On 2018/5/24 23:04, Jean-Philippe Brucker wrote: >> On 24/05/18 13:35, Xu Zaibo wrote: Right, sva_init() must be called once for any device that intends to use bind(). For the second process though, group->sva_enabled will be true so we won't call sva_init() again, only bind(). >>> Well, while I create mediated devices based on one parent device to support >>> multiple >>> processes(a new process will create a new 'vfio_group' for the >>> corresponding mediated device, >>> and 'sva_enabled' cannot work any more), in fact, *sva_init and >>> *sva_shutdown are basically >>> working on parent device, so, as a result, I just only need sva initiation >>> and shutdown on the >>> parent device only once. So I change the two as following: >>> >>> @@ -551,8 +565,18 @@ int iommu_sva_device_init(struct device *dev, unsigned >>> long features, >>>if (features & ~IOMMU_SVA_FEAT_IOPF) >>> return -EINVAL; >>> >>> +/* If already exists, do nothing */ >>> +mutex_lock(>iommu_param->lock); >>> +if (dev->iommu_param->sva_param) { >>> +mutex_unlock(>iommu_param->lock); >>> +return 0; >>> +} >>> +mutex_unlock(>iommu_param->lock); >>> >>> if (features & IOMMU_SVA_FEAT_IOPF) { >>> ret = iommu_register_device_fault_handler(dev, iommu_queue_iopf, >>> >>> >>> @@ -621,6 +646,14 @@ int iommu_sva_device_shutdown(struct device *dev) >>> if (!domain) >>> return -ENODEV; >>> >>> +/* If any other process is working on the device, shut down does >>> nothing. */ >>> +mutex_lock(>iommu_param->lock); >>> +if (!list_empty(>iommu_param->sva_param->mm_list)) { >>> +mutex_unlock(>iommu_param->lock); >>> +return 0; >>> +} >>> +mutex_unlock(>iommu_param->lock); >> I don't think iommu-sva.c is the best place for this, it's probably >> better to implement an intermediate layer (the mediating driver), that >> calls iommu_sva_device_init() and iommu_sva_device_shutdown() once. Then >> vfio-pci would still call these functions itself, but for mdev the >> mediating driver keeps a refcount of groups, and calls device_shutdown() >> only when freeing the last mdev. >> >> A device driver (non mdev in this example) expects to be able to free >> all its resources after sva_device_shutdown() returns. Imagine the >> mm_list isn't empty (mm_exit() is running late), and instead of waiting >> in unbind_dev_all() below, we return 0 immediately. Then the calling >> driver frees its resources, and the mm_exit callback along with private >> data passed to bind() disappear. If a mm_exit() is still running in >> parallel, then it will try to access freed data and corrupt memory. So >> in this function if mm_list isn't empty, the only thing we can do is wait. >> > I still don't understand why we should 'unbind_dev_all', is it possible > to do a 'unbind_dev_pasid'? Not in sva_device_shutdown(), it needs to clean up everything. For example you want to physically unplug the device, or assign it to a VM. To prevent any leak sva_device_shutdown() needs to remove all bonds. In theory there shouldn't be any, since either the driver did unbind_dev(), or all process exited. This is a safety net. > Then we can do other things instead of waiting that user may not like. :) They may not like it, but it's for their own good :) At the moment we're waiting that: * All exit_mm() callback for this device have finished. If we don't wait then the caller will free the private data passed to bind and the mm_exit() callback while they are still being used. * All page requests targeting this device are dealt with. If we don't wait then some requests, that are lingering in the IOMMU PRI queue, may hit the next contexts bound to this device, possibly in a different VM. It may not be too risky (though probably exploitable in some way), but is incredibly messy. All of this is bounded in time, and normally should be over pretty fast unless the device driver's exit_mm() does something strange. If the driver did the right thing, there shouldn't be any wait here (although there may be one in unbind_dev() for the same reasons - prevent use after free). Thanks, Jean ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
[PATCH 25/25] MIPS: remove unneeded includes from dma-mapping.h
Keep this file as light as possible as it gets pulled into every driver using dma mapping APIs. Signed-off-by: Christoph Hellwig--- arch/mips/include/asm/dma-mapping.h | 8 arch/mips/mti-malta/malta-setup.c | 1 + 2 files changed, 1 insertion(+), 8 deletions(-) diff --git a/arch/mips/include/asm/dma-mapping.h b/arch/mips/include/asm/dma-mapping.h index 143250986e17..1c6e0c8ef483 100644 --- a/arch/mips/include/asm/dma-mapping.h +++ b/arch/mips/include/asm/dma-mapping.h @@ -2,14 +2,6 @@ #ifndef _ASM_DMA_MAPPING_H #define _ASM_DMA_MAPPING_H -#include -#include -#include - -#ifndef CONFIG_SGI_IP27 /* Kludge to fix 2.6.39 build for IP27 */ -#include -#endif - extern const struct dma_map_ops jazz_dma_ops; extern const struct dma_map_ops mips_swiotlb_ops; diff --git a/arch/mips/mti-malta/malta-setup.c b/arch/mips/mti-malta/malta-setup.c index 4d5cdfeee3db..7cb7d5a42087 100644 --- a/arch/mips/mti-malta/malta-setup.c +++ b/arch/mips/mti-malta/malta-setup.c @@ -26,6 +26,7 @@ #include #include +#include #include #include #include -- 2.17.0 ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
[PATCH 24/25] MIPS: remove the old dma-default implementation
Now unused. Signed-off-by: Christoph Hellwig--- arch/mips/Kconfig | 5 +- arch/mips/include/asm/dma-mapping.h | 3 - .../include/asm/mach-generic/dma-coherence.h | 73 arch/mips/mm/Makefile | 1 - arch/mips/mm/dma-default.c| 379 -- 5 files changed, 1 insertion(+), 460 deletions(-) delete mode 100644 arch/mips/include/asm/mach-generic/dma-coherence.h delete mode 100644 arch/mips/mm/dma-default.c diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 9ac3c6260b68..ad5a542bf094 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -72,9 +72,6 @@ config MIPS select SYSCTL_EXCEPTION_TRACE select VIRT_TO_BUS -config MIPS_DMA_DEFAULT - bool - menu "Machine selection" choice @@ -1113,7 +1110,7 @@ config DMA_NONCOHERENT select NEED_DMA_MAP_STATE select DMA_NONCOHERENT_MMAP select DMA_NONCOHERENT_CACHE_SYNC - select DMA_NONCOHERENT_OPS if !MIPS_DMA_DEFAULT + select DMA_NONCOHERENT_OPS config SYS_HAS_EARLY_PRINTK bool diff --git a/arch/mips/include/asm/dma-mapping.h b/arch/mips/include/asm/dma-mapping.h index caf97f739897..143250986e17 100644 --- a/arch/mips/include/asm/dma-mapping.h +++ b/arch/mips/include/asm/dma-mapping.h @@ -11,7 +11,6 @@ #endif extern const struct dma_map_ops jazz_dma_ops; -extern const struct dma_map_ops mips_default_dma_map_ops; extern const struct dma_map_ops mips_swiotlb_ops; static inline const struct dma_map_ops *get_arch_dma_ops(struct bus_type *bus) @@ -20,8 +19,6 @@ static inline const struct dma_map_ops *get_arch_dma_ops(struct bus_type *bus) return _dma_ops; #elif defined(CONFIG_SWIOTLB) return _swiotlb_ops; -#elif defined(CONFIG_MIPS_DMA_DEFAULT) - return _default_dma_map_ops; #elif defined(CONFIG_DMA_NONCOHERENT_OPS) return _noncoherent_ops; #else diff --git a/arch/mips/include/asm/mach-generic/dma-coherence.h b/arch/mips/include/asm/mach-generic/dma-coherence.h deleted file mode 100644 index 8ad7a40ca786.. --- a/arch/mips/include/asm/mach-generic/dma-coherence.h +++ /dev/null @@ -1,73 +0,0 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 2006 Ralf Baechle - * - */ -#ifndef __ASM_MACH_GENERIC_DMA_COHERENCE_H -#define __ASM_MACH_GENERIC_DMA_COHERENCE_H - -struct device; - -static inline dma_addr_t plat_map_dma_mem(struct device *dev, void *addr, - size_t size) -{ - return virt_to_phys(addr); -} - -static inline dma_addr_t plat_map_dma_mem_page(struct device *dev, - struct page *page) -{ - return page_to_phys(page); -} - -static inline unsigned long plat_dma_addr_to_phys(struct device *dev, - dma_addr_t dma_addr) -{ - return dma_addr; -} - -static inline void plat_unmap_dma_mem(struct device *dev, dma_addr_t dma_addr, - size_t size, enum dma_data_direction direction) -{ -} - -static inline int plat_dma_supported(struct device *dev, u64 mask) -{ - /* -* we fall back to GFP_DMA when the mask isn't all 1s, -* so we can't guarantee allocations that must be -* within a tighter range than GFP_DMA.. -*/ - if (mask < DMA_BIT_MASK(24)) - return 0; - - return 1; -} - -static inline int plat_device_is_coherent(struct device *dev) -{ -#ifdef CONFIG_DMA_PERDEV_COHERENT - return dev->archdata.dma_coherent; -#else - switch (coherentio) { - default: - case IO_COHERENCE_DEFAULT: - return hw_coherentio; - case IO_COHERENCE_ENABLED: - return 1; - case IO_COHERENCE_DISABLED: - return 0; - } -#endif -} - -#ifndef plat_post_dma_flush -static inline void plat_post_dma_flush(struct device *dev) -{ -} -#endif - -#endif /* __ASM_MACH_GENERIC_DMA_COHERENCE_H */ diff --git a/arch/mips/mm/Makefile b/arch/mips/mm/Makefile index c6146c3805dc..6922f393af19 100644 --- a/arch/mips/mm/Makefile +++ b/arch/mips/mm/Makefile @@ -17,7 +17,6 @@ obj-$(CONFIG_32BIT) += ioremap.o pgtable-32.o obj-$(CONFIG_64BIT)+= pgtable-64.o obj-$(CONFIG_HIGHMEM) += highmem.o obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o -obj-$(CONFIG_MIPS_DMA_DEFAULT) += dma-default.o obj-$(CONFIG_DMA_NONCOHERENT) += dma-noncoherent.o obj-$(CONFIG_SWIOTLB) += dma-swiotlb.o diff --git a/arch/mips/mm/dma-default.c b/arch/mips/mm/dma-default.c deleted file mode 100644 index 10b56e8a2076.. --- a/arch/mips/mm/dma-default.c +++ /dev/null @@ -1,379 +0,0 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 2000 Ani Joshi
RE: [External] Re: [RFC PATCH v2 00/12] get rid of GFP_ZONE_TABLE/BAD
From: Michal Hocko [mailto:mho...@kernel.org] Sent: Thursday, May 24, 2018 8:19 PM> > > Let me try to reply your questions. > > Exactly, GFP_ZONE_TABLE is too complicated. I think there are two advantages > > from the series of patches. > > > > 1. XOR operation is simple and efficient, GFP_ZONE_TABLE/BAD need to do > > twice > > shift operations, the first is for getting a zone_type and the second is for > > checking the to be returned type is a correct or not. But with these patch > > XOR > > operation just needs to use once. Because the bottom 3 bits of GFP bitmask > > have > > been used to represent the encoded zone number, we can say there is no bad > > zone > > number if all callers could use it without buggy way. Of course, the > > returned > > zone type in gfp_zone needs to be no more than ZONE_MOVABLE. > > But you are losing the ability to check for wrong usage. And it seems > that the sad reality is that the existing code do screw up. In my opinion, originally there shouldn't be such many wrong combinations of these bottom 3 bits. For any user, whether or driver and fs, they should make a decision that which zone is they preferred. Matthew's idea is great, because with it the user must offer an unambiguous flag to gfp zone bits. Ideally, before any user wants to modify the address zone modifier, they should clear it firstly, then ORing the GFP zone flag which comes from the zone they prefer. With these patches, we can loudly announce that, the bottom 3 bits of zone mask couldn't accept internal ORing operations. The operations like __GFP_DMA | __GFP_DMA32 | __GFP_HIGHMEM is illegal. The current GFP_ZONE_TABLE is precisely the root of this problem, that is __GFP_DMA, __GFP_DMA32 and __GFP_HIGHMEM are formatted as 0x1, 0x2 and 0x4. > > > 2. GFP_ZONE_TABLE has limit with the amount of zone types. Current > > GFP_ZONE_TABLE > > is 32 bits, in general, there are 4 zone types for most ofX86_64 platform, > > they > > are ZONE_DMA, ZONE_DMA32, ZONE_NORMAL and ZONE_MOVABLE. If we want to > > expand the > > amount of zone types to larger than 4, the zone shift should be 3. > > But we do not want to expand the number of zones IMHO. The existing zoo > is quite a maint. pain. > > That being said. I am not saying that I am in love with GFP_ZONE_TABLE. > It always makes my head explode when I look there but it seems to work > with the current code and it is optimized for it. If you want to change > this then you should make sure you describe reasons _why_ this is an > improvement. And I would argue that "we can have more zones" is a > relevant one. Yes, GFP_ZONE_TABLE is too complicated. The patches have 4 advantages as below. * The address zone modifiers have new operation method, that is, user should decide which zone is preferred at first, then give the encoded zone number to bottom 3 bits in GFP mask. That is much direct and clear than before. * No bad zone combination, because user should choose just one address zone modifier always. * Better performance and efficiency, current gfp_zone has to take shifting operation twice for GFP_ZONE_TABLE and GFP_ZONE_BAD. With these patches, gfp_zone() just needs one XOR. * Up to 8 zones can be used. At least it isn't a disadvantage, right? Sincerely, Huaisheng Ye ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
Re: [PATCH v1] arch/x86/kernel/pci-dma: Remove useless parameter of arch_dma_alloc_attrs
Thanks, applied to the dma-mapping tree. ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
[PATCH 23/25] MIPS: bmips: use generic dma noncoherent ops
Provide phys_to_dma/dma_to_phys helpers, and the special arch_sync_dma_for_cpu_all hook, everything else is generic Signed-off-by: Christoph Hellwig--- arch/mips/Kconfig | 3 +- arch/mips/bmips/dma.c | 32 ++- arch/mips/include/asm/bmips.h | 16 -- .../include/asm/mach-bmips/dma-coherence.h| 54 --- 4 files changed, 21 insertions(+), 84 deletions(-) delete mode 100644 arch/mips/include/asm/mach-bmips/dma-coherence.h diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 25a3c3262554..9ac3c6260b68 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -209,6 +209,8 @@ config ATH79 config BMIPS_GENERIC bool "Broadcom Generic BMIPS kernel" + select ARCH_HAS_SYNC_DMA_FOR_CPU_ALL + select ARCH_HAS_PHYS_TO_DMA select BOOT_RAW select NO_EXCEPT_FILL select USE_OF @@ -221,7 +223,6 @@ config BMIPS_GENERIC select BCM7120_L2_IRQ select BRCMSTB_L2_IRQ select IRQ_MIPS_CPU - select MIPS_DMA_DEFAULT select DMA_NONCOHERENT select SYS_SUPPORTS_32BIT_KERNEL select SYS_SUPPORTS_LITTLE_ENDIAN diff --git a/arch/mips/bmips/dma.c b/arch/mips/bmips/dma.c index 04790f4e1805..02ba0e38748d 100644 --- a/arch/mips/bmips/dma.c +++ b/arch/mips/bmips/dma.c @@ -17,7 +17,7 @@ #include #include #include -#include +#include /* * BCM338x has configurable address translation windows which allow the @@ -40,7 +40,7 @@ static struct bmips_dma_range *bmips_dma_ranges; #define FLUSH_RAC 0x100 -static dma_addr_t bmips_phys_to_dma(struct device *dev, phys_addr_t pa) +dma_addr_t __phys_to_dma(struct device *dev, phys_addr_t pa) { struct bmips_dma_range *r; @@ -52,17 +52,7 @@ static dma_addr_t bmips_phys_to_dma(struct device *dev, phys_addr_t pa) return pa; } -dma_addr_t plat_map_dma_mem(struct device *dev, void *addr, size_t size) -{ - return bmips_phys_to_dma(dev, virt_to_phys(addr)); -} - -dma_addr_t plat_map_dma_mem_page(struct device *dev, struct page *page) -{ - return bmips_phys_to_dma(dev, page_to_phys(page)); -} - -unsigned long plat_dma_addr_to_phys(struct device *dev, dma_addr_t dma_addr) +phys_addr_t __dma_to_phys(struct device *dev, dma_addr_t dma_addr) { struct bmips_dma_range *r; @@ -74,6 +64,22 @@ unsigned long plat_dma_addr_to_phys(struct device *dev, dma_addr_t dma_addr) return dma_addr; } +void arch_sync_dma_for_cpu_all(struct device *dev) +{ + void __iomem *cbr = BMIPS_GET_CBR(); + u32 cfg; + + if (boot_cpu_type() != CPU_BMIPS3300 && + boot_cpu_type() != CPU_BMIPS4350 && + boot_cpu_type() != CPU_BMIPS4380) + return; + + /* Flush stale data out of the readahead cache */ + cfg = __raw_readl(cbr + BMIPS_RAC_CONFIG); + __raw_writel(cfg | 0x100, cbr + BMIPS_RAC_CONFIG); + __raw_readl(cbr + BMIPS_RAC_CONFIG); +} + static int __init bmips_init_dma_ranges(void) { struct device_node *np = diff --git a/arch/mips/include/asm/bmips.h b/arch/mips/include/asm/bmips.h index b3e2975f83d3..bf6a8afd7ad2 100644 --- a/arch/mips/include/asm/bmips.h +++ b/arch/mips/include/asm/bmips.h @@ -123,22 +123,6 @@ static inline void bmips_write_zscm_reg(unsigned int offset, unsigned long data) barrier(); } -static inline void bmips_post_dma_flush(struct device *dev) -{ - void __iomem *cbr = BMIPS_GET_CBR(); - u32 cfg; - - if (boot_cpu_type() != CPU_BMIPS3300 && - boot_cpu_type() != CPU_BMIPS4350 && - boot_cpu_type() != CPU_BMIPS4380) - return; - - /* Flush stale data out of the readahead cache */ - cfg = __raw_readl(cbr + BMIPS_RAC_CONFIG); - __raw_writel(cfg | 0x100, cbr + BMIPS_RAC_CONFIG); - __raw_readl(cbr + BMIPS_RAC_CONFIG); -} - #endif /* !defined(__ASSEMBLY__) */ #endif /* _ASM_BMIPS_H */ diff --git a/arch/mips/include/asm/mach-bmips/dma-coherence.h b/arch/mips/include/asm/mach-bmips/dma-coherence.h deleted file mode 100644 index d29781f02285.. --- a/arch/mips/include/asm/mach-bmips/dma-coherence.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (C) 2006 Ralf Baechle - * Copyright (C) 2009 Broadcom Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#ifndef __ASM_MACH_BMIPS_DMA_COHERENCE_H -#define __ASM_MACH_BMIPS_DMA_COHERENCE_H - -#include -#include -#include - -struct device; - -extern dma_addr_t plat_map_dma_mem(struct
[PATCH 22/25] dma-noncoherent: add a arch_sync_dma_for_cpu_all hook
The MIPS bmips platform needs a global flush when transferring ownership back to the CPU. Add a hook for that to the dma-noncoherent implementation. Signed-off-by: Christoph Hellwig--- include/linux/dma-noncoherent.h | 8 lib/dma-noncoherent.c | 8 ++-- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/include/linux/dma-noncoherent.h b/include/linux/dma-noncoherent.h index 10b2654d549b..a0aa00cc909d 100644 --- a/include/linux/dma-noncoherent.h +++ b/include/linux/dma-noncoherent.h @@ -44,4 +44,12 @@ static inline void arch_sync_dma_for_cpu(struct device *dev, } #endif /* ARCH_HAS_SYNC_DMA_FOR_CPU */ +#ifdef CONFIG_ARCH_HAS_SYNC_DMA_FOR_CPU_ALL +void arch_sync_dma_for_cpu_all(struct device *dev); +#else +static inline void arch_sync_dma_for_cpu_all(struct device *dev) +{ +} +#endif /* CONFIG_ARCH_HAS_SYNC_DMA_FOR_CPU_ALL */ + #endif /* _LINUX_DMA_NONCOHERENT_H */ diff --git a/lib/dma-noncoherent.c b/lib/dma-noncoherent.c index 79e9a757387f..031fe235d958 100644 --- a/lib/dma-noncoherent.c +++ b/lib/dma-noncoherent.c @@ -49,11 +49,13 @@ static int dma_noncoherent_map_sg(struct device *dev, struct scatterlist *sgl, return nents; } -#ifdef CONFIG_ARCH_HAS_SYNC_DMA_FOR_CPU +#if defined(CONFIG_ARCH_HAS_SYNC_DMA_FOR_CPU) || \ +defined(CONFIG_ARCH_HAS_SYNC_DMA_FOR_CPU_ALL) static void dma_noncoherent_sync_single_for_cpu(struct device *dev, dma_addr_t addr, size_t size, enum dma_data_direction dir) { arch_sync_dma_for_cpu(dev, dma_to_phys(dev, addr), size, dir); + arch_sync_dma_for_cpu_all(dev); } static void dma_noncoherent_sync_sg_for_cpu(struct device *dev, @@ -64,6 +66,7 @@ static void dma_noncoherent_sync_sg_for_cpu(struct device *dev, for_each_sg(sgl, sg, nents, i) arch_sync_dma_for_cpu(dev, sg_phys(sg), sg->length, dir); + arch_sync_dma_for_cpu_all(dev); } static void dma_noncoherent_unmap_page(struct device *dev, dma_addr_t addr, @@ -89,7 +92,8 @@ const struct dma_map_ops dma_noncoherent_ops = { .sync_sg_for_device = dma_noncoherent_sync_sg_for_device, .map_page = dma_noncoherent_map_page, .map_sg = dma_noncoherent_map_sg, -#ifdef CONFIG_ARCH_HAS_SYNC_DMA_FOR_CPU +#if defined(CONFIG_ARCH_HAS_SYNC_DMA_FOR_CPU) || \ +defined(CONFIG_ARCH_HAS_SYNC_DMA_FOR_CPU_ALL) .sync_single_for_cpu= dma_noncoherent_sync_single_for_cpu, .sync_sg_for_cpu= dma_noncoherent_sync_sg_for_cpu, .unmap_page = dma_noncoherent_unmap_page, -- 2.17.0 ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
[PATCH 21/25] MIPS: jazz: split dma mapping operations from dma-default
Jazz actually has a very basic IOMMU, so split the ops into a separate implementation from the generic default support (which is about to go away anyway). Signed-off-by: Christoph Hellwig--- arch/mips/include/asm/dma-mapping.h | 5 +- .../include/asm/mach-jazz/dma-coherence.h | 60 arch/mips/jazz/Kconfig| 3 - arch/mips/jazz/jazzdma.c | 141 +- 4 files changed, 144 insertions(+), 65 deletions(-) delete mode 100644 arch/mips/include/asm/mach-jazz/dma-coherence.h diff --git a/arch/mips/include/asm/dma-mapping.h b/arch/mips/include/asm/dma-mapping.h index e32a7b439816..caf97f739897 100644 --- a/arch/mips/include/asm/dma-mapping.h +++ b/arch/mips/include/asm/dma-mapping.h @@ -10,12 +10,15 @@ #include #endif +extern const struct dma_map_ops jazz_dma_ops; extern const struct dma_map_ops mips_default_dma_map_ops; extern const struct dma_map_ops mips_swiotlb_ops; static inline const struct dma_map_ops *get_arch_dma_ops(struct bus_type *bus) { -#ifdef CONFIG_SWIOTLB +#if defined(CONFIG_MACH_JAZZ) + return _dma_ops; +#elif defined(CONFIG_SWIOTLB) return _swiotlb_ops; #elif defined(CONFIG_MIPS_DMA_DEFAULT) return _default_dma_map_ops; diff --git a/arch/mips/include/asm/mach-jazz/dma-coherence.h b/arch/mips/include/asm/mach-jazz/dma-coherence.h deleted file mode 100644 index dc347c25c343.. --- a/arch/mips/include/asm/mach-jazz/dma-coherence.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 2006 Ralf Baechle - */ -#ifndef __ASM_MACH_JAZZ_DMA_COHERENCE_H -#define __ASM_MACH_JAZZ_DMA_COHERENCE_H - -#include - -struct device; - -static inline dma_addr_t plat_map_dma_mem(struct device *dev, void *addr, size_t size) -{ - return vdma_alloc(virt_to_phys(addr), size); -} - -static inline dma_addr_t plat_map_dma_mem_page(struct device *dev, - struct page *page) -{ - return vdma_alloc(page_to_phys(page), PAGE_SIZE); -} - -static inline unsigned long plat_dma_addr_to_phys(struct device *dev, - dma_addr_t dma_addr) -{ - return vdma_log2phys(dma_addr); -} - -static inline void plat_unmap_dma_mem(struct device *dev, dma_addr_t dma_addr, - size_t size, enum dma_data_direction direction) -{ - vdma_free(dma_addr); -} - -static inline int plat_dma_supported(struct device *dev, u64 mask) -{ - /* -* we fall back to GFP_DMA when the mask isn't all 1s, -* so we can't guarantee allocations that must be -* within a tighter range than GFP_DMA.. -*/ - if (mask < DMA_BIT_MASK(24)) - return 0; - - return 1; -} - -static inline void plat_post_dma_flush(struct device *dev) -{ -} - -static inline int plat_device_is_coherent(struct device *dev) -{ - return 0; -} - -#endif /* __ASM_MACH_JAZZ_DMA_COHERENCE_H */ diff --git a/arch/mips/jazz/Kconfig b/arch/mips/jazz/Kconfig index d3ae3e0356f6..06838f80a5d7 100644 --- a/arch/mips/jazz/Kconfig +++ b/arch/mips/jazz/Kconfig @@ -3,7 +3,6 @@ config ACER_PICA_61 bool "Support for Acer PICA 1 chipset" depends on MACH_JAZZ select DMA_NONCOHERENT - select MIPS_DMA_DEFAULT select SYS_SUPPORTS_LITTLE_ENDIAN help This is a machine with a R4400 133/150 MHz CPU. To compile a Linux @@ -15,7 +14,6 @@ config MIPS_MAGNUM_4000 bool "Support for MIPS Magnum 4000" depends on MACH_JAZZ select DMA_NONCOHERENT - select MIPS_DMA_DEFAULT select SYS_SUPPORTS_BIG_ENDIAN select SYS_SUPPORTS_LITTLE_ENDIAN help @@ -28,7 +26,6 @@ config OLIVETTI_M700 bool "Support for Olivetti M700-10" depends on MACH_JAZZ select DMA_NONCOHERENT - select MIPS_DMA_DEFAULT select SYS_SUPPORTS_LITTLE_ENDIAN help This is a machine with a R4000 100 MHz CPU. To compile a Linux diff --git a/arch/mips/jazz/jazzdma.c b/arch/mips/jazz/jazzdma.c index d626a9a391cc..446fc8c92e1e 100644 --- a/arch/mips/jazz/jazzdma.c +++ b/arch/mips/jazz/jazzdma.c @@ -16,6 +16,8 @@ #include #include #include +#include +#include #include #include #include @@ -86,6 +88,7 @@ static int __init vdma_init(void) printk(KERN_INFO "VDMA: R4030 DMA pagetables initialized.\n"); return 0; } +arch_initcall(vdma_init); /* * Allocate DMA pagetables using a simple first-fit algorithm @@ -556,4 +559,140 @@ int vdma_get_enable(int channel) return enable; } -arch_initcall(vdma_init); +static void *jazz_dma_alloc(struct device *dev, size_t size, + dma_addr_t *dma_handle, gfp_t gfp, unsigned long attrs) +{ + void *ret; + + ret = dma_direct_alloc(dev, size, dma_handle, gfp, attrs); + if (!ret) +
[PATCH 20/25] MIPS: ath25: use generic dma noncoherent ops
Provide phys_to_dma/dma_to_phys helpers only if PCI support is enabled, everything else is generic. Signed-off-by: Christoph Hellwig--- arch/mips/Kconfig | 1 - arch/mips/ath25/Kconfig | 1 + .../include/asm/mach-ath25/dma-coherence.h| 71 --- arch/mips/pci/pci-ar2315.c| 24 +++ 4 files changed, 25 insertions(+), 72 deletions(-) delete mode 100644 arch/mips/include/asm/mach-ath25/dma-coherence.h diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index bde16399a8fe..25a3c3262554 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -176,7 +176,6 @@ config ATH25 select DMA_NONCOHERENT select IRQ_MIPS_CPU select IRQ_DOMAIN - select MIPS_DMA_DEFAULT select SYS_HAS_CPU_MIPS32_R1 select SYS_SUPPORTS_BIG_ENDIAN select SYS_SUPPORTS_32BIT_KERNEL diff --git a/arch/mips/ath25/Kconfig b/arch/mips/ath25/Kconfig index 7070b4bcd01d..2c1dfd06c366 100644 --- a/arch/mips/ath25/Kconfig +++ b/arch/mips/ath25/Kconfig @@ -12,6 +12,7 @@ config SOC_AR2315 config PCI_AR2315 bool "Atheros AR2315 PCI controller support" depends on SOC_AR2315 + select ARCH_HAS_PHYS_TO_DMA select HW_HAS_PCI select PCI default y diff --git a/arch/mips/include/asm/mach-ath25/dma-coherence.h b/arch/mips/include/asm/mach-ath25/dma-coherence.h deleted file mode 100644 index 124755d4f079.. --- a/arch/mips/include/asm/mach-ath25/dma-coherence.h +++ /dev/null @@ -1,71 +0,0 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 2006 Ralf Baechle - * Copyright (C) 2007 Felix Fietkau - * - */ -#ifndef __ASM_MACH_ATH25_DMA_COHERENCE_H -#define __ASM_MACH_ATH25_DMA_COHERENCE_H - -#include - -/* - * We need some arbitrary non-zero value to be programmed to the BAR1 register - * of PCI host controller to enable DMA. The same value should be used as the - * offset to calculate the physical address of DMA buffer for PCI devices. - */ -#define AR2315_PCI_HOST_SDRAM_BASEADDR 0x2000 - -static inline dma_addr_t ath25_dev_offset(struct device *dev) -{ -#ifdef CONFIG_PCI - extern struct bus_type pci_bus_type; - - if (dev && dev->bus == _bus_type) - return AR2315_PCI_HOST_SDRAM_BASEADDR; -#endif - return 0; -} - -static inline dma_addr_t -plat_map_dma_mem(struct device *dev, void *addr, size_t size) -{ - return virt_to_phys(addr) + ath25_dev_offset(dev); -} - -static inline dma_addr_t -plat_map_dma_mem_page(struct device *dev, struct page *page) -{ - return page_to_phys(page) + ath25_dev_offset(dev); -} - -static inline unsigned long -plat_dma_addr_to_phys(struct device *dev, dma_addr_t dma_addr) -{ - return dma_addr - ath25_dev_offset(dev); -} - -static inline void -plat_unmap_dma_mem(struct device *dev, dma_addr_t dma_addr, size_t size, - enum dma_data_direction direction) -{ -} - -static inline int plat_dma_supported(struct device *dev, u64 mask) -{ - return 1; -} - -static inline int plat_device_is_coherent(struct device *dev) -{ - return 0; -} - -static inline void plat_post_dma_flush(struct device *dev) -{ -} - -#endif /* __ASM_MACH_ATH25_DMA_COHERENCE_H */ diff --git a/arch/mips/pci/pci-ar2315.c b/arch/mips/pci/pci-ar2315.c index b4fa6413c4e5..c539d0d2b0cf 100644 --- a/arch/mips/pci/pci-ar2315.c +++ b/arch/mips/pci/pci-ar2315.c @@ -149,6 +149,13 @@ #define AR2315_PCI_HOST_SLOT 3 #define AR2315_PCI_HOST_DEVID ((0xff18 << 16) | PCI_VENDOR_ID_ATHEROS) +/* + * We need some arbitrary non-zero value to be programmed to the BAR1 register + * of PCI host controller to enable DMA. The same value should be used as the + * offset to calculate the physical address of DMA buffer for PCI devices. + */ +#define AR2315_PCI_HOST_SDRAM_BASEADDR 0x2000 + /* ??? access BAR */ #define AR2315_PCI_HOST_MBAR0 0x1000 /* RAM access BAR */ @@ -167,6 +174,23 @@ struct ar2315_pci_ctrl { struct resource io_res; }; +static inline dma_addr_t ar2315_dev_offset(struct device *dev) +{ + if (dev && dev_is_pci(dev)) + return AR2315_PCI_HOST_SDRAM_BASEADDR; + return 0; +} + +dma_addr_t __phys_to_dma(struct device *dev, phys_addr_t paddr) +{ + return paddr + ar2315_dev_offset(dev); +} + +phys_addr_t __dma_to_phys(struct device *dev, dma_addr_t dma_addr) +{ + return dma_addr - ar2315_dev_offset(dev); +} + static inline struct ar2315_pci_ctrl *ar2315_pci_bus_to_apc(struct pci_bus *bus) { struct pci_controller *hose = bus->sysdata; -- 2.17.0 ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
[PATCH 19/25] MIPS: IP32: use generic dma noncoherent ops
Provide phys_to_dma/dma_to_phys helpers, everything else is generic. Signed-off-by: Christoph Hellwig--- arch/mips/Kconfig | 2 +- .../include/asm/mach-ip32/dma-coherence.h | 92 --- arch/mips/sgi-ip32/Makefile | 2 +- arch/mips/sgi-ip32/ip32-dma.c | 37 4 files changed, 39 insertions(+), 94 deletions(-) delete mode 100644 arch/mips/include/asm/mach-ip32/dma-coherence.h create mode 100644 arch/mips/sgi-ip32/ip32-dma.c diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 3140955bc77c..bde16399a8fe 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -720,6 +720,7 @@ config SGI_IP28 config SGI_IP32 bool "SGI IP32 (O2)" + select ARCH_HAS_PHYS_TO_DMA select FW_ARC select FW_ARC32 select BOOT_ELF32 @@ -728,7 +729,6 @@ config SGI_IP32 select DMA_NONCOHERENT select HW_HAS_PCI select IRQ_MIPS_CPU - select MIPS_DMA_DEFAULT select R5000_CPU_SCACHE select RM7000_CPU_SCACHE select SYS_HAS_CPU_R5000 diff --git a/arch/mips/include/asm/mach-ip32/dma-coherence.h b/arch/mips/include/asm/mach-ip32/dma-coherence.h deleted file mode 100644 index 7bdf212587a0.. --- a/arch/mips/include/asm/mach-ip32/dma-coherence.h +++ /dev/null @@ -1,92 +0,0 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 2006 Ralf Baechle - * - */ -#ifndef __ASM_MACH_IP32_DMA_COHERENCE_H -#define __ASM_MACH_IP32_DMA_COHERENCE_H - -#include - -struct device; - -/* - * Few notes. - * 1. CPU sees memory as two chunks: 0-256M@0x0, and the rest @0x4000+256M - * 2. PCI sees memory as one big chunk @0x0 (or we could use 0x4000 for - *native-endian) - * 3. All other devices see memory as one big chunk at 0x4000 - * 4. Non-PCI devices will pass NULL as struct device* - * - * Thus we translate differently, depending on device. - */ - -#define RAM_OFFSET_MASK 0x3fffUL - -static inline dma_addr_t plat_map_dma_mem(struct device *dev, void *addr, - size_t size) -{ - dma_addr_t pa = virt_to_phys(addr) & RAM_OFFSET_MASK; - - if (dev == NULL) - pa += CRIME_HI_MEM_BASE; - - return pa; -} - -static inline dma_addr_t plat_map_dma_mem_page(struct device *dev, - struct page *page) -{ - dma_addr_t pa; - - pa = page_to_phys(page) & RAM_OFFSET_MASK; - - if (dev == NULL) - pa += CRIME_HI_MEM_BASE; - - return pa; -} - -/* This is almost certainly wrong but it's what dma-ip32.c used to use */ -static inline unsigned long plat_dma_addr_to_phys(struct device *dev, - dma_addr_t dma_addr) -{ - unsigned long addr = dma_addr & RAM_OFFSET_MASK; - - if (dma_addr >= 256*1024*1024) - addr += CRIME_HI_MEM_BASE; - - return addr; -} - -static inline void plat_unmap_dma_mem(struct device *dev, dma_addr_t dma_addr, - size_t size, enum dma_data_direction direction) -{ -} - -static inline int plat_dma_supported(struct device *dev, u64 mask) -{ - /* -* we fall back to GFP_DMA when the mask isn't all 1s, -* so we can't guarantee allocations that must be -* within a tighter range than GFP_DMA.. -*/ - if (mask < DMA_BIT_MASK(24)) - return 0; - - return 1; -} - -static inline void plat_post_dma_flush(struct device *dev) -{ -} - -static inline int plat_device_is_coherent(struct device *dev) -{ - return 0; /* IP32 is non-coherent */ -} - -#endif /* __ASM_MACH_IP32_DMA_COHERENCE_H */ diff --git a/arch/mips/sgi-ip32/Makefile b/arch/mips/sgi-ip32/Makefile index 60f0227425e7..4745cd94df11 100644 --- a/arch/mips/sgi-ip32/Makefile +++ b/arch/mips/sgi-ip32/Makefile @@ -4,4 +4,4 @@ # obj-y += ip32-berr.o ip32-irq.o ip32-platform.o ip32-setup.o ip32-reset.o \ - crime.o ip32-memory.o + crime.o ip32-memory.o ip32-dma.o diff --git a/arch/mips/sgi-ip32/ip32-dma.c b/arch/mips/sgi-ip32/ip32-dma.c new file mode 100644 index ..fa7b17cb5385 --- /dev/null +++ b/arch/mips/sgi-ip32/ip32-dma.c @@ -0,0 +1,37 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2006 Ralf Baechle + */ +#include +#include + +/* + * Few notes. + * 1. CPU sees memory as two chunks: 0-256M@0x0, and the rest @0x4000+256M + * 2. PCI sees memory as one big chunk @0x0 (or we could use 0x4000 for + *native-endian) + * 3. All other devices see memory as one big chunk at 0x4000 + * 4. Non-PCI devices will pass NULL as struct device* + * + * Thus we translate differently, depending on device. + */ + +#define RAM_OFFSET_MASK 0x3fffUL + +dma_addr_t __phys_to_dma(struct device *dev, phys_addr_t paddr) +{ + dma_addr_t dma_addr = paddr &
[PATCH 18/25] MIPS: loongson64: use generic dma noncoherent ops
Provide phys_to_dma/dma_to_phys helpers, everything else is generic. Signed-off-by: Christoph Hellwig--- arch/mips/Kconfig | 1 + .../asm/mach-loongson64/dma-coherence.h | 69 --- arch/mips/loongson64/Kconfig | 2 - arch/mips/loongson64/common/Makefile | 1 + arch/mips/loongson64/common/dma.c | 16 + 5 files changed, 18 insertions(+), 71 deletions(-) delete mode 100644 arch/mips/include/asm/mach-loongson64/dma-coherence.h create mode 100644 arch/mips/loongson64/common/dma.c diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index b39b430c92a3..3140955bc77c 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -1822,6 +1822,7 @@ config CPU_LOONGSON2 select CPU_SUPPORTS_64BIT_KERNEL select CPU_SUPPORTS_HIGHMEM select CPU_SUPPORTS_HUGEPAGES + select ARCH_HAS_PHYS_TO_DMA config CPU_LOONGSON1 bool diff --git a/arch/mips/include/asm/mach-loongson64/dma-coherence.h b/arch/mips/include/asm/mach-loongson64/dma-coherence.h deleted file mode 100644 index 651dd2eb3ee5.. --- a/arch/mips/include/asm/mach-loongson64/dma-coherence.h +++ /dev/null @@ -1,69 +0,0 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 2006, 07 Ralf Baechle - * Copyright (C) 2007 Lemote, Inc. & Institute of Computing Technology - * Author: Fuxin Zhang, zhan...@lemote.com - * - */ -#ifndef __ASM_MACH_LOONGSON64_DMA_COHERENCE_H -#define __ASM_MACH_LOONGSON64_DMA_COHERENCE_H - -#ifdef CONFIG_SWIOTLB -#include -#endif - -struct device; - -static inline dma_addr_t plat_map_dma_mem(struct device *dev, void *addr, - size_t size) -{ - return virt_to_phys(addr) | 0x8000; -} - -static inline dma_addr_t plat_map_dma_mem_page(struct device *dev, - struct page *page) -{ - return page_to_phys(page) | 0x8000; -} - -static inline unsigned long plat_dma_addr_to_phys(struct device *dev, - dma_addr_t dma_addr) -{ -#if defined(CONFIG_CPU_LOONGSON2F) && defined(CONFIG_64BIT) - return (dma_addr > 0x8fff) ? dma_addr : (dma_addr & 0x0fff); -#else - return dma_addr & 0x7fff; -#endif -} - -static inline void plat_unmap_dma_mem(struct device *dev, dma_addr_t dma_addr, - size_t size, enum dma_data_direction direction) -{ -} - -static inline int plat_dma_supported(struct device *dev, u64 mask) -{ - /* -* we fall back to GFP_DMA when the mask isn't all 1s, -* so we can't guarantee allocations that must be -* within a tighter range than GFP_DMA.. -*/ - if (mask < DMA_BIT_MASK(24)) - return 0; - - return 1; -} - -static inline int plat_device_is_coherent(struct device *dev) -{ - return 0; -} - -static inline void plat_post_dma_flush(struct device *dev) -{ -} - -#endif /* __ASM_MACH_LOONGSON64_DMA_COHERENCE_H */ diff --git a/arch/mips/loongson64/Kconfig b/arch/mips/loongson64/Kconfig index a785bf8da3f3..c865b4b9b775 100644 --- a/arch/mips/loongson64/Kconfig +++ b/arch/mips/loongson64/Kconfig @@ -13,7 +13,6 @@ config LEMOTE_FULOONG2E select CSRC_R4K select SYS_HAS_CPU_LOONGSON2E select DMA_NONCOHERENT - select MIPS_DMA_DEFAULT select BOOT_ELF32 select BOARD_SCACHE select HW_HAS_PCI @@ -45,7 +44,6 @@ config LEMOTE_MACH2F select CS5536 select CSRC_R4K if ! MIPS_EXTERNAL_TIMER select DMA_NONCOHERENT - select MIPS_DMA_DEFAULT select GENERIC_ISA_DMA_SUPPORT_BROKEN select HAVE_CLK select HW_HAS_PCI diff --git a/arch/mips/loongson64/common/Makefile b/arch/mips/loongson64/common/Makefile index 684624f61f5a..57ee03022941 100644 --- a/arch/mips/loongson64/common/Makefile +++ b/arch/mips/loongson64/common/Makefile @@ -6,6 +6,7 @@ obj-y += setup.o init.o cmdline.o env.o time.o reset.o irq.o \ bonito-irq.o mem.o machtype.o platform.o serial.o obj-$(CONFIG_PCI) += pci.o +obj-$(CONFIG_CPU_LOONGSON2) += dma.o # # Serial port support diff --git a/arch/mips/loongson64/common/dma.c b/arch/mips/loongson64/common/dma.c new file mode 100644 index ..95ede4b0fbbb --- /dev/null +++ b/arch/mips/loongson64/common/dma.c @@ -0,0 +1,16 @@ +// SPDX-License-Identifier: GPL-2.0 +#include + +dma_addr_t __phys_to_dma(struct device *dev, phys_addr_t paddr) +{ + return paddr | 0x8000; +} + +phys_addr_t __dma_to_phys(struct device *dev, dma_addr_t dma_addr) +{ +#if defined(CONFIG_CPU_LOONGSON2F) && defined(CONFIG_64BIT) + if (dma_addr > 0x8fff) + return dma_addr; +#endif + return dma_addr & 0x0fff; +} -- 2.17.0 ___ iommu mailing list
[PATCH 17/25] MIPS: use generic dma noncoherent ops for simple noncoherent platforms
Convert everything not overriding dma-coherence.h to the generic noncoherent ops. The new dma-noncoherent.c file duplicates a lot of the code in dma-default.c, but that file will be gone by the end of this series. Signed-off-by: Christoph Hellwig--- arch/mips/Kconfig | 24 +--- arch/mips/include/asm/dma-mapping.h | 2 + arch/mips/loongson32/Kconfig| 2 - arch/mips/mm/Makefile | 1 + arch/mips/mm/dma-noncoherent.c | 208 arch/mips/pic32/Kconfig | 1 - arch/mips/txx9/Kconfig | 1 - arch/mips/vr41xx/Kconfig| 5 - 8 files changed, 216 insertions(+), 28 deletions(-) create mode 100644 arch/mips/mm/dma-noncoherent.c diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 934696595ad6..b39b430c92a3 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -96,7 +96,6 @@ config MIPS_GENERIC select IRQ_MIPS_CPU select LIBFDT select MIPS_CPU_SCACHE - select MIPS_DMA_DEFAULT select MIPS_GIC select MIPS_L1_CACHE_SHIFT_7 select NO_EXCEPT_FILL @@ -140,7 +139,6 @@ config MIPS_ALCHEMY select CEVT_R4K select CSRC_R4K select IRQ_MIPS_CPU - select MIPS_DMA_DEFAULT select DMA_MAYBE_COHERENT # Au1000,1500,1100 aren't, rest is select SYS_HAS_CPU_MIPS32_R1 select SYS_SUPPORTS_32BIT_KERNEL @@ -156,7 +154,6 @@ config AR7 select CEVT_R4K select CSRC_R4K select IRQ_MIPS_CPU - select MIPS_DMA_DEFAULT select NO_EXCEPT_FILL select SWAP_IO_SPACE select SYS_HAS_CPU_MIPS32_R1 @@ -199,7 +196,6 @@ config ATH79 select COMMON_CLK select CLKDEV_LOOKUP select IRQ_MIPS_CPU - select MIPS_DMA_DEFAULT select MIPS_MACHINE select SYS_HAS_CPU_MIPS32_R2 select SYS_HAS_EARLY_PRINTK @@ -257,7 +253,6 @@ config BCM47XX select HW_HAS_PCI select IRQ_MIPS_CPU select SYS_HAS_CPU_MIPS32_R1 - select MIPS_DMA_DEFAULT select NO_EXCEPT_FILL select SYS_SUPPORTS_32BIT_KERNEL select SYS_SUPPORTS_LITTLE_ENDIAN @@ -281,7 +276,6 @@ config BCM63XX select SYNC_R4K select DMA_NONCOHERENT select IRQ_MIPS_CPU - select MIPS_DMA_DEFAULT select SYS_SUPPORTS_32BIT_KERNEL select SYS_SUPPORTS_BIG_ENDIAN select SYS_HAS_EARLY_PRINTK @@ -304,7 +298,6 @@ config MIPS_COBALT select I8259 select IRQ_MIPS_CPU select IRQ_GT641XX - select MIPS_DMA_DEFAULT select PCI_GT64XXX_PCI0 select PCI select SYS_HAS_CPU_NEVADA @@ -325,7 +318,6 @@ config MACH_DECSTATION select CPU_R4000_WORKAROUNDS if 64BIT select CPU_R4400_WORKAROUNDS if 64BIT select DMA_NONCOHERENT - select MIPS_DMA_DEFAULT select NO_IOPORT_MAP select IRQ_MIPS_CPU select SYS_HAS_CPU_R3000 @@ -385,7 +377,6 @@ config MACH_INGENIC select SYS_SUPPORTS_ZBOOT_UART16550 select DMA_NONCOHERENT select IRQ_MIPS_CPU - select MIPS_DMA_DEFAULT select PINCTRL select GPIOLIB select COMMON_CLK @@ -400,7 +391,6 @@ config LANTIQ select IRQ_MIPS_CPU select CEVT_R4K select CSRC_R4K - select MIPS_DMA_DEFAULT select SYS_HAS_CPU_MIPS32_R1 select SYS_HAS_CPU_MIPS32_R2 select SYS_SUPPORTS_BIG_ENDIAN @@ -428,7 +418,6 @@ config LASAT select SYS_HAS_EARLY_PRINTK select HW_HAS_PCI select IRQ_MIPS_CPU - select MIPS_DMA_DEFAULT select PCI_GT64XXX_PCI0 select MIPS_NILE4 select R5000_CPU_SCACHE @@ -474,7 +463,6 @@ config MACH_PISTACHIO select LIBFDT select MFD_SYSCON select MIPS_CPU_SCACHE - select MIPS_DMA_DEFAULT select MIPS_GIC select PINCTRL select REGULATOR @@ -507,7 +495,6 @@ config MIPS_MALTA select GENERIC_ISA_DMA select HAVE_PCSPKR_PLATFORM select IRQ_MIPS_CPU - select MIPS_DMA_DEFAULT select MIPS_GIC select HW_HAS_PCI select I8253 @@ -602,7 +589,6 @@ config PMC_MSP select SYS_SUPPORTS_BIG_ENDIAN select SYS_SUPPORTS_MIPS16 select IRQ_MIPS_CPU - select MIPS_DMA_DEFAULT select SERIAL_8250 select SERIAL_8250_CONSOLE select USB_EHCI_BIG_ENDIAN_MMIO @@ -620,7 +606,6 @@ config RALINK select BOOT_RAW select DMA_NONCOHERENT select IRQ_MIPS_CPU - select MIPS_DMA_DEFAULT select USE_OF select SYS_HAS_CPU_MIPS32_R1 select SYS_HAS_CPU_MIPS32_R2 @@ -647,7 +632,6 @@ config SGI_IP22 select I8259 select IP22_CPU_SCACHE select IRQ_MIPS_CPU - select MIPS_DMA_DEFAULT select GENERIC_ISA_DMA_SUPPORT_BROKEN select SGI_HAS_I8042 select SGI_HAS_INDYDOG @@ -708,7 +692,6 @@ config SGI_IP28
[PATCH 16/25] MIPS: move coherentio setup to setup.c
We want to be able to use it even when not building dma-default.c in the near future. Signed-off-by: Christoph Hellwig--- arch/mips/kernel/setup.c | 24 arch/mips/mm/dma-default.c | 23 --- 2 files changed, 24 insertions(+), 23 deletions(-) diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c index 563188ac6fa2..8dc72797d5cb 100644 --- a/arch/mips/kernel/setup.c +++ b/arch/mips/kernel/setup.c @@ -36,6 +36,7 @@ #include #include #include +#include #include #include #include @@ -1055,3 +1056,26 @@ static int __init debugfs_mips(void) } arch_initcall(debugfs_mips); #endif + +#if defined(CONFIG_DMA_MAYBE_COHERENT) && !defined(CONFIG_DMA_PERDEV_COHERENT) +/* User defined DMA coherency from command line. */ +enum coherent_io_user_state coherentio = IO_COHERENCE_DEFAULT; +EXPORT_SYMBOL_GPL(coherentio); +int hw_coherentio = 0; /* Actual hardware supported DMA coherency setting. */ + +static int __init setcoherentio(char *str) +{ + coherentio = IO_COHERENCE_ENABLED; + pr_info("Hardware DMA cache coherency (command line)\n"); + return 0; +} +early_param("coherentio", setcoherentio); + +static int __init setnocoherentio(char *str) +{ + coherentio = IO_COHERENCE_DISABLED; + pr_info("Software DMA cache coherency (command line)\n"); + return 0; +} +early_param("nocoherentio", setnocoherentio); +#endif diff --git a/arch/mips/mm/dma-default.c b/arch/mips/mm/dma-default.c index 2db6c2a6f964..10b56e8a2076 100644 --- a/arch/mips/mm/dma-default.c +++ b/arch/mips/mm/dma-default.c @@ -24,29 +24,6 @@ #include -#if defined(CONFIG_DMA_MAYBE_COHERENT) && !defined(CONFIG_DMA_PERDEV_COHERENT) -/* User defined DMA coherency from command line. */ -enum coherent_io_user_state coherentio = IO_COHERENCE_DEFAULT; -EXPORT_SYMBOL_GPL(coherentio); -int hw_coherentio = 0; /* Actual hardware supported DMA coherency setting. */ - -static int __init setcoherentio(char *str) -{ - coherentio = IO_COHERENCE_ENABLED; - pr_info("Hardware DMA cache coherency (command line)\n"); - return 0; -} -early_param("coherentio", setcoherentio); - -static int __init setnocoherentio(char *str) -{ - coherentio = IO_COHERENCE_DISABLED; - pr_info("Software DMA cache coherency (command line)\n"); - return 0; -} -early_param("nocoherentio", setnocoherentio); -#endif - static inline struct page *dma_addr_to_page(struct device *dev, dma_addr_t dma_addr) { -- 2.17.0 ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
[PATCH 15/25] MIPS: IP27: use dma_direct_ops
IP27 is coherent and has a reasonably direct mapping, just with a little per-bus offset added into the dma address. Signed-off-by: Christoph Hellwig--- arch/mips/Kconfig | 2 +- .../include/asm/mach-ip27/dma-coherence.h | 70 --- arch/mips/pci/pci-ip27.c | 14 3 files changed, 15 insertions(+), 71 deletions(-) delete mode 100644 arch/mips/include/asm/mach-ip27/dma-coherence.h diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 173e5714151c..934696595ad6 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -677,11 +677,11 @@ config SGI_IP22 config SGI_IP27 bool "SGI IP27 (Origin200/2000)" + select ARCH_HAS_PHYS_TO_DMA select FW_ARC select FW_ARC64 select BOOT_ELF64 select DEFAULT_SGI_PARTITION - select MIPS_DMA_DEFAULT select SYS_HAS_EARLY_PRINTK select HW_HAS_PCI select NR_CPUS_DEFAULT_64 diff --git a/arch/mips/include/asm/mach-ip27/dma-coherence.h b/arch/mips/include/asm/mach-ip27/dma-coherence.h deleted file mode 100644 index 04d862020ac9.. --- a/arch/mips/include/asm/mach-ip27/dma-coherence.h +++ /dev/null @@ -1,70 +0,0 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 2006 Ralf Baechle - * - */ -#ifndef __ASM_MACH_IP27_DMA_COHERENCE_H -#define __ASM_MACH_IP27_DMA_COHERENCE_H - -#include - -#define pdev_to_baddr(pdev, addr) \ - (BRIDGE_CONTROLLER(pdev->bus)->baddr + (addr)) -#define dev_to_baddr(dev, addr) \ - pdev_to_baddr(to_pci_dev(dev), (addr)) - -struct device; - -static inline dma_addr_t plat_map_dma_mem(struct device *dev, void *addr, - size_t size) -{ - dma_addr_t pa = dev_to_baddr(dev, virt_to_phys(addr)); - - return pa; -} - -static inline dma_addr_t plat_map_dma_mem_page(struct device *dev, - struct page *page) -{ - dma_addr_t pa = dev_to_baddr(dev, page_to_phys(page)); - - return pa; -} - -static inline unsigned long plat_dma_addr_to_phys(struct device *dev, - dma_addr_t dma_addr) -{ - return dma_addr & ~(0xffUL << 56); -} - -static inline void plat_unmap_dma_mem(struct device *dev, dma_addr_t dma_addr, - size_t size, enum dma_data_direction direction) -{ -} - -static inline int plat_dma_supported(struct device *dev, u64 mask) -{ - /* -* we fall back to GFP_DMA when the mask isn't all 1s, -* so we can't guarantee allocations that must be -* within a tighter range than GFP_DMA.. -*/ - if (mask < DMA_BIT_MASK(24)) - return 0; - - return 1; -} - -static inline void plat_post_dma_flush(struct device *dev) -{ -} - -static inline int plat_device_is_coherent(struct device *dev) -{ - return 1; /* IP27 non-coherent mode is unsupported */ -} - -#endif /* __ASM_MACH_IP27_DMA_COHERENCE_H */ diff --git a/arch/mips/pci/pci-ip27.c b/arch/mips/pci/pci-ip27.c index 0f09eafa5e3a..65b48d41a229 100644 --- a/arch/mips/pci/pci-ip27.c +++ b/arch/mips/pci/pci-ip27.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -182,6 +183,19 @@ int pcibios_plat_dev_init(struct pci_dev *dev) return 0; } +dma_addr_t __phys_to_dma(struct device *dev, phys_addr_t paddr) +{ + struct pci_dev *pdev = to_pci_dev(dev); + struct bridge_controller *bc = BRIDGE_CONTROLLER(pdev->bus); + + return bc->baddr + paddr; +} + +phys_addr_t __dma_to_phys(struct device *dev, dma_addr_t dma_addr) +{ + return dma_addr & ~(0xffUL << 56); +} + /* * Device might live on a subordinate PCI bus. XXX Walk up the chain of buses * to find the slot number in sense of the bridge device register. -- 2.17.0 ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
[PATCH 14/25] MIPS: use dma_direct_ops for coherent I/O
Switch the simple cache coherent architectures that don't require any DMA address translation to dma_direct_ops. We'll soon use at least parts of the direct DMA ops implementation for all platforms, so select the symbol globally. Signed-off-by: Christoph Hellwig--- arch/mips/Kconfig | 15 +-- arch/mips/include/asm/dma-mapping.h | 2 +- 2 files changed, 2 insertions(+), 15 deletions(-) diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 24cc20ea60b9..173e5714151c 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -16,6 +16,7 @@ config MIPS select BUILDTIME_EXTABLE_SORT select CLONE_BACKWARDS select CPU_PM if CPU_IDLE + select DMA_DIRECT_OPS select GENERIC_ATOMIC64 if !64BIT select GENERIC_CLOCKEVENTS select GENERIC_CMOS_UPDATE @@ -563,7 +564,6 @@ config NEC_MARKEINS bool "NEC EMMA2RH Mark-eins board" select SOC_EMMA2RH select HW_HAS_PCI - select MIPS_DMA_DEFAULT help This enables support for the NEC Electronics Mark-eins boards. @@ -577,14 +577,12 @@ config MACH_VR41XX config NXP_STB220 bool "NXP STB220 board" - select MIPS_DMA_DEFAULT select SOC_PNX833X help Support for NXP Semiconductors STB220 Development Board. config NXP_STB225 bool "NXP 225 board" - select MIPS_DMA_DEFAULT select SOC_PNX833X select SOC_PNX8335 help @@ -762,7 +760,6 @@ config SGI_IP32 config SIBYTE_CRHINE bool "Sibyte BCM91120C-CRhine" select BOOT_ELF32 - select MIPS_DMA_DEFAULT select SIBYTE_BCM1120 select SWAP_IO_SPACE select SYS_HAS_CPU_SB1 @@ -772,7 +769,6 @@ config SIBYTE_CRHINE config SIBYTE_CARMEL bool "Sibyte BCM91120x-Carmel" select BOOT_ELF32 - select MIPS_DMA_DEFAULT select SIBYTE_BCM1120 select SWAP_IO_SPACE select SYS_HAS_CPU_SB1 @@ -782,7 +778,6 @@ config SIBYTE_CARMEL config SIBYTE_CRHONE bool "Sibyte BCM91125C-CRhone" select BOOT_ELF32 - select MIPS_DMA_DEFAULT select SIBYTE_BCM1125 select SWAP_IO_SPACE select SYS_HAS_CPU_SB1 @@ -793,7 +788,6 @@ config SIBYTE_CRHONE config SIBYTE_RHONE bool "Sibyte BCM91125E-Rhone" select BOOT_ELF32 - select MIPS_DMA_DEFAULT select SIBYTE_BCM1125H select SWAP_IO_SPACE select SYS_HAS_CPU_SB1 @@ -804,7 +798,6 @@ config SIBYTE_SWARM bool "Sibyte BCM91250A-SWARM" select BOOT_ELF32 select HAVE_PATA_PLATFORM - select MIPS_DMA_DEFAULT select SIBYTE_SB1250 select SWAP_IO_SPACE select SYS_HAS_CPU_SB1 @@ -817,7 +810,6 @@ config SIBYTE_LITTLESUR bool "Sibyte BCM91250C2-LittleSur" select BOOT_ELF32 select HAVE_PATA_PLATFORM - select MIPS_DMA_DEFAULT select SIBYTE_SB1250 select SWAP_IO_SPACE select SYS_HAS_CPU_SB1 @@ -828,7 +820,6 @@ config SIBYTE_LITTLESUR config SIBYTE_SENTOSA bool "Sibyte BCM91250E-Sentosa" select BOOT_ELF32 - select MIPS_DMA_DEFAULT select SIBYTE_SB1250 select SWAP_IO_SPACE select SYS_HAS_CPU_SB1 @@ -838,7 +829,6 @@ config SIBYTE_SENTOSA config SIBYTE_BIGSUR bool "Sibyte BCM91480B-BigSur" select BOOT_ELF32 - select MIPS_DMA_DEFAULT select NR_CPUS_DEFAULT_4 select SIBYTE_BCM1x80 select SWAP_IO_SPACE @@ -959,7 +949,6 @@ config NLM_XLR_BOARD select SYS_HAS_CPU_XLR select SYS_SUPPORTS_SMP select HW_HAS_PCI - select MIPS_DMA_DEFAULT select SWAP_IO_SPACE select SYS_SUPPORTS_32BIT_KERNEL select SYS_SUPPORTS_64BIT_KERNEL @@ -986,7 +975,6 @@ config NLM_XLP_BOARD select SYS_HAS_CPU_XLP select SYS_SUPPORTS_SMP select HW_HAS_PCI - select MIPS_DMA_DEFAULT select SYS_SUPPORTS_32BIT_KERNEL select SYS_SUPPORTS_64BIT_KERNEL select PHYS_ADDR_T_64BIT @@ -1012,7 +1000,6 @@ config MIPS_PARAVIRT bool "Para-Virtualized guest system" select CEVT_R4K select CSRC_R4K - select MIPS_DMA_DEFAULT select SYS_SUPPORTS_64BIT_KERNEL select SYS_SUPPORTS_32BIT_KERNEL select SYS_SUPPORTS_BIG_ENDIAN diff --git a/arch/mips/include/asm/dma-mapping.h b/arch/mips/include/asm/dma-mapping.h index eaf3d9054104..7c0d4f0ccaa0 100644 --- a/arch/mips/include/asm/dma-mapping.h +++ b/arch/mips/include/asm/dma-mapping.h @@ -20,7 +20,7 @@ static inline const struct dma_map_ops *get_arch_dma_ops(struct bus_type *bus) #elif defined(CONFIG_MIPS_DMA_DEFAULT) return _default_dma_map_ops; #else - return NULL; + return _direct_ops; #endif } -- 2.17.0 ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
[PATCH 13/25] MIPS: loongson: remove loongson-3 handling from dma-coherence.h
Loongson3 is dma coherent and uses swiotlb, so it will never used any of these helpers. Signed-off-by: Christoph Hellwig--- .../include/asm/mach-loongson64/dma-coherence.h | 16 +--- 1 file changed, 1 insertion(+), 15 deletions(-) diff --git a/arch/mips/include/asm/mach-loongson64/dma-coherence.h b/arch/mips/include/asm/mach-loongson64/dma-coherence.h index b8825a7d1279..651dd2eb3ee5 100644 --- a/arch/mips/include/asm/mach-loongson64/dma-coherence.h +++ b/arch/mips/include/asm/mach-loongson64/dma-coherence.h @@ -20,29 +20,19 @@ struct device; static inline dma_addr_t plat_map_dma_mem(struct device *dev, void *addr, size_t size) { -#ifdef CONFIG_CPU_LOONGSON3 - return __phys_to_dma(dev, virt_to_phys(addr)); -#else return virt_to_phys(addr) | 0x8000; -#endif } static inline dma_addr_t plat_map_dma_mem_page(struct device *dev, struct page *page) { -#ifdef CONFIG_CPU_LOONGSON3 - return __phys_to_dma(dev, page_to_phys(page)); -#else return page_to_phys(page) | 0x8000; -#endif } static inline unsigned long plat_dma_addr_to_phys(struct device *dev, dma_addr_t dma_addr) { -#if defined(CONFIG_CPU_LOONGSON3) && defined(CONFIG_64BIT) - return __dma_to_phys(dev, dma_addr); -#elif defined(CONFIG_CPU_LOONGSON2F) && defined(CONFIG_64BIT) +#if defined(CONFIG_CPU_LOONGSON2F) && defined(CONFIG_64BIT) return (dma_addr > 0x8fff) ? dma_addr : (dma_addr & 0x0fff); #else return dma_addr & 0x7fff; @@ -69,11 +59,7 @@ static inline int plat_dma_supported(struct device *dev, u64 mask) static inline int plat_device_is_coherent(struct device *dev) { -#ifdef CONFIG_DMA_NONCOHERENT return 0; -#else - return 1; -#endif /* CONFIG_DMA_NONCOHERENT */ } static inline void plat_post_dma_flush(struct device *dev) -- 2.17.0 ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
[PATCH 12/25] MIPS: loongson: untangle dma implementations
Only loongson-3 is DMA coherent and uses swiotlb. So move the dma address translations stubs directly to the loongson-3 code, and remove a few Kconfig indirections. Signed-off-by: Christoph Hellwig--- arch/mips/Kconfig| 2 +- arch/mips/loongson64/Kconfig | 5 - arch/mips/loongson64/common/Makefile | 5 - arch/mips/loongson64/loongson-3/Makefile | 2 +- .../{common/dma-swiotlb.c => loongson-3/dma.c} | 16 5 files changed, 6 insertions(+), 24 deletions(-) rename arch/mips/loongson64/{common/dma-swiotlb.c => loongson-3/dma.c} (68%) diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 92cc7943d940..24cc20ea60b9 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -448,7 +448,6 @@ config MACH_LOONGSON32 config MACH_LOONGSON64 bool "Loongson-2/3 family of machines" - select ARCH_HAS_PHYS_TO_DMA select SYS_SUPPORTS_ZBOOT help This enables the support of Loongson-2/3 family of machines. @@ -1383,6 +1382,7 @@ choice config CPU_LOONGSON3 bool "Loongson 3 CPU" depends on SYS_HAS_CPU_LOONGSON3 + select ARCH_HAS_PHYS_TO_DMA select CPU_SUPPORTS_64BIT_KERNEL select CPU_SUPPORTS_HIGHMEM select CPU_SUPPORTS_HUGEPAGES diff --git a/arch/mips/loongson64/Kconfig b/arch/mips/loongson64/Kconfig index dbd2a9f9f9a9..a785bf8da3f3 100644 --- a/arch/mips/loongson64/Kconfig +++ b/arch/mips/loongson64/Kconfig @@ -93,7 +93,6 @@ config LOONGSON_MACH3X select LOONGSON_MC146818 select ZONE_DMA32 select LEFI_FIRMWARE_INTERFACE - select PHYS48_TO_HT40 help Generic Loongson 3 family machines utilize the 3A/3B revision of Loongson processor and RS780/SBX00 chipset. @@ -132,10 +131,6 @@ config LOONGSON_UART_BASE default y depends on EARLY_PRINTK || SERIAL_8250 -config PHYS48_TO_HT40 - bool - default y if CPU_LOONGSON3 - config LOONGSON_MC146818 bool default n diff --git a/arch/mips/loongson64/common/Makefile b/arch/mips/loongson64/common/Makefile index 8235ac7eac95..684624f61f5a 100644 --- a/arch/mips/loongson64/common/Makefile +++ b/arch/mips/loongson64/common/Makefile @@ -25,8 +25,3 @@ obj-$(CONFIG_CS5536) += cs5536/ # obj-$(CONFIG_SUSPEND) += pm.o - -# -# Big Memory (SWIOTLB) Support -# -obj-$(CONFIG_SWIOTLB) += dma-swiotlb.o diff --git a/arch/mips/loongson64/loongson-3/Makefile b/arch/mips/loongson64/loongson-3/Makefile index 44bc1482158b..b5a0c2fa5446 100644 --- a/arch/mips/loongson64/loongson-3/Makefile +++ b/arch/mips/loongson64/loongson-3/Makefile @@ -1,7 +1,7 @@ # # Makefile for Loongson-3 family machines # -obj-y += irq.o cop2-ex.o platform.o acpi_init.o +obj-y += irq.o cop2-ex.o platform.o acpi_init.o dma.o obj-$(CONFIG_SMP) += smp.o diff --git a/arch/mips/loongson64/common/dma-swiotlb.c b/arch/mips/loongson64/loongson-3/dma.c similarity index 68% rename from arch/mips/loongson64/common/dma-swiotlb.c rename to arch/mips/loongson64/loongson-3/dma.c index a4f554bf1232..5e86635f71db 100644 --- a/arch/mips/loongson64/common/dma-swiotlb.c +++ b/arch/mips/loongson64/loongson-3/dma.c @@ -5,26 +5,18 @@ dma_addr_t __phys_to_dma(struct device *dev, phys_addr_t paddr) { - long nid; -#ifdef CONFIG_PHYS48_TO_HT40 /* We extract 2bit node id (bit 44~47, only bit 44~45 used now) from * Loongson-3's 48bit address space and embed it into 40bit */ - nid = (paddr >> 44) & 0x3; - paddr = ((nid << 44) ^ paddr) | (nid << 37); -#endif - return paddr; + long nid = (paddr >> 44) & 0x3; + return ((nid << 44) ^ paddr) | (nid << 37); } phys_addr_t __dma_to_phys(struct device *dev, dma_addr_t daddr) { - long nid; -#ifdef CONFIG_PHYS48_TO_HT40 /* We extract 2bit node id (bit 44~47, only bit 44~45 used now) from * Loongson-3's 48bit address space and embed it into 40bit */ - nid = (daddr >> 37) & 0x3; - daddr = ((nid << 37) ^ daddr) | (nid << 44); -#endif - return daddr; + long nid = (daddr >> 37) & 0x3; + return ((nid << 37) ^ daddr) | (nid << 44); } void __init plat_swiotlb_setup(void) -- 2.17.0 ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
[PATCH 11/25] MIPS: Octeon: move swiotlb declarations out of dma-coherence.h
No need to pull them into a global header. Signed-off-by: Christoph Hellwig--- .../asm/mach-cavium-octeon/dma-coherence.h | 18 -- arch/mips/include/asm/octeon/pci-octeon.h | 3 +++ arch/mips/pci/pci-octeon.c | 2 -- arch/mips/pci/pcie-octeon.c| 2 -- 4 files changed, 3 insertions(+), 22 deletions(-) delete mode 100644 arch/mips/include/asm/mach-cavium-octeon/dma-coherence.h diff --git a/arch/mips/include/asm/mach-cavium-octeon/dma-coherence.h b/arch/mips/include/asm/mach-cavium-octeon/dma-coherence.h deleted file mode 100644 index 66eee98b8b8d.. --- a/arch/mips/include/asm/mach-cavium-octeon/dma-coherence.h +++ /dev/null @@ -1,18 +0,0 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 2006 Ralf Baechle - */ -#ifndef __ASM_MACH_CAVIUM_OCTEON_DMA_COHERENCE_H -#define __ASM_MACH_CAVIUM_OCTEON_DMA_COHERENCE_H - -#include - -struct device; - -extern void octeon_pci_dma_init(void); -extern char *octeon_swiotlb; - -#endif /* __ASM_MACH_CAVIUM_OCTEON_DMA_COHERENCE_H */ diff --git a/arch/mips/include/asm/octeon/pci-octeon.h b/arch/mips/include/asm/octeon/pci-octeon.h index 1884609741a8..b12d9a3fbfb6 100644 --- a/arch/mips/include/asm/octeon/pci-octeon.h +++ b/arch/mips/include/asm/octeon/pci-octeon.h @@ -63,4 +63,7 @@ enum octeon_dma_bar_type { */ extern enum octeon_dma_bar_type octeon_dma_bar_type; +void octeon_pci_dma_init(void); +extern char *octeon_swiotlb; + #endif diff --git a/arch/mips/pci/pci-octeon.c b/arch/mips/pci/pci-octeon.c index a20697df3539..5017d5843c5a 100644 --- a/arch/mips/pci/pci-octeon.c +++ b/arch/mips/pci/pci-octeon.c @@ -21,8 +21,6 @@ #include #include -#include - #define USE_OCTEON_INTERNAL_ARBITER /* diff --git a/arch/mips/pci/pcie-octeon.c b/arch/mips/pci/pcie-octeon.c index 87ba86bd8696..9cc5905860ef 100644 --- a/arch/mips/pci/pcie-octeon.c +++ b/arch/mips/pci/pcie-octeon.c @@ -94,8 +94,6 @@ union cvmx_pcie_address { static int cvmx_pcie_rc_initialize(int pcie_port); -#include - /** * Return the Core virtual base address for PCIe IO access. IOs are * read/written as an offset from this address. -- 2.17.0 ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
[PATCH 10/25] MIPS: Octeon: remove mips dma-default stubs
Octeon doesn't use the dma-default code, and now doesn't built it either, so these stubs can be removed. Signed-off-by: Christoph Hellwig--- .../asm/mach-cavium-octeon/dma-coherence.h| 48 --- 1 file changed, 48 deletions(-) diff --git a/arch/mips/include/asm/mach-cavium-octeon/dma-coherence.h b/arch/mips/include/asm/mach-cavium-octeon/dma-coherence.h index c0254c72d97b..66eee98b8b8d 100644 --- a/arch/mips/include/asm/mach-cavium-octeon/dma-coherence.h +++ b/arch/mips/include/asm/mach-cavium-octeon/dma-coherence.h @@ -4,11 +4,6 @@ * for more details. * * Copyright (C) 2006 Ralf Baechle - * - * - * Similar to mach-generic/dma-coherence.h except - * plat_device_is_coherent hard coded to return 1. - * */ #ifndef __ASM_MACH_CAVIUM_OCTEON_DMA_COHERENCE_H #define __ASM_MACH_CAVIUM_OCTEON_DMA_COHERENCE_H @@ -18,49 +13,6 @@ struct device; extern void octeon_pci_dma_init(void); - -static inline dma_addr_t plat_map_dma_mem(struct device *dev, void *addr, - size_t size) -{ - BUG(); - return 0; -} - -static inline dma_addr_t plat_map_dma_mem_page(struct device *dev, - struct page *page) -{ - BUG(); - return 0; -} - -static inline unsigned long plat_dma_addr_to_phys(struct device *dev, - dma_addr_t dma_addr) -{ - BUG(); - return 0; -} - -static inline void plat_unmap_dma_mem(struct device *dev, dma_addr_t dma_addr, - size_t size, enum dma_data_direction direction) -{ - BUG(); -} - -static inline int plat_dma_supported(struct device *dev, u64 mask) -{ - BUG(); - return 0; -} - -static inline int plat_device_is_coherent(struct device *dev) -{ - return 1; -} - -static inline void plat_post_dma_flush(struct device *dev) -{ -} - extern char *octeon_swiotlb; #endif /* __ASM_MACH_CAVIUM_OCTEON_DMA_COHERENCE_H */ -- 2.17.0 ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
[PATCH 09/25] MIPS: make the default mips dma implementation optional
Octeon and loonson64 already don't use it at all, and we're going to migrate more plaforms away from it. Signed-off-by: Christoph Hellwig--- arch/mips/Kconfig | 40 + arch/mips/include/asm/dma-mapping.h | 4 ++- arch/mips/jazz/Kconfig | 3 +++ arch/mips/loongson32/Kconfig| 2 ++ arch/mips/loongson64/Kconfig| 2 ++ arch/mips/mm/Makefile | 3 ++- arch/mips/pic32/Kconfig | 1 + arch/mips/txx9/Kconfig | 1 + arch/mips/vr41xx/Kconfig| 5 9 files changed, 59 insertions(+), 2 deletions(-) diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 43bb037301f6..92cc7943d940 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -71,6 +71,9 @@ config MIPS select SYSCTL_EXCEPTION_TRACE select VIRT_TO_BUS +config MIPS_DMA_DEFAULT + bool + menu "Machine selection" choice @@ -92,6 +95,7 @@ config MIPS_GENERIC select IRQ_MIPS_CPU select LIBFDT select MIPS_CPU_SCACHE + select MIPS_DMA_DEFAULT select MIPS_GIC select MIPS_L1_CACHE_SHIFT_7 select NO_EXCEPT_FILL @@ -135,6 +139,7 @@ config MIPS_ALCHEMY select CEVT_R4K select CSRC_R4K select IRQ_MIPS_CPU + select MIPS_DMA_DEFAULT select DMA_MAYBE_COHERENT # Au1000,1500,1100 aren't, rest is select SYS_HAS_CPU_MIPS32_R1 select SYS_SUPPORTS_32BIT_KERNEL @@ -150,6 +155,7 @@ config AR7 select CEVT_R4K select CSRC_R4K select IRQ_MIPS_CPU + select MIPS_DMA_DEFAULT select NO_EXCEPT_FILL select SWAP_IO_SPACE select SYS_HAS_CPU_MIPS32_R1 @@ -172,6 +178,7 @@ config ATH25 select DMA_NONCOHERENT select IRQ_MIPS_CPU select IRQ_DOMAIN + select MIPS_DMA_DEFAULT select SYS_HAS_CPU_MIPS32_R1 select SYS_SUPPORTS_BIG_ENDIAN select SYS_SUPPORTS_32BIT_KERNEL @@ -191,6 +198,7 @@ config ATH79 select COMMON_CLK select CLKDEV_LOOKUP select IRQ_MIPS_CPU + select MIPS_DMA_DEFAULT select MIPS_MACHINE select SYS_HAS_CPU_MIPS32_R2 select SYS_HAS_EARLY_PRINTK @@ -217,6 +225,7 @@ config BMIPS_GENERIC select BCM7120_L2_IRQ select BRCMSTB_L2_IRQ select IRQ_MIPS_CPU + select MIPS_DMA_DEFAULT select DMA_NONCOHERENT select SYS_SUPPORTS_32BIT_KERNEL select SYS_SUPPORTS_LITTLE_ENDIAN @@ -247,6 +256,7 @@ config BCM47XX select HW_HAS_PCI select IRQ_MIPS_CPU select SYS_HAS_CPU_MIPS32_R1 + select MIPS_DMA_DEFAULT select NO_EXCEPT_FILL select SYS_SUPPORTS_32BIT_KERNEL select SYS_SUPPORTS_LITTLE_ENDIAN @@ -270,6 +280,7 @@ config BCM63XX select SYNC_R4K select DMA_NONCOHERENT select IRQ_MIPS_CPU + select MIPS_DMA_DEFAULT select SYS_SUPPORTS_32BIT_KERNEL select SYS_SUPPORTS_BIG_ENDIAN select SYS_HAS_EARLY_PRINTK @@ -292,6 +303,7 @@ config MIPS_COBALT select I8259 select IRQ_MIPS_CPU select IRQ_GT641XX + select MIPS_DMA_DEFAULT select PCI_GT64XXX_PCI0 select PCI select SYS_HAS_CPU_NEVADA @@ -312,6 +324,7 @@ config MACH_DECSTATION select CPU_R4000_WORKAROUNDS if 64BIT select CPU_R4400_WORKAROUNDS if 64BIT select DMA_NONCOHERENT + select MIPS_DMA_DEFAULT select NO_IOPORT_MAP select IRQ_MIPS_CPU select SYS_HAS_CPU_R3000 @@ -371,6 +384,7 @@ config MACH_INGENIC select SYS_SUPPORTS_ZBOOT_UART16550 select DMA_NONCOHERENT select IRQ_MIPS_CPU + select MIPS_DMA_DEFAULT select PINCTRL select GPIOLIB select COMMON_CLK @@ -385,6 +399,7 @@ config LANTIQ select IRQ_MIPS_CPU select CEVT_R4K select CSRC_R4K + select MIPS_DMA_DEFAULT select SYS_HAS_CPU_MIPS32_R1 select SYS_HAS_CPU_MIPS32_R2 select SYS_SUPPORTS_BIG_ENDIAN @@ -412,6 +427,7 @@ config LASAT select SYS_HAS_EARLY_PRINTK select HW_HAS_PCI select IRQ_MIPS_CPU + select MIPS_DMA_DEFAULT select PCI_GT64XXX_PCI0 select MIPS_NILE4 select R5000_CPU_SCACHE @@ -458,6 +474,7 @@ config MACH_PISTACHIO select LIBFDT select MFD_SYSCON select MIPS_CPU_SCACHE + select MIPS_DMA_DEFAULT select MIPS_GIC select PINCTRL select REGULATOR @@ -490,6 +507,7 @@ config MIPS_MALTA select GENERIC_ISA_DMA select HAVE_PCSPKR_PLATFORM select IRQ_MIPS_CPU + select MIPS_DMA_DEFAULT select MIPS_GIC select HW_HAS_PCI select I8253 @@ -546,6 +564,7 @@ config NEC_MARKEINS bool "NEC EMMA2RH Mark-eins board" select SOC_EMMA2RH select HW_HAS_PCI + select MIPS_DMA_DEFAULT help This enables
[PATCH 08/25] MIPS: remove the mips_dma_map_ops indirection
And use mips_default_dma_map_ops directly. Signed-off-by: Christoph Hellwig--- arch/mips/include/asm/dma-mapping.h | 4 ++-- arch/mips/mm/dma-default.c | 6 ++ 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/arch/mips/include/asm/dma-mapping.h b/arch/mips/include/asm/dma-mapping.h index ebcce3e22297..f24b052ec740 100644 --- a/arch/mips/include/asm/dma-mapping.h +++ b/arch/mips/include/asm/dma-mapping.h @@ -10,7 +10,7 @@ #include #endif -extern const struct dma_map_ops *mips_dma_map_ops; +extern const struct dma_map_ops mips_default_dma_map_ops; extern const struct dma_map_ops mips_swiotlb_ops; static inline const struct dma_map_ops *get_arch_dma_ops(struct bus_type *bus) @@ -18,7 +18,7 @@ static inline const struct dma_map_ops *get_arch_dma_ops(struct bus_type *bus) #ifdef CONFIG_SWIOTLB return _swiotlb_ops; #else - return mips_dma_map_ops; + return _default_dma_map_ops; #endif } diff --git a/arch/mips/mm/dma-default.c b/arch/mips/mm/dma-default.c index f9fef0028ca2..2db6c2a6f964 100644 --- a/arch/mips/mm/dma-default.c +++ b/arch/mips/mm/dma-default.c @@ -384,7 +384,7 @@ static void mips_dma_cache_sync(struct device *dev, void *vaddr, size_t size, __dma_sync_virtual(vaddr, size, direction); } -static const struct dma_map_ops mips_default_dma_map_ops = { +const struct dma_map_ops mips_default_dma_map_ops = { .alloc = mips_dma_alloc_coherent, .free = mips_dma_free_coherent, .mmap = mips_dma_mmap, @@ -399,6 +399,4 @@ static const struct dma_map_ops mips_default_dma_map_ops = { .dma_supported = mips_dma_supported, .cache_sync = mips_dma_cache_sync, }; - -const struct dma_map_ops *mips_dma_map_ops = _default_dma_map_ops; -EXPORT_SYMBOL(mips_dma_map_ops); +EXPORT_SYMBOL(mips_default_dma_map_ops); -- 2.17.0 ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
[PATCH 06/25] MIPS: loongson: remove loongson_dma_supported
swiotlb_dma_supported will always return true for the a mask large enough to be covered by wired up physical address, so this function is pointless. Signed-off-by: Christoph Hellwig--- arch/mips/loongson64/common/dma-swiotlb.c | 9 + 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/arch/mips/loongson64/common/dma-swiotlb.c b/arch/mips/loongson64/common/dma-swiotlb.c index 6a739f8ae110..a5e50f2ec301 100644 --- a/arch/mips/loongson64/common/dma-swiotlb.c +++ b/arch/mips/loongson64/common/dma-swiotlb.c @@ -56,13 +56,6 @@ static void loongson_dma_sync_sg_for_device(struct device *dev, mb(); } -static int loongson_dma_supported(struct device *dev, u64 mask) -{ - if (mask > DMA_BIT_MASK(loongson_sysconf.dma_mask_bits)) - return 0; - return swiotlb_dma_supported(dev, mask); -} - dma_addr_t __phys_to_dma(struct device *dev, phys_addr_t paddr) { long nid; @@ -99,7 +92,7 @@ static const struct dma_map_ops loongson_dma_map_ops = { .sync_sg_for_cpu = swiotlb_sync_sg_for_cpu, .sync_sg_for_device = loongson_dma_sync_sg_for_device, .mapping_error = swiotlb_dma_mapping_error, - .dma_supported = loongson_dma_supported, + .dma_supported = swiotlb_dma_supported, }; void __init plat_swiotlb_setup(void) -- 2.17.0 ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
[PATCH 07/25] MIPS: consolidate the swiotlb implementations
Octeon and Loongson share exactly the same code, move it into a common implementation, and use that implementation directly from get_arch_dma_ops. Also provide the expected dma-direct.h helpers directly instead of delegating to platform dma-coherence.h headers. Signed-off-by: Christoph Hellwig--- arch/mips/cavium-octeon/dma-octeon.c | 61 arch/mips/include/asm/dma-direct.h| 17 - arch/mips/include/asm/dma-mapping.h | 5 ++ .../asm/mach-cavium-octeon/dma-coherence.h| 11 --- .../asm/mach-loongson64/dma-coherence.h | 10 --- arch/mips/loongson64/common/dma-swiotlb.c | 71 +-- arch/mips/mm/Makefile | 1 + arch/mips/mm/dma-swiotlb.c| 61 8 files changed, 84 insertions(+), 153 deletions(-) create mode 100644 arch/mips/mm/dma-swiotlb.c diff --git a/arch/mips/cavium-octeon/dma-octeon.c b/arch/mips/cavium-octeon/dma-octeon.c index 1e68636c9137..939620b90164 100644 --- a/arch/mips/cavium-octeon/dma-octeon.c +++ b/arch/mips/cavium-octeon/dma-octeon.c @@ -11,7 +11,6 @@ * Copyright (C) 2010 Cavium Networks, Inc. */ #include -#include #include #include #include @@ -159,49 +158,6 @@ void __init octeon_pci_dma_init(void) } #endif /* CONFIG_PCI */ -static dma_addr_t octeon_dma_map_page(struct device *dev, struct page *page, - unsigned long offset, size_t size, enum dma_data_direction direction, - unsigned long attrs) -{ - dma_addr_t daddr = swiotlb_map_page(dev, page, offset, size, - direction, attrs); - mb(); - - return daddr; -} - -static int octeon_dma_map_sg(struct device *dev, struct scatterlist *sg, - int nents, enum dma_data_direction direction, unsigned long attrs) -{ - int r = swiotlb_map_sg_attrs(dev, sg, nents, direction, attrs); - mb(); - return r; -} - -static void octeon_dma_sync_single_for_device(struct device *dev, - dma_addr_t dma_handle, size_t size, enum dma_data_direction direction) -{ - swiotlb_sync_single_for_device(dev, dma_handle, size, direction); - mb(); -} - -static void octeon_dma_sync_sg_for_device(struct device *dev, - struct scatterlist *sg, int nelems, enum dma_data_direction direction) -{ - swiotlb_sync_sg_for_device(dev, sg, nelems, direction); - mb(); -} - -static void *octeon_dma_alloc_coherent(struct device *dev, size_t size, - dma_addr_t *dma_handle, gfp_t gfp, unsigned long attrs) -{ - void *ret = swiotlb_alloc(dev, size, dma_handle, gfp, attrs); - - mb(); - - return ret; -} - dma_addr_t __phys_to_dma(struct device *dev, phys_addr_t paddr) { #ifdef CONFIG_PCI @@ -220,21 +176,6 @@ phys_addr_t __dma_to_phys(struct device *dev, dma_addr_t daddr) return daddr; } -static const struct dma_map_ops octeon_swiotlb_ops = { - .alloc = octeon_dma_alloc_coherent, - .free = swiotlb_free, - .map_page = octeon_dma_map_page, - .unmap_page = swiotlb_unmap_page, - .map_sg = octeon_dma_map_sg, - .unmap_sg = swiotlb_unmap_sg_attrs, - .sync_single_for_cpu= swiotlb_sync_single_for_cpu, - .sync_single_for_device = octeon_dma_sync_single_for_device, - .sync_sg_for_cpu= swiotlb_sync_sg_for_cpu, - .sync_sg_for_device = octeon_dma_sync_sg_for_device, - .mapping_error = swiotlb_dma_mapping_error, - .dma_supported = swiotlb_dma_supported -}; - char *octeon_swiotlb; void __init plat_swiotlb_setup(void) @@ -297,6 +238,4 @@ void __init plat_swiotlb_setup(void) if (swiotlb_init_with_tbl(octeon_swiotlb, swiotlb_nslabs, 1) == -ENOMEM) panic("Cannot allocate SWIOTLB buffer"); - - mips_dma_map_ops = _swiotlb_ops; } diff --git a/arch/mips/include/asm/dma-direct.h b/arch/mips/include/asm/dma-direct.h index f32f15530aba..b5c240806e1b 100644 --- a/arch/mips/include/asm/dma-direct.h +++ b/arch/mips/include/asm/dma-direct.h @@ -1 +1,16 @@ -#include +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef _MIPS_DMA_DIRECT_H +#define _MIPS_DMA_DIRECT_H 1 + +static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t size) +{ + if (!dev->dma_mask) + return false; + + return addr + size - 1 <= *dev->dma_mask; +} + +dma_addr_t __phys_to_dma(struct device *dev, phys_addr_t paddr); +phys_addr_t __dma_to_phys(struct device *dev, dma_addr_t daddr); + +#endif /* _MIPS_DMA_DIRECT_H */ diff --git a/arch/mips/include/asm/dma-mapping.h b/arch/mips/include/asm/dma-mapping.h index 886e75a383f2..ebcce3e22297 100644 --- a/arch/mips/include/asm/dma-mapping.h +++ b/arch/mips/include/asm/dma-mapping.h @@ -11,10 +11,15 @@ #endif extern const struct dma_map_ops *mips_dma_map_ops; +extern const struct dma_map_ops mips_swiotlb_ops;
[PATCH 05/25] MIPS: Octeon: refactor swiotlb code
Share a common set of swiotlb operations, and to instead branch out in __phys_to_dma/__dma_to_phys for the PCI vs non-PCI case. Also use const structures for the PCI methods so that attackers can't use them as exploit vectors. Signed-off-by: Christoph Hellwig--- arch/mips/cavium-octeon/dma-octeon.c | 169 -- .../asm/mach-cavium-octeon/dma-coherence.h| 2 - arch/mips/pci/pci-octeon.c| 2 - 3 files changed, 70 insertions(+), 103 deletions(-) diff --git a/arch/mips/cavium-octeon/dma-octeon.c b/arch/mips/cavium-octeon/dma-octeon.c index e5d00c79bd26..1e68636c9137 100644 --- a/arch/mips/cavium-octeon/dma-octeon.c +++ b/arch/mips/cavium-octeon/dma-octeon.c @@ -23,10 +23,16 @@ #include #ifdef CONFIG_PCI +#include #include #include #include +struct octeon_dma_map_ops { + dma_addr_t (*phys_to_dma)(struct device *dev, phys_addr_t paddr); + phys_addr_t (*dma_to_phys)(struct device *dev, dma_addr_t daddr); +}; + static dma_addr_t octeon_hole_phys_to_dma(phys_addr_t paddr) { if (paddr >= CVMX_PCIE_BAR1_PHYS_BASE && paddr < (CVMX_PCIE_BAR1_PHYS_BASE + CVMX_PCIE_BAR1_PHYS_SIZE)) @@ -43,6 +49,11 @@ static phys_addr_t octeon_hole_dma_to_phys(dma_addr_t daddr) return daddr; } +static const struct octeon_dma_map_ops octeon_gen2_ops = { + .phys_to_dma= octeon_hole_phys_to_dma, + .dma_to_phys= octeon_hole_dma_to_phys, +}; + static dma_addr_t octeon_gen1_phys_to_dma(struct device *dev, phys_addr_t paddr) { if (paddr >= 0x41000ull && paddr < 0x42000ull) @@ -60,15 +71,10 @@ static phys_addr_t octeon_gen1_dma_to_phys(struct device *dev, dma_addr_t daddr) return daddr; } -static dma_addr_t octeon_gen2_phys_to_dma(struct device *dev, phys_addr_t paddr) -{ - return octeon_hole_phys_to_dma(paddr); -} - -static phys_addr_t octeon_gen2_dma_to_phys(struct device *dev, dma_addr_t daddr) -{ - return octeon_hole_dma_to_phys(daddr); -} +static const struct octeon_dma_map_ops octeon_gen1_ops = { + .phys_to_dma= octeon_gen1_phys_to_dma, + .dma_to_phys= octeon_gen1_dma_to_phys, +}; static dma_addr_t octeon_big_phys_to_dma(struct device *dev, phys_addr_t paddr) { @@ -92,6 +98,11 @@ static phys_addr_t octeon_big_dma_to_phys(struct device *dev, dma_addr_t daddr) return daddr; } +static const struct octeon_dma_map_ops octeon_big_ops = { + .phys_to_dma= octeon_big_phys_to_dma, + .dma_to_phys= octeon_big_dma_to_phys, +}; + static dma_addr_t octeon_small_phys_to_dma(struct device *dev, phys_addr_t paddr) { @@ -120,6 +131,32 @@ static phys_addr_t octeon_small_dma_to_phys(struct device *dev, return daddr; } +static const struct octeon_dma_map_ops octeon_small_ops = { + .phys_to_dma= octeon_small_phys_to_dma, + .dma_to_phys= octeon_small_dma_to_phys, +}; + +static const struct octeon_dma_map_ops *octeon_pci_dma_ops; + +void __init octeon_pci_dma_init(void) +{ + switch (octeon_dma_bar_type) { + case OCTEON_DMA_BAR_TYPE_PCIE2: + octeon_pci_dma_ops = _gen2_ops; + break; + case OCTEON_DMA_BAR_TYPE_PCIE: + octeon_pci_dma_ops = _gen1_ops; + break; + case OCTEON_DMA_BAR_TYPE_BIG: + octeon_pci_dma_ops = _big_ops; + break; + case OCTEON_DMA_BAR_TYPE_SMALL: + octeon_pci_dma_ops = _small_ops; + break; + default: + BUG(); + } +} #endif /* CONFIG_PCI */ static dma_addr_t octeon_dma_map_page(struct device *dev, struct page *page, @@ -165,57 +202,37 @@ static void *octeon_dma_alloc_coherent(struct device *dev, size_t size, return ret; } -static dma_addr_t octeon_unity_phys_to_dma(struct device *dev, phys_addr_t paddr) -{ - return paddr; -} - -static phys_addr_t octeon_unity_dma_to_phys(struct device *dev, dma_addr_t daddr) -{ - return daddr; -} - -struct octeon_dma_map_ops { - const struct dma_map_ops dma_map_ops; - dma_addr_t (*phys_to_dma)(struct device *dev, phys_addr_t paddr); - phys_addr_t (*dma_to_phys)(struct device *dev, dma_addr_t daddr); -}; - dma_addr_t __phys_to_dma(struct device *dev, phys_addr_t paddr) { - struct octeon_dma_map_ops *ops = container_of(get_dma_ops(dev), - struct octeon_dma_map_ops, - dma_map_ops); - - return ops->phys_to_dma(dev, paddr); +#ifdef CONFIG_PCI + if (dev && dev_is_pci(dev)) + return octeon_pci_dma_ops->phys_to_dma(dev, paddr); +#endif + return paddr; } phys_addr_t __dma_to_phys(struct device *dev, dma_addr_t daddr) { - struct octeon_dma_map_ops *ops = container_of(get_dma_ops(dev), - struct
[PATCH 04/25] MIPS: Octeon: unexport __phys_to_dma and __dma_to_phys
These functions are just low-level helpers for the swiotlb and dma-direct implementations, and should never be used by drivers. Signed-off-by: Christoph Hellwig--- arch/mips/cavium-octeon/dma-octeon.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/arch/mips/cavium-octeon/dma-octeon.c b/arch/mips/cavium-octeon/dma-octeon.c index 7b335ab21697..e5d00c79bd26 100644 --- a/arch/mips/cavium-octeon/dma-octeon.c +++ b/arch/mips/cavium-octeon/dma-octeon.c @@ -13,7 +13,6 @@ #include #include #include -#include #include #include #include @@ -190,7 +189,6 @@ dma_addr_t __phys_to_dma(struct device *dev, phys_addr_t paddr) return ops->phys_to_dma(dev, paddr); } -EXPORT_SYMBOL(__phys_to_dma); phys_addr_t __dma_to_phys(struct device *dev, dma_addr_t daddr) { @@ -200,7 +198,6 @@ phys_addr_t __dma_to_phys(struct device *dev, dma_addr_t daddr) return ops->dma_to_phys(dev, daddr); } -EXPORT_SYMBOL(__dma_to_phys); static struct octeon_dma_map_ops octeon_linear_dma_map_ops = { .dma_map_ops = { -- 2.17.0 ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
[PATCH 02/25] MIPS: simplify CONFIG_DMA_NONCOHERENT ifdefs
CONFIG_DMA_MAYBE_COHERENT already selects CONFIG_DMA_NONCOHERENT, so we can remove the extra conditions. Signed-off-by: Christoph Hellwig--- arch/mips/include/asm/io.h | 4 ++-- arch/mips/mm/c-r4k.c | 4 ++-- arch/mips/mm/cache.c | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/arch/mips/include/asm/io.h b/arch/mips/include/asm/io.h index a7d0b836f2f7..6d6bdc6a48eb 100644 --- a/arch/mips/include/asm/io.h +++ b/arch/mips/include/asm/io.h @@ -588,7 +588,7 @@ static inline void memcpy_toio(volatile void __iomem *dst, const void *src, int * * This API used to be exported; it now is for arch code internal use only. */ -#if defined(CONFIG_DMA_NONCOHERENT) || defined(CONFIG_DMA_MAYBE_COHERENT) +#ifdef CONFIG_DMA_NONCOHERENT extern void (*_dma_cache_wback_inv)(unsigned long start, unsigned long size); extern void (*_dma_cache_wback)(unsigned long start, unsigned long size); @@ -607,7 +607,7 @@ extern void (*_dma_cache_inv)(unsigned long start, unsigned long size); #define dma_cache_inv(start,size) \ do { (void) (start); (void) (size); } while (0) -#endif /* CONFIG_DMA_NONCOHERENT || CONFIG_DMA_MAYBE_COHERENT */ +#endif /* CONFIG_DMA_NONCOHERENT */ /* * Read a 32-bit register that requires a 64-bit read cycle on the bus. diff --git a/arch/mips/mm/c-r4k.c b/arch/mips/mm/c-r4k.c index 6f534b209971..dcfff4f6cd88 100644 --- a/arch/mips/mm/c-r4k.c +++ b/arch/mips/mm/c-r4k.c @@ -830,7 +830,7 @@ static void r4k_flush_icache_user_range(unsigned long start, unsigned long end) return __r4k_flush_icache_range(start, end, true); } -#if defined(CONFIG_DMA_NONCOHERENT) || defined(CONFIG_DMA_MAYBE_COHERENT) +#ifdef CONFIG_DMA_NONCOHERENT static void r4k_dma_cache_wback_inv(unsigned long addr, unsigned long size) { @@ -901,7 +901,7 @@ static void r4k_dma_cache_inv(unsigned long addr, unsigned long size) bc_inv(addr, size); __sync(); } -#endif /* CONFIG_DMA_NONCOHERENT || CONFIG_DMA_MAYBE_COHERENT */ +#endif /* CONFIG_DMA_NONCOHERENT */ struct flush_cache_sigtramp_args { struct mm_struct *mm; diff --git a/arch/mips/mm/cache.c b/arch/mips/mm/cache.c index 0d3c656feba0..70a523151ff3 100644 --- a/arch/mips/mm/cache.c +++ b/arch/mips/mm/cache.c @@ -56,7 +56,7 @@ EXPORT_SYMBOL_GPL(local_flush_data_cache_page); EXPORT_SYMBOL(flush_data_cache_page); EXPORT_SYMBOL(flush_icache_all); -#if defined(CONFIG_DMA_NONCOHERENT) || defined(CONFIG_DMA_MAYBE_COHERENT) +#ifdef CONFIG_DMA_NONCOHERENT /* DMA cache operations. */ void (*_dma_cache_wback_inv)(unsigned long start, unsigned long size); @@ -65,7 +65,7 @@ void (*_dma_cache_inv)(unsigned long start, unsigned long size); EXPORT_SYMBOL(_dma_cache_wback_inv); -#endif /* CONFIG_DMA_NONCOHERENT || CONFIG_DMA_MAYBE_COHERENT */ +#endif /* CONFIG_DMA_NONCOHERENT */ /* * We could optimize the case where the cache argument is not BCACHE but -- 2.17.0 ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
[PATCH 03/25] MIPS: remove CONFIG_DMA_COHERENT
We can just check for !CONFIG_DMA_NONCOHERENT instead and simplify things a lot. Signed-off-by: Christoph Hellwig--- arch/mips/Kconfig| 16 arch/mips/include/asm/dma-coherence.h| 6 +++--- arch/mips/include/asm/mach-generic/kmalloc.h | 3 +-- arch/mips/mti-malta/malta-setup.c| 4 ++-- arch/mips/sibyte/Kconfig | 1 - 5 files changed, 6 insertions(+), 24 deletions(-) diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 2dcdc13cd65d..43bb037301f6 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -660,7 +660,6 @@ config SGI_IP27 select FW_ARC64 select BOOT_ELF64 select DEFAULT_SGI_PARTITION - select DMA_COHERENT select SYS_HAS_EARLY_PRINTK select HW_HAS_PCI select NR_CPUS_DEFAULT_64 @@ -737,7 +736,6 @@ config SGI_IP32 config SIBYTE_CRHINE bool "Sibyte BCM91120C-CRhine" select BOOT_ELF32 - select DMA_COHERENT select SIBYTE_BCM1120 select SWAP_IO_SPACE select SYS_HAS_CPU_SB1 @@ -747,7 +745,6 @@ config SIBYTE_CRHINE config SIBYTE_CARMEL bool "Sibyte BCM91120x-Carmel" select BOOT_ELF32 - select DMA_COHERENT select SIBYTE_BCM1120 select SWAP_IO_SPACE select SYS_HAS_CPU_SB1 @@ -757,7 +754,6 @@ config SIBYTE_CARMEL config SIBYTE_CRHONE bool "Sibyte BCM91125C-CRhone" select BOOT_ELF32 - select DMA_COHERENT select SIBYTE_BCM1125 select SWAP_IO_SPACE select SYS_HAS_CPU_SB1 @@ -768,7 +764,6 @@ config SIBYTE_CRHONE config SIBYTE_RHONE bool "Sibyte BCM91125E-Rhone" select BOOT_ELF32 - select DMA_COHERENT select SIBYTE_BCM1125H select SWAP_IO_SPACE select SYS_HAS_CPU_SB1 @@ -778,7 +773,6 @@ config SIBYTE_RHONE config SIBYTE_SWARM bool "Sibyte BCM91250A-SWARM" select BOOT_ELF32 - select DMA_COHERENT select HAVE_PATA_PLATFORM select SIBYTE_SB1250 select SWAP_IO_SPACE @@ -791,7 +785,6 @@ config SIBYTE_SWARM config SIBYTE_LITTLESUR bool "Sibyte BCM91250C2-LittleSur" select BOOT_ELF32 - select DMA_COHERENT select HAVE_PATA_PLATFORM select SIBYTE_SB1250 select SWAP_IO_SPACE @@ -803,7 +796,6 @@ config SIBYTE_LITTLESUR config SIBYTE_SENTOSA bool "Sibyte BCM91250E-Sentosa" select BOOT_ELF32 - select DMA_COHERENT select SIBYTE_SB1250 select SWAP_IO_SPACE select SYS_HAS_CPU_SB1 @@ -813,7 +805,6 @@ config SIBYTE_SENTOSA config SIBYTE_BIGSUR bool "Sibyte BCM91480B-BigSur" select BOOT_ELF32 - select DMA_COHERENT select NR_CPUS_DEFAULT_4 select SIBYTE_BCM1x80 select SWAP_IO_SPACE @@ -890,7 +881,6 @@ config CAVIUM_OCTEON_SOC select CEVT_R4K select ARCH_HAS_PHYS_TO_DMA select PHYS_ADDR_T_64BIT - select DMA_COHERENT select SYS_SUPPORTS_64BIT_KERNEL select SYS_SUPPORTS_BIG_ENDIAN select EDAC_SUPPORT @@ -939,7 +929,6 @@ config NLM_XLR_BOARD select PHYS_ADDR_T_64BIT select SYS_SUPPORTS_BIG_ENDIAN select SYS_SUPPORTS_HIGHMEM - select DMA_COHERENT select NR_CPUS_DEFAULT_32 select CEVT_R4K select CSRC_R4K @@ -967,7 +956,6 @@ config NLM_XLP_BOARD select SYS_SUPPORTS_BIG_ENDIAN select SYS_SUPPORTS_LITTLE_ENDIAN select SYS_SUPPORTS_HIGHMEM - select DMA_COHERENT select NR_CPUS_DEFAULT_32 select CEVT_R4K select CSRC_R4K @@ -986,7 +974,6 @@ config MIPS_PARAVIRT bool "Para-Virtualized guest system" select CEVT_R4K select CSRC_R4K - select DMA_COHERENT select SYS_SUPPORTS_64BIT_KERNEL select SYS_SUPPORTS_32BIT_KERNEL select SYS_SUPPORTS_BIG_ENDIAN @@ -1112,9 +1099,6 @@ config DMA_PERDEV_COHERENT bool select DMA_MAYBE_COHERENT -config DMA_COHERENT - bool - config DMA_NONCOHERENT bool select NEED_DMA_MAP_STATE diff --git a/arch/mips/include/asm/dma-coherence.h b/arch/mips/include/asm/dma-coherence.h index 72d0eab02afc..8eda48748ed5 100644 --- a/arch/mips/include/asm/dma-coherence.h +++ b/arch/mips/include/asm/dma-coherence.h @@ -21,10 +21,10 @@ enum coherent_io_user_state { extern enum coherent_io_user_state coherentio; extern int hw_coherentio; #else -#ifdef CONFIG_DMA_COHERENT -#define coherentio IO_COHERENCE_ENABLED -#else +#ifdef CONFIG_DMA_NONCOHERENT #define coherentio IO_COHERENCE_DISABLED +#else +#define coherentio IO_COHERENCE_ENABLED #endif #define hw_coherentio 0 #endif /* CONFIG_DMA_MAYBE_COHERENT */ diff --git a/arch/mips/include/asm/mach-generic/kmalloc.h b/arch/mips/include/asm/mach-generic/kmalloc.h index 74207c7bd00d..649a98338886 100644 --- a/arch/mips/include/asm/mach-generic/kmalloc.h +++
[PATCH 01/25] MIPS: remove a dead ifdef from mach-ath25/dma-coherence.h
ath25 is alwas non-coherent, so keeping these ifdefs doesn't make any sense. Signed-off-by: Christoph Hellwig--- arch/mips/include/asm/mach-ath25/dma-coherence.h | 5 - 1 file changed, 5 deletions(-) diff --git a/arch/mips/include/asm/mach-ath25/dma-coherence.h b/arch/mips/include/asm/mach-ath25/dma-coherence.h index d5defdde32db..124755d4f079 100644 --- a/arch/mips/include/asm/mach-ath25/dma-coherence.h +++ b/arch/mips/include/asm/mach-ath25/dma-coherence.h @@ -61,12 +61,7 @@ static inline int plat_dma_supported(struct device *dev, u64 mask) static inline int plat_device_is_coherent(struct device *dev) { -#ifdef CONFIG_DMA_COHERENT - return 1; -#endif -#ifdef CONFIG_DMA_NONCOHERENT return 0; -#endif } static inline void plat_post_dma_flush(struct device *dev) -- 2.17.0 ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
[RFC] switch mips to use the generic dma map ops
Hi all, this huge series does a deep cleaning of the mips dma mapping code and moves most architectures over to use the generic dma_direct_ops or dma_noncoherent_ops. The Jazz architectures grows a new dma_map_ops tailered to its bare bones iommu implementation, and the swiotlb code use by Loongson-3 and Octeon is merged into a single implementation, pending further unification with the generic swiotlb_ops in another step. Note that all this has been compile tested only, and I've probably missed even that for some platforms.. A git tree is available here: git://git.infradead.org/users/hch/misc.git mips-direct-ops Gitweb: http://git.infradead.org/users/hch/misc.git/shortlog/refs/heads/mips-direct-ops ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
RE: [PATCH v6 0/7] vfio/type1: Add support for valid iova list management
Hi Alex, > -Original Message- > From: Alex Williamson [mailto:alex.william...@redhat.com] > Sent: Thursday, May 24, 2018 7:21 PM > To: Shameerali Kolothum Thodi> Cc: eric.au...@redhat.com; pmo...@linux.vnet.ibm.com; > k...@vger.kernel.org; linux-ker...@vger.kernel.org; iommu@lists.linux- > foundation.org; Linuxarm ; John Garry > ; xuwei (O) ; Joerg Roedel > > Subject: Re: [PATCH v6 0/7] vfio/type1: Add support for valid iova list > management > > [Cc +Joerg: AMD-Vi observation towards the end] > > On Wed, 18 Apr 2018 12:40:38 +0100 > Shameer Kolothum wrote: > > > This series introduces an iova list associated with a vfio > > iommu. The list is kept updated taking care of iommu apertures, > > and reserved regions. Also this series adds checks for any conflict > > with existing dma mappings whenever a new device group is attached to > > the domain. > > > > User-space can retrieve valid iova ranges using VFIO_IOMMU_GET_INFO > > ioctl capability chains. Any dma map request outside the valid iova > > range will be rejected. > > Hi Shameer, > > I ran into two minor issues in testing this series, both related to > mdev usage of type1. First, in patch 5/7 when we try to validate a dma > map request: I must admit I haven't looked into the mdev use case at all and my impression was that it will be same as others. Thanks for doing these tests. > > +static bool vfio_iommu_iova_dma_valid(struct vfio_iommu *iommu, > > + dma_addr_t start, dma_addr_t end) > > +{ > > + struct list_head *iova = >iova_list; > > + struct vfio_iova *node; > > + > > + list_for_each_entry(node, iova, list) { > > + if ((start >= node->start) && (end <= node->end)) > > + return true; > > + } > > + > > + return false; > > +} > > A container with only an mdev device will have an empty list because it > has not backing iommu to set ranges or reserved regions, so any dma map > will fail. I think this is resolved as follows: > > --- a/drivers/vfio/vfio_iommu_type1.c > +++ b/drivers/vfio/vfio_iommu_type1.c > @@ -1100,7 +1100,7 @@ static bool vfio_iommu_iova_dma_valid(struct > vfio_iommu *iommu, > return true; > } > > - return false; > + return list_empty(>iova_list); > } Ok. > ie. return false only if there was anything to test against. > > The second issue is similar, patch 6/7 adds to VFIO_IOMMU_GET_INFO: > > + ret = vfio_iommu_iova_build_caps(iommu, ); > + if (ret) > + return ret; > > And build_caps has: > > + list_for_each_entry(iova, >iova_list, list) > + iovas++; > + > + if (!iovas) { > + ret = -EINVAL; > > Therefore if the iova list is empty, as for mdevs, the use can no > longer even call VFIO_IOMMU_GET_INFO on the container, which is a > regression. Again, I think the fix is simple: > > @@ -2090,7 +2090,7 @@ static int vfio_iommu_iova_build_caps(struct > vfio_iommu *iommu, > iovas++; > > if (!iovas) { > - ret = -EINVAL; > + ret = 0; > goto out_unlock; > } > > ie. build_caps needs to handle lack of an iova_list as a non-error. Ok. > Also, I wrote a small unit test to validate the iova list for my > systems[1]. With the above changes, my Intel test system gives expected > results: > > # ./vfio-type1-iova-list /sys/bus/mdev/devices/c08db5ed-05d3-4b39-b150- > 438a18bc698f /sys/bus/pci/devices/:00:1b.0 > Adding device: c08db5ed-05d3-4b39-b150-438a18bc698f > Initial info struct size: 0x18 > No caps > Adding device: :00:1b.0 > Initial info struct size: 0x18 > Requested info struct size: 0x48 > New info struct size: 0x48 > argsz: 0x48, flags: 0x3, cap_offset: 0x18 > 00: 4800 0300 00f0 > 10: 1800 0100 0100 > 20: 0200 > 30: dffe f0fe > 40: ff01 > [cap id: 1, version: 1, next: 0x0] > Found type1 iova range version: 1 > 00: - fedf > 01: fef0 - 01ff > > Adding an mdev device to the container results in no iova list, adding > the physical device updates to the expected set with the MSI range > excluded. > > I was a little surprised by an AMD system: > > # ./vfio-type1-iova-list /sys/bus/pci/devices/:01:00.0 > Adding device: :01:00.0 > Initial info struct size: 0x18 > Requested info struct size: 0x58 > New info struct size: 0x58 > argsz: 0x58, flags: 0x3, cap_offset: 0x18 > 00: 5800 0300 00f0 7fff > 10: 1800 0100 0100 > 20: 0300 > 30:
Re: [PATCH] swiotlb: Fix inversed DMA_ATTR_NO_WARN test
On 2018-05-25 10:41 AM, Christoph Hellwig wrote: > On Tue, May 22, 2018 at 03:13:58PM +0200, Christian König wrote: >> Am 02.05.2018 um 18:59 schrieb Michel Dänzer: >>> On 2018-05-02 06:21 PM, Christoph Hellwig wrote: On Wed, May 02, 2018 at 04:31:09PM +0200, Michel Dänzer wrote: >> No. __GFP_NOWARN (and gfp_t flags in general) are the wrong interface >> for dma allocations and just cause problems. I actually plan to >> get rid of the gfp_t argument in dma_alloc_attrs sooner, and only >> allow either GFP_KERNEL or GFP_DMA passed in dma_alloc_coherent. > How about GFP_TRANSHUGE_LIGHT? TTM uses that to opportunistically > allocate huge pages (GFP_TRANSHUGE can result in unacceptably long > delays with memory pressure). Well, that is exactly what I don't want drivers to do - same for __GFP_COMP in some drm code. This very much assumes the page allocator is used to back dma allocations, which very often it actually isn't, and any use of magic gfp flags creates a tight coupling of consumers with a specific implementation. In general I can't think of a good reason not to actually use GFP_TRANSHUGE_LIGHT by default in the dma allocator unless DMA_ATTR_ALLOC_SINGLE_PAGES is set. Can you prepare a patch for that? >>> I'm afraid I'll have to leave that to somebody else. >> >> Coming back to this topic once more, sorry for the delay but busy as usual >> :) >> >> What exactly do you mean with "dma allocator" here? The TTM allocator using >> the dma_alloc_coherent calls? Or the swiotlb implementation of the calls? > > dma allocatr in this case: backends for dma_alloc_coherent/ > dma_alloc_attrs. Most importantly dma_direct_alloc. > > But while we're at it I can't actually see any GFP_TRANSHUGE_LIGHT > usage in TTM, just plain old GFP_TRANSHUGE. See https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=da291320baec914f0bb4e65a9dccb86bd6c728f2 . -- Earthling Michel Dänzer | http://www.amd.com Libre software enthusiast | Mesa and X developer ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
Re: [PATCH v2 03/40] iommu/sva: Manage process address spaces
+CC Kenneth Lee On Fri, 25 May 2018 09:33:11 +0300 Ilias Apalodimaswrote: > On Thu, May 24, 2018 at 04:04:39PM +0100, Jean-Philippe Brucker wrote: > > On 24/05/18 12:50, Ilias Apalodimas wrote: > > >> Interesting, I hadn't thought about this use-case before. At first I > > >> thought you were talking about mdev devices assigned to VMs, but I think > > >> you're referring to mdevs assigned to userspace drivers instead? Out of > > >> curiosity, is it only theoretical or does someone actually need this? > > > > > > There has been some non upstreamed efforts to have mdev and produce > > > userspace > > > drivers. Huawei is using it on what they call "wrapdrive" for crypto > > > devices and > > > we did a proof of concept for ethernet interfaces. At the time we choose > > > not to > > > involve the IOMMU for the reason you mentioned, but having it there would > > > be > > > good. > > > > I'm guessing there were good reasons to do it that way but I wonder, is > > it not simpler to just have the kernel driver create a /dev/foo, with a > > standard ioctl/mmap/poll interface? Here VFIO adds a layer of > > indirection, and since the mediating driver has to implement these > > operations already, what is gained? > The best reason i can come up with is "common code". You already have one API > doing that for you so we replicate it in a /dev file? > The mdev approach still needs extentions to support what we tried to do (i.e > mdev bus might need yo have access on iommu_ops), but as far as i undestand > it's > a possible case. > > > > Thanks, > > Jean ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
Re: [PATCH] swiotlb: Fix inversed DMA_ATTR_NO_WARN test
On Tue, May 22, 2018 at 03:13:58PM +0200, Christian König wrote: > Am 02.05.2018 um 18:59 schrieb Michel Dänzer: >> On 2018-05-02 06:21 PM, Christoph Hellwig wrote: >>> On Wed, May 02, 2018 at 04:31:09PM +0200, Michel Dänzer wrote: > No. __GFP_NOWARN (and gfp_t flags in general) are the wrong interface > for dma allocations and just cause problems. I actually plan to > get rid of the gfp_t argument in dma_alloc_attrs sooner, and only > allow either GFP_KERNEL or GFP_DMA passed in dma_alloc_coherent. How about GFP_TRANSHUGE_LIGHT? TTM uses that to opportunistically allocate huge pages (GFP_TRANSHUGE can result in unacceptably long delays with memory pressure). >>> Well, that is exactly what I don't want drivers to do - same for >>> __GFP_COMP in some drm code. This very much assumes the page allocator >>> is used to back dma allocations, which very often it actually isn't, and >>> any use of magic gfp flags creates a tight coupling of consumers with a >>> specific implementation. >>> >>> In general I can't think of a good reason not to actually use >>> GFP_TRANSHUGE_LIGHT by default in the dma allocator unless >>> DMA_ATTR_ALLOC_SINGLE_PAGES is set. Can you prepare a patch for that? >> I'm afraid I'll have to leave that to somebody else. > > Coming back to this topic once more, sorry for the delay but busy as usual > :) > > What exactly do you mean with "dma allocator" here? The TTM allocator using > the dma_alloc_coherent calls? Or the swiotlb implementation of the calls? dma allocatr in this case: backends for dma_alloc_coherent/ dma_alloc_attrs. Most importantly dma_direct_alloc. But while we're at it I can't actually see any GFP_TRANSHUGE_LIGHT usage in TTM, just plain old GFP_TRANSHUGE. ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
Re: [PATCH v2 03/40] iommu/sva: Manage process address spaces
On Thu, May 24, 2018 at 04:04:39PM +0100, Jean-Philippe Brucker wrote: > On 24/05/18 12:50, Ilias Apalodimas wrote: > >> Interesting, I hadn't thought about this use-case before. At first I > >> thought you were talking about mdev devices assigned to VMs, but I think > >> you're referring to mdevs assigned to userspace drivers instead? Out of > >> curiosity, is it only theoretical or does someone actually need this? > > > > There has been some non upstreamed efforts to have mdev and produce > > userspace > > drivers. Huawei is using it on what they call "wrapdrive" for crypto > > devices and > > we did a proof of concept for ethernet interfaces. At the time we choose > > not to > > involve the IOMMU for the reason you mentioned, but having it there would be > > good. > > I'm guessing there were good reasons to do it that way but I wonder, is > it not simpler to just have the kernel driver create a /dev/foo, with a > standard ioctl/mmap/poll interface? Here VFIO adds a layer of > indirection, and since the mediating driver has to implement these > operations already, what is gained? The best reason i can come up with is "common code". You already have one API doing that for you so we replicate it in a /dev file? The mdev approach still needs extentions to support what we tried to do (i.e mdev bus might need yo have access on iommu_ops), but as far as i undestand it's a possible case. > > Thanks, > Jean ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu