# HG changeset patch
# User Isaku Yamahata <yamahata@xxxxxxxxxxxxx>
# Date 1216782620 -32400
# Node ID 1970781956c7f779a27f6b92fc07634269ae1cf0
# Parent 1e7a371cee11c6bf30f5f2f79dc56f315611a74c
# Parent f86941c1b523e4c301210a8d74ab251fb3e2d6c8
merge with xen-unstable.hg
---
.hgignore | 1
extras/mini-os/arch/ia64/mm.c | 5
extras/mini-os/arch/ia64/sched.c | 5
extras/mini-os/arch/x86/mm.c | 23
extras/mini-os/arch/x86/traps.c | 93 +++
extras/mini-os/fs-front.c | 39 +
extras/mini-os/include/ia64/traps.h | 2
extras/mini-os/include/list.h | 6
extras/mini-os/include/mm.h | 1
extras/mini-os/include/x86/traps.h | 1
extras/mini-os/kernel.c | 1
stubdom/Makefile | 12
stubdom/README | 4
tools/Makefile | 1
tools/examples/Makefile | 1
tools/examples/blktap | 1
tools/examples/block | 8
tools/examples/stubdom-ExampleHVMDomain | 14
tools/examples/xmexample.hvm | 14
tools/examples/xmexample.hvm-stubdom | 320 +++++++++++++
tools/flask/libflask/flask_op.c | 6
tools/flask/libflask/include/flask.h | 6
tools/fs-back/fs-backend.c | 2
tools/fs-back/fs-ops.c | 4
tools/ioemu/hw/pc.c | 6
tools/ioemu/hw/vga.c | 89 +--
tools/libxc/xc_linux.c | 23
tools/libxc/xenctrl.h | 17
tools/python/xen/xend/XendNode.py | 28 -
tools/python/xen/xend/balloon.py | 14
tools/python/xen/xend/image.py | 4
tools/python/xen/xend/osdep.py | 46 +
tools/python/xen/xm/create.py | 11
xen/arch/x86/acpi/cpufreq/cpufreq.c | 41 -
xen/arch/x86/domain.c | 4
xen/arch/x86/i8259.c | 2
xen/arch/x86/setup.c | 25 -
xen/arch/x86/time.c | 104 ++--
xen/common/keyhandler.c | 2
xen/drivers/passthrough/amd/pci_amd_iommu.c | 38 +
xen/drivers/passthrough/vtd/dmar.h | 2
xen/drivers/passthrough/vtd/iommu.c | 49 +-
xen/include/asm-x86/hvm/vpt.h | 2
xen/include/public/xsm/flask_op.h | 8
xen/include/xen/pci.h | 6
xen/include/xsm/xsm.h | 6
xen/xsm/dummy.c | 6
xen/xsm/flask/avc.c | 4
xen/xsm/flask/flask_op.c | 652 ++++++++++------------------
xen/xsm/flask/hooks.c | 13
xen/xsm/flask/include/avc.h | 2
51 files changed, 1097 insertions(+), 677 deletions(-)
diff -r 1e7a371cee11 -r 1970781956c7 .hgignore
--- a/.hgignore Wed Jul 23 11:21:47 2008 +0900
+++ b/.hgignore Wed Jul 23 12:10:20 2008 +0900
@@ -138,6 +138,7 @@
^tools/firmware/vgabios/vbetables-gen$
^tools/firmware/vgabios/vbetables\.h$
^tools/flask/loadpolicy/flask-loadpolicy$
+^tools/fs-back/fs-backend$
^tools/include/xen/.*$
^tools/include/xen-foreign/.*\.(c|h|size)$
^tools/include/xen-foreign/checker$
diff -r 1e7a371cee11 -r 1970781956c7 extras/mini-os/arch/ia64/mm.c
--- a/extras/mini-os/arch/ia64/mm.c Wed Jul 23 11:21:47 2008 +0900
+++ b/extras/mini-os/arch/ia64/mm.c Wed Jul 23 12:10:20 2008 +0900
@@ -130,6 +130,11 @@ arch_init_demand_mapping_area(unsigned l
max_pfn = max_pfn;
}
+unsigned long allocate_ondemand(unsigned long n, unsigned long alignment)
+{
+ return 0;
+}
+
/* Helper function used in gnttab.c. */
void do_map_frames(unsigned long addr,
unsigned long *f, unsigned long n, unsigned long stride,
diff -r 1e7a371cee11 -r 1970781956c7 extras/mini-os/arch/ia64/sched.c
--- a/extras/mini-os/arch/ia64/sched.c Wed Jul 23 11:21:47 2008 +0900
+++ b/extras/mini-os/arch/ia64/sched.c Wed Jul 23 12:10:20 2008 +0900
@@ -33,6 +33,11 @@
/* The function is implemented in fw.S */
extern void thread_starter(void);
+
+void stack_walk(void)
+{
+ /* TODO */
+}
struct thread*
arch_create_thread(char *name, void (*function)(void *), void *data)
diff -r 1e7a371cee11 -r 1970781956c7 extras/mini-os/arch/x86/mm.c
--- a/extras/mini-os/arch/x86/mm.c Wed Jul 23 11:21:47 2008 +0900
+++ b/extras/mini-os/arch/x86/mm.c Wed Jul 23 12:10:20 2008 +0900
@@ -492,9 +492,7 @@ void do_map_frames(unsigned long addr,
}
}
-void *map_frames_ex(unsigned long *f, unsigned long n, unsigned long stride,
- unsigned long increment, unsigned long alignment, domid_t id,
- int may_fail, unsigned long prot)
+unsigned long allocate_ondemand(unsigned long n, unsigned long alignment)
{
unsigned long x;
unsigned long y = 0;
@@ -517,13 +515,24 @@ void *map_frames_ex(unsigned long *f, un
}
if (y != n) {
printk("Failed to find %ld frames!\n", n);
+ return 0;
+ }
+ return demand_map_area_start + x * PAGE_SIZE;
+}
+
+void *map_frames_ex(unsigned long *f, unsigned long n, unsigned long stride,
+ unsigned long increment, unsigned long alignment, domid_t id,
+ int may_fail, unsigned long prot)
+{
+ unsigned long addr = allocate_ondemand(n, alignment);
+
+ if (!addr)
return NULL;
- }
/* Found it at x. Map it in. */
- do_map_frames(demand_map_area_start + x * PAGE_SIZE, f, n, stride,
increment, id, may_fail, prot);
-
- return (void *)(unsigned long)(demand_map_area_start + x * PAGE_SIZE);
+ do_map_frames(addr, f, n, stride, increment, id, may_fail, prot);
+
+ return (void *)addr;
}
static void clear_bootstrap(void)
diff -r 1e7a371cee11 -r 1970781956c7 extras/mini-os/arch/x86/traps.c
--- a/extras/mini-os/arch/x86/traps.c Wed Jul 23 11:21:47 2008 +0900
+++ b/extras/mini-os/arch/x86/traps.c Wed Jul 23 12:10:20 2008 +0900
@@ -112,7 +112,7 @@ void page_walk(unsigned long virt_addres
printk(" L2 = %"PRIpte" (%p) [offset = %lx]\n", page, tab,
l2_table_offset(addr));
page = tab[l1_table_offset(addr)];
- printk(" L1 = %"PRIpte" (%p) [offset = %lx]\n", page, tab,
l1_table_offset(addr));
+ printk(" L1 = %"PRIpte" [offset = %lx]\n", page,
l1_table_offset(addr));
}
@@ -155,6 +155,40 @@ static int handle_cow(unsigned long addr
return 0;
}
+static void do_stack_walk(unsigned long frame_base)
+{
+ unsigned long *frame = (void*) frame_base;
+ printk("base is %#lx ", frame_base);
+ printk("caller is %#lx\n", frame[1]);
+ if (frame[0])
+ do_stack_walk(frame[0]);
+}
+
+void stack_walk(void)
+{
+ unsigned long bp;
+#ifdef __x86_64__
+ asm("movq %%rbp, %0":"=r"(bp));
+#else
+ asm("movl %%ebp, %0":"=r"(bp));
+#endif
+ do_stack_walk(bp);
+}
+
+static void dump_mem(unsigned long addr)
+{
+ unsigned long i;
+ if (addr < PAGE_SIZE)
+ return;
+
+ for (i = ((addr)-16 ) & ~15; i < (((addr)+48 ) & ~15); i++)
+ {
+ if (!(i%16))
+ printk("\n%lx:", i);
+ printk(" %02x", *(unsigned char *)i);
+ }
+ printk("\n");
+}
#define read_cr2() \
(HYPERVISOR_shared_info->vcpu_info[smp_processor_id()].arch.cr2)
@@ -163,6 +197,7 @@ void do_page_fault(struct pt_regs *regs,
void do_page_fault(struct pt_regs *regs, unsigned long error_code)
{
unsigned long addr = read_cr2();
+ struct sched_shutdown sched_shutdown = { .reason = SHUTDOWN_crash };
if ((error_code & TRAP_PF_WRITE) && handle_cow(addr))
return;
@@ -170,37 +205,61 @@ void do_page_fault(struct pt_regs *regs,
/* If we are already handling a page fault, and got another one
that means we faulted in pagetable walk. Continuing here would cause
a recursive fault */
- if(handling_pg_fault)
+ if(handling_pg_fault == 1)
{
printk("Page fault in pagetable walk (access to invalid memory?).\n");
- do_exit();
+ HYPERVISOR_sched_op(SCHEDOP_shutdown, &sched_shutdown);
}
- handling_pg_fault = 1;
-
-#if defined(__x86_64__)
- printk("Page fault at linear address %p, rip %p, code %lx\n",
- addr, regs->rip, error_code);
-#else
- printk("Page fault at linear address %p, eip %p, code %lx\n",
- addr, regs->eip, error_code);
-#endif
-
- dump_regs(regs);
+ handling_pg_fault++;
+ barrier();
+
+#if defined(__x86_64__)
+ printk("Page fault at linear address %p, rip %p, regs %p, sp %p, our_sp
%p, code %lx\n",
+ addr, regs->rip, regs, regs->rsp, &addr, error_code);
+#else
+ printk("Page fault at linear address %p, eip %p, regs %p, sp %p, our_sp
%p, code %lx\n",
+ addr, regs->eip, regs, regs->esp, &addr, error_code);
+#endif
+
+ dump_regs(regs);
+#if defined(__x86_64__)
+ do_stack_walk(regs->rbp);
+ dump_mem(regs->rsp);
+ dump_mem(regs->rbp);
+ dump_mem(regs->rip);
+#else
+ do_stack_walk(regs->ebp);
+ dump_mem(regs->esp);
+ dump_mem(regs->ebp);
+ dump_mem(regs->eip);
+#endif
page_walk(addr);
- do_exit();
+ HYPERVISOR_sched_op(SCHEDOP_shutdown, &sched_shutdown);
/* We should never get here ... but still */
- handling_pg_fault = 0;
+ handling_pg_fault--;
}
void do_general_protection(struct pt_regs *regs, long error_code)
{
+ struct sched_shutdown sched_shutdown = { .reason = SHUTDOWN_crash };
#ifdef __i386__
printk("GPF eip: %p, error_code=%lx\n", regs->eip, error_code);
#else
printk("GPF rip: %p, error_code=%lx\n", regs->rip, error_code);
#endif
dump_regs(regs);
- do_exit();
+#if defined(__x86_64__)
+ do_stack_walk(regs->rbp);
+ dump_mem(regs->rsp);
+ dump_mem(regs->rbp);
+ dump_mem(regs->rip);
+#else
+ do_stack_walk(regs->ebp);
+ dump_mem(regs->esp);
+ dump_mem(regs->ebp);
+ dump_mem(regs->eip);
+#endif
+ HYPERVISOR_sched_op(SCHEDOP_shutdown, &sched_shutdown);
}
diff -r 1e7a371cee11 -r 1970781956c7 extras/mini-os/fs-front.c
--- a/extras/mini-os/fs-front.c Wed Jul 23 11:21:47 2008 +0900
+++ b/extras/mini-os/fs-front.c Wed Jul 23 12:10:20 2008 +0900
@@ -183,12 +183,13 @@ int fs_open(struct fs_import *import, ch
/* Prepare request for the backend */
back_req_id = reserve_fsif_request(import);
- DEBUG("Backend request id=%d, gref=%d\n", back_req_id, fsr->gref);
+ DEBUG("Backend request id=%d\n", back_req_id);
/* Prepare our private request structure */
priv_req_id = get_id_from_freelist(import->freelist);
DEBUG("Request id for fs_open call is: %d\n", priv_req_id);
fsr = &import->requests[priv_req_id];
+ DEBUG("gref id=%d\n", fsr->gref);
fsr->thread = current;
sprintf(fsr->page, "%s", file);
@@ -221,7 +222,7 @@ int fs_close(struct fs_import *import, i
/* Prepare request for the backend */
back_req_id = reserve_fsif_request(import);
- DEBUG("Backend request id=%d, gref=%d\n", back_req_id, fsr->gref);
+ DEBUG("Backend request id=%d\n", back_req_id);
/* Prepare our private request structure */
priv_req_id = get_id_from_freelist(import->freelist);
@@ -261,12 +262,13 @@ ssize_t fs_read(struct fs_import *import
/* Prepare request for the backend */
back_req_id = reserve_fsif_request(import);
- DEBUG("Backend request id=%d, gref=%d\n", back_req_id, fsr->gref);
+ DEBUG("Backend request id=%d\n", back_req_id);
/* Prepare our private request structure */
priv_req_id = get_id_from_freelist(import->freelist);
DEBUG("Request id for fs_read call is: %d\n", priv_req_id);
fsr = &import->requests[priv_req_id];
+ DEBUG("gref=%d\n", fsr->gref);
fsr->thread = current;
memset(fsr->page, 0, PAGE_SIZE);
@@ -307,12 +309,13 @@ ssize_t fs_write(struct fs_import *impor
/* Prepare request for the backend */
back_req_id = reserve_fsif_request(import);
- DEBUG("Backend request id=%d, gref=%d\n", back_req_id, fsr->gref);
+ DEBUG("Backend request id=%d\n", back_req_id);
/* Prepare our private request structure */
priv_req_id = get_id_from_freelist(import->freelist);
DEBUG("Request id for fs_read call is: %d\n", priv_req_id);
fsr = &import->requests[priv_req_id];
+ DEBUG("gref=%d\n", fsr->gref);
fsr->thread = current;
memcpy(fsr->page, buf, len);
BUG_ON(len > PAGE_SIZE);
@@ -352,12 +355,13 @@ int fs_stat(struct fs_import *import,
/* Prepare request for the backend */
back_req_id = reserve_fsif_request(import);
- DEBUG("Backend request id=%d, gref=%d\n", back_req_id, fsr->gref);
+ DEBUG("Backend request id=%d\n", back_req_id);
/* Prepare our private request structure */
priv_req_id = get_id_from_freelist(import->freelist);
DEBUG("Request id for fs_stat call is: %d\n", priv_req_id);
fsr = &import->requests[priv_req_id];
+ DEBUG("gref=%d\n", fsr->gref);
fsr->thread = current;
memset(fsr->page, 0, PAGE_SIZE);
@@ -394,7 +398,7 @@ int fs_truncate(struct fs_import *import
/* Prepare request for the backend */
back_req_id = reserve_fsif_request(import);
- DEBUG("Backend request id=%d, gref=%d\n", back_req_id, fsr->gref);
+ DEBUG("Backend request id=%d\n", back_req_id);
/* Prepare our private request structure */
priv_req_id = get_id_from_freelist(import->freelist);
@@ -432,12 +436,13 @@ int fs_remove(struct fs_import *import,
/* Prepare request for the backend */
back_req_id = reserve_fsif_request(import);
- DEBUG("Backend request id=%d, gref=%d\n", back_req_id, fsr->gref);
+ DEBUG("Backend request id=%d\n", back_req_id);
/* Prepare our private request structure */
priv_req_id = get_id_from_freelist(import->freelist);
DEBUG("Request id for fs_open call is: %d\n", priv_req_id);
fsr = &import->requests[priv_req_id];
+ DEBUG("gref=%d\n", fsr->gref);
fsr->thread = current;
sprintf(fsr->page, "%s", file);
@@ -475,12 +480,13 @@ int fs_rename(struct fs_import *import,
/* Prepare request for the backend */
back_req_id = reserve_fsif_request(import);
- DEBUG("Backend request id=%d, gref=%d\n", back_req_id, fsr->gref);
+ DEBUG("Backend request id=%d\n", back_req_id);
/* Prepare our private request structure */
priv_req_id = get_id_from_freelist(import->freelist);
DEBUG("Request id for fs_open call is: %d\n", priv_req_id);
fsr = &import->requests[priv_req_id];
+ DEBUG("gref=%d\n", fsr->gref);
fsr->thread = current;
sprintf(fsr->page, "%s%s%c%s%s",
old_header, old_file_name, '\0', new_header, new_file_name);
@@ -521,12 +527,13 @@ int fs_create(struct fs_import *import,
/* Prepare request for the backend */
back_req_id = reserve_fsif_request(import);
- DEBUG("Backend request id=%d, gref=%d\n", back_req_id, fsr->gref);
+ DEBUG("Backend request id=%d\n", back_req_id);
/* Prepare our private request structure */
priv_req_id = get_id_from_freelist(import->freelist);
DEBUG("Request id for fs_create call is: %d\n", priv_req_id);
fsr = &import->requests[priv_req_id];
+ DEBUG("gref=%d\n", fsr->gref);
fsr->thread = current;
sprintf(fsr->page, "%s", name);
@@ -566,12 +573,13 @@ char** fs_list(struct fs_import *import,
/* Prepare request for the backend */
back_req_id = reserve_fsif_request(import);
- DEBUG("Backend request id=%d, gref=%d\n", back_req_id, fsr->gref);
+ DEBUG("Backend request id=%d\n", back_req_id);
/* Prepare our private request structure */
priv_req_id = get_id_from_freelist(import->freelist);
DEBUG("Request id for fs_list call is: %d\n", priv_req_id);
fsr = &import->requests[priv_req_id];
+ DEBUG("gref=%d\n", fsr->gref);
fsr->thread = current;
sprintf(fsr->page, "%s", name);
@@ -615,7 +623,7 @@ int fs_chmod(struct fs_import *import, i
/* Prepare request for the backend */
back_req_id = reserve_fsif_request(import);
- DEBUG("Backend request id=%d, gref=%d\n", back_req_id, fsr->gref);
+ DEBUG("Backend request id=%d\n", back_req_id);
/* Prepare our private request structure */
priv_req_id = get_id_from_freelist(import->freelist);
@@ -653,12 +661,13 @@ int64_t fs_space(struct fs_import *impor
/* Prepare request for the backend */
back_req_id = reserve_fsif_request(import);
- DEBUG("Backend request id=%d, gref=%d\n", back_req_id, fsr->gref);
+ DEBUG("Backend request id=%d\n", back_req_id);
/* Prepare our private request structure */
priv_req_id = get_id_from_freelist(import->freelist);
DEBUG("Request id for fs_space is: %d\n", priv_req_id);
fsr = &import->requests[priv_req_id];
+ DEBUG("gref=%d\n", fsr->gref);
fsr->thread = current;
sprintf(fsr->page, "%s", location);
@@ -691,7 +700,7 @@ int fs_sync(struct fs_import *import, in
/* Prepare request for the backend */
back_req_id = reserve_fsif_request(import);
- DEBUG("Backend request id=%d, gref=%d\n", back_req_id, fsr->gref);
+ DEBUG("Backend request id=%d\n", back_req_id);
/* Prepare our private request structure */
priv_req_id = get_id_from_freelist(import->freelist);
@@ -737,7 +746,7 @@ static void fsfront_handler(evtchn_port_
DEBUG("Event from import [%d:%d].\n", import->dom_id, import->export_id);
moretodo:
- rp = import->ring.sring->req_prod;
+ rp = import->ring.sring->rsp_prod;
rmb(); /* Ensure we see queued responses up to 'rp'. */
cons = import->ring.rsp_cons;
while (cons != rp)
@@ -747,7 +756,7 @@ moretodo:
rsp = RING_GET_RESPONSE(&import->ring, cons);
DEBUG("Response at idx=%d to request id=%d, ret_val=%lx\n",
- import->ring.rsp_cons, rsp->id, rsp->ret_val);
+ cons, rsp->id, rsp->ret_val);
req = &import->requests[rsp->id];
memcpy(&req->shadow_rsp, rsp, sizeof(struct fsif_response));
DEBUG("Waking up: %s\n", req->thread->name);
diff -r 1e7a371cee11 -r 1970781956c7 extras/mini-os/include/ia64/traps.h
--- a/extras/mini-os/include/ia64/traps.h Wed Jul 23 11:21:47 2008 +0900
+++ b/extras/mini-os/include/ia64/traps.h Wed Jul 23 12:10:20 2008 +0900
@@ -48,5 +48,7 @@ inline static void trap_fini(void)
#include "ia64_cpu.h"
+void stack_walk(void);
+
#endif /* !defined(_TRAPS_H_) */
diff -r 1e7a371cee11 -r 1970781956c7 extras/mini-os/include/list.h
--- a/extras/mini-os/include/list.h Wed Jul 23 11:21:47 2008 +0900
+++ b/extras/mini-os/include/list.h Wed Jul 23 12:10:20 2008 +0900
@@ -23,6 +23,12 @@ struct list_head {
#define INIT_LIST_HEAD(ptr) do { \
(ptr)->next = (ptr); (ptr)->prev = (ptr); \
} while (0)
+
+#define list_top(head, type, member) \
+({ \
+ struct list_head *_head = (head); \
+ list_empty(_head) ? NULL : list_entry(_head->next, type, member); \
+})
/*
* Insert a new entry between two known consecutive entries.
diff -r 1e7a371cee11 -r 1970781956c7 extras/mini-os/include/mm.h
--- a/extras/mini-os/include/mm.h Wed Jul 23 11:21:47 2008 +0900
+++ b/extras/mini-os/include/mm.h Wed Jul 23 12:10:20 2008 +0900
@@ -63,6 +63,7 @@ void arch_init_mm(unsigned long* start_p
void arch_init_mm(unsigned long* start_pfn_p, unsigned long* max_pfn_p);
void arch_init_p2m(unsigned long max_pfn_p);
+unsigned long allocate_ondemand(unsigned long n, unsigned long alignment);
/* map f[i*stride]+i*increment for i in 0..n-1, aligned on alignment pages */
void *map_frames_ex(unsigned long *f, unsigned long n, unsigned long stride,
unsigned long increment, unsigned long alignment, domid_t id,
diff -r 1e7a371cee11 -r 1970781956c7 extras/mini-os/include/x86/traps.h
--- a/extras/mini-os/include/x86/traps.h Wed Jul 23 11:21:47 2008 +0900
+++ b/extras/mini-os/include/x86/traps.h Wed Jul 23 12:10:20 2008 +0900
@@ -69,6 +69,7 @@ struct pt_regs {
#endif
void dump_regs(struct pt_regs *regs);
+void stack_walk(void);
#define TRAP_PF_PROT 0x1
#define TRAP_PF_WRITE 0x2
diff -r 1e7a371cee11 -r 1970781956c7 extras/mini-os/kernel.c
--- a/extras/mini-os/kernel.c Wed Jul 23 11:21:47 2008 +0900
+++ b/extras/mini-os/kernel.c Wed Jul 23 12:10:20 2008 +0900
@@ -592,6 +592,7 @@ void do_exit(void)
void do_exit(void)
{
printk("Do_exit called!\n");
+ stack_walk();
for( ;; )
{
struct sched_shutdown sched_shutdown = { .reason = SHUTDOWN_crash };
diff -r 1e7a371cee11 -r 1970781956c7 stubdom/Makefile
--- a/stubdom/Makefile Wed Jul 23 11:21:47 2008 +0900
+++ b/stubdom/Makefile Wed Jul 23 12:10:20 2008 +0900
@@ -85,7 +85,7 @@ NEWLIB_STAMPFILE=$(CROSS_ROOT)/$(GNU_TAR
NEWLIB_STAMPFILE=$(CROSS_ROOT)/$(GNU_TARGET_ARCH)-xen-elf/lib/libc.a
.PHONY: cross-newlib
cross-newlib: $(NEWLIB_STAMPFILE)
-$(NEWLIB_STAMPFILE): newlib-$(NEWLIB_VERSION)
+$(NEWLIB_STAMPFILE): mk-headers newlib-$(NEWLIB_VERSION)
mkdir -p newlib-build
( cd newlib-build && \
CC_FOR_TARGET="$(CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS)
$(NEWLIB_CFLAGS)" AR_FOR_TARGET=$(AR) LD_FOR_TARGET=$(LD)
RANLIB_FOR_TARGET=$(RANLIB) ../newlib-$(NEWLIB_VERSION)/configure
--prefix=$(CROSS_PREFIX) --verbose --target=$(GNU_TARGET_ARCH)-xen-elf
--enable-newlib-io-long-long --disable-multilib && \
@@ -205,7 +205,7 @@ TARGETS_MINIOS=$(addprefix mini-os-,$(TA
.PHONY: libxc
libxc: libxc/libxenctrl.a libxc/libxenguest.a
-libxc/libxenctrl.a libxc/libxenguest.a:: cross-zlib mk-headers
+libxc/libxenctrl.a libxc/libxenguest.a:: cross-zlib
CPPFLAGS="$(TARGET_CPPFLAGS)" CFLAGS="$(TARGET_CFLAGS)" $(MAKE) -C libxc
#######
@@ -213,7 +213,7 @@ libxc/libxenctrl.a libxc/libxenguest.a::
#######
.PHONY: ioemu
-ioemu: cross-zlib cross-libpci mk-headers libxc
+ioemu: cross-zlib cross-libpci libxc
ifeq ($(CONFIG_QEMU),ioemu)
[ -f ioemu/config-host.mak ] || \
( cd ioemu ; \
@@ -231,7 +231,7 @@ endif
######
.PHONY: caml
-caml: cross-newlib mk-headers
+caml: $(CROSS_ROOT)
CPPFLAGS="$(TARGET_CPPFLAGS)" CFLAGS="$(TARGET_CFLAGS)" $(MAKE) -C $@
LWIPDIR=$(CURDIR)/lwip
###
@@ -239,7 +239,7 @@ caml: cross-newlib mk-headers
###
.PHONY: c
-c: cross-newlib mk-headers
+c: $(CROSS_ROOT)
CPPFLAGS="$(TARGET_CPPFLAGS)" CFLAGS="$(TARGET_CFLAGS)" $(MAKE) -C $@
LWIPDIR=$(CURDIR)/lwip
######
@@ -257,7 +257,7 @@ grub-upstream: grub-$(GRUB_VERSION).tar.
done
.PHONY: grub
-grub: grub-upstream cross-newlib mk-headers
+grub: grub-upstream $(CROSS_ROOT)
CPPFLAGS="$(TARGET_CPPFLAGS)" CFLAGS="$(TARGET_CFLAGS)" $(MAKE) -C $@
########
diff -r 1e7a371cee11 -r 1970781956c7 stubdom/README
--- a/stubdom/README Wed Jul 23 11:21:47 2008 +0900
+++ b/stubdom/README Wed Jul 23 12:10:20 2008 +0900
@@ -87,8 +87,8 @@ To run
To run
======
-mkdir -p /exports/usr/share/qemu
-ln -s /usr/share/qemu/keymaps /exports/usr/share/qemu
+mkdir -p /exports/usr/share/xen/qemu
+ln -s /usr/share/xen/qemu/keymaps /exports/usr/share/xen/qemu
mkdir -p /exports/var/lib
ln -s /var/lib/xen /exports/var/lib
/usr/sbin/fs-backend &
diff -r 1e7a371cee11 -r 1970781956c7 tools/Makefile
--- a/tools/Makefile Wed Jul 23 11:21:47 2008 +0900
+++ b/tools/Makefile Wed Jul 23 12:10:20 2008 +0900
@@ -22,6 +22,7 @@ SUBDIRS-y += blktap
SUBDIRS-y += blktap
SUBDIRS-y += libfsimage
SUBDIRS-$(LIBXENAPI_BINDINGS) += libxen
+SUBDIRS-y += fs-back
ifeq (ioemu,$(CONFIG_QEMU))
SUBDIRS-$(CONFIG_IOEMU) += ioemu
diff -r 1e7a371cee11 -r 1970781956c7 tools/examples/Makefile
--- a/tools/examples/Makefile Wed Jul 23 11:21:47 2008 +0900
+++ b/tools/examples/Makefile Wed Jul 23 12:10:20 2008 +0900
@@ -28,6 +28,7 @@ XEN_SCRIPTS += vtpm vtpm-delete
XEN_SCRIPTS += vtpm vtpm-delete
XEN_SCRIPTS += xen-hotplug-cleanup
XEN_SCRIPTS += external-device-migrate
+XEN_SCRIPTS += vscsi
XEN_SCRIPT_DATA = xen-script-common.sh locking.sh logging.sh
XEN_SCRIPT_DATA += xen-hotplug-common.sh xen-network-common.sh vif-common.sh
XEN_SCRIPT_DATA += block-common.sh vtpm-common.sh vtpm-hotplug-common.sh
diff -r 1e7a371cee11 -r 1970781956c7 tools/examples/blktap
--- a/tools/examples/blktap Wed Jul 23 11:21:47 2008 +0900
+++ b/tools/examples/blktap Wed Jul 23 12:10:20 2008 +0900
@@ -69,7 +69,6 @@ if [ -L "$p" ]; then
if [ -L "$p" ]; then
file=$(readlink -f "$p") || fatal "$p link does not exist."
else
- [ -f "$p" ] || { fatal "$p file does not exist."; }
file="$p"
fi
diff -r 1e7a371cee11 -r 1970781956c7 tools/examples/block
--- a/tools/examples/block Wed Jul 23 11:21:47 2008 +0900
+++ b/tools/examples/block Wed Jul 23 12:10:20 2008 +0900
@@ -209,6 +209,14 @@ case "$command" in
FRONTEND_ID=$(xenstore_read "$XENBUS_PATH/frontend-id")
FRONTEND_UUID=$(xenstore_read_default \
"/local/domain/$FRONTEND_ID/vm" 'unknown')
+
+ if [ -L "$dev" ]
+ then
+ dev=$(readlink -f "$dev") || fatal "$dev link does not exist."
+ fi
+ test -e "$dev" || fatal "$dev does not exist."
+ test -b "$dev" || fatal "$dev is not a block device."
+
claim_lock "block"
check_device_sharing "$dev" "$mode"
write_dev "$dev"
diff -r 1e7a371cee11 -r 1970781956c7 tools/examples/stubdom-ExampleHVMDomain
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/examples/stubdom-ExampleHVMDomain Wed Jul 23 12:10:20 2008 +0900
@@ -0,0 +1,14 @@
+# Not to be started directly,
+# See xmexample.hvm-stubdom and stubdom/README for more details
+
+kernel = "/usr/lib/xen/boot/ioemu-stubdom.gz"
+
+# Must be the same as in xmexample.hvm-stubdom, with a prepended vif for TCP/IP
+# networking in the stubdomain itself, here just ''
+vif = [ '', 'type=ioemu, bridge=xenbr0' ]
+
+# Set here instead of in xmexample.hvm-stubdom
+disk = [ 'file:/var/images/min-el3-i386.img,hda,w', ',hdc:cdrom,r' ]
+
+# Actual output via PVFB
+vfb = [ 'type=sdl' ]
diff -r 1e7a371cee11 -r 1970781956c7 tools/examples/xmexample.hvm
--- a/tools/examples/xmexample.hvm Wed Jul 23 11:21:47 2008 +0900
+++ b/tools/examples/xmexample.hvm Wed Jul 23 12:10:20 2008 +0900
@@ -119,7 +119,7 @@ disk = [ 'file:/var/images/min-el3-i386.
#============================================================================
-# New stuff
+# Device Model to be used
device_model = '/usr/' + arch_libdir + '/xen/bin/qemu-dm'
#-----------------------------------------------------------------------------
@@ -247,12 +247,14 @@ serial='pty'
#vcpus=8
#
# Example for amd, expose a 5-core processor :
-# cpuid = ['1:ebx=xxxxxxxx00000001xxxxxxxxxxxxxxxx,
+# cpuid = ['1:ebx=xxxxxxxx00001010xxxxxxxxxxxxxxxx,
# edx=xxx1xxxxxxxxxxxxxxxxxxxxxxxxxxxx',
-# '0x80000008:ecx=xxxxxxxxxxxxxxxx0000xxxx00001010']
-# - CPUID.1[EBX] : (Thread * Cores ) per processors
-# - CPUID.1[EDX][HT] : Enable HT
-# - CPUID.0x80000008[ECX] : Number of vcpus * 2
+# '0x80000001:ecx=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx1x',
+# '0x80000008:ecx=xxxxxxxxxxxxxxxxxxxxxxxxxx001001']
+# - CPUID.1[EBX] : Threads per Core * Cores per Socket (2 * #vcpus)
+# - CPUID.1[EDX][HT] : Enable HT
+# - CPUID.0x80000001[CmpLegacy] : Use legacy method
+# - CPUID.0x80000008[ECX] : #vcpus * 2 - 1
#vcpus=5
#
# Downgrade the cpuid to make a better compatibility for migration :
diff -r 1e7a371cee11 -r 1970781956c7 tools/examples/xmexample.hvm-stubdom
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/examples/xmexample.hvm-stubdom Wed Jul 23 12:10:20 2008 +0900
@@ -0,0 +1,320 @@
+# -*- mode: python; -*-
+#============================================================================
+# Python configuration setup for 'xm create'.
+# This script sets the parameters used when a domain is created using 'xm
create'.
+# You use a separate script for each domain you want to create, or
+# you can set the parameters for the domain on the xm command line.
+#============================================================================
+#
+# This is a version using a stubdomain for device model, see
+# stubdom-ExampleHVMDomain and stubdom/README for more details
+# The differences with xmexample.hvm are marked with "STUBDOM"
+
+#----------------------------------------------------------------------------
+# Kernel image file.
+kernel = "/usr/lib/xen/boot/hvmloader"
+
+# The domain build function. HVM domain uses 'hvm'.
+builder='hvm'
+
+# Initial memory allocation (in megabytes) for the new domain.
+#
+# WARNING: Creating a domain with insufficient memory may cause out of
+# memory errors. The domain needs enough memory to boot kernel
+# and modules. Allocating less than 32MBs is not recommended.
+memory = 128
+
+# Shadow pagetable memory for the domain, in MB.
+# If not explicictly set, xend will pick an appropriate value.
+# Should be at least 2KB per MB of domain memory, plus a few MB per vcpu.
+# shadow_memory = 8
+
+# A name for your domain. All domains must have different names.
+name = "ExampleHVMDomain"
+
+# 128-bit UUID for the domain. The default behavior is to generate a new UUID
+# on each call to 'xm create'.
+#uuid = "06ed00fe-1162-4fc4-b5d8-11993ee4a8b9"
+
+#-----------------------------------------------------------------------------
+# The number of cpus guest platform has, default=1
+#vcpus=1
+
+# Enable/disable HVM guest PAE, default=1 (enabled)
+#pae=1
+
+# Enable/disable HVM guest ACPI, default=1 (enabled)
+#acpi=1
+
+# Enable/disable HVM APIC mode, default=1 (enabled)
+# Note that this option is ignored if vcpus > 1
+#apic=1
+
+# List of which CPUS this domain is allowed to use, default Xen picks
+#cpus = "" # leave to Xen to pick
+#cpus = "0" # all vcpus run on CPU0
+#cpus = "0-3,5,^1" # all vcpus run on cpus 0,2,3,5
+#cpus = ["2", "3"] # VCPU0 runs on CPU2, VCPU1 runs on CPU3
+
+# Optionally define mac and/or bridge for the network interfaces.
+# Random MACs are assigned if not given.
+#vif = [ 'type=ioemu, mac=00:16:3e:00:00:11, bridge=xenbr0, model=ne2k_pci' ]
+# type=ioemu specify the NIC is an ioemu device not netfront
+vif = [ 'type=ioemu, bridge=xenbr0' ]
+
+#----------------------------------------------------------------------------
+# Define the disk devices you want the domain to have access to, and
+# what you want them accessible as.
+# Each disk entry is of the form phy:UNAME,DEV,MODE
+# where UNAME is the device, DEV is the device name the domain will see,
+# and MODE is r for read-only, w for read-write.
+#
+# STUBDOM: do not put it here but in stubdom-ExampleHVMDomain
+
+#disk = [ 'phy:hda1,hda1,r' ]
+#disk = [ 'file:/var/images/min-el3-i386.img,hda,w', ',hdc:cdrom,r' ]
+
+#----------------------------------------------------------------------------
+# Configure the behaviour when a domain exits. There are three 'reasons'
+# for a domain to stop: poweroff, reboot, and crash. For each of these you
+# may specify:
+#
+# "destroy", meaning that the domain is cleaned up as normal;
+# "restart", meaning that a new domain is started in place of the old
+# one;
+# "preserve", meaning that no clean-up is done until the domain is
+# manually destroyed (using xm destroy, for example); or
+# "rename-restart", meaning that the old domain is not cleaned up, but is
+# renamed and a new domain started in its place.
+#
+# In the event a domain stops due to a crash, you have the additional options:
+#
+# "coredump-destroy", meaning dump the crashed domain's core and then
destroy;
+# "coredump-restart', meaning dump the crashed domain's core and the restart.
+#
+# The default is
+#
+# on_poweroff = 'destroy'
+# on_reboot = 'restart'
+# on_crash = 'restart'
+#
+# For backwards compatibility we also support the deprecated option restart
+#
+# restart = 'onreboot' means on_poweroff = 'destroy'
+# on_reboot = 'restart'
+# on_crash = 'destroy'
+#
+# restart = 'always' means on_poweroff = 'restart'
+# on_reboot = 'restart'
+# on_crash = 'restart'
+#
+# restart = 'never' means on_poweroff = 'destroy'
+# on_reboot = 'destroy'
+# on_crash = 'destroy'
+
+#on_poweroff = 'destroy'
+#on_reboot = 'restart'
+#on_crash = 'restart'
+
+#============================================================================
+
+# Device Model to be used
+#
+# STUBDOM: this is a script that creates the stub domain running the device
+# model
+device_model = '/usr/lib/xen/bin/stubdom-dm'
+
+#-----------------------------------------------------------------------------
+# boot on floppy (a), hard disk (c), Network (n) or CD-ROM (d)
+# default: hard disk, cd-rom, floppy
+#boot="cda"
+
+#-----------------------------------------------------------------------------
+# write to temporary files instead of disk image files
+#snapshot=1
+
+#----------------------------------------------------------------------------
+# enable SDL library for graphics, default = 0
+#
+# STUBDOM: always disable since the stub domain doesn't have direct X access
+sdl=0
+
+#----------------------------------------------------------------------------
+# enable OpenGL for texture rendering inside the SDL window, default = 1
+# valid only if sdl is enabled.
+#
+# STUBDOM: always disable for the same reason
+opengl=0
+
+#----------------------------------------------------------------------------
+# enable VNC library for graphics, default = 1
+vnc=0
+
+#----------------------------------------------------------------------------
+# address that should be listened on for the VNC server if vnc is set.
+# default is to use 'vnc-listen' setting from /etc/xen/xend-config.sxp
+#vnclisten="127.0.0.1"
+
+#----------------------------------------------------------------------------
+# set VNC display number, default = domid
+#vncdisplay=1
+
+#----------------------------------------------------------------------------
+# try to find an unused port for the VNC server, default = 1
+#vncunused=1
+
+#----------------------------------------------------------------------------
+# enable spawning vncviewer for domain's console
+# (only valid when vnc=1), default = 0
+#vncconsole=0
+
+#----------------------------------------------------------------------------
+# set password for domain's VNC console
+# default is depents on vncpasswd in xend-config.sxp
+vncpasswd=''
+
+#----------------------------------------------------------------------------
+# no graphics, use serial port
+#nographic=0
+
+#----------------------------------------------------------------------------
+# enable stdvga, default = 0 (use cirrus logic device model)
+stdvga=0
+
+#-----------------------------------------------------------------------------
+# serial port re-direct to pty deivce, /dev/pts/n
+# then xm console or minicom can connect
+#
+# STUBDOM: always disable as the stub domain doesn't have access to dom0's
+# ptys
+#serial='pty'
+
+
+#-----------------------------------------------------------------------------
+# Qemu Monitor, default is disable
+# Use ctrl-alt-2 to connect
+#monitor=1
+
+
+#-----------------------------------------------------------------------------
+# enable sound card support, [sb16|es1370|all|..,..], default none
+#
+# STUBDOM: not supported
+#soundhw='sb16'
+
+
+#-----------------------------------------------------------------------------
+# set the real time clock to local time [default=0 i.e. set to utc]
+#localtime=1
+
+
+#-----------------------------------------------------------------------------
+# set the real time clock offset in seconds [default=0 i.e. same as dom0]
+#rtc_timeoffset=3600
+
+#-----------------------------------------------------------------------------
+# start in full screen
+#full-screen=1
+
+
+#-----------------------------------------------------------------------------
+# Enable USB support (specific devices specified at runtime through the
+# monitor window)
+#usb=1
+
+# Enable USB mouse support (only enable one of the following, `mouse' for
+# PS/2 protocol relative mouse, `tablet' for
+# absolute mouse)
+#usbdevice='mouse'
+#usbdevice='tablet'
+
+#-----------------------------------------------------------------------------
+# Set keyboard layout, default is en-us keyboard.
+#keymap='ja'
+
+#-----------------------------------------------------------------------------
+# Configure guest CPUID responses:
+#
+#cpuid=[ '1:ecx=xxxxxxxxxxx00xxxxxxxxxxxxxxxxxxx,
+# eax=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' ]
+# - Unset the SSE4 features (CPUID.1[ECX][20-19])
+# - Default behaviour for all other bits in ECX And EAX registers.
+#
+# Each successive character represent a lesser-significant bit:
+# '1' -> force the corresponding bit to 1
+# '0' -> force to 0
+# 'x' -> Get a safe value (pass through and mask with the default policy)
+# 'k' -> pass through the host bit value
+# 's' -> as 'k' but preserve across save/restore and migration
+#
+# Expose to the guest multi-core cpu instead of multiple processors
+# Example for intel, expose a 8-core processor :
+#cpuid=['1:edx=xxx1xxxxxxxxxxxxxxxxxxxxxxxxxxxx,
+# ebx=xxxxxxxx00010000xxxxxxxxxxxxxxxx',
+# '4,0:eax=001111xxxxxxxxxxxxxxxxxxxxxxxxxx']
+# - CPUID.1[EDX][HT] : Enable HT
+# - CPUID.1[EBX] : Number of vcpus * 2
+# - CPUID.4,0[EAX] : Number of vcpus * 2 - 1
+#vcpus=8
+#
+# Example for amd, expose a 5-core processor :
+# cpuid = ['1:ebx=xxxxxxxx00001010xxxxxxxxxxxxxxxx,
+# edx=xxx1xxxxxxxxxxxxxxxxxxxxxxxxxxxx',
+# '0x80000001:ecx=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx1x',
+# '0x80000008:ecx=xxxxxxxxxxxxxxxxxxxxxxxxxx001001']
+# - CPUID.1[EBX] : Threads per Core * Cores per Socket (2 * #vcpus)
+# - CPUID.1[EDX][HT] : Enable HT
+# - CPUID.0x80000001[CmpLegacy] : Use legacy method
+# - CPUID.0x80000008[ECX] : #vcpus * 2 - 1
+#vcpus=5
+#
+# Downgrade the cpuid to make a better compatibility for migration :
+# Look like a generic 686 :
+# cpuid = [ '0:eax=0x3,ebx=0x0,ecx=0x0,edx=0x0',
+# '1:eax=0x06b1,
+# ecx=xxxxxxxxxx0000xx00xxx0000000xx0,
+# edx=xx00000xxxxxxx0xxxxxxxxx0xxxxxx',
+# '4:eax=0x3,ebx=0x0,ecx=0x0,edx=0x0',
+# '0x80000000:eax=0x3,ebx=0x0,ecx=0x0,edx=0x0']
+# with the highest leaf
+# - CPUID.0[EAX] : Set the highest leaf
+# - CPUID.1[EAX] : 686
+# - CPUID.1[ECX] : Mask some features
+# - CPUID.1[EDX] : Mask some features
+# - CPUID.4 : Reply like the highest leaf, in our case CPUID.3
+# - CPUID.0x80000000 : No extension we are on a Pentium III, reply like the
+# highest leaf (CPUID.3).
+#
+# Configure host CPUID consistency checks, which must be satisfied for this
+# VM to be allowed to run on this host's processor type:
+#cpuid_check=[ '1:ecx=xxxxxxxxxxxxxxxxxxxxxxxxxx1xxxxx' ]
+# - Host must have VMX feature flag set
+#
+# The format is similar to the above for 'cpuid':
+# '1' -> the bit must be '1'
+# '0' -> the bit must be '0'
+# 'x' -> we don't care (do not check)
+# 's' -> the bit must be the same as on the host that started this VM
+
+
+#-----------------------------------------------------------------------------
+# Configure PVSCSI devices:
+#
+#vscsi=[ 'PDEV, VDEV' ]
+#
+# PDEV gives physical SCSI device to be attached to specified guest
+# domain by one of the following identifier format.
+# - XX:XX:XX:XX (4-tuples with decimal notation which shows
+# "host:channel:target:lun")
+# - /dev/sdxx or sdx
+# - /dev/stxx or stx
+# - /dev/sgxx or sgx
+# - result of 'scsi_id -gu -s'.
+# ex. # scsi_id -gu -s /block/sdb
+# 36000b5d0006a0000006a0257004c0000
+#
+# VDEV gives virtual SCSI device by 4-tuples (XX:XX:XX:XX) as
+# which the specified guest domain recognize.
+#
+
+#vscsi = [ '/dev/sdx, 0:0:0:0' ]
diff -r 1e7a371cee11 -r 1970781956c7 tools/flask/libflask/flask_op.c
--- a/tools/flask/libflask/flask_op.c Wed Jul 23 11:21:47 2008 +0900
+++ b/tools/flask/libflask/flask_op.c Wed Jul 23 12:10:20 2008 +0900
@@ -22,7 +22,7 @@
#include <flask.h>
#include <xenctrl.h>
-int flask_load(int xc_handle, char *buf, int size)
+int flask_load(int xc_handle, char *buf, uint32_t size)
{
int err;
flask_op_t op;
@@ -37,7 +37,7 @@ int flask_load(int xc_handle, char *buf,
return 0;
}
-int flask_context_to_sid(int xc_handle, char *buf, int size, uint32_t *sid)
+int flask_context_to_sid(int xc_handle, char *buf, uint32_t size, uint32_t
*sid)
{
int err;
flask_op_t op;
@@ -54,7 +54,7 @@ int flask_context_to_sid(int xc_handle,
return 0;
}
-int flask_sid_to_context(int xc_handle, int sid, char *buf, int size)
+int flask_sid_to_context(int xc_handle, int sid, char *buf, uint32_t size)
{
int err;
flask_op_t op;
diff -r 1e7a371cee11 -r 1970781956c7 tools/flask/libflask/include/flask.h
--- a/tools/flask/libflask/include/flask.h Wed Jul 23 11:21:47 2008 +0900
+++ b/tools/flask/libflask/include/flask.h Wed Jul 23 12:10:20 2008 +0900
@@ -15,8 +15,8 @@
#include <xen/xen.h>
#include <xen/xsm/flask_op.h>
-int flask_load(int xc_handle, char *buf, int size);
-int flask_context_to_sid(int xc_handle, char *buf, int size, uint32_t *sid);
-int flask_sid_to_context(int xc_handle, int sid, char *buf, int size);
+int flask_load(int xc_handle, char *buf, uint32_t size);
+int flask_context_to_sid(int xc_handle, char *buf, uint32_t size, uint32_t
*sid);
+int flask_sid_to_context(int xc_handle, int sid, char *buf, uint32_t size);
#endif /* __FLASK_H__ */
diff -r 1e7a371cee11 -r 1970781956c7 tools/fs-back/fs-backend.c
--- a/tools/fs-back/fs-backend.c Wed Jul 23 11:21:47 2008 +0900
+++ b/tools/fs-back/fs-backend.c Wed Jul 23 12:10:20 2008 +0900
@@ -239,7 +239,7 @@ static void handle_connection(int fronte
mount->dom_id,
mount->gref,
PROT_READ | PROT_WRITE);
- BACK_RING_INIT(&mount->ring, sring, PAGE_SIZE);
+ BACK_RING_INIT(&mount->ring, sring, XC_PAGE_SIZE);
mount->nr_entries = mount->ring.nr_ents;
for (i = 0; i < MAX_FDS; i++)
mount->fds[i] = -1;
diff -r 1e7a371cee11 -r 1970781956c7 tools/fs-back/fs-ops.c
--- a/tools/fs-back/fs-ops.c Wed Jul 23 11:21:47 2008 +0900
+++ b/tools/fs-back/fs-ops.c Wed Jul 23 12:10:20 2008 +0900
@@ -515,9 +515,9 @@ void dispatch_list(struct mount *mount,
/* If there was any error with reading the directory, errno will be set */
error_code = errno;
/* Copy file names of the remaining non-NULL dirents into buf */
- assert(NAME_MAX < PAGE_SIZE >> 1);
+ assert(NAME_MAX < XC_PAGE_SIZE >> 1);
while(dirent != NULL &&
- (PAGE_SIZE - ((unsigned long)buf & PAGE_MASK) > NAME_MAX))
+ (XC_PAGE_SIZE - ((unsigned long)buf & XC_PAGE_MASK) > NAME_MAX))
{
int curr_length = strlen(dirent->d_name) + 1;
diff -r 1e7a371cee11 -r 1970781956c7 tools/ioemu/hw/pc.c
--- a/tools/ioemu/hw/pc.c Wed Jul 23 11:21:47 2008 +0900
+++ b/tools/ioemu/hw/pc.c Wed Jul 23 12:10:20 2008 +0900
@@ -591,9 +591,9 @@ static void load_linux(const char *kerne
"qemu: real_addr = %#zx\n"
"qemu: cmdline_addr = %#zx\n"
"qemu: prot_addr = %#zx\n",
- real_addr,
- cmdline_addr,
- prot_addr);
+ (size_t)real_addr,
+ (size_t)cmdline_addr,
+ (size_t)prot_addr);
/* highest address for loading the initrd */
if (protocol >= 0x203)
diff -r 1e7a371cee11 -r 1970781956c7 tools/ioemu/hw/vga.c
--- a/tools/ioemu/hw/vga.c Wed Jul 23 11:21:47 2008 +0900
+++ b/tools/ioemu/hw/vga.c Wed Jul 23 12:10:20 2008 +0900
@@ -1511,51 +1511,52 @@ static void vga_draw_graphic(VGAState *s
width, height, v, line_offset, s->cr[9], s->cr[0x17],
s->line_compare, s->sr[0x01]);
#endif
- if (height - 1 > s->line_compare || multi_run || (s->cr[0x17] & 3) != 3
- || !s->lfb_addr) {
- /* Tricky things happen, just track all video memory */
- start = 0;
- end = s->vram_size;
- } else {
- /* Tricky things won't have any effect, i.e. we are in the very simple
- * (and very usual) case of a linear buffer. */
- /* use page table dirty bit tracking for the LFB plus border */
- start = (s->start_addr * 4) & TARGET_PAGE_MASK;
- end = ((s->start_addr * 4 + height * line_offset) + TARGET_PAGE_SIZE -
1) & TARGET_PAGE_MASK;
- }
-
- for (y = 0 ; y < start; y += TARGET_PAGE_SIZE)
- /* We will not read that anyway. */
- cpu_physical_memory_set_dirty(s->vram_offset + y);
-
- {
- unsigned long npages = (end - y) / TARGET_PAGE_SIZE;
- const int width = sizeof(unsigned long) * 8;
- unsigned long bitmap[(npages + width - 1) / width];
- int err;
-
- if (!(err = xc_hvm_track_dirty_vram(xc_handle, domid,
- (s->lfb_addr + y) / TARGET_PAGE_SIZE, npages, bitmap))) {
- int i, j;
- for (i = 0; i < sizeof(bitmap) / sizeof(*bitmap); i++) {
- unsigned long map = bitmap[i];
- for (j = i * width; map && j < npages; map >>= 1, j++)
- if (map & 1)
- cpu_physical_memory_set_dirty(s->vram_offset + y
- + j * TARGET_PAGE_SIZE);
+ if (s->lfb_addr) {
+ if (height - 1 > s->line_compare || multi_run || (s->cr[0x17] & 3) !=
3) {
+ /* Tricky things happen, just track all video memory */
+ start = 0;
+ end = s->vram_size;
+ } else {
+ /* Tricky things won't have any effect, i.e. we are in the very
simple
+ * (and very usual) case of a linear buffer. */
+ /* use page table dirty bit tracking for the LFB plus border */
+ start = (s->start_addr * 4) & TARGET_PAGE_MASK;
+ end = ((s->start_addr * 4 + height * line_offset) +
TARGET_PAGE_SIZE - 1) & TARGET_PAGE_MASK;
+ }
+
+ for (y = 0 ; y < start; y += TARGET_PAGE_SIZE)
+ /* We will not read that anyway. */
+ cpu_physical_memory_set_dirty(s->vram_offset + y);
+
+ {
+ unsigned long npages = (end - y) / TARGET_PAGE_SIZE;
+ const int width = sizeof(unsigned long) * 8;
+ unsigned long bitmap[(npages + width - 1) / width];
+ int err;
+
+ if (!(err = xc_hvm_track_dirty_vram(xc_handle, domid,
+ (s->lfb_addr + y) / TARGET_PAGE_SIZE, npages,
bitmap))) {
+ int i, j;
+ for (i = 0; i < sizeof(bitmap) / sizeof(*bitmap); i++) {
+ unsigned long map = bitmap[i];
+ for (j = i * width; map && j < npages; map >>= 1, j++)
+ if (map & 1)
+ cpu_physical_memory_set_dirty(s->vram_offset + y
+ + j * TARGET_PAGE_SIZE);
+ }
+ y += npages * TARGET_PAGE_SIZE;
+ } else {
+ /* ENODATA just means we have changed mode and will succeed
+ * next time */
+ if (err != -ENODATA)
+ fprintf(stderr, "track_dirty_vram(%lx, %lx) failed
(%d)\n", s->lfb_addr + y, npages, err);
}
- y += npages * TARGET_PAGE_SIZE;
- } else {
- /* ENODATA just means we have changed mode and will succeed
- * next time */
- if (err != -ENODATA)
- fprintf(stderr, "track_dirty_vram(%lx, %lx) failed (%d)\n",
s->lfb_addr + y, npages, err);
- }
- }
-
- for ( ; y < s->vram_size; y += TARGET_PAGE_SIZE)
- /* We will not read that anyway. */
- cpu_physical_memory_set_dirty(s->vram_offset + y);
+ }
+
+ for ( ; y < s->vram_size; y += TARGET_PAGE_SIZE)
+ /* We will not read that anyway. */
+ cpu_physical_memory_set_dirty(s->vram_offset + y);
+ }
addr1 = (s->start_addr * 4);
bwidth = (width * bits + 7) / 8;
diff -r 1e7a371cee11 -r 1970781956c7 tools/libxc/xc_linux.c
--- a/tools/libxc/xc_linux.c Wed Jul 23 11:21:47 2008 +0900
+++ b/tools/libxc/xc_linux.c Wed Jul 23 12:10:20 2008 +0900
@@ -418,9 +418,10 @@ void *xc_gnttab_map_grant_ref(int xcg_ha
return addr;
}
-void *xc_gnttab_map_grant_refs(int xcg_handle,
+static void *do_gnttab_map_grant_refs(int xcg_handle,
uint32_t count,
uint32_t *domids,
+ int domids_stride,
uint32_t *refs,
int prot)
{
@@ -435,7 +436,7 @@ void *xc_gnttab_map_grant_refs(int xcg_h
for ( i = 0; i < count; i++ )
{
- map->refs[i].domid = domids[i];
+ map->refs[i].domid = domids[i * domids_stride];
map->refs[i].ref = refs[i];
}
@@ -464,6 +465,24 @@ void *xc_gnttab_map_grant_refs(int xcg_h
return addr;
}
+void *xc_gnttab_map_grant_refs(int xcg_handle,
+ uint32_t count,
+ uint32_t *domids,
+ uint32_t *refs,
+ int prot)
+{
+ return do_gnttab_map_grant_refs(xcg_handle, count, domids, 1, refs, prot);
+}
+
+void *xc_gnttab_map_domain_grant_refs(int xcg_handle,
+ uint32_t count,
+ uint32_t domid,
+ uint32_t *refs,
+ int prot)
+{
+ return do_gnttab_map_grant_refs(xcg_handle, count, &domid, 0, refs, prot);
+}
+
int xc_gnttab_munmap(int xcg_handle,
void *start_address,
uint32_t count)
diff -r 1e7a371cee11 -r 1970781956c7 tools/libxc/xenctrl.h
--- a/tools/libxc/xenctrl.h Wed Jul 23 11:21:47 2008 +0900
+++ b/tools/libxc/xenctrl.h Wed Jul 23 12:10:20 2008 +0900
@@ -865,6 +865,23 @@ void *xc_gnttab_map_grant_refs(int xcg_h
uint32_t *refs,
int prot);
+/**
+ * Memory maps one or more grant references from one domain to a
+ * contiguous local address range. Mappings should be unmapped with
+ * xc_gnttab_munmap. Returns NULL on failure.
+ *
+ * @parm xcg_handle a handle on an open grant table interface
+ * @parm count the number of grant references to be mapped
+ * @parm domid the domain to map memory from
+ * @parm refs an array of @count grant references to be mapped
+ * @parm prot same flag as in mmap()
+ */
+void *xc_gnttab_map_domain_grant_refs(int xcg_handle,
+ uint32_t count,
+ uint32_t domid,
+ uint32_t *refs,
+ int prot);
+
/*
* Unmaps the @count pages starting at @start_address, which were mapped by a
* call to xc_gnttab_map_grant_ref or xc_gnttab_map_grant_refs. Returns zero
diff -r 1e7a371cee11 -r 1970781956c7 tools/python/xen/xend/XendNode.py
--- a/tools/python/xen/xend/XendNode.py Wed Jul 23 11:21:47 2008 +0900
+++ b/tools/python/xen/xend/XendNode.py Wed Jul 23 12:10:20 2008 +0900
@@ -23,6 +23,7 @@ from xen.util import Brctl
from xen.util import Brctl
from xen.util import pci as PciUtil
from xen.xend import XendAPIStore
+from xen.xend import osdep
import uuid, arch
from XendPBD import XendPBD
@@ -91,7 +92,7 @@ class XendNode:
for cpu_uuid, cpu in saved_cpus.items():
self.cpus[cpu_uuid] = cpu
- cpuinfo = parse_proc_cpuinfo()
+ cpuinfo = osdep.get_cpuinfo()
physinfo = self.physinfo_dict()
cpu_count = physinfo['nr_cpus']
cpu_features = physinfo['hw_caps']
@@ -743,31 +744,6 @@ class XendNode:
def info_dict(self):
return dict(self.info())
-def parse_proc_cpuinfo():
- cpuinfo = {}
- f = file('/proc/cpuinfo', 'r')
- try:
- p = -1
- d = {}
- for line in f:
- keyvalue = line.split(':')
- if len(keyvalue) != 2:
- continue
- key = keyvalue[0].strip()
- val = keyvalue[1].strip()
- if key == 'processor':
- if p != -1:
- cpuinfo[p] = d
- p = int(val)
- d = {}
- else:
- d[key] = val
- cpuinfo[p] = d
- return cpuinfo
- finally:
- f.close()
-
-
def instance():
global inst
try:
diff -r 1e7a371cee11 -r 1970781956c7 tools/python/xen/xend/balloon.py
--- a/tools/python/xen/xend/balloon.py Wed Jul 23 11:21:47 2008 +0900
+++ b/tools/python/xen/xend/balloon.py Wed Jul 23 12:10:20 2008 +0900
@@ -39,11 +39,11 @@ SLEEP_TIME_GROWTH = 0.1
# A mapping between easy-to-remember labels and the more verbose
# label actually shown in the PROC_XEN_BALLOON file.
-labels = { 'current' : 'Current allocation',
- 'target' : 'Requested target',
- 'low-balloon' : 'Low-mem balloon',
- 'high-balloon' : 'High-mem balloon',
- 'limit' : 'Xen hard limit' }
+#labels = { 'current' : 'Current allocation',
+# 'target' : 'Requested target',
+# 'low-balloon' : 'Low-mem balloon',
+# 'high-balloon' : 'High-mem balloon',
+# 'limit' : 'Xen hard limit' }
def _get_proc_balloon(label):
"""Returns the value for the named label. Returns None if the label was
@@ -54,7 +54,7 @@ def get_dom0_current_alloc():
def get_dom0_current_alloc():
"""Returns the current memory allocation (in KiB) of dom0."""
- kb = _get_proc_balloon(labels['current'])
+ kb = _get_proc_balloon('current')
if kb == None:
raise VmError('Failed to query current memory allocation of dom0.')
return kb
@@ -62,7 +62,7 @@ def get_dom0_target_alloc():
def get_dom0_target_alloc():
"""Returns the target memory allocation (in KiB) of dom0."""
- kb = _get_proc_balloon(labels['target'])
+ kb = _get_proc_balloon('target')
if kb == None:
raise VmError('Failed to query target memory allocation of dom0.')
return kb
diff -r 1e7a371cee11 -r 1970781956c7 tools/python/xen/xend/image.py
--- a/tools/python/xen/xend/image.py Wed Jul 23 11:21:47 2008 +0900
+++ b/tools/python/xen/xend/image.py Wed Jul 23 12:10:20 2008 +0900
@@ -265,9 +265,12 @@ class ImageHandler:
has_vnc = int(vmConfig['platform'].get('vnc', 0)) != 0
has_sdl = int(vmConfig['platform'].get('sdl', 0)) != 0
opengl = 1
+ keymap = vmConfig['platform'].get("keymap")
for dev_uuid in vmConfig['console_refs']:
dev_type, dev_info = vmConfig['devices'][dev_uuid]
if dev_type == 'vfb':
+ if 'keymap' in dev_info:
+ keymap = dev_info.get('keymap',{})
vfb_type = dev_info.get('type', {})
if vfb_type == 'sdl':
self.display = dev_info.get('display', {})
@@ -279,7 +282,6 @@ class ImageHandler:
has_vnc = True
break
- keymap = vmConfig['platform'].get("keymap")
if keymap:
ret.append("-k")
ret.append(keymap)
diff -r 1e7a371cee11 -r 1970781956c7 tools/python/xen/xend/osdep.py
--- a/tools/python/xen/xend/osdep.py Wed Jul 23 11:21:47 2008 +0900
+++ b/tools/python/xen/xend/osdep.py Wed Jul 23 12:10:20 2008 +0900
@@ -41,12 +41,18 @@ def _linux_balloon_stat(label):
def _linux_balloon_stat(label):
"""Returns the value for the named label, or None if an error occurs."""
+ xend2linux_labels = { 'current' : 'Current allocation',
+ 'target' : 'Requested target',
+ 'low-balloon' : 'Low-mem balloon',
+ 'high-balloon' : 'High-mem balloon',
+ 'limit' : 'Xen hard limit' }
+
PROC_XEN_BALLOON = '/proc/xen/balloon'
f = file(PROC_XEN_BALLOON, 'r')
try:
for line in f:
keyvalue = line.split(':')
- if keyvalue[0] == label:
+ if keyvalue[0] == xend2linux_labels[label]:
values = keyvalue[1].split()
if values[0].isdigit():
return int(values[0])
@@ -67,11 +73,11 @@ def _solaris_balloon_stat(label):
BLN_IOCTL_LOW = 0x42410003
BLN_IOCTL_HIGH = 0x42410004
BLN_IOCTL_LIMIT = 0x42410005
- label_to_ioctl = { 'Current allocation' : BLN_IOCTL_CURRENT,
- 'Requested target' : BLN_IOCTL_TARGET,
- 'Low-mem balloon' : BLN_IOCTL_LOW,
- 'High-mem balloon' : BLN_IOCTL_HIGH,
- 'Xen hard limit' : BLN_IOCTL_LIMIT }
+ label_to_ioctl = { 'current' : BLN_IOCTL_CURRENT,
+ 'target' : BLN_IOCTL_TARGET,
+ 'low-balloon' : BLN_IOCTL_LOW,
+ 'high-balloon' : BLN_IOCTL_HIGH,
+ 'limit' : BLN_IOCTL_LIMIT }
f = file(DEV_XEN_BALLOON, 'r')
try:
@@ -87,6 +93,33 @@ _balloon_stat = {
"SunOS": _solaris_balloon_stat
}
+def _linux_get_cpuinfo():
+ cpuinfo = {}
+ f = file('/proc/cpuinfo', 'r')
+ try:
+ p = -1
+ d = {}
+ for line in f:
+ keyvalue = line.split(':')
+ if len(keyvalue) != 2:
+ continue
+ key = keyvalue[0].strip()
+ val = keyvalue[1].strip()
+ if key == 'processor':
+ if p != -1:
+ cpuinfo[p] = d
+ p = int(val)
+ d = {}
+ else:
+ d[key] = val
+ cpuinfo[p] = d
+ return cpuinfo
+ finally:
+ f.close()
+
+_get_cpuinfo = {
+}
+
def _get(var, default=None):
return var.get(os.uname()[0], default)
@@ -95,3 +128,4 @@ pygrub_path = _get(_pygrub_path, "/usr/b
pygrub_path = _get(_pygrub_path, "/usr/bin/pygrub")
vif_script = _get(_vif_script, "vif-bridge")
lookup_balloon_stat = _get(_balloon_stat, _linux_balloon_stat)
+get_cpuinfo = _get(_get_cpuinfo, _linux_get_cpuinfo)
diff -r 1e7a371cee11 -r 1970781956c7 tools/python/xen/xm/create.py
--- a/tools/python/xen/xm/create.py Wed Jul 23 11:21:47 2008 +0900
+++ b/tools/python/xen/xm/create.py Wed Jul 23 12:10:20 2008 +0900
@@ -325,7 +325,7 @@ gopts.var('irq', val='IRQ',
For example 'irq=7'.
This option may be repeated to add more than one IRQ.""")
-gopts.var('vfb',
val="type={vnc,sdl},vncunused=1,vncdisplay=N,vnclisten=ADDR,display=DISPLAY,xauthority=XAUTHORITY,vncpasswd=PASSWORD,opengl=1",
+gopts.var('vfb',
val="type={vnc,sdl},vncunused=1,vncdisplay=N,vnclisten=ADDR,display=DISPLAY,xauthority=XAUTHORITY,vncpasswd=PASSWORD,opengl=1,keymap=FILE",
fn=append_value, default=[],
use="""Make the domain a framebuffer backend.
The backend type should be either sdl or vnc.
@@ -336,7 +336,8 @@ gopts.var('vfb', val="type={vnc,sdl},vnc
default password.
For type=sdl, a viewer will be started automatically using the
given DISPLAY and XAUTHORITY, which default to the current user's
- ones. OpenGL will be used by default unless opengl is set to 0.""")
+ ones. OpenGL will be used by default unless opengl is set to 0.
+ keymap overrides the XendD configured default layout file.""")
gopts.var('vif',
val="type=TYPE,mac=MAC,bridge=BRIDGE,ip=IPADDR,script=SCRIPT," + \
"backend=DOM,vifname=NAME,rate=RATE,model=MODEL,accel=ACCEL",
@@ -741,7 +742,7 @@ def configure_vfbs(config_devs, vals):
for (k,v) in d.iteritems():
if not k in [ 'vnclisten', 'vncunused', 'vncdisplay', 'display',
'videoram', 'xauthority', 'type', 'vncpasswd',
- 'opengl' ]:
+ 'opengl', 'keymap' ]:
err("configuration option %s unknown to vfbs" % k)
config.append([k,v])
if not d.has_key("keymap"):
@@ -955,6 +956,10 @@ def preprocess_cpuid(vals, attr_name):
if reg_match == None:
err("cpuid's syntax is (eax|ebx|ecx|edx)=value")
res = reg_match.groupdict()
+ if (res['val'][:2] != '0x' and len(res['val']) != 32):
+ err("cpuid: We should specify all the bits " \
+ "of the register %s for input %s\n"
+ % (res['reg'], input) )
cpuid[input][res['reg']] = res['val'] # new register
setattr(vals, attr_name, cpuid)
diff -r 1e7a371cee11 -r 1970781956c7 xen/arch/x86/acpi/cpufreq/cpufreq.c
--- a/xen/arch/x86/acpi/cpufreq/cpufreq.c Wed Jul 23 11:21:47 2008 +0900
+++ b/xen/arch/x86/acpi/cpufreq/cpufreq.c Wed Jul 23 12:10:20 2008 +0900
@@ -237,9 +237,9 @@ static u32 get_cur_val(cpumask_t mask)
* Only IA32_APERF/IA32_MPERF ratio is architecturally defined and
* no meaning should be associated with absolute values of these MSRs.
*/
-/* FIXME: handle query on non-current cpu later */
-static unsigned int get_measured_perf(unsigned int cpu)
-{
+static void __get_measured_perf(void *perf_percent)
+{
+ unsigned int *ratio = perf_percent;
union {
struct {
uint32_t lo;
@@ -248,9 +248,6 @@ static unsigned int get_measured_perf(un
uint64_t whole;
} aperf_cur, mperf_cur;
- unsigned int perf_percent;
- unsigned int retval;
-
rdmsr(MSR_IA32_APERF, aperf_cur.split.lo, aperf_cur.split.hi);
rdmsr(MSR_IA32_MPERF, mperf_cur.split.lo, mperf_cur.split.hi);
@@ -264,10 +261,21 @@ static unsigned int get_measured_perf(un
}
if (aperf_cur.whole && mperf_cur.whole)
- perf_percent = (aperf_cur.whole * 100) / mperf_cur.whole;
+ *ratio = (aperf_cur.whole * 100) / mperf_cur.whole;
else
- perf_percent = 0;
-
+ *ratio = 0;
+}
+
+static unsigned int get_measured_perf(unsigned int cpu)
+{
+ unsigned int retval, perf_percent;
+ cpumask_t cpumask;
+
+ if (!cpu_online(cpu))
+ return 0;
+
+ cpumask = cpumask_of_cpu(cpu);
+ on_selected_cpus(cpumask, __get_measured_perf, (void *)&perf_percent,0,1);
retval = drv_data[cpu]->max_freq * perf_percent / 100;
return retval;
@@ -433,16 +441,13 @@ acpi_cpufreq_cpu_init(struct cpufreq_pol
perf = data->acpi_data;
policy->shared_type = perf->shared_type;
- /*
- * Will let policy->cpus know about dependency only when software
- * coordination is required.
+ /*
+ * Currently the latest linux (kernel version 2.6.26)
+ * still has issue when handle the situation _psd HW_ALL coordination.
+ * In Xen hypervisor, we handle _psd HW_ALL coordination in same way as
+ * _psd SW_ALL coordination for the seek of safety.
*/
- if (policy->shared_type == CPUFREQ_SHARED_TYPE_ALL ||
- policy->shared_type == CPUFREQ_SHARED_TYPE_ANY) {
- policy->cpus = perf->shared_cpu_map;
- } else {
- policy->cpus = cpumask_of_cpu(cpu);
- }
+ policy->cpus = perf->shared_cpu_map;
/* capability check */
if (perf->state_count <= 1) {
diff -r 1e7a371cee11 -r 1970781956c7 xen/arch/x86/domain.c
--- a/xen/arch/x86/domain.c Wed Jul 23 11:21:47 2008 +0900
+++ b/xen/arch/x86/domain.c Wed Jul 23 12:10:20 2008 +0900
@@ -286,10 +286,6 @@ int vcpu_initialise(struct vcpu *v)
v->arch.flags = TF_kernel_mode;
- /* Ensure that update_vcpu_system_time() fires at least once. */
- if ( !is_idle_domain(d) )
- vcpu_info(v, time).tsc_timestamp = ~0ull;
-
#if defined(__i386__)
mapcache_vcpu_init(v);
#endif
diff -r 1e7a371cee11 -r 1970781956c7 xen/arch/x86/i8259.c
--- a/xen/arch/x86/i8259.c Wed Jul 23 11:21:47 2008 +0900
+++ b/xen/arch/x86/i8259.c Wed Jul 23 12:10:20 2008 +0900
@@ -411,7 +411,7 @@ void __init init_IRQ(void)
apic_intr_init();
/* Set the clock to HZ Hz */
-#define CLOCK_TICK_RATE 1193180 /* crystal freq (Hz) */
+#define CLOCK_TICK_RATE 1193182 /* crystal freq (Hz) */
#define LATCH (((CLOCK_TICK_RATE)+(HZ/2))/HZ)
outb_p(0x34, PIT_MODE); /* binary, mode 2, LSB/MSB, ch 0 */
outb_p(LATCH & 0xff, PIT_CH0); /* LSB */
diff -r 1e7a371cee11 -r 1970781956c7 xen/arch/x86/setup.c
--- a/xen/arch/x86/setup.c Wed Jul 23 11:21:47 2008 +0900
+++ b/xen/arch/x86/setup.c Wed Jul 23 12:10:20 2008 +0900
@@ -521,14 +521,6 @@ void __init __start_xen(unsigned long mb
if ( ((unsigned long)cpu0_stack & (STACK_SIZE-1)) != 0 )
EARLY_FAIL("Misaligned CPU0 stack.\n");
- /*
- * Since there are some stubs getting built on the stacks which use
- * direct calls/jumps, the heap must be confined to the lower 2G so
- * that those branches can reach their targets.
- */
- if ( opt_xenheap_megabytes > 2048 )
- opt_xenheap_megabytes = 2048;
-
if ( e820_raw_nr != 0 )
{
memmap_type = "Xen-e820";
@@ -599,6 +591,23 @@ void __init __start_xen(unsigned long mb
/* Sanitise the raw E820 map to produce a final clean version. */
max_page = init_e820(memmap_type, e820_raw, &e820_raw_nr);
+
+#ifdef CONFIG_X86_64
+ /*
+ * On x86/64 we are able to account for the allocation bitmap
+ * (allocated in common/page_alloc.c:init_boot_allocator()) stealing
+ * from the Xen heap. Here we make the Xen heap appropriately larger.
+ */
+ opt_xenheap_megabytes += (max_page / 8) >> 20;
+#endif
+
+ /*
+ * Since there are some stubs getting built on the stacks which use
+ * direct calls/jumps, the heap must be confined to the lower 2G so
+ * that those branches can reach their targets.
+ */
+ if ( opt_xenheap_megabytes > 2048 )
+ opt_xenheap_megabytes = 2048;
/* Create a temporary copy of the E820 map. */
memcpy(&boot_e820, &e820, sizeof(e820));
diff -r 1e7a371cee11 -r 1970781956c7 xen/arch/x86/time.c
--- a/xen/arch/x86/time.c Wed Jul 23 11:21:47 2008 +0900
+++ b/xen/arch/x86/time.c Wed Jul 23 12:10:20 2008 +0900
@@ -214,7 +214,7 @@ static struct irqaction irq0 = { timer_i
* Return processor ticks per second / CALIBRATE_FRAC.
*/
-#define CLOCK_TICK_RATE 1193180 /* system crystal frequency (Hz) */
+#define CLOCK_TICK_RATE 1193182 /* system crystal frequency (Hz) */
#define CALIBRATE_FRAC 20 /* calibrate over 50ms */
#define CALIBRATE_LATCH ((CLOCK_TICK_RATE+(CALIBRATE_FRAC/2))/CALIBRATE_FRAC)
@@ -484,40 +484,29 @@ static int init_pmtimer(struct platform_
* PLATFORM TIMER 5: TSC
*/
-#define platform_timer_is_tsc() (!strcmp(plt_src.name, "TSC"))
-static u64 tsc_freq;
-
-static u64 read_tsc_count(void)
-{
+static const char plt_tsc_name[] = "TSC";
+#define platform_timer_is_tsc() (plt_src.name == plt_tsc_name)
+
+static int init_tsctimer(struct platform_timesource *pts)
+{
+ if ( !tsc_invariant )
+ return 0;
+
+ pts->name = (char *)plt_tsc_name;
+ return 1;
+}
+
+static void make_tsctimer_record(void)
+{
+ struct cpu_time *t = &this_cpu(cpu_time);
+ s_time_t now;
u64 tsc;
+
rdtscll(tsc);
- return tsc;
-}
-
-static int init_tsctimer(struct platform_timesource *pts)
-{
- unsigned int cpu;
-
- /*
- * TODO: evaluate stability of TSC here, return 0 if not stable.
- * For now we assume all TSCs are synchronised and hence can all share
- * CPU 0's calibration values.
- */
- for_each_cpu ( cpu )
- {
- if ( cpu == 0 )
- continue;
- memcpy(&per_cpu(cpu_time, cpu),
- &per_cpu(cpu_time, 0),
- sizeof(struct cpu_time));
- }
-
- pts->name = "TSC";
- pts->frequency = tsc_freq;
- pts->read_counter = read_tsc_count;
- pts->counter_bits = 64;
-
- return 1;
+ now = scale_delta(tsc, &t->tsc_scale);
+
+ t->local_tsc_stamp = tsc;
+ t->stime_local_stamp = t->stime_master_stamp = now;
}
/************************************************************
@@ -585,6 +574,12 @@ static void platform_time_calibration(vo
static void resume_platform_timer(void)
{
+ if ( platform_timer_is_tsc() )
+ {
+ /* TODO: Save/restore TSC values. */
+ return;
+ }
+
/* No change in platform_stime across suspend/resume. */
platform_timer_stamp = plt_stamp64;
plt_stamp = plt_src.read_counter();
@@ -619,6 +614,12 @@ static void init_platform_timer(void)
!init_hpet(pts) &&
!init_pmtimer(pts) )
init_pit(pts);
+
+ if ( platform_timer_is_tsc() )
+ {
+ printk("Platform timer is TSC\n");
+ return;
+ }
plt_mask = (u64)~0ull >> (64 - pts->counter_bits);
@@ -907,6 +908,14 @@ static void local_time_calibration(void
/* The overall calibration scale multiplier. */
u32 calibration_mul_frac;
+ if ( platform_timer_is_tsc() )
+ {
+ make_tsctimer_record();
+ update_vcpu_system_time(current);
+ set_timer(&t->calibration_timer, NOW() + MILLISECS(10*1000));
+ return;
+ }
+
prev_tsc = t->local_tsc_stamp;
prev_local_stime = t->stime_local_stamp;
prev_master_stime = t->stime_master_stamp;
@@ -1025,16 +1034,20 @@ void init_percpu_time(void)
s_time_t now;
if ( platform_timer_is_tsc() )
- return;
+ {
+ make_tsctimer_record();
+ goto out;
+ }
local_irq_save(flags);
rdtscll(t->local_tsc_stamp);
- now = read_platform_stime();
+ now = !plt_src.read_counter ? 0 : read_platform_stime();
local_irq_restore(flags);
t->stime_master_stamp = now;
t->stime_local_stamp = now;
+ out:
init_timer(&t->calibration_timer, local_time_calibration,
NULL, smp_processor_id());
set_timer(&t->calibration_timer, NOW() + EPOCH);
@@ -1043,19 +1056,19 @@ void init_percpu_time(void)
/* Late init function (after all CPUs are booted). */
int __init init_xen_time(void)
{
- wc_sec = get_cmos_time();
-
local_irq_disable();
+
+ /* check if TSC is invariant during deep C state
+ this is a new feature introduced by Nehalem*/
+ if ( cpuid_edx(0x80000007) & (1u<<8) )
+ tsc_invariant = 1;
+
+ init_percpu_time();
stime_platform_stamp = 0;
init_platform_timer();
- init_percpu_time();
-
- /* check if TSC is invariant during deep C state
- this is a new feature introduced by Nehalem*/
- if ( cpuid_edx(0x80000007) & (1U<<8) )
- tsc_invariant = 1;
+ do_settime(get_cmos_time(), 0, NOW());
local_irq_enable();
@@ -1068,7 +1081,6 @@ void __init early_time_init(void)
{
u64 tmp = init_pit_and_calibrate_tsc();
- tsc_freq = tmp;
set_time_scale(&this_cpu(cpu_time).tsc_scale, tmp);
do_div(tmp, 1000);
@@ -1170,9 +1182,9 @@ int time_resume(void)
resume_platform_timer();
- do_settime(get_cmos_time() + cmos_utc_offset, 0, read_platform_stime());
-
init_percpu_time();
+
+ do_settime(get_cmos_time() + cmos_utc_offset, 0, NOW());
if ( !is_idle_vcpu(current) )
update_vcpu_system_time(current);
diff -r 1e7a371cee11 -r 1970781956c7 xen/common/keyhandler.c
--- a/xen/common/keyhandler.c Wed Jul 23 11:21:47 2008 +0900
+++ b/xen/common/keyhandler.c Wed Jul 23 12:10:20 2008 +0900
@@ -240,10 +240,12 @@ static void read_clocks_slave(void *unus
static void read_clocks_slave(void *unused)
{
unsigned int cpu = smp_processor_id();
+ local_irq_disable();
while ( !cpu_isset(cpu, read_clocks_cpumask) )
cpu_relax();
read_clocks_time[cpu] = NOW();
cpu_clear(cpu, read_clocks_cpumask);
+ local_irq_enable();
}
static void read_clocks(unsigned char key)
diff -r 1e7a371cee11 -r 1970781956c7 xen/drivers/passthrough/amd/pci_amd_iommu.c
--- a/xen/drivers/passthrough/amd/pci_amd_iommu.c Wed Jul 23 11:21:47
2008 +0900
+++ b/xen/drivers/passthrough/amd/pci_amd_iommu.c Wed Jul 23 12:10:20
2008 +0900
@@ -620,11 +620,49 @@ static int amd_iommu_return_device(
static int amd_iommu_add_device(struct pci_dev *pdev)
{
+ struct amd_iommu *iommu;
+ u16 bdf;
+ if ( !pdev->domain )
+ return -EINVAL;
+
+ bdf = (pdev->bus << 8) | pdev->devfn;
+ iommu = (bdf < ivrs_bdf_entries) ?
+ find_iommu_for_device(pdev->bus, pdev->devfn) : NULL;
+
+ if ( !iommu )
+ {
+ amd_iov_error("Fail to find iommu."
+ " %x:%x.%x cannot be assigned to domain %d\n",
+ pdev->bus, PCI_SLOT(pdev->devfn),
+ PCI_FUNC(pdev->devfn), pdev->domain->domain_id);
+ return -ENODEV;
+ }
+
+ amd_iommu_setup_domain_device(pdev->domain, iommu, bdf);
return 0;
}
static int amd_iommu_remove_device(struct pci_dev *pdev)
{
+ struct amd_iommu *iommu;
+ u16 bdf;
+ if ( !pdev->domain )
+ return -EINVAL;
+
+ bdf = (pdev->bus << 8) | pdev->devfn;
+ iommu = (bdf < ivrs_bdf_entries) ?
+ find_iommu_for_device(pdev->bus, pdev->devfn) : NULL;
+
+ if ( !iommu )
+ {
+ amd_iov_error("Fail to find iommu."
+ " %x:%x.%x cannot be removed from domain %d\n",
+ pdev->bus, PCI_SLOT(pdev->devfn),
+ PCI_FUNC(pdev->devfn), pdev->domain->domain_id);
+ return -ENODEV;
+ }
+
+ amd_iommu_disable_domain_device(pdev->domain, iommu, bdf);
return 0;
}
diff -r 1e7a371cee11 -r 1970781956c7 xen/drivers/passthrough/vtd/dmar.h
--- a/xen/drivers/passthrough/vtd/dmar.h Wed Jul 23 11:21:47 2008 +0900
+++ b/xen/drivers/passthrough/vtd/dmar.h Wed Jul 23 12:10:20 2008 +0900
@@ -76,7 +76,7 @@ struct acpi_atsr_unit {
#define for_each_rmrr_device(rmrr, bdf, idx) \
list_for_each_entry(rmrr, &acpi_rmrr_units, list) \
/* assume there never is a bdf == 0 */ \
- for (idx = 0; (bdf = rmrr->scope.devices[i]) && \
+ for (idx = 0; (bdf = rmrr->scope.devices[idx]) && \
idx < rmrr->scope.devices_cnt; idx++)
struct acpi_drhd_unit * acpi_find_matched_drhd_unit(u8 bus, u8 devfn);
diff -r 1e7a371cee11 -r 1970781956c7 xen/drivers/passthrough/vtd/iommu.c
--- a/xen/drivers/passthrough/vtd/iommu.c Wed Jul 23 11:21:47 2008 +0900
+++ b/xen/drivers/passthrough/vtd/iommu.c Wed Jul 23 12:10:20 2008 +0900
@@ -1294,11 +1294,18 @@ static int domain_context_mapping(struct
return ret;
}
-static int domain_context_unmap_one(struct iommu *iommu, u8 bus, u8 devfn)
+static int domain_context_unmap_one(
+ struct domain *domain,
+ struct iommu *iommu,
+ u8 bus, u8 devfn)
{
struct context_entry *context, *context_entries;
unsigned long flags;
u64 maddr;
+ struct acpi_rmrr_unit *rmrr;
+ u16 bdf;
+ int i;
+ unsigned int is_rmrr_device = 0;
maddr = bus_to_context_maddr(iommu, bus);
context_entries = (struct context_entry *)map_vtd_domain_page(maddr);
@@ -1311,18 +1318,32 @@ static int domain_context_unmap_one(stru
}
spin_lock_irqsave(&iommu->lock, flags);
- context_clear_present(*context);
- context_clear_entry(*context);
- iommu_flush_cache_entry(context);
- iommu_flush_context_global(iommu, 0);
- iommu_flush_iotlb_global(iommu, 0);
+ if ( domain->domain_id == 0 )
+ {
+ for_each_rmrr_device ( rmrr, bdf, i )
+ {
+ if ( PCI_BUS(bdf) == bus && PCI_DEVFN2(bdf) == devfn )
+ {
+ is_rmrr_device = 1;
+ break;
+ }
+ }
+ }
+ if ( !is_rmrr_device )
+ {
+ context_clear_present(*context);
+ context_clear_entry(*context);
+ iommu_flush_cache_entry(context);
+ iommu_flush_context_domain(iommu, domain_iommu_domid(domain), 0);
+ iommu_flush_iotlb_dsi(iommu, domain_iommu_domid(domain), 0);
+ }
unmap_vtd_domain_page(context_entries);
spin_unlock_irqrestore(&iommu->lock, flags);
return 0;
}
-static int domain_context_unmap(u8 bus, u8 devfn)
+static int domain_context_unmap(struct domain *domain, u8 bus, u8 devfn)
{
struct acpi_drhd_unit *drhd;
u16 sec_bus, sub_bus;
@@ -1345,18 +1366,18 @@ static int domain_context_unmap(u8 bus,
PCI_SUBORDINATE_BUS);
/*dmar_scope_remove_buses(&drhd->scope, sec_bus, sub_bus);*/
if ( DEV_TYPE_PCI_BRIDGE )
- ret = domain_context_unmap_one(drhd->iommu, bus, devfn);
+ ret = domain_context_unmap_one(domain, drhd->iommu, bus, devfn);
break;
case DEV_TYPE_PCIe_ENDPOINT:
- ret = domain_context_unmap_one(drhd->iommu, bus, devfn);
+ ret = domain_context_unmap_one(domain, drhd->iommu, bus, devfn);
break;
case DEV_TYPE_PCI:
if ( find_pcie_endpoint(&bus, &devfn, &secbus) )
- ret = domain_context_unmap_one(drhd->iommu, bus, devfn);
+ ret = domain_context_unmap_one(domain, drhd->iommu, bus, devfn);
if ( bus != secbus )
- domain_context_unmap_one(drhd->iommu, secbus, 0);
+ domain_context_unmap_one(domain, drhd->iommu, secbus, 0);
break;
default:
@@ -1386,7 +1407,7 @@ static int reassign_device_ownership(
drhd = acpi_find_matched_drhd_unit(bus, devfn);
pdev_iommu = drhd->iommu;
- domain_context_unmap(bus, devfn);
+ domain_context_unmap(source, bus, devfn);
write_lock(&pcidevs_lock);
list_move(&pdev->domain_list, &target->arch.pdev_list);
@@ -1584,7 +1605,9 @@ static int intel_iommu_add_device(struct
static int intel_iommu_remove_device(struct pci_dev *pdev)
{
- return domain_context_unmap(pdev->bus, pdev->devfn);
+ if ( !pdev->domain )
+ return -EINVAL;
+ return domain_context_unmap(pdev->domain, pdev->bus, pdev->devfn);
}
static void setup_dom0_devices(struct domain *d)
diff -r 1e7a371cee11 -r 1970781956c7 xen/include/asm-x86/hvm/vpt.h
--- a/xen/include/asm-x86/hvm/vpt.h Wed Jul 23 11:21:47 2008 +0900
+++ b/xen/include/asm-x86/hvm/vpt.h Wed Jul 23 12:10:20 2008 +0900
@@ -95,7 +95,7 @@ struct periodic_time {
};
-#define PIT_FREQ 1193181
+#define PIT_FREQ 1193182
#define PIT_BASE 0x40
typedef struct PITState {
diff -r 1e7a371cee11 -r 1970781956c7 xen/include/public/xsm/flask_op.h
--- a/xen/include/public/xsm/flask_op.h Wed Jul 23 11:21:47 2008 +0900
+++ b/xen/include/public/xsm/flask_op.h Wed Jul 23 12:10:20 2008 +0900
@@ -32,10 +32,12 @@
#define FLASK_AVC_CACHESTATS 19
#define FLASK_MEMBER 20
+#define FLASK_LAST FLASK_MEMBER
+
typedef struct flask_op {
- int cmd;
- int size;
- char *buf;
+ uint32_t cmd;
+ uint32_t size;
+ char *buf;
} flask_op_t;
DEFINE_XEN_GUEST_HANDLE(flask_op_t);
diff -r 1e7a371cee11 -r 1970781956c7 xen/include/xen/pci.h
--- a/xen/include/xen/pci.h Wed Jul 23 11:21:47 2008 +0900
+++ b/xen/include/xen/pci.h Wed Jul 23 12:10:20 2008 +0900
@@ -24,10 +24,10 @@
#define PCI_BUS(bdf) (((bdf) >> 8) & 0xff)
#define PCI_SLOT(bdf) (((bdf) >> 3) & 0x1f)
#define PCI_FUNC(bdf) ((bdf) & 0x07)
-#define PCI_DEVFN(d,f) (((d & 0x1f) << 3) | (f & 0x07))
+#define PCI_DEVFN(d,f) ((((d) & 0x1f) << 3) | ((f) & 0x07))
#define PCI_DEVFN2(bdf) ((bdf) & 0xff)
-#define PCI_BDF(b,d,f) (((b * 0xff) << 8) | PCI_DEVFN(d,f))
-#define PCI_BDF2(b,df) (((b & 0xff) << 8) | (df & 0xff))
+#define PCI_BDF(b,d,f) ((((b) & 0xff) << 8) | PCI_DEVFN(d,f))
+#define PCI_BDF2(b,df) ((((b) & 0xff) << 8) | ((df) & 0xff))
struct pci_dev {
struct list_head alldevs_list;
diff -r 1e7a371cee11 -r 1970781956c7 xen/include/xsm/xsm.h
--- a/xen/include/xsm/xsm.h Wed Jul 23 11:21:47 2008 +0900
+++ b/xen/include/xsm/xsm.h Wed Jul 23 12:10:20 2008 +0900
@@ -108,7 +108,6 @@ struct xsm_operations {
int (*schedop_shutdown) (struct domain *d1, struct domain *d2);
long (*__do_xsm_op) (XEN_GUEST_HANDLE(xsm_op_t) op);
- void (*complete_init) (struct domain *d);
#ifdef CONFIG_X86
int (*shadow_control) (struct domain *d, uint32_t op);
@@ -392,11 +391,6 @@ static inline long __do_xsm_op (XEN_GUES
return xsm_call(__do_xsm_op(op));
}
-static inline void xsm_complete_init (struct domain *d)
-{
- xsm_call(complete_init(d));
-}
-
#ifdef XSM_ENABLE
extern int xsm_init(unsigned int *initrdidx, const multiboot_info_t *mbi,
unsigned long initial_images_start);
diff -r 1e7a371cee11 -r 1970781956c7 xen/xsm/dummy.c
--- a/xen/xsm/dummy.c Wed Jul 23 11:21:47 2008 +0900
+++ b/xen/xsm/dummy.c Wed Jul 23 12:10:20 2008 +0900
@@ -250,11 +250,6 @@ static int dummy_alloc_security_evtchn (
}
static void dummy_free_security_evtchn (struct evtchn *chn)
-{
- return;
-}
-
-static void dummy_complete_init (struct domain *d)
{
return;
}
@@ -462,7 +457,6 @@ void xsm_fixup_ops (struct xsm_operation
set_to_dummy_if_null(ops, schedop_shutdown);
set_to_dummy_if_null(ops, __do_xsm_op);
- set_to_dummy_if_null(ops, complete_init);
#ifdef CONFIG_X86
set_to_dummy_if_null(ops, shadow_control);
diff -r 1e7a371cee11 -r 1970781956c7 xen/xsm/flask/avc.c
--- a/xen/xsm/flask/avc.c Wed Jul 23 11:21:47 2008 +0900
+++ b/xen/xsm/flask/avc.c Wed Jul 23 12:10:20 2008 +0900
@@ -250,7 +250,7 @@ void __init avc_init(void)
printk("AVC INITIALIZED\n");
}
-int avc_get_hash_stats(char *page)
+int avc_get_hash_stats(char *buf, uint32_t size)
{
int i, chain_len, max_chain_len, slots_used;
struct avc_node *node;
@@ -274,7 +274,7 @@ int avc_get_hash_stats(char *page)
rcu_read_unlock();
- return snprintf(page, PAGE_SIZE, "entries: %d\nbuckets used: %d/%d\n"
+ return snprintf(buf, size, "entries: %d\nbuckets used: %d/%d\n"
"longest chain: %d\n",
atomic_read(&avc_cache.active_nodes),
slots_used, AVC_CACHE_SLOTS, max_chain_len);
diff -r 1e7a371cee11 -r 1970781956c7 xen/xsm/flask/flask_op.c
--- a/xen/xsm/flask/flask_op.c Wed Jul 23 11:21:47 2008 +0900
+++ b/xen/xsm/flask/flask_op.c Wed Jul 23 12:10:20 2008 +0900
@@ -29,6 +29,43 @@ integer_param("flask_enabled", flask_ena
integer_param("flask_enabled", flask_enabled);
#endif
+#define MAX_POLICY_SIZE 0x4000000
+#define FLASK_COPY_IN \
+ ( \
+ 1UL<<FLASK_LOAD | \
+ 1UL<<FLASK_SETENFORCE | \
+ 1UL<<FLASK_CONTEXT_TO_SID | \
+ 1UL<<FLASK_SID_TO_CONTEXT | \
+ 1UL<<FLASK_ACCESS | \
+ 1UL<<FLASK_CREATE | \
+ 1UL<<FLASK_RELABEL | \
+ 1UL<<FLASK_USER | \
+ 1UL<<FLASK_GETBOOL | \
+ 1UL<<FLASK_SETBOOL | \
+ 1UL<<FLASK_COMMITBOOLS | \
+ 1UL<<FLASK_DISABLE | \
+ 1UL<<FLASK_SETAVC_THRESHOLD | \
+ 1UL<<FLASK_MEMBER \
+ )
+
+#define FLASK_COPY_OUT \
+ ( \
+ 1UL<<FLASK_GETENFORCE | \
+ 1UL<<FLASK_CONTEXT_TO_SID | \
+ 1UL<<FLASK_SID_TO_CONTEXT | \
+ 1UL<<FLASK_ACCESS | \
+ 1UL<<FLASK_CREATE | \
+ 1UL<<FLASK_RELABEL | \
+ 1UL<<FLASK_USER | \
+ 1UL<<FLASK_POLICYVERS | \
+ 1UL<<FLASK_GETBOOL | \
+ 1UL<<FLASK_MLS | \
+ 1UL<<FLASK_GETAVC_THRESHOLD | \
+ 1UL<<FLASK_AVC_HASHSTATS | \
+ 1UL<<FLASK_AVC_CACHESTATS | \
+ 1UL<<FLASK_MEMBER \
+ )
+
static DEFINE_SPINLOCK(sel_sem);
/* global data for booleans */
@@ -51,7 +88,7 @@ static int domain_has_security(struct do
perms, NULL);
}
-static int flask_security_user(char *buf, int size)
+static int flask_security_user(char *buf, uint32_t size)
{
char *page = NULL;
char *con, *user, *ptr;
@@ -82,12 +119,8 @@ static int flask_security_user(char *buf
goto out2;
memset(page, 0, PAGE_SIZE);
- length = -EFAULT;
- if ( copy_from_user(page, buf, size) )
- goto out2;
-
length = -EINVAL;
- if ( sscanf(page, "%s %s", con, user) != 2 )
+ if ( sscanf(buf, "%s %s", con, user) != 2 )
goto out2;
length = security_context_to_sid(con, strlen(con)+1, &sid);
@@ -98,7 +131,6 @@ static int flask_security_user(char *buf
if ( length < 0 )
goto out2;
- memset(page, 0, PAGE_SIZE);
length = snprintf(page, PAGE_SIZE, "%u", nsids) + 1;
ptr = page + length;
for ( i = 0; i < nsids; i++ )
@@ -121,8 +153,16 @@ static int flask_security_user(char *buf
length += len;
}
- if ( copy_to_user(buf, page, length) )
- length = -EFAULT;
+ if ( length > size )
+ {
+ printk( "%s: context size (%u) exceeds payload "
+ "max\n", __FUNCTION__, length);
+ length = -ERANGE;
+ goto out3;
+ }
+
+ memset(buf, 0, size);
+ memcpy(buf, page, length);
out3:
xfree(sids);
@@ -135,7 +175,7 @@ out:
return length;
}
-static int flask_security_relabel(char *buf, int size)
+static int flask_security_relabel(char *buf, uint32_t size)
{
char *scon, *tcon;
u32 ssid, tsid, newsid;
@@ -178,15 +218,81 @@ static int flask_security_relabel(char *
if ( length < 0 )
goto out2;
- if ( len > PAGE_SIZE )
- {
+ if ( len > size )
+ {
+ printk( "%s: context size (%u) exceeds payload "
+ "max\n", __FUNCTION__, len);
length = -ERANGE;
goto out3;
}
-
- if ( copy_to_user(buf, newcon, len) )
- len = -EFAULT;
-
+
+ memset(buf, 0, size);
+ memcpy(buf, newcon, len);
+ length = len;
+
+out3:
+ xfree(newcon);
+out2:
+ xfree(tcon);
+out:
+ xfree(scon);
+ return length;
+}
+
+static int flask_security_create(char *buf, uint32_t size)
+{
+ char *scon, *tcon;
+ u32 ssid, tsid, newsid;
+ u16 tclass;
+ int length;
+ char *newcon;
+ u32 len;
+
+ length = domain_has_security(current->domain, SECURITY__COMPUTE_CREATE);
+ if ( length )
+ return length;
+
+ length = -ENOMEM;
+ scon = xmalloc_array(char, size+1);
+ if ( !scon )
+ return length;
+ memset(scon, 0, size+1);
+
+ tcon = xmalloc_array(char, size+1);
+ if ( !tcon )
+ goto out;
+ memset(tcon, 0, size+1);
+
+ length = -EINVAL;
+ if ( sscanf(buf, "%s %s %hu", scon, tcon, &tclass) != 3 )
+ goto out2;
+
+ length = security_context_to_sid(scon, strlen(scon)+1, &ssid);
+ if ( length < 0 )
+ goto out2;
+
+ length = security_context_to_sid(tcon, strlen(tcon)+1, &tsid);
+ if ( length < 0 )
+ goto out2;
+
+ length = security_transition_sid(ssid, tsid, tclass, &newsid);
+ if ( length < 0 )
+ goto out2;
+
+ length = security_sid_to_context(newsid, &newcon, &len);
+ if ( length < 0 )
+ goto out2;
+
+ if ( len > size )
+ {
+ printk( "%s: context size (%u) exceeds payload "
+ "max\n", __FUNCTION__, len);
+ length = -ERANGE;
+ goto out3;
+ }
+
+ memset(buf, 0, size);
+ memcpy(buf, newcon, len);
length = len;
out3:
@@ -198,75 +304,8 @@ out:
return length;
}
-static int flask_security_create(char *buf, int size)
-{
- char *scon, *tcon;
- u32 ssid, tsid, newsid;
- u16 tclass;
- int length;
- char *newcon;
- u32 len;
-
- length = domain_has_security(current->domain, SECURITY__COMPUTE_CREATE);
- if ( length )
- return length;
-
- length = -ENOMEM;
- scon = xmalloc_array(char, size+1);
- if ( !scon )
- return length;
- memset(scon, 0, size+1);
-
- tcon = xmalloc_array(char, size+1);
- if ( !tcon )
- goto out;
- memset(tcon, 0, size+1);
-
- length = -EINVAL;
- if ( sscanf(buf, "%s %s %hu", scon, tcon, &tclass) != 3 )
- goto out2;
-
- length = security_context_to_sid(scon, strlen(scon)+1, &ssid);
- if ( length < 0 )
- goto out2;
-
- length = security_context_to_sid(tcon, strlen(tcon)+1, &tsid);
- if ( length < 0 )
- goto out2;
-
- length = security_transition_sid(ssid, tsid, tclass, &newsid);
- if ( length < 0 )
- goto out2;
-
- length = security_sid_to_context(newsid, &newcon, &len);
- if ( length < 0 )
- goto out2;
-
- if ( len > PAGE_SIZE )
- {
- printk( "%s: context size (%u) exceeds payload "
- "max\n", __FUNCTION__, len);
- length = -ERANGE;
- goto out3;
- }
-
- if ( copy_to_user(buf, newcon, len) )
- len = -EFAULT;
-
- length = len;
-
-out3:
- xfree(newcon);
-out2:
- xfree(tcon);
-out:
- xfree(scon);
- return length;
-}
-
-static int flask_security_access(char *buf, int size)
-{
- char *page = NULL;
+static int flask_security_access(char *buf, uint32_t size)
+{
char *scon, *tcon;
u32 ssid, tsid;
u16 tclass;
@@ -305,23 +344,12 @@ static int flask_security_access(char *b
if ( length < 0 )
goto out2;
- page = (char *)xmalloc_bytes(PAGE_SIZE);
- if ( !page )
- {
- length = -ENOMEM;
- goto out2;
- }
-
- memset(page, 0, PAGE_SIZE);
-
- length = snprintf(page, PAGE_SIZE, "%x %x %x %x %u",
+ memset(buf, 0, size);
+ length = snprintf(buf, size, "%x %x %x %x %u",
avd.allowed, avd.decided,
avd.auditallow, avd.auditdeny,
avd.seqno);
- if ( copy_to_user(buf, page, length) )
- length = -EFAULT;
-
out2:
xfree(tcon);
out:
@@ -329,7 +357,7 @@ out:
return length;
}
-static int flask_security_member(char *buf, int size)
+static int flask_security_member(char *buf, uint32_t size)
{
char *scon, *tcon;
u32 ssid, tsid, newsid;
@@ -373,7 +401,7 @@ static int flask_security_member(char *b
if ( length < 0 )
goto out2;
- if ( len > PAGE_SIZE )
+ if ( len > size )
{
printk("%s: context size (%u) exceeds payload "
"max\n", __FUNCTION__, len);
@@ -381,9 +409,8 @@ static int flask_security_member(char *b
goto out3;
}
- if ( copy_to_user(buf, newcon, len) )
- len = -EFAULT;
-
+ memset(buf, 0, size);
+ memcpy(buf, newcon, len);
length = len;
out3:
@@ -395,26 +422,13 @@ out:
return length;
}
-static int flask_security_setenforce(char *buf, int count)
-{
- char *page = NULL;
+static int flask_security_setenforce(char *buf, uint32_t count)
+{
int length;
int new_value;
- if ( count < 0 || count >= PAGE_SIZE )
- return -ENOMEM;
-
- page = (char *)xmalloc_bytes(PAGE_SIZE);
- if ( !page )
- return -ENOMEM;
- memset(page, 0, PAGE_SIZE);
- length = -EFAULT;
- if ( copy_from_user(page, buf, count) )
- goto out;
-
- length = -EINVAL;
- if ( sscanf(page, "%d", &new_value) != 1 )
- goto out;
+ if ( sscanf(buf, "%d", &new_value) != 1 )
+ return -EINVAL;
if ( new_value != flask_enforcing )
{
@@ -428,13 +442,11 @@ static int flask_security_setenforce(cha
length = count;
out:
- xfree(page);
- return length;
-}
-
-static int flask_security_context(char *buf, int count)
-{
- char *page = NULL;
+ return length;
+}
+
+static int flask_security_context(char *buf, uint32_t count)
+{
u32 sid;
int length;
@@ -442,35 +454,19 @@ static int flask_security_context(char *
if ( length )
goto out;
- if ( count < 0 || count >= PAGE_SIZE )
- return -ENOMEM;
-
- page = (char *)xmalloc_bytes(PAGE_SIZE);
- if ( !page )
- return -ENOMEM;
- memset(page, 0, PAGE_SIZE);
- length = -EFAULT;
- if ( copy_from_user(page, buf, count) )
- goto out;
-
- length = security_context_to_sid(page, count, &sid);
- if ( length < 0 )
- goto out;
-
- memset(page, 0, PAGE_SIZE);
- length = snprintf(page, PAGE_SIZE, "%u", sid);
-
- if ( copy_to_user(buf, page, count) )
- length = -EFAULT;
-
-out:
- xfree(page);
- return length;
-}
-
-static int flask_security_sid(char *buf, int count)
-{
- char *page = NULL;
+ length = security_context_to_sid(buf, count, &sid);
+ if ( length < 0 )
+ goto out;
+
+ memset(buf, 0, count);
+ length = snprintf(buf, count, "%u", sid);
+
+out:
+ return length;
+}
+
+static int flask_security_sid(char *buf, uint32_t count)
+{
char *context;
u32 sid;
u32 len;
@@ -480,31 +476,20 @@ static int flask_security_sid(char *buf,
if ( length )
goto out;
- if ( count < 0 || count >= PAGE_SIZE )
- return -ENOMEM;
-
- page = (char *)xmalloc_bytes(PAGE_SIZE);
- if ( !page )
- return -ENOMEM;
- memset(page, 0, PAGE_SIZE);
- length = -EFAULT;
- if ( copy_from_user(page, buf, count) )
- goto out;
-
- if ( sscanf(page, "%u", &sid) != 1 )
+ if ( sscanf(buf, "%u", &sid) != 1 )
goto out;
length = security_sid_to_context(sid, &context, &len);
if ( length < 0 )
goto out;
- if ( copy_to_user(buf, context, len) )
- length = -EFAULT;
-
+ memset(buf, 0, count);
+ memcpy(buf, context, len);
+ length = len;
+
xfree(context);
out:
- xfree(page);
return length;
}
@@ -534,24 +519,13 @@ int flask_disable(void)
return 0;
}
-static int flask_security_disable(char *buf, int count)
-{
- char *page = NULL;
+static int flask_security_disable(char *buf, uint32_t count)
+{
int length;
int new_value;
- if ( count < 0 || count >= PAGE_SIZE )
- return -ENOMEM;
- page = (char *)xmalloc_bytes(PAGE_SIZE);
- if ( !page )
- return -ENOMEM;
- memset(page, 0, PAGE_SIZE);
- length = -EFAULT;
- if ( copy_from_user(page, buf, count) )
- goto out;
-
length = -EINVAL;
- if ( sscanf(page, "%d", &new_value) != 1 )
+ if ( sscanf(buf, "%d", &new_value) != 1 )
goto out;
if ( new_value )
@@ -564,57 +538,35 @@ static int flask_security_disable(char *
length = count;
out:
- xfree(page);
- return length;
-}
-
-static int flask_security_setavc_threshold(char *buf, int count)
-{
- char *page = NULL;
+ return length;
+}
+
+static int flask_security_setavc_threshold(char *buf, uint32_t count)
+{
int ret;
int new_value;
- if ( count < 0 || count >= PAGE_SIZE )
- {
- ret = -ENOMEM;
- goto out;
- }
-
- page = (char*)xmalloc_bytes(PAGE_SIZE);
- if (!page)
- return -ENOMEM;
- memset(page, 0, PAGE_SIZE);
-
- if ( copy_from_user(page, buf, count) )
- {
- ret = -EFAULT;
- goto out_free;
- }
-
- if ( sscanf(page, "%u", &new_value) != 1 )
+ if ( sscanf(buf, "%u", &new_value) != 1 )
{
ret = -EINVAL;
- goto out_free;
+ goto out;
}
if ( new_value != avc_cache_threshold )
{
ret = domain_has_security(current->domain, SECURITY__SETSECPARAM);
if ( ret )
- goto out_free;
+ goto out;
avc_cache_threshold = new_value;
}
ret = count;
-out_free:
- xfree(page);
out:
return ret;
}
-static int flask_security_set_bool(char *buf, int count)
-{
- char *page = NULL;
+static int flask_security_set_bool(char *buf, uint32_t count)
+{
int length = -EFAULT;
int i, new_value;
@@ -624,25 +576,8 @@ static int flask_security_set_bool(char
if ( length )
goto out;
- if ( count < 0 || count >= PAGE_SIZE )
- {
- length = -ENOMEM;
- goto out;
- }
-
- page = (char *)xmalloc_bytes(PAGE_SIZE);
- if ( !page )
- {
- length = -ENOMEM;
- goto out;
- }
- memset(page, 0, PAGE_SIZE);
-
- if ( copy_from_user(page, buf, count) )
- goto out;
-
length = -EINVAL;
- if ( sscanf(page, "%d %d", &i, &new_value) != 2 )
+ if ( sscanf(buf, "%d %d", &i, &new_value) != 2 )
goto out;
if ( new_value )
@@ -655,14 +590,11 @@ static int flask_security_set_bool(char
out:
spin_unlock(&sel_sem);
- if ( page )
- xfree(page);
- return length;
-}
-
-static int flask_security_commit_bools(char *buf, int count)
-{
- char *page = NULL;
+ return length;
+}
+
+static int flask_security_commit_bools(char *buf, uint32_t count)
+{
int length = -EFAULT;
int new_value;
@@ -672,25 +604,8 @@ static int flask_security_commit_bools(c
if ( length )
goto out;
- if ( count < 0 || count >= PAGE_SIZE )
- {
- length = -ENOMEM;
- goto out;
- }
-
- page = (char *)xmalloc_bytes(PAGE_SIZE);
- if ( !page )
- {
- length = -ENOMEM;
- goto out;
- }
- memset(page, 0, PAGE_SIZE);
-
- if ( copy_from_user(page, buf, count) )
- goto out;
-
length = -EINVAL;
- if ( sscanf(page, "%d", &new_value) != 1 )
+ if ( sscanf(buf, "%d", &new_value) != 1 )
goto out;
if ( new_value )
@@ -700,40 +615,18 @@ static int flask_security_commit_bools(c
out:
spin_unlock(&sel_sem);
- if ( page )
- xfree(page);
- return length;
-}
-
-static int flask_security_get_bool(char *buf, int count)
-{
- char *page = NULL;
+ return length;
+}
+
+static int flask_security_get_bool(char *buf, uint32_t count)
+{
int length;
int i, cur_enforcing;
spin_lock(&sel_sem);
- length = -EFAULT;
-
- if ( count < 0 || count > PAGE_SIZE )
- {
- length = -EINVAL;
- goto out;
- }
-
- page = (char *)xmalloc_bytes(PAGE_SIZE);
- if ( !page )
- {
- length = -ENOMEM;
- goto out;
- }
- memset(page, 0, PAGE_SIZE);
-
- if ( copy_from_user(page, buf, count) )
- goto out;
-
length = -EINVAL;
- if ( sscanf(page, "%d", &i) != 1 )
+ if ( sscanf(buf, "%d", &i) != 1 )
goto out;
cur_enforcing = security_get_bool_value(i);
@@ -743,18 +636,12 @@ static int flask_security_get_bool(char
goto out;
}
- length = snprintf(page, PAGE_SIZE, "%d %d", cur_enforcing,
+ memset(buf, 0, count);
+ length = snprintf(buf, count, "%d %d", cur_enforcing,
bool_pending_values[i]);
- if ( length < 0 )
- goto out;
-
- if ( copy_to_user(buf, page, length) )
- length = -EFAULT;
out:
spin_unlock(&sel_sem);
- if ( page )
- xfree(page);
return length;
}
@@ -786,7 +673,7 @@ out:
#ifdef FLASK_AVC_STATS
-static int flask_security_avc_cachestats(char *buf, int count)
+static int flask_security_avc_cachestats(char *buf, uint32_t count)
{
char *page = NULL;
int len = 0;
@@ -802,9 +689,15 @@ static int flask_security_avc_cachestats
len = snprintf(page, PAGE_SIZE, "lookups hits misses allocations reclaims "
"frees\n");
+ if ( len > count ) {
+ length = -EINVAL;
+ goto out;
+ }
+
memcpy(buf, page, len);
buf += len;
length += len;
+ count -= len;
for ( cpu = idx; cpu < NR_CPUS; ++cpu )
{
@@ -816,22 +709,27 @@ static int flask_security_avc_cachestats
len = snprintf(page, PAGE_SIZE, "%u %u %u %u %u %u\n", st->lookups,
st->hits, st->misses, st->allocations,
st->reclaims,
st->frees);
+ if ( len > count ) {
+ length = -EINVAL;
+ goto out;
+ }
memcpy(buf, page, len);
buf += len;
length += len;
- }
-
+ count -= len;
+ }
+
+out:
xfree(page);
return length;
}
#endif
-static int flask_security_load(char *buf, int count)
+static int flask_security_load(char *buf, uint32_t count)
{
int ret;
int length;
- void *data = NULL;
spin_lock(&sel_sem);
@@ -839,18 +737,7 @@ static int flask_security_load(char *buf
if ( length )
goto out;
- if ( (count < 0) || (count > 64 * 1024 * 1024)
- || (data = xmalloc_array(char, count)) == NULL )
- {
- length = -ENOMEM;
- goto out;
- }
-
- length = -EFAULT;
- if ( copy_from_user(data, buf, count) != 0 )
- goto out;
-
- length = security_load_policy(data, count);
+ length = security_load_policy(buf, count);
if ( length )
goto out;
@@ -862,7 +749,6 @@ static int flask_security_load(char *buf
out:
spin_unlock(&sel_sem);
- xfree(data);
return length;
}
@@ -871,188 +757,156 @@ long do_flask_op(XEN_GUEST_HANDLE(xsm_op
flask_op_t curop, *op = &curop;
int rc = 0;
int length = 0;
- char *page = NULL;
+ char *arg = NULL;
if ( copy_from_guest(op, u_flask_op, 1) )
return -EFAULT;
+ if ( op->cmd > FLASK_LAST)
+ return -EINVAL;
+
+ if ( op->size > MAX_POLICY_SIZE )
+ return -EINVAL;
+
+ if ( (op->buf == NULL && op->size != 0) ||
+ (op->buf != NULL && op->size == 0) )
+ return -EINVAL;
+
+ arg = xmalloc_bytes(op->size + 1);
+ if ( !arg )
+ return -ENOMEM;
+
+ memset(arg, 0, op->size + 1);
+
+ if ( (FLASK_COPY_IN&(1UL<<op->cmd)) && op->buf != NULL &&
+ copy_from_guest(arg, guest_handle_from_ptr(op->buf, char),
op->size) )
+ {
+ rc = -EFAULT;
+ goto out;
+ }
+
switch ( op->cmd )
{
case FLASK_LOAD:
{
- length = flask_security_load(op->buf, op->size);
+ length = flask_security_load(arg, op->size);
}
break;
case FLASK_GETENFORCE:
{
- page = (char *)xmalloc_bytes(PAGE_SIZE);
- if ( !page )
- return -ENOMEM;
- memset(page, 0, PAGE_SIZE);
-
- length = snprintf(page, PAGE_SIZE, "%d", flask_enforcing);
-
- if ( copy_to_user(op->buf, page, length) )
- {
- rc = -EFAULT;
- goto out;
- }
+ length = snprintf(arg, op->size, "%d", flask_enforcing);
}
break;
case FLASK_SETENFORCE:
{
- length = flask_security_setenforce(op->buf, op->size);
+ length = flask_security_setenforce(arg, op->size);
}
break;
case FLASK_CONTEXT_TO_SID:
{
- length = flask_security_context(op->buf, op->size);
+ length = flask_security_context(arg, op->size);
}
break;
case FLASK_SID_TO_CONTEXT:
{
- length = flask_security_sid(op->buf, op->size);
+ length = flask_security_sid(arg, op->size);
}
break;
case FLASK_ACCESS:
{
- length = flask_security_access(op->buf, op->size);
+ length = flask_security_access(arg, op->size);
}
break;
case FLASK_CREATE:
{
- length = flask_security_create(op->buf, op->size);
+ length = flask_security_create(arg, op->size);
}
break;
case FLASK_RELABEL:
{
- length = flask_security_relabel(op->buf, op->size);
+ length = flask_security_relabel(arg, op->size);
}
break;
case FLASK_USER:
{
- length = flask_security_user(op->buf, op->size);
+ length = flask_security_user(arg, op->size);
}
break;
case FLASK_POLICYVERS:
{
- page = (char *)xmalloc_bytes(PAGE_SIZE);
- if ( !page )
- return -ENOMEM;
- memset(page, 0, PAGE_SIZE);
-
- length = snprintf(page, PAGE_SIZE, "%d", POLICYDB_VERSION_MAX);
-
- if ( copy_to_user(op->buf, page, length) )
- {
- rc = -EFAULT;
- goto out;
- }
+ length = snprintf(arg, op->size, "%d", POLICYDB_VERSION_MAX);
}
break;
case FLASK_GETBOOL:
{
- length = flask_security_get_bool(op->buf, op->size);
+ length = flask_security_get_bool(arg, op->size);
}
break;
case FLASK_SETBOOL:
{
- length = flask_security_set_bool(op->buf, op->size);
+ length = flask_security_set_bool(arg, op->size);
}
break;
case FLASK_COMMITBOOLS:
{
- length = flask_security_commit_bools(op->buf, op->size);
+ length = flask_security_commit_bools(arg, op->size);
}
break;
case FLASK_MLS:
{
- page = (char *)xmalloc_bytes(PAGE_SIZE);
- if ( !page )
- return -ENOMEM;
- memset(page, 0, PAGE_SIZE);
-
- length = snprintf(page, PAGE_SIZE, "%d", flask_mls_enabled);
-
- if ( copy_to_user(op->buf, page, length) )
- {
- rc = -EFAULT;
- goto out;
- }
+ length = snprintf(arg, op->size, "%d", flask_mls_enabled);
}
break;
case FLASK_DISABLE:
{
- length = flask_security_disable(op->buf, op->size);
+ length = flask_security_disable(arg, op->size);
}
break;
case FLASK_GETAVC_THRESHOLD:
{
- page = (char *)xmalloc_bytes(PAGE_SIZE);
- if ( !page )
- return -ENOMEM;
- memset(page, 0, PAGE_SIZE);
-
- length = snprintf(page, PAGE_SIZE, "%d", avc_cache_threshold);
-
- if ( copy_to_user(op->buf, page, length) )
- {
- rc = -EFAULT;
- goto out;
- }
+ length = snprintf(arg, op->size, "%d", avc_cache_threshold);
}
break;
case FLASK_SETAVC_THRESHOLD:
{
- length = flask_security_setavc_threshold(op->buf, op->size);
+ length = flask_security_setavc_threshold(arg, op->size);
}
break;
case FLASK_AVC_HASHSTATS:
{
- page = (char *)xmalloc_bytes(PAGE_SIZE);
- if ( !page )
- return -ENOMEM;
- memset(page, 0, PAGE_SIZE);
-
- length = avc_get_hash_stats(page);
-
- if ( copy_to_user(op->buf, page, length) )
- {
- rc = -EFAULT;
- goto out;
- }
+ length = avc_get_hash_stats(arg, op->size);
}
break;
#ifdef FLASK_AVC_STATS
case FLASK_AVC_CACHESTATS:
{
- length = flask_security_avc_cachestats(op->buf, op->size);
+ length = flask_security_avc_cachestats(arg, op->size);
}
break;
-#endif
+#endif
case FLASK_MEMBER:
{
- length = flask_security_member(op->buf, op->size);
+ length = flask_security_member(arg, op->size);
}
break;
@@ -1067,13 +921,19 @@ long do_flask_op(XEN_GUEST_HANDLE(xsm_op
rc = length;
goto out;
}
+
+ if ( (FLASK_COPY_OUT&(1UL<<op->cmd)) && op->buf != NULL &&
+ copy_to_guest(guest_handle_from_ptr(op->buf, char), arg,
op->size) )
+ {
+ rc = -EFAULT;
+ goto out;
+ }
+
op->size = length;
if ( copy_to_guest(u_flask_op, op, 1) )
rc = -EFAULT;
out:
- if ( page )
- xfree(page);
+ xfree(arg);
return rc;
}
-
diff -r 1e7a371cee11 -r 1970781956c7 xen/xsm/flask/hooks.c
--- a/xen/xsm/flask/hooks.c Wed Jul 23 11:21:47 2008 +0900
+++ b/xen/xsm/flask/hooks.c Wed Jul 23 12:10:20 2008 +0900
@@ -712,18 +712,6 @@ static int flask_perfcontrol(void)
static int flask_perfcontrol(void)
{
return domain_has_xen(current->domain, XEN__PERFCONTROL);
-}
-
-void flask_complete_init(struct domain *d)
-{
- struct domain_security_struct *dsec;
-
- /* Set the security state for the Dom0 domain. */
- dsec = d->ssid;
- dsec->sid = SECINITSID_DOM0;
- dsec->create_sid = SECINITSID_UNLABELED;
-
- printk("Flask: Completed initialization.\n");
}
#ifdef CONFIG_X86
@@ -1101,7 +1089,6 @@ static struct xsm_operations flask_ops =
.schedop_shutdown = flask_schedop_shutdown,
.__do_xsm_op = do_flask_op,
- .complete_init = flask_complete_init,
#ifdef CONFIG_X86
.shadow_control = flask_shadow_control,
diff -r 1e7a371cee11 -r 1970781956c7 xen/xsm/flask/include/avc.h
--- a/xen/xsm/flask/include/avc.h Wed Jul 23 11:21:47 2008 +0900
+++ b/xen/xsm/flask/include/avc.h Wed Jul 23 12:10:20 2008 +0900
@@ -95,7 +95,7 @@ int avc_add_callback(int (*callback)(u32
u32 ssid, u32 tsid, u16 tclass, u32 perms);
/* Exported to selinuxfs */
-int avc_get_hash_stats(char *page);
+int avc_get_hash_stats(char *buf, uint32_t size);
extern unsigned int avc_cache_threshold;
#ifdef FLASK_AVC_STATS
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|