|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [PATCH 60/65] x86/emul: Update emulation stubs to be CET-IBT compatible
All indirect branches need to land on an endbr64 instruction.
For stub_selftests(), use endbr64 unconditionally for simplicity. For ioport
and instruction emulation, add endbr64 conditionally.
Signed-off-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
---
CC: Jan Beulich <JBeulich@xxxxxxxx>
CC: Roger Pau Monné <roger.pau@xxxxxxxxxx>
CC: Wei Liu <wl@xxxxxxx>
---
xen/arch/x86/extable.c | 14 +++++++++-----
xen/arch/x86/pv/emul-priv-op.c | 5 +++++
xen/arch/x86/x86_emulate.c | 12 ++++++++++--
3 files changed, 24 insertions(+), 7 deletions(-)
diff --git a/xen/arch/x86/extable.c b/xen/arch/x86/extable.c
index 4aa1ab4b2a45..25c6fda00d28 100644
--- a/xen/arch/x86/extable.c
+++ b/xen/arch/x86/extable.c
@@ -129,19 +129,23 @@ search_exception_table(const struct cpu_user_regs *regs)
static int __init cf_check stub_selftest(void)
{
static const struct {
- uint8_t opc[4];
+ uint8_t opc[8];
uint64_t rax;
union stub_exception_token res;
} tests[] __initconst = {
- { .opc = { 0x0f, 0xb9, 0xc3, 0xc3 }, /* ud1 */
+ { .opc = { 0xf3, 0x0f, 0x1e, 0xfa, /* endbr64 */
+ 0x0f, 0xb9, 0xc3, 0xc3 }, /* ud1 */
.res.fields.trapnr = TRAP_invalid_op },
- { .opc = { 0x90, 0x02, 0x00, 0xc3 }, /* nop; add (%rax),%al */
+ { .opc = { 0xf3, 0x0f, 0x1e, 0xfa, /* endbr64 */
+ 0x90, 0x02, 0x00, 0xc3 }, /* nop; add (%rax),%al */
.rax = 0x0123456789abcdef,
.res.fields.trapnr = TRAP_gp_fault },
- { .opc = { 0x02, 0x04, 0x04, 0xc3 }, /* add (%rsp,%rax),%al */
+ { .opc = { 0xf3, 0x0f, 0x1e, 0xfa, /* endbr64 */
+ 0x02, 0x04, 0x04, 0xc3 }, /* add (%rsp,%rax),%al */
.rax = 0xfedcba9876543210,
.res.fields.trapnr = TRAP_stack_error },
- { .opc = { 0xcc, 0xc3, 0xc3, 0xc3 }, /* int3 */
+ { .opc = { 0xf3, 0x0f, 0x1e, 0xfa, /* endbr64 */
+ 0xcc, 0xc3, 0xc3, 0xc3 }, /* int3 */
.res.fields.trapnr = TRAP_int3 },
};
unsigned long addr = this_cpu(stubs.addr) + STUB_BUF_SIZE / 2;
diff --git a/xen/arch/x86/pv/emul-priv-op.c b/xen/arch/x86/pv/emul-priv-op.c
index 808ff1873352..51638c8f7273 100644
--- a/xen/arch/x86/pv/emul-priv-op.c
+++ b/xen/arch/x86/pv/emul-priv-op.c
@@ -68,6 +68,9 @@ static io_emul_stub_t *io_emul_stub_setup(struct priv_op_ctxt
*ctxt, u8 opcode,
* helpers (non-standard ABI), and one of several possible stubs
* performing the real I/O.
*/
+ static const char endbr64[] = {
+ 0xf3, 0x0f, 0x1e, 0xfa, /* endbr64 */
+ };
static const char prologue[] = {
0x53, /* push %rbx */
0x55, /* push %rbp */
@@ -111,6 +114,8 @@ static io_emul_stub_t *io_emul_stub_setup(struct
priv_op_ctxt *ctxt, u8 opcode,
p = ctxt->io_emul_stub;
+ if ( cpu_has_xen_ibt )
+ APPEND_BUFF(endbr64);
APPEND_BUFF(prologue);
APPEND_CALL(load_guest_gprs);
diff --git a/xen/arch/x86/x86_emulate.c b/xen/arch/x86/x86_emulate.c
index 60191a94dc18..8ba71a577f09 100644
--- a/xen/arch/x86/x86_emulate.c
+++ b/xen/arch/x86/x86_emulate.c
@@ -29,11 +29,19 @@
cpu_has_amd_erratum(¤t_cpu_data, AMD_ERRATUM_##nr)
#define get_stub(stb) ({ \
+ void *ptr; \
BUILD_BUG_ON(STUB_BUF_SIZE / 2 < MAX_INST_LEN + 1); \
ASSERT(!(stb).ptr); \
(stb).addr = this_cpu(stubs.addr) + STUB_BUF_SIZE / 2; \
- memset(((stb).ptr = map_domain_page(_mfn(this_cpu(stubs.mfn)))) + \
- ((stb).addr & ~PAGE_MASK), 0xcc, STUB_BUF_SIZE / 2); \
+ (stb).ptr = map_domain_page(_mfn(this_cpu(stubs.mfn))) + \
+ ((stb).addr & ~PAGE_MASK); \
+ ptr = memset((stb).ptr, 0xcc, STUB_BUF_SIZE / 2); \
+ if ( cpu_has_xen_ibt ) \
+ { \
+ memcpy(ptr, "\xf3\x0f\x1e\xfa", 4); /* endbr64 */ \
+ ptr += 4; \
+ } \
+ ptr; \
})
#define put_stub(stb) ({ \
if ( (stb).ptr ) \
--
2.11.0
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |