|
14 | 14 | #include <asm/uaccess.h> |
15 | 15 | #include <asm/unistd.h> |
16 | 16 | #include <asm-generic/mman-common.h> |
| 17 | +#include <vdso/vsyscall.h> |
17 | 18 |
|
18 | 19 | static long riscv_sys_mmap(unsigned long addr, unsigned long len, |
19 | 20 | unsigned long prot, unsigned long flags, |
@@ -243,6 +244,50 @@ static int do_riscv_hwprobe(struct riscv_hwprobe __user *pairs, |
243 | 244 | return 0; |
244 | 245 | } |
245 | 246 |
|
| 247 | +#ifdef CONFIG_MMU |
| 248 | + |
| 249 | +static int __init init_hwprobe_vdso_data(void) |
| 250 | +{ |
| 251 | + struct vdso_data *vd = __arch_get_k_vdso_data(); |
| 252 | + struct arch_vdso_data *avd = &vd->arch_data; |
| 253 | + u64 id_bitsmash = 0; |
| 254 | + struct riscv_hwprobe pair; |
| 255 | + int key; |
| 256 | + |
| 257 | + /* |
| 258 | + * Initialize vDSO data with the answers for the "all CPUs" case, to |
| 259 | + * save a syscall in the common case. |
| 260 | + */ |
| 261 | + for (key = 0; key <= RISCV_HWPROBE_MAX_KEY; key++) { |
| 262 | + pair.key = key; |
| 263 | + hwprobe_one_pair(&pair, cpu_online_mask); |
| 264 | + |
| 265 | + WARN_ON_ONCE(pair.key < 0); |
| 266 | + |
| 267 | + avd->all_cpu_hwprobe_values[key] = pair.value; |
| 268 | + /* |
| 269 | + * Smash together the vendor, arch, and impl IDs to see if |
| 270 | + * they're all 0 or any negative. |
| 271 | + */ |
| 272 | + if (key <= RISCV_HWPROBE_KEY_MIMPID) |
| 273 | + id_bitsmash |= pair.value; |
| 274 | + } |
| 275 | + |
| 276 | + /* |
| 277 | + * If the arch, vendor, and implementation ID are all the same across |
| 278 | + * all harts, then assume all CPUs are the same, and allow the vDSO to |
| 279 | + * answer queries for arbitrary masks. However if all values are 0 (not |
| 280 | + * populated) or any value returns -1 (varies across CPUs), then the |
| 281 | + * vDSO should defer to the kernel for exotic cpu masks. |
| 282 | + */ |
| 283 | + avd->homogeneous_cpus = (id_bitsmash > 0); |
| 284 | + return 0; |
| 285 | +} |
| 286 | + |
| 287 | +arch_initcall_sync(init_hwprobe_vdso_data); |
| 288 | + |
| 289 | +#endif /* CONFIG_MMU */ |
| 290 | + |
246 | 291 | SYSCALL_DEFINE5(riscv_hwprobe, struct riscv_hwprobe __user *, pairs, |
247 | 292 | size_t, pair_count, size_t, cpu_count, unsigned long __user *, |
248 | 293 | cpus, unsigned int, flags) |
|
0 commit comments