desc_struct integration
Subsystems (6)
PATCH 2/19 unify struct desc_ptr
In reply to Glauber de Oliveira CostaThis patch unifies struct desc_ptr between i386 and x86_64. They can be expressed in the exact same way in C code, only having to change the name of one of them. As Xgt_desc_struct is ugly and big, this is the one that goes away.
There's also a padding field in i386, but it is not really needed in the C structure definition.
--- arch/x86/kernel/asm-offsets_32.c | 5 ++--- arch/x86/kernel/cpu/common.c | 2 +- arch/x86/kernel/doublefault_32.c | 2 +- arch/x86/kernel/efi_32.c | 4 ++-- arch/x86/kernel/machine_kexec_32.c | 4 ++-- arch/x86/kernel/reboot_32.c | 2 +- arch/x86/lguest/boot.c | 4 ++-- arch/x86/xen/enlighten.c | 10 +++++----- drivers/kvm/svm.c | 2 +- include/asm-x86/desc_32.h | 16 +++++----------- include/asm-x86/lguest.h | 8 ++++---- include/asm-x86/paravirt.h | 18 +++++++++--------- include/asm-x86/processor_32.h | 2 +- include/asm-x86/suspend_32.h | 4 ++-- 14 files changed, 38 insertions(+), 45 deletions(-)
arch/x86/kernel/asm-offsets_32.c +2 -3
@@ -70,9 +70,8 @@ void foo(void)OFFSET (TI_cpu, thread_info, cpu);BLANK (); -OFFSET (GDS_size, Xgt_desc_struct, size); -OFFSET (GDS_address, Xgt_desc_struct, address); -OFFSET (GDS_pad, Xgt_desc_struct, pad); +OFFSET (GDS_size, desc_ptr, size); +OFFSET (GDS_address, desc_ptr, address);BLANK ();OFFSET (PT_EBX , pt_regs, bx);
arch/x86/kernel/cpu/common.c +1 -1
@@ -649,7 +649,7 @@ struct pt_regs * __devinit idle_regs(str* it's on the real one. */ void switch_to_new_gdt (void ) { -struct Xgt_desc_struct gdt_descr; +struct desc_ptr gdt_descr; gdt_descr.address = (long )get_cpu_gdt_table (smp_processor_id ()); gdt_descr.size =GDT_SIZE -1 ;
arch/x86/kernel/doublefault_32.c +1 -1
@@ -17,7 +17,7 @@ static unsigned long doublefault_stack[Dstatic void doublefault_fn (void ) { -struct Xgt_desc_struct gdt_desc = {0 ,0 }; +struct desc_ptr gdt_desc = {0 ,0 };unsigned long gdt, tss;store_gdt (&gdt_desc);
arch/x86/kernel/efi_32.c +2 -2
@@ -69,7 +69,7 @@ static void efi_call_phys_prelog(void) _ {unsigned long cr4;unsigned long temp; -struct Xgt_desc_struct gdt_descr; +struct desc_ptr gdt_descr;spin_lock (&efi_rt_lock);local_irq_save (efi_rt_eflags);
@@ -111,7 +111,7 @@ static void efi_call_phys_prelog(void) _static void efi_call_phys_epilog (void )__releases (efi_rt_lock) {unsigned long cr4; -struct Xgt_desc_struct gdt_descr; +struct desc_ptr gdt_descr; gdt_descr.address = (unsigned long )get_cpu_gdt_table (0 ); gdt_descr.size =GDT_SIZE -1 ;
arch/x86/kernel/machine_kexec_32.c +2 -2
@@ -32,7 +32,7 @@ static u32 kexec_pte1[1024] PAGE_ALIGNEDstatic void set_idt (void *newidt,__u16 limit) { -struct Xgt_desc_struct curidt; +struct desc_ptr curidt;/* ia32 supports unaliged loads & stores */ curidt.size = limit;
@@ -44,7 +44,7 @@ static void set_idt(void *newidt, __u16static void set_gdt (void *newgdt,__u16 limit) { -struct Xgt_desc_struct curgdt; +struct desc_ptr curgdt;/* ia32 supports unaligned loads & stores */ curgdt.size = limit;
arch/x86/kernel/reboot_32.c +1 -1
@@ -161,7 +161,7 @@ real_mode_gdt_entries [3] = 0x000092000100ffffULL /* 16-bit real-mode 64k data at 0x00000100 */ }; -static struct Xgt_desc_struct +static struct desc_ptr real_mode_gdt = {sizeof (real_mode_gdt_entries) -1 , (long )real_mode_gdt_entries }, real_mode_idt = {0x3ff ,0 }, no_idt = {0 ,0 };
arch/x86/lguest/boot.c +2 -2
@@ -229,7 +229,7 @@ static void lguest_write_idt_entry(struc/* Changing to a different IDT is very rare: we keep the IDT up-to-date every * time it is written, so we can simply loop through all entries and tell the * Host about them. */ -static void lguest_load_idt (const struct Xgt_desc_struct *desc) +static void lguest_load_idt (const struct desc_ptr *desc) {unsigned int i;struct desc_struct *idt = (void *)desc->address;
@@ -252,7 +252,7 @@ static void lguest_load_idt(const struct* hypercall and use that repeatedly to load a new IDT. I don't think it * really matters, but wouldn't it be nice if they were the same? */ -static void lguest_load_gdt (const struct Xgt_desc_struct *desc) +static void lguest_load_gdt (const struct desc_ptr *desc) {BUG_ON ((desc->size+1 )/8 !=GDT_ENTRIES );hcall (LHCALL_LOAD_GDT ,__pa (desc->address),GDT_ENTRIES ,0 );
arch/x86/xen/enlighten.c +5 -5
@@ -295,7 +295,7 @@ static void xen_set_ldt(const void *addrxen_mc_issue (PARAVIRT_LAZY_CPU ); } -static void xen_load_gdt (const struct Xgt_desc_struct *dtr) +static void xen_load_gdt (const struct desc_ptr *dtr) {unsigned long *frames;unsigned long va = dtr->address;
@@ -395,7 +395,7 @@ static int cvt_gate_to_trap(int vector, }/* Locations of each CPU's IDT */ -static DEFINE_PER_CPU(struct Xgt_desc_struct, idt_desc); +static DEFINE_PER_CPU(struct desc_ptr, idt_desc);/* Set an IDT entry. If the entry is part of the current IDT, then also update Xen. */
@@ -427,7 +427,7 @@ static void xen_write_idt_entry(struct dpreempt_enable (); } -static void xen_convert_trap_info (const struct Xgt_desc_struct *desc, +static void xen_convert_trap_info (const struct desc_ptr *desc,struct trap_info *traps) {unsigned in, out, count;
@@ -446,7 +446,7 @@ static void xen_convert_trap_info(constvoid xen_copy_trap_info (struct trap_info *traps) { -const struct Xgt_desc_struct *desc = &__get_cpu_var (idt_desc); +const struct desc_ptr *desc = &__get_cpu_var (idt_desc);xen_convert_trap_info (desc, traps); }
@@ -454,7 +454,7 @@ void xen_copy_trap_info(struct trap_info/* Load a new IDT into Xen. In principle this can be per-CPU, so we hold a spinlock to protect the static traps[] array (static because it avoids allocation, and saves stack space). */ -static void xen_load_idt (const struct Xgt_desc_struct *desc) +static void xen_load_idt (const struct desc_ptr *desc) {static DEFINE_SPINLOCK (lock);static struct trap_info traps[257 ];
drivers/kvm/svm.c +1 -1
@@ -290,7 +290,7 @@ static void svm_hardware_enable(void *ga#ifdef CONFIG_X86_64 struct desc_ptr gdt_descr;#else -struct Xgt_desc_struct gdt_descr; +struct desc_ptr gdt_descr;#endif struct desc_struct *gdt;int me =raw_smp_processor_id ();
include/asm-x86/desc_32.h +5 -11
@@ -12,12 +12,6 @@#include <asm/mmu.h> -struct Xgt_desc_struct { -unsigned short size; -unsigned long address __attribute__((packed)); -unsigned short pad; -} __attribute__ ((packed)); -struct gdt_page {struct desc_struct gdt[GDT_ENTRIES ];
@@ -29,7 +23,7 @@ static inline struct desc_struct *get_cpreturn per_cpu (gdt_page, cpu).gdt; } -extern struct Xgt_desc_struct idt_descr; +extern struct desc_ptr idt_descr;extern struct desc_struct idt_table[];extern void set_intr_gate (unsigned int irq,void * addr);
@@ -107,22 +101,22 @@ static inline void native_load_tr_desc(v asmvolatile ("ltr %w0" ::"q" (GDT_ENTRY_TSS *8 )); } -static inline void native_load_gdt (const struct Xgt_desc_struct *dtr) +static inline void native_load_gdt (const struct desc_ptr *dtr) { asmvolatile ("lgdt %0" ::"m" (*dtr)); } -static inline void native_load_idt (const struct Xgt_desc_struct *dtr) +static inline void native_load_idt (const struct desc_ptr *dtr) { asmvolatile ("lidt %0" ::"m" (*dtr)); } -static inline void native_store_gdt (struct Xgt_desc_struct *dtr) +static inline void native_store_gdt (struct desc_ptr *dtr) { asm ("sgdt %0" :"=m" (*dtr)); } -static inline void native_store_idt (struct Xgt_desc_struct *dtr) +static inline void native_store_idt (struct desc_ptr *dtr) { asm ("sidt %0" :"=m" (*dtr)); }
include/asm-x86/lguest.h +4 -4
@@ -44,13 +44,13 @@ struct lguest_ro_state {/* Host information we need to restore when we switch back. */ u32 host_cr3; -struct Xgt_desc_struct host_idt_desc; -struct Xgt_desc_struct host_gdt_desc; +struct desc_ptr host_idt_desc; +struct desc_ptr host_gdt_desc;u32 host_sp;/* Fields which are used when guest is running. */ -struct Xgt_desc_struct guest_idt_desc; -struct Xgt_desc_struct guest_gdt_desc; +struct desc_ptr guest_idt_desc; +struct desc_ptr guest_gdt_desc;struct i386_hw_tss guest_tss;struct desc_struct guest_idt[IDT_ENTRIES ];struct desc_struct guest_gdt[GDT_ENTRIES ];
include/asm-x86/paravirt.h +9 -9
@@ -20,7 +20,7 @@struct page ;struct thread_struct ; -struct Xgt_desc_struct ; +struct desc_ptr ;struct tss_struct ;struct mm_struct ;struct desc_struct ;
@@ -88,10 +88,10 @@ struct pv_cpu_ops {/* Segment descriptor handling */ void (*load_tr_desc)(void ); -void (*load_gdt)(const struct Xgt_desc_struct *); -void (*load_idt)(const struct Xgt_desc_struct *); -void (*store_gdt)(struct Xgt_desc_struct *); -void (*store_idt)(struct Xgt_desc_struct *); +void (*load_gdt)(const struct desc_ptr *); +void (*load_idt)(const struct desc_ptr *); +void (*store_gdt)(struct desc_ptr *); +void (*store_idt)(struct desc_ptr *);void (*set_ldt)(const void *desc,unsigned entries);unsigned long (*store_tr)(void );void (*load_tls)(struct thread_struct *t,unsigned int cpu);
@@ -630,11 +630,11 @@ static inline void load_TR_desc(void) {PVOP_VCALL0 (pv_cpu_ops.load_tr_desc); } -static inline void load_gdt (const struct Xgt_desc_struct *dtr) +static inline void load_gdt (const struct desc_ptr *dtr) {PVOP_VCALL1 (pv_cpu_ops.load_gdt, dtr); } -static inline void load_idt (const struct Xgt_desc_struct *dtr) +static inline void load_idt (const struct desc_ptr *dtr) {PVOP_VCALL1 (pv_cpu_ops.load_idt, dtr); }
@@ -642,11 +642,11 @@ static inline void set_ldt(const void *a {PVOP_VCALL2 (pv_cpu_ops.set_ldt, addr, entries); } -static inline void store_gdt (struct Xgt_desc_struct *dtr) +static inline void store_gdt (struct desc_ptr *dtr) {PVOP_VCALL1 (pv_cpu_ops.store_gdt, dtr); } -static inline void store_idt (struct Xgt_desc_struct *dtr) +static inline void store_idt (struct desc_ptr *dtr) {PVOP_VCALL1 (pv_cpu_ops.store_idt, dtr); }
include/asm-x86/processor_32.h +1 -1
@@ -707,7 +707,7 @@ extern void enable_sep_cpu(void);extern int sysenter_setup (void );/* Defined in head.S */ -extern struct Xgt_desc_struct early_gdt_descr; +extern struct desc_ptr early_gdt_descr;extern void cpu_set_gdt (int );extern void switch_to_new_gdt (void );
include/asm-x86/suspend_32.h +2 -2
@@ -12,8 +12,8 @@ static inline int arch_prepare_suspend(vstruct saved_context {u16 es, fs, gs, ss;unsigned long cr0, cr2, cr3, cr4; -struct Xgt_desc_struct gdt; -struct Xgt_desc_struct idt; +struct desc_ptr gdt; +struct desc_ptr idt;u16 ldt;u16 tss;unsigned long tr;
PATCH 2/19 unify struct desc_ptr
In reply to Glauber de Oliveira CostaThis patch unifies struct desc_ptr between i386 and x86_64. They can be expressed in the exact same way in C code, only having to change the name of one of them. As Xgt_desc_struct is ugly and big, this is the one that goes away.
There's also a padding field in i386, but it is not really needed in the C structure definition.
--- arch/x86/kernel/asm-offsets_32.c | 5 ++--- arch/x86/kernel/cpu/common.c | 2 +- arch/x86/kernel/doublefault_32.c | 2 +- arch/x86/kernel/efi_32.c | 4 ++-- arch/x86/kernel/machine_kexec_32.c | 4 ++-- arch/x86/kernel/reboot_32.c | 2 +- arch/x86/lguest/boot.c | 4 ++-- arch/x86/xen/enlighten.c | 10 +++++----- drivers/kvm/svm.c | 2 +- include/asm-x86/desc_32.h | 16 +++++----------- include/asm-x86/lguest.h | 8 ++++---- include/asm-x86/paravirt.h | 18 +++++++++--------- include/asm-x86/processor_32.h | 2 +- include/asm-x86/suspend_32.h | 4 ++-- 14 files changed, 38 insertions(+), 45 deletions(-)
arch/x86/kernel/asm-offsets_32.c +2 -3
@@ -70,9 +70,8 @@ void foo(void)OFFSET (TI_cpu, thread_info, cpu);BLANK (); -OFFSET (GDS_size, Xgt_desc_struct, size); -OFFSET (GDS_address, Xgt_desc_struct, address); -OFFSET (GDS_pad, Xgt_desc_struct, pad); +OFFSET (GDS_size, desc_ptr, size); +OFFSET (GDS_address, desc_ptr, address);BLANK ();OFFSET (PT_EBX , pt_regs, bx);
arch/x86/kernel/cpu/common.c +1 -1
@@ -649,7 +649,7 @@ struct pt_regs * __devinit idle_regs(str* it's on the real one. */ void switch_to_new_gdt (void ) { -struct Xgt_desc_struct gdt_descr; +struct desc_ptr gdt_descr; gdt_descr.address = (long )get_cpu_gdt_table (smp_processor_id ()); gdt_descr.size =GDT_SIZE -1 ;
arch/x86/kernel/doublefault_32.c +1 -1
@@ -17,7 +17,7 @@ static unsigned long doublefault_stack[Dstatic void doublefault_fn (void ) { -struct Xgt_desc_struct gdt_desc = {0 ,0 }; +struct desc_ptr gdt_desc = {0 ,0 };unsigned long gdt, tss;store_gdt (&gdt_desc);
arch/x86/kernel/efi_32.c +2 -2
@@ -69,7 +69,7 @@ static void efi_call_phys_prelog(void) _ {unsigned long cr4;unsigned long temp; -struct Xgt_desc_struct gdt_descr; +struct desc_ptr gdt_descr;spin_lock (&efi_rt_lock);local_irq_save (efi_rt_eflags);
@@ -111,7 +111,7 @@ static void efi_call_phys_prelog(void) _static void efi_call_phys_epilog (void )__releases (efi_rt_lock) {unsigned long cr4; -struct Xgt_desc_struct gdt_descr; +struct desc_ptr gdt_descr; gdt_descr.address = (unsigned long )get_cpu_gdt_table (0 ); gdt_descr.size =GDT_SIZE -1 ;
arch/x86/kernel/machine_kexec_32.c +2 -2
@@ -32,7 +32,7 @@ static u32 kexec_pte1[1024] PAGE_ALIGNEDstatic void set_idt (void *newidt,__u16 limit) { -struct Xgt_desc_struct curidt; +struct desc_ptr curidt;/* ia32 supports unaliged loads & stores */ curidt.size = limit;
@@ -44,7 +44,7 @@ static void set_idt(void *newidt, __u16static void set_gdt (void *newgdt,__u16 limit) { -struct Xgt_desc_struct curgdt; +struct desc_ptr curgdt;/* ia32 supports unaligned loads & stores */ curgdt.size = limit;
arch/x86/kernel/reboot_32.c +1 -1
@@ -161,7 +161,7 @@ real_mode_gdt_entries [3] = 0x000092000100ffffULL /* 16-bit real-mode 64k data at 0x00000100 */ }; -static struct Xgt_desc_struct +static struct desc_ptr real_mode_gdt = {sizeof (real_mode_gdt_entries) -1 , (long )real_mode_gdt_entries }, real_mode_idt = {0x3ff ,0 }, no_idt = {0 ,0 };
arch/x86/lguest/boot.c +2 -2
@@ -229,7 +229,7 @@ static void lguest_write_idt_entry(struc/* Changing to a different IDT is very rare: we keep the IDT up-to-date every * time it is written, so we can simply loop through all entries and tell the * Host about them. */ -static void lguest_load_idt (const struct Xgt_desc_struct *desc) +static void lguest_load_idt (const struct desc_ptr *desc) {unsigned int i;struct desc_struct *idt = (void *)desc->address;
@@ -252,7 +252,7 @@ static void lguest_load_idt(const struct* hypercall and use that repeatedly to load a new IDT. I don't think it * really matters, but wouldn't it be nice if they were the same? */ -static void lguest_load_gdt (const struct Xgt_desc_struct *desc) +static void lguest_load_gdt (const struct desc_ptr *desc) {BUG_ON ((desc->size+1 )/8 !=GDT_ENTRIES );hcall (LHCALL_LOAD_GDT ,__pa (desc->address),GDT_ENTRIES ,0 );
arch/x86/xen/enlighten.c +5 -5
@@ -295,7 +295,7 @@ static void xen_set_ldt(const void *addrxen_mc_issue (PARAVIRT_LAZY_CPU ); } -static void xen_load_gdt (const struct Xgt_desc_struct *dtr) +static void xen_load_gdt (const struct desc_ptr *dtr) {unsigned long *frames;unsigned long va = dtr->address;
@@ -395,7 +395,7 @@ static int cvt_gate_to_trap(int vector, }/* Locations of each CPU's IDT */ -static DEFINE_PER_CPU(struct Xgt_desc_struct, idt_desc); +static DEFINE_PER_CPU(struct desc_ptr, idt_desc);/* Set an IDT entry. If the entry is part of the current IDT, then also update Xen. */
@@ -427,7 +427,7 @@ static void xen_write_idt_entry(struct dpreempt_enable (); } -static void xen_convert_trap_info (const struct Xgt_desc_struct *desc, +static void xen_convert_trap_info (const struct desc_ptr *desc,struct trap_info *traps) {unsigned in, out, count;
@@ -446,7 +446,7 @@ static void xen_convert_trap_info(constvoid xen_copy_trap_info (struct trap_info *traps) { -const struct Xgt_desc_struct *desc = &__get_cpu_var (idt_desc); +const struct desc_ptr *desc = &__get_cpu_var (idt_desc);xen_convert_trap_info (desc, traps); }
@@ -454,7 +454,7 @@ void xen_copy_trap_info(struct trap_info/* Load a new IDT into Xen. In principle this can be per-CPU, so we hold a spinlock to protect the static traps[] array (static because it avoids allocation, and saves stack space). */ -static void xen_load_idt (const struct Xgt_desc_struct *desc) +static void xen_load_idt (const struct desc_ptr *desc) {static DEFINE_SPINLOCK (lock);static struct trap_info traps[257 ];
drivers/kvm/svm.c +1 -1
@@ -290,7 +290,7 @@ static void svm_hardware_enable(void *ga#ifdef CONFIG_X86_64 struct desc_ptr gdt_descr;#else -struct Xgt_desc_struct gdt_descr; +struct desc_ptr gdt_descr;#endif struct desc_struct *gdt;int me =raw_smp_processor_id ();
include/asm-x86/desc_32.h +5 -11
@@ -12,12 +12,6 @@#include <asm/mmu.h> -struct Xgt_desc_struct { -unsigned short size; -unsigned long address __attribute__((packed)); -unsigned short pad; -} __attribute__ ((packed)); -struct gdt_page {struct desc_struct gdt[GDT_ENTRIES ];
@@ -29,7 +23,7 @@ static inline struct desc_struct *get_cpreturn per_cpu (gdt_page, cpu).gdt; } -extern struct Xgt_desc_struct idt_descr; +extern struct desc_ptr idt_descr;extern struct desc_struct idt_table[];extern void set_intr_gate (unsigned int irq,void * addr);
@@ -107,22 +101,22 @@ static inline void native_load_tr_desc(v asmvolatile ("ltr %w0" ::"q" (GDT_ENTRY_TSS *8 )); } -static inline void native_load_gdt (const struct Xgt_desc_struct *dtr) +static inline void native_load_gdt (const struct desc_ptr *dtr) { asmvolatile ("lgdt %0" ::"m" (*dtr)); } -static inline void native_load_idt (const struct Xgt_desc_struct *dtr) +static inline void native_load_idt (const struct desc_ptr *dtr) { asmvolatile ("lidt %0" ::"m" (*dtr)); } -static inline void native_store_gdt (struct Xgt_desc_struct *dtr) +static inline void native_store_gdt (struct desc_ptr *dtr) { asm ("sgdt %0" :"=m" (*dtr)); } -static inline void native_store_idt (struct Xgt_desc_struct *dtr) +static inline void native_store_idt (struct desc_ptr *dtr) { asm ("sidt %0" :"=m" (*dtr)); }
include/asm-x86/lguest.h +4 -4
@@ -44,13 +44,13 @@ struct lguest_ro_state {/* Host information we need to restore when we switch back. */ u32 host_cr3; -struct Xgt_desc_struct host_idt_desc; -struct Xgt_desc_struct host_gdt_desc; +struct desc_ptr host_idt_desc; +struct desc_ptr host_gdt_desc;u32 host_sp;/* Fields which are used when guest is running. */ -struct Xgt_desc_struct guest_idt_desc; -struct Xgt_desc_struct guest_gdt_desc; +struct desc_ptr guest_idt_desc; +struct desc_ptr guest_gdt_desc;struct i386_hw_tss guest_tss;struct desc_struct guest_idt[IDT_ENTRIES ];struct desc_struct guest_gdt[GDT_ENTRIES ];
include/asm-x86/paravirt.h +9 -9
@@ -20,7 +20,7 @@struct page ;struct thread_struct ; -struct Xgt_desc_struct ; +struct desc_ptr ;struct tss_struct ;struct mm_struct ;struct desc_struct ;
@@ -88,10 +88,10 @@ struct pv_cpu_ops {/* Segment descriptor handling */ void (*load_tr_desc)(void ); -void (*load_gdt)(const struct Xgt_desc_struct *); -void (*load_idt)(const struct Xgt_desc_struct *); -void (*store_gdt)(struct Xgt_desc_struct *); -void (*store_idt)(struct Xgt_desc_struct *); +void (*load_gdt)(const struct desc_ptr *); +void (*load_idt)(const struct desc_ptr *); +void (*store_gdt)(struct desc_ptr *); +void (*store_idt)(struct desc_ptr *);void (*set_ldt)(const void *desc,unsigned entries);unsigned long (*store_tr)(void );void (*load_tls)(struct thread_struct *t,unsigned int cpu);
@@ -630,11 +630,11 @@ static inline void load_TR_desc(void) {PVOP_VCALL0 (pv_cpu_ops.load_tr_desc); } -static inline void load_gdt (const struct Xgt_desc_struct *dtr) +static inline void load_gdt (const struct desc_ptr *dtr) {PVOP_VCALL1 (pv_cpu_ops.load_gdt, dtr); } -static inline void load_idt (const struct Xgt_desc_struct *dtr) +static inline void load_idt (const struct desc_ptr *dtr) {PVOP_VCALL1 (pv_cpu_ops.load_idt, dtr); }
@@ -642,11 +642,11 @@ static inline void set_ldt(const void *a {PVOP_VCALL2 (pv_cpu_ops.set_ldt, addr, entries); } -static inline void store_gdt (struct Xgt_desc_struct *dtr) +static inline void store_gdt (struct desc_ptr *dtr) {PVOP_VCALL1 (pv_cpu_ops.store_gdt, dtr); } -static inline void store_idt (struct Xgt_desc_struct *dtr) +static inline void store_idt (struct desc_ptr *dtr) {PVOP_VCALL1 (pv_cpu_ops.store_idt, dtr); }
include/asm-x86/processor_32.h +1 -1
@@ -707,7 +707,7 @@ extern void enable_sep_cpu(void);extern int sysenter_setup (void );/* Defined in head.S */ -extern struct Xgt_desc_struct early_gdt_descr; +extern struct desc_ptr early_gdt_descr;extern void cpu_set_gdt (int );extern void switch_to_new_gdt (void );
include/asm-x86/suspend_32.h +2 -2
@@ -12,8 +12,8 @@ static inline int arch_prepare_suspend(vstruct saved_context {u16 es, fs, gs, ss;unsigned long cr0, cr2, cr3, cr4; -struct Xgt_desc_struct gdt; -struct Xgt_desc_struct idt; +struct desc_ptr gdt; +struct desc_ptr idt;u16 ldt;u16 tss;unsigned long tr;
PATCH 3/19 change gdt acessor macro name
This patch changes the name of x86_64 macro used to access the per-cpu gdt. It is now equal to the i386 version, which will allow code to be shared.
--- arch/x86/kernel/setup64.c | 2 +- arch/x86/kernel/suspend_64.c | 2 +- arch/x86/kernel/vsyscall_64.c | 2 +- include/asm-x86/desc_64.h | 10 +++++----- 4 files changed, 8 insertions(+), 8 deletions(-)
arch/x86/kernel/setup64.c +1 -1
@@ -228,7 +228,7 @@ void __cpuinit cpu_init (void)* and set up the GDT descriptor: */ if (cpu) -memcpy (cpu_gdt (cpu), cpu_gdt_table,GDT_SIZE ); +memcpy (get_cpu_gdt_table (cpu), cpu_gdt_table,GDT_SIZE ); cpu_gdt_descr[cpu].size =GDT_SIZE ;load_gdt ((const struct desc_ptr *)&cpu_gdt_descr[cpu]);
arch/x86/kernel/suspend_64.c +1 -1
@@ -118,7 +118,7 @@ void fix_processor_context(void)set_tss_desc (cpu,t);/* This just modifies memory; should not be necessary. But... This is necessary, because 386 hardware has concept of busy TSS or some similar stupidity. */ -cpu_gdt (cpu)[GDT_ENTRY_TSS ].type =9 ; +get_cpu_gdt_table (cpu)[GDT_ENTRY_TSS ].type =9 ;syscall_init ();/* This sets MSR_*STAR and related */ load_TR_desc ();/* This does ltr */
arch/x86/kernel/vsyscall_64.c +1 -1
@@ -297,7 +297,7 @@ static void __cpuinit vsyscall_set_cpu(i/* Store cpu number in limit so that it can be loaded quickly in user space in vgetcpu. 12 bits for the CPU and 8 bits for the node. */ - d = (unsigned long *)(cpu_gdt (cpu) +GDT_ENTRY_PER_CPU ); + d = (unsigned long *)(get_cpu_gdt_table (cpu) +GDT_ENTRY_PER_CPU ); *d =0x0f40000000000ULL ; *d |= cpu; *d |= (node &0xf ) <<12 ;
include/asm-x86/desc_64.h +5 -5
@@ -48,7 +48,7 @@ static inline void write_ldt_entry(struc }/* the cpu gdt accessor */ -#define cpu_gdt (_cpu) ((struct desc_struct *)cpu_gdt_descr[_cpu].address) +#define get_cpu_gdt_table (x) ((struct desc_struct *)cpu_gdt_descr[x].address)static inline void load_gdt (const struct desc_ptr *ptr) {
@@ -141,15 +141,15 @@ static inline void set_tss_desc(unsigned* -1? seg base+limit should be pointing to the address of the * last valid byte */ -set_tssldt_descriptor (&cpu_gdt (cpu)[GDT_ENTRY_TSS ], +set_tssldt_descriptor (&get_cpu_gdt_table (cpu)[GDT_ENTRY_TSS ], (unsigned long )addr,DESC_TSS ,IO_BITMAP_OFFSET +IO_BITMAP_BYTES +sizeof (unsigned long ) -1 ); }static inline void set_ldt_desc (unsigned cpu,void *addr,int size) { -set_tssldt_descriptor (&cpu_gdt (cpu)[GDT_ENTRY_LDT ], (unsigned long )addr, -DESC_LDT , size *8 -1 ); +set_tssldt_descriptor (&get_cpu_gdt_table (cpu)[GDT_ENTRY_LDT ], + (unsigned long )addr,DESC_LDT , size *8 -1 ); }#define LDT_entry_a (info) \
@@ -183,7 +183,7 @@ static inline void set_ldt_desc(unsignedstatic inline void load_TLS (struct thread_struct *t,unsigned int cpu) {unsigned int i; -u64 *gdt = (u64 *)(cpu_gdt (cpu) +GDT_ENTRY_TLS_MIN ); +u64 *gdt = (u64 *)(get_cpu_gdt_table (cpu) +GDT_ENTRY_TLS_MIN );for (i =0 ; i <GDT_ENTRY_TLS_ENTRIES ; i++) gdt[i] = t->tls_array[i];
PATCH 3/19 change gdt acessor macro name
In reply to Glauber de Oliveira CostaThis patch changes the name of x86_64 macro used to access the per-cpu gdt. It is now equal to the i386 version, which will allow code to be shared.
--- arch/x86/kernel/setup64.c | 2 +- arch/x86/kernel/suspend_64.c | 2 +- arch/x86/kernel/vsyscall_64.c | 2 +- include/asm-x86/desc_64.h | 10 +++++----- 4 files changed, 8 insertions(+), 8 deletions(-)
arch/x86/kernel/setup64.c +1 -1
@@ -228,7 +228,7 @@ void __cpuinit cpu_init (void)* and set up the GDT descriptor: */ if (cpu) -memcpy (cpu_gdt (cpu), cpu_gdt_table,GDT_SIZE ); +memcpy (get_cpu_gdt_table (cpu), cpu_gdt_table,GDT_SIZE ); cpu_gdt_descr[cpu].size =GDT_SIZE ;load_gdt ((const struct desc_ptr *)&cpu_gdt_descr[cpu]);
arch/x86/kernel/suspend_64.c +1 -1
@@ -118,7 +118,7 @@ void fix_processor_context(void)set_tss_desc (cpu,t);/* This just modifies memory; should not be necessary. But... This is necessary, because 386 hardware has concept of busy TSS or some similar stupidity. */ -cpu_gdt (cpu)[GDT_ENTRY_TSS ].type =9 ; +get_cpu_gdt_table (cpu)[GDT_ENTRY_TSS ].type =9 ;syscall_init ();/* This sets MSR_*STAR and related */ load_TR_desc ();/* This does ltr */
arch/x86/kernel/vsyscall_64.c +1 -1
@@ -297,7 +297,7 @@ static void __cpuinit vsyscall_set_cpu(i/* Store cpu number in limit so that it can be loaded quickly in user space in vgetcpu. 12 bits for the CPU and 8 bits for the node. */ - d = (unsigned long *)(cpu_gdt (cpu) +GDT_ENTRY_PER_CPU ); + d = (unsigned long *)(get_cpu_gdt_table (cpu) +GDT_ENTRY_PER_CPU ); *d =0x0f40000000000ULL ; *d |= cpu; *d |= (node &0xf ) <<12 ;
include/asm-x86/desc_64.h +5 -5
@@ -48,7 +48,7 @@ static inline void write_ldt_entry(struc }/* the cpu gdt accessor */ -#define cpu_gdt (_cpu) ((struct desc_struct *)cpu_gdt_descr[_cpu].address) +#define get_cpu_gdt_table (x) ((struct desc_struct *)cpu_gdt_descr[x].address)static inline void load_gdt (const struct desc_ptr *ptr) {
@@ -141,15 +141,15 @@ static inline void set_tss_desc(unsigned* -1? seg base+limit should be pointing to the address of the * last valid byte */ -set_tssldt_descriptor (&cpu_gdt (cpu)[GDT_ENTRY_TSS ], +set_tssldt_descriptor (&get_cpu_gdt_table (cpu)[GDT_ENTRY_TSS ], (unsigned long )addr,DESC_TSS ,IO_BITMAP_OFFSET +IO_BITMAP_BYTES +sizeof (unsigned long ) -1 ); }static inline void set_ldt_desc (unsigned cpu,void *addr,int size) { -set_tssldt_descriptor (&cpu_gdt (cpu)[GDT_ENTRY_LDT ], (unsigned long )addr, -DESC_LDT , size *8 -1 ); +set_tssldt_descriptor (&get_cpu_gdt_table (cpu)[GDT_ENTRY_LDT ], + (unsigned long )addr,DESC_LDT , size *8 -1 ); }#define LDT_entry_a (info) \
@@ -183,7 +183,7 @@ static inline void set_ldt_desc(unsignedstatic inline void load_TLS (struct thread_struct *t,unsigned int cpu) {unsigned int i; -u64 *gdt = (u64 *)(cpu_gdt (cpu) +GDT_ENTRY_TLS_MIN ); +u64 *gdt = (u64 *)(get_cpu_gdt_table (cpu) +GDT_ENTRY_TLS_MIN );for (i =0 ; i <GDT_ENTRY_TLS_ENTRIES ; i++) gdt[i] = t->tls_array[i];
PATCH 4/19 removed unused variable
This variable is not used anywere, and is then removed
--- include/asm-x86/desc_64.h | 5 ----- 1 files changed, 0 insertions(+), 5 deletions(-)
include/asm-x86/desc_64.h +0 -5
@@ -30,11 +30,6 @@ static inline unsigned long __store_tr(void)#define store_tr (tr) (tr) = __store_tr() -/* -* This is the ldt that every process will get unless we need -* something other than this. -*/ -extern struct desc_struct default_ldt[];extern struct gate_struct idt_table[];extern struct desc_ptr cpu_gdt_descr[];
Signature · 1 line
1.5.0.6
PATCH 4/19 removed unused variable
In reply to Glauber de Oliveira CostaThis variable is not used anywere, and is then removed
--- include/asm-x86/desc_64.h | 5 ----- 1 files changed, 0 insertions(+), 5 deletions(-)
include/asm-x86/desc_64.h +0 -5
@@ -30,11 +30,6 @@ static inline unsigned long __store_tr(void)#define store_tr (tr) (tr) = __store_tr() -/* -* This is the ldt that every process will get unless we need -* something other than this. -*/ -extern struct desc_struct default_ldt[];extern struct gate_struct idt_table[];extern struct desc_ptr cpu_gdt_descr[];
Signature · 1 line
1.5.0.6
PATCH 5/19 introduce gate_desc type.
To account for the differences in gate descriptor in i386 and x86_64 a gate_desc type is introduced.
--- arch/x86/kernel/traps_32.c | 3 ++- include/asm-x86/desc_32.h | 15 ++++++++------- include/asm-x86/desc_64.h | 4 ++-- include/asm-x86/desc_defs.h | 8 +++++++- 4 files changed, 19 insertions(+), 11 deletions(-)
arch/x86/kernel/traps_32.c +2 -2
@@ -76,8 +76,8 @@ char ignore_fpu_irq = 0;* F0 0F bug workaround.. We have a special link segment * for this. */ -struct desc_struct idt_table[256] - __attribute__((__section__(".data.idt"))) = { { { { 0, 0 } } }, }; +gate_desc idt_table[256] + __attribute__((__section__(".data.idt"))) = { { { { 0, 0 } } }, }; asmlinkage void divide_error(void); asmlinkage void debug(void);
include/asm-x86/desc_32.h +8 -7
@@ -3,6 +3,7 @@#include <asm/ldt.h> #include <asm/segment.h> +#include <asm/desc_defs.h> #ifndef __ASSEMBLY__
@@ -24,7 +25,7 @@ static inline struct desc_struct *get_cpu_gdt_table(unsigned int cpu) }extern struct desc_ptr idt_descr; -extern struct desc_struct idt_table[]; +extern gate_desc idt_table[];extern void set_intr_gate (unsigned int irq,void * addr); static inline void pack_descriptor(__u32 *a, __u32 *b,
@@ -35,11 +36,11 @@ static inline void pack_descriptor(__u32 *a, __u32 *b, (limit &0x000f0000 ) | ((type &0xff ) <<8 ) | ((flags &0xf ) <<20 ); } -static inline void pack_gate (__u32 *a,__u32 *b, +static inline void pack_gate (gate_desc *gate,unsigned long base,unsigned short seg,unsigned char type,unsigned char flags) { - *a = (seg <<16 ) | (base &0xffff ); - *b = (base &0xffff0000 ) | ((type &0xff ) <<8 ) | (flags &0xff ); + gate->a = (seg <<16 ) | (base &0xffff ); + gate->b = (base &0xffff0000 ) | ((type &0xff ) <<8 ) | (flags &0xff ); }#define DESCTYPE_LDT 0x82/* present, system, DPL-0, LDT */
@@ -139,9 +140,9 @@ static inline void native_load_tls(struct thread_struct *t, unsigned int cpu)static inline void _set_gate (int gate,unsigned int type,void *addr,unsigned short seg) { -__u32 a, b; -pack_gate (&a, &b, (unsigned long )addr, seg, type,0 ); -write_idt_entry (idt_table, gate, a, b); +gate_desc g; +pack_gate (&g, (unsigned long )addr, seg, type,0 ); +write_idt_entry (idt_table, gate, g.a, g.b); }static inline void __set_tss_desc (unsigned int cpu,unsigned int entry,const void *addr)
include/asm-x86/desc_64.h +2 -2
@@ -30,7 +30,7 @@ static inline unsigned long __store_tr(void)#define store_tr (tr) (tr) = __store_tr() -extern struct gate_struct idt_table[]; +extern gate_desc idt_table[];extern struct desc_ptr cpu_gdt_descr[]; static inline void write_ldt_entry(struct desc_struct *ldt,
@@ -58,7 +58,7 @@ static inline void store_gdt(struct desc_ptr *ptr)static inline void _set_gate (void *adr,unsigned type,unsigned long func,unsigned dpl,unsigned ist) { -struct gate_struct s; +gate_desc s; s.offset_low =PTR_LOW (func); s.segment = __KERNEL_CS;
include/asm-x86/desc_defs.h +7 -1
@@ -39,7 +39,7 @@ enum { };// 16byte gate -struct gate_struct { +struct gate_struct64 {u16 offset_low;u16 segment;unsigned ist :3 , zero0 :5 , type :5 , dpl :2 , p :1 ;
@@ -67,6 +67,12 @@ struct ldttss_desc {u32 zero1; } __attribute__((packed)); +#ifdef CONFIG_X86_64 +typedef struct gate_struct64 gate_desc ; +#else +typedef struct desc_struct gate_desc ; +#endif +struct desc_ptr {unsigned short size;unsigned long address;
Signature · 1 line
1.5.0.6
PATCH 5/19 introduce gate_desc type.
In reply to Glauber de Oliveira CostaTo account for the differences in gate descriptor in i386 and x86_64 a gate_desc type is introduced.
--- arch/x86/kernel/traps_32.c | 3 ++- include/asm-x86/desc_32.h | 15 ++++++++------- include/asm-x86/desc_64.h | 4 ++-- include/asm-x86/desc_defs.h | 8 +++++++- 4 files changed, 19 insertions(+), 11 deletions(-)
arch/x86/kernel/traps_32.c +2 -2
@@ -76,8 +76,8 @@ char ignore_fpu_irq = 0;* F0 0F bug workaround.. We have a special link segment * for this. */ -struct desc_struct idt_table[256] - __attribute__((__section__(".data.idt"))) = { { { { 0, 0 } } }, }; +gate_desc idt_table[256] + __attribute__((__section__(".data.idt"))) = { { { { 0, 0 } } }, }; asmlinkage void divide_error(void); asmlinkage void debug(void);
include/asm-x86/desc_32.h +8 -7
@@ -3,6 +3,7 @@#include <asm/ldt.h> #include <asm/segment.h> +#include <asm/desc_defs.h> #ifndef __ASSEMBLY__
@@ -24,7 +25,7 @@ static inline struct desc_struct *get_cpu_gdt_table(unsigned int cpu) }extern struct desc_ptr idt_descr; -extern struct desc_struct idt_table[]; +extern gate_desc idt_table[];extern void set_intr_gate (unsigned int irq,void * addr); static inline void pack_descriptor(__u32 *a, __u32 *b,
@@ -35,11 +36,11 @@ static inline void pack_descriptor(__u32 *a, __u32 *b, (limit &0x000f0000 ) | ((type &0xff ) <<8 ) | ((flags &0xf ) <<20 ); } -static inline void pack_gate (__u32 *a,__u32 *b, +static inline void pack_gate (gate_desc *gate,unsigned long base,unsigned short seg,unsigned char type,unsigned char flags) { - *a = (seg <<16 ) | (base &0xffff ); - *b = (base &0xffff0000 ) | ((type &0xff ) <<8 ) | (flags &0xff ); + gate->a = (seg <<16 ) | (base &0xffff ); + gate->b = (base &0xffff0000 ) | ((type &0xff ) <<8 ) | (flags &0xff ); }#define DESCTYPE_LDT 0x82/* present, system, DPL-0, LDT */
@@ -139,9 +140,9 @@ static inline void native_load_tls(struct thread_struct *t, unsigned int cpu)static inline void _set_gate (int gate,unsigned int type,void *addr,unsigned short seg) { -__u32 a, b; -pack_gate (&a, &b, (unsigned long )addr, seg, type,0 ); -write_idt_entry (idt_table, gate, a, b); +gate_desc g; +pack_gate (&g, (unsigned long )addr, seg, type,0 ); +write_idt_entry (idt_table, gate, g.a, g.b); }static inline void __set_tss_desc (unsigned int cpu,unsigned int entry,const void *addr)
include/asm-x86/desc_64.h +2 -2
@@ -30,7 +30,7 @@ static inline unsigned long __store_tr(void)#define store_tr (tr) (tr) = __store_tr() -extern struct gate_struct idt_table[]; +extern gate_desc idt_table[];extern struct desc_ptr cpu_gdt_descr[]; static inline void write_ldt_entry(struct desc_struct *ldt,
@@ -58,7 +58,7 @@ static inline void store_gdt(struct desc_ptr *ptr)static inline void _set_gate (void *adr,unsigned type,unsigned long func,unsigned dpl,unsigned ist) { -struct gate_struct s; +gate_desc s; s.offset_low =PTR_LOW (func); s.segment = __KERNEL_CS;
include/asm-x86/desc_defs.h +7 -1
@@ -39,7 +39,7 @@ enum { };// 16byte gate -struct gate_struct { +struct gate_struct64 {u16 offset_low;u16 segment;unsigned ist :3 , zero0 :5 , type :5 , dpl :2 , p :1 ;
@@ -67,6 +67,12 @@ struct ldttss_desc {u32 zero1; } __attribute__((packed)); +#ifdef CONFIG_X86_64 +typedef struct gate_struct64 gate_desc ; +#else +typedef struct desc_struct gate_desc ; +#endif +struct desc_ptr {unsigned short size;unsigned long address;
Signature · 1 line
1.5.0.6
PATCH 6/19 change write_idt_entry signature
this patch changes write_idt_entry signature. It now takes a gate_desc instead of the a and b parameters. It will allow it to be later unified between i386 and x86_64.
--- arch/x86/kernel/paravirt_32.c | 2 +- arch/x86/kernel/vmi_32.c | 10 +++++++++- arch/x86/lguest/boot.c | 9 +++++---- arch/x86/xen/enlighten.c | 8 ++++---- include/asm-x86/desc_32.h | 10 ++++++++-- include/asm-x86/paravirt.h | 9 +++++---- 6 files changed, 32 insertions(+), 16 deletions(-)
arch/x86/kernel/paravirt_32.c +1 -1
@@ -381,7 +381,7 @@ struct pv_cpu_ops pv_cpu_ops = { .load_tls = native_load_tls, .write_ldt_entry = write_dt_entry, .write_gdt_entry = write_dt_entry, - .write_idt_entry = write_dt_entry, + .write_idt_entry = native_write_idt_entry, .load_sp0 = native_load_sp0, .irq_enable_syscall_ret = native_irq_enable_syscall_ret,
arch/x86/kernel/vmi_32.c +9 -1
@@ -62,6 +62,7 @@ static struct {void (*cpuid)(void /* non-c */ );void (*_set_ldt)(u32 selector);void (*set_tr)(u32 selector); +void (*write_idt_entry)(struct desc_struct *,int ,u32 ,u32 );void (*set_kernel_stack)(u32 selector,u32 sp0);void (*allocate_page)(u32 ,u32 ,u32 ,u32 ,u32 );void (*release_page)(u32 ,u32 );
@@ -214,6 +215,12 @@ static void vmi_set_tr(void) vmi_ops.set_tr (GDT_ENTRY_TSS *sizeof (struct desc_struct )); } +static void vmi_write_idt_entry (gate_desc *dt,int entry,const gate_desc *g) +{ +u32 *idt_entry = (u32 *)g; + vmi_ops.write_idt_entry (dt, entry, idt_entry[0 ], idt_entry[2 ]); +} +static void vmi_load_sp0 (struct tss_struct *tss,struct thread_struct *thread) {
@@ -792,7 +799,8 @@ static inline int __init activate_vmi(void) pv_cpu_ops.load_tls = vmi_load_tls;para_fill (pv_cpu_ops.write_ldt_entry, WriteLDTEntry);para_fill (pv_cpu_ops.write_gdt_entry, WriteGDTEntry); -para_fill (pv_cpu_ops.write_idt_entry, WriteIDTEntry); +para_wrap (pv_cpu_ops.write_idt_entry, vmi_write_idt_entry, + write_idt_entry, WriteIDTEntry);para_wrap (pv_cpu_ops.load_sp0, vmi_load_sp0, set_kernel_stack, UpdateKernelStack);para_fill (pv_cpu_ops.set_iopl_mask, SetIOPLMask);para_fill (pv_cpu_ops.io_delay, IODelay);
arch/x86/lguest/boot.c +5 -4
@@ -217,13 +217,14 @@ static void irq_enable(void)* address of the handler, and... well, who cares? The Guest just asks the * Host to make the change anyway, because the Host controls the real IDT. */ -static void lguest_write_idt_entry (struct desc_struct *dt, -int entrynum,u32 low,u32 high) +static void lguest_write_idt_entry (gate_desc *dt, +int entrynum,const gate_desc *g) { +u32 *desc = (u32 *)g;/* Keep the local copy up to date. */ -write_dt_entry (dt, entrynum, low, high); +native_write_idt_entry (dt, entrynum, g);/* Tell Host about this new entry. */ -hcall (LHCALL_LOAD_IDT_ENTRY , entrynum, low, high); +hcall (LHCALL_LOAD_IDT_ENTRY , entrynum, desc[0 ], desc[1 ]); }/* Changing to a different IDT is very rare: we keep the IDT up-to-date every
arch/x86/xen/enlighten.c +4 -4
@@ -399,8 +399,7 @@ static DEFINE_PER_CPU(struct desc_ptr, idt_desc);/* Set an IDT entry. If the entry is part of the current IDT, then also update Xen. */ -static void xen_write_idt_entry (struct desc_struct *dt,int entrynum, -u32 low,u32 high) +static void xen_write_idt_entry (gate_desc *dt,int entrynum,const gate_desc *g) {unsigned long p = (unsigned long )&dt[entrynum];unsigned long start, end;
@@ -412,14 +411,15 @@ static void xen_write_idt_entry(struct desc_struct *dt, int entrynum,xen_mc_flush (); -write_dt_entry (dt, entrynum, low, high); +native_write_idt_entry (dt, entrynum, g);if (p >= start && (p +8 ) <= end) {struct trap_info info[2 ]; +u32 *desc = (u32 *)g; info[1 ].address =0 ; -if (cvt_gate_to_trap (entrynum, low, high, &info[0 ])) +if (cvt_gate_to_trap (entrynum, desc[0 ], desc[1 ], &info[0 ]))if (HYPERVISOR_set_trap_table (info))BUG (); }
include/asm-x86/desc_32.h +8 -2
@@ -70,9 +70,15 @@ static inline void pack_gate(gate_desc *gate,#define write_ldt_entry (dt, entry, a, b) write_dt_entry(dt, entry, a, b)#define write_gdt_entry (dt, entry, a, b) write_dt_entry(dt, entry, a, b) -#define write_idt_entry (dt, entry, a, b) write_dt_entry(dt, entry, a, b) +#define write_idt_entry (dt, entry, g) native_write_idt_entry(dt, entry, g)#endif +static inline void native_write_idt_entry (gate_desc *idt,int entry, +const gate_desc *gate) +{ +memcpy (&idt[entry], gate,sizeof (*gate)); +} +static inline void write_dt_entry (struct desc_struct *dt,int entry,u32 entry_low,u32 entry_high) {
@@ -142,7 +148,7 @@ static inline void _set_gate(int gate, unsigned int type, void *addr, unsigned s {gate_desc g;pack_gate (&g, (unsigned long )addr, seg, type,0 ); -write_idt_entry (idt_table, gate, g.a, g.b); +write_idt_entry (idt_table, gate, &g); }static inline void __set_tss_desc (unsigned int cpu,unsigned int entry,const void *addr)
include/asm-x86/paravirt.h +5 -4
@@ -17,6 +17,7 @@#include <linux/types.h> #include <linux/cpumask.h> #include <asm/kmap_types.h> +#include <asm/desc_defs.h> struct page ;struct thread_struct ;
@@ -99,8 +100,8 @@ struct pv_cpu_ops { int entrynum, u32 low, u32 high);void (*write_gdt_entry)(struct desc_struct *,int entrynum,u32 low,u32 high); -void (*write_idt_entry)(struct desc_struct *, -int entrynum,u32 low,u32 high); +void (*write_idt_entry)(gate_desc *, +int entrynum,const gate_desc *gate);void (*load_sp0)(struct tss_struct *tss,struct thread_struct *t);void (*set_iopl_mask)(unsigned mask);
@@ -667,9 +668,9 @@ static inline void write_gdt_entry(void *dt, int entry, u32 low, u32 high) {PVOP_VCALL4 (pv_cpu_ops.write_gdt_entry, dt, entry, low, high); } -static inline void write_idt_entry (void *dt,int entry,u32 low,u32 high) +static inline void write_idt_entry (gate_desc *dt,int entry,const gate_desc *g) { -PVOP_VCALL4 (pv_cpu_ops.write_idt_entry, dt, entry, low, high); +PVOP_VCALL3 (pv_cpu_ops.write_idt_entry, dt, entry, g); }static inline void set_iopl_mask (unsigned mask) {
Signature · 1 line
1.5.0.6
PATCH 6/19 change write_idt_entry signature
In reply to Glauber de Oliveira Costathis patch changes write_idt_entry signature. It now takes a gate_desc instead of the a and b parameters. It will allow it to be later unified between i386 and x86_64.
--- arch/x86/kernel/paravirt_32.c | 2 +- arch/x86/kernel/vmi_32.c | 10 +++++++++- arch/x86/lguest/boot.c | 9 +++++---- arch/x86/xen/enlighten.c | 8 ++++---- include/asm-x86/desc_32.h | 10 ++++++++-- include/asm-x86/paravirt.h | 9 +++++---- 6 files changed, 32 insertions(+), 16 deletions(-)
arch/x86/kernel/paravirt_32.c +1 -1
@@ -381,7 +381,7 @@ struct pv_cpu_ops pv_cpu_ops = { .load_tls = native_load_tls, .write_ldt_entry = write_dt_entry, .write_gdt_entry = write_dt_entry, - .write_idt_entry = write_dt_entry, + .write_idt_entry = native_write_idt_entry, .load_sp0 = native_load_sp0, .irq_enable_syscall_ret = native_irq_enable_syscall_ret,
arch/x86/kernel/vmi_32.c +9 -1
@@ -62,6 +62,7 @@ static struct {void (*cpuid)(void /* non-c */ );void (*_set_ldt)(u32 selector);void (*set_tr)(u32 selector); +void (*write_idt_entry)(struct desc_struct *,int ,u32 ,u32 );void (*set_kernel_stack)(u32 selector,u32 sp0);void (*allocate_page)(u32 ,u32 ,u32 ,u32 ,u32 );void (*release_page)(u32 ,u32 );
@@ -214,6 +215,12 @@ static void vmi_set_tr(void) vmi_ops.set_tr (GDT_ENTRY_TSS *sizeof (struct desc_struct )); } +static void vmi_write_idt_entry (gate_desc *dt,int entry,const gate_desc *g) +{ +u32 *idt_entry = (u32 *)g; + vmi_ops.write_idt_entry (dt, entry, idt_entry[0 ], idt_entry[2 ]); +} +static void vmi_load_sp0 (struct tss_struct *tss,struct thread_struct *thread) {
@@ -792,7 +799,8 @@ static inline int __init activate_vmi(void) pv_cpu_ops.load_tls = vmi_load_tls;para_fill (pv_cpu_ops.write_ldt_entry, WriteLDTEntry);para_fill (pv_cpu_ops.write_gdt_entry, WriteGDTEntry); -para_fill (pv_cpu_ops.write_idt_entry, WriteIDTEntry); +para_wrap (pv_cpu_ops.write_idt_entry, vmi_write_idt_entry, + write_idt_entry, WriteIDTEntry);para_wrap (pv_cpu_ops.load_sp0, vmi_load_sp0, set_kernel_stack, UpdateKernelStack);para_fill (pv_cpu_ops.set_iopl_mask, SetIOPLMask);para_fill (pv_cpu_ops.io_delay, IODelay);
arch/x86/lguest/boot.c +5 -4
@@ -217,13 +217,14 @@ static void irq_enable(void)* address of the handler, and... well, who cares? The Guest just asks the * Host to make the change anyway, because the Host controls the real IDT. */ -static void lguest_write_idt_entry (struct desc_struct *dt, -int entrynum,u32 low,u32 high) +static void lguest_write_idt_entry (gate_desc *dt, +int entrynum,const gate_desc *g) { +u32 *desc = (u32 *)g;/* Keep the local copy up to date. */ -write_dt_entry (dt, entrynum, low, high); +native_write_idt_entry (dt, entrynum, g);/* Tell Host about this new entry. */ -hcall (LHCALL_LOAD_IDT_ENTRY , entrynum, low, high); +hcall (LHCALL_LOAD_IDT_ENTRY , entrynum, desc[0 ], desc[1 ]); }/* Changing to a different IDT is very rare: we keep the IDT up-to-date every
arch/x86/xen/enlighten.c +4 -4
@@ -399,8 +399,7 @@ static DEFINE_PER_CPU(struct desc_ptr, idt_desc);/* Set an IDT entry. If the entry is part of the current IDT, then also update Xen. */ -static void xen_write_idt_entry (struct desc_struct *dt,int entrynum, -u32 low,u32 high) +static void xen_write_idt_entry (gate_desc *dt,int entrynum,const gate_desc *g) {unsigned long p = (unsigned long )&dt[entrynum];unsigned long start, end;
@@ -412,14 +411,15 @@ static void xen_write_idt_entry(struct desc_struct *dt, int entrynum,xen_mc_flush (); -write_dt_entry (dt, entrynum, low, high); +native_write_idt_entry (dt, entrynum, g);if (p >= start && (p +8 ) <= end) {struct trap_info info[2 ]; +u32 *desc = (u32 *)g; info[1 ].address =0 ; -if (cvt_gate_to_trap (entrynum, low, high, &info[0 ])) +if (cvt_gate_to_trap (entrynum, desc[0 ], desc[1 ], &info[0 ]))if (HYPERVISOR_set_trap_table (info))BUG (); }
include/asm-x86/desc_32.h +8 -2
@@ -70,9 +70,15 @@ static inline void pack_gate(gate_desc *gate,#define write_ldt_entry (dt, entry, a, b) write_dt_entry(dt, entry, a, b)#define write_gdt_entry (dt, entry, a, b) write_dt_entry(dt, entry, a, b) -#define write_idt_entry (dt, entry, a, b) write_dt_entry(dt, entry, a, b) +#define write_idt_entry (dt, entry, g) native_write_idt_entry(dt, entry, g)#endif +static inline void native_write_idt_entry (gate_desc *idt,int entry, +const gate_desc *gate) +{ +memcpy (&idt[entry], gate,sizeof (*gate)); +} +static inline void write_dt_entry (struct desc_struct *dt,int entry,u32 entry_low,u32 entry_high) {
@@ -142,7 +148,7 @@ static inline void _set_gate(int gate, unsigned int type, void *addr, unsigned s {gate_desc g;pack_gate (&g, (unsigned long )addr, seg, type,0 ); -write_idt_entry (idt_table, gate, g.a, g.b); +write_idt_entry (idt_table, gate, &g); }static inline void __set_tss_desc (unsigned int cpu,unsigned int entry,const void *addr)
include/asm-x86/paravirt.h +5 -4
@@ -17,6 +17,7 @@#include <linux/types.h> #include <linux/cpumask.h> #include <asm/kmap_types.h> +#include <asm/desc_defs.h> struct page ;struct thread_struct ;
@@ -99,8 +100,8 @@ struct pv_cpu_ops { int entrynum, u32 low, u32 high);void (*write_gdt_entry)(struct desc_struct *,int entrynum,u32 low,u32 high); -void (*write_idt_entry)(struct desc_struct *, -int entrynum,u32 low,u32 high); +void (*write_idt_entry)(gate_desc *, +int entrynum,const gate_desc *gate);void (*load_sp0)(struct tss_struct *tss,struct thread_struct *t);void (*set_iopl_mask)(unsigned mask);
@@ -667,9 +668,9 @@ static inline void write_gdt_entry(void *dt, int entry, u32 low, u32 high) {PVOP_VCALL4 (pv_cpu_ops.write_gdt_entry, dt, entry, low, high); } -static inline void write_idt_entry (void *dt,int entry,u32 low,u32 high) +static inline void write_idt_entry (gate_desc *dt,int entry,const gate_desc *g) { -PVOP_VCALL4 (pv_cpu_ops.write_idt_entry, dt, entry, low, high); +PVOP_VCALL3 (pv_cpu_ops.write_idt_entry, dt, entry, g); }static inline void set_iopl_mask (unsigned mask) {
Signature · 1 line
1.5.0.6
PATCH 7/19 introduce ldt_desc type.
this patch introduces ldt_desc type to account for the differences in the ldt descriptor in x86_64 and i386
--- include/asm-x86/desc_64.h | 2 +- include/asm-x86/desc_defs.h | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-)
include/asm-x86/desc_64.h +1 -1
@@ -113,7 +113,7 @@ static inline void store_idt(struct desc_ptr *dtr)static inline void set_tssldt_descriptor (void *ptr,unsigned long tss,unsigned type,unsigned size) { -struct ldttss_desc d; +struct ldttss_desc64 d;memset (&d,0 ,sizeof (d)); d.limit0 = size &0xFFFF ;
include/asm-x86/desc_defs.h +3 -1
@@ -58,7 +58,7 @@ enum { };// LDT or TSS descriptor in the GDT. 16 bytes. -struct ldttss_desc { +struct ldttss_desc64 {u16 limit0;u16 base0;unsigned base1 :8 , type :5 , dpl :2 , p :1 ;
@@ -69,8 +69,10 @@ struct ldttss_desc {#ifdef CONFIG_X86_64 typedef struct gate_struct64 gate_desc ; +typedef struct ldttss_desc64 ldt_desc ;#else typedef struct desc_struct gate_desc ; +typedef struct desc_struct ldt_desc ;#endif struct desc_ptr {
Signature · 1 line
1.5.0.6
PATCH 8/19 modify write_ldt function
This patch modifies the write_ldt() function to make use of the new struct desc_struct instead of entry_1 and entry_2 entries
--- arch/x86/kernel/ldt.c | 15 +++++++-------- 1 files changed, 7 insertions(+), 8 deletions(-)
arch/x86/kernel/ldt.c +7 -8
@@ -186,7 +186,7 @@ static int read_default_ldt(void __user *ptr, unsigned long bytecount)static int write_ldt (void __user *ptr,unsigned long bytecount,int oldmode) {struct mm_struct *mm = current->mm; -__u32 entry_1, entry_2; +struct desc_struct ldt;int error;struct user_desc ldt_info;
@@ -218,21 +218,20 @@ static int write_ldt(void __user *ptr, unsigned long bytecount, int oldmode)/* Allow LDTs to be cleared by the user. */ if (ldt_info.base_addr ==0 && ldt_info.limit ==0 ) {if (oldmode ||LDT_empty (&ldt_info)) { - entry_1 =0 ; - entry_2 =0 ; +memset (&ldt,0 ,sizeof (ldt)); goto install; } } - entry_1 =LDT_entry_a (&ldt_info); - entry_2 =LDT_entry_b (&ldt_info); + ldt.a =LDT_entry_a (&ldt_info); + ldt.b =LDT_entry_b (&ldt_info);if (oldmode) - entry_2 &= ~(1 <<20 ); + ldt.avl =0 ;/* Install the new entry ... */ install: -write_ldt_entry (mm->context.ldt, ldt_info.entry_number, entry_1, - entry_2); +write_ldt_entry (mm->context.ldt, ldt_info.entry_number, + ldt.a, ldt.b); error =0 ; out_unlock:
Signature · 1 line
1.5.0.6
PATCH 8/19 modify write_ldt function
In reply to Glauber de Oliveira CostaThis patch modifies the write_ldt() function to make use of the new struct desc_struct instead of entry_1 and entry_2 entries
--- arch/x86/kernel/ldt.c | 15 +++++++-------- 1 files changed, 7 insertions(+), 8 deletions(-)
arch/x86/kernel/ldt.c +7 -8
@@ -186,7 +186,7 @@ static int read_default_ldt(void __user *ptr, unsigned long bytecount)static int write_ldt (void __user *ptr,unsigned long bytecount,int oldmode) {struct mm_struct *mm = current->mm; -__u32 entry_1, entry_2; +struct desc_struct ldt;int error;struct user_desc ldt_info;
@@ -218,21 +218,20 @@ static int write_ldt(void __user *ptr, unsigned long bytecount, int oldmode)/* Allow LDTs to be cleared by the user. */ if (ldt_info.base_addr ==0 && ldt_info.limit ==0 ) {if (oldmode ||LDT_empty (&ldt_info)) { - entry_1 =0 ; - entry_2 =0 ; +memset (&ldt,0 ,sizeof (ldt)); goto install; } } - entry_1 =LDT_entry_a (&ldt_info); - entry_2 =LDT_entry_b (&ldt_info); + ldt.a =LDT_entry_a (&ldt_info); + ldt.b =LDT_entry_b (&ldt_info);if (oldmode) - entry_2 &= ~(1 <<20 ); + ldt.avl =0 ;/* Install the new entry ... */ install: -write_ldt_entry (mm->context.ldt, ldt_info.entry_number, entry_1, - entry_2); +write_ldt_entry (mm->context.ldt, ldt_info.entry_number, + ldt.a, ldt.b); error =0 ; out_unlock:
Signature · 1 line
1.5.0.6
PATCH 9/19 introduce fill_ldt
This patch introduces fill_ldt(), which populates a ldt descriptor from a user_desc in once, instead of relying in the LDT_entry_a and LDT_entry_b macros
--- arch/x86/kernel/ldt.c | 3 +-- arch/x86/kernel/process_64.c | 3 +-- arch/x86/kernel/tls.c | 7 +++---- include/asm-x86/desc_32.h | 15 --------------- include/asm-x86/desc_64.h | 17 ----------------- include/asm-x86/ldt.h | 19 +++++++++++++++++++ 6 files changed, 24 insertions(+), 40 deletions(-)
arch/x86/kernel/ldt.c +1 -2
@@ -223,8 +223,7 @@ static int write_ldt(void __user *ptr, u } } - ldt.a =LDT_entry_a (&ldt_info); - ldt.b =LDT_entry_b (&ldt_info); +fill_ldt (&ldt, &ldt_info);if (oldmode) ldt.avl =0 ;
arch/x86/kernel/process_64.c +1 -2
@@ -446,8 +446,7 @@ static inline void set_32bit_tls(struct };struct desc_struct *desc = (void *)t->thread.tls_array; desc += tls; - desc->a =LDT_entry_a (&ud); - desc->b =LDT_entry_b (&ud); +fill_ldt (desc, &ud); }static inline u32 read_32bit_tls (struct task_struct *t,int tls)
arch/x86/kernel/tls.c +3 -4
@@ -67,10 +67,9 @@ int do_set_thread_area(struct task_strucif (LDT_empty (&info)) { desc[0 ] =0 ; desc[1 ] =0 ; - }else { - desc[0 ] =LDT_entry_a (&info); - desc[1 ] =LDT_entry_b (&info); - } + }else +fill_ldt ((struct desc_struct *)desc, &info); +if (t == ¤t->thread)load_TLS (t, cpu);
include/asm-x86/desc_32.h +0 -15
@@ -163,21 +163,6 @@ static inline void __set_tss_desc(unsign#define set_tss_desc (cpu,addr) __set_tss_desc(cpu, GDT_ENTRY_TSS, addr) -#define LDT_entry_a (info) \ - ((((info)->base_addr & 0x0000ffff) << 16) | ((info)->limit & 0x0ffff)) - -#define LDT_entry_b (info) \ - (((info)->base_addr & 0xff000000) | \ - (((info)->base_addr & 0x00ff0000) >> 16) | \ - ((info)->limit & 0xf0000) | \ - (((info)->read_exec_only ^ 1) << 9) | \ - ((info)->contents << 10) | \ - (((info)->seg_not_present ^ 1) << 15) | \ - ((info)->seg_32bit << 22) | \ - ((info)->limit_in_pages << 23) | \ - ((info)->useable << 20) | \ - 0x7000) -#define LDT_empty (info) (\ (info)->base_addr == 0 && \ (info)->limit == 0 && \
include/asm-x86/desc_64.h +0 -17
@@ -147,23 +147,6 @@ static inline void set_ldt_desc(unsigned (unsigned long)addr, DESC_LDT, size * 8 - 1); } -#define LDT_entry_a (info) \ - ((((info)->base_addr & 0x0000ffff) << 16) | ((info)->limit & 0x0ffff)) -/* Don't allow setting of the lm bit. It is useless anyways because -64bit system calls require __USER_CS. */ -#define LDT_entry_b(info) \ - (((info)->base_addr & 0xff000000) | \ - (((info)->base_addr & 0x00ff0000) >> 16) | \ - ((info)->limit & 0xf0000) | \ - (((info)->read_exec_only ^ 1) << 9) | \ - ((info)->contents << 10) | \ - (((info)->seg_not_present ^ 1) << 15) | \ - ((info)->seg_32bit << 22) | \ - ((info)->limit_in_pages << 23) | \ - ((info)->useable << 20) | \ - /* ((info)->lm << 21) | */ \ - 0x7000) -#define LDT_empty (info) (\ (info)->base_addr == 0 && \ (info)->limit == 0 && \
include/asm-x86/desc.h +29 -0
@@ -1,5 +1,34 @@ +#ifndef _ASM_DESC_H_ +#define _ASM_DESC_H_ + +#ifndef __ASSEMBLY__ +#include <asm/desc_defs.h> +#include <asm/ldt.h> + +static inline void fill_ldt (struct desc_struct *desc,struct user_desc *info) +{ + desc->limit0 = info->limit &0x0ffff ; + desc->base0 = info->base_addr &0x0000ffff ; + + desc->base1 = (info->base_addr &0x00ff0000 ) >>16 ; + desc->type = (info->read_exec_only ^1 ) <<1 ; + desc->type |= info->contents <<2 ; + desc->s =1 ; + desc->dpl =0x3 ; + desc->p = info->seg_not_present ^1 ; + desc->limit = (info->limit &0xf0000 ) >>16 ; + desc->avl = info->useable; + desc->d = info->seg_32bit; + desc->g = info->limit_in_pages; + desc->base2 = (info->base_addr &0xff000000 ) >>24 ; +} + +#endif +#ifdef CONFIG_X86_32 # include "desc_32.h" #else # include "desc_64.h" #endif + +#endif
PATCH 10/19 provide tss_desc
Provide a new type, tss_desc, to represent the tss descriptor in a unified way accross x86_64 and i386
--- include/asm-x86/desc_defs.h | 2 ++ 1 files changed, 2 insertions(+), 0 deletions(-)
include/asm-x86/desc_defs.h +2 -0
@@ -70,9 +70,11 @@ struct ldttss_desc64 {#ifdef CONFIG_X86_64 typedef struct gate_struct64 gate_desc ;typedef struct ldttss_desc64 ldt_desc ; +typedef struct ldttss_desc64 tss_desc ;#else typedef struct desc_struct gate_desc ;typedef struct desc_struct ldt_desc ; +typedef struct desc_struct tss_desc ;#endif struct desc_ptr {
Signature · 1 line
1.5.0.6
PATCH 11/19 change write_gdt_entry signature.
This patch changes the write_gdt_entry function signature. Instead of the old "a" and "b" parameters, it now receives a pointer to a desc_struct, and the size of the entry being handled. This is because x86_64 can have some 16-byte entries as well as 8-byte ones.
--- arch/x86/kernel/paravirt_32.c | 2 +- arch/x86/kernel/smpcommon_32.c | 7 ++++--- arch/x86/kernel/vmi_32.c | 21 +++++++++++++++------ arch/x86/lguest/boot.c | 6 +++--- arch/x86/xen/enlighten.c | 11 +++++------ include/asm-x86/desc_32.h | 34 ++++++++++++++++++++++------------ include/asm-x86/paravirt.h | 9 ++++++--- 7 files changed, 56 insertions(+), 34 deletions(-)
arch/x86/kernel/paravirt_32.c +1 -1
@@ -380,7 +380,7 @@ struct pv_cpu_ops pv_cpu_ops = { .store_tr = native_store_tr, .load_tls = native_load_tls, .write_ldt_entry = write_dt_entry, - .write_gdt_entry = write_dt_entry, + .write_gdt_entry = native_write_gdt_entry, .write_idt_entry = native_write_idt_entry, .load_sp0 = native_load_sp0,
arch/x86/kernel/smpcommon_32.c +4 -3
@@ -14,10 +14,11 @@ __cpuinit void init_gdt(int cpu) {struct desc_struct *gdt =get_cpu_gdt_table (cpu); -pack_descriptor ((u32 *)&gdt[GDT_ENTRY_PERCPU ].a, - (u32 *)&gdt[GDT_ENTRY_PERCPU ].b, +pack_descriptor (&gdt[GDT_ENTRY_PERCPU ], __per_cpu_offset[cpu],0xFFFFF , -0x80 |DESCTYPE_S |0x2 ,0x8 ); +0x2 |DESCTYPE_S ,0x8 ); + + gdt[GDT_ENTRY_PERCPU ].s =1 ;per_cpu (this_cpu_off, cpu) = __per_cpu_offset[cpu];per_cpu (cpu_number, cpu) = cpu;
arch/x86/kernel/vmi_32.c +15 -6
@@ -63,6 +63,7 @@ static struct {void (*_set_ldt)(u32 selector);void (*set_tr)(u32 selector);void (*write_idt_entry)(struct desc_struct *,int ,u32 ,u32 ); +void (*write_gdt_entry)(struct desc_struct *,int ,u32 ,u32 );void (*set_kernel_stack)(u32 selector,u32 sp0);void (*allocate_page)(u32 ,u32 ,u32 ,u32 ,u32 );void (*release_page)(u32 ,u32 );
@@ -187,7 +188,7 @@ static void vmi_cpuid(unsigned int *ax, unsigned int *bx,static inline void vmi_maybe_load_tls (struct desc_struct *gdt,int nr,struct desc_struct *new) {if (gdt[nr].a != new->a || gdt[nr].b != new->b) -write_gdt_entry (gdt, nr, new->a, new->b); +write_gdt_entry (gdt, nr, new,0 ); }static void vmi_load_tls (struct thread_struct *t,unsigned int cpu)
@@ -201,12 +202,12 @@ static void vmi_load_tls(struct thread_struct *t, unsigned int cpu)static void vmi_set_ldt (const void *addr,unsigned entries) {unsigned cpu =smp_processor_id (); -u32 low, high; +struct desc_struct desc; -pack_descriptor (&low, &high, (unsigned long )addr, +pack_descriptor (&desc, (unsigned long )addr, entries *sizeof (struct desc_struct ) -1 , -DESCTYPE_LDT ,0 ); -write_gdt_entry (get_cpu_gdt_table (cpu),GDT_ENTRY_LDT , low, high); +DESC_LDT ,0 ); +write_gdt_entry (get_cpu_gdt_table (cpu),GDT_ENTRY_LDT , &desc,DESC_LDT ); vmi_ops._set_ldt (entries ?GDT_ENTRY_LDT *sizeof (struct desc_struct ) :0 ); }
@@ -221,6 +222,13 @@ static void vmi_write_idt_entry(gate_desc *dt, int entry, const gate_desc *g) vmi_ops.write_idt_entry (dt, entry, idt_entry[0 ], idt_entry[2 ]); } +static void vmi_write_gdt_entry (struct desc_struct *dt,int entry, +const void *desc,int type) +{ +u32 *gdt_entry = (u32 *)desc; + vmi_ops.write_gdt_entry (dt, entry, gdt_entry[0 ], gdt_entry[2 ]); +} +static void vmi_load_sp0 (struct tss_struct *tss,struct thread_struct *thread) {
@@ -798,7 +806,8 @@ static inline int __init activate_vmi(void)para_fill (pv_cpu_ops.store_tr, GetTR); pv_cpu_ops.load_tls = vmi_load_tls;para_fill (pv_cpu_ops.write_ldt_entry, WriteLDTEntry); -para_fill (pv_cpu_ops.write_gdt_entry, WriteGDTEntry); +para_wrap (pv_cpu_ops.write_gdt_entry, vmi_write_gdt_entry, + write_gdt_entry, WriteGDTEntry);para_wrap (pv_cpu_ops.write_idt_entry, vmi_write_idt_entry, write_idt_entry, WriteIDTEntry);para_wrap (pv_cpu_ops.load_sp0, vmi_load_sp0, set_kernel_stack, UpdateKernelStack);
arch/x86/lguest/boot.c +3 -3
@@ -262,10 +262,10 @@ static void lguest_load_gdt(const struct desc_ptr *desc)/* For a single GDT entry which changes, we do the lazy thing: alter our GDT, * then tell the Host to reload the entire thing. This operation is so rare * that this naive implementation is reasonable. */ -static void lguest_write_gdt_entry (struct desc_struct *dt, -int entrynum,u32 low,u32 high) +static void lguest_write_gdt_entry (struct desc_struct *dt,int entrynum, +const void *desc,int type) { -write_dt_entry (dt, entrynum, low, high); +native_write_gdt_entry (dt, entrynum, desc, type);hcall (LHCALL_LOAD_GDT ,__pa (dt),GDT_ENTRIES ,0 ); }
arch/x86/xen/enlighten.c +5 -6
@@ -475,22 +475,21 @@ static void xen_load_idt(const struct desc_ptr *desc)/* Write a GDT descriptor entry. Ignore LDT descriptors, since they're handled differently. */ static void xen_write_gdt_entry (struct desc_struct *dt,int entry, -u32 low,u32 high) +const void *desc,int type) {preempt_disable (); -switch ((high >>8 ) &0xff ) { -case DESCTYPE_LDT : -case DESCTYPE_TSS : +switch (type) { +case DESC_LDT : +case DESC_TSS :/* ignore */ break ;default : {xmaddr_t maddr =virt_to_machine (&dt[entry]); -u64 desc = (u64 )high <<32 | low;xen_mc_flush (); -if (HYPERVISOR_update_descriptor (maddr.maddr, desc)) +if (HYPERVISOR_update_descriptor (maddr.maddr, *(u64 *)desc))BUG (); }
include/asm-x86/desc_32.h +22 -12
@@ -28,12 +28,13 @@ extern struct desc_ptr idt_descr;extern gate_desc idt_table[];extern void set_intr_gate (unsigned int irq,void * addr); -static inline void pack_descriptor (__u32 *a,__u32 *b, +static inline void pack_descriptor (struct desc_struct *desc,unsigned long base,unsigned long limit,unsigned char type,unsigned char flags) { - *a = ((base &0xffff ) <<16 ) | (limit &0xffff ); - *b = (base &0xff000000 ) | ((base &0xff0000 ) >>16 ) | + desc->a = ((base &0xffff ) <<16 ) | (limit &0xffff ); + desc->b = (base &0xff000000 ) | ((base &0xff0000 ) >>16 ) | (limit &0x000f0000 ) | ((type &0xff ) <<8 ) | ((flags &0xf ) <<20 ); + desc->p =1 ; } static inline void pack_gate(gate_desc *gate,
@@ -69,7 +70,8 @@ static inline void pack_gate(gate_desc *gate,#define set_ldt native_set_ldt#define write_ldt_entry (dt, entry, a, b) write_dt_entry(dt, entry, a, b) -#define write_gdt_entry (dt, entry, a, b) write_dt_entry(dt, entry, a, b) +#define write_gdt_entry (dt, entry, desc, type) \ + native_write_gdt_entry(dt, entry, desc, type)#define write_idt_entry (dt, entry, g) native_write_idt_entry(dt, entry, g)#endif
@@ -79,6 +81,12 @@ static inline void native_write_idt_entry(gate_desc *idt, int entry,memcpy (&idt[entry], gate,sizeof (*gate)); } +static inline void native_write_gdt_entry (struct desc_struct *gdt,int entry, +const void *desc,int type) +{ +memcpy (&gdt[entry], desc,sizeof (struct desc_struct )); +} +static inline void write_dt_entry (struct desc_struct *dt,int entry,u32 entry_low,u32 entry_high) {
@@ -86,18 +94,20 @@ static inline void write_dt_entry(struct desc_struct *dt, dt[entry].b = entry_high; } +static inline void native_set_ldt (const void *addr,unsigned int entries) {if (likely (entries ==0 )) __asm__ __volatile__("lldt %w0" ::"q" (0 ));else {unsigned cpu =smp_processor_id (); -__u32 a, b; +ldt_desc ldt; -pack_descriptor (&a, &b, (unsigned long )addr, +pack_descriptor (&ldt, (unsigned long )addr, entries *sizeof (struct desc_struct ) -1 , -DESCTYPE_LDT ,0 ); -write_gdt_entry (get_cpu_gdt_table (cpu),GDT_ENTRY_LDT , a, b); +DESC_LDT ,0 ); +write_gdt_entry (get_cpu_gdt_table (cpu),GDT_ENTRY_LDT , + &ldt,DESC_LDT ); __asm__ __volatile__("lldt %w0" ::"q" (GDT_ENTRY_LDT *8 )); } }
@@ -153,11 +163,11 @@ static inline void _set_gate(int gate, unsigned int type, void *addr, unsigned sstatic inline void __set_tss_desc (unsigned int cpu,unsigned int entry,const void *addr) { -__u32 a, b; -pack_descriptor (&a, &b, (unsigned long )addr, +tss_desc tss; +pack_descriptor (&tss, (unsigned long )addr, offsetof(struct tss_struct , __cacheline_filler) -1 , -DESCTYPE_TSS ,0 ); -write_gdt_entry (get_cpu_gdt_table (cpu), entry, a, b); +DESC_TSS ,0 ); +write_gdt_entry (get_cpu_gdt_table (cpu), entry, &tss,DESC_TSS ); }
include/asm-x86/paravirt.h +6 -3
@@ -99,7 +99,7 @@ struct pv_cpu_ops {void (*write_ldt_entry)(struct desc_struct *,int entrynum,u32 low,u32 high);void (*write_gdt_entry)(struct desc_struct *, -int entrynum,u32 low,u32 high); +int entrynum,const void *desc,int size);void (*write_idt_entry)(gate_desc *,int entrynum,const gate_desc *gate);void (*load_sp0)(struct tss_struct *tss,struct thread_struct *t);
@@ -664,10 +664,13 @@ static inline void write_ldt_entry(void *dt, int entry, u32 low, u32 high) {PVOP_VCALL4 (pv_cpu_ops.write_ldt_entry, dt, entry, low, high); } -static inline void write_gdt_entry (void *dt,int entry,u32 low,u32 high) + +static inline void write_gdt_entry (struct desc_struct *dt,int entry, +void *desc,int type) { -PVOP_VCALL4 (pv_cpu_ops.write_gdt_entry, dt, entry, low, high); +PVOP_VCALL4 (pv_cpu_ops.write_gdt_entry, dt, entry, desc, type); } +static inline void write_idt_entry (gate_desc *dt,int entry,const gate_desc *g) {PVOP_VCALL3 (pv_cpu_ops.write_idt_entry, dt, entry, g);
Signature · 1 line
1.5.0.6
PATCH 12/19 change write_ldt_entry signature
this patch changes the signature of write_ldt_entry.
--- arch/x86/kernel/ldt.c | 3 +-- arch/x86/kernel/paravirt_32.c | 2 +- arch/x86/kernel/vmi_32.c | 11 ++++++++++- arch/x86/xen/enlighten.c | 4 ++-- include/asm-x86/desc_32.h | 9 ++++++++- include/asm-x86/desc_64.h | 7 ++----- include/asm-x86/paravirt.h | 10 ++++++---- 7 files changed, 30 insertions(+), 16 deletions(-)
arch/x86/kernel/ldt.c +1 -2
@@ -229,8 +229,7 @@ static int write_ldt(void __user *ptr, unsigned long bytecount, int oldmode)/* Install the new entry ... */ install: -write_ldt_entry (mm->context.ldt, ldt_info.entry_number, - ldt.a, ldt.b); +write_ldt_entry (mm->context.ldt, ldt_info.entry_number, &ldt); error =0 ; out_unlock:
arch/x86/kernel/paravirt_32.c +1 -1
@@ -379,7 +379,7 @@ struct pv_cpu_ops pv_cpu_ops = { .store_idt = native_store_idt, .store_tr = native_store_tr, .load_tls = native_load_tls, - .write_ldt_entry = write_dt_entry, + .write_ldt_entry = native_write_ldt_entry, .write_gdt_entry = native_write_gdt_entry, .write_idt_entry = native_write_idt_entry, .load_sp0 = native_load_sp0,
arch/x86/kernel/vmi_32.c +10 -1
@@ -64,6 +64,7 @@ static struct {void (*set_tr)(u32 selector);void (*write_idt_entry)(struct desc_struct *,int ,u32 ,u32 );void (*write_gdt_entry)(struct desc_struct *,int ,u32 ,u32 ); +void (*write_ldt_entry)(struct desc_struct *,int ,u32 ,u32 );void (*set_kernel_stack)(u32 selector,u32 sp0);void (*allocate_page)(u32 ,u32 ,u32 ,u32 ,u32 );void (*release_page)(u32 ,u32 );
@@ -229,6 +230,13 @@ static void vmi_write_gdt_entry(struct desc_struct *dt, int entry, vmi_ops.write_gdt_entry (dt, entry, gdt_entry[0 ], gdt_entry[2 ]); } +static void vmi_write_ldt_entry (struct desc_struct *dt,int entry, +const void *desc) +{ +u32 *ldt_entry = (u32 *)desc; + vmi_ops.write_idt_entry (dt, entry, ldt_entry[0 ], ldt_entry[2 ]); +} +static void vmi_load_sp0 (struct tss_struct *tss,struct thread_struct *thread) {
@@ -805,7 +813,8 @@ static inline int __init activate_vmi(void)para_fill (pv_cpu_ops.store_idt, GetIDT);para_fill (pv_cpu_ops.store_tr, GetTR); pv_cpu_ops.load_tls = vmi_load_tls; -para_fill (pv_cpu_ops.write_ldt_entry, WriteLDTEntry); +para_wrap (pv_cpu_ops.write_ldt_entry, vmi_write_ldt_entry, + write_ldt_entry, WriteLDTEntry);para_wrap (pv_cpu_ops.write_gdt_entry, vmi_write_gdt_entry, write_gdt_entry, WriteGDTEntry); para_wrap(pv_cpu_ops.write_idt_entry, vmi_write_idt_entry,
arch/x86/xen/enlighten.c +2 -2
@@ -357,11 +357,11 @@ static void xen_load_tls(struct thread_struct *t, unsigned int cpu) }static void xen_write_ldt_entry (struct desc_struct *dt,int entrynum, -u32 low,u32 high) +const void *ptr) {unsigned long lp = (unsigned long )&dt[entrynum];xmaddr_t mach_lp =virt_to_machine (lp); -u64 entry = (u64 )high <<32 | low; +u64 entry = *(u64 *)ptr;preempt_disable ();
include/asm-x86/desc_32.h +8 -1
@@ -69,12 +69,19 @@ static inline void pack_gate(gate_desc *gate,#define load_TLS (t, cpu) native_load_tls(t, cpu)#define set_ldt native_set_ldt -#define write_ldt_entry (dt, entry, a, b) write_dt_entry(dt, entry, a, b) +#define write_ldt_entry (dt, entry, desc) \ + native_write_ldt_entry(dt, entry, desc)#define write_gdt_entry (dt, entry, desc, type) \ native_write_gdt_entry(dt, entry, desc, type)#define write_idt_entry (dt, entry, g) native_write_idt_entry(dt, entry, g)#endif +static inline void native_write_ldt_entry (struct desc_struct *ldt,int entry, +const void *desc) +{ +memcpy (&ldt[entry], desc,sizeof (struct desc_struct )); +} +static inline void native_write_idt_entry (gate_desc *idt,int entry,const gate_desc *gate) {
include/asm-x86/desc_64.h +2 -5
@@ -34,12 +34,9 @@ extern gate_desc idt_table[];extern struct desc_ptr cpu_gdt_descr[];static inline void write_ldt_entry (struct desc_struct *ldt, -int entry,u32 entry_low,u32 entry_high) +int entry,void *ptr) { -__u32 *lp = (__u32 *)((entry <<3 ) + (char *)ldt); - - lp[0 ] = entry_low; - lp[1 ] = entry_high; +memcpy (&ldt[entry], ptr,8 ); }/* the cpu gdt accessor */
include/asm-x86/paravirt.h +6 -4
@@ -96,8 +96,8 @@ struct pv_cpu_ops {void (*set_ldt)(const void *desc,unsigned entries);unsigned long (*store_tr)(void );void (*load_tls)(struct thread_struct *t,unsigned int cpu); -void (*write_ldt_entry)(struct desc_struct *, -int entrynum,u32 low,u32 high); +void (*write_ldt_entry)(struct desc_struct *ldt,int entrynum, +const void *desc);void (*write_gdt_entry)(struct desc_struct *,int entrynum,const void *desc,int size); void (*write_idt_entry)(gate_desc *,
@@ -660,9 +660,11 @@ static inline void load_TLS(struct thread_struct *t, unsigned cpu) {PVOP_VCALL2 (pv_cpu_ops.load_tls, t, cpu); } -static inline void write_ldt_entry (void *dt,int entry,u32 low,u32 high) + +static inline void write_ldt_entry (struct desc_struct *dt,int entry, +const void *desc) { -PVOP_VCALL4 (pv_cpu_ops.write_ldt_entry, dt, entry, low, high); +PVOP_VCALL3 (pv_cpu_ops.write_ldt_entry, dt, entry, desc); } static inline void write_gdt_entry(struct desc_struct *dt, int entry,
Signature · 1 line
1.5.0.6
PATCH 13/19 move constants to desc_defs.h
this patch moves constant definitions regarding descriptor types from desc_32.h to desc_defs.h. The change from defines to enum to comply with previous versions in desc_defs.h
--- include/asm-x86/desc_32.h | 8 -------- include/asm-x86/desc_defs.h | 5 +++++ 2 files changed, 5 insertions(+), 8 deletions(-)
include/asm-x86/desc_32.h +0 -8
@@ -44,14 +44,6 @@ static inline void pack_gate(gate_desc *gate, gate->b = (base &0xffff0000 ) | ((type &0xff ) <<8 ) | (flags &0xff ); } -#define DESCTYPE_LDT 0x82/* present, system, DPL-0, LDT */ -#define DESCTYPE_TSS 0x89/* present, system, DPL-0, 32-bit TSS */ -#define DESCTYPE_TASK 0x85/* present, system, DPL-0, task gate */ -#define DESCTYPE_INT 0x8e/* present, system, DPL-0, interrupt gate */ -#define DESCTYPE_TRAP 0x8f/* present, system, DPL-0, trap gate */ -#define DESCTYPE_DPL3 0x60/* DPL-3 */ -#define DESCTYPE_S 0x10/* !system */ -#ifdef CONFIG_PARAVIRT #include <asm/paravirt.h> #else
include/asm-x86/desc_defs.h +5 -0
@@ -55,6 +55,11 @@ struct gate_struct64 {enum {DESC_TSS =0x9 ,DESC_LDT =0x2 , +DESCTYPE_TASK =0x85 ,/* present, system, DPL-0, task gate */ +DESCTYPE_INT =0x8e ,/* present, system, DPL-0, interrupt gate */ +DESCTYPE_TRAP =0x8f ,/* present, system, DPL-0, trap gate */ +DESCTYPE_DPL3 =0x60 ,/* DPL-3 */ +DESCTYPE_S =0x10 ,/* !system */ };// LDT or TSS descriptor in the GDT. 16 bytes.
Signature · 1 line
1.5.0.6
PATCH 14/19 unify non-paravirt parts of desc.h
This patch unifies the non-paravirt part of desc_{32,64}.h into desc.h. Most of it, is simply common code, that is moved to the shared header. The only exception is the set_ldt_desc in desc_64.h, which is changed - included its name - to accomodate for the way the ldt is set up in i386.
Also, constant definitions used in desc_32.h are moved to desc_defs.h
--- include/asm-x86/desc.h | 87 ++++++++++++++++++++++++++++++++++++++ include/asm-x86/desc_32.h | 66 ---------------------------- include/asm-x86/desc_64.h | 64 ++++----------------------- include/asm-x86/mmu_context_64.h | 4 +- 4 files changed, 99 insertions(+), 122 deletions(-)
include/asm-x86/desc.h +64 -1
@@ -4,6 +4,7 @@#ifndef __ASSEMBLY__#include <asm/desc_defs.h> #include <asm/ldt.h> +#include <asm/mmu.h> static inline void fill_ldt (struct desc_struct *desc,struct user_desc *info) {
@@ -23,7 +24,8 @@ static inline void fill_ldt(struct desc_ desc->base2 = (info->base_addr &0xff000000 ) >>24 ; } -#endif +extern struct desc_ptr idt_descr; +extern gate_desc idt_table[];#ifdef CONFIG_X86_32 # include "desc_32.h"
@@ -31,4 +33,65 @@ static inline void fill_ldt(struct desc_# include "desc_64.h" #endif +#define _LDT_empty (info) (\ + (info)->base_addr == 0 && \ + (info)->limit == 0 && \ + (info)->contents == 0 && \ + (info)->read_exec_only == 1 && \ + (info)->seg_32bit == 0 && \ + (info)->limit_in_pages == 0 && \ + (info)->seg_not_present == 1 && \ + (info)->useable == 0) + +#ifdef CONFIG_X86_64 +#define LDT_empty (info) (_LDT_empty(info) && ((info)->lm == 0)) +#else +#define LDT_empty (info) (_LDT_empty(info)) +#endif + +static inline void clear_LDT (void ) +{ +set_ldt (NULL ,0 ); +} + +/* +* load one particular LDT into the current CPU +*/ +static inline void load_LDT_nolock (mm_context_t *pc) +{ +set_ldt (pc->ldt, pc->size); +} + +static inline void load_LDT (mm_context_t *pc) +{ +preempt_disable (); +load_LDT_nolock (pc); +preempt_enable (); +} + +#else +/* +* GET_DESC_BASE reads the descriptor base of the specified segment. +* +* Args: +* idx - descriptor index +* gdt - GDT pointer +* base - 32bit register to which the base will be written +* lo_w - lo word of the "base" register +* lo_b - lo byte of the "base" register +* hi_b - hi byte of the low word of the "base" register +* +* Example: +* GET_DESC_BASE(GDT_ENTRY_ESPFIX_SS, %ebx, %eax, %ax, %al, %ah) +* Will read the base address of GDT_ENTRY_ESPFIX_SS and put it into %eax. +*/ +#define GET_DESC_BASE (idx, gdt, base, lo_w, lo_b, hi_b) \ + movb idx*8+4(gdt), lo_b; \ + movb idx*8+7(gdt), hi_b; \ + shll $16, base; \ + movw idx*8+2(gdt), lo_w; + + +#endif /* __ASSEMBLY__ */ +#endif
include/asm-x86/desc_32.h +0 -58
82 lines not on this page · raw message
include/asm-x86/desc_64.h +10 -45
95 lines not on this page · raw message
include/asm-x86/mmu_context_64.h +2 -2
@@ -43,7 +43,7 @@ static inline void switch_mm(struct mm_sload_cr3 (next->pgd);if (unlikely (next->context.ldt != prev->context.ldt)) -load_LDT_nolock (&next->context, cpu); +load_LDT_nolock (&next->context); }#ifdef CONFIG_SMP else {
@@ -56,7 +56,7 @@ static inline void switch_mm(struct mm_s* to make sure to use no freed page tables. */ load_cr3 (next->pgd); - load_LDT_nolock(&next->context, cpu); + load_LDT_nolock(&next->context); } }#endif
PATCH 15/19 use the same data type for tls_array.
This patch changes the type of tls_array in x86_64 to a desc_struct. Now, both i386 and x86_64 tls_array have the same type, and code accessing it can be shared.
--- include/asm-x86/desc_64.h | 2 +- include/asm-x86/processor_64.h | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-)
include/asm-x86/desc_64.h +1 -1
@@ -150,7 +150,7 @@ static inline void set_ldt(void *addr, int entries)static inline void load_TLS (struct thread_struct *t,unsigned int cpu) {unsigned int i; -u64 *gdt = (u64 *)(get_cpu_gdt_table (cpu) +GDT_ENTRY_TLS_MIN ); +struct desc_struct *gdt = (get_cpu_gdt_table (cpu) +GDT_ENTRY_TLS_MIN );for (i =0 ; i <GDT_ENTRY_TLS_ENTRIES ; i++) gdt[i] = t->tls_array[i];
include/asm-x86/processor_64.h +2 -1
@@ -19,6 +19,7 @@#include <linux/personality.h> #include <linux/cpumask.h> #include <asm/processor-flags.h> +#include <asm/desc_defs.h> #define TF_MASK 0x00000100#define IF_MASK 0x00000200
@@ -244,7 +245,7 @@ struct thread_struct {* goes into MSR_IA32_DS_AREA */ unsigned long ds_area_msr;/* cached TLS descriptors. */ -u64 tls_array[GDT_ENTRY_TLS_ENTRIES ]; +struct desc_struct tls_array[GDT_ENTRY_TLS_ENTRIES ]; } __attribute__((aligned(16)));#define INIT_THREAD { \
Signature · 1 line
1.5.0.6
PATCH 15/19 use the same data type for tls_array.
In reply to Glauber de Oliveira CostaThis patch changes the type of tls_array in x86_64 to a desc_struct. Now, both i386 and x86_64 tls_array have the same type, and code accessing it can be shared.
--- include/asm-x86/desc_64.h | 2 +- include/asm-x86/processor_64.h | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-)
include/asm-x86/desc_64.h +1 -1
@@ -150,7 +150,7 @@ static inline void set_ldt(void *addr, int entries)static inline void load_TLS (struct thread_struct *t,unsigned int cpu) {unsigned int i; -u64 *gdt = (u64 *)(get_cpu_gdt_table (cpu) +GDT_ENTRY_TLS_MIN ); +struct desc_struct *gdt = (get_cpu_gdt_table (cpu) +GDT_ENTRY_TLS_MIN );for (i =0 ; i <GDT_ENTRY_TLS_ENTRIES ; i++) gdt[i] = t->tls_array[i];
include/asm-x86/processor_64.h +2 -1
@@ -19,6 +19,7 @@#include <linux/personality.h> #include <linux/cpumask.h> #include <asm/processor-flags.h> +#include <asm/desc_defs.h> #define TF_MASK 0x00000100#define IF_MASK 0x00000200
@@ -244,7 +245,7 @@ struct thread_struct {* goes into MSR_IA32_DS_AREA */ unsigned long ds_area_msr;/* cached TLS descriptors. */ -u64 tls_array[GDT_ENTRY_TLS_ENTRIES ]; +struct desc_struct tls_array[GDT_ENTRY_TLS_ENTRIES ]; } __attribute__((aligned(16)));#define INIT_THREAD { \
Signature · 1 line
1.5.0.6
PATCH 16/19 modify get_desc_base
This patch makes get_desc_base() receive a struct desc_struct, and then uses its internal fields to compute the base address. This is done at both i386 and x86_64, and then it is moved to common header
--- arch/x86/kernel/tls.c | 2 +- arch/x86/mm/fault_32.c | 2 +- include/asm-x86/desc.h | 8 ++------ 3 files changed, 4 insertions(+), 8 deletions(-)
arch/x86/kernel/tls.c +1 -1
@@ -112,7 +112,7 @@ int do_get_thread_area(struct task_strucmemset (&info,0 ,sizeof (struct user_desc )); info.entry_number = idx; - info.base_addr =get_desc_base ((void *)desc); + info.base_addr =get_desc_base ((struct desc_struct *)desc); info.limit =GET_LIMIT (desc); info.seg_32bit =GET_32BIT (desc); info.contents =GET_CONTENTS (desc);
arch/x86/mm/fault_32.c +1 -1
@@ -115,7 +115,7 @@ static inline unsigned long get_segment_ }/* Decode the code segment base from the descriptor */ - base =get_desc_base ((unsigned long *)desc); + base =get_desc_base ((struct desc_struct *)desc);if (seg & (1 <<2 )) {mutex_unlock (¤t->mm->context.lock);
include/asm-x86/desc.h +5 -0
@@ -69,6 +69,11 @@ static inline void load_LDT(mm_context_t preempt_enable(); } +static inline unsigned long get_desc_base (struct desc_struct *desc) +{ +return desc->base0 | ((desc->base1) <<16 ) | ((desc->base2) <<24 ); +} +#else /* * GET_DESC_BASE reads the descriptor base of the specified segment.
include/asm-x86/desc_32.h +0 -8
@@ -168,14 +168,6 @@ static inline void __set_tss_desc(unsign#define set_tss_desc (cpu,addr) __set_tss_desc(cpu, GDT_ENTRY_TSS, addr) -static inline unsigned long get_desc_base (unsigned long *desc) -{ -unsigned long base; - base = ((desc[0 ] >>16 ) &0x0000ffff ) | - ((desc[1 ] <<16 ) &0x00ff0000 ) | - (desc[1 ] &0xff000000 ); -return base; -}#endif /* !__ASSEMBLY__ */ #endif
include/asm-x86/desc_64.h +0 -9
@@ -156,15 +156,6 @@ static inline void load_TLS(struct threa gdt[i] = t->tls_array[i]; } -static inline unsigned long get_desc_base (const void *ptr) -{ -const u32 *desc = ptr; -unsigned long base; - base = ((desc[0 ] >>16 ) &0x0000ffff ) | - ((desc[1 ] <<16 ) &0x00ff0000 ) | - (desc[1 ] &0xff000000 ); -return base; -}#endif /* !__ASSEMBLY__ */ #endif
PATCH 16/19 modify get_desc_base
In reply to Glauber de Oliveira CostaThis patch makes get_desc_base() receive a struct desc_struct, and then uses its internal fields to compute the base address. This is done at both i386 and x86_64, and then it is moved to common header
--- arch/x86/kernel/tls.c | 2 +- arch/x86/mm/fault_32.c | 2 +- include/asm-x86/desc.h | 8 ++------ 3 files changed, 4 insertions(+), 8 deletions(-)
arch/x86/kernel/tls.c +1 -1
@@ -112,7 +112,7 @@ int do_get_thread_area(struct task_strucmemset (&info,0 ,sizeof (struct user_desc )); info.entry_number = idx; - info.base_addr =get_desc_base ((void *)desc); + info.base_addr =get_desc_base ((struct desc_struct *)desc); info.limit =GET_LIMIT (desc); info.seg_32bit =GET_32BIT (desc); info.contents =GET_CONTENTS (desc);
arch/x86/mm/fault_32.c +1 -1
@@ -115,7 +115,7 @@ static inline unsigned long get_segment_ }/* Decode the code segment base from the descriptor */ - base =get_desc_base ((unsigned long *)desc); + base =get_desc_base ((struct desc_struct *)desc);if (seg & (1 <<2 )) {mutex_unlock (¤t->mm->context.lock);
include/asm-x86/desc.h +5 -0
@@ -69,6 +69,11 @@ static inline void load_LDT(mm_context_t preempt_enable(); } +static inline unsigned long get_desc_base (struct desc_struct *desc) +{ +return desc->base0 | ((desc->base1) <<16 ) | ((desc->base2) <<24 ); +} +#else /* * GET_DESC_BASE reads the descriptor base of the specified segment.
include/asm-x86/desc_32.h +0 -8
@@ -168,14 +168,6 @@ static inline void __set_tss_desc(unsign#define set_tss_desc (cpu,addr) __set_tss_desc(cpu, GDT_ENTRY_TSS, addr) -static inline unsigned long get_desc_base (unsigned long *desc) -{ -unsigned long base; - base = ((desc[0 ] >>16 ) &0x0000ffff ) | - ((desc[1 ] <<16 ) &0x00ff0000 ) | - (desc[1 ] &0xff000000 ); -return base; -}#endif /* !__ASSEMBLY__ */ #endif
include/asm-x86/desc_64.h +0 -9
@@ -156,15 +156,6 @@ static inline void load_TLS(struct threa gdt[i] = t->tls_array[i]; } -static inline unsigned long get_desc_base (const void *ptr) -{ -const u32 *desc = ptr; -unsigned long base; - base = ((desc[0 ] >>16 ) &0x0000ffff ) | - ((desc[1 ] <<16 ) &0x00ff0000 ) | - (desc[1 ] &0xff000000 ); -return base; -}#endif /* !__ASSEMBLY__ */ #endif
PATCH 17/19 unify paravirt pieces of descriptor handling
With the types used to access descriptors in x86_64 and i386 now being the same, the code that effectively handles them can now be easily shared. This patch moves the paravirt part of desc_32.h into desc.h, and then, we get paravirt support in x86_64 for free.
--- include/asm-x86/desc.h | 169 +++++++++++++++++++++++++++++++++++++++++++ include/asm-x86/desc_32.h | 130 --------------------------------- include/asm-x86/desc_64.h | 104 +++------------------------ include/asm-x86/desc_defs.h | 6 +- 4 files changed, 183 insertions(+), 226 deletions(-)
include/asm-x86/desc_32.h +0 -130
@@ -8,31 +8,10 @@#ifndef __ASSEMBLY__#include <linux/preempt.h> -#include <linux/smp.h> #include <linux/percpu.h> -struct gdt_page -{ -struct desc_struct gdt[GDT_ENTRIES ]; -} __attribute__((aligned (PAGE_SIZE ))); -DECLARE_PER_CPU(struct gdt_page, gdt_page); - -static inline struct desc_struct *get_cpu_gdt_table (unsigned int cpu) -{ -return per_cpu (gdt_page, cpu).gdt; -} -extern void set_intr_gate (unsigned int irq,void * addr); -static inline void pack_descriptor (struct desc_struct *desc, -unsigned long base,unsigned long limit,unsigned char type,unsigned char flags) -{ - desc->a = ((base &0xffff ) <<16 ) | (limit &0xffff ); - desc->b = (base &0xff000000 ) | ((base &0xff0000 ) >>16 ) | - (limit &0x000f0000 ) | ((type &0xff ) <<8 ) | ((flags &0xf ) <<20 ); - desc->p =1 ; -} -static inline void pack_gate (gate_desc *gate,unsigned long base,unsigned short seg,unsigned char type,unsigned char flags) {
@@ -40,115 +19,6 @@ static inline void pack_gate(gate_desc * gate->b = (base &0xffff0000 ) | ((type &0xff ) <<8 ) | (flags &0xff ); } -#ifdef CONFIG_PARAVIRT -#include <asm/paravirt.h> -#else -#define load_TR_desc () native_load_tr_desc() -#define load_gdt (dtr) native_load_gdt(dtr) -#define load_idt (dtr) native_load_idt(dtr) -#define load_tr (tr) __asm__ __volatile("ltr %0"::"m" (tr)) -#define load_ldt (ldt) __asm__ __volatile("lldt %0"::"m" (ldt)) - -#define store_gdt (dtr) native_store_gdt(dtr) -#define store_idt (dtr) native_store_idt(dtr) -#define store_tr (tr) (tr = native_store_tr()) -#define store_ldt (ldt) __asm__ ("sldt %0":"=m" (ldt)) - -#define load_TLS (t, cpu) native_load_tls(t, cpu) -#define set_ldt native_set_ldt - -#define write_ldt_entry (dt, entry, desc) \ - native_write_ldt_entry(dt, entry, desc) -#define write_gdt_entry (dt, entry, desc, type) \ - native_write_gdt_entry(dt, entry, desc, type) -#define write_idt_entry (dt, entry, g) native_write_idt_entry(dt, entry, g) -#endif - -static inline void native_write_ldt_entry (struct desc_struct *ldt,int entry, -const void *desc) -{ -memcpy (&ldt[entry], desc,sizeof (struct desc_struct )); -} - -static inline void native_write_idt_entry (gate_desc *idt,int entry, -const gate_desc *gate) -{ -memcpy (&idt[entry], gate,sizeof (*gate)); -} - -static inline void native_write_gdt_entry (struct desc_struct *gdt,int entry, -const void *desc,int type) -{ -memcpy (&gdt[entry], desc,sizeof (struct desc_struct )); -} - -static inline void write_dt_entry (struct desc_struct *dt, -int entry,u32 entry_low,u32 entry_high) -{ - dt[entry].a = entry_low; - dt[entry].b = entry_high; -} - - -static inline void native_set_ldt (const void *addr,unsigned int entries) -{ -if (likely (entries ==0 )) - __asm__ __volatile__("lldt %w0" ::"q" (0 )); -else { -unsigned cpu =smp_processor_id (); -ldt_desc ldt; - -pack_descriptor (&ldt, (unsigned long )addr, - entries *sizeof (struct desc_struct ) -1 , -DESC_LDT ,0 ); -write_gdt_entry (get_cpu_gdt_table (cpu),GDT_ENTRY_LDT , - &ldt,DESC_LDT ); - __asm__ __volatile__("lldt %w0" ::"q" (GDT_ENTRY_LDT *8 )); - } -} - - -static inline void native_load_tr_desc (void ) -{ - asmvolatile ("ltr %w0" ::"q" (GDT_ENTRY_TSS *8 )); -} - -static inline void native_load_gdt (const struct desc_ptr *dtr) -{ - asmvolatile ("lgdt %0" ::"m" (*dtr)); -} - -static inline void native_load_idt (const struct desc_ptr *dtr) -{ - asmvolatile ("lidt %0" ::"m" (*dtr)); -} - -static inline void native_store_gdt (struct desc_ptr *dtr) -{ - asm ("sgdt %0" :"=m" (*dtr)); -} - -static inline void native_store_idt (struct desc_ptr *dtr) -{ - asm ("sidt %0" :"=m" (*dtr)); -} - -static inline unsigned long native_store_tr (void ) -{ -unsigned long tr; - asm ("str %0" :"=r" (tr)); -return tr; -} - -static inline void native_load_tls (struct thread_struct *t,unsigned int cpu) -{ -unsigned int i; -struct desc_struct *gdt =get_cpu_gdt_table (cpu); - -for (i =0 ; i <GDT_ENTRY_TLS_ENTRIES ; i++) - gdt[GDT_ENTRY_TLS_MIN + i] = t->tls_array[i]; -} -static inline void _set_gate (int gate,unsigned int type,void *addr,unsigned short seg) {gate_desc g;
include/asm-x86/desc_64.h +11 -93
150 lines not on this page · raw message
include/asm-x86/desc_defs.h +3 -3
@@ -48,9 +48,9 @@ struct gate_struct64 {u32 zero1; } __attribute__((packed)); -#define PTR_LOW (x) ((unsigned long)(x) & 0xFFFF) -#define PTR_MIDDLE (x) (((unsigned long)(x) >> 16) & 0xFFFF) -#define PTR_HIGH (x) ((unsigned long)(x) >> 32) +#define PTR_LOW (x) ((unsigned long long)(x) & 0xFFFF) +#define PTR_MIDDLE (x) (((unsigned long long)(x) >> 16) & 0xFFFF) +#define PTR_HIGH (x) ((unsigned long long)(x) >> 32)enum {DESC_TSS =0x9 ,
include/asm-x86/desc.h +169 -0
181 lines not on this page · raw message
PATCH 17/19 unify paravirt pieces of descriptor handling
In reply to Glauber de Oliveira CostaWith the types used to access descriptors in x86_64 and i386 now being the same, the code that effectively handles them can now be easily shared. This patch moves the paravirt part of desc_32.h into desc.h, and then, we get paravirt support in x86_64 for free.
--- include/asm-x86/desc.h | 169 +++++++++++++++++++++++++++++++++++++++++++ include/asm-x86/desc_32.h | 130 --------------------------------- include/asm-x86/desc_64.h | 104 +++------------------------ include/asm-x86/desc_defs.h | 6 +- 4 files changed, 183 insertions(+), 226 deletions(-)
include/asm-x86/desc_32.h +0 -130
@@ -8,31 +8,10 @@#ifndef __ASSEMBLY__#include <linux/preempt.h> -#include <linux/smp.h> #include <linux/percpu.h> -struct gdt_page -{ -struct desc_struct gdt[GDT_ENTRIES ]; -} __attribute__((aligned (PAGE_SIZE ))); -DECLARE_PER_CPU(struct gdt_page, gdt_page); - -static inline struct desc_struct *get_cpu_gdt_table (unsigned int cpu) -{ -return per_cpu (gdt_page, cpu).gdt; -} -extern void set_intr_gate (unsigned int irq,void * addr); -static inline void pack_descriptor (struct desc_struct *desc, -unsigned long base,unsigned long limit,unsigned char type,unsigned char flags) -{ - desc->a = ((base &0xffff ) <<16 ) | (limit &0xffff ); - desc->b = (base &0xff000000 ) | ((base &0xff0000 ) >>16 ) | - (limit &0x000f0000 ) | ((type &0xff ) <<8 ) | ((flags &0xf ) <<20 ); - desc->p =1 ; -} -static inline void pack_gate (gate_desc *gate,unsigned long base,unsigned short seg,unsigned char type,unsigned char flags) {
@@ -40,115 +19,6 @@ static inline void pack_gate(gate_desc * gate->b = (base &0xffff0000 ) | ((type &0xff ) <<8 ) | (flags &0xff ); } -#ifdef CONFIG_PARAVIRT -#include <asm/paravirt.h> -#else -#define load_TR_desc () native_load_tr_desc() -#define load_gdt (dtr) native_load_gdt(dtr) -#define load_idt (dtr) native_load_idt(dtr) -#define load_tr (tr) __asm__ __volatile("ltr %0"::"m" (tr)) -#define load_ldt (ldt) __asm__ __volatile("lldt %0"::"m" (ldt)) - -#define store_gdt (dtr) native_store_gdt(dtr) -#define store_idt (dtr) native_store_idt(dtr) -#define store_tr (tr) (tr = native_store_tr()) -#define store_ldt (ldt) __asm__ ("sldt %0":"=m" (ldt)) - -#define load_TLS (t, cpu) native_load_tls(t, cpu) -#define set_ldt native_set_ldt - -#define write_ldt_entry (dt, entry, desc) \ - native_write_ldt_entry(dt, entry, desc) -#define write_gdt_entry (dt, entry, desc, type) \ - native_write_gdt_entry(dt, entry, desc, type) -#define write_idt_entry (dt, entry, g) native_write_idt_entry(dt, entry, g) -#endif - -static inline void native_write_ldt_entry (struct desc_struct *ldt,int entry, -const void *desc) -{ -memcpy (&ldt[entry], desc,sizeof (struct desc_struct )); -} - -static inline void native_write_idt_entry (gate_desc *idt,int entry, -const gate_desc *gate) -{ -memcpy (&idt[entry], gate,sizeof (*gate)); -} - -static inline void native_write_gdt_entry (struct desc_struct *gdt,int entry, -const void *desc,int type) -{ -memcpy (&gdt[entry], desc,sizeof (struct desc_struct )); -} - -static inline void write_dt_entry (struct desc_struct *dt, -int entry,u32 entry_low,u32 entry_high) -{ - dt[entry].a = entry_low; - dt[entry].b = entry_high; -} - - -static inline void native_set_ldt (const void *addr,unsigned int entries) -{ -if (likely (entries ==0 )) - __asm__ __volatile__("lldt %w0" ::"q" (0 )); -else { -unsigned cpu =smp_processor_id (); -ldt_desc ldt; - -pack_descriptor (&ldt, (unsigned long )addr, - entries *sizeof (struct desc_struct ) -1 , -DESC_LDT ,0 ); -write_gdt_entry (get_cpu_gdt_table (cpu),GDT_ENTRY_LDT , - &ldt,DESC_LDT ); - __asm__ __volatile__("lldt %w0" ::"q" (GDT_ENTRY_LDT *8 )); - } -} - - -static inline void native_load_tr_desc (void ) -{ - asmvolatile ("ltr %w0" ::"q" (GDT_ENTRY_TSS *8 )); -} - -static inline void native_load_gdt (const struct desc_ptr *dtr) -{ - asmvolatile ("lgdt %0" ::"m" (*dtr)); -} - -static inline void native_load_idt (const struct desc_ptr *dtr) -{ - asmvolatile ("lidt %0" ::"m" (*dtr)); -} - -static inline void native_store_gdt (struct desc_ptr *dtr) -{ - asm ("sgdt %0" :"=m" (*dtr)); -} - -static inline void native_store_idt (struct desc_ptr *dtr) -{ - asm ("sidt %0" :"=m" (*dtr)); -} - -static inline unsigned long native_store_tr (void ) -{ -unsigned long tr; - asm ("str %0" :"=r" (tr)); -return tr; -} - -static inline void native_load_tls (struct thread_struct *t,unsigned int cpu) -{ -unsigned int i; -struct desc_struct *gdt =get_cpu_gdt_table (cpu); - -for (i =0 ; i <GDT_ENTRY_TLS_ENTRIES ; i++) - gdt[GDT_ENTRY_TLS_MIN + i] = t->tls_array[i]; -} -static inline void _set_gate (int gate,unsigned int type,void *addr,unsigned short seg) {gate_desc g;
include/asm-x86/desc_64.h +11 -93
150 lines not on this page · raw message
include/asm-x86/desc_defs.h +3 -3
@@ -48,9 +48,9 @@ struct gate_struct64 {u32 zero1; } __attribute__((packed)); -#define PTR_LOW (x) ((unsigned long)(x) & 0xFFFF) -#define PTR_MIDDLE (x) (((unsigned long)(x) >> 16) & 0xFFFF) -#define PTR_HIGH (x) ((unsigned long)(x) >> 32) +#define PTR_LOW (x) ((unsigned long long)(x) & 0xFFFF) +#define PTR_MIDDLE (x) (((unsigned long long)(x) >> 16) & 0xFFFF) +#define PTR_HIGH (x) ((unsigned long long)(x) >> 32)enum {DESC_TSS =0x9 ,
include/asm-x86/desc.h +169 -0
181 lines not on this page · raw message
PATCH 18/19 move _set_gate and its users to a common location
This patch moves _set_gate and its users to desc.h. We can now use common code for x86_64 and i386.
--- arch/x86/kernel/traps_32.c | 34 ---------------- include/asm-x86/desc.h | 88 +++++++++++++++++++++++++++++++++++++++++++ include/asm-x86/desc_32.h | 16 -------- include/asm-x86/desc_64.h | 45 ---------------------- include/asm-x86/desc_defs.h | 5 +-- 5 files changed, 89 insertions(+), 99 deletions(-)
arch/x86/kernel/traps_32.c +0 -34
@@ -1102,40 +1102,6 @@ asmlinkage void math_emulate(long arg)#endif /* CONFIG_MATH_EMULATION */ -/* -* This needs to use 'idt_table' rather than 'idt', and -* thus use the _nonmapped_ version of the IDT, as the -* Pentium F0 0F bugfix can have resulted in the mapped -* IDT being write-protected. -*/ -void set_intr_gate (unsigned int n,void *addr) -{ -_set_gate (n,DESCTYPE_INT , addr, __KERNEL_CS); -} - -/* -* This routine sets up an interrupt gate at directory privilege level 3. -*/ -static inline void set_system_intr_gate (unsigned int n,void *addr) -{ -_set_gate (n,DESCTYPE_INT |DESCTYPE_DPL3 , addr, __KERNEL_CS); -} - -static void __init set_trap_gate (unsigned int n,void *addr) -{ -_set_gate (n,DESCTYPE_TRAP , addr, __KERNEL_CS); -} - -static void __init set_system_gate (unsigned int n,void *addr) -{ -_set_gate (n,DESCTYPE_TRAP |DESCTYPE_DPL3 , addr, __KERNEL_CS); -} - -static void __init set_task_gate (unsigned int n,unsigned int gdt_entry) -{ -_set_gate (n,DESCTYPE_TASK , (void *)0 , (gdt_entry<<3 )); -} -void __init trap_init (void ) {
include/asm-x86/desc.h +88 -0
106 lines not on this page · raw message
include/asm-x86/desc_32.h +0 -16
@@ -10,22 +10,6 @@#include <linux/preempt.h> #include <linux/percpu.h> -extern void set_intr_gate (unsigned int irq,void * addr); - -static inline void pack_gate (gate_desc *gate, -unsigned long base,unsigned short seg,unsigned char type,unsigned char flags) -{ - gate->a = (seg <<16 ) | (base &0xffff ); - gate->b = (base &0xffff0000 ) | ((type &0xff ) <<8 ) | (flags &0xff ); -} - -static inline void _set_gate (int gate,unsigned int type,void *addr,unsigned short seg) -{ -gate_desc g; -pack_gate (&g, (unsigned long )addr, seg, type,0 ); -write_idt_entry (idt_table, gate, &g); -} -static inline void __set_tss_desc (unsigned int cpu,unsigned int entry,const void *addr) {tss_desc tss;
include/asm-x86/desc_64.h +0 -45
51 lines not on this page · raw message
include/asm-x86/desc_defs.h +1 -4
@@ -36,6 +36,7 @@ enum {GATE_INTERRUPT =0xE ,GATE_TRAP =0xF ,GATE_CALL =0xC , + GATE_TASK = 0x5, };// 16byte gate
@@ -55,10 +56,6 @@ struct gate_struct64 {enum {DESC_TSS =0x9 ,DESC_LDT =0x2 , -DESCTYPE_TASK =0x85 ,/* present, system, DPL-0, task gate */ -DESCTYPE_INT =0x8e ,/* present, system, DPL-0, interrupt gate */ -DESCTYPE_TRAP =0x8f ,/* present, system, DPL-0, trap gate */ -DESCTYPE_DPL3 =0x60 ,/* DPL-3 */ DESCTYPE_S =0x10 ,/* !system */ };
PATCH 18/19 move _set_gate and its users to a common location
In reply to Glauber de Oliveira CostaThis patch moves _set_gate and its users to desc.h. We can now use common code for x86_64 and i386.
--- arch/x86/kernel/traps_32.c | 34 ---------------- include/asm-x86/desc.h | 88 +++++++++++++++++++++++++++++++++++++++++++ include/asm-x86/desc_32.h | 16 -------- include/asm-x86/desc_64.h | 45 ---------------------- include/asm-x86/desc_defs.h | 5 +-- 5 files changed, 89 insertions(+), 99 deletions(-)
arch/x86/kernel/traps_32.c +0 -34
@@ -1102,40 +1102,6 @@ asmlinkage void math_emulate(long arg)#endif /* CONFIG_MATH_EMULATION */ -/* -* This needs to use 'idt_table' rather than 'idt', and -* thus use the _nonmapped_ version of the IDT, as the -* Pentium F0 0F bugfix can have resulted in the mapped -* IDT being write-protected. -*/ -void set_intr_gate (unsigned int n,void *addr) -{ -_set_gate (n,DESCTYPE_INT , addr, __KERNEL_CS); -} - -/* -* This routine sets up an interrupt gate at directory privilege level 3. -*/ -static inline void set_system_intr_gate (unsigned int n,void *addr) -{ -_set_gate (n,DESCTYPE_INT |DESCTYPE_DPL3 , addr, __KERNEL_CS); -} - -static void __init set_trap_gate (unsigned int n,void *addr) -{ -_set_gate (n,DESCTYPE_TRAP , addr, __KERNEL_CS); -} - -static void __init set_system_gate (unsigned int n,void *addr) -{ -_set_gate (n,DESCTYPE_TRAP |DESCTYPE_DPL3 , addr, __KERNEL_CS); -} - -static void __init set_task_gate (unsigned int n,unsigned int gdt_entry) -{ -_set_gate (n,DESCTYPE_TASK , (void *)0 , (gdt_entry<<3 )); -} -void __init trap_init (void ) {
include/asm-x86/desc.h +88 -0
106 lines not on this page · raw message
include/asm-x86/desc_32.h +0 -16
@@ -10,22 +10,6 @@#include <linux/preempt.h> #include <linux/percpu.h> -extern void set_intr_gate (unsigned int irq,void * addr); - -static inline void pack_gate (gate_desc *gate, -unsigned long base,unsigned short seg,unsigned char type,unsigned char flags) -{ - gate->a = (seg <<16 ) | (base &0xffff ); - gate->b = (base &0xffff0000 ) | ((type &0xff ) <<8 ) | (flags &0xff ); -} - -static inline void _set_gate (int gate,unsigned int type,void *addr,unsigned short seg) -{ -gate_desc g; -pack_gate (&g, (unsigned long )addr, seg, type,0 ); -write_idt_entry (idt_table, gate, &g); -} -static inline void __set_tss_desc (unsigned int cpu,unsigned int entry,const void *addr) {tss_desc tss;
include/asm-x86/desc_64.h +0 -45
51 lines not on this page · raw message
include/asm-x86/desc_defs.h +1 -4
@@ -36,6 +36,7 @@ enum {GATE_INTERRUPT =0xE ,GATE_TRAP =0xF ,GATE_CALL =0xC , + GATE_TASK = 0x5, };// 16byte gate
@@ -55,10 +56,6 @@ struct gate_struct64 {enum {DESC_TSS =0x9 ,DESC_LDT =0x2 , -DESCTYPE_TASK =0x85 ,/* present, system, DPL-0, task gate */ -DESCTYPE_INT =0x8e ,/* present, system, DPL-0, interrupt gate */ -DESCTYPE_TRAP =0x8f ,/* present, system, DPL-0, trap gate */ -DESCTYPE_DPL3 =0x60 ,/* DPL-3 */ DESCTYPE_S =0x10 ,/* !system */ };
PATCH 19/19 unify set_tss_desc
This patch unifies the set_tss_desc between i386 and x86_64, which can now have a common implementation. After the old functions are removed from desc_{32,64}.h, nothing important is left, and the files can be removed.
--- include/asm-x86/desc.h | 40 +++++++++++++++++++++++++++++++++------- include/asm-x86/desc_32.h | 27 --------------------------- include/asm-x86/desc_64.h | 34 ---------------------------------- 3 files changed, 33 insertions(+), 68 deletions(-) delete mode 100644 include/asm-x86/desc_32.h delete mode 100644 include/asm-x86/desc_64.h
include/asm-x86/desc.h +33 -6
@@ -165,6 +165,39 @@ static inline void pack_ldt(ldt_desc *ld#endif } +static inline void pack_tss (tss_desc *tss,unsigned long addr, +unsigned size,unsigned entry) +{ +#ifdef CONFIG_X86_64 +set_tssldt_descriptor (tss, + addr, entry, size); +#else +pack_descriptor (tss, (unsigned long )addr, + size, +0x80 | entry,0 ); +#endif +} + +static inline void __set_tss_desc (unsigned cpu,unsigned int entry,void *addr) +{ +struct desc_struct *d =get_cpu_gdt_table (cpu); +tss_desc tss; + +/* +* sizeof(unsigned long) coming from an extra "long" at the end +* of the iobitmap. See tss_struct definition in processor.h +* +* -1? seg base+limit should be pointing to the address of the +* last valid byte +*/ +pack_tss (&tss, (unsigned long )addr, +IO_BITMAP_OFFSET +IO_BITMAP_BYTES +sizeof (unsigned long ) -1 , +DESC_TSS ); +write_gdt_entry (d, entry, &tss,DESC_TSS ); +} + +#define set_tss_desc (cpu, addr) __set_tss_desc(cpu, GDT_ENTRY_TSS, addr) +static inline void native_set_ldt (const void *addr,unsigned int entries) {if (likely (entries ==0 ))
@@ -222,12 +255,6 @@ static inline void native_load_tls(struc gdt[GDT_ENTRY_TLS_MIN + i] = t->tls_array[i]; } -#ifdef CONFIG_X86_32 -# include "desc_32.h" -#else -# include "desc_64.h" -#endif -#define _LDT_empty (info) (\ (info)->base_addr == 0 && \ (info)->limit == 0 && \
include/asm-x86/desc_32.h deleted +0 -27
@@ -1,27 +0,0 @@ -#ifndef __ARCH_DESC_H -#define __ARCH_DESC_H - -#include <asm/ldt.h> -#include <asm/segment.h> -#include <asm/desc_defs.h> - -#ifndef __ASSEMBLY__ - -#include <linux/preempt.h> -#include <linux/percpu.h> - -static inline void __set_tss_desc (unsigned int cpu,unsigned int entry,const void *addr) -{ -tss_desc tss; -pack_descriptor (&tss, (unsigned long )addr, - offsetof(struct tss_struct , __cacheline_filler) -1 , -DESC_TSS ,0 ); -write_gdt_entry (get_cpu_gdt_table (cpu), entry, &tss,DESC_TSS ); -} - - -#define set_tss_desc (cpu,addr) __set_tss_desc(cpu, GDT_ENTRY_TSS, addr) - -#endif /* !__ASSEMBLY__ */ - -#endif
include/asm-x86/desc_64.h +0 -33
@@ -1,34 +1 @@ -/* Written 2000 by Andi Kleen */ -#ifndef __ARCH_DESC_H -#define __ARCH_DESC_H -#include <linux/threads.h> -#include <asm/ldt.h> - -#ifndef __ASSEMBLY__ - -#include <linux/string.h> - -#include <asm/segment.h> - -static inline void set_tss_desc (unsigned cpu,void *addr) -{ -struct desc_struct *d =get_cpu_gdt_table (cpu); -tss_desc tss; - -/* -* sizeof(unsigned long) coming from an extra "long" at the end -* of the iobitmap. See tss_struct definition in processor.h -* -* -1? seg base+limit should be pointing to the address of the -* last valid byte -*/ -set_tssldt_descriptor (&tss, - (unsigned long )addr,DESC_TSS , -IO_BITMAP_OFFSET +IO_BITMAP_BYTES +sizeof (unsigned long ) -1 ); -write_gdt_entry (d,GDT_ENTRY_TSS , &tss,DESC_TSS ); -} - -#endif /* !__ASSEMBLY__ */ - -#endif
Re: [PATCH 19/19] unify set_tss_desc
include/asm-x86/desc.h static inline void pack_ldt(ldt_desc *ld · line 177
Quoted 10 lines
include/asm-x86/desc.h +10
-0+static inline void pack_tss (tss_desc *tss,unsigned long addr, +unsigned size,unsigned entry) +{ +#ifdef CONFIG_X86_64 +set_tssldt_descriptor (tss, + addr, entry, size); +#else +pack_descriptor (tss, (unsigned long )addr, + size, +0x80 | entry,0 );
It would be better if you just unified that first instead of ifdef'ing. I guess i386 could get a set_tssldt_descriptor() like wrapper around pack_descriptor().
-Andi
Re: [PATCH 19/19] unify set_tss_desc
In reply to Glauber de Oliveira Costainclude/asm-x86/desc.h static inline void pack_ldt(ldt_desc *ld · line 177
Quoted 10 lines
include/asm-x86/desc.h +10
-0+static inline void pack_tss (tss_desc *tss,unsigned long addr, +unsigned size,unsigned entry) +{ +#ifdef CONFIG_X86_64 +set_tssldt_descriptor (tss, + addr, entry, size); +#else +pack_descriptor (tss, (unsigned long )addr, + size, +0x80 | entry,0 );
It would be better if you just unified that first instead of ifdef'ing. I guess i386 could get a set_tssldt_descriptor() like wrapper around pack_descriptor().
-Andi
Re: [PATCH 19/19] unify set_tss_desc
Quoted 6 lines · Andi Kleen
Quoted 6 lines
include/asm-x86/desc.h +6
-0+static inline void pack_tss (tss_desc *tss,unsigned long addr, +unsigned size,unsigned entry) +{ +#ifdef CONFIG_X86_64 +set_tssldt_descriptor (tss, + addr, entry, size);
Quoted 8 lines
include/asm-x86/desc.h static inline void pack_ldt(ldt_desc *ld · line 177
Quoted 4 lines
include/asm-x86/desc.h +4
-0+#else +pack_descriptor (tss, (unsigned long )addr, + size, +0x80 | entry,0 );It would be better if you just unified that first instead of ifdef'ing. I guess i386 could get a
set_tssldt_descriptor()like wrapper aroundpack_descriptor().
Good point.
Thanks, Andi.
cover desc_struct integration
In reply to Glauber de Oliveira CostaSince the last version of it received no comments on the interfaces, here it goes a version, that I feel ready for inclusion.
The comments regarding style, specially the elimination of the #defines in the desc_struct definition were merged. I also implemented the vmi functions,
missing last time.
Ingo, in the absense of further complaints, could you please push to the x86 tree?
cover desc_struct integration
In reply to Glauber de Oliveira CostaSince the last version of it received no comments on the interfaces, here it goes a version, that I feel ready for inclusion.
The comments regarding style, specially the elimination of the #defines in the desc_struct definition were merged. I also implemented the vmi functions,
missing last time.
Ingo, in the absense of further complaints, could you please push to the x86 tree?
PATCH 1/19 unify desc_struct
This patch aims to make the access of struct desc_struct variables equal across architectures. In this patch, I unify the i386 and x86_64 versions under an anonymous union, keeping the way they are accessed untouched (a and b for 32-bit code, individual bit-fields for 64-bit).
This solution is not beautiful, but will allow us to integrate common code that differed by the way descriptors were used. This is to be viewed incrementally. There's simply too much code to be fixed at once.
In the future, goal is to set up in a single way of acessing the desc_struct fields.
--- arch/x86/kernel/apm_32.c | 2 +- arch/x86/kernel/cpu/common.c | 28 ++++++++++++++-------------- arch/x86/kernel/process_64.c | 2 +- arch/x86/kernel/traps_32.c | 2 +- include/asm-x86/desc_defs.h | 25 +++++++++++++++++-------- include/asm-x86/lguest.h | 4 ++-- include/asm-x86/processor_32.h | 5 +---- 7 files changed, 37 insertions(+), 31 deletions(-)
arch/x86/kernel/apm_32.c +1 -1
@@ -405,7 +405,7 @@ static DECLARE_WAIT_QUEUE_HEAD(apm_waitqstatic DECLARE_WAIT_QUEUE_HEAD (apm_suspend_waitqueue);static struct apm_user * user_list;static DEFINE_SPINLOCK (user_list_lock); -static const struct desc_struct bad_bios_desc = {0 ,0x00409200 }; +static const struct desc_struct bad_bios_desc = { { {0 ,0x00409200 } } };static const char driver_version[] ="1.16ac" ;/* no spaces */
arch/x86/kernel/cpu/common.c +21 -14
@@ -22,31 +22,38 @@#include "cpu.h" DEFINE_PER_CPU(struct gdt_page, gdt_page) = { .gdt = { - [GDT_ENTRY_KERNEL_CS ] = {0x0000ffff ,0x00cf9a00 }, - [GDT_ENTRY_KERNEL_DS ] = {0x0000ffff ,0x00cf9200 }, - [GDT_ENTRY_DEFAULT_USER_CS ] = {0x0000ffff ,0x00cffa00 }, - [GDT_ENTRY_DEFAULT_USER_DS ] = {0x0000ffff ,0x00cff200 }, + [GDT_ENTRY_KERNEL_CS ] = { { {0x0000ffff ,0x00cf9a00 } } }, + [GDT_ENTRY_KERNEL_DS ] = { { {0x0000ffff ,0x00cf9200 } } }, + [GDT_ENTRY_DEFAULT_USER_CS ] = { { {0x0000ffff ,0x00cffa00 } } }, + [GDT_ENTRY_DEFAULT_USER_DS ] = { { {0x0000ffff ,0x00cff200 } } },/* * Segments used for calling PnP BIOS have byte granularity. * They code segments and data segments have fixed 64k limits, * the transfer segment sizes are set at run time. */ - [GDT_ENTRY_PNPBIOS_CS32 ] = {0x0000ffff ,0x00409a00 },/* 32-bit code */ - [GDT_ENTRY_PNPBIOS_CS16 ] = {0x0000ffff ,0x00009a00 },/* 16-bit code */ - [GDT_ENTRY_PNPBIOS_DS ] = {0x0000ffff ,0x00009200 },/* 16-bit data */ - [GDT_ENTRY_PNPBIOS_TS1 ] = {0x00000000 ,0x00009200 },/* 16-bit data */ - [GDT_ENTRY_PNPBIOS_TS2 ] = {0x00000000 ,0x00009200 },/* 16-bit data */ +/* 32-bit code */ + [GDT_ENTRY_PNPBIOS_CS32 ] = { { {0x0000ffff ,0x00409a00 } } }, +/* 16-bit code */ + [GDT_ENTRY_PNPBIOS_CS16 ] = { { {0x0000ffff ,0x00009a00 } } }, +/* 16-bit data */ + [GDT_ENTRY_PNPBIOS_DS ] = { { {0x0000ffff ,0x00009200 } } }, +/* 16-bit data */ + [GDT_ENTRY_PNPBIOS_TS1 ] = { { {0x00000000 ,0x00009200 } } }, +/* 16-bit data */ + [GDT_ENTRY_PNPBIOS_TS2 ] = { { {0x00000000 ,0x00009200 } } },/* * The APM segments have byte granularity and their bases * are set at run time. All have 64k limits. */ - [GDT_ENTRY_APMBIOS_BASE ] = {0x0000ffff ,0x00409a00 },/* 32-bit code */ +/* 32-bit code */ + [GDT_ENTRY_APMBIOS_BASE ] = { { {0x0000ffff ,0x00409a00 } } },/* 16-bit code */ - [GDT_ENTRY_APMBIOS_BASE +1 ] = {0x0000ffff ,0x00009a00 }, - [GDT_ENTRY_APMBIOS_BASE +2 ] = {0x0000ffff ,0x00409200 },/* data */ + [GDT_ENTRY_APMBIOS_BASE +1 ] = { { {0x0000ffff ,0x00009a00 } } }, +/* data */ + [GDT_ENTRY_APMBIOS_BASE +2 ] = { { {0x0000ffff ,0x00409200 } } }, - [GDT_ENTRY_ESPFIX_SS ] = {0x00000000 ,0x00c09200 }, - [GDT_ENTRY_PERCPU ] = {0x00000000 ,0x00000000 }, + [GDT_ENTRY_ESPFIX_SS ] = { { {0x00000000 ,0x00c09200 } } }, + [GDT_ENTRY_PERCPU ] = { { {0x00000000 ,0x00000000 } } }, } };EXPORT_PER_CPU_SYMBOL_GPL (gdt_page);
arch/x86/kernel/process_64.c +1 -1
@@ -444,7 +444,7 @@ static inline void set_32bit_tls(struct .limit_in_pages = 1, .useable = 1, }; -struct n_desc_struct *desc = (void *)t->thread.tls_array; +struct desc_struct *desc = (void *)t->thread.tls_array; desc += tls; desc->a =LDT_entry_a (&ud); desc->b =LDT_entry_b (&ud);
arch/x86/kernel/traps_32.c +2 -1
@@ -76,7 +76,8 @@ char ignore_fpu_irq = 0;* F0 0F bug workaround.. We have a special link segment * for this. */ -struct desc_struct idt_table[256] __attribute__((__section__(".data.idt"))) = { {0, 0}, }; +struct desc_struct idt_table[256] + __attribute__((__section__(".data.idt"))) = { { { { 0, 0 } } }, }; asmlinkage void divide_error(void); asmlinkage void debug(void);
include/asm-x86/desc_defs.h +17 -8
@@ -11,17 +11,26 @@#include <linux/types.h> +/* +* FIXME: Acessing the desc_struct through its fields is more elegant, +* and should be the one valid thing to do. However, a lot of open code +* still touches the a and b acessors, and doing this allow us to do it +* incrementally. We keep the signature as a struct, rather than an union, +* so we can get rid of it transparently in the future -- glommer +*/ // 8 byte segment descriptor struct desc_struct { -u16 limit0; -u16 base0; -unsigned base1 :8 , type :4 , s :1 , dpl :2 , p :1 ; -unsigned limit :4 , avl :1 , l :1 , d :1 , g :1 , base2 :8 ; -} __attribute__((packed)); +union { +struct {unsigned int a, b; }; +struct { +u16 limit0; +u16 base0; +unsigned base1:8 , type:4 , s:1 , dpl:2 , p:1 ; +unsigned limit:4 , avl:1 , l:1 , d:1 , g:1 , base2:8 ; + }; -struct n_desc_struct { -unsigned int a,b; -}; + }; +} __attribute__((packed));enum {GATE_INTERRUPT =0xE ,
include/asm-x86/lguest.h +2 -2
@@ -78,8 +78,8 @@ static inline void lguest_set_ts(void) }/* Full 4G segment descriptors, suitable for CS and DS. */ -#define FULL_EXEC_SEGMENT ((struct desc_struct){0x0000ffff, 0x00cf9b00}) -#define FULL_SEGMENT ((struct desc_struct){0x0000ffff, 0x00cf9300}) +#define FULL_EXEC_SEGMENT ((struct desc_struct){ { {0x0000ffff, 0x00cf9b00} } }) +#define FULL_SEGMENT ((struct desc_struct){ { {0x0000ffff, 0x00cf9300} } })#endif /* __ASSEMBLY__ */
include/asm-x86/processor_32.h +1 -4
@@ -20,14 +20,11 @@#include <linux/cpumask.h> #include <linux/init.h> #include <asm/processor-flags.h> +#include <asm/desc_defs.h> /* flag for disabling the tsc */ extern int tsc_disable; -struct desc_struct { -unsigned long a,b; -}; -static inline int desc_empty (const void *ptr) {const u32 *desc = ptr;
PATCH 2/19 unify struct desc_ptr
This patch unifies struct desc_ptr between i386 and x86_64. They can be expressed in the exact same way in C code, only having to change the name of one of them. As Xgt_desc_struct is ugly and big, this is the one that goes away.
There's also a padding field in i386, but it is not really needed in the C structure definition.
--- arch/x86/kernel/asm-offsets_32.c | 5 ++--- arch/x86/kernel/cpu/common.c | 2 +- arch/x86/kernel/doublefault_32.c | 2 +- arch/x86/kernel/efi_32.c | 4 ++-- arch/x86/kernel/machine_kexec_32.c | 4 ++-- arch/x86/kernel/reboot_32.c | 2 +- arch/x86/lguest/boot.c | 4 ++-- arch/x86/xen/enlighten.c | 10 +++++----- drivers/kvm/svm.c | 2 +- include/asm-x86/desc_32.h | 16 +++++----------- include/asm-x86/lguest.h | 8 ++++---- include/asm-x86/paravirt.h | 18 +++++++++--------- include/asm-x86/processor_32.h | 2 +- include/asm-x86/suspend_32.h | 4 ++-- 14 files changed, 38 insertions(+), 45 deletions(-)
arch/x86/kernel/asm-offsets_32.c +2 -3
@@ -70,9 +70,8 @@ void foo(void)OFFSET (TI_cpu, thread_info, cpu);BLANK (); -OFFSET (GDS_size, Xgt_desc_struct, size); -OFFSET (GDS_address, Xgt_desc_struct, address); -OFFSET (GDS_pad, Xgt_desc_struct, pad); +OFFSET (GDS_size, desc_ptr, size); +OFFSET (GDS_address, desc_ptr, address);BLANK ();OFFSET (PT_EBX , pt_regs, bx);
arch/x86/kernel/cpu/common.c +1 -1
@@ -649,7 +649,7 @@ struct pt_regs * __devinit idle_regs(str* it's on the real one. */ void switch_to_new_gdt (void ) { -struct Xgt_desc_struct gdt_descr; +struct desc_ptr gdt_descr; gdt_descr.address = (long )get_cpu_gdt_table (smp_processor_id ()); gdt_descr.size =GDT_SIZE -1 ;
arch/x86/kernel/doublefault_32.c +1 -1
@@ -17,7 +17,7 @@ static unsigned long doublefault_stack[Dstatic void doublefault_fn (void ) { -struct Xgt_desc_struct gdt_desc = {0 ,0 }; +struct desc_ptr gdt_desc = {0 ,0 };unsigned long gdt, tss;store_gdt (&gdt_desc);
arch/x86/kernel/efi_32.c +2 -2
@@ -69,7 +69,7 @@ static void efi_call_phys_prelog(void) _ {unsigned long cr4;unsigned long temp; -struct Xgt_desc_struct gdt_descr; +struct desc_ptr gdt_descr;spin_lock (&efi_rt_lock);local_irq_save (efi_rt_eflags);
@@ -111,7 +111,7 @@ static void efi_call_phys_prelog(void) _static void efi_call_phys_epilog (void )__releases (efi_rt_lock) {unsigned long cr4; -struct Xgt_desc_struct gdt_descr; +struct desc_ptr gdt_descr; gdt_descr.address = (unsigned long )get_cpu_gdt_table (0 ); gdt_descr.size =GDT_SIZE -1 ;
arch/x86/kernel/machine_kexec_32.c +2 -2
@@ -32,7 +32,7 @@ static u32 kexec_pte1[1024] PAGE_ALIGNEDstatic void set_idt (void *newidt,__u16 limit) { -struct Xgt_desc_struct curidt; +struct desc_ptr curidt;/* ia32 supports unaliged loads & stores */ curidt.size = limit;
@@ -44,7 +44,7 @@ static void set_idt(void *newidt, __u16static void set_gdt (void *newgdt,__u16 limit) { -struct Xgt_desc_struct curgdt; +struct desc_ptr curgdt;/* ia32 supports unaligned loads & stores */ curgdt.size = limit;
arch/x86/kernel/reboot_32.c +1 -1
@@ -161,7 +161,7 @@ real_mode_gdt_entries [3] = 0x000092000100ffffULL /* 16-bit real-mode 64k data at 0x00000100 */ }; -static struct Xgt_desc_struct +static struct desc_ptr real_mode_gdt = {sizeof (real_mode_gdt_entries) -1 , (long )real_mode_gdt_entries }, real_mode_idt = {0x3ff ,0 }, no_idt = {0 ,0 };
arch/x86/lguest/boot.c +2 -2
@@ -229,7 +229,7 @@ static void lguest_write_idt_entry(struc/* Changing to a different IDT is very rare: we keep the IDT up-to-date every * time it is written, so we can simply loop through all entries and tell the * Host about them. */ -static void lguest_load_idt (const struct Xgt_desc_struct *desc) +static void lguest_load_idt (const struct desc_ptr *desc) {unsigned int i;struct desc_struct *idt = (void *)desc->address;
@@ -252,7 +252,7 @@ static void lguest_load_idt(const struct* hypercall and use that repeatedly to load a new IDT. I don't think it * really matters, but wouldn't it be nice if they were the same? */ -static void lguest_load_gdt (const struct Xgt_desc_struct *desc) +static void lguest_load_gdt (const struct desc_ptr *desc) {BUG_ON ((desc->size+1 )/8 !=GDT_ENTRIES );hcall (LHCALL_LOAD_GDT ,__pa (desc->address),GDT_ENTRIES ,0 );
arch/x86/xen/enlighten.c +5 -5
@@ -295,7 +295,7 @@ static void xen_set_ldt(const void *addrxen_mc_issue (PARAVIRT_LAZY_CPU ); } -static void xen_load_gdt (const struct Xgt_desc_struct *dtr) +static void xen_load_gdt (const struct desc_ptr *dtr) {unsigned long *frames;unsigned long va = dtr->address;
@@ -395,7 +395,7 @@ static int cvt_gate_to_trap(int vector, }/* Locations of each CPU's IDT */ -static DEFINE_PER_CPU(struct Xgt_desc_struct, idt_desc); +static DEFINE_PER_CPU(struct desc_ptr, idt_desc);/* Set an IDT entry. If the entry is part of the current IDT, then also update Xen. */
@@ -427,7 +427,7 @@ static void xen_write_idt_entry(struct dpreempt_enable (); } -static void xen_convert_trap_info (const struct Xgt_desc_struct *desc, +static void xen_convert_trap_info (const struct desc_ptr *desc,struct trap_info *traps) {unsigned in, out, count;
@@ -446,7 +446,7 @@ static void xen_convert_trap_info(constvoid xen_copy_trap_info (struct trap_info *traps) { -const struct Xgt_desc_struct *desc = &__get_cpu_var (idt_desc); +const struct desc_ptr *desc = &__get_cpu_var (idt_desc);xen_convert_trap_info (desc, traps); }
@@ -454,7 +454,7 @@ void xen_copy_trap_info(struct trap_info/* Load a new IDT into Xen. In principle this can be per-CPU, so we hold a spinlock to protect the static traps[] array (static because it avoids allocation, and saves stack space). */ -static void xen_load_idt (const struct Xgt_desc_struct *desc) +static void xen_load_idt (const struct desc_ptr *desc) {static DEFINE_SPINLOCK (lock);static struct trap_info traps[257 ];
drivers/kvm/svm.c +1 -1
@@ -290,7 +290,7 @@ static void svm_hardware_enable(void *ga#ifdef CONFIG_X86_64 struct desc_ptr gdt_descr;#else -struct Xgt_desc_struct gdt_descr; +struct desc_ptr gdt_descr;#endif struct desc_struct *gdt;int me =raw_smp_processor_id ();
include/asm-x86/desc_32.h +5 -11
@@ -12,12 +12,6 @@#include <asm/mmu.h> -struct Xgt_desc_struct { -unsigned short size; -unsigned long address __attribute__((packed)); -unsigned short pad; -} __attribute__ ((packed)); -struct gdt_page {struct desc_struct gdt[GDT_ENTRIES ];
@@ -29,7 +23,7 @@ static inline struct desc_struct *get_cpreturn per_cpu (gdt_page, cpu).gdt; } -extern struct Xgt_desc_struct idt_descr; +extern struct desc_ptr idt_descr;extern struct desc_struct idt_table[];extern void set_intr_gate (unsigned int irq,void * addr);
@@ -107,22 +101,22 @@ static inline void native_load_tr_desc(v asmvolatile ("ltr %w0" ::"q" (GDT_ENTRY_TSS *8 )); } -static inline void native_load_gdt (const struct Xgt_desc_struct *dtr) +static inline void native_load_gdt (const struct desc_ptr *dtr) { asmvolatile ("lgdt %0" ::"m" (*dtr)); } -static inline void native_load_idt (const struct Xgt_desc_struct *dtr) +static inline void native_load_idt (const struct desc_ptr *dtr) { asmvolatile ("lidt %0" ::"m" (*dtr)); } -static inline void native_store_gdt (struct Xgt_desc_struct *dtr) +static inline void native_store_gdt (struct desc_ptr *dtr) { asm ("sgdt %0" :"=m" (*dtr)); } -static inline void native_store_idt (struct Xgt_desc_struct *dtr) +static inline void native_store_idt (struct desc_ptr *dtr) { asm ("sidt %0" :"=m" (*dtr)); }
include/asm-x86/lguest.h +4 -4
@@ -44,13 +44,13 @@ struct lguest_ro_state {/* Host information we need to restore when we switch back. */ u32 host_cr3; -struct Xgt_desc_struct host_idt_desc; -struct Xgt_desc_struct host_gdt_desc; +struct desc_ptr host_idt_desc; +struct desc_ptr host_gdt_desc;u32 host_sp;/* Fields which are used when guest is running. */ -struct Xgt_desc_struct guest_idt_desc; -struct Xgt_desc_struct guest_gdt_desc; +struct desc_ptr guest_idt_desc; +struct desc_ptr guest_gdt_desc;struct i386_hw_tss guest_tss;struct desc_struct guest_idt[IDT_ENTRIES ];struct desc_struct guest_gdt[GDT_ENTRIES ];
include/asm-x86/paravirt.h +9 -9
@@ -20,7 +20,7 @@struct page ;struct thread_struct ; -struct Xgt_desc_struct ; +struct desc_ptr ;struct tss_struct ;struct mm_struct ;struct desc_struct ;
@@ -88,10 +88,10 @@ struct pv_cpu_ops {/* Segment descriptor handling */ void (*load_tr_desc)(void ); -void (*load_gdt)(const struct Xgt_desc_struct *); -void (*load_idt)(const struct Xgt_desc_struct *); -void (*store_gdt)(struct Xgt_desc_struct *); -void (*store_idt)(struct Xgt_desc_struct *); +void (*load_gdt)(const struct desc_ptr *); +void (*load_idt)(const struct desc_ptr *); +void (*store_gdt)(struct desc_ptr *); +void (*store_idt)(struct desc_ptr *);void (*set_ldt)(const void *desc,unsigned entries);unsigned long (*store_tr)(void );void (*load_tls)(struct thread_struct *t,unsigned int cpu);
@@ -630,11 +630,11 @@ static inline void load_TR_desc(void) {PVOP_VCALL0 (pv_cpu_ops.load_tr_desc); } -static inline void load_gdt (const struct Xgt_desc_struct *dtr) +static inline void load_gdt (const struct desc_ptr *dtr) {PVOP_VCALL1 (pv_cpu_ops.load_gdt, dtr); } -static inline void load_idt (const struct Xgt_desc_struct *dtr) +static inline void load_idt (const struct desc_ptr *dtr) {PVOP_VCALL1 (pv_cpu_ops.load_idt, dtr); }
@@ -642,11 +642,11 @@ static inline void set_ldt(const void *a {PVOP_VCALL2 (pv_cpu_ops.set_ldt, addr, entries); } -static inline void store_gdt (struct Xgt_desc_struct *dtr) +static inline void store_gdt (struct desc_ptr *dtr) {PVOP_VCALL1 (pv_cpu_ops.store_gdt, dtr); } -static inline void store_idt (struct Xgt_desc_struct *dtr) +static inline void store_idt (struct desc_ptr *dtr) {PVOP_VCALL1 (pv_cpu_ops.store_idt, dtr); }
include/asm-x86/processor_32.h +1 -1
@@ -707,7 +707,7 @@ extern void enable_sep_cpu(void);extern int sysenter_setup (void );/* Defined in head.S */ -extern struct Xgt_desc_struct early_gdt_descr; +extern struct desc_ptr early_gdt_descr;extern void cpu_set_gdt (int );extern void switch_to_new_gdt (void );
include/asm-x86/suspend_32.h +2 -2
@@ -12,8 +12,8 @@ static inline int arch_prepare_suspend(vstruct saved_context {u16 es, fs, gs, ss;unsigned long cr0, cr2, cr3, cr4; -struct Xgt_desc_struct gdt; -struct Xgt_desc_struct idt; +struct desc_ptr gdt; +struct desc_ptr idt;u16 ldt;u16 tss;unsigned long tr;
PATCH 2/19 unify struct desc_ptr
In reply to Glauber de Oliveira CostaThis patch unifies struct desc_ptr between i386 and x86_64. They can be expressed in the exact same way in C code, only having to change the name of one of them. As Xgt_desc_struct is ugly and big, this is the one that goes away.
There's also a padding field in i386, but it is not really needed in the C structure definition.
--- arch/x86/kernel/asm-offsets_32.c | 5 ++--- arch/x86/kernel/cpu/common.c | 2 +- arch/x86/kernel/doublefault_32.c | 2 +- arch/x86/kernel/efi_32.c | 4 ++-- arch/x86/kernel/machine_kexec_32.c | 4 ++-- arch/x86/kernel/reboot_32.c | 2 +- arch/x86/lguest/boot.c | 4 ++-- arch/x86/xen/enlighten.c | 10 +++++----- drivers/kvm/svm.c | 2 +- include/asm-x86/desc_32.h | 16 +++++----------- include/asm-x86/lguest.h | 8 ++++---- include/asm-x86/paravirt.h | 18 +++++++++--------- include/asm-x86/processor_32.h | 2 +- include/asm-x86/suspend_32.h | 4 ++-- 14 files changed, 38 insertions(+), 45 deletions(-)
arch/x86/kernel/asm-offsets_32.c +2 -3
@@ -70,9 +70,8 @@ void foo(void)OFFSET (TI_cpu, thread_info, cpu);BLANK (); -OFFSET (GDS_size, Xgt_desc_struct, size); -OFFSET (GDS_address, Xgt_desc_struct, address); -OFFSET (GDS_pad, Xgt_desc_struct, pad); +OFFSET (GDS_size, desc_ptr, size); +OFFSET (GDS_address, desc_ptr, address);BLANK ();OFFSET (PT_EBX , pt_regs, bx);
arch/x86/kernel/cpu/common.c +1 -1
@@ -649,7 +649,7 @@ struct pt_regs * __devinit idle_regs(str* it's on the real one. */ void switch_to_new_gdt (void ) { -struct Xgt_desc_struct gdt_descr; +struct desc_ptr gdt_descr; gdt_descr.address = (long )get_cpu_gdt_table (smp_processor_id ()); gdt_descr.size =GDT_SIZE -1 ;
arch/x86/kernel/doublefault_32.c +1 -1
@@ -17,7 +17,7 @@ static unsigned long doublefault_stack[Dstatic void doublefault_fn (void ) { -struct Xgt_desc_struct gdt_desc = {0 ,0 }; +struct desc_ptr gdt_desc = {0 ,0 };unsigned long gdt, tss;store_gdt (&gdt_desc);
arch/x86/kernel/efi_32.c +2 -2
@@ -69,7 +69,7 @@ static void efi_call_phys_prelog(void) _ {unsigned long cr4;unsigned long temp; -struct Xgt_desc_struct gdt_descr; +struct desc_ptr gdt_descr;spin_lock (&efi_rt_lock);local_irq_save (efi_rt_eflags);
@@ -111,7 +111,7 @@ static void efi_call_phys_prelog(void) _static void efi_call_phys_epilog (void )__releases (efi_rt_lock) {unsigned long cr4; -struct Xgt_desc_struct gdt_descr; +struct desc_ptr gdt_descr; gdt_descr.address = (unsigned long )get_cpu_gdt_table (0 ); gdt_descr.size =GDT_SIZE -1 ;
arch/x86/kernel/machine_kexec_32.c +2 -2
@@ -32,7 +32,7 @@ static u32 kexec_pte1[1024] PAGE_ALIGNEDstatic void set_idt (void *newidt,__u16 limit) { -struct Xgt_desc_struct curidt; +struct desc_ptr curidt;/* ia32 supports unaliged loads & stores */ curidt.size = limit;
@@ -44,7 +44,7 @@ static void set_idt(void *newidt, __u16static void set_gdt (void *newgdt,__u16 limit) { -struct Xgt_desc_struct curgdt; +struct desc_ptr curgdt;/* ia32 supports unaligned loads & stores */ curgdt.size = limit;
arch/x86/kernel/reboot_32.c +1 -1
@@ -161,7 +161,7 @@ real_mode_gdt_entries [3] = 0x000092000100ffffULL /* 16-bit real-mode 64k data at 0x00000100 */ }; -static struct Xgt_desc_struct +static struct desc_ptr real_mode_gdt = {sizeof (real_mode_gdt_entries) -1 , (long )real_mode_gdt_entries }, real_mode_idt = {0x3ff ,0 }, no_idt = {0 ,0 };
arch/x86/lguest/boot.c +2 -2
@@ -229,7 +229,7 @@ static void lguest_write_idt_entry(struc/* Changing to a different IDT is very rare: we keep the IDT up-to-date every * time it is written, so we can simply loop through all entries and tell the * Host about them. */ -static void lguest_load_idt (const struct Xgt_desc_struct *desc) +static void lguest_load_idt (const struct desc_ptr *desc) {unsigned int i;struct desc_struct *idt = (void *)desc->address;
@@ -252,7 +252,7 @@ static void lguest_load_idt(const struct* hypercall and use that repeatedly to load a new IDT. I don't think it * really matters, but wouldn't it be nice if they were the same? */ -static void lguest_load_gdt (const struct Xgt_desc_struct *desc) +static void lguest_load_gdt (const struct desc_ptr *desc) {BUG_ON ((desc->size+1 )/8 !=GDT_ENTRIES );hcall (LHCALL_LOAD_GDT ,__pa (desc->address),GDT_ENTRIES ,0 );
arch/x86/xen/enlighten.c +5 -5
@@ -295,7 +295,7 @@ static void xen_set_ldt(const void *addrxen_mc_issue (PARAVIRT_LAZY_CPU ); } -static void xen_load_gdt (const struct Xgt_desc_struct *dtr) +static void xen_load_gdt (const struct desc_ptr *dtr) {unsigned long *frames;unsigned long va = dtr->address;
@@ -395,7 +395,7 @@ static int cvt_gate_to_trap(int vector, }/* Locations of each CPU's IDT */ -static DEFINE_PER_CPU(struct Xgt_desc_struct, idt_desc); +static DEFINE_PER_CPU(struct desc_ptr, idt_desc);/* Set an IDT entry. If the entry is part of the current IDT, then also update Xen. */
@@ -427,7 +427,7 @@ static void xen_write_idt_entry(struct dpreempt_enable (); } -static void xen_convert_trap_info (const struct Xgt_desc_struct *desc, +static void xen_convert_trap_info (const struct desc_ptr *desc,struct trap_info *traps) {unsigned in, out, count;
@@ -446,7 +446,7 @@ static void xen_convert_trap_info(constvoid xen_copy_trap_info (struct trap_info *traps) { -const struct Xgt_desc_struct *desc = &__get_cpu_var (idt_desc); +const struct desc_ptr *desc = &__get_cpu_var (idt_desc);xen_convert_trap_info (desc, traps); }
@@ -454,7 +454,7 @@ void xen_copy_trap_info(struct trap_info/* Load a new IDT into Xen. In principle this can be per-CPU, so we hold a spinlock to protect the static traps[] array (static because it avoids allocation, and saves stack space). */ -static void xen_load_idt (const struct Xgt_desc_struct *desc) +static void xen_load_idt (const struct desc_ptr *desc) {static DEFINE_SPINLOCK (lock);static struct trap_info traps[257 ];
drivers/kvm/svm.c +1 -1
@@ -290,7 +290,7 @@ static void svm_hardware_enable(void *ga#ifdef CONFIG_X86_64 struct desc_ptr gdt_descr;#else -struct Xgt_desc_struct gdt_descr; +struct desc_ptr gdt_descr;#endif struct desc_struct *gdt;int me =raw_smp_processor_id ();
include/asm-x86/desc_32.h +5 -11
@@ -12,12 +12,6 @@#include <asm/mmu.h> -struct Xgt_desc_struct { -unsigned short size; -unsigned long address __attribute__((packed)); -unsigned short pad; -} __attribute__ ((packed)); -struct gdt_page {struct desc_struct gdt[GDT_ENTRIES ];
@@ -29,7 +23,7 @@ static inline struct desc_struct *get_cpreturn per_cpu (gdt_page, cpu).gdt; } -extern struct Xgt_desc_struct idt_descr; +extern struct desc_ptr idt_descr;extern struct desc_struct idt_table[];extern void set_intr_gate (unsigned int irq,void * addr);
@@ -107,22 +101,22 @@ static inline void native_load_tr_desc(v asmvolatile ("ltr %w0" ::"q" (GDT_ENTRY_TSS *8 )); } -static inline void native_load_gdt (const struct Xgt_desc_struct *dtr) +static inline void native_load_gdt (const struct desc_ptr *dtr) { asmvolatile ("lgdt %0" ::"m" (*dtr)); } -static inline void native_load_idt (const struct Xgt_desc_struct *dtr) +static inline void native_load_idt (const struct desc_ptr *dtr) { asmvolatile ("lidt %0" ::"m" (*dtr)); } -static inline void native_store_gdt (struct Xgt_desc_struct *dtr) +static inline void native_store_gdt (struct desc_ptr *dtr) { asm ("sgdt %0" :"=m" (*dtr)); } -static inline void native_store_idt (struct Xgt_desc_struct *dtr) +static inline void native_store_idt (struct desc_ptr *dtr) { asm ("sidt %0" :"=m" (*dtr)); }
include/asm-x86/lguest.h +4 -4
@@ -44,13 +44,13 @@ struct lguest_ro_state {/* Host information we need to restore when we switch back. */ u32 host_cr3; -struct Xgt_desc_struct host_idt_desc; -struct Xgt_desc_struct host_gdt_desc; +struct desc_ptr host_idt_desc; +struct desc_ptr host_gdt_desc;u32 host_sp;/* Fields which are used when guest is running. */ -struct Xgt_desc_struct guest_idt_desc; -struct Xgt_desc_struct guest_gdt_desc; +struct desc_ptr guest_idt_desc; +struct desc_ptr guest_gdt_desc;struct i386_hw_tss guest_tss;struct desc_struct guest_idt[IDT_ENTRIES ];struct desc_struct guest_gdt[GDT_ENTRIES ];
include/asm-x86/paravirt.h +9 -9
@@ -20,7 +20,7 @@struct page ;struct thread_struct ; -struct Xgt_desc_struct ; +struct desc_ptr ;struct tss_struct ;struct mm_struct ;struct desc_struct ;
@@ -88,10 +88,10 @@ struct pv_cpu_ops {/* Segment descriptor handling */ void (*load_tr_desc)(void ); -void (*load_gdt)(const struct Xgt_desc_struct *); -void (*load_idt)(const struct Xgt_desc_struct *); -void (*store_gdt)(struct Xgt_desc_struct *); -void (*store_idt)(struct Xgt_desc_struct *); +void (*load_gdt)(const struct desc_ptr *); +void (*load_idt)(const struct desc_ptr *); +void (*store_gdt)(struct desc_ptr *); +void (*store_idt)(struct desc_ptr *);void (*set_ldt)(const void *desc,unsigned entries);unsigned long (*store_tr)(void );void (*load_tls)(struct thread_struct *t,unsigned int cpu);
@@ -630,11 +630,11 @@ static inline void load_TR_desc(void) {PVOP_VCALL0 (pv_cpu_ops.load_tr_desc); } -static inline void load_gdt (const struct Xgt_desc_struct *dtr) +static inline void load_gdt (const struct desc_ptr *dtr) {PVOP_VCALL1 (pv_cpu_ops.load_gdt, dtr); } -static inline void load_idt (const struct Xgt_desc_struct *dtr) +static inline void load_idt (const struct desc_ptr *dtr) {PVOP_VCALL1 (pv_cpu_ops.load_idt, dtr); }
@@ -642,11 +642,11 @@ static inline void set_ldt(const void *a {PVOP_VCALL2 (pv_cpu_ops.set_ldt, addr, entries); } -static inline void store_gdt (struct Xgt_desc_struct *dtr) +static inline void store_gdt (struct desc_ptr *dtr) {PVOP_VCALL1 (pv_cpu_ops.store_gdt, dtr); } -static inline void store_idt (struct Xgt_desc_struct *dtr) +static inline void store_idt (struct desc_ptr *dtr) {PVOP_VCALL1 (pv_cpu_ops.store_idt, dtr); }
include/asm-x86/processor_32.h +1 -1
@@ -707,7 +707,7 @@ extern void enable_sep_cpu(void);extern int sysenter_setup (void );/* Defined in head.S */ -extern struct Xgt_desc_struct early_gdt_descr; +extern struct desc_ptr early_gdt_descr;extern void cpu_set_gdt (int );extern void switch_to_new_gdt (void );
include/asm-x86/suspend_32.h +2 -2
@@ -12,8 +12,8 @@ static inline int arch_prepare_suspend(vstruct saved_context {u16 es, fs, gs, ss;unsigned long cr0, cr2, cr3, cr4; -struct Xgt_desc_struct gdt; -struct Xgt_desc_struct idt; +struct desc_ptr gdt; +struct desc_ptr idt;u16 ldt;u16 tss;unsigned long tr;
PATCH 3/19 change gdt acessor macro name
This patch changes the name of x86_64 macro used to access the per-cpu gdt. It is now equal to the i386 version, which will allow code to be shared.
--- arch/x86/kernel/setup64.c | 2 +- arch/x86/kernel/suspend_64.c | 2 +- arch/x86/kernel/vsyscall_64.c | 2 +- include/asm-x86/desc_64.h | 10 +++++----- 4 files changed, 8 insertions(+), 8 deletions(-)
arch/x86/kernel/setup64.c +1 -1
@@ -228,7 +228,7 @@ void __cpuinit cpu_init (void)* and set up the GDT descriptor: */ if (cpu) -memcpy (cpu_gdt (cpu), cpu_gdt_table,GDT_SIZE ); +memcpy (get_cpu_gdt_table (cpu), cpu_gdt_table,GDT_SIZE ); cpu_gdt_descr[cpu].size =GDT_SIZE ;load_gdt ((const struct desc_ptr *)&cpu_gdt_descr[cpu]);
arch/x86/kernel/suspend_64.c +1 -1
@@ -118,7 +118,7 @@ void fix_processor_context(void)set_tss_desc (cpu,t);/* This just modifies memory; should not be necessary. But... This is necessary, because 386 hardware has concept of busy TSS or some similar stupidity. */ -cpu_gdt (cpu)[GDT_ENTRY_TSS ].type =9 ; +get_cpu_gdt_table (cpu)[GDT_ENTRY_TSS ].type =9 ;syscall_init ();/* This sets MSR_*STAR and related */ load_TR_desc ();/* This does ltr */
arch/x86/kernel/vsyscall_64.c +1 -1
@@ -297,7 +297,7 @@ static void __cpuinit vsyscall_set_cpu(i/* Store cpu number in limit so that it can be loaded quickly in user space in vgetcpu. 12 bits for the CPU and 8 bits for the node. */ - d = (unsigned long *)(cpu_gdt (cpu) +GDT_ENTRY_PER_CPU ); + d = (unsigned long *)(get_cpu_gdt_table (cpu) +GDT_ENTRY_PER_CPU ); *d =0x0f40000000000ULL ; *d |= cpu; *d |= (node &0xf ) <<12 ;
include/asm-x86/desc_64.h +5 -5
@@ -48,7 +48,7 @@ static inline void write_ldt_entry(struc }/* the cpu gdt accessor */ -#define cpu_gdt (_cpu) ((struct desc_struct *)cpu_gdt_descr[_cpu].address) +#define get_cpu_gdt_table (x) ((struct desc_struct *)cpu_gdt_descr[x].address)static inline void load_gdt (const struct desc_ptr *ptr) {
@@ -141,15 +141,15 @@ static inline void set_tss_desc(unsigned* -1? seg base+limit should be pointing to the address of the * last valid byte */ -set_tssldt_descriptor (&cpu_gdt (cpu)[GDT_ENTRY_TSS ], +set_tssldt_descriptor (&get_cpu_gdt_table (cpu)[GDT_ENTRY_TSS ], (unsigned long )addr,DESC_TSS ,IO_BITMAP_OFFSET +IO_BITMAP_BYTES +sizeof (unsigned long ) -1 ); }static inline void set_ldt_desc (unsigned cpu,void *addr,int size) { -set_tssldt_descriptor (&cpu_gdt (cpu)[GDT_ENTRY_LDT ], (unsigned long )addr, -DESC_LDT , size *8 -1 ); +set_tssldt_descriptor (&get_cpu_gdt_table (cpu)[GDT_ENTRY_LDT ], + (unsigned long )addr,DESC_LDT , size *8 -1 ); }#define LDT_entry_a (info) \
@@ -183,7 +183,7 @@ static inline void set_ldt_desc(unsignedstatic inline void load_TLS (struct thread_struct *t,unsigned int cpu) {unsigned int i; -u64 *gdt = (u64 *)(cpu_gdt (cpu) +GDT_ENTRY_TLS_MIN ); +u64 *gdt = (u64 *)(get_cpu_gdt_table (cpu) +GDT_ENTRY_TLS_MIN );for (i =0 ; i <GDT_ENTRY_TLS_ENTRIES ; i++) gdt[i] = t->tls_array[i];
PATCH 4/19 removed unused variable
This variable is not used anywere, and is then removed
--- include/asm-x86/desc_64.h | 5 ----- 1 files changed, 0 insertions(+), 5 deletions(-)
include/asm-x86/desc_64.h +0 -5
@@ -30,11 +30,6 @@ static inline unsigned long __store_tr(void)#define store_tr (tr) (tr) = __store_tr() -/* -* This is the ldt that every process will get unless we need -* something other than this. -*/ -extern struct desc_struct default_ldt[];extern struct gate_struct idt_table[];extern struct desc_ptr cpu_gdt_descr[];
Signature · 1 line
1.5.0.6
PATCH 4/19 removed unused variable
In reply to Glauber de Oliveira CostaThis variable is not used anywere, and is then removed
--- include/asm-x86/desc_64.h | 5 ----- 1 files changed, 0 insertions(+), 5 deletions(-)
include/asm-x86/desc_64.h +0 -5
@@ -30,11 +30,6 @@ static inline unsigned long __store_tr(void)#define store_tr (tr) (tr) = __store_tr() -/* -* This is the ldt that every process will get unless we need -* something other than this. -*/ -extern struct desc_struct default_ldt[];extern struct gate_struct idt_table[];extern struct desc_ptr cpu_gdt_descr[];
Signature · 1 line
1.5.0.6
PATCH 5/19 introduce gate_desc type.
To account for the differences in gate descriptor in i386 and x86_64 a gate_desc type is introduced.
--- arch/x86/kernel/traps_32.c | 3 ++- include/asm-x86/desc_32.h | 15 ++++++++------- include/asm-x86/desc_64.h | 4 ++-- include/asm-x86/desc_defs.h | 8 +++++++- 4 files changed, 19 insertions(+), 11 deletions(-)
arch/x86/kernel/traps_32.c +2 -2
@@ -76,8 +76,8 @@ char ignore_fpu_irq = 0;* F0 0F bug workaround.. We have a special link segment * for this. */ -struct desc_struct idt_table[256] - __attribute__((__section__(".data.idt"))) = { { { { 0, 0 } } }, }; +gate_desc idt_table[256] + __attribute__((__section__(".data.idt"))) = { { { { 0, 0 } } }, }; asmlinkage void divide_error(void); asmlinkage void debug(void);
include/asm-x86/desc_32.h +8 -7
@@ -3,6 +3,7 @@#include <asm/ldt.h> #include <asm/segment.h> +#include <asm/desc_defs.h> #ifndef __ASSEMBLY__
@@ -24,7 +25,7 @@ static inline struct desc_struct *get_cpu_gdt_table(unsigned int cpu) }extern struct desc_ptr idt_descr; -extern struct desc_struct idt_table[]; +extern gate_desc idt_table[];extern void set_intr_gate (unsigned int irq,void * addr); static inline void pack_descriptor(__u32 *a, __u32 *b,
@@ -35,11 +36,11 @@ static inline void pack_descriptor(__u32 *a, __u32 *b, (limit &0x000f0000 ) | ((type &0xff ) <<8 ) | ((flags &0xf ) <<20 ); } -static inline void pack_gate (__u32 *a,__u32 *b, +static inline void pack_gate (gate_desc *gate,unsigned long base,unsigned short seg,unsigned char type,unsigned char flags) { - *a = (seg <<16 ) | (base &0xffff ); - *b = (base &0xffff0000 ) | ((type &0xff ) <<8 ) | (flags &0xff ); + gate->a = (seg <<16 ) | (base &0xffff ); + gate->b = (base &0xffff0000 ) | ((type &0xff ) <<8 ) | (flags &0xff ); }#define DESCTYPE_LDT 0x82/* present, system, DPL-0, LDT */
@@ -139,9 +140,9 @@ static inline void native_load_tls(struct thread_struct *t, unsigned int cpu)static inline void _set_gate (int gate,unsigned int type,void *addr,unsigned short seg) { -__u32 a, b; -pack_gate (&a, &b, (unsigned long )addr, seg, type,0 ); -write_idt_entry (idt_table, gate, a, b); +gate_desc g; +pack_gate (&g, (unsigned long )addr, seg, type,0 ); +write_idt_entry (idt_table, gate, g.a, g.b); }static inline void __set_tss_desc (unsigned int cpu,unsigned int entry,const void *addr)
include/asm-x86/desc_64.h +2 -2
@@ -30,7 +30,7 @@ static inline unsigned long __store_tr(void)#define store_tr (tr) (tr) = __store_tr() -extern struct gate_struct idt_table[]; +extern gate_desc idt_table[];extern struct desc_ptr cpu_gdt_descr[]; static inline void write_ldt_entry(struct desc_struct *ldt,
@@ -58,7 +58,7 @@ static inline void store_gdt(struct desc_ptr *ptr)static inline void _set_gate (void *adr,unsigned type,unsigned long func,unsigned dpl,unsigned ist) { -struct gate_struct s; +gate_desc s; s.offset_low =PTR_LOW (func); s.segment = __KERNEL_CS;
include/asm-x86/desc_defs.h +7 -1
@@ -39,7 +39,7 @@ enum { };// 16byte gate -struct gate_struct { +struct gate_struct64 {u16 offset_low;u16 segment;unsigned ist :3 , zero0 :5 , type :5 , dpl :2 , p :1 ;
@@ -67,6 +67,12 @@ struct ldttss_desc {u32 zero1; } __attribute__((packed)); +#ifdef CONFIG_X86_64 +typedef struct gate_struct64 gate_desc ; +#else +typedef struct desc_struct gate_desc ; +#endif +struct desc_ptr {unsigned short size;unsigned long address;
Signature · 1 line
1.5.0.6
PATCH 5/19 introduce gate_desc type.
In reply to Glauber de Oliveira CostaTo account for the differences in gate descriptor in i386 and x86_64 a gate_desc type is introduced.
--- arch/x86/kernel/traps_32.c | 3 ++- include/asm-x86/desc_32.h | 15 ++++++++------- include/asm-x86/desc_64.h | 4 ++-- include/asm-x86/desc_defs.h | 8 +++++++- 4 files changed, 19 insertions(+), 11 deletions(-)
arch/x86/kernel/traps_32.c +2 -2
@@ -76,8 +76,8 @@ char ignore_fpu_irq = 0;* F0 0F bug workaround.. We have a special link segment * for this. */ -struct desc_struct idt_table[256] - __attribute__((__section__(".data.idt"))) = { { { { 0, 0 } } }, }; +gate_desc idt_table[256] + __attribute__((__section__(".data.idt"))) = { { { { 0, 0 } } }, }; asmlinkage void divide_error(void); asmlinkage void debug(void);
include/asm-x86/desc_32.h +8 -7
@@ -3,6 +3,7 @@#include <asm/ldt.h> #include <asm/segment.h> +#include <asm/desc_defs.h> #ifndef __ASSEMBLY__
@@ -24,7 +25,7 @@ static inline struct desc_struct *get_cpu_gdt_table(unsigned int cpu) }extern struct desc_ptr idt_descr; -extern struct desc_struct idt_table[]; +extern gate_desc idt_table[];extern void set_intr_gate (unsigned int irq,void * addr); static inline void pack_descriptor(__u32 *a, __u32 *b,
@@ -35,11 +36,11 @@ static inline void pack_descriptor(__u32 *a, __u32 *b, (limit &0x000f0000 ) | ((type &0xff ) <<8 ) | ((flags &0xf ) <<20 ); } -static inline void pack_gate (__u32 *a,__u32 *b, +static inline void pack_gate (gate_desc *gate,unsigned long base,unsigned short seg,unsigned char type,unsigned char flags) { - *a = (seg <<16 ) | (base &0xffff ); - *b = (base &0xffff0000 ) | ((type &0xff ) <<8 ) | (flags &0xff ); + gate->a = (seg <<16 ) | (base &0xffff ); + gate->b = (base &0xffff0000 ) | ((type &0xff ) <<8 ) | (flags &0xff ); }#define DESCTYPE_LDT 0x82/* present, system, DPL-0, LDT */
@@ -139,9 +140,9 @@ static inline void native_load_tls(struct thread_struct *t, unsigned int cpu)static inline void _set_gate (int gate,unsigned int type,void *addr,unsigned short seg) { -__u32 a, b; -pack_gate (&a, &b, (unsigned long )addr, seg, type,0 ); -write_idt_entry (idt_table, gate, a, b); +gate_desc g; +pack_gate (&g, (unsigned long )addr, seg, type,0 ); +write_idt_entry (idt_table, gate, g.a, g.b); }static inline void __set_tss_desc (unsigned int cpu,unsigned int entry,const void *addr)
include/asm-x86/desc_64.h +2 -2
@@ -30,7 +30,7 @@ static inline unsigned long __store_tr(void)#define store_tr (tr) (tr) = __store_tr() -extern struct gate_struct idt_table[]; +extern gate_desc idt_table[];extern struct desc_ptr cpu_gdt_descr[]; static inline void write_ldt_entry(struct desc_struct *ldt,
@@ -58,7 +58,7 @@ static inline void store_gdt(struct desc_ptr *ptr)static inline void _set_gate (void *adr,unsigned type,unsigned long func,unsigned dpl,unsigned ist) { -struct gate_struct s; +gate_desc s; s.offset_low =PTR_LOW (func); s.segment = __KERNEL_CS;
include/asm-x86/desc_defs.h +7 -1
@@ -39,7 +39,7 @@ enum { };// 16byte gate -struct gate_struct { +struct gate_struct64 {u16 offset_low;u16 segment;unsigned ist :3 , zero0 :5 , type :5 , dpl :2 , p :1 ;
@@ -67,6 +67,12 @@ struct ldttss_desc {u32 zero1; } __attribute__((packed)); +#ifdef CONFIG_X86_64 +typedef struct gate_struct64 gate_desc ; +#else +typedef struct desc_struct gate_desc ; +#endif +struct desc_ptr {unsigned short size;unsigned long address;
Signature · 1 line
1.5.0.6
PATCH 6/19 change write_idt_entry signature
this patch changes write_idt_entry signature. It now takes a gate_desc instead of the a and b parameters. It will allow it to be later unified between i386 and x86_64.
--- arch/x86/kernel/paravirt_32.c | 2 +- arch/x86/kernel/vmi_32.c | 10 +++++++++- arch/x86/lguest/boot.c | 9 +++++---- arch/x86/xen/enlighten.c | 8 ++++---- include/asm-x86/desc_32.h | 10 ++++++++-- include/asm-x86/paravirt.h | 9 +++++---- 6 files changed, 32 insertions(+), 16 deletions(-)
arch/x86/kernel/paravirt_32.c +1 -1
@@ -381,7 +381,7 @@ struct pv_cpu_ops pv_cpu_ops = { .load_tls = native_load_tls, .write_ldt_entry = write_dt_entry, .write_gdt_entry = write_dt_entry, - .write_idt_entry = write_dt_entry, + .write_idt_entry = native_write_idt_entry, .load_sp0 = native_load_sp0, .irq_enable_syscall_ret = native_irq_enable_syscall_ret,
arch/x86/kernel/vmi_32.c +9 -1
@@ -62,6 +62,7 @@ static struct {void (*cpuid)(void /* non-c */ );void (*_set_ldt)(u32 selector);void (*set_tr)(u32 selector); +void (*write_idt_entry)(struct desc_struct *,int ,u32 ,u32 );void (*set_kernel_stack)(u32 selector,u32 sp0);void (*allocate_page)(u32 ,u32 ,u32 ,u32 ,u32 );void (*release_page)(u32 ,u32 );
@@ -214,6 +215,12 @@ static void vmi_set_tr(void) vmi_ops.set_tr (GDT_ENTRY_TSS *sizeof (struct desc_struct )); } +static void vmi_write_idt_entry (gate_desc *dt,int entry,const gate_desc *g) +{ +u32 *idt_entry = (u32 *)g; + vmi_ops.write_idt_entry (dt, entry, idt_entry[0 ], idt_entry[2 ]); +} +static void vmi_load_sp0 (struct tss_struct *tss,struct thread_struct *thread) {
@@ -792,7 +799,8 @@ static inline int __init activate_vmi(void) pv_cpu_ops.load_tls = vmi_load_tls;para_fill (pv_cpu_ops.write_ldt_entry, WriteLDTEntry);para_fill (pv_cpu_ops.write_gdt_entry, WriteGDTEntry); -para_fill (pv_cpu_ops.write_idt_entry, WriteIDTEntry); +para_wrap (pv_cpu_ops.write_idt_entry, vmi_write_idt_entry, + write_idt_entry, WriteIDTEntry);para_wrap (pv_cpu_ops.load_sp0, vmi_load_sp0, set_kernel_stack, UpdateKernelStack);para_fill (pv_cpu_ops.set_iopl_mask, SetIOPLMask);para_fill (pv_cpu_ops.io_delay, IODelay);
arch/x86/lguest/boot.c +5 -4
@@ -217,13 +217,14 @@ static void irq_enable(void)* address of the handler, and... well, who cares? The Guest just asks the * Host to make the change anyway, because the Host controls the real IDT. */ -static void lguest_write_idt_entry (struct desc_struct *dt, -int entrynum,u32 low,u32 high) +static void lguest_write_idt_entry (gate_desc *dt, +int entrynum,const gate_desc *g) { +u32 *desc = (u32 *)g;/* Keep the local copy up to date. */ -write_dt_entry (dt, entrynum, low, high); +native_write_idt_entry (dt, entrynum, g);/* Tell Host about this new entry. */ -hcall (LHCALL_LOAD_IDT_ENTRY , entrynum, low, high); +hcall (LHCALL_LOAD_IDT_ENTRY , entrynum, desc[0 ], desc[1 ]); }/* Changing to a different IDT is very rare: we keep the IDT up-to-date every
arch/x86/xen/enlighten.c +4 -4
@@ -399,8 +399,7 @@ static DEFINE_PER_CPU(struct desc_ptr, idt_desc);/* Set an IDT entry. If the entry is part of the current IDT, then also update Xen. */ -static void xen_write_idt_entry (struct desc_struct *dt,int entrynum, -u32 low,u32 high) +static void xen_write_idt_entry (gate_desc *dt,int entrynum,const gate_desc *g) {unsigned long p = (unsigned long )&dt[entrynum];unsigned long start, end;
@@ -412,14 +411,15 @@ static void xen_write_idt_entry(struct desc_struct *dt, int entrynum,xen_mc_flush (); -write_dt_entry (dt, entrynum, low, high); +native_write_idt_entry (dt, entrynum, g);if (p >= start && (p +8 ) <= end) {struct trap_info info[2 ]; +u32 *desc = (u32 *)g; info[1 ].address =0 ; -if (cvt_gate_to_trap (entrynum, low, high, &info[0 ])) +if (cvt_gate_to_trap (entrynum, desc[0 ], desc[1 ], &info[0 ]))if (HYPERVISOR_set_trap_table (info))BUG (); }
include/asm-x86/desc_32.h +8 -2
@@ -70,9 +70,15 @@ static inline void pack_gate(gate_desc *gate,#define write_ldt_entry (dt, entry, a, b) write_dt_entry(dt, entry, a, b)#define write_gdt_entry (dt, entry, a, b) write_dt_entry(dt, entry, a, b) -#define write_idt_entry (dt, entry, a, b) write_dt_entry(dt, entry, a, b) +#define write_idt_entry (dt, entry, g) native_write_idt_entry(dt, entry, g)#endif +static inline void native_write_idt_entry (gate_desc *idt,int entry, +const gate_desc *gate) +{ +memcpy (&idt[entry], gate,sizeof (*gate)); +} +static inline void write_dt_entry (struct desc_struct *dt,int entry,u32 entry_low,u32 entry_high) {
@@ -142,7 +148,7 @@ static inline void _set_gate(int gate, unsigned int type, void *addr, unsigned s {gate_desc g;pack_gate (&g, (unsigned long )addr, seg, type,0 ); -write_idt_entry (idt_table, gate, g.a, g.b); +write_idt_entry (idt_table, gate, &g); }static inline void __set_tss_desc (unsigned int cpu,unsigned int entry,const void *addr)
include/asm-x86/paravirt.h +5 -4
@@ -17,6 +17,7 @@#include <linux/types.h> #include <linux/cpumask.h> #include <asm/kmap_types.h> +#include <asm/desc_defs.h> struct page ;struct thread_struct ;
@@ -99,8 +100,8 @@ struct pv_cpu_ops { int entrynum, u32 low, u32 high);void (*write_gdt_entry)(struct desc_struct *,int entrynum,u32 low,u32 high); -void (*write_idt_entry)(struct desc_struct *, -int entrynum,u32 low,u32 high); +void (*write_idt_entry)(gate_desc *, +int entrynum,const gate_desc *gate);void (*load_sp0)(struct tss_struct *tss,struct thread_struct *t);void (*set_iopl_mask)(unsigned mask);
@@ -667,9 +668,9 @@ static inline void write_gdt_entry(void *dt, int entry, u32 low, u32 high) {PVOP_VCALL4 (pv_cpu_ops.write_gdt_entry, dt, entry, low, high); } -static inline void write_idt_entry (void *dt,int entry,u32 low,u32 high) +static inline void write_idt_entry (gate_desc *dt,int entry,const gate_desc *g) { -PVOP_VCALL4 (pv_cpu_ops.write_idt_entry, dt, entry, low, high); +PVOP_VCALL3 (pv_cpu_ops.write_idt_entry, dt, entry, g); }static inline void set_iopl_mask (unsigned mask) {
Signature · 1 line
1.5.0.6
PATCH 6/19 change write_idt_entry signature
In reply to Glauber de Oliveira Costathis patch changes write_idt_entry signature. It now takes a gate_desc instead of the a and b parameters. It will allow it to be later unified between i386 and x86_64.
--- arch/x86/kernel/paravirt_32.c | 2 +- arch/x86/kernel/vmi_32.c | 10 +++++++++- arch/x86/lguest/boot.c | 9 +++++---- arch/x86/xen/enlighten.c | 8 ++++---- include/asm-x86/desc_32.h | 10 ++++++++-- include/asm-x86/paravirt.h | 9 +++++---- 6 files changed, 32 insertions(+), 16 deletions(-)
arch/x86/kernel/paravirt_32.c +1 -1
@@ -381,7 +381,7 @@ struct pv_cpu_ops pv_cpu_ops = { .load_tls = native_load_tls, .write_ldt_entry = write_dt_entry, .write_gdt_entry = write_dt_entry, - .write_idt_entry = write_dt_entry, + .write_idt_entry = native_write_idt_entry, .load_sp0 = native_load_sp0, .irq_enable_syscall_ret = native_irq_enable_syscall_ret,
arch/x86/kernel/vmi_32.c +9 -1
@@ -62,6 +62,7 @@ static struct {void (*cpuid)(void /* non-c */ );void (*_set_ldt)(u32 selector);void (*set_tr)(u32 selector); +void (*write_idt_entry)(struct desc_struct *,int ,u32 ,u32 );void (*set_kernel_stack)(u32 selector,u32 sp0);void (*allocate_page)(u32 ,u32 ,u32 ,u32 ,u32 );void (*release_page)(u32 ,u32 );
@@ -214,6 +215,12 @@ static void vmi_set_tr(void) vmi_ops.set_tr (GDT_ENTRY_TSS *sizeof (struct desc_struct )); } +static void vmi_write_idt_entry (gate_desc *dt,int entry,const gate_desc *g) +{ +u32 *idt_entry = (u32 *)g; + vmi_ops.write_idt_entry (dt, entry, idt_entry[0 ], idt_entry[2 ]); +} +static void vmi_load_sp0 (struct tss_struct *tss,struct thread_struct *thread) {
@@ -792,7 +799,8 @@ static inline int __init activate_vmi(void) pv_cpu_ops.load_tls = vmi_load_tls;para_fill (pv_cpu_ops.write_ldt_entry, WriteLDTEntry);para_fill (pv_cpu_ops.write_gdt_entry, WriteGDTEntry); -para_fill (pv_cpu_ops.write_idt_entry, WriteIDTEntry); +para_wrap (pv_cpu_ops.write_idt_entry, vmi_write_idt_entry, + write_idt_entry, WriteIDTEntry);para_wrap (pv_cpu_ops.load_sp0, vmi_load_sp0, set_kernel_stack, UpdateKernelStack);para_fill (pv_cpu_ops.set_iopl_mask, SetIOPLMask);para_fill (pv_cpu_ops.io_delay, IODelay);
arch/x86/lguest/boot.c +5 -4
@@ -217,13 +217,14 @@ static void irq_enable(void)* address of the handler, and... well, who cares? The Guest just asks the * Host to make the change anyway, because the Host controls the real IDT. */ -static void lguest_write_idt_entry (struct desc_struct *dt, -int entrynum,u32 low,u32 high) +static void lguest_write_idt_entry (gate_desc *dt, +int entrynum,const gate_desc *g) { +u32 *desc = (u32 *)g;/* Keep the local copy up to date. */ -write_dt_entry (dt, entrynum, low, high); +native_write_idt_entry (dt, entrynum, g);/* Tell Host about this new entry. */ -hcall (LHCALL_LOAD_IDT_ENTRY , entrynum, low, high); +hcall (LHCALL_LOAD_IDT_ENTRY , entrynum, desc[0 ], desc[1 ]); }/* Changing to a different IDT is very rare: we keep the IDT up-to-date every
arch/x86/xen/enlighten.c +4 -4
@@ -399,8 +399,7 @@ static DEFINE_PER_CPU(struct desc_ptr, idt_desc);/* Set an IDT entry. If the entry is part of the current IDT, then also update Xen. */ -static void xen_write_idt_entry (struct desc_struct *dt,int entrynum, -u32 low,u32 high) +static void xen_write_idt_entry (gate_desc *dt,int entrynum,const gate_desc *g) {unsigned long p = (unsigned long )&dt[entrynum];unsigned long start, end;
@@ -412,14 +411,15 @@ static void xen_write_idt_entry(struct desc_struct *dt, int entrynum,xen_mc_flush (); -write_dt_entry (dt, entrynum, low, high); +native_write_idt_entry (dt, entrynum, g);if (p >= start && (p +8 ) <= end) {struct trap_info info[2 ]; +u32 *desc = (u32 *)g; info[1 ].address =0 ; -if (cvt_gate_to_trap (entrynum, low, high, &info[0 ])) +if (cvt_gate_to_trap (entrynum, desc[0 ], desc[1 ], &info[0 ]))if (HYPERVISOR_set_trap_table (info))BUG (); }
include/asm-x86/desc_32.h +8 -2
@@ -70,9 +70,15 @@ static inline void pack_gate(gate_desc *gate,#define write_ldt_entry (dt, entry, a, b) write_dt_entry(dt, entry, a, b)#define write_gdt_entry (dt, entry, a, b) write_dt_entry(dt, entry, a, b) -#define write_idt_entry (dt, entry, a, b) write_dt_entry(dt, entry, a, b) +#define write_idt_entry (dt, entry, g) native_write_idt_entry(dt, entry, g)#endif +static inline void native_write_idt_entry (gate_desc *idt,int entry, +const gate_desc *gate) +{ +memcpy (&idt[entry], gate,sizeof (*gate)); +} +static inline void write_dt_entry (struct desc_struct *dt,int entry,u32 entry_low,u32 entry_high) {
@@ -142,7 +148,7 @@ static inline void _set_gate(int gate, unsigned int type, void *addr, unsigned s {gate_desc g;pack_gate (&g, (unsigned long )addr, seg, type,0 ); -write_idt_entry (idt_table, gate, g.a, g.b); +write_idt_entry (idt_table, gate, &g); }static inline void __set_tss_desc (unsigned int cpu,unsigned int entry,const void *addr)
include/asm-x86/paravirt.h +5 -4
@@ -17,6 +17,7 @@#include <linux/types.h> #include <linux/cpumask.h> #include <asm/kmap_types.h> +#include <asm/desc_defs.h> struct page ;struct thread_struct ;
@@ -99,8 +100,8 @@ struct pv_cpu_ops { int entrynum, u32 low, u32 high);void (*write_gdt_entry)(struct desc_struct *,int entrynum,u32 low,u32 high); -void (*write_idt_entry)(struct desc_struct *, -int entrynum,u32 low,u32 high); +void (*write_idt_entry)(gate_desc *, +int entrynum,const gate_desc *gate);void (*load_sp0)(struct tss_struct *tss,struct thread_struct *t);void (*set_iopl_mask)(unsigned mask);
@@ -667,9 +668,9 @@ static inline void write_gdt_entry(void *dt, int entry, u32 low, u32 high) {PVOP_VCALL4 (pv_cpu_ops.write_gdt_entry, dt, entry, low, high); } -static inline void write_idt_entry (void *dt,int entry,u32 low,u32 high) +static inline void write_idt_entry (gate_desc *dt,int entry,const gate_desc *g) { -PVOP_VCALL4 (pv_cpu_ops.write_idt_entry, dt, entry, low, high); +PVOP_VCALL3 (pv_cpu_ops.write_idt_entry, dt, entry, g); }static inline void set_iopl_mask (unsigned mask) {
Signature · 1 line
1.5.0.6
PATCH 7/19 introduce ldt_desc type.
this patch introduces ldt_desc type to account for the differences in the ldt descriptor in x86_64 and i386
--- include/asm-x86/desc_64.h | 2 +- include/asm-x86/desc_defs.h | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-)
include/asm-x86/desc_64.h +1 -1
@@ -113,7 +113,7 @@ static inline void store_idt(struct desc_ptr *dtr)static inline void set_tssldt_descriptor (void *ptr,unsigned long tss,unsigned type,unsigned size) { -struct ldttss_desc d; +struct ldttss_desc64 d;memset (&d,0 ,sizeof (d)); d.limit0 = size &0xFFFF ;
include/asm-x86/desc_defs.h +3 -1
@@ -58,7 +58,7 @@ enum { };// LDT or TSS descriptor in the GDT. 16 bytes. -struct ldttss_desc { +struct ldttss_desc64 {u16 limit0;u16 base0;unsigned base1 :8 , type :5 , dpl :2 , p :1 ;
@@ -69,8 +69,10 @@ struct ldttss_desc {#ifdef CONFIG_X86_64 typedef struct gate_struct64 gate_desc ; +typedef struct ldttss_desc64 ldt_desc ;#else typedef struct desc_struct gate_desc ; +typedef struct desc_struct ldt_desc ;#endif struct desc_ptr {
Signature · 1 line
1.5.0.6
PATCH 7/19 introduce ldt_desc type.
In reply to Glauber de Oliveira Costathis patch introduces ldt_desc type to account for the differences in the ldt descriptor in x86_64 and i386
--- include/asm-x86/desc_64.h | 2 +- include/asm-x86/desc_defs.h | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-)
include/asm-x86/desc_64.h +1 -1
@@ -113,7 +113,7 @@ static inline void store_idt(struct desc_ptr *dtr)static inline void set_tssldt_descriptor (void *ptr,unsigned long tss,unsigned type,unsigned size) { -struct ldttss_desc d; +struct ldttss_desc64 d;memset (&d,0 ,sizeof (d)); d.limit0 = size &0xFFFF ;
include/asm-x86/desc_defs.h +3 -1
@@ -58,7 +58,7 @@ enum { };// LDT or TSS descriptor in the GDT. 16 bytes. -struct ldttss_desc { +struct ldttss_desc64 {u16 limit0;u16 base0;unsigned base1 :8 , type :5 , dpl :2 , p :1 ;
@@ -69,8 +69,10 @@ struct ldttss_desc {#ifdef CONFIG_X86_64 typedef struct gate_struct64 gate_desc ; +typedef struct ldttss_desc64 ldt_desc ;#else typedef struct desc_struct gate_desc ; +typedef struct desc_struct ldt_desc ;#endif struct desc_ptr {
Signature · 1 line
1.5.0.6
PATCH 8/19 modify write_ldt function
This patch modifies the write_ldt() function to make use of the new struct desc_struct instead of entry_1 and entry_2 entries
--- arch/x86/kernel/ldt.c | 15 +++++++-------- 1 files changed, 7 insertions(+), 8 deletions(-)
arch/x86/kernel/ldt.c +7 -8
@@ -186,7 +186,7 @@ static int read_default_ldt(void __user *ptr, unsigned long bytecount)static int write_ldt (void __user *ptr,unsigned long bytecount,int oldmode) {struct mm_struct *mm = current->mm; -__u32 entry_1, entry_2; +struct desc_struct ldt;int error;struct user_desc ldt_info;
@@ -218,21 +218,20 @@ static int write_ldt(void __user *ptr, unsigned long bytecount, int oldmode)/* Allow LDTs to be cleared by the user. */ if (ldt_info.base_addr ==0 && ldt_info.limit ==0 ) {if (oldmode ||LDT_empty (&ldt_info)) { - entry_1 =0 ; - entry_2 =0 ; +memset (&ldt,0 ,sizeof (ldt)); goto install; } } - entry_1 =LDT_entry_a (&ldt_info); - entry_2 =LDT_entry_b (&ldt_info); + ldt.a =LDT_entry_a (&ldt_info); + ldt.b =LDT_entry_b (&ldt_info);if (oldmode) - entry_2 &= ~(1 <<20 ); + ldt.avl =0 ;/* Install the new entry ... */ install: -write_ldt_entry (mm->context.ldt, ldt_info.entry_number, entry_1, - entry_2); +write_ldt_entry (mm->context.ldt, ldt_info.entry_number, + ldt.a, ldt.b); error =0 ; out_unlock:
Signature · 1 line
1.5.0.6
PATCH 8/19 modify write_ldt function
In reply to Glauber de Oliveira CostaThis patch modifies the write_ldt() function to make use of the new struct desc_struct instead of entry_1 and entry_2 entries
--- arch/x86/kernel/ldt.c | 15 +++++++-------- 1 files changed, 7 insertions(+), 8 deletions(-)
arch/x86/kernel/ldt.c +7 -8
@@ -186,7 +186,7 @@ static int read_default_ldt(void __user *ptr, unsigned long bytecount)static int write_ldt (void __user *ptr,unsigned long bytecount,int oldmode) {struct mm_struct *mm = current->mm; -__u32 entry_1, entry_2; +struct desc_struct ldt;int error;struct user_desc ldt_info;
@@ -218,21 +218,20 @@ static int write_ldt(void __user *ptr, unsigned long bytecount, int oldmode)/* Allow LDTs to be cleared by the user. */ if (ldt_info.base_addr ==0 && ldt_info.limit ==0 ) {if (oldmode ||LDT_empty (&ldt_info)) { - entry_1 =0 ; - entry_2 =0 ; +memset (&ldt,0 ,sizeof (ldt)); goto install; } } - entry_1 =LDT_entry_a (&ldt_info); - entry_2 =LDT_entry_b (&ldt_info); + ldt.a =LDT_entry_a (&ldt_info); + ldt.b =LDT_entry_b (&ldt_info);if (oldmode) - entry_2 &= ~(1 <<20 ); + ldt.avl =0 ;/* Install the new entry ... */ install: -write_ldt_entry (mm->context.ldt, ldt_info.entry_number, entry_1, - entry_2); +write_ldt_entry (mm->context.ldt, ldt_info.entry_number, + ldt.a, ldt.b); error =0 ; out_unlock:
Signature · 1 line
1.5.0.6
PATCH 9/19 introduce fill_ldt
This patch introduces fill_ldt(), which populates a ldt descriptor from a user_desc in once, instead of relying in the LDT_entry_a and LDT_entry_b macros
--- arch/x86/kernel/ldt.c | 3 +-- arch/x86/kernel/process_64.c | 3 +-- arch/x86/kernel/tls.c | 7 +++---- include/asm-x86/desc_32.h | 15 --------------- include/asm-x86/desc_64.h | 17 ----------------- include/asm-x86/ldt.h | 19 +++++++++++++++++++ 6 files changed, 24 insertions(+), 40 deletions(-)
arch/x86/kernel/ldt.c +1 -2
@@ -223,8 +223,7 @@ static int write_ldt(void __user *ptr, u } } - ldt.a =LDT_entry_a (&ldt_info); - ldt.b =LDT_entry_b (&ldt_info); +fill_ldt (&ldt, &ldt_info);if (oldmode) ldt.avl =0 ;
arch/x86/kernel/process_64.c +1 -2
@@ -446,8 +446,7 @@ static inline void set_32bit_tls(struct };struct desc_struct *desc = (void *)t->thread.tls_array; desc += tls; - desc->a =LDT_entry_a (&ud); - desc->b =LDT_entry_b (&ud); +fill_ldt (desc, &ud); }static inline u32 read_32bit_tls (struct task_struct *t,int tls)
arch/x86/kernel/tls.c +3 -4
@@ -67,10 +67,9 @@ int do_set_thread_area(struct task_strucif (LDT_empty (&info)) { desc[0 ] =0 ; desc[1 ] =0 ; - }else { - desc[0 ] =LDT_entry_a (&info); - desc[1 ] =LDT_entry_b (&info); - } + }else +fill_ldt ((struct desc_struct *)desc, &info); +if (t == ¤t->thread)load_TLS (t, cpu);
include/asm-x86/desc_32.h +0 -15
@@ -163,21 +163,6 @@ static inline void __set_tss_desc(unsign#define set_tss_desc (cpu,addr) __set_tss_desc(cpu, GDT_ENTRY_TSS, addr) -#define LDT_entry_a (info) \ - ((((info)->base_addr & 0x0000ffff) << 16) | ((info)->limit & 0x0ffff)) - -#define LDT_entry_b (info) \ - (((info)->base_addr & 0xff000000) | \ - (((info)->base_addr & 0x00ff0000) >> 16) | \ - ((info)->limit & 0xf0000) | \ - (((info)->read_exec_only ^ 1) << 9) | \ - ((info)->contents << 10) | \ - (((info)->seg_not_present ^ 1) << 15) | \ - ((info)->seg_32bit << 22) | \ - ((info)->limit_in_pages << 23) | \ - ((info)->useable << 20) | \ - 0x7000) -#define LDT_empty (info) (\ (info)->base_addr == 0 && \ (info)->limit == 0 && \
include/asm-x86/desc_64.h +0 -17
@@ -147,23 +147,6 @@ static inline void set_ldt_desc(unsigned (unsigned long)addr, DESC_LDT, size * 8 - 1); } -#define LDT_entry_a (info) \ - ((((info)->base_addr & 0x0000ffff) << 16) | ((info)->limit & 0x0ffff)) -/* Don't allow setting of the lm bit. It is useless anyways because -64bit system calls require __USER_CS. */ -#define LDT_entry_b(info) \ - (((info)->base_addr & 0xff000000) | \ - (((info)->base_addr & 0x00ff0000) >> 16) | \ - ((info)->limit & 0xf0000) | \ - (((info)->read_exec_only ^ 1) << 9) | \ - ((info)->contents << 10) | \ - (((info)->seg_not_present ^ 1) << 15) | \ - ((info)->seg_32bit << 22) | \ - ((info)->limit_in_pages << 23) | \ - ((info)->useable << 20) | \ - /* ((info)->lm << 21) | */ \ - 0x7000) -#define LDT_empty (info) (\ (info)->base_addr == 0 && \ (info)->limit == 0 && \
include/asm-x86/desc.h +29 -0
@@ -1,5 +1,34 @@ +#ifndef _ASM_DESC_H_ +#define _ASM_DESC_H_ + +#ifndef __ASSEMBLY__ +#include <asm/desc_defs.h> +#include <asm/ldt.h> + +static inline void fill_ldt (struct desc_struct *desc,struct user_desc *info) +{ + desc->limit0 = info->limit &0x0ffff ; + desc->base0 = info->base_addr &0x0000ffff ; + + desc->base1 = (info->base_addr &0x00ff0000 ) >>16 ; + desc->type = (info->read_exec_only ^1 ) <<1 ; + desc->type |= info->contents <<2 ; + desc->s =1 ; + desc->dpl =0x3 ; + desc->p = info->seg_not_present ^1 ; + desc->limit = (info->limit &0xf0000 ) >>16 ; + desc->avl = info->useable; + desc->d = info->seg_32bit; + desc->g = info->limit_in_pages; + desc->base2 = (info->base_addr &0xff000000 ) >>24 ; +} + +#endif +#ifdef CONFIG_X86_32 # include "desc_32.h" #else # include "desc_64.h" #endif + +#endif
PATCH 9/19 introduce fill_ldt
In reply to Glauber de Oliveira CostaThis patch introduces fill_ldt(), which populates a ldt descriptor from a user_desc in once, instead of relying in the LDT_entry_a and LDT_entry_b macros
--- arch/x86/kernel/ldt.c | 3 +-- arch/x86/kernel/process_64.c | 3 +-- arch/x86/kernel/tls.c | 7 +++---- include/asm-x86/desc_32.h | 15 --------------- include/asm-x86/desc_64.h | 17 ----------------- include/asm-x86/ldt.h | 19 +++++++++++++++++++ 6 files changed, 24 insertions(+), 40 deletions(-)
arch/x86/kernel/ldt.c +1 -2
@@ -223,8 +223,7 @@ static int write_ldt(void __user *ptr, u } } - ldt.a =LDT_entry_a (&ldt_info); - ldt.b =LDT_entry_b (&ldt_info); +fill_ldt (&ldt, &ldt_info);if (oldmode) ldt.avl =0 ;
arch/x86/kernel/process_64.c +1 -2
@@ -446,8 +446,7 @@ static inline void set_32bit_tls(struct };struct desc_struct *desc = (void *)t->thread.tls_array; desc += tls; - desc->a =LDT_entry_a (&ud); - desc->b =LDT_entry_b (&ud); +fill_ldt (desc, &ud); }static inline u32 read_32bit_tls (struct task_struct *t,int tls)
arch/x86/kernel/tls.c +3 -4
@@ -67,10 +67,9 @@ int do_set_thread_area(struct task_strucif (LDT_empty (&info)) { desc[0 ] =0 ; desc[1 ] =0 ; - }else { - desc[0 ] =LDT_entry_a (&info); - desc[1 ] =LDT_entry_b (&info); - } + }else +fill_ldt ((struct desc_struct *)desc, &info); +if (t == ¤t->thread)load_TLS (t, cpu);
include/asm-x86/desc_32.h +0 -15
@@ -163,21 +163,6 @@ static inline void __set_tss_desc(unsign#define set_tss_desc (cpu,addr) __set_tss_desc(cpu, GDT_ENTRY_TSS, addr) -#define LDT_entry_a (info) \ - ((((info)->base_addr & 0x0000ffff) << 16) | ((info)->limit & 0x0ffff)) - -#define LDT_entry_b (info) \ - (((info)->base_addr & 0xff000000) | \ - (((info)->base_addr & 0x00ff0000) >> 16) | \ - ((info)->limit & 0xf0000) | \ - (((info)->read_exec_only ^ 1) << 9) | \ - ((info)->contents << 10) | \ - (((info)->seg_not_present ^ 1) << 15) | \ - ((info)->seg_32bit << 22) | \ - ((info)->limit_in_pages << 23) | \ - ((info)->useable << 20) | \ - 0x7000) -#define LDT_empty (info) (\ (info)->base_addr == 0 && \ (info)->limit == 0 && \
include/asm-x86/desc_64.h +0 -17
@@ -147,23 +147,6 @@ static inline void set_ldt_desc(unsigned (unsigned long)addr, DESC_LDT, size * 8 - 1); } -#define LDT_entry_a (info) \ - ((((info)->base_addr & 0x0000ffff) << 16) | ((info)->limit & 0x0ffff)) -/* Don't allow setting of the lm bit. It is useless anyways because -64bit system calls require __USER_CS. */ -#define LDT_entry_b(info) \ - (((info)->base_addr & 0xff000000) | \ - (((info)->base_addr & 0x00ff0000) >> 16) | \ - ((info)->limit & 0xf0000) | \ - (((info)->read_exec_only ^ 1) << 9) | \ - ((info)->contents << 10) | \ - (((info)->seg_not_present ^ 1) << 15) | \ - ((info)->seg_32bit << 22) | \ - ((info)->limit_in_pages << 23) | \ - ((info)->useable << 20) | \ - /* ((info)->lm << 21) | */ \ - 0x7000) -#define LDT_empty (info) (\ (info)->base_addr == 0 && \ (info)->limit == 0 && \
include/asm-x86/desc.h +29 -0
@@ -1,5 +1,34 @@ +#ifndef _ASM_DESC_H_ +#define _ASM_DESC_H_ + +#ifndef __ASSEMBLY__ +#include <asm/desc_defs.h> +#include <asm/ldt.h> + +static inline void fill_ldt (struct desc_struct *desc,struct user_desc *info) +{ + desc->limit0 = info->limit &0x0ffff ; + desc->base0 = info->base_addr &0x0000ffff ; + + desc->base1 = (info->base_addr &0x00ff0000 ) >>16 ; + desc->type = (info->read_exec_only ^1 ) <<1 ; + desc->type |= info->contents <<2 ; + desc->s =1 ; + desc->dpl =0x3 ; + desc->p = info->seg_not_present ^1 ; + desc->limit = (info->limit &0xf0000 ) >>16 ; + desc->avl = info->useable; + desc->d = info->seg_32bit; + desc->g = info->limit_in_pages; + desc->base2 = (info->base_addr &0xff000000 ) >>24 ; +} + +#endif +#ifdef CONFIG_X86_32 # include "desc_32.h" #else # include "desc_64.h" #endif + +#endif
PATCH 10/19 provide tss_desc
Provide a new type, tss_desc, to represent the tss descriptor in a unified way accross x86_64 and i386
--- include/asm-x86/desc_defs.h | 2 ++ 1 files changed, 2 insertions(+), 0 deletions(-)
include/asm-x86/desc_defs.h +2 -0
@@ -70,9 +70,11 @@ struct ldttss_desc64 {#ifdef CONFIG_X86_64 typedef struct gate_struct64 gate_desc ;typedef struct ldttss_desc64 ldt_desc ; +typedef struct ldttss_desc64 tss_desc ;#else typedef struct desc_struct gate_desc ;typedef struct desc_struct ldt_desc ; +typedef struct desc_struct tss_desc ;#endif struct desc_ptr {
Signature · 1 line
1.5.0.6
PATCH 10/19 provide tss_desc
In reply to Glauber de Oliveira CostaProvide a new type, tss_desc, to represent the tss descriptor in a unified way accross x86_64 and i386
--- include/asm-x86/desc_defs.h | 2 ++ 1 files changed, 2 insertions(+), 0 deletions(-)
include/asm-x86/desc_defs.h +2 -0
@@ -70,9 +70,11 @@ struct ldttss_desc64 {#ifdef CONFIG_X86_64 typedef struct gate_struct64 gate_desc ;typedef struct ldttss_desc64 ldt_desc ; +typedef struct ldttss_desc64 tss_desc ;#else typedef struct desc_struct gate_desc ;typedef struct desc_struct ldt_desc ; +typedef struct desc_struct tss_desc ;#endif struct desc_ptr {
Signature · 1 line
1.5.0.6
PATCH 11/19 change write_gdt_entry signature.
This patch changes the write_gdt_entry function signature. Instead of the old "a" and "b" parameters, it now receives a pointer to a desc_struct, and the size of the entry being handled. This is because x86_64 can have some 16-byte entries as well as 8-byte ones.
--- arch/x86/kernel/paravirt_32.c | 2 +- arch/x86/kernel/smpcommon_32.c | 7 ++++--- arch/x86/kernel/vmi_32.c | 21 +++++++++++++++------ arch/x86/lguest/boot.c | 6 +++--- arch/x86/xen/enlighten.c | 11 +++++------ include/asm-x86/desc_32.h | 34 ++++++++++++++++++++++------------ include/asm-x86/paravirt.h | 9 ++++++--- 7 files changed, 56 insertions(+), 34 deletions(-)
arch/x86/kernel/paravirt_32.c +1 -1
@@ -380,7 +380,7 @@ struct pv_cpu_ops pv_cpu_ops = { .store_tr = native_store_tr, .load_tls = native_load_tls, .write_ldt_entry = write_dt_entry, - .write_gdt_entry = write_dt_entry, + .write_gdt_entry = native_write_gdt_entry, .write_idt_entry = native_write_idt_entry, .load_sp0 = native_load_sp0,
arch/x86/kernel/smpcommon_32.c +4 -3
@@ -14,10 +14,11 @@ __cpuinit void init_gdt(int cpu) {struct desc_struct *gdt =get_cpu_gdt_table (cpu); -pack_descriptor ((u32 *)&gdt[GDT_ENTRY_PERCPU ].a, - (u32 *)&gdt[GDT_ENTRY_PERCPU ].b, +pack_descriptor (&gdt[GDT_ENTRY_PERCPU ], __per_cpu_offset[cpu],0xFFFFF , -0x80 |DESCTYPE_S |0x2 ,0x8 ); +0x2 |DESCTYPE_S ,0x8 ); + + gdt[GDT_ENTRY_PERCPU ].s =1 ;per_cpu (this_cpu_off, cpu) = __per_cpu_offset[cpu];per_cpu (cpu_number, cpu) = cpu;
arch/x86/kernel/vmi_32.c +15 -6
@@ -63,6 +63,7 @@ static struct {void (*_set_ldt)(u32 selector);void (*set_tr)(u32 selector);void (*write_idt_entry)(struct desc_struct *,int ,u32 ,u32 ); +void (*write_gdt_entry)(struct desc_struct *,int ,u32 ,u32 );void (*set_kernel_stack)(u32 selector,u32 sp0);void (*allocate_page)(u32 ,u32 ,u32 ,u32 ,u32 );void (*release_page)(u32 ,u32 );
@@ -187,7 +188,7 @@ static void vmi_cpuid(unsigned int *ax, unsigned int *bx,static inline void vmi_maybe_load_tls (struct desc_struct *gdt,int nr,struct desc_struct *new) {if (gdt[nr].a != new->a || gdt[nr].b != new->b) -write_gdt_entry (gdt, nr, new->a, new->b); +write_gdt_entry (gdt, nr, new,0 ); }static void vmi_load_tls (struct thread_struct *t,unsigned int cpu)
@@ -201,12 +202,12 @@ static void vmi_load_tls(struct thread_struct *t, unsigned int cpu)static void vmi_set_ldt (const void *addr,unsigned entries) {unsigned cpu =smp_processor_id (); -u32 low, high; +struct desc_struct desc; -pack_descriptor (&low, &high, (unsigned long )addr, +pack_descriptor (&desc, (unsigned long )addr, entries *sizeof (struct desc_struct ) -1 , -DESCTYPE_LDT ,0 ); -write_gdt_entry (get_cpu_gdt_table (cpu),GDT_ENTRY_LDT , low, high); +DESC_LDT ,0 ); +write_gdt_entry (get_cpu_gdt_table (cpu),GDT_ENTRY_LDT , &desc,DESC_LDT ); vmi_ops._set_ldt (entries ?GDT_ENTRY_LDT *sizeof (struct desc_struct ) :0 ); }
@@ -221,6 +222,13 @@ static void vmi_write_idt_entry(gate_desc *dt, int entry, const gate_desc *g) vmi_ops.write_idt_entry (dt, entry, idt_entry[0 ], idt_entry[2 ]); } +static void vmi_write_gdt_entry (struct desc_struct *dt,int entry, +const void *desc,int type) +{ +u32 *gdt_entry = (u32 *)desc; + vmi_ops.write_gdt_entry (dt, entry, gdt_entry[0 ], gdt_entry[2 ]); +} +static void vmi_load_sp0 (struct tss_struct *tss,struct thread_struct *thread) {
@@ -798,7 +806,8 @@ static inline int __init activate_vmi(void)para_fill (pv_cpu_ops.store_tr, GetTR); pv_cpu_ops.load_tls = vmi_load_tls;para_fill (pv_cpu_ops.write_ldt_entry, WriteLDTEntry); -para_fill (pv_cpu_ops.write_gdt_entry, WriteGDTEntry); +para_wrap (pv_cpu_ops.write_gdt_entry, vmi_write_gdt_entry, + write_gdt_entry, WriteGDTEntry);para_wrap (pv_cpu_ops.write_idt_entry, vmi_write_idt_entry, write_idt_entry, WriteIDTEntry);para_wrap (pv_cpu_ops.load_sp0, vmi_load_sp0, set_kernel_stack, UpdateKernelStack);
arch/x86/lguest/boot.c +3 -3
@@ -262,10 +262,10 @@ static void lguest_load_gdt(const struct desc_ptr *desc)/* For a single GDT entry which changes, we do the lazy thing: alter our GDT, * then tell the Host to reload the entire thing. This operation is so rare * that this naive implementation is reasonable. */ -static void lguest_write_gdt_entry (struct desc_struct *dt, -int entrynum,u32 low,u32 high) +static void lguest_write_gdt_entry (struct desc_struct *dt,int entrynum, +const void *desc,int type) { -write_dt_entry (dt, entrynum, low, high); +native_write_gdt_entry (dt, entrynum, desc, type);hcall (LHCALL_LOAD_GDT ,__pa (dt),GDT_ENTRIES ,0 ); }
arch/x86/xen/enlighten.c +5 -6
@@ -475,22 +475,21 @@ static void xen_load_idt(const struct desc_ptr *desc)/* Write a GDT descriptor entry. Ignore LDT descriptors, since they're handled differently. */ static void xen_write_gdt_entry (struct desc_struct *dt,int entry, -u32 low,u32 high) +const void *desc,int type) {preempt_disable (); -switch ((high >>8 ) &0xff ) { -case DESCTYPE_LDT : -case DESCTYPE_TSS : +switch (type) { +case DESC_LDT : +case DESC_TSS :/* ignore */ break ;default : {xmaddr_t maddr =virt_to_machine (&dt[entry]); -u64 desc = (u64 )high <<32 | low;xen_mc_flush (); -if (HYPERVISOR_update_descriptor (maddr.maddr, desc)) +if (HYPERVISOR_update_descriptor (maddr.maddr, *(u64 *)desc))BUG (); }
include/asm-x86/desc_32.h +22 -12
@@ -28,12 +28,13 @@ extern struct desc_ptr idt_descr;extern gate_desc idt_table[];extern void set_intr_gate (unsigned int irq,void * addr); -static inline void pack_descriptor (__u32 *a,__u32 *b, +static inline void pack_descriptor (struct desc_struct *desc,unsigned long base,unsigned long limit,unsigned char type,unsigned char flags) { - *a = ((base &0xffff ) <<16 ) | (limit &0xffff ); - *b = (base &0xff000000 ) | ((base &0xff0000 ) >>16 ) | + desc->a = ((base &0xffff ) <<16 ) | (limit &0xffff ); + desc->b = (base &0xff000000 ) | ((base &0xff0000 ) >>16 ) | (limit &0x000f0000 ) | ((type &0xff ) <<8 ) | ((flags &0xf ) <<20 ); + desc->p =1 ; } static inline void pack_gate(gate_desc *gate,
@@ -69,7 +70,8 @@ static inline void pack_gate(gate_desc *gate,#define set_ldt native_set_ldt#define write_ldt_entry (dt, entry, a, b) write_dt_entry(dt, entry, a, b) -#define write_gdt_entry (dt, entry, a, b) write_dt_entry(dt, entry, a, b) +#define write_gdt_entry (dt, entry, desc, type) \ + native_write_gdt_entry(dt, entry, desc, type)#define write_idt_entry (dt, entry, g) native_write_idt_entry(dt, entry, g)#endif
@@ -79,6 +81,12 @@ static inline void native_write_idt_entry(gate_desc *idt, int entry,memcpy (&idt[entry], gate,sizeof (*gate)); } +static inline void native_write_gdt_entry (struct desc_struct *gdt,int entry, +const void *desc,int type) +{ +memcpy (&gdt[entry], desc,sizeof (struct desc_struct )); +} +static inline void write_dt_entry (struct desc_struct *dt,int entry,u32 entry_low,u32 entry_high) {
@@ -86,18 +94,20 @@ static inline void write_dt_entry(struct desc_struct *dt, dt[entry].b = entry_high; } +static inline void native_set_ldt (const void *addr,unsigned int entries) {if (likely (entries ==0 )) __asm__ __volatile__("lldt %w0" ::"q" (0 ));else {unsigned cpu =smp_processor_id (); -__u32 a, b; +ldt_desc ldt; -pack_descriptor (&a, &b, (unsigned long )addr, +pack_descriptor (&ldt, (unsigned long )addr, entries *sizeof (struct desc_struct ) -1 , -DESCTYPE_LDT ,0 ); -write_gdt_entry (get_cpu_gdt_table (cpu),GDT_ENTRY_LDT , a, b); +DESC_LDT ,0 ); +write_gdt_entry (get_cpu_gdt_table (cpu),GDT_ENTRY_LDT , + &ldt,DESC_LDT ); __asm__ __volatile__("lldt %w0" ::"q" (GDT_ENTRY_LDT *8 )); } }
@@ -153,11 +163,11 @@ static inline void _set_gate(int gate, unsigned int type, void *addr, unsigned sstatic inline void __set_tss_desc (unsigned int cpu,unsigned int entry,const void *addr) { -__u32 a, b; -pack_descriptor (&a, &b, (unsigned long )addr, +tss_desc tss; +pack_descriptor (&tss, (unsigned long )addr, offsetof(struct tss_struct , __cacheline_filler) -1 , -DESCTYPE_TSS ,0 ); -write_gdt_entry (get_cpu_gdt_table (cpu), entry, a, b); +DESC_TSS ,0 ); +write_gdt_entry (get_cpu_gdt_table (cpu), entry, &tss,DESC_TSS ); }
include/asm-x86/paravirt.h +6 -3
@@ -99,7 +99,7 @@ struct pv_cpu_ops {void (*write_ldt_entry)(struct desc_struct *,int entrynum,u32 low,u32 high);void (*write_gdt_entry)(struct desc_struct *, -int entrynum,u32 low,u32 high); +int entrynum,const void *desc,int size);void (*write_idt_entry)(gate_desc *,int entrynum,const gate_desc *gate);void (*load_sp0)(struct tss_struct *tss,struct thread_struct *t);
@@ -664,10 +664,13 @@ static inline void write_ldt_entry(void *dt, int entry, u32 low, u32 high) {PVOP_VCALL4 (pv_cpu_ops.write_ldt_entry, dt, entry, low, high); } -static inline void write_gdt_entry (void *dt,int entry,u32 low,u32 high) + +static inline void write_gdt_entry (struct desc_struct *dt,int entry, +void *desc,int type) { -PVOP_VCALL4 (pv_cpu_ops.write_gdt_entry, dt, entry, low, high); +PVOP_VCALL4 (pv_cpu_ops.write_gdt_entry, dt, entry, desc, type); } +static inline void write_idt_entry (gate_desc *dt,int entry,const gate_desc *g) {PVOP_VCALL3 (pv_cpu_ops.write_idt_entry, dt, entry, g);
Signature · 1 line
1.5.0.6
PATCH 11/19 change write_gdt_entry signature.
In reply to Glauber de Oliveira CostaThis patch changes the write_gdt_entry function signature. Instead of the old "a" and "b" parameters, it now receives a pointer to a desc_struct, and the size of the entry being handled. This is because x86_64 can have some 16-byte entries as well as 8-byte ones.
--- arch/x86/kernel/paravirt_32.c | 2 +- arch/x86/kernel/smpcommon_32.c | 7 ++++--- arch/x86/kernel/vmi_32.c | 21 +++++++++++++++------ arch/x86/lguest/boot.c | 6 +++--- arch/x86/xen/enlighten.c | 11 +++++------ include/asm-x86/desc_32.h | 34 ++++++++++++++++++++++------------ include/asm-x86/paravirt.h | 9 ++++++--- 7 files changed, 56 insertions(+), 34 deletions(-)
arch/x86/kernel/paravirt_32.c +1 -1
@@ -380,7 +380,7 @@ struct pv_cpu_ops pv_cpu_ops = { .store_tr = native_store_tr, .load_tls = native_load_tls, .write_ldt_entry = write_dt_entry, - .write_gdt_entry = write_dt_entry, + .write_gdt_entry = native_write_gdt_entry, .write_idt_entry = native_write_idt_entry, .load_sp0 = native_load_sp0,
arch/x86/kernel/smpcommon_32.c +4 -3
@@ -14,10 +14,11 @@ __cpuinit void init_gdt(int cpu) {struct desc_struct *gdt =get_cpu_gdt_table (cpu); -pack_descriptor ((u32 *)&gdt[GDT_ENTRY_PERCPU ].a, - (u32 *)&gdt[GDT_ENTRY_PERCPU ].b, +pack_descriptor (&gdt[GDT_ENTRY_PERCPU ], __per_cpu_offset[cpu],0xFFFFF , -0x80 |DESCTYPE_S |0x2 ,0x8 ); +0x2 |DESCTYPE_S ,0x8 ); + + gdt[GDT_ENTRY_PERCPU ].s =1 ;per_cpu (this_cpu_off, cpu) = __per_cpu_offset[cpu];per_cpu (cpu_number, cpu) = cpu;
arch/x86/kernel/vmi_32.c +15 -6
@@ -63,6 +63,7 @@ static struct {void (*_set_ldt)(u32 selector);void (*set_tr)(u32 selector);void (*write_idt_entry)(struct desc_struct *,int ,u32 ,u32 ); +void (*write_gdt_entry)(struct desc_struct *,int ,u32 ,u32 );void (*set_kernel_stack)(u32 selector,u32 sp0);void (*allocate_page)(u32 ,u32 ,u32 ,u32 ,u32 );void (*release_page)(u32 ,u32 );
@@ -187,7 +188,7 @@ static void vmi_cpuid(unsigned int *ax, unsigned int *bx,static inline void vmi_maybe_load_tls (struct desc_struct *gdt,int nr,struct desc_struct *new) {if (gdt[nr].a != new->a || gdt[nr].b != new->b) -write_gdt_entry (gdt, nr, new->a, new->b); +write_gdt_entry (gdt, nr, new,0 ); }static void vmi_load_tls (struct thread_struct *t,unsigned int cpu)
@@ -201,12 +202,12 @@ static void vmi_load_tls(struct thread_struct *t, unsigned int cpu)static void vmi_set_ldt (const void *addr,unsigned entries) {unsigned cpu =smp_processor_id (); -u32 low, high; +struct desc_struct desc; -pack_descriptor (&low, &high, (unsigned long )addr, +pack_descriptor (&desc, (unsigned long )addr, entries *sizeof (struct desc_struct ) -1 , -DESCTYPE_LDT ,0 ); -write_gdt_entry (get_cpu_gdt_table (cpu),GDT_ENTRY_LDT , low, high); +DESC_LDT ,0 ); +write_gdt_entry (get_cpu_gdt_table (cpu),GDT_ENTRY_LDT , &desc,DESC_LDT ); vmi_ops._set_ldt (entries ?GDT_ENTRY_LDT *sizeof (struct desc_struct ) :0 ); }
@@ -221,6 +222,13 @@ static void vmi_write_idt_entry(gate_desc *dt, int entry, const gate_desc *g) vmi_ops.write_idt_entry (dt, entry, idt_entry[0 ], idt_entry[2 ]); } +static void vmi_write_gdt_entry (struct desc_struct *dt,int entry, +const void *desc,int type) +{ +u32 *gdt_entry = (u32 *)desc; + vmi_ops.write_gdt_entry (dt, entry, gdt_entry[0 ], gdt_entry[2 ]); +} +static void vmi_load_sp0 (struct tss_struct *tss,struct thread_struct *thread) {
@@ -798,7 +806,8 @@ static inline int __init activate_vmi(void)para_fill (pv_cpu_ops.store_tr, GetTR); pv_cpu_ops.load_tls = vmi_load_tls;para_fill (pv_cpu_ops.write_ldt_entry, WriteLDTEntry); -para_fill (pv_cpu_ops.write_gdt_entry, WriteGDTEntry); +para_wrap (pv_cpu_ops.write_gdt_entry, vmi_write_gdt_entry, + write_gdt_entry, WriteGDTEntry);para_wrap (pv_cpu_ops.write_idt_entry, vmi_write_idt_entry, write_idt_entry, WriteIDTEntry);para_wrap (pv_cpu_ops.load_sp0, vmi_load_sp0, set_kernel_stack, UpdateKernelStack);
arch/x86/lguest/boot.c +3 -3
@@ -262,10 +262,10 @@ static void lguest_load_gdt(const struct desc_ptr *desc)/* For a single GDT entry which changes, we do the lazy thing: alter our GDT, * then tell the Host to reload the entire thing. This operation is so rare * that this naive implementation is reasonable. */ -static void lguest_write_gdt_entry (struct desc_struct *dt, -int entrynum,u32 low,u32 high) +static void lguest_write_gdt_entry (struct desc_struct *dt,int entrynum, +const void *desc,int type) { -write_dt_entry (dt, entrynum, low, high); +native_write_gdt_entry (dt, entrynum, desc, type);hcall (LHCALL_LOAD_GDT ,__pa (dt),GDT_ENTRIES ,0 ); }
arch/x86/xen/enlighten.c +5 -6
@@ -475,22 +475,21 @@ static void xen_load_idt(const struct desc_ptr *desc)/* Write a GDT descriptor entry. Ignore LDT descriptors, since they're handled differently. */ static void xen_write_gdt_entry (struct desc_struct *dt,int entry, -u32 low,u32 high) +const void *desc,int type) {preempt_disable (); -switch ((high >>8 ) &0xff ) { -case DESCTYPE_LDT : -case DESCTYPE_TSS : +switch (type) { +case DESC_LDT : +case DESC_TSS :/* ignore */ break ;default : {xmaddr_t maddr =virt_to_machine (&dt[entry]); -u64 desc = (u64 )high <<32 | low;xen_mc_flush (); -if (HYPERVISOR_update_descriptor (maddr.maddr, desc)) +if (HYPERVISOR_update_descriptor (maddr.maddr, *(u64 *)desc))BUG (); }
include/asm-x86/desc_32.h +22 -12
@@ -28,12 +28,13 @@ extern struct desc_ptr idt_descr;extern gate_desc idt_table[];extern void set_intr_gate (unsigned int irq,void * addr); -static inline void pack_descriptor (__u32 *a,__u32 *b, +static inline void pack_descriptor (struct desc_struct *desc,unsigned long base,unsigned long limit,unsigned char type,unsigned char flags) { - *a = ((base &0xffff ) <<16 ) | (limit &0xffff ); - *b = (base &0xff000000 ) | ((base &0xff0000 ) >>16 ) | + desc->a = ((base &0xffff ) <<16 ) | (limit &0xffff ); + desc->b = (base &0xff000000 ) | ((base &0xff0000 ) >>16 ) | (limit &0x000f0000 ) | ((type &0xff ) <<8 ) | ((flags &0xf ) <<20 ); + desc->p =1 ; } static inline void pack_gate(gate_desc *gate,
@@ -69,7 +70,8 @@ static inline void pack_gate(gate_desc *gate,#define set_ldt native_set_ldt#define write_ldt_entry (dt, entry, a, b) write_dt_entry(dt, entry, a, b) -#define write_gdt_entry (dt, entry, a, b) write_dt_entry(dt, entry, a, b) +#define write_gdt_entry (dt, entry, desc, type) \ + native_write_gdt_entry(dt, entry, desc, type)#define write_idt_entry (dt, entry, g) native_write_idt_entry(dt, entry, g)#endif
@@ -79,6 +81,12 @@ static inline void native_write_idt_entry(gate_desc *idt, int entry,memcpy (&idt[entry], gate,sizeof (*gate)); } +static inline void native_write_gdt_entry (struct desc_struct *gdt,int entry, +const void *desc,int type) +{ +memcpy (&gdt[entry], desc,sizeof (struct desc_struct )); +} +static inline void write_dt_entry (struct desc_struct *dt,int entry,u32 entry_low,u32 entry_high) {
@@ -86,18 +94,20 @@ static inline void write_dt_entry(struct desc_struct *dt, dt[entry].b = entry_high; } +static inline void native_set_ldt (const void *addr,unsigned int entries) {if (likely (entries ==0 )) __asm__ __volatile__("lldt %w0" ::"q" (0 ));else {unsigned cpu =smp_processor_id (); -__u32 a, b; +ldt_desc ldt; -pack_descriptor (&a, &b, (unsigned long )addr, +pack_descriptor (&ldt, (unsigned long )addr, entries *sizeof (struct desc_struct ) -1 , -DESCTYPE_LDT ,0 ); -write_gdt_entry (get_cpu_gdt_table (cpu),GDT_ENTRY_LDT , a, b); +DESC_LDT ,0 ); +write_gdt_entry (get_cpu_gdt_table (cpu),GDT_ENTRY_LDT , + &ldt,DESC_LDT ); __asm__ __volatile__("lldt %w0" ::"q" (GDT_ENTRY_LDT *8 )); } }
@@ -153,11 +163,11 @@ static inline void _set_gate(int gate, unsigned int type, void *addr, unsigned sstatic inline void __set_tss_desc (unsigned int cpu,unsigned int entry,const void *addr) { -__u32 a, b; -pack_descriptor (&a, &b, (unsigned long )addr, +tss_desc tss; +pack_descriptor (&tss, (unsigned long )addr, offsetof(struct tss_struct , __cacheline_filler) -1 , -DESCTYPE_TSS ,0 ); -write_gdt_entry (get_cpu_gdt_table (cpu), entry, a, b); +DESC_TSS ,0 ); +write_gdt_entry (get_cpu_gdt_table (cpu), entry, &tss,DESC_TSS ); }
include/asm-x86/paravirt.h +6 -3
@@ -99,7 +99,7 @@ struct pv_cpu_ops {void (*write_ldt_entry)(struct desc_struct *,int entrynum,u32 low,u32 high);void (*write_gdt_entry)(struct desc_struct *, -int entrynum,u32 low,u32 high); +int entrynum,const void *desc,int size);void (*write_idt_entry)(gate_desc *,int entrynum,const gate_desc *gate);void (*load_sp0)(struct tss_struct *tss,struct thread_struct *t);
@@ -664,10 +664,13 @@ static inline void write_ldt_entry(void *dt, int entry, u32 low, u32 high) {PVOP_VCALL4 (pv_cpu_ops.write_ldt_entry, dt, entry, low, high); } -static inline void write_gdt_entry (void *dt,int entry,u32 low,u32 high) + +static inline void write_gdt_entry (struct desc_struct *dt,int entry, +void *desc,int type) { -PVOP_VCALL4 (pv_cpu_ops.write_gdt_entry, dt, entry, low, high); +PVOP_VCALL4 (pv_cpu_ops.write_gdt_entry, dt, entry, desc, type); } +static inline void write_idt_entry (gate_desc *dt,int entry,const gate_desc *g) {PVOP_VCALL3 (pv_cpu_ops.write_idt_entry, dt, entry, g);
Signature · 1 line
1.5.0.6
PATCH 12/19 change write_ldt_entry signature
this patch changes the signature of write_ldt_entry.
--- arch/x86/kernel/ldt.c | 3 +-- arch/x86/kernel/paravirt_32.c | 2 +- arch/x86/kernel/vmi_32.c | 11 ++++++++++- arch/x86/xen/enlighten.c | 4 ++-- include/asm-x86/desc_32.h | 9 ++++++++- include/asm-x86/desc_64.h | 7 ++----- include/asm-x86/paravirt.h | 10 ++++++---- 7 files changed, 30 insertions(+), 16 deletions(-)
arch/x86/kernel/ldt.c +1 -2
@@ -229,8 +229,7 @@ static int write_ldt(void __user *ptr, unsigned long bytecount, int oldmode)/* Install the new entry ... */ install: -write_ldt_entry (mm->context.ldt, ldt_info.entry_number, - ldt.a, ldt.b); +write_ldt_entry (mm->context.ldt, ldt_info.entry_number, &ldt); error =0 ; out_unlock:
arch/x86/kernel/paravirt_32.c +1 -1
@@ -379,7 +379,7 @@ struct pv_cpu_ops pv_cpu_ops = { .store_idt = native_store_idt, .store_tr = native_store_tr, .load_tls = native_load_tls, - .write_ldt_entry = write_dt_entry, + .write_ldt_entry = native_write_ldt_entry, .write_gdt_entry = native_write_gdt_entry, .write_idt_entry = native_write_idt_entry, .load_sp0 = native_load_sp0,
arch/x86/kernel/vmi_32.c +10 -1
@@ -64,6 +64,7 @@ static struct {void (*set_tr)(u32 selector);void (*write_idt_entry)(struct desc_struct *,int ,u32 ,u32 );void (*write_gdt_entry)(struct desc_struct *,int ,u32 ,u32 ); +void (*write_ldt_entry)(struct desc_struct *,int ,u32 ,u32 );void (*set_kernel_stack)(u32 selector,u32 sp0);void (*allocate_page)(u32 ,u32 ,u32 ,u32 ,u32 );void (*release_page)(u32 ,u32 );
@@ -229,6 +230,13 @@ static void vmi_write_gdt_entry(struct desc_struct *dt, int entry, vmi_ops.write_gdt_entry (dt, entry, gdt_entry[0 ], gdt_entry[2 ]); } +static void vmi_write_ldt_entry (struct desc_struct *dt,int entry, +const void *desc) +{ +u32 *ldt_entry = (u32 *)desc; + vmi_ops.write_idt_entry (dt, entry, ldt_entry[0 ], ldt_entry[2 ]); +} +static void vmi_load_sp0 (struct tss_struct *tss,struct thread_struct *thread) {
@@ -805,7 +813,8 @@ static inline int __init activate_vmi(void)para_fill (pv_cpu_ops.store_idt, GetIDT);para_fill (pv_cpu_ops.store_tr, GetTR); pv_cpu_ops.load_tls = vmi_load_tls; -para_fill (pv_cpu_ops.write_ldt_entry, WriteLDTEntry); +para_wrap (pv_cpu_ops.write_ldt_entry, vmi_write_ldt_entry, + write_ldt_entry, WriteLDTEntry);para_wrap (pv_cpu_ops.write_gdt_entry, vmi_write_gdt_entry, write_gdt_entry, WriteGDTEntry); para_wrap(pv_cpu_ops.write_idt_entry, vmi_write_idt_entry,
arch/x86/xen/enlighten.c +2 -2
@@ -357,11 +357,11 @@ static void xen_load_tls(struct thread_struct *t, unsigned int cpu) }static void xen_write_ldt_entry (struct desc_struct *dt,int entrynum, -u32 low,u32 high) +const void *ptr) {unsigned long lp = (unsigned long )&dt[entrynum];xmaddr_t mach_lp =virt_to_machine (lp); -u64 entry = (u64 )high <<32 | low; +u64 entry = *(u64 *)ptr;preempt_disable ();
include/asm-x86/desc_32.h +8 -1
@@ -69,12 +69,19 @@ static inline void pack_gate(gate_desc *gate,#define load_TLS (t, cpu) native_load_tls(t, cpu)#define set_ldt native_set_ldt -#define write_ldt_entry (dt, entry, a, b) write_dt_entry(dt, entry, a, b) +#define write_ldt_entry (dt, entry, desc) \ + native_write_ldt_entry(dt, entry, desc)#define write_gdt_entry (dt, entry, desc, type) \ native_write_gdt_entry(dt, entry, desc, type)#define write_idt_entry (dt, entry, g) native_write_idt_entry(dt, entry, g)#endif +static inline void native_write_ldt_entry (struct desc_struct *ldt,int entry, +const void *desc) +{ +memcpy (&ldt[entry], desc,sizeof (struct desc_struct )); +} +static inline void native_write_idt_entry (gate_desc *idt,int entry,const gate_desc *gate) {
include/asm-x86/desc_64.h +2 -5
@@ -34,12 +34,9 @@ extern gate_desc idt_table[];extern struct desc_ptr cpu_gdt_descr[];static inline void write_ldt_entry (struct desc_struct *ldt, -int entry,u32 entry_low,u32 entry_high) +int entry,void *ptr) { -__u32 *lp = (__u32 *)((entry <<3 ) + (char *)ldt); - - lp[0 ] = entry_low; - lp[1 ] = entry_high; +memcpy (&ldt[entry], ptr,8 ); }/* the cpu gdt accessor */
include/asm-x86/paravirt.h +6 -4
@@ -96,8 +96,8 @@ struct pv_cpu_ops {void (*set_ldt)(const void *desc,unsigned entries);unsigned long (*store_tr)(void );void (*load_tls)(struct thread_struct *t,unsigned int cpu); -void (*write_ldt_entry)(struct desc_struct *, -int entrynum,u32 low,u32 high); +void (*write_ldt_entry)(struct desc_struct *ldt,int entrynum, +const void *desc);void (*write_gdt_entry)(struct desc_struct *,int entrynum,const void *desc,int size); void (*write_idt_entry)(gate_desc *,
@@ -660,9 +660,11 @@ static inline void load_TLS(struct thread_struct *t, unsigned cpu) {PVOP_VCALL2 (pv_cpu_ops.load_tls, t, cpu); } -static inline void write_ldt_entry (void *dt,int entry,u32 low,u32 high) + +static inline void write_ldt_entry (struct desc_struct *dt,int entry, +const void *desc) { -PVOP_VCALL4 (pv_cpu_ops.write_ldt_entry, dt, entry, low, high); +PVOP_VCALL3 (pv_cpu_ops.write_ldt_entry, dt, entry, desc); } static inline void write_gdt_entry(struct desc_struct *dt, int entry,
Signature · 1 line
1.5.0.6
PATCH 12/19 change write_ldt_entry signature
In reply to Glauber de Oliveira Costathis patch changes the signature of write_ldt_entry.
--- arch/x86/kernel/ldt.c | 3 +-- arch/x86/kernel/paravirt_32.c | 2 +- arch/x86/kernel/vmi_32.c | 11 ++++++++++- arch/x86/xen/enlighten.c | 4 ++-- include/asm-x86/desc_32.h | 9 ++++++++- include/asm-x86/desc_64.h | 7 ++----- include/asm-x86/paravirt.h | 10 ++++++---- 7 files changed, 30 insertions(+), 16 deletions(-)
arch/x86/kernel/ldt.c +1 -2
@@ -229,8 +229,7 @@ static int write_ldt(void __user *ptr, unsigned long bytecount, int oldmode)/* Install the new entry ... */ install: -write_ldt_entry (mm->context.ldt, ldt_info.entry_number, - ldt.a, ldt.b); +write_ldt_entry (mm->context.ldt, ldt_info.entry_number, &ldt); error =0 ; out_unlock:
arch/x86/kernel/paravirt_32.c +1 -1
@@ -379,7 +379,7 @@ struct pv_cpu_ops pv_cpu_ops = { .store_idt = native_store_idt, .store_tr = native_store_tr, .load_tls = native_load_tls, - .write_ldt_entry = write_dt_entry, + .write_ldt_entry = native_write_ldt_entry, .write_gdt_entry = native_write_gdt_entry, .write_idt_entry = native_write_idt_entry, .load_sp0 = native_load_sp0,
arch/x86/kernel/vmi_32.c +10 -1
@@ -64,6 +64,7 @@ static struct {void (*set_tr)(u32 selector);void (*write_idt_entry)(struct desc_struct *,int ,u32 ,u32 );void (*write_gdt_entry)(struct desc_struct *,int ,u32 ,u32 ); +void (*write_ldt_entry)(struct desc_struct *,int ,u32 ,u32 );void (*set_kernel_stack)(u32 selector,u32 sp0);void (*allocate_page)(u32 ,u32 ,u32 ,u32 ,u32 );void (*release_page)(u32 ,u32 );
@@ -229,6 +230,13 @@ static void vmi_write_gdt_entry(struct desc_struct *dt, int entry, vmi_ops.write_gdt_entry (dt, entry, gdt_entry[0 ], gdt_entry[2 ]); } +static void vmi_write_ldt_entry (struct desc_struct *dt,int entry, +const void *desc) +{ +u32 *ldt_entry = (u32 *)desc; + vmi_ops.write_idt_entry (dt, entry, ldt_entry[0 ], ldt_entry[2 ]); +} +static void vmi_load_sp0 (struct tss_struct *tss,struct thread_struct *thread) {
@@ -805,7 +813,8 @@ static inline int __init activate_vmi(void)para_fill (pv_cpu_ops.store_idt, GetIDT);para_fill (pv_cpu_ops.store_tr, GetTR); pv_cpu_ops.load_tls = vmi_load_tls; -para_fill (pv_cpu_ops.write_ldt_entry, WriteLDTEntry); +para_wrap (pv_cpu_ops.write_ldt_entry, vmi_write_ldt_entry, + write_ldt_entry, WriteLDTEntry);para_wrap (pv_cpu_ops.write_gdt_entry, vmi_write_gdt_entry, write_gdt_entry, WriteGDTEntry); para_wrap(pv_cpu_ops.write_idt_entry, vmi_write_idt_entry,
arch/x86/xen/enlighten.c +2 -2
@@ -357,11 +357,11 @@ static void xen_load_tls(struct thread_struct *t, unsigned int cpu) }static void xen_write_ldt_entry (struct desc_struct *dt,int entrynum, -u32 low,u32 high) +const void *ptr) {unsigned long lp = (unsigned long )&dt[entrynum];xmaddr_t mach_lp =virt_to_machine (lp); -u64 entry = (u64 )high <<32 | low; +u64 entry = *(u64 *)ptr;preempt_disable ();
include/asm-x86/desc_32.h +8 -1
@@ -69,12 +69,19 @@ static inline void pack_gate(gate_desc *gate,#define load_TLS (t, cpu) native_load_tls(t, cpu)#define set_ldt native_set_ldt -#define write_ldt_entry (dt, entry, a, b) write_dt_entry(dt, entry, a, b) +#define write_ldt_entry (dt, entry, desc) \ + native_write_ldt_entry(dt, entry, desc)#define write_gdt_entry (dt, entry, desc, type) \ native_write_gdt_entry(dt, entry, desc, type)#define write_idt_entry (dt, entry, g) native_write_idt_entry(dt, entry, g)#endif +static inline void native_write_ldt_entry (struct desc_struct *ldt,int entry, +const void *desc) +{ +memcpy (&ldt[entry], desc,sizeof (struct desc_struct )); +} +static inline void native_write_idt_entry (gate_desc *idt,int entry,const gate_desc *gate) {
include/asm-x86/desc_64.h +2 -5
@@ -34,12 +34,9 @@ extern gate_desc idt_table[];extern struct desc_ptr cpu_gdt_descr[];static inline void write_ldt_entry (struct desc_struct *ldt, -int entry,u32 entry_low,u32 entry_high) +int entry,void *ptr) { -__u32 *lp = (__u32 *)((entry <<3 ) + (char *)ldt); - - lp[0 ] = entry_low; - lp[1 ] = entry_high; +memcpy (&ldt[entry], ptr,8 ); }/* the cpu gdt accessor */
include/asm-x86/paravirt.h +6 -4
@@ -96,8 +96,8 @@ struct pv_cpu_ops {void (*set_ldt)(const void *desc,unsigned entries);unsigned long (*store_tr)(void );void (*load_tls)(struct thread_struct *t,unsigned int cpu); -void (*write_ldt_entry)(struct desc_struct *, -int entrynum,u32 low,u32 high); +void (*write_ldt_entry)(struct desc_struct *ldt,int entrynum, +const void *desc);void (*write_gdt_entry)(struct desc_struct *,int entrynum,const void *desc,int size); void (*write_idt_entry)(gate_desc *,
@@ -660,9 +660,11 @@ static inline void load_TLS(struct thread_struct *t, unsigned cpu) {PVOP_VCALL2 (pv_cpu_ops.load_tls, t, cpu); } -static inline void write_ldt_entry (void *dt,int entry,u32 low,u32 high) + +static inline void write_ldt_entry (struct desc_struct *dt,int entry, +const void *desc) { -PVOP_VCALL4 (pv_cpu_ops.write_ldt_entry, dt, entry, low, high); +PVOP_VCALL3 (pv_cpu_ops.write_ldt_entry, dt, entry, desc); } static inline void write_gdt_entry(struct desc_struct *dt, int entry,
Signature · 1 line
1.5.0.6
PATCH 13/19 move constants to desc_defs.h
this patch moves constant definitions regarding descriptor types from desc_32.h to desc_defs.h. The change from defines to enum to comply with previous versions in desc_defs.h
--- include/asm-x86/desc_32.h | 8 -------- include/asm-x86/desc_defs.h | 5 +++++ 2 files changed, 5 insertions(+), 8 deletions(-)
include/asm-x86/desc_32.h +0 -8
@@ -44,14 +44,6 @@ static inline void pack_gate(gate_desc *gate, gate->b = (base &0xffff0000 ) | ((type &0xff ) <<8 ) | (flags &0xff ); } -#define DESCTYPE_LDT 0x82/* present, system, DPL-0, LDT */ -#define DESCTYPE_TSS 0x89/* present, system, DPL-0, 32-bit TSS */ -#define DESCTYPE_TASK 0x85/* present, system, DPL-0, task gate */ -#define DESCTYPE_INT 0x8e/* present, system, DPL-0, interrupt gate */ -#define DESCTYPE_TRAP 0x8f/* present, system, DPL-0, trap gate */ -#define DESCTYPE_DPL3 0x60/* DPL-3 */ -#define DESCTYPE_S 0x10/* !system */ -#ifdef CONFIG_PARAVIRT #include <asm/paravirt.h> #else
include/asm-x86/desc_defs.h +5 -0
@@ -55,6 +55,11 @@ struct gate_struct64 {enum {DESC_TSS =0x9 ,DESC_LDT =0x2 , +DESCTYPE_TASK =0x85 ,/* present, system, DPL-0, task gate */ +DESCTYPE_INT =0x8e ,/* present, system, DPL-0, interrupt gate */ +DESCTYPE_TRAP =0x8f ,/* present, system, DPL-0, trap gate */ +DESCTYPE_DPL3 =0x60 ,/* DPL-3 */ +DESCTYPE_S =0x10 ,/* !system */ };// LDT or TSS descriptor in the GDT. 16 bytes.
Signature · 1 line
1.5.0.6
PATCH 13/19 move constants to desc_defs.h
In reply to Glauber de Oliveira Costathis patch moves constant definitions regarding descriptor types from desc_32.h to desc_defs.h. The change from defines to enum to comply with previous versions in desc_defs.h
--- include/asm-x86/desc_32.h | 8 -------- include/asm-x86/desc_defs.h | 5 +++++ 2 files changed, 5 insertions(+), 8 deletions(-)
include/asm-x86/desc_32.h +0 -8
@@ -44,14 +44,6 @@ static inline void pack_gate(gate_desc *gate, gate->b = (base &0xffff0000 ) | ((type &0xff ) <<8 ) | (flags &0xff ); } -#define DESCTYPE_LDT 0x82/* present, system, DPL-0, LDT */ -#define DESCTYPE_TSS 0x89/* present, system, DPL-0, 32-bit TSS */ -#define DESCTYPE_TASK 0x85/* present, system, DPL-0, task gate */ -#define DESCTYPE_INT 0x8e/* present, system, DPL-0, interrupt gate */ -#define DESCTYPE_TRAP 0x8f/* present, system, DPL-0, trap gate */ -#define DESCTYPE_DPL3 0x60/* DPL-3 */ -#define DESCTYPE_S 0x10/* !system */ -#ifdef CONFIG_PARAVIRT #include <asm/paravirt.h> #else
include/asm-x86/desc_defs.h +5 -0
@@ -55,6 +55,11 @@ struct gate_struct64 {enum {DESC_TSS =0x9 ,DESC_LDT =0x2 , +DESCTYPE_TASK =0x85 ,/* present, system, DPL-0, task gate */ +DESCTYPE_INT =0x8e ,/* present, system, DPL-0, interrupt gate */ +DESCTYPE_TRAP =0x8f ,/* present, system, DPL-0, trap gate */ +DESCTYPE_DPL3 =0x60 ,/* DPL-3 */ +DESCTYPE_S =0x10 ,/* !system */ };// LDT or TSS descriptor in the GDT. 16 bytes.
Signature · 1 line
1.5.0.6
PATCH 14/19 unify non-paravirt parts of desc.h
This patch unifies the non-paravirt part of desc_{32,64}.h into desc.h. Most of it, is simply common code, that is moved to the shared header. The only exception is the set_ldt_desc in desc_64.h, which is changed - included its name - to accomodate for the way the ldt is set up in i386.
Also, constant definitions used in desc_32.h are moved to desc_defs.h
--- include/asm-x86/desc.h | 87 ++++++++++++++++++++++++++++++++++++++ include/asm-x86/desc_32.h | 66 ---------------------------- include/asm-x86/desc_64.h | 64 ++++----------------------- include/asm-x86/mmu_context_64.h | 4 +- 4 files changed, 99 insertions(+), 122 deletions(-)
include/asm-x86/desc.h +64 -1
@@ -4,6 +4,7 @@#ifndef __ASSEMBLY__#include <asm/desc_defs.h> #include <asm/ldt.h> +#include <asm/mmu.h> static inline void fill_ldt (struct desc_struct *desc,struct user_desc *info) {
@@ -23,7 +24,8 @@ static inline void fill_ldt(struct desc_ desc->base2 = (info->base_addr &0xff000000 ) >>24 ; } -#endif +extern struct desc_ptr idt_descr; +extern gate_desc idt_table[];#ifdef CONFIG_X86_32 # include "desc_32.h"
@@ -31,4 +33,65 @@ static inline void fill_ldt(struct desc_# include "desc_64.h" #endif +#define _LDT_empty (info) (\ + (info)->base_addr == 0 && \ + (info)->limit == 0 && \ + (info)->contents == 0 && \ + (info)->read_exec_only == 1 && \ + (info)->seg_32bit == 0 && \ + (info)->limit_in_pages == 0 && \ + (info)->seg_not_present == 1 && \ + (info)->useable == 0) + +#ifdef CONFIG_X86_64 +#define LDT_empty (info) (_LDT_empty(info) && ((info)->lm == 0)) +#else +#define LDT_empty (info) (_LDT_empty(info)) +#endif + +static inline void clear_LDT (void ) +{ +set_ldt (NULL ,0 ); +} + +/* +* load one particular LDT into the current CPU +*/ +static inline void load_LDT_nolock (mm_context_t *pc) +{ +set_ldt (pc->ldt, pc->size); +} + +static inline void load_LDT (mm_context_t *pc) +{ +preempt_disable (); +load_LDT_nolock (pc); +preempt_enable (); +} + +#else +/* +* GET_DESC_BASE reads the descriptor base of the specified segment. +* +* Args: +* idx - descriptor index +* gdt - GDT pointer +* base - 32bit register to which the base will be written +* lo_w - lo word of the "base" register +* lo_b - lo byte of the "base" register +* hi_b - hi byte of the low word of the "base" register +* +* Example: +* GET_DESC_BASE(GDT_ENTRY_ESPFIX_SS, %ebx, %eax, %ax, %al, %ah) +* Will read the base address of GDT_ENTRY_ESPFIX_SS and put it into %eax. +*/ +#define GET_DESC_BASE (idx, gdt, base, lo_w, lo_b, hi_b) \ + movb idx*8+4(gdt), lo_b; \ + movb idx*8+7(gdt), hi_b; \ + shll $16, base; \ + movw idx*8+2(gdt), lo_w; + + +#endif /* __ASSEMBLY__ */ +#endif
include/asm-x86/desc_32.h +0 -58
82 lines not on this page · raw message
include/asm-x86/desc_64.h +10 -45
95 lines not on this page · raw message
include/asm-x86/mmu_context_64.h +2 -2
@@ -43,7 +43,7 @@ static inline void switch_mm(struct mm_sload_cr3 (next->pgd);if (unlikely (next->context.ldt != prev->context.ldt)) -load_LDT_nolock (&next->context, cpu); +load_LDT_nolock (&next->context); }#ifdef CONFIG_SMP else {
@@ -56,7 +56,7 @@ static inline void switch_mm(struct mm_s* to make sure to use no freed page tables. */ load_cr3 (next->pgd); - load_LDT_nolock(&next->context, cpu); + load_LDT_nolock(&next->context); } }#endif
PATCH 14/19 unify non-paravirt parts of desc.h
In reply to Glauber de Oliveira CostaThis patch unifies the non-paravirt part of desc_{32,64}.h into desc.h. Most of it, is simply common code, that is moved to the shared header. The only exception is the set_ldt_desc in desc_64.h, which is changed - included its name - to accomodate for the way the ldt is set up in i386.
Also, constant definitions used in desc_32.h are moved to desc_defs.h
--- include/asm-x86/desc.h | 87 ++++++++++++++++++++++++++++++++++++++ include/asm-x86/desc_32.h | 66 ---------------------------- include/asm-x86/desc_64.h | 64 ++++----------------------- include/asm-x86/mmu_context_64.h | 4 +- 4 files changed, 99 insertions(+), 122 deletions(-)
include/asm-x86/desc.h +64 -1
@@ -4,6 +4,7 @@#ifndef __ASSEMBLY__#include <asm/desc_defs.h> #include <asm/ldt.h> +#include <asm/mmu.h> static inline void fill_ldt (struct desc_struct *desc,struct user_desc *info) {
@@ -23,7 +24,8 @@ static inline void fill_ldt(struct desc_ desc->base2 = (info->base_addr &0xff000000 ) >>24 ; } -#endif +extern struct desc_ptr idt_descr; +extern gate_desc idt_table[];#ifdef CONFIG_X86_32 # include "desc_32.h"
@@ -31,4 +33,65 @@ static inline void fill_ldt(struct desc_# include "desc_64.h" #endif +#define _LDT_empty (info) (\ + (info)->base_addr == 0 && \ + (info)->limit == 0 && \ + (info)->contents == 0 && \ + (info)->read_exec_only == 1 && \ + (info)->seg_32bit == 0 && \ + (info)->limit_in_pages == 0 && \ + (info)->seg_not_present == 1 && \ + (info)->useable == 0) + +#ifdef CONFIG_X86_64 +#define LDT_empty (info) (_LDT_empty(info) && ((info)->lm == 0)) +#else +#define LDT_empty (info) (_LDT_empty(info)) +#endif + +static inline void clear_LDT (void ) +{ +set_ldt (NULL ,0 ); +} + +/* +* load one particular LDT into the current CPU +*/ +static inline void load_LDT_nolock (mm_context_t *pc) +{ +set_ldt (pc->ldt, pc->size); +} + +static inline void load_LDT (mm_context_t *pc) +{ +preempt_disable (); +load_LDT_nolock (pc); +preempt_enable (); +} + +#else +/* +* GET_DESC_BASE reads the descriptor base of the specified segment. +* +* Args: +* idx - descriptor index +* gdt - GDT pointer +* base - 32bit register to which the base will be written +* lo_w - lo word of the "base" register +* lo_b - lo byte of the "base" register +* hi_b - hi byte of the low word of the "base" register +* +* Example: +* GET_DESC_BASE(GDT_ENTRY_ESPFIX_SS, %ebx, %eax, %ax, %al, %ah) +* Will read the base address of GDT_ENTRY_ESPFIX_SS and put it into %eax. +*/ +#define GET_DESC_BASE (idx, gdt, base, lo_w, lo_b, hi_b) \ + movb idx*8+4(gdt), lo_b; \ + movb idx*8+7(gdt), hi_b; \ + shll $16, base; \ + movw idx*8+2(gdt), lo_w; + + +#endif /* __ASSEMBLY__ */ +#endif
include/asm-x86/desc_32.h +0 -58
82 lines not on this page · raw message
include/asm-x86/desc_64.h +10 -45
95 lines not on this page · raw message
include/asm-x86/mmu_context_64.h +2 -2
@@ -43,7 +43,7 @@ static inline void switch_mm(struct mm_sload_cr3 (next->pgd);if (unlikely (next->context.ldt != prev->context.ldt)) -load_LDT_nolock (&next->context, cpu); +load_LDT_nolock (&next->context); }#ifdef CONFIG_SMP else {
@@ -56,7 +56,7 @@ static inline void switch_mm(struct mm_s* to make sure to use no freed page tables. */ load_cr3 (next->pgd); - load_LDT_nolock(&next->context, cpu); + load_LDT_nolock(&next->context); } }#endif
PATCH 15/19 use the same data type for tls_array.
This patch changes the type of tls_array in x86_64 to a desc_struct. Now, both i386 and x86_64 tls_array have the same type, and code accessing it can be shared.
--- include/asm-x86/desc_64.h | 2 +- include/asm-x86/processor_64.h | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-)
include/asm-x86/desc_64.h +1 -1
@@ -150,7 +150,7 @@ static inline void set_ldt(void *addr, int entries)static inline void load_TLS (struct thread_struct *t,unsigned int cpu) {unsigned int i; -u64 *gdt = (u64 *)(get_cpu_gdt_table (cpu) +GDT_ENTRY_TLS_MIN ); +struct desc_struct *gdt = (get_cpu_gdt_table (cpu) +GDT_ENTRY_TLS_MIN );for (i =0 ; i <GDT_ENTRY_TLS_ENTRIES ; i++) gdt[i] = t->tls_array[i];
include/asm-x86/processor_64.h +2 -1
@@ -19,6 +19,7 @@#include <linux/personality.h> #include <linux/cpumask.h> #include <asm/processor-flags.h> +#include <asm/desc_defs.h> #define TF_MASK 0x00000100#define IF_MASK 0x00000200
@@ -244,7 +245,7 @@ struct thread_struct {* goes into MSR_IA32_DS_AREA */ unsigned long ds_area_msr;/* cached TLS descriptors. */ -u64 tls_array[GDT_ENTRY_TLS_ENTRIES ]; +struct desc_struct tls_array[GDT_ENTRY_TLS_ENTRIES ]; } __attribute__((aligned(16)));#define INIT_THREAD { \
Signature · 1 line
1.5.0.6
PATCH 16/19 modify get_desc_base
This patch makes get_desc_base() receive a struct desc_struct, and then uses its internal fields to compute the base address. This is done at both i386 and x86_64, and then it is moved to common header
--- arch/x86/kernel/tls.c | 2 +- arch/x86/mm/fault_32.c | 2 +- include/asm-x86/desc.h | 8 ++------ 3 files changed, 4 insertions(+), 8 deletions(-)
arch/x86/kernel/tls.c +1 -1
@@ -112,7 +112,7 @@ int do_get_thread_area(struct task_strucmemset (&info,0 ,sizeof (struct user_desc )); info.entry_number = idx; - info.base_addr =get_desc_base ((void *)desc); + info.base_addr =get_desc_base ((struct desc_struct *)desc); info.limit =GET_LIMIT (desc); info.seg_32bit =GET_32BIT (desc); info.contents =GET_CONTENTS (desc);
arch/x86/mm/fault_32.c +1 -1
@@ -115,7 +115,7 @@ static inline unsigned long get_segment_ }/* Decode the code segment base from the descriptor */ - base =get_desc_base ((unsigned long *)desc); + base =get_desc_base ((struct desc_struct *)desc);if (seg & (1 <<2 )) {mutex_unlock (¤t->mm->context.lock);
include/asm-x86/desc.h +5 -0
@@ -69,6 +69,11 @@ static inline void load_LDT(mm_context_t preempt_enable(); } +static inline unsigned long get_desc_base (struct desc_struct *desc) +{ +return desc->base0 | ((desc->base1) <<16 ) | ((desc->base2) <<24 ); +} +#else /* * GET_DESC_BASE reads the descriptor base of the specified segment.
include/asm-x86/desc_32.h +0 -8
@@ -168,14 +168,6 @@ static inline void __set_tss_desc(unsign#define set_tss_desc (cpu,addr) __set_tss_desc(cpu, GDT_ENTRY_TSS, addr) -static inline unsigned long get_desc_base (unsigned long *desc) -{ -unsigned long base; - base = ((desc[0 ] >>16 ) &0x0000ffff ) | - ((desc[1 ] <<16 ) &0x00ff0000 ) | - (desc[1 ] &0xff000000 ); -return base; -}#endif /* !__ASSEMBLY__ */ #endif
include/asm-x86/desc_64.h +0 -9
@@ -156,15 +156,6 @@ static inline void load_TLS(struct threa gdt[i] = t->tls_array[i]; } -static inline unsigned long get_desc_base (const void *ptr) -{ -const u32 *desc = ptr; -unsigned long base; - base = ((desc[0 ] >>16 ) &0x0000ffff ) | - ((desc[1 ] <<16 ) &0x00ff0000 ) | - (desc[1 ] &0xff000000 ); -return base; -}#endif /* !__ASSEMBLY__ */ #endif
PATCH 16/19 modify get_desc_base
In reply to Glauber de Oliveira CostaThis patch makes get_desc_base() receive a struct desc_struct, and then uses its internal fields to compute the base address. This is done at both i386 and x86_64, and then it is moved to common header
--- arch/x86/kernel/tls.c | 2 +- arch/x86/mm/fault_32.c | 2 +- include/asm-x86/desc.h | 8 ++------ 3 files changed, 4 insertions(+), 8 deletions(-)
arch/x86/kernel/tls.c +1 -1
@@ -112,7 +112,7 @@ int do_get_thread_area(struct task_strucmemset (&info,0 ,sizeof (struct user_desc )); info.entry_number = idx; - info.base_addr =get_desc_base ((void *)desc); + info.base_addr =get_desc_base ((struct desc_struct *)desc); info.limit =GET_LIMIT (desc); info.seg_32bit =GET_32BIT (desc); info.contents =GET_CONTENTS (desc);
arch/x86/mm/fault_32.c +1 -1
@@ -115,7 +115,7 @@ static inline unsigned long get_segment_ }/* Decode the code segment base from the descriptor */ - base =get_desc_base ((unsigned long *)desc); + base =get_desc_base ((struct desc_struct *)desc);if (seg & (1 <<2 )) {mutex_unlock (¤t->mm->context.lock);
include/asm-x86/desc.h +5 -0
@@ -69,6 +69,11 @@ static inline void load_LDT(mm_context_t preempt_enable(); } +static inline unsigned long get_desc_base (struct desc_struct *desc) +{ +return desc->base0 | ((desc->base1) <<16 ) | ((desc->base2) <<24 ); +} +#else /* * GET_DESC_BASE reads the descriptor base of the specified segment.
include/asm-x86/desc_32.h +0 -8
@@ -168,14 +168,6 @@ static inline void __set_tss_desc(unsign#define set_tss_desc (cpu,addr) __set_tss_desc(cpu, GDT_ENTRY_TSS, addr) -static inline unsigned long get_desc_base (unsigned long *desc) -{ -unsigned long base; - base = ((desc[0 ] >>16 ) &0x0000ffff ) | - ((desc[1 ] <<16 ) &0x00ff0000 ) | - (desc[1 ] &0xff000000 ); -return base; -}#endif /* !__ASSEMBLY__ */ #endif
include/asm-x86/desc_64.h +0 -9
@@ -156,15 +156,6 @@ static inline void load_TLS(struct threa gdt[i] = t->tls_array[i]; } -static inline unsigned long get_desc_base (const void *ptr) -{ -const u32 *desc = ptr; -unsigned long base; - base = ((desc[0 ] >>16 ) &0x0000ffff ) | - ((desc[1 ] <<16 ) &0x00ff0000 ) | - (desc[1 ] &0xff000000 ); -return base; -}#endif /* !__ASSEMBLY__ */ #endif
PATCH 17/19 unify paravirt pieces of descriptor handling
With the types used to access descriptors in x86_64 and i386 now being the same, the code that effectively handles them can now be easily shared. This patch moves the paravirt part of desc_32.h into desc.h, and then, we get paravirt support in x86_64 for free.
--- include/asm-x86/desc.h | 169 +++++++++++++++++++++++++++++++++++++++++++ include/asm-x86/desc_32.h | 130 --------------------------------- include/asm-x86/desc_64.h | 104 +++------------------------ include/asm-x86/desc_defs.h | 6 +- 4 files changed, 183 insertions(+), 226 deletions(-)
include/asm-x86/desc_32.h +0 -130
@@ -8,31 +8,10 @@#ifndef __ASSEMBLY__#include <linux/preempt.h> -#include <linux/smp.h> #include <linux/percpu.h> -struct gdt_page -{ -struct desc_struct gdt[GDT_ENTRIES ]; -} __attribute__((aligned (PAGE_SIZE ))); -DECLARE_PER_CPU(struct gdt_page, gdt_page); - -static inline struct desc_struct *get_cpu_gdt_table (unsigned int cpu) -{ -return per_cpu (gdt_page, cpu).gdt; -} -extern void set_intr_gate (unsigned int irq,void * addr); -static inline void pack_descriptor (struct desc_struct *desc, -unsigned long base,unsigned long limit,unsigned char type,unsigned char flags) -{ - desc->a = ((base &0xffff ) <<16 ) | (limit &0xffff ); - desc->b = (base &0xff000000 ) | ((base &0xff0000 ) >>16 ) | - (limit &0x000f0000 ) | ((type &0xff ) <<8 ) | ((flags &0xf ) <<20 ); - desc->p =1 ; -} -static inline void pack_gate (gate_desc *gate,unsigned long base,unsigned short seg,unsigned char type,unsigned char flags) {
@@ -40,115 +19,6 @@ static inline void pack_gate(gate_desc * gate->b = (base &0xffff0000 ) | ((type &0xff ) <<8 ) | (flags &0xff ); } -#ifdef CONFIG_PARAVIRT -#include <asm/paravirt.h> -#else -#define load_TR_desc () native_load_tr_desc() -#define load_gdt (dtr) native_load_gdt(dtr) -#define load_idt (dtr) native_load_idt(dtr) -#define load_tr (tr) __asm__ __volatile("ltr %0"::"m" (tr)) -#define load_ldt (ldt) __asm__ __volatile("lldt %0"::"m" (ldt)) - -#define store_gdt (dtr) native_store_gdt(dtr) -#define store_idt (dtr) native_store_idt(dtr) -#define store_tr (tr) (tr = native_store_tr()) -#define store_ldt (ldt) __asm__ ("sldt %0":"=m" (ldt)) - -#define load_TLS (t, cpu) native_load_tls(t, cpu) -#define set_ldt native_set_ldt - -#define write_ldt_entry (dt, entry, desc) \ - native_write_ldt_entry(dt, entry, desc) -#define write_gdt_entry (dt, entry, desc, type) \ - native_write_gdt_entry(dt, entry, desc, type) -#define write_idt_entry (dt, entry, g) native_write_idt_entry(dt, entry, g) -#endif - -static inline void native_write_ldt_entry (struct desc_struct *ldt,int entry, -const void *desc) -{ -memcpy (&ldt[entry], desc,sizeof (struct desc_struct )); -} - -static inline void native_write_idt_entry (gate_desc *idt,int entry, -const gate_desc *gate) -{ -memcpy (&idt[entry], gate,sizeof (*gate)); -} - -static inline void native_write_gdt_entry (struct desc_struct *gdt,int entry, -const void *desc,int type) -{ -memcpy (&gdt[entry], desc,sizeof (struct desc_struct )); -} - -static inline void write_dt_entry (struct desc_struct *dt, -int entry,u32 entry_low,u32 entry_high) -{ - dt[entry].a = entry_low; - dt[entry].b = entry_high; -} - - -static inline void native_set_ldt (const void *addr,unsigned int entries) -{ -if (likely (entries ==0 )) - __asm__ __volatile__("lldt %w0" ::"q" (0 )); -else { -unsigned cpu =smp_processor_id (); -ldt_desc ldt; - -pack_descriptor (&ldt, (unsigned long )addr, - entries *sizeof (struct desc_struct ) -1 , -DESC_LDT ,0 ); -write_gdt_entry (get_cpu_gdt_table (cpu),GDT_ENTRY_LDT , - &ldt,DESC_LDT ); - __asm__ __volatile__("lldt %w0" ::"q" (GDT_ENTRY_LDT *8 )); - } -} - - -static inline void native_load_tr_desc (void ) -{ - asmvolatile ("ltr %w0" ::"q" (GDT_ENTRY_TSS *8 )); -} - -static inline void native_load_gdt (const struct desc_ptr *dtr) -{ - asmvolatile ("lgdt %0" ::"m" (*dtr)); -} - -static inline void native_load_idt (const struct desc_ptr *dtr) -{ - asmvolatile ("lidt %0" ::"m" (*dtr)); -} - -static inline void native_store_gdt (struct desc_ptr *dtr) -{ - asm ("sgdt %0" :"=m" (*dtr)); -} - -static inline void native_store_idt (struct desc_ptr *dtr) -{ - asm ("sidt %0" :"=m" (*dtr)); -} - -static inline unsigned long native_store_tr (void ) -{ -unsigned long tr; - asm ("str %0" :"=r" (tr)); -return tr; -} - -static inline void native_load_tls (struct thread_struct *t,unsigned int cpu) -{ -unsigned int i; -struct desc_struct *gdt =get_cpu_gdt_table (cpu); - -for (i =0 ; i <GDT_ENTRY_TLS_ENTRIES ; i++) - gdt[GDT_ENTRY_TLS_MIN + i] = t->tls_array[i]; -} -static inline void _set_gate (int gate,unsigned int type,void *addr,unsigned short seg) {gate_desc g;
include/asm-x86/desc_64.h +11 -93
150 lines not on this page · raw message
include/asm-x86/desc_defs.h +3 -3
@@ -48,9 +48,9 @@ struct gate_struct64 {u32 zero1; } __attribute__((packed)); -#define PTR_LOW (x) ((unsigned long)(x) & 0xFFFF) -#define PTR_MIDDLE (x) (((unsigned long)(x) >> 16) & 0xFFFF) -#define PTR_HIGH (x) ((unsigned long)(x) >> 32) +#define PTR_LOW (x) ((unsigned long long)(x) & 0xFFFF) +#define PTR_MIDDLE (x) (((unsigned long long)(x) >> 16) & 0xFFFF) +#define PTR_HIGH (x) ((unsigned long long)(x) >> 32)enum {DESC_TSS =0x9 ,
include/asm-x86/desc.h +161 -0
173 lines not on this page · raw message
PATCH 17/19 unify paravirt pieces of descriptor handling
In reply to Glauber de Oliveira CostaWith the types used to access descriptors in x86_64 and i386 now being the same, the code that effectively handles them can now be easily shared. This patch moves the paravirt part of desc_32.h into desc.h, and then, we get paravirt support in x86_64 for free.
--- include/asm-x86/desc.h | 169 +++++++++++++++++++++++++++++++++++++++++++ include/asm-x86/desc_32.h | 130 --------------------------------- include/asm-x86/desc_64.h | 104 +++------------------------ include/asm-x86/desc_defs.h | 6 +- 4 files changed, 183 insertions(+), 226 deletions(-)
include/asm-x86/desc_32.h +0 -130
@@ -8,31 +8,10 @@#ifndef __ASSEMBLY__#include <linux/preempt.h> -#include <linux/smp.h> #include <linux/percpu.h> -struct gdt_page -{ -struct desc_struct gdt[GDT_ENTRIES ]; -} __attribute__((aligned (PAGE_SIZE ))); -DECLARE_PER_CPU(struct gdt_page, gdt_page); - -static inline struct desc_struct *get_cpu_gdt_table (unsigned int cpu) -{ -return per_cpu (gdt_page, cpu).gdt; -} -extern void set_intr_gate (unsigned int irq,void * addr); -static inline void pack_descriptor (struct desc_struct *desc, -unsigned long base,unsigned long limit,unsigned char type,unsigned char flags) -{ - desc->a = ((base &0xffff ) <<16 ) | (limit &0xffff ); - desc->b = (base &0xff000000 ) | ((base &0xff0000 ) >>16 ) | - (limit &0x000f0000 ) | ((type &0xff ) <<8 ) | ((flags &0xf ) <<20 ); - desc->p =1 ; -} -static inline void pack_gate (gate_desc *gate,unsigned long base,unsigned short seg,unsigned char type,unsigned char flags) {
@@ -40,115 +19,6 @@ static inline void pack_gate(gate_desc * gate->b = (base &0xffff0000 ) | ((type &0xff ) <<8 ) | (flags &0xff ); } -#ifdef CONFIG_PARAVIRT -#include <asm/paravirt.h> -#else -#define load_TR_desc () native_load_tr_desc() -#define load_gdt (dtr) native_load_gdt(dtr) -#define load_idt (dtr) native_load_idt(dtr) -#define load_tr (tr) __asm__ __volatile("ltr %0"::"m" (tr)) -#define load_ldt (ldt) __asm__ __volatile("lldt %0"::"m" (ldt)) - -#define store_gdt (dtr) native_store_gdt(dtr) -#define store_idt (dtr) native_store_idt(dtr) -#define store_tr (tr) (tr = native_store_tr()) -#define store_ldt (ldt) __asm__ ("sldt %0":"=m" (ldt)) - -#define load_TLS (t, cpu) native_load_tls(t, cpu) -#define set_ldt native_set_ldt - -#define write_ldt_entry (dt, entry, desc) \ - native_write_ldt_entry(dt, entry, desc) -#define write_gdt_entry (dt, entry, desc, type) \ - native_write_gdt_entry(dt, entry, desc, type) -#define write_idt_entry (dt, entry, g) native_write_idt_entry(dt, entry, g) -#endif - -static inline void native_write_ldt_entry (struct desc_struct *ldt,int entry, -const void *desc) -{ -memcpy (&ldt[entry], desc,sizeof (struct desc_struct )); -} - -static inline void native_write_idt_entry (gate_desc *idt,int entry, -const gate_desc *gate) -{ -memcpy (&idt[entry], gate,sizeof (*gate)); -} - -static inline void native_write_gdt_entry (struct desc_struct *gdt,int entry, -const void *desc,int type) -{ -memcpy (&gdt[entry], desc,sizeof (struct desc_struct )); -} - -static inline void write_dt_entry (struct desc_struct *dt, -int entry,u32 entry_low,u32 entry_high) -{ - dt[entry].a = entry_low; - dt[entry].b = entry_high; -} - - -static inline void native_set_ldt (const void *addr,unsigned int entries) -{ -if (likely (entries ==0 )) - __asm__ __volatile__("lldt %w0" ::"q" (0 )); -else { -unsigned cpu =smp_processor_id (); -ldt_desc ldt; - -pack_descriptor (&ldt, (unsigned long )addr, - entries *sizeof (struct desc_struct ) -1 , -DESC_LDT ,0 ); -write_gdt_entry (get_cpu_gdt_table (cpu),GDT_ENTRY_LDT , - &ldt,DESC_LDT ); - __asm__ __volatile__("lldt %w0" ::"q" (GDT_ENTRY_LDT *8 )); - } -} - - -static inline void native_load_tr_desc (void ) -{ - asmvolatile ("ltr %w0" ::"q" (GDT_ENTRY_TSS *8 )); -} - -static inline void native_load_gdt (const struct desc_ptr *dtr) -{ - asmvolatile ("lgdt %0" ::"m" (*dtr)); -} - -static inline void native_load_idt (const struct desc_ptr *dtr) -{ - asmvolatile ("lidt %0" ::"m" (*dtr)); -} - -static inline void native_store_gdt (struct desc_ptr *dtr) -{ - asm ("sgdt %0" :"=m" (*dtr)); -} - -static inline void native_store_idt (struct desc_ptr *dtr) -{ - asm ("sidt %0" :"=m" (*dtr)); -} - -static inline unsigned long native_store_tr (void ) -{ -unsigned long tr; - asm ("str %0" :"=r" (tr)); -return tr; -} - -static inline void native_load_tls (struct thread_struct *t,unsigned int cpu) -{ -unsigned int i; -struct desc_struct *gdt =get_cpu_gdt_table (cpu); - -for (i =0 ; i <GDT_ENTRY_TLS_ENTRIES ; i++) - gdt[GDT_ENTRY_TLS_MIN + i] = t->tls_array[i]; -} -static inline void _set_gate (int gate,unsigned int type,void *addr,unsigned short seg) {gate_desc g;
include/asm-x86/desc_64.h +11 -93
150 lines not on this page · raw message
include/asm-x86/desc_defs.h +3 -3
@@ -48,9 +48,9 @@ struct gate_struct64 {u32 zero1; } __attribute__((packed)); -#define PTR_LOW (x) ((unsigned long)(x) & 0xFFFF) -#define PTR_MIDDLE (x) (((unsigned long)(x) >> 16) & 0xFFFF) -#define PTR_HIGH (x) ((unsigned long)(x) >> 32) +#define PTR_LOW (x) ((unsigned long long)(x) & 0xFFFF) +#define PTR_MIDDLE (x) (((unsigned long long)(x) >> 16) & 0xFFFF) +#define PTR_HIGH (x) ((unsigned long long)(x) >> 32)enum {DESC_TSS =0x9 ,
include/asm-x86/desc.h +161 -0
173 lines not on this page · raw message
PATCH 18/19 move _set_gate and its users to a common location
This patch moves _set_gate and its users to desc.h. We can now use common code for x86_64 and i386.
--- arch/x86/kernel/traps_32.c | 34 ---------------- include/asm-x86/desc.h | 88 +++++++++++++++++++++++++++++++++++++++++++ include/asm-x86/desc_32.h | 16 -------- include/asm-x86/desc_64.h | 45 ---------------------- include/asm-x86/desc_defs.h | 5 +-- 5 files changed, 89 insertions(+), 99 deletions(-)
arch/x86/kernel/traps_32.c +0 -34
@@ -1102,40 +1102,6 @@ asmlinkage void math_emulate(long arg)#endif /* CONFIG_MATH_EMULATION */ -/* -* This needs to use 'idt_table' rather than 'idt', and -* thus use the _nonmapped_ version of the IDT, as the -* Pentium F0 0F bugfix can have resulted in the mapped -* IDT being write-protected. -*/ -void set_intr_gate (unsigned int n,void *addr) -{ -_set_gate (n,DESCTYPE_INT , addr, __KERNEL_CS); -} - -/* -* This routine sets up an interrupt gate at directory privilege level 3. -*/ -static inline void set_system_intr_gate (unsigned int n,void *addr) -{ -_set_gate (n,DESCTYPE_INT |DESCTYPE_DPL3 , addr, __KERNEL_CS); -} - -static void __init set_trap_gate (unsigned int n,void *addr) -{ -_set_gate (n,DESCTYPE_TRAP , addr, __KERNEL_CS); -} - -static void __init set_system_gate (unsigned int n,void *addr) -{ -_set_gate (n,DESCTYPE_TRAP |DESCTYPE_DPL3 , addr, __KERNEL_CS); -} - -static void __init set_task_gate (unsigned int n,unsigned int gdt_entry) -{ -_set_gate (n,DESCTYPE_TASK , (void *)0 , (gdt_entry<<3 )); -} -void __init trap_init (void ) {
include/asm-x86/desc.h +88 -0
106 lines not on this page · raw message
include/asm-x86/desc_32.h +0 -16
@@ -10,22 +10,6 @@#include <linux/preempt.h> #include <linux/percpu.h> -extern void set_intr_gate (unsigned int irq,void * addr); - -static inline void pack_gate (gate_desc *gate, -unsigned long base,unsigned short seg,unsigned char type,unsigned char flags) -{ - gate->a = (seg <<16 ) | (base &0xffff ); - gate->b = (base &0xffff0000 ) | ((type &0xff ) <<8 ) | (flags &0xff ); -} - -static inline void _set_gate (int gate,unsigned int type,void *addr,unsigned short seg) -{ -gate_desc g; -pack_gate (&g, (unsigned long )addr, seg, type,0 ); -write_idt_entry (idt_table, gate, &g); -} -static inline void __set_tss_desc (unsigned int cpu,unsigned int entry,const void *addr) {tss_desc tss;
include/asm-x86/desc_64.h +0 -45
51 lines not on this page · raw message
include/asm-x86/desc_defs.h +1 -4
@@ -36,6 +36,7 @@ enum {GATE_INTERRUPT =0xE ,GATE_TRAP =0xF ,GATE_CALL =0xC , + GATE_TASK = 0x5, };// 16byte gate
@@ -55,10 +56,6 @@ struct gate_struct64 {enum {DESC_TSS =0x9 ,DESC_LDT =0x2 , -DESCTYPE_TASK =0x85 ,/* present, system, DPL-0, task gate */ -DESCTYPE_INT =0x8e ,/* present, system, DPL-0, interrupt gate */ -DESCTYPE_TRAP =0x8f ,/* present, system, DPL-0, trap gate */ -DESCTYPE_DPL3 =0x60 ,/* DPL-3 */ DESCTYPE_S =0x10 ,/* !system */ };
PATCH 18/19 move _set_gate and its users to a common location
In reply to Glauber de Oliveira CostaThis patch moves _set_gate and its users to desc.h. We can now use common code for x86_64 and i386.
--- arch/x86/kernel/traps_32.c | 34 ---------------- include/asm-x86/desc.h | 88 +++++++++++++++++++++++++++++++++++++++++++ include/asm-x86/desc_32.h | 16 -------- include/asm-x86/desc_64.h | 45 ---------------------- include/asm-x86/desc_defs.h | 5 +-- 5 files changed, 89 insertions(+), 99 deletions(-)
arch/x86/kernel/traps_32.c +0 -34
@@ -1102,40 +1102,6 @@ asmlinkage void math_emulate(long arg)#endif /* CONFIG_MATH_EMULATION */ -/* -* This needs to use 'idt_table' rather than 'idt', and -* thus use the _nonmapped_ version of the IDT, as the -* Pentium F0 0F bugfix can have resulted in the mapped -* IDT being write-protected. -*/ -void set_intr_gate (unsigned int n,void *addr) -{ -_set_gate (n,DESCTYPE_INT , addr, __KERNEL_CS); -} - -/* -* This routine sets up an interrupt gate at directory privilege level 3. -*/ -static inline void set_system_intr_gate (unsigned int n,void *addr) -{ -_set_gate (n,DESCTYPE_INT |DESCTYPE_DPL3 , addr, __KERNEL_CS); -} - -static void __init set_trap_gate (unsigned int n,void *addr) -{ -_set_gate (n,DESCTYPE_TRAP , addr, __KERNEL_CS); -} - -static void __init set_system_gate (unsigned int n,void *addr) -{ -_set_gate (n,DESCTYPE_TRAP |DESCTYPE_DPL3 , addr, __KERNEL_CS); -} - -static void __init set_task_gate (unsigned int n,unsigned int gdt_entry) -{ -_set_gate (n,DESCTYPE_TASK , (void *)0 , (gdt_entry<<3 )); -} -void __init trap_init (void ) {
include/asm-x86/desc.h +88 -0
106 lines not on this page · raw message
include/asm-x86/desc_32.h +0 -16
@@ -10,22 +10,6 @@#include <linux/preempt.h> #include <linux/percpu.h> -extern void set_intr_gate (unsigned int irq,void * addr); - -static inline void pack_gate (gate_desc *gate, -unsigned long base,unsigned short seg,unsigned char type,unsigned char flags) -{ - gate->a = (seg <<16 ) | (base &0xffff ); - gate->b = (base &0xffff0000 ) | ((type &0xff ) <<8 ) | (flags &0xff ); -} - -static inline void _set_gate (int gate,unsigned int type,void *addr,unsigned short seg) -{ -gate_desc g; -pack_gate (&g, (unsigned long )addr, seg, type,0 ); -write_idt_entry (idt_table, gate, &g); -} -static inline void __set_tss_desc (unsigned int cpu,unsigned int entry,const void *addr) {tss_desc tss;
include/asm-x86/desc_64.h +0 -45
51 lines not on this page · raw message
include/asm-x86/desc_defs.h +1 -4
@@ -36,6 +36,7 @@ enum {GATE_INTERRUPT =0xE ,GATE_TRAP =0xF ,GATE_CALL =0xC , + GATE_TASK = 0x5, };// 16byte gate
@@ -55,10 +56,6 @@ struct gate_struct64 {enum {DESC_TSS =0x9 ,DESC_LDT =0x2 , -DESCTYPE_TASK =0x85 ,/* present, system, DPL-0, task gate */ -DESCTYPE_INT =0x8e ,/* present, system, DPL-0, interrupt gate */ -DESCTYPE_TRAP =0x8f ,/* present, system, DPL-0, trap gate */ -DESCTYPE_DPL3 =0x60 ,/* DPL-3 */ DESCTYPE_S =0x10 ,/* !system */ };
PATCH 19/19 unify set_tss_desc
This patch unifies the set_tss_desc between i386 and x86_64, which can now have a common implementation. After the old functions are removed from desc_{32,64}.h, nothing important is left, and the files can be removed.
--- include/asm-x86/desc.h | 40 +++++++++++++++++++++++++++++++++------- include/asm-x86/desc_32.h | 27 --------------------------- include/asm-x86/desc_64.h | 34 ---------------------------------- 3 files changed, 33 insertions(+), 68 deletions(-) delete mode 100644 include/asm-x86/desc_32.h delete mode 100644 include/asm-x86/desc_64.h
include/asm-x86/desc.h +20 -6
@@ -157,6 +157,26 @@ static inline void set_tssldt_descriptor#endif } +static inline void __set_tss_desc (unsigned cpu,unsigned int entry,void *addr) +{ +struct desc_struct *d =get_cpu_gdt_table (cpu); +tss_desc tss; + +/* +* sizeof(unsigned long) coming from an extra "long" at the end +* of the iobitmap. See tss_struct definition in processor.h +* +* -1? seg base+limit should be pointing to the address of the +* last valid byte +*/ +set_tssldt_descriptor (&tss, (unsigned long )addr, +IO_BITMAP_OFFSET +IO_BITMAP_BYTES +sizeof (unsigned long ) -1 , +DESC_TSS ); +write_gdt_entry (d, entry, &tss,DESC_TSS ); +} + +#define set_tss_desc (cpu, addr) __set_tss_desc(cpu, GDT_ENTRY_TSS, addr) +static inline void native_set_ldt (const void *addr,unsigned int entries) {if (likely (entries ==0 ))
@@ -214,12 +234,6 @@ static inline void native_load_tls(struc gdt[GDT_ENTRY_TLS_MIN + i] = t->tls_array[i]; } -#ifdef CONFIG_X86_32 -# include "desc_32.h" -#else -# include "desc_64.h" -#endif -#define _LDT_empty (info) (\ (info)->base_addr == 0 && \ (info)->limit == 0 && \
include/asm-x86/desc_32.h deleted +0 -27
@@ -1,27 +0,0 @@ -#ifndef __ARCH_DESC_H -#define __ARCH_DESC_H - -#include <asm/ldt.h> -#include <asm/segment.h> -#include <asm/desc_defs.h> - -#ifndef __ASSEMBLY__ - -#include <linux/preempt.h> -#include <linux/percpu.h> - -static inline void __set_tss_desc (unsigned int cpu,unsigned int entry,const void *addr) -{ -tss_desc tss; -pack_descriptor (&tss, (unsigned long )addr, - offsetof(struct tss_struct , __cacheline_filler) -1 , -DESC_TSS ,0 ); -write_gdt_entry (get_cpu_gdt_table (cpu), entry, &tss,DESC_TSS ); -} - - -#define set_tss_desc (cpu,addr) __set_tss_desc(cpu, GDT_ENTRY_TSS, addr) - -#endif /* !__ASSEMBLY__ */ - -#endif
include/asm-x86/desc_64.h +0 -33
@@ -1,34 +1 @@ -/* Written 2000 by Andi Kleen */ -#ifndef __ARCH_DESC_H -#define __ARCH_DESC_H -#include <linux/threads.h> -#include <asm/ldt.h> - -#ifndef __ASSEMBLY__ - -#include <linux/string.h> - -#include <asm/segment.h> - -static inline void set_tss_desc (unsigned cpu,void *addr) -{ -struct desc_struct *d =get_cpu_gdt_table (cpu); -tss_desc tss; - -/* -* sizeof(unsigned long) coming from an extra "long" at the end -* of the iobitmap. See tss_struct definition in processor.h -* -* -1? seg base+limit should be pointing to the address of the -* last valid byte -*/ -set_tssldt_descriptor (&tss, - (unsigned long )addr,DESC_TSS , -IO_BITMAP_OFFSET +IO_BITMAP_BYTES +sizeof (unsigned long ) -1 ); -write_gdt_entry (d,GDT_ENTRY_TSS , &tss,DESC_TSS ); -} - -#endif /* !__ASSEMBLY__ */ - -#endif
PATCH 19/19 unify set_tss_desc
In reply to Glauber de Oliveira CostaThis patch unifies the set_tss_desc between i386 and x86_64, which can now have a common implementation. After the old functions are removed from desc_{32,64}.h, nothing important is left, and the files can be removed.
--- include/asm-x86/desc.h | 40 +++++++++++++++++++++++++++++++++------- include/asm-x86/desc_32.h | 27 --------------------------- include/asm-x86/desc_64.h | 34 ---------------------------------- 3 files changed, 33 insertions(+), 68 deletions(-) delete mode 100644 include/asm-x86/desc_32.h delete mode 100644 include/asm-x86/desc_64.h
include/asm-x86/desc.h +20 -6
@@ -157,6 +157,26 @@ static inline void set_tssldt_descriptor#endif } +static inline void __set_tss_desc (unsigned cpu,unsigned int entry,void *addr) +{ +struct desc_struct *d =get_cpu_gdt_table (cpu); +tss_desc tss; + +/* +* sizeof(unsigned long) coming from an extra "long" at the end +* of the iobitmap. See tss_struct definition in processor.h +* +* -1? seg base+limit should be pointing to the address of the +* last valid byte +*/ +set_tssldt_descriptor (&tss, (unsigned long )addr, +IO_BITMAP_OFFSET +IO_BITMAP_BYTES +sizeof (unsigned long ) -1 , +DESC_TSS ); +write_gdt_entry (d, entry, &tss,DESC_TSS ); +} + +#define set_tss_desc (cpu, addr) __set_tss_desc(cpu, GDT_ENTRY_TSS, addr) +static inline void native_set_ldt (const void *addr,unsigned int entries) {if (likely (entries ==0 ))
@@ -214,12 +234,6 @@ static inline void native_load_tls(struc gdt[GDT_ENTRY_TLS_MIN + i] = t->tls_array[i]; } -#ifdef CONFIG_X86_32 -# include "desc_32.h" -#else -# include "desc_64.h" -#endif -#define _LDT_empty (info) (\ (info)->base_addr == 0 && \ (info)->limit == 0 && \
include/asm-x86/desc_32.h deleted +0 -27
@@ -1,27 +0,0 @@ -#ifndef __ARCH_DESC_H -#define __ARCH_DESC_H - -#include <asm/ldt.h> -#include <asm/segment.h> -#include <asm/desc_defs.h> - -#ifndef __ASSEMBLY__ - -#include <linux/preempt.h> -#include <linux/percpu.h> - -static inline void __set_tss_desc (unsigned int cpu,unsigned int entry,const void *addr) -{ -tss_desc tss; -pack_descriptor (&tss, (unsigned long )addr, - offsetof(struct tss_struct , __cacheline_filler) -1 , -DESC_TSS ,0 ); -write_gdt_entry (get_cpu_gdt_table (cpu), entry, &tss,DESC_TSS ); -} - - -#define set_tss_desc (cpu,addr) __set_tss_desc(cpu, GDT_ENTRY_TSS, addr) - -#endif /* !__ASSEMBLY__ */ - -#endif
include/asm-x86/desc_64.h +0 -33
@@ -1,34 +1 @@ -/* Written 2000 by Andi Kleen */ -#ifndef __ARCH_DESC_H -#define __ARCH_DESC_H -#include <linux/threads.h> -#include <asm/ldt.h> - -#ifndef __ASSEMBLY__ - -#include <linux/string.h> - -#include <asm/segment.h> - -static inline void set_tss_desc (unsigned cpu,void *addr) -{ -struct desc_struct *d =get_cpu_gdt_table (cpu); -tss_desc tss; - -/* -* sizeof(unsigned long) coming from an extra "long" at the end -* of the iobitmap. See tss_struct definition in processor.h -* -* -1? seg base+limit should be pointing to the address of the -* last valid byte -*/ -set_tssldt_descriptor (&tss, - (unsigned long )addr,DESC_TSS , -IO_BITMAP_OFFSET +IO_BITMAP_BYTES +sizeof (unsigned long ) -1 ); -write_gdt_entry (d,GDT_ENTRY_TSS , &tss,DESC_TSS ); -} - -#endif /* !__ASSEMBLY__ */ - -#endif
Re: [PATCH 18/19] move _set_gate and its users to a common location
In reply to Glauber de Oliveira CostaQuoted 2 lines · Glauber de Oliveira Costa
This patch moves
_set_gateand its users todesc.h. We can now use common code forx86_64and i386.
a few days ago i started seeing weird crashes on 64-bit x86 in the random-kernel-bootup tests. Nothing truly reproducable to be bisectable, but quality of x86.git went down drastically. Double faults, triple faults, crashes all around the place, with every few dozen kernel bootups.
Today i found a config and a workload that triggered the crashes a bit more reliably. I still needed a 6 hours bisection marathon to pinpoint the patch - the one in this thread. A review of it with H. Peter Anvin pinpointed the breakage:
include/asm-x86/desc.h static inline unsigned long get_desc_bas
Quoted 11 lines
include/asm-x86/desc.h +5
-5+static inline void set_system_gate (unsigned int n,void *addr) +{ +BUG_ON ((unsigned )n >0xFF ); +_set_gate (n,GATE_TRAP , addr,0x3 ,0 , __KERNEL_CS); +} -static inline void set_system_gate (int nr,void *func) -{ -BUG_ON ((unsigned )nr >0xFF ); -_set_gate (nr,GATE_INTERRUPT , (unsigned long ) func,3 ,0 ); -}
you changed the type of system gates on 64-bit from GATE_INTERRUPT to GATE_TRAP. The effect of this is that these gates enter with interrupts enabled - instead of interrupts disabled. This, amongst others, affects the following key gate:
set_system_gate(IA32_SYSCALL_VECTOR, ia32_syscall);
which relies on disabled interrupts to fix up its stack. If an interrupt comes in the wrong moment then we get a kernel stack corruption that is not survivable.
the reason for this bug was that you tried to do too many changes in a single patch. You did a cleanup, you did unification and you moved code around. It was totally non-obvious what you did and the resulting patch was not reviewable at all - even after the bisection poinpointed the patch, it took us almost 30 minutes to figure out where the bug was. If this unstructured, careless mess of patches continues then we are not going to be able to accept any more 64-bit paravirt patches into x86.git.
Ingo
Re: [PATCH 18/19] move _set_gate and its users to a common location
In reply to Glauber de Oliveira CostaQuoted 2 lines · Glauber de Oliveira Costa
This patch moves
_set_gateand its users todesc.h. We can now use common code forx86_64and i386.
a few days ago i started seeing weird crashes on 64-bit x86 in the random-kernel-bootup tests. Nothing truly reproducable to be bisectable, but quality of x86.git went down drastically. Double faults, triple faults, crashes all around the place, with every few dozen kernel bootups.
Today i found a config and a workload that triggered the crashes a bit more reliably. I still needed a 6 hours bisection marathon to pinpoint the patch - the one in this thread. A review of it with H. Peter Anvin pinpointed the breakage:
include/asm-x86/desc.h static inline unsigned long get_desc_bas
Quoted 11 lines
include/asm-x86/desc.h +5
-5+static inline void set_system_gate (unsigned int n,void *addr) +{ +BUG_ON ((unsigned )n >0xFF ); +_set_gate (n,GATE_TRAP , addr,0x3 ,0 , __KERNEL_CS); +} -static inline void set_system_gate (int nr,void *func) -{ -BUG_ON ((unsigned )nr >0xFF ); -_set_gate (nr,GATE_INTERRUPT , (unsigned long ) func,3 ,0 ); -}
you changed the type of system gates on 64-bit from GATE_INTERRUPT to GATE_TRAP. The effect of this is that these gates enter with interrupts enabled - instead of interrupts disabled. This, amongst others, affects the following key gate:
set_system_gate(IA32_SYSCALL_VECTOR, ia32_syscall);
which relies on disabled interrupts to fix up its stack. If an interrupt comes in the wrong moment then we get a kernel stack corruption that is not survivable.
the reason for this bug was that you tried to do too many changes in a single patch. You did a cleanup, you did unification and you moved code around. It was totally non-obvious what you did and the resulting patch was not reviewable at all - even after the bisection poinpointed the patch, it took us almost 30 minutes to figure out where the bug was. If this unstructured, careless mess of patches continues then we are not going to be able to accept any more 64-bit paravirt patches into x86.git.
Ingo
Quoted 9 lines · Glauber de Oliveira Costa
Since the last version of it received no comments on the interfaces, here it goes a version, that I feel ready for inclusion.
The comments regarding style, specially the elimination of the #defines in the
desc_structdefinition were merged. I also implemented the vmi functions, missing last time.Ingo, in the absense of further complaints, could you please push to the x86 tree?
well i've already included v3 in x86.git (and it's pushed out), and that was looking good already in review and in testing - could you send a v3->v4 delta too?
Ingo
Quoted 9 lines · Glauber de Oliveira Costa
Since the last version of it received no comments on the interfaces, here it goes a version, that I feel ready for inclusion.
The comments regarding style, specially the elimination of the #defines in the
desc_structdefinition were merged. I also implemented the vmi functions, missing last time.Ingo, in the absense of further complaints, could you please push to the x86 tree?
well i've already included v3 in x86.git (and it's pushed out), and that was looking good already in review and in testing - could you send a v3->v4 delta too?
Ingo
Quoted 9 lines · Ingo Molnar
Quoted 5 lines · Glauber de Oliveira Costa
Since the last version of it received no comments on the interfaces, here it goes a version, that I feel ready for inclusion.
The comments regarding style, specially the elimination of the #defines in the
desc_structdefinition were merged. I also implemented the vmi functions, missing last time.Ingo, in the absense of further complaints, could you please push to the x86 tree?
well i've already included v3 in x86.git (and it's pushed out), and that was looking good already in review and in testing - could you send a
v3->v4delta too?
Sure. The only real difference was Andi suggestion, but it was more stylish. Will do soon.
Quoted 9 lines · Ingo Molnar
Quoted 5 lines · Glauber de Oliveira Costa
Since the last version of it received no comments on the interfaces, here it goes a version, that I feel ready for inclusion.
The comments regarding style, specially the elimination of the #defines in the
desc_structdefinition were merged. I also implemented the vmi functions, missing last time.Ingo, in the absense of further complaints, could you please push to the x86 tree?
well i've already included v3 in x86.git (and it's pushed out), and that was looking good already in review and in testing - could you send a
v3->v4delta too?
Sure. The only real difference was Andi suggestion, but it was more stylish. Will do soon.