public inbox for libc-alpha@sourceware.org
 help / color / mirror / Atom feed
From: Evan Green <evan@rivosinc.com>
To: libc-alpha@sourceware.org
Cc: vineetg@rivosinc.com, slewis@rivosinc.com, palmer@rivosinc.com,
	Florian Weimer <fweimer@redhat.com>,
	Evan Green <evan@rivosinc.com>
Subject: [PATCH v5 3/4] riscv: Add ifunc-compatible hwprobe function
Date: Wed, 12 Jul 2023 12:36:27 -0700	[thread overview]
Message-ID: <20230712193629.2880253-4-evan@rivosinc.com> (raw)
In-Reply-To: <20230712193629.2880253-1-evan@rivosinc.com>

ifunc selector functions are called very early, and are not able to call
external functions that require relocation. This presents a problem for
applications and libraries outside of glibc that may want to use
__riscv_hwprobe() in their ifunc selectors.

Add a new function, __riscv_hwprobe_early(), that is compiled into
libc_nonshared.a and is safe to use in application and library ifunc
selectors. The _early() variant checks a weak alias of __riscv_hwprobe,
__riscv_hwprobe_weak, to see if the symbol is available, and simply
calls that if so. However if it's called before the symbol is available,
it makes the system call directly. The early call has some caveats,
primarily that it does not take advantage of the cached vDSO data, and
does not set errno (another external symbol) upon failing.

The original dynamic __riscv_hwprobe() function is still available for
users that don't need the overhead of handling early init cases.

Signed-off-by: Evan Green <evan@rivosinc.com>

---

Changes in v5:
 - Introduced __riscv_hwprobe_early()

 sysdeps/unix/sysv/linux/riscv/Makefile        |  3 +-
 sysdeps/unix/sysv/linux/riscv/Versions        |  1 +
 sysdeps/unix/sysv/linux/riscv/hwprobe.c       |  2 ++
 .../unix/sysv/linux/riscv/hwprobe_static.c    | 36 +++++++++++++++++++
 .../unix/sysv/linux/riscv/rv32/libc.abilist   |  1 +
 .../unix/sysv/linux/riscv/rv64/libc.abilist   |  1 +
 sysdeps/unix/sysv/linux/riscv/sys/hwprobe.h   | 21 +++++++++++
 7 files changed, 64 insertions(+), 1 deletion(-)
 create mode 100644 sysdeps/unix/sysv/linux/riscv/hwprobe_static.c

diff --git a/sysdeps/unix/sysv/linux/riscv/Makefile b/sysdeps/unix/sysv/linux/riscv/Makefile
index 45cc29e40d..fd8fd48ade 100644
--- a/sysdeps/unix/sysv/linux/riscv/Makefile
+++ b/sysdeps/unix/sysv/linux/riscv/Makefile
@@ -1,6 +1,7 @@
 ifeq ($(subdir),misc)
 sysdep_headers += sys/cachectl.h sys/hwprobe.h
-sysdep_routines += flush-icache hwprobe
+sysdep_routines += flush-icache hwprobe hwprobe_static
+static-only-routines += hwprobe_static
 endif
 
 ifeq ($(subdir),stdlib)
diff --git a/sysdeps/unix/sysv/linux/riscv/Versions b/sysdeps/unix/sysv/linux/riscv/Versions
index 0c4016382d..571d4c2046 100644
--- a/sysdeps/unix/sysv/linux/riscv/Versions
+++ b/sysdeps/unix/sysv/linux/riscv/Versions
@@ -10,5 +10,6 @@ libc {
   }
   GLIBC_2.38 {
     __riscv_hwprobe;
+    __riscv_hwprobe_weak;
   }
 }
diff --git a/sysdeps/unix/sysv/linux/riscv/hwprobe.c b/sysdeps/unix/sysv/linux/riscv/hwprobe.c
index 14f7136998..a8bd63fca4 100644
--- a/sysdeps/unix/sysv/linux/riscv/hwprobe.c
+++ b/sysdeps/unix/sysv/linux/riscv/hwprobe.c
@@ -29,3 +29,5 @@ int __riscv_hwprobe (struct riscv_hwprobe *pairs, size_t pair_count,
  /* The vDSO may be able to provide the answer without a syscall. */
   return INLINE_VSYSCALL(riscv_hwprobe, 5, pairs, pair_count, cpu_count, cpus, flags);
 }
