mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-12-16 00:06:46 +07:00
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: Christian Borntraeger <borntraeger@de.ibm.com> Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com> Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
This commit is contained in:
parent
a2308c11ec
commit
5a5525b048
@ -41,8 +41,17 @@ struct vdso_data {
|
|||||||
struct vdso_per_cpu_data {
|
struct vdso_per_cpu_data {
|
||||||
__u64 ectg_timer_base;
|
__u64 ectg_timer_base;
|
||||||
__u64 ectg_user_time;
|
__u64 ectg_user_time;
|
||||||
__u32 cpu_nr;
|
/*
|
||||||
__u32 node_id;
|
* 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;
|
extern struct vdso_data *vdso_data;
|
||||||
|
@ -78,8 +78,7 @@ int main(void)
|
|||||||
OFFSET(__VDSO_TS_END, vdso_data, ts_end);
|
OFFSET(__VDSO_TS_END, vdso_data, ts_end);
|
||||||
OFFSET(__VDSO_ECTG_BASE, vdso_per_cpu_data, ectg_timer_base);
|
OFFSET(__VDSO_ECTG_BASE, vdso_per_cpu_data, ectg_timer_base);
|
||||||
OFFSET(__VDSO_ECTG_USER, vdso_per_cpu_data, ectg_user_time);
|
OFFSET(__VDSO_ECTG_USER, vdso_per_cpu_data, ectg_user_time);
|
||||||
OFFSET(__VDSO_CPU_NR, vdso_per_cpu_data, cpu_nr);
|
OFFSET(__VDSO_GETCPU_VAL, vdso_per_cpu_data, getcpu_val);
|
||||||
OFFSET(__VDSO_NODE_ID, vdso_per_cpu_data, node_id);
|
|
||||||
BLANK();
|
BLANK();
|
||||||
/* constants used by the vdso */
|
/* constants used by the vdso */
|
||||||
DEFINE(__CLOCK_REALTIME, CLOCK_REALTIME);
|
DEFINE(__CLOCK_REALTIME, CLOCK_REALTIME);
|
||||||
|
@ -16,10 +16,8 @@
|
|||||||
.type __kernel_getcpu,@function
|
.type __kernel_getcpu,@function
|
||||||
__kernel_getcpu:
|
__kernel_getcpu:
|
||||||
CFI_STARTPROC
|
CFI_STARTPROC
|
||||||
la %r4,0
|
|
||||||
sacf 256
|
sacf 256
|
||||||
l %r5,__VDSO_CPU_NR(%r4)
|
lm %r4,%r5,__VDSO_GETCPU_VAL(%r0)
|
||||||
l %r4,__VDSO_NODE_ID(%r4)
|
|
||||||
sacf 0
|
sacf 0
|
||||||
ltr %r2,%r2
|
ltr %r2,%r2
|
||||||
jz 2f
|
jz 2f
|
||||||
|
@ -16,10 +16,8 @@
|
|||||||
.type __kernel_getcpu,@function
|
.type __kernel_getcpu,@function
|
||||||
__kernel_getcpu:
|
__kernel_getcpu:
|
||||||
CFI_STARTPROC
|
CFI_STARTPROC
|
||||||
la %r4,0
|
|
||||||
sacf 256
|
sacf 256
|
||||||
l %r5,__VDSO_CPU_NR(%r4)
|
lm %r4,%r5,__VDSO_GETCPU_VAL(%r0)
|
||||||
l %r4,__VDSO_NODE_ID(%r4)
|
|
||||||
sacf 0
|
sacf 0
|
||||||
ltgr %r2,%r2
|
ltgr %r2,%r2
|
||||||
jz 2f
|
jz 2f
|
||||||
|
Loading…
Reference in New Issue
Block a user