Merge tag 'timers-vdso-2024-11-18' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull vdso data page handling updates from Thomas Gleixner:
 "First steps of consolidating the VDSO data page handling.

  The VDSO data page handling is architecture specific for historical
  reasons, but there is no real technical reason to do so.

  Aside of that VDSO data has become a dump ground for various
  mechanisms and fail to provide a clear separation of the
  functionalities.

  Clean this up by:

   - consolidating the VDSO page data by getting rid of architecture
     specific warts especially in x86 and PowerPC.

   - removing the last includes of header files which are pulling in
     other headers outside of the VDSO namespace.

   - seperating timekeeping and other VDSO data accordingly.

  Further consolidation of the VDSO page handling is done in subsequent
  changes scheduled for the next merge window.

  This also lays the ground for expanding the VDSO time getters for
  independent PTP clocks in a generic way without making every
  architecture add support seperately"

* tag 'timers-vdso-2024-11-18' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (42 commits)
  x86/vdso: Add missing brackets in switch case
  vdso: Rename struct arch_vdso_data to arch_vdso_time_data
  powerpc: Split systemcfg struct definitions out from vdso
  powerpc: Split systemcfg data out of vdso data page
  powerpc: Add kconfig option for the systemcfg page
  powerpc/pseries/lparcfg: Use num_possible_cpus() for potential processors
  powerpc/pseries/lparcfg: Fix printing of system_active_processors
  powerpc/procfs: Propagate error of remap_pfn_range()
  powerpc/vdso: Remove offset comment from 32bit vdso_arch_data
  x86/vdso: Split virtual clock pages into dedicated mapping
  x86/vdso: Delete vvar.h
  x86/vdso: Access vdso data without vvar.h
  x86/vdso: Move the rng offset to vsyscall.h
  x86/vdso: Access rng vdso data without vvar.h
  x86/vdso: Access timens vdso data without vvar.h
  x86/vdso: Allocate vvar page from C code
  x86/vdso: Access rng data from kernel without vvar
  x86/vdso: Place vdso_data at beginning of vvar page
  x86/vdso: Use __arch_get_vdso_data() to access vdso data
  x86/mm/mmap: Remove arch_vma_name()
  ...
