4 #include <linux/cache.h>
6 /* Per processor datastructure. %gs points to it while the kernel runs */
7 /* To use a new field with the *_pda macros it needs to be added to tools/offset.c */
9 unsigned long kernelstack; /* TOS for current process */
10 unsigned long oldrsp; /* user rsp for system call */
11 unsigned long irqrsp; /* Old rsp for interrupts. */
12 struct task_struct *pcurrent; /* Current process */
13 int irqcount; /* Irq nesting counter. Starts with -1 */
14 int cpunumber; /* Logical CPU number */
15 /* XXX: could be a single list */
16 unsigned long *pgd_quick;
17 unsigned long *pmd_quick;
18 unsigned long *pte_quick;
19 unsigned long pgtable_cache_sz;
20 char *irqstackptr; /* top of irqstack */
21 unsigned long volatile *level4_pgt;
22 } ____cacheline_aligned;
24 #define PDA_STACKOFFSET (5*8)
26 #define IRQSTACK_ORDER 2
27 #define IRQSTACKSIZE (PAGE_SIZE << IRQSTACK_ORDER)
29 extern struct x8664_pda cpu_pda[];
32 * There is no fast way to get the base address of the PDA, all the accesses
33 * have to mention %fs/%gs. So it needs to be done this Torvaldian way.
35 #define sizeof_field(type,field) (sizeof(((type *)0)->field))
36 #define typeof_field(type,field) typeof(((type *)0)->field)
38 extern void __bad_pda_field(void);
39 /* Don't use offsetof because it requires too much infrastructure */
40 #define pda_offset(field) ((unsigned long)&((struct x8664_pda *)0)->field)
42 #define pda_to_op(op,field,val) do { \
43 switch (sizeof_field(struct x8664_pda, field)) { \
44 case 2: asm volatile(op "w %0,%%gs:%P1" :: "r" (val), "i"(pda_offset(field)):"memory"); break; \
45 case 4: asm volatile(op "l %0,%%gs:%P1" :: "r" (val), "i"(pda_offset(field)):"memory"); break; \
46 case 8: asm volatile(op "q %0,%%gs:%P1" :: "r" (val), "i"(pda_offset(field)):"memory"); break; \
47 default: __bad_pda_field(); \
52 #define pda_from_op(op,field) ({ \
53 typedef typeof_field(struct x8664_pda, field) T__; T__ ret__; \
54 switch (sizeof_field(struct x8664_pda, field)) { \
55 case 2: asm volatile(op "w %%gs:%P1,%0":"=r" (ret__): "i" (pda_offset(field)):"memory"); break; \
56 case 4: asm volatile(op "l %%gs:%P1,%0":"=r" (ret__): "i" (pda_offset(field)):"memory"); break; \
57 case 8: asm volatile(op "q %%gs:%P1,%0":"=r" (ret__): "i" (pda_offset(field)):"memory"); break; \
58 default: __bad_pda_field(); \
63 #define read_pda(field) pda_from_op("mov",field)
64 #define write_pda(field,val) pda_to_op("mov",field,val)
65 #define add_pda(field,val) pda_to_op("add",field,val)
66 #define sub_pda(field,val) pda_to_op("sub",field,val)