This commit is contained in:
parent
241ee9df04
commit
d7002a96b9
147
32on64-acmop.patch
Normal file
147
32on64-acmop.patch
Normal file
@ -0,0 +1,147 @@
|
||||
Enable compatibility mode operation for HYPERVISOR_acm_op.
|
||||
|
||||
Index: 2007-01-08/xen/arch/x86/x86_64/compat/entry.S
|
||||
===================================================================
|
||||
--- 2007-01-08.orig/xen/arch/x86/x86_64/compat/entry.S 2007-01-08 15:20:00.000000000 +0100
|
||||
+++ 2007-01-08/xen/arch/x86/x86_64/compat/entry.S 2007-01-08 15:20:01.000000000 +0100
|
||||
@@ -278,7 +278,6 @@ CFIX14:
|
||||
|
||||
.section .rodata, "a", @progbits
|
||||
|
||||
-#define compat_acm_op domain_crash_synchronous
|
||||
#define compat_xenoprof_op domain_crash_synchronous
|
||||
#define compat_sysctl domain_crash_synchronous
|
||||
#define compat_domctl domain_crash_synchronous
|
||||
Index: 2007-01-08/xen/common/Makefile
|
||||
===================================================================
|
||||
--- 2007-01-08.orig/xen/common/Makefile 2007-01-08 15:19:22.000000000 +0100
|
||||
+++ 2007-01-08/xen/common/Makefile 2007-01-08 15:20:01.000000000 +0100
|
||||
@@ -42,6 +42,7 @@ version.o: $(BASEDIR)/include/xen/compil
|
||||
|
||||
ifeq ($(CONFIG_COMPAT),y)
|
||||
# extra dependencies
|
||||
+acm_ops.o: compat/acm_ops.c
|
||||
grant_table.o: compat/grant_table.c
|
||||
schedule.o: compat/schedule.c
|
||||
endif
|
||||
Index: 2007-01-08/xen/common/acm_ops.c
|
||||
===================================================================
|
||||
--- 2007-01-08.orig/xen/common/acm_ops.c 2007-01-08 15:04:23.000000000 +0100
|
||||
+++ 2007-01-08/xen/common/acm_ops.c 2007-01-08 15:20:01.000000000 +0100
|
||||
@@ -15,6 +15,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
+#ifndef COMPAT
|
||||
#include <xen/config.h>
|
||||
#include <xen/types.h>
|
||||
#include <xen/lib.h>
|
||||
@@ -28,6 +29,10 @@
|
||||
#include <xen/guest_access.h>
|
||||
#include <acm/acm_hooks.h>
|
||||
|
||||
+typedef long ret_t;
|
||||
+
|
||||
+#endif /* !COMPAT */
|
||||
+
|
||||
#ifndef ACM_SECURITY
|
||||
|
||||
|
||||
@@ -40,6 +45,7 @@ long do_acm_op(int cmd, XEN_GUEST_HANDLE
|
||||
#else
|
||||
|
||||
|
||||
+#ifndef COMPAT
|
||||
int acm_authorize_acm_ops(struct domain *d)
|
||||
{
|
||||
/* currently, policy management functions are restricted to privileged domains */
|
||||
@@ -47,11 +53,12 @@ int acm_authorize_acm_ops(struct domain
|
||||
return -EPERM;
|
||||
return 0;
|
||||
}
|
||||
+#endif
|
||||
|
||||
|
||||
-long do_acm_op(int cmd, XEN_GUEST_HANDLE(void) arg)
|
||||
+ret_t do_acm_op(int cmd, XEN_GUEST_HANDLE(void) arg)
|
||||
{
|
||||
- long rc = -EFAULT;
|
||||
+ ret_t rc = -EFAULT;
|
||||
|
||||
if (acm_authorize_acm_ops(current->domain))
|
||||
return -EPERM;
|
||||
@@ -219,6 +226,10 @@ long do_acm_op(int cmd, XEN_GUEST_HANDLE
|
||||
|
||||
#endif
|
||||
|
||||
+#if defined(CONFIG_COMPAT) && !defined(COMPAT)
|
||||
+#include "compat/acm_ops.c"
|
||||
+#endif
|
||||
+
|
||||
/*
|
||||
* Local variables:
|
||||
* mode: C
|
||||
Index: 2007-01-08/xen/common/compat/acm_ops.c
|
||||
===================================================================
|
||||
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
|
||||
+++ 2007-01-08/xen/common/compat/acm_ops.c 2007-01-08 15:20:01.000000000 +0100
|
||||
@@ -0,0 +1,47 @@
|
||||
+/******************************************************************************
|
||||
+ * compat/acm_ops.c
|
||||
+ */
|
||||
+
|
||||
+#include <compat/acm.h>
|
||||
+#include <compat/acm_ops.h>
|
||||
+
|
||||
+#define COMPAT
|
||||
+#define ret_t int
|
||||
+
|
||||
+#define do_acm_op compat_acm_op
|
||||
+
|
||||
+static inline XEN_GUEST_HANDLE(void) acm_xlat_handle(COMPAT_HANDLE(void) cmp)
|
||||
+{
|
||||
+ XEN_GUEST_HANDLE(void) nat;
|
||||
+
|
||||
+ guest_from_compat_handle(nat, cmp);
|
||||
+ return nat;
|
||||
+}
|
||||
+
|
||||
+#define acm_setpolicy compat_acm_setpolicy
|
||||
+#define acm_set_policy(h, sz) acm_set_policy(acm_xlat_handle(h), sz)
|
||||
+
|
||||
+#define acm_getpolicy compat_acm_getpolicy
|
||||
+#define acm_get_policy(h, sz) acm_get_policy(acm_xlat_handle(h), sz)
|
||||
+
|
||||
+#define acm_dumpstats compat_acm_dumpstats
|
||||
+#define acm_dump_statistics(h, sz) acm_dump_statistics(acm_xlat_handle(h), sz)
|
||||
+
|
||||
+#define acm_getssid compat_acm_getssid
|
||||
+#define acm_get_ssid(r, h, sz) acm_get_ssid(r, acm_xlat_handle(h), sz)
|
||||
+
|
||||
+#define xen_acm_getdecision acm_getdecision
|
||||
+CHECK_acm_getdecision;
|
||||
+#undef xen_acm_getdecision
|
||||
+
|
||||
+#include "../acm_ops.c"
|
||||
+
|
||||
+/*
|
||||
+ * Local variables:
|
||||
+ * mode: C
|
||||
+ * c-set-style: "BSD"
|
||||
+ * c-basic-offset: 4
|
||||
+ * tab-width: 4
|
||||
+ * indent-tabs-mode: nil
|
||||
+ * End:
|
||||
+ */
|
||||
Index: 2007-01-08/xen/include/xlat.lst
|
||||
===================================================================
|
||||
--- 2007-01-08.orig/xen/include/xlat.lst 2007-01-08 15:19:22.000000000 +0100
|
||||
+++ 2007-01-08/xen/include/xlat.lst 2007-01-08 15:20:24.000000000 +0100
|
||||
@@ -9,6 +9,7 @@
|
||||
! cpu_user_regs arch-@arch@/xen-@subarch@.h
|
||||
! trap_info arch-@arch@/xen.h
|
||||
! vcpu_guest_context arch-@arch@/xen.h
|
||||
+? acm_getdecision acm_ops.h
|
||||
? evtchn_alloc_unbound event_channel.h
|
||||
? evtchn_bind_interdomain event_channel.h
|
||||
? evtchn_bind_ipi event_channel.h
|
1058
32on64-base.patch
Normal file
1058
32on64-base.patch
Normal file
File diff suppressed because it is too large
Load Diff
484
32on64-call-gates.patch
Normal file
484
32on64-call-gates.patch
Normal file
@ -0,0 +1,484 @@
|
||||
Index: 2007-01-31/xen/arch/x86/traps.c
|
||||
===================================================================
|
||||
--- 2007-01-31.orig/xen/arch/x86/traps.c 2007-01-31 09:39:19.000000000 +0100
|
||||
+++ 2007-01-31/xen/arch/x86/traps.c 2007-01-31 09:41:46.000000000 +0100
|
||||
@@ -1051,6 +1051,63 @@ static int read_descriptor(unsigned int
|
||||
return 1;
|
||||
}
|
||||
|
||||
+#ifdef CONFIG_COMPAT/* XXX __x86_64__ */
|
||||
+static int read_gate_descriptor(unsigned int gate_sel,
|
||||
+ const struct vcpu *v,
|
||||
+ unsigned int *sel,
|
||||
+ unsigned long *off,
|
||||
+ unsigned int *ar)
|
||||
+{
|
||||
+ struct desc_struct desc;
|
||||
+ const struct desc_struct *pdesc;
|
||||
+
|
||||
+
|
||||
+ pdesc = (const struct desc_struct *)(!(gate_sel & 4) ?
|
||||
+ GDT_VIRT_START(v) :
|
||||
+ LDT_VIRT_START(v))
|
||||
+ + (gate_sel >> 3);
|
||||
+ if ( gate_sel < 4 ||
|
||||
+ (gate_sel >= FIRST_RESERVED_GDT_BYTE && !(gate_sel & 4)) ||
|
||||
+ __get_user(desc, pdesc) )
|
||||
+ return 0;
|
||||
+
|
||||
+ *sel = (desc.a >> 16) & 0x0000fffc;
|
||||
+ *off = (desc.a & 0x0000ffff) | (desc.b & 0xffff0000);
|
||||
+ *ar = desc.b & 0x0000ffff;
|
||||
+ /*
|
||||
+ * check_descriptor() clears the DPL field and stores the
|
||||
+ * guest requested DPL in the selector's RPL field.
|
||||
+ */
|
||||
+ ASSERT(!(*ar & _SEGMENT_DPL));
|
||||
+ *ar |= (desc.a >> (16 - 13)) & _SEGMENT_DPL;
|
||||
+
|
||||
+ if ( !IS_COMPAT(v->domain) )
|
||||
+ {
|
||||
+ if ( (*ar & 0x1f00) != 0x0c00 ||
|
||||
+ (gate_sel >= FIRST_RESERVED_GDT_BYTE - 8 && !(gate_sel & 4)) ||
|
||||
+ __get_user(desc, pdesc + 1) ||
|
||||
+ (desc.b & 0x1f00) )
|
||||
+ return 0;
|
||||
+
|
||||
+ *off |= (unsigned long)desc.a << 32;
|
||||
+ return 1;
|
||||
+ }
|
||||
+
|
||||
+ switch ( *ar & 0x1f00 )
|
||||
+ {
|
||||
+ case 0x0400:
|
||||
+ *off &= 0xffff;
|
||||
+ break;
|
||||
+ case 0x0c00:
|
||||
+ break;
|
||||
+ default:
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ return 1;
|
||||
+}
|
||||
+#endif
|
||||
+
|
||||
/* Has the guest requested sufficient permission for this I/O access? */
|
||||
static inline int guest_io_okay(
|
||||
unsigned int port, unsigned int bytes,
|
||||
@@ -1118,6 +1175,8 @@ unsigned long guest_to_host_gpr_switch(u
|
||||
#define insn_fetch(type, base, eip, limit) \
|
||||
({ unsigned long _rc, _ptr = (base) + (eip); \
|
||||
type _x; \
|
||||
+ if ( ad_default < 8 ) \
|
||||
+ _ptr = (unsigned int)_ptr; \
|
||||
if ( (limit) < sizeof(_x) - 1 || (eip) > (limit) - (sizeof(_x) - 1) ) \
|
||||
goto fail; \
|
||||
if ( (_rc = copy_from_user(&_x, (type *)_ptr, sizeof(_x))) != 0 ) \
|
||||
@@ -1714,6 +1773,336 @@ static int emulate_privileged_op(struct
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static inline int check_stack_limit(unsigned int ar, unsigned int limit,
|
||||
+ unsigned int esp, unsigned int decr)
|
||||
+{
|
||||
+ return esp - decr < esp - 1 &&
|
||||
+ (!(ar & _SEGMENT_EC) ? esp - 1 <= limit : esp - decr > limit);
|
||||
+}
|
||||
+
|
||||
+static int emulate_gate_op(struct cpu_user_regs *regs)
|
||||
+{
|
||||
+#ifdef CONFIG_COMPAT/* XXX __x86_64__ */
|
||||
+ struct vcpu *v = current;
|
||||
+ unsigned int sel, ar, dpl, nparm, opnd_sel;
|
||||
+ unsigned int op_default, op_bytes, ad_default, ad_bytes;
|
||||
+ unsigned long off, eip, opnd_off, base, limit;
|
||||
+ int jump;
|
||||
+
|
||||
+ /* Check whether this fault is due to the use of a call gate. */
|
||||
+ if ( !read_gate_descriptor(regs->error_code, v, &sel, &off, &ar) ||
|
||||
+ ((ar >> 13) & 3) < (regs->cs & 3) ||
|
||||
+ (ar & _SEGMENT_TYPE) != 0xc00 )
|
||||
+ return do_guest_trap(TRAP_gp_fault, regs, 1);
|
||||
+ if ( !(ar & _SEGMENT_P) )
|
||||
+ return do_guest_trap(TRAP_no_segment, regs, 1);
|
||||
+ dpl = (ar >> 13) & 3;
|
||||
+ nparm = ar & 0x1f;
|
||||
+
|
||||
+ /*
|
||||
+ * Decode instruction (and perhaps operand) to determine RPL,
|
||||
+ * whether this is a jump or a call, and the call return offset.
|
||||
+ */
|
||||
+ if ( !read_descriptor(regs->cs, v, regs, &base, &limit, &ar, 0) ||
|
||||
+ !(ar & _SEGMENT_S) ||
|
||||
+ !(ar & _SEGMENT_P) ||
|
||||
+ !(ar & _SEGMENT_CODE) )
|
||||
+ return do_guest_trap(TRAP_gp_fault, regs, 1);
|
||||
+
|
||||
+ op_bytes = op_default = ar & _SEGMENT_DB ? 4 : 2;
|
||||
+ ad_default = ad_bytes = op_default;
|
||||
+ opnd_sel = opnd_off = 0;
|
||||
+ jump = -1;
|
||||
+ for ( eip = regs->eip; eip - regs->_eip < 10; )
|
||||
+ {
|
||||
+ switch ( insn_fetch(u8, base, eip, limit) )
|
||||
+ {
|
||||
+ case 0x66: /* operand-size override */
|
||||
+ op_bytes = op_default ^ 6; /* switch between 2/4 bytes */
|
||||
+ continue;
|
||||
+ case 0x67: /* address-size override */
|
||||
+ ad_bytes = ad_default != 4 ? 4 : 2; /* switch to 2/4 bytes */
|
||||
+ continue;
|
||||
+ case 0x2e: /* CS override */
|
||||
+ opnd_sel = regs->cs;
|
||||
+ ASSERT(opnd_sel);
|
||||
+ continue;
|
||||
+ case 0x3e: /* DS override */
|
||||
+ opnd_sel = read_sreg(regs, ds);
|
||||
+ if ( !opnd_sel )
|
||||
+ opnd_sel = dpl;
|
||||
+ continue;
|
||||
+ case 0x26: /* ES override */
|
||||
+ opnd_sel = read_sreg(regs, es);
|
||||
+ if ( !opnd_sel )
|
||||
+ opnd_sel = dpl;
|
||||
+ continue;
|
||||
+ case 0x64: /* FS override */
|
||||
+ opnd_sel = read_sreg(regs, fs);
|
||||
+ if ( !opnd_sel )
|
||||
+ opnd_sel = dpl;
|
||||
+ continue;
|
||||
+ case 0x65: /* GS override */
|
||||
+ opnd_sel = read_sreg(regs, gs);
|
||||
+ if ( !opnd_sel )
|
||||
+ opnd_sel = dpl;
|
||||
+ continue;
|
||||
+ case 0x36: /* SS override */
|
||||
+ opnd_sel = regs->ss;
|
||||
+ if ( !opnd_sel )
|
||||
+ opnd_sel = dpl;
|
||||
+ continue;
|
||||
+ case 0xea:
|
||||
+ ++jump;
|
||||
+ /* FALLTHROUGH */
|
||||
+ case 0x9a:
|
||||
+ ++jump;
|
||||
+ opnd_sel = regs->cs;
|
||||
+ opnd_off = eip;
|
||||
+ ad_bytes = ad_default;
|
||||
+ eip += op_bytes + 2;
|
||||
+ break;
|
||||
+ case 0xff:
|
||||
+ {
|
||||
+ unsigned int modrm;
|
||||
+
|
||||
+ switch ( (modrm = insn_fetch(u8, base, eip, limit)) & 0xf8 )
|
||||
+ {
|
||||
+ case 0x28: case 0x68: case 0xa8:
|
||||
+ ++jump;
|
||||
+ /* FALLTHROUGH */
|
||||
+ case 0x18: case 0x58: case 0x98:
|
||||
+ ++jump;
|
||||
+ if ( ad_bytes != 2 )
|
||||
+ {
|
||||
+ if ( (modrm & 7) == 4 )
|
||||
+ {
|
||||
+ unsigned int sib = insn_fetch(u8, base, eip, limit);
|
||||
+
|
||||
+ modrm = (modrm & ~7) | (sib & 7);
|
||||
+ if ( (sib >>= 3) != 4 )
|
||||
+ opnd_off = *(unsigned long *)decode_register(sib & 7, regs, 0);
|
||||
+ opnd_off <<= sib >> 3;
|
||||
+ }
|
||||
+ if ( (modrm & 7) != 5 || (modrm & 0xc0) )
|
||||
+ opnd_off += *(unsigned long *)decode_register(modrm & 7, regs, 0);
|
||||
+ else
|
||||
+ modrm |= 0x87;
|
||||
+ if ( !opnd_sel )
|
||||
+ {
|
||||
+ switch ( modrm & 7 )
|
||||
+ {
|
||||
+ default:
|
||||
+ opnd_sel = read_sreg(regs, ds);
|
||||
+ break;
|
||||
+ case 4: case 5:
|
||||
+ opnd_sel = regs->ss;
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ switch ( modrm & 7 )
|
||||
+ {
|
||||
+ case 0: case 1: case 7:
|
||||
+ opnd_off = regs->ebx;
|
||||
+ break;
|
||||
+ case 6:
|
||||
+ if ( !(modrm & 0xc0) )
|
||||
+ modrm |= 0x80;
|
||||
+ else
|
||||
+ case 2: case 3:
|
||||
+ {
|
||||
+ opnd_off = regs->ebp;
|
||||
+ if ( !opnd_sel )
|
||||
+ opnd_sel = regs->ss;
|
||||
+ }
|
||||
+ break;
|
||||
+ }
|
||||
+ if ( !opnd_sel )
|
||||
+ opnd_sel = read_sreg(regs, ds);
|
||||
+ switch ( modrm & 7 )
|
||||
+ {
|
||||
+ case 0: case 2: case 4:
|
||||
+ opnd_off += regs->esi;
|
||||
+ break;
|
||||
+ case 1: case 3: case 5:
|
||||
+ opnd_off += regs->edi;
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+ switch ( modrm & 0xc0 )
|
||||
+ {
|
||||
+ case 0x40:
|
||||
+ opnd_off += insn_fetch(s8, base, eip, limit);
|
||||
+ break;
|
||||
+ case 0x80:
|
||||
+ opnd_off += insn_fetch(s32, base, eip, limit);
|
||||
+ break;
|
||||
+ }
|
||||
+ if ( ad_bytes == 4 )
|
||||
+ opnd_off = (unsigned int)opnd_off;
|
||||
+ else if ( ad_bytes == 2 )
|
||||
+ opnd_off = (unsigned short)opnd_off;
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+ break;
|
||||
+ }
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ if ( jump < 0 )
|
||||
+ {
|
||||
+ fail:
|
||||
+ return do_guest_trap(TRAP_gp_fault, regs, 1);
|
||||
+ }
|
||||
+
|
||||
+ if ( (opnd_sel != regs->cs &&
|
||||
+ !read_descriptor(opnd_sel, v, regs, &base, &limit, &ar, 0)) ||
|
||||
+ !(ar & _SEGMENT_S) ||
|
||||
+ !(ar & _SEGMENT_P) ||
|
||||
+ ((ar & _SEGMENT_CODE) && !(ar & _SEGMENT_WR)) )
|
||||
+ return do_guest_trap(TRAP_gp_fault, regs, 1);
|
||||
+
|
||||
+ opnd_off += op_bytes;
|
||||
+#define ad_default ad_bytes
|
||||
+ opnd_sel = insn_fetch(u16, base, opnd_off, limit);
|
||||
+#undef ad_default
|
||||
+ ASSERT((opnd_sel & ~3) == regs->error_code);
|
||||
+ if ( dpl < (opnd_sel & 3) )
|
||||
+ return do_guest_trap(TRAP_gp_fault, regs, 1);
|
||||
+
|
||||
+ if ( !read_descriptor(sel, v, regs, &base, &limit, &ar, 0) ||
|
||||
+ !(ar & _SEGMENT_S) ||
|
||||
+ !(ar & _SEGMENT_CODE) ||
|
||||
+ (!jump || (ar & _SEGMENT_EC) ?
|
||||
+ ((ar >> 13) & 3) > (regs->cs & 3) :
|
||||
+ ((ar >> 13) & 3) != (regs->cs & 3)) )
|
||||
+ {
|
||||
+ regs->error_code = sel;
|
||||
+ return do_guest_trap(TRAP_gp_fault, regs, 1);
|
||||
+ }
|
||||
+ if ( !(ar & _SEGMENT_P) )
|
||||
+ {
|
||||
+ regs->error_code = sel;
|
||||
+ return do_guest_trap(TRAP_no_segment, regs, 1);
|
||||
+ }
|
||||
+ if ( off > limit )
|
||||
+ {
|
||||
+ regs->error_code = 0;
|
||||
+ return do_guest_trap(TRAP_gp_fault, regs, 1);
|
||||
+ }
|
||||
+
|
||||
+ if ( !jump )
|
||||
+ {
|
||||
+ unsigned int ss, esp, *stkp;
|
||||
+ int rc;
|
||||
+#define push(item) do \
|
||||
+ { \
|
||||
+ --stkp; \
|
||||
+ esp -= 4; \
|
||||
+ rc = __put_user(item, stkp); \
|
||||
+ if ( rc ) \
|
||||
+ { \
|
||||
+ propagate_page_fault((unsigned long)(stkp + 1) - rc, \
|
||||
+ PFEC_write_access); \
|
||||
+ return 0; \
|
||||
+ } \
|
||||
+ } while ( 0 )
|
||||
+
|
||||
+ if ( ((ar >> 13) & 3) < (regs->cs & 3) )
|
||||
+ {
|
||||
+ sel |= (ar >> 13) & 3;
|
||||
+ /* Inner stack known only for kernel ring. */
|
||||
+ if ( (sel & 3) != GUEST_KERNEL_RPL(v->domain) )
|
||||
+ return do_guest_trap(TRAP_gp_fault, regs, 1);
|
||||
+ esp = v->arch.guest_context.kernel_sp;
|
||||
+ ss = v->arch.guest_context.kernel_ss;
|
||||
+ if ( (ss & 3) != (sel & 3) ||
|
||||
+ !read_descriptor(ss, v, regs, &base, &limit, &ar, 0) ||
|
||||
+ ((ar >> 13) & 3) != (sel & 3) ||
|
||||
+ !(ar & _SEGMENT_S) ||
|
||||
+ (ar & _SEGMENT_CODE) ||
|
||||
+ !(ar & _SEGMENT_WR) )
|
||||
+ {
|
||||
+ regs->error_code = ss & ~3;
|
||||
+ return do_guest_trap(TRAP_invalid_tss, regs, 1);
|
||||
+ }
|
||||
+ if ( !(ar & _SEGMENT_P) ||
|
||||
+ !check_stack_limit(ar, limit, esp, (4 + nparm) * 4) )
|
||||
+ {
|
||||
+ regs->error_code = ss & ~3;
|
||||
+ return do_guest_trap(TRAP_stack_error, regs, 1);
|
||||
+ }
|
||||
+ stkp = (unsigned int *)(unsigned long)((unsigned int)base + esp);
|
||||
+ if ( !compat_access_ok(stkp - 4 - nparm, (4 + nparm) * 4) )
|
||||
+ return do_guest_trap(TRAP_gp_fault, regs, 1);
|
||||
+ push(regs->ss);
|
||||
+ push(regs->esp);
|
||||
+ if ( nparm )
|
||||
+ {
|
||||
+ const unsigned int *ustkp;
|
||||
+
|
||||
+ if ( !read_descriptor(regs->ss, v, regs, &base, &limit, &ar, 0) ||
|
||||
+ ((ar >> 13) & 3) != (regs->cs & 3) ||
|
||||
+ !(ar & _SEGMENT_S) ||
|
||||
+ (ar & _SEGMENT_CODE) ||
|
||||
+ !(ar & _SEGMENT_WR) ||
|
||||
+ !check_stack_limit(ar, limit, esp + nparm * 4, nparm * 4) )
|
||||
+ return do_guest_trap(TRAP_gp_fault, regs, 1);
|
||||
+ ustkp = (unsigned int *)(unsigned long)((unsigned int)base + regs->_esp + nparm * 4);
|
||||
+ if ( !compat_access_ok(ustkp - nparm, nparm * 4) )
|
||||
+ return do_guest_trap(TRAP_gp_fault, regs, 1);
|
||||
+ do
|
||||
+ {
|
||||
+ unsigned int parm;
|
||||
+
|
||||
+ --ustkp;
|
||||
+ rc = __get_user(parm, ustkp);
|
||||
+ if ( rc )
|
||||
+ {
|
||||
+ propagate_page_fault((unsigned long)(ustkp + 1) - rc, 0);
|
||||
+ return 0;
|
||||
+ }
|
||||
+ push(parm);
|
||||
+ } while ( --nparm );
|
||||
+ }
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ sel |= (regs->cs & 3);
|
||||
+ esp = regs->esp;
|
||||
+ ss = regs->ss;
|
||||
+ if ( !read_descriptor(ss, v, regs, &base, &limit, &ar, 0) ||
|
||||
+ ((ar >> 13) & 3) != (sel & 3) )
|
||||
+ return do_guest_trap(TRAP_gp_fault, regs, 1);
|
||||
+ if ( !check_stack_limit(ar, limit, esp, 2 * 4) )
|
||||
+ {
|
||||
+ regs->error_code = 0;
|
||||
+ return do_guest_trap(TRAP_stack_error, regs, 1);
|
||||
+ }
|
||||
+ stkp = (unsigned int *)(unsigned long)((unsigned int)base + esp);
|
||||
+ if ( !compat_access_ok(stkp - 2, 2 * 4) )
|
||||
+ return do_guest_trap(TRAP_gp_fault, regs, 1);
|
||||
+ }
|
||||
+ push(regs->cs);
|
||||
+ push(eip);
|
||||
+#undef push
|
||||
+ regs->esp = esp;
|
||||
+ regs->ss = ss;
|
||||
+ }
|
||||
+ else
|
||||
+ sel |= (regs->cs & 3);
|
||||
+
|
||||
+ regs->eip = off;
|
||||
+ regs->cs = sel;
|
||||
+#endif
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
asmlinkage int do_general_protection(struct cpu_user_regs *regs)
|
||||
{
|
||||
struct vcpu *v = current;
|
||||
@@ -1759,6 +2148,8 @@ asmlinkage int do_general_protection(str
|
||||
return do_guest_trap(vector, regs, 0);
|
||||
}
|
||||
}
|
||||
+ else if ( IS_COMPAT(v->domain) && regs->error_code )
|
||||
+ return emulate_gate_op(regs);
|
||||
|
||||
/* Emulate some simple privileged and I/O instructions. */
|
||||
if ( (regs->error_code == 0) &&
|
||||
Index: 2007-01-31/xen/arch/x86/x86_64/mm.c
|
||||
===================================================================
|
||||
--- 2007-01-31.orig/xen/arch/x86/x86_64/mm.c 2007-01-31 09:29:17.000000000 +0100
|
||||
+++ 2007-01-31/xen/arch/x86/x86_64/mm.c 2007-01-31 09:41:46.000000000 +0100
|
||||
@@ -366,14 +366,16 @@ int check_descriptor(const struct domain
|
||||
{
|
||||
u32 a = d->a, b = d->b;
|
||||
u16 cs;
|
||||
+ unsigned int dpl;
|
||||
|
||||
/* A not-present descriptor will always fault, so is safe. */
|
||||
if ( !(b & _SEGMENT_P) )
|
||||
goto good;
|
||||
|
||||
/* Check and fix up the DPL. */
|
||||
- if ( (b & _SEGMENT_DPL) < (GUEST_KERNEL_RPL(dom) << 13) )
|
||||
- d->b = b = (b & ~_SEGMENT_DPL) | (GUEST_KERNEL_RPL(dom) << 13);
|
||||
+ dpl = (b >> 13) & 3;
|
||||
+ __fixup_guest_selector(dom, dpl);
|
||||
+ b = (b & ~_SEGMENT_DPL) | (dpl << 13);
|
||||
|
||||
/* All code and data segments are okay. No base/limit checking. */
|
||||
if ( (b & _SEGMENT_S) )
|
||||
@@ -391,18 +393,33 @@ int check_descriptor(const struct domain
|
||||
if ( (b & _SEGMENT_TYPE) != 0xc00 )
|
||||
goto bad;
|
||||
|
||||
- /* Validate and fix up the target code selector. */
|
||||
+ /* Validate the target code selector. */
|
||||
cs = a >> 16;
|
||||
- fixup_guest_code_selector(dom, cs);
|
||||
if ( !guest_gate_selector_okay(dom, cs) )
|
||||
goto bad;
|
||||
- a = d->a = (d->a & 0xffffU) | (cs << 16);
|
||||
+#ifdef __x86_64__
|
||||
+ /*
|
||||
+ * Force DPL to zero, causing a GP fault with its error code indicating
|
||||
+ * the gate in use, allowing emulation. This is necessary because with
|
||||
+ * native guests (kernel in ring 3) call gates cannot be used directly
|
||||
+ * to transition from user to kernel mode (and whether a gate is used
|
||||
+ * to enter the kernel can only be determined when the gate is being
|
||||
+ * used), and with compat guests call gates cannot be used at all as
|
||||
+ * there are only 64-bit ones.
|
||||
+ * Store the original DPL in the selector's RPL field.
|
||||
+ */
|
||||
+ b &= ~_SEGMENT_DPL;
|
||||
+ cs = (cs & ~3) | dpl;
|
||||
+#endif
|
||||
+ a = (a & 0xffffU) | (cs << 16);
|
||||
|
||||
/* Reserved bits must be zero. */
|
||||
- if ( (b & 0xe0) != 0 )
|
||||
+ if ( b & (CONFIG_PAGING_LEVELS < 4 || IS_COMPAT(dom) ? 0xe0 : 0xff) )
|
||||
goto bad;
|
||||
|
||||
good:
|
||||
+ d->a = a;
|
||||
+ d->b = b;
|
||||
return 1;
|
||||
bad:
|
||||
return 0;
|
1336
32on64-domctl.patch
Normal file
1336
32on64-domctl.patch
Normal file
File diff suppressed because it is too large
Load Diff
647
32on64-emul.patch
Normal file
647
32on64-emul.patch
Normal file
@ -0,0 +1,647 @@
|
||||
Adjust emulation code to deal with compatibility mode guests. This
|
||||
includes enhancements to emulate_privileged_op() that aren't directly
|
||||
related to such guests.
|
||||
|
||||
Index: 2006-12-18/xen/arch/x86/domain.c
|
||||
===================================================================
|
||||
--- 2006-12-18.orig/xen/arch/x86/domain.c 2006-12-18 17:53:11.000000000 +0100
|
||||
+++ 2006-12-18/xen/arch/x86/domain.c 2006-12-18 09:49:18.000000000 +0100
|
||||
@@ -1065,6 +1065,20 @@ void domain_relinquish_resources(struct
|
||||
{
|
||||
/* Drop ref to guest_table (from new_guest_cr3(), svm/vmx cr3 handling,
|
||||
* or sh_update_paging_modes()) */
|
||||
+#ifdef CONFIG_COMPAT
|
||||
+ if ( IS_COMPAT(d) )
|
||||
+ {
|
||||
+ pfn = l4e_get_pfn(*(l4_pgentry_t *)__va(pagetable_get_paddr(v->arch.guest_table)));
|
||||
+ if ( pfn != 0 )
|
||||
+ {
|
||||
+ if ( shadow_mode_refcounts(d) )
|
||||
+ put_page(mfn_to_page(pfn));
|
||||
+ else
|
||||
+ put_page_and_type(mfn_to_page(pfn));
|
||||
+ }
|
||||
+ continue;
|
||||
+ }
|
||||
+#endif
|
||||
pfn = pagetable_get_pfn(v->arch.guest_table);
|
||||
if ( pfn != 0 )
|
||||
{
|
||||
Index: 2006-12-18/xen/arch/x86/mm.c
|
||||
===================================================================
|
||||
--- 2006-12-18.orig/xen/arch/x86/mm.c 2006-12-18 17:53:11.000000000 +0100
|
||||
+++ 2006-12-18/xen/arch/x86/mm.c 2006-12-18 09:49:18.000000000 +0100
|
||||
@@ -1759,6 +1759,33 @@ int new_guest_cr3(unsigned long mfn)
|
||||
if ( is_hvm_domain(d) && !hvm_paging_enabled(v) )
|
||||
return 0;
|
||||
|
||||
+#ifdef CONFIG_COMPAT
|
||||
+ if ( IS_COMPAT(d) )
|
||||
+ {
|
||||
+ l4_pgentry_t l4e = l4e_from_pfn(mfn, _PAGE_PRESENT|_PAGE_RW|_PAGE_USER|_PAGE_ACCESSED);
|
||||
+
|
||||
+ if ( shadow_mode_refcounts(d) )
|
||||
+ {
|
||||
+ okay = get_page_from_pagenr(mfn, d);
|
||||
+ old_base_mfn = l4e_get_pfn(l4e);
|
||||
+ if ( okay && old_base_mfn )
|
||||
+ put_page(mfn_to_page(old_base_mfn));
|
||||
+ }
|
||||
+ else
|
||||
+ okay = mod_l4_entry(__va(pagetable_get_paddr(v->arch.guest_table)),
|
||||
+ l4e, 0);
|
||||
+ if ( unlikely(!okay) )
|
||||
+ {
|
||||
+ MEM_LOG("Error while installing new compat baseptr %lx", mfn);
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ invalidate_shadow_ldt(v);
|
||||
+ write_ptbase(v);
|
||||
+
|
||||
+ return 1;
|
||||
+ }
|
||||
+#endif
|
||||
if ( shadow_mode_refcounts(d) )
|
||||
{
|
||||
okay = get_page_from_pagenr(mfn, d);
|
||||
@@ -3212,7 +3239,7 @@ static int ptwr_emulated_update(
|
||||
nl1e = l1e_from_intpte(val);
|
||||
if ( unlikely(!get_page_from_l1e(gl1e_to_ml1e(d, nl1e), d)) )
|
||||
{
|
||||
- if ( (CONFIG_PAGING_LEVELS == 3) &&
|
||||
+ if ( (CONFIG_PAGING_LEVELS == 3 || IS_COMPAT(d)) &&
|
||||
(bytes == 4) &&
|
||||
!do_cmpxchg &&
|
||||
(l1e_get_flags(nl1e) & _PAGE_PRESENT) )
|
||||
@@ -3356,7 +3383,7 @@ int ptwr_do_page_fault(struct vcpu *v, u
|
||||
goto bail;
|
||||
|
||||
ptwr_ctxt.ctxt.regs = guest_cpu_user_regs();
|
||||
- ptwr_ctxt.ctxt.mode = X86EMUL_MODE_HOST;
|
||||
+ ptwr_ctxt.ctxt.mode = !IS_COMPAT(d) ? X86EMUL_MODE_HOST : X86EMUL_MODE_PROT32;
|
||||
ptwr_ctxt.cr2 = addr;
|
||||
ptwr_ctxt.pte = pte;
|
||||
if ( x86_emulate_memop(&ptwr_ctxt.ctxt, &ptwr_emulate_ops) )
|
||||
Index: 2006-12-18/xen/arch/x86/traps.c
|
||||
===================================================================
|
||||
--- 2006-12-18.orig/xen/arch/x86/traps.c 2006-12-18 17:53:11.000000000 +0100
|
||||
+++ 2006-12-18/xen/arch/x86/traps.c 2006-12-18 17:53:52.000000000 +0100
|
||||
@@ -993,6 +993,64 @@ long do_fpu_taskswitch(int set)
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static int read_descriptor(unsigned int sel,
|
||||
+ const struct vcpu *v,
|
||||
+ const struct cpu_user_regs * regs,
|
||||
+ unsigned long *base,
|
||||
+ unsigned long *limit,
|
||||
+ unsigned int *ar,
|
||||
+ unsigned int vm86attr)
|
||||
+{
|
||||
+ struct desc_struct desc;
|
||||
+
|
||||
+ if ( !vm86_mode(regs) )
|
||||
+ {
|
||||
+ if ( sel < 4)
|
||||
+ desc.b = desc.a = 0;
|
||||
+ else if ( __get_user(desc,
|
||||
+ (const struct desc_struct *)(!(sel & 4)
|
||||
+ ? GDT_VIRT_START(v)
|
||||
+ : LDT_VIRT_START(v))
|
||||
+ + (sel >> 3)) )
|
||||
+ return 0;
|
||||
+ if ( !(vm86attr & _SEGMENT_CODE) )
|
||||
+ desc.b &= ~_SEGMENT_L;
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ desc.a = (sel << 20) | 0xffff;
|
||||
+ desc.b = vm86attr | (sel >> 12);
|
||||
+ }
|
||||
+
|
||||
+ *ar = desc.b & 0x00f0ff00;
|
||||
+ if ( !(desc.b & _SEGMENT_L) )
|
||||
+ {
|
||||
+ *base = (desc.a >> 16) + ((desc.b & 0xff) << 16) + (desc.b & 0xff000000);
|
||||
+ *limit = (desc.a & 0xffff) | (desc.b & 0x000f0000);
|
||||
+ if ( desc.b & _SEGMENT_G )
|
||||
+ *limit = ((*limit + 1) << 12) - 1;
|
||||
+#ifndef NDEBUG
|
||||
+ if ( !vm86_mode(regs) && sel > 3 )
|
||||
+ {
|
||||
+ unsigned int a, l;
|
||||
+ unsigned char valid;
|
||||
+
|
||||
+ __asm__("larl %2, %0\n\tsetz %1" : "=r" (a), "=rm" (valid) : "rm" (sel));
|
||||
+ BUG_ON(valid && (a & 0x00f0ff00) != *ar);
|
||||
+ __asm__("lsll %2, %0\n\tsetz %1" : "=r" (l), "=rm" (valid) : "rm" (sel));
|
||||
+ BUG_ON(valid && l != *limit);
|
||||
+ }
|
||||
+#endif
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ *base = 0UL;
|
||||
+ *limit = ~0UL;
|
||||
+ }
|
||||
+
|
||||
+ return 1;
|
||||
+}
|
||||
+
|
||||
/* Has the guest requested sufficient permission for this I/O access? */
|
||||
static inline int guest_io_okay(
|
||||
unsigned int port, unsigned int bytes,
|
||||
@@ -1057,65 +1115,113 @@ unsigned long guest_to_host_gpr_switch(u
|
||||
__attribute__((__regparm__(1)));
|
||||
|
||||
/* Instruction fetch with error handling. */
|
||||
-#define insn_fetch(_type, _size, cs, eip) \
|
||||
-({ unsigned long _rc, _x, _ptr = eip; \
|
||||
- if ( vm86_mode(regs) ) \
|
||||
- _ptr += cs << 4; \
|
||||
- if ( (_rc = copy_from_user(&_x, (_type *)_ptr, sizeof(_type))) != 0 ) \
|
||||
+#define insn_fetch(type, base, eip, limit) \
|
||||
+({ unsigned long _rc, _ptr = (base) + (eip); \
|
||||
+ type _x; \
|
||||
+ if ( (limit) < sizeof(_x) - 1 || (eip) > (limit) - (sizeof(_x) - 1) ) \
|
||||
+ goto fail; \
|
||||
+ if ( (_rc = copy_from_user(&_x, (type *)_ptr, sizeof(_x))) != 0 ) \
|
||||
{ \
|
||||
- propagate_page_fault(eip + sizeof(_type) - _rc, 0); \
|
||||
+ propagate_page_fault(_ptr + sizeof(_x) - _rc, 0); \
|
||||
return EXCRET_fault_fixed; \
|
||||
} \
|
||||
- eip += _size; (_type)_x; })
|
||||
+ (eip) += sizeof(_x); _x; })
|
||||
+
|
||||
+#if defined(CONFIG_X86_32)
|
||||
+# define read_sreg(regs, sr) ((regs)->sr)
|
||||
+#elif defined(CONFIG_X86_64)
|
||||
+# define read_sreg(regs, sr) read_segment_register(sr)
|
||||
+#endif
|
||||
|
||||
static int emulate_privileged_op(struct cpu_user_regs *regs)
|
||||
{
|
||||
struct vcpu *v = current;
|
||||
- unsigned long *reg, eip = regs->eip, cs = regs->cs, res;
|
||||
- u8 opcode, modrm_reg = 0, modrm_rm = 0, rep_prefix = 0;
|
||||
- unsigned int port, i, op_bytes = 4, data, rc;
|
||||
+ unsigned long *reg, eip = regs->eip, res;
|
||||
+ u8 opcode, modrm_reg = 0, modrm_rm = 0, rep_prefix = 0, rex = 0;
|
||||
+ enum { lm_seg_none, lm_seg_fs, lm_seg_gs } lm_ovr = lm_seg_none;
|
||||
+ unsigned int port, i, data_sel, ar, data, rc;
|
||||
+ unsigned int op_bytes, op_default, ad_bytes, ad_default;
|
||||
+#define rd_ad(reg) (ad_bytes >= sizeof(regs->reg) \
|
||||
+ ? regs->reg \
|
||||
+ : ad_bytes == 4 \
|
||||
+ ? (u32)regs->reg \
|
||||
+ : (u16)regs->reg)
|
||||
+#define wr_ad(reg, val) (ad_bytes >= sizeof(regs->reg) \
|
||||
+ ? regs->reg = (val) \
|
||||
+ : ad_bytes == 4 \
|
||||
+ ? (*(u32 *)®s->reg = (val)) \
|
||||
+ : (*(u16 *)®s->reg = (val)))
|
||||
+ unsigned long code_base, code_limit;
|
||||
char io_emul_stub[16];
|
||||
void (*io_emul)(struct cpu_user_regs *) __attribute__((__regparm__(1)));
|
||||
u32 l, h;
|
||||
|
||||
+ if ( !read_descriptor(regs->cs, v, regs,
|
||||
+ &code_base, &code_limit, &ar,
|
||||
+ _SEGMENT_CODE|_SEGMENT_S|_SEGMENT_DPL|_SEGMENT_P) )
|
||||
+ goto fail;
|
||||
+ op_default = op_bytes = (ar & (_SEGMENT_L|_SEGMENT_DB)) ? 4 : 2;
|
||||
+ ad_default = ad_bytes = (ar & _SEGMENT_L) ? 8 : op_default;
|
||||
+ if ( !(ar & (_SEGMENT_CODE|_SEGMENT_S|_SEGMENT_P)) )
|
||||
+ goto fail;
|
||||
+
|
||||
+ /* emulating only opcodes not allowing SS to be default */
|
||||
+ data_sel = read_sreg(regs, ds);
|
||||
+
|
||||
/* Legacy prefixes. */
|
||||
- for ( i = 0; i < 8; i++ )
|
||||
+ for ( i = 0; i < 8; i++, rex == opcode || (rex = 0) )
|
||||
{
|
||||
- switch ( opcode = insn_fetch(u8, 1, cs, eip) )
|
||||
+ switch ( opcode = insn_fetch(u8, code_base, eip, code_limit) )
|
||||
{
|
||||
case 0x66: /* operand-size override */
|
||||
- op_bytes ^= 6; /* switch between 2/4 bytes */
|
||||
- break;
|
||||
+ op_bytes = op_default ^ 6; /* switch between 2/4 bytes */
|
||||
+ continue;
|
||||
case 0x67: /* address-size override */
|
||||
+ ad_bytes = ad_default != 4 ? 4 : 2; /* switch to 2/4 bytes */
|
||||
+ continue;
|
||||
case 0x2e: /* CS override */
|
||||
+ data_sel = regs->cs;
|
||||
+ continue;
|
||||
case 0x3e: /* DS override */
|
||||
+ data_sel = read_sreg(regs, ds);
|
||||
+ continue;
|
||||
case 0x26: /* ES override */
|
||||
+ data_sel = read_sreg(regs, es);
|
||||
+ continue;
|
||||
case 0x64: /* FS override */
|
||||
+ data_sel = read_sreg(regs, fs);
|
||||
+ lm_ovr = lm_seg_fs;
|
||||
+ continue;
|
||||
case 0x65: /* GS override */
|
||||
+ data_sel = read_sreg(regs, gs);
|
||||
+ lm_ovr = lm_seg_gs;
|
||||
+ continue;
|
||||
case 0x36: /* SS override */
|
||||
+ data_sel = regs->ss;
|
||||
+ continue;
|
||||
case 0xf0: /* LOCK */
|
||||
+ continue;
|
||||
case 0xf2: /* REPNE/REPNZ */
|
||||
- break;
|
||||
case 0xf3: /* REP/REPE/REPZ */
|
||||
rep_prefix = 1;
|
||||
- break;
|
||||
+ continue;
|
||||
default:
|
||||
- goto done_prefixes;
|
||||
+ if ( (ar & _SEGMENT_L) && (opcode & 0xf0) == 0x40 )
|
||||
+ {
|
||||
+ rex = opcode;
|
||||
+ continue;
|
||||
+ }
|
||||
+ break;
|
||||
}
|
||||
+ break;
|
||||
}
|
||||
- done_prefixes:
|
||||
|
||||
-#ifdef __x86_64__
|
||||
/* REX prefix. */
|
||||
- if ( (opcode & 0xf0) == 0x40 )
|
||||
- {
|
||||
- modrm_reg = (opcode & 4) << 1; /* REX.R */
|
||||
- modrm_rm = (opcode & 1) << 3; /* REX.B */
|
||||
-
|
||||
- /* REX.W and REX.X do not need to be decoded. */
|
||||
- opcode = insn_fetch(u8, 1, cs, eip);
|
||||
- }
|
||||
-#endif
|
||||
+ if ( rex & 8 ) /* REX.W */
|
||||
+ op_bytes = 4; /* emulating only opcodes not supporting 64-bit operands */
|
||||
+ modrm_reg = (rex & 4) << 1; /* REX.R */
|
||||
+ /* REX.X does not need to be decoded. */
|
||||
+ modrm_rm = (rex & 1) << 3; /* REX.B */
|
||||
|
||||
if ( opcode == 0x0f )
|
||||
goto twobyte_opcode;
|
||||
@@ -1123,16 +1229,68 @@ static int emulate_privileged_op(struct
|
||||
/* Input/Output String instructions. */
|
||||
if ( (opcode >= 0x6c) && (opcode <= 0x6f) )
|
||||
{
|
||||
- if ( rep_prefix && (regs->ecx == 0) )
|
||||
+ unsigned long data_base, data_limit;
|
||||
+
|
||||
+ if ( rep_prefix && (rd_ad(ecx) == 0) )
|
||||
goto done;
|
||||
|
||||
+ if ( !(opcode & 2) )
|
||||
+ {
|
||||
+ data_sel = read_sreg(regs, es);
|
||||
+ lm_ovr = lm_seg_none;
|
||||
+ }
|
||||
+
|
||||
+ if ( !(ar & _SEGMENT_L) )
|
||||
+ {
|
||||
+ if ( !read_descriptor(data_sel, v, regs,
|
||||
+ &data_base, &data_limit, &ar,
|
||||
+ _SEGMENT_WR|_SEGMENT_S|_SEGMENT_DPL|_SEGMENT_P) )
|
||||
+ goto fail;
|
||||
+ if ( !(ar & (_SEGMENT_S|_SEGMENT_P)) ||
|
||||
+ (opcode & 2 ?
|
||||
+ (ar & _SEGMENT_CODE) && !(ar & _SEGMENT_WR) :
|
||||
+ (ar & _SEGMENT_CODE) || !(ar & _SEGMENT_WR)) )
|
||||
+ goto fail;
|
||||
+ }
|
||||
+#ifdef CONFIG_X86_64
|
||||
+ else
|
||||
+ {
|
||||
+ if ( lm_ovr == lm_seg_none || data_sel < 4 )
|
||||
+ {
|
||||
+ switch ( lm_ovr )
|
||||
+ {
|
||||
+ case lm_seg_none:
|
||||
+ data_base = 0UL;
|
||||
+ break;
|
||||
+ case lm_seg_fs:
|
||||
+ data_base = v->arch.guest_context.fs_base;
|
||||
+ break;
|
||||
+ case lm_seg_gs:
|
||||
+ if ( guest_kernel_mode(v, regs) )
|
||||
+ data_base = v->arch.guest_context.gs_base_kernel;
|
||||
+ else
|
||||
+ data_base = v->arch.guest_context.gs_base_user;
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+ else
|
||||
+ read_descriptor(data_sel, v, regs,
|
||||
+ &data_base, &data_limit, &ar,
|
||||
+ 0);
|
||||
+ data_limit = ~0UL;
|
||||
+ ar = _SEGMENT_WR|_SEGMENT_S|_SEGMENT_DPL|_SEGMENT_P;
|
||||
+ }
|
||||
+#endif
|
||||
+
|
||||
continue_io_string:
|
||||
switch ( opcode )
|
||||
{
|
||||
case 0x6c: /* INSB */
|
||||
op_bytes = 1;
|
||||
case 0x6d: /* INSW/INSL */
|
||||
- if ( !guest_io_okay((u16)regs->edx, op_bytes, v, regs) )
|
||||
+ if ( data_limit < op_bytes - 1 ||
|
||||
+ rd_ad(edi) > data_limit - (op_bytes - 1) ||
|
||||
+ !guest_io_okay((u16)regs->edx, op_bytes, v, regs) )
|
||||
goto fail;
|
||||
port = (u16)regs->edx;
|
||||
switch ( op_bytes )
|
||||
@@ -1150,24 +1308,26 @@ static int emulate_privileged_op(struct
|
||||
data = (u32)(guest_inl_okay(port, v, regs) ? inl(port) : ~0);
|
||||
break;
|
||||
}
|
||||
- if ( (rc = copy_to_user((void *)regs->edi, &data, op_bytes)) != 0 )
|
||||
+ if ( (rc = copy_to_user((void *)data_base + rd_ad(edi), &data, op_bytes)) != 0 )
|
||||
{
|
||||
- propagate_page_fault(regs->edi + op_bytes - rc,
|
||||
+ propagate_page_fault(data_base + rd_ad(edi) + op_bytes - rc,
|
||||
PFEC_write_access);
|
||||
return EXCRET_fault_fixed;
|
||||
}
|
||||
- regs->edi += (int)((regs->eflags & EF_DF) ? -op_bytes : op_bytes);
|
||||
+ wr_ad(edi, regs->edi + (int)((regs->eflags & EF_DF) ? -op_bytes : op_bytes));
|
||||
break;
|
||||
|
||||
case 0x6e: /* OUTSB */
|
||||
op_bytes = 1;
|
||||
case 0x6f: /* OUTSW/OUTSL */
|
||||
- if ( !guest_io_okay((u16)regs->edx, op_bytes, v, regs) )
|
||||
+ if ( data_limit < op_bytes - 1 ||
|
||||
+ rd_ad(esi) > data_limit - (op_bytes - 1) ||
|
||||
+ !guest_io_okay((u16)regs->edx, op_bytes, v, regs) )
|
||||
goto fail;
|
||||
- rc = copy_from_user(&data, (void *)regs->esi, op_bytes);
|
||||
+ rc = copy_from_user(&data, (void *)data_base + rd_ad(esi), op_bytes);
|
||||
if ( rc != 0 )
|
||||
{
|
||||
- propagate_page_fault(regs->esi + op_bytes - rc, 0);
|
||||
+ propagate_page_fault(data_base + rd_ad(esi) + op_bytes - rc, 0);
|
||||
return EXCRET_fault_fixed;
|
||||
}
|
||||
port = (u16)regs->edx;
|
||||
@@ -1188,11 +1348,11 @@ static int emulate_privileged_op(struct
|
||||
outl((u32)data, port);
|
||||
break;
|
||||
}
|
||||
- regs->esi += (int)((regs->eflags & EF_DF) ? -op_bytes : op_bytes);
|
||||
+ wr_ad(esi, regs->esi + (int)((regs->eflags & EF_DF) ? -op_bytes : op_bytes));
|
||||
break;
|
||||
}
|
||||
|
||||
- if ( rep_prefix && (--regs->ecx != 0) )
|
||||
+ if ( rep_prefix && (wr_ad(ecx, regs->ecx - 1) != 0) )
|
||||
{
|
||||
if ( !hypercall_preempt_check() )
|
||||
goto continue_io_string;
|
||||
@@ -1232,7 +1392,7 @@ static int emulate_privileged_op(struct
|
||||
case 0xe4: /* IN imm8,%al */
|
||||
op_bytes = 1;
|
||||
case 0xe5: /* IN imm8,%eax */
|
||||
- port = insn_fetch(u8, 1, cs, eip);
|
||||
+ port = insn_fetch(u8, code_base, eip, code_limit);
|
||||
io_emul_stub[7] = port; /* imm8 */
|
||||
exec_in:
|
||||
if ( !guest_io_okay(port, op_bytes, v, regs) )
|
||||
@@ -1274,7 +1434,7 @@ static int emulate_privileged_op(struct
|
||||
case 0xe6: /* OUT %al,imm8 */
|
||||
op_bytes = 1;
|
||||
case 0xe7: /* OUT %eax,imm8 */
|
||||
- port = insn_fetch(u8, 1, cs, eip);
|
||||
+ port = insn_fetch(u8, code_base, eip, code_limit);
|
||||
io_emul_stub[7] = port; /* imm8 */
|
||||
exec_out:
|
||||
if ( !guest_io_okay(port, op_bytes, v, regs) )
|
||||
@@ -1327,7 +1487,7 @@ static int emulate_privileged_op(struct
|
||||
goto fail;
|
||||
|
||||
/* Privileged (ring 0) instructions. */
|
||||
- opcode = insn_fetch(u8, 1, cs, eip);
|
||||
+ opcode = insn_fetch(u8, code_base, eip, code_limit);
|
||||
switch ( opcode )
|
||||
{
|
||||
case 0x06: /* CLTS */
|
||||
@@ -1345,7 +1505,7 @@ static int emulate_privileged_op(struct
|
||||
break;
|
||||
|
||||
case 0x20: /* MOV CR?,<reg> */
|
||||
- opcode = insn_fetch(u8, 1, cs, eip);
|
||||
+ opcode = insn_fetch(u8, code_base, eip, code_limit);
|
||||
modrm_reg |= (opcode >> 3) & 7;
|
||||
modrm_rm |= (opcode >> 0) & 7;
|
||||
reg = decode_register(modrm_rm, regs, 0);
|
||||
@@ -1361,8 +1521,14 @@ static int emulate_privileged_op(struct
|
||||
break;
|
||||
|
||||
case 3: /* Read CR3 */
|
||||
- *reg = xen_pfn_to_cr3(mfn_to_gmfn(
|
||||
- v->domain, pagetable_get_pfn(v->arch.guest_table)));
|
||||
+ if ( !IS_COMPAT(v->domain) )
|
||||
+ *reg = xen_pfn_to_cr3(mfn_to_gmfn(
|
||||
+ v->domain, pagetable_get_pfn(v->arch.guest_table)));
|
||||
+#ifdef CONFIG_COMPAT
|
||||
+ else
|
||||
+ *reg = compat_pfn_to_cr3(mfn_to_gmfn(
|
||||
+ v->domain, l4e_get_pfn(*(l4_pgentry_t *)__va(pagetable_get_paddr(v->arch.guest_table)))));
|
||||
+#endif
|
||||
break;
|
||||
|
||||
case 4: /* Read CR4 */
|
||||
@@ -1379,7 +1545,7 @@ static int emulate_privileged_op(struct
|
||||
break;
|
||||
|
||||
case 0x21: /* MOV DR?,<reg> */
|
||||
- opcode = insn_fetch(u8, 1, cs, eip);
|
||||
+ opcode = insn_fetch(u8, code_base, eip, code_limit);
|
||||
modrm_reg |= (opcode >> 3) & 7;
|
||||
modrm_rm |= (opcode >> 0) & 7;
|
||||
reg = decode_register(modrm_rm, regs, 0);
|
||||
@@ -1389,7 +1555,7 @@ static int emulate_privileged_op(struct
|
||||
break;
|
||||
|
||||
case 0x22: /* MOV <reg>,CR? */
|
||||
- opcode = insn_fetch(u8, 1, cs, eip);
|
||||
+ opcode = insn_fetch(u8, code_base, eip, code_limit);
|
||||
modrm_reg |= (opcode >> 3) & 7;
|
||||
modrm_rm |= (opcode >> 0) & 7;
|
||||
reg = decode_register(modrm_rm, regs, 0);
|
||||
@@ -1412,7 +1578,12 @@ static int emulate_privileged_op(struct
|
||||
|
||||
case 3: /* Write CR3 */
|
||||
LOCK_BIGLOCK(v->domain);
|
||||
- rc = new_guest_cr3(gmfn_to_mfn(v->domain, xen_cr3_to_pfn(*reg)));
|
||||
+ if ( !IS_COMPAT(v->domain) )
|
||||
+ rc = new_guest_cr3(gmfn_to_mfn(v->domain, xen_cr3_to_pfn(*reg)));
|
||||
+#ifdef CONFIG_COMPAT
|
||||
+ else
|
||||
+ rc = new_guest_cr3(gmfn_to_mfn(v->domain, compat_cr3_to_pfn(*reg)));
|
||||
+#endif
|
||||
UNLOCK_BIGLOCK(v->domain);
|
||||
if ( rc == 0 ) /* not okay */
|
||||
goto fail;
|
||||
@@ -1432,7 +1603,7 @@ static int emulate_privileged_op(struct
|
||||
break;
|
||||
|
||||
case 0x23: /* MOV <reg>,DR? */
|
||||
- opcode = insn_fetch(u8, 1, cs, eip);
|
||||
+ opcode = insn_fetch(u8, code_base, eip, code_limit);
|
||||
modrm_reg |= (opcode >> 3) & 7;
|
||||
modrm_rm |= (opcode >> 0) & 7;
|
||||
reg = decode_register(modrm_rm, regs, 0);
|
||||
@@ -1445,18 +1616,24 @@ static int emulate_privileged_op(struct
|
||||
{
|
||||
#ifdef CONFIG_X86_64
|
||||
case MSR_FS_BASE:
|
||||
+ if ( IS_COMPAT(v->domain) )
|
||||
+ goto fail;
|
||||
if ( wrmsr_safe(MSR_FS_BASE, regs->eax, regs->edx) )
|
||||
goto fail;
|
||||
v->arch.guest_context.fs_base =
|
||||
((u64)regs->edx << 32) | regs->eax;
|
||||
break;
|
||||
case MSR_GS_BASE:
|
||||
+ if ( IS_COMPAT(v->domain) )
|
||||
+ goto fail;
|
||||
if ( wrmsr_safe(MSR_GS_BASE, regs->eax, regs->edx) )
|
||||
goto fail;
|
||||
v->arch.guest_context.gs_base_kernel =
|
||||
((u64)regs->edx << 32) | regs->eax;
|
||||
break;
|
||||
case MSR_SHADOW_GS_BASE:
|
||||
+ if ( IS_COMPAT(v->domain) )
|
||||
+ goto fail;
|
||||
if ( wrmsr_safe(MSR_SHADOW_GS_BASE, regs->eax, regs->edx) )
|
||||
goto fail;
|
||||
v->arch.guest_context.gs_base_user =
|
||||
@@ -1481,14 +1658,20 @@ static int emulate_privileged_op(struct
|
||||
{
|
||||
#ifdef CONFIG_X86_64
|
||||
case MSR_FS_BASE:
|
||||
+ if ( IS_COMPAT(v->domain) )
|
||||
+ goto fail;
|
||||
regs->eax = v->arch.guest_context.fs_base & 0xFFFFFFFFUL;
|
||||
regs->edx = v->arch.guest_context.fs_base >> 32;
|
||||
break;
|
||||
case MSR_GS_BASE:
|
||||
+ if ( IS_COMPAT(v->domain) )
|
||||
+ goto fail;
|
||||
regs->eax = v->arch.guest_context.gs_base_kernel & 0xFFFFFFFFUL;
|
||||
regs->edx = v->arch.guest_context.gs_base_kernel >> 32;
|
||||
break;
|
||||
case MSR_SHADOW_GS_BASE:
|
||||
+ if ( IS_COMPAT(v->domain) )
|
||||
+ goto fail;
|
||||
regs->eax = v->arch.guest_context.gs_base_user & 0xFFFFFFFFUL;
|
||||
regs->edx = v->arch.guest_context.gs_base_user >> 32;
|
||||
break;
|
||||
@@ -1517,6 +1700,9 @@ static int emulate_privileged_op(struct
|
||||
goto fail;
|
||||
}
|
||||
|
||||
+#undef wr_ad
|
||||
+#undef rd_ad
|
||||
+
|
||||
done:
|
||||
regs->eip = eip;
|
||||
return EXCRET_fault_fixed;
|
||||
Index: 2006-12-18/xen/arch/x86/x86_64/mm.c
|
||||
===================================================================
|
||||
--- 2006-12-18.orig/xen/arch/x86/x86_64/mm.c 2006-12-18 17:53:11.000000000 +0100
|
||||
+++ 2006-12-18/xen/arch/x86/x86_64/mm.c 2006-12-18 09:49:18.000000000 +0100
|
||||
@@ -376,7 +376,11 @@ int check_descriptor(const struct domain
|
||||
|
||||
/* All code and data segments are okay. No base/limit checking. */
|
||||
if ( (b & _SEGMENT_S) )
|
||||
- goto good;
|
||||
+ {
|
||||
+ if ( !IS_COMPAT(dom) || !(b & _SEGMENT_L) )
|
||||
+ goto good;
|
||||
+ goto bad;
|
||||
+ }
|
||||
|
||||
/* Invalid type 0 is harmless. It is used for 2nd half of a call gate. */
|
||||
if ( (b & _SEGMENT_TYPE) == 0x000 )
|
||||
Index: 2006-12-18/xen/include/asm-x86/desc.h
|
||||
===================================================================
|
||||
--- 2006-12-18.orig/xen/include/asm-x86/desc.h 2006-12-18 17:53:11.000000000 +0100
|
||||
+++ 2006-12-18/xen/include/asm-x86/desc.h 2006-12-18 09:49:18.000000000 +0100
|
||||
@@ -113,12 +113,19 @@
|
||||
|
||||
/* These are bitmasks for the high 32 bits of a descriptor table entry. */
|
||||
#define _SEGMENT_TYPE (15<< 8)
|
||||
+#define _SEGMENT_WR ( 1<< 9) /* Writeable (data) or Readable (code)
|
||||
+ segment */
|
||||
#define _SEGMENT_EC ( 1<<10) /* Expand-down or Conforming segment */
|
||||
#define _SEGMENT_CODE ( 1<<11) /* Code (vs data) segment for non-system
|
||||
segments */
|
||||
#define _SEGMENT_S ( 1<<12) /* System descriptor (yes iff S==0) */
|
||||
#define _SEGMENT_DPL ( 3<<13) /* Descriptor Privilege Level */
|
||||
#define _SEGMENT_P ( 1<<15) /* Segment Present */
|
||||
+#ifdef __x86_64
|
||||
+#define _SEGMENT_L ( 1<<21) /* 64-bit segment */
|
||||
+#else
|
||||
+#define _SEGMENT_L 0
|
||||
+#endif
|
||||
#define _SEGMENT_DB ( 1<<22) /* 16- or 32-bit segment */
|
||||
#define _SEGMENT_G ( 1<<23) /* Granularity */
|
||||
|
||||
Index: 2006-12-18/xen/include/asm-x86/mm.h
|
||||
===================================================================
|
||||
--- 2006-12-18.orig/xen/include/asm-x86/mm.h 2006-12-18 17:53:11.000000000 +0100
|
||||
+++ 2006-12-18/xen/include/asm-x86/mm.h 2006-12-18 09:49:18.000000000 +0100
|
||||
@@ -279,6 +279,11 @@ int check_descriptor(const struct domain
|
||||
|
||||
#define INVALID_MFN (~0UL)
|
||||
|
||||
+#ifdef CONFIG_COMPAT
|
||||
+#define compat_pfn_to_cr3(pfn) (((unsigned)(pfn) << 12) | ((unsigned)(pfn) >> 20))
|
||||
+#define compat_cr3_to_pfn(cr3) (((unsigned)(cr3) >> 12) | ((unsigned)(cr3) << 20))
|
||||
+#endif
|
||||
+
|
||||
#ifdef MEMORY_GUARD
|
||||
void memguard_init(void);
|
||||
void memguard_guard_range(void *p, unsigned long l);
|
||||
Index: 2006-12-18/xen/include/asm-x86/x86_32/uaccess.h
|
||||
===================================================================
|
||||
--- 2006-12-18.orig/xen/include/asm-x86/x86_32/uaccess.h 2006-12-18 17:53:11.000000000 +0100
|
||||
+++ 2006-12-18/xen/include/asm-x86/x86_32/uaccess.h 2006-12-18 09:49:18.000000000 +0100
|
||||
@@ -83,7 +83,7 @@ do { \
|
||||
case 2: __get_user_asm(x,ptr,retval,"w","w","=r",errret);break; \
|
||||
case 4: __get_user_asm(x,ptr,retval,"l","","=r",errret);break; \
|
||||
case 8: __get_user_u64(x,ptr,retval,errret);break; \
|
||||
- default: (x) = __get_user_bad(); \
|
||||
+ default: __get_user_bad(); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
Index: 2006-12-18/xen/include/asm-x86/x86_64/uaccess.h
|
||||
===================================================================
|
||||
--- 2006-12-18.orig/xen/include/asm-x86/x86_64/uaccess.h 2006-12-18 17:53:11.000000000 +0100
|
||||
+++ 2006-12-18/xen/include/asm-x86/x86_64/uaccess.h 2006-12-18 09:49:18.000000000 +0100
|
||||
@@ -48,7 +48,7 @@ do { \
|
||||
case 2: __get_user_asm(x,ptr,retval,"w","w","=r",errret);break; \
|
||||
case 4: __get_user_asm(x,ptr,retval,"l","k","=r",errret);break; \
|
||||
case 8: __get_user_asm(x,ptr,retval,"q","","=r",errret); break; \
|
||||
- default: (x) = __get_user_bad(); \
|
||||
+ default: __get_user_bad(); \
|
||||
} \
|
||||
} while (0)
|
||||
|
110
32on64-fixes.patch
Normal file
110
32on64-fixes.patch
Normal file
@ -0,0 +1,110 @@
|
||||
Index: 2007-01-08/xen/arch/x86/traps.c
|
||||
===================================================================
|
||||
--- 2007-01-08.orig/xen/arch/x86/traps.c 2007-01-25 13:53:38.000000000 +0100
|
||||
+++ 2007-01-08/xen/arch/x86/traps.c 2007-01-25 16:01:23.000000000 +0100
|
||||
@@ -1162,7 +1162,9 @@ static int emulate_privileged_op(struct
|
||||
goto fail;
|
||||
op_default = op_bytes = (ar & (_SEGMENT_L|_SEGMENT_DB)) ? 4 : 2;
|
||||
ad_default = ad_bytes = (ar & _SEGMENT_L) ? 8 : op_default;
|
||||
- if ( !(ar & (_SEGMENT_CODE|_SEGMENT_S|_SEGMENT_P)) )
|
||||
+ if ( !(ar & _SEGMENT_S) ||
|
||||
+ !(ar & _SEGMENT_P) ||
|
||||
+ !(ar & _SEGMENT_CODE) )
|
||||
goto fail;
|
||||
|
||||
/* emulating only opcodes not allowing SS to be default */
|
||||
@@ -1246,7 +1248,8 @@ static int emulate_privileged_op(struct
|
||||
&data_base, &data_limit, &ar,
|
||||
_SEGMENT_WR|_SEGMENT_S|_SEGMENT_DPL|_SEGMENT_P) )
|
||||
goto fail;
|
||||
- if ( !(ar & (_SEGMENT_S|_SEGMENT_P)) ||
|
||||
+ if ( !(ar & _SEGMENT_S) ||
|
||||
+ !(ar & _SEGMENT_P) ||
|
||||
(opcode & 2 ?
|
||||
(ar & _SEGMENT_CODE) && !(ar & _SEGMENT_WR) :
|
||||
(ar & _SEGMENT_CODE) || !(ar & _SEGMENT_WR)) )
|
||||
Index: 2007-01-08/xen/arch/x86/x86_64/compat/entry.S
|
||||
===================================================================
|
||||
--- 2007-01-08.orig/xen/arch/x86/x86_64/compat/entry.S 2007-01-25 13:53:38.000000000 +0100
|
||||
+++ 2007-01-08/xen/arch/x86/x86_64/compat/entry.S 2007-01-25 16:01:22.000000000 +0100
|
||||
@@ -23,7 +23,9 @@ ENTRY(compat_hypercall)
|
||||
movq %rsp,%rdi
|
||||
movl $0xDEADBEEF,%eax
|
||||
rep stosq
|
||||
- popq %r9 ; popq %r8 ; popq %rcx; popq %rdx; popq %rsi; popq %rdi
|
||||
+ popq %r8 ; popq %r9 ; xchgl %r8d,%r9d
|
||||
+ popq %rdx; popq %rcx; xchgl %edx,%ecx
|
||||
+ popq %rdi; popq %rsi; xchgl %edi,%esi
|
||||
movl UREGS_rax(%rsp),%eax
|
||||
pushq %rax
|
||||
pushq UREGS_rip+8(%rsp)
|
||||
@@ -31,8 +33,9 @@ ENTRY(compat_hypercall)
|
||||
movl %eax,%eax
|
||||
movl %ebp,%r9d
|
||||
movl %edi,%r8d
|
||||
- xchgl %ecx,%esi
|
||||
+ xchgl %ecx,%esi
|
||||
movl UREGS_rbx(%rsp),%edi
|
||||
+ movl %edx,%edx
|
||||
#endif
|
||||
leaq compat_hypercall_table(%rip),%r10
|
||||
PERFC_INCR(PERFC_hypercalls, %rax)
|
||||
Index: 2007-01-08/xen/arch/x86/x86_64/compat/mm.c
|
||||
===================================================================
|
||||
--- 2007-01-08.orig/xen/arch/x86/x86_64/compat/mm.c 2007-01-12 17:22:50.000000000 +0100
|
||||
+++ 2007-01-08/xen/arch/x86/x86_64/compat/mm.c 2007-01-10 16:06:16.000000000 +0100
|
||||
@@ -1,6 +1,7 @@
|
||||
#ifdef CONFIG_COMPAT
|
||||
|
||||
#include <xen/event.h>
|
||||
+#include <xen/multicall.h>
|
||||
#include <compat/memory.h>
|
||||
#include <compat/xen.h>
|
||||
|
||||
@@ -289,20 +290,27 @@ int compat_mmuext_op(XEN_GUEST_HANDLE(mm
|
||||
if ( err == __HYPERVISOR_mmuext_op )
|
||||
{
|
||||
struct cpu_user_regs *regs = guest_cpu_user_regs();
|
||||
- unsigned int left = regs->ecx & ~MMU_UPDATE_PREEMPTED;
|
||||
+ struct mc_state *mcs = &this_cpu(mc_state);
|
||||
+ unsigned int arg1 = !test_bit(_MCSF_in_multicall, &mcs->flags)
|
||||
+ ? regs->ecx
|
||||
+ : mcs->call.args[1];
|
||||
+ unsigned int left = arg1 & ~MMU_UPDATE_PREEMPTED;
|
||||
|
||||
- BUG_ON(!(regs->ecx & MMU_UPDATE_PREEMPTED));
|
||||
+ BUG_ON(left == arg1);
|
||||
BUG_ON(left > count);
|
||||
guest_handle_add_offset(nat_ops, count - left);
|
||||
BUG_ON(left + i < count);
|
||||
guest_handle_add_offset(cmp_uops, (signed int)(count - left - i));
|
||||
left = 1;
|
||||
BUG_ON(!hypercall_xlat_continuation(&left, 0x01, nat_ops, cmp_uops));
|
||||
- BUG_ON(left != regs->ecx);
|
||||
- regs->ecx += count - i;
|
||||
+ BUG_ON(left != arg1);
|
||||
+ if (!test_bit(_MCSF_in_multicall, &mcs->flags))
|
||||
+ regs->_ecx += count - i;
|
||||
+ else
|
||||
+ mcs->compat_call.args[1] += count - i;
|
||||
}
|
||||
else
|
||||
- BUG_ON(rc > 0);
|
||||
+ BUG_ON(err > 0);
|
||||
rc = err;
|
||||
}
|
||||
|
||||
Index: 2007-01-08/xen/include/asm-x86/x86_64/uaccess.h
|
||||
===================================================================
|
||||
--- 2007-01-08.orig/xen/include/asm-x86/x86_64/uaccess.h 2006-12-18 09:49:18.000000000 +0100
|
||||
+++ 2007-01-08/xen/include/asm-x86/x86_64/uaccess.h 2007-01-25 15:18:37.000000000 +0100
|
||||
@@ -20,7 +20,8 @@
|
||||
#define __compat_addr_ok(addr) \
|
||||
((unsigned long)(addr) < HYPERVISOR_COMPAT_VIRT_START(current->domain))
|
||||
|
||||
-#define compat_access_ok(addr, size) __compat_addr_ok((addr) + (size))
|
||||
+#define compat_access_ok(addr, size) \
|
||||
+ __compat_addr_ok((unsigned long)(addr) + ((size) ? (size) - 1 : 0))
|
||||
|
||||
#define compat_array_access_ok(addr,count,size) \
|
||||
(likely((count) < (~0U / (size))) && \
|
281
32on64-gnttabop.patch
Normal file
281
32on64-gnttabop.patch
Normal file
@ -0,0 +1,281 @@
|
||||
Enable compatibility mode operation for HYPERVISOR_grant_table_op.
|
||||
|
||||
Index: 2006-12-18/xen/arch/x86/x86_64/compat/entry.S
|
||||
===================================================================
|
||||
--- 2006-12-18.orig/xen/arch/x86/x86_64/compat/entry.S 2006-12-18 09:49:57.000000000 +0100
|
||||
+++ 2006-12-18/xen/arch/x86/x86_64/compat/entry.S 2006-12-18 09:50:00.000000000 +0100
|
||||
@@ -279,7 +279,6 @@ CFIX14:
|
||||
.section .rodata, "a", @progbits
|
||||
|
||||
#define compat_platform_op domain_crash_synchronous
|
||||
-#define compat_grant_table_op domain_crash_synchronous
|
||||
#define compat_acm_op domain_crash_synchronous
|
||||
#define compat_xenoprof_op domain_crash_synchronous
|
||||
#define compat_sysctl domain_crash_synchronous
|
||||
Index: 2006-12-18/xen/common/Makefile
|
||||
===================================================================
|
||||
--- 2006-12-18.orig/xen/common/Makefile 2006-12-18 09:49:57.000000000 +0100
|
||||
+++ 2006-12-18/xen/common/Makefile 2006-12-18 09:50:00.000000000 +0100
|
||||
@@ -42,5 +42,6 @@ version.o: $(BASEDIR)/include/xen/compil
|
||||
|
||||
ifeq ($(CONFIG_COMPAT),y)
|
||||
# extra dependencies
|
||||
+grant_table.o: compat/grant_table.c
|
||||
schedule.o: compat/schedule.c
|
||||
endif
|
||||
Index: 2006-12-18/xen/common/compat/grant_table.c
|
||||
===================================================================
|
||||
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
|
||||
+++ 2006-12-18/xen/common/compat/grant_table.c 2006-12-18 09:50:00.000000000 +0100
|
||||
@@ -0,0 +1,218 @@
|
||||
+/******************************************************************************
|
||||
+ * common/compat/grant_table.c
|
||||
+ *
|
||||
+ */
|
||||
+
|
||||
+#include <compat/grant_table.h>
|
||||
+
|
||||
+#define xen_grant_entry grant_entry
|
||||
+CHECK_grant_entry;
|
||||
+#undef xen_grant_entry
|
||||
+
|
||||
+#define xen_gnttab_map_grant_ref gnttab_map_grant_ref
|
||||
+CHECK_gnttab_map_grant_ref;
|
||||
+#undef xen_gnttab_map_grant_ref
|
||||
+
|
||||
+#define xen_gnttab_unmap_grant_ref gnttab_unmap_grant_ref
|
||||
+CHECK_gnttab_unmap_grant_ref;
|
||||
+#undef xen_gnttab_unmap_grant_ref
|
||||
+
|
||||
+DEFINE_XEN_GUEST_HANDLE(gnttab_setup_table_compat_t);
|
||||
+DEFINE_XEN_GUEST_HANDLE(gnttab_transfer_compat_t);
|
||||
+DEFINE_XEN_GUEST_HANDLE(gnttab_copy_compat_t);
|
||||
+
|
||||
+#define xen_gnttab_dump_table gnttab_dump_table
|
||||
+CHECK_gnttab_dump_table;
|
||||
+#undef xen_gnttab_dump_table
|
||||
+
|
||||
+int compat_grant_table_op(unsigned int cmd,
|
||||
+ XEN_GUEST_HANDLE(void) cmp_uop,
|
||||
+ unsigned int count)
|
||||
+{
|
||||
+ int rc = 0;
|
||||
+ unsigned int i;
|
||||
+
|
||||
+ switch ( cmd )
|
||||
+ {
|
||||
+#define CASE(name) \
|
||||
+ case GNTTABOP_##name: \
|
||||
+ if ( unlikely(!guest_handle_okay(guest_handle_cast(cmp_uop, \
|
||||
+ gnttab_##name##_compat_t), \
|
||||
+ count)) ) \
|
||||
+ rc = -EFAULT; \
|
||||
+ break
|
||||
+
|
||||
+#ifndef CHECK_gnttab_map_grant_ref
|
||||
+ CASE(map_grant_ref);
|
||||
+#endif
|
||||
+
|
||||
+#ifndef CHECK_gnttab_unmap_grant_ref
|
||||
+ CASE(unmap_grant_ref);
|
||||
+#endif
|
||||
+
|
||||
+#ifndef CHECK_gnttab_setup_table
|
||||
+ CASE(setup_table);
|
||||
+#endif
|
||||
+
|
||||
+#ifndef CHECK_gnttab_transfer
|
||||
+ CASE(transfer);
|
||||
+#endif
|
||||
+
|
||||
+#ifndef CHECK_gnttab_copy
|
||||
+ CASE(copy);
|
||||
+#endif
|
||||
+
|
||||
+#ifndef CHECK_gnttab_dump_table
|
||||
+ CASE(dump_table);
|
||||
+#endif
|
||||
+
|
||||
+#undef CASE
|
||||
+ default:
|
||||
+ return do_grant_table_op(cmd, cmp_uop, count);
|
||||
+ }
|
||||
+
|
||||
+ if ( count > 512 )
|
||||
+ rc = -EINVAL;
|
||||
+
|
||||
+ for ( i = 0; i < count && rc == 0; )
|
||||
+ {
|
||||
+ unsigned int n;
|
||||
+ union {
|
||||
+ XEN_GUEST_HANDLE(void) uop;
|
||||
+ struct gnttab_setup_table *setup;
|
||||
+ struct gnttab_transfer *xfer;
|
||||
+ struct gnttab_copy *copy;
|
||||
+ } nat;
|
||||
+ union {
|
||||
+ struct compat_gnttab_setup_table setup;
|
||||
+ struct compat_gnttab_transfer xfer;
|
||||
+ struct compat_gnttab_copy copy;
|
||||
+ } cmp;
|
||||
+
|
||||
+ set_xen_guest_handle(nat.uop, (void *)COMPAT_ARG_XLAT_VIRT_START(current->vcpu_id));
|
||||
+ switch ( cmd )
|
||||
+ {
|
||||
+ case GNTTABOP_setup_table:
|
||||
+ if ( unlikely(count > 1) )
|
||||
+ rc = -EINVAL;
|
||||
+ else if ( unlikely(__copy_from_guest(&cmp.setup, cmp_uop, 1)) )
|
||||
+ rc = -EFAULT;
|
||||
+ else if ( unlikely(!compat_handle_okay(cmp.setup.frame_list, cmp.setup.nr_frames)) )
|
||||
+ rc = -EFAULT;
|
||||
+ else
|
||||
+ {
|
||||
+ BUILD_BUG_ON((COMPAT_ARG_XLAT_SIZE - sizeof(*nat.setup)) / sizeof(*nat.setup->frame_list.p) < NR_GRANT_FRAMES);
|
||||
+#define XLAT_gnttab_setup_table_HNDL_frame_list(_d_, _s_) \
|
||||
+ set_xen_guest_handle((_d_)->frame_list, (unsigned long *)(nat.setup + 1))
|
||||
+ XLAT_gnttab_setup_table(nat.setup, &cmp.setup);
|
||||
+#undef XLAT_gnttab_setup_table_HNDL_frame_list
|
||||
+ rc = gnttab_setup_table(guest_handle_cast(nat.uop, gnttab_setup_table_t), 1);
|
||||
+ }
|
||||
+ if ( rc == 0 )
|
||||
+ {
|
||||
+ BUG_ON(nat.setup->nr_frames > NR_GRANT_FRAMES);
|
||||
+#define XLAT_gnttab_setup_table_HNDL_frame_list(_d_, _s_) \
|
||||
+ do \
|
||||
+ { \
|
||||
+ if ( (_s_)->status == GNTST_okay ) \
|
||||
+ { \
|
||||
+ for ( i = 0; i < (_s_)->nr_frames; ++i ) \
|
||||
+ { \
|
||||
+ unsigned int frame = (_s_)->frame_list.p[i]; \
|
||||
+ BUG_ON(frame != (_s_)->frame_list.p[i]); \
|
||||
+ (void)__copy_to_compat_offset((_d_)->frame_list, i, &frame, 1); \
|
||||
+ } \
|
||||
+ } \
|
||||
+ } while (0)
|
||||
+ XLAT_gnttab_setup_table(&cmp.setup, nat.setup);
|
||||
+#undef XLAT_gnttab_setup_table_HNDL_frame_list
|
||||
+ if ( unlikely(__copy_to_guest(cmp_uop, &cmp.setup, 1)) )
|
||||
+ rc = -EFAULT;
|
||||
+ else
|
||||
+ i = 1;
|
||||
+ }
|
||||
+ break;
|
||||
+
|
||||
+ case GNTTABOP_transfer:
|
||||
+ for ( n = 0; i < COMPAT_ARG_XLAT_SIZE / sizeof(*nat.xfer) && i < count && rc == 0; ++i, ++n )
|
||||
+ {
|
||||
+ if ( unlikely(__copy_from_guest_offset(&cmp.xfer, cmp_uop, i, 1)) )
|
||||
+ rc = -EFAULT;
|
||||
+ else
|
||||
+ {
|
||||
+ XLAT_gnttab_transfer(nat.xfer + n, &cmp.xfer);
|
||||
+ }
|
||||
+ }
|
||||
+ if ( rc == 0 )
|
||||
+ rc = gnttab_transfer(guest_handle_cast(nat.uop, gnttab_transfer_t), n);
|
||||
+ if ( rc == 0 )
|
||||
+ {
|
||||
+ XEN_GUEST_HANDLE(gnttab_transfer_compat_t) xfer;
|
||||
+
|
||||
+ xfer = guest_handle_cast(cmp_uop, gnttab_transfer_compat_t);
|
||||
+ guest_handle_add_offset(xfer, i);
|
||||
+ while ( n-- )
|
||||
+ {
|
||||
+ guest_handle_add_offset(xfer, -1);
|
||||
+ if ( __copy_field_to_guest(xfer, nat.xfer, status) )
|
||||
+ rc = -EFAULT;
|
||||
+ }
|
||||
+ }
|
||||
+ break;
|
||||
+
|
||||
+ case GNTTABOP_copy:
|
||||
+ for ( n = 0; i < COMPAT_ARG_XLAT_SIZE / sizeof(*nat.copy) && i < count && rc == 0; ++i, ++n )
|
||||
+ {
|
||||
+ if ( unlikely(__copy_from_guest_offset(&cmp.copy, cmp_uop, i, 1)) )
|
||||
+ rc = -EFAULT;
|
||||
+ else
|
||||
+ {
|
||||
+ enum XLAT_gnttab_copy_source_u source_u;
|
||||
+ enum XLAT_gnttab_copy_dest_u dest_u;
|
||||
+
|
||||
+ if ( cmp.copy.flags & GNTCOPY_source_gref )
|
||||
+ source_u = XLAT_gnttab_copy_source_u_ref;
|
||||
+ else
|
||||
+ source_u = XLAT_gnttab_copy_source_u_gmfn;
|
||||
+ if ( cmp.copy.flags & GNTCOPY_dest_gref )
|
||||
+ dest_u = XLAT_gnttab_copy_dest_u_ref;
|
||||
+ else
|
||||
+ dest_u = XLAT_gnttab_copy_dest_u_gmfn;
|
||||
+ XLAT_gnttab_copy(nat.copy + n, &cmp.copy);
|
||||
+ }
|
||||
+ }
|
||||
+ if ( rc == 0 )
|
||||
+ rc = gnttab_copy(guest_handle_cast(nat.uop, gnttab_copy_t), n);
|
||||
+ if ( rc == 0 )
|
||||
+ {
|
||||
+ XEN_GUEST_HANDLE(gnttab_copy_compat_t) copy;
|
||||
+
|
||||
+ copy = guest_handle_cast(cmp_uop, gnttab_copy_compat_t);
|
||||
+ guest_handle_add_offset(copy, i);
|
||||
+ while ( n-- )
|
||||
+ {
|
||||
+ guest_handle_add_offset(copy, -1);
|
||||
+ if ( __copy_field_to_guest(copy, nat.copy, status) )
|
||||
+ rc = -EFAULT;
|
||||
+ }
|
||||
+ }
|
||||
+ break;
|
||||
+
|
||||
+ default:
|
||||
+ domain_crash(current->domain);
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return rc;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * Local variables:
|
||||
+ * mode: C
|
||||
+ * c-set-style: "BSD"
|
||||
+ * c-basic-offset: 4
|
||||
+ * tab-width: 4
|
||||
+ * indent-tabs-mode: nil
|
||||
+ * End:
|
||||
+ */
|
||||
Index: 2006-12-18/xen/common/grant_table.c
|
||||
===================================================================
|
||||
--- 2006-12-18.orig/xen/common/grant_table.c 2006-12-13 11:15:54.000000000 +0100
|
||||
+++ 2006-12-18/xen/common/grant_table.c 2006-12-18 09:50:00.000000000 +0100
|
||||
@@ -1048,6 +1048,10 @@ do_grant_table_op(
|
||||
return rc;
|
||||
}
|
||||
|
||||
+#ifdef CONFIG_COMPAT
|
||||
+#include "compat/grant_table.c"
|
||||
+#endif
|
||||
+
|
||||
int
|
||||
grant_table_create(
|
||||
struct domain *d)
|
||||
Index: 2006-12-18/xen/include/xlat.lst
|
||||
===================================================================
|
||||
--- 2006-12-18.orig/xen/include/xlat.lst 2006-12-18 09:49:57.000000000 +0100
|
||||
+++ 2006-12-18/xen/include/xlat.lst 2006-12-18 09:50:00.000000000 +0100
|
||||
@@ -20,6 +20,13 @@
|
||||
? evtchn_send event_channel.h
|
||||
? evtchn_status event_channel.h
|
||||
? evtchn_unmask event_channel.h
|
||||
+! gnttab_copy grant_table.h
|
||||
+? gnttab_dump_table grant_table.h
|
||||
+? gnttab_map_grant_ref grant_table.h
|
||||
+! gnttab_setup_table grant_table.h
|
||||
+! gnttab_transfer grant_table.h
|
||||
+? gnttab_unmap_grant_ref grant_table.h
|
||||
+? grant_entry grant_table.h
|
||||
! add_to_physmap memory.h
|
||||
! foreign_memory_map memory.h
|
||||
! memory_exchange memory.h
|
184
32on64-hvm.patch
Normal file
184
32on64-hvm.patch
Normal file
@ -0,0 +1,184 @@
|
||||
unstable c/s 13276: Support for save and restore of compatibility guests
|
||||
|
||||
Signed-off-by: Emmanuel Ackaouy <ack@xensource.com>
|
||||
|
||||
unstable c/s 13279: Initial support for HVM compat guests
|
||||
|
||||
Signed-off-by: Emmanuel Ackaouy <ack@xensource.com>
|
||||
|
||||
Index: 2007-01-31/tools/libxc/xc_linux_save.c
|
||||
===================================================================
|
||||
--- 2007-01-31.orig/tools/libxc/xc_linux_save.c 2007-01-31 09:19:49.000000000 +0100
|
||||
+++ 2007-01-31/tools/libxc/xc_linux_save.c 2007-01-31 09:33:01.000000000 +0100
|
||||
@@ -44,6 +44,7 @@ static xen_pfn_t *live_p2m = NULL;
|
||||
|
||||
/* Live mapping of system MFN to PFN table. */
|
||||
static xen_pfn_t *live_m2p = NULL;
|
||||
+static unsigned long m2p_mfn0;
|
||||
|
||||
/* grep fodder: machine_to_phys */
|
||||
|
||||
@@ -467,13 +468,23 @@ static int canonicalize_pagetable(unsign
|
||||
** that this check will fail for other L2s.
|
||||
*/
|
||||
if (pt_levels == 3 && type == XEN_DOMCTL_PFINFO_L2TAB) {
|
||||
+ int hstart;
|
||||
+ unsigned long he;
|
||||
|
||||
-/* XXX index of the L2 entry in PAE mode which holds the guest LPT */
|
||||
-#define PAE_GLPT_L2ENTRY (495)
|
||||
- pte = ((const uint64_t*)spage)[PAE_GLPT_L2ENTRY];
|
||||
+ hstart = (hvirt_start >> L2_PAGETABLE_SHIFT_PAE) & 0x1ff;
|
||||
+ he = ((const uint64_t *) spage)[hstart];
|
||||
|
||||
- if(((pte >> PAGE_SHIFT) & 0x0fffffff) == live_p2m[pfn])
|
||||
- xen_start = (hvirt_start >> L2_PAGETABLE_SHIFT_PAE) & 0x1ff;
|
||||
+ if ( ((he >> PAGE_SHIFT) & 0x0fffffff) == m2p_mfn0 ) {
|
||||
+ /* hvirt starts with xen stuff... */
|
||||
+ xen_start = hstart;
|
||||
+ } else if ( hvirt_start != 0xf5800000 ) {
|
||||
+ /* old L2s from before hole was shrunk... */
|
||||
+ hstart = (0xf5800000 >> L2_PAGETABLE_SHIFT_PAE) & 0x1ff;
|
||||
+ he = ((const uint64_t *) spage)[hstart];
|
||||
+
|
||||
+ if( ((he >> PAGE_SHIFT) & 0x0fffffff) == m2p_mfn0 )
|
||||
+ xen_start = hstart;
|
||||
+ }
|
||||
}
|
||||
|
||||
if (pt_levels == 4 && type == XEN_DOMCTL_PFINFO_L4TAB) {
|
||||
@@ -577,6 +588,8 @@ static xen_pfn_t *xc_map_m2p(int xc_hand
|
||||
return NULL;
|
||||
}
|
||||
|
||||
+ m2p_mfn0 = entries[0].mfn;
|
||||
+
|
||||
free(extent_start);
|
||||
free(entries);
|
||||
|
||||
Index: 2007-01-31/tools/libxc/xg_save_restore.h
|
||||
===================================================================
|
||||
--- 2007-01-31.orig/tools/libxc/xg_save_restore.h 2007-01-08 14:16:35.000000000 +0100
|
||||
+++ 2007-01-31/tools/libxc/xg_save_restore.h 2007-01-31 09:33:01.000000000 +0100
|
||||
@@ -53,8 +53,17 @@ static int get_platform_info(int xc_hand
|
||||
|
||||
*hvirt_start = xen_params.virt_start;
|
||||
|
||||
+ /*
|
||||
+ * XXX For now, 32bit dom0's can only save/restore 32bit domUs
|
||||
+ * on 64bit hypervisors, so no need to check which type of domain
|
||||
+ * we're dealing with.
|
||||
+ */
|
||||
if (strstr(xen_caps, "xen-3.0-x86_64"))
|
||||
+#if defined(__i386__)
|
||||
+ *pt_levels = 3;
|
||||
+#else
|
||||
*pt_levels = 4;
|
||||
+#endif
|
||||
else if (strstr(xen_caps, "xen-3.0-x86_32p"))
|
||||
*pt_levels = 3;
|
||||
else if (strstr(xen_caps, "xen-3.0-x86_32"))
|
||||
Index: 2007-01-31/xen/arch/x86/domain.c
|
||||
===================================================================
|
||||
--- 2007-01-31.orig/xen/arch/x86/domain.c 2007-01-31 09:31:01.000000000 +0100
|
||||
+++ 2007-01-31/xen/arch/x86/domain.c 2007-01-31 09:34:52.000000000 +0100
|
||||
@@ -1405,7 +1405,11 @@ void domain_relinquish_resources(struct
|
||||
#ifdef CONFIG_COMPAT
|
||||
if ( IS_COMPAT(d) )
|
||||
{
|
||||
- pfn = l4e_get_pfn(*(l4_pgentry_t *)__va(pagetable_get_paddr(v->arch.guest_table)));
|
||||
+ if ( is_hvm_vcpu(v) )
|
||||
+ pfn = pagetable_get_pfn(v->arch.guest_table);
|
||||
+ else
|
||||
+ pfn = l4e_get_pfn(*(l4_pgentry_t *)__va(pagetable_get_paddr(v->arch.guest_table)));
|
||||
+
|
||||
if ( pfn != 0 )
|
||||
{
|
||||
if ( shadow_mode_refcounts(d) )
|
||||
Index: 2007-01-31/xen/arch/x86/domctl.c
|
||||
===================================================================
|
||||
--- 2007-01-31.orig/xen/arch/x86/domctl.c 2007-01-31 09:29:26.000000000 +0100
|
||||
+++ 2007-01-31/xen/arch/x86/domctl.c 2007-01-31 09:33:01.000000000 +0100
|
||||
@@ -356,7 +356,10 @@ void arch_get_info_guest(struct vcpu *v,
|
||||
c.nat->ctrlreg[3] = xen_pfn_to_cr3(pagetable_get_pfn(v->arch.guest_table));
|
||||
#ifdef CONFIG_COMPAT
|
||||
else
|
||||
- c.cmp->ctrlreg[3] = compat_pfn_to_cr3(pagetable_get_pfn(v->arch.guest_table));
|
||||
+ {
|
||||
+ l4_pgentry_t *l4e = __va(pagetable_get_paddr(v->arch.guest_table));
|
||||
+ c.cmp->ctrlreg[3] = compat_pfn_to_cr3(l4e_get_pfn(*l4e));
|
||||
+ }
|
||||
#endif
|
||||
|
||||
c(vm_assist = v->domain->vm_assist);
|
||||
Index: 2007-01-31/xen/arch/x86/hvm/intercept.c
|
||||
===================================================================
|
||||
--- 2007-01-31.orig/xen/arch/x86/hvm/intercept.c 2006-12-13 11:15:53.000000000 +0100
|
||||
+++ 2007-01-31/xen/arch/x86/hvm/intercept.c 2007-01-31 09:34:52.000000000 +0100
|
||||
@@ -180,7 +180,7 @@ int hvm_buffered_io_intercept(ioreq_t *p
|
||||
spin_lock(buffered_io_lock);
|
||||
|
||||
if ( buffered_iopage->write_pointer - buffered_iopage->read_pointer ==
|
||||
- (unsigned long)IOREQ_BUFFER_SLOT_NUM ) {
|
||||
+ (unsigned int)IOREQ_BUFFER_SLOT_NUM ) {
|
||||
/* the queue is full.
|
||||
* send the iopacket through the normal path.
|
||||
* NOTE: The arithimetic operation could handle the situation for
|
||||
Index: 2007-01-31/xen/arch/x86/x86_64/compat/entry.S
|
||||
===================================================================
|
||||
--- 2007-01-31.orig/xen/arch/x86/x86_64/compat/entry.S 2007-01-31 09:29:27.000000000 +0100
|
||||
+++ 2007-01-31/xen/arch/x86/x86_64/compat/entry.S 2007-01-31 09:34:52.000000000 +0100
|
||||
@@ -313,7 +313,7 @@ ENTRY(compat_hypercall_table)
|
||||
.quad compat_xenoprof_op
|
||||
.quad do_event_channel_op
|
||||
.quad compat_physdev_op
|
||||
- .quad compat_ni_hypercall
|
||||
+ .quad do_hvm_op
|
||||
.quad compat_sysctl /* 35 */
|
||||
.quad compat_domctl
|
||||
.quad compat_kexec_op
|
||||
@@ -356,7 +356,7 @@ ENTRY(compat_hypercall_args_table)
|
||||
.byte 2 /* compat_xenoprof_op */
|
||||
.byte 2 /* compat_event_channel_op */
|
||||
.byte 2 /* compat_physdev_op */
|
||||
- .byte 0 /* compat_ni_hypercall */
|
||||
+ .byte 2 /* do_hvm_op */
|
||||
.byte 1 /* compat_sysctl */ /* 35 */
|
||||
.byte 1 /* compat_domctl */
|
||||
.byte 2 /* compat_kexec_op */
|
||||
Index: 2007-01-31/xen/include/asm-x86/x86_64/page.h
|
||||
===================================================================
|
||||
--- 2007-01-31.orig/xen/include/asm-x86/x86_64/page.h 2007-01-31 09:29:11.000000000 +0100
|
||||
+++ 2007-01-31/xen/include/asm-x86/x86_64/page.h 2007-01-31 09:33:01.000000000 +0100
|
||||
@@ -96,7 +96,7 @@ typedef l4_pgentry_t root_pgentry_t;
|
||||
#define L3_DISALLOW_MASK (BASE_DISALLOW_MASK | 0x180U /* must-be-zero */)
|
||||
#define L4_DISALLOW_MASK (BASE_DISALLOW_MASK | 0x180U /* must-be-zero */)
|
||||
|
||||
-#define COMPAT_L3_DISALLOW_MASK 0xFFFFF1E6U /* must-be-zero */
|
||||
+#define COMPAT_L3_DISALLOW_MASK L3_DISALLOW_MASK
|
||||
|
||||
#define PAGE_HYPERVISOR (__PAGE_HYPERVISOR | _PAGE_GLOBAL)
|
||||
#define PAGE_HYPERVISOR_NOCACHE (__PAGE_HYPERVISOR_NOCACHE | _PAGE_GLOBAL)
|
||||
Index: 2007-01-31/xen/include/public/hvm/ioreq.h
|
||||
===================================================================
|
||||
--- 2007-01-31.orig/xen/include/public/hvm/ioreq.h 2006-12-13 11:15:56.000000000 +0100
|
||||
+++ 2007-01-31/xen/include/public/hvm/ioreq.h 2007-01-31 09:34:52.000000000 +0100
|
||||
@@ -56,6 +56,7 @@ struct ioreq {
|
||||
uint8_t dir:1; /* 1=read, 0=write */
|
||||
uint8_t df:1;
|
||||
uint8_t type; /* I/O type */
|
||||
+ uint8_t _pad0[6];
|
||||
uint64_t io_count; /* How many IO done on a vcpu */
|
||||
};
|
||||
typedef struct ioreq ioreq_t;
|
||||
@@ -74,8 +75,8 @@ typedef struct shared_iopage shared_iopa
|
||||
|
||||
#define IOREQ_BUFFER_SLOT_NUM 80
|
||||
struct buffered_iopage {
|
||||
- unsigned long read_pointer;
|
||||
- unsigned long write_pointer;
|
||||
+ unsigned int read_pointer;
|
||||
+ unsigned int write_pointer;
|
||||
ioreq_t ioreq[IOREQ_BUFFER_SLOT_NUM];
|
||||
}; /* sizeof this structure must be in one page */
|
||||
typedef struct buffered_iopage buffered_iopage_t;
|
900
32on64-hypercall.patch
Normal file
900
32on64-hypercall.patch
Normal file
@ -0,0 +1,900 @@
|
||||
Add entry points for handling hypercalls from and returning to
|
||||
compatibility mode guests.
|
||||
|
||||
Index: 2006-12-18/xen/arch/x86/traps.c
|
||||
===================================================================
|
||||
--- 2006-12-18.orig/xen/arch/x86/traps.c 2006-12-18 09:37:45.000000000 +0100
|
||||
+++ 2006-12-18/xen/arch/x86/traps.c 2006-12-18 09:43:08.000000000 +0100
|
||||
@@ -139,6 +139,12 @@ static void show_guest_stack(struct cpu_
|
||||
if ( is_hvm_vcpu(current) )
|
||||
return;
|
||||
|
||||
+ if ( IS_COMPAT(container_of(regs, struct cpu_info, guest_cpu_user_regs)->current_vcpu->domain) )
|
||||
+ {
|
||||
+ compat_show_guest_stack(regs, debug_stack_lines);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
if ( vm86_mode(regs) )
|
||||
{
|
||||
stack = (unsigned long *)((regs->ss << 4) + (regs->esp & 0xffff));
|
||||
Index: 2006-12-18/xen/arch/x86/x86_64/Makefile
|
||||
===================================================================
|
||||
--- 2006-12-18.orig/xen/arch/x86/x86_64/Makefile 2006-12-13 11:15:54.000000000 +0100
|
||||
+++ 2006-12-18/xen/arch/x86/x86_64/Makefile 2006-12-18 09:43:08.000000000 +0100
|
||||
@@ -2,3 +2,9 @@ obj-y += entry.o
|
||||
obj-y += gpr_switch.o
|
||||
obj-y += mm.o
|
||||
obj-y += traps.o
|
||||
+
|
||||
+ifeq ($(CONFIG_COMPAT),y)
|
||||
+# extra dependencies
|
||||
+entry.o: compat/entry.S
|
||||
+traps.o: compat/traps.c
|
||||
+endif
|
||||
Index: 2006-12-18/xen/arch/x86/x86_64/asm-offsets.c
|
||||
===================================================================
|
||||
--- 2006-12-18.orig/xen/arch/x86/x86_64/asm-offsets.c 2006-12-18 09:37:45.000000000 +0100
|
||||
+++ 2006-12-18/xen/arch/x86/x86_64/asm-offsets.c 2006-12-18 09:43:08.000000000 +0100
|
||||
@@ -53,6 +53,7 @@ void __dummy__(void)
|
||||
BLANK();
|
||||
|
||||
OFFSET(VCPU_processor, struct vcpu, processor);
|
||||
+ OFFSET(VCPU_domain, struct vcpu, domain);
|
||||
OFFSET(VCPU_vcpu_info, struct vcpu, vcpu_info);
|
||||
OFFSET(VCPU_trap_bounce, struct vcpu, arch.trap_bounce);
|
||||
OFFSET(VCPU_thread_flags, struct vcpu, arch.flags);
|
||||
@@ -87,6 +88,10 @@ void __dummy__(void)
|
||||
OFFSET(VCPU_vmx_cr2, struct vcpu, arch.hvm_vmx.cpu_cr2);
|
||||
BLANK();
|
||||
|
||||
+ OFFSET(DOMAIN_domain_flags, struct domain, domain_flags);
|
||||
+ DEFINE(_DOMF_compat, _DOMF_compat);
|
||||
+ BLANK();
|
||||
+
|
||||
OFFSET(VMCB_rax, struct vmcb_struct, rax);
|
||||
OFFSET(VMCB_tsc_offset, struct vmcb_struct, tsc_offset);
|
||||
BLANK();
|
||||
@@ -95,6 +100,7 @@ void __dummy__(void)
|
||||
OFFSET(VCPUINFO_upcall_mask, vcpu_info_t, evtchn_upcall_mask);
|
||||
BLANK();
|
||||
|
||||
+ OFFSET(CPUINFO_current_vcpu, struct cpu_info, current_vcpu);
|
||||
DEFINE(CPUINFO_sizeof, sizeof(struct cpu_info));
|
||||
BLANK();
|
||||
|
||||
Index: 2006-12-18/xen/arch/x86/x86_64/compat/entry.S
|
||||
===================================================================
|
||||
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
|
||||
+++ 2006-12-18/xen/arch/x86/x86_64/compat/entry.S 2006-12-18 09:43:08.000000000 +0100
|
||||
@@ -0,0 +1,395 @@
|
||||
+/*
|
||||
+ * Compatibility hypercall routines.
|
||||
+ */
|
||||
+
|
||||
+#include <asm/desc.h>
|
||||
+
|
||||
+.text
|
||||
+
|
||||
+ENTRY(compat_hypercall)
|
||||
+ pushq $0
|
||||
+ movl $TRAP_syscall,4(%rsp)
|
||||
+ SAVE_ALL
|
||||
+ GET_CURRENT(%rbx)
|
||||
+
|
||||
+ cmpl $NR_hypercalls,%eax
|
||||
+ jae compat_bad_hypercall
|
||||
+#ifndef NDEBUG
|
||||
+ /* Deliberately corrupt parameter regs not used by this hypercall. */
|
||||
+ pushq UREGS_rbx(%rsp); pushq %rcx; pushq %rdx; pushq %rsi; pushq %rdi; pushq UREGS_rbp+5*8(%rsp)
|
||||
+ leaq compat_hypercall_args_table(%rip),%r10
|
||||
+ movq $6,%rcx
|
||||
+ subb (%r10,%rax,1),%cl
|
||||
+ movq %rsp,%rdi
|
||||
+ movl $0xDEADBEEF,%eax
|
||||
+ rep stosq
|
||||
+ popq %r9 ; popq %r8 ; popq %rcx; popq %rdx; popq %rsi; popq %rdi
|
||||
+ movl UREGS_rax(%rsp),%eax
|
||||
+ pushq %rax
|
||||
+ pushq UREGS_rip+8(%rsp)
|
||||
+#else
|
||||
+ movl %eax,%eax
|
||||
+ movl %ebp,%r9d
|
||||
+ movl %edi,%r8d
|
||||
+ xchgl %ecx,%esi
|
||||
+ movl UREGS_rbx(%rsp),%edi
|
||||
+#endif
|
||||
+ leaq compat_hypercall_table(%rip),%r10
|
||||
+ PERFC_INCR(PERFC_hypercalls, %rax)
|
||||
+ callq *(%r10,%rax,8)
|
||||
+#ifndef NDEBUG
|
||||
+ /* Deliberately corrupt parameter regs used by this hypercall. */
|
||||
+ popq %r10 # Shadow RIP
|
||||
+ cmpq %r10,UREGS_rip+8(%rsp)
|
||||
+ popq %rcx # Shadow hypercall index
|
||||
+ jne compat_skip_clobber /* If RIP has changed then don't clobber. */
|
||||
+ leaq compat_hypercall_args_table(%rip),%r10
|
||||
+ movb (%r10,%rcx,1),%cl
|
||||
+ movl $0xDEADBEEF,%r10d
|
||||
+ testb %cl,%cl; jz compat_skip_clobber; movl %r10d,UREGS_rbx(%rsp)
|
||||
+ cmpb $2, %cl; jb compat_skip_clobber; movl %r10d,UREGS_rcx(%rsp)
|
||||
+ cmpb $3, %cl; jb compat_skip_clobber; movl %r10d,UREGS_rdx(%rsp)
|
||||
+ cmpb $4, %cl; jb compat_skip_clobber; movl %r10d,UREGS_rsi(%rsp)
|
||||
+ cmpb $5, %cl; jb compat_skip_clobber; movl %r10d,UREGS_rdi(%rsp)
|
||||
+ cmpb $6, %cl; jb compat_skip_clobber; movl %r10d,UREGS_rbp(%rsp)
|
||||
+compat_skip_clobber:
|
||||
+#endif
|
||||
+ movl %eax,UREGS_rax(%rsp) # save the return value
|
||||
+
|
||||
+/* %rbx: struct vcpu */
|
||||
+compat_test_all_events:
|
||||
+ cli # tests must not race interrupts
|
||||
+/*compat_test_softirqs:*/
|
||||
+ movl VCPU_processor(%rbx),%eax
|
||||
+ shlq $IRQSTAT_shift,%rax
|
||||
+ leaq irq_stat(%rip),%rcx
|
||||
+ testl $~0,(%rcx,%rax,1)
|
||||
+ jnz compat_process_softirqs
|
||||
+ btrq $_VCPUF_nmi_pending,VCPU_flags(%rbx)
|
||||
+ jc compat_process_nmi
|
||||
+compat_test_guest_events:
|
||||
+ movq VCPU_vcpu_info(%rbx),%rax
|
||||
+ testb $0xFF,VCPUINFO_upcall_mask(%rax)
|
||||
+ jnz compat_restore_all_guest
|
||||
+ testb $0xFF,VCPUINFO_upcall_pending(%rax)
|
||||
+ jz compat_restore_all_guest
|
||||
+/*compat_process_guest_events:*/
|
||||
+ sti
|
||||
+ leaq VCPU_trap_bounce(%rbx),%rdx
|
||||
+ movl VCPU_event_addr(%rbx),%eax
|
||||
+ movl %eax,TRAPBOUNCE_eip(%rdx)
|
||||
+ movl VCPU_event_sel(%rbx),%eax
|
||||
+ movl %eax,TRAPBOUNCE_cs(%rdx)
|
||||
+ movw $TBF_INTERRUPT,TRAPBOUNCE_flags(%rdx)
|
||||
+ call compat_create_bounce_frame
|
||||
+ jmp compat_test_all_events
|
||||
+
|
||||
+ ALIGN
|
||||
+/* %rbx: struct vcpu */
|
||||
+compat_process_softirqs:
|
||||
+ sti
|
||||
+ call do_softirq
|
||||
+ jmp compat_test_all_events
|
||||
+
|
||||
+ ALIGN
|
||||
+/* %rbx: struct vcpu */
|
||||
+compat_process_nmi:
|
||||
+ movl VCPU_nmi_addr(%rbx),%eax
|
||||
+ testl %eax,%eax
|
||||
+ jz compat_test_all_events
|
||||
+ btsq $_VCPUF_nmi_masked,VCPU_flags(%rbx)
|
||||
+ jc 1f
|
||||
+ sti
|
||||
+ leaq VCPU_trap_bounce(%rbx),%rdx
|
||||
+ movl %eax,TRAPBOUNCE_eip(%rdx)
|
||||
+ movl $FLAT_COMPAT_KERNEL_CS,TRAPBOUNCE_cs(%rdx)
|
||||
+ movw $TBF_INTERRUPT,TRAPBOUNCE_flags(%rdx)
|
||||
+ call compat_create_bounce_frame
|
||||
+ jmp compat_test_all_events
|
||||
+1:
|
||||
+ btsq $_VCPUF_nmi_pending,VCPU_flags(%rbx)
|
||||
+ jmp compat_test_guest_events
|
||||
+
|
||||
+compat_bad_hypercall:
|
||||
+ movl $-ENOSYS,UREGS_rax(%rsp)
|
||||
+ jmp compat_test_all_events
|
||||
+
|
||||
+/* %rbx: struct vcpu, interrupts disabled */
|
||||
+compat_restore_all_guest:
|
||||
+ RESTORE_ALL
|
||||
+ addq $8,%rsp
|
||||
+CFLT0: iretq
|
||||
+
|
||||
+.section .fixup,"ax"
|
||||
+CFIX0: popq -15*8-8(%rsp) # error_code/entry_vector
|
||||
+ SAVE_ALL # 15*8 bytes pushed
|
||||
+ movq -8(%rsp),%rsi # error_code/entry_vector
|
||||
+ sti # after stack abuse (-1024(%rsp))
|
||||
+ pushq $__HYPERVISOR_DS # SS
|
||||
+ leaq 8(%rsp),%rax
|
||||
+ pushq %rax # RSP
|
||||
+ pushfq # RFLAGS
|
||||
+ pushq $__HYPERVISOR_CS # CS
|
||||
+ leaq CDBLFLT0(%rip),%rax
|
||||
+ pushq %rax # RIP
|
||||
+ pushq %rsi # error_code/entry_vector
|
||||
+ jmp handle_exception
|
||||
+CDBLFLT0:GET_CURRENT(%rbx)
|
||||
+ jmp compat_test_all_events
|
||||
+compat_failsafe_callback:
|
||||
+ GET_CURRENT(%rbx)
|
||||
+ leaq VCPU_trap_bounce(%rbx),%rdx
|
||||
+ movl VCPU_failsafe_addr(%rbx),%eax
|
||||
+ movl %eax,TRAPBOUNCE_eip(%rdx)
|
||||
+ movl VCPU_failsafe_sel(%rbx),%eax
|
||||
+ movl %eax,TRAPBOUNCE_cs(%rdx)
|
||||
+ movw $TBF_FAILSAFE,TRAPBOUNCE_flags(%rdx)
|
||||
+ btq $_VGCF_failsafe_disables_events,VCPU_guest_context_flags(%rbx)
|
||||
+ jnc 1f
|
||||
+ orw $TBF_INTERRUPT,TRAPBOUNCE_flags(%rdx)
|
||||
+1:
|
||||
+ call compat_create_bounce_frame
|
||||
+ jmp compat_test_all_events
|
||||
+.previous
|
||||
+.section __pre_ex_table,"a"
|
||||
+ .quad CFLT0,CFIX0
|
||||
+.previous
|
||||
+.section __ex_table,"a"
|
||||
+ .quad CDBLFLT0,compat_failsafe_callback
|
||||
+.previous
|
||||
+
|
||||
+/* %rdx: trap_bounce, %rbx: struct vcpu */
|
||||
+compat_post_handle_exception:
|
||||
+ testb $TBF_EXCEPTION,TRAPBOUNCE_flags(%rdx)
|
||||
+ jz compat_test_all_events
|
||||
+ call compat_create_bounce_frame
|
||||
+ jmp compat_test_all_events
|
||||
+
|
||||
+/* CREATE A BASIC EXCEPTION FRAME ON GUEST OS (RING-1) STACK: */
|
||||
+/* {[ERRCODE,] EIP, CS, EFLAGS, [ESP, SS]} */
|
||||
+/* %rdx: trap_bounce, %rbx: struct vcpu */
|
||||
+/* On return only %rbx is guaranteed non-clobbered. */
|
||||
+compat_create_bounce_frame:
|
||||
+ mov %fs,%edi
|
||||
+ testb $2,UREGS_cs+8(%rsp)
|
||||
+ jz 1f
|
||||
+ /* Push new frame at registered guest-OS stack base. */
|
||||
+ movl VCPU_kernel_sp(%rbx),%esi
|
||||
+CFLT1: mov VCPU_kernel_ss(%rbx),%fs
|
||||
+ subl $2*4,%esi
|
||||
+ movl UREGS_rsp+8(%rsp),%eax
|
||||
+CFLT2: movl %eax,%fs:(%rsi)
|
||||
+ movl UREGS_ss+8(%rsp),%eax
|
||||
+CFLT3: movl %eax,%fs:4(%rsi)
|
||||
+ jmp 2f
|
||||
+1: /* In kernel context already: push new frame at existing %rsp. */
|
||||
+ movl UREGS_rsp+8(%rsp),%esi
|
||||
+CFLT4: mov UREGS_ss+8(%rsp),%fs
|
||||
+2:
|
||||
+ movb TRAPBOUNCE_flags(%rdx),%cl
|
||||
+ subl $3*4,%esi
|
||||
+ movq VCPU_vcpu_info(%rbx),%rax
|
||||
+ pushq VCPUINFO_upcall_mask(%rax)
|
||||
+ testb $TBF_INTERRUPT,%cl
|
||||
+ setnz %ch # TBF_INTERRUPT -> set upcall mask
|
||||
+ orb %ch,VCPUINFO_upcall_mask(%rax)
|
||||
+ popq %rax
|
||||
+ shll $16,%eax # Bits 16-23: saved_upcall_mask
|
||||
+ movw UREGS_cs+8(%rsp),%ax # Bits 0-15: CS
|
||||
+CFLT5: movl %eax,%fs:4(%rsi) # CS / saved_upcall_mask
|
||||
+ shrl $16,%eax
|
||||
+ testb %al,%al # Bits 0-7: saved_upcall_mask
|
||||
+ setz %ch # %ch == !saved_upcall_mask
|
||||
+ movl UREGS_eflags+8(%rsp),%eax
|
||||
+ andl $~X86_EFLAGS_IF,%eax
|
||||
+ shlb $1,%ch # Bit 9 (EFLAGS.IF)
|
||||
+ orb %ch,%ah # Fold EFLAGS.IF into %eax
|
||||
+CFLT6: movl %eax,%fs:2*4(%rsi) # EFLAGS
|
||||
+ movl UREGS_rip+8(%rsp),%eax
|
||||
+CFLT7: movl %eax,%fs:(%rsi) # EIP
|
||||
+ testb $TBF_EXCEPTION_ERRCODE,%cl
|
||||
+ jz 1f
|
||||
+ subl $4,%esi
|
||||
+ movl TRAPBOUNCE_error_code(%rdx),%eax
|
||||
+CFLT8: movl %eax,%fs:(%rsi) # ERROR CODE
|
||||
+1:
|
||||
+ testb $TBF_FAILSAFE,%cl
|
||||
+ jz 2f
|
||||
+ subl $4*4,%esi
|
||||
+ movl %gs,%eax
|
||||
+CFLT9: movl %eax,%fs:3*4(%rsi) # GS
|
||||
+CFLT10: movl %edi,%fs:2*4(%rsi) # FS
|
||||
+ movl %es,%eax
|
||||
+CFLT11: movl %eax,%fs:1*4(%rsi) # ES
|
||||
+ movl %ds,%eax
|
||||
+CFLT12: movl %eax,%fs:0*4(%rsi) # DS
|
||||
+2:
|
||||
+ /* Rewrite our stack frame and return to guest-OS mode. */
|
||||
+ /* IA32 Ref. Vol. 3: TF, VM, RF and NT flags are cleared on trap. */
|
||||
+ movl $TRAP_syscall,UREGS_entry_vector+8(%rsp)
|
||||
+ andl $~(X86_EFLAGS_VM|X86_EFLAGS_RF|\
|
||||
+ X86_EFLAGS_NT|X86_EFLAGS_TF),UREGS_eflags+8(%rsp)
|
||||
+ mov %fs,UREGS_ss+8(%rsp)
|
||||
+ movl %esi,UREGS_rsp+8(%rsp)
|
||||
+CFLT13: mov %edi,%fs
|
||||
+ movzwl TRAPBOUNCE_cs(%rdx),%eax
|
||||
+ /* Null selectors (0-3) are not allowed. */
|
||||
+ testl $~3,%eax
|
||||
+ jz domain_crash_synchronous
|
||||
+ movl %eax,UREGS_cs+8(%rsp)
|
||||
+ movl TRAPBOUNCE_eip(%rdx),%eax
|
||||
+ movl %eax,UREGS_rip+8(%rsp)
|
||||
+ movb $0,TRAPBOUNCE_flags(%rdx)
|
||||
+ ret
|
||||
+.section .fixup,"ax"
|
||||
+CFIX13:
|
||||
+ xorl %edi,%edi
|
||||
+ jmp CFLT13
|
||||
+.previous
|
||||
+.section __ex_table,"a"
|
||||
+ .quad CFLT1,domain_crash_synchronous , CFLT2,compat_crash_page_fault
|
||||
+ .quad CFLT3,compat_crash_page_fault_4 , CFLT4,domain_crash_synchronous
|
||||
+ .quad CFLT5,compat_crash_page_fault_4 , CFLT6,compat_crash_page_fault_8
|
||||
+ .quad CFLT7,compat_crash_page_fault , CFLT8,compat_crash_page_fault
|
||||
+ .quad CFLT9,compat_crash_page_fault_12, CFLT10,compat_crash_page_fault_8
|
||||
+ .quad CFLT11,compat_crash_page_fault_4 , CFLT12,compat_crash_page_fault
|
||||
+ .quad CFLT13,CFIX13
|
||||
+.previous
|
||||
+
|
||||
+compat_crash_page_fault_12:
|
||||
+ addl $4,%esi
|
||||
+compat_crash_page_fault_8:
|
||||
+ addl $4,%esi
|
||||
+compat_crash_page_fault_4:
|
||||
+ addl $4,%esi
|
||||
+compat_crash_page_fault:
|
||||
+CFLT14: mov %edi,%fs
|
||||
+ movl %esi,%edi
|
||||
+ call show_page_walk
|
||||
+ jmp domain_crash_synchronous
|
||||
+.section .fixup,"ax"
|
||||
+CFIX14:
|
||||
+ xorl %edi,%edi
|
||||
+ jmp CFLT14
|
||||
+.previous
|
||||
+.section __ex_table,"a"
|
||||
+ .quad CFLT14,CFIX14
|
||||
+.previous
|
||||
+
|
||||
+.section .rodata, "a", @progbits
|
||||
+
|
||||
+#define compat_set_trap_table domain_crash_synchronous
|
||||
+#define compat_mmu_update domain_crash_synchronous
|
||||
+#define compat_set_gdt domain_crash_synchronous
|
||||
+#define compat_stack_switch domain_crash_synchronous
|
||||
+#define compat_fpu_taskswitch domain_crash_synchronous
|
||||
+#define compat_arch_sched_op_compat domain_crash_synchronous
|
||||
+#define compat_platform_op domain_crash_synchronous
|
||||
+#define compat_set_debugreg domain_crash_synchronous
|
||||
+#define compat_get_debugreg domain_crash_synchronous
|
||||
+#define compat_update_descriptor domain_crash_synchronous
|
||||
+#define compat_memory_op domain_crash_synchronous
|
||||
+#define compat_multicall domain_crash_synchronous
|
||||
+#define compat_update_va_mapping domain_crash_synchronous
|
||||
+#define compat_set_timer_op domain_crash_synchronous
|
||||
+#define compat_event_channel_op_compat domain_crash_synchronous
|
||||
+#define compat_xen_version domain_crash_synchronous
|
||||
+#define compat_console_io domain_crash_synchronous
|
||||
+#define compat_physdev_op_compat domain_crash_synchronous
|
||||
+#define compat_grant_table_op domain_crash_synchronous
|
||||
+#define compat_vm_assist domain_crash_synchronous
|
||||
+#define compat_update_va_mapping_otherdomain domain_crash_synchronous
|
||||
+#define compat_vcpu_op domain_crash_synchronous
|
||||
+#define compat_mmuext_op domain_crash_synchronous
|
||||
+#define compat_acm_op domain_crash_synchronous
|
||||
+#define compat_nmi_op domain_crash_synchronous
|
||||
+#define compat_arch_sched_op domain_crash_synchronous
|
||||
+#define compat_xenoprof_op domain_crash_synchronous
|
||||
+#define compat_event_channel_op domain_crash_synchronous
|
||||
+#define compat_physdev_op domain_crash_synchronous
|
||||
+#define compat_sysctl domain_crash_synchronous
|
||||
+#define compat_domctl domain_crash_synchronous
|
||||
+
|
||||
+ENTRY(compat_hypercall_table)
|
||||
+ .quad compat_set_trap_table /* 0 */
|
||||
+ .quad compat_mmu_update
|
||||
+ .quad compat_set_gdt
|
||||
+ .quad compat_stack_switch
|
||||
+ .quad compat_set_callbacks
|
||||
+ .quad compat_fpu_taskswitch /* 5 */
|
||||
+ .quad compat_arch_sched_op_compat
|
||||
+ .quad compat_platform_op
|
||||
+ .quad compat_set_debugreg
|
||||
+ .quad compat_get_debugreg
|
||||
+ .quad compat_update_descriptor /* 10 */
|
||||
+ .quad do_ni_hypercall
|
||||
+ .quad compat_memory_op
|
||||
+ .quad compat_multicall
|
||||
+ .quad compat_update_va_mapping
|
||||
+ .quad compat_set_timer_op /* 15 */
|
||||
+ .quad compat_event_channel_op_compat
|
||||
+ .quad compat_xen_version
|
||||
+ .quad compat_console_io
|
||||
+ .quad compat_physdev_op_compat
|
||||
+ .quad compat_grant_table_op /* 20 */
|
||||
+ .quad compat_vm_assist
|
||||
+ .quad compat_update_va_mapping_otherdomain
|
||||
+ .quad compat_iret
|
||||
+ .quad compat_vcpu_op
|
||||
+ .quad do_ni_hypercall /* 25 */
|
||||
+ .quad compat_mmuext_op
|
||||
+ .quad compat_acm_op
|
||||
+ .quad compat_nmi_op
|
||||
+ .quad compat_arch_sched_op
|
||||
+ .quad compat_callback_op /* 30 */
|
||||
+ .quad compat_xenoprof_op
|
||||
+ .quad compat_event_channel_op
|
||||
+ .quad compat_physdev_op
|
||||
+ .quad do_ni_hypercall
|
||||
+ .quad compat_sysctl /* 35 */
|
||||
+ .quad compat_domctl
|
||||
+ .rept NR_hypercalls-((.-compat_hypercall_table)/8)
|
||||
+ .quad do_ni_hypercall
|
||||
+ .endr
|
||||
+
|
||||
+ENTRY(compat_hypercall_args_table)
|
||||
+ .byte 1 /* compat_set_trap_table */ /* 0 */
|
||||
+ .byte 4 /* compat_mmu_update */
|
||||
+ .byte 2 /* compat_set_gdt */
|
||||
+ .byte 2 /* compat_stack_switch */
|
||||
+ .byte 4 /* compat_set_callbacks */
|
||||
+ .byte 1 /* compat_fpu_taskswitch */ /* 5 */
|
||||
+ .byte 2 /* compat_arch_sched_op_compat */
|
||||
+ .byte 1 /* compat_platform_op */
|
||||
+ .byte 2 /* compat_set_debugreg */
|
||||
+ .byte 1 /* compat_get_debugreg */
|
||||
+ .byte 4 /* compat_update_descriptor */ /* 10 */
|
||||
+ .byte 0 /* do_ni_hypercall */
|
||||
+ .byte 2 /* compat_memory_op */
|
||||
+ .byte 2 /* compat_multicall */
|
||||
+ .byte 4 /* compat_update_va_mapping */
|
||||
+ .byte 2 /* compat_set_timer_op */ /* 15 */
|
||||
+ .byte 1 /* compat_event_channel_op_compat */
|
||||
+ .byte 2 /* compat_xen_version */
|
||||
+ .byte 3 /* compat_console_io */
|
||||
+ .byte 1 /* compat_physdev_op_compat */
|
||||
+ .byte 3 /* compat_grant_table_op */ /* 20 */
|
||||
+ .byte 2 /* compat_vm_assist */
|
||||
+ .byte 5 /* compat_update_va_mapping_otherdomain */
|
||||
+ .byte 0 /* compat_iret */
|
||||
+ .byte 3 /* compat_vcpu_op */
|
||||
+ .byte 0 /* do_ni_hypercall */ /* 25 */
|
||||
+ .byte 4 /* compat_mmuext_op */
|
||||
+ .byte 1 /* compat_acm_op */
|
||||
+ .byte 2 /* compat_nmi_op */
|
||||
+ .byte 2 /* compat_arch_sched_op */
|
||||
+ .byte 2 /* compat_callback_op */ /* 30 */
|
||||
+ .byte 2 /* compat_xenoprof_op */
|
||||
+ .byte 2 /* compat_event_channel_op */
|
||||
+ .byte 2 /* compat_physdev_op */
|
||||
+ .byte 0 /* do_ni_hypercall */
|
||||
+ .byte 1 /* compat_sysctl */ /* 35 */
|
||||
+ .byte 1 /* compat_domctl */
|
||||
+ .rept NR_hypercalls-(.-compat_hypercall_args_table)
|
||||
+ .byte 0 /* do_ni_hypercall */
|
||||
+ .endr
|
||||
Index: 2006-12-18/xen/arch/x86/x86_64/compat/traps.c
|
||||
===================================================================
|
||||
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
|
||||
+++ 2006-12-18/xen/arch/x86/x86_64/compat/traps.c 2006-12-18 09:43:08.000000000 +0100
|
||||
@@ -0,0 +1,312 @@
|
||||
+#ifdef CONFIG_COMPAT
|
||||
+
|
||||
+#if 0 /* XXX */
|
||||
+#include <compat/callback.h>
|
||||
+#else
|
||||
+struct compat_xen_callback {
|
||||
+ unsigned int cs;
|
||||
+ unsigned int eip;
|
||||
+};
|
||||
+typedef struct compat_xen_callback xen_callback_compat_t;
|
||||
+
|
||||
+struct compat_callback_register {
|
||||
+ uint16_t type;
|
||||
+ uint16_t flags;
|
||||
+ xen_callback_compat_t address;
|
||||
+};
|
||||
+
|
||||
+struct compat_callback_unregister {
|
||||
+ uint16_t type;
|
||||
+ uint16_t _unused;
|
||||
+};
|
||||
+#endif
|
||||
+
|
||||
+void compat_show_guest_stack(struct cpu_user_regs *regs, int debug_stack_lines)
|
||||
+{
|
||||
+ unsigned int i, *stack, addr;
|
||||
+
|
||||
+ stack = (unsigned int *)(unsigned long)regs->_esp;
|
||||
+ printk("Guest stack trace from esp=%08lx:\n ", (unsigned long)stack);
|
||||
+
|
||||
+ for ( i = 0; i < debug_stack_lines * 8; i++ )
|
||||
+ {
|
||||
+ if ( (((long)stack + 3) & (STACK_SIZE - 4)) == 0 )
|
||||
+ break;
|
||||
+ if ( get_user(addr, stack) )
|
||||
+ {
|
||||
+ if ( i != 0 )
|
||||
+ printk("\n ");
|
||||
+ printk("Fault while accessing guest memory.");
|
||||
+ i = 1;
|
||||
+ break;
|
||||
+ }
|
||||
+ if ( (i != 0) && ((i % 8) == 0) )
|
||||
+ printk("\n ");
|
||||
+ printk(" %08x", addr);
|
||||
+ stack++;
|
||||
+ }
|
||||
+ if ( i == 0 )
|
||||
+ printk("Stack empty.");
|
||||
+ printk("\n");
|
||||
+}
|
||||
+
|
||||
+unsigned int compat_iret(void)
|
||||
+{
|
||||
+ struct cpu_user_regs *regs = guest_cpu_user_regs();
|
||||
+ u32 eflags;
|
||||
+
|
||||
+ /* Restore EAX (clobbered by hypercall). */
|
||||
+ if ( unlikely(__get_user(regs->_eax, (u32 __user *)regs->rsp)) )
|
||||
+ goto exit_and_crash;
|
||||
+
|
||||
+ /* Restore CS and EIP. */
|
||||
+ if ( unlikely(__get_user(regs->_eip, (u32 __user *)regs->rsp + 1)) ||
|
||||
+ unlikely(__get_user(regs->cs, (u32 __user *)regs->rsp + 2)) )
|
||||
+ goto exit_and_crash;
|
||||
+
|
||||
+ /*
|
||||
+ * Fix up and restore EFLAGS. We fix up in a local staging area
|
||||
+ * to avoid firing the BUG_ON(IOPL) check in arch_getdomaininfo_ctxt.
|
||||
+ */
|
||||
+ if ( unlikely(__get_user(eflags, (u32 __user *)regs->rsp + 3)) )
|
||||
+ goto exit_and_crash;
|
||||
+ regs->_eflags = (eflags & ~X86_EFLAGS_IOPL) | X86_EFLAGS_IF;
|
||||
+
|
||||
+ if ( unlikely(eflags & X86_EFLAGS_VM) )
|
||||
+ {
|
||||
+ /*
|
||||
+ * Cannot return to VM86 mode: inject a GP fault instead. Note that
|
||||
+ * the GP fault is reported on the first VM86 mode instruction, not on
|
||||
+ * the IRET (which is why we can simply leave the stack frame as-is
|
||||
+ * (except for perhaps having to copy it), which in turn seems better
|
||||
+ * than teaching create_bounce_frame() to needlessly deal with vm86
|
||||
+ * mode frames).
|
||||
+ */
|
||||
+ const struct trap_info *ti;
|
||||
+ u32 x, ksp = current->arch.guest_context.kernel_sp - 40;
|
||||
+ unsigned int i;
|
||||
+ int rc = 0;
|
||||
+
|
||||
+ gdprintk(XENLOG_ERR, "VM86 mode unavailable (ksp:%08X->%08X)\n",
|
||||
+ regs->_esp, ksp);
|
||||
+ if ( ksp < regs->_esp )
|
||||
+ {
|
||||
+ for (i = 1; i < 10; ++i)
|
||||
+ {
|
||||
+ rc |= __get_user(x, (u32 __user *)regs->rsp + i);
|
||||
+ rc |= __put_user(x, (u32 __user *)(unsigned long)ksp + i);
|
||||
+ }
|
||||
+ }
|
||||
+ else if ( ksp > regs->_esp )
|
||||
+ {
|
||||
+ for (i = 9; i > 0; ++i)
|
||||
+ {
|
||||
+ rc |= __get_user(x, (u32 __user *)regs->rsp + i);
|
||||
+ rc |= __put_user(x, (u32 __user *)(unsigned long)ksp + i);
|
||||
+ }
|
||||
+ }
|
||||
+ if ( rc )
|
||||
+ goto exit_and_crash;
|
||||
+ regs->_esp = ksp;
|
||||
+ regs->ss = current->arch.guest_context.kernel_ss;
|
||||
+
|
||||
+ ti = ¤t->arch.guest_context.trap_ctxt[13];
|
||||
+ if ( TI_GET_IF(ti) )
|
||||
+ eflags &= ~X86_EFLAGS_IF;
|
||||
+ regs->_eflags = eflags & ~(X86_EFLAGS_VM|X86_EFLAGS_RF|
|
||||
+ X86_EFLAGS_NT|X86_EFLAGS_TF);
|
||||
+
|
||||
+ if ( unlikely(__put_user(0, (u32 __user *)regs->rsp)) )
|
||||
+ goto exit_and_crash;
|
||||
+ regs->_eip = ti->address;
|
||||
+ regs->cs = ti->cs;
|
||||
+ }
|
||||
+ else if ( unlikely(ring_0(regs)) )
|
||||
+ goto exit_and_crash;
|
||||
+ else if ( !ring_1(regs) )
|
||||
+ {
|
||||
+ /* Return to ring 2/3: restore ESP and SS. */
|
||||
+ if ( __get_user(regs->ss, (u32 __user *)regs->rsp + 5)
|
||||
+ || __get_user(regs->_esp, (u32 __user *)regs->rsp + 4))
|
||||
+ goto exit_and_crash;
|
||||
+ }
|
||||
+ else
|
||||
+ regs->_esp += 16;
|
||||
+
|
||||
+ /* No longer in NMI context. */
|
||||
+ clear_bit(_VCPUF_nmi_masked, ¤t->vcpu_flags);
|
||||
+
|
||||
+ /* Restore upcall mask from supplied EFLAGS.IF. */
|
||||
+ current->vcpu_info->evtchn_upcall_mask = !(eflags & X86_EFLAGS_IF);
|
||||
+
|
||||
+ /*
|
||||
+ * The hypercall exit path will overwrite EAX with this return
|
||||
+ * value.
|
||||
+ */
|
||||
+ return regs->_eax;
|
||||
+
|
||||
+ exit_and_crash:
|
||||
+ gdprintk(XENLOG_ERR, "Fatal error\n");
|
||||
+ domain_crash(current->domain);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static long compat_register_guest_callback(struct compat_callback_register *reg)
|
||||
+{
|
||||
+ long ret = 0;
|
||||
+ struct vcpu *v = current;
|
||||
+
|
||||
+ fixup_guest_code_selector(v->domain, reg->address.cs);
|
||||
+
|
||||
+ switch ( reg->type )
|
||||
+ {
|
||||
+ case CALLBACKTYPE_event:
|
||||
+ v->arch.guest_context.event_callback_cs = reg->address.cs;
|
||||
+ v->arch.guest_context.event_callback_eip = reg->address.eip;
|
||||
+ break;
|
||||
+
|
||||
+ case CALLBACKTYPE_failsafe:
|
||||
+ v->arch.guest_context.failsafe_callback_cs = reg->address.cs;
|
||||
+ v->arch.guest_context.failsafe_callback_eip = reg->address.eip;
|
||||
+ if ( reg->flags & CALLBACKF_mask_events )
|
||||
+ set_bit(_VGCF_failsafe_disables_events,
|
||||
+ &v->arch.guest_context.flags);
|
||||
+ else
|
||||
+ clear_bit(_VGCF_failsafe_disables_events,
|
||||
+ &v->arch.guest_context.flags);
|
||||
+ break;
|
||||
+
|
||||
+ case CALLBACKTYPE_nmi:
|
||||
+ ret = register_guest_nmi_callback(reg->address.eip);
|
||||
+ break;
|
||||
+
|
||||
+ default:
|
||||
+ ret = -EINVAL;
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static long compat_unregister_guest_callback(struct compat_callback_unregister *unreg)
|
||||
+{
|
||||
+ long ret;
|
||||
+
|
||||
+ switch ( unreg->type )
|
||||
+ {
|
||||
+ case CALLBACKTYPE_nmi:
|
||||
+ ret = unregister_guest_nmi_callback();
|
||||
+ break;
|
||||
+
|
||||
+ default:
|
||||
+ ret = -EINVAL;
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+long compat_callback_op(int cmd, XEN_GUEST_HANDLE(void) arg)
|
||||
+{
|
||||
+ long ret;
|
||||
+
|
||||
+ switch ( cmd )
|
||||
+ {
|
||||
+ case CALLBACKOP_register:
|
||||
+ {
|
||||
+ struct compat_callback_register reg;
|
||||
+
|
||||
+ ret = -EFAULT;
|
||||
+ if ( copy_from_guest(®, arg, 1) )
|
||||
+ break;
|
||||
+
|
||||
+ ret = compat_register_guest_callback(®);
|
||||
+ }
|
||||
+ break;
|
||||
+
|
||||
+ case CALLBACKOP_unregister:
|
||||
+ {
|
||||
+ struct compat_callback_unregister unreg;
|
||||
+
|
||||
+ ret = -EFAULT;
|
||||
+ if ( copy_from_guest(&unreg, arg, 1) )
|
||||
+ break;
|
||||
+
|
||||
+ ret = compat_unregister_guest_callback(&unreg);
|
||||
+ }
|
||||
+ break;
|
||||
+
|
||||
+ default:
|
||||
+ ret = -EINVAL;
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+long compat_set_callbacks(unsigned long event_selector,
|
||||
+ unsigned long event_address,
|
||||
+ unsigned long failsafe_selector,
|
||||
+ unsigned long failsafe_address)
|
||||
+{
|
||||
+ struct compat_callback_register event = {
|
||||
+ .type = CALLBACKTYPE_event,
|
||||
+ .address = {
|
||||
+ .cs = event_selector,
|
||||
+ .eip = event_address
|
||||
+ }
|
||||
+ };
|
||||
+ struct compat_callback_register failsafe = {
|
||||
+ .type = CALLBACKTYPE_failsafe,
|
||||
+ .address = {
|
||||
+ .cs = failsafe_selector,
|
||||
+ .eip = failsafe_address
|
||||
+ }
|
||||
+ };
|
||||
+
|
||||
+ compat_register_guest_callback(&event);
|
||||
+ compat_register_guest_callback(&failsafe);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+#endif /* CONFIG_COMPAT */
|
||||
+
|
||||
+static void hypercall_page_initialise_ring1_kernel(void *hypercall_page)
|
||||
+{
|
||||
+ char *p;
|
||||
+ int i;
|
||||
+
|
||||
+ /* Fill in all the transfer points with template machine code. */
|
||||
+
|
||||
+ for ( i = 0; i < (PAGE_SIZE / 32); i++ )
|
||||
+ {
|
||||
+ p = (char *)(hypercall_page + (i * 32));
|
||||
+ *(u8 *)(p+ 0) = 0xb8; /* mov $<i>,%eax */
|
||||
+ *(u32 *)(p+ 1) = i;
|
||||
+ *(u16 *)(p+ 5) = 0x82cd; /* int $0x82 */
|
||||
+ *(u8 *)(p+ 7) = 0xc3; /* ret */
|
||||
+ }
|
||||
+
|
||||
+ /*
|
||||
+ * HYPERVISOR_iret is special because it doesn't return and expects a
|
||||
+ * special stack frame. Guests jump at this transfer point instead of
|
||||
+ * calling it.
|
||||
+ */
|
||||
+ p = (char *)(hypercall_page + (__HYPERVISOR_iret * 32));
|
||||
+ *(u8 *)(p+ 0) = 0x50; /* push %eax */
|
||||
+ *(u8 *)(p+ 1) = 0xb8; /* mov $__HYPERVISOR_iret,%eax */
|
||||
+ *(u32 *)(p+ 2) = __HYPERVISOR_iret;
|
||||
+ *(u16 *)(p+ 6) = 0x82cd; /* int $0x82 */
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * Local variables:
|
||||
+ * mode: C
|
||||
+ * c-set-style: "BSD"
|
||||
+ * c-basic-offset: 4
|
||||
+ * tab-width: 4
|
||||
+ * indent-tabs-mode: nil
|
||||
+ * End:
|
||||
+ */
|
||||
Index: 2006-12-18/xen/arch/x86/x86_64/entry.S
|
||||
===================================================================
|
||||
--- 2006-12-18.orig/xen/arch/x86/x86_64/entry.S 2006-12-18 09:36:35.000000000 +0100
|
||||
+++ 2006-12-18/xen/arch/x86/x86_64/entry.S 2006-12-18 09:43:08.000000000 +0100
|
||||
@@ -337,7 +337,16 @@ domain_crash_synchronous:
|
||||
GET_GUEST_REGS(%rax)
|
||||
movq %rax,%rsp
|
||||
# create_bounce_frame() temporarily clobbers CS.RPL. Fix up.
|
||||
+#ifdef CONFIG_COMPAT
|
||||
+ movq CPUINFO_current_vcpu(%rax),%rax
|
||||
+ movq VCPU_domain(%rax),%rax
|
||||
+ btl $_DOMF_compat,DOMAIN_domain_flags(%rax)
|
||||
+ setnc %al
|
||||
+ leal (%rax,%rax,2),%eax
|
||||
+ orb %al,UREGS_cs(%rsp)
|
||||
+#else
|
||||
orb $3,UREGS_cs(%rsp)
|
||||
+#endif
|
||||
# printk(domain_crash_synchronous_string)
|
||||
leaq domain_crash_synchronous_string(%rip),%rdi
|
||||
xorl %eax,%eax
|
||||
@@ -349,8 +358,15 @@ domain_crash_synchronous:
|
||||
ENTRY(ret_from_intr)
|
||||
GET_CURRENT(%rbx)
|
||||
testb $3,UREGS_cs(%rsp)
|
||||
- jnz test_all_events
|
||||
- jmp restore_all_xen
|
||||
+ jz restore_all_xen
|
||||
+#ifndef CONFIG_COMPAT
|
||||
+ jmp test_all_events
|
||||
+#else
|
||||
+ movq VCPU_domain(%rbx),%rax
|
||||
+ btl $_DOMF_compat,DOMAIN_domain_flags(%rax)
|
||||
+ jnc test_all_events
|
||||
+ jmp compat_test_all_events
|
||||
+#endif
|
||||
|
||||
ALIGN
|
||||
/* No special register assumptions. */
|
||||
@@ -368,6 +384,11 @@ handle_exception:
|
||||
testb $3,UREGS_cs(%rsp)
|
||||
jz restore_all_xen
|
||||
leaq VCPU_trap_bounce(%rbx),%rdx
|
||||
+#ifdef CONFIG_COMPAT
|
||||
+ movq VCPU_domain(%rbx),%rax
|
||||
+ btl $_DOMF_compat,DOMAIN_domain_flags(%rax)
|
||||
+ jc compat_post_handle_exception
|
||||
+#endif
|
||||
testb $TBF_EXCEPTION,TRAPBOUNCE_flags(%rdx)
|
||||
jz test_all_events
|
||||
call create_bounce_frame
|
||||
@@ -625,3 +646,7 @@ ENTRY(hypercall_args_table)
|
||||
.rept NR_hypercalls-(.-hypercall_args_table)
|
||||
.byte 0 /* do_ni_hypercall */
|
||||
.endr
|
||||
+
|
||||
+#ifdef CONFIG_COMPAT
|
||||
+#include "compat/entry.S"
|
||||
+#endif
|
||||
Index: 2006-12-18/xen/arch/x86/x86_64/traps.c
|
||||
===================================================================
|
||||
--- 2006-12-18.orig/xen/arch/x86/x86_64/traps.c 2006-12-18 09:37:45.000000000 +0100
|
||||
+++ 2006-12-18/xen/arch/x86/x86_64/traps.c 2006-12-18 09:43:08.000000000 +0100
|
||||
@@ -246,6 +246,7 @@ unsigned long do_iret(void)
|
||||
}
|
||||
|
||||
asmlinkage void syscall_enter(void);
|
||||
+asmlinkage void compat_hypercall(void);
|
||||
void __init percpu_traps_init(void)
|
||||
{
|
||||
char *stack_bottom, *stack;
|
||||
@@ -257,6 +258,11 @@ void __init percpu_traps_init(void)
|
||||
set_intr_gate(TRAP_double_fault, &double_fault);
|
||||
idt_table[TRAP_double_fault].a |= 1UL << 32; /* IST1 */
|
||||
idt_table[TRAP_nmi].a |= 2UL << 32; /* IST2 */
|
||||
+
|
||||
+#ifdef CONFIG_COMPAT
|
||||
+ /* The hypercall entry vector is only accessible from ring 1. */
|
||||
+ _set_gate(idt_table+HYPERCALL_VECTOR, 15, 1, &compat_hypercall);
|
||||
+#endif
|
||||
}
|
||||
|
||||
stack_bottom = (char *)get_stack_bottom();
|
||||
@@ -503,12 +509,16 @@ static void hypercall_page_initialise_ri
|
||||
*(u16 *)(p+ 9) = 0x050f; /* syscall */
|
||||
}
|
||||
|
||||
+#include "compat/traps.c"
|
||||
+
|
||||
void hypercall_page_initialise(struct domain *d, void *hypercall_page)
|
||||
{
|
||||
if ( is_hvm_domain(d) )
|
||||
hvm_hypercall_page_initialise(d, hypercall_page);
|
||||
- else
|
||||
+ else if ( !IS_COMPAT(d) )
|
||||
hypercall_page_initialise_ring3_kernel(hypercall_page);
|
||||
+ else
|
||||
+ hypercall_page_initialise_ring1_kernel(hypercall_page);
|
||||
}
|
||||
|
||||
/*
|
||||
Index: 2006-12-18/xen/include/asm-x86/processor.h
|
||||
===================================================================
|
||||
--- 2006-12-18.orig/xen/include/asm-x86/processor.h 2006-12-13 11:15:56.000000000 +0100
|
||||
+++ 2006-12-18/xen/include/asm-x86/processor.h 2006-12-18 09:43:08.000000000 +0100
|
||||
@@ -559,6 +559,12 @@ void show_execution_state(struct cpu_use
|
||||
void show_page_walk(unsigned long addr);
|
||||
asmlinkage void fatal_trap(int trapnr, struct cpu_user_regs *regs);
|
||||
|
||||
+#ifdef CONFIG_COMPAT
|
||||
+void compat_show_guest_stack(struct cpu_user_regs *, int lines);
|
||||
+#else
|
||||
+#define compat_show_guest_stack(regs, lines) ((void)0)
|
||||
+#endif
|
||||
+
|
||||
/* Dumps current register and stack state. */
|
||||
#define dump_execution_state() \
|
||||
/* NB. Needs interrupts enabled else we end up in fatal_trap(). */ \
|
616
32on64-interface.patch
Normal file
616
32on64-interface.patch
Normal file
@ -0,0 +1,616 @@
|
||||
Add logic to generate headers reflecting the compatibility mode layout
|
||||
of hypercall arguments. Provide infrastructure for accessing handles
|
||||
passed from compatibility mode guests. Vector those hypercalls not
|
||||
needing any translation to their native implementations.
|
||||
|
||||
Index: 2007-01-08/xen/Makefile
|
||||
===================================================================
|
||||
--- 2007-01-08.orig/xen/Makefile 2007-01-08 15:17:24.000000000 +0100
|
||||
+++ 2007-01-08/xen/Makefile 2007-01-08 15:17:29.000000000 +0100
|
||||
@@ -48,6 +48,7 @@ _debug:
|
||||
.PHONY: _clean
|
||||
_clean: delete-unfresh-files
|
||||
$(MAKE) -C tools clean
|
||||
+ $(MAKE) -f $(BASEDIR)/Rules.mk -C include clean
|
||||
$(MAKE) -f $(BASEDIR)/Rules.mk -C common clean
|
||||
$(MAKE) -f $(BASEDIR)/Rules.mk -C drivers clean
|
||||
$(MAKE) -f $(BASEDIR)/Rules.mk -C acm clean
|
||||
@@ -69,6 +70,7 @@ $(TARGET): delete-unfresh-files
|
||||
$(MAKE) -f $(BASEDIR)/Rules.mk include/xen/compile.h
|
||||
$(MAKE) -f $(BASEDIR)/Rules.mk include/xen/acm_policy.h
|
||||
[ -e include/asm ] || ln -sf asm-$(TARGET_ARCH) include/asm
|
||||
+ $(MAKE) -f $(BASEDIR)/Rules.mk -C include
|
||||
$(MAKE) -f $(BASEDIR)/Rules.mk -C arch/$(TARGET_ARCH) asm-offsets.s
|
||||
$(MAKE) -f $(BASEDIR)/Rules.mk include/asm-$(TARGET_ARCH)/asm-offsets.h
|
||||
$(MAKE) -f $(BASEDIR)/Rules.mk -C arch/$(TARGET_ARCH) $(TARGET)
|
||||
Index: 2007-01-08/xen/Rules.mk
|
||||
===================================================================
|
||||
--- 2007-01-08.orig/xen/Rules.mk 2007-01-08 15:17:24.000000000 +0100
|
||||
+++ 2007-01-08/xen/Rules.mk 2007-01-08 15:17:29.000000000 +0100
|
||||
@@ -34,6 +34,7 @@ TARGET := $(BASEDIR)/xen
|
||||
|
||||
HDRS := $(wildcard $(BASEDIR)/include/xen/*.h)
|
||||
HDRS += $(wildcard $(BASEDIR)/include/public/*.h)
|
||||
+HDRS += $(wildcard $(BASEDIR)/include/compat/*.h)
|
||||
HDRS += $(wildcard $(BASEDIR)/include/asm-$(TARGET_ARCH)/*.h)
|
||||
HDRS += $(wildcard $(BASEDIR)/include/asm-$(TARGET_ARCH)/$(TARGET_SUBARCH)/*.h)
|
||||
|
||||
Index: 2007-01-08/xen/arch/x86/x86_64/compat/entry.S
|
||||
===================================================================
|
||||
--- 2007-01-08.orig/xen/arch/x86/x86_64/compat/entry.S 2007-01-08 15:17:24.000000000 +0100
|
||||
+++ 2007-01-08/xen/arch/x86/x86_64/compat/entry.S 2007-01-08 15:17:29.000000000 +0100
|
||||
@@ -281,28 +281,19 @@ CFIX14:
|
||||
#define compat_set_trap_table domain_crash_synchronous
|
||||
#define compat_mmu_update domain_crash_synchronous
|
||||
#define compat_set_gdt domain_crash_synchronous
|
||||
-#define compat_stack_switch domain_crash_synchronous
|
||||
-#define compat_fpu_taskswitch domain_crash_synchronous
|
||||
-#define compat_arch_sched_op_compat domain_crash_synchronous
|
||||
#define compat_platform_op domain_crash_synchronous
|
||||
-#define compat_set_debugreg domain_crash_synchronous
|
||||
-#define compat_get_debugreg domain_crash_synchronous
|
||||
#define compat_update_descriptor domain_crash_synchronous
|
||||
#define compat_memory_op domain_crash_synchronous
|
||||
#define compat_multicall domain_crash_synchronous
|
||||
#define compat_update_va_mapping domain_crash_synchronous
|
||||
#define compat_set_timer_op domain_crash_synchronous
|
||||
#define compat_event_channel_op_compat domain_crash_synchronous
|
||||
-#define compat_xen_version domain_crash_synchronous
|
||||
-#define compat_console_io domain_crash_synchronous
|
||||
#define compat_physdev_op_compat domain_crash_synchronous
|
||||
#define compat_grant_table_op domain_crash_synchronous
|
||||
-#define compat_vm_assist domain_crash_synchronous
|
||||
#define compat_update_va_mapping_otherdomain domain_crash_synchronous
|
||||
#define compat_vcpu_op domain_crash_synchronous
|
||||
#define compat_mmuext_op domain_crash_synchronous
|
||||
#define compat_acm_op domain_crash_synchronous
|
||||
-#define compat_nmi_op domain_crash_synchronous
|
||||
#define compat_arch_sched_op domain_crash_synchronous
|
||||
#define compat_xenoprof_op domain_crash_synchronous
|
||||
#define compat_event_channel_op domain_crash_synchronous
|
||||
@@ -314,29 +305,29 @@ ENTRY(compat_hypercall_table)
|
||||
.quad compat_set_trap_table /* 0 */
|
||||
.quad compat_mmu_update
|
||||
.quad compat_set_gdt
|
||||
- .quad compat_stack_switch
|
||||
+ .quad do_stack_switch
|
||||
.quad compat_set_callbacks
|
||||
- .quad compat_fpu_taskswitch /* 5 */
|
||||
- .quad compat_arch_sched_op_compat
|
||||
+ .quad do_fpu_taskswitch /* 5 */
|
||||
+ .quad do_sched_op_compat
|
||||
.quad compat_platform_op
|
||||
- .quad compat_set_debugreg
|
||||
- .quad compat_get_debugreg
|
||||
+ .quad do_set_debugreg
|
||||
+ .quad do_get_debugreg
|
||||
.quad compat_update_descriptor /* 10 */
|
||||
- .quad do_ni_hypercall
|
||||
+ .quad compat_ni_hypercall
|
||||
.quad compat_memory_op
|
||||
.quad compat_multicall
|
||||
.quad compat_update_va_mapping
|
||||
.quad compat_set_timer_op /* 15 */
|
||||
.quad compat_event_channel_op_compat
|
||||
.quad compat_xen_version
|
||||
- .quad compat_console_io
|
||||
+ .quad do_console_io
|
||||
.quad compat_physdev_op_compat
|
||||
.quad compat_grant_table_op /* 20 */
|
||||
.quad compat_vm_assist
|
||||
.quad compat_update_va_mapping_otherdomain
|
||||
.quad compat_iret
|
||||
.quad compat_vcpu_op
|
||||
- .quad do_ni_hypercall /* 25 */
|
||||
+ .quad compat_ni_hypercall /* 25 */
|
||||
.quad compat_mmuext_op
|
||||
.quad compat_acm_op
|
||||
.quad compat_nmi_op
|
||||
@@ -345,11 +336,11 @@ ENTRY(compat_hypercall_table)
|
||||
.quad compat_xenoprof_op
|
||||
.quad compat_event_channel_op
|
||||
.quad compat_physdev_op
|
||||
- .quad do_ni_hypercall
|
||||
+ .quad compat_ni_hypercall
|
||||
.quad compat_sysctl /* 35 */
|
||||
.quad compat_domctl
|
||||
.rept NR_hypercalls-((.-compat_hypercall_table)/8)
|
||||
- .quad do_ni_hypercall
|
||||
+ .quad compat_ni_hypercall
|
||||
.endr
|
||||
|
||||
ENTRY(compat_hypercall_args_table)
|
||||
@@ -359,12 +350,12 @@ ENTRY(compat_hypercall_args_table)
|
||||
.byte 2 /* compat_stack_switch */
|
||||
.byte 4 /* compat_set_callbacks */
|
||||
.byte 1 /* compat_fpu_taskswitch */ /* 5 */
|
||||
- .byte 2 /* compat_arch_sched_op_compat */
|
||||
+ .byte 2 /* compat_sched_op_compat */
|
||||
.byte 1 /* compat_platform_op */
|
||||
.byte 2 /* compat_set_debugreg */
|
||||
.byte 1 /* compat_get_debugreg */
|
||||
.byte 4 /* compat_update_descriptor */ /* 10 */
|
||||
- .byte 0 /* do_ni_hypercall */
|
||||
+ .byte 0 /* compat_ni_hypercall */
|
||||
.byte 2 /* compat_memory_op */
|
||||
.byte 2 /* compat_multicall */
|
||||
.byte 4 /* compat_update_va_mapping */
|
||||
@@ -378,7 +369,7 @@ ENTRY(compat_hypercall_args_table)
|
||||
.byte 5 /* compat_update_va_mapping_otherdomain */
|
||||
.byte 0 /* compat_iret */
|
||||
.byte 3 /* compat_vcpu_op */
|
||||
- .byte 0 /* do_ni_hypercall */ /* 25 */
|
||||
+ .byte 0 /* compat_ni_hypercall */ /* 25 */
|
||||
.byte 4 /* compat_mmuext_op */
|
||||
.byte 1 /* compat_acm_op */
|
||||
.byte 2 /* compat_nmi_op */
|
||||
@@ -387,9 +378,9 @@ ENTRY(compat_hypercall_args_table)
|
||||
.byte 2 /* compat_xenoprof_op */
|
||||
.byte 2 /* compat_event_channel_op */
|
||||
.byte 2 /* compat_physdev_op */
|
||||
- .byte 0 /* do_ni_hypercall */
|
||||
+ .byte 0 /* compat_ni_hypercall */
|
||||
.byte 1 /* compat_sysctl */ /* 35 */
|
||||
.byte 1 /* compat_domctl */
|
||||
.rept NR_hypercalls-(.-compat_hypercall_args_table)
|
||||
- .byte 0 /* do_ni_hypercall */
|
||||
+ .byte 0 /* compat_ni_hypercall */
|
||||
.endr
|
||||
Index: 2007-01-08/xen/arch/x86/x86_64/compat/traps.c
|
||||
===================================================================
|
||||
--- 2007-01-08.orig/xen/arch/x86/x86_64/compat/traps.c 2007-01-08 15:17:24.000000000 +0100
|
||||
+++ 2007-01-08/xen/arch/x86/x86_64/compat/traps.c 2007-01-08 15:17:29.000000000 +0100
|
||||
@@ -1,25 +1,6 @@
|
||||
#ifdef CONFIG_COMPAT
|
||||
|
||||
-#if 0 /* XXX */
|
||||
#include <compat/callback.h>
|
||||
-#else
|
||||
-struct compat_xen_callback {
|
||||
- unsigned int cs;
|
||||
- unsigned int eip;
|
||||
-};
|
||||
-typedef struct compat_xen_callback xen_callback_compat_t;
|
||||
-
|
||||
-struct compat_callback_register {
|
||||
- uint16_t type;
|
||||
- uint16_t flags;
|
||||
- xen_callback_compat_t address;
|
||||
-};
|
||||
-
|
||||
-struct compat_callback_unregister {
|
||||
- uint16_t type;
|
||||
- uint16_t _unused;
|
||||
-};
|
||||
-#endif
|
||||
|
||||
void compat_show_guest_stack(struct cpu_user_regs *regs, int debug_stack_lines)
|
||||
{
|
||||
Index: 2007-01-08/xen/common/Makefile
|
||||
===================================================================
|
||||
--- 2007-01-08.orig/xen/common/Makefile 2007-01-08 15:17:24.000000000 +0100
|
||||
+++ 2007-01-08/xen/common/Makefile 2007-01-08 15:17:29.000000000 +0100
|
||||
@@ -35,5 +35,7 @@ obj-$(xenoprof) += xenoprof.o
|
||||
|
||||
obj-$(CONFIG_XENCOMM) += xencomm.o
|
||||
|
||||
+subdir-$(CONFIG_COMPAT) += compat
|
||||
+
|
||||
# Object file contains changeset and compiler information.
|
||||
version.o: $(BASEDIR)/include/xen/compile.h
|
||||
Index: 2007-01-08/xen/common/compat/Makefile
|
||||
===================================================================
|
||||
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
|
||||
+++ 2007-01-08/xen/common/compat/Makefile 2007-01-08 15:17:29.000000000 +0100
|
||||
@@ -0,0 +1,4 @@
|
||||
+obj-y += kernel.o
|
||||
+
|
||||
+# extra dependencies
|
||||
+kernel.o: ../kernel.c
|
||||
Index: 2007-01-08/xen/common/compat/kernel.c
|
||||
===================================================================
|
||||
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
|
||||
+++ 2007-01-08/xen/common/compat/kernel.c 2007-01-08 15:17:29.000000000 +0100
|
||||
@@ -0,0 +1,59 @@
|
||||
+/******************************************************************************
|
||||
+ * kernel.c
|
||||
+ */
|
||||
+
|
||||
+#include <xen/config.h>
|
||||
+#include <xen/init.h>
|
||||
+#include <xen/lib.h>
|
||||
+#include <xen/errno.h>
|
||||
+#include <xen/version.h>
|
||||
+#include <xen/sched.h>
|
||||
+#include <xen/shadow.h>
|
||||
+#include <xen/nmi.h>
|
||||
+#include <xen/guest_access.h>
|
||||
+#include <asm/current.h>
|
||||
+#include <compat/xen.h>
|
||||
+#include <compat/nmi.h>
|
||||
+#include <compat/version.h>
|
||||
+
|
||||
+#define xen_extraversion compat_extraversion
|
||||
+#define xen_extraversion_t compat_extraversion_t
|
||||
+
|
||||
+#define xen_compile_info compat_compile_info
|
||||
+#define xen_compile_info_t compat_compile_info_t
|
||||
+
|
||||
+CHECK_TYPE(capabilities_info);
|
||||
+
|
||||
+#define xen_platform_parameters compat_platform_parameters
|
||||
+#define xen_platform_parameters_t compat_platform_parameters_t
|
||||
+#undef HYPERVISOR_VIRT_START
|
||||
+#define HYPERVISOR_VIRT_START HYPERVISOR_COMPAT_VIRT_START
|
||||
+
|
||||
+#define xen_changeset_info compat_changeset_info
|
||||
+#define xen_changeset_info_t compat_changeset_info_t
|
||||
+
|
||||
+#define xen_feature_info compat_feature_info
|
||||
+#define xen_feature_info_t compat_feature_info_t
|
||||
+
|
||||
+CHECK_TYPE(domain_handle);
|
||||
+
|
||||
+#define xennmi_callback compat_nmi_callback
|
||||
+#define xennmi_callback_t compat_nmi_callback_t
|
||||
+
|
||||
+#define DO(fn) int compat_##fn
|
||||
+#define COMPAT
|
||||
+
|
||||
+#include "../kernel.c"
|
||||
+
|
||||
+int compat_disabled = 0;
|
||||
+boolean_param("no-pv-compat", compat_disabled);
|
||||
+
|
||||
+/*
|
||||
+ * Local variables:
|
||||
+ * mode: C
|
||||
+ * c-set-style: "BSD"
|
||||
+ * c-basic-offset: 4
|
||||
+ * tab-width: 4
|
||||
+ * indent-tabs-mode: nil
|
||||
+ * End:
|
||||
+ */
|
||||
Index: 2007-01-08/xen/common/kernel.c
|
||||
===================================================================
|
||||
--- 2007-01-08.orig/xen/common/kernel.c 2007-01-08 15:17:24.000000000 +0100
|
||||
+++ 2007-01-08/xen/common/kernel.c 2007-01-08 15:17:29.000000000 +0100
|
||||
@@ -11,11 +11,14 @@
|
||||
#include <xen/version.h>
|
||||
#include <xen/sched.h>
|
||||
#include <xen/shadow.h>
|
||||
+#include <xen/nmi.h>
|
||||
#include <xen/guest_access.h>
|
||||
#include <asm/current.h>
|
||||
#include <public/nmi.h>
|
||||
#include <public/version.h>
|
||||
|
||||
+#ifndef COMPAT
|
||||
+
|
||||
int tainted;
|
||||
|
||||
void cmdline_parse(char *cmdline)
|
||||
@@ -116,11 +119,15 @@ void add_taint(unsigned flag)
|
||||
tainted |= flag;
|
||||
}
|
||||
|
||||
+# define DO(fn) long do_##fn
|
||||
+
|
||||
+#endif
|
||||
+
|
||||
/*
|
||||
* Simple hypercalls.
|
||||
*/
|
||||
|
||||
-long do_xen_version(int cmd, XEN_GUEST_HANDLE(void) arg)
|
||||
+DO(xen_version)(int cmd, XEN_GUEST_HANDLE(void) arg)
|
||||
{
|
||||
switch ( cmd )
|
||||
{
|
||||
@@ -230,6 +237,8 @@ long do_xen_version(int cmd, XEN_GUEST_H
|
||||
return -ENOSYS;
|
||||
}
|
||||
|
||||
+#ifndef COMPAT
|
||||
+
|
||||
long register_guest_nmi_callback(unsigned long address)
|
||||
{
|
||||
struct vcpu *v = current;
|
||||
@@ -260,7 +269,9 @@ long unregister_guest_nmi_callback(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
-long do_nmi_op(unsigned int cmd, XEN_GUEST_HANDLE(void) arg)
|
||||
+#endif
|
||||
+
|
||||
+DO(nmi_op)(unsigned int cmd, XEN_GUEST_HANDLE(void) arg)
|
||||
{
|
||||
struct xennmi_callback cb;
|
||||
long rc = 0;
|
||||
@@ -284,12 +295,12 @@ long do_nmi_op(unsigned int cmd, XEN_GUE
|
||||
return rc;
|
||||
}
|
||||
|
||||
-long do_vm_assist(unsigned int cmd, unsigned int type)
|
||||
+DO(vm_assist)(unsigned int cmd, unsigned int type)
|
||||
{
|
||||
return vm_assist(current->domain, cmd, type);
|
||||
}
|
||||
|
||||
-long do_ni_hypercall(void)
|
||||
+DO(ni_hypercall)(void)
|
||||
{
|
||||
/* No-op hypercall. */
|
||||
return -ENOSYS;
|
||||
Index: 2007-01-08/xen/include/Makefile
|
||||
===================================================================
|
||||
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
|
||||
+++ 2007-01-08/xen/include/Makefile 2007-01-08 15:18:26.000000000 +0100
|
||||
@@ -0,0 +1,60 @@
|
||||
+ifneq ($(CONFIG_COMPAT),)
|
||||
+
|
||||
+compat-subarch-$(CONFIG_X86) := x86_32
|
||||
+compat-arch-$(CONFIG_X86) := x86
|
||||
+
|
||||
+headers-y := $(shell echo public/*.h | sed -e 's,[^[:space:]]*-[^[:space:]]*,,g' -e 's,public/,compat/,g')
|
||||
+headers-y := $(filter-out %/dom0_ops.h,$(headers-y))
|
||||
+headers-y += compat/arch-$(compat-subarch-y).h
|
||||
+headers-y += compat/arch-$(compat-arch-y)/xen.h
|
||||
+headers-y += compat/arch-$(compat-arch-y)/xen-$(compat-subarch-y).h
|
||||
+
|
||||
+cppflags-y := -include public/xen-compat.h
|
||||
+cppflags-$(CONFIG_X86) += -m32
|
||||
+
|
||||
+# 8-byte types are 4-byte aligned on x86_32 ...
|
||||
+prefix-$(CONFIG_X86) := \#pragma pack(push, 4)
|
||||
+suffix-$(CONFIG_X86) := \#pragma pack(pop)
|
||||
+
|
||||
+endif
|
||||
+
|
||||
+.PHONY: all
|
||||
+all: $(headers-y)
|
||||
+
|
||||
+compat/%.h: compat/%.i Makefile
|
||||
+ id=_$$(echo $@ | sed 'y,abcdefghijklmnopqrstuvwxyz-/.,ABCDEFGHIJKLMNOPQRSTUVWXYZ___,'); \
|
||||
+ echo "#ifndef $$id" >$@.new; \
|
||||
+ echo "#define $$id" >>$@.new; \
|
||||
+ echo "#include <xen/compat.h>" >>$@.new; \
|
||||
+ $(if $(filter-out compat/arch-%.h,$@),echo "#include <$(patsubst compat/%,public/%,$@)>" >>$@.new;) \
|
||||
+ $(if $(prefix-y),echo "$(prefix-y)" >>$@.new;) \
|
||||
+ grep -v '^# [[:digit:]]' $< | \
|
||||
+ sed -e 's,__InClUdE__,#include,' \
|
||||
+ -e 's,"xen-compat.h",<public/xen-compat.h>,' \
|
||||
+ -e 's,\(struct\|union\|enum\)[[:space:]]\+\(xen_\?\)\?\([[:alpha:]_]\),\1 compat_\3,g' \
|
||||
+ -e 's,_t\([^[:alnum:]_]\|$$\),_compat_t\1,g' \
|
||||
+ -e 's,\(8\|16\|32\|64\)_compat_t\([^[:alnum:]_]\|$$\),\1_t\2,g' \
|
||||
+ -e 's,\(^\|[^[:alnum:]_]\)xen_\?\([[:alnum:]_]*\)_compat_t\([^[:alnum:]_]\|$$\),\1compat_\2_t\3,g' \
|
||||
+ -e 's,\(^\|[^[:alnum:]_]\)XEN_\?,\1COMPAT_,' \
|
||||
+ -e 's,\(^\|[^[:alnum:]_]\)Xen_\?,\1Compat_,' \
|
||||
+ -e 's,\(^\|[^[:alnum:]]\)long\([^[:alnum:]]\|$$\),\1int\2,g' | \
|
||||
+ uniq >>$@.new; \
|
||||
+ $(if $(suffix-y),echo "$(suffix-y)" >>$@.new;) \
|
||||
+ echo "#endif /* $$id */" >>$@.new
|
||||
+ mv -f $@.new $@
|
||||
+
|
||||
+compat/%.i: compat/%.c Makefile
|
||||
+ $(CPP) $(CFLAGS) $(cppflags-y) -o $@ $<
|
||||
+
|
||||
+compat/%.c: public/%.h Makefile
|
||||
+ mkdir -p $(@D)
|
||||
+ grep -v 'DEFINE_XEN_GUEST_HANDLE(long)' $< | \
|
||||
+ sed -e 's,^[[:space:]]*#[[:space:]]*include[[:space:]]\+,__InClUdE__ ,' \
|
||||
+ -e 's,^[[:space:]]*#[[:space:]]*define[[:space:]]\+\([[:upper:]_]*_GUEST_HANDLE\),#define HIDE_\1,' \
|
||||
+ -e 's,^[[:space:]]*#[[:space:]]*define[[:space:]]\+\([[:lower:]_]*_guest_handle\),#define hide_\1,' \
|
||||
+ -e 's,XEN_GUEST_HANDLE\(_[[:xdigit:]]\+\)\?,COMPAT_HANDLE,g' \
|
||||
+ >$@.new
|
||||
+ mv -f $@.new $@
|
||||
+
|
||||
+clean::
|
||||
+ rm -rf compat
|
||||
Index: 2007-01-08/xen/include/asm-x86/compat.h
|
||||
===================================================================
|
||||
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
|
||||
+++ 2007-01-08/xen/include/asm-x86/compat.h 2007-01-08 15:17:29.000000000 +0100
|
||||
@@ -0,0 +1,6 @@
|
||||
+/******************************************************************************
|
||||
+ * compat.h
|
||||
+ */
|
||||
+
|
||||
+typedef uint32_t compat_ptr_t;
|
||||
+typedef unsigned long full_ptr_t;
|
||||
Index: 2007-01-08/xen/include/asm-x86/x86_64/uaccess.h
|
||||
===================================================================
|
||||
--- 2007-01-08.orig/xen/include/asm-x86/x86_64/uaccess.h 2007-01-08 15:17:24.000000000 +0100
|
||||
+++ 2007-01-08/xen/include/asm-x86/x86_64/uaccess.h 2007-01-08 15:17:29.000000000 +0100
|
||||
@@ -15,6 +15,19 @@
|
||||
|
||||
#define array_access_ok(addr, count, size) (__addr_ok(addr))
|
||||
|
||||
+#ifdef CONFIG_COMPAT
|
||||
+
|
||||
+#define __compat_addr_ok(addr) \
|
||||
+ ((unsigned long)(addr) < HYPERVISOR_COMPAT_VIRT_START)
|
||||
+
|
||||
+#define compat_access_ok(addr, size) __compat_addr_ok((addr) + (size))
|
||||
+
|
||||
+#define compat_array_access_ok(addr,count,size) \
|
||||
+ (likely((count) < (~0U / (size))) && \
|
||||
+ compat_access_ok(addr, (count) * (size)))
|
||||
+
|
||||
+#endif
|
||||
+
|
||||
#define __put_user_size(x,ptr,size,retval,errret) \
|
||||
do { \
|
||||
retval = 0; \
|
||||
Index: 2007-01-08/xen/include/xen/compat.h
|
||||
===================================================================
|
||||
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
|
||||
+++ 2007-01-08/xen/include/xen/compat.h 2007-01-08 15:17:29.000000000 +0100
|
||||
@@ -0,0 +1,167 @@
|
||||
+/******************************************************************************
|
||||
+ * compat.h
|
||||
+ */
|
||||
+
|
||||
+#ifndef __XEN_COMPAT_H__
|
||||
+#define __XEN_COMPAT_H__
|
||||
+
|
||||
+#include <xen/config.h>
|
||||
+
|
||||
+#ifdef CONFIG_COMPAT
|
||||
+
|
||||
+#include <xen/types.h>
|
||||
+#include <asm/compat.h>
|
||||
+#include <compat/xlat.h>
|
||||
+
|
||||
+#define __DEFINE_COMPAT_HANDLE(name, type) \
|
||||
+ typedef struct { \
|
||||
+ compat_ptr_t c; \
|
||||
+ type *_[0] __attribute__((__packed__)); \
|
||||
+ } __compat_handle_ ## name
|
||||
+
|
||||
+#define DEFINE_COMPAT_HANDLE(name) __DEFINE_COMPAT_HANDLE(name, name)
|
||||
+#define COMPAT_HANDLE(name) __compat_handle_ ## name
|
||||
+
|
||||
+/* Is the compat handle a NULL reference? */
|
||||
+#define compat_handle_is_null(hnd) ((hnd).c == 0)
|
||||
+
|
||||
+/* Offset the given compat handle into the array it refers to. */
|
||||
+#define compat_handle_add_offset(hnd, nr) \
|
||||
+ ((hnd).c += (nr) * sizeof(**(hnd)._))
|
||||
+
|
||||
+/* Cast a compat handle to the specified type of handle. */
|
||||
+#define compat_handle_cast(chnd, type) ({ \
|
||||
+ type *_x = (__typeof__(**(chnd)._) *)(full_ptr_t)(chnd).c; \
|
||||
+ (XEN_GUEST_HANDLE(type)) { _x }; \
|
||||
+})
|
||||
+
|
||||
+#define guest_from_compat_handle(ghnd, chnd) \
|
||||
+ set_xen_guest_handle(ghnd, \
|
||||
+ (__typeof__(**(chnd)._) *)(full_ptr_t)(chnd).c)
|
||||
+
|
||||
+/*
|
||||
+ * Copy an array of objects to guest context via a compat handle,
|
||||
+ * specifying an offset into the guest array.
|
||||
+ */
|
||||
+#define copy_to_compat_offset(hnd, off, ptr, nr) ({ \
|
||||
+ const typeof(ptr) _x = (typeof(**(hnd)._) *)(full_ptr_t)(hnd).c; \
|
||||
+ const typeof(*(ptr)) *const _y = (ptr); \
|
||||
+ copy_to_user(_x + (off), _y, sizeof(*_x) * (nr)); \
|
||||
+})
|
||||
+
|
||||
+/*
|
||||
+ * Copy an array of objects from guest context via a compat handle,
|
||||
+ * specifying an offset into the guest array.
|
||||
+ */
|
||||
+#define copy_from_compat_offset(ptr, hnd, off, nr) ({ \
|
||||
+ const typeof(ptr) _x = (typeof(**(hnd)._) *)(full_ptr_t)(hnd).c; \
|
||||
+ const typeof(ptr) _y = (ptr); \
|
||||
+ copy_from_user(_y, _x + (off), sizeof(*_x) * (nr)); \
|
||||
+})
|
||||
+
|
||||
+#define copy_to_compat(hnd, ptr, nr) \
|
||||
+ copy_to_compat_offset(hnd, 0, ptr, nr)
|
||||
+
|
||||
+#define copy_from_compat(ptr, hnd, nr) \
|
||||
+ copy_from_compat_offset(ptr, hnd, 0, nr)
|
||||
+
|
||||
+/* Copy sub-field of a structure to guest context via a compat handle. */
|
||||
+#define copy_field_to_compat(hnd, ptr, field) ({ \
|
||||
+ typeof((ptr)->field) *const _x = &((typeof(**(hnd)._) *)(full_ptr_t)(hnd).c)->field; \
|
||||
+ const typeof((ptr)->field) *const _y = &(ptr)->field; \
|
||||
+ copy_to_user(_x, _y, sizeof(*_x)); \
|
||||
+})
|
||||
+
|
||||
+/* Copy sub-field of a structure from guest context via a compat handle. */
|
||||
+#define copy_field_from_compat(ptr, hnd, field) ({ \
|
||||
+ typeof((ptr)->field) *const _x = &((typeof(**(hnd)._) *)(full_ptr_t)(hnd).c)->field; \
|
||||
+ typeof((ptr)->field) *const _y = &(ptr)->field; \
|
||||
+ copy_from_user(_y, _x, sizeof(*_x)); \
|
||||
+})
|
||||
+
|
||||
+/*
|
||||
+ * Pre-validate a guest handle.
|
||||
+ * Allows use of faster __copy_* functions.
|
||||
+ */
|
||||
+#define compat_handle_okay(hnd, nr) \
|
||||
+ compat_array_access_ok((void *)(full_ptr_t)(hnd).c, (nr), sizeof(**(hnd)._))
|
||||
+
|
||||
+#define __copy_to_compat_offset(hnd, off, ptr, nr) ({ \
|
||||
+ const typeof(ptr) _x = (typeof(**(hnd)._) *)(full_ptr_t)(hnd).c; \
|
||||
+ const typeof(*(ptr)) *const _y = (ptr); \
|
||||
+ __copy_to_user(_x + (off), _y, sizeof(*_x) * (nr)); \
|
||||
+})
|
||||
+
|
||||
+#define __copy_from_compat_offset(ptr, hnd, off, nr) ({ \
|
||||
+ const typeof(ptr) _x = (typeof(**(hnd)._) *)(full_ptr_t)(hnd).c; \
|
||||
+ const typeof(ptr) _y = (ptr); \
|
||||
+ __copy_from_user(_y, _x + (off), sizeof(*_x) * (nr)); \
|
||||
+})
|
||||
+
|
||||
+#define __copy_to_compat(hnd, ptr, nr) \
|
||||
+ __copy_to_compat_offset(hnd, 0, ptr, nr)
|
||||
+
|
||||
+#define __copy_from_compat(ptr, hnd, nr) \
|
||||
+ __copy_from_compat_offset(ptr, hnd, 0, nr)
|
||||
+
|
||||
+#define __copy_field_to_compat(hnd, ptr, field) ({ \
|
||||
+ typeof((ptr)->field) *const _x = &((typeof(**(hnd)._) *)(full_ptr_t)(hnd).c)->field; \
|
||||
+ const typeof((ptr)->field) *const _y = &(ptr)->field; \
|
||||
+ __copy_to_user(_x, _y, sizeof(*_x)); \
|
||||
+})
|
||||
+
|
||||
+#define __copy_field_from_compat(ptr, hnd, field) ({ \
|
||||
+ typeof((ptr)->field) *const _x = &((typeof(**(hnd)._) *)(full_ptr_t)(hnd).c)->field; \
|
||||
+ typeof((ptr)->field) *const _y = &(ptr)->field; \
|
||||
+ __copy_from_user(_y, _x, sizeof(*_x)); \
|
||||
+})
|
||||
+
|
||||
+
|
||||
+#define CHECK_TYPE(name) \
|
||||
+ typedef int __checkT ## name[1 - ((xen_ ## name ## _t *)0 != \
|
||||
+ (compat_ ## name ## _t *)0) * 2]
|
||||
+#define CHECK_TYPE_(k, n) \
|
||||
+ typedef int __checkT ## k ## _ ## n[1 - ((k xen_ ## n *)0 != \
|
||||
+ (k compat_ ## n *)0) * 2]
|
||||
+
|
||||
+#define CHECK_SIZE(name) \
|
||||
+ typedef int __checkS ## name[1 - (sizeof(xen_ ## name ## _t) != \
|
||||
+ sizeof(compat_ ## name ## _t)) * 2]
|
||||
+#define CHECK_SIZE_(k, n) \
|
||||
+ typedef int __checkS ## k ## _ ## n[1 - (sizeof(k xen_ ## n) != \
|
||||
+ sizeof(k compat_ ## n)) * 2]
|
||||
+
|
||||
+#define CHECK_FIELD(t, f) \
|
||||
+ typedef int __checkF ## t ## __ ## f[1 - (&((xen_ ## t ## _t *)0)->f != \
|
||||
+ &((compat_ ## t ## _t *)0)->f) * 2]
|
||||
+#define CHECK_FIELD_(k, n, f) \
|
||||
+ typedef int __checkF ## k ## _ ## n ## __ ## f[1 - (&((k xen_ ## n *)0)->f != \
|
||||
+ &((k compat_ ## n *)0)->f) * 2]
|
||||
+
|
||||
+#define CHECK_SUBFIELD_1(t, f1, f2) \
|
||||
+ typedef int __checkF1 ## t ## __ ## f1 ## __ ## f2 \
|
||||
+ [1 - (&((xen_ ## t ## _t *)0)->f1.f2 != \
|
||||
+ &((compat_ ## t ## _t *)0)->f1.f2) * 2]
|
||||
+#define CHECK_SUBFIELD_1_(k, n, f1, f2) \
|
||||
+ typedef int __checkF1 ## k ## _ ## n ## __ ## f1 ## __ ## f2 \
|
||||
+ [1 - (&((k xen_ ## n *)0)->f1.f2 != \
|
||||
+ &((k compat_ ## n *)0)->f1.f2) * 2]
|
||||
+
|
||||
+#define CHECK_SUBFIELD_2(t, f1, f2, f3) \
|
||||
+ typedef int __checkF2 ## t ## __ ## f1 ## __ ## f2 ## __ ## f3 \
|
||||
+ [1 - (&((xen_ ## t ## _t *)0)->f1.f2.f3 != \
|
||||
+ &((compat_ ## t ## _t *)0)->f1.f2.f3) * 2]
|
||||
+#define CHECK_SUBFIELD_2_(k, n, f1, f2, f3) \
|
||||
+ typedef int __checkF2 ## k ## _ ## n ## __ ## f1 ## __ ## f2 ## __ ## f3 \
|
||||
+ [1 - (&((k xen_ ## n *)0)->f1.f2.f3 != \
|
||||
+ &((k compat_ ## n *)0)->f1.f2.f3) * 2]
|
||||
+
|
||||
+extern int compat_disabled;
|
||||
+
|
||||
+/* In-place translation functons: */
|
||||
+struct start_info;
|
||||
+void xlat_start_info(struct start_info *, enum XLAT_start_info_console);
|
||||
+
|
||||
+#endif
|
||||
+
|
||||
+#endif /* __XEN_COMPAT_H__ */
|
226
32on64-kexec.patch
Normal file
226
32on64-kexec.patch
Normal file
@ -0,0 +1,226 @@
|
||||
Enable compatibility mode operation for kexec.
|
||||
|
||||
Index: 2006-12-18/xen/arch/x86/x86_64/compat/entry.S
|
||||
===================================================================
|
||||
--- 2006-12-18.orig/xen/arch/x86/x86_64/compat/entry.S 2006-12-18 09:50:12.000000000 +0100
|
||||
+++ 2006-12-18/xen/arch/x86/x86_64/compat/entry.S 2006-12-18 09:52:27.000000000 +0100
|
||||
@@ -316,6 +316,7 @@ ENTRY(compat_hypercall_table)
|
||||
.quad compat_ni_hypercall
|
||||
.quad compat_sysctl /* 35 */
|
||||
.quad compat_domctl
|
||||
+ .quad compat_kexec_op
|
||||
.rept NR_hypercalls-((.-compat_hypercall_table)/8)
|
||||
.quad compat_ni_hypercall
|
||||
.endr
|
||||
@@ -358,6 +359,7 @@ ENTRY(compat_hypercall_args_table)
|
||||
.byte 0 /* compat_ni_hypercall */
|
||||
.byte 1 /* compat_sysctl */ /* 35 */
|
||||
.byte 1 /* compat_domctl */
|
||||
+ .byte 2 /* compat_kexec_op */
|
||||
.rept NR_hypercalls-(.-compat_hypercall_args_table)
|
||||
.byte 0 /* compat_ni_hypercall */
|
||||
.endr
|
||||
Index: 2006-12-18/xen/common/Makefile
|
||||
===================================================================
|
||||
--- 2006-12-18.orig/xen/common/Makefile 2006-12-18 09:50:08.000000000 +0100
|
||||
+++ 2006-12-18/xen/common/Makefile 2006-12-18 09:52:27.000000000 +0100
|
||||
@@ -44,6 +44,7 @@ ifeq ($(CONFIG_COMPAT),y)
|
||||
# extra dependencies
|
||||
acm_ops.o: compat/acm_ops.c
|
||||
grant_table.o: compat/grant_table.c
|
||||
+kexec.o: compat/kexec.c
|
||||
schedule.o: compat/schedule.c
|
||||
xenoprof.o: compat/xenoprof.c
|
||||
endif
|
||||
Index: 2006-12-18/xen/common/compat/kexec.c
|
||||
===================================================================
|
||||
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
|
||||
+++ 2006-12-18/xen/common/compat/kexec.c 2006-12-18 09:52:27.000000000 +0100
|
||||
@@ -0,0 +1,33 @@
|
||||
+/*
|
||||
+ * compat/kexec.c
|
||||
+ */
|
||||
+
|
||||
+#include <compat/kexec.h>
|
||||
+
|
||||
+#define COMPAT
|
||||
+#define ret_t int
|
||||
+
|
||||
+#define do_kexec_op compat_kexec_op
|
||||
+
|
||||
+#undef kexec_get
|
||||
+#define kexec_get(x) compat_kexec_get_##x
|
||||
+#define xen_kexec_range compat_kexec_range
|
||||
+#define xen_kexec_range_t compat_kexec_range_t
|
||||
+
|
||||
+#define kexec_load_unload compat_kexec_load_unload
|
||||
+#define xen_kexec_load compat_kexec_load
|
||||
+#define xen_kexec_load_t compat_kexec_load_t
|
||||
+
|
||||
+CHECK_kexec_exec;
|
||||
+
|
||||
+#include "../kexec.c"
|
||||
+
|
||||
+/*
|
||||
+ * Local variables:
|
||||
+ * mode: C
|
||||
+ * c-set-style: "BSD"
|
||||
+ * c-basic-offset: 4
|
||||
+ * tab-width: 4
|
||||
+ * indent-tabs-mode: nil
|
||||
+ * End:
|
||||
+ */
|
||||
Index: 2006-12-18/xen/common/kexec.c
|
||||
===================================================================
|
||||
--- 2006-12-18.orig/xen/common/kexec.c 2006-12-15 16:33:59.000000000 +0100
|
||||
+++ 2006-12-18/xen/common/kexec.c 2006-12-18 09:52:27.000000000 +0100
|
||||
@@ -22,6 +22,10 @@
|
||||
#include <xen/version.h>
|
||||
#include <public/elfnote.h>
|
||||
|
||||
+#ifndef COMPAT
|
||||
+
|
||||
+typedef long ret_t;
|
||||
+
|
||||
DEFINE_PER_CPU (crash_note_t, crash_notes);
|
||||
cpumask_t crash_saved_cpus;
|
||||
|
||||
@@ -143,7 +147,11 @@ static __init int register_crashdump_tri
|
||||
}
|
||||
__initcall(register_crashdump_trigger);
|
||||
|
||||
-static int kexec_get_reserve(xen_kexec_range_t *range)
|
||||
+#define kexec_get(x) kexec_get_##x
|
||||
+
|
||||
+#endif
|
||||
+
|
||||
+static int kexec_get(reserve)(xen_kexec_range_t *range)
|
||||
{
|
||||
range->start = kexec_crash_area.start;
|
||||
range->size = kexec_crash_area.size;
|
||||
@@ -152,14 +160,14 @@ static int kexec_get_reserve(xen_kexec_r
|
||||
|
||||
extern unsigned long _text;
|
||||
|
||||
-static int kexec_get_xen(xen_kexec_range_t *range)
|
||||
+static int kexec_get(xen)(xen_kexec_range_t *range)
|
||||
{
|
||||
range->start = virt_to_maddr(&_text);
|
||||
range->size = (unsigned long)&_end - (unsigned long)&_text;
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static int kexec_get_cpu(xen_kexec_range_t *range)
|
||||
+static int kexec_get(cpu)(xen_kexec_range_t *range)
|
||||
{
|
||||
if ( range->nr < 0 || range->nr >= num_present_cpus() )
|
||||
return -EINVAL;
|
||||
@@ -169,7 +177,7 @@ static int kexec_get_cpu(xen_kexec_range
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static int kexec_get_range(XEN_GUEST_HANDLE(void) uarg)
|
||||
+static int kexec_get(range)(XEN_GUEST_HANDLE(void) uarg)
|
||||
{
|
||||
xen_kexec_range_t range;
|
||||
int ret = -EINVAL;
|
||||
@@ -180,13 +188,13 @@ static int kexec_get_range(XEN_GUEST_HAN
|
||||
switch ( range.range )
|
||||
{
|
||||
case KEXEC_RANGE_MA_CRASH:
|
||||
- ret = kexec_get_reserve(&range);
|
||||
+ ret = kexec_get(reserve)(&range);
|
||||
break;
|
||||
case KEXEC_RANGE_MA_XEN:
|
||||
- ret = kexec_get_xen(&range);
|
||||
+ ret = kexec_get(xen)(&range);
|
||||
break;
|
||||
case KEXEC_RANGE_MA_CPU:
|
||||
- ret = kexec_get_cpu(&range);
|
||||
+ ret = kexec_get(cpu)(&range);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -196,6 +204,8 @@ static int kexec_get_range(XEN_GUEST_HAN
|
||||
return ret;
|
||||
}
|
||||
|
||||
+#ifndef COMPAT
|
||||
+
|
||||
static int kexec_load_get_bits(int type, int *base, int *bit)
|
||||
{
|
||||
switch ( type )
|
||||
@@ -214,6 +224,8 @@ static int kexec_load_get_bits(int type,
|
||||
return 0;
|
||||
}
|
||||
|
||||
+#endif
|
||||
+
|
||||
static int kexec_load_unload(unsigned long op, XEN_GUEST_HANDLE(void) uarg)
|
||||
{
|
||||
xen_kexec_load_t load;
|
||||
@@ -236,7 +248,11 @@ static int kexec_load_unload(unsigned lo
|
||||
|
||||
BUG_ON(test_bit((base + !pos), &kexec_flags)); /* must be free */
|
||||
|
||||
+#ifndef COMPAT
|
||||
memcpy(image, &load.image, sizeof(*image));
|
||||
+#else
|
||||
+ XLAT_kexec_image(image, &load.image);
|
||||
+#endif
|
||||
|
||||
if ( !(ret = machine_kexec_load(load.type, base + !pos, image)) )
|
||||
{
|
||||
@@ -261,6 +277,8 @@ static int kexec_load_unload(unsigned lo
|
||||
return ret;
|
||||
}
|
||||
|
||||
+#ifndef COMPAT
|
||||
+
|
||||
static int kexec_exec(XEN_GUEST_HANDLE(void) uarg)
|
||||
{
|
||||
xen_kexec_exec_t exec;
|
||||
@@ -294,7 +312,9 @@ static int kexec_exec(XEN_GUEST_HANDLE(v
|
||||
return -EINVAL; /* never reached */
|
||||
}
|
||||
|
||||
-long do_kexec_op(unsigned long op, XEN_GUEST_HANDLE(void) uarg)
|
||||
+#endif
|
||||
+
|
||||
+ret_t do_kexec_op(unsigned long op, XEN_GUEST_HANDLE(void) uarg)
|
||||
{
|
||||
unsigned long flags;
|
||||
int ret = -EINVAL;
|
||||
@@ -305,7 +325,7 @@ long do_kexec_op(unsigned long op, XEN_G
|
||||
switch ( op )
|
||||
{
|
||||
case KEXEC_CMD_kexec_get_range:
|
||||
- ret = kexec_get_range(uarg);
|
||||
+ ret = kexec_get(range)(uarg);
|
||||
break;
|
||||
case KEXEC_CMD_kexec_load:
|
||||
case KEXEC_CMD_kexec_unload:
|
||||
@@ -324,6 +344,10 @@ long do_kexec_op(unsigned long op, XEN_G
|
||||
return ret;
|
||||
}
|
||||
|
||||
+#if defined(CONFIG_COMPAT) && !defined(COMPAT)
|
||||
+#include "compat/kexec.c"
|
||||
+#endif
|
||||
+
|
||||
/*
|
||||
* Local variables:
|
||||
* mode: C
|
||||
Index: 2006-12-18/xen/include/xlat.lst
|
||||
===================================================================
|
||||
--- 2006-12-18.orig/xen/include/xlat.lst 2006-12-18 09:52:23.000000000 +0100
|
||||
+++ 2006-12-18/xen/include/xlat.lst 2006-12-18 09:52:27.000000000 +0100
|
||||
@@ -32,6 +32,8 @@
|
||||
! gnttab_transfer grant_table.h
|
||||
? gnttab_unmap_grant_ref grant_table.h
|
||||
? grant_entry grant_table.h
|
||||
+? kexec_exec kexec.h
|
||||
+! kexec_image kexec.h
|
||||
! add_to_physmap memory.h
|
||||
! foreign_memory_map memory.h
|
||||
! memory_exchange memory.h
|
1192
32on64-m2p.patch
Normal file
1192
32on64-m2p.patch
Normal file
File diff suppressed because it is too large
Load Diff
1196
32on64-memop.patch
Normal file
1196
32on64-memop.patch
Normal file
File diff suppressed because it is too large
Load Diff
292
32on64-mmuop.patch
Normal file
292
32on64-mmuop.patch
Normal file
@ -0,0 +1,292 @@
|
||||
Enable compatibility mode operation for HYPERVISOR_mmu_update and
|
||||
HYPERVISOR_mmuext_op.
|
||||
|
||||
Index: 2006-12-18/xen/arch/x86/mm.c
|
||||
===================================================================
|
||||
--- 2006-12-18.orig/xen/arch/x86/mm.c 2006-12-18 09:49:30.000000000 +0100
|
||||
+++ 2006-12-18/xen/arch/x86/mm.c 2006-12-18 09:49:35.000000000 +0100
|
||||
@@ -106,6 +106,7 @@
|
||||
#include <asm/ldt.h>
|
||||
#include <asm/x86_emulate.h>
|
||||
#include <asm/e820.h>
|
||||
+#include <asm/hypercall.h>
|
||||
#include <public/memory.h>
|
||||
|
||||
#define MEM_LOG(_f, _a...) gdprintk(XENLOG_WARNING , _f "\n" , ## _a)
|
||||
@@ -119,13 +120,6 @@
|
||||
#define PTE_UPDATE_WITH_CMPXCHG
|
||||
#endif
|
||||
|
||||
-/*
|
||||
- * Both do_mmuext_op() and do_mmu_update():
|
||||
- * We steal the m.s.b. of the @count parameter to indicate whether this
|
||||
- * invocation of do_mmu_update() is resuming a previously preempted call.
|
||||
- */
|
||||
-#define MMU_UPDATE_PREEMPTED (~(~0U>>1))
|
||||
-
|
||||
/* Used to defer flushing of memory structures. */
|
||||
struct percpu_mm_info {
|
||||
#define DOP_FLUSH_TLB (1<<0) /* Flush the local TLB. */
|
||||
@@ -2027,6 +2021,8 @@ int do_mmuext_op(
|
||||
goto pin_page;
|
||||
|
||||
case MMUEXT_PIN_L4_TABLE:
|
||||
+ if ( IS_COMPAT(FOREIGNDOM) )
|
||||
+ break;
|
||||
type = PGT_l4_page_table;
|
||||
|
||||
pin_page:
|
||||
@@ -2090,7 +2086,11 @@ int do_mmuext_op(
|
||||
|
||||
#ifdef __x86_64__
|
||||
case MMUEXT_NEW_USER_BASEPTR:
|
||||
- okay = 1;
|
||||
+ if ( IS_COMPAT(FOREIGNDOM) )
|
||||
+ {
|
||||
+ okay = 0;
|
||||
+ break;
|
||||
+ }
|
||||
if (likely(mfn != 0))
|
||||
{
|
||||
if ( shadow_mode_refcounts(d) )
|
||||
Index: 2006-12-18/xen/arch/x86/x86_64/compat/entry.S
|
||||
===================================================================
|
||||
--- 2006-12-18.orig/xen/arch/x86/x86_64/compat/entry.S 2006-12-18 09:49:30.000000000 +0100
|
||||
+++ 2006-12-18/xen/arch/x86/x86_64/compat/entry.S 2006-12-18 09:49:35.000000000 +0100
|
||||
@@ -279,7 +279,6 @@ CFIX14:
|
||||
.section .rodata, "a", @progbits
|
||||
|
||||
#define compat_set_trap_table domain_crash_synchronous
|
||||
-#define compat_mmu_update domain_crash_synchronous
|
||||
#define compat_set_gdt domain_crash_synchronous
|
||||
#define compat_platform_op domain_crash_synchronous
|
||||
#define compat_multicall domain_crash_synchronous
|
||||
@@ -288,7 +287,6 @@ CFIX14:
|
||||
#define compat_physdev_op_compat domain_crash_synchronous
|
||||
#define compat_grant_table_op domain_crash_synchronous
|
||||
#define compat_vcpu_op domain_crash_synchronous
|
||||
-#define compat_mmuext_op domain_crash_synchronous
|
||||
#define compat_acm_op domain_crash_synchronous
|
||||
#define compat_arch_sched_op domain_crash_synchronous
|
||||
#define compat_xenoprof_op domain_crash_synchronous
|
||||
@@ -299,7 +297,7 @@ CFIX14:
|
||||
|
||||
ENTRY(compat_hypercall_table)
|
||||
.quad compat_set_trap_table /* 0 */
|
||||
- .quad compat_mmu_update
|
||||
+ .quad do_mmu_update
|
||||
.quad compat_set_gdt
|
||||
.quad do_stack_switch
|
||||
.quad compat_set_callbacks
|
||||
Index: 2006-12-18/xen/arch/x86/x86_64/compat/mm.c
|
||||
===================================================================
|
||||
--- 2006-12-18.orig/xen/arch/x86/x86_64/compat/mm.c 2006-12-18 09:49:30.000000000 +0100
|
||||
+++ 2006-12-18/xen/arch/x86/x86_64/compat/mm.c 2006-12-18 09:49:35.000000000 +0100
|
||||
@@ -1,6 +1,8 @@
|
||||
#ifdef CONFIG_COMPAT
|
||||
|
||||
+#include <xen/event.h>
|
||||
#include <compat/memory.h>
|
||||
+#include <compat/xen.h>
|
||||
|
||||
int compat_update_descriptor(u32 pa_lo, u32 pa_hi, u32 desc_lo, u32 desc_hi)
|
||||
{
|
||||
@@ -135,6 +137,152 @@ int compat_update_va_mapping_otherdomain
|
||||
{
|
||||
return do_update_va_mapping_otherdomain(va, lo | ((u64)hi << 32), flags, domid);
|
||||
}
|
||||
+
|
||||
+DEFINE_XEN_GUEST_HANDLE(mmuext_op_compat_t);
|
||||
+
|
||||
+int compat_mmuext_op(XEN_GUEST_HANDLE(mmuext_op_compat_t) cmp_uops,
|
||||
+ unsigned int count,
|
||||
+ XEN_GUEST_HANDLE(uint) pdone,
|
||||
+ unsigned int foreigndom)
|
||||
+{
|
||||
+ unsigned int i, preempt_mask;
|
||||
+ int rc = 0;
|
||||
+ XEN_GUEST_HANDLE(mmuext_op_t) nat_ops;
|
||||
+
|
||||
+ preempt_mask = count & MMU_UPDATE_PREEMPTED;
|
||||
+ count ^= preempt_mask;
|
||||
+
|
||||
+ if ( unlikely(!guest_handle_okay(cmp_uops, count)) )
|
||||
+ return -EFAULT;
|
||||
+
|
||||
+ set_xen_guest_handle(nat_ops, (void *)COMPAT_ARG_XLAT_VIRT_START(current->vcpu_id));
|
||||
+
|
||||
+ for ( ; count; count -= i )
|
||||
+ {
|
||||
+ mmuext_op_t *nat_op = nat_ops.p;
|
||||
+ unsigned int limit;
|
||||
+ int err;
|
||||
+
|
||||
+ if ( hypercall_preempt_check() )
|
||||
+ {
|
||||
+ rc = hypercall_create_continuation(
|
||||
+ __HYPERVISOR_mmuext_op, "hihi",
|
||||
+ cmp_uops, count | MMU_UPDATE_PREEMPTED, pdone, foreigndom);
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ limit = COMPAT_ARG_XLAT_SIZE / sizeof(*nat_op);
|
||||
+
|
||||
+ for ( i = 0; i < min(limit, count); ++i )
|
||||
+ {
|
||||
+ mmuext_op_compat_t cmp_op;
|
||||
+ enum XLAT_mmuext_op_arg1 arg1;
|
||||
+ enum XLAT_mmuext_op_arg2 arg2;
|
||||
+
|
||||
+ if ( unlikely(__copy_from_guest(&cmp_op, cmp_uops, 1) != 0) )
|
||||
+ {
|
||||
+ rc = -EFAULT;
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ switch ( cmp_op.cmd )
|
||||
+ {
|
||||
+ case MMUEXT_PIN_L1_TABLE:
|
||||
+ case MMUEXT_PIN_L2_TABLE:
|
||||
+ case MMUEXT_PIN_L3_TABLE:
|
||||
+ case MMUEXT_PIN_L4_TABLE:
|
||||
+ case MMUEXT_UNPIN_TABLE:
|
||||
+ case MMUEXT_NEW_BASEPTR:
|
||||
+ arg1 = XLAT_mmuext_op_arg1_mfn;
|
||||
+ break;
|
||||
+ default:
|
||||
+ arg1 = XLAT_mmuext_op_arg1_linear_addr;
|
||||
+ break;
|
||||
+ case MMUEXT_NEW_USER_BASEPTR:
|
||||
+ rc = -EINVAL;
|
||||
+ case MMUEXT_TLB_FLUSH_LOCAL:
|
||||
+ case MMUEXT_TLB_FLUSH_MULTI:
|
||||
+ case MMUEXT_TLB_FLUSH_ALL:
|
||||
+ case MMUEXT_FLUSH_CACHE:
|
||||
+ arg1 = -1;
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ if ( rc )
|
||||
+ break;
|
||||
+
|
||||
+ switch ( cmp_op.cmd )
|
||||
+ {
|
||||
+ case MMUEXT_SET_LDT:
|
||||
+ arg2 = XLAT_mmuext_op_arg2_nr_ents;
|
||||
+ break;
|
||||
+ case MMUEXT_TLB_FLUSH_MULTI:
|
||||
+ case MMUEXT_INVLPG_MULTI:
|
||||
+ arg2 = XLAT_mmuext_op_arg2_vcpumask;
|
||||
+ break;
|
||||
+ default:
|
||||
+ arg2 = -1;
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+#define XLAT_mmuext_op_HNDL_arg2_vcpumask(_d_, _s_) \
|
||||
+ do \
|
||||
+ { \
|
||||
+ unsigned int vcpumask; \
|
||||
+ if ( i < --limit ) \
|
||||
+ { \
|
||||
+ (_d_)->arg2.vcpumask.p = (void *)(nat_ops.p + limit); \
|
||||
+ if ( copy_from_compat(&vcpumask, (_s_)->arg2.vcpumask, 1) == 0 ) \
|
||||
+ *(unsigned long *)(_d_)->arg2.vcpumask.p = vcpumask; \
|
||||
+ else \
|
||||
+ rc = -EFAULT; \
|
||||
+ } \
|
||||
+ } while(0)
|
||||
+ XLAT_mmuext_op(nat_op, &cmp_op);
|
||||
+#undef XLAT_mmuext_op_HNDL_arg2_vcpumask
|
||||
+
|
||||
+ if ( rc || i >= limit )
|
||||
+ break;
|
||||
+
|
||||
+ guest_handle_add_offset(cmp_uops, 1);
|
||||
+ ++nat_op;
|
||||
+ }
|
||||
+
|
||||
+ err = do_mmuext_op(nat_ops, i | preempt_mask, pdone, foreigndom);
|
||||
+
|
||||
+ if ( err )
|
||||
+ {
|
||||
+ BUILD_BUG_ON(__HYPERVISOR_mmuext_op <= 0);
|
||||
+ if ( err == __HYPERVISOR_mmuext_op )
|
||||
+ {
|
||||
+ struct cpu_user_regs *regs = guest_cpu_user_regs();
|
||||
+ unsigned int left = regs->ecx & ~MMU_UPDATE_PREEMPTED;
|
||||
+
|
||||
+ BUG_ON(!(regs->ecx & MMU_UPDATE_PREEMPTED));
|
||||
+ BUG_ON(left > count);
|
||||
+ guest_handle_add_offset(nat_ops, count - left);
|
||||
+ BUG_ON(left + i < count);
|
||||
+ guest_handle_add_offset(cmp_uops, (signed int)(count - left - i));
|
||||
+ left = 1;
|
||||
+ BUG_ON(!hypercall_xlat_continuation(&left, 0x01, nat_ops, cmp_uops));
|
||||
+ BUG_ON(left != regs->ecx);
|
||||
+ regs->ecx += count - i;
|
||||
+ }
|
||||
+ else
|
||||
+ BUG_ON(rc > 0);
|
||||
+ rc = err;
|
||||
+ }
|
||||
+
|
||||
+ if ( rc )
|
||||
+ break;
|
||||
+
|
||||
+ /* Force do_mmuext_op() to not start counting from zero again. */
|
||||
+ preempt_mask = MMU_UPDATE_PREEMPTED;
|
||||
+ }
|
||||
+
|
||||
+ return rc;
|
||||
+}
|
||||
+
|
||||
#endif /* CONFIG_COMPAT */
|
||||
|
||||
/*
|
||||
Index: 2006-12-18/xen/common/compat/xlat.c
|
||||
===================================================================
|
||||
--- 2006-12-18.orig/xen/common/compat/xlat.c 2006-12-18 09:46:14.000000000 +0100
|
||||
+++ 2006-12-18/xen/common/compat/xlat.c 2006-12-18 09:49:35.000000000 +0100
|
||||
@@ -21,6 +21,10 @@ void xlat_start_info(struct start_info *
|
||||
CHECK_dom0_vga_console_info;
|
||||
#undef dom0_vga_console_info
|
||||
|
||||
+#define xen_mmu_update mmu_update
|
||||
+CHECK_mmu_update;
|
||||
+#undef xen_mmu_update
|
||||
+
|
||||
#define xen_vcpu_time_info vcpu_time_info
|
||||
CHECK_vcpu_time_info;
|
||||
#undef xen_vcpu_time_info
|
||||
Index: 2006-12-18/xen/include/asm-x86/hypercall.h
|
||||
===================================================================
|
||||
--- 2006-12-18.orig/xen/include/asm-x86/hypercall.h 2006-12-13 11:15:56.000000000 +0100
|
||||
+++ 2006-12-18/xen/include/asm-x86/hypercall.h 2006-12-18 09:49:35.000000000 +0100
|
||||
@@ -8,6 +8,13 @@
|
||||
#include <public/physdev.h>
|
||||
#include <xen/types.h>
|
||||
|
||||
+/*
|
||||
+ * Both do_mmuext_op() and do_mmu_update():
|
||||
+ * We steal the m.s.b. of the @count parameter to indicate whether this
|
||||
+ * invocation of do_mmu_update() is resuming a previously preempted call.
|
||||
+ */
|
||||
+#define MMU_UPDATE_PREEMPTED (~(~0U>>1))
|
||||
+
|
||||
extern long
|
||||
do_event_channel_op_compat(
|
||||
XEN_GUEST_HANDLE(evtchn_op_t) uop);
|
||||
Index: 2006-12-18/xen/include/xlat.lst
|
||||
===================================================================
|
||||
--- 2006-12-18.orig/xen/include/xlat.lst 2006-12-18 09:49:30.000000000 +0100
|
||||
+++ 2006-12-18/xen/include/xlat.lst 2006-12-18 09:49:35.000000000 +0100
|
||||
@@ -2,6 +2,8 @@
|
||||
# ! - needs translation
|
||||
# ? - needs checking
|
||||
? dom0_vga_console_info xen.h
|
||||
+? mmu_update xen.h
|
||||
+! mmuext_op xen.h
|
||||
! start_info xen.h
|
||||
? vcpu_time_info xen.h
|
||||
! add_to_physmap memory.h
|
168
32on64-multicall.patch
Normal file
168
32on64-multicall.patch
Normal file
@ -0,0 +1,168 @@
|
||||
Enable compatibility mode operation for HYPERVISOR_multicall.
|
||||
|
||||
Index: 2006-12-11/xen/arch/x86/x86_64/asm-offsets.c
|
||||
===================================================================
|
||||
--- 2006-12-11.orig/xen/arch/x86/x86_64/asm-offsets.c 2006-12-15 15:28:41.000000000 +0100
|
||||
+++ 2006-12-11/xen/arch/x86/x86_64/asm-offsets.c 2006-12-15 15:33:03.000000000 +0100
|
||||
@@ -135,5 +135,17 @@ void __dummy__(void)
|
||||
OFFSET(MULTICALL_result, struct multicall_entry, result);
|
||||
BLANK();
|
||||
|
||||
+#ifdef CONFIG_COMPAT
|
||||
+ OFFSET(COMPAT_MULTICALL_op, struct compat_multicall_entry, op);
|
||||
+ OFFSET(COMPAT_MULTICALL_arg0, struct compat_multicall_entry, args[0]);
|
||||
+ OFFSET(COMPAT_MULTICALL_arg1, struct compat_multicall_entry, args[1]);
|
||||
+ OFFSET(COMPAT_MULTICALL_arg2, struct compat_multicall_entry, args[2]);
|
||||
+ OFFSET(COMPAT_MULTICALL_arg3, struct compat_multicall_entry, args[3]);
|
||||
+ OFFSET(COMPAT_MULTICALL_arg4, struct compat_multicall_entry, args[4]);
|
||||
+ OFFSET(COMPAT_MULTICALL_arg5, struct compat_multicall_entry, args[5]);
|
||||
+ OFFSET(COMPAT_MULTICALL_result, struct compat_multicall_entry, result);
|
||||
+ BLANK();
|
||||
+#endif
|
||||
+
|
||||
DEFINE(IRQSTAT_shift, LOG_2(sizeof(irq_cpustat_t)));
|
||||
}
|
||||
Index: 2006-12-11/xen/arch/x86/x86_64/compat/entry.S
|
||||
===================================================================
|
||||
--- 2006-12-11.orig/xen/arch/x86/x86_64/compat/entry.S 2006-12-15 15:32:58.000000000 +0100
|
||||
+++ 2006-12-11/xen/arch/x86/x86_64/compat/entry.S 2006-12-15 15:33:03.000000000 +0100
|
||||
@@ -279,7 +279,6 @@ CFIX14:
|
||||
.section .rodata, "a", @progbits
|
||||
|
||||
#define compat_platform_op domain_crash_synchronous
|
||||
-#define compat_multicall domain_crash_synchronous
|
||||
#define compat_set_timer_op domain_crash_synchronous
|
||||
#define compat_grant_table_op domain_crash_synchronous
|
||||
#define compat_acm_op domain_crash_synchronous
|
||||
Index: 2006-12-11/xen/common/compat/Makefile
|
||||
===================================================================
|
||||
--- 2006-12-11.orig/xen/common/compat/Makefile 2006-12-15 15:32:56.000000000 +0100
|
||||
+++ 2006-12-11/xen/common/compat/Makefile 2006-12-15 15:33:03.000000000 +0100
|
||||
@@ -1,7 +1,9 @@
|
||||
obj-y += domain.o
|
||||
obj-y += kernel.o
|
||||
obj-y += memory.o
|
||||
+obj-y += multicall.o
|
||||
obj-y += xlat.o
|
||||
|
||||
# extra dependencies
|
||||
kernel.o: ../kernel.c
|
||||
+multicall.o: ../multicall.c
|
||||
Index: 2006-12-11/xen/common/compat/multicall.c
|
||||
===================================================================
|
||||
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
|
||||
+++ 2006-12-11/xen/common/compat/multicall.c 2006-12-15 15:33:03.000000000 +0100
|
||||
@@ -0,0 +1,31 @@
|
||||
+/******************************************************************************
|
||||
+ * multicall.c
|
||||
+ */
|
||||
+
|
||||
+#include <xen/config.h>
|
||||
+#include <xen/types.h>
|
||||
+#include <xen/multicall.h>
|
||||
+
|
||||
+#define COMPAT
|
||||
+typedef int ret_t;
|
||||
+#undef do_multicall_call
|
||||
+
|
||||
+DEFINE_XEN_GUEST_HANDLE(multicall_entry_compat_t);
|
||||
+#define multicall_entry compat_multicall_entry
|
||||
+#define multicall_entry_t multicall_entry_compat_t
|
||||
+#define do_multicall_call compat_multicall_call
|
||||
+#define call compat_call
|
||||
+#define do_multicall(l, n) compat_multicall(_##l, n)
|
||||
+#define _XEN_GUEST_HANDLE(t) XEN_GUEST_HANDLE(t)
|
||||
+
|
||||
+#include "../multicall.c"
|
||||
+
|
||||
+/*
|
||||
+ * Local variables:
|
||||
+ * mode: C
|
||||
+ * c-set-style: "BSD"
|
||||
+ * c-basic-offset: 4
|
||||
+ * tab-width: 4
|
||||
+ * indent-tabs-mode: nil
|
||||
+ * End:
|
||||
+ */
|
||||
Index: 2006-12-11/xen/common/multicall.c
|
||||
===================================================================
|
||||
--- 2006-12-11.orig/xen/common/multicall.c 2006-12-15 15:20:37.000000000 +0100
|
||||
+++ 2006-12-11/xen/common/multicall.c 2006-12-15 15:33:03.000000000 +0100
|
||||
@@ -13,9 +13,12 @@
|
||||
#include <asm/current.h>
|
||||
#include <asm/hardirq.h>
|
||||
|
||||
+#ifndef COMPAT
|
||||
DEFINE_PER_CPU(struct mc_state, mc_state);
|
||||
+typedef long ret_t;
|
||||
+#endif
|
||||
|
||||
-long
|
||||
+ret_t
|
||||
do_multicall(
|
||||
XEN_GUEST_HANDLE(multicall_entry_t) call_list, unsigned int nr_calls)
|
||||
{
|
||||
Index: 2006-12-11/xen/include/asm-x86/multicall.h
|
||||
===================================================================
|
||||
--- 2006-12-11.orig/xen/include/asm-x86/multicall.h 2006-12-15 15:20:34.000000000 +0100
|
||||
+++ 2006-12-11/xen/include/asm-x86/multicall.h 2006-12-15 15:33:03.000000000 +0100
|
||||
@@ -35,6 +35,31 @@
|
||||
"r8", "r9", "r10", "r11" ); \
|
||||
} while ( 0 )
|
||||
|
||||
+#define compat_multicall_call(_call) \
|
||||
+ do { \
|
||||
+ __asm__ __volatile__ ( \
|
||||
+ " movl "STR(COMPAT_MULTICALL_op)"(%0),%%eax; " \
|
||||
+ " leaq compat_hypercall_table(%%rip),%%rdi; " \
|
||||
+ " cmpl $("STR(NR_hypercalls)"),%%eax; " \
|
||||
+ " jae 2f; " \
|
||||
+ " movq (%%rdi,%%rax,8),%%rax; " \
|
||||
+ " movl "STR(COMPAT_MULTICALL_arg0)"(%0),%%edi; " \
|
||||
+ " movl "STR(COMPAT_MULTICALL_arg1)"(%0),%%esi; " \
|
||||
+ " movl "STR(COMPAT_MULTICALL_arg2)"(%0),%%edx; " \
|
||||
+ " movl "STR(COMPAT_MULTICALL_arg3)"(%0),%%ecx; " \
|
||||
+ " movl "STR(COMPAT_MULTICALL_arg4)"(%0),%%r8d; " \
|
||||
+ " callq *%%rax; " \
|
||||
+ "1: movl %%eax,"STR(COMPAT_MULTICALL_result)"(%0)\n"\
|
||||
+ ".section .fixup,\"ax\"\n" \
|
||||
+ "2: movl $-"STR(ENOSYS)",%%eax\n" \
|
||||
+ " jmp 1b\n" \
|
||||
+ ".previous\n" \
|
||||
+ : : "b" (_call) \
|
||||
+ /* all the caller-saves registers */ \
|
||||
+ : "rax", "rcx", "rdx", "rsi", "rdi", \
|
||||
+ "r8", "r9", "r10", "r11" ); \
|
||||
+ } while ( 0 )
|
||||
+
|
||||
#else
|
||||
|
||||
#define do_multicall_call(_call) \
|
||||
Index: 2006-12-11/xen/include/xen/multicall.h
|
||||
===================================================================
|
||||
--- 2006-12-11.orig/xen/include/xen/multicall.h 2006-12-15 15:20:37.000000000 +0100
|
||||
+++ 2006-12-11/xen/include/xen/multicall.h 2006-12-15 15:33:42.000000000 +0100
|
||||
@@ -7,6 +7,9 @@
|
||||
|
||||
#include <xen/percpu.h>
|
||||
#include <asm/multicall.h>
|
||||
+#ifdef CONFIG_COMPAT
|
||||
+#include <compat/xen.h>
|
||||
+#endif
|
||||
|
||||
#define _MCSF_in_multicall 0
|
||||
#define _MCSF_call_preempted 1
|
||||
@@ -14,7 +17,12 @@
|
||||
#define MCSF_call_preempted (1<<_MCSF_call_preempted)
|
||||
struct mc_state {
|
||||
unsigned long flags;
|
||||
- struct multicall_entry call;
|
||||
+ union {
|
||||
+ struct multicall_entry call;
|
||||
+#ifdef CONFIG_COMPAT
|
||||
+ struct compat_multicall_entry compat_call;
|
||||
+#endif
|
||||
+ };
|
||||
};
|
||||
|
||||
DECLARE_PER_CPU(struct mc_state, mc_state);
|
78
32on64-per-domain-pa-bits.patch
Normal file
78
32on64-per-domain-pa-bits.patch
Normal file
@ -0,0 +1,78 @@
|
||||
Index: 2007-01-08/xen/arch/x86/domain.c
|
||||
===================================================================
|
||||
--- 2007-01-08.orig/xen/arch/x86/domain.c 2007-01-08 15:20:39.000000000 +0100
|
||||
+++ 2007-01-08/xen/arch/x86/domain.c 2007-01-08 14:54:35.000000000 +0100
|
||||
@@ -253,7 +253,7 @@ static void release_compat_l4(struct vcp
|
||||
|
||||
static inline int may_switch_mode(struct domain *d)
|
||||
{
|
||||
- return 1; /* XXX */
|
||||
+ return d->tot_pages == 0;
|
||||
}
|
||||
|
||||
int switch_native(struct domain *d)
|
||||
@@ -281,6 +281,8 @@ int switch_native(struct domain *d)
|
||||
release_compat_l4(d->vcpu[vcpuid]);
|
||||
}
|
||||
|
||||
+ d->pa_bitsize = 0;
|
||||
+
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -311,6 +313,9 @@ int switch_compat(struct domain *d)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
+ d->pa_bitsize = fls((1UL << 32) - HYPERVISOR_COMPAT_VIRT_START(d)) - 1
|
||||
+ + (PAGE_SIZE - 2);
|
||||
+
|
||||
return 0;
|
||||
}
|
||||
|
||||
Index: 2007-01-08/xen/arch/x86/domain_build.c
|
||||
===================================================================
|
||||
--- 2007-01-08.orig/xen/arch/x86/domain_build.c 2007-01-08 14:54:33.000000000 +0100
|
||||
+++ 2007-01-08/xen/arch/x86/domain_build.c 2007-01-08 15:36:39.000000000 +0100
|
||||
@@ -396,6 +396,8 @@ int construct_dom0(struct domain *d,
|
||||
value = (value + mask) & ~mask;
|
||||
#ifdef CONFIG_COMPAT
|
||||
HYPERVISOR_COMPAT_VIRT_START(d) = max_t(unsigned int, m2p_compat_vstart, value);
|
||||
+ d->pa_bitsize = fls((1UL << 32) - HYPERVISOR_COMPAT_VIRT_START(d)) - 1
|
||||
+ + (PAGE_SIZE - 2);
|
||||
if ( value > (!IS_COMPAT(d) ?
|
||||
HYPERVISOR_VIRT_START :
|
||||
__HYPERVISOR_COMPAT_VIRT_START) )
|
||||
Index: 2007-01-08/xen/common/page_alloc.c
|
||||
===================================================================
|
||||
--- 2007-01-08.orig/xen/common/page_alloc.c 2007-01-08 14:54:33.000000000 +0100
|
||||
+++ 2007-01-08/xen/common/page_alloc.c 2007-01-08 14:54:35.000000000 +0100
|
||||
@@ -718,7 +718,12 @@ struct page_info *__alloc_domheap_pages(
|
||||
if ( bits && bits <= PAGE_SHIFT + 1 )
|
||||
return NULL;
|
||||
|
||||
- zone_hi = bits - PAGE_SHIFT - 1;
|
||||
+#ifdef CONFIG_COMPAT
|
||||
+ if ( d && d->pa_bitsize && bits > d->pa_bitsize )
|
||||
+ zone_hi = d->pa_bitsize - PAGE_SHIFT - 1;
|
||||
+ else
|
||||
+#endif
|
||||
+ zone_hi = bits - PAGE_SHIFT - 1;
|
||||
if ( zone_hi >= NR_ZONES )
|
||||
zone_hi = NR_ZONES - 1;
|
||||
|
||||
Index: 2007-01-08/xen/include/xen/sched.h
|
||||
===================================================================
|
||||
--- 2007-01-08.orig/xen/include/xen/sched.h 2007-01-08 15:20:39.000000000 +0100
|
||||
+++ 2007-01-08/xen/include/xen/sched.h 2007-01-08 14:54:35.000000000 +0100
|
||||
@@ -165,6 +165,10 @@ struct domain
|
||||
|
||||
unsigned long domain_flags;
|
||||
|
||||
+#ifdef CONFIG_COMPAT
|
||||
+ unsigned int pa_bitsize;
|
||||
+#endif
|
||||
+
|
||||
/* Boolean: Is this an HVM guest? */
|
||||
char is_hvm;
|
||||
|
316
32on64-physdevop.patch
Normal file
316
32on64-physdevop.patch
Normal file
@ -0,0 +1,316 @@
|
||||
Enable compatibility mode operation for HYPERVISOR_physdev_op and
|
||||
HYPERVISOR_event_channel_op.
|
||||
|
||||
Index: 2006-12-11/xen/arch/x86/compat.c
|
||||
===================================================================
|
||||
--- 2006-12-11.orig/xen/arch/x86/compat.c 2006-12-15 15:20:34.000000000 +0100
|
||||
+++ 2006-12-11/xen/arch/x86/compat.c 2006-12-15 15:32:54.000000000 +0100
|
||||
@@ -9,17 +9,23 @@
|
||||
#include <xen/guest_access.h>
|
||||
#include <xen/hypercall.h>
|
||||
|
||||
+#ifndef COMPAT
|
||||
+typedef long ret_t;
|
||||
+#endif
|
||||
+
|
||||
/* Legacy hypercall (as of 0x00030202). */
|
||||
-long do_physdev_op_compat(XEN_GUEST_HANDLE(physdev_op_t) uop)
|
||||
+ret_t do_physdev_op_compat(XEN_GUEST_HANDLE(physdev_op_t) uop)
|
||||
{
|
||||
struct physdev_op op;
|
||||
|
||||
if ( unlikely(copy_from_guest(&op, uop, 1) != 0) )
|
||||
return -EFAULT;
|
||||
|
||||
- return do_physdev_op(op.cmd, (XEN_GUEST_HANDLE(void)) { &uop.p->u });
|
||||
+ return do_physdev_op(op.cmd, guest_handle_from_ptr(&uop.p->u, void));
|
||||
}
|
||||
|
||||
+#ifndef COMPAT
|
||||
+
|
||||
/* Legacy hypercall (as of 0x00030202). */
|
||||
long do_event_channel_op_compat(XEN_GUEST_HANDLE(evtchn_op_t) uop)
|
||||
{
|
||||
@@ -28,5 +34,7 @@ long do_event_channel_op_compat(XEN_GUES
|
||||
if ( unlikely(copy_from_guest(&op, uop, 1) != 0) )
|
||||
return -EFAULT;
|
||||
|
||||
- return do_event_channel_op(op.cmd, (XEN_GUEST_HANDLE(void)) {&uop.p->u });
|
||||
+ return do_event_channel_op(op.cmd, guest_handle_from_ptr(&uop.p->u, void));
|
||||
}
|
||||
+
|
||||
+#endif
|
||||
Index: 2006-12-11/xen/arch/x86/physdev.c
|
||||
===================================================================
|
||||
--- 2006-12-11.orig/xen/arch/x86/physdev.c 2006-12-15 15:20:34.000000000 +0100
|
||||
+++ 2006-12-11/xen/arch/x86/physdev.c 2006-12-15 15:32:54.000000000 +0100
|
||||
@@ -9,9 +9,14 @@
|
||||
#include <xen/guest_access.h>
|
||||
#include <asm/current.h>
|
||||
#include <asm/smpboot.h>
|
||||
+#include <asm/hypercall.h>
|
||||
#include <public/xen.h>
|
||||
#include <public/physdev.h>
|
||||
|
||||
+#ifndef COMPAT
|
||||
+typedef long ret_t;
|
||||
+#endif
|
||||
+
|
||||
int
|
||||
ioapic_guest_read(
|
||||
unsigned long physbase, unsigned int reg, u32 *pval);
|
||||
@@ -19,10 +24,10 @@ int
|
||||
ioapic_guest_write(
|
||||
unsigned long physbase, unsigned int reg, u32 pval);
|
||||
|
||||
-long do_physdev_op(int cmd, XEN_GUEST_HANDLE(void) arg)
|
||||
+ret_t do_physdev_op(int cmd, XEN_GUEST_HANDLE(void) arg)
|
||||
{
|
||||
int irq;
|
||||
- long ret;
|
||||
+ ret_t ret;
|
||||
|
||||
switch ( cmd )
|
||||
{
|
||||
@@ -129,7 +134,11 @@ long do_physdev_op(int cmd, XEN_GUEST_HA
|
||||
(set_iobitmap.nr_ports > 65536) )
|
||||
break;
|
||||
ret = 0;
|
||||
+#ifndef COMPAT
|
||||
current->arch.iobmp = set_iobitmap.bitmap;
|
||||
+#else
|
||||
+ guest_from_compat_handle(current->arch.iobmp, set_iobitmap.bitmap);
|
||||
+#endif
|
||||
current->arch.iobmp_limit = set_iobitmap.nr_ports;
|
||||
break;
|
||||
}
|
||||
Index: 2006-12-11/xen/arch/x86/x86_64/Makefile
|
||||
===================================================================
|
||||
--- 2006-12-11.orig/xen/arch/x86/x86_64/Makefile 2006-12-15 15:29:19.000000000 +0100
|
||||
+++ 2006-12-11/xen/arch/x86/x86_64/Makefile 2006-12-15 15:32:54.000000000 +0100
|
||||
@@ -3,9 +3,14 @@ obj-y += gpr_switch.o
|
||||
obj-y += mm.o
|
||||
obj-y += traps.o
|
||||
|
||||
+obj-$(CONFIG_COMPAT) += compat.o
|
||||
+obj-$(CONFIG_COMPAT) += physdev.o
|
||||
+
|
||||
ifeq ($(CONFIG_COMPAT),y)
|
||||
# extra dependencies
|
||||
+compat.o: ../compat.c
|
||||
entry.o: compat/entry.S
|
||||
mm.o: compat/mm.c
|
||||
+physdev.o: ../physdev.c
|
||||
traps.o: compat/traps.c
|
||||
endif
|
||||
Index: 2006-12-11/xen/arch/x86/x86_64/compat.c
|
||||
===================================================================
|
||||
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
|
||||
+++ 2006-12-11/xen/arch/x86/x86_64/compat.c 2006-12-15 15:32:54.000000000 +0100
|
||||
@@ -0,0 +1,30 @@
|
||||
+/******************************************************************************
|
||||
+ * compat.c
|
||||
+ */
|
||||
+
|
||||
+#include <xen/config.h>
|
||||
+#include <xen/hypercall.h>
|
||||
+#include <compat/xen.h>
|
||||
+#include <compat/physdev.h>
|
||||
+
|
||||
+DEFINE_XEN_GUEST_HANDLE(physdev_op_compat_t);
|
||||
+#define physdev_op compat_physdev_op
|
||||
+#define physdev_op_t physdev_op_compat_t
|
||||
+#define do_physdev_op compat_physdev_op
|
||||
+#define do_physdev_op_compat(x) compat_physdev_op_compat(_##x)
|
||||
+
|
||||
+#define COMPAT
|
||||
+#define _XEN_GUEST_HANDLE(t) XEN_GUEST_HANDLE(t)
|
||||
+typedef int ret_t;
|
||||
+
|
||||
+#include "../compat.c"
|
||||
+
|
||||
+/*
|
||||
+ * Local variables:
|
||||
+ * mode: C
|
||||
+ * c-set-style: "BSD"
|
||||
+ * c-basic-offset: 4
|
||||
+ * tab-width: 4
|
||||
+ * indent-tabs-mode: nil
|
||||
+ * End:
|
||||
+ */
|
||||
Index: 2006-12-11/xen/arch/x86/x86_64/compat/entry.S
|
||||
===================================================================
|
||||
--- 2006-12-11.orig/xen/arch/x86/x86_64/compat/entry.S 2006-12-15 15:32:08.000000000 +0100
|
||||
+++ 2006-12-11/xen/arch/x86/x86_64/compat/entry.S 2006-12-15 15:32:54.000000000 +0100
|
||||
@@ -283,15 +283,11 @@ CFIX14:
|
||||
#define compat_platform_op domain_crash_synchronous
|
||||
#define compat_multicall domain_crash_synchronous
|
||||
#define compat_set_timer_op domain_crash_synchronous
|
||||
-#define compat_event_channel_op_compat domain_crash_synchronous
|
||||
-#define compat_physdev_op_compat domain_crash_synchronous
|
||||
#define compat_grant_table_op domain_crash_synchronous
|
||||
#define compat_vcpu_op domain_crash_synchronous
|
||||
#define compat_acm_op domain_crash_synchronous
|
||||
#define compat_arch_sched_op domain_crash_synchronous
|
||||
#define compat_xenoprof_op domain_crash_synchronous
|
||||
-#define compat_event_channel_op domain_crash_synchronous
|
||||
-#define compat_physdev_op domain_crash_synchronous
|
||||
#define compat_sysctl domain_crash_synchronous
|
||||
#define compat_domctl domain_crash_synchronous
|
||||
|
||||
@@ -312,7 +308,7 @@ ENTRY(compat_hypercall_table)
|
||||
.quad compat_multicall
|
||||
.quad compat_update_va_mapping
|
||||
.quad compat_set_timer_op /* 15 */
|
||||
- .quad compat_event_channel_op_compat
|
||||
+ .quad do_event_channel_op_compat
|
||||
.quad compat_xen_version
|
||||
.quad do_console_io
|
||||
.quad compat_physdev_op_compat
|
||||
@@ -328,7 +324,7 @@ ENTRY(compat_hypercall_table)
|
||||
.quad compat_arch_sched_op
|
||||
.quad compat_callback_op /* 30 */
|
||||
.quad compat_xenoprof_op
|
||||
- .quad compat_event_channel_op
|
||||
+ .quad do_event_channel_op
|
||||
.quad compat_physdev_op
|
||||
.quad compat_ni_hypercall
|
||||
.quad compat_sysctl /* 35 */
|
||||
Index: 2006-12-11/xen/arch/x86/x86_64/physdev.c
|
||||
===================================================================
|
||||
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
|
||||
+++ 2006-12-11/xen/arch/x86/x86_64/physdev.c 2006-12-15 15:32:54.000000000 +0100
|
||||
@@ -0,0 +1,48 @@
|
||||
+/******************************************************************************
|
||||
+ * physdev.c
|
||||
+ */
|
||||
+
|
||||
+#include <xen/config.h>
|
||||
+#include <xen/types.h>
|
||||
+#include <xen/guest_access.h>
|
||||
+#include <compat/xen.h>
|
||||
+#include <compat/event_channel.h>
|
||||
+#include <compat/physdev.h>
|
||||
+#include <asm/hypercall.h>
|
||||
+
|
||||
+#define do_physdev_op compat_physdev_op
|
||||
+
|
||||
+#define physdev_apic compat_physdev_apic
|
||||
+#define physdev_apic_t physdev_apic_compat_t
|
||||
+
|
||||
+#define physdev_eoi compat_physdev_eoi
|
||||
+#define physdev_eoi_t physdev_eoi_compat_t
|
||||
+
|
||||
+#define physdev_set_iobitmap compat_physdev_set_iobitmap
|
||||
+#define physdev_set_iobitmap_t physdev_set_iobitmap_compat_t
|
||||
+
|
||||
+#define physdev_set_iopl compat_physdev_set_iopl
|
||||
+#define physdev_set_iopl_t physdev_set_iopl_compat_t
|
||||
+
|
||||
+#define physdev_irq compat_physdev_irq
|
||||
+#define physdev_irq_t physdev_irq_compat_t
|
||||
+
|
||||
+#define physdev_irq_status_query compat_physdev_irq_status_query
|
||||
+#define physdev_irq_status_query_t physdev_irq_status_query_compat_t
|
||||
+
|
||||
+#define COMPAT
|
||||
+#undef guest_handle_okay
|
||||
+#define guest_handle_okay compat_handle_okay
|
||||
+typedef int ret_t;
|
||||
+
|
||||
+#include "../physdev.c"
|
||||
+
|
||||
+/*
|
||||
+ * Local variables:
|
||||
+ * mode: C
|
||||
+ * c-set-style: "BSD"
|
||||
+ * c-basic-offset: 4
|
||||
+ * tab-width: 4
|
||||
+ * indent-tabs-mode: nil
|
||||
+ * End:
|
||||
+ */
|
||||
Index: 2006-12-11/xen/common/compat/xlat.c
|
||||
===================================================================
|
||||
--- 2006-12-11.orig/xen/common/compat/xlat.c 2006-12-15 15:32:08.000000000 +0100
|
||||
+++ 2006-12-11/xen/common/compat/xlat.c 2006-12-15 15:32:54.000000000 +0100
|
||||
@@ -4,8 +4,8 @@
|
||||
|
||||
#include <xen/compat.h>
|
||||
#include <xen/lib.h>
|
||||
-#include <public/xen.h>
|
||||
#include <compat/xen.h>
|
||||
+#include <compat/event_channel.h>
|
||||
|
||||
/* In-place translation functons: */
|
||||
void xlat_start_info(struct start_info *native,
|
||||
@@ -21,6 +21,30 @@ void xlat_start_info(struct start_info *
|
||||
CHECK_dom0_vga_console_info;
|
||||
#undef dom0_vga_console_info
|
||||
|
||||
+#define xen_evtchn_alloc_unbound evtchn_alloc_unbound
|
||||
+#define xen_evtchn_bind_interdomain evtchn_bind_interdomain
|
||||
+#define xen_evtchn_bind_ipi evtchn_bind_ipi
|
||||
+#define xen_evtchn_bind_pirq evtchn_bind_pirq
|
||||
+#define xen_evtchn_bind_vcpu evtchn_bind_vcpu
|
||||
+#define xen_evtchn_bind_virq evtchn_bind_virq
|
||||
+#define xen_evtchn_close evtchn_close
|
||||
+#define xen_evtchn_op evtchn_op
|
||||
+#define xen_evtchn_send evtchn_send
|
||||
+#define xen_evtchn_status evtchn_status
|
||||
+#define xen_evtchn_unmask evtchn_unmask
|
||||
+CHECK_evtchn_op;
|
||||
+#undef xen_evtchn_alloc_unbound
|
||||
+#undef xen_evtchn_bind_interdomain
|
||||
+#undef xen_evtchn_bind_ipi
|
||||
+#undef xen_evtchn_bind_pirq
|
||||
+#undef xen_evtchn_bind_vcpu
|
||||
+#undef xen_evtchn_bind_virq
|
||||
+#undef xen_evtchn_close
|
||||
+#undef xen_evtchn_op
|
||||
+#undef xen_evtchn_send
|
||||
+#undef xen_evtchn_status
|
||||
+#undef xen_evtchn_unmask
|
||||
+
|
||||
#define xen_mmu_update mmu_update
|
||||
CHECK_mmu_update;
|
||||
#undef xen_mmu_update
|
||||
Index: 2006-12-11/xen/include/asm-x86/hypercall.h
|
||||
===================================================================
|
||||
--- 2006-12-11.orig/xen/include/asm-x86/hypercall.h 2006-12-15 15:32:08.000000000 +0100
|
||||
+++ 2006-12-11/xen/include/asm-x86/hypercall.h 2006-12-15 15:32:54.000000000 +0100
|
||||
@@ -123,4 +123,13 @@ do_set_callbacks(
|
||||
|
||||
#endif
|
||||
|
||||
+#ifdef CONFIG_COMPAT
|
||||
+
|
||||
+extern int
|
||||
+compat_physdev_op(
|
||||
+ int cmd,
|
||||
+ XEN_GUEST_HANDLE(void) arg);
|
||||
+
|
||||
+#endif
|
||||
+
|
||||
#endif /* __ASM_X86_HYPERCALL_H__ */
|
||||
Index: 2006-12-11/xen/include/xlat.lst
|
||||
===================================================================
|
||||
--- 2006-12-11.orig/xen/include/xlat.lst 2006-12-15 15:32:08.000000000 +0100
|
||||
+++ 2006-12-11/xen/include/xlat.lst 2006-12-15 15:32:54.000000000 +0100
|
||||
@@ -6,6 +6,17 @@
|
||||
! mmuext_op xen.h
|
||||
! start_info xen.h
|
||||
? vcpu_time_info xen.h
|
||||
+? evtchn_alloc_unbound event_channel.h
|
||||
+? evtchn_bind_interdomain event_channel.h
|
||||
+? evtchn_bind_ipi event_channel.h
|
||||
+? evtchn_bind_pirq event_channel.h
|
||||
+? evtchn_bind_vcpu event_channel.h
|
||||
+? evtchn_bind_virq event_channel.h
|
||||
+? evtchn_close event_channel.h
|
||||
+? evtchn_op event_channel.h
|
||||
+? evtchn_send event_channel.h
|
||||
+? evtchn_status event_channel.h
|
||||
+? evtchn_unmask event_channel.h
|
||||
! add_to_physmap memory.h
|
||||
! foreign_memory_map memory.h
|
||||
! memory_exchange memory.h
|
108
32on64-pltop.patch
Normal file
108
32on64-pltop.patch
Normal file
@ -0,0 +1,108 @@
|
||||
Enable compatibility mode operation for HYPERVISOR_platformop.
|
||||
|
||||
Index: 2006-12-11/xen/arch/x86/platform_hypercall.c
|
||||
===================================================================
|
||||
--- 2006-12-11.orig/xen/arch/x86/platform_hypercall.c 2006-12-15 15:20:33.000000000 +0100
|
||||
+++ 2006-12-11/xen/arch/x86/platform_hypercall.c 2006-12-15 15:37:24.000000000 +0100
|
||||
@@ -23,11 +23,17 @@
|
||||
#include <asm/mtrr.h>
|
||||
#include "cpu/mtrr/mtrr.h"
|
||||
|
||||
-long do_platform_op(XEN_GUEST_HANDLE(xen_platform_op_t) u_xenpf_op)
|
||||
+#ifndef COMPAT
|
||||
+typedef long ret_t;
|
||||
+DEFINE_SPINLOCK(xenpf_lock);
|
||||
+#else
|
||||
+extern spinlock_t xenpf_lock;
|
||||
+#endif
|
||||
+
|
||||
+ret_t do_platform_op(XEN_GUEST_HANDLE(xen_platform_op_t) u_xenpf_op)
|
||||
{
|
||||
- long ret = 0;
|
||||
+ ret_t ret = 0;
|
||||
struct xen_platform_op curop, *op = &curop;
|
||||
- static DEFINE_SPINLOCK(xenpf_lock);
|
||||
|
||||
if ( !IS_PRIV(current->domain) )
|
||||
return -EPERM;
|
||||
@@ -105,8 +111,15 @@ long do_platform_op(XEN_GUEST_HANDLE(xen
|
||||
case XENPF_microcode_update:
|
||||
{
|
||||
extern int microcode_update(XEN_GUEST_HANDLE(void), unsigned long len);
|
||||
+#ifndef COMPAT
|
||||
ret = microcode_update(op->u.microcode.data,
|
||||
op->u.microcode.length);
|
||||
+#else
|
||||
+ XEN_GUEST_HANDLE(void) data;
|
||||
+
|
||||
+ guest_from_compat_handle(data, op->u.microcode.data);
|
||||
+ ret = microcode_update(data, op->u.microcode.length);
|
||||
+#endif
|
||||
}
|
||||
break;
|
||||
|
||||
Index: 2006-12-11/xen/arch/x86/x86_64/Makefile
|
||||
===================================================================
|
||||
--- 2006-12-11.orig/xen/arch/x86/x86_64/Makefile 2006-12-15 15:37:19.000000000 +0100
|
||||
+++ 2006-12-11/xen/arch/x86/x86_64/Makefile 2006-12-15 15:37:24.000000000 +0100
|
||||
@@ -6,6 +6,7 @@ obj-y += traps.o
|
||||
obj-$(CONFIG_COMPAT) += compat.o
|
||||
obj-$(CONFIG_COMPAT) += domain.o
|
||||
obj-$(CONFIG_COMPAT) += physdev.o
|
||||
+obj-$(CONFIG_COMPAT) += platform_hypercall.o
|
||||
|
||||
ifeq ($(CONFIG_COMPAT),y)
|
||||
# extra dependencies
|
||||
@@ -13,5 +14,6 @@ compat.o: ../compat.c
|
||||
entry.o: compat/entry.S
|
||||
mm.o: compat/mm.c
|
||||
physdev.o: ../physdev.c
|
||||
+platform_hypercall.o: ../platform_hypercall.c
|
||||
traps.o: compat/traps.c
|
||||
endif
|
||||
Index: 2006-12-11/xen/arch/x86/x86_64/compat/entry.S
|
||||
===================================================================
|
||||
--- 2006-12-11.orig/xen/arch/x86/x86_64/compat/entry.S 2006-12-15 15:37:22.000000000 +0100
|
||||
+++ 2006-12-11/xen/arch/x86/x86_64/compat/entry.S 2006-12-15 15:37:24.000000000 +0100
|
||||
@@ -278,7 +278,6 @@ CFIX14:
|
||||
|
||||
.section .rodata, "a", @progbits
|
||||
|
||||
-#define compat_platform_op domain_crash_synchronous
|
||||
#define compat_acm_op domain_crash_synchronous
|
||||
#define compat_xenoprof_op domain_crash_synchronous
|
||||
#define compat_sysctl domain_crash_synchronous
|
||||
Index: 2006-12-11/xen/arch/x86/x86_64/platform_hypercall.c
|
||||
===================================================================
|
||||
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
|
||||
+++ 2006-12-11/xen/arch/x86/x86_64/platform_hypercall.c 2006-12-15 15:37:24.000000000 +0100
|
||||
@@ -0,0 +1,29 @@
|
||||
+/******************************************************************************
|
||||
+ * platform_hypercall.c
|
||||
+ *
|
||||
+ */
|
||||
+
|
||||
+#include <xen/config.h>
|
||||
+#include <xen/types.h>
|
||||
+#include <compat/platform.h>
|
||||
+
|
||||
+DEFINE_XEN_GUEST_HANDLE(compat_platform_op_t);
|
||||
+#define xen_platform_op compat_platform_op
|
||||
+#define xen_platform_op_t compat_platform_op_t
|
||||
+#define do_platform_op(x) compat_platform_op(_##x)
|
||||
+
|
||||
+#define COMPAT
|
||||
+#define _XEN_GUEST_HANDLE(t) XEN_GUEST_HANDLE(t)
|
||||
+typedef int ret_t;
|
||||
+
|
||||
+#include "../platform_hypercall.c"
|
||||
+
|
||||
+/*
|
||||
+ * Local variables:
|
||||
+ * mode: C
|
||||
+ * c-set-style: "BSD"
|
||||
+ * c-basic-offset: 4
|
||||
+ * tab-width: 4
|
||||
+ * indent-tabs-mode: nil
|
||||
+ * End:
|
||||
+ */
|
167
32on64-schedop.patch
Normal file
167
32on64-schedop.patch
Normal file
@ -0,0 +1,167 @@
|
||||
Enable compatibility mode operation for HYPERVISOR_sched_op and
|
||||
HYPERVISOR_set_timer_op.
|
||||
|
||||
Index: 2006-12-18/xen/arch/x86/x86_64/compat/entry.S
|
||||
===================================================================
|
||||
--- 2006-12-18.orig/xen/arch/x86/x86_64/compat/entry.S 2006-12-18 09:49:55.000000000 +0100
|
||||
+++ 2006-12-18/xen/arch/x86/x86_64/compat/entry.S 2006-12-18 09:49:57.000000000 +0100
|
||||
@@ -279,10 +279,8 @@ CFIX14:
|
||||
.section .rodata, "a", @progbits
|
||||
|
||||
#define compat_platform_op domain_crash_synchronous
|
||||
-#define compat_set_timer_op domain_crash_synchronous
|
||||
#define compat_grant_table_op domain_crash_synchronous
|
||||
#define compat_acm_op domain_crash_synchronous
|
||||
-#define compat_arch_sched_op domain_crash_synchronous
|
||||
#define compat_xenoprof_op domain_crash_synchronous
|
||||
#define compat_sysctl domain_crash_synchronous
|
||||
#define compat_domctl domain_crash_synchronous
|
||||
@@ -317,7 +315,7 @@ ENTRY(compat_hypercall_table)
|
||||
.quad compat_mmuext_op
|
||||
.quad compat_acm_op
|
||||
.quad compat_nmi_op
|
||||
- .quad compat_arch_sched_op
|
||||
+ .quad compat_sched_op
|
||||
.quad compat_callback_op /* 30 */
|
||||
.quad compat_xenoprof_op
|
||||
.quad do_event_channel_op
|
||||
@@ -359,7 +357,7 @@ ENTRY(compat_hypercall_args_table)
|
||||
.byte 4 /* compat_mmuext_op */
|
||||
.byte 1 /* compat_acm_op */
|
||||
.byte 2 /* compat_nmi_op */
|
||||
- .byte 2 /* compat_arch_sched_op */
|
||||
+ .byte 2 /* compat_sched_op */
|
||||
.byte 2 /* compat_callback_op */ /* 30 */
|
||||
.byte 2 /* compat_xenoprof_op */
|
||||
.byte 2 /* compat_event_channel_op */
|
||||
Index: 2006-12-18/xen/common/Makefile
|
||||
===================================================================
|
||||
--- 2006-12-18.orig/xen/common/Makefile 2006-12-18 09:43:12.000000000 +0100
|
||||
+++ 2006-12-18/xen/common/Makefile 2006-12-18 09:49:57.000000000 +0100
|
||||
@@ -39,3 +39,8 @@ subdir-$(CONFIG_COMPAT) += compat
|
||||
|
||||
# Object file contains changeset and compiler information.
|
||||
version.o: $(BASEDIR)/include/xen/compile.h
|
||||
+
|
||||
+ifeq ($(CONFIG_COMPAT),y)
|
||||
+# extra dependencies
|
||||
+schedule.o: compat/schedule.c
|
||||
+endif
|
||||
Index: 2006-12-18/xen/common/compat/schedule.c
|
||||
===================================================================
|
||||
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
|
||||
+++ 2006-12-18/xen/common/compat/schedule.c 2006-12-18 09:49:57.000000000 +0100
|
||||
@@ -0,0 +1,51 @@
|
||||
+/****************************************************************************
|
||||
+ * schedule.c
|
||||
+ *
|
||||
+ */
|
||||
+
|
||||
+#include <compat/sched.h>
|
||||
+
|
||||
+#define COMPAT
|
||||
+#define ret_t int
|
||||
+
|
||||
+#define do_sched_op compat_sched_op
|
||||
+
|
||||
+#define xen_sched_shutdown sched_shutdown
|
||||
+CHECK_sched_shutdown;
|
||||
+#undef xen_sched_shutdown
|
||||
+
|
||||
+#define xen_sched_remote_shutdown sched_remote_shutdown
|
||||
+CHECK_sched_remote_shutdown;
|
||||
+#undef xen_sched_remote_shutdown
|
||||
+
|
||||
+static int compat_poll(struct compat_sched_poll *compat)
|
||||
+{
|
||||
+ struct sched_poll native;
|
||||
+
|
||||
+#define XLAT_sched_poll_HNDL_ports(_d_, _s_) \
|
||||
+ guest_from_compat_handle((_d_)->ports, (_s_)->ports)
|
||||
+ XLAT_sched_poll(&native, compat);
|
||||
+#undef XLAT_sched_poll_HNDL_ports
|
||||
+
|
||||
+ return do_poll(&native);
|
||||
+}
|
||||
+
|
||||
+#define do_poll compat_poll
|
||||
+#define sched_poll compat_sched_poll
|
||||
+
|
||||
+#include "../schedule.c"
|
||||
+
|
||||
+int compat_set_timer_op(u32 lo, s32 hi)
|
||||
+{
|
||||
+ return do_set_timer_op(((s64)hi << 32) | lo);
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * Local variables:
|
||||
+ * mode: C
|
||||
+ * c-set-style: "BSD"
|
||||
+ * c-basic-offset: 4
|
||||
+ * tab-width: 4
|
||||
+ * indent-tabs-mode: nil
|
||||
+ * End:
|
||||
+ */
|
||||
Index: 2006-12-18/xen/common/schedule.c
|
||||
===================================================================
|
||||
--- 2006-12-18.orig/xen/common/schedule.c 2006-12-18 09:46:14.000000000 +0100
|
||||
+++ 2006-12-18/xen/common/schedule.c 2006-12-18 09:49:57.000000000 +0100
|
||||
@@ -13,6 +13,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
+#ifndef COMPAT
|
||||
#include <xen/config.h>
|
||||
#include <xen/init.h>
|
||||
#include <xen/lib.h>
|
||||
@@ -366,9 +367,13 @@ long do_sched_op_compat(int cmd, unsigne
|
||||
return ret;
|
||||
}
|
||||
|
||||
-long do_sched_op(int cmd, XEN_GUEST_HANDLE(void) arg)
|
||||
+typedef long ret_t;
|
||||
+
|
||||
+#endif /* !COMPAT */
|
||||
+
|
||||
+ret_t do_sched_op(int cmd, XEN_GUEST_HANDLE(void) arg)
|
||||
{
|
||||
- long ret = 0;
|
||||
+ ret_t ret = 0;
|
||||
|
||||
switch ( cmd )
|
||||
{
|
||||
@@ -445,6 +450,8 @@ long do_sched_op(int cmd, XEN_GUEST_HAND
|
||||
return ret;
|
||||
}
|
||||
|
||||
+#ifndef COMPAT
|
||||
+
|
||||
/* Per-domain one-shot-timer hypercall. */
|
||||
long do_set_timer_op(s_time_t timeout)
|
||||
{
|
||||
@@ -736,6 +743,12 @@ void dump_runq(unsigned char key)
|
||||
local_irq_restore(flags);
|
||||
}
|
||||
|
||||
+#ifdef CONFIG_COMPAT
|
||||
+#include "compat/schedule.c"
|
||||
+#endif
|
||||
+
|
||||
+#endif /* !COMPAT */
|
||||
+
|
||||
/*
|
||||
* Local variables:
|
||||
* mode: C
|
||||
Index: 2006-12-18/xen/include/xlat.lst
|
||||
===================================================================
|
||||
--- 2006-12-18.orig/xen/include/xlat.lst 2006-12-18 09:49:49.000000000 +0100
|
||||
+++ 2006-12-18/xen/include/xlat.lst 2006-12-18 09:49:57.000000000 +0100
|
||||
@@ -26,4 +26,7 @@
|
||||
! memory_map memory.h
|
||||
! memory_reservation memory.h
|
||||
! translate_gpfn_list memory.h
|
||||
+! sched_poll sched.h
|
||||
+? sched_remote_shutdown sched.h
|
||||
+? sched_shutdown sched.h
|
||||
! vcpu_runstate_info vcpu.h
|
123
32on64-settrap.patch
Normal file
123
32on64-settrap.patch
Normal file
@ -0,0 +1,123 @@
|
||||
Enable compatibility mode operation for HYPERVISOR_set_trap_table and
|
||||
HYPERVISOR_set_gdt.
|
||||
|
||||
Index: 2006-12-11/xen/arch/x86/x86_64/compat/entry.S
|
||||
===================================================================
|
||||
--- 2006-12-11.orig/xen/arch/x86/x86_64/compat/entry.S 2006-12-15 15:32:56.000000000 +0100
|
||||
+++ 2006-12-11/xen/arch/x86/x86_64/compat/entry.S 2006-12-15 15:32:58.000000000 +0100
|
||||
@@ -278,8 +278,6 @@ CFIX14:
|
||||
|
||||
.section .rodata, "a", @progbits
|
||||
|
||||
-#define compat_set_trap_table domain_crash_synchronous
|
||||
-#define compat_set_gdt domain_crash_synchronous
|
||||
#define compat_platform_op domain_crash_synchronous
|
||||
#define compat_multicall domain_crash_synchronous
|
||||
#define compat_set_timer_op domain_crash_synchronous
|
||||
Index: 2006-12-11/xen/arch/x86/x86_64/compat/mm.c
|
||||
===================================================================
|
||||
--- 2006-12-11.orig/xen/arch/x86/x86_64/compat/mm.c 2006-12-15 15:32:08.000000000 +0100
|
||||
+++ 2006-12-11/xen/arch/x86/x86_64/compat/mm.c 2006-12-15 15:32:58.000000000 +0100
|
||||
@@ -4,6 +4,39 @@
|
||||
#include <compat/memory.h>
|
||||
#include <compat/xen.h>
|
||||
|
||||
+int compat_set_gdt(XEN_GUEST_HANDLE(uint) frame_list, unsigned int entries)
|
||||
+{
|
||||
+ unsigned int i, nr_pages = (entries + 511) / 512;
|
||||
+ unsigned long frames[16];
|
||||
+ long ret;
|
||||
+
|
||||
+ /* Rechecked in set_gdt, but ensures a sane limit for copy_from_user(). */
|
||||
+ if ( entries > FIRST_RESERVED_GDT_ENTRY )
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ if ( !guest_handle_okay(frame_list, nr_pages) )
|
||||
+ return -EFAULT;
|
||||
+
|
||||
+ for ( i = 0; i < nr_pages; ++i )
|
||||
+ {
|
||||
+ unsigned int frame;
|
||||
+
|
||||
+ if ( __copy_from_guest(&frame, frame_list, 1) )
|
||||
+ return -EFAULT;
|
||||
+ frames[i] = frame;
|
||||
+ guest_handle_add_offset(frame_list, 1);
|
||||
+ }
|
||||
+
|
||||
+ LOCK_BIGLOCK(current->domain);
|
||||
+
|
||||
+ if ( (ret = set_gdt(current, frames, entries)) == 0 )
|
||||
+ local_flush_tlb();
|
||||
+
|
||||
+ UNLOCK_BIGLOCK(current->domain);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
int compat_update_descriptor(u32 pa_lo, u32 pa_hi, u32 desc_lo, u32 desc_hi)
|
||||
{
|
||||
return do_update_descriptor(pa_lo | ((u64)pa_hi << 32),
|
||||
Index: 2006-12-11/xen/arch/x86/x86_64/compat/traps.c
|
||||
===================================================================
|
||||
--- 2006-12-11.orig/xen/arch/x86/x86_64/compat/traps.c 2006-12-15 15:28:41.000000000 +0100
|
||||
+++ 2006-12-11/xen/arch/x86/x86_64/compat/traps.c 2006-12-15 15:32:58.000000000 +0100
|
||||
@@ -1,6 +1,8 @@
|
||||
#ifdef CONFIG_COMPAT
|
||||
|
||||
+#include <xen/event.h>
|
||||
#include <compat/callback.h>
|
||||
+#include <compat/arch-x86_32.h>
|
||||
|
||||
void compat_show_guest_stack(struct cpu_user_regs *regs, int debug_stack_lines)
|
||||
{
|
||||
@@ -252,6 +254,49 @@ long compat_set_callbacks(unsigned long
|
||||
return 0;
|
||||
}
|
||||
|
||||
+DEFINE_XEN_GUEST_HANDLE(trap_info_compat_t);
|
||||
+
|
||||
+int compat_set_trap_table(XEN_GUEST_HANDLE(trap_info_compat_t) traps)
|
||||
+{
|
||||
+ struct compat_trap_info cur;
|
||||
+ struct trap_info *dst = current->arch.guest_context.trap_ctxt;
|
||||
+ long rc = 0;
|
||||
+
|
||||
+ /* If no table is presented then clear the entire virtual IDT. */
|
||||
+ if ( guest_handle_is_null(traps) )
|
||||
+ {
|
||||
+ memset(dst, 0, 256 * sizeof(*dst));
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ for ( ; ; )
|
||||
+ {
|
||||
+ if ( hypercall_preempt_check() )
|
||||
+ {
|
||||
+ rc = hypercall_create_continuation(
|
||||
+ __HYPERVISOR_set_trap_table, "h", traps);
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ if ( copy_from_guest(&cur, traps, 1) )
|
||||
+ {
|
||||
+ rc = -EFAULT;
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ if ( cur.address == 0 )
|
||||
+ break;
|
||||
+
|
||||
+ fixup_guest_code_selector(current->domain, cur.cs);
|
||||
+
|
||||
+ XLAT_trap_info(dst + cur.vector, &cur);
|
||||
+
|
||||
+ guest_handle_add_offset(traps, 1);
|
||||
+ }
|
||||
+
|
||||
+ return rc;
|
||||
+}
|
||||
+
|
||||
#endif /* CONFIG_COMPAT */
|
||||
|
||||
static void hypercall_page_initialise_ring1_kernel(void *hypercall_page)
|
199
32on64-shadow.patch
Normal file
199
32on64-shadow.patch
Normal file
@ -0,0 +1,199 @@
|
||||
Preliminary, likely incomplete and/or wrong, adjustments to shadow code.
|
||||
|
||||
unstable c/s 13296: [HVM] Fix shadow memory tracking
|
||||
Fixes a missing free from cset 13275, and a missing prealloc.
|
||||
Signed-off-by: Tim Deegan <Tim.Deegan@xensource.com>
|
||||
|
||||
Index: 2007-01-31/xen/arch/x86/mm/shadow/common.c
|
||||
===================================================================
|
||||
--- 2007-01-31.orig/xen/arch/x86/mm/shadow/common.c 2007-01-31 09:31:33.000000000 +0100
|
||||
+++ 2007-01-31/xen/arch/x86/mm/shadow/common.c 2007-01-31 09:36:44.000000000 +0100
|
||||
@@ -2427,7 +2427,7 @@ void sh_update_paging_modes(struct vcpu
|
||||
///
|
||||
#if CONFIG_PAGING_LEVELS == 4
|
||||
if ( pv_32bit_guest(v) )
|
||||
- v->arch.shadow.mode = &SHADOW_INTERNAL_NAME(sh_paging_mode,4,3);
|
||||
+ v->arch.shadow.mode = &SHADOW_INTERNAL_NAME(sh_paging_mode,3,3);
|
||||
else
|
||||
v->arch.shadow.mode = &SHADOW_INTERNAL_NAME(sh_paging_mode,4,4);
|
||||
#elif CONFIG_PAGING_LEVELS == 3
|
||||
Index: 2007-01-31/xen/arch/x86/mm/shadow/multi.c
|
||||
===================================================================
|
||||
--- 2007-01-31.orig/xen/arch/x86/mm/shadow/multi.c 2007-01-31 09:31:33.000000000 +0100
|
||||
+++ 2007-01-31/xen/arch/x86/mm/shadow/multi.c 2007-01-31 09:36:54.000000000 +0100
|
||||
@@ -1423,7 +1423,7 @@ void sh_install_xen_entries_in_l4(struct
|
||||
}
|
||||
#endif
|
||||
|
||||
-#if CONFIG_PAGING_LEVELS == 3 && GUEST_PAGING_LEVELS == 3
|
||||
+#if (CONFIG_PAGING_LEVELS == 3 || defined(CONFIG_COMPAT)) && GUEST_PAGING_LEVELS == 3
|
||||
// For 3-on-3 PV guests, we need to make sure the xen mappings are in
|
||||
// place, which means that we need to populate the l2h entry in the l3
|
||||
// table.
|
||||
@@ -1433,12 +1433,20 @@ void sh_install_xen_entries_in_l2h(struc
|
||||
{
|
||||
struct domain *d = v->domain;
|
||||
shadow_l2e_t *sl2e;
|
||||
+#if CONFIG_PAGING_LEVELS == 3
|
||||
int i;
|
||||
+#else
|
||||
+
|
||||
+ if ( !pv_32bit_guest(v) )
|
||||
+ return;
|
||||
+#endif
|
||||
|
||||
sl2e = sh_map_domain_page(sl2hmfn);
|
||||
ASSERT(sl2e != NULL);
|
||||
ASSERT(sizeof (l2_pgentry_t) == sizeof (shadow_l2e_t));
|
||||
|
||||
+#if CONFIG_PAGING_LEVELS == 3
|
||||
+
|
||||
/* Copy the common Xen mappings from the idle domain */
|
||||
memcpy(&sl2e[L2_PAGETABLE_FIRST_XEN_SLOT & (L2_PAGETABLE_ENTRIES-1)],
|
||||
&idle_pg_table_l2[L2_PAGETABLE_FIRST_XEN_SLOT],
|
||||
@@ -1479,6 +1487,15 @@ void sh_install_xen_entries_in_l2h(struc
|
||||
}
|
||||
sh_unmap_domain_page(p2m);
|
||||
}
|
||||
+
|
||||
+#else
|
||||
+
|
||||
+ /* Copy the common Xen mappings from the idle domain */
|
||||
+ memcpy(&sl2e[COMPAT_L2_PAGETABLE_FIRST_XEN_SLOT(d)],
|
||||
+ &compat_idle_pg_table_l2[l2_table_offset(HIRO_COMPAT_MPT_VIRT_START)],
|
||||
+ COMPAT_L2_PAGETABLE_XEN_SLOTS(d) * sizeof(*sl2e));
|
||||
+
|
||||
+#endif
|
||||
|
||||
sh_unmap_domain_page(sl2e);
|
||||
}
|
||||
@@ -1639,12 +1656,15 @@ make_fl1_shadow(struct vcpu *v, gfn_t gf
|
||||
mfn_t
|
||||
sh_make_monitor_table(struct vcpu *v)
|
||||
{
|
||||
+ struct domain *d = v->domain;
|
||||
|
||||
ASSERT(pagetable_get_pfn(v->arch.monitor_table) == 0);
|
||||
|
||||
+ /* Guarantee we can get the memory we need */
|
||||
+ shadow_prealloc(d, SHADOW_MAX_ORDER);
|
||||
+
|
||||
#if CONFIG_PAGING_LEVELS == 4
|
||||
{
|
||||
- struct domain *d = v->domain;
|
||||
mfn_t m4mfn;
|
||||
m4mfn = shadow_alloc(d, SH_type_monitor_table, 0);
|
||||
sh_install_xen_entries_in_l4(v, m4mfn, m4mfn);
|
||||
@@ -1661,6 +1681,19 @@ sh_make_monitor_table(struct vcpu *v)
|
||||
l4e = sh_map_domain_page(m4mfn);
|
||||
l4e[0] = l4e_from_pfn(mfn_x(m3mfn), __PAGE_HYPERVISOR);
|
||||
sh_unmap_domain_page(l4e);
|
||||
+ if ( pv_32bit_guest(v) )
|
||||
+ {
|
||||
+ // Install a monitor l2 table in slot 3 of the l3 table.
|
||||
+ // This is used for all Xen entries.
|
||||
+ mfn_t m2mfn;
|
||||
+ l3_pgentry_t *l3e;
|
||||
+ m2mfn = shadow_alloc(d, SH_type_monitor_table, 0);
|
||||
+ mfn_to_page(m2mfn)->shadow_flags = 2;
|
||||
+ l3e = sh_map_domain_page(m3mfn);
|
||||
+ l3e[3] = l3e_from_pfn(mfn_x(m2mfn), _PAGE_PRESENT);
|
||||
+ sh_install_xen_entries_in_l2h(v, m2mfn);
|
||||
+ sh_unmap_domain_page(l3e);
|
||||
+ }
|
||||
}
|
||||
#endif /* SHADOW_PAGING_LEVELS < 4 */
|
||||
return m4mfn;
|
||||
@@ -1669,7 +1702,6 @@ sh_make_monitor_table(struct vcpu *v)
|
||||
#elif CONFIG_PAGING_LEVELS == 3
|
||||
|
||||
{
|
||||
- struct domain *d = v->domain;
|
||||
mfn_t m3mfn, m2mfn;
|
||||
l3_pgentry_t *l3e;
|
||||
l2_pgentry_t *l2e;
|
||||
@@ -1703,7 +1735,6 @@ sh_make_monitor_table(struct vcpu *v)
|
||||
#elif CONFIG_PAGING_LEVELS == 2
|
||||
|
||||
{
|
||||
- struct domain *d = v->domain;
|
||||
mfn_t m2mfn;
|
||||
m2mfn = shadow_alloc(d, SH_type_monitor_table, 0);
|
||||
sh_install_xen_entries_in_l2(v, m2mfn, m2mfn);
|
||||
@@ -2066,9 +2097,19 @@ void sh_destroy_monitor_table(struct vcp
|
||||
#if (CONFIG_PAGING_LEVELS == 4) && (SHADOW_PAGING_LEVELS != 4)
|
||||
/* Need to destroy the l3 monitor page in slot 0 too */
|
||||
{
|
||||
+ mfn_t m3mfn;
|
||||
l4_pgentry_t *l4e = sh_map_domain_page(mmfn);
|
||||
ASSERT(l4e_get_flags(l4e[0]) & _PAGE_PRESENT);
|
||||
- shadow_free(d, _mfn(l4e_get_pfn(l4e[0])));
|
||||
+ m3mfn = _mfn(l4e_get_pfn(l4e[0]));
|
||||
+ if ( pv_32bit_guest(v) )
|
||||
+ {
|
||||
+ /* Need to destroy the l2 monitor page in slot 3 too */
|
||||
+ l3_pgentry_t *l3e = sh_map_domain_page(m3mfn);
|
||||
+ ASSERT(l3e_get_flags(l3e[3]) & _PAGE_PRESENT);
|
||||
+ shadow_free(d, _mfn(l3e_get_pfn(l3e[3])));
|
||||
+ sh_unmap_domain_page(l3e);
|
||||
+ }
|
||||
+ shadow_free(d, m3mfn);
|
||||
sh_unmap_domain_page(l4e);
|
||||
}
|
||||
#elif CONFIG_PAGING_LEVELS == 3
|
||||
@@ -3048,12 +3089,15 @@ sh_update_linear_entries(struct vcpu *v)
|
||||
|
||||
#elif (CONFIG_PAGING_LEVELS == 4) && (SHADOW_PAGING_LEVELS == 3)
|
||||
|
||||
- /* This case only exists in HVM. To give ourselves a linear map of the
|
||||
- * shadows, we need to extend a PAE shadow to 4 levels. We do this by
|
||||
- * having a monitor l3 in slot 0 of the monitor l4 table, and
|
||||
- * copying the PAE l3 entries into it. Then, by having the monitor l4e
|
||||
- * for shadow pagetables also point to the monitor l4, we can use it
|
||||
- * to access the shadows. */
|
||||
+ /* PV: XXX
|
||||
+ *
|
||||
+ * HVM: To give ourselves a linear map of the shadows, we need to
|
||||
+ * extend a PAE shadow to 4 levels. We do this by having a monitor
|
||||
+ * l3 in slot 0 of the monitor l4 table, and copying the PAE l3
|
||||
+ * entries into it. Then, by having the monitor l4e for shadow
|
||||
+ * pagetables also point to the monitor l4, we can use it to access
|
||||
+ * the shadows.
|
||||
+ */
|
||||
|
||||
if ( shadow_mode_external(d) )
|
||||
{
|
||||
@@ -3096,6 +3140,8 @@ sh_update_linear_entries(struct vcpu *v)
|
||||
if ( v != current )
|
||||
sh_unmap_domain_page(ml3e);
|
||||
}
|
||||
+ else
|
||||
+ domain_crash(d); /* XXX */
|
||||
|
||||
#elif CONFIG_PAGING_LEVELS == 3
|
||||
|
||||
Index: 2007-01-31/xen/include/asm-x86/shadow.h
|
||||
===================================================================
|
||||
--- 2007-01-31.orig/xen/include/asm-x86/shadow.h 2007-01-31 09:31:33.000000000 +0100
|
||||
+++ 2007-01-31/xen/include/asm-x86/shadow.h 2007-01-31 09:36:44.000000000 +0100
|
||||
@@ -70,9 +70,9 @@
|
||||
|
||||
// How do we tell that we have a 32-bit PV guest in a 64-bit Xen?
|
||||
#ifdef __x86_64__
|
||||
-#define pv_32bit_guest(_v) 0 // not yet supported
|
||||
+#define pv_32bit_guest(_v) (!is_hvm_vcpu(_v) && IS_COMPAT((_v)->domain))
|
||||
#else
|
||||
-#define pv_32bit_guest(_v) !is_hvm_vcpu(v)
|
||||
+#define pv_32bit_guest(_v) (!is_hvm_vcpu(_v))
|
||||
#endif
|
||||
|
||||
/* The shadow lock.
|
||||
@@ -418,7 +418,7 @@ static inline void update_cr3(struct vcp
|
||||
}
|
||||
|
||||
#if CONFIG_PAGING_LEVELS == 4
|
||||
- if ( !(v->arch.flags & TF_kernel_mode) )
|
||||
+ if ( !(v->arch.flags & TF_kernel_mode) && !IS_COMPAT(v->domain) )
|
||||
cr3_mfn = pagetable_get_pfn(v->arch.guest_table_user);
|
||||
else
|
||||
#endif
|
900
32on64-shared.patch
Normal file
900
32on64-shared.patch
Normal file
@ -0,0 +1,900 @@
|
||||
Handle shared info (having different layout for native and compatibility
|
||||
mode guests) accesses.
|
||||
|
||||
Index: 2007-01-08/xen/arch/x86/crash.c
|
||||
===================================================================
|
||||
--- 2007-01-08.orig/xen/arch/x86/crash.c 2007-01-08 15:34:16.000000000 +0100
|
||||
+++ 2007-01-08/xen/arch/x86/crash.c 2007-01-08 15:19:11.000000000 +0100
|
||||
@@ -25,6 +25,7 @@
|
||||
#include <xen/kexec.h>
|
||||
#include <xen/sched.h>
|
||||
#include <public/xen.h>
|
||||
+#include <asm/shared.h>
|
||||
#include <asm/hvm/hvm.h>
|
||||
|
||||
static atomic_t waiting_for_crash_ipi;
|
||||
@@ -103,7 +104,7 @@ void machine_crash_shutdown(void)
|
||||
|
||||
info = kexec_crash_save_info();
|
||||
info->dom0_pfn_to_mfn_frame_list_list =
|
||||
- dom0->shared_info->arch.pfn_to_mfn_frame_list_list;
|
||||
+ arch_get_pfn_to_mfn_frame_list_list(dom0);
|
||||
}
|
||||
|
||||
/*
|
||||
Index: 2007-01-08/xen/arch/x86/domain.c
|
||||
===================================================================
|
||||
--- 2007-01-08.orig/xen/arch/x86/domain.c 2007-01-08 14:45:40.000000000 +0100
|
||||
+++ 2007-01-08/xen/arch/x86/domain.c 2007-01-08 15:19:11.000000000 +0100
|
||||
@@ -547,10 +547,10 @@ static void load_segments(struct vcpu *n
|
||||
|
||||
/* CS longword also contains full evtchn_upcall_mask. */
|
||||
cs_and_mask = (unsigned short)regs->cs |
|
||||
- ((unsigned int)n->vcpu_info->evtchn_upcall_mask << 16);
|
||||
+ ((unsigned int)vcpu_info(n, evtchn_upcall_mask) << 16);
|
||||
/* Fold upcall mask into RFLAGS.IF. */
|
||||
eflags = regs->_eflags & ~X86_EFLAGS_IF;
|
||||
- eflags |= !n->vcpu_info->evtchn_upcall_mask << 9;
|
||||
+ eflags |= !vcpu_info(n, evtchn_upcall_mask) << 9;
|
||||
|
||||
if ( !ring_1(regs) )
|
||||
{
|
||||
@@ -575,7 +575,7 @@ static void load_segments(struct vcpu *n
|
||||
|
||||
if ( test_bit(_VGCF_failsafe_disables_events,
|
||||
&n->arch.guest_context.flags) )
|
||||
- n->vcpu_info->evtchn_upcall_mask = 1;
|
||||
+ vcpu_info(n, evtchn_upcall_mask) = 1;
|
||||
|
||||
regs->entry_vector = TRAP_syscall;
|
||||
regs->_eflags &= 0xFFFCBEFFUL;
|
||||
@@ -593,11 +593,11 @@ static void load_segments(struct vcpu *n
|
||||
|
||||
/* CS longword also contains full evtchn_upcall_mask. */
|
||||
cs_and_mask = (unsigned long)regs->cs |
|
||||
- ((unsigned long)n->vcpu_info->evtchn_upcall_mask << 32);
|
||||
+ ((unsigned long)vcpu_info(n, evtchn_upcall_mask) << 32);
|
||||
|
||||
/* Fold upcall mask into RFLAGS.IF. */
|
||||
rflags = regs->rflags & ~X86_EFLAGS_IF;
|
||||
- rflags |= !n->vcpu_info->evtchn_upcall_mask << 9;
|
||||
+ rflags |= !vcpu_info(n, evtchn_upcall_mask) << 9;
|
||||
|
||||
if ( put_user(regs->ss, rsp- 1) |
|
||||
put_user(regs->rsp, rsp- 2) |
|
||||
@@ -618,7 +618,7 @@ static void load_segments(struct vcpu *n
|
||||
|
||||
if ( test_bit(_VGCF_failsafe_disables_events,
|
||||
&n->arch.guest_context.flags) )
|
||||
- n->vcpu_info->evtchn_upcall_mask = 1;
|
||||
+ vcpu_info(n, evtchn_upcall_mask) = 1;
|
||||
|
||||
regs->entry_vector = TRAP_syscall;
|
||||
regs->rflags &= ~(X86_EFLAGS_AC|X86_EFLAGS_VM|X86_EFLAGS_RF|
|
||||
Index: 2007-01-08/xen/arch/x86/domain_build.c
|
||||
===================================================================
|
||||
--- 2007-01-08.orig/xen/arch/x86/domain_build.c 2007-01-08 15:35:20.000000000 +0100
|
||||
+++ 2007-01-08/xen/arch/x86/domain_build.c 2007-01-08 15:35:36.000000000 +0100
|
||||
@@ -328,6 +328,7 @@ int construct_dom0(struct domain *d,
|
||||
l1_pgentry_t gdt_l1e;
|
||||
|
||||
set_bit(_DOMF_compat, &d->domain_flags);
|
||||
+ v->vcpu_info = (void *)&d->shared_info->compat.vcpu_info[0];
|
||||
|
||||
if ( nr_pages != (unsigned int)nr_pages )
|
||||
nr_pages = UINT_MAX;
|
||||
@@ -730,7 +731,7 @@ int construct_dom0(struct domain *d,
|
||||
|
||||
/* Mask all upcalls... */
|
||||
for ( i = 0; i < MAX_VIRT_CPUS; i++ )
|
||||
- d->shared_info->vcpu_info[i].evtchn_upcall_mask = 1;
|
||||
+ shared_info(d, vcpu_info[i].evtchn_upcall_mask) = 1;
|
||||
|
||||
if ( opt_dom0_max_vcpus == 0 )
|
||||
opt_dom0_max_vcpus = num_online_cpus();
|
||||
@@ -738,6 +739,8 @@ int construct_dom0(struct domain *d,
|
||||
opt_dom0_max_vcpus = num_online_cpus();
|
||||
if ( opt_dom0_max_vcpus > MAX_VIRT_CPUS )
|
||||
opt_dom0_max_vcpus = MAX_VIRT_CPUS;
|
||||
+ if ( opt_dom0_max_vcpus > BITS_PER_GUEST_LONG(d) )
|
||||
+ opt_dom0_max_vcpus = BITS_PER_GUEST_LONG(d);
|
||||
printk("Dom0 has maximum %u VCPUs\n", opt_dom0_max_vcpus);
|
||||
|
||||
for ( i = 1; i < opt_dom0_max_vcpus; i++ )
|
||||
Index: 2007-01-08/xen/arch/x86/irq.c
|
||||
===================================================================
|
||||
--- 2007-01-08.orig/xen/arch/x86/irq.c 2007-01-08 15:34:16.000000000 +0100
|
||||
+++ 2007-01-08/xen/arch/x86/irq.c 2007-01-08 15:19:11.000000000 +0100
|
||||
@@ -13,6 +13,7 @@
|
||||
#include <xen/perfc.h>
|
||||
#include <xen/sched.h>
|
||||
#include <xen/keyhandler.h>
|
||||
+#include <xen/compat.h>
|
||||
#include <asm/current.h>
|
||||
#include <asm/smpboot.h>
|
||||
|
||||
@@ -332,7 +333,7 @@ int pirq_guest_unmask(struct domain *d)
|
||||
irq < NR_IRQS;
|
||||
irq = find_next_bit(d->pirq_mask, NR_IRQS, irq+1) )
|
||||
{
|
||||
- if ( !test_bit(d->pirq_to_evtchn[irq], s->evtchn_mask) )
|
||||
+ if ( !test_bit(d->pirq_to_evtchn[irq], __shared_info_addr(d, s, evtchn_mask)) )
|
||||
__pirq_guest_eoi(d, irq);
|
||||
}
|
||||
|
||||
@@ -624,14 +625,13 @@ static void dump_irqs(unsigned char key)
|
||||
printk("%u(%c%c%c%c)",
|
||||
d->domain_id,
|
||||
(test_bit(d->pirq_to_evtchn[irq],
|
||||
- d->shared_info->evtchn_pending) ?
|
||||
+ shared_info_addr(d, evtchn_pending)) ?
|
||||
'P' : '-'),
|
||||
- (test_bit(d->pirq_to_evtchn[irq]/BITS_PER_LONG,
|
||||
- &d->shared_info->vcpu_info[0].
|
||||
- evtchn_pending_sel) ?
|
||||
+ (test_bit(d->pirq_to_evtchn[irq]/BITS_PER_GUEST_LONG(d),
|
||||
+ vcpu_info_addr(d->vcpu[0], evtchn_pending_sel)) ?
|
||||
'S' : '-'),
|
||||
(test_bit(d->pirq_to_evtchn[irq],
|
||||
- d->shared_info->evtchn_mask) ?
|
||||
+ shared_info_addr(d, evtchn_mask)) ?
|
||||
'M' : '-'),
|
||||
(test_bit(irq, d->pirq_mask) ?
|
||||
'M' : '-'));
|
||||
Index: 2007-01-08/xen/arch/x86/mm/shadow/common.c
|
||||
===================================================================
|
||||
--- 2007-01-08.orig/xen/arch/x86/mm/shadow/common.c 2007-01-08 15:34:16.000000000 +0100
|
||||
+++ 2007-01-08/xen/arch/x86/mm/shadow/common.c 2007-01-08 15:19:11.000000000 +0100
|
||||
@@ -36,6 +36,7 @@
|
||||
#include <asm/current.h>
|
||||
#include <asm/flushtlb.h>
|
||||
#include <asm/shadow.h>
|
||||
+#include <asm/shared.h>
|
||||
#include "private.h"
|
||||
|
||||
#if SHADOW_AUDIT
|
||||
@@ -2890,7 +2891,7 @@ sh_alloc_log_dirty_bitmap(struct domain
|
||||
{
|
||||
ASSERT(d->arch.shadow.dirty_bitmap == NULL);
|
||||
d->arch.shadow.dirty_bitmap_size =
|
||||
- (d->shared_info->arch.max_pfn + (BITS_PER_LONG - 1)) &
|
||||
+ (arch_get_max_pfn(d) + (BITS_PER_LONG - 1)) &
|
||||
~(BITS_PER_LONG - 1);
|
||||
d->arch.shadow.dirty_bitmap =
|
||||
xmalloc_array(unsigned long,
|
||||
Index: 2007-01-08/xen/arch/x86/setup.c
|
||||
===================================================================
|
||||
--- 2007-01-08.orig/xen/arch/x86/setup.c 2007-01-08 15:18:32.000000000 +0100
|
||||
+++ 2007-01-08/xen/arch/x86/setup.c 2007-01-08 15:19:11.000000000 +0100
|
||||
@@ -548,14 +548,13 @@ void __init __start_xen(multiboot_info_t
|
||||
|
||||
BUILD_BUG_ON(sizeof(start_info_t) > PAGE_SIZE);
|
||||
BUILD_BUG_ON(sizeof(shared_info_t) > PAGE_SIZE);
|
||||
- BUILD_BUG_ON(sizeof(vcpu_info_t) != 64);
|
||||
+ BUILD_BUG_ON(sizeof(struct vcpu_info) != 64);
|
||||
|
||||
#ifdef CONFIG_COMPAT
|
||||
BUILD_BUG_ON(sizeof(((struct compat_platform_op *)0)->u) !=
|
||||
sizeof(((struct compat_platform_op *)0)->u.pad));
|
||||
BUILD_BUG_ON(sizeof(start_info_compat_t) > PAGE_SIZE);
|
||||
- BUILD_BUG_ON(sizeof(shared_info_compat_t) > PAGE_SIZE);
|
||||
- BUILD_BUG_ON(sizeof(vcpu_info_compat_t) != 64);
|
||||
+ BUILD_BUG_ON(sizeof(struct compat_vcpu_info) != 64);
|
||||
#endif
|
||||
|
||||
/* Check definitions in public headers match internal defs. */
|
||||
Index: 2007-01-08/xen/arch/x86/time.c
|
||||
===================================================================
|
||||
--- 2007-01-08.orig/xen/arch/x86/time.c 2007-01-08 15:34:16.000000000 +0100
|
||||
+++ 2007-01-08/xen/arch/x86/time.c 2007-01-08 15:19:11.000000000 +0100
|
||||
@@ -676,7 +676,7 @@ static inline void __update_vcpu_system_
|
||||
struct vcpu_time_info *u;
|
||||
|
||||
t = &this_cpu(cpu_time);
|
||||
- u = &v->vcpu_info->time;
|
||||
+ u = &vcpu_info(v, time);
|
||||
|
||||
version_update_begin(&u->version);
|
||||
|
||||
@@ -690,7 +690,7 @@ static inline void __update_vcpu_system_
|
||||
|
||||
void update_vcpu_system_time(struct vcpu *v)
|
||||
{
|
||||
- if ( v->vcpu_info->time.tsc_timestamp !=
|
||||
+ if ( vcpu_info(v, time.tsc_timestamp) !=
|
||||
this_cpu(cpu_time).local_tsc_stamp )
|
||||
__update_vcpu_system_time(v);
|
||||
}
|
||||
@@ -698,10 +698,10 @@ void update_vcpu_system_time(struct vcpu
|
||||
void update_domain_wallclock_time(struct domain *d)
|
||||
{
|
||||
spin_lock(&wc_lock);
|
||||
- version_update_begin(&d->shared_info->wc_version);
|
||||
- d->shared_info->wc_sec = wc_sec + d->time_offset_seconds;
|
||||
- d->shared_info->wc_nsec = wc_nsec;
|
||||
- version_update_end(&d->shared_info->wc_version);
|
||||
+ version_update_begin(&shared_info(d, wc_version));
|
||||
+ shared_info(d, wc_sec) = wc_sec + d->time_offset_seconds;
|
||||
+ shared_info(d, wc_nsec) = wc_nsec;
|
||||
+ version_update_end(&shared_info(d, wc_version));
|
||||
spin_unlock(&wc_lock);
|
||||
}
|
||||
|
||||
Index: 2007-01-08/xen/arch/x86/traps.c
|
||||
===================================================================
|
||||
--- 2007-01-08.orig/xen/arch/x86/traps.c 2006-12-18 09:43:08.000000000 +0100
|
||||
+++ 2007-01-08/xen/arch/x86/traps.c 2007-01-08 15:19:11.000000000 +0100
|
||||
@@ -58,6 +58,7 @@
|
||||
#include <asm/i387.h>
|
||||
#include <asm/debugger.h>
|
||||
#include <asm/msr.h>
|
||||
+#include <asm/shared.h>
|
||||
#include <asm/x86_emulate.h>
|
||||
#include <asm/hvm/vpt.h>
|
||||
|
||||
@@ -681,7 +682,7 @@ void propagate_page_fault(unsigned long
|
||||
struct trap_bounce *tb = &v->arch.trap_bounce;
|
||||
|
||||
v->arch.guest_context.ctrlreg[2] = addr;
|
||||
- v->vcpu_info->arch.cr2 = addr;
|
||||
+ arch_set_cr2(v, addr);
|
||||
|
||||
/* Re-set error_code.user flag appropriately for the guest. */
|
||||
error_code &= ~PFEC_user_mode;
|
||||
@@ -1406,7 +1407,7 @@ static int emulate_privileged_op(struct
|
||||
|
||||
case 2: /* Write CR2 */
|
||||
v->arch.guest_context.ctrlreg[2] = *reg;
|
||||
- v->vcpu_info->arch.cr2 = *reg;
|
||||
+ arch_set_cr2(v, *reg);
|
||||
break;
|
||||
|
||||
case 3: /* Write CR3 */
|
||||
@@ -1617,7 +1618,7 @@ static void nmi_dom0_report(unsigned int
|
||||
if ( ((d = dom0) == NULL) || ((v = d->vcpu[0]) == NULL) )
|
||||
return;
|
||||
|
||||
- set_bit(reason_idx, &d->shared_info->arch.nmi_reason);
|
||||
+ set_bit(reason_idx, nmi_reason(d));
|
||||
|
||||
if ( test_and_set_bit(_VCPUF_nmi_pending, &v->vcpu_flags) )
|
||||
raise_softirq(NMI_SOFTIRQ); /* not safe to wake up a vcpu here */
|
||||
Index: 2007-01-08/xen/arch/x86/x86_64/asm-offsets.c
|
||||
===================================================================
|
||||
--- 2007-01-08.orig/xen/arch/x86/x86_64/asm-offsets.c 2006-12-18 09:43:08.000000000 +0100
|
||||
+++ 2007-01-08/xen/arch/x86/x86_64/asm-offsets.c 2007-01-08 15:19:11.000000000 +0100
|
||||
@@ -7,6 +7,9 @@
|
||||
#include <xen/config.h>
|
||||
#include <xen/perfc.h>
|
||||
#include <xen/sched.h>
|
||||
+#ifdef CONFIG_COMPAT
|
||||
+#include <compat/xen.h>
|
||||
+#endif
|
||||
#include <asm/fixmap.h>
|
||||
#include <asm/hardirq.h>
|
||||
|
||||
@@ -96,9 +99,15 @@ void __dummy__(void)
|
||||
OFFSET(VMCB_tsc_offset, struct vmcb_struct, tsc_offset);
|
||||
BLANK();
|
||||
|
||||
- OFFSET(VCPUINFO_upcall_pending, vcpu_info_t, evtchn_upcall_pending);
|
||||
- OFFSET(VCPUINFO_upcall_mask, vcpu_info_t, evtchn_upcall_mask);
|
||||
+ OFFSET(VCPUINFO_upcall_pending, struct vcpu_info, evtchn_upcall_pending);
|
||||
+ OFFSET(VCPUINFO_upcall_mask, struct vcpu_info, evtchn_upcall_mask);
|
||||
+ BLANK();
|
||||
+
|
||||
+#ifdef CONFIG_COMPAT
|
||||
+ OFFSET(COMPAT_VCPUINFO_upcall_pending, struct compat_vcpu_info, evtchn_upcall_pending);
|
||||
+ OFFSET(COMPAT_VCPUINFO_upcall_mask, struct compat_vcpu_info, evtchn_upcall_mask);
|
||||
BLANK();
|
||||
+#endif
|
||||
|
||||
OFFSET(CPUINFO_current_vcpu, struct cpu_info, current_vcpu);
|
||||
DEFINE(CPUINFO_sizeof, sizeof(struct cpu_info));
|
||||
Index: 2007-01-08/xen/arch/x86/x86_64/compat/entry.S
|
||||
===================================================================
|
||||
--- 2007-01-08.orig/xen/arch/x86/x86_64/compat/entry.S 2007-01-08 15:17:29.000000000 +0100
|
||||
+++ 2007-01-08/xen/arch/x86/x86_64/compat/entry.S 2007-01-08 15:19:11.000000000 +0100
|
||||
@@ -69,9 +69,9 @@ compat_test_all_events:
|
||||
jc compat_process_nmi
|
||||
compat_test_guest_events:
|
||||
movq VCPU_vcpu_info(%rbx),%rax
|
||||
- testb $0xFF,VCPUINFO_upcall_mask(%rax)
|
||||
+ testb $0xFF,COMPAT_VCPUINFO_upcall_mask(%rax)
|
||||
jnz compat_restore_all_guest
|
||||
- testb $0xFF,VCPUINFO_upcall_pending(%rax)
|
||||
+ testb $0xFF,COMPAT_VCPUINFO_upcall_pending(%rax)
|
||||
jz compat_restore_all_guest
|
||||
/*compat_process_guest_events:*/
|
||||
sti
|
||||
@@ -189,10 +189,10 @@ CFLT4: mov UREGS_ss+8(%rsp),%fs
|
||||
movb TRAPBOUNCE_flags(%rdx),%cl
|
||||
subl $3*4,%esi
|
||||
movq VCPU_vcpu_info(%rbx),%rax
|
||||
- pushq VCPUINFO_upcall_mask(%rax)
|
||||
+ pushq COMPAT_VCPUINFO_upcall_mask(%rax)
|
||||
testb $TBF_INTERRUPT,%cl
|
||||
setnz %ch # TBF_INTERRUPT -> set upcall mask
|
||||
- orb %ch,VCPUINFO_upcall_mask(%rax)
|
||||
+ orb %ch,COMPAT_VCPUINFO_upcall_mask(%rax)
|
||||
popq %rax
|
||||
shll $16,%eax # Bits 16-23: saved_upcall_mask
|
||||
movw UREGS_cs+8(%rsp),%ax # Bits 0-15: CS
|
||||
Index: 2007-01-08/xen/arch/x86/x86_64/compat/traps.c
|
||||
===================================================================
|
||||
--- 2007-01-08.orig/xen/arch/x86/x86_64/compat/traps.c 2007-01-08 15:17:29.000000000 +0100
|
||||
+++ 2007-01-08/xen/arch/x86/x86_64/compat/traps.c 2007-01-08 15:19:11.000000000 +0100
|
||||
@@ -118,7 +118,7 @@ unsigned int compat_iret(void)
|
||||
clear_bit(_VCPUF_nmi_masked, ¤t->vcpu_flags);
|
||||
|
||||
/* Restore upcall mask from supplied EFLAGS.IF. */
|
||||
- current->vcpu_info->evtchn_upcall_mask = !(eflags & X86_EFLAGS_IF);
|
||||
+ vcpu_info(current, evtchn_upcall_mask) = !(eflags & X86_EFLAGS_IF);
|
||||
|
||||
/*
|
||||
* The hypercall exit path will overwrite EAX with this return
|
||||
Index: 2007-01-08/xen/arch/x86/x86_64/traps.c
|
||||
===================================================================
|
||||
--- 2007-01-08.orig/xen/arch/x86/x86_64/traps.c 2006-12-18 09:43:08.000000000 +0100
|
||||
+++ 2007-01-08/xen/arch/x86/x86_64/traps.c 2007-01-08 15:19:11.000000000 +0100
|
||||
@@ -17,6 +17,7 @@
|
||||
#include <asm/msr.h>
|
||||
#include <asm/page.h>
|
||||
#include <asm/shadow.h>
|
||||
+#include <asm/shared.h>
|
||||
#include <asm/hvm/hvm.h>
|
||||
#include <asm/hvm/support.h>
|
||||
|
||||
@@ -52,7 +53,7 @@ void show_registers(struct cpu_user_regs
|
||||
if ( guest_mode(regs) )
|
||||
{
|
||||
context = "guest";
|
||||
- fault_crs[2] = current->vcpu_info->arch.cr2;
|
||||
+ fault_crs[2] = arch_get_cr2(current);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -234,7 +235,7 @@ unsigned long do_iret(void)
|
||||
clear_bit(_VCPUF_nmi_masked, ¤t->vcpu_flags);
|
||||
|
||||
/* Restore upcall mask from supplied EFLAGS.IF. */
|
||||
- current->vcpu_info->evtchn_upcall_mask = !(iret_saved.rflags & EF_IE);
|
||||
+ vcpu_info(current, evtchn_upcall_mask) = !(iret_saved.rflags & EF_IE);
|
||||
|
||||
/* Saved %rax gets written back to regs->rax in entry.S. */
|
||||
return iret_saved.rax;
|
||||
Index: 2007-01-08/xen/common/compat/xlat.c
|
||||
===================================================================
|
||||
--- 2007-01-08.orig/xen/common/compat/xlat.c 2007-01-08 15:18:32.000000000 +0100
|
||||
+++ 2007-01-08/xen/common/compat/xlat.c 2007-01-08 15:19:11.000000000 +0100
|
||||
@@ -21,6 +21,10 @@ void xlat_start_info(struct start_info *
|
||||
CHECK_dom0_vga_console_info;
|
||||
#undef dom0_vga_console_info
|
||||
|
||||
+#define xen_vcpu_time_info vcpu_time_info
|
||||
+CHECK_vcpu_time_info;
|
||||
+#undef xen_vcpu_time_info
|
||||
+
|
||||
/*
|
||||
* Local variables:
|
||||
* mode: C
|
||||
Index: 2007-01-08/xen/common/domain.c
|
||||
===================================================================
|
||||
--- 2007-01-08.orig/xen/common/domain.c 2007-01-08 15:34:16.000000000 +0100
|
||||
+++ 2007-01-08/xen/common/domain.c 2007-01-08 15:19:11.000000000 +0100
|
||||
@@ -90,7 +90,7 @@ struct vcpu *alloc_vcpu(
|
||||
|
||||
v->domain = d;
|
||||
v->vcpu_id = vcpu_id;
|
||||
- v->vcpu_info = &d->shared_info->vcpu_info[vcpu_id];
|
||||
+ v->vcpu_info = shared_info_addr(d, vcpu_info[vcpu_id]);
|
||||
spin_lock_init(&v->pause_lock);
|
||||
|
||||
v->runstate.state = is_idle_vcpu(v) ? RUNSTATE_running : RUNSTATE_offline;
|
||||
Index: 2007-01-08/xen/common/event_channel.c
|
||||
===================================================================
|
||||
--- 2007-01-08.orig/xen/common/event_channel.c 2007-01-08 15:34:16.000000000 +0100
|
||||
+++ 2007-01-08/xen/common/event_channel.c 2007-01-08 15:19:11.000000000 +0100
|
||||
@@ -23,6 +23,7 @@
|
||||
#include <xen/event.h>
|
||||
#include <xen/irq.h>
|
||||
#include <xen/iocap.h>
|
||||
+#include <xen/compat.h>
|
||||
#include <xen/guest_access.h>
|
||||
#include <asm/current.h>
|
||||
|
||||
@@ -33,7 +34,7 @@
|
||||
#define bucket_from_port(d,p) \
|
||||
((d)->evtchn[(p)/EVTCHNS_PER_BUCKET])
|
||||
#define port_is_valid(d,p) \
|
||||
- (((p) >= 0) && ((p) < MAX_EVTCHNS) && \
|
||||
+ (((p) >= 0) && ((p) < MAX_EVTCHNS(d)) && \
|
||||
(bucket_from_port(d,p) != NULL))
|
||||
#define evtchn_from_port(d,p) \
|
||||
(&(bucket_from_port(d,p))[(p)&(EVTCHNS_PER_BUCKET-1)])
|
||||
@@ -82,7 +83,7 @@ static int get_free_port(struct domain *
|
||||
if ( evtchn_from_port(d, port)->state == ECS_FREE )
|
||||
return port;
|
||||
|
||||
- if ( port == MAX_EVTCHNS )
|
||||
+ if ( port == MAX_EVTCHNS(d) )
|
||||
return -ENOSPC;
|
||||
|
||||
chn = xmalloc_array(struct evtchn, EVTCHNS_PER_BUCKET);
|
||||
@@ -517,12 +518,12 @@ void evtchn_set_pending(struct vcpu *v,
|
||||
* others may require explicit memory barriers.
|
||||
*/
|
||||
|
||||
- if ( test_and_set_bit(port, s->evtchn_pending) )
|
||||
+ if ( test_and_set_bit(port, __shared_info_addr(d, s, evtchn_pending)) )
|
||||
return;
|
||||
|
||||
- if ( !test_bit (port, s->evtchn_mask) &&
|
||||
- !test_and_set_bit(port / BITS_PER_LONG,
|
||||
- &v->vcpu_info->evtchn_pending_sel) )
|
||||
+ if ( !test_bit (port, __shared_info_addr(d, s, evtchn_mask)) &&
|
||||
+ !test_and_set_bit(port / BITS_PER_GUEST_LONG(d),
|
||||
+ vcpu_info_addr(v, evtchn_pending_sel)) )
|
||||
{
|
||||
vcpu_mark_events_pending(v);
|
||||
}
|
||||
@@ -720,10 +721,10 @@ static long evtchn_unmask(evtchn_unmask_
|
||||
* These operations must happen in strict order. Based on
|
||||
* include/xen/event.h:evtchn_set_pending().
|
||||
*/
|
||||
- if ( test_and_clear_bit(port, s->evtchn_mask) &&
|
||||
- test_bit (port, s->evtchn_pending) &&
|
||||
- !test_and_set_bit (port / BITS_PER_LONG,
|
||||
- &v->vcpu_info->evtchn_pending_sel) )
|
||||
+ if ( test_and_clear_bit(port, __shared_info_addr(d, s, evtchn_mask)) &&
|
||||
+ test_bit (port, __shared_info_addr(d, s, evtchn_pending)) &&
|
||||
+ !test_and_set_bit (port / BITS_PER_GUEST_LONG(d),
|
||||
+ vcpu_info_addr(v, evtchn_pending_sel)) )
|
||||
{
|
||||
vcpu_mark_events_pending(v);
|
||||
}
|
||||
Index: 2007-01-08/xen/common/kernel.c
|
||||
===================================================================
|
||||
--- 2007-01-08.orig/xen/common/kernel.c 2007-01-08 15:17:29.000000000 +0100
|
||||
+++ 2007-01-08/xen/common/kernel.c 2007-01-08 15:19:11.000000000 +0100
|
||||
@@ -16,6 +16,9 @@
|
||||
#include <asm/current.h>
|
||||
#include <public/nmi.h>
|
||||
#include <public/version.h>
|
||||
+#ifdef CONFIG_X86
|
||||
+#include <asm/shared.h>
|
||||
+#endif
|
||||
|
||||
#ifndef COMPAT
|
||||
|
||||
@@ -253,7 +256,7 @@ long register_guest_nmi_callback(unsigne
|
||||
* If no handler was registered we can 'lose the NMI edge'. Re-assert it
|
||||
* now.
|
||||
*/
|
||||
- if ( d->shared_info->arch.nmi_reason != 0 )
|
||||
+ if ( arch_get_nmi_reason(d) != 0 )
|
||||
set_bit(_VCPUF_nmi_pending, &v->vcpu_flags);
|
||||
#endif
|
||||
|
||||
Index: 2007-01-08/xen/common/keyhandler.c
|
||||
===================================================================
|
||||
--- 2007-01-08.orig/xen/common/keyhandler.c 2007-01-08 15:34:16.000000000 +0100
|
||||
+++ 2007-01-08/xen/common/keyhandler.c 2007-01-08 15:19:11.000000000 +0100
|
||||
@@ -12,6 +12,7 @@
|
||||
#include <xen/softirq.h>
|
||||
#include <xen/domain.h>
|
||||
#include <xen/rangeset.h>
|
||||
+#include <xen/compat.h>
|
||||
#include <asm/debugger.h>
|
||||
#include <asm/shadow.h>
|
||||
#include <asm/div64.h>
|
||||
@@ -171,8 +172,8 @@ static void dump_domains(unsigned char k
|
||||
v->vcpu_id, v->processor,
|
||||
test_bit(_VCPUF_running, &v->vcpu_flags) ? 'T':'F',
|
||||
v->vcpu_flags,
|
||||
- v->vcpu_info->evtchn_upcall_pending,
|
||||
- v->vcpu_info->evtchn_upcall_mask);
|
||||
+ vcpu_info(v, evtchn_upcall_pending),
|
||||
+ vcpu_info(v, evtchn_upcall_mask));
|
||||
cpuset_print(cpuset, sizeof(cpuset), v->vcpu_dirty_cpumask);
|
||||
printk("dirty_cpus=%s ", cpuset);
|
||||
cpuset_print(cpuset, sizeof(cpuset), v->cpu_affinity);
|
||||
@@ -181,11 +182,11 @@ static void dump_domains(unsigned char k
|
||||
printk(" Notifying guest (virq %d, port %d, stat %d/%d/%d)\n",
|
||||
VIRQ_DEBUG, v->virq_to_evtchn[VIRQ_DEBUG],
|
||||
test_bit(v->virq_to_evtchn[VIRQ_DEBUG],
|
||||
- d->shared_info->evtchn_pending),
|
||||
+ shared_info_addr(d, evtchn_pending)),
|
||||
test_bit(v->virq_to_evtchn[VIRQ_DEBUG],
|
||||
- d->shared_info->evtchn_mask),
|
||||
- test_bit(v->virq_to_evtchn[VIRQ_DEBUG]/BITS_PER_LONG,
|
||||
- &v->vcpu_info->evtchn_pending_sel));
|
||||
+ shared_info_addr(d, evtchn_mask)),
|
||||
+ test_bit(v->virq_to_evtchn[VIRQ_DEBUG]/BITS_PER_GUEST_LONG(d),
|
||||
+ vcpu_info_addr(v, evtchn_pending_sel)));
|
||||
send_guest_vcpu_virq(v, VIRQ_DEBUG);
|
||||
}
|
||||
}
|
||||
Index: 2007-01-08/xen/common/schedule.c
|
||||
===================================================================
|
||||
--- 2007-01-08.orig/xen/common/schedule.c 2007-01-08 15:34:16.000000000 +0100
|
||||
+++ 2007-01-08/xen/common/schedule.c 2007-01-08 15:19:11.000000000 +0100
|
||||
@@ -277,10 +277,11 @@ static long do_block(void)
|
||||
|
||||
static long do_poll(struct sched_poll *sched_poll)
|
||||
{
|
||||
- struct vcpu *v = current;
|
||||
- evtchn_port_t port;
|
||||
- long rc = 0;
|
||||
- unsigned int i;
|
||||
+ struct vcpu *v = current;
|
||||
+ struct domain *d = v->domain;
|
||||
+ evtchn_port_t port;
|
||||
+ long rc = 0;
|
||||
+ unsigned int i;
|
||||
|
||||
/* Fairly arbitrary limit. */
|
||||
if ( sched_poll->nr_ports > 128 )
|
||||
@@ -292,7 +293,7 @@ static long do_poll(struct sched_poll *s
|
||||
/* These operations must occur in order. */
|
||||
set_bit(_VCPUF_blocked, &v->vcpu_flags);
|
||||
set_bit(_VCPUF_polling, &v->vcpu_flags);
|
||||
- set_bit(_DOMF_polling, &v->domain->domain_flags);
|
||||
+ set_bit(_DOMF_polling, &d->domain_flags);
|
||||
|
||||
/* Check for events /after/ setting flags: avoids wakeup waiting race. */
|
||||
for ( i = 0; i < sched_poll->nr_ports; i++ )
|
||||
@@ -302,18 +303,18 @@ static long do_poll(struct sched_poll *s
|
||||
goto out;
|
||||
|
||||
rc = -EINVAL;
|
||||
- if ( port >= MAX_EVTCHNS )
|
||||
+ if ( port >= MAX_EVTCHNS(d) )
|
||||
goto out;
|
||||
|
||||
rc = 0;
|
||||
- if ( test_bit(port, v->domain->shared_info->evtchn_pending) )
|
||||
+ if ( test_bit(port, shared_info_addr(d, evtchn_pending)) )
|
||||
goto out;
|
||||
}
|
||||
|
||||
if ( sched_poll->timeout != 0 )
|
||||
set_timer(&v->poll_timer, sched_poll->timeout);
|
||||
|
||||
- TRACE_2D(TRC_SCHED_BLOCK, v->domain->domain_id, v->vcpu_id);
|
||||
+ TRACE_2D(TRC_SCHED_BLOCK, d->domain_id, v->vcpu_id);
|
||||
raise_softirq(SCHEDULE_SOFTIRQ);
|
||||
|
||||
return 0;
|
||||
Index: 2007-01-08/xen/include/Makefile
|
||||
===================================================================
|
||||
--- 2007-01-08.orig/xen/include/Makefile 2007-01-08 15:18:58.000000000 +0100
|
||||
+++ 2007-01-08/xen/include/Makefile 2007-01-08 15:19:11.000000000 +0100
|
||||
@@ -32,6 +32,7 @@ compat/%.h: compat/%.i Makefile
|
||||
sed -e 's,__InClUdE__,#include,' \
|
||||
-e 's,"xen-compat.h",<public/xen-compat.h>,' \
|
||||
-e 's,\(struct\|union\|enum\)[[:space:]]\+\(xen_\?\)\?\([[:alpha:]_]\),\1 compat_\3,g' \
|
||||
+ -e 's,@KeeP@,,g' \
|
||||
-e 's,_t\([^[:alnum:]_]\|$$\),_compat_t\1,g' \
|
||||
-e 's,\(8\|16\|32\|64\)_compat_t\([^[:alnum:]_]\|$$\),\1_t\2,g' \
|
||||
-e 's,\(^\|[^[:alnum:]_]\)xen_\?\([[:alnum:]_]*\)_compat_t\([^[:alnum:]_]\|$$\),\1compat_\2_t\3,g' \
|
||||
@@ -46,13 +47,15 @@ compat/%.h: compat/%.i Makefile
|
||||
compat/%.i: compat/%.c Makefile
|
||||
$(CPP) $(CFLAGS) $(cppflags-y) -o $@ $<
|
||||
|
||||
-compat/%.c: public/%.h Makefile
|
||||
+compat/%.c: public/%.h xlat.lst Makefile
|
||||
mkdir -p $(@D)
|
||||
grep -v 'DEFINE_XEN_GUEST_HANDLE(long)' $< | \
|
||||
sed -e 's,^[[:space:]]*#[[:space:]]*include[[:space:]]\+,__InClUdE__ ,' \
|
||||
-e 's,^[[:space:]]*#[[:space:]]*define[[:space:]]\+\([[:upper:]_]*_GUEST_HANDLE\),#define HIDE_\1,' \
|
||||
-e 's,^[[:space:]]*#[[:space:]]*define[[:space:]]\+\([[:lower:]_]*_guest_handle\),#define hide_\1,' \
|
||||
-e 's,XEN_GUEST_HANDLE\(_[[:xdigit:]]\+\)\?,COMPAT_HANDLE,g' \
|
||||
+ $(foreach n,$(shell sed -n 's,^[[:space:]]*?[[:space:]]\+\([[:alnum:]_]*\)[[:space:]].*,\1,p' xlat.lst), \
|
||||
+ -e 's,\(struct\|union\)[[:space:]]\+\(xen_\?\)\?$n[[:space:]]\+\([[:alpha:]_]\),\1 @KeeP@\2$n \3,g') \
|
||||
>$@.new
|
||||
mv -f $@.new $@
|
||||
|
||||
Index: 2007-01-08/xen/include/asm-ia64/shared.h
|
||||
===================================================================
|
||||
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
|
||||
+++ 2007-01-08/xen/include/asm-ia64/shared.h 2007-01-08 15:19:11.000000000 +0100
|
||||
@@ -0,0 +1,4 @@
|
||||
+#ifndef __XEN_ASM_SHARED_H__
|
||||
+#define __XEN_ASM_SHARED_H__
|
||||
+
|
||||
+#endif /* __XEN_ASM_SHARED_H__ */
|
||||
Index: 2007-01-08/xen/include/asm-powerpc/shared.h
|
||||
===================================================================
|
||||
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
|
||||
+++ 2007-01-08/xen/include/asm-powerpc/shared.h 2007-01-08 15:19:11.000000000 +0100
|
||||
@@ -0,0 +1,4 @@
|
||||
+#ifndef __XEN_ASM_SHARED_H__
|
||||
+#define __XEN_ASM_SHARED_H__
|
||||
+
|
||||
+#endif /* __XEN_ASM_SHARED_H__ */
|
||||
Index: 2007-01-08/xen/include/asm-x86/shared.h
|
||||
===================================================================
|
||||
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
|
||||
+++ 2007-01-08/xen/include/asm-x86/shared.h 2007-01-08 15:19:11.000000000 +0100
|
||||
@@ -0,0 +1,78 @@
|
||||
+#ifndef __XEN_X86_SHARED_H__
|
||||
+#define __XEN_X86_SHARED_H__
|
||||
+
|
||||
+#ifdef CONFIG_COMPAT
|
||||
+
|
||||
+#define nmi_reason(d) (!IS_COMPAT(d) ? \
|
||||
+ (void *)&(d)->shared_info->native.arch.nmi_reason : \
|
||||
+ (void *)&(d)->shared_info->compat.arch.nmi_reason)
|
||||
+
|
||||
+#define GET_SET_SHARED(type, field) \
|
||||
+static inline type arch_get_##field(const struct domain *d) \
|
||||
+{ \
|
||||
+ return !IS_COMPAT(d) ? \
|
||||
+ d->shared_info->native.arch.field : \
|
||||
+ d->shared_info->compat.arch.field; \
|
||||
+} \
|
||||
+static inline void arch_set_##field(struct domain *d, \
|
||||
+ type val) \
|
||||
+{ \
|
||||
+ if ( !IS_COMPAT(d) ) \
|
||||
+ d->shared_info->native.arch.field = val; \
|
||||
+ else \
|
||||
+ d->shared_info->compat.arch.field = val; \
|
||||
+}
|
||||
+
|
||||
+#define GET_SET_VCPU(type, field) \
|
||||
+static inline type arch_get_##field(const struct vcpu *v) \
|
||||
+{ \
|
||||
+ return !IS_COMPAT(v->domain) ? \
|
||||
+ v->vcpu_info->native.arch.field : \
|
||||
+ v->vcpu_info->compat.arch.field; \
|
||||
+} \
|
||||
+static inline void arch_set_##field(struct vcpu *v, \
|
||||
+ type val) \
|
||||
+{ \
|
||||
+ if ( !IS_COMPAT(v->domain) ) \
|
||||
+ v->vcpu_info->native.arch.field = val; \
|
||||
+ else \
|
||||
+ v->vcpu_info->compat.arch.field = val; \
|
||||
+}
|
||||
+
|
||||
+#else
|
||||
+
|
||||
+#define nmi_reason(d) ((void *)&(d)->shared_info->arch.nmi_reason)
|
||||
+
|
||||
+#define GET_SET_SHARED(type, field) \
|
||||
+static inline type arch_get_##field(const struct domain *d) \
|
||||
+{ \
|
||||
+ return d->shared_info->arch.field; \
|
||||
+} \
|
||||
+static inline void arch_set_##field(struct domain *d, \
|
||||
+ type val) \
|
||||
+{ \
|
||||
+ d->shared_info->arch.field = val; \
|
||||
+}
|
||||
+
|
||||
+#define GET_SET_VCPU(type, field) \
|
||||
+static inline type arch_get_##field(const struct vcpu *v) \
|
||||
+{ \
|
||||
+ return v->vcpu_info->arch.field; \
|
||||
+} \
|
||||
+static inline void arch_set_##field(struct vcpu *v, \
|
||||
+ type val) \
|
||||
+{ \
|
||||
+ v->vcpu_info->arch.field = val; \
|
||||
+}
|
||||
+#endif
|
||||
+
|
||||
+GET_SET_SHARED(unsigned long, max_pfn)
|
||||
+GET_SET_SHARED(xen_pfn_t, pfn_to_mfn_frame_list_list)
|
||||
+GET_SET_SHARED(unsigned long, nmi_reason)
|
||||
+
|
||||
+GET_SET_VCPU(unsigned long, cr2)
|
||||
+
|
||||
+#undef GET_SET_VCPU
|
||||
+#undef GET_SET_SHARED
|
||||
+
|
||||
+#endif /* __XEN_X86_SHARED_H__ */
|
||||
Index: 2007-01-08/xen/include/asm-x86/compat.h
|
||||
===================================================================
|
||||
--- 2007-01-08.orig/xen/include/asm-x86/compat.h 2007-01-08 15:17:29.000000000 +0100
|
||||
+++ 2007-01-08/xen/include/asm-x86/compat.h 2007-01-08 15:19:11.000000000 +0100
|
||||
@@ -2,5 +2,7 @@
|
||||
* compat.h
|
||||
*/
|
||||
|
||||
+#define COMPAT_BITS_PER_LONG 32
|
||||
+
|
||||
typedef uint32_t compat_ptr_t;
|
||||
typedef unsigned long full_ptr_t;
|
||||
Index: 2007-01-08/xen/include/asm-x86/event.h
|
||||
===================================================================
|
||||
--- 2007-01-08.orig/xen/include/asm-x86/event.h 2007-01-08 15:34:16.000000000 +0100
|
||||
+++ 2007-01-08/xen/include/asm-x86/event.h 2007-01-08 15:19:11.000000000 +0100
|
||||
@@ -9,6 +9,8 @@
|
||||
#ifndef __ASM_EVENT_H__
|
||||
#define __ASM_EVENT_H__
|
||||
|
||||
+#include <xen/shared.h>
|
||||
+
|
||||
static inline void vcpu_kick(struct vcpu *v)
|
||||
{
|
||||
/*
|
||||
@@ -28,7 +30,7 @@ static inline void vcpu_kick(struct vcpu
|
||||
|
||||
static inline void vcpu_mark_events_pending(struct vcpu *v)
|
||||
{
|
||||
- if ( !test_and_set_bit(0, &v->vcpu_info->evtchn_upcall_pending) )
|
||||
+ if ( !test_and_set_bit(0, &vcpu_info(v, evtchn_upcall_pending)) )
|
||||
vcpu_kick(v);
|
||||
}
|
||||
|
||||
@@ -36,23 +38,23 @@ static inline int local_events_need_deli
|
||||
{
|
||||
struct vcpu *v = current;
|
||||
/* Note: Bitwise operations result in fast code with no branches. */
|
||||
- return (!!v->vcpu_info->evtchn_upcall_pending &
|
||||
- !v->vcpu_info->evtchn_upcall_mask);
|
||||
+ return (!!vcpu_info(v, evtchn_upcall_pending) &
|
||||
+ !vcpu_info(v, evtchn_upcall_mask));
|
||||
}
|
||||
|
||||
static inline int local_event_delivery_is_enabled(void)
|
||||
{
|
||||
- return !current->vcpu_info->evtchn_upcall_mask;
|
||||
+ return !vcpu_info(current, evtchn_upcall_mask);
|
||||
}
|
||||
|
||||
static inline void local_event_delivery_disable(void)
|
||||
{
|
||||
- current->vcpu_info->evtchn_upcall_mask = 1;
|
||||
+ vcpu_info(current, evtchn_upcall_mask) = 1;
|
||||
}
|
||||
|
||||
static inline void local_event_delivery_enable(void)
|
||||
{
|
||||
- current->vcpu_info->evtchn_upcall_mask = 0;
|
||||
+ vcpu_info(current, evtchn_upcall_mask) = 0;
|
||||
}
|
||||
|
||||
/* No arch specific virq definition now. Default to global. */
|
||||
Index: 2007-01-08/xen/include/public/xen.h
|
||||
===================================================================
|
||||
--- 2007-01-08.orig/xen/include/public/xen.h 2007-01-08 15:34:16.000000000 +0100
|
||||
+++ 2007-01-08/xen/include/public/xen.h 2007-01-08 15:19:11.000000000 +0100
|
||||
@@ -408,7 +408,9 @@ struct vcpu_info {
|
||||
struct arch_vcpu_info arch;
|
||||
struct vcpu_time_info time;
|
||||
}; /* 64 bytes (x86) */
|
||||
+#ifndef __XEN__
|
||||
typedef struct vcpu_info vcpu_info_t;
|
||||
+#endif
|
||||
|
||||
/*
|
||||
* Xen/kernel shared data -- pointer provided in start_info.
|
||||
@@ -466,7 +468,9 @@ struct shared_info {
|
||||
struct arch_shared_info arch;
|
||||
|
||||
};
|
||||
+#ifndef __XEN__
|
||||
typedef struct shared_info shared_info_t;
|
||||
+#endif
|
||||
|
||||
/*
|
||||
* Start-of-day memory layout for the initial domain (DOM0):
|
||||
Index: 2007-01-08/xen/include/xen/compat.h
|
||||
===================================================================
|
||||
--- 2007-01-08.orig/xen/include/xen/compat.h 2007-01-08 15:17:29.000000000 +0100
|
||||
+++ 2007-01-08/xen/include/xen/compat.h 2007-01-08 15:19:11.000000000 +0100
|
||||
@@ -162,6 +162,12 @@ extern int compat_disabled;
|
||||
struct start_info;
|
||||
void xlat_start_info(struct start_info *, enum XLAT_start_info_console);
|
||||
|
||||
+#define BITS_PER_GUEST_LONG(d) (!IS_COMPAT(d) ? BITS_PER_LONG : COMPAT_BITS_PER_LONG)
|
||||
+
|
||||
+#else
|
||||
+
|
||||
+#define BITS_PER_GUEST_LONG(d) BITS_PER_LONG
|
||||
+
|
||||
#endif
|
||||
|
||||
#endif /* __XEN_COMPAT_H__ */
|
||||
Index: 2007-01-08/xen/include/xen/sched.h
|
||||
===================================================================
|
||||
--- 2007-01-08.orig/xen/include/xen/sched.h 2007-01-08 14:45:40.000000000 +0100
|
||||
+++ 2007-01-08/xen/include/xen/sched.h 2007-01-08 15:19:11.000000000 +0100
|
||||
@@ -6,6 +6,7 @@
|
||||
#include <xen/types.h>
|
||||
#include <xen/spinlock.h>
|
||||
#include <xen/smp.h>
|
||||
+#include <xen/shared.h>
|
||||
#include <public/xen.h>
|
||||
#include <public/domctl.h>
|
||||
#include <public/vcpu.h>
|
||||
@@ -23,9 +24,15 @@ extern rwlock_t domlist_lock;
|
||||
/* A global pointer to the initial domain (DOM0). */
|
||||
extern struct domain *dom0;
|
||||
|
||||
-#define MAX_EVTCHNS NR_EVENT_CHANNELS
|
||||
+#ifndef CONFIG_COMPAT
|
||||
+#define MAX_EVTCHNS(d) NR_EVENT_CHANNELS
|
||||
+#else
|
||||
+#define MAX_EVTCHNS(d) (!IS_COMPAT(d) ? \
|
||||
+ NR_EVENT_CHANNELS : \
|
||||
+ sizeof(unsigned int) * sizeof(unsigned int) * 64)
|
||||
+#endif
|
||||
#define EVTCHNS_PER_BUCKET 128
|
||||
-#define NR_EVTCHN_BUCKETS (MAX_EVTCHNS / EVTCHNS_PER_BUCKET)
|
||||
+#define NR_EVTCHN_BUCKETS (NR_EVENT_CHANNELS / EVTCHNS_PER_BUCKET)
|
||||
|
||||
struct evtchn
|
||||
{
|
||||
Index: 2007-01-08/xen/include/xen/shared.h
|
||||
===================================================================
|
||||
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
|
||||
+++ 2007-01-08/xen/include/xen/shared.h 2007-01-08 15:19:11.000000000 +0100
|
||||
@@ -0,0 +1,54 @@
|
||||
+#ifndef __XEN_SHARED_H__
|
||||
+#define __XEN_SHARED_H__
|
||||
+
|
||||
+#include <xen/config.h>
|
||||
+
|
||||
+#ifdef CONFIG_COMPAT
|
||||
+
|
||||
+#include <compat/xen.h>
|
||||
+
|
||||
+typedef union {
|
||||
+ struct shared_info native;
|
||||
+ struct compat_shared_info compat;
|
||||
+} shared_info_t;
|
||||
+
|
||||
+#define __shared_info(d, s, field) (*(!IS_COMPAT(d) ? \
|
||||
+ &(s)->native.field : \
|
||||
+ &(s)->compat.field))
|
||||
+#define __shared_info_addr(d, s, field) (!IS_COMPAT(d) ? \
|
||||
+ (void *)&(s)->native.field : \
|
||||
+ (void *)&(s)->compat.field)
|
||||
+
|
||||
+#define shared_info(d, field) __shared_info(d, (d)->shared_info, field)
|
||||
+#define shared_info_addr(d, field) __shared_info_addr(d, (d)->shared_info, field)
|
||||
+
|
||||
+typedef union {
|
||||
+ struct vcpu_info native;
|
||||
+ struct compat_vcpu_info compat;
|
||||
+} vcpu_info_t;
|
||||
+
|
||||
+#define vcpu_info(v, field) (*(!IS_COMPAT((v)->domain) ? \
|
||||
+ &(v)->vcpu_info->native.field : \
|
||||
+ &(v)->vcpu_info->compat.field))
|
||||
+#define vcpu_info_addr(v, field) (!IS_COMPAT((v)->domain) ? \
|
||||
+ (void *)&(v)->vcpu_info->native.field : \
|
||||
+ (void *)&(v)->vcpu_info->compat.field)
|
||||
+
|
||||
+#else
|
||||
+
|
||||
+typedef struct shared_info shared_info_t;
|
||||
+
|
||||
+#define __shared_info(d, s, field) ((s)->field)
|
||||
+#define __shared_info_addr(d, s, field) ((void *)&(s)->field)
|
||||
+
|
||||
+#define shared_info(d, field) ((d)->shared_info->field)
|
||||
+#define shared_info_addr(d, field) ((void *)&(d)->shared_info->field)
|
||||
+
|
||||
+typedef struct vcpu_info vcpu_info_t;
|
||||
+
|
||||
+#define vcpu_info(v, field) ((v)->vcpu_info->field)
|
||||
+#define vcpu_info_addr(v, field) ((void *)&(v)->vcpu_info->field)
|
||||
+
|
||||
+#endif
|
||||
+
|
||||
+#endif /* __XEN_SHARED_H__ */
|
||||
Index: 2007-01-08/xen/include/xlat.lst
|
||||
===================================================================
|
||||
--- 2007-01-08.orig/xen/include/xlat.lst 2007-01-08 15:18:32.000000000 +0100
|
||||
+++ 2007-01-08/xen/include/xlat.lst 2007-01-08 15:19:11.000000000 +0100
|
||||
@@ -3,3 +3,4 @@
|
||||
# ? - needs checking
|
||||
? dom0_vga_console_info xen.h
|
||||
! start_info xen.h
|
||||
+? vcpu_time_info xen.h
|
584
32on64-startup.patch
Normal file
584
32on64-startup.patch
Normal file
@ -0,0 +1,584 @@
|
||||
Handle the creation of startup info for compatibility mode guests. This
|
||||
includes a script to auto-generate checking or translation code between
|
||||
native and compatibility mode hypercall argument structures.
|
||||
|
||||
Index: 2007-01-08/Config.mk
|
||||
===================================================================
|
||||
--- 2007-01-08.orig/Config.mk 2007-01-08 15:34:16.000000000 +0100
|
||||
+++ 2007-01-08/Config.mk 2007-01-08 15:18:32.000000000 +0100
|
||||
@@ -11,6 +11,8 @@ XEN_OS ?= $(shell uname -s)
|
||||
|
||||
CONFIG_$(XEN_OS) := y
|
||||
|
||||
+SHELL ?= /bin/sh
|
||||
+
|
||||
# Tools to run on system hosting the build
|
||||
HOSTCC = gcc
|
||||
HOSTCFLAGS = -Wall -Werror -Wstrict-prototypes -O2 -fomit-frame-pointer
|
||||
Index: 2007-01-08/xen/arch/x86/domain_build.c
|
||||
===================================================================
|
||||
--- 2007-01-08.orig/xen/arch/x86/domain_build.c 2007-01-08 15:34:55.000000000 +0100
|
||||
+++ 2007-01-08/xen/arch/x86/domain_build.c 2007-01-08 15:35:20.000000000 +0100
|
||||
@@ -19,6 +19,7 @@
|
||||
#include <xen/version.h>
|
||||
#include <xen/iocap.h>
|
||||
#include <xen/bitops.h>
|
||||
+#include <xen/compat.h>
|
||||
#include <asm/regs.h>
|
||||
#include <asm/system.h>
|
||||
#include <asm/io.h>
|
||||
@@ -848,6 +849,11 @@ int construct_dom0(struct domain *d,
|
||||
si->console.dom0.info_size = sizeof(struct dom0_vga_console_info);
|
||||
}
|
||||
|
||||
+#ifdef CONFIG_COMPAT
|
||||
+ if ( IS_COMPAT(d) )
|
||||
+ xlat_start_info(si, XLAT_start_info_console_dom0);
|
||||
+#endif
|
||||
+
|
||||
/* Reinstate the caller's page tables. */
|
||||
write_ptbase(current);
|
||||
local_irq_enable();
|
||||
Index: 2007-01-08/xen/arch/x86/setup.c
|
||||
===================================================================
|
||||
--- 2007-01-08.orig/xen/arch/x86/setup.c 2007-01-08 14:45:40.000000000 +0100
|
||||
+++ 2007-01-08/xen/arch/x86/setup.c 2007-01-08 15:18:32.000000000 +0100
|
||||
@@ -18,6 +18,10 @@
|
||||
#include <xen/keyhandler.h>
|
||||
#include <xen/numa.h>
|
||||
#include <public/version.h>
|
||||
+#ifdef CONFIG_COMPAT
|
||||
+#include <compat/platform.h>
|
||||
+#include <compat/xen.h>
|
||||
+#endif
|
||||
#include <asm/bitops.h>
|
||||
#include <asm/smp.h>
|
||||
#include <asm/processor.h>
|
||||
@@ -546,6 +550,14 @@ void __init __start_xen(multiboot_info_t
|
||||
BUILD_BUG_ON(sizeof(shared_info_t) > PAGE_SIZE);
|
||||
BUILD_BUG_ON(sizeof(vcpu_info_t) != 64);
|
||||
|
||||
+#ifdef CONFIG_COMPAT
|
||||
+ BUILD_BUG_ON(sizeof(((struct compat_platform_op *)0)->u) !=
|
||||
+ sizeof(((struct compat_platform_op *)0)->u.pad));
|
||||
+ BUILD_BUG_ON(sizeof(start_info_compat_t) > PAGE_SIZE);
|
||||
+ BUILD_BUG_ON(sizeof(shared_info_compat_t) > PAGE_SIZE);
|
||||
+ BUILD_BUG_ON(sizeof(vcpu_info_compat_t) != 64);
|
||||
+#endif
|
||||
+
|
||||
/* Check definitions in public headers match internal defs. */
|
||||
BUILD_BUG_ON(__HYPERVISOR_VIRT_START != HYPERVISOR_VIRT_START);
|
||||
#ifdef HYPERVISOR_VIRT_END
|
||||
Index: 2007-01-08/xen/common/compat/Makefile
|
||||
===================================================================
|
||||
--- 2007-01-08.orig/xen/common/compat/Makefile 2007-01-08 15:17:29.000000000 +0100
|
||||
+++ 2007-01-08/xen/common/compat/Makefile 2007-01-08 15:18:32.000000000 +0100
|
||||
@@ -1,4 +1,5 @@
|
||||
obj-y += kernel.o
|
||||
+obj-y += xlat.o
|
||||
|
||||
# extra dependencies
|
||||
kernel.o: ../kernel.c
|
||||
Index: 2007-01-08/xen/common/compat/xlat.c
|
||||
===================================================================
|
||||
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
|
||||
+++ 2007-01-08/xen/common/compat/xlat.c 2007-01-08 15:18:32.000000000 +0100
|
||||
@@ -0,0 +1,32 @@
|
||||
+/******************************************************************************
|
||||
+ * xlat.c
|
||||
+ */
|
||||
+
|
||||
+#include <xen/compat.h>
|
||||
+#include <xen/lib.h>
|
||||
+#include <public/xen.h>
|
||||
+#include <compat/xen.h>
|
||||
+
|
||||
+/* In-place translation functons: */
|
||||
+void xlat_start_info(struct start_info *native,
|
||||
+ enum XLAT_start_info_console console)
|
||||
+{
|
||||
+ struct compat_start_info *compat = (void *)native;
|
||||
+
|
||||
+ BUILD_BUG_ON(sizeof(*native) < sizeof(*compat));
|
||||
+ XLAT_start_info(compat, native);
|
||||
+}
|
||||
+
|
||||
+#define xen_dom0_vga_console_info dom0_vga_console_info
|
||||
+CHECK_dom0_vga_console_info;
|
||||
+#undef dom0_vga_console_info
|
||||
+
|
||||
+/*
|
||||
+ * Local variables:
|
||||
+ * mode: C
|
||||
+ * c-set-style: "BSD"
|
||||
+ * c-basic-offset: 4
|
||||
+ * tab-width: 4
|
||||
+ * indent-tabs-mode: nil
|
||||
+ * End:
|
||||
+ */
|
||||
Index: 2007-01-08/xen/include/Makefile
|
||||
===================================================================
|
||||
--- 2007-01-08.orig/xen/include/Makefile 2007-01-08 15:18:26.000000000 +0100
|
||||
+++ 2007-01-08/xen/include/Makefile 2007-01-08 15:18:58.000000000 +0100
|
||||
@@ -5,7 +5,7 @@ compat-arch-$(CONFIG_X86) := x86
|
||||
|
||||
headers-y := $(shell echo public/*.h | sed -e 's,[^[:space:]]*-[^[:space:]]*,,g' -e 's,public/,compat/,g')
|
||||
headers-y := $(filter-out %/dom0_ops.h,$(headers-y))
|
||||
-headers-y += compat/arch-$(compat-subarch-y).h
|
||||
+headers-y += compat/arch-$(compat-subarch-y).h compat/xlat.h
|
||||
headers-y += compat/arch-$(compat-arch-y)/xen.h
|
||||
headers-y += compat/arch-$(compat-arch-y)/xen-$(compat-subarch-y).h
|
||||
|
||||
@@ -56,5 +56,12 @@ compat/%.c: public/%.h Makefile
|
||||
>$@.new
|
||||
mv -f $@.new $@
|
||||
|
||||
+compat/xlat.h: xlat.lst $(filter-out compat/xlat.h,$(headers-y)) $(BASEDIR)/tools/get-fields.sh Makefile
|
||||
+ grep -v '^[[:space:]]*#' xlat.lst | \
|
||||
+ while read what name hdr; do \
|
||||
+ $(SHELL) $(BASEDIR)/tools/get-fields.sh "$$what" compat_$$name $$(echo compat/$$hdr | sed -e 's,@arch@,$(compat-arch-y),g' -e 's,@subarch@,$(compat-subarch-y),g') || exit $$?; \
|
||||
+ done >$@.new
|
||||
+ mv -f $@.new $@
|
||||
+
|
||||
clean::
|
||||
rm -rf compat
|
||||
Index: 2007-01-08/xen/include/xlat.lst
|
||||
===================================================================
|
||||
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
|
||||
+++ 2007-01-08/xen/include/xlat.lst 2007-01-08 15:18:32.000000000 +0100
|
||||
@@ -0,0 +1,5 @@
|
||||
+# First column indicator:
|
||||
+# ! - needs translation
|
||||
+# ? - needs checking
|
||||
+? dom0_vga_console_info xen.h
|
||||
+! start_info xen.h
|
||||
Index: 2007-01-08/xen/tools/get-fields.sh
|
||||
===================================================================
|
||||
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
|
||||
+++ 2007-01-08/xen/tools/get-fields.sh 2007-01-08 15:18:32.000000000 +0100
|
||||
@@ -0,0 +1,425 @@
|
||||
+#!/bin/sh
|
||||
+test -n "$1" -a -n "$2" -a -n "$3"
|
||||
+set -ef
|
||||
+
|
||||
+get_fields() {
|
||||
+ local level=1 aggr=0 name= fields=
|
||||
+ for token in $2
|
||||
+ do
|
||||
+ case "$token" in
|
||||
+ struct|union)
|
||||
+ test $level != 1 || aggr=1 fields= name=
|
||||
+ ;;
|
||||
+ "{")
|
||||
+ level=$(expr $level + 1)
|
||||
+ ;;
|
||||
+ "}")
|
||||
+ level=$(expr $level - 1)
|
||||
+ if [ $level = 1 -a $name = $1 ]
|
||||
+ then
|
||||
+ echo "$fields }"
|
||||
+ return 0
|
||||
+ fi
|
||||
+ ;;
|
||||
+ [[:alpha:]_]*)
|
||||
+ test $aggr = 0 -o -n "$name" || name="$token"
|
||||
+ ;;
|
||||
+ esac
|
||||
+ test $aggr = 0 || fields="$fields $token"
|
||||
+ done
|
||||
+}
|
||||
+
|
||||
+build_enums() {
|
||||
+ local level=1 kind= fields= members= named= id= token
|
||||
+ for token in $2
|
||||
+ do
|
||||
+ case "$token" in
|
||||
+ struct|union)
|
||||
+ test $level != 2 || fields=" "
|
||||
+ kind="$token;$kind"
|
||||
+ ;;
|
||||
+ "{")
|
||||
+ level=$(expr $level + 1)
|
||||
+ ;;
|
||||
+ "}")
|
||||
+ level=$(expr $level - 1)
|
||||
+ if [ $level = 1 ]
|
||||
+ then
|
||||
+ if [ "${kind%%;*}" = union ]
|
||||
+ then
|
||||
+ echo
|
||||
+ echo "enum XLAT_$1 {"
|
||||
+ for m in $members
|
||||
+ do
|
||||
+ echo " XLAT_${1}_$m,"
|
||||
+ done
|
||||
+ echo "};"
|
||||
+ fi
|
||||
+ return 0
|
||||
+ elif [ $level = 2 ]
|
||||
+ then
|
||||
+ named='?'
|
||||
+ fi
|
||||
+ ;;
|
||||
+ [[:alpha:]]*)
|
||||
+ id=$token
|
||||
+ if [ -n "$named" -a -n "${kind#*;}" ]
|
||||
+ then
|
||||
+ build_enums ${1}_$token "$fields"
|
||||
+ named='!'
|
||||
+ fi
|
||||
+ ;;
|
||||
+ ",")
|
||||
+ test $level != 2 || members="$members $id"
|
||||
+ ;;
|
||||
+ ";")
|
||||
+ test $level != 2 || members="$members $id"
|
||||
+ test -z "$named" || kind=${kind#*;}
|
||||
+ named=
|
||||
+ ;;
|
||||
+ esac
|
||||
+ test -z "$fields" || fields="$fields $token"
|
||||
+ done
|
||||
+}
|
||||
+
|
||||
+handle_field() {
|
||||
+ if [ -z "$5" ]
|
||||
+ then
|
||||
+ echo " \\"
|
||||
+ if [ -z "$4" ]
|
||||
+ then
|
||||
+ echo -n "$1(_d_)->$3 = (_s_)->$3;"
|
||||
+ else
|
||||
+ echo -n "$1XLAT_${2}_HNDL_$(echo $3 | sed 's,\.,_,g')(_d_, _s_);"
|
||||
+ fi
|
||||
+ elif [ -z "$(echo "$5" | sed 's,[^{}],,g')" ]
|
||||
+ then
|
||||
+ local tag=$(echo "$5" | sed 's,[[:space:]]*\(struct\|union\)[[:space:]]\+\(compat_\)\?\([[:alnum:]_]\+\)[[:space:]].*,\3,')
|
||||
+ echo " \\"
|
||||
+ echo -n "${1}XLAT_$tag(&(_d_)->$3, &(_s_)->$3);"
|
||||
+ else
|
||||
+ local level=1 kind= fields= id= array= arrlvl=1 array_type= type= token
|
||||
+ for token in $5
|
||||
+ do
|
||||
+ case "$token" in
|
||||
+ struct|union)
|
||||
+ test $level != 2 || fields=" "
|
||||
+ if [ $level == 1 ]
|
||||
+ then
|
||||
+ kind=$token
|
||||
+ if [ $kind = union ]
|
||||
+ then
|
||||
+ echo " \\"
|
||||
+ echo -n "${1}switch ($(echo $3 | sed 's,\.,_,g')) {"
|
||||
+ fi
|
||||
+ fi
|
||||
+ ;;
|
||||
+ "{")
|
||||
+ level=$(expr $level + 1) id=
|
||||
+ ;;
|
||||
+ "}")
|
||||
+ level=$(expr $level - 1) id=
|
||||
+ if [ $level == 1 -a $kind = union ]
|
||||
+ then
|
||||
+ echo " \\"
|
||||
+ echo -n "$1}"
|
||||
+ fi
|
||||
+ ;;
|
||||
+ "[")
|
||||
+ if [ $level != 2 -o $arrlvl != 1 ]
|
||||
+ then
|
||||
+ :
|
||||
+ elif [ -z "$array" ]
|
||||
+ then
|
||||
+ array=" "
|
||||
+ else
|
||||
+ array="$array;"
|
||||
+ fi
|
||||
+ arrlvl=$(expr $arrlvl + 1)
|
||||
+ ;;
|
||||
+ "]")
|
||||
+ arrlvl=$(expr $arrlvl - 1)
|
||||
+ ;;
|
||||
+ COMPAT_HANDLE\(*\))
|
||||
+ if [ $level == 2 -a -z "$id" ]
|
||||
+ then
|
||||
+ type=${token#COMPAT_HANDLE?}
|
||||
+ type=${type%?}
|
||||
+ type=${type#compat_}
|
||||
+ fi
|
||||
+ ;;
|
||||
+ compat_domain_handle_t)
|
||||
+ if [ $level == 2 -a -z "$id" ]
|
||||
+ then
|
||||
+ array_type=$token
|
||||
+ fi
|
||||
+ ;;
|
||||
+ [[:alpha:]]*)
|
||||
+ id=$token
|
||||
+ ;;
|
||||
+ [\,\;])
|
||||
+ if [ $level == 2 -a -n "$(echo $id | sed 's,^_pad[[:digit:]]*,,')" ]
|
||||
+ then
|
||||
+ if [ $kind = union ]
|
||||
+ then
|
||||
+ echo " \\"
|
||||
+ echo -n "${1}case XLAT_${2}_$(echo $3.$id | sed 's,\.,_,g'):"
|
||||
+ handle_field "$1 " $2 $3.$id "$type" "$fields"
|
||||
+ elif [ -z "$array" -a -z "$array_type" ]
|
||||
+ then
|
||||
+ handle_field "$1" $2 $3.$id "$type" "$fields"
|
||||
+ elif [ -z "$array" ]
|
||||
+ then
|
||||
+ copy_array " " $3.$id
|
||||
+ else
|
||||
+ handle_array "$1" $2 $3.$id "${array#*;}" "$type" "$fields"
|
||||
+ fi
|
||||
+ test "$token" != ";" || fields= id= type=
|
||||
+ array=
|
||||
+ if [ $kind = union ]
|
||||
+ then
|
||||
+ echo " \\"
|
||||
+ echo -n "$1 break;"
|
||||
+ fi
|
||||
+ fi
|
||||
+ ;;
|
||||
+ *)
|
||||
+ if [ -n "$array" ]
|
||||
+ then
|
||||
+ array="$array $token"
|
||||
+ fi
|
||||
+ ;;
|
||||
+ esac
|
||||
+ test -z "$fields" || fields="$fields $token"
|
||||
+ done
|
||||
+ fi
|
||||
+}
|
||||
+
|
||||
+copy_array() {
|
||||
+ echo " \\"
|
||||
+ echo "${1}if ((_d_)->$2 != (_s_)->$2) \\"
|
||||
+ echo -n "$1 memcpy((_d_)->$2, (_s_)->$2, sizeof((_d_)->$2));"
|
||||
+}
|
||||
+
|
||||
+handle_array() {
|
||||
+ local i="i$(echo $4 | sed 's,[^;], ,g' | wc -w)"
|
||||
+ echo " \\"
|
||||
+ echo "$1{ \\"
|
||||
+ echo "$1 unsigned int $i; \\"
|
||||
+ echo -n "$1 for ($i = 0; $i < "${4%%;*}"; ++$i) {"
|
||||
+ if [ "$4" = "${4#*;}" ]
|
||||
+ then
|
||||
+ handle_field "$1 " $2 $3[$i] "$5" "$6"
|
||||
+ else
|
||||
+ handle_array "$1 " $2 $3[$i] "${4#*;}" "$5" "$6"
|
||||
+ fi
|
||||
+ echo " \\"
|
||||
+ echo "$1 } \\"
|
||||
+ echo -n "$1}"
|
||||
+}
|
||||
+
|
||||
+build_body() {
|
||||
+ echo
|
||||
+ echo -n "#define XLAT_$1(_d_, _s_)"
|
||||
+ local level=1 fields= id= array= arrlvl=1 array_type= type= token
|
||||
+ for token in $2
|
||||
+ do
|
||||
+ case "$token" in
|
||||
+ struct|union)
|
||||
+ test $level != 2 || fields=" "
|
||||
+ ;;
|
||||
+ "{")
|
||||
+ level=$(expr $level + 1) id=
|
||||
+ ;;
|
||||
+ "}")
|
||||
+ level=$(expr $level - 1) id=
|
||||
+ ;;
|
||||
+ "[")
|
||||
+ if [ $level != 2 -o $arrlvl != 1 ]
|
||||
+ then
|
||||
+ :
|
||||
+ elif [ -z "$array" ]
|
||||
+ then
|
||||
+ array=" "
|
||||
+ else
|
||||
+ array="$array;"
|
||||
+ fi
|
||||
+ arrlvl=$(expr $arrlvl + 1)
|
||||
+ ;;
|
||||
+ "]")
|
||||
+ arrlvl=$(expr $arrlvl - 1)
|
||||
+ ;;
|
||||
+ COMPAT_HANDLE\(*\))
|
||||
+ if [ $level == 2 -a -z "$id" ]
|
||||
+ then
|
||||
+ type=${token#COMPAT_HANDLE?}
|
||||
+ type=${type%?}
|
||||
+ type=${type#compat_}
|
||||
+ fi
|
||||
+ ;;
|
||||
+ compat_domain_handle_t)
|
||||
+ if [ $level == 2 -a -z "$id" ]
|
||||
+ then
|
||||
+ array_type=$token
|
||||
+ fi
|
||||
+ ;;
|
||||
+ [[:alpha:]_]*)
|
||||
+ if [ -n "$array" ]
|
||||
+ then
|
||||
+ array="$array $token"
|
||||
+ else
|
||||
+ id=$token
|
||||
+ fi
|
||||
+ ;;
|
||||
+ [\,\;])
|
||||
+ if [ $level == 2 -a -n "$(echo $id | sed 's,^_pad[[:digit:]]*,,')" ]
|
||||
+ then
|
||||
+ if [ -z "$array" -a -z "$array_type" ]
|
||||
+ then
|
||||
+ handle_field " " $1 $id "$type" "$fields"
|
||||
+ elif [ -z "$array" ]
|
||||
+ then
|
||||
+ copy_array " " $id
|
||||
+ else
|
||||
+ handle_array " " $1 $id "${array#*;}" "$type" "$fields"
|
||||
+ fi
|
||||
+ test "$token" != ";" || fields= id= type=
|
||||
+ array=
|
||||
+ fi
|
||||
+ ;;
|
||||
+ *)
|
||||
+ if [ -n "$array" ]
|
||||
+ then
|
||||
+ array="$array $token"
|
||||
+ fi
|
||||
+ ;;
|
||||
+ esac
|
||||
+ test -z "$fields" || fields="$fields $token"
|
||||
+ done
|
||||
+ echo ""
|
||||
+}
|
||||
+
|
||||
+check_field() {
|
||||
+ if [ -z "$(echo "$4" | sed 's,[^{}],,g')" ]
|
||||
+ then
|
||||
+ echo "; \\"
|
||||
+ local n=$(echo $3 | sed 's,[^.], ,g' | wc -w)
|
||||
+ if [ -n "$4" ]
|
||||
+ then
|
||||
+ for n in $4
|
||||
+ do
|
||||
+ case $n in
|
||||
+ struct|union)
|
||||
+ ;;
|
||||
+ [[:alpha:]_]*)
|
||||
+ echo -n " CHECK_$n"
|
||||
+ break
|
||||
+ ;;
|
||||
+ *)
|
||||
+ echo "Malformed compound declaration: '$n'" >&2
|
||||
+ exit 1
|
||||
+ ;;
|
||||
+ esac
|
||||
+ done
|
||||
+ elif [ $n = 0 ]
|
||||
+ then
|
||||
+ echo -n " CHECK_FIELD_($1, $2, $3)"
|
||||
+ else
|
||||
+ echo -n " CHECK_SUBFIELD_${n}_($1, $2, $(echo $3 | sed 's!\.!, !g'))"
|
||||
+ fi
|
||||
+ else
|
||||
+ local level=1 fields= id= token
|
||||
+ for token in $4
|
||||
+ do
|
||||
+ case "$token" in
|
||||
+ struct|union)
|
||||
+ test $level != 2 || fields=" "
|
||||
+ ;;
|
||||
+ "{")
|
||||
+ level=$(expr $level + 1) id=
|
||||
+ ;;
|
||||
+ "}")
|
||||
+ level=$(expr $level - 1) id=
|
||||
+ ;;
|
||||
+ [[:alpha:]]*)
|
||||
+ id=$token
|
||||
+ ;;
|
||||
+ [\,\;])
|
||||
+ if [ $level == 2 -a -n "$(echo $id | sed 's,^_pad[[:digit:]]*,,')" ]
|
||||
+ then
|
||||
+ check_field $1 $2 $3.$id "$fields"
|
||||
+ test "$token" != ";" || fields= id=
|
||||
+ fi
|
||||
+ ;;
|
||||
+ esac
|
||||
+ test -z "$fields" || fields="$fields $token"
|
||||
+ done
|
||||
+ fi
|
||||
+}
|
||||
+
|
||||
+build_check() {
|
||||
+ echo
|
||||
+ echo "#define CHECK_$1 \\"
|
||||
+ local level=1 fields= kind= id= arrlvl=1 token
|
||||
+ for token in $2
|
||||
+ do
|
||||
+ case "$token" in
|
||||
+ struct|union)
|
||||
+ if [ $level == 1 ]
|
||||
+ then
|
||||
+ kind=$token
|
||||
+ echo -n " CHECK_SIZE_($kind, $1)"
|
||||
+ elif [ $level == 2 ]
|
||||
+ then
|
||||
+ fields=" "
|
||||
+ fi
|
||||
+ ;;
|
||||
+ "{")
|
||||
+ level=$(expr $level + 1) id=
|
||||
+ ;;
|
||||
+ "}")
|
||||
+ level=$(expr $level - 1) id=
|
||||
+ ;;
|
||||
+ "[")
|
||||
+ arrlvl=$(expr $arrlvl + 1)
|
||||
+ ;;
|
||||
+ "]")
|
||||
+ arrlvl=$(expr $arrlvl - 1)
|
||||
+ ;;
|
||||
+ [[:alpha:]_]*)
|
||||
+ test $level != 2 -o $arrlvl != 1 || id=$token
|
||||
+ ;;
|
||||
+ [\,\;])
|
||||
+ if [ $level == 2 -a -n "$(echo $id | sed 's,^_pad[[:digit:]]*,,')" ]
|
||||
+ then
|
||||
+ check_field $kind $1 $id "$fields"
|
||||
+ test "$token" != ";" || fields= id=
|
||||
+ fi
|
||||
+ ;;
|
||||
+ esac
|
||||
+ test -z "$fields" || fields="$fields $token"
|
||||
+ done
|
||||
+ echo ""
|
||||
+}
|
||||
+
|
||||
+fields="$(get_fields $(echo $2 | sed 's,^compat_xen,compat_,') "$(sed -e 's,^[[:space:]]#.*,,' -e 's!\([]\[,;:{}]\)! \1 !g' $3)")"
|
||||
+if [ -z "$fields" ]
|
||||
+then
|
||||
+ echo "Fields of '$2' not found in '$3'" >&2
|
||||
+ exit 1
|
||||
+fi
|
||||
+name=${2#compat_}
|
||||
+name=${name#xen}
|
||||
+case "$1" in
|
||||
+"!")
|
||||
+ build_enums $name "$fields"
|
||||
+ build_body $name "$fields"
|
||||
+ ;;
|
||||
+"?")
|
||||
+ build_check $name "$fields"
|
||||
+ ;;
|
||||
+*)
|
||||
+ echo "Invalid translation indicator: '$1'" >&2
|
||||
+ exit 1
|
||||
+ ;;
|
||||
+esac
|
312
32on64-sysctl.patch
Normal file
312
32on64-sysctl.patch
Normal file
@ -0,0 +1,312 @@
|
||||
Enable compatibility mode operation for HYPERVISOR_sysctl.
|
||||
|
||||
Index: 2007-01-08/xen/arch/x86/sysctl.c
|
||||
===================================================================
|
||||
--- 2007-01-08.orig/xen/arch/x86/sysctl.c 2007-01-08 15:04:23.000000000 +0100
|
||||
+++ 2007-01-08/xen/arch/x86/sysctl.c 2007-01-08 15:20:32.000000000 +0100
|
||||
@@ -25,10 +25,14 @@
|
||||
#include <asm/hvm/support.h>
|
||||
#include <asm/processor.h>
|
||||
|
||||
-long arch_do_sysctl(
|
||||
+#ifndef COMPAT
|
||||
+typedef long ret_t;
|
||||
+#endif
|
||||
+
|
||||
+ret_t arch_do_sysctl(
|
||||
struct xen_sysctl *sysctl, XEN_GUEST_HANDLE(xen_sysctl_t) u_sysctl)
|
||||
{
|
||||
- long ret = 0;
|
||||
+ ret_t ret = 0;
|
||||
|
||||
switch ( sysctl->cmd )
|
||||
{
|
||||
Index: 2007-01-08/xen/arch/x86/x86_64/Makefile
|
||||
===================================================================
|
||||
--- 2007-01-08.orig/xen/arch/x86/x86_64/Makefile 2007-01-08 15:20:00.000000000 +0100
|
||||
+++ 2007-01-08/xen/arch/x86/x86_64/Makefile 2007-01-08 15:20:32.000000000 +0100
|
||||
@@ -7,6 +7,7 @@ obj-$(CONFIG_COMPAT) += compat.o
|
||||
obj-$(CONFIG_COMPAT) += domain.o
|
||||
obj-$(CONFIG_COMPAT) += physdev.o
|
||||
obj-$(CONFIG_COMPAT) += platform_hypercall.o
|
||||
+obj-$(CONFIG_COMPAT) += sysctl.o
|
||||
|
||||
ifeq ($(CONFIG_COMPAT),y)
|
||||
# extra dependencies
|
||||
@@ -15,5 +16,6 @@ entry.o: compat/entry.S
|
||||
mm.o: compat/mm.c
|
||||
physdev.o: ../physdev.c
|
||||
platform_hypercall.o: ../platform_hypercall.c
|
||||
+sysctl.o: ../sysctl.c
|
||||
traps.o: compat/traps.c
|
||||
endif
|
||||
Index: 2007-01-08/xen/arch/x86/x86_64/compat/entry.S
|
||||
===================================================================
|
||||
--- 2007-01-08.orig/xen/arch/x86/x86_64/compat/entry.S 2007-01-08 15:20:29.000000000 +0100
|
||||
+++ 2007-01-08/xen/arch/x86/x86_64/compat/entry.S 2007-01-08 15:20:32.000000000 +0100
|
||||
@@ -278,7 +278,6 @@ CFIX14:
|
||||
|
||||
.section .rodata, "a", @progbits
|
||||
|
||||
-#define compat_sysctl domain_crash_synchronous
|
||||
#define compat_domctl domain_crash_synchronous
|
||||
|
||||
ENTRY(compat_hypercall_table)
|
||||
Index: 2007-01-08/xen/arch/x86/x86_64/sysctl.c
|
||||
===================================================================
|
||||
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
|
||||
+++ 2007-01-08/xen/arch/x86/x86_64/sysctl.c 2007-01-08 15:20:32.000000000 +0100
|
||||
@@ -0,0 +1,33 @@
|
||||
+/******************************************************************************
|
||||
+ * Arch-specific compatibility sysctl.c
|
||||
+ */
|
||||
+
|
||||
+#include <xen/config.h>
|
||||
+#include <compat/sysctl.h>
|
||||
+
|
||||
+DEFINE_XEN_GUEST_HANDLE(compat_sysctl_t);
|
||||
+#define xen_sysctl compat_sysctl
|
||||
+#define xen_sysctl_t compat_sysctl_t
|
||||
+#define arch_do_sysctl(x, h) arch_compat_sysctl(x, _##h)
|
||||
+
|
||||
+#define xen_sysctl_physinfo compat_sysctl_physinfo
|
||||
+#define xen_sysctl_physinfo_t compat_sysctl_physinfo_t
|
||||
+
|
||||
+#define xen_sysctl_ioport_emulation compat_sysctl_ioport_emulation
|
||||
+#define xen_sysctl_ioport_emulation_t compat_sysctl_ioport_emulation_t
|
||||
+
|
||||
+#define COMPAT
|
||||
+#define _XEN_GUEST_HANDLE(t) XEN_GUEST_HANDLE(t)
|
||||
+typedef int ret_t;
|
||||
+
|
||||
+#include "../sysctl.c"
|
||||
+
|
||||
+/*
|
||||
+ * Local variables:
|
||||
+ * mode: C
|
||||
+ * c-set-style: "BSD"
|
||||
+ * c-basic-offset: 4
|
||||
+ * tab-width: 4
|
||||
+ * indent-tabs-mode: nil
|
||||
+ * End:
|
||||
+ */
|
||||
Index: 2007-01-08/xen/common/compat/Makefile
|
||||
===================================================================
|
||||
--- 2007-01-08.orig/xen/common/compat/Makefile 2007-01-08 15:19:20.000000000 +0100
|
||||
+++ 2007-01-08/xen/common/compat/Makefile 2007-01-08 15:20:32.000000000 +0100
|
||||
@@ -2,8 +2,10 @@ obj-y += domain.o
|
||||
obj-y += kernel.o
|
||||
obj-y += memory.o
|
||||
obj-y += multicall.o
|
||||
+obj-y += sysctl.o
|
||||
obj-y += xlat.o
|
||||
|
||||
# extra dependencies
|
||||
kernel.o: ../kernel.c
|
||||
multicall.o: ../multicall.c
|
||||
+sysctl.o: ../sysctl.c
|
||||
Index: 2007-01-08/xen/common/compat/sysctl.c
|
||||
===================================================================
|
||||
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
|
||||
+++ 2007-01-08/xen/common/compat/sysctl.c 2007-01-08 15:20:32.000000000 +0100
|
||||
@@ -0,0 +1,102 @@
|
||||
+/******************************************************************************
|
||||
+ * compat/sysctl.c
|
||||
+ */
|
||||
+
|
||||
+#include <xen/config.h>
|
||||
+#include <compat/sysctl.h>
|
||||
+#include <xen/domain.h>
|
||||
+#include <xen/guest_access.h>
|
||||
+#include <xen/perfc.h>
|
||||
+#include <xen/trace.h>
|
||||
+
|
||||
+DEFINE_XEN_GUEST_HANDLE(compat_sysctl_t);
|
||||
+#define xen_sysctl compat_sysctl
|
||||
+#define xen_sysctl_t compat_sysctl_t
|
||||
+#define do_sysctl(h) compat_sysctl(_##h)
|
||||
+#define arch_do_sysctl(x, h) arch_compat_sysctl(x, _##h)
|
||||
+
|
||||
+#define xen_sysctl_readconsole compat_sysctl_readconsole
|
||||
+#define xen_sysctl_readconsole_t compat_sysctl_readconsole_t
|
||||
+
|
||||
+static int compat_tb_control(struct compat_sysctl_tbuf_op *cmp_tbc)
|
||||
+{
|
||||
+ struct xen_sysctl_tbuf_op nat_tbc;
|
||||
+ int ret;
|
||||
+
|
||||
+#define XLAT_ctl_cpumap_HNDL_bitmap(_d_, _s_) \
|
||||
+ guest_from_compat_handle((_d_)->bitmap, (_s_)->bitmap)
|
||||
+ XLAT_sysctl_tbuf_op(&nat_tbc, cmp_tbc);
|
||||
+#undef XLAT_ctl_cpumap_HNDL_bitmap
|
||||
+ ret = tb_control(&nat_tbc);
|
||||
+#define XLAT_ctl_cpumap_HNDL_bitmap(_d_, _s_) ((void)0)
|
||||
+ XLAT_sysctl_tbuf_op(cmp_tbc, &nat_tbc);
|
||||
+#undef XLAT_ctl_cpumap_HNDL_bitmap
|
||||
+ return ret;
|
||||
+}
|
||||
+#define xen_sysctl_tbuf_op compat_sysctl_tbuf_op
|
||||
+#define xen_sysctl_tbuf_op_t compat_sysctl_tbuf_op_t
|
||||
+#define tb_control(p) compat_tb_control(p)
|
||||
+
|
||||
+#define xen_sysctl_sched_id compat_sysctl_sched_id
|
||||
+#define xen_sysctl_sched_id_t compat_sysctl_sched_id_t
|
||||
+
|
||||
+static void compat_getdomaininfo(struct domain *d, struct compat_domctl_getdomaininfo *ci)
|
||||
+{
|
||||
+ struct xen_domctl_getdomaininfo ni;
|
||||
+
|
||||
+ getdomaininfo(d, &ni);
|
||||
+ XLAT_domctl_getdomaininfo(ci, &ni);
|
||||
+}
|
||||
+#define xen_sysctl_getdomaininfolist compat_sysctl_getdomaininfolist
|
||||
+#define xen_sysctl_getdomaininfolist_t compat_sysctl_getdomaininfolist_t
|
||||
+#define xen_domctl_getdomaininfo compat_domctl_getdomaininfo
|
||||
+#define xen_domctl_getdomaininfo_t compat_domctl_getdomaininfo_t
|
||||
+#define getdomaininfo(d, i) compat_getdomaininfo(d, i)
|
||||
+
|
||||
+#ifdef PERF_COUNTERS
|
||||
+static int compat_perfc_control(struct compat_sysctl_perfc_op *cmp_pc)
|
||||
+{
|
||||
+ CHECK_sysctl_perfc_desc;
|
||||
+ CHECK_TYPE(sysctl_perfc_val);
|
||||
+ struct xen_sysctl_perfc_op nat_pc;
|
||||
+ int ret;
|
||||
+
|
||||
+#define XLAT_sysctl_perfc_op_HNDL_desc(_d_, _s_) \
|
||||
+ guest_from_compat_handle((_d_)->desc, (_s_)->desc)
|
||||
+#define XLAT_sysctl_perfc_op_HNDL_val(_d_, _s_) \
|
||||
+ guest_from_compat_handle((_d_)->val, (_s_)->val)
|
||||
+ XLAT_sysctl_perfc_op(&nat_pc, cmp_pc);
|
||||
+#undef XLAT_sysctl_perfc_op_HNDL_val
|
||||
+#undef XLAT_sysctl_perfc_op_HNDL_desc
|
||||
+ ret = perfc_control(&nat_pc);
|
||||
+#define XLAT_sysctl_perfc_op_HNDL_desc(_d_, _s_)
|
||||
+#define XLAT_sysctl_perfc_op_HNDL_val(_d_, _s_)
|
||||
+ XLAT_sysctl_perfc_op(cmp_pc, &nat_pc);
|
||||
+#undef XLAT_sysctl_perfc_op_HNDL_val
|
||||
+#undef XLAT_sysctl_perfc_op_HNDL_desc
|
||||
+ return ret;
|
||||
+}
|
||||
+#define xen_sysctl_perfc_op compat_sysctl_perfc_op
|
||||
+#define xen_sysctl_perfc_op_t compat_sysctl_perfc_op_t
|
||||
+#define perfc_control(p) compat_perfc_control(p)
|
||||
+#endif
|
||||
+
|
||||
+#define COMPAT
|
||||
+#define _XEN_GUEST_HANDLE(t) XEN_GUEST_HANDLE(t)
|
||||
+#define _u_sysctl u_sysctl
|
||||
+#undef guest_handle_cast
|
||||
+#define guest_handle_cast compat_handle_cast
|
||||
+#define copy_to_xxx_offset copy_to_compat_offset
|
||||
+typedef int ret_t;
|
||||
+
|
||||
+#include "../sysctl.c"
|
||||
+
|
||||
+/*
|
||||
+ * Local variables:
|
||||
+ * mode: C
|
||||
+ * c-set-style: "BSD"
|
||||
+ * c-basic-offset: 4
|
||||
+ * tab-width: 4
|
||||
+ * indent-tabs-mode: nil
|
||||
+ * End:
|
||||
+ */
|
||||
Index: 2007-01-08/xen/common/sysctl.c
|
||||
===================================================================
|
||||
--- 2007-01-08.orig/xen/common/sysctl.c 2007-01-08 15:04:23.000000000 +0100
|
||||
+++ 2007-01-08/xen/common/sysctl.c 2007-01-08 15:20:32.000000000 +0100
|
||||
@@ -21,14 +21,17 @@
|
||||
#include <asm/current.h>
|
||||
#include <public/sysctl.h>
|
||||
|
||||
-extern long arch_do_sysctl(
|
||||
+#ifndef COMPAT
|
||||
+typedef long ret_t;
|
||||
+#define copy_to_xxx_offset copy_to_guest_offset
|
||||
+#endif
|
||||
+
|
||||
+extern ret_t arch_do_sysctl(
|
||||
struct xen_sysctl *op, XEN_GUEST_HANDLE(xen_sysctl_t) u_sysctl);
|
||||
-extern void getdomaininfo(
|
||||
- struct domain *d, struct xen_domctl_getdomaininfo *info);
|
||||
|
||||
-long do_sysctl(XEN_GUEST_HANDLE(xen_sysctl_t) u_sysctl)
|
||||
+ret_t do_sysctl(XEN_GUEST_HANDLE(xen_sysctl_t) u_sysctl)
|
||||
{
|
||||
- long ret = 0;
|
||||
+ ret_t ret = 0;
|
||||
struct xen_sysctl curop, *op = &curop;
|
||||
static DEFINE_SPINLOCK(sysctl_lock);
|
||||
|
||||
@@ -98,8 +101,8 @@ long do_sysctl(XEN_GUEST_HANDLE(xen_sysc
|
||||
|
||||
put_domain(d);
|
||||
|
||||
- if ( copy_to_guest_offset(op->u.getdomaininfolist.buffer,
|
||||
- num_domains, &info, 1) )
|
||||
+ if ( copy_to_xxx_offset(op->u.getdomaininfolist.buffer,
|
||||
+ num_domains, &info, 1) )
|
||||
{
|
||||
ret = -EFAULT;
|
||||
break;
|
||||
@@ -123,7 +126,6 @@ long do_sysctl(XEN_GUEST_HANDLE(xen_sysc
|
||||
#ifdef PERF_COUNTERS
|
||||
case XEN_SYSCTL_perfc_op:
|
||||
{
|
||||
- extern int perfc_control(xen_sysctl_perfc_op_t *);
|
||||
ret = perfc_control(&op->u.perfc_op);
|
||||
if ( copy_to_guest(u_sysctl, op, 1) )
|
||||
ret = -EFAULT;
|
||||
Index: 2007-01-08/xen/include/xen/domain.h
|
||||
===================================================================
|
||||
--- 2007-01-08.orig/xen/include/xen/domain.h 2007-01-08 15:04:23.000000000 +0100
|
||||
+++ 2007-01-08/xen/include/xen/domain.h 2007-01-08 15:20:32.000000000 +0100
|
||||
@@ -11,6 +11,10 @@ struct vcpu *alloc_idle_vcpu(unsigned in
|
||||
struct domain *alloc_domain(domid_t domid);
|
||||
void free_domain(struct domain *d);
|
||||
|
||||
+struct xen_domctl_getdomaininfo;
|
||||
+void getdomaininfo(
|
||||
+ struct domain *d, struct xen_domctl_getdomaininfo *info);
|
||||
+
|
||||
/*
|
||||
* Arch-specifics.
|
||||
*/
|
||||
Index: 2007-01-08/xen/include/xen/perfc.h
|
||||
===================================================================
|
||||
--- 2007-01-08.orig/xen/include/xen/perfc.h 2007-01-08 15:04:23.000000000 +0100
|
||||
+++ 2007-01-08/xen/include/xen/perfc.h 2007-01-08 15:20:32.000000000 +0100
|
||||
@@ -102,6 +102,9 @@ extern struct perfcounter perfcounters;
|
||||
#else
|
||||
#define perfc_incr_histo(_x,_v,_n) ((void)0)
|
||||
#endif
|
||||
+
|
||||
+struct xen_sysctl_perfc_op;
|
||||
+int perfc_control(struct xen_sysctl_perfc_op *);
|
||||
|
||||
#else /* PERF_COUNTERS */
|
||||
|
||||
Index: 2007-01-08/xen/include/xlat.lst
|
||||
===================================================================
|
||||
--- 2007-01-08.orig/xen/include/xlat.lst 2007-01-08 15:20:29.000000000 +0100
|
||||
+++ 2007-01-08/xen/include/xlat.lst 2007-01-08 15:20:32.000000000 +0100
|
||||
@@ -10,6 +10,8 @@
|
||||
! trap_info arch-@arch@/xen.h
|
||||
! vcpu_guest_context arch-@arch@/xen.h
|
||||
? acm_getdecision acm_ops.h
|
||||
+! ctl_cpumap domctl.h
|
||||
+! domctl_getdomaininfo domctl.h
|
||||
? evtchn_alloc_unbound event_channel.h
|
||||
? evtchn_bind_interdomain event_channel.h
|
||||
? evtchn_bind_ipi event_channel.h
|
||||
@@ -37,6 +39,9 @@
|
||||
! sched_poll sched.h
|
||||
? sched_remote_shutdown sched.h
|
||||
? sched_shutdown sched.h
|
||||
+? sysctl_perfc_desc sysctl.h
|
||||
+! sysctl_perfc_op sysctl.h
|
||||
+! sysctl_tbuf_op sysctl.h
|
||||
! vcpu_runstate_info vcpu.h
|
||||
? xenoprof_init xenoprof.h
|
||||
? xenoprof_passive xenoprof.h
|
142
32on64-trace.patch
Normal file
142
32on64-trace.patch
Normal file
@ -0,0 +1,142 @@
|
||||
Enable compatibility mode operation for trace buffer access.
|
||||
|
||||
Index: 2006-12-11/xen/common/trace.c
|
||||
===================================================================
|
||||
--- 2006-12-11.orig/xen/common/trace.c 2006-12-15 15:20:32.000000000 +0100
|
||||
+++ 2006-12-11/xen/common/trace.c 2006-12-15 15:39:01.000000000 +0100
|
||||
@@ -32,13 +32,29 @@
|
||||
#include <asm/atomic.h>
|
||||
#include <public/sysctl.h>
|
||||
|
||||
+#ifdef CONFIG_COMPAT
|
||||
+#include <compat/trace.h>
|
||||
+#define xen_t_buf t_buf
|
||||
+CHECK_t_buf;
|
||||
+#undef xen_t_buf
|
||||
+#define TB_COMPAT IS_COMPAT(dom0)
|
||||
+#else
|
||||
+#define compat_t_rec t_rec
|
||||
+#define TB_COMPAT 0
|
||||
+#endif
|
||||
+
|
||||
+typedef union {
|
||||
+ struct t_rec *nat;
|
||||
+ struct compat_t_rec *cmp;
|
||||
+} t_rec_u;
|
||||
+
|
||||
/* opt_tbuf_size: trace buffer size (in pages) */
|
||||
static unsigned int opt_tbuf_size = 0;
|
||||
integer_param("tbuf_size", opt_tbuf_size);
|
||||
|
||||
/* Pointers to the meta-data objects for all system trace buffers */
|
||||
static DEFINE_PER_CPU(struct t_buf *, t_bufs);
|
||||
-static DEFINE_PER_CPU(struct t_rec *, t_recs);
|
||||
+static DEFINE_PER_CPU(t_rec_u, t_recs);
|
||||
static int nr_recs;
|
||||
|
||||
/* High water mark for trace buffers; */
|
||||
@@ -87,7 +103,7 @@ static int alloc_trace_bufs(void)
|
||||
nr_pages = num_online_cpus() * opt_tbuf_size;
|
||||
order = get_order_from_pages(nr_pages);
|
||||
nr_recs = (opt_tbuf_size * PAGE_SIZE - sizeof(struct t_buf)) /
|
||||
- sizeof(struct t_rec);
|
||||
+ (!TB_COMPAT ? sizeof(struct t_rec) : sizeof(struct compat_t_rec));
|
||||
|
||||
if ( (rawbuf = alloc_xenheap_pages(order)) == NULL )
|
||||
{
|
||||
@@ -106,7 +122,7 @@ static int alloc_trace_bufs(void)
|
||||
buf = per_cpu(t_bufs, i) = (struct t_buf *)
|
||||
&rawbuf[i*opt_tbuf_size*PAGE_SIZE];
|
||||
buf->cons = buf->prod = 0;
|
||||
- per_cpu(t_recs, i) = (struct t_rec *)(buf + 1);
|
||||
+ per_cpu(t_recs, i).nat = (struct t_rec *)(buf + 1);
|
||||
}
|
||||
|
||||
t_buf_highwater = nr_recs >> 1; /* 50% high water */
|
||||
@@ -232,7 +248,7 @@ void trace(u32 event, unsigned long d1,
|
||||
unsigned long d3, unsigned long d4, unsigned long d5)
|
||||
{
|
||||
struct t_buf *buf;
|
||||
- struct t_rec *rec;
|
||||
+ t_rec_u rec;
|
||||
unsigned long flags;
|
||||
|
||||
BUG_ON(!tb_init_done);
|
||||
@@ -269,25 +285,51 @@ void trace(u32 event, unsigned long d1,
|
||||
|
||||
if ( unlikely(this_cpu(lost_records) != 0) )
|
||||
{
|
||||
- rec = &this_cpu(t_recs)[buf->prod % nr_recs];
|
||||
- memset(rec, 0, sizeof(*rec));
|
||||
- rec->cycles = (u64)get_cycles();
|
||||
- rec->event = TRC_LOST_RECORDS;
|
||||
- rec->data[0] = this_cpu(lost_records);
|
||||
- this_cpu(lost_records) = 0;
|
||||
+ if ( !TB_COMPAT )
|
||||
+ {
|
||||
+ rec.nat = &this_cpu(t_recs).nat[buf->prod % nr_recs];
|
||||
+ memset(rec.nat, 0, sizeof(*rec.nat));
|
||||
+ rec.nat->cycles = (u64)get_cycles();
|
||||
+ rec.nat->event = TRC_LOST_RECORDS;
|
||||
+ rec.nat->data[0] = this_cpu(lost_records);
|
||||
+ this_cpu(lost_records) = 0;
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ rec.cmp = &this_cpu(t_recs).cmp[buf->prod % nr_recs];
|
||||
+ memset(rec.cmp, 0, sizeof(*rec.cmp));
|
||||
+ rec.cmp->cycles = (u64)get_cycles();
|
||||
+ rec.cmp->event = TRC_LOST_RECORDS;
|
||||
+ rec.cmp->data[0] = this_cpu(lost_records);
|
||||
+ this_cpu(lost_records) = 0;
|
||||
+ }
|
||||
|
||||
wmb();
|
||||
buf->prod++;
|
||||
}
|
||||
|
||||
- rec = &this_cpu(t_recs)[buf->prod % nr_recs];
|
||||
- rec->cycles = (u64)get_cycles();
|
||||
- rec->event = event;
|
||||
- rec->data[0] = d1;
|
||||
- rec->data[1] = d2;
|
||||
- rec->data[2] = d3;
|
||||
- rec->data[3] = d4;
|
||||
- rec->data[4] = d5;
|
||||
+ if ( !TB_COMPAT )
|
||||
+ {
|
||||
+ rec.nat = &this_cpu(t_recs).nat[buf->prod % nr_recs];
|
||||
+ rec.nat->cycles = (u64)get_cycles();
|
||||
+ rec.nat->event = event;
|
||||
+ rec.nat->data[0] = d1;
|
||||
+ rec.nat->data[1] = d2;
|
||||
+ rec.nat->data[2] = d3;
|
||||
+ rec.nat->data[3] = d4;
|
||||
+ rec.nat->data[4] = d5;
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ rec.cmp = &this_cpu(t_recs).cmp[buf->prod % nr_recs];
|
||||
+ rec.cmp->cycles = (u64)get_cycles();
|
||||
+ rec.cmp->event = event;
|
||||
+ rec.cmp->data[0] = d1;
|
||||
+ rec.cmp->data[1] = d2;
|
||||
+ rec.cmp->data[2] = d3;
|
||||
+ rec.cmp->data[3] = d4;
|
||||
+ rec.cmp->data[4] = d5;
|
||||
+ }
|
||||
|
||||
wmb();
|
||||
buf->prod++;
|
||||
Index: 2006-12-11/xen/include/xlat.lst
|
||||
===================================================================
|
||||
--- 2006-12-11.orig/xen/include/xlat.lst 2006-12-15 15:37:45.000000000 +0100
|
||||
+++ 2006-12-11/xen/include/xlat.lst 2006-12-15 15:39:01.000000000 +0100
|
||||
@@ -44,6 +44,7 @@
|
||||
? sysctl_perfc_desc sysctl.h
|
||||
! sysctl_perfc_op sysctl.h
|
||||
! sysctl_tbuf_op sysctl.h
|
||||
+? t_buf trace.h
|
||||
! vcpu_runstate_info vcpu.h
|
||||
? xenoprof_init xenoprof.h
|
||||
? xenoprof_passive xenoprof.h
|
379
32on64-vcpuop.patch
Normal file
379
32on64-vcpuop.patch
Normal file
@ -0,0 +1,379 @@
|
||||
Enable compatibility mode operation for HYPERVISOR_vcpu_op.
|
||||
|
||||
Index: 2007-01-08/xen/arch/x86/domain.c
|
||||
===================================================================
|
||||
--- 2007-01-08.orig/xen/arch/x86/domain.c 2007-01-08 15:07:36.000000000 +0100
|
||||
+++ 2007-01-08/xen/arch/x86/domain.c 2007-01-08 15:07:40.000000000 +0100
|
||||
@@ -40,6 +40,9 @@
|
||||
#include <asm/hvm/hvm.h>
|
||||
#include <asm/hvm/support.h>
|
||||
#include <asm/msr.h>
|
||||
+#ifdef CONFIG_COMPAT
|
||||
+#include <compat/vcpu.h>
|
||||
+#endif
|
||||
|
||||
DEFINE_PER_CPU(struct vcpu *, curr_vcpu);
|
||||
|
||||
@@ -572,16 +575,16 @@ arch_do_vcpu_op(
|
||||
break;
|
||||
|
||||
rc = 0;
|
||||
- v->runstate_guest = area.addr.h;
|
||||
+ runstate_guest(v) = area.addr.h;
|
||||
|
||||
if ( v == current )
|
||||
{
|
||||
- __copy_to_guest(v->runstate_guest, &v->runstate, 1);
|
||||
+ __copy_to_guest(runstate_guest(v), &v->runstate, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
vcpu_runstate_get(v, &runstate);
|
||||
- __copy_to_guest(v->runstate_guest, &runstate, 1);
|
||||
+ __copy_to_guest(runstate_guest(v), &runstate, 1);
|
||||
}
|
||||
|
||||
break;
|
||||
@@ -980,8 +983,20 @@ void context_switch(struct vcpu *prev, s
|
||||
context_saved(prev);
|
||||
|
||||
/* Update per-VCPU guest runstate shared memory area (if registered). */
|
||||
- if ( !guest_handle_is_null(next->runstate_guest) )
|
||||
- __copy_to_guest(next->runstate_guest, &next->runstate, 1);
|
||||
+ if ( !guest_handle_is_null(runstate_guest(next)) )
|
||||
+ {
|
||||
+ if ( !IS_COMPAT(next->domain) )
|
||||
+ __copy_to_guest(runstate_guest(next), &next->runstate, 1);
|
||||
+#ifdef CONFIG_COMPAT
|
||||
+ else
|
||||
+ {
|
||||
+ struct compat_vcpu_runstate_info info;
|
||||
+
|
||||
+ XLAT_vcpu_runstate_info(&info, &next->runstate);
|
||||
+ __copy_to_guest(next->runstate_guest.compat, &info, 1);
|
||||
+ }
|
||||
+#endif
|
||||
+ }
|
||||
|
||||
schedule_tail(next);
|
||||
BUG();
|
||||
Index: 2007-01-08/xen/arch/x86/x86_64/Makefile
|
||||
===================================================================
|
||||
--- 2007-01-08.orig/xen/arch/x86/x86_64/Makefile 2007-01-08 15:07:38.000000000 +0100
|
||||
+++ 2007-01-08/xen/arch/x86/x86_64/Makefile 2007-01-08 15:07:40.000000000 +0100
|
||||
@@ -4,6 +4,7 @@ obj-y += mm.o
|
||||
obj-y += traps.o
|
||||
|
||||
obj-$(CONFIG_COMPAT) += compat.o
|
||||
+obj-$(CONFIG_COMPAT) += domain.o
|
||||
obj-$(CONFIG_COMPAT) += physdev.o
|
||||
|
||||
ifeq ($(CONFIG_COMPAT),y)
|
||||
Index: 2007-01-08/xen/arch/x86/x86_64/compat/entry.S
|
||||
===================================================================
|
||||
--- 2007-01-08.orig/xen/arch/x86/x86_64/compat/entry.S 2007-01-08 15:07:38.000000000 +0100
|
||||
+++ 2007-01-08/xen/arch/x86/x86_64/compat/entry.S 2007-01-08 15:07:40.000000000 +0100
|
||||
@@ -284,7 +284,6 @@ CFIX14:
|
||||
#define compat_multicall domain_crash_synchronous
|
||||
#define compat_set_timer_op domain_crash_synchronous
|
||||
#define compat_grant_table_op domain_crash_synchronous
|
||||
-#define compat_vcpu_op domain_crash_synchronous
|
||||
#define compat_acm_op domain_crash_synchronous
|
||||
#define compat_arch_sched_op domain_crash_synchronous
|
||||
#define compat_xenoprof_op domain_crash_synchronous
|
||||
Index: 2007-01-08/xen/arch/x86/x86_64/domain.c
|
||||
===================================================================
|
||||
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
|
||||
+++ 2007-01-08/xen/arch/x86/x86_64/domain.c 2007-01-08 15:07:40.000000000 +0100
|
||||
@@ -0,0 +1,68 @@
|
||||
+/******************************************************************************
|
||||
+ * arch/x86/x86_64/domain.c
|
||||
+ *
|
||||
+ */
|
||||
+
|
||||
+#include <xen/config.h>
|
||||
+#include <xen/types.h>
|
||||
+#include <xen/guest_access.h>
|
||||
+#include <asm/hypercall.h>
|
||||
+#include <compat/vcpu.h>
|
||||
+
|
||||
+int
|
||||
+arch_compat_vcpu_op(
|
||||
+ int cmd, struct vcpu *v, XEN_GUEST_HANDLE(void) arg)
|
||||
+{
|
||||
+ long rc = 0;
|
||||
+
|
||||
+ switch ( cmd )
|
||||
+ {
|
||||
+ case VCPUOP_register_runstate_memory_area:
|
||||
+ {
|
||||
+ struct compat_vcpu_register_runstate_memory_area area;
|
||||
+ struct compat_vcpu_runstate_info info;
|
||||
+
|
||||
+ rc = -EFAULT;
|
||||
+ if ( copy_from_guest(&area, arg, 1) )
|
||||
+ break;
|
||||
+
|
||||
+ if ( area.addr.h.c != area.addr.p ||
|
||||
+ !compat_handle_okay(area.addr.h, 1) )
|
||||
+ break;
|
||||
+
|
||||
+ rc = 0;
|
||||
+ guest_from_compat_handle(v->runstate_guest.compat, area.addr.h);
|
||||
+
|
||||
+ if ( v == current )
|
||||
+ {
|
||||
+ XLAT_vcpu_runstate_info(&info, &v->runstate);
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ struct vcpu_runstate_info runstate;
|
||||
+
|
||||
+ vcpu_runstate_get(v, &runstate);
|
||||
+ XLAT_vcpu_runstate_info(&info, &v->runstate);
|
||||
+ }
|
||||
+ __copy_to_guest(v->runstate_guest.compat, &info, 1);
|
||||
+
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ default:
|
||||
+ rc = -ENOSYS;
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ return rc;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * Local variables:
|
||||
+ * mode: C
|
||||
+ * c-set-style: "BSD"
|
||||
+ * c-basic-offset: 4
|
||||
+ * tab-width: 4
|
||||
+ * indent-tabs-mode: nil
|
||||
+ * End:
|
||||
+ */
|
||||
Index: 2007-01-08/xen/common/compat/Makefile
|
||||
===================================================================
|
||||
--- 2007-01-08.orig/xen/common/compat/Makefile 2007-01-08 15:07:36.000000000 +0100
|
||||
+++ 2007-01-08/xen/common/compat/Makefile 2007-01-08 15:07:40.000000000 +0100
|
||||
@@ -1,3 +1,4 @@
|
||||
+obj-y += domain.o
|
||||
obj-y += kernel.o
|
||||
obj-y += memory.o
|
||||
obj-y += xlat.o
|
||||
Index: 2007-01-08/xen/common/compat/domain.c
|
||||
===================================================================
|
||||
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
|
||||
+++ 2007-01-08/xen/common/compat/domain.c 2007-01-08 15:07:40.000000000 +0100
|
||||
@@ -0,0 +1,102 @@
|
||||
+/******************************************************************************
|
||||
+ * domain.c
|
||||
+ *
|
||||
+ */
|
||||
+
|
||||
+#include <xen/config.h>
|
||||
+#include <xen/lib.h>
|
||||
+#include <xen/sched.h>
|
||||
+#include <xen/domain.h>
|
||||
+#include <xen/guest_access.h>
|
||||
+#include <xen/hypercall.h>
|
||||
+#include <compat/vcpu.h>
|
||||
+
|
||||
+int compat_vcpu_op(int cmd, int vcpuid, XEN_GUEST_HANDLE(void) arg)
|
||||
+{
|
||||
+ struct domain *d = current->domain;
|
||||
+ struct vcpu *v;
|
||||
+ long rc = 0;
|
||||
+
|
||||
+ if ( (vcpuid < 0) || (vcpuid >= MAX_VIRT_CPUS) )
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ if ( (v = d->vcpu[vcpuid]) == NULL )
|
||||
+ return -ENOENT;
|
||||
+
|
||||
+ switch ( cmd )
|
||||
+ {
|
||||
+ case VCPUOP_initialise:
|
||||
+ {
|
||||
+ struct compat_vcpu_guest_context *cmp_ctxt;
|
||||
+ struct vcpu_guest_context *nat_ctxt;
|
||||
+
|
||||
+ if ( (cmp_ctxt = xmalloc(struct compat_vcpu_guest_context)) == NULL )
|
||||
+ {
|
||||
+ rc = -ENOMEM;
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ if ( copy_from_guest(cmp_ctxt, arg, 1) )
|
||||
+ {
|
||||
+ xfree(cmp_ctxt);
|
||||
+ rc = -EFAULT;
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ if ( (nat_ctxt = xmalloc(struct vcpu_guest_context)) == NULL )
|
||||
+ {
|
||||
+ rc = -ENOMEM;
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ memset(nat_ctxt, 0, sizeof(*nat_ctxt));
|
||||
+ XLAT_vcpu_guest_context(nat_ctxt, cmp_ctxt);
|
||||
+ xfree(cmp_ctxt);
|
||||
+
|
||||
+ LOCK_BIGLOCK(d);
|
||||
+ rc = -EEXIST;
|
||||
+ if ( !test_bit(_VCPUF_initialised, &v->vcpu_flags) )
|
||||
+ rc = boot_vcpu(d, vcpuid, nat_ctxt);
|
||||
+ UNLOCK_BIGLOCK(d);
|
||||
+
|
||||
+ xfree(nat_ctxt);
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ case VCPUOP_up:
|
||||
+ case VCPUOP_down:
|
||||
+ case VCPUOP_is_up:
|
||||
+ rc = do_vcpu_op(cmd, vcpuid, arg);
|
||||
+ break;
|
||||
+
|
||||
+ case VCPUOP_get_runstate_info:
|
||||
+ {
|
||||
+ union {
|
||||
+ struct vcpu_runstate_info nat;
|
||||
+ struct compat_vcpu_runstate_info cmp;
|
||||
+ } runstate;
|
||||
+
|
||||
+ vcpu_runstate_get(v, &runstate.nat);
|
||||
+ xlat_vcpu_runstate_info(&runstate.nat);
|
||||
+ if ( copy_to_guest(arg, &runstate.cmp, 1) )
|
||||
+ rc = -EFAULT;
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ default:
|
||||
+ rc = arch_compat_vcpu_op(cmd, v, arg);
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ return rc;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * Local variables:
|
||||
+ * mode: C
|
||||
+ * c-set-style: "BSD"
|
||||
+ * c-basic-offset: 4
|
||||
+ * tab-width: 4
|
||||
+ * indent-tabs-mode: nil
|
||||
+ * End:
|
||||
+ */
|
||||
Index: 2007-01-08/xen/common/compat/xlat.c
|
||||
===================================================================
|
||||
--- 2007-01-08.orig/xen/common/compat/xlat.c 2007-01-08 15:07:38.000000000 +0100
|
||||
+++ 2007-01-08/xen/common/compat/xlat.c 2007-01-08 15:07:40.000000000 +0100
|
||||
@@ -6,6 +6,7 @@
|
||||
#include <xen/lib.h>
|
||||
#include <compat/xen.h>
|
||||
#include <compat/event_channel.h>
|
||||
+#include <compat/vcpu.h>
|
||||
|
||||
/* In-place translation functons: */
|
||||
void xlat_start_info(struct start_info *native,
|
||||
@@ -17,6 +18,14 @@ void xlat_start_info(struct start_info *
|
||||
XLAT_start_info(compat, native);
|
||||
}
|
||||
|
||||
+void xlat_vcpu_runstate_info(struct vcpu_runstate_info *native)
|
||||
+{
|
||||
+ struct compat_vcpu_runstate_info *compat = (void *)native;
|
||||
+
|
||||
+ BUILD_BUG_ON(sizeof(*native) < sizeof(*compat));
|
||||
+ XLAT_vcpu_runstate_info(compat, native);
|
||||
+}
|
||||
+
|
||||
#define xen_dom0_vga_console_info dom0_vga_console_info
|
||||
CHECK_dom0_vga_console_info;
|
||||
#undef dom0_vga_console_info
|
||||
Index: 2007-01-08/xen/include/asm-x86/hypercall.h
|
||||
===================================================================
|
||||
--- 2007-01-08.orig/xen/include/asm-x86/hypercall.h 2007-01-08 15:07:38.000000000 +0100
|
||||
+++ 2007-01-08/xen/include/asm-x86/hypercall.h 2007-01-08 15:07:40.000000000 +0100
|
||||
@@ -130,6 +130,10 @@ compat_physdev_op(
|
||||
int cmd,
|
||||
XEN_GUEST_HANDLE(void) arg);
|
||||
|
||||
+extern int
|
||||
+arch_compat_vcpu_op(
|
||||
+ int cmd, struct vcpu *v, XEN_GUEST_HANDLE(void) arg);
|
||||
+
|
||||
#endif
|
||||
|
||||
#endif /* __ASM_X86_HYPERCALL_H__ */
|
||||
Index: 2007-01-08/xen/include/xen/compat.h
|
||||
===================================================================
|
||||
--- 2007-01-08.orig/xen/include/xen/compat.h 2007-01-08 15:07:36.000000000 +0100
|
||||
+++ 2007-01-08/xen/include/xen/compat.h 2007-01-08 15:07:40.000000000 +0100
|
||||
@@ -163,6 +163,8 @@ int hypercall_xlat_continuation(unsigned
|
||||
/* In-place translation functons: */
|
||||
struct start_info;
|
||||
void xlat_start_info(struct start_info *, enum XLAT_start_info_console);
|
||||
+struct vcpu_runstate_info;
|
||||
+void xlat_vcpu_runstate_info(struct vcpu_runstate_info *);
|
||||
|
||||
#define BITS_PER_GUEST_LONG(d) (!IS_COMPAT(d) ? BITS_PER_LONG : COMPAT_BITS_PER_LONG)
|
||||
|
||||
Index: 2007-01-08/xen/include/xen/sched.h
|
||||
===================================================================
|
||||
--- 2007-01-08.orig/xen/include/xen/sched.h 2007-01-08 15:07:28.000000000 +0100
|
||||
+++ 2007-01-08/xen/include/xen/sched.h 2007-01-08 15:07:40.000000000 +0100
|
||||
@@ -18,6 +18,11 @@
|
||||
#include <xen/xenoprof.h>
|
||||
#include <xen/irq.h>
|
||||
|
||||
+#ifdef CONFIG_COMPAT
|
||||
+#include <compat/vcpu.h>
|
||||
+DEFINE_XEN_GUEST_HANDLE(vcpu_runstate_info_compat_t);
|
||||
+#endif
|
||||
+
|
||||
extern unsigned long volatile jiffies;
|
||||
extern rwlock_t domlist_lock;
|
||||
|
||||
@@ -82,7 +87,16 @@ struct vcpu
|
||||
void *sched_priv; /* scheduler-specific data */
|
||||
|
||||
struct vcpu_runstate_info runstate;
|
||||
+#ifndef CONFIG_COMPAT
|
||||
+# define runstate_guest(v) ((v)->runstate_guest)
|
||||
XEN_GUEST_HANDLE(vcpu_runstate_info_t) runstate_guest; /* guest address */
|
||||
+#else
|
||||
+# define runstate_guest(v) ((v)->runstate_guest.native)
|
||||
+ union {
|
||||
+ XEN_GUEST_HANDLE(vcpu_runstate_info_t) native;
|
||||
+ XEN_GUEST_HANDLE(vcpu_runstate_info_compat_t) compat;
|
||||
+ } runstate_guest; /* guest address */
|
||||
+#endif
|
||||
|
||||
unsigned long vcpu_flags;
|
||||
|
||||
Index: 2007-01-08/xen/include/xlat.lst
|
||||
===================================================================
|
||||
--- 2007-01-08.orig/xen/include/xlat.lst 2007-01-08 15:07:38.000000000 +0100
|
||||
+++ 2007-01-08/xen/include/xlat.lst 2007-01-08 15:08:28.000000000 +0100
|
||||
@@ -6,6 +6,9 @@
|
||||
! mmuext_op xen.h
|
||||
! start_info xen.h
|
||||
? vcpu_time_info xen.h
|
||||
+! cpu_user_regs arch-@arch@/xen-@subarch@.h
|
||||
+! trap_info arch-@arch@/xen.h
|
||||
+! vcpu_guest_context arch-@arch@/xen.h
|
||||
? evtchn_alloc_unbound event_channel.h
|
||||
? evtchn_bind_interdomain event_channel.h
|
||||
? evtchn_bind_ipi event_channel.h
|
||||
@@ -23,3 +26,4 @@
|
||||
! memory_map memory.h
|
||||
! memory_reservation memory.h
|
||||
! translate_gpfn_list memory.h
|
||||
+! vcpu_runstate_info vcpu.h
|
326
32on64-xenoprof.patch
Normal file
326
32on64-xenoprof.patch
Normal file
@ -0,0 +1,326 @@
|
||||
Enable compatibility mode operation for HYPERVISOR_xenoprof_op.
|
||||
|
||||
Index: 2006-12-18/xen/arch/x86/x86_64/compat/entry.S
|
||||
===================================================================
|
||||
--- 2006-12-18.orig/xen/arch/x86/x86_64/compat/entry.S 2006-12-18 09:50:05.000000000 +0100
|
||||
+++ 2006-12-18/xen/arch/x86/x86_64/compat/entry.S 2006-12-18 09:50:08.000000000 +0100
|
||||
@@ -278,7 +278,6 @@ CFIX14:
|
||||
|
||||
.section .rodata, "a", @progbits
|
||||
|
||||
-#define compat_xenoprof_op domain_crash_synchronous
|
||||
#define compat_sysctl domain_crash_synchronous
|
||||
#define compat_domctl domain_crash_synchronous
|
||||
|
||||
Index: 2006-12-18/xen/include/public/xenoprof.h
|
||||
===================================================================
|
||||
--- 2006-12-18.orig/xen/include/public/xenoprof.h 2006-12-15 16:33:59.000000000 +0100
|
||||
+++ 2006-12-18/xen/include/public/xenoprof.h 2006-12-18 09:50:08.000000000 +0100
|
||||
@@ -74,8 +74,10 @@ struct xenoprof_buf {
|
||||
uint64_t lost_samples;
|
||||
struct event_log event_log[1];
|
||||
};
|
||||
+#ifndef __XEN__
|
||||
typedef struct xenoprof_buf xenoprof_buf_t;
|
||||
DEFINE_XEN_GUEST_HANDLE(xenoprof_buf_t);
|
||||
+#endif
|
||||
|
||||
struct xenoprof_init {
|
||||
int32_t num_events;
|
||||
Index: 2006-12-18/xen/include/xen/xenoprof.h
|
||||
===================================================================
|
||||
--- 2006-12-18.orig/xen/include/xen/xenoprof.h 2006-12-13 11:15:57.000000000 +0100
|
||||
+++ 2006-12-18/xen/include/xen/xenoprof.h 2006-12-18 09:50:08.000000000 +0100
|
||||
@@ -10,6 +10,7 @@
|
||||
#ifndef __XEN_XENOPROF_H__
|
||||
#define __XEN_XENOPROF_H__
|
||||
|
||||
+#include <xen/config.h>
|
||||
#include <public/xenoprof.h>
|
||||
#include <asm/xenoprof.h>
|
||||
|
||||
@@ -22,9 +23,19 @@
|
||||
#define XENOPROF_READY 2
|
||||
#define XENOPROF_PROFILING 3
|
||||
|
||||
+#ifndef CONFIG_COMPAT
|
||||
+typedef struct xenoprof_buf xenoprof_buf_t;
|
||||
+#else
|
||||
+#include <compat/xenoprof.h>
|
||||
+typedef union {
|
||||
+ struct xenoprof_buf native;
|
||||
+ struct compat_oprof_buf compat;
|
||||
+} xenoprof_buf_t;
|
||||
+#endif
|
||||
+
|
||||
struct xenoprof_vcpu {
|
||||
int event_size;
|
||||
- struct xenoprof_buf *buffer;
|
||||
+ xenoprof_buf_t *buffer;
|
||||
};
|
||||
|
||||
struct xenoprof {
|
||||
@@ -35,9 +46,22 @@ struct xenoprof {
|
||||
int domain_type;
|
||||
int domain_ready;
|
||||
int is_primary;
|
||||
+#ifdef CONFIG_COMPAT
|
||||
+ int is_compat;
|
||||
+#endif
|
||||
struct xenoprof_vcpu vcpu [MAX_VIRT_CPUS];
|
||||
};
|
||||
|
||||
+#ifndef CONFIG_COMPAT
|
||||
+#define XENOPROF_COMPAT(x) 0
|
||||
+#define xenoprof_buf(d, b, field) ((b)->field)
|
||||
+#else
|
||||
+#define XENOPROF_COMPAT(x) ((x)->is_compat)
|
||||
+#define xenoprof_buf(d, b, field) (*(!(d)->xenoprof->is_compat ? \
|
||||
+ &(b)->native.field : \
|
||||
+ &(b)->compat.field))
|
||||
+#endif
|
||||
+
|
||||
struct domain;
|
||||
void free_xenoprof_pages(struct domain *d);
|
||||
|
||||
Index: 2006-12-18/xen/include/xlat.lst
|
||||
===================================================================
|
||||
--- 2006-12-18.orig/xen/include/xlat.lst 2006-12-18 09:50:05.000000000 +0100
|
||||
+++ 2006-12-18/xen/include/xlat.lst 2006-12-18 09:50:08.000000000 +0100
|
||||
@@ -38,3 +38,5 @@
|
||||
? sched_remote_shutdown sched.h
|
||||
? sched_shutdown sched.h
|
||||
! vcpu_runstate_info vcpu.h
|
||||
+? xenoprof_init xenoprof.h
|
||||
+? xenoprof_passive xenoprof.h
|
||||
Index: 2006-12-18/xen/common/Makefile
|
||||
===================================================================
|
||||
--- 2006-12-18.orig/xen/common/Makefile 2006-12-18 09:50:05.000000000 +0100
|
||||
+++ 2006-12-18/xen/common/Makefile 2006-12-18 09:50:08.000000000 +0100
|
||||
@@ -45,4 +45,5 @@ ifeq ($(CONFIG_COMPAT),y)
|
||||
acm_ops.o: compat/acm_ops.c
|
||||
grant_table.o: compat/grant_table.c
|
||||
schedule.o: compat/schedule.c
|
||||
+xenoprof.o: compat/xenoprof.c
|
||||
endif
|
||||
Index: 2006-12-18/xen/common/compat/xenoprof.c
|
||||
===================================================================
|
||||
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
|
||||
+++ 2006-12-18/xen/common/compat/xenoprof.c 2006-12-18 09:50:08.000000000 +0100
|
||||
@@ -0,0 +1,40 @@
|
||||
+/*
|
||||
+ * compat/xenoprof.c
|
||||
+ */
|
||||
+
|
||||
+#include <compat/xenoprof.h>
|
||||
+
|
||||
+#define COMPAT
|
||||
+
|
||||
+#define do_xenoprof_op compat_xenoprof_op
|
||||
+
|
||||
+#define xen_oprof_init xenoprof_init
|
||||
+CHECK_oprof_init;
|
||||
+#undef xen_oprof_init
|
||||
+
|
||||
+#define xenoprof_get_buffer compat_oprof_get_buffer
|
||||
+#define xenoprof_op_get_buffer compat_oprof_op_get_buffer
|
||||
+
|
||||
+#define xen_domid_t domid_t
|
||||
+#define compat_domid_t domid_compat_t
|
||||
+CHECK_TYPE(domid);
|
||||
+#undef compat_domid_t
|
||||
+#undef xen_domid_t
|
||||
+
|
||||
+#define xen_oprof_passive xenoprof_passive
|
||||
+CHECK_oprof_passive;
|
||||
+#undef xen_oprof_passive
|
||||
+
|
||||
+#define xenoprof_counter compat_oprof_counter
|
||||
+
|
||||
+#include "../xenoprof.c"
|
||||
+
|
||||
+/*
|
||||
+ * Local variables:
|
||||
+ * mode: C
|
||||
+ * c-set-style: "BSD"
|
||||
+ * c-basic-offset: 4
|
||||
+ * tab-width: 4
|
||||
+ * indent-tabs-mode: nil
|
||||
+ * End:
|
||||
+ */
|
||||
Index: 2006-12-18/xen/common/xenoprof.c
|
||||
===================================================================
|
||||
--- 2006-12-18.orig/xen/common/xenoprof.c 2006-12-13 11:15:54.000000000 +0100
|
||||
+++ 2006-12-18/xen/common/xenoprof.c 2006-12-18 09:50:08.000000000 +0100
|
||||
@@ -9,6 +9,7 @@
|
||||
* VA Linux Systems Japan K.K.
|
||||
*/
|
||||
|
||||
+#ifndef COMPAT
|
||||
#include <xen/guest_access.h>
|
||||
#include <xen/sched.h>
|
||||
#include <public/xenoprof.h>
|
||||
@@ -72,7 +73,7 @@ static void xenoprof_reset_stat(void)
|
||||
static void xenoprof_reset_buf(struct domain *d)
|
||||
{
|
||||
int j;
|
||||
- struct xenoprof_buf *buf;
|
||||
+ xenoprof_buf_t *buf;
|
||||
|
||||
if ( d->xenoprof == NULL )
|
||||
{
|
||||
@@ -86,8 +87,8 @@ static void xenoprof_reset_buf(struct do
|
||||
buf = d->xenoprof->vcpu[j].buffer;
|
||||
if ( buf != NULL )
|
||||
{
|
||||
- buf->event_head = 0;
|
||||
- buf->event_tail = 0;
|
||||
+ xenoprof_buf(d, buf, event_head) = 0;
|
||||
+ xenoprof_buf(d, buf, event_tail) = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -166,15 +167,24 @@ static int alloc_xenoprof_struct(
|
||||
for_each_vcpu ( d, v )
|
||||
nvcpu++;
|
||||
|
||||
+ bufsize = sizeof(struct xenoprof_buf);
|
||||
+ i = sizeof(struct event_log);
|
||||
+#ifdef CONFIG_COMPAT
|
||||
+ d->xenoprof->is_compat = IS_COMPAT(is_passive ? dom0 : d);
|
||||
+ if ( XENOPROF_COMPAT(d->xenoprof) )
|
||||
+ {
|
||||
+ bufsize = sizeof(struct compat_oprof_buf);
|
||||
+ i = sizeof(struct compat_event_log);
|
||||
+ }
|
||||
+#endif
|
||||
+
|
||||
/* reduce max_samples if necessary to limit pages allocated */
|
||||
max_bufsize = (MAX_OPROF_SHARED_PAGES * PAGE_SIZE) / nvcpu;
|
||||
- max_max_samples = ( (max_bufsize - sizeof(struct xenoprof_buf)) /
|
||||
- sizeof(struct event_log) ) + 1;
|
||||
+ max_max_samples = ( (max_bufsize - bufsize) / i ) + 1;
|
||||
if ( (unsigned)max_samples > max_max_samples )
|
||||
max_samples = max_max_samples;
|
||||
|
||||
- bufsize = sizeof(struct xenoprof_buf) +
|
||||
- (max_samples - 1) * sizeof(struct event_log);
|
||||
+ bufsize += (max_samples - 1) * i;
|
||||
npages = (nvcpu * bufsize - 1) / PAGE_SIZE + 1;
|
||||
|
||||
d->xenoprof->rawbuf = alloc_xenheap_pages(get_order_from_pages(npages));
|
||||
@@ -195,11 +205,12 @@ static int alloc_xenoprof_struct(
|
||||
i = 0;
|
||||
for_each_vcpu ( d, v )
|
||||
{
|
||||
+ xenoprof_buf_t *buf = (xenoprof_buf_t *)&d->xenoprof->rawbuf[i * bufsize];
|
||||
+
|
||||
d->xenoprof->vcpu[v->vcpu_id].event_size = max_samples;
|
||||
- d->xenoprof->vcpu[v->vcpu_id].buffer =
|
||||
- (struct xenoprof_buf *)&d->xenoprof->rawbuf[i * bufsize];
|
||||
- d->xenoprof->vcpu[v->vcpu_id].buffer->event_size = max_samples;
|
||||
- d->xenoprof->vcpu[v->vcpu_id].buffer->vcpu_id = v->vcpu_id;
|
||||
+ d->xenoprof->vcpu[v->vcpu_id].buffer = buf;
|
||||
+ xenoprof_buf(d, buf, event_size) = max_samples;
|
||||
+ xenoprof_buf(d, buf, vcpu_id) = v->vcpu_id;
|
||||
|
||||
i++;
|
||||
/* in the unlikely case that the number of active vcpus changes */
|
||||
@@ -406,8 +417,9 @@ static int add_passive_list(XEN_GUEST_HA
|
||||
void xenoprof_log_event(
|
||||
struct vcpu *vcpu, unsigned long eip, int mode, int event)
|
||||
{
|
||||
+ struct domain *d = vcpu->domain;
|
||||
struct xenoprof_vcpu *v;
|
||||
- struct xenoprof_buf *buf;
|
||||
+ xenoprof_buf_t *buf;
|
||||
int head;
|
||||
int tail;
|
||||
int size;
|
||||
@@ -417,13 +429,13 @@ void xenoprof_log_event(
|
||||
|
||||
/* ignore samples of un-monitored domains */
|
||||
/* Count samples in idle separate from other unmonitored domains */
|
||||
- if ( !is_profiled(vcpu->domain) )
|
||||
+ if ( !is_profiled(d) )
|
||||
{
|
||||
others_samples++;
|
||||
return;
|
||||
}
|
||||
|
||||
- v = &vcpu->domain->xenoprof->vcpu[vcpu->vcpu_id];
|
||||
+ v = &d->xenoprof->vcpu[vcpu->vcpu_id];
|
||||
|
||||
/* Sanity check. Should never happen */
|
||||
if ( v->buffer == NULL )
|
||||
@@ -432,10 +444,10 @@ void xenoprof_log_event(
|
||||
return;
|
||||
}
|
||||
|
||||
- buf = vcpu->domain->xenoprof->vcpu[vcpu->vcpu_id].buffer;
|
||||
+ buf = v->buffer;
|
||||
|
||||
- head = buf->event_head;
|
||||
- tail = buf->event_tail;
|
||||
+ head = xenoprof_buf(d, buf, event_head);
|
||||
+ tail = xenoprof_buf(d, buf, event_tail);
|
||||
size = v->event_size;
|
||||
|
||||
/* make sure indexes in shared buffer are sane */
|
||||
@@ -447,28 +459,28 @@ void xenoprof_log_event(
|
||||
|
||||
if ( (head == tail - 1) || (head == size - 1 && tail == 0) )
|
||||
{
|
||||
- buf->lost_samples++;
|
||||
+ xenoprof_buf(d, buf, lost_samples)++;
|
||||
lost_samples++;
|
||||
}
|
||||
else
|
||||
{
|
||||
- buf->event_log[head].eip = eip;
|
||||
- buf->event_log[head].mode = mode;
|
||||
- buf->event_log[head].event = event;
|
||||
+ xenoprof_buf(d, buf, event_log[head].eip) = eip;
|
||||
+ xenoprof_buf(d, buf, event_log[head].mode) = mode;
|
||||
+ xenoprof_buf(d, buf, event_log[head].event) = event;
|
||||
head++;
|
||||
if ( head >= size )
|
||||
head = 0;
|
||||
- buf->event_head = head;
|
||||
+ xenoprof_buf(d, buf, event_head) = head;
|
||||
if ( is_active(vcpu->domain) )
|
||||
active_samples++;
|
||||
else
|
||||
passive_samples++;
|
||||
if ( mode == 0 )
|
||||
- buf->user_samples++;
|
||||
+ xenoprof_buf(d, buf, user_samples)++;
|
||||
else if ( mode == 1 )
|
||||
- buf->kernel_samples++;
|
||||
+ xenoprof_buf(d, buf, kernel_samples)++;
|
||||
else
|
||||
- buf->xen_samples++;
|
||||
+ xenoprof_buf(d, buf, xen_samples)++;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -494,6 +506,8 @@ static int xenoprof_op_init(XEN_GUEST_HA
|
||||
return 0;
|
||||
}
|
||||
|
||||
+#endif /* !COMPAT */
|
||||
+
|
||||
static int xenoprof_op_get_buffer(XEN_GUEST_HANDLE(void) arg)
|
||||
{
|
||||
struct xenoprof_get_buffer xenoprof_get_buffer;
|
||||
@@ -732,6 +746,10 @@ int do_xenoprof_op(int op, XEN_GUEST_HAN
|
||||
return ret;
|
||||
}
|
||||
|
||||
+#if defined(CONFIG_COMPAT) && !defined(COMPAT)
|
||||
+#include "compat/xenoprof.c"
|
||||
+#endif
|
||||
+
|
||||
/*
|
||||
* Local variables:
|
||||
* mode: C
|
116
README.SuSE
116
README.SuSE
@ -18,7 +18,7 @@ About
|
||||
Xen allows you to run multiple virtual machines on a single physical machine.
|
||||
|
||||
See the Xen homepage for more information:
|
||||
http://www.cl.cam.ac.uk/Research/SRG/netos/xen/
|
||||
http://www.cl.cam.ac.uk/research/srg/netos/xen/
|
||||
|
||||
If you want to use Xen, you need to install the Xen hypervisor and a number of
|
||||
supporting packages. During the initial SUSE installation (or when installing
|
||||
@ -30,11 +30,13 @@ instead, you wish to install Xen manually later, install the following packages:
|
||||
xen
|
||||
xen-libs
|
||||
xen-tools
|
||||
xen-tools-ioemu (Only required for hardware-assisted virtualization)
|
||||
xen-tools-ioemu (Required for hardware-assisted virtualization)
|
||||
multipath-tools (Required by xen-tools for domUloader)
|
||||
xen-doc-* (Optional)
|
||||
python-gtk (Optional, to install VMs graphically)
|
||||
virt-manager (Optional, to manage VMs graphically)
|
||||
tightvnc (Optional, to view VMs)
|
||||
yast2-vm (Optional, to facilitate creation and management of VMs)
|
||||
multipath-tools (Required by yast2-vm, for domUloader)
|
||||
yast2-vm (Optional, convenient icons to install/manage VMs)
|
||||
|
||||
You then need to reboot your machine. Instead of booting a normal Linux
|
||||
kernel, you will boot the Xen hypervisor and a slightly changed Linux kernel.
|
||||
@ -44,10 +46,10 @@ hardware.
|
||||
This approach is called para-virtualization, since it is a partial
|
||||
virtualization (the Linux kernel needs to be changed slightly, to make the
|
||||
virtualization easier). It results in very good performance (consult
|
||||
http://www.cl.cam.ac.uk/Research/SRG/netos/xen/performance.html) but has the
|
||||
downside of unchanged operating systems not being supported. However,
|
||||
upcoming hardware features (e.g., Intel's VT and AMD's Virtualization) will
|
||||
help overcome this limitation.
|
||||
http://www.cl.cam.ac.uk/research/srg/netos/xen/performance.html) but has the
|
||||
downside of unchanged operating systems not being supported. However, new
|
||||
hardware features (e.g., Intel's VT and AMD's V) are overcoming this
|
||||
limitation.
|
||||
|
||||
|
||||
Terminology
|
||||
@ -73,7 +75,7 @@ machines".
|
||||
|
||||
The acronym "HVM" refers to a hardware-assisted virtual machine. These are
|
||||
VMs that have not been modified (e.g., Windows) and therefore need hardware
|
||||
support such as Intel's VT or AMD's Virtualization to run on Xen.
|
||||
support such as Intel's VT or AMD's V to run on Xen.
|
||||
|
||||
|
||||
Kernels
|
||||
@ -155,8 +157,8 @@ Start Scripts
|
||||
-------------
|
||||
Before you can create additional VMs (or use any other xm command) xend must
|
||||
be running. This init script is part of the xen-tools package, and it is
|
||||
activated at installation time. You can (de)activate it using insserv (or
|
||||
chkconfig). You can also start it manually with "rcxend start".
|
||||
activated at installation time. You can (de)activate it using insserv. You
|
||||
can also start it manually with "rcxend start".
|
||||
|
||||
One other relevant startup script is xendomains. This script can be used to
|
||||
start other VMs when the VM server boots. It also cleanly shuts down the
|
||||
@ -165,59 +167,53 @@ symbolic link in /etc/xen/auto that points to the VM's configuration file.
|
||||
Look in /etc/sysconfig/xendomains for relevant settings.
|
||||
|
||||
|
||||
Creating a VM with YaST
|
||||
-----------------------
|
||||
YaST is the recommended method to create VMs. The YaST module (from the
|
||||
yast2-vm package) handles creating both the VM's configuration file and
|
||||
disk(s). YaST can help install any operating system, not just SUSE.
|
||||
Creating a VM with vm-install
|
||||
-----------------------------
|
||||
The vm-install program (part of the xen-tools package, and accessible
|
||||
through YaST's Control Center) is the recommended method to create VMs. This
|
||||
program handles creating both the VM's configuration file and disk(s). It can
|
||||
help install any operating system, not just SUSE.
|
||||
|
||||
From the command line, run "yast2 xen". From the GUI, start YaST, select
|
||||
"System", then start "Virtual Machine Management (Xen)". For full
|
||||
functionality, YaST must run in graphical mode, not ncurses.
|
||||
|
||||
The first screen shows all created and running VMs. To create a new one,
|
||||
click "Add". Now adjust the VM's configuration to your liking.
|
||||
From the command line, run "vm-install". If the DISPLAY environment
|
||||
variable is set and the supporting packages (python-gtk) are installed, a
|
||||
graphical wizard will start. Otherwise, a text wizard will start.
|
||||
|
||||
Xen does not yet properly support removable media in VMs in paravirtual mode,
|
||||
so installing an operating system from CDs can be difficult. We recommend
|
||||
using a network installation source, a DVD, or a DVD ISO. CDs do, however,
|
||||
work as expected in fully-virtual mode.
|
||||
|
||||
Note that paravirtualized SUSE Linux will default to using a text-based
|
||||
installation. To perform a graphical installation, add "vnc=1" to the
|
||||
"Installation Options" line in YaST. See this page for further guidance on
|
||||
installing via VNC:
|
||||
Note that older paravirtualized SUSE Linux (older than SLES 10 SP1) will
|
||||
default to using a text-based installation. To perform a graphical
|
||||
installation of these OSs, add "vnc=1" to the "Additional Arguments" field
|
||||
(found on the "Operating System Installation" page in the wizard). See this
|
||||
page for further guidance on installing via VNC:
|
||||
http://www.novell.com/coolsolutions/feature/15568.html
|
||||
SLES 10 SP1 and later will automatically install graphically, as they contain
|
||||
the paravirtual frame buffer driver.
|
||||
|
||||
Once you have the VM configured, click "Next". YaST will now create a
|
||||
Once you have the VM configured, click "OK". The wizard will now create a
|
||||
configuration file for the VM, and create a disk image. The disk image will
|
||||
exist in /var/lib/xen/images, and a corresponding config file will exist in
|
||||
/etc/xen/vm. The operating system's installation program will then run within
|
||||
the VM.
|
||||
|
||||
When the VM shuts down (because the installation -- or at least the first stage
|
||||
of it -- is done), YaST gives you a chance to finalize the VM's configuration.
|
||||
This is useful, for example, if the installer and the application that will
|
||||
run in the VM have different memory or network requirements.
|
||||
When the VM shuts down (because the installation -- or at least the first
|
||||
stage of it -- is done), the wizard gives you a chance to finalize the VM's
|
||||
configuration. This is useful, for example, if the installer and the
|
||||
application that will run in the VM have different memory or network
|
||||
requirements.
|
||||
|
||||
The creation of VMs can be automated with AutoYaST. A single AutoYaST profile
|
||||
can control the VM's settings (regardless of OS type) and/or the actual
|
||||
installation of the OS within the VM (for SUSE only). Perhaps the easiest way
|
||||
to create such a profile is to install a SUSE OS within a VM and "clone" the
|
||||
operating system in the final stage of the OS installation. Then copy the
|
||||
resulting file (/root/autoinst.xml) into the VM server's filesystem, into the
|
||||
directory /var/lib/autoinstall/repository/. Start the AutoYaST tool (YaST >
|
||||
Miscellaneous > Autoinstall) and then open the profile. Select the "Virtual
|
||||
Machine Management (Xen)" heading, and add the settings for the VM. Save the
|
||||
profile. Now the single profile can direct both the configuration of a VM,
|
||||
and the installation of the OS within the VM.
|
||||
The creation of VMs can be automated; read the vm-install man page for more
|
||||
details. The installation of an OS within the VM can be automated if the OS
|
||||
supports it.
|
||||
|
||||
|
||||
Creating a VM Manually
|
||||
----------------------
|
||||
If you create a VM manually (as opposed to using YaST, which is the recommended
|
||||
way), you will need to create a disk (or reuse an existing one) and a
|
||||
configuration file.
|
||||
If you create a VM manually (as opposed to using vm-install, which is the
|
||||
recommended way), you will need to create a disk (or reuse an existing one)
|
||||
and a configuration file.
|
||||
|
||||
Each VM needs to have its own root filesystem. The root filesystem can live on
|
||||
a block device (e.g., a hard disk partition, or an LVM2 or EVMS volume) or in
|
||||
@ -253,22 +249,10 @@ boots. (See "Network Troubleshooting" below.) XenSource has been allocated a
|
||||
range of MAC addresses with the OUI of 00-16-3E. By using MACs from this
|
||||
range you can be sure they will not conflict with any physical adapters.
|
||||
|
||||
To get started quickly, you can use a modified rescue image from the Novell
|
||||
SUSE installation CD/DVD. It's on the first CD/DVD in the boot/ directory with
|
||||
the name "rescue". To make it usable with Xen, run the script
|
||||
/usr/share/doc/packages/xen/mk-xen-rescue-img.sh (run it with no arguments to
|
||||
get help). The script replaces the normal Linux kernel in the image with a
|
||||
Xen-enabled Linux kernel (among other things; read the script for details).
|
||||
The script also creates a matching configuration file. The disadvantage of
|
||||
using the rescue way of constructing a root filesystem is that the result does
|
||||
not have an RPM database, so you can't easily add packages using rpm. On the
|
||||
positive side, the result is relatively small yet has most of what's needed to
|
||||
get started with networking.
|
||||
|
||||
|
||||
Managing Virtual Machines
|
||||
-------------------------
|
||||
VMs can be managed from the command line or from YaST.
|
||||
VMs can be managed from the command line or from virt-manager.
|
||||
|
||||
To create a new VM from the command line, use a command like:
|
||||
xm create my-vm
|
||||
@ -372,10 +356,6 @@ FW_FORWARD_ALWAYS_INOUT_DEV="xenbr0".
|
||||
If xenbr0 and xenbr1 are being used, the line should be:
|
||||
FW_FORWARD_ALWAYS_INOUT_DEV="xenbr0 xenbr1".
|
||||
|
||||
If you use the rescue images created by the above mentioned script, you'll
|
||||
have a boot script inside that parses the ip=.... boot parameter. You can set
|
||||
this parameter in the config file, and can have networking work automatically.
|
||||
|
||||
When using bridging, the eth0 in domain 0 device will be renamed to peth0 and
|
||||
its MAC address will be set to fe:ff:ff:ff:ff:ff and ARP will be disabled.
|
||||
veth0 will take over the old MAC address, be renamed to eth0, and be enabled
|
||||
@ -475,13 +455,15 @@ grow the virtual hardware beyond what the kernel has been booted with. But
|
||||
you can trick domU Linux to prepare for a larger amount of RAM by passing the
|
||||
mem= boot parameter.
|
||||
|
||||
The export of virtual hard disks from files in Xen is handled via the loopback
|
||||
driver. You can easily run out of those, as by default only 8 loopback devices
|
||||
are supported. You can change this by inserting:
|
||||
The export of virtual hard disks from files in Xen can be handled via the
|
||||
loopback driver (although in Xen 3.0.4, this is being replaced by the "blktap"
|
||||
user-space driver.) If you are still using loopback, you can easily run out
|
||||
of loopback devices, as by default only 8 are supported. You can change this
|
||||
by inserting:
|
||||
options loop max_loop=64
|
||||
into /etc/modprobe.conf.local in domain 0.
|
||||
|
||||
Similarly, the netback driver comes up with 8 virtual network device pairs
|
||||
Similarly, the netback driver comes up with 4 virtual network device pairs
|
||||
(vif0.X - vethX). You can change this by inserting:
|
||||
options netloop nloopbacks=64
|
||||
into /etc/modprobe.conf.local in domain 0.
|
||||
@ -526,7 +508,7 @@ may help. Xen and Linux understand similar ACPI boot parameters. Try the
|
||||
options acpi=off,force,strict,ht,noirq or acpi_skip_timer_override. Other
|
||||
useful debugging options to Xen may be nosmp, noreboot, mem=1024M,
|
||||
sync_console, noirqbalance (Dell). For a complete list of Xen boot options,
|
||||
consult chapter 10.3 of the Xen users' manual.
|
||||
consult chapter 11.3 of the Xen users' manual.
|
||||
|
||||
If domain 0 Linux crashes on X11 startup, please try to boot into runlevel 3.
|
||||
|
||||
|
71
blktools-bimodal.diff
Normal file
71
blktools-bimodal.diff
Normal file
@ -0,0 +1,71 @@
|
||||
bimodal: blk tools
|
||||
|
||||
Add one more option to the disk configuration, so one can specify the
|
||||
protocol the frontend speaks in the config file. This is needed for
|
||||
old frontends which don't advertise the protocol they are speaking
|
||||
themself.
|
||||
|
||||
I'm not that happy with this approach, but it works for now and I'm
|
||||
kida lost in the stack of python classes doing domain and device
|
||||
handling ...
|
||||
|
||||
Signed-off-by: Gerd Hoffmann <kraxel@suse.de>
|
||||
---
|
||||
tools/python/xen/xend/server/blkif.py | 3 +++
|
||||
tools/python/xen/xm/create.py | 7 ++++++-
|
||||
2 files changed, 9 insertions(+), 1 deletion(-)
|
||||
|
||||
Index: build-64-release304-13133/tools/python/xen/xend/server/blkif.py
|
||||
===================================================================
|
||||
--- build-64-release304-13133.orig/tools/python/xen/xend/server/blkif.py
|
||||
+++ build-64-release304-13133/tools/python/xen/xend/server/blkif.py
|
||||
@@ -38,6 +38,7 @@ class BlkifController(DevController):
|
||||
"""@see DevController.getDeviceDetails"""
|
||||
uname = config.get('uname', '')
|
||||
dev = config.get('dev', '')
|
||||
+ protocol = config.get('protocol')
|
||||
|
||||
if 'ioemu:' in dev:
|
||||
(_, dev) = string.split(dev, ':', 1)
|
||||
@@ -85,6 +86,8 @@ class BlkifController(DevController):
|
||||
front = { 'virtual-device' : "%i" % devid,
|
||||
'device-type' : dev_type
|
||||
}
|
||||
+ if protocol:
|
||||
+ front.update({ 'protocol' : protocol });
|
||||
|
||||
return (devid, back, front)
|
||||
|
||||
Index: build-64-release304-13133/tools/python/xen/xm/create.py
|
||||
===================================================================
|
||||
--- build-64-release304-13133.orig/tools/python/xen/xm/create.py
|
||||
+++ build-64-release304-13133/tools/python/xen/xm/create.py
|
||||
@@ -531,7 +531,7 @@ def configure_image(vals):
|
||||
def configure_disks(config_devs, vals):
|
||||
"""Create the config for disks (virtual block devices).
|
||||
"""
|
||||
- for (uname, dev, mode, backend) in vals.disk:
|
||||
+ for (uname, dev, mode, backend, protocol) in vals.disk:
|
||||
if uname.startswith('tap:'):
|
||||
cls = 'tap'
|
||||
else:
|
||||
@@ -543,6 +543,8 @@ def configure_disks(config_devs, vals):
|
||||
['mode', mode ] ]
|
||||
if backend:
|
||||
config_vbd.append(['backend', backend])
|
||||
+ if protocol:
|
||||
+ config_vbd.append(['protocol', protocol])
|
||||
config_devs.append(['device', config_vbd])
|
||||
|
||||
def configure_pci(config_devs, vals):
|
||||
@@ -787,7 +789,10 @@ def preprocess_disk(vals):
|
||||
n = len(d)
|
||||
if n == 3:
|
||||
d.append(None)
|
||||
+ d.append(None)
|
||||
elif n == 4:
|
||||
+ d.append(None)
|
||||
+ elif n == 5:
|
||||
pass
|
||||
else:
|
||||
err('Invalid disk specifier: ' + v)
|
180
block-iscsi
180
block-iscsi
@ -1,90 +1,90 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Usage: block-iscsi [add tgtname | remove dev]
|
||||
#
|
||||
# This assumes you're running a correctly configured
|
||||
# iscsi target (server) at the other end!
|
||||
# Note that we assume that the passwords for discovery (if needed)
|
||||
# are in /etc/iscsid.conf
|
||||
# and the node session passwords (if required) in the
|
||||
# open-iscsi database below /var/lib/open-iscsi/node.db
|
||||
#
|
||||
# (c) Kurt Garloff <kurt@garloff.de>, 2006-09-04, GNU GPL
|
||||
|
||||
dir=$(dirname "$0")
|
||||
. "$dir/block-common.sh"
|
||||
#command=$1
|
||||
|
||||
#echo "DBG:xen/scripts/block-iscsi $1 $2 XENBUS_PATH=$XENBUS_PATH $par $node"
|
||||
|
||||
#write_dev()
|
||||
#{
|
||||
# echo "$1"
|
||||
#}
|
||||
|
||||
find_sdev()
|
||||
{
|
||||
unset dev
|
||||
for session in /sys/class/iscsi_session/session*; do
|
||||
if test $1 = `cat $session/targetname`; then
|
||||
dev=`readlink $session/device/target*/*:0:*/block*`
|
||||
dev=${dev##*/}
|
||||
return
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
find_sdev_rev()
|
||||
{
|
||||
unset tgt
|
||||
for session in /sys/class/iscsi_session/session*; do
|
||||
dev=`readlink $session/device/target*/*:0:*/block*`
|
||||
dev=${dev##*/}
|
||||
if test $dev = $1; then
|
||||
tgt=`cat $session/targetname`
|
||||
return
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
case "$command" in
|
||||
add)
|
||||
# load modules and start iscsid
|
||||
/etc/init.d/open-iscsi status >/dev/null 2>&1 ||
|
||||
{ /etc/init.d/open-iscsi start >/dev/null 2>&1; sleep 1; }
|
||||
# list of targets on node
|
||||
par=`xenstore-read $XENBUS_PATH/params` || true
|
||||
TGTID=$par; TGTID=${TGTID//@/:}
|
||||
while read rec port uuid; do
|
||||
if test $uuid = $TGTID; then
|
||||
rec=${rec%]}; rec=${rec#[}
|
||||
find_sdev $TGTID
|
||||
if test -z "$dev"; then
|
||||
iscsiadm -m node -r $rec -l || exit 2
|
||||
usleep 100000
|
||||
find_sdev $TGTID
|
||||
fi
|
||||
xenstore-write $XENBUS_PATH/node /dev/$dev
|
||||
write_dev /dev/$dev
|
||||
exit 0
|
||||
fi
|
||||
done < <(iscsiadm -m node)
|
||||
exit 1
|
||||
;;
|
||||
remove)
|
||||
node=`xenstore-read $XENBUS_PATH/node` || true
|
||||
dev=$node; dev=${dev#/dev/}
|
||||
find_sdev_rev $dev
|
||||
#echo $tgt
|
||||
if test -x /sbin/blockdev -a -n "$node"; then blockdev --flushbufs $node; fi
|
||||
test -z "$tgt" && exit 2
|
||||
while read rec port uuid; do
|
||||
if test $uuid = $tgt; then
|
||||
rec=${rec%]}; rec=${rec#[}
|
||||
iscsiadm -m node -r $rec -u
|
||||
exit 0
|
||||
fi
|
||||
done < <(iscsiadm -m node)
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
#!/bin/bash
|
||||
|
||||
# Usage: block-iscsi [add tgtname | remove dev]
|
||||
#
|
||||
# This assumes you're running a correctly configured
|
||||
# iscsi target (server) at the other end!
|
||||
# Note that we assume that the passwords for discovery (if needed)
|
||||
# are in /etc/iscsid.conf
|
||||
# and the node session passwords (if required) in the
|
||||
# open-iscsi database below /var/lib/open-iscsi/node.db
|
||||
#
|
||||
# (c) Kurt Garloff <kurt@garloff.de>, 2006-09-04, GNU GPL
|
||||
|
||||
dir=$(dirname "$0")
|
||||
. "$dir/block-common.sh"
|
||||
#command=$1
|
||||
|
||||
#echo "DBG:xen/scripts/block-iscsi $1 $2 XENBUS_PATH=$XENBUS_PATH $par $node"
|
||||
|
||||
#write_dev()
|
||||
#{
|
||||
# echo "$1"
|
||||
#}
|
||||
|
||||
find_sdev()
|
||||
{
|
||||
unset dev
|
||||
for session in /sys/class/iscsi_session/session*; do
|
||||
if test $1 = `cat $session/targetname`; then
|
||||
dev=`readlink $session/device/target*/*:0:*/block*`
|
||||
dev=${dev##*/}
|
||||
return
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
find_sdev_rev()
|
||||
{
|
||||
unset tgt
|
||||
for session in /sys/class/iscsi_session/session*; do
|
||||
dev=`readlink $session/device/target*/*:0:*/block*`
|
||||
dev=${dev##*/}
|
||||
if test $dev = $1; then
|
||||
tgt=`cat $session/targetname`
|
||||
return
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
case "$command" in
|
||||
add)
|
||||
# load modules and start iscsid
|
||||
/etc/init.d/open-iscsi status >/dev/null 2>&1 ||
|
||||
{ /etc/init.d/open-iscsi start >/dev/null 2>&1; sleep 1; }
|
||||
# list of targets on node
|
||||
par=`xenstore-read $XENBUS_PATH/params` || true
|
||||
TGTID=$par; TGTID=${TGTID//@/:}
|
||||
while read rec port uuid; do
|
||||
if test $uuid = $TGTID; then
|
||||
rec=${rec%]}; rec=${rec#[}
|
||||
find_sdev $TGTID
|
||||
if test -z "$dev"; then
|
||||
iscsiadm -m node -r $rec -l || exit 2
|
||||
usleep 100000
|
||||
find_sdev $TGTID
|
||||
fi
|
||||
xenstore-write $XENBUS_PATH/node /dev/$dev
|
||||
write_dev /dev/$dev
|
||||
exit 0
|
||||
fi
|
||||
done < <(iscsiadm -m node)
|
||||
exit 1
|
||||
;;
|
||||
remove)
|
||||
node=`xenstore-read $XENBUS_PATH/node` || true
|
||||
dev=$node; dev=${dev#/dev/}
|
||||
find_sdev_rev $dev
|
||||
#echo $tgt
|
||||
if test -x /sbin/blockdev -a -n "$node"; then blockdev --flushbufs $node; fi
|
||||
test -z "$tgt" && exit 2
|
||||
while read rec port uuid; do
|
||||
if test $uuid = $tgt; then
|
||||
rec=${rec%]}; rec=${rec#[}
|
||||
iscsiadm -m node -r $rec -u
|
||||
exit 0
|
||||
fi
|
||||
done < <(iscsiadm -m node)
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
@ -1,8 +1,8 @@
|
||||
Index: xen-unstable/tools/examples/block
|
||||
Index: xen-3.0.4-testing/tools/examples/block
|
||||
===================================================================
|
||||
--- xen-unstable.orig/tools/examples/block
|
||||
+++ xen-unstable/tools/examples/block
|
||||
@@ -391,8 +391,18 @@ mount it read-write in a guest domain."
|
||||
--- xen-3.0.4-testing.orig/tools/examples/block
|
||||
+++ xen-3.0.4-testing/tools/examples/block
|
||||
@@ -390,8 +390,18 @@ mount it read-write in a guest domain."
|
||||
|
||||
file)
|
||||
node=$(xenstore_read "$XENBUS_PATH/node")
|
||||
|
@ -12,7 +12,7 @@ dir=$(dirname "$0")
|
||||
|
||||
#set -x
|
||||
par=`xenstore-read $XENBUS_PATH/params` || true
|
||||
echo $par
|
||||
#echo $par
|
||||
|
||||
case "$command" in
|
||||
add)
|
||||
|
@ -1,7 +1,7 @@
|
||||
Index: xen-unstable/tools/examples/block
|
||||
Index: xen-3.0.4-testing/tools/examples/block
|
||||
===================================================================
|
||||
--- xen-unstable.orig/tools/examples/block
|
||||
+++ xen-unstable/tools/examples/block
|
||||
--- xen-3.0.4-testing.orig/tools/examples/block
|
||||
+++ xen-3.0.4-testing/tools/examples/block
|
||||
@@ -42,6 +42,20 @@ canonicalise_mode()
|
||||
fi
|
||||
}
|
||||
|
82
bridge-hostonly.diff
Normal file
82
bridge-hostonly.diff
Normal file
@ -0,0 +1,82 @@
|
||||
Add support for "hostonly" xen bridges.
|
||||
|
||||
Add support for "hostonly" networking, i.e. create a bridge without a
|
||||
physical network device linked in. The virtual machines can see each
|
||||
other and the host, but can't (directly) talk to the outside. Pass
|
||||
"netdev=none" to the network-bridge script to activate this.
|
||||
|
||||
I'm using this on a laptop which has different network connections at
|
||||
different times (wired / wireless), so it is inconvinient to add the
|
||||
physical device into the bridge. In case the laptop is offline the
|
||||
virtual network still works just fine. It also avoids the problem that
|
||||
bridging doesn't work with wireless due to being limited to one mac
|
||||
address then.
|
||||
|
||||
dom0 on that laptop also runs a dhcp server for the virtual network.
|
||||
Guests can talk to the internet via apache configured as http proxy.
|
||||
Another possible approach for guest internet access is NATing the
|
||||
virtual network.
|
||||
|
||||
Signed-off-by: Gerd Hoffmann <kraxel@suse.de>
|
||||
---
|
||||
tools/examples/network-bridge | 37 +++++++++++++++++++++++++++++++++++--
|
||||
1 file changed, 35 insertions(+), 2 deletions(-)
|
||||
|
||||
Index: build-32-unstable-11624/tools/examples/network-bridge
|
||||
===================================================================
|
||||
--- build-32-unstable-11624.orig/tools/examples/network-bridge
|
||||
+++ build-32-unstable-11624/tools/examples/network-bridge
|
||||
@@ -269,6 +269,31 @@ op_stop () {
|
||||
brctl delbr ${bridge}
|
||||
}
|
||||
|
||||
+op_start_hostonly () {
|
||||
+ if [ "${bridge}" = "null" ] ; then
|
||||
+ return
|
||||
+ fi
|
||||
+ if link_exists "${bridge}"; then
|
||||
+ return
|
||||
+ fi
|
||||
+
|
||||
+ create_bridge ${bridge}
|
||||
+ setup_bridge_port ${vif0}
|
||||
+ add_to_bridge ${bridge} ${vif0}
|
||||
+}
|
||||
+
|
||||
+op_stop_hostonly () {
|
||||
+ if [ "${bridge}" = "null" ]; then
|
||||
+ return
|
||||
+ fi
|
||||
+ if ! link_exists "$bridge"; then
|
||||
+ return
|
||||
+ fi
|
||||
+
|
||||
+ brctl delbr ${bridge}
|
||||
+}
|
||||
+
|
||||
+
|
||||
# adds $dev to $bridge but waits for $dev to be in running state first
|
||||
add_to_bridge2() {
|
||||
local bridge=$1
|
||||
@@ -293,11 +318,19 @@ add_to_bridge2() {
|
||||
|
||||
case "$command" in
|
||||
start)
|
||||
- op_start
|
||||
+ if test "$netdev" = "none"; then
|
||||
+ op_start_hostonly
|
||||
+ else
|
||||
+ op_start
|
||||
+ fi
|
||||
;;
|
||||
|
||||
stop)
|
||||
- op_stop
|
||||
+ if test "$netdev" = "none"; then
|
||||
+ op_stop_hostonly
|
||||
+ else
|
||||
+ op_stop
|
||||
+ fi
|
||||
;;
|
||||
|
||||
status)
|
325
bug.patch
Normal file
325
bug.patch
Normal file
@ -0,0 +1,325 @@
|
||||
Index: 2007-01-31/xen/arch/powerpc/backtrace.c
|
||||
===================================================================
|
||||
--- 2007-01-31.orig/xen/arch/powerpc/backtrace.c 2006-12-15 16:33:59.000000000 +0100
|
||||
+++ 2007-01-31/xen/arch/powerpc/backtrace.c 2007-01-31 09:42:07.000000000 +0100
|
||||
@@ -206,7 +206,7 @@ void show_backtrace_regs(struct cpu_user
|
||||
console_end_sync();
|
||||
}
|
||||
|
||||
-void __warn(char *file, int line)
|
||||
+void __warn(const char *file, int line)
|
||||
{
|
||||
ulong sp;
|
||||
ulong lr;
|
||||
Index: 2007-01-31/xen/arch/x86/mm/shadow/common.c
|
||||
===================================================================
|
||||
--- 2007-01-31.orig/xen/arch/x86/mm/shadow/common.c 2007-01-31 09:36:44.000000000 +0100
|
||||
+++ 2007-01-31/xen/arch/x86/mm/shadow/common.c 2007-01-31 09:42:07.000000000 +0100
|
||||
@@ -940,6 +940,7 @@ mfn_t shadow_alloc(struct domain *d,
|
||||
* we might free up higher-level pages that the caller is working on. */
|
||||
SHADOW_PRINTK("Can't allocate %i shadow pages!\n", 1 << order);
|
||||
BUG();
|
||||
+ return _mfn(0);
|
||||
}
|
||||
|
||||
|
||||
Index: 2007-01-31/xen/arch/x86/mm/shadow/multi.c
|
||||
===================================================================
|
||||
--- 2007-01-31.orig/xen/arch/x86/mm/shadow/multi.c 2007-01-31 09:36:54.000000000 +0100
|
||||
+++ 2007-01-31/xen/arch/x86/mm/shadow/multi.c 2007-01-31 09:42:07.000000000 +0100
|
||||
@@ -3160,7 +3160,7 @@ sh_update_linear_entries(struct vcpu *v)
|
||||
*/
|
||||
{
|
||||
l2_pgentry_t *l2e, new_l2e;
|
||||
- shadow_l3e_t *guest_l3e = NULL, *shadow_l3e;
|
||||
+ shadow_l3e_t *guest_l3e = NULL, *shadow_l3e = NULL;
|
||||
int i;
|
||||
int unmap_l2e = 0;
|
||||
|
||||
Index: 2007-01-31/xen/arch/x86/traps.c
|
||||
===================================================================
|
||||
--- 2007-01-31.orig/xen/arch/x86/traps.c 2007-01-31 09:41:54.000000000 +0100
|
||||
+++ 2007-01-31/xen/arch/x86/traps.c 2007-01-31 09:42:07.000000000 +0100
|
||||
@@ -635,14 +635,50 @@ asmlinkage int do_invalid_op(struct cpu_
|
||||
|
||||
if ( unlikely(!guest_mode(regs)) )
|
||||
{
|
||||
- char sig[5];
|
||||
- /* Signature (ud2; .ascii "dbg") indicates dump state and continue. */
|
||||
- if ( (__copy_from_user(sig, (char *)regs->eip, sizeof(sig)) == 0) &&
|
||||
- (memcmp(sig, "\xf\xb""dbg", sizeof(sig)) == 0) )
|
||||
- {
|
||||
- show_execution_state(regs);
|
||||
- regs->eip += sizeof(sig);
|
||||
- return EXCRET_fault_fixed;
|
||||
+ struct bug_frame f;
|
||||
+
|
||||
+ if ( (__copy_from_user(&f, (char *)regs->eip, sizeof(f)) == 0) &&
|
||||
+ f.ud2[0] == 0x0f && f.ud2[1] == 0x0b && f.ret == 0xc2 )
|
||||
+ {
|
||||
+ const char *text = NULL;
|
||||
+ char file[40];
|
||||
+
|
||||
+ switch ( f.id )
|
||||
+ {
|
||||
+ case bug_bug:
|
||||
+ text = "BUG";
|
||||
+ break;
|
||||
+ case bug_warn:
|
||||
+ text = "Badness";
|
||||
+ break;
|
||||
+ case bug_dump_state:
|
||||
+ text = "State";
|
||||
+ break;
|
||||
+ case bug_crash_dom:
|
||||
+ text = "domain_crash called";
|
||||
+ break;
|
||||
+ }
|
||||
+ if ( text )
|
||||
+ {
|
||||
+ const void *ptr;
|
||||
+
|
||||
+ ptr = &((const struct bug_frame *)regs->eip)->id + f.file_rel;
|
||||
+ if ( __addr_ok(ptr) ||
|
||||
+ __copy_from_user(file, ptr, sizeof(file) - 1) )
|
||||
+ text = NULL;
|
||||
+ else
|
||||
+ file[sizeof(file) - 1] = 0;
|
||||
+ }
|
||||
+ if ( text )
|
||||
+ {
|
||||
+ printk("%s at %s:%d\n", text, file, f.line);
|
||||
+ if ( f.id != bug_bug )
|
||||
+ {
|
||||
+ show_execution_state(regs);
|
||||
+ regs->eip += sizeof(f);
|
||||
+ return EXCRET_fault_fixed;
|
||||
+ }
|
||||
+ }
|
||||
}
|
||||
DEBUGGER_trap_fatal(TRAP_invalid_op, regs);
|
||||
show_execution_state(regs);
|
||||
Index: 2007-01-31/xen/common/keyhandler.c
|
||||
===================================================================
|
||||
--- 2007-01-31.orig/xen/common/keyhandler.c 2007-01-31 09:29:10.000000000 +0100
|
||||
+++ 2007-01-31/xen/common/keyhandler.c 2007-01-31 09:42:07.000000000 +0100
|
||||
@@ -94,7 +94,7 @@ static void show_handlers(unsigned char
|
||||
|
||||
static void __dump_execstate(void *unused)
|
||||
{
|
||||
- dump_execution_state();
|
||||
+ DUMP_STATE();
|
||||
}
|
||||
|
||||
static void dump_registers(unsigned char key, struct cpu_user_regs *regs)
|
||||
Index: 2007-01-31/xen/drivers/char/console.c
|
||||
===================================================================
|
||||
--- 2007-01-31.orig/xen/drivers/char/console.c 2006-12-15 16:33:59.000000000 +0100
|
||||
+++ 2007-01-31/xen/drivers/char/console.c 2007-01-31 09:42:07.000000000 +0100
|
||||
@@ -880,15 +880,21 @@ void panic(const char *fmt, ...)
|
||||
}
|
||||
}
|
||||
|
||||
-void __bug(char *file, int line)
|
||||
+void __bug(const char *file, int line)
|
||||
{
|
||||
console_start_sync();
|
||||
printk("BUG at %s:%d\n", file, line);
|
||||
- dump_execution_state();
|
||||
+ DUMP_STATE();
|
||||
panic("BUG at %s:%d\n", file, line);
|
||||
for ( ; ; ) ;
|
||||
}
|
||||
|
||||
+void __warn(const char *file, int line) __attribute__((__weak__));
|
||||
+void __warn(const char *file, int line)
|
||||
+{
|
||||
+ printk("Badness at %s:%d\n", file, line);
|
||||
+}
|
||||
+
|
||||
/*
|
||||
* Local variables:
|
||||
* mode: C
|
||||
Index: 2007-01-31/xen/include/asm-ia64/bug.h
|
||||
===================================================================
|
||||
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
|
||||
+++ 2007-01-31/xen/include/asm-ia64/bug.h 2007-01-31 09:42:07.000000000 +0100
|
||||
@@ -0,0 +1,6 @@
|
||||
+#ifndef __ASM_IA64_BUG_H__
|
||||
+#define __ASM_IA64_BUG_H__
|
||||
+
|
||||
+#define DUMP_STATE() printk("FIXME: implement ia64 dump_execution_state()\n");
|
||||
+
|
||||
+#endif /* __ASM_IA64_BUG_H__ */
|
||||
Index: 2007-01-31/xen/include/asm-ia64/linux-xen/asm/iosapic.h
|
||||
===================================================================
|
||||
--- 2007-01-31.orig/xen/include/asm-ia64/linux-xen/asm/iosapic.h 2006-12-13 11:15:55.000000000 +0100
|
||||
+++ 2007-01-31/xen/include/asm-ia64/linux-xen/asm/iosapic.h 2007-01-31 09:42:07.000000000 +0100
|
||||
@@ -123,11 +123,10 @@ static inline void list_move(struct list
|
||||
|
||||
#define move_irq(x)
|
||||
|
||||
-#define WARN_ON(condition) do { \
|
||||
- if (unlikely((condition)!=0)) { \
|
||||
- printk("Badness in %s at %s:%d\n", __FUNCTION__, __FILE__, __LINE__); \
|
||||
- dump_stack(); \
|
||||
- } \
|
||||
+#undef WARN
|
||||
+#define WARN() do { \
|
||||
+ printk("Badness in %s at %s:%d\n", __FUNCTION__, __FILE__, __LINE__); \
|
||||
+ dump_stack(); \
|
||||
} while (0)
|
||||
|
||||
#ifdef nop
|
||||
Index: 2007-01-31/xen/include/asm-ia64/xenprocessor.h
|
||||
===================================================================
|
||||
--- 2007-01-31.orig/xen/include/asm-ia64/xenprocessor.h 2006-12-13 11:15:55.000000000 +0100
|
||||
+++ 2007-01-31/xen/include/asm-ia64/xenprocessor.h 2007-01-31 09:42:07.000000000 +0100
|
||||
@@ -237,6 +237,4 @@ typedef union {
|
||||
u64 itir;
|
||||
} ia64_itir_t;
|
||||
|
||||
-#define dump_execution_state() printk("FIXME: implement ia64 dump_execution_state()\n");
|
||||
-
|
||||
#endif // _ASM_IA64_XENPROCESSOR_H
|
||||
Index: 2007-01-31/xen/include/asm-powerpc/bug.h
|
||||
===================================================================
|
||||
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
|
||||
+++ 2007-01-31/xen/include/asm-powerpc/bug.h 2007-01-31 09:42:07.000000000 +0100
|
||||
@@ -0,0 +1,7 @@
|
||||
+#ifndef __ASM_PPC_BUG_H__
|
||||
+#define __ASM_PPC_BUG_H__
|
||||
+
|
||||
+extern void dump_execution_state(void);
|
||||
+#define DUMP_STATE() dump_execution_state()
|
||||
+
|
||||
+#endif /* __ASM_PPC_BUG_H__ */
|
||||
Index: 2007-01-31/xen/include/asm-powerpc/debugger.h
|
||||
===================================================================
|
||||
--- 2007-01-31.orig/xen/include/asm-powerpc/debugger.h 2006-12-15 16:33:59.000000000 +0100
|
||||
+++ 2007-01-31/xen/include/asm-powerpc/debugger.h 2007-01-31 09:42:07.000000000 +0100
|
||||
@@ -67,10 +67,6 @@ static inline void unimplemented(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
-extern void __warn(char *file, int line);
|
||||
-#define WARN() __warn(__FILE__, __LINE__)
|
||||
-#define WARN_ON(_p) do { if (_p) WARN(); } while ( 0 )
|
||||
-
|
||||
extern void __attn(void);
|
||||
#define ATTN() __attn();
|
||||
|
||||
Index: 2007-01-31/xen/include/asm-x86/bug.h
|
||||
===================================================================
|
||||
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
|
||||
+++ 2007-01-31/xen/include/asm-x86/bug.h 2007-01-31 09:42:07.000000000 +0100
|
||||
@@ -0,0 +1,60 @@
|
||||
+#ifndef __ASM_X86_BUG_H__
|
||||
+#define __ASM_X86_BUG_H__
|
||||
+
|
||||
+enum bug_id {
|
||||
+ bug_bug = 0xb8,
|
||||
+ bug_warn,
|
||||
+ bug_dump_state,
|
||||
+ bug_crash_dom
|
||||
+} __attribute__((__packed__));
|
||||
+
|
||||
+struct bug_frame {
|
||||
+ unsigned char ud2[2];
|
||||
+ enum bug_id id;
|
||||
+ signed int file_rel;
|
||||
+ unsigned char ret;
|
||||
+ unsigned short line;
|
||||
+} __attribute__((__packed__));
|
||||
+
|
||||
+/* NB. These need interrupts enabled else we end up in fatal_trap(). */
|
||||
+
|
||||
+#define BUG() __asm__ __volatile__( \
|
||||
+ "pushf\n\t" \
|
||||
+ "sti\n\t" \
|
||||
+ "ud2\n\t" \
|
||||
+ "movl $%c0-.,%%eax\n\t" \
|
||||
+ "ret $%c1\n\t" \
|
||||
+ "popf" \
|
||||
+ : : "i" (__FILE__), "i" (__LINE__))
|
||||
+
|
||||
+#define WARN() __asm__ __volatile__( \
|
||||
+ "pushf\n\t" \
|
||||
+ "sti\n\t" \
|
||||
+ "ud2\n\t" \
|
||||
+ "movl $%c0-.,%%ecx\n\t" \
|
||||
+ "ret $%c1\n\t" \
|
||||
+ "popf" \
|
||||
+ : : "i" (__FILE__), "i" (__LINE__))
|
||||
+
|
||||
+#define DUMP_STATE() __asm__ __volatile__( \
|
||||
+ "pushf\n\t" \
|
||||
+ "sti\n\t" \
|
||||
+ "ud2\n\t" \
|
||||
+ "movl $%c0-.,%%edx\n\t" \
|
||||
+ "ret $%c1\n\t" \
|
||||
+ "popf" \
|
||||
+ : : "i" (__FILE__), "i" (__LINE__))
|
||||
+
|
||||
+#define CRASH_DOM(d) do { \
|
||||
+ __asm__ __volatile__( \
|
||||
+ "pushf\n\t" \
|
||||
+ "sti\n\t" \
|
||||
+ "ud2\n\t" \
|
||||
+ "movl $%c0-.,%%ebx\n\t" \
|
||||
+ "ret $%c1\n\t" \
|
||||
+ "popf" \
|
||||
+ : : "i" (__FILE__), "i" (__LINE__)); \
|
||||
+ __domain_crash(d); \
|
||||
+ } while (0)
|
||||
+
|
||||
+#endif /* __ASM_X86_BUG_H__ */
|
||||
Index: 2007-01-31/xen/include/asm-x86/processor.h
|
||||
===================================================================
|
||||
--- 2007-01-31.orig/xen/include/asm-x86/processor.h 2007-01-31 09:29:08.000000000 +0100
|
||||
+++ 2007-01-31/xen/include/asm-x86/processor.h 2007-01-31 09:42:07.000000000 +0100
|
||||
@@ -565,11 +565,6 @@ void compat_show_guest_stack(struct cpu_
|
||||
#define compat_show_guest_stack(regs, lines) ((void)0)
|
||||
#endif
|
||||
|
||||
-/* Dumps current register and stack state. */
|
||||
-#define dump_execution_state() \
|
||||
- /* NB. Needs interrupts enabled else we end up in fatal_trap(). */ \
|
||||
- __asm__ __volatile__ ( "pushf ; sti ; ud2 ; .ascii \"dbg\" ; popf" )
|
||||
-
|
||||
extern void mtrr_ap_init(void);
|
||||
extern void mtrr_bp_init(void);
|
||||
|
||||
Index: 2007-01-31/xen/include/xen/lib.h
|
||||
===================================================================
|
||||
--- 2007-01-31.orig/xen/include/xen/lib.h 2007-01-08 14:16:35.000000000 +0100
|
||||
+++ 2007-01-31/xen/include/xen/lib.h 2007-01-31 09:42:07.000000000 +0100
|
||||
@@ -7,10 +7,26 @@
|
||||
#include <xen/types.h>
|
||||
#include <xen/xmalloc.h>
|
||||
#include <xen/string.h>
|
||||
+#include <asm/bug.h>
|
||||
|
||||
-extern void __bug(char *file, int line) __attribute__((noreturn));
|
||||
+#ifndef BUG
|
||||
+extern void __bug(const char *file, int line) __attribute__((noreturn));
|
||||
#define BUG() __bug(__FILE__, __LINE__)
|
||||
-#define BUG_ON(_p) do { if (_p) BUG(); } while ( 0 )
|
||||
+#endif
|
||||
+
|
||||
+#ifndef WARN
|
||||
+extern void __warn(const char *file, int line);
|
||||
+#define WARN() __warn(__FILE__, __LINE__)
|
||||
+#endif
|
||||
+
|
||||
+#ifndef CRASH_DOM
|
||||
+#define CRASH_DOM(d) domain_crash(d)
|
||||
+#endif
|
||||
+
|
||||
+#define BUG_ON(_p) do { if (unlikely(_p)) BUG(); } while ( 0 )
|
||||
+#define WARN_ON(_p) do { if (unlikely(_p)) WARN(); } while ( 0 )
|
||||
+#define DUMP_STATE_ON(_p) do { if (unlikely(_p)) DUMP_STATE(); } while ( 0 )
|
||||
+#define CRASH_DOM_ON(_d, _p) do { if (unlikely(_p)) CRASH_DOM(_d); } while ( 0 )
|
||||
|
||||
/* Force a compilation error if condition is true */
|
||||
#define BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2 * !!(condition)]))
|
45
cross-build-fix.diff
Normal file
45
cross-build-fix.diff
Normal file
@ -0,0 +1,45 @@
|
||||
Fix 32bit xen-tools build.
|
||||
|
||||
This fixes building 32bit xen-tools on a amd64 machine, i.e.
|
||||
"XEN_TARGET_ARCH=x86_32 make".
|
||||
|
||||
For ioemu I've taken the lazy path and just disabled them for
|
||||
cross-builds, I'll leave that to fix to someone who knows the
|
||||
qemu makefiles better than I do ;)
|
||||
|
||||
Signed-off-by: Gerd Hoffmann <kraxel@suse.de>
|
||||
---
|
||||
config/x86_32.mk | 6 ++++--
|
||||
tools/Makefile | 2 +-
|
||||
2 files changed, 5 insertions(+), 3 deletions(-)
|
||||
|
||||
Index: build-32-unstable-12621/config/x86_32.mk
|
||||
===================================================================
|
||||
--- build-32-unstable-12621.orig/config/x86_32.mk
|
||||
+++ build-32-unstable-12621/config/x86_32.mk
|
||||
@@ -6,8 +6,10 @@ CONFIG_MIGRATE := y
|
||||
CONFIG_XCUTILS := y
|
||||
CONFIG_IOEMU := y
|
||||
|
||||
-CFLAGS += -m32 -march=i686
|
||||
-LIBDIR := lib
|
||||
+CFLAGS += -m32 -march=i686
|
||||
+LDFLAGS += -m32
|
||||
+ASFLAGS += -m32
|
||||
+LIBDIR := lib
|
||||
|
||||
# Use only if calling $(LD) directly.
|
||||
ifeq ($(XEN_OS),OpenBSD)
|
||||
Index: build-32-unstable-12621/tools/Makefile
|
||||
===================================================================
|
||||
--- build-32-unstable-12621.orig/tools/Makefile
|
||||
+++ build-32-unstable-12621/tools/Makefile
|
||||
@@ -62,7 +62,7 @@ check_clean:
|
||||
$(MAKE) -C check clean
|
||||
|
||||
.PHONY: ioemu ioemuinstall ioemuclean
|
||||
-ifeq ($(CONFIG_IOEMU),y)
|
||||
+ifeq ($(XEN_COMPILE_ARCH)$(CONFIG_IOEMU),$(XEN_TARGET_ARCH)y)
|
||||
export IOEMU_DIR ?= ioemu
|
||||
ioemu ioemuinstall:
|
||||
[ -f $(IOEMU_DIR)/config-host.mak ] || \
|
470
domUloader.py
470
domUloader.py
@ -1,39 +1,35 @@
|
||||
#!/usr/bin/env python
|
||||
# domUloader.py
|
||||
"""Loader for kernel and (optional) ramdisk from domU filesystem
|
||||
|
||||
Given a physical disk (or disk image) for a domU and the path of a kernel and
|
||||
optional ramdisk, copies the kernel and ramdisk from the domU disk to a
|
||||
temporary location in dom0.
|
||||
|
||||
The --entry parameter specifies the location of the kernel (and optional
|
||||
ramdisk) within the domU filesystem. dev is the disk as seen by domU.
|
||||
Filenames are relative to that filesystem.
|
||||
|
||||
The disk is passed as the last parameter. It must be a block device or raw
|
||||
disk image. More complex disk images (QCOW, VMDK, etc) must already be
|
||||
configured via blktap and presented as a block device.
|
||||
|
||||
The script writes an sxpr specifying the locations of the copied kernel and
|
||||
ramdisk into the file specified by --output (default is stdout).
|
||||
|
||||
Limitations:
|
||||
- It is assumed both kernel and ramdisk are on the same filesystem.
|
||||
- domUs might use LVM; the script currently does not have support for setting
|
||||
up LVM mappings for domUs; it's not trivial and we might risk namespace
|
||||
conflicts. If you want to use LVM inside domUs, set up a small non-LVM boot
|
||||
partition and specify it in bootentry.
|
||||
|
||||
Uses bootentry = [dev:]kernel[,initrd] to get a kernel [and initrd]
|
||||
from a domU filesystem to boot it for Xen.
|
||||
dev is the disk as seen by domU, filenames are relative to
|
||||
that filesystem. The script uses the disk settings from the
|
||||
config file to find the domU filesystems.
|
||||
The bootentry is passed to the script using --entry=
|
||||
Optionally, dev: can be omitted; the script then looks at the
|
||||
root filesystem, parses /etc/fstab to resolve the path to the
|
||||
kernel [and the initrd]. Obviously, the paths relative to the
|
||||
domU root filesystem needs to be specified for the kernel
|
||||
and initrd filenames.
|
||||
The script uses kpartx (multipath-tools) to create mappings for devices that
|
||||
are exported as whole disk devices that are partitioned.
|
||||
|
||||
The root FS is passed using --root=, the filesystem setup in
|
||||
--disks=. The disks list is a python list
|
||||
[[uname, dev, mode, backend], [uname, dev, mode, backend], ...]
|
||||
passed as a string. The script writes an sxpr specifying the
|
||||
locations of the copied kernel and initrd into the file
|
||||
specified by --output (default is stdout).
|
||||
|
||||
Limitations:
|
||||
- It is assumed both kernel and initrd are on the same filesystem.
|
||||
- domUs might use LVM; the script currently does not have support
|
||||
for setting up LVM mappings for domUs; it's not trivial and we
|
||||
might risk namespace conflicts. If you want to use LVM inside domUs,
|
||||
set up a small non-LVM boot partition and specify it in bootentry.
|
||||
|
||||
The script uses kpartx (multipath-tools) to create mappings for
|
||||
devices that are exported as whole disk devices that are partitioned.
|
||||
|
||||
(c) 01/2006 Novell Inc
|
||||
License: GNU GPL
|
||||
Author: Kurt Garloff <garloff@suse.de>
|
||||
(c) 01/2006 Novell Inc
|
||||
License: GNU GPL
|
||||
Author: Kurt Garloff <garloff@suse.de>
|
||||
"""
|
||||
|
||||
import os, sys, getopt
|
||||
@ -44,23 +40,21 @@ import time
|
||||
|
||||
# Global options
|
||||
quiet = False
|
||||
dryrun = False
|
||||
verbose = False
|
||||
dryrun = False
|
||||
tmpdir = '/var/lib/xen/tmp'
|
||||
|
||||
# List of partitions
|
||||
# It's created by setting up the all the devices from the xen disk
|
||||
# config; every entry creates on Wholedisk object, which does necessary
|
||||
# preparatory steps such as losetup and kpartx -a; then a Partition
|
||||
# object is setup for every partition (which may be one or several per
|
||||
# Wholedisk); it references the Wholedisk if needed; python reference
|
||||
# counting will take care of the cleanup.
|
||||
partitions = []
|
||||
|
||||
# Helper functions
|
||||
|
||||
def error(s):
|
||||
print >> sys.stderr, "domUloader error: %s" % s
|
||||
|
||||
def verbose_print(s):
|
||||
if verbose:
|
||||
print >> sys.stderr, "domUloader: %s" % s
|
||||
|
||||
def traildigits(strg):
|
||||
"Return the trailing digits, used to split the partition number off"
|
||||
"""Return the trailing digits, used to split the partition number off"""
|
||||
idx = len(strg)-1
|
||||
while strg[idx].isdigit():
|
||||
if len == 0:
|
||||
@ -68,33 +62,49 @@ def traildigits(strg):
|
||||
idx -= 1
|
||||
return strg[idx+1:]
|
||||
|
||||
def isWholedisk(domUname):
|
||||
"Determines whether dev is a wholedisk dev"
|
||||
return not domUname[-1:].isdigit()
|
||||
def getWholedisk(part):
|
||||
while len(part) and part[len(part)-1].isdigit():
|
||||
part = part[:-1]
|
||||
return part
|
||||
|
||||
#def isWholedisk(domUname):
|
||||
# """Determines whether dev is a wholedisk dev"""
|
||||
# return not domUname[-1:].isdigit()
|
||||
|
||||
def findPart(dev):
|
||||
"Find device dev in list of partitions"
|
||||
if len(dev) > 5 and dev[:5] == "/dev/":
|
||||
dev = dev[5:]
|
||||
for part in partitions:
|
||||
if dev == part.domname:
|
||||
return part
|
||||
return None
|
||||
|
||||
class Wholedisk:
|
||||
"Class representing a whole disk that has partitions"
|
||||
def __init__(self, domname, physdev, loopfile = None):
|
||||
"Class representing a whole disk that may have partitions"
|
||||
def __init__(self, vdev, pdev):
|
||||
"c'tor: set up"
|
||||
self.domname = domname
|
||||
self.physdev = physdev
|
||||
self.loopfile = loopfile
|
||||
self.mapped = 0
|
||||
self.pcount = self.scanpartitions()
|
||||
self.is_blk = (S_ISBLK(os.stat(pdev)[ST_MODE]))
|
||||
self.ldev = None
|
||||
self.vdev = vdev
|
||||
self.pdev = pdev
|
||||
self.mapped = 0
|
||||
self.partitions = []
|
||||
self.pcount = self.scanpartitions()
|
||||
|
||||
def physdev(self):
|
||||
"""Gets the physical device used to access the device from dom0"""
|
||||
if self.ldev:
|
||||
return self.ldev
|
||||
return self.pdev
|
||||
|
||||
def findPart(self, vdev):
|
||||
"Find device dev in list of partitions"
|
||||
if len(vdev) > 5 and vdev[:5] == "/dev/":
|
||||
vdev = vdev[5:]
|
||||
for part in self.partitions:
|
||||
if vdev == part.vdev:
|
||||
return part
|
||||
return None
|
||||
|
||||
def loopsetup(self):
|
||||
"Setup the loop mapping"
|
||||
if self.loopfile and not self.physdev:
|
||||
"""Sets up the loop mapping for a disk image.
|
||||
|
||||
Will raise if no loopbacks are available.
|
||||
"""
|
||||
if not self.is_blk and not self.ldev:
|
||||
# Loops through all loopback devices, attempting to
|
||||
# find a free one to set up. Don't scan for free and
|
||||
# then try to set it up as a separate step - too racy!
|
||||
@ -104,28 +114,29 @@ class Wholedisk:
|
||||
if not os.path.exists(ldev):
|
||||
break
|
||||
i += 1
|
||||
fd = os.popen("losetup %s %s 2> /dev/null" % (ldev, self.loopfile))
|
||||
fd = os.popen("losetup %s %s 2> /dev/null" % (ldev, self.pdev))
|
||||
if not fd.close():
|
||||
if verbose:
|
||||
print "domUloader: losetup %s %s" % (ldev, self.loopfile)
|
||||
self.physdev = ldev
|
||||
verbose_print("losetup %s %s" % (ldev, self.pdev))
|
||||
self.ldev = ldev
|
||||
break
|
||||
if not self.physdev:
|
||||
raise RuntimeError("domUloader: No free loop device found")
|
||||
if not self.ldev:
|
||||
raise RuntimeError("No free loop device found")
|
||||
|
||||
def loopclean(self):
|
||||
"Delete the loop mapping"
|
||||
if self.loopfile and self.physdev:
|
||||
if verbose:
|
||||
print "domUloader: losetup -d %s" % self.physdev
|
||||
"""Delete the loop mapping.
|
||||
|
||||
Will never raise.
|
||||
"""
|
||||
if self.ldev:
|
||||
verbose_print("losetup -d %s" % self.ldev)
|
||||
# Even seemingly innocent queries like "losetup /dev/loop0"
|
||||
# can temporarily block the loopback and cause transient
|
||||
# failures deleting the loopback, hence the retry logic.
|
||||
retries = 10
|
||||
while retries:
|
||||
fd = os.popen("losetup -d %s" % self.physdev)
|
||||
fd = os.popen("losetup -d %s" % self.ldev)
|
||||
if not fd.close():
|
||||
self.physdev = None
|
||||
self.ldev = None
|
||||
break
|
||||
else:
|
||||
time.sleep(0.1)
|
||||
@ -137,25 +148,27 @@ class Wholedisk:
|
||||
self.loopsetup()
|
||||
# TODO: We could use fdisk -l instead and look at the type of
|
||||
# partitions; this way we could also detect LVM and support it.
|
||||
fd = os.popen("kpartx -l %s" % self.physdev)
|
||||
fd = os.popen("kpartx -l %s" % self.physdev())
|
||||
pcount = 0
|
||||
for line in fd.readlines():
|
||||
line = line.strip()
|
||||
verbose_print("kpartx -l: %s" % (line,))
|
||||
(pname, params) = line.split(':')
|
||||
pno = int(traildigits(pname.strip()))
|
||||
#if pname.rfind('/') != -1:
|
||||
# pname = pname[pname.rfind('/')+1:]
|
||||
#pname = self.physdev[:self.physdev.rfind('/')] + '/' + pname
|
||||
#pname = self.pdev[:self.pdev.rfind('/')] + '/' + pname
|
||||
pname = "/dev/mapper/" + pname
|
||||
partitions.append(Partition(self, self.domname + '%i' % pno, pname))
|
||||
verbose_print("Found partition: vdev %s, pdev %s" % ('%s%i' % (self.vdev, pno), pname))
|
||||
self.partitions.append(Partition(self, '%s%i' % (self.vdev, pno), pname))
|
||||
pcount += 1
|
||||
fd.close()
|
||||
if not pcount:
|
||||
if self.loopfile:
|
||||
if self.ldev:
|
||||
ref = self
|
||||
else:
|
||||
ref = None
|
||||
partitions.append(Partition(ref, self.domname, self.physdev))
|
||||
self.partitions.append(Partition(ref, self.vdev, self.pdev))
|
||||
return pcount
|
||||
|
||||
def activatepartitions(self):
|
||||
@ -163,22 +176,23 @@ class Wholedisk:
|
||||
if not self.mapped:
|
||||
self.loopsetup()
|
||||
if self.pcount:
|
||||
if verbose:
|
||||
print "domUloader: kpartx -a %s" % self.physdev
|
||||
fd = os.popen("kpartx -a %s" % self.physdev)
|
||||
verbose_print("kpartx -a %s" % self.physdev())
|
||||
fd = os.popen("kpartx -a %s" % self.physdev())
|
||||
fd.close()
|
||||
self.mapped += 1
|
||||
|
||||
def deactivatepartitions(self):
|
||||
"Remove device-mapper mappings and loop mapping"
|
||||
"""Remove device-mapper mappings and loop mapping.
|
||||
|
||||
Will never raise.
|
||||
"""
|
||||
if not self.mapped:
|
||||
return
|
||||
self.mapped -= 1
|
||||
if not self.mapped:
|
||||
if self.pcount:
|
||||
if verbose:
|
||||
print "domUloader: kpartx -d %s" % self.physdev
|
||||
fd = os.popen("kpartx -d %s" % self.physdev)
|
||||
verbose_print("kpartx -d %s" % self.physdev())
|
||||
fd = os.popen("kpartx -d %s" % self.physdev())
|
||||
fd.close()
|
||||
self.loopclean()
|
||||
|
||||
@ -189,24 +203,20 @@ class Wholedisk:
|
||||
|
||||
def __repr__(self):
|
||||
"string representation for debugging"
|
||||
strg = "[" + self.domname + ","
|
||||
if self.physdev:
|
||||
strg += self.physdev
|
||||
strg += ","
|
||||
if self.loopfile:
|
||||
strg += self.loopfile
|
||||
strg = "[" + self.vdev + "," + self.pdev + ","
|
||||
if self.ldev:
|
||||
strg += self.ldev
|
||||
strg += "," + str(self.pcount) + ",mapped %ix]" % self.mapped
|
||||
return strg
|
||||
|
||||
class Partition:
|
||||
"""Class representing a domU filesystem (partition) that can be
|
||||
mounted in dom0"""
|
||||
def __init__(self, whole = None, domname = None,
|
||||
physdev = None):
|
||||
def __init__(self, whole = None, vdev = None, pdev = None):
|
||||
"c'tor: setup"
|
||||
self.wholedisk = whole
|
||||
self.domname = domname
|
||||
self.physdev = physdev
|
||||
self.wholedisk = whole
|
||||
self.vdev = vdev
|
||||
self.pdev = pdev
|
||||
self.mountpoint = None
|
||||
|
||||
def __del__(self):
|
||||
@ -219,7 +229,7 @@ class Partition:
|
||||
|
||||
def __repr__(self):
|
||||
"string representation for debugging"
|
||||
strg = "[" + self.domname + "," + self.physdev + ","
|
||||
strg = "[" + self.vdev + "," + self.pdev + ","
|
||||
if self.mountpoint:
|
||||
strg += "mounted on " + self.mountpoint + ","
|
||||
else:
|
||||
@ -235,171 +245,69 @@ class Partition:
|
||||
return
|
||||
if self.wholedisk:
|
||||
self.wholedisk.activatepartitions()
|
||||
mtpt = tempfile.mkdtemp(prefix = "%s." % self.domname, dir = tmpdir)
|
||||
mtpt = tempfile.mkdtemp(prefix = "%s." % self.vdev, dir = tmpdir)
|
||||
mopts = ""
|
||||
if fstype:
|
||||
mopts += " -t %s" % fstype
|
||||
mopts += " -o %s" % options
|
||||
if verbose:
|
||||
print "domUloader: mount %s %s %s" % (mopts, self.physdev, mtpt)
|
||||
fd = os.popen("mount %s %s %s" % (mopts, self.physdev, mtpt))
|
||||
verbose_print("mount %s %s %s" % (mopts, self.pdev, mtpt))
|
||||
fd = os.popen("mount %s %s %s" % (mopts, self.pdev, mtpt))
|
||||
err = fd.close()
|
||||
if err:
|
||||
raise RuntimeError("domUloader: Error %i from mount %s %s on %s" % \
|
||||
(err, mopts, self.physdev, mtpt))
|
||||
raise RuntimeError("Error %i from mount %s %s on %s" % \
|
||||
(err, mopts, self.pdev, mtpt))
|
||||
self.mountpoint = mtpt
|
||||
|
||||
def umount(self):
|
||||
"umount filesystem at self.mountpoint"
|
||||
"""umount filesystem at self.mountpoint"""
|
||||
if not self.mountpoint:
|
||||
return
|
||||
if verbose:
|
||||
print "domUloader: umount %s" % self.mountpoint
|
||||
verbose_print("umount %s" % self.mountpoint)
|
||||
fd = os.popen("umount %s" % self.mountpoint)
|
||||
err = fd.close()
|
||||
os.rmdir(self.mountpoint)
|
||||
try:
|
||||
os.rmdir(self.mountpoint)
|
||||
except:
|
||||
pass
|
||||
if err:
|
||||
raise RuntimeError("domUloader: Error %i from umount %s" % \
|
||||
(err, self.mountpoint))
|
||||
self.mountpoint = None
|
||||
error("Error %i from umount %s" % (err, self.mountpoint))
|
||||
else:
|
||||
self.mountpoint = None
|
||||
if self.wholedisk:
|
||||
self.wholedisk.deactivatepartitions()
|
||||
|
||||
|
||||
def setupOneDisk(cfg):
|
||||
"""Sets up one exported disk (incl. partitions if existing)
|
||||
@param cfg: 4-tuple (uname, dev, mode, backend)"""
|
||||
from xen.util.blkif import blkdev_uname_to_file
|
||||
values = cfg[0].split(':')
|
||||
if len(values) == 2:
|
||||
(type, dev) = values
|
||||
else:
|
||||
(type, subtype, dev) = values
|
||||
(loopfile, physdev) = (None, None)
|
||||
if type == "tap":
|
||||
if subtype == "aio":
|
||||
# FIXME: if device, "/dev/" may need to be prepended
|
||||
mode = os.stat(dev)[ST_MODE]
|
||||
if S_ISBLK(mode):
|
||||
physdev = dev
|
||||
else:
|
||||
loopfile = dev
|
||||
else:
|
||||
raise RuntimeError("domUloader: domUloader supports 'tap' only with 'aio'.")
|
||||
if type == "file":
|
||||
loopfile = dev
|
||||
elif type == "phy":
|
||||
physdev = blkdev_uname_to_file(cfg[0])
|
||||
wdisk = Wholedisk(cfg[1], physdev, loopfile)
|
||||
|
||||
def setupDisks(vbds):
|
||||
"""Create a list of all disks from the disk config:
|
||||
@param vbds: The disk config as list of 4-tuples
|
||||
(uname, dev, mode, backend)"""
|
||||
disks = eval(vbds)
|
||||
for disk in disks:
|
||||
setupOneDisk(disk)
|
||||
if verbose:
|
||||
print "Partitions: " + str(partitions)
|
||||
|
||||
class Fstab:
|
||||
"Class representing an fstab"
|
||||
|
||||
class FstabEntry:
|
||||
"Class representing one fstab line"
|
||||
def __init__(self, line):
|
||||
"c'tor: parses one line"
|
||||
spline = line.split()
|
||||
self.dev, self.mtpt, self.fstype, self.opts = \
|
||||
spline[0], spline[1], spline[2], spline[3]
|
||||
if len(self.mtpt) > 1:
|
||||
self.mtpt = self.mtpt.rstrip('/')
|
||||
|
||||
def __init__(self, filename):
|
||||
"c'tor: parses fstab"
|
||||
self.entries = []
|
||||
fd = open(filename)
|
||||
for line in fd.readlines():
|
||||
line = line.strip()
|
||||
if len(line) == 0 or line[0] == '#':
|
||||
continue
|
||||
self.entries.append(Fstab.FstabEntry(line))
|
||||
|
||||
def find(self, fname):
|
||||
"Looks for matching filesystem in fstab"
|
||||
matchlen = 0
|
||||
match = None
|
||||
fnmlst = fname.split('/')
|
||||
for fs in self.entries:
|
||||
entlst = fs.mtpt.split('/')
|
||||
# '/' needs special treatment :-(
|
||||
if entlst == ['','']:
|
||||
entlst = ['']
|
||||
entln = len(entlst)
|
||||
if len(fnmlst) >= entln and fnmlst[:entln] == entlst \
|
||||
and entln > matchlen:
|
||||
match = fs
|
||||
matchlen = entln
|
||||
if not match:
|
||||
return (None, None)
|
||||
return (match.dev, match.mtpt)
|
||||
|
||||
def fsFromFstab(kernel, initrd, root):
|
||||
"""Investigate rootFS fstab, check for filesystem that contains the kernel
|
||||
and return it; also returns adapted kernel and initrd path.
|
||||
"""
|
||||
part = findPart(root)
|
||||
if not part:
|
||||
raise RuntimeError("domUloader: Root fs %s not exported?" % root)
|
||||
part.mount()
|
||||
if not os.access(part.mountpoint + '/etc/fstab', os.R_OK):
|
||||
part.umount()
|
||||
raise RuntimeError("domUloader: /etc/fstab not found on %s" % root)
|
||||
fstab = Fstab(part.mountpoint + '/etc/fstab')
|
||||
(dev, fs) = fstab.find(kernel)
|
||||
if not fs:
|
||||
raise RuntimeError("domUloader: no matching filesystem for image %s found in fstab" % kernel)
|
||||
#return (None, kernel, initrd)
|
||||
if fs == '/':
|
||||
ln = 0
|
||||
# this avoids the stupid /dev/root problem
|
||||
dev = root
|
||||
else:
|
||||
ln = len(fs)
|
||||
kernel = kernel[ln:]
|
||||
if initrd:
|
||||
initrd = initrd[ln:]
|
||||
if verbose:
|
||||
print "fsFromFstab: %s %s -- %s,%s" % (dev, fs, kernel, initrd)
|
||||
return (kernel, initrd, dev)
|
||||
|
||||
def parseEntry(entry):
|
||||
"disects bootentry and returns kernel, initrd, filesys"
|
||||
fs = None
|
||||
initrd = None
|
||||
"disects bootentry and returns vdev, kernel, ramdisk"
|
||||
def bad():
|
||||
raise RuntimeError, "Malformed --entry"
|
||||
fsspl = entry.split(':')
|
||||
if len(fsspl) > 1:
|
||||
fs = fsspl[0]
|
||||
entry = fsspl[1]
|
||||
if len(fsspl) != 2:
|
||||
bad()
|
||||
vdev = fsspl[0]
|
||||
entry = fsspl[1]
|
||||
enspl = entry.split(',')
|
||||
if len(enspl) not in (1, 2):
|
||||
bad()
|
||||
# Prepend '/' if missing
|
||||
kernel = enspl[0]
|
||||
if kernel == '':
|
||||
bad()
|
||||
if kernel[0] != '/':
|
||||
kernel = '/' + kernel
|
||||
ramdisk = None
|
||||
if len(enspl) > 1:
|
||||
initrd = enspl[1]
|
||||
if initrd[0] != '/':
|
||||
initrd = '/' + initrd
|
||||
return kernel, initrd, fs
|
||||
ramdisk = enspl[1]
|
||||
if ramdisk != '' and ramdisk[0] != '/':
|
||||
ramdisk = '/' + ramdisk
|
||||
return vdev, kernel, ramdisk
|
||||
|
||||
def copyFile(src, dst):
|
||||
"Wrapper for shutil.filecopy"
|
||||
import shutil
|
||||
if verbose:
|
||||
print "domUloader: cp %s %s" % (src, dst)
|
||||
verbose_print("cp %s %s" % (src, dst))
|
||||
stat = os.stat(src)
|
||||
if stat.st_size > 16*1024*1024:
|
||||
raise RuntimeError("domUloader: Too large file %s (%s larger than 16MB)" \
|
||||
raise RuntimeError("Too large file %s (%s larger than 16MB)" \
|
||||
% (src, stat.st_size))
|
||||
try:
|
||||
shutil.copyfile(src, dst)
|
||||
@ -407,36 +315,37 @@ def copyFile(src, dst):
|
||||
os.unlink(dst)
|
||||
raise()
|
||||
|
||||
def copyKernelAndInitrd(fs, kernel, initrd):
|
||||
"""Finds fs in list of partitions, mounts the partition, copies
|
||||
kernel [and initrd] off to dom0 files, umounts the parition again,
|
||||
def copyKernelAndRamdisk(disk, vdev, kernel, ramdisk):
|
||||
"""Finds vdev in list of partitions, mounts the partition, copies
|
||||
kernel [and ramdisk] off to dom0 files, umounts the parition again,
|
||||
and returns sxpr pointing to these copies."""
|
||||
verbose_print("copyKernelAndRamdisk(%s, %s, %s, %s)" % (disk, vdev, kernel, ramdisk))
|
||||
if dryrun:
|
||||
return "linux (kernel vmlinuz.dummy) (ramdisk initrd.dummy)"
|
||||
import shutil
|
||||
part = findPart(fs)
|
||||
return "linux (kernel kernel.dummy) (ramdisk ramdisk.dummy)"
|
||||
part = disk.findPart(vdev)
|
||||
if not part:
|
||||
raise RuntimeError("domUloader: Filesystem %s not exported\n" % fs)
|
||||
raise RuntimeError("Partition '%s' does not exist" % vdev)
|
||||
part.mount()
|
||||
try:
|
||||
(fd, knm) = tempfile.mkstemp(prefix = "vmlinuz.", dir = tmpdir)
|
||||
(fd, knm) = tempfile.mkstemp(prefix = "kernel.", dir = tmpdir)
|
||||
os.close(fd)
|
||||
copyFile(part.mountpoint + kernel, knm)
|
||||
except:
|
||||
os.unlink(knm)
|
||||
part.umount()
|
||||
raise
|
||||
if not quiet:
|
||||
print "Copy kernel %s from %s to %s for booting" % \
|
||||
(kernel, fs, knm)
|
||||
print "Copy kernel %s from %s to %s for booting" % (kernel, vdev, knm)
|
||||
sxpr = "linux (kernel %s)" % knm
|
||||
if (initrd):
|
||||
if ramdisk:
|
||||
try:
|
||||
(fd, inm) = tempfile.mkstemp(prefix = "initrd.", dir = tmpdir)
|
||||
(fd, inm) = tempfile.mkstemp(prefix = "ramdisk.", dir = tmpdir)
|
||||
os.close(fd)
|
||||
copyFile(part.mountpoint + initrd, inm)
|
||||
copyFile(part.mountpoint + ramdisk, inm)
|
||||
except:
|
||||
os.unlink(knm)
|
||||
os.unlink(inm)
|
||||
part.umount()
|
||||
raise
|
||||
sxpr += "(ramdisk %s)" % inm
|
||||
part.umount()
|
||||
@ -448,46 +357,49 @@ def main(argv):
|
||||
def usage():
|
||||
"Help output (usage info)"
|
||||
global verbose, quiet, dryrun
|
||||
print >> sys.stderr, "domUloader usage: domUloader --disks=disklist [--root=rootFS]\n" \
|
||||
+ " --entry=kernel[,initrd] [--output=fd] [--quiet] [--dryrun] [--verbose] [--help]\n"
|
||||
print >> sys.stderr, "domUloader usage: domUloader [--output=fd] [--quiet] [--dryrun] [--verbose]\n" +\
|
||||
"[--help] --entry=dev:kernel[,ramdisk] physdisk [virtdisk]\n"
|
||||
print >> sys.stderr, __doc__
|
||||
|
||||
#print "domUloader " + str(argv)
|
||||
try:
|
||||
(optlist, args) = getopt.gnu_getopt(argv, 'qvh', \
|
||||
('disks=', 'root=', 'entry=', 'output=',
|
||||
'tmpdir=', 'help', 'quiet', 'dryrun', 'verbose'))
|
||||
('entry=', 'output=', 'tmpdir=', 'help', 'quiet', 'dryrun', 'verbose'))
|
||||
except:
|
||||
usage()
|
||||
sys.exit(1)
|
||||
|
||||
entry = None
|
||||
output = None
|
||||
root = None
|
||||
disks = None
|
||||
pdisk = None
|
||||
vdisk = None
|
||||
|
||||
for (opt, oarg) in optlist:
|
||||
if opt in ('-h', '--help'):
|
||||
usage()
|
||||
sys.exit(0)
|
||||
sys.exit(1)
|
||||
elif opt in ('-q', '--quiet'):
|
||||
quiet = True
|
||||
elif opt in ('-n', '--dryrun'):
|
||||
dryrun = True
|
||||
elif opt in ('-v', '--verbose'):
|
||||
verbose = True
|
||||
elif opt == '--root':
|
||||
root = oarg
|
||||
elif opt == '--output':
|
||||
output = oarg
|
||||
elif opt == '--disks':
|
||||
disks = oarg
|
||||
elif opt == '--entry':
|
||||
entry = oarg
|
||||
elif opt == '--tmpdir':
|
||||
tmpdir = oarg
|
||||
|
||||
if not entry or not disks:
|
||||
verbose_print(str(argv))
|
||||
|
||||
if args:
|
||||
if len(args) == 2:
|
||||
pdisk = args[1]
|
||||
elif len(args) == 3:
|
||||
pdisk = args[1]
|
||||
vdisk = args[2]
|
||||
|
||||
if not entry or not pdisk:
|
||||
usage()
|
||||
sys.exit(1)
|
||||
|
||||
@ -500,22 +412,34 @@ def main(argv):
|
||||
os.mkdir(tmpdir)
|
||||
os.chmod(tmpdir, 0750)
|
||||
|
||||
# We assume kernel and initrd are on the same FS,
|
||||
# so only one fs
|
||||
kernel, initrd, fs = parseEntry(entry)
|
||||
setupDisks(disks)
|
||||
if not fs:
|
||||
if not root:
|
||||
usage()
|
||||
raise RuntimeError("domUloader: No root= to parse fstab and no disk in bootentry")
|
||||
sys.exit(1)
|
||||
kernel, initrd, fs = fsFromFstab(kernel, initrd, root)
|
||||
vdev, kernel, ramdisk = parseEntry(entry)
|
||||
if not vdisk:
|
||||
vdisk = getWholedisk(vdev)
|
||||
verbose_print("vdisk not specified; guessing '%s' based on '%s'" % (vdisk, vdev))
|
||||
if not vdev.startswith(vdisk):
|
||||
error("Virtual disk '%s' does not match entry '%s'" % (vdisk, entry))
|
||||
sys.exit(1)
|
||||
disk = Wholedisk(vdisk, pdisk)
|
||||
|
||||
sxpr = copyKernelAndInitrd(fs, kernel, initrd)
|
||||
sys.stdout.flush()
|
||||
os.write(fd, sxpr)
|
||||
r = 0
|
||||
try:
|
||||
sxpr = copyKernelAndRamdisk(disk, vdev, kernel, ramdisk)
|
||||
os.write(fd, sxpr)
|
||||
except Exception, e:
|
||||
error(str(e))
|
||||
r = 1
|
||||
|
||||
for part in disk.partitions:
|
||||
part.wholedisk = None
|
||||
del disk
|
||||
|
||||
return r
|
||||
|
||||
# Call main if called (and not imported)
|
||||
if __name__ == "__main__":
|
||||
main(sys.argv)
|
||||
|
||||
r = 1
|
||||
try:
|
||||
r = main(sys.argv)
|
||||
except Exception, e:
|
||||
error(str(e))
|
||||
sys.exit(r)
|
||||
|
168
domheap-no-dma.patch
Normal file
168
domheap-no-dma.patch
Normal file
@ -0,0 +1,168 @@
|
||||
Index: xen-3.0.4-testing/xen/arch/x86/domain_build.c
|
||||
===================================================================
|
||||
--- xen-3.0.4-testing.orig/xen/arch/x86/domain_build.c
|
||||
+++ xen-3.0.4-testing/xen/arch/x86/domain_build.c
|
||||
@@ -473,11 +473,14 @@ int construct_dom0(struct domain *d,
|
||||
if ( (1UL << order) > nr_pages )
|
||||
panic("Domain 0 allocation is too small for kernel image.\n");
|
||||
|
||||
- /*
|
||||
- * Allocate from DMA pool: on i386 this ensures that our low-memory 1:1
|
||||
- * mapping covers the allocation.
|
||||
- */
|
||||
- if ( (page = alloc_domheap_pages(d, order, MEMF_dma)) == NULL )
|
||||
+#ifdef __i386__
|
||||
+ /* Ensure that our low-memory 1:1 mapping covers the allocation. */
|
||||
+ page = alloc_domheap_pages(d, order,
|
||||
+ MEMF_bits(30 + (dsi.v_start >> 31)));
|
||||
+#else
|
||||
+ page = alloc_domheap_pages(d, order, 0);
|
||||
+#endif
|
||||
+ if ( page == NULL )
|
||||
panic("Not enough RAM for domain 0 allocation.\n");
|
||||
alloc_spfn = page_to_mfn(page);
|
||||
alloc_epfn = alloc_spfn + d->tot_pages;
|
||||
Index: xen-3.0.4-testing/xen/common/memory.c
|
||||
===================================================================
|
||||
--- xen-3.0.4-testing.orig/xen/common/memory.c
|
||||
+++ xen-3.0.4-testing/xen/common/memory.c
|
||||
@@ -322,12 +322,12 @@ static long memory_exchange(XEN_GUEST_HA
|
||||
(exch.out.address_bits <
|
||||
(get_order_from_pages(max_page) + PAGE_SHIFT)) )
|
||||
{
|
||||
- if ( exch.out.address_bits < dma_bitsize )
|
||||
+ if ( exch.out.address_bits <= PAGE_SHIFT )
|
||||
{
|
||||
rc = -ENOMEM;
|
||||
goto fail_early;
|
||||
}
|
||||
- memflags = MEMF_dma;
|
||||
+ memflags = MEMF_bits(exch.out.address_bits);
|
||||
}
|
||||
|
||||
if ( exch.in.extent_order <= exch.out.extent_order )
|
||||
@@ -535,9 +535,9 @@ long do_memory_op(unsigned long cmd, XEN
|
||||
(reservation.address_bits <
|
||||
(get_order_from_pages(max_page) + PAGE_SHIFT)) )
|
||||
{
|
||||
- if ( reservation.address_bits < dma_bitsize )
|
||||
+ if ( reservation.address_bits <= PAGE_SHIFT )
|
||||
return start_extent;
|
||||
- args.memflags = MEMF_dma;
|
||||
+ args.memflags = MEMF_bits(reservation.address_bits);
|
||||
}
|
||||
|
||||
if ( likely(reservation.domid == DOMID_SELF) )
|
||||
Index: xen-3.0.4-testing/xen/common/page_alloc.c
|
||||
===================================================================
|
||||
--- xen-3.0.4-testing.orig/xen/common/page_alloc.c
|
||||
+++ xen-3.0.4-testing/xen/common/page_alloc.c
|
||||
@@ -62,8 +62,8 @@ custom_param("lowmem_emergency_pool", pa
|
||||
/*
|
||||
* Bit width of the DMA heap.
|
||||
*/
|
||||
-unsigned int dma_bitsize = CONFIG_DMA_BITSIZE;
|
||||
-unsigned long max_dma_mfn = (1UL << (CONFIG_DMA_BITSIZE - PAGE_SHIFT)) - 1;
|
||||
+static unsigned int dma_bitsize = CONFIG_DMA_BITSIZE;
|
||||
+static unsigned long max_dma_mfn = (1UL << (CONFIG_DMA_BITSIZE - PAGE_SHIFT)) - 1;
|
||||
static void parse_dma_bits(char *s)
|
||||
{
|
||||
unsigned int v = simple_strtol(s, NULL, 0);
|
||||
@@ -72,7 +72,7 @@ static void parse_dma_bits(char *s)
|
||||
dma_bitsize = BITS_PER_LONG + PAGE_SHIFT;
|
||||
max_dma_mfn = ~0UL;
|
||||
}
|
||||
- else if ( v > PAGE_SHIFT )
|
||||
+ else if ( v > PAGE_SHIFT + 1 )
|
||||
{
|
||||
dma_bitsize = v;
|
||||
max_dma_mfn = (1UL << (dma_bitsize - PAGE_SHIFT)) - 1;
|
||||
@@ -725,12 +725,22 @@ struct page_info *__alloc_domheap_pages(
|
||||
struct page_info *pg = NULL;
|
||||
cpumask_t mask;
|
||||
unsigned long i;
|
||||
+ unsigned int bits = memflags >> _MEMF_bits, zone_hi;
|
||||
|
||||
ASSERT(!in_irq());
|
||||
|
||||
- if ( !(memflags & MEMF_dma) )
|
||||
+ if ( bits && bits <= PAGE_SHIFT + 1 )
|
||||
+ return NULL;
|
||||
+
|
||||
+ zone_hi = bits - PAGE_SHIFT - 1;
|
||||
+ if ( zone_hi >= NR_ZONES )
|
||||
+ zone_hi = NR_ZONES - 1;
|
||||
+
|
||||
+ if ( NR_ZONES + PAGE_SHIFT > dma_bitsize &&
|
||||
+ (!bits || bits > dma_bitsize) )
|
||||
{
|
||||
- pg = alloc_heap_pages(dma_bitsize - PAGE_SHIFT, NR_ZONES - 1, cpu, order);
|
||||
+ pg = alloc_heap_pages(dma_bitsize - PAGE_SHIFT, zone_hi, cpu, order);
|
||||
+
|
||||
/* Failure? Then check if we can fall back to the DMA pool. */
|
||||
if ( unlikely(pg == NULL) &&
|
||||
((order > MAX_ORDER) ||
|
||||
@@ -743,7 +753,7 @@ struct page_info *__alloc_domheap_pages(
|
||||
|
||||
if ( pg == NULL )
|
||||
if ( (pg = alloc_heap_pages(MEMZONE_XEN + 1,
|
||||
- dma_bitsize - PAGE_SHIFT - 1,
|
||||
+ zone_hi,
|
||||
cpu, order)) == NULL )
|
||||
return NULL;
|
||||
|
||||
Index: xen-3.0.4-testing/xen/include/asm-ia64/config.h
|
||||
===================================================================
|
||||
--- xen-3.0.4-testing.orig/xen/include/asm-ia64/config.h
|
||||
+++ xen-3.0.4-testing/xen/include/asm-ia64/config.h
|
||||
@@ -41,7 +41,7 @@
|
||||
#define CONFIG_IOSAPIC
|
||||
#define supervisor_mode_kernel (0)
|
||||
|
||||
-#define CONFIG_DMA_BITSIZE 30
|
||||
+#define CONFIG_DMA_BITSIZE 32
|
||||
|
||||
/* If PERFC is used, include privop maps. */
|
||||
#ifdef PERF_COUNTERS
|
||||
Index: xen-3.0.4-testing/xen/include/asm-x86/config.h
|
||||
===================================================================
|
||||
--- xen-3.0.4-testing.orig/xen/include/asm-x86/config.h
|
||||
+++ xen-3.0.4-testing/xen/include/asm-x86/config.h
|
||||
@@ -82,7 +82,7 @@
|
||||
/* Debug stack is restricted to 8kB by guard pages. */
|
||||
#define DEBUG_STACK_SIZE 8192
|
||||
|
||||
-#define CONFIG_DMA_BITSIZE 30
|
||||
+#define CONFIG_DMA_BITSIZE 32
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
extern unsigned long _end; /* standard ELF symbol */
|
||||
Index: xen-3.0.4-testing/xen/include/xen/mm.h
|
||||
===================================================================
|
||||
--- xen-3.0.4-testing.orig/xen/include/xen/mm.h
|
||||
+++ xen-3.0.4-testing/xen/include/xen/mm.h
|
||||
@@ -71,10 +71,10 @@ int assign_pages(
|
||||
unsigned int memflags);
|
||||
|
||||
/* memflags: */
|
||||
-#define _MEMF_dma 0
|
||||
-#define MEMF_dma (1U<<_MEMF_dma)
|
||||
-#define _MEMF_no_refcount 1
|
||||
+#define _MEMF_no_refcount 0
|
||||
#define MEMF_no_refcount (1U<<_MEMF_no_refcount)
|
||||
+#define _MEMF_bits 24
|
||||
+#define MEMF_bits(n) ((n)<<_MEMF_bits)
|
||||
|
||||
#ifdef CONFIG_PAGEALLOC_MAX_ORDER
|
||||
#define MAX_ORDER CONFIG_PAGEALLOC_MAX_ORDER
|
||||
@@ -82,10 +82,6 @@ int assign_pages(
|
||||
#define MAX_ORDER 20 /* 2^20 contiguous pages */
|
||||
#endif
|
||||
|
||||
-/* DMA heap parameters. */
|
||||
-extern unsigned int dma_bitsize;
|
||||
-extern unsigned long max_dma_mfn;
|
||||
-
|
||||
/* Automatic page scrubbing for dead domains. */
|
||||
extern struct list_head page_scrub_list;
|
||||
#define page_scrub_schedule_work() \
|
76
emul-privop-lock.patch
Normal file
76
emul-privop-lock.patch
Normal file
@ -0,0 +1,76 @@
|
||||
Index: 2007-01-31/xen/arch/x86/traps.c
|
||||
===================================================================
|
||||
--- 2007-01-31.orig/xen/arch/x86/traps.c 2007-01-31 09:41:46.000000000 +0100
|
||||
+++ 2007-01-31/xen/arch/x86/traps.c 2007-01-31 09:41:54.000000000 +0100
|
||||
@@ -1196,7 +1196,7 @@ static int emulate_privileged_op(struct
|
||||
{
|
||||
struct vcpu *v = current;
|
||||
unsigned long *reg, eip = regs->eip, res;
|
||||
- u8 opcode, modrm_reg = 0, modrm_rm = 0, rep_prefix = 0, rex = 0;
|
||||
+ u8 opcode, modrm_reg = 0, modrm_rm = 0, rep_prefix = 0, lock = 0, rex = 0;
|
||||
enum { lm_seg_none, lm_seg_fs, lm_seg_gs } lm_ovr = lm_seg_none;
|
||||
unsigned int port, i, data_sel, ar, data, rc;
|
||||
unsigned int op_bytes, op_default, ad_bytes, ad_default;
|
||||
@@ -1261,6 +1261,7 @@ static int emulate_privileged_op(struct
|
||||
data_sel = regs->ss;
|
||||
continue;
|
||||
case 0xf0: /* LOCK */
|
||||
+ lock = 1;
|
||||
continue;
|
||||
case 0xf2: /* REPNE/REPNZ */
|
||||
case 0xf3: /* REP/REPE/REPZ */
|
||||
@@ -1287,6 +1288,9 @@ static int emulate_privileged_op(struct
|
||||
if ( opcode == 0x0f )
|
||||
goto twobyte_opcode;
|
||||
|
||||
+ if ( lock )
|
||||
+ goto fail;
|
||||
+
|
||||
/* Input/Output String instructions. */
|
||||
if ( (opcode >= 0x6c) && (opcode <= 0x6f) )
|
||||
{
|
||||
@@ -1550,6 +1554,8 @@ static int emulate_privileged_op(struct
|
||||
|
||||
/* Privileged (ring 0) instructions. */
|
||||
opcode = insn_fetch(u8, code_base, eip, code_limit);
|
||||
+ if ( lock && (opcode & ~3) != 0x20 )
|
||||
+ goto fail;
|
||||
switch ( opcode )
|
||||
{
|
||||
case 0x06: /* CLTS */
|
||||
@@ -1568,7 +1574,7 @@ static int emulate_privileged_op(struct
|
||||
|
||||
case 0x20: /* MOV CR?,<reg> */
|
||||
opcode = insn_fetch(u8, code_base, eip, code_limit);
|
||||
- modrm_reg |= (opcode >> 3) & 7;
|
||||
+ modrm_reg += ((opcode >> 3) & 7) + (lock << 3);
|
||||
modrm_rm |= (opcode >> 0) & 7;
|
||||
reg = decode_register(modrm_rm, regs, 0);
|
||||
switch ( modrm_reg )
|
||||
@@ -1608,7 +1614,7 @@ static int emulate_privileged_op(struct
|
||||
|
||||
case 0x21: /* MOV DR?,<reg> */
|
||||
opcode = insn_fetch(u8, code_base, eip, code_limit);
|
||||
- modrm_reg |= (opcode >> 3) & 7;
|
||||
+ modrm_reg += ((opcode >> 3) & 7) + (lock << 3);
|
||||
modrm_rm |= (opcode >> 0) & 7;
|
||||
reg = decode_register(modrm_rm, regs, 0);
|
||||
if ( (res = do_get_debugreg(modrm_reg)) > (unsigned long)-256 )
|
||||
@@ -1618,7 +1624,7 @@ static int emulate_privileged_op(struct
|
||||
|
||||
case 0x22: /* MOV <reg>,CR? */
|
||||
opcode = insn_fetch(u8, code_base, eip, code_limit);
|
||||
- modrm_reg |= (opcode >> 3) & 7;
|
||||
+ modrm_reg += ((opcode >> 3) & 7) + (lock << 3);
|
||||
modrm_rm |= (opcode >> 0) & 7;
|
||||
reg = decode_register(modrm_rm, regs, 0);
|
||||
switch ( modrm_reg )
|
||||
@@ -1666,7 +1672,7 @@ static int emulate_privileged_op(struct
|
||||
|
||||
case 0x23: /* MOV <reg>,DR? */
|
||||
opcode = insn_fetch(u8, code_base, eip, code_limit);
|
||||
- modrm_reg |= (opcode >> 3) & 7;
|
||||
+ modrm_reg += ((opcode >> 3) & 7) + (lock << 3);
|
||||
modrm_rm |= (opcode >> 0) & 7;
|
||||
reg = decode_register(modrm_rm, regs, 0);
|
||||
if ( do_set_debugreg(modrm_reg, *reg) != 0 )
|
158
fbback-bimodal.diff
Normal file
158
fbback-bimodal.diff
Normal file
@ -0,0 +1,158 @@
|
||||
bimodal: pvfb backend
|
||||
|
||||
Teach pvfb backend to deal with bith 32 and 64 bit frontends.
|
||||
|
||||
Signed-off-by: Gerd Hoffmann <kraxel@suse.de>
|
||||
---
|
||||
tools/xenfb/xenfb.c | 98 ++++++++++++++++++++++++++++++++++++++++++++++------
|
||||
1 file changed, 87 insertions(+), 11 deletions(-)
|
||||
|
||||
Index: build-32-release304-13133/tools/xenfb/xenfb.c
|
||||
===================================================================
|
||||
--- build-32-release304-13133.orig/tools/xenfb/xenfb.c
|
||||
+++ build-32-release304-13133/tools/xenfb/xenfb.c
|
||||
@@ -7,6 +7,7 @@
|
||||
#include <xen/io/xenbus.h>
|
||||
#include <xen/io/fbif.h>
|
||||
#include <xen/io/kbdif.h>
|
||||
+#include <xen/io/protocols.h>
|
||||
#include <sys/select.h>
|
||||
#include <stdbool.h>
|
||||
#include <xen/linux/evtchn.h>
|
||||
@@ -40,6 +41,7 @@ struct xenfb_private {
|
||||
struct xs_handle *xsh; /* xs daemon handle */
|
||||
struct xenfb_device fb, kbd;
|
||||
size_t fb_len; /* size of framebuffer */
|
||||
+ char protocol[64]; /* frontend protocol */
|
||||
};
|
||||
|
||||
static void xenfb_detach_dom(struct xenfb_private *);
|
||||
@@ -324,36 +326,107 @@ static int xenfb_wait_for_frontend_initi
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static void xenfb_copy_mfns(int mode, int count, unsigned long *dst, void *src)
|
||||
+{
|
||||
+ uint32_t *src32 = src;
|
||||
+ uint64_t *src64 = src;
|
||||
+ int i;
|
||||
+
|
||||
+ for (i = 0; i < count; i++)
|
||||
+ dst[i] = (mode == 32) ? src32[i] : src64[i];
|
||||
+}
|
||||
+
|
||||
static int xenfb_map_fb(struct xenfb_private *xenfb, int domid)
|
||||
{
|
||||
struct xenfb_page *page = xenfb->fb.page;
|
||||
int n_fbmfns;
|
||||
int n_fbdirs;
|
||||
- unsigned long *fbmfns;
|
||||
+ unsigned long *pgmfns = NULL;
|
||||
+ unsigned long *fbmfns = NULL;
|
||||
+ void *map, *pd;
|
||||
+ int mode, ret = -1;
|
||||
+
|
||||
+ /* default to native */
|
||||
+ pd = page->pd;
|
||||
+ mode = sizeof(unsigned long) * 8;
|
||||
+
|
||||
+ if (0 == strlen(xenfb->protocol)) {
|
||||
+ /*
|
||||
+ * Undefined protocol, some guesswork needed.
|
||||
+ *
|
||||
+ * Old frontends which don't set the protocol use
|
||||
+ * one page directory only, thus pd[1] must be zero.
|
||||
+ * pd[1] of the 32bit struct layout and the lower
|
||||
+ * 32 bits of pd[0] of the 64bit struct layout have
|
||||
+ * the same location, so we can check that ...
|
||||
+ */
|
||||
+ uint32_t *ptr32 = NULL;
|
||||
+ uint32_t *ptr64 = NULL;
|
||||
+#if defined(__i386__)
|
||||
+ ptr32 = (void*)page->pd;
|
||||
+ ptr64 = ((void*)page->pd) + 4;
|
||||
+#elif defined(__x86_64__)
|
||||
+ ptr32 = ((void*)page->pd) - 4;
|
||||
+ ptr64 = (void*)page->pd;
|
||||
+#endif
|
||||
+ if (ptr32) {
|
||||
+ if (0 == ptr32[1]) {
|
||||
+ mode = 32;
|
||||
+ pd = ptr32;
|
||||
+ } else {
|
||||
+ mode = 64;
|
||||
+ pd = ptr64;
|
||||
+ }
|
||||
+ }
|
||||
+#if defined(__x86_64__)
|
||||
+ } else if (0 == strcmp(xenfb->protocol, XEN_IO_PROTO_ABI_X86_32)) {
|
||||
+ /* 64bit dom0, 32bit domU */
|
||||
+ mode = 32;
|
||||
+ pd = ((void*)page->pd) - 4;
|
||||
+#elif defined(__i386__)
|
||||
+ } else if (0 == strcmp(xenfb->protocol, XEN_IO_PROTO_ABI_X86_64)) {
|
||||
+ /* 32bit dom0, 64bit domU */
|
||||
+ mode = 64;
|
||||
+ pd = ((void*)page->pd) + 4;
|
||||
+#endif
|
||||
+ }
|
||||
|
||||
n_fbmfns = (xenfb->fb_len + (XC_PAGE_SIZE - 1)) / XC_PAGE_SIZE;
|
||||
- n_fbdirs = n_fbmfns * sizeof(unsigned long);
|
||||
+ n_fbdirs = n_fbmfns * mode / 8;
|
||||
n_fbdirs = (n_fbdirs + (XC_PAGE_SIZE - 1)) / XC_PAGE_SIZE;
|
||||
|
||||
+ pgmfns = malloc(sizeof(unsigned long) * n_fbdirs);
|
||||
+ fbmfns = malloc(sizeof(unsigned long) * n_fbmfns);
|
||||
+ if (!pgmfns || !fbmfns)
|
||||
+ goto out;
|
||||
+
|
||||
/*
|
||||
* Bug alert: xc_map_foreign_batch() can fail partly and
|
||||
* return a non-null value. This is a design flaw. When it
|
||||
* happens, we happily continue here, and later crash on
|
||||
* access.
|
||||
*/
|
||||
- fbmfns = xc_map_foreign_batch(xenfb->xc, domid,
|
||||
- PROT_READ, page->pd, n_fbdirs);
|
||||
- if (fbmfns == NULL)
|
||||
- return -1;
|
||||
+ xenfb_copy_mfns(mode, n_fbdirs, pgmfns, pd);
|
||||
+ map = xc_map_foreign_batch(xenfb->xc, domid,
|
||||
+ PROT_READ, pgmfns, n_fbdirs);
|
||||
+ if (map == NULL)
|
||||
+ goto out;
|
||||
+ xenfb_copy_mfns(mode, n_fbmfns, fbmfns, map);
|
||||
+ munmap(map, n_fbdirs * XC_PAGE_SIZE);
|
||||
|
||||
xenfb->pub.pixels = xc_map_foreign_batch(xenfb->xc, domid,
|
||||
PROT_READ | PROT_WRITE, fbmfns, n_fbmfns);
|
||||
- if (xenfb->pub.pixels == NULL) {
|
||||
- munmap(fbmfns, n_fbdirs * XC_PAGE_SIZE);
|
||||
- return -1;
|
||||
- }
|
||||
+ if (xenfb->pub.pixels == NULL)
|
||||
+ goto out;
|
||||
|
||||
- return munmap(fbmfns, n_fbdirs * XC_PAGE_SIZE);
|
||||
+ ret = 0; /* all is fine */
|
||||
+
|
||||
+ out:
|
||||
+ if (pgmfns)
|
||||
+ free(pgmfns);
|
||||
+ if (fbmfns)
|
||||
+ free(fbmfns);
|
||||
+ return ret;
|
||||
}
|
||||
|
||||
static int xenfb_bind(struct xenfb_device *dev)
|
||||
@@ -491,6 +564,9 @@ int xenfb_attach_dom(struct xenfb *xenfb
|
||||
errno = ENOTSUP;
|
||||
goto error;
|
||||
}
|
||||
+ if (xenfb_xs_scanf1(xsh, xenfb->fb.otherend, "protocol", "%63s",
|
||||
+ xenfb->protocol) < 0)
|
||||
+ xenfb->protocol[0] = '\0';
|
||||
xenfb_xs_printf(xsh, xenfb->fb.nodename, "request-update", "1");
|
||||
|
||||
/* TODO check for permitted ranges */
|
505
hide-asm-labels.patch
Normal file
505
hide-asm-labels.patch
Normal file
@ -0,0 +1,505 @@
|
||||
Index: 2006-12-11/xen/arch/x86/x86_32/entry.S
|
||||
===================================================================
|
||||
--- 2006-12-11.orig/xen/arch/x86/x86_32/entry.S 2006-12-15 15:21:44.000000000 +0100
|
||||
+++ 2006-12-11/xen/arch/x86/x86_32/entry.S 2006-12-15 15:39:13.000000000 +0100
|
||||
@@ -84,10 +84,10 @@ restore_all_guest:
|
||||
jmp restore_all_vm86
|
||||
1:
|
||||
#endif
|
||||
-FLT1: mov UREGS_ds(%esp),%ds
|
||||
-FLT2: mov UREGS_es(%esp),%es
|
||||
-FLT3: mov UREGS_fs(%esp),%fs
|
||||
-FLT4: mov UREGS_gs(%esp),%gs
|
||||
+.LFT1: mov UREGS_ds(%esp),%ds
|
||||
+.LFT2: mov UREGS_es(%esp),%es
|
||||
+.LFT3: mov UREGS_fs(%esp),%fs
|
||||
+.LFT4: mov UREGS_gs(%esp),%gs
|
||||
restore_all_vm86:
|
||||
popl %ebx
|
||||
popl %ecx
|
||||
@@ -97,9 +97,9 @@ restore_all_vm86:
|
||||
popl %ebp
|
||||
popl %eax
|
||||
addl $4,%esp
|
||||
-FLT5: iret
|
||||
+.LFT5: iret
|
||||
.section .fixup,"ax"
|
||||
-FIX5: subl $28,%esp
|
||||
+.LFX5: subl $28,%esp
|
||||
pushl 28(%esp) # error_code/entry_vector
|
||||
movl %eax,UREGS_eax+4(%esp)
|
||||
movl %ebp,UREGS_ebp+4(%esp)
|
||||
@@ -108,7 +108,7 @@ FIX5: subl $28,%esp
|
||||
movl %edx,UREGS_edx+4(%esp)
|
||||
movl %ecx,UREGS_ecx+4(%esp)
|
||||
movl %ebx,UREGS_ebx+4(%esp)
|
||||
-FIX1: SET_XEN_SEGMENTS(a)
|
||||
+.LFX1: SET_XEN_SEGMENTS(a)
|
||||
movl %eax,%fs
|
||||
movl %eax,%gs
|
||||
sti
|
||||
@@ -116,11 +116,11 @@ FIX1: SET_XEN_SEGMENTS(a)
|
||||
pushfl # EFLAGS
|
||||
movl $__HYPERVISOR_CS,%eax
|
||||
pushl %eax # CS
|
||||
- movl $DBLFLT1,%eax
|
||||
+ movl $.LDF1,%eax
|
||||
pushl %eax # EIP
|
||||
pushl %esi # error_code/entry_vector
|
||||
jmp handle_exception
|
||||
-DBLFLT1:GET_CURRENT(%ebx)
|
||||
+.LDF1: GET_CURRENT(%ebx)
|
||||
jmp test_all_events
|
||||
failsafe_callback:
|
||||
GET_CURRENT(%ebx)
|
||||
@@ -142,14 +142,14 @@ failsafe_callback:
|
||||
jmp test_all_events
|
||||
.previous
|
||||
.section __pre_ex_table,"a"
|
||||
- .long FLT1,FIX1
|
||||
- .long FLT2,FIX1
|
||||
- .long FLT3,FIX1
|
||||
- .long FLT4,FIX1
|
||||
- .long FLT5,FIX5
|
||||
+ .long .LFT1,.LFX1
|
||||
+ .long .LFT2,.LFX1
|
||||
+ .long .LFT3,.LFX1
|
||||
+ .long .LFT4,.LFX1
|
||||
+ .long .LFT5,.LFX5
|
||||
.previous
|
||||
.section __ex_table,"a"
|
||||
- .long DBLFLT1,failsafe_callback
|
||||
+ .long .LDF1,failsafe_callback
|
||||
.previous
|
||||
|
||||
ALIGN
|
||||
@@ -288,32 +288,33 @@ create_bounce_frame:
|
||||
testl $(2|X86_EFLAGS_VM),%ecx
|
||||
jz ring1 /* jump if returning to an existing ring-1 activation */
|
||||
movl VCPU_kernel_sp(%ebx),%esi
|
||||
-FLT6: mov VCPU_kernel_ss(%ebx),%gs
|
||||
+.LFT6: mov VCPU_kernel_ss(%ebx),%gs
|
||||
testl $X86_EFLAGS_VM,UREGS_eflags+4(%esp)
|
||||
- jz nvm86_1
|
||||
+ jz .Lnvm86_1
|
||||
subl $16,%esi /* push ES/DS/FS/GS (VM86 stack frame) */
|
||||
movl UREGS_es+4(%esp),%eax
|
||||
-FLT7: movl %eax,%gs:(%esi)
|
||||
+.LFT7: movl %eax,%gs:(%esi)
|
||||
movl UREGS_ds+4(%esp),%eax
|
||||
-FLT8: movl %eax,%gs:4(%esi)
|
||||
+.LFT8: movl %eax,%gs:4(%esi)
|
||||
movl UREGS_fs+4(%esp),%eax
|
||||
-FLT9: movl %eax,%gs:8(%esi)
|
||||
+.LFT9: movl %eax,%gs:8(%esi)
|
||||
movl UREGS_gs+4(%esp),%eax
|
||||
-FLT10: movl %eax,%gs:12(%esi)
|
||||
-nvm86_1:subl $8,%esi /* push SS/ESP (inter-priv iret) */
|
||||
+.LFT10: movl %eax,%gs:12(%esi)
|
||||
+.Lnvm86_1:
|
||||
+ subl $8,%esi /* push SS/ESP (inter-priv iret) */
|
||||
movl UREGS_esp+4(%esp),%eax
|
||||
-FLT11: movl %eax,%gs:(%esi)
|
||||
+.LFT11: movl %eax,%gs:(%esi)
|
||||
movl UREGS_ss+4(%esp),%eax
|
||||
-FLT12: movl %eax,%gs:4(%esi)
|
||||
+.LFT12: movl %eax,%gs:4(%esi)
|
||||
jmp 1f
|
||||
ring1: /* obtain ss/esp from oldss/oldesp -- a ring-1 activation exists */
|
||||
movl UREGS_esp+4(%esp),%esi
|
||||
-FLT13: mov UREGS_ss+4(%esp),%gs
|
||||
+.LFT13: mov UREGS_ss+4(%esp),%gs
|
||||
1: /* Construct a stack frame: EFLAGS, CS/EIP */
|
||||
movb TRAPBOUNCE_flags(%edx),%cl
|
||||
subl $12,%esi
|
||||
movl UREGS_eip+4(%esp),%eax
|
||||
-FLT14: movl %eax,%gs:(%esi)
|
||||
+.LFT14: movl %eax,%gs:(%esi)
|
||||
movl VCPU_vcpu_info(%ebx),%eax
|
||||
pushl VCPUINFO_upcall_mask(%eax)
|
||||
testb $TBF_INTERRUPT,%cl
|
||||
@@ -324,49 +325,51 @@ FLT14: movl %eax,%gs:(%esi)
|
||||
movw UREGS_cs+4(%esp),%ax # Bits 0-15: CS
|
||||
#ifdef CONFIG_X86_SUPERVISOR_MODE_KERNEL
|
||||
testw $2,%ax
|
||||
- jnz FLT15
|
||||
+ jnz .LFT15
|
||||
and $~3,%ax # RPL 1 -> RPL 0
|
||||
#endif
|
||||
-FLT15: movl %eax,%gs:4(%esi)
|
||||
+.LFT15: movl %eax,%gs:4(%esi)
|
||||
test $0x00FF0000,%eax # Bits 16-23: saved_upcall_mask
|
||||
setz %ch # %ch == !saved_upcall_mask
|
||||
movl UREGS_eflags+4(%esp),%eax
|
||||
andl $~X86_EFLAGS_IF,%eax
|
||||
shlb $1,%ch # Bit 9 (EFLAGS.IF)
|
||||
orb %ch,%ah # Fold EFLAGS.IF into %eax
|
||||
-FLT16: movl %eax,%gs:8(%esi)
|
||||
+.LFT16: movl %eax,%gs:8(%esi)
|
||||
test $TBF_EXCEPTION_ERRCODE,%cl
|
||||
jz 1f
|
||||
subl $4,%esi # push error_code onto guest frame
|
||||
movl TRAPBOUNCE_error_code(%edx),%eax
|
||||
-FLT17: movl %eax,%gs:(%esi)
|
||||
+.LFT17: movl %eax,%gs:(%esi)
|
||||
1: testb $TBF_FAILSAFE,%cl
|
||||
jz 2f
|
||||
subl $16,%esi # add DS/ES/FS/GS to failsafe stack frame
|
||||
testl $X86_EFLAGS_VM,UREGS_eflags+4(%esp)
|
||||
- jz nvm86_2
|
||||
+ jz .Lnvm86_2
|
||||
xorl %eax,%eax # VM86: we write zero selector values
|
||||
-FLT18: movl %eax,%gs:(%esi)
|
||||
-FLT19: movl %eax,%gs:4(%esi)
|
||||
-FLT20: movl %eax,%gs:8(%esi)
|
||||
-FLT21: movl %eax,%gs:12(%esi)
|
||||
+.LFT18: movl %eax,%gs:(%esi)
|
||||
+.LFT19: movl %eax,%gs:4(%esi)
|
||||
+.LFT20: movl %eax,%gs:8(%esi)
|
||||
+.LFT21: movl %eax,%gs:12(%esi)
|
||||
jmp 2f
|
||||
-nvm86_2:movl UREGS_ds+4(%esp),%eax # non-VM86: write real selector values
|
||||
-FLT22: movl %eax,%gs:(%esi)
|
||||
+.Lnvm86_2:
|
||||
+ movl UREGS_ds+4(%esp),%eax # non-VM86: write real selector values
|
||||
+.LFT22: movl %eax,%gs:(%esi)
|
||||
movl UREGS_es+4(%esp),%eax
|
||||
-FLT23: movl %eax,%gs:4(%esi)
|
||||
+.LFT23: movl %eax,%gs:4(%esi)
|
||||
movl UREGS_fs+4(%esp),%eax
|
||||
-FLT24: movl %eax,%gs:8(%esi)
|
||||
+.LFT24: movl %eax,%gs:8(%esi)
|
||||
movl UREGS_gs+4(%esp),%eax
|
||||
-FLT25: movl %eax,%gs:12(%esi)
|
||||
+.LFT25: movl %eax,%gs:12(%esi)
|
||||
2: testl $X86_EFLAGS_VM,UREGS_eflags+4(%esp)
|
||||
- jz nvm86_3
|
||||
+ jz .Lnvm86_3
|
||||
xorl %eax,%eax /* zero DS-GS, just as a real CPU would */
|
||||
movl %eax,UREGS_ds+4(%esp)
|
||||
movl %eax,UREGS_es+4(%esp)
|
||||
movl %eax,UREGS_fs+4(%esp)
|
||||
movl %eax,UREGS_gs+4(%esp)
|
||||
-nvm86_3:/* Rewrite our stack frame and return to ring 1. */
|
||||
+.Lnvm86_3:
|
||||
+ /* Rewrite our stack frame and return to ring 1. */
|
||||
/* IA32 Ref. Vol. 3: TF, VM, RF and NT flags are cleared on trap. */
|
||||
andl $~(X86_EFLAGS_VM|X86_EFLAGS_RF|\
|
||||
X86_EFLAGS_NT|X86_EFLAGS_TF),UREGS_eflags+4(%esp)
|
||||
@@ -382,16 +385,16 @@ nvm86_3:/* Rewrite our stack frame and r
|
||||
movb $0,TRAPBOUNCE_flags(%edx)
|
||||
ret
|
||||
.section __ex_table,"a"
|
||||
- .long FLT6,domain_crash_synchronous , FLT7,domain_crash_page_fault
|
||||
- .long FLT8,domain_crash_page_fault_4 , FLT9,domain_crash_page_fault_8
|
||||
- .long FLT10,domain_crash_page_fault_12, FLT11,domain_crash_page_fault
|
||||
- .long FLT12,domain_crash_page_fault_4 , FLT13,domain_crash_synchronous
|
||||
- .long FLT14,domain_crash_page_fault , FLT15,domain_crash_page_fault_4
|
||||
- .long FLT16,domain_crash_page_fault_8 , FLT17,domain_crash_page_fault
|
||||
- .long FLT18,domain_crash_page_fault , FLT19,domain_crash_page_fault_4
|
||||
- .long FLT20,domain_crash_page_fault_8 , FLT21,domain_crash_page_fault_12
|
||||
- .long FLT22,domain_crash_page_fault , FLT23,domain_crash_page_fault_4
|
||||
- .long FLT24,domain_crash_page_fault_8 , FLT25,domain_crash_page_fault_12
|
||||
+ .long .LFT6,domain_crash_synchronous , .LFT7,domain_crash_page_fault
|
||||
+ .long .LFT8,domain_crash_page_fault_4 , .LFT9,domain_crash_page_fault_8
|
||||
+ .long .LFT10,domain_crash_page_fault_12, .LFT11,domain_crash_page_fault
|
||||
+ .long .LFT12,domain_crash_page_fault_4 , .LFT13,domain_crash_synchronous
|
||||
+ .long .LFT14,domain_crash_page_fault , .LFT15,domain_crash_page_fault_4
|
||||
+ .long .LFT16,domain_crash_page_fault_8 , .LFT17,domain_crash_page_fault
|
||||
+ .long .LFT18,domain_crash_page_fault , .LFT19,domain_crash_page_fault_4
|
||||
+ .long .LFT20,domain_crash_page_fault_8 , .LFT21,domain_crash_page_fault_12
|
||||
+ .long .LFT22,domain_crash_page_fault , .LFT23,domain_crash_page_fault_4
|
||||
+ .long .LFT24,domain_crash_page_fault_8 , .LFT25,domain_crash_page_fault_12
|
||||
.previous
|
||||
|
||||
.section .rodata,"a"
|
||||
Index: 2006-12-11/xen/arch/x86/x86_64/compat/entry.S
|
||||
===================================================================
|
||||
--- 2006-12-11.orig/xen/arch/x86/x86_64/compat/entry.S 2006-12-15 15:39:03.000000000 +0100
|
||||
+++ 2006-12-11/xen/arch/x86/x86_64/compat/entry.S 2006-12-15 15:39:13.000000000 +0100
|
||||
@@ -118,10 +118,10 @@ compat_bad_hypercall:
|
||||
compat_restore_all_guest:
|
||||
RESTORE_ALL
|
||||
addq $8,%rsp
|
||||
-CFLT0: iretq
|
||||
+.Lft0: iretq
|
||||
|
||||
.section .fixup,"ax"
|
||||
-CFIX0: popq -15*8-8(%rsp) # error_code/entry_vector
|
||||
+.Lfx0: popq -15*8-8(%rsp) # error_code/entry_vector
|
||||
SAVE_ALL # 15*8 bytes pushed
|
||||
movq -8(%rsp),%rsi # error_code/entry_vector
|
||||
sti # after stack abuse (-1024(%rsp))
|
||||
@@ -130,11 +130,11 @@ CFIX0: popq -15*8-8(%rsp) #
|
||||
pushq %rax # RSP
|
||||
pushfq # RFLAGS
|
||||
pushq $__HYPERVISOR_CS # CS
|
||||
- leaq CDBLFLT0(%rip),%rax
|
||||
+ leaq .Ldf0(%rip),%rax
|
||||
pushq %rax # RIP
|
||||
pushq %rsi # error_code/entry_vector
|
||||
jmp handle_exception
|
||||
-CDBLFLT0:GET_CURRENT(%rbx)
|
||||
+.Ldf0: GET_CURRENT(%rbx)
|
||||
jmp compat_test_all_events
|
||||
compat_failsafe_callback:
|
||||
GET_CURRENT(%rbx)
|
||||
@@ -152,10 +152,10 @@ compat_failsafe_callback:
|
||||
jmp compat_test_all_events
|
||||
.previous
|
||||
.section __pre_ex_table,"a"
|
||||
- .quad CFLT0,CFIX0
|
||||
+ .quad .Lft0,.Lfx0
|
||||
.previous
|
||||
.section __ex_table,"a"
|
||||
- .quad CDBLFLT0,compat_failsafe_callback
|
||||
+ .quad .Ldf0,compat_failsafe_callback
|
||||
.previous
|
||||
|
||||
/* %rdx: trap_bounce, %rbx: struct vcpu */
|
||||
@@ -175,16 +175,16 @@ compat_create_bounce_frame:
|
||||
jz 1f
|
||||
/* Push new frame at registered guest-OS stack base. */
|
||||
movl VCPU_kernel_sp(%rbx),%esi
|
||||
-CFLT1: mov VCPU_kernel_ss(%rbx),%fs
|
||||
+.Lft1: mov VCPU_kernel_ss(%rbx),%fs
|
||||
subl $2*4,%esi
|
||||
movl UREGS_rsp+8(%rsp),%eax
|
||||
-CFLT2: movl %eax,%fs:(%rsi)
|
||||
+.Lft2: movl %eax,%fs:(%rsi)
|
||||
movl UREGS_ss+8(%rsp),%eax
|
||||
-CFLT3: movl %eax,%fs:4(%rsi)
|
||||
+.Lft3: movl %eax,%fs:4(%rsi)
|
||||
jmp 2f
|
||||
1: /* In kernel context already: push new frame at existing %rsp. */
|
||||
movl UREGS_rsp+8(%rsp),%esi
|
||||
-CFLT4: mov UREGS_ss+8(%rsp),%fs
|
||||
+.Lft4: mov UREGS_ss+8(%rsp),%fs
|
||||
2:
|
||||
movb TRAPBOUNCE_flags(%rdx),%cl
|
||||
subl $3*4,%esi
|
||||
@@ -196,7 +196,7 @@ CFLT4: mov UREGS_ss+8(%rsp),%fs
|
||||
popq %rax
|
||||
shll $16,%eax # Bits 16-23: saved_upcall_mask
|
||||
movw UREGS_cs+8(%rsp),%ax # Bits 0-15: CS
|
||||
-CFLT5: movl %eax,%fs:4(%rsi) # CS / saved_upcall_mask
|
||||
+.Lft5: movl %eax,%fs:4(%rsi) # CS / saved_upcall_mask
|
||||
shrl $16,%eax
|
||||
testb %al,%al # Bits 0-7: saved_upcall_mask
|
||||
setz %ch # %ch == !saved_upcall_mask
|
||||
@@ -204,25 +204,25 @@ CFLT5: movl %eax,%fs:4(%rsi)
|
||||
andl $~X86_EFLAGS_IF,%eax
|
||||
shlb $1,%ch # Bit 9 (EFLAGS.IF)
|
||||
orb %ch,%ah # Fold EFLAGS.IF into %eax
|
||||
-CFLT6: movl %eax,%fs:2*4(%rsi) # EFLAGS
|
||||
+.Lft6: movl %eax,%fs:2*4(%rsi) # EFLAGS
|
||||
movl UREGS_rip+8(%rsp),%eax
|
||||
-CFLT7: movl %eax,%fs:(%rsi) # EIP
|
||||
+.Lft7: movl %eax,%fs:(%rsi) # EIP
|
||||
testb $TBF_EXCEPTION_ERRCODE,%cl
|
||||
jz 1f
|
||||
subl $4,%esi
|
||||
movl TRAPBOUNCE_error_code(%rdx),%eax
|
||||
-CFLT8: movl %eax,%fs:(%rsi) # ERROR CODE
|
||||
+.Lft8: movl %eax,%fs:(%rsi) # ERROR CODE
|
||||
1:
|
||||
testb $TBF_FAILSAFE,%cl
|
||||
jz 2f
|
||||
subl $4*4,%esi
|
||||
movl %gs,%eax
|
||||
-CFLT9: movl %eax,%fs:3*4(%rsi) # GS
|
||||
-CFLT10: movl %edi,%fs:2*4(%rsi) # FS
|
||||
+.Lft9: movl %eax,%fs:3*4(%rsi) # GS
|
||||
+.Lft10: movl %edi,%fs:2*4(%rsi) # FS
|
||||
movl %es,%eax
|
||||
-CFLT11: movl %eax,%fs:1*4(%rsi) # ES
|
||||
+.Lft11: movl %eax,%fs:1*4(%rsi) # ES
|
||||
movl %ds,%eax
|
||||
-CFLT12: movl %eax,%fs:0*4(%rsi) # DS
|
||||
+.Lft12: movl %eax,%fs:0*4(%rsi) # DS
|
||||
2:
|
||||
/* Rewrite our stack frame and return to guest-OS mode. */
|
||||
/* IA32 Ref. Vol. 3: TF, VM, RF and NT flags are cleared on trap. */
|
||||
@@ -231,7 +231,7 @@ CFLT12: movl %eax,%fs:0*4(%rsi)
|
||||
X86_EFLAGS_NT|X86_EFLAGS_TF),UREGS_eflags+8(%rsp)
|
||||
mov %fs,UREGS_ss+8(%rsp)
|
||||
movl %esi,UREGS_rsp+8(%rsp)
|
||||
-CFLT13: mov %edi,%fs
|
||||
+.Lft13: mov %edi,%fs
|
||||
movzwl TRAPBOUNCE_cs(%rdx),%eax
|
||||
/* Null selectors (0-3) are not allowed. */
|
||||
testl $~3,%eax
|
||||
@@ -242,18 +242,18 @@ CFLT13: mov %edi,%fs
|
||||
movb $0,TRAPBOUNCE_flags(%rdx)
|
||||
ret
|
||||
.section .fixup,"ax"
|
||||
-CFIX13:
|
||||
+.Lfx13:
|
||||
xorl %edi,%edi
|
||||
- jmp CFLT13
|
||||
+ jmp .Lft13
|
||||
.previous
|
||||
.section __ex_table,"a"
|
||||
- .quad CFLT1,domain_crash_synchronous , CFLT2,compat_crash_page_fault
|
||||
- .quad CFLT3,compat_crash_page_fault_4 , CFLT4,domain_crash_synchronous
|
||||
- .quad CFLT5,compat_crash_page_fault_4 , CFLT6,compat_crash_page_fault_8
|
||||
- .quad CFLT7,compat_crash_page_fault , CFLT8,compat_crash_page_fault
|
||||
- .quad CFLT9,compat_crash_page_fault_12, CFLT10,compat_crash_page_fault_8
|
||||
- .quad CFLT11,compat_crash_page_fault_4 , CFLT12,compat_crash_page_fault
|
||||
- .quad CFLT13,CFIX13
|
||||
+ .quad .Lft1,domain_crash_synchronous , .Lft2,compat_crash_page_fault
|
||||
+ .quad .Lft3,compat_crash_page_fault_4 , .Lft4,domain_crash_synchronous
|
||||
+ .quad .Lft5,compat_crash_page_fault_4 , .Lft6,compat_crash_page_fault_8
|
||||
+ .quad .Lft7,compat_crash_page_fault , .Lft8,compat_crash_page_fault
|
||||
+ .quad .Lft9,compat_crash_page_fault_12, .Lft10,compat_crash_page_fault_8
|
||||
+ .quad .Lft11,compat_crash_page_fault_4 , .Lft12,compat_crash_page_fault
|
||||
+ .quad .Lft13,.Lfx13
|
||||
.previous
|
||||
|
||||
compat_crash_page_fault_12:
|
||||
@@ -263,17 +263,17 @@ compat_crash_page_fault_8:
|
||||
compat_crash_page_fault_4:
|
||||
addl $4,%esi
|
||||
compat_crash_page_fault:
|
||||
-CFLT14: mov %edi,%fs
|
||||
+.Lft14: mov %edi,%fs
|
||||
movl %esi,%edi
|
||||
call show_page_walk
|
||||
jmp domain_crash_synchronous
|
||||
.section .fixup,"ax"
|
||||
-CFIX14:
|
||||
+.Lfx14:
|
||||
xorl %edi,%edi
|
||||
- jmp CFLT14
|
||||
+ jmp .Lft14
|
||||
.previous
|
||||
.section __ex_table,"a"
|
||||
- .quad CFLT14,CFIX14
|
||||
+ .quad .Lft14,.Lfx14
|
||||
.previous
|
||||
|
||||
.section .rodata, "a", @progbits
|
||||
Index: 2006-12-11/xen/arch/x86/x86_64/entry.S
|
||||
===================================================================
|
||||
--- 2006-12-11.orig/xen/arch/x86/x86_64/entry.S 2006-12-15 15:23:16.000000000 +0100
|
||||
+++ 2006-12-11/xen/arch/x86/x86_64/entry.S 2006-12-15 15:39:13.000000000 +0100
|
||||
@@ -56,10 +56,10 @@ restore_all_guest:
|
||||
/* No special register assumptions. */
|
||||
iret_exit_to_guest:
|
||||
addq $8,%rsp
|
||||
-FLT1: iretq
|
||||
+.LFT1: iretq
|
||||
|
||||
.section .fixup,"ax"
|
||||
-FIX1: popq -15*8-8(%rsp) # error_code/entry_vector
|
||||
+.LFX1: popq -15*8-8(%rsp) # error_code/entry_vector
|
||||
SAVE_ALL # 15*8 bytes pushed
|
||||
movq -8(%rsp),%rsi # error_code/entry_vector
|
||||
sti # after stack abuse (-1024(%rsp))
|
||||
@@ -68,11 +68,11 @@ FIX1: popq -15*8-8(%rsp) #
|
||||
pushq %rax # RSP
|
||||
pushf # RFLAGS
|
||||
pushq $__HYPERVISOR_CS # CS
|
||||
- leaq DBLFLT1(%rip),%rax
|
||||
+ leaq .LDF1(%rip),%rax
|
||||
pushq %rax # RIP
|
||||
pushq %rsi # error_code/entry_vector
|
||||
jmp handle_exception
|
||||
-DBLFLT1:GET_CURRENT(%rbx)
|
||||
+.LDF1: GET_CURRENT(%rbx)
|
||||
jmp test_all_events
|
||||
failsafe_callback:
|
||||
GET_CURRENT(%rbx)
|
||||
@@ -87,10 +87,10 @@ failsafe_callback:
|
||||
jmp test_all_events
|
||||
.previous
|
||||
.section __pre_ex_table,"a"
|
||||
- .quad FLT1,FIX1
|
||||
+ .quad .LFT1,.LFX1
|
||||
.previous
|
||||
.section __ex_table,"a"
|
||||
- .quad DBLFLT1,failsafe_callback
|
||||
+ .quad .LDF1,failsafe_callback
|
||||
.previous
|
||||
|
||||
ALIGN
|
||||
@@ -249,9 +249,9 @@ create_bounce_frame:
|
||||
1: movb TRAPBOUNCE_flags(%rdx),%cl
|
||||
subq $40,%rsi
|
||||
movq UREGS_ss+8(%rsp),%rax
|
||||
-FLT2: movq %rax,32(%rsi) # SS
|
||||
+.LFT2: movq %rax,32(%rsi) # SS
|
||||
movq UREGS_rsp+8(%rsp),%rax
|
||||
-FLT3: movq %rax,24(%rsi) # RSP
|
||||
+.LFT3: movq %rax,24(%rsi) # RSP
|
||||
movq VCPU_vcpu_info(%rbx),%rax
|
||||
pushq VCPUINFO_upcall_mask(%rax)
|
||||
testb $TBF_INTERRUPT,%cl
|
||||
@@ -260,7 +260,7 @@ FLT3: movq %rax,24(%rsi)
|
||||
popq %rax
|
||||
shlq $32,%rax # Bits 32-39: saved_upcall_mask
|
||||
movw UREGS_cs+8(%rsp),%ax # Bits 0-15: CS
|
||||
-FLT4: movq %rax,8(%rsi) # CS / saved_upcall_mask
|
||||
+.LFT4: movq %rax,8(%rsi) # CS / saved_upcall_mask
|
||||
shrq $32,%rax
|
||||
testb $0xFF,%al # Bits 0-7: saved_upcall_mask
|
||||
setz %ch # %ch == !saved_upcall_mask
|
||||
@@ -268,30 +268,30 @@ FLT4: movq %rax,8(%rsi)
|
||||
andq $~X86_EFLAGS_IF,%rax
|
||||
shlb $1,%ch # Bit 9 (EFLAGS.IF)
|
||||
orb %ch,%ah # Fold EFLAGS.IF into %eax
|
||||
-FLT5: movq %rax,16(%rsi) # RFLAGS
|
||||
+.LFT5: movq %rax,16(%rsi) # RFLAGS
|
||||
movq UREGS_rip+8(%rsp),%rax
|
||||
-FLT6: movq %rax,(%rsi) # RIP
|
||||
+.LFT6: movq %rax,(%rsi) # RIP
|
||||
testb $TBF_EXCEPTION_ERRCODE,%cl
|
||||
jz 1f
|
||||
subq $8,%rsi
|
||||
movl TRAPBOUNCE_error_code(%rdx),%eax
|
||||
-FLT7: movq %rax,(%rsi) # ERROR CODE
|
||||
+.LFT7: movq %rax,(%rsi) # ERROR CODE
|
||||
1: testb $TBF_FAILSAFE,%cl
|
||||
jz 2f
|
||||
subq $32,%rsi
|
||||
movl %gs,%eax
|
||||
-FLT8: movq %rax,24(%rsi) # GS
|
||||
+.LFT8: movq %rax,24(%rsi) # GS
|
||||
movl %fs,%eax
|
||||
-FLT9: movq %rax,16(%rsi) # FS
|
||||
+.LFT9: movq %rax,16(%rsi) # FS
|
||||
movl %es,%eax
|
||||
-FLT10: movq %rax,8(%rsi) # ES
|
||||
+.LFT10: movq %rax,8(%rsi) # ES
|
||||
movl %ds,%eax
|
||||
-FLT11: movq %rax,(%rsi) # DS
|
||||
+.LFT11: movq %rax,(%rsi) # DS
|
||||
2: subq $16,%rsi
|
||||
movq UREGS_r11+8(%rsp),%rax
|
||||
-FLT12: movq %rax,8(%rsi) # R11
|
||||
+.LFT12: movq %rax,8(%rsi) # R11
|
||||
movq UREGS_rcx+8(%rsp),%rax
|
||||
-FLT13: movq %rax,(%rsi) # RCX
|
||||
+.LFT13: movq %rax,(%rsi) # RCX
|
||||
/* Rewrite our stack frame and return to guest-OS mode. */
|
||||
/* IA32 Ref. Vol. 3: TF, VM, RF and NT flags are cleared on trap. */
|
||||
/* Also clear AC: alignment checks shouldn't trigger in kernel mode. */
|
||||
@@ -308,12 +308,12 @@ FLT13: movq %rax,(%rsi)
|
||||
movb $0,TRAPBOUNCE_flags(%rdx)
|
||||
ret
|
||||
.section __ex_table,"a"
|
||||
- .quad FLT2,domain_crash_page_fault_32, FLT3,domain_crash_page_fault_24
|
||||
- .quad FLT4,domain_crash_page_fault_8 , FLT5,domain_crash_page_fault_16
|
||||
- .quad FLT6,domain_crash_page_fault , FLT7,domain_crash_page_fault
|
||||
- .quad FLT8,domain_crash_page_fault_24, FLT9,domain_crash_page_fault_16
|
||||
- .quad FLT10,domain_crash_page_fault_8 , FLT11,domain_crash_page_fault
|
||||
- .quad FLT12,domain_crash_page_fault_8 , FLT13,domain_crash_page_fault
|
||||
+ .quad .LFT2,domain_crash_page_fault_32, .LFT3,domain_crash_page_fault_24
|
||||
+ .quad .LFT4,domain_crash_page_fault_8 , .LFT5,domain_crash_page_fault_16
|
||||
+ .quad .LFT6,domain_crash_page_fault , .LFT7,domain_crash_page_fault
|
||||
+ .quad .LFT8,domain_crash_page_fault_24, .LFT9,domain_crash_page_fault_16
|
||||
+ .quad .LFT10,domain_crash_page_fault_8 , .LFT11,domain_crash_page_fault
|
||||
+ .quad .LFT12,domain_crash_page_fault_8 , .LFT13,domain_crash_page_fault
|
||||
.previous
|
||||
|
||||
.section .rodata,"a"
|
29
init.xend
29
init.xend
@ -48,6 +48,23 @@ cleanup()
|
||||
rm -f /var/lib/xen/xenbl* 2>/dev/null
|
||||
}
|
||||
|
||||
parseln()
|
||||
{
|
||||
name=${1:0:$((${#1}-36))}
|
||||
name=${name%% *}
|
||||
rest="${1: -36}"
|
||||
id=${rest:0:4}
|
||||
id=`echo $id`
|
||||
mem=${rest:4:6}
|
||||
mem=`echo $mem`
|
||||
vcpu=${rest:10:6}
|
||||
vcpu=`echo $vcpu`
|
||||
state=${rest:16:11}
|
||||
state=`echo $state`
|
||||
tm=${rest:27}
|
||||
tm=`echo $tm`
|
||||
}
|
||||
|
||||
if [ "$1" == status ]; then
|
||||
if [ ! -e /proc/xen/capabilities ]; then
|
||||
xend_abort 3
|
||||
@ -70,7 +87,6 @@ fi
|
||||
XEND=`ps ax | grep xend | grep python | awk '{ print $1 }'`
|
||||
XEND=`echo $XEND`
|
||||
|
||||
#export PYTHONOPTIMIZE=2
|
||||
case "$1" in
|
||||
start)
|
||||
echo -n "Starting xend "
|
||||
@ -101,14 +117,16 @@ case "$1" in
|
||||
else
|
||||
echo -n "(pid $XEND) "
|
||||
unset sysrq_sent
|
||||
while read nm id mem vcpu state time; do
|
||||
if [ $id = 0 ]; then continue; fi
|
||||
while read LN; do
|
||||
parseln "$LN"
|
||||
[ -z "$id" ] && continue
|
||||
[ "$id" = 0 ] && continue
|
||||
sysrq_sent=1
|
||||
echo -en "\n Warning: Domain $nm (ID $id) still up ($state)"
|
||||
echo -en "\n Warning: Domain $name (ID $id) still up ($state)"
|
||||
# Domains should be closed down by xendomains; anyway, send
|
||||
# SysRq-S to avoid the worst in case domains are not shut down.
|
||||
xm sysrq $id s
|
||||
done < <(xm list | grep -v ^Name)
|
||||
done < <(xm list | grep -v '^Name *ID')
|
||||
if [ -n "$sysrq_sent" ]; then sleep 1; fi
|
||||
xend stop
|
||||
cleanup
|
||||
@ -146,6 +164,5 @@ case "$1" in
|
||||
rc_exit
|
||||
esac
|
||||
|
||||
#unset PYTHONOPTIMIZE
|
||||
rc_status -v
|
||||
rc_exit
|
||||
|
@ -105,10 +105,19 @@ running_auto_names()
|
||||
|
||||
parseln()
|
||||
{
|
||||
name=`echo "$1" | cut -c0-49`
|
||||
name=${1:0:$((${#1}-36))}
|
||||
name=${name%% *}
|
||||
rest=`echo "$1" | cut -c40- `
|
||||
read id mem vcpu state tm < <(echo "$rest")
|
||||
rest="${1: -36}"
|
||||
id=${rest:0:4}
|
||||
id=`echo $id`
|
||||
mem=${rest:4:6}
|
||||
mem=`echo $mem`
|
||||
vcpu=${rest:10:6}
|
||||
vcpu=`echo $vcpu`
|
||||
state=${rest:16:11}
|
||||
state=`echo $state`
|
||||
tm=${rest:27}
|
||||
tm=`echo $tm`
|
||||
}
|
||||
|
||||
is_cfg_running()
|
||||
@ -116,9 +125,12 @@ is_cfg_running()
|
||||
get_name_from_cfg "$1"
|
||||
while read LN; do
|
||||
parseln "$LN"
|
||||
[ $id = 0 ] && continue
|
||||
[ "$name" = "$NM" ] && return 0
|
||||
done < <(xm list | grep -v '^Name')
|
||||
[ "$id" = 0 ] && continue
|
||||
if [ "$name" = "$NM" ]; then
|
||||
[ -z "$state" ] && return 1
|
||||
return 0
|
||||
fi
|
||||
done < <(xm list | grep -v '^Name *ID')
|
||||
return 1
|
||||
}
|
||||
|
||||
@ -189,9 +201,10 @@ any_non_zombies()
|
||||
{
|
||||
while read LN; do
|
||||
parseln "$LN"
|
||||
[ $id = 0 ] && continue
|
||||
[ "$id" = 0 ] && continue
|
||||
[ -z "$state" ] && continue
|
||||
is_zombie_state "$state" || return 0
|
||||
done < <(xm list | grep -v '^Name')
|
||||
done < <(xm list | grep -v '^Name *ID')
|
||||
return 1
|
||||
}
|
||||
|
||||
@ -261,7 +274,8 @@ stop()
|
||||
local printed=0
|
||||
while read LN; do
|
||||
parseln "$LN"
|
||||
[ $id = 0 ] && continue
|
||||
[ "$id" = 0 ] && continue
|
||||
[ -z "$state" ] && continue
|
||||
printed=1
|
||||
if [ "$XENDOMAINS_AUTO_ONLY" = "true" ]; then
|
||||
is_auto_domain=0
|
||||
@ -354,7 +368,7 @@ stop()
|
||||
fi
|
||||
rc_status -v
|
||||
fi
|
||||
done < <(xm list | grep -v '^Name')
|
||||
done < <(xm list | grep -v '^Name *ID')
|
||||
|
||||
if [ -n "$XENDOMAINS_SHUTDOWN_ALL" ] && any_non_zombies ; then
|
||||
echo -n " others: shutting down... "
|
||||
@ -379,9 +393,12 @@ check_domain_up()
|
||||
{
|
||||
while read LN; do
|
||||
parseln "$LN"
|
||||
[ $id = 0 ] && continue
|
||||
[ "$name" = "$1" ] && return 0
|
||||
done < <(xm list | grep -v "^Name")
|
||||
[ "$id" = 0 ] && continue
|
||||
if [ "$name" = "$1" ]; then
|
||||
[ -z "$state" ] && return 1
|
||||
return 0
|
||||
fi
|
||||
done < <(xm list | grep -v '^Name *ID')
|
||||
return 1
|
||||
}
|
||||
|
||||
|
3100
libelf-add-to-xenkernel.diff
Normal file
3100
libelf-add-to-xenkernel.diff
Normal file
File diff suppressed because it is too large
Load Diff
36
libelf-symlink-to-libxc.diff
Normal file
36
libelf-symlink-to-libxc.diff
Normal file
@ -0,0 +1,36 @@
|
||||
libelf: add to libxc
|
||||
|
||||
This patch makes libelf available to the tools, by symlinking the source
|
||||
files and compiling them into libxc.
|
||||
|
||||
Signed-off-by: Gerd Hoffmann <kraxel@suse.de>
|
||||
---
|
||||
tools/libxc/Makefile | 15 +++++++++++++++
|
||||
1 file changed, 15 insertions(+)
|
||||
|
||||
Index: build-32-unstable-12621/tools/libxc/Makefile
|
||||
===================================================================
|
||||
--- build-32-unstable-12621.orig/tools/libxc/Makefile
|
||||
+++ build-32-unstable-12621/tools/libxc/Makefile
|
||||
@@ -29,6 +29,21 @@ GUEST_SRCS-$(CONFIG_IA64) += xc_linux_bu
|
||||
GUEST_SRCS-$(CONFIG_MIGRATE) += xc_linux_restore.c xc_linux_save.c
|
||||
GUEST_SRCS-$(CONFIG_HVM) += xc_hvm_build.c
|
||||
|
||||
+# symlink libelf from xen/common/libelf/
|
||||
+LIBELF_SRCS := libelf-tools.c libelf-loader.c
|
||||
+LIBELF_SRCS += libelf-dominfo.c libelf-relocate.c
|
||||
+
|
||||
+libelf-tools.o: libelf-tools.c libelf-private.h
|
||||
+libelf-loader.o: libelf-loader.c libelf-private.h
|
||||
+libelf-dominfo.o: libelf-dominfo.c libelf-private.h
|
||||
+libelf-relocate.o: libelf-relocate.c libelf-private.h
|
||||
+
|
||||
+$(LIBELF_SRCS) libelf-private.h:
|
||||
+ ln -s ../../xen/common/libelf/$@ $@
|
||||
+
|
||||
+# add libelf bits to libxc
|
||||
+GUEST_SRCS-y += $(LIBELF_SRCS)
|
||||
+
|
||||
-include $(XEN_TARGET_ARCH)/Makefile
|
||||
|
||||
CFLAGS += -Werror -Wmissing-prototypes
|
300
libelf-use-hvm-build.diff
Normal file
300
libelf-use-hvm-build.diff
Normal file
@ -0,0 +1,300 @@
|
||||
libelf: use for hvm builder.
|
||||
|
||||
This patch switches over the hvm domain builder to libelf
|
||||
(for loading hvmloader).
|
||||
|
||||
Signed-off-by: Gerd Hoffmann <kraxel@suse.de>
|
||||
---
|
||||
tools/libxc/xc_hvm_build.c | 220 +++++++++++++--------------------------------
|
||||
1 file changed, 65 insertions(+), 155 deletions(-)
|
||||
|
||||
Index: build-32-unstable-12802/tools/libxc/xc_hvm_build.c
|
||||
===================================================================
|
||||
--- build-32-unstable-12802.orig/tools/libxc/xc_hvm_build.c
|
||||
+++ build-32-unstable-12802/tools/libxc/xc_hvm_build.c
|
||||
@@ -2,29 +2,22 @@
|
||||
* xc_hvm_build.c
|
||||
*/
|
||||
|
||||
-#define ELFSIZE 32
|
||||
#include <stddef.h>
|
||||
#include <inttypes.h>
|
||||
-#include "xg_private.h"
|
||||
-#include "xc_private.h"
|
||||
-#include "xc_elf.h"
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <zlib.h>
|
||||
+
|
||||
+#include "xg_private.h"
|
||||
+#include "xc_private.h"
|
||||
+
|
||||
#include <xen/hvm/hvm_info_table.h>
|
||||
#include <xen/hvm/params.h>
|
||||
#include <xen/hvm/e820.h>
|
||||
|
||||
-#define SCRATCH_PFN 0xFFFFF
|
||||
+#include <xen/libelf.h>
|
||||
|
||||
-#define HVM_LOADER_ENTR_ADDR 0x00100000
|
||||
-static int
|
||||
-parseelfimage(
|
||||
- char *elfbase, unsigned long elfsize, struct domain_setup_info *dsi);
|
||||
-static int
|
||||
-loadelfimage(
|
||||
- char *elfbase, int xch, uint32_t dom, unsigned long *parray,
|
||||
- struct domain_setup_info *dsi);
|
||||
+#define SCRATCH_PFN 0xFFFFF
|
||||
|
||||
int xc_set_hvm_param(
|
||||
int handle, domid_t dom, int param, unsigned long value)
|
||||
@@ -144,6 +137,48 @@ static void build_e820map(void *e820_pag
|
||||
*(((unsigned char *)e820_page) + E820_MAP_NR_OFFSET) = nr_map;
|
||||
}
|
||||
|
||||
+static int
|
||||
+loadelfimage(struct elf_binary *elf, int xch, uint32_t dom, unsigned long *parray)
|
||||
+{
|
||||
+ privcmd_mmap_entry_t *entries = NULL;
|
||||
+ int pages = (elf->pend - elf->pstart + PAGE_SIZE - 1) >> PAGE_SHIFT;
|
||||
+ int i, rc = -1;
|
||||
+
|
||||
+ /* map hvmloader address space */
|
||||
+ entries = malloc(pages * sizeof(privcmd_mmap_entry_t));
|
||||
+ if (NULL == entries)
|
||||
+ goto err;
|
||||
+ elf->dest = mmap(NULL, pages << PAGE_SHIFT, PROT_READ | PROT_WRITE,
|
||||
+ MAP_SHARED, xch, 0);
|
||||
+ if (MAP_FAILED == elf->dest)
|
||||
+ goto err;
|
||||
+
|
||||
+ for (i = 0; i < pages; i++)
|
||||
+ {
|
||||
+ entries[i].va = (uintptr_t)elf->dest + (i << PAGE_SHIFT);
|
||||
+ entries[i].mfn = parray[(elf->pstart >> PAGE_SHIFT) + i];
|
||||
+ entries[i].npages = 1;
|
||||
+ }
|
||||
+ rc = xc_map_foreign_ranges(xch, dom, entries, pages);
|
||||
+ if (rc < 0)
|
||||
+ goto err;
|
||||
+
|
||||
+ /* load hvmloader */
|
||||
+ elf_load_binary(elf);
|
||||
+ rc = 0;
|
||||
+
|
||||
+ err:
|
||||
+ /* cleanup */
|
||||
+ if (elf->dest) {
|
||||
+ munmap(elf->dest, pages << PAGE_SHIFT);
|
||||
+ elf->dest = NULL;
|
||||
+ }
|
||||
+ if (entries)
|
||||
+ free(entries);
|
||||
+
|
||||
+ return rc;
|
||||
+}
|
||||
+
|
||||
static int setup_guest(int xc_handle,
|
||||
uint32_t dom, int memsize,
|
||||
char *image, unsigned long image_size,
|
||||
@@ -155,35 +190,35 @@ static int setup_guest(int xc_handle,
|
||||
struct xen_add_to_physmap xatp;
|
||||
struct shared_info *shared_info;
|
||||
void *e820_page;
|
||||
- struct domain_setup_info dsi;
|
||||
- uint64_t v_end;
|
||||
+ struct elf_binary elf;
|
||||
+ uint64_t v_start, v_end;
|
||||
int rc;
|
||||
|
||||
- memset(&dsi, 0, sizeof(struct domain_setup_info));
|
||||
-
|
||||
- if ( (parseelfimage(image, image_size, &dsi)) != 0 )
|
||||
+ if (0 != elf_init(&elf, image, image_size))
|
||||
goto error_out;
|
||||
+ elf_parse_binary(&elf);
|
||||
+ v_start = 0;
|
||||
+ v_end = (unsigned long long)memsize << 20;
|
||||
|
||||
- if ( (dsi.v_kernstart & (PAGE_SIZE - 1)) != 0 )
|
||||
+ if ( (elf.pstart & (PAGE_SIZE - 1)) != 0 )
|
||||
{
|
||||
PERROR("Guest OS must load to a page boundary.\n");
|
||||
goto error_out;
|
||||
}
|
||||
|
||||
- v_end = (unsigned long long)memsize << 20;
|
||||
-
|
||||
IPRINTF("VIRTUAL MEMORY ARRANGEMENT:\n"
|
||||
- " Loaded HVM loader: %016"PRIx64"->%016"PRIx64"\n"
|
||||
- " TOTAL: %016"PRIx64"->%016"PRIx64"\n",
|
||||
- dsi.v_kernstart, dsi.v_kernend,
|
||||
- dsi.v_start, v_end);
|
||||
- IPRINTF(" ENTRY ADDRESS: %016"PRIx64"\n", dsi.v_kernentry);
|
||||
+ " Loaded HVM loader: %016"PRIx64"->%016"PRIx64"\n"
|
||||
+ " TOTAL: %016"PRIx64"->%016"PRIx64"\n"
|
||||
+ " ENTRY ADDRESS: %016"PRIx64"\n",
|
||||
+ elf.pstart, elf.pend,
|
||||
+ v_start, v_end,
|
||||
+ elf_uval(&elf, elf.ehdr, e_entry));
|
||||
|
||||
- if ( (v_end - dsi.v_start) > ((unsigned long long)nr_pages << PAGE_SHIFT) )
|
||||
+ if ( (v_end - v_start) > ((unsigned long long)nr_pages << PAGE_SHIFT) )
|
||||
{
|
||||
PERROR("Initial guest OS requires too much space: "
|
||||
"(%lluMB is greater than %lluMB limit)\n",
|
||||
- (unsigned long long)(v_end - dsi.v_start) >> 20,
|
||||
+ (unsigned long long)(v_end - v_start) >> 20,
|
||||
((unsigned long long)nr_pages << PAGE_SHIFT) >> 20);
|
||||
goto error_out;
|
||||
}
|
||||
@@ -212,7 +247,7 @@ static int setup_guest(int xc_handle,
|
||||
goto error_out;
|
||||
}
|
||||
|
||||
- loadelfimage(image, xc_handle, dom, page_array, &dsi);
|
||||
+ loadelfimage(&elf, xc_handle, dom, page_array);
|
||||
|
||||
if ( (e820_page = xc_map_foreign_range(
|
||||
xc_handle, dom, PAGE_SIZE, PROT_READ | PROT_WRITE,
|
||||
@@ -256,7 +291,7 @@ static int setup_guest(int xc_handle,
|
||||
|
||||
free(page_array);
|
||||
|
||||
- ctxt->user_regs.eip = dsi.v_kernentry;
|
||||
+ ctxt->user_regs.eip = elf_uval(&elf, elf.ehdr, e_entry);
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -315,131 +350,6 @@ static inline int is_loadable_phdr(Elf32
|
||||
((phdr->p_flags & (PF_W|PF_X)) != 0));
|
||||
}
|
||||
|
||||
-static int parseelfimage(char *elfbase,
|
||||
- unsigned long elfsize,
|
||||
- struct domain_setup_info *dsi)
|
||||
-{
|
||||
- Elf32_Ehdr *ehdr = (Elf32_Ehdr *)elfbase;
|
||||
- Elf32_Phdr *phdr;
|
||||
- Elf32_Shdr *shdr;
|
||||
- unsigned long kernstart = ~0UL, kernend=0UL;
|
||||
- char *shstrtab;
|
||||
- int h;
|
||||
-
|
||||
- if ( !IS_ELF(*ehdr) )
|
||||
- {
|
||||
- xc_set_error(XC_INVALID_KERNEL,
|
||||
- "Kernel image does not have an ELF header.");
|
||||
- return -EINVAL;
|
||||
- }
|
||||
-
|
||||
- if ( (ehdr->e_phoff + (ehdr->e_phnum * ehdr->e_phentsize)) > elfsize )
|
||||
- {
|
||||
- xc_set_error(XC_INVALID_KERNEL,
|
||||
- "ELF program headers extend beyond end of image.");
|
||||
- return -EINVAL;
|
||||
- }
|
||||
-
|
||||
- if ( (ehdr->e_shoff + (ehdr->e_shnum * ehdr->e_shentsize)) > elfsize )
|
||||
- {
|
||||
- xc_set_error(XC_INVALID_KERNEL,
|
||||
- "ELF section headers extend beyond end of image.");
|
||||
- return -EINVAL;
|
||||
- }
|
||||
-
|
||||
- /* Find the section-header strings table. */
|
||||
- if ( ehdr->e_shstrndx == SHN_UNDEF )
|
||||
- {
|
||||
- xc_set_error(XC_INVALID_KERNEL,
|
||||
- "ELF image has no section-header strings table (shstrtab).");
|
||||
- return -EINVAL;
|
||||
- }
|
||||
- shdr = (Elf32_Shdr *)(elfbase + ehdr->e_shoff +
|
||||
- (ehdr->e_shstrndx*ehdr->e_shentsize));
|
||||
- shstrtab = elfbase + shdr->sh_offset;
|
||||
-
|
||||
- for ( h = 0; h < ehdr->e_phnum; h++ )
|
||||
- {
|
||||
- phdr = (Elf32_Phdr *)(elfbase + ehdr->e_phoff + (h*ehdr->e_phentsize));
|
||||
- if ( !is_loadable_phdr(phdr) )
|
||||
- continue;
|
||||
- if ( phdr->p_paddr < kernstart )
|
||||
- kernstart = phdr->p_paddr;
|
||||
- if ( (phdr->p_paddr + phdr->p_memsz) > kernend )
|
||||
- kernend = phdr->p_paddr + phdr->p_memsz;
|
||||
- }
|
||||
-
|
||||
- if ( (kernstart > kernend) ||
|
||||
- (ehdr->e_entry < kernstart) ||
|
||||
- (ehdr->e_entry > kernend) )
|
||||
- {
|
||||
- xc_set_error(XC_INVALID_KERNEL,
|
||||
- "Malformed ELF image.");
|
||||
- return -EINVAL;
|
||||
- }
|
||||
-
|
||||
- dsi->v_start = 0x00000000;
|
||||
-
|
||||
- dsi->v_kernstart = kernstart;
|
||||
- dsi->v_kernend = kernend;
|
||||
- dsi->v_kernentry = HVM_LOADER_ENTR_ADDR;
|
||||
-
|
||||
- dsi->v_end = dsi->v_kernend;
|
||||
-
|
||||
- return 0;
|
||||
-}
|
||||
-
|
||||
-static int
|
||||
-loadelfimage(
|
||||
- char *elfbase, int xch, uint32_t dom, unsigned long *parray,
|
||||
- struct domain_setup_info *dsi)
|
||||
-{
|
||||
- Elf32_Ehdr *ehdr = (Elf32_Ehdr *)elfbase;
|
||||
- Elf32_Phdr *phdr;
|
||||
- int h;
|
||||
-
|
||||
- char *va;
|
||||
- unsigned long pa, done, chunksz;
|
||||
-
|
||||
- for ( h = 0; h < ehdr->e_phnum; h++ )
|
||||
- {
|
||||
- phdr = (Elf32_Phdr *)(elfbase + ehdr->e_phoff + (h*ehdr->e_phentsize));
|
||||
- if ( !is_loadable_phdr(phdr) )
|
||||
- continue;
|
||||
-
|
||||
- for ( done = 0; done < phdr->p_filesz; done += chunksz )
|
||||
- {
|
||||
- pa = (phdr->p_paddr + done) - dsi->v_start;
|
||||
- if ((va = xc_map_foreign_range(
|
||||
- xch, dom, PAGE_SIZE, PROT_WRITE,
|
||||
- parray[pa >> PAGE_SHIFT])) == 0)
|
||||
- return -1;
|
||||
- chunksz = phdr->p_filesz - done;
|
||||
- if ( chunksz > (PAGE_SIZE - (pa & (PAGE_SIZE-1))) )
|
||||
- chunksz = PAGE_SIZE - (pa & (PAGE_SIZE-1));
|
||||
- memcpy(va + (pa & (PAGE_SIZE-1)),
|
||||
- elfbase + phdr->p_offset + done, chunksz);
|
||||
- munmap(va, PAGE_SIZE);
|
||||
- }
|
||||
-
|
||||
- for ( ; done < phdr->p_memsz; done += chunksz )
|
||||
- {
|
||||
- pa = (phdr->p_paddr + done) - dsi->v_start;
|
||||
- if ((va = xc_map_foreign_range(
|
||||
- xch, dom, PAGE_SIZE, PROT_WRITE,
|
||||
- parray[pa >> PAGE_SHIFT])) == 0)
|
||||
- return -1;
|
||||
- chunksz = phdr->p_memsz - done;
|
||||
- if ( chunksz > (PAGE_SIZE - (pa & (PAGE_SIZE-1))) )
|
||||
- chunksz = PAGE_SIZE - (pa & (PAGE_SIZE-1));
|
||||
- memset(va + (pa & (PAGE_SIZE-1)), 0, chunksz);
|
||||
- munmap(va, PAGE_SIZE);
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- return 0;
|
||||
-}
|
||||
-
|
||||
/* xc_hvm_build
|
||||
*
|
||||
* Create a domain for a virtualized Linux, using files/filenames
|
360
libelf-use-readnotes.diff
Normal file
360
libelf-use-readnotes.diff
Normal file
@ -0,0 +1,360 @@
|
||||
libelf: use for readnotes utility.
|
||||
|
||||
This patch makes the readnotes utility use libelf.
|
||||
|
||||
Signed-off-by: Gerd Hoffmann <kraxel@suse.de>
|
||||
---
|
||||
tools/xcutils/readnotes.c | 277 +++++++---------------------------------------
|
||||
1 file changed, 45 insertions(+), 232 deletions(-)
|
||||
|
||||
Index: build-32-unstable-12621/tools/xcutils/readnotes.c
|
||||
===================================================================
|
||||
--- build-32-unstable-12621.orig/tools/xcutils/readnotes.c
|
||||
+++ build-32-unstable-12621/tools/xcutils/readnotes.c
|
||||
@@ -1,4 +1,3 @@
|
||||
-#include <elf.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <inttypes.h>
|
||||
@@ -11,219 +10,35 @@
|
||||
#include <sys/stat.h>
|
||||
#include <sys/mman.h>
|
||||
|
||||
-#include <xen/elfnote.h>
|
||||
-
|
||||
-#define ELFNOTE_NAME(_n_) ((void*)(_n_) + sizeof(*(_n_)))
|
||||
-#define ELFNOTE_DESC(_n_) (ELFNOTE_NAME(_n_) + (((_n_)->n_namesz+3)&~3))
|
||||
-#define ELFNOTE_NEXT(_n_) (ELFNOTE_DESC(_n_) + (((_n_)->n_descsz+3)&~3))
|
||||
-
|
||||
-#ifndef ELFSIZE
|
||||
-#include <limits.h>
|
||||
-#if UINT_MAX == ULONG_MAX
|
||||
-#define ELFSIZE 32
|
||||
-#else
|
||||
-#define ELFSIZE 64
|
||||
-#endif
|
||||
-#endif
|
||||
-
|
||||
-#if (ELFSIZE == 32)
|
||||
-typedef Elf32_Nhdr Elf_Nhdr;
|
||||
-typedef Elf32_Half Elf_Half;
|
||||
-typedef Elf32_Word Elf_Word;
|
||||
-#elif (ELFSIZE == 64)
|
||||
-typedef Elf64_Nhdr Elf_Nhdr;
|
||||
-typedef Elf64_Half Elf_Half;
|
||||
-typedef Elf64_Word Elf_Word;
|
||||
-#else
|
||||
-#error "Unknown ELFSIZE"
|
||||
-#endif
|
||||
-
|
||||
-static void print_string_note(const char *prefix, Elf_Nhdr *note)
|
||||
-{
|
||||
- printf("%s: %s\n", prefix, (const char *)ELFNOTE_DESC(note));
|
||||
-}
|
||||
-
|
||||
-static void print_numeric_note(const char *prefix,Elf_Nhdr *note)
|
||||
-{
|
||||
- switch (note->n_descsz)
|
||||
- {
|
||||
- case 4:
|
||||
- printf("%s: %#010" PRIx32 " (4 bytes)\n",
|
||||
- prefix, *(uint32_t *)ELFNOTE_DESC(note));
|
||||
- break;
|
||||
- case 8:
|
||||
- printf("%s: %#018" PRIx64 " (8 bytes)\n",
|
||||
- prefix, *(uint64_t *)ELFNOTE_DESC(note));
|
||||
- break;
|
||||
- default:
|
||||
- printf("%s: unknown data size %#lx\n", prefix,
|
||||
- (unsigned long)note->n_descsz);
|
||||
- break;
|
||||
- }
|
||||
-}
|
||||
-
|
||||
-static inline int is_elf(void *image)
|
||||
-{
|
||||
- /*
|
||||
- * Since we are only accessing the e_ident field we can
|
||||
- * acccess the bytes directly without needing to figure out
|
||||
- * which version of Elf*_Ehdr structure to use.
|
||||
- */
|
||||
- const unsigned char *hdr = image;
|
||||
- return ( hdr[EI_MAG0] == ELFMAG0 &&
|
||||
- hdr[EI_MAG1] == ELFMAG1 &&
|
||||
- hdr[EI_MAG2] == ELFMAG2 &&
|
||||
- hdr[EI_MAG3] == ELFMAG3 );
|
||||
-}
|
||||
-
|
||||
-static inline unsigned char ehdr_class(void *image)
|
||||
-{
|
||||
- /*
|
||||
- * Since we are only accessing the e_ident field we can
|
||||
- * acccess the bytes directly without needing to figure out
|
||||
- * which version of Elf*_Ehdr structure to use.
|
||||
- */
|
||||
- const unsigned char *hdr = image;
|
||||
- switch (hdr[EI_CLASS])
|
||||
- {
|
||||
- case ELFCLASS32:
|
||||
- case ELFCLASS64:
|
||||
- return hdr[EI_CLASS];
|
||||
- default:
|
||||
- fprintf(stderr, "Unknown ELF class %d\n", hdr[EI_CLASS]);
|
||||
- exit(1);
|
||||
- }
|
||||
-}
|
||||
+#include <xg_private.h>
|
||||
|
||||
-static inline Elf_Half ehdr_shnum(void *image)
|
||||
-{
|
||||
- switch (ehdr_class(image))
|
||||
- {
|
||||
- case ELFCLASS32:
|
||||
- return ((Elf32_Ehdr *)image)->e_shnum;
|
||||
- case ELFCLASS64:
|
||||
- return ((Elf64_Ehdr *)image)->e_shnum;
|
||||
- default:
|
||||
- exit(1);
|
||||
- }
|
||||
-}
|
||||
+#include <xen/libelf.h>
|
||||
|
||||
-static inline Elf_Word shdr_type(void *image, int shnum)
|
||||
+static void print_string_note(const char *prefix, struct elf_binary *elf,
|
||||
+ const elf_note *note)
|
||||
{
|
||||
- switch (ehdr_class(image))
|
||||
- {
|
||||
- case ELFCLASS32:
|
||||
- {
|
||||
- Elf32_Ehdr *ehdr = (Elf32_Ehdr *)image;
|
||||
- Elf32_Shdr *shdr = (Elf32_Shdr*)(image + ehdr->e_shoff +
|
||||
- (shnum*ehdr->e_shentsize));
|
||||
- return shdr->sh_type;
|
||||
- }
|
||||
- case ELFCLASS64:
|
||||
- {
|
||||
- Elf64_Ehdr *ehdr = (Elf64_Ehdr *)image;
|
||||
- Elf64_Shdr *shdr = (Elf64_Shdr*)(image + ehdr->e_shoff +
|
||||
- (shnum*ehdr->e_shentsize));
|
||||
- return shdr->sh_type;
|
||||
- }
|
||||
- default:
|
||||
- exit(1);
|
||||
- }
|
||||
+ printf("%s: %s\n", prefix, (char*)elf_note_desc(elf, note));
|
||||
}
|
||||
|
||||
-static inline const char *shdr_name(void *image, int shnum)
|
||||
-{
|
||||
- const char *shstrtab;
|
||||
-
|
||||
- switch (ehdr_class(image))
|
||||
- {
|
||||
- case ELFCLASS32:
|
||||
- {
|
||||
- Elf32_Ehdr *ehdr = (Elf32_Ehdr *)image;
|
||||
- Elf32_Shdr *shdr;
|
||||
- /* Find the section-header strings table. */
|
||||
- if ( ehdr->e_shstrndx == SHN_UNDEF )
|
||||
- return NULL;
|
||||
- shdr = (Elf32_Shdr *)(image + ehdr->e_shoff +
|
||||
- (ehdr->e_shstrndx*ehdr->e_shentsize));
|
||||
- shstrtab = image + shdr->sh_offset;
|
||||
-
|
||||
- shdr= (Elf32_Shdr*)(image + ehdr->e_shoff +
|
||||
- (shnum*ehdr->e_shentsize));
|
||||
- return &shstrtab[shdr->sh_name];
|
||||
- }
|
||||
- case ELFCLASS64:
|
||||
- {
|
||||
- Elf64_Ehdr *ehdr = (Elf64_Ehdr *)image;
|
||||
- Elf64_Shdr *shdr;
|
||||
- /* Find the section-header strings table. */
|
||||
- if ( ehdr->e_shstrndx == SHN_UNDEF )
|
||||
- return NULL;
|
||||
- shdr = (Elf64_Shdr *)(image + ehdr->e_shoff +
|
||||
- (ehdr->e_shstrndx*ehdr->e_shentsize));
|
||||
- shstrtab = image + shdr->sh_offset;
|
||||
-
|
||||
- shdr= (Elf64_Shdr*)(image + ehdr->e_shoff +
|
||||
- (shnum*ehdr->e_shentsize));
|
||||
- return &shstrtab[shdr->sh_name];
|
||||
- }
|
||||
- default:
|
||||
- exit(1);
|
||||
- }
|
||||
-}
|
||||
-static inline void *shdr_start(void *image, int shnum)
|
||||
+static void print_numeric_note(const char *prefix, struct elf_binary *elf,
|
||||
+ const elf_note *note)
|
||||
{
|
||||
- switch (ehdr_class(image))
|
||||
- {
|
||||
- case ELFCLASS32:
|
||||
- {
|
||||
- Elf32_Ehdr *ehdr = (Elf32_Ehdr *)image;
|
||||
- Elf32_Shdr *shdr = (Elf32_Shdr*)(image + ehdr->e_shoff +
|
||||
- (shnum*ehdr->e_shentsize));
|
||||
- return image + shdr->sh_offset;
|
||||
- }
|
||||
- case ELFCLASS64:
|
||||
- {
|
||||
- Elf64_Ehdr *ehdr = (Elf64_Ehdr *)image;
|
||||
- Elf64_Shdr *shdr = (Elf64_Shdr*)(image + ehdr->e_shoff +
|
||||
- (shnum*ehdr->e_shentsize));
|
||||
- return image + shdr->sh_offset;
|
||||
- }
|
||||
- default:
|
||||
- exit(1);
|
||||
- }
|
||||
-}
|
||||
+ uint64_t value = elf_note_numeric(elf, note);
|
||||
+ int descsz = elf_uval(elf, note, descsz);
|
||||
|
||||
-static inline void *shdr_end(void *image, int shnum)
|
||||
-{
|
||||
- switch (ehdr_class(image))
|
||||
- {
|
||||
- case ELFCLASS32:
|
||||
- {
|
||||
- Elf32_Ehdr *ehdr = (Elf32_Ehdr *)image;
|
||||
- Elf32_Shdr *shdr = (Elf32_Shdr*)(image + ehdr->e_shoff +
|
||||
- (shnum*ehdr->e_shentsize));
|
||||
- return image + shdr->sh_offset + shdr->sh_size;
|
||||
- }
|
||||
- case ELFCLASS64:
|
||||
- {
|
||||
- Elf64_Ehdr *ehdr = (Elf64_Ehdr *)image;
|
||||
- Elf64_Shdr *shdr = (Elf64_Shdr*)(image + ehdr->e_shoff +
|
||||
- (shnum*ehdr->e_shentsize));
|
||||
- return image + shdr->sh_offset + shdr->sh_size;
|
||||
- }
|
||||
- default:
|
||||
- exit(1);
|
||||
- }
|
||||
+ printf("%s: %#*" PRIx64 " (%d bytes)\n",
|
||||
+ prefix, 2+2*descsz, value, descsz);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
const char *f;
|
||||
- int fd,h;
|
||||
+ int fd,h,size,count;
|
||||
void *image;
|
||||
struct stat st;
|
||||
- Elf_Nhdr *note;
|
||||
+ struct elf_binary elf;
|
||||
+ const elf_shdr *shdr;
|
||||
+ const elf_note *note, *end;
|
||||
|
||||
if (argc != 2)
|
||||
{
|
||||
@@ -251,76 +66,74 @@ int main(int argc, char **argv)
|
||||
fprintf(stderr, "Unable to map %s: %s\n", f, strerror(errno));
|
||||
return 1;
|
||||
}
|
||||
+ size = st.st_size;
|
||||
|
||||
- if ( !is_elf(image) )
|
||||
+ if (0 != elf_init(&elf, image, size))
|
||||
{
|
||||
fprintf(stderr, "File %s is not an ELF image\n", f);
|
||||
return 1;
|
||||
}
|
||||
+ elf_set_logfile(&elf, stderr, 0);
|
||||
|
||||
- for ( h=0; h < ehdr_shnum(image); h++)
|
||||
+ count = elf_shdr_count(&elf);
|
||||
+ for ( h=0; h < count; h++)
|
||||
{
|
||||
- if (shdr_type(image,h) != SHT_NOTE)
|
||||
+ shdr = elf_shdr_by_index(&elf, h);
|
||||
+ if (elf_uval(&elf, shdr, sh_type) != SHT_NOTE)
|
||||
continue;
|
||||
- for (note = (Elf_Nhdr*)shdr_start(image,h);
|
||||
- note < (Elf_Nhdr*)shdr_end(image,h);
|
||||
- note = (Elf_Nhdr*)(ELFNOTE_NEXT(note)))
|
||||
+ end = elf_section_end(&elf, shdr);
|
||||
+ for (note = elf_section_start(&elf, shdr);
|
||||
+ note < end;
|
||||
+ note = elf_note_next(&elf, note))
|
||||
{
|
||||
- switch(note->n_type)
|
||||
+ if (0 != strcmp(elf_note_name(&elf, note), "Xen"))
|
||||
+ continue;
|
||||
+ switch(elf_uval(&elf, note, type))
|
||||
{
|
||||
case XEN_ELFNOTE_INFO:
|
||||
- print_string_note("INFO", note);
|
||||
+ print_string_note("INFO", &elf , note);
|
||||
break;
|
||||
case XEN_ELFNOTE_ENTRY:
|
||||
- print_numeric_note("ENTRY", note);
|
||||
+ print_numeric_note("ENTRY", &elf , note);
|
||||
break;
|
||||
case XEN_ELFNOTE_HYPERCALL_PAGE:
|
||||
- print_numeric_note("HYPERCALL_PAGE", note);
|
||||
+ print_numeric_note("HYPERCALL_PAGE", &elf , note);
|
||||
break;
|
||||
case XEN_ELFNOTE_VIRT_BASE:
|
||||
- print_numeric_note("VIRT_BASE", note);
|
||||
+ print_numeric_note("VIRT_BASE", &elf , note);
|
||||
break;
|
||||
case XEN_ELFNOTE_PADDR_OFFSET:
|
||||
- print_numeric_note("PADDR_OFFSET", note);
|
||||
+ print_numeric_note("PADDR_OFFSET", &elf , note);
|
||||
break;
|
||||
case XEN_ELFNOTE_XEN_VERSION:
|
||||
- print_string_note("XEN_VERSION", note);
|
||||
+ print_string_note("XEN_VERSION", &elf , note);
|
||||
break;
|
||||
case XEN_ELFNOTE_GUEST_OS:
|
||||
- print_string_note("GUEST_OS", note);
|
||||
+ print_string_note("GUEST_OS", &elf , note);
|
||||
break;
|
||||
case XEN_ELFNOTE_GUEST_VERSION:
|
||||
- print_string_note("GUEST_VERSION", note);
|
||||
+ print_string_note("GUEST_VERSION", &elf , note);
|
||||
break;
|
||||
case XEN_ELFNOTE_LOADER:
|
||||
- print_string_note("LOADER", note);
|
||||
+ print_string_note("LOADER", &elf , note);
|
||||
break;
|
||||
case XEN_ELFNOTE_PAE_MODE:
|
||||
- print_string_note("PAE_MODE", note);
|
||||
+ print_string_note("PAE_MODE", &elf , note);
|
||||
break;
|
||||
case XEN_ELFNOTE_FEATURES:
|
||||
- print_string_note("FEATURES", note);
|
||||
+ print_string_note("FEATURES", &elf , note);
|
||||
break;
|
||||
default:
|
||||
- printf("unknown note type %#lx\n",
|
||||
- (unsigned long)note->n_type);
|
||||
+ printf("unknown note type %#x\n",
|
||||
+ (int)elf_uval(&elf, note, type));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- for ( h=0; h < ehdr_shnum(image); h++)
|
||||
- {
|
||||
- const char *name = shdr_name(image,h);
|
||||
-
|
||||
- if ( name == NULL )
|
||||
- continue;
|
||||
- if ( strcmp(name, "__xen_guest") != 0 )
|
||||
- continue;
|
||||
-
|
||||
- printf("__xen_guest: %s\n", (const char *)shdr_start(image, h));
|
||||
- break;
|
||||
- }
|
||||
+ shdr = elf_shdr_by_name(&elf, "__xen_guest");
|
||||
+ if (shdr)
|
||||
+ printf("__xen_guest: %s\n", (char*)elf_section_start(&elf, shdr));
|
||||
|
||||
return 0;
|
||||
}
|
722
libelf-use-xen-dom0.diff
Normal file
722
libelf-use-xen-dom0.diff
Normal file
@ -0,0 +1,722 @@
|
||||
libelf: use for x86 dom0 builder.
|
||||
|
||||
This patch switches the x86 dom0 builder over to libelf.
|
||||
|
||||
Signed-off-by: Gerd Hoffmann <kraxel@suse.de>
|
||||
---
|
||||
xen/arch/ia64/xen/domain.c | 79 +++++------
|
||||
xen/arch/x86/domain_build.c | 305 +++++++++++++++-----------------------------
|
||||
xen/common/Makefile | 4
|
||||
3 files changed, 149 insertions(+), 239 deletions(-)
|
||||
|
||||
Index: build-32-release304-13131/xen/common/Makefile
|
||||
===================================================================
|
||||
--- build-32-release304-13131.orig/xen/common/Makefile
|
||||
+++ build-32-release304-13131/xen/common/Makefile
|
||||
@@ -2,8 +2,8 @@ obj-y += acm_ops.o
|
||||
obj-y += bitmap.o
|
||||
obj-y += domctl.o
|
||||
obj-y += domain.o
|
||||
-obj-y += elf.o
|
||||
-obj-$(CONFIG_COMPAT) += elf32.o
|
||||
+#obj-y += elf.o
|
||||
+#obj-$(CONFIG_COMPAT) += elf32.o
|
||||
obj-y += event_channel.o
|
||||
obj-y += grant_table.o
|
||||
obj-y += kernel.o
|
||||
Index: build-32-release304-13131/xen/arch/x86/domain_build.c
|
||||
===================================================================
|
||||
--- build-32-release304-13131.orig/xen/arch/x86/domain_build.c
|
||||
+++ build-32-release304-13131/xen/arch/x86/domain_build.c
|
||||
@@ -13,7 +13,6 @@
|
||||
#include <xen/delay.h>
|
||||
#include <xen/event.h>
|
||||
#include <xen/console.h>
|
||||
-#include <xen/elf.h>
|
||||
#include <xen/kernel.h>
|
||||
#include <xen/domain.h>
|
||||
#include <xen/version.h>
|
||||
@@ -29,7 +28,7 @@
|
||||
#include <asm/shadow.h>
|
||||
|
||||
#include <public/version.h>
|
||||
-#include <public/elfnote.h>
|
||||
+#include <public/libelf.h>
|
||||
|
||||
extern unsigned long initial_images_nrpages(void);
|
||||
extern void discard_initial_images(void);
|
||||
@@ -190,69 +189,12 @@ static void process_dom0_ioports_disable
|
||||
}
|
||||
}
|
||||
|
||||
-static const char *feature_names[XENFEAT_NR_SUBMAPS*32] = {
|
||||
- [XENFEAT_writable_page_tables] = "writable_page_tables",
|
||||
- [XENFEAT_writable_descriptor_tables] = "writable_descriptor_tables",
|
||||
- [XENFEAT_auto_translated_physmap] = "auto_translated_physmap",
|
||||
- [XENFEAT_supervisor_mode_kernel] = "supervisor_mode_kernel",
|
||||
- [XENFEAT_pae_pgdir_above_4gb] = "pae_pgdir_above_4gb"
|
||||
-};
|
||||
-
|
||||
-static void parse_features(
|
||||
- const char *feats,
|
||||
- uint32_t supported[XENFEAT_NR_SUBMAPS],
|
||||
- uint32_t required[XENFEAT_NR_SUBMAPS])
|
||||
-{
|
||||
- const char *end, *p;
|
||||
- int i, req;
|
||||
-
|
||||
- if ( (end = strchr(feats, ',')) == NULL )
|
||||
- end = feats + strlen(feats);
|
||||
-
|
||||
- while ( feats < end )
|
||||
- {
|
||||
- p = strchr(feats, '|');
|
||||
- if ( (p == NULL) || (p > end) )
|
||||
- p = end;
|
||||
-
|
||||
- req = (*feats == '!');
|
||||
- if ( req )
|
||||
- feats++;
|
||||
-
|
||||
- for ( i = 0; i < XENFEAT_NR_SUBMAPS*32; i++ )
|
||||
- {
|
||||
- if ( feature_names[i] == NULL )
|
||||
- continue;
|
||||
-
|
||||
- if ( strncmp(feature_names[i], feats, p-feats) == 0 )
|
||||
- {
|
||||
- set_bit(i, supported);
|
||||
- if ( req )
|
||||
- set_bit(i, required);
|
||||
- break;
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- if ( i == XENFEAT_NR_SUBMAPS*32 )
|
||||
- {
|
||||
- printk("Unknown kernel feature \"%.*s\".\n",
|
||||
- (int)(p-feats), feats);
|
||||
- if ( req )
|
||||
- panic("Domain 0 requires an unknown hypervisor feature.\n");
|
||||
- }
|
||||
-
|
||||
- feats = p;
|
||||
- if ( *feats == '|' )
|
||||
- feats++;
|
||||
- }
|
||||
-}
|
||||
-
|
||||
int construct_dom0(struct domain *d,
|
||||
unsigned long _image_start, unsigned long image_len,
|
||||
unsigned long _initrd_start, unsigned long initrd_len,
|
||||
char *cmdline)
|
||||
{
|
||||
- int i, rc, dom0_pae, xen_pae, order;
|
||||
+ int i, rc, compatible, compat32, order, machine;
|
||||
struct cpu_user_regs *regs;
|
||||
unsigned long pfn, mfn;
|
||||
unsigned long nr_pages;
|
||||
@@ -263,9 +205,7 @@ int construct_dom0(struct domain *d,
|
||||
struct page_info *page = NULL;
|
||||
start_info_t *si;
|
||||
struct vcpu *v = d->vcpu[0];
|
||||
- const char *p;
|
||||
unsigned long long value;
|
||||
- int value_defined;
|
||||
#if defined(__i386__)
|
||||
char *image_start = (char *)_image_start; /* use lowmem mappings */
|
||||
char *initrd_start = (char *)_initrd_start; /* use lowmem mappings */
|
||||
@@ -287,7 +227,10 @@ int construct_dom0(struct domain *d,
|
||||
* *_start address are page-aligned, except v_start (and v_end) which are
|
||||
* superpage-aligned.
|
||||
*/
|
||||
- struct domain_setup_info dsi;
|
||||
+ struct elf_binary elf;
|
||||
+ struct elf_dom_parms parms;
|
||||
+ unsigned long vkern_start;
|
||||
+ unsigned long vkern_end;
|
||||
unsigned long vinitrd_start;
|
||||
unsigned long vinitrd_end;
|
||||
unsigned long vphysmap_start;
|
||||
@@ -298,6 +241,7 @@ int construct_dom0(struct domain *d,
|
||||
unsigned long vstack_end;
|
||||
unsigned long vpt_start;
|
||||
unsigned long vpt_end;
|
||||
+ unsigned long v_start;
|
||||
unsigned long v_end;
|
||||
|
||||
/* Machine address of next candidate page-table page. */
|
||||
@@ -312,21 +256,71 @@ int construct_dom0(struct domain *d,
|
||||
BUG_ON(d->vcpu[0] == NULL);
|
||||
BUG_ON(test_bit(_VCPUF_initialised, &v->vcpu_flags));
|
||||
|
||||
- memset(&dsi, 0, sizeof(struct domain_setup_info));
|
||||
- dsi.image_addr = (unsigned long)image_start;
|
||||
- dsi.image_len = image_len;
|
||||
-
|
||||
printk("*** LOADING DOMAIN 0 ***\n");
|
||||
|
||||
d->max_pages = ~0U;
|
||||
|
||||
nr_pages = compute_dom0_nr_pages();
|
||||
|
||||
- rc = parseelfimage(&dsi);
|
||||
+ if (0 != (rc = elf_init(&elf, image_start, image_len)))
|
||||
+ return rc;
|
||||
+#ifdef VERBOSE
|
||||
+ elf_set_verbose(&elf);
|
||||
+#endif
|
||||
+ elf_parse_binary(&elf);
|
||||
+ if (0 != (elf_xen_parse(&elf, &parms)))
|
||||
+ return rc;
|
||||
+
|
||||
+ /* compatibility check */
|
||||
+ compatible = 0;
|
||||
+ compat32 = 0;
|
||||
+ machine = elf_uval(&elf, elf.ehdr, e_machine);
|
||||
+ switch (CONFIG_PAGING_LEVELS) {
|
||||
+ case 2: /* x86_32 */
|
||||
+ if (parms.pae == PAEKERN_bimodal)
|
||||
+ parms.pae = PAEKERN_no;
|
||||
+ printk(" Xen kernel: 32-bit, lsb\n");
|
||||
+ if (elf_32bit(&elf) && !parms.pae && machine == EM_386)
|
||||
+ compatible = 1;
|
||||
+ break;
|
||||
+ case 3: /* x86_32p */
|
||||
+ if (parms.pae == PAEKERN_bimodal)
|
||||
+ parms.pae = PAEKERN_extended_cr3;
|
||||
+ printk(" Xen kernel: 32-bit, PAE, lsb\n");
|
||||
+ if (elf_32bit(&elf) && parms.pae && machine == EM_386)
|
||||
+ compatible = 1;
|
||||
+ break;
|
||||
+ case 4: /* x86_64 */
|
||||
+#ifndef CONFIG_COMPAT
|
||||
+ printk(" Xen kernel: 64-bit, lsb\n");
|
||||
+#else
|
||||
+ printk(" Xen kernel: 64-bit, lsb, compat32\n");
|
||||
+ if (elf_32bit(&elf) && parms.pae == PAEKERN_bimodal)
|
||||
+ parms.pae = PAEKERN_extended_cr3;
|
||||
+ if (elf_32bit(&elf) && parms.pae && machine == EM_386)
|
||||
+ {
|
||||
+ compat32 = 1;
|
||||
+ compatible = 1;
|
||||
+ }
|
||||
+#endif
|
||||
+ if (elf_64bit(&elf) && machine == EM_X86_64)
|
||||
+ compatible = 1;
|
||||
+ break;
|
||||
+ }
|
||||
+ printk(" Dom0 kernel: %s%s, %s, paddr 0x%" PRIx64 " -> 0x%" PRIx64 "\n",
|
||||
+ elf_64bit(&elf) ? "64-bit" : "32-bit",
|
||||
+ parms.pae ? ", PAE" : "",
|
||||
+ elf_msb(&elf) ? "msb" : "lsb",
|
||||
+ elf.pstart, elf.pend);
|
||||
+
|
||||
+ if ( !compatible )
|
||||
+ {
|
||||
+ printk("Mismatch between Xen and DOM0 kernel\n");
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
#ifdef CONFIG_COMPAT
|
||||
- if ( rc == -ENOSYS
|
||||
- && !compat_disabled
|
||||
- && (rc = parseelf32image(&dsi)) == 0 )
|
||||
+ if (compat32)
|
||||
{
|
||||
l1_pgentry_t gdt_l1e;
|
||||
|
||||
@@ -348,42 +342,10 @@ int construct_dom0(struct domain *d,
|
||||
local_flush_tlb_one(GDT_LDT_VIRT_START + FIRST_RESERVED_GDT_BYTE);
|
||||
}
|
||||
#endif
|
||||
- if ( rc != 0)
|
||||
- {
|
||||
- if ( rc == -ENOSYS )
|
||||
- printk("DOM0 image is not a Xen-compatible Elf image.\n");
|
||||
- return rc;
|
||||
- }
|
||||
-
|
||||
- xen_pae = (CONFIG_PAGING_LEVELS == 3) || IS_COMPAT(d);
|
||||
- if (dsi.pae_kernel == PAEKERN_bimodal)
|
||||
- dom0_pae = xen_pae;
|
||||
- else
|
||||
- dom0_pae = (dsi.pae_kernel != PAEKERN_no);
|
||||
- if ( dom0_pae != xen_pae )
|
||||
- {
|
||||
- printk("PAE mode mismatch between Xen and DOM0 (xen=%s, dom0=%s)\n",
|
||||
- xen_pae ? "yes" : "no", dom0_pae ? "yes" : "no");
|
||||
- return -EINVAL;
|
||||
- }
|
||||
-
|
||||
- if ( xen_pae && (dsi.pae_kernel == PAEKERN_extended_cr3 ||
|
||||
- dsi.pae_kernel == PAEKERN_bimodal) )
|
||||
+ if ( parms.pae == PAEKERN_extended_cr3 )
|
||||
set_bit(VMASST_TYPE_pae_extended_cr3, &d->vm_assist);
|
||||
|
||||
-#ifdef CONFIG_COMPAT
|
||||
- if ( IS_COMPAT(d) )
|
||||
- {
|
||||
- value = xen_elf32note_numeric(&dsi, XEN_ELFNOTE_HV_START_LOW, &value_defined);
|
||||
- p = xen_elf32note_string(&dsi, XEN_ELFNOTE_FEATURES);
|
||||
- }
|
||||
- else
|
||||
-#endif
|
||||
- {
|
||||
- value = xen_elfnote_numeric(&dsi, XEN_ELFNOTE_HV_START_LOW, &value_defined);
|
||||
- p = xen_elfnote_string(&dsi, XEN_ELFNOTE_FEATURES);
|
||||
- }
|
||||
- if ( value_defined )
|
||||
+ if ( UNSET_ADDR != parms.virt_hv_start_low && elf_32bit(&elf) )
|
||||
{
|
||||
#if CONFIG_PAGING_LEVELS < 4
|
||||
unsigned long mask = (1UL << L2_PAGETABLE_SHIFT) - 1;
|
||||
@@ -393,7 +355,7 @@ int construct_dom0(struct domain *d,
|
||||
: (1UL << L2_PAGETABLE_SHIFT) - 1;
|
||||
#endif
|
||||
|
||||
- value = (value + mask) & ~mask;
|
||||
+ value = (parms.virt_hv_start_low + mask) & ~mask;
|
||||
#ifdef CONFIG_COMPAT
|
||||
HYPERVISOR_COMPAT_VIRT_START(d) = max_t(unsigned int, m2p_compat_vstart, value);
|
||||
d->pa_bitsize = fls((1UL << 32) - HYPERVISOR_COMPAT_VIRT_START(d)) - 1
|
||||
@@ -406,21 +368,12 @@ int construct_dom0(struct domain *d,
|
||||
#endif
|
||||
panic("Domain 0 expects too high a hypervisor start address.\n");
|
||||
}
|
||||
- if ( p != NULL )
|
||||
- {
|
||||
- parse_features(p,
|
||||
- dom0_features_supported,
|
||||
- dom0_features_required);
|
||||
- printk("Domain 0 kernel supports features = { %08x }.\n",
|
||||
- dom0_features_supported[0]);
|
||||
- printk("Domain 0 kernel requires features = { %08x }.\n",
|
||||
- dom0_features_required[0]);
|
||||
- if ( dom0_features_required[0] )
|
||||
+
|
||||
+ if ( parms.f_required[0] /* Huh? -- kraxel */ )
|
||||
panic("Domain 0 requires an unsupported hypervisor feature.\n");
|
||||
- }
|
||||
|
||||
/* Align load address to 4MB boundary. */
|
||||
- dsi.v_start &= ~((1UL<<22)-1);
|
||||
+ v_start = parms.virt_base & ~((1UL<<22)-1);
|
||||
|
||||
/*
|
||||
* Why do we need this? The number of page-table frames depends on the
|
||||
@@ -429,7 +382,9 @@ int construct_dom0(struct domain *d,
|
||||
* read-only). We have a pair of simultaneous equations in two unknowns,
|
||||
* which we solve by exhaustive search.
|
||||
*/
|
||||
- vinitrd_start = round_pgup(dsi.v_end);
|
||||
+ vkern_start = parms.virt_kstart;
|
||||
+ vkern_end = parms.virt_kend;
|
||||
+ vinitrd_start = round_pgup(vkern_end);
|
||||
vinitrd_end = vinitrd_start + initrd_len;
|
||||
vphysmap_start = round_pgup(vinitrd_end);
|
||||
vphysmap_end = vphysmap_start + (nr_pages * (!IS_COMPAT(d) ?
|
||||
@@ -449,12 +404,12 @@ int construct_dom0(struct domain *d,
|
||||
if ( (v_end - vstack_end) < (512UL << 10) )
|
||||
v_end += 1UL << 22; /* Add extra 4MB to get >= 512kB padding. */
|
||||
#if defined(__i386__) && !defined(CONFIG_X86_PAE)
|
||||
- if ( (((v_end - dsi.v_start + ((1UL<<L2_PAGETABLE_SHIFT)-1)) >>
|
||||
+ if ( (((v_end - v_start + ((1UL<<L2_PAGETABLE_SHIFT)-1)) >>
|
||||
L2_PAGETABLE_SHIFT) + 1) <= nr_pt_pages )
|
||||
break;
|
||||
#elif defined(__i386__) && defined(CONFIG_X86_PAE)
|
||||
/* 5 pages: 1x 3rd + 4x 2nd level */
|
||||
- if ( (((v_end - dsi.v_start + ((1UL<<L2_PAGETABLE_SHIFT)-1)) >>
|
||||
+ if ( (((v_end - v_start + ((1UL<<L2_PAGETABLE_SHIFT)-1)) >>
|
||||
L2_PAGETABLE_SHIFT) + 5) <= nr_pt_pages )
|
||||
break;
|
||||
#elif defined(__x86_64__)
|
||||
@@ -462,24 +417,24 @@ int construct_dom0(struct domain *d,
|
||||
(((((_h) + ((1UL<<(_s))-1)) & ~((1UL<<(_s))-1)) - \
|
||||
((_l) & ~((1UL<<(_s))-1))) >> (_s))
|
||||
if ( (1 + /* # L4 */
|
||||
- NR(dsi.v_start, v_end, L4_PAGETABLE_SHIFT) + /* # L3 */
|
||||
+ NR(v_start, v_end, L4_PAGETABLE_SHIFT) + /* # L3 */
|
||||
(!IS_COMPAT(d) ?
|
||||
- NR(dsi.v_start, v_end, L3_PAGETABLE_SHIFT) : /* # L2 */
|
||||
+ NR(v_start, v_end, L3_PAGETABLE_SHIFT) : /* # L2 */
|
||||
4) + /* # compat L2 */
|
||||
- NR(dsi.v_start, v_end, L2_PAGETABLE_SHIFT)) /* # L1 */
|
||||
+ NR(v_start, v_end, L2_PAGETABLE_SHIFT)) /* # L1 */
|
||||
<= nr_pt_pages )
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
|
||||
- order = get_order_from_bytes(v_end - dsi.v_start);
|
||||
+ order = get_order_from_bytes(v_end - v_start);
|
||||
if ( (1UL << order) > nr_pages )
|
||||
panic("Domain 0 allocation is too small for kernel image.\n");
|
||||
|
||||
#ifdef __i386__
|
||||
/* Ensure that our low-memory 1:1 mapping covers the allocation. */
|
||||
page = alloc_domheap_pages(d, order,
|
||||
- MEMF_bits(30 + (dsi.v_start >> 31)));
|
||||
+ MEMF_bits(30 + (v_start >> 31)));
|
||||
#else
|
||||
page = alloc_domheap_pages(d, order, 0);
|
||||
#endif
|
||||
@@ -502,24 +457,24 @@ int construct_dom0(struct domain *d,
|
||||
" Page tables: %p->%p\n"
|
||||
" Boot stack: %p->%p\n"
|
||||
" TOTAL: %p->%p\n",
|
||||
- _p(dsi.v_kernstart), _p(dsi.v_kernend),
|
||||
+ _p(vkern_start), _p(vkern_end),
|
||||
_p(vinitrd_start), _p(vinitrd_end),
|
||||
_p(vphysmap_start), _p(vphysmap_end),
|
||||
_p(vstartinfo_start), _p(vstartinfo_end),
|
||||
_p(vpt_start), _p(vpt_end),
|
||||
_p(vstack_start), _p(vstack_end),
|
||||
- _p(dsi.v_start), _p(v_end));
|
||||
- printk(" ENTRY ADDRESS: %p\n", _p(dsi.v_kernentry));
|
||||
+ _p(v_start), _p(v_end));
|
||||
+ printk(" ENTRY ADDRESS: %p\n", _p(parms.virt_entry));
|
||||
|
||||
- if ( ((v_end - dsi.v_start)>>PAGE_SHIFT) > nr_pages )
|
||||
+ if ( ((v_end - v_start)>>PAGE_SHIFT) > nr_pages )
|
||||
{
|
||||
printk("Initial guest OS requires too much space\n"
|
||||
"(%luMB is greater than %luMB limit)\n",
|
||||
- (v_end-dsi.v_start)>>20, nr_pages>>(20-PAGE_SHIFT));
|
||||
+ (v_end-v_start)>>20, nr_pages>>(20-PAGE_SHIFT));
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
- mpt_alloc = (vpt_start - dsi.v_start) +
|
||||
+ mpt_alloc = (vpt_start - v_start) +
|
||||
(unsigned long)pfn_to_paddr(alloc_spfn);
|
||||
|
||||
#if defined(__i386__)
|
||||
@@ -527,7 +482,7 @@ int construct_dom0(struct domain *d,
|
||||
* Protect the lowest 1GB of memory. We use a temporary mapping there
|
||||
* from which we copy the kernel and ramdisk images.
|
||||
*/
|
||||
- if ( dsi.v_start < (1UL<<30) )
|
||||
+ if ( v_start < (1UL<<30) )
|
||||
{
|
||||
printk("Initial loading isn't allowed to lowest 1GB of memory.\n");
|
||||
return -EINVAL;
|
||||
@@ -557,9 +512,9 @@ int construct_dom0(struct domain *d,
|
||||
l2e_from_page(virt_to_page(d->arch.mm_perdomain_pt) + i,
|
||||
__PAGE_HYPERVISOR);
|
||||
|
||||
- l2tab += l2_linear_offset(dsi.v_start);
|
||||
+ l2tab += l2_linear_offset(v_start);
|
||||
mfn = alloc_spfn;
|
||||
- for ( count = 0; count < ((v_end-dsi.v_start)>>PAGE_SHIFT); count++ )
|
||||
+ for ( count = 0; count < ((v_end-v_start)>>PAGE_SHIFT); count++ )
|
||||
{
|
||||
if ( !((unsigned long)l1tab & (PAGE_SIZE-1)) )
|
||||
{
|
||||
@@ -569,7 +524,7 @@ int construct_dom0(struct domain *d,
|
||||
l2tab++;
|
||||
clear_page(l1tab);
|
||||
if ( count == 0 )
|
||||
- l1tab += l1_table_offset(dsi.v_start);
|
||||
+ l1tab += l1_table_offset(v_start);
|
||||
}
|
||||
*l1tab = l1e_from_pfn(mfn, L1_PROT);
|
||||
l1tab++;
|
||||
@@ -659,7 +614,7 @@ int construct_dom0(struct domain *d,
|
||||
|
||||
/* Overlap with Xen protected area? */
|
||||
if ( !IS_COMPAT(d) ?
|
||||
- ((dsi.v_start < HYPERVISOR_VIRT_END) &&
|
||||
+ ((v_start < HYPERVISOR_VIRT_END) &&
|
||||
(v_end > HYPERVISOR_VIRT_START)) :
|
||||
(v_end > HYPERVISOR_COMPAT_VIRT_START(d)) )
|
||||
{
|
||||
@@ -699,9 +654,9 @@ int construct_dom0(struct domain *d,
|
||||
panic("Not enough RAM for domain 0 hypercall argument translation.\n");
|
||||
}
|
||||
|
||||
- l4tab += l4_table_offset(dsi.v_start);
|
||||
+ l4tab += l4_table_offset(v_start);
|
||||
mfn = alloc_spfn;
|
||||
- for ( count = 0; count < ((v_end-dsi.v_start)>>PAGE_SHIFT); count++ )
|
||||
+ for ( count = 0; count < ((v_end-v_start)>>PAGE_SHIFT); count++ )
|
||||
{
|
||||
if ( !((unsigned long)l1tab & (PAGE_SIZE-1)) )
|
||||
{
|
||||
@@ -709,14 +664,14 @@ int construct_dom0(struct domain *d,
|
||||
l1start = l1tab = __va(mpt_alloc); mpt_alloc += PAGE_SIZE;
|
||||
clear_page(l1tab);
|
||||
if ( count == 0 )
|
||||
- l1tab += l1_table_offset(dsi.v_start);
|
||||
+ l1tab += l1_table_offset(v_start);
|
||||
if ( !((unsigned long)l2tab & (PAGE_SIZE-1)) )
|
||||
{
|
||||
maddr_to_page(mpt_alloc)->u.inuse.type_info = PGT_l2_page_table;
|
||||
l2start = l2tab = __va(mpt_alloc); mpt_alloc += PAGE_SIZE;
|
||||
clear_page(l2tab);
|
||||
if ( count == 0 )
|
||||
- l2tab += l2_table_offset(dsi.v_start);
|
||||
+ l2tab += l2_table_offset(v_start);
|
||||
if ( !((unsigned long)l3tab & (PAGE_SIZE-1)) )
|
||||
{
|
||||
maddr_to_page(mpt_alloc)->u.inuse.type_info =
|
||||
@@ -724,7 +679,7 @@ int construct_dom0(struct domain *d,
|
||||
l3start = l3tab = __va(mpt_alloc); mpt_alloc += PAGE_SIZE;
|
||||
clear_page(l3tab);
|
||||
if ( count == 0 )
|
||||
- l3tab += l3_table_offset(dsi.v_start);
|
||||
+ l3tab += l3_table_offset(v_start);
|
||||
*l4tab = l4e_from_paddr(__pa(l3start), L4_PROT);
|
||||
l4tab++;
|
||||
}
|
||||
@@ -837,30 +792,20 @@ int construct_dom0(struct domain *d,
|
||||
write_ptbase(v);
|
||||
|
||||
/* Copy the OS image and free temporary buffer. */
|
||||
-#ifdef CONFIG_COMPAT
|
||||
- if ( IS_COMPAT(d) )
|
||||
- {
|
||||
- (void)loadelf32image(&dsi);
|
||||
- value =
|
||||
- xen_elf32note_numeric(&dsi, XEN_ELFNOTE_HYPERCALL_PAGE, &value_defined);
|
||||
- }
|
||||
- else
|
||||
-#endif
|
||||
- {
|
||||
- (void)loadelfimage(&dsi);
|
||||
- value =
|
||||
- xen_elfnote_numeric(&dsi, XEN_ELFNOTE_HYPERCALL_PAGE, &value_defined);
|
||||
- }
|
||||
- if ( value_defined )
|
||||
+ elf.dest = (void*)vkern_start;
|
||||
+ elf_load_binary(&elf);
|
||||
+
|
||||
+ if ( UNSET_ADDR != parms.virt_hypercall )
|
||||
{
|
||||
- if ( (value < dsi.v_start) || (value >= v_end) )
|
||||
+ if ( (parms.virt_hypercall < v_start) ||
|
||||
+ (parms.virt_hypercall >= v_end) )
|
||||
{
|
||||
write_ptbase(current);
|
||||
local_irq_enable();
|
||||
printk("Invalid HYPERCALL_PAGE field in ELF notes.\n");
|
||||
return -1;
|
||||
}
|
||||
- hypercall_page_initialise(d, (void *)(unsigned long)value);
|
||||
+ hypercall_page_initialise(d, (void *)(unsigned long)parms.virt_hypercall);
|
||||
}
|
||||
|
||||
/* Copy the initial ramdisk. */
|
||||
@@ -883,14 +828,15 @@ int construct_dom0(struct domain *d,
|
||||
si->mfn_list = vphysmap_start;
|
||||
sprintf(si->magic, "xen-%i.%i-x86_%d%s",
|
||||
xen_major_version(), xen_minor_version(),
|
||||
- !IS_COMPAT(d) ? BITS_PER_LONG : 32, xen_pae ? "p" : "");
|
||||
+ elf_64bit(&elf) ? 64 : 32,
|
||||
+ parms.pae ? "p" : "");
|
||||
|
||||
/* Write the phys->machine and machine->phys table entries. */
|
||||
for ( pfn = 0; pfn < d->tot_pages; pfn++ )
|
||||
{
|
||||
mfn = pfn + alloc_spfn;
|
||||
#ifndef NDEBUG
|
||||
-#define REVERSE_START ((v_end - dsi.v_start) >> PAGE_SHIFT)
|
||||
+#define REVERSE_START ((v_end - v_start) >> PAGE_SHIFT)
|
||||
if ( pfn > REVERSE_START )
|
||||
mfn = alloc_epfn - (pfn - REVERSE_START);
|
||||
#endif
|
||||
@@ -971,7 +917,7 @@ int construct_dom0(struct domain *d,
|
||||
: FLAT_COMPAT_KERNEL_DS;
|
||||
regs->ss = !IS_COMPAT(d) ? FLAT_KERNEL_SS : FLAT_COMPAT_KERNEL_SS;
|
||||
regs->cs = !IS_COMPAT(d) ? FLAT_KERNEL_CS : FLAT_COMPAT_KERNEL_CS;
|
||||
- regs->eip = dsi.v_kernentry;
|
||||
+ regs->eip = parms.virt_entry;
|
||||
regs->esp = vstack_end;
|
||||
regs->esi = vstartinfo_start;
|
||||
regs->eflags = X86_EFLAGS_IF;
|
||||
@@ -1042,41 +988,6 @@ int construct_dom0(struct domain *d,
|
||||
return 0;
|
||||
}
|
||||
|
||||
-int elf_sanity_check(const Elf_Ehdr *ehdr)
|
||||
-{
|
||||
- if ( !IS_ELF(*ehdr) ||
|
||||
-#if defined(__i386__)
|
||||
- (ehdr->e_ident[EI_CLASS] != ELFCLASS32) ||
|
||||
- (ehdr->e_machine != EM_386) ||
|
||||
-#elif defined(__x86_64__)
|
||||
- (ehdr->e_ident[EI_CLASS] != ELFCLASS64) ||
|
||||
- (ehdr->e_machine != EM_X86_64) ||
|
||||
-#endif
|
||||
- (ehdr->e_ident[EI_DATA] != ELFDATA2LSB) ||
|
||||
- (ehdr->e_type != ET_EXEC) )
|
||||
- {
|
||||
- return 0;
|
||||
- }
|
||||
-
|
||||
- return 1;
|
||||
-}
|
||||
-
|
||||
-#ifdef CONFIG_COMPAT
|
||||
-int elf32_sanity_check(const Elf32_Ehdr *ehdr)
|
||||
-{
|
||||
- if ( !IS_ELF(*ehdr) ||
|
||||
- (ehdr->e_ident[EI_CLASS] != ELFCLASS32) ||
|
||||
- (ehdr->e_machine != EM_386) ||
|
||||
- (ehdr->e_ident[EI_DATA] != ELFDATA2LSB) ||
|
||||
- (ehdr->e_type != ET_EXEC) )
|
||||
- {
|
||||
- return 0;
|
||||
- }
|
||||
-
|
||||
- return 1;
|
||||
-}
|
||||
-#endif
|
||||
-
|
||||
/*
|
||||
* Local variables:
|
||||
* mode: C
|
||||
Index: build-32-release304-13131/xen/arch/ia64/xen/domain.c
|
||||
===================================================================
|
||||
--- build-32-release304-13131.orig/xen/arch/ia64/xen/domain.c
|
||||
+++ build-32-release304-13131/xen/arch/ia64/xen/domain.c
|
||||
@@ -31,7 +31,7 @@
|
||||
#include <xen/event.h>
|
||||
#include <xen/console.h>
|
||||
#include <xen/version.h>
|
||||
-#include <xen/elf.h>
|
||||
+#include <public/libelf.h>
|
||||
#include <asm/pgalloc.h>
|
||||
#include <asm/offsets.h> /* for IA64_THREAD_INFO_SIZE */
|
||||
#include <asm/vcpu.h> /* for function declarations */
|
||||
@@ -866,38 +866,23 @@ int shadow_mode_control(struct domain *d
|
||||
#define privify_memory(x,y) do {} while(0)
|
||||
#endif
|
||||
|
||||
-// see arch/x86/xxx/domain_build.c
|
||||
-int elf_sanity_check(Elf_Ehdr *ehdr)
|
||||
-{
|
||||
- if (!(IS_ELF(*ehdr)))
|
||||
- {
|
||||
- printk("DOM0 image is not a Xen-compatible Elf image.\n");
|
||||
- return 0;
|
||||
- }
|
||||
- return 1;
|
||||
-}
|
||||
-
|
||||
-static void loaddomainelfimage(struct domain *d, unsigned long image_start)
|
||||
+static void loaddomainelfimage(struct domain *d, struct elf_binary *elf)
|
||||
{
|
||||
- char *elfbase = (char *) image_start;
|
||||
- Elf_Ehdr ehdr;
|
||||
- Elf_Phdr phdr;
|
||||
- int h, filesz, memsz;
|
||||
+ const elf_phdr *phdr;
|
||||
+ int h, phnum, filesz, memsz;
|
||||
unsigned long elfaddr, dom_mpaddr, dom_imva;
|
||||
struct page_info *p;
|
||||
-
|
||||
- memcpy(&ehdr, (void *) image_start, sizeof(Elf_Ehdr));
|
||||
- for ( h = 0; h < ehdr.e_phnum; h++ ) {
|
||||
- memcpy(&phdr,
|
||||
- elfbase + ehdr.e_phoff + (h*ehdr.e_phentsize),
|
||||
- sizeof(Elf_Phdr));
|
||||
- if ((phdr.p_type != PT_LOAD))
|
||||
+
|
||||
+ phnum = elf_uval(elf, elf->ehdr, e_phnum);
|
||||
+ for ( h = 0; h < phnum; h++ ) {
|
||||
+ phdr = elf_phdr_by_index(elf, h);
|
||||
+ if (!elf_phdr_is_loadable(elf, phdr))
|
||||
continue;
|
||||
|
||||
- filesz = phdr.p_filesz;
|
||||
- memsz = phdr.p_memsz;
|
||||
- elfaddr = (unsigned long) elfbase + phdr.p_offset;
|
||||
- dom_mpaddr = phdr.p_paddr;
|
||||
+ filesz = elf_uval(elf, phdr, p_filesz);
|
||||
+ memsz = elf_uval(elf, phdr, p_memsz);
|
||||
+ elfaddr = (unsigned long) elf->image + elf_uval(elf, phdr, p_offset);
|
||||
+ dom_mpaddr = elf_uval(elf, phdr, p_paddr);
|
||||
|
||||
while (memsz > 0) {
|
||||
p = assign_new_domain_page(d,dom_mpaddr);
|
||||
@@ -917,7 +902,7 @@ static void loaddomainelfimage(struct do
|
||||
PAGE_SIZE-filesz);
|
||||
}
|
||||
//FIXME: This test for code seems to find a lot more than objdump -x does
|
||||
- if (phdr.p_flags & PF_X) {
|
||||
+ if (elf_uval(elf, phdr, p_flags) & PF_X) {
|
||||
privify_memory(dom_imva,PAGE_SIZE);
|
||||
flush_icache_range(dom_imva,
|
||||
dom_imva+PAGE_SIZE);
|
||||
@@ -980,7 +965,8 @@ int construct_dom0(struct domain *d,
|
||||
struct vcpu *v = d->vcpu[0];
|
||||
unsigned long max_pages;
|
||||
|
||||
- struct domain_setup_info dsi;
|
||||
+ struct elf_binary elf;
|
||||
+ struct elf_dom_parms parms;
|
||||
unsigned long p_start;
|
||||
unsigned long pkern_start;
|
||||
unsigned long pkern_entry;
|
||||
@@ -1004,18 +990,31 @@ int construct_dom0(struct domain *d,
|
||||
BUG_ON(d->vcpu[0] == NULL);
|
||||
BUG_ON(test_bit(_VCPUF_initialised, &v->vcpu_flags));
|
||||
|
||||
- memset(&dsi, 0, sizeof(struct domain_setup_info));
|
||||
-
|
||||
printk("*** LOADING DOMAIN 0 ***\n");
|
||||
|
||||
max_pages = dom0_size / PAGE_SIZE;
|
||||
d->max_pages = max_pages;
|
||||
d->tot_pages = 0;
|
||||
- dsi.image_addr = (unsigned long)image_start;
|
||||
- dsi.image_len = image_len;
|
||||
- rc = parseelfimage(&dsi);
|
||||
+
|
||||
+ rc = elf_init(&elf, (void*)image_start, image_len);
|
||||
if ( rc != 0 )
|
||||
return rc;
|
||||
+#ifdef VERBOSE
|
||||
+ elf_set_verbose(&elf);
|
||||
+#endif
|
||||
+ elf_parse_binary(&elf);
|
||||
+ if (0 != (elf_xen_parse(&elf, &parms)))
|
||||
+ return rc;
|
||||
+
|
||||
+ printk(" Dom0 kernel: %s, %s, paddr 0x%" PRIx64 " -> 0x%" PRIx64 "\n",
|
||||
+ elf_64bit(&elf) ? "64-bit" : "32-bit",
|
||||
+ elf_msb(&elf) ? "msb" : "lsb",
|
||||
+ elf.pstart, elf.pend);
|
||||
+ if (!elf_64bit(&elf) ||
|
||||
+ elf_uval(&elf, elf.ehdr, e_machine) != EM_IA_64) {
|
||||
+ printk("Incompatible kernel binary\n");
|
||||
+ return -1;
|
||||
+ }
|
||||
|
||||
#ifdef VALIDATE_VT
|
||||
/* Temp workaround */
|
||||
@@ -1034,10 +1033,10 @@ int construct_dom0(struct domain *d,
|
||||
}
|
||||
#endif
|
||||
|
||||
- p_start = dsi.v_start;
|
||||
- pkern_start = dsi.v_kernstart;
|
||||
- pkern_end = dsi.v_kernend;
|
||||
- pkern_entry = dsi.v_kernentry;
|
||||
+ p_start = parms.virt_base;
|
||||
+ pkern_start = parms.virt_kstart;
|
||||
+ pkern_end = parms.virt_kend;
|
||||
+ pkern_entry = parms.virt_entry;
|
||||
|
||||
//printk("p_start=%lx, pkern_start=%lx, pkern_end=%lx, pkern_entry=%lx\n",p_start,pkern_start,pkern_end,pkern_entry);
|
||||
|
||||
@@ -1107,7 +1106,7 @@ int construct_dom0(struct domain *d,
|
||||
printk ("Cannot allocate dom0 vcpu %d\n", i);
|
||||
|
||||
/* Copy the OS image. */
|
||||
- loaddomainelfimage(d,image_start);
|
||||
+ loaddomainelfimage(d,&elf);
|
||||
|
||||
/* Copy the initial ramdisk. */
|
||||
//if ( initrd_len != 0 )
|
111
libxc-logging.diff
Normal file
111
libxc-logging.diff
Normal file
@ -0,0 +1,111 @@
|
||||
debug: log libxc output to /var/log/xen/libxc.log
|
||||
|
||||
sledge hammer patch ;)
|
||||
---
|
||||
tools/libxc/xc_dom_compat_linux.c | 2 ++
|
||||
tools/libxc/xc_hvm_build.c | 2 ++
|
||||
tools/libxc/xc_linux_build.c | 2 ++
|
||||
tools/libxc/xc_private.c | 9 +++++++++
|
||||
tools/libxc/xc_private.h | 11 +++++++----
|
||||
5 files changed, 22 insertions(+), 4 deletions(-)
|
||||
|
||||
Index: build-64-release304-13087/tools/libxc/xc_hvm_build.c
|
||||
===================================================================
|
||||
--- build-64-release304-13087.orig/tools/libxc/xc_hvm_build.c
|
||||
+++ build-64-release304-13087/tools/libxc/xc_hvm_build.c
|
||||
@@ -310,6 +310,8 @@ static int xc_hvm_build_internal(int xc_
|
||||
vcpu_guest_context_t ctxt;
|
||||
int rc;
|
||||
|
||||
+ log_kraxel();
|
||||
+
|
||||
if ( (image == NULL) || (image_size == 0) )
|
||||
{
|
||||
ERROR("Image required");
|
||||
Index: build-64-release304-13087/tools/libxc/xc_linux_build.c
|
||||
===================================================================
|
||||
--- build-64-release304-13087.orig/tools/libxc/xc_linux_build.c
|
||||
+++ build-64-release304-13087/tools/libxc/xc_linux_build.c
|
||||
@@ -1099,6 +1099,8 @@ static int xc_linux_build_internal(int x
|
||||
unsigned long vstartinfo_start, vkern_entry, vstack_start;
|
||||
uint32_t features_bitmap[XENFEAT_NR_SUBMAPS] = { 0, };
|
||||
|
||||
+ log_kraxel();
|
||||
+
|
||||
if ( features != NULL )
|
||||
{
|
||||
if ( !parse_features(features, features_bitmap, NULL) )
|
||||
Index: build-64-release304-13087/tools/libxc/xc_private.c
|
||||
===================================================================
|
||||
--- build-64-release304-13087.orig/tools/libxc/xc_private.c
|
||||
+++ build-64-release304-13087/tools/libxc/xc_private.c
|
||||
@@ -88,6 +88,15 @@ void xc_set_error(int code, const char *
|
||||
error_handler(&last_error);
|
||||
}
|
||||
|
||||
+FILE *kraxel;
|
||||
+
|
||||
+void log_kraxel(void)
|
||||
+{
|
||||
+ kraxel = fopen("/var/log/xen/libxc.log", "a");
|
||||
+ setvbuf(kraxel, NULL, _IONBF, 0);
|
||||
+ fprintf(kraxel, "--- started ---\n");
|
||||
+}
|
||||
+
|
||||
int lock_pages(void *addr, size_t len)
|
||||
{
|
||||
int e = 0;
|
||||
Index: build-64-release304-13087/tools/libxc/xc_private.h
|
||||
===================================================================
|
||||
--- build-64-release304-13087.orig/tools/libxc/xc_private.h
|
||||
+++ build-64-release304-13087/tools/libxc/xc_private.h
|
||||
@@ -39,22 +39,25 @@
|
||||
|
||||
#define DEBUG 1
|
||||
#define INFO 1
|
||||
-#define PROGRESS 0
|
||||
+#define PROGRESS 1
|
||||
+
|
||||
+extern FILE *kraxel;
|
||||
+void log_kraxel(void);
|
||||
|
||||
#if INFO
|
||||
-#define IPRINTF(_f, _a...) printf(_f , ## _a)
|
||||
+#define IPRINTF(_f, _a...) fprintf(kraxel, _f , ## _a)
|
||||
#else
|
||||
#define IPRINTF(_f, _a...) ((void)0)
|
||||
#endif
|
||||
|
||||
#if DEBUG
|
||||
-#define DPRINTF(_f, _a...) fprintf(stderr, _f , ## _a)
|
||||
+#define DPRINTF(_f, _a...) fprintf(kraxel, _f , ## _a)
|
||||
#else
|
||||
#define DPRINTF(_f, _a...) ((void)0)
|
||||
#endif
|
||||
|
||||
#if PROGRESS
|
||||
-#define PPRINTF(_f, _a...) fprintf(stderr, _f , ## _a)
|
||||
+#define PPRINTF(_f, _a...) fprintf(kraxel, _f , ## _a)
|
||||
#else
|
||||
#define PPRINTF(_f, _a...)
|
||||
#endif
|
||||
Index: build-64-release304-13087/tools/libxc/xc_dom_compat_linux.c
|
||||
===================================================================
|
||||
--- build-64-release304-13087.orig/tools/libxc/xc_dom_compat_linux.c
|
||||
+++ build-64-release304-13087/tools/libxc/xc_dom_compat_linux.c
|
||||
@@ -74,6 +74,7 @@ int xc_linux_build_mem(int xc_handle, ui
|
||||
int rc;
|
||||
|
||||
xc_dom_loginit();
|
||||
+ log_kraxel();
|
||||
dom = xc_dom_allocate(cmdline, features);
|
||||
if (0 != (rc = xc_dom_kernel_mem(dom, image_buffer, image_size)))
|
||||
goto out;
|
||||
@@ -106,6 +107,7 @@ int xc_linux_build(int xc_handle, uint32
|
||||
int rc;
|
||||
|
||||
xc_dom_loginit();
|
||||
+ log_kraxel();
|
||||
dom = xc_dom_allocate(cmdline, features);
|
||||
if (0 != (rc = xc_dom_kernel_file(dom, image_name)))
|
||||
goto out;
|
244
mem-zones.patch
Normal file
244
mem-zones.patch
Normal file
@ -0,0 +1,244 @@
|
||||
Index: xen-3.0.4-testing/xen/common/page_alloc.c
|
||||
===================================================================
|
||||
--- xen-3.0.4-testing.orig/xen/common/page_alloc.c
|
||||
+++ xen-3.0.4-testing/xen/common/page_alloc.c
|
||||
@@ -67,16 +67,18 @@ unsigned long max_dma_mfn = (1UL << (CON
|
||||
static void parse_dma_bits(char *s)
|
||||
{
|
||||
unsigned int v = simple_strtol(s, NULL, 0);
|
||||
- if ( v >= (sizeof(long)*8 + PAGE_SHIFT) )
|
||||
+ if ( v >= (BITS_PER_LONG + PAGE_SHIFT) )
|
||||
{
|
||||
- dma_bitsize = sizeof(long)*8 + PAGE_SHIFT;
|
||||
+ dma_bitsize = BITS_PER_LONG + PAGE_SHIFT;
|
||||
max_dma_mfn = ~0UL;
|
||||
}
|
||||
- else
|
||||
+ else if ( v > PAGE_SHIFT )
|
||||
{
|
||||
dma_bitsize = v;
|
||||
max_dma_mfn = (1UL << (dma_bitsize - PAGE_SHIFT)) - 1;
|
||||
}
|
||||
+ else
|
||||
+ printk("Invalid dma_bits value of %u ignored.\n", v);
|
||||
}
|
||||
custom_param("dma_bits", parse_dma_bits);
|
||||
|
||||
@@ -293,12 +295,13 @@ unsigned long alloc_boot_pages(unsigned
|
||||
*/
|
||||
|
||||
#define MEMZONE_XEN 0
|
||||
-#define MEMZONE_DOM 1
|
||||
-#define MEMZONE_DMADOM 2
|
||||
-#define NR_ZONES 3
|
||||
+#ifdef PADDR_BITS
|
||||
+#define NR_ZONES (PADDR_BITS - PAGE_SHIFT)
|
||||
+#else
|
||||
+#define NR_ZONES (BITS_PER_LONG - PAGE_SHIFT)
|
||||
+#endif
|
||||
|
||||
-#define pfn_dom_zone_type(_pfn) \
|
||||
- (((_pfn) <= max_dma_mfn) ? MEMZONE_DMADOM : MEMZONE_DOM)
|
||||
+#define pfn_dom_zone_type(_pfn) (fls(_pfn) - 1)
|
||||
|
||||
static struct list_head heap[NR_ZONES][MAX_NUMNODES][MAX_ORDER+1];
|
||||
|
||||
@@ -308,15 +311,17 @@ static DEFINE_SPINLOCK(heap_lock);
|
||||
|
||||
/* Allocate 2^@order contiguous pages. */
|
||||
static struct page_info *alloc_heap_pages(
|
||||
- unsigned int zone, unsigned int cpu, unsigned int order)
|
||||
+ unsigned int zone_lo, unsigned zone_hi,
|
||||
+ unsigned int cpu, unsigned int order)
|
||||
{
|
||||
unsigned int i, j, node = cpu_to_node(cpu), num_nodes = num_online_nodes();
|
||||
- unsigned int request = (1UL << order);
|
||||
+ unsigned int zone, request = (1UL << order);
|
||||
struct page_info *pg;
|
||||
|
||||
ASSERT(node >= 0);
|
||||
ASSERT(node < num_nodes);
|
||||
- ASSERT(zone < NR_ZONES);
|
||||
+ ASSERT(zone_lo <= zone_hi);
|
||||
+ ASSERT(zone_hi < NR_ZONES);
|
||||
|
||||
if ( unlikely(order > MAX_ORDER) )
|
||||
return NULL;
|
||||
@@ -329,14 +334,17 @@ static struct page_info *alloc_heap_page
|
||||
* needless computation on fast-path */
|
||||
for ( i = 0; i < num_nodes; i++ )
|
||||
{
|
||||
- /* check if target node can support the allocation */
|
||||
- if ( avail[zone][node] >= request )
|
||||
+ for ( zone = zone_hi; zone >= zone_lo; --zone )
|
||||
{
|
||||
- /* Find smallest order which can satisfy the request. */
|
||||
- for ( j = order; j <= MAX_ORDER; j++ )
|
||||
+ /* check if target node can support the allocation */
|
||||
+ if ( avail[zone][node] >= request )
|
||||
{
|
||||
- if ( !list_empty(&heap[zone][node][j]) )
|
||||
- goto found;
|
||||
+ /* Find smallest order which can satisfy the request. */
|
||||
+ for ( j = order; j <= MAX_ORDER; j++ )
|
||||
+ {
|
||||
+ if ( !list_empty(&heap[zone][node][j]) )
|
||||
+ goto found;
|
||||
+ }
|
||||
}
|
||||
}
|
||||
/* pick next node, wrapping around if needed */
|
||||
@@ -461,16 +469,17 @@ void init_heap_pages(
|
||||
}
|
||||
|
||||
static unsigned long avail_heap_pages(
|
||||
- int zone, int node)
|
||||
+ unsigned int zone_lo, unsigned int zone_hi, unsigned int node)
|
||||
{
|
||||
- unsigned int i, j, num_nodes = num_online_nodes();
|
||||
+ unsigned int i, zone, num_nodes = num_online_nodes();
|
||||
unsigned long free_pages = 0;
|
||||
|
||||
- for (i=0; i<NR_ZONES; i++)
|
||||
- if ( (zone == -1) || (zone == i) )
|
||||
- for (j=0; j < num_nodes; j++)
|
||||
- if ( (node == -1) || (node == j) )
|
||||
- free_pages += avail[i][j];
|
||||
+ if ( zone_hi >= NR_ZONES )
|
||||
+ zone_hi = NR_ZONES - 1;
|
||||
+ for ( zone = zone_lo; zone <= zone_hi; zone++ )
|
||||
+ for ( i = 0; i < num_nodes; i++ )
|
||||
+ if ( (node == -1) || (node == i) )
|
||||
+ free_pages += avail[zone][i];
|
||||
|
||||
return free_pages;
|
||||
}
|
||||
@@ -590,7 +599,7 @@ void *alloc_xenheap_pages(unsigned int o
|
||||
int i;
|
||||
|
||||
local_irq_save(flags);
|
||||
- pg = alloc_heap_pages(MEMZONE_XEN, smp_processor_id(), order);
|
||||
+ pg = alloc_heap_pages(MEMZONE_XEN, MEMZONE_XEN, smp_processor_id(), order);
|
||||
local_irq_restore(flags);
|
||||
|
||||
if ( unlikely(pg == NULL) )
|
||||
@@ -635,22 +644,26 @@ void free_xenheap_pages(void *v, unsigne
|
||||
|
||||
void init_domheap_pages(paddr_t ps, paddr_t pe)
|
||||
{
|
||||
- unsigned long s_tot, e_tot, s_dma, e_dma, s_nrm, e_nrm;
|
||||
+ unsigned long s_tot, e_tot;
|
||||
+ unsigned int zone;
|
||||
|
||||
ASSERT(!in_irq());
|
||||
|
||||
s_tot = round_pgup(ps) >> PAGE_SHIFT;
|
||||
e_tot = round_pgdown(pe) >> PAGE_SHIFT;
|
||||
|
||||
- s_dma = min(s_tot, max_dma_mfn + 1);
|
||||
- e_dma = min(e_tot, max_dma_mfn + 1);
|
||||
- if ( s_dma < e_dma )
|
||||
- init_heap_pages(MEMZONE_DMADOM, mfn_to_page(s_dma), e_dma - s_dma);
|
||||
-
|
||||
- s_nrm = max(s_tot, max_dma_mfn + 1);
|
||||
- e_nrm = max(e_tot, max_dma_mfn + 1);
|
||||
- if ( s_nrm < e_nrm )
|
||||
- init_heap_pages(MEMZONE_DOM, mfn_to_page(s_nrm), e_nrm - s_nrm);
|
||||
+ zone = fls(s_tot);
|
||||
+ BUG_ON(zone <= MEMZONE_XEN + 1);
|
||||
+ for ( --zone; s_tot < e_tot; ++zone )
|
||||
+ {
|
||||
+ unsigned long end = e_tot;
|
||||
+
|
||||
+ BUILD_BUG_ON(NR_ZONES > BITS_PER_LONG);
|
||||
+ if ( zone < BITS_PER_LONG - 1 && end > 1UL << (zone + 1) )
|
||||
+ end = 1UL << (zone + 1);
|
||||
+ init_heap_pages(zone, mfn_to_page(s_tot), end - s_tot);
|
||||
+ s_tot = end;
|
||||
+ }
|
||||
}
|
||||
|
||||
|
||||
@@ -717,17 +730,21 @@ struct page_info *__alloc_domheap_pages(
|
||||
|
||||
if ( !(memflags & MEMF_dma) )
|
||||
{
|
||||
- pg = alloc_heap_pages(MEMZONE_DOM, cpu, order);
|
||||
+ pg = alloc_heap_pages(dma_bitsize - PAGE_SHIFT, NR_ZONES - 1, cpu, order);
|
||||
/* Failure? Then check if we can fall back to the DMA pool. */
|
||||
if ( unlikely(pg == NULL) &&
|
||||
((order > MAX_ORDER) ||
|
||||
- (avail_heap_pages(MEMZONE_DMADOM,-1) <
|
||||
+ (avail_heap_pages(MEMZONE_XEN + 1,
|
||||
+ dma_bitsize - PAGE_SHIFT - 1,
|
||||
+ -1) <
|
||||
(dma_emergency_pool_pages + (1UL << order)))) )
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ( pg == NULL )
|
||||
- if ( (pg = alloc_heap_pages(MEMZONE_DMADOM, cpu, order)) == NULL )
|
||||
+ if ( (pg = alloc_heap_pages(MEMZONE_XEN + 1,
|
||||
+ dma_bitsize - PAGE_SHIFT - 1,
|
||||
+ cpu, order)) == NULL )
|
||||
return NULL;
|
||||
|
||||
mask = pg->u.free.cpumask;
|
||||
@@ -849,9 +866,14 @@ unsigned long avail_domheap_pages(void)
|
||||
{
|
||||
unsigned long avail_nrm, avail_dma;
|
||||
|
||||
- avail_nrm = avail_heap_pages(MEMZONE_DOM,-1);
|
||||
+ avail_nrm = avail_heap_pages(dma_bitsize - PAGE_SHIFT,
|
||||
+ NR_ZONES - 1,
|
||||
+ -1);
|
||||
+
|
||||
+ avail_dma = avail_heap_pages(MEMZONE_XEN + 1,
|
||||
+ dma_bitsize - PAGE_SHIFT - 1,
|
||||
+ -1);
|
||||
|
||||
- avail_dma = avail_heap_pages(MEMZONE_DMADOM,-1);
|
||||
if ( avail_dma > dma_emergency_pool_pages )
|
||||
avail_dma -= dma_emergency_pool_pages;
|
||||
else
|
||||
@@ -862,18 +884,33 @@ unsigned long avail_domheap_pages(void)
|
||||
|
||||
unsigned long avail_nodeheap_pages(int node)
|
||||
{
|
||||
- return avail_heap_pages(-1, node);
|
||||
+ return avail_heap_pages(0, NR_ZONES - 1, node);
|
||||
}
|
||||
|
||||
static void pagealloc_keyhandler(unsigned char key)
|
||||
{
|
||||
+ unsigned int zone = MEMZONE_XEN;
|
||||
+ unsigned long total = 0;
|
||||
+
|
||||
printk("Physical memory information:\n");
|
||||
- printk(" Xen heap: %lukB free\n"
|
||||
- " DMA heap: %lukB free\n"
|
||||
- " Dom heap: %lukB free\n",
|
||||
- avail_heap_pages(MEMZONE_XEN, -1) << (PAGE_SHIFT-10),
|
||||
- avail_heap_pages(MEMZONE_DMADOM, -1) <<(PAGE_SHIFT-10),
|
||||
- avail_heap_pages(MEMZONE_DOM, -1) <<(PAGE_SHIFT-10));
|
||||
+ printk(" Xen heap: %lukB free\n",
|
||||
+ avail_heap_pages(zone, zone, -1) << (PAGE_SHIFT-10));
|
||||
+
|
||||
+ while ( ++zone < NR_ZONES )
|
||||
+ {
|
||||
+ unsigned long n;
|
||||
+
|
||||
+ if ( zone == dma_bitsize - PAGE_SHIFT )
|
||||
+ {
|
||||
+ printk(" DMA heap: %lukB free\n", total << (PAGE_SHIFT-10));
|
||||
+ total = 0;
|
||||
+ }
|
||||
+ n = avail_heap_pages(zone, zone, -1);
|
||||
+ total += n;
|
||||
+ if ( n )
|
||||
+ printk(" heap[%02u]: %lukB free\n", zone, n << (PAGE_SHIFT-10));
|
||||
+ }
|
||||
+ printk(" Dom heap: %lukB free\n", total << (PAGE_SHIFT-10));
|
||||
}
|
||||
|
||||
|
61
microcode-xen-13079.diff
Normal file
61
microcode-xen-13079.diff
Normal file
@ -0,0 +1,61 @@
|
||||
# HG changeset patch
|
||||
# User Kurt Garloff <kurt@garloff.de>
|
||||
# Node ID b1752c878a7845d812c9b15e721f401d786394b2
|
||||
# Parent 469478194aef6e987f9281efbc0756749be6eb80
|
||||
Microcode does not need to have the default size of 2000+48 bytes.
|
||||
A corresponding patch has gone into Linux 2.6.19; this is the
|
||||
port to Xen.
|
||||
|
||||
Signed-off-by: Kurt Garloff <kurt@garloff.de>
|
||||
|
||||
Reference: Patch to linux kernel from Sep 27 2006
|
||||
> # User Shaohua Li <shaohua.li@intel.com>
|
||||
> # Node ID 45898b908138b5d93c2cc7353f061ce54af145dc
|
||||
> # Parent f962eab7b82c9bf1a6da69571046e764f5128395
|
||||
> [PATCH] x86 microcode: don't check the size
|
||||
>
|
||||
> IA32 manual says if micorcode update's size is 0, then the size is
|
||||
> default size (2048 bytes). But this doesn't suggest all microcode
|
||||
> update's size should be above 2048 bytes to me. We actually had a
|
||||
> microcode update whose size is 1024 bytes. The patch just removed the
|
||||
> check.
|
||||
>
|
||||
> Signed-off-by: Shaohua Li <shaohua.li@intel.com>
|
||||
> Cc: Tigran Aivazian <tigran@veritas.com>
|
||||
> Signed-off-by: Andrew Morton <akpm@osdl.org>
|
||||
> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
|
||||
>
|
||||
> committer: Linus Torvalds <torvalds@g5.osdl.org> 1159370778 -0700
|
||||
|
||||
diff -r 469478194aef -r b1752c878a78 xen/arch/x86/microcode.c
|
||||
--- a/xen/arch/x86/microcode.c Mon Dec 18 00:14:40 2006 +0000
|
||||
+++ b/xen/arch/x86/microcode.c Sun Dec 24 17:06:23 2006 +0100
|
||||
@@ -249,14 +249,14 @@ static int find_matching_ucodes (void)
|
||||
}
|
||||
|
||||
total_size = get_totalsize(&mc_header);
|
||||
- if ((cursor + total_size > user_buffer_size) || (total_size < DEFAULT_UCODE_TOTALSIZE)) {
|
||||
+ if (cursor + total_size > user_buffer_size) {
|
||||
printk(KERN_ERR "microcode: error! Bad data in microcode data file\n");
|
||||
error = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
data_size = get_datasize(&mc_header);
|
||||
- if ((data_size + MC_HEADER_SIZE > total_size) || (data_size < DEFAULT_UCODE_DATASIZE)) {
|
||||
+ if (data_size + MC_HEADER_SIZE > total_size) {
|
||||
printk(KERN_ERR "microcode: error! Bad data in microcode data file\n");
|
||||
error = -EINVAL;
|
||||
goto out;
|
||||
@@ -459,11 +459,6 @@ int microcode_update(XEN_GUEST_HANDLE(vo
|
||||
{
|
||||
int ret;
|
||||
|
||||
- if (len < DEFAULT_UCODE_TOTALSIZE) {
|
||||
- printk(KERN_ERR "microcode: not enough data\n");
|
||||
- return -EINVAL;
|
||||
- }
|
||||
-
|
||||
if (len != (typeof(user_buffer_size))len) {
|
||||
printk(KERN_ERR "microcode: too much data\n");
|
||||
return -E2BIG;
|
@ -1,278 +0,0 @@
|
||||
#!/bin/bash
|
||||
# Shell script to prepare a root FS image based on the Novell/SUSE rescue
|
||||
# image source. You must have a xen kernel installed for this to work.
|
||||
# (c) Kurt Garloff <garloff@suse.de>, 2005-01-24, GNU GPL
|
||||
# Maintained by Charles Coffing <ccoffing@novell.com>
|
||||
#
|
||||
# TODO:
|
||||
# - trap SIGINT and clean up
|
||||
# - can't know that /sbin/depmod will work with this rescue image
|
||||
# - support domUloader
|
||||
# - check for disk full in exchange_kernel_modules
|
||||
|
||||
MB_DEFAULT=88
|
||||
|
||||
usage()
|
||||
{
|
||||
echo "Usage:"
|
||||
echo " mk-xen-rescue-img.sh source destination [MB [kernelver]]"
|
||||
echo "Purpose:"
|
||||
echo " Creates a root filesystem and an associated config file for a Xen-compatible"
|
||||
echo " Linux virtual machine."
|
||||
echo "Arguments:"
|
||||
echo " * 'source' is the source from which to copy files. Normally, this is"
|
||||
echo " the SUSE rescue image, such as /media/cdrom/boot/x86_64/rescue,"
|
||||
echo " but it could also be an already-mounted root filesystem."
|
||||
echo " * 'destination' is the pathname of a disk image to be created, based on"
|
||||
echo " 'source'."
|
||||
echo " * 'MB' is the size of disk image (default $MB_DEFAULT)."
|
||||
echo " * 'kernelver' is the version of an installed Xen-compatible Linux kernel"
|
||||
echo " (from the kernel-xen package) to install in the disk image. If not"
|
||||
echo " specified, the newest of those currently installed will be selected."
|
||||
exit 2
|
||||
}
|
||||
|
||||
usage_error()
|
||||
{
|
||||
echo "Error: $@"
|
||||
echo ""
|
||||
usage
|
||||
}
|
||||
|
||||
error()
|
||||
{
|
||||
echo "Error: $@"
|
||||
if [ ! -z "$DST_MNT" ]; then
|
||||
umount "$DST_MNT"
|
||||
rmdir "$DST_MNT"
|
||||
fi
|
||||
exit 1
|
||||
}
|
||||
|
||||
cp_error()
|
||||
{
|
||||
error "Failed to copy files to '$DST'."
|
||||
}
|
||||
|
||||
# Determine Xen kernel version
|
||||
get_xen_kernel()
|
||||
{
|
||||
if [ -z "$KVER" ]; then
|
||||
KVER="`cd /lib/modules && ls -td *-xen/kernel | head -n1 | sed 's@/kernel@@'`"
|
||||
else
|
||||
if [ ! -d /lib/modules/$KVER/kernel ]; then
|
||||
error "/lib/modules/$KVER/kernel does not exist."
|
||||
fi
|
||||
fi
|
||||
if [ -z "$KVER" ]; then
|
||||
error "You need to have a 'kernel-xen' package installed."
|
||||
fi
|
||||
}
|
||||
|
||||
cp_rescue()
|
||||
{
|
||||
local LSRC=$1
|
||||
local LDST=$2
|
||||
|
||||
# The rescue image has empty directories all hard-linked to the same
|
||||
# thing, probably to conserve inodes. This gives 'cp' heartburn.
|
||||
# I want hard linked directories to be created separately (i.e.,
|
||||
# dereferenced), but I don't want to dereference soft links.
|
||||
# 'tar' handles this nicely.
|
||||
|
||||
(cd "$LSRC" && tar --atime-preserve --one-file-system -cf - *) | \
|
||||
(cd "$LDST" && tar -xmf -)
|
||||
}
|
||||
|
||||
# Create FS and copy rescue FS
|
||||
create_basis_and_mount()
|
||||
{
|
||||
echo "Creating disk image within '$DST'..."
|
||||
dd if=/dev/zero of="$DST" bs=4096 count=1 2>/dev/null >/dev/null 2>&1
|
||||
dd if=/dev/zero of="$DST" bs=1048576 count=0 seek=$MB >/dev/null 2>&1
|
||||
/sbin/mke2fs -b 1024 -i 2048 -L xen_rescue -F "$DST" >/dev/null 2>&1
|
||||
DST_MNT="$DST".mnt
|
||||
mkdir -p "$DST_MNT"
|
||||
mount -o loop "$DST" "$DST_MNT"
|
||||
if [ $? -ne 0 ]; then
|
||||
error "Failed to mount destination disk image via loopback."
|
||||
fi
|
||||
echo "Copying files from '$SRC'..."
|
||||
if test -d "$SRC"; then
|
||||
if [ ! -d "$SRC"/dev ] || [ ! -d "$SRC"/sbin ]; then
|
||||
error "'$SRC' does not look like a valid root filesystem."
|
||||
fi
|
||||
cp_rescue "$SRC" "$DST_MNT"
|
||||
if [ $? -ne 0 ]; then
|
||||
cp_error
|
||||
fi
|
||||
else
|
||||
mkdir -p "$DST".src
|
||||
if test ! -z "`file $SRC | grep gzip`"; then
|
||||
cp -p "$SRC" "$DST".stage.gz
|
||||
gunzip -f "$DST".stage.gz || rm -f "$DST".stage.gz
|
||||
mount -o loop "$DST".stage "$DST".src
|
||||
if [ $? -ne 0 ]; then
|
||||
rm "$DST".stage
|
||||
rmdir "$DST".src
|
||||
error "Failed to mount the source via loopback."
|
||||
fi
|
||||
cp_rescue "$DST".src "$DST_MNT"
|
||||
if [ $? -ne 0 ]; then
|
||||
umount "$DST".src
|
||||
rm "$DST".stage
|
||||
rmdir "$DST".src
|
||||
cp_error
|
||||
fi
|
||||
umount "$DST".src
|
||||
rm "$DST".stage
|
||||
else
|
||||
mount -o loop "$SRC" "$DST".src
|
||||
if [ $? -ne 0 ]; then
|
||||
rmdir "$DST".src
|
||||
error "Failed to mount the source via loopback."
|
||||
fi
|
||||
cp_rescue "$DST".src "$DST_MNT"
|
||||
if [ $? -ne 0 ]; then
|
||||
umount "$DST".src
|
||||
rmdir "$DST".src
|
||||
cp_error
|
||||
fi
|
||||
umount "$DST".src
|
||||
fi
|
||||
rmdir "$DST".src
|
||||
fi
|
||||
}
|
||||
|
||||
# Save some inodes
|
||||
remove_some_files()
|
||||
{
|
||||
# these consume an excessive amount of inodes
|
||||
rm -f "$DST_MNT"/dev/sd[c-z][a-z][0-9]*
|
||||
# hwclock does not work
|
||||
rm -f "$DST_MNT"/etc/init.d/boot.d/*boot.clock
|
||||
}
|
||||
|
||||
xenify_image()
|
||||
{
|
||||
# Xen doesn't yet support virtualizing USB
|
||||
sed -i "s/^usbfs/#usbfs/" "$DST_MNT"/etc/fstab
|
||||
}
|
||||
|
||||
# Copy extra files to rescue image
|
||||
copy_extra_files()
|
||||
{
|
||||
test ! -e "$DST_MNT"/sbin/depmod && cp -p /sbin/depmod "$DST_MNT"/sbin/
|
||||
cp -p /usr/share/doc/packages/xen/boot.local.xenU "$DST_MNT"/etc/init.d/boot.local
|
||||
}
|
||||
|
||||
# Remove kernel modules and replace by ours
|
||||
exchange_kernel_modules()
|
||||
{
|
||||
echo "Updating kernel within '$DST'..."
|
||||
KMODDIR=/lib/modules/$KVER/kernel
|
||||
MNTKVER="`cd "$DST_MNT"/lib/modules && ls -td */kernel 2>/dev/null | sed 's@/kernel@@' 2>/dev/null`"
|
||||
for dir in $MNTKVER; do
|
||||
if test "$MNTKVER" != "$KVER"; then
|
||||
rm -rf "$DST_MNT"/lib/modules/$MNTKVER
|
||||
fi
|
||||
done
|
||||
mkdir -p "$DST_MNT"$KMODDIR
|
||||
# complete trees
|
||||
for dir in arch crypto lib net security; do
|
||||
cp -ax $KMODDIR/$dir "$DST_MNT"$KMODDIR/
|
||||
done
|
||||
mkdir -p "$DST_MNT"$KMODDIR/fs
|
||||
cp -p $KMODDIR/fs/*.ko "$DST_MNT"$KMODDIR/fs/
|
||||
# a selection of FS
|
||||
for fs in afs autofs autofs4 cifs exportfs ext3 fat jbd jfs msdos ncpfs nfsd nls ntfs reiser4 reiserfs smbfs subfs sysv udf ufs vfat xfs; do
|
||||
if test -e $KMODDIR/fs/$fs; then
|
||||
cp -ax $KMODDIR/fs/$fs "$DST_MNT"$KMODDIR/fs/
|
||||
fi
|
||||
done
|
||||
# some drivers
|
||||
mkdir -p "$DST_MNT"$KMODDIR/drivers/char
|
||||
for name in lp.ko n_hdlc.ko raw.ko; do
|
||||
cp -p $KMODDIR/drivers/char/$name "$DST_MNT"$KMODDIR/drivers/char/
|
||||
done
|
||||
mkdir -p "$DST_MNT"$KMODDIR/drivers/block
|
||||
for name in umem.ko nbd.ko loop.ko loop_fish2.ko cryptoloop.ko; do
|
||||
cp -p $KMODDIR/drivers/block/$name "$DST_MNT"$KMODDIR/drivers/block/
|
||||
done
|
||||
mkdir -p "$DST_MNT"$KMODDIR/drivers/base
|
||||
cp -p $KMODDIR/drivers/base/firmware_class.ko "$DST_MNT"$KMODDIR/drivers/base/
|
||||
mkdir -p "$DST_MNT"$KMODDIR/drivers/md
|
||||
cp -p $KMODDIR/drivers/md/*.ko "$DST_MNT"$KMODDIR/drivers/md/
|
||||
mkdir -p "$DST_MNT"$KMODDIR/drivers/xen
|
||||
for dir in $KMODDIR/drivers/xen/*front; do
|
||||
cp -ax $dir "$DST_MNT"$KMODDIR/drivers/xen/
|
||||
done
|
||||
if test -e $KMODDIR/kernel; then
|
||||
mkdir -p "$DST_MNT"$KMODDIR/kernel
|
||||
cp -ax $KMODDIR/kernel/* "$DST_MNT"$KMODDIR/kernel/
|
||||
fi
|
||||
# Kernel image + System.map
|
||||
mkdir -p "$DST_MNT"/boot
|
||||
rm -f "$DST_MNT"/boot/vmlinuz-* "$DST_MNT"/boot/System.map-* "$DST_MNT"/boot/initrd-*
|
||||
cp -p /boot/vmlinuz-$KVER "$DST_MNT"/boot/
|
||||
if test -e /boot/initrd-$KVER-domU; then
|
||||
cp -p /boot/initrd-$KVER-domU "$DST_MNT"/boot/initrd-$KVER
|
||||
else
|
||||
cp -p /boot/initrd-$KVER "$DST_MNT"/boot/
|
||||
fi
|
||||
cp -p /boot/System.map-$KVER "$DST_MNT"/boot/
|
||||
depmod -a $KVER -b "$DST_MNT" -F "$DST_MNT"/boot/System.map-$KVER
|
||||
|
||||
}
|
||||
|
||||
# umount and display message
|
||||
umount_and_msg()
|
||||
{
|
||||
umount "$DST_MNT"
|
||||
rmdir "$DST_MNT"
|
||||
DST_MNT=
|
||||
echo "'$DST' has been prepared successfully."
|
||||
CFGFILE=/etc/xen/vm/${DST##*/}
|
||||
if test -e $CFGFILE; then
|
||||
mv -b $CFGFILE $CFGFILE.save
|
||||
fi
|
||||
if test "${DST:0:1}" != "/"; then
|
||||
DST="`pwd`/$DST"
|
||||
fi
|
||||
cp -p /etc/xen/examples/xmexample.rescue $CFGFILE
|
||||
sed -i "/^disk/s@^.*\$@disk = [ \'file:$DST,hda1,w\' ]@" $CFGFILE
|
||||
# These next two lines are only applicable if not using domUloader,
|
||||
# but try anyway.
|
||||
sed -i "/^kernel/s@^.*\$@kernel = \"/boot/vmlinuz-$KVER\"@" $CFGFILE
|
||||
sed -i "/^ramdisk/s@^.*\$@ramdisk = \"/boot/initrd-$KVER\"@" $CFGFILE
|
||||
echo ""
|
||||
echo "Config file '$CFGFILE' has been created. Please review!"
|
||||
echo "You may also want to add an IP address to the config file."
|
||||
echo "Start the domain with 'xm create -c $CFGFILE'."
|
||||
}
|
||||
|
||||
if test -z "$1" -o -z "$2"; then
|
||||
usage
|
||||
fi
|
||||
SRC=$1
|
||||
if [ ! -e "$SRC" ]; then
|
||||
usage_error "'$SRC' does not exist."
|
||||
fi
|
||||
DST=$2
|
||||
if [ -e "$DST" ]; then
|
||||
error "'$DST' already exists."
|
||||
fi
|
||||
MB=$MB_DEFAULT
|
||||
[ ! -z "$3" ] && MB=$3
|
||||
KVER=$4
|
||||
if [ `id -u` -ne 0 ]; then
|
||||
usage_error "Please run this script as root."
|
||||
fi
|
||||
|
||||
get_xen_kernel
|
||||
create_basis_and_mount
|
||||
remove_some_files
|
||||
copy_extra_files
|
||||
xenify_image
|
||||
exchange_kernel_modules
|
||||
umount_and_msg
|
@ -1,461 +0,0 @@
|
||||
From: Jan Beulich
|
||||
Bugzilla #214568
|
||||
|
||||
Index: xen-3.0.3-testing/xen/arch/x86/hvm/platform.c
|
||||
===================================================================
|
||||
--- xen-3.0.3-testing.orig/xen/arch/x86/hvm/platform.c
|
||||
+++ xen-3.0.3-testing/xen/arch/x86/hvm/platform.c
|
||||
@@ -883,19 +883,14 @@ void handle_mmio(unsigned long va, unsig
|
||||
memcpy(regs, guest_cpu_user_regs(), HVM_CONTEXT_STACK_BYTES);
|
||||
hvm_store_cpu_guest_regs(v, regs, NULL);
|
||||
|
||||
- inst_len = hvm_instruction_length(regs, hvm_guest_x86_mode(v));
|
||||
+ inst_addr = hvm_get_segment_base(current, seg_cs) + regs->eip;
|
||||
+ inst_len = hvm_instruction_length(inst_addr, hvm_guest_x86_mode(v));
|
||||
if ( inst_len <= 0 )
|
||||
{
|
||||
printk("handle_mmio: failed to get instruction length\n");
|
||||
domain_crash_synchronous();
|
||||
}
|
||||
|
||||
- realmode = hvm_realmode(v);
|
||||
- if (realmode)
|
||||
- inst_addr = (regs->cs << 4) + regs->eip;
|
||||
- else
|
||||
- inst_addr = regs->eip;
|
||||
-
|
||||
memset(inst, 0, MAX_INST_LEN);
|
||||
ret = inst_copy_from_guest(inst, inst_addr, inst_len);
|
||||
if (ret != inst_len) {
|
||||
@@ -904,6 +899,7 @@ void handle_mmio(unsigned long va, unsig
|
||||
}
|
||||
|
||||
init_instruction(&mmio_inst);
|
||||
+ realmode = hvm_realmode(v);
|
||||
|
||||
if (hvm_decode(realmode, inst, &mmio_inst) == DECODE_failure) {
|
||||
printk("handle_mmio: failed to decode instruction\n");
|
||||
Index: xen-3.0.3-testing/xen/arch/x86/hvm/svm/svm.c
|
||||
===================================================================
|
||||
--- xen-3.0.3-testing.orig/xen/arch/x86/hvm/svm/svm.c
|
||||
+++ xen-3.0.3-testing/xen/arch/x86/hvm/svm/svm.c
|
||||
@@ -507,6 +507,24 @@ unsigned long svm_get_ctrl_reg(struct vc
|
||||
return 0; /* dummy */
|
||||
}
|
||||
|
||||
+static unsigned long svm_get_segment_base(struct vcpu *v, enum segment seg)
|
||||
+{
|
||||
+ switch ( seg )
|
||||
+ {
|
||||
+ case seg_cs: return v->arch.hvm_svm.vmcb->cs.base;
|
||||
+ case seg_ds: return v->arch.hvm_svm.vmcb->ds.base;
|
||||
+ case seg_es: return v->arch.hvm_svm.vmcb->es.base;
|
||||
+ case seg_fs: return v->arch.hvm_svm.vmcb->fs.base;
|
||||
+ case seg_gs: return v->arch.hvm_svm.vmcb->gs.base;
|
||||
+ case seg_ss: return v->arch.hvm_svm.vmcb->ss.base;
|
||||
+ case seg_tr: return v->arch.hvm_svm.vmcb->tr.base;
|
||||
+ case seg_gdtr: return v->arch.hvm_svm.vmcb->gdtr.base;
|
||||
+ case seg_idtr: return v->arch.hvm_svm.vmcb->idtr.base;
|
||||
+ case seg_ldtr: return v->arch.hvm_svm.vmcb->ldtr.base;
|
||||
+ }
|
||||
+ BUG();
|
||||
+ return 0;
|
||||
+}
|
||||
|
||||
/* Make sure that xen intercepts any FP accesses from current */
|
||||
static void svm_stts(struct vcpu *v)
|
||||
@@ -887,6 +905,7 @@ int start_svm(void)
|
||||
hvm_funcs.pae_enabled = svm_pae_enabled;
|
||||
hvm_funcs.guest_x86_mode = svm_guest_x86_mode;
|
||||
hvm_funcs.get_guest_ctrl_reg = svm_get_ctrl_reg;
|
||||
+ hvm_funcs.get_segment_base = svm_get_segment_base;
|
||||
|
||||
hvm_funcs.update_host_cr3 = svm_update_host_cr3;
|
||||
|
||||
Index: xen-3.0.3-testing/xen/arch/x86/hvm/vmx/vmx.c
|
||||
===================================================================
|
||||
--- xen-3.0.3-testing.orig/xen/arch/x86/hvm/vmx/vmx.c
|
||||
+++ xen-3.0.3-testing/xen/arch/x86/hvm/vmx/vmx.c
|
||||
@@ -610,7 +610,27 @@ static unsigned long vmx_get_ctrl_reg(st
|
||||
return 0; /* dummy */
|
||||
}
|
||||
|
||||
+static unsigned long vmx_get_segment_base(struct vcpu *v, enum segment seg)
|
||||
+{
|
||||
+ unsigned long base;
|
||||
|
||||
+ BUG_ON(v != current);
|
||||
+ switch ( seg )
|
||||
+ {
|
||||
+ case seg_cs: __vmread(GUEST_CS_BASE, &base); break;
|
||||
+ case seg_ds: __vmread(GUEST_DS_BASE, &base); break;
|
||||
+ case seg_es: __vmread(GUEST_ES_BASE, &base); break;
|
||||
+ case seg_fs: __vmread(GUEST_FS_BASE, &base); break;
|
||||
+ case seg_gs: __vmread(GUEST_GS_BASE, &base); break;
|
||||
+ case seg_ss: __vmread(GUEST_SS_BASE, &base); break;
|
||||
+ case seg_tr: __vmread(GUEST_TR_BASE, &base); break;
|
||||
+ case seg_gdtr: __vmread(GUEST_GDTR_BASE, &base); break;
|
||||
+ case seg_idtr: __vmread(GUEST_IDTR_BASE, &base); break;
|
||||
+ case seg_ldtr: __vmread(GUEST_LDTR_BASE, &base); break;
|
||||
+ default: BUG(); base = 0; break;
|
||||
+ }
|
||||
+ return base;
|
||||
+}
|
||||
|
||||
/* Make sure that xen intercepts any FP accesses from current */
|
||||
static void vmx_stts(struct vcpu *v)
|
||||
@@ -753,6 +773,7 @@ static void vmx_setup_hvm_funcs(void)
|
||||
hvm_funcs.pae_enabled = vmx_pae_enabled;
|
||||
hvm_funcs.guest_x86_mode = vmx_guest_x86_mode;
|
||||
hvm_funcs.get_guest_ctrl_reg = vmx_get_ctrl_reg;
|
||||
+ hvm_funcs.get_segment_base = vmx_get_segment_base;
|
||||
|
||||
hvm_funcs.update_host_cr3 = vmx_update_host_cr3;
|
||||
|
||||
Index: xen-3.0.3-testing/xen/include/asm-x86/hvm/hvm.h
|
||||
===================================================================
|
||||
--- xen-3.0.3-testing.orig/xen/include/asm-x86/hvm/hvm.h
|
||||
+++ xen-3.0.3-testing/xen/include/asm-x86/hvm/hvm.h
|
||||
@@ -20,6 +20,19 @@
|
||||
#ifndef __ASM_X86_HVM_HVM_H__
|
||||
#define __ASM_X86_HVM_HVM_H__
|
||||
|
||||
+enum segment {
|
||||
+ seg_cs,
|
||||
+ seg_ss,
|
||||
+ seg_ds,
|
||||
+ seg_es,
|
||||
+ seg_fs,
|
||||
+ seg_gs,
|
||||
+ seg_tr,
|
||||
+ seg_ldtr,
|
||||
+ seg_gdtr,
|
||||
+ seg_idtr
|
||||
+};
|
||||
+
|
||||
/*
|
||||
* The hardware virtual machine (HVM) interface abstracts away from the
|
||||
* x86/x86_64 CPU virtualization assist specifics. Currently this interface
|
||||
@@ -52,6 +65,7 @@ struct hvm_function_table {
|
||||
* 1) determine whether the guest is in real or vm8086 mode,
|
||||
* 2) determine whether paging is enabled,
|
||||
* 3) return the current guest control-register value
|
||||
+ * 4) return the current guest segment descriptor base
|
||||
*/
|
||||
int (*realmode)(struct vcpu *v);
|
||||
int (*paging_enabled)(struct vcpu *v);
|
||||
@@ -59,6 +73,7 @@ struct hvm_function_table {
|
||||
int (*pae_enabled)(struct vcpu *v);
|
||||
int (*guest_x86_mode)(struct vcpu *v);
|
||||
unsigned long (*get_guest_ctrl_reg)(struct vcpu *v, unsigned int num);
|
||||
+ unsigned long (*get_segment_base)(struct vcpu *v, enum segment seg);
|
||||
|
||||
/*
|
||||
* Re-set the value of CR3 that Xen runs on when handling VM exits
|
||||
@@ -157,7 +172,7 @@ hvm_guest_x86_mode(struct vcpu *v)
|
||||
return hvm_funcs.guest_x86_mode(v);
|
||||
}
|
||||
|
||||
-int hvm_instruction_length(struct cpu_user_regs *regs, int mode);
|
||||
+int hvm_instruction_length(unsigned long pc, int mode);
|
||||
|
||||
static inline void
|
||||
hvm_update_host_cr3(struct vcpu *v)
|
||||
@@ -176,6 +191,12 @@ hvm_get_guest_ctrl_reg(struct vcpu *v, u
|
||||
return 0; /* force to fail */
|
||||
}
|
||||
|
||||
+static inline unsigned long
|
||||
+hvm_get_segment_base(struct vcpu *v, enum segment seg)
|
||||
+{
|
||||
+ return hvm_funcs.get_segment_base(v, seg);
|
||||
+}
|
||||
+
|
||||
void hvm_stts(struct vcpu *v);
|
||||
void hvm_set_guest_time(struct vcpu *v, u64 gtime);
|
||||
void hvm_do_resume(struct vcpu *v);
|
||||
Index: xen-3.0.3-testing/xen/arch/x86/hvm/instrlen.c
|
||||
===================================================================
|
||||
--- xen-3.0.3-testing.orig/xen/arch/x86/hvm/instrlen.c
|
||||
+++ xen-3.0.3-testing/xen/arch/x86/hvm/instrlen.c
|
||||
@@ -20,7 +20,6 @@
|
||||
#include <xen/config.h>
|
||||
#include <xen/sched.h>
|
||||
#include <xen/mm.h>
|
||||
-#include <asm/regs.h>
|
||||
#include <asm-x86/x86_emulate.h>
|
||||
|
||||
/* read from guest memory */
|
||||
@@ -195,54 +194,51 @@ static uint8_t twobyte_table[256] = {
|
||||
};
|
||||
|
||||
/*
|
||||
- * insn_fetch - fetch the next 1 to 4 bytes from instruction stream
|
||||
- * @_type: u8, u16, u32, s8, s16, or s32
|
||||
- * @_size: 1, 2, or 4 bytes
|
||||
+ * insn_fetch - fetch the next byte from instruction stream
|
||||
*/
|
||||
-#define insn_fetch(_type, _size) \
|
||||
-({ unsigned long _x, _ptr = _regs.eip; \
|
||||
- if ( mode == X86EMUL_MODE_REAL ) _ptr += _regs.cs << 4; \
|
||||
- rc = inst_copy_from_guest((unsigned char *)(&(_x)), _ptr, _size); \
|
||||
- if ( rc != _size ) goto done; \
|
||||
- _regs.eip += (_size); \
|
||||
- length += (_size); \
|
||||
- (_type)_x; \
|
||||
+#define insn_fetch() \
|
||||
+({ uint8_t _x; \
|
||||
+ if ( inst_copy_from_guest(&_x, pc, 1) != 1 ) { \
|
||||
+ DPRINTK("Cannot read from address %lx (eip %lx, mode %d)\n", \
|
||||
+ pc, org_pc, mode); \
|
||||
+ return -1; \
|
||||
+ } \
|
||||
+ pc += 1; \
|
||||
+ length += 1; \
|
||||
+ _x; \
|
||||
})
|
||||
|
||||
/**
|
||||
* hvm_instruction_length - returns the current instructions length
|
||||
*
|
||||
- * @regs: guest register state
|
||||
+ * @org_pc: guest instruction pointer
|
||||
* @mode: guest operating mode
|
||||
*
|
||||
* EXTERNAL this routine calculates the length of the current instruction
|
||||
- * pointed to by eip. The guest state is _not_ changed by this routine.
|
||||
+ * pointed to by org_pc. The guest state is _not_ changed by this routine.
|
||||
*/
|
||||
-int hvm_instruction_length(struct cpu_user_regs *regs, int mode)
|
||||
+int hvm_instruction_length(unsigned long org_pc, int mode)
|
||||
{
|
||||
uint8_t b, d, twobyte = 0, rex_prefix = 0;
|
||||
uint8_t modrm, modrm_mod = 0, modrm_reg = 0, modrm_rm = 0;
|
||||
- unsigned int op_bytes, ad_bytes, i;
|
||||
- int rc = 0;
|
||||
+ unsigned int op_default, op_bytes, ad_default, ad_bytes, i;
|
||||
int length = 0;
|
||||
unsigned int tmp;
|
||||
-
|
||||
- /* Shadow copy of register state. Committed on successful emulation. */
|
||||
- struct cpu_user_regs _regs = *regs;
|
||||
+ unsigned long pc = org_pc;
|
||||
|
||||
switch ( mode )
|
||||
{
|
||||
case X86EMUL_MODE_REAL:
|
||||
case X86EMUL_MODE_PROT16:
|
||||
- op_bytes = ad_bytes = 2;
|
||||
+ op_bytes = op_default = ad_bytes = ad_default = 2;
|
||||
break;
|
||||
case X86EMUL_MODE_PROT32:
|
||||
- op_bytes = ad_bytes = 4;
|
||||
+ op_bytes = op_default = ad_bytes = ad_default = 4;
|
||||
break;
|
||||
#ifdef __x86_64__
|
||||
case X86EMUL_MODE_PROT64:
|
||||
- op_bytes = 4;
|
||||
- ad_bytes = 8;
|
||||
+ op_bytes = op_default = 4;
|
||||
+ ad_bytes = ad_default = 8;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
@@ -252,16 +248,16 @@ int hvm_instruction_length(struct cpu_us
|
||||
/* Legacy prefixes. */
|
||||
for ( i = 0; i < 8; i++ )
|
||||
{
|
||||
- switch ( b = insn_fetch(uint8_t, 1) )
|
||||
+ switch ( b = insn_fetch() )
|
||||
{
|
||||
case 0x66: /* operand-size override */
|
||||
- op_bytes ^= 6; /* switch between 2/4 bytes */
|
||||
+ op_bytes = op_default ^ 6; /* switch between 2/4 bytes */
|
||||
break;
|
||||
case 0x67: /* address-size override */
|
||||
if ( mode == X86EMUL_MODE_PROT64 )
|
||||
- ad_bytes ^= 12; /* switch between 4/8 bytes */
|
||||
+ ad_bytes = ad_default ^ 12; /* switch between 4/8 bytes */
|
||||
else
|
||||
- ad_bytes ^= 6; /* switch between 2/4 bytes */
|
||||
+ ad_bytes = ad_default ^ 6; /* switch between 2/4 bytes */
|
||||
break;
|
||||
case 0x2e: /* CS override */
|
||||
case 0x3e: /* DS override */
|
||||
@@ -273,21 +269,30 @@ int hvm_instruction_length(struct cpu_us
|
||||
case 0xf3: /* REP/REPE/REPZ */
|
||||
case 0xf2: /* REPNE/REPNZ */
|
||||
break;
|
||||
+#ifdef __x86_64__
|
||||
+ case 0x40 ... 0x4f:
|
||||
+ if ( mode == X86EMUL_MODE_PROT64 )
|
||||
+ {
|
||||
+ rex_prefix = b;
|
||||
+ continue;
|
||||
+ }
|
||||
+ /* FALLTHRU */
|
||||
+#endif
|
||||
default:
|
||||
goto done_prefixes;
|
||||
}
|
||||
+ rex_prefix = 0;
|
||||
}
|
||||
done_prefixes:
|
||||
|
||||
/* REX prefix. */
|
||||
- if ( (mode == X86EMUL_MODE_PROT64) && ((b & 0xf0) == 0x40) )
|
||||
+ if ( rex_prefix )
|
||||
{
|
||||
- rex_prefix = b;
|
||||
- if ( b & 8 )
|
||||
- op_bytes = 8; /* REX.W */
|
||||
- modrm_reg = (b & 4) << 1; /* REX.R */
|
||||
+ if ( rex_prefix & 8 )
|
||||
+ op_bytes = 8; /* REX.W */
|
||||
+ modrm_reg = (rex_prefix & 4) << 1; /* REX.R */
|
||||
/* REX.B and REX.X do not need to be decoded. */
|
||||
- b = insn_fetch(uint8_t, 1);
|
||||
+ b = insn_fetch();
|
||||
}
|
||||
|
||||
/* Opcode byte(s). */
|
||||
@@ -298,7 +303,7 @@ done_prefixes:
|
||||
if ( b == 0x0f )
|
||||
{
|
||||
twobyte = 1;
|
||||
- b = insn_fetch(uint8_t, 1);
|
||||
+ b = insn_fetch();
|
||||
d = twobyte_table[b];
|
||||
}
|
||||
|
||||
@@ -310,7 +315,7 @@ done_prefixes:
|
||||
/* ModRM and SIB bytes. */
|
||||
if ( d & ModRM )
|
||||
{
|
||||
- modrm = insn_fetch(uint8_t, 1);
|
||||
+ modrm = insn_fetch();
|
||||
modrm_mod |= (modrm & 0xc0) >> 6;
|
||||
modrm_reg |= (modrm & 0x38) >> 3;
|
||||
modrm_rm |= (modrm & 0x07);
|
||||
@@ -330,16 +335,16 @@ done_prefixes:
|
||||
if ( modrm_rm == 6 )
|
||||
{
|
||||
length += 2;
|
||||
- _regs.eip += 2; /* skip disp16 */
|
||||
+ pc += 2; /* skip disp16 */
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
length += 1;
|
||||
- _regs.eip += 1; /* skip disp8 */
|
||||
+ pc += 1; /* skip disp8 */
|
||||
break;
|
||||
case 2:
|
||||
length += 2;
|
||||
- _regs.eip += 2; /* skip disp16 */
|
||||
+ pc += 2; /* skip disp16 */
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -350,33 +355,34 @@ done_prefixes:
|
||||
{
|
||||
case 0:
|
||||
if ( (modrm_rm == 4) &&
|
||||
- (((insn_fetch(uint8_t, 1)) & 7)
|
||||
- == 5) )
|
||||
+ ((insn_fetch() & 7) == 5) )
|
||||
{
|
||||
length += 4;
|
||||
- _regs.eip += 4; /* skip disp32 specified by SIB.base */
|
||||
+ pc += 4; /* skip disp32 specified by SIB.base */
|
||||
}
|
||||
else if ( modrm_rm == 5 )
|
||||
{
|
||||
length += 4;
|
||||
- _regs.eip += 4; /* skip disp32 */
|
||||
+ pc += 4; /* skip disp32 */
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
if ( modrm_rm == 4 )
|
||||
{
|
||||
- insn_fetch(uint8_t, 1);
|
||||
+ length += 1;
|
||||
+ pc += 1;
|
||||
}
|
||||
length += 1;
|
||||
- _regs.eip += 1; /* skip disp8 */
|
||||
+ pc += 1; /* skip disp8 */
|
||||
break;
|
||||
case 2:
|
||||
if ( modrm_rm == 4 )
|
||||
{
|
||||
- insn_fetch(uint8_t, 1);
|
||||
+ length += 1;
|
||||
+ pc += 1;
|
||||
}
|
||||
length += 4;
|
||||
- _regs.eip += 4; /* skip disp32 */
|
||||
+ pc += 4; /* skip disp32 */
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -397,15 +403,12 @@ done_prefixes:
|
||||
tmp = (d & ByteOp) ? 1 : op_bytes;
|
||||
if ( tmp == 8 ) tmp = 4;
|
||||
/* NB. Immediates are sign-extended as necessary. */
|
||||
- switch ( tmp )
|
||||
- {
|
||||
- case 1: insn_fetch(int8_t, 1); break;
|
||||
- case 2: insn_fetch(int16_t, 2); break;
|
||||
- case 4: insn_fetch(int32_t, 4); break;
|
||||
- }
|
||||
+ length += tmp;
|
||||
+ pc += tmp;
|
||||
break;
|
||||
case SrcImmByte:
|
||||
- insn_fetch(int8_t, 1);
|
||||
+ length += 1;
|
||||
+ pc += 1;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -414,13 +417,9 @@ done_prefixes:
|
||||
|
||||
switch ( b )
|
||||
{
|
||||
- case 0xa0 ... 0xa1: /* mov */
|
||||
- length += ad_bytes;
|
||||
- _regs.eip += ad_bytes; /* skip src displacement */
|
||||
- break;
|
||||
- case 0xa2 ... 0xa3: /* mov */
|
||||
+ case 0xa0 ... 0xa3: /* mov */
|
||||
length += ad_bytes;
|
||||
- _regs.eip += ad_bytes; /* skip dst displacement */
|
||||
+ pc += ad_bytes; /* skip src/dst displacement */
|
||||
break;
|
||||
case 0xf6 ... 0xf7: /* Grp3 */
|
||||
switch ( modrm_reg )
|
||||
@@ -429,12 +428,8 @@ done_prefixes:
|
||||
/* Special case in Grp3: test has an immediate source operand. */
|
||||
tmp = (d & ByteOp) ? 1 : op_bytes;
|
||||
if ( tmp == 8 ) tmp = 4;
|
||||
- switch ( tmp )
|
||||
- {
|
||||
- case 1: insn_fetch(int8_t, 1); break;
|
||||
- case 2: insn_fetch(int16_t, 2); break;
|
||||
- case 4: insn_fetch(int32_t, 4); break;
|
||||
- }
|
||||
+ length += tmp;
|
||||
+ pc += tmp;
|
||||
goto done;
|
||||
}
|
||||
break;
|
||||
@@ -445,6 +440,6 @@ done:
|
||||
|
||||
cannot_emulate:
|
||||
DPRINTK("Cannot emulate %02x at address %lx (eip %lx, mode %d)\n",
|
||||
- b, (unsigned long)_regs.eip, (unsigned long)regs->eip, mode);
|
||||
+ b, pc, org_pc, mode);
|
||||
return -1;
|
||||
}
|
28
npt-fpu-bug.patch
Normal file
28
npt-fpu-bug.patch
Normal file
@ -0,0 +1,28 @@
|
||||
Index: xen-3.0.4-testing/xen/arch/x86/hvm/svm/svm.c
|
||||
===================================================================
|
||||
--- xen-3.0.4-testing.orig/xen/arch/x86/hvm/svm/svm.c
|
||||
+++ xen-3.0.4-testing/xen/arch/x86/hvm/svm/svm.c
|
||||
@@ -1745,6 +1745,13 @@ int npt_mov_to_cr(int gpreg, int cr, str
|
||||
case 0:
|
||||
vmcb->cr0 = value;
|
||||
v->arch.hvm_svm.cpu_shadow_cr0 = value;
|
||||
+
|
||||
+ /* TS cleared? Then initialise FPU now. */
|
||||
+ if ( !(value & X86_CR0_TS) ) {
|
||||
+ setup_fpu(v);
|
||||
+ vmcb->exception_intercepts &= ~EXCEPTION_BITMAP_NM;
|
||||
+ }
|
||||
+
|
||||
npt_update_guest_paging_mode(v);
|
||||
break;
|
||||
case 3:
|
||||
@@ -1755,8 +1762,8 @@ int npt_mov_to_cr(int gpreg, int cr, str
|
||||
case 4: /* CR4 */
|
||||
vmcb->cr4 = value;
|
||||
v->arch.hvm_svm.cpu_shadow_cr4 = value;
|
||||
- npt_update_guest_paging_mode(v);
|
||||
set_bit(ARCH_SVM_VMCB_ASSIGN_ASID, &v->arch.hvm_svm.flags);
|
||||
+ npt_update_guest_paging_mode(v);
|
||||
break;
|
||||
case 8:
|
||||
vlapic_set_reg(vlapic, APIC_TASKPRI, ((value & 0x0F) << 4));
|
302
npt-windows-bug.patch
Normal file
302
npt-windows-bug.patch
Normal file
@ -0,0 +1,302 @@
|
||||
Index: xen-3.0.4-testing/xen/arch/x86/domain.c
|
||||
===================================================================
|
||||
--- xen-3.0.4-testing.orig/xen/arch/x86/domain.c
|
||||
+++ xen-3.0.4-testing/xen/arch/x86/domain.c
|
||||
@@ -41,6 +41,7 @@
|
||||
#include <asm/hvm/hvm.h>
|
||||
#include <asm/hvm/support.h>
|
||||
#include <asm/msr.h>
|
||||
+#include <asm/hap.h>
|
||||
#ifdef CONFIG_COMPAT
|
||||
#include <compat/vcpu.h>
|
||||
#endif
|
||||
@@ -334,6 +335,8 @@ int vcpu_initialise(struct vcpu *v)
|
||||
|
||||
pae_l3_cache_init(&v->arch.pae_l3_cache);
|
||||
|
||||
+ hap_vcpu_init(v);
|
||||
+
|
||||
/* This should move to arch_domain_create(). */
|
||||
if ( !is_idle_domain(d) && (v->vcpu_id == 0) )
|
||||
pit_init(v, cpu_khz);
|
||||
@@ -470,6 +473,9 @@ void arch_domain_destroy(struct domain *
|
||||
hvm_domain_destroy(d);
|
||||
}
|
||||
|
||||
+ for_each_vcpu ( d, v )
|
||||
+ hap_vcpu_destroy(v);
|
||||
+
|
||||
shadow_final_teardown(d);
|
||||
|
||||
free_xenheap_pages(
|
||||
Index: xen-3.0.4-testing/xen/arch/x86/hvm/hvm.c
|
||||
===================================================================
|
||||
--- xen-3.0.4-testing.orig/xen/arch/x86/hvm/hvm.c
|
||||
+++ xen-3.0.4-testing/xen/arch/x86/hvm/hvm.c
|
||||
@@ -49,6 +49,7 @@
|
||||
#include <public/hvm/ioreq.h>
|
||||
#include <public/version.h>
|
||||
#include <public/memory.h>
|
||||
+#include <asm/hap.h>
|
||||
|
||||
int hvm_enabled = 0;
|
||||
|
||||
@@ -339,7 +340,7 @@ static int __hvm_copy(void *buf, paddr_t
|
||||
count = min_t(int, PAGE_SIZE - (addr & ~PAGE_MASK), todo);
|
||||
|
||||
if ( virt )
|
||||
- mfn = get_mfn_from_gpfn(shadow_gva_to_gfn(current, addr));
|
||||
+ mfn = get_mfn_from_gpfn(hap_gva_to_gfn(current, addr));
|
||||
else
|
||||
mfn = get_mfn_from_gpfn(addr >> PAGE_SHIFT);
|
||||
|
||||
Index: xen-3.0.4-testing/xen/arch/x86/hvm/platform.c
|
||||
===================================================================
|
||||
--- xen-3.0.4-testing.orig/xen/arch/x86/hvm/platform.c
|
||||
+++ xen-3.0.4-testing/xen/arch/x86/hvm/platform.c
|
||||
@@ -37,6 +37,7 @@
|
||||
#include <xen/lib.h>
|
||||
#include <xen/sched.h>
|
||||
#include <asm/current.h>
|
||||
+#include <asm/hap.h>
|
||||
|
||||
#define DECODE_success 1
|
||||
#define DECODE_failure 0
|
||||
@@ -793,7 +794,7 @@ void send_pio_req(unsigned long port, un
|
||||
if ( value_is_ptr ) /* get physical address of data */
|
||||
{
|
||||
if ( hvm_paging_enabled(current) )
|
||||
- p->data = shadow_gva_to_gpa(current, value);
|
||||
+ p->data = hap_gva_to_gpa(current, value);
|
||||
else
|
||||
p->data = value; /* guest VA == guest PA */
|
||||
}
|
||||
@@ -849,7 +850,7 @@ static void send_mmio_req(unsigned char
|
||||
if ( value_is_ptr )
|
||||
{
|
||||
if ( hvm_paging_enabled(v) )
|
||||
- p->data = shadow_gva_to_gpa(v, value);
|
||||
+ p->data = hap_gva_to_gpa(v, value);
|
||||
else
|
||||
p->data = value; /* guest VA == guest PA */
|
||||
}
|
||||
@@ -965,7 +966,7 @@ void handle_mmio(unsigned long gpa)
|
||||
if ( ad_size == WORD )
|
||||
addr &= 0xFFFF;
|
||||
addr += hvm_get_segment_base(v, x86_seg_es);
|
||||
- if ( shadow_gva_to_gpa(v, addr) == gpa )
|
||||
+ if ( hap_gva_to_gpa(v, addr) == gpa )
|
||||
{
|
||||
enum x86_segment seg;
|
||||
|
||||
Index: xen-3.0.4-testing/xen/arch/x86/mm/hap/hap.c
|
||||
===================================================================
|
||||
--- xen-3.0.4-testing.orig/xen/arch/x86/mm/hap/hap.c
|
||||
+++ xen-3.0.4-testing/xen/arch/x86/mm/hap/hap.c
|
||||
@@ -18,7 +18,21 @@
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
-#include <xen/init.h>
|
||||
+#include <xen/config.h>
|
||||
+#include <xen/types.h>
|
||||
+#include <xen/mm.h>
|
||||
+#include <xen/trace.h>
|
||||
+#include <xen/sched.h>
|
||||
+#include <xen/perfc.h>
|
||||
+#include <xen/irq.h>
|
||||
+#include <xen/domain_page.h>
|
||||
+#include <xen/guest_access.h>
|
||||
+#include <xen/keyhandler.h>
|
||||
+#include <asm/event.h>
|
||||
+#include <asm/page.h>
|
||||
+#include <asm/current.h>
|
||||
+#include <asm/flushtlb.h>
|
||||
+#include <asm/hap.h>
|
||||
|
||||
/* initialize hardware assisted paging. It checks whether hap option is enabled
|
||||
* in Xen boot option.
|
||||
@@ -26,6 +40,20 @@
|
||||
int opt_hap_enabled = 0;
|
||||
boolean_param("hap", opt_hap_enabled);
|
||||
|
||||
+/*************************************************/
|
||||
+/* hap functions */
|
||||
+/*************************************************/
|
||||
+void hap_vcpu_init(struct vcpu *v)
|
||||
+{
|
||||
+ v->arch.hap_activated = 0; /* not activated at the beginning */
|
||||
+}
|
||||
+
|
||||
+void hap_vcpu_destroy(struct vcpu *v)
|
||||
+{
|
||||
+ /* nothing to do */
|
||||
+}
|
||||
+
|
||||
+
|
||||
/*
|
||||
* Local variables:
|
||||
* mode: C
|
||||
Index: xen-3.0.4-testing/xen/arch/x86/mm/hap/npt/npt.c
|
||||
===================================================================
|
||||
--- xen-3.0.4-testing.orig/xen/arch/x86/mm/hap/npt/npt.c
|
||||
+++ xen-3.0.4-testing/xen/arch/x86/mm/hap/npt/npt.c
|
||||
@@ -34,6 +34,49 @@
|
||||
#include "page-guest32.h"
|
||||
|
||||
extern int opt_hap_enabled;
|
||||
+
|
||||
+/* Forward Declaration */
|
||||
+static paddr_t npt_gva_to_gpa_real_mode(struct vcpu *v, unsigned long gva);
|
||||
+static paddr_t npt_gva_to_gpa_protected_mode(struct vcpu *v,
|
||||
+ unsigned long gva);
|
||||
+static paddr_t npt_gva_to_gpa_pae_mode(struct vcpu *v, unsigned long gva);
|
||||
+static paddr_t npt_gva_to_gpa_long_mode(struct vcpu *v, unsigned long gva);
|
||||
+static unsigned long npt_gva_to_gfn_real_mode(struct vcpu *v,
|
||||
+ unsigned long gva);
|
||||
+static unsigned long npt_gva_to_gfn_protected_mode(struct vcpu *v,
|
||||
+ unsigned long gva);
|
||||
+static unsigned long npt_gva_to_gfn_pae_mode(struct vcpu *v,
|
||||
+ unsigned long gva);
|
||||
+static unsigned long npt_gva_to_gfn_long_mode(struct vcpu *v,
|
||||
+ unsigned long gva);
|
||||
+
|
||||
+/*******************************************/
|
||||
+/* global variables */
|
||||
+/*******************************************/
|
||||
+struct hap_vcpu NPT_REAL_MODE_HANDLER = {
|
||||
+ .guest_page_level = 1,
|
||||
+ .gva_to_gfn = npt_gva_to_gfn_real_mode,
|
||||
+ .gva_to_gpa = npt_gva_to_gpa_real_mode
|
||||
+};
|
||||
+
|
||||
+struct hap_vcpu NPT_PROTECTED_MODE_HANDLER = {
|
||||
+ .guest_page_level = 2,
|
||||
+ .gva_to_gfn = npt_gva_to_gfn_protected_mode,
|
||||
+ .gva_to_gpa = npt_gva_to_gpa_protected_mode
|
||||
+};
|
||||
+
|
||||
+struct hap_vcpu NPT_PAE_MODE_HANDLER = {
|
||||
+ .guest_page_level = 3,
|
||||
+ .gva_to_gfn = npt_gva_to_gfn_pae_mode,
|
||||
+ .gva_to_gpa = npt_gva_to_gpa_pae_mode
|
||||
+};
|
||||
+
|
||||
+struct hap_vcpu NPT_LONG_MODE_HANDLER = {
|
||||
+ .guest_page_level = 4,
|
||||
+ .gva_to_gfn = npt_gva_to_gfn_long_mode,
|
||||
+ .gva_to_gpa = npt_gva_to_gpa_long_mode
|
||||
+};
|
||||
+
|
||||
/*******************************************/
|
||||
/* Platform Specific Functions */
|
||||
/*******************************************/
|
||||
@@ -350,7 +393,9 @@ void npt_detect(void)
|
||||
|
||||
/* check CPUID for nested paging support */
|
||||
cpuid(0x8000000A, &eax, &ebx, &ecx, &edx);
|
||||
- if ( !(edx & 0x01) && opt_hap_enabled ) {
|
||||
+ if ( edx & 0x01 ) {
|
||||
+ }
|
||||
+ else if ( opt_hap_enabled ) {
|
||||
printk(" nested paging is not supported by this CPU.\n");
|
||||
opt_hap_enabled = 0; /* no nested paging, we disable op_hap_enabled */
|
||||
}
|
||||
@@ -366,23 +411,19 @@ void npt_set_guest_paging_levels(struct
|
||||
switch(levels) {
|
||||
case 1:
|
||||
NPT_PRINTK("Install real mode guest with ID = %d\n", v->vcpu_id);
|
||||
- v->arch.shadow.mode->gva_to_gpa = &npt_gva_to_gpa_real_mode;
|
||||
- v->arch.shadow.mode->gva_to_gfn = &npt_gva_to_gfn_real_mode;
|
||||
+ v->arch.hap_mode = &NPT_REAL_MODE_HANDLER;
|
||||
break;
|
||||
case 2:
|
||||
NPT_PRINTK("Install 32-bit non-PAE guest with ID = %d\n", v->vcpu_id);
|
||||
- v->arch.shadow.mode->gva_to_gpa = &npt_gva_to_gpa_protected_mode;
|
||||
- v->arch.shadow.mode->gva_to_gfn = &npt_gva_to_gfn_protected_mode;
|
||||
+ v->arch.hap_mode = &NPT_PROTECTED_MODE_HANDLER;
|
||||
break;
|
||||
case 3:
|
||||
NPT_PRINTK("Install 32-bit PAE guest with ID = %d\n", v->vcpu_id);
|
||||
- v->arch.shadow.mode->gva_to_gpa = &npt_gva_to_gpa_pae_mode;
|
||||
- v->arch.shadow.mode->gva_to_gfn = &npt_gva_to_gfn_pae_mode;
|
||||
+ v->arch.hap_mode = &NPT_PAE_MODE_HANDLER;
|
||||
break;
|
||||
case 4:
|
||||
NPT_PRINTK("Install 64-bit guest with ID = %d\n", v->vcpu_id);
|
||||
- v->arch.shadow.mode->gva_to_gpa = &npt_gva_to_gpa_long_mode;
|
||||
- v->arch.shadow.mode->gva_to_gfn = &npt_gva_to_gfn_long_mode;
|
||||
+ v->arch.hap_mode = &NPT_LONG_MODE_HANDLER;
|
||||
break;
|
||||
default:
|
||||
printk("Un-supported guest paging level: %d\n", levels);
|
||||
Index: xen-3.0.4-testing/xen/include/asm-x86/domain.h
|
||||
===================================================================
|
||||
--- xen-3.0.4-testing.orig/xen/include/asm-x86/domain.h
|
||||
+++ xen-3.0.4-testing/xen/include/asm-x86/domain.h
|
||||
@@ -208,8 +208,8 @@ struct arch_vcpu
|
||||
unsigned long shadow_ldt_mapcnt;
|
||||
|
||||
struct shadow_vcpu shadow;
|
||||
-
|
||||
- unsigned int hap_activated:1; /* hardware assisted paging */
|
||||
+ struct hap_vcpu *hap_mode; /* hardware assisted paging support */
|
||||
+ unsigned int hap_activated:1;
|
||||
} __cacheline_aligned;
|
||||
|
||||
/* shorthands to improve code legibility */
|
||||
Index: xen-3.0.4-testing/xen/include/asm-x86/hap.h
|
||||
===================================================================
|
||||
--- xen-3.0.4-testing.orig/xen/include/asm-x86/hap.h
|
||||
+++ xen-3.0.4-testing/xen/include/asm-x86/hap.h
|
||||
@@ -26,6 +26,25 @@
|
||||
#include <xen/domain_page.h>
|
||||
#include <asm/flushtlb.h>
|
||||
|
||||
+/************************************************/
|
||||
+/* HAP data structure */
|
||||
+/************************************************/
|
||||
+struct hap_vcpu {
|
||||
+ int guest_page_level;
|
||||
+
|
||||
+ /* function pointers */
|
||||
+ int (*host_pgfault )(struct vcpu *v, unsigned long va,
|
||||
+ struct cpu_user_regs *regs);
|
||||
+ unsigned long (*gva_to_gfn )(struct vcpu *v, unsigned long gva);
|
||||
+ paddr_t (*gva_to_gpa )(struct vcpu *v, unsigned long gva);
|
||||
+};
|
||||
+
|
||||
+/************************************************/
|
||||
+/* HAP interface to Xen */
|
||||
+/************************************************/
|
||||
+void hap_vcpu_init(struct vcpu *v);
|
||||
+void hap_vcpu_destroy(struct vcpu *v);
|
||||
+
|
||||
static inline unsigned int hap_is_activated(struct vcpu *v)
|
||||
{
|
||||
return v->arch.hap_activated;
|
||||
@@ -41,6 +60,24 @@ static inline void hap_deactivate(struct
|
||||
v->arch.hap_activated = 0;
|
||||
}
|
||||
|
||||
+static inline paddr_t hap_gva_to_gpa(struct vcpu *v, unsigned long gva)
|
||||
+{
|
||||
+ if ( v->arch.hap_activated )
|
||||
+ return v->arch.hap_mode->gva_to_gpa(v, gva);
|
||||
+ else
|
||||
+ return shadow_gva_to_gpa(v, gva);
|
||||
+}
|
||||
+
|
||||
+static inline unsigned long hap_gva_to_gfn(struct vcpu *v, unsigned long gva)
|
||||
+{
|
||||
+ if ( v->arch.hap_activated )
|
||||
+ return v->arch.hap_mode->gva_to_gfn(v, gva);
|
||||
+ else
|
||||
+ return shadow_gva_to_gfn(v, gva);
|
||||
+}
|
||||
+/************************************************/
|
||||
+/* nested paging interface */
|
||||
+/************************************************/
|
||||
void npt_update_guest_paging_mode(struct vcpu *v);
|
||||
void npt_detect(void);
|
||||
#endif
|
1096
npt_part1.patch
Normal file
1096
npt_part1.patch
Normal file
File diff suppressed because it is too large
Load Diff
13
npt_part2.patch
Normal file
13
npt_part2.patch
Normal file
@ -0,0 +1,13 @@
|
||||
Index: xen-3.0.4-testing/xen/arch/x86/mm/shadow/common.c
|
||||
===================================================================
|
||||
--- xen-3.0.4-testing.orig/xen/arch/x86/mm/shadow/common.c
|
||||
+++ xen-3.0.4-testing/xen/arch/x86/mm/shadow/common.c
|
||||
@@ -1163,6 +1163,8 @@ p2m_next_level(struct domain *d, mfn_t *
|
||||
if (type == PGT_l2_page_table)
|
||||
{
|
||||
struct vcpu *v;
|
||||
+ /* for PAE mode, PDPE only have PCD/PWT/P bits available */
|
||||
+ *p2m_entry = l1e_from_pfn(mfn_x(mfn), _PAGE_PRESENT);
|
||||
/* We have written to the p2m l3: need to sync the per-vcpu
|
||||
* copies of it in the monitor tables */
|
||||
p2m_install_entry_in_monitors(d, (l3_pgentry_t *)p2m_entry);
|
83
pae-guest-linear-pgtable.patch
Normal file
83
pae-guest-linear-pgtable.patch
Normal file
@ -0,0 +1,83 @@
|
||||
Index: 2007-01-31/xen/arch/x86/mm.c
|
||||
===================================================================
|
||||
--- 2007-01-31.orig/xen/arch/x86/mm.c 2007-01-31 09:43:38.000000000 +0100
|
||||
+++ 2007-01-31/xen/arch/x86/mm.c 2007-02-02 16:34:03.000000000 +0100
|
||||
@@ -509,7 +509,7 @@ get_linear_pagetable(
|
||||
return 0;
|
||||
|
||||
/*
|
||||
- * Make sure that the mapped frame is an already-validated L2 table.
|
||||
+ * Make sure that the mapped frame is an already-validated root table.
|
||||
* If so, atomically increment the count (checking for overflow).
|
||||
*/
|
||||
page = mfn_to_page(pfn);
|
||||
@@ -531,6 +531,51 @@ get_linear_pagetable(
|
||||
}
|
||||
#endif /* !CONFIG_X86_PAE */
|
||||
|
||||
+#if defined(CONFIG_X86_PAE) || defined(CONFIG_X86_64)
|
||||
+static int
|
||||
+get_l2_linear_pagetable(
|
||||
+ l2_pgentry_t l2e, unsigned long l2e_pfn, struct domain *d)
|
||||
+{
|
||||
+ unsigned long pfn;
|
||||
+
|
||||
+ if ( (l2e_get_flags(l2e) & _PAGE_RW) )
|
||||
+ {
|
||||
+ MEM_LOG("Attempt to create linear p.t. with write perms");
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ if ( (pfn = l2e_get_pfn(l2e)) != l2e_pfn )
|
||||
+ {
|
||||
+ unsigned long x, y;
|
||||
+ struct page_info *page;
|
||||
+
|
||||
+ /* Make sure the mapped frame belongs to the correct domain. */
|
||||
+ if ( unlikely(!get_page_from_pagenr(pfn, d)) )
|
||||
+ return 0;
|
||||
+
|
||||
+ /*
|
||||
+ * Make sure that the mapped frame is an already-validated L2 table.
|
||||
+ * If so, atomically increment the count (checking for overflow).
|
||||
+ */
|
||||
+ page = mfn_to_page(pfn);
|
||||
+ y = page->u.inuse.type_info;
|
||||
+ do {
|
||||
+ x = y;
|
||||
+ if ( unlikely((x & PGT_count_mask) == PGT_count_mask) ||
|
||||
+ unlikely((x & (PGT_type_mask|PGT_validated)) !=
|
||||
+ (PGT_l2_page_table|PGT_validated)) )
|
||||
+ {
|
||||
+ put_page(page);
|
||||
+ return 0;
|
||||
+ }
|
||||
+ }
|
||||
+ while ( (y = cmpxchg(&page->u.inuse.type_info, x, x + 1)) != x );
|
||||
+ }
|
||||
+
|
||||
+ return 1;
|
||||
+}
|
||||
+#endif /* !CONFIG_X86_PAE */
|
||||
+
|
||||
int
|
||||
get_page_from_l1e(
|
||||
l1_pgentry_t l1e, struct domain *d)
|
||||
@@ -607,10 +652,16 @@ get_page_from_l2e(
|
||||
}
|
||||
|
||||
rc = get_page_and_type_from_pagenr(l2e_get_pfn(l2e), PGT_l1_page_table, d);
|
||||
-#if CONFIG_PAGING_LEVELS == 2
|
||||
if ( unlikely(!rc) )
|
||||
+ {
|
||||
+#if CONFIG_PAGING_LEVELS == 2
|
||||
rc = get_linear_pagetable(l2e, pfn, d);
|
||||
+#else
|
||||
+ if ( (CONFIG_PAGING_LEVELS == 3 || IS_COMPAT(d)) )
|
||||
+ rc = get_l2_linear_pagetable(l2e, pfn, d);
|
||||
#endif
|
||||
+ }
|
||||
+
|
||||
return rc;
|
||||
}
|
||||
|
35
protocol-bimodal.diff
Normal file
35
protocol-bimodal.diff
Normal file
@ -0,0 +1,35 @@
|
||||
bimodal: header file with protocol names.
|
||||
|
||||
This patch adds a header file with the protocol names.
|
||||
|
||||
Signed-off-by: Gerd Hoffmann <kraxel@suse.de>
|
||||
---
|
||||
xen/include/public/io/protocols.h | 21 +++++++++++++++++++++
|
||||
1 file changed, 21 insertions(+)
|
||||
|
||||
Index: build-32-unstable-13495/xen/include/public/io/protocols.h
|
||||
===================================================================
|
||||
--- /dev/null
|
||||
+++ build-32-unstable-13495/xen/include/public/io/protocols.h
|
||||
@@ -0,0 +1,21 @@
|
||||
+#ifndef __XEN_PROTOCOLS_H__
|
||||
+#define __XEN_PROTOCOLS_H__
|
||||
+
|
||||
+#define XEN_IO_PROTO_ABI_X86_32 "x86_32-abi"
|
||||
+#define XEN_IO_PROTO_ABI_X86_64 "x86_64-abi"
|
||||
+#define XEN_IO_PROTO_ABI_IA64 "ia64-abi"
|
||||
+#define XEN_IO_PROTO_ABI_POWERPC64 "powerpc64-abi"
|
||||
+
|
||||
+#if defined(__i386__)
|
||||
+# define XEN_IO_PROTO_ABI_NATIVE XEN_IO_PROTO_ABI_X86_32
|
||||
+#elif defined(__x86_64__)
|
||||
+# define XEN_IO_PROTO_ABI_NATIVE XEN_IO_PROTO_ABI_X86_64
|
||||
+#elif defined(__ia64__)
|
||||
+# define XEN_IO_PROTO_ABI_NATIVE XEN_IO_PROTO_ABI_IA64
|
||||
+#elif defined(__powerpc64__)
|
||||
+# define XEN_IO_PROTO_ABI_NATIVE XEN_IO_PROTO_ABI_POWERPC64
|
||||
+#else
|
||||
+# error arch fixup needed here
|
||||
+#endif
|
||||
+
|
||||
+#endif
|
101
pv-driver-build.patch
Normal file
101
pv-driver-build.patch
Normal file
@ -0,0 +1,101 @@
|
||||
Index: 2007-01-19/unmodified_drivers/linux-2.6/mkbuildtree
|
||||
===================================================================
|
||||
--- 2007-01-19.orig/unmodified_drivers/linux-2.6/mkbuildtree 2006-12-14 22:49:58.000000000 +0100
|
||||
+++ 2007-01-19/unmodified_drivers/linux-2.6/mkbuildtree 2007-01-24 14:48:33.000000000 +0100
|
||||
@@ -8,10 +8,12 @@ else
|
||||
echo "This may be overridden on the command line (i386,x86_64,ia64)."
|
||||
fi
|
||||
|
||||
-C=$PWD
|
||||
-
|
||||
-XEN=$C/../../xen
|
||||
-XL=$C/../../linux-2.6-xen-sparse
|
||||
+if [ -n "$XL" -a -d "$XL" ]; then
|
||||
+ XL=$(cd $XL && pwd)
|
||||
+else
|
||||
+ XL=/usr/src/linux
|
||||
+fi
|
||||
+cd "$(dirname "$0")"
|
||||
|
||||
for d in $(find ${XL}/drivers/xen/ -maxdepth 1 -type d | sed -e 1d); do
|
||||
if ! echo $d | egrep -q back; then
|
||||
@@ -24,14 +26,9 @@ ln -sf ${XL}/drivers/xen/core/features.c
|
||||
ln -sf ${XL}/drivers/xen/core/xen_proc.c xenbus
|
||||
ln -sf ${XL}/drivers/xen/core/reboot.c util
|
||||
|
||||
-mkdir -p include
|
||||
-mkdir -p include/xen
|
||||
-mkdir -p include/public
|
||||
-mkdir -p include/asm
|
||||
-mkdir -p include/asm/xen
|
||||
+mkdir -p include/asm include/xen
|
||||
|
||||
lndir -silent ${XL}/include/xen include/xen
|
||||
-ln -nsf ${XEN}/include/public include/xen/interface
|
||||
|
||||
# Need to be quite careful here: we don't want the files we link in to
|
||||
# risk overriding the native Linux ones (in particular, system.h must
|
||||
@@ -43,7 +40,8 @@ in
|
||||
ln -sf ${XL}/include/asm-x86_64/mach-xen/asm/hypercall.h include/asm
|
||||
ln -sf ${XL}/include/asm-x86_64/mach-xen/asm/synch_bitops.h include/asm
|
||||
ln -sf ${XL}/include/asm-x86_64/mach-xen/asm/maddr.h include/asm
|
||||
- ln -sf ${XL}/include/asm-i386 include/asm-i386
|
||||
+ mkdir include/asm-i386
|
||||
+ lndir -silent ${XL}/include/asm-i386 include/asm-i386
|
||||
;;
|
||||
i[34567]86)
|
||||
ln -sf ${XL}/include/asm-i386/mach-xen/asm/hypervisor.h include/asm
|
||||
@@ -56,6 +54,7 @@ i[34567]86)
|
||||
ln -sf ${XL}/include/asm-ia64/hypercall.h include/asm
|
||||
ln -sf ${XL}/include/asm-ia64/synch_bitops.h include/asm
|
||||
ln -sf ${XL}/include/asm-ia64/maddr.h include/asm
|
||||
+ mkdir include/asm/xen
|
||||
ln -sf ${XL}/include/asm-ia64/xen/xcom_hcall.h include/asm/xen
|
||||
ln -sf ${XL}/include/asm-ia64/xen/xencomm.h include/asm/xen
|
||||
ln -sf ${XL}/arch/ia64/xen/xcom_mini.c platform-pci
|
||||
Index: 2007-01-19/unmodified_drivers/linux-2.6/compat-include/xen/platform-compat.h
|
||||
===================================================================
|
||||
--- 2007-01-19.orig/unmodified_drivers/linux-2.6/compat-include/xen/platform-compat.h 2006-12-14 22:49:58.000000000 +0100
|
||||
+++ 2007-01-19/unmodified_drivers/linux-2.6/compat-include/xen/platform-compat.h 2007-01-26 10:44:53.000000000 +0100
|
||||
@@ -69,4 +69,12 @@ extern char *kasprintf(gfp_t gfp, const
|
||||
__attribute__ ((format (printf, 2, 3)));
|
||||
#endif
|
||||
|
||||
+/*
|
||||
+ * This variable at present is referenced by netfront, but only in code that
|
||||
+ * is dead when running in hvm guests. To detect potential active uses of it
|
||||
+ * in the future, don't try to supply a 'valid' value here, so that any
|
||||
+ * mappings created with it will fault when accessed.
|
||||
+ */
|
||||
+#define __supported_pte_mask ((maddr_t)0)
|
||||
+
|
||||
#endif
|
||||
Index: 2007-01-19/unmodified_drivers/linux-2.6/overrides.mk
|
||||
===================================================================
|
||||
--- 2007-01-19.orig/unmodified_drivers/linux-2.6/overrides.mk 2006-12-14 22:49:58.000000000 +0100
|
||||
+++ 2007-01-19/unmodified_drivers/linux-2.6/overrides.mk 2007-01-23 13:19:27.000000000 +0100
|
||||
@@ -4,9 +4,5 @@
|
||||
#
|
||||
# (i.e. we need the native config for things like -mregparm, but
|
||||
# a Xen kernel to find the right headers)
|
||||
-EXTRA_CFLAGS += -DCONFIG_VMX -DCONFIG_VMX_GUEST -DCONFIG_X86_XEN
|
||||
-EXTRA_CFLAGS += -DCONFIG_XEN_SHADOW_MODE -DCONFIG_XEN_SHADOW_TRANSLATE
|
||||
-EXTRA_CFLAGS += -DCONFIG_XEN_BLKDEV_GRANT -DXEN_EVTCHN_MASK_OPS
|
||||
-EXTRA_CFLAGS += -DCONFIG_XEN_NETDEV_GRANT_RX -DCONFIG_XEN_NETDEV_GRANT_TX
|
||||
EXTRA_CFLAGS += -D__XEN_INTERFACE_VERSION__=0x00030202
|
||||
EXTRA_CFLAGS += -I$(M)/include -I$(M)/compat-include -DHAVE_XEN_PLATFORM_COMPAT_H
|
||||
Index: 2007-01-19/unmodified_drivers/linux-2.6/platform-pci/platform-compat.c
|
||||
===================================================================
|
||||
--- 2007-01-19.orig/unmodified_drivers/linux-2.6/platform-pci/platform-compat.c 2006-12-14 22:49:58.000000000 +0100
|
||||
+++ 2007-01-19/unmodified_drivers/linux-2.6/platform-pci/platform-compat.c 2007-01-23 12:54:45.000000000 +0100
|
||||
@@ -115,7 +115,9 @@ void *kzalloc(size_t size, int flags)
|
||||
EXPORT_SYMBOL(kzalloc);
|
||||
#endif
|
||||
|
||||
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18)
|
||||
+#if defined(CONFIG_SUSE_KERNEL) \
|
||||
+ ? LINUX_VERSION_CODE < KERNEL_VERSION(2,6,16) \
|
||||
+ : LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18)
|
||||
/* Simplified asprintf. */
|
||||
char *kasprintf(gfp_t gfp, const char *fmt, ...)
|
||||
{
|
@ -1,7 +1,7 @@
|
||||
Index: xen-3.0-testing/tools/misc/serial-split/Makefile
|
||||
Index: xen-3.0.4-testing/tools/misc/serial-split/Makefile
|
||||
===================================================================
|
||||
--- /dev/null
|
||||
+++ xen-3.0-testing/tools/misc/serial-split/Makefile
|
||||
+++ xen-3.0.4-testing/tools/misc/serial-split/Makefile
|
||||
@@ -0,0 +1,20 @@
|
||||
+CC ?= gcc
|
||||
+CFLAGS ?= -Wall -Os
|
||||
@ -23,10 +23,10 @@ Index: xen-3.0-testing/tools/misc/serial-split/Makefile
|
||||
+
|
||||
+%.o: %.c Makefile
|
||||
+ $(CC) $(CFLAGS) -c -o $@ $<
|
||||
Index: xen-3.0-testing/tools/misc/serial-split/serial-split.c
|
||||
Index: xen-3.0.4-testing/tools/misc/serial-split/serial-split.c
|
||||
===================================================================
|
||||
--- /dev/null
|
||||
+++ xen-3.0-testing/tools/misc/serial-split/serial-split.c
|
||||
+++ xen-3.0.4-testing/tools/misc/serial-split/serial-split.c
|
||||
@@ -0,0 +1,422 @@
|
||||
+/*
|
||||
+ * serial-split.c
|
||||
|
28
suppress-rdtscp.patch
Normal file
28
suppress-rdtscp.patch
Normal file
@ -0,0 +1,28 @@
|
||||
Index: 2007-01-31/xen/arch/x86/traps.c
|
||||
===================================================================
|
||||
--- 2007-01-31.orig/xen/arch/x86/traps.c 2007-01-31 09:42:07.000000000 +0100
|
||||
+++ 2007-01-31/xen/arch/x86/traps.c 2007-02-07 17:03:20.000000000 +0100
|
||||
@@ -613,6 +613,11 @@ static int emulate_forced_invalid_op(str
|
||||
if ( !IS_PRIV(current->domain) )
|
||||
clear_bit(X86_FEATURE_MTRR, &d);
|
||||
}
|
||||
+ else if ( regs->eax == 0x80000001 )
|
||||
+ {
|
||||
+ /* Modify Feature Information. */
|
||||
+ clear_bit(X86_FEATURE_RDTSCP % 32, &d);
|
||||
+ }
|
||||
else
|
||||
{
|
||||
(void)cpuid_hypervisor_leaves(regs->eax, &a, &b, &c, &d);
|
||||
Index: 2007-01-31/xen/include/asm-x86/cpufeature.h
|
||||
===================================================================
|
||||
--- 2007-01-31.orig/xen/include/asm-x86/cpufeature.h 2007-01-31 09:28:56.000000000 +0100
|
||||
+++ 2007-01-31/xen/include/asm-x86/cpufeature.h 2007-02-07 17:03:20.000000000 +0100
|
||||
@@ -49,6 +49,7 @@
|
||||
#define X86_FEATURE_MP (1*32+19) /* MP Capable. */
|
||||
#define X86_FEATURE_NX (1*32+20) /* Execute Disable */
|
||||
#define X86_FEATURE_MMXEXT (1*32+22) /* AMD MMX extensions */
|
||||
+#define X86_FEATURE_RDTSCP (1*32+27) /* RDTSCP */
|
||||
#define X86_FEATURE_LM (1*32+29) /* Long Mode (x86-64) */
|
||||
#define X86_FEATURE_3DNOWEXT (1*32+30) /* AMD 3DNow! extensions */
|
||||
#define X86_FEATURE_3DNOW (1*32+31) /* 3DNow! */
|
116
svm-update-v_tpr-on-mmio.patch
Normal file
116
svm-update-v_tpr-on-mmio.patch
Normal file
@ -0,0 +1,116 @@
|
||||
# HG changeset patch
|
||||
# User Travis Betak <travis.betak@amd.com>
|
||||
# Date 1168370530 21600
|
||||
# Node ID e822926dd62492282e51c5847a8d85a3d22dda1d
|
||||
# Parent d401cb96d8a0da5febe737b86f453a88f1f45bb7
|
||||
[HVM][SVM] Updated the SVM V_TPR register on MMIO writes to the VLAPIC TPR
|
||||
|
||||
The SVM architecture includes a virtual TPR register. This patch
|
||||
updates this register on MMIO writes to the HVM Virtual APIC.
|
||||
|
||||
VT does not have this register as far as I know so a stub is added in
|
||||
the VT code.
|
||||
|
||||
Signed-off-by: Travis Betak <travis.betak@amd.com>
|
||||
|
||||
Index: xen-3.0.4-testing/xen/arch/x86/hvm/svm/svm.c
|
||||
===================================================================
|
||||
--- xen-3.0.4-testing.orig/xen/arch/x86/hvm/svm/svm.c
|
||||
+++ xen-3.0.4-testing/xen/arch/x86/hvm/svm/svm.c
|
||||
@@ -503,6 +503,13 @@ void svm_update_guest_cr3(struct vcpu *v
|
||||
v->arch.hvm_svm.vmcb->cr3 = v->arch.hvm_vcpu.hw_cr3;
|
||||
}
|
||||
|
||||
+static void svm_update_vtpr(struct vcpu *v, unsigned long value)
|
||||
+{
|
||||
+ struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
|
||||
+
|
||||
+ vmcb->vintr.fields.tpr = value & 0x0f;
|
||||
+}
|
||||
+
|
||||
unsigned long svm_get_ctrl_reg(struct vcpu *v, unsigned int num)
|
||||
{
|
||||
switch ( num )
|
||||
@@ -894,6 +901,8 @@ int start_svm(void)
|
||||
hvm_funcs.update_host_cr3 = svm_update_host_cr3;
|
||||
hvm_funcs.update_guest_cr3 = svm_update_guest_cr3;
|
||||
|
||||
+ hvm_funcs.update_vtpr = svm_update_vtpr;
|
||||
+
|
||||
hvm_funcs.stts = svm_stts;
|
||||
hvm_funcs.set_tsc_offset = svm_set_tsc_offset;
|
||||
|
||||
@@ -1956,6 +1965,7 @@ static int mov_to_cr(int gpreg, int cr,
|
||||
|
||||
case 8:
|
||||
vlapic_set_reg(vlapic, APIC_TASKPRI, ((value & 0x0F) << 4));
|
||||
+ vmcb->vintr.fields.tpr = value & 0x0F;
|
||||
break;
|
||||
|
||||
default:
|
||||
Index: xen-3.0.4-testing/xen/arch/x86/hvm/vlapic.c
|
||||
===================================================================
|
||||
--- xen-3.0.4-testing.orig/xen/arch/x86/hvm/vlapic.c
|
||||
+++ xen-3.0.4-testing/xen/arch/x86/hvm/vlapic.c
|
||||
@@ -631,6 +631,7 @@ static void vlapic_write(struct vcpu *v,
|
||||
{
|
||||
case APIC_TASKPRI:
|
||||
vlapic_set_reg(vlapic, APIC_TASKPRI, val & 0xff);
|
||||
+ hvm_update_vtpr(v, (val >> 4) & 0x0f);
|
||||
break;
|
||||
|
||||
case APIC_EOI:
|
||||
Index: xen-3.0.4-testing/xen/arch/x86/hvm/vmx/vmx.c
|
||||
===================================================================
|
||||
--- xen-3.0.4-testing.orig/xen/arch/x86/hvm/vmx/vmx.c
|
||||
+++ xen-3.0.4-testing/xen/arch/x86/hvm/vmx/vmx.c
|
||||
@@ -738,6 +738,11 @@ static void vmx_inject_exception(
|
||||
v->arch.hvm_vmx.cpu_cr2 = cr2;
|
||||
}
|
||||
|
||||
+static void vmx_update_vtpr(struct vcpu *v, unsigned long value)
|
||||
+{
|
||||
+ /* VMX doesn't have a V_TPR field */
|
||||
+}
|
||||
+
|
||||
/* Setup HVM interfaces */
|
||||
static void vmx_setup_hvm_funcs(void)
|
||||
{
|
||||
@@ -763,6 +768,8 @@ static void vmx_setup_hvm_funcs(void)
|
||||
hvm_funcs.update_host_cr3 = vmx_update_host_cr3;
|
||||
hvm_funcs.update_guest_cr3 = vmx_update_guest_cr3;
|
||||
|
||||
+ hvm_funcs.update_vtpr = vmx_update_vtpr;
|
||||
+
|
||||
hvm_funcs.stts = vmx_stts;
|
||||
hvm_funcs.set_tsc_offset = vmx_set_tsc_offset;
|
||||
|
||||
Index: xen-3.0.4-testing/xen/include/asm-x86/hvm/hvm.h
|
||||
===================================================================
|
||||
--- xen-3.0.4-testing.orig/xen/include/asm-x86/hvm/hvm.h
|
||||
+++ xen-3.0.4-testing/xen/include/asm-x86/hvm/hvm.h
|
||||
@@ -108,6 +108,11 @@ struct hvm_function_table {
|
||||
void (*update_guest_cr3)(struct vcpu *v);
|
||||
|
||||
/*
|
||||
+ * Reflect the virtual APIC's value in the guest's V_TPR register
|
||||
+ */
|
||||
+ void (*update_vtpr)(struct vcpu *v, unsigned long value);
|
||||
+
|
||||
+ /*
|
||||
* Update specifics of the guest state:
|
||||
* 1) TS bit in guest cr0
|
||||
* 2) TSC offset in guest
|
||||
@@ -193,6 +198,12 @@ hvm_update_host_cr3(struct vcpu *v)
|
||||
hvm_funcs.update_host_cr3(v);
|
||||
}
|
||||
|
||||
+static inline void
|
||||
+hvm_update_vtpr(struct vcpu *v, unsigned long value)
|
||||
+{
|
||||
+ hvm_funcs.update_vtpr(v, value);
|
||||
+}
|
||||
+
|
||||
void hvm_update_guest_cr3(struct vcpu *v, unsigned long guest_cr3);
|
||||
|
||||
void hvm_hypercall_page_initialise(struct domain *d,
|
25
svm_cpuid_ffxsr_13743.patch
Normal file
25
svm_cpuid_ffxsr_13743.patch
Normal file
@ -0,0 +1,25 @@
|
||||
Index: xen-3.0.4-testing/xen/arch/x86/hvm/svm/svm.c
|
||||
===================================================================
|
||||
--- xen-3.0.4-testing.orig/xen/arch/x86/hvm/svm/svm.c
|
||||
+++ xen-3.0.4-testing/xen/arch/x86/hvm/svm/svm.c
|
||||
@@ -1085,6 +1085,8 @@ static void svm_vmexit_do_cpuid(struct v
|
||||
/* So far, we do not support 3DNow for the guest. */
|
||||
clear_bit(X86_FEATURE_3DNOW & 31, &edx);
|
||||
clear_bit(X86_FEATURE_3DNOWEXT & 31, &edx);
|
||||
+ /* no FFXSR instructions feature. */
|
||||
+ clear_bit(X86_FEATURE_FFXSR & 31, &edx);
|
||||
}
|
||||
}
|
||||
else if ( ( input == 0x80000007 ) || ( input == 0x8000000A ) )
|
||||
Index: xen-3.0.4-testing/xen/include/asm-x86/cpufeature.h
|
||||
===================================================================
|
||||
--- xen-3.0.4-testing.orig/xen/include/asm-x86/cpufeature.h
|
||||
+++ xen-3.0.4-testing/xen/include/asm-x86/cpufeature.h
|
||||
@@ -92,6 +92,7 @@
|
||||
#define X86_FEATURE_LAHF_LM (6*32+ 0) /* LAHF/SAHF in long mode */
|
||||
#define X86_FEATURE_CMP_LEGACY (6*32+ 1) /* If yes HyperThreading not valid */
|
||||
#define X86_FEATURE_SVME (6*32+ 2) /* Secure Virtual Machine */
|
||||
+#define X86_FEATURE_FFXSR (6*32+25) /* FFXSR instruction optimizations */
|
||||
|
||||
#define cpu_has(c, bit) test_bit(bit, (c)->x86_capability)
|
||||
#define boot_cpu_has(bit) test_bit(bit, boot_cpu_data.x86_capability)
|
41
tools-add-errors.diff
Normal file
41
tools-add-errors.diff
Normal file
@ -0,0 +1,41 @@
|
||||
Add more xc_error_code values.
|
||||
|
||||
XC_INVALID_PARAM
|
||||
such as asking for features unsupported by either xen or guest kernel.
|
||||
XC_OUT_OF_MEMORY
|
||||
no comment ;)
|
||||
|
||||
Signed-off-by: Gerd Hoffmann <kraxel@suse.de>
|
||||
---
|
||||
tools/libxc/xc_private.c | 4 ++++
|
||||
tools/libxc/xenctrl.h | 2 ++
|
||||
2 files changed, 6 insertions(+)
|
||||
|
||||
Index: build-32-unstable-12809/tools/libxc/xenctrl.h
|
||||
===================================================================
|
||||
--- build-32-unstable-12809.orig/tools/libxc/xenctrl.h
|
||||
+++ build-32-unstable-12809/tools/libxc/xenctrl.h
|
||||
@@ -691,6 +691,8 @@ typedef enum {
|
||||
XC_ERROR_NONE = 0,
|
||||
XC_INTERNAL_ERROR = 1,
|
||||
XC_INVALID_KERNEL = 2,
|
||||
+ XC_INVALID_PARAM = 3,
|
||||
+ XC_OUT_OF_MEMORY = 4,
|
||||
} xc_error_code;
|
||||
|
||||
#define XC_MAX_ERROR_MSG_LEN 1024
|
||||
Index: build-32-unstable-12809/tools/libxc/xc_private.c
|
||||
===================================================================
|
||||
--- build-32-unstable-12809.orig/tools/libxc/xc_private.c
|
||||
+++ build-32-unstable-12809/tools/libxc/xc_private.c
|
||||
@@ -45,6 +45,10 @@ const char *xc_error_code_to_desc(int co
|
||||
return "Internal error";
|
||||
case XC_INVALID_KERNEL:
|
||||
return "Invalid kernel";
|
||||
+ case XC_INVALID_PARAM:
|
||||
+ return "Invalid configuration";
|
||||
+ case XC_OUT_OF_MEMORY:
|
||||
+ return "Out of memory";
|
||||
}
|
||||
|
||||
return "Unknown error code";
|
238
tools-debug-oldbuilder.diff
Normal file
238
tools-debug-oldbuilder.diff
Normal file
@ -0,0 +1,238 @@
|
||||
debug: compile old domain builder too.
|
||||
|
||||
Compile both old and new domain builder into the tools, so both
|
||||
are available and can be selected at runtime. Nice for a quick
|
||||
check when things go wrong, to see if the new domain builder is
|
||||
incompatible with the old one or whenever something else broke.
|
||||
|
||||
Activate with "builder=old" in the config file or as option for
|
||||
the "xm create" command
|
||||
|
||||
---
|
||||
tools/libxc/Makefile | 4 +--
|
||||
tools/libxc/xc_linux_build.c | 4 +--
|
||||
tools/libxc/xenguest.h | 28 +++++++++++++++++++++
|
||||
tools/python/xen/lowlevel/xc/xc.c | 50 +++++++++++++++++++++++++++++++++++++-
|
||||
tools/python/xen/xend/image.py | 40 ++++++++++++++++++++++++++++++
|
||||
5 files changed, 121 insertions(+), 5 deletions(-)
|
||||
|
||||
Index: build-32-release304-13087/tools/libxc/Makefile
|
||||
===================================================================
|
||||
--- build-32-release304-13087.orig/tools/libxc/Makefile
|
||||
+++ build-32-release304-13087/tools/libxc/Makefile
|
||||
@@ -24,8 +24,8 @@ GUEST_SRCS-y :=
|
||||
GUEST_SRCS-y += xc_load_bin.c
|
||||
GUEST_SRCS-y += xc_load_elf.c
|
||||
GUEST_SRCS-y += xg_private.c
|
||||
-#GUEST_SRCS-$(CONFIG_X86) += xc_linux_build.c
|
||||
-#GUEST_SRCS-$(CONFIG_IA64) += xc_linux_build.c
|
||||
+GUEST_SRCS-$(CONFIG_X86) += xc_linux_build.c
|
||||
+GUEST_SRCS-$(CONFIG_IA64) += xc_linux_build.c
|
||||
GUEST_SRCS-$(CONFIG_MIGRATE) += xc_linux_restore.c xc_linux_save.c
|
||||
GUEST_SRCS-$(CONFIG_HVM) += xc_hvm_build.c
|
||||
|
||||
Index: build-32-release304-13087/tools/libxc/xc_linux_build.c
|
||||
===================================================================
|
||||
--- build-32-release304-13087.orig/tools/libxc/xc_linux_build.c
|
||||
+++ build-32-release304-13087/tools/libxc/xc_linux_build.c
|
||||
@@ -1185,7 +1185,7 @@ static int xc_linux_build_internal(int x
|
||||
return -1;
|
||||
}
|
||||
|
||||
-int xc_linux_build_mem(int xc_handle,
|
||||
+int old_xc_linux_build_mem(int xc_handle,
|
||||
uint32_t domid,
|
||||
unsigned int mem_mb,
|
||||
const char *image_buffer,
|
||||
@@ -1254,7 +1254,7 @@ int xc_linux_build_mem(int xc_handle,
|
||||
return sts;
|
||||
}
|
||||
|
||||
-int xc_linux_build(int xc_handle,
|
||||
+int old_xc_linux_build(int xc_handle,
|
||||
uint32_t domid,
|
||||
unsigned int mem_mb,
|
||||
const char *image_name,
|
||||
Index: build-32-release304-13087/tools/libxc/xenguest.h
|
||||
===================================================================
|
||||
--- build-32-release304-13087.orig/tools/libxc/xenguest.h
|
||||
+++ build-32-release304-13087/tools/libxc/xenguest.h
|
||||
@@ -59,6 +59,19 @@ int xc_linux_restore(int xc_handle, int
|
||||
* @parm conole_mfn returned with the mfn of the console page
|
||||
* @return 0 on success, -1 on failure
|
||||
*/
|
||||
+int old_xc_linux_build(int xc_handle,
|
||||
+ uint32_t domid,
|
||||
+ unsigned int mem_mb,
|
||||
+ const char *image_name,
|
||||
+ const char *ramdisk_name,
|
||||
+ const char *cmdline,
|
||||
+ const char *features,
|
||||
+ unsigned long flags,
|
||||
+ unsigned int store_evtchn,
|
||||
+ unsigned long *store_mfn,
|
||||
+ unsigned int console_evtchn,
|
||||
+ unsigned long *console_mfn);
|
||||
+
|
||||
int xc_linux_build(int xc_handle,
|
||||
uint32_t domid,
|
||||
unsigned int mem_mb,
|
||||
@@ -91,6 +104,21 @@ int xc_linux_build(int xc_handle,
|
||||
* @parm conole_mfn returned with the mfn of the console page
|
||||
* @return 0 on success, -1 on failure
|
||||
*/
|
||||
+int old_xc_linux_build_mem(int xc_handle,
|
||||
+ uint32_t domid,
|
||||
+ unsigned int mem_mb,
|
||||
+ const char *image_buffer,
|
||||
+ unsigned long image_size,
|
||||
+ const char *initrd_buffer,
|
||||
+ unsigned long initrd_size,
|
||||
+ const char *cmdline,
|
||||
+ const char *features,
|
||||
+ unsigned long flags,
|
||||
+ unsigned int store_evtchn,
|
||||
+ unsigned long *store_mfn,
|
||||
+ unsigned int console_evtchn,
|
||||
+ unsigned long *console_mfn);
|
||||
+
|
||||
int xc_linux_build_mem(int xc_handle,
|
||||
uint32_t domid,
|
||||
unsigned int mem_mb,
|
||||
Index: build-32-release304-13087/tools/python/xen/lowlevel/xc/xc.c
|
||||
===================================================================
|
||||
--- build-32-release304-13087.orig/tools/python/xen/lowlevel/xc/xc.c
|
||||
+++ build-32-release304-13087/tools/python/xen/lowlevel/xc/xc.c
|
||||
@@ -349,6 +349,43 @@ static PyObject *pyxc_vcpu_getinfo(XcObj
|
||||
return info_dict;
|
||||
}
|
||||
|
||||
+static PyObject *pyxc_old_linux_build(XcObject *self,
|
||||
+ PyObject *args,
|
||||
+ PyObject *kwds)
|
||||
+{
|
||||
+ uint32_t dom;
|
||||
+ char *image, *ramdisk = NULL, *cmdline = "", *features = NULL;
|
||||
+ int flags = 0;
|
||||
+ int store_evtchn, console_evtchn;
|
||||
+ unsigned int mem_mb;
|
||||
+ unsigned long store_mfn = 0;
|
||||
+ unsigned long console_mfn = 0;
|
||||
+
|
||||
+ static char *kwd_list[] = { "domid", "store_evtchn", "memsize",
|
||||
+ "console_evtchn", "image",
|
||||
+ /* optional */
|
||||
+ "ramdisk", "cmdline", "flags",
|
||||
+ "features", NULL };
|
||||
+
|
||||
+ if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iiiis|ssis", kwd_list,
|
||||
+ &dom, &store_evtchn, &mem_mb,
|
||||
+ &console_evtchn, &image,
|
||||
+ /* optional */
|
||||
+ &ramdisk, &cmdline, &flags,
|
||||
+ &features) )
|
||||
+ return NULL;
|
||||
+
|
||||
+ if ( old_xc_linux_build(self->xc_handle, dom, mem_mb, image,
|
||||
+ ramdisk, cmdline, features, flags,
|
||||
+ store_evtchn, &store_mfn,
|
||||
+ console_evtchn, &console_mfn) != 0 ) {
|
||||
+ return pyxc_error_to_exception();
|
||||
+ }
|
||||
+ return Py_BuildValue("{s:i,s:i}",
|
||||
+ "store_mfn", store_mfn,
|
||||
+ "console_mfn", console_mfn);
|
||||
+}
|
||||
+
|
||||
static PyObject *pyxc_linux_build(XcObject *self,
|
||||
PyObject *args,
|
||||
PyObject *kwds)
|
||||
@@ -1093,7 +1130,18 @@ static PyMethodDef pyxc_methods[] = {
|
||||
" cpumap [int]: Bitmap of CPUs this VCPU can run on\n"
|
||||
" cpu [int]: CPU that this VCPU is currently bound to\n" },
|
||||
|
||||
- { "linux_build",
|
||||
+ { "old_linux_build",
|
||||
+ (PyCFunction)pyxc_old_linux_build,
|
||||
+ METH_VARARGS | METH_KEYWORDS, "\n"
|
||||
+ "Build a new Linux guest OS.\n"
|
||||
+ " dom [int]: Identifier of domain to build into.\n"
|
||||
+ " image [str]: Name of kernel image file. May be gzipped.\n"
|
||||
+ " ramdisk [str, n/a]: Name of ramdisk file, if any.\n"
|
||||
+ " cmdline [str, n/a]: Kernel parameters, if any.\n\n"
|
||||
+ " vcpus [int, 1]: Number of Virtual CPUS in domain.\n\n"
|
||||
+ "Returns: [int] 0 on success; -1 on error.\n" },
|
||||
+
|
||||
+ { "linux_build",
|
||||
(PyCFunction)pyxc_linux_build,
|
||||
METH_VARARGS | METH_KEYWORDS, "\n"
|
||||
"Build a new Linux guest OS.\n"
|
||||
Index: build-32-release304-13087/tools/python/xen/xend/image.py
|
||||
===================================================================
|
||||
--- build-32-release304-13087.orig/tools/python/xen/xend/image.py
|
||||
+++ build-32-release304-13087/tools/python/xen/xend/image.py
|
||||
@@ -181,6 +181,35 @@ class ImageHandler:
|
||||
pass
|
||||
|
||||
|
||||
+class OldLinuxImageHandler(ImageHandler):
|
||||
+
|
||||
+ ostype = "linux"
|
||||
+
|
||||
+ def buildDomain(self):
|
||||
+ store_evtchn = self.vm.getStorePort()
|
||||
+ console_evtchn = self.vm.getConsolePort()
|
||||
+
|
||||
+ mem_mb = self.getRequiredInitialReservation() / 1024
|
||||
+
|
||||
+ log.debug("domid = %d", self.vm.getDomid())
|
||||
+ log.debug("memsize = %d", mem_mb)
|
||||
+ log.debug("image = %s", self.kernel)
|
||||
+ log.debug("store_evtchn = %d", store_evtchn)
|
||||
+ log.debug("console_evtchn = %d", console_evtchn)
|
||||
+ log.debug("cmdline = %s", self.cmdline)
|
||||
+ log.debug("ramdisk = %s", self.ramdisk)
|
||||
+ log.debug("vcpus = %d", self.vm.getVCpuCount())
|
||||
+ log.debug("features = %s", self.vm.getFeatures())
|
||||
+
|
||||
+ return xc.old_linux_build(domid = self.vm.getDomid(),
|
||||
+ memsize = mem_mb,
|
||||
+ image = self.kernel,
|
||||
+ store_evtchn = store_evtchn,
|
||||
+ console_evtchn = console_evtchn,
|
||||
+ cmdline = self.cmdline,
|
||||
+ ramdisk = self.ramdisk,
|
||||
+ features = self.vm.getFeatures())
|
||||
+
|
||||
class LinuxImageHandler(ImageHandler):
|
||||
|
||||
ostype = "linux"
|
||||
@@ -625,6 +654,15 @@ class X86_Linux_ImageHandler(LinuxImageH
|
||||
xc.domain_set_memmap_limit(self.vm.getDomid(), mem_kb)
|
||||
return LinuxImageHandler.buildDomain(self)
|
||||
|
||||
+class X86_OldLinux_ImageHandler(OldLinuxImageHandler):
|
||||
+
|
||||
+ def buildDomain(self):
|
||||
+ # set physical mapping limit
|
||||
+ # add an 8MB slack to balance backend allocations.
|
||||
+ mem_kb = self.getRequiredInitialReservation() + (8 * 1024)
|
||||
+ xc.domain_set_memmap_limit(self.vm.getDomid(), mem_kb)
|
||||
+ return OldLinuxImageHandler.buildDomain(self)
|
||||
+
|
||||
_handlers = {
|
||||
"powerpc": {
|
||||
"linux": PPC_LinuxImageHandler,
|
||||
@@ -632,10 +670,12 @@ _handlers = {
|
||||
},
|
||||
"ia64": {
|
||||
"linux": LinuxImageHandler,
|
||||
+ "old": OldLinuxImageHandler,
|
||||
"hvm": IA64_HVM_ImageHandler,
|
||||
},
|
||||
"x86": {
|
||||
"linux": X86_Linux_ImageHandler,
|
||||
+ "old": X86_OldLinux_ImageHandler,
|
||||
"hvm": X86_HVM_ImageHandler,
|
||||
},
|
||||
}
|
3066
tools-domain-builder-core.diff
Normal file
3066
tools-domain-builder-core.diff
Normal file
File diff suppressed because it is too large
Load Diff
165
tools-domain-builder-header-libxc.diff
Normal file
165
tools-domain-builder-header-libxc.diff
Normal file
@ -0,0 +1,165 @@
|
||||
libxc header fixups.
|
||||
|
||||
Make some arch-specific #defines for page table handling
|
||||
available unconditionally, add a suffix to avoid name clashes.
|
||||
|
||||
The versions without suffix are defined depending on the
|
||||
architecture like they used to, so code using them continues
|
||||
to work.
|
||||
|
||||
Signed-off-by: Gerd Hoffmann <kraxel@suse.de>
|
||||
---
|
||||
tools/libxc/xg_private.h | 114 +++++++++++++++++++++++++++--------------------
|
||||
1 file changed, 67 insertions(+), 47 deletions(-)
|
||||
|
||||
Index: build-32-unstable-11822/tools/libxc/xg_private.h
|
||||
===================================================================
|
||||
--- build-32-unstable-11822.orig/tools/libxc/xg_private.h
|
||||
+++ build-32-unstable-11822/tools/libxc/xg_private.h
|
||||
@@ -46,37 +46,41 @@ unsigned long csum_page (void * page);
|
||||
#define _PAGE_PSE 0x080
|
||||
#define _PAGE_GLOBAL 0x100
|
||||
|
||||
-#define L1_PAGETABLE_SHIFT_PAE 12
|
||||
-#define L2_PAGETABLE_SHIFT_PAE 21
|
||||
-#define L3_PAGETABLE_SHIFT_PAE 30
|
||||
-
|
||||
-#define L2_PAGETABLE_SHIFT_I386 22
|
||||
-
|
||||
-#if defined(__i386__)
|
||||
-#define L1_PAGETABLE_SHIFT 12
|
||||
-#define L2_PAGETABLE_SHIFT 22
|
||||
-#elif defined(__x86_64__)
|
||||
-#define L1_PAGETABLE_SHIFT 12
|
||||
-#define L2_PAGETABLE_SHIFT 21
|
||||
-#define L3_PAGETABLE_SHIFT 30
|
||||
-#define L4_PAGETABLE_SHIFT 39
|
||||
-#endif
|
||||
+#define L1_PAGETABLE_SHIFT_I386 12
|
||||
+#define L2_PAGETABLE_SHIFT_I386 22
|
||||
+#define L1_PAGETABLE_ENTRIES_I386 1024
|
||||
+#define L2_PAGETABLE_ENTRIES_I386 1024
|
||||
|
||||
-#define L1_PAGETABLE_ENTRIES_PAE 512
|
||||
-#define L2_PAGETABLE_ENTRIES_PAE 512
|
||||
-#define L3_PAGETABLE_ENTRIES_PAE 4
|
||||
+#define L1_PAGETABLE_SHIFT_PAE 12
|
||||
+#define L2_PAGETABLE_SHIFT_PAE 21
|
||||
+#define L3_PAGETABLE_SHIFT_PAE 30
|
||||
+#define L1_PAGETABLE_ENTRIES_PAE 512
|
||||
+#define L2_PAGETABLE_ENTRIES_PAE 512
|
||||
+#define L3_PAGETABLE_ENTRIES_PAE 4
|
||||
|
||||
-#define L1_PAGETABLE_ENTRIES_I386 1024
|
||||
-#define L2_PAGETABLE_ENTRIES_I386 1024
|
||||
+#define L1_PAGETABLE_SHIFT_X86_64 12
|
||||
+#define L2_PAGETABLE_SHIFT_X86_64 21
|
||||
+#define L3_PAGETABLE_SHIFT_X86_64 30
|
||||
+#define L4_PAGETABLE_SHIFT_X86_64 39
|
||||
+#define L1_PAGETABLE_ENTRIES_X86_64 512
|
||||
+#define L2_PAGETABLE_ENTRIES_X86_64 512
|
||||
+#define L3_PAGETABLE_ENTRIES_X86_64 512
|
||||
+#define L4_PAGETABLE_ENTRIES_X86_64 512
|
||||
|
||||
#if defined(__i386__)
|
||||
-#define L1_PAGETABLE_ENTRIES 1024
|
||||
-#define L2_PAGETABLE_ENTRIES 1024
|
||||
+#define L1_PAGETABLE_SHIFT L1_PAGETABLE_SHIFT_I386
|
||||
+#define L2_PAGETABLE_SHIFT L2_PAGETABLE_SHIFT_I386
|
||||
+#define L1_PAGETABLE_ENTRIES L1_PAGETABLE_ENTRIES_I386
|
||||
+#define L2_PAGETABLE_ENTRIES L2_PAGETABLE_ENTRIES_I386
|
||||
#elif defined(__x86_64__)
|
||||
-#define L1_PAGETABLE_ENTRIES 512
|
||||
-#define L2_PAGETABLE_ENTRIES 512
|
||||
-#define L3_PAGETABLE_ENTRIES 512
|
||||
-#define L4_PAGETABLE_ENTRIES 512
|
||||
+#define L1_PAGETABLE_SHIFT L1_PAGETABLE_SHIFT_X86_64
|
||||
+#define L2_PAGETABLE_SHIFT L2_PAGETABLE_SHIFT_X86_64
|
||||
+#define L3_PAGETABLE_SHIFT L3_PAGETABLE_SHIFT_X86_64
|
||||
+#define L4_PAGETABLE_SHIFT L4_PAGETABLE_SHIFT_X86_64
|
||||
+#define L1_PAGETABLE_ENTRIES L1_PAGETABLE_ENTRIES_X86_64
|
||||
+#define L2_PAGETABLE_ENTRIES L2_PAGETABLE_ENTRIES_X86_64
|
||||
+#define L3_PAGETABLE_ENTRIES L3_PAGETABLE_ENTRIES_X86_64
|
||||
+#define L4_PAGETABLE_ENTRIES L4_PAGETABLE_ENTRIES_X86_64
|
||||
#endif
|
||||
|
||||
typedef uint32_t l1_pgentry_32_t;
|
||||
@@ -84,13 +88,23 @@ typedef uint32_t l2_pgentry_32_t;
|
||||
typedef uint64_t l1_pgentry_64_t;
|
||||
typedef uint64_t l2_pgentry_64_t;
|
||||
typedef uint64_t l3_pgentry_64_t;
|
||||
-typedef unsigned long l1_pgentry_t;
|
||||
-typedef unsigned long l2_pgentry_t;
|
||||
-#if defined(__x86_64__)
|
||||
-typedef unsigned long l3_pgentry_t;
|
||||
-typedef unsigned long l4_pgentry_t;
|
||||
+typedef uint64_t l4_pgentry_64_t;
|
||||
+
|
||||
+#if defined(__i386__)
|
||||
+typedef l1_pgentry_32_t l1_pgentry_t;
|
||||
+typedef l2_pgentry_32_t l2_pgentry_t;
|
||||
+#elif defined(__x86_64__)
|
||||
+typedef l1_pgentry_64_t l1_pgentry_t;
|
||||
+typedef l2_pgentry_64_t l2_pgentry_t;
|
||||
+typedef l3_pgentry_64_t l3_pgentry_t;
|
||||
+typedef l4_pgentry_64_t l4_pgentry_t;
|
||||
#endif
|
||||
|
||||
+#define l1_table_offset_i386(_a) \
|
||||
+ (((_a) >> L1_PAGETABLE_SHIFT_I386) & (L1_PAGETABLE_ENTRIES_I386 - 1))
|
||||
+#define l2_table_offset_i386(_a) \
|
||||
+ (((_a) >> L2_PAGETABLE_SHIFT_I386) & (L2_PAGETABLE_ENTRIES_I386 - 1))
|
||||
+
|
||||
#define l1_table_offset_pae(_a) \
|
||||
(((_a) >> L1_PAGETABLE_SHIFT_PAE) & (L1_PAGETABLE_ENTRIES_PAE - 1))
|
||||
#define l2_table_offset_pae(_a) \
|
||||
@@ -98,27 +112,33 @@ typedef unsigned long l4_pgentry_t;
|
||||
#define l3_table_offset_pae(_a) \
|
||||
(((_a) >> L3_PAGETABLE_SHIFT_PAE) & (L3_PAGETABLE_ENTRIES_PAE - 1))
|
||||
|
||||
-#define l1_table_offset_i386(_a) \
|
||||
- (((_a) >> L1_PAGETABLE_SHIFT) & (L1_PAGETABLE_ENTRIES_I386 - 1))
|
||||
-#define l2_table_offset_i386(_a) \
|
||||
- (((_a) >> L2_PAGETABLE_SHIFT_I386) & (L2_PAGETABLE_ENTRIES_I386 - 1))
|
||||
+#define l1_table_offset_x86_64(_a) \
|
||||
+ (((_a) >> L1_PAGETABLE_SHIFT_X86_64) & (L1_PAGETABLE_ENTRIES_X86_64 - 1))
|
||||
+#define l2_table_offset_x86_64(_a) \
|
||||
+ (((_a) >> L2_PAGETABLE_SHIFT_X86_64) & (L2_PAGETABLE_ENTRIES_X86_64 - 1))
|
||||
+#define l3_table_offset_x86_64(_a) \
|
||||
+ (((_a) >> L3_PAGETABLE_SHIFT_X86_64) & (L3_PAGETABLE_ENTRIES_X86_64 - 1))
|
||||
+#define l4_table_offset_x86_64(_a) \
|
||||
+ (((_a) >> L4_PAGETABLE_SHIFT_X86_64) & (L4_PAGETABLE_ENTRIES_X86_64 - 1))
|
||||
|
||||
#if defined(__i386__)
|
||||
-#define l1_table_offset(_a) \
|
||||
- (((_a) >> L1_PAGETABLE_SHIFT) & (L1_PAGETABLE_ENTRIES - 1))
|
||||
-#define l2_table_offset(_a) \
|
||||
- ((_a) >> L2_PAGETABLE_SHIFT)
|
||||
+#define l1_table_offset(_a) l1_table_offset_i386(_a)
|
||||
+#define l2_table_offset(_a) l2_table_offset_i386(_a)
|
||||
#elif defined(__x86_64__)
|
||||
-#define l1_table_offset(_a) \
|
||||
- (((_a) >> L1_PAGETABLE_SHIFT) & (L1_PAGETABLE_ENTRIES - 1))
|
||||
-#define l2_table_offset(_a) \
|
||||
- (((_a) >> L2_PAGETABLE_SHIFT) & (L2_PAGETABLE_ENTRIES - 1))
|
||||
-#define l3_table_offset(_a) \
|
||||
- (((_a) >> L3_PAGETABLE_SHIFT) & (L3_PAGETABLE_ENTRIES - 1))
|
||||
-#define l4_table_offset(_a) \
|
||||
- (((_a) >> L4_PAGETABLE_SHIFT) & (L4_PAGETABLE_ENTRIES - 1))
|
||||
+#define l1_table_offset(_a) l1_table_offset_x86_64(_a)
|
||||
+#define l2_table_offset(_a) l2_table_offset_x86_64(_a)
|
||||
+#define l3_table_offset(_a) l3_table_offset_x86_64(_a)
|
||||
+#define l4_table_offset(_a) l4_table_offset_x86_64(_a)
|
||||
#endif
|
||||
|
||||
+#define PAGE_SHIFT_X86 12
|
||||
+#define PAGE_SIZE_X86 (1UL << PAGE_SHIFT_X86)
|
||||
+#define PAGE_MASK_X86 (~(PAGE_SIZE_X86-1))
|
||||
+
|
||||
+#define PAGE_SHIFT_IA64 14
|
||||
+#define PAGE_SIZE_IA64 (1UL << PAGE_SHIFT_IA64)
|
||||
+#define PAGE_MASK_IA64 (~(PAGE_SIZE_IA64-1))
|
||||
+
|
||||
struct domain_setup_info
|
||||
{
|
||||
uint64_t v_start;
|
164
tools-domain-builder-linux.diff
Normal file
164
tools-domain-builder-linux.diff
Normal file
@ -0,0 +1,164 @@
|
||||
libxc domain builder rewrite, linux builder
|
||||
|
||||
use new domain builder for the linux (aka generic elf) loader.
|
||||
|
||||
Signed-off-by: Gerd Hoffmann <kraxel@suse.de>
|
||||
---
|
||||
tools/libxc/Makefile | 7 +-
|
||||
tools/libxc/xc_dom_compat_linux.c | 124 ++++++++++++++++++++++++++++++++++++++
|
||||
2 files changed, 129 insertions(+), 2 deletions(-)
|
||||
|
||||
Index: build-32-release304-12901/tools/libxc/xc_dom_compat_linux.c
|
||||
===================================================================
|
||||
--- /dev/null
|
||||
+++ build-32-release304-12901/tools/libxc/xc_dom_compat_linux.c
|
||||
@@ -0,0 +1,124 @@
|
||||
+/*
|
||||
+ * Xen domain builder -- compatibility code.
|
||||
+ *
|
||||
+ * Replacements for xc_linux_build & friends,
|
||||
+ * as example code and to make the new builder
|
||||
+ * usable as drop-in replacement.
|
||||
+ *
|
||||
+ * This code is licenced under the GPL.
|
||||
+ * written 2006 by Gerd Hoffmann <kraxel@suse.de>.
|
||||
+ *
|
||||
+ */
|
||||
+#include <stdio.h>
|
||||
+#include <stdlib.h>
|
||||
+#include <string.h>
|
||||
+#include <inttypes.h>
|
||||
+#include <zlib.h>
|
||||
+
|
||||
+#include "xenctrl.h"
|
||||
+#include "xg_private.h"
|
||||
+#include "xc_dom.h"
|
||||
+
|
||||
+/* ------------------------------------------------------------------------ */
|
||||
+
|
||||
+static int xc_linux_build_internal(struct xc_dom_image *dom,
|
||||
+ int xc_handle, uint32_t domid,
|
||||
+ unsigned int mem_mb,
|
||||
+ unsigned long flags,
|
||||
+ unsigned int store_evtchn,
|
||||
+ unsigned long *store_mfn,
|
||||
+ unsigned int console_evtchn,
|
||||
+ unsigned long *console_mfn)
|
||||
+{
|
||||
+ int rc;
|
||||
+
|
||||
+ if (0 != (rc = xc_dom_boot_xen_init(dom, xc_handle, domid)))
|
||||
+ goto out;
|
||||
+ if (0 != (rc = xc_dom_parse_image(dom)))
|
||||
+ goto out;
|
||||
+ if (0 != (rc = xc_dom_mem_init(dom, mem_mb)))
|
||||
+ goto out;
|
||||
+ if (0 != (rc = xc_dom_boot_mem_init(dom)))
|
||||
+ goto out;
|
||||
+ if (0 != (rc = xc_dom_build_image(dom)))
|
||||
+ goto out;
|
||||
+
|
||||
+ dom->flags = flags;
|
||||
+ dom->console_evtchn = console_evtchn;
|
||||
+ dom->xenstore_evtchn = store_evtchn;
|
||||
+ rc = xc_dom_boot_image(dom);
|
||||
+ if (0 != rc)
|
||||
+ goto out;
|
||||
+
|
||||
+ *console_mfn = xc_dom_p2m_host(dom, dom->console_pfn);
|
||||
+ *store_mfn = xc_dom_p2m_host(dom, dom->xenstore_pfn);
|
||||
+
|
||||
+ out:
|
||||
+ return rc;
|
||||
+}
|
||||
+
|
||||
+int xc_linux_build_mem(int xc_handle, uint32_t domid,
|
||||
+ unsigned int mem_mb,
|
||||
+ const char *image_buffer,
|
||||
+ unsigned long image_size,
|
||||
+ const char *initrd,
|
||||
+ unsigned long initrd_len,
|
||||
+ const char *cmdline,
|
||||
+ const char *features,
|
||||
+ unsigned long flags,
|
||||
+ unsigned int store_evtchn,
|
||||
+ unsigned long *store_mfn,
|
||||
+ unsigned int console_evtchn, unsigned long *console_mfn)
|
||||
+{
|
||||
+ struct xc_dom_image *dom;
|
||||
+ int rc;
|
||||
+
|
||||
+ xc_dom_loginit();
|
||||
+ dom = xc_dom_allocate(cmdline, features);
|
||||
+ if (0 != (rc = xc_dom_kernel_mem(dom, image_buffer, image_size)))
|
||||
+ goto out;
|
||||
+ if (initrd)
|
||||
+ if (0 != (rc = xc_dom_ramdisk_mem(dom, initrd, initrd_len)))
|
||||
+ goto out;
|
||||
+
|
||||
+ rc = xc_linux_build_internal(dom, xc_handle, domid,
|
||||
+ mem_mb, flags,
|
||||
+ store_evtchn, store_mfn,
|
||||
+ console_evtchn, console_mfn);
|
||||
+
|
||||
+ out:
|
||||
+ xc_dom_release(dom);
|
||||
+ return rc;
|
||||
+}
|
||||
+
|
||||
+int xc_linux_build(int xc_handle, uint32_t domid,
|
||||
+ unsigned int mem_mb,
|
||||
+ const char *image_name,
|
||||
+ const char *initrd_name,
|
||||
+ const char *cmdline,
|
||||
+ const char *features,
|
||||
+ unsigned long flags,
|
||||
+ unsigned int store_evtchn,
|
||||
+ unsigned long *store_mfn,
|
||||
+ unsigned int console_evtchn, unsigned long *console_mfn)
|
||||
+{
|
||||
+ struct xc_dom_image *dom;
|
||||
+ int rc;
|
||||
+
|
||||
+ xc_dom_loginit();
|
||||
+ dom = xc_dom_allocate(cmdline, features);
|
||||
+ if (0 != (rc = xc_dom_kernel_file(dom, image_name)))
|
||||
+ goto out;
|
||||
+ if (initrd_name && strlen(initrd_name))
|
||||
+ if (0 != (rc = xc_dom_ramdisk_file(dom, initrd_name)))
|
||||
+ goto out;
|
||||
+
|
||||
+ rc = xc_linux_build_internal(dom, xc_handle, domid,
|
||||
+ mem_mb, flags,
|
||||
+ store_evtchn, store_mfn,
|
||||
+ console_evtchn, console_mfn);
|
||||
+
|
||||
+ out:
|
||||
+ xc_dom_release(dom);
|
||||
+ return rc;
|
||||
+}
|
||||
Index: build-32-release304-12901/tools/libxc/Makefile
|
||||
===================================================================
|
||||
--- build-32-release304-12901.orig/tools/libxc/Makefile
|
||||
+++ build-32-release304-12901/tools/libxc/Makefile
|
||||
@@ -24,8 +24,8 @@ GUEST_SRCS-y :=
|
||||
GUEST_SRCS-y += xc_load_bin.c
|
||||
GUEST_SRCS-y += xc_load_elf.c
|
||||
GUEST_SRCS-y += xg_private.c
|
||||
-GUEST_SRCS-$(CONFIG_X86) += xc_linux_build.c
|
||||
-GUEST_SRCS-$(CONFIG_IA64) += xc_linux_build.c
|
||||
+#GUEST_SRCS-$(CONFIG_X86) += xc_linux_build.c
|
||||
+#GUEST_SRCS-$(CONFIG_IA64) += xc_linux_build.c
|
||||
GUEST_SRCS-$(CONFIG_MIGRATE) += xc_linux_restore.c xc_linux_save.c
|
||||
GUEST_SRCS-$(CONFIG_HVM) += xc_hvm_build.c
|
||||
|
||||
@@ -58,6 +58,9 @@ GUEST_SRCS-y += xc_dom_x86.c
|
||||
GUEST_SRCS-y += xc_dom_ia64.c
|
||||
endif
|
||||
|
||||
+GUEST_SRCS-$(CONFIG_X86) += xc_dom_compat_linux.c
|
||||
+GUEST_SRCS-$(CONFIG_IA64) += xc_dom_compat_linux.c
|
||||
+
|
||||
-include $(XEN_TARGET_ARCH)/Makefile
|
||||
|
||||
CFLAGS += -Werror -Wmissing-prototypes
|
2171
tools-kboot.diff
Normal file
2171
tools-kboot.diff
Normal file
File diff suppressed because it is too large
Load Diff
46
tools-readnotes-gunzip.diff
Normal file
46
tools-readnotes-gunzip.diff
Normal file
@ -0,0 +1,46 @@
|
||||
Support transparant gunzipping in the readnotes utility.
|
||||
|
||||
Signed-off-by: Gerd Hoffmann <kraxel@suse.de>
|
||||
---
|
||||
tools/xcutils/readnotes.c | 14 ++++++++++++--
|
||||
1 file changed, 12 insertions(+), 2 deletions(-)
|
||||
|
||||
Index: build-32-release304-13138/tools/xcutils/readnotes.c
|
||||
===================================================================
|
||||
--- build-32-release304-13138.orig/tools/xcutils/readnotes.c
|
||||
+++ build-32-release304-13138/tools/xcutils/readnotes.c
|
||||
@@ -11,6 +11,7 @@
|
||||
#include <sys/mman.h>
|
||||
|
||||
#include <xg_private.h>
|
||||
+#include <xc_dom.h> /* gunzip bits */
|
||||
|
||||
#include <xen/libelf.h>
|
||||
|
||||
@@ -33,8 +34,8 @@ static void print_numeric_note(const cha
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
const char *f;
|
||||
- int fd,h,size,count;
|
||||
- void *image;
|
||||
+ int fd,h,size,usize,count;
|
||||
+ void *image,*tmp;
|
||||
struct stat st;
|
||||
struct elf_binary elf;
|
||||
const elf_shdr *shdr;
|
||||
@@ -68,6 +69,15 @@ int main(int argc, char **argv)
|
||||
}
|
||||
size = st.st_size;
|
||||
|
||||
+ usize = xc_dom_check_gzip(image, st.st_size);
|
||||
+ if (usize)
|
||||
+ {
|
||||
+ tmp = malloc(usize);
|
||||
+ xc_dom_do_gunzip(image, st.st_size, tmp, usize);
|
||||
+ image = tmp;
|
||||
+ size = usize;
|
||||
+ }
|
||||
+
|
||||
if (0 != elf_init(&elf, image, size))
|
||||
{
|
||||
fprintf(stderr, "File %s is not an ELF image\n", f);
|
5135
tools-xc_kexec.diff
Normal file
5135
tools-xc_kexec.diff
Normal file
File diff suppressed because it is too large
Load Diff
44
vgacon-50-lines.patch
Normal file
44
vgacon-50-lines.patch
Normal file
@ -0,0 +1,44 @@
|
||||
Index: xen-3.0.4-testing/xen/drivers/video/vga.c
|
||||
===================================================================
|
||||
--- xen-3.0.4-testing.orig/xen/drivers/video/vga.c
|
||||
+++ xen-3.0.4-testing/xen/drivers/video/vga.c
|
||||
@@ -557,7 +557,7 @@ static int vga_load_font(const struct fo
|
||||
|
||||
static int vgacon_enabled = 0;
|
||||
static int vgacon_keep = 0;
|
||||
-static int vgacon_lines = 25;
|
||||
+static int vgacon_lines = 50;
|
||||
static const struct font_desc *font;
|
||||
|
||||
static int xpos, ypos;
|
||||
@@ -609,6 +609,8 @@ void vga_init(void)
|
||||
vgacon_keep = 1;
|
||||
else if ( strncmp(p, "text-80x", 8) == 0 )
|
||||
vgacon_lines = simple_strtoul(p + 8, NULL, 10);
|
||||
+ else if ( strncmp(p, "text", 4) == 0 && p[4] != '-' )
|
||||
+ vgacon_lines = 0;
|
||||
}
|
||||
|
||||
video = setup_vga();
|
||||
@@ -625,17 +627,18 @@ void vga_init(void)
|
||||
case 34:
|
||||
font = &font_vga_8x14;
|
||||
break;
|
||||
+ default:
|
||||
+ vgacon_lines = 50;
|
||||
case 43:
|
||||
case 50:
|
||||
case 60:
|
||||
font = &font_vga_8x8;
|
||||
break;
|
||||
- default:
|
||||
- vgacon_lines = 25;
|
||||
+ case 0:
|
||||
break;
|
||||
}
|
||||
|
||||
- if ( (font != NULL) && (vga_load_font(font, vgacon_lines) < 0) )
|
||||
+ if ( (font == NULL) || (vga_load_font(font, vgacon_lines) < 0) )
|
||||
{
|
||||
vgacon_lines = 25;
|
||||
font = NULL;
|
113
vgacon-keep.patch
Normal file
113
vgacon-keep.patch
Normal file
@ -0,0 +1,113 @@
|
||||
Index: 2007-01-08/xen/drivers/video/vga.c
|
||||
===================================================================
|
||||
--- 2007-01-08.orig/xen/drivers/video/vga.c 2007-01-11 17:41:46.000000000 +0100
|
||||
+++ 2007-01-08/xen/drivers/video/vga.c 2007-01-11 17:42:35.000000000 +0100
|
||||
@@ -556,7 +556,6 @@ static int vga_load_font(const struct fo
|
||||
*/
|
||||
|
||||
static int vgacon_enabled = 0;
|
||||
-static int vgacon_keep = 0;
|
||||
static int vgacon_lines = 50;
|
||||
static const struct font_desc *font;
|
||||
|
||||
@@ -576,13 +575,16 @@ string_param("vga", opt_vga);
|
||||
void vga_init(void)
|
||||
{
|
||||
char *p;
|
||||
+ int keep = 0;
|
||||
|
||||
for ( p = opt_vga; p != NULL; p = strchr(p, ',') )
|
||||
{
|
||||
if ( *p == ',' )
|
||||
p++;
|
||||
if ( strncmp(p, "keep", 4) == 0 )
|
||||
- vgacon_keep = 1;
|
||||
+ keep = 1;
|
||||
+ else if ( strncmp(p, "yield", 5) == 0 )
|
||||
+ keep = -1;
|
||||
else if ( strncmp(p, "text-80x", 8) == 0 )
|
||||
vgacon_lines = simple_strtoul(p + 8, NULL, 10);
|
||||
else if ( strncmp(p, "text", 4) == 0 && p[4] != '-' )
|
||||
@@ -627,21 +629,48 @@ void vga_init(void)
|
||||
/* Disable cursor. */
|
||||
vga_wcrt(vgabase, VGA_CRTC_CURSOR_START, 0x20);
|
||||
|
||||
- vgacon_enabled = 1;
|
||||
+ vgacon_enabled = 3 + keep;
|
||||
}
|
||||
|
||||
void vga_endboot(void)
|
||||
{
|
||||
+ static const char *const str[] =
|
||||
+ {
|
||||
+ "relinquishing",
|
||||
+ "auto-sensing",
|
||||
+ "keeping"
|
||||
+ };
|
||||
+
|
||||
if ( !vgacon_enabled )
|
||||
return;
|
||||
|
||||
- if ( !vgacon_keep )
|
||||
- vgacon_enabled = 0;
|
||||
+ vgacon_enabled -= 2;
|
||||
+ BUG_ON(vgacon_enabled < 0 || vgacon_enabled > 2);
|
||||
|
||||
- printk("Xen is %s VGA console.\n",
|
||||
- vgacon_keep ? "keeping" : "relinquishing");
|
||||
+ printk("Xen is %s VGA console.\n", str[vgacon_enabled]);
|
||||
}
|
||||
|
||||
+static int gfx_vga(void)
|
||||
+{
|
||||
+ unsigned char idx, data;
|
||||
+
|
||||
+ idx = vga_r(vgabase, VGA_GFX_I);
|
||||
+ data = vga_rgfx(vgabase, VGA_GFX_MISC);
|
||||
+ vga_w(vgabase, VGA_GFX_I, idx);
|
||||
+
|
||||
+ if ( data & 0x01 )
|
||||
+ return 1;
|
||||
+
|
||||
+ /* Unfortunately many cards don't reflect their mode in the GDC
|
||||
+ * miscellaneous register, bit 0 (and even fewer reflect it in the
|
||||
+ * ATC mode control register, bit 0). Therefore we further check
|
||||
+ * horizontal display width against our original setting. */
|
||||
+ idx = vga_r(vgabase, VGA_CRT_IC);
|
||||
+ data = vga_rcrt(vgabase, VGA_CRTC_H_DISP);
|
||||
+ vga_w(vgabase, VGA_CRT_IC, idx);
|
||||
+
|
||||
+ return data != COLUMNS - 1;
|
||||
+}
|
||||
|
||||
static void put_newline(void)
|
||||
{
|
||||
@@ -659,14 +688,25 @@ static void put_newline(void)
|
||||
|
||||
void vga_putchar(int c)
|
||||
{
|
||||
- if ( !vgacon_enabled )
|
||||
+ static int vga_in_gfx = -1;
|
||||
+
|
||||
+ switch ( vgacon_enabled )
|
||||
+ {
|
||||
+ case 0:
|
||||
return;
|
||||
+ case 1:
|
||||
+ if ( vga_in_gfx < 0 )
|
||||
+ vga_in_gfx = gfx_vga();
|
||||
+ break;
|
||||
+ }
|
||||
|
||||
if ( c == '\n' )
|
||||
{
|
||||
- put_newline();
|
||||
+ if ( vga_in_gfx <= 0 )
|
||||
+ put_newline();
|
||||
+ vga_in_gfx = -1;
|
||||
}
|
||||
- else
|
||||
+ else if ( vga_in_gfx <= 0 )
|
||||
{
|
||||
if ( xpos >= COLUMNS )
|
||||
put_newline();
|
89
x86-extra-trap-info.patch
Normal file
89
x86-extra-trap-info.patch
Normal file
@ -0,0 +1,89 @@
|
||||
Index: 2006-12-05/xen/arch/x86/x86_32/entry.S
|
||||
===================================================================
|
||||
--- 2006-12-05.orig/xen/arch/x86/x86_32/entry.S 2006-12-01 10:44:36.000000000 +0100
|
||||
+++ 2006-12-05/xen/arch/x86/x86_32/entry.S 2006-12-08 14:24:54.000000000 +0100
|
||||
@@ -382,21 +382,33 @@ nvm86_3:/* Rewrite our stack frame and r
|
||||
movb $0,TRAPBOUNCE_flags(%edx)
|
||||
ret
|
||||
.section __ex_table,"a"
|
||||
- .long FLT6,domain_crash_synchronous , FLT7,domain_crash_synchronous
|
||||
- .long FLT8,domain_crash_synchronous , FLT9,domain_crash_synchronous
|
||||
- .long FLT10,domain_crash_synchronous , FLT11,domain_crash_synchronous
|
||||
- .long FLT12,domain_crash_synchronous , FLT13,domain_crash_synchronous
|
||||
- .long FLT14,domain_crash_synchronous , FLT15,domain_crash_synchronous
|
||||
- .long FLT16,domain_crash_synchronous , FLT17,domain_crash_synchronous
|
||||
- .long FLT18,domain_crash_synchronous , FLT19,domain_crash_synchronous
|
||||
- .long FLT20,domain_crash_synchronous , FLT21,domain_crash_synchronous
|
||||
- .long FLT22,domain_crash_synchronous , FLT23,domain_crash_synchronous
|
||||
- .long FLT24,domain_crash_synchronous , FLT25,domain_crash_synchronous
|
||||
+ .long FLT6,domain_crash_synchronous , FLT7,domain_crash_page_fault
|
||||
+ .long FLT8,domain_crash_page_fault_4 , FLT9,domain_crash_page_fault_8
|
||||
+ .long FLT10,domain_crash_page_fault_12, FLT11,domain_crash_page_fault
|
||||
+ .long FLT12,domain_crash_page_fault_4 , FLT13,domain_crash_synchronous
|
||||
+ .long FLT14,domain_crash_page_fault , FLT15,domain_crash_page_fault_4
|
||||
+ .long FLT16,domain_crash_page_fault_8 , FLT17,domain_crash_page_fault
|
||||
+ .long FLT18,domain_crash_page_fault , FLT19,domain_crash_page_fault_4
|
||||
+ .long FLT20,domain_crash_page_fault_8 , FLT21,domain_crash_page_fault_12
|
||||
+ .long FLT22,domain_crash_page_fault , FLT23,domain_crash_page_fault_4
|
||||
+ .long FLT24,domain_crash_page_fault_8 , FLT25,domain_crash_page_fault_12
|
||||
.previous
|
||||
|
||||
+.section .rodata,"a"
|
||||
domain_crash_synchronous_string:
|
||||
.asciz "domain_crash_sync called from entry.S (%lx)\n"
|
||||
+.previous
|
||||
|
||||
+domain_crash_page_fault_12:
|
||||
+ addl $4,%esi
|
||||
+domain_crash_page_fault_8:
|
||||
+ addl $4,%esi
|
||||
+domain_crash_page_fault_4:
|
||||
+ addl $4,%esi
|
||||
+domain_crash_page_fault:
|
||||
+ pushl %esi
|
||||
+ call show_page_walk
|
||||
+ addl $4,%esp
|
||||
domain_crash_synchronous:
|
||||
pushl $domain_crash_synchronous_string
|
||||
call printk
|
||||
Index: 2006-12-05/xen/arch/x86/x86_64/entry.S
|
||||
===================================================================
|
||||
--- 2006-12-05.orig/xen/arch/x86/x86_64/entry.S 2006-12-01 10:44:36.000000000 +0100
|
||||
+++ 2006-12-05/xen/arch/x86/x86_64/entry.S 2006-12-08 14:24:54.000000000 +0100
|
||||
@@ -308,17 +308,30 @@ FLT13: movq %rax,(%rsi)
|
||||
movb $0,TRAPBOUNCE_flags(%rdx)
|
||||
ret
|
||||
.section __ex_table,"a"
|
||||
- .quad FLT2,domain_crash_synchronous , FLT3,domain_crash_synchronous
|
||||
- .quad FLT4,domain_crash_synchronous , FLT5,domain_crash_synchronous
|
||||
- .quad FLT6,domain_crash_synchronous , FLT7,domain_crash_synchronous
|
||||
- .quad FLT8,domain_crash_synchronous , FLT9,domain_crash_synchronous
|
||||
- .quad FLT10,domain_crash_synchronous , FLT11,domain_crash_synchronous
|
||||
- .quad FLT12,domain_crash_synchronous , FLT13,domain_crash_synchronous
|
||||
+ .quad FLT2,domain_crash_page_fault_32, FLT3,domain_crash_page_fault_24
|
||||
+ .quad FLT4,domain_crash_page_fault_8 , FLT5,domain_crash_page_fault_16
|
||||
+ .quad FLT6,domain_crash_page_fault , FLT7,domain_crash_page_fault
|
||||
+ .quad FLT8,domain_crash_page_fault_24, FLT9,domain_crash_page_fault_16
|
||||
+ .quad FLT10,domain_crash_page_fault_8 , FLT11,domain_crash_page_fault
|
||||
+ .quad FLT12,domain_crash_page_fault_8 , FLT13,domain_crash_page_fault
|
||||
.previous
|
||||
|
||||
+.section .rodata,"a"
|
||||
domain_crash_synchronous_string:
|
||||
.asciz "domain_crash_sync called from entry.S\n"
|
||||
+.previous
|
||||
|
||||
+domain_crash_page_fault_32:
|
||||
+ addq $8,%rsi
|
||||
+domain_crash_page_fault_24:
|
||||
+ addq $8,%rsi
|
||||
+domain_crash_page_fault_16:
|
||||
+ addq $8,%rsi
|
||||
+domain_crash_page_fault_8:
|
||||
+ addq $8,%rsi
|
||||
+domain_crash_page_fault:
|
||||
+ movq %rsi,%rdi
|
||||
+ call show_page_walk
|
||||
domain_crash_synchronous:
|
||||
# Get out of the guest-save area of the stack.
|
||||
GET_GUEST_REGS(%rax)
|
56
x86-mm-simplify.patch
Normal file
56
x86-mm-simplify.patch
Normal file
@ -0,0 +1,56 @@
|
||||
Replace mfn_to_page(lXe_get_pfn()) by lXe_get_page().
|
||||
|
||||
However, what I got surprised by while looking for all of these is that
|
||||
ptwr_emulated_update() uses gmfn_to_mfn() on the pte loaded from the
|
||||
emulation context, while ptwr_do_page_fault() doesn't on the pte stored
|
||||
into that context. Shouldn't these two be symmetric?
|
||||
|
||||
Index: 2007-01-08/xen/arch/x86/mm.c
|
||||
===================================================================
|
||||
--- 2007-01-08.orig/xen/arch/x86/mm.c 2007-01-11 15:33:22.000000000 +0100
|
||||
+++ 2007-01-08/xen/arch/x86/mm.c 2007-01-12 17:25:55.000000000 +0100
|
||||
@@ -794,7 +794,7 @@ static void put_page_from_l2e(l2_pgentry
|
||||
{
|
||||
if ( (l2e_get_flags(l2e) & _PAGE_PRESENT) &&
|
||||
(l2e_get_pfn(l2e) != pfn) )
|
||||
- put_page_and_type(mfn_to_page(l2e_get_pfn(l2e)));
|
||||
+ put_page_and_type(l2e_get_page(l2e));
|
||||
}
|
||||
|
||||
|
||||
@@ -803,7 +803,7 @@ static void put_page_from_l3e(l3_pgentry
|
||||
{
|
||||
if ( (l3e_get_flags(l3e) & _PAGE_PRESENT) &&
|
||||
(l3e_get_pfn(l3e) != pfn) )
|
||||
- put_page_and_type(mfn_to_page(l3e_get_pfn(l3e)));
|
||||
+ put_page_and_type(l3e_get_page(l3e));
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -812,7 +812,7 @@ static void put_page_from_l4e(l4_pgentry
|
||||
{
|
||||
if ( (l4e_get_flags(l4e) & _PAGE_PRESENT) &&
|
||||
(l4e_get_pfn(l4e) != pfn) )
|
||||
- put_page_and_type(mfn_to_page(l4e_get_pfn(l4e)));
|
||||
+ put_page_and_type(l4e_get_page(l4e));
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -3365,7 +3365,6 @@ int ptwr_do_page_fault(struct vcpu *v, u
|
||||
struct cpu_user_regs *regs)
|
||||
{
|
||||
struct domain *d = v->domain;
|
||||
- unsigned long pfn;
|
||||
struct page_info *page;
|
||||
l1_pgentry_t pte;
|
||||
struct ptwr_emulate_ctxt ptwr_ctxt;
|
||||
@@ -3379,8 +3378,7 @@ int ptwr_do_page_fault(struct vcpu *v, u
|
||||
guest_get_eff_l1e(v, addr, &pte);
|
||||
if ( !(l1e_get_flags(pte) & _PAGE_PRESENT) )
|
||||
goto bail;
|
||||
- pfn = l1e_get_pfn(pte);
|
||||
- page = mfn_to_page(pfn);
|
||||
+ page = l1e_get_page(pte);
|
||||
|
||||
/* We are looking only for read-only mappings of p.t. pages. */
|
||||
if ( ((l1e_get_flags(pte) & (_PAGE_PRESENT|_PAGE_RW)) != _PAGE_PRESENT) ||
|
33
x86-ptwr_emulate.patch
Normal file
33
x86-ptwr_emulate.patch
Normal file
@ -0,0 +1,33 @@
|
||||
Index: 2007-01-31/xen/arch/x86/mm.c
|
||||
===================================================================
|
||||
--- 2007-01-31.orig/xen/arch/x86/mm.c 2007-01-31 09:42:10.000000000 +0100
|
||||
+++ 2007-01-31/xen/arch/x86/mm.c 2007-01-31 09:43:38.000000000 +0100
|
||||
@@ -3248,14 +3248,15 @@ static int ptwr_emulated_update(
|
||||
{
|
||||
if ( (CONFIG_PAGING_LEVELS == 3 || IS_COMPAT(d)) &&
|
||||
(bytes == 4) &&
|
||||
+ (addr & 4) &&
|
||||
!do_cmpxchg &&
|
||||
(l1e_get_flags(nl1e) & _PAGE_PRESENT) )
|
||||
{
|
||||
/*
|
||||
- * If this is a half-write to a PAE PTE then we assume that the
|
||||
- * guest has simply got the two writes the wrong way round. We
|
||||
- * zap the PRESENT bit on the assumption the bottom half will be
|
||||
- * written immediately after we return to the guest.
|
||||
+ * If this is an upper half write to a PAE PTE then we assume
|
||||
+ * that the guest has simply got the two writes the wrong way
|
||||
+ * round. We zap the PRESENT bit on the assumption the bottom
|
||||
+ * half will be written immediately after we return to the guest.
|
||||
*/
|
||||
MEM_LOG("ptwr_emulate: fixing up invalid PAE PTE %"PRIpte,
|
||||
l1e_get_intpte(nl1e));
|
||||
@@ -3387,7 +3388,7 @@ int ptwr_do_page_fault(struct vcpu *v, u
|
||||
(page_get_owner(page) != d) )
|
||||
goto bail;
|
||||
|
||||
- ptwr_ctxt.ctxt.regs = guest_cpu_user_regs();
|
||||
+ ptwr_ctxt.ctxt.regs = regs;
|
||||
ptwr_ctxt.ctxt.mode = !IS_COMPAT(d) ? X86EMUL_MODE_HOST : X86EMUL_MODE_PROT32;
|
||||
ptwr_ctxt.cr2 = addr;
|
||||
ptwr_ctxt.pte = pte;
|
554
x86_emulate.patch
Normal file
554
x86_emulate.patch
Normal file
@ -0,0 +1,554 @@
|
||||
Index: 2007-01-31/xen/arch/x86/mm.c
|
||||
===================================================================
|
||||
--- 2007-01-31.orig/xen/arch/x86/mm.c 2006-12-15 16:33:59.000000000 +0100
|
||||
+++ 2007-01-31/xen/arch/x86/mm.c 2007-01-31 09:28:56.000000000 +0100
|
||||
@@ -3245,6 +3245,7 @@ static int ptwr_emulated_cmpxchg(
|
||||
container_of(ctxt, struct ptwr_emulate_ctxt, ctxt));
|
||||
}
|
||||
|
||||
+#ifdef __i386__
|
||||
static int ptwr_emulated_cmpxchg8b(
|
||||
enum x86_segment seg,
|
||||
unsigned long offset,
|
||||
@@ -3260,13 +3261,16 @@ static int ptwr_emulated_cmpxchg8b(
|
||||
offset, ((u64)old_hi << 32) | old, ((u64)new_hi << 32) | new, 8, 1,
|
||||
container_of(ctxt, struct ptwr_emulate_ctxt, ctxt));
|
||||
}
|
||||
+#endif
|
||||
|
||||
static struct x86_emulate_ops ptwr_emulate_ops = {
|
||||
.read = ptwr_emulated_read,
|
||||
.insn_fetch = ptwr_emulated_read,
|
||||
.write = ptwr_emulated_write,
|
||||
.cmpxchg = ptwr_emulated_cmpxchg,
|
||||
- .cmpxchg8b = ptwr_emulated_cmpxchg8b
|
||||
+#ifdef __i386__
|
||||
+ .cmpxchg2 = ptwr_emulated_cmpxchg8b
|
||||
+#endif
|
||||
};
|
||||
|
||||
/* Write page fault handler: check if guest is trying to modify a PTE. */
|
||||
Index: 2007-01-31/xen/arch/x86/mm/shadow/common.c
|
||||
===================================================================
|
||||
--- 2007-01-31.orig/xen/arch/x86/mm/shadow/common.c 2007-01-08 14:16:35.000000000 +0100
|
||||
+++ 2007-01-31/xen/arch/x86/mm/shadow/common.c 2007-01-31 09:28:56.000000000 +0100
|
||||
@@ -276,6 +276,7 @@ hvm_emulate_cmpxchg(enum x86_segment seg
|
||||
v, addr, old, new, bytes, sh_ctxt);
|
||||
}
|
||||
|
||||
+#ifdef __i386__
|
||||
static int
|
||||
hvm_emulate_cmpxchg8b(enum x86_segment seg,
|
||||
unsigned long offset,
|
||||
@@ -299,13 +300,31 @@ hvm_emulate_cmpxchg8b(enum x86_segment s
|
||||
return v->arch.shadow.mode->x86_emulate_cmpxchg8b(
|
||||
v, addr, old_lo, old_hi, new_lo, new_hi, sh_ctxt);
|
||||
}
|
||||
+#endif
|
||||
+
|
||||
+static unsigned int
|
||||
+hvm_stack_word_size(struct x86_emulate_ctxt *ctxt)
|
||||
+{
|
||||
+#ifdef __x86_64__
|
||||
+ if ( ctxt->mode == X86EMUL_MODE_PROT64 )
|
||||
+ return 8;
|
||||
+#endif
|
||||
+
|
||||
+ return hvm_get_seg_reg(x86_seg_ss,
|
||||
+ container_of(ctxt,
|
||||
+ struct sh_emulate_ctxt,
|
||||
+ ctxt))->attr.fields.db ? 4 : 2;
|
||||
+}
|
||||
|
||||
static struct x86_emulate_ops hvm_shadow_emulator_ops = {
|
||||
.read = hvm_emulate_read,
|
||||
.insn_fetch = hvm_emulate_insn_fetch,
|
||||
.write = hvm_emulate_write,
|
||||
.cmpxchg = hvm_emulate_cmpxchg,
|
||||
- .cmpxchg8b = hvm_emulate_cmpxchg8b,
|
||||
+#ifdef __i386__
|
||||
+ .cmpxchg2 = hvm_emulate_cmpxchg8b,
|
||||
+#endif
|
||||
+ .stksz = hvm_stack_word_size
|
||||
};
|
||||
|
||||
static int
|
||||
@@ -356,6 +375,7 @@ pv_emulate_cmpxchg(enum x86_segment seg,
|
||||
v, offset, old, new, bytes, sh_ctxt);
|
||||
}
|
||||
|
||||
+#ifdef __i386__
|
||||
static int
|
||||
pv_emulate_cmpxchg8b(enum x86_segment seg,
|
||||
unsigned long offset,
|
||||
@@ -371,13 +391,16 @@ pv_emulate_cmpxchg8b(enum x86_segment se
|
||||
return v->arch.shadow.mode->x86_emulate_cmpxchg8b(
|
||||
v, offset, old_lo, old_hi, new_lo, new_hi, sh_ctxt);
|
||||
}
|
||||
+#endif
|
||||
|
||||
static struct x86_emulate_ops pv_shadow_emulator_ops = {
|
||||
.read = pv_emulate_read,
|
||||
.insn_fetch = pv_emulate_read,
|
||||
.write = pv_emulate_write,
|
||||
.cmpxchg = pv_emulate_cmpxchg,
|
||||
- .cmpxchg8b = pv_emulate_cmpxchg8b,
|
||||
+#ifdef __i386__
|
||||
+ .cmpxchg2 = pv_emulate_cmpxchg8b,
|
||||
+#endif
|
||||
};
|
||||
|
||||
struct x86_emulate_ops *shadow_init_emulation(
|
||||
Index: 2007-01-31/xen/arch/x86/mm/shadow/multi.c
|
||||
===================================================================
|
||||
--- 2007-01-31.orig/xen/arch/x86/mm/shadow/multi.c 2007-01-31 09:19:50.000000000 +0100
|
||||
+++ 2007-01-31/xen/arch/x86/mm/shadow/multi.c 2007-01-31 09:28:56.000000000 +0100
|
||||
@@ -3914,7 +3914,8 @@ sh_x86_emulate_cmpxchg(struct vcpu *v, u
|
||||
return rv;
|
||||
}
|
||||
|
||||
-int
|
||||
+#ifdef __i386__
|
||||
+static int
|
||||
sh_x86_emulate_cmpxchg8b(struct vcpu *v, unsigned long vaddr,
|
||||
unsigned long old_lo, unsigned long old_hi,
|
||||
unsigned long new_lo, unsigned long new_hi,
|
||||
@@ -3950,6 +3951,7 @@ sh_x86_emulate_cmpxchg8b(struct vcpu *v,
|
||||
shadow_audit_tables(v);
|
||||
return rv;
|
||||
}
|
||||
+#endif
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
@@ -4237,7 +4239,9 @@ struct shadow_paging_mode sh_paging_mode
|
||||
.detach_old_tables = sh_detach_old_tables,
|
||||
.x86_emulate_write = sh_x86_emulate_write,
|
||||
.x86_emulate_cmpxchg = sh_x86_emulate_cmpxchg,
|
||||
+#ifdef __i386__
|
||||
.x86_emulate_cmpxchg8b = sh_x86_emulate_cmpxchg8b,
|
||||
+#endif
|
||||
.make_monitor_table = sh_make_monitor_table,
|
||||
.destroy_monitor_table = sh_destroy_monitor_table,
|
||||
.guest_map_l1e = sh_guest_map_l1e,
|
||||
Index: 2007-01-31/xen/arch/x86/x86_emulate.c
|
||||
===================================================================
|
||||
--- 2007-01-31.orig/xen/arch/x86/x86_emulate.c 2006-12-13 11:15:54.000000000 +0100
|
||||
+++ 2007-01-31/xen/arch/x86/x86_emulate.c 2007-01-31 09:28:56.000000000 +0100
|
||||
@@ -15,6 +15,7 @@
|
||||
#include <xen/types.h>
|
||||
#include <xen/lib.h>
|
||||
#include <asm/regs.h>
|
||||
+#include <asm/processor.h>
|
||||
#undef cmpxchg
|
||||
#endif
|
||||
#include <asm-x86/x86_emulate.h>
|
||||
@@ -371,7 +372,10 @@ do{ __asm__ __volatile__ (
|
||||
/* Fetch next part of the instruction being emulated. */
|
||||
#define insn_fetch_bytes(_size) \
|
||||
({ unsigned long _x; \
|
||||
- rc = ops->insn_fetch(x86_seg_cs, _regs.eip, &_x, (_size), ctxt); \
|
||||
+ if ( _regs.eip - ctxt->regs->eip < 16 - (_size) ) \
|
||||
+ rc = ops->insn_fetch(x86_seg_cs, _regs.eip, &_x, (_size), ctxt); \
|
||||
+ else \
|
||||
+ goto cannot_emulate; \
|
||||
if ( rc != 0 ) \
|
||||
goto done; \
|
||||
_regs.eip += (_size); \
|
||||
@@ -385,6 +389,14 @@ do{ __asm__ __volatile__ (
|
||||
(__ea & ((1UL << (ad_bytes << 3)) - 1))); \
|
||||
})
|
||||
|
||||
+#define truncate_sp() \
|
||||
+({ \
|
||||
+ if ( !stksz ) \
|
||||
+ stksz = !ops->stksz ? ad_default : ops->stksz(ctxt); \
|
||||
+ ((stksz == sizeof(unsigned long)) ? _regs.esp : \
|
||||
+ (_regs.esp & ((1UL << (stksz << 3)) - 1))); \
|
||||
+})
|
||||
+
|
||||
/* Update address held in a register, based on addressing mode. */
|
||||
#define register_address_increment(reg, inc) \
|
||||
do { \
|
||||
@@ -396,6 +408,18 @@ do {
|
||||
(((reg) + _inc) & ((1UL << (ad_bytes << 3)) - 1)); \
|
||||
} while (0)
|
||||
|
||||
+#define sp_increment(inc) \
|
||||
+do { \
|
||||
+ int _inc = (inc); /* signed type ensures sign extension to long */ \
|
||||
+ if ( !stksz ) \
|
||||
+ stksz = !ops->stksz ? ad_default : ops->stksz(ctxt); \
|
||||
+ if ( stksz == sizeof(unsigned long) ) \
|
||||
+ _regs.esp += _inc; \
|
||||
+ else \
|
||||
+ _regs.esp = (_regs.esp & ~((1UL << (stksz << 3)) - 1)) | \
|
||||
+ ((_regs.esp + _inc) & ((1UL << (stksz << 3)) - 1)); \
|
||||
+} while (0)
|
||||
+
|
||||
void *
|
||||
decode_register(
|
||||
uint8_t modrm_reg, struct cpu_user_regs *regs, int highbyte_regs)
|
||||
@@ -446,7 +470,8 @@ x86_emulate_memop(
|
||||
|
||||
uint8_t b, d, sib, sib_index, sib_base, twobyte = 0, rex_prefix = 0;
|
||||
uint8_t modrm, modrm_mod = 0, modrm_reg = 0, modrm_rm = 0;
|
||||
- unsigned int op_bytes, ad_bytes, lock_prefix = 0, rep_prefix = 0, i;
|
||||
+ unsigned int op_bytes, ad_bytes, lock_prefix = 0, rep_prefix = 0;
|
||||
+ unsigned int op_default, ad_default, stksz = 0;
|
||||
int rc = 0;
|
||||
struct operand src, dst;
|
||||
int mode = ctxt->mode;
|
||||
@@ -458,15 +483,15 @@ x86_emulate_memop(
|
||||
{
|
||||
case X86EMUL_MODE_REAL:
|
||||
case X86EMUL_MODE_PROT16:
|
||||
- op_bytes = ad_bytes = 2;
|
||||
+ op_default = op_bytes = ad_default = ad_bytes = 2;
|
||||
break;
|
||||
case X86EMUL_MODE_PROT32:
|
||||
- op_bytes = ad_bytes = 4;
|
||||
+ op_default = op_bytes = ad_default = ad_bytes = 4;
|
||||
break;
|
||||
#ifdef __x86_64__
|
||||
case X86EMUL_MODE_PROT64:
|
||||
- op_bytes = 4;
|
||||
- ad_bytes = 8;
|
||||
+ op_default = op_bytes = 4;
|
||||
+ ad_default = ad_bytes = 8;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
@@ -474,18 +499,18 @@ x86_emulate_memop(
|
||||
}
|
||||
|
||||
/* Legacy prefixes. */
|
||||
- for ( i = 0; i < 8; i++ )
|
||||
+ for ( ; ; )
|
||||
{
|
||||
switch ( b = insn_fetch_type(uint8_t) )
|
||||
{
|
||||
case 0x66: /* operand-size override */
|
||||
- op_bytes ^= 6; /* switch between 2/4 bytes */
|
||||
+ op_bytes = op_default ^ 6; /* switch between 2/4 bytes */
|
||||
break;
|
||||
case 0x67: /* address-size override */
|
||||
if ( mode == X86EMUL_MODE_PROT64 )
|
||||
- ad_bytes ^= 12; /* switch between 4/8 bytes */
|
||||
+ ad_bytes = ad_default ^ 12; /* switch between 4/8 bytes */
|
||||
else
|
||||
- ad_bytes ^= 6; /* switch between 2/4 bytes */
|
||||
+ ad_bytes = ad_default ^ 6; /* switch between 2/4 bytes */
|
||||
break;
|
||||
case 0x2e: /* CS override */
|
||||
ea_seg = x86_seg_cs;
|
||||
@@ -508,25 +533,29 @@ x86_emulate_memop(
|
||||
case 0xf0: /* LOCK */
|
||||
lock_prefix = 1;
|
||||
break;
|
||||
+ case 0xf2: /* REPNE/REPNZ */
|
||||
case 0xf3: /* REP/REPE/REPZ */
|
||||
rep_prefix = 1;
|
||||
break;
|
||||
- case 0xf2: /* REPNE/REPNZ */
|
||||
- break;
|
||||
+#ifdef __x86_64__
|
||||
+ case 0x40 ... 0x4f:
|
||||
+ if ( mode == X86EMUL_MODE_PROT64 )
|
||||
+ {
|
||||
+ rex_prefix = b;
|
||||
+ continue;
|
||||
+ }
|
||||
+ /* FALLTHRU */
|
||||
+#endif
|
||||
default:
|
||||
goto done_prefixes;
|
||||
}
|
||||
+ rex_prefix = 0;
|
||||
}
|
||||
done_prefixes:
|
||||
|
||||
/* REX prefix. */
|
||||
- if ( (mode == X86EMUL_MODE_PROT64) && ((b & 0xf0) == 0x40) )
|
||||
- {
|
||||
- rex_prefix = b;
|
||||
- if ( b & 8 ) /* REX.W */
|
||||
- op_bytes = 8;
|
||||
- b = insn_fetch_type(uint8_t);
|
||||
- }
|
||||
+ if ( rex_prefix & 8 ) /* REX.W */
|
||||
+ op_bytes = 8;
|
||||
|
||||
/* Opcode byte(s). */
|
||||
d = opcode_table[b];
|
||||
@@ -598,7 +627,16 @@ x86_emulate_memop(
|
||||
if ( (modrm_mod == 0) && ((sib_base & 7) == 5) )
|
||||
ea_off += insn_fetch_type(int32_t);
|
||||
else
|
||||
+ {
|
||||
ea_off += *(long *)decode_register(sib_base, &_regs, 0);
|
||||
+ if ( sib_base == 4 && !twobyte && b == 0x8f )
|
||||
+ {
|
||||
+ /* POP to an address with esp as base register. */
|
||||
+ if ( mode == X86EMUL_MODE_PROT64 && op_bytes == 4 )
|
||||
+ op_bytes = 8;
|
||||
+ ea_off += op_bytes;
|
||||
+ }
|
||||
+ }
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -841,12 +879,12 @@ x86_emulate_memop(
|
||||
break;
|
||||
case 0x8f: /* pop (sole member of Grp1a) */
|
||||
/* 64-bit mode: POP always pops a 64-bit operand. */
|
||||
- if ( mode == X86EMUL_MODE_PROT64 )
|
||||
+ if ( mode == X86EMUL_MODE_PROT64 && dst.bytes == 4 )
|
||||
dst.bytes = 8;
|
||||
- if ( (rc = ops->read(x86_seg_ss, truncate_ea(_regs.esp),
|
||||
+ if ( (rc = ops->read(x86_seg_ss, truncate_sp(),
|
||||
&dst.val, dst.bytes, ctxt)) != 0 )
|
||||
goto done;
|
||||
- register_address_increment(_regs.esp, dst.bytes);
|
||||
+ sp_increment(dst.bytes);
|
||||
break;
|
||||
case 0xc0 ... 0xc1: grp2: /* Grp2 */
|
||||
switch ( modrm_reg & 7 )
|
||||
@@ -917,15 +955,15 @@ x86_emulate_memop(
|
||||
break;
|
||||
case 6: /* push */
|
||||
/* 64-bit mode: PUSH always pushes a 64-bit operand. */
|
||||
- if ( mode == X86EMUL_MODE_PROT64 )
|
||||
+ if ( mode == X86EMUL_MODE_PROT64 && dst.bytes == 4 )
|
||||
{
|
||||
dst.bytes = 8;
|
||||
if ( (rc = ops->read(dst.mem_seg, dst.mem_off,
|
||||
&dst.val, 8, ctxt)) != 0 )
|
||||
goto done;
|
||||
}
|
||||
- register_address_increment(_regs.esp, -dst.bytes);
|
||||
- if ( (rc = ops->write(x86_seg_ss, truncate_ea(_regs.esp),
|
||||
+ sp_increment(-dst.bytes);
|
||||
+ if ( (rc = ops->write(x86_seg_ss, truncate_sp(),
|
||||
dst.val, dst.bytes, ctxt)) != 0 )
|
||||
goto done;
|
||||
dst.val = dst.orig_val; /* skanky: disable writeback */
|
||||
@@ -975,7 +1013,7 @@ x86_emulate_memop(
|
||||
special_insn:
|
||||
if ( twobyte )
|
||||
goto twobyte_special_insn;
|
||||
- if ( rep_prefix )
|
||||
+ if ( rep_prefix && (b & ~3) != 0xa0 )
|
||||
{
|
||||
if ( _regs.ecx == 0 )
|
||||
{
|
||||
@@ -1119,6 +1157,7 @@ x86_emulate_memop(
|
||||
case 1: goto bts;
|
||||
case 2: goto btr;
|
||||
case 3: goto btc;
|
||||
+ default: goto cannot_emulate;
|
||||
}
|
||||
break;
|
||||
case 0xbe ... 0xbf: /* movsx */
|
||||
@@ -1146,56 +1185,65 @@ x86_emulate_memop(
|
||||
case 0x0d: /* GrpP (prefetch) */
|
||||
case 0x18: /* Grp16 (prefetch/nop) */
|
||||
break;
|
||||
- case 0xc7: /* Grp9 (cmpxchg8b) */
|
||||
-#if defined(__i386__)
|
||||
- {
|
||||
- unsigned long old_lo, old_hi;
|
||||
- if ( ((rc = ops->read(ea_seg, ea_off+0, &old_lo, 4, ctxt)) != 0) ||
|
||||
- ((rc = ops->read(ea_seg, ea_off+4, &old_hi, 4, ctxt)) != 0) )
|
||||
- goto done;
|
||||
- if ( (old_lo != _regs.eax) || (old_hi != _regs.edx) )
|
||||
- {
|
||||
- _regs.eax = old_lo;
|
||||
- _regs.edx = old_hi;
|
||||
- _regs.eflags &= ~EFLG_ZF;
|
||||
- }
|
||||
- else if ( ops->cmpxchg8b == NULL )
|
||||
- {
|
||||
- rc = X86EMUL_UNHANDLEABLE;
|
||||
- goto done;
|
||||
- }
|
||||
- else
|
||||
+ case 0xc7: /* Grp9 (cmpxchg{8,16}b) */
|
||||
+#ifdef __x86_64__
|
||||
+ if ( op_bytes != 8 )
|
||||
{
|
||||
- if ( (rc = ops->cmpxchg8b(ea_seg, ea_off, old_lo, old_hi,
|
||||
- _regs.ebx, _regs.ecx, ctxt)) != 0 )
|
||||
+ unsigned long old, new;
|
||||
+ if ( (rc = ops->read(ea_seg, ea_off, &old, 8, ctxt)) != 0 )
|
||||
goto done;
|
||||
- _regs.eflags |= EFLG_ZF;
|
||||
- }
|
||||
- break;
|
||||
- }
|
||||
-#elif defined(__x86_64__)
|
||||
- {
|
||||
- unsigned long old, new;
|
||||
- if ( (rc = ops->read(ea_seg, ea_off, &old, 8, ctxt)) != 0 )
|
||||
- goto done;
|
||||
- if ( ((uint32_t)(old>>0) != (uint32_t)_regs.eax) ||
|
||||
- ((uint32_t)(old>>32) != (uint32_t)_regs.edx) )
|
||||
- {
|
||||
- _regs.eax = (uint32_t)(old>>0);
|
||||
- _regs.edx = (uint32_t)(old>>32);
|
||||
- _regs.eflags &= ~EFLG_ZF;
|
||||
+ if ( ((uint32_t)(old>>0) != (uint32_t)_regs.eax) ||
|
||||
+ ((uint32_t)(old>>32) != (uint32_t)_regs.edx) )
|
||||
+ {
|
||||
+ _regs.eax = (uint32_t)(old>>0);
|
||||
+ _regs.edx = (uint32_t)(old>>32);
|
||||
+ _regs.eflags &= ~EFLG_ZF;
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ new = (_regs.ecx<<32)|(uint32_t)_regs.ebx;
|
||||
+ if ( (rc = ops->cmpxchg(ea_seg, ea_off, old, new, 8, ctxt)) != 0 )
|
||||
+ goto done;
|
||||
+ _regs.eflags |= EFLG_ZF;
|
||||
+ }
|
||||
}
|
||||
else
|
||||
+#endif
|
||||
{
|
||||
- new = (_regs.ecx<<32)|(uint32_t)_regs.ebx;
|
||||
- if ( (rc = ops->cmpxchg(ea_seg, ea_off, old, new, 8, ctxt)) != 0 )
|
||||
+ unsigned long old_lo, old_hi;
|
||||
+ if ( ((rc = ops->read(ea_seg, ea_off, &old_lo,
|
||||
+ sizeof(old_lo), ctxt)) != 0) ||
|
||||
+ ((rc = ops->read(ea_seg, ea_off+sizeof(old_lo), &old_hi,
|
||||
+ sizeof(old_hi), ctxt)) != 0) )
|
||||
+ goto done;
|
||||
+ if ( (old_lo != _regs.eax) || (old_hi != _regs.edx) )
|
||||
+ {
|
||||
+ _regs.eax = old_lo;
|
||||
+ _regs.edx = old_hi;
|
||||
+ _regs.eflags &= ~EFLG_ZF;
|
||||
+ }
|
||||
+ else if ( ops->cmpxchg2 == NULL )
|
||||
+ {
|
||||
+ rc = X86EMUL_UNHANDLEABLE;
|
||||
goto done;
|
||||
- _regs.eflags |= EFLG_ZF;
|
||||
+ }
|
||||
+#ifdef __x86_64__
|
||||
+ else if ( !cpu_has_cmpxchg16b )
|
||||
+ {
|
||||
+ rc = X86EMUL_UNHANDLEABLE;
|
||||
+ goto done;
|
||||
+ }
|
||||
+#endif
|
||||
+ else
|
||||
+ {
|
||||
+ if ( (rc = ops->cmpxchg2(ea_seg, ea_off, old_lo, old_hi,
|
||||
+ _regs.ebx, _regs.ecx, ctxt)) != 0 )
|
||||
+ goto done;
|
||||
+ _regs.eflags |= EFLG_ZF;
|
||||
+ }
|
||||
}
|
||||
break;
|
||||
}
|
||||
-#endif
|
||||
- }
|
||||
goto writeback;
|
||||
|
||||
cannot_emulate:
|
||||
Index: 2007-01-31/xen/include/asm-x86/cpufeature.h
|
||||
===================================================================
|
||||
--- 2007-01-31.orig/xen/include/asm-x86/cpufeature.h 2006-12-13 11:15:56.000000000 +0100
|
||||
+++ 2007-01-31/xen/include/asm-x86/cpufeature.h 2007-01-31 09:28:56.000000000 +0100
|
||||
@@ -118,6 +118,7 @@
|
||||
#define cpu_has_cyrix_arr boot_cpu_has(X86_FEATURE_CYRIX_ARR)
|
||||
#define cpu_has_centaur_mcr boot_cpu_has(X86_FEATURE_CENTAUR_MCR)
|
||||
#define cpu_has_clflush boot_cpu_has(X86_FEATURE_CLFLSH)
|
||||
+#define cpu_has_cmpxchg16b 0
|
||||
#else /* __x86_64__ */
|
||||
#define cpu_has_vme 0
|
||||
#define cpu_has_de 1
|
||||
@@ -140,6 +141,7 @@
|
||||
#define cpu_has_cyrix_arr 0
|
||||
#define cpu_has_centaur_mcr 0
|
||||
#define cpu_has_clflush boot_cpu_has(X86_FEATURE_CLFLSH)
|
||||
+#define cpu_has_cmpxchg16b boot_cpu_has(X86_FEATURE_CX16)
|
||||
#endif
|
||||
|
||||
#endif /* __ASM_I386_CPUFEATURE_H */
|
||||
Index: 2007-01-31/xen/include/asm-x86/shadow.h
|
||||
===================================================================
|
||||
--- 2007-01-31.orig/xen/include/asm-x86/shadow.h 2007-01-08 14:16:35.000000000 +0100
|
||||
+++ 2007-01-31/xen/include/asm-x86/shadow.h 2007-01-31 09:28:56.000000000 +0100
|
||||
@@ -273,12 +273,14 @@ struct shadow_paging_mode {
|
||||
unsigned long new,
|
||||
unsigned int bytes,
|
||||
struct sh_emulate_ctxt *sh_ctxt);
|
||||
+#ifdef __i386__
|
||||
int (*x86_emulate_cmpxchg8b )(struct vcpu *v, unsigned long va,
|
||||
unsigned long old_lo,
|
||||
unsigned long old_hi,
|
||||
unsigned long new_lo,
|
||||
unsigned long new_hi,
|
||||
struct sh_emulate_ctxt *sh_ctxt);
|
||||
+#endif
|
||||
mfn_t (*make_monitor_table )(struct vcpu *v);
|
||||
void (*destroy_monitor_table )(struct vcpu *v, mfn_t mmfn);
|
||||
void * (*guest_map_l1e )(struct vcpu *v, unsigned long va,
|
||||
Index: 2007-01-31/xen/include/asm-x86/x86_emulate.h
|
||||
===================================================================
|
||||
--- 2007-01-31.orig/xen/include/asm-x86/x86_emulate.h 2006-12-13 11:15:56.000000000 +0100
|
||||
+++ 2007-01-31/xen/include/asm-x86/x86_emulate.h 2007-01-31 09:28:56.000000000 +0100
|
||||
@@ -39,8 +39,9 @@ enum x86_segment {
|
||||
* some out-of-band mechanism, unknown to the emulator. The memop signals
|
||||
* failure by returning X86EMUL_PROPAGATE_FAULT to the emulator, which will
|
||||
* then immediately bail.
|
||||
- * 2. Valid access sizes are 1, 2, 4 and 8 bytes. On x86/32 systems only
|
||||
- * cmpxchg8b_emulated need support 8-byte accesses.
|
||||
+ * 2. Valid access sizes are 1, 2, 4, 8, and 16 bytes. On x86/32 systems only
|
||||
+ * cmpxchg2_emulated need support 8-byte accesses. On x86/64 systems only
|
||||
+ * cmpxchg2_emulated need support 16-byte accesses.
|
||||
* 3. The emulator cannot handle 64-bit mode emulation on an x86/32 system.
|
||||
*/
|
||||
/* Access completed successfully: continue emulation as normal. */
|
||||
@@ -110,16 +111,17 @@ struct x86_emulate_ops
|
||||
struct x86_emulate_ctxt *ctxt);
|
||||
|
||||
/*
|
||||
- * cmpxchg8b: Emulate an atomic (LOCKed) CMPXCHG8B operation.
|
||||
+ * cmpxchg2: Emulate an atomic (LOCKed) CMPXCHG{8,16}B operation.
|
||||
* @old: [IN ] Value expected to be current at @addr.
|
||||
* @new: [IN ] Value to write to @addr.
|
||||
* NOTES:
|
||||
- * 1. This function is only ever called when emulating a real CMPXCHG8B.
|
||||
- * 2. This function is *never* called on x86/64 systems.
|
||||
- * 2. Not defining this function (i.e., specifying NULL) is equivalent
|
||||
+ * 1. This function is only ever called when emulating a real CMPXCHG{8,16}B.
|
||||
+ * 2. This function is *never* called on x86/64 systems for emulating
|
||||
+ * CMPXCHG8B.
|
||||
+ * 3. Not defining this function (i.e., specifying NULL) is equivalent
|
||||
* to defining a function that always returns X86EMUL_UNHANDLEABLE.
|
||||
*/
|
||||
- int (*cmpxchg8b)(
|
||||
+ int (*cmpxchg2)(
|
||||
enum x86_segment seg,
|
||||
unsigned long offset,
|
||||
unsigned long old_lo,
|
||||
@@ -127,6 +129,16 @@ struct x86_emulate_ops
|
||||
unsigned long new_lo,
|
||||
unsigned long new_hi,
|
||||
struct x86_emulate_ctxt *ctxt);
|
||||
+
|
||||
+ /*
|
||||
+ * stksz: Determine the item size of the guest stack.
|
||||
+ * NOTE:
|
||||
+ * Not defining this function (i.e., specifying NULL) is equivalent
|
||||
+ * to defining a function that returns the default address size of
|
||||
+ * the execution mode (X86EMUL_MODE_xxx).
|
||||
+ */
|
||||
+ unsigned int (*stksz)(
|
||||
+ struct x86_emulate_ctxt *ctxt);
|
||||
};
|
||||
|
||||
struct cpu_user_regs;
|
@ -1,3 +0,0 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:50d18f4e082110db27a98ffcd39d98cc12058a6dd89c58a378ce283fa911ba89
|
||||
size 4580110
|
3
xen-3.0.4-testing-src.tar.bz2
Normal file
3
xen-3.0.4-testing-src.tar.bz2
Normal file
@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:ed27830300bd6d68d35737d3e8deefe815115f2d165574c8a1f527ee8ec6a606
|
||||
size 5383589
|
@ -1,8 +1,8 @@
|
||||
Index: xen-unstable/tools/examples/network-bridge
|
||||
Index: xen-3.0.4-testing/tools/examples/network-bridge
|
||||
===================================================================
|
||||
--- xen-unstable.orig/tools/examples/network-bridge
|
||||
+++ xen-unstable/tools/examples/network-bridge
|
||||
@@ -145,6 +145,21 @@ antispoofing () {
|
||||
--- xen-3.0.4-testing.orig/tools/examples/network-bridge
|
||||
+++ xen-3.0.4-testing/tools/examples/network-bridge
|
||||
@@ -143,6 +143,21 @@ antispoofing () {
|
||||
iptables -A FORWARD -m physdev --physdev-in ${vif0} -j ACCEPT
|
||||
}
|
||||
|
||||
@ -24,7 +24,7 @@ Index: xen-unstable/tools/examples/network-bridge
|
||||
# Usage: show_status dev bridge
|
||||
# Print ifconfig and routes.
|
||||
show_status () {
|
||||
@@ -187,10 +202,11 @@ using loopback.nloopbacks=<N> on the dom
|
||||
@@ -185,10 +200,11 @@ using loopback.nloopbacks=<N> on the dom
|
||||
|
||||
create_bridge ${bridge}
|
||||
|
||||
@ -38,9 +38,9 @@ Index: xen-unstable/tools/examples/network-bridge
|
||||
transfer_addrs ${netdev} ${vdev}
|
||||
ifdown ${netdev}
|
||||
ip link set ${netdev} name ${pdev}
|
||||
@@ -205,6 +221,13 @@ using loopback.nloopbacks=<N> on the dom
|
||||
@@ -203,6 +219,13 @@ using loopback.nloopbacks=<N> on the dom
|
||||
add_to_bridge2 ${bridge} ${pdev}
|
||||
ip link set ${netdev} up
|
||||
ip link set ${netdev} up
|
||||
ifup ${hwddev}
|
||||
+ elif [ "$BONDING_MASTER" = yes ]; then
|
||||
+ ip link set ${bridge} arp on
|
||||
@ -52,7 +52,7 @@ Index: xen-unstable/tools/examples/network-bridge
|
||||
else
|
||||
# old style without ${vdev}
|
||||
transfer_addrs ${netdev} ${bridge}
|
||||
@@ -243,6 +266,10 @@ op_stop () {
|
||||
@@ -241,6 +264,10 @@ op_stop () {
|
||||
ip link set ${pdev} name ${netdev}
|
||||
ifup ${netdev}
|
||||
else
|
||||
|
22
xen-bootloader-dryrun.diff
Normal file
22
xen-bootloader-dryrun.diff
Normal file
@ -0,0 +1,22 @@
|
||||
Index: xen-3.0.4-testing/tools/python/xen/xend/XendBootloader.py
|
||||
===================================================================
|
||||
--- xen-3.0.4-testing.orig/tools/python/xen/xend/XendBootloader.py
|
||||
+++ xen-3.0.4-testing/tools/python/xen/xend/XendBootloader.py
|
||||
@@ -22,7 +22,7 @@ from XendLogging import log
|
||||
from XendError import VmError
|
||||
|
||||
def bootloader(blexec, disk, quiet = False, blargs = '', kernel = '',
|
||||
- ramdisk = '', kernel_args = ''):
|
||||
+ ramdisk = '', kernel_args = '', dryrun = False):
|
||||
"""Run the boot loader executable on the given disk and return a
|
||||
config image.
|
||||
@param blexec Binary to use as the boot loader
|
||||
@@ -55,6 +55,8 @@ def bootloader(blexec, disk, quiet = Fal
|
||||
args = [ blexec ]
|
||||
if quiet:
|
||||
args.append("-q")
|
||||
+ if dryrun:
|
||||
+ args.append("--dryrun")
|
||||
args.append("--output=%s" % fifo)
|
||||
if blargs:
|
||||
args.extend(shlex.split(blargs))
|
32
xen-bootloader-nohang.diff
Normal file
32
xen-bootloader-nohang.diff
Normal file
@ -0,0 +1,32 @@
|
||||
Index: xen-3.0.4-testing/tools/python/xen/xend/XendBootloader.py
|
||||
===================================================================
|
||||
--- xen-3.0.4-testing.orig/tools/python/xen/xend/XendBootloader.py
|
||||
+++ xen-3.0.4-testing/tools/python/xen/xend/XendBootloader.py
|
||||
@@ -70,20 +70,18 @@ def bootloader(blexec, disk, quiet = Fal
|
||||
|
||||
while True:
|
||||
try:
|
||||
- r = os.open(fifo, os.O_RDONLY)
|
||||
+ r = os.open(fifo, os.O_RDONLY, os.O_NONBLOCK)
|
||||
except OSError, e:
|
||||
if e.errno == errno.EINTR:
|
||||
continue
|
||||
break
|
||||
ret = ""
|
||||
- while True:
|
||||
- select.select([r], [], [])
|
||||
- s = os.read(r, 1024)
|
||||
- ret = ret + s
|
||||
- if len(s) == 0:
|
||||
- break
|
||||
-
|
||||
- os.waitpid(child, 0)
|
||||
+ while os.waitpid(child, os.WNOHANG) == (0, 0):
|
||||
+ # Large timeout, because crashed bootloader is a corner case
|
||||
+ if select.select([r], [], [], 5.0)[0]:
|
||||
+ s = os.read(r, 1024)
|
||||
+ ret = ret + s
|
||||
+
|
||||
os.close(r)
|
||||
os.unlink(fifo)
|
||||
|
13
xen-bootloader-tidy.diff
Normal file
13
xen-bootloader-tidy.diff
Normal file
@ -0,0 +1,13 @@
|
||||
Index: xen-3.0.4-testing/tools/python/xen/xend/XendDomainInfo.py
|
||||
===================================================================
|
||||
--- xen-3.0.4-testing.orig/tools/python/xen/xend/XendDomainInfo.py
|
||||
+++ xen-3.0.4-testing/tools/python/xen/xend/XendDomainInfo.py
|
||||
@@ -1589,7 +1589,7 @@ class XendDomainInfo:
|
||||
log.info("Unmounting %s from %s." %
|
||||
(fn, BOOTLOADER_LOOPBACK_DEVICE))
|
||||
|
||||
- dom0.destroyDevice('tap', '/dev/xvdp')
|
||||
+ dom0.destroyDevice('tap', BOOTLOADER_LOOPBACK_DEVICE)
|
||||
|
||||
break
|
||||
|
@ -1,20 +1,17 @@
|
||||
Index: xen-3.0.3-testing/xen/Makefile
|
||||
Index: xen-3.0.4-testing/xen/Makefile
|
||||
===================================================================
|
||||
--- xen-3.0.3-testing.orig/xen/Makefile
|
||||
+++ xen-3.0.3-testing/xen/Makefile
|
||||
@@ -3,6 +3,7 @@
|
||||
export XEN_VERSION = 3
|
||||
export XEN_SUBVERSION = 0
|
||||
export XEN_EXTRAVERSION ?= .3-0
|
||||
--- xen-3.0.4-testing.orig/xen/Makefile
|
||||
+++ xen-3.0.4-testing/xen/Makefile
|
||||
@@ -1,3 +1,4 @@
|
||||
+export XEN_CHANGESET = unavailable
|
||||
export XEN_FULLVERSION = $(XEN_VERSION).$(XEN_SUBVERSION)$(XEN_EXTRAVERSION)
|
||||
-include xen-version
|
||||
|
||||
# This is the correct place to edit the build version.
|
||||
# All other places this is stored (eg. compile.h) should be autogenerated.
|
||||
export XEN_VERSION = 3
|
||||
@@ -103,7 +104,7 @@ include/xen/compile.h: include/xen/compi
|
||||
-e 's/@@version@@/$(XEN_VERSION)/g' \
|
||||
-e 's/@@subversion@@/$(XEN_SUBVERSION)/g' \
|
||||
-e 's/@@extraversion@@/$(XEN_EXTRAVERSION)/g' \
|
||||
- -e 's!@@changeset@@!$(shell ((hg parents || head -n 7 ../ChangeLog || echo date: unavailable) | awk '{FS="changeset:[ ]+"}/^changeset/{CS=$$2};{FS="date:[ ]+"}/^date/{D=$$2}; END {print D, CS}') 2>/dev/null)!g' \
|
||||
- -e 's!@@changeset@@!$(shell ((hg parents --template "{date|date} {rev}:{node|short}" >/dev/null && hg parents --template "{date|date} {rev}:{node|short}") || echo "unavailable") 2>/dev/null)!g' \
|
||||
+ -e 's!@@changeset@@!$(XEN_CHANGESET)!g' \
|
||||
< include/xen/compile.h.in > $@.new
|
||||
tools/figlet/figlet -d tools/figlet Xen $(XEN_FULLVERSION) >> $@.new
|
||||
|
14
xen-config.diff
Normal file
14
xen-config.diff
Normal file
@ -0,0 +1,14 @@
|
||||
Index: xen-unstable/Config.mk
|
||||
===================================================================
|
||||
--- xen-unstable.orig/Config.mk
|
||||
+++ xen-unstable/Config.mk
|
||||
@@ -70,7 +70,7 @@ ACM_DEFAULT_SECURITY_POLICY ?= ACM_NULL_
|
||||
# Optional components
|
||||
XENSTAT_XENTOP ?= y
|
||||
VTPM_TOOLS ?= n
|
||||
-LIBXENAPI_BINDINGS ?= n
|
||||
-XENFB_TOOLS ?= n
|
||||
+LIBXENAPI_BINDINGS ?= y
|
||||
+XENFB_TOOLS ?= y
|
||||
|
||||
-include $(XEN_ROOT)/.config
|
@ -1,63 +0,0 @@
|
||||
Subject: video mode detection (161541)
|
||||
|
||||
Charles, attached the promised patch for replacing xen-console.diff. Jan
|
||||
|
||||
Index: xen-unstable/xen/drivers/video/vga.c
|
||||
===================================================================
|
||||
--- xen-unstable.orig/xen/drivers/video/vga.c
|
||||
+++ xen-unstable/xen/drivers/video/vga.c
|
||||
@@ -573,6 +573,30 @@ string_param("vga", opt_vga);
|
||||
#define ATTRIBUTE 7
|
||||
#define VIDEO_SIZE (COLUMNS * LINES * 2)
|
||||
|
||||
+static int gfx_vga(void)
|
||||
+{
|
||||
+ unsigned char idx, data;
|
||||
+
|
||||
+ idx = inb(0x3ce);
|
||||
+ outb(0x06, 0x3ce);
|
||||
+ data = inb(0x3cf);
|
||||
+ outb(idx, 0x3ce);
|
||||
+
|
||||
+ if ( data & 0x01 )
|
||||
+ return 1;
|
||||
+
|
||||
+ /* Unfortunately many cards don't reflect their mode in the GDC
|
||||
+ * miscellaneous register, bit 0 (and even fewer reflect it in the
|
||||
+ * ATC mode control register, bit 0). Therefore we further check
|
||||
+ * horizontal display width against our original setting. */
|
||||
+ idx = inb(0x3d4);
|
||||
+ outb(0x01, 0x3d4);
|
||||
+ data = inb(0x3d5);
|
||||
+ outb(idx, 0x3d4);
|
||||
+
|
||||
+ return data != COLUMNS - 1;
|
||||
+}
|
||||
+
|
||||
void vga_init(void)
|
||||
{
|
||||
char *p;
|
||||
@@ -656,14 +680,21 @@ static void put_newline(void)
|
||||
|
||||
void vga_putchar(int c)
|
||||
{
|
||||
+ static int vga_in_gfx = -1;
|
||||
+
|
||||
if ( !vgacon_enabled )
|
||||
return;
|
||||
|
||||
+ if ( vga_in_gfx < 0 )
|
||||
+ vga_in_gfx = gfx_vga();
|
||||
+
|
||||
if ( c == '\n' )
|
||||
{
|
||||
- put_newline();
|
||||
+ if ( vga_in_gfx <= 0 )
|
||||
+ put_newline();
|
||||
+ vga_in_gfx = -1;
|
||||
}
|
||||
- else
|
||||
+ else if ( vga_in_gfx <= 0 )
|
||||
{
|
||||
if ( xpos >= COLUMNS )
|
||||
put_newline();
|
110
xen-destdir.diff
110
xen-destdir.diff
@ -1,8 +1,8 @@
|
||||
Index: xen-3.0.3-testing/docs/Makefile
|
||||
Index: xen-3.0.4-testing/docs/Makefile
|
||||
===================================================================
|
||||
--- xen-3.0.3-testing.orig/docs/Makefile
|
||||
+++ xen-3.0.3-testing/docs/Makefile
|
||||
@@ -12,8 +12,8 @@ LATEX2HTML := latex2html
|
||||
--- xen-3.0.4-testing.orig/docs/Makefile
|
||||
+++ xen-3.0.4-testing/docs/Makefile
|
||||
@@ -13,8 +13,8 @@ LATEX2HTML := latex2html
|
||||
DOXYGEN := doxygen
|
||||
POD2MAN := pod2man
|
||||
|
||||
@ -13,11 +13,37 @@ Index: xen-3.0.3-testing/docs/Makefile
|
||||
|
||||
DOC_MAN5SRC := $(wildcard man/*.pod.5)
|
||||
DOC_MAN1SRC := $(wildcard man/*.pod.1)
|
||||
Index: xen-3.0.3-testing/tools/xentrace/Makefile
|
||||
@@ -87,13 +87,13 @@ distclean: clean
|
||||
.PHONY: install
|
||||
install: all
|
||||
rm -rf $(DESTDIR)$(pkgdocdir)
|
||||
- $(INSTALL_DIR) $(DESTDIR)$(pkgdocdir)
|
||||
+ $(INSTALL_DIR) $(DESTDIR)$(pkgdocdir)/html
|
||||
cp -dR ps $(DESTDIR)$(pkgdocdir)
|
||||
cp -dR pdf $(DESTDIR)$(pkgdocdir)
|
||||
+ cp -dR html.done/* $(DESTDIR)$(pkgdocdir)/html
|
||||
$(INSTALL_DIR) $(DESTDIR)$(mandir)
|
||||
cp -dR man1 $(DESTDIR)$(mandir)
|
||||
cp -dR man5 $(DESTDIR)$(mandir)
|
||||
- [ ! -d html ] || cp -dR html $(DESTDIR)$(pkgdocdir)
|
||||
|
||||
pdf/%.pdf: ps/%.ps
|
||||
$(INSTALL_DIR) $(@D)
|
||||
@@ -117,3 +117,9 @@ html/%/index.html: src/%.tex
|
||||
$(LATEX2HTML) -split 0 -show_section_numbers -toc_depth 3 -nonavigation \
|
||||
-numbered_footnotes -local_icons -noinfo -math -dir $(@D) \
|
||||
$< 1>/dev/null 2>/dev/null
|
||||
+ rm -rf html.done/$*/
|
||||
+ mkdir -p html.done/$*/
|
||||
+ cp html/$*/*.html html/$*/*.css html/$*/*.png html.done/$*/
|
||||
+ ln -sf $*.html html.done/$*/index.html
|
||||
+ rm -rf html/
|
||||
+
|
||||
Index: xen-3.0.4-testing/tools/xentrace/Makefile
|
||||
===================================================================
|
||||
--- xen-3.0.3-testing.orig/tools/xentrace/Makefile
|
||||
+++ xen-3.0.3-testing/tools/xentrace/Makefile
|
||||
@@ -43,14 +43,14 @@ install: build
|
||||
--- xen-3.0.4-testing.orig/tools/xentrace/Makefile
|
||||
+++ xen-3.0.4-testing/tools/xentrace/Makefile
|
||||
@@ -38,14 +38,14 @@ install: build
|
||||
[ -d $(DESTDIR)/usr/bin ] || $(INSTALL_DIR) $(DESTDIR)/usr/bin
|
||||
[ -z "$(LIBBIN)" ] || [ -d $(DESTDIR)/usr/$(LIBDIR)/xen/bin ] || \
|
||||
$(INSTALL_DIR) $(DESTDIR)/usr/$(LIBDIR)/xen/bin
|
||||
@ -38,11 +64,11 @@ Index: xen-3.0.3-testing/tools/xentrace/Makefile
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
Index: xen-3.0.3-testing/tools/examples/Makefile
|
||||
Index: xen-3.0.4-testing/tools/examples/Makefile
|
||||
===================================================================
|
||||
--- xen-3.0.3-testing.orig/tools/examples/Makefile
|
||||
+++ xen-3.0.3-testing/tools/examples/Makefile
|
||||
@@ -43,18 +43,6 @@ XEN_HOTPLUG_SCRIPTS = xen-backend.agent
|
||||
--- xen-3.0.4-testing.orig/tools/examples/Makefile
|
||||
+++ xen-3.0.4-testing/tools/examples/Makefile
|
||||
@@ -38,18 +38,6 @@ XEN_HOTPLUG_SCRIPTS = xen-backend.agent
|
||||
UDEV_RULES_DIR = /etc/udev
|
||||
UDEV_RULES = xen-backend.rules
|
||||
|
||||
@ -61,7 +87,7 @@ Index: xen-3.0.3-testing/tools/examples/Makefile
|
||||
.PHONY: all
|
||||
all:
|
||||
|
||||
@@ -62,15 +50,15 @@ all:
|
||||
@@ -57,15 +45,15 @@ all:
|
||||
build:
|
||||
|
||||
.PHONY: install
|
||||
@ -80,7 +106,7 @@ Index: xen-3.0.3-testing/tools/examples/Makefile
|
||||
|
||||
.PHONY: install-configs
|
||||
install-configs: $(XEN_CONFIGS)
|
||||
@@ -111,9 +99,7 @@ install-udev:
|
||||
@@ -106,9 +94,7 @@ install-udev:
|
||||
$(INSTALL_DIR) $(DESTDIR)$(UDEV_RULES_DIR)/rules.d
|
||||
for i in $(UDEV_RULES); \
|
||||
do \
|
||||
@ -91,10 +117,10 @@ Index: xen-3.0.3-testing/tools/examples/Makefile
|
||||
done
|
||||
|
||||
.PHONY: clean
|
||||
Index: xen-3.0.3-testing/tools/security/Makefile
|
||||
Index: xen-3.0.4-testing/tools/security/Makefile
|
||||
===================================================================
|
||||
--- xen-3.0.3-testing.orig/tools/security/Makefile
|
||||
+++ xen-3.0.3-testing/tools/security/Makefile
|
||||
--- xen-3.0.4-testing.orig/tools/security/Makefile
|
||||
+++ xen-3.0.4-testing/tools/security/Makefile
|
||||
@@ -73,9 +73,9 @@ install: all $(ACM_CONFIG_FILE)
|
||||
$(INSTALL_DIR) -p $(DESTDIR)$(ACM_SECGEN_CGIDIR)
|
||||
$(INSTALL_PROG) -p $(ACM_INST_CGI) $(DESTDIR)$(ACM_SECGEN_CGIDIR)
|
||||
@ -107,45 +133,41 @@ Index: xen-3.0.3-testing/tools/security/Makefile
|
||||
endif
|
||||
else
|
||||
.PHONY: all
|
||||
Index: xen-3.0.3-testing/tools/pygrub/Makefile
|
||||
Index: xen-3.0.4-testing/tools/pygrub/Makefile
|
||||
===================================================================
|
||||
--- xen-3.0.3-testing.orig/tools/pygrub/Makefile
|
||||
+++ xen-3.0.3-testing/tools/pygrub/Makefile
|
||||
--- xen-3.0.4-testing.orig/tools/pygrub/Makefile
|
||||
+++ xen-3.0.4-testing/tools/pygrub/Makefile
|
||||
@@ -15,7 +15,7 @@ install: all
|
||||
$(INSTALL_DIR) -p $(DESTDIR)/var/lib/xen
|
||||
$(INSTALL_DIR) -p $(DESTDIR)/var/run/xend/boot
|
||||
else
|
||||
install: all
|
||||
- CFLAGS="$(CFLAGS)" python setup.py install --root="$(DESTDIR)"
|
||||
+ CFLAGS="$(CFLAGS)" python setup.py install --root="$(DESTDIR)" --prefix="/usr"
|
||||
$(INSTALL_DIR) -p $(DESTDIR)/var/lib/xen
|
||||
- CC="$(CC)" CFLAGS="$(CFLAGS)" python setup.py install --root="$(DESTDIR)"
|
||||
+ CC="$(CC)" CFLAGS="$(CFLAGS)" python setup.py install --root="$(DESTDIR)" --prefix="/usr"
|
||||
$(INSTALL_DIR) -p $(DESTDIR)/var/run/xend/boot
|
||||
endif
|
||||
|
||||
Index: xen-3.0.3-testing/tools/python/Makefile
|
||||
Index: xen-3.0.4-testing/tools/python/Makefile
|
||||
===================================================================
|
||||
--- xen-3.0.3-testing.orig/tools/python/Makefile
|
||||
+++ xen-3.0.3-testing/tools/python/Makefile
|
||||
--- xen-3.0.4-testing.orig/tools/python/Makefile
|
||||
+++ xen-3.0.4-testing/tools/python/Makefile
|
||||
@@ -14,7 +14,7 @@ install: all
|
||||
CFLAGS="$(CFLAGS)" python setup.py install --home="$(DESTDIR)/usr" --prefix="" --force
|
||||
CC="$(CC)" CFLAGS="$(CFLAGS)" python setup.py install --home="$(DESTDIR)/usr" --prefix="" --force
|
||||
else
|
||||
install: all
|
||||
- CFLAGS="$(CFLAGS)" python setup.py install --root="$(DESTDIR)" --force
|
||||
+ CFLAGS="$(CFLAGS)" python setup.py install --root="$(DESTDIR)" --prefix="/usr" --force
|
||||
- CC="$(CC)" CFLAGS="$(CFLAGS)" python setup.py install --root="$(DESTDIR)" --force
|
||||
+ CC="$(CC)" CFLAGS="$(CFLAGS)" python setup.py install --root="$(DESTDIR)" --prefix="/usr" --force
|
||||
endif
|
||||
|
||||
.PHONY: test
|
||||
Index: xen-3.0.3-testing/xen/Makefile
|
||||
Index: xen-3.0.4-testing/tools/Makefile
|
||||
===================================================================
|
||||
--- xen-3.0.3-testing.orig/xen/Makefile
|
||||
+++ xen-3.0.3-testing/xen/Makefile
|
||||
@@ -31,8 +31,11 @@ _install: $(TARGET).gz
|
||||
$(INSTALL_DATA) $(TARGET)-syms $(DESTDIR)/boot/$(notdir $(TARGET))-syms-$(XEN_FULLVERSION)
|
||||
[ -d $(DESTDIR)/usr/include/xen/io ] || \
|
||||
$(INSTALL_DIR) $(DESTDIR)/usr/include/xen/io
|
||||
+ [ -d $(DESTDIR)/usr/include/xen/hvm ] || \
|
||||
+ $(INSTALL_DIR) $(DESTDIR)/usr/include/xen/hvm
|
||||
$(INSTALL_DATA) include/public/*.h $(DESTDIR)/usr/include/xen
|
||||
$(INSTALL_DATA) include/public/io/*.h $(DESTDIR)/usr/include/xen/io
|
||||
+ $(INSTALL_DATA) include/public/hvm/*.h $(DESTDIR)/usr/include/xen/hvm
|
||||
$(INSTALL_DATA) include/public/COPYING $(DESTDIR)/usr/include/xen
|
||||
--- xen-3.0.4-testing.orig/tools/Makefile
|
||||
+++ xen-3.0.4-testing/tools/Makefile
|
||||
@@ -25,7 +25,6 @@ SUBDIRS-$(LIBXENAPI_BINDINGS) += libxen
|
||||
# These don't cross-compile
|
||||
ifeq ($(XEN_COMPILE_ARCH),$(XEN_TARGET_ARCH))
|
||||
SUBDIRS-y += python
|
||||
-SUBDIRS-y += pygrub
|
||||
endif
|
||||
|
||||
.PHONY: _debug
|
||||
.PHONY: all
|
||||
|
@ -1,30 +0,0 @@
|
||||
Index: xen-3.0.3-testing/docs/Makefile
|
||||
===================================================================
|
||||
--- xen-3.0.3-testing.orig/docs/Makefile
|
||||
+++ xen-3.0.3-testing/docs/Makefile
|
||||
@@ -86,13 +86,13 @@ distclean: clean
|
||||
.PHONY: install
|
||||
install: all
|
||||
rm -rf $(DESTDIR)$(pkgdocdir)
|
||||
- $(INSTALL_DIR) $(DESTDIR)$(pkgdocdir)
|
||||
+ $(INSTALL_DIR) $(DESTDIR)$(pkgdocdir)/html
|
||||
cp -dR ps $(DESTDIR)$(pkgdocdir)
|
||||
cp -dR pdf $(DESTDIR)$(pkgdocdir)
|
||||
+ cp -dR html.done/* $(DESTDIR)$(pkgdocdir)/html
|
||||
$(INSTALL_DIR) $(DESTDIR)$(mandir)
|
||||
cp -dR man1 $(DESTDIR)$(mandir)
|
||||
cp -dR man5 $(DESTDIR)$(mandir)
|
||||
- [ ! -d html ] || cp -dR html $(DESTDIR)$(pkgdocdir)
|
||||
|
||||
pdf/%.pdf: ps/%.ps
|
||||
$(INSTALL_DIR) $(@D)
|
||||
@@ -116,3 +116,9 @@ html/%/index.html: src/%.tex
|
||||
$(LATEX2HTML) -split 0 -show_section_numbers -toc_depth 3 -nonavigation \
|
||||
-numbered_footnotes -local_icons -noinfo -math -dir $(@D) \
|
||||
$< 1>/dev/null 2>/dev/null
|
||||
+ rm -rf html.done/$*/
|
||||
+ mkdir -p html.done/$*/
|
||||
+ cp html/$*/*.html html/$*/*.css html/$*/*.png html.done/$*/
|
||||
+ ln -sf $*.html html.done/$*/index.html
|
||||
+ rm -rf html/
|
||||
+
|
@ -1,16 +0,0 @@
|
||||
Index: xen-unstable/tools/pygrub/src/pygrub
|
||||
===================================================================
|
||||
--- xen-unstable.orig/tools/pygrub/src/pygrub
|
||||
+++ xen-unstable/tools/pygrub/src/pygrub
|
||||
@@ -432,9 +432,9 @@ if __name__ == "__main__":
|
||||
print >> sys.stderr, "Usage: %s [-q|--quiet] [--output=] [--entry=] <image>" %(sys.argv[0],)
|
||||
|
||||
try:
|
||||
- opts, args = getopt.gnu_getopt(sys.argv[1:], 'qh::',
|
||||
+ opts, args = getopt.gnu_getopt(sys.argv[1:], 'qvh::',
|
||||
["quiet", "help", "output=", "entry=",
|
||||
- "isconfig"])
|
||||
+ "isconfig", "root=", "disks=", "verbose="])
|
||||
except getopt.GetoptError:
|
||||
usage()
|
||||
sys.exit(1)
|
@ -1,18 +1,89 @@
|
||||
Index: xen-3.0.3-testing/tools/python/xen/xm/create.py
|
||||
Index: xen-3.0.4-testing/tools/python/xen/xend/XendDomainInfo.py
|
||||
===================================================================
|
||||
--- xen-3.0.3-testing.orig/tools/python/xen/xm/create.py
|
||||
+++ xen-3.0.3-testing/tools/python/xen/xm/create.py
|
||||
@@ -126,7 +126,7 @@ gopts.var('bootloader', val='FILE',
|
||||
use="Path to bootloader.")
|
||||
--- xen-3.0.4-testing.orig/tools/python/xen/xend/XendDomainInfo.py
|
||||
+++ xen-3.0.4-testing/tools/python/xen/xend/XendDomainInfo.py
|
||||
@@ -41,7 +41,7 @@ from xen.xend import balloon, sxp, uuid,
|
||||
from xen.xend import XendRoot, XendNode, XendConfig
|
||||
|
||||
gopts.var('bootargs', val='NAME',
|
||||
- fn=set_value, default=None,
|
||||
+ fn=set_value, default='',
|
||||
use="Arguments to pass to boot loader")
|
||||
from xen.xend.XendConfig import scrub_password
|
||||
-from xen.xend.XendBootloader import bootloader
|
||||
+from xen.xend.XendBootloader import bootloader, bootfilter
|
||||
from xen.xend.XendError import XendError, VmError
|
||||
from xen.xend.XendDevices import XendDevices
|
||||
from xen.xend.xenstore.xstransact import xstransact, complete
|
||||
@@ -1556,13 +1556,17 @@ class XendDomainInfo:
|
||||
if not devtype or not devinfo or devtype not in ('vbd', 'tap'):
|
||||
continue
|
||||
disk = None
|
||||
+ vdisk = None
|
||||
for param in devinfo:
|
||||
if param[0] == 'uname':
|
||||
disk = param[1]
|
||||
- break
|
||||
+ elif param[0] == 'dev':
|
||||
+ vdisk = param[1]
|
||||
|
||||
gopts.var('bootentry', val='NAME',
|
||||
@@ -649,16 +649,17 @@ def run_bootloader(vals, config_image):
|
||||
err("Bootloader isn't executable")
|
||||
if disk is None:
|
||||
continue
|
||||
+ if not bootfilter(blexec, bootloader_args, vdisk):
|
||||
+ continue
|
||||
fn = blkdev_uname_to_file(disk)
|
||||
mounted = devtype == 'tap' and not os.stat(fn).st_rdev
|
||||
if mounted:
|
||||
Index: xen-3.0.4-testing/tools/python/xen/xend/XendBootloader.py
|
||||
===================================================================
|
||||
--- xen-3.0.4-testing.orig/tools/python/xen/xend/XendBootloader.py
|
||||
+++ xen-3.0.4-testing/tools/python/xen/xend/XendBootloader.py
|
||||
@@ -14,6 +14,7 @@
|
||||
|
||||
import os, select, errno, stat
|
||||
import random
|
||||
+import re
|
||||
import shlex
|
||||
from xen.xend import sxp
|
||||
|
||||
@@ -97,3 +98,26 @@ def bootloader(blexec, disk, quiet = Fal
|
||||
pin.input_eof()
|
||||
blcfg = pin.val
|
||||
return blcfg
|
||||
+
|
||||
+def bootfilter(bootloader, bootloader_args, vdisk):
|
||||
+ """Is this virtual disk ok to boot from?"""
|
||||
+ if vdisk.endswith(':disk'):
|
||||
+ vdisk = vdisk[:-5] # temporary work-around for bug 237414
|
||||
+ if bootloader.endswith('domUloader.py'):
|
||||
+ for arg in bootloader_args.split():
|
||||
+ if arg.startswith('--entry='):
|
||||
+ m = re.match(r'^([hsx]v?d[a-z])[0-9]*:[^,]*(,[^,]*)?$', arg[8:])
|
||||
+ if m:
|
||||
+ return vdisk == m.group(1) or vdisk == m.group(2)
|
||||
+ return True
|
||||
+
|
||||
+def bootselector(bootloader, bootloader_args, disks):
|
||||
+ """Returns the desired disk to boot from.
|
||||
+ @param disks List of (pdev, vdev, ...) tuples.
|
||||
+ """
|
||||
+ if bootloader.endswith('domUloader.py'):
|
||||
+ for disk in disks:
|
||||
+ if bootfilter(bootloader, bootloader_args, disk[1]):
|
||||
+ return disk
|
||||
+ return disks[0]
|
||||
+
|
||||
Index: xen-3.0.4-testing/tools/python/xen/xm/create.py
|
||||
===================================================================
|
||||
--- xen-3.0.4-testing.orig/tools/python/xen/xm/create.py
|
||||
+++ xen-3.0.4-testing/tools/python/xen/xm/create.py
|
||||
@@ -29,7 +29,7 @@ import xmlrpclib
|
||||
from xen.xend import sxp
|
||||
from xen.xend import PrettyPrint
|
||||
import xen.xend.XendClient
|
||||
-from xen.xend.XendBootloader import bootloader
|
||||
+from xen.xend.XendBootloader import bootloader, bootselector
|
||||
from xen.util import blkif
|
||||
from xen.util import security
|
||||
|
||||
@@ -710,14 +710,15 @@ def run_bootloader(vals, config_image):
|
||||
err("Bootloader '%s' isn't executable" % vals.bootloader)
|
||||
if len(vals.disk) < 1:
|
||||
err("No disks configured and boot loader requested")
|
||||
- (uname, dev, mode, backend) = vals.disk[0]
|
||||
@ -22,102 +93,10 @@ Index: xen-3.0.3-testing/tools/python/xen/xm/create.py
|
||||
warn("The bootentry option is deprecated. Use bootargs and pass "
|
||||
"--entry= directly.")
|
||||
vals.bootargs = "--entry=%s" %(vals.bootentry,)
|
||||
+ if vals.root:
|
||||
+ vals.bootargs += " --root=%s" % vals.root.split()[0]
|
||||
+ vals.bootargs += " --disks=\"%s\"" % str(vals.disk)
|
||||
|
||||
- return bootloader(vals.bootloader, file, not vals.console_autoconnect,
|
||||
- vals.bootargs, config_image)
|
||||
+ return bootloader(vals.bootloader, not vals.console_autoconnect,
|
||||
+ vals.dryrun, vals.bootargs, config_image)
|
||||
+ bootdisk = bootselector(vals.bootloader, vals.bootargs, vals.disk)
|
||||
+ uname = bootdisk[0]
|
||||
+ file = blkif.blkdev_uname_to_file(uname)
|
||||
return bootloader(vals.bootloader, file, not vals.console_autoconnect,
|
||||
vals.bootargs, config_image)
|
||||
|
||||
def make_config(vals):
|
||||
"""Create the domain configuration.
|
||||
Index: xen-3.0.3-testing/tools/python/xen/xend/XendBootloader.py
|
||||
===================================================================
|
||||
--- xen-3.0.3-testing.orig/tools/python/xen/xend/XendBootloader.py
|
||||
+++ xen-3.0.3-testing/tools/python/xen/xend/XendBootloader.py
|
||||
@@ -20,11 +20,9 @@ import shlex
|
||||
from XendLogging import log
|
||||
from XendError import VmError
|
||||
|
||||
-def bootloader(blexec, disk, quiet = 0, blargs = None, imgcfg = None):
|
||||
- """Run the boot loader executable on the given disk and return a
|
||||
- config image.
|
||||
+def bootloader(blexec, quiet = 0, dryrun = 0, blargs = None, imgcfg = None):
|
||||
+ """Run the boot loader executable and return a config image.
|
||||
@param blexec Binary to use as the boot loader
|
||||
- @param disk Disk to run the boot loader on.
|
||||
@param quiet Run in non-interactive mode, just booting the default.
|
||||
@param blargs Arguments to pass to the bootloader."""
|
||||
|
||||
@@ -32,10 +30,6 @@ def bootloader(blexec, disk, quiet = 0,
|
||||
msg = "Bootloader isn't executable"
|
||||
log.error(msg)
|
||||
raise VmError(msg)
|
||||
- if not os.access(disk, os.R_OK):
|
||||
- msg = "Disk isn't accessible"
|
||||
- log.error(msg)
|
||||
- raise VmError(msg)
|
||||
|
||||
while True:
|
||||
fifo = "/var/lib/xen/xenbl.%s" %(random.randint(0, 32000),)
|
||||
@@ -48,10 +42,11 @@ def bootloader(blexec, disk, quiet = 0,
|
||||
args = [ blexec ]
|
||||
if quiet:
|
||||
args.append("-q")
|
||||
+ if dryrun:
|
||||
+ args.append("--dryrun")
|
||||
args.append("--output=%s" %(fifo,))
|
||||
if blargs is not None:
|
||||
args.extend(shlex.split(blargs))
|
||||
- args.append(disk)
|
||||
|
||||
try:
|
||||
os.execvp(args[0], args)
|
||||
@@ -68,6 +63,7 @@ def bootloader(blexec, disk, quiet = 0,
|
||||
continue
|
||||
break
|
||||
ret = ""
|
||||
+ # TODO: Add timeout, cleanup and raise VmError if it occurs
|
||||
while 1:
|
||||
select.select([r], [], [])
|
||||
s = os.read(r, 1024)
|
||||
Index: xen-3.0.3-testing/tools/python/xen/xend/XendDomainInfo.py
|
||||
===================================================================
|
||||
--- xen-3.0.3-testing.orig/tools/python/xen/xend/XendDomainInfo.py
|
||||
+++ xen-3.0.3-testing/tools/python/xen/xend/XendDomainInfo.py
|
||||
@@ -1743,18 +1743,27 @@ class XendDomainInfo:
|
||||
if not self.info['bootloader']:
|
||||
return
|
||||
blcfg = None
|
||||
- # FIXME: this assumes that we want to use the first disk device
|
||||
+ """This code is currently unneeded, but will be used
|
||||
+ again when boot device selection is more dynamic.
|
||||
+ vbds = []
|
||||
for (n,c) in self.info['device']:
|
||||
if not n or not c or not(n in ["vbd", "tap"]):
|
||||
continue
|
||||
disk = sxp.child_value(c, "uname")
|
||||
if disk is None:
|
||||
continue
|
||||
- fn = blkdev_uname_to_file(disk)
|
||||
- blcfg = bootloader(self.info['bootloader'], fn, 1,
|
||||
- self.info['bootloader_args'],
|
||||
- self.info['image'])
|
||||
- break
|
||||
+ vbds.append([sxp.child_value(c, "uname"),
|
||||
+ sxp.child_value(c, "dev"),
|
||||
+ sxp.child_value(c, "mode"),
|
||||
+ sxp.child_value(c, "backend")])
|
||||
+ if vbds:
|
||||
+ bootargs = self.info['bootloader_args'] + \
|
||||
+ " --disks=\"%s\"" % str(vbds)
|
||||
+ if self.info['root']:
|
||||
+ bootargs += " --root=%s" % self.info['root'].split()[0]
|
||||
+ """
|
||||
+ blcfg = bootloader(self.info['bootloader'], 1, 0,
|
||||
+ self.info['bootloader_args'], self.info['image'])
|
||||
if blcfg is None:
|
||||
msg = "Had a bootloader specified, but can't find disk"
|
||||
log.error(msg)
|
||||
|
406
xen-generate-foreign-headers.diff
Normal file
406
xen-generate-foreign-headers.diff
Normal file
@ -0,0 +1,406 @@
|
||||
Generate headers with arch-specific structs.
|
||||
|
||||
This patch adds a script to generate headers with arch-specific
|
||||
structs which can be included on any architecture. Can be used
|
||||
to deal with structs of "foreign" architectures, needed for
|
||||
32-on-64 support for example.
|
||||
|
||||
Signed-off-by: Gerd Hoffmann <kraxel@suse.de>
|
||||
---
|
||||
tools/Rules.mk | 2
|
||||
xen/Makefile | 5
|
||||
xen/include/public/foreign/Makefile | 30 +++++
|
||||
xen/include/public/foreign/mkchecker.py | 58 +++++++++++
|
||||
xen/include/public/foreign/mkheader.py | 153 ++++++++++++++++++++++++++++++
|
||||
xen/include/public/foreign/reference.size | 17 +++
|
||||
xen/include/public/foreign/structs.py | 49 +++++++++
|
||||
7 files changed, 314 insertions(+)
|
||||
|
||||
Index: xen-3.0.4-testing/xen/include/public/foreign/Makefile
|
||||
===================================================================
|
||||
--- /dev/null
|
||||
+++ xen-3.0.4-testing/xen/include/public/foreign/Makefile
|
||||
@@ -0,0 +1,37 @@
|
||||
+XEN_ROOT := ../../../..
|
||||
+include $(XEN_ROOT)/tools/Rules.mk
|
||||
+
|
||||
+architectures := x86_32 x86_64 ia64
|
||||
+headers := $(patsubst %, %.h, $(architectures))
|
||||
+scripts := $(wildcard *.py)
|
||||
+
|
||||
+.PHONY: all clean check-headers
|
||||
+all: $(headers) check-headers
|
||||
+
|
||||
+clean:
|
||||
+ rm -f $(headers)
|
||||
+ rm -f checker checker.c $(XEN_TARGET_ARCH).size
|
||||
+ rm -f *.pyc *.o *~
|
||||
+
|
||||
+check-headers: checker
|
||||
+ifeq ($(CROSS_COMPILE),)
|
||||
+ ./checker > $(XEN_TARGET_ARCH).size
|
||||
+ diff -u reference.size $(XEN_TARGET_ARCH).size
|
||||
+else
|
||||
+ @echo "cross build: skipping check"
|
||||
+endif
|
||||
+
|
||||
+x86_32.h: ../arch-x86/xen-x86_32.h ../arch-x86/xen.h ../xen.h $(scripts)
|
||||
+ python mkheader.py $* $@ $(filter %.h,$^)
|
||||
+
|
||||
+x86_64.h: ../arch-x86/xen-x86_64.h ../arch-x86/xen.h ../xen.h $(scripts)
|
||||
+ python mkheader.py $* $@ $(filter %.h,$^)
|
||||
+
|
||||
+ia64.h: ../arch-ia64.h ../xen.h $(scripts)
|
||||
+ python mkheader.py $* $@ $(filter %.h,$^)
|
||||
+
|
||||
+checker: checker.c $(headers)
|
||||
+ $(HOSTCC) -o $@ $<
|
||||
+
|
||||
+checker.c: $(scripts)
|
||||
+ python mkchecker.py $(XEN_TARGET_ARCH) $@ $(architectures)
|
||||
Index: xen-3.0.4-testing/xen/include/public/foreign/mkheader.py
|
||||
===================================================================
|
||||
--- /dev/null
|
||||
+++ xen-3.0.4-testing/xen/include/public/foreign/mkheader.py
|
||||
@@ -0,0 +1,153 @@
|
||||
+#!/usr/bin/python
|
||||
+
|
||||
+import sys, re;
|
||||
+from structs import structs, defines;
|
||||
+
|
||||
+# command line arguments
|
||||
+arch = sys.argv[1];
|
||||
+outfile = sys.argv[2];
|
||||
+infiles = sys.argv[3:];
|
||||
+
|
||||
+
|
||||
+###########################################################################
|
||||
+# configuration #2: architecture information
|
||||
+
|
||||
+inttypes = {};
|
||||
+header = {};
|
||||
+footer = {};
|
||||
+
|
||||
+# x86_32
|
||||
+inttypes["x86_32"] = {
|
||||
+ "unsigned long" : "uint32_t",
|
||||
+ "long" : "uint32_t",
|
||||
+ "xen_pfn_t" : "uint32_t",
|
||||
+};
|
||||
+header["x86_32"] = """
|
||||
+#define __i386___X86_32 1
|
||||
+#pragma pack(push, 4)
|
||||
+""";
|
||||
+footer["x86_32"] = """
|
||||
+#pragma pack(pop)
|
||||
+""";
|
||||
+
|
||||
+# x86_64
|
||||
+inttypes["x86_64"] = {
|
||||
+ "unsigned long" : "__align8__ uint64_t",
|
||||
+ "long" : "__align8__ uint64_t",
|
||||
+ "xen_pfn_t" : "__align8__ uint64_t",
|
||||
+};
|
||||
+header["x86_64"] = """
|
||||
+#ifdef __GNUC__
|
||||
+# define __DECL_REG(name) union { uint64_t r ## name, e ## name; }
|
||||
+# define __align8__ __attribute__((aligned (8)))
|
||||
+#else
|
||||
+# define __DECL_REG(name) uint64_t r ## name
|
||||
+# define __align8__ FIXME
|
||||
+#endif
|
||||
+#define __x86_64___X86_64 1
|
||||
+""";
|
||||
+
|
||||
+# ia64
|
||||
+inttypes["ia64"] = {
|
||||
+ "unsigned long" : "__align8__ uint64_t",
|
||||
+ "long" : "__align8__ uint64_t",
|
||||
+ "xen_pfn_t" : "__align8__ uint64_t",
|
||||
+ "long double" : "__align16__ ldouble_t",
|
||||
+};
|
||||
+header["ia64"] = """
|
||||
+#define __align8__ __attribute__((aligned (8)))
|
||||
+#define __align16__ __attribute__((aligned (16)))
|
||||
+typedef unsigned char ldouble_t[16];
|
||||
+""";
|
||||
+
|
||||
+
|
||||
+###########################################################################
|
||||
+# main
|
||||
+
|
||||
+input = "";
|
||||
+output = "";
|
||||
+fileid = re.sub("[-.]", "_", "__FOREIGN_%s__" % outfile.upper());
|
||||
+
|
||||
+# read input header files
|
||||
+for name in infiles:
|
||||
+ f = open(name, "r");
|
||||
+ input += f.read();
|
||||
+ f.close();
|
||||
+
|
||||
+# add header
|
||||
+output += """
|
||||
+/*
|
||||
+ * public xen defines and struct for %s
|
||||
+ * generated by %s -- DO NOT EDIT
|
||||
+ */
|
||||
+
|
||||
+#ifndef %s
|
||||
+#define %s 1
|
||||
+
|
||||
+""" % (arch, sys.argv[0], fileid, fileid)
|
||||
+
|
||||
+if arch in header:
|
||||
+ output += header[arch];
|
||||
+ output += "\n";
|
||||
+
|
||||
+# add defines to output
|
||||
+for line in re.findall("#define[^\n]+", input):
|
||||
+ for define in defines:
|
||||
+ regex = "#define\s+%s\\b" % define;
|
||||
+ match = re.search(regex, line);
|
||||
+ if None == match:
|
||||
+ continue;
|
||||
+ if define.upper()[0] == define[0]:
|
||||
+ replace = define + "_" + arch.upper();
|
||||
+ else:
|
||||
+ replace = define + "_" + arch;
|
||||
+ regex = "\\b%s\\b" % define;
|
||||
+ output += re.sub(regex, replace, line) + "\n";
|
||||
+output += "\n";
|
||||
+
|
||||
+# delete defines, comments, empty lines
|
||||
+input = re.sub("#define[^\n]+\n", "", input);
|
||||
+input = re.compile("/\*(.*?)\*/", re.S).sub("", input)
|
||||
+input = re.compile("\n\s*\n", re.S).sub("\n", input);
|
||||
+
|
||||
+# add structs to output
|
||||
+for struct in structs:
|
||||
+ regex = "struct\s+%s\s*\{(.*?)\n\};" % struct;
|
||||
+ match = re.search(regex, input, re.S)
|
||||
+ if None == match:
|
||||
+ output += "#define %s_has_no_%s 1\n" % (arch, struct);
|
||||
+ else:
|
||||
+ output += "struct %s_%s {%s\n};\n" % (struct, arch, match.group(1));
|
||||
+ output += "typedef struct %s_%s %s_%s_t;\n" % (struct, arch, struct, arch);
|
||||
+ output += "\n";
|
||||
+
|
||||
+# add footer
|
||||
+if arch in footer:
|
||||
+ output += footer[arch];
|
||||
+ output += "\n";
|
||||
+output += "#endif /* %s */\n" % fileid;
|
||||
+
|
||||
+# replace: defines
|
||||
+for define in defines:
|
||||
+ if define.upper()[0] == define[0]:
|
||||
+ replace = define + "_" + arch.upper();
|
||||
+ else:
|
||||
+ replace = define + "_" + arch;
|
||||
+ output = re.sub("\\b%s\\b" % define, replace, output);
|
||||
+
|
||||
+# replace: structs + struct typedefs
|
||||
+for struct in structs:
|
||||
+ output = re.sub("\\b(struct\s+%s)\\b" % struct, "\\1_%s" % arch, output);
|
||||
+ output = re.sub("\\b(%s)_t\\b" % struct, "\\1_%s_t" % arch, output);
|
||||
+
|
||||
+# replace: integer types
|
||||
+integers = inttypes[arch].keys();
|
||||
+integers.sort(lambda a, b: cmp(len(b),len(a)));
|
||||
+for type in integers:
|
||||
+ output = re.sub("\\b%s\\b" % type, inttypes[arch][type], output);
|
||||
+
|
||||
+# print results
|
||||
+f = open(outfile, "w");
|
||||
+f.write(output);
|
||||
+f.close;
|
||||
+
|
||||
Index: xen-3.0.4-testing/xen/include/public/foreign/structs.py
|
||||
===================================================================
|
||||
--- /dev/null
|
||||
+++ xen-3.0.4-testing/xen/include/public/foreign/structs.py
|
||||
@@ -0,0 +1,52 @@
|
||||
+# configuration: what needs translation
|
||||
+
|
||||
+structs = [ "start_info",
|
||||
+ "trap_info",
|
||||
+ "pt_fpreg",
|
||||
+ "cpu_user_regs",
|
||||
+ "xen_ia64_boot_param",
|
||||
+ "ia64_tr_entry",
|
||||
+ "vcpu_extra_regs",
|
||||
+ "vcpu_guest_context",
|
||||
+ "arch_vcpu_info",
|
||||
+ "vcpu_time_info",
|
||||
+ "vcpu_info",
|
||||
+ "arch_shared_info",
|
||||
+ "shared_info" ];
|
||||
+
|
||||
+defines = [ "__i386__",
|
||||
+ "__x86_64__",
|
||||
+
|
||||
+ "FLAT_RING1_CS",
|
||||
+ "FLAT_RING1_DS",
|
||||
+ "FLAT_RING1_SS",
|
||||
+
|
||||
+ "FLAT_RING3_CS64",
|
||||
+ "FLAT_RING3_DS64",
|
||||
+ "FLAT_RING3_SS64",
|
||||
+ "FLAT_KERNEL_CS64",
|
||||
+ "FLAT_KERNEL_DS64",
|
||||
+ "FLAT_KERNEL_SS64",
|
||||
+
|
||||
+ "FLAT_KERNEL_CS",
|
||||
+ "FLAT_KERNEL_DS",
|
||||
+ "FLAT_KERNEL_SS",
|
||||
+
|
||||
+ # x86_{32,64}
|
||||
+ "_VGCF_i387_valid",
|
||||
+ "VGCF_i387_valid",
|
||||
+ "_VGCF_in_kernel",
|
||||
+ "VGCF_in_kernel",
|
||||
+ "_VGCF_failsafe_disables_events",
|
||||
+ "VGCF_failsafe_disables_events",
|
||||
+ "_VGCF_syscall_disables_events",
|
||||
+ "VGCF_syscall_disables_events",
|
||||
+
|
||||
+ # ia64
|
||||
+ "VGCF_EXTRA_REGS",
|
||||
+
|
||||
+ # all archs
|
||||
+ "xen_pfn_to_cr3",
|
||||
+ "MAX_VIRT_CPUS",
|
||||
+ "MAX_GUEST_CMDLINE" ];
|
||||
+
|
||||
Index: xen-3.0.4-testing/xen/include/public/foreign/reference.size
|
||||
===================================================================
|
||||
--- /dev/null
|
||||
+++ xen-3.0.4-testing/xen/include/public/foreign/reference.size
|
||||
@@ -0,0 +1,17 @@
|
||||
+
|
||||
+structs | x86_32 x86_64 ia64
|
||||
+
|
||||
+start_info | 1104 1152 1152
|
||||
+trap_info | 8 16 -
|
||||
+pt_fpreg | - - 16
|
||||
+cpu_user_regs | 68 200 496
|
||||
+xen_ia64_boot_param | - - 96
|
||||
+ia64_tr_entry | - - 32
|
||||
+vcpu_extra_regs | - - 536
|
||||
+vcpu_guest_context | 2800 5168 1056
|
||||
+arch_vcpu_info | 24 16 0
|
||||
+vcpu_time_info | 32 32 32
|
||||
+vcpu_info | 64 64 48
|
||||
+arch_shared_info | 268 280 272
|
||||
+shared_info | 2584 3368 4384
|
||||
+
|
||||
Index: xen-3.0.4-testing/xen/Makefile
|
||||
===================================================================
|
||||
--- xen-3.0.4-testing.orig/xen/Makefile
|
||||
+++ xen-3.0.4-testing/xen/Makefile
|
||||
@@ -36,10 +36,13 @@ _install: $(TARGET).gz
|
||||
$(INSTALL_DIR) $(DESTDIR)/usr/include/xen/hvm
|
||||
[ -d $(DESTDIR)/usr/include/xen/io ] || \
|
||||
$(INSTALL_DIR) $(DESTDIR)/usr/include/xen/io
|
||||
+ [ -d $(DESTDIR)/usr/include/xen/foreign ] || \
|
||||
+ $(INSTALL_DIR) $(DESTDIR)/usr/include/xen/foreign
|
||||
$(INSTALL_DATA) include/public/*.h $(DESTDIR)/usr/include/xen
|
||||
$(INSTALL_DATA) include/public/arch-x86/*.h $(DESTDIR)/usr/include/xen/arch-x86
|
||||
$(INSTALL_DATA) include/public/hvm/*.h $(DESTDIR)/usr/include/xen/hvm
|
||||
$(INSTALL_DATA) include/public/io/*.h $(DESTDIR)/usr/include/xen/io
|
||||
+ $(INSTALL_DATA) include/public/foreign/*.h $(DESTDIR)/usr/include/xen/foreign
|
||||
$(INSTALL_DATA) include/public/COPYING $(DESTDIR)/usr/include/xen
|
||||
|
||||
.PHONY: _debug
|
||||
@@ -49,6 +52,7 @@ _debug:
|
||||
.PHONY: _clean
|
||||
_clean: delete-unfresh-files
|
||||
$(MAKE) -C tools clean
|
||||
+ $(MAKE) -C include/public/foreign clean
|
||||
$(MAKE) -f $(BASEDIR)/Rules.mk -C include clean
|
||||
$(MAKE) -f $(BASEDIR)/Rules.mk -C common clean
|
||||
$(MAKE) -f $(BASEDIR)/Rules.mk -C drivers clean
|
||||
@@ -68,6 +72,7 @@ $(TARGET).gz: $(TARGET)
|
||||
|
||||
$(TARGET): delete-unfresh-files
|
||||
$(MAKE) -C tools
|
||||
+ $(MAKE) -C include/public/foreign
|
||||
$(MAKE) -f $(BASEDIR)/Rules.mk include/xen/compile.h
|
||||
$(MAKE) -f $(BASEDIR)/Rules.mk include/xen/acm_policy.h
|
||||
[ -e include/asm ] || ln -sf asm-$(TARGET_ARCH) include/asm
|
||||
Index: xen-3.0.4-testing/xen/include/public/foreign/mkchecker.py
|
||||
===================================================================
|
||||
--- /dev/null
|
||||
+++ xen-3.0.4-testing/xen/include/public/foreign/mkchecker.py
|
||||
@@ -0,0 +1,58 @@
|
||||
+#!/usr/bin/python
|
||||
+
|
||||
+import sys;
|
||||
+from structs import structs;
|
||||
+
|
||||
+# command line arguments
|
||||
+arch = sys.argv[1];
|
||||
+outfile = sys.argv[2];
|
||||
+archs = sys.argv[3:];
|
||||
+
|
||||
+f = open(outfile, "w");
|
||||
+f.write('''
|
||||
+/*
|
||||
+ * sanity checks for generated foreign headers:
|
||||
+ * - verify struct sizes
|
||||
+ *
|
||||
+ * generated by %s -- DO NOT EDIT
|
||||
+ */
|
||||
+#include <stdio.h>
|
||||
+#include <stdlib.h>
|
||||
+#include <stddef.h>
|
||||
+#include <inttypes.h>
|
||||
+#include "../xen.h"
|
||||
+''');
|
||||
+
|
||||
+for a in archs:
|
||||
+ f.write('#include "%s.h"\n' % a);
|
||||
+
|
||||
+f.write('int main(int argc, char *argv[])\n{\n');
|
||||
+
|
||||
+f.write('\tprintf("\\n");');
|
||||
+f.write('printf("%-20s |", "structs");\n');
|
||||
+for a in archs:
|
||||
+ f.write('\tprintf("%%8s", "%s");\n' % a);
|
||||
+f.write('\tprintf("\\n");');
|
||||
+
|
||||
+f.write('\tprintf("\\n");');
|
||||
+for struct in structs:
|
||||
+ f.write('\tprintf("%%-20s |", "%s");\n' % struct);
|
||||
+ for a in archs:
|
||||
+ if a == arch:
|
||||
+ s = struct; # native
|
||||
+ else:
|
||||
+ s = struct + "_" + a;
|
||||
+ f.write('#ifdef %s_has_no_%s\n' % (a, struct));
|
||||
+ f.write('\tprintf("%8s", "-");\n');
|
||||
+ f.write("#else\n");
|
||||
+ f.write('\tprintf("%%8zd", sizeof(struct %s));\n' % s);
|
||||
+ f.write("#endif\n");
|
||||
+
|
||||
+ f.write('\tprintf("\\n");\n\n');
|
||||
+
|
||||
+f.write('\tprintf("\\n");\n');
|
||||
+f.write('\texit(0);\n');
|
||||
+f.write('}\n');
|
||||
+
|
||||
+f.close();
|
||||
+
|
||||
Index: xen-3.0.4-testing/tools/Rules.mk
|
||||
===================================================================
|
||||
--- xen-3.0.4-testing.orig/tools/Rules.mk
|
||||
+++ xen-3.0.4-testing/tools/Rules.mk
|
||||
@@ -52,5 +52,7 @@ mk-symlinks-xen:
|
||||
( cd xen/io && ln -sf ../../$(XEN_ROOT)/xen/include/public/io/*.h . )
|
||||
mkdir -p xen/arch-x86
|
||||
( cd xen/arch-x86 && ln -sf ../../$(XEN_ROOT)/xen/include/public/arch-x86/*.h . )
|
||||
+ mkdir -p xen/foreign
|
||||
+ ( cd xen/foreign && ln -sf ../../$(XEN_ROOT)/xen/include/public/foreign/*.h . )
|
||||
|
||||
mk-symlinks: mk-symlinks-xen mk-symlinks-$(XEN_OS)
|
@ -1,8 +1,8 @@
|
||||
Index: xen-3.0.3-testing/tools/examples/xend-config.sxp
|
||||
Index: xen-3.0.4-testing/tools/examples/xend-config.sxp
|
||||
===================================================================
|
||||
--- xen-3.0.3-testing.orig/tools/examples/xend-config.sxp
|
||||
+++ xen-3.0.3-testing/tools/examples/xend-config.sxp
|
||||
@@ -76,7 +76,8 @@
|
||||
--- xen-3.0.4-testing.orig/tools/examples/xend-config.sxp
|
||||
+++ xen-3.0.4-testing/tools/examples/xend-config.sxp
|
||||
@@ -116,7 +116,8 @@
|
||||
#
|
||||
# (network-script 'network-bridge netdev=eth1')
|
||||
#
|
||||
@ -12,10 +12,10 @@ Index: xen-3.0.3-testing/tools/examples/xend-config.sxp
|
||||
#
|
||||
# (network-script 'network-bridge bridge=<name>')
|
||||
#
|
||||
Index: xen-3.0.3-testing/tools/ioemu/vl.c
|
||||
Index: xen-3.0.4-testing/tools/ioemu/vl.c
|
||||
===================================================================
|
||||
--- xen-3.0.3-testing.orig/tools/ioemu/vl.c
|
||||
+++ xen-3.0.3-testing/tools/ioemu/vl.c
|
||||
--- xen-3.0.4-testing.orig/tools/ioemu/vl.c
|
||||
+++ xen-3.0.4-testing/tools/ioemu/vl.c
|
||||
@@ -89,7 +89,6 @@
|
||||
#include "exec-all.h"
|
||||
|
||||
@ -24,7 +24,7 @@ Index: xen-3.0.3-testing/tools/ioemu/vl.c
|
||||
|
||||
//#define DEBUG_UNUSED_IOPORT
|
||||
//#define DEBUG_IOPORT
|
||||
@@ -3773,10 +3772,10 @@ int net_client_init(const char *str)
|
||||
@@ -3779,10 +3778,10 @@ int net_client_init(const char *str)
|
||||
if (get_param_value(setup_script, sizeof(setup_script), "script", p) == 0) {
|
||||
pstrcpy(setup_script, sizeof(setup_script), DEFAULT_NETWORK_SCRIPT);
|
||||
}
|
||||
@ -39,33 +39,33 @@ Index: xen-3.0.3-testing/tools/ioemu/vl.c
|
||||
}
|
||||
} else
|
||||
#endif
|
||||
Index: xen-3.0.3-testing/tools/python/xen/xend/image.py
|
||||
Index: xen-3.0.4-testing/tools/python/xen/xend/image.py
|
||||
===================================================================
|
||||
--- xen-3.0.3-testing.orig/tools/python/xen/xend/image.py
|
||||
+++ xen-3.0.3-testing/tools/python/xen/xend/image.py
|
||||
@@ -339,13 +339,16 @@ class HVMImageHandler(ImageHandler):
|
||||
mac = sxp.child_value(info, 'mac')
|
||||
if mac == None:
|
||||
mac = randomMAC()
|
||||
- bridge = sxp.child_value(info, 'bridge', 'xenbr0')
|
||||
+ bridge = sxp.child_value(info, 'bridge', None)
|
||||
model = sxp.child_value(info, 'model', 'rtl8139')
|
||||
ret.append("-net")
|
||||
ret.append("nic,vlan=%d,macaddr=%s,model=%s" %
|
||||
(nics, mac, model))
|
||||
ret.append("-net")
|
||||
- ret.append("tap,vlan=%d,bridge=%s" % (nics, bridge))
|
||||
+ net = "tap,vlan=%d" % (nics,)
|
||||
+ if bridge:
|
||||
+ net += ",bridge=%s" % (bridge,)
|
||||
+ ret.append(net)
|
||||
--- xen-3.0.4-testing.orig/tools/python/xen/xend/image.py
|
||||
+++ xen-3.0.4-testing/tools/python/xen/xend/image.py
|
||||
@@ -419,13 +419,16 @@ class HVMImageHandler(ImageHandler):
|
||||
mac = devinfo.get('mac')
|
||||
if mac is None:
|
||||
mac = randomMAC()
|
||||
- bridge = devinfo.get('bridge', 'xenbr0')
|
||||
+ bridge = devinfo.get('bridge', None)
|
||||
model = devinfo.get('model', 'rtl8139')
|
||||
ret.append("-net")
|
||||
ret.append("nic,vlan=%d,macaddr=%s,model=%s" %
|
||||
(nics, mac, model))
|
||||
ret.append("-net")
|
||||
- ret.append("tap,vlan=%d,bridge=%s" % (nics, bridge))
|
||||
+ net = "tap,vlan=%d" % (nics,)
|
||||
+ if bridge:
|
||||
+ net += ",bridge=%s" % (bridge,)
|
||||
+ ret.append(net)
|
||||
|
||||
return ret
|
||||
|
||||
def configVNC(self, config):
|
||||
Index: xen-3.0.3-testing/tools/ioemu/target-i386-dm/qemu-ifup
|
||||
Index: xen-3.0.4-testing/tools/ioemu/target-i386-dm/qemu-ifup
|
||||
===================================================================
|
||||
--- xen-3.0.3-testing.orig/tools/ioemu/target-i386-dm/qemu-ifup
|
||||
+++ xen-3.0.3-testing/tools/ioemu/target-i386-dm/qemu-ifup
|
||||
--- xen-3.0.4-testing.orig/tools/ioemu/target-i386-dm/qemu-ifup
|
||||
+++ xen-3.0.4-testing/tools/ioemu/target-i386-dm/qemu-ifup
|
||||
@@ -1,10 +1,11 @@
|
||||
#!/bin/sh
|
||||
|
||||
|
@ -1,15 +1,15 @@
|
||||
PAE must be on for 64-on-64 to work at all.
|
||||
|
||||
Index: xen-3.0.3-testing/tools/python/xen/xend/image.py
|
||||
Index: xen-3.0.4-testing/tools/python/xen/xend/image.py
|
||||
===================================================================
|
||||
--- xen-3.0.3-testing.orig/tools/python/xen/xend/image.py
|
||||
+++ xen-3.0.3-testing/tools/python/xen/xend/image.py
|
||||
@@ -263,7 +263,7 @@ class HVMImageHandler(ImageHandler):
|
||||
--- xen-3.0.4-testing.orig/tools/python/xen/xend/image.py
|
||||
+++ xen-3.0.4-testing/tools/python/xen/xend/image.py
|
||||
@@ -334,7 +334,7 @@ class HVMImageHandler(ImageHandler):
|
||||
|
||||
self.dmargs += self.configVNC(imageConfig)
|
||||
|
||||
- self.pae = int(sxp.child_value(imageConfig, 'pae', 0))
|
||||
+ self.pae = int(sxp.child_value(imageConfig, 'pae', 1))
|
||||
|
||||
self.acpi = int(sxp.child_value(imageConfig, 'acpi', 0))
|
||||
self.apic = int(sxp.child_value(imageConfig, 'apic', 0))
|
||||
- self.pae = imageConfig['hvm'].get('pae', 0)
|
||||
+ self.pae = imageConfig['hvm'].get('pae', 1)
|
||||
self.apic = imageConfig['hvm'].get('apic', 0)
|
||||
self.acpi = imageConfig['hvm']['devices'].get('acpi', 0)
|
||||
|
||||
|
@ -1,8 +1,8 @@
|
||||
Index: xen-3.0.3-testing/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c
|
||||
Index: xen-3.0.4-testing/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c
|
||||
===================================================================
|
||||
--- xen-3.0.3-testing.orig/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c
|
||||
+++ xen-3.0.3-testing/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c
|
||||
@@ -275,6 +275,13 @@ static int __devinit netfront_probe(stru
|
||||
--- xen-3.0.4-testing.orig/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c
|
||||
+++ xen-3.0.4-testing/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c
|
||||
@@ -282,6 +282,13 @@ static int __devinit netfront_probe(stru
|
||||
int err;
|
||||
struct net_device *netdev;
|
||||
struct netfront_info *info;
|
||||
|
@ -1,680 +0,0 @@
|
||||
From: Jan Beulich
|
||||
Bugzilla #192150
|
||||
|
||||
Index: xen-unstable/xen/arch/x86/domain_build.c
|
||||
===================================================================
|
||||
--- xen-unstable.orig/xen/arch/x86/domain_build.c
|
||||
+++ xen-unstable/xen/arch/x86/domain_build.c
|
||||
@@ -33,6 +33,11 @@
|
||||
extern unsigned long initial_images_nrpages(void);
|
||||
extern void discard_initial_images(void);
|
||||
|
||||
+/* I/O-port Xen-enforced or admin-specified access control. */
|
||||
+struct rangeset *ioport_caps = NULL;
|
||||
+/* I/O-port admin-specified non-special access requirements. */
|
||||
+struct rangeset *ioport_emul = NULL;
|
||||
+
|
||||
static long dom0_nrpages;
|
||||
|
||||
/*
|
||||
@@ -64,6 +69,12 @@ integer_param("dom0_max_vcpus", opt_dom0
|
||||
static unsigned int opt_dom0_shadow;
|
||||
boolean_param("dom0_shadow", opt_dom0_shadow);
|
||||
|
||||
+static char opt_ioports_noemul[200] = "";
|
||||
+string_param("ioports_noemul", opt_ioports_noemul);
|
||||
+
|
||||
+static char opt_ioports_disable[200] = "";
|
||||
+string_param("ioports_disable", opt_ioports_disable);
|
||||
+
|
||||
static char opt_dom0_ioports_disable[200] = "";
|
||||
string_param("dom0_ioports_disable", opt_dom0_ioports_disable);
|
||||
|
||||
@@ -103,10 +114,10 @@ static struct page_info *alloc_chunk(str
|
||||
return page;
|
||||
}
|
||||
|
||||
-static void process_dom0_ioports_disable(void)
|
||||
+static void process_ioports(char *opt)
|
||||
{
|
||||
unsigned long io_from, io_to;
|
||||
- char *t, *u, *s = opt_dom0_ioports_disable;
|
||||
+ char *t, *u, *s = opt;
|
||||
|
||||
if ( *s == '\0' )
|
||||
return;
|
||||
@@ -118,7 +129,9 @@ static void process_dom0_ioports_disable
|
||||
{
|
||||
parse_error:
|
||||
printk("Invalid ioport range <%s> "
|
||||
- "in dom0_ioports_disable, skipping\n", t);
|
||||
+ "in %sioports_%s, skipping\n", t,
|
||||
+ opt == opt_dom0_ioports_disable ? "dom0_" : "",
|
||||
+ opt != opt_ioports_noemul ? "disable" : "noemul");
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -132,11 +145,26 @@ static void process_dom0_ioports_disable
|
||||
if ( (*u != '\0') || (io_to < io_from) || (io_to >= 65536) )
|
||||
goto parse_error;
|
||||
|
||||
- printk("Disabling dom0 access to ioport range %04lx-%04lx\n",
|
||||
- io_from, io_to);
|
||||
+ if ( opt != opt_ioports_noemul )
|
||||
+ {
|
||||
+ printk("Disabling %saccess to ioport range %04lx-%04lx\n",
|
||||
+ opt != opt_ioports_disable ? "dom0 " : "",
|
||||
+ io_from, io_to);
|
||||
|
||||
- if ( ioports_deny_access(dom0, io_from, io_to) != 0 )
|
||||
- BUG();
|
||||
+ if ( opt == opt_ioports_disable
|
||||
+ && ioports_deny_access_all(io_from, io_to) != 0 )
|
||||
+ BUG();
|
||||
+ if ( ioports_deny_access(dom0, io_from, io_to) != 0 )
|
||||
+ BUG();
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ printk("Setting non-emulated access for ioport range %04lx-%04lx\n",
|
||||
+ io_from, io_to);
|
||||
+
|
||||
+ if ( ioports_set_noemul(io_from, io_to) != 0 )
|
||||
+ BUG();
|
||||
+ }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -812,6 +840,13 @@ int construct_dom0(struct domain *d,
|
||||
|
||||
rc = 0;
|
||||
|
||||
+ /* Command-line I/O ranges. */
|
||||
+ ioport_caps = rangeset_new(NULL,
|
||||
+ "global I/O Port access control",
|
||||
+ RANGESETF_prettyprint_hex);
|
||||
+ BUG_ON(!ioport_caps);
|
||||
+ rc |= ioports_permit_access_all(0, 0xFFFF);
|
||||
+
|
||||
/* DOM0 is permitted full I/O capabilities. */
|
||||
rc |= ioports_permit_access(dom0, 0, 0xFFFF);
|
||||
rc |= iomem_permit_access(dom0, 0UL, ~0UL);
|
||||
@@ -821,15 +856,20 @@ int construct_dom0(struct domain *d,
|
||||
* Modify I/O port access permissions.
|
||||
*/
|
||||
/* Master Interrupt Controller (PIC). */
|
||||
+ rc |= ioports_deny_access_all(0x20, 0x21);
|
||||
rc |= ioports_deny_access(dom0, 0x20, 0x21);
|
||||
/* Slave Interrupt Controller (PIC). */
|
||||
+ rc |= ioports_deny_access_all(0xA0, 0xA1);
|
||||
rc |= ioports_deny_access(dom0, 0xA0, 0xA1);
|
||||
/* Interval Timer (PIT). */
|
||||
+ rc |= ioports_deny_access_all(0x40, 0x43);
|
||||
rc |= ioports_deny_access(dom0, 0x40, 0x43);
|
||||
/* PIT Channel 2 / PC Speaker Control. */
|
||||
+ rc |= ioports_deny_access_all(0x61, 0x61);
|
||||
rc |= ioports_deny_access(dom0, 0x61, 0x61);
|
||||
/* Command-line I/O ranges. */
|
||||
- process_dom0_ioports_disable();
|
||||
+ process_ioports(opt_ioports_disable);
|
||||
+ process_ioports(opt_dom0_ioports_disable);
|
||||
|
||||
/*
|
||||
* Modify I/O memory access permissions.
|
||||
@@ -848,6 +888,14 @@ int construct_dom0(struct domain *d,
|
||||
rc |= iomem_deny_access(dom0, mfn, mfn);
|
||||
}
|
||||
|
||||
+ /* Command-line I/O ranges requiring full register context access. */
|
||||
+ ioport_emul = rangeset_new(NULL,
|
||||
+ "I/O Port emulation control",
|
||||
+ RANGESETF_prettyprint_hex);
|
||||
+ BUG_ON(!ioport_emul);
|
||||
+ rc |= ioports_set_emul(0, 0xFFFF);
|
||||
+ process_ioports(opt_ioports_noemul);
|
||||
+
|
||||
BUG_ON(rc != 0);
|
||||
|
||||
return 0;
|
||||
Index: xen-unstable/xen/arch/x86/sysctl.c
|
||||
===================================================================
|
||||
--- xen-unstable.orig/xen/arch/x86/sysctl.c
|
||||
+++ xen-unstable/xen/arch/x86/sysctl.c
|
||||
@@ -57,6 +57,23 @@ long arch_do_sysctl(
|
||||
}
|
||||
break;
|
||||
|
||||
+ case XEN_SYSCTL_ioport_emulation:
|
||||
+ {
|
||||
+ unsigned int fp = sysctl->u.ioport_emulation.first_port;
|
||||
+ unsigned int np = sysctl->u.ioport_emulation.nr_ports;
|
||||
+
|
||||
+ ret = -EINVAL;
|
||||
+ if ( (fp + np) > 65536 )
|
||||
+ break;
|
||||
+
|
||||
+ if ( np == 0 )
|
||||
+ ret = 0;
|
||||
+ else if ( sysctl->u.ioport_emulation.emulate )
|
||||
+ ret = ioports_set_emul(fp, fp + np - 1);
|
||||
+ else
|
||||
+ ret = ioports_set_noemul(fp, fp + np - 1);
|
||||
+ }
|
||||
+ break;
|
||||
|
||||
default:
|
||||
ret = -ENOSYS;
|
||||
Index: xen-unstable/xen/arch/x86/traps.c
|
||||
===================================================================
|
||||
--- xen-unstable.orig/xen/arch/x86/traps.c
|
||||
+++ xen-unstable/xen/arch/x86/traps.c
|
||||
@@ -1002,9 +1002,20 @@ static inline int admin_io_okay(
|
||||
return ioports_access_permitted(v->domain, port, port + bytes - 1);
|
||||
}
|
||||
|
||||
+typedef unsigned long io_emul_stub_t(struct cpu_user_regs *) __attribute__((__regparm__(1)));
|
||||
+long io_emul_stub_offset = 0, io_emul_insn_offset = 0;
|
||||
+
|
||||
+/* Can the I/O access be carried out without full register context? */
|
||||
+static inline int normal_io_okay(
|
||||
+ unsigned int port, unsigned int bytes)
|
||||
+{
|
||||
+ return ioports_emul(port, port + bytes - 1);
|
||||
+}
|
||||
+
|
||||
/* Check admin limits. Silently fail the access if it is disallowed. */
|
||||
static inline unsigned char inb_user(
|
||||
- unsigned int port, struct vcpu *v, struct cpu_user_regs *regs)
|
||||
+ unsigned int port, io_emul_stub_t *stub,
|
||||
+ struct vcpu *v, struct cpu_user_regs *regs)
|
||||
{
|
||||
/*
|
||||
* Allow read access to port 0x61. Bit 4 oscillates with period 30us, and
|
||||
@@ -1014,18 +1025,54 @@ static inline unsigned char inb_user(
|
||||
* but there's not really a good reason to do so.
|
||||
*/
|
||||
if ( admin_io_okay(port, 1, v, regs) || (port == 0x61) )
|
||||
- return inb(port);
|
||||
+ return !stub || normal_io_okay(port, 1) ? inb(port) : stub(regs);
|
||||
return ~0;
|
||||
}
|
||||
-//#define inb_user(_p, _d, _r) (admin_io_okay(_p, 1, _d, _r) ? inb(_p) : ~0)
|
||||
-#define inw_user(_p, _d, _r) (admin_io_okay(_p, 2, _d, _r) ? inw(_p) : ~0)
|
||||
-#define inl_user(_p, _d, _r) (admin_io_okay(_p, 4, _d, _r) ? inl(_p) : ~0)
|
||||
-#define outb_user(_v, _p, _d, _r) \
|
||||
- (admin_io_okay(_p, 1, _d, _r) ? outb(_v, _p) : ((void)0))
|
||||
-#define outw_user(_v, _p, _d, _r) \
|
||||
- (admin_io_okay(_p, 2, _d, _r) ? outw(_v, _p) : ((void)0))
|
||||
-#define outl_user(_v, _p, _d, _r) \
|
||||
- (admin_io_okay(_p, 4, _d, _r) ? outl(_v, _p) : ((void)0))
|
||||
+
|
||||
+static inline unsigned short inw_user(
|
||||
+ unsigned int port, io_emul_stub_t *stub,
|
||||
+ struct vcpu *v, struct cpu_user_regs *regs)
|
||||
+{
|
||||
+ if ( admin_io_okay(port, 2, v, regs) )
|
||||
+ return !stub || normal_io_okay(port, 2) ? inw(port) : stub(regs);
|
||||
+ return ~0;
|
||||
+}
|
||||
+
|
||||
+static inline unsigned int inl_user(
|
||||
+ unsigned int port, io_emul_stub_t *stub,
|
||||
+ struct vcpu *v, struct cpu_user_regs *regs)
|
||||
+{
|
||||
+ if ( admin_io_okay(port, 4, v, regs) )
|
||||
+ return !stub || normal_io_okay(port, 4) ? inl(port) : stub(regs);
|
||||
+ return ~0;
|
||||
+}
|
||||
+
|
||||
+static inline void outb_user(
|
||||
+ unsigned char value, unsigned int port,
|
||||
+ io_emul_stub_t *stub,
|
||||
+ struct vcpu *v, struct cpu_user_regs *regs)
|
||||
+{
|
||||
+ if ( admin_io_okay(port, 1, v, regs) )
|
||||
+ !stub || normal_io_okay(port, 1) ? outb(value, port) : (void)stub(regs);
|
||||
+}
|
||||
+
|
||||
+static inline void outw_user(
|
||||
+ unsigned short value, unsigned int port,
|
||||
+ io_emul_stub_t *stub,
|
||||
+ struct vcpu *v, struct cpu_user_regs *regs)
|
||||
+{
|
||||
+ if ( admin_io_okay(port, 2, v, regs) )
|
||||
+ !stub || normal_io_okay(port, 2) ? outw(value, port) : (void)stub(regs);
|
||||
+}
|
||||
+
|
||||
+static inline void outl_user(
|
||||
+ unsigned int value, unsigned int port,
|
||||
+ io_emul_stub_t *stub,
|
||||
+ struct vcpu *v, struct cpu_user_regs *regs)
|
||||
+{
|
||||
+ if ( admin_io_okay(port, 4, v, regs) )
|
||||
+ !stub || normal_io_okay(port, 4) ? outl(value, port) : (void)stub(regs);
|
||||
+}
|
||||
|
||||
/* Instruction fetch with error handling. */
|
||||
#define insn_fetch(_type, _size, cs, eip) \
|
||||
@@ -1046,6 +1093,8 @@ static int emulate_privileged_op(struct
|
||||
u8 opcode, modrm_reg = 0, modrm_rm = 0, rep_prefix = 0;
|
||||
unsigned int port, i, op_bytes = 4, data, rc;
|
||||
u32 l, h;
|
||||
+ io_emul_stub_t *stub;
|
||||
+ char *insn;
|
||||
|
||||
/* Legacy prefixes. */
|
||||
for ( i = 0; i < 8; i++ )
|
||||
@@ -1103,13 +1152,13 @@ static int emulate_privileged_op(struct
|
||||
switch ( op_bytes )
|
||||
{
|
||||
case 1:
|
||||
- data = (u8)inb_user((u16)regs->edx, v, regs);
|
||||
+ data = (u8)inb_user((u16)regs->edx, NULL, v, regs);
|
||||
break;
|
||||
case 2:
|
||||
- data = (u16)inw_user((u16)regs->edx, v, regs);
|
||||
+ data = (u16)inw_user((u16)regs->edx, NULL, v, regs);
|
||||
break;
|
||||
case 4:
|
||||
- data = (u32)inl_user((u16)regs->edx, v, regs);
|
||||
+ data = (u32)inl_user((u16)regs->edx, NULL, v, regs);
|
||||
break;
|
||||
}
|
||||
if ( (rc = copy_to_user((void *)regs->edi, &data, op_bytes)) != 0 )
|
||||
@@ -1135,13 +1184,13 @@ static int emulate_privileged_op(struct
|
||||
switch ( op_bytes )
|
||||
{
|
||||
case 1:
|
||||
- outb_user((u8)data, (u16)regs->edx, v, regs);
|
||||
+ outb_user((u8)data, (u16)regs->edx, NULL, v, regs);
|
||||
break;
|
||||
case 2:
|
||||
- outw_user((u16)data, (u16)regs->edx, v, regs);
|
||||
+ outw_user((u16)data, (u16)regs->edx, NULL, v, regs);
|
||||
break;
|
||||
case 4:
|
||||
- outl_user((u32)data, (u16)regs->edx, v, regs);
|
||||
+ outl_user((u32)data, (u16)regs->edx, NULL, v, regs);
|
||||
break;
|
||||
}
|
||||
regs->esi += (int)((regs->eflags & EF_DF) ? -op_bytes : op_bytes);
|
||||
@@ -1159,27 +1208,33 @@ static int emulate_privileged_op(struct
|
||||
}
|
||||
|
||||
/* I/O Port and Interrupt Flag instructions. */
|
||||
+ insn = (char *)get_stack_bottom();
|
||||
+ stub = (io_emul_stub_t *)(insn + io_emul_stub_offset);
|
||||
+ insn += io_emul_insn_offset;
|
||||
+ *insn++ = op_bytes != 2 ? 0x90 : 0x66;
|
||||
+ *insn++ = opcode;
|
||||
switch ( opcode )
|
||||
{
|
||||
case 0xe4: /* IN imm8,%al */
|
||||
op_bytes = 1;
|
||||
case 0xe5: /* IN imm8,%eax */
|
||||
port = insn_fetch(u8, 1, cs, eip);
|
||||
+ *insn = port;
|
||||
exec_in:
|
||||
if ( !guest_io_okay(port, op_bytes, v, regs) )
|
||||
goto fail;
|
||||
switch ( op_bytes )
|
||||
{
|
||||
case 1:
|
||||
- regs->eax &= ~0xffUL;
|
||||
- regs->eax |= (u8)inb_user(port, v, regs);
|
||||
+ res = regs->eax & ~0xffUL;
|
||||
+ regs->eax = res | (u8)inb_user(port, stub, v, regs);
|
||||
break;
|
||||
case 2:
|
||||
- regs->eax &= ~0xffffUL;
|
||||
- regs->eax |= (u16)inw_user(port, v, regs);
|
||||
+ res = regs->eax & ~0xffffUL;
|
||||
+ regs->eax = res | (u16)inw_user(port, stub, v, regs);
|
||||
break;
|
||||
case 4:
|
||||
- regs->eax = (u32)inl_user(port, v, regs);
|
||||
+ regs->eax = (u32)inl_user(port, stub, v, regs);
|
||||
break;
|
||||
}
|
||||
goto done;
|
||||
@@ -1188,25 +1243,27 @@ static int emulate_privileged_op(struct
|
||||
op_bytes = 1;
|
||||
case 0xed: /* IN %dx,%eax */
|
||||
port = (u16)regs->edx;
|
||||
+ *insn = 0x90;
|
||||
goto exec_in;
|
||||
|
||||
case 0xe6: /* OUT %al,imm8 */
|
||||
op_bytes = 1;
|
||||
case 0xe7: /* OUT %eax,imm8 */
|
||||
port = insn_fetch(u8, 1, cs, eip);
|
||||
+ *insn = port;
|
||||
exec_out:
|
||||
if ( !guest_io_okay(port, op_bytes, v, regs) )
|
||||
goto fail;
|
||||
switch ( op_bytes )
|
||||
{
|
||||
case 1:
|
||||
- outb_user((u8)regs->eax, port, v, regs);
|
||||
+ outb_user((u8)regs->eax, port, stub, v, regs);
|
||||
break;
|
||||
case 2:
|
||||
- outw_user((u16)regs->eax, port, v, regs);
|
||||
+ outw_user((u16)regs->eax, port, stub, v, regs);
|
||||
break;
|
||||
case 4:
|
||||
- outl_user((u32)regs->eax, port, v, regs);
|
||||
+ outl_user((u32)regs->eax, port, stub, v, regs);
|
||||
break;
|
||||
}
|
||||
goto done;
|
||||
@@ -1215,6 +1272,7 @@ static int emulate_privileged_op(struct
|
||||
op_bytes = 1;
|
||||
case 0xef: /* OUT %eax,%dx */
|
||||
port = (u16)regs->edx;
|
||||
+ *insn = 0x90;
|
||||
goto exec_out;
|
||||
|
||||
case 0xfa: /* CLI */
|
||||
Index: xen-unstable/xen/arch/x86/x86_32/Makefile
|
||||
===================================================================
|
||||
--- xen-unstable.orig/xen/arch/x86/x86_32/Makefile
|
||||
+++ xen-unstable/xen/arch/x86/x86_32/Makefile
|
||||
@@ -1,5 +1,6 @@
|
||||
obj-y += domain_page.o
|
||||
obj-y += entry.o
|
||||
+obj-y += io.o
|
||||
obj-y += mm.o
|
||||
obj-y += seg_fixup.o
|
||||
obj-y += traps.o
|
||||
Index: xen-unstable/xen/arch/x86/x86_32/io.S
|
||||
===================================================================
|
||||
--- /dev/null
|
||||
+++ xen-unstable/xen/arch/x86/x86_32/io.S
|
||||
@@ -0,0 +1,42 @@
|
||||
+/*
|
||||
+ * Special (full-context) I/O handling routines.
|
||||
+ *
|
||||
+ * Copyright (c) 2006, Novell, Inc.
|
||||
+ */
|
||||
+
|
||||
+#include <xen/config.h>
|
||||
+#include <asm/asm_defns.h>
|
||||
+
|
||||
+ENTRY(save_host_restore_guest)
|
||||
+ movl (%esp), %ecx
|
||||
+ movl %eax, (%esp)
|
||||
+ movl UREGS_edx(%eax), %edx
|
||||
+ pushl %ebx
|
||||
+ movl UREGS_ebx(%eax), %ebx
|
||||
+ pushl %ebp
|
||||
+ movl UREGS_ebp(%eax), %ebp
|
||||
+ pushl %esi
|
||||
+ movl UREGS_esi(%eax), %esi
|
||||
+ pushl %edi
|
||||
+ movl UREGS_edi(%eax), %edi
|
||||
+ pushl %ecx
|
||||
+ movl UREGS_ecx(%eax), %ecx
|
||||
+ movl UREGS_eax(%eax), %eax
|
||||
+ ret
|
||||
+
|
||||
+ENTRY(save_guest_restore_host)
|
||||
+ pushl %edx
|
||||
+ movl 5*4(%esp), %edx
|
||||
+ movl %eax, UREGS_eax(%edx)
|
||||
+ popl UREGS_edx(%edx)
|
||||
+ movl %edi, UREGS_edi(%edx)
|
||||
+ popl %edi
|
||||
+ movl %esi, UREGS_esi(%edx)
|
||||
+ popl %esi
|
||||
+ movl %ebp, UREGS_ebp(%edx)
|
||||
+ popl %ebp
|
||||
+ movl %ebx, UREGS_ebx(%edx)
|
||||
+ popl %ebx
|
||||
+ movl %ecx, UREGS_ecx(%edx)
|
||||
+ popl %ecx
|
||||
+ ret
|
||||
Index: xen-unstable/xen/arch/x86/x86_32/traps.c
|
||||
===================================================================
|
||||
--- xen-unstable.orig/xen/arch/x86/x86_32/traps.c
|
||||
+++ xen-unstable/xen/arch/x86/x86_32/traps.c
|
||||
@@ -13,6 +13,7 @@
|
||||
#include <xen/nmi.h>
|
||||
#include <asm/current.h>
|
||||
#include <asm/flushtlb.h>
|
||||
+#include <asm/io.h>
|
||||
#include <asm/hvm/hvm.h>
|
||||
#include <asm/hvm/support.h>
|
||||
|
||||
@@ -250,6 +251,7 @@ fastcall void smp_deferred_nmi(struct cp
|
||||
void __init percpu_traps_init(void)
|
||||
{
|
||||
struct tss_struct *tss = &doublefault_tss;
|
||||
+ char *stack_bottom, *stack;
|
||||
asmlinkage int hypercall(void);
|
||||
|
||||
if ( smp_processor_id() != 0 )
|
||||
@@ -283,6 +285,28 @@ void __init percpu_traps_init(void)
|
||||
(unsigned long)tss, 235, 9);
|
||||
|
||||
set_task_gate(TRAP_double_fault, __DOUBLEFAULT_TSS_ENTRY<<3);
|
||||
+
|
||||
+ /*
|
||||
+ * Stub for full-context I/O emulation.
|
||||
+ */
|
||||
+ stack_bottom = (char *)get_stack_bottom();
|
||||
+ stack = (char *)((unsigned long)stack_bottom & ~(STACK_SIZE - 1));
|
||||
+ if ( !io_emul_stub_offset )
|
||||
+ io_emul_stub_offset = stack - stack_bottom;
|
||||
+ else
|
||||
+ BUG_ON(io_emul_stub_offset != stack - stack_bottom);
|
||||
+ /* call save_host_restore_guest */
|
||||
+ stack[0] = 0xe8;
|
||||
+ *(s32*)&stack[1] = (char *)save_host_restore_guest - &stack[5];
|
||||
+ stack += 5;
|
||||
+ if ( !io_emul_insn_offset )
|
||||
+ io_emul_insn_offset = stack - stack_bottom;
|
||||
+ else
|
||||
+ BUG_ON(io_emul_insn_offset != stack - stack_bottom);
|
||||
+ stack += 3; /* operand size prefix, opcode, immediate */
|
||||
+ /* jmp save_guest_restore_host */
|
||||
+ stack[0] = 0xe9;
|
||||
+ *(s32*)&stack[1] = (char *)save_guest_restore_host - &stack[5];
|
||||
}
|
||||
|
||||
void init_int80_direct_trap(struct vcpu *v)
|
||||
Index: xen-unstable/xen/arch/x86/x86_64/Makefile
|
||||
===================================================================
|
||||
--- xen-unstable.orig/xen/arch/x86/x86_64/Makefile
|
||||
+++ xen-unstable/xen/arch/x86/x86_64/Makefile
|
||||
@@ -1,3 +1,4 @@
|
||||
obj-y += entry.o
|
||||
+obj-y += io.o
|
||||
obj-y += mm.o
|
||||
obj-y += traps.o
|
||||
Index: xen-unstable/xen/arch/x86/x86_64/io.S
|
||||
===================================================================
|
||||
--- /dev/null
|
||||
+++ xen-unstable/xen/arch/x86/x86_64/io.S
|
||||
@@ -0,0 +1,62 @@
|
||||
+/*
|
||||
+ * Special (full-context) I/O handling routines.
|
||||
+ *
|
||||
+ * Copyright (c) 2006, Novell, Inc.
|
||||
+ */
|
||||
+
|
||||
+#include <xen/config.h>
|
||||
+#include <asm/asm_defns.h>
|
||||
+
|
||||
+ENTRY(save_host_restore_guest)
|
||||
+ movq (%rsp), %rcx
|
||||
+ movq %rdi, (%rsp)
|
||||
+ movq UREGS_rdx(%rdi), %rdx
|
||||
+ pushq %rbx
|
||||
+ movq UREGS_rax(%rdi), %rax
|
||||
+ movq UREGS_rbx(%rdi), %rbx
|
||||
+ pushq %rbp
|
||||
+ movq UREGS_rsi(%rdi), %rsi
|
||||
+ movq UREGS_rbp(%rdi), %rbp
|
||||
+ pushq %r12
|
||||
+ movq UREGS_r8(%rdi), %r8
|
||||
+ movq UREGS_r12(%rdi), %r12
|
||||
+ pushq %r13
|
||||
+ movq UREGS_r9(%rdi), %r9
|
||||
+ movq UREGS_r13(%rdi), %r13
|
||||
+ pushq %r14
|
||||
+ movq UREGS_r10(%rdi), %r10
|
||||
+ movq UREGS_r14(%rdi), %r14
|
||||
+ pushq %r15
|
||||
+ movq UREGS_r11(%rdi), %r11
|
||||
+ movq UREGS_r15(%rdi), %r15
|
||||
+ pushq %rcx
|
||||
+ movq UREGS_rcx(%rdi), %rcx
|
||||
+ movq UREGS_rdi(%rdi), %rdi
|
||||
+ ret
|
||||
+
|
||||
+ENTRY(save_guest_restore_host)
|
||||
+ pushq %rdi
|
||||
+ movq 7*8(%rsp), %rdi
|
||||
+ movq %rax, UREGS_rax(%rdi)
|
||||
+ popq UREGS_rdi(%rdi)
|
||||
+ movq %r15, UREGS_r15(%rdi)
|
||||
+ movq %r11, UREGS_r11(%rdi)
|
||||
+ popq %r15
|
||||
+ movq %r14, UREGS_r14(%rdi)
|
||||
+ movq %r10, UREGS_r10(%rdi)
|
||||
+ popq %r14
|
||||
+ movq %r13, UREGS_r13(%rdi)
|
||||
+ movq %r9, UREGS_r9(%rdi)
|
||||
+ popq %r13
|
||||
+ movq %r12, UREGS_r12(%rdi)
|
||||
+ movq %r8, UREGS_r8(%rdi)
|
||||
+ popq %r12
|
||||
+ movq %rbp, UREGS_rbp(%rdi)
|
||||
+ movq %rsi, UREGS_rsi(%rdi)
|
||||
+ popq %rbp
|
||||
+ movq %rbx, UREGS_rbx(%rdi)
|
||||
+ movq %rdx, UREGS_rdx(%rdi)
|
||||
+ popq %rbx
|
||||
+ movq %rcx, UREGS_rcx(%rdi)
|
||||
+ popq %rcx
|
||||
+ ret
|
||||
Index: xen-unstable/xen/arch/x86/x86_64/traps.c
|
||||
===================================================================
|
||||
--- xen-unstable.orig/xen/arch/x86/x86_64/traps.c
|
||||
+++ xen-unstable/xen/arch/x86/x86_64/traps.c
|
||||
@@ -14,6 +14,7 @@
|
||||
#include <xen/nmi.h>
|
||||
#include <asm/current.h>
|
||||
#include <asm/flushtlb.h>
|
||||
+#include <asm/io.h>
|
||||
#include <asm/msr.h>
|
||||
#include <asm/page.h>
|
||||
#include <asm/shadow.h>
|
||||
@@ -337,6 +338,29 @@ void __init percpu_traps_init(void)
|
||||
|
||||
wrmsr(MSR_STAR, 0, (FLAT_RING3_CS32<<16) | __HYPERVISOR_CS);
|
||||
wrmsr(MSR_SYSCALL_MASK, EF_VM|EF_RF|EF_NT|EF_DF|EF_IE|EF_TF, 0U);
|
||||
+
|
||||
+ /*
|
||||
+ * Stub for full-context I/O emulation.
|
||||
+ */
|
||||
+
|
||||
+ /* Skip the compatibility-mode entry trampoline. */
|
||||
+ stack += 26;
|
||||
+ if ( !io_emul_stub_offset )
|
||||
+ io_emul_stub_offset = stack - stack_bottom;
|
||||
+ else
|
||||
+ BUG_ON(io_emul_stub_offset != stack - stack_bottom);
|
||||
+ /* call save_host_restore_guest */
|
||||
+ stack[0] = 0xe8;
|
||||
+ *(s32*)&stack[1] = (char *)save_host_restore_guest - &stack[5];
|
||||
+ stack += 5;
|
||||
+ if ( !io_emul_insn_offset )
|
||||
+ io_emul_insn_offset = stack - stack_bottom;
|
||||
+ else
|
||||
+ BUG_ON(io_emul_insn_offset != stack - stack_bottom);
|
||||
+ stack += 3; /* operand size prefix, opcode, immediate */
|
||||
+ /* jmp save_guest_restore_host */
|
||||
+ stack[0] = 0xe9;
|
||||
+ *(s32*)&stack[1] = (char *)save_guest_restore_host - &stack[5];
|
||||
}
|
||||
|
||||
static long register_guest_callback(struct callback_register *reg)
|
||||
Index: xen-unstable/xen/include/asm-x86/io.h
|
||||
===================================================================
|
||||
--- xen-unstable.orig/xen/include/asm-x86/io.h
|
||||
+++ xen-unstable/xen/include/asm-x86/io.h
|
||||
@@ -50,4 +50,10 @@ __OUT(b,"b",char)
|
||||
__OUT(w,"w",short)
|
||||
__OUT(l,,int)
|
||||
|
||||
+struct cpu_user_regs;
|
||||
+void save_host_restore_guest(struct cpu_user_regs *) __attribute__((__regparm__(1)));
|
||||
+unsigned long save_guest_restore_host(unsigned long) __attribute__((__regparm__(1)));
|
||||
+
|
||||
+extern long io_emul_stub_offset, io_emul_insn_offset;
|
||||
+
|
||||
#endif
|
||||
Index: xen-unstable/xen/include/asm-x86/iocap.h
|
||||
===================================================================
|
||||
--- xen-unstable.orig/xen/include/asm-x86/iocap.h
|
||||
+++ xen-unstable/xen/include/asm-x86/iocap.h
|
||||
@@ -7,6 +7,15 @@
|
||||
#ifndef __X86_IOCAP_H__
|
||||
#define __X86_IOCAP_H__
|
||||
|
||||
+extern struct rangeset *ioport_caps, *ioport_emul;
|
||||
+
|
||||
+#define ioports_permit_access_all(s, e) \
|
||||
+ rangeset_add_range(ioport_caps, s, e)
|
||||
+#define ioports_deny_access_all(s, e) \
|
||||
+ rangeset_remove_range(ioport_caps, s, e)
|
||||
+#define ioports_any_access_permitted(s, e) \
|
||||
+ rangeset_contains_range(ioport_caps, s, e)
|
||||
+
|
||||
#define ioports_permit_access(d, s, e) \
|
||||
rangeset_add_range((d)->arch.ioport_caps, s, e)
|
||||
#define ioports_deny_access(d, s, e) \
|
||||
@@ -14,6 +23,13 @@
|
||||
#define ioports_access_permitted(d, s, e) \
|
||||
rangeset_contains_range((d)->arch.ioport_caps, s, e)
|
||||
|
||||
+#define ioports_set_emul(s, e) \
|
||||
+ rangeset_add_range(ioport_emul, s, e)
|
||||
+#define ioports_set_noemul(s, e) \
|
||||
+ rangeset_remove_range(ioport_emul, s, e)
|
||||
+#define ioports_emul(s, e) \
|
||||
+ rangeset_contains_range(ioport_emul, s, e)
|
||||
+
|
||||
#define cache_flush_permitted(d) \
|
||||
(!rangeset_is_empty((d)->iomem_caps))
|
||||
|
||||
Index: xen-unstable/xen/include/public/sysctl.h
|
||||
===================================================================
|
||||
--- xen-unstable.orig/xen/include/public/sysctl.h
|
||||
+++ xen-unstable/xen/include/public/sysctl.h
|
||||
@@ -122,6 +122,15 @@ struct xen_sysctl_getdomaininfolist {
|
||||
typedef struct xen_sysctl_getdomaininfolist xen_sysctl_getdomaininfolist_t;
|
||||
DEFINE_XEN_GUEST_HANDLE(xen_sysctl_getdomaininfolist_t);
|
||||
|
||||
+#define XEN_SYSCTL_ioport_emulation 7
|
||||
+struct xen_sysctl_ioport_emulation {
|
||||
+ uint32_t first_port; /* first port int range */
|
||||
+ uint32_t nr_ports; /* size of port range */
|
||||
+ uint8_t emulate; /* emulate access to range? */
|
||||
+};
|
||||
+typedef struct xen_sysctl_ioport_emulation xen_sysctl_ioport_emulation_t;
|
||||
+DEFINE_XEN_GUEST_HANDLE(xen_sysctl_ioport_emulation_t);
|
||||
+
|
||||
struct xen_sysctl {
|
||||
uint32_t cmd;
|
||||
uint32_t interface_version; /* XEN_SYSCTL_INTERFACE_VERSION */
|
||||
@@ -132,6 +141,7 @@ struct xen_sysctl {
|
||||
struct xen_sysctl_sched_id sched_id;
|
||||
struct xen_sysctl_perfc_op perfc_op;
|
||||
struct xen_sysctl_getdomaininfolist getdomaininfolist;
|
||||
+ struct xen_sysctl_ioport_emulation ioport_emulation;
|
||||
uint8_t pad[128];
|
||||
} u;
|
||||
};
|
@ -1,11 +1,11 @@
|
||||
Change default IO-APIC ack mode for single IO-APIC systems to old-style. Jan
|
||||
|
||||
|
||||
Index: xen-unstable/xen/arch/x86/io_apic.c
|
||||
Index: xen-3.0.4-testing/xen/arch/x86/io_apic.c
|
||||
===================================================================
|
||||
--- xen-unstable.orig/xen/arch/x86/io_apic.c
|
||||
+++ xen-unstable/xen/arch/x86/io_apic.c
|
||||
@@ -1342,7 +1342,7 @@ static unsigned int startup_level_ioapic
|
||||
--- xen-3.0.4-testing.orig/xen/arch/x86/io_apic.c
|
||||
+++ xen-3.0.4-testing/xen/arch/x86/io_apic.c
|
||||
@@ -1339,7 +1339,7 @@ static unsigned int startup_level_ioapic
|
||||
return 0; /* don't check for pending */
|
||||
}
|
||||
|
||||
@ -14,7 +14,7 @@ Index: xen-unstable/xen/arch/x86/io_apic.c
|
||||
static void setup_ioapic_ack(char *s)
|
||||
{
|
||||
if ( !strcmp(s, "old") )
|
||||
@@ -1779,6 +1779,8 @@ void __init setup_IO_APIC(void)
|
||||
@@ -1776,6 +1776,8 @@ void __init setup_IO_APIC(void)
|
||||
else
|
||||
io_apic_irqs = ~PIC_IRQS;
|
||||
|
||||
|
@ -1,47 +0,0 @@
|
||||
Index: xen-3.0.3-testing/tools/python/xen/xm/create.py
|
||||
===================================================================
|
||||
--- xen-3.0.3-testing.orig/tools/python/xen/xm/create.py
|
||||
+++ xen-3.0.3-testing/tools/python/xen/xm/create.py
|
||||
@@ -428,6 +428,10 @@ gopts.var('sdl', val='',
|
||||
fn=set_value, default=None,
|
||||
use="""Should the device model use SDL?""")
|
||||
|
||||
+gopts.var('keymap', val='',
|
||||
+ fn=set_value, default=None,
|
||||
+ use="""Keyboard mapping for SDL/VNC""")
|
||||
+
|
||||
gopts.var('display', val='DISPLAY',
|
||||
fn=set_value, default=None,
|
||||
use="X11 display to use")
|
||||
@@ -639,7 +643,7 @@ def configure_hvm(config_image, vals):
|
||||
'localtime', 'serial', 'stdvga', 'isa', 'nographic', 'soundhw',
|
||||
'vnc', 'vncdisplay', 'vncunused', 'vncconsole', 'vnclisten',
|
||||
'sdl', 'display', 'xauthority',
|
||||
- 'acpi', 'apic', 'usb', 'usbdevice' ]
|
||||
+ 'acpi', 'apic', 'usb', 'usbdevice', 'keymap' ]
|
||||
for a in args:
|
||||
if (vals.__dict__[a]):
|
||||
config_image.append([a, vals.__dict__[a]])
|
||||
Index: xen-3.0.3-testing/tools/python/xen/xend/image.py
|
||||
===================================================================
|
||||
--- xen-3.0.3-testing.orig/tools/python/xen/xend/image.py
|
||||
+++ xen-3.0.3-testing/tools/python/xen/xend/image.py
|
||||
@@ -352,6 +352,10 @@ class HVMImageHandler(ImageHandler):
|
||||
if nographic:
|
||||
ret.append('-nographic')
|
||||
return ret
|
||||
+ keymap = sxp.child_value(config, 'keymap')
|
||||
+ if not keymap:
|
||||
+ keymap = "en-us"
|
||||
+ ret += ['-k', keymap]
|
||||
if vnc:
|
||||
vncdisplay = sxp.child_value(config, 'vncdisplay',
|
||||
int(self.vm.getDomid()))
|
||||
@@ -360,7 +364,6 @@ class HVMImageHandler(ImageHandler):
|
||||
ret += ['-vncunused']
|
||||
else:
|
||||
ret += ['-vnc', '%d' % vncdisplay]
|
||||
- ret += ['-k', 'en-us']
|
||||
vnclisten = sxp.child_value(config, 'vnclisten')
|
||||
if not(vnclisten):
|
||||
vnclisten = xen.xend.XendRoot.instance().get_vnclisten_address()
|
14
xen-localtime.patch
Normal file
14
xen-localtime.patch
Normal file
@ -0,0 +1,14 @@
|
||||
Fix usage of localtime parameter in PV guest configuration
|
||||
Signed-off-by: Bruce Rogers <brogers@novell.com>
|
||||
|
||||
--- a/tools/python/xen/xend/XendDomainInfo.py 2007-01-20 08:19:11.877589448 -0700
|
||||
+++ b/tools/python/xen/xend/XendDomainInfo.py 2007-01-20 09:20:59.805618252 -0700
|
||||
@@ -1361,7 +1361,7 @@
|
||||
self.info['image'],
|
||||
self.info['devices'])
|
||||
|
||||
- localtime = self.info.get('localtime', False)
|
||||
+ localtime = self.info.get('platform_localtime', False)
|
||||
if localtime:
|
||||
xc.domain_set_time_offset(self.domid)
|
||||
|
@ -5,16 +5,16 @@ SIGKILL causes atexit to not be called, so mouse SDL cleanup wasn't
|
||||
performed, so mouse wasn't released.
|
||||
|
||||
|
||||
Index: xen-unstable/tools/python/xen/xend/image.py
|
||||
Index: xen-3.0.4-testing/tools/python/xen/xend/image.py
|
||||
===================================================================
|
||||
--- xen-unstable.orig/tools/python/xen/xend/image.py
|
||||
+++ xen-unstable/tools/python/xen/xend/image.py
|
||||
@@ -412,7 +412,7 @@ class HVMImageHandler(ImageHandler):
|
||||
import signal
|
||||
if not self.pid:
|
||||
return
|
||||
- os.kill(self.pid, signal.SIGKILL)
|
||||
+ os.kill(self.pid, signal.SIGTERM)
|
||||
os.waitpid(self.pid, 0)
|
||||
self.pid = 0
|
||||
|
||||
--- xen-3.0.4-testing.orig/tools/python/xen/xend/image.py
|
||||
+++ xen-3.0.4-testing/tools/python/xen/xend/image.py
|
||||
@@ -502,7 +502,7 @@ class HVMImageHandler(ImageHandler):
|
||||
self.unregister_reboot_feature_watch();
|
||||
if self.pid:
|
||||
try:
|
||||
- os.kill(self.pid, signal.SIGKILL)
|
||||
+ os.kill(self.pid, signal.SIGTERM)
|
||||
except OSError, exn:
|
||||
log.exception(exn)
|
||||
try:
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user