Skip to content

Commit 365841e

Browse files
t-8chKAGA-KOKO
authored andcommitted
vdso: Add generic architecture-specific data storage
Some architectures need to expose architecture-specific data to the vDSO. Enable the generic vDSO storage mechanism to both store and map this data. Some architectures require more than a single page, like LoongArch, so prepare for that usecase, too. Signed-off-by: Thomas Weißschuh <[email protected]> Signed-off-by: Thomas Gleixner <[email protected]> Link: https://lore.kernel.org/all/[email protected]
1 parent 51d6ca3 commit 365841e

File tree

3 files changed

+43
-0
lines changed

3 files changed

+43
-0
lines changed

arch/Kconfig

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1584,6 +1584,10 @@ config HAVE_SPARSE_SYSCALL_NR
15841584
entries at 4000, 5000 and 6000 locations. This option turns on syscall
15851585
related optimizations for a given architecture.
15861586

1587+
config ARCH_HAS_VDSO_ARCH_DATA
1588+
depends on GENERIC_VDSO_DATA_STORE
1589+
bool
1590+
15871591
config ARCH_HAS_VDSO_TIME_DATA
15881592
bool
15891593

include/vdso/datapage.h

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,13 @@
99
#include <uapi/linux/types.h>
1010
#include <uapi/asm-generic/errno-base.h>
1111

12+
#include <vdso/align.h>
1213
#include <vdso/bits.h>
1314
#include <vdso/clocksource.h>
1415
#include <vdso/ktime.h>
1516
#include <vdso/limits.h>
1617
#include <vdso/math64.h>
18+
#include <vdso/page.h>
1719
#include <vdso/processor.h>
1820
#include <vdso/time.h>
1921
#include <vdso/time32.h>
@@ -25,6 +27,15 @@
2527
struct arch_vdso_time_data {};
2628
#endif
2729

30+
#if defined(CONFIG_ARCH_HAS_VDSO_ARCH_DATA)
31+
#include <asm/vdso/arch_data.h>
32+
#elif defined(CONFIG_GENERIC_VDSO_DATA_STORE)
33+
struct vdso_arch_data {
34+
/* Needed for the generic code, never actually used at runtime */
35+
char __unused;
36+
};
37+
#endif
38+
2839
#define VDSO_BASES (CLOCK_TAI + 1)
2940
#define VDSO_HRES (BIT(CLOCK_REALTIME) | \
3041
BIT(CLOCK_MONOTONIC) | \
@@ -145,9 +156,11 @@ extern struct vdso_rng_data _vdso_rng_data __attribute__((visibility("hidden")))
145156
#else
146157
extern struct vdso_time_data vdso_u_time_data[CS_BASES] __attribute__((visibility("hidden")));
147158
extern struct vdso_rng_data vdso_u_rng_data __attribute__((visibility("hidden")));
159+
extern struct vdso_arch_data vdso_u_arch_data __attribute__((visibility("hidden")));
148160

149161
extern struct vdso_time_data *vdso_k_time_data;
150162
extern struct vdso_rng_data *vdso_k_rng_data;
163+
extern struct vdso_arch_data *vdso_k_arch_data;
151164
#endif
152165

153166
/**
@@ -160,10 +173,15 @@ union vdso_data_store {
160173

161174
#ifdef CONFIG_GENERIC_VDSO_DATA_STORE
162175

176+
#define VDSO_ARCH_DATA_SIZE ALIGN(sizeof(struct vdso_arch_data), PAGE_SIZE)
177+
#define VDSO_ARCH_DATA_PAGES (VDSO_ARCH_DATA_SIZE >> PAGE_SHIFT)
178+
163179
enum vdso_pages {
164180
VDSO_TIME_PAGE_OFFSET,
165181
VDSO_TIMENS_PAGE_OFFSET,
166182
VDSO_RNG_PAGE_OFFSET,
183+
VDSO_ARCH_PAGES_START,
184+
VDSO_ARCH_PAGES_END = VDSO_ARCH_PAGES_START + VDSO_ARCH_DATA_PAGES - 1,
167185
VDSO_NR_PAGES
168186
};
169187

@@ -193,10 +211,17 @@ enum vdso_pages {
193211
#define __vdso_u_rng_data
194212
#endif
195213

214+
#ifdef CONFIG_ARCH_HAS_VDSO_ARCH_DATA
215+
#define __vdso_u_arch_data PROVIDE(vdso_u_arch_data = vdso_u_data + 3 * PAGE_SIZE);
216+
#else
217+
#define __vdso_u_arch_data
218+
#endif
219+
196220
#define VDSO_VVAR_SYMS \
197221
PROVIDE(vdso_u_data = . - __VDSO_PAGES * PAGE_SIZE); \
198222
PROVIDE(vdso_u_time_data = vdso_u_data); \
199223
__vdso_u_rng_data \
224+
__vdso_u_arch_data \
200225

201226

202227
#endif /* !__ASSEMBLY__ */

lib/vdso/datastore.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,14 @@ struct vdso_rng_data *vdso_k_rng_data = &vdso_rng_data_store.data;
2626
static_assert(sizeof(vdso_rng_data_store) == PAGE_SIZE);
2727
#endif /* CONFIG_VDSO_GETRANDOM */
2828

29+
#ifdef CONFIG_ARCH_HAS_VDSO_ARCH_DATA
30+
static union {
31+
struct vdso_arch_data data;
32+
u8 page[VDSO_ARCH_DATA_SIZE];
33+
} vdso_arch_data_store __page_aligned_data;
34+
struct vdso_arch_data *vdso_k_arch_data = &vdso_arch_data_store.data;
35+
#endif /* CONFIG_ARCH_HAS_VDSO_ARCH_DATA */
36+
2937
static vm_fault_t vvar_fault(const struct vm_special_mapping *sm,
3038
struct vm_area_struct *vma, struct vm_fault *vmf)
3139
{
@@ -67,6 +75,12 @@ static vm_fault_t vvar_fault(const struct vm_special_mapping *sm,
6775
return VM_FAULT_SIGBUS;
6876
pfn = __phys_to_pfn(__pa_symbol(vdso_k_rng_data));
6977
break;
78+
case VDSO_ARCH_PAGES_START ... VDSO_ARCH_PAGES_END:
79+
if (!IS_ENABLED(CONFIG_ARCH_HAS_VDSO_ARCH_DATA))
80+
return VM_FAULT_SIGBUS;
81+
pfn = __phys_to_pfn(__pa_symbol(vdso_k_arch_data)) +
82+
vmf->pgoff - VDSO_ARCH_PAGES_START;
83+
break;
7084
default:
7185
return VM_FAULT_SIGBUS;
7286
}

0 commit comments

Comments
 (0)