ia64/xen-unstable
changeset 722:7a9d47fea66c
bitkeeper revision 1.428 (3f677454_j81KDQLm_L7AscjYn2nYg)
Merge labyrinth.cl.cam.ac.uk:/auto/groups/xeno/BK/xeno.bk
into labyrinth.cl.cam.ac.uk:/auto/anfs/scratch/labyrinth/iap10/xeno-clone/xeno.bk
Merge labyrinth.cl.cam.ac.uk:/auto/groups/xeno/BK/xeno.bk
into labyrinth.cl.cam.ac.uk:/auto/anfs/scratch/labyrinth/iap10/xeno-clone/xeno.bk
author | iap10@labyrinth.cl.cam.ac.uk |
---|---|
date | Tue Sep 16 20:36:36 2003 +0000 (2003-09-16) |
parents | 2c22db3e819b d0cdb9994a2b |
children | 115b02b108a1 efd1ad397eb3 |
files | xen/arch/i386/entry.S xen/arch/i386/nmi.c xen/arch/i386/process.c xen/arch/i386/setup.c xen/arch/i386/traps.c xen/common/schedule.c xen/include/asm-i386/desc.h xen/include/xeno/sched.h |
line diff
1.1 --- a/xen/arch/i386/entry.S Tue Sep 16 20:36:20 2003 +0000 1.2 +++ b/xen/arch/i386/entry.S Tue Sep 16 20:36:36 2003 +0000 1.3 @@ -590,10 +590,6 @@ ENTRY(coprocessor_segment_overrun) 1.4 pushl $ SYMBOL_NAME(do_coprocessor_segment_overrun) 1.5 jmp error_code 1.6 1.7 -ENTRY(double_fault) 1.8 - pushl $ SYMBOL_NAME(do_double_fault) 1.9 - jmp error_code 1.10 - 1.11 ENTRY(invalid_TSS) 1.12 pushl $ SYMBOL_NAME(do_invalid_TSS) 1.13 jmp error_code
2.1 --- a/xen/arch/i386/nmi.c Tue Sep 16 20:36:20 2003 +0000 2.2 +++ b/xen/arch/i386/nmi.c Tue Sep 16 20:36:36 2003 +0000 2.3 @@ -230,7 +230,7 @@ static int __pminit setup_p4_watchdog(vo 2.4 return 1; 2.5 } 2.6 2.7 -void __pminit setup_apic_nmi_watchdog (void) 2.8 +void __pminit setup_apic_nmi_watchdog(void) 2.9 { 2.10 if (!nmi_watchdog) 2.11 return;
3.1 --- a/xen/arch/i386/process.c Tue Sep 16 20:36:20 2003 +0000 3.2 +++ b/xen/arch/i386/process.c Tue Sep 16 20:36:36 2003 +0000 3.3 @@ -73,9 +73,8 @@ void cpu_idle (void) 3.4 { 3.5 int cpu = smp_processor_id(); 3.6 3.7 + /* Just some sanity to ensure that the scheduler is set up okay. */ 3.8 ASSERT(current->domain == IDLE_DOMAIN_ID); 3.9 - 3.10 - current->has_cpu = 1; 3.11 (void)wake_up(current); 3.12 schedule(); 3.13
4.1 --- a/xen/arch/i386/setup.c Tue Sep 16 20:36:20 2003 +0000 4.2 +++ b/xen/arch/i386/setup.c Tue Sep 16 20:36:36 2003 +0000 4.3 @@ -271,6 +271,8 @@ void __init cpu_init(void) 4.4 mapcache[nr] = (unsigned long *)get_free_page(GFP_KERNEL); 4.5 clear_page(mapcache[nr]); 4.6 *pl2e = mk_l2_pgentry(__pa(mapcache[nr]) | PAGE_HYPERVISOR); 4.7 + 4.8 + init_idle_task(); 4.9 } 4.10 4.11 static void __init do_initcalls(void)
5.1 --- a/xen/arch/i386/traps.c Tue Sep 16 20:36:20 2003 +0000 5.2 +++ b/xen/arch/i386/traps.c Tue Sep 16 20:36:36 2003 +0000 5.3 @@ -41,6 +41,10 @@ struct guest_trap_bounce { 5.4 unsigned long eip; /* 12 */ 5.5 } guest_trap_bounce[NR_CPUS] = { { 0 } }; 5.6 5.7 +#define DOUBLEFAULT_STACK_SIZE 1024 5.8 +static struct tss_struct doublefault_tss; 5.9 +static unsigned char doublefault_stack[DOUBLEFAULT_STACK_SIZE]; 5.10 + 5.11 asmlinkage int hypervisor_call(void); 5.12 asmlinkage void lcall7(void); 5.13 asmlinkage void lcall27(void); 5.14 @@ -58,7 +62,6 @@ asmlinkage void overflow(void); 5.15 asmlinkage void bounds(void); 5.16 asmlinkage void invalid_op(void); 5.17 asmlinkage void device_not_available(void); 5.18 -asmlinkage void double_fault(void); 5.19 asmlinkage void coprocessor_segment_overrun(void); 5.20 asmlinkage void invalid_TSS(void); 5.21 asmlinkage void segment_not_present(void); 5.22 @@ -119,19 +122,17 @@ void show_stack(unsigned long * esp) 5.23 unsigned long *stack; 5.24 int i; 5.25 5.26 - // debugging aid: "show_stack(NULL);" prints the 5.27 - // back trace for this cpu. 5.28 - 5.29 - if(esp==NULL) 5.30 - esp=(unsigned long*)&esp; 5.31 + if ( esp == NULL ) 5.32 + esp = (unsigned long *)&esp; 5.33 5.34 printk("Stack trace from ESP=%p:\n", esp); 5.35 5.36 stack = esp; 5.37 - for(i=0; i < kstack_depth_to_print; i++) { 5.38 - if (((long) stack & (THREAD_SIZE-1)) == 0) 5.39 + for ( i = 0; i < kstack_depth_to_print; i++ ) 5.40 + { 5.41 + if ( ((long)stack & (THREAD_SIZE-1)) == 0 ) 5.42 break; 5.43 - if (i && ((i % 8) == 0)) 5.44 + if ( i && ((i % 8) == 0) ) 5.45 printk("\n "); 5.46 if ( kernel_text_address(*stack) ) 5.47 printk("[%08lx] ", *stack++); 5.48 @@ -139,7 +140,6 @@ void show_stack(unsigned long * esp) 5.49 printk("%08lx ", *stack++); 5.50 } 5.51 printk("\n"); 5.52 - //show_trace(esp); 5.53 } 5.54 5.55 void show_registers(struct pt_regs *regs) 5.56 @@ -240,7 +240,6 @@ DO_ERROR_NOCODE( 4, "overflow", overflow 5.57 DO_ERROR_NOCODE( 5, "bounds", bounds) 5.58 DO_ERROR_NOCODE( 6, "invalid operand", invalid_op) 5.59 DO_ERROR_NOCODE( 7, "device not available", device_not_available) 5.60 -DO_ERROR( 8, "double fault", double_fault) 5.61 DO_ERROR_NOCODE( 9, "coprocessor segment overrun", coprocessor_segment_overrun) 5.62 DO_ERROR(10, "invalid TSS", invalid_TSS) 5.63 DO_ERROR(11, "segment not present", segment_not_present) 5.64 @@ -251,6 +250,38 @@ DO_ERROR(17, "alignment check", alignmen 5.65 DO_ERROR_NOCODE(18, "machine check", machine_check) 5.66 DO_ERROR_NOCODE(19, "simd error", simd_coprocessor_error) 5.67 5.68 +asmlinkage void do_double_fault(void) 5.69 +{ 5.70 + extern spinlock_t console_lock; 5.71 + struct tss_struct *tss = &doublefault_tss; 5.72 + unsigned int cpu = ((tss->back_link>>3)-__FIRST_TSS_ENTRY)>>1; 5.73 + 5.74 + /* Disable the NMI watchdog. It's useless now. */ 5.75 + watchdog_on = 0; 5.76 + 5.77 + /* Find information saved during fault and dump it to the console. */ 5.78 + tss = &init_tss[cpu]; 5.79 + printk("CPU: %d\nEIP: %04x:[<%08lx>] \nEFLAGS: %08lx\n", 5.80 + cpu, tss->cs, tss->eip, tss->eflags); 5.81 + printk("CR3: %08lx\n", tss->__cr3); 5.82 + printk("eax: %08lx ebx: %08lx ecx: %08lx edx: %08lx\n", 5.83 + tss->eax, tss->ebx, tss->ecx, tss->edx); 5.84 + printk("esi: %08lx edi: %08lx ebp: %08lx esp: %08lx\n", 5.85 + tss->esi, tss->edi, tss->ebp, tss->esp); 5.86 + printk("ds: %04x es: %04x fs: %04x gs: %04x ss: %04x\n", 5.87 + tss->ds, tss->es, tss->fs, tss->gs, tss->ss); 5.88 + printk("************************************\n"); 5.89 + printk("CPU%d DOUBLE FAULT -- system shutdown\n", cpu); 5.90 + printk("System needs manual reset.\n"); 5.91 + printk("************************************\n"); 5.92 + 5.93 + /* Lock up the console to prevent spurious output from other CPUs. */ 5.94 + spin_lock(&console_lock); 5.95 + 5.96 + /* Wait for manual reset. */ 5.97 + for ( ; ; ) ; 5.98 +} 5.99 + 5.100 asmlinkage void do_page_fault(struct pt_regs *regs, long error_code) 5.101 { 5.102 struct guest_trap_bounce *gtb = guest_trap_bounce+smp_processor_id(); 5.103 @@ -603,6 +634,12 @@ static void __init set_system_gate(unsig 5.104 _set_gate(idt_table+n,14,3,addr); 5.105 } 5.106 5.107 +static void set_task_gate(unsigned int n, unsigned int sel) 5.108 +{ 5.109 + idt_table[n].a = sel << 16; 5.110 + idt_table[n].b = 0x8500; 5.111 +} 5.112 + 5.113 #define _set_seg_desc(gate_addr,type,dpl,base,limit) {\ 5.114 *((gate_addr)+1) = ((base) & 0xff000000) | \ 5.115 (((base) & 0x00ff0000)>>16) | \ 5.116 @@ -632,6 +669,25 @@ void set_tss_desc(unsigned int n, void * 5.117 void __init trap_init(void) 5.118 { 5.119 /* 5.120 + * Make a separate task for double faults. This will get us debug output if 5.121 + * we blow the kernel stack. 5.122 + */ 5.123 + struct tss_struct *tss = &doublefault_tss; 5.124 + memset(tss, 0, sizeof(*tss)); 5.125 + tss->ds = __HYPERVISOR_DS; 5.126 + tss->es = __HYPERVISOR_DS; 5.127 + tss->ss = __HYPERVISOR_DS; 5.128 + tss->esp = (unsigned long) 5.129 + &doublefault_stack[DOUBLEFAULT_STACK_SIZE]; 5.130 + tss->__cr3 = __pa(idle0_pg_table); 5.131 + tss->cs = __HYPERVISOR_CS; 5.132 + tss->eip = (unsigned long)do_double_fault; 5.133 + tss->eflags = 2; 5.134 + tss->bitmap = INVALID_IO_BITMAP_OFFSET; 5.135 + _set_tssldt_desc(gdt_table+__DOUBLEFAULT_TSS_ENTRY, 5.136 + (int)tss, 235, 0x89); 5.137 + 5.138 + /* 5.139 * Note that interrupt gates are always used, rather than trap gates. We 5.140 * must have interrupts disabled until DS/ES/FS/GS are saved because the 5.141 * first activation must have the "bad" value(s) for these registers and 5.142 @@ -647,7 +703,7 @@ void __init trap_init(void) 5.143 set_intr_gate(5,&bounds); 5.144 set_intr_gate(6,&invalid_op); 5.145 set_intr_gate(7,&device_not_available); 5.146 - set_intr_gate(8,&double_fault); 5.147 + set_task_gate(8,__DOUBLEFAULT_TSS_ENTRY<<3); 5.148 set_intr_gate(9,&coprocessor_segment_overrun); 5.149 set_intr_gate(10,&invalid_TSS); 5.150 set_intr_gate(11,&segment_not_present);
6.1 --- a/xen/common/schedule.c Tue Sep 16 20:36:20 2003 +0000 6.2 +++ b/xen/common/schedule.c Tue Sep 16 20:36:36 2003 +0000 6.3 @@ -1,22 +1,15 @@ 6.4 /* -*- Mode:C; c-basic-offset:4; tab-width:4 -*- 6.5 **************************************************************************** 6.6 - * (C) 2002 - Rolf Neugebauer - Intel Research Cambridge 6.7 + * (C) 2002-2003 - Rolf Neugebauer - Intel Research Cambridge 6.8 + * (C) 2002-2003 University of Cambridge 6.9 **************************************************************************** 6.10 * 6.11 - * File: schedule.c 6.12 - * Author: Rolf Neugebauer (neugebar@dcs.gla.ac.uk) 6.13 - * Changes: 6.14 - * 6.15 - * Date: Nov 2002 6.16 + * File: common/schedule.c 6.17 + * Author: Rolf Neugebar & Keir Fraser 6.18 * 6.19 - * Environment: Xen Hypervisor 6.20 * Description: CPU scheduling 6.21 * implements A Borrowed Virtual Time scheduler. 6.22 * (see Duda & Cheriton SOSP'99) 6.23 - * 6.24 - **************************************************************************** 6.25 - * $Id: c-insert.c,v 1.7 2002/11/08 16:04:34 rn Exp $ 6.26 - **************************************************************************** 6.27 */ 6.28 6.29 #include <xeno/config.h> 6.30 @@ -39,20 +32,16 @@ 6.31 #define TRC(_x) 6.32 #endif 6.33 6.34 -#define SCHED_HISTO 6.35 +/*#define SCHED_HISTO*/ 6.36 #ifdef SCHED_HISTO 6.37 #define BUCKETS 31 6.38 #endif 6.39 6.40 +#define MCU (s32)MICROSECS(100) /* Minimum unit */ 6.41 +#define MCU_ADVANCE 10 /* default weight */ 6.42 +#define TIME_SLOP (s32)MICROSECS(50) /* allow time to slip a bit */ 6.43 +static s32 ctx_allow = (s32)MILLISECS(5); /* context switch allowance */ 6.44 6.45 -#define MCU (s32)MICROSECS(100) /* Minimum unit */ 6.46 -#define MCU_ADVANCE 10 /* default weight */ 6.47 -#define TIME_SLOP (s32)MICROSECS(50) /* allow time to slip a bit */ 6.48 -static s32 ctx_allow=(s32)MILLISECS(5); /* context switch allowance */ 6.49 - 6.50 -/***************************************************************************** 6.51 - * per CPU data for the scheduler. 6.52 - *****************************************************************************/ 6.53 typedef struct schedule_data_st 6.54 { 6.55 spinlock_t lock; /* lock for protecting this */ 6.56 @@ -64,61 +53,59 @@ typedef struct schedule_data_st 6.57 #ifdef SCHED_HISTO 6.58 u32 hist[BUCKETS]; /* for scheduler latency histogram */ 6.59 #endif 6.60 - 6.61 } __cacheline_aligned schedule_data_t; 6.62 schedule_data_t schedule_data[NR_CPUS]; 6.63 6.64 -struct ac_timer v_timer; /* scheduling timer */ 6.65 +struct ac_timer v_timer; /* scheduling timer */ 6.66 static void virt_timer(unsigned long foo); 6.67 static void dump_rqueue(struct list_head *queue, char *name); 6.68 6.69 6.70 -/***************************************************************************** 6.71 - * Some convenience functions 6.72 - *****************************************************************************/ 6.73 -/* add a task to the head of the runqueue */ 6.74 static inline void __add_to_runqueue_head(struct task_struct * p) 6.75 -{ 6.76 - 6.77 +{ 6.78 list_add(&p->run_list, &schedule_data[p->processor].runqueue); 6.79 } 6.80 -/* add a task to the tail of the runqueue */ 6.81 + 6.82 static inline void __add_to_runqueue_tail(struct task_struct * p) 6.83 { 6.84 list_add_tail(&p->run_list, &schedule_data[p->processor].runqueue); 6.85 } 6.86 6.87 -/* remove a task from runqueue */ 6.88 static inline void __del_from_runqueue(struct task_struct * p) 6.89 { 6.90 list_del(&p->run_list); 6.91 p->run_list.next = NULL; 6.92 } 6.93 -/* is task on run queue? */ 6.94 + 6.95 static inline int __task_on_runqueue(struct task_struct *p) 6.96 { 6.97 - return (p->run_list.next != NULL); 6.98 + return p->run_list.next != NULL; 6.99 } 6.100 6.101 #define next_domain(p) \\ 6.102 list_entry((p)->run_list.next, struct task_struct, run_list) 6.103 6.104 -/* calculate evt */ 6.105 static void __calc_evt(struct task_struct *p) 6.106 { 6.107 s_time_t now = NOW(); 6.108 - if (p->warpback) { 6.109 - if (((now - p->warped) < p->warpl) && 6.110 - ((now - p->uwarped) > p->warpu)) { 6.111 + if ( p->warpback ) 6.112 + { 6.113 + if ( ((now - p->warped) < p->warpl) && 6.114 + ((now - p->uwarped) > p->warpu) ) 6.115 + { 6.116 /* allowed to warp */ 6.117 p->evt = p->avt - p->warp; 6.118 - } else { 6.119 + } 6.120 + else 6.121 + { 6.122 /* warped for too long -> unwarp */ 6.123 p->evt = p->avt; 6.124 p->uwarped = now; 6.125 p->warpback = 0; 6.126 } 6.127 - } else { 6.128 + } 6.129 + else 6.130 + { 6.131 p->evt = p->avt; 6.132 } 6.133 } 6.134 @@ -132,11 +119,14 @@ void sched_add_domain(struct task_struct 6.135 p->state = TASK_SUSPENDED; 6.136 p->mcu_advance = MCU_ADVANCE; 6.137 6.138 - if (p->domain == IDLE_DOMAIN_ID) { 6.139 + if ( p->domain == IDLE_DOMAIN_ID ) 6.140 + { 6.141 p->avt = 0xffffffff; 6.142 p->evt = 0xffffffff; 6.143 schedule_data[p->processor].idle = p; 6.144 - } else { 6.145 + } 6.146 + else 6.147 + { 6.148 /* set avt end evt to system virtual time */ 6.149 p->avt = schedule_data[p->processor].svt; 6.150 p->evt = schedule_data[p->processor].svt; 6.151 @@ -154,6 +144,19 @@ void sched_rem_domain(struct task_struct 6.152 } 6.153 6.154 6.155 +void init_idle_task(void) 6.156 +{ 6.157 + unsigned long flags; 6.158 + struct task_struct *p = current; 6.159 + spin_lock_irqsave(&schedule_data[p->processor].lock, flags); 6.160 + p->has_cpu = 1; 6.161 + p->state = TASK_RUNNING; 6.162 + if ( !__task_on_runqueue(p) ) 6.163 + __add_to_runqueue_head(p); 6.164 + spin_unlock_irqrestore(&schedule_data[p->processor].lock, flags); 6.165 +} 6.166 + 6.167 + 6.168 /**************************************************************************** 6.169 * wake up a domain which had been sleeping 6.170 ****************************************************************************/
7.1 --- a/xen/include/asm-i386/desc.h Tue Sep 16 20:36:20 2003 +0000 7.2 +++ b/xen/include/asm-i386/desc.h Tue Sep 16 20:36:36 2003 +0000 7.3 @@ -3,6 +3,8 @@ 7.4 7.5 #define LDT_ENTRY_SIZE 8 7.6 7.7 +#define __DOUBLEFAULT_TSS_ENTRY FIRST_RESERVED_GDT_ENTRY 7.8 + 7.9 #define __FIRST_TSS_ENTRY (FIRST_RESERVED_GDT_ENTRY + 8) 7.10 #define __FIRST_LDT_ENTRY (__FIRST_TSS_ENTRY + 1) 7.11
8.1 --- a/xen/include/xeno/sched.h Tue Sep 16 20:36:20 2003 +0000 8.2 +++ b/xen/include/xeno/sched.h Tue Sep 16 20:36:36 2003 +0000 8.3 @@ -271,6 +271,7 @@ void sched_rem_domain(struct task_struct 8.4 long sched_bvtctl(unsigned long ctx_allow); 8.5 long sched_adjdom(int dom, unsigned long mcu_adv, unsigned long warp, 8.6 unsigned long warpl, unsigned long warpu); 8.7 +void init_idle_task(void); 8.8 int wake_up(struct task_struct *p); 8.9 long schedule_timeout(long timeout); 8.10 long do_yield(void);