Received: by 2002:a05:6358:d09b:b0:dc:cd0c:909e with SMTP id jc27csp5742157rwb; Mon, 14 Nov 2022 08:51:23 -0800 (PST) X-Google-Smtp-Source: AA0mqf4+1sB0ei/UW5tlnHrlXh7UN5310t83lGnrsPhRI13D4S+0FZUqtK1ttIOgaMYeKzkE+O3L X-Received: by 2002:a17:903:130d:b0:187:31da:a260 with SMTP id iy13-20020a170903130d00b0018731daa260mr155067plb.64.1668444682814; Mon, 14 Nov 2022 08:51:22 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1668444682; cv=none; d=google.com; s=arc-20160816; b=gjMG9SU959vWsFNxoOR7eZ8UKRR5HuXj5hGAFl3KDZt54J+kCyfVCXWQnLtthsB2/i HR6fYPIKqfVeAWcA7dAfRUS3z8TdhGa+Dx3xaVFLeKoz+89Aqc2/edKcY3Ijkae5pb/Z B2K13qD9wPJFIo+Kx1tGb/Hsa5NkVrEcpW03ItsefK5WroU1FwuLpf2xCTX2GYzfVR3w nWHiUJrBmszcl70upCZ1H8+zrsPJgeOwqLX48sKgXIBdVEfWNzZ+5KOGKo60rslcAYVP RAVc/1gG7isKxlN9Vv0/344d80wVaXvaQATKYJZIAEa4ab43g5N7iCiu8/FNpMc+LxO3 qh9A== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:dkim-signature :dkim-signature:from; bh=YDZaOSQfmA3ieeMvolr63sTSZIZ73N1pM1Ndsn4fuIc=; b=jGqyuAl1v8L8rQeM4vxHV67PzWbmSyvthELUx7pAis6PPdpjt7V4WzEkd7NDyD8Gi8 o+WJSmiirRAQDgY+pJ83F0NPC/8BqXR/G/+z/BOKIj4FQlz4ImOQ0x1w+wBi+hF4ivlS qWpy4VQ5dy/+kzyvN2Hwk5PFC1l1BzBRbgkeUDaTib4MN4ab2mWKbW6RQi67mZezDSlm XHjRuLbeqSV76gQH2VtnF27NpcW068TXICgTjxEYFkVq3ZG0rwRPC7mQkys+Bnze6KB5 eDMVKKMJoxkCK7lGQY+nJ+6zJPZaLaNEdBZNM3Kt9ATUzdTu2eGKAkB84YKpZtCxFBA8 QBCA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linutronix.de header.s=2020 header.b=dHJbmvzV; dkim=neutral (no key) header.i=@linutronix.de header.s=2020e header.b=Klw6CO0+; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=linutronix.de Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id mw13-20020a17090b4d0d00b001fe2de6a2c9si11878094pjb.4.2022.11.14.08.51.11; Mon, 14 Nov 2022 08:51:22 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@linutronix.de header.s=2020 header.b=dHJbmvzV; dkim=neutral (no key) header.i=@linutronix.de header.s=2020e header.b=Klw6CO0+; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=linutronix.de Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237852AbiKNQbl (ORCPT + 87 others); Mon, 14 Nov 2022 11:31:41 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38244 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237681AbiKNQan (ORCPT ); Mon, 14 Nov 2022 11:30:43 -0500 Received: from galois.linutronix.de (Galois.linutronix.de [IPv6:2a0a:51c0:0:12e:550::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 807072F00D; Mon, 14 Nov 2022 08:29:49 -0800 (PST) From: John Ogness DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1668443388; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=YDZaOSQfmA3ieeMvolr63sTSZIZ73N1pM1Ndsn4fuIc=; b=dHJbmvzVtPyJ1YbuVbBDgnUwEWvzqfIWX/lYG3qITzjamvKx/92bfjhlfedBeaYSYuS0Im yWcAO3B1E6yEYpBKXY9DAqh4w5MYqQrald2Xy8tyYfE/SWY/9Pvqj2aYR/nTRZ4xqgUBJ4 BwCpqphpuUcJjpFKWBWJpAAsCmVqnnVRJpZYuE/Az366y1W/WIAjXssnej2lMOy1SyXLtK DM78o+xXRSp+HpMDkEX9thcmyIq6GKVHX30uRk/xLxCIlajhvzUnN56off+bh1t6+vg+px 7Yo7D50qtqLgc8JemIqSf3cnkCD6XVy7fq+9oTDXpUzuxQp03SrFF7tZlHpSNw== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1668443388; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=YDZaOSQfmA3ieeMvolr63sTSZIZ73N1pM1Ndsn4fuIc=; b=Klw6CO0+RzlaQaF/TUs5OEp+YJFNKlnTXcnXdz4EGApnJTMd02z6VogUxfhBmPoyrSLS/L mpQPoXYjSbHQ65Dg== To: Petr Mladek Cc: Sergey Senozhatsky , Steven Rostedt , Thomas Gleixner , linux-kernel@vger.kernel.org, Helge Deller , Greg Kroah-Hartman , Javier Martinez Canillas , Thomas Zimmermann , Juergen Gross , Boris Ostrovsky , Tom Rix , linux-fbdev@vger.kernel.org, dri-devel@lists.freedesktop.org Subject: [PATCH printk v4 31/39] printk, xen: fbfront: create/use safe function for forcing preferred Date: Mon, 14 Nov 2022 17:35:24 +0106 Message-Id: <20221114162932.141883-32-john.ogness@linutronix.de> In-Reply-To: <20221114162932.141883-1-john.ogness@linutronix.de> References: <20221114162932.141883-1-john.ogness@linutronix.de> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-3.9 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,INVALID_DATE_TZ_ABSURD, RCVD_IN_DNSWL_MED,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org With commit 9e124fe16ff2("xen: Enable console tty by default in domU if it's not a dummy") a hack was implemented to make sure that the tty console remains the console behind the /dev/console device. The main problem with the hack is that, after getting the console pointer to the tty console, it is assumed the pointer is still valid after releasing the console_sem. This assumption is incorrect and unsafe. Make the hack safe by introducing a new function console_force_preferred_locked() and perform the full operation under the console_list_lock. Signed-off-by: John Ogness --- drivers/video/fbdev/xen-fbfront.c | 12 +++----- include/linux/console.h | 1 + kernel/printk/printk.c | 49 +++++++++++++++++++++++++++++-- 3 files changed, 51 insertions(+), 11 deletions(-) diff --git a/drivers/video/fbdev/xen-fbfront.c b/drivers/video/fbdev/xen-fbfront.c index 4d2694d904aa..8752d389e382 100644 --- a/drivers/video/fbdev/xen-fbfront.c +++ b/drivers/video/fbdev/xen-fbfront.c @@ -504,18 +504,14 @@ static void xenfb_make_preferred_console(void) if (console_set_on_cmdline) return; - console_lock(); + console_list_lock(); for_each_console(c) { if (!strcmp(c->name, "tty") && c->index == 0) break; } - console_unlock(); - if (c) { - unregister_console(c); - c->flags |= CON_CONSDEV; - c->flags &= ~CON_PRINTBUFFER; /* don't print again */ - register_console(c); - } + if (c) + console_force_preferred_locked(c); + console_list_unlock(); } static int xenfb_resume(struct xenbus_device *dev) diff --git a/include/linux/console.h b/include/linux/console.h index f716e1dd9eaf..9cea254b34b8 100644 --- a/include/linux/console.h +++ b/include/linux/console.h @@ -291,6 +291,7 @@ enum con_flush_mode { }; extern int add_preferred_console(char *name, int idx, char *options); +extern void console_force_preferred_locked(struct console *con); extern void register_console(struct console *); extern int unregister_console(struct console *); extern void console_lock(void); diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c index e770b1ede6c9..dff76c1cef80 100644 --- a/kernel/printk/printk.c +++ b/kernel/printk/printk.c @@ -247,9 +247,10 @@ int devkmsg_sysctl_set_loglvl(struct ctl_table *table, int write, void console_list_lock(void) { /* - * In unregister_console(), synchronize_srcu() is called with the - * console_list_lock held. Therefore it is not allowed that the - * console_list_lock is taken with the srcu_lock held. + * In unregister_console() and console_force_preferred_locked(), + * synchronize_srcu() is called with the console_list_lock held. + * Therefore it is not allowed that the console_list_lock is taken + * with the srcu_lock held. * * Detecting if this context is really in the read-side critical * section is only possible if the appropriate debug options are @@ -3461,6 +3462,48 @@ int unregister_console(struct console *console) } EXPORT_SYMBOL(unregister_console); +/** + * console_force_preferred_locked - force a registered console preferred + * @con: The registered console to force preferred. + * + * Must be called under console_list_lock(). + */ +void console_force_preferred_locked(struct console *con) +{ + struct console *cur_pref_con; + + if (!console_is_registered_locked(con)) + return; + + cur_pref_con = console_first(); + + /* Already preferred? */ + if (cur_pref_con == con) + return; + + /* + * Delete, but do not re-initialize the entry. This allows the console + * to continue to appear registered (via any hlist_unhashed_lockless() + * checks), even though it was briefly removed from the console list. + */ + hlist_del_rcu(&con->node); + + /* + * Ensure that all SRCU list walks have completed so that the console + * can be added to the beginning of the console list and its forward + * list pointer can be re-initialized. + */ + synchronize_srcu(&console_srcu); + + con->flags |= CON_CONSDEV; + WARN_ON(!con->device); + + /* Only the new head can have CON_CONSDEV set. */ + console_srcu_write_flags(cur_pref_con, cur_pref_con->flags & ~CON_CONSDEV); + hlist_add_behind_rcu(&con->node, console_list.first); +} +EXPORT_SYMBOL(console_force_preferred_locked); + /* * Initialize the console device. This is called *early*, so * we can't necessarily depend on lots of kernel help here. -- 2.30.2