aboutsummaryrefslogtreecommitdiffstats
path: root/xen
diff options
context:
space:
mode:
Diffstat (limited to 'xen')
-rw-r--r--xen/common/dom0_ops.c57
-rw-r--r--xen/common/domain.c23
-rw-r--r--xen/common/schedule.c1
-rw-r--r--xen/include/xeno/dom0_ops.h34
-rw-r--r--xen/include/xeno/sched.h7
5 files changed, 112 insertions, 10 deletions
diff --git a/xen/common/dom0_ops.c b/xen/common/dom0_ops.c
index 3ac6e72c0f..fb8d44429e 100644
--- a/xen/common/dom0_ops.c
+++ b/xen/common/dom0_ops.c
@@ -62,11 +62,19 @@ long do_dom0_op(dom0_op_t *u_dom0_op)
switch ( op.cmd )
{
- case DOM0_STARTDOM:
+ case DOM0_BUILDDOMAIN:
{
struct task_struct * p = find_domain_by_id(op.u.meminfo.domain);
if ( (ret = final_setup_guestos(p, &op.u.meminfo)) != 0 )
break;
+ ret = p->domain;
+ free_task_struct(p);
+ }
+ break;
+
+ case DOM0_STARTDOMAIN:
+ {
+ struct task_struct * p = find_domain_by_id(op.u.meminfo.domain);
wake_up(p);
reschedule(p);
ret = p->domain;
@@ -74,7 +82,13 @@ long do_dom0_op(dom0_op_t *u_dom0_op)
}
break;
- case DOM0_NEWDOMAIN:
+ case DOM0_STOPDOMAIN:
+ {
+ ret = stop_other_domain (op.u.meminfo.domain);
+ }
+ break;
+
+ case DOM0_CREATEDOMAIN:
{
struct task_struct *p;
static unsigned int pro = 0;
@@ -89,6 +103,11 @@ long do_dom0_op(dom0_op_t *u_dom0_op)
if ( p == NULL )
break;
+ if (op.u.newdomain.name[0]) {
+ strncpy (p -> name, op.u.newdomain.name, MAX_DOMAIN_NAME);
+ p -> name[MAX_DOMAIN_NAME - 1] = 0;
+ }
+
ret = alloc_new_dom_mem(p, op.u.newdomain.memory_kb);
if ( ret != 0 )
{
@@ -108,7 +127,7 @@ long do_dom0_op(dom0_op_t *u_dom0_op)
}
break;
- case DOM0_KILLDOMAIN:
+ case DOM0_DESTROYDOMAIN:
{
unsigned int dom = op.u.killdomain.domain;
int force = op.u.killdomain.force;
@@ -168,6 +187,38 @@ long do_dom0_op(dom0_op_t *u_dom0_op)
}
break;
+ case DOM0_GETDOMAININFO:
+ {
+ struct task_struct *p;
+ u_long flags;
+
+ p = idle0_task.next_task;
+ read_lock_irqsave (&tasklist_lock, flags);
+ do {
+ if ((!is_idle_task (p)) && (p -> domain >= op.u.getdominfo.domain)) {
+ break;
+ }
+ } while ((p = p -> next_task) != &idle0_task);
+
+ if (p == &idle0_task) {
+ ret = -ESRCH;
+ } else {
+ op.u.getdominfo.domain = p -> domain;
+ strcpy (op.u.getdominfo.name, p -> name);
+ op.u.getdominfo.processor = p -> processor;
+ op.u.getdominfo.has_cpu = p -> has_cpu;
+ op.u.getdominfo.state = p -> state;
+ op.u.getdominfo.hyp_events = p -> hyp_events;
+ op.u.getdominfo.mcu_advance = p -> mcu_advance;
+ op.u.getdominfo.pg_head = list_entry(p->pg_head.next,
+ struct pfn_info, list) - frame_table;
+ op.u.getdominfo.tot_pages = p -> tot_pages;
+ }
+ read_unlock_irqrestore (&tasklist_lock, flags);
+ copy_to_user(u_dom0_op, &op, sizeof(op));
+ break;
+ }
+
default:
ret = -ENOSYS;
diff --git a/xen/common/domain.c b/xen/common/domain.c
index f54e7c9d67..35154baf37 100644
--- a/xen/common/domain.c
+++ b/xen/common/domain.c
@@ -175,6 +175,29 @@ long kill_other_domain(unsigned int dom, int force)
return 0;
}
+void stop_domain(void)
+{
+ current -> state = TASK_SUSPENDED;
+ clear_bit(_HYP_EVENT_STOP, &(current->hyp_events));
+ schedule ();
+}
+
+long stop_other_domain(unsigned int dom)
+{
+ unsigned long cpu_mask;
+ struct task_struct *p;
+
+ p = find_domain_by_id (dom);
+ if ( p == NULL) return -ESRCH;
+
+ if ( p -> state != TASK_SUSPENDED )
+ {
+ cpu_mask = mark_hyp_event(p, _HYP_EVENT_STOP);
+ hyp_event_notify(cpu_mask);
+ }
+
+ return 0;
+}
unsigned int alloc_new_dom_mem(struct task_struct *p, unsigned int kbytes)
{
diff --git a/xen/common/schedule.c b/xen/common/schedule.c
index 5749d27d4a..6536bf1ba5 100644
--- a/xen/common/schedule.c
+++ b/xen/common/schedule.c
@@ -349,6 +349,7 @@ asmlinkage void schedule(void)
case TASK_UNINTERRUPTIBLE:
case TASK_WAIT:
case TASK_DYING:
+ case TASK_SUSPENDED:
default:
/* done if not running. Else, continue */
goto deschedule_done;
diff --git a/xen/include/xeno/dom0_ops.h b/xen/include/xeno/dom0_ops.h
index ea3f829d73..8737e192aa 100644
--- a/xen/include/xeno/dom0_ops.h
+++ b/xen/include/xeno/dom0_ops.h
@@ -12,14 +12,18 @@
#ifndef __DOM0_OPS_H__
#define __DOM0_OPS_H__
-#define DOM0_NEWDOMAIN 0
-#define DOM0_KILLDOMAIN 1
-#define DOM0_GETMEMLIST 2
-#define DOM0_STARTDOM 4
-#define DOM0_BVTCTL 6
-#define DOM0_ADJUSTDOM 7
+#define DOM0_GETMEMLIST 2
+#define DOM0_BVTCTL 6
+#define DOM0_ADJUSTDOM 7
+#define DOM0_CREATEDOMAIN 8
+#define DOM0_DESTROYDOMAIN 9
+#define DOM0_STARTDOMAIN 10
+#define DOM0_STOPDOMAIN 11
+#define DOM0_GETDOMAININFO 12
+#define DOM0_BUILDDOMAIN 13
#define MAX_CMD_LEN 256
+#define MAX_DOMAIN_NAME 16
typedef struct dom0_newdomain_st
{
@@ -27,6 +31,7 @@ typedef struct dom0_newdomain_st
unsigned int memory_kb;
unsigned int num_vifs; // temporary
unsigned long pg_head; // return parameter
+ char name[MAX_DOMAIN_NAME];
} dom0_newdomain_t;
typedef struct dom0_killdomain_st
@@ -69,6 +74,20 @@ typedef struct dom0_adjustdom_st
unsigned long warpu; /* unwarp time requirement */
} dom0_adjustdom_t;
+typedef struct dom0_getdominfo_st
+{
+ unsigned int domain; /* All returns except domain */
+ char name[MAX_DOMAIN_NAME];
+ int processor;
+ int has_cpu;
+ int state;
+ int hyp_events;
+ unsigned long mcu_advance;
+ unsigned long pg_head;
+ unsigned int tot_pages;
+} dom0_getdominfo_t;
+
+
typedef struct dom0_op_st
{
unsigned long cmd;
@@ -80,7 +99,8 @@ typedef struct dom0_op_st
dom0_bvtctl_t bvtctl;
dom0_adjustdom_t adjustdom;
dom_meminfo_t meminfo;
- }
+ dom0_getdominfo_t getdominfo;
+ }
u;
} dom0_op_t;
diff --git a/xen/include/xeno/sched.h b/xen/include/xeno/sched.h
index d29c7f9e49..fe4c49736e 100644
--- a/xen/include/xeno/sched.h
+++ b/xen/include/xeno/sched.h
@@ -16,6 +16,8 @@
#include <xeno/time.h>
#include <xeno/ac_timer.h>
+#define MAX_DOMAIN_NAME 16
+
extern unsigned long volatile jiffies;
extern rwlock_t tasklist_lock;
@@ -51,6 +53,7 @@ extern struct mm_struct init_mm;
#define _HYP_EVENT_NEED_RESCHED 0
#define _HYP_EVENT_DIE 1
+#define _HYP_EVENT_STOP 2
#define PF_DONEFPUINIT 0x1 /* Has the FPU been initialised for this task? */
#define PF_USEDFPU 0x2 /* Has this task used the FPU since last save? */
@@ -141,6 +144,8 @@ struct task_struct
0-0xFFFFFFFF for kernel-thread
*/
+ char name[MAX_DOMAIN_NAME];
+
/*
* active_mm stays for now. It's entangled in the tricky TLB flushing
* stuff which I haven't addressed yet. It stays until I'm man enough
@@ -223,6 +228,8 @@ 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(unsigned int dom, int force);
+extern void stop_domain(void);
+extern long stop_other_domain(unsigned int dom);
/* arch/process.c */
void new_thread(struct task_struct *p,