mirror of
https://github.com/xen-project/xen.git
synced 2026-10-29 18:50:05 +01:00
bitkeeper revision 1.1236.43.9 (42441631VxhWONemyRXIOoB5s3kllQ)
Merge firebug.cl.cam.ac.uk:/auto/groups/xeno-xenod/BK/xen-unstable.bk into firebug.cl.cam.ac.uk:/local/scratch/kaf24/xen-unstable.bk
This commit is contained in:
commit
bf559936d8
17 files changed
+128
-202
No files matched your search
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
|
||||
+8
-40
@@ -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();
|
||||
}
|
||||
@@ -2400,6 +2400,7 @@ void ptwr_flush(const int which)
|
||||
*pl2e = mk_l2_pgentry(l2_pgentry_val(*pl2e) | _PAGE_PRESENT);
|
||||
}
|
||||
domain_crash();
|
||||
return;
|
||||
}
|
||||
|
||||
if ( unlikely(sl1e != NULL) )
|
||||
@@ -2693,6 +2694,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;
|
||||
@@ -2730,40 +2732,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;
|
||||
|
||||
+10
-6
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
+3
-26
@@ -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;
|
||||
|
||||
|
||||
+10
-9
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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]);
|
||||
|
||||
@@ -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 */
|
||||
|
||||
+14
-10
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
+15
-13
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -594,8 +594,6 @@ __initcall(debugtrace_init);
|
||||
* **************************************************************
|
||||
*/
|
||||
|
||||
extern void trap_to_xendbg(void);
|
||||
|
||||
void panic(const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
|
||||
@@ -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,78 +41,39 @@
|
||||
|
||||
int call_with_registers(int (*f)(struct xen_regs *r));
|
||||
|
||||
#ifdef XEN_DEBUGGER
|
||||
|
||||
#include <asm/pdb.h>
|
||||
|
||||
static inline int debugger_trap_entry(
|
||||
unsigned int vector, struct xen_regs *regs)
|
||||
{
|
||||
int ret = 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;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#define debugger_trap_immediate() ()
|
||||
|
||||
#elif defined(CRASH_DEBUG)
|
||||
#if defined(CRASH_DEBUG)
|
||||
|
||||
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)
|
||||
{
|
||||
struct exec_domain *ed = current;
|
||||
|
||||
if ( !KERNEL_MODE(ed, regs) || (ed->domain->id == 0) )
|
||||
return 0;
|
||||
|
||||
switch ( vector )
|
||||
{
|
||||
case TRAP_int3:
|
||||
case TRAP_debug:
|
||||
set_bit(EDF_CTRLPAUSE, &ed->ed_flags);
|
||||
raise_softirq(SCHEDULE_SOFTIRQ);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define debugger_trap_fatal(_v, _r) (0)
|
||||
#define debugger_trap_immediate()
|
||||
|
||||
|
||||
#elif 0
|
||||
|
||||
extern int kdb_trap(int, int, struct xen_regs *);
|
||||
|
||||
@@ -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__ */
|
||||
|
||||
+12
-3
@@ -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);
|
||||
|
||||