Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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 <thomas.weissschuh@linutronix.de>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Link: https://lore.kernel.org/all/20250204-vdso-store-rng-v3-7-13a4669dfc8c@linutronix.de

authored by

Thomas Weißschuh and committed by
Thomas Gleixner
365841e1 51d6ca37

+43
+4
arch/Kconfig
··· 1584 1584 entries at 4000, 5000 and 6000 locations. This option turns on syscall 1585 1585 related optimizations for a given architecture. 1586 1586 1587 + config ARCH_HAS_VDSO_ARCH_DATA 1588 + depends on GENERIC_VDSO_DATA_STORE 1589 + bool 1590 + 1587 1591 config ARCH_HAS_VDSO_TIME_DATA 1588 1592 bool 1589 1593
+25
include/vdso/datapage.h
··· 9 9 #include <uapi/linux/types.h> 10 10 #include <uapi/asm-generic/errno-base.h> 11 11 12 + #include <vdso/align.h> 12 13 #include <vdso/bits.h> 13 14 #include <vdso/clocksource.h> 14 15 #include <vdso/ktime.h> 15 16 #include <vdso/limits.h> 16 17 #include <vdso/math64.h> 18 + #include <vdso/page.h> 17 19 #include <vdso/processor.h> 18 20 #include <vdso/time.h> 19 21 #include <vdso/time32.h> ··· 25 23 #include <asm/vdso/time_data.h> 26 24 #else 27 25 struct arch_vdso_time_data {}; 26 + #endif 27 + 28 + #if defined(CONFIG_ARCH_HAS_VDSO_ARCH_DATA) 29 + #include <asm/vdso/arch_data.h> 30 + #elif defined(CONFIG_GENERIC_VDSO_DATA_STORE) 31 + struct vdso_arch_data { 32 + /* Needed for the generic code, never actually used at runtime */ 33 + char __unused; 34 + }; 28 35 #endif 29 36 30 37 #define VDSO_BASES (CLOCK_TAI + 1) ··· 156 145 #else 157 146 extern struct vdso_time_data vdso_u_time_data[CS_BASES] __attribute__((visibility("hidden"))); 158 147 extern struct vdso_rng_data vdso_u_rng_data __attribute__((visibility("hidden"))); 148 + extern struct vdso_arch_data vdso_u_arch_data __attribute__((visibility("hidden"))); 159 149 160 150 extern struct vdso_time_data *vdso_k_time_data; 161 151 extern struct vdso_rng_data *vdso_k_rng_data; 152 + extern struct vdso_arch_data *vdso_k_arch_data; 162 153 #endif 163 154 164 155 /** ··· 173 160 174 161 #ifdef CONFIG_GENERIC_VDSO_DATA_STORE 175 162 163 + #define VDSO_ARCH_DATA_SIZE ALIGN(sizeof(struct vdso_arch_data), PAGE_SIZE) 164 + #define VDSO_ARCH_DATA_PAGES (VDSO_ARCH_DATA_SIZE >> PAGE_SHIFT) 165 + 176 166 enum vdso_pages { 177 167 VDSO_TIME_PAGE_OFFSET, 178 168 VDSO_TIMENS_PAGE_OFFSET, 179 169 VDSO_RNG_PAGE_OFFSET, 170 + VDSO_ARCH_PAGES_START, 171 + VDSO_ARCH_PAGES_END = VDSO_ARCH_PAGES_START + VDSO_ARCH_DATA_PAGES - 1, 180 172 VDSO_NR_PAGES 181 173 }; 182 174 ··· 211 193 #define __vdso_u_rng_data 212 194 #endif 213 195 196 + #ifdef CONFIG_ARCH_HAS_VDSO_ARCH_DATA 197 + #define __vdso_u_arch_data PROVIDE(vdso_u_arch_data = vdso_u_data + 3 * PAGE_SIZE); 198 + #else 199 + #define __vdso_u_arch_data 200 + #endif 201 + 214 202 #define VDSO_VVAR_SYMS \ 215 203 PROVIDE(vdso_u_data = . - __VDSO_PAGES * PAGE_SIZE); \ 216 204 PROVIDE(vdso_u_time_data = vdso_u_data); \ 217 205 __vdso_u_rng_data \ 206 + __vdso_u_arch_data \ 218 207 219 208 220 209 #endif /* !__ASSEMBLY__ */
+14
lib/vdso/datastore.c
··· 26 26 static_assert(sizeof(vdso_rng_data_store) == PAGE_SIZE); 27 27 #endif /* CONFIG_VDSO_GETRANDOM */ 28 28 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 + 29 37 static vm_fault_t vvar_fault(const struct vm_special_mapping *sm, 30 38 struct vm_area_struct *vma, struct vm_fault *vmf) 31 39 { ··· 74 66 if (!IS_ENABLED(CONFIG_VDSO_GETRANDOM)) 75 67 return VM_FAULT_SIGBUS; 76 68 pfn = __phys_to_pfn(__pa_symbol(vdso_k_rng_data)); 69 + break; 70 + case VDSO_ARCH_PAGES_START ... VDSO_ARCH_PAGES_END: 71 + if (!IS_ENABLED(CONFIG_ARCH_HAS_VDSO_ARCH_DATA)) 72 + return VM_FAULT_SIGBUS; 73 + pfn = __phys_to_pfn(__pa_symbol(vdso_k_arch_data)) + 74 + vmf->pgoff - VDSO_ARCH_PAGES_START; 77 75 break; 78 76 default: 79 77 return VM_FAULT_SIGBUS;