* [LTP] [PATCH] arch_prctl: add ARCH_GET_FS, ARCH_GET_GS tests
@ 2026-10-08 19:47 dm.chestnykh
2026-10-09 10:12 ` [LTP] " linuxtestproject.agent
2026-10-09 15:52 ` [LTP] [PATCH v2] " dm.chestnykh
0 siblings, 2 replies; 14+ messages in thread
From: dm.chestnykh @ 2026-10-08 19:47 UTC (permalink / raw)
To: ltp; +Cc: Dmitry Chestnykh
From: Dmitry Chestnykh <dm.chestnykh@gmail.com>
Signed-off-by: Dmitry Chestnykh <dm.chestnykh@gmail.com>
---
.../kernel/syscalls/arch_prctl/.gitignore | 1 +
testcases/kernel/syscalls/arch_prctl/Makefile | 2 +
.../kernel/syscalls/arch_prctl/arch_prctl02.c | 81 +++++++++++++++++++
3 files changed, 84 insertions(+)
create mode 100644 testcases/kernel/syscalls/arch_prctl/arch_prctl02.c
diff --git a/testcases/kernel/syscalls/arch_prctl/.gitignore b/testcases/kernel/syscalls/arch_prctl/.gitignore
index 24871e249..72187b8b4 100644
--- a/testcases/kernel/syscalls/arch_prctl/.gitignore
+++ b/testcases/kernel/syscalls/arch_prctl/.gitignore
@@ -1 +1,2 @@
/arch_prctl01
+/arch_prctl02
diff --git a/testcases/kernel/syscalls/arch_prctl/Makefile b/testcases/kernel/syscalls/arch_prctl/Makefile
index 272949d57..c4413a81f 100644
--- a/testcases/kernel/syscalls/arch_prctl/Makefile
+++ b/testcases/kernel/syscalls/arch_prctl/Makefile
@@ -6,3 +6,5 @@ top_srcdir ?= ../../../..
include $(top_srcdir)/include/mk/testcases.mk
include $(top_srcdir)/include/mk/generic_leaf_target.mk
+
+CFLAGS += -mfsgsbase
diff --git a/testcases/kernel/syscalls/arch_prctl/arch_prctl02.c b/testcases/kernel/syscalls/arch_prctl/arch_prctl02.c
new file mode 100644
index 000000000..124dd13b9
--- /dev/null
+++ b/testcases/kernel/syscalls/arch_prctl/arch_prctl02.c
@@ -0,0 +1,81 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Author: Dmitry Chestnykh <dm.chestnykh@gmail.com>
+ */
+
+/*\
+ * Simple test on arch_prctl to get FS_BASE and GS_BASE
+ */
+
+#include "tst_test.h"
+#include "lapi/syscalls.h"
+#include "lapi/arch_prctl.h"
+#include <stdlib.h>
+#include <string.h>
+
+#include <sys/auxv.h>
+#ifndef HWCAP2_FSGSBASE
+#if defined(__has_include) && __has_include(<asm/hwcap2.h>)
+#include <asm/hwcap2.h>
+#else
+#warning "Cannot obtain HWCAP2_FSGSBASE from system headers"
+#define HWCAP2_FSGSBASE (1UL << 1)
+#endif /* defined(__has_include) && __has_include(<asm/hwcap2.h>) */
+#endif /* HWCAP2_FSGSBASE */
+
+static int arch_prctl_get(int code, unsigned long *out)
+{
+ return tst_syscall(__NR_arch_prctl, code, out);
+}
+
+static bool tag;
+
+static void setup(void)
+{
+ unsigned long v = getauxval(AT_HWCAP2);
+
+ tag = v & HWCAP2_FSGSBASE ? true : false;
+}
+
+#define READ_FS_BASE() ({ \
+ unsigned long long __res; \
+ asm volatile("rdfsbase %0" : "=r"(__res)); \
+ __res; \
+})
+
+#define READ_GS_BASE() ({ \
+ unsigned long long __res; \
+ asm volatile("rdgsbase %0" : "=r"(__res)); \
+ __res; \
+})
+
+static void run(unsigned int index)
+{
+ (void)index;
+ if (!tag)
+ tst_brk(TCONF, "rdfsbase/rdgsbase are not supported/enabled");
+
+ unsigned long fs = READ_FS_BASE();
+ unsigned long gs = READ_GS_BASE();
+ unsigned long fs_prctl, gs_prctl;
+
+ TEST(arch_prctl_get(ARCH_GET_FS, &fs_prctl));
+ if (TST_RET == 0 && fs_prctl == fs)
+ tst_res(TPASS, "get fs succeed");
+ else
+ tst_res(TFAIL, "got wrong fs register value");
+
+ TEST(arch_prctl_get(ARCH_GET_GS, &gs_prctl));
+ if (TST_RET == 0 && gs_prctl == gs)
+ tst_res(TPASS, "get gs succeed");
+ else
+ tst_res(TFAIL, "got wrong gs register value");
+}
+
+static struct tst_test test = {
+ .test = run,
+ .setup = setup,
+ .tcnt = 1,
+ .min_kver = "5.9",
+ .supported_archs = (const char *const []){"x86_64", NULL}
+};
--
2.56.0
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply related [flat|nested] 14+ messages in thread
* Re: [LTP] arch_prctl: add ARCH_GET_FS, ARCH_GET_GS tests
2026-10-08 19:47 [LTP] [PATCH] arch_prctl: add ARCH_GET_FS, ARCH_GET_GS tests dm.chestnykh
@ 2026-10-09 10:12 ` linuxtestproject.agent
2026-10-09 15:52 ` [LTP] [PATCH v2] " dm.chestnykh
1 sibling, 0 replies; 14+ messages in thread
From: linuxtestproject.agent @ 2026-10-09 10:12 UTC (permalink / raw)
To: dm.chestnykh; +Cc: ltp
Hi Dmitry,
On Thu, 8 Oct 2026, Dmitry Chestnykh wrote:
> arch_prctl: add ARCH_GET_FS, ARCH_GET_GS tests
> +CFLAGS += -mfsgsbase
This directory-wide x86 option breaks supported non-x86 builds, including
the existing arch_prctl01 target; AArch64 clang rejects it. Remove the
option: the new test's inline assembly compiles without it on x86_64.
> + asm volatile("rdfsbase %0" : "=r"(__res)); \
> + asm volatile("rdgsbase %0" : "=r"(__res)); \
> + .supported_archs = (const char *const []){"x86_64", NULL}
Removing the compiler option alone is insufficient: the unconditional
assembly still fails on AArch64, and lapi/arch_prctl.h supplies no
ARCH_GET_FS/ARCH_GET_GS definitions on non-x86 targets. The supported_archs
check runs only after compilation; provide a buildable unsupported-feature
path or filter the target appropriately in the Makefile.
> +#if defined(__has_include) && __has_include(<asm/hwcap2.h>)
GCC 4.8.5, a supported compiler, cannot parse this expression: the left
operand does not protect an undefined function-like preprocessing operator.
The repository's sparse check also rejects this line. Use separately nested
checks or configured optional-header inclusion.
> +#include <asm/hwcap2.h>
> +#else
> +#warning "Cannot obtain HWCAP2_FSGSBASE from system headers"
> +#define HWCAP2_FSGSBASE (1UL << 1)
An existing older header bypasses the fallback even when it lacks this bit:
compilation against Linux 5.4's hwcap2.h fails with HWCAP2_FSGSBASE
undeclared.
Apply the fallback after optional header inclusion, independently of header
availability, and put the compatibility definition in include/lapi.
> +/arch_prctl02
The new binary has no entry in any runtest file, so normal syscall-suite
runs never execute it. Add "arch_prctl02 arch_prctl02" to runtest/syscalls.
> + TEST(arch_prctl_get(ARCH_GET_FS, &fs_prctl));
> + if (TST_RET == 0 && fs_prctl == fs)
> + tst_res(TPASS, "get fs succeed");
> + else
> + tst_res(TFAIL, "got wrong fs register value");
These messages discard errno and the expected/actual bases, and report a
syscall failure as a register mismatch. Use TST_EXP_PASS_SILENT(), then
TST_EXP_EQ_LU() only when TST_PASS is true; apply the same change to GS.
> + * Author: Dmitry Chestnykh <dm.chestnykh@gmail.com>
Add the required copyright line with year and author, for example
"Copyright (c) 2026 Dmitry Chestnykh <dm.chestnykh@gmail.com>".
> + * Simple test on arch_prctl to get FS_BASE and GS_BASE
Use the required manpage role and describe the comparison, for example:
"Check that :manpage:`arch_prctl(2)` with ``ARCH_GET_FS`` and ``ARCH_GET_GS``
returns bases matching ``rdfsbase`` and ``rdgsbase``."
Verdict - Needs revision
---
Note:
The agent can sometimes produce false positives although often its
findings are genuine. If you find issues with the review, please
comment this email or ignore the suggestions.
Regards,
LTP AI Reviewer
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply [flat|nested] 14+ messages in thread
* [LTP] [PATCH v2] arch_prctl: add ARCH_GET_FS, ARCH_GET_GS tests
2026-10-08 19:47 [LTP] [PATCH] arch_prctl: add ARCH_GET_FS, ARCH_GET_GS tests dm.chestnykh
2026-10-09 10:12 ` [LTP] " linuxtestproject.agent
@ 2026-10-09 15:52 ` dm.chestnykh
2026-10-09 17:27 ` [LTP] " linuxtestproject.agent
2026-10-09 18:35 ` [LTP] [PATCH v3] " dm.chestnykh
1 sibling, 2 replies; 14+ messages in thread
From: dm.chestnykh @ 2026-10-09 15:52 UTC (permalink / raw)
To: ltp; +Cc: Dmitry Chestnykh
From: Dmitry Chestnykh <dm.chestnykh@gmail.com>
Signed-off-by: Dmitry Chestnykh <dm.chestnykh@gmail.com>
---
configure.ac | 1 +
include/lapi/arch_prctl.h | 9 ++
runtest/syscalls | 1 +
.../kernel/syscalls/arch_prctl/.gitignore | 1 +
.../kernel/syscalls/arch_prctl/arch_prctl02.c | 87 +++++++++++++++++++
5 files changed, 99 insertions(+)
create mode 100644 testcases/kernel/syscalls/arch_prctl/arch_prctl02.c
diff --git a/configure.ac b/configure.ac
index e979de0e7..9db3e06ad 100644
--- a/configure.ac
+++ b/configure.ac
@@ -53,6 +53,7 @@ AC_CHECK_HEADERS_ONCE([ \
aio.h \
asm/ldt.h \
asm/prctl.h \
+ asm/hwcap2.h \
cpuid.h \
emmintrin.h \
ifaddrs.h \
diff --git a/include/lapi/arch_prctl.h b/include/lapi/arch_prctl.h
index a4e7f8458..6d8376e58 100644
--- a/include/lapi/arch_prctl.h
+++ b/include/lapi/arch_prctl.h
@@ -19,4 +19,13 @@
# define ARCH_SET_CPUID 0x1012
#endif
+#ifdef __x86_64__
+# ifdef HAVE_ASM_HWCAP2_H
+# include <asm/hwcap2.h>
+# endif /* HAVE_ASM_HWCAP2_H */
+# ifndef HWCAP2_FSGSBASE
+# define HWCAP2_FSGSBASE (1UL << 1)
+# endif /* HWCAP2_FSGSBASE */
+#endif /* __x86_64__ */
+
#endif /* LAPI_ARCH_PRCTL_H__ */
diff --git a/runtest/syscalls b/runtest/syscalls
index accdf2df9..f2f2a0602 100644
--- a/runtest/syscalls
+++ b/runtest/syscalls
@@ -32,6 +32,7 @@ alarm06 alarm06
alarm07 alarm07
arch_prctl01 arch_prctl01
+arch_prctl02 arch_prctl02
bind01 bind01
bind02 bind02
diff --git a/testcases/kernel/syscalls/arch_prctl/.gitignore b/testcases/kernel/syscalls/arch_prctl/.gitignore
index 24871e249..72187b8b4 100644
--- a/testcases/kernel/syscalls/arch_prctl/.gitignore
+++ b/testcases/kernel/syscalls/arch_prctl/.gitignore
@@ -1 +1,2 @@
/arch_prctl01
+/arch_prctl02
diff --git a/testcases/kernel/syscalls/arch_prctl/arch_prctl02.c b/testcases/kernel/syscalls/arch_prctl/arch_prctl02.c
new file mode 100644
index 000000000..180c64b27
--- /dev/null
+++ b/testcases/kernel/syscalls/arch_prctl/arch_prctl02.c
@@ -0,0 +1,87 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2026 Dmitry Chestnykh <dm.chestnykh@gmail.com>
+ * Author: Dmitry Chestnykh <dm.chestnykh@gmail.com>
+ */
+
+/*\
+ * Simple test on arch_prctl to get FS_BASE and GS_BASE
+ */
+
+#include "tst_test.h"
+#include "lapi/syscalls.h"
+#include "lapi/arch_prctl.h"
+#include <stdlib.h>
+#include <string.h>
+
+#ifdef __x86_64__
+
+#ifdef HAVE_GETAUXVAL
+# include <sys/auxv.h>
+#endif
+
+static int arch_prctl_get(int code, unsigned long *out)
+{
+ return tst_syscall(__NR_arch_prctl, code, out);
+}
+
+static bool tag;
+
+static void setup(void)
+{
+ unsigned long v = 0;
+
+#ifdef AT_HWCAP2
+ v = getauxval(AT_HWCAP2);
+#endif
+ tag = v & HWCAP2_FSGSBASE ? true : false;
+}
+
+#define READ_FS_BASE() ({ \
+ unsigned long long __res; \
+ asm volatile("rdfsbase %0" : "=r"(__res)); \
+ __res; \
+})
+
+#define READ_GS_BASE() ({ \
+ unsigned long long __res; \
+ asm volatile("rdgsbase %0" : "=r"(__res)); \
+ __res; \
+})
+
+static void run(unsigned int index)
+{
+ (void)index;
+ if (!tag)
+ tst_brk(TCONF, "rdfsbase/rdgsbase are not supported/enabled");
+
+ unsigned long fs = READ_FS_BASE();
+ unsigned long gs = READ_GS_BASE();
+ unsigned long fs_prctl, gs_prctl;
+
+ TST_EXP_PASS_SILENT(arch_prctl_get(ARCH_GET_FS, &fs_prctl));
+ if (TST_PASS)
+ TST_EXP_EQ_LU(fs_prctl, fs);
+ else
+ tst_res(TFAIL, "got wrong fs register value");
+
+ TST_EXP_PASS_SILENT(arch_prctl_get(ARCH_GET_GS, &gs_prctl));
+ if (TST_PASS)
+ TST_EXP_EQ_LU(gs_prctl, gs);
+ else
+ tst_res(TFAIL, "got wrong gs register value");
+}
+
+static struct tst_test test = {
+ .test = run,
+ .setup = setup,
+ .tcnt = 1,
+ .min_kver = "5.9",
+ .supported_archs = (const char *const []){"x86_64", NULL}
+};
+
+#else
+
+TST_TEST_TCONF("Tests needs x86_64 CPU");
+
+#endif /* __x86_64__ */
--
2.56.0
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply related [flat|nested] 14+ messages in thread
* Re: [LTP] arch_prctl: add ARCH_GET_FS, ARCH_GET_GS tests
2026-10-09 15:52 ` [LTP] [PATCH v2] " dm.chestnykh
@ 2026-10-09 17:27 ` linuxtestproject.agent
2026-10-09 18:35 ` [LTP] [PATCH v3] " dm.chestnykh
1 sibling, 0 replies; 14+ messages in thread
From: linuxtestproject.agent @ 2026-10-09 17:27 UTC (permalink / raw)
To: dm.chestnykh; +Cc: ltp
Hi Dmitry,
On Fri Oct 9 18:52:24 2026 +0300, Dmitry Chestnykh wrote:
> arch_prctl: add ARCH_GET_FS, ARCH_GET_GS tests
> +++ b/testcases/kernel/syscalls/arch_prctl/arch_prctl02.c
> + unsigned long gs = READ_GS_BASE();
> + TST_EXP_EQ_LU(gs_prctl, gs);
The default GS base is zero in ordinary runs, so an always-zero getter
passes; replacing ARCH_GET_GS with a successful zero write reproduced this.
Also exercise a known nonzero 64-bit GS base and restore the original
afterward, without changing the libc-owned FS base.
> + TST_EXP_PASS_SILENT(arch_prctl_get(ARCH_GET_FS, &fs_prctl));
> + if (TST_PASS)
> + TST_EXP_EQ_LU(fs_prctl, fs);
> + else
> + tst_res(TFAIL, "got wrong fs register value");
TST_EXP_PASS_SILENT() already reports syscall failures; injecting EINVAL
for both getters produces four failures for two calls. Remove both else
branches: they duplicate the failures and claim value mismatches without
comparing either value.
> +static void run(unsigned int index)
> +{
> + (void)index;
> + .test = run,
> + .tcnt = 1,
Represent FS and GS as two tcases entries and use
.tcnt = ARRAY_SIZE(tcases), with the index selecting the opcode and
corresponding register read instead of duplicating both cases in run(0).
> + unsigned long v = 0;
> + unsigned long long __res; \
Use a tab for v's indentation; checkpatch reports a warning here.
Rename __res to a non-reserved identifier in both register-reading macros.
> +/*\
> + * Simple test on arch_prctl to get FS_BASE and GS_BASE
> + */
Use the :manpage:`arch_prctl(2)` role and describe the actual assertion:
``ARCH_GET_FS`` and ``ARCH_GET_GS`` return the bases read independently
by RDFSBASE and RDGSBASE.
Verdict - Needs revision
---
Note:
The agent can sometimes produce false positives although often its
findings are genuine. If you find issues with the review, please
comment this email or ignore the suggestions.
Regards,
LTP AI Reviewer
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply [flat|nested] 14+ messages in thread
* [LTP] [PATCH v3] arch_prctl: add ARCH_GET_FS, ARCH_GET_GS tests
2026-10-09 15:52 ` [LTP] [PATCH v2] " dm.chestnykh
2026-10-09 17:27 ` [LTP] " linuxtestproject.agent
@ 2026-10-09 18:35 ` dm.chestnykh
2026-10-09 18:39 ` [LTP] [PATCH v4] " dm.chestnykh
2026-10-09 22:23 ` linuxtestproject.agent
1 sibling, 2 replies; 14+ messages in thread
From: dm.chestnykh @ 2026-10-09 18:35 UTC (permalink / raw)
To: ltp; +Cc: Dmitry Chestnykh
From: Dmitry Chestnykh <dm.chestnykh@gmail.com>
Signed-off-by: Dmitry Chestnykh <dm.chestnykh@gmail.com>
---
configure.ac | 1 +
include/lapi/arch_prctl.h | 9 ++
runtest/syscalls | 1 +
.../kernel/syscalls/arch_prctl/.gitignore | 1 +
.../kernel/syscalls/arch_prctl/arch_prctl02.c | 122 ++++++++++++++++++
5 files changed, 134 insertions(+)
create mode 100644 testcases/kernel/syscalls/arch_prctl/arch_prctl02.c
diff --git a/configure.ac b/configure.ac
index e979de0e7..9db3e06ad 100644
--- a/configure.ac
+++ b/configure.ac
@@ -53,6 +53,7 @@ AC_CHECK_HEADERS_ONCE([ \
aio.h \
asm/ldt.h \
asm/prctl.h \
+ asm/hwcap2.h \
cpuid.h \
emmintrin.h \
ifaddrs.h \
diff --git a/include/lapi/arch_prctl.h b/include/lapi/arch_prctl.h
index a4e7f8458..6d8376e58 100644
--- a/include/lapi/arch_prctl.h
+++ b/include/lapi/arch_prctl.h
@@ -19,4 +19,13 @@
# define ARCH_SET_CPUID 0x1012
#endif
+#ifdef __x86_64__
+# ifdef HAVE_ASM_HWCAP2_H
+# include <asm/hwcap2.h>
+# endif /* HAVE_ASM_HWCAP2_H */
+# ifndef HWCAP2_FSGSBASE
+# define HWCAP2_FSGSBASE (1UL << 1)
+# endif /* HWCAP2_FSGSBASE */
+#endif /* __x86_64__ */
+
#endif /* LAPI_ARCH_PRCTL_H__ */
diff --git a/runtest/syscalls b/runtest/syscalls
index accdf2df9..f2f2a0602 100644
--- a/runtest/syscalls
+++ b/runtest/syscalls
@@ -32,6 +32,7 @@ alarm06 alarm06
alarm07 alarm07
arch_prctl01 arch_prctl01
+arch_prctl02 arch_prctl02
bind01 bind01
bind02 bind02
diff --git a/testcases/kernel/syscalls/arch_prctl/.gitignore b/testcases/kernel/syscalls/arch_prctl/.gitignore
index 24871e249..72187b8b4 100644
--- a/testcases/kernel/syscalls/arch_prctl/.gitignore
+++ b/testcases/kernel/syscalls/arch_prctl/.gitignore
@@ -1 +1,2 @@
/arch_prctl01
+/arch_prctl02
diff --git a/testcases/kernel/syscalls/arch_prctl/arch_prctl02.c b/testcases/kernel/syscalls/arch_prctl/arch_prctl02.c
new file mode 100644
index 000000000..6992e93a3
--- /dev/null
+++ b/testcases/kernel/syscalls/arch_prctl/arch_prctl02.c
@@ -0,0 +1,122 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2026 Dmitry Chestnykh <dm.chestnykh@gmail.com>
+ * Author: Dmitry Chestnykh <dm.chestnykh@gmail.com>
+ */
+
+/*\
+ * Test that ``ARCH_GET_FS`` and ``ARCH_GET_GS`` return the same bases read independently
+ * by RDFSBASE and RDGSBASE.
+ */
+
+#include "tst_test.h"
+#include "lapi/syscalls.h"
+#include "lapi/arch_prctl.h"
+#include <stdlib.h>
+#include <string.h>
+
+#ifdef __x86_64__
+
+#ifdef HAVE_GETAUXVAL
+# include <sys/auxv.h>
+#endif
+
+static int arch_prctl_get(int code, unsigned long *out)
+{
+ return tst_syscall(__NR_arch_prctl, code, out);
+}
+
+static int set_gs(unsigned long val)
+{
+ return tst_syscall(__NR_arch_prctl, ARCH_SET_GS, val);
+}
+
+static bool tag;
+
+static void setup(void)
+{
+ unsigned long v = 0;
+
+#ifdef AT_HWCAP2
+ v = getauxval(AT_HWCAP2);
+#endif
+ tag = v & HWCAP2_FSGSBASE ? true : false;
+}
+
+#define READ_FS_BASE() ({ \
+ unsigned long long __res_fs; \
+ asm volatile("rdfsbase %0" : "=r"(__res_fs)); \
+ __res_fs; \
+})
+
+#define READ_GS_BASE() ({ \
+ unsigned long long __res_gs; \
+ asm volatile("rdgsbase %0" : "=r"(__res_gs)); \
+ __res_gs; \
+})
+
+static void test_fs(void)
+{
+ unsigned long fs = READ_FS_BASE();
+ unsigned long fs_prctl;
+ TST_EXP_PASS_SILENT(arch_prctl_get(ARCH_GET_FS, &fs_prctl));
+ if (TST_PASS)
+ TST_EXP_EQ_LU(fs_prctl, fs);
+}
+
+static void test_gs(void)
+{
+ unsigned long gs_prctl;
+ unsigned long gs, orig_gs;
+#define TEST_GS_BASE() do { \
+ gs = READ_GS_BASE(); \
+ TST_EXP_PASS_SILENT(arch_prctl_get(ARCH_GET_GS, &gs_prctl)); \
+ if (TST_PASS) { \
+ TST_EXP_EQ_LU(gs_prctl, gs); \
+ } \
+} while (0)
+
+ TEST_GS_BASE();
+ orig_gs = gs;
+
+ if (gs == 0) {
+ unsigned long test_gs = 0xabababab;
+ TST_EXP_PASS_SILENT(set_gs(test_gs));
+ if (TST_PASS) {
+ TEST_GS_BASE();
+ }
+ }
+
+ set_gs(orig_gs);
+}
+
+static struct tcase {
+ unsigned idx;
+ void (*test_fn)(void);
+} tcases[] = {
+ {0, test_fs},
+ {1, test_gs}
+};
+
+static void run(unsigned index)
+{
+ if (!tag)
+ tst_brk(TCONF, "rdfsbase/rdgsbase are not supported/enabled");
+
+ struct tcase *tc = &tcases[index];
+ (*tc->test_fn)();
+}
+
+static struct tst_test test = {
+ .test = run,
+ .setup = setup,
+ .tcnt = ARRAY_SIZE(tcases),
+ .min_kver = "5.9",
+ .supported_archs = (const char *const []){"x86_64", NULL}
+};
+
+#else
+
+TST_TEST_TCONF("Tests needs x86_64 CPU");
+
+#endif /* __x86_64__ */
--
2.56.0
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [LTP] [PATCH v4] arch_prctl: add ARCH_GET_FS, ARCH_GET_GS tests
2026-10-09 18:35 ` [LTP] [PATCH v3] " dm.chestnykh
@ 2026-10-09 18:39 ` dm.chestnykh
2026-10-09 22:23 ` [LTP] " linuxtestproject.agent
2026-10-10 6:38 ` [LTP] [PATCH v5] " dm.chestnykh
2026-10-09 22:23 ` linuxtestproject.agent
1 sibling, 2 replies; 14+ messages in thread
From: dm.chestnykh @ 2026-10-09 18:39 UTC (permalink / raw)
To: ltp; +Cc: Dmitry Chestnykh
From: Dmitry Chestnykh <dm.chestnykh@gmail.com>
Signed-off-by: Dmitry Chestnykh <dm.chestnykh@gmail.com>
---
configure.ac | 1 +
include/lapi/arch_prctl.h | 9 ++
runtest/syscalls | 1 +
.../kernel/syscalls/arch_prctl/.gitignore | 1 +
.../kernel/syscalls/arch_prctl/arch_prctl02.c | 119 ++++++++++++++++++
5 files changed, 131 insertions(+)
create mode 100644 testcases/kernel/syscalls/arch_prctl/arch_prctl02.c
diff --git a/configure.ac b/configure.ac
index e979de0e7..9db3e06ad 100644
--- a/configure.ac
+++ b/configure.ac
@@ -53,6 +53,7 @@ AC_CHECK_HEADERS_ONCE([ \
aio.h \
asm/ldt.h \
asm/prctl.h \
+ asm/hwcap2.h \
cpuid.h \
emmintrin.h \
ifaddrs.h \
diff --git a/include/lapi/arch_prctl.h b/include/lapi/arch_prctl.h
index a4e7f8458..6d8376e58 100644
--- a/include/lapi/arch_prctl.h
+++ b/include/lapi/arch_prctl.h
@@ -19,4 +19,13 @@
# define ARCH_SET_CPUID 0x1012
#endif
+#ifdef __x86_64__
+# ifdef HAVE_ASM_HWCAP2_H
+# include <asm/hwcap2.h>
+# endif /* HAVE_ASM_HWCAP2_H */
+# ifndef HWCAP2_FSGSBASE
+# define HWCAP2_FSGSBASE (1UL << 1)
+# endif /* HWCAP2_FSGSBASE */
+#endif /* __x86_64__ */
+
#endif /* LAPI_ARCH_PRCTL_H__ */
diff --git a/runtest/syscalls b/runtest/syscalls
index accdf2df9..f2f2a0602 100644
--- a/runtest/syscalls
+++ b/runtest/syscalls
@@ -32,6 +32,7 @@ alarm06 alarm06
alarm07 alarm07
arch_prctl01 arch_prctl01
+arch_prctl02 arch_prctl02
bind01 bind01
bind02 bind02
diff --git a/testcases/kernel/syscalls/arch_prctl/.gitignore b/testcases/kernel/syscalls/arch_prctl/.gitignore
index 24871e249..72187b8b4 100644
--- a/testcases/kernel/syscalls/arch_prctl/.gitignore
+++ b/testcases/kernel/syscalls/arch_prctl/.gitignore
@@ -1 +1,2 @@
/arch_prctl01
+/arch_prctl02
diff --git a/testcases/kernel/syscalls/arch_prctl/arch_prctl02.c b/testcases/kernel/syscalls/arch_prctl/arch_prctl02.c
new file mode 100644
index 000000000..a69ee00ad
--- /dev/null
+++ b/testcases/kernel/syscalls/arch_prctl/arch_prctl02.c
@@ -0,0 +1,119 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2026 Dmitry Chestnykh <dm.chestnykh@gmail.com>
+ * Author: Dmitry Chestnykh <dm.chestnykh@gmail.com>
+ */
+
+/*\
+ * Test that ``ARCH_GET_FS`` and ``ARCH_GET_GS`` return the same bases read independently
+ * by RDFSBASE and RDGSBASE.
+ */
+
+#include "tst_test.h"
+#include "lapi/syscalls.h"
+#include "lapi/arch_prctl.h"
+#include <stdlib.h>
+#include <string.h>
+
+#ifdef __x86_64__
+
+#ifdef HAVE_GETAUXVAL
+# include <sys/auxv.h>
+#endif
+
+static int arch_prctl_get(int code, unsigned long *out)
+{
+ return tst_syscall(__NR_arch_prctl, code, out);
+}
+
+static int set_gs(unsigned long val)
+{
+ return tst_syscall(__NR_arch_prctl, ARCH_SET_GS, val);
+}
+
+static bool tag;
+
+static void setup(void)
+{
+ unsigned long v = 0;
+
+#ifdef AT_HWCAP2
+ v = getauxval(AT_HWCAP2);
+#endif
+ tag = v & HWCAP2_FSGSBASE ? true : false;
+}
+
+#define READ_FS_BASE() ({ \
+ unsigned long long __res_fs; \
+ asm volatile("rdfsbase %0" : "=r"(__res_fs)); \
+ __res_fs; \
+})
+
+#define READ_GS_BASE() ({ \
+ unsigned long long __res_gs; \
+ asm volatile("rdgsbase %0" : "=r"(__res_gs)); \
+ __res_gs; \
+})
+
+static void test_fs(void)
+{
+ unsigned long fs = READ_FS_BASE();
+ unsigned long fs_prctl;
+ TST_EXP_PASS_SILENT(arch_prctl_get(ARCH_GET_FS, &fs_prctl));
+ if (TST_PASS)
+ TST_EXP_EQ_LU(fs_prctl, fs);
+}
+
+static void test_gs(void)
+{
+ unsigned long gs, gs_prctl;
+#define TEST_GS_BASE() do { \
+ gs = READ_GS_BASE(); \
+ TST_EXP_PASS_SILENT(arch_prctl_get(ARCH_GET_GS, &gs_prctl)); \
+ if (TST_PASS) { \
+ TST_EXP_EQ_LU(gs_prctl, gs); \
+ } \
+} while (0)
+
+ TEST_GS_BASE();
+
+ if (gs == 0) {
+ unsigned long test_gs = 0xabababab;
+ TST_EXP_PASS_SILENT(set_gs(test_gs));
+ if (TST_PASS) {
+ TEST_GS_BASE();
+ }
+ }
+
+}
+
+static struct tcase {
+ unsigned idx;
+ void (*test_fn)(void);
+} tcases[] = {
+ {0, test_fs},
+ {1, test_gs}
+};
+
+static void run(unsigned index)
+{
+ if (!tag)
+ tst_brk(TCONF, "rdfsbase/rdgsbase are not supported/enabled");
+
+ struct tcase *tc = &tcases[index];
+ (*tc->test_fn)();
+}
+
+static struct tst_test test = {
+ .test = run,
+ .setup = setup,
+ .tcnt = ARRAY_SIZE(tcases),
+ .min_kver = "5.9",
+ .supported_archs = (const char *const []){"x86_64", NULL}
+};
+
+#else
+
+TST_TEST_TCONF("Tests needs x86_64 CPU");
+
+#endif /* __x86_64__ */
--
2.56.0
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply related [flat|nested] 14+ messages in thread
* Re: [LTP] arch_prctl: add ARCH_GET_FS, ARCH_GET_GS tests
2026-10-09 18:35 ` [LTP] [PATCH v3] " dm.chestnykh
2026-10-09 18:39 ` [LTP] [PATCH v4] " dm.chestnykh
@ 2026-10-09 22:23 ` linuxtestproject.agent
1 sibling, 0 replies; 14+ messages in thread
From: linuxtestproject.agent @ 2026-10-09 22:23 UTC (permalink / raw)
To: dm.chestnykh; +Cc: ltp
Hi Dmitry,
On 2026-10-09, Dmitry Chestnykh wrote:
> arch_prctl: add ARCH_GET_FS, ARCH_GET_GS tests
> diff --git a/testcases/kernel/syscalls/arch_prctl/arch_prctl02.c b/testcases/kernel/syscalls/arch_prctl/arch_prctl02.c
> +static int arch_prctl_get(int code, unsigned long *out)
> +{
> + return tst_syscall(__NR_arch_prctl, code, out);
> +}
High: On x32, unsigned long is four bytes, but these raw GET operations
write eight bytes, overflowing fs_prctl and gs_prctl. Both __x86_64__ and
the framework's x86_64 architecture check admit x32; glibc's x32
arch_prctl wrapper uses a uint64_t temporary, but tst_syscall bypasses it.
Use uint64_t for the output pointer, both output objects, and comparison
values.
> + if (gs == 0) {
> + unsigned long test_gs = 0xabababab;
> + TST_EXP_PASS_SILENT(set_gs(test_gs));
> + if (TST_PASS) {
> + TEST_GS_BASE();
> + }
> + }
Low: GS remains nonzero after the first iteration, so subsequent -i
iterations skip the zero-base comparison and ARCH_SET_GS branch; -i 3
produces seven comparisons rather than repeating all three each time.
Restore the original GS base after the changed-base comparison.
> + unsigned long long __res_fs; \
> + unsigned long long __res_gs; \
> + if (TST_PASS) {
> + TEST_GS_BASE();
> + }
> + unsigned idx;
> +static void run(unsigned index)
Low: check-arch_prctl02 reports missing blank lines after declarations,
unnecessary single-statement braces, an unnecessary blank line before a
closing brace, and bare unsigned declarations; fix these and use unsigned
int. Rename __res_fs and __res_gs to avoid reserved identifiers.
Verdict - Needs revision
---
Note:
The agent can sometimes produce false positives although often its
findings are genuine. If you find issues with the review, please
comment this email or ignore the suggestions.
Regards,
LTP AI Reviewer
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [LTP] arch_prctl: add ARCH_GET_FS, ARCH_GET_GS tests
2026-10-09 18:39 ` [LTP] [PATCH v4] " dm.chestnykh
@ 2026-10-09 22:23 ` linuxtestproject.agent
2026-10-10 6:38 ` [LTP] [PATCH v5] " dm.chestnykh
1 sibling, 0 replies; 14+ messages in thread
From: linuxtestproject.agent @ 2026-10-09 22:23 UTC (permalink / raw)
To: dm.chestnykh; +Cc: ltp
Hi Dmitry,
On Fri Oct 9 2026, Dmitry Chestnykh wrote:
> arch_prctl: add ARCH_GET_FS, ARCH_GET_GS tests
> diff --git a/testcases/kernel/syscalls/arch_prctl/arch_prctl02.c b/testcases/kernel/syscalls/arch_prctl/arch_prctl02.c
> +static int arch_prctl_get(int code, unsigned long *out)
> +{
> + return tst_syscall(__NR_arch_prctl, code, out);
> +}
High severity: x32 also defines __x86_64__ and passes .supported_archs,
but its unsigned long is four bytes. The raw getters still write eight
bytes, overrunning fs_prctl and gs_prctl; glibc's x32 arch_prctl wrapper
uses a uint64_t temporary for this reason. Use uint64_t or unsigned long
long consistently for the output pointer, result buffers and bases read
by the instructions.
> + if (gs == 0) {
> + unsigned long test_gs = 0xabababab;
> + TST_EXP_PASS_SILENT(set_gs(test_gs));
> + if (TST_PASS) {
> + TEST_GS_BASE();
> + }
> + }
Low severity: the checkpatch stage of make check-arch_prctl02 fails on
declaration spacing, single-statement braces, a trailing blank line and
bare unsigned declarations. Add blank lines after declarations, remove
the unnecessary braces/blank line, and spell the types unsigned int;
make ignores checker errors, so its zero exit status does not mean this
check passed.
Verdict - Needs revision
---
Note:
The agent can sometimes produce false positives although often its
findings are genuine. If you find issues with the review, please
comment this email or ignore the suggestions.
Regards,
LTP AI Reviewer
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply [flat|nested] 14+ messages in thread
* [LTP] [PATCH v5] arch_prctl: add ARCH_GET_FS, ARCH_GET_GS tests
2026-10-09 18:39 ` [LTP] [PATCH v4] " dm.chestnykh
2026-10-09 22:23 ` [LTP] " linuxtestproject.agent
@ 2026-10-10 6:38 ` dm.chestnykh
2026-10-10 6:42 ` [LTP] [PATCH v6] " dm.chestnykh
2026-10-10 9:35 ` linuxtestproject.agent
1 sibling, 2 replies; 14+ messages in thread
From: dm.chestnykh @ 2026-10-10 6:38 UTC (permalink / raw)
To: ltp; +Cc: Dmitry Chestnykh
From: Dmitry Chestnykh <dm.chestnykh@gmail.com>
Signed-off-by: Dmitry Chestnykh <dm.chestnykh@gmail.com>
---
configure.ac | 1 +
include/lapi/arch_prctl.h | 9 ++
runtest/syscalls | 1 +
.../kernel/syscalls/arch_prctl/.gitignore | 1 +
.../kernel/syscalls/arch_prctl/arch_prctl02.c | 119 ++++++++++++++++++
5 files changed, 131 insertions(+)
create mode 100644 testcases/kernel/syscalls/arch_prctl/arch_prctl02.c
diff --git a/configure.ac b/configure.ac
index e979de0e7..9db3e06ad 100644
--- a/configure.ac
+++ b/configure.ac
@@ -53,6 +53,7 @@ AC_CHECK_HEADERS_ONCE([ \
aio.h \
asm/ldt.h \
asm/prctl.h \
+ asm/hwcap2.h \
cpuid.h \
emmintrin.h \
ifaddrs.h \
diff --git a/include/lapi/arch_prctl.h b/include/lapi/arch_prctl.h
index a4e7f8458..6d8376e58 100644
--- a/include/lapi/arch_prctl.h
+++ b/include/lapi/arch_prctl.h
@@ -19,4 +19,13 @@
# define ARCH_SET_CPUID 0x1012
#endif
+#ifdef __x86_64__
+# ifdef HAVE_ASM_HWCAP2_H
+# include <asm/hwcap2.h>
+# endif /* HAVE_ASM_HWCAP2_H */
+# ifndef HWCAP2_FSGSBASE
+# define HWCAP2_FSGSBASE (1UL << 1)
+# endif /* HWCAP2_FSGSBASE */
+#endif /* __x86_64__ */
+
#endif /* LAPI_ARCH_PRCTL_H__ */
diff --git a/runtest/syscalls b/runtest/syscalls
index accdf2df9..f2f2a0602 100644
--- a/runtest/syscalls
+++ b/runtest/syscalls
@@ -32,6 +32,7 @@ alarm06 alarm06
alarm07 alarm07
arch_prctl01 arch_prctl01
+arch_prctl02 arch_prctl02
bind01 bind01
bind02 bind02
diff --git a/testcases/kernel/syscalls/arch_prctl/.gitignore b/testcases/kernel/syscalls/arch_prctl/.gitignore
index 24871e249..72187b8b4 100644
--- a/testcases/kernel/syscalls/arch_prctl/.gitignore
+++ b/testcases/kernel/syscalls/arch_prctl/.gitignore
@@ -1 +1,2 @@
/arch_prctl01
+/arch_prctl02
diff --git a/testcases/kernel/syscalls/arch_prctl/arch_prctl02.c b/testcases/kernel/syscalls/arch_prctl/arch_prctl02.c
new file mode 100644
index 000000000..15a1be2bc
--- /dev/null
+++ b/testcases/kernel/syscalls/arch_prctl/arch_prctl02.c
@@ -0,0 +1,119 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2026 Dmitry Chestnykh <dm.chestnykh@gmail.com>
+ * Author: Dmitry Chestnykh <dm.chestnykh@gmail.com>
+ */
+
+/*\
+ * Test that ``ARCH_GET_FS`` and ``ARCH_GET_GS`` return the same bases read independently
+ * by RDFSBASE and RDGSBASE.
+ */
+
+#include "tst_test.h"
+#include "lapi/syscalls.h"
+#include "lapi/arch_prctl.h"
+#include <stdlib.h>
+#include <string.h>
+
+#ifdef __x86_64__
+
+#ifdef HAVE_GETAUXVAL
+# include <sys/auxv.h>
+#endif
+
+static int arch_prctl_get(int code, unsigned long long *out)
+{
+ return tst_syscall(__NR_arch_prctl, code, out);
+}
+
+static int set_gs(unsigned long long val)
+{
+ return tst_syscall(__NR_arch_prctl, ARCH_SET_GS, val);
+}
+
+static bool tag;
+
+static void setup(void)
+{
+ unsigned long long v = 0;
+
+#ifdef AT_HWCAP2
+ v = getauxval(AT_HWCAP2);
+#endif
+ tag = v & HWCAP2_FSGSBASE ? true : false;
+}
+
+#define READ_FS_BASE() ({ \
+ unsigned long long __res_fs; \
+ asm volatile("rdfsbase %0" : "=r"(__res_fs)); \
+ __res_fs; \
+})
+
+#define READ_GS_BASE() ({ \
+ unsigned long long __res_gs; \
+ asm volatile("rdgsbase %0" : "=r"(__res_gs)); \
+ __res_gs; \
+})
+
+static void test_fs(void)
+{
+ unsigned long long fs = READ_FS_BASE();
+ unsigned long long fs_prctl;
+
+ TST_EXP_PASS_SILENT(arch_prctl_get(ARCH_GET_FS, &fs_prctl));
+ if (TST_PASS)
+ TST_EXP_EQ_LU(fs_prctl, fs);
+}
+
+static void test_gs(void)
+{
+ unsigned long long gs, gs_prctl;
+#define TEST_GS_BASE() do { \
+ gs = READ_GS_BASE(); \
+ TST_EXP_PASS_SILENT(arch_prctl_get(ARCH_GET_GS, &gs_prctl)); \
+ if (TST_PASS) { \
+ TST_EXP_EQ_LU(gs_prctl, gs); \
+ } \
+} while (0)
+
+ TEST_GS_BASE();
+
+ if (gs == 0) {
+ unsigned long long test_gs = 0xabababab;
+
+ TST_EXP_PASS_SILENT(set_gs(test_gs));
+ if (TST_PASS)
+ TEST_GS_BASE();
+ }
+}
+
+static struct tcase {
+ unsigned int idx;
+ void (*test_fn)(void);
+} tcases[] = {
+ {0, test_fs},
+ {1, test_gs}
+};
+
+static void run(unsigned int index)
+{
+ if (!tag)
+ tst_brk(TCONF, "rdfsbase/rdgsbase are not supported/enabled");
+
+ struct tcase *tc = &tcases[index];
+ (*tc->test_fn)();
+}
+
+static struct tst_test test = {
+ .test = run,
+ .setup = setup,
+ .tcnt = ARRAY_SIZE(tcases),
+ .min_kver = "5.9",
+ .supported_archs = (const char *const []){"x86_64", NULL}
+};
+
+#else
+
+TST_TEST_TCONF("Tests needs x86_64 CPU");
+
+#endif /* __x86_64__ */
--
2.56.0
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [LTP] [PATCH v6] arch_prctl: add ARCH_GET_FS, ARCH_GET_GS tests
2026-10-10 6:38 ` [LTP] [PATCH v5] " dm.chestnykh
@ 2026-10-10 6:42 ` dm.chestnykh
2026-10-10 9:35 ` [LTP] " linuxtestproject.agent
2026-10-10 9:44 ` [LTP] [PATCH v7] " dm.chestnykh
2026-10-10 9:35 ` linuxtestproject.agent
1 sibling, 2 replies; 14+ messages in thread
From: dm.chestnykh @ 2026-10-10 6:42 UTC (permalink / raw)
To: ltp; +Cc: Dmitry Chestnykh
From: Dmitry Chestnykh <dm.chestnykh@gmail.com>
Signed-off-by: Dmitry Chestnykh <dm.chestnykh@gmail.com>
---
configure.ac | 1 +
include/lapi/arch_prctl.h | 9 ++
runtest/syscalls | 1 +
.../kernel/syscalls/arch_prctl/.gitignore | 1 +
.../kernel/syscalls/arch_prctl/arch_prctl02.c | 122 ++++++++++++++++++
5 files changed, 134 insertions(+)
create mode 100644 testcases/kernel/syscalls/arch_prctl/arch_prctl02.c
diff --git a/configure.ac b/configure.ac
index e979de0e7..9db3e06ad 100644
--- a/configure.ac
+++ b/configure.ac
@@ -53,6 +53,7 @@ AC_CHECK_HEADERS_ONCE([ \
aio.h \
asm/ldt.h \
asm/prctl.h \
+ asm/hwcap2.h \
cpuid.h \
emmintrin.h \
ifaddrs.h \
diff --git a/include/lapi/arch_prctl.h b/include/lapi/arch_prctl.h
index a4e7f8458..6d8376e58 100644
--- a/include/lapi/arch_prctl.h
+++ b/include/lapi/arch_prctl.h
@@ -19,4 +19,13 @@
# define ARCH_SET_CPUID 0x1012
#endif
+#ifdef __x86_64__
+# ifdef HAVE_ASM_HWCAP2_H
+# include <asm/hwcap2.h>
+# endif /* HAVE_ASM_HWCAP2_H */
+# ifndef HWCAP2_FSGSBASE
+# define HWCAP2_FSGSBASE (1UL << 1)
+# endif /* HWCAP2_FSGSBASE */
+#endif /* __x86_64__ */
+
#endif /* LAPI_ARCH_PRCTL_H__ */
diff --git a/runtest/syscalls b/runtest/syscalls
index accdf2df9..f2f2a0602 100644
--- a/runtest/syscalls
+++ b/runtest/syscalls
@@ -32,6 +32,7 @@ alarm06 alarm06
alarm07 alarm07
arch_prctl01 arch_prctl01
+arch_prctl02 arch_prctl02
bind01 bind01
bind02 bind02
diff --git a/testcases/kernel/syscalls/arch_prctl/.gitignore b/testcases/kernel/syscalls/arch_prctl/.gitignore
index 24871e249..72187b8b4 100644
--- a/testcases/kernel/syscalls/arch_prctl/.gitignore
+++ b/testcases/kernel/syscalls/arch_prctl/.gitignore
@@ -1 +1,2 @@
/arch_prctl01
+/arch_prctl02
diff --git a/testcases/kernel/syscalls/arch_prctl/arch_prctl02.c b/testcases/kernel/syscalls/arch_prctl/arch_prctl02.c
new file mode 100644
index 000000000..81295234d
--- /dev/null
+++ b/testcases/kernel/syscalls/arch_prctl/arch_prctl02.c
@@ -0,0 +1,122 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2026 Dmitry Chestnykh <dm.chestnykh@gmail.com>
+ * Author: Dmitry Chestnykh <dm.chestnykh@gmail.com>
+ */
+
+/*\
+ * Test that ``ARCH_GET_FS`` and ``ARCH_GET_GS`` return the same bases read independently
+ * by RDFSBASE and RDGSBASE.
+ */
+
+#include "tst_test.h"
+#include "lapi/syscalls.h"
+#include "lapi/arch_prctl.h"
+#include <stdlib.h>
+#include <string.h>
+
+#ifdef __x86_64__
+
+#ifdef HAVE_GETAUXVAL
+# include <sys/auxv.h>
+#endif
+
+static int arch_prctl_get(int code, unsigned long long *out)
+{
+ return tst_syscall(__NR_arch_prctl, code, out);
+}
+
+static int set_gs(unsigned long long val)
+{
+ return tst_syscall(__NR_arch_prctl, ARCH_SET_GS, val);
+}
+
+static bool tag;
+
+static void setup(void)
+{
+ unsigned long long v = 0;
+
+#ifdef AT_HWCAP2
+ v = getauxval(AT_HWCAP2);
+#endif
+ tag = v & HWCAP2_FSGSBASE ? true : false;
+}
+
+#define READ_FS_BASE() ({ \
+ unsigned long long __res_fs; \
+ asm volatile("rdfsbase %0" : "=r"(__res_fs)); \
+ __res_fs; \
+})
+
+#define READ_GS_BASE() ({ \
+ unsigned long long __res_gs; \
+ asm volatile("rdgsbase %0" : "=r"(__res_gs)); \
+ __res_gs; \
+})
+
+static void test_fs(void)
+{
+ unsigned long long fs = READ_FS_BASE();
+ unsigned long long fs_prctl;
+
+ TST_EXP_PASS_SILENT(arch_prctl_get(ARCH_GET_FS, &fs_prctl));
+ if (TST_PASS)
+ TST_EXP_EQ_LU(fs_prctl, fs);
+}
+
+static void test_gs(void)
+{
+ unsigned long long gs, gs_prctl, orig_gs;
+#define TEST_GS_BASE() do { \
+ gs = READ_GS_BASE(); \
+ TST_EXP_PASS_SILENT(arch_prctl_get(ARCH_GET_GS, &gs_prctl)); \
+ if (TST_PASS) { \
+ TST_EXP_EQ_LU(gs_prctl, gs); \
+ } \
+} while (0)
+
+ TEST_GS_BASE();
+ orig_gs = gs;
+
+ if (gs == 0) {
+ unsigned long long test_gs = 0xabababab;
+
+ TST_EXP_PASS_SILENT(set_gs(test_gs));
+ if (TST_PASS)
+ TEST_GS_BASE();
+
+ set_gs(orig_gs);
+ }
+}
+
+static struct tcase {
+ unsigned int idx;
+ void (*test_fn)(void);
+} tcases[] = {
+ {0, test_fs},
+ {1, test_gs}
+};
+
+static void run(unsigned int index)
+{
+ if (!tag)
+ tst_brk(TCONF, "rdfsbase/rdgsbase are not supported/enabled");
+
+ struct tcase *tc = &tcases[index];
+ (*tc->test_fn)();
+}
+
+static struct tst_test test = {
+ .test = run,
+ .setup = setup,
+ .tcnt = ARRAY_SIZE(tcases),
+ .min_kver = "5.9",
+ .supported_archs = (const char *const []){"x86_64", NULL}
+};
+
+#else
+
+TST_TEST_TCONF("Tests needs x86_64 CPU");
+
+#endif /* __x86_64__ */
--
2.56.0
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply related [flat|nested] 14+ messages in thread
* Re: [LTP] arch_prctl: add ARCH_GET_FS, ARCH_GET_GS tests
2026-10-10 6:42 ` [LTP] [PATCH v6] " dm.chestnykh
@ 2026-10-10 9:35 ` linuxtestproject.agent
2026-10-10 9:44 ` [LTP] [PATCH v7] " dm.chestnykh
1 sibling, 0 replies; 14+ messages in thread
From: linuxtestproject.agent @ 2026-10-10 9:35 UTC (permalink / raw)
To: dm.chestnykh; +Cc: ltp
Hi Dmitry,
On Sat, 10 Oct 2026, Dmitry Chestnykh wrote:
> arch_prctl: add ARCH_GET_FS, ARCH_GET_GS tests
> diff --git a/testcases/kernel/syscalls/arch_prctl/arch_prctl02.c b/testcases/kernel/syscalls/arch_prctl/arch_prctl02.c
> + if (gs == 0) {
> + unsigned long long test_gs = 0xabababab;
Medium: Both exercised GS bases fit in 32 bits when the initial base is
zero, so an ARCH_GET_GS implementation that drops the upper 32 bits still
passes. Include a valid base above UINT32_MAX, such as 0x1ababababULL, to
exercise the documented 64-bit result.
> + set_gs(orig_gs);
Medium: The restoration syscall's return value is discarded. Injecting
EPERM here leaves GS nonzero, but -i 3 exits successfully with seven
passes and silently skips the set/read case in subsequent iterations.
Use TST_EXP_PASS_SILENT(set_gs(orig_gs)) and abort with TBROK on failure.
Verdict - Needs revision
---
Note:
The agent can sometimes produce false positives although often its
findings are genuine. If you find issues with the review, please
comment this email or ignore the suggestions.
Regards,
LTP AI Reviewer
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [LTP] arch_prctl: add ARCH_GET_FS, ARCH_GET_GS tests
2026-10-10 6:38 ` [LTP] [PATCH v5] " dm.chestnykh
2026-10-10 6:42 ` [LTP] [PATCH v6] " dm.chestnykh
@ 2026-10-10 9:35 ` linuxtestproject.agent
1 sibling, 0 replies; 14+ messages in thread
From: linuxtestproject.agent @ 2026-10-10 9:35 UTC (permalink / raw)
To: dm.chestnykh; +Cc: ltp
Hi Dmitry,
On Sat, 10 Oct 2026, Dmitry Chestnykh wrote:
> arch_prctl: add ARCH_GET_FS, ARCH_GET_GS tests
> +++ b/testcases/kernel/syscalls/arch_prctl/arch_prctl02.c
> + if (gs == 0) {
> + unsigned long long test_gs = 0xabababab;
Medium: When the original GS base is zero, both samples fit in 32 bits,
so the test misses truncation in ARCH_GET_GS. A probe masking its result
to 32 bits still reported all tests passed. Use a canonical user-space
base with nonzero upper 32 bits, such as 0x1234ababababULL.
Verdict - Needs revision
---
Note:
The agent can sometimes produce false positives although often its
findings are genuine. If you find issues with the review, please
comment this email or ignore the suggestions.
Regards,
LTP AI Reviewer
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply [flat|nested] 14+ messages in thread
* [LTP] [PATCH v7] arch_prctl: add ARCH_GET_FS, ARCH_GET_GS tests
2026-10-10 6:42 ` [LTP] [PATCH v6] " dm.chestnykh
2026-10-10 9:35 ` [LTP] " linuxtestproject.agent
@ 2026-10-10 9:44 ` dm.chestnykh
2026-10-10 15:49 ` [LTP] " linuxtestproject.agent
1 sibling, 1 reply; 14+ messages in thread
From: dm.chestnykh @ 2026-10-10 9:44 UTC (permalink / raw)
To: ltp; +Cc: Dmitry Chestnykh
From: Dmitry Chestnykh <dm.chestnykh@gmail.com>
Signed-off-by: Dmitry Chestnykh <dm.chestnykh@gmail.com>
---
configure.ac | 1 +
include/lapi/arch_prctl.h | 9 ++
runtest/syscalls | 1 +
.../kernel/syscalls/arch_prctl/.gitignore | 1 +
.../kernel/syscalls/arch_prctl/arch_prctl02.c | 124 ++++++++++++++++++
5 files changed, 136 insertions(+)
create mode 100644 testcases/kernel/syscalls/arch_prctl/arch_prctl02.c
diff --git a/configure.ac b/configure.ac
index e979de0e7..9db3e06ad 100644
--- a/configure.ac
+++ b/configure.ac
@@ -53,6 +53,7 @@ AC_CHECK_HEADERS_ONCE([ \
aio.h \
asm/ldt.h \
asm/prctl.h \
+ asm/hwcap2.h \
cpuid.h \
emmintrin.h \
ifaddrs.h \
diff --git a/include/lapi/arch_prctl.h b/include/lapi/arch_prctl.h
index a4e7f8458..6d8376e58 100644
--- a/include/lapi/arch_prctl.h
+++ b/include/lapi/arch_prctl.h
@@ -19,4 +19,13 @@
# define ARCH_SET_CPUID 0x1012
#endif
+#ifdef __x86_64__
+# ifdef HAVE_ASM_HWCAP2_H
+# include <asm/hwcap2.h>
+# endif /* HAVE_ASM_HWCAP2_H */
+# ifndef HWCAP2_FSGSBASE
+# define HWCAP2_FSGSBASE (1UL << 1)
+# endif /* HWCAP2_FSGSBASE */
+#endif /* __x86_64__ */
+
#endif /* LAPI_ARCH_PRCTL_H__ */
diff --git a/runtest/syscalls b/runtest/syscalls
index accdf2df9..f2f2a0602 100644
--- a/runtest/syscalls
+++ b/runtest/syscalls
@@ -32,6 +32,7 @@ alarm06 alarm06
alarm07 alarm07
arch_prctl01 arch_prctl01
+arch_prctl02 arch_prctl02
bind01 bind01
bind02 bind02
diff --git a/testcases/kernel/syscalls/arch_prctl/.gitignore b/testcases/kernel/syscalls/arch_prctl/.gitignore
index 24871e249..72187b8b4 100644
--- a/testcases/kernel/syscalls/arch_prctl/.gitignore
+++ b/testcases/kernel/syscalls/arch_prctl/.gitignore
@@ -1 +1,2 @@
/arch_prctl01
+/arch_prctl02
diff --git a/testcases/kernel/syscalls/arch_prctl/arch_prctl02.c b/testcases/kernel/syscalls/arch_prctl/arch_prctl02.c
new file mode 100644
index 000000000..67bd27639
--- /dev/null
+++ b/testcases/kernel/syscalls/arch_prctl/arch_prctl02.c
@@ -0,0 +1,124 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2026 Dmitry Chestnykh <dm.chestnykh@gmail.com>
+ * Author: Dmitry Chestnykh <dm.chestnykh@gmail.com>
+ */
+
+/*\
+ * Test that ``ARCH_GET_FS`` and ``ARCH_GET_GS`` return the same bases read independently
+ * by RDFSBASE and RDGSBASE.
+ */
+
+#include "tst_test.h"
+#include "lapi/syscalls.h"
+#include "lapi/arch_prctl.h"
+#include <stdlib.h>
+#include <string.h>
+
+#ifdef __x86_64__
+
+#ifdef HAVE_GETAUXVAL
+# include <sys/auxv.h>
+#endif
+
+static int arch_prctl_get(int code, unsigned long long *out)
+{
+ return tst_syscall(__NR_arch_prctl, code, out);
+}
+
+static int set_gs(unsigned long long val)
+{
+ return tst_syscall(__NR_arch_prctl, ARCH_SET_GS, val);
+}
+
+static bool tag;
+
+static void setup(void)
+{
+ unsigned long long v = 0;
+
+#ifdef AT_HWCAP2
+ v = getauxval(AT_HWCAP2);
+#endif
+ tag = v & HWCAP2_FSGSBASE ? true : false;
+}
+
+#define READ_FS_BASE() ({ \
+ unsigned long long __res_fs; \
+ asm volatile("rdfsbase %0" : "=r"(__res_fs)); \
+ __res_fs; \
+})
+
+#define READ_GS_BASE() ({ \
+ unsigned long long __res_gs; \
+ asm volatile("rdgsbase %0" : "=r"(__res_gs)); \
+ __res_gs; \
+})
+
+static void test_fs(void)
+{
+ unsigned long long fs = READ_FS_BASE();
+ unsigned long long fs_prctl;
+
+ TST_EXP_PASS_SILENT(arch_prctl_get(ARCH_GET_FS, &fs_prctl));
+ if (TST_PASS)
+ TST_EXP_EQ_LU(fs_prctl, fs);
+}
+
+static void test_gs(void)
+{
+ unsigned long long gs, gs_prctl, orig_gs;
+#define TEST_GS_BASE() do { \
+ gs = READ_GS_BASE(); \
+ TST_EXP_PASS_SILENT(arch_prctl_get(ARCH_GET_GS, &gs_prctl)); \
+ if (TST_PASS) { \
+ TST_EXP_EQ_LU(gs_prctl, gs); \
+ } \
+} while (0)
+
+ TEST_GS_BASE();
+ orig_gs = gs;
+
+ if (gs == 0) {
+ unsigned long long test_gs = 0x1ababababULL;
+
+ TST_EXP_PASS_SILENT(set_gs(test_gs));
+ if (TST_PASS)
+ TEST_GS_BASE();
+
+ TST_EXP_PASS_SILENT(set_gs(orig_gs));
+ if (!TST_PASS)
+ tst_brk(TBROK | TTERRNO, "Failed to restore GS base");
+ }
+}
+
+static struct tcase {
+ unsigned int idx;
+ void (*test_fn)(void);
+} tcases[] = {
+ {0, test_fs},
+ {1, test_gs}
+};
+
+static void run(unsigned int index)
+{
+ if (!tag)
+ tst_brk(TCONF, "rdfsbase/rdgsbase are not supported/enabled");
+
+ struct tcase *tc = &tcases[index];
+ (*tc->test_fn)();
+}
+
+static struct tst_test test = {
+ .test = run,
+ .setup = setup,
+ .tcnt = ARRAY_SIZE(tcases),
+ .min_kver = "5.9",
+ .supported_archs = (const char *const []){"x86_64", NULL}
+};
+
+#else
+
+TST_TEST_TCONF("Tests needs x86_64 CPU");
+
+#endif /* __x86_64__ */
--
2.56.0
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply related [flat|nested] 14+ messages in thread
* Re: [LTP] arch_prctl: add ARCH_GET_FS, ARCH_GET_GS tests
2026-10-10 9:44 ` [LTP] [PATCH v7] " dm.chestnykh
@ 2026-10-10 15:49 ` linuxtestproject.agent
0 siblings, 0 replies; 14+ messages in thread
From: linuxtestproject.agent @ 2026-10-10 15:49 UTC (permalink / raw)
To: dm.chestnykh; +Cc: ltp
Hi Dmitry,
On Sat, 10 Oct 2026, Dmitry Chestnykh wrote:
> arch_prctl: add ARCH_GET_FS, ARCH_GET_GS tests
> Signed-off-by: Dmitry Chestnykh <dm.chestnykh@gmail.com>
The commit body lacks a rationale. Explain the coverage gap and why
instruction reads are used as the independent oracle.
> #ifdef HAVE_GETAUXVAL
> # include <sys/auxv.h>
> #endif
>
> static void setup(void)
> {
> unsigned long long v = 0;
>
> #ifdef AT_HWCAP2
> v = getauxval(AT_HWCAP2);
> #endif
> tag = v & HWCAP2_FSGSBASE ? true : false;
> }
Without getauxval support, v stays zero and run() incorrectly reports
that the CPU/kernel does not support the instructions. Guard the entire
test with HAVE_GETAUXVAL and use TST_TEST_TCONF() to report missing libc
support, or provide an auxiliary-vector fallback.
> #define READ_FS_BASE() ({ \
> unsigned long long __res_fs; \
> #define READ_GS_BASE() ({ \
> unsigned long long __res_gs; \
These double-underscore names are reserved to the implementation.
Rename them to fs_base and gs_base.
> static struct tcase {
> unsigned int idx;
> void (*test_fn)(void);
> } tcases[] = {
> {0, test_fs},
> {1, test_gs}
> };
The table dispatches to separate per-case test functions rather than
parameterizing a common comparison. Use one comparison handler with
entries selecting the ARCH_GET operation and base reader; keep
GS-specific preparation in a helper and remove the unused idx member.
Verdict - Needs revision
---
Note:
The agent can sometimes produce false positives although often its
findings are genuine. If you find issues with the review, please
comment this email or ignore the suggestions.
Regards,
LTP AI Reviewer
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply [flat|nested] 14+ messages in thread
end of thread, other threads:[~2026-10-10 15:50 UTC | newest]
Thread overview: 14+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-10-08 19:47 [LTP] [PATCH] arch_prctl: add ARCH_GET_FS, ARCH_GET_GS tests dm.chestnykh
2026-10-09 10:12 ` [LTP] " linuxtestproject.agent
2026-10-09 15:52 ` [LTP] [PATCH v2] " dm.chestnykh
2026-10-09 17:27 ` [LTP] " linuxtestproject.agent
2026-10-09 18:35 ` [LTP] [PATCH v3] " dm.chestnykh
2026-10-09 18:39 ` [LTP] [PATCH v4] " dm.chestnykh
2026-10-09 22:23 ` [LTP] " linuxtestproject.agent
2026-10-10 6:38 ` [LTP] [PATCH v5] " dm.chestnykh
2026-10-10 6:42 ` [LTP] [PATCH v6] " dm.chestnykh
2026-10-10 9:35 ` [LTP] " linuxtestproject.agent
2026-10-10 9:44 ` [LTP] [PATCH v7] " dm.chestnykh
2026-10-10 15:49 ` [LTP] " linuxtestproject.agent
2026-10-10 9:35 ` linuxtestproject.agent
2026-10-09 22:23 ` linuxtestproject.agent
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.