]> git.ipfire.org Git - thirdparty/ipxe.git/commitdiff
[librm] Conditionalize the workaround for the Tivoli VMM's SSE garbling
authorLaszlo Ersek <lersek@redhat.com>
Wed, 26 Oct 2016 22:13:50 +0000 (00:13 +0200)
committerMichael Brown <mcb30@ipxe.org>
Tue, 8 Nov 2016 17:37:59 +0000 (17:37 +0000)
Commit 71560d1 ("[librm] Preserve FPU, MMX and SSE state across calls
to virt_call()") 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 0418631 ("[thunderx] Fix
compilation with older versions of gcc") which is a descendant of
commit 71560d1 (see above).

This was done in QEMU commit ffdc5a2 ("ipxe: update submodule from
4e03af8ec to 041863191").  The resultant binaries were bundled with
the QEMU v2.7.0 release; see QEMU commit c52125a ("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 arch/x86/prefix/romprefix.S.  Also, TIVOLI_VMM_WORKAROUND seems to
be a good fit for the "Obscure configuration options" section in
config/general.h.

Cc: Bandan Das <bsd@redhat.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Cc: Greg <rollenwiese@yahoo.com>
Cc: Michael Brown <mcb30@ipxe.org>
Cc: Michael Prokop <launchpad@michael-prokop.at>
Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: Peter Pickford <arch@netremedies.ca>
Cc: Radim Krčmář <rkrcmar@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@redhat.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
src/arch/x86/transitions/librm.S
src/config/general.h

index e91ede372619af7c3419062d93f9488edf3f003b..c31daad8402b0aaa60fa10823f7d56dac1d2366f 100644 (file)
@@ -7,6 +7,9 @@
 
 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )
 
+/* Drag in general configuration */
+#include <config/general.h>
+
 /* Drag in local definitions */
 #include "librm.h"
 
@@ -207,7 +210,9 @@ VC_TMP_CR3:         .space  4
 VC_TMP_CR4:            .space  4
 VC_TMP_EMER:           .space  8
 .endif
+#ifdef TIVOLI_VMM_WORKAROUND
 VC_TMP_FXSAVE:         .space  512
+#endif
 VC_TMP_END:
        .previous
 
@@ -1000,11 +1005,12 @@ virt_call:
 
        /* Claim ownership of temporary static buffer */
        cli
+       movw    %cs:rm_ds, %ds
 
+#ifdef TIVOLI_VMM_WORKAROUND
        /* Preserve FPU, MMX and SSE state in temporary static buffer */
-       movw    %cs:rm_ds, %ds
        fxsave  ( rm_tmpbuf + VC_TMP_FXSAVE )
-
+#endif
        /* Preserve GDT and IDT in temporary static buffer */
        sidt    ( rm_tmpbuf + VC_TMP_IDT )
        sgdt    ( rm_tmpbuf + VC_TMP_GDT )
@@ -1070,9 +1076,11 @@ vc_rmode:
        movl    $MSR_EFER, %ecx
        wrmsr
 .endif
+
+#ifdef TIVOLI_VMM_WORKAROUND
        /* Restore FPU, MMX and SSE state from temporary static buffer */
        fxrstor ( rm_tmpbuf + VC_TMP_FXSAVE )
-
+#endif
        /* Restore registers and flags and return */
        popl    %eax /* skip %cs and %ss */
        popw    %ds
index d2bbeb067e9a823079a6a249ee33a5f6c503da65..be0845f68da4736cf733f2736213ba71500ba924 100644 (file)
@@ -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)