Message ID | 20180119134103.3390-7-julien.grall@linaro.org |
---|---|
State | Superseded |
Headers | show |
Series | xen/arm32: Branch predictor hardening (XSA-254 variant 2) | expand |
On Fri, 19 Jan 2018, Julien Grall wrote: > In order to avoid aliasing attacks against the branch predictor on > Cortex A-15, let's invalidate the BTB on guest exit, which can only be > done by invalidating the icache (with ACTLR[0] being set). > > We use the same hack as for A12/A17 to perform the vector decoding. > > This is based on Linux patch from the kpti branch in [1]. > > [1] https://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux.git > > Signed-off-by: Marc Zyngier <marc.zyngier@arm.com> > Signed-off-by: Julien Grall <julien.grall@linaro.org> Reviewed-by: Stefano Stabellini <sstabellini@kernel.org> > --- > xen/arch/arm/arm32/entry.S | 21 +++++++++++++++++++++ > xen/arch/arm/cpuerrata.c | 13 +++++++++++++ > 2 files changed, 34 insertions(+) > > diff --git a/xen/arch/arm/arm32/entry.S b/xen/arch/arm/arm32/entry.S > index c6ec0aa399..c529592d20 100644 > --- a/xen/arch/arm/arm32/entry.S > +++ b/xen/arch/arm/arm32/entry.S > @@ -161,6 +161,26 @@ GLOBAL(hyp_traps_vector) > b trap_fiq /* 0x1c - FIQ */ > > .align 5 > +GLOBAL(hyp_traps_vector_ic_inv) > + /* > + * We encode the exception entry in the bottom 3 bits of > + * SP, and we have to guarantee to be 8 bytes aligned. > + */ > + add sp, sp, #1 /* Reset 7 */ > + add sp, sp, #1 /* Undef 6 */ > + add sp, sp, #1 /* Hypervisor call 5 */ > + add sp, sp, #1 /* Prefetch abort 4 */ > + add sp, sp, #1 /* Data abort 3 */ > + add sp, sp, #1 /* Hypervisor 2 */ > + add sp, sp, #1 /* IRQ 1 */ > + nop /* FIQ 0 */ > + > + mcr p15, 0, r0, c7, c5, 0 /* ICIALLU */ > + isb > + > + b decode_vectors > + > + .align 5 > GLOBAL(hyp_traps_vector_bp_inv) > /* > * We encode the exception entry in the bottom 3 bits of > @@ -178,6 +198,7 @@ GLOBAL(hyp_traps_vector_bp_inv) > mcr p15, 0, r0, c7, c5, 6 /* BPIALL */ > isb > > +decode_vectors: > /* > * As we cannot use any temporary registers and cannot > * clobber SP, we can decode the exception entry using > diff --git a/xen/arch/arm/cpuerrata.c b/xen/arch/arm/cpuerrata.c > index c79e6d65d3..9c7458ef06 100644 > --- a/xen/arch/arm/cpuerrata.c > +++ b/xen/arch/arm/cpuerrata.c > @@ -180,6 +180,7 @@ static int enable_psci_bp_hardening(void *data) > DEFINE_PER_CPU_READ_MOSTLY(const char *, bp_harden_vecs); > > extern char hyp_traps_vector_bp_inv[]; > +extern char hyp_traps_vector_ic_inv[]; > > static void __maybe_unused > install_bp_hardening_vecs(const struct arm_cpu_capabilities *entry, > @@ -205,6 +206,13 @@ static int enable_bp_inv_hardening(void *data) > return 0; > } > > +static int enable_ic_inv_hardening(void *data) > +{ > + install_bp_hardening_vecs(data, hyp_traps_vector_ic_inv, > + "execute ICIALLU"); > + return 0; > +} > + > #endif > > #define MIDR_RANGE(model, min, max) \ > @@ -302,6 +310,11 @@ static const struct arm_cpu_capabilities arm_errata[] = { > MIDR_ALL_VERSIONS(MIDR_CORTEX_A17), > .enable = enable_bp_inv_hardening, > }, > + { > + .capability = ARM_HARDEN_BRANCH_PREDICTOR, > + MIDR_ALL_VERSIONS(MIDR_CORTEX_A15), > + .enable = enable_ic_inv_hardening, > + }, > #endif > {}, > }; > -- > 2.11.0 >
diff --git a/xen/arch/arm/arm32/entry.S b/xen/arch/arm/arm32/entry.S index c6ec0aa399..c529592d20 100644 --- a/xen/arch/arm/arm32/entry.S +++ b/xen/arch/arm/arm32/entry.S @@ -161,6 +161,26 @@ GLOBAL(hyp_traps_vector) b trap_fiq /* 0x1c - FIQ */ .align 5 +GLOBAL(hyp_traps_vector_ic_inv) + /* + * We encode the exception entry in the bottom 3 bits of + * SP, and we have to guarantee to be 8 bytes aligned. + */ + add sp, sp, #1 /* Reset 7 */ + add sp, sp, #1 /* Undef 6 */ + add sp, sp, #1 /* Hypervisor call 5 */ + add sp, sp, #1 /* Prefetch abort 4 */ + add sp, sp, #1 /* Data abort 3 */ + add sp, sp, #1 /* Hypervisor 2 */ + add sp, sp, #1 /* IRQ 1 */ + nop /* FIQ 0 */ + + mcr p15, 0, r0, c7, c5, 0 /* ICIALLU */ + isb + + b decode_vectors + + .align 5 GLOBAL(hyp_traps_vector_bp_inv) /* * We encode the exception entry in the bottom 3 bits of @@ -178,6 +198,7 @@ GLOBAL(hyp_traps_vector_bp_inv) mcr p15, 0, r0, c7, c5, 6 /* BPIALL */ isb +decode_vectors: /* * As we cannot use any temporary registers and cannot * clobber SP, we can decode the exception entry using diff --git a/xen/arch/arm/cpuerrata.c b/xen/arch/arm/cpuerrata.c index c79e6d65d3..9c7458ef06 100644 --- a/xen/arch/arm/cpuerrata.c +++ b/xen/arch/arm/cpuerrata.c @@ -180,6 +180,7 @@ static int enable_psci_bp_hardening(void *data) DEFINE_PER_CPU_READ_MOSTLY(const char *, bp_harden_vecs); extern char hyp_traps_vector_bp_inv[]; +extern char hyp_traps_vector_ic_inv[]; static void __maybe_unused install_bp_hardening_vecs(const struct arm_cpu_capabilities *entry, @@ -205,6 +206,13 @@ static int enable_bp_inv_hardening(void *data) return 0; } +static int enable_ic_inv_hardening(void *data) +{ + install_bp_hardening_vecs(data, hyp_traps_vector_ic_inv, + "execute ICIALLU"); + return 0; +} + #endif #define MIDR_RANGE(model, min, max) \ @@ -302,6 +310,11 @@ static const struct arm_cpu_capabilities arm_errata[] = { MIDR_ALL_VERSIONS(MIDR_CORTEX_A17), .enable = enable_bp_inv_hardening, }, + { + .capability = ARM_HARDEN_BRANCH_PREDICTOR, + MIDR_ALL_VERSIONS(MIDR_CORTEX_A15), + .enable = enable_ic_inv_hardening, + }, #endif {}, };