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 random data storage

Extend the generic vDSO data storage with a page for the random state data.
The random state data is stored in a dedicated page, as the existing
storage page is only meant for time-related, time-namespace-aware data.
This simplifies to access logic to not need to handle time namespaces
anymore and also frees up more space in the time-related page.

In case further generic vDSO data store is required it can be added to
the random state page.

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-6-13a4669dfc8c@linutronix.de

authored by

Thomas Weißschuh and committed by
Thomas Gleixner
51d6ca37 df7fcbef

+45 -5
+3 -3
drivers/char/random.c
··· 278 278 WRITE_ONCE(base_crng.generation, next_gen); 279 279 #ifdef CONFIG_VDSO_GETRANDOM 280 280 /* base_crng.generation's invalid value is ULONG_MAX, while 281 - * _vdso_rng_data.generation's invalid value is 0, so add one to the 281 + * vdso_k_rng_data->generation's invalid value is 0, so add one to the 282 282 * former to arrive at the latter. Use smp_store_release so that this 283 283 * is ordered with the write above to base_crng.generation. Pairs with 284 284 * the smp_rmb() before the syscall in the vDSO code. ··· 290 290 * because the vDSO side only checks whether the value changed, without 291 291 * actually using or interpreting the value. 292 292 */ 293 - smp_store_release((unsigned long *)&__arch_get_k_vdso_rng_data()->generation, next_gen + 1); 293 + smp_store_release((unsigned long *)&vdso_k_rng_data->generation, next_gen + 1); 294 294 #endif 295 295 if (!static_branch_likely(&crng_is_ready)) 296 296 crng_init = CRNG_READY; ··· 743 743 queue_work(system_unbound_wq, &set_ready); 744 744 atomic_notifier_call_chain(&random_ready_notifier, 0, NULL); 745 745 #ifdef CONFIG_VDSO_GETRANDOM 746 - WRITE_ONCE(__arch_get_k_vdso_rng_data()->is_ready, true); 746 + WRITE_ONCE(vdso_k_rng_data->is_ready, true); 747 747 #endif 748 748 wake_up_interruptible(&crng_init_wait); 749 749 kill_fasync(&fasync, SIGIO, POLL_IN);
+12
include/asm-generic/vdso/vsyscall.h
··· 13 13 } 14 14 #endif 15 15 16 + #ifndef __arch_get_vdso_u_rng_data 17 + static __always_inline const struct vdso_rng_data *__arch_get_vdso_u_rng_data(void) 18 + { 19 + return &vdso_u_rng_data; 20 + } 21 + #endif 22 + 16 23 #else /* !CONFIG_GENERIC_VDSO_DATA_STORE */ 17 24 18 25 #ifndef __arch_get_k_vdso_data ··· 31 24 #define vdso_k_time_data __arch_get_k_vdso_data() 32 25 33 26 #define __arch_get_vdso_u_time_data __arch_get_vdso_data 27 + 28 + #ifndef __arch_get_vdso_u_rng_data 29 + #define __arch_get_vdso_u_rng_data() __arch_get_vdso_rng_data() 30 + #endif 31 + #define vdso_k_rng_data __arch_get_k_vdso_rng_data() 34 32 35 33 #endif /* CONFIG_GENERIC_VDSO_DATA_STORE */ 36 34
+10
include/vdso/datapage.h
··· 144 144 extern struct vdso_rng_data _vdso_rng_data __attribute__((visibility("hidden"))); 145 145 #else 146 146 extern struct vdso_time_data vdso_u_time_data[CS_BASES] __attribute__((visibility("hidden"))); 147 + extern struct vdso_rng_data vdso_u_rng_data __attribute__((visibility("hidden"))); 147 148 148 149 extern struct vdso_time_data *vdso_k_time_data; 150 + extern struct vdso_rng_data *vdso_k_rng_data; 149 151 #endif 150 152 151 153 /** ··· 163 161 enum vdso_pages { 164 162 VDSO_TIME_PAGE_OFFSET, 165 163 VDSO_TIMENS_PAGE_OFFSET, 164 + VDSO_RNG_PAGE_OFFSET, 166 165 VDSO_NR_PAGES 167 166 }; 168 167 ··· 187 184 188 185 #else /* !__ASSEMBLY__ */ 189 186 187 + #ifdef CONFIG_VDSO_GETRANDOM 188 + #define __vdso_u_rng_data PROVIDE(vdso_u_rng_data = vdso_u_data + 2 * PAGE_SIZE); 189 + #else 190 + #define __vdso_u_rng_data 191 + #endif 192 + 190 193 #define VDSO_VVAR_SYMS \ 191 194 PROVIDE(vdso_u_data = . - __VDSO_PAGES * PAGE_SIZE); \ 192 195 PROVIDE(vdso_u_time_data = vdso_u_data); \ 196 + __vdso_u_rng_data \ 193 197 194 198 195 199 #endif /* !__ASSEMBLY__ */
+14
lib/vdso/datastore.c
··· 17 17 static_assert(sizeof(vdso_time_data_store) == PAGE_SIZE); 18 18 #endif /* CONFIG_HAVE_GENERIC_VDSO */ 19 19 20 + #ifdef CONFIG_VDSO_GETRANDOM 21 + static union { 22 + struct vdso_rng_data data; 23 + u8 page[PAGE_SIZE]; 24 + } vdso_rng_data_store __page_aligned_data; 25 + struct vdso_rng_data *vdso_k_rng_data = &vdso_rng_data_store.data; 26 + static_assert(sizeof(vdso_rng_data_store) == PAGE_SIZE); 27 + #endif /* CONFIG_VDSO_GETRANDOM */ 28 + 20 29 static vm_fault_t vvar_fault(const struct vm_special_mapping *sm, 21 30 struct vm_area_struct *vma, struct vm_fault *vmf) 22 31 { ··· 61 52 if (!IS_ENABLED(CONFIG_TIME_NS) || !timens_page) 62 53 return VM_FAULT_SIGBUS; 63 54 pfn = __phys_to_pfn(__pa_symbol(vdso_k_time_data)); 55 + break; 56 + case VDSO_RNG_PAGE_OFFSET: 57 + if (!IS_ENABLED(CONFIG_VDSO_GETRANDOM)) 58 + return VM_FAULT_SIGBUS; 59 + pfn = __phys_to_pfn(__pa_symbol(vdso_k_rng_data)); 64 60 break; 65 61 default: 66 62 return VM_FAULT_SIGBUS;
+6 -2
lib/vdso/getrandom.c
··· 12 12 #include <uapi/linux/mman.h> 13 13 #include <uapi/linux/random.h> 14 14 15 + /* Bring in default accessors */ 16 + #include <vdso/vsyscall.h> 17 + 15 18 #undef PAGE_SIZE 16 19 #undef PAGE_MASK 17 20 #define PAGE_SIZE (1UL << CONFIG_PAGE_SHIFT) ··· 155 152 156 153 /* 157 154 * Prevent the syscall from being reordered wrt current_generation. Pairs with the 158 - * smp_store_release(&_vdso_rng_data.generation) in random.c. 155 + * smp_store_release(&vdso_k_rng_data->generation) in random.c. 159 156 */ 160 157 smp_rmb(); 161 158 ··· 259 256 static __always_inline ssize_t 260 257 __cvdso_getrandom(void *buffer, size_t len, unsigned int flags, void *opaque_state, size_t opaque_len) 261 258 { 262 - return __cvdso_getrandom_data(__arch_get_vdso_rng_data(), buffer, len, flags, opaque_state, opaque_len); 259 + return __cvdso_getrandom_data(__arch_get_vdso_u_rng_data(), buffer, len, flags, 260 + opaque_state, opaque_len); 263 261 }