Re: [PATCH v15 06/12] swiotlb: Use is_swiotlb_force_bounce for swiotlb data bouncing
On Tue, Jul 06, 2021 at 06:48:48AM +0200, Christoph Hellwig wrote: > On Mon, Jul 05, 2021 at 08:03:52PM +0100, Will Deacon wrote: > > So at this point, the AMD IOMMU driver does: > > > > swiotlb= (iommu_default_passthrough() || sme_me_mask) ? 1 : 0; > > > > where 'swiotlb' is a global variable indicating whether or not swiotlb > > is in use. It's picked up a bit later on by pci_swiotlb_late_init(), which > > will call swiotlb_exit() if 'swiotlb' is false. > > > > Now, that used to work fine, because swiotlb_exit() clears > > 'io_tlb_default_mem' to NULL, but now with the restricted DMA changes, I > > think that all the devices which have successfully probed beforehand will > > have stale pointers to the freed structure in their 'dev->dma_io_tlb_mem' > > field. > > Yeah. I don't think we can do that anymore, and I also think it is > a bad idea to start with. I've had a crack at reworking things along the following lines: - io_tlb_default_mem now lives in the BSS, the flexible array member is now a pointer and that part is allocated dynamically (downside of this is an extra indirection to get at the slots). - io_tlb_default_mem.nslabs tells you whether the thing is valid - swiotlb_exit() frees the slots array and clears the rest of the structure to 0. I also extended it to free the actual slabs, but I'm not sure why it wasn't doing that before. So a non-NULL dev->dma_io_tlb_mem should always be valid to follow. Untested diff below... Nathan, it would be ace if you're brave enough to give this a shot. Will --->8 diff --git a/drivers/base/core.c b/drivers/base/core.c index bbad7c559901..9e1218f89e4b 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -2820,7 +2820,7 @@ void device_initialize(struct device *dev) dev->dma_coherent = dma_default_coherent; #endif #ifdef CONFIG_SWIOTLB - dev->dma_io_tlb_mem = io_tlb_default_mem; + dev->dma_io_tlb_mem = &io_tlb_default_mem; #endif } EXPORT_SYMBOL_GPL(device_initialize); diff --git a/drivers/xen/swiotlb-xen.c b/drivers/xen/swiotlb-xen.c index 785ec7e8be01..f06d9b4f1e0f 100644 --- a/drivers/xen/swiotlb-xen.c +++ b/drivers/xen/swiotlb-xen.c @@ -164,7 +164,7 @@ int __ref xen_swiotlb_init(void) int rc = -ENOMEM; char *start; - if (io_tlb_default_mem != NULL) { + if (io_tlb_default_mem.nslabs) { pr_warn("swiotlb buffer already initialized\n"); return -EEXIST; } @@ -547,7 +547,7 @@ xen_swiotlb_sync_sg_for_device(struct device *dev, struct scatterlist *sgl, static int xen_swiotlb_dma_supported(struct device *hwdev, u64 mask) { - return xen_phys_to_dma(hwdev, io_tlb_default_mem->end - 1) <= mask; + return xen_phys_to_dma(hwdev, io_tlb_default_mem.end - 1) <= mask; } const struct dma_map_ops xen_swiotlb_dma_ops = { diff --git a/include/linux/swiotlb.h b/include/linux/swiotlb.h index 39284ff2a6cd..b0cb2a9973f4 100644 --- a/include/linux/swiotlb.h +++ b/include/linux/swiotlb.h @@ -103,9 +103,9 @@ struct io_tlb_mem { phys_addr_t orig_addr; size_t alloc_size; unsigned int list; - } slots[]; + } *slots; }; -extern struct io_tlb_mem *io_tlb_default_mem; +extern struct io_tlb_mem io_tlb_default_mem; static inline bool is_swiotlb_buffer(struct device *dev, phys_addr_t paddr) { diff --git a/kernel/dma/swiotlb.c b/kernel/dma/swiotlb.c index 0ffbaae9fba2..91cd1d413027 100644 --- a/kernel/dma/swiotlb.c +++ b/kernel/dma/swiotlb.c @@ -70,7 +70,7 @@ enum swiotlb_force swiotlb_force; -struct io_tlb_mem *io_tlb_default_mem; +struct io_tlb_mem io_tlb_default_mem; /* * Max segment that we can provide which (if pages are contingous) will @@ -101,7 +101,7 @@ early_param("swiotlb", setup_io_tlb_npages); unsigned int swiotlb_max_segment(void) { - return io_tlb_default_mem ? max_segment : 0; + return io_tlb_default_mem.nslabs ? max_segment : 0; } EXPORT_SYMBOL_GPL(swiotlb_max_segment); @@ -134,9 +134,9 @@ void __init swiotlb_adjust_size(unsigned long size) void swiotlb_print_info(void) { - struct io_tlb_mem *mem = io_tlb_default_mem; + struct io_tlb_mem *mem = &io_tlb_default_mem; - if (!mem) { + if (!mem->nslabs) { pr_warn("No low mem\n"); return; } @@ -163,11 +163,11 @@ static inline unsigned long nr_slots(u64 val) */ void __init swiotlb_update_mem_attributes(void) { - struct io_tlb_mem *mem = io_tlb_default_mem; + struct io_tlb_mem *mem = &io_tlb_default_mem; void *vaddr; unsigned long bytes; - if (!mem || mem->late_alloc) + if (!mem->nslabs || mem->late_alloc) ret
Re: [PATCH v15 06/12] swiotlb: Use is_swiotlb_force_bounce for swiotlb data bouncing
On Tue, Jul 06, 2021 at 10:46:07AM -0400, Konrad Rzeszutek Wilk wrote: > On Tue, Jul 06, 2021 at 04:05:13PM +0200, Christoph Hellwig wrote: > > On Tue, Jul 06, 2021 at 03:01:04PM +0100, Robin Murphy wrote: > > > FWIW I was pondering the question of whether to do something along those > > > lines or just scrap the default assignment entirely, so since I hadn't > > > got > > > round to saying that I've gone ahead and hacked up the alternative > > > (similarly untested) for comparison :) > > > > > > TBH I'm still not sure which one I prefer... > > > > Claire did implement something like your suggestion originally, but > > I don't really like it as it doesn't scale for adding multiple global > > pools, e.g. for the 64-bit addressable one for the various encrypted > > secure guest schemes. > > Couple of things: > - I am not pushing to Linus the Claire's patchset until we have a >resolution on this. I hope you all agree that is a sensible way >forward as much as I hate doing that. Sure, it's a pity but we could clearly use a bit more time to get these just right and we've run out of time for 5.14. I think the main question I have is how would you like to see patches for 5.15? i.e. as patches on top of devel/for-linus-5.14 or something else? Cheers, Will
Re: [PATCH v15 06/12] swiotlb: Use is_swiotlb_force_bounce for swiotlb data bouncing
On Tue, Jul 06, 2021 at 04:39:11PM +0100, Robin Murphy wrote: > On 2021-07-06 15:05, Christoph Hellwig wrote: > > On Tue, Jul 06, 2021 at 03:01:04PM +0100, Robin Murphy wrote: > > > FWIW I was pondering the question of whether to do something along those > > > lines or just scrap the default assignment entirely, so since I hadn't got > > > round to saying that I've gone ahead and hacked up the alternative > > > (similarly untested) for comparison :) > > > > > > TBH I'm still not sure which one I prefer... > > > > Claire did implement something like your suggestion originally, but > > I don't really like it as it doesn't scale for adding multiple global > > pools, e.g. for the 64-bit addressable one for the various encrypted > > secure guest schemes. > > Ah yes, that had slipped my mind, and it's a fair point indeed. Since we're > not concerned with a minimal fix for backports anyway I'm more than happy to > focus on Will's approach. Another thing is that that looks to take us a > quiet step closer to the possibility of dynamically resizing a SWIOTLB pool, > which is something that some of the hypervisor protection schemes looking to > build on top of this series may want to explore at some point. Ok, I'll split that nasty diff I posted up into a reviewable series and we can take it from there. Will
Re: [PATCH v15 06/12] swiotlb: Use is_swiotlb_force_bounce for swiotlb data bouncing
On Tue, Jul 06, 2021 at 12:14:16PM -0700, Nathan Chancellor wrote: > On 7/6/2021 10:06 AM, Will Deacon wrote: > > On Tue, Jul 06, 2021 at 04:39:11PM +0100, Robin Murphy wrote: > > > On 2021-07-06 15:05, Christoph Hellwig wrote: > > > > On Tue, Jul 06, 2021 at 03:01:04PM +0100, Robin Murphy wrote: > > > > > FWIW I was pondering the question of whether to do something along > > > > > those > > > > > lines or just scrap the default assignment entirely, so since I > > > > > hadn't got > > > > > round to saying that I've gone ahead and hacked up the alternative > > > > > (similarly untested) for comparison :) > > > > > > > > > > TBH I'm still not sure which one I prefer... > > > > > > > > Claire did implement something like your suggestion originally, but > > > > I don't really like it as it doesn't scale for adding multiple global > > > > pools, e.g. for the 64-bit addressable one for the various encrypted > > > > secure guest schemes. > > > > > > Ah yes, that had slipped my mind, and it's a fair point indeed. Since > > > we're > > > not concerned with a minimal fix for backports anyway I'm more than happy > > > to > > > focus on Will's approach. Another thing is that that looks to take us a > > > quiet step closer to the possibility of dynamically resizing a SWIOTLB > > > pool, > > > which is something that some of the hypervisor protection schemes looking > > > to > > > build on top of this series may want to explore at some point. > > > > Ok, I'll split that nasty diff I posted up into a reviewable series and we > > can take it from there. > > For what it's worth, I attempted to boot Will's diff on top of Konrad's > devel/for-linus-5.14 and it did not work; in fact, I got no output on my > monitor period, even with earlyprintk=, and I do not think this machine has > a serial console. Looking back at the diff, I completely messed up swiotlb_exit() by mixing up physical and virtual addresses. > Robin's fix does work, it survived ten reboots with no issues getting to X > and I do not see the KASAN and slub debug messages anymore but I understand > that this is not the preferred solution it seems (although Konrad did want > to know if it works). > > I am happy to test any further patches or follow ups as needed, just keep me > on CC. Cheers. Since this isn't 5.14 material any more, I'll CC you on a series next week. Will
Re: [PATCH v15 06/12] swiotlb: Use is_swiotlb_force_bounce for swiotlb data bouncing
On Tue, Jul 06, 2021 at 12:59:57PM -0400, Konrad Rzeszutek Wilk wrote: > On Tue, Jul 06, 2021 at 05:57:21PM +0100, Will Deacon wrote: > > On Tue, Jul 06, 2021 at 10:46:07AM -0400, Konrad Rzeszutek Wilk wrote: > > > On Tue, Jul 06, 2021 at 04:05:13PM +0200, Christoph Hellwig wrote: > > > > On Tue, Jul 06, 2021 at 03:01:04PM +0100, Robin Murphy wrote: > > > > > FWIW I was pondering the question of whether to do something along > > > > > those > > > > > lines or just scrap the default assignment entirely, so since I > > > > > hadn't got > > > > > round to saying that I've gone ahead and hacked up the alternative > > > > > (similarly untested) for comparison :) > > > > > > > > > > TBH I'm still not sure which one I prefer... > > > > > > > > Claire did implement something like your suggestion originally, but > > > > I don't really like it as it doesn't scale for adding multiple global > > > > pools, e.g. for the 64-bit addressable one for the various encrypted > > > > secure guest schemes. > > > > > > Couple of things: > > > - I am not pushing to Linus the Claire's patchset until we have a > > >resolution on this. I hope you all agree that is a sensible way > > >forward as much as I hate doing that. > > > > Sure, it's a pity but we could clearly use a bit more time to get these > > just right and we've run out of time for 5.14. > > > > I think the main question I have is how would you like to see patches for > > 5.15? i.e. as patches on top of devel/for-linus-5.14 or something else? > > Yes that would be perfect. If there are any dependencies on the rc1, I > can rebase it on top of that. Yes, please, rebasing would be very helpful. The broader rework of 'io_tlb_default_mem' is going to conflict quite badly otherwise. Cheers, Will
Re: [PATCH v4 13/14] dt-bindings: of: Add restricted DMA pool
Hi Claire, On Tue, Feb 09, 2021 at 02:21:30PM +0800, Claire Chang wrote: > Introduce the new compatible string, restricted-dma-pool, for restricted > DMA. One can specify the address and length of the restricted DMA memory > region by restricted-dma-pool in the reserved-memory node. > > Signed-off-by: Claire Chang > --- > .../reserved-memory/reserved-memory.txt | 24 +++ > 1 file changed, 24 insertions(+) > > diff --git > a/Documentation/devicetree/bindings/reserved-memory/reserved-memory.txt > b/Documentation/devicetree/bindings/reserved-memory/reserved-memory.txt > index e8d3096d922c..fc9a12c2f679 100644 > --- a/Documentation/devicetree/bindings/reserved-memory/reserved-memory.txt > +++ b/Documentation/devicetree/bindings/reserved-memory/reserved-memory.txt > @@ -51,6 +51,20 @@ compatible (optional) - standard definition >used as a shared pool of DMA buffers for a set of devices. It can >be used by an operating system to instantiate the necessary pool >management subsystem if necessary. > +- restricted-dma-pool: This indicates a region of memory meant to be > + used as a pool of restricted DMA buffers for a set of devices. The > + memory region would be the only region accessible to those devices. > + When using this, the no-map and reusable properties must not be > set, > + so the operating system can create a virtual mapping that will be > used > + for synchronization. The main purpose for restricted DMA is to > + mitigate the lack of DMA access control on systems without an > IOMMU, > + which could result in the DMA accessing the system memory at > + unexpected times and/or unexpected addresses, possibly leading to > data > + leakage or corruption. The feature on its own provides a basic > level > + of protection against the DMA overwriting buffer contents at > + unexpected times. However, to protect against general data leakage > and > + system memory corruption, the system needs to provide way to lock > down > + the memory access, e.g., MPU. As far as I can tell, these pools work with both static allocations (which seem to match your use-case where firmware has preconfigured the DMA ranges) but also with dynamic allocations where a 'size' property is present instead of the 'reg' property and the kernel is responsible for allocating the reservation during boot. Am I right and, if so, is that deliberate? I ask because I think that would potentially be useful to us for the Protected KVM work, where we need to bounce virtio memory accesses via guest-determined windows because the guest memory is generally inaccessible to the host. We've been hacking this using a combination of "swiotlb=force" and set_memory_{decrypted,encrypted}() but it would be much better to leverage the stuff you have here. Also: > + > + restricted_dma_mem_reserved: restricted_dma_mem_reserved { > + compatible = "restricted-dma-pool"; > + reg = <0x5000 0x40>; > + }; > }; > > /* ... */ > @@ -138,4 +157,9 @@ one for multimedia processing (named > multimedia-memory@7700, 64MiB). > memory-region = <&multimedia_reserved>; > /* ... */ > }; > + > + pcie_device: pcie_device@0,0 { > + memory-region = <&restricted_dma_mem_reserved>; > + /* ... */ > + }; I find this example a bit weird, as I didn't think we usually had DT nodes for PCI devices; rather they are discovered as a result of probing config space. Is the idea that you have one reserved memory region attached to the RC and all the PCI devices below that share the region, or is there a need for a mapping mechanism? Will
Re: [PATCH v7 14/15] dt-bindings: of: Add restricted DMA pool
Hi Claire, On Tue, May 18, 2021 at 02:42:14PM +0800, Claire Chang wrote: > Introduce the new compatible string, restricted-dma-pool, for restricted > DMA. One can specify the address and length of the restricted DMA memory > region by restricted-dma-pool in the reserved-memory node. > > Signed-off-by: Claire Chang > --- > .../reserved-memory/reserved-memory.txt | 27 +++ > 1 file changed, 27 insertions(+) > > diff --git > a/Documentation/devicetree/bindings/reserved-memory/reserved-memory.txt > b/Documentation/devicetree/bindings/reserved-memory/reserved-memory.txt > index e8d3096d922c..284aea659015 100644 > --- a/Documentation/devicetree/bindings/reserved-memory/reserved-memory.txt > +++ b/Documentation/devicetree/bindings/reserved-memory/reserved-memory.txt > @@ -51,6 +51,23 @@ compatible (optional) - standard definition >used as a shared pool of DMA buffers for a set of devices. It can >be used by an operating system to instantiate the necessary pool >management subsystem if necessary. > +- restricted-dma-pool: This indicates a region of memory meant to be > + used as a pool of restricted DMA buffers for a set of devices. The > + memory region would be the only region accessible to those devices. > + When using this, the no-map and reusable properties must not be > set, > + so the operating system can create a virtual mapping that will be > used > + for synchronization. The main purpose for restricted DMA is to > + mitigate the lack of DMA access control on systems without an > IOMMU, > + which could result in the DMA accessing the system memory at > + unexpected times and/or unexpected addresses, possibly leading to > data > + leakage or corruption. The feature on its own provides a basic > level > + of protection against the DMA overwriting buffer contents at > + unexpected times. However, to protect against general data leakage > and > + system memory corruption, the system needs to provide way to lock > down > + the memory access, e.g., MPU. Note that since coherent allocation > + needs remapping, one must set up another device coherent pool by > + shared-dma-pool and use dma_alloc_from_dev_coherent instead for > atomic > + coherent allocation. > - vendor specific string in the form ,[-] > no-map (optional) - empty property > - Indicates the operating system must not create a virtual mapping > @@ -120,6 +137,11 @@ one for multimedia processing (named > multimedia-memory@7700, 64MiB). > compatible = "acme,multimedia-memory"; > reg = <0x7700 0x400>; > }; > + > + restricted_dma_mem_reserved: restricted_dma_mem_reserved { > + compatible = "restricted-dma-pool"; > + reg = <0x5000 0x40>; > + }; nit: You need to update the old text that states "This example defines 3 contiguous regions ...". > }; > > /* ... */ > @@ -138,4 +160,9 @@ one for multimedia processing (named > multimedia-memory@7700, 64MiB). > memory-region = <&multimedia_reserved>; > /* ... */ > }; > + > + pcie_device: pcie_device@0,0 { > + memory-region = <&restricted_dma_mem_reserved>; > + /* ... */ > + }; I still don't understand how this works for individual PCIe devices -- how is dev->of_node set to point at the node you have above? I tried adding the memory-region to the host controller instead, and then I see it crop up in dmesg: | pci-host-generic 4000.pci: assigned reserved memory node restricted_dma_mem_reserved but none of the actual PCI devices end up with 'dma_io_tlb_mem' set, and so the restricted DMA area is not used. In fact, swiotlb isn't used at all. What am I missing to make this work with PCIe devices? Thanks, Will
Re: [PATCH v7 14/15] dt-bindings: of: Add restricted DMA pool
On Wed, May 26, 2021 at 01:13:22PM +0100, Will Deacon wrote: > On Tue, May 18, 2021 at 02:42:14PM +0800, Claire Chang wrote: > > @@ -138,4 +160,9 @@ one for multimedia processing (named > > multimedia-memory@7700, 64MiB). > > memory-region = <&multimedia_reserved>; > > /* ... */ > > }; > > + > > + pcie_device: pcie_device@0,0 { > > + memory-region = <&restricted_dma_mem_reserved>; > > + /* ... */ > > + }; > > I still don't understand how this works for individual PCIe devices -- how > is dev->of_node set to point at the node you have above? > > I tried adding the memory-region to the host controller instead, and then > I see it crop up in dmesg: > > | pci-host-generic 4000.pci: assigned reserved memory node > restricted_dma_mem_reserved > > but none of the actual PCI devices end up with 'dma_io_tlb_mem' set, and > so the restricted DMA area is not used. In fact, swiotlb isn't used at all. > > What am I missing to make this work with PCIe devices? Aha, looks like we're just missing the logic to inherit the DMA configuration. The diff below gets things working for me. Will --->8 diff --git a/drivers/of/address.c b/drivers/of/address.c index c562a9ff5f0b..bf499fdd6e93 100644 --- a/drivers/of/address.c +++ b/drivers/of/address.c @@ -1113,25 +1113,25 @@ bool of_dma_is_coherent(struct device_node *np) } EXPORT_SYMBOL_GPL(of_dma_is_coherent); -int of_dma_set_restricted_buffer(struct device *dev) +int of_dma_set_restricted_buffer(struct device *dev, struct device_node *np) { - struct device_node *node; int count, i; - if (!dev->of_node) + if (!np) return 0; - count = of_property_count_elems_of_size(dev->of_node, "memory-region", + count = of_property_count_elems_of_size(np, "memory-region", sizeof(phandle)); for (i = 0; i < count; i++) { - node = of_parse_phandle(dev->of_node, "memory-region", i); + struct device_node *node; + + node = of_parse_phandle(np, "memory-region", i); /* There might be multiple memory regions, but only one -* restriced-dma-pool region is allowed. +* restricted-dma-pool region is allowed. */ if (of_device_is_compatible(node, "restricted-dma-pool") && of_device_is_available(node)) - return of_reserved_mem_device_init_by_idx( - dev, dev->of_node, i); + return of_reserved_mem_device_init_by_idx(dev, np, i); } return 0; diff --git a/drivers/of/device.c b/drivers/of/device.c index d8d865223e51..2defdca418ec 100644 --- a/drivers/of/device.c +++ b/drivers/of/device.c @@ -166,7 +166,7 @@ int of_dma_configure_id(struct device *dev, struct device_node *np, arch_setup_dma_ops(dev, dma_start, size, iommu, coherent); if (!iommu) - return of_dma_set_restricted_buffer(dev); + return of_dma_set_restricted_buffer(dev, np); return 0; } diff --git a/drivers/of/of_private.h b/drivers/of/of_private.h index 9fc874548528..8fde97565d11 100644 --- a/drivers/of/of_private.h +++ b/drivers/of/of_private.h @@ -163,14 +163,15 @@ struct bus_dma_region; #if defined(CONFIG_OF_ADDRESS) && defined(CONFIG_HAS_DMA) int of_dma_get_range(struct device_node *np, const struct bus_dma_region **map); -int of_dma_set_restricted_buffer(struct device *dev); +int of_dma_set_restricted_buffer(struct device *dev, struct device_node *np); #else static inline int of_dma_get_range(struct device_node *np, const struct bus_dma_region **map) { return -ENODEV; } -static inline int of_dma_set_restricted_buffer(struct device *dev) +static inline int of_dma_set_restricted_buffer(struct device *dev, + struct device_node *np) { return -ENODEV; }
Re: [PATCH v7 14/15] dt-bindings: of: Add restricted DMA pool
On Thu, May 27, 2021 at 07:29:20PM +0800, Claire Chang wrote: > On Wed, May 26, 2021 at 11:53 PM Will Deacon wrote: > > > > On Wed, May 26, 2021 at 01:13:22PM +0100, Will Deacon wrote: > > > On Tue, May 18, 2021 at 02:42:14PM +0800, Claire Chang wrote: > > > > @@ -138,4 +160,9 @@ one for multimedia processing (named > > > > multimedia-memory@7700, 64MiB). > > > > memory-region = <&multimedia_reserved>; > > > > /* ... */ > > > > }; > > > > + > > > > + pcie_device: pcie_device@0,0 { > > > > + memory-region = <&restricted_dma_mem_reserved>; > > > > + /* ... */ > > > > + }; > > > > > > I still don't understand how this works for individual PCIe devices -- how > > > is dev->of_node set to point at the node you have above? > > > > > > I tried adding the memory-region to the host controller instead, and then > > > I see it crop up in dmesg: > > > > > > | pci-host-generic 4000.pci: assigned reserved memory node > > > restricted_dma_mem_reserved > > > > > > but none of the actual PCI devices end up with 'dma_io_tlb_mem' set, and > > > so the restricted DMA area is not used. In fact, swiotlb isn't used at > > > all. > > > > > > What am I missing to make this work with PCIe devices? > > > > Aha, looks like we're just missing the logic to inherit the DMA > > configuration. The diff below gets things working for me. > > I guess what was missing is the reg property in the pcie_device node. > Will update the example dts. Thanks. I still think something like my diff makes sense, if you wouldn't mind including it, as it allows restricted DMA to be used for situations where the PCIe topology is not static. Perhaps we should prefer dev->of_node if it exists, but then use the node of the host bridge's parent node otherwise? Will
Re: [PATCH v7 14/15] dt-bindings: of: Add restricted DMA pool
On Thu, May 27, 2021 at 08:48:59PM +0800, Claire Chang wrote: > On Thu, May 27, 2021 at 7:35 PM Will Deacon wrote: > > > > On Thu, May 27, 2021 at 07:29:20PM +0800, Claire Chang wrote: > > > On Wed, May 26, 2021 at 11:53 PM Will Deacon wrote: > > > > > > > > On Wed, May 26, 2021 at 01:13:22PM +0100, Will Deacon wrote: > > > > > On Tue, May 18, 2021 at 02:42:14PM +0800, Claire Chang wrote: > > > > > > @@ -138,4 +160,9 @@ one for multimedia processing (named > > > > > > multimedia-memory@7700, 64MiB). > > > > > > memory-region = <&multimedia_reserved>; > > > > > > /* ... */ > > > > > > }; > > > > > > + > > > > > > + pcie_device: pcie_device@0,0 { > > > > > > + memory-region = <&restricted_dma_mem_reserved>; > > > > > > + /* ... */ > > > > > > + }; > > > > > > > > > > I still don't understand how this works for individual PCIe devices > > > > > -- how > > > > > is dev->of_node set to point at the node you have above? > > > > > > > > > > I tried adding the memory-region to the host controller instead, and > > > > > then > > > > > I see it crop up in dmesg: > > > > > > > > > > | pci-host-generic 4000.pci: assigned reserved memory node > > > > > restricted_dma_mem_reserved > > > > > > > > > > but none of the actual PCI devices end up with 'dma_io_tlb_mem' set, > > > > > and > > > > > so the restricted DMA area is not used. In fact, swiotlb isn't used > > > > > at all. > > > > > > > > > > What am I missing to make this work with PCIe devices? > > > > > > > > Aha, looks like we're just missing the logic to inherit the DMA > > > > configuration. The diff below gets things working for me. > > > > > > I guess what was missing is the reg property in the pcie_device node. > > > Will update the example dts. > > > > Thanks. I still think something like my diff makes sense, if you wouldn't > > mind including > > it, as it allows restricted DMA to be used for situations where the PCIe > > topology is not static. > > > > Perhaps we should prefer dev->of_node if it exists, but then use the node > > of the host bridge's parent node otherwise? > > Sure. Let me add in the next version. Brill, thanks! I'll take it for a spin once it lands on the list. Will
Re: [PATCH v8 00/15] Restricted DMA
Hi Claire, On Thu, May 27, 2021 at 08:58:30PM +0800, Claire Chang wrote: > This series implements mitigations for lack of DMA access control on > systems without an IOMMU, which could result in the DMA accessing the > system memory at unexpected times and/or unexpected addresses, possibly > leading to data leakage or corruption. > > For example, we plan to use the PCI-e bus for Wi-Fi and that PCI-e bus is > not behind an IOMMU. As PCI-e, by design, gives the device full access to > system memory, a vulnerability in the Wi-Fi firmware could easily escalate > to a full system exploit (remote wifi exploits: [1a], [1b] that shows a > full chain of exploits; [2], [3]). > > To mitigate the security concerns, we introduce restricted DMA. Restricted > DMA utilizes the existing swiotlb to bounce streaming DMA in and out of a > specially allocated region and does memory allocation from the same region. > The feature on its own provides a basic level of protection against the DMA > overwriting buffer contents at unexpected times. However, to protect > against general data leakage and system memory corruption, the system needs > to provide a way to restrict the DMA to a predefined memory region (this is > usually done at firmware level, e.g. MPU in ATF on some ARM platforms [4]). > > [1a] > https://googleprojectzero.blogspot.com/2017/04/over-air-exploiting-broadcoms-wi-fi_4.html > [1b] > https://googleprojectzero.blogspot.com/2017/04/over-air-exploiting-broadcoms-wi-fi_11.html > [2] https://blade.tencent.com/en/advisories/qualpwn/ > [3] > https://www.bleepingcomputer.com/news/security/vulnerabilities-found-in-highly-popular-firmware-for-wifi-chips/ > [4] > https://github.com/ARM-software/arm-trusted-firmware/blob/master/plat/mediatek/mt8183/drivers/emi_mpu/emi_mpu.c#L132 > > v8: > - Fix reserved-memory.txt and add the reg property in example. > - Fix sizeof for of_property_count_elems_of_size in > drivers/of/address.c#of_dma_set_restricted_buffer. > - Apply Will's suggestion to try the OF node having DMA configuration in > drivers/of/address.c#of_dma_set_restricted_buffer. > - Fix typo in the comment of > drivers/of/address.c#of_dma_set_restricted_buffer. > - Add error message for PageHighMem in > kernel/dma/swiotlb.c#rmem_swiotlb_device_init and move it to > rmem_swiotlb_setup. > - Fix the message string in rmem_swiotlb_setup. Thanks for the v8. It works for me out of the box on arm64 under KVM, so: Tested-by: Will Deacon Note that something seems to have gone wrong with the mail threading, so the last 5 patches ended up as a separate thread for me. Probably worth posting again with all the patches in one place, if you can. Cheers, Will
Re: [PATCH v12 00/12] Restricted DMA
Hi Claire, On Wed, Jun 16, 2021 at 02:21:45PM +0800, Claire Chang wrote: > This series implements mitigations for lack of DMA access control on > systems without an IOMMU, which could result in the DMA accessing the > system memory at unexpected times and/or unexpected addresses, possibly > leading to data leakage or corruption. > > For example, we plan to use the PCI-e bus for Wi-Fi and that PCI-e bus is > not behind an IOMMU. As PCI-e, by design, gives the device full access to > system memory, a vulnerability in the Wi-Fi firmware could easily escalate > to a full system exploit (remote wifi exploits: [1a], [1b] that shows a > full chain of exploits; [2], [3]). > > To mitigate the security concerns, we introduce restricted DMA. Restricted > DMA utilizes the existing swiotlb to bounce streaming DMA in and out of a > specially allocated region and does memory allocation from the same region. > The feature on its own provides a basic level of protection against the DMA > overwriting buffer contents at unexpected times. However, to protect > against general data leakage and system memory corruption, the system needs > to provide a way to restrict the DMA to a predefined memory region (this is > usually done at firmware level, e.g. MPU in ATF on some ARM platforms [4]). > > [1a] > https://googleprojectzero.blogspot.com/2017/04/over-air-exploiting-broadcoms-wi-fi_4.html > [1b] > https://googleprojectzero.blogspot.com/2017/04/over-air-exploiting-broadcoms-wi-fi_11.html > [2] https://blade.tencent.com/en/advisories/qualpwn/ > [3] > https://www.bleepingcomputer.com/news/security/vulnerabilities-found-in-highly-popular-firmware-for-wifi-chips/ > [4] > https://github.com/ARM-software/arm-trusted-firmware/blob/master/plat/mediatek/mt8183/drivers/emi_mpu/emi_mpu.c#L132 > > v12: > Split is_dev_swiotlb_force into is_swiotlb_force_bounce (patch 06/12) and > is_swiotlb_for_alloc (patch 09/12) I took this for a spin in an arm64 KVM guest with virtio devices using the DMA API and it works as expected on top of swiotlb devel/for-linus-5.14, so: Tested-by: Will Deacon Thanks! Will
Re: [PATCH v14 06/12] swiotlb: Use is_swiotlb_force_bounce for swiotlb data bouncing
On Wed, Jun 23, 2021 at 12:39:29PM -0400, Qian Cai wrote: > > > On 6/18/2021 11:40 PM, Claire Chang wrote: > > Propagate the swiotlb_force into io_tlb_default_mem->force_bounce and > > use it to determine whether to bounce the data or not. This will be > > useful later to allow for different pools. > > > > Signed-off-by: Claire Chang > > Reviewed-by: Christoph Hellwig > > Tested-by: Stefano Stabellini > > Tested-by: Will Deacon > > Acked-by: Stefano Stabellini > > Reverting the rest of the series up to this patch fixed a boot crash with > NVMe on today's linux-next. Hmm, so that makes patch 7 the suspicious one, right? Looking at that one more closely, it looks like swiotlb_find_slots() takes 'alloc_size + offset' as its 'alloc_size' parameter from swiotlb_tbl_map_single() and initialises 'mem->slots[i].alloc_size' based on 'alloc_size + offset', which looks like a change in behaviour from the old code, which didn't include the offset there. swiotlb_release_slots() then adds the offset back on afaict, so we end up accounting for it twice and possibly unmap more than we're supposed to? Will
Re: [PATCH v14 06/12] swiotlb: Use is_swiotlb_force_bounce for swiotlb data bouncing
On Thu, Jun 24, 2021 at 12:14:39PM +0100, Robin Murphy wrote: > On 2021-06-24 07:05, Claire Chang wrote: > > On Thu, Jun 24, 2021 at 1:43 PM Christoph Hellwig wrote: > > > > > > On Wed, Jun 23, 2021 at 02:44:34PM -0400, Qian Cai wrote: > > > > is_swiotlb_force_bounce at > > > > /usr/src/linux-next/./include/linux/swiotlb.h:119 > > > > > > > > is_swiotlb_force_bounce() was the new function introduced in this patch > > > > here. > > > > > > > > +static inline bool is_swiotlb_force_bounce(struct device *dev) > > > > +{ > > > > + return dev->dma_io_tlb_mem->force_bounce; > > > > +} > > > > > > To me the crash looks like dev->dma_io_tlb_mem is NULL. Can you > > > turn this into : > > > > > > return dev->dma_io_tlb_mem && dev->dma_io_tlb_mem->force_bounce; > > > > > > for a quick debug check? > > > > I just realized that dma_io_tlb_mem might be NULL like Christoph > > pointed out since swiotlb might not get initialized. > > However, `Unable to handle kernel paging request at virtual address > > dfff800e` looks more like the address is garbage rather than > > NULL? > > I wonder if that's because dev->dma_io_tlb_mem is not assigned > > properly (which means device_initialize is not called?). > > What also looks odd is that the base "address" 0xdfff8000 is held in > a couple of registers, but the offset 0xe looks too small to match up to any > relevant structure member in that dereference chain :/ FWIW, I've managed to trigger a NULL dereference locally when swiotlb hasn't been initialised but we dereference 'dev->dma_io_tlb_mem', so I think Christoph's suggestion is needed regardless. But I agree that it won't help with the issue reported by Qian Cai. Qian Cai: please can you share your .config and your command line? Thanks, Will
Re: [PATCH v14 06/12] swiotlb: Use is_swiotlb_force_bounce for swiotlb data bouncing
On Thu, Jun 24, 2021 at 12:34:09PM +0100, Robin Murphy wrote: > On 2021-06-24 12:18, Will Deacon wrote: > > On Thu, Jun 24, 2021 at 12:14:39PM +0100, Robin Murphy wrote: > > > On 2021-06-24 07:05, Claire Chang wrote: > > > > On Thu, Jun 24, 2021 at 1:43 PM Christoph Hellwig wrote: > > > > > > > > > > On Wed, Jun 23, 2021 at 02:44:34PM -0400, Qian Cai wrote: > > > > > > is_swiotlb_force_bounce at > > > > > > /usr/src/linux-next/./include/linux/swiotlb.h:119 > > > > > > > > > > > > is_swiotlb_force_bounce() was the new function introduced in this > > > > > > patch here. > > > > > > > > > > > > +static inline bool is_swiotlb_force_bounce(struct device *dev) > > > > > > +{ > > > > > > + return dev->dma_io_tlb_mem->force_bounce; > > > > > > +} > > > > > > > > > > To me the crash looks like dev->dma_io_tlb_mem is NULL. Can you > > > > > turn this into : > > > > > > > > > > return dev->dma_io_tlb_mem && > > > > > dev->dma_io_tlb_mem->force_bounce; > > > > > > > > > > for a quick debug check? > > > > > > > > I just realized that dma_io_tlb_mem might be NULL like Christoph > > > > pointed out since swiotlb might not get initialized. > > > > However, `Unable to handle kernel paging request at virtual address > > > > dfff800e` looks more like the address is garbage rather than > > > > NULL? > > > > I wonder if that's because dev->dma_io_tlb_mem is not assigned > > > > properly (which means device_initialize is not called?). > > > > > > What also looks odd is that the base "address" 0xdfff8000 is held > > > in > > > a couple of registers, but the offset 0xe looks too small to match up to > > > any > > > relevant structure member in that dereference chain :/ > > > > FWIW, I've managed to trigger a NULL dereference locally when swiotlb hasn't > > been initialised but we dereference 'dev->dma_io_tlb_mem', so I think > > Christoph's suggestion is needed regardless. > > Ack to that - for SWIOTLB_NO_FORCE, io_tlb_default_mem will remain NULL. The > massive jump in KernelCI baseline failures as of yesterday looks like every > arm64 machine with less than 4GB of RAM blowing up... Ok, diff below which attempts to tackle the offset issue I mentioned as well. Qian Cai -- please can you try with these changes? Will --->8 diff --git a/include/linux/swiotlb.h b/include/linux/swiotlb.h index 175b6c113ed8..39284ff2a6cd 100644 --- a/include/linux/swiotlb.h +++ b/include/linux/swiotlb.h @@ -116,7 +116,9 @@ static inline bool is_swiotlb_buffer(struct device *dev, phys_addr_t paddr) static inline bool is_swiotlb_force_bounce(struct device *dev) { - return dev->dma_io_tlb_mem->force_bounce; + struct io_tlb_mem *mem = dev->dma_io_tlb_mem; + + return mem && mem->force_bounce; } void __init swiotlb_exit(void); diff --git a/kernel/dma/swiotlb.c b/kernel/dma/swiotlb.c index 44be8258e27b..0ffbaae9fba2 100644 --- a/kernel/dma/swiotlb.c +++ b/kernel/dma/swiotlb.c @@ -449,6 +449,7 @@ static int swiotlb_find_slots(struct device *dev, phys_addr_t orig_addr, dma_get_min_align_mask(dev) & ~(IO_TLB_SIZE - 1); unsigned int nslots = nr_slots(alloc_size), stride; unsigned int index, wrap, count = 0, i; + unsigned int offset = swiotlb_align_offset(dev, orig_addr); unsigned long flags; BUG_ON(!nslots); @@ -497,7 +498,7 @@ static int swiotlb_find_slots(struct device *dev, phys_addr_t orig_addr, for (i = index; i < index + nslots; i++) { mem->slots[i].list = 0; mem->slots[i].alloc_size = - alloc_size - ((i - index) << IO_TLB_SHIFT); + alloc_size - (offset + ((i - index) << IO_TLB_SHIFT)); } for (i = index - 1; io_tlb_offset(i) != IO_TLB_SEGSIZE - 1 &&
Re: [PATCH v15 00/12] Restricted DMA
On Thu, Jun 24, 2021 at 03:19:48PM -0400, Konrad Rzeszutek Wilk wrote: > On Thu, Jun 24, 2021 at 11:55:14PM +0800, Claire Chang wrote: > > This series implements mitigations for lack of DMA access control on > > systems without an IOMMU, which could result in the DMA accessing the > > system memory at unexpected times and/or unexpected addresses, possibly > > leading to data leakage or corruption. > > > > For example, we plan to use the PCI-e bus for Wi-Fi and that PCI-e bus is > > not behind an IOMMU. As PCI-e, by design, gives the device full access to > > system memory, a vulnerability in the Wi-Fi firmware could easily escalate > > to a full system exploit (remote wifi exploits: [1a], [1b] that shows a > > full chain of exploits; [2], [3]). > > > > To mitigate the security concerns, we introduce restricted DMA. Restricted > > DMA utilizes the existing swiotlb to bounce streaming DMA in and out of a > > specially allocated region and does memory allocation from the same region. > > The feature on its own provides a basic level of protection against the DMA > > overwriting buffer contents at unexpected times. However, to protect > > against general data leakage and system memory corruption, the system needs > > to provide a way to restrict the DMA to a predefined memory region (this is > > usually done at firmware level, e.g. MPU in ATF on some ARM platforms [4]). > > > > [1a] > > https://googleprojectzero.blogspot.com/2017/04/over-air-exploiting-broadcoms-wi-fi_4.html > > [1b] > > https://googleprojectzero.blogspot.com/2017/04/over-air-exploiting-broadcoms-wi-fi_11.html > > [2] https://blade.tencent.com/en/advisories/qualpwn/ > > [3] > > https://www.bleepingcomputer.com/news/security/vulnerabilities-found-in-highly-popular-firmware-for-wifi-chips/ > > [4] > > https://github.com/ARM-software/arm-trusted-firmware/blob/master/plat/mediatek/mt8183/drivers/emi_mpu/emi_mpu.c#L132 > > > > v15: > > - Apply Will's diff > > (https://lore.kernel.org/patchwork/patch/1448957/#1647521) > > to fix the crash reported by Qian. > > - Add Stefano's Acked-by tag for patch 01/12 from v14 > > That all should be now be on > > https://git.kernel.org/pub/scm/linux/kernel/git/konrad/swiotlb.git/ > devel/for-linus-5.14 (and linux-next) Thanks Konrad! Will
Re: [PATCH v15 06/12] swiotlb: Use is_swiotlb_force_bounce for swiotlb data bouncing
On Wed, Jun 30, 2021 at 05:17:27PM +0800, Claire Chang wrote: > On Wed, Jun 30, 2021 at 9:43 AM Nathan Chancellor wrote: > > > > On Thu, Jun 24, 2021 at 11:55:20PM +0800, Claire Chang wrote: > > > Propagate the swiotlb_force into io_tlb_default_mem->force_bounce and > > > use it to determine whether to bounce the data or not. This will be > > > useful later to allow for different pools. > > > > > > Signed-off-by: Claire Chang > > > Reviewed-by: Christoph Hellwig > > > Tested-by: Stefano Stabellini > > > Tested-by: Will Deacon > > > Acked-by: Stefano Stabellini > > > > This patch as commit af452ec1b1a3 ("swiotlb: Use is_swiotlb_force_bounce > > for swiotlb data bouncing") causes my Ryzen 3 4300G system to fail to > > get to an X session consistently (although not every single time), > > presumably due to a crash in the AMDGPU driver that I see in dmesg. > > > > I have attached logs at af452ec1b1a3 and f127c9556a8e and I am happy > > to provide any further information, debug, or test patches as necessary. > > Are you using swiotlb=force? or the swiotlb_map is called because of > !dma_capable? > (https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/tree/kernel/dma/direct.h#n93) The command line is in the dmesg: | Kernel command line: initrd=\amd-ucode.img initrd=\initramfs-linux-next-llvm.img root=PARTUUID=8680aa0c-cf09-4a69-8cf3-970478040ee7 rw intel_pstate=no_hwp irqpoll but I worry that this looks _very_ similar to the issue reported by Qian Cai which we thought we had fixed. Nathan -- is the failure deterministic? > `BUG: unable to handle page fault for address: 003a8290` and > the fact it crashed at `_raw_spin_lock_irqsave` look like the memory > (maybe dev->dma_io_tlb_mem) was corrupted? > The dev->dma_io_tlb_mem should be set here > (https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/tree/drivers/pci/probe.c#n2528) > through device_initialize. I'm less sure about this. 'dma_io_tlb_mem' should be pointing at 'io_tlb_default_mem', which is a page-aligned allocation from memblock. The spinlock is at offset 0x24 in that structure, and looking at the register dump from the crash: Jun 29 18:28:42 hp-4300G kernel: RSP: 0018:adb4013db9e8 EFLAGS: 00010006 Jun 29 18:28:42 hp-4300G kernel: RAX: 003a8290 RBX: RCX: 8900572ad580 Jun 29 18:28:42 hp-4300G kernel: RDX: 89005653f024 RSI: 000c RDI: 1d17 Jun 29 18:28:42 hp-4300G kernel: RBP: 0a20d000 R08: 000c R09: Jun 29 18:28:42 hp-4300G kernel: R10: 0a20d000 R11: 89005653f000 R12: 0212 Jun 29 18:28:42 hp-4300G kernel: R13: 1000 R14: 0002 R15: 0020 Jun 29 18:28:42 hp-4300G kernel: FS: 7f1f8898ea40() GS:89005728() knlGS: Jun 29 18:28:42 hp-4300G kernel: CS: 0010 DS: ES: CR0: 80050033 Jun 29 18:28:42 hp-4300G kernel: CR2: 003a8290 CR3: 0001020d CR4: 00350ee0 Jun 29 18:28:42 hp-4300G kernel: Call Trace: Jun 29 18:28:42 hp-4300G kernel: _raw_spin_lock_irqsave+0x39/0x50 Jun 29 18:28:42 hp-4300G kernel: swiotlb_tbl_map_single+0x12b/0x4c0 Then that correlates with R11 holding the 'dma_io_tlb_mem' pointer and RDX pointing at the spinlock. Yet RAX is holding junk :/ I agree that enabling KASAN would be a good idea, but I also think we probably need to get some more information out of swiotlb_tbl_map_single() to see see what exactly is going wrong in there. Will
Re: [PATCH v15 06/12] swiotlb: Use is_swiotlb_force_bounce for swiotlb data bouncing
On Wed, Jun 30, 2021 at 08:56:51AM -0700, Nathan Chancellor wrote: > On Wed, Jun 30, 2021 at 12:43:48PM +0100, Will Deacon wrote: > > On Wed, Jun 30, 2021 at 05:17:27PM +0800, Claire Chang wrote: > > > `BUG: unable to handle page fault for address: 003a8290` and > > > the fact it crashed at `_raw_spin_lock_irqsave` look like the memory > > > (maybe dev->dma_io_tlb_mem) was corrupted? > > > The dev->dma_io_tlb_mem should be set here > > > (https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/tree/drivers/pci/probe.c#n2528) > > > through device_initialize. > > > > I'm less sure about this. 'dma_io_tlb_mem' should be pointing at > > 'io_tlb_default_mem', which is a page-aligned allocation from memblock. > > The spinlock is at offset 0x24 in that structure, and looking at the > > register dump from the crash: > > > > Jun 29 18:28:42 hp-4300G kernel: RSP: 0018:adb4013db9e8 EFLAGS: 00010006 > > Jun 29 18:28:42 hp-4300G kernel: RAX: 003a8290 RBX: > > RCX: 8900572ad580 > > Jun 29 18:28:42 hp-4300G kernel: RDX: 89005653f024 RSI: > > 000c RDI: 1d17 > > Jun 29 18:28:42 hp-4300G kernel: RBP: 0a20d000 R08: > > 000c R09: > > Jun 29 18:28:42 hp-4300G kernel: R10: 0a20d000 R11: > > 89005653f000 R12: 0212 > > Jun 29 18:28:42 hp-4300G kernel: R13: 1000 R14: > > 0002 R15: 0020 > > Jun 29 18:28:42 hp-4300G kernel: FS: 7f1f8898ea40() > > GS:89005728() knlGS: > > Jun 29 18:28:42 hp-4300G kernel: CS: 0010 DS: ES: CR0: > > 80050033 > > Jun 29 18:28:42 hp-4300G kernel: CR2: 003a8290 CR3: > > 0001020d CR4: 00350ee0 > > Jun 29 18:28:42 hp-4300G kernel: Call Trace: > > Jun 29 18:28:42 hp-4300G kernel: _raw_spin_lock_irqsave+0x39/0x50 > > Jun 29 18:28:42 hp-4300G kernel: swiotlb_tbl_map_single+0x12b/0x4c0 > > > > Then that correlates with R11 holding the 'dma_io_tlb_mem' pointer and > > RDX pointing at the spinlock. Yet RAX is holding junk :/ > > > > I agree that enabling KASAN would be a good idea, but I also think we > > probably need to get some more information out of swiotlb_tbl_map_single() > > to see see what exactly is going wrong in there. > > I can certainly enable KASAN and if there is any debug print I can add > or dump anything, let me know! I bit the bullet and took v5.13 with swiotlb/for-linus-5.14 merged in, built x86 defconfig and ran it on my laptop. However, it seems to work fine! Please can you share your .config? Will
Re: [PATCH v15 12/12] of: Add plumbing for restricted DMA pool
On Fri, Jul 02, 2021 at 12:39:41PM +0100, Robin Murphy wrote: > On 2021-07-02 04:08, Guenter Roeck wrote: > > On Thu, Jun 24, 2021 at 11:55:26PM +0800, Claire Chang wrote: > > > If a device is not behind an IOMMU, we look up the device node and set > > > up the restricted DMA when the restricted-dma-pool is presented. > > > > > > Signed-off-by: Claire Chang > > > Tested-by: Stefano Stabellini > > > Tested-by: Will Deacon > > > > With this patch in place, all sparc and sparc64 qemu emulations > > fail to boot. Symptom is that the root file system is not found. > > Reverting this patch fixes the problem. Bisect log is attached. > > Ah, OF_ADDRESS depends on !SPARC, so of_dma_configure_id() is presumably > returning an unexpected -ENODEV from the of_dma_set_restricted_buffer() > stub. That should probably be returning 0 instead, since either way it's not > an error condition for it to simply do nothing. Something like below? Will --->8 >From 4d9dcb9210c1f37435b6088284e04b6b36ee8c4d Mon Sep 17 00:00:00 2001 From: Will Deacon Date: Fri, 2 Jul 2021 14:13:28 +0100 Subject: [PATCH] of: Return success from of_dma_set_restricted_buffer() when !OF_ADDRESS When CONFIG_OF_ADDRESS=n, of_dma_set_restricted_buffer() returns -ENODEV and breaks the boot for sparc[64] machines. Return 0 instead, since the function is essentially a glorified NOP in this configuration. Cc: Claire Chang Cc: Konrad Rzeszutek Wilk Reported-by: Guenter Roeck Suggested-by: Robin Murphy Link: https://lore.kernel.org/r/20210702030807.ga2685...@roeck-us.net Signed-off-by: Will Deacon --- drivers/of/of_private.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/of/of_private.h b/drivers/of/of_private.h index 8fde97565d11..34dd548c5eac 100644 --- a/drivers/of/of_private.h +++ b/drivers/of/of_private.h @@ -173,7 +173,8 @@ static inline int of_dma_get_range(struct device_node *np, static inline int of_dma_set_restricted_buffer(struct device *dev, struct device_node *np) { - return -ENODEV; + /* Do nothing, successfully. */ + return 0; } #endif -- 2.32.0.93.g670b81a890-goog
Re: [PATCH v15 06/12] swiotlb: Use is_swiotlb_force_bounce for swiotlb data bouncing
Hi Nathan, On Thu, Jul 01, 2021 at 12:52:20AM -0700, Nathan Chancellor wrote: > On 7/1/2021 12:40 AM, Will Deacon wrote: > > On Wed, Jun 30, 2021 at 08:56:51AM -0700, Nathan Chancellor wrote: > > > On Wed, Jun 30, 2021 at 12:43:48PM +0100, Will Deacon wrote: > > > > On Wed, Jun 30, 2021 at 05:17:27PM +0800, Claire Chang wrote: > > > > > `BUG: unable to handle page fault for address: 003a8290` and > > > > > the fact it crashed at `_raw_spin_lock_irqsave` look like the memory > > > > > (maybe dev->dma_io_tlb_mem) was corrupted? > > > > > The dev->dma_io_tlb_mem should be set here > > > > > (https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/tree/drivers/pci/probe.c#n2528) > > > > > through device_initialize. > > > > > > > > I'm less sure about this. 'dma_io_tlb_mem' should be pointing at > > > > 'io_tlb_default_mem', which is a page-aligned allocation from memblock. > > > > The spinlock is at offset 0x24 in that structure, and looking at the > > > > register dump from the crash: > > > > > > > > Jun 29 18:28:42 hp-4300G kernel: RSP: 0018:adb4013db9e8 EFLAGS: > > > > 00010006 > > > > Jun 29 18:28:42 hp-4300G kernel: RAX: 003a8290 RBX: > > > > RCX: 8900572ad580 > > > > Jun 29 18:28:42 hp-4300G kernel: RDX: 89005653f024 RSI: > > > > 000c RDI: 1d17 > > > > Jun 29 18:28:42 hp-4300G kernel: RBP: 0a20d000 R08: > > > > 000c R09: > > > > Jun 29 18:28:42 hp-4300G kernel: R10: 0a20d000 R11: > > > > 89005653f000 R12: 0212 > > > > Jun 29 18:28:42 hp-4300G kernel: R13: 1000 R14: > > > > 0002 R15: 0020 > > > > Jun 29 18:28:42 hp-4300G kernel: FS: 7f1f8898ea40() > > > > GS:89005728() knlGS: > > > > Jun 29 18:28:42 hp-4300G kernel: CS: 0010 DS: ES: CR0: > > > > 80050033 > > > > Jun 29 18:28:42 hp-4300G kernel: CR2: 003a8290 CR3: > > > > 0001020d CR4: 00350ee0 > > > > Jun 29 18:28:42 hp-4300G kernel: Call Trace: > > > > Jun 29 18:28:42 hp-4300G kernel: _raw_spin_lock_irqsave+0x39/0x50 > > > > Jun 29 18:28:42 hp-4300G kernel: swiotlb_tbl_map_single+0x12b/0x4c0 > > > > > > > > Then that correlates with R11 holding the 'dma_io_tlb_mem' pointer and > > > > RDX pointing at the spinlock. Yet RAX is holding junk :/ > > > > > > > > I agree that enabling KASAN would be a good idea, but I also think we > > > > probably need to get some more information out of > > > > swiotlb_tbl_map_single() > > > > to see see what exactly is going wrong in there. > > > > > > I can certainly enable KASAN and if there is any debug print I can add > > > or dump anything, let me know! > > > > I bit the bullet and took v5.13 with swiotlb/for-linus-5.14 merged in, built > > x86 defconfig and ran it on my laptop. However, it seems to work fine! > > > > Please can you share your .config? > > Sure thing, it is attached. It is just Arch Linux's config run through > olddefconfig. The original is below in case you need to diff it. > > https://raw.githubusercontent.com/archlinux/svntogit-packages/9045405dc835527164f3034b3ceb9a67c7a53cd4/trunk/config > > If there is anything more that I can provide, please let me know. I eventually got this booting (for some reason it was causing LD to SEGV trying to link it for a while...) and sadly it works fine on my laptop. Hmm. Did you manage to try again with KASAN? It might also be worth taking the IOMMU out of the equation, since that interfaces differently with SWIOTLB and I couldn't figure out the code path from the log you provided. What happens if you boot with "amd_iommu=off swiotlb=force"? (although word of warning here: i915 dies horribly on my laptop if I pass swiotlb=force, even with the distro 5.10 kernel) Will
Re: [PATCH v15 06/12] swiotlb: Use is_swiotlb_force_bounce for swiotlb data bouncing
Hi Nathan, I may have just spotted something in these logs... On Fri, Jul 02, 2021 at 10:55:17PM -0700, Nathan Chancellor wrote: > [2.340956] pci :0c:00.1: Adding to iommu group 4 > [2.340996] pci :0c:00.2: Adding to iommu group 4 > [2.341038] pci :0c:00.3: Adding to iommu group 4 > [2.341078] pci :0c:00.4: Adding to iommu group 4 > [2.341122] pci :0c:00.6: Adding to iommu group 4 > [2.341163] pci :0d:00.0: Adding to iommu group 4 > [2.341203] pci :0d:00.1: Adding to iommu group 4 > [2.361821] pci :00:00.2: AMD-Vi: Found IOMMU cap 0x40 > [2.361839] pci :00:00.2: AMD-Vi: Extended features > (0x206d73ef22254ade): > [2.361846] PPR X2APIC NX GT IA GA PC GA_vAPIC > [2.361861] AMD-Vi: Interrupt remapping enabled > [2.361865] AMD-Vi: Virtual APIC enabled > [2.361870] AMD-Vi: X2APIC enabled > [2.362272] AMD-Vi: Lazy IO/TLB flushing enabled So at this point, the AMD IOMMU driver does: swiotlb= (iommu_default_passthrough() || sme_me_mask) ? 1 : 0; where 'swiotlb' is a global variable indicating whether or not swiotlb is in use. It's picked up a bit later on by pci_swiotlb_late_init(), which will call swiotlb_exit() if 'swiotlb' is false. Now, that used to work fine, because swiotlb_exit() clears 'io_tlb_default_mem' to NULL, but now with the restricted DMA changes, I think that all the devices which have successfully probed beforehand will have stale pointers to the freed structure in their 'dev->dma_io_tlb_mem' field. Will
Re: [Xen-devel] [PATCH v5 3/6] arm64: remove uaccess_ttbr0 asm macros from cache functions
On Thu, Jan 02, 2020 at 04:13:54PM -0500, Pavel Tatashin wrote: > We currently duplicate the logic to enable/disable uaccess via TTBR0, > with C functions and assembly macros. This is a maintenenace burden > and is liable to lead to subtle bugs, so let's get rid of the assembly > macros, and always use the C functions. This requires refactoring > some assembly functions to have a C wrapper. > > Signed-off-by: Pavel Tatashin > --- > arch/arm64/include/asm/asm-uaccess.h | 22 > arch/arm64/include/asm/cacheflush.h | 39 +--- > arch/arm64/mm/cache.S| 36 ++--- > arch/arm64/mm/flush.c| 2 +- > 4 files changed, 50 insertions(+), 49 deletions(-) > > diff --git a/arch/arm64/include/asm/asm-uaccess.h > b/arch/arm64/include/asm/asm-uaccess.h > index f68a0e64482a..fba2a69f7fef 100644 > --- a/arch/arm64/include/asm/asm-uaccess.h > +++ b/arch/arm64/include/asm/asm-uaccess.h > @@ -34,28 +34,6 @@ > msr ttbr0_el1, \tmp1// set the non-PAN TTBR0_EL1 > isb > .endm > - > - .macro uaccess_ttbr0_disable, tmp1, tmp2 > -alternative_if_not ARM64_HAS_PAN > - save_and_disable_irq \tmp2 // avoid preemption > - __uaccess_ttbr0_disable \tmp1 > - restore_irq \tmp2 > -alternative_else_nop_endif > - .endm > - > - .macro uaccess_ttbr0_enable, tmp1, tmp2, tmp3 > -alternative_if_not ARM64_HAS_PAN > - save_and_disable_irq \tmp3 // avoid preemption > - __uaccess_ttbr0_enable \tmp1, \tmp2 > - restore_irq \tmp3 > -alternative_else_nop_endif > - .endm > -#else > - .macro uaccess_ttbr0_disable, tmp1, tmp2 > - .endm > - > - .macro uaccess_ttbr0_enable, tmp1, tmp2, tmp3 > - .endm > #endif > > #endif > diff --git a/arch/arm64/include/asm/cacheflush.h > b/arch/arm64/include/asm/cacheflush.h > index 665c78e0665a..cb00c61e0bde 100644 > --- a/arch/arm64/include/asm/cacheflush.h > +++ b/arch/arm64/include/asm/cacheflush.h > @@ -61,16 +61,49 @@ > * - kaddr - page address > * - size - region size > */ > -extern void __flush_icache_range(unsigned long start, unsigned long end); > -extern int invalidate_icache_range(unsigned long start, unsigned long end); > +extern void __asm_flush_icache_range(unsigned long start, unsigned long end); > +extern long __asm_flush_cache_user_range(unsigned long start, > + unsigned long end); > +extern int __asm_invalidate_icache_range(unsigned long start, > + unsigned long end); > extern void __flush_dcache_area(void *addr, size_t len); > extern void __inval_dcache_area(void *addr, size_t len); > extern void __clean_dcache_area_poc(void *addr, size_t len); > extern void __clean_dcache_area_pop(void *addr, size_t len); > extern void __clean_dcache_area_pou(void *addr, size_t len); > -extern long __flush_cache_user_range(unsigned long start, unsigned long end); > extern void sync_icache_aliases(void *kaddr, unsigned long len); > > +static inline long __flush_cache_user_range(unsigned long start, > + unsigned long end) > +{ > + int ret; > + > + uaccess_ttbr0_enable(); > + ret = __asm_flush_cache_user_range(start, end); > + uaccess_ttbr0_disable(); > + > + return ret; > +} > + > +static inline void __flush_icache_range(unsigned long start, unsigned long > end) > +{ > + uaccess_ttbr0_enable(); > + __asm_flush_icache_range(start, end); > + uaccess_ttbr0_disable(); > +} Interesting... I don't think we should be enabling uaccess here: the function has a void return type so we can't communicate failure back to the caller if we fault, so my feeling is that this should only ever be called on kernel addresses. > + > +static inline int invalidate_icache_range(unsigned long start, > + unsigned long end) > +{ > + int ret; > + > + uaccess_ttbr0_enable(); > + ret = __asm_invalidate_icache_range(start, end); > + uaccess_ttbr0_disable(); > + > + return ret; > +} Same here -- I don't think think this is ever called on user addresses. Can we make the return type void and drop the uaccess toggle? Will ___ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel
Re: [Xen-devel] [PATCH v5 5/6] arm64: move ARM64_HAS_CACHE_DIC/_IDC from asm to C
On Thu, Jan 02, 2020 at 04:13:56PM -0500, Pavel Tatashin wrote: > The assmbly functions __asm_flush_cache_user_range and > __asm_invalidate_icache_range have alternatives: > > alternative_if ARM64_HAS_CACHE_DIC > ... > > alternative_if ARM64_HAS_CACHE_IDC > ... > > But, the implementation of those alternatives is trivial and therefore > can be done in the C inline wrappers. > > Signed-off-by: Pavel Tatashin > --- > arch/arm64/include/asm/cacheflush.h | 19 +++ > arch/arm64/mm/cache.S | 27 +-- > arch/arm64/mm/flush.c | 1 + > 3 files changed, 25 insertions(+), 22 deletions(-) > > diff --git a/arch/arm64/include/asm/cacheflush.h > b/arch/arm64/include/asm/cacheflush.h > index 047af338ba15..fc5217a18398 100644 > --- a/arch/arm64/include/asm/cacheflush.h > +++ b/arch/arm64/include/asm/cacheflush.h > @@ -77,8 +77,22 @@ static inline long __flush_cache_user_range(unsigned long > start, > { > int ret; > > + if (cpus_have_const_cap(ARM64_HAS_CACHE_IDC)) { > + dsb(ishst); > + if (cpus_have_const_cap(ARM64_HAS_CACHE_DIC)) { > + isb(); > + return 0; > + } > + } > + > uaccess_ttbr0_enable(); > ret = __asm_flush_cache_user_range(start, end); I don't understand this. Doesn't it mean a CPU with IDC but not DIC will end up with doing the D-cache maintenance? Will ___ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel
Re: [Xen-devel] [PATCH 11/11] arm64: use asm-generic/dma-mapping.h
On Fri, Aug 16, 2019 at 03:00:13PM +0200, Christoph Hellwig wrote: > Now that the Xen special cases are gone nothing worth mentioning is > left in the arm64 file, so switch to use the > asm-generic version instead. > > Signed-off-by: Christoph Hellwig > --- > arch/arm64/include/asm/Kbuild| 1 + > arch/arm64/include/asm/dma-mapping.h | 22 -- > arch/arm64/mm/dma-mapping.c | 1 + > 3 files changed, 2 insertions(+), 22 deletions(-) > delete mode 100644 arch/arm64/include/asm/dma-mapping.h Acked-by: Will Deacon Thanks for cleaning this up. Will ___ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel
Re: [Xen-devel] [PATCH v2] arm64: xen: Use modern annotations for assembly functions
On Thu, Dec 19, 2019 at 01:07:50PM -0800, Stefano Stabellini wrote: > On Thu, 19 Dec 2019, Mark Brown wrote: > > In an effort to clarify and simplify the annotation of assembly functions > > in the kernel new macros have been introduced. These replace ENTRY and > > ENDPROC. Update the annotations in the xen code to the new macros. > > > > Signed-off-by: Mark Brown > > Reviewed-by: Julien Grall > > Reviewed-by: Stefano Stabellini > > Thank you! > > > --- > > arch/arm64/xen/hypercall.S | 8 > > 1 file changed, 4 insertions(+), 4 deletions(-) Is this going via the Xen tree, or shall I queue it along with the other asm annotation patches in the arm64 tree? I don't see it in -next yet. Cheers, Will ___ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel
Re: [Xen-devel] [PATCH v2] arm64: xen: Use modern annotations for assembly functions
On Thu, Jan 09, 2020 at 08:33:37AM -0800, Stefano Stabellini wrote: > On Thu, 9 Jan 2020, Catalin Marinas wrote: > > On Wed, Jan 08, 2020 at 03:55:52PM +0000, Will Deacon wrote: > > > On Thu, Dec 19, 2019 at 01:07:50PM -0800, Stefano Stabellini wrote: > > > > On Thu, 19 Dec 2019, Mark Brown wrote: > > > > > In an effort to clarify and simplify the annotation of assembly > > > > > functions > > > > > in the kernel new macros have been introduced. These replace ENTRY and > > > > > ENDPROC. Update the annotations in the xen code to the new macros. > > > > > > > > > > Signed-off-by: Mark Brown > > > > > Reviewed-by: Julien Grall > > > > > Reviewed-by: Stefano Stabellini > > > > > > > > Thank you! > > > > > > > > > --- > > > > > arch/arm64/xen/hypercall.S | 8 > > > > > 1 file changed, 4 insertions(+), 4 deletions(-) > > > > > > Is this going via the Xen tree, or shall I queue it along with the other > > > asm annotation patches in the arm64 tree? I don't see it in -next yet. > > > > Since it has been reviewed by the Xen maintainers, just queue it via the > > arm64 tree. > > Yes, that's fine by me Done. Will update the branch tomorrow. Cheers, Will ___ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel