• Eric Biggers's avatar
    /dev/mem: Add missing memory barriers for devmem_inode · b34e7e29
    Eric Biggers authored
    WRITE_ONCE() isn't the correct way to publish a pointer to a data
    structure, since it doesn't include a write memory barrier.  Therefore
    other tasks may see that the pointer has been set but not see that the
    pointed-to memory has finished being initialized yet.  Instead a
    primitive with "release" semantics is needed.
    
    Use smp_store_release() for this.
    
    The use of READ_ONCE() on the read side is still potentially correct if
    there's no control dependency, i.e. if all memory being "published" is
    transitively reachable via the pointer itself.  But this pairing is
    somewhat confusing and error-prone.  So just upgrade the read side to
    smp_load_acquire() so that it clearly pairs with smp_store_release().
    
    Cc: Arnd Bergmann <arnd@arndb.de>
    Cc: Ingo Molnar <mingo@redhat.com>
    Cc: Kees Cook <keescook@chromium.org>
    Cc: Matthew Wilcox <willy@infradead.org>
    Cc: Russell King <linux@arm.linux.org.uk>
    Cc: Andrew Morton <akpm@linux-foundation.org>
    Fixes: 3234ac66 ("/dev/mem: Revoke mappings when a driver claims the region")
    Signed-off-by: default avatarEric Biggers <ebiggers@google.com>
    Cc: stable <stable@vger.kernel.org>
    Acked-by: default avatarDan Williams <dan.j.williams@intel.com>
    Link: https://lore.kernel.org/r/20200716060553.24618-1-ebiggers@kernel.orgSigned-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
    b34e7e29
mem.c 23.1 KB