From 0a63222b019cd760fc42fb2632d6a211212486e77bf7dd5d031dd67ae117a091 Mon Sep 17 00:00:00 2001 From: OBS User unknown Date: Mon, 21 May 2007 20:28:46 +0000 Subject: [PATCH] OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/xen?expand=0&rev=12 --- xend-localtime.diff => 15048-localtime.diff | 2 +- 32on64-call-gates.patch | 484 ++++++++++++++ 32on64-cpuid.patch | 13 + 32on64-ioemu.patch | 119 ++++ check-libvncserver.patch | 29 + check-xenapi.patch | 108 ++++ domUloader.py | 23 +- edd.patch | 660 +++++++++++++++++++ edid.patch | 188 ++++++ guest-copy.patch | 374 +++++++++++ hvm-debug-msg.patch | 401 ++++++++++++ hvm-efer.patch | 670 ++++++++++++++++++++ hvm-hypercall-context.patch | 309 +++++++++ hvm-hypercall-debug.patch | 58 ++ hvm-pio-read.patch | 37 ++ hvm-shared-info-size.patch | 34 + intpte_t-cast.patch | 40 ++ inval-sh-ldt.patch | 25 + kill-sh_mapcache.patch | 29 + page-cacheability.patch | 561 ++++++++++++++++ ptwr-sanity.patch | 74 +++ realmode.patch | 406 ++++++++++++ svm-reg-save.patch | 264 ++++++++ vgacon-50-lines.patch | 10 +- vgacon-keep.patch | 12 +- vmx-no-cstar.patch | 78 +++ vnc-i18n-keys.diff | 133 ++++ x86-extra-trap-info.patch | 14 +- x86-nmi-inject.patch | 276 ++++++++ x86_emulate.patch | 439 ++++--------- xen-enable-hvm-debug.diff | 32 +- xen-lost-mouse.diff | 20 - xen-rpmoptflags.diff | 25 - xen-vm-install.tar.bz2 | 4 +- xen-warnings.diff | 92 ++- xen.changes | 24 + xen.spec | 267 +++++--- xend_vbd_type.patch | 12 - 38 files changed, 5798 insertions(+), 548 deletions(-) rename xend-localtime.diff => 15048-localtime.diff (94%) create mode 100644 32on64-call-gates.patch create mode 100644 32on64-cpuid.patch create mode 100644 32on64-ioemu.patch create mode 100644 check-libvncserver.patch create mode 100644 check-xenapi.patch create mode 100644 edd.patch create mode 100644 edid.patch create mode 100644 guest-copy.patch create mode 100644 hvm-debug-msg.patch create mode 100644 hvm-efer.patch create mode 100644 hvm-hypercall-context.patch create mode 100644 hvm-hypercall-debug.patch create mode 100644 hvm-pio-read.patch create mode 100644 hvm-shared-info-size.patch create mode 100644 intpte_t-cast.patch create mode 100644 inval-sh-ldt.patch create mode 100644 kill-sh_mapcache.patch create mode 100644 page-cacheability.patch create mode 100644 ptwr-sanity.patch create mode 100644 realmode.patch create mode 100644 svm-reg-save.patch create mode 100644 vmx-no-cstar.patch create mode 100644 vnc-i18n-keys.diff create mode 100644 x86-nmi-inject.patch delete mode 100644 xen-lost-mouse.diff delete mode 100644 xend_vbd_type.patch diff --git a/xend-localtime.diff b/15048-localtime.diff similarity index 94% rename from xend-localtime.diff rename to 15048-localtime.diff index b69ecf9..c7cff3c 100644 --- a/xend-localtime.diff +++ b/15048-localtime.diff @@ -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) diff --git a/32on64-call-gates.patch b/32on64-call-gates.patch new file mode 100644 index 0000000..dd642af --- /dev/null +++ b/32on64-call-gates.patch @@ -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; diff --git a/32on64-cpuid.patch b/32on64-cpuid.patch new file mode 100644 index 0000000..421169a --- /dev/null +++ b/32on64-cpuid.patch @@ -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 diff --git a/32on64-ioemu.patch b/32on64-ioemu.patch new file mode 100644 index 0000000..db09b9e --- /dev/null +++ b/32on64-ioemu.patch @@ -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: diff --git a/check-libvncserver.patch b/check-libvncserver.patch new file mode 100644 index 0000000..3663934 --- /dev/null +++ b/check-libvncserver.patch @@ -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 diff --git a/check-xenapi.patch b/check-xenapi.patch new file mode 100644 index 0000000..45b6ff9 --- /dev/null +++ b/check-xenapi.patch @@ -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 diff --git a/domUloader.py b/domUloader.py index ec84852..08e7baa 100644 --- a/domUloader.py +++ b/domUloader.py @@ -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 diff --git a/edd.patch b/edd.patch new file mode 100644 index 0000000..f3b1e50 --- /dev/null +++ b/edd.patch @@ -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 October 2002 ++ * conformant to T13 Committee www.t13.org ++ * projects 1572D, 1484D, 1386D, 1226DT ++ * disk signature read by Matt Domsch ++ * and Andrew Wilks September 2003, June 2004 ++ * legacy CHS retrieval by Patrick J. LoPresti ++ * March 2004 ++ * Command line option parsing, Matt Domsch, November 2004 ++ * Xen adoption by Jan Beulich , February 2007 ++ */ ++ ++#include ++ ++# 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 + #include + #include ++#include + #include + #include + #include +@@ -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 ++ * Adopted for Xen (C) 2007 Novell, Inc. ++ * by Jan Beulich ++ * ++ * 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 */ diff --git a/edid.patch b/edid.patch new file mode 100644 index 0000000..2cd1416 --- /dev/null +++ b/edid.patch @@ -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 + #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; diff --git a/guest-copy.patch b/guest-copy.patch new file mode 100644 index 0000000..dac1dc8 --- /dev/null +++ b/guest-copy.patch @@ -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)); \ + }) + + diff --git a/hvm-debug-msg.patch b/hvm-debug-msg.patch new file mode 100644 index 0000000..1c89f4f --- /dev/null +++ b/hvm-debug-msg.patch @@ -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: diff --git a/hvm-efer.patch b/hvm-efer.patch new file mode 100644 index 0000000..903f90b --- /dev/null +++ b/hvm-efer.patch @@ -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 ++#include ++ + #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 + diff --git a/hvm-hypercall-context.patch b/hvm-hypercall-context.patch new file mode 100644 index 0000000..17dfedb --- /dev/null +++ b/hvm-hypercall-context.patch @@ -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 + #include + #include ++#include + #include + #include + #include +@@ -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); diff --git a/hvm-hypercall-debug.patch b/hvm-hypercall-debug.patch new file mode 100644 index 0000000..461cbd9 --- /dev/null +++ b/hvm-hypercall-debug.patch @@ -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...) \ diff --git a/hvm-pio-read.patch b/hvm-pio-read.patch new file mode 100644 index 0000000..b4ea618 --- /dev/null +++ b/hvm-pio-read.patch @@ -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); diff --git a/hvm-shared-info-size.patch b/hvm-shared-info-size.patch new file mode 100644 index 0000000..4584ac1 --- /dev/null +++ b/hvm-shared-info-size.patch @@ -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; diff --git a/intpte_t-cast.patch b/intpte_t-cast.patch new file mode 100644 index 0000000..708032a --- /dev/null +++ b/intpte_t-cast.patch @@ -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); + diff --git a/inval-sh-ldt.patch b/inval-sh-ldt.patch new file mode 100644 index 0000000..860819e --- /dev/null +++ b/inval-sh-ldt.patch @@ -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) diff --git a/kill-sh_mapcache.patch b/kill-sh_mapcache.patch new file mode 100644 index 0000000..a07549f --- /dev/null +++ b/kill-sh_mapcache.patch @@ -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); + diff --git a/page-cacheability.patch b/page-cacheability.patch new file mode 100644 index 0000000..7cb75e7 --- /dev/null +++ b/page-cacheability.patch @@ -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<shadow_flags & (1<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) diff --git a/ptwr-sanity.patch b/ptwr-sanity.patch new file mode 100644 index 0000000..b7d7aab --- /dev/null +++ b/ptwr-sanity.patch @@ -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) ) diff --git a/realmode.patch b/realmode.patch new file mode 100644 index 0000000..9c5f137 --- /dev/null +++ b/realmode.patch @@ -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 + #include + #include ++#include + #include + #include + +@@ -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 + #include + #include ++#include + #ifdef CONFIG_COMPAT + #include + #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 = .; + diff --git a/svm-reg-save.patch b/svm-reg-save.patch new file mode 100644 index 0000000..a8eeaef --- /dev/null +++ b/svm-reg-save.patch @@ -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 diff --git a/vgacon-50-lines.patch b/vgacon-50-lines.patch index 5e4e54d..b770fd4 100644 --- a/vgacon-50-lines.patch +++ b/vgacon-50-lines.patch @@ -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] != '-' ) diff --git a/vgacon-keep.patch b/vgacon-keep.patch index 16405bb..cd14742 100644 --- a/vgacon-keep.patch +++ b/vgacon-keep.patch @@ -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) { diff --git a/vmx-no-cstar.patch b/vmx-no-cstar.patch new file mode 100644 index 0000000..b973f46 --- /dev/null +++ b/vmx-no-cstar.patch @@ -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; diff --git a/vnc-i18n-keys.diff b/vnc-i18n-keys.diff new file mode 100644 index 0000000..5f57ddf --- /dev/null +++ b/vnc-i18n-keys.diff @@ -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 diff --git a/x86-extra-trap-info.patch b/x86-extra-trap-info.patch index 017a14e..2992a14 100644 --- a/x86-extra-trap-info.patch +++ b/x86-extra-trap-info.patch @@ -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 diff --git a/x86-nmi-inject.patch b/x86-nmi-inject.patch new file mode 100644 index 0000000..4bda242 --- /dev/null +++ b/x86-nmi-inject.patch @@ -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 diff --git a/x86_emulate.patch b/x86_emulate.patch index bc8c966..ac38214 100644 --- a/x86_emulate.patch +++ b/x86_emulate.patch @@ -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 #include #include @@ -143,223 +141,18 @@ Index: 2007-01-31/xen/arch/x86/x86_emulate.c #undef cmpxchg #endif #include -@@ -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, diff --git a/xen-enable-hvm-debug.diff b/xen-enable-hvm-debug.diff index 2d963e1..9dad34c 100644 --- a/xen-enable-hvm-debug.diff +++ b/xen-enable-hvm-debug.diff @@ -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[] = { "", -@@ -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) diff --git a/xen-lost-mouse.diff b/xen-lost-mouse.diff deleted file mode 100644 index e75b2da..0000000 --- a/xen-lost-mouse.diff +++ /dev/null @@ -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 diff --git a/xen-rpmoptflags.diff b/xen-rpmoptflags.diff index 189b4d4..bfec1df 100644 --- a/xen-rpmoptflags.diff +++ b/xen-rpmoptflags.diff @@ -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 diff --git a/xen-vm-install.tar.bz2 b/xen-vm-install.tar.bz2 index b66b1d0..b4420cd 100644 --- a/xen-vm-install.tar.bz2 +++ b/xen-vm-install.tar.bz2 @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:26a506f1732698429dd8e4bf2a62b37aaab9bcd0b94578ba5cb548aaed70fa3e -size 174056 +oid sha256:eb5f079f1f13a77acbf4f8a1e64d26bf4892ed5191f6db9c373bb2c374c67186 +size 173451 diff --git a/xen-warnings.diff b/xen-warnings.diff index 4c88c4f..6c2231f 100644 --- a/xen-warnings.diff +++ b/xen-warnings.diff @@ -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; + } + } diff --git a/xen.changes b/xen.changes index 5d0efdb..f0f3486 100644 --- a/xen.changes +++ b/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 diff --git a/xen.spec b/xen.spec index 6102609..9763e9c 100644 --- a/xen.spec +++ b/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) diff --git a/xend_vbd_type.patch b/xend_vbd_type.patch deleted file mode 100644 index 17077c3..0000000 --- a/xend_vbd_type.patch +++ /dev/null @@ -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