Subject: [PATCH 0/3] x86: Provide a vdso for getcpu on x86-32.

This tiny series provides getcpu in vdso on x86-32. Due to the setup
RDTSCP now also returns CPU and node information like x86-64 does.

The usage of RDTSCP + vdso has been tested in a VM with 64bit kernel and
32bit binary and a 32bit kernel.

Sebastian



Subject: [PATCH 3/3] selftests: Make a warning if getcpu is missing on 32bit.

The vsyscall for getcpu has been wired up on 32bit so it can be warned
now if missing.

Cc: Shuah Khan <[email protected]>
Cc: [email protected]
Signed-off-by: Sebastian Andrzej Siewior <[email protected]>
---
tools/testing/selftests/x86/test_vsyscall.c | 7 ++-----
1 file changed, 2 insertions(+), 5 deletions(-)

diff --git a/tools/testing/selftests/x86/test_vsyscall.c b/tools/testing/selftests/x86/test_vsyscall.c
index 5b45e6986aeab..47cab972807c4 100644
--- a/tools/testing/selftests/x86/test_vsyscall.c
+++ b/tools/testing/selftests/x86/test_vsyscall.c
@@ -92,11 +92,8 @@ static void init_vdso(void)
printf("[WARN]\tfailed to find time in vDSO\n");

vdso_getcpu = (getcpu_t)dlsym(vdso, "__vdso_getcpu");
- if (!vdso_getcpu) {
- /* getcpu() was never wired up in the 32-bit vDSO. */
- printf("[%s]\tfailed to find getcpu in vDSO\n",
- sizeof(long) == 8 ? "WARN" : "NOTE");
- }
+ if (!vdso_getcpu)
+ printf("[WARN]\tfailed to find getcpu in vDSO\n");
}

static int init_vsys(void)
--
2.38.1

Subject: [PATCH 2/3] x86/vdso: Provide getcpu for x86-32.

Wire up __vdso_getcpu() for x86-32. The version for 64bit can be reused.
The defines must no be faked (like it is done for vclock_gettime.c)
because we need the 64bit defines for the 32bit VDSO because the segment
number of the host kernel is required.

Reuse the vgetcpu.c for vdso32. Remove the time* header files which lead
to compile errors on 32bit. Add segment.h which provides
vdso_read_cpunode() and its requirements.

Signed-off-by: Sebastian Andrzej Siewior <[email protected]>
---
arch/x86/entry/vdso/Makefile | 3 ++-
arch/x86/entry/vdso/vdso32/vdso32.lds.S | 1 +
arch/x86/entry/vdso/vdso32/vgetcpu.c | 2 ++
arch/x86/entry/vdso/vgetcpu.c | 3 +--
4 files changed, 6 insertions(+), 3 deletions(-)
create mode 100644 arch/x86/entry/vdso/vdso32/vgetcpu.c

diff --git a/arch/x86/entry/vdso/Makefile b/arch/x86/entry/vdso/Makefile
index 3e88b9df8c8f1..fcbcfc2b4e1a7 100644
--- a/arch/x86/entry/vdso/Makefile
+++ b/arch/x86/entry/vdso/Makefile
@@ -29,7 +29,7 @@ VDSO32-$(CONFIG_IA32_EMULATION) := y
# files to link into the vdso
vobjs-y := vdso-note.o vclock_gettime.o vgetcpu.o
vobjs32-y := vdso32/note.o vdso32/system_call.o vdso32/sigreturn.o
-vobjs32-y += vdso32/vclock_gettime.o
+vobjs32-y += vdso32/vclock_gettime.o vdso32/vgetcpu.o
vobjs-$(CONFIG_X86_SGX) += vsgx.o

# files to link into kernel
@@ -103,6 +103,7 @@ $(vobjs): KBUILD_AFLAGS += -DBUILD_VDSO
CFLAGS_REMOVE_vclock_gettime.o = -pg
CFLAGS_REMOVE_vdso32/vclock_gettime.o = -pg
CFLAGS_REMOVE_vgetcpu.o = -pg
+CFLAGS_REMOVE_vdso32/vgetcpu.o = -pg
CFLAGS_REMOVE_vsgx.o = -pg

