Tests which currently use the vDSO find it using getauxval(). However, in purecap, the pointer to the vDSO in the auxiliary vector is a capability and therefore cannot be returned as an unsigned long. Replace getauxval() with getauxptr() when building for purecap to solve this issue.
This patch replicates changes made to the Morello kernel vDSO selftests to enable testing in purecap. See Morello/Linux/Kernel: ad001738e9c8 ("Add support for purecap vDSO testing").
Signed-off-by: Aditya Deshpande aditya.deshpande@arm.com --- include/parse_vdso.h | 28 ++++++++++++++++++++++++++++ libs/libltpvdso/vdso_helpers.c | 4 ++-- 2 files changed, 30 insertions(+), 2 deletions(-)
diff --git a/include/parse_vdso.h b/include/parse_vdso.h index 5212fc659..43c865cc1 100644 --- a/include/parse_vdso.h +++ b/include/parse_vdso.h @@ -9,6 +9,10 @@
#include <stdint.h>
+#ifdef HAVE_GETAUXVAL +# include <sys/auxv.h> +#endif /* HAVE_GETAUXVAL */ + /* * To use this vDSO parser, first call one of the vdso_init_* functions. * If you've already parsed auxv, then pass the value of AT_SYSINFO_EHDR @@ -38,4 +42,28 @@ extern void *vdso_sym(const char *version, const char *name); typedef int (*gettime_t)(clockid_t clk_id, void *ts); void find_clock_gettime_vdso(gettime_t *ptr_vdso_gettime, gettime_t *ptr_vdso_gettime64); + +/* + * Define uintptr_t as a capability in purecap. + * When not in purecap, uintptr_t will default to unsigned long. + */ +#ifdef __CHERI_PURE_CAPABILITY__ +typedef __uintcap_t uintptr_t; +#endif + +/* + * Under PCuABI, pointers in the auxiliary vector can no longer be represented + * as unsigned long as they are now capabilities. Get the capability to the + * vDSO using getauxptr() instead, which returns a a capability instead of + * unsigned long. + */ +static inline uintptr_t get_sysinfo_ehdr() +{ +#ifdef __CHERI_PURE_CAPABILITY__ + return getauxptr(AT_SYSINFO_EHDR); +#else + return (uintptr_t)getauxval(AT_SYSINFO_EHDR); +#endif +} + #endif /* PARSE_VDSO_H__ */ diff --git a/libs/libltpvdso/vdso_helpers.c b/libs/libltpvdso/vdso_helpers.c index 208c12f65..cb5e01687 100644 --- a/libs/libltpvdso/vdso_helpers.c +++ b/libs/libltpvdso/vdso_helpers.c @@ -14,7 +14,7 @@ # include <sys/auxv.h> #endif /* HAVE_GETAUXVAL */
-static unsigned long sysinfo_ehdr; +static uintptr_t sysinfo_ehdr;
static void vdso_init(void) { @@ -22,7 +22,7 @@ static void vdso_init(void) if (sysinfo_ehdr) return;
- sysinfo_ehdr = getauxval(AT_SYSINFO_EHDR); + sysinfo_ehdr = get_sysinfo_ehdr(); if (!sysinfo_ehdr) { tst_res(TINFO, "Couldn't find AT_SYSINFO_EHDR"); return;
On 05/12/2023 18:22, Aditya Deshpande wrote:
Tests which currently use the vDSO find it using getauxval(). However, in purecap, the pointer to the vDSO in the auxiliary vector is a capability and therefore cannot be returned as an unsigned long. Replace getauxval() with getauxptr() when building for purecap to solve this issue.
This patch replicates changes made to the Morello kernel vDSO selftests to enable testing in purecap. See Morello/Linux/Kernel: ad001738e9c8
We avoid referring to hashes because they change every time we rebase. Just referring to the commit title is enough.
("Add support for purecap vDSO testing").
Signed-off-by: Aditya Deshpande aditya.deshpande@arm.com
include/parse_vdso.h | 28 ++++++++++++++++++++++++++++ libs/libltpvdso/vdso_helpers.c | 4 ++-- 2 files changed, 30 insertions(+), 2 deletions(-)
diff --git a/include/parse_vdso.h b/include/parse_vdso.h index 5212fc659..43c865cc1 100644 --- a/include/parse_vdso.h +++ b/include/parse_vdso.h @@ -9,6 +9,10 @@ #include <stdint.h> +#ifdef HAVE_GETAUXVAL +# include <sys/auxv.h> +#endif /* HAVE_GETAUXVAL */
/*
- To use this vDSO parser, first call one of the vdso_init_* functions.
- If you've already parsed auxv, then pass the value of AT_SYSINFO_EHDR
@@ -38,4 +42,28 @@ extern void *vdso_sym(const char *version, const char *name); typedef int (*gettime_t)(clockid_t clk_id, void *ts); void find_clock_gettime_vdso(gettime_t *ptr_vdso_gettime, gettime_t *ptr_vdso_gettime64);
+/*
- Define uintptr_t as a capability in purecap.
- When not in purecap, uintptr_t will default to unsigned long.
- */
+#ifdef __CHERI_PURE_CAPABILITY__ +typedef __uintcap_t uintptr_t;
stdint.h should already provide exactly this definition, so this should have no effect. In fact compilation would outside of purecap if stdint.h didn't already provide that type.
+#endif
+/*
- Under PCuABI, pointers in the auxiliary vector can no longer be represented
- as unsigned long as they are now capabilities. Get the capability to the
- vDSO using getauxptr() instead, which returns a a capability instead of
- unsigned long.
- */
+static inline uintptr_t get_sysinfo_ehdr() +{ +#ifdef __CHERI_PURE_CAPABILITY__
- return getauxptr(AT_SYSINFO_EHDR);
This triggers a warning because getauxptr() returns voids *, not uintptr_t. In fact I think the cast is in the wrong #if: there's no need for it with getauxval(), but there is for getauxptr().
I missed this when reviewing the kselftest patch (since I couldn't build the vDSO kselftests), it should be updated accordingly (a new fix patch since it's already merged).
Kevin
+#else
- return (uintptr_t)getauxval(AT_SYSINFO_EHDR);
+#endif +}
#endif /* PARSE_VDSO_H__ */ diff --git a/libs/libltpvdso/vdso_helpers.c b/libs/libltpvdso/vdso_helpers.c index 208c12f65..cb5e01687 100644 --- a/libs/libltpvdso/vdso_helpers.c +++ b/libs/libltpvdso/vdso_helpers.c @@ -14,7 +14,7 @@ # include <sys/auxv.h> #endif /* HAVE_GETAUXVAL */ -static unsigned long sysinfo_ehdr; +static uintptr_t sysinfo_ehdr; static void vdso_init(void) { @@ -22,7 +22,7 @@ static void vdso_init(void) if (sysinfo_ehdr) return;
- sysinfo_ehdr = getauxval(AT_SYSINFO_EHDR);
- sysinfo_ehdr = get_sysinfo_ehdr(); if (!sysinfo_ehdr) { tst_res(TINFO, "Couldn't find AT_SYSINFO_EHDR"); return;
linux-morello-ltp@op-lists.linaro.org