OBS User unknown 2007-02-11 10:48:10 +00:00 committed by Git OBS Bridge
parent 241ee9df04
commit d7002a96b9
166 changed files with 35454 additions and 7164 deletions

147
32on64-acmop.patch Normal file
View 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

File diff suppressed because it is too large Load Diff

484
32on64-call-gates.patch Normal file
View 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

File diff suppressed because it is too large Load Diff

647
32on64-emul.patch Normal file
View 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 *)&regs->reg = (val)) \
+ : (*(u16 *)&regs->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
View 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
View 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
View 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
View 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 = &current->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, &current->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(&reg, arg, 1) )
+ break;
+
+ ret = compat_register_guest_callback(&reg);
+ }
+ 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
View 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
View 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

File diff suppressed because it is too large Load Diff

1196
32on64-memop.patch Normal file

File diff suppressed because it is too large Load Diff

292
32on64-mmuop.patch Normal file
View 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
View 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);

View 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
View 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
View 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
View 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
View 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
View 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
View 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, &current->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, &current->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
View 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
View 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
View 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
View 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
View 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

View File

@ -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
View 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)

View File

@ -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

View File

@ -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")

View File

@ -12,7 +12,7 @@ dir=$(dirname "$0")
#set -x
par=`xenstore-read $XENBUS_PATH/params` || true
echo $par
#echo $par
case "$command" in
add)

View File

@ -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
View 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
View 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
View 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 ] || \

View File

@ -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
View 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
View 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
View 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
View 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"

View File

@ -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

View File

@ -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

File diff suppressed because it is too large Load Diff

View 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
View 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
View 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
View 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
View 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
View 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
View 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;

View File

@ -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

View File

@ -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
View 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
View 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

File diff suppressed because it is too large Load Diff

13
npt_part2.patch Normal file
View 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);

View 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
View 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
View 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, ...)
{

View File

@ -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
View 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! */

View 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,

View 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
View 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
View 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,
},
}

File diff suppressed because it is too large Load Diff

View 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;

View 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

File diff suppressed because it is too large Load Diff

View 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

File diff suppressed because it is too large Load Diff

44
vgacon-50-lines.patch Normal file
View 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
View 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
View 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
View 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
View 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
View 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;

View File

@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:50d18f4e082110db27a98ffcd39d98cc12058a6dd89c58a378ce283fa911ba89
size 4580110

View File

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:ed27830300bd6d68d35737d3e8deefe815115f2d165574c8a1f527ee8ec6a606
size 5383589

View File

@ -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

View 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))

View 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
View 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

View File

@ -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
View 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

View File

@ -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();

View File

@ -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

View File

@ -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/
+

View File

@ -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)

View File

@ -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)

View 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)

View File

@ -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

View File

@ -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)

View File

@ -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;

View File

@ -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;
};

View File

@ -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;

View File

@ -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
View 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)

View File

@ -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