KVM: x86: add asm_safe wrapper
authorRadim Krčmář <rkrcmar@redhat.com>
Tue, 8 Nov 2016 19:54:18 +0000 (20:54 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 19 Jan 2017 19:18:00 +0000 (20:18 +0100)
commit aabba3c6abd50b05b1fc2c6ec44244aa6bcda576 upstream.

Move the existing exception handling for inline assembly into a macro
and switch its return values to X86EMUL type.

Signed-off-by: Radim Krčmář <rkrcmar@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
arch/x86/kvm/emulate.c

index 7a6f9fa20485cc1e18699cee16918307b44869c5..a1427f74099836824380e62d097ce55e24ec4969 100644 (file)
@@ -447,6 +447,26 @@ FOP_END;
 FOP_START(salc) "pushf; sbb %al, %al; popf \n\t" FOP_RET
 FOP_END;
 
+/*
+ * XXX: inoutclob user must know where the argument is being expanded.
+ *      Relying on CC_HAVE_ASM_GOTO would allow us to remove _fault.
+ */
+#define asm_safe(insn, inoutclob...) \
+({ \
+       int _fault = 0; \
+ \
+       asm volatile("1:" insn "\n" \
+                    "2:\n" \
+                    ".pushsection .fixup, \"ax\"\n" \
+                    "3: movl $1, %[_fault]\n" \
+                    "   jmp  2b\n" \
+                    ".popsection\n" \
+                    _ASM_EXTABLE(1b, 3b) \
+                    : [_fault] "+qm"(_fault) inoutclob ); \
+ \
+       _fault ? X86EMUL_UNHANDLEABLE : X86EMUL_CONTINUE; \
+})
+
 static int emulator_check_intercept(struct x86_emulate_ctxt *ctxt,
                                    enum x86_intercept intercept,
                                    enum x86_intercept_stage stage)
@@ -5098,21 +5118,13 @@ static bool string_insn_completed(struct x86_emulate_ctxt *ctxt)
 
 static int flush_pending_x87_faults(struct x86_emulate_ctxt *ctxt)
 {
-       bool fault = false;
+       int rc;
 
        ctxt->ops->get_fpu(ctxt);
-       asm volatile("1: fwait \n\t"
-                    "2: \n\t"
-                    ".pushsection .fixup,\"ax\" \n\t"
-                    "3: \n\t"
-                    "movb $1, %[fault] \n\t"
-                    "jmp 2b \n\t"
-                    ".popsection \n\t"
-                    _ASM_EXTABLE(1b, 3b)
-                    : [fault]"+qm"(fault));
+       rc = asm_safe("fwait");
        ctxt->ops->put_fpu(ctxt);
 
-       if (unlikely(fault))
+       if (unlikely(rc != X86EMUL_CONTINUE))
                return emulate_exception(ctxt, MF_VECTOR, 0, false);
 
        return X86EMUL_CONTINUE;