Commit 64b302ab authored by Dmitry Safonov's avatar Dmitry Safonov Committed by Thomas Gleixner

x86/vdso: Provide vdso_data offset on vvar_page

VDSO support for time namespaces needs to set up a page with the same
layout as VVAR. That timens page will be placed on position of VVAR page
inside namespace. That page has vdso_data->seq set to 1 to enforce
the slow path and vdso_data->clock_mode set to VCLOCK_TIMENS to enforce
the time namespace handling path.

To prepare the time namespace page the kernel needs to know the vdso_data
offset.  Provide arch_get_vdso_data() helper for locating vdso_data on VVAR
page.
Co-developed-by: default avatarAndrei Vagin <avagin@openvz.org>
Signed-off-by: default avatarAndrei Vagin <avagin@openvz.org>
Signed-off-by: default avatarDmitry Safonov <dima@arista.com>
Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
Link: https://lore.kernel.org/r/20191112012724.250792-22-dima@arista.com
parent 660fd04f
...@@ -21,9 +21,7 @@ SECTIONS ...@@ -21,9 +21,7 @@ SECTIONS
/* Place all vvars at the offsets in asm/vvar.h. */ /* Place all vvars at the offsets in asm/vvar.h. */
#define EMIT_VVAR(name, offset) vvar_ ## name = vvar_page + offset; #define EMIT_VVAR(name, offset) vvar_ ## name = vvar_page + offset;
#define __VVAR_KERNEL_LDS
#include <asm/vvar.h> #include <asm/vvar.h>
#undef __VVAR_KERNEL_LDS
#undef EMIT_VVAR #undef EMIT_VVAR
pvclock_page = vvar_start + PAGE_SIZE; pvclock_page = vvar_start + PAGE_SIZE;
......
...@@ -24,6 +24,17 @@ ...@@ -24,6 +24,17 @@
#include <asm/cpufeature.h> #include <asm/cpufeature.h>
#include <clocksource/hyperv_timer.h> #include <clocksource/hyperv_timer.h>
#undef _ASM_X86_VVAR_H
#define EMIT_VVAR(name, offset) \
const size_t name ## _offset = offset;
#include <asm/vvar.h>
struct vdso_data *arch_get_vdso_data(void *vvar_page)
{
return (struct vdso_data *)(vvar_page + _vdso_data_offset);
}
#undef EMIT_VVAR
#if defined(CONFIG_X86_64) #if defined(CONFIG_X86_64)
unsigned int __read_mostly vdso64_enabled = 1; unsigned int __read_mostly vdso64_enabled = 1;
#endif #endif
......
...@@ -19,10 +19,10 @@ ...@@ -19,10 +19,10 @@
#ifndef _ASM_X86_VVAR_H #ifndef _ASM_X86_VVAR_H
#define _ASM_X86_VVAR_H #define _ASM_X86_VVAR_H
#if defined(__VVAR_KERNEL_LDS) #ifdef EMIT_VVAR
/*
/* The kernel linker script defines its own magic to put vvars in the * EMIT_VVAR() is used by the kernel linker script to put vvars in the
* right place. * right place. Also, it's used by kernel code to import offsets values.
*/ */
#define DECLARE_VVAR(offset, type, name) \ #define DECLARE_VVAR(offset, type, name) \
EMIT_VVAR(name, offset) EMIT_VVAR(name, offset)
......
...@@ -196,9 +196,7 @@ SECTIONS ...@@ -196,9 +196,7 @@ SECTIONS
#define EMIT_VVAR(name, offset) \ #define EMIT_VVAR(name, offset) \
. = __vvar_beginning_hack + offset; \ . = __vvar_beginning_hack + offset; \
*(.vvar_ ## name) *(.vvar_ ## name)
#define __VVAR_KERNEL_LDS
#include <asm/vvar.h> #include <asm/vvar.h>
#undef __VVAR_KERNEL_LDS
#undef EMIT_VVAR #undef EMIT_VVAR
/* /*
......
...@@ -39,6 +39,7 @@ struct time_namespace *copy_time_ns(unsigned long flags, ...@@ -39,6 +39,7 @@ struct time_namespace *copy_time_ns(unsigned long flags,
struct time_namespace *old_ns); struct time_namespace *old_ns);
void free_time_ns(struct kref *kref); void free_time_ns(struct kref *kref);
int timens_on_fork(struct nsproxy *nsproxy, struct task_struct *tsk); int timens_on_fork(struct nsproxy *nsproxy, struct task_struct *tsk);
struct vdso_data *arch_get_vdso_data(void *vvar_page);
static inline void put_time_ns(struct time_namespace *ns) static inline void put_time_ns(struct time_namespace *ns)
{ {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment