diff options
-rw-r--r-- | xen/arch/ia64/domain.c | 5 | ||||
-rw-r--r-- | xen/arch/x86/domain.c | 3 | ||||
-rw-r--r-- | xen/arch/x86/mm.c | 48 | ||||
-rw-r--r-- | xen/arch/x86/shadow.c | 16 | ||||
-rw-r--r-- | xen/arch/x86/traps.c | 29 | ||||
-rw-r--r-- | xen/arch/x86/vmx.c | 19 | ||||
-rw-r--r-- | xen/arch/x86/vmx_intercept.c | 2 | ||||
-rw-r--r-- | xen/arch/x86/vmx_io.c | 6 | ||||
-rw-r--r-- | xen/arch/x86/vmx_platform.c | 14 | ||||
-rw-r--r-- | xen/arch/x86/x86_32/entry.S | 24 | ||||
-rw-r--r-- | xen/arch/x86/x86_64/entry.S | 14 | ||||
-rw-r--r-- | xen/common/domain.c | 28 | ||||
-rw-r--r-- | xen/common/schedule.c | 9 | ||||
-rw-r--r-- | xen/drivers/char/console.c | 2 | ||||
-rw-r--r-- | xen/include/asm-x86/debugger.h | 76 | ||||
-rw-r--r-- | xen/include/asm-x86/vmx_vmcs.h | 2 | ||||
-rw-r--r-- | xen/include/xen/sched.h | 15 |
17 files changed, 119 insertions, 193 deletions
diff --git a/xen/arch/ia64/domain.c b/xen/arch/ia64/domain.c index 612a2059d0..640da616d2 100644 --- a/xen/arch/ia64/domain.c +++ b/xen/arch/ia64/domain.c @@ -102,8 +102,9 @@ void startup_cpu_idle_loop(void) { /* Just some sanity to ensure that the scheduler is set up okay. */ ASSERT(current->domain == IDLE_DOMAIN_ID); - domain_unpause_by_systemcontroller(current); - __enter_scheduler(); + domain_unpause_by_systemcontroller(current); + raise_softirq(SCHEDULE_SOFTIRQ); + do_softirq(); /* * Declares CPU setup done to the boot processor. diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c index 906da39dea..dbebab53d6 100644 --- a/xen/arch/x86/domain.c +++ b/xen/arch/x86/domain.c @@ -74,7 +74,8 @@ void startup_cpu_idle_loop(void) /* Just some sanity to ensure that the scheduler is set up okay. */ ASSERT(current->domain->id == IDLE_DOMAIN_ID); domain_unpause_by_systemcontroller(current->domain); - __enter_scheduler(); + raise_softirq(SCHEDULE_SOFTIRQ); + do_softirq(); /* * Declares CPU setup done to the boot processor. diff --git a/xen/arch/x86/mm.c b/xen/arch/x86/mm.c index ee661bc186..775af20209 100644 --- a/xen/arch/x86/mm.c +++ b/xen/arch/x86/mm.c @@ -1669,8 +1669,8 @@ int do_mmu_update( if ( unlikely(shadow_mode_enabled(d)) ) check_pagetable(d, ed->arch.guest_table, "pre-mmu"); /* debug */ - if ( unlikely(shadow_mode_translate(d) ) ) - domain_crash(); + if ( unlikely(shadow_mode_translate(d)) ) + domain_crash_synchronous(); /* * If we are resuming after preemption, read how much work we have already @@ -2033,8 +2033,8 @@ int do_update_va_mapping(unsigned long va, if ( unlikely(!__addr_ok(va)) ) return -EINVAL; - if ( unlikely(shadow_mode_translate(d) ) ) - domain_crash(); + if ( unlikely(shadow_mode_translate(d)) ) + domain_crash_synchronous(); LOCK_BIGLOCK(d); @@ -2312,7 +2312,7 @@ void ptwr_flush(const int which) MEM_LOG("ptwr: Could not read pte at %p\n", ptep); /* * Really a bug. We could read this PTE during the initial fault, - * and pagetables can't have changed meantime. XXX Multi-CPU guests? + * and pagetables can't have changed meantime. */ BUG(); } @@ -2339,7 +2339,7 @@ void ptwr_flush(const int which) MEM_LOG("ptwr: Could not update pte at %p\n", ptep); /* * Really a bug. We could write this PTE during the initial fault, - * and pagetables can't have changed meantime. XXX Multi-CPU guests? + * and pagetables can't have changed meantime. */ BUG(); } @@ -2395,6 +2395,7 @@ void ptwr_flush(const int which) unmap_domain_mem(pl1e); ptwr_info[cpu].ptinfo[which].l1va = 0; domain_crash(); + return; } if ( unlikely(sl1e != NULL) ) @@ -2688,6 +2689,7 @@ int ptwr_do_page_fault(unsigned long addr) unmap_domain_mem(ptwr_info[cpu].ptinfo[which].pl1e); ptwr_info[cpu].ptinfo[which].l1va = 0; domain_crash(); + return 0; } return EXCRET_fault_fixed; @@ -2725,40 +2727,6 @@ __initcall(ptwr_init); #ifndef NDEBUG -void ptwr_status(void) -{ - unsigned long pte, *ptep, pfn; - struct pfn_info *page; - int cpu = smp_processor_id(); - - ptep = (unsigned long *)&linear_pg_table - [ptwr_info[cpu].ptinfo[PTWR_PT_INACTIVE].l1va>>PAGE_SHIFT]; - - if ( __get_user(pte, ptep) ) { - MEM_LOG("ptwr: Could not read pte at %p\n", ptep); - domain_crash(); - } - - pfn = pte >> PAGE_SHIFT; - page = &frame_table[pfn]; - printk("need to alloc l1 page %p\n", page); - /* make pt page writable */ - printk("need to make read-only l1-page at %p is %p\n", - ptep, pte); - - if ( ptwr_info[cpu].ptinfo[PTWR_PT_ACTIVE].l1va == 0 ) - return; - - if ( __get_user(pte, (unsigned long *) - ptwr_info[cpu].ptinfo[PTWR_PT_ACTIVE].l1va) ) { - MEM_LOG("ptwr: Could not read pte at %p\n", (unsigned long *) - ptwr_info[cpu].ptinfo[PTWR_PT_ACTIVE].l1va); - domain_crash(); - } - pfn = pte >> PAGE_SHIFT; - page = &frame_table[pfn]; -} - void audit_pagelist(struct domain *d) { struct list_head *list_ent; diff --git a/xen/arch/x86/shadow.c b/xen/arch/x86/shadow.c index f9c1b84ff7..4e755d0597 100644 --- a/xen/arch/x86/shadow.c +++ b/xen/arch/x86/shadow.c @@ -655,15 +655,13 @@ int shadow_fault(unsigned long va, struct xen_regs *regs) &linear_pg_table[va >> PAGE_SHIFT])) ) { SH_VVLOG("shadow_fault - EXIT: read gpte faulted2" ); - shadow_unlock(d); - return 0; + goto fail; } if ( unlikely(!(gpte & _PAGE_PRESENT)) ) { SH_VVLOG("shadow_fault - EXIT: gpte not present2 (%lx)",gpte ); - shadow_unlock(d); - return 0; + goto fail; } /* Write fault? */ @@ -673,8 +671,7 @@ int shadow_fault(unsigned long va, struct xen_regs *regs) { /* Write fault on a read-only mapping. */ SH_VVLOG("shadow_fault - EXIT: wr fault on RO page (%lx)", gpte); - shadow_unlock(d); - return 0; + goto fail; } l1pte_write_fault(d, &gpte, &spte); @@ -691,7 +688,10 @@ int shadow_fault(unsigned long va, struct xen_regs *regs) /* XXX Watch out for read-only L2 entries! (not used in Linux). */ if ( unlikely(__put_user(gpte, (unsigned long *) &linear_pg_table[va >> PAGE_SHIFT])) ) + { domain_crash(); + goto fail; + } /* * Update of shadow PTE can fail because the L1 p.t. is not shadowed, @@ -712,6 +712,10 @@ int shadow_fault(unsigned long va, struct xen_regs *regs) check_pagetable(d, ed->arch.guest_table, "post-sf"); return EXCRET_fault_fixed; + + fail: + shadow_unlock(d); + return 0; } diff --git a/xen/arch/x86/traps.c b/xen/arch/x86/traps.c index 3304d96df5..c9eebd4954 100644 --- a/xen/arch/x86/traps.c +++ b/xen/arch/x86/traps.c @@ -223,18 +223,7 @@ asmlinkage int do_int3(struct xen_regs *regs) show_registers(regs); panic("CPU%d FATAL TRAP: vector = 3 (Int3)\n", smp_processor_id()); } -#ifdef DOMU_DEBUG - else if ( KERNEL_MODE(ed, regs) && ed->domain->id != 0 ) - { - if ( !test_and_set_bit(EDF_CTRLPAUSE, &ed->ed_flags) ) { - while (ed == current) - __enter_scheduler(); - domain_pause_by_systemcontroller(ed->domain); - } - - return 0; - } -#endif /* DOMU_DEBUG */ + ti = current->arch.traps + 3; tb->flags = TBF_EXCEPTION; tb->cs = ti->cs; @@ -950,8 +939,6 @@ asmlinkage int do_debug(struct xen_regs *regs) struct exec_domain *ed = current; struct trap_bounce *tb = &ed->arch.trap_bounce; - DEBUGGER_trap_entry(TRAP_debug, regs); - __asm__ __volatile__("mov %%db6,%0" : "=r" (condition)); /* Mask out spurious debug traps due to lazy DR7 setting */ @@ -962,6 +949,8 @@ asmlinkage int do_debug(struct xen_regs *regs) goto out; } + DEBUGGER_trap_entry(TRAP_debug, regs); + if ( !GUEST_MODE(regs) ) { /* Clear TF just for absolute sanity. */ @@ -974,19 +963,7 @@ asmlinkage int do_debug(struct xen_regs *regs) */ goto out; } -#ifdef DOMU_DEBUG - else if ( KERNEL_MODE(ed, regs) && ed->domain->id != 0 ) - { - regs->eflags &= ~EF_TF; - if ( !test_and_set_bit(EDF_CTRLPAUSE, &ed->ed_flags) ) { - while (ed == current) - __enter_scheduler(); - domain_pause_by_systemcontroller(ed->domain); - } - goto out; - } -#endif /* DOMU_DEBUG */ /* Save debug status register where guest OS can peek at it */ ed->arch.debugreg[6] = condition; diff --git a/xen/arch/x86/vmx.c b/xen/arch/x86/vmx.c index 047d4aa3ea..330776b7a4 100644 --- a/xen/arch/x86/vmx.c +++ b/xen/arch/x86/vmx.c @@ -22,6 +22,7 @@ #include <xen/lib.h> #include <xen/trace.h> #include <xen/sched.h> +#include <xen/softirq.h> #include <asm/current.h> #include <asm/io.h> #include <asm/irq.h> @@ -314,7 +315,7 @@ static void vmx_io_instruction(struct xen_regs *regs, vio = (vcpu_iodata_t *) d->arch.arch_vmx.vmx_platform.shared_page_va; if (vio == 0) { VMX_DBG_LOG(DBG_LEVEL_1, "bad shared page: %lx", (unsigned long) vio); - domain_crash(); + domain_crash_synchronous(); } p = &vio->vp_ioreq; p->dir = test_bit(3, &exit_qualification); @@ -340,7 +341,7 @@ static void vmx_io_instruction(struct xen_regs *regs, printk("stringio crosses page boundary!\n"); if (p->u.data & (p->size - 1)) { printk("Not aligned I/O!\n"); - domain_crash(); + domain_crash_synchronous(); } p->count = (PAGE_SIZE - (p->u.data & ~PAGE_MASK)) / p->size; } else { @@ -424,7 +425,7 @@ static void mov_to_cr(int gp, int cr, struct xen_regs *regs) { VMX_DBG_LOG(DBG_LEVEL_VMMU, "Invalid CR3 value = %lx", d->arch.arch_vmx.cpu_cr3); - domain_crash(); /* need to take a clean path */ + domain_crash_synchronous(); /* need to take a clean path */ } old_base_mfn = pagetable_val(d->arch.guest_table) >> PAGE_SHIFT; @@ -494,7 +495,7 @@ static void mov_to_cr(int gp, int cr, struct xen_regs *regs) { VMX_DBG_LOG(DBG_LEVEL_VMMU, "Invalid CR3 value=%lx", value); - domain_crash(); /* need to take a clean path */ + domain_crash_synchronous(); /* need to take a clean path */ } mfn = phys_to_machine_mapping(value >> PAGE_SHIFT); vmx_shadow_clear_state(d->domain); @@ -620,24 +621,24 @@ static inline void vmx_do_msr_read(struct xen_regs *regs) /* * Need to use this exit to rescheule */ -static inline void vmx_vmexit_do_hlt() +static inline void vmx_vmexit_do_hlt(void) { #if VMX_DEBUG unsigned long eip; __vmread(GUEST_EIP, &eip); #endif VMX_DBG_LOG(DBG_LEVEL_1, "vmx_vmexit_do_hlt:eip=%p", eip); - __enter_scheduler(); + raise_softirq(SCHEDULE_SOFTIRQ); } -static inline void vmx_vmexit_do_mwait() +static inline void vmx_vmexit_do_mwait(void) { #if VMX_DEBUG unsigned long eip; __vmread(GUEST_EIP, &eip); #endif VMX_DBG_LOG(DBG_LEVEL_1, "vmx_vmexit_do_mwait:eip=%p", eip); - __enter_scheduler(); + raise_softirq(SCHEDULE_SOFTIRQ); } #define BUF_SIZ 256 @@ -736,7 +737,7 @@ asmlinkage void vmx_vmexit_handler(struct xen_regs regs) VMX_DBG_LOG(DBG_LEVEL_0, "exit reason = %x", exit_reason); if (exit_reason & VMX_EXIT_REASONS_FAILED_VMENTRY) { - domain_crash(); + domain_crash_synchronous(); return; } diff --git a/xen/arch/x86/vmx_intercept.c b/xen/arch/x86/vmx_intercept.c index 0e30b85c42..11ee2bb2fb 100644 --- a/xen/arch/x86/vmx_intercept.c +++ b/xen/arch/x86/vmx_intercept.c @@ -56,7 +56,7 @@ int register_io_handler(unsigned long addr, unsigned long offset, intercept_acti if (num >= MAX_IO_HANDLER) { printk("no extra space, register io interceptor failed!\n"); - domain_crash(); + domain_crash_synchronous(); } handler->hdl_list[num].addr = addr; diff --git a/xen/arch/x86/vmx_io.c b/xen/arch/x86/vmx_io.c index 2152174a7f..4ee33cf3d6 100644 --- a/xen/arch/x86/vmx_io.c +++ b/xen/arch/x86/vmx_io.c @@ -195,7 +195,7 @@ void vmx_io_assist(struct exec_domain *ed) if (vio == 0) { VMX_DBG_LOG(DBG_LEVEL_1, "bad shared page: %lx", (unsigned long) vio); - domain_crash(); + domain_crash_synchronous(); } p = &vio->vp_ioreq; @@ -314,7 +314,7 @@ static inline int find_highest_pending_irq(struct exec_domain *d) if (vio == 0) { VMX_DBG_LOG(DBG_LEVEL_1, "bad shared page: %lx", (unsigned long) vio); - domain_crash(); + domain_crash_synchronous(); } return find_highest_irq(&vio->vp_intr[0]); @@ -328,7 +328,7 @@ static inline void clear_highest_bit(struct exec_domain *d, int vector) if (vio == 0) { VMX_DBG_LOG(DBG_LEVEL_1, "bad shared page: %lx", (unsigned long) vio); - domain_crash(); + domain_crash_synchronous(); } clear_bit(vector, &vio->vp_intr[0]); diff --git a/xen/arch/x86/vmx_platform.c b/xen/arch/x86/vmx_platform.c index ee84c716f0..a55c3a2fc1 100644 --- a/xen/arch/x86/vmx_platform.c +++ b/xen/arch/x86/vmx_platform.c @@ -436,7 +436,7 @@ static void send_mmio_req(unsigned long gpa, if (vio == NULL) { printk("bad shared page\n"); - domain_crash(); + domain_crash_synchronous(); } p = &vio->vp_ioreq; @@ -490,13 +490,13 @@ void handle_mmio(unsigned long va, unsigned long gpa) ret = inst_copy_from_guest(inst, eip, inst_len); if (ret != inst_len) { printk("handle_mmio - EXIT: get guest instruction fault\n"); - domain_crash(); + domain_crash_synchronous(); } init_instruction(&mmio_inst); if (vmx_decode(check_prefix(inst, &mmio_inst), &mmio_inst) == DECODE_failure) - domain_crash(); + domain_crash_synchronous(); __vmwrite(GUEST_EIP, eip + inst_len); store_xen_regs(inst_decoder_regs); @@ -510,7 +510,7 @@ void handle_mmio(unsigned long va, unsigned long gpa) return ; } else { printk("handle_mmio - EXIT: movz error!\n"); - domain_crash(); + domain_crash_synchronous(); } } @@ -539,14 +539,14 @@ void handle_mmio(unsigned long va, unsigned long gpa) index = operand_index(mmio_inst.operand[0]); value = get_reg_value(size, index, 0, inst_decoder_regs); } else { - domain_crash(); + domain_crash_synchronous(); } send_mmio_req(gpa, &mmio_inst, value, 0, 0); return; } - domain_crash(); } - domain_crash(); + + domain_crash_synchronous(); } #endif /* CONFIG_VMX */ diff --git a/xen/arch/x86/x86_32/entry.S b/xen/arch/x86/x86_32/entry.S index 4fb1221fb6..b1d9d5ecee 100644 --- a/xen/arch/x86/x86_32/entry.S +++ b/xen/arch/x86/x86_32/entry.S @@ -385,13 +385,17 @@ nvm86_3:/* Rewrite our stack frame and return to ring 1. */ movb $0,TRAPBOUNCE_flags(%edx) ret .section __ex_table,"a" - .long FLT6,domain_crash , FLT7,domain_crash , FLT8,domain_crash - .long FLT9,domain_crash , FLT10,domain_crash , FLT11,domain_crash - .long FLT12,domain_crash , FLT13,domain_crash , FLT14,domain_crash - .long FLT15,domain_crash , FLT16,domain_crash , FLT17,domain_crash - .long FLT18,domain_crash , FLT19,domain_crash , FLT20,domain_crash - .long FLT21,domain_crash , FLT22,domain_crash , FLT23,domain_crash - .long FLT24,domain_crash , FLT25,domain_crash , FLT26,domain_crash + .long FLT6,domain_crash_synchronous , FLT7,domain_crash_synchronous + .long FLT8,domain_crash_synchronous , FLT9,domain_crash_synchronous + .long FLT10,domain_crash_synchronous , FLT11,domain_crash_synchronous + .long FLT12,domain_crash_synchronous , FLT13,domain_crash_synchronous + .long FLT14,domain_crash_synchronous , FLT15,domain_crash_synchronous + .long FLT16,domain_crash_synchronous , FLT17,domain_crash_synchronous + .long FLT18,domain_crash_synchronous , FLT19,domain_crash_synchronous + .long FLT20,domain_crash_synchronous , FLT21,domain_crash_synchronous + .long FLT22,domain_crash_synchronous , FLT23,domain_crash_synchronous + .long FLT24,domain_crash_synchronous , FLT25,domain_crash_synchronous + .long FLT26,domain_crash_synchronous .previous ALIGN @@ -682,9 +686,9 @@ VFLT3: movl %gs:(%esi),%eax jmp test_all_events .section __ex_table,"a" - .long VFLT1,domain_crash - .long VFLT2,domain_crash - .long VFLT3,domain_crash + .long VFLT1,domain_crash_synchronous + .long VFLT2,domain_crash_synchronous + .long VFLT3,domain_crash_synchronous .previous .data diff --git a/xen/arch/x86/x86_64/entry.S b/xen/arch/x86/x86_64/entry.S index ddac4247b3..e3a522e76a 100644 --- a/xen/arch/x86/x86_64/entry.S +++ b/xen/arch/x86/x86_64/entry.S @@ -179,7 +179,7 @@ create_bounce_frame: jb 1f # In +ve address space? Then okay. movq $HYPERVISOR_VIRT_END+60,%rax cmpq %rax,%rsi - jb domain_crash # Above Xen private area? Then okay. + jb domain_crash_synchronous # Above Xen private area? Then okay. 1: subq $40,%rsi movq XREGS_ss+8(%rsp),%rax FLT2: movq %rax,32(%rsi) # SS @@ -230,11 +230,13 @@ FLT14: movq %rax,(%rsi) # RCX movb $0,TRAPBOUNCE_flags(%rdx) ret .section __ex_table,"a" - .quad FLT2,domain_crash , FLT3,domain_crash , FLT4,domain_crash - .quad FLT5,domain_crash , FLT6,domain_crash , FLT7,domain_crash - .quad FLT8,domain_crash , FLT9,domain_crash , FLT10,domain_crash - .quad FLT11,domain_crash , FLT12,domain_crash , FLT13,domain_crash - .quad FLT14,domain_crash + .quad FLT2,domain_crash_synchronous , FLT3,domain_crash_synchronous + .quad FLT4,domain_crash_synchronous , FLT5,domain_crash_synchronous + .quad FLT6,domain_crash_synchronous , FLT7,domain_crash_synchronous + .quad FLT8,domain_crash_synchronous , FLT9,domain_crash_synchronous + .quad FLT10,domain_crash_synchronous , FLT11,domain_crash_synchronous + .quad FLT12,domain_crash_synchronous , FLT13,domain_crash_synchronous + .quad FLT14,domain_crash_synchronous .previous ALIGN diff --git a/xen/common/domain.c b/xen/common/domain.c index 523b65430b..09748b93a6 100644 --- a/xen/common/domain.c +++ b/xen/common/domain.c @@ -161,12 +161,18 @@ void domain_crash(void) set_bit(DF_CRASHED, &d->d_flags); send_guest_virq(dom0->exec_domain[0], VIRQ_DOM_EXC); - - __enter_scheduler(); - BUG(); + + raise_softirq(SCHEDULE_SOFTIRQ); +} + + +void domain_crash_synchronous(void) +{ + domain_crash(); + for ( ; ; ) + do_softirq(); } -extern void trap_to_xendbg(void); void domain_shutdown(u8 reason) { @@ -191,18 +197,14 @@ void domain_shutdown(u8 reason) } } - if ( reason == SHUTDOWN_crash ) - { - domain_crash(); - BUG(); - } - - d->shutdown_code = reason; - set_bit(DF_SHUTDOWN, &d->d_flags); + if ( (d->shutdown_code = reason) == SHUTDOWN_crash ) + set_bit(DF_CRASHED, &d->d_flags); + else + set_bit(DF_SHUTDOWN, &d->d_flags); send_guest_virq(dom0->exec_domain[0], VIRQ_DOM_EXC); - __enter_scheduler(); + raise_softirq(SCHEDULE_SOFTIRQ); } unsigned int alloc_new_dom_mem(struct domain *d, unsigned int kbytes) diff --git a/xen/common/schedule.c b/xen/common/schedule.c index 761f636a75..9e3d2c9309 100644 --- a/xen/common/schedule.c +++ b/xen/common/schedule.c @@ -69,16 +69,13 @@ static void dom_timer_fn(unsigned long data); struct schedule_data schedule_data[NR_CPUS]; extern struct scheduler sched_bvt_def; -// extern struct scheduler sched_rrobin_def; -// extern struct scheduler sched_atropos_def; static struct scheduler *schedulers[] = { &sched_bvt_def, -// &sched_rrobin_def, -// &sched_atropos_def, NULL }; -/* Operations for the current scheduler. */ +static void __enter_scheduler(void); + static struct scheduler ops; #define SCHED_OP(fn, ...) \ @@ -366,7 +363,7 @@ long sched_adjdom(struct sched_adjdom_cmd *cmd) * - deschedule the current domain (scheduler independent). * - pick a new domain (scheduler dependent). */ -void __enter_scheduler(void) +static void __enter_scheduler(void) { struct exec_domain *prev = current, *next = NULL; int cpu = prev->processor; diff --git a/xen/drivers/char/console.c b/xen/drivers/char/console.c index 8813609df3..fa248efa2d 100644 --- a/xen/drivers/char/console.c +++ b/xen/drivers/char/console.c @@ -594,8 +594,6 @@ __initcall(debugtrace_init); * ************************************************************** */ -extern void trap_to_xendbg(void); - void panic(const char *fmt, ...) { va_list args; diff --git a/xen/include/asm-x86/debugger.h b/xen/include/asm-x86/debugger.h index d09a1264fc..fc65736e60 100644 --- a/xen/include/asm-x86/debugger.h +++ b/xen/include/asm-x86/debugger.h @@ -30,6 +30,7 @@ #ifndef __X86_DEBUGGER_H__ #define __X86_DEBUGGER_H__ +#include <xen/softirq.h> #include <asm/processor.h> /* The main trap handlers use these helper macros which include early bail. */ @@ -40,77 +41,38 @@ int call_with_registers(int (*f)(struct xen_regs *r)); -#ifdef XEN_DEBUGGER +#if defined(CRASH_DEBUG) -#include <asm/pdb.h> +extern int __trap_to_cdb(struct xen_regs *r); +#define debugger_trap_entry(_v, _r) (0) +#define debugger_trap_fatal(_v, _r) __trap_to_cdb(_r) +#define debugger_trap_immediate() call_with_registers(__trap_to_cdb) + +#elif defined(DOMU_DEBUG) static inline int debugger_trap_entry( unsigned int vector, struct xen_regs *regs) { - int ret = 0; + struct exec_domain *ed = current; + if ( !KERNEL_MODE(ed, regs) || (ed->domain->id == 0) ) + return 0; + switch ( vector ) { - case TRAP_debug: - if ( pdb_initialized ) - { - pdb_handle_debug_trap(regs, regs->error_code); - ret = 1; /* early exit */ - } - break; - case TRAP_int3: - if ( pdb_initialized && (pdb_handle_exception(vector, regs) == 0) ) - ret = 1; /* early exit */ - break; - - case TRAP_gp_fault: - if ( (VM86_MODE(regs) || !RING_0(regs)) && - ((regs->error_code & 3) == 2) && - pdb_initialized && (pdb_ctx.system_call != 0) ) - { - unsigned long cr3 = read_cr3(); - if ( cr3 == pdb_ctx.ptbr ) - pdb_linux_syscall_enter_bkpt( - regs, regs->error_code, - current->thread.traps + (regs->error_code>>3)); - } - break; - } - - return ret; -} - -static inline int debugger_trap_fatal( - unsigned int vector, struct xen_regs *regs) -{ - int ret = 0; - - switch ( vector ) - { - case TRAP_page_fault: - if ( pdb_page_fault_possible ) - { - pdb_page_fault = 1; - /* make eax & edx valid to complete the instruction */ - regs->eax = (long)&pdb_page_fault_scratch; - regs->edx = (long)&pdb_page_fault_scratch; - ret = 1; /* exit - do not crash! */ - } - break; + case TRAP_debug: + set_bit(EDF_CTRLPAUSE, &ed->ed_flags); + raise_softirq(SCHEDULE_SOFTIRQ); + return 1; } - return ret; + return 0; } -#define debugger_trap_immediate() () - -#elif defined(CRASH_DEBUG) +#define debugger_trap_fatal(_v, _r) (0) +#define debugger_trap_immediate() -extern int __trap_to_cdb(struct xen_regs *r); -#define debugger_trap_entry(_v, _r) (0) -#define debugger_trap_fatal(_v, _r) __trap_to_cdb(_r) -#define debugger_trap_immediate() call_with_registers(__trap_to_cdb) #elif 0 diff --git a/xen/include/asm-x86/vmx_vmcs.h b/xen/include/asm-x86/vmx_vmcs.h index 79262f5b43..c9ee1cba2d 100644 --- a/xen/include/asm-x86/vmx_vmcs.h +++ b/xen/include/asm-x86/vmx_vmcs.h @@ -207,7 +207,7 @@ extern unsigned int opt_vmx_debug_level; do { \ printk("__vmx_bug at %s:%d\n", __FILE__, __LINE__); \ show_registers(regs); \ - domain_crash(); \ + domain_crash_synchronous(); \ } while (0) #endif /* ASM_X86_VMX_VMCS_H__ */ diff --git a/xen/include/xen/sched.h b/xen/include/xen/sched.h index 861f1a24a0..de13d2d7fe 100644 --- a/xen/include/xen/sched.h +++ b/xen/include/xen/sched.h @@ -218,9 +218,20 @@ struct domain *find_domain_by_id(domid_t dom); struct domain *find_last_domain(void); extern void domain_destruct(struct domain *d); extern void domain_kill(struct domain *d); -extern void domain_crash(void); extern void domain_shutdown(u8 reason); +/* + * Mark current domain as crashed. This function returns: the domain is not + * synchronously descheduled from any processor. + */ +extern void domain_crash(void); + +/* + * Mark current domain as crashed and synchronously deschedule from the local + * processor. This function never returns. + */ +extern void domain_crash_synchronous(void) __attribute__((noreturn)); + void new_thread(struct exec_domain *d, unsigned long start_pc, unsigned long start_stack, @@ -241,8 +252,6 @@ void init_idle_task(void); void domain_wake(struct exec_domain *d); void domain_sleep(struct exec_domain *d); -void __enter_scheduler(void); - extern void context_switch( struct exec_domain *prev, struct exec_domain *next); |