aboutsummaryrefslogtreecommitdiffstats
path: root/include/asm-i386/pda.h
diff options
context:
space:
mode:
authorJeremy Fitzhardinge <jeremy@goop.org>2007-05-02 13:27:16 -0400
committerAndi Kleen <andi@basil.nowhere.org>2007-05-02 13:27:16 -0400
commit7c3576d261ce046789a7db14f43303f8120910c7 (patch)
treead27a8459bbcdb183fe2411aec3b840942992ad5 /include/asm-i386/pda.h
parent7a61d35d4b4056e7711031202da7605e052f4137 (diff)
[PATCH] i386: Convert PDA into the percpu section
Currently x86 (similar to x84-64) has a special per-cpu structure called "i386_pda" which can be easily and efficiently referenced via the %fs register. An ELF section is more flexible than a structure, allowing any piece of code to use this area. Indeed, such a section already exists: the per-cpu area. So this patch: (1) Removes the PDA and uses per-cpu variables for each current member. (2) Replaces the __KERNEL_PDA segment with __KERNEL_PERCPU. (3) Creates a per-cpu mirror of __per_cpu_offset called this_cpu_off, which can be used to calculate addresses for this CPU's variables. (4) Simplifies startup, because %fs doesn't need to be loaded with a special segment at early boot; it can be deferred until the first percpu area is allocated (or never for UP). The result is less code and one less x86-specific concept. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au> Signed-off-by: Jeremy Fitzhardinge <jeremy@xensource.com> Signed-off-by: Andi Kleen <ak@suse.de> Cc: Andi Kleen <ak@suse.de>
Diffstat (limited to 'include/asm-i386/pda.h')
-rw-r--r--include/asm-i386/pda.h99
1 files changed, 0 insertions, 99 deletions
diff --git a/include/asm-i386/pda.h b/include/asm-i386/pda.h
deleted file mode 100644
index aef7f732f77e..000000000000
--- a/include/asm-i386/pda.h
+++ /dev/null
@@ -1,99 +0,0 @@
1/*
2 Per-processor Data Areas
3 Jeremy Fitzhardinge <jeremy@goop.org> 2006
4 Based on asm-x86_64/pda.h by Andi Kleen.
5 */
6#ifndef _I386_PDA_H
7#define _I386_PDA_H
8
9#include <linux/stddef.h>
10#include <linux/types.h>
11#include <asm/percpu.h>
12
13struct i386_pda
14{
15 struct i386_pda *_pda; /* pointer to self */
16
17 int cpu_number;
18 struct task_struct *pcurrent; /* current process */
19 struct pt_regs *irq_regs;
20};
21
22DECLARE_PER_CPU(struct i386_pda, _cpu_pda);
23#define cpu_pda(i) (&per_cpu(_cpu_pda, (i)))
24#define pda_offset(field) offsetof(struct i386_pda, field)
25
26extern void __bad_pda_field(void);
27
28/* This variable is never instantiated. It is only used as a stand-in
29 for the real per-cpu PDA memory, so that gcc can understand what
30 memory operations the inline asms() below are performing. This
31 eliminates the need to make the asms volatile or have memory
32 clobbers, so gcc can readily analyse them. */
33extern struct i386_pda _proxy_pda;
34
35#define pda_to_op(op,field,val) \
36 do { \
37 typedef typeof(_proxy_pda.field) T__; \
38 if (0) { T__ tmp__; tmp__ = (val); } \
39 switch (sizeof(_proxy_pda.field)) { \
40 case 1: \
41 asm(op "b %1,%%fs:%c2" \
42 : "+m" (_proxy_pda.field) \
43 :"ri" ((T__)val), \
44 "i"(pda_offset(field))); \
45 break; \
46 case 2: \
47 asm(op "w %1,%%fs:%c2" \
48 : "+m" (_proxy_pda.field) \
49 :"ri" ((T__)val), \
50 "i"(pda_offset(field))); \
51 break; \
52 case 4: \
53 asm(op "l %1,%%fs:%c2" \
54 : "+m" (_proxy_pda.field) \
55 :"ri" ((T__)val), \
56 "i"(pda_offset(field))); \
57 break; \
58 default: __bad_pda_field(); \
59 } \
60 } while (0)
61
62#define pda_from_op(op,field) \
63 ({ \
64 typeof(_proxy_pda.field) ret__; \
65 switch (sizeof(_proxy_pda.field)) { \
66 case 1: \
67 asm(op "b %%fs:%c1,%0" \
68 : "=r" (ret__) \
69 : "i" (pda_offset(field)), \
70 "m" (_proxy_pda.field)); \
71 break; \
72 case 2: \
73 asm(op "w %%fs:%c1,%0" \
74 : "=r" (ret__) \
75 : "i" (pda_offset(field)), \
76 "m" (_proxy_pda.field)); \
77 break; \
78 case 4: \
79 asm(op "l %%fs:%c1,%0" \
80 : "=r" (ret__) \
81 : "i" (pda_offset(field)), \
82 "m" (_proxy_pda.field)); \
83 break; \
84 default: __bad_pda_field(); \
85 } \
86 ret__; })
87
88/* Return a pointer to a pda field */
89#define pda_addr(field) \
90 ((typeof(_proxy_pda.field) *)((unsigned char *)read_pda(_pda) + \
91 pda_offset(field)))
92
93#define read_pda(field) pda_from_op("mov",field)
94#define write_pda(field,val) pda_to_op("mov",field,val)
95#define add_pda(field,val) pda_to_op("add",field,val)
96#define sub_pda(field,val) pda_to_op("sub",field,val)
97#define or_pda(field,val) pda_to_op("or",field,val)
98
99#endif /* _I386_PDA_H */