s390/vdso: reimplement getcpu vdso syscall
Implement the previously removed getcpu vdso syscall by using the TOD programmable field to pass the cpu number to user space. Reviewed-by: Sven Schnelle <svens@linux.ibm.com> Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
This commit is contained in:
parent
062e527956
commit
80f0630624
|
@ -49,6 +49,13 @@ static inline void set_clock_comparator(__u64 time)
|
||||||
asm volatile("sckc %0" : : "Q" (time));
|
asm volatile("sckc %0" : : "Q" (time));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void set_tod_programmable_field(u16 val)
|
||||||
|
{
|
||||||
|
register unsigned long reg0 asm("0") = val;
|
||||||
|
|
||||||
|
asm volatile("sckpf" : : "d" (reg0));
|
||||||
|
}
|
||||||
|
|
||||||
void clock_comparator_work(void);
|
void clock_comparator_work(void);
|
||||||
|
|
||||||
void __init time_early_init(void);
|
void __init time_early_init(void);
|
||||||
|
|
|
@ -14,5 +14,7 @@
|
||||||
|
|
||||||
extern struct vdso_data *vdso_data;
|
extern struct vdso_data *vdso_data;
|
||||||
|
|
||||||
|
void vdso_getcpu_init(void);
|
||||||
|
|
||||||
#endif /* __ASSEMBLY__ */
|
#endif /* __ASSEMBLY__ */
|
||||||
#endif /* __S390_VDSO_H__ */
|
#endif /* __S390_VDSO_H__ */
|
||||||
|
|
|
@ -54,6 +54,7 @@
|
||||||
#include <asm/nmi.h>
|
#include <asm/nmi.h>
|
||||||
#include <asm/stacktrace.h>
|
#include <asm/stacktrace.h>
|
||||||
#include <asm/topology.h>
|
#include <asm/topology.h>
|
||||||
|
#include <asm/vdso.h>
|
||||||
#include "entry.h"
|
#include "entry.h"
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
|
@ -858,6 +859,7 @@ static void smp_init_secondary(void)
|
||||||
preempt_disable();
|
preempt_disable();
|
||||||
init_cpu_timer();
|
init_cpu_timer();
|
||||||
vtime_init();
|
vtime_init();
|
||||||
|
vdso_getcpu_init();
|
||||||
pfault_init();
|
pfault_init();
|
||||||
notify_cpu_starting(cpu);
|
notify_cpu_starting(cpu);
|
||||||
if (topology_cpu_dedicated(cpu))
|
if (topology_cpu_dedicated(cpu))
|
||||||
|
|
|
@ -29,6 +29,7 @@
|
||||||
#include <asm/sections.h>
|
#include <asm/sections.h>
|
||||||
#include <asm/vdso.h>
|
#include <asm/vdso.h>
|
||||||
#include <asm/facility.h>
|
#include <asm/facility.h>
|
||||||
|
#include <asm/timex.h>
|
||||||
|
|
||||||
extern char vdso64_start, vdso64_end;
|
extern char vdso64_start, vdso64_end;
|
||||||
static void *vdso64_kbase = &vdso64_start;
|
static void *vdso64_kbase = &vdso64_start;
|
||||||
|
@ -100,6 +101,11 @@ static union {
|
||||||
} vdso_data_store __page_aligned_data;
|
} vdso_data_store __page_aligned_data;
|
||||||
struct vdso_data *vdso_data = (struct vdso_data *)&vdso_data_store.data;
|
struct vdso_data *vdso_data = (struct vdso_data *)&vdso_data_store.data;
|
||||||
|
|
||||||
|
void vdso_getcpu_init(void)
|
||||||
|
{
|
||||||
|
set_tod_programmable_field(smp_processor_id());
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This is called from binfmt_elf, we create the special vma for the
|
* This is called from binfmt_elf, we create the special vma for the
|
||||||
* vDSO and insert it into the mm struct tree
|
* vDSO and insert it into the mm struct tree
|
||||||
|
@ -170,6 +176,7 @@ static int __init vdso_init(void)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
vdso_getcpu_init();
|
||||||
/* Calculate the size of the 64 bit vDSO */
|
/* Calculate the size of the 64 bit vDSO */
|
||||||
vdso64_pages = ((&vdso64_end - &vdso64_start
|
vdso64_pages = ((&vdso64_end - &vdso64_start
|
||||||
+ PAGE_SIZE - 1) >> PAGE_SHIFT) + 1;
|
+ PAGE_SIZE - 1) >> PAGE_SHIFT) + 1;
|
||||||
|
|
|
@ -7,7 +7,8 @@ ARCH_REL_TYPE_ABS += R_390_GOT|R_390_PLT
|
||||||
|
|
||||||
include $(srctree)/lib/vdso/Makefile
|
include $(srctree)/lib/vdso/Makefile
|
||||||
obj-vdso64 = vdso_user_wrapper.o note.o
|
obj-vdso64 = vdso_user_wrapper.o note.o
|
||||||
obj-cvdso64 = vdso64_generic.o
|
obj-cvdso64 = vdso64_generic.o getcpu.o
|
||||||
|
CFLAGS_REMOVE_getcpu.o = -pg $(CC_FLAGS_FTRACE) $(CC_FLAGS_EXPOLINE)
|
||||||
CFLAGS_REMOVE_vdso64_generic.o = -pg $(CC_FLAGS_FTRACE) $(CC_FLAGS_EXPOLINE)
|
CFLAGS_REMOVE_vdso64_generic.o = -pg $(CC_FLAGS_FTRACE) $(CC_FLAGS_EXPOLINE)
|
||||||
|
|
||||||
# Build rules
|
# Build rules
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
// SPDX-License-Identifier: GPL-2.0
|
||||||
|
/* Copyright IBM Corp. 2020 */
|
||||||
|
|
||||||
|
#include <linux/compiler.h>
|
||||||
|
#include <linux/getcpu.h>
|
||||||
|
#include <asm/timex.h>
|
||||||
|
|
||||||
|
int __s390_vdso_getcpu(unsigned *cpu, unsigned *node, struct getcpu_cache *unused)
|
||||||
|
{
|
||||||
|
__u16 todval[8];
|
||||||
|
|
||||||
|
/* CPU number is stored in the programmable field of the TOD clock */
|
||||||
|
get_tod_clock_ext((char *)todval);
|
||||||
|
if (cpu)
|
||||||
|
*cpu = todval[7];
|
||||||
|
/* NUMA node is always zero */
|
||||||
|
if (node)
|
||||||
|
*node = 0;
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -135,7 +135,7 @@ VERSION
|
||||||
__kernel_gettimeofday;
|
__kernel_gettimeofday;
|
||||||
__kernel_clock_gettime;
|
__kernel_clock_gettime;
|
||||||
__kernel_clock_getres;
|
__kernel_clock_getres;
|
||||||
|
__kernel_getcpu;
|
||||||
local: *;
|
local: *;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,3 +36,4 @@ __kernel_\func:
|
||||||
vdso_func gettimeofday
|
vdso_func gettimeofday
|
||||||
vdso_func clock_getres
|
vdso_func clock_getres
|
||||||
vdso_func clock_gettime
|
vdso_func clock_gettime
|
||||||
|
vdso_func getcpu
|
||||||
|
|
Loading…
Reference in New Issue