diff options
author | kaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk> | 2003-10-13 16:59:01 +0000 |
---|---|---|
committer | kaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk> | 2003-10-13 16:59:01 +0000 |
commit | 2f2720da7ecaa8ed1da048644c226400b1503665 (patch) | |
tree | a9e989ff20bb9c6898aa35bb99beb50155b23feb | |
parent | bc09945cf54db20b4bb66341d832bc6516b9207c (diff) | |
download | xen-2f2720da7ecaa8ed1da048644c226400b1503665.tar.gz xen-2f2720da7ecaa8ed1da048644c226400b1503665.tar.bz2 xen-2f2720da7ecaa8ed1da048644c226400b1503665.zip |
bitkeeper revision 1.507 (3f8ad9d51NEWhiPGDd2jxu-ez0fnOA)
i386_ksyms.c, sched.h, ide-cd.h, memory.c, traps.c, process.c, entry.S:
Fix LDT bug when switching domains.
-rw-r--r-- | xen/arch/i386/entry.S | 19 | ||||
-rw-r--r-- | xen/arch/i386/process.c | 2 | ||||
-rw-r--r-- | xen/arch/i386/traps.c | 48 | ||||
-rw-r--r-- | xen/common/memory.c | 10 | ||||
-rw-r--r-- | xen/drivers/ide/ide-cd.h | 2 | ||||
-rw-r--r-- | xen/include/xeno/sched.h | 6 | ||||
-rw-r--r-- | xenolinux-2.4.22-sparse/arch/xeno/kernel/i386_ksyms.c | 2 |
7 files changed, 59 insertions, 30 deletions
diff --git a/xen/arch/i386/entry.S b/xen/arch/i386/entry.S index 2fe19dfb68..7454b693f5 100644 --- a/xen/arch/i386/entry.S +++ b/xen/arch/i386/entry.S @@ -490,15 +490,6 @@ ENTRY(ret_from_intr) jne test_all_events jmp restore_all - ALIGN -ret_from_exception: - movb CS(%esp),%al - testb $3,%al # return to non-supervisor? - jne process_guest_exception_and_events - jmp restore_all - - ALIGN - ENTRY(divide_error) pushl $0 # no error code pushl $ SYMBOL_NAME(do_divide_error) @@ -530,11 +521,11 @@ error_code: movl %edx,%es GET_CURRENT(%ebx) call *%edi - # NB. We reenable interrupts AFTER exception processing, as that is - # required by the page fault handler (needs to save %cr2) - sti addl $8,%esp - jmp ret_from_exception + movb CS(%esp),%al + testb $3,%al + je restore_all + jmp process_guest_exception_and_events ENTRY(coprocessor_error) pushl $0 @@ -564,7 +555,7 @@ ENTRY(nmi) pushl %edx call SYMBOL_NAME(do_nmi) addl $8,%esp - RESTORE_ALL + jmp restore_all ENTRY(int3) pushl $0 diff --git a/xen/arch/i386/process.c b/xen/arch/i386/process.c index 0adcbbf47d..a00a95f8fd 100644 --- a/xen/arch/i386/process.c +++ b/xen/arch/i386/process.c @@ -288,7 +288,7 @@ void switch_to(struct task_struct *prev_p, struct task_struct *next_p) /* Switch GDT and LDT. */ __asm__ __volatile__ ("lgdt %0" : "=m" (*next_p->mm.gdt)); - load_LDT(); + load_LDT(next_p); /* Maybe switch the debug registers. */ if ( next->debugreg[7] ) diff --git a/xen/arch/i386/traps.c b/xen/arch/i386/traps.c index e855ec29ed..a255fe9f1f 100644 --- a/xen/arch/i386/traps.c +++ b/xen/arch/i386/traps.c @@ -185,13 +185,47 @@ void die(const char * str, struct pt_regs * regs, long err) panic("HYPERVISOR DEATH!!\n"); } -static inline void die_if_kernel(const char * str, struct pt_regs * regs, long err) +#define check_selector(_s) \ + ({ int err; \ + __asm__ __volatile__ ( \ + "1: movl %2,%%gs \n" \ + "2: \n" \ + ".section .fixup,\"ax\"\n" \ + "3: incl %0 \n" \ + " jmp 2b \n" \ + ".previous \n" \ + ".section __ex_table,\"a\"\n" \ + ".align 4 \n" \ + ".long 1b,3b \n" \ + ".previous " \ + : "=&r" (err) : "0" (0), \ + "m" (*(unsigned int *)&(_s))); \ + err; }) + +static inline void check_saved_selectors(struct pt_regs *regs) { - if (!(3 & regs->xcs)) die(str, regs, err); + /* Prevent recursion. */ + __asm__ __volatile__ ( + "movl %0,%%fs; movl %0,%%gs" + : : "r" (0) ); + + /* + * NB. We need to check DS and ES as well, since we may have taken + * an exception after they were restored in + */ + if ( check_selector(regs->xds) ) + regs->xds = 0; + if ( check_selector(regs->xes) ) + regs->xes = 0; + if ( check_selector(regs->xfs) ) + regs->xfs = 0; + if ( check_selector(regs->xgs) ) + regs->xgs = 0; } -static void inline do_trap(int trapnr, char *str, - struct pt_regs * regs, + +static inline void do_trap(int trapnr, char *str, + struct pt_regs *regs, long error_code, int use_error_code) { struct task_struct *p = current; @@ -216,7 +250,7 @@ static void inline do_trap(int trapnr, char *str, if ( (fixup = search_exception_table(regs->eip)) != 0 ) { regs->eip = fixup; - regs->xfs = regs->xgs = 0; + check_saved_selectors(regs); return; } @@ -380,7 +414,7 @@ asmlinkage void do_page_fault(struct pt_regs *regs, long error_code) if ( (fixup = search_exception_table(regs->eip)) != 0 ) { regs->eip = fixup; - regs->xfs = regs->xgs = 0; + check_saved_selectors(regs); return; } @@ -463,7 +497,7 @@ asmlinkage void do_general_protection(struct pt_regs *regs, long error_code) if ( (fixup = search_exception_table(regs->eip)) != 0 ) { regs->eip = fixup; - regs->xfs = regs->xgs = 0; + check_saved_selectors(regs); return; } diff --git a/xen/common/memory.c b/xen/common/memory.c index 0a066de955..b230c7cb7c 100644 --- a/xen/common/memory.c +++ b/xen/common/memory.c @@ -231,7 +231,12 @@ static void __invalidate_shadow_ldt(void) put_page_type(page); put_page_tot(page); } + + /* Dispose of the (now possibly invalid) mappings from the TLB. */ + flush_tlb[smp_processor_id()] = 1; } + + static inline void invalidate_shadow_ldt(void) { if ( current->mm.shadow_ldt_mapcnt != 0 ) @@ -720,13 +725,10 @@ static int do_extended_command(unsigned long ptr, unsigned long val) (current->mm.ldt_base != ptr) ) { if ( current->mm.ldt_ents != 0 ) - { invalidate_shadow_ldt(); - flush_tlb[smp_processor_id()] = 1; - } current->mm.ldt_base = ptr; current->mm.ldt_ents = ents; - load_LDT(); + load_LDT(current); } break; } diff --git a/xen/drivers/ide/ide-cd.h b/xen/drivers/ide/ide-cd.h index 636e88b02d..e2fe314851 100644 --- a/xen/drivers/ide/ide-cd.h +++ b/xen/drivers/ide/ide-cd.h @@ -439,7 +439,7 @@ struct atapi_mechstat_header { byte curlba[3]; byte nslots; - __u8 short slot_tablelen; + __u16 slot_tablelen; }; diff --git a/xen/include/xeno/sched.h b/xen/include/xeno/sched.h index 820bd29313..595eb4c216 100644 --- a/xen/include/xeno/sched.h +++ b/xen/include/xeno/sched.h @@ -311,20 +311,20 @@ struct task_struct *task_hash[TASK_HASH_SIZE]; extern void update_process_times(int user); #include <asm/desc.h> -static inline void load_LDT(void) +static inline void load_LDT(struct task_struct *p) { unsigned int cpu; struct desc_struct *desc; unsigned long ents; - if ( (ents = current->mm.ldt_ents) == 0 ) + if ( (ents = p->mm.ldt_ents) == 0 ) { __asm__ __volatile__ ( "lldt %%ax" : : "a" (0) ); } else { cpu = smp_processor_id(); - desc = (struct desc_struct *)GET_GDT_ADDRESS(current) + __LDT(cpu); + desc = (struct desc_struct *)GET_GDT_ADDRESS(p) + __LDT(cpu); desc->a = ((LDT_VIRT_START&0xffff)<<16) | (ents*8-1); desc->b = (LDT_VIRT_START&(0xff<<24)) | 0x8200 | ((LDT_VIRT_START&0xff0000)>>16); diff --git a/xenolinux-2.4.22-sparse/arch/xeno/kernel/i386_ksyms.c b/xenolinux-2.4.22-sparse/arch/xeno/kernel/i386_ksyms.c index 06673f253d..87f65156b4 100644 --- a/xenolinux-2.4.22-sparse/arch/xeno/kernel/i386_ksyms.c +++ b/xenolinux-2.4.22-sparse/arch/xeno/kernel/i386_ksyms.c @@ -159,3 +159,5 @@ EXPORT_SYMBOL(xquad_portio); EXPORT_SYMBOL(create_xeno_proc_entry); EXPORT_SYMBOL(remove_xeno_proc_entry); +EXPORT_SYMBOL(do_hypervisor_callback) +EXPORT_SYMBOL(HYPERVISOR_shared_info) |