aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--xen/arch/ia64/domain.c5
-rw-r--r--xen/arch/x86/domain.c3
-rw-r--r--xen/arch/x86/mm.c48
-rw-r--r--xen/arch/x86/shadow.c16
-rw-r--r--xen/arch/x86/traps.c29
-rw-r--r--xen/arch/x86/vmx.c19
-rw-r--r--xen/arch/x86/vmx_intercept.c2
-rw-r--r--xen/arch/x86/vmx_io.c6
-rw-r--r--xen/arch/x86/vmx_platform.c14
-rw-r--r--xen/arch/x86/x86_32/entry.S24
-rw-r--r--xen/arch/x86/x86_64/entry.S14
-rw-r--r--xen/common/domain.c28
-rw-r--r--xen/common/schedule.c9
-rw-r--r--xen/drivers/char/console.c2
-rw-r--r--xen/include/asm-x86/debugger.h76
-rw-r--r--xen/include/asm-x86/vmx_vmcs.h2
-rw-r--r--xen/include/xen/sched.h15
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);