This commit is contained in:
kaf24@firebug.cl.cam.ac.uk committed 2005-10-29 09:51:35 +01:00
commit 1464591d5f
85 files changed
+2880 -973

No files matched your search

+1 -1
View File
@@ -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);
}
+151 -519
View File
@@ -14,6 +14,7 @@
#include <types.h>
#include <xen/xen.h>
#include <xen/dom0_ops.h>
/*
* 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 <xen/sched.h>
#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__ */
+3 -1
View File
@@ -24,7 +24,7 @@
#include <xen/xen.h>
#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);
/*
+8 -1
View File
@@ -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))
+2 -2
View File
@@ -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);
}
+1 -1
View File
@@ -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);
}
+6 -1
View File
@@ -39,7 +39,7 @@
#include <wait.h>
#include <sched.h>
#include <semaphore.h>
#include "xenstored.h"
#include <xen/io/xs_wire.h>
#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)
@@ -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
@@ -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)
@@ -70,6 +70,9 @@ spinlock_t balloon_lock = SPIN_LOCK_UNLOCKED;
static unsigned long current_pages;
static unsigned long target_pages;
/* VM /proc information for memory */
extern unsigned long totalram_pages;
/* We may hit the hard limit in Xen. If we do then we remember it. */
static unsigned long hard_limit;
@@ -188,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;
}
@@ -210,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);
@@ -223,6 +230,7 @@ static int increase_reservation(unsigned long nr_pages)
}
current_pages += nr_pages;
totalram_pages = current_pages;
out:
balloon_unlock(flags);
@@ -238,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,
@@ -264,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 {
@@ -291,10 +301,11 @@ 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;
balloon_unlock(flags);
@@ -496,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,
@@ -505,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;
}
@@ -514,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)
@@ -522,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);
@@ -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();
@@ -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)
@@ -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:
@@ -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();
@@ -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)
@@ -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);
@@ -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,
@@ -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) {
@@ -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
+3 -1
View File
@@ -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);
}
@@ -738,6 +738,7 @@ static int __init xenbus_probe_init(void)
unsigned long page;
evtchn_op_t op = { 0 };
int ret;
/* Allocate page. */
@@ -758,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 */
@@ -82,7 +82,7 @@ static struct xs_handle xs_state;
static LIST_HEAD(watches);
static DEFINE_SPINLOCK(watches_lock);
/* List of pending watch calbback events, and a lock to protect it. */
/* List of pending watch callback events, and a lock to protect it. */
static LIST_HEAD(watch_events);
static DEFINE_SPINLOCK(watch_events_lock);
@@ -544,11 +544,8 @@ void xenbus_dev_error(struct xenbus_device *dev, int err, const char *fmt, ...)
char *printf_buffer = NULL, *path_buffer = NULL;
printf_buffer = kmalloc(PRINTF_BUFFER_SIZE, GFP_KERNEL);
if (printf_buffer == NULL) {
printk("xenbus: failed to write error node for %s (%d): %d\n",
dev->nodename, err, errno);
if (printf_buffer == NULL)
goto fail;
}
len = sprintf(printf_buffer, "%i ", -err);
va_start(ap, fmt);
@@ -561,8 +558,8 @@ void xenbus_dev_error(struct xenbus_device *dev, int err, const char *fmt, ...)
path_buffer = error_path(dev);
if (path_buffer == NULL) {
printk("xenbus: failed to write error node for %s (%s): %d\n",
dev->nodename, printf_buffer, errno);
printk("xenbus: failed to write error node for %s (%s)\n",
dev->nodename, printf_buffer);
goto fail;
}
@@ -587,8 +584,8 @@ void xenbus_dev_ok(struct xenbus_device *dev)
char *path_buffer = error_path(dev);
if (path_buffer == NULL) {
printk("xenbus: failed to clear error node for %s: "
"%d\n", dev->nodename, errno);
printk("xenbus: failed to clear error node for %s\n",
dev->nodename);
return;
}
-3
View File
@@ -16,9 +16,6 @@ SUBDIRS += vtpm_manager
SUBDIRS += vtpm
endif
SUBDIRS += xenstat
.PHONY: all install clean check check_clean ioemu eioemuinstall ioemuclean
# These don't cross-compile
ifeq ($(XEN_COMPILE_ARCH),$(XEN_TARGET_ARCH))
SUBDIRS += python
+3 -1
View File
@@ -512,7 +512,9 @@ static void handle_xs(int fd)
enum_domains();
else if (sscanf(vec[XS_WATCH_TOKEN], "dom%u", &domid) == 1) {
dom = lookup_domain(domid);
if (dom->is_dead == false)
/* We may get watches firing for domains that have recently
been removed, so dom may be NULL here. */
if (dom && dom->is_dead == false)
domain_create_ring(dom);
}
+5 -1
View File
@@ -9,6 +9,7 @@ INSTALL_DATA = $(INSTALL) -m0644
# Init scripts.
XEND_INITD = init.d/xend
XENDOMAINS_INITD = init.d/xendomains
XENDOMAINS_SYSCONFIG = init.d/sysconfig.xendomains
# Xen configuration dir and configs to go there.
XEN_CONFIG_DIR = /etc/xen
@@ -24,8 +25,9 @@ XEN_SCRIPTS = network-bridge vif-bridge
XEN_SCRIPTS += network-route vif-route
XEN_SCRIPTS += network-nat vif-nat
XEN_SCRIPTS += block
XEN_SCRIPTS += block-enbd
XEN_SCRIPTS += block-enbd block-nbd
XEN_SCRIPTS += xen-hotplug-common.sh xen-network-common.sh vif-common.sh
XEN_SCRIPTS += block-common.sh
XEN_HOTPLUG_DIR = /etc/hotplug
XEN_HOTPLUG_SCRIPTS = xen-backend.agent
@@ -52,8 +54,10 @@ install: all install-initd install-configs install-scripts $(HOTPLUGS)
install-initd:
[ -d $(DESTDIR)/etc/init.d ] || $(INSTALL_DIR) $(DESTDIR)/etc/init.d
[ -d $(DESTDIR)/etc/sysconfig ] || $(INSTALL_DIR) $(DESTDIR)/etc/sysconfig
$(INSTALL_PROG) $(XEND_INITD) $(DESTDIR)/etc/init.d
$(INSTALL_PROG) $(XENDOMAINS_INITD) $(DESTDIR)/etc/init.d
$(INSTALL_PROG) $(XENDOMAINS_SYSCONFIG) $(DESTDIR)/etc/sysconfig/xendomains
install-configs: $(XEN_CONFIGS)
[ -d $(DESTDIR)$(XEN_CONFIG_DIR) ] || \
+2 -14
View File
@@ -1,7 +1,7 @@
#!/bin/sh
dir=$(dirname "$0")
. "$dir/xen-hotplug-common.sh"
. "$dir/block-common.sh"
expand_dev() {
local dev
@@ -16,21 +16,9 @@ expand_dev() {
echo -n $dev
}
write_dev() {
local major
local minor
local pdev
major=$(stat -L -c %t "$1")
minor=$(stat -L -c %T "$1")
pdev=$(printf "0x%02x%02x" 0x$major 0x$minor)
xenstore_write "$XENBUS_PATH"/physical-device $pdev \
"$XENBUS_PATH"/node $1
}
t=$(xenstore_read "$XENBUS_PATH"/type || true)
case $1 in
case "$command" in
bind)
p=$(xenstore_read "$XENBUS_PATH"/params)
case $t in
+51
View File
@@ -0,0 +1,51 @@
#
# Copyright (c) 2005 XenSource Ltd.
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of version 2.1 of the GNU Lesser General Public
# License as published by the Free Software Foundation.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
dir=$(dirname "$0")
. "$dir/xen-hotplug-common.sh"
command="$1"
if [ "$command" != "bind" ] && [ "$command" != "unbind" ]
then
log err "Invalid command: $command"
exit 1
fi
XENBUS_PATH="${XENBUS_PATH:?}"
##
# Write physical-device = 0xMMmm and node = device to the store, where MM
# and mm are the major and minor numbers of device.
#
# @param device The device from which major and minor numbers are read, which
# will be written into the store.
#
write_dev() {
local major
local minor
local pdev
major=$(stat -L -c %t "$1")
minor=$(stat -L -c %T "$1")
pdev=$(printf "0x%02x%02x" "0x$major" "0x$minor")
xenstore_write "$XENBUS_PATH"/physical-device "$pdev" \
"$XENBUS_PATH"/node "$1"
}
+4 -10
View File
@@ -2,25 +2,19 @@
# Usage: block-enbd [bind server ctl_port |unbind node]
#
# The file argument to the bind command is the file we are to bind to a
# loop device.
#
# The node argument to unbind is the name of the device node we are to
# unbind.
#
# This assumes you're running a correctly configured server at the other end!
set -e
dir=$(dirname "$0")
. "$dir/block-common.sh"
case $1 in
case "$command" in
bind)
for dev in /dev/nd*; do
if nbd-client $2:$3 $dev; then
major=$(stat -L -c %t "$dev")
minor=$(stat -L -c %T "$dev")
pdev=$(printf "0x%02x%02x" 0x$major 0x$minor)
xenstore-write "$XENBUS_PATH"/physical-device $pdev \
"$XENBUS_PATH"/node $dev
write_dev $dev
exit 0
fi
done
+27
View File
@@ -0,0 +1,27 @@
#!/bin/sh
# Usage: block-nbd [bind server ctl_port |unbind node]
#
# The node argument to unbind is the name of the device node we are to
# unbind.
#
# This assumes you're running a correctly configured server at the other end!
dir=$(dirname "$0")
. "$dir/block-common.sh"
case "$command" in
bind)
for dev in /dev/nbd*; do
if nbd-client $2 $3 $dev; then
write_dev $dev
exit 0
fi
done
exit 1
;;
unbind)
nbd-client -d $2
exit 0
;;
esac
+126
View File
@@ -0,0 +1,126 @@
## Path: System/xen
## Description: xen domain start/stop on boot
## Type: string
## Default:
#
# The xendomains script can send SysRq requests to domains on shutdown.
# If you don't want to MIGRATE, SAVE, or SHUTDOWN, this may be a possibility
# to do a quick and dirty shutdown ("s e i u o") or at least sync the disks
# of the domains ("s").
#
XENDOMAINS_SYSRQ=""
## Type: integer
## Default: 100000
#
# If XENDOMAINS_SYSRQ is set, this variable determines how long to wait
# (in microseconds) after each SysRq, so the domain has a chance to react.
# If you want to a quick'n'dirty shutdown via SysRq, you may want to set
# it to a relatively high value (1200000).
#
XENDOMAINS_USLEEP=100000
## Type: string
## Default: ""
#
# Set this to a non-empty string if you want to migrate virtual machines
# on shutdown. The string will be passed to the xm migrate DOMID command
# as is: It should contain the target IP address of the physical machine
# to migrate to and optionally parameters like --live. Leave empty if
# you don't want to try virtual machine relocation on shutdown.
# If migration succeeds, neither SAVE nor SHUTDOWN will be executed for
# that domain.
#
XENDOMAINS_MIGRATE=""
## Type: string
## Default: /var/lib/xen/save
#
# Directory to save running domains to when the system (dom0) is
# shut down. Will also be used to restore domains from if # XENDOMAINS_RESTORE
# is set (see below). Leave empty to disable domain saving on shutdown
# (e.g. because you rather shut domains down).
# If domain saving does succeed, SHUTDOWN will not be executed.
#
XENDOMAINS_SAVE=/var/lib/xen/save
## Type: string
## Default: "--halt --wait"
#
# If neither MIGRATE nor SAVE were enabled or if they failed, you can
# try to shut down a domain by sending it a shutdown request. To do this,
# set this to "--halt --wait". Omit the "--wait" flag to avoid waiting
# for the domain to be really down. Leave empty to skip domain shutdown.
#
XENDOMAINS_SHUTDOWN="--halt --wait"
## Type: string
## Default: "--all --halt --wait"
#
# After we have gone over all virtual machines (resp. all automatically
# started ones, see XENDOMAINS_AUTO_ONLY below) in a loop and sent SysRq,
# migrated, saved and/or shutdown according to the settings above, we
# might want to shutdown the virtual machines that are still running
# for some reason or another. To do this, set this variable to
# "--all --halt --wait", it will be passed to xm shutdown.
# Leave it empty not to do anything special here.
# (Note: This will hit all virtual machines, even if XENDOMAINS_AUTO_ONLY
# is set.)
#
XENDOMAINS_SHUTDOWN_ALL="--all --halt --wait"
## Type: boolean
## Default: true
#
# This variable determines whether saved domains from XENDOMAINS_SAVE
# will be restored on system startup.
#
XENDOMAINS_RESTORE=true
## Type: string
## Default: /etc/xen/auto
#
# This variable sets the directory where domains configurations
# are stored that should be started on system startup automatically.
# Leave empty if you don't want to start domains automatically
# (or just don't place any xen domain config files in that dir).
# Note that the script tries to be clever if both RESTORE and AUTO are
# set: It will first restore saved domains and then only start domains
# in AUTO which are not running yet.
# Note that the name matching is somewhat fuzzy.
#
XENDOMAINS_AUTO=/etc/xen/auto
## Type: boolean
## Default: false
#
# If this variable is set to "true", only the domains started via config
# files in XENDOMAINS_AUTO will be treated according to XENDOMAINS_SYSRQ,
# XENDOMAINS_MIGRATE, XENDOMAINS_SAVE, XENDMAINS_SHUTDOWN; otherwise
# all running domains will be.
# Note that the name matching is somewhat fuzzy.
#
XENDOMAINS_AUTO_ONLY=false
## Type: integer
## Default: 300
#
# On xendomains stop, a number of xm commands (xm migrate, save, shutdown,
# shutdown --all) may be executed. In the worst case, these commands may
# stall forever, which will prevent a successful shutdown of the machine.
# If this variable is non-zero, the script will set up a watchdog timer
# for every of these xm commands and time it out after the number of seconds
# specified by this variable.
# Note that SHUTDOWN_ALL will not be called if no virtual machines or only
# zombies are still running, so you don't need to enable this timeout just
# for the zombie case.
# The setting should be large enough to make sure that migrate/save/shutdown
# can succeed. If you do live migrations, keep in mind that live migration
# of a 1GB machine over Gigabit ethernet may actually take something like
# 100s (assuming that live migration uses 10% of the network # bandwidth).
# Depending on the virtual machine, a shutdown may also require a significant
# amount of time. So better setup this variable to a huge number and hope the
# watchdog never fires.
#
XENDOMAINS_STOP_MAXWAIT=300
Executable → Regular
+406 -80
View File
@@ -1,4 +1,4 @@
#!/bin/sh
#!/bin/bash
#
# /etc/init.d/xendomains
# Start / stop domains automatically when domain 0 boots / shuts down.
@@ -22,101 +22,418 @@
# Should-Stop:
# Default-Start: 3 4 5
# Default-Stop: 0 1 2 6
# Default-Enabled: yes
# Short-Description: Start/stop secondary xen domains
# Description: Start / stop domains automatically when domain 0
# boots / shuts down.
### END INIT INFO
# Correct exit code would probably be 5, but it's enough
# if xend complains if we're not running as privileged domain
if ! [ -e /proc/xen/privcmd ]; then
exit 0
fi
RETVAL=0
INITD=/etc/init.d
AUTODIR=/etc/xen/auto
LOCKFILE=/var/lock/subsys/xendomains
XENDOM_CONFIG=/etc/sysconfig/xendomains
if [ -e /lib/lsb ]; then
# assume an LSB-compliant distro (Debian with LSB package,
# recent-enough SuSE, others...)
test -r $XENDOM_CONFIG || { echo "$XENDOM_CONFIG not existing";
if [ "$1" = "stop" ]; then exit 0;
else exit 6; fi; }
. /lib/lsb/init-functions # source LSB standard functions
. $XENDOM_CONFIG
on_fn_exit()
# Use the SUSE rc_ init script functions;
# emulate them on LSB, RH and other systems
if test -e /etc/rc.status; then
# SUSE rc script library
. /etc/rc.status
else
_cmd=$1
declare -a _SMSG
if test "${_cmd}" = "status"; then
_SMSG=(running dead dead unused unknown)
_RC_UNUSED=3
else
_SMSG=(done failed failed missed failed skipped unused failed failed)
_RC_UNUSED=6
fi
if test -e /lib/lsb/init-functions; then
# LSB
. /lib/lsb/init-functions
echo_rc()
{
if test ${_RC_RV} = 0; then
log_success_msg " [${_SMSG[${_RC_RV}]}] "
else
log_failure_msg " [${_SMSG[${_RC_RV}]}] "
fi
}
elif test -e /etc/init.d/functions; then
# REDHAT
. /etc/init.d/functions
echo_rc()
{
#echo -n " [${_SMSG[${_RC_RV}]}] "
if test ${_RC_RV} = 0; then
success " [${_SMSG[${_RC_RV}]}] "
else
failure " [${_SMSG[${_RC_RV}]}] "
fi
}
else
# emulate it
echo_rc()
{
echo " [${_SMSG[${_RC_RV}]}] "
}
fi
rc_reset() { _RC_RV=0; }
rc_failed()
{
if [ $RETVAL -eq 0 ]; then
log_success_msg
else
log_failure_msg
fi
if test -z "$1"; then
_RC_RV=1;
elif test "$1" != "0"; then
_RC_RV=$1;
fi
return ${_RC_RV}
}
elif [ -r $INITD/functions ]; then
# assume a Redhat-like distro
. $INITD/functions # source Redhat functions
on_fn_exit()
rc_check()
{
if [ $RETVAL -eq 0 ]; then
success
else
failure
fi
echo
return rc_failed $?
}
rc_status()
{
rc_failed $?
if test "$1" = "-r"; then _RC_RV=0; shift; fi
if test "$1" = "-s"; then rc_failed 5; echo_rc; rc_failed 3; shift; fi
if test "$1" = "-u"; then rc_failed ${_RC_UNUSED}; echo_rc; rc_failed 3; shift; fi
if test "$1" = "-v"; then echo_rc; shift; fi
if test "$1" = "-r"; then _RC_RV=0; shift; fi
return ${_RC_RV}
}
else
# none of the above
LOCKFILE=/var/lock/xendomains
on_fn_exit()
rc_exit() { exit ${_RC_RV}; }
rc_active()
{
echo
if test -z "$RUNLEVEL"; then read RUNLEVEL REST < <(/sbin/runlevel); fi
if test -e /etc/init.d/S[0-9][0-9]${1}; then return 0; fi
return 1
}
fi
if ! which usleep >&/dev/null
then
usleep()
{
if [ -n "$1" ]
then
sleep $(( $1 / 1000 ))
fi
}
fi
# Reset status of this service
rc_reset
start() {
if [ -f $LOCKFILE ]; then return; fi
##
# Returns 0 (success) if the given parameter names a directory, and that
# directory is not empty.
#
contains_something()
{
if [ -d "$1" ] && [ `/bin/ls $1 | wc -l` -gt 0 ]
then
return 0
else
return 1
fi
}
echo -n $"Starting auto Xen domains:"
# read name from xen config file
rdname()
{
NM=`grep '^name *=' $1 | sed -e 's/^name *= *"\([^"]*\)".*$/\1/' -e 's/%[id]/[0-9]*/g'`
}
# We expect config scripts for auto starting domains to be in
# AUTODIR - they could just be symlinks to files elsewhere
if [ -d $AUTODIR ] && [ $(ls $AUTODIR | wc -l) -gt 0 ]; then
touch $LOCKFILE
# Create all domains with config files in AUTODIR.
for dom in $AUTODIR/*; do
xm create --quiet --defconfig $dom
if [ $? -ne 0 ]; then
RETVAL=$?
fi
done
rdnames()
{
NAMES=
if ! contains_something "$XENDOMAINS_AUTO"
then
return
fi
for dom in $XENDOMAINS_AUTO/*; do
rdname $dom
if test -z $NAMES; then
NAMES=$NM;
else
NAMES="$NAMES|$NM"
fi
done
}
parseln()
{
name=`echo "$1" | cut -c0-17`
name=${name%% *}
rest=`echo "$1" | cut -c18- `
read id mem cpu vcpu state tm < <(echo "$rest")
}
is_running()
{
rdname $1
RC=1
while read LN; do
parseln "$LN"
if test $id = 0; then continue; fi
case $name in
($NM)
RC=0
;;
esac
done < <(xm list | grep -v '^Name')
return $RC
}
start()
{
if [ -f $LOCKFILE ]; then
echo -n "xendomains already running (lockfile exists)"
return;
fi
on_fn_exit
if [ "$XENDOMAINS_RESTORE" = "true" ] &&
contains_something "$XENDOMAINS_SAVE"
then
mkdir -p $(dirname "$LOCKFILE")
touch $LOCKFILE
echo -n "Restoring Xen domains:"
for dom in $XENDOMAINS_SAVE/*; do
echo -n " ${dom##*/}"
xm restore $dom
if [ $? -ne 0 ]; then
rc_failed $?
echo -n '!'
else
# mv $dom ${dom%/*}/.${dom##*/}
rm $dom
fi
done
fi
if contains_something "$XENDOMAINS_AUTO"
then
touch $LOCKFILE
echo -n "Starting auto Xen domains:"
# We expect config scripts for auto starting domains to be in
# XENDOMAINS_AUTO - they could just be symlinks to files elsewhere
# Create all domains with config files in XENDOMAINS_AUTO.
# TODO: We should record which domain name belongs
# so we have the option to selectively shut down / migrate later
for dom in $XENDOMAINS_AUTO/*; do
echo -n " ${dom##*/}"
if is_running $dom; then
echo -n "(skip)"
else
xm create --quiet --defconfig $dom
if [ $? -ne 0 ]; then
rc_failed $?
echo -n '!'
fi
fi
done
fi
}
all_zombies()
{
while read LN; do
parseln "$LN"
if test $id = 0; then continue; fi
if test "$state" != "-b---d" -a "$state" != "-----d"; then
return 1;
fi
done < <(xm list | grep -v '^Name')
return 0
}
# Wait for max $XENDOMAINS_STOP_MAXWAIT for xm $1 to finish;
# if it has not exited by that time kill it, so the init script will
# succeed within a finite amount of time; if $2 is nonnull, it will
# kill the command as well as soon as no domain (except for zombies)
# are left (used for shutdown --all).
watchdog_xm()
{
if test -z "$XENDOMAINS_STOP_MAXWAIT" -o "$XENDOMAINS_STOP_MAXWAIT" = "0"; then
exit
fi
usleep 20000
for no in `seq 0 $XENDOMAINS_STOP_MAXWAIT`; do
# exit if xm save/migrate/shutdown is finished
PSAX=`ps axlw | grep "xm $1" | grep -v grep`
if test -z "$PSAX"; then exit; fi
echo -n "."; sleep 1
# go to kill immediately if there's only zombies left
if all_zombies && test -n "$2"; then break; fi
done
sleep 1
read PSF PSUID PSPID PSPPID < <(echo "$PSAX")
# kill xm $1
kill $PSPID >/dev/null 2>&1
}
stop()
{
# Collect list of domains to shut down
if test "$XENDOMAINS_AUTO_ONLY" = "true"; then
rdnames
fi
echo -n "Shutting down Xen domains:"
while read LN; do
parseln "$LN"
if test $id = 0; then continue; fi
echo -n " $name"
if test "$XENDOMAINS_AUTO_ONLY" = "true"; then
case $name in
($NAMES)
# nothing
;;
(*)
echo -n "(skip)"
continue
;;
esac
fi
# XENDOMAINS_SYSRQ chould be something like just "s"
# or "s e i u" or even "s e s i u o"
# for the latter, you should set XENDOMAINS_USLEEP to 1200000 or so
if test -n "$XENDOMAINS_SYSRQ"; then
for sysrq in $XENDOMAINS_SYSRQ; do
echo -n "(SR-$sysrq)"
xm sysrq $id $sysrq
if test $? -ne 0; then
rc_failed $?
echo -n '!'
fi
# usleep just ignores empty arg
usleep $XENDOMAINS_USLEEP
done
fi
if test "$state" = "-b---d" -o "$state" = "-----d"; then
echo -n "(zomb)"
continue
fi
if test -n "$XENDOMAINS_MIGRATE"; then
echo -n "(migr)"
watchdog_xm migrate &
WDOG_PID=$!
xm migrate $id $XENDOMAINS_MIGRATE
if test $? -ne 0; then
rc_failed $?
echo -n '!'
kill $WDOG_PID >/dev/null 2>&1
else
kill $WDOG_PID >/dev/null 2>&1
continue
fi
fi
if test -n "$XENDOMAINS_SAVE"; then
echo -n "(save)"
watchdog_xm save &
WDOG_PID=$!
xm save $id $XENDOMAINS_SAVE/$name
if test $? -ne 0; then
rc_failed $?
echo -n '!'
kill $WDOG_PIG >/dev/null 2>&1
else
kill $WDOG_PIG >/dev/null 2>&1
continue
fi
fi
if test -n "$XENDOMAINS_SHUTDOWN"; then
# XENDOMAINS_SHUTDOWN should be "--halt --wait"
echo -n "(shut)"
watchdog_xm shutdown &
WDOG_PID=$!
xm shutdown $id $XENDOMAINS_SHUTDOWN
if test $? -ne 0; then
rc_failed $?
echo -n '!'
fi
kill $WDOG_PIG >/dev/null 2>&1
fi
done < <(xm list | grep -v '^Name')
# NB. this shuts down ALL Xen domains (politely), not just the ones in
# AUTODIR/*
# This is because it's easier to do ;-) but arguably if this script is run
# on system shutdown then it's also the right thing to do.
echo -n $"Shutting down all Xen domains:"
if ! all_zombies && test -n "$XENDOMAINS_SHUTDOWN_ALL"; then
# XENDOMAINS_SHUTDOWN_ALL should be "--all --halt --wait"
echo -n " SHUTDOWN_ALL "
watchdog_xm shutdown 1 &
WDOG_PID=$!
xm shutdown $XENDOMAINS_SHUTDOWN_ALL
if test $? -ne 0; then
rc_failed $?
echo -n '!'
fi
kill $WDOG_PID >/dev/null 2>&1
fi
xm shutdown --all --wait --halt
# Unconditionally delete lock file
rm -f $LOCKFILE
}
RETVAL=$?
check_domain_up()
{
while read LN; do
parseln "$LN"
if test $id = 0; then continue; fi
case $name in
($1)
return 0
;;
esac
done < <(xm list | grep -v "^Name")
return 1
}
[ $RETVAL -eq 0 ] && rm -f $LOCKFILE
check_all_auto_domains_up()
{
if ! contains_something "$XENDOMAINS_AUTO"
then
return 0
fi
missing=
for nm in $XENDOMAINS_AUTO/*; do
rdname $nm
found=0
if check_domain_up "$NM"; then
echo -n " $name"
else
missing="$missing $NM"
fi
done
if test -n "$missing"; then
echo -n " MISS AUTO:$missing"
return 1
fi
return 0
}
on_fn_exit
check_all_saved_domains_up()
{
if ! contains_something "$XENDOMAINS_SAVE"
then
return 0
fi
missing=`/bin/ls $XENDOMAINS_SAVE`
echo -n " MISS SAVED: " $missing
return 1
}
# This does NOT necessarily restart all running domains: instead it
@@ -124,47 +441,56 @@ stop()
# AUTODIR. If other domains have been started manually then they will
# not get restarted.
# Commented out to avoid confusion!
#
#restart()
#{
# stop
# start
#}
# same as restart for now - commented out to avoid confusion
#reload()
#{
# restart
#}
restart()
{
stop
start
}
reload()
{
restart
}
case "$1" in
start)
start
rc_status
if test -f $LOCKFILE; then rc_status -v; fi
;;
stop)
stop
rc_status -v
;;
# The following are commented out to disable them by default to avoid confusion
# - see the notes above
#
# restart)
# restart
# ;;
#
# reload)
# reload
# ;;
restart)
restart
;;
reload)
reload
;;
status)
xm list
echo -n "Checking for xendomains:"
if test ! -f $LOCKFILE; then
rc_failed 3
else
check_all_auto_domains_up
rc_status
check_all_saved_domains_up
rc_status
fi
rc_status -v
;;
*)
echo $"Usage: $0 {start|stop|status}"
echo "Usage: $0 {start|stop|restart|reload|status}"
rc_failed 3
rc_status -v
;;
esac
exit $RETVAL
rc_exit
+2 -2
View File
@@ -208,7 +208,7 @@ op_start () {
if ip link show ${vdev} 2>/dev/null >/dev/null; then
mac=`ip link show ${netdev} | grep 'link\/ether' | sed -e 's/.*ether \(..:..:..:..:..:..\).*/\1/'`
eval `/sbin/getcfg -d /etc/sysconfig/network/ -f ifcfg- -- ${netdev}`
preiftransfer ${netdev}
transfer_addrs ${netdev} ${vdev}
if ! ifdown ${netdev}; then
# if ifup didn't work, see if we have an ip= on cmd line
@@ -231,7 +231,7 @@ op_start () {
ip link set ${bridge} up
ip link set ${vif0} up
ip link set ${pdev} up
if ! ifup ${HWD_CONFIG_0} ${netdev} ; then
if ! ifup ${netdev} ; then
if [ ${kip} ] ; then
# use the addresses we grocked from /proc/cmdline
if [ -z "${kmask}" ]; then
+18
View File
@@ -1,3 +1,21 @@
#
# Copyright (c) 2005 XenSource Ltd.
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of version 2.1 of the GNU Lesser General Public
# License as published by the Free Software Foundation.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
set -e
export PATH="/sbin:/bin:/usr/bin:/usr/sbin:$PATH"
+36 -2
View File
@@ -16,11 +16,40 @@
#
# Gentoo doesn't have ifup/ifdown: define appropriate alternatives
if ! which ifup >&/dev/null
# On SuSE it is necessary to run a command before transfering addresses and
# routes from the physical interface to the virtual. This command creates a
# variable $HWD_CONFIG_0 that specifies the appropriate configuration for
# ifup.
# Gentoo doesn't have ifup/ifdown, so we define appropriate alternatives.
# Other platforms just use ifup / ifdown directly.
##
# preiftransfer
#
# @param $1 The current name for the physical device, which is also the name
# that the virtual device will take once the physical device has
# been renamed.
if [ -e /etc/SuSE-release ]
then
preiftransfer()
{
eval `/sbin/getcfg -d /etc/sysconfig/network/ -f ifcfg- -- $1`
}
ifup()
{
/sbin/ifup ${HWD_CONFIG_0} $1
}
elif ! which ifup >&/dev/null
then
if [ -e /etc/conf.d/net ]
then
preiftransfer()
{
true
}
ifup()
{
/etc/init.d/net.$1 start
@@ -34,4 +63,9 @@ then
"You don't have ifup and don't seem to be running Gentoo either!"
exit 1
fi
else
preiftransfer()
{
true
}
fi
+23
View File
@@ -0,0 +1,23 @@
# -*- mode: python; -*-
#
# xm create configuration example.
#
# This configuration is appropriate for using Network Block Device (NBD)
# filesystems.
#
# Each of these parameters will need changing to match your setup.
#
kernel = "/boot/vmlinuz-2.6.13-15b-xen"
ramdisk = "/boot/initrd-2.6.13-15b-xen"
memory = 128
name = "nbd4"
nics=1
# Please change MAC
vif = [ 'mac=aa:cc:10:10:00:a0, bridge=xenbr0' ]
# Please change PORT
disk = [ 'nbd:134.100.233.115 20004,hda1,w' ]
dhcp = "dhcp"
hostname= "nbd4"
root = "/dev/hda1 ro"
extra = "3"
+57
View File
@@ -22,6 +22,7 @@
* THE SOFTWARE.
*/
#include "vl.h"
#include <pthread.h>
/* 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
}
/***********************************************************/
+11 -11
View File
@@ -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
+4
View File
@@ -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;
+6 -4
View File
@@ -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;
+1
View File
@@ -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);
-1
View File
@@ -16,7 +16,6 @@
#include <sys/types.h>
#include <sched.h>
#include <error.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
+1 -1
View File
@@ -29,7 +29,7 @@
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/signal.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/wait.h>
+5 -4
View File
@@ -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);
+1 -1
View File
@@ -695,7 +695,7 @@ static PyObject *xspy_introduce_domain(PyObject *self, PyObject *args,
PyObject *kwds)
{
static char *kwd_spec[] = { "dom", "page", "port", NULL };
static char *arg_spec = "iii";
static char *arg_spec = "ili";
domid_t dom = 0;
unsigned long page = 0;
unsigned int port = 0;
+1 -1
View File
@@ -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)
+1
View File
@@ -595,6 +595,7 @@ class XendDomainInfo:
to_store = {
'domid': str(self.domid),
'vm': self.vmpath,
'name': self.info['name'],
'console/limit': str(xroot.get_console_limit() * 1024),
'memory/target': str(self.info['memory_KiB'])
}
+6
View File
@@ -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())
+1 -4
View File
@@ -262,10 +262,7 @@ class Daemon:
return 1
def stop(self):
result = self.cleanup_xend(True)
from xen.xend import Vifctl
Vifctl.network("stop")
return result
return self.cleanup_xend(True)
def run(self, status):
try:
+4 -5
View File
@@ -25,7 +25,6 @@ from xen.xend import XendDomain
from xen.xend.XendDomainInfo import XendDomainInfo
from xen.xend.Args import FormFn
from xen.xend.XendError import XendError
from xen.xend.XendLogging import log
from xen.web.SrvDir import SrvDir
from SrvDomain import SrvDomain
@@ -52,7 +51,7 @@ class SrvDomainDir(SrvDir):
else:
return self.domain(x)
def op_create(self, op, req):
def op_create(self, _, req):
"""Create a domain.
Expects the domain config in request parameter 'config' in SXP format.
"""
@@ -66,12 +65,12 @@ class SrvDomainDir(SrvDir):
pin.input_eof()
config = pin.get_val()
ok = 1
except sxp.ParseError, ex:
errmsg = 'Invalid configuration ' + str(ex)
except Exception, ex:
print 'op_create> Exception in config', ex
traceback.print_exc()
errmsg = 'Configuration error ' + str(ex)
except sxp.ParseError, ex:
errmsg = 'Invalid configuration ' + str(ex)
if not ok:
raise XendError(errmsg)
try:
@@ -108,7 +107,7 @@ class SrvDomainDir(SrvDir):
"""
return req.threadRequest(self.do_restore, op, req)
def do_restore(self, op, req):
def do_restore(self, _, req):
fn = FormFn(self.xd.domain_restore,
[['file', 'str']])
dominfo = fn(req.args)
+2 -1
View File
@@ -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()
@@ -5,9 +5,6 @@
# Public License. See the file "COPYING" in the main directory of
# this archive for more details.
import errno
import threading
from xen.lowlevel import xs
from xen.xend.xenstore.xsutil import xshandle
+7 -7
View File
@@ -158,6 +158,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.")
@@ -316,10 +320,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.")
@@ -542,9 +542,9 @@ def configure_vfr(opts, config, vals):
def configure_vmx(opts, 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]])
+4
View File
@@ -61,6 +61,8 @@ xm common subcommands:
top monitor system and domains in real-time
unpause <DomId> unpause a paused domain
<DomName> can be substituted for <DomId> 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 <config> create a vnet from a config file
vnet-delete <vnetid> delete a vnet
<DomName> can be substituted for <DomId> 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"""
+15 -12
View File
@@ -36,18 +36,21 @@ source labelfuncs.sh
usage ()
{
echo "Usage: $0 -sid <ssidref> [<policy name>] or"
echo " $0 -dom <domid> [<policy name>] "
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 <ssidref> [<policy name>] or
$0 -dom <domid> [<policy name>]
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'
"
}
+23 -17
View File
@@ -39,21 +39,27 @@ source labelfuncs.sh
usage ()
{
echo "Usage: $0 [Option] <vmfile> <label> [<policy name>]"
echo " or $0 -l [<policy name>]"
echo ""
echo "Valid options are:"
echo "-r : to relabel a file without being prompted"
echo ""
echo "vmfile : XEN vm configuration file"
echo "label : the label to map to an ssidref"
echo "policy name : the name of the policy, i.e. 'chwall'"
echo " If the policy name is omitted, it is attempted"
echo " to find the current policy's name in grub.conf."
echo ""
echo "-l [<policy name>] is used to show valid labels in the map file of"
echo " the given or current policy."
echo ""
echo "Use this tool to put the ssidref corresponding to a label of a policy into
the VM configuration file, or use it to display all labels of a policy.
Usage: $0 [Option] <vmfile> <label> [<policy name>]
or $0 -l [<policy name>]
Valid options are:
-r : to relabel a file without being prompted
vmfile : XEN vm configuration file; give complete path
label : the label to map to an ssidref
policy name : the name of the policy, i.e. 'chwall'
If the policy name is omitted, it is attempted
to find the current policy's name in grub.conf.
-l [<policy name>] is used to show valid labels in the map file of
the given or current policy. If the policy name
is omitted, it will be tried to determine the
current policy from grub.conf (/boot/grub/grub.conf)
"
}
@@ -83,7 +89,7 @@ if [ "$mode" == "show" ]; then
exit -1;
fi
else
policy=$3;
policy=$1;
fi
@@ -92,7 +98,7 @@ if [ "$mode" == "show" ]; then
if [ "$res" != "0" ]; then
showLabels $mapfile
else
echo "Could not find map file for policy '$1'."
echo "Could not find map file for policy '$policy'."
fi
elif [ "$mode" == "usage" ]; then
usage
+38 -11
View File
@@ -26,11 +26,16 @@ fi
# Show usage of this program
usage ()
{
echo "Usage: $0 <policy name> <root of xen repository>"
echo ""
echo "<policy name> : The name of the policy, i.e. xen_null"
echo "<root of xen repository> : The root of the XEN repositrory."
echo ""
echo "Use this tool to add the binary policy to the Xen grub entry and
have Xen automatically enforce the policy when starting.
Usage: $0 <policy name> <root of xen repository>
<policy name> : The name of the policy, i.e. xen_null
<root of xen repository> : The root of the XEN repository. Give
complete path.
"
}
# This function sets the global variable 'linux'
@@ -43,11 +48,24 @@ getLinuxVersion ()
for f in $path/linux-*-xen0 ; do
versionfile=$f/include/linux/version.h
if [ -r $versionfile ]; then
lnx=`cat $versionfile | \
grep UTS_RELEASE | \
awk '{ \
len=length($3); \
print substr($3,2,len-2) }'`
lnx=`cat $versionfile | \
grep UTS_RELEASE | \
awk '{ \
len=length($3); \
version=substr($3,2,len-2); \
split(version,numbers,"."); \
if (numbers[4]=="") { \
printf("%s.%s.%s", \
numbers[1], \
numbers[2], \
numbers[3]); \
} else { \
printf("%s.%s.%s[.0-9]*-xen0",\
numbers[1], \
numbers[2], \
numbers[3]); \
} \
}'`
fi
if [ "$lnx" != "" ]; then
linux="[./0-9a-zA-z]*$lnx"
@@ -143,10 +161,19 @@ updateGrub ()
echo "Could not create temporary file! Aborting."
exit -1
fi
mv -f $tmpfile $grubconf
diff $tmpfile $grubconf > /dev/null
RES=$?
if [ "$RES" == "0" ]; then
echo "No changes were made to $grubconf."
else
echo "Successfully updated $grubconf."
mv -f $tmpfile $grubconf
fi
}
if [ "$1" == "" -o "$2" == "" ]; then
echo "Error: Not enough command line parameters."
echo ""
usage
exit -1
fi
+2 -2
View File
@@ -38,13 +38,13 @@ SONAME_FLAGS=-Wl,-soname -Wl,libxenstat.so.$(MAJOR)
WARN_FLAGS=-Wall -Werror
CFLAGS+=-Isrc -I$(XEN_LIBXC)
CFLAGS+=-Isrc -I$(XEN_LIBXC) -I$(XEN_XENSTORE)
LDFLAGS+=-Lsrc
all: $(LIB)
$(LIB): $(OBJECTS)
$(AR) rc $@ $^
$(AR) rc $@ $^ $(XEN_XENSTORE)/libxenstore.so
$(RANLIB) $@
$(SHLIB): $(OBJECTS)
+41
View File
@@ -21,6 +21,7 @@
#include <string.h>
#include <unistd.h>
#include <xen-interface.h>
#include <xs.h>
#include "xenstat.h"
/*
@@ -31,6 +32,7 @@
struct xenstat_handle {
xi_handle *xihandle;
struct xs_handle *xshandle; /* xenstore handle */
int page_size;
FILE *procnetdev;
char xen_version[VERSION_SIZE]; /* xen version running on this node */
@@ -49,6 +51,7 @@ struct xenstat_node {
struct xenstat_domain {
unsigned int id;
char *name;
unsigned int state;
unsigned long long cpu_ns;
unsigned int num_vcpus; /* No. vcpus configured for domain */
@@ -110,6 +113,7 @@ static void xenstat_free_xen_version(xenstat_node * node);
static void xenstat_uninit_vcpus(xenstat_handle * handle);
static void xenstat_uninit_networks(xenstat_handle * handle);
static void xenstat_uninit_xen_version(xenstat_handle * handle);
static char *xenstat_get_domain_name(xenstat_handle * handle, unsigned int domain_id);
static xenstat_collector collectors[] = {
{ XENSTAT_VCPU, xenstat_collect_vcpus,
@@ -153,6 +157,13 @@ xenstat_handle *xenstat_init()
return NULL;
}
handle->xshandle = xs_daemon_open_readonly(); /* open handle to xenstore*/
if (handle->xshandle == NULL) {
perror("unable to open xenstore\n");
free(handle);
return NULL;
}
return handle;
}
@@ -163,6 +174,7 @@ void xenstat_uninit(xenstat_handle * handle)
for (i = 0; i < NUM_COLLECTORS; i++)
collectors[i].uninit(handle);
xi_uninit(handle->xihandle);
xs_daemon_close(handle->xshandle);
free(handle);
}
}
@@ -228,6 +240,7 @@ xenstat_node *xenstat_get_node(xenstat_handle * handle, unsigned int flags)
for (i = 0; i < new_domains; i++) {
/* Fill in domain using domaininfo[i] */
domain->id = domaininfo[i].domain;
domain->name = xenstat_get_domain_name(handle, domaininfo[i].domain);
domain->state = domaininfo[i].flags;
domain->cpu_ns = domaininfo[i].cpu_time;
domain->num_vcpus = (domaininfo[i].max_vcpu_id+1);
@@ -339,6 +352,12 @@ unsigned xenstat_domain_id(xenstat_domain * domain)
return domain->id;
}
/* Get the domain name for the domain */
char *xenstat_domain_name(xenstat_domain * domain)
{
return domain->name;
}
/* Get information about how much CPU time has been used */
unsigned long long xenstat_domain_cpu_ns(xenstat_domain * domain)
{
@@ -675,3 +694,25 @@ static void xenstat_free_xen_version(xenstat_node * node)
static void xenstat_uninit_xen_version(xenstat_handle * handle)
{
}
static char *xenstat_get_domain_name(xenstat_handle *handle, unsigned int domain_id)
{
char path[80];
char *name;
unsigned int *len;
struct xs_transaction_handle *xstranshandle;
snprintf(path, sizeof(path),"/local/domain/%i/name", domain_id);
xstranshandle = xs_transaction_start(handle->xshandle);
if (xstranshandle == NULL) {
perror("Unable to get transcation handle from xenstore\n");
exit(1); /* Change this */
}
name = (char *) xs_read(handle->xshandle, xstranshandle, path, len);
xs_transaction_end(handle->xshandle, xstranshandle, false);
return name;
}
+3
View File
@@ -80,6 +80,9 @@ unsigned long long xenstat_node_cpu_hz(xenstat_node * node);
/* Get the domain ID for this domain */
unsigned xenstat_domain_id(xenstat_domain * domain);
/* Set the domain name for the domain */
char *xenstat_domain_name(xenstat_domain * domain);
/* Get information about how much CPU time has been used */
unsigned long long xenstat_domain_cpu_ns(xenstat_domain * domain);
+10 -9
View File
@@ -67,8 +67,6 @@ static int compare_domains(xenstat_domain **, xenstat_domain **);
static unsigned long long tot_net_bytes( xenstat_domain *, int);
/* Field functions */
static int compare_domid(xenstat_domain *domain1, xenstat_domain *domain2);
static void print_domid(xenstat_domain *domain);
static int compare_state(xenstat_domain *domain1, xenstat_domain *domain2);
static void print_state(xenstat_domain *domain);
static int compare_cpu(xenstat_domain *domain1, xenstat_domain *domain2);
@@ -91,6 +89,8 @@ static int compare_net_rx(xenstat_domain *domain1, xenstat_domain *domain2);
static void print_net_rx(xenstat_domain *domain);
static int compare_ssid(xenstat_domain *domain1, xenstat_domain *domain2);
static void print_ssid(xenstat_domain *domain);
static int compare_name(xenstat_domain *domain1, xenstat_domain *domain2);
static void print_name(xenstat_domain *domain);
/* Section printing functions */
static void do_summary(void);
@@ -104,6 +104,7 @@ static void top(void);
/* Field types */
typedef enum field_id {
FIELD_DOMID,
FIELD_NAME,
FIELD_STATE,
FIELD_CPU,
FIELD_CPU_PCT,
@@ -127,7 +128,7 @@ typedef struct field {
} field;
field fields[] = {
{ FIELD_DOMID, "DOMID", 5, compare_domid, print_domid },
{ FIELD_NAME, "NAME", 10, compare_name, print_name },
{ FIELD_STATE, "STATE", 6, compare_state, print_state },
{ FIELD_CPU, "CPU(sec)", 10, compare_cpu, print_cpu },
{ FIELD_CPU_PCT, "CPU(%)", 6, compare_cpu_pct, print_cpu_pct },
@@ -344,16 +345,16 @@ static int compare_domains(xenstat_domain **domain1, xenstat_domain **domain2)
/* Field functions */
/* Compares domain ids of two domains, returning -1,0,1 for <,=,> */
int compare_domid(xenstat_domain *domain1, xenstat_domain *domain2)
/* Compare domain names, returning -1,0,1 for <,=,> */
int compare_name(xenstat_domain *domain1, xenstat_domain *domain2)
{
return compare(xenstat_domain_id(domain1), xenstat_domain_id(domain2));
return strcasecmp(xenstat_domain_name(domain1), xenstat_domain_name(domain2));
}
/* Prints domain identification number */
void print_domid(xenstat_domain *domain)
/* Prints domain name */
void print_name(xenstat_domain *domain)
{
print("%5u", xenstat_domain_id(domain));
print("%10s", xenstat_domain_name(domain));
}
struct {
+1 -1
View File
@@ -77,7 +77,7 @@ libxenstore.so: xs.opic xs_lib.opic
clean: testsuite-clean
rm -f *.o *.opic *.so
rm -f xenstored xs_random xs_stress xs_crashme
rm -f xs_test xenstored_test
rm -f xs_test xenstored_test xs_tdb_dump
$(RM) $(PROG_DEP)
print-dir:
+1 -1
View File
@@ -188,7 +188,7 @@ static void trace_io(const struct connection *conn,
tm = localtime(&now);
write(tracefd, prefix, strlen(prefix));
sprintf(string, " %p %0d:%0d:%0d ", conn, tm->tm_hour, tm->tm_min,
sprintf(string, " %p %02d:%02d:%02d ", conn, tm->tm_hour, tm->tm_min,
tm->tm_sec);
write(tracefd, string, strlen(string));
write(tracefd, sockmsg_string(data->hdr.msg.type),
+66 -40
View File
@@ -392,8 +392,11 @@ check_cache(struct domain *dom, domid_t rdom) {
int i;
printkd("checking cache: %x --> %x.\n", dom->domain_id, rdom);
if (dom->ssid == NULL)
return 0;
ste_ssid = GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY,
(struct acm_ssid_domain *)(dom)->ssid);
(struct acm_ssid_domain *)(dom->ssid));
for(i=0; i< ACM_TE_CACHE_SIZE; i++) {
if ((ste_ssid->ste_cache[i].valid == VALID) &&
@@ -412,6 +415,8 @@ cache_result(struct domain *subj, struct domain *obj) {
struct ste_ssid *ste_ssid;
int i;
printkd("caching from doms: %x --> %x.\n", subj->domain_id, obj->domain_id);
if (subj->ssid == NULL)
return;
ste_ssid = GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY,
(struct acm_ssid_domain *)(subj)->ssid);
for(i=0; i< ACM_TE_CACHE_SIZE; i++)
@@ -431,26 +436,34 @@ clean_id_from_cache(domid_t id)
struct ste_ssid *ste_ssid;
int i;
struct domain **pd;
struct acm_ssid_domain *ssid;
printkd("deleting cache for dom %x.\n", id);
read_lock(&domlist_lock); /* look through caches of all domains */
pd = &domain_list;
for ( pd = &domain_list; *pd != NULL; pd = &(*pd)->next_in_list ) {
ste_ssid = GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY,
(struct acm_ssid_domain *)(*pd)->ssid);
ssid = (struct acm_ssid_domain *)((*pd)->ssid);
if (ssid == NULL)
continue; /* hanging domain structure, no ssid any more ... */
ste_ssid = GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, ssid);
if (!ste_ssid) {
printk("%s: deleting ID from cache ERROR (no ste_ssid)!\n",
__func__);
goto out;
}
for (i=0; i<ACM_TE_CACHE_SIZE; i++)
if ((ste_ssid->ste_cache[i].valid == VALID) &&
(ste_ssid->ste_cache[i].id = id))
(ste_ssid->ste_cache[i].id == id))
ste_ssid->ste_cache[i].valid = FREE;
}
out:
read_unlock(&domlist_lock);
}
/***************************
* Authorization functions
**************************/
static int
ste_pre_domain_create(void *subject_ssid, ssidref_t ssidref)
{
@@ -484,44 +497,13 @@ ste_post_domain_destroy(void *subject_ssid, domid_t id)
/* -------- EVENTCHANNEL OPERATIONS -----------*/
static int
ste_pre_eventchannel_unbound(domid_t id) {
struct domain *subj, *obj;
int ret;
traceprintk("%s: dom%x-->dom%x.\n",
__func__, current->domain->domain_id, id);
if (check_cache(current->domain, id)) {
atomic_inc(&ste_bin_pol.ec_cachehit_count);
return ACM_ACCESS_PERMITTED;
}
atomic_inc(&ste_bin_pol.ec_eval_count);
subj = current->domain;
obj = find_domain_by_id(id);
if (share_common_type(subj, obj)) {
cache_result(subj, obj);
ret = ACM_ACCESS_PERMITTED;
} else {
atomic_inc(&ste_bin_pol.ec_denied_count);
ret = ACM_ACCESS_DENIED;
}
if (obj != NULL)
put_domain(obj);
return ret;
}
static int
ste_pre_eventchannel_interdomain(domid_t id1, domid_t id2)
{
ste_pre_eventchannel_unbound(domid_t id1, domid_t id2) {
struct domain *subj, *obj;
int ret;
traceprintk("%s: dom%x-->dom%x.\n", __func__,
(id1 == DOMID_SELF) ? current->domain->domain_id : id1,
(id2 == DOMID_SELF) ? current->domain->domain_id : id2);
/* following is a bit longer but ensures that we
* "put" only domains that we where "find"-ing
*/
if (id1 == DOMID_SELF) id1 = current->domain->domain_id;
if (id2 == DOMID_SELF) id2 = current->domain->domain_id;
@@ -531,7 +513,7 @@ ste_pre_eventchannel_interdomain(domid_t id1, domid_t id2)
ret = ACM_ACCESS_DENIED;
goto out;
}
/* cache check late, but evtchn is not on performance critical path */
/* cache check late */
if (check_cache(subj, obj->domain_id)) {
atomic_inc(&ste_bin_pol.ec_cachehit_count);
ret = ACM_ACCESS_PERMITTED;
@@ -546,7 +528,7 @@ ste_pre_eventchannel_interdomain(domid_t id1, domid_t id2)
atomic_inc(&ste_bin_pol.ec_denied_count);
ret = ACM_ACCESS_DENIED;
}
out:
out:
if (obj != NULL)
put_domain(obj);
if (subj != NULL)
@@ -554,6 +536,50 @@ ste_pre_eventchannel_interdomain(domid_t id1, domid_t id2)
return ret;
}
static int
ste_pre_eventchannel_interdomain(domid_t id)
{
struct domain *subj=NULL, *obj=NULL;
int ret;
traceprintk("%s: dom%x-->dom%x.\n", __func__,
current->domain->domain_id,
(id == DOMID_SELF) ? current->domain->domain_id : id);
/* following is a bit longer but ensures that we
* "put" only domains that we where "find"-ing
*/
if (id == DOMID_SELF) id = current->domain->domain_id;
subj = current->domain;
obj = find_domain_by_id(id);
if (obj == NULL) {
ret = ACM_ACCESS_DENIED;
goto out;
}
/* cache check late, but evtchn is not on performance critical path */
if (check_cache(subj, obj->domain_id)) {
atomic_inc(&ste_bin_pol.ec_cachehit_count);
ret = ACM_ACCESS_PERMITTED;
goto out;
}
atomic_inc(&ste_bin_pol.ec_eval_count);
if (share_common_type(subj, obj)) {
cache_result(subj, obj);
ret = ACM_ACCESS_PERMITTED;
} else {
atomic_inc(&ste_bin_pol.ec_denied_count);
ret = ACM_ACCESS_DENIED;
}
out:
if (obj != NULL)
put_domain(obj);
return ret;
}
/* -------- SHARED MEMORY OPERATIONS -----------*/
static int
+2
View File
@@ -29,6 +29,7 @@
#include <xen/event.h>
//#include <xen/shadow.h>
#include <xen/console.h>
#include <xen/compile.h>
#include <xen/elf.h>
//#include <asm/page.h>
@@ -948,6 +949,7 @@ int construct_dom0(struct domain *d,
si = (start_info_t *)alloc_xenheap_page();
memset(si, 0, PAGE_SIZE);
d->shared_info->arch.start_info_pfn = __pa(si) >> PAGE_SHIFT;
sprintf(si->magic, "Xen-%i.%i", XEN_VERSION, XEN_SUBVERSION);
#if 0
si->nr_pages = d->tot_pages;
+4
View File
@@ -815,6 +815,10 @@ int __init calibrate_APIC_clock(void)
return result;
}
unsigned int get_apic_bus_scale(void)
{
return bus_scale;
}
static unsigned int calibration_result;
+11 -4
View File
@@ -32,8 +32,8 @@
#include <public/io/ioreq.h>
#include <asm/vmx.h>
#include <public/io/vmx_vpic.h>
#include <public/io/vmx_vlapic.h>
#include <asm/current.h>
#include <asm/vmx_vlapic.h>
/* set irq level. If an edge is detected, then the IRR is set to 1 */
static inline void pic_set_irq1(PicState *s, int irq, int level)
@@ -135,7 +135,6 @@ void do_pic_irqs (struct vmx_virpic *s, uint16_t irqs)
{
s->pics[1].irr |= (uint8_t)(irqs >> 8);
s->pics[0].irr |= (uint8_t) irqs;
/* TODO for alt_irq_func */
pic_update_irq(s);
}
@@ -505,14 +504,22 @@ int cpu_get_pic_interrupt(struct vcpu *v, int *type)
{
int intno;
struct vmx_virpic *s = &v->domain->arch.vmx_platform.vmx_pic;
struct vmx_platform *plat = &v->domain->arch.vmx_platform;
if ( !vlapic_accept_pic_intr(v) )
return -1;
if ( !plat->interrupt_request )
return -1;
/* read the irq from the PIC */
intno = pic_read_irq(s);
*type = VLAPIC_DELIV_MODE_EXT;
plat->interrupt_request = 0;
return intno;
}
int is_pit_irq(struct vcpu *v, int irq)
int is_pit_irq(struct vcpu *v, int irq, int type)
{
int pit_vec = v->domain->arch.vmx_platform.vmx_pic.pics[0].irq_base;
+5 -7
View File
@@ -15,6 +15,7 @@
#include <xen/elf.h>
#include <xen/kernel.h>
#include <xen/domain.h>
#include <xen/compile.h>
#include <asm/regs.h>
#include <asm/system.h>
#include <asm/io.h>
@@ -582,26 +583,23 @@ int construct_dom0(struct domain *d,
_initrd_start, (_initrd_start+initrd_len+PAGE_SIZE-1) & PAGE_MASK);
}
d->next_io_page = max_page;
/* Set up start info area. */
si = (start_info_t *)vstartinfo_start;
memset(si, 0, PAGE_SIZE);
si->nr_pages = nr_pages;
si->shared_info = virt_to_phys(d->shared_info);
if ( opt_dom0_translate )
{
si->shared_info = d->next_io_page << PAGE_SHIFT;
set_pfn_from_mfn(virt_to_phys(d->shared_info) >> PAGE_SHIFT, d->next_io_page);
d->next_io_page++;
si->shared_info = max_page << PAGE_SHIFT;
set_pfn_from_mfn(virt_to_phys(d->shared_info) >> PAGE_SHIFT, max_page);
}
else
si->shared_info = virt_to_phys(d->shared_info);
si->flags = SIF_PRIVILEGED | SIF_INITDOMAIN;
si->pt_base = vpt_start;
si->nr_pt_frames = nr_pt_pages;
si->mfn_list = vphysmap_start;
sprintf(si->magic, "Xen-%i.%i", XEN_VERSION, XEN_SUBVERSION);
/* Write the phys->machine and machine->phys table entries. */
for ( pfn = 0; pfn < d->tot_pages; pfn++ )
+4 -1
View File
@@ -1164,6 +1164,7 @@ static int mod_l3_entry(l3_pgentry_t *pl3e,
{
l3_pgentry_t ol3e;
unsigned long vaddr;
int okay;
if ( unlikely(!is_guest_l3_slot(pgentry_ptr_to_slot(pl3e))) )
{
@@ -1218,7 +1219,9 @@ static int mod_l3_entry(l3_pgentry_t *pl3e,
return 0;
}
BUG_ON(!create_pae_xen_mappings(pl3e));
okay = create_pae_xen_mappings(pl3e);
BUG_ON(!okay);
put_page_from_l3e(ol3e, pfn);
return 1;
}
+2 -4
View File
@@ -323,7 +323,7 @@ static u64 read_pit_count(void)
return pit_counter64 + (u16)(pit_stamp - pit_read_counter());
}
static int init_pit(void)
static void init_pit(void)
{
read_platform_count = read_pit_count;
@@ -333,8 +333,6 @@ static int init_pit(void)
printk("Platform timer is %s PIT\n", freq_string(CLOCK_TICK_RATE));
using_pit = 1;
return 1;
}
/************************************************************
@@ -563,7 +561,7 @@ static void platform_time_calibration(void)
static void init_platform_timer(void)
{
if ( !init_cyclone() && !init_hpet() )
BUG_ON(!init_pit());
init_pit();
}
+24 -1
View File
@@ -65,6 +65,11 @@ void vmx_final_setup_guest(struct vcpu *v)
if ( v == v->domain->vcpu[0] )
{
v->domain->arch.vmx_platform.lapic_enable =
v->arch.guest_context.user_regs.ecx;
v->arch.guest_context.user_regs.ecx = 0;
VMX_DBG_LOG(DBG_LEVEL_VLAPIC, "lapic enable is %d.\n",
v->domain->arch.vmx_platform.lapic_enable);
/*
* Required to do this once per domain
* XXX todo: add a seperate function to do these.
@@ -96,6 +101,10 @@ void vmx_relinquish_resources(struct vcpu *v)
destroy_vmcs(&v->arch.arch_vmx);
free_monitor_pagetable(v);
rem_ac_timer(&v->domain->arch.vmx_platform.vmx_pit.pit_timer);
if ( vmx_apic_support(v->domain) ) {
rem_ac_timer( &(VLAPIC(v)->vlapic_timer) );
xfree( VLAPIC(v) );
}
}
#ifdef __x86_64__
@@ -442,7 +451,9 @@ static int vmx_do_page_fault(unsigned long va, struct cpu_user_regs *regs)
/* Use 1:1 page table to identify MMIO address space */
if ( mmio_space(gpa) ){
if (gpa >= 0xFEE00000) { /* workaround for local APIC */
struct vcpu *v = current;
/* No support for APIC */
if (!vmx_apic_support(v->domain) && gpa >= 0xFEC00000) {
u32 inst_len;
__vmread(VM_EXIT_INSTRUCTION_LEN, &(inst_len));
__update_guest_eip(inst_len);
@@ -487,6 +498,7 @@ static void vmx_vmexit_do_cpuid(unsigned long input, struct cpu_user_regs *regs)
{
unsigned int eax, ebx, ecx, edx;
unsigned long eip;
struct vcpu *v = current;
__vmread(GUEST_RIP, &eip);
@@ -500,6 +512,9 @@ static void vmx_vmexit_do_cpuid(unsigned long input, struct cpu_user_regs *regs)
cpuid(input, &eax, &ebx, &ecx, &edx);
if (input == 1) {
if ( vmx_apic_support(v->domain) &&
!vlapic_global_enabled((VLAPIC(v))) )
clear_bit(X86_FEATURE_APIC, &edx);
#ifdef __i386__
clear_bit(X86_FEATURE_PSE, &edx);
clear_bit(X86_FEATURE_PAE, &edx);
@@ -1441,6 +1456,7 @@ static int vmx_cr_access(unsigned long exit_qualification, struct cpu_user_regs
static inline void vmx_do_msr_read(struct cpu_user_regs *regs)
{
u64 msr_content = 0;
struct vcpu *v = current;
VMX_DBG_LOG(DBG_LEVEL_1, "vmx_do_msr_read: ecx=%lx, eax=%lx, edx=%lx",
(unsigned long)regs->ecx, (unsigned long)regs->eax,
@@ -1455,6 +1471,9 @@ static inline void vmx_do_msr_read(struct cpu_user_regs *regs)
case MSR_IA32_SYSENTER_EIP:
__vmread(GUEST_SYSENTER_EIP, &msr_content);
break;
case MSR_IA32_APICBASE:
msr_content = VLAPIC(v) ? VLAPIC(v)->apic_base_msr : 0;
break;
default:
if(long_mode_do_msr_read(regs))
return;
@@ -1474,6 +1493,7 @@ static inline void vmx_do_msr_read(struct cpu_user_regs *regs)
static inline void vmx_do_msr_write(struct cpu_user_regs *regs)
{
u64 msr_content;
struct vcpu *v = current;
VMX_DBG_LOG(DBG_LEVEL_1, "vmx_do_msr_write: ecx=%lx, eax=%lx, edx=%lx",
(unsigned long)regs->ecx, (unsigned long)regs->eax,
@@ -1491,6 +1511,9 @@ static inline void vmx_do_msr_write(struct cpu_user_regs *regs)
case MSR_IA32_SYSENTER_EIP:
__vmwrite(GUEST_SYSENTER_EIP, msr_content);
break;
case MSR_IA32_APICBASE:
vlapic_msr_set(VLAPIC(v), msr_content);
break;
default:
long_mode_do_msr_write(regs);
break;
+118
View File
@@ -23,6 +23,7 @@
#include <asm/vmx_platform.h>
#include <asm/vmx_virpit.h>
#include <asm/vmx_intercept.h>
#include <asm/vmx_vlapic.h>
#include <public/io/ioreq.h>
#include <xen/lib.h>
#include <xen/sched.h>
@@ -32,6 +33,123 @@
#ifdef CONFIG_VMX
struct vmx_mmio_handler vmx_mmio_handers[VMX_MMIO_HANDLER_NR] =
{
{
.check_handler = vlapic_range,
.read_handler = vlapic_read,
.write_handler = vlapic_write
}
};
static inline void vmx_mmio_access(struct vcpu *v,
ioreq_t *p,
vmx_mmio_read_t read_handler,
vmx_mmio_write_t write_handler)
{
ioreq_t *req;
vcpu_iodata_t *vio = get_vio(v->domain, v->vcpu_id);
unsigned int tmp1, tmp2;
unsigned long data;
if (vio == NULL) {
printk("vlapic_access: bad shared page\n");
domain_crash_synchronous();
}
req = &vio->vp_ioreq;
switch (req->type) {
case IOREQ_TYPE_COPY:
{
int sign = (req->df) ? -1 : 1, i;
if (!req->pdata_valid) {
if (req->dir == IOREQ_READ){
req->u.data = read_handler(v, req->addr, req->size);
} else { /* req->dir != IOREQ_READ */
write_handler(v, req->addr, req->size, req->u.data);
}
} else { /* !req->pdata_valid */
if (req->dir == IOREQ_READ) {
for (i = 0; i < req->count; i++) {
data = read_handler(v,
req->addr + (sign * i * req->size),
req->size);
vmx_copy(&data,
(unsigned long)p->u.pdata + (sign * i * req->size),
p->size,
VMX_COPY_OUT);
}
} else { /* !req->dir == IOREQ_READ */
for (i = 0; i < req->count; i++) {
vmx_copy(&data,
(unsigned long)p->u.pdata + (sign * i * req->size),
p->size,
VMX_COPY_IN);
write_handler(v,
req->addr + (sign * i * req->size),
req->size, data);
}
}
}
break;
}
case IOREQ_TYPE_AND:
tmp1 = read_handler(v, req->addr, req->size);
if (req->dir == IOREQ_WRITE) {
tmp2 = tmp1 & (unsigned long) req->u.data;
write_handler(v, req->addr, req->size, tmp2);
}
req->u.data = tmp1;
break;
case IOREQ_TYPE_OR:
tmp1 = read_handler(v, req->addr, req->size);
if (req->dir == IOREQ_WRITE) {
tmp2 = tmp1 | (unsigned long) req->u.data;
write_handler(v, req->addr, req->size, tmp2);
}
req->u.data = tmp1;
break;
case IOREQ_TYPE_XOR:
tmp1 = read_handler(v, req->addr, req->size);
if (req->dir == IOREQ_WRITE) {
tmp2 = tmp1 ^ (unsigned long) req->u.data;
write_handler(v, req->addr, req->size, tmp2);
}
req->u.data = tmp1;
break;
default:
printk("error ioreq type for local APIC %x\n", req->type);
domain_crash_synchronous();
break;
}
}
int vmx_mmio_intercept(ioreq_t *p)
{
struct vcpu *v = current;
int i;
struct vmx_mmio_handler *handler = vmx_mmio_handers;
/* XXX currently only APIC use intercept */
if ( !vmx_apic_support(v->domain) )
return 0;
for ( i = 0; i < VMX_MMIO_HANDLER_NR; i++ ) {
if ( handler[i].check_handler(v, p->addr) ) {
vmx_mmio_access(v, p,
handler[i].read_handler, handler[i].write_handler);
return 1;
}
}
return 0;
}
/*
* Check if the request is handled inside xen
* return value: 0 --not handled; 1 --handled
+47 -71
View File
@@ -36,9 +36,9 @@
#include <asm/apic.h>
#include <asm/shadow.h>
#include <asm/vmx_vlapic.h>
#include <public/io/ioreq.h>
#include <public/io/vmx_vpic.h>
#include <public/io/vmx_vlapic.h>
#ifdef CONFIG_VMX
#if defined (__i386__)
@@ -732,48 +732,6 @@ void vmx_wait_io()
} while(1);
}
#if defined(__i386__) || defined(__x86_64__)
static inline int __fls(u32 word)
{
int bit;
__asm__("bsrl %1,%0"
:"=r" (bit)
:"rm" (word));
return word ? bit : -1;
}
#else
#define __fls(x) generic_fls(x)
static __inline__ int generic_fls(u32 x)
{
int r = 31;
if (!x)
return -1;
if (!(x & 0xffff0000u)) {
x <<= 16;
r -= 16;
}
if (!(x & 0xff000000u)) {
x <<= 8;
r -= 8;
}
if (!(x & 0xf0000000u)) {
x <<= 4;
r -= 4;
}
if (!(x & 0xc0000000u)) {
x <<= 2;
r -= 2;
}
if (!(x & 0x80000000u)) {
x <<= 1;
r -= 1;
}
return r;
}
#endif
/* Simple minded Local APIC priority implementation. Fix later */
static __inline__ int find_highest_irq(u32 *pintr)
{
@@ -801,31 +759,31 @@ interrupt_post_injection(struct vcpu * v, int vector, int type)
struct vmx_virpit *vpit = &(v->domain->arch.vmx_platform.vmx_pit);
u64 drift;
if ( is_pit_irq(v, vector, type) ) {
if ( !vpit->first_injected ) {
vpit->first_injected = 1;
vpit->pending_intr_nr = 0;
} else {
vpit->pending_intr_nr--;
}
vpit->inject_point = NOW();
drift = vpit->period_cycles * vpit->pending_intr_nr;
drift = v->arch.arch_vmx.tsc_offset - drift;
__vmwrite(TSC_OFFSET, drift);
#if defined (__i386__)
__vmwrite(TSC_OFFSET_HIGH, (drift >> 32));
#endif
}
switch(type)
{
case VLAPIC_DELIV_MODE_EXT:
if ( is_pit_irq(v, vector) ) {
if ( !vpit->first_injected ) {
vpit->first_injected = 1;
vpit->pending_intr_nr = 0;
}
else {
vpit->pending_intr_nr--;
}
vpit->inject_point = NOW();
drift = vpit->period_cycles * vpit->pending_intr_nr;
drift = v->arch.arch_vmx.tsc_offset - drift;
__vmwrite(TSC_OFFSET, drift);
#if defined (__i386__)
__vmwrite(TSC_OFFSET_HIGH, (drift >> 32));
#endif
}
break;
default:
printk("Not support interrupt type\n");
vlapic_post_injection(v, vector, type);
break;
}
}
@@ -885,6 +843,24 @@ void vmx_pic_assist(struct vcpu *v)
}
int cpu_get_interrupt(struct vcpu *v, int *type)
{
int intno;
struct vmx_virpic *s = &v->domain->arch.vmx_platform.vmx_pic;
if ( (intno = cpu_get_apic_interrupt(v, type)) != -1 ) {
/* set irq request if a PIC irq is still pending */
/* XXX: improve that */
pic_update_irq(s);
return intno;
}
/* read the irq from the PIC */
if ( (intno = cpu_get_pic_interrupt(v, type)) != -1 )
return intno;
return -1;
}
asmlinkage void vmx_intr_assist(void)
{
int intr_type = 0;
@@ -902,11 +878,6 @@ asmlinkage void vmx_intr_assist(void)
pic_set_irq(pic, 0, 1);
}
if ( !plat->interrupt_request ) {
disable_irq_window(cpu_exec_control);
return;
}
__vmread(VM_ENTRY_INTR_INFO_FIELD, &intr_fields);
if (intr_fields & INTR_INFO_VALID_MASK) {
@@ -928,16 +899,21 @@ asmlinkage void vmx_intr_assist(void)
enable_irq_window(cpu_exec_control);
return;
}
plat->interrupt_request = 0;
highest_vector = cpu_get_pic_interrupt(v, &intr_type);
highest_vector = cpu_get_interrupt(v, &intr_type);
if (highest_vector == -1) {
disable_irq_window(cpu_exec_control);
return;
}
switch (intr_type) {
case VLAPIC_DELIV_MODE_EXT:
case VLAPIC_DELIV_MODE_FIXED:
case VLAPIC_DELIV_MODE_LPRI:
vmx_inject_extint(v, highest_vector, VMX_INVALID_ERROR_CODE);
TRACE_3D(TRC_VMX_INT, v->domain->domain_id, highest_vector, 0);
break;
case VLAPIC_DELIV_MODE_FIXED:
case VLAPIC_DELIV_MODE_LPRI:
case VLAPIC_DELIV_MODE_SMI:
case VLAPIC_DELIV_MODE_NMI:
case VLAPIC_DELIV_MODE_INIT:
+997
View File
@@ -0,0 +1,997 @@
/*
* vmx_vlapic.c: virtualize LAPIC for VMX vcpus.
* Copyright (c) 2004, Intel Corporation.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple
* Place - Suite 330, Boston, MA 02111-1307 USA.
*
*/
#include <xen/config.h>
#include <xen/types.h>
#include <xen/mm.h>
#include <xen/xmalloc.h>
#include <asm/shadow.h>
#include <asm/page.h>
#include <xen/event.h>
#include <xen/trace.h>
#include <asm/vmx.h>
#include <asm/vmx_platform.h>
#include <asm/vmx_vlapic.h>
#include <xen/lib.h>
#include <xen/sched.h>
#include <asm/current.h>
#include <public/io/ioreq.h>
#ifdef CONFIG_VMX
/* XXX remove this definition after GFW enabled */
#define VLAPIC_NO_BIOS
extern unsigned int get_apic_bus_scale(void);
static unsigned int vlapic_lvt_mask[VLAPIC_LVT_NUM] =
{
0x310ff, 0x117ff, 0x117ff, 0x1f7ff, 0x1f7ff, 0x117ff
};
int vlapic_find_highest_irr(struct vlapic *vlapic)
{
int result;
result = find_highest_bit((uint32_t *)&vlapic->irr[0], INTR_LEN_32);
if (result != -1 && result < 16) {
printk("VLAPIC: irr on reserved bits %d\n ", result);
domain_crash_synchronous();
}
return result;
}
inline int vmx_apic_support(struct domain *d)
{
return d->arch.vmx_platform.lapic_enable;
}
int vlapic_find_highest_isr(struct vlapic *vlapic)
{
int result;
result = find_highest_bit((uint32_t *)&vlapic->isr[0], INTR_LEN_32);
if (result != -1 && result < 16) {
int i = 0;
printk("VLAPIC: isr on reserved bits %d, isr is\n ", result);
for (i = 0; i < INTR_LEN_32; i += 2)
printk("%d: 0x%08x%08x\n", i, vlapic->isr[i], vlapic->isr[i+1]);
return -1;
}
return result;
}
uint32_t vlapic_update_ppr(struct vlapic *vlapic)
{
uint32_t tpr, isrv, ppr;
int isr;
tpr = (vlapic->task_priority >> 4) & 0xf; /* we want 7:4 */
isr = vlapic_find_highest_isr(vlapic);
if (isr != -1)
isrv = (isr >> 4) & 0xf; /* ditto */
else
isrv = 0;
if (tpr >= isrv)
ppr = vlapic->task_priority & 0xff;
else
ppr = isrv << 4; /* low 4 bits of PPR have to be cleared */
vlapic->processor_priority = ppr;
VMX_DBG_LOG(DBG_LEVEL_VLAPIC_INTERRUPT,
"vlapic_update_ppr: vlapic %p ppr %x isr %x isrv %x",
vlapic, ppr, isr, isrv);
return ppr;
}
/* This only for fixed delivery mode */
int vlapic_match_dest(struct vlapic *target, struct vlapic *source,
int short_hand, int dest, int dest_mode,
int delivery_mode)
{
int result = 0;
VMX_DBG_LOG(DBG_LEVEL_VLAPIC, "vlapic_match_dest: "
"target %p source %p dest %x dest_mode %x short_hand %x "
"delivery_mode %x",
target, source, dest, dest_mode, short_hand, delivery_mode);
switch (short_hand) {
case VLAPIC_NO_SHORTHAND:
if (!dest_mode) { /* Physical */
result = (target->id == dest);
} else { /* Logical */
if (((target->dest_format >> 28) & 0xf) == 0xf) { /* Flat mode */
result = (target->logical_dest >> 24) & dest;
} else {
if ((delivery_mode == VLAPIC_DELIV_MODE_LPRI) &&
(dest == 0xff)) {
/* What shall we do now? */
printk("Broadcast IPI with lowest priority "
"delivery mode\n");
domain_crash_synchronous();
}
result = (target->logical_dest == (dest & 0xf)) ?
((target->logical_dest >> 4) & (dest >> 4)) : 0;
}
}
break;
case VLAPIC_SHORTHAND_SELF:
if (target == source)
result = 1;
break;
case VLAPIC_SHORTHAND_INCLUDE_SELF:
result = 1;
break;
case VLAPIC_SHORTHAND_EXCLUDE_SELF:
if (target != source)
result = 1;
break;
default:
break;
}
return result;
}
/*
* Add a pending IRQ into lapic.
* Return 1 if successfully added and 0 if discarded.
*/
int vlapic_accept_irq(struct vlapic *vlapic, int delivery_mode,
int vector, int level, int trig_mode)
{
int result = 1;
switch (delivery_mode) {
case VLAPIC_DELIV_MODE_FIXED:
case VLAPIC_DELIV_MODE_LPRI:
/* FIXME add logic for vcpu on reset */
if (!vlapic->vcpu || !vlapic_enabled(vlapic))
return 0;
if (test_and_set_bit(vector, &vlapic->irr[0])) {
printk("<vlapic_accept_irq>"
"level trig mode repeatedly for vector %d\n", vector);
result = 0;
} else {
if (level) {
printk("<vlapic_accept_irq> level trig mode for vector %d\n", vector);
set_bit(vector, &vlapic->tmr[0]);
}
}
evtchn_set_pending(vlapic->vcpu, iopacket_port(vlapic->domain));
break;
case VLAPIC_DELIV_MODE_RESERVED:
printk("Ignore deliver mode 3 in vlapic_accept_irq\n");
break;
case VLAPIC_DELIV_MODE_SMI:
case VLAPIC_DELIV_MODE_NMI:
/* Fixme */
printk("TODO: for guest SMI/NMI\n");
break;
case VLAPIC_DELIV_MODE_INIT:
if (!level && trig_mode == 1) { //Deassert
printk("This vmx_vlapic is for P4, no work for De-assert init\n");
} else {
/* FIXME How to check the situation after vcpu reset? */
vlapic->init_sipi_sipi_state = VLAPIC_INIT_SIPI_SIPI_STATE_WAIT_SIPI;
if (vlapic->vcpu) {
vcpu_pause(vlapic->vcpu);
}
}
break;
case VLAPIC_DELIV_MODE_STARTUP:
if (vlapic->init_sipi_sipi_state != VLAPIC_INIT_SIPI_SIPI_STATE_WAIT_SIPI)
break;
vlapic->init_sipi_sipi_state = VLAPIC_INIT_SIPI_SIPI_STATE_NORM;
if (!vlapic->vcpu) {
/* XXX Call vmx_bringup_ap here */
result = 0;
}else{
//vmx_vcpu_reset(vlapic->vcpu);
}
break;
default:
printk("TODO: not support interrup type %x\n", delivery_mode);
domain_crash_synchronous();
break;
}
return result;
}
/*
This function is used by both ioapic and local APIC
The bitmap is for vcpu_id
*/
struct vlapic* apic_round_robin(struct domain *d,
uint8_t dest_mode,
uint8_t vector,
uint32_t bitmap)
{
int next, old;
struct vlapic* target = NULL;
if (dest_mode == 0) { //Physical mode
printk("<apic_round_robin> lowest priority for physical mode\n");
return NULL;
}
if (!bitmap) {
printk("<apic_round_robin> no bit on bitmap\n");
return NULL;
}
spin_lock(&d->arch.vmx_platform.round_robin_lock);
old = next = d->arch.vmx_platform.round_info[vector];
next++;
if (next == MAX_VIRT_CPUS || !d->vcpu[next])
next = 0;
do {
/* the vcpu array is arranged according to vcpu_id */
if (test_bit(next, &bitmap)) {
target = d->vcpu[next]->arch.arch_vmx.vlapic;
if (!vlapic_enabled(target)) {
printk("warning: targe round robin local apic disabled\n");
/* XXX should we domain crash?? Or should we return NULL */
}
break;
}
next ++;
if (next == MAX_VIRT_CPUS || !d->vcpu[next])
next = 0;
}while(next != old);
d->arch.vmx_platform.round_info[vector] = next;
spin_unlock(&d->arch.vmx_platform.round_robin_lock);
return target;
}
void
vlapic_EOI_set(struct vlapic *vlapic)
{
int vector = vlapic_find_highest_isr(vlapic);
/* Not every write EOI will has correpsoning ISR,
one example is when Kernel check timer on setup_IO_APIC */
if (vector == -1) {
return ;
}
vlapic_clear_isr(vlapic, vector);
vlapic_update_ppr(vlapic);
}
int vlapic_check_vector(struct vlapic *vlapic,
unsigned char dm, int vector)
{
if ((dm == VLAPIC_DELIV_MODE_FIXED) && (vector < 16)) {
vlapic->err_status |= 0x40;
vlapic_accept_irq(vlapic, VLAPIC_DELIV_MODE_FIXED,
vlapic_lvt_vector(vlapic, VLAPIC_LVT_ERROR), 0, 0);
printk("<vlapic_check_vector>: check fail\n");
return 0;
}
return 1;
}
void vlapic_ipi(struct vlapic *vlapic)
{
unsigned int dest = (vlapic->icr_high >> 24) & 0xff;
unsigned int short_hand = (vlapic->icr_low >> 18) & 3;
unsigned int trig_mode = (vlapic->icr_low >> 15) & 1;
unsigned int level = (vlapic->icr_low >> 14) & 1;
unsigned int dest_mode = (vlapic->icr_low >> 11) & 1;
unsigned int delivery_mode = (vlapic->icr_low >> 8) & 7;
unsigned int vector = (vlapic->icr_low & 0xff);
struct vlapic *target;
struct vcpu *v = NULL;
int result = 0;
uint32_t lpr_map;
VMX_DBG_LOG(DBG_LEVEL_VLAPIC, "vlapic_ipi: "
"icr_high %x icr_low %x "
"short_hand %x dest %x trig_mode %x level %x "
"dest_mode %x delivery_mode %x vector %x",
vlapic->icr_high, vlapic->icr_low,
short_hand, dest, trig_mode, level, dest_mode,
delivery_mode, vector);
for_each_vcpu ( vlapic->domain, v ) {
target = VLAPIC(v);
if (vlapic_match_dest(target, vlapic, short_hand,
dest, dest_mode, delivery_mode)) {
if (delivery_mode == VLAPIC_DELIV_MODE_LPRI) {
set_bit(v->vcpu_id, &lpr_map);
}else
result = vlapic_accept_irq(target, delivery_mode,
vector, level, trig_mode);
}
}
if (delivery_mode == VLAPIC_DELIV_MODE_LPRI) {
extern struct vlapic*
apic_round_robin(struct domain *d,
uint8_t dest_mode, uint8_t vector, uint32_t bitmap);
v = vlapic->vcpu;
target = apic_round_robin(v->domain, dest_mode, vector, lpr_map);
if (target)
vlapic_accept_irq(target, delivery_mode,
vector, level, trig_mode);
}
}
void vlapic_begin_timer(struct vlapic *vlapic)
{
s_time_t cur = NOW(), offset;
offset = vlapic->timer_current *
(262144 / get_apic_bus_scale()) * vlapic->timer_divide_counter;
vlapic->vlapic_timer.expires = cur + offset;
set_ac_timer(&(vlapic->vlapic_timer), vlapic->vlapic_timer.expires );
VMX_DBG_LOG(DBG_LEVEL_VLAPIC, "vlapic_begin_timer: "
"bus_scale %x now %08x%08x expire %08x%08x "
"offset %08x%08x current %x",
get_apic_bus_scale(), (uint32_t)(cur >> 32), (uint32_t)cur,
(uint32_t)(vlapic->vlapic_timer.expires >> 32),
(uint32_t) vlapic->vlapic_timer.expires,
(uint32_t)(offset >> 32), (uint32_t)offset,
vlapic->timer_current);
}
void vlapic_read_aligned(struct vlapic *vlapic, unsigned int offset,
unsigned int len, unsigned int *result)
{
if (len != 4) {
VMX_DBG_LOG(DBG_LEVEL_VLAPIC,
"local apic read with len=%d (should be 4)", len);
}
*result = 0;
switch (offset) {
case APIC_ID:
*result = (vlapic->id) << 24;
break;
case APIC_LVR:
*result = vlapic->version;
break;
case APIC_TASKPRI:
*result = vlapic->task_priority;
break;
case APIC_ARBPRI:
printk("Access local APIC ARBPRI register which is for P6\n");
break;
case APIC_PROCPRI:
*result = vlapic->processor_priority;
break;
case APIC_EOI: /* EOI is write only */
break;
case APIC_LDR:
*result = vlapic->logical_dest;
break;
case APIC_DFR:
*result = vlapic->dest_format;
break;
case APIC_SPIV:
*result = vlapic->spurious_vec;
break;
case APIC_ISR:
case 0x110:
case 0x120:
case 0x130:
case 0x140:
case 0x150:
case 0x160:
case 0x170:
*result = vlapic->isr[(offset - APIC_ISR) >> 4];
break;
case APIC_TMR:
case 0x190:
case 0x1a0:
case 0x1b0:
case 0x1c0:
case 0x1d0:
case 0x1e0:
case 0x1f0:
*result = vlapic->tmr[(offset - APIC_TMR) >> 4];
break;
case APIC_IRR:
case 0x210:
case 0x220:
case 0x230:
case 0x240:
case 0x250:
case 0x260:
case 0x270:
*result = vlapic->irr[(offset - APIC_IRR) >> 4];
break;
case APIC_ESR:
if (vlapic->err_write_count)
*result = vlapic->err_status;
break;
case APIC_ICR:
*result = vlapic->icr_low;
break;
case APIC_ICR2:
*result = vlapic->icr_high;
break;
case APIC_LVTT: /* LVT Timer Reg */
case APIC_LVTTHMR: /* LVT Thermal Monitor */
case APIC_LVTPC: /* LVT Performance Counter */
case APIC_LVT0: /* LVT LINT0 Reg */
case APIC_LVT1: /* LVT Lint1 Reg */
case APIC_LVTERR: /* LVT Error Reg */
*result = vlapic->lvt[(offset - APIC_LVTT) >> 4];
break;
case APIC_TMICT:
*result = vlapic->timer_initial;
break;
case APIC_TMCCT: //Timer CCR
{
uint32_t counter;
s_time_t passed, cur = NOW();
if (cur <= vlapic->timer_current_update) {
passed = ~0x0LL - vlapic->timer_current_update + cur;
VMX_DBG_LOG(DBG_LEVEL_VLAPIC,"time elapsed");
}else
passed = cur - vlapic->timer_current_update;
counter = (passed * get_apic_bus_scale()) / (262144* vlapic->timer_divide_counter);
if (vlapic->timer_current > counter)
*result = vlapic->timer_current - counter;
else {
if (!vlapic_lvt_timer_period(vlapic))
*result = 0;
//FIXME should we add interrupt here?
else
//*result = counter % vlapic->timer_initial;
*result = vlapic->timer_initial - (counter - vlapic->timer_current);
}
vlapic->timer_current = *result;
vlapic->timer_current_update = NOW();
VMX_DBG_LOG(DBG_LEVEL_VLAPIC_TIMER,
"initial %x timer current %x "
"update %08x%08x cur %08x%08x offset %d",
vlapic->timer_initial, vlapic->timer_current,
(uint32_t)(vlapic->timer_current_update >> 32),
(uint32_t)vlapic->timer_current_update ,
(uint32_t)(cur >> 32), (uint32_t)cur, counter);
}
break;
case APIC_TDCR:
*result = vlapic->timer_divconf;
break;
default:
printk("Read local APIC address %x not implemented\n",offset);
*result = 0;
break;
}
}
unsigned long vlapic_read(struct vcpu *v, unsigned long address,
unsigned long len)
{
unsigned int alignment;
unsigned int tmp;
unsigned long result;
struct vlapic *vlapic = VLAPIC(v);
unsigned int offset = address - vlapic->base_address;
if ( len != 4) {
/* some bugs on kernel cause read this with byte*/
printk("Local APIC read with len = %lx, should be 4 instead\n", len);
}
alignment = offset & 0x3;
vlapic_read_aligned(vlapic, offset & ~0x3, 4, &tmp);
switch (len) {
case 1:
result = *((unsigned char *)&tmp + alignment);
break;
case 2:
result = *(unsigned short *)((unsigned char *)&tmp + alignment);
break;
case 4:
result = *(unsigned int *)((unsigned char *)&tmp + alignment);
break;
default:
printk("Local APIC read with len = %lx, should be 4 instead\n", len);
domain_crash_synchronous();
break;
}
VMX_DBG_LOG(DBG_LEVEL_VLAPIC,
"vlapic_read offset %x with length %lx and the result is %lx",
offset, len, result);
return result;
}
unsigned long vlapic_write(struct vcpu *v, unsigned long address,
unsigned long len, unsigned long val)
{
struct vlapic *vlapic = VLAPIC(v);
unsigned int offset = address - vlapic->base_address;
if (offset != 0xb0)
VMX_DBG_LOG(DBG_LEVEL_VLAPIC,
"vlapic_write offset %x with length %lx source %lx",
offset, len, val);
/*
* According to IA 32 Manual, all resgiters should be accessed with
* 32 bits alignment.
*/
if (len != 4) {
unsigned int tmp;
unsigned char alignment;
/* Some kernel do will access with byte/word alignment*/
printk("Notice: Local APIC write with len = %lx\n",len);
alignment = offset & 0x3;
tmp = vlapic_read(v, offset & (~0x3), 4);
switch (len) {
case 1:
/* XXX the saddr is a tmp variable from caller, so should be ok
But we should still change the following ref to val to
local variable later */
val = (tmp & ~(0xff << alignment)) |
((val & 0xff) << alignment);
break;
case 2:
if (alignment != 0x0 && alignment != 0x2) {
printk("alignment error for vlapic with len == 2\n");
domain_crash_synchronous();
}
val = (tmp & ~(0xffff << alignment)) |
((val & 0xffff) << alignment);
break;
case 3:
/* will it happen? */
printk("vlapic_write with len = 3 !!!\n");
domain_crash_synchronous();
break;
default:
printk("Local APIC write with len = %lx, should be 4 instead\n", len);
domain_crash_synchronous();
break;
}
}
offset &= 0xff0;
switch (offset) {
case APIC_ID: /* Local APIC ID */
vlapic->id = ((val) >> 24) & VAPIC_ID_MASK;
break;
case APIC_TASKPRI:
vlapic->task_priority = val & 0xff;
vlapic_update_ppr(vlapic);
break;
case APIC_EOI:
vlapic_EOI_set(vlapic);
break;
case APIC_LDR:
vlapic->logical_dest = val & VAPIC_LDR_MASK;
break;
case APIC_DFR:
vlapic->dest_format = val ;
break;
case APIC_SPIV:
vlapic->spurious_vec = val & 0x1ff;
if (!(vlapic->spurious_vec & 0x100)) {
int i = 0;
for (i=0; i < VLAPIC_LVT_NUM; i++)
vlapic->lvt[i] |= 0x10000;
vlapic->status |= VLAPIC_SOFTWARE_DISABLE_MASK;
}
else
vlapic->status &= ~VLAPIC_SOFTWARE_DISABLE_MASK;
break;
case APIC_ESR:
vlapic->err_write_count = !vlapic->err_write_count;
if (!vlapic->err_write_count)
vlapic->err_status = 0;
break;
case APIC_ICR:
/* No delay here, so we always clear the pending bit*/
vlapic->icr_low = val & ~(1 << 12);
vlapic_ipi(vlapic);
break;
case APIC_ICR2:
vlapic->icr_high = val & 0xff000000;
break;
case APIC_LVTT: // LVT Timer Reg
case APIC_LVTTHMR: // LVT Thermal Monitor
case APIC_LVTPC: // LVT Performance Counter
case APIC_LVT0: // LVT LINT0 Reg
case APIC_LVT1: // LVT Lint1 Reg
case APIC_LVTERR: // LVT Error Reg
{
int vt = (offset - APIC_LVTT) >> 4;
vlapic->lvt[vt] = val & vlapic_lvt_mask[vt];
if (vlapic->status & VLAPIC_SOFTWARE_DISABLE_MASK)
vlapic->lvt[vt] |= VLAPIC_LVT_BIT_MASK;
/* On hardware, when write vector less than 0x20 will error */
vlapic_check_vector(vlapic, vlapic_lvt_dm(vlapic->lvt[vt]),
vlapic_lvt_vector(vlapic, vt));
if (!vlapic->vcpu_id && (offset == APIC_LVT0)) {
if ((vlapic->lvt[VLAPIC_LVT_LINT0] & VLAPIC_LVT_BIT_DELIMOD)
== 0x700) {
if (!(vlapic->lvt[VLAPIC_LVT_LINT0] & VLAPIC_LVT_BIT_MASK)) {
set_bit(_VLAPIC_BSP_ACCEPT_PIC, &vlapic->status);
}else
clear_bit(_VLAPIC_BSP_ACCEPT_PIC, &vlapic->status);
}
else
clear_bit(_VLAPIC_BSP_ACCEPT_PIC, &vlapic->status);
}
}
break;
case APIC_TMICT:
if (vlapic_timer_active(vlapic))
rem_ac_timer(&(vlapic->vlapic_timer));
vlapic->timer_initial = val;
vlapic->timer_current = val;
vlapic->timer_current_update = NOW();
VMX_DBG_LOG(DBG_LEVEL_VLAPIC,
"timer_init %x timer_current %x timer_current_update %08x%08x",
vlapic->timer_initial, vlapic->timer_current, (uint32_t)(vlapic->timer_current_update>>32), (uint32_t)vlapic->timer_current_update);
vlapic_begin_timer(vlapic);
break;
case APIC_TDCR:
{
//FIXME clean this code
unsigned char tmp1,tmp2;
tmp1 = (val & 0xf);
tmp2 = ((tmp1 & 0x3 )|((tmp1 & 0x8) >>1)) + 1;
vlapic->timer_divide_counter = 0x1<<tmp2;
VMX_DBG_LOG(DBG_LEVEL_VLAPIC_TIMER,
"timer divider is 0x%x",
vlapic->timer_divide_counter);
}
break;
default:
printk("Local APIC Write to read-only register\n");
break;
}
return 1;
}
int vlapic_range(struct vcpu *v, unsigned long addr)
{
struct vlapic *vlapic = VLAPIC(v);
if (vlapic_global_enabled(vlapic) &&
(addr >= vlapic->base_address) &&
(addr <= (vlapic->base_address + VLOCAL_APIC_MEM_LENGTH)))
return 1;
return 0;
}
void vlapic_msr_set(struct vlapic *vlapic, uint64_t value)
{
/* When apic disabled */
if (!vlapic)
return;
if (vlapic->vcpu_id)
value &= ~MSR_IA32_APICBASE_BSP;
vlapic->apic_base_msr = value;
vlapic->base_address = vlapic_get_base_address(vlapic);
if (!(value & 0x800))
set_bit(_VLAPIC_GLOB_DISABLE, &vlapic->status );
VMX_DBG_LOG(DBG_LEVEL_VLAPIC,
"apic base msr = 0x%08x%08x,\nbase address = 0x%lx",
(uint32_t)(vlapic->apic_base_msr >> 32),
(uint32_t)vlapic->apic_base_msr,
vlapic->base_address);
}
static inline int vlapic_get_init_id(struct vcpu *v)
{
return v->vcpu_id;
}
void vlapic_timer_fn(void *data)
{
struct vlapic *vlapic;
vlapic = data;
if (!vlapic_enabled(vlapic)) return;
vlapic->timer_current_update = NOW();
if (vlapic_lvt_timer_enabled(vlapic)) {
if (!vlapic_irr_status(vlapic,
vlapic_lvt_vector(vlapic, VLAPIC_LVT_TIMER))) {
test_and_set_bit(vlapic_lvt_vector(vlapic, VLAPIC_LVT_TIMER),
&vlapic->irr[0]);
}
else
vlapic->intr_pending_count[vlapic_lvt_vector(vlapic, VLAPIC_LVT_TIMER)]++;
}
vlapic->timer_current_update = NOW();
if (vlapic_lvt_timer_period(vlapic)) {
s_time_t offset;
vlapic->timer_current = vlapic->timer_initial;
offset = vlapic->timer_current * (262144/get_apic_bus_scale()) * vlapic->timer_divide_counter;
vlapic->vlapic_timer.expires = NOW() + offset;
set_ac_timer(&(vlapic->vlapic_timer), vlapic->vlapic_timer.expires);
}else {
vlapic->timer_current = 0;
}
VMX_DBG_LOG(DBG_LEVEL_VLAPIC_TIMER,
"vlapic_timer_fn: now: %08x%08x expire %08x%08x init %x current %x",
(uint32_t)(NOW() >> 32),(uint32_t)NOW(),
(uint32_t)(vlapic->vlapic_timer.expires >> 32),
(uint32_t)vlapic->vlapic_timer.expires,
vlapic->timer_initial,vlapic->timer_current);
}
#if 0
static int
vlapic_check_direct_intr(struct vcpu *v, int * mode)
{
struct vlapic *vlapic = VLAPIC(v);
int type;
type = __fls(vlapic->direct_intr.deliver_mode);
if (type == -1)
return -1;
*mode = type;
return 0;
}
#endif
int
vlapic_accept_pic_intr(struct vcpu *v)
{
struct vlapic *vlapic = VLAPIC(v);
return vlapic ? test_bit(_VLAPIC_BSP_ACCEPT_PIC, &vlapic->status) : 1;
}
int cpu_get_apic_interrupt(struct vcpu* v, int *mode)
{
struct vlapic *vlapic = VLAPIC(v);
if (vlapic && vlapic_enabled(vlapic)) {
int highest_irr = vlapic_find_highest_irr(vlapic);
if (highest_irr != -1 && highest_irr >= vlapic->processor_priority) {
if (highest_irr < 0x10) {
vlapic->err_status |= 0x20;
/* XXX What will happen if this vector illegal stil */
VMX_DBG_LOG(DBG_LEVEL_VLAPIC,
"vmx_intr_assist: illegal vector number %x err_status %x",
highest_irr, vlapic_lvt_vector(vlapic, VLAPIC_LVT_ERROR));
set_bit(vlapic_lvt_vector(vlapic, VLAPIC_LVT_ERROR), &vlapic->irr[0]);
highest_irr = vlapic_lvt_vector(vlapic, VLAPIC_LVT_ERROR);
}
*mode = VLAPIC_DELIV_MODE_FIXED;
return highest_irr;
}
}
return -1;
}
void vlapic_post_injection(struct vcpu *v, int vector, int deliver_mode) {
struct vlapic *vlapic = VLAPIC(v);
if (!vlapic)
return;
switch (deliver_mode) {
case VLAPIC_DELIV_MODE_FIXED:
case VLAPIC_DELIV_MODE_LPRI:
vlapic_set_isr(vlapic, vector);
vlapic_clear_irr(vlapic, vector);
vlapic_update_ppr(vlapic);
if (vector == vlapic_lvt_vector(vlapic, VLAPIC_LVT_TIMER)) {
vlapic->intr_pending_count[vector]--;
if (vlapic->intr_pending_count[vector] > 0)
test_and_set_bit(vlapic_lvt_vector(vlapic, VLAPIC_LVT_TIMER),
&vlapic->irr[0]);
}
break;
/*XXX deal with these later */
case VLAPIC_DELIV_MODE_RESERVED:
printk("Ignore deliver mode 3 in vlapic_post_injection\n");
break;
case VLAPIC_DELIV_MODE_SMI:
case VLAPIC_DELIV_MODE_NMI:
case VLAPIC_DELIV_MODE_INIT:
case VLAPIC_DELIV_MODE_STARTUP:
vlapic->direct_intr.deliver_mode &= ~(1 << deliver_mode);
break;
default:
printk("<vlapic_post_injection> error deliver mode\n");
break;
}
}
static int vlapic_reset(struct vlapic *vlapic)
{
struct vcpu *v = vlapic->vcpu;
int apic_id = v->vcpu_id, i;
if (!v || !vlapic)
return 0;
memset(vlapic, 0,sizeof(struct vlapic));
v->arch.arch_vmx.vlapic = vlapic;
vlapic->domain = v->domain;
vlapic->id = apic_id;
vlapic->version = VLAPIC_VERSION;
vlapic->apic_base_msr = VLAPIC_BASE_MSR_INIT_VALUE;
if (apic_id == 0)
vlapic->apic_base_msr |= MSR_IA32_APICBASE_BSP;
vlapic->base_address = vlapic_get_base_address(vlapic);
for (i = 0; i < VLAPIC_LVT_NUM; i++)
vlapic->lvt[i] = VLAPIC_LVT_BIT_MASK;
vlapic->dest_format = 0xffffffffU;
vlapic->spurious_vec = 0xff;
init_ac_timer(&vlapic->vlapic_timer,
vlapic_timer_fn, vlapic, v->processor);
#ifdef VLAPIC_NO_BIOS
/*
* XXX According to mp sepcific, BIOS will enable LVT0/1,
* remove it after BIOS enabled
*/
if (!v->vcpu_id) {
vlapic->lvt[VLAPIC_LVT_LINT0] = 0x700;
vlapic->lvt[VLAPIC_LVT_LINT1] = 0x500;
set_bit(_VLAPIC_BSP_ACCEPT_PIC, &vlapic->status);
}
#endif
VMX_DBG_LOG(DBG_LEVEL_VLAPIC, "vlapic_reset: "
"vcpu=%p id=%d vlapic_apic_base_msr=%08x%08x "
"vlapic_base_address=%0lx",
v, vlapic->id, (uint32_t)(vlapic->apic_base_msr >> 32),
(uint32_t)vlapic->apic_base_msr, vlapic->base_address);
return 1;
}
int vlapic_init(struct vcpu *v)
{
struct vlapic *vlapic = NULL;
VMX_DBG_LOG(DBG_LEVEL_VLAPIC, "vlapic_init %d", v->vcpu_id);
vlapic = xmalloc_bytes(sizeof(struct vlapic));
if (!vlapic) {
printk("malloc vlapic error for vcpu %x\n", v->vcpu_id);
return -ENOMEM;
}
vlapic->vcpu = v;
vlapic_reset(vlapic);
return 0;
}
#endif /* CONFIG_VMX */
+7
View File
@@ -252,6 +252,10 @@ static void vmx_setup_platform(struct domain* d)
pic_init(&platform->vmx_pic, pic_irq_request,
&platform->interrupt_request);
register_pic_io_hook();
if ( vmx_apic_support(d) ) {
spin_lock_init(&d->arch.vmx_platform.round_robin_lock);
}
}
static void vmx_set_host_env(struct vcpu *v)
@@ -313,6 +317,9 @@ static void vmx_do_launch(struct vcpu *v)
vmx_stts();
if(vmx_apic_support(v->domain))
vlapic_init(v);
vmx_set_host_env(v);
error |= __vmwrite(GUEST_LDTR_SELECTOR, 0);
+12 -1
View File
@@ -133,7 +133,10 @@ long do_acm_op(struct acm_op * u_acm_op)
struct domain *subj = find_domain_by_id(op->u.getssid.id.domainid);
if (!subj)
return -ESRCH; /* domain not found */
if (subj->ssid == NULL) {
put_domain(subj);
return -ESRCH;
}
ssidref = ((struct acm_ssid_domain *)(subj->ssid))->ssidref;
put_domain(subj);
} else
@@ -167,6 +170,10 @@ long do_acm_op(struct acm_op * u_acm_op)
ret = -ESRCH; /* domain not found */
goto out;
}
if (subj->ssid == NULL) {
put_domain(subj);
ret = -ESRCH;
}
ssidref1 = ((struct acm_ssid_domain *)(subj->ssid))->ssidref;
put_domain(subj);
} else {
@@ -182,6 +189,10 @@ long do_acm_op(struct acm_op * u_acm_op)
ret = -ESRCH; /* domain not found */
goto out;
}
if (subj->ssid == NULL) {
put_domain(subj);
return -ESRCH;
}
ssidref2 = ((struct acm_ssid_domain *)(subj->ssid))->ssidref;
put_domain(subj);
} else {
+4 -2
View File
@@ -514,7 +514,7 @@ static void dom_timer_fn(void *data)
/* Initialise the data structures. */
void __init scheduler_init(void)
{
int i;
int i, rc;
open_softirq(SCHEDULE_SOFTIRQ, __enter_scheduler);
@@ -540,7 +540,9 @@ void __init scheduler_init(void)
printk("Using scheduler: %s (%s)\n", ops.name, ops.opt_name);
BUG_ON(SCHED_OP(alloc_task, idle_task[0]) < 0);
rc = SCHED_OP(alloc_task, idle_task[0]);
BUG_ON(rc < 0);
sched_add_domain(idle_task[0]);
}
+32 -18
View File
@@ -100,10 +100,10 @@ struct acm_operations {
void (*fail_domain_create) (void *subject_ssid, ssidref_t ssidref);
void (*post_domain_destroy) (void *object_ssid, domid_t id);
/* event channel control hooks (can be NULL) */
int (*pre_eventchannel_unbound) (domid_t id);
void (*fail_eventchannel_unbound) (domid_t id);
int (*pre_eventchannel_interdomain) (domid_t id1, domid_t id2);
int (*fail_eventchannel_interdomain) (domid_t id1, domid_t id2);
int (*pre_eventchannel_unbound) (domid_t id1, domid_t id2);
void (*fail_eventchannel_unbound) (domid_t id1, domid_t id2);
int (*pre_eventchannel_interdomain) (domid_t id);
void (*fail_eventchannel_interdomain) (domid_t id);
/* grant table control hooks (can be NULL) */
int (*pre_grant_map_ref) (domid_t id);
void (*fail_grant_map_ref) (domid_t id);
@@ -193,31 +193,31 @@ static inline void acm_post_domain_destroy(void *object_ssid, domid_t id)
return;
}
static inline int acm_pre_eventchannel_unbound(domid_t id)
static inline int acm_pre_eventchannel_unbound(domid_t id1, domid_t id2)
{
if ((acm_primary_ops->pre_eventchannel_unbound != NULL) &&
acm_primary_ops->pre_eventchannel_unbound(id))
acm_primary_ops->pre_eventchannel_unbound(id1, id2))
return ACM_ACCESS_DENIED;
else if ((acm_secondary_ops->pre_eventchannel_unbound != NULL) &&
acm_secondary_ops->pre_eventchannel_unbound(id)) {
acm_secondary_ops->pre_eventchannel_unbound(id1, id2)) {
/* roll-back primary */
if (acm_primary_ops->fail_eventchannel_unbound != NULL)
acm_primary_ops->fail_eventchannel_unbound(id);
acm_primary_ops->fail_eventchannel_unbound(id1, id2);
return ACM_ACCESS_DENIED;
} else
return ACM_ACCESS_PERMITTED;
}
static inline int acm_pre_eventchannel_interdomain(domid_t id1, domid_t id2)
static inline int acm_pre_eventchannel_interdomain(domid_t id)
{
if ((acm_primary_ops->pre_eventchannel_interdomain != NULL) &&
acm_primary_ops->pre_eventchannel_interdomain(id1, id2))
acm_primary_ops->pre_eventchannel_interdomain(id))
return ACM_ACCESS_DENIED;
else if ((acm_secondary_ops->pre_eventchannel_interdomain != NULL) &&
acm_secondary_ops->pre_eventchannel_interdomain(id1, id2)) {
acm_secondary_ops->pre_eventchannel_interdomain(id)) {
/* roll-back primary */
if (acm_primary_ops->fail_eventchannel_interdomain != NULL)
acm_primary_ops->fail_eventchannel_interdomain(id1, id2);
acm_primary_ops->fail_eventchannel_interdomain(id);
return ACM_ACCESS_DENIED;
} else
return ACM_ACCESS_PERMITTED;
@@ -234,10 +234,22 @@ static inline int acm_pre_dom0_op(dom0_op_t *op, void **ssid)
current->domain->ssid, op->u.createdomain.ssidref);
break;
case DOM0_DESTROYDOMAIN:
if (*ssid != NULL) {
printkd("%s: Warning. Overlapping destruction.\n",
__func__);
return -EACCES;
}
d = find_domain_by_id(op->u.destroydomain.domain);
if (d != NULL) {
*ssid = d->ssid; /* save for post destroy when d is gone */
/* no policy-specific hook */
if (*ssid == NULL) {
printk("%s: Warning. Destroying domain without ssid pointer.\n",
__func__);
put_domain(d);
return -EACCES;
}
d->ssid = NULL; /* make sure it's not used any more */
/* no policy-specific hook */
put_domain(d);
ret = 0;
}
@@ -248,7 +260,7 @@ static inline int acm_pre_dom0_op(dom0_op_t *op, void **ssid)
return ret;
}
static inline void acm_post_dom0_op(dom0_op_t *op, void *ssid)
static inline void acm_post_dom0_op(dom0_op_t *op, void **ssid)
{
switch(op->cmd) {
case DOM0_CREATEDOMAIN:
@@ -261,7 +273,8 @@ static inline void acm_post_dom0_op(dom0_op_t *op, void *ssid)
case DOM0_DESTROYDOMAIN:
acm_post_domain_destroy(ssid, op->u.destroydomain.domain);
/* free security ssid for the destroyed domain (also if null policy */
acm_free_domain_ssid((struct acm_ssid_domain *)ssid);
acm_free_domain_ssid((struct acm_ssid_domain *)(*ssid));
*ssid = NULL;
break;
}
}
@@ -282,12 +295,13 @@ static inline int acm_pre_event_channel(evtchn_op_t *op)
switch(op->cmd) {
case EVTCHNOP_alloc_unbound:
ret = acm_pre_eventchannel_unbound(op->u.alloc_unbound.dom);
ret = acm_pre_eventchannel_unbound(
op->u.alloc_unbound.dom,
op->u.alloc_unbound.remote_dom);
break;
case EVTCHNOP_bind_interdomain:
ret = acm_pre_eventchannel_interdomain(
current->domain->domain_id,
op->u.bind_interdomain.remote_dom);
op->u.bind_interdomain.remote_dom);
break;
default:
ret = 0; /* ok */
+21 -11
View File
@@ -14,6 +14,16 @@
#define VMX_MMIO 1
typedef int (*intercept_action_t)(ioreq_t *);
typedef unsigned long (*vmx_mmio_read_t)(struct vcpu *v,
unsigned long addr,
unsigned long length);
typedef unsigned long (*vmx_mmio_write_t)(struct vcpu *v,
unsigned long addr,
unsigned long length,
unsigned long val);
typedef int (*vmx_mmio_check_t)(struct vcpu *v, unsigned long addr);
struct io_handler {
int type;
@@ -27,6 +37,16 @@ struct vmx_io_handler {
struct io_handler hdl_list[MAX_IO_HANDLER];
};
struct vmx_mmio_handler {
vmx_mmio_check_t check_handler;
vmx_mmio_read_t read_handler;
vmx_mmio_write_t write_handler;
};
#define VMX_MMIO_HANDLER_NR 1
extern struct vmx_mmio_handler vmx_mmio_handers[VMX_MMIO_HANDLER_NR];
/* global io interception point in HV */
extern int vmx_io_intercept(ioreq_t *p, int type);
extern int register_io_handler(unsigned long addr, unsigned long size,
@@ -37,10 +57,7 @@ static inline int vmx_portio_intercept(ioreq_t *p)
return vmx_io_intercept(p, VMX_PORTIO);
}
static inline int vmx_mmio_intercept(ioreq_t *p)
{
return vmx_io_intercept(p, VMX_MMIO);
}
int vmx_mmio_intercept(ioreq_t *p);
static inline int register_portio_handler(unsigned long addr,
unsigned long size,
@@ -49,11 +66,4 @@ static inline int register_portio_handler(unsigned long addr,
return register_io_handler(addr, size, action, VMX_PORTIO);
}
static inline int register_mmio_handler(unsigned long addr,
unsigned long size,
intercept_action_t action)
{
return register_io_handler(addr, size, action, VMX_MMIO);
}
#endif /* _VMX_INTERCEPT_H */
+3
View File
@@ -80,10 +80,13 @@ struct instruction {
struct vmx_platform {
unsigned long shared_page_va;
unsigned int nr_vcpu;
unsigned int lapic_enable;
struct vmx_virpit vmx_pit;
struct vmx_io_handler vmx_io_handler;
struct vmx_virpic vmx_pic;
unsigned char round_info[256];
spinlock_t round_robin_lock;
int interrupt_request;
};
+245
View File
@@ -0,0 +1,245 @@
/*
* vmx_vlapic.h: virtualize LAPIC definitions.
* Copyright (c) 2004, Intel Corporation.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple
* Place - Suite 330, Boston, MA 02111-1307 USA.
*
*/
#ifndef VMX_VLAPIC_H
#define VMX_VLAPIC_H
#include <asm/msr.h>
#include <public/io/ioreq.h>
#if defined(__i386__) || defined(__x86_64__)
static inline int __fls(uint32_t word)
{
int bit;
__asm__("bsrl %1,%0"
:"=r" (bit)
:"rm" (word));
return word ? bit : -1;
}
#else
#define __fls(x) generic_fls(x)
static __inline__ int generic_fls(uint32_t x)
{
int r = 31;
if (!x)
return -1;
if (!(x & 0xffff0000u)) {
x <<= 16;
r -= 16;
}
if (!(x & 0xff000000u)) {
x <<= 8;
r -= 8;
}
if (!(x & 0xf0000000u)) {
x <<= 4;
r -= 4;
}
if (!(x & 0xc0000000u)) {
x <<= 2;
r -= 2;
}
if (!(x & 0x80000000u)) {
x <<= 1;
r -= 1;
}
return r;
}
#endif
static __inline__ int find_highest_bit(uint32_t *data, int length)
{
while(length && !data[--length]);
return __fls(data[length]) + 32 * length;
}
#define VLAPIC(v) (v->arch.arch_vmx.vlapic)
#define VAPIC_ID_MASK 0xff
#define VAPIC_LDR_MASK (VAPIC_ID_MASK << 24)
#define VLAPIC_VERSION 0x00050014
#define VLAPIC_BASE_MSR_MASK 0x00000000fffff900ULL
#define VLAPIC_BASE_MSR_INIT_BASE_ADDR 0xfee00000U
#define VLAPIC_BASE_MSR_BASE_ADDR_MASK 0xfffff000U
#define VLAPIC_BASE_MSR_INIT_VALUE (VLAPIC_BASE_MSR_INIT_BASE_ADDR | \
MSR_IA32_APICBASE_ENABLE)
#define VLOCAL_APIC_MEM_LENGTH (1 << 12)
#define VLAPIC_LVT_TIMER 0
#define VLAPIC_LVT_THERMAL 1
#define VLAPIC_LVT_PERFORM 2
#define VLAPIC_LVT_LINT0 3
#define VLAPIC_LVT_LINT1 4
#define VLAPIC_LVT_ERROR 5
#define VLAPIC_LVT_NUM 6
#define VLAPIC_LVT_BIT_MASK (1 << 16)
#define VLAPIC_LVT_BIT_VECTOR 0xff
#define VLAPIC_LVT_BIT_DELIMOD (0x7 << 8)
#define VLAPIC_LVT_BIT_DELISTATUS (1 << 12)
#define VLAPIC_LVT_BIT_POLARITY (1 << 13)
#define VLAPIC_LVT_BIT_IRR (1 << 14)
#define VLAPIC_LVT_BIT_TRIG (1 << 15)
#define VLAPIC_LVT_TIMERMODE (1 << 17)
#define VLAPIC_DELIV_MODE_FIXED 0x0
#define VLAPIC_DELIV_MODE_LPRI 0x1
#define VLAPIC_DELIV_MODE_SMI 0x2
#define VLAPIC_DELIV_MODE_RESERVED 0x3
#define VLAPIC_DELIV_MODE_NMI 0x4
#define VLAPIC_DELIV_MODE_INIT 0x5
#define VLAPIC_DELIV_MODE_STARTUP 0x6
#define VLAPIC_DELIV_MODE_EXT 0x7
#define VLAPIC_NO_SHORTHAND 0x0
#define VLAPIC_SHORTHAND_SELF 0x1
#define VLAPIC_SHORTHAND_INCLUDE_SELF 0x2
#define VLAPIC_SHORTHAND_EXCLUDE_SELF 0x3
#define vlapic_lvt_timer_enabled(vlapic) \
(!(vlapic->lvt[VLAPIC_LVT_TIMER] & VLAPIC_LVT_BIT_MASK))
#define vlapic_lvt_vector(vlapic, type) \
(vlapic->lvt[type] & VLAPIC_LVT_BIT_VECTOR)
#define vlapic_lvt_dm(value) ((value >> 8) && 7)
#define vlapic_lvt_timer_period(vlapic) \
(vlapic->lvt[VLAPIC_LVT_TIMER] & VLAPIC_LVT_TIMERMODE)
#define vlapic_isr_status(vlapic,vector) \
test_bit(vector, &vlapic->isr[0])
#define vlapic_irr_status(vlapic,vector) \
test_bit(vector, &vlapic->irr[0])
#define vlapic_set_isr(vlapic,vector) \
test_and_set_bit(vector, &vlapic->isr[0])
#define vlapic_set_irr(vlapic,vector) \
test_and_set_bit(vector, &vlapic->irr[0])
#define vlapic_clear_irr(vlapic,vector) \
clear_bit(vector, &vlapic->irr[0])
#define vlapic_clear_isr(vlapic,vector) \
clear_bit(vector, &vlapic->isr[0])
#define vlapic_enabled(vlapic) \
(!(vlapic->status & \
(VLAPIC_GLOB_DISABLE_MASK | VLAPIC_SOFTWARE_DISABLE_MASK)))
#define vlapic_global_enabled(vlapic) \
!(test_bit(_VLAPIC_GLOB_DISABLE, &(vlapic)->status))
typedef struct direct_intr_info {
int deliver_mode;
int source[6];
} direct_intr_info_t;
#define VLAPIC_INIT_SIPI_SIPI_STATE_NORM 0
#define VLAPIC_INIT_SIPI_SIPI_STATE_WAIT_SIPI 1
struct vlapic
{
//FIXME check what would be 64 bit on EM64T
uint32_t version;
#define _VLAPIC_GLOB_DISABLE 0x0
#define VLAPIC_GLOB_DISABLE_MASK 0x1
#define VLAPIC_SOFTWARE_DISABLE_MASK 0x2
#define _VLAPIC_BSP_ACCEPT_PIC 0x3
uint32_t status;
uint32_t id;
uint32_t vcpu_id;
unsigned long base_address;
uint32_t isr[8];
uint32_t irr[INTR_LEN_32];
uint32_t tmr[INTR_LEN_32];
uint32_t task_priority;
uint32_t processor_priority;
uint32_t logical_dest;
uint32_t dest_format;
uint32_t spurious_vec;
uint32_t lvt[6];
uint32_t timer_initial;
uint32_t timer_current;
uint32_t timer_divconf;
uint32_t timer_divide_counter;
struct ac_timer vlapic_timer;
int intr_pending_count[MAX_VECTOR];
s_time_t timer_current_update;
uint32_t icr_high;
uint32_t icr_low;
direct_intr_info_t direct_intr;
uint32_t err_status;
unsigned long init_ticks;
uint32_t err_write_count;
uint64_t apic_base_msr;
uint32_t init_sipi_sipi_state;
struct vcpu *vcpu;
struct domain *domain;
};
static inline int vlapic_timer_active(struct vlapic *vlapic)
{
return active_ac_timer(&(vlapic->vlapic_timer));
}
int vlapic_find_highest_irr(struct vlapic *vlapic);
int vlapic_find_highest_isr(struct vlapic *vlapic);
static uint32_t inline vlapic_get_base_address(struct vlapic *vlapic)
{
return (vlapic->apic_base_msr & VLAPIC_BASE_MSR_BASE_ADDR_MASK);
}
void vlapic_post_injection(struct vcpu* v, int vector, int deliver_mode);
int cpu_get_apic_interrupt(struct vcpu* v, int *mode);
extern uint32_t vlapic_update_ppr(struct vlapic *vlapic);
int vlapic_update(struct vcpu *v);
extern int vlapic_init(struct vcpu *vc);
extern void vlapic_msr_set(struct vlapic *vlapic, uint64_t value);
int vlapic_range(struct vcpu *v, unsigned long addr);
unsigned long vlapic_write(struct vcpu *v, unsigned long address,
unsigned long len, unsigned long val);
unsigned long vlapic_read(struct vcpu *v, unsigned long address,
unsigned long len);
int vlapic_accept_pic_intr(struct vcpu *v);
struct vlapic* apic_round_robin(struct domain *d,
uint8_t dest_mode,
uint8_t vector,
uint32_t bitmap);
int vmx_apic_support(struct domain *d);
#endif /* VMX_VLAPIC_H */
+12 -7
View File
@@ -22,6 +22,7 @@
#include <asm/config.h>
#include <asm/vmx_cpu.h>
#include <asm/vmx_platform.h>
#include <asm/vmx_vlapic.h>
#include <public/vmx_assist.h>
extern int start_vmx(void);
@@ -96,6 +97,7 @@ struct arch_vmx_struct {
struct msr_state msr_content;
struct mmio_op mmio_op; /* MMIO */
void *io_bitmap_a, *io_bitmap_b;
struct vlapic *vlapic;
u64 tsc_offset;
};
@@ -272,18 +274,21 @@ enum vmcs_field {
#define VMX_DEBUG 1
#if VMX_DEBUG
#define DBG_LEVEL_0 (1 << 0)
#define DBG_LEVEL_1 (1 << 1)
#define DBG_LEVEL_2 (1 << 2)
#define DBG_LEVEL_3 (1 << 3)
#define DBG_LEVEL_IO (1 << 4)
#define DBG_LEVEL_VMMU (1 << 5)
#define DBG_LEVEL_0 (1 << 0)
#define DBG_LEVEL_1 (1 << 1)
#define DBG_LEVEL_2 (1 << 2)
#define DBG_LEVEL_3 (1 << 3)
#define DBG_LEVEL_IO (1 << 4)
#define DBG_LEVEL_VMMU (1 << 5)
#define DBG_LEVEL_VLAPIC (1 << 6)
#define DBG_LEVEL_VLAPIC_TIMER (1 << 7)
#define DBG_LEVEL_VLAPIC_INTERRUPT (1 << 7)
extern unsigned int opt_vmx_debug_level;
#define VMX_DBG_LOG(level, _f, _a...) \
if ((level) & opt_vmx_debug_level) \
printk("[VMX:%d.%d] " _f "\n", \
current->domain->domain_id, current->vcpu_id, ## _a)
current->domain->domain_id, current->vcpu_id, ## _a)
#else
#define VMX_DBG_LOG(level, _f, _a...)
#endif
+7 -6
View File
@@ -29,11 +29,11 @@
#define STATE_IORESP_READY 3
#define STATE_IORESP_HOOK 4
#define IOREQ_TYPE_PIO 0 /* pio */
#define IOREQ_TYPE_COPY 1 /* mmio ops */
#define IOREQ_TYPE_AND 2
#define IOREQ_TYPE_OR 3
#define IOREQ_TYPE_XOR 4
#define IOREQ_TYPE_PIO 0 /* pio */
#define IOREQ_TYPE_COPY 1 /* mmio ops */
#define IOREQ_TYPE_AND 2
#define IOREQ_TYPE_OR 3
#define IOREQ_TYPE_XOR 4
/*
* VMExit dispatcher should cooperate with instruction decoder to
@@ -55,9 +55,10 @@ typedef struct {
uint8_t type; /* I/O type */
} ioreq_t;
#define MAX_VECTOR 256
#define MAX_VECTOR 256
#define BITS_PER_BYTE 8
#define INTR_LEN (MAX_VECTOR/(BITS_PER_BYTE * sizeof(uint64_t)))
#define INTR_LEN_32 (MAX_VECTOR/(BITS_PER_BYTE * sizeof(uint32_t)))
typedef struct {
uint16_t pic_elcr;
+1 -1
View File
@@ -76,7 +76,7 @@ void pic_update_irq(struct vmx_virpic *s);
uint32_t pic_intack_read(struct vmx_virpic *s);
void register_pic_io_hook (void);
int cpu_get_pic_interrupt(struct vcpu *v, int *type);
int is_pit_irq(struct vcpu *v, int irq);
int is_pit_irq(struct vcpu *v, int irq, int type);
void do_pic_irqs (struct vmx_virpic *s, uint16_t irqs);
void do_pic_irqs_clear (struct vmx_virpic *s, uint16_t irqs);
+1
View File
@@ -410,6 +410,7 @@ typedef struct shared_info {
#define MAX_GUEST_CMDLINE 1024
typedef struct start_info {
/* THE FOLLOWING ARE FILLED IN BOTH ON INITIAL BOOT AND ON RESUME. */
char magic[32]; /* "Xen-<version>.<subversion>". */
unsigned long nr_pages; /* Total pages allocated to this domain. */
unsigned long shared_info; /* MACHINE address of shared info struct. */
uint32_t flags; /* SIF_xxx flags. */
-1
View File
@@ -101,7 +101,6 @@ struct domain
struct list_head xenpage_list; /* linked list, of size xenheap_pages */
unsigned int tot_pages; /* number of pages currently possesed */
unsigned int max_pages; /* maximum value for tot_pages */
unsigned int next_io_page; /* next io pfn to give to domain */
unsigned int xenheap_pages; /* # pages allocated from Xen heap */
/* Scheduling. */
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.