18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * Fast user context implementation of getcpu() 48c2ecf20Sopenharmony_ci */ 58c2ecf20Sopenharmony_ci 68c2ecf20Sopenharmony_ci#include <asm/vdso.h> 78c2ecf20Sopenharmony_ci#include <linux/getcpu.h> 88c2ecf20Sopenharmony_ci 98c2ecf20Sopenharmony_cistatic __always_inline int read_cpu_id(void) 108c2ecf20Sopenharmony_ci{ 118c2ecf20Sopenharmony_ci int cpu_id; 128c2ecf20Sopenharmony_ci 138c2ecf20Sopenharmony_ci __asm__ __volatile__( 148c2ecf20Sopenharmony_ci " rdtime.d $zero, %0\n" 158c2ecf20Sopenharmony_ci : "=r" (cpu_id) 168c2ecf20Sopenharmony_ci : 178c2ecf20Sopenharmony_ci : "memory"); 188c2ecf20Sopenharmony_ci 198c2ecf20Sopenharmony_ci return cpu_id; 208c2ecf20Sopenharmony_ci} 218c2ecf20Sopenharmony_ci 228c2ecf20Sopenharmony_cistatic __always_inline const struct vdso_pcpu_data *get_pcpu_data(void) 238c2ecf20Sopenharmony_ci{ 248c2ecf20Sopenharmony_ci return (struct vdso_pcpu_data *)(get_vdso_data() + VVAR_LOONGARCH_PAGES_START * PAGE_SIZE); 258c2ecf20Sopenharmony_ci} 268c2ecf20Sopenharmony_ci 278c2ecf20Sopenharmony_ciint __vdso_getcpu(unsigned int *cpu, unsigned int *node, struct getcpu_cache *unused) 288c2ecf20Sopenharmony_ci{ 298c2ecf20Sopenharmony_ci int cpu_id; 308c2ecf20Sopenharmony_ci const struct vdso_pcpu_data *data; 318c2ecf20Sopenharmony_ci 328c2ecf20Sopenharmony_ci cpu_id = read_cpu_id(); 338c2ecf20Sopenharmony_ci 348c2ecf20Sopenharmony_ci if (cpu) 358c2ecf20Sopenharmony_ci *cpu = cpu_id; 368c2ecf20Sopenharmony_ci 378c2ecf20Sopenharmony_ci if (node) { 388c2ecf20Sopenharmony_ci data = get_pcpu_data(); 398c2ecf20Sopenharmony_ci *node = data[cpu_id].node; 408c2ecf20Sopenharmony_ci } 418c2ecf20Sopenharmony_ci 428c2ecf20Sopenharmony_ci return 0; 438c2ecf20Sopenharmony_ci} 44