From 12e3410e071e284398e49d125e7d9cec076d00e5 Mon Sep 17 00:00:00 2001 From: Andrew Cooper Date: Fri, 26 Nov 2021 15:42:48 +0000 Subject: [PATCH] x86/altcall: Check and optimise altcall targets When converting indirect to direct calls, there is no need to execute endbr64 instructions. Detect and optimise this case, leaving a warning in the case that no endbr64 was found, as it likely indicates a build error. Signed-off-by: Andrew Cooper Reviewed-by: Jan Beulich --- xen/arch/x86/alternative.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/xen/arch/x86/alternative.c b/xen/arch/x86/alternative.c index ec24692e95..ae7e646074 100644 --- a/xen/arch/x86/alternative.c +++ b/xen/arch/x86/alternative.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -279,6 +280,28 @@ static void init_or_livepatch _apply_alternatives(struct alt_instr *start, if ( dest ) { + /* + * When building for CET-IBT, all function pointer targets + * should have an endbr64 instruction. + * + * If this is not the case, leave a warning because + * something is probably wrong with the build. A CET-IBT + * enabled system might have exploded already. + * + * Otherwise, skip the endbr64 instruction. This is a + * marginal perf improvement which saves on instruction + * decode bandwidth. + */ + if ( IS_ENABLED(CONFIG_HAS_CC_CET_IBT) ) + { + if ( is_endbr64(dest) ) + dest += ENDBR64_LEN; + else + printk(XENLOG_WARNING + "altcall %ps dest %ps has no endbr64\n", + orig, dest); + } + disp = dest - (orig + 5); ASSERT(disp == (int32_t)disp); *(int32_t *)(buf + 1) = disp; -- 2.30.2