diff
-rupN a/tools/libxc/Makefile b/tools/libxc/Makefile
---
a/tools/libxc/Makefile 2010-04-13
10:49:37.573793000 -0400
+++
b/tools/libxc/Makefile 2010-04-14
17:49:26.952638000 -0400
@@
-17,6 +17,7 @@ CTRL_SRCS-y +=
xc_physdev.c
CTRL_SRCS-y
+= xc_private.c
CTRL_SRCS-y
+= xc_sedf.c
CTRL_SRCS-y
+= xc_csched.c
+CTRL_SRCS-y
+= xc_arinc653.c
CTRL_SRCS-y
+= xc_tbuf.c
CTRL_SRCS-y
+= xc_pm.c
CTRL_SRCS-y
+= xc_cpu_hotplug.c
diff
-rupN a/tools/libxc/xc_arinc653.c b/tools/libxc/xc_arinc653.c
---
a/tools/libxc/xc_arinc653.c 1969-12-31 19:00:00.000000000
-0500
+++
b/tools/libxc/xc_arinc653.c 2010-04-14 17:49:26.952638000 -0400
@@ -0,0
+1,28 @@
+/****************************************************************************
+ * (C)
2010 - DornerWorks, Ltd <DornerWorks.com>
+
****************************************************************************
+ *
+
* File: xc_arinc653.c
+
* Author: Josh Holtrop <DornerWorks.com>
+ *
+ *
Description: XC Interface to the ARINC 653 scheduler
+ *
+ */
+
+#include
"xc_private.h"
+
+int
+xc_sched_arinc653_sched_set(
+
int xc_handle,
+
xen_domctl_sched_arinc653_schedule_t * sched)
+{
+
DECLARE_DOMCTL;
+
+
domctl.cmd = XEN_DOMCTL_scheduler_op;
+
domctl.domain = (domid_t) 0;
+
domctl.u.scheduler_op.sched_id = XEN_SCHEDULER_ARINC653;
+
domctl.u.scheduler_op.cmd = XEN_DOMCTL_SCHEDOP_put_global_info;
+
set_xen_guest_handle(domctl.u.scheduler_op.u.arinc653.schedule, sched);
+
+
return do_domctl(xc_handle, &domctl);
+}
diff
-rupN a/tools/libxc/xenctrl.h b/tools/libxc/xenctrl.h
---
a/tools/libxc/xenctrl.h 2010-04-13
10:49:37.573793000 -0400
+++
b/tools/libxc/xenctrl.h 2010-04-14
17:49:26.952638000 -0400
@@
-476,6 +476,16 @@ int xc_sched_credit_domain_get(int xc_ha
struct xen_domctl_sched_credit *sdom);
/**
+ *
This function sets the global ARINC 653 schedule.
+ *
+ *
@parm xc_handle a handle to an open hypervisor interface
+ *
@parm sched a pointer to the new ARINC 653 schedule
+ *
return 0 on success
+ */
+int
xc_sched_arinc653_sched_set(int xc_handle,
+
xen_domctl_sched_arinc653_schedule_t * sched);
+
+/**
* This function sends a trigger to a domain.
*
* @parm xc_handle a handle to an open hypervisor interface
diff
-rupN a/xen/common/Makefile b/xen/common/Makefile
---
a/xen/common/Makefile 2010-04-13
10:49:37.573793000 -0400
+++
b/xen/common/Makefile 2010-04-13 13:00:31.651749000
-0400
@@
-14,6 +14,7 @@ obj-y += page_alloc.o
obj-y
+= rangeset.o
obj-y
+= sched_credit.o
obj-y
+= sched_sedf.o
+obj-y
+= sched_arinc653.o
obj-y
+= schedule.o
obj-y
+= shutdown.o
obj-y
+= softirq.o
diff
-rupN a/xen/common/sched_arinc653.c b/xen/common/sched_arinc653.c
---
a/xen/common/sched_arinc653.c 1969-12-31
19:00:00.000000000 -0500
+++
b/xen/common/sched_arinc653.c 2010-04-14 18:13:26.163404000
-0400
@@ -0,0
+1,590 @@
+/*
+ *
File: sched_arinc653.c
+ *
Copyright (c) 2010, DornerWorks, Ltd. <DornerWorks.com>
+ *
+ *
Description:
+
* This file provides an ARINC653-compatible scheduling algorithm
+
* for use in Xen.
+ *
+ *
This program is free software; you can redistribute it and/or modify it
+ *
under the terms of the GNU General Public License as published by the Free
+ *
software Foundation; either version 2 of the License, or (at your option)
+ * any
later version.
+ *
+ *
This program is distributed in the hope that it will be useful,
+ * but
WITHOUT ANY WARRANTY; without even the implied warranty of
+ *
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See
the GNU General Public License for more details.
+ */
+
+
+/**************************************************************************
+ *
Includes
*
+
*************************************************************************/
+#include
<xen/lib.h>
+#include
<xen/sched.h>
+#include
<xen/sched-if.h>
+#include
<xen/timer.h>
+#include
<xen/softirq.h>
+#include
<xen/time.h>
+#include
<xen/errno.h>
+#include
<xen/list.h>
+#include
<public/domctl.h>
/* ARINC653_MAX_DOMAINS_PER_SCHEDULE */
+#include
<xen/guest_access.h>
+
+
+/**************************************************************************
+ *
Private
Macros
*
+
**************************************************************************/
+
+/**
+ *
Retrieve the idle VCPU for a given physical CPU
+ */
+#define
IDLETASK(cpu) ((struct vcpu *) per_cpu(schedule_data, (cpu)).idle)
+
+/**
+ *
Return a pointer to the ARINC 653-specific scheduler data information
+ *
associated with the given VCPU (vc)
+ */
+#define
AVCPU(vc) ((arinc653_vcpu_t *)(vc)->sched_priv)
+
+/**************************************************************************
+ *
Private Type
Definitions
*
+
**************************************************************************/
+
+/**
+ * The
sched_entry_t structure holds a single entry of the
+ *
ARINC 653 schedule.
+ */
+typedef
struct sched_entry_s
+{
+
/* dom_handle holds the handle ("UUID") for the domain that this
+
* schedule entry refers to. */
+
xen_domain_handle_t dom_handle;
+
/* vcpu_id holds the VCPU number for the VCPU that this schedule
+
* entry refers to. */
+
int
vcpu_id;
+
/* runtime holds the number of nanoseconds that the VCPU for this
+
* schedule entry should be allowed to run per major frame. */
+
s_time_t
runtime;
+
/* vc holds a pointer to the Xen VCPU structure */
+
struct vcpu * vc;
+}
sched_entry_t;
+
+/**
+ * The
arinc653_vcpu_t structure holds ARINC 653-scheduler-specific
+ *
information for all non-idle VCPUs
+ */
+typedef
struct arinc653_vcpu_s
+{
+
/* vc points to Xen's struct vcpu so we can get to it from an
+
* arinc653_vcpu_t pointer. */
+
struct vcpu * vc;
+
/* awake holds whether the VCPU has been woken with vcpu_wake() */
+
bool_t
awake;
+
/* list holds the linked list information for the list this VCPU
+
* is stored in */
+
struct list_head list;
+}
arinc653_vcpu_t;
+
+
+/**************************************************************************
+ *
Global
Data
*
+
**************************************************************************/
+
+/**
+ *
This array holds the active ARINC 653 schedule.
+ *
+ *
When the system tries to start a new VCPU, this schedule is scanned
+ * to
look for a matching (handle, VCPU #) pair. If both the handle
("UUID")
+ * and
VCPU number match, then the VCPU is allowed to run. Its run time
+ *
(per major frame) is given in the third entry of the schedule.
+ */
+static
sched_entry_t arinc653_schedule[ARINC653_MAX_DOMAINS_PER_SCHEDULE] = {
+
{ "", 0, MILLISECS(10), NULL }
+};
+
+/**
+ *
This variable holds the number of entries that are valid in
+ * the
arinc653_schedule table.
+ *
+ *
This is not necessarily the same as the number of domains in the
+ *
schedule. A domain could be listed multiple times within the schedule,
+ * or
a domain with multiple VCPUs could have a different
+ *
schedule entry for each VCPU.
+ *
+ * A
value of 1 means that only 1 domain (Dom0) will initially be started.
+ */
+static
int num_schedule_entries = 1;
+
+/**
+ *
arinc653_major_frame holds the major frame time for the ARINC 653 schedule.
+ */
+static
s_time_t arinc653_major_frame = MILLISECS(10);
+
+/**
+ *
next_major_frame holds the time that the next major frame starts
+ */
+static
s_time_t next_major_frame = 0;
+
+/**
+ *
vcpu_list holds pointers to all Xen VCPU structures for iterating through
+ */
+static
LIST_HEAD(vcpu_list);
+
+/**************************************************************************
+ *
Scheduler
functions
*
+
**************************************************************************/
+
+/**
+ *
This function compares two domain handles.
+ *
+ *
@param h1 Pointer to handle 1
+ *
@param h2 Pointer to handle 2
+ *
+ *
@return <ul>
+
*
<li> <0: handle 1 is less than handle 2
+
*
<li> 0: handle 1 is equal to handle 2
+
*
<li> >0: handle 1 is greater than handle 2
+
*
</ul>
+ */
+static
int dom_handle_cmp(const xen_domain_handle_t h1,
+
const xen_domain_handle_t h2)
+{
+
return memcmp(h1, h2, sizeof(xen_domain_handle_t));
+} /*
end dom_handle_cmp */
+
+/**
+ *
This function searches the vcpu list to find a VCPU that matches
+ * the
domain handle and VCPU ID specified.
+ *
+ *
@param handle Pointer to handler
+ *
@param vcpu_id VCPU ID
+ *
+ *
@return <ul>
+
*
<li> Pointer to the matching VCPU if one is found
+
*
<li> NULL otherwise
+
*
</ul>
+ */
+static
struct vcpu * find_vcpu(xen_domain_handle_t handle, int vcpu_id)
+{
+
arinc653_vcpu_t * avcpu; /* loop index variable */
+
struct vcpu * vc = NULL;
+
+
/* loop through the vcpu_list looking for the specified VCPU */
+
list_for_each_entry(avcpu, &vcpu_list, list)
+
{
+
/* If the handles & VCPU IDs match, we've found a matching VCPU */
+
if ((dom_handle_cmp(avcpu->vc->domain->handle, handle) == 0)
+
&& (vcpu_id == avcpu->vc->vcpu_id))
+
{
+
vc = avcpu->vc;
+
/*
+
* "break" statement used instead of loop control variable because
+
* the macro used for this loop does not support using loop control
+
* variables
+
*/
+
break;
+
}
+
}
+
+
return vc;
+} /*
end find_vcpu */
+
+/**
+ *
This function updates the pointer to the Xen VCPU structure for each entry in
+ * the
ARINC 653 schedule.
+ *
+ *
@param
<None>
+ *
@return <None>
+ */
+static
void update_schedule_vcpus(void)
+{
+
/* Loop through the number of entries in the schedule */
+
for (int i = 0; i < num_schedule_entries; i++)
+
{
+
/* Update the pointer to the Xen VCPU structure for the current entry */
+
arinc653_schedule[i].vc =
+
find_vcpu(arinc653_schedule[i].dom_handle,
+
arinc653_schedule[i].vcpu_id);
+
}
+} /*
end update_schedule_vcpus */
+
+/**
+ *
This function is called by the arinc653_adjust_global scheduler
+ *
callback function in response to a domain control hypercall with
+ * a
scheduler operation.
+ *
+ * The
parameter schedule is set to be the address of a local variable from
+ *
within arinc653_adjust_global(), so it is guaranteed to not be NULL.
+ *
+ *
@param schedule Pointer to the new ARINC 653 schedule.
+ *
+ *
@return <ul>
+
* <li>
0 = success
+
*
<li> !0 = error
+
*
</ul>
+ */
+static
int arinc653_sched_set(xen_domctl_sched_arinc653_schedule_t * schedule)
+{
+
int ret = 0;
+
s_time_t total_runtime = 0;
+
bool_t found_dom0 = 0;
+
const static xen_domain_handle_t dom0_handle = {0};
+
+
/* check for valid major frame and number of schedule entries */
+
if ( (schedule->major_frame <= 0)
+
|| (schedule->num_sched_entries < 1)
+
|| (schedule->num_sched_entries > ARINC653_MAX_DOMAINS_PER_SCHEDULE) )
+
{
+
ret = -EINVAL;
+
}
+
+
if (ret == 0)
+
{
+
for (int i = 0; i < schedule->num_sched_entries; i++)
+
{
+
/*
+
* look for domain 0 handle - every schedule must contain
+
* some time for domain 0 to run
+
*/
+
if (dom_handle_cmp(schedule->sched_entries[i].dom_handle,
+
dom0_handle) == 0)
+
{
+
found_dom0 = 1;
+
}
+
+
/* check for a valid VCPU ID and run time */
+
if ( (schedule->sched_entries[i].vcpu_id < 0)
+
|| (schedule->sched_entries[i].runtime <= 0) )
+
{
+
ret = -EINVAL;
+
}
+
else
+
{
+
/* Add this entry's run time to total run time */
+
total_runtime += schedule->sched_entries[i].runtime;
+
}
+
} /* end loop through schedule entries */
+
}
+
+
if (ret == 0)
+
{
+
/* error if the schedule doesn't contain a slot for domain 0 */
+
if (found_dom0 == 0)
+
{
+
ret = -EINVAL;
+
}
+
}
+
+
if (ret == 0)
+
{
+
/*
+
* error if the major frame is not large enough to run all entries
+
* as indicated by comparing the total run time to the major frame
+
* length
+
*/
+
if (total_runtime > schedule->major_frame)
+
{
+
ret = -EINVAL;
+
}
+
}
+
+
if (ret == 0)
+
{
+
/* copy the new schedule into place */
+
num_schedule_entries = schedule->num_sched_entries;
+
arinc653_major_frame = schedule->major_frame;
+
for (int i = 0; i < num_schedule_entries; i++)
+
{
+
memcpy(arinc653_schedule[i].dom_handle,
+
schedule->sched_entries[i].dom_handle,
+
sizeof(arinc653_schedule[i].dom_handle));
+
arinc653_schedule[i].vcpu_id = schedule->sched_entries[i].vcpu_id;
+
arinc653_schedule[i].runtime = schedule->sched_entries[i].runtime;
+
}
+
update_schedule_vcpus();
+
+
/*
+
* The newly-installed schedule takes effect immediately.
+
* We do not even wait for the current major frame to expire.
+
*
+
* Signal a new major frame to begin. The next major frame
+
* is set up by the do_schedule callback function when it
+
* is next invoked.
+
*/
+
next_major_frame = NOW();
+
}
+
+
return ret;
+} /*
end arinc653_sched_set */
+
+/**
+ * Xen
scheduler callback function to adjust global scheduling parameters
+ *
+ *
@param op Pointer to the domain control scheduler operation
structure
+ *
+ *
@return <ul>
+
*
<li> 0 for success
+
*
<li> !0 if there is an error
+
*
</ul>
+ */
+static
int arinc653_adjust_global(struct xen_domctl_scheduler_op * op)
+{
+
int ret = -1;
+
xen_domctl_sched_arinc653_schedule_t new_sched;
+
+
if (op->cmd == XEN_DOMCTL_SCHEDOP_put_global_info)
+
{
+
if (copy_from_guest(&new_sched, op->u.arinc653.schedule, 1) != 0)
+
{
+
ret = -EFAULT;
+
}
+
else
+
{
+
ret = arinc653_sched_set(&new_sched);
+
}
+
}
+
+
return ret;
+} /*
end arinc653_adjust_global */
+
+/**
+ * Xen
scheduler callback function to initialize a virtual CPU (VCPU).
+ *
+ *
@param v Pointer to the VCPU
structure
+ *
+ *
@return <ul>
+
*
<li> 0 if the VCPU is allowed to run
+
*
<li> !0 if there is an error
+
*
</ul>
+ */
+static
int arinc653_init_vcpu(struct vcpu * v)
+{
+
int ret = -1;
+
+
if (is_idle_vcpu(v))
+
{
+
/*
+
* The idle VCPU is created by Xen to run when no domains
+
* are runnable or require CPU time.
+
* It is similar to an "idle task" or "halt loop" process
+
* in an operating system.
+
* We do not track any scheduler information for the idle VCPU.
+
*/
+
v->sched_priv = NULL;
+
ret = 0;
+
}
+
else
+
{
+
/*
+
* Allocate memory for the ARINC 653-specific scheduler data information
+
* associated with the given VCPU (vc).
+
*/
+
v->sched_priv = xmalloc(arinc653_vcpu_t);
+
if (AVCPU(v) != NULL)
+
{
+
/*
+
* Initialize our ARINC 653 scheduler-specific information
+
* for the VCPU.
+
* The VCPU starts "asleep."
+
* When Xen is ready for the VCPU to run, it will call
+
* the vcpu_wake scheduler callback function and our
+
* scheduler will mark the VCPU awake.
+
*/
+
AVCPU(v)->vc = v;
+
AVCPU(v)->awake = 0;
+
list_add(&AVCPU(v)->list, &vcpu_list);
+
ret = 0;
+
update_schedule_vcpus();
+
}
+
}
+
+
return ret;
+} /*
end arinc653_init_vcpu */
+
+/**
+ * Xen
scheduler callback function to remove a VCPU
+ *
+ *
@param v Pointer to the VCPU
structure to remove
+ *
+ *
@return <None>
+ */
+static
void arinc653_destroy_vcpu(struct vcpu * v)
+{
+
if (AVCPU(v) != NULL)
+
{
+
/* remove the VCPU from whichever list it is on */
+
list_del(&AVCPU(v)->list);
+
/* free the arinc653_vcpu structure */
+
xfree(AVCPU(v));
+
update_schedule_vcpus();
+
}
+} /*
end arinc653_destroy_vcpu */
+
+/**
+ * Xen
scheduler callback function to select a VCPU to run.
+ *
This is the main scheduler routine.
+ *
+ *
@param t Current time
+ *
+ *
@return Time slice and
address of the VCPU structure for the chosen
+
*
domain
+ */
+static
struct task_slice arinc653_do_schedule(s_time_t t)
+{
+
struct task_slice ret; /*
hold the chosen domain */
+
struct vcpu * new_task = NULL;
+
static int sched_index = 0;
+
static s_time_t last_major_frame;
+
static s_time_t last_switch_time;
+
static s_time_t next_switch_time;
+
+
if (t >= next_major_frame)
+
{
+
/* time to enter a new major frame
+
* the first time this function is called, this will be true */
+
sched_index = 0;
+
last_major_frame = last_switch_time = t;
+
next_major_frame = t + arinc653_major_frame;
+
}
+
else if (t >= next_switch_time)
+
{
+
/* time to switch to the next domain in this major frame */
+
sched_index++;
+
last_switch_time = next_switch_time;
+
}
+
+
/*
+
* If there are more domains to run in the current major frame, set
+
* next_switch_time equal to the last switch time + this domain's run time.
+
* Otherwise, set next_switch_time equal to the start of the next major
+
* frame.
+
*/
+
next_switch_time = (sched_index < num_schedule_entries)
+
? last_switch_time + arinc653_schedule[sched_index].runtime
+
: next_major_frame;
+
+
/*
+
* If there are more domains to run in the current major frame, set
+
* new_task equal to the address of next domain's VCPU structure.
+
* Otherwise, set new_task equal to the address of the idle task's VCPU
+
* structure.
+
*/
+
new_task = (sched_index < num_schedule_entries)
+
?
arinc653_schedule[sched_index].vc
+
: IDLETASK(0);
+
+
/* Check to see if the new task can be run (awake & runnable). */
+
if (!((new_task != NULL)
+
&& AVCPU(new_task)->awake
+
&& vcpu_runnable(new_task)) )
+
{
+
new_task = IDLETASK(0);
+
}
+
BUG_ON(new_task == NULL);
+
+
/*
+
* Check to make sure we did not miss a major frame.
+
* This is a good test for robust partitioning.
+
*/
+
BUG_ON(t >= next_major_frame);
+
+
/*
+
* Return the amount of time the next domain has to run and the address
+
* of the selected task's VCPU structure.
+
*/
+
ret.time = next_switch_time - t;
+
ret.task = new_task;
+
+
BUG_ON(ret.time <= 0);
+
+
return ret;
+} /*
end arinc653_do_schedule */
+
+/**
+ * Xen
scheduler callback function to select a CPU for the VCPU to run on
+ *
+ *
@param v Pointer to the VCPU
structure for the current domain
+ *
+ *
@return Number of
selected physical CPU
+ */
+static
int arinc653_pick_cpu(struct vcpu * v)
+{
+
/* this implementation only supports one physical CPU */
+
return 0;
+} /*
end arinc653_pick_cpu */
+
+/**
+ * Xen
scheduler callback function to wake up a VCPU
+ *
+ *
@param vc Pointer to the VCPU
structure for the current domain
+ *
+ *
@return <None>
+ */
+static
void arinc653_vcpu_wake(struct vcpu * vc)
+{
+
/* boolean flag to indicate first run */
+
static bool_t dont_raise_softirq = 0;
+
+
if (AVCPU(vc) != NULL) /* check that this is a VCPU we are tracking */
+
{
+
AVCPU(vc)->awake = 1;
+
}
+
+
/* the first time the vcpu_wake function is called, we should raise
+
* a softirq to invoke the do_scheduler callback */
+
if (!dont_raise_softirq)
+
{
+
cpu_raise_softirq(vc->processor, SCHEDULE_SOFTIRQ);
+
dont_raise_softirq = 1;
+
}
+} /*
end arinc653_vcpu_wake */
+
+/**
+ * Xen
scheduler callback function to sleep a VCPU
+ *
+ *
@param vc Pointer to the VCPU
structure for the current domain
+ *
+ *
@return <None>
+ */
+static
void arinc653_vcpu_sleep(struct vcpu * vc)
+{
+
if (AVCPU(vc) != NULL) /* check that this is a VCPU we are tracking */
+
{
+
AVCPU(vc)->awake = 0;
+
}
+
+
/* if the VCPU being put to sleep is the same one that is currently
+
* running, raise a softirq to invoke the scheduler to switch domains */
+
if (per_cpu(schedule_data, vc->processor).curr == vc)
+
{
+
cpu_raise_softirq(vc->processor, SCHEDULE_SOFTIRQ);
+
}
+} /*
end arinc653_vcpu_sleep */
+
+/**
+ *
This structure defines our scheduler for Xen.
+ * The
entries tell Xen where to find our scheduler-specific
+ *
callback functions.
+ * The
symbol must be visible to the rest of Xen at link time.
+ */
+struct
scheduler sched_arinc653_def = {
+
.name =
"ARINC 653 Scheduler",
+
.opt_name = "arinc653",
+
.sched_id = XEN_SCHEDULER_ARINC653,
+
+
.init_domain = NULL,
+
.destroy_domain = NULL,
+
+
.init_vcpu = arinc653_init_vcpu,
+
.destroy_vcpu = arinc653_destroy_vcpu,
+
+
.do_schedule = arinc653_do_schedule,
+
.pick_cpu = arinc653_pick_cpu,
+
.dump_cpu_state = NULL,
+
.sleep =
arinc653_vcpu_sleep,
+
.wake =
arinc653_vcpu_wake,
+
.adjust = NULL,
+
.adjust_global = arinc653_adjust_global,
+};
diff
-rupN a/xen/common/schedule.c b/xen/common/schedule.c
---
a/xen/common/schedule.c 2010-04-14 10:57:11.262796000
-0400
+++
b/xen/common/schedule.c 2010-04-14 16:40:21.543608000 -0400
@@ -7,7
+7,8 @@
* File: common/schedule.c
* Author: Rolf Neugebauer & Keir Fraser
*
Updated for generic API by Mark Williamson
- *
+
*
ARINC653 scheduler added by DornerWorks <DornerWorks.com>
+ *
* Description: Generic CPU scheduling code
*
implements support functionality for the Xen scheduler API.
*
@@
-56,9 +57,11 @@ DEFINE_PER_CPU(struct schedule_data, sch
extern
const struct scheduler sched_sedf_def;
extern
const struct scheduler sched_credit_def;
+extern
const struct scheduler sched_arinc653_def;
static
const struct scheduler *__initdata schedulers[] = {
&sched_sedf_def,
&sched_credit_def,
+
&sched_arinc653_def,
NULL
};
diff
-rupN a/xen/include/public/domctl.h b/xen/include/public/domctl.h
---
a/xen/include/public/domctl.h 2010-04-14 10:57:11.262796000 -0400
+++
b/xen/include/public/domctl.h 2010-04-14
16:40:21.543608000 -0400
@@
-23,6 +23,8 @@
*
* Copyright (c) 2002-2003, B Dragovic
* Copyright (c) 2002-2006, K Fraser
+ *
+ *
ARINC653 Scheduler type added by DornerWorks <DornerWorks.com>.
*/
#ifndef
__XEN_PUBLIC_DOMCTL_H__
@@
-303,11 +305,43 @@ DEFINE_XEN_GUEST_HANDLE(xen_domctl_max_v
/*
Scheduler types. */
#define
XEN_SCHEDULER_SEDF 4
#define
XEN_SCHEDULER_CREDIT 5
+#define
XEN_SCHEDULER_ARINC653 6
+
/*
Set or get info? */
#define
XEN_DOMCTL_SCHEDOP_putinfo 0
#define
XEN_DOMCTL_SCHEDOP_getinfo 1
#define
XEN_DOMCTL_SCHEDOP_put_global_info 2
#define
XEN_DOMCTL_SCHEDOP_get_global_info 3
+
+/*
+ *
This structure is used to pass a new ARINC653 schedule from a
+ *
privileged domain (ie dom0) to Xen.
+ */
+#define
ARINC653_MAX_DOMAINS_PER_SCHEDULE 64
+struct
xen_domctl_sched_arinc653_schedule {
+
/* major_frame holds the time for the new schedule's major frame
+
* in nanoseconds. */
+
int64_t major_frame;
+
/* num_sched_entries holds how many of the entries in the
+
* sched_entries[] array are valid. */
+
uint8_t num_sched_entries;
+
/* The sched_entries array holds the actual schedule entries. */
+
struct {
+
/* dom_handle must match a domain's UUID */
+
xen_domain_handle_t dom_handle;
+
/* If a domain has multiple VCPUs, vcpu_id specifies which one
+
* this schedule entry applies to. It should be set to 0 if
+
* there is only one VCPU for the domain. */
+
int vcpu_id;
+
/* runtime specifies the amount of time that should be allocated
+
* to this VCPU per major frame. It is specified in nanoseconds */
+
int64_t
runtime;
+
} sched_entries[ARINC653_MAX_DOMAINS_PER_SCHEDULE];
+};
+typedef
struct xen_domctl_sched_arinc653_schedule
+
xen_domctl_sched_arinc653_schedule_t;
+DEFINE_XEN_GUEST_HANDLE(xen_domctl_sched_arinc653_schedule_t);
+
struct
xen_domctl_scheduler_op {
uint32_t sched_id; /* XEN_SCHEDULER_* */
uint32_t cmd; /*
XEN_DOMCTL_SCHEDOP_* */
@@
-323,6 +357,9 @@ struct xen_domctl_scheduler_op {
uint16_t weight;
uint16_t cap;
} credit;
+
struct xen_domctl_sched_arinc653 {
+
XEN_GUEST_HANDLE(xen_domctl_sched_arinc653_schedule_t) schedule;
+
} arinc653;
} u;
};
typedef
struct xen_domctl_scheduler_op xen_domctl_scheduler_op_t;
|