lkml.org 
[lkml]   [2017]   [Jun]   [12]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 4.9 109/119] arm64: hw_breakpoint: fix watchpoint matching for tagged pointers
    Date
    4.9-stable review patch.  If anyone has any objections, please let me know.

    ------------------

    From: Kristina Martsenko <kristina.martsenko@arm.com>

    commit 7dcd9dd8cebe9fa626af7e2358d03a37041a70fb upstream.

    This backport has a small difference from the upstream commit:
    - The address tag is removed in watchpoint_handler() instead of
    get_distance_from_watchpoint(), because 4.9 does not have commit
    fdfeff0f9e3d ("arm64: hw_breakpoint: Handle inexact watchpoint
    addresses").

    Original patch description:

    When we take a watchpoint exception, the address that triggered the
    watchpoint is found in FAR_EL1. We compare it to the address of each
    configured watchpoint to see which one was hit.

    The configured watchpoint addresses are untagged, while the address in
    FAR_EL1 will have an address tag if the data access was done using a
    tagged address. The tag needs to be removed to compare the address to
    the watchpoints.

    Currently we don't remove it, and as a result can report the wrong
    watchpoint as being hit (specifically, always either the highest TTBR0
    watchpoint or lowest TTBR1 watchpoint). This patch removes the tag.

    Fixes: d50240a5f6ce ("arm64: mm: permit use of tagged pointers at EL0")
    Acked-by: Mark Rutland <mark.rutland@arm.com>
    Acked-by: Will Deacon <will.deacon@arm.com>
    Signed-off-by: Kristina Martsenko <kristina.martsenko@arm.com>
    Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
    ---
    arch/arm64/include/asm/uaccess.h | 6 +++---
    arch/arm64/kernel/hw_breakpoint.c | 3 ++-
    2 files changed, 5 insertions(+), 4 deletions(-)

    --- a/arch/arm64/include/asm/uaccess.h
    +++ b/arch/arm64/include/asm/uaccess.h
    @@ -105,9 +105,9 @@ static inline void set_fs(mm_segment_t f
    })

    /*
    - * When dealing with data aborts or instruction traps we may end up with
    - * a tagged userland pointer. Clear the tag to get a sane pointer to pass
    - * on to access_ok(), for instance.
    + * When dealing with data aborts, watchpoints, or instruction traps we may end
    + * up with a tagged userland pointer. Clear the tag to get a sane pointer to
    + * pass on to access_ok(), for instance.
    */
    #define untagged_addr(addr) sign_extend64(addr, 55)

    --- a/arch/arm64/kernel/hw_breakpoint.c
    +++ b/arch/arm64/kernel/hw_breakpoint.c
    @@ -36,6 +36,7 @@
    #include <asm/traps.h>
    #include <asm/cputype.h>
    #include <asm/system_misc.h>
    +#include <asm/uaccess.h>

    /* Breakpoint currently in use for each BRP. */
    static DEFINE_PER_CPU(struct perf_event *, bp_on_reg[ARM_MAX_BRP]);
    @@ -696,7 +697,7 @@ static int watchpoint_handler(unsigned l

    /* Check if the watchpoint value matches. */
    val = read_wb_reg(AARCH64_DBG_REG_WVR, i);
    - if (val != (addr & ~alignment_mask))
    + if (val != (untagged_addr(addr) & ~alignment_mask))
    goto unlock;

    /* Possible match, check the byte address select to confirm. */

    \
     
     \ /
      Last update: 2017-06-12 17:38    [W:4.117 / U:0.068 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site