From nobody Fri Dec 19 10:35:33 2025 Received: from mail-wm1-f45.google.com (mail-wm1-f45.google.com [209.85.128.45]) (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 6EBDF1AB6C3 for ; Mon, 2 Sep 2024 16:19:23 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.45 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1725293966; cv=none; b=KmZBqhIxnPrMUABnk90zQXtuWUES7WnznfMVLf7S3UfKERDzbSZbOhFVXwCHMP33k4fxYAJwKU1DQzePxOwBQbJU8+hHIg61FZ8Y2hiIG5puOkXWyYfIOYxHNcg8n9kGRl9Y5iG/NXXs5spEKTqT8Tr727Rkpg8dGrxL5vKiUPM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1725293966; c=relaxed/simple; bh=44yzxRSTqwlOROlkCwEXzmTbMUBKaeO1+N1E/oREDTU=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=QThvNnJiHZ0UJ79pLTBMajiDK6oV/uizTTSKzxSMi5l9N8J23isEvY94Otf5ekbDWuHEXoFyvEBqEx0WsYOtH8u6AR1u7Mgo6d/A6KUp/T7mPnT4Vc2+DMZQXN7w0u98l6S2SuB0vrS1cfSoFSk0JNVWailJzR1UrgVI3XIkXiY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linaro.org; spf=pass smtp.mailfrom=linaro.org; dkim=pass (2048-bit key) header.d=linaro.org header.i=@linaro.org header.b=lwcYyvop; arc=none smtp.client-ip=209.85.128.45 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linaro.org Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linaro.org header.i=@linaro.org header.b="lwcYyvop" Received: by mail-wm1-f45.google.com with SMTP id 5b1f17b1804b1-42bb6d3e260so37938535e9.1 for ; Mon, 02 Sep 2024 09:19:23 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1725293962; x=1725898762; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=/DUDom//tRZnCzR0TPrW7dnmFkZZ6kQdXEFrODb12u4=; b=lwcYyvopyDeBgfSRp7/tIiAcqCkEOuFwD51W4k3NPu9Z6o0XfXuP2+72Sw/TLb8l22 nQoGWBcyhptiOP9BWeovgiZROJ/CsKQPSFiQKAz6HVa744lxQEkY8Y8cNNJONSJaqo0Z jIwNlMZFR2t5UCdFYyQi+b3ZrSaEsm7QHFderSjWPCWotBHMQ6CHgLXxO1Ek/hU6KEp2 NPSygsa+43jKjimBcilASH91FJYo1bn5ILNa7BJkZZS7y4NeOiXSYFauUgcDV0fN1jdo RiyQpgMOeopXXpxua9DY/ap9RlBvAWatpvlw4KVWhUf2T+78DpwEfJrkMNz+2GuTgURj IOAA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1725293962; x=1725898762; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=/DUDom//tRZnCzR0TPrW7dnmFkZZ6kQdXEFrODb12u4=; b=PRWxzLqaXf0B9/vxTIQrh33FiRRyfvwh86nWKqKKJ3pcGpA910T0nsrfkaRMSaaMc5 eBTzLEDPLWVvXGyCR9HEQrXEzycn1sQcB10PWEWggz/RFq36IldNd8M8xeIynlG6JhK4 8YzmD+L+K6fWd5KKMwhsz+15BpLRN2SbAxsB2UTPbrhNnqRwPkOaN9oppR9XyIHbfjwf VB9C1AqoRCZ71Qf9qzCjhBnQOHhp1gzjn4++s5V1DAg3E1Hr4cFSV2wfLoV6JNgXOV3H dIC0hhxIIBopXOSeFuA04tgOxHWQHthQPTxHBi6sEl+RM5u6qg/I6IvfAO0Bb91CjBHS ztfg== X-Forwarded-Encrypted: i=1; AJvYcCUe/2VYROmLJMAeteEU48zNCzz2n+qMzZVpM6qEXotqgnUNeJ+/2TBmKPiNQRiEkonqReXSSY6H7L0MfW8=@vger.kernel.org X-Gm-Message-State: AOJu0YwrwTkWcKCjWR8LqKaN9STvAtsGgXbE31MoE+wcifHcL87j6udS qmo1Yr+NiQoI1Yhc0udrEUjdmVV7foPAacsn5Kn5ZmwAB0EWUHT8KDSianECbEU= X-Google-Smtp-Source: AGHT+IHxlg744kdhRp7ia5MEnyLycaQtMyvS6PmquQ558nqH6B/b8PrByKr+corJQzJhDTQ9+etDCA== X-Received: by 2002:a05:600c:3b87:b0:428:151b:e8e with SMTP id 5b1f17b1804b1-42bdc63348bmr46501825e9.10.1725293961685; Mon, 02 Sep 2024 09:19:21 -0700 (PDT) Received: from ubuntu-vm.. (51-148-40-55.dsl.zen.co.uk. [51.148.40.55]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-42bb6deb239sm145970065e9.5.2024.09.02.09.19.20 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 02 Sep 2024 09:19:21 -0700 (PDT) From: Adhemerval Zanella To: "Jason A . Donenfeld" , Theodore Ts'o , linux-kernel@vger.kernel.org, linux-crypto@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-arch@vger.kernel.org, Catalin Marinas , Will Deacon , Thomas Gleixner , Eric Biggers , Christophe Leroy Cc: Mark Rutland Subject: [PATCH v4 1/2] arm64: alternative: make alternative_has_cap_likely() VDSO compatible Date: Mon, 2 Sep 2024 16:15:46 +0000 Message-ID: <20240902161912.2751-2-adhemerval.zanella@linaro.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240902161912.2751-1-adhemerval.zanella@linaro.org> References: <20240902161912.2751-1-adhemerval.zanella@linaro.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Mark Rutland Currently alternative_has_cap_unlikely() can be used in VDSO code, but alternative_has_cap_likely() cannot as it references alt_cb_patch_nops, which is not available when linking the VDSO. This is unfortunate as it would be useful to have alternative_has_cap_likely() available in VDSO code. The use of alt_cb_patch_nops was added in commit: d926079f17bf8aa4 ("arm64: alternatives: add shared NOP callback") ... as removing duplicate NOPs within the kernel Image saved areasonable amount of space. Given the VDSO code will have nowhere near as many alternative branches as the main kernel image, this isn't much of a concern, and a few extra nops isn't a massive problem. Change alternative_has_cap_likely() to only use alt_cb_patch_nops for the main kernel image, and allow duplicate NOPs in VDSO code. Signed-off-by: Mark Rutland Signed-off-by: Adhemerval Zanella --- arch/arm64/include/asm/alternative-macros.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/arm64/include/asm/alternative-macros.h b/arch/arm64/inclu= de/asm/alternative-macros.h index d328f549b1a6..c8c77f9e36d6 100644 --- a/arch/arm64/include/asm/alternative-macros.h +++ b/arch/arm64/include/asm/alternative-macros.h @@ -230,7 +230,11 @@ alternative_has_cap_likely(const unsigned long cpucap) return false; =20 asm goto( +#ifdef BUILD_VDSO + ALTERNATIVE("b %l[l_no]", "nop", %[cpucap]) +#else ALTERNATIVE_CB("b %l[l_no]", %[cpucap], alt_cb_patch_nops) +#endif : : [cpucap] "i" (cpucap) : --=20 2.43.0 From nobody Fri Dec 19 10:35:33 2025 Received: from mail-wr1-f42.google.com (mail-wr1-f42.google.com [209.85.221.42]) (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 2F7E51AB6C8 for ; Mon, 2 Sep 2024 16:19:24 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.221.42 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1725293967; cv=none; b=I6tPcyHOixIPwgQxaJ/3wcmZ9AxdkYaHRToo+QeOlp1Ob3zpSV5nxSzEiKpRruypFdCk66zmKLpQgWAW2Ltyr9l99ml0NSlVu+JfJ30R536/14zo+rD1YJGi/VMb06Z5VEmB2i7klhHwDYaEqZFzffIxoGQM2ucxGHvK8BkIknk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1725293967; c=relaxed/simple; bh=CTg1HnpXMiVou2jm/6rfgRfO1zcdu2yEgoJ4xCcDd8Q=; h=From:To:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=NyVLz4zgPjoCs5LbmG08bVhhpJQmPtsomH54G9isulr3fN/PHBVQNiAGj3rxfd/sRJuUAtylqjf8/TzhAkN/REWUO/7rOLjKNIluZ/jVhqnollrzCaDTt3C0q4xcgFQNTHg1w/qXjiJ8GDxfNxvLRjKalb1SMV6cJHzP0hnmQno= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linaro.org; spf=pass smtp.mailfrom=linaro.org; dkim=pass (2048-bit key) header.d=linaro.org header.i=@linaro.org header.b=NxHvZtrP; arc=none smtp.client-ip=209.85.221.42 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linaro.org Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linaro.org header.i=@linaro.org header.b="NxHvZtrP" Received: by mail-wr1-f42.google.com with SMTP id ffacd0b85a97d-374cacf18b1so866374f8f.2 for ; Mon, 02 Sep 2024 09:19:24 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1725293963; x=1725898763; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=Ie9W1L9uNFC23ZDP70zJ0oUPkgRwFshdvpGZOvbHuRQ=; b=NxHvZtrP3sNnfh0a9ys2BBon7JaqWTRIIchsQVl9/th1niL2cc7r/u/ZJpf72hWRvD GjKdkwdxUdFwoLUz87MbZf41XSbPg18BQ9qhOuG7nw59G+BD0YtWVIomN2wv/DaJQINy 8fsv0R+Rq/6SQNBrIwwwtzNhhKHqWgOuZXT3N5RPiSY6iGkTy4W/v+ecPRmTCcZVpsA6 t8RIiFTRAopnmhbG9cJsFgizAROu6IsL90+gPM3KIxuNy/4ZEgV2JeNAtxoFWxM/lxA+ tkR3Gs3SDbh7fp+/P/BtUyBDh9Q9PIvpeOmwxWOfHoJyhwJq9cXzRk/icOG+NMpaPNaR hEZg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1725293963; x=1725898763; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=Ie9W1L9uNFC23ZDP70zJ0oUPkgRwFshdvpGZOvbHuRQ=; b=E9Jhch0Rul60lGIT/p5xXd4sGvEH2eXu/Me3Ztq0SSkAN3geMVTvXj/WGaSXa5HdCa vu9LJkN32ej9gtMsuhBpTaEHCD6SJk3cjjiOpRUqmYECMV5FOTv6qg83IpPpRJ+Iyxh0 OBPzTKGseNqnhviJc9CWc5+5FSjRjM+dB+/GQFDBzS5JB9iNG4flXbpfiB7sr9wVEz0O UWKn6pUny9rsAnOOhKtoUYYCICbO575fGDNK1XT7EQBsW+kFUMUxpxoSKHNT6xHIqsja 76ewrHv9LF7a8QOuXBomQl6CctdYCTKsY9AnSWHwpN6WHZOdGta3CfVQLttSW0b8h3TZ 9o/A== X-Forwarded-Encrypted: i=1; AJvYcCXy7moADlk/tbQxycvej+HYWNzsPlpaMfEZr28MJPvY3VfPsw4lunGtsH+FEdO1yA+oaNUG/mguP7tI6Hk=@vger.kernel.org X-Gm-Message-State: AOJu0Yx4qcfr4UOeqgVe3ZWK1Zhyuf+MVAwa4O7S/B2sGf8ULEi7AqpO BXuNg2XtPMQqf3oqthcGw3yTZFMij9OnBkQlzxGO+OqZdLzVGN3p8YJjARjReFs= X-Google-Smtp-Source: AGHT+IH4phemO6lKDX8phDZWlIUpSXP7tWTANei7+Fbp85cS9vgDau+TxVHvHXo9nGtcthCFPr5IFw== X-Received: by 2002:adf:f0cb:0:b0:374:c432:4971 with SMTP id ffacd0b85a97d-374c4324b58mr4193553f8f.16.1725293963228; Mon, 02 Sep 2024 09:19:23 -0700 (PDT) Received: from ubuntu-vm.. (51-148-40-55.dsl.zen.co.uk. [51.148.40.55]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-42bb6deb239sm145970065e9.5.2024.09.02.09.19.21 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 02 Sep 2024 09:19:22 -0700 (PDT) From: Adhemerval Zanella To: "Jason A . Donenfeld" , Theodore Ts'o , linux-kernel@vger.kernel.org, linux-crypto@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-arch@vger.kernel.org, Catalin Marinas , Will Deacon , Thomas Gleixner , Eric Biggers , Christophe Leroy Subject: [PATCH v4 2/2] arm64: vdso: wire up getrandom() vDSO implementation Date: Mon, 2 Sep 2024 16:15:47 +0000 Message-ID: <20240902161912.2751-3-adhemerval.zanella@linaro.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240902161912.2751-1-adhemerval.zanella@linaro.org> References: <20240902161912.2751-1-adhemerval.zanella@linaro.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Hook up the generic vDSO implementation to the aarch64 vDSO data page. The _vdso_rng_data required data is placed within the _vdso_data vvar page, by using a offset larger than the vdso_data. The vDSO function requires a ChaCha20 implementation that does not write to the stack, and that can do an entire ChaCha20 permutation. The one provided uses NEON on the permute operation, with a fallback to the syscall for chips that do not support AdvSIMD. This also passes the vdso_test_chacha test along with vdso_test_getrandom. The vdso_test_getrandom bench-single result on Neoverse-N1 shows: vdso: 25000000 times in 0.783884250 seconds libc: 25000000 times in 8.780275399 seconds syscall: 25000000 times in 8.786581518 seconds A small fixup to arch/arm64/include/asm/mman.h was required to avoid pulling kernel code into the vDSO, similar to what's already done in arch/arm64/include/asm/rwonce.h. Signed-off-by: Adhemerval Zanella --- arch/arm64/Kconfig | 1 + arch/arm64/include/asm/mman.h | 6 +- arch/arm64/include/asm/vdso.h | 6 + arch/arm64/include/asm/vdso/getrandom.h | 50 ++++++ arch/arm64/include/asm/vdso/vsyscall.h | 10 ++ arch/arm64/kernel/vdso.c | 6 - arch/arm64/kernel/vdso/Makefile | 25 ++- arch/arm64/kernel/vdso/vdso | 1 + arch/arm64/kernel/vdso/vdso.lds.S | 4 + arch/arm64/kernel/vdso/vgetrandom-chacha.S | 178 +++++++++++++++++++++ arch/arm64/kernel/vdso/vgetrandom.c | 15 ++ tools/arch/arm64/vdso | 1 + tools/include/linux/compiler.h | 4 + tools/testing/selftests/vDSO/Makefile | 3 +- 14 files changed, 294 insertions(+), 16 deletions(-) create mode 100644 arch/arm64/include/asm/vdso/getrandom.h create mode 120000 arch/arm64/kernel/vdso/vdso create mode 100644 arch/arm64/kernel/vdso/vgetrandom-chacha.S create mode 100644 arch/arm64/kernel/vdso/vgetrandom.c create mode 120000 tools/arch/arm64/vdso diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index a2f8ff354ca6..7f7424d1b3b8 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -262,6 +262,7 @@ config ARM64 select TRACE_IRQFLAGS_NMI_SUPPORT select HAVE_SOFTIRQ_ON_OWN_STACK select USER_STACKTRACE_SUPPORT + select VDSO_GETRANDOM help ARM 64-bit (AArch64) Linux support. =20 diff --git a/arch/arm64/include/asm/mman.h b/arch/arm64/include/asm/mman.h index 5966ee4a6154..ceb4370a69c5 100644 --- a/arch/arm64/include/asm/mman.h +++ b/arch/arm64/include/asm/mman.h @@ -2,9 +2,11 @@ #ifndef __ASM_MMAN_H__ #define __ASM_MMAN_H__ =20 +#include + +#ifndef BUILD_VDSO #include #include -#include =20 static inline unsigned long arch_calc_vm_prot_bits(unsigned long prot, unsigned long pkey __always_unused) @@ -60,4 +62,6 @@ static inline bool arch_validate_flags(unsigned long vm_f= lags) } #define arch_validate_flags(vm_flags) arch_validate_flags(vm_flags) =20 +#endif /* !BUILD_VDSO */ + #endif /* ! __ASM_MMAN_H__ */ diff --git a/arch/arm64/include/asm/vdso.h b/arch/arm64/include/asm/vdso.h index 4305995c8f82..18407b757c95 100644 --- a/arch/arm64/include/asm/vdso.h +++ b/arch/arm64/include/asm/vdso.h @@ -16,6 +16,12 @@ =20 #ifndef __ASSEMBLY__ =20 +enum vvar_pages { + VVAR_DATA_PAGE_OFFSET, + VVAR_TIMENS_PAGE_OFFSET, + VVAR_NR_PAGES, +}; + #include =20 #define VDSO_SYMBOL(base, name) \ diff --git a/arch/arm64/include/asm/vdso/getrandom.h b/arch/arm64/include/a= sm/vdso/getrandom.h new file mode 100644 index 000000000000..6cda64e6da83 --- /dev/null +++ b/arch/arm64/include/asm/vdso/getrandom.h @@ -0,0 +1,50 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#ifndef __ASM_VDSO_GETRANDOM_H +#define __ASM_VDSO_GETRANDOM_H + +#ifndef __ASSEMBLY__ + +#include +#include +#include + +/** + * getrandom_syscall - Invoke the getrandom() syscall. + * @buffer: Destination buffer to fill with random bytes. + * @len: Size of @buffer in bytes. + * @flags: Zero or more GRND_* flags. + * Returns: The number of random bytes written to @buffer, or a negative v= alue indicating an error. + */ +static __always_inline ssize_t getrandom_syscall(void *_buffer, size_t _le= n, unsigned int _flags) +{ + register void *buffer asm ("x0") =3D _buffer; + register size_t len asm ("x1") =3D _len; + register unsigned int flags asm ("x2") =3D _flags; + register long ret asm ("x0"); + register long nr asm ("x8") =3D __NR_getrandom; + + asm volatile( + " svc #0\n" + : "=3Dr" (ret) + : "r" (buffer), "r" (len), "r" (flags), "r" (nr) + : "memory"); + + return ret; +} + +static __always_inline const struct vdso_rng_data *__arch_get_vdso_rng_dat= a(void) +{ + /* + * The RNG data is in the real VVAR data page, but if a task belongs to a= time namespace + * then VVAR_DATA_PAGE_OFFSET points to the namespace-specific VVAR page = and VVAR_TIMENS_ + * PAGE_OFFSET points to the real VVAR page. + */ + if (IS_ENABLED(CONFIG_TIME_NS) && _vdso_data->clock_mode =3D=3D VDSO_CLOC= KMODE_TIMENS) + return (void *)&_vdso_rng_data + VVAR_TIMENS_PAGE_OFFSET * (1UL << CONFI= G_PAGE_SHIFT); + return &_vdso_rng_data; +} + +#endif /* !__ASSEMBLY__ */ + +#endif /* __ASM_VDSO_GETRANDOM_H */ diff --git a/arch/arm64/include/asm/vdso/vsyscall.h b/arch/arm64/include/as= m/vdso/vsyscall.h index f94b1457c117..b4241510dc36 100644 --- a/arch/arm64/include/asm/vdso/vsyscall.h +++ b/arch/arm64/include/asm/vdso/vsyscall.h @@ -2,8 +2,11 @@ #ifndef __ASM_VDSO_VSYSCALL_H #define __ASM_VDSO_VSYSCALL_H =20 +#define __VDSO_RND_DATA_OFFSET 480 + #ifndef __ASSEMBLY__ =20 +#include #include #include =20 @@ -21,6 +24,13 @@ struct vdso_data *__arm64_get_k_vdso_data(void) } #define __arch_get_k_vdso_data __arm64_get_k_vdso_data =20 +static __always_inline +struct vdso_rng_data *__arm64_get_k_vdso_rnd_data(void) +{ + return (void *)vdso_data + __VDSO_RND_DATA_OFFSET; +} +#define __arch_get_k_vdso_rng_data __arm64_get_k_vdso_rnd_data + static __always_inline void __arm64_update_vsyscall(struct vdso_data *vdata, struct timekeeper *t= k) { diff --git a/arch/arm64/kernel/vdso.c b/arch/arm64/kernel/vdso.c index 89b6e7840002..706c9c3a7a50 100644 --- a/arch/arm64/kernel/vdso.c +++ b/arch/arm64/kernel/vdso.c @@ -34,12 +34,6 @@ enum vdso_abi { VDSO_ABI_AA32, }; =20 -enum vvar_pages { - VVAR_DATA_PAGE_OFFSET, - VVAR_TIMENS_PAGE_OFFSET, - VVAR_NR_PAGES, -}; - struct vdso_abi_info { const char *name; const char *vdso_code_start; diff --git a/arch/arm64/kernel/vdso/Makefile b/arch/arm64/kernel/vdso/Makef= ile index d11da6461278..35685c036044 100644 --- a/arch/arm64/kernel/vdso/Makefile +++ b/arch/arm64/kernel/vdso/Makefile @@ -9,7 +9,7 @@ # Include the generic Makefile to check the built vdso. include $(srctree)/lib/vdso/Makefile =20 -obj-vdso :=3D vgettimeofday.o note.o sigreturn.o +obj-vdso :=3D vgettimeofday.o note.o sigreturn.o vgetrandom.o vgetrandom-c= hacha.o =20 # Build rules targets :=3D $(obj-vdso) vdso.so vdso.so.dbg @@ -34,19 +34,28 @@ ccflags-y :=3D -fno-common -fno-builtin -fno-stack-prot= ector -ffixed-x18 ccflags-y +=3D -DDISABLE_BRANCH_PROFILING -DBUILD_VDSO =20 # -Wmissing-prototypes and -Wmissing-declarations are removed from -# the CFLAGS of vgettimeofday.c to make possible to build the -# kernel with CONFIG_WERROR enabled. -CFLAGS_REMOVE_vgettimeofday.o =3D $(CC_FLAGS_FTRACE) -Os $(CC_FLAGS_SCS) \ - $(RANDSTRUCT_CFLAGS) $(GCC_PLUGINS_CFLAGS) \ - $(CC_FLAGS_LTO) $(CC_FLAGS_CFI) \ - -Wmissing-prototypes -Wmissing-declarations +# the CFLAGS to make possible to build the kernel with CONFIG_WERROR enabl= ed. +CC_FLAGS_REMOVE_VDSO :=3D $(CC_FLAGS_FTRACE) -Os $(CC_FLAGS_SCS) \ + $(RANDSTRUCT_CFLAGS) $(GCC_PLUGINS_CFLAGS) \ + $(CC_FLAGS_LTO) $(CC_FLAGS_CFI) \ + -Wmissing-prototypes -Wmissing-declarations =20 -CFLAGS_vgettimeofday.o =3D -O2 -mcmodel=3Dtiny -fasynchronous-unwind-tables +CC_FLAGS_ADD_VDSO :=3D -O2 -mcmodel=3Dtiny -fasynchronous-unwind-tables + +CFLAGS_REMOVE_vgettimeofday.o =3D $(CC_FLAGS_REMOVE_VDSO) +CFLAGS_REMOVE_vgetrandom.o =3D $(CC_FLAGS_REMOVE_VDSO) + +CFLAGS_vgettimeofday.o =3D $(CC_FLAGS_ADD_VDSO) +CFLAGS_vgetrandom.o =3D $(CC_FLAGS_ADD_VDSO) =20 ifneq ($(c-gettimeofday-y),) CFLAGS_vgettimeofday.o +=3D -include $(c-gettimeofday-y) endif =20 +ifneq ($(c-getrandom-y),) + CFLAGS_vgetrandom.o +=3D -include $(c-getrandom-y) +endif + targets +=3D vdso.lds CPPFLAGS_vdso.lds +=3D -P -C -U$(ARCH) =20 diff --git a/arch/arm64/kernel/vdso/vdso b/arch/arm64/kernel/vdso/vdso new file mode 120000 index 000000000000..233c7a26f6e5 --- /dev/null +++ b/arch/arm64/kernel/vdso/vdso @@ -0,0 +1 @@ +../../../arch/arm64/kernel/vdso \ No newline at end of file diff --git a/arch/arm64/kernel/vdso/vdso.lds.S b/arch/arm64/kernel/vdso/vds= o.lds.S index 45354f2ddf70..f204a9ddc833 100644 --- a/arch/arm64/kernel/vdso/vdso.lds.S +++ b/arch/arm64/kernel/vdso/vdso.lds.S @@ -11,7 +11,9 @@ #include #include #include +#include #include +#include =20 OUTPUT_FORMAT("elf64-littleaarch64", "elf64-bigaarch64", "elf64-littleaarc= h64") OUTPUT_ARCH(aarch64) @@ -19,6 +21,7 @@ OUTPUT_ARCH(aarch64) SECTIONS { PROVIDE(_vdso_data =3D . - __VVAR_PAGES * PAGE_SIZE); + PROVIDE(_vdso_rng_data =3D _vdso_data + __VDSO_RND_DATA_OFFSET); #ifdef CONFIG_TIME_NS PROVIDE(_timens_data =3D _vdso_data + PAGE_SIZE); #endif @@ -102,6 +105,7 @@ VERSION __kernel_gettimeofday; __kernel_clock_gettime; __kernel_clock_getres; + __kernel_getrandom; local: *; }; } diff --git a/arch/arm64/kernel/vdso/vgetrandom-chacha.S b/arch/arm64/kernel= /vdso/vgetrandom-chacha.S new file mode 100644 index 000000000000..4e5f9c349522 --- /dev/null +++ b/arch/arm64/kernel/vdso/vgetrandom-chacha.S @@ -0,0 +1,178 @@ +// SPDX-License-Identifier: GPL-2.0 + +#include +#include +#include + + .text + +#define state0 v0 +#define state1 v1 +#define state2 v2 +#define state3 v3 +#define copy0 v4 +#define copy0_q q4 +#define copy1 v5 +#define copy2 v6 +#define copy3 v7 +#define copy3_d d7 +#define one_d d16 +#define one_q q16 +#define one_v v16 +#define tmp v17 +#define rot8 v18 + +/* + * ARM64 ChaCha20 implementation meant for vDSO. Produces a given positive + * number of blocks of output with nonce 0, taking an input key and 8-bytes + * counter. Importantly does not spill to the stack. + * + * This implementation avoids d8-d15 because they are callee-save in user + * space. + * + * void __arch_chacha20_blocks_nostack(uint8_t *dst_bytes, + * const uint8_t *key, + * uint32_t *counter, + * size_t nblocks) + * + * x0: output bytes + * x1: 32-byte key input + * x2: 8-byte counter input/output + * x3: number of 64-byte block to write to output + */ +SYM_FUNC_START(__arch_chacha20_blocks_nostack) + + /* copy0 =3D "expand 32-byte k" */ + mov_q x8, 0x3320646e61707865 + mov_q x9, 0x6b20657479622d32 + mov copy0.d[0], x8 + mov copy0.d[1], x9 + + /* copy1,copy2 =3D key */ + ld1 { copy1.4s, copy2.4s }, [x1] + /* copy3 =3D counter || zero nonce */ + ldr copy3_d, [x2] +CPU_BE( rev64 copy3.4s, copy3.4s) + + movi one_v.2s, #1 + uzp1 one_v.4s, one_v.4s, one_v.4s + +.Lblock: + /* copy state to auxiliary vectors for the final add after the permute. = */ + mov state0.16b, copy0.16b + mov state1.16b, copy1.16b + mov state2.16b, copy2.16b + mov state3.16b, copy3.16b + + mov w4, 20 +.Lpermute: + /* + * Permute one 64-byte block where the state matrix is stored in the four= NEON + * registers state0-state3. It performs matrix operations on four words = in parallel, + * but requires shuffling to rearrange the words after each round. + */ + +.Ldoubleround: + /* state0 +=3D state1, state3 =3D rotl32(state3 ^ state0, 16) */ + add state0.4s, state0.4s, state1.4s + eor state3.16b, state3.16b, state0.16b + rev32 state3.8h, state3.8h + + /* state2 +=3D state3, state1 =3D rotl32(state1 ^ state2, 12) */ + add state2.4s, state2.4s, state3.4s + eor tmp.16b, state1.16b, state2.16b + shl state1.4s, tmp.4s, #12 + sri state1.4s, tmp.4s, #20 + + /* state0 +=3D state1, state3 =3D rotl32(state3 ^ state0, 8) */ + add state0.4s, state0.4s, state1.4s + eor tmp.16b, state3.16b, state0.16b + shl state3.4s, tmp.4s, #8 + sri state3.4s, tmp.4s, #24 + + /* state2 +=3D state3, state1 =3D rotl32(state1 ^ state2, 7) */ + add state2.4s, state2.4s, state3.4s + eor tmp.16b, state1.16b, state2.16b + shl state1.4s, tmp.4s, #7 + sri state1.4s, tmp.4s, #25 + + /* state1[0,1,2,3] =3D state1[1,2,3,0] */ + ext state1.16b, state1.16b, state1.16b, #4 + /* state2[0,1,2,3] =3D state2[2,3,0,1] */ + ext state2.16b, state2.16b, state2.16b, #8 + /* state3[0,1,2,3] =3D state3[1,2,3,0] */ + ext state3.16b, state3.16b, state3.16b, #12 + + /* state0 +=3D state1, state3 =3D rotl32(state3 ^ state0, 16) */ + add state0.4s, state0.4s, state1.4s + eor state3.16b, state3.16b, state0.16b + rev32 state3.8h, state3.8h + + /* state2 +=3D state3, state1 =3D rotl32(state1 ^ state2, 12) */ + add state2.4s, state2.4s, state3.4s + eor tmp.16b, state1.16b, state2.16b + shl state1.4s, tmp.4s, #12 + sri state1.4s, tmp.4s, #20 + + /* state0 +=3D state1, state3 =3D rotl32(state3 ^ state0, 8) */ + add state0.4s, state0.4s, state1.4s + eor tmp.16b, state3.16b, state0.16b + shl state3.4s, tmp.4s, #8 + sri state3.4s, tmp.4s, #24 + + /* state2 +=3D state3, state1 =3D rotl32(state1 ^ state2, 7) */ + add state2.4s, state2.4s, state3.4s + eor tmp.16b, state1.16b, state2.16b + shl state1.4s, tmp.4s, #7 + sri state1.4s, tmp.4s, #25 + + /* state1[0,1,2,3] =3D state1[3,0,1,2] */ + ext state1.16b, state1.16b, state1.16b, #12 + /* state2[0,1,2,3] =3D state2[2,3,0,1] */ + ext state2.16b, state2.16b, state2.16b, #8 + /* state3[0,1,2,3] =3D state3[1,2,3,0] */ + ext state3.16b, state3.16b, state3.16b, #4 + + subs w4, w4, #2 + b.ne .Ldoubleround + + /* output0 =3D state0 + state0 */ + add state0.4s, state0.4s, copy0.4s +CPU_BE( rev32 state0.16b, state0.16b) + /* output1 =3D state1 + state1 */ + add state1.4s, state1.4s, copy1.4s +CPU_BE( rev32 state1.16b, state1.16b) + /* output2 =3D state2 + state2 */ + add state2.4s, state2.4s, copy2.4s +CPU_BE( rev32 state2.16b, state2.16b) + /* output2 =3D state3 + state3 */ + add state3.4s, state3.4s, copy3.4s +CPU_BE( rev32 state3.16b, state3.16b) + st1 { state0.4s - state3.4s }, [x0] + + /* + * ++copy3.counter, the 'add' clears the upper half of the SIMD register + * which is the expected behaviour here. + */ + add copy3_d, copy3_d, one_d + + /* output +=3D 64, --nblocks */ + add x0, x0, 64 + subs x3, x3, #1 + b.ne .Lblock + + /* counter =3D copy3.counter */ +CPU_BE( rev64 copy3.4s, copy3.4s) + str copy3_d, [x2] + + /* Zero out the potentially sensitive regs, in case nothing uses these ag= ain. */ + movi state0.16b, #0 + movi state1.16b, #0 + movi state2.16b, #0 + movi state3.16b, #0 + movi copy1.16b, #0 + movi copy2.16b, #0 + ret +SYM_FUNC_END(__arch_chacha20_blocks_nostack) + +emit_aarch64_feature_1_and diff --git a/arch/arm64/kernel/vdso/vgetrandom.c b/arch/arm64/kernel/vdso/v= getrandom.c new file mode 100644 index 000000000000..832fe195292b --- /dev/null +++ b/arch/arm64/kernel/vdso/vgetrandom.c @@ -0,0 +1,15 @@ +// SPDX-License-Identifier: GPL-2.0 + +#include + +typeof(__cvdso_getrandom) __kernel_getrandom; + +ssize_t __kernel_getrandom(void *buffer, size_t len, unsigned int flags, v= oid *opaque_state, size_t opaque_len) +{ + if (alternative_has_cap_likely(ARM64_HAS_FPSIMD)) + return __cvdso_getrandom(buffer, len, flags, opaque_state, opaque_len); + + if (unlikely(opaque_len =3D=3D ~0UL && !buffer && !len && !flags)) + return -ENOSYS; + return getrandom_syscall(buffer, len, flags); +} diff --git a/tools/arch/arm64/vdso b/tools/arch/arm64/vdso new file mode 120000 index 000000000000..233c7a26f6e5 --- /dev/null +++ b/tools/arch/arm64/vdso @@ -0,0 +1 @@ +../../../arch/arm64/kernel/vdso \ No newline at end of file diff --git a/tools/include/linux/compiler.h b/tools/include/linux/compiler.h index 6f7f22ac9da5..4366da278033 100644 --- a/tools/include/linux/compiler.h +++ b/tools/include/linux/compiler.h @@ -2,6 +2,8 @@ #ifndef _TOOLS_LINUX_COMPILER_H_ #define _TOOLS_LINUX_COMPILER_H_ =20 +#ifndef __ASSEMBLY__ + #include =20 #ifndef __compiletime_error @@ -224,4 +226,6 @@ static __always_inline void __write_once_size(volatile = void *p, void *res, int s __asm__ ("" : "=3Dr" (var) : "0" (var)) #endif =20 +#endif /* __ASSEMBLY__ */ + #endif /* _TOOLS_LINUX_COMPILER_H */ diff --git a/tools/testing/selftests/vDSO/Makefile b/tools/testing/selftest= s/vDSO/Makefile index 04930125035e..3c6fafbd83a6 100644 --- a/tools/testing/selftests/vDSO/Makefile +++ b/tools/testing/selftests/vDSO/Makefile @@ -9,7 +9,7 @@ ifeq ($(ARCH),$(filter $(ARCH),x86 x86_64)) TEST_GEN_PROGS +=3D vdso_standalone_test_x86 endif TEST_GEN_PROGS +=3D vdso_test_correctness -ifeq ($(ARCH)$(CONFIG_X86_32),$(filter $(ARCH)$(CONFIG_X86_32),x86 x86_64 = loongarch)) +ifeq ($(ARCH)$(CONFIG_X86_32),$(filter $(ARCH)$(CONFIG_X86_32),x86 x86_64 = loongarch arm64)) TEST_GEN_PROGS +=3D vdso_test_getrandom TEST_GEN_PROGS +=3D vdso_test_chacha endif @@ -40,5 +40,6 @@ $(OUTPUT)/vdso_test_getrandom: CFLAGS +=3D -isystem $(top= _srcdir)/tools/include \ $(OUTPUT)/vdso_test_chacha: $(top_srcdir)/tools/arch/$(SRCARCH)/vdso/vgetr= andom-chacha.S $(OUTPUT)/vdso_test_chacha: CFLAGS +=3D -idirafter $(top_srcdir)/tools/inc= lude \ -idirafter $(top_srcdir)/arch/$(SRCA= RCH)/include \ + -idirafter $(top_srcdir)/arch/$(SRCA= RCH)/include/generated \ -idirafter $(top_srcdir)/include \ -D__ASSEMBLY__ -Wa,--noexecstack --=20 2.43.0