Skip to content

Commit

Permalink
powerpc/security: Allow for processors that flush the link stack usin…
Browse files Browse the repository at this point in the history
…g 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
  • Loading branch information
npiggin authored and mpe committed Jul 16, 2020
1 parent 70d7cda commit 4d24e21
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 8 deletions.
2 changes: 2 additions & 0 deletions arch/powerpc/include/asm/security_features.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@ static inline bool security_ftr_enabled(u64 feature)
// bcctr 2,0,0 triggers a hardware assisted count cache flush
#define SEC_FTR_BCCTR_FLUSH_ASSIST 0x0000000000000800ull

// bcctr 2,0,0 triggers a hardware assisted link stack flush
#define SEC_FTR_BCCTR_LINK_FLUSH_ASSIST 0x0000000000002000ull

// Features indicating need for Spectre/Meltdown mitigations

Expand Down
27 changes: 19 additions & 8 deletions arch/powerpc/kernel/security.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
}
Expand All @@ -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);
Expand Down Expand Up @@ -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();
Expand Down

0 comments on commit 4d24e21

Please sign in to comment.