--- zzzz-none-000/linux-2.6.19.2/include/asm-i386/desc.h 2007-01-10 19:10:37.000000000 +0000 +++ davinci-8020-5505/linux-2.6.19.2/include/asm-i386/desc.h 2007-01-19 14:42:56.000000000 +0000 @@ -10,11 +10,13 @@ #include #include -#include +#include #include +#include +#include -extern struct desc_struct cpu_gdt_table[GDT_ENTRIES]; +extern struct desc_struct cpu_gdt_table[NR_CPUS][PAGE_SIZE / sizeof(struct desc_struct)]; DECLARE_PER_CPU(unsigned char, cpu_16bit_stack[CPU_16BIT_STACK_SIZE]); @@ -24,20 +26,33 @@ unsigned short pad; } __attribute__ ((packed)); -extern struct Xgt_desc_struct idt_descr; -DECLARE_PER_CPU(struct Xgt_desc_struct, cpu_gdt_descr); - +extern struct Xgt_desc_struct idt_descr, cpu_gdt_descr[NR_CPUS]; static inline struct desc_struct *get_cpu_gdt_table(unsigned int cpu) { - return (struct desc_struct *)per_cpu(cpu_gdt_descr, cpu).address; + return cpu_gdt_table[cpu]; } +#define pax_open_kernel(cr0) \ +do { \ + typecheck(unsigned long,cr0); \ + preempt_disable(); \ + cr0 = read_cr0(); \ + write_cr0(cr0 & ~0x10000UL); \ +} while(0) + +#define pax_close_kernel(cr0) \ +do { \ + typecheck(unsigned long,cr0); \ + write_cr0(cr0); \ + preempt_enable_no_resched(); \ +} while(0) + /* * This is the ldt that every process will get unless we need * something other than this. */ -extern struct desc_struct default_ldt[]; +extern const struct desc_struct default_ldt[]; extern struct desc_struct idt_table[]; extern void set_intr_gate(unsigned int irq, void * addr); @@ -91,8 +106,20 @@ static inline void write_dt_entry(void *dt, int entry, __u32 entry_a, __u32 entry_b) { __u32 *lp = (__u32 *)((char *)dt + entry*8); + +#ifdef CONFIG_PAX_KERNEXEC + unsigned long cr0; + + pax_open_kernel(cr0); +#endif + *lp = entry_a; *(lp+1) = entry_b; + +#ifdef CONFIG_PAX_KERNEXEC + pax_close_kernel(cr0); +#endif + } #define write_ldt_entry(dt, entry, a, b) write_dt_entry(dt, entry, a, b) @@ -115,7 +142,7 @@ write_gdt_entry(get_cpu_gdt_table(cpu), entry, a, b); } -static inline void set_ldt_desc(unsigned int cpu, void *addr, unsigned int entries) +static inline void set_ldt_desc(unsigned int cpu, const void *addr, unsigned int entries) { __u32 a, b; pack_descriptor(&a, &b, (unsigned long)addr, @@ -139,7 +166,7 @@ ((info)->seg_32bit << 22) | \ ((info)->limit_in_pages << 23) | \ ((info)->useable << 20) | \ - 0x7000) + 0x7100) #define LDT_empty(info) (\ (info)->base_addr == 0 && \ @@ -165,7 +192,7 @@ */ static inline void load_LDT_nolock(mm_context_t *pc, int cpu) { - void *segments = pc->ldt; + const void *segments = pc->ldt; int count = pc->size; if (likely(!count)) { @@ -184,15 +211,25 @@ put_cpu(); } -static inline unsigned long get_desc_base(unsigned long *desc) +static inline unsigned long get_desc_base(struct desc_struct *desc) { unsigned long base; - base = ((desc[0] >> 16) & 0x0000ffff) | - ((desc[1] << 16) & 0x00ff0000) | - (desc[1] & 0xff000000); + base = ((desc->a >> 16) & 0x0000ffff) | + ((desc->b << 16) & 0x00ff0000) | + (desc->b & 0xff000000); return base; } +static inline void set_user_cs(struct mm_struct *mm, int cpu) +{ +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC) + __u32 a, b; + + pack_descriptor(&a, &b, mm->context.user_cs_base, mm->context.user_cs_limit - 1, 0xFB, 0xC); + write_gdt_entry(get_cpu_gdt_table(cpu), GDT_ENTRY_DEFAULT_USER_CS, a, b); +#endif +} + #endif /* !__ASSEMBLY__ */ #endif