From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from out30-132.freemail.mail.aliyun.com ([115.124.30.132]:58538 "EHLO out30-132.freemail.mail.aliyun.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752888AbeDLLTI (ORCPT ); Thu, 12 Apr 2018 07:19:08 -0400 Message-ID: <5ACF4099.9000104@linux.alibaba.com> Date: Thu, 12 Apr 2018 19:18:49 +0800 From: Qixuan Wu MIME-Version: 1.0 To: chenggang.qin@linux.alibaba.com, alikernel-developer@linux.alibaba.com CC: Andy Lutomirski , Borislav Petkov , Linus Torvalds , Peter Zijlstra , Thomas Gleixner , stable@vger.kernel.org, Ingo Molnar Subject: Re: [PATCH] x86/nmi: Enable nested do_nmi() handling for 64-bit kernels References: <1523509136-41469-1-git-send-email-chenggang.qin@linux.alibaba.com> In-Reply-To: <1523509136-41469-1-git-send-email-chenggang.qin@linux.alibaba.com> Content-Type: text/plain; charset=GB2312 Content-Transfer-Encoding: 7bit Sender: stable-owner@vger.kernel.org List-ID: Hi Chenggang, Have a doubt about the old code. On 2018/4/12 PM 12:58, chenggang.qin@linux.alibaba.com Wrote: > From: Andy Lutomirski > > commit: 9d05041679904b12c12421cbcf9cb5f4860a8d7b upstream > > 32-bit kernels handle nested NMIs in C. Enable the exact same > handling on 64-bit kernels as well. This isn't currently > necessary, but it will become necessary once the asm code starts > allowing limited nesting. > > ...... > -static inline void nmi_nesting_preprocess(struct pt_regs *regs) > +dotraplinkage notrace void > +do_nmi(struct pt_regs *regs, long error_code) > { > + if (this_cpu_read(nmi_state) != NMI_NOT_RUNNING) { > + this_cpu_write(nmi_state, NMI_LATCHED); > + return; > + } > + this_cpu_write(nmi_state, NMI_EXECUTING); > + this_cpu_write(nmi_cr2, read_cr2()); > +nmi_restart: > + Here if there are more than 2 NMIs nested, but the nmi_state is always NMI_LATCHED. > > - /* On i386, may loop back to preprocess */ > - nmi_nesting_postprocess(); > + if (unlikely(this_cpu_read(nmi_cr2) != read_cr2())) > + write_cr2(this_cpu_read(nmi_cr2)); > + if (this_cpu_dec_return(nmi_state)) > + goto nmi_restart; > } But here at most re-execute 2 NMIs, so some nmi lost ? And cr2 is always the first NMI's cr2. CR2 is wrong for the later NMIs. > void stop_nmi(void) > Thanks & Regards Qixuan Wu.