From nobody Fri Dec 19 16:44:57 2025 Received: from galois.linutronix.de (Galois.linutronix.de [193.142.43.55]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 9395E1A3168; Sat, 15 Feb 2025 10:56:38 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=193.142.43.55 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739617000; cv=none; b=JxT+daEk/73x1KF7yq5PzDC7iAbCksXmEoscDsSd/cnmqijuxJeGLNrlThXhvDzSshtn3c+xkeOjNDQ0zCmjbqeNYWLgRkF5rFqaOOIrqh7nDzM+be4lEGOPv4Z+0ctK9oZjgHDkc+BTsV2HT1tGLMkr59OsQ73ADscdilrg4Qc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739617000; c=relaxed/simple; bh=iIDOGNcGLoJvc66/45g/yCMkq2atkFudQaSXXdLZzOY=; h=Date:From:To:Subject:Cc:In-Reply-To:References:MIME-Version: Message-ID:Content-Type; b=L1lzl4E/6lKp/xS0ayfi1thaVO4pnqFEYD9t/VKko+IGBdo89kCM7UWtY686rFamFGbrzlWnIGo4MEa71UbXu0bf2crNIF4cvcvwh+yQKEIBEnAbasJqyOstmJzd+xlx6DSBNCMZcNj6dYZiD5gVRHF8UBBZ0GgHfOz9HhDeWes= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de; spf=pass smtp.mailfrom=linutronix.de; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=g+AmOBm+; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=ZjNCMXzf; arc=none smtp.client-ip=193.142.43.55 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linutronix.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="g+AmOBm+"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="ZjNCMXzf" Date: Sat, 15 Feb 2025 10:56:36 -0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1739616997; h=from:from:sender:sender:reply-to:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=0hM6mQEM2DquiCXn3DFjKV52LFKc/MnW+V8Ac2kU8+M=; b=g+AmOBm+3N1NGKcT7JHn63D69n6UkM4Wj0SkK0mpqaCRAG1mMae7GQxiPn7KUeUqCbs1SA gtc4dPB8XidK+VmoaWgDOYBwx+8ccpGj5mZjk5SP+DW9kOO4FvTlua58CpkIV3tx2/LQAp 3F0CzFCGMRv32EDO/fsjCfCa+wO6Enqcep40qXI2A+xjj+Twb/9RfqnNca/mj66oxqeFuT 7jZEozBcy1PvA1T3B+kmJ6z1YP0OqVTyeDUCtiNtMSNyF/OvHnMG9QpeQX/lGdUOkqJ3rQ efPFSPghMvFi3moQZQ8QAL8s9Zjn7TOfafgKRCj4heoZvJzUCM3sHrayGRCjfw== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1739616997; h=from:from:sender:sender:reply-to:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=0hM6mQEM2DquiCXn3DFjKV52LFKc/MnW+V8Ac2kU8+M=; b=ZjNCMXzfRPSEHhBmHrB1lUnOtVTPbLL0CC9v7cVyrpTbjX05diOfwYOeAcnh/nntmEfGLc VNeJQI8y9rm2bDBw== From: "tip-bot2 for Peter Zijlstra" Sender: tip-bot2@linutronix.de Reply-to: linux-kernel@vger.kernel.org To: linux-tip-commits@vger.kernel.org Subject: [tip: x86/core] x86/early_printk: Harden early_serial Cc: Scott Constable , "Peter Zijlstra (Intel)" , Sami Tolvanen , x86@kernel.org, linux-kernel@vger.kernel.org In-Reply-To: <20250207122546.919773202@infradead.org> References: <20250207122546.919773202@infradead.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-ID: <173961699643.10177.2484228241413795642.tip-bot2@tip-bot2> Robot-ID: Robot-Unsubscribe: Contact to get blacklisted from these emails Precedence: bulk Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable The following commit has been merged into the x86/core branch of tip: Commit-ID: 306859de59e59f88662b6b56ff2ce3bbb1e375bb Gitweb: https://git.kernel.org/tip/306859de59e59f88662b6b56ff2ce3bbb= 1e375bb Author: Peter Zijlstra AuthorDate: Fri, 07 Feb 2025 13:15:38 +01:00 Committer: Peter Zijlstra CommitterDate: Fri, 14 Feb 2025 10:32:07 +01:00 x86/early_printk: Harden early_serial Scott found that mem32_serial_in() is an ideal speculation gadget, an indirectly callable function that takes an adddress and offset and immediately does a load. Use static_call() to take away the need for indirect calls and explicitly seal the functions to ensure they're not callable on IBT enabled parts. Reported-by: Scott Constable Signed-off-by: Peter Zijlstra (Intel) Reviewed-by: Sami Tolvanen Link: https://lore.kernel.org/r/20250207122546.919773202@infradead.org --- arch/x86/kernel/early_printk.c | 49 ++++++++++++++++----------------- 1 file changed, 24 insertions(+), 25 deletions(-) diff --git a/arch/x86/kernel/early_printk.c b/arch/x86/kernel/early_printk.c index 44f9370..fc1714b 100644 --- a/arch/x86/kernel/early_printk.c +++ b/arch/x86/kernel/early_printk.c @@ -19,6 +19,7 @@ #include #include #include +#include =20 /* Simple VGA output */ #define VGABASE (__ISA_IO_base + 0xb8000) @@ -94,26 +95,28 @@ static unsigned long early_serial_base =3D 0x3f8; /* t= tyS0 */ #define DLL 0 /* Divisor Latch Low */ #define DLH 1 /* Divisor latch High */ =20 -static unsigned int io_serial_in(unsigned long addr, int offset) +static __noendbr unsigned int io_serial_in(unsigned long addr, int offset) { return inb(addr + offset); } +ANNOTATE_NOENDBR_SYM(io_serial_in); =20 -static void io_serial_out(unsigned long addr, int offset, int value) +static __noendbr void io_serial_out(unsigned long addr, int offset, int va= lue) { outb(value, addr + offset); } +ANNOTATE_NOENDBR_SYM(io_serial_out); =20 -static unsigned int (*serial_in)(unsigned long addr, int offset) =3D io_se= rial_in; -static void (*serial_out)(unsigned long addr, int offset, int value) =3D i= o_serial_out; +DEFINE_STATIC_CALL(serial_in, io_serial_in); +DEFINE_STATIC_CALL(serial_out, io_serial_out); =20 static int early_serial_putc(unsigned char ch) { unsigned timeout =3D 0xffff; =20 - while ((serial_in(early_serial_base, LSR) & XMTRDY) =3D=3D 0 && --timeout) + while ((static_call(serial_in)(early_serial_base, LSR) & XMTRDY) =3D=3D 0= && --timeout) cpu_relax(); - serial_out(early_serial_base, TXR, ch); + static_call(serial_out)(early_serial_base, TXR, ch); return timeout ? 0 : -1; } =20 @@ -131,16 +134,16 @@ static __init void early_serial_hw_init(unsigned divi= sor) { unsigned char c; =20 - serial_out(early_serial_base, LCR, 0x3); /* 8n1 */ - serial_out(early_serial_base, IER, 0); /* no interrupt */ - serial_out(early_serial_base, FCR, 0); /* no fifo */ - serial_out(early_serial_base, MCR, 0x3); /* DTR + RTS */ + static_call(serial_out)(early_serial_base, LCR, 0x3); /* 8n1 */ + static_call(serial_out)(early_serial_base, IER, 0); /* no interrupt */ + static_call(serial_out)(early_serial_base, FCR, 0); /* no fifo */ + static_call(serial_out)(early_serial_base, MCR, 0x3); /* DTR + RTS */ =20 - c =3D serial_in(early_serial_base, LCR); - serial_out(early_serial_base, LCR, c | DLAB); - serial_out(early_serial_base, DLL, divisor & 0xff); - serial_out(early_serial_base, DLH, (divisor >> 8) & 0xff); - serial_out(early_serial_base, LCR, c & ~DLAB); + c =3D static_call(serial_in)(early_serial_base, LCR); + static_call(serial_out)(early_serial_base, LCR, c | DLAB); + static_call(serial_out)(early_serial_base, DLL, divisor & 0xff); + static_call(serial_out)(early_serial_base, DLH, (divisor >> 8) & 0xff); + static_call(serial_out)(early_serial_base, LCR, c & ~DLAB); } =20 #define DEFAULT_BAUD 9600 @@ -183,28 +186,26 @@ static __init void early_serial_init(char *s) /* Convert from baud to divisor value */ divisor =3D 115200 / baud; =20 - /* These will always be IO based ports */ - serial_in =3D io_serial_in; - serial_out =3D io_serial_out; - /* Set up the HW */ early_serial_hw_init(divisor); } =20 #ifdef CONFIG_PCI -static void mem32_serial_out(unsigned long addr, int offset, int value) +static __noendbr void mem32_serial_out(unsigned long addr, int offset, int= value) { u32 __iomem *vaddr =3D (u32 __iomem *)addr; /* shift implied by pointer type */ writel(value, vaddr + offset); } +ANNOTATE_NOENDBR_SYM(mem32_serial_out); =20 -static unsigned int mem32_serial_in(unsigned long addr, int offset) +static __noendbr unsigned int mem32_serial_in(unsigned long addr, int offs= et) { u32 __iomem *vaddr =3D (u32 __iomem *)addr; /* shift implied by pointer type */ return readl(vaddr + offset); } +ANNOTATE_NOENDBR_SYM(mem32_serial_in); =20 /* * early_pci_serial_init() @@ -278,15 +279,13 @@ static __init void early_pci_serial_init(char *s) */ if ((bar0 & PCI_BASE_ADDRESS_SPACE) =3D=3D PCI_BASE_ADDRESS_SPACE_IO) { /* it is IO mapped */ - serial_in =3D io_serial_in; - serial_out =3D io_serial_out; early_serial_base =3D bar0 & PCI_BASE_ADDRESS_IO_MASK; write_pci_config(bus, slot, func, PCI_COMMAND, cmdreg|PCI_COMMAND_IO); } else { /* It is memory mapped - assume 32-bit alignment */ - serial_in =3D mem32_serial_in; - serial_out =3D mem32_serial_out; + static_call_update(serial_in, mem32_serial_in); + static_call_update(serial_out, mem32_serial_out); /* WARNING! assuming the address is always in the first 4G */ early_serial_base =3D (unsigned long)early_ioremap(bar0 & PCI_BASE_ADDRESS_MEM_MASK, 0x10);