summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVincenzo Frascino <vincenzo.frascino@arm.com>2019-06-21 05:52:46 -0400
committerPaul Burton <paul.burton@mips.com>2019-07-26 00:45:05 -0400
commit24640f233b466051ad3a5d2786d2951e43026c9d (patch)
treeca9acaf821110f4d249dd4a250d7a9b740675261
parentc2aeaaea175652af6610f97a0de6d7cd07311e18 (diff)
mips: Add support for generic vDSO
The mips vDSO library requires some adaptations to take advantage of the newly introduced generic vDSO library. Introduce the following changes: - Modification of vdso.c to be compliant with the common vdso datapage - Use of lib/vdso for gettimeofday Cc: Ralf Baechle <ralf@linux-mips.org> Cc: Paul Burton <paul.burton@mips.com> Signed-off-by: Vincenzo Frascino <vincenzo.frascino@arm.com> [paul.burton@mips.com: Prepend $(src) to config-n32-o32-env.c path.] Signed-off-by: Paul Burton <paul.burton@mips.com>
-rw-r--r--arch/mips/Kconfig2
-rw-r--r--arch/mips/include/asm/vdso.h78
-rw-r--r--arch/mips/include/asm/vdso/gettimeofday.h151
-rw-r--r--arch/mips/include/asm/vdso/vdso.h (renamed from arch/mips/vdso/vdso.h)6
-rw-r--r--arch/mips/include/asm/vdso/vsyscall.h43
-rw-r--r--arch/mips/kernel/vdso.c37
-rw-r--r--arch/mips/vdso/Makefile33
-rw-r--r--arch/mips/vdso/config-n32-o32-env.c17
-rw-r--r--arch/mips/vdso/elf.S2
-rw-r--r--arch/mips/vdso/sigreturn.S2
-rw-r--r--arch/mips/vdso/vgettimeofday.c40
11 files changed, 296 insertions, 115 deletions
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 947c75684897..99078c1b5273 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -22,6 +22,7 @@ config MIPS
22 select GENERIC_CLOCKEVENTS 22 select GENERIC_CLOCKEVENTS
23 select GENERIC_CMOS_UPDATE 23 select GENERIC_CMOS_UPDATE
24 select GENERIC_CPU_AUTOPROBE 24 select GENERIC_CPU_AUTOPROBE
25 select GENERIC_GETTIMEOFDAY
25 select GENERIC_IOMAP 26 select GENERIC_IOMAP
26 select GENERIC_IRQ_PROBE 27 select GENERIC_IRQ_PROBE
27 select GENERIC_IRQ_SHOW 28 select GENERIC_IRQ_SHOW
@@ -74,6 +75,7 @@ config MIPS
74 select HAVE_STACKPROTECTOR 75 select HAVE_STACKPROTECTOR
75 select HAVE_SYSCALL_TRACEPOINTS 76 select HAVE_SYSCALL_TRACEPOINTS
76 select HAVE_VIRT_CPU_ACCOUNTING_GEN if 64BIT || !SMP 77 select HAVE_VIRT_CPU_ACCOUNTING_GEN if 64BIT || !SMP
78 select HAVE_GENERIC_VDSO
77 select IRQ_FORCED_THREADING 79 select IRQ_FORCED_THREADING
78 select ISA if EISA 80 select ISA if EISA
79 select MODULES_USE_ELF_RELA if MODULES && 64BIT 81 select MODULES_USE_ELF_RELA if MODULES && 64BIT
diff --git a/arch/mips/include/asm/vdso.h b/arch/mips/include/asm/vdso.h
index a013fa4a3682..cc7b516129a8 100644
--- a/arch/mips/include/asm/vdso.h
+++ b/arch/mips/include/asm/vdso.h
@@ -8,6 +8,7 @@
8#define __ASM_VDSO_H 8#define __ASM_VDSO_H
9 9
10#include <linux/mm_types.h> 10#include <linux/mm_types.h>
11#include <vdso/datapage.h>
11 12
12#include <asm/barrier.h> 13#include <asm/barrier.h>
13 14
@@ -49,84 +50,9 @@ extern struct mips_vdso_image vdso_image_o32;
49extern struct mips_vdso_image vdso_image_n32; 50extern struct mips_vdso_image vdso_image_n32;
50#endif 51#endif
51 52
52/**
53 * union mips_vdso_data - Data provided by the kernel for the VDSO.
54 * @xtime_sec: Current real time (seconds part).
55 * @xtime_nsec: Current real time (nanoseconds part, shifted).
56 * @wall_to_mono_sec: Wall-to-monotonic offset (seconds part).
57 * @wall_to_mono_nsec: Wall-to-monotonic offset (nanoseconds part).
58 * @seq_count: Counter to synchronise updates (odd = updating).
59 * @cs_shift: Clocksource shift value.
60 * @clock_mode: Clocksource to use for time functions.
61 * @cs_mult: Clocksource multiplier value.
62 * @cs_cycle_last: Clock cycle value at last update.
63 * @cs_mask: Clocksource mask value.
64 * @tz_minuteswest: Minutes west of Greenwich (from timezone).
65 * @tz_dsttime: Type of DST correction (from timezone).
66 *
67 * This structure contains data needed by functions within the VDSO. It is
68 * populated by the kernel and mapped read-only into user memory. The time
69 * fields are mirrors of internal data from the timekeeping infrastructure.
70 *
71 * Note: Care should be taken when modifying as the layout must remain the same
72 * for both 64- and 32-bit (for 32-bit userland on 64-bit kernel).
73 */
74union mips_vdso_data { 53union mips_vdso_data {
75 struct { 54 struct vdso_data data[CS_BASES];
76 u64 xtime_sec;
77 u64 xtime_nsec;
78 u64 wall_to_mono_sec;
79 u64 wall_to_mono_nsec;
80 u32 seq_count;
81 u32 cs_shift;
82 u8 clock_mode;
83 u32 cs_mult;
84 u64 cs_cycle_last;
85 u64 cs_mask;
86 s32 tz_minuteswest;
87 s32 tz_dsttime;
88 };
89
90 u8 page[PAGE_SIZE]; 55 u8 page[PAGE_SIZE];
91}; 56};
92 57
93static inline u32 vdso_data_read_begin(const union mips_vdso_data *data)
94{
95 u32 seq;
96
97 while (true) {
98 seq = READ_ONCE(data->seq_count);
99 if (likely(!(seq & 1))) {
100 /* Paired with smp_wmb() in vdso_data_write_*(). */
101 smp_rmb();
102 return seq;
103 }
104
105 cpu_relax();
106 }
107}
108
109static inline bool vdso_data_read_retry(const union mips_vdso_data *data,
110 u32 start_seq)
111{
112 /* Paired with smp_wmb() in vdso_data_write_*(). */
113 smp_rmb();
114 return unlikely(data->seq_count != start_seq);
115}
116
117static inline void vdso_data_write_begin(union mips_vdso_data *data)
118{
119 ++data->seq_count;
120
121 /* Ensure sequence update is written before other data page values. */
122 smp_wmb();
123}
124
125static inline void vdso_data_write_end(union mips_vdso_data *data)
126{
127 /* Ensure data values are written before updating sequence again. */
128 smp_wmb();
129 ++data->seq_count;
130}
131
132#endif /* __ASM_VDSO_H */ 58#endif /* __ASM_VDSO_H */
diff --git a/arch/mips/include/asm/vdso/gettimeofday.h b/arch/mips/include/asm/vdso/gettimeofday.h
new file mode 100644
index 000000000000..aa20865b288b
--- /dev/null
+++ b/arch/mips/include/asm/vdso/gettimeofday.h
@@ -0,0 +1,151 @@
1/*
2 * Copyright (C) 2018 ARM Limited
3 * Copyright (C) 2015 Imagination Technologies
4 * Author: Alex Smith <alex.smith@imgtec.com>
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version.
10 */
11#ifndef __ASM_VDSO_GETTIMEOFDAY_H
12#define __ASM_VDSO_GETTIMEOFDAY_H
13
14#ifndef __ASSEMBLY__
15
16#include <linux/compiler.h>
17#include <linux/time.h>
18
19#include <asm/vdso/vdso.h>
20#include <asm/clocksource.h>
21#include <asm/io.h>
22#include <asm/unistd.h>
23#include <asm/vdso.h>
24
25#ifdef CONFIG_MIPS_CLOCK_VSYSCALL
26
27static __always_inline long gettimeofday_fallback(
28 struct __kernel_old_timeval *_tv,
29 struct timezone *_tz)
30{
31 register struct timezone *tz asm("a1") = _tz;
32 register struct __kernel_old_timeval *tv asm("a0") = _tv;
33 register long ret asm("v0");
34 register long nr asm("v0") = __NR_gettimeofday;
35 register long error asm("a3");
36
37 asm volatile(
38 " syscall\n"
39 : "=r" (ret), "=r" (error)
40 : "r" (tv), "r" (tz), "r" (nr)
41 : "$1", "$3", "$8", "$9", "$10", "$11", "$12", "$13",
42 "$14", "$15", "$24", "$25", "hi", "lo", "memory");
43
44 return error ? -ret : ret;
45}
46
47#else
48
49static __always_inline long gettimeofday_fallback(
50 struct __kernel_old_timeval *_tv,
51 struct timezone *_tz)
52{
53 return -1;
54}
55
56#endif
57
58static __always_inline long clock_gettime_fallback(
59 clockid_t _clkid,
60 struct __kernel_timespec *_ts)
61{
62 register struct __kernel_timespec *ts asm("a1") = _ts;
63 register clockid_t clkid asm("a0") = _clkid;
64 register long ret asm("v0");
65#if _MIPS_SIM == _MIPS_SIM_ABI64
66 register long nr asm("v0") = __NR_clock_gettime;
67#else
68 register long nr asm("v0") = __NR_clock_gettime64;
69#endif
70 register long error asm("a3");
71
72 asm volatile(
73 " syscall\n"
74 : "=r" (ret), "=r" (error)
75 : "r" (clkid), "r" (ts), "r" (nr)
76 : "$1", "$3", "$8", "$9", "$10", "$11", "$12", "$13",
77 "$14", "$15", "$24", "$25", "hi", "lo", "memory");
78
79 return error ? -ret : ret;
80}
81
82#ifdef CONFIG_CSRC_R4K
83
84static __always_inline u64 read_r4k_count(void)
85{
86 unsigned int count;
87
88 __asm__ __volatile__(
89 " .set push\n"
90 " .set mips32r2\n"
91 " rdhwr %0, $2\n"
92 " .set pop\n"
93 : "=r" (count));
94
95 return count;
96}
97
98#endif
99
100#ifdef CONFIG_CLKSRC_MIPS_GIC
101
102static __always_inline u64 read_gic_count(const struct vdso_data *data)
103{
104 void __iomem *gic = get_gic(data);
105 u32 hi, hi2, lo;
106
107 do {
108 hi = __raw_readl(gic + sizeof(lo));
109 lo = __raw_readl(gic);
110 hi2 = __raw_readl(gic + sizeof(lo));
111 } while (hi2 != hi);
112
113 return (((u64)hi) << 32) + lo;
114}
115
116#endif
117
118static __always_inline u64 __arch_get_hw_counter(s32 clock_mode)
119{
120#ifdef CONFIG_CLKSRC_MIPS_GIC
121 const struct vdso_data *data = get_vdso_data();
122#endif
123 u64 cycle_now;
124
125 switch (clock_mode) {
126#ifdef CONFIG_CSRC_R4K
127 case VDSO_CLOCK_R4K:
128 cycle_now = read_r4k_count();
129 break;
130#endif
131#ifdef CONFIG_CLKSRC_MIPS_GIC
132 case VDSO_CLOCK_GIC:
133 cycle_now = read_gic_count(data);
134 break;
135#endif
136 default:
137 cycle_now = 0;
138 break;
139 }
140
141 return cycle_now;
142}
143
144static __always_inline const struct vdso_data *__arch_get_vdso_data(void)
145{
146 return get_vdso_data();
147}
148
149#endif /* !__ASSEMBLY__ */
150
151#endif /* __ASM_VDSO_GETTIMEOFDAY_H */
diff --git a/arch/mips/vdso/vdso.h b/arch/mips/include/asm/vdso/vdso.h
index 14b1931be69c..526695bc65ee 100644
--- a/arch/mips/vdso/vdso.h
+++ b/arch/mips/include/asm/vdso/vdso.h
@@ -68,14 +68,14 @@ static inline unsigned long get_vdso_base(void)
68 return addr; 68 return addr;
69} 69}
70 70
71static inline const union mips_vdso_data *get_vdso_data(void) 71static inline const struct vdso_data *get_vdso_data(void)
72{ 72{
73 return (const union mips_vdso_data *)(get_vdso_base() - PAGE_SIZE); 73 return (const struct vdso_data *)(get_vdso_base() - PAGE_SIZE);
74} 74}
75 75
76#ifdef CONFIG_CLKSRC_MIPS_GIC 76#ifdef CONFIG_CLKSRC_MIPS_GIC
77 77
78static inline void __iomem *get_gic(const union mips_vdso_data *data) 78static inline void __iomem *get_gic(const struct vdso_data *data)
79{ 79{
80 return (void __iomem *)data - PAGE_SIZE; 80 return (void __iomem *)data - PAGE_SIZE;
81} 81}
diff --git a/arch/mips/include/asm/vdso/vsyscall.h b/arch/mips/include/asm/vdso/vsyscall.h
new file mode 100644
index 000000000000..195314732233
--- /dev/null
+++ b/arch/mips/include/asm/vdso/vsyscall.h
@@ -0,0 +1,43 @@
1/* SPDX-License-Identifier: GPL-2.0 */
2#ifndef __ASM_VDSO_VSYSCALL_H
3#define __ASM_VDSO_VSYSCALL_H
4
5#ifndef __ASSEMBLY__
6
7#include <linux/timekeeper_internal.h>
8#include <vdso/datapage.h>
9
10extern struct vdso_data *vdso_data;
11
12/*
13 * Update the vDSO data page to keep in sync with kernel timekeeping.
14 */
15static __always_inline
16struct vdso_data *__mips_get_k_vdso_data(void)
17{
18 return vdso_data;
19}
20#define __arch_get_k_vdso_data __mips_get_k_vdso_data
21
22static __always_inline
23int __mips_get_clock_mode(struct timekeeper *tk)
24{
25 u32 clock_mode = tk->tkr_mono.clock->archdata.vdso_clock_mode;
26
27 return clock_mode;
28}
29#define __arch_get_clock_mode __mips_get_clock_mode
30
31static __always_inline
32int __mips_use_vsyscall(struct vdso_data *vdata)
33{
34 return (vdata[CS_HRES_COARSE].clock_mode != VDSO_CLOCK_NONE);
35}
36#define __arch_use_vsyscall __mips_use_vsyscall
37
38/* The asm-generic header needs to be included after the definitions above */
39#include <asm-generic/vdso/vsyscall.h>
40
41#endif /* !__ASSEMBLY__ */
42
43#endif /* __ASM_VDSO_VSYSCALL_H */
diff --git a/arch/mips/kernel/vdso.c b/arch/mips/kernel/vdso.c
index 3a372686ffca..bc35f8499111 100644
--- a/arch/mips/kernel/vdso.c
+++ b/arch/mips/kernel/vdso.c
@@ -20,9 +20,12 @@
20#include <asm/mips-cps.h> 20#include <asm/mips-cps.h>
21#include <asm/page.h> 21#include <asm/page.h>
22#include <asm/vdso.h> 22#include <asm/vdso.h>
23#include <vdso/helpers.h>
24#include <vdso/vsyscall.h>
23 25
24/* Kernel-provided data used by the VDSO. */ 26/* Kernel-provided data used by the VDSO. */
25static union mips_vdso_data vdso_data __page_aligned_data; 27static union mips_vdso_data mips_vdso_data __page_aligned_data;
28struct vdso_data *vdso_data = mips_vdso_data.data;
26 29
27/* 30/*
28 * Mapping for the VDSO data/GIC pages. The real pages are mapped manually, as 31 * Mapping for the VDSO data/GIC pages. The real pages are mapped manually, as
@@ -66,34 +69,6 @@ static int __init init_vdso(void)
66} 69}
67subsys_initcall(init_vdso); 70subsys_initcall(init_vdso);
68 71
69void update_vsyscall(struct timekeeper *tk)
70{
71 vdso_data_write_begin(&vdso_data);
72
73 vdso_data.xtime_sec = tk->xtime_sec;
74 vdso_data.xtime_nsec = tk->tkr_mono.xtime_nsec;
75 vdso_data.wall_to_mono_sec = tk->wall_to_monotonic.tv_sec;
76 vdso_data.wall_to_mono_nsec = tk->wall_to_monotonic.tv_nsec;
77 vdso_data.cs_shift = tk->tkr_mono.shift;
78
79 vdso_data.clock_mode = tk->tkr_mono.clock->archdata.vdso_clock_mode;
80 if (vdso_data.clock_mode != VDSO_CLOCK_NONE) {
81 vdso_data.cs_mult = tk->tkr_mono.mult;
82 vdso_data.cs_cycle_last = tk->tkr_mono.cycle_last;
83 vdso_data.cs_mask = tk->tkr_mono.mask;
84 }
85
86 vdso_data_write_end(&vdso_data);
87}
88
89void update_vsyscall_tz(void)
90{
91 if (vdso_data.clock_mode != VDSO_CLOCK_NONE) {
92 vdso_data.tz_minuteswest = sys_tz.tz_minuteswest;
93 vdso_data.tz_dsttime = sys_tz.tz_dsttime;
94 }
95}
96
97static unsigned long vdso_base(void) 72static unsigned long vdso_base(void)
98{ 73{
99 unsigned long base; 74 unsigned long base;
@@ -163,7 +138,7 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
163 */ 138 */
164 if (cpu_has_dc_aliases) { 139 if (cpu_has_dc_aliases) {
165 base = __ALIGN_MASK(base, shm_align_mask); 140 base = __ALIGN_MASK(base, shm_align_mask);
166 base += ((unsigned long)&vdso_data - gic_size) & shm_align_mask; 141 base += ((unsigned long)vdso_data - gic_size) & shm_align_mask;
167 } 142 }
168 143
169 data_addr = base + gic_size; 144 data_addr = base + gic_size;
@@ -189,7 +164,7 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
189 164
190 /* Map data page. */ 165 /* Map data page. */
191 ret = remap_pfn_range(vma, data_addr, 166 ret = remap_pfn_range(vma, data_addr,
192 virt_to_phys(&vdso_data) >> PAGE_SHIFT, 167 virt_to_phys(vdso_data) >> PAGE_SHIFT,
193 PAGE_SIZE, PAGE_READONLY); 168 PAGE_SIZE, PAGE_READONLY);
194 if (ret) 169 if (ret)
195 goto out; 170 goto out;
diff --git a/arch/mips/vdso/Makefile b/arch/mips/vdso/Makefile
index 7221df24cb23..de853c6aab28 100644
--- a/arch/mips/vdso/Makefile
+++ b/arch/mips/vdso/Makefile
@@ -1,6 +1,12 @@
1# SPDX-License-Identifier: GPL-2.0 1# SPDX-License-Identifier: GPL-2.0
2# Objects to go into the VDSO. 2# Objects to go into the VDSO.
3obj-vdso-y := elf.o gettimeofday.o sigreturn.o 3
4# Absolute relocation type $(ARCH_REL_TYPE_ABS) needs to be defined before
5# the inclusion of generic Makefile.
6ARCH_REL_TYPE_ABS := R_MIPS_JUMP_SLOT|R_MIPS_GLOB_DAT
7include $(srctree)/lib/vdso/Makefile
8
9obj-vdso-y := elf.o vgettimeofday.o sigreturn.o
4 10
5# Common compiler flags between ABIs. 11# Common compiler flags between ABIs.
6ccflags-vdso := \ 12ccflags-vdso := \
@@ -15,15 +21,31 @@ ifdef CONFIG_CC_IS_CLANG
15ccflags-vdso += $(filter --target=%,$(KBUILD_CFLAGS)) 21ccflags-vdso += $(filter --target=%,$(KBUILD_CFLAGS))
16endif 22endif
17 23
24#
25# The -fno-jump-tables flag only prevents the compiler from generating
26# jump tables but does not prevent the compiler from emitting absolute
27# offsets.
18cflags-vdso := $(ccflags-vdso) \ 28cflags-vdso := $(ccflags-vdso) \
19 $(filter -W%,$(filter-out -Wa$(comma)%,$(KBUILD_CFLAGS))) \ 29 $(filter -W%,$(filter-out -Wa$(comma)%,$(KBUILD_CFLAGS))) \
20 -O2 -g -fPIC -fno-strict-aliasing -fno-common -fno-builtin -G 0 \ 30 -O3 -g -fPIC -fno-strict-aliasing -fno-common -fno-builtin -G 0 \
21 -DDISABLE_BRANCH_PROFILING \ 31 -fno-stack-protector -fno-jump-tables -DDISABLE_BRANCH_PROFILING \
22 $(call cc-option, -fno-asynchronous-unwind-tables) \ 32 $(call cc-option, -fno-asynchronous-unwind-tables) \
23 $(call cc-option, -fno-stack-protector) 33 $(call cc-option, -fno-stack-protector)
24aflags-vdso := $(ccflags-vdso) \ 34aflags-vdso := $(ccflags-vdso) \
25 -D__ASSEMBLY__ -Wa,-gdwarf-2 35 -D__ASSEMBLY__ -Wa,-gdwarf-2
26 36
37ifneq ($(c-gettimeofday-y),)
38CFLAGS_vgettimeofday.o = -include $(c-gettimeofday-y)
39
40# config-n32-o32-env.c prepares the environment to build a 32bit vDSO
41# library on a 64bit kernel.
42# Note: Needs to be included before than the generic library.
43CFLAGS_vgettimeofday-o32.o = -include $(src)/config-n32-o32-env.c -include $(c-gettimeofday-y)
44CFLAGS_vgettimeofday-n32.o = -include $(src)/config-n32-o32-env.c -include $(c-gettimeofday-y)
45endif
46
47CFLAGS_REMOVE_vgettimeofday.o = -pg
48
27# 49#
28# For the pre-R6 code in arch/mips/vdso/vdso.h for locating 50# For the pre-R6 code in arch/mips/vdso/vdso.h for locating
29# the base address of VDSO, the linker will emit a R_MIPS_PC32 51# the base address of VDSO, the linker will emit a R_MIPS_PC32
@@ -48,6 +70,8 @@ VDSO_LDFLAGS := \
48 $(addprefix -Wl$(comma),$(filter -E%,$(KBUILD_CFLAGS))) \ 70 $(addprefix -Wl$(comma),$(filter -E%,$(KBUILD_CFLAGS))) \
49 -nostdlib -shared -Wl,--hash-style=sysv -Wl,--build-id 71 -nostdlib -shared -Wl,--hash-style=sysv -Wl,--build-id
50 72
73CFLAGS_REMOVE_vdso.o = -pg
74
51GCOV_PROFILE := n 75GCOV_PROFILE := n
52UBSAN_SANITIZE := n 76UBSAN_SANITIZE := n
53 77
@@ -96,6 +120,7 @@ $(obj)/vdso.lds: KBUILD_CPPFLAGS := $(ccflags-vdso) $(native-abi)
96 120
97$(obj)/vdso.so.dbg.raw: $(obj)/vdso.lds $(obj-vdso) FORCE 121$(obj)/vdso.so.dbg.raw: $(obj)/vdso.lds $(obj-vdso) FORCE
98 $(call if_changed,vdsold) 122 $(call if_changed,vdsold)
123 $(call if_changed,vdso_check)
99 124
100$(obj)/vdso-image.c: $(obj)/vdso.so.dbg.raw $(obj)/vdso.so.raw \ 125$(obj)/vdso-image.c: $(obj)/vdso.so.dbg.raw $(obj)/vdso.so.raw \
101 $(obj)/genvdso FORCE 126 $(obj)/genvdso FORCE
@@ -134,6 +159,7 @@ $(obj)/vdso-o32.lds: $(src)/vdso.lds.S FORCE
134 159
135$(obj)/vdso-o32.so.dbg.raw: $(obj)/vdso-o32.lds $(obj-vdso-o32) FORCE 160$(obj)/vdso-o32.so.dbg.raw: $(obj)/vdso-o32.lds $(obj-vdso-o32) FORCE
136 $(call if_changed,vdsold) 161 $(call if_changed,vdsold)
162 $(call if_changed,vdso_check)
137 163
138$(obj)/vdso-o32-image.c: VDSO_NAME := o32 164$(obj)/vdso-o32-image.c: VDSO_NAME := o32
139$(obj)/vdso-o32-image.c: $(obj)/vdso-o32.so.dbg.raw $(obj)/vdso-o32.so.raw \ 165$(obj)/vdso-o32-image.c: $(obj)/vdso-o32.so.dbg.raw $(obj)/vdso-o32.so.raw \
@@ -174,6 +200,7 @@ $(obj)/vdso-n32.lds: $(src)/vdso.lds.S FORCE
174 200
175$(obj)/vdso-n32.so.dbg.raw: $(obj)/vdso-n32.lds $(obj-vdso-n32) FORCE 201$(obj)/vdso-n32.so.dbg.raw: $(obj)/vdso-n32.lds $(obj-vdso-n32) FORCE
176 $(call if_changed,vdsold) 202 $(call if_changed,vdsold)
203 $(call if_changed,vdso_check)
177 204
178$(obj)/vdso-n32-image.c: VDSO_NAME := n32 205$(obj)/vdso-n32-image.c: VDSO_NAME := n32
179$(obj)/vdso-n32-image.c: $(obj)/vdso-n32.so.dbg.raw $(obj)/vdso-n32.so.raw \ 206$(obj)/vdso-n32-image.c: $(obj)/vdso-n32.so.dbg.raw $(obj)/vdso-n32.so.raw \
diff --git a/arch/mips/vdso/config-n32-o32-env.c b/arch/mips/vdso/config-n32-o32-env.c
new file mode 100644
index 000000000000..da4994b2b3e5
--- /dev/null
+++ b/arch/mips/vdso/config-n32-o32-env.c
@@ -0,0 +1,17 @@
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * Configuration file for O32 and N32 binaries.
4 * Note: To be included before lib/vdso/gettimeofday.c
5 */
6#if defined(CONFIG_MIPS32_O32) || defined(CONFIG_MIPS32_N32)
7/*
8 * In case of a 32 bit VDSO for a 64 bit kernel fake a 32 bit kernel
9 * configuration.
10 */
11#undef CONFIG_64BIT
12
13#define CONFIG_32BIT 1
14#define CONFIG_GENERIC_ATOMIC64 1
15
16#endif
17
diff --git a/arch/mips/vdso/elf.S b/arch/mips/vdso/elf.S
index e7543e8f426c..a25cb147f1ca 100644
--- a/arch/mips/vdso/elf.S
+++ b/arch/mips/vdso/elf.S
@@ -4,7 +4,7 @@
4 * Author: Alex Smith <alex.smith@imgtec.com> 4 * Author: Alex Smith <alex.smith@imgtec.com>
5 */ 5 */
6 6
7#include "vdso.h" 7#include <asm/vdso/vdso.h>
8 8
9#include <asm/isa-rev.h> 9#include <asm/isa-rev.h>
10 10
diff --git a/arch/mips/vdso/sigreturn.S b/arch/mips/vdso/sigreturn.S
index c3597632874b..e5c0ab98ab46 100644
--- a/arch/mips/vdso/sigreturn.S
+++ b/arch/mips/vdso/sigreturn.S
@@ -4,7 +4,7 @@
4 * Author: Alex Smith <alex.smith@imgtec.com> 4 * Author: Alex Smith <alex.smith@imgtec.com>
5 */ 5 */
6 6
7#include "vdso.h" 7#include <asm/vdso/vdso.h>
8 8
9#include <uapi/asm/unistd.h> 9#include <uapi/asm/unistd.h>
10 10
diff --git a/arch/mips/vdso/vgettimeofday.c b/arch/mips/vdso/vgettimeofday.c
new file mode 100644
index 000000000000..1c46dace041e
--- /dev/null
+++ b/arch/mips/vdso/vgettimeofday.c
@@ -0,0 +1,40 @@
1// SPDX-License-Identifier: GPL-2.0-or-later
2/*
3 * MIPS64 and compat userspace implementations of gettimeofday()
4 * and similar.
5 *
6 * Copyright (C) 2015 Imagination Technologies
7 * Copyright (C) 2018 ARM Limited
8 *
9 */
10#include <linux/time.h>
11#include <linux/types.h>
12
13#if _MIPS_SIM != _MIPS_SIM_ABI64
14int __vdso_clock_gettime(clockid_t clock,
15 struct old_timespec32 *ts)
16{
17 return __cvdso_clock_gettime32(clock, ts);
18}
19
20int __vdso_gettimeofday(struct __kernel_old_timeval *tv,
21 struct timezone *tz)
22{
23 return __cvdso_gettimeofday(tv, tz);
24}
25
26#else
27
28int __vdso_clock_gettime(clockid_t clock,
29 struct __kernel_timespec *ts)
30{
31 return __cvdso_clock_gettime(clock, ts);
32}
33
34int __vdso_gettimeofday(struct __kernel_old_timeval *tv,
35 struct timezone *tz)
36{
37 return __cvdso_gettimeofday(tv, tz);
38}
39
40#endif