[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] merge with xen-unstable.hg
# 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
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |