• Simon Guinot's avatar
    kernel/resource.c: fix muxed resource handling in __request_region() · a6d989cd
    Simon Guinot authored
    commit 59ceeaaf upstream.
    
    In __request_region, if a conflict with a BUSY and MUXED resource is
    detected, then the caller goes to sleep and waits for the resource to be
    released.  A pointer on the conflicting resource is kept.  At wake-up
    this pointer is used as a parent to retry to request the region.
    
    A first problem is that this pointer might well be invalid (if for
    example the conflicting resource have already been freed).  Another
    problem is that the next call to __request_region() fails to detect a
    remaining conflict.  The previously conflicting resource is passed as a
    parameter and __request_region() will look for a conflict among the
    children of this resource and not at the resource itself.  It is likely
    to succeed anyway, even if there is still a conflict.
    
    Instead, the parent of the conflicting resource should be passed to
    __request_region().
    
    As a fix, this patch doesn't update the parent resource pointer in the
    case we have to wait for a muxed region right after.
    Reported-and-tested-by: default avatarVincent Pelletier <plr.vincent@gmail.com>
    Signed-off-by: default avatarSimon Guinot <simon.guinot@sequanux.org>
    Tested-by: default avatarVincent Donnefort <vdonnefort@gmail.com>
    Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
    Signed-off-by: default avatarKamal Mostafa <kamal@canonical.com>
    a6d989cd
resource.c 31.8 KB