This commit is contained in:
parent
28b141bb6f
commit
0a63222b01
@ -12,7 +12,7 @@ Index: xen-3.1-testing/tools/python/xen/xend/XendDomainInfo.py
|
||||
===================================================================
|
||||
--- xen-3.1-testing.orig/tools/python/xen/xend/XendDomainInfo.py
|
||||
+++ xen-3.1-testing/tools/python/xen/xend/XendDomainInfo.py
|
||||
@@ -1490,8 +1490,7 @@ class XendDomainInfo:
|
||||
@@ -1472,8 +1472,7 @@ class XendDomainInfo:
|
||||
try:
|
||||
self.image = image.create(self, self.info)
|
||||
|
484
32on64-call-gates.patch
Normal file
484
32on64-call-gates.patch
Normal file
@ -0,0 +1,484 @@
|
||||
Index: 2007-05-14/xen/arch/x86/traps.c
|
||||
===================================================================
|
||||
--- 2007-05-14.orig/xen/arch/x86/traps.c 2007-05-14 14:39:42.000000000 +0200
|
||||
+++ 2007-05-14/xen/arch/x86/traps.c 2007-05-14 14:40:03.000000000 +0200
|
||||
@@ -1091,6 +1091,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_pv_32on64_vcpu(v) )
|
||||
+ {
|
||||
+ 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,
|
||||
@@ -1158,6 +1215,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 ) \
|
||||
@@ -1760,6 +1819,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;
|
||||
@@ -1805,6 +2194,8 @@ asmlinkage int do_general_protection(str
|
||||
return do_guest_trap(vector, regs, 0);
|
||||
}
|
||||
}
|
||||
+ else if ( is_pv_32on64_vcpu(v) && regs->error_code )
|
||||
+ return emulate_gate_op(regs);
|
||||
|
||||
/* Emulate some simple privileged and I/O instructions. */
|
||||
if ( (regs->error_code == 0) &&
|
||||
Index: 2007-05-14/xen/arch/x86/x86_64/mm.c
|
||||
===================================================================
|
||||
--- 2007-05-14.orig/xen/arch/x86/x86_64/mm.c 2007-05-03 09:45:09.000000000 +0200
|
||||
+++ 2007-05-14/xen/arch/x86/x86_64/mm.c 2007-05-14 14:40:03.000000000 +0200
|
||||
@@ -372,14 +372,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) )
|
||||
@@ -397,18 +399,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_pv_32on64_domain(dom) ? 0xe0 : 0xff) )
|
||||
goto bad;
|
||||
|
||||
good:
|
||||
+ d->a = a;
|
||||
+ d->b = b;
|
||||
return 1;
|
||||
bad:
|
||||
return 0;
|
13
32on64-cpuid.patch
Normal file
13
32on64-cpuid.patch
Normal file
@ -0,0 +1,13 @@
|
||||
Index: 2007-04-27/xen/arch/x86/traps.c
|
||||
===================================================================
|
||||
--- 2007-04-27.orig/xen/arch/x86/traps.c 2007-04-27 11:02:48.000000000 +0200
|
||||
+++ 2007-04-27/xen/arch/x86/traps.c 2007-05-09 17:56:43.000000000 +0200
|
||||
@@ -594,6 +594,8 @@ static int emulate_forced_invalid_op(str
|
||||
else if ( regs->eax == 0x80000001 )
|
||||
{
|
||||
/* Modify Feature Information. */
|
||||
+ if ( is_pv_32on64_vcpu(current) )
|
||||
+ clear_bit(X86_FEATURE_SYSCALL % 32, &d);
|
||||
clear_bit(X86_FEATURE_RDTSCP % 32, &d);
|
||||
}
|
||||
else
|
119
32on64-ioemu.patch
Normal file
119
32on64-ioemu.patch
Normal file
@ -0,0 +1,119 @@
|
||||
Index: 2007-04-27/tools/ioemu/target-i386-dm/helper2.c
|
||||
===================================================================
|
||||
--- 2007-04-27.orig/tools/ioemu/target-i386-dm/helper2.c 2007-04-23 12:41:32.000000000 +0200
|
||||
+++ 2007-04-27/tools/ioemu/target-i386-dm/helper2.c 2007-05-09 17:58:07.000000000 +0200
|
||||
@@ -322,7 +322,7 @@ void cpu_ioreq_pio(CPUState *env, ioreq_
|
||||
do_outp(env, req->addr, req->size, req->data);
|
||||
} else {
|
||||
for (i = 0; i < req->count; i++) {
|
||||
- unsigned long tmp;
|
||||
+ unsigned long tmp = 0;
|
||||
|
||||
read_physical((target_phys_addr_t) req->data
|
||||
+ (sign * i * req->size),
|
||||
@@ -354,7 +354,7 @@ void cpu_ioreq_move(CPUState *env, ioreq
|
||||
}
|
||||
}
|
||||
} else {
|
||||
- unsigned long tmp;
|
||||
+ target_ulong tmp;
|
||||
|
||||
if (req->dir == IOREQ_READ) {
|
||||
for (i = 0; i < req->count; i++) {
|
||||
@@ -380,14 +380,14 @@ void cpu_ioreq_move(CPUState *env, ioreq
|
||||
|
||||
void cpu_ioreq_and(CPUState *env, ioreq_t *req)
|
||||
{
|
||||
- unsigned long tmp1, tmp2;
|
||||
+ target_ulong tmp1, tmp2;
|
||||
|
||||
if (req->data_is_ptr != 0)
|
||||
hw_error("expected scalar value");
|
||||
|
||||
read_physical(req->addr, req->size, &tmp1);
|
||||
if (req->dir == IOREQ_WRITE) {
|
||||
- tmp2 = tmp1 & (unsigned long) req->data;
|
||||
+ tmp2 = tmp1 & (target_ulong) req->data;
|
||||
write_physical(req->addr, req->size, &tmp2);
|
||||
}
|
||||
req->data = tmp1;
|
||||
@@ -395,14 +395,14 @@ void cpu_ioreq_and(CPUState *env, ioreq_
|
||||
|
||||
void cpu_ioreq_add(CPUState *env, ioreq_t *req)
|
||||
{
|
||||
- unsigned long tmp1, tmp2;
|
||||
+ target_ulong tmp1, tmp2;
|
||||
|
||||
if (req->data_is_ptr != 0)
|
||||
hw_error("expected scalar value");
|
||||
|
||||
read_physical(req->addr, req->size, &tmp1);
|
||||
if (req->dir == IOREQ_WRITE) {
|
||||
- tmp2 = tmp1 + (unsigned long) req->data;
|
||||
+ tmp2 = tmp1 + (target_ulong) req->data;
|
||||
write_physical(req->addr, req->size, &tmp2);
|
||||
}
|
||||
req->data = tmp1;
|
||||
@@ -410,14 +410,14 @@ void cpu_ioreq_add(CPUState *env, ioreq_
|
||||
|
||||
void cpu_ioreq_sub(CPUState *env, ioreq_t *req)
|
||||
{
|
||||
- unsigned long tmp1, tmp2;
|
||||
+ target_ulong tmp1, tmp2;
|
||||
|
||||
if (req->data_is_ptr != 0)
|
||||
hw_error("expected scalar value");
|
||||
|
||||
read_physical(req->addr, req->size, &tmp1);
|
||||
if (req->dir == IOREQ_WRITE) {
|
||||
- tmp2 = tmp1 - (unsigned long) req->data;
|
||||
+ tmp2 = tmp1 - (target_ulong) req->data;
|
||||
write_physical(req->addr, req->size, &tmp2);
|
||||
}
|
||||
req->data = tmp1;
|
||||
@@ -425,14 +425,14 @@ void cpu_ioreq_sub(CPUState *env, ioreq_
|
||||
|
||||
void cpu_ioreq_or(CPUState *env, ioreq_t *req)
|
||||
{
|
||||
- unsigned long tmp1, tmp2;
|
||||
+ target_ulong tmp1, tmp2;
|
||||
|
||||
if (req->data_is_ptr != 0)
|
||||
hw_error("expected scalar value");
|
||||
|
||||
read_physical(req->addr, req->size, &tmp1);
|
||||
if (req->dir == IOREQ_WRITE) {
|
||||
- tmp2 = tmp1 | (unsigned long) req->data;
|
||||
+ tmp2 = tmp1 | (target_ulong) req->data;
|
||||
write_physical(req->addr, req->size, &tmp2);
|
||||
}
|
||||
req->data = tmp1;
|
||||
@@ -440,14 +440,14 @@ void cpu_ioreq_or(CPUState *env, ioreq_t
|
||||
|
||||
void cpu_ioreq_xor(CPUState *env, ioreq_t *req)
|
||||
{
|
||||
- unsigned long tmp1, tmp2;
|
||||
+ target_ulong tmp1, tmp2;
|
||||
|
||||
if (req->data_is_ptr != 0)
|
||||
hw_error("expected scalar value");
|
||||
|
||||
read_physical(req->addr, req->size, &tmp1);
|
||||
if (req->dir == IOREQ_WRITE) {
|
||||
- tmp2 = tmp1 ^ (unsigned long) req->data;
|
||||
+ tmp2 = tmp1 ^ (target_ulong) req->data;
|
||||
write_physical(req->addr, req->size, &tmp2);
|
||||
}
|
||||
req->data = tmp1;
|
||||
@@ -495,8 +495,9 @@ void cpu_ioreq_xchg(CPUState *env, ioreq
|
||||
|
||||
void __handle_ioreq(CPUState *env, ioreq_t *req)
|
||||
{
|
||||
- if (!req->data_is_ptr && req->dir == IOREQ_WRITE && req->size != 4)
|
||||
- req->data &= (1UL << (8 * req->size)) - 1;
|
||||
+ if (!req->data_is_ptr && req->dir == IOREQ_WRITE &&
|
||||
+ req->size < sizeof(target_ulong))
|
||||
+ req->data &= ((target_ulong)1 << (8 * req->size)) - 1;
|
||||
|
||||
switch (req->type) {
|
||||
case IOREQ_TYPE_PIO:
|
29
check-libvncserver.patch
Normal file
29
check-libvncserver.patch
Normal file
@ -0,0 +1,29 @@
|
||||
Index: 2007-04-27/tools/check/check_libvncserver
|
||||
===================================================================
|
||||
--- 2007-04-27.orig/tools/check/check_libvncserver 2006-12-04 08:49:57.000000000 +0100
|
||||
+++ 2007-04-27/tools/check/check_libvncserver 2007-04-27 09:31:02.000000000 +0200
|
||||
@@ -10,6 +10,7 @@ fi
|
||||
RC=0
|
||||
|
||||
LIBVNCSERVER_CONFIG="$(which libvncserver-config)"
|
||||
+tmpfile=$(mktemp)
|
||||
|
||||
if test -z ${LIBVNCSERVER_CONFIG}; then
|
||||
RC=1
|
||||
@@ -22,6 +23,16 @@ if test $RC -ne 0; then
|
||||
echo "FAILED"
|
||||
echo " *** libvncserver-config is missing. "
|
||||
echo " *** Please install libvncserver."
|
||||
+elif ! ld $($LIBVNCSERVER_CONFIG --libs) -o $tmpfile >/dev/null 2>&1; then
|
||||
+ echo "FAILED"
|
||||
+ echo " *** dependency libraries for libvncserver are missing: "
|
||||
+ RC=1
|
||||
+ for i in $(ld $($LIBVNCSERVER_CONFIG --libs) -o $tmpfile 2>&1 >/dev/null); do
|
||||
+ case $i in
|
||||
+ -l*) echo lib${i#-l}
|
||||
+ esac
|
||||
+ done
|
||||
fi
|
||||
+rm -f $tmpfile
|
||||
|
||||
exit $RC
|
108
check-xenapi.patch
Normal file
108
check-xenapi.patch
Normal file
@ -0,0 +1,108 @@
|
||||
Index: 2007-04-18/tools/check/Makefile
|
||||
===================================================================
|
||||
--- 2007-04-18.orig/tools/check/Makefile 2006-12-14 22:49:54.000000000 +0100
|
||||
+++ 2007-04-18/tools/check/Makefile 2007-04-24 16:32:39.000000000 +0200
|
||||
@@ -7,7 +7,7 @@ all: build
|
||||
# Check this machine is OK for building on.
|
||||
.PHONY: build
|
||||
build:
|
||||
- XENFB_TOOLS=$(XENFB_TOOLS) ./chk build
|
||||
+ XENFB_TOOLS=$(XENFB_TOOLS) LIBXENAPI_BINDINGS=$(LIBXENAPI_BINDINGS) ./chk build
|
||||
|
||||
# Check this machine is OK for installing on.
|
||||
# DO NOT use this check from 'make install' in the parent
|
||||
@@ -15,7 +15,7 @@ build:
|
||||
# copy rather than actually installing.
|
||||
.PHONY: install
|
||||
install:
|
||||
- XENFB_TOOLS=$(XENFB_TOOLS) ./chk install
|
||||
+ XENFB_TOOLS=$(XENFB_TOOLS) LIBXENAPI_BINDINGS=$(LIBXENAPI_BINDINGS) ./chk install
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
Index: 2007-04-18/tools/check/check_curl
|
||||
===================================================================
|
||||
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
|
||||
+++ 2007-04-18/tools/check/check_curl 2007-04-24 16:41:08.000000000 +0200
|
||||
@@ -0,0 +1,38 @@
|
||||
+#!/bin/sh
|
||||
+# CHECK-BUILD CHECK-INSTALL
|
||||
+
|
||||
+if [ ! "$LIBXENAPI_BINDINGS" = "y" ]
|
||||
+then
|
||||
+ echo -n "unused, "
|
||||
+ exit 0
|
||||
+fi
|
||||
+
|
||||
+RC=0
|
||||
+
|
||||
+CURL_CONFIG="$(which curl-config)"
|
||||
+tmpfile=$(mktemp)
|
||||
+
|
||||
+if test -z ${CURL_CONFIG}; then
|
||||
+ RC=1
|
||||
+else
|
||||
+ ${CURL_CONFIG} --libs 2>&1 > /dev/null
|
||||
+ RC=$?
|
||||
+fi
|
||||
+
|
||||
+if test $RC -ne 0; then
|
||||
+ echo "FAILED"
|
||||
+ echo " *** curl-config is missing. "
|
||||
+ echo " *** Please install curl-devel."
|
||||
+elif ! ld $($CURL_CONFIG --libs) -o $tmpfile >/dev/null 2>&1; then
|
||||
+ echo "FAILED"
|
||||
+ echo " *** dependency libraries for curl are missing: "
|
||||
+ RC=1
|
||||
+ for i in $(ld $($CURL_CONFIG --libs) -o $tmpfile 2>&1 >/dev/null); do
|
||||
+ case $i in
|
||||
+ -l*) echo lib${i#-l}
|
||||
+ esac
|
||||
+ done
|
||||
+fi
|
||||
+rm -f $tmpfile
|
||||
+
|
||||
+exit $RC
|
||||
Index: 2007-04-18/tools/check/check_xml2
|
||||
===================================================================
|
||||
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
|
||||
+++ 2007-04-18/tools/check/check_xml2 2007-04-24 16:41:16.000000000 +0200
|
||||
@@ -0,0 +1,38 @@
|
||||
+#!/bin/sh
|
||||
+# CHECK-BUILD CHECK-INSTALL
|
||||
+
|
||||
+if [ ! "$LIBXENAPI_BINDINGS" = "y" ]
|
||||
+then
|
||||
+ echo -n "unused, "
|
||||
+ exit 0
|
||||
+fi
|
||||
+
|
||||
+RC=0
|
||||
+
|
||||
+XML2_CONFIG="$(which xml2-config)"
|
||||
+tmpfile=$(mktemp)
|
||||
+
|
||||
+if test -z ${XML2_CONFIG}; then
|
||||
+ RC=1
|
||||
+else
|
||||
+ ${XML2_CONFIG} --libs 2>&1 > /dev/null
|
||||
+ RC=$?
|
||||
+fi
|
||||
+
|
||||
+if test $RC -ne 0; then
|
||||
+ echo "FAILED"
|
||||
+ echo " *** xml2-config is missing. "
|
||||
+ echo " *** Please install libxml2-devel."
|
||||
+elif ! ld $($XML2_CONFIG --libs) -o $tmpfile >/dev/null 2>&1; then
|
||||
+ echo "FAILED"
|
||||
+ echo " *** dependency libraries for xml2 are missing: "
|
||||
+ RC=1
|
||||
+ for i in $(ld $($XML2_CONFIG --libs) -o $tmpfile 2>&1 >/dev/null); do
|
||||
+ case $i in
|
||||
+ -l*) echo lib${i#-l}
|
||||
+ esac
|
||||
+ done
|
||||
+fi
|
||||
+rm -f $tmpfile
|
||||
+
|
||||
+exit $RC
|
@ -115,9 +115,9 @@ class Wholedisk:
|
||||
if not os.path.exists(ldev):
|
||||
break
|
||||
i += 1
|
||||
fd = os.popen("losetup %s %s 2> /dev/null" % (ldev, self.pdev))
|
||||
fd = os.popen("losetup %s '%s' 2> /dev/null" % (ldev, self.pdev))
|
||||
if not fd.close():
|
||||
verbose_print("losetup %s %s" % (ldev, self.pdev))
|
||||
verbose_print("losetup %s '%s'" % (ldev, self.pdev))
|
||||
self.ldev = ldev
|
||||
break
|
||||
if not self.ldev:
|
||||
@ -149,13 +149,14 @@ 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()))
|
||||
pname = pname.strip()
|
||||
pno = int(traildigits(pname))
|
||||
#if pname.rfind('/') != -1:
|
||||
# pname = pname[pname.rfind('/')+1:]
|
||||
#pname = self.pdev[:self.pdev.rfind('/')] + '/' + pname
|
||||
@ -177,8 +178,8 @@ class Wholedisk:
|
||||
if not self.mapped:
|
||||
self.loopsetup()
|
||||
if self.pcount:
|
||||
verbose_print("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
|
||||
|
||||
@ -192,8 +193,8 @@ class Wholedisk:
|
||||
self.mapped -= 1
|
||||
if not self.mapped:
|
||||
if self.pcount:
|
||||
verbose_print("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()
|
||||
|
||||
@ -251,11 +252,11 @@ class Partition:
|
||||
if fstype:
|
||||
mopts += " -t %s" % fstype
|
||||
mopts += " -o %s" % options
|
||||
verbose_print("mount %s %s %s" % (mopts, self.pdev, mtpt))
|
||||
fd = os.popen("mount %s %s %s" % (mopts, self.pdev, 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("Error %i from mount %s %s on %s" % \
|
||||
raise RuntimeError("Error %i from mount %s '%s' on %s" % \
|
||||
(err, mopts, self.pdev, mtpt))
|
||||
self.mountpoint = mtpt
|
||||
|
||||
|
660
edd.patch
Normal file
660
edd.patch
Normal file
@ -0,0 +1,660 @@
|
||||
Index: 2007-03-19/xen/arch/x86/Makefile
|
||||
===================================================================
|
||||
--- 2007-03-19.orig/xen/arch/x86/Makefile 2007-03-19 14:07:06.000000000 +0100
|
||||
+++ 2007-03-19/xen/arch/x86/Makefile 2007-03-19 14:07:47.000000000 +0100
|
||||
@@ -78,7 +78,7 @@ xen.lds: $(TARGET_SUBARCH)/xen.lds.S $(H
|
||||
boot/mkelf32: boot/mkelf32.c
|
||||
$(HOSTCC) $(HOSTCFLAGS) -o $@ $<
|
||||
|
||||
-boot/$(TARGET_SUBARCH).o: boot/realmode.S
|
||||
+boot/$(TARGET_SUBARCH).o: boot/realmode.S boot/edd.S
|
||||
|
||||
.PHONY: clean
|
||||
clean::
|
||||
Index: 2007-03-19/xen/arch/x86/boot/edd.S
|
||||
===================================================================
|
||||
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
|
||||
+++ 2007-03-19/xen/arch/x86/boot/edd.S 2007-03-19 14:07:47.000000000 +0100
|
||||
@@ -0,0 +1,217 @@
|
||||
+/*
|
||||
+ * BIOS Enhanced Disk Drive support
|
||||
+ * Copyright (C) 2002, 2003, 2004 Dell, Inc.
|
||||
+ * by Matt Domsch <Matt_Domsch@dell.com> October 2002
|
||||
+ * conformant to T13 Committee www.t13.org
|
||||
+ * projects 1572D, 1484D, 1386D, 1226DT
|
||||
+ * disk signature read by Matt Domsch <Matt_Domsch@dell.com>
|
||||
+ * and Andrew Wilks <Andrew_Wilks@dell.com> September 2003, June 2004
|
||||
+ * legacy CHS retrieval by Patrick J. LoPresti <patl@users.sourceforge.net>
|
||||
+ * March 2004
|
||||
+ * Command line option parsing, Matt Domsch, November 2004
|
||||
+ * Xen adoption by Jan Beulich <jbeulich@novell.com>, February 2007
|
||||
+ */
|
||||
+
|
||||
+#include <xen/edd.h>
|
||||
+
|
||||
+# It is assumed that %ds == INITSEG here
|
||||
+
|
||||
+ movb $0, (EDD_MBR_SIG_NR_BUF)
|
||||
+ movb $0, (EDDNR)
|
||||
+
|
||||
+# Check the command line for options:
|
||||
+# edd=of disables EDD completely (edd=off)
|
||||
+# edd=sk skips the MBR test (edd=skipmbr)
|
||||
+# edd=on re-enables EDD (edd=on)
|
||||
+
|
||||
+ pushl %esi
|
||||
+ movw $SYM_REAL(edd_mbr_sig_start), %di # Default to edd=on
|
||||
+
|
||||
+ movl %cs:SYM_REAL(cmd_line_ptr), %esi
|
||||
+ andl %esi, %esi
|
||||
+ jz done_cl
|
||||
+
|
||||
+# Convert to a real-mode pointer in fs:si
|
||||
+ movl %esi, %eax
|
||||
+ shrl $4, %eax
|
||||
+ mov %ax, %fs
|
||||
+ andw $0xf, %si
|
||||
+
|
||||
+# fs:si has the pointer to the command line now
|
||||
+
|
||||
+# Loop through kernel command line one byte at a time. Just in
|
||||
+# case the loader is buggy and failed to null-terminate the command line
|
||||
+# terminate if we get close enough to the end of the segment that we
|
||||
+# cannot fit "edd=XX"...
|
||||
+cl_atspace:
|
||||
+ cmpw $-5, %si # Watch for segment wraparound
|
||||
+ jae done_cl
|
||||
+ movl %fs:(%si), %eax
|
||||
+ andb %al, %al # End of line?
|
||||
+ jz done_cl
|
||||
+ cmpl $EDD_CL_EQUALS, %eax
|
||||
+ jz found_edd_equals
|
||||
+ cmpb $0x20, %al # <= space consider whitespace
|
||||
+ ja cl_skipword
|
||||
+ incw %si
|
||||
+ jmp cl_atspace
|
||||
+
|
||||
+cl_skipword:
|
||||
+ cmpw $-5, %si # Watch for segment wraparound
|
||||
+ jae done_cl
|
||||
+ movb %fs:(%si), %al # End of string?
|
||||
+ andb %al, %al
|
||||
+ jz done_cl
|
||||
+ cmpb $0x20, %al
|
||||
+ jbe cl_atspace
|
||||
+ incw %si
|
||||
+ jmp cl_skipword
|
||||
+
|
||||
+found_edd_equals:
|
||||
+# only looking at first two characters after equals
|
||||
+# late overrides early on the command line, so keep going after finding something
|
||||
+ movw %fs:4(%si), %ax
|
||||
+ cmpw $EDD_CL_OFF, %ax # edd=of
|
||||
+ je do_edd_off
|
||||
+ cmpw $EDD_CL_SKIP, %ax # edd=sk
|
||||
+ je do_edd_skipmbr
|
||||
+ cmpw $EDD_CL_ON, %ax # edd=on
|
||||
+ je do_edd_on
|
||||
+ jmp cl_skipword
|
||||
+do_edd_skipmbr:
|
||||
+ movw $SYM_REAL(edd_start), %di
|
||||
+ jmp cl_skipword
|
||||
+do_edd_off:
|
||||
+ movw $SYM_REAL(edd_done), %di
|
||||
+ jmp cl_skipword
|
||||
+do_edd_on:
|
||||
+ movw $SYM_REAL(edd_mbr_sig_start), %di
|
||||
+ jmp cl_skipword
|
||||
+
|
||||
+done_cl:
|
||||
+ popl %esi
|
||||
+ jmpw *%di
|
||||
+
|
||||
+# Read the first sector of each BIOS disk device and store the 4-byte signature
|
||||
+edd_mbr_sig_start:
|
||||
+ movb $0x80, %dl # from device 80
|
||||
+ movw $EDD_MBR_SIG_BUF, %bx # store buffer ptr in bx
|
||||
+edd_mbr_sig_read:
|
||||
+ movl $0xFFFFFFFF, %eax
|
||||
+ movl %eax, (%bx) # assume failure
|
||||
+ pushw %bx
|
||||
+ movb $READ_SECTORS, %ah
|
||||
+ movb $1, %al # read 1 sector
|
||||
+ movb $0, %dh # at head 0
|
||||
+ movw $1, %cx # cylinder 0, sector 0
|
||||
+ pushw %es
|
||||
+ pushw %ds
|
||||
+ popw %es
|
||||
+ movw $EDDBUF, %bx # disk's data goes into EDDBUF
|
||||
+ pushw %dx # work around buggy BIOSes
|
||||
+ stc # work around buggy BIOSes
|
||||
+ int $0x13
|
||||
+ sti # work around buggy BIOSes
|
||||
+ popw %dx
|
||||
+ popw %es
|
||||
+ popw %bx
|
||||
+ jc edd_mbr_sig_done # on failure, we're done.
|
||||
+ cmpb $0, %ah # some BIOSes do not set CF
|
||||
+ jne edd_mbr_sig_done # on failure, we're done.
|
||||
+ movl (EDDBUF+EDD_MBR_SIG_OFFSET), %eax # read sig out of the MBR
|
||||
+ movl %eax, (%bx) # store success
|
||||
+ incb (EDD_MBR_SIG_NR_BUF) # note that we stored something
|
||||
+ incb %dl # increment to next device
|
||||
+ addw $4, %bx # increment sig buffer ptr
|
||||
+ cmpb $EDD_MBR_SIG_MAX, (EDD_MBR_SIG_NR_BUF) # Out of space?
|
||||
+ jb edd_mbr_sig_read # keep looping
|
||||
+edd_mbr_sig_done:
|
||||
+
|
||||
+# Do the BIOS Enhanced Disk Drive calls
|
||||
+# This consists of two calls:
|
||||
+# int 13h ah=41h "Check Extensions Present"
|
||||
+# int 13h ah=48h "Get Device Parameters"
|
||||
+# int 13h ah=08h "Legacy Get Device Parameters"
|
||||
+#
|
||||
+# A buffer of size EDDMAXNR*(EDDEXTSIZE+EDDPARMSIZE) is reserved for our use
|
||||
+# in the boot_params at EDDBUF. The first four bytes of which are
|
||||
+# used to store the device number, interface support map and version
|
||||
+# results from fn41. The next four bytes are used to store the legacy
|
||||
+# cylinders, heads, and sectors from fn08. The following 74 bytes are used to
|
||||
+# store the results from fn48. Starting from device 80h, fn41, then fn48
|
||||
+# are called and their results stored in EDDBUF+n*(EDDEXTSIZE+EDDPARMIZE).
|
||||
+# Then the pointer is incremented to store the data for the next call.
|
||||
+# This repeats until either a device doesn't exist, or until EDDMAXNR
|
||||
+# devices have been stored.
|
||||
+# The one tricky part is that ds:si always points EDDEXTSIZE bytes into
|
||||
+# the structure, and the fn41 and fn08 results are stored at offsets
|
||||
+# from there. This removes the need to increment the pointer for
|
||||
+# every store, and leaves it ready for the fn48 call.
|
||||
+# A second one-byte buffer, EDDNR, in the boot_params stores
|
||||
+# the number of BIOS devices which exist, up to EDDMAXNR.
|
||||
+# In setup.c, copy_edd() stores both boot_params buffers away
|
||||
+# for later use, as they would get overwritten otherwise.
|
||||
+# This code is sensitive to the size of the structs in edd.h
|
||||
+edd_start:
|
||||
+ # %ds points to the bootsector
|
||||
+ # result buffer for fn48
|
||||
+ movw $EDDBUF+EDDEXTSIZE, %si # in ds:si, fn41 results
|
||||
+ # kept just before that
|
||||
+ movb $0x80, %dl # BIOS device 0x80
|
||||
+
|
||||
+edd_check_ext:
|
||||
+ movb $CHECKEXTENSIONSPRESENT, %ah # Function 41
|
||||
+ movw $EDDMAGIC1, %bx # magic
|
||||
+ int $0x13 # make the call
|
||||
+ jc edd_done # no more BIOS devices
|
||||
+
|
||||
+ cmpw $EDDMAGIC2, %bx # is magic right?
|
||||
+ jne edd_next # nope, next...
|
||||
+
|
||||
+ movb %dl, %ds:-8(%si) # store device number
|
||||
+ movb %ah, %ds:-7(%si) # store version
|
||||
+ movw %cx, %ds:-6(%si) # store extensions
|
||||
+ incb (EDDNR) # note that we stored something
|
||||
+
|
||||
+edd_get_device_params:
|
||||
+ movw $EDDPARMSIZE, %ds:(%si) # put size
|
||||
+ movw $0x0, %ds:2(%si) # work around buggy BIOSes
|
||||
+ movb $GETDEVICEPARAMETERS, %ah # Function 48
|
||||
+ int $0x13 # make the call
|
||||
+ # Don't check for fail return
|
||||
+ # it doesn't matter.
|
||||
+edd_get_legacy_chs:
|
||||
+ xorw %ax, %ax
|
||||
+ movw %ax, %ds:-4(%si)
|
||||
+ movw %ax, %ds:-2(%si)
|
||||
+ # Ralf Brown's Interrupt List says to set ES:DI to
|
||||
+ # 0000h:0000h "to guard against BIOS bugs"
|
||||
+ pushw %es
|
||||
+ movw %ax, %es
|
||||
+ movw %ax, %di
|
||||
+ pushw %dx # legacy call clobbers %dl
|
||||
+ movb $LEGACYGETDEVICEPARAMETERS, %ah # Function 08
|
||||
+ int $0x13 # make the call
|
||||
+ jc edd_legacy_done # failed
|
||||
+ movb %cl, %al # Low 6 bits are max
|
||||
+ andb $0x3F, %al # sector number
|
||||
+ movb %al, %ds:-1(%si) # Record max sect
|
||||
+ movb %dh, %ds:-2(%si) # Record max head number
|
||||
+ movb %ch, %al # Low 8 bits of max cyl
|
||||
+ shr $6, %cl
|
||||
+ movb %cl, %ah # High 2 bits of max cyl
|
||||
+ movw %ax, %ds:-4(%si)
|
||||
+
|
||||
+edd_legacy_done:
|
||||
+ popw %dx
|
||||
+ popw %es
|
||||
+ movw %si, %ax # increment si
|
||||
+ addw $EDDPARMSIZE+EDDEXTSIZE, %ax
|
||||
+ movw %ax, %si
|
||||
+
|
||||
+edd_next:
|
||||
+ incb %dl # increment to next device
|
||||
+ cmpb $EDDMAXNR, (EDDNR) # Out of space?
|
||||
+ jb edd_check_ext # keep looping
|
||||
+
|
||||
+edd_done:
|
||||
Index: 2007-03-19/xen/arch/x86/boot/realmode.S
|
||||
===================================================================
|
||||
--- 2007-03-19.orig/xen/arch/x86/boot/realmode.S 2007-03-21 14:34:55.000000000 +0100
|
||||
+++ 2007-03-19/xen/arch/x86/boot/realmode.S 2007-03-21 14:35:06.000000000 +0100
|
||||
@@ -120,3 +120,26 @@ cmd_line_ptr: .long 0
|
||||
.Lgdt: .skip 2+4
|
||||
.Lidt: .skip 2+4
|
||||
.previous
|
||||
+
|
||||
+#define EDDNR SYM_REAL(eddnr)
|
||||
+#define EDDBUF SYM_REAL(eddbuf)
|
||||
+#define EDD_MBR_SIG_NR_BUF SYM_REAL(edd_mbr_sig_nr_buf)
|
||||
+#define EDD_MBR_SIG_BUF SYM_REAL(edd_mbr_sig_buf)
|
||||
+
|
||||
+edd:
|
||||
+#include "edd.S"
|
||||
+ ret
|
||||
+
|
||||
+ .section .real.data
|
||||
+ .globl eddnr, eddbuf, edd_mbr_sig_nr_buf, edd_mbr_sig_buf
|
||||
+ .align 4
|
||||
+eddbuf: .skip EDDMAXNR * (EDDEXTSIZE + EDDPARMSIZE)
|
||||
+#if EDDMAXNR * (EDDEXTSIZE + EDDPARMSIZE) < 512
|
||||
+/* Must have space for a full 512-byte sector */
|
||||
+ .skip 512 - EDDMAXNR * (EDDEXTSIZE + EDDPARMSIZE)
|
||||
+#endif
|
||||
+ .align 4
|
||||
+edd_mbr_sig_buf: .skip EDD_MBR_SIG_MAX * 4
|
||||
+eddnr: .skip 1
|
||||
+edd_mbr_sig_nr_buf: .skip 1
|
||||
+ .previous
|
||||
Index: 2007-03-19/xen/arch/x86/boot/x86_32.S
|
||||
===================================================================
|
||||
--- 2007-03-19.orig/xen/arch/x86/boot/x86_32.S 2007-03-19 14:07:06.000000000 +0100
|
||||
+++ 2007-03-19/xen/arch/x86/boot/x86_32.S 2007-03-19 14:07:47.000000000 +0100
|
||||
@@ -90,6 +90,9 @@ __start:
|
||||
lea __PAGE_OFFSET(%ebx),%eax
|
||||
push %eax
|
||||
|
||||
+ pushl $SYM_PHYS(edd)
|
||||
+ call realmode
|
||||
+
|
||||
#ifdef CONFIG_X86_PAE
|
||||
/* Initialize low and high mappings of all memory with 2MB pages */
|
||||
mov $SYM_PHYS(idle_pg_table_l2),%edi
|
||||
Index: 2007-03-19/xen/arch/x86/boot/x86_64.S
|
||||
===================================================================
|
||||
--- 2007-03-19.orig/xen/arch/x86/boot/x86_64.S 2007-03-19 14:07:06.000000000 +0100
|
||||
+++ 2007-03-19/xen/arch/x86/boot/x86_64.S 2007-03-19 14:07:47.000000000 +0100
|
||||
@@ -73,6 +73,8 @@ __start:
|
||||
mov %ebx,SYM_PHYS(multiboot_ptr)
|
||||
|
||||
lss SYM_PHYS(.Lstack_start),%esp
|
||||
+ pushl $SYM_PHYS(edd)
|
||||
+ call realmode
|
||||
|
||||
/* We begin by interrogating the CPU for the presence of long mode. */
|
||||
mov $0x80000000,%eax
|
||||
Index: 2007-03-19/xen/arch/x86/platform_hypercall.c
|
||||
===================================================================
|
||||
--- 2007-03-19.orig/xen/arch/x86/platform_hypercall.c 2007-03-21 14:32:46.000000000 +0100
|
||||
+++ 2007-03-19/xen/arch/x86/platform_hypercall.c 2007-03-19 14:07:47.000000000 +0100
|
||||
@@ -17,6 +17,7 @@
|
||||
#include <xen/trace.h>
|
||||
#include <xen/console.h>
|
||||
#include <xen/iocap.h>
|
||||
+#include <xen/edd.h>
|
||||
#include <xen/guest_access.h>
|
||||
#include <asm/current.h>
|
||||
#include <public/platform.h>
|
||||
@@ -26,8 +27,14 @@
|
||||
#ifndef COMPAT
|
||||
typedef long ret_t;
|
||||
DEFINE_SPINLOCK(xenpf_lock);
|
||||
+struct edd edd;
|
||||
+# undef copy_from_compat
|
||||
+# define copy_from_compat copy_from_guest
|
||||
+# undef copy_to_compat
|
||||
+# define copy_to_compat copy_to_guest
|
||||
#else
|
||||
extern spinlock_t xenpf_lock;
|
||||
+extern struct edd edd;
|
||||
#endif
|
||||
|
||||
ret_t do_platform_op(XEN_GUEST_HANDLE(xen_platform_op_t) u_xenpf_op)
|
||||
@@ -151,6 +158,73 @@ ret_t do_platform_op(XEN_GUEST_HANDLE(xe
|
||||
}
|
||||
break;
|
||||
|
||||
+ case XENPF_firmware_info:
|
||||
+ switch ( op->u.firmware_info.type )
|
||||
+ {
|
||||
+ case XEN_FW_DISK_INFO:
|
||||
+ if ( op->u.firmware_info.index < edd.edd_info_nr )
|
||||
+ {
|
||||
+ const struct edd_info *info = edd.edd_info + op->u.firmware_info.index;
|
||||
+
|
||||
+ op->u.firmware_info.u.disk_info.max_cylinder = info->legacy_max_cylinder;
|
||||
+ op->u.firmware_info.u.disk_info.max_head = info->legacy_max_head;
|
||||
+ op->u.firmware_info.u.disk_info.sectors_per_track = info->legacy_sectors_per_track;
|
||||
+ if ( copy_field_to_guest(u_xenpf_op, op, u.firmware_info.u.disk_info) )
|
||||
+ ret = -EFAULT;
|
||||
+ }
|
||||
+ else
|
||||
+ ret = -ESRCH;
|
||||
+ break;
|
||||
+ case XEN_FW_EDD_INFO:
|
||||
+ if ( op->u.firmware_info.index < edd.edd_info_nr )
|
||||
+ {
|
||||
+ const struct edd_info *info = edd.edd_info + op->u.firmware_info.index;
|
||||
+
|
||||
+ op->u.firmware_info.u.edd_info.device = info->device;
|
||||
+ op->u.firmware_info.u.edd_info.version = info->version;
|
||||
+ op->u.firmware_info.u.edd_info.interface = info->interface_support;
|
||||
+ if ( copy_field_to_guest(u_xenpf_op, op, u.firmware_info.u.edd_info) )
|
||||
+ ret = -EFAULT;
|
||||
+ }
|
||||
+ else
|
||||
+ ret = -ESRCH;
|
||||
+ break;
|
||||
+ case XEN_FW_EDD_PARAMS:
|
||||
+ if ( op->u.firmware_info.index < edd.edd_info_nr )
|
||||
+ {
|
||||
+ u16 length;
|
||||
+
|
||||
+ if ( copy_from_compat(&length, op->u.firmware_info.u.edd_params, 1) == 0 )
|
||||
+ {
|
||||
+ if ( length > edd.edd_info[op->u.firmware_info.index].params.length )
|
||||
+ length = edd.edd_info[op->u.firmware_info.index].params.length;
|
||||
+ if ( copy_to_compat(op->u.firmware_info.u.edd_params,
|
||||
+ (u8*)&edd.edd_info[op->u.firmware_info.index].params,
|
||||
+ length) )
|
||||
+ ret = -EFAULT;
|
||||
+ }
|
||||
+ else
|
||||
+ ret = -EFAULT;
|
||||
+ }
|
||||
+ else
|
||||
+ ret = -ESRCH;
|
||||
+ break;
|
||||
+ case XEN_FW_MBR_SIGNATURE:
|
||||
+ if ( op->u.firmware_info.index < edd.mbr_signature_nr )
|
||||
+ {
|
||||
+ op->u.firmware_info.u.mbr_signature = edd.mbr_signature[op->u.firmware_info.index];
|
||||
+ if ( copy_field_to_guest(u_xenpf_op, op, u.firmware_info.u.mbr_signature) )
|
||||
+ ret = -EFAULT;
|
||||
+ }
|
||||
+ else
|
||||
+ ret = -ESRCH;
|
||||
+ break;
|
||||
+ default:
|
||||
+ ret = -EINVAL;
|
||||
+ break;
|
||||
+ }
|
||||
+ break;
|
||||
+
|
||||
default:
|
||||
ret = -ENOSYS;
|
||||
break;
|
||||
@@ -161,6 +235,19 @@ ret_t do_platform_op(XEN_GUEST_HANDLE(xe
|
||||
return ret;
|
||||
}
|
||||
|
||||
+#ifndef COMPAT
|
||||
+static int __init firmware_init(void)
|
||||
+{
|
||||
+ memcpy(edd.mbr_signature, edd_mbr_sig_buf, sizeof(edd.mbr_signature));
|
||||
+ memcpy(edd.edd_info, eddbuf, sizeof(edd.edd_info));
|
||||
+ edd.mbr_signature_nr = edd_mbr_sig_nr_buf;
|
||||
+ edd.edd_info_nr = eddnr;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+__initcall(firmware_init);
|
||||
+#endif
|
||||
+
|
||||
/*
|
||||
* Local variables:
|
||||
* mode: C
|
||||
Index: 2007-03-19/xen/include/public/platform.h
|
||||
===================================================================
|
||||
--- 2007-03-19.orig/xen/include/public/platform.h 2007-03-21 14:32:46.000000000 +0100
|
||||
+++ 2007-03-19/xen/include/public/platform.h 2007-03-19 14:07:47.000000000 +0100
|
||||
@@ -114,6 +114,35 @@ struct xenpf_platform_quirk {
|
||||
typedef struct xenpf_platform_quirk xenpf_platform_quirk_t;
|
||||
DEFINE_XEN_GUEST_HANDLE(xenpf_platform_quirk_t);
|
||||
|
||||
+#define XENPF_firmware_info 50
|
||||
+#define XEN_FW_DISK_INFO 1 /* from int 13 AH=08 */
|
||||
+#define XEN_FW_EDD_INFO 2 /* from int 13 AH=41 */
|
||||
+#define XEN_FW_EDD_PARAMS 3 /* from int 13 AH=48 */
|
||||
+#define XEN_FW_MBR_SIGNATURE 4
|
||||
+struct xenpf_firmware_info {
|
||||
+ /* IN variables. */
|
||||
+ uint32_t type;
|
||||
+ uint32_t index;
|
||||
+ /* OUT variables. */
|
||||
+ union {
|
||||
+ struct {
|
||||
+ uint16_t max_cylinder;
|
||||
+ uint8_t max_head;
|
||||
+ uint8_t sectors_per_track;
|
||||
+ } disk_info;
|
||||
+ struct {
|
||||
+ uint8_t device;
|
||||
+ uint8_t version;
|
||||
+ uint16_t interface;
|
||||
+ } edd_info;
|
||||
+ /* first uint16_t of buffer must be set to buffer size */
|
||||
+ XEN_GUEST_HANDLE(void) edd_params;
|
||||
+ uint32_t mbr_signature;
|
||||
+ } u;
|
||||
+};
|
||||
+typedef struct xenpf_firmware_info xenpf_firmware_info_t;
|
||||
+DEFINE_XEN_GUEST_HANDLE(xenpf_firmware_info_t);
|
||||
+
|
||||
struct xen_platform_op {
|
||||
uint32_t cmd;
|
||||
uint32_t interface_version; /* XENPF_INTERFACE_VERSION */
|
||||
@@ -124,6 +153,7 @@ struct xen_platform_op {
|
||||
struct xenpf_read_memtype read_memtype;
|
||||
struct xenpf_microcode_update microcode;
|
||||
struct xenpf_platform_quirk platform_quirk;
|
||||
+ struct xenpf_firmware_info firmware_info;
|
||||
uint8_t pad[128];
|
||||
} u;
|
||||
};
|
||||
Index: 2007-03-19/xen/include/xen/edd.h
|
||||
===================================================================
|
||||
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
|
||||
+++ 2007-03-19/xen/include/xen/edd.h 2007-03-19 14:07:47.000000000 +0100
|
||||
@@ -0,0 +1,193 @@
|
||||
+/*
|
||||
+ * xen/include/linux/edd.h
|
||||
+ * Copyright (C) 2002, 2003, 2004 Dell Inc.
|
||||
+ * by Matt Domsch <Matt_Domsch@dell.com>
|
||||
+ * Adopted for Xen (C) 2007 Novell, Inc.
|
||||
+ * by Jan Beulich <jbeulich@novell.com>
|
||||
+ *
|
||||
+ * structures and definitions for the int 13h, ax={41,48}h
|
||||
+ * BIOS Enhanced Disk Drive Services
|
||||
+ * This is based on the T13 group document D1572 Revision 0 (August 14 2002)
|
||||
+ * available at http://www.t13.org/docs2002/d1572r0.pdf. It is
|
||||
+ * very similar to D1484 Revision 3 http://www.t13.org/docs2002/d1484r3.pdf
|
||||
+ *
|
||||
+ * In a nutshell, arch/{i386,x86_64}/boot/setup.S populates a scratch
|
||||
+ * table in the boot_params that contains a list of BIOS-enumerated
|
||||
+ * boot devices.
|
||||
+ * In arch/{i386,x86_64}/kernel/setup.c, this information is
|
||||
+ * transferred into the edd structure, and in drivers/firmware/edd.c, that
|
||||
+ * information is used to identify BIOS boot disk. The code in setup.S
|
||||
+ * is very sensitive to the size of these structures.
|
||||
+ *
|
||||
+ * This program is free software; you can redistribute it and/or modify
|
||||
+ * it under the terms of the GNU General Public License v2.0 as published by
|
||||
+ * the Free Software Foundation
|
||||
+ *
|
||||
+ * This program is distributed in the hope that it will be useful,
|
||||
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
+ * GNU General Public License for more details.
|
||||
+ *
|
||||
+ */
|
||||
+#ifndef _XEN_EDD_H
|
||||
+#define _XEN_EDD_H
|
||||
+
|
||||
+#define EDDMAXNR 6 /* number of edd_info structs starting at eddbuf */
|
||||
+#define EDDEXTSIZE 8 /* change these if you muck with the structures */
|
||||
+#define EDDPARMSIZE 74
|
||||
+#define CHECKEXTENSIONSPRESENT 0x41
|
||||
+#define GETDEVICEPARAMETERS 0x48
|
||||
+#define LEGACYGETDEVICEPARAMETERS 0x08
|
||||
+#define EDDMAGIC1 0x55AA
|
||||
+#define EDDMAGIC2 0xAA55
|
||||
+
|
||||
+
|
||||
+#define READ_SECTORS 0x02 /* int13 AH=0x02 is READ_SECTORS command */
|
||||
+#define EDD_MBR_SIG_OFFSET 0x1B8 /* offset of signature in the MBR */
|
||||
+#define EDD_MBR_SIG_MAX 16 /* max number of signatures to store */
|
||||
+#define EDD_CL_EQUALS 0x3d646465 /* "edd=" */
|
||||
+#define EDD_CL_OFF 0x666f /* "of" for off */
|
||||
+#define EDD_CL_SKIP 0x6b73 /* "sk" for skipmbr */
|
||||
+#define EDD_CL_ON 0x6e6f /* "on" for on */
|
||||
+
|
||||
+#ifndef __ASSEMBLY__
|
||||
+
|
||||
+#define EDD_EXT_FIXED_DISK_ACCESS (1 << 0)
|
||||
+#define EDD_EXT_DEVICE_LOCKING_AND_EJECTING (1 << 1)
|
||||
+#define EDD_EXT_ENHANCED_DISK_DRIVE_SUPPORT (1 << 2)
|
||||
+#define EDD_EXT_64BIT_EXTENSIONS (1 << 3)
|
||||
+
|
||||
+#define EDD_INFO_DMA_BOUNDARY_ERROR_TRANSPARENT (1 << 0)
|
||||
+#define EDD_INFO_GEOMETRY_VALID (1 << 1)
|
||||
+#define EDD_INFO_REMOVABLE (1 << 2)
|
||||
+#define EDD_INFO_WRITE_VERIFY (1 << 3)
|
||||
+#define EDD_INFO_MEDIA_CHANGE_NOTIFICATION (1 << 4)
|
||||
+#define EDD_INFO_LOCKABLE (1 << 5)
|
||||
+#define EDD_INFO_NO_MEDIA_PRESENT (1 << 6)
|
||||
+#define EDD_INFO_USE_INT13_FN50 (1 << 7)
|
||||
+
|
||||
+struct edd_device_params {
|
||||
+ u16 length;
|
||||
+ u16 info_flags;
|
||||
+ u32 num_default_cylinders;
|
||||
+ u32 num_default_heads;
|
||||
+ u32 sectors_per_track;
|
||||
+ u64 number_of_sectors;
|
||||
+ u16 bytes_per_sector;
|
||||
+ u32 dpte_ptr; /* 0xFFFFFFFF for our purposes */
|
||||
+ u16 key; /* = 0xBEDD */
|
||||
+ u8 device_path_info_length; /* = 44 */
|
||||
+ u8 reserved2;
|
||||
+ u16 reserved3;
|
||||
+ u8 host_bus_type[4];
|
||||
+ u8 interface_type[8];
|
||||
+ union {
|
||||
+ struct {
|
||||
+ u16 base_address;
|
||||
+ u16 reserved1;
|
||||
+ u32 reserved2;
|
||||
+ } __attribute__ ((packed)) isa;
|
||||
+ struct {
|
||||
+ u8 bus;
|
||||
+ u8 slot;
|
||||
+ u8 function;
|
||||
+ u8 channel;
|
||||
+ u32 reserved;
|
||||
+ } __attribute__ ((packed)) pci;
|
||||
+ /* pcix is same as pci */
|
||||
+ struct {
|
||||
+ u64 reserved;
|
||||
+ } __attribute__ ((packed)) ibnd;
|
||||
+ struct {
|
||||
+ u64 reserved;
|
||||
+ } __attribute__ ((packed)) xprs;
|
||||
+ struct {
|
||||
+ u64 reserved;
|
||||
+ } __attribute__ ((packed)) htpt;
|
||||
+ struct {
|
||||
+ u64 reserved;
|
||||
+ } __attribute__ ((packed)) unknown;
|
||||
+ } interface_path;
|
||||
+ union {
|
||||
+ struct {
|
||||
+ u8 device;
|
||||
+ u8 reserved1;
|
||||
+ u16 reserved2;
|
||||
+ u32 reserved3;
|
||||
+ u64 reserved4;
|
||||
+ } __attribute__ ((packed)) ata;
|
||||
+ struct {
|
||||
+ u8 device;
|
||||
+ u8 lun;
|
||||
+ u8 reserved1;
|
||||
+ u8 reserved2;
|
||||
+ u32 reserved3;
|
||||
+ u64 reserved4;
|
||||
+ } __attribute__ ((packed)) atapi;
|
||||
+ struct {
|
||||
+ u16 id;
|
||||
+ u64 lun;
|
||||
+ u16 reserved1;
|
||||
+ u32 reserved2;
|
||||
+ } __attribute__ ((packed)) scsi;
|
||||
+ struct {
|
||||
+ u64 serial_number;
|
||||
+ u64 reserved;
|
||||
+ } __attribute__ ((packed)) usb;
|
||||
+ struct {
|
||||
+ u64 eui;
|
||||
+ u64 reserved;
|
||||
+ } __attribute__ ((packed)) i1394;
|
||||
+ struct {
|
||||
+ u64 wwid;
|
||||
+ u64 lun;
|
||||
+ } __attribute__ ((packed)) fibre;
|
||||
+ struct {
|
||||
+ u64 identity_tag;
|
||||
+ u64 reserved;
|
||||
+ } __attribute__ ((packed)) i2o;
|
||||
+ struct {
|
||||
+ u32 array_number;
|
||||
+ u32 reserved1;
|
||||
+ u64 reserved2;
|
||||
+ } __attribute__ ((packed)) raid;
|
||||
+ struct {
|
||||
+ u8 device;
|
||||
+ u8 reserved1;
|
||||
+ u16 reserved2;
|
||||
+ u32 reserved3;
|
||||
+ u64 reserved4;
|
||||
+ } __attribute__ ((packed)) sata;
|
||||
+ struct {
|
||||
+ u64 reserved1;
|
||||
+ u64 reserved2;
|
||||
+ } __attribute__ ((packed)) unknown;
|
||||
+ } device_path;
|
||||
+ u8 reserved4;
|
||||
+ u8 checksum;
|
||||
+} __attribute__ ((packed));
|
||||
+
|
||||
+struct edd_info {
|
||||
+ u8 device;
|
||||
+ u8 version;
|
||||
+ u16 interface_support;
|
||||
+ u16 legacy_max_cylinder;
|
||||
+ u8 legacy_max_head;
|
||||
+ u8 legacy_sectors_per_track;
|
||||
+ struct edd_device_params params;
|
||||
+} __attribute__ ((packed));
|
||||
+
|
||||
+struct edd {
|
||||
+ unsigned int mbr_signature[EDD_MBR_SIG_MAX];
|
||||
+ struct edd_info edd_info[EDDMAXNR];
|
||||
+ unsigned char mbr_signature_nr;
|
||||
+ unsigned char edd_info_nr;
|
||||
+};
|
||||
+
|
||||
+extern unsigned char eddnr, edd_mbr_sig_nr_buf;
|
||||
+extern struct edd_info eddbuf[];
|
||||
+extern unsigned int edd_mbr_sig_buf[];
|
||||
+
|
||||
+#endif /*!__ASSEMBLY__ */
|
||||
+
|
||||
+#endif /* _XEN_EDD_H */
|
188
edid.patch
Normal file
188
edid.patch
Normal file
@ -0,0 +1,188 @@
|
||||
Index: 2007-03-19/xen/arch/x86/Makefile
|
||||
===================================================================
|
||||
--- 2007-03-19.orig/xen/arch/x86/Makefile 2007-03-19 14:07:47.000000000 +0100
|
||||
+++ 2007-03-19/xen/arch/x86/Makefile 2007-03-19 14:07:50.000000000 +0100
|
||||
@@ -78,7 +78,7 @@ xen.lds: $(TARGET_SUBARCH)/xen.lds.S $(H
|
||||
boot/mkelf32: boot/mkelf32.c
|
||||
$(HOSTCC) $(HOSTCFLAGS) -o $@ $<
|
||||
|
||||
-boot/$(TARGET_SUBARCH).o: boot/realmode.S boot/edd.S
|
||||
+boot/$(TARGET_SUBARCH).o: boot/realmode.S boot/edd.S boot/video.S
|
||||
|
||||
.PHONY: clean
|
||||
clean::
|
||||
Index: 2007-03-19/xen/arch/x86/boot/realmode.S
|
||||
===================================================================
|
||||
--- 2007-03-19.orig/xen/arch/x86/boot/realmode.S 2007-03-21 14:35:06.000000000 +0100
|
||||
+++ 2007-03-19/xen/arch/x86/boot/realmode.S 2007-03-21 14:35:14.000000000 +0100
|
||||
@@ -142,4 +142,11 @@ eddbuf: .skip EDDMAXNR * (EDDEXTSIZE +
|
||||
edd_mbr_sig_buf: .skip EDD_MBR_SIG_MAX * 4
|
||||
eddnr: .skip 1
|
||||
edd_mbr_sig_nr_buf: .skip 1
|
||||
+
|
||||
+ .globl ddc_capabilities, edid_transfer_time, edid
|
||||
+ddc_capabilities: .skip 1
|
||||
+edid_transfer_time: .skip 1
|
||||
+edid: .skip 128
|
||||
.previous
|
||||
+
|
||||
+#include "video.S"
|
||||
Index: 2007-03-19/xen/arch/x86/boot/video.S
|
||||
===================================================================
|
||||
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
|
||||
+++ 2007-03-19/xen/arch/x86/boot/video.S 2007-03-19 14:07:50.000000000 +0100
|
||||
@@ -0,0 +1,35 @@
|
||||
+store_edid:
|
||||
+ movl $0x13131313, %eax # memset block with 0x13
|
||||
+ movw $32, %cx
|
||||
+ movw $SYM_REAL(edid), %di
|
||||
+ cld
|
||||
+ rep
|
||||
+ stosl
|
||||
+
|
||||
+ pushw %es # save ES
|
||||
+ xorw %di, %di # Report Capability
|
||||
+ movw %di, %es # ES:DI must be 0:0
|
||||
+ movw $0x4f15, %ax
|
||||
+ xorw %bx, %bx
|
||||
+ xorw %cx, %cx
|
||||
+ int $0x10
|
||||
+ popw %es # restore ES
|
||||
+
|
||||
+ testb %ah, %ah # call successful
|
||||
+ jnz no_edid
|
||||
+
|
||||
+ cmpb $0x4f, %al # function supported
|
||||
+ jne no_edid
|
||||
+
|
||||
+ movb %bl, SYM_REAL(ddc_capabilities)
|
||||
+ movb %bh, SYM_REAL(edid_transfer_time)
|
||||
+
|
||||
+ movw $0x4f15, %ax # do VBE/DDC
|
||||
+ movw $0x01, %bx
|
||||
+ xorw %cx, %cx
|
||||
+ xorw %dx, %dx
|
||||
+ movw $SYM_REAL(edid), %di
|
||||
+ int $0x10
|
||||
+
|
||||
+no_edid:
|
||||
+ ret
|
||||
Index: 2007-03-19/xen/arch/x86/boot/x86_32.S
|
||||
===================================================================
|
||||
--- 2007-03-19.orig/xen/arch/x86/boot/x86_32.S 2007-03-19 14:07:47.000000000 +0100
|
||||
+++ 2007-03-19/xen/arch/x86/boot/x86_32.S 2007-03-19 14:07:50.000000000 +0100
|
||||
@@ -92,6 +92,8 @@ __start:
|
||||
|
||||
pushl $SYM_PHYS(edd)
|
||||
call realmode
|
||||
+ pushl $SYM_PHYS(store_edid)
|
||||
+ call realmode
|
||||
|
||||
#ifdef CONFIG_X86_PAE
|
||||
/* Initialize low and high mappings of all memory with 2MB pages */
|
||||
Index: 2007-03-19/xen/arch/x86/boot/x86_64.S
|
||||
===================================================================
|
||||
--- 2007-03-19.orig/xen/arch/x86/boot/x86_64.S 2007-03-19 14:07:47.000000000 +0100
|
||||
+++ 2007-03-19/xen/arch/x86/boot/x86_64.S 2007-03-19 14:07:50.000000000 +0100
|
||||
@@ -75,6 +75,8 @@ __start:
|
||||
lss SYM_PHYS(.Lstack_start),%esp
|
||||
pushl $SYM_PHYS(edd)
|
||||
call realmode
|
||||
+ pushl $SYM_PHYS(store_edid)
|
||||
+ call realmode
|
||||
|
||||
/* We begin by interrogating the CPU for the presence of long mode. */
|
||||
mov $0x80000000,%eax
|
||||
Index: 2007-03-19/xen/arch/x86/platform_hypercall.c
|
||||
===================================================================
|
||||
--- 2007-03-19.orig/xen/arch/x86/platform_hypercall.c 2007-03-19 14:07:47.000000000 +0100
|
||||
+++ 2007-03-19/xen/arch/x86/platform_hypercall.c 2007-03-19 14:07:50.000000000 +0100
|
||||
@@ -24,10 +24,15 @@
|
||||
#include <asm/mtrr.h>
|
||||
#include "cpu/mtrr/mtrr.h"
|
||||
|
||||
+struct ddc {
|
||||
+ uint8_t capabilities, edid_transfer_time, edid[128];
|
||||
+};
|
||||
+
|
||||
#ifndef COMPAT
|
||||
typedef long ret_t;
|
||||
DEFINE_SPINLOCK(xenpf_lock);
|
||||
struct edd edd;
|
||||
+struct ddc ddc;
|
||||
# undef copy_from_compat
|
||||
# define copy_from_compat copy_from_guest
|
||||
# undef copy_to_compat
|
||||
@@ -35,6 +40,7 @@ struct edd edd;
|
||||
#else
|
||||
extern spinlock_t xenpf_lock;
|
||||
extern struct edd edd;
|
||||
+extern struct ddc ddc;
|
||||
#endif
|
||||
|
||||
ret_t do_platform_op(XEN_GUEST_HANDLE(xen_platform_op_t) u_xenpf_op)
|
||||
@@ -219,6 +225,21 @@ ret_t do_platform_op(XEN_GUEST_HANDLE(xe
|
||||
else
|
||||
ret = -ESRCH;
|
||||
break;
|
||||
+ case XEN_FW_DDC_INFO:
|
||||
+ if ( op->u.firmware_info.index == 0 )
|
||||
+ {
|
||||
+ op->u.firmware_info.u.ddc_info.capabilities = ddc.capabilities;
|
||||
+ op->u.firmware_info.u.ddc_info.edid_transfer_time = ddc.edid_transfer_time;
|
||||
+ if ( copy_field_to_guest(u_xenpf_op, op, u.firmware_info.u.ddc_info.capabilities) ||
|
||||
+ copy_field_to_guest(u_xenpf_op, op, u.firmware_info.u.ddc_info.edid_transfer_time) ||
|
||||
+ copy_to_compat(op->u.firmware_info.u.ddc_info.edid,
|
||||
+ ddc.edid,
|
||||
+ ARRAY_SIZE(ddc.edid)) )
|
||||
+ ret = -EFAULT;
|
||||
+ }
|
||||
+ else
|
||||
+ ret = -ESRCH;
|
||||
+ break;
|
||||
default:
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
@@ -238,11 +259,17 @@ ret_t do_platform_op(XEN_GUEST_HANDLE(xe
|
||||
#ifndef COMPAT
|
||||
static int __init firmware_init(void)
|
||||
{
|
||||
+ extern uint8_t ddc_capabilities, edid_transfer_time, edid[];
|
||||
+
|
||||
memcpy(edd.mbr_signature, edd_mbr_sig_buf, sizeof(edd.mbr_signature));
|
||||
memcpy(edd.edd_info, eddbuf, sizeof(edd.edd_info));
|
||||
edd.mbr_signature_nr = edd_mbr_sig_nr_buf;
|
||||
edd.edd_info_nr = eddnr;
|
||||
|
||||
+ ddc.capabilities = ddc_capabilities;
|
||||
+ ddc.edid_transfer_time = edid_transfer_time;
|
||||
+ memcpy(ddc.edid, edid, sizeof(ddc.edid));
|
||||
+
|
||||
return 0;
|
||||
}
|
||||
__initcall(firmware_init);
|
||||
Index: 2007-03-19/xen/include/public/platform.h
|
||||
===================================================================
|
||||
--- 2007-03-19.orig/xen/include/public/platform.h 2007-03-19 14:07:47.000000000 +0100
|
||||
+++ 2007-03-19/xen/include/public/platform.h 2007-03-19 14:07:50.000000000 +0100
|
||||
@@ -119,6 +119,7 @@ DEFINE_XEN_GUEST_HANDLE(xenpf_platform_q
|
||||
#define XEN_FW_EDD_INFO 2 /* from int 13 AH=41 */
|
||||
#define XEN_FW_EDD_PARAMS 3 /* from int 13 AH=48 */
|
||||
#define XEN_FW_MBR_SIGNATURE 4
|
||||
+#define XEN_FW_DDC_INFO 5 /* from int 10 AX=4f15 */
|
||||
struct xenpf_firmware_info {
|
||||
/* IN variables. */
|
||||
uint32_t type;
|
||||
@@ -138,6 +139,12 @@ struct xenpf_firmware_info {
|
||||
/* first uint16_t of buffer must be set to buffer size */
|
||||
XEN_GUEST_HANDLE(void) edd_params;
|
||||
uint32_t mbr_signature;
|
||||
+ struct {
|
||||
+ uint8_t capabilities;
|
||||
+ uint8_t edid_transfer_time;
|
||||
+ /* must refer to 128-byte buffer */
|
||||
+ XEN_GUEST_HANDLE(uint8_t) edid;
|
||||
+ } ddc_info;
|
||||
} u;
|
||||
};
|
||||
typedef struct xenpf_firmware_info xenpf_firmware_info_t;
|
374
guest-copy.patch
Normal file
374
guest-copy.patch
Normal file
@ -0,0 +1,374 @@
|
||||
Index: 2007-05-14/xen/arch/x86/mm.c
|
||||
===================================================================
|
||||
--- 2007-05-14.orig/xen/arch/x86/mm.c 2007-05-14 13:44:25.000000000 +0200
|
||||
+++ 2007-05-14/xen/arch/x86/mm.c 2007-05-14 14:33:33.000000000 +0200
|
||||
@@ -2896,7 +2896,7 @@ long do_set_gdt(XEN_GUEST_HANDLE(ulong)
|
||||
if ( entries > FIRST_RESERVED_GDT_ENTRY )
|
||||
return -EINVAL;
|
||||
|
||||
- if ( copy_from_guest((unsigned long *)frames, frame_list, nr_pages) )
|
||||
+ if ( copy_from_guest(frames, frame_list, nr_pages) )
|
||||
return -EFAULT;
|
||||
|
||||
LOCK_BIGLOCK(current->domain);
|
||||
@@ -3077,7 +3077,7 @@ long arch_memory_op(int op, XEN_GUEST_HA
|
||||
else if ( (d = rcu_lock_domain_by_id(fmap.domid)) == NULL )
|
||||
return -ESRCH;
|
||||
|
||||
- rc = copy_from_guest(&d->arch.e820[0], fmap.map.buffer,
|
||||
+ rc = copy_from_guest(d->arch.e820, fmap.map.buffer,
|
||||
fmap.map.nr_entries) ? -EFAULT : 0;
|
||||
d->arch.nr_e820 = fmap.map.nr_entries;
|
||||
|
||||
@@ -3098,7 +3098,7 @@ long arch_memory_op(int op, XEN_GUEST_HA
|
||||
return -EFAULT;
|
||||
|
||||
map.nr_entries = min(map.nr_entries, d->arch.nr_e820);
|
||||
- if ( copy_to_guest(map.buffer, &d->arch.e820[0], map.nr_entries) ||
|
||||
+ if ( copy_to_guest(map.buffer, d->arch.e820, map.nr_entries) ||
|
||||
copy_to_guest(arg, &map, 1) )
|
||||
return -EFAULT;
|
||||
|
||||
@@ -3122,7 +3122,7 @@ long arch_memory_op(int op, XEN_GUEST_HA
|
||||
buffer = guest_handle_cast(memmap.buffer, e820entry_t);
|
||||
|
||||
count = min((unsigned int)e820.nr_map, memmap.nr_entries);
|
||||
- if ( copy_to_guest(buffer, &e820.map[0], count) < 0 )
|
||||
+ if ( copy_to_guest(buffer, e820.map, count) < 0 )
|
||||
return -EFAULT;
|
||||
|
||||
memmap.nr_entries = count;
|
||||
@@ -3135,7 +3135,7 @@ long arch_memory_op(int op, XEN_GUEST_HA
|
||||
|
||||
case XENMEM_machphys_mapping:
|
||||
{
|
||||
- struct xen_machphys_mapping mapping = {
|
||||
+ static const struct xen_machphys_mapping mapping = {
|
||||
.v_start = MACH2PHYS_VIRT_START,
|
||||
.v_end = MACH2PHYS_VIRT_END,
|
||||
.max_mfn = MACH2PHYS_NR_ENTRIES - 1
|
||||
Index: 2007-05-14/xen/arch/x86/traps.c
|
||||
===================================================================
|
||||
--- 2007-05-14.orig/xen/arch/x86/traps.c 2007-05-14 13:43:46.000000000 +0200
|
||||
+++ 2007-05-14/xen/arch/x86/traps.c 2007-05-14 14:33:33.000000000 +0200
|
||||
@@ -1117,7 +1117,7 @@ static inline int guest_io_okay(
|
||||
* read as 0xff (no access allowed).
|
||||
*/
|
||||
TOGGLE_MODE();
|
||||
- switch ( __copy_from_guest_offset(&x.bytes[0], v->arch.iobmp,
|
||||
+ switch ( __copy_from_guest_offset(x.bytes, v->arch.iobmp,
|
||||
port>>3, 2) )
|
||||
{
|
||||
default: x.bytes[0] = ~0;
|
||||
Index: 2007-05-14/xen/common/domctl.c
|
||||
===================================================================
|
||||
--- 2007-05-14.orig/xen/common/domctl.c 2007-04-26 09:25:12.000000000 +0200
|
||||
+++ 2007-05-14/xen/common/domctl.c 2007-05-14 14:33:33.000000000 +0200
|
||||
@@ -43,7 +43,7 @@ void cpumask_to_xenctl_cpumap(
|
||||
|
||||
bitmap_long_to_byte(bytemap, cpus_addr(*cpumask), NR_CPUS);
|
||||
|
||||
- copy_to_guest(xenctl_cpumap->bitmap, &bytemap[0], copy_bytes);
|
||||
+ copy_to_guest(xenctl_cpumap->bitmap, bytemap, copy_bytes);
|
||||
|
||||
for ( i = copy_bytes; i < guest_bytes; i++ )
|
||||
copy_to_guest_offset(xenctl_cpumap->bitmap, i, &zero, 1);
|
||||
@@ -63,7 +63,7 @@ void xenctl_cpumap_to_cpumask(
|
||||
if ( guest_handle_is_null(xenctl_cpumap->bitmap) )
|
||||
return;
|
||||
|
||||
- copy_from_guest(&bytemap[0], xenctl_cpumap->bitmap, copy_bytes);
|
||||
+ copy_from_guest(bytemap, xenctl_cpumap->bitmap, copy_bytes);
|
||||
|
||||
bitmap_byte_to_long(cpus_addr(*cpumask), bytemap, NR_CPUS);
|
||||
}
|
||||
Index: 2007-05-14/xen/common/kernel.c
|
||||
===================================================================
|
||||
--- 2007-05-14.orig/xen/common/kernel.c 2007-05-14 13:43:09.000000000 +0200
|
||||
+++ 2007-05-14/xen/common/kernel.c 2007-05-14 14:33:33.000000000 +0200
|
||||
@@ -142,7 +142,7 @@ DO(xen_version)(int cmd, XEN_GUEST_HANDL
|
||||
{
|
||||
xen_extraversion_t extraversion;
|
||||
safe_strcpy(extraversion, xen_extra_version());
|
||||
- if ( copy_to_guest(arg, (char *)extraversion, sizeof(extraversion)) )
|
||||
+ if ( copy_to_guest(arg, extraversion, ARRAY_SIZE(extraversion)) )
|
||||
return -EFAULT;
|
||||
return 0;
|
||||
}
|
||||
@@ -167,7 +167,7 @@ DO(xen_version)(int cmd, XEN_GUEST_HANDL
|
||||
memset(info, 0, sizeof(info));
|
||||
arch_get_xen_caps(&info);
|
||||
|
||||
- if ( copy_to_guest(arg, (char *)info, sizeof(info)) )
|
||||
+ if ( copy_to_guest(arg, info, ARRAY_SIZE(info)) )
|
||||
return -EFAULT;
|
||||
return 0;
|
||||
}
|
||||
@@ -187,7 +187,7 @@ DO(xen_version)(int cmd, XEN_GUEST_HANDL
|
||||
{
|
||||
xen_changeset_info_t chgset;
|
||||
safe_strcpy(chgset, xen_changeset());
|
||||
- if ( copy_to_guest(arg, (char *)chgset, sizeof(chgset)) )
|
||||
+ if ( copy_to_guest(arg, chgset, ARRAY_SIZE(chgset)) )
|
||||
return -EFAULT;
|
||||
return 0;
|
||||
}
|
||||
@@ -229,8 +229,8 @@ DO(xen_version)(int cmd, XEN_GUEST_HANDL
|
||||
|
||||
case XENVER_guest_handle:
|
||||
{
|
||||
- if ( copy_to_guest(arg, (char *)current->domain->handle,
|
||||
- sizeof(current->domain->handle)) )
|
||||
+ if ( copy_to_guest(arg, current->domain->handle,
|
||||
+ ARRAY_SIZE(current->domain->handle)) )
|
||||
return -EFAULT;
|
||||
return 0;
|
||||
}
|
||||
Index: 2007-05-14/xen/common/perfc.c
|
||||
===================================================================
|
||||
--- 2007-05-14.orig/xen/common/perfc.c 2007-04-26 09:25:12.000000000 +0200
|
||||
+++ 2007-05-14/xen/common/perfc.c 2007-05-14 14:33:33.000000000 +0200
|
||||
@@ -227,7 +227,7 @@ static int perfc_copy_info(XEN_GUEST_HAN
|
||||
}
|
||||
BUG_ON(v != perfc_nbr_vals);
|
||||
|
||||
- if ( copy_to_guest(desc, (xen_sysctl_perfc_desc_t *)perfc_d, NR_PERFCTRS) )
|
||||
+ if ( copy_to_guest(desc, perfc_d, NR_PERFCTRS) )
|
||||
return -EFAULT;
|
||||
if ( copy_to_guest(val, perfc_vals, perfc_nbr_vals) )
|
||||
return -EFAULT;
|
||||
Index: 2007-05-14/xen/drivers/char/console.c
|
||||
===================================================================
|
||||
--- 2007-05-14.orig/xen/drivers/char/console.c 2007-04-23 10:01:44.000000000 +0200
|
||||
+++ 2007-05-14/xen/drivers/char/console.c 2007-05-14 14:33:33.000000000 +0200
|
||||
@@ -326,7 +326,7 @@ static long guest_console_write(XEN_GUES
|
||||
CONSOLEIO_write, count, buffer);
|
||||
|
||||
kcount = min_t(int, count, sizeof(kbuf)-1);
|
||||
- if ( copy_from_guest((char *)kbuf, buffer, kcount) )
|
||||
+ if ( copy_from_guest(kbuf, buffer, kcount) )
|
||||
return -EFAULT;
|
||||
kbuf[kcount] = '\0';
|
||||
|
||||
Index: 2007-05-14/xen/include/asm-x86/guest_access.h
|
||||
===================================================================
|
||||
--- 2007-05-14.orig/xen/include/asm-x86/guest_access.h 2007-04-23 10:01:46.000000000 +0200
|
||||
+++ 2007-05-14/xen/include/asm-x86/guest_access.h 2007-05-14 14:33:33.000000000 +0200
|
||||
@@ -32,11 +32,12 @@
|
||||
* specifying an offset into the guest array.
|
||||
*/
|
||||
#define copy_to_guest_offset(hnd, off, ptr, nr) ({ \
|
||||
- typeof(ptr) _x = (hnd).p; \
|
||||
- const typeof(ptr) _y = (ptr); \
|
||||
+ const typeof(*(ptr)) *_s = (ptr); \
|
||||
+ char (*_d)[sizeof(*_s)] = (void *)(hnd).p; \
|
||||
+ ((void)((hnd).p == (ptr))); \
|
||||
is_hvm_vcpu(current) ? \
|
||||
- copy_to_user_hvm(_x+(off), _y, sizeof(*_x)*(nr)) : \
|
||||
- copy_to_user(_x+(off), _y, sizeof(*_x)*(nr)); \
|
||||
+ copy_to_user_hvm(_d+(off), _s, sizeof(*_s)*(nr)) : \
|
||||
+ copy_to_user(_d+(off), _s, sizeof(*_s)*(nr)); \
|
||||
})
|
||||
|
||||
/*
|
||||
@@ -44,29 +45,31 @@
|
||||
* specifying an offset into the guest array.
|
||||
*/
|
||||
#define copy_from_guest_offset(ptr, hnd, off, nr) ({ \
|
||||
- const typeof(ptr) _x = (hnd).p; \
|
||||
- typeof(ptr) _y = (ptr); \
|
||||
+ const typeof(*(ptr)) *_s = (hnd).p; \
|
||||
+ typeof(*(ptr)) *_d = (ptr); \
|
||||
is_hvm_vcpu(current) ? \
|
||||
- copy_from_user_hvm(_y, _x+(off), sizeof(*_x)*(nr)) :\
|
||||
- copy_from_user(_y, _x+(off), sizeof(*_x)*(nr)); \
|
||||
+ copy_from_user_hvm(_d, _s+(off), sizeof(*_d)*(nr)) :\
|
||||
+ copy_from_user(_d, _s+(off), sizeof(*_d)*(nr)); \
|
||||
})
|
||||
|
||||
/* Copy sub-field of a structure to guest context via a guest handle. */
|
||||
#define copy_field_to_guest(hnd, ptr, field) ({ \
|
||||
- typeof(&(ptr)->field) _x = &(hnd).p->field; \
|
||||
- const typeof(&(ptr)->field) _y = &(ptr)->field; \
|
||||
+ const typeof(&(ptr)->field) _s = &(ptr)->field; \
|
||||
+ void *_d = &(hnd).p->field; \
|
||||
+ ((void)((hnd).p == (ptr))); \
|
||||
is_hvm_vcpu(current) ? \
|
||||
- copy_to_user_hvm(_x, _y, sizeof(*_x)) : \
|
||||
- copy_to_user(_x, _y, sizeof(*_x)); \
|
||||
+ copy_to_user_hvm(_d, _s, sizeof(*_s)) : \
|
||||
+ copy_to_user(_d, _s, sizeof(*_s)); \
|
||||
})
|
||||
|
||||
/* Copy sub-field of a structure from guest context via a guest handle. */
|
||||
#define copy_field_from_guest(ptr, hnd, field) ({ \
|
||||
- const typeof(&(ptr)->field) _x = &(hnd).p->field; \
|
||||
- typeof(&(ptr)->field) _y = &(ptr)->field; \
|
||||
+ const void *_s = &(hnd).p->field; \
|
||||
+ typeof(&(ptr)->field) _d = &(ptr)->field; \
|
||||
+ ((void)((hnd).p == (ptr))); \
|
||||
is_hvm_vcpu(current) ? \
|
||||
- copy_from_user_hvm(_y, _x, sizeof(*_x)) : \
|
||||
- copy_from_user(_y, _x, sizeof(*_x)); \
|
||||
+ copy_from_user_hvm(_d, _s, sizeof(*_d)) : \
|
||||
+ copy_from_user(_d, _s, sizeof(*_d)); \
|
||||
})
|
||||
|
||||
/*
|
||||
@@ -78,35 +81,37 @@
|
||||
array_access_ok((hnd).p, (nr), sizeof(*(hnd).p)))
|
||||
|
||||
#define __copy_to_guest_offset(hnd, off, ptr, nr) ({ \
|
||||
- typeof(ptr) _x = (hnd).p; \
|
||||
- const typeof(ptr) _y = (ptr); \
|
||||
+ const typeof(*(ptr)) *_s = (ptr); \
|
||||
+ char (*_d)[sizeof(*_s)] = (void *)(hnd).p; \
|
||||
+ ((void)((hnd).p == (ptr))); \
|
||||
is_hvm_vcpu(current) ? \
|
||||
- copy_to_user_hvm(_x+(off), _y, sizeof(*_x)*(nr)) : \
|
||||
- __copy_to_user(_x+(off), _y, sizeof(*_x)*(nr)); \
|
||||
+ copy_to_user_hvm(_d+(off), _s, sizeof(*_s)*(nr)) : \
|
||||
+ __copy_to_user(_d+(off), _s, sizeof(*_s)*(nr)); \
|
||||
})
|
||||
|
||||
#define __copy_from_guest_offset(ptr, hnd, off, nr) ({ \
|
||||
- const typeof(ptr) _x = (hnd).p; \
|
||||
- typeof(ptr) _y = (ptr); \
|
||||
+ const typeof(*(ptr)) *_s = (hnd).p; \
|
||||
+ typeof(*(ptr)) *_d = (ptr); \
|
||||
is_hvm_vcpu(current) ? \
|
||||
- copy_from_user_hvm(_y, _x+(off),sizeof(*_x)*(nr)) : \
|
||||
- __copy_from_user(_y, _x+(off), sizeof(*_x)*(nr)); \
|
||||
+ copy_from_user_hvm(_d, _s+(off), sizeof(*_d)*(nr)) :\
|
||||
+ __copy_from_user(_d, _s+(off), sizeof(*_d)*(nr)); \
|
||||
})
|
||||
|
||||
#define __copy_field_to_guest(hnd, ptr, field) ({ \
|
||||
- typeof(&(ptr)->field) _x = &(hnd).p->field; \
|
||||
- const typeof(&(ptr)->field) _y = &(ptr)->field; \
|
||||
+ const typeof(&(ptr)->field) _s = &(ptr)->field; \
|
||||
+ void *_d = &(hnd).p->field; \
|
||||
+ ((void)(&(hnd).p->field == &(ptr)->field)); \
|
||||
is_hvm_vcpu(current) ? \
|
||||
- copy_to_user_hvm(_x, _y, sizeof(*_x)) : \
|
||||
- __copy_to_user(_x, _y, sizeof(*_x)); \
|
||||
+ copy_to_user_hvm(_d, _s, sizeof(*_s)) : \
|
||||
+ __copy_to_user(_d, _s, sizeof(*_s)); \
|
||||
})
|
||||
|
||||
#define __copy_field_from_guest(ptr, hnd, field) ({ \
|
||||
- const typeof(&(ptr)->field) _x = &(hnd).p->field; \
|
||||
- typeof(&(ptr)->field) _y = &(ptr)->field; \
|
||||
+ const typeof(&(ptr)->field) _s = &(hnd).p->field; \
|
||||
+ typeof(&(ptr)->field) _d = &(ptr)->field; \
|
||||
is_hvm_vcpu(current) ? \
|
||||
- copy_from_user_hvm(_y, _x, sizeof(*_x)) : \
|
||||
- __copy_from_user(_y, _x, sizeof(*_x)); \
|
||||
+ copy_from_user_hvm(_d, _s, sizeof(*_d)) : \
|
||||
+ __copy_from_user(_d, _s, sizeof(*_d)); \
|
||||
})
|
||||
|
||||
#endif /* __ASM_X86_GUEST_ACCESS_H__ */
|
||||
Index: 2007-05-14/xen/include/xen/compat.h
|
||||
===================================================================
|
||||
--- 2007-05-14.orig/xen/include/xen/compat.h 2007-04-23 10:01:47.000000000 +0200
|
||||
+++ 2007-05-14/xen/include/xen/compat.h 2007-05-14 14:33:33.000000000 +0200
|
||||
@@ -44,9 +44,10 @@
|
||||
* 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)); \
|
||||
+ const typeof(*(ptr)) *_s = (ptr); \
|
||||
+ char (*_d)[sizeof(*_s)] = (void *)(full_ptr_t)(hnd).c; \
|
||||
+ ((void)((typeof(**(hnd)._) *)(full_ptr_t)(hnd).c == (ptr))); \
|
||||
+ copy_to_user(_d + (off), _s, sizeof(*_s) * (nr)); \
|
||||
})
|
||||
|
||||
/*
|
||||
@@ -54,9 +55,9 @@
|
||||
* 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)); \
|
||||
+ const typeof(*(ptr)) *_s = (typeof(**(hnd)._) *)(full_ptr_t)(hnd).c; \
|
||||
+ typeof(*(ptr)) *_d = (ptr); \
|
||||
+ copy_from_user(_d, _s + (off), sizeof(*_d) * (nr)); \
|
||||
})
|
||||
|
||||
#define copy_to_compat(hnd, ptr, nr) \
|
||||
@@ -67,16 +68,18 @@
|
||||
|
||||
/* 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)); \
|
||||
+ const typeof(&(ptr)->field) _s = &(ptr)->field; \
|
||||
+ void *_d = &((typeof(**(hnd)._) *)(full_ptr_t)(hnd).c)->field; \
|
||||
+ ((void)((typeof(**(hnd)._) *)(full_ptr_t)(hnd).c == (ptr))); \
|
||||
+ copy_to_user(_d, _s, sizeof(*_s)); \
|
||||
})
|
||||
|
||||
/* 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)); \
|
||||
+ const void *_s = &((typeof(**(hnd)._) *)(full_ptr_t)(hnd).c)->field; \
|
||||
+ typeof(&(ptr)->field) _d = &(ptr)->field; \
|
||||
+ ((void)((typeof(**(hnd)._) *)(full_ptr_t)(hnd).c == (ptr))); \
|
||||
+ copy_from_user(_d, _s, sizeof(*_d)); \
|
||||
})
|
||||
|
||||
/*
|
||||
@@ -87,15 +90,16 @@
|
||||
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)); \
|
||||
+ const typeof(*(ptr)) *_s = (ptr); \
|
||||
+ char (*_d)[sizeof(*_s)] = (void *)(full_ptr_t)(hnd).c; \
|
||||
+ ((void)((typeof(**(hnd)._) *)(full_ptr_t)(hnd).c == (ptr))); \
|
||||
+ __copy_to_user(_d + (off), _s, sizeof(*_s) * (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)); \
|
||||
+ const typeof(*(ptr)) *_s = (typeof(**(hnd)._) *)(full_ptr_t)(hnd).c; \
|
||||
+ typeof(*(ptr)) *_d = (ptr); \
|
||||
+ __copy_from_user(_d, _s + (off), sizeof(*_d) * (nr)); \
|
||||
})
|
||||
|
||||
#define __copy_to_compat(hnd, ptr, nr) \
|
||||
@@ -105,15 +109,17 @@
|
||||
__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)); \
|
||||
+ const typeof(&(ptr)->field) _s = &(ptr)->field; \
|
||||
+ void *_d = &((typeof(**(hnd)._) *)(full_ptr_t)(hnd).c)->field; \
|
||||
+ ((void)((typeof(**(hnd)._) *)(full_ptr_t)(hnd).c == (ptr))); \
|
||||
+ __copy_to_user(_d, _s, sizeof(*_s)); \
|
||||
})
|
||||
|
||||
#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)); \
|
||||
+ const void *_s = &((typeof(**(hnd)._) *)(full_ptr_t)(hnd).c)->field; \
|
||||
+ typeof(&(ptr)->field) _d = &(ptr)->field; \
|
||||
+ ((void)((typeof(**(hnd)._) *)(full_ptr_t)(hnd).c == (ptr))); \
|
||||
+ __copy_from_user(_d, _s, sizeof(*_d)); \
|
||||
})
|
||||
|
||||
|
401
hvm-debug-msg.patch
Normal file
401
hvm-debug-msg.patch
Normal file
@ -0,0 +1,401 @@
|
||||
Index: 2007-05-14/xen/arch/x86/hvm/svm/emulate.c
|
||||
===================================================================
|
||||
--- 2007-05-14.orig/xen/arch/x86/hvm/svm/emulate.c 2007-04-23 10:01:41.000000000 +0200
|
||||
+++ 2007-05-14/xen/arch/x86/hvm/svm/emulate.c 2007-05-14 14:33:28.000000000 +0200
|
||||
@@ -145,9 +145,8 @@ unsigned long get_effective_addr_modrm64
|
||||
struct vcpu *v = current;
|
||||
struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
|
||||
|
||||
- HVM_DBG_LOG(DBG_LEVEL_1, "get_effective_addr_modrm64(): prefix = %x, "
|
||||
- "length = %d, operand[0,1] = %x %x.\n", prefix, *size, operand [0],
|
||||
- operand [1]);
|
||||
+ HVM_DBG_LOG(DBG_LEVEL_1, "prefix = %x, length = %d, operand[0,1] = %x %x",
|
||||
+ prefix, *size, operand[0], operand[1]);
|
||||
|
||||
if ((NULL == size) || (NULL == operand) || (1 > *size))
|
||||
{
|
||||
Index: 2007-05-14/xen/arch/x86/hvm/svm/svm.c
|
||||
===================================================================
|
||||
--- 2007-05-14.orig/xen/arch/x86/hvm/svm/svm.c 2007-05-14 14:33:08.000000000 +0200
|
||||
+++ 2007-05-14/xen/arch/x86/hvm/svm/svm.c 2007-05-14 14:33:28.000000000 +0200
|
||||
@@ -135,7 +135,7 @@ static inline int long_mode_do_msr_write
|
||||
struct vcpu *v = current;
|
||||
struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
|
||||
|
||||
- HVM_DBG_LOG(DBG_LEVEL_1, "msr %x msr_content %"PRIx64"\n",
|
||||
+ HVM_DBG_LOG(DBG_LEVEL_0, "msr %x msr_content %"PRIx64,
|
||||
ecx, msr_content);
|
||||
|
||||
switch ( ecx )
|
||||
@@ -394,7 +394,7 @@ int svm_vmcb_restore(struct vcpu *v, str
|
||||
* If different, make a shadow. Check if the PDBR is valid
|
||||
* first.
|
||||
*/
|
||||
- HVM_DBG_LOG(DBG_LEVEL_VMMU, "CR3 c->cr3 = %"PRIx64"", c->cr3);
|
||||
+ HVM_DBG_LOG(DBG_LEVEL_VMMU, "CR3 c->cr3 = %"PRIx64, c->cr3);
|
||||
mfn = gmfn_to_mfn(v->domain, c->cr3 >> PAGE_SHIFT);
|
||||
if( !mfn_valid(mfn) || !get_page(mfn_to_page(mfn), v->domain) )
|
||||
goto bad_cr3;
|
||||
@@ -1532,7 +1532,7 @@ static int svm_set_cr0(unsigned long val
|
||||
struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
|
||||
unsigned long old_base_mfn;
|
||||
|
||||
- HVM_DBG_LOG(DBG_LEVEL_VMMU, "Update CR0 value = %lx\n", value);
|
||||
+ HVM_DBG_LOG(DBG_LEVEL_VMMU, "Update CR0 value = %lx", value);
|
||||
|
||||
/* ET is reserved and should be always be 1. */
|
||||
value |= X86_CR0_ET;
|
||||
@@ -1557,11 +1557,11 @@ static int svm_set_cr0(unsigned long val
|
||||
{
|
||||
if ( !svm_cr4_pae_is_set(v) )
|
||||
{
|
||||
- HVM_DBG_LOG(DBG_LEVEL_1, "Enable paging before PAE enable\n");
|
||||
+ HVM_DBG_LOG(DBG_LEVEL_1, "Enable paging before PAE enable");
|
||||
svm_inject_exception(v, TRAP_gp_fault, 1, 0);
|
||||
return 0;
|
||||
}
|
||||
- HVM_DBG_LOG(DBG_LEVEL_1, "Enable the Long mode\n");
|
||||
+ HVM_DBG_LOG(DBG_LEVEL_1, "Enable the Long mode");
|
||||
v->arch.hvm_svm.cpu_shadow_efer |= EFER_LMA;
|
||||
vmcb->efer |= EFER_LMA | EFER_LME;
|
||||
}
|
||||
@@ -1654,7 +1654,7 @@ static void mov_from_cr(int cr, int gp,
|
||||
|
||||
set_reg(gp, value, regs, vmcb);
|
||||
|
||||
- HVM_DBG_LOG(DBG_LEVEL_VMMU, "mov_from_cr: CR%d, value = %lx,", cr, value);
|
||||
+ HVM_DBG_LOG(DBG_LEVEL_VMMU, "mov_from_cr: CR%d, value = %lx", cr, value);
|
||||
}
|
||||
|
||||
|
||||
@@ -1672,8 +1672,8 @@ static int mov_to_cr(int gpreg, int cr,
|
||||
|
||||
HVMTRACE_2D(CR_WRITE, v, cr, value);
|
||||
|
||||
- HVM_DBG_LOG(DBG_LEVEL_1, "mov_to_cr: CR%d, value = %lx,", cr, value);
|
||||
- HVM_DBG_LOG(DBG_LEVEL_1, "current = %lx,", (unsigned long) current);
|
||||
+ HVM_DBG_LOG(DBG_LEVEL_1, "mov_to_cr: CR%d, value = %lx, current = %p",
|
||||
+ cr, value, v);
|
||||
|
||||
switch ( cr )
|
||||
{
|
||||
Index: 2007-05-14/xen/arch/x86/hvm/vioapic.c
|
||||
===================================================================
|
||||
--- 2007-05-14.orig/xen/arch/x86/hvm/vioapic.c 2007-04-23 10:01:41.000000000 +0200
|
||||
+++ 2007-05-14/xen/arch/x86/hvm/vioapic.c 2007-05-14 14:33:28.000000000 +0200
|
||||
@@ -99,7 +99,7 @@ static unsigned long vioapic_read(struct
|
||||
struct hvm_hw_vioapic *vioapic = domain_vioapic(v->domain);
|
||||
uint32_t result;
|
||||
|
||||
- HVM_DBG_LOG(DBG_LEVEL_IOAPIC, "vioapic_read addr %lx\n", addr);
|
||||
+ HVM_DBG_LOG(DBG_LEVEL_IOAPIC, "addr %lx", addr);
|
||||
|
||||
addr &= 0xff;
|
||||
|
||||
@@ -183,8 +183,7 @@ static void vioapic_write_indirect(
|
||||
{
|
||||
uint32_t redir_index = (vioapic->ioregsel - 0x10) >> 1;
|
||||
|
||||
- HVM_DBG_LOG(DBG_LEVEL_IOAPIC, "vioapic_write_indirect "
|
||||
- "change redir index %x val %lx\n",
|
||||
+ HVM_DBG_LOG(DBG_LEVEL_IOAPIC, "change redir index %x val %lx",
|
||||
redir_index, val);
|
||||
|
||||
if ( redir_index >= VIOAPIC_NUM_PINS )
|
||||
@@ -252,8 +251,7 @@ static void ioapic_inj_irq(
|
||||
uint8_t trig_mode,
|
||||
uint8_t delivery_mode)
|
||||
{
|
||||
- HVM_DBG_LOG(DBG_LEVEL_IOAPIC, "ioapic_inj_irq "
|
||||
- "irq %d trig %d delive mode %d\n",
|
||||
+ HVM_DBG_LOG(DBG_LEVEL_IOAPIC, "irq %d trig %d deliv %d",
|
||||
vector, trig_mode, delivery_mode);
|
||||
|
||||
switch ( delivery_mode )
|
||||
@@ -275,8 +273,8 @@ static uint32_t ioapic_get_delivery_bitm
|
||||
uint32_t mask = 0;
|
||||
struct vcpu *v;
|
||||
|
||||
- HVM_DBG_LOG(DBG_LEVEL_IOAPIC, "ioapic_get_delivery_bitmask "
|
||||
- "dest %d dest_mode %d\n", dest, dest_mode);
|
||||
+ HVM_DBG_LOG(DBG_LEVEL_IOAPIC, "dest %d dest_mode %d",
|
||||
+ dest, dest_mode);
|
||||
|
||||
if ( dest_mode == 0 ) /* Physical mode. */
|
||||
{
|
||||
@@ -304,7 +302,7 @@ static uint32_t ioapic_get_delivery_bitm
|
||||
}
|
||||
|
||||
out:
|
||||
- HVM_DBG_LOG(DBG_LEVEL_IOAPIC, "ioapic_get_delivery_bitmask mask %x\n",
|
||||
+ HVM_DBG_LOG(DBG_LEVEL_IOAPIC, "mask %x",
|
||||
mask);
|
||||
return mask;
|
||||
}
|
||||
@@ -331,14 +329,13 @@ static void vioapic_deliver(struct hvm_h
|
||||
|
||||
HVM_DBG_LOG(DBG_LEVEL_IOAPIC,
|
||||
"dest=%x dest_mode=%x delivery_mode=%x "
|
||||
- "vector=%x trig_mode=%x\n",
|
||||
+ "vector=%x trig_mode=%x",
|
||||
dest, dest_mode, delivery_mode, vector, trig_mode);
|
||||
|
||||
deliver_bitmask = ioapic_get_delivery_bitmask(vioapic, dest, dest_mode);
|
||||
if ( !deliver_bitmask )
|
||||
{
|
||||
- HVM_DBG_LOG(DBG_LEVEL_IOAPIC, "ioapic deliver "
|
||||
- "no target on destination\n");
|
||||
+ HVM_DBG_LOG(DBG_LEVEL_IOAPIC, "no target on destination");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -364,7 +361,7 @@ static void vioapic_deliver(struct hvm_h
|
||||
else
|
||||
{
|
||||
HVM_DBG_LOG(DBG_LEVEL_IOAPIC, "null round robin: "
|
||||
- "mask=%x vector=%x delivery_mode=%x\n",
|
||||
+ "mask=%x vector=%x delivery_mode=%x",
|
||||
deliver_bitmask, vector, dest_LowestPrio);
|
||||
}
|
||||
break;
|
||||
@@ -412,7 +409,7 @@ void vioapic_irq_positive_edge(struct do
|
||||
struct hvm_hw_vioapic *vioapic = domain_vioapic(d);
|
||||
union vioapic_redir_entry *ent;
|
||||
|
||||
- HVM_DBG_LOG(DBG_LEVEL_IOAPIC, "ioapic_irq_positive_edge irq %x", irq);
|
||||
+ HVM_DBG_LOG(DBG_LEVEL_IOAPIC, "irq %x", irq);
|
||||
|
||||
ASSERT(irq < VIOAPIC_NUM_PINS);
|
||||
ASSERT(spin_is_locked(&d->arch.hvm_domain.irq_lock));
|
||||
Index: 2007-05-14/xen/arch/x86/hvm/vlapic.c
|
||||
===================================================================
|
||||
--- 2007-05-14.orig/xen/arch/x86/hvm/vlapic.c 2007-04-23 10:01:41.000000000 +0200
|
||||
+++ 2007-05-14/xen/arch/x86/hvm/vlapic.c 2007-05-14 14:33:28.000000000 +0200
|
||||
@@ -171,7 +171,7 @@ uint32_t vlapic_get_ppr(struct vlapic *v
|
||||
ppr = isrv & 0xf0;
|
||||
|
||||
HVM_DBG_LOG(DBG_LEVEL_VLAPIC_INTERRUPT,
|
||||
- "vlapic %p, ppr 0x%x, isr 0x%x, isrv 0x%x.",
|
||||
+ "vlapic %p, ppr 0x%x, isr 0x%x, isrv 0x%x",
|
||||
vlapic, ppr, isr, isrv);
|
||||
|
||||
return ppr;
|
||||
@@ -211,7 +211,7 @@ static int vlapic_match_dest(struct vcpu
|
||||
struct vlapic *target = vcpu_vlapic(v);
|
||||
|
||||
HVM_DBG_LOG(DBG_LEVEL_VLAPIC, "target %p, source %p, dest 0x%x, "
|
||||
- "dest_mode 0x%x, short_hand 0x%x\n",
|
||||
+ "dest_mode 0x%x, short_hand 0x%x",
|
||||
target, source, dest, dest_mode, short_hand);
|
||||
|
||||
switch ( short_hand )
|
||||
@@ -270,14 +270,14 @@ static int vlapic_accept_irq(struct vcpu
|
||||
if ( vlapic_test_and_set_irr(vector, vlapic) && trig_mode )
|
||||
{
|
||||
HVM_DBG_LOG(DBG_LEVEL_VLAPIC,
|
||||
- "level trig mode repeatedly for vector %d\n", vector);
|
||||
+ "level trig mode repeatedly for vector %d", vector);
|
||||
break;
|
||||
}
|
||||
|
||||
if ( trig_mode )
|
||||
{
|
||||
HVM_DBG_LOG(DBG_LEVEL_VLAPIC,
|
||||
- "level trig mode for vector %d\n", vector);
|
||||
+ "level trig mode for vector %d", vector);
|
||||
vlapic_set_vector(vector, &vlapic->regs->data[APIC_TMR]);
|
||||
}
|
||||
|
||||
@@ -399,7 +399,7 @@ static void vlapic_ipi(struct vlapic *vl
|
||||
|
||||
HVM_DBG_LOG(DBG_LEVEL_VLAPIC, "icr_high 0x%x, icr_low 0x%x, "
|
||||
"short_hand 0x%x, dest 0x%x, trig_mode 0x%x, level 0x%x, "
|
||||
- "dest_mode 0x%x, delivery_mode 0x%x, vector 0x%x.",
|
||||
+ "dest_mode 0x%x, delivery_mode 0x%x, vector 0x%x",
|
||||
icr_high, icr_low, short_hand, dest,
|
||||
trig_mode, level, dest_mode, delivery_mode, vector);
|
||||
|
||||
@@ -437,7 +437,7 @@ static uint32_t vlapic_get_tmcct(struct
|
||||
|
||||
HVM_DBG_LOG(DBG_LEVEL_VLAPIC_TIMER,
|
||||
"timer initial count %d, timer current count %d, "
|
||||
- "offset %"PRId64".",
|
||||
+ "offset %"PRId64,
|
||||
tmict, tmcct, counter_passed);
|
||||
|
||||
return tmcct;
|
||||
@@ -454,7 +454,7 @@ static void vlapic_set_tdcr(struct vlapi
|
||||
vlapic->hw.timer_divisor = 1 << (val & 7);
|
||||
|
||||
HVM_DBG_LOG(DBG_LEVEL_VLAPIC_TIMER,
|
||||
- "vlapic_set_tdcr timer_divisor: %d.", vlapic->hw.timer_divisor);
|
||||
+ "timer_divisor: %d", vlapic->hw.timer_divisor);
|
||||
}
|
||||
|
||||
static void vlapic_read_aligned(struct vlapic *vlapic, unsigned int offset,
|
||||
@@ -493,7 +493,7 @@ static unsigned long vlapic_read(struct
|
||||
/* some bugs on kernel cause read this with byte*/
|
||||
if ( len != 4 )
|
||||
HVM_DBG_LOG(DBG_LEVEL_VLAPIC,
|
||||
- "read with len=0x%lx, should be 4 instead.\n",
|
||||
+ "read with len=0x%lx, should be 4 instead",
|
||||
len);
|
||||
|
||||
alignment = offset & 0x3;
|
||||
@@ -522,7 +522,7 @@ static unsigned long vlapic_read(struct
|
||||
}
|
||||
|
||||
HVM_DBG_LOG(DBG_LEVEL_VLAPIC, "offset 0x%x with length 0x%lx, "
|
||||
- "and the result is 0x%lx.", offset, len, result);
|
||||
+ "and the result is 0x%lx", offset, len, result);
|
||||
|
||||
return result;
|
||||
|
||||
@@ -539,7 +539,7 @@ static void vlapic_write(struct vcpu *v,
|
||||
|
||||
if ( offset != 0xb0 )
|
||||
HVM_DBG_LOG(DBG_LEVEL_VLAPIC,
|
||||
- "offset 0x%x with length 0x%lx, and value is 0x%lx.",
|
||||
+ "offset 0x%x with length 0x%lx, and value is 0x%lx",
|
||||
offset, len, val);
|
||||
|
||||
/*
|
||||
@@ -713,7 +713,7 @@ void vlapic_msr_set(struct vlapic *vlapi
|
||||
vlapic->hw.apic_base_msr = value;
|
||||
|
||||
HVM_DBG_LOG(DBG_LEVEL_VLAPIC,
|
||||
- "apic base msr is 0x%016"PRIx64".", vlapic->hw.apic_base_msr);
|
||||
+ "apic base msr is 0x%016"PRIx64, vlapic->hw.apic_base_msr);
|
||||
}
|
||||
|
||||
int vlapic_accept_pic_intr(struct vcpu *v)
|
||||
@@ -913,7 +913,7 @@ int vlapic_init(struct vcpu *v)
|
||||
{
|
||||
struct vlapic *vlapic = vcpu_vlapic(v);
|
||||
|
||||
- HVM_DBG_LOG(DBG_LEVEL_VLAPIC, "vlapic_init %d", v->vcpu_id);
|
||||
+ HVM_DBG_LOG(DBG_LEVEL_VLAPIC, "%d", v->vcpu_id);
|
||||
|
||||
vlapic->regs_page = alloc_domheap_page(NULL);
|
||||
if ( vlapic->regs_page == NULL )
|
||||
Index: 2007-05-14/xen/arch/x86/hvm/vmx/vmx.c
|
||||
===================================================================
|
||||
--- 2007-05-14.orig/xen/arch/x86/hvm/vmx/vmx.c 2007-05-14 14:33:24.000000000 +0200
|
||||
+++ 2007-05-14/xen/arch/x86/hvm/vmx/vmx.c 2007-05-14 14:33:28.000000000 +0200
|
||||
@@ -111,10 +111,11 @@ static void vmx_save_host_msrs(void)
|
||||
static inline int long_mode_do_msr_read(struct cpu_user_regs *regs)
|
||||
{
|
||||
u64 msr_content = 0;
|
||||
+ u32 ecx = regs->ecx;
|
||||
struct vcpu *v = current;
|
||||
struct vmx_msr_state *guest_msr_state = &v->arch.hvm_vmx.msr_state;
|
||||
|
||||
- switch ( (u32)regs->ecx ) {
|
||||
+ switch ( ecx ) {
|
||||
case MSR_EFER:
|
||||
msr_content = v->arch.hvm_vmx.efer;
|
||||
break;
|
||||
@@ -157,7 +158,7 @@ static inline int long_mode_do_msr_read(
|
||||
return 0;
|
||||
}
|
||||
|
||||
- HVM_DBG_LOG(DBG_LEVEL_2, "msr_content: 0x%"PRIx64, msr_content);
|
||||
+ HVM_DBG_LOG(DBG_LEVEL_0, "msr 0x%x content 0x%"PRIx64, ecx, msr_content);
|
||||
|
||||
regs->eax = (u32)(msr_content >> 0);
|
||||
regs->edx = (u32)(msr_content >> 32);
|
||||
@@ -173,8 +174,7 @@ static inline int long_mode_do_msr_write
|
||||
struct vmx_msr_state *guest_msr_state = &v->arch.hvm_vmx.msr_state;
|
||||
struct vmx_msr_state *host_msr_state = &this_cpu(host_msr_state);
|
||||
|
||||
- HVM_DBG_LOG(DBG_LEVEL_1, "msr 0x%x msr_content 0x%"PRIx64"\n",
|
||||
- ecx, msr_content);
|
||||
+ HVM_DBG_LOG(DBG_LEVEL_0, "msr 0x%x content 0x%"PRIx64, ecx, msr_content);
|
||||
|
||||
switch ( ecx )
|
||||
{
|
||||
@@ -262,7 +262,7 @@ static inline int long_mode_do_msr_write
|
||||
return 1;
|
||||
|
||||
uncanonical_address:
|
||||
- HVM_DBG_LOG(DBG_LEVEL_1, "Not cano address of msr write %x\n", ecx);
|
||||
+ HVM_DBG_LOG(DBG_LEVEL_0, "Not cano address of msr write %x", ecx);
|
||||
gp_fault:
|
||||
vmx_inject_hw_exception(v, TRAP_gp_fault, 0);
|
||||
return 0;
|
||||
@@ -577,7 +577,7 @@ int vmx_vmcs_restore(struct vcpu *v, str
|
||||
* If different, make a shadow. Check if the PDBR is valid
|
||||
* first.
|
||||
*/
|
||||
- HVM_DBG_LOG(DBG_LEVEL_VMMU, "CR3 c->cr3 = %"PRIx64"", c->cr3);
|
||||
+ HVM_DBG_LOG(DBG_LEVEL_VMMU, "CR3 c->cr3 = %"PRIx64, c->cr3);
|
||||
/* current!=vcpu as not called by arch_vmx_do_launch */
|
||||
mfn = gmfn_to_mfn(v->domain, c->cr3 >> PAGE_SHIFT);
|
||||
if( !mfn_valid(mfn) || !get_page(mfn_to_page(mfn), v->domain)) {
|
||||
@@ -2024,7 +2024,7 @@ static int vmx_set_cr0(unsigned long val
|
||||
unsigned long old_cr0;
|
||||
unsigned long old_base_mfn;
|
||||
|
||||
- HVM_DBG_LOG(DBG_LEVEL_VMMU, "Update CR0 value = %lx\n", value);
|
||||
+ HVM_DBG_LOG(DBG_LEVEL_VMMU, "Update CR0 value = %lx", value);
|
||||
|
||||
/* ET is reserved and should be always be 1. */
|
||||
value |= X86_CR0_ET;
|
||||
@@ -2073,12 +2073,12 @@ static int vmx_set_cr0(unsigned long val
|
||||
if ( !(v->arch.hvm_vmx.cpu_shadow_cr4 & X86_CR4_PAE) )
|
||||
{
|
||||
HVM_DBG_LOG(DBG_LEVEL_1, "Guest enabled paging "
|
||||
- "with EFER.LME set but not CR4.PAE\n");
|
||||
+ "with EFER.LME set but not CR4.PAE");
|
||||
vmx_inject_hw_exception(v, TRAP_gp_fault, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
- HVM_DBG_LOG(DBG_LEVEL_1, "Enabling long mode\n");
|
||||
+ HVM_DBG_LOG(DBG_LEVEL_1, "Enabling long mode");
|
||||
v->arch.hvm_vmx.efer |= EFER_LMA;
|
||||
vm_entry_value = __vmread(VM_ENTRY_CONTROLS);
|
||||
vm_entry_value |= VM_ENTRY_IA32E_MODE;
|
||||
@@ -2139,7 +2139,7 @@ static int vmx_set_cr0(unsigned long val
|
||||
{
|
||||
eip = __vmread(GUEST_RIP);
|
||||
HVM_DBG_LOG(DBG_LEVEL_1,
|
||||
- "Transfering control to vmxassist %%eip 0x%lx\n", eip);
|
||||
+ "Transfering control to vmxassist %%eip 0x%lx", eip);
|
||||
return 0; /* do not update eip! */
|
||||
}
|
||||
}
|
||||
@@ -2147,12 +2147,12 @@ static int vmx_set_cr0(unsigned long val
|
||||
{
|
||||
eip = __vmread(GUEST_RIP);
|
||||
HVM_DBG_LOG(DBG_LEVEL_1,
|
||||
- "Enabling CR0.PE at %%eip 0x%lx\n", eip);
|
||||
+ "Enabling CR0.PE at %%eip 0x%lx", eip);
|
||||
if ( vmx_assist(v, VMX_ASSIST_RESTORE) )
|
||||
{
|
||||
eip = __vmread(GUEST_RIP);
|
||||
HVM_DBG_LOG(DBG_LEVEL_1,
|
||||
- "Restoring to %%eip 0x%lx\n", eip);
|
||||
+ "Restoring to %%eip 0x%lx", eip);
|
||||
return 0; /* do not update eip! */
|
||||
}
|
||||
}
|
||||
@@ -2310,7 +2310,7 @@ static int mov_to_cr(int gp, int cr, str
|
||||
if ( unlikely(vmx_long_mode_enabled(v)) )
|
||||
{
|
||||
HVM_DBG_LOG(DBG_LEVEL_1, "Guest cleared CR4.PAE while "
|
||||
- "EFER.LMA is set\n");
|
||||
+ "EFER.LMA is set");
|
||||
vmx_inject_hw_exception(v, TRAP_gp_fault, 0);
|
||||
}
|
||||
}
|
||||
@@ -2440,8 +2440,7 @@ static inline int vmx_do_msr_read(struct
|
||||
u32 ecx = regs->ecx, eax, edx;
|
||||
struct vcpu *v = current;
|
||||
|
||||
- HVM_DBG_LOG(DBG_LEVEL_1, "ecx=%x, eax=%x, edx=%x",
|
||||
- ecx, (u32)regs->eax, (u32)regs->edx);
|
||||
+ HVM_DBG_LOG(DBG_LEVEL_1, "ecx=%x", ecx);
|
||||
|
||||
switch (ecx) {
|
||||
case MSR_IA32_TIME_STAMP_COUNTER:
|
670
hvm-efer.patch
Normal file
670
hvm-efer.patch
Normal file
@ -0,0 +1,670 @@
|
||||
Index: 2007-05-14/xen/arch/x86/domain.c
|
||||
===================================================================
|
||||
--- 2007-05-14.orig/xen/arch/x86/domain.c 2007-05-14 14:27:23.000000000 +0200
|
||||
+++ 2007-05-14/xen/arch/x86/domain.c 2007-05-14 14:31:12.000000000 +0200
|
||||
@@ -47,6 +47,7 @@
|
||||
#endif
|
||||
|
||||
DEFINE_PER_CPU(struct vcpu *, curr_vcpu);
|
||||
+DEFINE_PER_CPU(__u64, efer);
|
||||
|
||||
static void paravirt_ctxt_switch_from(struct vcpu *v);
|
||||
static void paravirt_ctxt_switch_to(struct vcpu *v);
|
||||
@@ -1138,21 +1139,18 @@ void context_switch(struct vcpu *prev, s
|
||||
__context_switch();
|
||||
|
||||
#ifdef CONFIG_COMPAT
|
||||
- if ( is_idle_vcpu(prev) ||
|
||||
- (is_pv_32on64_domain(prev->domain) !=
|
||||
- is_pv_32on64_domain(next->domain)) )
|
||||
+ if ( !is_hvm_vcpu(next) &&
|
||||
+ (is_idle_vcpu(prev) ||
|
||||
+ is_hvm_vcpu(prev) ||
|
||||
+ is_pv_32on64_vcpu(prev) != is_pv_32on64_vcpu(next)) )
|
||||
{
|
||||
- uint32_t efer_lo, efer_hi;
|
||||
+ uint64_t efer = read_efer();
|
||||
|
||||
local_flush_tlb_one(GDT_VIRT_START(next) +
|
||||
FIRST_RESERVED_GDT_BYTE);
|
||||
|
||||
- rdmsr(MSR_EFER, efer_lo, efer_hi);
|
||||
- if ( !is_pv_32on64_domain(next->domain) == !(efer_lo & EFER_SCE) )
|
||||
- {
|
||||
- efer_lo ^= EFER_SCE;
|
||||
- wrmsr(MSR_EFER, efer_lo, efer_hi);
|
||||
- }
|
||||
+ if ( !is_pv_32on64_vcpu(next) == !(efer & EFER_SCE) )
|
||||
+ write_efer(efer ^ EFER_SCE);
|
||||
}
|
||||
#endif
|
||||
|
||||
Index: 2007-05-14/xen/arch/x86/hvm/svm/svm.c
|
||||
===================================================================
|
||||
--- 2007-05-14.orig/xen/arch/x86/hvm/svm/svm.c 2007-05-14 13:47:25.000000000 +0200
|
||||
+++ 2007-05-14/xen/arch/x86/hvm/svm/svm.c 2007-05-14 14:28:19.000000000 +0200
|
||||
@@ -96,11 +96,8 @@ static inline void svm_inject_exception(
|
||||
|
||||
static void stop_svm(void)
|
||||
{
|
||||
- u32 eax, edx;
|
||||
/* We turn off the EFER_SVME bit. */
|
||||
- rdmsr(MSR_EFER, eax, edx);
|
||||
- eax &= ~EFER_SVME;
|
||||
- wrmsr(MSR_EFER, eax, edx);
|
||||
+ write_efer(read_efer() & ~EFER_SVME);
|
||||
}
|
||||
|
||||
static void svm_store_cpu_guest_regs(
|
||||
@@ -145,7 +142,13 @@ static inline int long_mode_do_msr_write
|
||||
{
|
||||
case MSR_EFER:
|
||||
/* Offending reserved bit will cause #GP. */
|
||||
- if ( msr_content & ~(EFER_LME | EFER_LMA | EFER_NX | EFER_SCE) )
|
||||
+#ifdef __x86_64__
|
||||
+ if ( (msr_content & ~(EFER_LME | EFER_LMA | EFER_NX | EFER_SCE)) ||
|
||||
+#else
|
||||
+ if ( (msr_content & ~(EFER_NX | EFER_SCE)) ||
|
||||
+#endif
|
||||
+ (!cpu_has_nx && (msr_content & EFER_NX)) ||
|
||||
+ (!cpu_has_syscall && (msr_content & EFER_SCE)) )
|
||||
{
|
||||
gdprintk(XENLOG_WARNING, "Trying to set reserved bit in "
|
||||
"EFER: %"PRIx64"\n", msr_content);
|
||||
@@ -502,7 +505,7 @@ int svm_vmcb_restore(struct vcpu *v, str
|
||||
}
|
||||
|
||||
|
||||
-void svm_save_cpu_state(struct vcpu *v, struct hvm_hw_cpu *data)
|
||||
+static void svm_save_cpu_state(struct vcpu *v, struct hvm_hw_cpu *data)
|
||||
{
|
||||
struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
|
||||
|
||||
@@ -518,7 +521,7 @@ void svm_save_cpu_state(struct vcpu *v,
|
||||
}
|
||||
|
||||
|
||||
-void svm_load_cpu_state(struct vcpu *v, struct hvm_hw_cpu *data)
|
||||
+static void svm_load_cpu_state(struct vcpu *v, struct hvm_hw_cpu *data)
|
||||
{
|
||||
struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
|
||||
|
||||
@@ -537,13 +540,13 @@ void svm_load_cpu_state(struct vcpu *v,
|
||||
hvm_set_guest_time(v, data->tsc);
|
||||
}
|
||||
|
||||
-void svm_save_vmcb_ctxt(struct vcpu *v, struct hvm_hw_cpu *ctxt)
|
||||
+static void svm_save_vmcb_ctxt(struct vcpu *v, struct hvm_hw_cpu *ctxt)
|
||||
{
|
||||
svm_save_cpu_state(v, ctxt);
|
||||
svm_vmcb_save(v, ctxt);
|
||||
}
|
||||
|
||||
-int svm_load_vmcb_ctxt(struct vcpu *v, struct hvm_hw_cpu *ctxt)
|
||||
+static int svm_load_vmcb_ctxt(struct vcpu *v, struct hvm_hw_cpu *ctxt)
|
||||
{
|
||||
svm_load_cpu_state(v, ctxt);
|
||||
if (svm_vmcb_restore(v, ctxt)) {
|
||||
@@ -871,6 +874,7 @@ static struct hvm_function_table svm_fun
|
||||
.paging_enabled = svm_paging_enabled,
|
||||
.long_mode_enabled = svm_long_mode_enabled,
|
||||
.pae_enabled = svm_pae_enabled,
|
||||
+ .nx_enabled = svm_nx_enabled,
|
||||
.interrupts_enabled = svm_interrupts_enabled,
|
||||
.guest_x86_mode = svm_guest_x86_mode,
|
||||
.get_guest_ctrl_reg = svm_get_ctrl_reg,
|
||||
@@ -927,9 +931,7 @@ int start_svm(void)
|
||||
((root_vmcb[cpu] = alloc_vmcb()) == NULL) )
|
||||
return 0;
|
||||
|
||||
- rdmsr(MSR_EFER, eax, edx);
|
||||
- eax |= EFER_SVME;
|
||||
- wrmsr(MSR_EFER, eax, edx);
|
||||
+ write_efer(read_efer() | EFER_SVME);
|
||||
|
||||
svm_npt_detect();
|
||||
|
||||
Index: 2007-05-14/xen/arch/x86/hvm/vmx/vmcs.c
|
||||
===================================================================
|
||||
--- 2007-05-14.orig/xen/arch/x86/hvm/vmx/vmcs.c 2007-05-03 09:45:09.000000000 +0200
|
||||
+++ 2007-05-14/xen/arch/x86/hvm/vmx/vmcs.c 2007-05-14 14:28:19.000000000 +0200
|
||||
@@ -285,11 +285,6 @@ static void construct_vmcs(struct vcpu *
|
||||
|
||||
vmx_vmcs_enter(v);
|
||||
|
||||
- v->arch.hvm_vmx.cpu_cr2 = 0;
|
||||
- v->arch.hvm_vmx.cpu_cr3 = 0;
|
||||
- memset(&v->arch.hvm_vmx.msr_state, 0, sizeof(v->arch.hvm_vmx.msr_state));
|
||||
- v->arch.hvm_vmx.vmxassist_enabled = 0;
|
||||
-
|
||||
/* VMCS controls. */
|
||||
__vmwrite(PIN_BASED_VM_EXEC_CONTROL, vmx_pin_based_exec_control);
|
||||
__vmwrite(VM_EXIT_CONTROLS, vmx_vmexit_control);
|
||||
Index: 2007-05-14/xen/arch/x86/hvm/vmx/vmx.c
|
||||
===================================================================
|
||||
--- 2007-05-14.orig/xen/arch/x86/hvm/vmx/vmx.c 2007-05-14 13:47:25.000000000 +0200
|
||||
+++ 2007-05-14/xen/arch/x86/hvm/vmx/vmx.c 2007-05-14 14:28:19.000000000 +0200
|
||||
@@ -89,7 +89,7 @@ static DEFINE_PER_CPU(struct vmx_msr_sta
|
||||
static u32 msr_index[VMX_MSR_COUNT] =
|
||||
{
|
||||
MSR_LSTAR, MSR_STAR, MSR_CSTAR,
|
||||
- MSR_SYSCALL_MASK, MSR_EFER,
|
||||
+ MSR_SYSCALL_MASK
|
||||
};
|
||||
|
||||
static void vmx_save_host_msrs(void)
|
||||
@@ -117,8 +117,7 @@ static inline int long_mode_do_msr_read(
|
||||
|
||||
switch ( (u32)regs->ecx ) {
|
||||
case MSR_EFER:
|
||||
- HVM_DBG_LOG(DBG_LEVEL_2, "EFER msr_content 0x%"PRIx64, msr_content);
|
||||
- msr_content = guest_msr_state->msrs[VMX_INDEX_MSR_EFER];
|
||||
+ msr_content = v->arch.hvm_vmx.efer;
|
||||
break;
|
||||
|
||||
case MSR_FS_BASE:
|
||||
@@ -130,7 +129,7 @@ static inline int long_mode_do_msr_read(
|
||||
goto check_long_mode;
|
||||
|
||||
case MSR_SHADOW_GS_BASE:
|
||||
- msr_content = guest_msr_state->shadow_gs;
|
||||
+ msr_content = v->arch.hvm_vmx.shadow_gs;
|
||||
check_long_mode:
|
||||
if ( !(vmx_long_mode_enabled(v)) )
|
||||
{
|
||||
@@ -182,7 +181,9 @@ static inline int long_mode_do_msr_write
|
||||
{
|
||||
case MSR_EFER:
|
||||
/* offending reserved bit will cause #GP */
|
||||
- if ( msr_content & ~(EFER_LME | EFER_LMA | EFER_NX | EFER_SCE) )
|
||||
+ if ( (msr_content & ~(EFER_LME | EFER_LMA | EFER_NX | EFER_SCE)) ||
|
||||
+ (!cpu_has_nx && (msr_content & EFER_NX)) ||
|
||||
+ (!cpu_has_syscall && (msr_content & EFER_SCE)) )
|
||||
{
|
||||
gdprintk(XENLOG_WARNING, "Trying to set reserved bit in "
|
||||
"EFER: %"PRIx64"\n", msr_content);
|
||||
@@ -190,7 +191,7 @@ static inline int long_mode_do_msr_write
|
||||
}
|
||||
|
||||
if ( (msr_content & EFER_LME)
|
||||
- && !(guest_msr_state->msrs[VMX_INDEX_MSR_EFER] & EFER_LME) )
|
||||
+ && !(v->arch.hvm_vmx.efer & EFER_LME) )
|
||||
{
|
||||
if ( unlikely(vmx_paging_enabled(v)) )
|
||||
{
|
||||
@@ -200,7 +201,7 @@ static inline int long_mode_do_msr_write
|
||||
}
|
||||
}
|
||||
else if ( !(msr_content & EFER_LME)
|
||||
- && (guest_msr_state->msrs[VMX_INDEX_MSR_EFER] & EFER_LME) )
|
||||
+ && (v->arch.hvm_vmx.efer & EFER_LME) )
|
||||
{
|
||||
if ( unlikely(vmx_paging_enabled(v)) )
|
||||
{
|
||||
@@ -210,7 +211,11 @@ static inline int long_mode_do_msr_write
|
||||
}
|
||||
}
|
||||
|
||||
- guest_msr_state->msrs[VMX_INDEX_MSR_EFER] = msr_content;
|
||||
+ if ( (msr_content ^ v->arch.hvm_vmx.efer) & (EFER_NX|EFER_SCE) )
|
||||
+ write_efer((read_efer() & ~(EFER_NX|EFER_SCE)) |
|
||||
+ (msr_content & (EFER_NX|EFER_SCE)));
|
||||
+
|
||||
+ v->arch.hvm_vmx.efer = msr_content;
|
||||
break;
|
||||
|
||||
case MSR_FS_BASE:
|
||||
@@ -228,7 +233,7 @@ static inline int long_mode_do_msr_write
|
||||
__vmwrite(GUEST_GS_BASE, msr_content);
|
||||
else
|
||||
{
|
||||
- v->arch.hvm_vmx.msr_state.shadow_gs = msr_content;
|
||||
+ v->arch.hvm_vmx.shadow_gs = msr_content;
|
||||
wrmsrl(MSR_SHADOW_GS_BASE, msr_content);
|
||||
}
|
||||
|
||||
@@ -280,12 +285,14 @@ static void vmx_restore_host_msrs(void)
|
||||
wrmsrl(msr_index[i], host_msr_state->msrs[i]);
|
||||
clear_bit(i, &host_msr_state->flags);
|
||||
}
|
||||
+ if ( !(read_efer() & EFER_NX) )
|
||||
+ write_efer(read_efer() | EFER_NX);
|
||||
}
|
||||
|
||||
static void vmx_save_guest_msrs(struct vcpu *v)
|
||||
{
|
||||
/* MSR_SHADOW_GS_BASE may have been changed by swapgs instruction. */
|
||||
- rdmsrl(MSR_SHADOW_GS_BASE, v->arch.hvm_vmx.msr_state.shadow_gs);
|
||||
+ rdmsrl(MSR_SHADOW_GS_BASE, v->arch.hvm_vmx.shadow_gs);
|
||||
}
|
||||
|
||||
static void vmx_restore_guest_msrs(struct vcpu *v)
|
||||
@@ -297,11 +304,9 @@ static void vmx_restore_guest_msrs(struc
|
||||
guest_msr_state = &v->arch.hvm_vmx.msr_state;
|
||||
host_msr_state = &this_cpu(host_msr_state);
|
||||
|
||||
- wrmsrl(MSR_SHADOW_GS_BASE, guest_msr_state->shadow_gs);
|
||||
+ wrmsrl(MSR_SHADOW_GS_BASE, v->arch.hvm_vmx.shadow_gs);
|
||||
|
||||
guest_flags = guest_msr_state->flags;
|
||||
- if ( !guest_flags )
|
||||
- return;
|
||||
|
||||
while ( guest_flags ) {
|
||||
i = find_first_set_bit(guest_flags);
|
||||
@@ -313,23 +318,90 @@ static void vmx_restore_guest_msrs(struc
|
||||
wrmsrl(msr_index[i], guest_msr_state->msrs[i]);
|
||||
clear_bit(i, &guest_flags);
|
||||
}
|
||||
+
|
||||
+ if ( (v->arch.hvm_vmx.efer ^ read_efer()) & (EFER_NX|EFER_SCE) )
|
||||
+ {
|
||||
+ HVM_DBG_LOG(DBG_LEVEL_2,
|
||||
+ "restore guest's EFER with value %lx",
|
||||
+ v->arch.hvm_vmx.efer);
|
||||
+ write_efer((read_efer() & ~(EFER_NX|EFER_SCE)) |
|
||||
+ (v->arch.hvm_vmx.efer & (EFER_NX|EFER_SCE)));
|
||||
+ }
|
||||
}
|
||||
|
||||
#else /* __i386__ */
|
||||
|
||||
#define vmx_save_host_msrs() ((void)0)
|
||||
-#define vmx_restore_host_msrs() ((void)0)
|
||||
+
|
||||
+static void vmx_restore_host_msrs(void)
|
||||
+{
|
||||
+ if ( !(read_efer() & EFER_NX) )
|
||||
+ write_efer(read_efer() | EFER_NX);
|
||||
+}
|
||||
+
|
||||
#define vmx_save_guest_msrs(v) ((void)0)
|
||||
-#define vmx_restore_guest_msrs(v) ((void)0)
|
||||
+
|
||||
+static void vmx_restore_guest_msrs(struct vcpu *v)
|
||||
+{
|
||||
+ if ( (v->arch.hvm_vmx.efer ^ read_efer()) & EFER_NX )
|
||||
+ {
|
||||
+ HVM_DBG_LOG(DBG_LEVEL_2,
|
||||
+ "restore guest's EFER with value %lx",
|
||||
+ v->arch.hvm_vmx.efer);
|
||||
+ write_efer((read_efer() & ~EFER_NX) |
|
||||
+ (v->arch.hvm_vmx.efer & EFER_NX));
|
||||
+ }
|
||||
+}
|
||||
|
||||
static inline int long_mode_do_msr_read(struct cpu_user_regs *regs)
|
||||
{
|
||||
- return 0;
|
||||
+ u64 msr_content = 0;
|
||||
+ struct vcpu *v = current;
|
||||
+
|
||||
+ switch ( regs->ecx ) {
|
||||
+ case MSR_EFER:
|
||||
+ msr_content = v->arch.hvm_vmx.efer;
|
||||
+ break;
|
||||
+
|
||||
+ default:
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ regs->eax = msr_content >> 0;
|
||||
+ regs->edx = msr_content >> 32;
|
||||
+
|
||||
+ return 1;
|
||||
}
|
||||
|
||||
static inline int long_mode_do_msr_write(struct cpu_user_regs *regs)
|
||||
{
|
||||
- return 0;
|
||||
+ u64 msr_content = regs->eax | ((u64)regs->edx << 32);
|
||||
+ struct vcpu *v = current;
|
||||
+
|
||||
+ switch ( regs->ecx )
|
||||
+ {
|
||||
+ case MSR_EFER:
|
||||
+ /* offending reserved bit will cause #GP */
|
||||
+ if ( (msr_content & ~EFER_NX) ||
|
||||
+ (!cpu_has_nx && (msr_content & EFER_NX)) )
|
||||
+ {
|
||||
+ gdprintk(XENLOG_WARNING, "Trying to set reserved bit in "
|
||||
+ "EFER: %"PRIx64"\n", msr_content);
|
||||
+ vmx_inject_hw_exception(v, TRAP_gp_fault, 0);
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ if ( (msr_content ^ v->arch.hvm_vmx.efer) & EFER_NX )
|
||||
+ write_efer((read_efer() & ~EFER_NX) | (msr_content & EFER_NX));
|
||||
+
|
||||
+ v->arch.hvm_vmx.efer = msr_content;
|
||||
+ break;
|
||||
+
|
||||
+ default:
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ return 1;
|
||||
}
|
||||
|
||||
#endif /* __i386__ */
|
||||
@@ -637,7 +709,7 @@ int vmx_vmcs_restore(struct vcpu *v, str
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
-#ifdef HVM_DEBUG_SUSPEND
|
||||
+#if defined(__x86_64__) && defined(HVM_DEBUG_SUSPEND)
|
||||
static void dump_msr_state(struct vmx_msr_state *m)
|
||||
{
|
||||
int i = 0;
|
||||
@@ -648,17 +720,16 @@ static void dump_msr_state(struct vmx_ms
|
||||
printk("\n");
|
||||
}
|
||||
#else
|
||||
-static void dump_msr_state(struct vmx_msr_state *m)
|
||||
-{
|
||||
-}
|
||||
+#define dump_msr_state(m) ((void)0)
|
||||
#endif
|
||||
|
||||
-void vmx_save_cpu_state(struct vcpu *v, struct hvm_hw_cpu *data)
|
||||
+static void vmx_save_cpu_state(struct vcpu *v, struct hvm_hw_cpu *data)
|
||||
{
|
||||
+#ifdef __x86_64__
|
||||
struct vmx_msr_state *guest_state = &v->arch.hvm_vmx.msr_state;
|
||||
unsigned long guest_flags = guest_state->flags;
|
||||
|
||||
- data->shadow_gs = guest_state->shadow_gs;
|
||||
+ data->shadow_gs = v->arch.hvm_vmx.shadow_gs;
|
||||
|
||||
/* save msrs */
|
||||
data->msr_flags = guest_flags;
|
||||
@@ -666,15 +737,18 @@ void vmx_save_cpu_state(struct vcpu *v,
|
||||
data->msr_star = guest_state->msrs[VMX_INDEX_MSR_STAR];
|
||||
data->msr_cstar = guest_state->msrs[VMX_INDEX_MSR_CSTAR];
|
||||
data->msr_syscall_mask = guest_state->msrs[VMX_INDEX_MSR_SYSCALL_MASK];
|
||||
- data->msr_efer = guest_state->msrs[VMX_INDEX_MSR_EFER];
|
||||
+#endif
|
||||
+
|
||||
+ data->msr_efer = v->arch.hvm_vmx.efer;
|
||||
|
||||
data->tsc = hvm_get_guest_time(v);
|
||||
|
||||
dump_msr_state(guest_state);
|
||||
}
|
||||
|
||||
-void vmx_load_cpu_state(struct vcpu *v, struct hvm_hw_cpu *data)
|
||||
+static void vmx_load_cpu_state(struct vcpu *v, struct hvm_hw_cpu *data)
|
||||
{
|
||||
+#ifdef __x86_64__
|
||||
struct vmx_msr_state *guest_state = &v->arch.hvm_vmx.msr_state;
|
||||
|
||||
/* restore msrs */
|
||||
@@ -683,9 +757,11 @@ void vmx_load_cpu_state(struct vcpu *v,
|
||||
guest_state->msrs[VMX_INDEX_MSR_STAR] = data->msr_star;
|
||||
guest_state->msrs[VMX_INDEX_MSR_CSTAR] = data->msr_cstar;
|
||||
guest_state->msrs[VMX_INDEX_MSR_SYSCALL_MASK] = data->msr_syscall_mask;
|
||||
- guest_state->msrs[VMX_INDEX_MSR_EFER] = data->msr_efer;
|
||||
|
||||
- guest_state->shadow_gs = data->shadow_gs;
|
||||
+ v->arch.hvm_vmx.shadow_gs = data->shadow_gs;
|
||||
+#endif
|
||||
+
|
||||
+ v->arch.hvm_vmx.efer = data->msr_efer;
|
||||
|
||||
v->arch.hvm_vmx.vmxassist_enabled = !(data->cr0 & X86_CR0_PE);
|
||||
|
||||
@@ -695,7 +771,7 @@ void vmx_load_cpu_state(struct vcpu *v,
|
||||
}
|
||||
|
||||
|
||||
-void vmx_save_vmcs_ctxt(struct vcpu *v, struct hvm_hw_cpu *ctxt)
|
||||
+static void vmx_save_vmcs_ctxt(struct vcpu *v, struct hvm_hw_cpu *ctxt)
|
||||
{
|
||||
vmx_save_cpu_state(v, ctxt);
|
||||
vmx_vmcs_enter(v);
|
||||
@@ -703,7 +779,7 @@ void vmx_save_vmcs_ctxt(struct vcpu *v,
|
||||
vmx_vmcs_exit(v);
|
||||
}
|
||||
|
||||
-int vmx_load_vmcs_ctxt(struct vcpu *v, struct hvm_hw_cpu *ctxt)
|
||||
+static int vmx_load_vmcs_ctxt(struct vcpu *v, struct hvm_hw_cpu *ctxt)
|
||||
{
|
||||
vmx_load_cpu_state(v, ctxt);
|
||||
if (vmx_vmcs_restore(v, ctxt)) {
|
||||
@@ -1017,6 +1093,11 @@ static int vmx_pae_enabled(struct vcpu *
|
||||
return (vmx_paging_enabled(v) && (cr4 & X86_CR4_PAE));
|
||||
}
|
||||
|
||||
+static int vmx_nx_enabled(struct vcpu *v)
|
||||
+{
|
||||
+ return v->arch.hvm_vmx.efer & EFER_NX;
|
||||
+}
|
||||
+
|
||||
static int vmx_interrupts_enabled(struct vcpu *v)
|
||||
{
|
||||
unsigned long eflags = __vmread(GUEST_RFLAGS);
|
||||
@@ -1097,6 +1178,7 @@ static struct hvm_function_table vmx_fun
|
||||
.paging_enabled = vmx_paging_enabled,
|
||||
.long_mode_enabled = vmx_long_mode_enabled,
|
||||
.pae_enabled = vmx_pae_enabled,
|
||||
+ .nx_enabled = vmx_nx_enabled,
|
||||
.interrupts_enabled = vmx_interrupts_enabled,
|
||||
.guest_x86_mode = vmx_guest_x86_mode,
|
||||
.get_guest_ctrl_reg = vmx_get_ctrl_reg,
|
||||
@@ -1997,8 +2079,7 @@ static int vmx_set_cr0(unsigned long val
|
||||
else
|
||||
{
|
||||
HVM_DBG_LOG(DBG_LEVEL_1, "Enabling long mode\n");
|
||||
- v->arch.hvm_vmx.msr_state.msrs[VMX_INDEX_MSR_EFER]
|
||||
- |= EFER_LMA;
|
||||
+ v->arch.hvm_vmx.efer |= EFER_LMA;
|
||||
vm_entry_value = __vmread(VM_ENTRY_CONTROLS);
|
||||
vm_entry_value |= VM_ENTRY_IA32E_MODE;
|
||||
__vmwrite(VM_ENTRY_CONTROLS, vm_entry_value);
|
||||
@@ -2047,8 +2128,7 @@ static int vmx_set_cr0(unsigned long val
|
||||
*/
|
||||
if ( vmx_long_mode_enabled(v) )
|
||||
{
|
||||
- v->arch.hvm_vmx.msr_state.msrs[VMX_INDEX_MSR_EFER]
|
||||
- &= ~EFER_LMA;
|
||||
+ v->arch.hvm_vmx.efer &= ~EFER_LMA;
|
||||
vm_entry_value = __vmread(VM_ENTRY_CONTROLS);
|
||||
vm_entry_value &= ~VM_ENTRY_IA32E_MODE;
|
||||
__vmwrite(VM_ENTRY_CONTROLS, vm_entry_value);
|
||||
@@ -2080,7 +2160,7 @@ static int vmx_set_cr0(unsigned long val
|
||||
{
|
||||
if ( vmx_long_mode_enabled(v) )
|
||||
{
|
||||
- v->arch.hvm_vmx.msr_state.msrs[VMX_INDEX_MSR_EFER] &= ~EFER_LMA;
|
||||
+ v->arch.hvm_vmx.efer &= ~EFER_LMA;
|
||||
vm_entry_value = __vmread(VM_ENTRY_CONTROLS);
|
||||
vm_entry_value &= ~VM_ENTRY_IA32E_MODE;
|
||||
__vmwrite(VM_ENTRY_CONTROLS, vm_entry_value);
|
||||
Index: 2007-05-14/xen/arch/x86/mm/shadow/multi.c
|
||||
===================================================================
|
||||
--- 2007-05-14.orig/xen/arch/x86/mm/shadow/multi.c 2007-05-03 09:45:09.000000000 +0200
|
||||
+++ 2007-05-14/xen/arch/x86/mm/shadow/multi.c 2007-05-14 14:28:19.000000000 +0200
|
||||
@@ -181,11 +181,11 @@ guest_supports_superpages(struct vcpu *v
|
||||
static inline int
|
||||
guest_supports_nx(struct vcpu *v)
|
||||
{
|
||||
+ if ( GUEST_PAGING_LEVELS == 2 || !cpu_has_nx )
|
||||
+ return 0;
|
||||
if ( !is_hvm_vcpu(v) )
|
||||
- return cpu_has_nx;
|
||||
-
|
||||
- // XXX - fix this!
|
||||
- return 1;
|
||||
+ return 1;
|
||||
+ return hvm_nx_enabled(v);
|
||||
}
|
||||
|
||||
|
||||
Index: 2007-05-14/xen/include/asm-x86/cpufeature.h
|
||||
===================================================================
|
||||
--- 2007-05-14.orig/xen/include/asm-x86/cpufeature.h 2007-04-23 10:01:46.000000000 +0200
|
||||
+++ 2007-05-14/xen/include/asm-x86/cpufeature.h 2007-05-14 14:28:19.000000000 +0200
|
||||
@@ -114,6 +114,7 @@
|
||||
#define cpu_has_xmm2 boot_cpu_has(X86_FEATURE_XMM2)
|
||||
#define cpu_has_xmm3 boot_cpu_has(X86_FEATURE_XMM3)
|
||||
#define cpu_has_ht boot_cpu_has(X86_FEATURE_HT)
|
||||
+#define cpu_has_syscall boot_cpu_has(X86_FEATURE_SYSCALL)
|
||||
#define cpu_has_mp boot_cpu_has(X86_FEATURE_MP)
|
||||
#define cpu_has_nx boot_cpu_has(X86_FEATURE_NX)
|
||||
#define cpu_has_k6_mtrr boot_cpu_has(X86_FEATURE_K6_MTRR)
|
||||
@@ -136,6 +137,7 @@
|
||||
#define cpu_has_xmm2 1
|
||||
#define cpu_has_xmm3 boot_cpu_has(X86_FEATURE_XMM3)
|
||||
#define cpu_has_ht boot_cpu_has(X86_FEATURE_HT)
|
||||
+#define cpu_has_syscall 1
|
||||
#define cpu_has_mp 1
|
||||
#define cpu_has_nx boot_cpu_has(X86_FEATURE_NX)
|
||||
#define cpu_has_k6_mtrr 0
|
||||
Index: 2007-05-14/xen/include/asm-x86/hvm/hvm.h
|
||||
===================================================================
|
||||
--- 2007-05-14.orig/xen/include/asm-x86/hvm/hvm.h 2007-04-23 10:01:46.000000000 +0200
|
||||
+++ 2007-05-14/xen/include/asm-x86/hvm/hvm.h 2007-05-14 14:28:19.000000000 +0200
|
||||
@@ -93,14 +93,17 @@ struct hvm_function_table {
|
||||
* 1) determine whether paging is enabled,
|
||||
* 2) determine whether long mode is enabled,
|
||||
* 3) determine whether PAE paging is enabled,
|
||||
- * 4) determine whether interrupts are enabled or not,
|
||||
- * 5) determine the mode the guest is running in,
|
||||
- * 6) return the current guest control-register value
|
||||
- * 7) return the current guest segment descriptor base
|
||||
+ * 4) determine whether NX is enabled,
|
||||
+ * 5) determine whether interrupts are enabled or not,
|
||||
+ * 6) determine the mode the guest is running in,
|
||||
+ * 7) return the current guest control-register value
|
||||
+ * 8) return the current guest segment descriptor base
|
||||
+ * 9) return the current guest segment descriptor
|
||||
*/
|
||||
int (*paging_enabled)(struct vcpu *v);
|
||||
int (*long_mode_enabled)(struct vcpu *v);
|
||||
int (*pae_enabled)(struct vcpu *v);
|
||||
+ int (*nx_enabled)(struct vcpu *v);
|
||||
int (*interrupts_enabled)(struct vcpu *v);
|
||||
int (*guest_x86_mode)(struct vcpu *v);
|
||||
unsigned long (*get_guest_ctrl_reg)(struct vcpu *v, unsigned int num);
|
||||
@@ -199,6 +202,12 @@ hvm_interrupts_enabled(struct vcpu *v)
|
||||
}
|
||||
|
||||
static inline int
|
||||
+hvm_nx_enabled(struct vcpu *v)
|
||||
+{
|
||||
+ return hvm_funcs.nx_enabled(v);
|
||||
+}
|
||||
+
|
||||
+static inline int
|
||||
hvm_guest_x86_mode(struct vcpu *v)
|
||||
{
|
||||
return hvm_funcs.guest_x86_mode(v);
|
||||
Index: 2007-05-14/xen/include/asm-x86/hvm/svm/svm.h
|
||||
===================================================================
|
||||
--- 2007-05-14.orig/xen/include/asm-x86/hvm/svm/svm.h 2007-04-23 10:01:46.000000000 +0200
|
||||
+++ 2007-05-14/xen/include/asm-x86/hvm/svm/svm.h 2007-05-14 14:28:19.000000000 +0200
|
||||
@@ -62,6 +62,11 @@ static inline int svm_pae_enabled(struct
|
||||
return svm_paging_enabled(v) && (guest_cr4 & X86_CR4_PAE);
|
||||
}
|
||||
|
||||
+static inline int svm_nx_enabled(struct vcpu *v)
|
||||
+{
|
||||
+ return v->arch.hvm_svm.cpu_shadow_efer & EFER_NX;
|
||||
+}
|
||||
+
|
||||
static inline int svm_pgbit_test(struct vcpu *v)
|
||||
{
|
||||
return v->arch.hvm_svm.cpu_shadow_cr0 & X86_CR0_PG;
|
||||
Index: 2007-05-14/xen/include/asm-x86/hvm/vmx/vmcs.h
|
||||
===================================================================
|
||||
--- 2007-05-14.orig/xen/include/asm-x86/hvm/vmx/vmcs.h 2007-05-03 09:45:09.000000000 +0200
|
||||
+++ 2007-05-14/xen/include/asm-x86/hvm/vmx/vmcs.h 2007-05-14 14:28:19.000000000 +0200
|
||||
@@ -39,7 +39,6 @@ enum {
|
||||
VMX_INDEX_MSR_STAR,
|
||||
VMX_INDEX_MSR_CSTAR,
|
||||
VMX_INDEX_MSR_SYSCALL_MASK,
|
||||
- VMX_INDEX_MSR_EFER,
|
||||
|
||||
VMX_MSR_COUNT
|
||||
};
|
||||
@@ -47,7 +46,6 @@ enum {
|
||||
struct vmx_msr_state {
|
||||
unsigned long flags;
|
||||
unsigned long msrs[VMX_MSR_COUNT];
|
||||
- unsigned long shadow_gs;
|
||||
};
|
||||
|
||||
struct arch_vmx_struct {
|
||||
@@ -76,7 +74,11 @@ struct arch_vmx_struct {
|
||||
unsigned long cpu_shadow_cr4; /* copy of guest read shadow CR4 */
|
||||
unsigned long cpu_cr2; /* save CR2 */
|
||||
unsigned long cpu_cr3;
|
||||
+#ifdef __x86_64__
|
||||
struct vmx_msr_state msr_state;
|
||||
+ unsigned long shadow_gs;
|
||||
+#endif
|
||||
+ unsigned long efer;
|
||||
unsigned long vmxassist_enabled:1;
|
||||
};
|
||||
|
||||
Index: 2007-05-14/xen/include/asm-x86/hvm/vmx/vmx.h
|
||||
===================================================================
|
||||
--- 2007-05-14.orig/xen/include/asm-x86/hvm/vmx/vmx.h 2007-04-23 10:01:46.000000000 +0200
|
||||
+++ 2007-05-14/xen/include/asm-x86/hvm/vmx/vmx.h 2007-05-14 14:28:19.000000000 +0200
|
||||
@@ -261,14 +261,12 @@ static inline int vmx_paging_enabled(str
|
||||
|
||||
static inline int vmx_long_mode_enabled(struct vcpu *v)
|
||||
{
|
||||
- u64 efer = v->arch.hvm_vmx.msr_state.msrs[VMX_INDEX_MSR_EFER];
|
||||
- return efer & EFER_LMA;
|
||||
+ return v->arch.hvm_vmx.efer & EFER_LMA;
|
||||
}
|
||||
|
||||
static inline int vmx_lme_is_set(struct vcpu *v)
|
||||
{
|
||||
- u64 efer = v->arch.hvm_vmx.msr_state.msrs[VMX_INDEX_MSR_EFER];
|
||||
- return efer & EFER_LME;
|
||||
+ return v->arch.hvm_vmx.efer & EFER_LME;
|
||||
}
|
||||
|
||||
static inline int vmx_pgbit_test(struct vcpu *v)
|
||||
Index: 2007-05-14/xen/include/asm-x86/msr.h
|
||||
===================================================================
|
||||
--- 2007-05-14.orig/xen/include/asm-x86/msr.h 2007-04-23 10:01:46.000000000 +0200
|
||||
+++ 2007-05-14/xen/include/asm-x86/msr.h 2007-05-14 14:28:19.000000000 +0200
|
||||
@@ -3,6 +3,9 @@
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
+#include <xen/smp.h>
|
||||
+#include <xen/percpu.h>
|
||||
+
|
||||
#define rdmsr(msr,val1,val2) \
|
||||
__asm__ __volatile__("rdmsr" \
|
||||
: "=a" (val1), "=d" (val2) \
|
||||
@@ -142,6 +145,25 @@ static inline void wrmsrl(unsigned int m
|
||||
#define EFER_NX (1<<_EFER_NX)
|
||||
#define EFER_SVME (1<<_EFER_SVME)
|
||||
|
||||
+#ifndef __ASSEMBLY__
|
||||
+
|
||||
+DECLARE_PER_CPU(__u64, efer);
|
||||
+
|
||||
+static inline __u64 read_efer(void)
|
||||
+{
|
||||
+ if (!this_cpu(efer))
|
||||
+ rdmsrl(MSR_EFER, this_cpu(efer));
|
||||
+ return this_cpu(efer);
|
||||
+}
|
||||
+
|
||||
+static inline void write_efer(__u64 val)
|
||||
+{
|
||||
+ this_cpu(efer) = val;
|
||||
+ wrmsrl(MSR_EFER, val);
|
||||
+}
|
||||
+
|
||||
+#endif
|
||||
+
|
||||
/* Intel MSRs. Some also available on other CPUs */
|
||||
#define MSR_IA32_PLATFORM_ID 0x17
|
||||
|
309
hvm-hypercall-context.patch
Normal file
309
hvm-hypercall-context.patch
Normal file
@ -0,0 +1,309 @@
|
||||
Index: 2007-05-14/xen/arch/x86/domain.c
|
||||
===================================================================
|
||||
--- 2007-05-14.orig/xen/arch/x86/domain.c 2007-05-14 13:43:44.000000000 +0200
|
||||
+++ 2007-05-14/xen/arch/x86/domain.c 2007-05-14 14:27:23.000000000 +0200
|
||||
@@ -38,6 +38,7 @@
|
||||
#include <asm/mpspec.h>
|
||||
#include <asm/ldt.h>
|
||||
#include <asm/paging.h>
|
||||
+#include <asm/hypercall.h>
|
||||
#include <asm/hvm/hvm.h>
|
||||
#include <asm/hvm/support.h>
|
||||
#include <asm/msr.h>
|
||||
@@ -1234,6 +1235,8 @@ void sync_vcpu_execstate(struct vcpu *v)
|
||||
__arg; \
|
||||
})
|
||||
|
||||
+DEFINE_PER_CPU(char, hc_preempted);
|
||||
+
|
||||
unsigned long hypercall_create_continuation(
|
||||
unsigned int op, const char *format, ...)
|
||||
{
|
||||
@@ -1265,7 +1268,9 @@ unsigned long hypercall_create_continuat
|
||||
regs->eip -= 2; /* re-execute 'syscall' / 'int 0x82' */
|
||||
|
||||
#ifdef __x86_64__
|
||||
- if ( !is_pv_32on64_domain(current->domain) )
|
||||
+ if ( !is_hvm_vcpu(current) ?
|
||||
+ !is_pv_32on64_vcpu(current) :
|
||||
+ hvm_guest_x86_mode(current) == 8 )
|
||||
{
|
||||
for ( i = 0; *p != '\0'; i++ )
|
||||
{
|
||||
@@ -1301,6 +1306,8 @@ unsigned long hypercall_create_continuat
|
||||
}
|
||||
}
|
||||
}
|
||||
+
|
||||
+ this_cpu(hc_preempted) = 1;
|
||||
}
|
||||
|
||||
va_end(args);
|
||||
Index: 2007-05-14/xen/arch/x86/hvm/hvm.c
|
||||
===================================================================
|
||||
--- 2007-05-14.orig/xen/arch/x86/hvm/hvm.c 2007-05-14 13:47:02.000000000 +0200
|
||||
+++ 2007-05-14/xen/arch/x86/hvm/hvm.c 2007-05-14 14:21:26.000000000 +0200
|
||||
@@ -663,7 +663,7 @@ typedef unsigned long hvm_hypercall_t(
|
||||
|
||||
#if defined(__i386__)
|
||||
|
||||
-static hvm_hypercall_t *hvm_hypercall_table[NR_hypercalls] = {
|
||||
+static hvm_hypercall_t *hvm_hypercall32_table[NR_hypercalls] = {
|
||||
HYPERCALL(memory_op),
|
||||
HYPERCALL(multicall),
|
||||
HYPERCALL(xen_version),
|
||||
@@ -672,21 +672,6 @@ static hvm_hypercall_t *hvm_hypercall_ta
|
||||
HYPERCALL(hvm_op)
|
||||
};
|
||||
|
||||
-static void __hvm_do_hypercall(struct cpu_user_regs *pregs)
|
||||
-{
|
||||
- if ( (pregs->eax >= NR_hypercalls) || !hvm_hypercall_table[pregs->eax] )
|
||||
- {
|
||||
- if ( pregs->eax != __HYPERVISOR_grant_table_op )
|
||||
- gdprintk(XENLOG_WARNING, "HVM vcpu %d:%d bad hypercall %d.\n",
|
||||
- current->domain->domain_id, current->vcpu_id, pregs->eax);
|
||||
- pregs->eax = -ENOSYS;
|
||||
- return;
|
||||
- }
|
||||
-
|
||||
- pregs->eax = hvm_hypercall_table[pregs->eax](
|
||||
- pregs->ebx, pregs->ecx, pregs->edx, pregs->esi, pregs->edi);
|
||||
-}
|
||||
-
|
||||
#else /* defined(__x86_64__) */
|
||||
|
||||
static long do_memory_op_compat32(int cmd, XEN_GUEST_HANDLE(void) arg)
|
||||
@@ -746,49 +731,38 @@ static hvm_hypercall_t *hvm_hypercall32_
|
||||
HYPERCALL(hvm_op)
|
||||
};
|
||||
|
||||
-static void __hvm_do_hypercall(struct cpu_user_regs *pregs)
|
||||
-{
|
||||
- pregs->rax = (uint32_t)pregs->eax; /* mask in case compat32 caller */
|
||||
- if ( (pregs->rax >= NR_hypercalls) || !hvm_hypercall64_table[pregs->rax] )
|
||||
- {
|
||||
- if ( pregs->rax != __HYPERVISOR_grant_table_op )
|
||||
- gdprintk(XENLOG_WARNING, "HVM vcpu %d:%d bad hypercall %ld.\n",
|
||||
- current->domain->domain_id, current->vcpu_id, pregs->rax);
|
||||
- pregs->rax = -ENOSYS;
|
||||
- return;
|
||||
- }
|
||||
-
|
||||
- if ( current->arch.paging.mode->guest_levels == 4 )
|
||||
- {
|
||||
- pregs->rax = hvm_hypercall64_table[pregs->rax](pregs->rdi,
|
||||
- pregs->rsi,
|
||||
- pregs->rdx,
|
||||
- pregs->r10,
|
||||
- pregs->r8);
|
||||
- }
|
||||
- else
|
||||
- {
|
||||
- pregs->eax = hvm_hypercall32_table[pregs->eax]((uint32_t)pregs->ebx,
|
||||
- (uint32_t)pregs->ecx,
|
||||
- (uint32_t)pregs->edx,
|
||||
- (uint32_t)pregs->esi,
|
||||
- (uint32_t)pregs->edi);
|
||||
- }
|
||||
-}
|
||||
-
|
||||
#endif /* defined(__x86_64__) */
|
||||
|
||||
int hvm_do_hypercall(struct cpu_user_regs *regs)
|
||||
{
|
||||
- int flush, preempted;
|
||||
- unsigned long old_eip;
|
||||
+ int flush, mode = hvm_guest_x86_mode(current);
|
||||
+ uint32_t eax = regs->eax;
|
||||
|
||||
- hvm_store_cpu_guest_regs(current, regs, NULL);
|
||||
+ switch ( mode )
|
||||
+ {
|
||||
+#ifdef __x86_64__
|
||||
+ case 8:
|
||||
+#endif
|
||||
+ case 4:
|
||||
+ case 2:
|
||||
+ hvm_store_cpu_guest_regs(current, regs, NULL);
|
||||
+ if ( unlikely(ring_3(regs)) )
|
||||
+ {
|
||||
+ default:
|
||||
+ regs->eax = -EPERM;
|
||||
+ return HVM_HCALL_completed;
|
||||
+ }
|
||||
+ case 0:
|
||||
+ break;
|
||||
+ }
|
||||
|
||||
- if ( unlikely(ring_3(regs)) )
|
||||
+ if ( (eax >= NR_hypercalls) || !hvm_hypercall32_table[eax] )
|
||||
{
|
||||
- regs->eax = -EPERM;
|
||||
- return 0;
|
||||
+ if ( eax != __HYPERVISOR_grant_table_op )
|
||||
+ gdprintk(XENLOG_WARNING, "HVM vcpu %d:%d bad hypercall %u.\n",
|
||||
+ current->domain->domain_id, current->vcpu_id, eax);
|
||||
+ regs->eax = -ENOSYS;
|
||||
+ return HVM_HCALL_completed;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -796,20 +770,29 @@ int hvm_do_hypercall(struct cpu_user_reg
|
||||
* For now we also need to flush when pages are added, as qemu-dm is not
|
||||
* yet capable of faulting pages into an existing valid mapcache bucket.
|
||||
*/
|
||||
- flush = ((uint32_t)regs->eax == __HYPERVISOR_memory_op);
|
||||
-
|
||||
- /* Check for preemption: RIP will be modified from this dummy value. */
|
||||
- old_eip = regs->eip;
|
||||
- regs->eip = 0xF0F0F0FF;
|
||||
-
|
||||
- __hvm_do_hypercall(regs);
|
||||
+ flush = (eax == __HYPERVISOR_memory_op);
|
||||
+ this_cpu(hc_preempted) = 0;
|
||||
|
||||
- preempted = (regs->eip != 0xF0F0F0FF);
|
||||
- regs->eip = old_eip;
|
||||
-
|
||||
- hvm_load_cpu_guest_regs(current, regs);
|
||||
+#ifdef __x86_64__
|
||||
+ if ( mode == 8 )
|
||||
+ {
|
||||
+ regs->rax = hvm_hypercall64_table[eax](regs->rdi,
|
||||
+ regs->rsi,
|
||||
+ regs->rdx,
|
||||
+ regs->r10,
|
||||
+ regs->r8);
|
||||
+ }
|
||||
+ else
|
||||
+#endif
|
||||
+ {
|
||||
+ regs->eax = hvm_hypercall32_table[eax]((uint32_t)regs->ebx,
|
||||
+ (uint32_t)regs->ecx,
|
||||
+ (uint32_t)regs->edx,
|
||||
+ (uint32_t)regs->esi,
|
||||
+ (uint32_t)regs->edi);
|
||||
+ }
|
||||
|
||||
- return (preempted ? HVM_HCALL_preempted :
|
||||
+ return (this_cpu(hc_preempted) ? HVM_HCALL_preempted :
|
||||
flush ? HVM_HCALL_invalidate : HVM_HCALL_completed);
|
||||
}
|
||||
|
||||
Index: 2007-05-14/xen/arch/x86/hvm/platform.c
|
||||
===================================================================
|
||||
--- 2007-05-14.orig/xen/arch/x86/hvm/platform.c 2007-04-23 10:01:41.000000000 +0200
|
||||
+++ 2007-05-14/xen/arch/x86/hvm/platform.c 2007-05-14 13:47:25.000000000 +0200
|
||||
@@ -1037,6 +1037,9 @@ void handle_mmio(unsigned long gpa)
|
||||
df = regs->eflags & X86_EFLAGS_DF ? 1 : 0;
|
||||
|
||||
address_bytes = hvm_guest_x86_mode(v);
|
||||
+ if (address_bytes < 2)
|
||||
+ /* real or vm86 modes */
|
||||
+ address_bytes = 2;
|
||||
inst_addr = hvm_get_segment_base(v, x86_seg_cs) + regs->eip;
|
||||
inst_len = hvm_instruction_length(inst_addr, address_bytes);
|
||||
if ( inst_len <= 0 )
|
||||
Index: 2007-05-14/xen/arch/x86/hvm/svm/svm.c
|
||||
===================================================================
|
||||
--- 2007-05-14.orig/xen/arch/x86/hvm/svm/svm.c 2007-05-03 09:45:09.000000000 +0200
|
||||
+++ 2007-05-14/xen/arch/x86/hvm/svm/svm.c 2007-05-14 13:47:25.000000000 +0200
|
||||
@@ -563,14 +563,6 @@ static inline void svm_restore_dr(struct
|
||||
}
|
||||
|
||||
|
||||
-static int svm_realmode(struct vcpu *v)
|
||||
-{
|
||||
- unsigned long cr0 = v->arch.hvm_svm.cpu_shadow_cr0;
|
||||
- unsigned long eflags = v->arch.hvm_svm.vmcb->rflags;
|
||||
-
|
||||
- return (eflags & X86_EFLAGS_VM) || !(cr0 & X86_CR0_PE);
|
||||
-}
|
||||
-
|
||||
static int svm_interrupts_enabled(struct vcpu *v)
|
||||
{
|
||||
unsigned long eflags = v->arch.hvm_svm.vmcb->rflags;
|
||||
@@ -581,13 +573,13 @@ static int svm_guest_x86_mode(struct vcp
|
||||
{
|
||||
struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
|
||||
|
||||
- if ( svm_long_mode_enabled(v) && vmcb->cs.attr.fields.l )
|
||||
+ if ( unlikely(!(v->arch.hvm_svm.cpu_shadow_cr0 & X86_CR0_PE)) )
|
||||
+ return 0;
|
||||
+ if ( unlikely(vmcb->rflags & X86_EFLAGS_VM) )
|
||||
+ return 1;
|
||||
+ if ( svm_long_mode_enabled(v) && likely(vmcb->cs.attr.fields.l) )
|
||||
return 8;
|
||||
-
|
||||
- if ( svm_realmode(v) )
|
||||
- return 2;
|
||||
-
|
||||
- return (vmcb->cs.attr.fields.db ? 4 : 2);
|
||||
+ return (likely(vmcb->cs.attr.fields.db) ? 4 : 2);
|
||||
}
|
||||
|
||||
void svm_update_host_cr3(struct vcpu *v)
|
||||
Index: 2007-05-14/xen/arch/x86/hvm/vmx/vmx.c
|
||||
===================================================================
|
||||
--- 2007-05-14.orig/xen/arch/x86/hvm/vmx/vmx.c 2007-05-03 09:45:09.000000000 +0200
|
||||
+++ 2007-05-14/xen/arch/x86/hvm/vmx/vmx.c 2007-05-14 13:47:25.000000000 +0200
|
||||
@@ -995,31 +995,20 @@ static void vmx_init_hypercall_page(stru
|
||||
*(u16 *)(hypercall_page + (__HYPERVISOR_iret * 32)) = 0x0b0f; /* ud2 */
|
||||
}
|
||||
|
||||
-static int vmx_realmode(struct vcpu *v)
|
||||
-{
|
||||
- unsigned long rflags;
|
||||
-
|
||||
- ASSERT(v == current);
|
||||
-
|
||||
- rflags = __vmread(GUEST_RFLAGS);
|
||||
- return rflags & X86_EFLAGS_VM;
|
||||
-}
|
||||
-
|
||||
static int vmx_guest_x86_mode(struct vcpu *v)
|
||||
{
|
||||
- unsigned long cs_ar_bytes;
|
||||
+ unsigned int cs_ar_bytes;
|
||||
|
||||
ASSERT(v == current);
|
||||
|
||||
+ if ( unlikely(!(v->arch.hvm_vmx.cpu_shadow_cr0 & X86_CR0_PE)) )
|
||||
+ return 0;
|
||||
+ if ( unlikely(__vmread(GUEST_RFLAGS) & X86_EFLAGS_VM) )
|
||||
+ return 1;
|
||||
cs_ar_bytes = __vmread(GUEST_CS_AR_BYTES);
|
||||
-
|
||||
- if ( vmx_long_mode_enabled(v) && (cs_ar_bytes & (1u<<13)) )
|
||||
+ if ( vmx_long_mode_enabled(v) && likely(cs_ar_bytes & (1u<<13)) )
|
||||
return 8;
|
||||
-
|
||||
- if ( vmx_realmode(v) )
|
||||
- return 2;
|
||||
-
|
||||
- return ((cs_ar_bytes & (1u<<14)) ? 4 : 2);
|
||||
+ return (likely(cs_ar_bytes & (1u<<14)) ? 4 : 2);
|
||||
}
|
||||
|
||||
static int vmx_pae_enabled(struct vcpu *v)
|
||||
Index: 2007-05-14/xen/include/asm-x86/hypercall.h
|
||||
===================================================================
|
||||
--- 2007-05-14.orig/xen/include/asm-x86/hypercall.h 2007-04-23 10:01:46.000000000 +0200
|
||||
+++ 2007-05-14/xen/include/asm-x86/hypercall.h 2007-05-14 14:26:36.000000000 +0200
|
||||
@@ -15,6 +15,15 @@
|
||||
*/
|
||||
#define MMU_UPDATE_PREEMPTED (~(~0U>>1))
|
||||
|
||||
+/*
|
||||
+ * This gets set to a non-zero value whenever hypercall_create_continuation()
|
||||
+ * is used (outside of multicall context; in multicall context the second call
|
||||
+ * from do_multicall() itself will have this effect). Internal callers of
|
||||
+ * hypercall handlers interested in this condition must clear the flag prior
|
||||
+ * to invoking the respective handler(s).
|
||||
+ */
|
||||
+DECLARE_PER_CPU(char, hc_preempted);
|
||||
+
|
||||
extern long
|
||||
do_event_channel_op_compat(
|
||||
XEN_GUEST_HANDLE(evtchn_op_t) uop);
|
58
hvm-hypercall-debug.patch
Normal file
58
hvm-hypercall-debug.patch
Normal file
@ -0,0 +1,58 @@
|
||||
Index: 2007-05-14/xen/arch/x86/hvm/hvm.c
|
||||
===================================================================
|
||||
--- 2007-05-14.orig/xen/arch/x86/hvm/hvm.c 2007-05-14 14:21:26.000000000 +0200
|
||||
+++ 2007-05-14/xen/arch/x86/hvm/hvm.c 2007-05-14 14:32:48.000000000 +0200
|
||||
@@ -776,6 +776,9 @@ int hvm_do_hypercall(struct cpu_user_reg
|
||||
#ifdef __x86_64__
|
||||
if ( mode == 8 )
|
||||
{
|
||||
+ HVM_DBG_LOG(DBG_LEVEL_HCALL, "hcall%u(%lx, %lx, %lx, %lx, %lx)", eax,
|
||||
+ regs->rdi, regs->rsi, regs->rdx, regs->r10, regs->r8);
|
||||
+
|
||||
regs->rax = hvm_hypercall64_table[eax](regs->rdi,
|
||||
regs->rsi,
|
||||
regs->rdx,
|
||||
@@ -785,6 +788,11 @@ int hvm_do_hypercall(struct cpu_user_reg
|
||||
else
|
||||
#endif
|
||||
{
|
||||
+ HVM_DBG_LOG(DBG_LEVEL_HCALL, "hcall%u(%x, %x, %x, %x, %x)", eax,
|
||||
+ (uint32_t)regs->ebx, (uint32_t)regs->ecx,
|
||||
+ (uint32_t)regs->edx, (uint32_t)regs->esi,
|
||||
+ (uint32_t)regs->edi);
|
||||
+
|
||||
regs->eax = hvm_hypercall32_table[eax]((uint32_t)regs->ebx,
|
||||
(uint32_t)regs->ecx,
|
||||
(uint32_t)regs->edx,
|
||||
@@ -792,6 +800,8 @@ int hvm_do_hypercall(struct cpu_user_reg
|
||||
(uint32_t)regs->edi);
|
||||
}
|
||||
|
||||
+ HVM_DBG_LOG(DBG_LEVEL_HCALL, "hcall%u -> %lx", eax, (unsigned long)regs->eax);
|
||||
+
|
||||
return (this_cpu(hc_preempted) ? HVM_HCALL_preempted :
|
||||
flush ? HVM_HCALL_invalidate : HVM_HCALL_completed);
|
||||
}
|
||||
@@ -1056,6 +1066,10 @@ long do_hvm_op(unsigned long op, XEN_GUE
|
||||
rc = copy_to_guest(arg, &a, 1) ? -EFAULT : 0;
|
||||
}
|
||||
|
||||
+ HVM_DBG_LOG(DBG_LEVEL_HCALL, "%s param %u = %"PRIx64,
|
||||
+ op == HVMOP_set_param ? "set" : "get",
|
||||
+ a.index, a.value);
|
||||
+
|
||||
param_fail:
|
||||
rcu_unlock_domain(d);
|
||||
break;
|
||||
Index: 2007-05-14/xen/include/asm-x86/hvm/support.h
|
||||
===================================================================
|
||||
--- 2007-05-14.orig/xen/include/asm-x86/hvm/support.h 2007-04-23 10:01:46.000000000 +0200
|
||||
+++ 2007-05-14/xen/include/asm-x86/hvm/support.h 2007-05-14 14:31:44.000000000 +0200
|
||||
@@ -62,6 +62,7 @@ static inline vcpu_iodata_t *get_ioreq(s
|
||||
#define DBG_LEVEL_VLAPIC_TIMER (1 << 7)
|
||||
#define DBG_LEVEL_VLAPIC_INTERRUPT (1 << 8)
|
||||
#define DBG_LEVEL_IOAPIC (1 << 9)
|
||||
+#define DBG_LEVEL_HCALL (1 << 10)
|
||||
|
||||
extern unsigned int opt_hvm_debug_level;
|
||||
#define HVM_DBG_LOG(level, _f, _a...) \
|
37
hvm-pio-read.patch
Normal file
37
hvm-pio-read.patch
Normal file
@ -0,0 +1,37 @@
|
||||
Index: 2007-04-27/xen/arch/x86/hvm/io.c
|
||||
===================================================================
|
||||
--- 2007-04-27.orig/xen/arch/x86/hvm/io.c 2007-04-16 09:26:34.000000000 +0200
|
||||
+++ 2007-04-27/xen/arch/x86/hvm/io.c 2007-05-09 18:00:08.000000000 +0200
|
||||
@@ -418,11 +418,10 @@ static inline void set_eflags_PF(int siz
|
||||
static void hvm_pio_assist(struct cpu_user_regs *regs, ioreq_t *p,
|
||||
struct hvm_io_op *pio_opp)
|
||||
{
|
||||
- unsigned long old_eax;
|
||||
- int sign = p->df ? -1 : 1;
|
||||
-
|
||||
if ( p->data_is_ptr || (pio_opp->flags & OVERLAP) )
|
||||
{
|
||||
+ int sign = p->df ? -1 : 1;
|
||||
+
|
||||
if ( pio_opp->flags & REPZ )
|
||||
regs->ecx -= p->count;
|
||||
|
||||
@@ -459,14 +458,15 @@ static void hvm_pio_assist(struct cpu_us
|
||||
}
|
||||
else if ( p->dir == IOREQ_READ )
|
||||
{
|
||||
- old_eax = regs->eax;
|
||||
+ unsigned long old_eax = regs->eax;
|
||||
+
|
||||
switch ( p->size )
|
||||
{
|
||||
case 1:
|
||||
- regs->eax = (old_eax & 0xffffff00) | (p->data & 0xff);
|
||||
+ regs->eax = (old_eax & ~0xff) | (p->data & 0xff);
|
||||
break;
|
||||
case 2:
|
||||
- regs->eax = (old_eax & 0xffff0000) | (p->data & 0xffff);
|
||||
+ regs->eax = (old_eax & ~0xffff) | (p->data & 0xffff);
|
||||
break;
|
||||
case 4:
|
||||
regs->eax = (p->data & 0xffffffff);
|
34
hvm-shared-info-size.patch
Normal file
34
hvm-shared-info-size.patch
Normal file
@ -0,0 +1,34 @@
|
||||
Index: 2007-05-14/xen/arch/x86/hvm/hvm.c
|
||||
===================================================================
|
||||
--- 2007-05-14.orig/xen/arch/x86/hvm/hvm.c 2007-05-14 08:28:38.000000000 +0200
|
||||
+++ 2007-05-14/xen/arch/x86/hvm/hvm.c 2007-05-14 13:47:02.000000000 +0200
|
||||
@@ -824,6 +824,15 @@ void hvm_update_guest_cr3(struct vcpu *v
|
||||
void hvm_hypercall_page_initialise(struct domain *d,
|
||||
void *hypercall_page)
|
||||
{
|
||||
+#ifdef __x86_64__
|
||||
+ /*
|
||||
+ * Since this operation is one of the very first executed by PV drivers
|
||||
+ * on initialisation or after save/restore, it is a sensible point at
|
||||
+ * which to sample the execution mode of the guest and latch 32- or 64-
|
||||
+ * bit format for shared state.
|
||||
+ */
|
||||
+ d->arch.has_32bit_shinfo = (hvm_guest_x86_mode(current) != 8);
|
||||
+#endif
|
||||
hvm_funcs.init_hypercall_page(d, hypercall_page);
|
||||
}
|
||||
|
||||
@@ -1053,13 +1062,6 @@ long do_hvm_op(unsigned long op, XEN_GUE
|
||||
break;
|
||||
case HVM_PARAM_CALLBACK_IRQ:
|
||||
hvm_set_callback_via(d, a.value);
|
||||
- /*
|
||||
- * Since this operation is one of the very first executed
|
||||
- * by PV drivers on initialisation or after save/restore, it
|
||||
- * is a sensible point at which to sample the execution mode of
|
||||
- * the guest and latch 32- or 64-bit format for shared state.
|
||||
- */
|
||||
- d->arch.has_32bit_shinfo = (hvm_guest_x86_mode(current) != 8);
|
||||
break;
|
||||
}
|
||||
d->arch.hvm_domain.params[a.index] = a.value;
|
40
intpte_t-cast.patch
Normal file
40
intpte_t-cast.patch
Normal file
@ -0,0 +1,40 @@
|
||||
Index: 2007-05-14/xen/arch/x86/mm.c
|
||||
===================================================================
|
||||
--- 2007-05-14.orig/xen/arch/x86/mm.c 2007-05-14 08:40:14.000000000 +0200
|
||||
+++ 2007-05-14/xen/arch/x86/mm.c 2007-05-14 08:40:20.000000000 +0200
|
||||
@@ -1017,7 +1017,7 @@ static void pae_flush_pgd(
|
||||
l3tab_ptr = &cache->table[cache->inuse_idx][idx];
|
||||
_ol3e = l3e_get_intpte(*l3tab_ptr);
|
||||
_nl3e = l3e_get_intpte(nl3e);
|
||||
- _pl3e = cmpxchg((intpte_t *)l3tab_ptr, _ol3e, _nl3e);
|
||||
+ _pl3e = cmpxchg(&l3e_get_intpte(*l3tab_ptr), _ol3e, _nl3e);
|
||||
BUG_ON(_pl3e != _ol3e);
|
||||
}
|
||||
|
||||
@@ -1316,7 +1316,7 @@ static inline int update_intpte(intpte_t
|
||||
/* Macro that wraps the appropriate type-changes around update_intpte().
|
||||
* Arguments are: type, ptr, old, new, mfn, vcpu */
|
||||
#define UPDATE_ENTRY(_t,_p,_o,_n,_m,_v) \
|
||||
- update_intpte((intpte_t *)(_p), \
|
||||
+ update_intpte(&_t ## e_get_intpte(*(_p)), \
|
||||
_t ## e_get_intpte(_o), _t ## e_get_intpte(_n), \
|
||||
(_m), (_v))
|
||||
|
||||
@@ -2498,7 +2498,7 @@ static int create_grant_pte_mapping(
|
||||
}
|
||||
|
||||
ol1e = *(l1_pgentry_t *)va;
|
||||
- if ( !UPDATE_ENTRY(l1, va, ol1e, nl1e, mfn, v) )
|
||||
+ if ( !UPDATE_ENTRY(l1, (l1_pgentry_t *)va, ol1e, nl1e, mfn, v) )
|
||||
{
|
||||
put_page_type(page);
|
||||
rc = GNTST_general_error;
|
||||
@@ -3278,7 +3278,7 @@ static int ptwr_emulated_update(
|
||||
intpte_t t = old;
|
||||
ol1e = l1e_from_intpte(old);
|
||||
|
||||
- okay = paging_cmpxchg_guest_entry(v, (intpte_t *) pl1e,
|
||||
+ okay = paging_cmpxchg_guest_entry(v, &l1e_get_intpte(*pl1e),
|
||||
&t, val, _mfn(mfn));
|
||||
okay = (okay && t == old);
|
||||
|
25
inval-sh-ldt.patch
Normal file
25
inval-sh-ldt.patch
Normal file
@ -0,0 +1,25 @@
|
||||
Index: 2007-04-27/xen/arch/x86/mm.c
|
||||
===================================================================
|
||||
--- 2007-04-27.orig/xen/arch/x86/mm.c 2007-04-27 08:27:18.000000000 +0200
|
||||
+++ 2007-04-27/xen/arch/x86/mm.c 2007-04-27 09:30:37.000000000 +0200
|
||||
@@ -410,7 +410,7 @@ void update_cr3(struct vcpu *v)
|
||||
}
|
||||
|
||||
|
||||
-void invalidate_shadow_ldt(struct vcpu *v)
|
||||
+static void invalidate_shadow_ldt(struct vcpu *v)
|
||||
{
|
||||
int i;
|
||||
unsigned long pfn;
|
||||
Index: 2007-04-27/xen/include/asm-x86/mm.h
|
||||
===================================================================
|
||||
--- 2007-04-27.orig/xen/include/asm-x86/mm.h 2007-04-02 12:16:27.000000000 +0200
|
||||
+++ 2007-04-27/xen/include/asm-x86/mm.h 2007-04-27 09:30:37.000000000 +0200
|
||||
@@ -143,7 +143,6 @@ void init_frametable(void);
|
||||
|
||||
int alloc_page_type(struct page_info *page, unsigned long type);
|
||||
void free_page_type(struct page_info *page, unsigned long type);
|
||||
-void invalidate_shadow_ldt(struct vcpu *d);
|
||||
int _shadow_mode_refcounts(struct domain *d);
|
||||
|
||||
static inline void put_page(struct page_info *page)
|
29
kill-sh_mapcache.patch
Normal file
29
kill-sh_mapcache.patch
Normal file
@ -0,0 +1,29 @@
|
||||
Index: 2007-05-14/xen/arch/x86/mm.c
|
||||
===================================================================
|
||||
--- 2007-05-14.orig/xen/arch/x86/mm.c 2007-05-14 08:39:16.000000000 +0200
|
||||
+++ 2007-05-14/xen/arch/x86/mm.c 2007-05-14 08:40:14.000000000 +0200
|
||||
@@ -2261,7 +2261,7 @@ int do_mmu_update(
|
||||
struct vcpu *v = current;
|
||||
struct domain *d = v->domain;
|
||||
unsigned long type_info;
|
||||
- struct domain_mmap_cache mapcache, sh_mapcache;
|
||||
+ struct domain_mmap_cache mapcache;
|
||||
|
||||
if ( unlikely(count & MMU_UPDATE_PREEMPTED) )
|
||||
{
|
||||
@@ -2285,7 +2285,6 @@ int do_mmu_update(
|
||||
}
|
||||
|
||||
domain_mmap_cache_init(&mapcache);
|
||||
- domain_mmap_cache_init(&sh_mapcache);
|
||||
|
||||
LOCK_BIGLOCK(d);
|
||||
|
||||
@@ -2447,7 +2446,6 @@ int do_mmu_update(
|
||||
UNLOCK_BIGLOCK(d);
|
||||
|
||||
domain_mmap_cache_destroy(&mapcache);
|
||||
- domain_mmap_cache_destroy(&sh_mapcache);
|
||||
|
||||
perfc_add(num_page_updates, i);
|
||||
|
561
page-cacheability.patch
Normal file
561
page-cacheability.patch
Normal file
@ -0,0 +1,561 @@
|
||||
Index: 2007-05-14/xen/arch/x86/mm.c
|
||||
===================================================================
|
||||
--- 2007-05-14.orig/xen/arch/x86/mm.c 2007-05-14 14:33:33.000000000 +0200
|
||||
+++ 2007-05-14/xen/arch/x86/mm.c 2007-05-14 14:35:02.000000000 +0200
|
||||
@@ -147,6 +147,14 @@ struct page_info *frame_table;
|
||||
unsigned long max_page;
|
||||
unsigned long total_pages;
|
||||
|
||||
+#define PAGE_CACHE_ATTRS (_PAGE_PAT|_PAGE_PCD|_PAGE_PWT)
|
||||
+
|
||||
+#define l1_disallow_mask(d) (!(d)->iomem_caps || \
|
||||
+ !rangeset_is_empty((d)->iomem_caps) || \
|
||||
+ !rangeset_is_empty((d)->arch.ioport_caps) ? \
|
||||
+ L1_DISALLOW_MASK : \
|
||||
+ L1_DISALLOW_MASK|PAGE_CACHE_ATTRS)
|
||||
+
|
||||
#ifdef CONFIG_COMPAT
|
||||
l2_pgentry_t *compat_idle_pg_table_l2 = NULL;
|
||||
#define l3_disallow_mask(d) (!is_pv_32on64_domain(d) ? \
|
||||
@@ -265,9 +273,10 @@ void share_xen_page_with_guest(
|
||||
|
||||
spin_lock(&d->page_alloc_lock);
|
||||
|
||||
- /* The incremented type count pins as writable or read-only. */
|
||||
page->u.inuse.type_info = (readonly ? PGT_none : PGT_writable_page);
|
||||
- page->u.inuse.type_info |= PGT_validated | 1;
|
||||
+ if ( readonly || d != dom_io )
|
||||
+ /* The incremented type count pins as writable or read-only. */
|
||||
+ page->u.inuse.type_info |= PGT_validated | 1;
|
||||
|
||||
page_set_owner(page, d);
|
||||
wmb(); /* install valid domain ptr before updating refcnt. */
|
||||
@@ -526,6 +535,74 @@ static int get_page_and_type_from_pagenr
|
||||
return 1;
|
||||
}
|
||||
|
||||
+static unsigned long get_writable_type(unsigned int flags)
|
||||
+{
|
||||
+ unsigned long type = PGT_none;
|
||||
+
|
||||
+ if ( flags & _PAGE_RW )
|
||||
+ type = PGT_writable_page;
|
||||
+ if ( flags & _PAGE_PWT )
|
||||
+ type |= PGT_pwt_mask | PGT_writable_page;
|
||||
+ if ( flags & _PAGE_PCD )
|
||||
+ type |= PGT_pcd_mask | PGT_writable_page;
|
||||
+#ifdef CONFIG_PAT
|
||||
+ if ( flags & _PAGE_PAT )
|
||||
+ type |= PGT_pat_mask | PGT_writable_page;
|
||||
+#endif
|
||||
+ BUG_ON(!(type & PGT_writable_page));
|
||||
+
|
||||
+ return type;
|
||||
+}
|
||||
+
|
||||
+static int alloc_writable_page(struct page_info *page, unsigned long type)
|
||||
+{
|
||||
+ unsigned long mfn = page_to_mfn(page);
|
||||
+ unsigned int flags = 0;
|
||||
+ int ret;
|
||||
+
|
||||
+ if ( page_get_owner(page) == dom_io )
|
||||
+ return 1;
|
||||
+#ifdef __i386__
|
||||
+ if ( mfn >= ((DIRECTMAP_VIRT_END - DIRECTMAP_VIRT_START) >> PAGE_SHIFT) )
|
||||
+ return 1;
|
||||
+#endif
|
||||
+
|
||||
+ if ( type & PGT_pwt_mask )
|
||||
+ flags |= _PAGE_PWT;
|
||||
+ if ( type & PGT_pcd_mask )
|
||||
+ flags |= _PAGE_PCD;
|
||||
+#ifdef CONFIG_PAT
|
||||
+ if ( type & PGT_pat_mask )
|
||||
+ flags |= _PAGE_PAT;
|
||||
+#endif
|
||||
+ ret = map_pages_to_xen((unsigned long)mfn_to_virt(mfn), mfn, 1,
|
||||
+ PAGE_HYPERVISOR | flags);
|
||||
+ if ( ret == 0 )
|
||||
+ return 1;
|
||||
+
|
||||
+ MEM_LOG("Error %d changing cacheability of mfn %lx", ret, mfn);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static void free_writable_page(struct page_info *page)
|
||||
+{
|
||||
+ unsigned long mfn = page_to_mfn(page);
|
||||
+
|
||||
+ if ( page_get_owner(page) == dom_io )
|
||||
+ return;
|
||||
+#ifdef __i386__
|
||||
+ if ( mfn >= ((DIRECTMAP_VIRT_END - DIRECTMAP_VIRT_START) >> PAGE_SHIFT) )
|
||||
+ return;
|
||||
+#endif
|
||||
+
|
||||
+ if ( map_pages_to_xen((unsigned long)mfn_to_virt(mfn), mfn, 1,
|
||||
+ PAGE_HYPERVISOR) )
|
||||
+ {
|
||||
+ printk("Reverting cacheability for %lx failed\n", mfn);
|
||||
+ BUG();
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
/*
|
||||
* We allow root tables to map each other (a.k.a. linear page tables). It
|
||||
* needs some special care with reference counts and access permissions:
|
||||
@@ -586,15 +663,16 @@ get_page_from_l1e(
|
||||
l1_pgentry_t l1e, struct domain *d)
|
||||
{
|
||||
unsigned long mfn = l1e_get_pfn(l1e);
|
||||
+ unsigned int flags = l1e_get_flags(l1e);
|
||||
struct page_info *page = mfn_to_page(mfn);
|
||||
int okay;
|
||||
|
||||
- if ( !(l1e_get_flags(l1e) & _PAGE_PRESENT) )
|
||||
+ if ( !(flags & _PAGE_PRESENT) )
|
||||
return 1;
|
||||
|
||||
- if ( unlikely(l1e_get_flags(l1e) & L1_DISALLOW_MASK) )
|
||||
+ if ( unlikely(flags & l1_disallow_mask(d)) )
|
||||
{
|
||||
- MEM_LOG("Bad L1 flags %x", l1e_get_flags(l1e) & L1_DISALLOW_MASK);
|
||||
+ MEM_LOG("Bad L1 flags %x", flags & l1_disallow_mask(d));
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -624,9 +702,9 @@ get_page_from_l1e(
|
||||
* contribute to writeable mapping refcounts. (This allows the
|
||||
* qemu-dm helper process in dom0 to map the domain's memory without
|
||||
* messing up the count of "real" writable mappings.) */
|
||||
- okay = (((l1e_get_flags(l1e) & _PAGE_RW) &&
|
||||
+ okay = (((flags & (_PAGE_RW|PAGE_CACHE_ATTRS)) &&
|
||||
!(unlikely(paging_mode_external(d) && (d != current->domain))))
|
||||
- ? get_page_and_type(page, d, PGT_writable_page)
|
||||
+ ? get_page_and_type(page, d, get_writable_type(flags))
|
||||
: get_page(page, d));
|
||||
if ( !okay )
|
||||
{
|
||||
@@ -819,7 +897,7 @@ void put_page_from_l1e(l1_pgentry_t l1e,
|
||||
|
||||
/* Remember we didn't take a type-count of foreign writable mappings
|
||||
* to paging-external domains */
|
||||
- if ( (l1e_get_flags(l1e) & _PAGE_RW) &&
|
||||
+ if ( (l1e_get_flags(l1e) & (_PAGE_RW|PAGE_CACHE_ATTRS)) &&
|
||||
!(unlikely((e != d) && paging_mode_external(e))) )
|
||||
{
|
||||
put_page_and_type(page);
|
||||
@@ -1320,6 +1398,60 @@ static inline int update_intpte(intpte_t
|
||||
_t ## e_get_intpte(_o), _t ## e_get_intpte(_n), \
|
||||
(_m), (_v))
|
||||
|
||||
+/*
|
||||
+ * Present->present transitions referencing the same page with old and new
|
||||
+ * attributes resulting in (different) PGT_writable_page types and with the
|
||||
+ * type use count being 1 must be special cased, as the transition would
|
||||
+ * otherwise fail.
|
||||
+ */
|
||||
+static int transition_writable_page(l1_pgentry_t *pl1e, l1_pgentry_t ol1e,
|
||||
+ l1_pgentry_t nl1e, unsigned long gl1mfn,
|
||||
+ int do_cmpxchg)
|
||||
+{
|
||||
+ struct page_info *page = l1e_get_page(nl1e);
|
||||
+ unsigned long type = get_writable_type(l1e_get_flags(ol1e));
|
||||
+ unsigned long nx = type | 2;
|
||||
+ unsigned long x = type | PGT_validated | 1;
|
||||
+
|
||||
+ if ( cmpxchg(&page->u.inuse.type_info, x, nx) == x )
|
||||
+ {
|
||||
+ /*
|
||||
+ * The adjustment is now safe because the refcnt is 2 and validated
|
||||
+ * bit is clear => non-free ops will spin or fail, and a racing free
|
||||
+ * is illegal (will crash domain below).
|
||||
+ */
|
||||
+ type = get_writable_type(l1e_get_flags(nl1e));
|
||||
+ if ( alloc_writable_page(page, type) )
|
||||
+ {
|
||||
+ x = nx;
|
||||
+ nx = type | PGT_validated | 1;
|
||||
+ if ( cmpxchg(&page->u.inuse.type_info, x, nx) == x )
|
||||
+ {
|
||||
+ if ( do_cmpxchg )
|
||||
+ {
|
||||
+ intpte_t t = l1e_get_intpte(ol1e);
|
||||
+
|
||||
+ if ( paging_cmpxchg_guest_entry(current,
|
||||
+ &l1e_get_intpte(*pl1e),
|
||||
+ &t,
|
||||
+ l1e_get_intpte(nl1e),
|
||||
+ _mfn(gl1mfn)) )
|
||||
+ return t == l1e_get_intpte(ol1e);
|
||||
+ }
|
||||
+ else if ( UPDATE_ENTRY(l1, pl1e, ol1e, nl1e, gl1mfn, current) )
|
||||
+ return 1;
|
||||
+ }
|
||||
+ domain_crash(current->domain);
|
||||
+ return 0;
|
||||
+ }
|
||||
+ page->u.inuse.type_info |= PGT_validated;
|
||||
+ /* Drop the extra reference. */
|
||||
+ put_page_type(page);
|
||||
+ }
|
||||
+
|
||||
+ return -1;
|
||||
+}
|
||||
+
|
||||
/* Update the L1 entry at pl1e to new value nl1e. */
|
||||
static int mod_l1_entry(l1_pgentry_t *pl1e, l1_pgentry_t nl1e,
|
||||
unsigned long gl1mfn)
|
||||
@@ -1339,19 +1471,31 @@ static int mod_l1_entry(l1_pgentry_t *pl
|
||||
nl1e = l1e_from_pfn(gmfn_to_mfn(FOREIGNDOM, l1e_get_pfn(nl1e)),
|
||||
l1e_get_flags(nl1e));
|
||||
|
||||
- if ( unlikely(l1e_get_flags(nl1e) & L1_DISALLOW_MASK) )
|
||||
+ if ( unlikely(l1e_get_flags(nl1e) & l1_disallow_mask(d)) )
|
||||
{
|
||||
MEM_LOG("Bad L1 flags %x",
|
||||
- l1e_get_flags(nl1e) & L1_DISALLOW_MASK);
|
||||
+ l1e_get_flags(nl1e) & l1_disallow_mask(d));
|
||||
return 0;
|
||||
}
|
||||
|
||||
adjust_guest_l1e(nl1e, d);
|
||||
|
||||
- /* Fast path for identical mapping, r/w and presence. */
|
||||
- if ( !l1e_has_changed(ol1e, nl1e, _PAGE_RW | _PAGE_PRESENT) )
|
||||
+ /* Fast path for identical mapping, r/w, cacheability, and presence. */
|
||||
+ if ( !l1e_has_changed(ol1e, nl1e,
|
||||
+ _PAGE_RW | _PAGE_PRESENT | PAGE_CACHE_ATTRS) )
|
||||
return UPDATE_ENTRY(l1, pl1e, ol1e, nl1e, gl1mfn, current);
|
||||
|
||||
+ if ( !l1e_has_changed(ol1e, nl1e, _PAGE_PRESENT) &&
|
||||
+ (l1e_get_flags(ol1e) & (_PAGE_RW | PAGE_CACHE_ATTRS)) &&
|
||||
+ (l1e_get_flags(nl1e) & (_PAGE_RW | PAGE_CACHE_ATTRS)) &&
|
||||
+ mfn_valid(l1e_get_pfn(nl1e)) )
|
||||
+ {
|
||||
+ int ret = transition_writable_page(pl1e, ol1e, nl1e, gl1mfn, 0);
|
||||
+
|
||||
+ if ( ret >= 0 )
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
if ( unlikely(!get_page_from_l1e(nl1e, FOREIGNDOM)) )
|
||||
return 0;
|
||||
|
||||
@@ -1546,10 +1690,13 @@ static int mod_l4_entry(struct domain *d
|
||||
|
||||
#endif
|
||||
|
||||
-int alloc_page_type(struct page_info *page, unsigned long type)
|
||||
+static int alloc_page_type(struct page_info *page, unsigned long type)
|
||||
{
|
||||
struct domain *owner = page_get_owner(page);
|
||||
|
||||
+ if ( type & PGT_writable_page )
|
||||
+ return alloc_writable_page(page, type);
|
||||
+
|
||||
/* A page table is dirtied when its type count becomes non-zero. */
|
||||
if ( likely(owner != NULL) )
|
||||
mark_dirty(owner, page_to_mfn(page));
|
||||
@@ -1583,6 +1730,12 @@ void free_page_type(struct page_info *pa
|
||||
struct domain *owner = page_get_owner(page);
|
||||
unsigned long gmfn;
|
||||
|
||||
+ if ( type & PGT_writable_page )
|
||||
+ {
|
||||
+ free_writable_page(page);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
if ( likely(owner != NULL) )
|
||||
{
|
||||
/*
|
||||
@@ -1652,11 +1805,13 @@ void put_page_type(struct page_info *pag
|
||||
|
||||
if ( unlikely((nx & PGT_count_mask) == 0) )
|
||||
{
|
||||
- if ( unlikely((nx & PGT_type_mask) <= PGT_l4_page_table) &&
|
||||
+ if ( (unlikely((nx & PGT_type_mask) <= PGT_l4_page_table) ||
|
||||
+ unlikely((nx & PGT_type_mask) > PGT_writable_page)) &&
|
||||
likely(nx & PGT_validated) )
|
||||
{
|
||||
/*
|
||||
- * Page-table pages must be unvalidated when count is zero. The
|
||||
+ * Page-table pages and writable pages with non-default
|
||||
+ * cacheability must be unvalidated when count is zero. The
|
||||
* 'free' is safe because the refcnt is non-zero and validated
|
||||
* bit is clear => other ops will spin or fail.
|
||||
*/
|
||||
@@ -1725,7 +1880,7 @@ int get_page_type(struct page_info *page
|
||||
if ( unlikely(!cpus_empty(mask)) &&
|
||||
/* Shadow mode: track only writable pages. */
|
||||
(!shadow_mode_enabled(page_get_owner(page)) ||
|
||||
- ((nx & PGT_type_mask) == PGT_writable_page)) )
|
||||
+ (nx & PGT_writable_page)) )
|
||||
{
|
||||
perfc_incr(need_flush_tlb_flush);
|
||||
flush_tlb_mask(mask);
|
||||
@@ -3243,8 +3398,30 @@ static int ptwr_emulated_update(
|
||||
ASSERT((page->u.inuse.type_info & PGT_count_mask) != 0);
|
||||
ASSERT(page_get_owner(page) == d);
|
||||
|
||||
+ pl1e = (l1_pgentry_t *)((unsigned long)map_domain_page(mfn)
|
||||
+ + (addr & ~PAGE_MASK));
|
||||
+ ol1e = do_cmpxchg ? l1e_from_intpte(old) : *pl1e;
|
||||
+
|
||||
/* Check the new PTE. */
|
||||
nl1e = l1e_from_intpte(val);
|
||||
+ adjust_guest_l1e(nl1e, d);
|
||||
+
|
||||
+ if ( (l1e_get_flags(nl1e) & _PAGE_PRESENT) &&
|
||||
+ !l1e_has_changed(ol1e, nl1e, _PAGE_PRESENT) &&
|
||||
+ l1e_has_changed(ol1e, nl1e, _PAGE_RW | PAGE_CACHE_ATTRS) &&
|
||||
+ (l1e_get_flags(ol1e) & (_PAGE_RW | PAGE_CACHE_ATTRS)) &&
|
||||
+ (l1e_get_flags(nl1e) & (_PAGE_RW | PAGE_CACHE_ATTRS)) &&
|
||||
+ mfn_valid(l1e_get_pfn(nl1e)) )
|
||||
+ {
|
||||
+ int ret = transition_writable_page(pl1e, ol1e, nl1e, mfn, do_cmpxchg);
|
||||
+
|
||||
+ if ( ret >= 0 )
|
||||
+ {
|
||||
+ unmap_domain_page(pl1e);
|
||||
+ return ret ? X86EMUL_OKAY : X86EMUL_RETRY;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
if ( unlikely(!get_page_from_l1e(nl1e, d)) )
|
||||
{
|
||||
if ( (CONFIG_PAGING_LEVELS >= 3) && is_pv_32bit_domain(d) &&
|
||||
@@ -3263,21 +3440,17 @@ static int ptwr_emulated_update(
|
||||
}
|
||||
else
|
||||
{
|
||||
+ unmap_domain_page(pl1e);
|
||||
MEM_LOG("ptwr_emulate: could not get_page_from_l1e()");
|
||||
return X86EMUL_UNHANDLEABLE;
|
||||
}
|
||||
}
|
||||
|
||||
- adjust_guest_l1e(nl1e, d);
|
||||
-
|
||||
/* Checked successfully: do the update (write or cmpxchg). */
|
||||
- pl1e = map_domain_page(mfn);
|
||||
- pl1e = (l1_pgentry_t *)((unsigned long)pl1e + (addr & ~PAGE_MASK));
|
||||
if ( do_cmpxchg )
|
||||
{
|
||||
int okay;
|
||||
intpte_t t = old;
|
||||
- ol1e = l1e_from_intpte(old);
|
||||
|
||||
okay = paging_cmpxchg_guest_entry(v, &l1e_get_intpte(*pl1e),
|
||||
&t, val, _mfn(mfn));
|
||||
@@ -3290,12 +3463,8 @@ static int ptwr_emulated_update(
|
||||
return X86EMUL_CMPXCHG_FAILED;
|
||||
}
|
||||
}
|
||||
- else
|
||||
- {
|
||||
- ol1e = *pl1e;
|
||||
- if ( !UPDATE_ENTRY(l1, pl1e, ol1e, nl1e, mfn, v) )
|
||||
- BUG();
|
||||
- }
|
||||
+ else if ( !UPDATE_ENTRY(l1, pl1e, ol1e, nl1e, mfn, v) )
|
||||
+ BUG();
|
||||
|
||||
unmap_domain_page(pl1e);
|
||||
|
||||
@@ -3439,6 +3608,8 @@ int map_pages_to_xen(
|
||||
if ( !(l2e_get_flags(*pl2e) & _PAGE_PRESENT) )
|
||||
{
|
||||
pl1e = alloc_xen_pagetable();
|
||||
+ if ( pl1e == NULL )
|
||||
+ return -ENOMEM;
|
||||
clear_page(pl1e);
|
||||
l2e_write(pl2e, l2e_from_pfn(virt_to_mfn(pl1e),
|
||||
__PAGE_HYPERVISOR));
|
||||
@@ -3446,6 +3617,8 @@ int map_pages_to_xen(
|
||||
else if ( l2e_get_flags(*pl2e) & _PAGE_PSE )
|
||||
{
|
||||
pl1e = alloc_xen_pagetable();
|
||||
+ if ( pl1e == NULL )
|
||||
+ return -ENOMEM;
|
||||
for ( i = 0; i < L1_PAGETABLE_ENTRIES; i++ )
|
||||
l1e_write(&pl1e[i],
|
||||
l1e_from_pfn(l2e_get_pfn(*pl2e) + i,
|
||||
@@ -3464,6 +3637,28 @@ int map_pages_to_xen(
|
||||
virt += 1UL << L1_PAGETABLE_SHIFT;
|
||||
mfn += 1UL;
|
||||
nr_mfns -= 1UL;
|
||||
+
|
||||
+ if ( !map_small_pages &&
|
||||
+ flags == PAGE_HYPERVISOR &&
|
||||
+ ( nr_mfns == 0 ||
|
||||
+ ((((virt>>PAGE_SHIFT) | mfn) & ((1<<PAGETABLE_ORDER)-1)) == 0)) )
|
||||
+ {
|
||||
+ unsigned long base_mfn;
|
||||
+
|
||||
+ pl1e = l2e_to_l1e(*pl2e);
|
||||
+ base_mfn = l1e_get_pfn(*pl1e);
|
||||
+ for ( i = 0; i < L1_PAGETABLE_ENTRIES; i++, pl1e++ )
|
||||
+ if ( l1e_get_pfn(*pl1e) != base_mfn + i ||
|
||||
+ l1e_get_flags(*pl1e) != flags )
|
||||
+ break;
|
||||
+ if ( i == L1_PAGETABLE_ENTRIES )
|
||||
+ {
|
||||
+ ol2e = *pl2e;
|
||||
+ l2e_write(pl2e, l2e_from_pfn(base_mfn, flags|_PAGE_PSE));
|
||||
+ local_flush_tlb_pge();
|
||||
+ free_xen_pagetable(mfn_to_virt(l2e_get_pfn(ol2e)));
|
||||
+ }
|
||||
+ }
|
||||
}
|
||||
}
|
||||
|
||||
Index: 2007-05-14/xen/arch/x86/mm/shadow/common.c
|
||||
===================================================================
|
||||
--- 2007-05-14.orig/xen/arch/x86/mm/shadow/common.c 2007-05-14 08:28:38.000000000 +0200
|
||||
+++ 2007-05-14/xen/arch/x86/mm/shadow/common.c 2007-05-14 14:35:02.000000000 +0200
|
||||
@@ -1320,7 +1320,7 @@ static void sh_hash_audit_bucket(struct
|
||||
/* Bad shadow flags on guest page? */
|
||||
BUG_ON( !(gpg->shadow_flags & (1<<sp->type)) );
|
||||
/* Bad type count on guest page? */
|
||||
- if ( (gpg->u.inuse.type_info & PGT_type_mask) == PGT_writable_page
|
||||
+ if ( (gpg->u.inuse.type_info & PGT_writable_page)
|
||||
&& (gpg->u.inuse.type_info & PGT_count_mask) != 0 )
|
||||
{
|
||||
SHADOW_ERROR("MFN %#lx shadowed (by %#"PRI_mfn")"
|
||||
Index: 2007-05-14/xen/arch/x86/mm/shadow/multi.c
|
||||
===================================================================
|
||||
--- 2007-05-14.orig/xen/arch/x86/mm/shadow/multi.c 2007-05-14 14:28:19.000000000 +0200
|
||||
+++ 2007-05-14/xen/arch/x86/mm/shadow/multi.c 2007-05-14 14:35:02.000000000 +0200
|
||||
@@ -4128,8 +4128,7 @@ audit_gfn_to_mfn(struct vcpu *v, gfn_t g
|
||||
if ( !shadow_mode_translate(v->domain) )
|
||||
return _mfn(gfn_x(gfn));
|
||||
|
||||
- if ( (mfn_to_page(gmfn)->u.inuse.type_info & PGT_type_mask)
|
||||
- != PGT_writable_page )
|
||||
+ if ( !(mfn_to_page(gmfn)->u.inuse.type_info & PGT_writable_page) )
|
||||
return _mfn(gfn_x(gfn)); /* This is a paging-disabled shadow */
|
||||
else
|
||||
return gfn_to_mfn(v->domain, gfn_x(gfn));
|
||||
Index: 2007-05-14/xen/include/asm-x86/mm.h
|
||||
===================================================================
|
||||
--- 2007-05-14.orig/xen/include/asm-x86/mm.h 2007-05-14 13:43:35.000000000 +0200
|
||||
+++ 2007-05-14/xen/include/asm-x86/mm.h 2007-05-14 14:35:02.000000000 +0200
|
||||
@@ -64,24 +64,35 @@ struct page_info
|
||||
};
|
||||
|
||||
/* The following page types are MUTUALLY EXCLUSIVE. */
|
||||
-#define PGT_none (0U<<29) /* no special uses of this page */
|
||||
-#define PGT_l1_page_table (1U<<29) /* using this page as an L1 page table? */
|
||||
-#define PGT_l2_page_table (2U<<29) /* using this page as an L2 page table? */
|
||||
-#define PGT_l3_page_table (3U<<29) /* using this page as an L3 page table? */
|
||||
-#define PGT_l4_page_table (4U<<29) /* using this page as an L4 page table? */
|
||||
-#define PGT_gdt_page (5U<<29) /* using this page in a GDT? */
|
||||
-#define PGT_ldt_page (6U<<29) /* using this page in an LDT? */
|
||||
-#define PGT_writable_page (7U<<29) /* has writable mappings of this page? */
|
||||
-#define PGT_type_mask (7U<<29) /* Bits 29-31. */
|
||||
+#define PGT_none (0U<<28) /* no special uses of this page */
|
||||
+#define PGT_l1_page_table (1U<<28) /* using this page as an L1 page table? */
|
||||
+#define PGT_l2_page_table (2U<<28) /* using this page as an L2 page table? */
|
||||
+#define PGT_l3_page_table (3U<<28) /* using this page as an L3 page table? */
|
||||
+#define PGT_l4_page_table (4U<<28) /* using this page as an L4 page table? */
|
||||
+#define PGT_gdt_page (5U<<28) /* using this page in a GDT? */
|
||||
+#define PGT_ldt_page (6U<<28) /* using this page in an LDT? */
|
||||
+#define PGT_writable_page (0x8U<<28) /* has writable mappings of this page? */
|
||||
+#define PGT_pwt_mask (0x1U<<28) /* (l1e & _PAGE_PWT) mirror */
|
||||
+#define PGT_pcd_mask (0x2U<<28) /* (l1e & _PAGE_PCD) mirror */
|
||||
+#define PGT_wb_page (0x8U<<28) /* WB cached writable page? */
|
||||
+#define PGT_wt_page (0x9U<<28) /* WT cached writable page? */
|
||||
+#define PGT_ucm_page (0xAU<<28) /* UC- cached writable page? */
|
||||
+#define PGT_uc_page (0xBU<<28) /* UC cached writable page? */
|
||||
+#ifdef CONFIG_PAT
|
||||
+#define PGT_pat_mask (0x4U<<28) /* (l1e & _PAGE_PAT) mirror */
|
||||
+#define PGT_wc_page (0xCU<<28) /* WC cached writable page? */
|
||||
+#define PGT_wp_page (0xDU<<28) /* WP cached writable page? */
|
||||
+#endif
|
||||
+#define PGT_type_mask (0xFU<<28) /* Bits 28-31. */
|
||||
|
||||
/* Owning guest has pinned this page to its current type? */
|
||||
-#define _PGT_pinned 28
|
||||
+#define _PGT_pinned 22
|
||||
#define PGT_pinned (1U<<_PGT_pinned)
|
||||
/* Has this page been validated for use as its current type? */
|
||||
-#define _PGT_validated 27
|
||||
+#define _PGT_validated 21
|
||||
#define PGT_validated (1U<<_PGT_validated)
|
||||
/* PAE only: is this an L2 page directory containing Xen-private mappings? */
|
||||
-#define _PGT_pae_xen_l2 26
|
||||
+#define _PGT_pae_xen_l2 20
|
||||
#define PGT_pae_xen_l2 (1U<<_PGT_pae_xen_l2)
|
||||
|
||||
/* 16-bit count of uses of this frame as its current type. */
|
||||
@@ -141,7 +152,6 @@ extern unsigned long max_page;
|
||||
extern unsigned long total_pages;
|
||||
void init_frametable(void);
|
||||
|
||||
-int alloc_page_type(struct page_info *page, unsigned long type);
|
||||
void free_page_type(struct page_info *page, unsigned long type);
|
||||
int _shadow_mode_refcounts(struct domain *d);
|
||||
|
||||
Index: 2007-05-14/xen/include/asm-x86/x86_32/page-3level.h
|
||||
===================================================================
|
||||
--- 2007-05-14.orig/xen/include/asm-x86/x86_32/page-3level.h 2007-04-23 10:01:46.000000000 +0200
|
||||
+++ 2007-05-14/xen/include/asm-x86/x86_32/page-3level.h 2007-05-14 14:35:02.000000000 +0200
|
||||
@@ -85,6 +85,6 @@ typedef l3_pgentry_t root_pgentry_t;
|
||||
#define get_pte_flags(x) (((int)((x) >> 32) & ~0xFFF) | ((int)(x) & 0xFFF))
|
||||
#define put_pte_flags(x) (((intpte_t)((x) & ~0xFFF) << 32) | ((x) & 0xFFF))
|
||||
|
||||
-#define L3_DISALLOW_MASK 0xFFFFF1E6U /* must-be-zero */
|
||||
+#define L3_DISALLOW_MASK 0xFFFFF1FEU /* must-be-zero */
|
||||
|
||||
#endif /* __X86_32_PAGE_3LEVEL_H__ */
|
||||
Index: 2007-05-14/xen/include/asm-x86/x86_32/page.h
|
||||
===================================================================
|
||||
--- 2007-05-14.orig/xen/include/asm-x86/x86_32/page.h 2007-04-23 10:01:46.000000000 +0200
|
||||
+++ 2007-05-14/xen/include/asm-x86/x86_32/page.h 2007-05-14 14:35:02.000000000 +0200
|
||||
@@ -29,13 +29,13 @@ extern unsigned int PAGE_HYPERVISOR_NOCA
|
||||
(_PAGE_PRESENT|_PAGE_ACCESSED|_PAGE_DIRTY|_PAGE_GNTTAB)
|
||||
|
||||
/*
|
||||
- * Disallow unused flag bits plus PAT, PSE and GLOBAL.
|
||||
+ * Disallow unused flag bits plus PAT/PSE and GLOBAL.
|
||||
* Permit the NX bit if the hardware supports it.
|
||||
*/
|
||||
#define BASE_DISALLOW_MASK (0xFFFFF180U & ~_PAGE_NX)
|
||||
|
||||
#define L1_DISALLOW_MASK (BASE_DISALLOW_MASK | _PAGE_GNTTAB)
|
||||
-#define L2_DISALLOW_MASK (BASE_DISALLOW_MASK)
|
||||
+#define L2_DISALLOW_MASK (BASE_DISALLOW_MASK | _PAGE_PCD | _PAGE_PWT)
|
||||
|
||||
#endif /* __X86_32_PAGE_H__ */
|
||||
|
||||
Index: 2007-05-14/xen/include/asm-x86/x86_64/page.h
|
||||
===================================================================
|
||||
--- 2007-05-14.orig/xen/include/asm-x86/x86_64/page.h 2007-05-03 09:45:09.000000000 +0200
|
||||
+++ 2007-05-14/xen/include/asm-x86/x86_64/page.h 2007-05-14 14:35:02.000000000 +0200
|
||||
@@ -87,18 +87,18 @@ typedef l4_pgentry_t root_pgentry_t;
|
||||
#define _PAGE_NX (cpu_has_nx ? _PAGE_NX_BIT : 0U)
|
||||
|
||||
/*
|
||||
- * Disallow unused flag bits plus PAT, PSE and GLOBAL.
|
||||
+ * Disallow unused flag bits plus PAT/PSE and GLOBAL.
|
||||
* Permit the NX bit if the hardware supports it.
|
||||
* Note that range [62:52] is available for software use on x86/64.
|
||||
*/
|
||||
#define BASE_DISALLOW_MASK (0xFF800180U & ~_PAGE_NX)
|
||||
|
||||
#define L1_DISALLOW_MASK (BASE_DISALLOW_MASK | _PAGE_GNTTAB)
|
||||
-#define L2_DISALLOW_MASK (BASE_DISALLOW_MASK)
|
||||
-#define L3_DISALLOW_MASK (BASE_DISALLOW_MASK)
|
||||
-#define L4_DISALLOW_MASK (BASE_DISALLOW_MASK)
|
||||
+#define L2_DISALLOW_MASK (BASE_DISALLOW_MASK | _PAGE_PCD | _PAGE_PWT)
|
||||
+#define L3_DISALLOW_MASK (BASE_DISALLOW_MASK | _PAGE_PCD | _PAGE_PWT)
|
||||
+#define L4_DISALLOW_MASK (BASE_DISALLOW_MASK | _PAGE_PCD | _PAGE_PWT)
|
||||
|
||||
-#define COMPAT_L3_DISALLOW_MASK 0xFFFFF1E6U
|
||||
+#define COMPAT_L3_DISALLOW_MASK 0xFFFFF1FEU
|
||||
|
||||
#define PAGE_HYPERVISOR (__PAGE_HYPERVISOR | _PAGE_GLOBAL)
|
||||
#define PAGE_HYPERVISOR_NOCACHE (__PAGE_HYPERVISOR_NOCACHE | _PAGE_GLOBAL)
|
74
ptwr-sanity.patch
Normal file
74
ptwr-sanity.patch
Normal file
@ -0,0 +1,74 @@
|
||||
Index: 2007-05-14/xen/arch/x86/mm.c
|
||||
===================================================================
|
||||
--- 2007-05-14.orig/xen/arch/x86/mm.c 2007-05-14 13:43:50.000000000 +0200
|
||||
+++ 2007-05-14/xen/arch/x86/mm.c 2007-05-14 13:44:25.000000000 +0200
|
||||
@@ -3238,13 +3238,14 @@ static int ptwr_emulated_update(
|
||||
|
||||
/* We are looking only for read-only mappings of p.t. pages. */
|
||||
ASSERT((l1e_get_flags(pte) & (_PAGE_RW|_PAGE_PRESENT)) == _PAGE_PRESENT);
|
||||
+ ASSERT(mfn_valid(mfn));
|
||||
ASSERT((page->u.inuse.type_info & PGT_type_mask) == PGT_l1_page_table);
|
||||
ASSERT((page->u.inuse.type_info & PGT_count_mask) != 0);
|
||||
ASSERT(page_get_owner(page) == d);
|
||||
|
||||
/* Check the new PTE. */
|
||||
nl1e = l1e_from_intpte(val);
|
||||
- if ( unlikely(!get_page_from_l1e(gl1e_to_ml1e(d, nl1e), d)) )
|
||||
+ if ( unlikely(!get_page_from_l1e(nl1e, d)) )
|
||||
{
|
||||
if ( (CONFIG_PAGING_LEVELS >= 3) && is_pv_32bit_domain(d) &&
|
||||
(bytes == 4) && (addr & 4) && !do_cmpxchg &&
|
||||
@@ -3270,7 +3271,7 @@ static int ptwr_emulated_update(
|
||||
adjust_guest_l1e(nl1e, d);
|
||||
|
||||
/* Checked successfully: do the update (write or cmpxchg). */
|
||||
- pl1e = map_domain_page(page_to_mfn(page));
|
||||
+ pl1e = map_domain_page(mfn);
|
||||
pl1e = (l1_pgentry_t *)((unsigned long)pl1e + (addr & ~PAGE_MASK));
|
||||
if ( do_cmpxchg )
|
||||
{
|
||||
@@ -3285,21 +3286,21 @@ static int ptwr_emulated_update(
|
||||
if ( !okay )
|
||||
{
|
||||
unmap_domain_page(pl1e);
|
||||
- put_page_from_l1e(gl1e_to_ml1e(d, nl1e), d);
|
||||
+ put_page_from_l1e(nl1e, d);
|
||||
return X86EMUL_CMPXCHG_FAILED;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ol1e = *pl1e;
|
||||
- if ( !UPDATE_ENTRY(l1, pl1e, ol1e, nl1e, page_to_mfn(page), v) )
|
||||
+ if ( !UPDATE_ENTRY(l1, pl1e, ol1e, nl1e, mfn, v) )
|
||||
BUG();
|
||||
}
|
||||
|
||||
unmap_domain_page(pl1e);
|
||||
|
||||
/* Finally, drop the old PTE. */
|
||||
- put_page_from_l1e(gl1e_to_ml1e(d, ol1e), d);
|
||||
+ put_page_from_l1e(ol1e, d);
|
||||
|
||||
return X86EMUL_OKAY;
|
||||
}
|
||||
@@ -3365,17 +3366,13 @@ int ptwr_do_page_fault(struct vcpu *v, u
|
||||
|
||||
LOCK_BIGLOCK(d);
|
||||
|
||||
- /*
|
||||
- * Attempt to read the PTE that maps the VA being accessed. By checking for
|
||||
- * PDE validity in the L2 we avoid many expensive fixups in __get_user().
|
||||
- */
|
||||
+ /* Attempt to read the PTE that maps the VA being accessed. */
|
||||
guest_get_eff_l1e(v, addr, &pte);
|
||||
- if ( !(l1e_get_flags(pte) & _PAGE_PRESENT) )
|
||||
- goto bail;
|
||||
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) ||
|
||||
+ !mfn_valid(l1e_get_pfn(pte)) ||
|
||||
((page->u.inuse.type_info & PGT_type_mask) != PGT_l1_page_table) ||
|
||||
((page->u.inuse.type_info & PGT_count_mask) == 0) ||
|
||||
(page_get_owner(page) != d) )
|
406
realmode.patch
Normal file
406
realmode.patch
Normal file
@ -0,0 +1,406 @@
|
||||
Index: 2007-04-27/xen/arch/x86/Makefile
|
||||
===================================================================
|
||||
--- 2007-04-27.orig/xen/arch/x86/Makefile 2006-12-01 10:44:36.000000000 +0100
|
||||
+++ 2007-04-27/xen/arch/x86/Makefile 2007-04-27 09:31:25.000000000 +0200
|
||||
@@ -78,6 +78,8 @@ xen.lds: $(TARGET_SUBARCH)/xen.lds.S $(H
|
||||
boot/mkelf32: boot/mkelf32.c
|
||||
$(HOSTCC) $(HOSTCFLAGS) -o $@ $<
|
||||
|
||||
+boot/$(TARGET_SUBARCH).o: boot/realmode.S
|
||||
+
|
||||
.PHONY: clean
|
||||
clean::
|
||||
rm -f asm-offsets.s xen.lds boot/*.o boot/*~ boot/core boot/mkelf32
|
||||
Index: 2007-04-27/xen/arch/x86/boot/realmode.S
|
||||
===================================================================
|
||||
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
|
||||
+++ 2007-04-27/xen/arch/x86/boot/realmode.S 2007-04-27 09:31:25.000000000 +0200
|
||||
@@ -0,0 +1,122 @@
|
||||
+#define REALMODE_SEG 0x1000
|
||||
+#define REALMODE_BASE (REALMODE_SEG << 4)
|
||||
+
|
||||
+ .section .init.data, "aw"
|
||||
+ .align 8
|
||||
+gdt16_table:
|
||||
+ .quad 0
|
||||
+ .quad 0x00cf9a000000ffff /* 0xe008 ring 0 4.00GB code at 0x0 */
|
||||
+ .quad 0x00cf92000000ffff /* 0xe010 ring 0 4.00GB data at 0x0 */
|
||||
+ /* 0xe018 ring 0 64kB 16-bit code at REALMODE_BASE */
|
||||
+#define __HYPERVISOR_CS16 (__HYPERVISOR_CS + 0x10)
|
||||
+ .long 0x0000ffff + ((REALMODE_BASE & 0xffff) << 16)
|
||||
+ .long 0x00009a00 + (REALMODE_BASE >> 16)
|
||||
+ /* 0xe020 ring 0 64kB 16-bit data at REALMODE_BASE */
|
||||
+#define __HYPERVISOR_DS16 (__HYPERVISOR_DS32 + 0x10)
|
||||
+ .long 0x0000ffff + ((REALMODE_BASE & 0xffff) << 16)
|
||||
+ .long 0x00009200 + (REALMODE_BASE >> 16)
|
||||
+#if __HYPERVISOR_CS32 != __HYPERVISOR_CS
|
||||
+/* This doesn't work properly with gas up to at least 2.17.50 as of Feb 2007.
|
||||
+ Using .skip or .fill also doesn't work up to 2.15 or 2.16. Use as' -K
|
||||
+ option to be pointed at the problematic construct (.word with its operand
|
||||
+ being the difference of two symbols) below.
|
||||
+ .org gdt16_table + (__HYPERVISOR_CS32 - FIRST_RESERVED_GDT_BYTE) */
|
||||
+ .rept (__HYPERVISOR_CS32 - __HYPERVISOR_DS16) / 8 - 1
|
||||
+ .quad 0
|
||||
+ .endr
|
||||
+ .quad 0x00cf9a000000ffff /* 0xe038 ring 0 4.00GB code at 0x0 */
|
||||
+#endif
|
||||
+.Lgdt16_end:
|
||||
+
|
||||
+ .word 0
|
||||
+gdt16: .word FIRST_RESERVED_GDT_BYTE + .Lgdt16_end - gdt16_table - 1
|
||||
+ .long SYM_PHYS(gdt16_table) - FIRST_RESERVED_GDT_BYTE
|
||||
+
|
||||
+#define SYM_REAL(x) ((x) - .L__realtext)
|
||||
+
|
||||
+ .section .init.text, "ax"
|
||||
+ .code32
|
||||
+realmode:
|
||||
+ pushal
|
||||
+ movl %esp, %ebp
|
||||
+ sgdt SYM_PHYS(.Lgdt)
|
||||
+ sidt SYM_PHYS(.Lidt)
|
||||
+ testl $MBI_CMDLINE, MBI_flags(%ebx)
|
||||
+ movl MBI_cmdline(%ebx), %esi
|
||||
+ jz 1f
|
||||
+ testl %esi, %esi
|
||||
+ jz 1f
|
||||
+ movl $REALMODE_BASE + 0x10000, %edi
|
||||
+ movl %edi, SYM_PHYS(cmd_line_ptr)
|
||||
+0:
|
||||
+ lodsb
|
||||
+ stosb
|
||||
+ testb %al, %al
|
||||
+ jnz 0b
|
||||
+1:
|
||||
+ movl $SYM_PHYS(.L__realtext), %esi
|
||||
+ movl $REALMODE_BASE, %edi
|
||||
+ movl $SYM_PHYS(__end_realmode), %ecx
|
||||
+ subl %esi, %ecx
|
||||
+ rep movsb
|
||||
+ movl 9*4(%ebp), %edi
|
||||
+ subl $SYM_PHYS(.L__realtext), %edi
|
||||
+ lgdt SYM_PHYS(gdt16)
|
||||
+ movl $__HYPERVISOR_DS16, %ecx
|
||||
+ mov %ecx, %ss
|
||||
+ xorl %esp, %esp
|
||||
+ mov %ecx, %ds
|
||||
+ mov %ecx, %es
|
||||
+ ljmpl $__HYPERVISOR_CS16, $SYM_REAL(.Ltext16)
|
||||
+
|
||||
+protmode:
|
||||
+ movl $__HYPERVISOR_DS32, %ecx
|
||||
+ mov %ecx, %ss
|
||||
+ movl %ebp, %esp
|
||||
+ mov %ecx, %ds
|
||||
+ mov %ecx, %es
|
||||
+ movl $REALMODE_BASE + SYM_PHYS(.L__realdata), %esi
|
||||
+ subl $SYM_PHYS(.L__realtext), %esi
|
||||
+ movl $SYM_PHYS(.L__realdata), %edi
|
||||
+ movl $SYM_PHYS(__end_realmode), %ecx
|
||||
+ subl %edi, %ecx
|
||||
+ rep movsb
|
||||
+ mov %ecx, %fs
|
||||
+ mov %ecx, %gs
|
||||
+ popal
|
||||
+ ret $4
|
||||
+
|
||||
+ .section .real.text, "ax"
|
||||
+.L__realtext:
|
||||
+ .code16
|
||||
+.Ltext16:
|
||||
+ mov %cr0, %eax
|
||||
+ andb $~1, %al
|
||||
+ mov %eax, %cr0
|
||||
+ ljmpw $REALMODE_SEG, $SYM_REAL(.Lrealmode)
|
||||
+.Lrealmode:
|
||||
+ mov %cs, %cx
|
||||
+ mov %cx, %ss
|
||||
+ mov %cx, %ds
|
||||
+ mov %cx, %es
|
||||
+
|
||||
+ pushal
|
||||
+ callw *%di
|
||||
+ popal
|
||||
+
|
||||
+ pushw $0
|
||||
+ popfw
|
||||
+ lgdtl %cs:SYM_REAL(.Lgdt)
|
||||
+ lidtl %cs:SYM_REAL(.Lidt)
|
||||
+ mov %cr0, %eax
|
||||
+ orb $1, %al
|
||||
+ mov %eax, %cr0
|
||||
+ ljmpl $__HYPERVISOR_CS32, $SYM_PHYS(protmode)
|
||||
+
|
||||
+ .section .real.data, "aw"
|
||||
+.L__realdata:
|
||||
+ .align 4
|
||||
+cmd_line_ptr: .long 0
|
||||
+.Lgdt: .skip 2+4
|
||||
+.Lidt: .skip 2+4
|
||||
+ .previous
|
||||
Index: 2007-04-27/xen/arch/x86/boot/x86_32.S
|
||||
===================================================================
|
||||
--- 2007-04-27.orig/xen/arch/x86/boot/x86_32.S 2007-01-05 10:09:13.000000000 +0100
|
||||
+++ 2007-04-27/xen/arch/x86/boot/x86_32.S 2007-04-27 09:31:25.000000000 +0200
|
||||
@@ -10,6 +10,8 @@
|
||||
|
||||
.text
|
||||
|
||||
+#define SYM_PHYS(sym) (sym - __PAGE_OFFSET)
|
||||
+
|
||||
ENTRY(start)
|
||||
jmp __start
|
||||
|
||||
@@ -28,7 +30,7 @@ ENTRY(start)
|
||||
not_multiboot_msg:
|
||||
.asciz "ERR: Not a Multiboot bootloader!"
|
||||
not_multiboot:
|
||||
- mov $not_multiboot_msg-__PAGE_OFFSET,%esi
|
||||
+ mov $SYM_PHYS(not_multiboot_msg),%esi
|
||||
mov $0xB8000,%edi # VGA framebuffer
|
||||
1: mov (%esi),%bl
|
||||
test %bl,%bl # Terminate on '\0' sentinel
|
||||
@@ -47,14 +49,14 @@ not_multiboot:
|
||||
|
||||
__start:
|
||||
/* Set up a few descriptors: on entry only CS is guaranteed good. */
|
||||
- lgdt %cs:nopaging_gdt_descr-__PAGE_OFFSET
|
||||
+ lgdt %cs:SYM_PHYS(nopaging_gdt_descr)
|
||||
mov $(__HYPERVISOR_DS),%ecx
|
||||
mov %ecx,%ds
|
||||
mov %ecx,%es
|
||||
mov %ecx,%fs
|
||||
mov %ecx,%gs
|
||||
- ljmp $(__HYPERVISOR_CS),$(1f)-__PAGE_OFFSET
|
||||
-1: lss stack_start-__PAGE_OFFSET,%esp
|
||||
+ ljmp $(__HYPERVISOR_CS),$SYM_PHYS(1f)
|
||||
+1: lss SYM_PHYS(stack_start),%esp
|
||||
add $(STACK_SIZE-CPUINFO_sizeof-__PAGE_OFFSET),%esp
|
||||
|
||||
/* Reset EFLAGS (subsumes CLI and CLD). */
|
||||
@@ -66,7 +68,7 @@ __start:
|
||||
|
||||
/* Set up CR4, except global flag which Intel requires should be */
|
||||
/* left until after paging is enabled (IA32 Manual Vol. 3, Sec. 2.5) */
|
||||
- mov mmu_cr4_features-__PAGE_OFFSET,%ecx
|
||||
+ mov SYM_PHYS(mmu_cr4_features),%ecx
|
||||
and $0x7f,%cl # CR4.PGE (global enable)
|
||||
mov %ecx,%cr4
|
||||
|
||||
@@ -78,19 +80,19 @@ __start:
|
||||
jne not_multiboot
|
||||
|
||||
/* Initialize BSS (no nasty surprises!) */
|
||||
- mov $__bss_start-__PAGE_OFFSET,%edi
|
||||
- mov $_end-__PAGE_OFFSET,%ecx
|
||||
+ mov $SYM_PHYS(__bss_start),%edi
|
||||
+ mov $SYM_PHYS(_end),%ecx
|
||||
sub %edi,%ecx
|
||||
xor %eax,%eax
|
||||
rep stosb
|
||||
|
||||
/* Save the Multiboot info structure for later use. */
|
||||
- add $__PAGE_OFFSET,%ebx
|
||||
- push %ebx
|
||||
+ lea __PAGE_OFFSET(%ebx),%eax
|
||||
+ push %eax
|
||||
|
||||
#ifdef CONFIG_X86_PAE
|
||||
/* Initialize low and high mappings of all memory with 2MB pages */
|
||||
- mov $idle_pg_table_l2-__PAGE_OFFSET,%edi
|
||||
+ mov $SYM_PHYS(idle_pg_table_l2),%edi
|
||||
mov $0xe3,%eax /* PRESENT+RW+A+D+2MB */
|
||||
1: mov %eax,__PAGE_OFFSET>>18(%edi) /* high mapping */
|
||||
stosl /* low mapping */
|
||||
@@ -105,7 +107,7 @@ __start:
|
||||
jne 1b
|
||||
#else
|
||||
/* Initialize low and high mappings of all memory with 4MB pages */
|
||||
- mov $idle_pg_table-__PAGE_OFFSET,%edi
|
||||
+ mov $SYM_PHYS(idle_pg_table),%edi
|
||||
mov $0xe3,%eax /* PRESENT+RW+A+D+4MB */
|
||||
1: mov %eax,__PAGE_OFFSET>>20(%edi) /* high mapping */
|
||||
stosl /* low mapping */
|
||||
@@ -123,7 +125,7 @@ __start:
|
||||
mov $(__HYPERVISOR_CS << 16),%eax
|
||||
mov %dx,%ax /* selector = 0x0010 = cs */
|
||||
mov $0x8E00,%dx /* interrupt gate - dpl=0, present */
|
||||
- lea idt_table-__PAGE_OFFSET,%edi
|
||||
+ lea SYM_PHYS(idt_table),%edi
|
||||
mov $256,%ecx
|
||||
1: mov %eax,(%edi)
|
||||
mov %edx,4(%edi)
|
||||
@@ -149,7 +151,7 @@ start_paging:
|
||||
no_execute_disable:
|
||||
pop %ebx
|
||||
#endif
|
||||
- mov $idle_pg_table-__PAGE_OFFSET,%eax
|
||||
+ mov $SYM_PHYS(idle_pg_table),%eax
|
||||
mov %eax,%cr3
|
||||
mov $0x80050033,%eax /* hi-to-lo: PG,AM,WP,NE,ET,MP,PE */
|
||||
mov %eax,%cr0
|
||||
@@ -212,7 +214,7 @@ gdt_descr:
|
||||
.word 0
|
||||
nopaging_gdt_descr:
|
||||
.word LAST_RESERVED_GDT_BYTE
|
||||
- .long gdt_table - FIRST_RESERVED_GDT_BYTE - __PAGE_OFFSET
|
||||
+ .long SYM_PHYS(gdt_table) - FIRST_RESERVED_GDT_BYTE
|
||||
|
||||
.align PAGE_SIZE, 0
|
||||
/* NB. Rings != 0 get access up to MACH2PHYS_VIRT_END. This allows access to */
|
||||
@@ -236,10 +238,10 @@ ENTRY(gdt_table)
|
||||
#ifdef CONFIG_X86_PAE
|
||||
ENTRY(idle_pg_table)
|
||||
ENTRY(idle_pg_table_l3)
|
||||
- .long idle_pg_table_l2 + 0*PAGE_SIZE + 0x01 - __PAGE_OFFSET, 0
|
||||
- .long idle_pg_table_l2 + 1*PAGE_SIZE + 0x01 - __PAGE_OFFSET, 0
|
||||
- .long idle_pg_table_l2 + 2*PAGE_SIZE + 0x01 - __PAGE_OFFSET, 0
|
||||
- .long idle_pg_table_l2 + 3*PAGE_SIZE + 0x01 - __PAGE_OFFSET, 0
|
||||
+ .long SYM_PHYS(idle_pg_table_l2) + 0*PAGE_SIZE + 0x01, 0
|
||||
+ .long SYM_PHYS(idle_pg_table_l2) + 1*PAGE_SIZE + 0x01, 0
|
||||
+ .long SYM_PHYS(idle_pg_table_l2) + 2*PAGE_SIZE + 0x01, 0
|
||||
+ .long SYM_PHYS(idle_pg_table_l2) + 3*PAGE_SIZE + 0x01, 0
|
||||
.section ".bss.page_aligned","w"
|
||||
ENTRY(idle_pg_table_l2)
|
||||
.fill 4*PAGE_SIZE,1,0
|
||||
@@ -253,3 +255,8 @@ ENTRY(idle_pg_table_l2)
|
||||
.section ".bss.stack_aligned","w"
|
||||
ENTRY(cpu0_stack)
|
||||
.fill STACK_SIZE,1,0
|
||||
+
|
||||
+#define __HYPERVISOR_CS32 __HYPERVISOR_CS
|
||||
+#define __HYPERVISOR_DS32 __HYPERVISOR_DS
|
||||
+
|
||||
+#include "realmode.S"
|
||||
Index: 2007-04-27/xen/arch/x86/boot/x86_64.S
|
||||
===================================================================
|
||||
--- 2007-04-27.orig/xen/arch/x86/boot/x86_64.S 2007-01-08 14:15:31.000000000 +0100
|
||||
+++ 2007-04-27/xen/arch/x86/boot/x86_64.S 2007-04-27 09:31:25.000000000 +0200
|
||||
@@ -72,6 +72,8 @@ __start:
|
||||
/* Save the Multiboot info structure for later use. */
|
||||
mov %ebx,SYM_PHYS(multiboot_ptr)
|
||||
|
||||
+ lss SYM_PHYS(.Lstack_start),%esp
|
||||
+
|
||||
/* We begin by interrogating the CPU for the presence of long mode. */
|
||||
mov $0x80000000,%eax
|
||||
cpuid
|
||||
@@ -200,7 +202,7 @@ multiboot_ptr:
|
||||
.word 0
|
||||
nopaging_gdt_descr:
|
||||
.word LAST_RESERVED_GDT_BYTE
|
||||
- .quad gdt_table - FIRST_RESERVED_GDT_BYTE - __PAGE_OFFSET
|
||||
+ .quad SYM_PHYS(gdt_table) - FIRST_RESERVED_GDT_BYTE
|
||||
|
||||
cpuid_ext_features:
|
||||
.long 0
|
||||
@@ -217,6 +219,9 @@ idt_descr:
|
||||
|
||||
ENTRY(stack_start)
|
||||
.quad cpu0_stack
|
||||
+.Lstack_start:
|
||||
+ .long SYM_PHYS(cpu0_stack) + STACK_SIZE - CPUINFO_sizeof
|
||||
+ .word __HYPERVISOR_DS32
|
||||
|
||||
high_start:
|
||||
.quad __high_start
|
||||
@@ -256,14 +261,14 @@ ENTRY(compat_gdt_table)
|
||||
.align PAGE_SIZE, 0
|
||||
ENTRY(idle_pg_table)
|
||||
ENTRY(idle_pg_table_4)
|
||||
- .quad idle_pg_table_l3 - __PAGE_OFFSET + 7 # PML4[0]
|
||||
+ .quad SYM_PHYS(idle_pg_table_l3) + 7 # PML4[0]
|
||||
.fill 261,8,0
|
||||
- .quad idle_pg_table_l3 - __PAGE_OFFSET + 7 # PML4[262]
|
||||
+ .quad SYM_PHYS(idle_pg_table_l3) + 7 # PML4[262]
|
||||
|
||||
/* Initial PDP -- level-3 page table. */
|
||||
.align PAGE_SIZE, 0
|
||||
ENTRY(idle_pg_table_l3)
|
||||
- .quad idle_pg_table_l2 - __PAGE_OFFSET + 7
|
||||
+ .quad SYM_PHYS(idle_pg_table_l2) + 7
|
||||
|
||||
/* Initial PDE -- level-2 page table. Maps first 1GB physical memory. */
|
||||
.align PAGE_SIZE, 0
|
||||
@@ -283,3 +288,5 @@ ENTRY(idle_pg_table_l2)
|
||||
.section ".bss.stack_aligned","w"
|
||||
ENTRY(cpu0_stack)
|
||||
.fill STACK_SIZE,1,0
|
||||
+
|
||||
+#include "realmode.S"
|
||||
Index: 2007-04-27/xen/arch/x86/x86_32/asm-offsets.c
|
||||
===================================================================
|
||||
--- 2007-04-27.orig/xen/arch/x86/x86_32/asm-offsets.c 2007-04-02 12:16:26.000000000 +0200
|
||||
+++ 2007-04-27/xen/arch/x86/x86_32/asm-offsets.c 2007-04-27 09:31:25.000000000 +0200
|
||||
@@ -7,6 +7,7 @@
|
||||
#include <xen/config.h>
|
||||
#include <xen/perfc.h>
|
||||
#include <xen/sched.h>
|
||||
+#include <xen/multiboot.h>
|
||||
#include <asm/fixmap.h>
|
||||
#include <asm/hardirq.h>
|
||||
|
||||
@@ -99,6 +100,10 @@ void __dummy__(void)
|
||||
DEFINE(CPUINFO_sizeof, sizeof(struct cpu_info));
|
||||
BLANK();
|
||||
|
||||
+ OFFSET(MBI_flags, multiboot_info_t, flags);
|
||||
+ OFFSET(MBI_cmdline, multiboot_info_t, cmdline);
|
||||
+ BLANK();
|
||||
+
|
||||
OFFSET(TRAPBOUNCE_error_code, struct trap_bounce, error_code);
|
||||
OFFSET(TRAPBOUNCE_flags, struct trap_bounce, flags);
|
||||
OFFSET(TRAPBOUNCE_cs, struct trap_bounce, cs);
|
||||
Index: 2007-04-27/xen/arch/x86/x86_32/xen.lds.S
|
||||
===================================================================
|
||||
--- 2007-04-27.orig/xen/arch/x86/x86_32/xen.lds.S 2007-01-05 10:09:13.000000000 +0100
|
||||
+++ 2007-04-27/xen/arch/x86/x86_32/xen.lds.S 2007-04-27 09:31:25.000000000 +0200
|
||||
@@ -63,6 +63,10 @@ SECTIONS
|
||||
__initcall_start = .;
|
||||
.initcall.init : { *(.initcall1.init) } :text
|
||||
__initcall_end = .;
|
||||
+ . = ALIGN(16);
|
||||
+ .real.text : { *(.real.text) } :text
|
||||
+ .real.data : { *(.real.data) } :text
|
||||
+ __end_realmode = .;
|
||||
. = ALIGN(PAGE_SIZE);
|
||||
__init_end = .;
|
||||
|
||||
Index: 2007-04-27/xen/arch/x86/x86_64/asm-offsets.c
|
||||
===================================================================
|
||||
--- 2007-04-27.orig/xen/arch/x86/x86_64/asm-offsets.c 2007-04-02 12:16:26.000000000 +0200
|
||||
+++ 2007-04-27/xen/arch/x86/x86_64/asm-offsets.c 2007-04-27 09:31:25.000000000 +0200
|
||||
@@ -7,6 +7,7 @@
|
||||
#include <xen/config.h>
|
||||
#include <xen/perfc.h>
|
||||
#include <xen/sched.h>
|
||||
+#include <xen/multiboot.h>
|
||||
#ifdef CONFIG_COMPAT
|
||||
#include <compat/xen.h>
|
||||
#endif
|
||||
@@ -112,6 +113,10 @@ void __dummy__(void)
|
||||
DEFINE(CPUINFO_sizeof, sizeof(struct cpu_info));
|
||||
BLANK();
|
||||
|
||||
+ OFFSET(MBI_flags, multiboot_info_t, flags);
|
||||
+ OFFSET(MBI_cmdline, multiboot_info_t, cmdline);
|
||||
+ BLANK();
|
||||
+
|
||||
OFFSET(TRAPBOUNCE_error_code, struct trap_bounce, error_code);
|
||||
OFFSET(TRAPBOUNCE_flags, struct trap_bounce, flags);
|
||||
OFFSET(TRAPBOUNCE_cs, struct trap_bounce, cs);
|
||||
Index: 2007-04-27/xen/arch/x86/x86_64/xen.lds.S
|
||||
===================================================================
|
||||
--- 2007-04-27.orig/xen/arch/x86/x86_64/xen.lds.S 2007-01-05 10:09:13.000000000 +0100
|
||||
+++ 2007-04-27/xen/arch/x86/x86_64/xen.lds.S 2007-04-27 09:31:25.000000000 +0200
|
||||
@@ -61,6 +61,10 @@ SECTIONS
|
||||
__initcall_start = .;
|
||||
.initcall.init : { *(.initcall1.init) } :text
|
||||
__initcall_end = .;
|
||||
+ . = ALIGN(16);
|
||||
+ .real.text : { *(.real.text) } :text
|
||||
+ .real.data : { *(.real.data) } :text
|
||||
+ __end_realmode = .;
|
||||
. = ALIGN(PAGE_SIZE);
|
||||
__init_end = .;
|
||||
|
264
svm-reg-save.patch
Normal file
264
svm-reg-save.patch
Normal file
@ -0,0 +1,264 @@
|
||||
Index: 2007-05-14/xen/arch/x86/hvm/svm/svm.c
|
||||
===================================================================
|
||||
--- 2007-05-14.orig/xen/arch/x86/hvm/svm/svm.c 2007-05-14 14:28:19.000000000 +0200
|
||||
+++ 2007-05-14/xen/arch/x86/hvm/svm/svm.c 2007-05-14 14:33:08.000000000 +0200
|
||||
@@ -747,28 +747,10 @@ static void svm_init_hypercall_page(stru
|
||||
*(u16 *)(hypercall_page + (__HYPERVISOR_iret * 32)) = 0x0b0f; /* ud2 */
|
||||
}
|
||||
|
||||
-static void save_svm_cpu_user_regs(struct vcpu *v, struct cpu_user_regs *ctxt)
|
||||
-{
|
||||
- struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
|
||||
-
|
||||
- ctxt->eax = vmcb->rax;
|
||||
- ctxt->ss = vmcb->ss.sel;
|
||||
- ctxt->esp = vmcb->rsp;
|
||||
- ctxt->eflags = vmcb->rflags;
|
||||
- ctxt->cs = vmcb->cs.sel;
|
||||
- ctxt->eip = vmcb->rip;
|
||||
-
|
||||
- ctxt->gs = vmcb->gs.sel;
|
||||
- ctxt->fs = vmcb->fs.sel;
|
||||
- ctxt->es = vmcb->es.sel;
|
||||
- ctxt->ds = vmcb->ds.sel;
|
||||
-}
|
||||
-
|
||||
static void svm_load_cpu_guest_regs(struct vcpu *v, struct cpu_user_regs *regs)
|
||||
{
|
||||
struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
|
||||
|
||||
- vmcb->rax = regs->eax;
|
||||
vmcb->ss.sel = regs->ss;
|
||||
vmcb->rsp = regs->esp;
|
||||
vmcb->rflags = regs->eflags | 2UL;
|
||||
@@ -1408,7 +1390,7 @@ static void svm_io_instruction(struct vc
|
||||
|
||||
/* Copy current guest state into io instruction state structure. */
|
||||
memcpy(regs, guest_cpu_user_regs(), HVM_CONTEXT_STACK_BYTES);
|
||||
- hvm_store_cpu_guest_regs(v, regs, NULL);
|
||||
+ svm_store_cpu_guest_regs(v, regs, NULL);
|
||||
|
||||
info.bytes = vmcb->exitinfo1;
|
||||
|
||||
@@ -2236,7 +2218,6 @@ asmlinkage void svm_vmexit_handler(struc
|
||||
int inst_len, rc;
|
||||
|
||||
exit_reason = vmcb->exitcode;
|
||||
- save_svm_cpu_user_regs(v, regs);
|
||||
|
||||
HVMTRACE_2D(VMEXIT, v, vmcb->rip, exit_reason);
|
||||
|
||||
Index: 2007-05-14/xen/arch/x86/hvm/svm/x86_32/exits.S
|
||||
===================================================================
|
||||
--- 2007-05-14.orig/xen/arch/x86/hvm/svm/x86_32/exits.S 2007-04-23 10:01:41.000000000 +0200
|
||||
+++ 2007-05-14/xen/arch/x86/hvm/svm/x86_32/exits.S 2007-05-14 14:33:08.000000000 +0200
|
||||
@@ -61,8 +61,11 @@
|
||||
#define HVM_SAVE_ALL_NOSEGREGS \
|
||||
pushl $HVM_MONITOR_EFLAGS; \
|
||||
popf; \
|
||||
- subl $(NR_SKIPPED_REGS*4), %esp; \
|
||||
- pushl %eax; \
|
||||
+ /* \
|
||||
+ * Skip %eax, we need have vmcb address in there. \
|
||||
+ * Don't worry, EAX is saved during #VMEXIT. \
|
||||
+ */ \
|
||||
+ subl $4+(NR_SKIPPED_REGS*4), %esp; \
|
||||
pushl %ebp; \
|
||||
pushl %edi; \
|
||||
pushl %esi; \
|
||||
@@ -77,8 +80,11 @@
|
||||
popl %esi; \
|
||||
popl %edi; \
|
||||
popl %ebp; \
|
||||
- popl %eax; \
|
||||
- addl $(NR_SKIPPED_REGS*4), %esp
|
||||
+ /* \
|
||||
+ * Skip %eax, we need to have vmcb address in there. \
|
||||
+ * Don't worry, EAX is restored through the VMRUN instruction. \
|
||||
+ */ \
|
||||
+ addl $4+(NR_SKIPPED_REGS*4), %esp
|
||||
|
||||
#define VMRUN .byte 0x0F,0x01,0xD8
|
||||
#define VMLOAD .byte 0x0F,0x01,0xDA
|
||||
@@ -88,63 +94,53 @@
|
||||
|
||||
ENTRY(svm_asm_do_resume)
|
||||
GET_CURRENT(%ebx)
|
||||
- xorl %ecx,%ecx
|
||||
- notl %ecx
|
||||
+.Lresume:
|
||||
cli # tests must not race interrupts
|
||||
movl VCPU_processor(%ebx),%eax
|
||||
shl $IRQSTAT_shift,%eax
|
||||
- test %ecx,irq_stat(%eax,1)
|
||||
- jnz svm_process_softirqs
|
||||
+ cmpl $0,irq_stat(%eax)
|
||||
+ jne svm_process_softirqs
|
||||
call svm_intr_assist
|
||||
call svm_load_cr2
|
||||
|
||||
CLGI
|
||||
sti
|
||||
- GET_CURRENT(%ebx)
|
||||
movl VCPU_svm_vmcb(%ebx), %ecx
|
||||
- movl 24(%esp), %eax
|
||||
+ movl UREGS_eax(%esp), %eax
|
||||
+ movl VCPU_processor(%ebx), %edx
|
||||
movl %eax, VMCB_rax(%ecx)
|
||||
- movl VCPU_processor(%ebx), %eax
|
||||
- movl root_vmcb_pa(,%eax,8), %eax
|
||||
+ movl root_vmcb_pa(,%edx,8), %eax
|
||||
VMSAVE
|
||||
|
||||
movl VCPU_svm_vmcb_pa(%ebx), %eax
|
||||
- popl %ebx
|
||||
- popl %ecx
|
||||
- popl %edx
|
||||
- popl %esi
|
||||
- popl %edi
|
||||
- popl %ebp
|
||||
-
|
||||
- /*
|
||||
- * Skip %eax, we need to have vmcb address in there.
|
||||
- * Don't worry, EAX is restored through the VMRUN instruction.
|
||||
- */
|
||||
- addl $4, %esp
|
||||
- addl $(NR_SKIPPED_REGS*4), %esp
|
||||
+ HVM_RESTORE_ALL_NOSEGREGS
|
||||
+
|
||||
VMLOAD
|
||||
VMRUN
|
||||
VMSAVE
|
||||
- /* eax is the only register we're allowed to touch here... */
|
||||
|
||||
- GET_CURRENT(%eax)
|
||||
+ HVM_SAVE_ALL_NOSEGREGS
|
||||
|
||||
- movl VCPU_processor(%eax), %eax
|
||||
- movl root_vmcb_pa(,%eax,8), %eax
|
||||
+ GET_CURRENT(%ebx)
|
||||
+ movl VCPU_processor(%ebx), %ecx
|
||||
+ movl VCPU_svm_vmcb(%ebx), %edx
|
||||
+ movl root_vmcb_pa(,%ecx,8), %eax
|
||||
VMLOAD
|
||||
+ movl VMCB_rax(%edx), %eax
|
||||
|
||||
- HVM_SAVE_ALL_NOSEGREGS
|
||||
STGI
|
||||
.globl svm_stgi_label;
|
||||
svm_stgi_label:
|
||||
+
|
||||
+ movl %eax, UREGS_eax(%esp)
|
||||
movl %esp,%eax
|
||||
push %eax
|
||||
call svm_vmexit_handler
|
||||
addl $4,%esp
|
||||
- jmp svm_asm_do_resume
|
||||
+ jmp .Lresume
|
||||
|
||||
ALIGN
|
||||
svm_process_softirqs:
|
||||
sti
|
||||
call do_softirq
|
||||
- jmp svm_asm_do_resume
|
||||
+ jmp .Lresume
|
||||
Index: 2007-05-14/xen/arch/x86/hvm/svm/x86_64/exits.S
|
||||
===================================================================
|
||||
--- 2007-05-14.orig/xen/arch/x86/hvm/svm/x86_64/exits.S 2007-04-23 10:01:41.000000000 +0200
|
||||
+++ 2007-05-14/xen/arch/x86/hvm/svm/x86_64/exits.S 2007-05-14 14:33:08.000000000 +0200
|
||||
@@ -85,7 +85,11 @@
|
||||
popq %r10; \
|
||||
popq %r9; \
|
||||
popq %r8; \
|
||||
- popq %rax; \
|
||||
+ /* \
|
||||
+ * Discard %rax, we need to have vmcb address in there. \
|
||||
+ * Don't worry, RAX is restored through the VMRUN instruction. \
|
||||
+ */ \
|
||||
+ addq $8, %rsp; \
|
||||
popq %rcx; \
|
||||
popq %rdx; \
|
||||
popq %rsi; \
|
||||
@@ -100,68 +104,54 @@
|
||||
|
||||
ENTRY(svm_asm_do_resume)
|
||||
GET_CURRENT(%rbx)
|
||||
+.Lresume:
|
||||
cli # tests must not race interrupts
|
||||
movl VCPU_processor(%rbx),%eax
|
||||
shl $IRQSTAT_shift, %rax
|
||||
leaq irq_stat(%rip), %rdx
|
||||
- testl $~0, (%rdx, %rax, 1)
|
||||
- jnz svm_process_softirqs
|
||||
+ cmpl $0, (%rdx, %rax)
|
||||
+ jne svm_process_softirqs
|
||||
call svm_intr_assist
|
||||
call svm_load_cr2
|
||||
|
||||
CLGI
|
||||
sti
|
||||
- GET_CURRENT(%rbx)
|
||||
movq VCPU_svm_vmcb(%rbx), %rcx
|
||||
movq UREGS_rax(%rsp), %rax
|
||||
+ movl VCPU_processor(%rbx), %edx
|
||||
movq %rax, VMCB_rax(%rcx)
|
||||
leaq root_vmcb_pa(%rip), %rax
|
||||
- movl VCPU_processor(%rbx), %ecx
|
||||
- movq (%rax,%rcx,8), %rax
|
||||
+ movq (%rax,%rdx,8), %rax
|
||||
VMSAVE
|
||||
|
||||
movq VCPU_svm_vmcb_pa(%rbx), %rax
|
||||
- popq %r15
|
||||
- popq %r14
|
||||
- popq %r13
|
||||
- popq %r12
|
||||
- popq %rbp
|
||||
- popq %rbx
|
||||
- popq %r11
|
||||
- popq %r10
|
||||
- popq %r9
|
||||
- popq %r8
|
||||
- /*
|
||||
- * Skip %rax, we need to have vmcb address in there.
|
||||
- * Don't worry, RAX is restored through the VMRUN instruction.
|
||||
- */
|
||||
- addq $8, %rsp
|
||||
- popq %rcx
|
||||
- popq %rdx
|
||||
- popq %rsi
|
||||
- popq %rdi
|
||||
- addq $(NR_SKIPPED_REGS*8), %rsp
|
||||
+ HVM_RESTORE_ALL_NOSEGREGS
|
||||
|
||||
VMLOAD
|
||||
VMRUN
|
||||
VMSAVE
|
||||
+
|
||||
HVM_SAVE_ALL_NOSEGREGS
|
||||
|
||||
GET_CURRENT(%rbx)
|
||||
- leaq root_vmcb_pa(%rip), %rax
|
||||
movl VCPU_processor(%rbx), %ecx
|
||||
+ leaq root_vmcb_pa(%rip), %rax
|
||||
+ movq VCPU_svm_vmcb(%rbx), %rdx
|
||||
movq (%rax,%rcx,8), %rax
|
||||
VMLOAD
|
||||
+ movq VMCB_rax(%rdx), %rax
|
||||
|
||||
STGI
|
||||
.globl svm_stgi_label;
|
||||
svm_stgi_label:
|
||||
+
|
||||
+ movq %rax, UREGS_rax(%rsp)
|
||||
movq %rsp,%rdi
|
||||
call svm_vmexit_handler
|
||||
- jmp svm_asm_do_resume
|
||||
+ jmp .Lresume
|
||||
|
||||
ALIGN
|
||||
svm_process_softirqs:
|
||||
sti
|
||||
call do_softirq
|
||||
- jmp svm_asm_do_resume
|
||||
+ jmp .Lresume
|
@ -1,9 +1,9 @@
|
||||
Index: xen-unstable/xen/drivers/video/vga.c
|
||||
Index: xen-3.1-testing/xen/drivers/video/vga.c
|
||||
===================================================================
|
||||
--- xen-unstable.orig/xen/drivers/video/vga.c
|
||||
+++ xen-unstable/xen/drivers/video/vga.c
|
||||
@@ -585,6 +585,8 @@ void vga_init(void)
|
||||
vgacon_keep = 1;
|
||||
--- xen-3.1-testing.orig/xen/drivers/video/vga.c
|
||||
+++ xen-3.1-testing/xen/drivers/video/vga.c
|
||||
@@ -587,6 +587,8 @@ void vga_init(void)
|
||||
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] != '-' )
|
||||
|
@ -1,7 +1,7 @@
|
||||
Index: xen-unstable/xen/drivers/video/vga.c
|
||||
Index: 2007-02-07/xen/drivers/video/vga.c
|
||||
===================================================================
|
||||
--- xen-unstable.orig/xen/drivers/video/vga.c
|
||||
+++ xen-unstable/xen/drivers/video/vga.c
|
||||
--- 2007-02-07.orig/xen/drivers/video/vga.c 2007-01-15 09:10:11.000000000 +0100
|
||||
+++ 2007-02-07/xen/drivers/video/vga.c 2007-02-07 16:31:41.000000000 +0100
|
||||
@@ -556,7 +556,6 @@ static int vga_load_font(const struct fo
|
||||
*/
|
||||
|
||||
@ -27,8 +27,8 @@ Index: xen-unstable/xen/drivers/video/vga.c
|
||||
+ 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] != '-' )
|
||||
@@ -623,21 +625,48 @@ void vga_init(void)
|
||||
}
|
||||
@@ -621,21 +623,48 @@ void vga_init(void)
|
||||
/* Disable cursor. */
|
||||
vga_wcrt(vgabase, VGA_CRTC_CURSOR_START, 0x20);
|
||||
|
||||
@ -82,7 +82,7 @@ Index: xen-unstable/xen/drivers/video/vga.c
|
||||
|
||||
static void put_newline(void)
|
||||
{
|
||||
@@ -655,14 +684,25 @@ static void put_newline(void)
|
||||
@@ -653,14 +682,25 @@ static void put_newline(void)
|
||||
|
||||
void vga_putchar(int c)
|
||||
{
|
||||
|
78
vmx-no-cstar.patch
Normal file
78
vmx-no-cstar.patch
Normal file
@ -0,0 +1,78 @@
|
||||
Index: 2007-05-14/xen/arch/x86/hvm/vmx/vmx.c
|
||||
===================================================================
|
||||
--- 2007-05-14.orig/xen/arch/x86/hvm/vmx/vmx.c 2007-05-14 14:28:19.000000000 +0200
|
||||
+++ 2007-05-14/xen/arch/x86/hvm/vmx/vmx.c 2007-05-14 14:33:24.000000000 +0200
|
||||
@@ -88,8 +88,7 @@ static DEFINE_PER_CPU(struct vmx_msr_sta
|
||||
|
||||
static u32 msr_index[VMX_MSR_COUNT] =
|
||||
{
|
||||
- MSR_LSTAR, MSR_STAR, MSR_CSTAR,
|
||||
- MSR_SYSCALL_MASK
|
||||
+ MSR_LSTAR, MSR_STAR, MSR_SYSCALL_MASK
|
||||
};
|
||||
|
||||
static void vmx_save_host_msrs(void)
|
||||
@@ -147,7 +146,7 @@ static inline int long_mode_do_msr_read(
|
||||
break;
|
||||
|
||||
case MSR_CSTAR:
|
||||
- msr_content = guest_msr_state->msrs[VMX_INDEX_MSR_CSTAR];
|
||||
+ msr_content = v->arch.hvm_vmx.cstar;
|
||||
break;
|
||||
|
||||
case MSR_SYSCALL_MASK:
|
||||
@@ -250,7 +249,8 @@ static inline int long_mode_do_msr_write
|
||||
case MSR_CSTAR:
|
||||
if ( !is_canonical_address(msr_content) )
|
||||
goto uncanonical_address;
|
||||
- WRITE_MSR(CSTAR);
|
||||
+ v->arch.hvm_vmx.cstar = msr_content;
|
||||
+ break;
|
||||
|
||||
case MSR_SYSCALL_MASK:
|
||||
WRITE_MSR(SYSCALL_MASK);
|
||||
@@ -730,12 +730,12 @@ static void vmx_save_cpu_state(struct vc
|
||||
unsigned long guest_flags = guest_state->flags;
|
||||
|
||||
data->shadow_gs = v->arch.hvm_vmx.shadow_gs;
|
||||
+ data->msr_cstar = v->arch.hvm_vmx.cstar;
|
||||
|
||||
/* save msrs */
|
||||
data->msr_flags = guest_flags;
|
||||
data->msr_lstar = guest_state->msrs[VMX_INDEX_MSR_LSTAR];
|
||||
data->msr_star = guest_state->msrs[VMX_INDEX_MSR_STAR];
|
||||
- data->msr_cstar = guest_state->msrs[VMX_INDEX_MSR_CSTAR];
|
||||
data->msr_syscall_mask = guest_state->msrs[VMX_INDEX_MSR_SYSCALL_MASK];
|
||||
#endif
|
||||
|
||||
@@ -755,9 +755,9 @@ static void vmx_load_cpu_state(struct vc
|
||||
guest_state->flags = data->msr_flags;
|
||||
guest_state->msrs[VMX_INDEX_MSR_LSTAR] = data->msr_lstar;
|
||||
guest_state->msrs[VMX_INDEX_MSR_STAR] = data->msr_star;
|
||||
- guest_state->msrs[VMX_INDEX_MSR_CSTAR] = data->msr_cstar;
|
||||
guest_state->msrs[VMX_INDEX_MSR_SYSCALL_MASK] = data->msr_syscall_mask;
|
||||
|
||||
+ v->arch.hvm_vmx.cstar = data->msr_cstar;
|
||||
v->arch.hvm_vmx.shadow_gs = data->shadow_gs;
|
||||
#endif
|
||||
|
||||
Index: 2007-05-14/xen/include/asm-x86/hvm/vmx/vmcs.h
|
||||
===================================================================
|
||||
--- 2007-05-14.orig/xen/include/asm-x86/hvm/vmx/vmcs.h 2007-05-14 14:28:19.000000000 +0200
|
||||
+++ 2007-05-14/xen/include/asm-x86/hvm/vmx/vmcs.h 2007-05-14 14:33:24.000000000 +0200
|
||||
@@ -37,7 +37,6 @@ struct vmcs_struct {
|
||||
enum {
|
||||
VMX_INDEX_MSR_LSTAR = 0,
|
||||
VMX_INDEX_MSR_STAR,
|
||||
- VMX_INDEX_MSR_CSTAR,
|
||||
VMX_INDEX_MSR_SYSCALL_MASK,
|
||||
|
||||
VMX_MSR_COUNT
|
||||
@@ -77,6 +76,7 @@ struct arch_vmx_struct {
|
||||
#ifdef __x86_64__
|
||||
struct vmx_msr_state msr_state;
|
||||
unsigned long shadow_gs;
|
||||
+ unsigned long cstar;
|
||||
#endif
|
||||
unsigned long efer;
|
||||
unsigned long vmxassist_enabled:1;
|
133
vnc-i18n-keys.diff
Normal file
133
vnc-i18n-keys.diff
Normal file
@ -0,0 +1,133 @@
|
||||
Index: xen-3.1-testing/tools/ioemu/sdl_keysym.h
|
||||
===================================================================
|
||||
--- xen-3.1-testing.orig/tools/ioemu/sdl_keysym.h
|
||||
+++ xen-3.1-testing/tools/ioemu/sdl_keysym.h
|
||||
@@ -274,5 +274,27 @@ static name2keysym_t name2keysym[]={
|
||||
{"Pause", SDLK_PAUSE},
|
||||
{"Escape", SDLK_ESCAPE},
|
||||
|
||||
+ /* dead keys */
|
||||
+{"dead_grave", 0xfe50},
|
||||
+{"dead_acute", 0xfe51},
|
||||
+{"dead_circumflex", 0xfe52},
|
||||
+{"dead_tilde", 0xfe53},
|
||||
+{"dead_macron", 0xfe54},
|
||||
+{"dead_brev", 0xfe55},
|
||||
+{"dead_abovedot", 0xfe56},
|
||||
+{"dead_diaeresis", 0xfe57},
|
||||
+{"dead_abovering", 0xfe58},
|
||||
+{"dead_doubleacute", 0xfe59},
|
||||
+{"dead_caron", 0xfe5a},
|
||||
+{"dead_cedilla", 0xfe5b},
|
||||
+{"dead_ogonek", 0xfe5c},
|
||||
+{"dead_iota", 0xfe5d},
|
||||
+{"dead_voiced_sound", 0xfe5e},
|
||||
+{"dead_semivoiced_sound", 0xfe5f},
|
||||
+{"dead_belowdot", 0xfe60},
|
||||
+{"dead_hook", 0xfe61},
|
||||
+{"dead_horn", 0xfe62},
|
||||
+
|
||||
{0,0},
|
||||
};
|
||||
+
|
||||
Index: xen-3.1-testing/tools/ioemu/vnc_keysym.h
|
||||
===================================================================
|
||||
--- xen-3.1-testing.orig/tools/ioemu/vnc_keysym.h
|
||||
+++ xen-3.1-testing/tools/ioemu/vnc_keysym.h
|
||||
@@ -291,10 +291,34 @@ static name2keysym_t name2keysym[]={
|
||||
{"BackApostrophe", 0xff21},
|
||||
{"Muhenkan", 0xff22},
|
||||
{"Katakana", 0xff25},
|
||||
-{"Zenkaku_Hankaku", 0xff29},
|
||||
+{"Hankaku", 0xff29},
|
||||
+{"Zenkaku_Hankaku", 0xff2a},
|
||||
{"Henkan_Mode_Real", 0xff23},
|
||||
{"Henkan_Mode_Ultra", 0xff3e},
|
||||
{"backslash_ja", 0xffa5},
|
||||
|
||||
+ /* dead keys */
|
||||
+{"dead_grave", 0xfe50},
|
||||
+{"dead_acute", 0xfe51},
|
||||
+{"dead_circumflex", 0xfe52},
|
||||
+{"dead_tilde", 0xfe53},
|
||||
+{"dead_macron", 0xfe54},
|
||||
+{"dead_brev", 0xfe55},
|
||||
+{"dead_abovedot", 0xfe56},
|
||||
+{"dead_diaeresis", 0xfe57},
|
||||
+{"dead_abovering", 0xfe58},
|
||||
+{"dead_doubleacute", 0xfe59},
|
||||
+{"dead_caron", 0xfe5a},
|
||||
+{"dead_cedilla", 0xfe5b},
|
||||
+{"dead_ogonek", 0xfe5c},
|
||||
+{"dead_iota", 0xfe5d},
|
||||
+{"dead_voiced_sound", 0xfe5e},
|
||||
+{"dead_semivoiced_sound", 0xfe5f},
|
||||
+{"dead_belowdot", 0xfe60},
|
||||
+{"dead_hook", 0xfe61},
|
||||
+{"dead_horn", 0xfe62},
|
||||
+
|
||||
+
|
||||
{0,0},
|
||||
};
|
||||
+
|
||||
Index: xen-3.1-testing/tools/python/xen/xend/XendOptions.py
|
||||
===================================================================
|
||||
--- xen-3.1-testing.orig/tools/python/xen/xend/XendOptions.py
|
||||
+++ xen-3.1-testing/tools/python/xen/xend/XendOptions.py
|
||||
@@ -278,6 +278,9 @@ class XendOptions:
|
||||
return self.get_config_string('vncpasswd',
|
||||
self.vncpasswd_default)
|
||||
|
||||
+ def get_keymap(self):
|
||||
+ return self.get_config_value('keymap', None)
|
||||
+
|
||||
class XendOptionsFile(XendOptions):
|
||||
|
||||
"""Default path to the config file."""
|
||||
Index: xen-3.1-testing/tools/python/xen/xend/XendConfig.py
|
||||
===================================================================
|
||||
--- xen-3.1-testing.orig/tools/python/xen/xend/XendConfig.py
|
||||
+++ xen-3.1-testing/tools/python/xen/xend/XendConfig.py
|
||||
@@ -27,6 +27,7 @@ from xen.xend.XendError import VmError
|
||||
from xen.xend.XendDevices import XendDevices
|
||||
from xen.xend.PrettyPrint import prettyprintstring
|
||||
from xen.xend.XendConstants import DOM_STATE_HALTED
|
||||
+from xen.xend import XendOptions
|
||||
|
||||
log = logging.getLogger("xend.XendConfig")
|
||||
log.setLevel(logging.WARN)
|
||||
@@ -389,6 +390,8 @@ class XendConfig(dict):
|
||||
self['name_label'] = 'Domain-' + self['uuid']
|
||||
|
||||
def _platform_sanity_check(self):
|
||||
+ if 'keymap' not in self['platform'] and XendOptions.instance().get_keymap():
|
||||
+ self['platform']['keymap'] = XendOptions.instance().get_keymap()
|
||||
if self.is_hvm():
|
||||
if 'device_model' not in self['platform']:
|
||||
self['platform']['device_model'] = DEFAULT_DM
|
||||
Index: xen-3.1-testing/tools/examples/xend-config.sxp
|
||||
===================================================================
|
||||
--- xen-3.1-testing.orig/tools/examples/xend-config.sxp
|
||||
+++ xen-3.1-testing/tools/examples/xend-config.sxp
|
||||
@@ -197,3 +197,7 @@
|
||||
# The default password for VNC console on HVM domain.
|
||||
# Empty string is no authentication.
|
||||
(vncpasswd '')
|
||||
+
|
||||
+# The default keymap to use for the VM's virtual keyboard.
|
||||
+#(keymap 'en-us')
|
||||
+
|
||||
Index: xen-3.1-testing/tools/python/xen/xend/XendDomainInfo.py
|
||||
===================================================================
|
||||
--- xen-3.1-testing.orig/tools/python/xen/xend/XendDomainInfo.py
|
||||
+++ xen-3.1-testing/tools/python/xen/xend/XendDomainInfo.py
|
||||
@@ -1336,6 +1336,9 @@ class XendDomainInfo:
|
||||
if devclass in XendDevices.valid_devices():
|
||||
log.info("createDevice: %s : %s" % (devclass, scrub_password(config)))
|
||||
dev_uuid = config.get('uuid')
|
||||
+ if 'keymap' not in config:
|
||||
+ if 'keymap' in self.info['platform']:
|
||||
+ config['keymap'] = self.info['platform']['keymap']
|
||||
devid = self._createDevice(devclass, config)
|
||||
|
||||
# store devid in XendConfig for caching reasons
|
@ -1,8 +1,8 @@
|
||||
Index: xen-3.0.5-testing/xen/arch/x86/x86_32/entry.S
|
||||
Index: 2007-04-27/xen/arch/x86/x86_32/entry.S
|
||||
===================================================================
|
||||
--- xen-3.0.5-testing.orig/xen/arch/x86/x86_32/entry.S
|
||||
+++ xen-3.0.5-testing/xen/arch/x86/x86_32/entry.S
|
||||
@@ -386,21 +386,33 @@ ring1: /* obtain ss/esp from oldss/olde
|
||||
--- 2007-04-27.orig/xen/arch/x86/x86_32/entry.S 2007-04-27 09:50:12.000000000 +0200
|
||||
+++ 2007-04-27/xen/arch/x86/x86_32/entry.S 2007-04-27 09:57:47.000000000 +0200
|
||||
@@ -387,21 +387,33 @@ ring1: /* obtain ss/esp from oldss/olde
|
||||
movl %eax,UREGS_eip+4(%esp)
|
||||
ret
|
||||
.section __ex_table,"a"
|
||||
@ -46,10 +46,10 @@ Index: xen-3.0.5-testing/xen/arch/x86/x86_32/entry.S
|
||||
domain_crash_synchronous:
|
||||
pushl $domain_crash_synchronous_string
|
||||
call printk
|
||||
Index: xen-3.0.5-testing/xen/arch/x86/x86_64/entry.S
|
||||
Index: 2007-04-27/xen/arch/x86/x86_64/entry.S
|
||||
===================================================================
|
||||
--- xen-3.0.5-testing.orig/xen/arch/x86/x86_64/entry.S
|
||||
+++ xen-3.0.5-testing/xen/arch/x86/x86_64/entry.S
|
||||
--- 2007-04-27.orig/xen/arch/x86/x86_64/entry.S 2007-04-27 09:31:40.000000000 +0200
|
||||
+++ 2007-04-27/xen/arch/x86/x86_64/entry.S 2007-04-27 09:57:47.000000000 +0200
|
||||
@@ -338,17 +338,30 @@ create_bounce_frame:
|
||||
movq %rax,UREGS_rip+8(%rsp)
|
||||
ret
|
||||
|
276
x86-nmi-inject.patch
Normal file
276
x86-nmi-inject.patch
Normal file
@ -0,0 +1,276 @@
|
||||
Index: 2007-05-14/xen/arch/x86/physdev.c
|
||||
===================================================================
|
||||
--- 2007-05-14.orig/xen/arch/x86/physdev.c 2007-04-23 10:01:42.000000000 +0200
|
||||
+++ 2007-05-14/xen/arch/x86/physdev.c 2007-05-14 14:40:35.000000000 +0200
|
||||
@@ -143,6 +143,56 @@ ret_t do_physdev_op(int cmd, XEN_GUEST_H
|
||||
break;
|
||||
}
|
||||
|
||||
+ case PHYSDEVOP_send_nmi: {
|
||||
+ struct physdev_send_nmi send_nmi;
|
||||
+ struct domain *d;
|
||||
+
|
||||
+ ret = -EFAULT;
|
||||
+ if ( copy_from_guest(&send_nmi, arg, 1) != 0 )
|
||||
+ break;
|
||||
+
|
||||
+ ret = -EPERM;
|
||||
+ if ( send_nmi.domain == DOMID_SELF )
|
||||
+ d = rcu_lock_current_domain();
|
||||
+ else if ( IS_PRIV(current->domain) )
|
||||
+ d = rcu_lock_domain_by_id(send_nmi.domain);
|
||||
+ else
|
||||
+ break;
|
||||
+ ret = -ESRCH;
|
||||
+ if ( d == NULL )
|
||||
+ break;
|
||||
+
|
||||
+ switch ( send_nmi.vcpu )
|
||||
+ {
|
||||
+ struct vcpu *v;
|
||||
+
|
||||
+ case XEN_SEND_NMI_ALL:
|
||||
+ case XEN_SEND_NMI_ALL_BUT_SELF:
|
||||
+ for_each_vcpu(d, v)
|
||||
+ {
|
||||
+ if ( (send_nmi.vcpu == XEN_SEND_NMI_ALL || v != current) &&
|
||||
+ !xchg(&v->nmi_pending, 1) )
|
||||
+ vcpu_kick(v);
|
||||
+ }
|
||||
+ ret = 0;
|
||||
+ break;
|
||||
+ case 0 ... MAX_VIRT_CPUS - 1:
|
||||
+ if ( (v = d->vcpu[send_nmi.vcpu]) != NULL )
|
||||
+ {
|
||||
+ if ( !xchg(&v->nmi_pending, 1) )
|
||||
+ vcpu_kick(v);
|
||||
+ ret = 0;
|
||||
+ }
|
||||
+ break;
|
||||
+ default:
|
||||
+ ret = EINVAL;
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ rcu_unlock_domain(d);
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
default:
|
||||
ret = -ENOSYS;
|
||||
break;
|
||||
Index: 2007-05-14/xen/arch/x86/traps.c
|
||||
===================================================================
|
||||
--- 2007-05-14.orig/xen/arch/x86/traps.c 2007-05-14 14:40:32.000000000 +0200
|
||||
+++ 2007-05-14/xen/arch/x86/traps.c 2007-05-14 14:40:35.000000000 +0200
|
||||
@@ -2517,6 +2517,12 @@ long do_set_trap_table(XEN_GUEST_HANDLE(
|
||||
if ( cur.address == 0 )
|
||||
break;
|
||||
|
||||
+ if ( cur.vector == 2 && !TI_GET_IF(&cur) )
|
||||
+ {
|
||||
+ rc = -EINVAL;
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
fixup_guest_code_selector(current->domain, cur.cs);
|
||||
|
||||
memcpy(&dst[cur.vector], &cur, sizeof(cur));
|
||||
Index: 2007-05-14/xen/arch/x86/x86_32/asm-offsets.c
|
||||
===================================================================
|
||||
--- 2007-05-14.orig/xen/arch/x86/x86_32/asm-offsets.c 2007-05-14 14:40:29.000000000 +0200
|
||||
+++ 2007-05-14/xen/arch/x86/x86_32/asm-offsets.c 2007-05-14 14:40:35.000000000 +0200
|
||||
@@ -68,6 +68,7 @@ void __dummy__(void)
|
||||
OFFSET(VCPU_guest_context_flags, struct vcpu, arch.guest_context.flags);
|
||||
OFFSET(VCPU_arch_guest_fpu_ctxt, struct vcpu, arch.guest_context.fpu_ctxt);
|
||||
OFFSET(VCPU_nmi_addr, struct vcpu, nmi_addr);
|
||||
+ OFFSET(VCPU_nmi_cs, struct vcpu, arch.guest_context.trap_ctxt[2].cs);
|
||||
OFFSET(VCPU_nmi_pending, struct vcpu, nmi_pending);
|
||||
OFFSET(VCPU_nmi_masked, struct vcpu, nmi_masked);
|
||||
DEFINE(_VGCF_failsafe_disables_events, _VGCF_failsafe_disables_events);
|
||||
Index: 2007-05-14/xen/arch/x86/x86_32/entry.S
|
||||
===================================================================
|
||||
--- 2007-05-14.orig/xen/arch/x86/x86_32/entry.S 2007-05-03 09:45:09.000000000 +0200
|
||||
+++ 2007-05-14/xen/arch/x86/x86_32/entry.S 2007-05-14 14:40:35.000000000 +0200
|
||||
@@ -263,14 +263,15 @@ process_nmi:
|
||||
testb $1,VCPU_nmi_masked(%ebx)
|
||||
jnz test_guest_events
|
||||
movb $0,VCPU_nmi_pending(%ebx)
|
||||
- movl VCPU_nmi_addr(%ebx),%eax
|
||||
+ movzwl VCPU_nmi_cs(%ebx),%eax
|
||||
+ movl VCPU_nmi_addr(%ebx),%ecx
|
||||
test %eax,%eax
|
||||
jz test_guest_events
|
||||
movb $1,VCPU_nmi_masked(%ebx)
|
||||
sti
|
||||
leal VCPU_trap_bounce(%ebx),%edx
|
||||
- movl %eax,TRAPBOUNCE_eip(%edx)
|
||||
- movw $FLAT_KERNEL_CS,TRAPBOUNCE_cs(%edx)
|
||||
+ movl %ecx,TRAPBOUNCE_eip(%edx)
|
||||
+ movw %ax,TRAPBOUNCE_cs(%edx)
|
||||
movb $TBF_INTERRUPT,TRAPBOUNCE_flags(%edx)
|
||||
call create_bounce_frame
|
||||
jmp test_all_events
|
||||
Index: 2007-05-14/xen/arch/x86/x86_64/asm-offsets.c
|
||||
===================================================================
|
||||
--- 2007-05-14.orig/xen/arch/x86/x86_64/asm-offsets.c 2007-05-14 14:40:29.000000000 +0200
|
||||
+++ 2007-05-14/xen/arch/x86/x86_64/asm-offsets.c 2007-05-14 14:40:35.000000000 +0200
|
||||
@@ -77,6 +77,7 @@ void __dummy__(void)
|
||||
OFFSET(VCPU_guest_context_flags, struct vcpu, arch.guest_context.flags);
|
||||
OFFSET(VCPU_arch_guest_fpu_ctxt, struct vcpu, arch.guest_context.fpu_ctxt);
|
||||
OFFSET(VCPU_nmi_addr, struct vcpu, nmi_addr);
|
||||
+ OFFSET(VCPU_nmi_cs, struct vcpu, arch.guest_context.trap_ctxt[2].cs);
|
||||
OFFSET(VCPU_nmi_pending, struct vcpu, nmi_pending);
|
||||
OFFSET(VCPU_nmi_masked, struct vcpu, nmi_masked);
|
||||
DEFINE(_VGCF_failsafe_disables_events, _VGCF_failsafe_disables_events);
|
||||
Index: 2007-05-14/xen/arch/x86/x86_64/compat/entry.S
|
||||
===================================================================
|
||||
--- 2007-05-14.orig/xen/arch/x86/x86_64/compat/entry.S 2007-05-03 09:45:09.000000000 +0200
|
||||
+++ 2007-05-14/xen/arch/x86/x86_64/compat/entry.S 2007-05-14 14:40:35.000000000 +0200
|
||||
@@ -119,14 +119,15 @@ compat_process_nmi:
|
||||
testb $1,VCPU_nmi_masked(%rbx)
|
||||
jnz compat_test_guest_events
|
||||
movb $0,VCPU_nmi_pending(%rbx)
|
||||
- movl VCPU_nmi_addr(%rbx),%eax
|
||||
+ movzwl VCPU_nmi_cs(%rbx),%eax
|
||||
+ movl VCPU_nmi_addr(%rbx),%ecx
|
||||
testl %eax,%eax
|
||||
jz compat_test_guest_events
|
||||
movb $1,VCPU_nmi_masked(%rbx)
|
||||
sti
|
||||
leaq VCPU_trap_bounce(%rbx),%rdx
|
||||
- movl %eax,TRAPBOUNCE_eip(%rdx)
|
||||
- movw $FLAT_COMPAT_KERNEL_CS,TRAPBOUNCE_cs(%rdx)
|
||||
+ movl %ecx,TRAPBOUNCE_eip(%rdx)
|
||||
+ movw %ax,TRAPBOUNCE_cs(%rdx)
|
||||
movb $TBF_INTERRUPT,TRAPBOUNCE_flags(%rdx)
|
||||
call compat_create_bounce_frame
|
||||
jmp compat_test_all_events
|
||||
Index: 2007-05-14/xen/arch/x86/x86_64/compat/traps.c
|
||||
===================================================================
|
||||
--- 2007-05-14.orig/xen/arch/x86/x86_64/compat/traps.c 2007-04-23 10:01:42.000000000 +0200
|
||||
+++ 2007-05-14/xen/arch/x86/x86_64/compat/traps.c 2007-05-14 14:40:35.000000000 +0200
|
||||
@@ -288,6 +288,12 @@ int compat_set_trap_table(XEN_GUEST_HAND
|
||||
if ( cur.address == 0 )
|
||||
break;
|
||||
|
||||
+ if ( cur.vector == 2 && !TI_GET_IF(&cur) )
|
||||
+ {
|
||||
+ rc = -EINVAL;
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
fixup_guest_code_selector(current->domain, cur.cs);
|
||||
|
||||
XLAT_trap_info(dst + cur.vector, &cur);
|
||||
Index: 2007-05-14/xen/arch/x86/x86_64/physdev.c
|
||||
===================================================================
|
||||
--- 2007-05-14.orig/xen/arch/x86/x86_64/physdev.c 2007-04-23 10:01:43.000000000 +0200
|
||||
+++ 2007-05-14/xen/arch/x86/x86_64/physdev.c 2007-05-14 14:40:35.000000000 +0200
|
||||
@@ -30,6 +30,10 @@
|
||||
#define physdev_irq_status_query compat_physdev_irq_status_query
|
||||
#define physdev_irq_status_query_t physdev_irq_status_query_compat_t
|
||||
|
||||
+#define xen_physdev_send_nmi physdev_send_nmi
|
||||
+CHECK_physdev_send_nmi;
|
||||
+#undef xen_physdev_send_nmi
|
||||
+
|
||||
#define COMPAT
|
||||
#undef guest_handle_okay
|
||||
#define guest_handle_okay compat_handle_okay
|
||||
Index: 2007-05-14/xen/common/kernel.c
|
||||
===================================================================
|
||||
--- 2007-05-14.orig/xen/common/kernel.c 2007-05-14 14:40:27.000000000 +0200
|
||||
+++ 2007-05-14/xen/common/kernel.c 2007-05-14 14:40:35.000000000 +0200
|
||||
@@ -246,16 +246,20 @@ long register_guest_nmi_callback(unsigne
|
||||
struct vcpu *v = current;
|
||||
struct domain *d = current->domain;
|
||||
|
||||
- if ( (d->domain_id != 0) || (v->vcpu_id != 0) )
|
||||
- return -EINVAL;
|
||||
-
|
||||
v->nmi_addr = address;
|
||||
#ifdef CONFIG_X86
|
||||
+ v->arch.guest_context.trap_ctxt[2].vector = 2;
|
||||
+ v->arch.guest_context.trap_ctxt[2].flags = 0;
|
||||
+ TI_SET_IF(v->arch.guest_context.trap_ctxt + 2, 1);
|
||||
+ v->arch.guest_context.trap_ctxt[2].cs =
|
||||
+ !is_pv_32on64_domain(d) ? FLAT_KERNEL_CS : FLAT_COMPAT_KERNEL_CS;
|
||||
+
|
||||
/*
|
||||
* If no handler was registered we can 'lose the NMI edge'. Re-assert it
|
||||
* now.
|
||||
*/
|
||||
- if ( arch_get_nmi_reason(d) != 0 )
|
||||
+ if ( d->domain_id == 0 && v->vcpu_id == 0 &&
|
||||
+ arch_get_nmi_reason(d) != 0 )
|
||||
v->nmi_pending = 1;
|
||||
#endif
|
||||
|
||||
@@ -266,6 +270,11 @@ long unregister_guest_nmi_callback(void)
|
||||
{
|
||||
struct vcpu *v = current;
|
||||
|
||||
+#ifdef CONFIG_X86
|
||||
+ v->arch.guest_context.trap_ctxt[2].cs = 0;
|
||||
+ v->arch.guest_context.trap_ctxt[2].vector = 0;
|
||||
+ v->arch.guest_context.trap_ctxt[2].flags = 0;
|
||||
+#endif
|
||||
v->nmi_addr = 0;
|
||||
|
||||
return 0;
|
||||
Index: 2007-05-14/xen/include/public/physdev.h
|
||||
===================================================================
|
||||
--- 2007-05-14.orig/xen/include/public/physdev.h 2007-04-23 10:01:47.000000000 +0200
|
||||
+++ 2007-05-14/xen/include/public/physdev.h 2007-05-14 14:40:35.000000000 +0200
|
||||
@@ -119,6 +119,22 @@ typedef struct physdev_irq physdev_irq_t
|
||||
DEFINE_XEN_GUEST_HANDLE(physdev_irq_t);
|
||||
|
||||
/*
|
||||
+ * Allocate or free a physical upcall vector for the specified IRQ line.
|
||||
+ * @arg == pointer to physdev_irq structure.
|
||||
+ */
|
||||
+#define PHYSDEVOP_send_nmi 13
|
||||
+struct physdev_send_nmi {
|
||||
+ /* IN */
|
||||
+ domid_t domain;
|
||||
+ uint32_t vcpu;
|
||||
+};
|
||||
+typedef struct physdev_send_nmi physdev_send_nmi_t;
|
||||
+DEFINE_XEN_GUEST_HANDLE(physdev_send_nmi_t);
|
||||
+
|
||||
+#define XEN_SEND_NMI_ALL (~(uint32_t)0)
|
||||
+#define XEN_SEND_NMI_ALL_BUT_SELF (~(uint32_t)1)
|
||||
+
|
||||
+/*
|
||||
* Argument to physdev_op_compat() hypercall. Superceded by new physdev_op()
|
||||
* hypercall since 0x00030202.
|
||||
*/
|
||||
Index: 2007-05-14/xen/include/xen/sched.h
|
||||
===================================================================
|
||||
--- 2007-05-14.orig/xen/include/xen/sched.h 2007-05-03 09:45:09.000000000 +0200
|
||||
+++ 2007-05-14/xen/include/xen/sched.h 2007-05-14 14:40:35.000000000 +0200
|
||||
@@ -128,7 +128,11 @@ struct vcpu
|
||||
/* Bitmask of CPUs on which this VCPU may run. */
|
||||
cpumask_t cpu_affinity;
|
||||
|
||||
+#ifndef CONFIG_X86
|
||||
unsigned long nmi_addr; /* NMI callback address. */
|
||||
+#else
|
||||
+# define nmi_addr arch.guest_context.trap_ctxt[2].address
|
||||
+#endif
|
||||
|
||||
/* Bitmask of CPUs which are holding onto this VCPU's state. */
|
||||
cpumask_t vcpu_dirty_cpumask;
|
||||
Index: 2007-05-14/xen/include/xlat.lst
|
||||
===================================================================
|
||||
--- 2007-05-14.orig/xen/include/xlat.lst 2007-05-03 09:45:09.000000000 +0200
|
||||
+++ 2007-05-14/xen/include/xlat.lst 2007-05-14 14:40:35.000000000 +0200
|
||||
@@ -35,6 +35,7 @@
|
||||
! memory_map memory.h
|
||||
! memory_reservation memory.h
|
||||
! translate_gpfn_list memory.h
|
||||
+? physdev_send_nmi physdev.h
|
||||
! sched_poll sched.h
|
||||
? sched_remote_shutdown sched.h
|
||||
? sched_shutdown sched.h
|
@ -1,8 +1,8 @@
|
||||
Index: 2007-01-31/xen/arch/x86/mm.c
|
||||
Index: 2007-05-14/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(
|
||||
--- 2007-05-14.orig/xen/arch/x86/mm.c 2007-05-14 14:40:28.000000000 +0200
|
||||
+++ 2007-05-14/xen/arch/x86/mm.c 2007-05-14 14:40:43.000000000 +0200
|
||||
@@ -3499,6 +3499,7 @@ static int ptwr_emulated_cmpxchg(
|
||||
container_of(ctxt, struct ptwr_emulate_ctxt, ctxt));
|
||||
}
|
||||
|
||||
@ -10,7 +10,7 @@ Index: 2007-01-31/xen/arch/x86/mm.c
|
||||
static int ptwr_emulated_cmpxchg8b(
|
||||
enum x86_segment seg,
|
||||
unsigned long offset,
|
||||
@@ -3260,13 +3261,16 @@ static int ptwr_emulated_cmpxchg8b(
|
||||
@@ -3514,13 +3515,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));
|
||||
}
|
||||
@ -28,11 +28,11 @@ Index: 2007-01-31/xen/arch/x86/mm.c
|
||||
};
|
||||
|
||||
/* Write page fault handler: check if guest is trying to modify a PTE. */
|
||||
Index: 2007-01-31/xen/arch/x86/mm/shadow/common.c
|
||||
Index: 2007-05-14/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
|
||||
--- 2007-05-14.orig/xen/arch/x86/mm/shadow/common.c 2007-05-14 14:40:28.000000000 +0200
|
||||
+++ 2007-05-14/xen/arch/x86/mm/shadow/common.c 2007-05-14 14:40:43.000000000 +0200
|
||||
@@ -310,6 +310,7 @@ hvm_emulate_cmpxchg(enum x86_segment seg
|
||||
v, addr, old, new, bytes, sh_ctxt);
|
||||
}
|
||||
|
||||
@ -40,25 +40,11 @@ Index: 2007-01-31/xen/arch/x86/mm/shadow/common.c
|
||||
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(
|
||||
@@ -333,13 +334,16 @@ hvm_emulate_cmpxchg8b(enum x86_segment s
|
||||
return v->arch.paging.mode->shadow.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,
|
||||
@ -69,11 +55,10 @@ Index: 2007-01-31/xen/arch/x86/mm/shadow/common.c
|
||||
+#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,
|
||||
@@ -390,6 +394,7 @@ pv_emulate_cmpxchg(enum x86_segment seg,
|
||||
v, offset, old, new, bytes, sh_ctxt);
|
||||
}
|
||||
|
||||
@ -81,8 +66,8 @@ Index: 2007-01-31/xen/arch/x86/mm/shadow/common.c
|
||||
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(
|
||||
@@ -405,13 +410,16 @@ pv_emulate_cmpxchg8b(enum x86_segment se
|
||||
return v->arch.paging.mode->shadow.x86_emulate_cmpxchg8b(
|
||||
v, offset, old_lo, old_hi, new_lo, new_hi, sh_ctxt);
|
||||
}
|
||||
+#endif
|
||||
@ -99,11 +84,24 @@ Index: 2007-01-31/xen/arch/x86/mm/shadow/common.c
|
||||
};
|
||||
|
||||
struct x86_emulate_ops *shadow_init_emulation(
|
||||
Index: 2007-01-31/xen/arch/x86/mm/shadow/multi.c
|
||||
@@ -425,7 +433,12 @@ struct x86_emulate_ops *shadow_init_emul
|
||||
|
||||
if ( !is_hvm_vcpu(v) )
|
||||
{
|
||||
+#ifndef CONFIG_COMPAT
|
||||
sh_ctxt->ctxt.addr_size = sh_ctxt->ctxt.sp_size = BITS_PER_LONG;
|
||||
+#else
|
||||
+ sh_ctxt->ctxt.addr_size = sh_ctxt->ctxt.sp_size =
|
||||
+ !is_pv_32on64_vcpu(v) ? BITS_PER_LONG : COMPAT_BITS_PER_LONG;
|
||||
+#endif
|
||||
return &pv_shadow_emulator_ops;
|
||||
}
|
||||
|
||||
Index: 2007-05-14/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
|
||||
--- 2007-05-14.orig/xen/arch/x86/mm/shadow/multi.c 2007-05-14 14:40:28.000000000 +0200
|
||||
+++ 2007-05-14/xen/arch/x86/mm/shadow/multi.c 2007-05-14 14:40:43.000000000 +0200
|
||||
@@ -4025,7 +4025,8 @@ sh_x86_emulate_cmpxchg(struct vcpu *v, u
|
||||
return rv;
|
||||
}
|
||||
|
||||
@ -113,7 +111,7 @@ Index: 2007-01-31/xen/arch/x86/mm/shadow/multi.c
|
||||
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,
|
||||
@@ -4068,6 +4069,7 @@ sh_x86_emulate_cmpxchg8b(struct vcpu *v,
|
||||
shadow_audit_tables(v);
|
||||
return rv;
|
||||
}
|
||||
@ -121,21 +119,21 @@ Index: 2007-01-31/xen/arch/x86/mm/shadow/multi.c
|
||||
|
||||
|
||||
/**************************************************************************/
|
||||
@@ -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,
|
||||
@@ -4352,7 +4354,9 @@ struct paging_mode sh_paging_mode = {
|
||||
.shadow.detach_old_tables = sh_detach_old_tables,
|
||||
.shadow.x86_emulate_write = sh_x86_emulate_write,
|
||||
.shadow.x86_emulate_cmpxchg = sh_x86_emulate_cmpxchg,
|
||||
+#ifdef __i386__
|
||||
.x86_emulate_cmpxchg8b = sh_x86_emulate_cmpxchg8b,
|
||||
.shadow.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
|
||||
.shadow.make_monitor_table = sh_make_monitor_table,
|
||||
.shadow.destroy_monitor_table = sh_destroy_monitor_table,
|
||||
#if SHADOW_OPTIMIZATIONS & SHOPT_WRITABLE_HEURISTIC
|
||||
Index: 2007-05-14/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 @@
|
||||
--- 2007-05-14.orig/xen/arch/x86/x86_emulate.c 2007-04-23 10:01:43.000000000 +0200
|
||||
+++ 2007-05-14/xen/arch/x86/x86_emulate.c 2007-05-14 14:40:43.000000000 +0200
|
||||
@@ -30,6 +30,7 @@
|
||||
#include <xen/types.h>
|
||||
#include <xen/lib.h>
|
||||
#include <asm/regs.h>
|
||||
@ -143,223 +141,18 @@ Index: 2007-01-31/xen/arch/x86/x86_emulate.c
|
||||
#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;
|
||||
@@ -2336,58 +2337,63 @@ x86_emulate(
|
||||
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) )
|
||||
+ case 0xc7: /* Grp9 (cmpxchg{8,16}b) */
|
||||
generate_exception_if((modrm_reg & 7) != 1, EXC_UD);
|
||||
- if ( (rc = ops->read(ea.mem.seg, ea.mem.off+0, &old_lo, 4, ctxt)) ||
|
||||
- (rc = ops->read(ea.mem.seg, ea.mem.off+4, &old_hi, 4, ctxt)) )
|
||||
- goto done;
|
||||
- if ( (old_lo != _regs.eax) || (old_hi != _regs.edx) )
|
||||
- {
|
||||
@ -373,14 +166,14 @@ Index: 2007-01-31/xen/arch/x86/x86_emulate.c
|
||||
- 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,
|
||||
- if ( (rc = ops->cmpxchg8b(ea.mem.seg, ea.mem.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 )
|
||||
+
|
||||
+ if ( (rc = ops->read(ea.mem.seg, ea.mem.off, &old, 8, ctxt)) != 0 )
|
||||
goto done;
|
||||
- _regs.eflags |= EFLG_ZF;
|
||||
- }
|
||||
@ -389,7 +182,8 @@ Index: 2007-01-31/xen/arch/x86/x86_emulate.c
|
||||
-#elif defined(__x86_64__)
|
||||
- {
|
||||
- unsigned long old, new;
|
||||
- if ( (rc = ops->read(ea_seg, ea_off, &old, 8, ctxt)) != 0 )
|
||||
- generate_exception_if((modrm_reg & 7) != 1, EXC_UD);
|
||||
- if ( (rc = ops->read(ea.mem.seg, ea.mem.off, &old, 8, ctxt)) != 0 )
|
||||
- goto done;
|
||||
- if ( ((uint32_t)(old>>0) != (uint32_t)_regs.eax) ||
|
||||
- ((uint32_t)(old>>32) != (uint32_t)_regs.edx) )
|
||||
@ -407,22 +201,28 @@ Index: 2007-01-31/xen/arch/x86/x86_emulate.c
|
||||
+ else
|
||||
+ {
|
||||
+ new = (_regs.ecx<<32)|(uint32_t)_regs.ebx;
|
||||
+ if ( (rc = ops->cmpxchg(ea_seg, ea_off, old, new, 8, ctxt)) != 0 )
|
||||
+ if ( (rc = ops->cmpxchg(ea.mem.seg, ea.mem.off, old,
|
||||
+ new, 8, ctxt)) != 0 )
|
||||
+ goto done;
|
||||
+ _regs.eflags |= EFLG_ZF;
|
||||
+ }
|
||||
}
|
||||
+ else if ( !cpu_has_cmpxchg16b )
|
||||
+ generate_exception_if(1, EXC_UD);
|
||||
else
|
||||
+#endif
|
||||
{
|
||||
- new = (_regs.ecx<<32)|(uint32_t)_regs.ebx;
|
||||
- if ( (rc = ops->cmpxchg(ea_seg, ea_off, old, new, 8, ctxt)) != 0 )
|
||||
- if ( (rc = ops->cmpxchg(ea.mem.seg, ea.mem.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 ( (rc = ops->read(ea.mem.seg, ea.mem.off,
|
||||
+ &old_lo, sizeof(old_lo), ctxt)) ||
|
||||
+ (rc = ops->read(ea.mem.seg, ea.mem.off+sizeof(old_lo),
|
||||
+ &old_hi, sizeof(old_lo), ctxt)) )
|
||||
goto done;
|
||||
- _regs.eflags |= EFLG_ZF;
|
||||
+ if ( (old_lo != _regs.eax) || (old_hi != _regs.edx) )
|
||||
+ {
|
||||
+ _regs.eax = old_lo;
|
||||
@ -431,37 +231,37 @@ Index: 2007-01-31/xen/arch/x86/x86_emulate.c
|
||||
+ }
|
||||
+ 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,
|
||||
+ if ( (rc = ops->cmpxchg2(ea.mem.seg, ea.mem.off, old_lo, old_hi,
|
||||
+ _regs.ebx, _regs.ecx, ctxt)) != 0 )
|
||||
+ goto done;
|
||||
+ _regs.eflags |= EFLG_ZF;
|
||||
+ }
|
||||
}
|
||||
break;
|
||||
}
|
||||
-#endif
|
||||
- }
|
||||
goto writeback;
|
||||
-#endif
|
||||
|
||||
cannot_emulate:
|
||||
Index: 2007-01-31/xen/include/asm-x86/cpufeature.h
|
||||
case 0xc8 ... 0xcf: /* bswap */
|
||||
dst.type = OP_REG;
|
||||
@@ -2397,7 +2403,7 @@ x86_emulate(
|
||||
{
|
||||
default: /* case 2: */
|
||||
/* Undefined behaviour. Writes zero on all tested CPUs. */
|
||||
- dst.val = 0;
|
||||
+ __asm__("data16 bswap %k0" : "+r" (dst.val));
|
||||
break;
|
||||
case 4:
|
||||
#ifdef __x86_64__
|
||||
Index: 2007-05-14/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 @@
|
||||
--- 2007-05-14.orig/xen/include/asm-x86/cpufeature.h 2007-05-14 14:40:20.000000000 +0200
|
||||
+++ 2007-05-14/xen/include/asm-x86/cpufeature.h 2007-05-14 14:40:43.000000000 +0200
|
||||
@@ -121,6 +121,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)
|
||||
@ -469,7 +269,7 @@ Index: 2007-01-31/xen/include/asm-x86/cpufeature.h
|
||||
#else /* __x86_64__ */
|
||||
#define cpu_has_vme 0
|
||||
#define cpu_has_de 1
|
||||
@@ -140,6 +141,7 @@
|
||||
@@ -144,6 +145,7 @@
|
||||
#define cpu_has_cyrix_arr 0
|
||||
#define cpu_has_centaur_mcr 0
|
||||
#define cpu_has_clflush boot_cpu_has(X86_FEATURE_CLFLSH)
|
||||
@ -477,32 +277,13 @@ Index: 2007-01-31/xen/include/asm-x86/cpufeature.h
|
||||
#endif
|
||||
|
||||
#endif /* __ASM_I386_CPUFEATURE_H */
|
||||
Index: 2007-01-31/xen/include/asm-x86/shadow.h
|
||||
Index: 2007-05-14/xen/include/asm-x86/x86_emulate.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 {
|
||||
--- 2007-05-14.orig/xen/include/asm-x86/x86_emulate.h 2007-04-23 10:01:47.000000000 +0200
|
||||
+++ 2007-05-14/xen/include/asm-x86/x86_emulate.h 2007-05-14 14:40:43.000000000 +0200
|
||||
@@ -68,8 +68,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
|
||||
* failure by returning X86EMUL_EXCEPTION 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.
|
||||
@ -511,8 +292,8 @@ Index: 2007-01-31/xen/include/asm-x86/x86_emulate.h
|
||||
+ * 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_ops
|
||||
@@ -129,16 +130,17 @@ struct x86_emulate_ops
|
||||
struct x86_emulate_ctxt *ctxt);
|
||||
|
||||
/*
|
||||
@ -535,20 +316,22 @@ Index: 2007-01-31/xen/include/asm-x86/x86_emulate.h
|
||||
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;
|
||||
Index: 2007-05-14/xen/include/asm-x86/paging.h
|
||||
===================================================================
|
||||
--- 2007-05-14.orig/xen/include/asm-x86/paging.h 2007-04-23 10:01:46.000000000 +0200
|
||||
+++ 2007-05-14/xen/include/asm-x86/paging.h 2007-05-14 14:40:43.000000000 +0200
|
||||
@@ -93,12 +93,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);
|
||||
int (*guess_wrmap )(struct vcpu *v,
|
||||
|
@ -1,9 +1,9 @@
|
||||
Index: xen-unstable/tools/firmware/vmxassist/vm86.c
|
||||
Index: xen-3.1-testing/tools/firmware/vmxassist/vm86.c
|
||||
===================================================================
|
||||
--- xen-unstable.orig/tools/firmware/vmxassist/vm86.c
|
||||
+++ xen-unstable/tools/firmware/vmxassist/vm86.c
|
||||
@@ -38,7 +38,7 @@ unsigned prev_eip = 0;
|
||||
enum vm86_mode mode;
|
||||
--- xen-3.1-testing.orig/tools/firmware/vmxassist/vm86.c
|
||||
+++ xen-3.1-testing/tools/firmware/vmxassist/vm86.c
|
||||
@@ -40,7 +40,7 @@ enum vm86_mode mode = 0;
|
||||
static struct regs saved_rm_regs;
|
||||
|
||||
#ifdef DEBUG
|
||||
-int traceset = 0;
|
||||
@ -11,8 +11,8 @@ Index: xen-unstable/tools/firmware/vmxassist/vm86.c
|
||||
|
||||
char *states[] = {
|
||||
"<VM86_REAL>",
|
||||
@@ -72,6 +72,35 @@ address(struct regs *regs, unsigned seg,
|
||||
return addr;
|
||||
@@ -164,6 +164,35 @@ address(struct regs *regs, unsigned seg,
|
||||
return 0;
|
||||
}
|
||||
|
||||
+void
|
||||
@ -47,7 +47,7 @@ Index: xen-unstable/tools/firmware/vmxassist/vm86.c
|
||||
#ifdef DEBUG
|
||||
void
|
||||
trace(struct regs *regs, int adjust, char *fmt, ...)
|
||||
@@ -1037,7 +1066,7 @@ emulate(struct regs *regs)
|
||||
@@ -1636,7 +1665,7 @@ emulate(struct regs *regs)
|
||||
/* detect the case where we are not making progress */
|
||||
if (nemul == 0 && prev_eip == regs->eip) {
|
||||
flteip = address(regs, MASK16(regs->cs), regs->eip);
|
||||
@ -56,16 +56,16 @@ Index: xen-unstable/tools/firmware/vmxassist/vm86.c
|
||||
MASK16(regs->cs), regs->eip, flteip);
|
||||
} else
|
||||
prev_eip = regs->eip;
|
||||
@@ -1061,7 +1090,7 @@ trap(int trapno, int errno, struct regs
|
||||
if (regs->eflags & EFLAGS_VM) {
|
||||
/* emulate any 8086 instructions */
|
||||
@@ -1662,7 +1691,7 @@ trap(int trapno, int errno, struct regs
|
||||
if (mode == VM86_REAL)
|
||||
return;
|
||||
if (mode != VM86_REAL_TO_PROTECTED)
|
||||
- panic("not in real-to-protected mode");
|
||||
+ panic_eip(regs, "not in real-to-protected mode");
|
||||
emulate(regs);
|
||||
return;
|
||||
}
|
||||
@@ -1071,7 +1100,7 @@ trap(int trapno, int errno, struct regs
|
||||
@@ -1672,7 +1701,7 @@ trap(int trapno, int errno, struct regs
|
||||
if (regs->eflags & EFLAGS_VM) {
|
||||
/* emulate any 8086 instructions */
|
||||
if (mode == VM86_PROTECTED)
|
||||
@ -74,11 +74,11 @@ Index: xen-unstable/tools/firmware/vmxassist/vm86.c
|
||||
emulate(regs);
|
||||
return;
|
||||
}
|
||||
Index: xen-unstable/tools/firmware/rombios/rombios.c
|
||||
Index: xen-3.1-testing/tools/firmware/rombios/rombios.c
|
||||
===================================================================
|
||||
--- xen-unstable.orig/tools/firmware/rombios/rombios.c
|
||||
+++ xen-unstable/tools/firmware/rombios/rombios.c
|
||||
@@ -129,18 +129,18 @@
|
||||
--- xen-3.1-testing.orig/tools/firmware/rombios/rombios.c
|
||||
+++ xen-3.1-testing/tools/firmware/rombios/rombios.c
|
||||
@@ -131,18 +131,18 @@
|
||||
//
|
||||
// BCC Bug: find a generic way to handle the bug of #asm after an "if" (fixed in 0.16.7)
|
||||
|
||||
|
@ -1,20 +0,0 @@
|
||||
From: ?
|
||||
Upstream: xen-unstable
|
||||
|
||||
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
|
||||
===================================================================
|
||||
--- xen-unstable.orig/tools/python/xen/xend/image.py
|
||||
+++ xen-unstable/tools/python/xen/xend/image.py
|
||||
@@ -454,7 +454,7 @@ class HVMImageHandler(ImageHandler):
|
||||
def destroy(self, suspend = False):
|
||||
if self.pid:
|
||||
try:
|
||||
- sig = signal.SIGKILL
|
||||
+ sig = signal.SIGTERM
|
||||
if suspend:
|
||||
log.info("use sigusr1 to signal qemu %d", self.pid)
|
||||
sig = signal.SIGUSR1
|
@ -1,28 +1,3 @@
|
||||
Index: xen-unstable/tools/blktap/drivers/Makefile
|
||||
===================================================================
|
||||
--- xen-unstable.orig/tools/blktap/drivers/Makefile
|
||||
+++ xen-unstable/tools/blktap/drivers/Makefile
|
||||
@@ -8,7 +8,6 @@ QCOW_UTIL = img2qcow qcow2raw qcow-cr
|
||||
INST_DIR = /usr/sbin
|
||||
LIBAIO_DIR = ../../libaio/src
|
||||
|
||||
-CFLAGS += -Werror
|
||||
CFLAGS += -Wno-unused
|
||||
CFLAGS += -fno-strict-aliasing
|
||||
CFLAGS += -I $(XEN_LIBXC) -I $(LIBAIO_DIR)
|
||||
Index: xen-unstable/tools/ioemu/Makefile
|
||||
===================================================================
|
||||
--- xen-unstable.orig/tools/ioemu/Makefile
|
||||
+++ xen-unstable/tools/ioemu/Makefile
|
||||
@@ -8,7 +8,7 @@ include $(XEN_ROOT)/tools/Rules.mk
|
||||
.PHONY: all clean distclean dvi info install install-doc tar tarbin \
|
||||
speed test test2 html dvi info
|
||||
|
||||
-CFLAGS+=-Wall -O2 -g -fno-strict-aliasing -I.
|
||||
+CFLAGS+=-Wall -fno-strict-aliasing -I.
|
||||
ifdef CONFIG_DARWIN
|
||||
CFLAGS+= -mdynamic-no-pic
|
||||
endif
|
||||
Index: xen-unstable/Config.mk
|
||||
===================================================================
|
||||
--- xen-unstable.orig/Config.mk
|
||||
|
@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:26a506f1732698429dd8e4bf2a62b37aaab9bcd0b94578ba5cb548aaed70fa3e
|
||||
size 174056
|
||||
oid sha256:eb5f079f1f13a77acbf4f8a1e64d26bf4892ed5191f6db9c373bb2c374c67186
|
||||
size 173451
|
||||
|
@ -1,7 +1,7 @@
|
||||
Index: xen-3.0.5-testing/tools/ioemu/hw/piix4acpi.c
|
||||
Index: xen-3.1-testing/tools/ioemu/hw/piix4acpi.c
|
||||
===================================================================
|
||||
--- xen-3.0.5-testing.orig/tools/ioemu/hw/piix4acpi.c
|
||||
+++ xen-3.0.5-testing/tools/ioemu/hw/piix4acpi.c
|
||||
--- xen-3.1-testing.orig/tools/ioemu/hw/piix4acpi.c
|
||||
+++ xen-3.1-testing/tools/ioemu/hw/piix4acpi.c
|
||||
@@ -69,6 +69,8 @@ static int piix4acpi_load(QEMUFile *f, v
|
||||
if (version_id > 1)
|
||||
return -EINVAL;
|
||||
@ -11,10 +11,10 @@ Index: xen-3.0.5-testing/tools/ioemu/hw/piix4acpi.c
|
||||
}
|
||||
|
||||
static void acpiPm1Control_writeb(void *opaque, uint32_t addr, uint32_t val)
|
||||
Index: xen-3.0.5-testing/tools/ioemu/hw/usb-hid.c
|
||||
Index: xen-3.1-testing/tools/ioemu/hw/usb-hid.c
|
||||
===================================================================
|
||||
--- xen-3.0.5-testing.orig/tools/ioemu/hw/usb-hid.c
|
||||
+++ xen-3.0.5-testing/tools/ioemu/hw/usb-hid.c
|
||||
--- xen-3.1-testing.orig/tools/ioemu/hw/usb-hid.c
|
||||
+++ xen-3.1-testing/tools/ioemu/hw/usb-hid.c
|
||||
@@ -557,6 +557,7 @@ int usb_mouse_load(QEMUFile *f, void *op
|
||||
fprintf(logfile, "usb_mouse_load:add usb_mouse_event.\n");
|
||||
qemu_add_mouse_event_handler(usb_mouse_event, s, 0);
|
||||
@ -23,10 +23,10 @@ Index: xen-3.0.5-testing/tools/ioemu/hw/usb-hid.c
|
||||
}
|
||||
|
||||
|
||||
Index: xen-3.0.5-testing/tools/misc/miniterm/miniterm.c
|
||||
Index: xen-3.1-testing/tools/misc/miniterm/miniterm.c
|
||||
===================================================================
|
||||
--- xen-3.0.5-testing.orig/tools/misc/miniterm/miniterm.c
|
||||
+++ xen-3.0.5-testing/tools/misc/miniterm/miniterm.c
|
||||
--- xen-3.1-testing.orig/tools/misc/miniterm/miniterm.c
|
||||
+++ xen-3.1-testing/tools/misc/miniterm/miniterm.c
|
||||
@@ -157,7 +157,7 @@ int main(int argc, char **argv)
|
||||
case 0:
|
||||
close(1); /* stdout not needed */
|
||||
@ -60,10 +60,10 @@ Index: xen-3.0.5-testing/tools/misc/miniterm/miniterm.c
|
||||
break;
|
||||
}
|
||||
|
||||
Index: xen-3.0.5-testing/xen/tools/symbols.c
|
||||
Index: xen-3.1-testing/xen/tools/symbols.c
|
||||
===================================================================
|
||||
--- xen-3.0.5-testing.orig/xen/tools/symbols.c
|
||||
+++ xen-3.0.5-testing/xen/tools/symbols.c
|
||||
--- xen-3.1-testing.orig/xen/tools/symbols.c
|
||||
+++ xen-3.1-testing/xen/tools/symbols.c
|
||||
@@ -80,7 +80,8 @@ static int read_symbol(FILE *in, struct
|
||||
if (rc != 3) {
|
||||
if (rc != EOF) {
|
||||
@ -74,3 +74,71 @@ Index: xen-3.0.5-testing/xen/tools/symbols.c
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
Index: xen-3.1-testing/tools/blktap/drivers/blktapctrl.c
|
||||
===================================================================
|
||||
--- xen-3.1-testing.orig/tools/blktap/drivers/blktapctrl.c
|
||||
+++ xen-3.1-testing/tools/blktap/drivers/blktapctrl.c
|
||||
@@ -678,7 +678,10 @@ int main(int argc, char *argv[])
|
||||
__init_blkif();
|
||||
snprintf(buf, sizeof(buf), "BLKTAPCTRL[%d]", getpid());
|
||||
openlog(buf, LOG_CONS|LOG_ODELAY, LOG_DAEMON);
|
||||
- daemon(0,0);
|
||||
+ if (daemon(0,0)) {
|
||||
+ DPRINTF("daemon failed (%d)\n", errno);
|
||||
+ goto open_failed;
|
||||
+ }
|
||||
|
||||
print_drivers();
|
||||
init_driver_list();
|
||||
Index: xen-3.1-testing/tools/blktap/drivers/block-vmdk.c
|
||||
===================================================================
|
||||
--- xen-3.1-testing.orig/tools/blktap/drivers/block-vmdk.c
|
||||
+++ xen-3.1-testing/tools/blktap/drivers/block-vmdk.c
|
||||
@@ -283,8 +283,9 @@ static uint64_t get_cluster_offset(struc
|
||||
if (!allocate)
|
||||
return 0;
|
||||
cluster_offset = lseek(prv->fd, 0, SEEK_END);
|
||||
- ftruncate(prv->fd, cluster_offset +
|
||||
- (prv->cluster_sectors << 9));
|
||||
+ if (ftruncate(prv->fd, cluster_offset +
|
||||
+ (prv->cluster_sectors << 9)))
|
||||
+ return 0;
|
||||
cluster_offset >>= 9;
|
||||
/* update L2 table */
|
||||
tmp = cpu_to_le32(cluster_offset);
|
||||
Index: xen-3.1-testing/tools/blktap/drivers/block-qcow.c
|
||||
===================================================================
|
||||
--- xen-3.1-testing.orig/tools/blktap/drivers/block-qcow.c
|
||||
+++ xen-3.1-testing/tools/blktap/drivers/block-qcow.c
|
||||
@@ -745,7 +745,10 @@ found:
|
||||
}
|
||||
memcpy(tmp_ptr2, l2_ptr, 4096);
|
||||
lseek(s->fd, l2_offset + (l2_sector << 12), SEEK_SET);
|
||||
- write(s->fd, tmp_ptr2, 4096);
|
||||
+ if (write(s->fd, tmp_ptr2, 4096) != 4096) {
|
||||
+ free(tmp_ptr2);
|
||||
+ return -1;
|
||||
+ }
|
||||
free(tmp_ptr2);
|
||||
}
|
||||
return cluster_offset;
|
||||
@@ -1162,7 +1165,7 @@ int tdqcow_close(struct disk_driver *dd)
|
||||
offset = sizeof(QCowHeader) + sizeof(uint32_t);
|
||||
lseek(fd, offset, SEEK_SET);
|
||||
out = cpu_to_be32(cksum);
|
||||
- write(fd, &out, sizeof(uint32_t));
|
||||
+ if (write(fd, &out, sizeof(uint32_t))) ;
|
||||
close(fd);
|
||||
}
|
||||
|
||||
@@ -1252,8 +1255,8 @@ int qcow_create(const char *filename, ui
|
||||
strncpy(backing_filename, backing_file,
|
||||
sizeof(backing_filename));
|
||||
} else {
|
||||
- realpath(backing_file, backing_filename);
|
||||
- if (stat(backing_filename, &st) != 0) {
|
||||
+ if (realpath(backing_file, backing_filename) == NULL ||
|
||||
+ stat(backing_filename, &st) != 0) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
24
xen.changes
24
xen.changes
@ -1,3 +1,27 @@
|
||||
-------------------------------------------------------------------
|
||||
Mon May 21 10:41:41 MDT 2007 - ccoffing@novell.com
|
||||
|
||||
- vm-install bug fixes:
|
||||
+ #211342: better progress bar
|
||||
+ #259994: disk size would reset when editing path
|
||||
+ #247073: handle autoyast URLs
|
||||
+ #254311: physical disks were showing as 0.0 GB
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Wed May 16 16:05:22 MDT 2007 - ccoffing@novell.com
|
||||
|
||||
- Properly quote pathnames in domUloader to fix EVMS. (#274484)
|
||||
- Allow user to specify a default 'keymap' in xend's configuration
|
||||
file. (#258818 and 241149)
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Mon May 14 12:46:35 MDT 2007 - plc@novell.com
|
||||
|
||||
- Added upstream python patches for keymap specification in
|
||||
PV config file. Added upstream ALTGR fix, sign extension fix
|
||||
and modified patch 323 so that upstream patches applied cleanly.
|
||||
(#258818)
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Fri May 11 12:29:27 MDT 2007 - ccoffing@novell.com
|
||||
|
||||
|
267
xen.spec
267
xen.spec
@ -35,7 +35,7 @@ BuildRequires: glibc-32bit glibc-devel-32bit
|
||||
BuildRequires: kernel-source kernel-syms xorg-x11
|
||||
%endif
|
||||
Version: 3.1.0_15040
|
||||
Release: 1
|
||||
Release: 5
|
||||
License: GNU General Public License (GPL)
|
||||
Group: System/Kernel
|
||||
Autoreqprov: on
|
||||
@ -58,58 +58,82 @@ Source13: xmexample.iscsi
|
||||
Source14: xmclone.sh
|
||||
Source15: dom0config
|
||||
Source16: network-multi_bridge
|
||||
Patch0: xen-config.diff
|
||||
Patch1: xend-config.diff
|
||||
Patch2: xen-destdir.diff
|
||||
Patch3: xen-vm-install.diff
|
||||
Patch4: xen-rpmoptflags.diff
|
||||
Patch5: xen-warnings.diff
|
||||
Patch6: xen-changeset.diff
|
||||
Patch7: xen-paths.diff
|
||||
Patch8: xen-xmexample.diff
|
||||
Patch9: xen-xmexample-nbd.diff
|
||||
Patch10: xen-bootloader-dryrun.diff
|
||||
Patch12: xen-domUloader.diff
|
||||
Patch13: xen-linguas.diff
|
||||
Patch14: xen-messages.diff
|
||||
Patch15: xen-network-bridge.diff
|
||||
Patch16: xen-no-dummy-nfs-ip.diff
|
||||
Patch17: serial-split.patch
|
||||
Patch18: xen-xm-top-needs-root.diff
|
||||
Patch19: xen-tightvnc-args.diff
|
||||
Patch20: xen-max-free-mem.diff
|
||||
Patch21: xen-bonding.diff
|
||||
Patch22: xen-ioapic-ack-default.diff
|
||||
Patch23: xen-lost-mouse.diff
|
||||
Patch24: xen-lowmem-emergency-pool.diff
|
||||
Patch25: block-losetup-retry.diff
|
||||
Patch26: block-flags.diff
|
||||
Patch28: xen-hvm-default-bridge.diff
|
||||
Patch29: xen-hvm-netfront.diff
|
||||
Patch30: xen-hvm-default-pae.diff
|
||||
Patch31: xm-test-cleanup.diff
|
||||
Patch32: x86-extra-trap-info.patch
|
||||
Patch33: x86_emulate.patch
|
||||
Patch34: vgacon-50-lines.patch
|
||||
Patch35: vgacon-keep.patch
|
||||
Patch36: cross-build-fix.diff
|
||||
Patch37: bridge-hostonly.diff
|
||||
Patch38: xen-generate-foreign-headers.diff
|
||||
Patch39: tools-xc_kexec.diff
|
||||
Patch40: tools-kboot.diff
|
||||
Patch41: libxen_permissive.patch
|
||||
Patch42: xend_vbd_type.patch
|
||||
Patch43: xend_multiple_create.patch
|
||||
Patch44: xen-ioemu-hvm-pv-support.diff
|
||||
Patch45: xenapi-console-protocol.patch
|
||||
Patch46: xen-disable-qemu-monitor.diff
|
||||
Patch47: supported_module.diff
|
||||
Patch48: disable_emulated_device.diff
|
||||
Patch49: pv-driver-build.patch
|
||||
Patch50: xend-localtime.diff
|
||||
Patch51: qemu-security-etch1.diff
|
||||
Patch52: netfront_mac.patch
|
||||
# Misc unused patches / need to be re-ported:
|
||||
# Upstream patches
|
||||
Patch0: 15048-localtime.diff
|
||||
# Our patches
|
||||
Patch100: xen-config.diff
|
||||
Patch101: xend-config.diff
|
||||
Patch102: xen-destdir.diff
|
||||
Patch103: xen-vm-install.diff
|
||||
Patch104: xen-rpmoptflags.diff
|
||||
Patch105: xen-warnings.diff
|
||||
Patch106: xen-changeset.diff
|
||||
Patch107: xen-paths.diff
|
||||
Patch108: xen-xmexample.diff
|
||||
Patch109: xen-xmexample-nbd.diff
|
||||
Patch110: xen-bootloader-dryrun.diff
|
||||
Patch112: xen-domUloader.diff
|
||||
Patch113: xen-linguas.diff
|
||||
Patch114: xen-messages.diff
|
||||
Patch115: xen-network-bridge.diff
|
||||
Patch116: xen-no-dummy-nfs-ip.diff
|
||||
Patch117: serial-split.patch
|
||||
Patch118: xen-xm-top-needs-root.diff
|
||||
Patch119: xen-tightvnc-args.diff
|
||||
Patch120: xen-max-free-mem.diff
|
||||
Patch121: xen-bonding.diff
|
||||
Patch122: xen-ioapic-ack-default.diff
|
||||
Patch123: xen-lowmem-emergency-pool.diff
|
||||
Patch124: block-losetup-retry.diff
|
||||
Patch125: block-flags.diff
|
||||
Patch126: xen-hvm-default-bridge.diff
|
||||
Patch127: xen-hvm-netfront.diff
|
||||
Patch128: xen-hvm-default-pae.diff
|
||||
Patch129: xm-test-cleanup.diff
|
||||
Patch130: cross-build-fix.diff
|
||||
Patch131: bridge-hostonly.diff
|
||||
Patch132: xen-generate-foreign-headers.diff
|
||||
Patch133: tools-xc_kexec.diff
|
||||
Patch134: tools-kboot.diff
|
||||
Patch135: libxen_permissive.patch
|
||||
Patch136: xend_multiple_create.patch
|
||||
Patch137: xen-ioemu-hvm-pv-support.diff
|
||||
Patch138: xenapi-console-protocol.patch
|
||||
Patch139: xen-disable-qemu-monitor.diff
|
||||
Patch140: supported_module.diff
|
||||
Patch141: disable_emulated_device.diff
|
||||
Patch142: pv-driver-build.patch
|
||||
Patch143: qemu-security-etch1.diff
|
||||
Patch144: netfront_mac.patch
|
||||
Patch145: vnc-i18n-keys.diff
|
||||
# Patches from Jan
|
||||
Patch170: inval-sh-ldt.patch
|
||||
Patch171: 32on64-cpuid.patch
|
||||
Patch172: 32on64-ioemu.patch
|
||||
Patch173: check-libvncserver.patch
|
||||
Patch174: check-xenapi.patch
|
||||
Patch175: kill-sh_mapcache.patch
|
||||
Patch176: intpte_t-cast.patch
|
||||
Patch177: ptwr-sanity.patch
|
||||
Patch178: hvm-pio-read.patch
|
||||
Patch179: hvm-shared-info-size.patch
|
||||
Patch180: hvm-hypercall-context.patch
|
||||
Patch181: hvm-efer.patch
|
||||
Patch182: hvm-hypercall-debug.patch
|
||||
Patch183: svm-reg-save.patch
|
||||
Patch184: vmx-no-cstar.patch
|
||||
Patch185: hvm-debug-msg.patch
|
||||
Patch186: guest-copy.patch
|
||||
Patch187: page-cacheability.patch
|
||||
Patch188: realmode.patch
|
||||
Patch189: edd.patch
|
||||
Patch190: edid.patch
|
||||
Patch191: 32on64-call-gates.patch
|
||||
Patch192: x86-nmi-inject.patch
|
||||
Patch193: x86_emulate.patch
|
||||
Patch194: vgacon-keep.patch
|
||||
Patch195: vgacon-50-lines.patch
|
||||
Patch196: x86-extra-trap-info.patch
|
||||
Patch300: xen-enable-hvm-debug.diff
|
||||
URL: http://www.cl.cam.ac.uk/Research/SRG/netos/xen/
|
||||
Prefix: /usr
|
||||
@ -508,58 +532,80 @@ Authors:
|
||||
%setup -q -c -n %xen_build_dir/tools -D -T -a 1
|
||||
cd ..
|
||||
%patch0 -p1
|
||||
%patch1 -p1
|
||||
%patch2 -p1
|
||||
%patch100 -p1
|
||||
%patch101 -p1
|
||||
%patch102 -p1
|
||||
%if %{?with_install}0
|
||||
%patch3 -p1
|
||||
%patch103 -p1
|
||||
%endif
|
||||
%patch4 -p1
|
||||
%patch5 -p1
|
||||
%patch6 -p1
|
||||
%patch7 -p1
|
||||
%patch8 -p1
|
||||
%patch9 -p1
|
||||
%patch10 -p1
|
||||
%patch12 -p1
|
||||
#%patch13 -p1 # po files are misnamed upstream
|
||||
%patch14 -p1
|
||||
%patch15 -p1
|
||||
%patch16 -p1
|
||||
%patch17 -p1
|
||||
%patch18 -p1
|
||||
%patch19 -p1
|
||||
%patch20 -p1
|
||||
%patch21 -p1
|
||||
%patch22 -p1
|
||||
%patch23 -p1
|
||||
%patch24 -p1
|
||||
%patch25 -p1
|
||||
%patch26 -p1
|
||||
%patch28 -p1
|
||||
%patch29 -p1
|
||||
%patch30 -p1
|
||||
%patch31 -p1
|
||||
%patch32 -p1
|
||||
#%patch33 -p1 # check if upstream
|
||||
%patch34 -p1
|
||||
%patch35 -p1
|
||||
%patch36 -p1
|
||||
%patch37 -p1
|
||||
%patch38 -p1
|
||||
%patch39 -p1
|
||||
%patch40 -p1
|
||||
%patch41 -p1
|
||||
%patch42 -p1
|
||||
#%patch43 -p1 # check if bug still exists in 3.1.0
|
||||
#%patch44 -p1 # re-port
|
||||
%patch45 -p1
|
||||
%patch46 -p1
|
||||
%patch47 -p1
|
||||
#%patch48 -p1 # Currently not disabling FV devices when loading PV drivers
|
||||
%patch49 -p1
|
||||
%patch50 -p1
|
||||
%patch51 -p1
|
||||
%patch52 -p1
|
||||
%patch104 -p1
|
||||
%patch105 -p1
|
||||
%patch106 -p1
|
||||
%patch107 -p1
|
||||
%patch108 -p1
|
||||
%patch109 -p1
|
||||
%patch110 -p1
|
||||
%patch112 -p1
|
||||
#%patch113 -p1 # po files are misnamed upstream
|
||||
%patch114 -p1
|
||||
%patch115 -p1
|
||||
%patch116 -p1
|
||||
%patch117 -p1
|
||||
%patch118 -p1
|
||||
%patch119 -p1
|
||||
%patch120 -p1
|
||||
%patch121 -p1
|
||||
%patch122 -p1
|
||||
%patch123 -p1
|
||||
%patch124 -p1
|
||||
%patch125 -p1
|
||||
%patch126 -p1
|
||||
%patch127 -p1
|
||||
%patch128 -p1
|
||||
%patch129 -p1
|
||||
%patch130 -p1
|
||||
%patch131 -p1
|
||||
%patch132 -p1
|
||||
%patch133 -p1
|
||||
%patch134 -p1
|
||||
%patch135 -p1
|
||||
#%patch136 -p1 # check if bug still exists in 3.1.0
|
||||
#%patch137 -p1 # re-port
|
||||
%patch138 -p1
|
||||
%patch139 -p1
|
||||
%patch140 -p1
|
||||
#%patch141 -p1 # Currently not disabling FV devices when loading PV drivers
|
||||
%patch142 -p1
|
||||
%patch143 -p1
|
||||
%patch144 -p1
|
||||
%patch145 -p1
|
||||
%patch170 -p1
|
||||
%patch171 -p1
|
||||
%patch172 -p1
|
||||
%patch173 -p1
|
||||
%patch174 -p1
|
||||
%patch175 -p1
|
||||
%patch176 -p1
|
||||
%patch177 -p1
|
||||
%patch178 -p1
|
||||
%patch179 -p1
|
||||
%patch180 -p1
|
||||
%patch181 -p1
|
||||
%patch182 -p1
|
||||
%patch183 -p1
|
||||
%patch184 -p1
|
||||
%patch185 -p1
|
||||
%patch186 -p1
|
||||
%patch187 -p1
|
||||
%patch188 -p1
|
||||
%patch189 -p1
|
||||
%patch190 -p1
|
||||
%patch191 -p1
|
||||
%patch192 -p1
|
||||
%patch193 -p1
|
||||
%patch194 -p1
|
||||
%patch195 -p1
|
||||
%patch196 -p1
|
||||
XEN_EXTRAVERSION=%version-%release
|
||||
XEN_EXTRAVERSION=${XEN_EXTRAVERSION#%{xvers}}
|
||||
sed -i "s/XEN_EXTRAVERSION[ ]*.=.*\$/XEN_EXTRAVERSION = $XEN_EXTRAVERSION/" xen/Makefile
|
||||
@ -879,6 +925,21 @@ rm -rf $RPM_BUILD_DIR/%xen_build_dir
|
||||
%{insserv_cleanup}
|
||||
|
||||
%changelog
|
||||
* Mon May 21 2007 - ccoffing@novell.com
|
||||
- vm-install bug fixes:
|
||||
+ #211342: better progress bar
|
||||
+ #259994: disk size would reset when editing path
|
||||
+ #247073: handle autoyast URLs
|
||||
+ #254311: physical disks were showing as 0.0 GB
|
||||
* Wed May 16 2007 - ccoffing@novell.com
|
||||
- Properly quote pathnames in domUloader to fix EVMS. (#274484)
|
||||
- Allow user to specify a default 'keymap' in xend's configuration
|
||||
file. (#258818 and 241149)
|
||||
* Mon May 14 2007 - plc@novell.com
|
||||
- Added upstream python patches for keymap specification in
|
||||
PV config file. Added upstream ALTGR fix, sign extension fix
|
||||
and modified patch 323 so that upstream patches applied cleanly.
|
||||
(#258818)
|
||||
* Fri May 11 2007 - ccoffing@novell.com
|
||||
- Update to xen-3.1-testing rc10 (changeset 15040).
|
||||
- Update .desktop with proper group. (#258600)
|
||||
|
@ -1,12 +0,0 @@
|
||||
Index: xen-unstable/tools/python/xen/xend/server/blkif.py
|
||||
===================================================================
|
||||
--- xen-unstable.orig/tools/python/xen/xend/server/blkif.py
|
||||
+++ xen-unstable/tools/python/xen/xend/server/blkif.py
|
||||
@@ -122,6 +122,7 @@ class BlkifController(DevController):
|
||||
dev_type = self.readFrontend(devid, 'device-type')
|
||||
if dev_type:
|
||||
dev += ':' + dev_type
|
||||
+ config['type'] = dev_type
|
||||
config['dev'] = dev
|
||||
if typ and params:
|
||||
config['uname'] = typ +':' + params
|
Loading…
Reference in New Issue
Block a user