Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 18ad51dd authored by Anton Blanchard's avatar Anton Blanchard Committed by Benjamin Herrenschmidt
Browse files

powerpc: Add VDSO version of getcpu



We have a request for a fast method of getting CPU and NUMA node IDs
from userspace. This patch implements a getcpu VDSO function,
similar to x86.

Ben suggested we use SPRG3 which is userspace readable. SPRG3 can be
modified by a KVM guest, so we save the SPRG3 value in the paca and
restore it when transitioning from the guest to the host.

I have a glibc patch that implements sched_getcpu on top of this.
Testing on a POWER7:

baseline: 538 cycles
vdso:      30 cycles

Signed-off-by: default avatarAnton Blanchard <anton@samba.org>
Signed-off-by: default avatarBenjamin Herrenschmidt <benh@kernel.crashing.org>
parent e6a74c6e
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -74,6 +74,7 @@ struct kvmppc_host_state {
	ulong vmhandler;
	ulong scratch0;
	ulong scratch1;
	ulong sprg3;
	u8 in_guest;
	u8 restore_hid5;
	u8 napping;
+3 −2
Original line number Diff line number Diff line
@@ -491,6 +491,7 @@
#define SPRN_SPRG1	0x111	/* Special Purpose Register General 1 */
#define SPRN_SPRG2	0x112	/* Special Purpose Register General 2 */
#define SPRN_SPRG3	0x113	/* Special Purpose Register General 3 */
#define SPRN_USPRG3	0x103	/* SPRG3 userspace read */
#define SPRN_SPRG4	0x114	/* Special Purpose Register General 4 */
#define SPRN_SPRG5	0x115	/* Special Purpose Register General 5 */
#define SPRN_SPRG6	0x116	/* Special Purpose Register General 6 */
@@ -753,14 +754,14 @@
 * 64-bit server:
 *	- SPRG0 unused (reserved for HV on Power4)
 *	- SPRG2 scratch for exception vectors
 *	- SPRG3 unused (user visible)
 *	- SPRG3 CPU and NUMA node for VDSO getcpu (user visible)
 *      - HSPRG0 stores PACA in HV mode
 *      - HSPRG1 scratch for "HV" exceptions
 *
 * 64-bit embedded
 *	- SPRG0 generic exception scratch
 *	- SPRG2 TLB exception stack
 *	- SPRG3 unused (user visible)
 *	- SPRG3 CPU and NUMA node for VDSO getcpu (user visible)
 *	- SPRG4 unused (user visible)
 *	- SPRG6 TLB miss scratch (user visible, sorry !)
 *	- SPRG7 critical exception scratch
+2 −0
Original line number Diff line number Diff line
@@ -22,6 +22,8 @@ extern unsigned long vdso64_rt_sigtramp;
extern unsigned long vdso32_sigtramp;
extern unsigned long vdso32_rt_sigtramp;

int __cpuinit vdso_getcpu_init(void);

#else /* __ASSEMBLY__ */

#ifdef __VDSO64__
+1 −0
Original line number Diff line number Diff line
@@ -533,6 +533,7 @@ int main(void)
	HSTATE_FIELD(HSTATE_VMHANDLER, vmhandler);
	HSTATE_FIELD(HSTATE_SCRATCH0, scratch0);
	HSTATE_FIELD(HSTATE_SCRATCH1, scratch1);
	HSTATE_FIELD(HSTATE_SPRG3, sprg3);
	HSTATE_FIELD(HSTATE_IN_GUEST, in_guest);
	HSTATE_FIELD(HSTATE_RESTORE_HID5, restore_hid5);
	HSTATE_FIELD(HSTATE_NAPPING, napping);
+3 −0
Original line number Diff line number Diff line
@@ -48,6 +48,7 @@
#ifdef CONFIG_PPC64
#include <asm/paca.h>
#endif
#include <asm/vdso.h>
#include <asm/debug.h>

#ifdef DEBUG
@@ -570,6 +571,8 @@ void __devinit start_secondary(void *unused)
#ifdef CONFIG_PPC64
	if (system_state == SYSTEM_RUNNING)
		vdso_data->processorCount++;

	vdso_getcpu_init();
#endif
	notify_cpu_starting(cpu);
	set_cpu_online(cpu, true);
Loading