#
diff --git a/arch/x86/entry/vdso/vdso32/vdso32.lds.S b/arch/x86/entry/vdso/vdso32/vdso32.lds.S
index c7720995ab1af..8a3be07006bb6 100644
--- a/arch/x86/entry/vdso/vdso32/vdso32.lds.S
+++ b/arch/x86/entry/vdso/vdso32/vdso32.lds.S
@@ -28,6 +28,7 @@ VERSION
__vdso_time;
__vdso_clock_getres;
__vdso_clock_gettime64;
+ __vdso_getcpu;
};

LINUX_2.5 {
diff --git a/arch/x86/entry/vdso/vdso32/vgetcpu.c b/arch/x86/entry/vdso/vdso32/vgetcpu.c
new file mode 100644
index 0000000000000..b777f84ffae9b
--- /dev/null
+++ b/arch/x86/entry/vdso/vdso32/vgetcpu.c
@@ -0,0 +1,2 @@
+// SPDX-License-Identifier: GPL-2.0
+#include "../vgetcpu.c"
diff --git a/arch/x86/entry/vdso/vgetcpu.c b/arch/x86/entry/vdso/vgetcpu.c
index b88a82bbc3593..0a9007c240568 100644
--- a/arch/x86/entry/vdso/vgetcpu.c
+++ b/arch/x86/entry/vdso/vgetcpu.c
@@ -7,8 +7,7 @@

#include <linux/kernel.h>
#include <linux/getcpu.h>
-#include <linux/time.h>
-#include <asm/vgtod.h>
+#include <asm/segment.h>

notrace long
__vdso_getcpu(unsigned *cpu, unsigned *node, struct getcpu_cache *unused)
--
2.38.1

2022-11-29 22:29:24

by Shuah Khan

[permalink] [raw]
Subject: Re: [PATCH 3/3] selftests: Make a warning if getcpu is missing on 32bit.

On 11/25/22 02:42, Sebastian Andrzej Siewior wrote:
> The vsyscall for getcpu has been wired up on 32bit so it can be warned
> now if missing.
>
> Cc: Shuah Khan <[email protected]>
> Cc: [email protected]
> Signed-off-by: Sebastian Andrzej Siewior <[email protected]>
> ---
> tools/testing/selftests/x86/test_vsyscall.c | 7 ++-----
> 1 file changed, 2 insertions(+), 5 deletions(-)
>
> diff --git a/tools/testing/selftests/x86/test_vsyscall.c b/tools/testing/selftests/x86/test_vsyscall.c
> index 5b45e6986aeab..47cab972807c4 100644
> --- a/tools/testing/selftests/x86/test_vsyscall.c
> +++ b/tools/testing/selftests/x86/test_vsyscall.c
> @@ -92,11 +92,8 @@ static void init_vdso(void)
> printf("[WARN]\tfailed to find time in vDSO\n");
>
> vdso_getcpu = (getcpu_t)dlsym(vdso, "__vdso_getcpu");
> - if (!vdso_getcpu) {
> - /* getcpu() was never wired up in the 32-bit vDSO. */
> - printf("[%s]\tfailed to find getcpu in vDSO\n",
> - sizeof(long) == 8 ? "WARN" : "NOTE");
> - }
> + if (!vdso_getcpu)
> + printf("[WARN]\tfailed to find getcpu in vDSO\n");
> }
>
> static int init_vsys(void)

Assuming this is going through x86 tree due to dependencies, here is
my ack

Acked-by: Shuah Khan <[email protected]>

Let me know if you would like to me pick this up.

thanks,
-- Shuah

Subject: Re: [PATCH 0/3] x86: Provide a vdso for getcpu on x86-32.

On 2022-11-25 10:42:13 [+0100], To [email protected] wrote:
> This tiny series provides getcpu in vdso on x86-32. Due to the setup
> RDTSCP now also returns CPU and node information like x86-64 does.
>
> The usage of RDTSCP + vdso has been tested in a VM with 64bit kernel and
> 32bit binary and a 32bit kernel.