+
+weak_alias(__riscv_hwprobe, __riscv_hwprobe_weak)
diff --git a/sysdeps/unix/sysv/linux/riscv/hwprobe_static.c b/sysdeps/unix/sysv/linux/riscv/hwprobe_static.c
new file mode 100644
index 0000000000..b1c0f4089f
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/riscv/hwprobe_static.c
@@ -0,0 +1,36 @@
+/* RISC-V hardware feature probing support on Linux, ifunc-compatible
+   Copyright (C) 2023 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
+   <https://www.gnu.org/licenses/>.  */
+
+#include <sys/syscall.h>
+#include <sys/hwprobe.h>
+#include <sysdep.h>
+#include <sysdep-vdso.h>
+
+attribute_hidden
+int __riscv_hwprobe_early (struct riscv_hwprobe *pairs, size_t pair_count,
+			   size_t cpu_count, unsigned long int *cpus,
+			   unsigned int flags)
+{
+  if (!__riscv_hwprobe_weak) {
+    /* Use INTERNAL_SYSCALL since errno is not available. */
+    return INTERNAL_SYSCALL(riscv_hwprobe, 5, pairs, pair_count, cpu_count, cpus, flags);
+  }
+
+  return __riscv_hwprobe_weak(pairs, pair_count, cpu_count, cpus, flags);
+}
diff --git a/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist b/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist
index 8fab4a606f..942e397be0 100644
--- a/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist
+++ b/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist
@@ -2437,3 +2437,4 @@ GLIBC_2.38 strlcpy F
 GLIBC_2.38 wcslcat F
 GLIBC_2.38 wcslcpy F
 GLIBC_2.38 __riscv_hwprobe F
+GLIBC_2.38 __riscv_hwprobe_weak F
diff --git a/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist b/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist
index 1ebb91deed..bc140fa7df 100644
--- a/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist
+++ b/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist
@@ -2637,3 +2637,4 @@ GLIBC_2.38 strlcpy F
 GLIBC_2.38 wcslcat F
 GLIBC_2.38 wcslcpy F
 GLIBC_2.38 __riscv_hwprobe F
+GLIBC_2.38 __riscv_hwprobe_weak F
diff --git a/sysdeps/unix/sysv/linux/riscv/sys/hwprobe.h b/sysdeps/unix/sysv/linux/riscv/sys/hwprobe.h
index b27af5cb07..d739371806 100644
--- a/sysdeps/unix/sysv/linux/riscv/sys/hwprobe.h
+++ b/sysdeps/unix/sysv/linux/riscv/sys/hwprobe.h
@@ -67,6 +67,27 @@ extern int __riscv_hwprobe (struct riscv_hwprobe *pairs, size_t pair_count,
      __fortified_attr_access (__read_write__, 1, 2)
      __fortified_attr_access (__read_only__, 4, 3);
 
+extern int __riscv_hwprobe_weak (struct riscv_hwprobe *pairs, size_t pair_count,
+				 size_t cpu_count, unsigned long int *cpus,
+				 unsigned int flags)
+     __THROW __nonnull ((1)) __wur
+     __fortified_attr_access (__read_write__, 1, 2)
+     __fortified_attr_access (__read_only__, 4, 3);
+
+# ifdef weak_extern
+weak_extern (__riscv_hwprobe_weak)
+# else
+#  pragma weak __riscv_hwprobe_weak
+# endif
+
+extern int __riscv_hwprobe_early (struct riscv_hwprobe *pairs, size_t pair_count,
+				  size_t cpu_count, unsigned long int *cpus,
+				  unsigned int flags)
+     __THROW __nonnull ((1)) __wur
+     __fortified_attr_access (__read_write__, 1, 2)
+     __fortified_attr_access (__read_only__, 4, 3)
+     __attribute__ ((__visibility__ ("hidden")));
+
 __END_DECLS
 
 #endif /* sys/hwprobe.h */
-- 
2.34.1


  parent reply	other threads:[~2023-07-12 19:36 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-07-12 19:36 [PATCH v5 0/4] RISC-V: ifunced memcpy using new kernel hwprobe interface Evan Green
2023-07-12 19:36 ` [PATCH v5 1/4] riscv: Add Linux hwprobe syscall support Evan Green
2023-07-19 22:44   ` Joseph Myers
2023-07-12 19:36 ` [PATCH v5 2/4] riscv: Add hwprobe vdso call support Evan Green
2023-07-12 19:36 ` Evan Green [this message]
2023-07-13  7:07   ` [PATCH v5 3/4] riscv: Add ifunc-compatible hwprobe function Florian Weimer
2023-07-13 16:33     ` Evan Green
2023-07-13 16:47       ` Palmer Dabbelt
2023-07-13 18:21         ` Evan Green
2023-07-14  6:54           ` Florian Weimer
2023-07-12 19:36 ` [PATCH v5 4/4] riscv: Add and use alignment-ignorant memcpy Evan Green
2023-07-12 22:35 ` [PATCH v5 0/4] RISC-V: ifunced memcpy using new kernel hwprobe interface Evan Green

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20230712193629.2880253-4-evan@rivosinc.com \
    --to=evan@rivosinc.com \
    --cc=fweimer@redhat.com \
    --cc=libc-alpha@sourceware.org \
    --cc=palmer@rivosinc.com \
    --cc=slewis@rivosinc.com \
    --cc=vineetg@rivosinc.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).