mailing list of musl libc
 help / color / mirror / code / Atom feed
* [musl] [PATCH] feat(x86_64): use wrfsbase if AT_HWCAP2 allows usage
@ 2022-03-29 11:42 Harald Hoyer
  2022-03-29 11:54 ` [musl] [PATCH V2 0/1] " Harald Hoyer
  0 siblings, 1 reply; 3+ messages in thread
From: Harald Hoyer @ 2022-03-29 11:42 UTC (permalink / raw)
  To: musl; +Cc: Harald Hoyer

If `AT_HWCAP2` has `HWCAP2_FSGSBASE` set, then instead of calling
`arch_prctl()`, the `wrfsbase` instruction will be used.

This is helpful in SGX contexts, where inside the enclave no other
mechanism is possible.

Tested against `libc-test`.

Signed-off-by: Harald Hoyer <harald@profian.com>
---
 ldso/dynlink.c                        |  1 +
 src/env/__libc_start_main.c           |  1 +
 src/internal/libc.c                   |  1 +
 src/internal/libc.h                   |  1 +
 src/thread/x86_64/__set_thread_area.c | 14 ++++++++++++++
 src/thread/x86_64/__set_thread_area.s | 11 -----------
 6 files changed, 18 insertions(+), 11 deletions(-)
 create mode 100644 src/thread/x86_64/__set_thread_area.c
 delete mode 100644 src/thread/x86_64/__set_thread_area.s

diff --git a/ldso/dynlink.c b/ldso/dynlink.c
index 5b9c8be4..2d38ec63 100644
--- a/ldso/dynlink.c
+++ b/ldso/dynlink.c
@@ -1710,6 +1710,7 @@ void __dls2b(size_t *sp, size_t *auxv)
 	 * use during dynamic linking. If possible it will also serve as the
 	 * thread pointer at runtime. */
 	search_vec(auxv, &__hwcap, AT_HWCAP);
+	search_vec(auxv, &__hwcap2, AT_HWCAP2);
 	libc.auxv = auxv;
 	libc.tls_size = sizeof builtin_tls;
 	libc.tls_align = tls_align;
diff --git a/src/env/__libc_start_main.c b/src/env/__libc_start_main.c
index c5b277bd..38772bdb 100644
--- a/src/env/__libc_start_main.c
+++ b/src/env/__libc_start_main.c
@@ -28,6 +28,7 @@ void __init_libc(char **envp, char *pn)
 	libc.auxv = auxv = (void *)(envp+i+1);
 	for (i=0; auxv[i]; i+=2) if (auxv[i]<AUX_CNT) aux[auxv[i]] = auxv[i+1];
 	__hwcap = aux[AT_HWCAP];
+	__hwcap2 = aux[AT_HWCAP2];
 	if (aux[AT_SYSINFO]) __sysinfo = aux[AT_SYSINFO];
 	libc.page_size = aux[AT_PAGESZ];
 
diff --git a/src/internal/libc.c b/src/internal/libc.c
index cb051810..16e47633 100644
--- a/src/internal/libc.c
+++ b/src/internal/libc.c
@@ -3,6 +3,7 @@
 struct __libc __libc;
 
 size_t __hwcap;
+size_t __hwcap2;
 char *__progname=0, *__progname_full=0;
 
 weak_alias(__progname, program_invocation_short_name);
diff --git a/src/internal/libc.h b/src/internal/libc.h
index 619bba86..7d239626 100644
--- a/src/internal/libc.h
+++ b/src/internal/libc.h
@@ -47,6 +47,7 @@ hidden void __libc_exit_fini(void);
 hidden void __fork_handler(int);
 
 extern hidden size_t __hwcap;
+extern hidden size_t __hwcap2;
 extern hidden size_t __sysinfo;
 extern char *__progname, *__progname_full;
 
diff --git a/src/thread/x86_64/__set_thread_area.c b/src/thread/x86_64/__set_thread_area.c
new file mode 100644
index 00000000..cd3a2519
--- /dev/null
+++ b/src/thread/x86_64/__set_thread_area.c
@@ -0,0 +1,14 @@
+#include <libc.h>
+#include <syscall.h>
+#include <bits/hwcap.h>
+
+hidden int __set_thread_area(void *p)
+{
+    if (__hwcap2 & HWCAP2_FSGSBASE) {
+        __asm__ ("wrfsbase %0" :: "r" (p) : "memory");
+        return 0;
+    }
+
+    // arch_prctl(SET_FS, arg)
+    return syscall(__NR_arch_prctl, 0x1002, p);
+}
diff --git a/src/thread/x86_64/__set_thread_area.s b/src/thread/x86_64/__set_thread_area.s
deleted file mode 100644
index 7347ff4d..00000000
--- a/src/thread/x86_64/__set_thread_area.s
+++ /dev/null
@@ -1,11 +0,0 @@
-/* Copyright 2011-2012 Nicholas J. Kain, licensed under standard MIT license */
-.text
-.global __set_thread_area
-.hidden __set_thread_area
-.type __set_thread_area,@function
-__set_thread_area:
-	mov %rdi,%rsi           /* shift for syscall */
-	movl $0x1002,%edi       /* SET_FS register */
-	movl $158,%eax          /* set fs segment to */
-	syscall                 /* arch_prctl(SET_FS, arg)*/
-	ret
-- 
2.35.1


^ permalink raw reply	[flat|nested] 3+ messages in thread

* [musl] [PATCH V2 0/1] feat(x86_64): use wrfsbase if AT_HWCAP2 allows usage
  2022-03-29 11:42 [musl] [PATCH] feat(x86_64): use wrfsbase if AT_HWCAP2 allows usage Harald Hoyer
@ 2022-03-29 11:54 ` Harald Hoyer
  2022-03-29 11:54   ` [musl] [PATCH 1/1] " Harald Hoyer
  0 siblings, 1 reply; 3+ messages in thread
From: Harald Hoyer @ 2022-03-29 11:54 UTC (permalink / raw)
  To: musl; +Cc: Harald Hoyer

Forgot to add `arch/x86_64/bits/hwcap.h`

Harald Hoyer (1):
  feat(x86_64): use wrfsbase if AT_HWCAP2 allows usage

 arch/x86_64/bits/hwcap.h              |  2 ++
 ldso/dynlink.c                        |  1 +
 src/env/__libc_start_main.c           |  1 +
 src/internal/libc.c                   |  1 +
 src/internal/libc.h                   |  1 +
 src/thread/x86_64/__set_thread_area.c | 14 ++++++++++++++
 src/thread/x86_64/__set_thread_area.s | 11 -----------
 7 files changed, 20 insertions(+), 11 deletions(-)
 create mode 100644 arch/x86_64/bits/hwcap.h
 create mode 100644 src/thread/x86_64/__set_thread_area.c
 delete mode 100644 src/thread/x86_64/__set_thread_area.s

-- 
2.35.1


^ permalink raw reply	[flat|nested] 3+ messages in thread

* [musl] [PATCH 1/1] feat(x86_64): use wrfsbase if AT_HWCAP2 allows usage
  2022-03-29 11:54 ` [musl] [PATCH V2 0/1] " Harald Hoyer
