Received: by 2002:a25:d7c1:0:0:0:0:0 with SMTP id o184csp1100483ybg; Wed, 23 Oct 2019 10:20:40 -0700 (PDT) X-Google-Smtp-Source: APXvYqzHcX7lYwsXSQTn0GWaJlvYt4KOz3ASsMhvQgrTFGWGSUh+Oiy5uYliuMfk7PaWRvOba2kj X-Received: by 2002:a17:906:386:: with SMTP id b6mr33135091eja.148.1571851240522; Wed, 23 Oct 2019 10:20:40 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1571851240; cv=none; d=google.com; s=arc-20160816; b=IcH2fJSpceveD1l5S8LMgxUbIZR5h86a/I19ny++E01ssEzXUwS47jriKdkoRo94n/ NVwzAXFtMaBdmHaop33Rrg+0Tbx12zsunCGd8xgdGInGUPg/zaRTt9u7kTNJYEPO/2R1 u4e3zIiydH88pX/fFfDP6shAQI813GsWhb+zwzTxa0sZQDcS+9Gf06r4D7e6y2HT2T4s lk2D/hPri1ReM5bT+0nEFWQYa1qVpvvCQT55629c2d32xrApDaJkgaRS2ovz02ZkhWpn uYTxNfzTbiJpTxZ5KZhy+7nMJkG2fq2UDqnaWBrucLgsUyaPFc7mY678yKFzmhmpmnKG GVrw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:mime-version:references:subject:cc:to :from:date:user-agent:message-id; bh=YFkJD929M66yrLpxEf0LlPpJPdd2BU98ocE94Ajzrfc=; b=S3w4SutEGpLJgh2q5z/V7DGolShiMsuQGMENRqRMZ43rKVNq+cMOwvOuN+ngjy+WsM mC6/kqYJSvgua1IE2hl3HaHMaWtKueykVYwdI4eiRPsBgm45XLZoQOPlY1bXL6DfFfX2 SfLEiZBnbKF73ZEwjfTkkj2DR+I5l/IsERpof/fQq1DEC0bNOl0uqdx4TGn1t8p2vV5b Ho33LrDRc4bq7PPHoWHP6/aPRGWVbQ6CJxaZagTaEKLD7sDQU5FTTeHaxu0ph+lykrG0 r8chSecPIjf99Ytf3nFDBaza8ETnwkC0g/Rn3DH4TWKK6Knwy9S2YakdlOGDcLs7OqsA GSpQ== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id e50si10421603ede.59.2019.10.23.10.20.16; Wed, 23 Oct 2019 10:20:40 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2405363AbfJWMdG (ORCPT + 99 others); Wed, 23 Oct 2019 08:33:06 -0400 Received: from Galois.linutronix.de ([193.142.43.55]:49096 "EHLO Galois.linutronix.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2389772AbfJWMbl (ORCPT ); Wed, 23 Oct 2019 08:31:41 -0400 Received: from localhost ([127.0.0.1] helo=nanos.tec.linutronix.de) by Galois.linutronix.de with esmtp (Exim 4.80) (envelope-from ) id 1iNFnc-00017I-Ug; Wed, 23 Oct 2019 14:31:37 +0200 Message-Id: <20191023123118.084086112@linutronix.de> User-Agent: quilt/0.65 Date: Wed, 23 Oct 2019 14:27:10 +0200 From: Thomas Gleixner To: LKML Cc: x86@kernel.org, Peter Zijlstra , Andy Lutomirski , Will Deacon , Paolo Bonzini , kvm@vger.kernel.org, linux-arch@vger.kernel.org, Mike Rapoport , Josh Poimboeuf , Miroslav Benes Subject: [patch V2 05/17] x86/traps: Make interrupt enable/disable symmetric in C code References: <20191023122705.198339581@linutronix.de> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Traps enable interrupts conditionally but rely on the ASM return code to disable them again. That results in redundant interrupt disable and trace calls. Make the trap handlers disable interrupts before returning to avoid that, which allows simplification of the ASM entry code. Originally-by: Peter Zijlstra Signed-off-by: Thomas Gleixner --- arch/x86/kernel/traps.c | 32 +++++++++++++++++++++----------- arch/x86/mm/fault.c | 7 +++++-- 2 files changed, 26 insertions(+), 13 deletions(-) --- a/arch/x86/kernel/traps.c +++ b/arch/x86/kernel/traps.c @@ -276,6 +276,7 @@ static void do_error_trap(struct pt_regs NOTIFY_STOP) { cond_local_irq_enable(regs); do_trap(trapnr, signr, str, regs, error_code, sicode, addr); + cond_local_irq_disable(regs); } } @@ -501,6 +502,7 @@ dotraplinkage void do_bounds(struct pt_r die("bounds", regs, error_code); } + cond_local_irq_disable(regs); return; exit_trap: @@ -512,6 +514,7 @@ dotraplinkage void do_bounds(struct pt_r * time.. */ do_trap(X86_TRAP_BR, SIGSEGV, "bounds", regs, error_code, 0, NULL); + cond_local_irq_disable(regs); } dotraplinkage void @@ -525,19 +528,19 @@ do_general_protection(struct pt_regs *re if (static_cpu_has(X86_FEATURE_UMIP)) { if (user_mode(regs) && fixup_umip_exception(regs)) - return; + goto exit_trap; } if (v8086_mode(regs)) { local_irq_enable(); handle_vm86_fault((struct kernel_vm86_regs *) regs, error_code); - return; + goto exit_trap; } tsk = current; if (!user_mode(regs)) { if (fixup_exception(regs, X86_TRAP_GP, error_code, 0)) - return; + goto exit_trap; tsk->thread.error_code = error_code; tsk->thread.trap_nr = X86_TRAP_GP; @@ -549,12 +552,12 @@ do_general_protection(struct pt_regs *re */ if (!preemptible() && kprobe_running() && kprobe_fault_handler(regs, X86_TRAP_GP)) - return; + goto exit_trap; if (notify_die(DIE_GPF, desc, regs, error_code, X86_TRAP_GP, SIGSEGV) != NOTIFY_STOP) die(desc, regs, error_code); - return; + goto exit_trap; } tsk->thread.error_code = error_code; @@ -563,6 +566,8 @@ do_general_protection(struct pt_regs *re show_signal(tsk, SIGSEGV, "", desc, regs, error_code); force_sig(SIGSEGV); +exit_trap: + cond_local_irq_disable(regs); } NOKPROBE_SYMBOL(do_general_protection); @@ -783,9 +788,7 @@ dotraplinkage void do_debug(struct pt_re if (v8086_mode(regs)) { handle_vm86_trap((struct kernel_vm86_regs *) regs, error_code, X86_TRAP_DB); - cond_local_irq_disable(regs); - debug_stack_usage_dec(); - goto exit; + goto exit_irq; } if (WARN_ON_ONCE((dr6 & DR_STEP) && !user_mode(regs))) { @@ -802,6 +805,8 @@ dotraplinkage void do_debug(struct pt_re si_code = get_si_code(tsk->thread.debugreg6); if (tsk->thread.debugreg6 & (DR_STEP | DR_TRAP_BITS) || user_icebp) send_sigtrap(regs, error_code, si_code); + +exit_irq: cond_local_irq_disable(regs); debug_stack_usage_dec(); @@ -827,7 +832,7 @@ static void math_error(struct pt_regs *r if (!user_mode(regs)) { if (fixup_exception(regs, trapnr, error_code, 0)) - return; + goto exit_trap; task->thread.error_code = error_code; task->thread.trap_nr = trapnr; @@ -835,7 +840,7 @@ static void math_error(struct pt_regs *r if (notify_die(DIE_TRAP, str, regs, error_code, trapnr, SIGFPE) != NOTIFY_STOP) die(str, regs, error_code); - return; + goto exit_trap; } /* @@ -849,10 +854,12 @@ static void math_error(struct pt_regs *r si_code = fpu__exception_code(fpu, trapnr); /* Retry when we get spurious exceptions: */ if (!si_code) - return; + goto exit_trap; force_sig_fault(SIGFPE, si_code, (void __user *)uprobe_get_trap_addr(regs)); +exit_trap: + cond_local_irq_disable(regs); } dotraplinkage void do_coprocessor_error(struct pt_regs *regs, long error_code) @@ -888,6 +895,8 @@ do_device_not_available(struct pt_regs * info.regs = regs; math_emulate(&info); + + cond_local_irq_disable(regs); return; } #endif @@ -918,6 +927,7 @@ dotraplinkage void do_iret_error(struct do_trap(X86_TRAP_IRET, SIGILL, "iret exception", regs, error_code, ILL_BADSTK, (void __user *)NULL); } + local_irq_disable(); } #endif --- a/arch/x86/mm/fault.c +++ b/arch/x86/mm/fault.c @@ -1500,10 +1500,13 @@ static noinline void return; /* Was the fault on kernel-controlled part of the address space? */ - if (unlikely(fault_in_kernel_space(address))) + if (unlikely(fault_in_kernel_space(address))) { do_kern_addr_fault(regs, hw_error_code, address); - else + } else { do_user_addr_fault(regs, hw_error_code, address); + if (regs->flags & X86_EFLAGS_IF) + local_irq_disable(); + } } NOKPROBE_SYMBOL(__do_page_fault);