Message ID | 20190926183808.11630-9-julien.grall@arm.com |
---|---|
State | Superseded |
Headers | show |
Series | xen/arm: XSA-201 and XSA-263 fixes | expand |
Julien Grall writes: > From: Mark Rutland <mark.rutland@arm.com> > > In some cases, one side of an alternative sequence is simply a number of > NOPs used to balance the other side. Keeping track of this manually is > tedious, and the presence of large chains of NOPs makes the code more > painful to read than necessary. > > To ameliorate matters, this patch adds a new alternative_else_nop_endif, > which automatically balances an alternative sequence with a trivial NOP > sled. > > In many cases, we would like a NOP-sled in the default case, and > instructions patched in in the presence of a feature. To enable the NOPs > to be generated automatically for this case, this patch also adds a new > alternative_if, and updates alternative_else and alternative_endif to > work with either alternative_if or alternative_endif. > > The alternative infrastructure was originally ported from Linux. So this > is pretty much a straight backport from commit 792d47379f4d "arm64: > alternative: add auto-nop infrastructure". The only difference is the > nops macro added as not yet existing in Xen. > > Signed-off-by: Mark Rutland <mark.rutland@arm.com> > [will: use new nops macro to generate nop sequences] > Signed-off-by: Will Deacon <will.deacon@arm.com> > [julien: Add nops and port to Xen] > Signed-off-by: Julien Grall <julien.grall@arm.com> Reviewed-by: Volodymyr Babchuk <volodymyr_babchuk@epam.com>
On Fri, 27 Sep 2019, Volodymyr Babchuk wrote: > Julien Grall writes: > > > From: Mark Rutland <mark.rutland@arm.com> > > > > In some cases, one side of an alternative sequence is simply a number of > > NOPs used to balance the other side. Keeping track of this manually is > > tedious, and the presence of large chains of NOPs makes the code more > > painful to read than necessary. > > > > To ameliorate matters, this patch adds a new alternative_else_nop_endif, > > which automatically balances an alternative sequence with a trivial NOP > > sled. > > > > In many cases, we would like a NOP-sled in the default case, and > > instructions patched in in the presence of a feature. To enable the NOPs > > to be generated automatically for this case, this patch also adds a new > > alternative_if, and updates alternative_else and alternative_endif to > > work with either alternative_if or alternative_endif. > > > > The alternative infrastructure was originally ported from Linux. So this > > is pretty much a straight backport from commit 792d47379f4d "arm64: > > alternative: add auto-nop infrastructure". The only difference is the > > nops macro added as not yet existing in Xen. > > > > Signed-off-by: Mark Rutland <mark.rutland@arm.com> > > [will: use new nops macro to generate nop sequences] > > Signed-off-by: Will Deacon <will.deacon@arm.com> > > [julien: Add nops and port to Xen] > > Signed-off-by: Julien Grall <julien.grall@arm.com> > Reviewed-by: Volodymyr Babchuk <volodymyr_babchuk@epam.com> Acked-by: Stefano Stabellini <sstabellini@kernel.org>
diff --git a/xen/include/asm-arm/alternative.h b/xen/include/asm-arm/alternative.h index 2830a6da2d..e8271ac04e 100644 --- a/xen/include/asm-arm/alternative.h +++ b/xen/include/asm-arm/alternative.h @@ -2,6 +2,7 @@ #define __ASM_ALTERNATIVE_H #include <asm/cpufeature.h> +#include <asm/insn.h> #define ARM_CB_PATCH ARM_NCAPS @@ -111,34 +112,55 @@ int apply_alternatives(const struct alt_instr *start, const struct alt_instr *en .endm /* - * Begin an alternative code sequence. + * Alternative sequences + * + * The code for the case where the capability is not present will be + * assembled and linked as normal. There are no restrictions on this + * code. + * + * The code for the case where the capability is present will be + * assembled into a special section to be used for dynamic patching. + * Code for that case must: + * + * 1. Be exactly the same length (in bytes) as the default code + * sequence. * - * The code that follows this macro will be assembled and linked as - * normal. There are no restrictions on this code. + * 2. Not contain a branch target that is used outside of the + * alternative sequence it is defined in (branches into an + * alternative sequence are not fixed up). + */ + +/* + * Begin an alternative code sequence. */ .macro alternative_if_not cap + .set .Lasm_alt_mode, 0 .pushsection .altinstructions, "a" altinstruction_entry 661f, 663f, \cap, 662f-661f, 664f-663f .popsection 661: .endm +.macro alternative_if cap + .set .Lasm_alt_mode, 1 + .pushsection .altinstructions, "a" + altinstruction_entry 663f, 661f, \cap, 664f-663f, 662f-661f + .popsection + .pushsection .altinstr_replacement, "ax" + .align 2 /* So GAS knows label 661 is suitably aligned */ +661: +.endm + /* - * Provide the alternative code sequence. - * - * The code that follows this macro is assembled into a special - * section to be used for dynamic patching. Code that follows this - * macro must: - * - * 1. Be exactly the same length (in bytes) as the default code - * sequence. - * - * 2. Not contain a branch target that is used outside of the - * alternative sequence it is defined in (branches into an - * alternative sequence are not fixed up). + * Provide the other half of the alternative code sequence. */ .macro alternative_else -662: .pushsection .altinstr_replacement, "ax" +662: + .if .Lasm_alt_mode==0 + .pushsection .altinstr_replacement, "ax" + .else + .popsection + .endif 663: .endm @@ -154,12 +176,26 @@ int apply_alternatives(const struct alt_instr *start, const struct alt_instr *en * Complete an alternative code sequence. */ .macro alternative_endif -664: .popsection +664: + .if .Lasm_alt_mode==0 + .popsection + .endif .org . - (664b-663b) + (662b-661b) .org . - (662b-661b) + (664b-663b) .endm /* + * Provides a trivial alternative or default sequence consisting solely + * of NOPs. The number of NOPs is chosen automatically to match the + * previous case. + */ +.macro alternative_else_nop_endif +alternative_else + nops (662b-661b) / ARCH_PATCH_INSN_SIZE +alternative_endif +.endm + +/* * Callback-based alternative epilogue */ .macro alternative_cb_end diff --git a/xen/include/asm-arm/macros.h b/xen/include/asm-arm/macros.h index 1d4bb41d15..91ea3505e4 100644 --- a/xen/include/asm-arm/macros.h +++ b/xen/include/asm-arm/macros.h @@ -13,4 +13,11 @@ # error "unknown ARM variant" #endif + /* NOP sequence */ + .macro nops, num + .rept \num + nop + .endr + .endm + #endif /* __ASM_ARM_MACROS_H */