lkml.org 
[lkml]   [2006]   [Aug]   [27]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[PATCH RFC 1/6] 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>
    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>

    ---
    arch/i386/kernel/asm-offsets.c | 4 ++
    arch/i386/kernel/head.S | 2 -
    include/asm-i386/pda.h | 67 ++++++++++++++++++++++++++++++++++++++++
    include/asm-i386/segment.h | 5 ++
    4 files changed, 76 insertions(+), 2 deletions(-)


    ===================================================================
    --- a/arch/i386/kernel/asm-offsets.c
    +++ b/arch/i386/kernel/asm-offsets.c
    @@ -15,6 +15,7 @@
    #include <asm/processor.h>
    #include <asm/thread_info.h>
    #include <asm/elf.h>
    +#include <asm/pda.h>

    #define DEFINE(sym, val) \
    asm volatile("\n->" #sym " %0 " #val : : "i" (val))
    @@ -74,4 +75,7 @@ void foo(void)
    DEFINE(VDSO_PRELINK, VDSO_PRELINK);

    OFFSET(crypto_tfm_ctx_offset, crypto_tfm, __crt_ctx);
    +
    + BLANK();
    + OFFSET(PDA_pcurrent, i386_pda, pcurrent);
    }
    ===================================================================
    --- a/arch/i386/kernel/head.S
    +++ b/arch/i386/kernel/head.S
    @@ -591,7 +591,7 @@ ENTRY(cpu_gdt_table)
    .quad 0x004092000000ffff /* 0xc8 APM DS data */

    .quad 0x0000920000000000 /* 0xd0 - ESPFIX 16-bit SS */
    - .quad 0x0000000000000000 /* 0xd8 - unused */
    + .quad 0x0000000000000000 /* 0xd8 - PDA */
    .quad 0x0000000000000000 /* 0xe0 - unused */
    .quad 0x0000000000000000 /* 0xe8 - unused */
    .quad 0x0000000000000000 /* 0xf0 - unused */
    ===================================================================
    --- a/include/asm-i386/segment.h
    +++ b/include/asm-i386/segment.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
    @@ -73,6 +73,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

    ===================================================================
    --- /dev/null
    +++ b/include/asm-i386/pda.h
    @@ -0,0 +1,67 @@
    +#ifndef _I386_PDA_H
    +#define _I386_PDA_H
    +
    +struct i386_pda
    +{
    + struct task_struct *pcurrent; /* current process */
    + int cpu_number;
    +};
    +
    +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);
    +
    +extern struct i386_pda _proxy_pda;
    +
    +#define pda_to_op(op,field,val) \
    + do { \
    + typedef typeof(_proxy_pda.field) T__; \
    + switch (sizeof(_proxy_pda.field)) { \
    + case 2: \
    + asm(op "w %1,%%gs:%P2" \
    + : "=m" (_proxy_pda.field) \
    + :"ri" ((T__)val), \
    + "i"(pda_offset(field))); \
    + break; \
    + case 4: \
    + asm(op "l %1,%%gs:%P2" \
    + : "=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 2: \
    + asm(op "w %%gs:%P1,%0" \
    + : "=r" (ret__) \
    + : "i" (pda_offset(field)), \
    + "m" (_proxy_pda.field)); \
    + break; \
    + case 4: \
    + asm(op "l %%gs:%P1,%0" \
    + : "=r" (ret__) \
    + : "i" (pda_offset(field)), \
    + "m" (_proxy_pda.field)); \
    + break; \
    + default: __bad_pda_field(); \
    + } \
    + ret__; })
    +
    +
    +#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 */
    --

    -
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

    \
     
     \ /
      Last update: 2006-08-27 11:29    [W:0.044 / U:0.144 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site