Commit df62b68c authored by Michael Ellerman's avatar Michael Ellerman Committed by Kleber Sacilotto de Souza

KVM: PPC: Book3S HV: Flush link stack on guest exit to host kernel

BugLink: https://bugs.launchpad.net/bugs/1853142

commit af2e8c68 upstream.

On some systems that are vulnerable to Spectre v2, it is up to
software to flush the link stack (return address stack), in order to
protect against Spectre-RSB.

When exiting from a guest we do some house keeping and then
potentially exit to C code which is several stack frames deep in the
host kernel. We will then execute a series of returns without
preceeding calls, opening up the possiblity that the guest could have
poisoned the link stack, and direct speculative execution of the host
to a gadget of some sort.

To prevent this we add a flush of the link stack on exit from a guest.
Signed-off-by: default avatarMichael Ellerman <mpe@ellerman.id.au>
[dja: backport to v4.4, drop P9 support]
Signed-off-by: default avatarDaniel Axtens <dja@axtens.net>

CVE-2019-18660
Signed-off-by: default avatarBenjamin M Romer <benjamin.romer@canonical.com>
Acked-by: default avatarStefan Bader <stefan.bader@canonical.com>
Acked-by: default avatarSultan Alsawaf <sultan.alsawaf@canonical.com>
Signed-off-by: default avatarStefan Bader <stefan.bader@canonical.com>
parent f0b64bfd
......@@ -16,7 +16,9 @@
extern s32 patch__call_flush_count_cache;
extern s32 patch__flush_count_cache_return;
extern s32 patch__flush_link_stack_return;
extern s32 patch__call_kvm_flush_link_stack;
extern long flush_count_cache;
extern long kvm_flush_link_stack;
#endif /* _ASM_POWERPC_ASM_PROTOTYPES_H */
......@@ -391,6 +391,9 @@ static void toggle_count_cache_flush(bool enable)
if (!enable) {
patch_instruction_site(&patch__call_flush_count_cache, PPC_INST_NOP);
#ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE
patch_instruction_site(&patch__call_kvm_flush_link_stack, PPC_INST_NOP);
#endif
pr_info("link-stack-flush: software flush disabled.\n");
link_stack_flush_enabled = false;
no_count_cache_flush();
......@@ -401,6 +404,12 @@ static void toggle_count_cache_flush(bool enable)
patch_branch_site(&patch__call_flush_count_cache,
(u64)&flush_count_cache, BRANCH_SET_LINK);
#ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE
// This enables the branch from guest_exit_cont to kvm_flush_link_stack
patch_branch_site(&patch__call_kvm_flush_link_stack,
(u64)&kvm_flush_link_stack, BRANCH_SET_LINK);
#endif
pr_info("link-stack-flush: software flush enabled.\n");
link_stack_flush_enabled = true;
......
......@@ -18,6 +18,7 @@
*/
#include <asm/ppc_asm.h>
#include <asm/code-patching-asm.h>
#include <asm/kvm_asm.h>
#include <asm/reg.h>
#include <asm/mmu.h>
......@@ -1193,6 +1194,10 @@ mc_cont:
bl kvmhv_accumulate_time
#endif
/* Possibly flush the link stack here. */
1: nop
patch_site 1b patch__call_kvm_flush_link_stack
mr r3, r12
/* Increment exit count, poke other threads to exit */
bl kvmhv_commence_exit
......@@ -1611,6 +1616,21 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S)
mtlr r0
blr
.balign 32
.global kvm_flush_link_stack
kvm_flush_link_stack:
/* Save LR into r0 */
mflr r0
/* Flush the link stack. On Power8 it's up to 32 entries in size. */
.rept 32
bl .+4
.endr
/* Restore LR */
mtlr r0
blr
/*
* Check whether an HDSI is an HPTE not found fault or something else.
* If it is an HPTE not found fault that is due to the guest accessing
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment