In order to protect against speculation attacks on
indirect branches, the branch predictor is flushed at
kernel entry to protect for the following situations:
- userspace process attacking another userspace process
- userspace process attacking the kernel
Basically when the privillege level change (i.e. the
kernel is entered), the branch predictor state is flushed.
Signed-off-by: Diana Craciun <redacted>
---
arch/powerpc/kernel/entry_64.S | 5 +++++
arch/powerpc/kernel/exceptions-64e.S | 26 +++++++++++++++++++++++++-
arch/powerpc/mm/tlb_low_64e.S | 7 +++++++
3 files changed, 37 insertions(+), 1 deletion(-)
Switching from the guest to host is another place
where the speculative accesses can be exploited.
Flush the branch predictor when entering KVM.
Signed-off-by: Diana Craciun <redacted>
---
arch/powerpc/kvm/bookehv_interrupts.S | 4 ++++
1 file changed, 4 insertions(+)
In order to protect against speculation attacks (Spectre
variant 2) on NXP PowerPC platforms, the branch predictor
should be flushed when the privillege level is changed.
This patch is adding the infrastructure to fixup at runtime
the code sections that are performing the branch predictor flush
depending on a boot arg parameter which is added later in a
separate patch.
Signed-off-by: Diana Craciun <redacted>
---
arch/powerpc/include/asm/feature-fixups.h | 12 ++++++++++++
arch/powerpc/include/asm/setup.h | 2 ++
arch/powerpc/kernel/vmlinux.lds.S | 8 ++++++++
arch/powerpc/lib/feature-fixups.c | 21 +++++++++++++++++++++
4 files changed, 43 insertions(+)
From: Michael Ellerman <hidden> Date: 2018-12-22 10:25:38
On Wed, 2018-12-12 at 14:03:00 UTC, Diana Craciun wrote:
In order to protect against speculation attacks (Spectre
variant 2) on NXP PowerPC platforms, the branch predictor
should be flushed when the privillege level is changed.
This patch is adding the infrastructure to fixup at runtime
the code sections that are performing the branch predictor flush
depending on a boot arg parameter which is added later in a
separate patch.
Signed-off-by: Diana Craciun <redacted>
@@ -2827,7 +2827,7 @@ check bypass). With this option data leaks are possible in the system.- nospectre_v2 [X86] Disable all mitigations for the Spectre variant 2+ nospectre_v2 [X86,PPC_FSL_BOOK3E] Disable all mitigations for the Spectre variant 2 (indirect branch prediction) vulnerability. System may allow data leaks with this option, which is equivalent to spectre_v2=off.
If the user choses not to use the mitigations, replace
the code sequence with nops.
Signed-off-by: Diana Craciun <redacted>
---
arch/powerpc/kernel/setup-common.c | 1 +
1 file changed, 1 insertion(+)
The BUCSR register can be used to invalidate the entries in the
branch prediction mechanisms.
Signed-off-by: Diana Craciun <redacted>
---
arch/powerpc/include/asm/ppc_asm.h | 10 ++++++++++
1 file changed, 10 insertions(+)
In order to flush the branch predictor the guest kernel
performs writes to the BUCSR register which is hypervisor
privilleged. However, the branch predictor is flushed at
each KVM entry, so the branch predictor has been already
flushed, so just return as soon as possible to guest.
Signed-off-by: Diana Craciun <redacted>
---
arch/powerpc/kvm/e500_emulate.c | 5 +++++
1 file changed, 5 insertions(+)
@@ -276,6 +276,11 @@ int kvmppc_core_emulate_mtspr_e500(struct kvm_vcpu *vcpu, int sprn, ulong spr_va*/vcpu->arch.pwrmgtcr0=spr_val;break;+/* if we are here, it means that we have already flushed the+*branchpredictor,sojustreturntoguest+*/+caseSPRN_BUCSR:+break;/* extra exceptions */#ifdef CONFIG_SPE_POSSIBLE
In order to protect against speculation attacks on
indirect branches, the branch predictor is flushed at
kernel entry to protect for the following situations:
- userspace process attacking another userspace process
- userspace process attacking the kernel
Basically when the privillege level change (i.e.the kernel
is entered), the branch predictor state is flushed.
Signed-off-by: Diana Craciun <redacted>
---
arch/powerpc/kernel/head_booke.h | 6 ++++++
arch/powerpc/kernel/head_fsl_booke.S | 15 +++++++++++++++
2 files changed, 21 insertions(+)
@@ -43,6 +43,9 @@andi.r11,r11,MSR_PR;/* check whether user or kernel */\mrr11,r1;\beq1f;\+START_BTB_FLUSH_SECTION\+BTB_FLUSH(r11)\+END_BTB_FLUSH_SECTION\/* if from user, start at top of this thread's kernel stack */\lwzr11,THREAD_INFO-THREAD(r10);\ALLOC_STACK_FRAME(r11,THREAD_SIZE);\
@@ -128,6 +131,9 @@stwr9,_CCR(r8);/* save CR on stack */\mfsprr11,exc_level_srr1;/* check whether user or kernel */\DO_KVMBOOKE_INTERRUPT_##intnoexc_level_srr1;\+START_BTB_FLUSH_SECTION\+BTB_FLUSH(r10)\+END_BTB_FLUSH_SECTION\andi.r11,r11,MSR_PR;\mfsprr11,SPRN_SPRG_THREAD;/* if from user, start at top of */\lwzr11,THREAD_INFO-THREAD(r11);/* this thread's kernel stack */\
powerpc-linux-gnu-ld: warning: orphan section `__btb_flush_fixup' from `arch/powerpc/kernel/head_44x.o' being placed in section `__btb_flush_fixup'.
powerpc-linux-gnu-ld: warning: orphan section `__btb_flush_fixup' from `arch/powerpc/kernel/head_44x.o' being placed in section `__btb_flush_fixup'.
powerpc-linux-gnu-ld: warning: orphan section `__btb_flush_fixup' from `arch/powerpc/kernel/head_44x.o' being placed in section `__btb_flush_fixup'.