From patchwork Mon Sep 13 01:41:16 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vincent Chen X-Patchwork-Id: 44931 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 923973858429 for ; Mon, 13 Sep 2021 01:43:25 +0000 (GMT) X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-pf1-x431.google.com (mail-pf1-x431.google.com [IPv6:2607:f8b0:4864:20::431]) by sourceware.org (Postfix) with ESMTPS id 0EB943857C76 for ; Mon, 13 Sep 2021 01:41:42 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 0EB943857C76 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=sifive.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=sifive.com Received: by mail-pf1-x431.google.com with SMTP id j16so7355112pfc.2 for ; Sun, 12 Sep 2021 18:41:42 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sifive.com; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=t2WrEjYWz9ib+JYKbyF1O9NW4OZkmT437+KMSkBchIE=; b=aAg83HE1FeqQKQ0zKihzxuoYjrX0dgNMvesjgD0KwQ9aqkoK9trodP2y36I/rMzMdr /KN0+7R5YHFYsSd7AniCKDwcD3nIbDaUqGtA+Fo2RTvzailuMulb2yEhNN2KvGxzE0E2 ygGM7TWgKTQXD49hF1AJV3NhZauQIHXJvIO9ZD/xGWp3VcaTjImxADBzZCysaMzemOHT y/PMGTC03Q2oAtkVr0uXvAdcPoHy50DEJnh6t81f//YfjcZ7ZJCavu0R8DJrnV44NdPO UP7sQpcOnTtNxUxHnu3ArLIJVn1eAekrpuX00DiOci9jn0cx+ilOlFgWHtSql7dcSj3T nKZA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=t2WrEjYWz9ib+JYKbyF1O9NW4OZkmT437+KMSkBchIE=; b=rRSbz/5PsHx1oCvolDlsUmQKIzHfoHnrhVkVKZMPseg3MyKlNXSrrVdzLJ4euJki8B E63i7hq82/FFfCCWM7PDAeIqTqjL0FwQzg2rCRJ3Y17rTZfCJQn1rh5QXYnpn5m4x9W3 OrrTGkxyoj1m7JhUh5F9a/AGNdIYYgZEzy5bhQpOleyjNKzQBeWjXChO/Eg0Cf2I0WUN qvdDNcvT4h2YP9vzMVtRQdDaK0G6B1qWxxAMVI0+STjwxL2BufhnDgMHe/nvwxolKKVQ zzOEzs0ItaJIJxXTvhiff/AXkm3xcnJYjICcPz41dcccwh/6/4uahOjrSoKXCzkHGHLB Qp5g== X-Gm-Message-State: AOAM5334aaAjBXiyd4zV4Ar+++PmIhuwyx9LBeLMqgE3hVbFP343HEuG A64Iyh7GydUql+U3fG1oXi63E6f8ncAExg== X-Google-Smtp-Source: ABdhPJwPDo7CvdpylE8ybNS4Kt0JAiTv3doeujX4KDmOG62P6LsKoESPgJTggObtmClN3CiSiU6q9g== X-Received: by 2002:a65:5086:: with SMTP id r6mr8878261pgp.65.1631497300905; Sun, 12 Sep 2021 18:41:40 -0700 (PDT) Received: from localhost.localdomain (36-227-141-62.dynamic-ip.hinet.net. [36.227.141.62]) by smtp.gmail.com with ESMTPSA id i10sm5052173pfk.87.2021.09.12.18.41.39 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Sun, 12 Sep 2021 18:41:40 -0700 (PDT) From: Vincent Chen To: libc-alpha@sourceware.org, palmer@dabbelt.com Subject: [RFC patch 3/5] RISC-V: Save and restore VCSR when doing user context switch Date: Mon, 13 Sep 2021 09:41:16 +0800 Message-Id: <1631497278-29829-4-git-send-email-vincent.chen@sifive.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1631497278-29829-1-git-send-email-vincent.chen@sifive.com> References: <1631497278-29829-1-git-send-email-vincent.chen@sifive.com> X-Spam-Status: No, score=-11.6 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_SHORT, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: andrew@sifive.com, Vincent Chen Errors-To: libc-alpha-bounces+patchwork=sourceware.org@sourceware.org Sender: "Libc-alpha" According to the RISC-V V extension specification, all vector registers except VCSR are caller-saved registers. The VCSR (vxrm + vxsat) has thread storage duration. Therefore, only VCSR needs to be added to the user context operation. --- sysdeps/riscv/Makefile | 5 ++++ sysdeps/riscv/rtld-global-offsets.sym | 7 +++++ sysdeps/unix/sysv/linux/riscv/bits/hwcap.h | 31 +++++++++++++++++++++ sysdeps/unix/sysv/linux/riscv/getcontext.S | 22 ++++++++++++++- sysdeps/unix/sysv/linux/riscv/setcontext.S | 22 +++++++++++++++ sysdeps/unix/sysv/linux/riscv/swapcontext.S | 41 ++++++++++++++++++++++++++++ sysdeps/unix/sysv/linux/riscv/sysdep.h | 1 + sysdeps/unix/sysv/linux/riscv/ucontext_i.sym | 6 ++++ 8 files changed, 134 insertions(+), 1 deletion(-) create mode 100644 sysdeps/riscv/rtld-global-offsets.sym create mode 100644 sysdeps/unix/sysv/linux/riscv/bits/hwcap.h diff --git a/sysdeps/riscv/Makefile b/sysdeps/riscv/Makefile index 20a9968..cda3ded 100644 --- a/sysdeps/riscv/Makefile +++ b/sysdeps/riscv/Makefile @@ -2,6 +2,11 @@ ifeq ($(subdir),misc) sysdep_headers += sys/asm.h endif +ifeq ($(subdir),csu) +# get offset to rtld_global._dl_hwcap and rtld_global._dl_hwcap2. +gen-as-const-headers += rtld-global-offsets.sym +endif + # RISC-V's assembler also needs to know about PIC as it changes the definition # of some assembler macros. ASFLAGS-.os += $(pic-ccflag) diff --git a/sysdeps/riscv/rtld-global-offsets.sym b/sysdeps/riscv/rtld-global-offsets.sym new file mode 100644 index 0000000..ff4e97f --- /dev/null +++ b/sysdeps/riscv/rtld-global-offsets.sym @@ -0,0 +1,7 @@ +#define SHARED 1 + +#include + +#define rtld_global_ro_offsetof(mem) offsetof (struct rtld_global_ro, mem) + +RTLD_GLOBAL_RO_DL_HWCAP_OFFSET rtld_global_ro_offsetof (_dl_hwcap) diff --git a/sysdeps/unix/sysv/linux/riscv/bits/hwcap.h b/sysdeps/unix/sysv/linux/riscv/bits/hwcap.h new file mode 100644 index 0000000..e6c5ef5 --- /dev/null +++ b/sysdeps/unix/sysv/linux/riscv/bits/hwcap.h @@ -0,0 +1,31 @@ +/* Defines for bits in AT_HWCAP. RISC-V Linux version. + Copyright (C) 2021 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 + . */ + +#if !defined (_SYS_AUXV_H) && !defined (_LINUX_RISCV_SYSDEP_H) +# error "Never include directly; use instead." +#endif + +/* The following must match the kernel's . */ +#define HWCAP_ISA_I 0x100 //(1 << ('I' - 'A')) +#define HWCAP_ISA_M 0x1000 //(1 << ('M' - 'A')) +#define HWCAP_ISA_A 0x1 //(1 << ('A' - 'A')) +#define HWCAP_ISA_F 0x20 //(1 << ('F' - 'A')) +#define HWCAP_ISA_D 0x8 //(1 << ('D' - 'A')) +#define HWCAP_ISA_C 0x4 //(1 << ('C' - 'A')) +#define HWCAP_ISA_V 0x200000 //(1 << ('V' - 'A')) + diff --git a/sysdeps/unix/sysv/linux/riscv/getcontext.S b/sysdeps/unix/sysv/linux/riscv/getcontext.S index d6a9bbc..840d8fe 100644 --- a/sysdeps/unix/sysv/linux/riscv/getcontext.S +++ b/sysdeps/unix/sysv/linux/riscv/getcontext.S @@ -16,6 +16,8 @@ License along with the GNU C Library. If not, see . */ +#include +#include #include "ucontext-macros.h" /* int getcontext (ucontext_t *ucp) */ @@ -39,6 +41,25 @@ LEAF (__getcontext) SAVE_INT_REG (s10, 26, a0) SAVE_INT_REG (s11, 27, a0) +#ifdef __riscv_vector +# ifdef SHARED + la t1, _rtld_global_ro + REG_L t1, RTLD_GLOBAL_RO_DL_HWCAP_OFFSET(t1) +# else + la t1, _dl_hwcap + REG_L t1, (t1) +# endif + li t2, HWCAP_ISA_V + and t2, t1, t2 + beqz t2, 1f + addi t2, a0, MCONTEXT_EXTENSION + li t1, RVV_MAGIC + sw t1, (t2) + csrr t1, vcsr + REG_S t1, VCSR_OFFSET(t2) +1: +#endif + #ifndef __riscv_float_abi_soft frsr a1 @@ -73,5 +94,4 @@ LEAF (__getcontext) 99: j __syscall_error PSEUDO_END (__getcontext) - weak_alias (__getcontext, getcontext) diff --git a/sysdeps/unix/sysv/linux/riscv/setcontext.S b/sysdeps/unix/sysv/linux/riscv/setcontext.S index 9510518..d2404fb 100644 --- a/sysdeps/unix/sysv/linux/riscv/setcontext.S +++ b/sysdeps/unix/sysv/linux/riscv/setcontext.S @@ -16,6 +16,8 @@ License along with the GNU C Library. If not, see . */ +#include +#include #include "ucontext-macros.h" /* int __setcontext (const ucontext_t *ucp) @@ -64,6 +66,26 @@ LEAF (__setcontext) fssr t1 #endif /* __riscv_float_abi_soft */ +#ifdef __riscv_vector +#ifdef SHARED + la t1, _rtld_global_ro + REG_L t1, RTLD_GLOBAL_RO_DL_HWCAP_OFFSET(t1) +#else + la t1, _dl_hwcap + REG_L t1, (t1) +#endif + li t2, HWCAP_ISA_V + and t2, t1, t2 + beqz t2, 1f + li t1, RVV_MAGIC + addi t2, t0, MCONTEXT_EXTENSION + lw a1, (t2) + bne a1, t1, 1f + REG_L t1, VCSR_OFFSET(t2) + csrw vcsr, t1 +1: +#endif + /* Note the contents of argument registers will be random unless makecontext() has been called. */ RESTORE_INT_REG (t1, 0, t0) diff --git a/sysdeps/unix/sysv/linux/riscv/swapcontext.S b/sysdeps/unix/sysv/linux/riscv/swapcontext.S index df0f699..94ae8e4 100644 --- a/sysdeps/unix/sysv/linux/riscv/swapcontext.S +++ b/sysdeps/unix/sysv/linux/riscv/swapcontext.S @@ -16,6 +16,8 @@ License along with the GNU C Library. If not, see . */ +#include +#include #include "ucontext-macros.h" /* int swapcontext (ucontext_t *oucp, const ucontext_t *ucp) */ @@ -40,6 +42,25 @@ LEAF (__swapcontext) SAVE_INT_REG (s10, 26, a0) SAVE_INT_REG (s11, 27, a0) +#ifdef __riscv_vector +#ifdef SHARED + la t1, _rtld_global_ro + REG_L t1, RTLD_GLOBAL_RO_DL_HWCAP_OFFSET(t1) +#else + la t1, _dl_hwcap + REG_L t1, (t1) +#endif + li t2, HWCAP_ISA_V + and t2, t1, t2 + beqz t2, 1f + addi t2, a0, MCONTEXT_EXTENSION + li t1, RVV_MAGIC + sw t1, (t2) + csrr t1, vcsr + REG_S t1, VCSR_OFFSET(t2) +1: +#endif + #ifndef __riscv_float_abi_soft frsr a1 @@ -89,6 +110,26 @@ LEAF (__swapcontext) fssr t1 #endif /* __riscv_float_abi_soft */ +#ifdef __riscv_vector +#ifdef SHARED + la t1, _rtld_global_ro + REG_L t1, RTLD_GLOBAL_RO_DL_HWCAP_OFFSET(t1) +#else + la t1, _dl_hwcap + REG_L t1, (t1) +#endif + li t2, HWCAP_ISA_V + and t2, t1, t2 + beqz t2, 1f + li t1, RVV_MAGIC + addi t2, t0, MCONTEXT_EXTENSION + lw a1, (t2) + bne a1, t1, 1f + REG_L t1, VCSR_OFFSET(t2) + csrw vcsr, t1 +1: +#endif + /* Note the contents of argument registers will be random unless makecontext() has been called. */ RESTORE_INT_REG (t1, 0, t0) diff --git a/sysdeps/unix/sysv/linux/riscv/sysdep.h b/sysdeps/unix/sysv/linux/riscv/sysdep.h index 37ff07a..c9f8fd8 100644 --- a/sysdeps/unix/sysv/linux/riscv/sysdep.h +++ b/sysdeps/unix/sysv/linux/riscv/sysdep.h @@ -50,6 +50,7 @@ #ifdef __ASSEMBLER__ +# include # include # define ENTRY(name) LEAF(name) diff --git a/sysdeps/unix/sysv/linux/riscv/ucontext_i.sym b/sysdeps/unix/sysv/linux/riscv/ucontext_i.sym index be55b26..4037473 100644 --- a/sysdeps/unix/sysv/linux/riscv/ucontext_i.sym +++ b/sysdeps/unix/sysv/linux/riscv/ucontext_i.sym @@ -2,6 +2,7 @@ #include #include #include +#include -- Constants used by the rt_sigprocmask call. @@ -27,5 +28,10 @@ STACK_FLAGS stack (ss_flags) MCONTEXT_GREGS mcontext (__gregs) MCONTEXT_FPREGS mcontext (__fpregs) +MCONTEXT_EXTENSION mcontext (__reserved) UCONTEXT_SIZE sizeof (ucontext_t) + +VCSR_OFFSET offsetof (struct __riscv_v_state, vcsr) + +RVV_MAGIC