Skip to content
  • Thomas Petazzoni's avatar
    net: phy: mdio_bus: add missing device_del() in mdiobus_register() error handling · e40e2a2e
    Thomas Petazzoni authored
    The current code in __mdiobus_register() doesn't properly handle
    failures returned by the devm_gpiod_get_optional() call: it returns
    immediately, without unregistering the device that was added by the
    call to device_register() earlier in the function.
    
    This leaves a stale device, which then causes a NULL pointer
    dereference in the code that handles deferred probing:
    
    [    1.489982] Unable to handle kernel NULL pointer dereference at virtual address 00000074
    [    1.498110] pgd = (ptrval)
    [    1.500838] [00000074] *pgd=00000000
    [    1.504432] Internal error: Oops: 17 [#1] SMP ARM
    [    1.509133] Modules linked in:
    [    1.512192] CPU: 1 PID: 51 Comm: kworker/1:3 Not tainted 4.20.0-00039-g3b73a4cc8b3e-dirty #99
    [    1.520708] Hardware name: Xilinx Zynq Platform
    [    1.525261] Workqueue: events deferred_probe_work_func
    [    1.530403] PC is at klist_next+0x10/0xfc
    [    1.534403] LR is at device_for_each_child+0x40/0x94
    [    1.539361] pc : [<c0683fbc>]    lr : [<c0455d90>]    psr: 200e0013
    [    1.545628] sp : ceeefe68  ip : 00000001  fp : ffffe000
    [    1.550863] r10: 00000000  r9 : c0c66790  r8 : 00000000
    [    1.556079] r7 : c0457d44  r6 : 00000000  r5 : ceeefe8c  r4 : cfa2ec78
    [    1.562604] r3 : 00000064  r2 : c0457d44  r1 : ceeefe8c  r0 : 00000064
    [    1.569129] Flags: nzCv  IRQs on  FIQs on  Mode SVC_32  ISA ARM  Segment none
    [    1.576263] Control: 18c5387d  Table: 0ed7804a  DAC: 00000051
    [    1.582013] Process kworker/1:3 (pid: 51, stack limit = 0x(ptrval))
    [    1.588280] Stack: (0xceeefe68 to 0xceef0000)
    [    1.592630] fe60:                   cfa2ec78 c0c03c08 00000000 c0457d44 00000000 c0c66790
    [    1.600814] fe80: 00000000 c0455d90 ceeefeac 00000064 00000000 0d7a542e cee9d494 cfa2ec78
    [    1.608998] fea0: cfa2ec78 00000000 c0457d44 c0457d7c cee9d494 c0c03c08 00000000 c0455dac
    [    1.617182] fec0: cf98ba44 cf926a00 cee9d494 0d7a542e 00000000 cf935a10 cf935a10 cf935a10
    [    1.625366] fee0: c0c4e9b8 c0457d7c c0c4e80c 00000001 cf935a10 c0457df4 cf935a10 c0c4e99c
    [    1.633550] ff00: c0c4e99c c045a27c c0c4e9c4 ced63f80 cfde8a80 cfdebc00 00000000 c013893c
    [    1.641734] ff20: cfde8a80 cfde8a80 c07bd354 ced63f80 ced63f94 cfde8a80 00000008 c0c02d00
    [    1.649936] ff40: cfde8a98 cfde8a80 ffffe000 c0139a30 ffffe000 c0c6624a c07bd354 00000000
    [    1.658120] ff60: ffffe000 cee9e780 ceebfe00 00000000 ceeee000 ced63f80 c0139788 cf8cdea4
    [    1.666304] ff80: cee9e79c c013e598 00000001 ceebfe00 c013e44c 00000000 00000000 00000000
    [    1.674488] ffa0: 00000000 00000000 00000000 c01010e8 00000000 00000000 00000000 00000000
    [    1.682671] ffc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
    [    1.690855] ffe0: 00000000 00000000 00000000 00000000 00000013 00000000 00000000 00000000
    [    1.699058] [<c0683fbc>] (klist_next) from [<c0455d90>] (device_for_each_child+0x40/0x94)
    [    1.707241] [<c0455d90>] (device_for_each_child) from [<c0457d7c>] (device_reorder_to_tail+0x38/0x88)
    [    1.716476] [<c0457d7c>] (device_reorder_to_tail) from [<c0455dac>] (device_for_each_child+0x5c/0x94)
    [    1.725692] [<c0455dac>] (device_for_each_child) from [<c0457d7c>] (device_reorder_to_tail+0x38/0x88)
    [    1.734927] [<c0457d7c>] (device_reorder_to_tail) from [<c0457df4>] (device_pm_move_to_tail+0x28/0x40)
    [    1.744235] [<c0457df4>] (device_pm_move_to_tail) from [<c045a27c>] (deferred_probe_work_func+0x58/0x8c)
    [    1.753746] [<c045a27c>] (deferred_probe_work_func) from [<c013893c>] (process_one_work+0x210/0x4fc)
    [    1.762888] [<c013893c>] (process_one_work) from [<c0139a30>] (worker_thread+0x2a8/0x5c0)
    [    1.771072] [<c0139a30>] (worker_thread) from [<c013e598>] (kthread+0x14c/0x154)
    [    1.778482] [<c013e598>] (kthread) from [<c01010e8>] (ret_from_fork+0x14/0x2c)
    [    1.785689] Exception stack(0xceeeffb0 to 0xceeefff8)
    [    1.790739] ffa0:                                     00000000 00000000 00000000 00000000
    [    1.798923] ffc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
    [    1.807107] ffe0: 00000000 00000000 00000000 00000000 00000013 00000000
    [    1.813724] Code: e92d47f0 e1a05000 e8900048 e1a00003 (e5937010)
    [    1.819844] ---[ end trace 3c2c0c8b65399ec9 ]---
    
    The actual error that we had from devm_gpiod_get_optional() was
    -EPROBE_DEFER, due to the GPIO being provided by a driver that is
    probed later than the Ethernet controller driver.
    
    To fix this, we simply add the missing device_del() invocation in the
    error path.
    
    Fixes: 69226896
    
     ("mdio_bus: Issue GPIO RESET to PHYs")
    Signed-off-by: default avatarThomas Petazzoni <thomas.petazzoni@bootlin.com>
    Reviewed-by: default avatarAndrew Lunn <andrew@lunn.ch>
    Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
    e40e2a2e