]>
Commit | Line | Data |
---|---|---|
79473355 GKH |
1 | From aabba3c6abd50b05b1fc2c6ec44244aa6bcda576 Mon Sep 17 00:00:00 2001 |
2 | From: =?UTF-8?q?Radim=20Kr=C4=8Dm=C3=A1=C5=99?= <rkrcmar@redhat.com> | |
3 | Date: Tue, 8 Nov 2016 20:54:18 +0100 | |
4 | Subject: KVM: x86: add asm_safe wrapper | |
5 | MIME-Version: 1.0 | |
6 | Content-Type: text/plain; charset=UTF-8 | |
7 | Content-Transfer-Encoding: 8bit | |
8 | ||
9 | From: Radim Krčmář <rkrcmar@redhat.com> | |
10 | ||
11 | commit aabba3c6abd50b05b1fc2c6ec44244aa6bcda576 upstream. | |
12 | ||
13 | Move the existing exception handling for inline assembly into a macro | |
14 | and switch its return values to X86EMUL type. | |
15 | ||
16 | Signed-off-by: Radim Krčmář <rkrcmar@redhat.com> | |
17 | Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> | |
18 | Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | |
19 | ||
20 | --- | |
21 | arch/x86/kvm/emulate.c | 34 +++++++++++++++++++++++----------- | |
22 | 1 file changed, 23 insertions(+), 11 deletions(-) | |
23 | ||
24 | --- a/arch/x86/kvm/emulate.c | |
25 | +++ b/arch/x86/kvm/emulate.c | |
26 | @@ -435,6 +435,26 @@ FOP_END; | |
27 | FOP_START(salc) "pushf; sbb %al, %al; popf \n\t" FOP_RET | |
28 | FOP_END; | |
29 | ||
30 | +/* | |
31 | + * XXX: inoutclob user must know where the argument is being expanded. | |
32 | + * Relying on CC_HAVE_ASM_GOTO would allow us to remove _fault. | |
33 | + */ | |
34 | +#define asm_safe(insn, inoutclob...) \ | |
35 | +({ \ | |
36 | + int _fault = 0; \ | |
37 | + \ | |
38 | + asm volatile("1:" insn "\n" \ | |
39 | + "2:\n" \ | |
40 | + ".pushsection .fixup, \"ax\"\n" \ | |
41 | + "3: movl $1, %[_fault]\n" \ | |
42 | + " jmp 2b\n" \ | |
43 | + ".popsection\n" \ | |
44 | + _ASM_EXTABLE(1b, 3b) \ | |
45 | + : [_fault] "+qm"(_fault) inoutclob ); \ | |
46 | + \ | |
47 | + _fault ? X86EMUL_UNHANDLEABLE : X86EMUL_CONTINUE; \ | |
48 | +}) | |
49 | + | |
50 | static int emulator_check_intercept(struct x86_emulate_ctxt *ctxt, | |
51 | enum x86_intercept intercept, | |
52 | enum x86_intercept_stage stage) | |
53 | @@ -5086,21 +5106,13 @@ static bool string_insn_completed(struct | |
54 | ||
55 | static int flush_pending_x87_faults(struct x86_emulate_ctxt *ctxt) | |
56 | { | |
57 | - bool fault = false; | |
58 | + int rc; | |
59 | ||
60 | ctxt->ops->get_fpu(ctxt); | |
61 | - asm volatile("1: fwait \n\t" | |
62 | - "2: \n\t" | |
63 | - ".pushsection .fixup,\"ax\" \n\t" | |
64 | - "3: \n\t" | |
65 | - "movb $1, %[fault] \n\t" | |
66 | - "jmp 2b \n\t" | |
67 | - ".popsection \n\t" | |
68 | - _ASM_EXTABLE(1b, 3b) | |
69 | - : [fault]"+qm"(fault)); | |
70 | + rc = asm_safe("fwait"); | |
71 | ctxt->ops->put_fpu(ctxt); | |
72 | ||
73 | - if (unlikely(fault)) | |
74 | + if (unlikely(rc != X86EMUL_CONTINUE)) | |
75 | return emulate_exception(ctxt, MF_VECTOR, 0, false); | |
76 | ||
77 | return X86EMUL_CONTINUE; |