aboutsummaryrefslogtreecommitdiff
path: root/arch/powerpc/kernel/security.c
diff options
context:
space:
mode:
authorGravatar Nicholas Piggin <npiggin@gmail.com> 2020-06-09 17:06:09 +1000
committerGravatar Michael Ellerman <mpe@ellerman.id.au> 2020-07-16 13:12:32 +1000
commit4d24e21cc694e7253a532fe5a9bde12b284f1317 (patch)
tree8bb401bd0919c77c6319c25e7233401b44c68765 /arch/powerpc/kernel/security.c
parentpowerpc/64s: Move branch cache flushing bcctr variant to ppc-ops.h (diff)
downloadlinux-4d24e21cc694e7253a532fe5a9bde12b284f1317.tar.gz
linux-4d24e21cc694e7253a532fe5a9bde12b284f1317.tar.bz2
linux-4d24e21cc694e7253a532fe5a9bde12b284f1317.zip
powerpc/security: Allow for processors that flush the link stack using the special bcctr
If both count cache and link stack are to be flushed, and can be flushed with the special bcctr, patch that in directly to the flush/branch nop site. Signed-off-by: Nicholas Piggin <npiggin@gmail.com> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au> Link: https://lore.kernel.org/r/20200609070610.846703-7-npiggin@gmail.com
Diffstat (limited to 'arch/powerpc/kernel/security.c')
-rw-r--r--arch/powerpc/kernel/security.c27
1 files changed, 19 insertions, 8 deletions
diff --git a/arch/powerpc/kernel/security.c b/arch/powerpc/kernel/security.c
index 05eeb22b3b97..c9876aab3142 100644
--- a/arch/powerpc/kernel/security.c
+++ b/arch/powerpc/kernel/security.c
@@ -219,24 +219,25 @@ ssize_t cpu_show_spectre_v2(struct device *dev, struct device_attribute *attr, c
if (ccd)
seq_buf_printf(&s, "Indirect branch cache disabled");
- if (link_stack_flush_type == BRANCH_CACHE_FLUSH_SW)
- seq_buf_printf(&s, ", Software link stack flush");
-
} else if (count_cache_flush_type != BRANCH_CACHE_FLUSH_NONE) {
seq_buf_printf(&s, "Mitigation: Software count cache flush");
if (count_cache_flush_type == BRANCH_CACHE_FLUSH_HW)
seq_buf_printf(&s, " (hardware accelerated)");
- if (link_stack_flush_type == BRANCH_CACHE_FLUSH_SW)
- seq_buf_printf(&s, ", Software link stack flush");
-
} else if (btb_flush_enabled) {
seq_buf_printf(&s, "Mitigation: Branch predictor state flush");
} else {
seq_buf_printf(&s, "Vulnerable");
}
+ if (bcs || ccd || count_cache_flush_type != BRANCH_CACHE_FLUSH_NONE) {
+ if (link_stack_flush_type != BRANCH_CACHE_FLUSH_NONE)
+ seq_buf_printf(&s, ", Software link stack flush");
+ if (link_stack_flush_type == BRANCH_CACHE_FLUSH_HW)
+ seq_buf_printf(&s, " (hardware accelerated)");
+ }
+
seq_buf_printf(&s, "\n");
return s.len;
@@ -435,6 +436,7 @@ static void update_branch_cache_flush(void)
patch_instruction_site(&patch__call_kvm_flush_link_stack,
ppc_inst(PPC_INST_NOP));
} else {
+ // Could use HW flush, but that could also flush count cache
patch_branch_site(&patch__call_kvm_flush_link_stack,
(u64)&kvm_flush_link_stack, BRANCH_SET_LINK);
}
@@ -445,6 +447,10 @@ static void update_branch_cache_flush(void)
link_stack_flush_type == BRANCH_CACHE_FLUSH_NONE) {
patch_instruction_site(&patch__call_flush_branch_caches,
ppc_inst(PPC_INST_NOP));
+ } else if (count_cache_flush_type == BRANCH_CACHE_FLUSH_HW &&
+ link_stack_flush_type == BRANCH_CACHE_FLUSH_HW) {
+ patch_instruction_site(&patch__call_flush_branch_caches,
+ ppc_inst(PPC_INST_BCCTR_FLUSH));
} else {
patch_branch_site(&patch__call_flush_branch_caches,
(u64)&flush_branch_caches, BRANCH_SET_LINK);
@@ -485,8 +491,13 @@ static void toggle_branch_cache_flush(bool enable)
pr_info("link-stack-flush: flush disabled.\n");
} else {
- link_stack_flush_type = BRANCH_CACHE_FLUSH_SW;
- pr_info("link-stack-flush: software flush enabled.\n");
+ if (security_ftr_enabled(SEC_FTR_BCCTR_LINK_FLUSH_ASSIST)) {
+ link_stack_flush_type = BRANCH_CACHE_FLUSH_HW;
+ pr_info("link-stack-flush: hardware flush enabled.\n");
+ } else {
+ link_stack_flush_type = BRANCH_CACHE_FLUSH_SW;
+ pr_info("link-stack-flush: software flush enabled.\n");
+ }
}
update_branch_cache_flush();