From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755509AbbCEULK (ORCPT ); Thu, 5 Mar 2015 15:11:10 -0500 Received: from mail-wi0-f180.google.com ([209.85.212.180]:39865 "EHLO mail-wi0-f180.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751500AbbCEULG (ORCPT ); Thu, 5 Mar 2015 15:11:06 -0500 Date: Thu, 5 Mar 2015 21:11:01 +0100 From: Ingo Molnar To: Oleg Nesterov Cc: Dave Hansen , Borislav Petkov , Andy Lutomirski , Linus Torvalds , Pekka Riikonen , Rik van Riel , Suresh Siddha , LKML , "Yu, Fenghua" , Quentin Casasnovas Subject: Re: [PATCH 1/1] x86/fpu: math_state_restore() should not blindly disable irqs Message-ID: <20150305201101.GA21571@gmail.com> References: <54F74F59.5070107@intel.com> <20150305195127.GA12657@redhat.com> <20150305195149.GB12657@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20150305195149.GB12657@redhat.com> User-Agent: Mutt/1.5.23 (2014-03-12) Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org * Oleg Nesterov wrote: > math_state_restore() assumes it is called with irqs disabled, but > this is not true if the caller is __restore_xstate_sig(). > > This means that if ia32_fxstate == T and __copy_from_user() fails > __restore_xstate_sig() returns with irqs disabled too. This trgiggers > > BUG: sleeping function called from invalid context at kernel/locking/rwsem.c:41 > [] dump_stack+0x59/0xa0 > [] ___might_sleep+0x105/0x110 > [] ? _raw_spin_unlock_irqrestore+0x3d/0x70 > [] __might_sleep+0x7d/0xb0 > [] down_read+0x26/0xa0 > [] ? _raw_spin_unlock_irqrestore+0x5a/0x70 > [] print_vma_addr+0x58/0x130 > [] signal_fault+0xbe/0xf0 > [] sys32_rt_sigreturn+0xba/0xd0 > > Change math_state_restore() to check irqs_disabled(). > > Note: this is the minimal fix for -stable, it is horrible but simple. > We need to rewrite math_state_restore(), init_fpu(), and cleanup their > users. > > Signed-off-by: Oleg Nesterov > Cc: > --- > arch/x86/kernel/traps.c | 9 +++++++-- > 1 files changed, 7 insertions(+), 2 deletions(-) > > diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c > index 51c4658..7310e0e 100644 > --- a/arch/x86/kernel/traps.c > +++ b/arch/x86/kernel/traps.c > @@ -774,7 +774,10 @@ void math_state_restore(void) > struct task_struct *tsk = current; > > if (!tsk_used_math(tsk)) { > - local_irq_enable(); > + bool disabled = irqs_disabled(); > + > + if (disabled) > + local_irq_enable(); > /* > * does a slab alloc which can sleep > */ > @@ -785,7 +788,9 @@ void math_state_restore(void) > do_group_exit(SIGKILL); > return; > } > - local_irq_disable(); > + > + if (disabled) > + local_irq_disable(); > } Yuck! Is there a fundamental reason why we cannot simply enable irqs and leave them enabled? Math state restore is not atomic and cannot really be atomic. [ A potential worry would be kernel code using vector instructions in irqs-off regions - but that's totally broken anyway so not a big worry IMO, we might even want to warn about it. ] But I might be missing something? Thanks, Ingo