ping.

Sebastian

2023-02-01 12:31:20

by Roland Mainz

[permalink] [raw]
Subject: Re: [PATCH 0/3] x86: Provide a vdso for getcpu on x86-32.

On Thu, Jan 12, 2023 at 9:52 AM Sebastian Andrzej Siewior
<[email protected]> wrote:
> On 2022-11-25 10:42:13 [+0100], To [email protected] wrote:
> > This tiny series provides getcpu in vdso on x86-32. Due to the setup
> > RDTSCP now also returns CPU and node information like x86-64 does.
> >
> > The usage of RDTSCP + vdso has been tested in a VM with 64bit kernel and
> > 32bit binary and a 32bit kernel.
>
> ping.

Is there a commit id for the Linux mainline yet ?

----

Bye,
Roland
--
__ . . __
(o.\ \/ /.o) [email protected]
\__\/\/__/ MPEG specialist, C&&JAVA&&Sun&&Unix programmer
/O /==\ O\ TEL +49 641 3992797
(;O/ \/ \O;)

2023-02-06 14:57:53

by tip-bot2 for Jacob Pan

[permalink] [raw]
Subject: [tip: x86/vdso] selftests: Emit a warning if getcpu() is missing on 32bit

The following commit has been merged into the x86/vdso branch of tip:

Commit-ID: 5646bbd6684acf5c9b9dedb863b7d2f6f5a330fb
Gitweb: https://git.kernel.org/tip/5646bbd6684acf5c9b9dedb863b7d2f6f5a330fb
Author: Sebastian Andrzej Siewior <[email protected]>
AuthorDate: Fri, 25 Nov 2022 10:42:16 +01:00
Committer: Thomas Gleixner <[email protected]>
CommitterDate: Mon, 06 Feb 2023 15:48:54 +01:00

selftests: Emit a warning if getcpu() is missing on 32bit

The VDSO implementation for getcpu() has been wired up on 32bit so warn if
missing.

Signed-off-by: Sebastian Andrzej Siewior <[email protected]>
Signed-off-by: Thomas Gleixner <[email protected]>
Acked-by: Shuah Khan <[email protected]>
Link: https://lore.kernel.org/r/[email protected]

---
tools/testing/selftests/x86/test_vsyscall.c | 7 ++-----
1 file changed, 2 insertions(+), 5 deletions(-)

diff --git a/tools/testing/selftests/x86/test_vsyscall.c b/tools/testing/selftests/x86/test_vsyscall.c
index 5b45e69..47cab97 100644
--- a/tools/testing/selftests/x86/test_vsyscall.c
+++ b/tools/testing/selftests/x86/test_vsyscall.c
@@ -92,11 +92,8 @@ static void init_vdso(void)
printf("[WARN]\tfailed to find time in vDSO\n");

vdso_getcpu = (getcpu_t)dlsym(vdso, "__vdso_getcpu");
- if (!vdso_getcpu) {
- /* getcpu() was never wired up in the 32-bit vDSO. */
- printf("[%s]\tfailed to find getcpu in vDSO\n",
- sizeof(long) == 8 ? "WARN" : "NOTE");
- }
+ if (!vdso_getcpu)
+ printf("[WARN]\tfailed to find getcpu in vDSO\n");
}

static int init_vsys(void)

2023-02-06 14:57:57

by tip-bot2 for Jacob Pan

[permalink] [raw]
Subject: [tip: x86/vdso] x86/vdso: Provide getcpu for x86-32.

The following commit has been merged into the x86/vdso branch of tip:

Commit-ID: 92d33063c081a82d25dd08a9cce03947c8ed9164
Gitweb: https://git.kernel.org/tip/92d33063c081a82d25dd08a9cce03947c8ed9164
Author: Sebastian Andrzej Siewior <[email protected]>
AuthorDate: Fri, 25 Nov 2022 10:42:15 +01:00
Committer: Thomas Gleixner <[email protected]>
CommitterDate: Mon, 06 Feb 2023 15:48:54 +01:00

