From 01e03d706ed94a6510f1db7b349248fc1482cd9b Mon Sep 17 00:00:00 2001 From: Stephen Tweedie Date: Tue, 11 Mar 2008 18:05:30 +0000 Subject: [PATCH] xen execshield: Add xen-specific load_user_cs_desc() x86 32-bit execshield uses load_user_cs_desc() to setup the user CS descriptor, but the Xen version needs to do this via a hypercall. Add this via a new pv_cpu_ops->load_user_cs_desc pv_ops indirection so that it can be selected appropriately at run-time. Signed-off-by: Stephen Tweedie --- arch/x86/kernel/paravirt.c | 1 + arch/x86/xen/enlighten.c | 17 +++++++++++++++++ include/asm-x86/desc.h | 8 ++++++-- include/asm-x86/paravirt.h | 6 ++++++ 4 files changed, 30 insertions(+), 2 deletions(-) diff --git a/arch/x86/kernel/paravirt.c b/arch/x86/kernel/paravirt.c index 075962c..d59db07 100644 --- a/arch/x86/kernel/paravirt.c +++ b/arch/x86/kernel/paravirt.c @@ -331,6 +331,7 @@ struct pv_cpu_ops pv_cpu_ops = { .read_tscp = native_read_tscp, .load_tr_desc = native_load_tr_desc, .set_ldt = native_set_ldt, + .load_user_cs_desc = native_load_user_cs_desc, .load_gdt = native_load_gdt, .load_idt = native_load_idt, .store_gdt = native_store_gdt, diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c index 27ee26a..66ffdb2 100644 --- a/arch/x86/xen/enlighten.c +++ b/arch/x86/xen/enlighten.c @@ -290,6 +290,22 @@ static void xen_set_ldt(const void *addr, unsigned entries) xen_mc_issue(PARAVIRT_LAZY_CPU); } +static inline void xen_load_user_cs_desc(int cpu, struct mm_struct *mm) +{ + void *gdt; + xmaddr_t mgdt; + u64 descriptor; + struct desc_struct user_cs; + + gdt = &get_cpu_gdt_table(cpu)[GDT_ENTRY_DEFAULT_USER_CS]; + mgdt = virt_to_machine(gdt); + + user_cs = mm->context.user_cs; + descriptor = (u64) user_cs.a | ((u64) user_cs.b) << 32; + + HYPERVISOR_update_descriptor(mgdt.maddr, descriptor); +} + static void xen_load_gdt(const struct desc_ptr *dtr) { unsigned long *frames; @@ -998,6 +1014,7 @@ static const struct pv_cpu_ops xen_cpu_ops __initdata = { .load_tr_desc = paravirt_nop, .set_ldt = xen_set_ldt, + .load_user_cs_desc = xen_load_user_cs_desc, .load_gdt = xen_load_gdt, .load_idt = xen_load_idt, .load_tls = xen_load_tls, diff --git a/include/asm-x86/desc.h b/include/asm-x86/desc.h index 7ad80b9..ec3a84a 100644 --- a/include/asm-x86/desc.h +++ b/include/asm-x86/desc.h @@ -6,6 +6,7 @@ #include #include #include +#include static inline void fill_ldt(struct desc_struct *desc, const struct user_desc *info) @@ -94,6 +95,7 @@ static inline int desc_empty(const void *ptr) #define load_TLS(t, cpu) native_load_tls(t, cpu) #define set_ldt native_set_ldt +#define load_user_cs_desc native_load_user_cs_desc #define write_ldt_entry(dt, entry, desc) \ native_write_ldt_entry(dt, entry, desc) @@ -360,8 +362,10 @@ static inline void set_user_cs(struct desc_struct *desc, unsigned long limit) desc->b = (limit & 0xf0000) | 0x00c0fb00; } -#define load_user_cs_desc(cpu, mm) \ - get_cpu_gdt_table(cpu)[GDT_ENTRY_DEFAULT_USER_CS] = (mm)->context.user_cs +static inline void native_load_user_cs_desc(int cpu, struct mm_struct *mm) +{ + get_cpu_gdt_table(cpu)[GDT_ENTRY_DEFAULT_USER_CS] = mm->context.user_cs; +} #ifdef CONFIG_X86_32 extern void arch_add_exec_range(struct mm_struct *mm, unsigned long limit); diff --git a/include/asm-x86/paravirt.h b/include/asm-x86/paravirt.h index d6236eb..ff8d218 100644 --- a/include/asm-x86/paravirt.h +++ b/include/asm-x86/paravirt.h @@ -113,6 +113,7 @@ struct pv_cpu_ops { void (*store_gdt)(struct desc_ptr *); void (*store_idt)(struct desc_ptr *); void (*set_ldt)(const void *desc, unsigned entries); + void (*load_user_cs_desc)(int cpu, struct mm_struct *mm); unsigned long (*store_tr)(void); void (*load_tls)(struct thread_struct *t, unsigned int cpu); void (*write_ldt_entry)(struct desc_struct *ldt, int entrynum, @@ -754,6 +755,11 @@ static inline void set_ldt(const void *addr, unsigned entries) { PVOP_VCALL2(pv_cpu_ops.set_ldt, addr, entries); } +static inline void load_user_cs_desc(unsigned int cpu, + struct mm_struct *mm) +{ + PVOP_VCALL2(pv_cpu_ops.load_user_cs_desc, cpu, mm); +} static inline void store_gdt(struct desc_ptr *dtr) { PVOP_VCALL1(pv_cpu_ops.store_gdt, dtr); -- 1.5.4.1