Commit 5a5525b0 authored by Heiko Carstens's avatar Heiko Carstens Committed by Vasily Gorbik
Browse files

s390/vdso: fix getcpu



getcpu reads the required values for cpu and node with two
instructions. This might lead to an inconsistent result if user space
gets preempted and migrated to a different CPU between the two
instructions.

Fix this by using just a single instruction to read both values at
once.

This is currently rather a theoretical bug, since there is no real
NUMA support available (except for NUMA emulation).

Reviewed-by: default avatarChristian Borntraeger <borntraeger@de.ibm.com>
Signed-off-by: default avatarHeiko Carstens <heiko.carstens@de.ibm.com>
Signed-off-by: default avatarVasily Gorbik <gor@linux.ibm.com>
parent a2308c11
Loading
Loading
Loading
Loading
+11 −2
Original line number Diff line number Diff line
@@ -41,8 +41,17 @@ struct vdso_data {
struct vdso_per_cpu_data {
	__u64 ectg_timer_base;
	__u64 ectg_user_time;
	__u32 cpu_nr;
	/*
	 * Note: node_id and cpu_nr must be at adjacent memory locations.
	 * VDSO userspace must read both values with a single instruction.
	 */
	union {
		__u64 getcpu_val;
		struct {
			__u32 node_id;
			__u32 cpu_nr;
		};
	};
};

extern struct vdso_data *vdso_data;
+1 −2
Original line number Diff line number Diff line
@@ -78,8 +78,7 @@ int main(void)
	OFFSET(__VDSO_TS_END, vdso_data, ts_end);
	OFFSET(__VDSO_ECTG_BASE, vdso_per_cpu_data, ectg_timer_base);
	OFFSET(__VDSO_ECTG_USER, vdso_per_cpu_data, ectg_user_time);
	OFFSET(__VDSO_CPU_NR, vdso_per_cpu_data, cpu_nr);
	OFFSET(__VDSO_NODE_ID, vdso_per_cpu_data, node_id);
	OFFSET(__VDSO_GETCPU_VAL, vdso_per_cpu_data, getcpu_val);
	BLANK();
	/* constants used by the vdso */
	DEFINE(__CLOCK_REALTIME, CLOCK_REALTIME);
+1 −3
Original line number Diff line number Diff line
@@ -16,10 +16,8 @@
	.type  __kernel_getcpu,@function
__kernel_getcpu:
	CFI_STARTPROC
	la	%r4,0
	sacf	256
	l	%r5,__VDSO_CPU_NR(%r4)
	l	%r4,__VDSO_NODE_ID(%r4)
	lm	%r4,%r5,__VDSO_GETCPU_VAL(%r0)
	sacf	0
	ltr	%r2,%r2
	jz	2f
+1 −3
Original line number Diff line number Diff line
@@ -16,10 +16,8 @@
	.type  __kernel_getcpu,@function
__kernel_getcpu:
	CFI_STARTPROC
	la	%r4,0
	sacf	256
	l	%r5,__VDSO_CPU_NR(%r4)
	l	%r4,__VDSO_NODE_ID(%r4)
	lm	%r4,%r5,__VDSO_GETCPU_VAL(%r0)
	sacf	0
	ltgr	%r2,%r2
	jz	2f