| 
									
										
										
										
											2007-07-21 17:10:01 +02:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * 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"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-05-12 21:20:41 +02:00
										 |  |  | notrace long | 
					
						
							|  |  |  | __vdso_getcpu(unsigned *cpu, unsigned *node, struct getcpu_cache *unused) | 
					
						
							| 
									
										
										
										
											2007-07-21 17:10:01 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2008-01-30 13:31:06 +01:00
										 |  |  | 	unsigned int p; | 
					
						
							| 
									
										
										
										
											2007-07-21 17:10:01 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-11-07 18:37:48 +01:00
										 |  |  | 	if (*vdso_vgetcpu_mode == VGETCPU_RDTSCP) { | 
					
						
							| 
									
										
										
										
											2007-07-21 17:10:01 +02:00
										 |  |  | 		/* Load per CPU data from RDTSCP */ | 
					
						
							| 
									
										
										
										
											2008-01-30 13:31:06 +01:00
										 |  |  | 		native_read_tscp(&p); | 
					
						
							| 
									
										
										
										
											2007-07-21 17:10:01 +02:00
										 |  |  | 	} 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"))); |