x86/vdso: Provide getcpu for x86-32.

Wire up __vdso_getcpu() for x86-32.

The 64bit version is reused with trivial modifications. Contrary to
vclock_gettime.c there is no requirement to fake any defines in the case of
32bit VDSO on a 64bit kernel because the GDT entry from which the CPU and
node information is read is always the native one.

Adopt vdso_getcpu.c by:

- removing the unneeded time* header files which lead to compile errors
for 32bit.
- adding segment.h which provides vdso_read_cpunode() and the defines
required by it.

Signed-off-by: Sebastian Andrzej Siewior <[email protected]>
Signed-off-by: Thomas Gleixner <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
---
arch/x86/entry/vdso/Makefile | 3 ++-
arch/x86/entry/vdso/vdso32/vdso32.lds.S | 1 +
arch/x86/entry/vdso/vdso32/vgetcpu.c | 2 ++
arch/x86/entry/vdso/vgetcpu.c | 3 +--
4 files changed, 6 insertions(+), 3 deletions(-)
create mode 100644 arch/x86/entry/vdso/vdso32/vgetcpu.c

diff --git a/arch/x86/entry/vdso/Makefile b/arch/x86/entry/vdso/Makefile
index 838613a..1506a22 100644
--- a/arch/x86/entry/vdso/Makefile
+++ b/arch/x86/entry/vdso/Makefile
@@ -29,7 +29,7 @@ VDSO32-$(CONFIG_IA32_EMULATION) := y
# files to link into the vdso
vobjs-y := vdso-note.o vclock_gettime.o vgetcpu.o
vobjs32-y := vdso32/note.o vdso32/system_call.o vdso32/sigreturn.o
-vobjs32-y += vdso32/vclock_gettime.o
+vobjs32-y += vdso32/vclock_gettime.o vdso32/vgetcpu.o
vobjs-$(CONFIG_X86_SGX) += vsgx.o

# files to link into kernel
@@ -104,6 +104,7 @@ $(vobjs): KBUILD_AFLAGS += -DBUILD_VDSO
CFLAGS_REMOVE_vclock_gettime.o = -pg
CFLAGS_REMOVE_vdso32/vclock_gettime.o = -pg
CFLAGS_REMOVE_vgetcpu.o = -pg
+CFLAGS_REMOVE_vdso32/vgetcpu.o = -pg
CFLAGS_REMOVE_vsgx.o = -pg

#
diff --git a/arch/x86/entry/vdso/vdso32/vdso32.lds.S b/arch/x86/entry/vdso/vdso32/vdso32.lds.S
index c772099..8a3be07 100644
--- a/arch/x86/entry/vdso/vdso32/vdso32.lds.S
+++ b/arch/x86/entry/vdso/vdso32/vdso32.lds.S
@@ -28,6 +28,7 @@ VERSION
__vdso_time;
__vdso_clock_getres;
__vdso_clock_gettime64;
+ __vdso_getcpu;
};

LINUX_2.5 {
diff --git a/arch/x86/entry/vdso/vdso32/vgetcpu.c b/arch/x86/entry/vdso/vdso32/vgetcpu.c
new file mode 100644
index 0000000..b777f84
--- /dev/null
+++ b/arch/x86/entry/vdso/vdso32/vgetcpu.c
@@ -0,0 +1,2 @@
+// SPDX-License-Identifier: GPL-2.0
+#include "../vgetcpu.c"
diff --git a/arch/x86/entry/vdso/vgetcpu.c b/arch/x86/entry/vdso/vgetcpu.c
index b88a82b..0a9007c 100644
--- a/arch/x86/entry/vdso/vgetcpu.c
+++ b/arch/x86/entry/vdso/vgetcpu.c
@@ -7,8 +7,7 @@

#include <linux/kernel.h>
#include <linux/getcpu.h>
-#include <linux/time.h>
-#include <asm/vgtod.h>
+#include <asm/segment.h>

notrace long
__vdso_getcpu(unsigned *cpu, unsigned *node, struct getcpu_cache *unused)