This commit is contained in:
Linus Torvalds
2024-11-19 16:09:13 -08:00
98 changed files with 371 additions and 781 deletions
+1 -1
View File
@@ -1529,7 +1529,7 @@ config HAVE_SPARSE_SYSCALL_NR
entries at 4000, 5000 and 6000 locations. This option turns on syscall
related optimizations for a given architecture.
config ARCH_HAS_VDSO_DATA
config ARCH_HAS_VDSO_TIME_DATA
bool
config HAVE_STATIC_CALL
+1 -5
View File
@@ -4,11 +4,7 @@
#include <linux/const.h>
#include <asm/pal.h>
/* PAGE_SHIFT determines the page size */
#define PAGE_SHIFT CONFIG_PAGE_SHIFT
#define PAGE_SIZE (_AC(1,UL) << PAGE_SHIFT)
#define PAGE_MASK (~(PAGE_SIZE-1))
#include <vdso/page.h>
#ifndef __ASSEMBLY__
+3 -4
View File
@@ -14,7 +14,7 @@
/* PAGE_SHIFT determines the page size */
#ifdef __KERNEL__
#define PAGE_SHIFT CONFIG_PAGE_SHIFT
#include <vdso/page.h>
#else
/*
* Default 8k
@@ -24,11 +24,10 @@
* not available
*/
#define PAGE_SHIFT 13
#define PAGE_SIZE _BITUL(PAGE_SHIFT) /* Default 8K */
#define PAGE_MASK (~(PAGE_SIZE-1))
#endif
#define PAGE_SIZE _BITUL(PAGE_SHIFT) /* Default 8K */
#define PAGE_OFFSET _AC(0x80000000, UL) /* Kernel starts at 2G onwrds */
#define PAGE_MASK (~(PAGE_SIZE-1))
#endif /* _UAPI__ASM_ARC_PAGE_H */
+1 -4
View File
@@ -7,10 +7,7 @@
#ifndef _ASMARM_PAGE_H
#define _ASMARM_PAGE_H
/* PAGE_SHIFT determines the page size */
#define PAGE_SHIFT CONFIG_PAGE_SHIFT
#define PAGE_SIZE (_AC(1,UL) << PAGE_SHIFT)
#define PAGE_MASK (~((1 << PAGE_SHIFT) - 1))
#include <vdso/page.h>
#ifndef __ASSEMBLY__
+1 -3
View File
@@ -15,8 +15,6 @@
#define VDSO_HAS_CLOCK_GETRES 1
extern struct vdso_data *__get_datapage(void);
static __always_inline int gettimeofday_fallback(
struct __kernel_old_timeval *_tv,
struct timezone *_tz)
@@ -139,7 +137,7 @@ static __always_inline u64 __arch_get_hw_counter(int clock_mode,
static __always_inline const struct vdso_data *__arch_get_vdso_data(void)
{
return __get_datapage();
return _vdso_data;
}
#endif /* !__ASSEMBLY__ */
-4
View File
@@ -4,16 +4,12 @@
#ifndef __ASSEMBLY__
#include <linux/timekeeper_internal.h>
#include <vdso/datapage.h>
#include <asm/cacheflush.h>
extern struct vdso_data *vdso_data;
extern bool cntvct_ok;
/*
* Update the vDSO data page to keep in sync with kernel timekeeping.
*/
static __always_inline
struct vdso_data *__arm_get_k_vdso_data(void)
{
-1
View File
@@ -14,7 +14,6 @@
#include <linux/of.h>
#include <linux/printk.h>
#include <linux/slab.h>
#include <linux/timekeeper_internal.h>
#include <linux/vmalloc.h>
#include <asm/arch_timer.h>
#include <asm/barrier.h>
+1 -1
View File
@@ -5,7 +5,7 @@ include $(srctree)/lib/vdso/Makefile
hostprogs := vdsomunge
obj-vdso := vgettimeofday.o datapage.o note.o
obj-vdso := vgettimeofday.o note.o
# Build rules
targets := $(obj-vdso) vdso.so vdso.so.dbg vdso.so.raw vdso.lds
-16
View File
@@ -1,16 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0 */
#include <linux/linkage.h>
#include <asm/asm-offsets.h>
.align 2
.L_vdso_data_ptr:
.long _start - . - VDSO_DATA_SIZE
ENTRY(__get_datapage)
.fnstart
adr r0, .L_vdso_data_ptr
ldr r1, [r0]
add r0, r0, r1
bx lr
.fnend
ENDPROC(__get_datapage)
+2 -1
View File
@@ -11,6 +11,7 @@
*/
#include <linux/const.h>
#include <asm/asm-offsets.h>
#include <asm/page.h>
#include <asm/vdso.h>
@@ -19,7 +20,7 @@ OUTPUT_ARCH(arm)
SECTIONS
{
PROVIDE(_start = .);
PROVIDE(_vdso_data = . - VDSO_DATA_SIZE);
. = SIZEOF_HEADERS;
+1 -4
View File
@@ -10,9 +10,6 @@
#include <linux/const.h>
/* PAGE_SHIFT determines the page size */
#define PAGE_SHIFT CONFIG_PAGE_SHIFT
#define PAGE_SIZE (_AC(1, UL) << PAGE_SHIFT)
#define PAGE_MASK (~(PAGE_SIZE-1))
#include <vdso/page.h>
#endif /* __ASM_PAGE_DEF_H */
+1 -8
View File
@@ -5,13 +5,6 @@
#ifndef __ASM_VDSO_H
#define __ASM_VDSO_H
/*
* Default link address for the vDSO.
* Since we randomise the VDSO mapping, there's little point in trying
* to prelink this.
*/
#define VDSO_LBASE 0x0
#define __VVAR_PAGES 2
#ifndef __ASSEMBLY__
@@ -20,7 +13,7 @@
#define VDSO_SYMBOL(base, name) \
({ \
(void *)(vdso_offset_##name - VDSO_LBASE + (unsigned long)(base)); \
(void *)(vdso_offset_##name + (unsigned long)(base)); \
})
extern char vdso_start[], vdso_end[];
+1 -2
View File
@@ -6,7 +6,6 @@
#ifndef __ASSEMBLY__
#include <linux/timekeeper_internal.h>
#include <vdso/datapage.h>
enum vvar_pages {
@@ -37,7 +36,7 @@ struct vdso_rng_data *__arm64_get_k_vdso_rnd_data(void)
#define __arch_get_k_vdso_rng_data __arm64_get_k_vdso_rnd_data
static __always_inline
void __arm64_update_vsyscall(struct vdso_data *vdata, struct timekeeper *tk)
void __arm64_update_vsyscall(struct vdso_data *vdata)
{
vdata[CS_HRES_COARSE].mask = VDSO_PRECISION_MASK;
vdata[CS_RAW].mask = VDSO_PRECISION_MASK;
+13 -31
View File
@@ -19,7 +19,6 @@
#include <linux/signal.h>
#include <linux/slab.h>
#include <linux/time_namespace.h>
#include <linux/timekeeper_internal.h>
#include <linux/vmalloc.h>
#include <vdso/datapage.h>
#include <vdso/helpers.h>
@@ -39,8 +38,6 @@ struct vdso_abi_info {
const char *vdso_code_start;
const char *vdso_code_end;
unsigned long vdso_pages;
/* Data Mapping */
struct vm_special_mapping *dm;
/* Code Mapping */
struct vm_special_mapping *cm;
};
@@ -113,6 +110,8 @@ struct vdso_data *arch_get_vdso_data(void *vvar_page)
return (struct vdso_data *)(vvar_page);
}
static const struct vm_special_mapping vvar_map;
/*
* The vvar mapping contains data for a specific time namespace, so when a task
* changes namespace we must unmap its vvar data for the old namespace.
@@ -129,12 +128,8 @@ int vdso_join_timens(struct task_struct *task, struct time_namespace *ns)
mmap_read_lock(mm);
for_each_vma(vmi, vma) {
if (vma_is_special_mapping(vma, vdso_info[VDSO_ABI_AA64].dm))
if (vma_is_special_mapping(vma, &vvar_map))
zap_vma_pages(vma);
#ifdef CONFIG_COMPAT_VDSO
if (vma_is_special_mapping(vma, vdso_info[VDSO_ABI_AA32].dm))
zap_vma_pages(vma);
#endif
}
mmap_read_unlock(mm);
@@ -176,6 +171,11 @@ static vm_fault_t vvar_fault(const struct vm_special_mapping *sm,
return vmf_insert_pfn(vma, vmf->address, pfn);
}
static const struct vm_special_mapping vvar_map = {
.name = "[vvar]",
.fault = vvar_fault,
};
static int __setup_additional_pages(enum vdso_abi abi,
struct mm_struct *mm,
struct linux_binprm *bprm,
@@ -199,7 +199,7 @@ static int __setup_additional_pages(enum vdso_abi abi,
ret = _install_special_mapping(mm, vdso_base, VVAR_NR_PAGES * PAGE_SIZE,
VM_READ|VM_MAYREAD|VM_PFNMAP,
vdso_info[abi].dm);
&vvar_map);
if (IS_ERR(ret))
goto up_fail;
@@ -229,7 +229,6 @@ up_fail:
enum aarch32_map {
AA32_MAP_VECTORS, /* kuser helpers */
AA32_MAP_SIGPAGE,
AA32_MAP_VVAR,
AA32_MAP_VDSO,
};
@@ -254,10 +253,6 @@ static struct vm_special_mapping aarch32_vdso_maps[] = {
.pages = &aarch32_sig_page,
.mremap = aarch32_sigpage_mremap,
},
[AA32_MAP_VVAR] = {
.name = "[vvar]",
.fault = vvar_fault,
},
[AA32_MAP_VDSO] = {
.name = "[vdso]",
.mremap = vdso_mremap,
@@ -307,7 +302,6 @@ static int __init __aarch32_alloc_vdso_pages(void)
if (!IS_ENABLED(CONFIG_COMPAT_VDSO))
return 0;
vdso_info[VDSO_ABI_AA32].dm = &aarch32_vdso_maps[AA32_MAP_VVAR];
vdso_info[VDSO_ABI_AA32].cm = &aarch32_vdso_maps[AA32_MAP_VDSO];
return __vdso_init(VDSO_ABI_AA32);
@@ -402,26 +396,14 @@ out:
}
#endif /* CONFIG_COMPAT */
enum aarch64_map {
AA64_MAP_VVAR,
AA64_MAP_VDSO,
};
static struct vm_special_mapping aarch64_vdso_maps[] __ro_after_init = {
[AA64_MAP_VVAR] = {
.name = "[vvar]",
.fault = vvar_fault,
},
[AA64_MAP_VDSO] = {
.name = "[vdso]",
.mremap = vdso_mremap,
},
static struct vm_special_mapping aarch64_vdso_map __ro_after_init = {
.name = "[vdso]",
.mremap = vdso_mremap,
};
static int __init vdso_init(void)
{
vdso_info[VDSO_ABI_AA64].dm = &aarch64_vdso_maps[AA64_MAP_VVAR];
vdso_info[VDSO_ABI_AA64].cm = &aarch64_vdso_maps[AA64_MAP_VDSO];
vdso_info[VDSO_ABI_AA64].cm = &aarch64_vdso_map;
return __vdso_init(VDSO_ABI_AA64);
}
+1 -1
View File
@@ -25,7 +25,7 @@ SECTIONS
#ifdef CONFIG_TIME_NS
PROVIDE(_timens_data = _vdso_data + PAGE_SIZE);
#endif
. = VDSO_LBASE + SIZEOF_HEADERS;
. = SIZEOF_HEADERS;
.hash : { *(.hash) } :text
.gnu.hash : { *(.gnu.hash) }
+1 -1
View File
@@ -22,7 +22,7 @@ SECTIONS
#ifdef CONFIG_TIME_NS
PROVIDE_HIDDEN(_timens_data = _vdso_data + PAGE_SIZE);
#endif
. = VDSO_LBASE + SIZEOF_HEADERS;
. = SIZEOF_HEADERS;
.hash : { *(.hash) } :text
.gnu.hash : { *(.gnu.hash) }
-4
View File
@@ -64,9 +64,6 @@ config CSKY
select GENERIC_IRQ_MULTI_HANDLER
select GENERIC_SCHED_CLOCK
select GENERIC_SMP_IDLE_THREAD
select GENERIC_TIME_VSYSCALL
select GENERIC_VDSO_32
select GENERIC_GETTIMEOFDAY
select GX6605S_TIMER if CPU_CK610
select HAVE_ARCH_TRACEHOOK
select HAVE_ARCH_AUDITSYSCALL
@@ -80,7 +77,6 @@ config CSKY
select HAVE_DEBUG_KMEMLEAK
select HAVE_DYNAMIC_FTRACE
select HAVE_DYNAMIC_FTRACE_WITH_REGS
select HAVE_GENERIC_VDSO
select HAVE_FUNCTION_TRACER
select HAVE_FUNCTION_GRAPH_TRACER
select HAVE_FUNCTION_ERROR_INJECTION
+2 -6
View File
@@ -7,12 +7,8 @@
#include <asm/cache.h>
#include <linux/const.h>
/*
* PAGE_SHIFT determines the page size: 4KB
*/
#define PAGE_SHIFT CONFIG_PAGE_SHIFT
#define PAGE_SIZE (_AC(1, UL) << PAGE_SHIFT)
#define PAGE_MASK (~(PAGE_SIZE - 1))
#include <vdso/page.h>
#define THREAD_SIZE (PAGE_SIZE * 2)
#define THREAD_MASK (~(THREAD_SIZE - 1))
#define THREAD_SHIFT (PAGE_SHIFT + 1)
-9
View File
@@ -1,9 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __ASM_VDSO_CSKY_CLOCKSOURCE_H
#define __ASM_VDSO_CSKY_CLOCKSOURCE_H
#define VDSO_ARCH_CLOCKMODES \
VDSO_CLOCKMODE_ARCHTIMER
#endif /* __ASM_VDSO_CSKY_CLOCKSOURCE_H */
-114
View File
@@ -1,114 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __ASM_VDSO_CSKY_GETTIMEOFDAY_H
#define __ASM_VDSO_CSKY_GETTIMEOFDAY_H
#ifndef __ASSEMBLY__
#include <asm/barrier.h>
#include <asm/unistd.h>
#include <abi/regdef.h>
#include <uapi/linux/time.h>
#define VDSO_HAS_CLOCK_GETRES 1
static __always_inline
int gettimeofday_fallback(struct __kernel_old_timeval *_tv,
struct timezone *_tz)
{
register struct __kernel_old_timeval *tv asm("a0") = _tv;
register struct timezone *tz asm("a1") = _tz;
register long ret asm("a0");
register long nr asm(syscallid) = __NR_gettimeofday;
asm volatile ("trap 0\n"
: "=r" (ret)
: "r"(tv), "r"(tz), "r"(nr)
: "memory");
return ret;
}
static __always_inline
long clock_gettime_fallback(clockid_t _clkid, struct __kernel_timespec *_ts)
{
register clockid_t clkid asm("a0") = _clkid;
register struct __kernel_timespec *ts asm("a1") = _ts;
register long ret asm("a0");
register long nr asm(syscallid) = __NR_clock_gettime64;
asm volatile ("trap 0\n"
: "=r" (ret)
: "r"(clkid), "r"(ts), "r"(nr)
: "memory");
return ret;
}
static __always_inline
long clock_gettime32_fallback(clockid_t _clkid, struct old_timespec32 *_ts)
{
register clockid_t clkid asm("a0") = _clkid;
register struct old_timespec32 *ts asm("a1") = _ts;
register long ret asm("a0");
register long nr asm(syscallid) = __NR_clock_gettime;
asm volatile ("trap 0\n"
: "=r" (ret)
: "r"(clkid), "r"(ts), "r"(nr)
: "memory");
return ret;
}
static __always_inline
int clock_getres_fallback(clockid_t _clkid, struct __kernel_timespec *_ts)
{
register clockid_t clkid asm("a0") = _clkid;
register struct __kernel_timespec *ts asm("a1") = _ts;
register long ret asm("a0");
register long nr asm(syscallid) = __NR_clock_getres_time64;
asm volatile ("trap 0\n"
: "=r" (ret)
: "r"(clkid), "r"(ts), "r"(nr)
: "memory");
return ret;
}
static __always_inline
int clock_getres32_fallback(clockid_t _clkid, struct old_timespec32 *_ts)
{
register clockid_t clkid asm("a0") = _clkid;
register struct old_timespec32 *ts asm("a1") = _ts;
register long ret asm("a0");
register long nr asm(syscallid) = __NR_clock_getres;
asm volatile ("trap 0\n"
: "=r" (ret)
: "r"(clkid), "r"(ts), "r"(nr)
: "memory");
return ret;
}
uint64_t csky_pmu_read_cc(void);
static __always_inline u64 __arch_get_hw_counter(s32 clock_mode,
const struct vdso_data *vd)
{
#ifdef CONFIG_CSKY_PMU_V1
return csky_pmu_read_cc();
#else
return 0;
#endif
}
static __always_inline const struct vdso_data *__arch_get_vdso_data(void)
{
return _vdso_data;
}
#endif /* !__ASSEMBLY__ */
#endif /* __ASM_VDSO_CSKY_GETTIMEOFDAY_H */

Some files were not shown because too many files have changed in this diff Show More