[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:
parent
eb5b7b9d86
commit
9ca36101a8
|
@ -585,7 +585,7 @@ ENTRY(cpu_gdt_table)
|
||||||
.quad 0x004092000000ffff /* 0xc8 APM DS data */
|
.quad 0x004092000000ffff /* 0xc8 APM DS data */
|
||||||
|
|
||||||
.quad 0x00c0920000000000 /* 0xd0 - ESPFIX SS */
|
.quad 0x00c0920000000000 /* 0xd0 - ESPFIX SS */
|
||||||
.quad 0x0000000000000000 /* 0xd8 - unused */
|
.quad 0x0000000000000000 /* 0xd8 - PDA */
|
||||||
.quad 0x0000000000000000 /* 0xe0 - unused */
|
.quad 0x0000000000000000 /* 0xe0 - unused */
|
||||||
.quad 0x0000000000000000 /* 0xe8 - unused */
|
.quad 0x0000000000000000 /* 0xe8 - unused */
|
||||||
.quad 0x0000000000000000 /* 0xf0 - unused */
|
.quad 0x0000000000000000 /* 0xf0 - unused */
|
||||||
|
|
95
include/asm-i386/pda.h
Normal file
95
include/asm-i386/pda.h
Normal file
|
@ -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
|
* 25 - APM BIOS support
|
||||||
*
|
*
|
||||||
* 26 - ESPFIX small SS
|
* 26 - ESPFIX small SS
|
||||||
* 27 - unused
|
* 27 - PDA [ per-cpu private data area ]
|
||||||
* 28 - unused
|
* 28 - unused
|
||||||
* 29 - unused
|
* 29 - unused
|
||||||
* 30 - unused
|
* 30 - unused
|
||||||
|
@ -74,6 +74,9 @@
|
||||||
#define GDT_ENTRY_ESPFIX_SS (GDT_ENTRY_KERNEL_BASE + 14)
|
#define GDT_ENTRY_ESPFIX_SS (GDT_ENTRY_KERNEL_BASE + 14)
|
||||||
#define __ESPFIX_SS (GDT_ENTRY_ESPFIX_SS * 8)
|
#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
|
#define GDT_ENTRY_DOUBLEFAULT_TSS 31
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
Loading…
Reference in a new issue