lkml.org 
[lkml]   [2020]   [Nov]   [11]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH v2 2/8] powernv/memtrace: fix crashing the kernel when enabling concurrently
    Date
    It's very easy to crash the kernel right now by simply trying to enable
    memtrace concurrently, hammering on the "enable" interface

    loop.sh:
    #!/bin/bash

    dmesg --console-off

    while true; do
    echo 0x40000000 > /sys/kernel/debug/powerpc/memtrace/enable
    done

    [root@localhost ~]# loop.sh &
    [root@localhost ~]# loop.sh &

    Resulting quickly in a kernel crash. Let's properly protect using a
    mutex.

    Fixes: 9d5171a8f248 ("powerpc/powernv: Enable removal of memory for in memory tracing")
    Cc: stable@vger.kernel.org# v4.14+
    Cc: Michael Ellerman <mpe@ellerman.id.au>
    Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
    Cc: Paul Mackerras <paulus@samba.org>
    Cc: Rashmica Gupta <rashmica.g@gmail.com>
    Signed-off-by: David Hildenbrand <david@redhat.com>
    ---
    arch/powerpc/platforms/powernv/memtrace.c | 22 +++++++++++++++-------
    1 file changed, 15 insertions(+), 7 deletions(-)

    diff --git a/arch/powerpc/platforms/powernv/memtrace.c b/arch/powerpc/platforms/powernv/memtrace.c
    index eea1f94482ff..0e42fe2d7b6a 100644
    --- a/arch/powerpc/platforms/powernv/memtrace.c
    +++ b/arch/powerpc/platforms/powernv/memtrace.c
    @@ -30,6 +30,7 @@ struct memtrace_entry {
    char name[16];
    };

    +static DEFINE_MUTEX(memtrace_mutex);
    static u64 memtrace_size;

    static struct memtrace_entry *memtrace_array;
    @@ -279,6 +280,7 @@ static int memtrace_online(void)

    static int memtrace_enable_set(void *data, u64 val)
    {
    + int rc = -EAGAIN;
    u64 bytes;

    /*
    @@ -291,25 +293,31 @@ static int memtrace_enable_set(void *data, u64 val)
    return -EINVAL;
    }

    + mutex_lock(&memtrace_mutex);
    +
    /* Re-add/online previously removed/offlined memory */
    if (memtrace_size) {
    if (memtrace_online())
    - return -EAGAIN;
    + goto out_unlock;
    }

    - if (!val)
    - return 0;
    + if (!val) {
    + rc = 0;
    + goto out_unlock;
    + }

    /* Offline and remove memory */
    if (memtrace_init_regions_runtime(val))
    - return -EINVAL;
    + goto out_unlock;

    if (memtrace_init_debugfs())
    - return -EINVAL;
    + goto out_unlock;

    memtrace_size = val;
    -
    - return 0;
    + rc = 0;
    +out_unlock:
    + mutex_unlock(&memtrace_mutex);
    + return rc;
    }

    static int memtrace_enable_get(void *data, u64 *val)
    --
    2.26.2
    \
     
     \ /
      Last update: 2020-11-11 15:54    [W:3.271 / U:0.004 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site