From patchwork Wed Jan 13 07:32:08 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nicholas Piggin X-Patchwork-Id: 1425685 Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4DG0RX4B44z9sS8 for ; Wed, 13 Jan 2021 19:07:36 +1100 (AEDT) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20161025 header.b=HE0KiTPP; dkim-atps=neutral Received: from bilbo.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 4DG0RX3G8RzDrTF for ; Wed, 13 Jan 2021 19:07:36 +1100 (AEDT) X-Original-To: linuxppc-dev@lists.ozlabs.org Delivered-To: linuxppc-dev@lists.ozlabs.org Authentication-Results: lists.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gmail.com (client-ip=2607:f8b0:4864:20::636; helo=mail-pl1-x636.google.com; envelope-from=npiggin@gmail.com; receiver=) Authentication-Results: lists.ozlabs.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: lists.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20161025 header.b=HE0KiTPP; dkim-atps=neutral Received: from mail-pl1-x636.google.com (mail-pl1-x636.google.com [IPv6:2607:f8b0:4864:20::636]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 4DFzgc2yhfzDqSC for ; Wed, 13 Jan 2021 18:32:59 +1100 (AEDT) Received: by mail-pl1-x636.google.com with SMTP id g3so595993plp.2 for ; Tue, 12 Jan 2021 23:32:59 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=p0meIkeGth02gQtyPnE+XC8e2+IlgiuL84Gr+gMj5mk=; b=HE0KiTPPINCb5dZkmMKDL+Z019MEt4UEUupRHRonvwYpbxL1ga3l5lL07oe4fYt3JN Xc39K+lPlkRjowmjIEJ584Q80WhVOzyuYLAJL90EN3nx23iKJgMkWKt+6uUKh6/kLzNi V5IJXMkPOWaFn/75k7+4/dgB6Z/m3A2+irVWY6R2Ui7hRq6iFA6kDIujZ9gCxNxWibA6 KN6Zn62Fz8+0Q1yvlCtDtiYVBiSbHG1YuSDnYksayvQCMO23MZKfOqOkV6Nhzd/1eH2y lRtxOJWkRSl3XLd7yF/+vSOmiS5XUOsafOOiszUJgS1XGMAfyQwnkBtHcWgfjM58MWGQ q7UQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=p0meIkeGth02gQtyPnE+XC8e2+IlgiuL84Gr+gMj5mk=; b=WSSENUy2CpUhx4tYeLdBUB3p+XdkPvgsW8P6BiTnVH2o9BU5iVeyAIMfg1QLe3GyYv kEpKmcGcXEBX6bWjGt8wWmvtPxq2u2T24gpU4tMSzKs0OLJjTyqGVfU87HROMKKtwVyt 2Cktk+2FiuvZEOHHuT3ZNv2HSKeuLe/FrNNGchtTaWKfVuauzqkwRc2bmdZ+Br0Y3tJi VD9ULdRIwUK7ZaSbbFme55Tnl+EnZ18rovHCap/TpNDFAzZNeefXZ3mFRsbKJnHs9Nsp IgyT2H8u0LsVvKVf3LYeinKJXB0iB5cAhlLIQCdqgRQ1QOv9PBfqN3Nqs/PUj1eWeg1q GFHw== X-Gm-Message-State: AOAM532vfC4I5JqegIF9quuUCVgcag2Zk8TFPRYuZ3WX27XY7mAsnPFt dOroM1hT18kq+dhh4bFWbhZvpbe9d8Q= X-Google-Smtp-Source: ABdhPJyegFfzsiYDl7rJGSMDVGqo2Ekg/jp4Kl2qRm8mRotcE69GlxZ7y1MvXney3kTdenHgYxAeXw== X-Received: by 2002:a17:90b:1213:: with SMTP id gl19mr905138pjb.232.1610523177135; Tue, 12 Jan 2021 23:32:57 -0800 (PST) Received: from bobo.ibm.com ([124.170.13.62]) by smtp.gmail.com with ESMTPSA id m77sm1394264pfd.105.2021.01.12.23.32.55 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 12 Jan 2021 23:32:56 -0800 (PST) From: Nicholas Piggin To: linuxppc-dev@lists.ozlabs.org Subject: [PATCH v5 14/21] powerpc/64s: move context tracking exit to interrupt exit path Date: Wed, 13 Jan 2021 17:32:08 +1000 Message-Id: <20210113073215.516986-15-npiggin@gmail.com> X-Mailer: git-send-email 2.23.0 In-Reply-To: <20210113073215.516986-1-npiggin@gmail.com> References: <20210113073215.516986-1-npiggin@gmail.com> MIME-Version: 1.0 X-BeenThere: linuxppc-dev@lists.ozlabs.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Linux on PowerPC Developers Mail List List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Nicholas Piggin Errors-To: linuxppc-dev-bounces+patchwork-incoming=ozlabs.org@lists.ozlabs.org Sender: "Linuxppc-dev" The interrupt handler wrapper functions are not the ideal place to maintain context tracking because after they return, the low level exit code must then determine if there are interrupts to replay, or if the task should be preempted, etc. Those paths (e.g., schedule_user) include their own exception_enter/exit pairs to fix this up but it's a bit hacky (see schedule_user() comments). Ideally context tracking will go to user mode only when there are no more interrupts or context switches or other exit processing work to handle. 64e can not do this because it does not use the C interrupt exit code. Signed-off-by: Nicholas Piggin --- arch/powerpc/include/asm/interrupt.h | 34 +++++++++++++++++++++++++--- arch/powerpc/kernel/syscall_64.c | 9 ++++++++ 2 files changed, 40 insertions(+), 3 deletions(-) diff --git a/arch/powerpc/include/asm/interrupt.h b/arch/powerpc/include/asm/interrupt.h index bee393c72fe5..34d7cca2cb2e 100644 --- a/arch/powerpc/include/asm/interrupt.h +++ b/arch/powerpc/include/asm/interrupt.h @@ -7,16 +7,30 @@ #include struct interrupt_state { -#ifdef CONFIG_PPC64 +#ifdef CONFIG_PPC_BOOK3E_64 enum ctx_state ctx_state; #endif }; static inline void interrupt_enter_prepare(struct pt_regs *regs, struct interrupt_state *state) { -#ifdef CONFIG_PPC64 +#ifdef CONFIG_PPC_BOOK3E_64 state->ctx_state = exception_enter(); #endif + +#ifdef CONFIG_PPC_BOOK3S_64 + if (user_mode(regs)) { + CT_WARN_ON(ct_state() != CONTEXT_USER); + user_exit_irqoff(); + } else { + /* + * CT_WARN_ON comes here via program_check_exception, + * so avoid recursion. + */ + if (TRAP(regs) != 0x700) + CT_WARN_ON(ct_state() != CONTEXT_KERNEL); + } +#endif } /* @@ -35,9 +49,23 @@ static inline void interrupt_enter_prepare(struct pt_regs *regs, struct interrup */ static inline void interrupt_exit_prepare(struct pt_regs *regs, struct interrupt_state *state) { -#ifdef CONFIG_PPC64 +#ifdef CONFIG_PPC_BOOK3E_64 exception_exit(state->ctx_state); #endif + + /* + * Book3S exits to user via interrupt_exit_user_prepare(), which does + * context tracking, which is a cleaner way to handle PREEMPT=y + * and avoid context entry/exit in e.g., preempt_schedule_irq()), + * which is likely to be where the core code wants to end up. + * + * The above comment explains why we can't do the + * + * if (user_mode(regs)) + * user_exit_irqoff(); + * + * sequence here. + */ } static inline void interrupt_async_enter_prepare(struct pt_regs *regs, struct interrupt_state *state) diff --git a/arch/powerpc/kernel/syscall_64.c b/arch/powerpc/kernel/syscall_64.c index d7d256a7a41f..42f0ad4b2fbb 100644 --- a/arch/powerpc/kernel/syscall_64.c +++ b/arch/powerpc/kernel/syscall_64.c @@ -305,6 +305,7 @@ notrace unsigned long interrupt_exit_user_prepare(struct pt_regs *regs, unsigned BUG_ON(!(regs->msr & MSR_PR)); BUG_ON(!FULL_REGS(regs)); BUG_ON(regs->softe != IRQS_ENABLED); + CT_WARN_ON(ct_state() == CONTEXT_USER); /* * We don't need to restore AMR on the way back to userspace for KUAP. @@ -347,7 +348,9 @@ notrace unsigned long interrupt_exit_user_prepare(struct pt_regs *regs, unsigned } } + user_enter_irqoff(); if (unlikely(!prep_irq_for_enabled_exit(true))) { + user_exit_irqoff(); local_irq_enable(); local_irq_disable(); goto again; @@ -392,6 +395,12 @@ notrace unsigned long interrupt_exit_kernel_prepare(struct pt_regs *regs, unsign unrecoverable_exception(regs); BUG_ON(regs->msr & MSR_PR); BUG_ON(!FULL_REGS(regs)); + /* + * CT_WARN_ON comes here via program_check_exception, + * so avoid recursion. + */ + if (TRAP(regs) != 0x700) + CT_WARN_ON(ct_state() == CONTEXT_USER); amr = kuap_get_and_check_amr();