lkml.org 
[lkml]   [2021]   [Jun]   [21]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH v2 2/9] entry: snapshot thread flags
    Date
    Some thread flags can be set remotely, and so even when IRQs are
    disabled, the flags can change under our feet. Generally this is
    unlikely to cause a problem in practice, but it is somewhat unsound, and
    KCSAN will legitimately warn that there is a data race.

    To avoid such issues, a snapshot of the flags has to be taken prior to
    using them. Some places already use READ_ONCE() for that, others do not.

    Convert them all to the new flag accessor helpers.

    Signed-off-by: Mark Rutland <mark.rutland@arm.com>
    Cc: Andy Lutomirski <luto@kernel.org>
    Cc: Peter Zijlstra <peterz@infradead.org>
    Cc: Thomas Gleixner <tglx@linutronix.de>
    ---
    include/linux/entry-kvm.h | 2 +-
    kernel/entry/common.c | 4 ++--
    kernel/entry/kvm.c | 4 ++--
    3 files changed, 5 insertions(+), 5 deletions(-)

    diff --git a/include/linux/entry-kvm.h b/include/linux/entry-kvm.h
    index 8b2b1d68b954..bc487dffb803 100644
    --- a/include/linux/entry-kvm.h
    +++ b/include/linux/entry-kvm.h
    @@ -70,7 +70,7 @@ static inline void xfer_to_guest_mode_prepare(void)
    */
    static inline bool __xfer_to_guest_mode_work_pending(void)
    {
    - unsigned long ti_work = READ_ONCE(current_thread_info()->flags);
    + unsigned long ti_work = read_thread_flags();

    return !!(ti_work & XFER_TO_GUEST_MODE_WORK);
    }
    diff --git a/kernel/entry/common.c b/kernel/entry/common.c
    index a0b3b04fb596..3147a1f2ed74 100644
    --- a/kernel/entry/common.c
    +++ b/kernel/entry/common.c
    @@ -188,7 +188,7 @@ static unsigned long exit_to_user_mode_loop(struct pt_regs *regs,
    /* Check if any of the above work has queued a deferred wakeup */
    rcu_nocb_flush_deferred_wakeup();

    - ti_work = READ_ONCE(current_thread_info()->flags);
    + ti_work = read_thread_flags();
    }

    /* Return the latest work state for arch_exit_to_user_mode() */
    @@ -197,7 +197,7 @@ static unsigned long exit_to_user_mode_loop(struct pt_regs *regs,

    static void exit_to_user_mode_prepare(struct pt_regs *regs)
    {
    - unsigned long ti_work = READ_ONCE(current_thread_info()->flags);
    + unsigned long ti_work = read_thread_flags();

    lockdep_assert_irqs_disabled();

    diff --git a/kernel/entry/kvm.c b/kernel/entry/kvm.c
    index 49972ee99aff..96d476e06c77 100644
    --- a/kernel/entry/kvm.c
    +++ b/kernel/entry/kvm.c
    @@ -26,7 +26,7 @@ static int xfer_to_guest_mode_work(struct kvm_vcpu *vcpu, unsigned long ti_work)
    if (ret)
    return ret;

    - ti_work = READ_ONCE(current_thread_info()->flags);
    + ti_work = read_thread_flags();
    } while (ti_work & XFER_TO_GUEST_MODE_WORK || need_resched());
    return 0;
    }
    @@ -43,7 +43,7 @@ int xfer_to_guest_mode_handle_work(struct kvm_vcpu *vcpu)
    * disabled in the inner loop before going into guest mode. No need
    * to disable interrupts here.
    */
    - ti_work = READ_ONCE(current_thread_info()->flags);
    + ti_work = read_thread_flags();
    if (!(ti_work & XFER_TO_GUEST_MODE_WORK))
    return 0;

    --
    2.11.0
    \
     
     \ /
      Last update: 2021-06-21 11:06    [W:2.924 / U:1.120 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site