From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from vib-mx02.apple.com (vib-mx02.apple.com [17.132.96.1]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C808C33507C for ; Fri, 31 Jul 2026 18:27:46 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=17.132.96.1 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785522468; cv=none; b=s7ZTXJPbpet03no7w0k3ImoWEFzTFPvPxdy7t4IpJFXsw9ICmTov7NaZ70qJk3NJVBBSp2Zm3ok/GcHP99gygQlL6usf9w+6t8y18zm1kqeVGqsI7XKAr+sK0XgyfFWdD39cln2+LcP+yQfYcVBYtZX5TjEvMIZ0b921xXLlAKg= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785522468; c=relaxed/simple; bh=aEokegEjN+OBt+6DDO9B3Pt1GFRx8IA+1f+tDUP+aRM=; h=Content-type:MIME-version:Subject:From:In-reply-to:Date:Cc: Message-id:References:To; b=uWErOpWSba50xv+ZnF3TIXQRarHBelOa4iE7VGUivG7b+6XYWXDDMKovntIRsjn7OmTNQK0/f8Si7z5s60vIIi5LUdZhZjEtYzBOk+3QT+JymRklrtO6phTBg1uTVBXXNfMwN/hPeblku+ExfYIx9mwmq61G6QUYJ5idFpmqnWQ= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=apple.com; spf=pass smtp.mailfrom=apple.com; dkim=pass (2048-bit key) header.d=apple.com header.i=@apple.com header.b=F6mc8cVl; arc=none smtp.client-ip=17.132.96.1 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=apple.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=apple.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=apple.com header.i=@apple.com header.b="F6mc8cVl" Received: from vb11p01nt-mtap02.apple.com (vb11p01nt-mtap02.ise.apple.com [100.84.70.82]) by vb11p01nt-mxp02.apple.com (Oracle Communications Messaging Server 8.1.0.28.20250821 64bit (built Aug 21 2025)) with ESMTPS id <0TJ11OTLSV5TPG00@vb11p01nt-mxp02.apple.com> for linux-kernel@vger.kernel.org; Fri, 31 Jul 2026 17:27:38 +0000 (GMT) X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1143,Hydra:6.1.134,FMLib:17.12.100.49 definitions=2026-07-31_05,2026-07-30_01,2025-10-01_01 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=apple.com; h=cc : content-transfer-encoding : content-type : date : from : in-reply-to : message-id : mime-version : references : subject : to; s=20180706; bh=MObF2ZufsNFWLakEy48uUA9PR0QzdQdPvYTzDxrlqLs=; b=F6mc8cVlKf7m61YxPZwe3ejymW1oDBnYK6G8l9OoxtSTsYX2rcA47imundOt3Rcev/6k +0MDrn6yH4CGndbzxqjshnNk9u49FNyt9zarG1VBNLdqODslscJIMm/8fGN9iBExoiLj YrYTLu9Co3c7y+yEmrpP54OGHid3945mHc1CJZ3Q4dNVZHY35rFnBDXsbr8cL5QxphAC WLjuLIUQMpDPksM4QvmP6a0dvM8c1th0FShUMUpUwooluEpqmTBHbSfxJS8IRnilKtl0 hPt1mHOdwEzNKSRo6TcJNYSSnP4JeizLAq43CArdmTUJ26j81E8iCeEX3YJXg4zFLZGo OA== Received: from am11p01nt-mmpp03.apple.com (am11p01nt-mmpp03.ise.apple.com [100.85.69.141]) by vb11p01nt-mtap02.apple.com (Oracle Communications Messaging Server 8.1.0.28.20250821 64bit (built Aug 21 2025)) with ESMTPS id <0TJ10MD85V4SJL10@vb11p01nt-mtap02.apple.com>; Fri, 31 Jul 2026 17:27:27 +0000 (GMT) Received: from process_milters-daemon.am11p01nt-mmpp03.apple.com by am11p01nt-mmpp03.apple.com (Oracle Communications Messaging Server 8.1.0.28.20260513 64bit (built May 13 2026)) id <0TJ103Y00V4MQO00@am11p01nt-mmpp03.apple.com>; Fri, 31 Jul 2026 17:27:05 +0000 (GMT) X-Va-A: X-Va-T-CD: cbf7380921e8e2f9db5ea993b70cea12 X-Va-E-CD: 70325e34e83579c3b3fcbc67bcb40655 X-Va-R-CD: bfd83131a8ab6e66990b315bd3663b76 X-Va-ID: 5150be6b-52f0-443a-9b0f-318900a89bab X-Va-CD: 0 X-V-A: X-V-T-CD: cbf7380921e8e2f9db5ea993b70cea12 X-V-E-CD: 70325e34e83579c3b3fcbc67bcb40655 X-V-R-CD: bfd83131a8ab6e66990b315bd3663b76 X-V-ID: bfdce288-5561-4bde-ae98-94b661e68972 X-V-CD: 0 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1143,Hydra:6.1.134,FMLib:17.12.100.49 definitions=2026-07-31_05,2026-07-30_01,2025-10-01_01 Received: from smtpclient.apple (unknown [10.106.1.184]) by am11p01nt-mmpp03.apple.com (Oracle Communications Messaging Server 8.1.0.28.20260513 64bit (built May 13 2026)) with ESMTPSA id <0TJ103G4AV4UMD00@am11p01nt-mmpp03.apple.com>; Fri, 31 Jul 2026 17:27:02 +0000 (GMT) Content-type: text/plain; charset=us-ascii Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-version: 1.0 (Mac OS X Mail 16.0 \(3892.100.6\)) Subject: Re: [PATCH] arm64: archrandom: avoid trapping ID register read in __cpu_has_rng() From: Aman Priyadarshi In-reply-to: Date: Fri, 31 Jul 2026 18:26:44 +0100 Cc: catalin.marinas@arm.com, Jason@zx2c4.com, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, Ard Biesheuvel Content-transfer-encoding: quoted-printable Message-id: <97FF53B9-993A-4E73-9C6B-0DA514AD0778@apple.com> References: <20260720140615.99343-1-amanp@apple.com> To: Will Deacon X-Mailer: Apple Mail (2.3892.100.6) Hi Will, Thank you for reviewing the patch! > On 31 Jul 2026, at 15:43, Will Deacon wrote: >=20 > Hi Aman, >=20 > On Mon, Jul 20, 2026 at 03:06:15PM +0100, Aman Priyadarshi wrote: >> __cpu_has_rng() has an early-boot fallback, taken before the >> ARM64_HAS_RNG alternative is patched, that calls >> this_cpu_has_cap(ARM64_HAS_RNG). With SCOPE_LOCAL_CPU that resolves = the >> capability by reading ID_AA64ISAR0_EL1 directly from hardware via >> __read_sysreg_by_encoding(), on every invocation. >>=20 >> Until the CRNG is seeded, crng_make_state() routes every = get_random_*() >> through extract_entropy(), which drains architectural entropy via >> arch_get_random_seed_longs()/arch_get_random_longs() and so calls >> __cpu_has_rng() several times per request. On a direct (non-EFI) boot >> there is no bootloader seed, so the CRNG stays unseeded for much of >> boot and essentially every early randomness consumer takes this path. >>=20 >> Under virtualization this is costly: the hypervisor traps guest >> accesses to the ID registers (HCR_EL2.TID3), making each read a = vmexit, >> producing ~200k trapped ID_AA64ISAR0_EL1 reads during boot. >>=20 >> The register value is invariant, so read the sanitised feature = register >> instead. read_sanitised_ftr_reg() returns the cached value from >> arm64_ftr_regs[] with no sysreg access, and hence no trap. That array >> is populated by cpuinfo_store_boot_cpu() in smp_prepare_boot_cpu(), >> before the first early RNG use in random_init_early(), so it is = always >> valid here. >>=20 >> With this change the trapped reads drop from ~200k to handful number = of >> times, and the boot time drops roughly by 6.3% in the test = environment. >=20 > Yikes, that's quite a compelling performance improvement. >=20 >> diff --git a/arch/arm64/include/asm/archrandom.h = b/arch/arm64/include/asm/archrandom.h >> index 8babfbe31f95..8067e9a35641 100644 >> --- a/arch/arm64/include/asm/archrandom.h >> +++ b/arch/arm64/include/asm/archrandom.h >> @@ -61,8 +61,22 @@ static inline bool __arm64_rndrrs(unsigned long = *v) >>=20 >> static __always_inline bool __cpu_has_rng(void) >> { >> - if (unlikely(!system_capabilities_finalized() && !preemptible())) >> - return this_cpu_has_cap(ARM64_HAS_RNG); >> + if (unlikely(!system_capabilities_finalized() && !preemptible())) { >> + /* >> + * Until the ARM64_HAS_RNG alternative is patched we can't use >> + * the static-branch form, so consult the feature register >> + * directly. Don't use this_cpu_has_cap() here: it reads >> + * ID_AA64ISAR0_EL1 from hardware on every call, under >> + * virtualization each ID register read traps to the hypervisor >> + * (HCR_EL2.TID3) -- producing a storm of vmexits during boot. >> + * The sanitised value is cached in memory. >> + */ >> + u64 isar0 =3D read_sanitised_ftr_reg(SYS_ID_AA64ISAR0_EL1); >> + >> + return cpuid_feature_extract_unsigned_field(isar0, >> + ID_AA64ISAR0_EL1_RNDR_SHIFT) >=3D >> + ID_AA64ISAR0_EL1_RNDR_IMP; >> + } >=20 > You can probably rewrite this a little more cleanly along the lines of > the (not even compile-tested) diff below. I was about to do that, but > then I got a bit confused by the whole thing. The preemptible() check = is > presumably not needed if we're accessing the in-memory feature = registers > rather than the per-CPU id registers, but then how do you handle races > with concurrent updates to the "safe value" made by CPUs concurrently > coming online? I kept preemptible() check for this exact reason: the updates made by = CPUs concurrently coming online will always take the downgrade path (a = secondary CPU can clear RNDR, never set it), and therefore by taking the = non-preemptible branch I can guarantee that the pinned CPU supports the said feature. I agree, this assumes that a secondary CPU folds its own ID registers = into sys_val before it can ever be a randomness consumer, but looking at the code = that seems the case, please feel free to correct me. Besides, in my opinion, it's hard to argue correctness of this code = without preemptible() check. >=20 > Will >=20 > --->8 >=20 > diff --git a/arch/arm64/include/asm/archrandom.h = b/arch/arm64/include/asm/archrandom.h > index 8babfbe31f95..1c6ccc1776cd 100644 > --- a/arch/arm64/include/asm/archrandom.h > +++ b/arch/arm64/include/asm/archrandom.h > @@ -61,8 +61,17 @@ static inline bool __arm64_rndrrs(unsigned long *v) >=20 > static __always_inline bool __cpu_has_rng(void) > { > - if (unlikely(!system_capabilities_finalized() && = !preemptible())) > - return this_cpu_has_cap(ARM64_HAS_RNG); > + if (unlikely(!system_capabilities_finalized() && = !preemptible())) { > + /* > + * Query the in-memory sanitised value to avoid a = potential > + * trap when accessing the ID register under a = hypervisor. > + */ > + u64 isar0 =3D = read_sanitised_ftr_reg(SYS_ID_AA64ISAR0_EL1); > + u64 rndr =3D SYS_FIELD_GET(ID_AA64ISAR0_EL1, RNDR, = isar0); > + > + return rndr >=3D ID_AA64ISAR0_EL1_RNDR_IMP; > + } > + > return alternative_has_cap_unlikely(ARM64_HAS_RNG); > } Agreed, this looks cleaner. Thanks! - Aman Priyadarshi=