diff options
| author | Thomas Weißschuh <thomas.weissschuh@linutronix.de> | 2025-02-04 13:05:38 +0100 |
|---|---|---|
| committer | Thomas Gleixner <tglx@linutronix.de> | 2025-02-21 09:54:01 +0100 |
| commit | 51d6ca373f459fa6c91743e14ae69854d844aa38 (patch) | |
| tree | 72ff45b96b2ce8938aa8676fcd5a6ac7fa5791e7 /lib/vdso | |
| parent | df7fcbefa71090a276fb841ffe19b8e5f12b4767 (diff) | |
| download | linux-51d6ca373f459fa6c91743e14ae69854d844aa38.tar.gz linux-51d6ca373f459fa6c91743e14ae69854d844aa38.tar.bz2 linux-51d6ca373f459fa6c91743e14ae69854d844aa38.zip | |
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
Diffstat (limited to 'lib/vdso')
| -rw-r--r-- | lib/vdso/datastore.c | 14 | ||||
| -rw-r--r-- | lib/vdso/getrandom.c | 8 |
2 files changed, 20 insertions, 2 deletions
diff --git a/lib/vdso/datastore.c b/lib/vdso/datastore.c index d3181768424c..9260b00dc852 100644 --- a/lib/vdso/datastore.c +++ b/lib/vdso/datastore.c @@ -17,6 +17,15 @@ struct vdso_time_data *vdso_k_time_data = vdso_time_data_store.data; static_assert(sizeof(vdso_time_data_store) == PAGE_SIZE); #endif /* CONFIG_HAVE_GENERIC_VDSO */ +#ifdef CONFIG_VDSO_GETRANDOM +static union { + struct vdso_rng_data data; + u8 page[PAGE_SIZE]; +} vdso_rng_data_store __page_aligned_data; +struct vdso_rng_data *vdso_k_rng_data = &vdso_rng_data_store.data; +static_assert(sizeof(vdso_rng_data_store) == PAGE_SIZE); +#endif /* CONFIG_VDSO_GETRANDOM */ + static vm_fault_t vvar_fault(const struct vm_special_mapping *sm, struct vm_area_struct *vma, struct vm_fault *vmf) { @@ -53,6 +62,11 @@ static vm_fault_t vvar_fault(const struct vm_special_mapping *sm, return VM_FAULT_SIGBUS; pfn = __phys_to_pfn(__pa_symbol(vdso_k_time_data)); break; + case VDSO_RNG_PAGE_OFFSET: + if (!IS_ENABLED(CONFIG_VDSO_GETRANDOM)) + return VM_FAULT_SIGBUS; + pfn = __phys_to_pfn(__pa_symbol(vdso_k_rng_data)); + break; default: return VM_FAULT_SIGBUS; } diff --git a/lib/vdso/getrandom.c b/lib/vdso/getrandom.c index 938ca539aaa6..440f8a6203a6 100644 --- a/lib/vdso/getrandom.c +++ b/lib/vdso/getrandom.c @@ -12,6 +12,9 @@ #include <uapi/linux/mman.h> #include <uapi/linux/random.h> +/* Bring in default accessors */ +#include <vdso/vsyscall.h> + #undef PAGE_SIZE #undef PAGE_MASK #define PAGE_SIZE (1UL << CONFIG_PAGE_SHIFT) @@ -152,7 +155,7 @@ retry_generation: /* * Prevent the syscall from being reordered wrt current_generation. Pairs with the - * smp_store_release(&_vdso_rng_data.generation) in random.c. + * smp_store_release(&vdso_k_rng_data->generation) in random.c. */ smp_rmb(); @@ -256,5 +259,6 @@ fallback_syscall: static __always_inline ssize_t __cvdso_getrandom(void *buffer, size_t len, unsigned int flags, void *opaque_state, size_t opaque_len) { - return __cvdso_getrandom_data(__arch_get_vdso_rng_data(), buffer, len, flags, opaque_state, opaque_len); + return __cvdso_getrandom_data(__arch_get_vdso_u_rng_data(), buffer, len, flags, + opaque_state, opaque_len); } |
