Hello community,
here is the log from the commit of package xen
checked in at Mon May 21 22:28:44 CEST 2007.
--------
--- arch/i386/xen/xen.changes 2007-05-11 22:49:58.000000000 +0200
+++ xen/xen.changes 2007-05-21 18:42:18.000000000 +0200
@@ -1,0 +2,24 @@
+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)
+
+-------------------------------------------------------------------
Old:
----
xend-localtime.diff
xend_vbd_type.patch
xen-lost-mouse.diff
New:
----
15048-localtime.diff
32on64-call-gates.patch
32on64-cpuid.patch
32on64-ioemu.patch
check-libvncserver.patch
check-xenapi.patch
edd.patch
edid.patch
guest-copy.patch
hvm-debug-msg.patch
hvm-efer.patch
hvm-hypercall-context.patch
hvm-hypercall-debug.patch
hvm-pio-read.patch
hvm-shared-info-size.patch
intpte_t-cast.patch
inval-sh-ldt.patch
kill-sh_mapcache.patch
page-cacheability.patch
ptwr-sanity.patch
realmode.patch
svm-reg-save.patch
vmx-no-cstar.patch
vnc-i18n-keys.diff
x86-nmi-inject.patch
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ xen.spec ++++++
--- /var/tmp/diff_new_pack.y15063/_old 2007-05-21 22:27:54.000000000 +0200
+++ /var/tmp/diff_new_pack.y15063/_new 2007-05-21 22:27:54.000000000 +0200
@@ -35,7 +35,7 @@
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 @@
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 @@
%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 @@
%{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)
++++++ xend-localtime.diff -> 15048-localtime.diff ++++++
--- arch/i386/xen/xend-localtime.diff 2007-05-11 22:23:58.000000000 +0200
+++ xen/15048-localtime.diff 2007-05-17 20:00:53.000000000 +0200
@@ -12,7 +12,7 @@
===================================================================
--- 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)
++++++ 32on64-call-gates.patch ++++++
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;
++++++ 32on64-cpuid.patch ++++++
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
++++++ 32on64-ioemu.patch ++++++
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:
++++++ check-libvncserver.patch ++++++
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
++++++ check-xenapi.patch ++++++
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
++++++ domUloader.py ++++++
--- arch/i386/xen/domUloader.py 2007-04-17 16:42:56.000000000 +0200
+++ xen/domUloader.py 2007-05-17 17:16:13.000000000 +0200
@@ -115,9 +115,9 @@
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 @@
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 @@
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 @@
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 @@
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
++++++ edd.patch ++++++
++++ 660 lines (skipped)
++++++ edid.patch ++++++
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;
++++++ guest-copy.patch ++++++
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)); \
})
++++++ hvm-debug-msg.patch ++++++
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:
++++++ hvm-efer.patch ++++++
++++ 670 lines (skipped)
++++++ hvm-hypercall-context.patch ++++++
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);
++++++ hvm-hypercall-debug.patch ++++++
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...) \
++++++ hvm-pio-read.patch ++++++
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);
++++++ hvm-shared-info-size.patch ++++++
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;
++++++ intpte_t-cast.patch ++++++
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);
++++++ inval-sh-ldt.patch ++++++
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)
++++++ kill-sh_mapcache.patch ++++++
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);
++++++ page-cacheability.patch ++++++
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<<sp->type)) );
/* Bad type count on guest page? */
- if ( (gpg->u.inuse.type_info & PGT_type_mask) == PGT_writable_page
+ if ( (gpg->u.inuse.type_info & PGT_writable_page)
&& (gpg->u.inuse.type_info & PGT_count_mask) != 0 )
{
SHADOW_ERROR("MFN %#lx shadowed (by %#"PRI_mfn")"
Index: 2007-05-14/xen/arch/x86/mm/shadow/multi.c
===================================================================
--- 2007-05-14.orig/xen/arch/x86/mm/shadow/multi.c 2007-05-14 14:28:19.000000000 +0200
+++ 2007-05-14/xen/arch/x86/mm/shadow/multi.c 2007-05-14 14:35:02.000000000 +0200
@@ -4128,8 +4128,7 @@ audit_gfn_to_mfn(struct vcpu *v, gfn_t g
if ( !shadow_mode_translate(v->domain) )
return _mfn(gfn_x(gfn));
- if ( (mfn_to_page(gmfn)->u.inuse.type_info & PGT_type_mask)
- != PGT_writable_page )
+ if ( !(mfn_to_page(gmfn)->u.inuse.type_info & PGT_writable_page) )
return _mfn(gfn_x(gfn)); /* This is a paging-disabled shadow */
else
return gfn_to_mfn(v->domain, gfn_x(gfn));
Index: 2007-05-14/xen/include/asm-x86/mm.h
===================================================================
--- 2007-05-14.orig/xen/include/asm-x86/mm.h 2007-05-14 13:43:35.000000000 +0200
+++ 2007-05-14/xen/include/asm-x86/mm.h 2007-05-14 14:35:02.000000000 +0200
@@ -64,24 +64,35 @@ struct page_info
};
/* The following page types are MUTUALLY EXCLUSIVE. */
-#define PGT_none (0U<<29) /* no special uses of this page */
-#define PGT_l1_page_table (1U<<29) /* using this page as an L1 page table? */
-#define PGT_l2_page_table (2U<<29) /* using this page as an L2 page table? */
-#define PGT_l3_page_table (3U<<29) /* using this page as an L3 page table? */
-#define PGT_l4_page_table (4U<<29) /* using this page as an L4 page table? */
-#define PGT_gdt_page (5U<<29) /* using this page in a GDT? */
-#define PGT_ldt_page (6U<<29) /* using this page in an LDT? */
-#define PGT_writable_page (7U<<29) /* has writable mappings of this page? */
-#define PGT_type_mask (7U<<29) /* Bits 29-31. */
+#define PGT_none (0U<<28) /* no special uses of this page */
+#define PGT_l1_page_table (1U<<28) /* using this page as an L1 page table? */
+#define PGT_l2_page_table (2U<<28) /* using this page as an L2 page table? */
+#define PGT_l3_page_table (3U<<28) /* using this page as an L3 page table? */
+#define PGT_l4_page_table (4U<<28) /* using this page as an L4 page table? */
+#define PGT_gdt_page (5U<<28) /* using this page in a GDT? */
+#define PGT_ldt_page (6U<<28) /* using this page in an LDT? */
+#define PGT_writable_page (0x8U<<28) /* has writable mappings of this page? */
+#define PGT_pwt_mask (0x1U<<28) /* (l1e & _PAGE_PWT) mirror */
+#define PGT_pcd_mask (0x2U<<28) /* (l1e & _PAGE_PCD) mirror */
+#define PGT_wb_page (0x8U<<28) /* WB cached writable page? */
+#define PGT_wt_page (0x9U<<28) /* WT cached writable page? */
+#define PGT_ucm_page (0xAU<<28) /* UC- cached writable page? */
+#define PGT_uc_page (0xBU<<28) /* UC cached writable page? */
+#ifdef CONFIG_PAT
+#define PGT_pat_mask (0x4U<<28) /* (l1e & _PAGE_PAT) mirror */
+#define PGT_wc_page (0xCU<<28) /* WC cached writable page? */
+#define PGT_wp_page (0xDU<<28) /* WP cached writable page? */
+#endif
+#define PGT_type_mask (0xFU<<28) /* Bits 28-31. */
/* Owning guest has pinned this page to its current type? */
-#define _PGT_pinned 28
+#define _PGT_pinned 22
#define PGT_pinned (1U<<_PGT_pinned)
/* Has this page been validated for use as its current type? */
-#define _PGT_validated 27
+#define _PGT_validated 21
#define PGT_validated (1U<<_PGT_validated)
/* PAE only: is this an L2 page directory containing Xen-private mappings? */
-#define _PGT_pae_xen_l2 26
+#define _PGT_pae_xen_l2 20
#define PGT_pae_xen_l2 (1U<<_PGT_pae_xen_l2)
/* 16-bit count of uses of this frame as its current type. */
@@ -141,7 +152,6 @@ extern unsigned long max_page;
extern unsigned long total_pages;
void init_frametable(void);
-int alloc_page_type(struct page_info *page, unsigned long type);
void free_page_type(struct page_info *page, unsigned long type);
int _shadow_mode_refcounts(struct domain *d);
Index: 2007-05-14/xen/include/asm-x86/x86_32/page-3level.h
===================================================================
--- 2007-05-14.orig/xen/include/asm-x86/x86_32/page-3level.h 2007-04-23 10:01:46.000000000 +0200
+++ 2007-05-14/xen/include/asm-x86/x86_32/page-3level.h 2007-05-14 14:35:02.000000000 +0200
@@ -85,6 +85,6 @@ typedef l3_pgentry_t root_pgentry_t;
#define get_pte_flags(x) (((int)((x) >> 32) & ~0xFFF) | ((int)(x) & 0xFFF))
#define put_pte_flags(x) (((intpte_t)((x) & ~0xFFF) << 32) | ((x) & 0xFFF))
-#define L3_DISALLOW_MASK 0xFFFFF1E6U /* must-be-zero */
+#define L3_DISALLOW_MASK 0xFFFFF1FEU /* must-be-zero */
#endif /* __X86_32_PAGE_3LEVEL_H__ */
Index: 2007-05-14/xen/include/asm-x86/x86_32/page.h
===================================================================
--- 2007-05-14.orig/xen/include/asm-x86/x86_32/page.h 2007-04-23 10:01:46.000000000 +0200
+++ 2007-05-14/xen/include/asm-x86/x86_32/page.h 2007-05-14 14:35:02.000000000 +0200
@@ -29,13 +29,13 @@ extern unsigned int PAGE_HYPERVISOR_NOCA
(_PAGE_PRESENT|_PAGE_ACCESSED|_PAGE_DIRTY|_PAGE_GNTTAB)
/*
- * Disallow unused flag bits plus PAT, PSE and GLOBAL.
+ * Disallow unused flag bits plus PAT/PSE and GLOBAL.
* Permit the NX bit if the hardware supports it.
*/
#define BASE_DISALLOW_MASK (0xFFFFF180U & ~_PAGE_NX)
#define L1_DISALLOW_MASK (BASE_DISALLOW_MASK | _PAGE_GNTTAB)
-#define L2_DISALLOW_MASK (BASE_DISALLOW_MASK)
+#define L2_DISALLOW_MASK (BASE_DISALLOW_MASK | _PAGE_PCD | _PAGE_PWT)
#endif /* __X86_32_PAGE_H__ */
Index: 2007-05-14/xen/include/asm-x86/x86_64/page.h
===================================================================
--- 2007-05-14.orig/xen/include/asm-x86/x86_64/page.h 2007-05-03 09:45:09.000000000 +0200
+++ 2007-05-14/xen/include/asm-x86/x86_64/page.h 2007-05-14 14:35:02.000000000 +0200
@@ -87,18 +87,18 @@ typedef l4_pgentry_t root_pgentry_t;
#define _PAGE_NX (cpu_has_nx ? _PAGE_NX_BIT : 0U)
/*
- * Disallow unused flag bits plus PAT, PSE and GLOBAL.
+ * Disallow unused flag bits plus PAT/PSE and GLOBAL.
* Permit the NX bit if the hardware supports it.
* Note that range [62:52] is available for software use on x86/64.
*/
#define BASE_DISALLOW_MASK (0xFF800180U & ~_PAGE_NX)
#define L1_DISALLOW_MASK (BASE_DISALLOW_MASK | _PAGE_GNTTAB)
-#define L2_DISALLOW_MASK (BASE_DISALLOW_MASK)
-#define L3_DISALLOW_MASK (BASE_DISALLOW_MASK)
-#define L4_DISALLOW_MASK (BASE_DISALLOW_MASK)
+#define L2_DISALLOW_MASK (BASE_DISALLOW_MASK | _PAGE_PCD | _PAGE_PWT)
+#define L3_DISALLOW_MASK (BASE_DISALLOW_MASK | _PAGE_PCD | _PAGE_PWT)
+#define L4_DISALLOW_MASK (BASE_DISALLOW_MASK | _PAGE_PCD | _PAGE_PWT)
-#define COMPAT_L3_DISALLOW_MASK 0xFFFFF1E6U
+#define COMPAT_L3_DISALLOW_MASK 0xFFFFF1FEU
#define PAGE_HYPERVISOR (__PAGE_HYPERVISOR | _PAGE_GLOBAL)
#define PAGE_HYPERVISOR_NOCACHE (__PAGE_HYPERVISOR_NOCACHE | _PAGE_GLOBAL)
++++++ ptwr-sanity.patch ++++++
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) )
++++++ realmode.patch ++++++
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 = .;
++++++ svm-reg-save.patch ++++++
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
++++++ vgacon-50-lines.patch ++++++
--- /var/tmp/diff_new_pack.y15063/_old 2007-05-21 22:27:54.000000000 +0200
+++ /var/tmp/diff_new_pack.y15063/_new 2007-05-21 22:27:54.000000000 +0200
@@ -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] != '-' )
++++++ vgacon-keep.patch ++++++
--- /var/tmp/diff_new_pack.y15063/_old 2007-05-21 22:27:54.000000000 +0200
+++ /var/tmp/diff_new_pack.y15063/_new 2007-05-21 22:27:54.000000000 +0200
@@ -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 @@
+ 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 @@
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)
{
++++++ vmx-no-cstar.patch ++++++
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;
++++++ vnc-i18n-keys.diff ++++++
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
++++++ x86_emulate.patch ++++++
++++ 609 lines (skipped)
++++ between arch/i386/xen/x86_emulate.patch
++++ and xen/x86_emulate.patch
++++++ x86-extra-trap-info.patch ++++++
--- /var/tmp/diff_new_pack.y15063/_old 2007-05-21 22:27:54.000000000 +0200
+++ /var/tmp/diff_new_pack.y15063/_new 2007-05-21 22:27:54.000000000 +0200
@@ -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 @@
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
++++++ x86-nmi-inject.patch ++++++
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
++++++ xen-enable-hvm-debug.diff ++++++
--- /var/tmp/diff_new_pack.y15063/_old 2007-05-21 22:27:55.000000000 +0200
+++ /var/tmp/diff_new_pack.y15063/_new 2007-05-21 22:27:55.000000000 +0200
@@ -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 @@
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 @@
#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 @@
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 @@
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)
++++++ xen-rpmoptflags.diff ++++++
--- /var/tmp/diff_new_pack.y15063/_old 2007-05-21 22:27:55.000000000 +0200
+++ /var/tmp/diff_new_pack.y15063/_new 2007-05-21 22:27:55.000000000 +0200
@@ -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
++++++ xen-vm-install.tar.bz2 ++++++
diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/xen-vm-install/glade/xen-vm-install.glade new/xen-vm-install/glade/xen-vm-install.glade
--- old/xen-vm-install/glade/xen-vm-install.glade 2007-04-06 01:22:11.000000000 +0200
+++ new/xen-vm-install/glade/xen-vm-install.glade 2007-05-18 20:42:57.000000000 +0200
@@ -6580,7 +6580,7 @@
<widget class="GtkHBox" id="hbox71">
<property name="visible">True</property>
<property name="homogeneous">False</property>
- <property name="spacing">0</property>
+ <property name="spacing">10</property>
<child>
<widget class="GtkComboBoxEntry" id="disk-location">
diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/xen-vm-install/src/disks.py new/xen-vm-install/src/disks.py
--- old/xen-vm-install/src/disks.py 2007-03-15 22:18:14.000000000 +0100
+++ new/xen-vm-install/src/disks.py 2007-05-18 22:55:15.000000000 +0200
@@ -89,13 +89,13 @@
vdevType = self.DEVICE_DISK
# Must specify at least one of vdev or options
-
+
self._created = False
self.options = options
self.disk_group = disk_group
self._pdevDriver = pdevDriver
self._mb = mb
-
+
self.set_pdev(pdev)
self.set_vdev(vdev)
self.set_vdevtype(vdevType)
@@ -109,13 +109,13 @@
def set_disk_group(self, disk_group):
self._disk_group = disk_group
disk_group = property(get_disk_group, set_disk_group)
-
+
def update(self, options):
self.options = options
-
+
def copy(self):
disk = XenDisk(pdev=self._pdev, vdev=self._vdev, vdevType=self._vdevType, ro=self._ro,
- mb=self._mb, sparse=self._sparse, pdevDriver=self._pdevDriver,
+ mb=self._mb, sparse=self._sparse, pdevDriver=self._pdevDriver,
options=self.options)
disk._pdev_auto = self._pdev_auto
return disk
@@ -123,7 +123,16 @@
def exists(self):
return self._exists
- def setup(self):
+ def setup_time(self):
+ """Returns a unit-less number, which attempts to describe the relative
+ amount of time it will take to set up the disk."""
+ if self._exists:
+ return 0.1
+ if self._sparse:
+ return 1.0
+ return self._mb / 20.0
+
+ def setup(self, progress=lambda f:None):
if self._pdev:
self._pdev = os.path.abspath(self._pdev)
self.validate()
@@ -133,10 +142,11 @@
if not os.path.exists(dpath):
os.makedirs(dpath)
log.info("Creating disk %s" % self.pdev)
- util.createEmptyImage(self.pdev, long(self._mb * 1024L * 1024L), sparse=self._sparse)
+ util.createEmptyImage(self.pdev, long(self._mb * 1024L * 1024L), sparse=self._sparse, progress=progress)
self._exists = True
self._created = True
self.is_block = False
+ progress(1.0)
def reset(self):
"""If the disk was created, destroys the disk image and allows the disk
@@ -259,30 +269,34 @@
def set_pdev(self, pdev):
self._pdev_auto = None
self.is_block = None
- self._mb = None
if pdev:
self._pdev = pdev
self._exists = os.path.exists(self._pdev)
if self._exists:
stats = os.stat(self._pdev)
- mode = stats[stat.ST_MODE]
+ mode = stats.st_mode
if stat.S_ISBLK(mode):
self.is_block = True
- self._mb = stats[stat.ST_SIZE] / (1024*1024.0) # FIXME - get size of block dev
+ try:
+ f = open(self._pdev)
+ f.seek(0, 2) # seek to end
+ self._mb = f.tell() / (1024*1024.0)
+ except:
+ self._mb = 1
elif stat.S_ISREG(mode):
self.is_block = False
# 0 byte file is a special case, for temp disks
- if stats[stat.ST_SIZE] == 0:
+ if stats.st_size == 0:
self._exists = False
- if self._mb is None:
- self._mb = 1
+ self._mb = 1
else:
- self._mb = stats[stat.ST_SIZE] / (1024*1024.0)
+ self._mb = stats.st_size / (1024*1024.0)
else:
# This is an invalid state (is_block is None and exists)
# but will be caught later in validate().
pass
else:
+ self._mb = None
self._pdev = None
self._exists = False
self.set_driver(self._pdevDriver)
@@ -294,9 +308,7 @@
if self._vdevType == self.DEVICE_CDROM:
ro = True
elif self._exists:
- stats = os.stat(self.pdev)
- mode = stats[stat.ST_MODE]
- if (mode & stat.S_IWRITE) == 0:
+ if (os.stat(self.pdev).st_mode & stat.S_IWRITE) == 0:
ro = True
self._ro = ro
ro = property(get_ro, set_ro)
diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/xen-vm-install/src/gui/gjob.py new/xen-vm-install/src/gui/gjob.py
--- old/xen-vm-install/src/gui/gjob.py 2007-05-09 00:32:45.000000000 +0200
+++ new/xen-vm-install/src/gui/gjob.py 2007-05-18 18:18:16.000000000 +0200
@@ -36,7 +36,9 @@
self.errors.insert(0, text)
self.emit('install-show-error')
def _stateChangeCB(job, state):
- self.emit('install-progress-change', state[2], (state[0]+1) / float(state[1]))
+ self.emit('install-progress-change', state[2], -1.0)
+ def _progressChangeCB(job, fraction):
+ self.emit('install-progress-change', '', fraction)
def _consoleCB(job):
return self.emit('install-show-console', job.guest.uuid)
def _finish_worker():
@@ -45,7 +47,8 @@
self.job.run(GetSettingsCB=_getSettingsCB,
StateChangeCB=_stateChangeCB,
ConsoleCB=_consoleCB,
- ErrorCB=_errorCB)
+ ErrorCB=_errorCB,
+ ProgressCB=_progressChangeCB)
except Exception, e:
xen.install.log.error("VM creation job failed: %s" % str(e))
self.emit('install-progress-close')
diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/xen-vm-install/src/gui/gui.py new/xen-vm-install/src/gui/gui.py
--- old/xen-vm-install/src/gui/gui.py 2007-05-09 03:39:04.000000000 +0200
+++ new/xen-vm-install/src/gui/gui.py 2007-05-18 23:16:28.000000000 +0200
@@ -65,7 +65,7 @@
return str(name)
def set_combo_from_list(combo, items):
- """Setup a ComboBox or ComboBoxEntry based on a list of strings."""
+ """Setup a ComboBox or ComboBoxEntry based on a list of strings."""
model = gtk.ListStore(gobject.TYPE_STRING)
for item in items:
model.append([item])
@@ -118,13 +118,11 @@
pass
if info:
self.xen_info = info
-
+
def __init__(self, job=None, options=None, defaults=None, virtman=False, key=0):
self.__gobject_init__()
- if job is None:
- job = xen.install.Job(background=False)
- self.job = job
+ self.job = job or xen.install.Job(background=False)
if options is None:
options = xen.install.Options()
defaults = xen.install.Options()
@@ -135,7 +133,7 @@
self.xen_info = None
self.refresh_xen_info()
-
+
self.virtman = virtman
self.key = key
@@ -414,12 +412,12 @@
self.disk_caller_page = 'pv_install'
self.disks_widget.set_disks(self.defaults.disks)
self.do_new_cdrom(button)
-
+
def do_new_fv_cdrom(self, button):
self.disk_caller_page = 'fv_install'
self.disks_widget.set_disks(self.defaults.disks)
self.do_new_cdrom(button)
-
+
def do_new_cdrom(self, button):
# mb is specified to pacify the constructor in case the default
# cdrom does not exist; disk.validate will ensure it does exist.
@@ -849,11 +847,13 @@
pbar = pbar_glade.get_widget("pbar")
label = pbar_glade.get_widget("status")
errors = []
+
def do_progress_change(src, text, fraction):
gtk.gdk.threads_enter()
if text:
label.set_text(text)
- pbar.set_fraction(fraction)
+ if fraction >= 0.0 and fraction <= 1.0:
+ pbar.set_fraction(fraction)
gtk.gdk.threads_leave()
def do_progress_close(src):
if pbar_win is None:
@@ -875,9 +875,11 @@
signal = 'action-show-console'
xen.install.log.info("%s of %s via virt-manager" % (signal, uuid))
def poke_virt_man():
+ gtk.gdk.threads_enter()
self.emit(signal, 'xen', uuid)
pbar_win.hide()
self.topwin.hide()
+ gtk.gdk.threads_leave()
return False # Do not call me again
# virt-manager (and libvirt) poll. Asking virt-manager to open
# the console too soon after the VM has started will fail.
diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/xen-vm-install/src/job.py new/xen-vm-install/src/job.py
--- old/xen-vm-install/src/job.py 2007-05-09 01:06:50.000000000 +0200
+++ new/xen-vm-install/src/job.py 2007-05-18 23:15:57.000000000 +0200
@@ -50,15 +50,14 @@
def __init__(self, background, debug=False):
"""Creates a job."""
self._states = (
- (Job.SETTINGS, msg.job_settings, 'settings'),
- (Job.PREP_INSTALL, msg.job_prep_install, 'prep_install'),
- (Job.INSTALL, msg.job_install, 'install'),
- (Job.POST_INSTALL, msg.job_post_install, 'post_install'),
- (Job.RUNTIME_CONF, msg.job_runtime_conf, 'runtime_conf'),
- (Job.RUNTIME, msg.job_runtime, 'runtime'),
- (Job.FINISHED, msg.job_finished, 'finish'),
+ (Job.SETTINGS, msg.job_settings, 'settings', 0.02),
+ (Job.PREP_INSTALL, msg.job_prep_install, 'prep_install', 0.80),
+ (Job.INSTALL, msg.job_install, 'install', 0.02),
+ (Job.POST_INSTALL, msg.job_post_install, 'post_install', 0.10),
+ (Job.RUNTIME_CONF, msg.job_runtime_conf, 'runtime_conf', 0.02),
+ (Job.RUNTIME, msg.job_runtime, 'runtime', 0.02),
+ (Job.FINISHED, msg.job_finished, 'finish', 0.02),
)
- self._StateChangeCB = self._GetSettingsCB = self._ConsoleCB = self._ErrorCB = None
self._guest = None
self._state_num = Job.SETTINGS
self._options = None
@@ -118,7 +117,7 @@
self.jobfd = os.open(self.jobfn, os.O_WRONLY | os.O_TRUNC)
os.write(self.jobfd, s)
os.close(self.jobfd)
- self.jobfd = None
+ self.jobfd = None
def _cleanup_conf(self):
if self._state_num == Job.FINISHED:
@@ -174,15 +173,13 @@
except NotImplementedError:
try_text = True
except RuntimeError, e:
- if self._ErrorCB:
- self._ErrorCB(self, str(e))
+ self._ErrorCB(self, str(e))
if try_text or self._options.graphics_viewer == 'none':
log.debug('Viewer is text')
try:
child = console.text_console(self.guest, detach=detached)
except NotImplementedError:
- if self._ErrorCB:
- self._ErrorCB(self, msg.display_failed)
+ self._ErrorCB(self, msg.display_failed)
if child is None:
if not detached:
log.debug('Not detached but no child; wait for VM to exit')
@@ -193,7 +190,8 @@
(pid, status) = os.waitpid(child, 0)
log.debug('Not detached; done waiting')
- def run(self, GetSettingsCB, StateChangeCB=None, ConsoleCB=None, ErrorCB=None):
+ def run(self, GetSettingsCB, StateChangeCB=lambda job,state:None, ConsoleCB=None, \
+ ErrorCB=lambda job,msg:None, ProgressCB=lambda job,f:None):
"""Starts the VM creation job.
GetSettingsCB: Called with job to get user's VM settings. Return XenGuest.
@@ -203,18 +201,26 @@
self._GetSettingsCB = GetSettingsCB
self._ConsoleCB = ConsoleCB
self._ErrorCB = ErrorCB
+ self._ProgressCB = ProgressCB
self._cancel = False
+ progress = util.filtered_progress(lambda f:self._ProgressCB(self, f))
+
try:
- for state in self._states:
- self._state_num = state[0]
- self._update_job_file()
- if self._StateChangeCB:
+ try:
+ done = 0.0
+ for state in self._states:
+ self._state_num = state[0]
+ self._update_job_file()
self._StateChangeCB(self, self.state)
- eval('self._state_%s()' % state[2])
- if self._cancel:
- log.debug("Job's cancel flag was set")
- raise JobError(JobError.E_CANCELED)
+ func = eval('self._state_%s' % state[2])
+ func(lambda f:progress(done+f*state[3]))
+ done += state[3]
+ if self._cancel:
+ log.debug("Job's cancel flag was set")
+ raise JobError(JobError.E_CANCELED)
+ except KeyboardInterrupt:
+ raise JobError(JobError.E_CANCELED)
except Error, e:
log.info("xen.install.Error caught in job.run: %s" % str(e))
if self._guest:
@@ -256,7 +262,7 @@
if uuid:
log.debug("Destroying VM %s" % uuid)
xend.connection.destroy(uuid)
-
+
def get_guest(self):
return self._guest
guest = property(get_guest)
@@ -265,24 +271,26 @@
return (self._state_num, len(self._states), self._states[self._state_num][1])
state = property(get_state)
- def _state_settings(self):
+ def _state_settings(self, progress):
if not caps.is_dom0():
raise XenError(XenError.E_NO_XEN)
if os.geteuid() != 0:
raise XenError(XenError.E_ROOT)
self._options = self._GetSettingsCB(self)
+ progress(0.5)
if self._options.full_virt:
self._guest = FullVirtGuest(self._options)
else:
self._guest = ParaVirtGuest(self._options)
+ progress(1.0)
- def _state_prep_install(self):
+ def _state_prep_install(self, progress):
if not self._options.install:
return
- self.guest.PreInstall()
+ self.guest.PreInstall(lambda f:progress(f*0.98))
conf = self.guest.GetConfigXml()
self._xml_conf = os.path.join(paths.configdir, self.guest.options.name + '.xml')
@@ -294,38 +302,47 @@
f = open(self._xen_conf, "w+")
f.write(conf)
f.close()
+ progress(1.0)
- def _state_install(self):
+ def _state_install(self, progress):
if not self._options.install:
return
self.guest.Start()
if not self._cancel:
+ progress(0.5)
self.show_console()
+ progress(0.9)
self.guest.Stop()
+ progress(1.0)
- def _state_post_install(self):
+ def _state_post_install(self, progress):
log.info("Post install check...")
self.guest.PostInstallCheck()
+ progress(1.0)
- def _state_runtime_conf(self):
+ def _state_runtime_conf(self, progress):
log.info("Post install configuration...")
self.guest.PostInstallConf()
+ progress(0.9)
log.info("Writing runtime configuration file...")
conf = self.guest.GetConfigXen()
cf = os.path.join(paths.configdir, self.guest.options.name)
f = open(cf, 'w+')
f.write(conf)
f.close()
+ progress(1.0)
- def _state_runtime(self):
+ def _state_runtime(self, progress):
if self._options.norestart:
return
self.guest.start_from_disk()
+ progress(0.5)
self.show_console()
+ progress(1.0)
- def _state_finish(self):
+ def _state_finish(self, progress):
self.job_exit = 0
- pass
+ progress(1.0)
def _get_job_filename(job_id):
diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/xen-vm-install/src/nics.py new/xen-vm-install/src/nics.py
--- old/xen-vm-install/src/nics.py 2007-03-29 22:13:19.000000000 +0200
+++ new/xen-vm-install/src/nics.py 2007-05-10 19:40:59.000000000 +0200
@@ -108,9 +108,10 @@
def copy(self):
return XenNic(number=self.number, mac=self.mac, bridge=self.bridge, model=self._model, full_virt=self.full_virt)
- def setup(self):
+ def setup(self, progress=lambda f:None):
if self.mac is None:
self.mac = randomMAC()
+ progress(1.0)
def update(self, full_virt):
if self._model is not None and self._model != 'para' and not full_virt:
diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/xen-vm-install/src/ParaVirtGuest.py new/xen-vm-install/src/ParaVirtGuest.py
--- old/xen-vm-install/src/ParaVirtGuest.py 2007-03-29 19:47:04.000000000 +0200
+++ new/xen-vm-install/src/ParaVirtGuest.py 2007-05-10 23:50:50.000000000 +0200
@@ -53,7 +53,7 @@
XenGuest.__init__(self, options)
self.runtime = {}
- def _get_paravirt_images(self, disk, partitions, copy):
+ def _get_paravirt_images(self, disk, partitions, copy, progress=lambda f:None):
def traildigits(strg):
"Return the trailing digits, used to split the partition number off"
idx = len(strg)-1
@@ -91,9 +91,11 @@
return (vpart, kernel, initrd)
finally:
vdisk.unmount()
+ progress(1.0)
+ progress(1.0)
return (None, None, None)
- def _get_paravirt_install_images(self):
+ def _get_paravirt_install_images(self, progress=lambda f:None):
"""Retrieves the kernel and initrd from the installation source.
Potentially a heavy-weight operation."""
actions = VMDefaults[self.options.os_type].actions()
@@ -110,12 +112,12 @@
mountpoint = mounted_disk.mount()
except Exception, e:
raise InstSrcError(InstSrcError.E_BAD, details=e.args[0])
- (kfn, ifn) = actions.getInstallImagesFromPath(mountpoint)
+ (kfn, ifn) = actions.getInstallImagesFromPath(mountpoint, progress)
mounted_disk.unmount()
else:
- (_, kfn, ifn) = self._get_paravirt_images(source, partitions, copy=True)
+ (_, kfn, ifn) = self._get_paravirt_images(source, partitions, copy=True, progress=progress)
else:
- (kfn, ifn) = actions.getInstallImagesFromUrl(source)
+ (kfn, ifn) = actions.getInstallImagesFromUrl(source, progress)
if kfn is None:
raise InstSrcError(InstSrcError.E_BAD, details=str(source))
return (kfn, ifn)
@@ -196,10 +198,10 @@
%(graphics)s
""" % { 'common': self.getCommonXen(), 'osblob': osblob, 'disks': self._get_disk_xen(), 'networks': self._get_network_xen(), 'graphics': self._get_graphics_xen() }
- def PreInstall(self):
- XenGuest.PreInstall(self)
+ def PreInstall(self, progress=lambda f:None):
+ XenGuest.PreInstall(self, lambda f:progress(f*0.5))
self._cleanup_kernel() # In case the install was retried
- (self.kernel, self.initrd) = self._get_paravirt_install_images()
+ (self.kernel, self.initrd) = self._get_paravirt_install_images(lambda f:progress(0.5+f*0.5))
def PostInstallCheck(self):
self._cleanup_kernel() # Regardless of success or failure, no longer needed
diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/xen-vm-install/src/util.py new/xen-vm-install/src/util.py
--- old/xen-vm-install/src/util.py 2007-03-29 19:46:12.000000000 +0200
+++ new/xen-vm-install/src/util.py 2007-05-18 22:34:19.000000000 +0200
@@ -64,7 +64,7 @@
# See http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/148061
rx=re.compile(u"([\u2e80-\uffff])", re.UNICODE)
def wrap(text, width=79, encoding="utf8"):
- return reduce(lambda line, word, width=width: '%s%s%s' %
+ return reduce(lambda line, word, width=width: '%s%s%s' %
(line,
[' ','\n', ''][(len(line)-line.rfind('\n')-1
+ len(word.split('\n',1)[0] ) >= width) or
@@ -80,19 +80,40 @@
backitems.sort()
return [ backitems[i][1] for i in xrange(0, len(backitems))]
-def copy_to_temp(fileobj, prefix):
+def filtered_progress(fn, step=0.01):
+ """Returns a function which takes a fraction (0.0 .. 1.0) describing
+ progress. When the progress advances beyond a specified step size,
+ the function calls 'fn' with the current progress."""
+ def p(f):
+ if f < p.f + step:
+ return
+ p.f = f
+ fn(p.f)
+ p.f = 0.0
+ fn(p.f)
+ return p
+
+def copy_to_temp(fileobj, prefix, progress=lambda f:None):
(fd, fn) = tempfile.mkstemp(prefix=prefix)
log.debug("Copying to temporary file '%s'" % fn)
- block_size = 16384
+ read = size = 0
+ try:
+ size = os.fstat(fileobj.fileno()).st_size
+ except:
+ pass
+ block_size = 65536
while 1:
buff = fileobj.read(block_size)
if not buff:
break
+ read += len(buff)
os.write(fd, buff)
+ if read <= size: # Some file objects can't accurately report size
+ progress(float(read) / float(size))
os.close(fd)
return fn
-def createEmptyImage(filename, size, sparse=True):
+def createEmptyImage(filename, size, sparse=True, progress=lambda f:None):
s = ''
if sparse:
s = 'sparse '
@@ -106,23 +127,28 @@
else:
block_size = 65536
data = '\x00' * block_size
- blocks = size / block_size
+ blocks = remaining = size / block_size
block = 0
- while blocks:
+ while remaining:
os.write(fd, data)
- blocks -= 1
+ remaining -= 1
block += 1
+ if (block & 1023) == 0:
+ progress(float(block) / float(blocks))
os.close(fd)
+ progress(1.0)
-def mke2fsImage(filename):
- args = ['/sbin/mkfs.ext2', '-F', '-m', '0', '--', filename]
+def mke2fsImage(filename, progress=lambda f:None):
+ args = ['/sbin/mkfs.ext2', '-F', '-m', '0', '-q', '--', filename]
log.debug("Creating filesystem: %s" % str(args))
run(args)
+ progress(1.0)
-def mkdosfsImage(filename):
+def mkdosfsImage(filename, progress=lambda f:None):
args = ['/sbin/mkdosfs', '--', filename]
log.debug("Creating filesystem: %s" % str(args))
run(args)
+ progress(1.0)
# the following three functions are from xend/uuid.py and are thus
# available under the LGPL,
diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/xen-vm-install/src/VMActions.py new/xen-vm-install/src/VMActions.py
--- old/xen-vm-install/src/VMActions.py 2007-03-15 19:33:08.000000000 +0100
+++ new/xen-vm-install/src/VMActions.py 2007-05-10 22:38:14.000000000 +0200
@@ -15,11 +15,12 @@
class VMActions:
"""Actions that are specific to a particular OS type within a VM."""
- def getInstallImagesFromPath(self, root):
+ def getInstallImagesFromPath(self, root, progress=lambda f:None):
"""Locates or creates a Xen-enabled kernel and initrd under 'root' to bootstrap install."""
+ progress(1.0)
return (None, None)
- def getInstallImagesFromUrl(self, url):
+ def getInstallImagesFromUrl(self, url, progress=lambda f:None):
"""Locates or creates a Xen-enabled kernel and initrd from 'url' to bootstrap install."""
raise InstSrcError(err=InstSrcError.E_UNSUPPORTED)
@@ -42,12 +43,12 @@
MUST BE IDEMPOTENT!"""
pass
- def setupOsSettings(self, guest):
+ def setupOsSettings(self, guest, progress=lambda f:None):
"""Prepares the guest to use the guest.os_settings file or URL.
For example, this may create a temporary disk image to contain
guest.os_settings, and add the disk to guest.tmpdisks."""
- pass
+ progress(1.0)
def postInstall(self, guest):
"""Give the guest a chance to massage options, after first stage
diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/xen-vm-install/src/VMDefaults.py new/xen-vm-install/src/VMDefaults.py
--- old/xen-vm-install/src/VMDefaults.py 2007-05-09 03:53:39.000000000 +0200
+++ new/xen-vm-install/src/VMDefaults.py 2007-05-04 20:58:59.000000000 +0200
@@ -114,8 +114,6 @@
def prefers_full(self):
# RHEL4 doesn't support para, but RHEL4 update 8 does.
return True
- def apic(self):
- return True
def min_memory(self):
return 256
def max_memory(self):
diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/xen-vm-install/src/VMNetWare.py new/xen-vm-install/src/VMNetWare.py
--- old/xen-vm-install/src/VMNetWare.py 2007-03-15 16:21:53.000000000 +0100
+++ new/xen-vm-install/src/VMNetWare.py 2007-05-18 22:35:44.000000000 +0200
@@ -25,13 +25,13 @@
def _kernel(self, base):
return '%s/STARTUP/XNLOADER.SYS' % (base,)
- def getInstallImagesFromPath(self, path):
+ def getInstallImagesFromPath(self, path, progress=lambda f:None):
"""Retrieves a Xen-enabled NetWare kernel and initrd.
Retrieves a Xen-enabled NetWare kernel from the base path, and
copies it to a temporary file. Returns the (kernel, None) tuple of
filenames."""
- kfn = util.copy_to_temp(open(self._kernel(path), 'r'), prefix='netware.')
+ kfn = util.copy_to_temp(open(self._kernel(path), 'r'), prefix='netware.', progress=progress)
return (kfn, None)
def getRuntimeImagesFromPath(self, root):
@@ -42,14 +42,16 @@
return (kernel, None)
return (None, None)
- def setupOsSettings(self, guest):
+ def setupOsSettings(self, guest, progress=lambda f:None):
"""Creates a temporary disk image, in which to pass the NetWare
response file."""
if not guest.options.os_settings:
+ progress(1.0)
return
if guest.options.full_virt:
# FIXME: Need to support qemu's floppies...
+ progress(1.0)
return
(fd, tmpdisk) = tempfile.mkstemp(prefix='netware-rsp.')
@@ -57,14 +59,14 @@
# Nominal "1.44 MB floppy" == 1440 KB == 1406.25 KiB == 1.40625 MiB
disk = XenDisk(pdev=tmpdisk, ro=True, mb=1.40625, options=guest.options,
disk_group=guest.options.disks)
- disk.setup()
- util.mkdosfsImage(disk.pdev)
+ disk.setup(lambda f:progress(f*0.5))
+ util.mkdosfsImage(disk.pdev, lambda f:progress(0.5+f*0.25))
mounted_disk = mount.TemporaryLoopMount(disk.pdev)
mountpoint = mounted_disk.mount(options='loop')
+ progress(0.8)
rf = False
try:
- stats = os.stat(guest.options.os_settings)
- mode = stats[stat.ST_MODE]
+ mode = os.stat(guest.options.os_settings).st_mode
if stat.S_ISREG(mode):
shutil.copyfile(guest.options.os_settings, mountpoint + '/netware.rsp')
rf = True
@@ -73,7 +75,7 @@
nlf = re.compile('.*\.nlf$', re.IGNORECASE)
nodes = os.listdir(guest.options.os_settings)
for node in nodes:
- mode = os.stat('%s/%s' % (guest.options.os_settings, node))[stat.ST_MODE]
+ mode = os.stat('%s/%s' % (guest.options.os_settings, node)).st_mode
if not stat.S_ISREG(mode):
continue
if not rf and rsp.match(node):
@@ -88,10 +90,12 @@
'%s/%s' % (mountpoint, dst))
else:
raise ParamError(err=ParamError.E_INVALID, desc='os-settings')
+ progress(0.9)
finally:
mounted_disk.unmount()
+ progress(1.0)
if rf:
- guest.options._install_args = " [INST: rf=a:netware.rsp]"
+ guest.options._install_args = ' [INST: rf=a:netware.rsp]'
except:
os.unlink(tmpdisk)
raise
diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/xen-vm-install/src/VMRedHat.py new/xen-vm-install/src/VMRedHat.py
--- old/xen-vm-install/src/VMRedHat.py 2007-03-15 19:35:29.000000000 +0100
+++ new/xen-vm-install/src/VMRedHat.py 2007-05-10 22:52:42.000000000 +0200
@@ -24,35 +24,42 @@
def _initrd(self, base):
return '%s/images/xen/initrd.img' % (base,)
- def getInstallImagesFromUrl(self, url):
+# def _getHostAndPathFromNFS(self, url):
+ # RedHat NFS URLs are of the form:
+ # nfs:host:/path/to/install/source
+ # SUSE's are of the form:
+ # nfs://host/path/to/install/source
+
+ def getInstallImagesFromUrl(self, url, progress=lambda f:None):
"""Retrieves a Xen-enabled RedHat kernel and initrd from the URL, and
copies them to temporary files. Returns the (kernel, initrd) tuple of
filenames."""
try:
if url.startswith('http://') or url.startswith('ftp://'):
- kfd = grabber.urlopen(self._kernel(url))
- ifd = grabber.urlopen(self._initrd(url))
+ kfd = grabber.urlopen(self._kernel(url), lambda f:progress(f*0.4))
+ ifd = grabber.urlopen(self._initrd(url), lambda f:progress(0.4+f*0.4))
elif url.startswith('nfs:'):
mnt = mount.TemporaryMount(url[4:])
mountpoint = mnt.mount(mnt)
kfd = open(self._kernel(mountpoint), 'r')
ifd = open(self._initrd(mountpoint), 'r')
+ progress(0.8)
else:
raise InstSrcError(err=InstSrcError.E_UNSUPPORTED, details=url)
except IOError, e:
raise RuntimeError(msg.invalid_url + ': ' + str(e))
- kfn = util.copy_to_temp(kfd, prefix='vmlinuz.')
- ifn = util.copy_to_temp(ifd, prefix='initrd.')
+ kfn = util.copy_to_temp(kfd, prefix='vmlinuz.', progress=lambda f:progress(0.8+f*0.1))
+ ifn = util.copy_to_temp(ifd, prefix='initrd.', progress=lambda f:progress(0.9+f*0.1))
return (kfn, ifn)
- def getInstallImagesFromPath(self, path):
+ def getInstallImagesFromPath(self, path, progress=lambda f:None):
"""Retrieves a Xen-enabled RedHat kernel and initrd from the base path, and
copies them to temporary files. Returns the (kernel, initrd) tuple of
filenames."""
kfd = open(self._kernel(path), 'r')
ifd = open(self._initrd(path), 'r')
- kfn = util.copy_to_temp(kfd, prefix='vmlinuz.')
- ifn = util.copy_to_temp(ifd, prefix='initrd.')
+ kfn = util.copy_to_temp(kfd, prefix='vmlinuz.', progress=lambda f:progress(f*0.5))
+ ifn = util.copy_to_temp(ifd, prefix='initrd.', progress=lambda f:progress(0.5+f*0.5))
return (kfn, ifn)
def getInstallArgs(self, options):
diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/xen-vm-install/src/VMSUSE.py new/xen-vm-install/src/VMSUSE.py
--- old/xen-vm-install/src/VMSUSE.py 2007-04-05 22:52:26.000000000 +0200
+++ new/xen-vm-install/src/VMSUSE.py 2007-05-18 22:37:17.000000000 +0200
@@ -16,7 +16,6 @@
import os
import re
import shutil
-import stat
import tempfile
import urlgrabber.grabber as grabber
@@ -33,8 +32,7 @@
def die_zero(fn):
try:
- stats = os.stat(fn)
- if not stats[stat.ST_SIZE]:
+ if not os.stat(fn).st_size:
raise RuntimeError
except:
try:
@@ -61,7 +59,7 @@
def _getPackageNamesByArch(self, base, lines, arch, ext):
kernel = 'kernel-' + ext
log.debug("Searching for %s %s" % (arch, kernel))
-
+
kernel_rpm = initrd_rpm = None
kernel_disc = initrd_disc = None
# The packages may or may not have a version.
@@ -94,27 +92,31 @@
details=base)
return [kernel_disc, kernel_rpm, initrd_disc, initrd_rpm]
- def _buildInitrd(self, krpm, irpm):
+ def _buildInitrd(self, krpm, irpm, progress=lambda f:None):
(fd, ifn) = tempfile.mkstemp(prefix='inst-initrd.')
tmpdir = tempfile.mkdtemp()
log.info("Building inst-initrd...")
try:
os.system("cd -- '%s' && /usr/bin/rpm2cpio '%s' | /usr/bin/cpio -idum 2>/dev/null" % \
(tmpdir, irpm))
+ progress(0.2)
os.system("%s/usr/sbin/mkinstallinitrd --kernel-rpm '%s' --libdir '%s' '%s'" % \
(tmpdir, krpm, tmpdir + '/usr/lib/install-initrd', ifn))
+ progress(0.9)
finally:
os.system("/bin/rm -rf -- '%s'" % (tmpdir,))
os.unlink(irpm)
+ progress(1.0)
return ifn
- def _extractKernel(self, krpm, ext):
+ def _extractKernel(self, krpm, ext, progress=lambda f:None):
(fd, kfn) = tempfile.mkstemp(prefix='vmlinuz-%s.' % ext)
tmpdir = tempfile.mkdtemp()
log.info("Extracting kernel from '%s' to '%s'" % (krpm, kfn))
try:
os.system("cd -- '%s' && /usr/bin/rpm2cpio '%s' | /usr/bin/cpio -idum -- '%s' 2>/dev/null" % \
(tmpdir, krpm, './boot/vmlinuz-*-' + ext))
+ progress(0.8)
kernels = glob.glob('%s/boot/vmlinuz-*-%s' % (tmpdir, ext))
for kernel in kernels:
if not os.path.islink(kernel):
@@ -124,10 +126,10 @@
finally:
os.system("/bin/rm -rf -- '%s'" % (tmpdir,))
os.unlink(krpm)
- pass
+ progress(1.0)
return kfn
- def getInstallImagesFromPath(self, root):
+ def getInstallImagesFromPath(self, root, progress=lambda f:None):
"""Retrieves a Xen-enabled SUSE kernel and initrd from the base path, and
copies them to temporary files. Returns the (kernel, initrd) tuple of
filenames."""
@@ -142,8 +144,8 @@
log.debug("Unpacked kernel/initrd found: %s %s" % (kfn, ifn))
kfd = open(kfn, 'r')
ifd = open(ifn, 'r')
- self.kfn = util.copy_to_temp(kfd, prefix='kernel.')
- self.ifn = util.copy_to_temp(ifd, prefix='install-initrd.')
+ self.kfn = util.copy_to_temp(kfd, prefix='kernel.', progress=lambda f:progress(f*0.5))
+ self.ifn = util.copy_to_temp(ifd, prefix='install-initrd.', progress=lambda f:progress(0.5+f*0.5))
return (self.kfn, self.ifn)
log.debug("No unpacked kernel/initrd found")
index_path = root + '/INDEX.gz'
@@ -156,18 +158,18 @@
(arch, ext, kernel_disc, kernel_rpm, initrd_disc, initrd_rpm) = self._getPackageNames(root, fobj)
# FIXME: may have to prompt to swap CDs...
-
+
kfd = open('%s/suse/%s/%s' % (root, arch, kernel_rpm), 'r')
- krpm = util.copy_to_temp(kfd, prefix='kernel.')
-
+ krpm = util.copy_to_temp(kfd, prefix='kernel.', progress=lambda f:progress(f*0.1))
+
ifd = open('%s/suse/%s/%s' % (root, arch, initrd_rpm), 'r')
- irpm = util.copy_to_temp(ifd, prefix='install-initrd.')
- self.ifn = self._buildInitrd(krpm, irpm)
- self.kfn = self._extractKernel(krpm, ext)
+ irpm = util.copy_to_temp(ifd, prefix='install-initrd.', progress=lambda f:progress(0.1+f*0.1))
+ self.ifn = self._buildInitrd(krpm, irpm, lambda f:progress(0.2+f*0.4))
+ self.kfn = self._extractKernel(krpm, ext, lambda f:progress(0.6+f*0.4))
log.debug("Extracted installation kernel/initrd: %s %s" % (self.kfn, self.ifn))
return (self.kfn, self.ifn)
- def getInstallImagesFromUrl(self, url):
+ def getInstallImagesFromUrl(self, url, progress=lambda f:None):
"""Retrieves a Xen-enabled SUSE kernel and initrd from the URL, and
copies them to temporary files. Returns the (kernel, initrd) tuple of
filenames."""
@@ -194,6 +196,7 @@
else:
# This should never happen (unless VMDefaults are out of sync?)
raise InstSrcError(err=InstSrcError.E_UNSUPPORTED, details=url)
+ progress(0.1)
arches = caps.compatible_arches()
for a in arches:
@@ -201,11 +204,11 @@
kfn = '/boot/%s/vmlinuz-%s' % (a[0], a[1])
ifn = '/boot/%s/initrd-%s' % (a[0], a[1])
kfd = urlopen(base + kfn)
- self.kfn = util.copy_to_temp(kfd, prefix='kernel.')
+ self.kfn = util.copy_to_temp(kfd, prefix='kernel.', progress=lambda f:progress(0.1+f*0.45))
kfd.close()
die_zero(self.kfn)
ifd = urlopen(base + ifn)
- self.ifn = util.copy_to_temp(ifd, prefix='install-initrd.')
+ self.ifn = util.copy_to_temp(ifd, prefix='install-initrd.', progress=lambda f:progress(0.55+f*0.45))
ifd.close()
die_zero(self.kfn)
log.debug("Unpacked kernel/initrd found: %s %s" % (kfn, ifn))
@@ -227,7 +230,7 @@
# NOTE: I can't back up above the NFS/SMB mount point, so (for
# now) no rewriting in those cases.
if ((not nfs and not smb) and kernel_disc and initrd_disc and
- (not kernel_disc.endswith('1') or not initrd_disc.endswith('1'))):
+ (not kernel_disc.endswith('1') or not initrd_disc.endswith('1'))):
diskless = base.strip('/').split('/')[:-1]
kbase = '/'.join(diskless + [kernel_disc])
ibase = '/'.join(diskless + [initrd_disc])
@@ -239,6 +242,7 @@
url = kbase + kurl
kfd = urlopen(url)
krpm = util.copy_to_temp(kfd, prefix='kernel.')
+ progress(0.15)
iurl = '/suse/%s/%s' % (arch, initrd_rpm)
log.debug("URL of initrd is %s" % iurl)
@@ -251,8 +255,9 @@
raise
except Exception, e:
raise InstSrcError(err=InstSrcError.E_BAD, desc=str(e), details=url)
- self.ifn = self._buildInitrd(krpm, irpm)
- self.kfn = self._extractKernel(krpm, ext)
+ progress(0.2)
+ self.ifn = self._buildInitrd(krpm, irpm, lambda f:progress(0.2+f*0.4))
+ self.kfn = self._extractKernel(krpm, ext, lambda f:progress(0.6+f*0.4))
log.debug("Extracted installation kernel/initrd: %s %s" % (self.kfn, self.ifn))
return (self.kfn, self.ifn)
@@ -267,8 +272,13 @@
else:
src = options.source
args += ' install=%s' % src
- if options.os_settings:
- args += ' autoyast=device://%s/autoinst.xml' % (autoyast_vdev,)
+ ay = options.os_settings
+ if ay:
+ if ay.startswith('ftp://') or ay.startswith('tftp://') or \
+ ay.startswith('http://') or ay.startswith('nfs://'):
+ args += ' autoyast=%s' % (ay,)
+ else:
+ args += ' autoyast=device://%s/autoinst.xml' % (autoyast_vdev,)
return args
def preprocessOptions(self, options):
@@ -292,23 +302,29 @@
extra_args += arg + ' '
options.extra_args = extra_args
- def setupOsSettings(self, guest):
+ def setupOsSettings(self, guest, progress=lambda f:None):
"""Creates a temporary disk image, in which to pass the autoyast
XML file."""
- if not guest.options.os_settings:
- return
- (fd, tmpdisk) = tempfile.mkstemp(prefix='autoyast.')
- disk = XenDisk(pdev=tmpdisk, vdev=autoyast_vdev, ro=True, mb=1, options=guest.options)
- try:
- disk.setup()
- util.mke2fsImage(disk.pdev)
- mounted_disk = mount.TemporaryLoopMount(disk.pdev)
- mountpoint = mounted_disk.mount(options='loop')
+ ay = guest.options.os_settings
+ if not ay or ay.startswith('ftp://') or ay.startswith('tftp://') or \
+ ay.startswith('http://') or ay.startswith('nfs://'):
+ pass
+ else:
+ (fd, tmpdisk) = tempfile.mkstemp(prefix='autoyast.')
+ disk = XenDisk(pdev=tmpdisk, vdev=autoyast_vdev, ro=True, mb=1, options=guest.options)
try:
- shutil.copyfile(guest.options.os_settings, mountpoint + '/autoinst.xml')
- finally:
- mounted_disk.unmount()
- except:
- os.unlink(tmpdisk)
- raise
- guest.tmpdisks.append(disk)
+ disk.setup(progress=lambda f:progress(f*0.5))
+ util.mke2fsImage(disk.pdev, progress=lambda f:progress(0.5+f*0.25))
+ mounted_disk = mount.TemporaryLoopMount(disk.pdev)
+ mountpoint = mounted_disk.mount(options='loop')
+ progress(0.8)
+ try:
+ shutil.copyfile(ay, mountpoint + '/autoinst.xml')
+ finally:
+ progress(0.9)
+ mounted_disk.unmount()
+ except:
+ os.unlink(tmpdisk)
+ raise
+ guest.tmpdisks.append(disk)
+ progress(1.0)
diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/xen-vm-install/src/xend.py new/xen-vm-install/src/xend.py
--- old/xen-vm-install/src/xend.py 2007-05-12 00:04:01.000000000 +0200
+++ new/xen-vm-install/src/xend.py 2007-05-18 17:59:28.000000000 +0200
@@ -12,7 +12,12 @@
import time
-from xen.util.xmlrpcclient import ServerProxy
+try:
+ # Xen 3.1+
+ from xen.util.xmlrpcclient import ServerProxy
+except:
+ # Xen 3.0.4 and older
+ from xen.util.xmlrpclib2 import ServerProxy
# Some Xen limits:
max_nics = 3
diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/xen-vm-install/src/XenGuest.py new/xen-vm-install/src/XenGuest.py
--- old/xen-vm-install/src/XenGuest.py 2007-04-12 17:42:21.000000000 +0200
+++ new/xen-vm-install/src/XenGuest.py 2007-05-18 19:06:38.000000000 +0200
@@ -80,7 +80,7 @@
return ' <ostype>%s</ostype>' % self.options.os_type
def _get_ostype_xen(self):
return 'ostype="%s"\n' % self.options.os_type
-
+
def getCommonXen(self):
s = ''
s += self._get_ostype_xen()
@@ -111,7 +111,7 @@
return ret
def _get_disk_xen(self):
- """Get the disk config in the xend python format"""
+ """Get the disk config in the xend python format"""
ret = 'disk=[ '
for disk in self.options.disks + self.tmpdisks:
ret += disk.get_xen_config()
@@ -196,20 +196,18 @@
lines += options
return '\n'.join(lines)
-
+
def GetConfigXml(self):
raise RuntimeError('pure virtual')
def GetConfigXen(self):
raise RuntimeError('pure virtual')
- def PreInstall(self):
+ def PreInstall(self, progress=lambda f:None):
if xen.install.xend.connection.domain_running(self.options.name):
raise VmError(VmError.E_VM_EXISTS)
-
if self.options.os_settings:
- VMDefaults[self.options.os_type].actions().setupOsSettings(self)
-
- self.create_devices()
+ VMDefaults[self.options.os_type].actions().setupOsSettings(self, lambda f:progress(f*0.05))
+ self.create_devices(lambda f:progress(0.05 + f*0.95))
def Start(self):
if (xen.install.xend.connection.domain_running(self.options.name) or
@@ -286,9 +284,15 @@
raise VmError(VmError.E_NO_START)
self.uuid = self.options.uuid
- def create_devices(self):
- for disk in self.options.disks + self.tmpdisks:
- disk.setup()
+ def create_devices(self, progress=lambda f:None):
+ disks = self.options.disks + self.tmpdisks
+ times = map(lambda d: d.setup_time(), disks)
+ cum_times = [0.0]
+ for i in range(len(times)):
+ cum_times.append(cum_times[-1]+times[i])
+ for i in range(len(disks)):
+ disks[i].setup(lambda f: progress(cum_times[i]/cum_times[-1] + f*cum_times[i+1]/cum_times[-1]))
+
for nic in self.options.nics:
nic.setup()
diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/xen-vm-install/TODO new/xen-vm-install/TODO
--- old/xen-vm-install/TODO 2007-04-20 23:06:26.000000000 +0200
+++ new/xen-vm-install/TODO 2007-05-18 23:16:46.000000000 +0200
@@ -1,89 +1,7 @@
- + /etc/xen/ -> /etc/xen/vm/
- + validate domain name
- + If interactive, prompt if RH, SUSE, NetWare, ...
- + OS defines what the "location" is
- + support multiple disks
- + support non-interactive
- + improve XenDisk class
- + kill pygrub
- + RedHat grabs kernel via URL; we need to do tricks :-(
- + probe disk after install; define "bootentry"
- + standard header on files
- + finish turning Options.py into a class, to remove lower dependencies on optparse
- + support autoinst.xml
- + os-specific hook to parse config file
- + restarting VM hangs (while reading XML?)
- + clean up tmp dir usage
- + well defined return codes
- + implemented job
- + kill "isinstall" junk
- + -x raises
- + abstract better between frontend (CLI/GUI) and backend
- + Create better exception class, derived from RuntimeError, for non-CLI users
- + better status messages / progress (callbacks?)
- + loopbacks not cleared
- + --debug is being ignored
- + fix finding kernel-xen on 64 bit
- + finish pv.install_disk/install_url --> pv.source
- + define network CLI format
- + finish cleaning up options vs. XenGuest
- + clean up "guest" crap in gui
- + add vif support to GUI, for network install
- + get notebook pages by name, not number
- + kill libvirt
- + conflict detection in cli
- + finish defining exceptions
- + check if a vm by that name is already running
- + conflict detection: OS doesn't support PV; hardware doesn't support FV
- + support netware response file
- + check disks for duplication
- + change PV iso/cd/network radio buttons to disk/network
- + default timezone based on OS
- + make summary screen scrollable
- + be able to specify CDROM vs. DISK
- + change FV install source to use defined disks
- + disk must always remain abstract, to change hda<=>xvda when switching FV<->PV
- + xen-manager (aka virt-manager) calls xen-vm-install
- + iterate, find an unused VM name
- + graphics (sdl, vnc, pvfb...)
- + change --sdl, --vnc, --vnc-port, etc to be --graphics-viewer (or some such)
- + support pvfb (test NW)
- + default to installing from CDROMs instead of disks
- + netware iso loopbacks not being cleared: domUloader bug (kpartx -d is failing)
- + remove CD for NW before reboot
- + default to vnc for netware
- + always use vnc, because of virt-manager
- + submit strings for translation
- + using physical cdrom asserts
- + allow os-settings to be a directory (*.rsp, *.nlf)
- + Support installing 32 bit SUSE domU on 64 bit dom0
- + xm new / xm start instead of xm create
- + CDROM/DVD should always be mode 'r'
- + hand cursor
- + finalize NIC model after user views it, so it doesn't change
- + On summary screen, flag items user must fill out before continuing
- + fix open port
- + # physical processors
- + amount physical memory
- + X memory free; OS requires Y; X < Y
- + properly use "vncunused" flag, to avoid displaying Xvnc
- + Can now install 32pae SLES 10 on x86_64 hypervisor (#237370)
- + Be able to use an existing disk, bypassing the OS installation (#237396)
- + Honor extra-args setting from UI
- + Clean up handling of user's "extra_args" versus implicit args necessary for OS
- + #234331, #239007: CD/DVDs should always be marked read-only
- + validate nic MAC
- + #239196: support SLED
- + increase SLES's recommended memory size to 512
- + Fix naming and re-ordering of disks and nics
- + Allow PV to install bootloader on any disk
- + single connection to xend
- + Check for conflicting VM names in filesystem, disks, and xend
- + clean up dot files
+ #238458: Work-around qemu slowness bug
+ #240064: clean up the vm on failure
+ #241197: Job support
-===beta 3===
+===SLES 10 SP1 beta 3===
+ Allow specifing disk (and disk size) vs. cdrom from CLI to match GUI
+ Add missing -M/--max-memory parameter to CLI to match GUI
+ #241528: Display error if user selects FV OS but hardware lacks VT
@@ -105,13 +23,13 @@
+ #240984: properly detach vncviewer
+ #240387: default to absolute coordinate mouse for Windows
+ Re-fix: Honor ordering of arguments (as claimed in man page)
-===beta 4 try #1===
+===SLES 10 SP1 beta 4 try #1===
+ #248047: Fix inability to use already-extracted SUSE kernel/initrds
+ Fix accumulation of 0-byte tmp files
+ #237063: close fds before running vncviewer because it is long-running
+ deleting a job whose (truncated) jobfile is lacking 'id' causes exception
+ default apic=0 for Windows, due to performance
-===beta 4 respin===
+===SLES 10 SP1 beta 4 respin===
+ #244772: display error message in GUI if xen isn't running
+ #246049: better error message when OS==SUSE but ISO looks wrong
+ Fix printing of jobid when run with --background
@@ -128,26 +46,26 @@
+ Updated 2 help strings, to help users add disks.
+ #240001: virt-manager keys: f10
+ #228133: default apic=0 for sles 8 & 9
-===beta 5===
+===SLES 10 SP1 beta 5===
+ Better description on "Virtual Disk" drop-down (not "xvda")
+ Proper separation of recording options versus calculating defaults; fixes corner cases
+ #247849, #253013, 253009: Multiple fixes related to how disks are defined, centered around bug #247849 (handle partitioned PV installation disk)
+ #252437: Allow virtual CDROM to be added (via ISO) even if physical CDROM doesn't exist
+ #241251: Support installs from NFS & SMB
-===beta 6===
+===SLES 10 SP1 beta 6===
+ #253743: vm-install-job was failing to query job status
+ #247849: Further fixes for NetWare factory install/configure mode
+ #241251: Fix bug in path concatenation for NFS/SMB
+ Updated translations
- + "xm delete" before "xm new" to avoid failed bootloader
- + #247980: Display more details on failure
+ + "xm delete" before "xm new" to avoid failed bootloader
+ + #247980: Display more details on failure
+ #254655: Cap VM's starting memory to available memory
-===RC1===
+===SLES 10 SP1 RC1===
+ update icon name (yast-network -> yast-create-new-vm)
+ #258376: pass args to child process as an array, not string
+ do not run "brctl show" just because of "import nics"
+ #259207: write out maxmem parameter
-===RC2===
+===SLES 10 SP1 RC2===
+ #259420: refresh available memory more often
+ #259972: cannot enter autoyast url
+ #259917: cannot do simultaneous installs via virt-manager
@@ -158,40 +76,52 @@
+ do not complain about existing /etc/xen/vm/ conf file
+ properly tear down failed VMs
+ #260983: support booting PV RHEL4,5
-===RC3===
-
+===SLES 10 SP1 RC3===
+===SLES 10 SP1 RC4===
+===SLES 10 SP1===
+ + #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
+
+ - hard to exit with ctrl-c -- gui
+ - block drivers:
+ - iscsi
+ - nbd
+ - #239173: default to blktap
+ - try to avoid sparse files + blktap, because it is slow
+ - specify driver on command line
+ - add gui
+ - add physical cdrom to VM, but don't use. Install. Reboot. Fails: "no medium found for /dev/cdrom"
+ - disallow incompatible architectures
+ - disable 64 bit OSs if not possible
+ - How to know what architecture the install source is (in general)?
+ - VMDefaults sees 64-bit capable machine, and defaults to 64 bit memory size, when OS is 32 bit
+ - catch backtrace when exception happens
+ - libvirt vs xenapi
+ - add password option to vnc, and expose in command line
+ - offer unsupported OSs: generic PV, *BSD, ...
+ - Live CDs
+ - require dosfstools?
- RHEL4/SLES9 isn't defaulting to FV in GUI (but is in CLI)
- - finish virt-manager & disks
- "Virtual Disk" field too wide
- - hide left-hand pane of Open dialog
- - #211342: make progress bar more meaningful for non-sparse file
- support --install / --no-install from the command line
- - add password to vnc
- Usability:
- list physical block devices
- - Change "Disks" title to "Virtual Disks" (?)
- "CD-Rom" on gtk-cdrom button should be "CD-ROM" to match rest of UI
- "CD-Rom" and "Harddisk" buttons should have a "+" icon
- - if job exits due to other reason (e.g., bad installation source) job.py assumes it was canceled
+ - if job exits due to other reason (e.g., bad installation source) job.py assumes it was canceled
- cryptic error message if out of loopback devs
- domUloader: test tap:qcow
- - hard to exit with ctrl-c
- memory reservation (to avoid races)
- touch new config file to avoid races
- windowing:
- pop to top if error (since it can block virt-manager)
- alt-tab to xen-vm-install window while installing; progress window should get focus
- - blktap:
- - #239173: use blktap
- - try to avoid sparse files + blktap, because it is slow
- - sparse, blktap, ... flags on command line
- don't allow/default "Network URL" if OS doesn't support it
- prompt for physical media before starting the installation
- - How to know what architecture the install source is (in general)?
- + VMDefaults sees 64-bit capable machine, and defaults to 64 bit memory size, when OS is 32 bit
- -M 0 ==> no max
- clean up rhpl
- - icons
- tidy up support for floppy (only for FV?)
- disk
FV only allows 1 CDROM
@@ -200,11 +130,8 @@
- fix dbus timeout
- support RH kickstart
- sort OS names with 10 > 9
- - "other OS" doesn't support para (at very least because user can't manually input kernel)
- windows 2003 immediately writes a bootsector, so I can't tell if install was canceled
- read disk/NIC xml
- - pull notebook pages out as separate glade objects
- - dynamically insert notebook pages from glade
- can't consistently use "=" with --long-args
- clean up imports
- good py doc strings
@@ -212,19 +139,3 @@
virt-manager:
- re-use xen-vm-install GUI widgets when editing running VMs
- Patch for virt-manager-launch is incorrect (lib vs. libexec)
- - Heed packaging doc's warning about gconf schema (?)
-
-
-Try to enter conflicting options. The re-calculation of options is now transactional, so things should never get into an inconsistent state. For example, pick an OS that can only be fully virtualized (Windows XP), and add a fully virtualized NIC, then back up and change your OS type to SLES 10.
-
-Set your installation source to be a disk/CD/DVD/ISO/whatever. Add, remove, re-order disks. The installation source should "follow" the previously set disk, even as it changes xvdX names. Also change the VM's name. Unless you've explicitly selected where the virtual disk is stored, the disk image name should change to match the VM's name.
-
-Test bootstrapping an installation from CD/DVD/ISO. This code has changed to support NetWare.
-
-Try doing an installation from an existing disk (check that it bootstraps the VM, even if it's not a true installation source). NetWare needs this sort of functionality for "Factory Configure".
-
-Check that the above changes haven't broken finding the kernel/initrd on a disk after the installation finishes.
-
-Start vm-install from the command line, pre-populating several disks. Don't specify the file that will hold the disk image; the tool should generate that for you. For example, this should start you off with 2 disks:
-vm-install --debug --disk ,xvda,disk,w,5120 --disk ,xvdb,disk,w,10240
-
diff -urN --exclude=CVS --exclude=.cvsignore --exclude=.svn --exclude=.svnignore old/xen-vm-install/xen-vm-install.desktop new/xen-vm-install/xen-vm-install.desktop
--- old/xen-vm-install/xen-vm-install.desktop 2007-03-28 19:25:07.000000000 +0200
+++ new/xen-vm-install/xen-vm-install.desktop 2007-05-21 17:47:19.000000000 +0200
@@ -1,7 +1,7 @@
[Desktop Entry]
X-SuSE-DocTeamID=ycc_xen
Type=Application
-Categories=Qt;X-SuSE-YaST;
+Categories=Qt;X-SuSE-YaST;X-SuSE-YaST-Virtualization;
X-KDE-ModuleType=Library
X-KDE-RootOnly=true
@@ -21,5 +21,3 @@
Name=Create Virtual Machines
GenericName=Create Virtual Machines
X-KDE-SubstituteUID=true
-
-X-SuSE-translate=true
++++++ xen-warnings.diff ++++++
--- /var/tmp/diff_new_pack.y15063/_old 2007-05-21 22:27:55.000000000 +0200
+++ /var/tmp/diff_new_pack.y15063/_new 2007-05-21 22:27:55.000000000 +0200
@@ -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 @@
}
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/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 @@
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 @@
}
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;
+ }
+ }
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Remember to have fun...
---------------------------------------------------------------------
To unsubscribe, e-mail: opensuse-commit+unsubscribe@opensuse.org
For additional commands, e-mail: opensuse-commit+help@opensuse.org