lkml.org 
[lkml]   [2018]   [Nov]   [29]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    Subject[RFC v3 08/19] arch: um: add shim to trap to allow installing a fault catcher for tests
    From
    Add context to current thread that allows a test to specify that it
    wants to skip the normal checks to run an installed fault catcher.

    Signed-off-by: Brendan Higgins <brendanhiggins@google.com>
    ---
    arch/um/include/asm/processor-generic.h | 4 +++-
    arch/um/kernel/trap.c | 15 +++++++++++----
    2 files changed, 14 insertions(+), 5 deletions(-)

    diff --git a/arch/um/include/asm/processor-generic.h b/arch/um/include/asm/processor-generic.h
    index b58b746d3f2ca..d566cd416ff02 100644
    --- a/arch/um/include/asm/processor-generic.h
    +++ b/arch/um/include/asm/processor-generic.h
    @@ -27,6 +27,7 @@ struct thread_struct {
    struct task_struct *prev_sched;
    struct arch_thread arch;
    jmp_buf switch_buf;
    + bool is_running_test;
    struct {
    int op;
    union {
    @@ -51,7 +52,8 @@ struct thread_struct {
    .fault_addr = NULL, \
    .prev_sched = NULL, \
    .arch = INIT_ARCH_THREAD, \
    - .request = { 0 } \
    + .request = { 0 }, \
    + .is_running_test = false, \
    }

    static inline void release_thread(struct task_struct *task)
    diff --git a/arch/um/kernel/trap.c b/arch/um/kernel/trap.c
    index cced829460427..bf90e678b3d71 100644
    --- a/arch/um/kernel/trap.c
    +++ b/arch/um/kernel/trap.c
    @@ -201,6 +201,12 @@ void segv_handler(int sig, struct siginfo *unused_si, struct uml_pt_regs *regs)
    segv(*fi, UPT_IP(regs), UPT_IS_USER(regs), regs);
    }

    +static void segv_run_catcher(jmp_buf *catcher, void *fault_addr)
    +{
    + current->thread.fault_addr = fault_addr;
    + UML_LONGJMP(catcher, 1);
    +}
    +
    /*
    * We give a *copy* of the faultinfo in the regs to segv.
    * This must be done, since nesting SEGVs could overwrite
    @@ -219,7 +225,10 @@ unsigned long segv(struct faultinfo fi, unsigned long ip, int is_user,
    if (!is_user && regs)
    current->thread.segv_regs = container_of(regs, struct pt_regs, regs);

    - if (!is_user && (address >= start_vm) && (address < end_vm)) {
    + catcher = current->thread.fault_catcher;
    + if (catcher && current->thread.is_running_test)
    + segv_run_catcher(catcher, (void *) address);
    + else if (!is_user && (address >= start_vm) && (address < end_vm)) {
    flush_tlb_kernel_vm();
    goto out;
    }
    @@ -246,12 +255,10 @@ unsigned long segv(struct faultinfo fi, unsigned long ip, int is_user,
    address = 0;
    }

    - catcher = current->thread.fault_catcher;
    if (!err)
    goto out;
    else if (catcher != NULL) {
    - current->thread.fault_addr = (void *) address;
    - UML_LONGJMP(catcher, 1);
    + segv_run_catcher(catcher, (void *) address);
    }
    else if (current->thread.fault_addr != NULL)
    panic("fault_addr set but no fault catcher");
    --
    2.20.0.rc0.387.gc7a69e6b6c-goog
    \
     
     \ /
      Last update: 2018-11-28 20:40    [W:2.920 / U:0.168 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site