[ipxe-devel] [PATCH 1/2] [librm] Conditionalize the workaround for the Tivoli VMM's SSE garbling

Laszlo Ersek lersek at redhat.com
Wed Oct 26 22:13:50 UTC 2016


  71560d185475 [librm] Preserve FPU, MMX and SSE state across calls to

added FXSAVE and FXRSTOR instructions to iPXE. In KVM virtual machines,
these instructions execute fine as long as the host CPU supports the
"unrestricted_guest" feature (that is, it can virtualize big real mode
natively). On older host CPUs however, KVM has to emulate big real mode,
and it currently doesn't implement FXSAVE emulation.

Upstream QEMU rebuilt iPXE at commit

  041863191812 [thunderx] Fix compilation with older versions of gcc

which is a descendant of commit 71560d185475 (see above).

This was done in QEMU commit

  ffdc5a2bcee1 ipxe: update submodule from 4e03af8ec to 041863191

The resultant binaries were bundled with the QEMU v2.7.0 release; see QEMU

  c52125ab9280 ipxe: update prebuilt binaries

This distributed the iPXE workaround for the Tivoli VMM bug to a number of
KVM users with old host CPUs, causing KVM emulation failures (guest
crashes) for them while netbooting.

Make the FXSAVE and FXRSTOR instructions conditional on a new feature test
macro called TIVOLI_VMM_WORKAROUND. Define the macro by default.

There is prior art for an assembly file including <config/general.h>: see
"src/arch/x86/prefix/romprefix.S". Also, TIVOLI_VMM_WORKAROUND seems to be
a good fit for the "Obscure configuration options" section in

Cc: Bandan Das <bsd at redhat.com>
Cc: Gerd Hoffmann <kraxel at redhat.com>
Cc: Greg <rollenwiese at yahoo.com>
Cc: Michael Brown <mcb30 at ipxe.org>
Cc: Michael Prokop <launchpad at michael-prokop.at>
Cc: Paolo Bonzini <pbonzini at redhat.com>
Cc: Peter Pickford <arch at netremedies.ca>
Cc: Radim Krčmář <rkrcmar at redhat.com>
Ref: https://bugs.archlinux.org/task/50778
Ref: https://bugs.launchpad.net/qemu/+bug/1623276
Ref: https://bugzilla.proxmox.com/show_bug.cgi?id=1182
Ref: https://bugzilla.redhat.com/show_bug.cgi?id=1356762
Signed-off-by: Laszlo Ersek <lersek at redhat.com>
 src/config/general.h             |  3 +++
 src/arch/x86/transitions/librm.S | 15 ++++++++++++++-
 2 files changed, 17 insertions(+), 1 deletion(-)

diff --git a/src/config/general.h b/src/config/general.h
index d2bbeb067e9a..be0845f68da4 100644
--- a/src/config/general.h
+++ b/src/config/general.h
@@ -190,6 +190,9 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 #undef	GDBUDP			/* Remote GDB debugging over UDP
 				 * (both may be set) */
 //#define EFI_DOWNGRADE_UX	/* Downgrade UEFI user experience */
+#define	TIVOLI_VMM_WORKAROUND	/* Work around the Tivoli VMM's garbling of SSE
+				 * registers when iPXE traps to it due to
+				 * privileged instructions */
 #include <config/named.h>
 #include NAMED_CONFIG(general.h)
diff --git a/src/arch/x86/transitions/librm.S b/src/arch/x86/transitions/librm.S
index e91ede372619..1fd4ed60f4de 100644
--- a/src/arch/x86/transitions/librm.S
+++ b/src/arch/x86/transitions/librm.S
@@ -7,6 +7,9 @@
+/* Drag in general configuration */
+#include <config/general.h>
 /* Drag in local definitions */
 #include "librm.h"
@@ -207,7 +210,11 @@ VC_TMP_CR3:		.space	4
 VC_TMP_CR4:		.space	4
 VC_TMP_EMER:		.space	8
 VC_TMP_FXSAVE:		.space	512
@@ -1001,9 +1008,12 @@ virt_call:
 	/* Claim ownership of temporary static buffer */
+	movw	%cs:rm_ds, %ds
 	/* Preserve FPU, MMX and SSE state in temporary static buffer */
-	movw	%cs:rm_ds, %ds
 	fxsave	( rm_tmpbuf + VC_TMP_FXSAVE )
 	/* Preserve GDT and IDT in temporary static buffer */
 	sidt	( rm_tmpbuf + VC_TMP_IDT )
@@ -1070,8 +1080,11 @@ vc_rmode:
 	movl	$MSR_EFER, %ecx
 	/* Restore FPU, MMX and SSE state from temporary static buffer */
 	fxrstor	( rm_tmpbuf + VC_TMP_FXSAVE )
 	/* Restore registers and flags and return */
 	popl	%eax /* skip %cs and %ss */

More information about the ipxe-devel mailing list