From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752917AbbICKmZ (ORCPT ); Thu, 3 Sep 2015 06:42:25 -0400 Received: from www.linutronix.de ([62.245.132.108]:46439 "EHLO Galois.linutronix.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751151AbbICKmY (ORCPT ); Thu, 3 Sep 2015 06:42:24 -0400 Date: Thu, 3 Sep 2015 12:41:47 +0200 (CEST) From: Thomas Gleixner To: Borislav Petkov cc: "Richard W.M. Jones" , Chuck Ebbert , linux-kernel@vger.kernel.org, x86@kernel.org, Ingo Molnar , "H. Peter Anvin" Subject: Re: [BUG 4.2-rc8] Interrupt occurs while apply_alternatives() is patching the handler In-Reply-To: <20150903085046.GA19397@nazgul.tnic> Message-ID: References: <20150830223757.6e4c5c02@as> <20150901062022.GA19002@redhat.com> <20150903085046.GA19397@nazgul.tnic> User-Agent: Alpine 2.11 (DEB 23 2013-08-11) MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII X-Linutronix-Spam-Score: -1.0 X-Linutronix-Spam-Level: - X-Linutronix-Spam-Status: No , -1.0 points, 5.0 required, ALL_TRUSTED=-1,SHORTCIRCUIT=-0.0001,URIBL_BLOCKED=0.001 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Thu, 3 Sep 2015, Borislav Petkov wrote: > On Wed, Sep 02, 2015 at 11:11:55AM +0200, Thomas Gleixner wrote: > > static void __init_or_module add_nops(void *insns, unsigned int len) > > { > > + unsigned long flags; > > + > > + local_irq_save(flags); > > while (len > 0) { > > I guess you want to optimize the len==0 case to not disable interrupts > needlessly: > > if (!len) > return; > > local_irq_save(flags); > while (len > 0) > ... Nah. I rather put the local_irq_save into optimize_nops(). All other callers of add_nops() are operating on a buffer and use text_poke after that. Aside of that optimize_nops() is missing a sync_core(). Updated patch below. Thanks, tglx -----------------> Subject: x86/alternatives: Make optimize_nops() interrupt safe and synced From: Thomas Gleixner Date: Thu, 03 Sep 2015 12:34:55 +0200 optimize_nops() is buggy in two aspects: - It's not disabling interrupts across the modification - It's lacking a sync_core() call Fixes: 4fd4b6e5537c 'x86/alternatives: Use optimized NOPs for padding' Reported-by: "Richard W.M. Jones" Signed-off-by: Thomas Gleixner --- arch/x86/kernel/alternative.c | 5 +++++ 1 file changed, 5 insertions(+) Index: tip/arch/x86/kernel/alternative.c =================================================================== --- tip.orig/arch/x86/kernel/alternative.c +++ tip/arch/x86/kernel/alternative.c @@ -338,10 +338,15 @@ done: static void __init_or_module optimize_nops(struct alt_instr *a, u8 *instr) { + unsigned long flags; + if (instr[0] != 0x90) return; + local_irq_save(flags); add_nops(instr + (a->instrlen - a->padlen), a->padlen); + sync_core(); + local_irq_restore(flags); DUMP_BYTES(instr, a->instrlen, "%p: [%d:%d) optimized NOPs: ", instr, a->instrlen - a->padlen, a->padlen);