@ 2022-03-29 11:54   ` Harald Hoyer
  0 siblings, 0 replies; 3+ messages in thread
From: Harald Hoyer @ 2022-03-29 11:54 UTC (permalink / raw)
  To: musl; +Cc: Harald Hoyer

If `AT_HWCAP2` has `HWCAP2_FSGSBASE` set, then instead of calling
`arch_prctl()`, the `wrfsbase` instruction will be used.

This is helpful in SGX contexts, where inside the enclave no other
mechanism is possible.

Tested against `libc-test`.

Signed-off-by: Harald Hoyer <harald@profian.com>
---
 arch/x86_64/bits/hwcap.h              |  2 ++
 ldso/dynlink.c                        |  1 +
 src/env/__libc_start_main.c           |  1 +
 src/internal/libc.c                   |  1 +
 src/internal/libc.h                   |  1 +
 src/thread/x86_64/__set_thread_area.c | 14 ++++++++++++++
 src/thread/x86_64/__set_thread_area.s | 11 -----------
 7 files changed, 20 insertions(+), 11 deletions(-)
 create mode 100644 arch/x86_64/bits/hwcap.h
 create mode 100644 src/thread/x86_64/__set_thread_area.c
 delete mode 100644 src/thread/x86_64/__set_thread_area.s

diff --git a/arch/x86_64/bits/hwcap.h b/arch/x86_64/bits/hwcap.h
new file mode 100644
index 00000000..804d41fa
--- /dev/null
+++ b/arch/x86_64/bits/hwcap.h
@@ -0,0 +1,2 @@
+#define HWCAP2_RING3MWAIT	(1 << 0)
+#define HWCAP2_FSGSBASE	    (1 << 1)
diff --git a/ldso/dynlink.c b/ldso/dynlink.c
index 5b9c8be4..2d38ec63 100644
--- a/ldso/dynlink.c
+++ b/ldso/dynlink.c
@@ -1710,6 +1710,7 @@ void __dls2b(size_t *sp, size_t *auxv)
 	 * use during dynamic linking. If possible it will also serve as the
 	 * thread pointer at runtime. */
 	search_vec(auxv, &__hwcap, AT_HWCAP);
+	search_vec(auxv, &__hwcap2, AT_HWCAP2);
 	libc.auxv = auxv;
 	libc.tls_size = sizeof builtin_tls;
 	libc.tls_align = tls_align;
diff --git a/src/env/__libc_start_main.c b/src/env/__libc_start_main.c
index c5b277bd..38772bdb 100644
--- a/src/env/__libc_start_main.c
+++ b/src/env/__libc_start_main.c
@@ -28,6 +28,7 @@ void __init_libc(char **envp, char *pn)
 	libc.auxv = auxv = (void *)(envp+i+1);
 	for (i=0; auxv[i]; i+=2) if (auxv[i]<AUX_CNT) aux[auxv[i]] = auxv[i+1];
 	__hwcap = aux[AT_HWCAP];
+	__hwcap2 = aux[AT_HWCAP2];
 	if (aux[AT_SYSINFO]) __sysinfo = aux[AT_SYSINFO];
 	libc.page_size = aux[AT_PAGESZ];
 
diff --git a/src/internal/libc.c b/src/internal/libc.c
index cb051810..16e47633 100644
--- a/src/internal/libc.c
+++ b/src/internal/libc.c
@@ -3,6 +3,7 @@
 struct __libc __libc;
 
 size_t __hwcap;
+size_t __hwcap2;
 char *__progname=0, *__progname_full=0;
 
 weak_alias(__progname, program_invocation_short_name);
diff --git a/src/internal/libc.h b/src/internal/libc.h
index 619bba86..7d239626 100644
--- a/src/internal/libc.h
+++ b/src/internal/libc.h
@@ -47,6 +47,7 @@ hidden void __libc_exit_fini(void);
 hidden void __fork_handler(int);
 
 extern hidden size_t __hwcap;
+extern hidden size_t __hwcap2;
 extern hidden size_t __sysinfo;
 extern char *__progname, *__progname_full;
 
diff --git a/src/thread/x86_64/__set_thread_area.c b/src/thread/x86_64/__set_thread_area.c
new file mode 100644
index 00000000..cd3a2519
--- /dev/null
+++ b/src/thread/x86_64/__set_thread_area.c
@@ -0,0 +1,14 @@
+#include <libc.h>
+#include <syscall.h>
+#include <bits/hwcap.h>
+
+hidden int __set_thread_area(void *p)
+{
+    if (__hwcap2 & HWCAP2_FSGSBASE) {
+        __asm__ ("wrfsbase %0" :: "r" (p) : "memory");
+        return 0;
+    }
+
+    // arch_prctl(SET_FS, arg)
+    return syscall(__NR_arch_prctl, 0x1002, p);
+}
diff --git a/src/thread/x86_64/__set_thread_area.s b/src/thread/x86_64/__set_thread_area.s
deleted file mode 100644
index 7347ff4d..00000000
--- a/src/thread/x86_64/__set_thread_area.s
+++ /dev/null
@@ -1,11 +0,0 @@
-/* Copyright 2011-2012 Nicholas J. Kain, licensed under standard MIT license */
-.text
-.global __set_thread_area
-.hidden __set_thread_area
-.type __set_thread_area,@function
-__set_thread_area:
-	mov %rdi,%rsi           /* shift for syscall */
-	movl $0x1002,%edi       /* SET_FS register */
-	movl $158,%eax          /* set fs segment to */
-	syscall                 /* arch_prctl(SET_FS, arg)*/
-	ret
-- 
2.35.1


^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2022-03-29 11:55 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-03-29 11:42 [musl] [PATCH] feat(x86_64): use wrfsbase if AT_HWCAP2 allows usage Harald Hoyer
2022-03-29 11:54 ` [musl] [PATCH V2 0/1] " Harald Hoyer
2022-03-29 11:54   ` [musl] [PATCH 1/1] " Harald Hoyer

Code repositories for project(s) associated with this inbox:

	https://git.vuxu.org/mirror/musl/

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 NNTP newsgroup(s).