[PATCH] i386: Basic definitions for i386-pda
This patch has the basic definitions of struct i386_pda, and the segment selector in the GDT. asm-i386/pda.h is more or less a direct copy of asm-x86_64/pda.h. The most interesting difference is the use of _proxy_pda, which is used to give gcc a model for the actual memory operations on the real pda structure. No actual reference is ever made to _proxy_pda, so it is never defined. Signed-off-by: Jeremy Fitzhardinge <jeremy@xensource.com> Signed-off-by: Andi Kleen <ak@suse.de> Cc: Chuck Ebbert <76306.1226@compuserve.com> Cc: Zachary Amsden <zach@vmware.com> Cc: Jan Beulich <jbeulich@novell.com> Cc: Andi Kleen <ak@suse.de> Signed-off-by: Andrew Morton <akpm@osdl.org>
This commit is contained in:
Родитель
eb5b7b9d86
Коммит
9ca36101a8
|
@ -585,7 +585,7 @@ ENTRY(cpu_gdt_table)
|
|||
.quad 0x004092000000ffff /* 0xc8 APM DS data */
|
||||
|
||||
.quad 0x00c0920000000000 /* 0xd0 - ESPFIX SS */
|
||||
.quad 0x0000000000000000 /* 0xd8 - unused */
|
||||
.quad 0x0000000000000000 /* 0xd8 - PDA */
|
||||
.quad 0x0000000000000000 /* 0xe0 - unused */
|
||||
.quad 0x0000000000000000 /* 0xe8 - unused */
|
||||
.quad 0x0000000000000000 /* 0xf0 - unused */
|
||||
|
|
|
@ -0,0 +1,95 @@
|
|||
/*
|
||||
Per-processor Data Areas
|
||||
Jeremy Fitzhardinge <jeremy@goop.org> 2006
|
||||
Based on asm-x86_64/pda.h by Andi Kleen.
|
||||
*/
|
||||
#ifndef _I386_PDA_H
|
||||
#define _I386_PDA_H
|
||||
|
||||
#include <linux/stddef.h>
|
||||
|
||||
struct i386_pda
|
||||
{
|
||||
struct i386_pda *_pda; /* pointer to self */
|
||||
};
|
||||
|
||||
extern struct i386_pda *_cpu_pda[];
|
||||
|
||||
#define cpu_pda(i) (_cpu_pda[i])
|
||||
|
||||
#define pda_offset(field) offsetof(struct i386_pda, field)
|
||||
|
||||
extern void __bad_pda_field(void);
|
||||
|
||||
/* This variable is never instantiated. It is only used as a stand-in
|
||||
for the real per-cpu PDA memory, so that gcc can understand what
|
||||
memory operations the inline asms() below are performing. This
|
||||
eliminates the need to make the asms volatile or have memory
|
||||
clobbers, so gcc can readily analyse them. */
|
||||
extern struct i386_pda _proxy_pda;
|
||||
|
||||
#define pda_to_op(op,field,val) \
|
||||
do { \
|
||||
typedef typeof(_proxy_pda.field) T__; \
|
||||
if (0) { T__ tmp__; tmp__ = (val); } \
|
||||
switch (sizeof(_proxy_pda.field)) { \
|
||||
case 1: \
|
||||
asm(op "b %1,%%gs:%c2" \
|
||||
: "+m" (_proxy_pda.field) \
|
||||
:"ri" ((T__)val), \
|
||||
"i"(pda_offset(field))); \
|
||||
break; \
|
||||
case 2: \
|
||||
asm(op "w %1,%%gs:%c2" \
|
||||
: "+m" (_proxy_pda.field) \
|
||||
:"ri" ((T__)val), \
|
||||
"i"(pda_offset(field))); \
|
||||
break; \
|
||||
case 4: \
|
||||
asm(op "l %1,%%gs:%c2" \
|
||||
: "+m" (_proxy_pda.field) \
|
||||
:"ri" ((T__)val), \
|
||||
"i"(pda_offset(field))); \
|
||||
break; \
|
||||
default: __bad_pda_field(); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define pda_from_op(op,field) \
|
||||
({ \
|
||||
typeof(_proxy_pda.field) ret__; \
|
||||
switch (sizeof(_proxy_pda.field)) { \
|
||||
case 1: \
|
||||
asm(op "b %%gs:%c1,%0" \
|
||||
: "=r" (ret__) \
|
||||
: "i" (pda_offset(field)), \
|
||||
"m" (_proxy_pda.field)); \
|
||||
break; \
|
||||
case 2: \
|
||||
asm(op "w %%gs:%c1,%0" \
|
||||
: "=r" (ret__) \
|
||||
: "i" (pda_offset(field)), \
|
||||
"m" (_proxy_pda.field)); \
|
||||
break; \
|
||||
case 4: \
|
||||
asm(op "l %%gs:%c1,%0" \
|
||||
: "=r" (ret__) \
|
||||
: "i" (pda_offset(field)), \
|
||||
"m" (_proxy_pda.field)); \
|
||||
break; \
|
||||
default: __bad_pda_field(); \
|
||||
} \
|
||||
ret__; })
|
||||
|
||||
/* Return a pointer to a pda field */
|
||||
#define pda_addr(field) \
|
||||
((typeof(_proxy_pda.field) *)((unsigned char *)read_pda(_pda) + \
|
||||
pda_offset(field)))
|
||||
|
||||
#define read_pda(field) pda_from_op("mov",field)
|
||||
#define write_pda(field,val) pda_to_op("mov",field,val)
|
||||
#define add_pda(field,val) pda_to_op("add",field,val)
|
||||
#define sub_pda(field,val) pda_to_op("sub",field,val)
|
||||
#define or_pda(field,val) pda_to_op("or",field,val)
|
||||
|
||||
#endif /* _I386_PDA_H */
|
|
@ -39,7 +39,7 @@
|
|||
* 25 - APM BIOS support
|
||||
*
|
||||
* 26 - ESPFIX small SS
|
||||
* 27 - unused
|
||||
* 27 - PDA [ per-cpu private data area ]
|
||||
* 28 - unused
|
||||
* 29 - unused
|
||||
* 30 - unused
|
||||
|
@ -74,6 +74,9 @@
|
|||
#define GDT_ENTRY_ESPFIX_SS (GDT_ENTRY_KERNEL_BASE + 14)
|
||||
#define __ESPFIX_SS (GDT_ENTRY_ESPFIX_SS * 8)
|
||||
|
||||
#define GDT_ENTRY_PDA (GDT_ENTRY_KERNEL_BASE + 15)
|
||||
#define __KERNEL_PDA (GDT_ENTRY_PDA * 8)
|
||||
|
||||
#define GDT_ENTRY_DOUBLEFAULT_TSS 31
|
||||
|
||||
/*
|
||||
|
|
Загрузка…
Ссылка в новой задаче