1dce6098bSHuacai Chen // SPDX-License-Identifier: GPL-2.0-only 2dce6098bSHuacai Chen /* 3dce6098bSHuacai Chen * Fast user context implementation of getcpu() 4dce6098bSHuacai Chen */ 5dce6098bSHuacai Chen 6dce6098bSHuacai Chen #include <asm/vdso.h> 7dce6098bSHuacai Chen #include <linux/getcpu.h> 8dce6098bSHuacai Chen read_cpu_id(void)9dce6098bSHuacai Chenstatic __always_inline int read_cpu_id(void) 10dce6098bSHuacai Chen { 11dce6098bSHuacai Chen int cpu_id; 12dce6098bSHuacai Chen 13dce6098bSHuacai Chen __asm__ __volatile__( 14dce6098bSHuacai Chen " rdtime.d $zero, %0\n" 15dce6098bSHuacai Chen : "=r" (cpu_id) 16dce6098bSHuacai Chen : 17dce6098bSHuacai Chen : "memory"); 18dce6098bSHuacai Chen 19dce6098bSHuacai Chen return cpu_id; 20dce6098bSHuacai Chen } 21dce6098bSHuacai Chen get_pcpu_data(void)22dce6098bSHuacai Chenstatic __always_inline const struct vdso_pcpu_data *get_pcpu_data(void) 23dce6098bSHuacai Chen { 24*aa5e65dcSTiezhu Yang return (struct vdso_pcpu_data *)(get_vdso_data() + VVAR_LOONGARCH_PAGES_START * PAGE_SIZE); 25dce6098bSHuacai Chen } 26dce6098bSHuacai Chen 2784e76206SHuacai Chen extern 2884e76206SHuacai Chen int __vdso_getcpu(unsigned int *cpu, unsigned int *node, struct getcpu_cache *unused); __vdso_getcpu(unsigned int * cpu,unsigned int * node,struct getcpu_cache * unused)29dce6098bSHuacai Chenint __vdso_getcpu(unsigned int *cpu, unsigned int *node, struct getcpu_cache *unused) 30dce6098bSHuacai Chen { 31dce6098bSHuacai Chen int cpu_id; 32dce6098bSHuacai Chen const struct vdso_pcpu_data *data; 33dce6098bSHuacai Chen 34dce6098bSHuacai Chen cpu_id = read_cpu_id(); 35dce6098bSHuacai Chen 36dce6098bSHuacai Chen if (cpu) 37dce6098bSHuacai Chen *cpu = cpu_id; 38dce6098bSHuacai Chen 39dce6098bSHuacai Chen if (node) { 40dce6098bSHuacai Chen data = get_pcpu_data(); 41dce6098bSHuacai Chen *node = data[cpu_id].node; 42dce6098bSHuacai Chen } 43dce6098bSHuacai Chen 44dce6098bSHuacai Chen return 0; 45dce6098bSHuacai Chen } 46