mirror of
https://github.com/xen-project/xen.git
synced 2026-10-29 18:50:05 +01:00
bitkeeper revision 1.947 (40c84719Ozi8_o69nGYdNuJ6OQd4eQ)
Cleanup domain stop/crash. Provide notification to DOM0 so that cleanup/postmortem can occur before domain is killed.
This commit is contained in:
1 parent
03907beb68
commit
cce2235b0f
17 files changed
+190
-121
No files matched your search
@@ -15,7 +15,7 @@
|
||||
#include <hypervisor-ifs/network.h>
|
||||
#include <hypervisor-ifs/block.h>
|
||||
#include <hypervisor-ifs/hypervisor-if.h>
|
||||
|
||||
#include "../../../tools/xend/lib/domain_controller.h"
|
||||
|
||||
/*
|
||||
* a placeholder for the start of day information passed up from the hypervisor
|
||||
@@ -155,25 +155,39 @@ static __inline__ int HYPERVISOR_block(void)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static __inline__ int HYPERVISOR_exit(void)
|
||||
static inline int HYPERVISOR_shutdown(void)
|
||||
{
|
||||
int ret;
|
||||
__asm__ __volatile__ (
|
||||
TRAP_INSTR
|
||||
: "=a" (ret) : "0" (__HYPERVISOR_sched_op),
|
||||
"b" (SCHEDOP_exit) : "memory" );
|
||||
"b" (SCHEDOP_stop | (STOPCODE_shutdown << SCHEDOP_reasonshift))
|
||||
: "memory" );
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static __inline__ int HYPERVISOR_stop(unsigned long srec)
|
||||
static inline int HYPERVISOR_reboot(void)
|
||||
{
|
||||
int ret;
|
||||
__asm__ __volatile__ (
|
||||
TRAP_INSTR
|
||||
: "=a" (ret) : "0" (__HYPERVISOR_sched_op),
|
||||
"b" (SCHEDOP_stop | (STOPCODE_reboot << SCHEDOP_reasonshift))
|
||||
: "memory" );
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline int HYPERVISOR_suspend(unsigned long srec)
|
||||
{
|
||||
int ret;
|
||||
/* NB. On suspend, control software expects a suspend record in %esi. */
|
||||
__asm__ __volatile__ (
|
||||
TRAP_INSTR
|
||||
: "=a" (ret) : "0" (__HYPERVISOR_sched_op),
|
||||
"b" (SCHEDOP_stop), "S" (srec) : "memory" );
|
||||
"b" (SCHEDOP_stop | (STOPCODE_suspend << SCHEDOP_reasonshift)),
|
||||
"S" (srec) : "memory" );
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -153,7 +153,7 @@ void start_kernel(start_info_t *si)
|
||||
void do_exit(void)
|
||||
{
|
||||
printk("do_exit called!\n");
|
||||
for ( ;; ) HYPERVISOR_exit();
|
||||
for ( ;; ) HYPERVISOR_shutdown();
|
||||
}
|
||||
static void exit_handler(int ev, struct pt_regs *regs) {
|
||||
do_exit();
|
||||
|
||||
@@ -120,17 +120,23 @@ void machine_restart(char * __unused)
|
||||
/* We really want to get pending console data out before we die. */
|
||||
extern void xencons_force_flush(void);
|
||||
xencons_force_flush();
|
||||
HYPERVISOR_exit();
|
||||
HYPERVISOR_reboot();
|
||||
}
|
||||
|
||||
void machine_halt(void)
|
||||
{
|
||||
machine_restart(NULL);
|
||||
/* We really want to get pending console data out before we die. */
|
||||
extern void xencons_force_flush(void);
|
||||
xencons_force_flush();
|
||||
HYPERVISOR_shutdown();
|
||||
}
|
||||
|
||||
void machine_power_off(void)
|
||||
{
|
||||
machine_restart(NULL);
|
||||
/* We really want to get pending console data out before we die. */
|
||||
extern void xencons_force_flush(void);
|
||||
xencons_force_flush();
|
||||
HYPERVISOR_shutdown();
|
||||
}
|
||||
|
||||
extern void show_trace(unsigned long* esp);
|
||||
|
||||
@@ -1205,7 +1205,7 @@ static void stop_task(void *unused)
|
||||
|
||||
memcpy(&suspend_record->resume_info, &start_info, sizeof(start_info));
|
||||
|
||||
HYPERVISOR_stop(virt_to_machine(suspend_record) >> PAGE_SHIFT);
|
||||
HYPERVISOR_suspend(virt_to_machine(suspend_record) >> PAGE_SHIFT);
|
||||
|
||||
suspending = 0;
|
||||
|
||||
|
||||
@@ -253,25 +253,39 @@ static inline int HYPERVISOR_block(void)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline int HYPERVISOR_exit(void)
|
||||
static inline int HYPERVISOR_shutdown(void)
|
||||
{
|
||||
int ret;
|
||||
__asm__ __volatile__ (
|
||||
TRAP_INSTR
|
||||
: "=a" (ret) : "0" (__HYPERVISOR_sched_op),
|
||||
"b" (SCHEDOP_exit) : "memory" );
|
||||
"b" (SCHEDOP_stop | (STOPCODE_shutdown << SCHEDOP_reasonshift))
|
||||
: "memory" );
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline int HYPERVISOR_stop(unsigned long srec)
|
||||
static inline int HYPERVISOR_reboot(void)
|
||||
{
|
||||
int ret;
|
||||
__asm__ __volatile__ (
|
||||
TRAP_INSTR
|
||||
: "=a" (ret) : "0" (__HYPERVISOR_sched_op),
|
||||
"b" (SCHEDOP_stop | (STOPCODE_reboot << SCHEDOP_reasonshift))
|
||||
: "memory" );
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline int HYPERVISOR_suspend(unsigned long srec)
|
||||
{
|
||||
int ret;
|
||||
/* NB. On suspend, control software expects a suspend record in %esi. */
|
||||
__asm__ __volatile__ (
|
||||
TRAP_INSTR
|
||||
: "=a" (ret) : "0" (__HYPERVISOR_sched_op),
|
||||
"b" (SCHEDOP_stop), "S" (srec) : "memory" );
|
||||
"b" (SCHEDOP_stop | (STOPCODE_suspend << SCHEDOP_reasonshift)),
|
||||
"S" (srec) : "memory" );
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -91,9 +91,14 @@ int xc_domain_getinfo(int xc_handle,
|
||||
if ( do_dom0_op(xc_handle, &op) < 0 )
|
||||
break;
|
||||
info->domid = (u32)op.u.getdomaininfo.domain;
|
||||
info->cpu = op.u.getdomaininfo.processor;
|
||||
info->has_cpu = op.u.getdomaininfo.has_cpu;
|
||||
info->stopped = (op.u.getdomaininfo.state == DOMSTATE_STOPPED);
|
||||
|
||||
info->cpu =
|
||||
(op.u.getdomaininfo.flags>>DOMFLAGS_CPUSHIFT) & DOMFLAGS_CPUMASK;
|
||||
info->has_cpu =
|
||||
(op.u.getdomaininfo.flags&DOMFLAGS_STATEMASK) == DOMSTATE_RUNNING;
|
||||
info->stopped =
|
||||
(op.u.getdomaininfo.flags&DOMFLAGS_STATEMASK) == DOMSTATE_STOPPED;
|
||||
|
||||
info->nr_pages = op.u.getdomaininfo.tot_pages;
|
||||
info->max_memkb = op.u.getdomaininfo.max_pages<<(PAGE_SHIFT-10);
|
||||
info->shared_info_frame = op.u.getdomaininfo.shared_info_frame;
|
||||
|
||||
@@ -436,7 +436,7 @@ int xc_linux_build(int xc_handle,
|
||||
PERROR("Could not get info on domain");
|
||||
goto error_out;
|
||||
}
|
||||
if ( (op.u.getdomaininfo.state != DOMSTATE_STOPPED) ||
|
||||
if ( ((op.u.getdomaininfo.flags&DOMFLAGS_STATEMASK) != DOMSTATE_STOPPED) ||
|
||||
(ctxt->pt_base != 0) )
|
||||
{
|
||||
ERROR("Domain is already constructed");
|
||||
|
||||
@@ -258,7 +258,7 @@ int xc_netbsd_build(int xc_handle,
|
||||
PERROR("Could not get info on domain");
|
||||
goto error_out;
|
||||
}
|
||||
if ( (op.u.getdomaininfo.state != DOMSTATE_STOPPED) ||
|
||||
if ( ((op.u.getdomaininfo.flags&DOMFLAGS_STATEMASK) != DOMSTATE_STOPPED) ||
|
||||
(op.u.getdomaininfo.ctxt->pt_base != 0) )
|
||||
{
|
||||
ERROR("Domain is already constructed");
|
||||
|
||||
@@ -229,7 +229,8 @@ int xc_domain_stop_sync( int xc_handle, domid_t domid,
|
||||
goto out;
|
||||
}
|
||||
|
||||
if ( op->u.getdomaininfo.state == DOMSTATE_STOPPED )
|
||||
if ( (op->u.getdomaininfo.flags & DOMFLAGS_STATEMASK) ==
|
||||
DOMSTATE_STOPPED )
|
||||
{
|
||||
printf("Domain %u stopped\n",domid);
|
||||
return 0;
|
||||
|
||||
@@ -28,6 +28,16 @@ typedef struct {
|
||||
#define SIF_NET_BE_DOMAIN (1<<5) /* Is this a net backend domain? */
|
||||
|
||||
|
||||
/*
|
||||
* Stop codes for SCHEDOP_stop. These are opaque to Xen but interpreted by
|
||||
* control software to determine appropriate action.
|
||||
*/
|
||||
|
||||
#define STOPCODE_shutdown 0 /* Domain exited normally. Clean up and kill. */
|
||||
#define STOPCODE_reboot 1 /* Clean up, kill, and then restart. */
|
||||
#define STOPCODE_suspend 2 /* Clean up, save suspend info, kill. */
|
||||
|
||||
|
||||
/*
|
||||
* CONTROLLER MESSAGING INTERFACE.
|
||||
*/
|
||||
|
||||
+19
-19
@@ -446,34 +446,34 @@ FAULT12:movl %eax,8(%esi)
|
||||
|
||||
.section __ex_table,"a"
|
||||
.align 4
|
||||
.long FAULT1, kill_domain_fixup3 # Fault writing to ring-1 stack
|
||||
.long FAULT2, kill_domain_fixup3 # Fault writing to ring-1 stack
|
||||
.long FAULT3, kill_domain_fixup3 # Fault writing to ring-1 stack
|
||||
.long FAULT4, kill_domain_fixup3 # Fault writing to ring-1 stack
|
||||
.long FAULT5, kill_domain_fixup1 # Fault executing failsafe iret
|
||||
.long FAULT6, kill_domain_fixup2 # Fault loading ring-1 stack selector
|
||||
.long FAULT7, kill_domain_fixup2 # Fault writing to ring-1 stack
|
||||
.long FAULT8, kill_domain_fixup2 # Fault writing to ring-1 stack
|
||||
.long FAULT9, kill_domain_fixup2 # Fault loading ring-1 stack selector
|
||||
.long FAULT10,kill_domain_fixup2 # Fault writing to ring-1 stack
|
||||
.long FAULT11,kill_domain_fixup2 # Fault writing to ring-1 stack
|
||||
.long FAULT12,kill_domain_fixup2 # Fault writing to ring-1 stack
|
||||
.long FAULT13,kill_domain_fixup3 # Fault writing to ring-1 stack
|
||||
.long FAULT14,kill_domain_fixup3 # Fault writing to ring-1 stack
|
||||
.long FAULT1, crash_domain_fixup3 # Fault writing to ring-1 stack
|
||||
.long FAULT2, crash_domain_fixup3 # Fault writing to ring-1 stack
|
||||
.long FAULT3, crash_domain_fixup3 # Fault writing to ring-1 stack
|
||||
.long FAULT4, crash_domain_fixup3 # Fault writing to ring-1 stack
|
||||
.long FAULT5, crash_domain_fixup1 # Fault executing failsafe iret
|
||||
.long FAULT6, crash_domain_fixup2 # Fault loading ring-1 stack selector
|
||||
.long FAULT7, crash_domain_fixup2 # Fault writing to ring-1 stack
|
||||
.long FAULT8, crash_domain_fixup2 # Fault writing to ring-1 stack
|
||||
.long FAULT9, crash_domain_fixup2 # Fault loading ring-1 stack selector
|
||||
.long FAULT10,crash_domain_fixup2 # Fault writing to ring-1 stack
|
||||
.long FAULT11,crash_domain_fixup2 # Fault writing to ring-1 stack
|
||||
.long FAULT12,crash_domain_fixup2 # Fault writing to ring-1 stack
|
||||
.long FAULT13,crash_domain_fixup3 # Fault writing to ring-1 stack
|
||||
.long FAULT14,crash_domain_fixup3 # Fault writing to ring-1 stack
|
||||
.previous
|
||||
|
||||
# This handler kills domains which experience unrecoverable faults.
|
||||
.section .fixup,"ax"
|
||||
kill_domain_fixup1:
|
||||
crash_domain_fixup1:
|
||||
subl $4,%esp
|
||||
SAVE_ALL
|
||||
jmp kill_domain
|
||||
kill_domain_fixup2:
|
||||
jmp crash_domain
|
||||
crash_domain_fixup2:
|
||||
addl $4,%esp
|
||||
kill_domain_fixup3:
|
||||
crash_domain_fixup3:
|
||||
pushl %ss
|
||||
popl %ds
|
||||
jmp kill_domain
|
||||
jmp crash_domain
|
||||
.previous
|
||||
|
||||
ALIGN
|
||||
|
||||
+29
-20
@@ -282,11 +282,12 @@ long do_dom0_op(dom0_op_t *u_dom0_op)
|
||||
|
||||
case DOM0_GETDOMAININFO:
|
||||
{
|
||||
struct task_struct *p;
|
||||
u_long flags;
|
||||
int i;
|
||||
full_execution_context_t *c;
|
||||
struct task_struct *p;
|
||||
unsigned long flags;
|
||||
int i;
|
||||
|
||||
read_lock_irqsave (&tasklist_lock, flags);
|
||||
read_lock_irqsave(&tasklist_lock, flags);
|
||||
|
||||
for_each_domain ( p )
|
||||
{
|
||||
@@ -294,7 +295,7 @@ long do_dom0_op(dom0_op_t *u_dom0_op)
|
||||
break;
|
||||
}
|
||||
|
||||
if ( p == NULL )
|
||||
if ( (p == NULL) || (p->state == TASK_DYING) )
|
||||
{
|
||||
ret = -ESRCH;
|
||||
goto gdi_out;
|
||||
@@ -302,12 +303,23 @@ long do_dom0_op(dom0_op_t *u_dom0_op)
|
||||
else
|
||||
{
|
||||
op->u.getdomaininfo.domain = p->domain;
|
||||
strcpy (op->u.getdomaininfo.name, p->name);
|
||||
op->u.getdomaininfo.processor = p->processor;
|
||||
op->u.getdomaininfo.has_cpu = p->has_cpu;
|
||||
op->u.getdomaininfo.state = DOMSTATE_ACTIVE;
|
||||
if ( (p->state == TASK_STOPPED) || (p->state == TASK_DYING) )
|
||||
op->u.getdomaininfo.state = DOMSTATE_STOPPED;
|
||||
strcpy(op->u.getdomaininfo.name, p->name);
|
||||
|
||||
if ( p->state == TASK_RUNNING )
|
||||
op->u.getdomaininfo.flags =
|
||||
p->has_cpu ? DOMSTATE_RUNNING : DOMSTATE_RUNNABLE;
|
||||
else if ( (p->state == TASK_INTERRUPTIBLE) ||
|
||||
(p->state == TASK_UNINTERRUPTIBLE) )
|
||||
op->u.getdomaininfo.flags = DOMSTATE_BLOCKED;
|
||||
else if ( p->state == TASK_PAUSED )
|
||||
op->u.getdomaininfo.flags = DOMSTATE_PAUSED;
|
||||
else if ( p->state == TASK_CRASHED )
|
||||
op->u.getdomaininfo.flags = DOMSTATE_CRASHED;
|
||||
else
|
||||
op->u.getdomaininfo.flags = DOMSTATE_STOPPED;
|
||||
op->u.getdomaininfo.flags |= p->processor << DOMFLAGS_CPUSHIFT;
|
||||
op->u.getdomaininfo.flags |= p->stop_code << DOMFLAGS_GUESTSHIFT;
|
||||
|
||||
op->u.getdomaininfo.hyp_events = p->hyp_events;
|
||||
op->u.getdomaininfo.tot_pages = p->tot_pages;
|
||||
op->u.getdomaininfo.max_pages = p->max_pages;
|
||||
@@ -315,13 +327,12 @@ long do_dom0_op(dom0_op_t *u_dom0_op)
|
||||
op->u.getdomaininfo.shared_info_frame =
|
||||
__pa(p->shared_info) >> PAGE_SHIFT;
|
||||
|
||||
if ( p->state == TASK_STOPPED && op->u.getdomaininfo.ctxt )
|
||||
if ( (p->state == TASK_STOPPED) &&
|
||||
(op->u.getdomaininfo.ctxt != NULL) )
|
||||
{
|
||||
full_execution_context_t *c=NULL;
|
||||
|
||||
if ( (c = kmalloc(sizeof(*c), GFP_KERNEL)) == NULL )
|
||||
{
|
||||
ret= -ENOMEM;
|
||||
ret = -ENOMEM;
|
||||
goto gdi_out;
|
||||
}
|
||||
|
||||
@@ -373,12 +384,11 @@ long do_dom0_op(dom0_op_t *u_dom0_op)
|
||||
c->failsafe_callback_eip =
|
||||
p->failsafe_address;
|
||||
|
||||
if( copy_to_user(op->u.getdomaininfo.ctxt, c, sizeof(*c)) )
|
||||
{
|
||||
if ( copy_to_user(op->u.getdomaininfo.ctxt, c, sizeof(*c)) )
|
||||
ret = -EINVAL;
|
||||
}
|
||||
|
||||
if (c) kfree(c);
|
||||
if ( c != NULL )
|
||||
kfree(c);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -387,7 +397,6 @@ long do_dom0_op(dom0_op_t *u_dom0_op)
|
||||
|
||||
gdi_out:
|
||||
read_unlock_irqrestore(&tasklist_lock, flags);
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
+24
-16
@@ -170,13 +170,6 @@ struct task_struct *find_last_domain(void)
|
||||
}
|
||||
|
||||
|
||||
void kill_domain_with_errmsg(const char *err)
|
||||
{
|
||||
printk("DOM%u FATAL ERROR: %s\n", current->domain, err);
|
||||
kill_domain();
|
||||
}
|
||||
|
||||
|
||||
void __kill_domain(struct task_struct *p)
|
||||
{
|
||||
int i;
|
||||
@@ -245,7 +238,7 @@ long kill_other_domain(domid_t dom, int force)
|
||||
if ( (p = find_domain_by_id(dom)) == NULL )
|
||||
return -ESRCH;
|
||||
|
||||
if ( p->state == TASK_STOPPED )
|
||||
if ( (p->state == TASK_STOPPED) || (p->state == TASK_CRASHED) )
|
||||
__kill_domain(p);
|
||||
else if ( force )
|
||||
send_hyp_event(p, _HYP_EVENT_DIE);
|
||||
@@ -256,8 +249,27 @@ long kill_other_domain(domid_t dom, int force)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void stop_domain(void)
|
||||
|
||||
void crash_domain(void)
|
||||
{
|
||||
struct task_struct *p;
|
||||
|
||||
set_current_state(TASK_CRASHED);
|
||||
|
||||
p = find_domain_by_id(0);
|
||||
send_guest_virq(p, VIRQ_DOM_EXC);
|
||||
put_task_struct(p);
|
||||
|
||||
__enter_scheduler();
|
||||
BUG();
|
||||
}
|
||||
|
||||
|
||||
void stop_domain(u8 reason)
|
||||
{
|
||||
struct task_struct *p;
|
||||
|
||||
current->stop_code = reason;
|
||||
memcpy(¤t->shared_info->execution_context,
|
||||
get_execution_context(),
|
||||
sizeof(execution_context_t));
|
||||
@@ -265,13 +277,9 @@ void stop_domain(void)
|
||||
wmb(); /* All CPUs must see saved info in state TASK_STOPPED. */
|
||||
set_current_state(TASK_STOPPED);
|
||||
|
||||
/* OK, this is grim, but helps speed up live migrate. When a domain stops,
|
||||
kick Dom0 */
|
||||
{
|
||||
struct task_struct *p;
|
||||
guest_schedule_to_run( p = find_domain_by_id(0ULL) );
|
||||
put_task_struct(p);
|
||||
}
|
||||
p = find_domain_by_id(0);
|
||||
send_guest_virq(p, VIRQ_DOM_EXC);
|
||||
put_task_struct(p);
|
||||
|
||||
__enter_scheduler();
|
||||
}
|
||||
|
||||
+5
-15
@@ -244,7 +244,7 @@ long do_sched_op(unsigned long op)
|
||||
{
|
||||
long ret = 0;
|
||||
|
||||
switch( op )
|
||||
switch ( op & SCHEDOP_cmdmask )
|
||||
{
|
||||
|
||||
case SCHEDOP_yield:
|
||||
@@ -259,19 +259,9 @@ long do_sched_op(unsigned long op)
|
||||
break;
|
||||
}
|
||||
|
||||
case SCHEDOP_exit:
|
||||
{
|
||||
DPRINTK("DOM%u killed itself!\n", current->domain);
|
||||
DPRINTK(" EIP == %08lx\n", get_execution_context()->eip);
|
||||
kill_domain();
|
||||
break;
|
||||
}
|
||||
|
||||
case SCHEDOP_stop:
|
||||
{
|
||||
DPRINTK("DOM%u stopped itself!\n", current->domain);
|
||||
DPRINTK(" EIP == %08lx\n", get_execution_context()->eip);
|
||||
stop_domain();
|
||||
stop_domain((u8)(op >> SCHEDOP_reasonshift));
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -284,9 +274,9 @@ long do_sched_op(unsigned long op)
|
||||
|
||||
|
||||
/*
|
||||
* sched_pause_sync - synchronously pause a domain's execution
|
||||
* XXXX This is horibly broken -- here just as a place holder at present,
|
||||
* do not use.
|
||||
* sched_pause_sync - synchronously pause a domain's execution.
|
||||
* XXXX This is horribly broken -- here just as a place holder at present,
|
||||
* do not use.
|
||||
*/
|
||||
void sched_pause_sync(struct task_struct *p)
|
||||
{
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
* This makes sure that old versions of dom0 tools will stop working in a
|
||||
* well-defined way (rather than crashing the machine, for instance).
|
||||
*/
|
||||
#define DOM0_INTERFACE_VERSION 0xAAAA000E
|
||||
#define DOM0_INTERFACE_VERSION 0xAAAA000F
|
||||
|
||||
#define MAX_DOMAIN_NAME 16
|
||||
|
||||
@@ -84,24 +84,33 @@ typedef struct {
|
||||
#define DOM0_GETDOMAININFO 12
|
||||
typedef struct {
|
||||
/* IN variables. */
|
||||
domid_t domain; /* 0 */
|
||||
u32 __pad;
|
||||
full_execution_context_t *ctxt; /* 8 */
|
||||
MEMORY_PADDING;
|
||||
domid_t domain; /* 0 */ /* NB. IN/OUT variable. */
|
||||
/* OUT variables. */
|
||||
u8 name[MAX_DOMAIN_NAME]; /* 16 */
|
||||
u32 processor; /* 32 */
|
||||
u32 has_cpu; /* 36 */
|
||||
#define DOMSTATE_ACTIVE 0
|
||||
#define DOMSTATE_STOPPED 1
|
||||
u32 state; /* 40 */
|
||||
u32 hyp_events; /* 44 */
|
||||
u32 tot_pages; /* 48 */
|
||||
u32 max_pages; /* 52 */
|
||||
u64 cpu_time; /* 56 */
|
||||
memory_t shared_info_frame; /* 64: MFN of shared_info struct */
|
||||
#define DOMSTATE_CRASHED 0 /* Crashed domain; frozen for postmortem. */
|
||||
#define DOMSTATE_STOPPED 1 /* Domain voluntarily halted it execution. */
|
||||
#define DOMSTATE_PAUSED 2 /* Currently paused (forced non-schedulable). */
|
||||
#define DOMSTATE_BLOCKED 3 /* Currently blocked pending a wake-up event. */
|
||||
#define DOMSTATE_RUNNABLE 4 /* Currently runnable. */
|
||||
#define DOMSTATE_RUNNING 5 /* Currently running. */
|
||||
#define DOMFLAGS_STATEMASK 7 /* One of the DOMSTATE_??? values. */
|
||||
#define DOMFLAGS_STATESHIFT 0
|
||||
#define DOMFLAGS_CPUMASK 255 /* CPU to which this domain is bound. */
|
||||
#define DOMFLAGS_CPUSHIFT 3
|
||||
#define DOMFLAGS_GUESTMASK 255 /* DOMSTATE_STOPPED -> Guest-supplied code. */
|
||||
#define DOMFLAGS_GUESTSHIFT 11
|
||||
u32 flags; /* 4 */
|
||||
u8 name[MAX_DOMAIN_NAME]; /* 8 */
|
||||
full_execution_context_t *ctxt; /* 24 */ /* NB. IN/OUT variable. */
|
||||
MEMORY_PADDING;
|
||||
} PACKED dom0_getdomaininfo_t; /* 72 bytes */
|
||||
memory_t tot_pages; /* 32 */
|
||||
MEMORY_PADDING;
|
||||
memory_t max_pages; /* 40 */
|
||||
MEMORY_PADDING;
|
||||
memory_t shared_info_frame; /* 48: MFN of shared_info struct */
|
||||
MEMORY_PADDING;
|
||||
u64 cpu_time; /* 56 */
|
||||
u32 hyp_events; /* 64 */
|
||||
} PACKED dom0_getdomaininfo_t; /* 68 bytes */
|
||||
|
||||
#define DOM0_BUILDDOMAIN 13
|
||||
typedef struct {
|
||||
@@ -314,7 +323,7 @@ typedef struct {
|
||||
u32 cmd; /* 0 */
|
||||
u32 interface_version; /* 4 */ /* DOM0_INTERFACE_VERSION */
|
||||
union { /* 8 */
|
||||
u32 dummy[14]; /* 56 bytes */
|
||||
u32 dummy[18]; /* 72 bytes */
|
||||
dom0_createdomain_t createdomain;
|
||||
dom0_startdomain_t startdomain;
|
||||
dom0_stopdomain_t stopdomain;
|
||||
@@ -341,6 +350,6 @@ typedef struct {
|
||||
dom0_setdomainmaxmem_t setdomainmaxmem;
|
||||
dom0_getpageframeinfo2_t getpageframeinfo2;
|
||||
} PACKED u;
|
||||
} PACKED dom0_op_t; /* 64 bytes */
|
||||
} PACKED dom0_op_t; /* 80 bytes */
|
||||
|
||||
#endif /* __DOM0_OPS_H__ */
|
||||
@@ -59,19 +59,20 @@
|
||||
*
|
||||
* Virtual interrupts that a guest OS may receive from the hypervisor.
|
||||
*/
|
||||
#define VIRQ_BLKDEV 0 /* A block device response has been queued. */
|
||||
#define VIRQ_BLKDEV 0 /* (OBS) A block device response has been queued. */
|
||||
#define VIRQ_TIMER 1 /* A timeout has been updated. */
|
||||
#define VIRQ_DIE 2 /* OS is about to be killed. Clean up please! */
|
||||
#define VIRQ_DIE 2 /* (OBS) OS is about to be killed. Clean up! */
|
||||
#define VIRQ_DEBUG 3 /* Request guest to dump debug info (gross!) */
|
||||
#define VIRQ_NET 4 /* There are packets for transmission. */
|
||||
#define VIRQ_PS2 5 /* PS/2 keyboard or mouse event(s) */
|
||||
#define VIRQ_STOP 6 /* Prepare for stopping and possible pickling */
|
||||
#define VIRQ_NET 4 /* (OBS) There are packets for transmission. */
|
||||
#define VIRQ_PS2 5 /* (OBS) PS/2 keyboard or mouse event(s) */
|
||||
#define VIRQ_STOP 6 /* (OBS) Prepare for stopping and pickling */
|
||||
#define VIRQ_EVTCHN 7 /* Event pending on an event channel */
|
||||
#define VIRQ_VBD_UPD 8 /* Event to signal VBDs should be reprobed */
|
||||
#define VIRQ_CONSOLE 9 /* This is only for domain-0 initial console. */
|
||||
#define VIRQ_PHYSIRQ 10 /* Event to signal pending physical IRQs. */
|
||||
#define VIRQ_VBD_UPD 8 /* (OBS) Event to signal VBDs should be reprobed */
|
||||
#define VIRQ_CONSOLE 9 /* (DOM0) bytes received on master console. */
|
||||
#define VIRQ_PHYSIRQ 10 /* Pending physical IRQs. */
|
||||
#define VIRQ_MISDIRECT 11 /* Catch-all virtual interrupt. */
|
||||
#define NR_VIRQS 12
|
||||
#define VIRQ_DOM_EXC 12 /* (DOM0) Exceptional event for some domain. */
|
||||
#define NR_VIRQS 13
|
||||
|
||||
/*
|
||||
* MMU-UPDATE REQUESTS
|
||||
@@ -169,8 +170,9 @@
|
||||
*/
|
||||
#define SCHEDOP_yield 0 /* Give up the CPU voluntarily. */
|
||||
#define SCHEDOP_block 1 /* Block until an event is received. */
|
||||
#define SCHEDOP_exit 3 /* Exit and kill this domain. */
|
||||
#define SCHEDOP_stop 4 /* Stop executing this domain. */
|
||||
#define SCHEDOP_cmdmask 255 /* 8-bit command. */
|
||||
#define SCHEDOP_reasonshift 8 /* 8-bit stop code. (SCHEDOP_stop only) */
|
||||
|
||||
/*
|
||||
* Commands to HYPERVISOR_console_io().
|
||||
|
||||
@@ -123,6 +123,7 @@ struct task_struct
|
||||
struct list_head run_list;
|
||||
int has_cpu;
|
||||
int state; /* current run state */
|
||||
int stop_code; /* stop code from OS (if TASK_STOPPED). */
|
||||
int cpupinned; /* true if pinned to curent CPU */
|
||||
s_time_t lastschd; /* time this domain was last scheduled */
|
||||
s_time_t lastdeschd; /* time this domain was last descheduled */
|
||||
@@ -207,6 +208,7 @@ struct task_struct
|
||||
#define TASK_STOPPED 4
|
||||
#define TASK_DYING 8
|
||||
#define TASK_PAUSED 16
|
||||
#define TASK_CRASHED 32
|
||||
|
||||
#include <asm/uaccess.h> /* for KERNEL_DS */
|
||||
|
||||
@@ -255,9 +257,8 @@ struct task_struct *find_last_domain(void);
|
||||
extern void release_task(struct task_struct *);
|
||||
extern void __kill_domain(struct task_struct *p);
|
||||
extern void kill_domain(void);
|
||||
extern void kill_domain_with_errmsg(const char *err);
|
||||
extern long kill_other_domain(domid_t dom, int force);
|
||||
extern void stop_domain(void);
|
||||
extern void stop_domain(u8 reason);
|
||||
extern long stop_other_domain(domid_t dom);
|
||||
|
||||
/* arch/process.c */
|
||||
|
||||