aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk>2003-10-13 16:59:01 +0000
committerkaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk>2003-10-13 16:59:01 +0000
commit2f2720da7ecaa8ed1da048644c226400b1503665 (patch)
treea9e989ff20bb9c6898aa35bb99beb50155b23feb
parentbc09945cf54db20b4bb66341d832bc6516b9207c (diff)
downloadxen-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.S19
-rw-r--r--xen/arch/i386/process.c2
-rw-r--r--xen/arch/i386/traps.c48
-rw-r--r--xen/common/memory.c10
-rw-r--r--xen/drivers/ide/ide-cd.h2
-rw-r--r--xen/include/xeno/sched.h6
-rw-r--r--xenolinux-2.4.22-sparse/arch/xeno/kernel/i386_ksyms.c2
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)