• Rasmus Villemoes's avatar
    soc: fsl: qe: refactor cpm_muram_alloc_common to prevent BUG on error path · ec2058ac
    Rasmus Villemoes authored
    If the kmalloc() fails, we try to undo the gen_pool allocation we've
    just done. Unfortunately, start has already been modified to subtract
    the GENPOOL_OFFSET bias, so we're freeing something that very likely
    doesn't exist in the gen_pool, meaning we hit the
    
     kernel BUG at lib/genalloc.c:399!
     Internal error: Oops - BUG: 0 [#1] PREEMPT SMP ARM
     ...
     [<803fd0e8>] (gen_pool_free) from [<80426bc8>] (cpm_muram_alloc_common+0xb0/0xc8)
     [<80426bc8>] (cpm_muram_alloc_common) from [<80426c28>] (cpm_muram_alloc+0x48/0x80)
     [<80426c28>] (cpm_muram_alloc) from [<80428214>] (ucc_slow_init+0x110/0x4f0)
     [<80428214>] (ucc_slow_init) from [<8044a718>] (qe_uart_request_port+0x3c/0x1d8)
    
    (this was tested by just injecting a random failure by adding
    "|| (get_random_int()&7) == 0" to the "if (!entry)" condition).
    
    Refactor the code so we do the kmalloc() first, meaning that's the
    thing that needs undoing in case gen_pool_alloc_algo() then
    fails. This allows a later cleanup to move the locking from the
    callers into the _common function, keeping the kmalloc() out of the
    critical region and then, hopefully (if all the muram_alloc callers
    allow) change it to a GFP_KERNEL allocation.
    Reviewed-by: default avatarTimur Tabi <timur@kernel.org>
    Signed-off-by: default avatarRasmus Villemoes <linux@rasmusvillemoes.dk>
    Signed-off-by: default avatarLi Yang <leoyang.li@nxp.com>
    ec2058ac
qe_common.c 5.99 KB