| /* |
| * Copyright 2006 Andi Kleen, SUSE Labs. |
| * Subject to the GNU Public License, v.2 |
| * |
| * Fast user context implementation of getcpu() |
| */ |
| |
| #include <linux/kernel.h> |
| #include <linux/getcpu.h> |
| #include <linux/jiffies.h> |
| #include <linux/time.h> |
| #include <asm/vsyscall.h> |
| #include <asm/vgtod.h> |
| #include "vextern.h" |
| |
| notrace long |
| __vdso_getcpu(unsigned *cpu, unsigned *node, struct getcpu_cache *unused) |
| { |
| unsigned int p; |
| |
| if (*vdso_vgetcpu_mode == VGETCPU_RDTSCP) { |
| /* Load per CPU data from RDTSCP */ |
| native_read_tscp(&p); |
| } else { |
| /* Load per CPU data from GDT */ |
| asm("lsl %1,%0" : "=r" (p) : "r" (__PER_CPU_SEG)); |
| } |
| if (cpu) |
| *cpu = p & 0xfff; |
| if (node) |
| *node = p >> 12; |
| return 0; |
| } |
| |
| long getcpu(unsigned *cpu, unsigned *node, struct getcpu_cache *tcache) |
| __attribute__((weak, alias("__vdso_getcpu"))); |