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 <khand...@linux.vnet.ibm.com> --- arch/powerpc/kernel/traps.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c index 1e48d15..4d5a55e 100644 --- a/arch/powerpc/kernel/traps.c +++ b/arch/powerpc/kernel/traps.c @@ -1611,6 +1611,13 @@ void facility_unavailable_exception(struct pt_regs *regs) else value = mfspr(SPRN_FSCR); + /* We should not have taken this interrupt in kernel */ + BUG_ON(!user_mode(regs)); + + /* We restore the interrupt state now */ + if (!arch_irq_disabled_regs(regs)) + local_irq_enable(); + status = value >> 56; if (status == FSCR_DSCR_LG) { /* @@ -1683,10 +1690,6 @@ void facility_unavailable_exception(struct pt_regs *regs) 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); -- 2.9.3