1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Copyright 2023 Rivos, Inc 4 */ 5 6 #include <linux/types.h> 7 #include <vdso/datapage.h> 8 #include <vdso/helpers.h> 9 10 extern int riscv_hwprobe(struct riscv_hwprobe *pairs, size_t pair_count, 11 size_t cpu_count, unsigned long *cpus, 12 unsigned int flags); 13 14 /* Add a prototype to avoid -Wmissing-prototypes warning. */ 15 int __vdso_riscv_hwprobe(struct riscv_hwprobe *pairs, size_t pair_count, 16 size_t cpu_count, unsigned long *cpus, 17 unsigned int flags); 18 19 int __vdso_riscv_hwprobe(struct riscv_hwprobe *pairs, size_t pair_count, 20 size_t cpu_count, unsigned long *cpus, 21 unsigned int flags) 22 { 23 const struct vdso_data *vd = __arch_get_vdso_data(); 24 const struct arch_vdso_data *avd = &vd->arch_data; 25 bool all_cpus = !cpu_count && !cpus; 26 struct riscv_hwprobe *p = pairs; 27 struct riscv_hwprobe *end = pairs + pair_count; 28 29 /* 30 * Defer to the syscall for exotic requests. The vdso has answers 31 * stashed away only for the "all cpus" case. If all CPUs are 32 * homogeneous, then this function can handle requests for arbitrary 33 * masks. 34 */ 35 if ((flags != 0) || (!all_cpus && !avd->homogeneous_cpus)) 36 return riscv_hwprobe(pairs, pair_count, cpu_count, cpus, flags); 37 38 /* This is something we can handle, fill out the pairs. */ 39 while (p < end) { 40 if (p->key <= RISCV_HWPROBE_MAX_KEY) { 41 p->value = avd->all_cpu_hwprobe_values[p->key]; 42 43 } else { 44 p->key = -1; 45 p->value = 0; 46 } 47 48 p++; 49 } 50 51 return 0; 52 } 53