linux-uconsole/drivers/base
Geert Uytterhoeven 7053a6faf0 driver core: Postpone DMA tear-down until after devres release
commit 376991db4b upstream.

When unbinding the (IOMMU-enabled) R-Car SATA device on Salvator-XS
(R-Car H3 ES2.0), in preparation of rebinding against vfio-platform for
device pass-through for virtualization:

    echo ee300000.sata > /sys/bus/platform/drivers/sata_rcar/unbind

the kernel crashes with:

    Unable to handle kernel paging request at virtual address ffffffbf029ffffc
    Mem abort info:
      ESR = 0x96000006
      Exception class = DABT (current EL), IL = 32 bits
      SET = 0, FnV = 0
      EA = 0, S1PTW = 0
    Data abort info:
      ISV = 0, ISS = 0x00000006
      CM = 0, WnR = 0
    swapper pgtable: 4k pages, 39-bit VAs, pgdp = 000000007e8c586c
    [ffffffbf029ffffc] pgd=000000073bfc6003, pud=000000073bfc6003, pmd=0000000000000000
    Internal error: Oops: 96000006 [#1] SMP
    Modules linked in:
    CPU: 0 PID: 1098 Comm: bash Not tainted 5.0.0-rc5-salvator-x-00452-g37596f884f4318ef #287
    Hardware name: Renesas Salvator-X 2nd version board based on r8a7795 ES2.0+ (DT)
    pstate: 60400005 (nZCv daif +PAN -UAO)
    pc : __free_pages+0x8/0x58
    lr : __dma_direct_free_pages+0x50/0x5c
    sp : ffffff801268baa0
    x29: ffffff801268baa0 x28: 0000000000000000
    x27: ffffffc6f9c60bf0 x26: ffffffc6f9c60bf0
    x25: ffffffc6f9c60810 x24: 0000000000000000
    x23: 00000000fffff000 x22: ffffff8012145000
    x21: 0000000000000800 x20: ffffffbf029fffc8
    x19: 0000000000000000 x18: ffffffc6f86c42c8
    x17: 0000000000000000 x16: 0000000000000070
    x15: 0000000000000003 x14: 0000000000000000
    x13: ffffff801103d7f8 x12: 0000000000000028
    x11: ffffff8011117604 x10: 0000000000009ad8
    x9 : ffffff80110126d0 x8 : ffffffc6f7563000
    x7 : 6b6b6b6b6b6b6b6b x6 : 0000000000000018
    x5 : ffffff8011cf3cc8 x4 : 0000000000004000
    x3 : 0000000000080000 x2 : 0000000000000001
    x1 : 0000000000000000 x0 : ffffffbf029fffc8
    Process bash (pid: 1098, stack limit = 0x00000000c38e3e32)
    Call trace:
     __free_pages+0x8/0x58
     __dma_direct_free_pages+0x50/0x5c
     arch_dma_free+0x1c/0x98
     dma_direct_free+0x14/0x24
     dma_free_attrs+0x9c/0xdc
     dmam_release+0x18/0x20
     release_nodes+0x25c/0x28c
     devres_release_all+0x48/0x4c
     device_release_driver_internal+0x184/0x1f0
     device_release_driver+0x14/0x1c
     unbind_store+0x70/0xb8
     drv_attr_store+0x24/0x34
     sysfs_kf_write+0x4c/0x64
     kernfs_fop_write+0x154/0x1c4
     __vfs_write+0x34/0x164
     vfs_write+0xb4/0x16c
     ksys_write+0x5c/0xbc
     __arm64_sys_write+0x14/0x1c
     el0_svc_common+0x98/0x114
     el0_svc_handler+0x1c/0x24
     el0_svc+0x8/0xc
    Code: d51b4234 17fffffa a9bf7bfd 910003fd (b9403404)
    ---[ end trace 8c564cdd3a1a840f ]---

While I've bisected this to commit e8e683ae9a ("iommu/of: Fix
probe-deferral"), and reverting that commit on post-v5.0-rc4 kernels
does fix the problem, this turned out to be a red herring.

On arm64, arch_teardown_dma_ops() resets dev->dma_ops to NULL.
Hence if a driver has used a managed DMA allocation API, the allocated
DMA memory will be freed using the direct DMA ops, while it may have
been allocated using a custom DMA ops (iommu_dma_ops in this case).

Fix this by reversing the order of the calls to devres_release_all() and
arch_teardown_dma_ops().

Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
Acked-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Cc: stable <stable@vger.kernel.org>
Reviewed-by: Robin Murphy <robin.murphy@arm.com>
[rm: backport for 4.12-4.19 - kernels before 5.0 will not see
 the crash above, but may get silent memory corruption instead]
Signed-off-by: Robin Murphy <robin.murphy@arm.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2019-03-13 14:02:41 -07:00
..
firmware_loader firmware: Always initialize the fw_priv list object 2018-09-30 08:49:55 -07:00
power PM / core: Clear the direct_complete flag on errors 2018-10-04 19:39:31 +02:00
regmap regmap: Support non-incrementing registers 2018-08-09 11:15:06 +01:00
test driver core: Remove redundant license text 2017-12-07 18:36:44 +01:00
arch_topology.c Revert "base: arch_topology: fix section mismatch build warnings" 2018-03-15 14:36:20 +01:00
attribute_container.c driver core: Remove redundant license text 2017-12-07 18:36:44 +01:00
base.h driver core: remove unnecessary function extern declare 2018-07-16 13:32:20 +02:00
bus.c kobject: return error code if writing /sys/.../uevent fails 2019-02-12 19:47:06 +01:00
cacheinfo.c cacheinfo: Keep the old value if of_property_read_u32 fails 2019-02-12 19:47:26 +01:00
class.c driver core: Remove redundant license text 2017-12-07 18:36:44 +01:00
component.c component: add debugfs support 2017-12-18 16:51:11 +01:00
container.c driver core: Remove redundant license text 2017-12-07 18:36:44 +01:00
core.c kobject: return error code if writing /sys/.../uevent fails 2019-02-12 19:47:06 +01:00
cpu.c x86/speculation/l1tf: Add sysfs reporting for l1tf 2018-06-20 19:10:00 +02:00
dd.c driver core: Postpone DMA tear-down until after devres release 2019-03-13 14:02:41 -07:00
devcon.c drivers: base: Unified device connection lookup 2018-03-22 13:10:29 +01:00
devcoredump.c driver core: Remove redundant license text 2017-12-07 18:36:44 +01:00
devres.c devres: Align data[] to ARCH_KMALLOC_MINALIGN 2019-02-12 19:46:56 +01:00
devtmpfs.c kernel: add ksys_unshare() helper; remove in-kernel calls to sys_unshare() 2018-04-02 20:16:06 +02:00
driver.c driver-core: return EINVAL error instead of BUG_ON() 2018-05-25 18:18:45 +02:00
firmware.c driver core: Remove redundant license text 2017-12-07 18:36:44 +01:00
hypervisor.c driver core: Remove redundant license text 2017-12-07 18:36:44 +01:00
init.c base: fix order of OF initialization 2018-07-07 17:54:29 +02:00
isa.c Merge 4.15-rc3 into driver-core-next 2017-12-11 08:50:05 +01:00
Kconfig firmware_loader: move kconfig FW_LOADER entries to its own file 2018-05-14 16:43:10 +02:00
Makefile dma-mapping: move all DMA mapping code to kernel/dma 2018-06-14 08:50:37 +02:00
map.c driver core: Remove redundant license text 2017-12-07 18:36:44 +01:00
memory.c memory_hotplug: fix kernel_panic on offline page processing 2018-09-04 16:45:02 -07:00
module.c driver core: Remove redundant license text 2017-12-07 18:36:44 +01:00
node.c mm/memory_hotplug.c: drop unnecessary checks from register_mem_sect_under_node() 2018-08-17 16:20:29 -07:00
pinctrl.c driver core: Remove redundant license text 2017-12-07 18:36:44 +01:00
platform-msi.c platform-msi: Free descriptors in platform_msi_domain_free() 2019-01-09 17:38:42 +01:00
platform.c Power management updates for 4.18-rc1 2018-06-05 09:38:39 -07:00
property.c device property: Get rid of union aliasing 2018-05-17 12:47:21 +02:00
soc.c base: soc: use put_device() instead of kfree() 2018-03-15 14:37:03 +01:00
syscore.c driver core: Remove redundant license text 2017-12-07 18:36:44 +01:00
topology.c driver core: Remove redundant license text 2017-12-07 18:36:44 +01:00
transport_class.c driver core: Remove redundant license text 2017-12-07 18:36:44 +01:00