Commit e1f3564b authored by Michael Ellerman's avatar Michael Ellerman Committed by Marcelo Henrique Cerri

UBUNTU: SAUCE: rfi-flush: Push the instruction selection down to the patching routine

CVE-2017-5754

BugLink: http://bugs.launchpad.net/bugs/1742772Signed-off-by: default avatarMichael Ellerman <mpe@ellerman.id.au>
Signed-off-by: default avatarMarcelo Henrique Cerri <marcelo.cerri@canonical.com>
parent 0929d8b8
......@@ -196,7 +196,6 @@ label##3: \
#include <linux/types.h>
extern long __start___rfi_flush_fixup, __stop___rfi_flush_fixup;
extern void do_rfi_flush_fixups(bool enable, unsigned int insn);
#endif
......
......@@ -37,6 +37,7 @@ enum l1d_flush_type {
};
void __init setup_rfi_flush(enum l1d_flush_type, bool enable);
void do_rfi_flush_fixups(enum l1d_flush_type types);
#endif /* !__ASSEMBLY__ */
......
......@@ -850,36 +850,14 @@ static void do_nothing(void *unused)
void rfi_flush_enable(bool enable)
{
unsigned int insn;
if (rfi_flush == enable)
return;
switch (l1d_flush_type) {
case L1D_FLUSH_NONE:
insn = 0x60000000; /* nop */
break;
case L1D_FLUSH_FALLBACK:
insn = 0x48000008; /* b .+8 to fallback flush */
pr_info("rfi-fixups: Using fallback displacement flush\n");
break;
case L1D_FLUSH_ORI:
insn = 0x63de0000;
pr_info("rfi-fixups: Using ori type flush\n");
break;
case L1D_FLUSH_MTTRIG:
insn = 0x7c12dba6;
pr_info("rfi-fixups: Using mttrig type flush\n");
break;
default:
printk("rfi-fixups: No flush type detected, system may be vulnerable, update firmware.\n");
return;
}
do_rfi_flush_fixups(enable, insn);
if (enable)
if (enable) {
do_rfi_flush_fixups(l1d_flush_type);
on_each_cpu(do_nothing, NULL, 1);
} else
do_rfi_flush_fixups(L1D_FLUSH_NONE);
rfi_flush = enable;
}
......@@ -891,6 +869,8 @@ void __init setup_rfi_flush(enum l1d_flush_type type, bool enable)
u64 l1d_size = ppc64_caches.dsize;
u64 limit = min(safe_stack_limit(), ppc64_rma_size);
pr_info("rfi-fixups: Using fallback displacement flush\n");
/*
* Align to L1d size, and size it at 2x L1d size, to
* catch possible hardware prefetch runoff. We don't
......@@ -916,7 +896,10 @@ void __init setup_rfi_flush(enum l1d_flush_type type, bool enable)
paca[cpu].l1d_flush_congruence = c;
paca[cpu].l1d_flush_sets = c / 128;
}
}
} else if (type == L1D_FLUSH_ORI)
pr_info("rfi-fixups: Using ori type flush\n");
else if (type == L1D_FLUSH_MTTRIG)
pr_info("rfi-fixups: Using mttrig type flush\n");
l1d_flush_type = type;
rfi_flush_enable(enable);
......
......@@ -114,26 +114,35 @@ void do_feature_fixups(unsigned long value, void *fixup_start, void *fixup_end)
}
#ifdef CONFIG_PPC_BOOK3S_64
void do_rfi_flush_fixups(bool enable, unsigned int insn)
void do_rfi_flush_fixups(enum l1d_flush_type types)
{
long *start, *end;
unsigned int *dest;
unsigned int instr, *dest;
int i;
switch (type) {
case L1D_FLUSH_FALLBACK:
instr = 0x48000008; /* b .+8 to fallback flush */
break;
case L1D_FLUSH_ORI:
instr = 0x63de0000; /* ori 30,30,0 */
break;
case L1D_FLUSH_MTTRIG:
instr = 0x7c12dba6; /* mtspr TRIG2,r0 (SPR #882) */
break;
default:
instr = 0x60000000; /* nop */
break;
}
start = PTRRELOC(&__start___rfi_flush_fixup),
end = PTRRELOC(&__stop___rfi_flush_fixup);
for (i = 0; start < end; start++, i++) {
dest = (void *)start + *start;
pr_devel("RFI FLUSH FIXUP %s %lx\n", enable ? "enable" : "disable", (unsigned long)start);
if (!enable) {
pr_devel("patching dest %lx\n", (unsigned long)dest);
patch_instruction(dest, PPC_INST_NOP);
} else {
pr_devel("patching dest %lx\n", (unsigned long)dest);
patch_instruction(dest, insn);
}
pr_devel("patching dest %lx\n", (unsigned long)dest);
patch_instruction(dest, instr);
}
printk(KERN_DEBUG "rfi-fixups: patched %d locations\n", i);
......
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