Skip to content

Commit

Permalink
vdso/treewide: Add vdso_data pointer argument to __arch_get_hw_counter()
Browse files Browse the repository at this point in the history
MIPS already uses and S390 will need the vdso data pointer in
__arch_get_hw_counter().

This works nicely as long as the architecture does not support time
namespaces in the VDSO. With time namespaces enabled the regular
accessor to the vdso data pointer __arch_get_vdso_data() will return the
namespace specific VDSO data page for tasks which are part of a
non-root time namespace. This would cause the architectures which need
the vdso data pointer in __arch_get_hw_counter() to access the wrong
vdso data page.

Add a vdso_data pointer argument to __arch_get_hw_counter() and hand it in
from the call sites in the core code. For architectures which do not need
the data pointer in their counter accessor function the compiler will just
optimize it out.

Fix up all existing architecture implementations and make MIPS utilize the
pointer instead of invoking the accessor function.

No functional change and no change in the resulting object code (except
MIPS).

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Link: https://lkml.kernel.org/r/draft-87wo2ekuzn.fsf@nanos.tec.linutronix.de
  • Loading branch information
Thomas Gleixner committed Aug 6, 2020
1 parent 2324d50 commit 4c5a116
Show file tree
Hide file tree
Showing 7 changed files with 15 additions and 9 deletions.
3 changes: 2 additions & 1 deletion arch/arm/include/asm/vdso/gettimeofday.h
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,8 @@ static inline bool arm_vdso_hres_capable(void)
}
#define __arch_vdso_hres_capable arm_vdso_hres_capable

static __always_inline u64 __arch_get_hw_counter(int clock_mode)
static __always_inline u64 __arch_get_hw_counter(int clock_mode,
const struct vdso_data *vd)
{
#ifdef CONFIG_ARM_ARCH_TIMER
u64 cycle_now;
Expand Down
3 changes: 2 additions & 1 deletion arch/arm64/include/asm/vdso/compat_gettimeofday.h
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,8 @@ int clock_getres32_fallback(clockid_t _clkid, struct old_timespec32 *_ts)
return ret;
}

static __always_inline u64 __arch_get_hw_counter(s32 clock_mode)
static __always_inline u64 __arch_get_hw_counter(s32 clock_mode,
const struct vdso_data *vd)
{
u64 res;

Expand Down
3 changes: 2 additions & 1 deletion arch/arm64/include/asm/vdso/gettimeofday.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,8 @@ int clock_getres_fallback(clockid_t _clkid, struct __kernel_timespec *_ts)
return ret;
}

static __always_inline u64 __arch_get_hw_counter(s32 clock_mode)
static __always_inline u64 __arch_get_hw_counter(s32 clock_mode,
const struct vdso_data *vd)
{
u64 res;

Expand Down
5 changes: 3 additions & 2 deletions arch/mips/include/asm/vdso/gettimeofday.h
Original file line number Diff line number Diff line change
Expand Up @@ -167,15 +167,16 @@ static __always_inline u64 read_gic_count(const struct vdso_data *data)

#endif

static __always_inline u64 __arch_get_hw_counter(s32 clock_mode)
static __always_inline u64 __arch_get_hw_counter(s32 clock_mode,
const struct vdso_data *vd)
{
#ifdef CONFIG_CSRC_R4K
if (clock_mode == VDSO_CLOCKMODE_R4K)
return read_r4k_count();
#endif
#ifdef CONFIG_CLKSRC_MIPS_GIC
if (clock_mode == VDSO_CLOCKMODE_GIC)
return read_gic_count(get_vdso_data());
return read_gic_count(vd);
#endif
/*
* Core checks mode already. So this raced against a concurrent
Expand Down
3 changes: 2 additions & 1 deletion arch/riscv/include/asm/vdso/gettimeofday.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,8 @@ int clock_getres_fallback(clockid_t _clkid, struct __kernel_timespec *_ts)
return ret;
}

static __always_inline u64 __arch_get_hw_counter(s32 clock_mode)
static __always_inline u64 __arch_get_hw_counter(s32 clock_mode,
const struct vdso_data *vd)
{
/*
* The purpose of csr_read(CSR_TIME) is to trap the system into
Expand Down
3 changes: 2 additions & 1 deletion arch/x86/include/asm/vdso/gettimeofday.h
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,8 @@ static u64 vread_hvclock(void)
}
#endif

static inline u64 __arch_get_hw_counter(s32 clock_mode)
static inline u64 __arch_get_hw_counter(s32 clock_mode,
const struct vdso_data *vd)
{
if (likely(clock_mode == VDSO_CLOCKMODE_TSC))
return (u64)rdtsc_ordered();
Expand Down
4 changes: 2 additions & 2 deletions lib/vdso/gettimeofday.c
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ static int do_hres_timens(const struct vdso_data *vdns, clockid_t clk,
if (unlikely(!vdso_clocksource_ok(vd)))
return -1;

cycles = __arch_get_hw_counter(vd->clock_mode);
cycles = __arch_get_hw_counter(vd->clock_mode, vd);
if (unlikely(!vdso_cycles_ok(cycles)))
return -1;
ns = vdso_ts->nsec;
Expand Down Expand Up @@ -138,7 +138,7 @@ static __always_inline int do_hres(const struct vdso_data *vd, clockid_t clk,
if (unlikely(!vdso_clocksource_ok(vd)))
return -1;

cycles = __arch_get_hw_counter(vd->clock_mode);
cycles = __arch_get_hw_counter(vd->clock_mode, vd);
if (unlikely(!vdso_cycles_ok(cycles)))
return -1;
ns = vdso_ts->nsec;
Expand Down

0 comments on commit 4c5a116

Please sign in to comment.