|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen master] x86emul: move stubs off the stack
commit 95668b015384879d36e2f3f0bd38b85fdcd34ef1
Author: Jan Beulich <jbeulich@xxxxxxxx>
AuthorDate: Fri May 22 10:46:32 2015 +0200
Commit: Jan Beulich <jbeulich@xxxxxxxx>
CommitDate: Fri May 22 10:46:32 2015 +0200
x86emul: move stubs off the stack
This is needed as stacks are going to become non-executable.
Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx>
Reviewed-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
---
tools/tests/x86_emulator/x86_emulate.c | 4 ++
xen/arch/x86/x86_emulate.c | 16 +++++++++
xen/arch/x86/x86_emulate/x86_emulate.c | 55 ++++++++++++++++++++++----------
xen/arch/x86/x86_emulate/x86_emulate.h | 13 +++++++
4 files changed, 71 insertions(+), 17 deletions(-)
diff --git a/tools/tests/x86_emulator/x86_emulate.c
b/tools/tests/x86_emulator/x86_emulate.c
index ef9bfe9..0b3b34a 100644
--- a/tools/tests/x86_emulator/x86_emulate.c
+++ b/tools/tests/x86_emulator/x86_emulate.c
@@ -17,4 +17,8 @@ typedef bool bool_t;
#define __packed __attribute__((packed))
#include "x86_emulate/x86_emulate.h"
+
+#define get_stub(stb) ((void *)((stb).addr = (uintptr_t)(stb).buf))
+#define put_stub(stb)
+
#include "x86_emulate/x86_emulate.c"
diff --git a/xen/arch/x86/x86_emulate.c b/xen/arch/x86/x86_emulate.c
index 79b4ab3..51c8e44 100644
--- a/xen/arch/x86/x86_emulate.c
+++ b/xen/arch/x86/x86_emulate.c
@@ -9,6 +9,7 @@
* Keir Fraser <keir@xxxxxxx>
*/
+#include <xen/domain_page.h>
#include <asm/x86_emulate.h>
#include <asm/asm_defns.h> /* mark_regs_dirty() */
#include <asm/processor.h> /* current_cpu_info */
@@ -17,8 +18,23 @@
/* Avoid namespace pollution. */
#undef cmpxchg
#undef cpuid
+#undef wbinvd
#define cpu_has_amd_erratum(nr) \
cpu_has_amd_erratum(¤t_cpu_data, AMD_ERRATUM_##nr)
+#define get_stub(stb) ({ \
+ BUILD_BUG_ON(STUB_BUF_SIZE / 2 < MAX_INST_LEN + 1); \
+ (stb).addr = this_cpu(stubs.addr) + STUB_BUF_SIZE / 2; \
+ ((stb).ptr = map_domain_page(this_cpu(stubs.mfn))) + \
+ ((stb).addr & ~PAGE_MASK); \
+})
+#define put_stub(stb) ({ \
+ if ( (stb).ptr ) \
+ { \
+ unmap_domain_page((stb).ptr); \
+ (stb).ptr = NULL; \
+ } \
+})
+
#include "x86_emulate/x86_emulate.c"
diff --git a/xen/arch/x86/x86_emulate/x86_emulate.c
b/xen/arch/x86/x86_emulate/x86_emulate.c
index d43ca4e..c017c69 100644
--- a/xen/arch/x86/x86_emulate/x86_emulate.c
+++ b/xen/arch/x86/x86_emulate/x86_emulate.c
@@ -717,11 +717,15 @@ do{ struct fpu_insn_ctxt fic; \
} while (0)
#define emulate_fpu_insn_stub(_bytes...) \
-do{ uint8_t stub[] = { _bytes, 0xc3 }; \
- struct fpu_insn_ctxt fic = { .insn_bytes = sizeof(stub)-1 }; \
+do { \
+ uint8_t *buf = get_stub(stub); \
+ unsigned int _nr = sizeof((uint8_t[]){ _bytes }); \
+ struct fpu_insn_ctxt fic = { .insn_bytes = _nr }; \
+ memcpy(buf, ((uint8_t[]){ _bytes, 0xc3 }), _nr + 1); \
get_fpu(X86EMUL_FPU_fpu, &fic); \
- (*(void(*)(void))stub)(); \
+ stub.func(); \
put_fpu(&fic); \
+ put_stub(stub); \
} while (0)
static unsigned long _get_rep_prefix(
@@ -1458,6 +1462,7 @@ x86_emulate(
struct operand src = { .reg = REG_POISON };
struct operand dst = { .reg = REG_POISON };
enum x86_swint_type swint_type;
+ struct x86_emulate_stub stub = {};
DECLARE_ALIGNED(mmval_t, mmval);
/*
* Data operand effective address (usually computed from ModRM).
@@ -3792,6 +3797,7 @@ x86_emulate(
done:
_put_fpu();
+ put_stub(stub);
return rc;
twobyte_insn:
@@ -4007,9 +4013,15 @@ x86_emulate(
/* {,v}movss xmm,xmm/m32 */
/* {,v}movsd xmm,xmm/m64 */
{
- uint8_t stub[] = { 0x3e, 0x3e, 0x0f, b, modrm, 0xc3 };
- struct fpu_insn_ctxt fic = { .insn_bytes = sizeof(stub)-1 };
-
+ uint8_t *buf = get_stub(stub);
+ struct fpu_insn_ctxt fic = { .insn_bytes = 5 };
+
+ buf[0] = 0x3e;
+ buf[1] = 0x3e;
+ buf[2] = 0x0f;
+ buf[3] = b;
+ buf[4] = modrm;
+ buf[5] = 0xc3;
if ( vex.opcx == vex_none )
{
if ( vex.pfx & VEX_PREFIX_DOUBLE_MASK )
@@ -4017,7 +4029,7 @@ x86_emulate(
else
vcpu_must_have_sse();
ea.bytes = 16;
- SET_SSE_PREFIX(stub[0], vex.pfx);
+ SET_SSE_PREFIX(buf[0], vex.pfx);
get_fpu(X86EMUL_FPU_xmm, &fic);
}
else
@@ -4044,15 +4056,16 @@ x86_emulate(
/* convert memory operand to (%rAX) */
rex_prefix &= ~REX_B;
vex.b = 1;
- stub[4] &= 0x38;
+ buf[4] &= 0x38;
}
if ( !rc )
{
- copy_REX_VEX(stub, rex_prefix, vex);
- asm volatile ( "call *%0" : : "r" (stub), "a" (mmvalp)
+ copy_REX_VEX(buf, rex_prefix, vex);
+ asm volatile ( "call *%0" : : "r" (stub.func), "a" (mmvalp)
: "memory" );
}
put_fpu(&fic);
+ put_stub(stub);
if ( !rc && (b & 1) && (ea.type == OP_MEM) )
rc = ops->write(ea.mem.seg, ea.mem.off, mmvalp,
ea.bytes, ctxt);
@@ -4242,9 +4255,15 @@ x86_emulate(
/* {,v}movdq{a,u} xmm,xmm/m128 */
/* vmovdq{a,u} ymm,ymm/m256 */
{
- uint8_t stub[] = { 0x3e, 0x3e, 0x0f, b, modrm, 0xc3 };
- struct fpu_insn_ctxt fic = { .insn_bytes = sizeof(stub)-1 };
-
+ uint8_t *buf = get_stub(stub);
+ struct fpu_insn_ctxt fic = { .insn_bytes = 5 };
+
+ buf[0] = 0x3e;
+ buf[1] = 0x3e;
+ buf[2] = 0x0f;
+ buf[3] = b;
+ buf[4] = modrm;
+ buf[5] = 0xc3;
if ( vex.opcx == vex_none )
{
switch ( vex.pfx )
@@ -4252,7 +4271,7 @@ x86_emulate(
case vex_66:
case vex_f3:
vcpu_must_have_sse2();
- stub[0] = 0x66; /* movdqa */
+ buf[0] = 0x66; /* movdqa */
get_fpu(X86EMUL_FPU_xmm, &fic);
ea.bytes = 16;
break;
@@ -4288,15 +4307,16 @@ x86_emulate(
/* convert memory operand to (%rAX) */
rex_prefix &= ~REX_B;
vex.b = 1;
- stub[4] &= 0x38;
+ buf[4] &= 0x38;
}
if ( !rc )
{
- copy_REX_VEX(stub, rex_prefix, vex);
- asm volatile ( "call *%0" : : "r" (stub), "a" (mmvalp)
+ copy_REX_VEX(buf, rex_prefix, vex);
+ asm volatile ( "call *%0" : : "r" (stub.func), "a" (mmvalp)
: "memory" );
}
put_fpu(&fic);
+ put_stub(stub);
if ( !rc && (b != 0x6f) && (ea.type == OP_MEM) )
rc = ops->write(ea.mem.seg, ea.mem.off, mmvalp,
ea.bytes, ctxt);
@@ -4638,5 +4658,6 @@ x86_emulate(
cannot_emulate:
_put_fpu();
+ put_stub(stub);
return X86EMUL_UNHANDLEABLE;
}
diff --git a/xen/arch/x86/x86_emulate/x86_emulate.h
b/xen/arch/x86/x86_emulate/x86_emulate.h
index c55063d..064b8f4 100644
--- a/xen/arch/x86/x86_emulate/x86_emulate.h
+++ b/xen/arch/x86/x86_emulate/x86_emulate.h
@@ -429,6 +429,19 @@ struct x86_emulate_ctxt
} retire;
};
+struct x86_emulate_stub {
+ union {
+ void (*func)(void);
+ uintptr_t addr;
+ };
+#ifdef __XEN__
+ void *ptr;
+#else
+ /* Room for one insn and a (single byte) RET. */
+ uint8_t buf[MAX_INST_LEN + 1];
+#endif
+};
+
/*
* x86_emulate: Emulate an instruction.
* Returns -1 on failure, 0 on success.
--
generated by git-patchbot for /home/xen/git/xen.git#master
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |