From ab2da34b207cb8fb98db9d96ed6f4b09d3791ace Mon Sep 17 00:00:00 2001 From: Andrew Cooper Date: Sat, 19 Apr 2025 21:23:56 +0100 Subject: [PATCH] x86/altcall: Split alternative-call.h out of alternative.h ... in preparation for changing how they're implemented. Update the MISRA deviations with the new path. No functional change. Signed-off-by: Andrew Cooper Acked-by: Jan Beulich --- .../eclair_analysis/ECLAIR/deviations.ecl | 4 +- xen/arch/x86/include/asm/alternative-call.h | 269 ++++++++++++++++++ xen/arch/x86/include/asm/alternative.h | 262 ----------------- xen/arch/x86/include/asm/hvm/hvm.h | 2 +- xen/common/core_parking.c | 4 +- xen/include/xen/alternative-call.h | 10 +- 6 files changed, 279 insertions(+), 272 deletions(-) create mode 100644 xen/arch/x86/include/asm/alternative-call.h diff --git a/automation/eclair_analysis/ECLAIR/deviations.ecl b/automation/eclair_analysis/ECLAIR/deviations.ecl index 2c8fb92713..9c67358d46 100644 --- a/automation/eclair_analysis/ECLAIR/deviations.ecl +++ b/automation/eclair_analysis/ECLAIR/deviations.ecl @@ -414,8 +414,8 @@ of the short-circuit evaluation strategy of such logical operators." -doc_end -doc_begin="Macros alternative_v?call[0-9] use sizeof and typeof to check that the argument types match the corresponding parameter ones." --config=MC3A2.R13.6,reports+={deliberate,"any_area(any_loc(any_exp(macro(^alternative_vcall[0-9]$))&&file(^xen/arch/x86/include/asm/alternative\\.h*$)))"} --config=B.UNEVALEFF,reports+={deliberate,"any_area(any_loc(any_exp(macro(^alternative_v?call[0-9]$))&&file(^xen/arch/x86/include/asm/alterantive\\.h*$)))"} +-config=MC3A2.R13.6,reports+={deliberate,"any_area(any_loc(any_exp(macro(^alternative_vcall[0-9]$))&&file(^xen/arch/x86/include/asm/alternative-call\\.h*$)))"} +-config=B.UNEVALEFF,reports+={deliberate,"any_area(any_loc(any_exp(macro(^alternative_v?call[0-9]$))&&file(^xen/arch/x86/include/asm/alterantive-call\\.h*$)))"} -doc_end -doc_begin="Anything, no matter how complicated, inside the BUILD_BUG_ON macro is subject to a compile-time evaluation without relevant side effects." diff --git a/xen/arch/x86/include/asm/alternative-call.h b/xen/arch/x86/include/asm/alternative-call.h new file mode 100644 index 0000000000..828ea32a96 --- /dev/null +++ b/xen/arch/x86/include/asm/alternative-call.h @@ -0,0 +1,269 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +#ifndef X86_ALTERNATIVE_CALL_H +#define X86_ALTERNATIVE_CALL_H + +#include + +/* + * Machinery to allow converting indirect to direct calls, when the called + * function is determined once at boot and later never changed. + */ + +#define ALT_CALL_arg1 "rdi" +#define ALT_CALL_arg2 "rsi" +#define ALT_CALL_arg3 "rdx" +#define ALT_CALL_arg4 "rcx" +#define ALT_CALL_arg5 "r8" +#define ALT_CALL_arg6 "r9" + +#ifdef CONFIG_CC_IS_CLANG +/* + * Clang doesn't follow the psABI and doesn't truncate parameter values at the + * callee. This can lead to bad code being generated when using alternative + * calls. + * + * Workaround it by using a temporary intermediate variable that's zeroed + * before being assigned the parameter value, as that forces clang to zero the + * register at the caller. + * + * This has been reported upstream: + * https://github.com/llvm/llvm-project/issues/12579 + * https://github.com/llvm/llvm-project/issues/82598 + */ +#define ALT_CALL_ARG(arg, n) \ + register unsigned long a ## n ## _ asm ( ALT_CALL_arg ## n ) = ({ \ + unsigned long tmp = 0; \ + BUILD_BUG_ON(sizeof(arg) > sizeof(unsigned long)); \ + *(typeof(arg) *)&tmp = (arg); \ + tmp; \ + }) +#else +#define ALT_CALL_ARG(arg, n) \ + register typeof(arg) a ## n ## _ asm ( ALT_CALL_arg ## n ) = \ + ({ BUILD_BUG_ON(sizeof(arg) > sizeof(void *)); (arg); }) +#endif +#define ALT_CALL_NO_ARG(n) \ + register unsigned long a ## n ## _ asm ( ALT_CALL_arg ## n ) + +#define ALT_CALL_NO_ARG6 ALT_CALL_NO_ARG(6) +#define ALT_CALL_NO_ARG5 ALT_CALL_NO_ARG(5); ALT_CALL_NO_ARG6 +#define ALT_CALL_NO_ARG4 ALT_CALL_NO_ARG(4); ALT_CALL_NO_ARG5 +#define ALT_CALL_NO_ARG3 ALT_CALL_NO_ARG(3); ALT_CALL_NO_ARG4 +#define ALT_CALL_NO_ARG2 ALT_CALL_NO_ARG(2); ALT_CALL_NO_ARG3 +#define ALT_CALL_NO_ARG1 ALT_CALL_NO_ARG(1); ALT_CALL_NO_ARG2 + +/* + * Unfortunately ALT_CALL_NO_ARG() above can't use a fake initializer (to + * suppress "uninitialized variable" warnings), as various versions of gcc + * older than 8.1 fall on the nose in various ways with that (always because + * of some other construct elsewhere in the same function needing to use the + * same hard register). Otherwise the asm() below could uniformly use "+r" + * output constraints, making unnecessary all these ALT_CALL_OUT macros. + */ +#define ALT_CALL0_OUT "=r" (a1_), "=r" (a2_), "=r" (a3_), \ + "=r" (a4_), "=r" (a5_), "=r" (a6_) +#define ALT_CALL1_OUT "+r" (a1_), "=r" (a2_), "=r" (a3_), \ + "=r" (a4_), "=r" (a5_), "=r" (a6_) +#define ALT_CALL2_OUT "+r" (a1_), "+r" (a2_), "=r" (a3_), \ + "=r" (a4_), "=r" (a5_), "=r" (a6_) +#define ALT_CALL3_OUT "+r" (a1_), "+r" (a2_), "+r" (a3_), \ + "=r" (a4_), "=r" (a5_), "=r" (a6_) +#define ALT_CALL4_OUT "+r" (a1_), "+r" (a2_), "+r" (a3_), \ + "+r" (a4_), "=r" (a5_), "=r" (a6_) +#define ALT_CALL5_OUT "+r" (a1_), "+r" (a2_), "+r" (a3_), \ + "+r" (a4_), "+r" (a5_), "=r" (a6_) +#define ALT_CALL6_OUT "+r" (a1_), "+r" (a2_), "+r" (a3_), \ + "+r" (a4_), "+r" (a5_), "+r" (a6_) + +#define alternative_callN(n, rettype, func) ({ \ + rettype ret_; \ + register unsigned long r10_ asm("r10"); \ + register unsigned long r11_ asm("r11"); \ + asm volatile (ALTERNATIVE("call *%c[addr](%%rip)", "call .", \ + X86_FEATURE_ALWAYS) \ + : ALT_CALL ## n ## _OUT, "=a" (ret_), \ + "=r" (r10_), "=r" (r11_) ASM_CALL_CONSTRAINT \ + : [addr] "i" (&(func)), "g" (func) \ + : "memory" ); \ + ret_; \ +}) + +#define alternative_vcall0(func) ({ \ + ALT_CALL_NO_ARG1; \ + (void)sizeof(func()); \ + (void)alternative_callN(0, int, func); \ +}) + +#define alternative_call0(func) ({ \ + ALT_CALL_NO_ARG1; \ + alternative_callN(0, typeof(func()), func); \ +}) + +#define alternative_vcall1(func, arg) ({ \ + typeof(arg) v1_ = (arg); \ + ALT_CALL_ARG(v1_, 1); \ + ALT_CALL_NO_ARG2; \ + (void)sizeof(func(arg)); \ + (void)alternative_callN(1, int, func); \ +}) + +#define alternative_call1(func, arg) ({ \ + typeof(arg) v1_ = (arg); \ + ALT_CALL_ARG(v1_, 1); \ + ALT_CALL_NO_ARG2; \ + alternative_callN(1, typeof(func(arg)), func); \ +}) + +#define alternative_vcall2(func, arg1, arg2) ({ \ + typeof(arg1) v1_ = (arg1); \ + typeof(arg2) v2_ = (arg2); \ + ALT_CALL_ARG(v1_, 1); \ + ALT_CALL_ARG(v2_, 2); \ + ALT_CALL_NO_ARG3; \ + (void)sizeof(func(arg1, arg2)); \ + (void)alternative_callN(2, int, func); \ +}) + +#define alternative_call2(func, arg1, arg2) ({ \ + typeof(arg1) v1_ = (arg1); \ + typeof(arg2) v2_ = (arg2); \ + ALT_CALL_ARG(v1_, 1); \ + ALT_CALL_ARG(v2_, 2); \ + ALT_CALL_NO_ARG3; \ + alternative_callN(2, typeof(func(arg1, arg2)), func); \ +}) + +#define alternative_vcall3(func, arg1, arg2, arg3) ({ \ + typeof(arg1) v1_ = (arg1); \ + typeof(arg2) v2_ = (arg2); \ + typeof(arg3) v3_ = (arg3); \ + ALT_CALL_ARG(v1_, 1); \ + ALT_CALL_ARG(v2_, 2); \ + ALT_CALL_ARG(v3_, 3); \ + ALT_CALL_NO_ARG4; \ + (void)sizeof(func(arg1, arg2, arg3)); \ + (void)alternative_callN(3, int, func); \ +}) + +#define alternative_call3(func, arg1, arg2, arg3) ({ \ + typeof(arg1) v1_ = (arg1); \ + typeof(arg2) v2_ = (arg2); \ + typeof(arg3) v3_ = (arg3); \ + ALT_CALL_ARG(v1_, 1); \ + ALT_CALL_ARG(v2_, 2); \ + ALT_CALL_ARG(v3_, 3); \ + ALT_CALL_NO_ARG4; \ + alternative_callN(3, typeof(func(arg1, arg2, arg3)), \ + func); \ +}) + +#define alternative_vcall4(func, arg1, arg2, arg3, arg4) ({ \ + typeof(arg1) v1_ = (arg1); \ + typeof(arg2) v2_ = (arg2); \ + typeof(arg3) v3_ = (arg3); \ + typeof(arg4) v4_ = (arg4); \ + ALT_CALL_ARG(v1_, 1); \ + ALT_CALL_ARG(v2_, 2); \ + ALT_CALL_ARG(v3_, 3); \ + ALT_CALL_ARG(v4_, 4); \ + ALT_CALL_NO_ARG5; \ + (void)sizeof(func(arg1, arg2, arg3, arg4)); \ + (void)alternative_callN(4, int, func); \ +}) + +#define alternative_call4(func, arg1, arg2, arg3, arg4) ({ \ + typeof(arg1) v1_ = (arg1); \ + typeof(arg2) v2_ = (arg2); \ + typeof(arg3) v3_ = (arg3); \ + typeof(arg4) v4_ = (arg4); \ + ALT_CALL_ARG(v1_, 1); \ + ALT_CALL_ARG(v2_, 2); \ + ALT_CALL_ARG(v3_, 3); \ + ALT_CALL_ARG(v4_, 4); \ + ALT_CALL_NO_ARG5; \ + alternative_callN(4, typeof(func(arg1, arg2, \ + arg3, arg4)), \ + func); \ +}) + +#define alternative_vcall5(func, arg1, arg2, arg3, arg4, arg5) ({ \ + typeof(arg1) v1_ = (arg1); \ + typeof(arg2) v2_ = (arg2); \ + typeof(arg3) v3_ = (arg3); \ + typeof(arg4) v4_ = (arg4); \ + typeof(arg5) v5_ = (arg5); \ + ALT_CALL_ARG(v1_, 1); \ + ALT_CALL_ARG(v2_, 2); \ + ALT_CALL_ARG(v3_, 3); \ + ALT_CALL_ARG(v4_, 4); \ + ALT_CALL_ARG(v5_, 5); \ + ALT_CALL_NO_ARG6; \ + (void)sizeof(func(arg1, arg2, arg3, arg4, arg5)); \ + (void)alternative_callN(5, int, func); \ +}) + +#define alternative_call5(func, arg1, arg2, arg3, arg4, arg5) ({ \ + typeof(arg1) v1_ = (arg1); \ + typeof(arg2) v2_ = (arg2); \ + typeof(arg3) v3_ = (arg3); \ + typeof(arg4) v4_ = (arg4); \ + typeof(arg5) v5_ = (arg5); \ + ALT_CALL_ARG(v1_, 1); \ + ALT_CALL_ARG(v2_, 2); \ + ALT_CALL_ARG(v3_, 3); \ + ALT_CALL_ARG(v4_, 4); \ + ALT_CALL_ARG(v5_, 5); \ + ALT_CALL_NO_ARG6; \ + alternative_callN(5, typeof(func(arg1, arg2, arg3, \ + arg4, arg5)), \ + func); \ +}) + +#define alternative_vcall6(func, arg1, arg2, arg3, arg4, arg5, arg6) ({ \ + typeof(arg1) v1_ = (arg1); \ + typeof(arg2) v2_ = (arg2); \ + typeof(arg3) v3_ = (arg3); \ + typeof(arg4) v4_ = (arg4); \ + typeof(arg5) v5_ = (arg5); \ + typeof(arg6) v6_ = (arg6); \ + ALT_CALL_ARG(v1_, 1); \ + ALT_CALL_ARG(v2_, 2); \ + ALT_CALL_ARG(v3_, 3); \ + ALT_CALL_ARG(v4_, 4); \ + ALT_CALL_ARG(v5_, 5); \ + ALT_CALL_ARG(v6_, 6); \ + (void)sizeof(func(arg1, arg2, arg3, arg4, arg5, arg6)); \ + (void)alternative_callN(6, int, func); \ +}) + +#define alternative_call6(func, arg1, arg2, arg3, arg4, arg5, arg6) ({ \ + typeof(arg1) v1_ = (arg1); \ + typeof(arg2) v2_ = (arg2); \ + typeof(arg3) v3_ = (arg3); \ + typeof(arg4) v4_ = (arg4); \ + typeof(arg5) v5_ = (arg5); \ + typeof(arg6) v6_ = (arg6); \ + ALT_CALL_ARG(v1_, 1); \ + ALT_CALL_ARG(v2_, 2); \ + ALT_CALL_ARG(v3_, 3); \ + ALT_CALL_ARG(v4_, 4); \ + ALT_CALL_ARG(v5_, 5); \ + ALT_CALL_ARG(v6_, 6); \ + alternative_callN(6, typeof(func(arg1, arg2, arg3, \ + arg4, arg5, arg6)), \ + func); \ +}) + +#define alternative_vcall__(nr) alternative_vcall ## nr +#define alternative_call__(nr) alternative_call ## nr + +#define alternative_vcall_(nr) alternative_vcall__(nr) +#define alternative_call_(nr) alternative_call__(nr) + +#define alternative_vcall(func, args...) \ + alternative_vcall_(count_args(args))(func, ## args) + +#define alternative_call(func, args...) \ + alternative_call_(count_args(args))(func, ## args) + +#endif /* X86_ALTERNATIVE_CALL_H */ diff --git a/xen/arch/x86/include/asm/alternative.h b/xen/arch/x86/include/asm/alternative.h index 7326ad9428..2d2ace97f7 100644 --- a/xen/arch/x86/include/asm/alternative.h +++ b/xen/arch/x86/include/asm/alternative.h @@ -161,268 +161,6 @@ extern void alternative_branches(void); /* Use this macro(s) if you need more than one output parameter. */ #define ASM_OUTPUT2(a...) a -/* - * Machinery to allow converting indirect to direct calls, when the called - * function is determined once at boot and later never changed. - */ - -#define ALT_CALL_arg1 "rdi" -#define ALT_CALL_arg2 "rsi" -#define ALT_CALL_arg3 "rdx" -#define ALT_CALL_arg4 "rcx" -#define ALT_CALL_arg5 "r8" -#define ALT_CALL_arg6 "r9" - -#ifdef CONFIG_CC_IS_CLANG -/* - * Clang doesn't follow the psABI and doesn't truncate parameter values at the - * callee. This can lead to bad code being generated when using alternative - * calls. - * - * Workaround it by using a temporary intermediate variable that's zeroed - * before being assigned the parameter value, as that forces clang to zero the - * register at the caller. - * - * This has been reported upstream: - * https://github.com/llvm/llvm-project/issues/12579 - * https://github.com/llvm/llvm-project/issues/82598 - */ -#define ALT_CALL_ARG(arg, n) \ - register unsigned long a ## n ## _ asm ( ALT_CALL_arg ## n ) = ({ \ - unsigned long tmp = 0; \ - BUILD_BUG_ON(sizeof(arg) > sizeof(unsigned long)); \ - *(typeof(arg) *)&tmp = (arg); \ - tmp; \ - }) -#else -#define ALT_CALL_ARG(arg, n) \ - register typeof(arg) a ## n ## _ asm ( ALT_CALL_arg ## n ) = \ - ({ BUILD_BUG_ON(sizeof(arg) > sizeof(void *)); (arg); }) -#endif -#define ALT_CALL_NO_ARG(n) \ - register unsigned long a ## n ## _ asm ( ALT_CALL_arg ## n ) - -#define ALT_CALL_NO_ARG6 ALT_CALL_NO_ARG(6) -#define ALT_CALL_NO_ARG5 ALT_CALL_NO_ARG(5); ALT_CALL_NO_ARG6 -#define ALT_CALL_NO_ARG4 ALT_CALL_NO_ARG(4); ALT_CALL_NO_ARG5 -#define ALT_CALL_NO_ARG3 ALT_CALL_NO_ARG(3); ALT_CALL_NO_ARG4 -#define ALT_CALL_NO_ARG2 ALT_CALL_NO_ARG(2); ALT_CALL_NO_ARG3 -#define ALT_CALL_NO_ARG1 ALT_CALL_NO_ARG(1); ALT_CALL_NO_ARG2 - -/* - * Unfortunately ALT_CALL_NO_ARG() above can't use a fake initializer (to - * suppress "uninitialized variable" warnings), as various versions of gcc - * older than 8.1 fall on the nose in various ways with that (always because - * of some other construct elsewhere in the same function needing to use the - * same hard register). Otherwise the asm() below could uniformly use "+r" - * output constraints, making unnecessary all these ALT_CALL_OUT macros. - */ -#define ALT_CALL0_OUT "=r" (a1_), "=r" (a2_), "=r" (a3_), \ - "=r" (a4_), "=r" (a5_), "=r" (a6_) -#define ALT_CALL1_OUT "+r" (a1_), "=r" (a2_), "=r" (a3_), \ - "=r" (a4_), "=r" (a5_), "=r" (a6_) -#define ALT_CALL2_OUT "+r" (a1_), "+r" (a2_), "=r" (a3_), \ - "=r" (a4_), "=r" (a5_), "=r" (a6_) -#define ALT_CALL3_OUT "+r" (a1_), "+r" (a2_), "+r" (a3_), \ - "=r" (a4_), "=r" (a5_), "=r" (a6_) -#define ALT_CALL4_OUT "+r" (a1_), "+r" (a2_), "+r" (a3_), \ - "+r" (a4_), "=r" (a5_), "=r" (a6_) -#define ALT_CALL5_OUT "+r" (a1_), "+r" (a2_), "+r" (a3_), \ - "+r" (a4_), "+r" (a5_), "=r" (a6_) -#define ALT_CALL6_OUT "+r" (a1_), "+r" (a2_), "+r" (a3_), \ - "+r" (a4_), "+r" (a5_), "+r" (a6_) - -#define alternative_callN(n, rettype, func) ({ \ - rettype ret_; \ - register unsigned long r10_ asm("r10"); \ - register unsigned long r11_ asm("r11"); \ - asm volatile (ALTERNATIVE("call *%c[addr](%%rip)", "call .", \ - X86_FEATURE_ALWAYS) \ - : ALT_CALL ## n ## _OUT, "=a" (ret_), \ - "=r" (r10_), "=r" (r11_) ASM_CALL_CONSTRAINT \ - : [addr] "i" (&(func)), "g" (func) \ - : "memory" ); \ - ret_; \ -}) - -#define alternative_vcall0(func) ({ \ - ALT_CALL_NO_ARG1; \ - (void)sizeof(func()); \ - (void)alternative_callN(0, int, func); \ -}) - -#define alternative_call0(func) ({ \ - ALT_CALL_NO_ARG1; \ - alternative_callN(0, typeof(func()), func); \ -}) - -#define alternative_vcall1(func, arg) ({ \ - typeof(arg) v1_ = (arg); \ - ALT_CALL_ARG(v1_, 1); \ - ALT_CALL_NO_ARG2; \ - (void)sizeof(func(arg)); \ - (void)alternative_callN(1, int, func); \ -}) - -#define alternative_call1(func, arg) ({ \ - typeof(arg) v1_ = (arg); \ - ALT_CALL_ARG(v1_, 1); \ - ALT_CALL_NO_ARG2; \ - alternative_callN(1, typeof(func(arg)), func); \ -}) - -#define alternative_vcall2(func, arg1, arg2) ({ \ - typeof(arg1) v1_ = (arg1); \ - typeof(arg2) v2_ = (arg2); \ - ALT_CALL_ARG(v1_, 1); \ - ALT_CALL_ARG(v2_, 2); \ - ALT_CALL_NO_ARG3; \ - (void)sizeof(func(arg1, arg2)); \ - (void)alternative_callN(2, int, func); \ -}) - -#define alternative_call2(func, arg1, arg2) ({ \ - typeof(arg1) v1_ = (arg1); \ - typeof(arg2) v2_ = (arg2); \ - ALT_CALL_ARG(v1_, 1); \ - ALT_CALL_ARG(v2_, 2); \ - ALT_CALL_NO_ARG3; \ - alternative_callN(2, typeof(func(arg1, arg2)), func); \ -}) - -#define alternative_vcall3(func, arg1, arg2, arg3) ({ \ - typeof(arg1) v1_ = (arg1); \ - typeof(arg2) v2_ = (arg2); \ - typeof(arg3) v3_ = (arg3); \ - ALT_CALL_ARG(v1_, 1); \ - ALT_CALL_ARG(v2_, 2); \ - ALT_CALL_ARG(v3_, 3); \ - ALT_CALL_NO_ARG4; \ - (void)sizeof(func(arg1, arg2, arg3)); \ - (void)alternative_callN(3, int, func); \ -}) - -#define alternative_call3(func, arg1, arg2, arg3) ({ \ - typeof(arg1) v1_ = (arg1); \ - typeof(arg2) v2_ = (arg2); \ - typeof(arg3) v3_ = (arg3); \ - ALT_CALL_ARG(v1_, 1); \ - ALT_CALL_ARG(v2_, 2); \ - ALT_CALL_ARG(v3_, 3); \ - ALT_CALL_NO_ARG4; \ - alternative_callN(3, typeof(func(arg1, arg2, arg3)), \ - func); \ -}) - -#define alternative_vcall4(func, arg1, arg2, arg3, arg4) ({ \ - typeof(arg1) v1_ = (arg1); \ - typeof(arg2) v2_ = (arg2); \ - typeof(arg3) v3_ = (arg3); \ - typeof(arg4) v4_ = (arg4); \ - ALT_CALL_ARG(v1_, 1); \ - ALT_CALL_ARG(v2_, 2); \ - ALT_CALL_ARG(v3_, 3); \ - ALT_CALL_ARG(v4_, 4); \ - ALT_CALL_NO_ARG5; \ - (void)sizeof(func(arg1, arg2, arg3, arg4)); \ - (void)alternative_callN(4, int, func); \ -}) - -#define alternative_call4(func, arg1, arg2, arg3, arg4) ({ \ - typeof(arg1) v1_ = (arg1); \ - typeof(arg2) v2_ = (arg2); \ - typeof(arg3) v3_ = (arg3); \ - typeof(arg4) v4_ = (arg4); \ - ALT_CALL_ARG(v1_, 1); \ - ALT_CALL_ARG(v2_, 2); \ - ALT_CALL_ARG(v3_, 3); \ - ALT_CALL_ARG(v4_, 4); \ - ALT_CALL_NO_ARG5; \ - alternative_callN(4, typeof(func(arg1, arg2, \ - arg3, arg4)), \ - func); \ -}) - -#define alternative_vcall5(func, arg1, arg2, arg3, arg4, arg5) ({ \ - typeof(arg1) v1_ = (arg1); \ - typeof(arg2) v2_ = (arg2); \ - typeof(arg3) v3_ = (arg3); \ - typeof(arg4) v4_ = (arg4); \ - typeof(arg5) v5_ = (arg5); \ - ALT_CALL_ARG(v1_, 1); \ - ALT_CALL_ARG(v2_, 2); \ - ALT_CALL_ARG(v3_, 3); \ - ALT_CALL_ARG(v4_, 4); \ - ALT_CALL_ARG(v5_, 5); \ - ALT_CALL_NO_ARG6; \ - (void)sizeof(func(arg1, arg2, arg3, arg4, arg5)); \ - (void)alternative_callN(5, int, func); \ -}) - -#define alternative_call5(func, arg1, arg2, arg3, arg4, arg5) ({ \ - typeof(arg1) v1_ = (arg1); \ - typeof(arg2) v2_ = (arg2); \ - typeof(arg3) v3_ = (arg3); \ - typeof(arg4) v4_ = (arg4); \ - typeof(arg5) v5_ = (arg5); \ - ALT_CALL_ARG(v1_, 1); \ - ALT_CALL_ARG(v2_, 2); \ - ALT_CALL_ARG(v3_, 3); \ - ALT_CALL_ARG(v4_, 4); \ - ALT_CALL_ARG(v5_, 5); \ - ALT_CALL_NO_ARG6; \ - alternative_callN(5, typeof(func(arg1, arg2, arg3, \ - arg4, arg5)), \ - func); \ -}) - -#define alternative_vcall6(func, arg1, arg2, arg3, arg4, arg5, arg6) ({ \ - typeof(arg1) v1_ = (arg1); \ - typeof(arg2) v2_ = (arg2); \ - typeof(arg3) v3_ = (arg3); \ - typeof(arg4) v4_ = (arg4); \ - typeof(arg5) v5_ = (arg5); \ - typeof(arg6) v6_ = (arg6); \ - ALT_CALL_ARG(v1_, 1); \ - ALT_CALL_ARG(v2_, 2); \ - ALT_CALL_ARG(v3_, 3); \ - ALT_CALL_ARG(v4_, 4); \ - ALT_CALL_ARG(v5_, 5); \ - ALT_CALL_ARG(v6_, 6); \ - (void)sizeof(func(arg1, arg2, arg3, arg4, arg5, arg6)); \ - (void)alternative_callN(6, int, func); \ -}) - -#define alternative_call6(func, arg1, arg2, arg3, arg4, arg5, arg6) ({ \ - typeof(arg1) v1_ = (arg1); \ - typeof(arg2) v2_ = (arg2); \ - typeof(arg3) v3_ = (arg3); \ - typeof(arg4) v4_ = (arg4); \ - typeof(arg5) v5_ = (arg5); \ - typeof(arg6) v6_ = (arg6); \ - ALT_CALL_ARG(v1_, 1); \ - ALT_CALL_ARG(v2_, 2); \ - ALT_CALL_ARG(v3_, 3); \ - ALT_CALL_ARG(v4_, 4); \ - ALT_CALL_ARG(v5_, 5); \ - ALT_CALL_ARG(v6_, 6); \ - alternative_callN(6, typeof(func(arg1, arg2, arg3, \ - arg4, arg5, arg6)), \ - func); \ -}) - -#define alternative_vcall__(nr) alternative_vcall ## nr -#define alternative_call__(nr) alternative_call ## nr - -#define alternative_vcall_(nr) alternative_vcall__(nr) -#define alternative_call_(nr) alternative_call__(nr) - -#define alternative_vcall(func, args...) \ - alternative_vcall_(count_args(args))(func, ## args) - -#define alternative_call(func, args...) \ - alternative_call_(count_args(args))(func, ## args) - #endif /* !__ASSEMBLY__ */ #endif /* __X86_ALTERNATIVE_H__ */ diff --git a/xen/arch/x86/include/asm/hvm/hvm.h b/xen/arch/x86/include/asm/hvm/hvm.h index 963e820113..bf8bc2e100 100644 --- a/xen/arch/x86/include/asm/hvm/hvm.h +++ b/xen/arch/x86/include/asm/hvm/hvm.h @@ -9,9 +9,9 @@ #ifndef __ASM_X86_HVM_HVM_H__ #define __ASM_X86_HVM_HVM_H__ +#include #include -#include #include #include #include diff --git a/xen/common/core_parking.c b/xen/common/core_parking.c index a970ffeab8..7d6a18cdcf 100644 --- a/xen/common/core_parking.c +++ b/xen/common/core_parking.c @@ -15,10 +15,10 @@ * General Public License for more details. */ -#include +#include #include -#include #include +#include #include #include diff --git a/xen/include/xen/alternative-call.h b/xen/include/xen/alternative-call.h index 62672b7324..39339c3f0f 100644 --- a/xen/include/xen/alternative-call.h +++ b/xen/include/xen/alternative-call.h @@ -13,10 +13,10 @@ * * For architectures to support: * - * - Implement alternative_{,v}call() in asm/alternative.h. Code generation - * requirements are to emit a function pointer call at build time, and stash - * enough metadata to simplify the call at boot once the implementation has - * been resolved. + * - Implement alternative_{,v}call() in asm/alternative-call.h. Code + * generation requirements are to emit a function pointer call at build + * time, and stash enough metadata to simplify the call at boot once the + * implementation has been resolved. * - Select ALTERNATIVE_CALL in Kconfig. * * To use: @@ -48,7 +48,7 @@ #ifdef CONFIG_ALTERNATIVE_CALL -#include +#include #ifdef CONFIG_LIVEPATCH /* Must keep for livepatches to resolve alternative calls. */ -- 2.39.5