Received: by 2002:ab2:69cc:0:b0:1fd:c486:4f03 with SMTP id n12csp549473lqp; Tue, 11 Jun 2024 11:56:52 -0700 (PDT) X-Forwarded-Encrypted: i=3; AJvYcCVhTncu3aUTXrHTn07IS/6f475A+RHjjah/qpKz06tQoYUSxib6Pzks6ay5ZGzFGcdvYMHJOWady8uZ7WhBRevzihfPQJykw9Vfq5N9IQ== X-Google-Smtp-Source: AGHT+IHEwBJUtI5tRJiQGGzz8UhLPg9iOE6fh+Z16V6IsphnF+MNS0UUTPIc+oyc3o1bCbMt/UPp X-Received: by 2002:a05:6a21:3a87:b0:1b8:9f3a:c1c3 with SMTP id adf61e73a8af0-1b89f3ac320mr2125147637.43.1718132212254; Tue, 11 Jun 2024 11:56:52 -0700 (PDT) ARC-Seal: i=2; a=rsa-sha256; t=1718132212; cv=pass; d=google.com; s=arc-20160816; b=UWPRzF5F/T90PH8BJQ8Py7G6ruWJlzsiNNRSo0D2cn/Jsi7h5Ko+mAzPVv+NCSZOpC 43K432eihAo91FZS6+I3ssqrd6kVlaw4TruUKafZAZ2F2+Xoy2DpA87bEqP6P4OLmMvJ iwFSUBmKE2BGiiA+ZDkv5iwN5Eljn5tX/0hXLB9SzoWl7QOLv0xErtEeSJ3Y/hnlG5Xx KCXhqNsInV/HnnWwPqLxAjjetlc+rzBR4uxnWZ8tbrifwkriBgZwEdtQl3JDaPM7en+C SeD0FkqUCFwjayVSgk4c410scMGCcr2u1OUap9r9VutDuS2fWb7aKlf2aoPl5EGD1eH+ ISKw== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=content-transfer-encoding:in-reply-to:from:content-language :references:cc:to:subject:user-agent:mime-version:list-unsubscribe :list-subscribe:list-id:precedence:date:message-id:dkim-signature :dkim-filter; bh=3mnT2Bwkk0vQJgnckDkHQNv+VtpPWp5qOEVzxmzIxI4=; fh=n5dvaHf3VkAiVo7TGy4ZsIkpzt8Dci9+2jl9o6F8Qg0=; b=Xs8sOqfc2rilBTJTS3qF3KaXG+0HE4ZWqo14SfgX6Cqx2Px3navApaGayIXGGuIJpK B0o/xPLSHKtkNuPhphekbZ7iA+4HCK7eMFsh4/IVQWyjR3UPGPgXOsLVIzFITQ3gDsul menFNym05LmNVyme2NLiAbiiU838ix1rJWeysQo5JkHaZy4YrueAuYmUKCiiEdrJnJ7W Jf1ZlQhkEUTf2tYBnwNa3MPlQbBDSYwjPNuVRtnR36y21FamKXEHi/HtvAH8YNIm8HC+ Kk39Utgoayf8LvLSbtTwo7evCmkAnURHl4NX/6XMWgLO9dvvteF9FYeGKxOuRCqcF/5l Nd+A==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@zytor.com header.s=2024051501 header.b=qeF2Gg3q; arc=pass (i=1 spf=pass spfdomain=zytor.com dkim=pass dkdomain=zytor.com dmarc=pass fromdomain=zytor.com); spf=pass (google.com: domain of linux-kernel+bounces-210457-linux.lists.archive=gmail.com@vger.kernel.org designates 2604:1380:40f1:3f00::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-210457-linux.lists.archive=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=zytor.com Return-Path: Received: from sy.mirrors.kernel.org (sy.mirrors.kernel.org. [2604:1380:40f1:3f00::1]) by mx.google.com with ESMTPS id 41be03b00d2f7-6f741dd4687si1412668a12.639.2024.06.11.11.56.51 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 11 Jun 2024 11:56:52 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel+bounces-210457-linux.lists.archive=gmail.com@vger.kernel.org designates 2604:1380:40f1:3f00::1 as permitted sender) client-ip=2604:1380:40f1:3f00::1; Authentication-Results: mx.google.com; dkim=pass header.i=@zytor.com header.s=2024051501 header.b=qeF2Gg3q; arc=pass (i=1 spf=pass spfdomain=zytor.com dkim=pass dkdomain=zytor.com dmarc=pass fromdomain=zytor.com); spf=pass (google.com: domain of linux-kernel+bounces-210457-linux.lists.archive=gmail.com@vger.kernel.org designates 2604:1380:40f1:3f00::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-210457-linux.lists.archive=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=zytor.com Received: from smtp.subspace.kernel.org (wormhole.subspace.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by sy.mirrors.kernel.org (Postfix) with ESMTPS id 85B3EB2582E for ; Tue, 11 Jun 2024 18:44:25 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id EEB7A7406E; Tue, 11 Jun 2024 18:44:16 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=zytor.com header.i=@zytor.com header.b="qeF2Gg3q" Received: from terminus.zytor.com (terminus.zytor.com [198.137.202.136]) (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 3597738FA1; Tue, 11 Jun 2024 18:44:13 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.137.202.136 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1718131456; cv=none; b=I0ILCpgmaNEqJQo9c8iIN3TCsdRtkpGFuiZ8bnWLhgIVFPUd0k0bmXM8hdgkE1mnpiTtlot24VPKck30nbo3EZnTqWsaNRugK//u8ioUHoNDjHVCYp6cnHBJPSDw8jDBkZmTesPh0/H3L80yL7LhUTCG9JtLK3g5odngtgYF6h4= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1718131456; c=relaxed/simple; bh=g1Q7qhG14yUPW9rk+97eEEMsOIkCtIcGn38GoRYuZSU=; h=Message-ID:Date:MIME-Version:Subject:To:Cc:References:From: In-Reply-To:Content-Type; b=qa569DxaucX2GkIRSX9O+pfUSQhs7tS89ZfI5vJcqoMu9jcsDqXERiOO/O6NFCgIKw/XJvp5d5cagg8w5TttUSmDSg7yt6mzgIs7a7v9xr946T+bHasF2d5kg8yhvJp0rHdNxbghXb281ojc3NXJHOQeZW5zLWFUH588B+jIWJQ= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=zytor.com; spf=pass smtp.mailfrom=zytor.com; dkim=pass (2048-bit key) header.d=zytor.com header.i=@zytor.com header.b=qeF2Gg3q; arc=none smtp.client-ip=198.137.202.136 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=zytor.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=zytor.com Received: from [IPV6:2601:646:8002:4640:7285:c2ff:fefb:fd4] ([IPv6:2601:646:8002:4640:7285:c2ff:fefb:fd4]) (authenticated bits=0) by mail.zytor.com (8.17.2/8.17.1) with ESMTPSA id 45BIMaUu3409249 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NO); Tue, 11 Jun 2024 11:22:37 -0700 DKIM-Filter: OpenDKIM Filter v2.11.0 mail.zytor.com 45BIMaUu3409249 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=zytor.com; s=2024051501; t=1718130158; bh=3mnT2Bwkk0vQJgnckDkHQNv+VtpPWp5qOEVzxmzIxI4=; h=Date:Subject:To:Cc:References:From:In-Reply-To:From; b=qeF2Gg3qVflPKKclkjRTOBCOM/fqAUAO37scpIV5HUO7ia+egHSHYeaqjigZtI1Ce On1u308bBkJB3xoX3lKeU4nz9j0E7Mel0Frwxpbe/x28yKYDsAH5oWeA2bIxQwDgAN zhVPged9gzWdCPLznRUmnE45KmYRRhgNp6gJSl1Dde1k3qaZOT68jkQVOqhTDZmLaU uAQywa2fnm+Cp07NacwmXf/d1VihLnGcesvfZK8gqNHzcBCk+kBECEYtZ2an4lKMZA r19zG8VyHgjCaVUz6CK301py09Ujezshi0i1hUnzOpPoEX32aJKaXGiFmToyCLrD4Z DZ2eTm8vf068Q== Message-ID: Date: Tue, 11 Jun 2024 11:22:31 -0700 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Subject: Re: [PATCH] x86: add 'runtime constant' infrastructure To: Linus Torvalds Cc: Borislav Petkov , Peter Zijlstra , Ingo Molnar , Thomas Gleixner , Rasmus Villemoes , Josh Poimboeuf , Linux Kernel Mailing List , the arch/x86 maintainers , linux-arch References: <20240608193504.429644-2-torvalds@linux-foundation.org> <20240610104352.GT8774@noisy.programming.kicks-ass.net> <20240610120201.GAZmbrOYmcA21kD8NB@fat_crate.local> <71FE7A14-62F6-45D3-9BC4-BE09E06F7863@zytor.com> Content-Language: en-US From: "H. Peter Anvin" In-Reply-To: Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 7bit On 6/10/24 18:24, Linus Torvalds wrote: > On Mon, 10 Jun 2024 at 18:09, Linus Torvalds > wrote: >> >> Doing it in general is actually very very painful. Feel free to try - >> but I can almost guarantee that you will throw out the "Keep It Simple >> Stupid" approach and your patch will be twice the size if you do some >> "rewrite the whole instruction" stuff. >> >> I really think there's a fundamental advantage to keeping things simple. > > I guess the KISS approach would be to have a debug mode that just adds > an 'int3' instruction *after* the constant. And then the constant > rewriting rewrites the constant and just changes the 'int3' into the > standard single-byte 'nop' instruction. > > That wouldn't be complicated, and the cost would be minimal. But I > don't see it being worth it, at least not for the current use where > the unrewritten constant will just cause an oops on use. > A general enough way to do it would be to put an int $3 and replace it with a ds: dummy prefix. The issue there is "current use". I'm really, really worried about someone in the future putting this where it won't get properly patched and then all hell will be breaking loose. Perhaps a better idea would be to provide the initial value as part of the declaration, so that the value is never "uninitialized" (much like a static variable can be initialized at compile time)? In other words: runtime_const_ptr(sym,init) Unfortunately gas doesn't seem to properly implement the {nooptimize} prefix that is documented. This does require some gentle assembly hacking: - Loading a pointer/long requires using the "movabs" mnemonic on x86-64. Combining that with (but not on x86-32 as there are no compacted forms of mov immediate; on x86-32 it is also legit to allow =rm rather than =r, but for an 8-bit immediate "=qm" has to be used.) A size/type-generic version (one nice thing here is that init also ends up specifying the type): #define _RUNTIME_CONST(where, sym, size) \ "\n\t" \ ".pushsection \"runtime_const_" #sym "\",\"a\"\n\t" \ ".long (" #where ") - (" #size ") - .\n\t" \ ".popsection" extern void __noreturn __runtime_const_bad_size(void); #define runtime_const(_sym, _init) ({ \ typeof(_init) __ret; \ const size_t __sz = sizeof(__ret); \ switch (__sz) { \ case 1: \ asm_inline("mov %[init],%[ret]\n1:" \ _RUNTIME_CONST(1b, _sym, 1) \ : [ret] "=qm" (__ret) \ : [init] "i" (_init)); \ break; \ case 8: \ asm_inline("movabs %[init],%[ret]\n1:" \ _RUNTIME_CONST(1b, _sym, 8) \ : [ret] "=r" (__ret) \ : [init] "i" (_init)); \ break; \ default: \ asm_inline("mov %[init],%[ret]\n1:" \ _RUNTIME_CONST(1b, _sym, %c[sz]) \ : [ret] "=rm" (__ret) \ : [init] "i" (_init), [sz] "n" (__sz))); \ break; \ } \ __ret; }) - For a shift count, it is unfortunately necessary to explicitly stitch together the instruction using .insn to avoid truncating the case where the operand is 1. Size- and operand-generic version: #define _runtime_const_shift(_val, _sym, _init, _op2) ({ \ typeof(_val) __ret = (_val); \ switch (sizeof(__ret)) { \ case 1: \ asm_inline(".insn 0xc0/%c[op2],%[ret],%[init]{:u8}\n1:" \ _RUNTIME_CONST(1b, _sym, 1) \ : [ret] "+qm" (__ret) \ : [init] "i" ((u8)(_init)), \ [op2] "n" (_op2)); \ break; \ default: \ asm_inline(".insn 0xc1/%c[op2],%[ret],%[init]{:u8}\n1:" \ _RUNTIME_CONST(1b, _sym, 1) \ : [ret] "+rm" (__ret) \ : [init] "i" ((u8)(_init)), \ [op2] "n" (_op2)); \ break; \ } \ __ret; }) \ #define runtime_const_rol(v,s,i) _runtime_const_shift(v,s,i,0) #define runtime_const_ror(v,s,i) _runtime_const_shift(v,s,i,1) #define runtime_const_shl(v,s,i) _runtime_const_shift(v,s,i,4) #define runtime_const_shr(v,s,i) _runtime_const_shift(v,s,i,5) #define runtime_const_sar(v,s,i) _runtime_const_shift(v,s,i,7) I am not sure if I'm missing something, but there really isn't a reason to use different section names for the shift counts specifically, is there? NOTE: if we are *not* making these type-generic there is no reason whatsoever to not make these inlines... *** Also: one thing I would *really* like to see this being used for is cr4_pinned_bits, in which case one can, indeed, safely use a zero value at init time as long as cr4_pinned_mask is patched at the same time, which very much goes along with the above. Again, this is a slightly less minimal versus what I had which was a maximal solution. My approach would pretty much have targeted doing this for nearly all instances, which I eventually felt called for compiler support (or C++!) as adding a bunch of static_imm_*() macros all over the kernel really felt unpleasant. -hpa