From patchwork Wed Jan 3 17:14:48 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sergey Bugaev X-Patchwork-Id: 1882027 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20230601 header.b=U2LuACRo; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=sourceware.org (client-ip=2620:52:3:1:0:246e:9693:128c; helo=server2.sourceware.org; envelope-from=libc-alpha-bounces+incoming=patchwork.ozlabs.org@sourceware.org; receiver=patchwork.ozlabs.org) Received: from server2.sourceware.org (server2.sourceware.org [IPv6:2620:52:3:1:0:246e:9693:128c]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (secp384r1) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4T4xJs5dt4z1yQ5 for ; Thu, 4 Jan 2024 04:18:53 +1100 (AEDT) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id C0AA8385F028 for ; Wed, 3 Jan 2024 17:18:51 +0000 (GMT) X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-lf1-x134.google.com (mail-lf1-x134.google.com [IPv6:2a00:1450:4864:20::134]) by sourceware.org (Postfix) with ESMTPS id 11F1938582AD for ; Wed, 3 Jan 2024 17:15:21 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 11F1938582AD Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=gmail.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 11F1938582AD Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=2a00:1450:4864:20::134 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1704302125; cv=none; b=Zm9U7aBZ6JU+jPM4XCb4ms98VO3WZWuk7c5n/mghs2xC83GFsD4ZpCYP5akXTa1PRUzsUzHwQDp4Ep8ooUw80ibmFteZBayvcPRU1qGedL/I+AgIdVqChKQzJKAXSnLJwF25eFVblJthbkM6n1WlDejDEDN4EK0hMkR7FaflxAw= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1704302125; c=relaxed/simple; bh=EhYjx4XAnScGgVDb/ZctUqO8yC/Slv8oo7sAsFj9cPw=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=sdZK9Wtxi8EyqdQOvHC76CPIGY4bIorMRPLVGcBDCi3B6YQQN/xKu7T9M/WZYyFmZquO/j1+C3HEuBeCL8Cw2zDWv+mV0d9m5vrMdJKjSrDJ570iEAJ5LR+mZLOrgTcj8qAgKdMAr9Lca0bo72CoE9id/QFfUx5Dp60sHaVpypo= ARC-Authentication-Results: i=1; server2.sourceware.org Received: by mail-lf1-x134.google.com with SMTP id 2adb3069b0e04-50e7dff3e9fso7927339e87.2 for ; Wed, 03 Jan 2024 09:15:20 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1704302119; x=1704906919; darn=sourceware.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=jFmI3igiG2KBkQZYPxqWmw6k7l9/jO+f5UcpFf6pQKY=; b=U2LuACRoBUuHOLm1zVrjqAgR4kRQdQxgtpIwzew0ux/rkWRnU2j17fVmkugLJjceeX CprsIQ1tFpQb9XMpaPH40BSYuDJ0mK0JmWa2s081x485qSd6zPMoEfiCmEdyODkVhXlW 0j/62zUBJUYwt7+kRjJiZDTeKk/5iEg7tHujKL7gIm+OFBbLXAt5sWllIfh6TpvXClzK Oz/ARYtKVnTVH9pkGdkJiIG6IhLO8fxivXO0DQNNnJ4O7XbsDwwwIS1K/BMhqCaoNxsW ndEI6+hCSQBM51eEC0sO4Ph0A99asU32vJqfMgKJ7amTE1x4ej3FBrq7XN0Zx1Ly0Jhg xveA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1704302119; x=1704906919; 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=jFmI3igiG2KBkQZYPxqWmw6k7l9/jO+f5UcpFf6pQKY=; b=RQC3FHCZ7EGwAQ1d/wZ1tryq9OTwa+0J3NWYnB3ZRzC+Y+q3WR0be83yd/lAXaYBrW dzT5deZ25NhY1IiHtfQ9H+ZT9PTYoeoc02gYDublPGZ9xSFBysThVJrPss+4MxfFhfxf Q+c5neUKWgQwA67h092+ohuShz6m00H/4OgYFXy7UbhbYk+MGgmH0tWSvRd/nHhPJd8L b3wuM2TDCSHZMGPtEnO70AX5+0uonkSEnf1DyXYvN4RClzTLQKNuU6IPK1o5lcxvYrHo a2e2t6E2DOFn1cb5Yf12JKqbKxnQL4hiK8oXWzKCRwA4534ox8AYIVsjEwxsBufj6woE fa4Q== X-Gm-Message-State: AOJu0Yyc36mYD3Gsa6tXhUQkj8EQhhZOtbBKFpGKzNx1SDqKXGr4D5UU GAhM2Ai0293t+wr5Bu/JL0xOW2uqnHw= X-Google-Smtp-Source: AGHT+IG4RTAh2ZU439PF1hiJE3ty/iEZLtfVzq3hhLWPD2H2WTI34y521e/YNyghgCDyJNBCQksGLw== X-Received: by 2002:ac2:4188:0:b0:50e:3649:8649 with SMTP id z8-20020ac24188000000b0050e36498649mr7087188lfh.61.1704302118644; Wed, 03 Jan 2024 09:15:18 -0800 (PST) Received: from surface-pro-6.. ([2a00:1370:818c:b32f:ebdc:fd0:376b:8006]) by smtp.gmail.com with ESMTPSA id y23-20020a196417000000b0050e6d84d177sm3546068lfb.279.2024.01.03.09.15.17 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 03 Jan 2024 09:15:18 -0800 (PST) From: Sergey Bugaev To: libc-alpha@sourceware.org, bug-hurd@gnu.org Subject: [RFC PATCH 15/23] mach: Add a basic AArch64 port Date: Wed, 3 Jan 2024 20:14:48 +0300 Message-ID: <20240103171502.1358371-16-bugaevc@gmail.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240103171502.1358371-1-bugaevc@gmail.com> References: <20240103171502.1358371-1-bugaevc@gmail.com> MIME-Version: 1.0 X-Spam-Status: No, score=-11.2 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_FROM, GIT_PATCH_0, KAM_SHORT, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libc-alpha-bounces+incoming=patchwork.ozlabs.org@sourceware.org This doesn't add any of the Hurd- or HTL-specific bits yet. Signed-off-by: Sergey Bugaev --- I don't think RPC_aarch64_get_hwcaps.c actually needs no-stack-protector since the stack protector is not (currently?) stored in TLS on AArch64, but let's have it there for consistency. cpu-features.c is heavily based on its Linux version, but hooked up to use the aarch64_get_hwcaps () RPC, invented specifically for this purpose, instead of auxval entries, which we don't have on the Hurd. sys/ucontext.h is mid-way between the Linux version (and x86 Hurd versions) and the FreeBSD version, but laid out to match the Mach aarch64_thread_state. Notably, like on FreeBSD, gregs/fpregs is an actual struct and not an array; but the field naming is like that of Linux and Hurd-on-x86. This unfortunately means there will be no source-level compatibility for applications with either Linux or BSD sys/ucontext.h. mach/Makefile | 1 + sysdeps/mach/aarch64/bits/mach/param.h | 24 ++++++ sysdeps/mach/aarch64/cpu-features.c | 109 +++++++++++++++++++++++++ sysdeps/mach/aarch64/sys/ucontext.h | 73 +++++++++++++++++ sysdeps/mach/aarch64/sysdep.h | 45 ++++++++++ sysdeps/mach/aarch64/thread_state.h | 44 ++++++++++ sysdeps/mach/configure | 1 + sysdeps/mach/configure.ac | 1 + 8 files changed, 298 insertions(+) create mode 100644 sysdeps/mach/aarch64/bits/mach/param.h create mode 100644 sysdeps/mach/aarch64/cpu-features.c create mode 100644 sysdeps/mach/aarch64/sys/ucontext.h create mode 100644 sysdeps/mach/aarch64/sysdep.h create mode 100644 sysdeps/mach/aarch64/thread_state.h diff --git a/mach/Makefile b/mach/Makefile index 0ea3b3c1..92394951 100644 --- a/mach/Makefile +++ b/mach/Makefile @@ -56,6 +56,7 @@ generated = # Avoid ssp before TLS is initialized. CFLAGS-mach_init.o = $(no-stack-protector) +CFLAGS-RPC_aarch64_get_hwcaps.o = $(no-stack-protector) CFLAGS-RPC_vm_statistics.o = $(no-stack-protector) CFLAGS-RPC_vm_map.o = $(no-stack-protector) CFLAGS-RPC_vm_protect.o = $(no-stack-protector) diff --git a/sysdeps/mach/aarch64/bits/mach/param.h b/sysdeps/mach/aarch64/bits/mach/param.h new file mode 100644 index 00000000..4f7b76ed --- /dev/null +++ b/sysdeps/mach/aarch64/bits/mach/param.h @@ -0,0 +1,24 @@ +/* Old-style Unix parameters and limits. aarch64 Mach version. + Copyright (C) 1993-2024 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#ifndef _SYS_PARAM_H +# error "Never use directly; include instead." +#endif + +/* There is no EXEC_PAGESIZE. Use vm_page_size or getpagesize () + or sysconf (_SC_PAGESIZE) instead. */ diff --git a/sysdeps/mach/aarch64/cpu-features.c b/sysdeps/mach/aarch64/cpu-features.c new file mode 100644 index 00000000..a818bf76 --- /dev/null +++ b/sysdeps/mach/aarch64/cpu-features.c @@ -0,0 +1,109 @@ +/* Initialize CPU feature data. Mach aarch64 version. + This file is part of the GNU C Library. + Copyright (C) 2017-2024 Free Software Foundation, Inc. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#include +#include +#include +#include +#include + +#define DCZID_DZP_MASK (1 << 4) +#define DCZID_BS_MASK (0xf) + +/* The maximal set of permitted tags that the MTE random tag generation + instruction may use. We exclude tag 0 because a) we want to reserve + that for the libc heap structures and b) because it makes it easier + to see when pointer have been correctly tagged. */ +#define MTE_ALLOWED_TAGS (0xfffe << PR_MTE_TAG_SHIFT) + +struct cpu_list +{ + const char *name; + size_t len; + uint64_t midr; +}; + +static const struct cpu_list cpu_list[] = +{ +#define CPU_LIST_ENTRY(__str, __num) { __str, sizeof (__str) - 1, __num } + CPU_LIST_ENTRY ("thunderxt88", 0x430F0A10), + CPU_LIST_ENTRY ("thunderx2t99", 0x431F0AF0), + CPU_LIST_ENTRY ("thunderx2t99p1", 0x420F5160), + CPU_LIST_ENTRY ("ares", 0x411FD0C0), + CPU_LIST_ENTRY ("emag", 0x503F0001), + CPU_LIST_ENTRY ("kunpeng920", 0x481FD010), + CPU_LIST_ENTRY ("a64fx", 0x460F0010), + CPU_LIST_ENTRY ("generic", 0x0), +}; + +static uint64_t +get_midr_from_mcpu (const struct tunable_str_t *mcpu) +{ + for (int i = 0; i < array_length (cpu_list); i++) + if (tunable_strcmp (mcpu, cpu_list[i].name, cpu_list[i].len)) + return cpu_list[i].midr; + + return UINT64_MAX; +} + +static inline void +init_cpu_features (struct cpu_features *cpu_features) +{ + error_t err; + uint32_t hwcaps[HWCAPS_COUNT]; + mach_msg_type_number_t hwcaps_size = HWCAPS_COUNT; + uint64_t midr, revidr; + + err = __aarch64_get_hwcaps (__mach_host_self (), hwcaps, + &hwcaps_size, &midr, &revidr); + assert_perror (err); + + if (hwcaps_size >= 1) + GLRO (dl_hwcap) = hwcaps[0]; + if (hwcaps_size >= 2) + GLRO (dl_hwcap2) = hwcaps[1]; + + cpu_features->midr_el1 = midr; + + /* Get the tunable override. */ + const struct tunable_str_t *mcpu = TUNABLE_GET (glibc, cpu, name, + struct tunable_str_t *, + NULL); + if (mcpu != NULL) + { + midr = get_midr_from_mcpu (mcpu); + if (midr != UINT64_MAX) + cpu_features->midr_el1 = midr; + } + + /* Check if ZVA is enabled. */ + unsigned dczid; + asm volatile ("mrs %0, dczid_el0" : "=r"(dczid)); + + if ((dczid & DCZID_DZP_MASK) == 0) + cpu_features->zva_size = 4 << (dczid & DCZID_BS_MASK); + + /* Check if BTI is supported. */ + cpu_features->bti = GLRO (dl_hwcap2) & HWCAP2_BTI; + + /* Check if SVE is supported. */ + cpu_features->sve = GLRO (dl_hwcap) & HWCAP_SVE; + + /* Check if MOPS is supported. */ + cpu_features->mops = GLRO (dl_hwcap2) & HWCAP2_MOPS; +} diff --git a/sysdeps/mach/aarch64/sys/ucontext.h b/sysdeps/mach/aarch64/sys/ucontext.h new file mode 100644 index 00000000..f77ebc87 --- /dev/null +++ b/sysdeps/mach/aarch64/sys/ucontext.h @@ -0,0 +1,73 @@ +/* Copyright (C) 1998-2024 Free Software Foundation, Inc. + + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +/* System V/AArch64 ABI compliant context switching support. */ + +#ifndef _SYS_UCONTEXT_H +#define _SYS_UCONTEXT_H 1 + +#include + +#include +#include + +#ifdef __USE_MISC +# define __ctx(fld) fld +#else +# define __ctx(fld) __ ## fld +#endif + +/* Type for general register. */ +__extension__ typedef long long int greg_t; + +/* gregset_t is laid out to match mach/aarch64/thread_status.h:struct aarch64_thread_state */ +typedef struct +{ + greg_t __ctx(x)[31]; + greg_t __ctx(sp); + greg_t __ctx(pc); + greg_t __ctx(tpidr_el0); + unsigned int __ctx(cpsr); +} gregset_t; + +/* fpregset_t is laid out to match mach/aarch64/thread_status.h:struct aarch64_float_state */ +typedef struct +{ + __int128_t __ctx(v)[32]; + unsigned int __ctx(fpsr); + unsigned int __ctx(fpcr); +} fpregset_t; + +typedef struct +{ + gregset_t __ctx(gregs); + fpregset_t __ctx(fpregs); +} mcontext_t; + +typedef struct ucontext_t +{ + unsigned long __ctx(uc_flags); + struct ucontext_t *uc_link; + stack_t uc_stack; + sigset_t uc_sigmask; + mcontext_t uc_mcontext; +} ucontext_t; + +#undef __ctx + +#endif /* sys/ucontext.h */ diff --git a/sysdeps/mach/aarch64/sysdep.h b/sysdeps/mach/aarch64/sysdep.h new file mode 100644 index 00000000..edf8e016 --- /dev/null +++ b/sysdeps/mach/aarch64/sysdep.h @@ -0,0 +1,45 @@ +/* Copyright (C) 1991-2024 Free Software Foundation, Inc. + + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#ifndef _MACH_AARCH64_SYSDEP_H +#define _MACH_AARCH64_SYSDEP_H 1 + +/* Defines RTLD_PRIVATE_ERRNO and USE_DL_SYSINFO. */ +#include +#include +/* Get the hwcap definitions. */ +#include + +#define LOSE asm volatile ("udf #0xdead") + +#define STACK_GROWTH_DOWN + +/* Get the machine-independent Mach definitions. */ +#include + +#undef ENTRY +#undef ALIGN + +#define RETURN_TO(sp, pc, retval) \ + asm volatile ("mov sp, %0; mov x30, %1; ret" \ + : : "r" (sp), "r" (pc)) + +#include +#include + +#endif /* mach/aarch64/sysdep.h */ diff --git a/sysdeps/mach/aarch64/thread_state.h b/sysdeps/mach/aarch64/thread_state.h new file mode 100644 index 00000000..5ddf9118 --- /dev/null +++ b/sysdeps/mach/aarch64/thread_state.h @@ -0,0 +1,44 @@ +/* Mach thread state definitions for machine-independent code. aarch64 version. + Copyright (C) 1994-2024 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#ifndef _MACH_AARCH64_THREAD_STATE_H +#define _MACH_AARCH64_THREAD_STATE_H 1 + +#include +#include + +#define MACHINE_NEW_THREAD_STATE_FLAVOR AARCH64_THREAD_STATE +#define MACHINE_THREAD_STATE_FLAVOR AARCH64_THREAD_STATE +#define MACHINE_THREAD_STATE_COUNT AARCH64_THREAD_STATE_COUNT + +#define machine_thread_state aarch64_thread_state + +#define PC pc +#define SP sp +#define SYSRETURN x[0] + +struct machine_thread_all_state + { + struct aarch64_thread_state basic; + struct aarch64_float_state fpu; + int set; + }; + +#include + +#endif /* mach/aarch64/thread_state.h */ diff --git a/sysdeps/mach/configure b/sysdeps/mach/configure index f15160d0..18f98967 100644 --- a/sysdeps/mach/configure +++ b/sysdeps/mach/configure @@ -268,6 +268,7 @@ for ifc in mach mach4 gnumach \ clock clock_priv host_priv host_security ledger lock_set \ processor processor_set task task_notify thread_act vm_map \ memory_object memory_object_default i386/mach_i386 x86_64/mach_i386 \ + aarch64/mach_aarch64 \ ; do as_ac_Header=`printf "%s\n" "ac_cv_header_mach/${ifc}.defs" | $as_tr_sh` ac_fn_c_check_header_preproc "$LINENO" "mach/${ifc}.defs" "$as_ac_Header" diff --git a/sysdeps/mach/configure.ac b/sysdeps/mach/configure.ac index 730fb25d..03e45df2 100644 --- a/sysdeps/mach/configure.ac +++ b/sysdeps/mach/configure.ac @@ -64,6 +64,7 @@ for ifc in mach mach4 gnumach \ clock clock_priv host_priv host_security ledger lock_set \ processor processor_set task task_notify thread_act vm_map \ memory_object memory_object_default i386/mach_i386 x86_64/mach_i386 \ + aarch64/mach_aarch64 \ ; do AC_CHECK_HEADER(mach/${ifc}.defs, [dnl mach_interface_list="$mach_interface_list $ifc"],, -)