diff --git a/extras/mini-os/include/events.h b/extras/mini-os/include/events.h index 3fad1f376c..76226efcd5 100644 --- a/extras/mini-os/include/events.h +++ b/extras/mini-os/include/events.h @@ -47,7 +47,7 @@ static inline int notify_via_evtchn(int port) { evtchn_op_t op; op.cmd = EVTCHNOP_send; - op.u.send.local_port = port; + op.u.send.port = port; return HYPERVISOR_event_channel_op(&op); } diff --git a/extras/mini-os/include/hypervisor.h b/extras/mini-os/include/hypervisor.h index d8b9b62948..98e319a6f9 100644 --- a/extras/mini-os/include/hypervisor.h +++ b/extras/mini-os/include/hypervisor.h @@ -14,6 +14,7 @@ #include #include +#include /* * a placeholder for the start of day information passed up from the hypervisor @@ -37,548 +38,281 @@ void clear_evtchn(u32 port); * Assembler stubs for hyper-calls. */ #if defined(__i386__) +/* Taken from Linux */ + +#ifndef __HYPERCALL_H__ +#define __HYPERCALL_H__ + +#include + +#define _hypercall0(type, name) \ +({ \ + long __res; \ + asm volatile ( \ + TRAP_INSTR \ + : "=a" (__res) \ + : "0" (__HYPERVISOR_##name) \ + : "memory" ); \ + (type)__res; \ +}) + +#define _hypercall1(type, name, a1) \ +({ \ + long __res, __ign1; \ + asm volatile ( \ + TRAP_INSTR \ + : "=a" (__res), "=b" (__ign1) \ + : "0" (__HYPERVISOR_##name), "1" ((long)(a1)) \ + : "memory" ); \ + (type)__res; \ +}) + +#define _hypercall2(type, name, a1, a2) \ +({ \ + long __res, __ign1, __ign2; \ + asm volatile ( \ + TRAP_INSTR \ + : "=a" (__res), "=b" (__ign1), "=c" (__ign2) \ + : "0" (__HYPERVISOR_##name), "1" ((long)(a1)), \ + "2" ((long)(a2)) \ + : "memory" ); \ + (type)__res; \ +}) + +#define _hypercall3(type, name, a1, a2, a3) \ +({ \ + long __res, __ign1, __ign2, __ign3; \ + asm volatile ( \ + TRAP_INSTR \ + : "=a" (__res), "=b" (__ign1), "=c" (__ign2), \ + "=d" (__ign3) \ + : "0" (__HYPERVISOR_##name), "1" ((long)(a1)), \ + "2" ((long)(a2)), "3" ((long)(a3)) \ + : "memory" ); \ + (type)__res; \ +}) + +#define _hypercall4(type, name, a1, a2, a3, a4) \ +({ \ + long __res, __ign1, __ign2, __ign3, __ign4; \ + asm volatile ( \ + TRAP_INSTR \ + : "=a" (__res), "=b" (__ign1), "=c" (__ign2), \ + "=d" (__ign3), "=S" (__ign4) \ + : "0" (__HYPERVISOR_##name), "1" ((long)(a1)), \ + "2" ((long)(a2)), "3" ((long)(a3)), \ + "4" ((long)(a4)) \ + : "memory" ); \ + (type)__res; \ +}) + +#define _hypercall5(type, name, a1, a2, a3, a4, a5) \ +({ \ + long __res, __ign1, __ign2, __ign3, __ign4, __ign5; \ + asm volatile ( \ + TRAP_INSTR \ + : "=a" (__res), "=b" (__ign1), "=c" (__ign2), \ + "=d" (__ign3), "=S" (__ign4), "=D" (__ign5) \ + : "0" (__HYPERVISOR_##name), "1" ((long)(a1)), \ + "2" ((long)(a2)), "3" ((long)(a3)), \ + "4" ((long)(a4)), "5" ((long)(a5)) \ + : "memory" ); \ + (type)__res; \ +}) + static inline int HYPERVISOR_set_trap_table( - trap_info_t *table) + trap_info_t *table) { - int ret; - unsigned long ignore; - - __asm__ __volatile__ ( - TRAP_INSTR - : "=a" (ret), "=b" (ignore) - : "0" (__HYPERVISOR_set_trap_table), "1" (table) - : "memory" ); - - return ret; + return _hypercall1(int, set_trap_table, table); } static inline int HYPERVISOR_mmu_update( - mmu_update_t *req, int count, int *success_count, domid_t domid) + mmu_update_t *req, int count, int *success_count, domid_t domid) { - int ret; - unsigned long ign1, ign2, ign3, ign4; - - __asm__ __volatile__ ( - TRAP_INSTR - : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3), "=S" (ign4) - : "0" (__HYPERVISOR_mmu_update), "1" (req), "2" (count), - "3" (success_count), "4" (domid) - : "memory" ); - - return ret; + return _hypercall4(int, mmu_update, req, count, success_count, domid); } static inline int HYPERVISOR_mmuext_op( - struct mmuext_op *op, int count, int *success_count, domid_t domid) + struct mmuext_op *op, int count, int *success_count, domid_t domid) { - int ret; - unsigned long ign1, ign2, ign3, ign4; - - __asm__ __volatile__ ( - TRAP_INSTR - : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3), "=S" (ign4) - : "0" (__HYPERVISOR_mmuext_op), "1" (op), "2" (count), - "3" (success_count), "4" (domid) - : "memory" ); - - return ret; + return _hypercall4(int, mmuext_op, op, count, success_count, domid); } static inline int HYPERVISOR_set_gdt( - unsigned long *frame_list, int entries) + unsigned long *frame_list, int entries) { - int ret; - unsigned long ign1, ign2; - - __asm__ __volatile__ ( - TRAP_INSTR - : "=a" (ret), "=b" (ign1), "=c" (ign2) - : "0" (__HYPERVISOR_set_gdt), "1" (frame_list), "2" (entries) - : "memory" ); - - - return ret; + return _hypercall2(int, set_gdt, frame_list, entries); } static inline int HYPERVISOR_stack_switch( - unsigned long ss, unsigned long esp) + unsigned long ss, unsigned long esp) { - int ret; - unsigned long ign1, ign2; - - __asm__ __volatile__ ( - TRAP_INSTR - : "=a" (ret), "=b" (ign1), "=c" (ign2) - : "0" (__HYPERVISOR_stack_switch), "1" (ss), "2" (esp) - : "memory" ); - - return ret; + return _hypercall2(int, stack_switch, ss, esp); } static inline int HYPERVISOR_set_callbacks( - unsigned long event_selector, unsigned long event_address, - unsigned long failsafe_selector, unsigned long failsafe_address) + unsigned long event_selector, unsigned long event_address, + unsigned long failsafe_selector, unsigned long failsafe_address) { - int ret; - unsigned long ign1, ign2, ign3, ign4; - - __asm__ __volatile__ ( - TRAP_INSTR - : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3), "=S" (ign4) - : "0" (__HYPERVISOR_set_callbacks), "1" (event_selector), - "2" (event_address), "3" (failsafe_selector), "4" (failsafe_address) - : "memory" ); - - return ret; + return _hypercall4(int, set_callbacks, + event_selector, event_address, + failsafe_selector, failsafe_address); } static inline int HYPERVISOR_fpu_taskswitch( - int set) + int set) { - int ret; - unsigned long ign; - - __asm__ __volatile__ ( - TRAP_INSTR - : "=a" (ret), "=b" (ign) - : "0" (__HYPERVISOR_fpu_taskswitch), "1" (set) - : "memory" ); - - return ret; + return _hypercall1(int, fpu_taskswitch, set); } static inline int -HYPERVISOR_yield( - void) +HYPERVISOR_sched_op( + int cmd, unsigned long arg) { - int ret; - unsigned long ign; - - __asm__ __volatile__ ( - TRAP_INSTR - : "=a" (ret), "=b" (ign) - : "0" (__HYPERVISOR_sched_op), "1" (SCHEDOP_yield) - : "memory", "ecx" ); - - return ret; -} - -static inline int -HYPERVISOR_block( - void) -{ - int ret; - unsigned long ign1; - __asm__ __volatile__ ( - TRAP_INSTR - : "=a" (ret), "=b" (ign1) - : "0" (__HYPERVISOR_sched_op), "1" (SCHEDOP_block) - : "memory", "ecx" ); - - return ret; -} - -static inline int -HYPERVISOR_shutdown( - void) -{ - int ret; - unsigned long ign1; - __asm__ __volatile__ ( - TRAP_INSTR - : "=a" (ret), "=b" (ign1) - : "0" (__HYPERVISOR_sched_op), - "1" (SCHEDOP_shutdown | (SHUTDOWN_poweroff << SCHEDOP_reasonshift)) - : "memory", "ecx" ); - - return ret; -} - -static inline int -HYPERVISOR_reboot( - void) -{ - int ret; - unsigned long ign1; - __asm__ __volatile__ ( - TRAP_INSTR - : "=a" (ret), "=b" (ign1) - : "0" (__HYPERVISOR_sched_op), - "1" (SCHEDOP_shutdown | (SHUTDOWN_reboot << SCHEDOP_reasonshift)) - : "memory", "ecx" ); - - return ret; -} - -static inline int -HYPERVISOR_suspend( - unsigned long srec) -{ - int ret; - unsigned long ign1, ign2; - - /* NB. On suspend, control software expects a suspend record in %esi. */ - __asm__ __volatile__ ( - TRAP_INSTR - : "=a" (ret), "=b" (ign1), "=S" (ign2) - : "0" (__HYPERVISOR_sched_op), - "b" (SCHEDOP_shutdown | (SHUTDOWN_suspend << SCHEDOP_reasonshift)), - "S" (srec) : "memory", "ecx"); - - return ret; -} - -static inline int -HYPERVISOR_crash( - void) -{ - int ret; - unsigned long ign1; - __asm__ __volatile__ ( - TRAP_INSTR - : "=a" (ret), "=b" (ign1) - : "0" (__HYPERVISOR_sched_op), - "1" (SCHEDOP_shutdown | (SHUTDOWN_crash << SCHEDOP_reasonshift)) - : "memory", "ecx" ); - - return ret; + return _hypercall2(int, sched_op, cmd, arg); } static inline long HYPERVISOR_set_timer_op( - u64 timeout) + u64 timeout) { - int ret; - unsigned long timeout_hi = (unsigned long)(timeout>>32); - unsigned long timeout_lo = (unsigned long)timeout; - unsigned long ign1, ign2; - - __asm__ __volatile__ ( - TRAP_INSTR - : "=a" (ret), "=b" (ign1), "=c" (ign2) - : "0" (__HYPERVISOR_set_timer_op), "b" (timeout_lo), "c" (timeout_hi) - : "memory"); - - return ret; + unsigned long timeout_hi = (unsigned long)(timeout>>32); + unsigned long timeout_lo = (unsigned long)timeout; + return _hypercall2(long, set_timer_op, timeout_lo, timeout_hi); } -#if 0 static inline int HYPERVISOR_dom0_op( - dom0_op_t *dom0_op) + dom0_op_t *dom0_op) { - int ret; - unsigned long ign1; - - dom0_op->interface_version = DOM0_INTERFACE_VERSION; - __asm__ __volatile__ ( - TRAP_INSTR - : "=a" (ret), "=b" (ign1) - : "0" (__HYPERVISOR_dom0_op), "1" (dom0_op) - : "memory"); - - return ret; + dom0_op->interface_version = DOM0_INTERFACE_VERSION; + return _hypercall1(int, dom0_op, dom0_op); } -#endif static inline int HYPERVISOR_set_debugreg( - int reg, unsigned long value) + int reg, unsigned long value) { - int ret; - unsigned long ign1, ign2; - __asm__ __volatile__ ( - TRAP_INSTR - : "=a" (ret), "=b" (ign1), "=c" (ign2) - : "0" (__HYPERVISOR_set_debugreg), "1" (reg), "2" (value) - : "memory" ); - - return ret; + return _hypercall2(int, set_debugreg, reg, value); } static inline unsigned long HYPERVISOR_get_debugreg( - int reg) + int reg) { - unsigned long ret; - unsigned long ign; - __asm__ __volatile__ ( - TRAP_INSTR - : "=a" (ret), "=b" (ign) - : "0" (__HYPERVISOR_get_debugreg), "1" (reg) - : "memory" ); - - return ret; + return _hypercall1(unsigned long, get_debugreg, reg); } static inline int HYPERVISOR_update_descriptor( - u64 ma, u64 desc) + u64 ma, u64 desc) { - int ret; - unsigned long ign1, ign2, ign3, ign4; - - __asm__ __volatile__ ( - TRAP_INSTR - : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3), "=S" (ign4) - : "0" (__HYPERVISOR_update_descriptor), - "1" ((unsigned long)ma), "2" ((unsigned long)(ma>>32)), - "3" ((unsigned long)desc), "4" ((unsigned long)(desc>>32)) - : "memory" ); - - return ret; + return _hypercall4(int, update_descriptor, ma, ma>>32, desc, desc>>32); } static inline int -HYPERVISOR_dom_mem_op( - unsigned int op, unsigned long *extent_list, - unsigned long nr_extents, unsigned int extent_order) +HYPERVISOR_memory_op( + unsigned int cmd, void *arg) { - int ret; - unsigned long ign1, ign2, ign3, ign4, ign5; - - __asm__ __volatile__ ( - TRAP_INSTR - : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3), "=S" (ign4), - "=D" (ign5) - : "0" (__HYPERVISOR_dom_mem_op), "1" (op), "2" (extent_list), - "3" (nr_extents), "4" (extent_order), "5" (DOMID_SELF) - : "memory" ); - - return ret; + return _hypercall2(int, memory_op, cmd, arg); } static inline int HYPERVISOR_multicall( - void *call_list, int nr_calls) + void *call_list, int nr_calls) { - int ret; - unsigned long ign1, ign2; - - __asm__ __volatile__ ( - TRAP_INSTR - : "=a" (ret), "=b" (ign1), "=c" (ign2) - : "0" (__HYPERVISOR_multicall), "1" (call_list), "2" (nr_calls) - : "memory" ); - - return ret; + return _hypercall2(int, multicall, call_list, nr_calls); } static inline int HYPERVISOR_update_va_mapping( - unsigned long va, pte_t new_val, unsigned long flags) + unsigned long va, pte_t new_val, unsigned long flags) { - int ret; - unsigned long ign1, ign2, ign3, ign4; - - __asm__ __volatile__ ( - TRAP_INSTR - : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3), "=S" (ign4) - : "0" (__HYPERVISOR_update_va_mapping), - "1" (va), "2" ((new_val).pte_low), + unsigned long pte_hi = 0; #ifdef CONFIG_X86_PAE - "3" ((new_val).pte_high), -#else - "3" (0), + pte_hi = new_val.pte_high; #endif - "4" (flags) - : "memory" ); - - return ret; + return _hypercall4(int, update_va_mapping, va, + new_val.pte_low, pte_hi, flags); } static inline int HYPERVISOR_event_channel_op( - void *op) + void *op) { - int ret; - unsigned long ignore; - __asm__ __volatile__ ( - TRAP_INSTR - : "=a" (ret), "=b" (ignore) - : "0" (__HYPERVISOR_event_channel_op), "1" (op) - : "memory" ); - - return ret; + return _hypercall1(int, event_channel_op, op); } static inline int HYPERVISOR_xen_version( - int cmd, void *arg) + int cmd, void *arg) { - int ret; - unsigned long ignore, ign2; - - __asm__ __volatile__ ( - TRAP_INSTR - : "=a" (ret), "=b" (ignore), "=c" (ign2) - : "0" (__HYPERVISOR_xen_version), "1" (cmd), "2" (arg) - : "memory" ); - - return ret; + return _hypercall2(int, xen_version, cmd, arg); } static inline int HYPERVISOR_console_io( - int cmd, int count, char *str) + int cmd, int count, char *str) { - int ret; - unsigned long ign1, ign2, ign3; - __asm__ __volatile__ ( - TRAP_INSTR - : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3) - : "0" (__HYPERVISOR_console_io), "1" (cmd), "2" (count), "3" (str) - : "memory" ); - - return ret; + return _hypercall3(int, console_io, cmd, count, str); } static inline int HYPERVISOR_physdev_op( - void *physdev_op) + void *physdev_op) { - int ret; - unsigned long ign; - - __asm__ __volatile__ ( - TRAP_INSTR - : "=a" (ret), "=b" (ign) - : "0" (__HYPERVISOR_physdev_op), "1" (physdev_op) - : "memory" ); - - return ret; + return _hypercall1(int, physdev_op, physdev_op); } static inline int HYPERVISOR_grant_table_op( - unsigned int cmd, void *uop, unsigned int count) + unsigned int cmd, void *uop, unsigned int count) { - int ret; - unsigned long ign1, ign2, ign3; - - __asm__ __volatile__ ( - TRAP_INSTR - : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3) - : "0" (__HYPERVISOR_grant_table_op), "1" (cmd), "2" (uop), "3" (count) - : "memory" ); - - return ret; + return _hypercall3(int, grant_table_op, cmd, uop, count); } static inline int HYPERVISOR_update_va_mapping_otherdomain( - unsigned long va, pte_t new_val, unsigned long flags, domid_t domid) + unsigned long va, pte_t new_val, unsigned long flags, domid_t domid) { - int ret; - unsigned long ign1, ign2, ign3, ign4, ign5; - - __asm__ __volatile__ ( - TRAP_INSTR - : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3), - "=S" (ign4), "=D" (ign5) - : "0" (__HYPERVISOR_update_va_mapping_otherdomain), - "1" (va), "2" ((new_val).pte_low), + unsigned long pte_hi = 0; #ifdef CONFIG_X86_PAE - "3" ((new_val).pte_high), -#else - "3" (0), + pte_hi = new_val.pte_high; #endif - "4" (flags), "5" (domid) : - "memory" ); - - return ret; + return _hypercall5(int, update_va_mapping_otherdomain, va, + new_val.pte_low, pte_hi, flags, domid); } static inline int HYPERVISOR_vm_assist( - unsigned int cmd, unsigned int type) + unsigned int cmd, unsigned int type) { - int ret; - unsigned long ign1, ign2; - - __asm__ __volatile__ ( - TRAP_INSTR - : "=a" (ret), "=b" (ign1), "=c" (ign2) - : "0" (__HYPERVISOR_vm_assist), "1" (cmd), "2" (type) - : "memory" ); - - return ret; + return _hypercall2(int, vm_assist, cmd, type); } static inline int -HYPERVISOR_boot_vcpu( - unsigned long vcpu, vcpu_guest_context_t *ctxt) +HYPERVISOR_vcpu_op( + int cmd, int vcpuid, void *extra_args) { - int ret; - unsigned long ign1, ign2; - - __asm__ __volatile__ ( - TRAP_INSTR - : "=a" (ret), "=b" (ign1), "=c" (ign2) - : "0" (__HYPERVISOR_boot_vcpu), "1" (vcpu), "2" (ctxt) - : "memory"); - - return ret; + return _hypercall3(int, vcpu_op, cmd, vcpuid, extra_args); } static inline int -HYPERVISOR_vcpu_down( - int vcpu) +HYPERVISOR_suspend( + unsigned long srec) { - int ret; - unsigned long ign1; - /* Yes, I really do want to clobber edx here: when we resume a - vcpu after unpickling a multi-processor domain, it returns - here, but clobbers all of the call clobbered registers. */ - __asm__ __volatile__ ( - TRAP_INSTR - : "=a" (ret), "=b" (ign1) - : "0" (__HYPERVISOR_sched_op), - "1" (SCHEDOP_vcpu_down | (vcpu << SCHEDOP_vcpushift)) - : "memory", "ecx", "edx" ); - - return ret; + return _hypercall3(int, sched_op, SCHEDOP_shutdown, + SHUTDOWN_suspend, srec); } -static inline int -HYPERVISOR_vcpu_up( - int vcpu) -{ - int ret; - unsigned long ign1; - __asm__ __volatile__ ( - TRAP_INSTR - : "=a" (ret), "=b" (ign1) - : "0" (__HYPERVISOR_sched_op), - "1" (SCHEDOP_vcpu_up | (vcpu << SCHEDOP_vcpushift)) - : "memory", "ecx" ); - - return ret; -} - -static inline int -HYPERVISOR_vcpu_pickle( - int vcpu, vcpu_guest_context_t *ctxt) -{ - int ret; - unsigned long ign1, ign2; - __asm__ __volatile__ ( - TRAP_INSTR - : "=a" (ret), "=b" (ign1), "=c" (ign2) - : "0" (__HYPERVISOR_sched_op), - "1" (SCHEDOP_vcpu_pickle | (vcpu << SCHEDOP_vcpushift)), - "2" (ctxt) - : "memory" ); - - return ret; -} +#endif /* __HYPERCALL_H__ */ #elif defined(__x86_64__) #define __syscall_clobber "r11","rcx","memory" @@ -792,106 +526,4 @@ HYPERVISOR_set_timer_op( } #endif - -static __inline__ int HYPERVISOR_dom0_op(void *dom0_op) -{ - int ret; - __asm__ __volatile__ ( - TRAP_INSTR - : "=a" (ret) : "0" (__HYPERVISOR_dom0_op), - _a1 (dom0_op) : "memory" ); - - return ret; -} - -static __inline__ int HYPERVISOR_set_debugreg(int reg, unsigned long value) -{ - int ret; - __asm__ __volatile__ ( - TRAP_INSTR - : "=a" (ret) : "0" (__HYPERVISOR_set_debugreg), - _a1 (reg), _a2 (value) : "memory" ); - - return ret; -} - -static __inline__ unsigned long HYPERVISOR_get_debugreg(int reg) -{ - unsigned long ret; - __asm__ __volatile__ ( - TRAP_INSTR - : "=a" (ret) : "0" (__HYPERVISOR_get_debugreg), - _a1 (reg) : "memory" ); - - return ret; -} - -static __inline__ int HYPERVISOR_update_descriptor( - unsigned long pa, unsigned long word1, unsigned long word2) -{ - int ret; - __asm__ __volatile__ ( - TRAP_INSTR - : "=a" (ret) : "0" (__HYPERVISOR_update_descriptor), - _a1 (pa), _a2 (word1), _a3 (word2) : "memory" ); - - return ret; -} - -static __inline__ int HYPERVISOR_dom_mem_op(void *dom_mem_op) -{ - int ret; - __asm__ __volatile__ ( - TRAP_INSTR - : "=a" (ret) : "0" (__HYPERVISOR_memory_op), - _a1 (dom_mem_op) : "memory" ); - - return ret; -} - -static __inline__ int HYPERVISOR_multicall(void *call_list, int nr_calls) -{ - int ret; - __asm__ __volatile__ ( - TRAP_INSTR - : "=a" (ret) : "0" (__HYPERVISOR_multicall), - _a1 (call_list), _a2 (nr_calls) : "memory" ); - - return ret; -} - -static __inline__ int HYPERVISOR_update_va_mapping( - unsigned long page_nr, unsigned long new_val, unsigned long flags) -{ - int ret; - __asm__ __volatile__ ( - TRAP_INSTR - : "=a" (ret) : "0" (__HYPERVISOR_update_va_mapping), - _a1 (page_nr), _a2 (new_val), _a3 (flags) : "memory" ); - - return ret; -} - -static __inline__ int HYPERVISOR_xen_version(int cmd) -{ - int ret; - __asm__ __volatile__ ( - TRAP_INSTR - : "=a" (ret) : "0" (__HYPERVISOR_xen_version), - _a1 (cmd) : "memory" ); - - return ret; -} - -static __inline__ int HYPERVISOR_console_io(int cmd, int count, char *str) -{ - int ret; - __asm__ __volatile__ ( - TRAP_INSTR - : "=a" (ret) : "0" (__HYPERVISOR_console_io), - _a1 (cmd), _a2 (count), _a3 (str) : "memory" ); - - return ret; -} - #endif /* __HYPERVISOR_H__ */ diff --git a/extras/mini-os/include/os.h b/extras/mini-os/include/os.h index 42882f364f..751a058888 100644 --- a/extras/mini-os/include/os.h +++ b/extras/mini-os/include/os.h @@ -24,7 +24,7 @@ #include -#define force_evtchn_callback() ((void)HYPERVISOR_xen_version(0)) +#define force_evtchn_callback() ((void)HYPERVISOR_xen_version(0, 0)) #define __KERNEL_CS FLAT_KERNEL_CS #define __KERNEL_DS FLAT_KERNEL_DS @@ -55,6 +55,8 @@ /* Everything below this point is not included by assembler (.S) files. */ #ifndef __ASSEMBLY__ +extern shared_info_t *HYPERVISOR_shared_info; + void trap_init(void); /* diff --git a/extras/mini-os/include/types.h b/extras/mini-os/include/types.h index 602a080152..8c3a6b385e 100644 --- a/extras/mini-os/include/types.h +++ b/extras/mini-os/include/types.h @@ -54,7 +54,14 @@ typedef unsigned long uintptr_t; typedef struct { unsigned long pte; } pte_t; #endif - +typedef u8 uint8_t; +typedef s8 int8_t; +typedef u16 uint16_t; +typedef s16 int16_t; +typedef u32 uint32_t; +typedef s32 int32_t; +typedef u64 uint64_t; +typedef s64 int64_t; #define INT_MAX ((int)(~0U>>1)) diff --git a/extras/mini-os/kernel.c b/extras/mini-os/kernel.c index 2f8a485a07..495e1f6ae6 100644 --- a/extras/mini-os/kernel.c +++ b/extras/mini-os/kernel.c @@ -61,7 +61,7 @@ void failsafe_callback(void); extern char shared_info[PAGE_SIZE]; -#define __pte(x) ((pte_t) { (0) } ) +#define __pte(x) ((pte_t) { (x) } ) static shared_info_t *map_shared_info(unsigned long pa) { @@ -150,5 +150,5 @@ void start_kernel(start_info_t *si) void do_exit(void) { printk("do_exit called!\n"); - for ( ;; ) HYPERVISOR_shutdown(); + for ( ;; ) HYPERVISOR_sched_op(SCHEDOP_shutdown, SHUTDOWN_crash); } diff --git a/extras/mini-os/time.c b/extras/mini-os/time.c index dc4213389d..e66331e592 100644 --- a/extras/mini-os/time.c +++ b/extras/mini-os/time.c @@ -208,7 +208,7 @@ void block_domain(u32 millisecs) struct timeval tv; gettimeofday(&tv); HYPERVISOR_set_timer_op(monotonic_clock() + 1000000LL * (s64) millisecs); - HYPERVISOR_block(); + HYPERVISOR_sched_op(SCHEDOP_block, 0); } diff --git a/extras/mini-os/xenbus/xenbus_xs.c b/extras/mini-os/xenbus/xenbus_xs.c index 8a6348ab89..355133b5e6 100644 --- a/extras/mini-os/xenbus/xenbus_xs.c +++ b/extras/mini-os/xenbus/xenbus_xs.c @@ -39,7 +39,7 @@ #include #include #include -#include "xenstored.h" +#include #include "xenbus_comms.h" #define streq(a, b) (strcmp((a), (b)) == 0) @@ -408,7 +408,12 @@ static char *xs_read_watch(char **token) static int xs_acknowledge_watch(const char *token) { +#if 0 return xs_error(xs_single(XS_WATCH_ACK, token, NULL)); +#else + /* XS_WATCH_ACK is no longer available */ + return 0; +#endif } static int xs_unwatch(const char *path, const char *token) diff --git a/linux-2.6-xen-sparse/arch/ia64/xen/drivers/evtchn_ia64.c b/linux-2.6-xen-sparse/arch/ia64/xen/drivers/evtchn_ia64.c index 0027b82a62..ac8ff9ec4c 100644 --- a/linux-2.6-xen-sparse/arch/ia64/xen/drivers/evtchn_ia64.c +++ b/linux-2.6-xen-sparse/arch/ia64/xen/drivers/evtchn_ia64.c @@ -29,7 +29,7 @@ unsigned int bind_virq_to_evtchn(int virq) return op.u.bind_virq.port; } -int bind_virq_to_irq(int virq) +int bind_virq_to_irq(int virq, int cpu) { printk("bind_virq_to_irq called... FIXME??\n"); while(1); @@ -66,7 +66,11 @@ int bind_evtchn_to_irqhandler(unsigned int evtchn, evtchns[evtchn].handler = handler; evtchns[evtchn].dev_id = dev_id; unmask_evtchn(evtchn); - return 0; + //return 0; + /* On ia64, there's only one irq vector allocated for all event channels, + * so let's just return evtchn as handle for later communication + */ + return evtchn; } void unbind_evtchn_from_irqhandler(unsigned int evtchn, void *dev_id) diff --git a/linux-2.6-xen-sparse/arch/ia64/xen/xenentry.S b/linux-2.6-xen-sparse/arch/ia64/xen/xenentry.S index a7b33a932f..8d701f3284 100644 --- a/linux-2.6-xen-sparse/arch/ia64/xen/xenentry.S +++ b/linux-2.6-xen-sparse/arch/ia64/xen/xenentry.S @@ -46,8 +46,6 @@ GLOBAL_ENTRY(ia64_switch_to) .prologue alloc r16=ar.pfs,1,0,0,0 #endif - .prologue - alloc r16=ar.pfs,1,0,0,0 DO_SAVE_SWITCH_STACK .body diff --git a/linux-2.6-xen-sparse/arch/xen/i386/kernel/entry.S b/linux-2.6-xen-sparse/arch/xen/i386/kernel/entry.S index 24c2d5a5fe..d4ac275630 100644 --- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/entry.S +++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/entry.S @@ -653,7 +653,7 @@ ENTRY(simd_coprocessor_error) ENTRY(device_not_available) pushl $-1 # mark this as an int SAVE_ALL - preempt_stop + #preempt_stop /* This is already an interrupt gate on Xen. */ call math_state_restore jmp ret_from_exception diff --git a/linux-2.6-xen-sparse/arch/xen/i386/kernel/process.c b/linux-2.6-xen-sparse/arch/xen/i386/kernel/process.c index 3328dc94ff..8625d6750f 100644 --- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/process.c +++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/process.c @@ -483,6 +483,9 @@ struct task_struct fastcall * __switch_to(struct task_struct *prev_p, struct tas mcl->args[0] = 1; mcl++; } +#if 0 /* lazy fpu sanity check */ + else BUG_ON(!(read_cr0() & 8)); +#endif /* * Reload esp0, LDT and the page table pointer: diff --git a/linux-2.6-xen-sparse/arch/xen/i386/kernel/traps.c b/linux-2.6-xen-sparse/arch/xen/i386/kernel/traps.c index 81f701b8a4..5a22809760 100644 --- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/traps.c +++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/traps.c @@ -648,6 +648,12 @@ fastcall void do_int3(struct pt_regs *regs, long error_code) } #endif +static inline void conditional_sti(struct pt_regs *regs) +{ + if ((uint8_t)(regs->xcs >> 16) == 0) + local_irq_enable(); +} + /* * Our handling of the processor debug registers is non-trivial. * We do not clear them on entry and exit from the kernel. Therefore @@ -680,11 +686,9 @@ fastcall void do_debug(struct pt_regs * regs, long error_code) if (notify_die(DIE_DEBUG, "debug", regs, condition, error_code, SIGTRAP) == NOTIFY_STOP) return; -#if 0 + /* It's safe to allow irq's after DR6 has been saved */ - if (regs->eflags & X86_EFLAGS_IF) - local_irq_enable(); -#endif + conditional_sti(regs); /* Mask out spurious debug traps due to lazy DR7 setting */ if (condition & (DR_TRAP0|DR_TRAP1|DR_TRAP2|DR_TRAP3)) { @@ -967,15 +971,18 @@ void __init trap_init_f00f_bug(void) #endif -/* NB. All these are "trap gates" (i.e. events_mask isn't cleared). */ +/* + * NB. All these are "trap gates" (i.e. events_mask isn't cleared) except + * for those that specify |4 in the second field. + */ static trap_info_t trap_table[] = { { 0, 0, __KERNEL_CS, (unsigned long)divide_error }, - { 1, 0, __KERNEL_CS, (unsigned long)debug }, - { 3, 3, __KERNEL_CS, (unsigned long)int3 }, + { 1, 0|4, __KERNEL_CS, (unsigned long)debug }, + { 3, 3|4, __KERNEL_CS, (unsigned long)int3 }, { 4, 3, __KERNEL_CS, (unsigned long)overflow }, { 5, 3, __KERNEL_CS, (unsigned long)bounds }, { 6, 0, __KERNEL_CS, (unsigned long)invalid_op }, - { 7, 0, __KERNEL_CS, (unsigned long)device_not_available }, + { 7, 0|4, __KERNEL_CS, (unsigned long)device_not_available }, { 9, 0, __KERNEL_CS, (unsigned long)coprocessor_segment_overrun }, { 10, 0, __KERNEL_CS, (unsigned long)invalid_TSS }, { 11, 0, __KERNEL_CS, (unsigned long)segment_not_present }, diff --git a/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/setup.c b/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/setup.c index 9c51a4f270..0173775542 100644 --- a/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/setup.c +++ b/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/setup.c @@ -733,6 +733,7 @@ void __init setup_arch(char **cmdline_p) #ifdef CONFIG_XEN { int i, j, k, fpp; + unsigned long va; /* Make sure we have a large enough P->M table. */ phys_to_machine_mapping = alloc_bootmem( @@ -746,9 +747,21 @@ void __init setup_arch(char **cmdline_p) __pa(xen_start_info->mfn_list), PFN_PHYS(PFN_UP(xen_start_info->nr_pages * sizeof(unsigned long)))); - make_pages_readonly((void *)xen_start_info->mfn_list, - PFN_UP(xen_start_info->nr_pages * - sizeof(unsigned long))); + + /* 'Initial mapping' of old p2m table must be destroyed. */ + for (va = xen_start_info->mfn_list; + va < (xen_start_info->mfn_list + + (xen_start_info->nr_pages*sizeof(unsigned long))); + va += PAGE_SIZE) { + HYPERVISOR_update_va_mapping(va, __pte_ma(0), 0); + } + + /* 'Initial mapping' of initrd must be destroyed. */ + for (va = xen_start_info->mod_start; + va < (xen_start_info->mod_start+xen_start_info->mod_len); + va += PAGE_SIZE) { + HYPERVISOR_update_va_mapping(va, __pte_ma(0), 0); + } /* * Initialise the list of the frames that specify the list of diff --git a/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/xen_entry.S b/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/xen_entry.S index a71496cc63..5a1d57219e 100644 --- a/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/xen_entry.S +++ b/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/xen_entry.S @@ -5,7 +5,7 @@ #define evtchn_upcall_pending 0 #define evtchn_upcall_mask 1 -#define sizeof_vcpu_shift 3 +#define sizeof_vcpu_shift 4 #ifdef CONFIG_SMP //#define preempt_disable(reg) incl threadinfo_preempt_count(reg) diff --git a/linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c b/linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c index f630d4bf71..fab1ea6bc3 100644 --- a/linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c +++ b/linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c @@ -191,12 +191,13 @@ static int increase_reservation(unsigned long nr_pages) rc = HYPERVISOR_memory_op( XENMEM_increase_reservation, &reservation); if (rc < nr_pages) { + int ret; /* We hit the Xen hard limit: reprobe. */ reservation.extent_start = mfn_list; reservation.nr_extents = rc; - BUG_ON(HYPERVISOR_memory_op( - XENMEM_decrease_reservation, - &reservation) != rc); + ret = HYPERVISOR_memory_op(XENMEM_decrease_reservation, + &reservation); + BUG_ON(ret != rc); hard_limit = current_pages + rc - driver_pages; goto out; } @@ -213,11 +214,14 @@ static int increase_reservation(unsigned long nr_pages) xen_machphys_update(mfn_list[i], pfn); /* Link back into the page tables if not highmem. */ - if (pfn < max_low_pfn) - BUG_ON(HYPERVISOR_update_va_mapping( + if (pfn < max_low_pfn) { + int ret; + ret = HYPERVISOR_update_va_mapping( (unsigned long)__va(pfn << PAGE_SHIFT), pfn_pte_ma(mfn_list[i], PAGE_KERNEL), - 0)); + 0); + BUG_ON(ret); + } /* Relinquish the page back to the allocator. */ ClearPageReserved(page); @@ -242,6 +246,7 @@ static int decrease_reservation(unsigned long nr_pages) struct page *page; void *v; int need_sleep = 0; + int ret; struct xen_memory_reservation reservation = { .address_bits = 0, .extent_order = 0, @@ -268,8 +273,9 @@ static int decrease_reservation(unsigned long nr_pages) if (!PageHighMem(page)) { v = phys_to_virt(pfn << PAGE_SHIFT); scrub_pages(v, 1); - BUG_ON(HYPERVISOR_update_va_mapping( - (unsigned long)v, __pte_ma(0), 0)); + ret = HYPERVISOR_update_va_mapping( + (unsigned long)v, __pte_ma(0), 0); + BUG_ON(ret); } #ifdef CONFIG_XEN_SCRUB_PAGES else { @@ -295,8 +301,8 @@ static int decrease_reservation(unsigned long nr_pages) reservation.extent_start = mfn_list; reservation.nr_extents = nr_pages; - BUG_ON(HYPERVISOR_memory_op( - XENMEM_decrease_reservation, &reservation) != nr_pages); + ret = HYPERVISOR_memory_op(XENMEM_decrease_reservation, &reservation); + BUG_ON(ret != nr_pages); current_pages -= nr_pages; totalram_pages = current_pages; @@ -501,6 +507,7 @@ static int dealloc_pte_fn( pte_t *pte, struct page *pte_page, unsigned long addr, void *data) { unsigned long mfn = pte_mfn(*pte); + int ret; struct xen_memory_reservation reservation = { .extent_start = &mfn, .nr_extents = 1, @@ -510,8 +517,8 @@ static int dealloc_pte_fn( set_pte_at(&init_mm, addr, pte, __pte_ma(0)); phys_to_machine_mapping[__pa(addr) >> PAGE_SHIFT] = INVALID_P2M_ENTRY; - BUG_ON(HYPERVISOR_memory_op( - XENMEM_decrease_reservation, &reservation) != 1); + ret = HYPERVISOR_memory_op(XENMEM_decrease_reservation, &reservation); + BUG_ON(ret != 1); return 0; } @@ -519,6 +526,7 @@ struct page *balloon_alloc_empty_page_range(unsigned long nr_pages) { unsigned long vstart, flags; unsigned int order = get_order(nr_pages * PAGE_SIZE); + int ret; vstart = __get_free_pages(GFP_KERNEL, order); if (vstart == 0) @@ -527,8 +535,9 @@ struct page *balloon_alloc_empty_page_range(unsigned long nr_pages) scrub_pages(vstart, 1 << order); balloon_lock(flags); - BUG_ON(generic_page_range( - &init_mm, vstart, PAGE_SIZE << order, dealloc_pte_fn, NULL)); + ret = generic_page_range( + &init_mm, vstart, PAGE_SIZE << order, dealloc_pte_fn, NULL); + BUG_ON(ret); current_pages -= 1UL << order; balloon_unlock(flags); diff --git a/linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c b/linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c index c9d812695e..3dc929f0a7 100644 --- a/linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c +++ b/linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c @@ -108,6 +108,7 @@ static void fast_flush_area(int idx, int nr_pages) struct gnttab_unmap_grant_ref unmap[BLKIF_MAX_SEGMENTS_PER_REQUEST]; unsigned int i, invcount = 0; u16 handle; + int ret; for (i = 0; i < nr_pages; i++) { handle = pending_handle(idx, i); @@ -120,8 +121,9 @@ static void fast_flush_area(int idx, int nr_pages) invcount++; } - BUG_ON(HYPERVISOR_grant_table_op( - GNTTABOP_unmap_grant_ref, unmap, invcount)); + ret = HYPERVISOR_grant_table_op( + GNTTABOP_unmap_grant_ref, unmap, invcount); + BUG_ON(ret); } @@ -338,6 +340,7 @@ static void dispatch_rw_block_io(blkif_t *blkif, blkif_request_t *req) struct bio *bio = NULL, *biolist[BLKIF_MAX_SEGMENTS_PER_REQUEST]; int nbio = 0; request_queue_t *q; + int ret; /* Check that number of segments is sane. */ nseg = req->nr_segments; @@ -367,8 +370,8 @@ static void dispatch_rw_block_io(blkif_t *blkif, blkif_request_t *req) map[i].flags |= GNTMAP_readonly; } - BUG_ON(HYPERVISOR_grant_table_op( - GNTTABOP_map_grant_ref, map, nseg)); + ret = HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, map, nseg); + BUG_ON(ret); for (i = 0; i < nseg; i++) { if (unlikely(map[i].handle < 0)) { @@ -493,6 +496,7 @@ static int __init blkif_init(void) { int i; struct page *page; + int ret; blkif_interface_init(); @@ -509,7 +513,8 @@ static int __init blkif_init(void) spin_lock_init(&blkio_schedule_list_lock); INIT_LIST_HEAD(&blkio_schedule_list); - BUG_ON(kernel_thread(blkio_schedule, 0, CLONE_FS | CLONE_FILES) < 0); + ret = kernel_thread(blkio_schedule, 0, CLONE_FS | CLONE_FILES); + BUG_ON(ret < 0); blkif_xenbus_init(); diff --git a/linux-2.6-xen-sparse/drivers/xen/blkback/interface.c b/linux-2.6-xen-sparse/drivers/xen/blkback/interface.c index ee1889a09a..be6f935191 100644 --- a/linux-2.6-xen-sparse/drivers/xen/blkback/interface.c +++ b/linux-2.6-xen-sparse/drivers/xen/blkback/interface.c @@ -31,6 +31,7 @@ blkif_t *alloc_blkif(domid_t domid) static int map_frontend_page(blkif_t *blkif, unsigned long shared_page) { struct gnttab_map_grant_ref op; + int ret; op.host_addr = (unsigned long)blkif->blk_ring_area->addr; op.flags = GNTMAP_host_map; @@ -38,8 +39,9 @@ static int map_frontend_page(blkif_t *blkif, unsigned long shared_page) op.dom = blkif->domid; lock_vm_area(blkif->blk_ring_area); - BUG_ON(HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1)); + ret = HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1); unlock_vm_area(blkif->blk_ring_area); + BUG_ON(ret); if (op.handle < 0) { DPRINTK(" Grant table operation failure !\n"); @@ -55,14 +57,16 @@ static int map_frontend_page(blkif_t *blkif, unsigned long shared_page) static void unmap_frontend_page(blkif_t *blkif) { struct gnttab_unmap_grant_ref op; + int ret; op.host_addr = (unsigned long)blkif->blk_ring_area->addr; op.handle = blkif->shmem_handle; op.dev_bus_addr = 0; lock_vm_area(blkif->blk_ring_area); - BUG_ON(HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1)); + ret = HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1); unlock_vm_area(blkif->blk_ring_area); + BUG_ON(ret); } int blkif_map(blkif_t *blkif, unsigned long shared_page, unsigned int evtchn) diff --git a/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c b/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c index 671f16038c..3485d84424 100644 --- a/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c +++ b/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c @@ -305,6 +305,7 @@ static irqreturn_t blkif_int(int irq, void *dev_id, struct pt_regs *ptregs) for (i = info->ring.rsp_cons; i != rp; i++) { unsigned long id; + int ret; bret = RING_GET_RESPONSE(&info->ring, i); id = bret->id; @@ -321,9 +322,10 @@ static irqreturn_t blkif_int(int irq, void *dev_id, struct pt_regs *ptregs) DPRINTK("Bad return from blkdev data " "request: %x\n", bret->status); - BUG_ON(end_that_request_first( + ret = end_that_request_first( req, (bret->status == BLKIF_RSP_OKAY), - req->hard_nr_sectors)); + req->hard_nr_sectors); + BUG_ON(ret); end_that_request_last(req); break; default: diff --git a/linux-2.6-xen-sparse/drivers/xen/blktap/blktap.c b/linux-2.6-xen-sparse/drivers/xen/blktap/blktap.c index dacedfc227..03a4fcb970 100644 --- a/linux-2.6-xen-sparse/drivers/xen/blktap/blktap.c +++ b/linux-2.6-xen-sparse/drivers/xen/blktap/blktap.c @@ -413,6 +413,7 @@ static void fast_flush_area(int idx, int nr_pages) unsigned int i, op = 0; struct grant_handle_pair *handle; unsigned long ptep; + int ret; for ( i = 0; i < nr_pages; i++) { @@ -440,8 +441,8 @@ static void fast_flush_area(int idx, int nr_pages) BLKTAP_INVALIDATE_HANDLE(handle); } - BUG_ON(HYPERVISOR_grant_table_op( - GNTTABOP_unmap_grant_ref, unmap, op)); + ret = HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, unmap, op); + BUG_ON(ret); if (blktap_vma != NULL) zap_page_range(blktap_vma, @@ -673,6 +674,7 @@ static void dispatch_rw_block_io(blkif_t *blkif, blkif_request_t *req) struct gnttab_map_grant_ref map[BLKIF_MAX_SEGMENTS_PER_REQUEST*2]; int op, ret; unsigned int nseg; + int retval; /* Check that number of segments is sane. */ nseg = req->nr_segments; @@ -740,8 +742,8 @@ static void dispatch_rw_block_io(blkif_t *blkif, blkif_request_t *req) op++; } - BUG_ON(HYPERVISOR_grant_table_op( - GNTTABOP_map_grant_ref, map, op)); + retval = HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, map, op); + BUG_ON(retval); op = 0; for (i = 0; i < (req->nr_segments*2); i += 2) { @@ -877,7 +879,8 @@ static int __init blkif_init(void) spin_lock_init(&blkio_schedule_list_lock); INIT_LIST_HEAD(&blkio_schedule_list); - BUG_ON(kernel_thread(blkio_schedule, 0, CLONE_FS | CLONE_FILES) < 0); + i = kernel_thread(blkio_schedule, 0, CLONE_FS | CLONE_FILES); + BUG_ON(i<0); blkif_xenbus_init(); diff --git a/linux-2.6-xen-sparse/drivers/xen/blktap/interface.c b/linux-2.6-xen-sparse/drivers/xen/blktap/interface.c index 1394922ac7..dcaedf875e 100644 --- a/linux-2.6-xen-sparse/drivers/xen/blktap/interface.c +++ b/linux-2.6-xen-sparse/drivers/xen/blktap/interface.c @@ -31,6 +31,7 @@ blkif_t *alloc_blkif(domid_t domid) static int map_frontend_page(blkif_t *blkif, unsigned long shared_page) { struct gnttab_map_grant_ref op; + int ret; op.host_addr = (unsigned long)blkif->blk_ring_area->addr; op.flags = GNTMAP_host_map; @@ -38,8 +39,9 @@ static int map_frontend_page(blkif_t *blkif, unsigned long shared_page) op.dom = blkif->domid; lock_vm_area(blkif->blk_ring_area); - BUG_ON(HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1)); + ret = HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1); unlock_vm_area(blkif->blk_ring_area); + BUG_ON(ret); if (op.handle < 0) { DPRINTK(" Grant table operation failure !\n"); @@ -55,14 +57,16 @@ static int map_frontend_page(blkif_t *blkif, unsigned long shared_page) static void unmap_frontend_page(blkif_t *blkif) { struct gnttab_unmap_grant_ref op; + int ret; op.host_addr = (unsigned long)blkif->blk_ring_area->addr; op.handle = blkif->shmem_handle; op.dev_bus_addr = 0; lock_vm_area(blkif->blk_ring_area); - BUG_ON(HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1)); + ret = HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1); unlock_vm_area(blkif->blk_ring_area); + BUG_ON(ret); } int blkif_map(blkif_t *blkif, unsigned long shared_page, unsigned int evtchn) diff --git a/linux-2.6-xen-sparse/drivers/xen/evtchn/evtchn.c b/linux-2.6-xen-sparse/drivers/xen/evtchn/evtchn.c index d3a805fb72..42f4a8f70a 100644 --- a/linux-2.6-xen-sparse/drivers/xen/evtchn/evtchn.c +++ b/linux-2.6-xen-sparse/drivers/xen/evtchn/evtchn.c @@ -282,6 +282,7 @@ static int evtchn_ioctl(struct inode *inode, struct file *file, case IOCTL_EVTCHN_UNBIND: { struct ioctl_evtchn_unbind unbind; + int ret; rc = -EFAULT; if (copy_from_user(&unbind, (void *)arg, sizeof(unbind))) @@ -306,7 +307,8 @@ static int evtchn_ioctl(struct inode *inode, struct file *file, op.cmd = EVTCHNOP_close; op.u.close.port = unbind.port; - BUG_ON(HYPERVISOR_event_channel_op(&op)); + ret = HYPERVISOR_event_channel_op(&op); + BUG_ON(ret); rc = 0; break; @@ -399,6 +401,7 @@ static int evtchn_release(struct inode *inode, struct file *filp) for (i = 0; i < NR_EVENT_CHANNELS; i++) { + int ret; if (port_user[i] != u) continue; @@ -407,7 +410,8 @@ static int evtchn_release(struct inode *inode, struct file *filp) op.cmd = EVTCHNOP_close; op.u.close.port = i; - BUG_ON(HYPERVISOR_event_channel_op(&op)); + ret = HYPERVISOR_event_channel_op(&op); + BUG_ON(ret); } spin_unlock_irq(&port_user_lock); diff --git a/linux-2.6-xen-sparse/drivers/xen/netback/interface.c b/linux-2.6-xen-sparse/drivers/xen/netback/interface.c index 404eb98831..7cfd3c944c 100644 --- a/linux-2.6-xen-sparse/drivers/xen/netback/interface.c +++ b/linux-2.6-xen-sparse/drivers/xen/netback/interface.c @@ -115,6 +115,7 @@ static int map_frontend_pages( netif_t *netif, grant_ref_t tx_ring_ref, grant_ref_t rx_ring_ref) { struct gnttab_map_grant_ref op; + int ret; op.host_addr = (unsigned long)netif->comms_area->addr; op.flags = GNTMAP_host_map; @@ -122,8 +123,9 @@ static int map_frontend_pages( op.dom = netif->domid; lock_vm_area(netif->comms_area); - BUG_ON(HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1)); + ret = HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1); unlock_vm_area(netif->comms_area); + BUG_ON(ret); if (op.handle < 0) { DPRINTK(" Gnttab failure mapping tx_ring_ref!\n"); @@ -139,8 +141,9 @@ static int map_frontend_pages( op.dom = netif->domid; lock_vm_area(netif->comms_area); - BUG_ON(HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1)); + ret = HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1); unlock_vm_area(netif->comms_area); + BUG_ON(ret); if (op.handle < 0) { DPRINTK(" Gnttab failure mapping rx_ring_ref!\n"); @@ -156,22 +159,25 @@ static int map_frontend_pages( static void unmap_frontend_pages(netif_t *netif) { struct gnttab_unmap_grant_ref op; + int ret; op.host_addr = (unsigned long)netif->comms_area->addr; op.handle = netif->tx_shmem_handle; op.dev_bus_addr = 0; lock_vm_area(netif->comms_area); - BUG_ON(HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1)); + ret = HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1); unlock_vm_area(netif->comms_area); + BUG_ON(ret); op.host_addr = (unsigned long)netif->comms_area->addr + PAGE_SIZE; op.handle = netif->rx_shmem_handle; op.dev_bus_addr = 0; lock_vm_area(netif->comms_area); - BUG_ON(HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1)); + ret = HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1); unlock_vm_area(netif->comms_area); + BUG_ON(ret); } int netif_map(netif_t *netif, unsigned long tx_ring_ref, diff --git a/linux-2.6-xen-sparse/drivers/xen/netback/netback.c b/linux-2.6-xen-sparse/drivers/xen/netback/netback.c index 656ed94ded..2eee002ec6 100644 --- a/linux-2.6-xen-sparse/drivers/xen/netback/netback.c +++ b/linux-2.6-xen-sparse/drivers/xen/netback/netback.c @@ -112,9 +112,12 @@ static void free_mfn(unsigned long mfn) spin_lock_irqsave(&mfn_lock, flags); if ( alloc_index != MAX_MFN_ALLOC ) mfn_list[alloc_index++] = mfn; - else - BUG_ON(HYPERVISOR_memory_op(XENMEM_decrease_reservation, - &reservation) != 1); + else { + int ret; + ret = HYPERVISOR_memory_op(XENMEM_decrease_reservation, + &reservation); + BUG_ON(ret != 1); + } spin_unlock_irqrestore(&mfn_lock, flags); } #endif @@ -159,13 +162,15 @@ int netif_be_start_xmit(struct sk_buff *skb, struct net_device *dev) */ if (skb_shared(skb) || skb_cloned(skb) || !is_xen_skb(skb)) { int hlen = skb->data - skb->head; + int ret; struct sk_buff *nskb = dev_alloc_skb(hlen + skb->len); if ( unlikely(nskb == NULL) ) goto drop; skb_reserve(nskb, hlen); __skb_put(nskb, skb->len); - BUG_ON(skb_copy_bits(skb, -hlen, nskb->data - hlen, - skb->len + hlen)); + ret = skb_copy_bits(skb, -hlen, nskb->data - hlen, + skb->len + hlen); + BUG_ON(ret); nskb->dev = skb->dev; nskb->proto_csum_valid = skb->proto_csum_valid; dev_kfree_skb(skb); @@ -218,6 +223,7 @@ static void net_rx_action(unsigned long unused) struct sk_buff *skb; u16 notify_list[NETIF_RX_RING_SIZE]; int notify_nr = 0; + int ret; skb_queue_head_init(&rxq); @@ -279,7 +285,8 @@ static void net_rx_action(unsigned long unused) mcl++; mcl[-2].args[MULTI_UVMFLAGS_INDEX] = UVMF_TLB_FLUSH|UVMF_ALL; - BUG_ON(HYPERVISOR_multicall(rx_mcl, mcl - rx_mcl) != 0); + ret = HYPERVISOR_multicall(rx_mcl, mcl - rx_mcl); + BUG_ON(ret != 0); mcl = rx_mcl; if( HYPERVISOR_grant_table_op(GNTTABOP_transfer, grant_rx_op, @@ -421,6 +428,7 @@ inline static void net_tx_action_dealloc(void) u16 pending_idx; PEND_RING_IDX dc, dp; netif_t *netif; + int ret; dc = dealloc_cons; dp = dealloc_prod; @@ -436,8 +444,9 @@ inline static void net_tx_action_dealloc(void) gop->handle = grant_tx_ref[pending_idx]; gop++; } - BUG_ON(HYPERVISOR_grant_table_op( - GNTTABOP_unmap_grant_ref, tx_unmap_ops, gop - tx_unmap_ops)); + ret = HYPERVISOR_grant_table_op( + GNTTABOP_unmap_grant_ref, tx_unmap_ops, gop - tx_unmap_ops); + BUG_ON(ret); while (dealloc_cons != dp) { pending_idx = dealloc_ring[MASK_PEND_IDX(dealloc_cons++)]; @@ -477,6 +486,7 @@ static void net_tx_action(unsigned long unused) NETIF_RING_IDX i; gnttab_map_grant_ref_t *mop; unsigned int data_len; + int ret; if (dealloc_cons != dealloc_prod) net_tx_action_dealloc(); @@ -599,8 +609,9 @@ static void net_tx_action(unsigned long unused) if (mop == tx_map_ops) return; - BUG_ON(HYPERVISOR_grant_table_op( - GNTTABOP_map_grant_ref, tx_map_ops, mop - tx_map_ops)); + ret = HYPERVISOR_grant_table_op( + GNTTABOP_map_grant_ref, tx_map_ops, mop - tx_map_ops); + BUG_ON(ret); mop = tx_map_ops; while ((skb = __skb_dequeue(&tx_queue)) != NULL) { diff --git a/linux-2.6-xen-sparse/drivers/xen/privcmd/privcmd.c b/linux-2.6-xen-sparse/drivers/xen/privcmd/privcmd.c index b13f22a771..db954ca768 100644 --- a/linux-2.6-xen-sparse/drivers/xen/privcmd/privcmd.c +++ b/linux-2.6-xen-sparse/drivers/xen/privcmd/privcmd.c @@ -25,8 +25,8 @@ #include #include #include -#include #include +#include #include #include #include diff --git a/linux-2.6-xen-sparse/drivers/xen/tpmback/interface.c b/linux-2.6-xen-sparse/drivers/xen/tpmback/interface.c index 98db181306..6dc05d217b 100644 --- a/linux-2.6-xen-sparse/drivers/xen/tpmback/interface.c +++ b/linux-2.6-xen-sparse/drivers/xen/tpmback/interface.c @@ -78,6 +78,7 @@ tpmif_find(domid_t domid, long int instance) static int map_frontend_page(tpmif_t *tpmif, unsigned long shared_page) { + int ret; struct gnttab_map_grant_ref op = { .host_addr = (unsigned long)tpmif->tx_area->addr, .flags = GNTMAP_host_map, @@ -86,8 +87,9 @@ map_frontend_page(tpmif_t *tpmif, unsigned long shared_page) }; lock_vm_area(tpmif->tx_area); - BUG_ON(HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1)); + ret = HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1); unlock_vm_area(tpmif->tx_area); + BUG_ON(ret); if (op.handle < 0) { DPRINTK(" Grant table operation failure !\n"); @@ -104,14 +106,16 @@ static void unmap_frontend_page(tpmif_t *tpmif) { struct gnttab_unmap_grant_ref op; + int ret; op.host_addr = (unsigned long)tpmif->tx_area->addr; op.handle = tpmif->shmem_handle; op.dev_bus_addr = 0; lock_vm_area(tpmif->tx_area); - BUG_ON(HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1)); + ret = HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1); unlock_vm_area(tpmif->tx_area); + BUG_ON(ret); } int diff --git a/linux-2.6-xen-sparse/drivers/xen/util.c b/linux-2.6-xen-sparse/drivers/xen/util.c index 8df067f29e..be2b155cf1 100644 --- a/linux-2.6-xen-sparse/drivers/xen/util.c +++ b/linux-2.6-xen-sparse/drivers/xen/util.c @@ -34,7 +34,9 @@ struct vm_struct *alloc_vm_area(unsigned long size) void free_vm_area(struct vm_struct *area) { - BUG_ON(remove_vm_area(area->addr) != area); + struct vm_struct *ret; + ret = remove_vm_area(area->addr); + BUG_ON(ret != area); kfree(area); } diff --git a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c index e5c9de1139..a0d5b4edb1 100644 --- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c +++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c @@ -714,11 +714,7 @@ static int xsd_port_read(char *page, char **start, off_t off, static int __init xenbus_probe_init(void) { - int err = 0; - /* - ** Domain0 doesn't have a store_evtchn or store_mfn yet. - */ - int dom0 = (xen_start_info->store_evtchn == 0); + int err = 0, dom0; printk("xenbus_probe_init\n"); @@ -733,10 +729,16 @@ static int __init xenbus_probe_init(void) device_register(&xenbus_frontend.dev); device_register(&xenbus_backend.dev); + /* + ** Domain0 doesn't have a store_evtchn or store_mfn yet. + */ + dom0 = (xen_start_info->store_evtchn == 0); + if (dom0) { unsigned long page; evtchn_op_t op = { 0 }; + int ret; /* Allocate page. */ @@ -757,7 +759,8 @@ static int __init xenbus_probe_init(void) op.u.alloc_unbound.dom = DOMID_SELF; op.u.alloc_unbound.remote_dom = 0; - BUG_ON(HYPERVISOR_event_channel_op(&op)); + ret = HYPERVISOR_event_channel_op(&op); + BUG_ON(ret); xen_start_info->store_evtchn = op.u.alloc_unbound.port; /* And finally publish the above info in /proc/xen */ diff --git a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c index 3daf866f33..d55037177b 100644 --- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c +++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c @@ -28,6 +28,7 @@ * IN THE SOFTWARE. */ +#include #include #include #include diff --git a/tools/examples/Makefile b/tools/examples/Makefile index ea358adabf..c1e974093b 100644 --- a/tools/examples/Makefile +++ b/tools/examples/Makefile @@ -17,6 +17,7 @@ XEN_CONFIGS = xend-config.sxp XEN_CONFIGS += xmexample1 XEN_CONFIGS += xmexample2 XEN_CONFIGS += xmexample.vmx +XEN_CONFIGS += xmexample.vti # Xen script dir and scripts to go there. XEN_SCRIPT_DIR = /etc/xen/scripts diff --git a/tools/examples/xmexample.vti b/tools/examples/xmexample.vti new file mode 100644 index 0000000000..63bdc25d3a --- /dev/null +++ b/tools/examples/xmexample.vti @@ -0,0 +1,100 @@ +# -*- 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. +#============================================================================ + +import os, re +arch = os.uname()[4] +arch_libdir = 'lib' + +#---------------------------------------------------------------------------- +# Kernel image file. +kernel = "/boot/Flash.fd" + +# The domain build function. VMX domain uses 'vmx'. +builder='vmx' + +# Initial memory allocation (in megabytes) for the new domain. +memory = 256 + +# A name for your domain. All domains must have different names. +name = "ExampleVMXDomain" + +# Which CPU to start domain on? +#cpu = -1 # leave to Xen to pick + +# Optionally define mac and/or bridge for the network interfaces. +# Random MACs are assigned if not given. +#vif = [ 'mac=aa:00:00:00:00:11, bridge=xen-br0' ] + +#---------------------------------------------------------------------------- +# 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. + +#disk = [ 'phy:hda1,hda1,r' ] +disk = [ 'file:/var/images/xenia64.img,ioemu:hda,w' ] + +#---------------------------------------------------------------------------- +# Set according to whether you want the domain restarted when it exits. +# The default is 'onreboot', which restarts the domain when it shuts down +# with exit code reboot. +# Other values are 'always', and 'never'. + +#restart = 'onreboot' + +#============================================================================ + +# New stuff +device_model = '/usr/' + arch_libdir + '/xen/bin/qemu-dm.debug' + +# Advanced users only. Don't touch if you don't know what you're doing +memmap = '/usr/lib/xen/boot/mem-map.sxp' + +#----------------------------------------------------------------------------- +# Disk image for +#cdrom= + +#----------------------------------------------------------------------------- +# boot on floppy (a), hard disk (c) or CD-ROM (d) +#boot=[a|c|d] +#----------------------------------------------------------------------------- +# write to temporary files instead of disk image files +#snapshot=1 + +#---------------------------------------------------------------------------- +# enable SDL library for graphics, default = 0 +sdl=1 + +stdvga=1 +#---------------------------------------------------------------------------- +# enable VNC library for graphics, default = 1 +vnc=0 + +#---------------------------------------------------------------------------- +# enable spawning vncviewer(only valid when vnc=1), default = 1 +vncviewer=0 + +#---------------------------------------------------------------------------- +# no graphics, use serial port +#nographic=0 + + +#----------------------------------------------------------------------------- +# enable audio support +#enable-audio=1 + + +#----------------------------------------------------------------------------- +# set the real time clock to local time [default=0 i.e. set to utc] +#localtime=1 + + +#----------------------------------------------------------------------------- +# start in full screen +#full-screen=1 diff -r 42cab8724273 tools/libxc/xc_ia64_stubs.c diff --git a/tools/ioemu/hw/ide.c b/tools/ioemu/hw/ide.c index c0228cbd9e..71ad561154 100644 --- a/tools/ioemu/hw/ide.c +++ b/tools/ioemu/hw/ide.c @@ -22,6 +22,7 @@ * THE SOFTWARE. */ #include "vl.h" +#include /* debug IDE devices */ //#define DEBUG_IDE @@ -360,6 +361,48 @@ typedef struct PCIIDEState { BMDMAState bmdma[2]; } PCIIDEState; +#define DMA_MULTI_THREAD + +#ifdef DMA_MULTI_THREAD + +static int file_pipes[2]; + +static void ide_dma_loop(BMDMAState *bm); +static void dma_thread_loop(BMDMAState *bm); + +static void *dma_thread_func(void* opaque) +{ + BMDMAState* req; + + while (read(file_pipes[0], &req, sizeof(req))) { + dma_thread_loop(req); + } + + return NULL; +} + +static void dma_create_thread() +{ + pthread_t tid; + int rt; + + if (pipe(file_pipes) != 0){ + fprintf(stderr, "create pipe failed\n"); + exit(1); + } + + if ( (rt = pthread_create(&tid, NULL, dma_thread_func, NULL)) ) { + fprintf(stderr, "Oops, dma thread creation failed, errno=%d\n", rt); + exit(1); + } + + if ( (rt = pthread_detach(tid)) ) { + fprintf(stderr, "Oops, dma thread detachment failed, errno=%d\n", rt); + exit(1); + } +} +#endif //DMA_MULTI_THREAD + static void ide_dma_start(IDEState *s, IDEDMAFunc *dma_cb); static void padstr(char *str, const char *src, int len) @@ -1978,7 +2021,15 @@ static void ide_map(PCIDevice *pci_dev, int region_num, /* XXX: full callback usage to prepare non blocking I/Os support - error handling */ +#ifdef DMA_MULTI_THREAD static void ide_dma_loop(BMDMAState *bm) +{ + write(file_pipes[1], &bm, sizeof(bm)); +} +static void dma_thread_loop(BMDMAState *bm) +#else +static void ide_dma_loop(BMDMAState *bm) +#endif //DMA_MULTI_THREAD { struct { uint32_t addr; @@ -2166,6 +2217,9 @@ void pci_ide_init(PCIBus *bus, BlockDriverState **hd_table) d->ide_if[i].pci_dev = (PCIDevice *)d; ide_init2(&d->ide_if[0], 16, hd_table[0], hd_table[1]); ide_init2(&d->ide_if[2], 16, hd_table[2], hd_table[3]); +#ifdef DMA_MULTI_THREAD + dma_create_thread(); +#endif //DMA_MULTI_THREAD } /* hd_table must contain 4 block drivers */ @@ -2196,6 +2250,9 @@ void pci_piix3_ide_init(PCIBus *bus, BlockDriverState **hd_table) ide_init2(&d->ide_if[2], 15, hd_table[2], hd_table[3]); ide_init_ioport(&d->ide_if[0], 0x1f0, 0x3f6); ide_init_ioport(&d->ide_if[2], 0x170, 0x376); +#ifdef DMA_MULTI_THREAD + dma_create_thread(); +#endif //DMA_MULTI_THREAD } /***********************************************************/ diff --git a/tools/libxc/xc_elf.h b/tools/libxc/xc_elf.h index e0d0c26131..da5e7b3bc8 100644 --- a/tools/libxc/xc_elf.h +++ b/tools/libxc/xc_elf.h @@ -24,26 +24,26 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -typedef u_int8_t Elf_Byte; +typedef uint8_t Elf_Byte; -typedef u_int32_t Elf32_Addr; /* Unsigned program address */ -typedef u_int32_t Elf32_Off; /* Unsigned file offset */ +typedef uint32_t Elf32_Addr; /* Unsigned program address */ +typedef uint32_t Elf32_Off; /* Unsigned file offset */ typedef int32_t Elf32_Sword; /* Signed large integer */ -typedef u_int32_t Elf32_Word; /* Unsigned large integer */ -typedef u_int16_t Elf32_Half; /* Unsigned medium integer */ +typedef uint32_t Elf32_Word; /* Unsigned large integer */ +typedef uint16_t Elf32_Half; /* Unsigned medium integer */ -typedef u_int64_t Elf64_Addr; -typedef u_int64_t Elf64_Off; +typedef uint64_t Elf64_Addr; +typedef uint64_t Elf64_Off; typedef int32_t Elf64_Shalf; typedef int32_t Elf64_Sword; -typedef u_int32_t Elf64_Word; +typedef uint32_t Elf64_Word; typedef int64_t Elf64_Sxword; -typedef u_int64_t Elf64_Xword; +typedef uint64_t Elf64_Xword; -typedef u_int32_t Elf64_Half; -typedef u_int16_t Elf64_Quarter; +typedef uint32_t Elf64_Half; +typedef uint16_t Elf64_Quarter; /* * e_ident[] identification indexes diff --git a/tools/libxc/xc_ia64_stubs.c b/tools/libxc/xc_ia64_stubs.c index b171ea37ef..b21959b8d2 100644 --- a/tools/libxc/xc_ia64_stubs.c +++ b/tools/libxc/xc_ia64_stubs.c @@ -1,5 +1,11 @@ #include "xg_private.h" #include "xenguest.h" +#include "xc_private.h" +#include "xc_elf.h" +#include +#include +#include "xen/arch-ia64.h" +#include int xc_linux_save(int xc_handle, int io_fd, uint32_t dom, uint32_t max_iters, uint32_t max_factor, uint32_t flags) @@ -16,22 +22,6 @@ int xc_linux_restore(int xc_handle, int io_fd, uint32_t dom, unsigned long nr_pf return -1; } -int xc_vmx_build(int xc_handle, - uint32_t domid, - int memsize, - const char *image_name, - struct mem_map *mem_mapp, - const char *ramdisk_name, - const char *cmdline, - unsigned int control_evtchn, - unsigned int vcpus, - unsigned int store_evtchn, - unsigned long *store_mfn) -{ - PERROR("xc_vmx_build not implemented\n"); - return -1; -} - int xc_plan9_build(int xc_handle, uint32_t domid, @@ -43,6 +33,653 @@ xc_plan9_build(int xc_handle, return -1; } +int xc_ia64_get_pfn_list(int xc_handle, + uint32_t domid, + unsigned long *pfn_buf, + unsigned int start_page, + unsigned int nr_pages) +{ + dom0_op_t op; + int ret; + unsigned long max_pfns = ((unsigned long)start_page << 32) | nr_pages; + + op.cmd = DOM0_GETMEMLIST; + op.u.getmemlist.domain = (domid_t)domid; + op.u.getmemlist.max_pfns = max_pfns; + op.u.getmemlist.buffer = pfn_buf; + + if ( (max_pfns != -1UL) + && mlock(pfn_buf, nr_pages * sizeof(unsigned long)) != 0 ) + { + PERROR("Could not lock pfn list buffer"); + return -1; + } + + ret = do_dom0_op(xc_handle, &op); + + if (max_pfns != -1UL) + (void)munlock(pfn_buf, nr_pages * sizeof(unsigned long)); + + return (ret < 0) ? -1 : op.u.getmemlist.num_pfns; +} + +long xc_get_max_pages(int xc_handle, uint32_t domid) +{ + dom0_op_t op; + op.cmd = DOM0_GETDOMAININFO; + op.u.getdomaininfo.domain = (domid_t)domid; + return (do_dom0_op(xc_handle, &op) < 0) ? + -1 : op.u.getdomaininfo.max_pages; +} + +int xc_ia64_copy_to_domain_pages(int xc_handle, uint32_t domid, + void* src_page, unsigned long dst_pfn, int nr_pages) +{ + // N.B. gva should be page aligned + + unsigned long *page_array=NULL; + int i; + + if ( (page_array = malloc(nr_pages * sizeof(unsigned long))) == NULL ){ + PERROR("Could not allocate memory"); + goto error_out; + } + if ( xc_ia64_get_pfn_list(xc_handle, domid, page_array, + dst_pfn>>PAGE_SHIFT, nr_pages) != nr_pages ){ + PERROR("Could not get the page frame list"); + goto error_out; + } + + for ( i=0; i< nr_pages; i++ ){ + if (xc_copy_to_domain_page(xc_handle, domid, page_array[i], + src_page + (i << PAGE_SHIFT))) + goto error_out; + } + free(page_array); + return 0; + +error_out: + if (page_array) + free(page_array); + return -1; +} + + +#define HOB_SIGNATURE 0x3436474953424f48 // "HOBSIG64" +#define GFW_HOB_START ((4UL<<30)-(14UL<<20)) //4G -14M +#define GFW_HOB_SIZE (1UL<<20) //1M +#define MEM_G (1UL << 30) +#define MEM_M (1UL << 20) + +typedef struct { + unsigned long signature; + unsigned int type; + unsigned int length; +} HOB_GENERIC_HEADER; + +/* + * INFO HOB is the first data data in one HOB list + * it contains the control information of the HOB list + */ +typedef struct { + HOB_GENERIC_HEADER header; + unsigned long length; // current length of hob + unsigned long cur_pos; // current poisiton of hob + unsigned long buf_size; // size of hob buffer +}HOB_INFO; + +typedef struct{ + unsigned long start; + unsigned long size; +}hob_mem_t; + +typedef enum { + HOB_TYPE_INFO=0, + HOB_TYPE_TERMINAL, + HOB_TYPE_MEM, + HOB_TYPE_PAL_BUS_GET_FEATURES_DATA, + HOB_TYPE_PAL_CACHE_SUMMARY, + HOB_TYPE_PAL_MEM_ATTRIB, + HOB_TYPE_PAL_CACHE_INFO, + HOB_TYPE_PAL_CACHE_PROT_INFO, + HOB_TYPE_PAL_DEBUG_INFO, + HOB_TYPE_PAL_FIXED_ADDR, + HOB_TYPE_PAL_FREQ_BASE, + HOB_TYPE_PAL_FREQ_RATIOS, + HOB_TYPE_PAL_HALT_INFO, + HOB_TYPE_PAL_PERF_MON_INFO, + HOB_TYPE_PAL_PROC_GET_FEATURES, + HOB_TYPE_PAL_PTCE_INFO, + HOB_TYPE_PAL_REGISTER_INFO, + HOB_TYPE_PAL_RSE_INFO, + HOB_TYPE_PAL_TEST_INFO, + HOB_TYPE_PAL_VM_SUMMARY, + HOB_TYPE_PAL_VM_INFO, + HOB_TYPE_PAL_VM_PAGE_SIZE, + HOB_TYPE_MAX +}hob_type_t; + +static int hob_init( void *buffer ,unsigned long buf_size); +static int add_pal_hob(void* hob_buf); +static int add_mem_hob(void* hob_buf, unsigned long dom_mem_size); +static int build_hob (void* hob_buf, unsigned long hob_buf_size, + unsigned long dom_mem_size); +static int load_hob(int xc_handle,uint32_t dom, void *hob_buf); + +int xc_ia64_build_hob(int xc_handle, uint32_t dom, unsigned long memsize){ + + char hob_buf[GFW_HOB_SIZE]; + + if ( build_hob( hob_buf, GFW_HOB_SIZE, memsize<<20) < 0){ + PERROR("Could not build hob"); + return -1; + } + + if ( load_hob( xc_handle, dom, hob_buf) <0){ + PERROR("Could not load hob"); + return -1; + } + + return 0; + +} +static int +hob_init( void *buffer ,unsigned long buf_size) +{ + HOB_INFO *phit; + HOB_GENERIC_HEADER *terminal; + + if (sizeof(HOB_INFO) + sizeof(HOB_GENERIC_HEADER) > buf_size){ + // buffer too small + return -1; + } + + phit = (HOB_INFO*)buffer; + phit->header.signature = HOB_SIGNATURE; + phit->header.type = HOB_TYPE_INFO; + phit->header.length = sizeof(HOB_INFO); + phit->length = sizeof(HOB_INFO) + sizeof(HOB_GENERIC_HEADER); + phit->cur_pos = 0; + phit->buf_size = buf_size; + + terminal = (HOB_GENERIC_HEADER*) (buffer + sizeof(HOB_INFO)); + terminal->signature= HOB_SIGNATURE; + terminal->type = HOB_TYPE_TERMINAL; + terminal->length = sizeof(HOB_GENERIC_HEADER); + + return 0; +} + +/* + * Add a new HOB to the HOB List. + * + * hob_start - start address of hob buffer + * type - type of the hob to be added + * data - data of the hob to be added + * data_size - size of the data + */ +static int +hob_add( + void* hob_start, + int type, + void* data, + int data_size +) +{ + HOB_INFO *phit; + HOB_GENERIC_HEADER *newhob,*tail; + + phit = (HOB_INFO*)hob_start; + + if (phit->length + data_size > phit->buf_size){ + // no space for new hob + return -1; + } + + //append new HOB + newhob = (HOB_GENERIC_HEADER*) + (hob_start + phit->length - sizeof(HOB_GENERIC_HEADER)); + newhob->signature = HOB_SIGNATURE; + newhob->type = type; + newhob->length = data_size + sizeof(HOB_GENERIC_HEADER); + memcpy((void*)newhob + sizeof(HOB_GENERIC_HEADER), data, data_size); + + // append terminal HOB + tail = (HOB_GENERIC_HEADER*) ( hob_start + phit->length + data_size); + tail->signature = HOB_SIGNATURE; + tail->type = HOB_TYPE_TERMINAL; + tail->length = sizeof(HOB_GENERIC_HEADER); + + // adjust HOB list length + phit->length += sizeof(HOB_GENERIC_HEADER)+ data_size; + + return 0; + +} + +int get_hob_size(void* hob_buf){ + + HOB_INFO *phit = (HOB_INFO*)hob_buf; + + if (phit->header.signature != HOB_SIGNATURE){ + PERROR("xc_get_hob_size:Incorrect signature"); + return -1; + } + return phit->length; +} + +int build_hob (void* hob_buf, unsigned long hob_buf_size, + unsigned long dom_mem_size) +{ + //Init HOB List + if (hob_init (hob_buf, hob_buf_size)<0){ + PERROR("buffer too small"); + goto err_out; + } + + if ( add_mem_hob( hob_buf,dom_mem_size) < 0){ + PERROR("Add memory hob failed, buffer too small"); + goto err_out; + } + + if ( add_pal_hob( hob_buf ) < 0 ){ + PERROR("Add PAL hob failed, buffer too small"); + goto err_out; + } + + return 0; + +err_out: + return -1; +} + +static int +load_hob(int xc_handle, uint32_t dom, void *hob_buf) +{ + // hob_buf should be page aligned + int hob_size; + int nr_pages; + + if ((hob_size = get_hob_size(hob_buf)) < 0){ + PERROR("Invalid hob data"); + return -1; + } + + if (hob_size > GFW_HOB_SIZE){ + PERROR("No enough memory for hob data"); + return -1; + } + + nr_pages = (hob_size + PAGE_SIZE -1) >> PAGE_SHIFT; + + return xc_ia64_copy_to_domain_pages(xc_handle, dom, + hob_buf, GFW_HOB_START, nr_pages ); +} + +#define MIN(x, y) ((x) < (y)) ? (x) : (y) +static int +add_mem_hob(void* hob_buf, unsigned long dom_mem_size){ + hob_mem_t memhob; + + // less than 3G + memhob.start = 0; + memhob.size = MIN(dom_mem_size, 0xC0000000); + + if (hob_add(hob_buf, HOB_TYPE_MEM, &memhob, sizeof(memhob)) < 0){ + return -1; + } + + if (dom_mem_size > 0xC0000000) { + // 4G ~ 4G+remain + memhob.start = 0x100000000; //4G + memhob.size = dom_mem_size - 0xC0000000; + if (hob_add(hob_buf, HOB_TYPE_MEM, &memhob, sizeof(memhob)) < 0) + return -1; + } + return 0; +} + +unsigned char config_pal_bus_get_features_data[24] = { + 0, 0, 0, 32, 0, 0, 240, 189, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; +unsigned char config_pal_cache_summary[16] = { + 3, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0}; +unsigned char config_pal_mem_attrib[8] = { + 241, 0, 0, 0, 0, 0, 0, 0 +}; +unsigned char config_pal_cache_info[152] = { + 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 6, 4, 6, 7, 255, 1, 0, 1, 0, 64, 0, 0, 12, 12, + 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 6, 7, 0, 1, + 0, 1, 0, 64, 0, 0, 12, 12, 49, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 6, 8, 7, 7, 255, 7, 0, 11, 0, 0, 16, 0, + 12, 17, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 8, 7, + 7, 7, 5, 9, 11, 0, 0, 4, 0, 12, 15, 49, 0, 254, 255, + 255, 255, 255, 255, 255, 255, 2, 8, 7, 7, 7, 5, 9, + 11, 0, 0, 4, 0, 12, 15, 49, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 3, 12, 7, 7, 7, 14, 1, 3, 0, 0, 192, 0, 12, 20, 49, 0 +}; +unsigned char config_pal_cache_prot_info[200] = { + 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 45, 0, 16, 8, 0, 76, 12, 64, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 8, 0, 16, 4, 0, 76, 44, 68, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, + 0, 16, 8, 0, 81, 44, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, + 112, 12, 0, 79, 124, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 254, 255, 255, 255, 255, 255, 255, 255, + 32, 0, 112, 12, 0, 79, 124, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 160, + 12, 0, 84, 124, 76, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0 +}; +unsigned char config_pal_debug_info[16] = { + 2, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0 +}; +unsigned char config_pal_fixed_addr[8] = { + 0, 0, 0, 0, 0, 0, 0, 0 +}; +unsigned char config_pal_freq_base[8] = { + 109, 219, 182, 13, 0, 0, 0, 0 +}; +unsigned char config_pal_freq_ratios[24] = { + 11, 1, 0, 0, 77, 7, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 4, + 0, 0, 0, 7, 0, 0, 0 +}; +unsigned char config_pal_halt_info[64] = { + 0, 0, 0, 0, 0, 0, 0, 48, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; +unsigned char config_pal_perf_mon_info[136] = { + 12, 47, 18, 8, 0, 0, 0, 0, 241, 255, 0, 0, 255, 7, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 241, 255, 0, 0, 223, 0, 255, 255, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 240, 255, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 240, 255, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0 +}; +unsigned char config_pal_proc_get_features[104] = { + 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 64, 6, 64, 49, 0, 0, 0, 0, 64, 6, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, + 231, 0, 0, 0, 0, 0, 0, 0, 228, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 0, + 63, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0 +}; +unsigned char config_pal_ptce_info[24] = { + 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0 +}; +unsigned char config_pal_register_info[64] = { + 255, 0, 47, 127, 17, 17, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, + 255, 208, 128, 238, 238, 0, 0, 248, 255, 255, 255, 255, 255, 0, 0, 7, 3, + 251, 3, 0, 0, 0, 0, 255, 7, 3, 0, 0, 0, 0, 0, 248, 252, 4, + 252, 255, 255, 255, 255, 2, 248, 252, 255, 255, 255, 255, 255 +}; +unsigned char config_pal_rse_info[16] = { + 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; +unsigned char config_pal_test_info[48] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; +unsigned char config_pal_vm_summary[16] = { + 101, 18, 15, 2, 7, 7, 4, 2, 59, 18, 0, 0, 0, 0, 0, 0 +}; +unsigned char config_pal_vm_info[104] = { + 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, + 32, 32, 0, 0, 0, 0, 0, 0, 112, 85, 21, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1, 32, 32, 0, 0, 0, 0, 0, 0, 112, 85, + 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 128, 128, 0, + 4, 0, 0, 0, 0, 112, 85, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 128, 128, 0, 4, 0, 0, 0, 0, 112, 85, 0, 0, 0, 0, 0 +}; +unsigned char config_pal_vm_page_size[16] = { + 0, 112, 85, 21, 0, 0, 0, 0, 0, 112, 85, 21, 0, 0, 0, 0 +}; + +typedef struct{ + hob_type_t type; + void* data; + unsigned long size; +}hob_batch_t; + +hob_batch_t hob_batch[]={ + { HOB_TYPE_PAL_BUS_GET_FEATURES_DATA, + &config_pal_bus_get_features_data, + sizeof(config_pal_bus_get_features_data) + }, + { HOB_TYPE_PAL_CACHE_SUMMARY, + &config_pal_cache_summary, + sizeof(config_pal_cache_summary) + }, + { HOB_TYPE_PAL_MEM_ATTRIB, + &config_pal_mem_attrib, + sizeof(config_pal_mem_attrib) + }, + { HOB_TYPE_PAL_CACHE_INFO, + &config_pal_cache_info, + sizeof(config_pal_cache_info) + }, + { HOB_TYPE_PAL_CACHE_PROT_INFO, + &config_pal_cache_prot_info, + sizeof(config_pal_cache_prot_info) + }, + { HOB_TYPE_PAL_DEBUG_INFO, + &config_pal_debug_info, + sizeof(config_pal_debug_info) + }, + { HOB_TYPE_PAL_FIXED_ADDR, + &config_pal_fixed_addr, + sizeof(config_pal_fixed_addr) + }, + { HOB_TYPE_PAL_FREQ_BASE, + &config_pal_freq_base, + sizeof(config_pal_freq_base) + }, + { HOB_TYPE_PAL_FREQ_RATIOS, + &config_pal_freq_ratios, + sizeof(config_pal_freq_ratios) + }, + { HOB_TYPE_PAL_HALT_INFO, + &config_pal_halt_info, + sizeof(config_pal_halt_info) + }, + { HOB_TYPE_PAL_PERF_MON_INFO, + &config_pal_perf_mon_info, + sizeof(config_pal_perf_mon_info) + }, + { HOB_TYPE_PAL_PROC_GET_FEATURES, + &config_pal_proc_get_features, + sizeof(config_pal_proc_get_features) + }, + { HOB_TYPE_PAL_PTCE_INFO, + &config_pal_ptce_info, + sizeof(config_pal_ptce_info) + }, + { HOB_TYPE_PAL_REGISTER_INFO, + &config_pal_register_info, + sizeof(config_pal_register_info) + }, + { HOB_TYPE_PAL_RSE_INFO, + &config_pal_rse_info, + sizeof(config_pal_rse_info) + }, + { HOB_TYPE_PAL_TEST_INFO, + &config_pal_test_info, + sizeof(config_pal_test_info) + }, + { HOB_TYPE_PAL_VM_SUMMARY, + &config_pal_vm_summary, + sizeof(config_pal_vm_summary) + }, + { HOB_TYPE_PAL_VM_INFO, + &config_pal_vm_info, + sizeof(config_pal_vm_info) + }, + { HOB_TYPE_PAL_VM_PAGE_SIZE, + &config_pal_vm_page_size, + sizeof(config_pal_vm_page_size) + }, +}; + +static int add_pal_hob(void* hob_buf){ + int i; + for (i=0; i 12 * MEM_M) || (image_size & (PAGE_SIZE - 1))) { + PERROR("Guest firmware size is incorrect [%ld]?", image_size); + return -1; + } + + /* Load guest firmware */ + if( xc_ia64_copy_to_domain_pages( xc_handle, dom, + image, 4*MEM_G-image_size, image_size>>PAGE_SHIFT)) { + PERROR("Could not load guest firmware into domain"); + goto error_out; + } + + /* Hand-off state passed to guest firmware */ + if (xc_ia64_build_hob(xc_handle, dom, memsize) < 0){ + PERROR("Could not build hob\n"); + goto error_out; + } + + /* Retrieve special pages like io, xenstore, etc. */ + if ( xc_ia64_get_pfn_list(xc_handle, dom, page_array, IO_PAGE_START>>PAGE_SHIFT, 2) != 2 ) + { + PERROR("Could not get the page frame list"); + goto error_out; + } + + *store_mfn = page_array[1]; + if ((sp = (shared_iopage_t *) xc_map_foreign_range( + xc_handle, dom, PAGE_SIZE, PROT_READ|PROT_WRITE, + page_array[0])) == 0) + goto error_out; + memset(sp, 0, PAGE_SIZE); + sp->sp_global.eport = control_evtchn; + munmap(sp, PAGE_SIZE); + + return 0; + + error_out: + return -1; +} + +int xc_vmx_build(int xc_handle, + uint32_t domid, + int memsize, + const char *image_name, + unsigned int control_evtchn, + unsigned int vcpus, + unsigned int store_evtchn, + unsigned long *store_mfn) +{ + dom0_op_t launch_op, op; + int rc ; + vcpu_guest_context_t st_ctxt, *ctxt = &st_ctxt; + char *image = NULL; + unsigned long image_size; + unsigned long nr_pages; + + if ( (nr_pages = xc_get_max_pages(xc_handle, domid)) < 0 ) + { + PERROR("Could not find total pages for domain"); + goto error_out; + } + + if ( (image = xc_read_kernel_image(image_name, &image_size)) == NULL ){ + PERROR("Could not read guest firmware image %s",image_name); + goto error_out; + } + + image_size = (image_size + PAGE_SIZE - 1) & PAGE_MASK; + + if ( mlock(&st_ctxt, sizeof(st_ctxt) ) ){ + PERROR("Unable to mlock ctxt"); + return 1; + } + + op.cmd = DOM0_GETDOMAININFO; + op.u.getdomaininfo.domain = (domid_t)domid; + if ( (do_dom0_op(xc_handle, &op) < 0) || + ((uint16_t)op.u.getdomaininfo.domain != domid) ) { + PERROR("Could not get info on domain"); + goto error_out; + } + + if ( xc_domain_get_vcpu_context(xc_handle, domid, 0, ctxt) ){ + PERROR("Could not get vcpu context"); + goto error_out; + } + + if ( !(op.u.getdomaininfo.flags & DOMFLAGS_PAUSED) ) { + ERROR("Domain is already constructed"); + goto error_out; + } + + if ( setup_guest(xc_handle, domid, (unsigned long)memsize, image, image_size, + control_evtchn, store_evtchn, store_mfn ) < 0 ){ + ERROR("Error constructing guest OS"); + goto error_out; + } + + if ( image != NULL ) + free(image); + + ctxt->flags = VGCF_VMX_GUEST; + ctxt->regs.cr_iip = 0x80000000ffffffb0UL; + ctxt->vcpu.privregs = 0; + + memset( &launch_op, 0, sizeof(launch_op) ); + + launch_op.u.setdomaininfo.domain = (domid_t)domid; + launch_op.u.setdomaininfo.vcpu = 0; + launch_op.u.setdomaininfo.ctxt = ctxt; + + launch_op.cmd = DOM0_SETDOMAININFO; + rc = do_dom0_op(xc_handle, &launch_op); + return rc; + + error_out: + if ( image != NULL ) + free(image); + + return -1; +} + /* * Local variables: * mode: C diff --git a/tools/libxc/xc_linux_build.c b/tools/libxc/xc_linux_build.c index 7a3a8737d9..cf4db7cb69 100644 --- a/tools/libxc/xc_linux_build.c +++ b/tools/libxc/xc_linux_build.c @@ -350,6 +350,8 @@ static int setup_guest(int xc_handle, start_info = xc_map_foreign_range( xc_handle, dom, PAGE_SIZE, PROT_READ|PROT_WRITE, page_array[0]); memset(start_info, 0, sizeof(*start_info)); + rc = xc_version(xc_handle, XENVER_version, NULL); + sprintf(start_info->magic, "Xen-%i.%i", rc >> 16, rc & (0xFFFF)); start_info->flags = flags; start_info->store_mfn = nr_pages - 2; start_info->store_evtchn = store_evtchn; @@ -624,6 +626,8 @@ static int setup_guest(int xc_handle, xc_handle, dom, PAGE_SIZE, PROT_READ|PROT_WRITE, page_array[(vstartinfo_start-dsi.v_start)>>PAGE_SHIFT]); memset(start_info, 0, sizeof(*start_info)); + rc = xc_version(xc_handle, XENVER_version, NULL); + sprintf(start_info->magic, "Xen-%i.%i", rc >> 16, rc & (0xFFFF)); start_info->nr_pages = nr_pages; start_info->shared_info = shared_info_frame << PAGE_SHIFT; start_info->flags = flags; diff --git a/tools/libxc/xc_private.c b/tools/libxc/xc_private.c index ea3798ebca..75e179a7c7 100644 --- a/tools/libxc/xc_private.c +++ b/tools/libxc/xc_private.c @@ -313,46 +313,6 @@ int xc_get_pfn_list(int xc_handle, return (ret < 0) ? -1 : op.u.getmemlist.num_pfns; } -#ifdef __ia64__ -int xc_ia64_get_pfn_list(int xc_handle, - uint32_t domid, - unsigned long *pfn_buf, - unsigned int start_page, - unsigned int nr_pages) -{ - dom0_op_t op; - int ret; - - op.cmd = DOM0_GETMEMLIST; - op.u.getmemlist.domain = (domid_t)domid; - op.u.getmemlist.max_pfns = ((unsigned long)start_page << 32) | nr_pages; - op.u.getmemlist.buffer = pfn_buf; - - if ( mlock(pfn_buf, nr_pages * sizeof(unsigned long)) != 0 ) - { - PERROR("Could not lock pfn list buffer"); - return -1; - } - - /* XXX Hack to put pages in TLB, hypervisor should be able to handle this */ - memset(pfn_buf, 0, nr_pages * sizeof(unsigned long)); - ret = do_dom0_op(xc_handle, &op); - - (void)munlock(pfn_buf, nr_pages * sizeof(unsigned long)); - - return (ret < 0) ? -1 : op.u.getmemlist.num_pfns; -} - -long xc_get_max_pages(int xc_handle, uint32_t domid) -{ - dom0_op_t op; - op.cmd = DOM0_GETDOMAININFO; - op.u.getdomaininfo.domain = (domid_t)domid; - return (do_dom0_op(xc_handle, &op) < 0) ? - -1 : op.u.getdomaininfo.max_pages; -} -#endif - long xc_get_tot_pages(int xc_handle, uint32_t domid) { dom0_op_t op; diff --git a/tools/libxc/xc_vmx_build.c b/tools/libxc/xc_vmx_build.c index 168acaf0d7..c81346558f 100644 --- a/tools/libxc/xc_vmx_build.c +++ b/tools/libxc/xc_vmx_build.c @@ -279,6 +279,7 @@ static int setup_guest(int xc_handle, vcpu_guest_context_t *ctxt, unsigned long shared_info_frame, unsigned int control_evtchn, + unsigned int lapic, unsigned int vcpus, unsigned int store_evtchn, unsigned long *store_mfn) @@ -554,7 +555,7 @@ static int setup_guest(int xc_handle, ctxt->user_regs.eax = 0; ctxt->user_regs.esp = 0; ctxt->user_regs.ebx = 0; /* startup_32 expects this to be 0 to signal boot cpu */ - ctxt->user_regs.ecx = 0; + ctxt->user_regs.ecx = lapic; ctxt->user_regs.esi = 0; ctxt->user_regs.edi = 0; ctxt->user_regs.ebp = 0; @@ -597,6 +598,7 @@ int xc_vmx_build(int xc_handle, int memsize, const char *image_name, unsigned int control_evtchn, + unsigned int lapic, unsigned int vcpus, unsigned int store_evtchn, unsigned long *store_mfn) @@ -651,9 +653,9 @@ int xc_vmx_build(int xc_handle, goto error_out; } - if ( setup_guest(xc_handle, domid, memsize, image, image_size, - nr_pages, ctxt, op.u.getdomaininfo.shared_info_frame, - control_evtchn, vcpus, store_evtchn, store_mfn) < 0) + if ( setup_guest(xc_handle, domid, memsize, image, image_size, nr_pages, + ctxt, op.u.getdomaininfo.shared_info_frame, control_evtchn, + lapic, vcpus, store_evtchn, store_mfn) < 0) { ERROR("Error constructing guest OS"); goto error_out; diff --git a/tools/libxc/xenctrl.h b/tools/libxc/xenctrl.h index 98408f25bf..ffbe4fdfff 100644 --- a/tools/libxc/xenctrl.h +++ b/tools/libxc/xenctrl.h @@ -414,6 +414,12 @@ int xc_ia64_get_pfn_list(int xc_handle, uint32_t domid, unsigned long *pfn_buf, unsigned int start_page, unsigned int nr_pages); +int xc_copy_to_domain_page(int xc_handle, uint32_t domid, + unsigned long dst_pfn, void *src_page); + +int xc_ia64_copy_to_domain_pages(int xc_handle, uint32_t domid, + void* src_page, unsigned long dst_pfn, int nr_pages); + long xc_get_max_pages(int xc_handle, uint32_t domid); int xc_mmuext_op(int xc_handle, struct mmuext_op *op, unsigned int nr_ops, diff --git a/tools/libxc/xenguest.h b/tools/libxc/xenguest.h index 70d23af826..8e01b73b10 100644 --- a/tools/libxc/xenguest.h +++ b/tools/libxc/xenguest.h @@ -56,6 +56,7 @@ int xc_vmx_build(int xc_handle, int memsize, const char *image_name, unsigned int control_evtchn, + unsigned int lapic, unsigned int vcpus, unsigned int store_evtchn, unsigned long *store_mfn); diff --git a/tools/misc/cpuperf/cpuperf.c b/tools/misc/cpuperf/cpuperf.c index 999c04891a..5047780532 100644 --- a/tools/misc/cpuperf/cpuperf.c +++ b/tools/misc/cpuperf/cpuperf.c @@ -16,7 +16,6 @@ #include #include -#include #include #include #include diff --git a/tools/misc/miniterm/miniterm.c b/tools/misc/miniterm/miniterm.c index 0dc4143b4e..92f8462781 100644 --- a/tools/misc/miniterm/miniterm.c +++ b/tools/misc/miniterm/miniterm.c @@ -29,7 +29,7 @@ #include #include #include -#include +#include #include #include diff --git a/tools/python/xen/lowlevel/xc/xc.c b/tools/python/xen/lowlevel/xc/xc.c index 8b72e0ec57..b01f3645a3 100644 --- a/tools/python/xen/lowlevel/xc/xc.c +++ b/tools/python/xen/lowlevel/xc/xc.c @@ -438,19 +438,20 @@ static PyObject *pyxc_vmx_build(PyObject *self, char *image; int control_evtchn, store_evtchn; int vcpus = 1; + int lapic = 0; int memsize; unsigned long store_mfn = 0; static char *kwd_list[] = { "dom", "control_evtchn", "store_evtchn", - "memsize", "image", "vcpus", NULL }; + "memsize", "image", "lapic", "vcpus", NULL }; - if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iiiisi", kwd_list, + if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iiiisii", kwd_list, &dom, &control_evtchn, &store_evtchn, - &memsize, &image, &vcpus) ) + &memsize, &image, &lapic, &vcpus) ) return NULL; if ( xc_vmx_build(xc->xc_handle, dom, memsize, image, control_evtchn, - vcpus, store_evtchn, &store_mfn) != 0 ) + lapic, vcpus, store_evtchn, &store_mfn) != 0 ) return PyErr_SetFromErrno(xc_error); return Py_BuildValue("{s:i}", "store_mfn", store_mfn); diff --git a/tools/python/xen/web/tcp.py b/tools/python/xen/web/tcp.py index b9dddd1526..743fd6daf3 100644 --- a/tools/python/xen/web/tcp.py +++ b/tools/python/xen/web/tcp.py @@ -99,7 +99,7 @@ def listenTCP(port, factory, interface='', backlog=None): return l def SetCloExec(SocketListener): - SocketListener.SetCloExec() + SocketListener.setCloExec() def connectTCP(host, port, factory, timeout=None, bindAddress=None): c = TCPConnector(host, port, factory, timeout=timeout, bindAddress=bindAddress) diff --git a/tools/python/xen/xend/image.py b/tools/python/xen/xend/image.py index 6cd9f540f3..0b54e83ca0 100644 --- a/tools/python/xen/xend/image.py +++ b/tools/python/xen/xend/image.py @@ -203,6 +203,10 @@ class VmxImageHandler(ImageHandler): self.dmargs += self.configVNC(imageConfig) + self.lapic = 0 + lapic = sxp.child_value(imageConfig, 'lapic') + if not lapic is None: + self.lapic = int(lapic) def buildDomain(self): # Create an event channel @@ -217,6 +221,7 @@ class VmxImageHandler(ImageHandler): log.debug("control_evtchn = %d", self.device_channel) log.debug("store_evtchn = %d", store_evtchn) log.debug("memsize = %d", self.vm.getMemoryTarget() / 1024) + log.debug("lapic = %d", self.lapic) log.debug("vcpus = %d", self.vm.getVCpuCount()) return xc.vmx_build(dom = self.vm.getDomid(), @@ -224,6 +229,7 @@ class VmxImageHandler(ImageHandler): control_evtchn = self.device_channel, store_evtchn = store_evtchn, memsize = self.vm.getMemoryTarget() / 1024, + lapic = self.lapic, vcpus = self.vm.getVCpuCount()) @@ -342,12 +348,15 @@ class VmxImageHandler(ImageHandler): def getDomainMemory(self, mem): """@see ImageHandler.getDomainMemory""" + page_kb = 4 + if os.uname()[4] == 'ia64': + page_kb = 16 # for ioreq_t and xenstore static_pages = 2 - return mem + self.getPageTableSize(mem / 1024) + 4 * static_pages + return mem + (self.getPageTableSize(mem / 1024) + static_pages) * page_kb def getPageTableSize(self, mem_mb): - """Return the size of memory needed for 1:1 page tables for physical + """Return the pages of memory needed for 1:1 page tables for physical mode. @param mem_mb: size in MB @@ -355,13 +364,13 @@ class VmxImageHandler(ImageHandler): """ # 1 page for the PGD + 1 pte page for 4MB of memory (rounded) if os.uname()[4] == 'x86_64': - return (5 + ((mem_mb + 1) >> 1)) * 4 + return 5 + ((mem_mb + 1) >> 1) elif os.uname()[4] == 'ia64': - # XEN/IA64 has p2m table allocated on demand, so only return - # guest firmware size here. - return 16 * 1024 + # 1:1 pgtable is allocated on demand ia64, so just return rom size + # for guest firmware + return 1024 else: - return (1 + ((mem_mb + 3) >> 2)) * 4 + return 1 + ((mem_mb + 3) >> 2) """Table of image handler classes for virtual machine images. Indexed by diff --git a/tools/python/xen/xend/server/event.py b/tools/python/xen/xend/server/event.py index bf0521c764..ab03c2cb6a 100644 --- a/tools/python/xen/xend/server/event.py +++ b/tools/python/xen/xend/server/event.py @@ -192,4 +192,5 @@ def listenEvent(daemon): if xroot.get_xend_http_server(): port = xroot.get_xend_event_port() interface = xroot.get_xend_address() - tcp.listenTCP(port, factory, interface=interface) + l = tcp.listenTCP(port, factory, interface=interface) + l.setCloExec() diff --git a/tools/python/xen/xend/tests/__init__.py b/tools/python/xen/xend/tests/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/tools/python/xen/xm/create.py b/tools/python/xen/xm/create.py index 9f476038cc..5bdb8ebf00 100644 --- a/tools/python/xen/xm/create.py +++ b/tools/python/xen/xm/create.py @@ -157,6 +157,10 @@ gopts.var('cpu', val='CPU', fn=set_int, default=None, use="CPU to run the domain on.") +gopts.var('lapic', val='LAPIC', + fn=set_int, default=0, + use="Disable or enable local APIC of VMX domain.") + gopts.var('vcpus', val='VCPUS', fn=set_int, default=1, use="# of Virtual CPUS in domain.") @@ -315,10 +319,6 @@ gopts.var('nfs_root', val="PATH", fn=set_value, default=None, use="Set the path of the root NFS directory.") -gopts.var('memmap', val='FILE', - fn=set_value, default='', - use="Path to memap SXP file.") - gopts.var('device_model', val='FILE', fn=set_value, default='', use="Path to device model program.") @@ -556,9 +556,9 @@ def configure_vfr(config, vals): def configure_vmx(config_image, vals): """Create the config for VMX devices. """ - args = [ 'memmap', 'device_model', 'vcpus', 'cdrom', - 'boot', 'fda', 'fdb', 'localtime', 'serial', 'macaddr', 'stdvga', - 'isa', 'nographic', 'vnc', 'vncviewer', 'sdl', 'display', 'ne2000'] + args = [ 'device_model', 'vcpus', 'cdrom', 'boot', 'fda', 'fdb', + 'localtime', 'serial', 'macaddr', 'stdvga', 'isa', 'nographic', + 'vnc', 'vncviewer', 'sdl', 'display', 'ne2000', 'lapic'] for a in args: if (vals.__dict__[a]): config_image.append([a, vals.__dict__[a]]) diff --git a/tools/python/xen/xm/main.py b/tools/python/xen/xm/main.py index 2949ff157c..9dd5d65111 100644 --- a/tools/python/xen/xm/main.py +++ b/tools/python/xen/xm/main.py @@ -61,6 +61,8 @@ xm common subcommands: top monitor system and domains in real-time unpause unpause a paused domain + can be substituted for in xm subcommands. + For a complete list of subcommands run 'xm help --long' For more help on xm see the xm(1) man page For more help on xm create, see the xmdomain.cfg(5) man page""" @@ -119,6 +121,8 @@ xm full list of subcommands: vnet-create create a vnet from a config file vnet-delete delete a vnet + can be substituted for in xm subcommands. + For a short list of subcommands run 'xm help' For more help on xm see the xm(1) man page For more help on xm create, see the xmdomain.cfg(5) man page""" diff --git a/tools/security/getlabel.sh b/tools/security/getlabel.sh index ee1fcba199..40c5c195d5 100644 --- a/tools/security/getlabel.sh +++ b/tools/security/getlabel.sh @@ -36,18 +36,21 @@ source labelfuncs.sh usage () { - echo "Usage: $0 -sid [] or" - echo " $0 -dom [] " - echo "" - echo "policy name : the name of the policy, i.e. 'chwall'" - echo " If the policy name is omitted, the grub.conf" - echo " entry of the running system is tried to be read" - echo " and the policy name determined from there." - echo "ssidref : an ssidref in hex or decimal format, i.e., '0x00010002'" - echo " or '65538'" - echo "domid : id of the domain, i.e., '1'; Use numbers from the 2nd" - echo " column shown when invoking 'xm list'" - echo "" +echo "Use this tool to display the label of a domain or the label that is +corresponding to an ssidref given the name of the running policy. + +Usage: $0 -sid [] or + $0 -dom [] + +policy name : the name of the policy, i.e. 'chwall' + If the policy name is omitted, the grub.conf + entry of the running system is tried to be read + and the policy name determined from there. +ssidref : an ssidref in hex or decimal format, i.e., '0x00010002' + or '65538' +domid : id of the domain, i.e., '1'; Use numbers from the 2nd + column shown when invoking 'xm list' +" } diff --git a/tools/security/setlabel.sh b/tools/security/setlabel.sh index 9e0ec34482..fcc08fc4aa 100644 --- a/tools/security/setlabel.sh +++ b/tools/security/setlabel.sh @@ -39,21 +39,27 @@ source labelfuncs.sh usage () { - echo "Usage: $0 [Option]