lkml.org 
[lkml]   [2018]   [May]   [28]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 4.14 330/496] powerpc/fscr: Enable interrupts earlier before calling get_user()
    Date
    4.14-stable review patch.  If anyone has any objections, please let me know.

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

    From: Anshuman Khandual <khandual@linux.vnet.ibm.com>

    [ Upstream commit 709b973c844c0b4d115ac3a227a2e5a68722c912 ]

    The function get_user() can sleep while trying to fetch instruction
    from user address space and causes the following warning from the
    scheduler.

    BUG: sleeping function called from invalid context

    Though interrupts get enabled back but it happens bit later after
    get_user() is called. This change moves enabling these interrupts
    earlier covering the function get_user(). While at this, lets check
    for kernel mode and crash as this interrupt should not have been
    triggered from the kernel context.

    Signed-off-by: Anshuman Khandual <khandual@linux.vnet.ibm.com>
    Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
    Signed-off-by: Sasha Levin <alexander.levin@microsoft.com>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
    ---
    arch/powerpc/kernel/traps.c | 32 +++++++++++++++++---------------
    1 file changed, 17 insertions(+), 15 deletions(-)

    --- a/arch/powerpc/kernel/traps.c
    +++ b/arch/powerpc/kernel/traps.c
    @@ -1379,6 +1379,22 @@ void facility_unavailable_exception(stru
    value = mfspr(SPRN_FSCR);

    status = value >> 56;
    + if ((hv || status >= 2) &&
    + (status < ARRAY_SIZE(facility_strings)) &&
    + facility_strings[status])
    + facility = facility_strings[status];
    +
    + /* We should not have taken this interrupt in kernel */
    + if (!user_mode(regs)) {
    + pr_emerg("Facility '%s' unavailable (%d) exception in kernel mode at %lx\n",
    + facility, status, regs->nip);
    + die("Unexpected facility unavailable exception", regs, SIGABRT);
    + }
    +
    + /* We restore the interrupt state now */
    + if (!arch_irq_disabled_regs(regs))
    + local_irq_enable();
    +
    if (status == FSCR_DSCR_LG) {
    /*
    * User is accessing the DSCR register using the problem
    @@ -1445,25 +1461,11 @@ void facility_unavailable_exception(stru
    return;
    }

    - if ((hv || status >= 2) &&
    - (status < ARRAY_SIZE(facility_strings)) &&
    - facility_strings[status])
    - facility = facility_strings[status];
    -
    - /* We restore the interrupt state now */
    - if (!arch_irq_disabled_regs(regs))
    - local_irq_enable();
    -
    pr_err_ratelimited("%sFacility '%s' unavailable (%d), exception at 0x%lx, MSR=%lx\n",
    hv ? "Hypervisor " : "", facility, status, regs->nip, regs->msr);

    out:
    - if (user_mode(regs)) {
    - _exception(SIGILL, regs, ILL_ILLOPC, regs->nip);
    - return;
    - }
    -
    - die("Unexpected facility unavailable exception", regs, SIGABRT);
    + _exception(SIGILL, regs, ILL_ILLOPC, regs->nip);
    }
    #endif


    \
     
     \ /
      Last update: 2018-05-28 14:51    [W:4.027 / U:0.328 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site