Re: use generic DMA mapping code in powerpc V4
> On 12. Dec 2018, at 01:47, Benjamin Herrenschmidt > wrote: > >> On Tue, 2018-12-11 at 19:17 +0100, Christian Zigotzky wrote: >> X5000 (P5020 board): U-Boot loads the kernel and the dtb file. Then the >> kernel starts but it doesn't find any hard disks (partitions). That >> means this is also the bad commit for the P5020 board. > > What are the disks hanging off ? A PCIe device of some sort ? > > Can you send good & bad dmesg logs ? > > Ben. > > Unfortunately not. It doesn’t detect any hard disk. That means the kernel ring buffer won’t save to log files. I don’t have a serial null modem cable for seeing all output. We use SATA disks. I will investigate more in this problem with rollback the files in the bad commit. — Christian ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
[RFC PATCH 1/3] PCI: Add dma-resv window list
Add a dma_resv parameter in pci host bridge structure to hold resource entries list of memory regions for which IOVAs has to reserve. IOMMU framework reserve IOVA for this list of address range while initializing IOMMU domain of corresponding PCI EP connected to the HOST. PCIe host driver will add resource entries to this list based on requirements. Few hosts can't use all inbound address, so those address regions will be add to this list to avoid IOMMU mapping. Signed-off-by: Srinath Mannam --- drivers/pci/probe.c | 3 +++ include/linux/pci.h | 1 + 2 files changed, 4 insertions(+) diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index ec78400..bbed0e7 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -544,6 +544,7 @@ struct pci_host_bridge *pci_alloc_host_bridge(size_t priv) return NULL; INIT_LIST_HEAD(>windows); + INIT_LIST_HEAD(>dma_resv); bridge->dev.release = pci_release_host_bridge_dev; /* @@ -572,6 +573,7 @@ struct pci_host_bridge *devm_pci_alloc_host_bridge(struct device *dev, return NULL; INIT_LIST_HEAD(>windows); + INIT_LIST_HEAD(>dma_resv); bridge->dev.release = devm_pci_release_host_bridge_dev; return bridge; @@ -581,6 +583,7 @@ EXPORT_SYMBOL(devm_pci_alloc_host_bridge); void pci_free_host_bridge(struct pci_host_bridge *bridge) { pci_free_resource_list(>windows); + pci_free_resource_list(>dma_resv); kfree(bridge); } diff --git a/include/linux/pci.h b/include/linux/pci.h index e72ca8d..1f0a32a 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -472,6 +472,7 @@ struct pci_host_bridge { void*sysdata; int busnr; struct list_head windows; /* resource_entry */ + struct list_head dma_resv; /* reserv dma ranges */ u8 (*swizzle_irq)(struct pci_dev *, u8 *); /* Platform IRQ swizzler */ int (*map_irq)(const struct pci_dev *, u8, u8); void (*release_fn)(struct pci_host_bridge *); -- 2.7.4 ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
[RFC PATCH 2/3] iommu/dma: IOVA reserve for PCI host reserve address list
PCI host has list of resource entries contain memory address range for which IOVA address mapping has to be reserve. These address ranges are the address holes in dma-ranges property. It is similar to PCI IO resources address range reserving in IOMMU for each EP connected to corresponding host. Signed-off-by: Srinath Mannam --- drivers/iommu/dma-iommu.c | 8 1 file changed, 8 insertions(+) diff --git a/drivers/iommu/dma-iommu.c b/drivers/iommu/dma-iommu.c index 511ff9a..346da81 100644 --- a/drivers/iommu/dma-iommu.c +++ b/drivers/iommu/dma-iommu.c @@ -220,6 +220,14 @@ static void iova_reserve_pci_windows(struct pci_dev *dev, hi = iova_pfn(iovad, window->res->end - window->offset); reserve_iova(iovad, lo, hi); } + + /* Get reserved DMA windows from host bridge */ + resource_list_for_each_entry(window, >dma_resv) { + + lo = iova_pfn(iovad, window->res->start - window->offset); + hi = iova_pfn(iovad, window->res->end - window->offset); + reserve_iova(iovad, lo, hi); + } } static int iova_reserve_iommu_regions(struct device *dev, -- 2.7.4 ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
[RFC PATCH 0/3] PCIe Host request to reserve IOVA
Few SOCs have limitation that their PCIe host can't allow few inbound address ranges. Allowed inbound address ranges are listed in dma-ranges DT property and this address ranges are required to do IOVA mapping. Remaining address ranges have to be reserved in IOVA mapping. PCIe Host driver of those SOCs has to list all address ranges which have to reserve their IOVA address into PCIe host bridge resource entry list. IOMMU framework will reserve these IOVAs while initializing IOMMU domain. This patch set is based on Linux-4.19-rc1. Srinath Mannam (3): PCI: Add dma-resv window list iommu/dma: IOVA reserve for PCI host reserve address list PCI: iproc: Add dma reserve resources to host drivers/iommu/dma-iommu.c | 8 ++ drivers/pci/controller/pcie-iproc.c | 49 + drivers/pci/probe.c | 3 +++ include/linux/pci.h | 1 + 4 files changed, 61 insertions(+) -- 2.7.4 ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
Re: use generic DMA mapping code in powerpc V4
On Tue, 2018-12-11 at 19:17 +0100, Christian Zigotzky wrote: > X5000 (P5020 board): U-Boot loads the kernel and the dtb file. Then the > kernel starts but it doesn't find any hard disks (partitions). That > means this is also the bad commit for the P5020 board. What are the disks hanging off ? A PCIe device of some sort ? Can you send good & bad dmesg logs ? Ben. ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
Re: [PATCH v6 0/7] Add virtio-iommu driver
On Tue, Dec 11, 2018 at 10:31:01AM -0800, Christoph Hellwig wrote: > On Tue, Dec 11, 2018 at 06:20:57PM +, Jean-Philippe Brucker wrote: > > Implement the virtio-iommu driver, following specification v0.9 [1]. > > > > Only minor changes since v5 [2]. I fixed issues reported by Michael and > > added tags from Eric and Bharat. Thanks! > > > > You can find Linux driver and kvmtool device on v0.9 branches [3], > > module and x86 support on virtio-iommu/devel. Also tested with Eric's > > QEMU device [4]. > > Just curious, what is the use case for it? If what I saw is any indication, it allows a very simple implementation of page table shadowing on the host, at the cost of not being able to accelerate with a hardware nested page tables support when available. -- MST ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
[GIT PULL] iommu/arm-smmu: Updates for 4.21
Hi Joerg, Please pull the following arm-smmu updates for 4.21. This includes the clock and pm_runtime updates to the arm-smmu driver, as well as some non-critical fixes for the arm-smmu-v3 driver. Cheers, Will --->8 The following changes since commit 9ff01193a20d391e8dbce4403dd5ef87c7eaaca6: Linux 4.20-rc3 (2018-11-18 13:33:44 -0800) are available in the git repository at: git://git.kernel.org/pub/scm/linux/kernel/git/will/linux.git for-joerg/arm-smmu/updates for you to fetch changes up to 89cddc563743cb1e0068867ac97013b2a5bf86aa: iommu/arm-smmu: Add support for qcom,smmu-v2 variant (2018-12-10 14:56:00 +) Robin Murphy (1): iommu/arm-smmu-v3: Fix big-endian CMD_SYNC writes Sricharan R (3): iommu/arm-smmu: Add pm_runtime/sleep ops iommu/arm-smmu: Invoke pm_runtime across the driver iommu/arm-smmu: Add the device_link between masters and smmu Vivek Gautam (2): dt-bindings: arm-smmu: Add bindings for qcom,smmu-v2 iommu/arm-smmu: Add support for qcom,smmu-v2 variant Will Deacon (1): iommu/arm-smmu-v3: Use explicit mb() when moving cons pointer Zhen Lei (1): iommu/arm-smmu-v3: Avoid memory corruption from Hisilicon MSI payloads .../devicetree/bindings/iommu/arm,smmu.txt | 39 + drivers/iommu/arm-smmu-v3.c| 22 ++- drivers/iommu/arm-smmu.c | 170 +++-- 3 files changed, 216 insertions(+), 15 deletions(-) ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
Re: [PATCH v6 0/7] Add virtio-iommu driver
On 11/12/2018 18:31, Christoph Hellwig wrote: > On Tue, Dec 11, 2018 at 06:20:57PM +, Jean-Philippe Brucker wrote: >> Implement the virtio-iommu driver, following specification v0.9 [1]. >> >> Only minor changes since v5 [2]. I fixed issues reported by Michael and >> added tags from Eric and Bharat. Thanks! >> >> You can find Linux driver and kvmtool device on v0.9 branches [3], >> module and x86 support on virtio-iommu/devel. Also tested with Eric's >> QEMU device [4]. > > Just curious, what is the use case for it? The main use case is assigning a device to guest userspace, using VFIO both in the host and in the guest (the most cited example being DPDK). There are others, and I wrote a little more about them last week: https://www.spinics.net/lists/linux-pci/msg78529.html Thanks, Jean ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
Re: [RFC PATCH 0/6] Auxiliary IOMMU domains and Arm SMMUv3
On 10/12/2018 08:57, 'j...@8bytes.org' wrote: > Hi Kevin, > > On Mon, Dec 10, 2018 at 02:06:44AM +, Tian, Kevin wrote: >> Can I interpret above as that you agree with the aux domain concept (i.e. one >> device can be linked to multiple domains) in general, and now we're just >> trying >> to address the remaining open in API level? > > Yes, I thouht about alternatives, but in the end they are all harder to > use than the aux-domain concept. We just need to make sure that we have > a clear definition of what the API extension do and how they impact the > behavior of existing functions. > >>> enum iommu_dev_features { >>> /* ... */ >>> IOMMU_DEV_FEAT_AUX, >>> IOMMU_DEV_FEAT_SVA, >>> /* ... */ >>> }; >>> >> >> Does above represent whether a device implements aux/sva features, >> or whether a device has been enabled by driver to support aux/sva >> features? > > These represent whether the device together with the IOMMU support them, > basically whether these features are usable via the IOMMU-API. > > >> >>> /* Check if a device supports a given feature of the IOMMU-API */ >>> bool iommu_dev_has_feature(struct device *dev, enum >>> iommu_dev_features *feat); >> >> If the latter we also need iommu_dev_set_feature so driver can poke >> it based on its own configuration. > > Do you mean we need an explict enable-API for the features? I thought > about that too, but some features clearly don't need it and I didn't > want to complicate the usage. My assumption was that when the feature is > available, it is also enabled. The cost of enabling those features for a device does seem negligible. For the SMMU we need to allocate about 70k of additional memory for the initial PASID table, but enabling the PASID cap shouldn't add any overhead otherwise. Same for PRI, shouldn't add any overhead. As for ATS, it supposedly makes things faster, although it does mean more invalidation requests. There currently is a global pci=noats parameter, but maybe we need something with finer granularity to enable/disable it per device? Thanks, Jean ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
Re: [PATCH v6 0/7] Add virtio-iommu driver
On Tue, Dec 11, 2018 at 06:20:57PM +, Jean-Philippe Brucker wrote: > Implement the virtio-iommu driver, following specification v0.9 [1]. > > Only minor changes since v5 [2]. I fixed issues reported by Michael and > added tags from Eric and Bharat. Thanks! > > You can find Linux driver and kvmtool device on v0.9 branches [3], > module and x86 support on virtio-iommu/devel. Also tested with Eric's > QEMU device [4]. Just curious, what is the use case for it? ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
[PATCH v6 6/7] iommu/virtio: Add probe request
When the device offers the probe feature, send a probe request for each device managed by the IOMMU. Extract RESV_MEM information. When we encounter a MSI doorbell region, set it up as a IOMMU_RESV_MSI region. This will tell other subsystems that there is no need to map the MSI doorbell in the virtio-iommu, because MSIs bypass it. Tested-by: Bharat Bhushan Tested-by: Eric Auger Reviewed-by: Eric Auger Signed-off-by: Jean-Philippe Brucker --- drivers/iommu/virtio-iommu.c | 156 -- include/uapi/linux/virtio_iommu.h | 36 +++ 2 files changed, 186 insertions(+), 6 deletions(-) diff --git a/drivers/iommu/virtio-iommu.c b/drivers/iommu/virtio-iommu.c index 7540dab9c8dc..0c7a7fa2628d 100644 --- a/drivers/iommu/virtio-iommu.c +++ b/drivers/iommu/virtio-iommu.c @@ -46,6 +46,7 @@ struct viommu_dev { struct iommu_domain_geometrygeometry; u64 pgsize_bitmap; u8 domain_bits; + u32 probe_size; }; struct viommu_mapping { @@ -67,8 +68,10 @@ struct viommu_domain { }; struct viommu_endpoint { + struct device *dev; struct viommu_dev *viommu; struct viommu_domain*vdomain; + struct list_headresv_regions; }; struct viommu_request { @@ -119,6 +122,9 @@ static off_t viommu_get_write_desc_offset(struct viommu_dev *viommu, { size_t tail_size = sizeof(struct virtio_iommu_req_tail); + if (req->type == VIRTIO_IOMMU_T_PROBE) + return len - viommu->probe_size - tail_size; + return len - tail_size; } @@ -393,6 +399,110 @@ static int viommu_replay_mappings(struct viommu_domain *vdomain) return ret; } +static int viommu_add_resv_mem(struct viommu_endpoint *vdev, + struct virtio_iommu_probe_resv_mem *mem, + size_t len) +{ + size_t size; + u64 start64, end64; + phys_addr_t start, end; + struct iommu_resv_region *region = NULL; + unsigned long prot = IOMMU_WRITE | IOMMU_NOEXEC | IOMMU_MMIO; + + start = start64 = le64_to_cpu(mem->start); + end = end64 = le64_to_cpu(mem->end); + size = end64 - start64 + 1; + + /* Catch any overflow, including the unlikely end64 - start64 + 1 = 0 */ + if (start != start64 || end != end64 || size < end64 - start64) + return -EOVERFLOW; + + if (len < sizeof(*mem)) + return -EINVAL; + + switch (mem->subtype) { + default: + dev_warn(vdev->dev, "unknown resv mem subtype 0x%x\n", +mem->subtype); + /* Fall-through */ + case VIRTIO_IOMMU_RESV_MEM_T_RESERVED: + region = iommu_alloc_resv_region(start, size, 0, +IOMMU_RESV_RESERVED); + break; + case VIRTIO_IOMMU_RESV_MEM_T_MSI: + region = iommu_alloc_resv_region(start, size, prot, +IOMMU_RESV_MSI); + break; + } + if (!region) + return -ENOMEM; + + list_add(>resv_regions, >list); + return 0; +} + +static int viommu_probe_endpoint(struct viommu_dev *viommu, struct device *dev) +{ + int ret; + u16 type, len; + size_t cur = 0; + size_t probe_len; + struct virtio_iommu_req_probe *probe; + struct virtio_iommu_probe_property *prop; + struct iommu_fwspec *fwspec = dev->iommu_fwspec; + struct viommu_endpoint *vdev = fwspec->iommu_priv; + + if (!fwspec->num_ids) + return -EINVAL; + + probe_len = sizeof(*probe) + viommu->probe_size + + sizeof(struct virtio_iommu_req_tail); + probe = kzalloc(probe_len, GFP_KERNEL); + if (!probe) + return -ENOMEM; + + probe->head.type = VIRTIO_IOMMU_T_PROBE; + /* +* For now, assume that properties of an endpoint that outputs multiple +* IDs are consistent. Only probe the first one. +*/ + probe->endpoint = cpu_to_le32(fwspec->ids[0]); + + ret = viommu_send_req_sync(viommu, probe, probe_len); + if (ret) + goto out_free; + + prop = (void *)probe->properties; + type = le16_to_cpu(prop->type) & VIRTIO_IOMMU_PROBE_T_MASK; + + while (type != VIRTIO_IOMMU_PROBE_T_NONE && + cur < viommu->probe_size) { + len = le16_to_cpu(prop->length) + sizeof(*prop); + + switch (type) { + case VIRTIO_IOMMU_PROBE_T_RESV_MEM: + ret = viommu_add_resv_mem(vdev, (void *)prop, len); + break; + default: + dev_err(dev, "unknown viommu prop 0x%x\n", type); + } + + if (ret) +
[PATCH v6 5/7] iommu: Add virtio-iommu driver
The virtio IOMMU is a para-virtualized device, allowing to send IOMMU requests such as map/unmap over virtio transport without emulating page tables. This implementation handles ATTACH, DETACH, MAP and UNMAP requests. The bulk of the code transforms calls coming from the IOMMU API into corresponding virtio requests. Mappings are kept in an interval tree instead of page tables. A little more work is required for modular and x86 support, so for the moment the driver depends on CONFIG_VIRTIO=y and CONFIG_ARM64. Tested-by: Bharat Bhushan Tested-by: Eric Auger Reviewed-by: Eric Auger Signed-off-by: Jean-Philippe Brucker --- MAINTAINERS | 7 + drivers/iommu/Kconfig | 11 + drivers/iommu/Makefile| 1 + drivers/iommu/virtio-iommu.c | 916 ++ include/uapi/linux/virtio_ids.h | 1 + include/uapi/linux/virtio_iommu.h | 106 6 files changed, 1042 insertions(+) create mode 100644 drivers/iommu/virtio-iommu.c create mode 100644 include/uapi/linux/virtio_iommu.h diff --git a/MAINTAINERS b/MAINTAINERS index 8119141a926f..6d250bc7a4ae 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -16041,6 +16041,13 @@ S: Maintained F: drivers/virtio/virtio_input.c F: include/uapi/linux/virtio_input.h +VIRTIO IOMMU DRIVER +M: Jean-Philippe Brucker +L: virtualizat...@lists.linux-foundation.org +S: Maintained +F: drivers/iommu/virtio-iommu.c +F: include/uapi/linux/virtio_iommu.h + VIRTUAL BOX GUEST DEVICE DRIVER M: Hans de Goede M: Arnd Bergmann diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig index d9a25715650e..d507fd754214 100644 --- a/drivers/iommu/Kconfig +++ b/drivers/iommu/Kconfig @@ -435,4 +435,15 @@ config QCOM_IOMMU help Support for IOMMU on certain Qualcomm SoCs. +config VIRTIO_IOMMU + bool "Virtio IOMMU driver" + depends on VIRTIO=y + depends on ARM64 + select IOMMU_API + select INTERVAL_TREE + help + Para-virtualised IOMMU driver with virtio. + + Say Y here if you intend to run this kernel as a guest. + endif # IOMMU_SUPPORT diff --git a/drivers/iommu/Makefile b/drivers/iommu/Makefile index a158a68c8ea8..48d831a39281 100644 --- a/drivers/iommu/Makefile +++ b/drivers/iommu/Makefile @@ -32,3 +32,4 @@ obj-$(CONFIG_EXYNOS_IOMMU) += exynos-iommu.o obj-$(CONFIG_FSL_PAMU) += fsl_pamu.o fsl_pamu_domain.o obj-$(CONFIG_S390_IOMMU) += s390-iommu.o obj-$(CONFIG_QCOM_IOMMU) += qcom_iommu.o +obj-$(CONFIG_VIRTIO_IOMMU) += virtio-iommu.o diff --git a/drivers/iommu/virtio-iommu.c b/drivers/iommu/virtio-iommu.c new file mode 100644 index ..7540dab9c8dc --- /dev/null +++ b/drivers/iommu/virtio-iommu.c @@ -0,0 +1,916 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Virtio driver for the paravirtualized IOMMU + * + * Copyright (C) 2018 Arm Limited + */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#define MSI_IOVA_BASE 0x800 +#define MSI_IOVA_LENGTH0x10 + +#define VIOMMU_REQUEST_VQ 0 +#define VIOMMU_NR_VQS 1 + +struct viommu_dev { + struct iommu_device iommu; + struct device *dev; + struct virtio_device*vdev; + + struct ida domain_ids; + + struct virtqueue*vqs[VIOMMU_NR_VQS]; + spinlock_t request_lock; + struct list_headrequests; + + /* Device configuration */ + struct iommu_domain_geometrygeometry; + u64 pgsize_bitmap; + u8 domain_bits; +}; + +struct viommu_mapping { + phys_addr_t paddr; + struct interval_tree_node iova; + u32 flags; +}; + +struct viommu_domain { + struct iommu_domain domain; + struct viommu_dev *viommu; + struct mutexmutex; /* protects viommu pointer */ + unsigned intid; + + spinlock_t mappings_lock; + struct rb_root_cached mappings; + + unsigned long nr_endpoints; +}; + +struct viommu_endpoint { + struct viommu_dev *viommu; + struct viommu_domain*vdomain; +}; + +struct viommu_request { + struct list_headlist; + void*writeback; + unsigned intwrite_offset; + unsigned intlen; + charbuf[]; +}; + +#define to_viommu_domain(domain) \ + container_of(domain, struct viommu_domain,
[PATCH v6 7/7] iommu/virtio: Add event queue
The event queue offers a way for the device to report access faults from endpoints. It is implemented on virtqueue #1. Whenever the host needs to signal a fault, it fills one of the buffers offered by the guest and interrupts it. Tested-by: Bharat Bhushan Tested-by: Eric Auger Reviewed-by: Eric Auger Signed-off-by: Jean-Philippe Brucker --- drivers/iommu/virtio-iommu.c | 115 +++--- include/uapi/linux/virtio_iommu.h | 19 + 2 files changed, 125 insertions(+), 9 deletions(-) diff --git a/drivers/iommu/virtio-iommu.c b/drivers/iommu/virtio-iommu.c index 0c7a7fa2628d..e6ff515d41c0 100644 --- a/drivers/iommu/virtio-iommu.c +++ b/drivers/iommu/virtio-iommu.c @@ -29,7 +29,8 @@ #define MSI_IOVA_LENGTH0x10 #define VIOMMU_REQUEST_VQ 0 -#define VIOMMU_NR_VQS 1 +#define VIOMMU_EVENT_VQ1 +#define VIOMMU_NR_VQS 2 struct viommu_dev { struct iommu_device iommu; @@ -41,6 +42,7 @@ struct viommu_dev { struct virtqueue*vqs[VIOMMU_NR_VQS]; spinlock_t request_lock; struct list_headrequests; + void*evts; /* Device configuration */ struct iommu_domain_geometrygeometry; @@ -82,6 +84,15 @@ struct viommu_request { charbuf[]; }; +#define VIOMMU_FAULT_RESV_MASK 0xff00 + +struct viommu_event { + union { + u32 head; + struct virtio_iommu_fault fault; + }; +}; + #define to_viommu_domain(domain) \ container_of(domain, struct viommu_domain, domain) @@ -503,6 +514,68 @@ static int viommu_probe_endpoint(struct viommu_dev *viommu, struct device *dev) return ret; } +static int viommu_fault_handler(struct viommu_dev *viommu, + struct virtio_iommu_fault *fault) +{ + char *reason_str; + + u8 reason = fault->reason; + u32 flags = le32_to_cpu(fault->flags); + u32 endpoint= le32_to_cpu(fault->endpoint); + u64 address = le64_to_cpu(fault->address); + + switch (reason) { + case VIRTIO_IOMMU_FAULT_R_DOMAIN: + reason_str = "domain"; + break; + case VIRTIO_IOMMU_FAULT_R_MAPPING: + reason_str = "page"; + break; + case VIRTIO_IOMMU_FAULT_R_UNKNOWN: + default: + reason_str = "unknown"; + break; + } + + /* TODO: find EP by ID and report_iommu_fault */ + if (flags & VIRTIO_IOMMU_FAULT_F_ADDRESS) + dev_err_ratelimited(viommu->dev, "%s fault from EP %u at %#llx [%s%s%s]\n", + reason_str, endpoint, address, + flags & VIRTIO_IOMMU_FAULT_F_READ ? "R" : "", + flags & VIRTIO_IOMMU_FAULT_F_WRITE ? "W" : "", + flags & VIRTIO_IOMMU_FAULT_F_EXEC ? "X" : ""); + else + dev_err_ratelimited(viommu->dev, "%s fault from EP %u\n", + reason_str, endpoint); + return 0; +} + +static void viommu_event_handler(struct virtqueue *vq) +{ + int ret; + unsigned int len; + struct scatterlist sg[1]; + struct viommu_event *evt; + struct viommu_dev *viommu = vq->vdev->priv; + + while ((evt = virtqueue_get_buf(vq, )) != NULL) { + if (len > sizeof(*evt)) { + dev_err(viommu->dev, + "invalid event buffer (len %u != %zu)\n", + len, sizeof(*evt)); + } else if (!(evt->head & VIOMMU_FAULT_RESV_MASK)) { + viommu_fault_handler(viommu, >fault); + } + + sg_init_one(sg, evt, sizeof(*evt)); + ret = virtqueue_add_inbuf(vq, sg, 1, evt, GFP_ATOMIC); + if (ret) + dev_err(viommu->dev, "could not add event buffer\n"); + } + + virtqueue_kick(vq); +} + /* IOMMU API */ static struct iommu_domain *viommu_domain_alloc(unsigned type) @@ -885,16 +958,35 @@ static struct iommu_ops viommu_ops = { static int viommu_init_vqs(struct viommu_dev *viommu) { struct virtio_device *vdev = dev_to_virtio(viommu->dev); - const char *name = "request"; - void *ret; + const char *names[] = { "request", "event" }; + vq_callback_t *callbacks[] = { + NULL, /* No async requests */ + viommu_event_handler, + }; - ret = virtio_find_single_vq(vdev, NULL, name); - if (IS_ERR(ret)) { - dev_err(viommu->dev, "cannot find VQ\n"); - return PTR_ERR(ret); - } + return virtio_find_vqs(vdev, VIOMMU_NR_VQS, viommu->vqs,
[PATCH v6 4/7] PCI: OF: Initialize dev->fwnode appropriately
For PCI devices that have an OF node, set the fwnode as well. This way drivers that rely on fwnode don't need the special case described by commit f94277af03ea ("of/platform: Initialise dev->fwnode appropriately"). Acked-by: Bjorn Helgaas Signed-off-by: Jean-Philippe Brucker --- drivers/pci/of.c | 7 +++ 1 file changed, 7 insertions(+) diff --git a/drivers/pci/of.c b/drivers/pci/of.c index 4c4217d0c3f1..c272ecfcd038 100644 --- a/drivers/pci/of.c +++ b/drivers/pci/of.c @@ -21,12 +21,15 @@ void pci_set_of_node(struct pci_dev *dev) return; dev->dev.of_node = of_pci_find_child_device(dev->bus->dev.of_node, dev->devfn); + if (dev->dev.of_node) + dev->dev.fwnode = >dev.of_node->fwnode; } void pci_release_of_node(struct pci_dev *dev) { of_node_put(dev->dev.of_node); dev->dev.of_node = NULL; + dev->dev.fwnode = NULL; } void pci_set_bus_of_node(struct pci_bus *bus) @@ -35,12 +38,16 @@ void pci_set_bus_of_node(struct pci_bus *bus) bus->dev.of_node = pcibios_get_phb_of_node(bus); else bus->dev.of_node = of_node_get(bus->self->dev.of_node); + + if (bus->dev.of_node) + bus->dev.fwnode = >dev.of_node->fwnode; } void pci_release_bus_of_node(struct pci_bus *bus) { of_node_put(bus->dev.of_node); bus->dev.of_node = NULL; + bus->dev.fwnode = NULL; } struct device_node * __weak pcibios_get_phb_of_node(struct pci_bus *bus) -- 2.19.1 ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
[PATCH v6 1/7] dt-bindings: virtio-mmio: Add IOMMU description
The nature of a virtio-mmio node is discovered by the virtio driver at probe time. However the DMA relation between devices must be described statically. When a virtio-mmio node is a virtio-iommu device, it needs an "#iommu-cells" property as specified by bindings/iommu/iommu.txt. Otherwise, the virtio-mmio device may perform DMA through an IOMMU, which requires an "iommus" property. Describe these requirements in the device-tree bindings documentation. Reviewed-by: Rob Herring Reviewed-by: Eric Auger Signed-off-by: Jean-Philippe Brucker --- .../devicetree/bindings/virtio/mmio.txt | 30 +++ 1 file changed, 30 insertions(+) diff --git a/Documentation/devicetree/bindings/virtio/mmio.txt b/Documentation/devicetree/bindings/virtio/mmio.txt index 5069c1b8e193..21af30fbb81f 100644 --- a/Documentation/devicetree/bindings/virtio/mmio.txt +++ b/Documentation/devicetree/bindings/virtio/mmio.txt @@ -8,10 +8,40 @@ Required properties: - reg: control registers base address and size including configuration space - interrupts: interrupt generated by the device +Required properties for virtio-iommu: + +- #iommu-cells:When the node corresponds to a virtio-iommu device, it is + linked to DMA masters using the "iommus" or "iommu-map" + properties [1][2]. #iommu-cells specifies the size of the + "iommus" property. For virtio-iommu #iommu-cells must be + 1, each cell describing a single endpoint ID. + +Optional properties: + +- iommus: If the device accesses memory through an IOMMU, it should + have an "iommus" property [1]. Since virtio-iommu itself + does not access memory through an IOMMU, the "virtio,mmio" + node cannot have both an "#iommu-cells" and an "iommus" + property. + Example: virtio_block@3000 { compatible = "virtio,mmio"; reg = <0x3000 0x100>; interrupts = <41>; + + /* Device has endpoint ID 23 */ + iommus = < 23> } + + viommu: iommu@3100 { + compatible = "virtio,mmio"; + reg = <0x3100 0x100>; + interrupts = <42>; + + #iommu-cells = <1> + } + +[1] Documentation/devicetree/bindings/iommu/iommu.txt +[2] Documentation/devicetree/bindings/pci/pci-iommu.txt -- 2.19.1 ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
[PATCH v6 0/7] Add virtio-iommu driver
Implement the virtio-iommu driver, following specification v0.9 [1]. Only minor changes since v5 [2]. I fixed issues reported by Michael and added tags from Eric and Bharat. Thanks! You can find Linux driver and kvmtool device on v0.9 branches [3], module and x86 support on virtio-iommu/devel. Also tested with Eric's QEMU device [4]. [1] Virtio-iommu specification v0.9, sources and pdf git://linux-arm.org/virtio-iommu.git virtio-iommu/v0.9 http://jpbrucker.net/virtio-iommu/spec/v0.9/virtio-iommu-v0.9.pdf [2] [PATCH v5 0/7] Add virtio-iommu driver https://www.spinics.net/lists/linux-pci/msg78158.html [3] git://linux-arm.org/linux-jpb.git virtio-iommu/v0.9.1 git://linux-arm.org/kvmtool-jpb.git virtio-iommu/v0.9 [4] [RFC v9 00/17] VIRTIO-IOMMU device https://www.mail-archive.com/qemu-devel@nongnu.org/msg575578.html Jean-Philippe Brucker (7): dt-bindings: virtio-mmio: Add IOMMU description dt-bindings: virtio: Add virtio-pci-iommu node of: Allow the iommu-map property to omit untranslated devices PCI: OF: Initialize dev->fwnode appropriately iommu: Add virtio-iommu driver iommu/virtio: Add probe request iommu/virtio: Add event queue .../devicetree/bindings/virtio/iommu.txt | 66 + .../devicetree/bindings/virtio/mmio.txt | 30 + MAINTAINERS |7 + drivers/iommu/Kconfig | 11 + drivers/iommu/Makefile|1 + drivers/iommu/virtio-iommu.c | 1157 + drivers/of/base.c | 10 +- drivers/pci/of.c |7 + include/uapi/linux/virtio_ids.h |1 + include/uapi/linux/virtio_iommu.h | 161 +++ 10 files changed, 1448 insertions(+), 3 deletions(-) create mode 100644 Documentation/devicetree/bindings/virtio/iommu.txt create mode 100644 drivers/iommu/virtio-iommu.c create mode 100644 include/uapi/linux/virtio_iommu.h -- 2.19.1 ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
[PATCH v6 2/7] dt-bindings: virtio: Add virtio-pci-iommu node
Some systems implement virtio-iommu as a PCI endpoint. The operating system needs to discover the relationship between IOMMU and masters long before the PCI endpoint gets probed. Add a PCI child node to describe the virtio-iommu device. The virtio-pci-iommu is conceptually split between a PCI programming interface and a translation component on the parent bus. The latter doesn't have a node in the device tree. The virtio-pci-iommu node describes both, by linking the PCI endpoint to "iommus" property of DMA master nodes and to "iommu-map" properties of bus nodes. Reviewed-by: Rob Herring Reviewed-by: Eric Auger Signed-off-by: Jean-Philippe Brucker --- .../devicetree/bindings/virtio/iommu.txt | 66 +++ 1 file changed, 66 insertions(+) create mode 100644 Documentation/devicetree/bindings/virtio/iommu.txt diff --git a/Documentation/devicetree/bindings/virtio/iommu.txt b/Documentation/devicetree/bindings/virtio/iommu.txt new file mode 100644 index ..2407fea0651c --- /dev/null +++ b/Documentation/devicetree/bindings/virtio/iommu.txt @@ -0,0 +1,66 @@ +* virtio IOMMU PCI device + +When virtio-iommu uses the PCI transport, its programming interface is +discovered dynamically by the PCI probing infrastructure. However the +device tree statically describes the relation between IOMMU and DMA +masters. Therefore, the PCI root complex that hosts the virtio-iommu +contains a child node representing the IOMMU device explicitly. + +Required properties: + +- compatible: Should be "virtio,pci-iommu" +- reg: PCI address of the IOMMU. As defined in the PCI Bus + Binding reference [1], the reg property is a five-cell + address encoded as (phys.hi phys.mid phys.lo size.hi + size.lo). phys.hi should contain the device's BDF as + 0b dfff . The other cells + should be zero. +- #iommu-cells:Each platform DMA master managed by the IOMMU is assigned + an endpoint ID, described by the "iommus" property [2]. + For virtio-iommu, #iommu-cells must be 1. + +Notes: + +- DMA from the IOMMU device isn't managed by another IOMMU. Therefore the + virtio-iommu node doesn't have an "iommus" property, and is omitted from + the iommu-map property of the root complex. + +Example: + +pcie@1000 { + compatible = "pci-host-ecam-generic"; + ... + + /* The IOMMU programming interface uses slot 00:01.0 */ + iommu0: iommu@0008 { + compatible = "virtio,pci-iommu"; + reg = <0x0800 0 0 0 0>; + #iommu-cells = <1>; + }; + + /* +* The IOMMU manages all functions in this PCI domain except +* itself. Omit BDF 00:01.0. +*/ + iommu-map = <0x0 0x0 0x8> + <0x9 0x9 0xfff7>; +}; + +pcie@2000 { + compatible = "pci-host-ecam-generic"; + ... + /* +* The IOMMU also manages all functions from this domain, +* with endpoint IDs 0x1 - 0x1 +*/ + iommu-map = <0x0 0x1 0x1>; +}; + +ethernet@fe001000 { + ... + /* The IOMMU manages this platform device with endpoint ID 0x2 */ + iommus = < 0x2>; +}; + +[1] Documentation/devicetree/bindings/pci/pci.txt +[2] Documentation/devicetree/bindings/iommu/iommu.txt -- 2.19.1 ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
Re: [RFC] avoid indirect calls for DMA direct mappings v2
On Tue, Dec 11, 2018 at 05:13:30PM +, Luck, Tony wrote: > > But that might not be your fault. My ancient system is getting flaky. A > > v4.19 build that > > has booted before is also resetting :-( > > After a power-cycle (and some time to let the machine cool off). System now > boots > with your patch series plus the __phys_to_pfn() #define > > So if you can figure the right way to fix that, you are good to go. > > Tested-by: Tony Luck Thanks. I'll just replace the __phys_to_pfn with PHYS_PFN for now, and see if I can find time to get the whole kernel to agree to one version of this macro eventually.. ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
RE: [RFC] avoid indirect calls for DMA direct mappings v2
> But that might not be your fault. My ancient system is getting flaky. A v4.19 > build that > has booted before is also resetting :-( After a power-cycle (and some time to let the machine cool off). System now boots with your patch series plus the __phys_to_pfn() #define So if you can figure the right way to fix that, you are good to go. Tested-by: Tony Luck ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
RE: [RFC] avoid indirect calls for DMA direct mappings v2
> This should fix it: ... > +#include Not quite. Still have an issue with __phys_to_pfn(paddr) Trying ti #include gave we a raft of redefined macros. So I just added #define __phys_to_pfn(paddr)PHYS_PFN(paddr) to arch/ia64/mm/init.c That made the build work. But boot spontaneously resets after: mptsas: ioc1: attaching ssp device: fw_channel 0, fw_id 6, phy 6, sas_addr 0x5000c5000ecada69 scsi 5:0:0:0: Direct-Access SEAGATE ST9146802SS 0003 PQ: 0 ANSI: 5 EFI Variables Facility v0.08 2004-May-17 sd 5:0:0:0: [sdb] 286749488 512-byte logical blocks: (147 GB/137 GiB) sd 5:0:0:0: [sdb] Write Protect is off sd 5:0:0:0: [sdb] Write cache: enabled, read cache: enabled, supports DPO and FUA sdb: sdb1 sdb2 sd 5:0:0:0: [sdb] Attached SCSI disk But that might not be your fault. My ancient system is getting flaky. A v4.19 build that has booted before is also resetting :-( -Tony ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
Re: [PATCH v5 5/7] iommu: Add virtio-iommu driver
On 10/12/2018 22:53, Michael S. Tsirkin wrote: > On Mon, Dec 10, 2018 at 03:06:47PM +, Jean-Philippe Brucker wrote: >> On 27/11/2018 18:53, Michael S. Tsirkin wrote: >>> On Tue, Nov 27, 2018 at 06:10:46PM +, Jean-Philippe Brucker wrote: On 27/11/2018 18:04, Michael S. Tsirkin wrote: > On Tue, Nov 27, 2018 at 05:50:50PM +, Jean-Philippe Brucker wrote: >> On 23/11/2018 22:02, Michael S. Tsirkin wrote: +/* + * __viommu_sync_req - Complete all in-flight requests + * + * Wait for all added requests to complete. When this function returns, all + * requests that were in-flight at the time of the call have completed. + */ +static int __viommu_sync_req(struct viommu_dev *viommu) +{ + int ret = 0; + unsigned int len; + size_t write_len; + struct viommu_request *req; + struct virtqueue *vq = viommu->vqs[VIOMMU_REQUEST_VQ]; + + assert_spin_locked(>request_lock); + + virtqueue_kick(vq); + + while (!list_empty(>requests)) { + len = 0; + req = virtqueue_get_buf(vq, ); + if (!req) + continue; + + if (!len) + viommu_set_req_status(req->buf, req->len, +VIRTIO_IOMMU_S_IOERR); + + write_len = req->len - req->write_offset; + if (req->writeback && len == write_len) + memcpy(req->writeback, req->buf + req->write_offset, + write_len); + + list_del(>list); + kfree(req); + } >>> >>> I didn't notice this in the past but it seems this will spin >>> with interrupts disabled until host handles the request. >>> Please do not do this - host execution can be another >>> task that needs the same host CPU. This will then disable >>> interrupts for a very very long time. >> >> In the guest yes, but that doesn't prevent the host from running another >> task right? > > Doesn't prevent it but it will delay it significantly > until scheduler decides to kick the VCPU task out. > >> My tests run fine when QEMU is bound to a single CPU, even >> though vcpu and viommu run in different threads >> >>> What to do then? Queue in software and wake up task. >> >> Unfortunately I can't do anything here, because IOMMU drivers can't >> sleep in the iommu_map() or iommu_unmap() path. >> >> The problem is the same >> for all IOMMU drivers. That's because the DMA API allows drivers to call >> some functions with interrupts disabled. For example >> Documentation/DMA-API-HOWTO.txt allows dma_alloc_coherent() and >> dma_unmap_single() to be called in interrupt context. > > In fact I don't really understand how it's supposed to > work at all: you only sync when ring is full. > So host may not have seen your map request if ring > is not full. > Why is it safe to use the address with a device then? viommu_map() calls viommu_send_req_sync(), which does the sync immediately after adding the MAP request. Thanks, Jean >>> >>> I see. So it happens on every request. Maybe you should clear >>> event index then. This way if exits are disabled you know that >>> host is processing the ring. Event index is good for when >>> you don't care when it will be processed, you just want >>> to reduce number of exits as much as possible. >>> >> >> I think that's already the case: since we don't attach a callback to the >> request queue, VRING_AVAIL_F_NO_INTERRUPT is set in avail_flags_shadow, >> which causes the used event index to stay clear. >> >> Thanks, >> Jean > > VRING_AVAIL_F_NO_INTERRUPT has no effect when the event index > feature has been negotiated. In any case, it also does not > affect kick notifications from guest - it affects > device interrupts. Ok, I thought we were talking about the used event. Then this is a device-side optimization right? In QEMU, disabling notifications while processing the queue didn't show any difference in netperf. Kvmtool already masks events when processing the ring - if the host is still handling requests while the guest adds more, then the avail event is at least one behind the new avail index, and the guest doesn't kick the host. Anyway I think we can look at optimizations later, since I don't think there is any trivial one that we can squash into the initial driver. I'll resend this series with the Kconfig and header change. Thanks, Jean ___ iommu mailing list
Re: [PATCH 1/6] driver core: Introduce device_iommu_mapped() function
On Tue, Dec 11, 2018 at 05:59:33PM +0300, Sergei Shtylyov wrote: > > +static inline bool device_iommu_mapped(struct device *dev) > > +{ > > + return (dev->iommu_group != NULL); > >You know that parens are unnecessary here, right? :-) Yes, I know, but it feels incomplete to me without them :-) Joerg ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
[PATCH 2/4] iommu: Consolitate ->add/remove_device() calls
From: Joerg Roedel Put them into separate functions and call those where the plain ops have been called before. Signed-off-by: Joerg Roedel --- drivers/iommu/iommu.c | 51 +-- include/linux/iommu.h | 3 +++ 2 files changed, 28 insertions(+), 26 deletions(-) diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c index edbdf5d6962c..1e8f4e0c9198 100644 --- a/drivers/iommu/iommu.c +++ b/drivers/iommu/iommu.c @@ -110,6 +110,23 @@ void iommu_device_unregister(struct iommu_device *iommu) spin_unlock(_device_lock); } +int iommu_probe_device(struct device *dev) +{ + const struct iommu_ops *ops = dev->bus->iommu_ops; + + WARN_ON(dev->iommu_group); + + return ops->add_device(dev); +} + +void iommu_release_device(struct device *dev) +{ + const struct iommu_ops *ops = dev->bus->iommu_ops; + + if (dev->iommu_group) + ops->remove_device(dev); +} + static struct iommu_domain *__iommu_domain_alloc(struct bus_type *bus, unsigned type); static int __iommu_attach_device(struct iommu_domain *domain, @@ -1117,16 +1134,7 @@ struct iommu_domain *iommu_group_default_domain(struct iommu_group *group) static int add_iommu_group(struct device *dev, void *data) { - struct iommu_callback_data *cb = data; - const struct iommu_ops *ops = cb->ops; - int ret; - - if (!ops->add_device) - return 0; - - WARN_ON(dev->iommu_group); - - ret = ops->add_device(dev); + int ret = iommu_probe_device(dev); /* * We ignore -ENODEV errors for now, as they just mean that the @@ -1141,11 +1149,7 @@ static int add_iommu_group(struct device *dev, void *data) static int remove_iommu_group(struct device *dev, void *data) { - struct iommu_callback_data *cb = data; - const struct iommu_ops *ops = cb->ops; - - if (ops->remove_device && dev->iommu_group) - ops->remove_device(dev); + iommu_release_device(dev); return 0; } @@ -1153,27 +1157,22 @@ static int remove_iommu_group(struct device *dev, void *data) static int iommu_bus_notifier(struct notifier_block *nb, unsigned long action, void *data) { + unsigned long group_action = 0; struct device *dev = data; - const struct iommu_ops *ops = dev->bus->iommu_ops; struct iommu_group *group; - unsigned long group_action = 0; /* * ADD/DEL call into iommu driver ops if provided, which may * result in ADD/DEL notifiers to group->notifier */ if (action == BUS_NOTIFY_ADD_DEVICE) { - if (ops->add_device) { - int ret; + int ret; - ret = ops->add_device(dev); - return (ret) ? NOTIFY_DONE : NOTIFY_OK; - } + ret = iommu_probe_device(dev); + return (ret) ? NOTIFY_DONE : NOTIFY_OK; } else if (action == BUS_NOTIFY_REMOVED_DEVICE) { - if (ops->remove_device && dev->iommu_group) { - ops->remove_device(dev); - return 0; - } + iommu_release_device(dev); + return NOTIFY_OK; } /* diff --git a/include/linux/iommu.h b/include/linux/iommu.h index a1d28f42cb77..cb36f32cd3c2 100644 --- a/include/linux/iommu.h +++ b/include/linux/iommu.h @@ -398,6 +398,9 @@ void iommu_fwspec_free(struct device *dev); int iommu_fwspec_add_ids(struct device *dev, u32 *ids, int num_ids); const struct iommu_ops *iommu_ops_from_fwnode(struct fwnode_handle *fwnode); +int iommu_probe_device(struct device *dev); +void iommu_release_device(struct device *dev); + #else /* CONFIG_IOMMU_API */ struct iommu_ops {}; -- 2.17.1 ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
[PATCH 3/4] iommu/of: Don't call iommu_ops->add_device directly
From: Joerg Roedel Make sure to invoke this call-back through the proper function of the IOMMU-API. Signed-off-by: Joerg Roedel --- drivers/iommu/of_iommu.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/iommu/of_iommu.c b/drivers/iommu/of_iommu.c index c5dd63072529..4d4847de727e 100644 --- a/drivers/iommu/of_iommu.c +++ b/drivers/iommu/of_iommu.c @@ -218,10 +218,10 @@ const struct iommu_ops *of_iommu_configure(struct device *dev, ops = dev->iommu_fwspec->ops; /* * If we have reason to believe the IOMMU driver missed the initial -* add_device callback for dev, replay it to get things in order. +* probe for dev, replay it to get things in order. */ - if (ops && ops->add_device && dev->bus && !dev->iommu_group) - err = ops->add_device(dev); + if (dev->bus && !dev->iommu_group) + err = iommu_probe_device(dev); /* Ignore all other errors apart from EPROBE_DEFER */ if (err == -EPROBE_DEFER) { -- 2.17.1 ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
[PATCH 1/4] iommu/sysfs: Rename iommu_release_device()
From: Joerg Roedel Remove the iommu_ prefix from the function and a few other static data structures so that the iommu_release_device name can be re-used in iommu core code. Signed-off-by: Joerg Roedel --- drivers/iommu/iommu-sysfs.c | 12 ++-- 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/iommu/iommu-sysfs.c b/drivers/iommu/iommu-sysfs.c index 36d1a7ce7fc4..71c2249d3260 100644 --- a/drivers/iommu/iommu-sysfs.c +++ b/drivers/iommu/iommu-sysfs.c @@ -22,25 +22,25 @@ static struct attribute *devices_attr[] = { NULL, }; -static const struct attribute_group iommu_devices_attr_group = { +static const struct attribute_group devices_attr_group = { .name = "devices", .attrs = devices_attr, }; -static const struct attribute_group *iommu_dev_groups[] = { - _devices_attr_group, +static const struct attribute_group *dev_groups[] = { + _attr_group, NULL, }; -static void iommu_release_device(struct device *dev) +static void release_device(struct device *dev) { kfree(dev); } static struct class iommu_class = { .name = "iommu", - .dev_release = iommu_release_device, - .dev_groups = iommu_dev_groups, + .dev_release = release_device, + .dev_groups = dev_groups, }; static int __init iommu_dev_init(void) -- 2.17.1 ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
[PATCH 4/4] ACPI/IORT: Don't call iommu_ops->add_device directly
From: Joerg Roedel Make sure to invoke this call-back through the proper function of the IOMMU-API. Signed-off-by: Joerg Roedel --- drivers/acpi/arm64/iort.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c index 70f4e80b9246..d4f7c1adc048 100644 --- a/drivers/acpi/arm64/iort.c +++ b/drivers/acpi/arm64/iort.c @@ -805,8 +805,8 @@ static inline int iort_add_device_replay(const struct iommu_ops *ops, { int err = 0; - if (ops->add_device && dev->bus && !dev->iommu_group) - err = ops->add_device(dev); + if (dev->bus && !dev->iommu_group) + err = iommu_probe_device(dev); return err; } -- 2.17.1 ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
[PATCH 0/4 v2] Consolidate iommu_ops->add/remove_device() calls
Hi, here is the second version of the patch-set to wrap the invocation of iommu_ops->add/remove_device() into functions. The functions will do more setup stuff later when the the iommu-related pointers in 'struct device' are consolidated. Since version one this patch-set was rebased to v4.20-rc6 and I removed the pointer checks for the function pointers, as suggested by Robin. I checked all 16 drivers and all of them implement the add/remove_device call-backs. Please review, if there are no objections I plan to queue these patches in the IOMMU tree. Thanks, Joerg Joerg Roedel (4): iommu/sysfs: Rename iommu_release_device() iommu: Consolitate ->add/remove_device() calls iommu/of: Don't call iommu_ops->add_device directly ACPI/IORT: Don't call iommu_ops->add_device directly drivers/acpi/arm64/iort.c | 4 +-- drivers/iommu/iommu-sysfs.c | 12 - drivers/iommu/iommu.c | 51 ++--- drivers/iommu/of_iommu.c| 6 ++--- include/linux/iommu.h | 3 +++ 5 files changed, 39 insertions(+), 37 deletions(-) -- 2.17.1 ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
Re: [PATCH 1/6] driver core: Introduce device_iommu_mapped() function
Hello! On 12/11/2018 04:43 PM, Joerg Roedel wrote: > From: Joerg Roedel > > Some places in the kernel check the iommu_group pointer in > 'struct device' in order to find ot whether a device is > mapped by an IOMMU. > > This is not good way to make this check, as the pointer will > be moved to 'struct dev_iommu_data'. This way to make the > check is also not very readable. > > Introduce an explicit function to perform this check. > > Cc: Greg Kroah-Hartman > Acked-by: Greg Kroah-Hartman > Acked-by: Robin Murphy > Signed-off-by: Joerg Roedel > --- > include/linux/device.h | 10 ++ > 1 file changed, 10 insertions(+) > > diff --git a/include/linux/device.h b/include/linux/device.h > index 1b25c7a43f4c..6cb4640b6160 100644 > --- a/include/linux/device.h > +++ b/include/linux/device.h > @@ -1058,6 +1058,16 @@ static inline struct device *kobj_to_dev(struct > kobject *kobj) > return container_of(kobj, struct device, kobj); > } > > +/** > + * device_iommu_mapped - Returns true when the device DMA is translated > + *by an IOMMU > + * @dev: Device to perform the check on > + */ > +static inline bool device_iommu_mapped(struct device *dev) > +{ > + return (dev->iommu_group != NULL); You know that parens are unnecessary here, right? :-) > +} > + > /* Get the wakeup routines, which depend on struct device */ > #include > MBR, Sergei ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
Re: use generic DMA mapping code in powerpc V4
Next step: 977706f9755d2d697aa6f45b4f9f0e07516efeda (powerpc/dma: remove dma_nommu_mmap_coherent) Result: The P5020 board boots and the PASEMI onboard ethernet works. -- Christian On 10 December 2018 at 4:54PM, Christian Zigotzky wrote: Next step: 64ecd2c160bbef31465c4d34efc0f076a2aad4df (powerpc/dma: use phys_to_dma instead of get_dma_offset) The P5020 board boots and the PASEMI onboard ethernet works. -- Christian On 09 December 2018 at 7:26PM, Christian Zigotzky wrote: Next step: c1bfcad4b0cf38ce5b00f7ad880d3a13484c123a (dma-mapping, powerpc: simplify the arch dma_set_mask override) Result: No problems with the PASEMI onboard ethernet and with booting the X5000 (P5020 board). -- Christian On 09 December 2018 at 3:20PM, Christian Zigotzky wrote: Next step: 602307b034734ce77a05da4b99333a2eaf6b6482 (powerpc/fsl_pci: simplify fsl_pci_dma_set_mask) git checkout 602307b034734ce77a05da4b99333a2eaf6b6482 The PASEMI onboard ethernet works and the X5000 boots. -- Christian On 08 December 2018 at 2:47PM, Christian Zigotzky wrote: Next step: e15cd8173ef85e9cc3e2a9c7cc2982f5c1355615 (powerpc/dma: fix an off-by-one in dma_capable) git checkout e15cd8173ef85e9cc3e2a9c7cc2982f5c1355615 The PASEMI onboard ethernet also works with this commit and the X5000 boots without any problems. -- Christian On 08 December 2018 at 11:29AM, Christian Zigotzky wrote: Next step: 7ebc44c535f6bd726d553756d38b137acc718443 (powerpc/dma: remove max_direct_dma_addr) git checkout 7ebc44c535f6bd726d553756d38b137acc718443 OK, the PASEMI onboard ethernet works and the P5020 board boots. -- Christian On 07 December 2018 at 7:33PM, Christian Zigotzky wrote: Next step: 13c1fdec5682b6e13257277fa16aa31f342d167d (powerpc/dma: move pci_dma_dev_setup_swiotlb to fsl_pci.c) git checkout 13c1fdec5682b6e13257277fa16aa31f342d167d Result: The PASEMI onboard ethernet works and the P5020 board boots. — Christian ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
Re: [PATCH 6/6] sparc: merge 32-bit and 64-bit version of pci.h
I've pulled this into the dma-mapping for-next tree now. ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
[PATCH 5/6] xhci: Use device_iommu_mapped()
From: Joerg Roedel Replace the dev->iommu_group check with a proper function call that better reprensents its purpose. Cc: Mathias Nyman Acked-by: Robin Murphy Signed-off-by: Joerg Roedel --- drivers/usb/host/xhci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index dae3be1b9c8f..8eacd2ed412b 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -244,7 +244,7 @@ static void xhci_zero_64b_regs(struct xhci_hcd *xhci) * an iommu. Doing anything when there is no iommu is definitely * unsafe... */ - if (!(xhci->quirks & XHCI_ZERO_64B_REGS) || !dev->iommu_group) + if (!(xhci->quirks & XHCI_ZERO_64B_REGS) || !device_iommu_mapped(dev)) return; xhci_info(xhci, "Zeroing 64bit base registers, expecting fault\n"); -- 2.17.1 ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
[PATCH 4/6] powerpc/iommu: Use device_iommu_mapped()
From: Joerg Roedel Use the new function to replace the open-coded iommu check. Cc: Benjamin Herrenschmidt Cc: Paul Mackerras Cc: Russell Currey Cc: Sam Bobroff Acked-by: Robin Murphy Signed-off-by: Joerg Roedel --- arch/powerpc/kernel/eeh.c | 2 +- arch/powerpc/kernel/iommu.c | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/arch/powerpc/kernel/eeh.c b/arch/powerpc/kernel/eeh.c index 6cae6b56ffd6..23fe62f11486 100644 --- a/arch/powerpc/kernel/eeh.c +++ b/arch/powerpc/kernel/eeh.c @@ -1472,7 +1472,7 @@ static int dev_has_iommu_table(struct device *dev, void *data) if (!dev) return 0; - if (dev->iommu_group) { + if (device_iommu_mapped(dev)) { *ppdev = pdev; return 1; } diff --git a/arch/powerpc/kernel/iommu.c b/arch/powerpc/kernel/iommu.c index f0dc680e659a..48d58d1dcac2 100644 --- a/arch/powerpc/kernel/iommu.c +++ b/arch/powerpc/kernel/iommu.c @@ -1086,7 +1086,7 @@ int iommu_add_device(struct device *dev) if (!device_is_registered(dev)) return -ENOENT; - if (dev->iommu_group) { + if (device_iommu_mapped(dev)) { pr_debug("%s: Skipping device %s with iommu group %d\n", __func__, dev_name(dev), iommu_group_id(dev->iommu_group)); @@ -1129,7 +1129,7 @@ void iommu_del_device(struct device *dev) * and we needn't detach them from the associated * IOMMU groups */ - if (!dev->iommu_group) { + if (!device_iommu_mapped(dev)) { pr_debug("iommu_tce: skipping device %s with no tbl\n", dev_name(dev)); return; @@ -1148,7 +1148,7 @@ static int tce_iommu_bus_notifier(struct notifier_block *nb, case BUS_NOTIFY_ADD_DEVICE: return iommu_add_device(dev); case BUS_NOTIFY_DEL_DEVICE: -if (dev->iommu_group) +if (device_iommu_mapped(dev)) iommu_del_device(dev); return 0; default: -- 2.17.1 ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
[PATCH 1/6] driver core: Introduce device_iommu_mapped() function
From: Joerg Roedel Some places in the kernel check the iommu_group pointer in 'struct device' in order to find ot whether a device is mapped by an IOMMU. This is not good way to make this check, as the pointer will be moved to 'struct dev_iommu_data'. This way to make the check is also not very readable. Introduce an explicit function to perform this check. Cc: Greg Kroah-Hartman Acked-by: Greg Kroah-Hartman Acked-by: Robin Murphy Signed-off-by: Joerg Roedel --- include/linux/device.h | 10 ++ 1 file changed, 10 insertions(+) diff --git a/include/linux/device.h b/include/linux/device.h index 1b25c7a43f4c..6cb4640b6160 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -1058,6 +1058,16 @@ static inline struct device *kobj_to_dev(struct kobject *kobj) return container_of(kobj, struct device, kobj); } +/** + * device_iommu_mapped - Returns true when the device DMA is translated + * by an IOMMU + * @dev: Device to perform the check on + */ +static inline bool device_iommu_mapped(struct device *dev) +{ + return (dev->iommu_group != NULL); +} + /* Get the wakeup routines, which depend on struct device */ #include -- 2.17.1 ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
[PATCH 2/6] iommu/of: Use device_iommu_mapped()
From: Joerg Roedel Use Use device_iommu_mapped() to check if the device is already mapped by an IOMMU. Acked-by: Robin Murphy Signed-off-by: Joerg Roedel --- drivers/iommu/of_iommu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/iommu/of_iommu.c b/drivers/iommu/of_iommu.c index c5dd63072529..bfcf139503f0 100644 --- a/drivers/iommu/of_iommu.c +++ b/drivers/iommu/of_iommu.c @@ -220,7 +220,7 @@ const struct iommu_ops *of_iommu_configure(struct device *dev, * If we have reason to believe the IOMMU driver missed the initial * add_device callback for dev, replay it to get things in order. */ - if (ops && ops->add_device && dev->bus && !dev->iommu_group) + if (ops && ops->add_device && dev->bus && !device_iommu_mapped(dev)) err = ops->add_device(dev); /* Ignore all other errors apart from EPROBE_DEFER */ -- 2.17.1 ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
Re: [PATCH v3 0/7] dma-debug cleanup and dynamic allocation
Thanks, applied to dma-mapping for-next. ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
[PATCH 3/6] ACPI/IORT: Use device_iommu_mapped()
From: Joerg Roedel Replace the iommu-check with a proper and readable function call. Cc: Lorenzo Pieralisi Acked-by: Robin Murphy Signed-off-by: Joerg Roedel --- drivers/acpi/arm64/iort.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c index 70f4e80b9246..0125c8eb9e81 100644 --- a/drivers/acpi/arm64/iort.c +++ b/drivers/acpi/arm64/iort.c @@ -805,7 +805,7 @@ static inline int iort_add_device_replay(const struct iommu_ops *ops, { int err = 0; - if (ops->add_device && dev->bus && !dev->iommu_group) + if (ops->add_device && dev->bus && !device_iommu_mapped(dev)) err = ops->add_device(dev); return err; -- 2.17.1 ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
[PATCH 0/6 v2] Introduce device_iommu_mapped() function
Hi, here is the second version of this patch-set. It replaces the various (dev->iommu_group) checks with a function call which better expresses their intend. Changes to the first version are the added patch for rcar-dmac, a driver I missed before. I also added all Acked-By's I received on the first version. Please review and provide Acks, if there are no objections. I have some iommu patches that depend on these, so I'd like to carry this patch-set in the IOMMU tree. Regards, Joerg Joerg Roedel (6): driver core: Introduce device_iommu_mapped() function iommu/of: Use device_iommu_mapped() ACPI/IORT: Use device_iommu_mapped() powerpc/iommu: Use device_iommu_mapped() xhci: Use device_iommu_mapped() dmaengine: sh: rcar-dmac: Use device_iommu_mapped() arch/powerpc/kernel/eeh.c | 2 +- arch/powerpc/kernel/iommu.c | 6 +++--- drivers/acpi/arm64/iort.c | 2 +- drivers/dma/sh/rcar-dmac.c | 2 +- drivers/iommu/of_iommu.c| 2 +- drivers/usb/host/xhci.c | 2 +- include/linux/device.h | 10 ++ 7 files changed, 18 insertions(+), 8 deletions(-) -- 2.17.1 ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
Re: [RFC PATCH 0/6] Auxiliary IOMMU domains and Arm SMMUv3
On 07/12/2018 10:29, 'j...@8bytes.org' wrote: > Hi, > > On Mon, Nov 26, 2018 at 07:29:45AM +, Tian, Kevin wrote: >> btw Baolu just reminded me one thing which is worthy of noting here. >> 'primary' vs. 'aux' concept makes sense only when we look from a device >> p.o.v. That binding relationship is not (*should not be*) carry-and-forwarded >> cross devices. every domain must be explicitly attached to other devices >> (instead of implicitly attached being above example), and new primary/aux >> attribute on another device will be decided at attach time. > > Okay, so after all the discussions we had I learned a few more things > about the scalable mode feature and thought a bit longer about how to > best support it in the IOMMU-API. > > The concept of sub-domains I initially proposed certainly makes no > sense, but scalable-mode specific attach/detach functions do. So instead > of a sub-domain mode, I'd like to propose device-feature sets. > > The posted patch-set already includes this as device-attributes, but I > don't like this naming as we are really talking about additional > feature sets of a device. So how about we introduce this: > > enum iommu_dev_features { > /* ... */ > IOMMU_DEV_FEAT_AUX, > IOMMU_DEV_FEAT_SVA, > /* ... */ > }; > > /* Check if a device supports a given feature of the IOMMU-API */ > bool iommu_dev_has_feature(struct device *dev, enum iommu_dev_features > *feat); > > /* >* Only works if iommu_dev_has_feature(dev, IOMMU_DEV_FEAT_AUX) >* returns true >* >* Also, as long as domains are attached to a device through >* this interface, any trys to call iommu_attach_device() should >* fail (iommu_detach_device() can't fail, so we fail on the >* tryint to re-attach). This should make us safe against a >* device being attached to a guest as a whole while there are >* still pasid users on it (aux and sva). >*/ > int iommu_aux_attach_device(struct iommu_domain *domain, > struct device *dev); > > int iommu_aux_detach_device(struct iommu_domain *domain, > struct device *dev); > /* >* I know we are targeting a system-wide pasid-space, so that >* the pasid would be the same for one domain on all devices, >* let's just keep the option open to have different >* pasid-spaces in one system. Also this way we can use it to >* check whether the domain is attached to this device at all. >* >* returns pasid or <0 if domain has no pasid on that device. >*/ > int iommu_aux_get_pasid(struct iommu_domain *domain, > struct device *dev);> > /* So we need a iommu_aux_detach_all()? */ This could be useful for device drivers that want to do bulk cleanup on device removal. If they rely on Function Level Reset to disable PASID states for example, they could also cleanup with a detach_all(). But most will probably need to clean up individual PASID states (for example free all mdevs) and therefore don't need detach_all() > This concept can also be easily extended for supporting SVA in parallel > on the same device, with the same constraints regarding the behavior of > iommu_attach_device()/iommu_detach_device(). So this would be without the initial step of attaching an "ext" domain to the device in order to enable SVA/PASID? If I understood it correctly, I agree with the iommu_attach/detach_device() behavior for SVA as well. If a device is bound to an mm, then the device cannot be attached to another domain with iommu_attach_device(). This prevents leaks and forces the device driver to clean up PASID states when switching to a different driver (e.g. vfio-pci) Thanks, Jean ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
[PATCH 9/9] iommu/tegra: Use helper functions to access dev->iommu_fwspec
From: Joerg Roedel Use the new helpers dev_iommu_fwspec_get()/set() to access the dev->iommu_fwspec pointer. This makes it easier to move that pointer later into another struct. Cc: Thierry Reding Signed-off-by: Joerg Roedel --- drivers/iommu/tegra-smmu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/iommu/tegra-smmu.c b/drivers/iommu/tegra-smmu.c index 0d03341317c4..0d026cb2dfff 100644 --- a/drivers/iommu/tegra-smmu.c +++ b/drivers/iommu/tegra-smmu.c @@ -846,7 +846,7 @@ static struct iommu_group *tegra_smmu_group_get(struct tegra_smmu *smmu, static struct iommu_group *tegra_smmu_device_group(struct device *dev) { - struct iommu_fwspec *fwspec = dev->iommu_fwspec; + struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev); struct tegra_smmu *smmu = dev->archdata.iommu; struct iommu_group *group; -- 2.17.1 ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
[PATCH 4/9] iommu/dma: Use helper functions to access dev->iommu_fwspec
From: Joerg Roedel Use the new helpers dev_iommu_fwspec_get()/set() to access the dev->iommu_fwspec pointer. This makes it easier to move that pointer later into another struct. Signed-off-by: Joerg Roedel --- drivers/iommu/dma-iommu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/iommu/dma-iommu.c b/drivers/iommu/dma-iommu.c index d1b04753b204..2b1c6912fbcc 100644 --- a/drivers/iommu/dma-iommu.c +++ b/drivers/iommu/dma-iommu.c @@ -177,7 +177,7 @@ EXPORT_SYMBOL(iommu_put_dma_cookie); void iommu_dma_get_resv_regions(struct device *dev, struct list_head *list) { - if (!is_of_node(dev->iommu_fwspec->iommu_fwnode)) + if (!is_of_node(dev_iommu_fwspec_get(dev)->iommu_fwnode)) iort_iommu_msi_get_resv_regions(dev, list); } -- 2.17.1 ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
[PATCH 2/9] ACPI/IORT: Use helper functions to access dev->iommu_fwspec
From: Joerg Roedel Use the new helpers dev_iommu_fwspec_get()/set() to access the dev->iommu_fwspec pointer. This makes it easier to move that pointer later into another struct. Cc: Lorenzo Pieralisi Signed-off-by: Joerg Roedel --- drivers/acpi/arm64/iort.c | 19 ++- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c index 70f4e80b9246..736381673638 100644 --- a/drivers/acpi/arm64/iort.c +++ b/drivers/acpi/arm64/iort.c @@ -779,7 +779,7 @@ static inline bool iort_iommu_driver_enabled(u8 type) static struct acpi_iort_node *iort_get_msi_resv_iommu(struct device *dev) { struct acpi_iort_node *iommu; - struct iommu_fwspec *fwspec = dev->iommu_fwspec; + struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev); iommu = iort_get_iort_node(fwspec->iommu_fwnode); @@ -794,9 +794,10 @@ static struct acpi_iort_node *iort_get_msi_resv_iommu(struct device *dev) return NULL; } -static inline const struct iommu_ops *iort_fwspec_iommu_ops( - struct iommu_fwspec *fwspec) +static inline const struct iommu_ops *iort_fwspec_iommu_ops(struct device *dev) { + struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev); + return (fwspec && fwspec->ops) ? fwspec->ops : NULL; } @@ -824,6 +825,7 @@ static inline int iort_add_device_replay(const struct iommu_ops *ops, */ int iort_iommu_msi_get_resv_regions(struct device *dev, struct list_head *head) { + struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev); struct acpi_iort_its_group *its; struct acpi_iort_node *iommu_node, *its_node = NULL; int i, resv = 0; @@ -841,9 +843,9 @@ int iort_iommu_msi_get_resv_regions(struct device *dev, struct list_head *head) * a given PCI or named component may map IDs to. */ - for (i = 0; i < dev->iommu_fwspec->num_ids; i++) { + for (i = 0; i < fwspec->num_ids; i++) { its_node = iort_node_map_id(iommu_node, - dev->iommu_fwspec->ids[i], + fwspec->ids[i], NULL, IORT_MSI_TYPE); if (its_node) break; @@ -874,8 +876,7 @@ int iort_iommu_msi_get_resv_regions(struct device *dev, struct list_head *head) return (resv == its->its_count) ? resv : -ENODEV; } #else -static inline const struct iommu_ops *iort_fwspec_iommu_ops( - struct iommu_fwspec *fwspec) +static inline const struct iommu_ops *iort_fwspec_iommu_ops(struct device *dev); { return NULL; } static inline int iort_add_device_replay(const struct iommu_ops *ops, struct device *dev) @@ -1045,7 +1046,7 @@ const struct iommu_ops *iort_iommu_configure(struct device *dev) * If we already translated the fwspec there * is nothing left to do, return the iommu_ops. */ - ops = iort_fwspec_iommu_ops(dev->iommu_fwspec); + ops = iort_fwspec_iommu_ops(dev); if (ops) return ops; @@ -1084,7 +1085,7 @@ const struct iommu_ops *iort_iommu_configure(struct device *dev) * add_device callback for dev, replay it to get things in order. */ if (!err) { - ops = iort_fwspec_iommu_ops(dev->iommu_fwspec); + ops = iort_fwspec_iommu_ops(dev); err = iort_add_device_replay(ops, dev); } -- 2.17.1 ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
[PATCH 5/9] iommu/ipmmu-vmsa: Use helper functions to access dev->iommu_fwspec
From: Joerg Roedel Use the new helpers dev_iommu_fwspec_get()/set() to access the dev->iommu_fwspec pointer. This makes it easier to move that pointer later into another struct. Signed-off-by: Joerg Roedel --- drivers/iommu/ipmmu-vmsa.c | 12 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/drivers/iommu/ipmmu-vmsa.c b/drivers/iommu/ipmmu-vmsa.c index ddf3a492e1d5..679f18bf0634 100644 --- a/drivers/iommu/ipmmu-vmsa.c +++ b/drivers/iommu/ipmmu-vmsa.c @@ -81,7 +81,9 @@ static struct ipmmu_vmsa_domain *to_vmsa_domain(struct iommu_domain *dom) static struct ipmmu_vmsa_device *to_ipmmu(struct device *dev) { - return dev->iommu_fwspec ? dev->iommu_fwspec->iommu_priv : NULL; + struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev); + + return fwspec ? fwspec->iommu_priv : NULL; } #define TLB_LOOP_TIMEOUT 100 /* 100us */ @@ -643,7 +645,7 @@ static void ipmmu_domain_free(struct iommu_domain *io_domain) static int ipmmu_attach_device(struct iommu_domain *io_domain, struct device *dev) { - struct iommu_fwspec *fwspec = dev->iommu_fwspec; + struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev); struct ipmmu_vmsa_device *mmu = to_ipmmu(dev); struct ipmmu_vmsa_domain *domain = to_vmsa_domain(io_domain); unsigned int i; @@ -692,7 +694,7 @@ static int ipmmu_attach_device(struct iommu_domain *io_domain, static void ipmmu_detach_device(struct iommu_domain *io_domain, struct device *dev) { - struct iommu_fwspec *fwspec = dev->iommu_fwspec; + struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev); struct ipmmu_vmsa_domain *domain = to_vmsa_domain(io_domain); unsigned int i; @@ -744,13 +746,15 @@ static phys_addr_t ipmmu_iova_to_phys(struct iommu_domain *io_domain, static int ipmmu_init_platform_device(struct device *dev, struct of_phandle_args *args) { + struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev); struct platform_device *ipmmu_pdev; ipmmu_pdev = of_find_device_by_node(args->np); if (!ipmmu_pdev) return -ENODEV; - dev->iommu_fwspec->iommu_priv = platform_get_drvdata(ipmmu_pdev); + fwspec->iommu_priv = platform_get_drvdata(ipmmu_pdev); + return 0; } -- 2.17.1 ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
[PATCH 0/9 v2] Access dev->iommu_fwspec through functions
Hi, here is the second patch-set to wrap accesses to dev->iommu_fwspec into functions so that the pointer location can be changed more easily later on. This version is rebased to v4.20-rc6 and addresses Robin's comments. The Ack from will is also added. If there are no objections I'd like to queue these patches soon. Regards, Joerg Joerg Roedel (9): iommu: Introduce wrappers around dev->iommu_fwspec ACPI/IORT: Use helper functions to access dev->iommu_fwspec iommu/arm-smmu: Use helper functions to access dev->iommu_fwspec iommu/dma: Use helper functions to access dev->iommu_fwspec iommu/ipmmu-vmsa: Use helper functions to access dev->iommu_fwspec iommu/mediatek: Use helper functions to access dev->iommu_fwspec iommu/of: Use helper functions to access dev->iommu_fwspec iommu/qcom: Use helper functions to access dev->iommu_fwspec iommu/tegra: Use helper functions to access dev->iommu_fwspec drivers/acpi/arm64/iort.c| 19 ++- drivers/iommu/arm-smmu-v3.c | 16 +--- drivers/iommu/arm-smmu.c | 12 ++-- drivers/iommu/dma-iommu.c| 2 +- drivers/iommu/iommu.c| 14 +++--- drivers/iommu/ipmmu-vmsa.c | 12 drivers/iommu/mtk_iommu.c| 21 - drivers/iommu/mtk_iommu_v1.c | 28 drivers/iommu/of_iommu.c | 10 +++--- drivers/iommu/qcom_iommu.c | 18 ++ drivers/iommu/tegra-smmu.c | 2 +- include/linux/iommu.h| 11 +++ 12 files changed, 98 insertions(+), 67 deletions(-) -- 2.17.1 ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
[PATCH 6/9] iommu/mediatek: Use helper functions to access dev->iommu_fwspec
From: Joerg Roedel Use the new helpers dev_iommu_fwspec_get()/set() to access the dev->iommu_fwspec pointer. This makes it easier to move that pointer later into another struct. Cc: Matthias Brugger Signed-off-by: Joerg Roedel --- drivers/iommu/mtk_iommu.c| 21 - drivers/iommu/mtk_iommu_v1.c | 28 2 files changed, 28 insertions(+), 21 deletions(-) diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c index 44bd5b9166bb..0783fba05d19 100644 --- a/drivers/iommu/mtk_iommu.c +++ b/drivers/iommu/mtk_iommu.c @@ -244,7 +244,7 @@ static void mtk_iommu_config(struct mtk_iommu_data *data, { struct mtk_smi_larb_iommu*larb_mmu; unsigned int larbid, portid; - struct iommu_fwspec *fwspec = dev->iommu_fwspec; + struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev); int i; for (i = 0; i < fwspec->num_ids; ++i) { @@ -336,7 +336,7 @@ static int mtk_iommu_attach_device(struct iommu_domain *domain, struct device *dev) { struct mtk_iommu_domain *dom = to_mtk_domain(domain); - struct mtk_iommu_data *data = dev->iommu_fwspec->iommu_priv; + struct mtk_iommu_data *data = dev_iommu_fwspec_get(dev)->iommu_priv; if (!data) return -ENODEV; @@ -355,7 +355,7 @@ static int mtk_iommu_attach_device(struct iommu_domain *domain, static void mtk_iommu_detach_device(struct iommu_domain *domain, struct device *dev) { - struct mtk_iommu_data *data = dev->iommu_fwspec->iommu_priv; + struct mtk_iommu_data *data = dev_iommu_fwspec_get(dev)->iommu_priv; if (!data) return; @@ -417,13 +417,14 @@ static phys_addr_t mtk_iommu_iova_to_phys(struct iommu_domain *domain, static int mtk_iommu_add_device(struct device *dev) { + struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev); struct mtk_iommu_data *data; struct iommu_group *group; - if (!dev->iommu_fwspec || dev->iommu_fwspec->ops != _iommu_ops) + if (!fwspec || fwspec->ops != _iommu_ops) return -ENODEV; /* Not a iommu client device */ - data = dev->iommu_fwspec->iommu_priv; + data = fwspec->iommu_priv; iommu_device_link(>iommu, dev); group = iommu_group_get_for_dev(dev); @@ -436,12 +437,13 @@ static int mtk_iommu_add_device(struct device *dev) static void mtk_iommu_remove_device(struct device *dev) { + struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev); struct mtk_iommu_data *data; - if (!dev->iommu_fwspec || dev->iommu_fwspec->ops != _iommu_ops) + if (!fwspec || fwspec->ops != _iommu_ops) return; - data = dev->iommu_fwspec->iommu_priv; + data = fwspec->iommu_priv; iommu_device_unlink(>iommu, dev); iommu_group_remove_device(dev); @@ -468,6 +470,7 @@ static struct iommu_group *mtk_iommu_device_group(struct device *dev) static int mtk_iommu_of_xlate(struct device *dev, struct of_phandle_args *args) { + struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev); struct platform_device *m4updev; if (args->args_count != 1) { @@ -476,13 +479,13 @@ static int mtk_iommu_of_xlate(struct device *dev, struct of_phandle_args *args) return -EINVAL; } - if (!dev->iommu_fwspec->iommu_priv) { + if (!fwspec->iommu_priv) { /* Get the m4u device */ m4updev = of_find_device_by_node(args->np); if (WARN_ON(!m4updev)) return -EINVAL; - dev->iommu_fwspec->iommu_priv = platform_get_drvdata(m4updev); + fwspec->iommu_priv = platform_get_drvdata(m4updev); } return iommu_fwspec_add_ids(dev, args->args, 1); diff --git a/drivers/iommu/mtk_iommu_v1.c b/drivers/iommu/mtk_iommu_v1.c index 0e780848f59b..d22a2a145bd2 100644 --- a/drivers/iommu/mtk_iommu_v1.c +++ b/drivers/iommu/mtk_iommu_v1.c @@ -206,7 +206,7 @@ static void mtk_iommu_config(struct mtk_iommu_data *data, { struct mtk_smi_larb_iommu*larb_mmu; unsigned int larbid, portid; - struct iommu_fwspec *fwspec = dev->iommu_fwspec; + struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev); int i; for (i = 0; i < fwspec->num_ids; ++i) { @@ -271,7 +271,7 @@ static int mtk_iommu_attach_device(struct iommu_domain *domain, struct device *dev) { struct mtk_iommu_domain *dom = to_mtk_domain(domain); - struct mtk_iommu_data *data = dev->iommu_fwspec->iommu_priv; + struct mtk_iommu_data *data = dev_iommu_fwspec_get(dev)->iommu_priv; int ret; if (!data) @@ -293,7 +293,7 @@ static int mtk_iommu_attach_device(struct iommu_domain *domain, static void mtk_iommu_detach_device(struct iommu_domain *domain,
[PATCH 1/9] iommu: Introduce wrappers around dev->iommu_fwspec
From: Joerg Roedel These wrappers will be used to easily change the location of the field later when all users are converted. Signed-off-by: Joerg Roedel --- drivers/iommu/iommu.c | 14 +++--- include/linux/iommu.h | 11 +++ 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c index edbdf5d6962c..4cfd407b972c 100644 --- a/drivers/iommu/iommu.c +++ b/drivers/iommu/iommu.c @@ -1976,7 +1976,7 @@ const struct iommu_ops *iommu_ops_from_fwnode(struct fwnode_handle *fwnode) int iommu_fwspec_init(struct device *dev, struct fwnode_handle *iommu_fwnode, const struct iommu_ops *ops) { - struct iommu_fwspec *fwspec = dev->iommu_fwspec; + struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev); if (fwspec) return ops == fwspec->ops ? 0 : -EINVAL; @@ -1988,26 +1988,26 @@ int iommu_fwspec_init(struct device *dev, struct fwnode_handle *iommu_fwnode, of_node_get(to_of_node(iommu_fwnode)); fwspec->iommu_fwnode = iommu_fwnode; fwspec->ops = ops; - dev->iommu_fwspec = fwspec; + dev_iommu_fwspec_set(dev, fwspec); return 0; } EXPORT_SYMBOL_GPL(iommu_fwspec_init); void iommu_fwspec_free(struct device *dev) { - struct iommu_fwspec *fwspec = dev->iommu_fwspec; + struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev); if (fwspec) { fwnode_handle_put(fwspec->iommu_fwnode); kfree(fwspec); - dev->iommu_fwspec = NULL; + dev_iommu_fwspec_set(dev, NULL); } } EXPORT_SYMBOL_GPL(iommu_fwspec_free); int iommu_fwspec_add_ids(struct device *dev, u32 *ids, int num_ids) { - struct iommu_fwspec *fwspec = dev->iommu_fwspec; + struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev); size_t size; int i; @@ -2016,11 +2016,11 @@ int iommu_fwspec_add_ids(struct device *dev, u32 *ids, int num_ids) size = offsetof(struct iommu_fwspec, ids[fwspec->num_ids + num_ids]); if (size > sizeof(*fwspec)) { - fwspec = krealloc(dev->iommu_fwspec, size, GFP_KERNEL); + fwspec = krealloc(fwspec, size, GFP_KERNEL); if (!fwspec) return -ENOMEM; - dev->iommu_fwspec = fwspec; + dev_iommu_fwspec_set(dev, fwspec); } for (i = 0; i < num_ids; i++) diff --git a/include/linux/iommu.h b/include/linux/iommu.h index a1d28f42cb77..f93fdcf7d130 100644 --- a/include/linux/iommu.h +++ b/include/linux/iommu.h @@ -398,6 +398,17 @@ void iommu_fwspec_free(struct device *dev); int iommu_fwspec_add_ids(struct device *dev, u32 *ids, int num_ids); const struct iommu_ops *iommu_ops_from_fwnode(struct fwnode_handle *fwnode); +static inline struct iommu_fwspec *dev_iommu_fwspec_get(struct device *dev) +{ + return dev->iommu_fwspec; +} + +static inline void dev_iommu_fwspec_set(struct device *dev, + struct iommu_fwspec *fwspec) +{ + dev->iommu_fwspec = fwspec; +} + #else /* CONFIG_IOMMU_API */ struct iommu_ops {}; -- 2.17.1 ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
[PATCH 3/9] iommu/arm-smmu: Use helper functions to access dev->iommu_fwspec
From: Joerg Roedel Use the new helpers dev_iommu_fwspec_get()/set() to access the dev->iommu_fwspec pointer. This makes it easier to move that pointer later into another struct. Cc: Will Deacon Cc: Robin Murphy Acked-by: Will Deacon Signed-off-by: Joerg Roedel --- drivers/iommu/arm-smmu-v3.c | 16 +--- drivers/iommu/arm-smmu.c| 12 ++-- 2 files changed, 15 insertions(+), 13 deletions(-) diff --git a/drivers/iommu/arm-smmu-v3.c b/drivers/iommu/arm-smmu-v3.c index 6947ccf26512..8f2d3a30d090 100644 --- a/drivers/iommu/arm-smmu-v3.c +++ b/drivers/iommu/arm-smmu-v3.c @@ -1691,24 +1691,26 @@ static void arm_smmu_install_ste_for_dev(struct iommu_fwspec *fwspec) static void arm_smmu_detach_dev(struct device *dev) { - struct arm_smmu_master_data *master = dev->iommu_fwspec->iommu_priv; + struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev); + struct arm_smmu_master_data *master = fwspec->iommu_priv; master->ste.assigned = false; - arm_smmu_install_ste_for_dev(dev->iommu_fwspec); + arm_smmu_install_ste_for_dev(fwspec); } static int arm_smmu_attach_dev(struct iommu_domain *domain, struct device *dev) { int ret = 0; + struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev); struct arm_smmu_device *smmu; struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain); struct arm_smmu_master_data *master; struct arm_smmu_strtab_ent *ste; - if (!dev->iommu_fwspec) + if (!fwspec) return -ENOENT; - master = dev->iommu_fwspec->iommu_priv; + master = fwspec->iommu_priv; smmu = master->smmu; ste = >ste; @@ -1748,7 +1750,7 @@ static int arm_smmu_attach_dev(struct iommu_domain *domain, struct device *dev) ste->s2_cfg = _domain->s2_cfg; } - arm_smmu_install_ste_for_dev(dev->iommu_fwspec); + arm_smmu_install_ste_for_dev(fwspec); out_unlock: mutex_unlock(_domain->init_mutex); return ret; @@ -1839,7 +1841,7 @@ static int arm_smmu_add_device(struct device *dev) int i, ret; struct arm_smmu_device *smmu; struct arm_smmu_master_data *master; - struct iommu_fwspec *fwspec = dev->iommu_fwspec; + struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev); struct iommu_group *group; if (!fwspec || fwspec->ops != _smmu_ops) @@ -1890,7 +1892,7 @@ static int arm_smmu_add_device(struct device *dev) static void arm_smmu_remove_device(struct device *dev) { - struct iommu_fwspec *fwspec = dev->iommu_fwspec; + struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev); struct arm_smmu_master_data *master; struct arm_smmu_device *smmu; diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c index 5a28ae892504..988d0362cd03 100644 --- a/drivers/iommu/arm-smmu.c +++ b/drivers/iommu/arm-smmu.c @@ -1103,7 +1103,7 @@ static bool arm_smmu_free_sme(struct arm_smmu_device *smmu, int idx) static int arm_smmu_master_alloc_smes(struct device *dev) { - struct iommu_fwspec *fwspec = dev->iommu_fwspec; + struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev); struct arm_smmu_master_cfg *cfg = fwspec->iommu_priv; struct arm_smmu_device *smmu = cfg->smmu; struct arm_smmu_smr *smrs = smmu->smrs; @@ -1206,7 +1206,7 @@ static int arm_smmu_domain_add_master(struct arm_smmu_domain *smmu_domain, static int arm_smmu_attach_dev(struct iommu_domain *domain, struct device *dev) { int ret; - struct iommu_fwspec *fwspec = dev->iommu_fwspec; + struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev); struct arm_smmu_device *smmu; struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain); @@ -1380,7 +1380,7 @@ static int arm_smmu_add_device(struct device *dev) { struct arm_smmu_device *smmu; struct arm_smmu_master_cfg *cfg; - struct iommu_fwspec *fwspec = dev->iommu_fwspec; + struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev); int i, ret; if (using_legacy_binding) { @@ -1391,7 +1391,7 @@ static int arm_smmu_add_device(struct device *dev) * will allocate/initialise a new one. Thus we need to update fwspec for * later use. */ - fwspec = dev->iommu_fwspec; + fwspec = dev_iommu_fwspec_get(dev); if (ret) goto out_free; } else if (fwspec && fwspec->ops == _smmu_ops) { @@ -1445,7 +1445,7 @@ static int arm_smmu_add_device(struct device *dev) static void arm_smmu_remove_device(struct device *dev) { - struct iommu_fwspec *fwspec = dev->iommu_fwspec; + struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev); struct arm_smmu_master_cfg *cfg; struct arm_smmu_device *smmu; @@ -1465,7 +1465,7 @@ static void arm_smmu_remove_device(struct device *dev) static struct
[PATCH 7/9] iommu/of: Use helper functions to access dev->iommu_fwspec
From: Joerg Roedel Use the new helpers dev_iommu_fwspec_get()/set() to access the dev->iommu_fwspec pointer. This makes it easier to move that pointer later into another struct. Signed-off-by: Joerg Roedel --- drivers/iommu/of_iommu.c | 10 +++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/drivers/iommu/of_iommu.c b/drivers/iommu/of_iommu.c index c5dd63072529..8b071f3dcf9e 100644 --- a/drivers/iommu/of_iommu.c +++ b/drivers/iommu/of_iommu.c @@ -164,7 +164,7 @@ const struct iommu_ops *of_iommu_configure(struct device *dev, struct device_node *master_np) { const struct iommu_ops *ops = NULL; - struct iommu_fwspec *fwspec = dev->iommu_fwspec; + struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev); int err = NO_IOMMU; if (!master_np) @@ -208,14 +208,18 @@ const struct iommu_ops *of_iommu_configure(struct device *dev, } } + /* * Two success conditions can be represented by non-negative err here: * >0 : there is no IOMMU, or one was unavailable for non-fatal reasons * 0 : we found an IOMMU, and dev->fwspec is initialised appropriately * <0 : any actual error */ - if (!err) - ops = dev->iommu_fwspec->ops; + if (!err) { + /* The fwspec pointer changed, read it again */ + fwspec = dev_iommu_fwspec_get(dev); + ops= fwspec->ops; + } /* * If we have reason to believe the IOMMU driver missed the initial * add_device callback for dev, replay it to get things in order. -- 2.17.1 ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
Re: [PATCH] dma-debug: fix soft lockup when a lot of debug are enabled
Hi Anders, On 11/12/2018 10:36, Anders Roxell wrote: When running a kernel in qemu with enough debugging options (slub-debug, ftrace, kcov, kasan, ubsan, ...) enabled together, that results in a slow initcall. So a 'watchdog: BUG: soft lockup' happens: [ 44.105619] Call trace: [ 44.106709] __slab_alloc+0x70/0x88 [ 44.107757] kmem_cache_alloc_trace+0x13c/0x590 [ 44.108764] prealloc_memory+0xb8/0x240 [ 44.109768] dma_debug_init+0x174/0x1f0 [ 44.110725] do_one_initcall+0x430/0x8b0 [ 44.111719] do_initcall_level+0x548/0x5b4 [ 44.112672] do_initcalls+0x28/0x4c [ 44.113628] do_basic_setup+0x34/0x3c [ 44.114559] kernel_init_freeable+0x194/0x24c [ 44.115570] kernel_init+0x24/0x18c [ 44.116498] ret_from_fork+0x10/0x18 Rework to call cond_resched(), in the function prealloc_memory()'s for-loop. Funnily enough I've just done a bit of work in this area which should make allocation a lot more efficient - would you mind giving this series a spin on the same setup to see how much it helps the performance? https://lore.kernel.org/lkml/cover.157601.git.robin.mur...@arm.com/ Thanks, Robin. Signed-off-by: Anders Roxell --- kernel/dma/debug.c | 1 + 1 file changed, 1 insertion(+) diff --git a/kernel/dma/debug.c b/kernel/dma/debug.c index 231ca4628062..2abdc265aec4 100644 --- a/kernel/dma/debug.c +++ b/kernel/dma/debug.c @@ -767,6 +767,7 @@ static int prealloc_memory(u32 num_entries) int i; for (i = 0; i < num_entries; ++i) { + cond_resched(); entry = kzalloc(sizeof(*entry), GFP_KERNEL); if (!entry) goto out_err; ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
[PATCH] dma-debug: fix soft lockup when a lot of debug are enabled
When running a kernel in qemu with enough debugging options (slub-debug, ftrace, kcov, kasan, ubsan, ...) enabled together, that results in a slow initcall. So a 'watchdog: BUG: soft lockup' happens: [ 44.105619] Call trace: [ 44.106709] __slab_alloc+0x70/0x88 [ 44.107757] kmem_cache_alloc_trace+0x13c/0x590 [ 44.108764] prealloc_memory+0xb8/0x240 [ 44.109768] dma_debug_init+0x174/0x1f0 [ 44.110725] do_one_initcall+0x430/0x8b0 [ 44.111719] do_initcall_level+0x548/0x5b4 [ 44.112672] do_initcalls+0x28/0x4c [ 44.113628] do_basic_setup+0x34/0x3c [ 44.114559] kernel_init_freeable+0x194/0x24c [ 44.115570] kernel_init+0x24/0x18c [ 44.116498] ret_from_fork+0x10/0x18 Rework to call cond_resched(), in the function prealloc_memory()'s for-loop. Signed-off-by: Anders Roxell --- kernel/dma/debug.c | 1 + 1 file changed, 1 insertion(+) diff --git a/kernel/dma/debug.c b/kernel/dma/debug.c index 231ca4628062..2abdc265aec4 100644 --- a/kernel/dma/debug.c +++ b/kernel/dma/debug.c @@ -767,6 +767,7 @@ static int prealloc_memory(u32 num_entries) int i; for (i = 0; i < num_entries; ++i) { + cond_resched(); entry = kzalloc(sizeof(*entry), GFP_KERNEL); if (!entry) goto out_err; -- 2.19.2 ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
Re: [PATCH 2/2] ACPI / scan: Refactor _CCA enforcement
On Fri, Dec 7, 2018 at 5:31 PM Robin Murphy wrote: > > Rather than checking the DMA attribute at each callsite, just pass it > through for acpi_dma_configure() to handle directly. That can then deal > with the relatively exceptional DEV_DMA_NOT_SUPPORTED case by explicitly > installing dummy DMA ops instead of just skipping setup entirely. This > will then free up the dev->dma_ops == NULL case for some valuable > fastpath optimisations. > > CC: Rafael J. Wysocki > CC: Len Brown > CC: Greg Kroah-Hartman > CC: Bjorn Helgaas > Signed-off-by: Robin Murphy The changes in this patch are fine by me: Reviewed-by: Rafael J. Wysocki > --- > drivers/acpi/scan.c | 5 + > drivers/base/platform.c | 3 +-- > drivers/pci/pci-driver.c | 3 +-- > 3 files changed, 7 insertions(+), 4 deletions(-) > > diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c > index bd1c59fb0e17..b75ae34ed188 100644 > --- a/drivers/acpi/scan.c > +++ b/drivers/acpi/scan.c > @@ -1456,6 +1456,11 @@ int acpi_dma_configure(struct device *dev, enum > dev_dma_attr attr) > const struct iommu_ops *iommu; > u64 dma_addr = 0, size = 0; > > + if (attr == DEV_DMA_NOT_SUPPORTED) { > + set_dma_ops(dev, _dummy_ops); > + return 0; > + } > + > iort_dma_setup(dev, _addr, ); > > iommu = iort_iommu_configure(dev); > diff --git a/drivers/base/platform.c b/drivers/base/platform.c > index 41b91af95afb..c6daca875c17 100644 > --- a/drivers/base/platform.c > +++ b/drivers/base/platform.c > @@ -1138,8 +1138,7 @@ int platform_dma_configure(struct device *dev) > ret = of_dma_configure(dev, dev->of_node, true); > } else if (has_acpi_companion(dev)) { > attr = acpi_get_dma_attr(to_acpi_device_node(dev->fwnode)); > - if (attr != DEV_DMA_NOT_SUPPORTED) > - ret = acpi_dma_configure(dev, attr); > + ret = acpi_dma_configure(dev, attr); > } > > return ret; > diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c > index bef17c3fca67..f899a28b90f8 100644 > --- a/drivers/pci/pci-driver.c > +++ b/drivers/pci/pci-driver.c > @@ -1602,8 +1602,7 @@ static int pci_dma_configure(struct device *dev) > struct acpi_device *adev = > to_acpi_device_node(bridge->fwnode); > enum dev_dma_attr attr = acpi_get_dma_attr(adev); > > - if (attr != DEV_DMA_NOT_SUPPORTED) > - ret = acpi_dma_configure(dev, attr); > + ret = acpi_dma_configure(dev, attr); > } > > pci_put_host_bridge_device(bridge); > -- > 2.19.1.dirty > ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
Re: [PATCH v4 00/18] MT8183 IOMMU SUPPORT
On Sat, Dec 08, 2018 at 04:39:13PM +0800, Yong Wu wrote: > Arvind Yadav (1): > iommu/mediatek: Constify iommu_ops > > Yong Wu (17): > dt-bindings: mediatek: Add binding for mt8183 IOMMU and SMI > iommu/mediatek: Use a struct as the platform data > memory: mtk-smi: Use a general config_port interface > memory: mtk-smi: Use a struct for the platform data for smi-common > iommu/io-pgtable-arm-v7s: Add paddr_to_iopte and iopte_to_paddr > helpers > iommu/io-pgtable-arm-v7s: Extend MediaTek 4GB Mode > iommu/mediatek: Add bclk can be supported optionally > iommu/mediatek: Add larb-id remapped support > memory: mtk-smi: Add gals support > iommu/mediatek: Add mt8183 IOMMU support > iommu/mediatek: Add mmu1 support > memory: mtk-smi: Invoke pm runtime_callback to enable clocks > memory: mtk-smi: Add bus_sel for mt8183 > iommu/mediatek: Fix VLD_PA_RANGE register backup when suspend > iommu/mediatek: Add shutdown callback > memory: mtk-smi: Get rid of need_larbid > iommu/mediatek: Switch to SPDX license identifier If Matthias is okay with these patches, I'll queue them for v4.21. Regards, Joerg ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
Re: [PATCH v6 00/12] iommu/vt-d: Add scalable mode support
On Mon, Dec 10, 2018 at 09:58:54AM +0800, Lu Baolu wrote: > Lu Baolu (12): > iommu/vt-d: Enumerate the scalable mode capability > iommu/vt-d: Manage scalalble mode PASID tables > iommu/vt-d: Move page table helpers into header > iommu/vt-d: Add 256-bit invalidation descriptor support > iommu/vt-d: Reserve a domain id for FL and PT modes > iommu/vt-d: Add second level page table interface > iommu/vt-d: Setup pasid entry for RID2PASID support > iommu/vt-d: Pass pasid table to context mapping > iommu/vt-d: Setup context and enable RID2PASID support > iommu/vt-d: Add first level page table interface > iommu/vt-d: Shared virtual address in scalable mode > iommu/vt-d: Remove deferred invalidation Applied, thanks. ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu