lkml.org 
[lkml]   [2018]   [Mar]   [15]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
From
Subject[PATCH RFC rebase 6/9] powerpc/64: Patch barrier_nospec in modules
Date
Note that unlike RFI which is patched only in kernel the nospec state
reflects settings at the time the module was loaded.

Iterating all modules and re-patching every time the settings change is
not implemented.

Based on lwsync patching.

Signed-off-by: Michal Suchanek <msuchanek@suse.de>
---
arch/powerpc/include/asm/setup.h | 5 ++++-
arch/powerpc/kernel/module.c | 6 ++++++
arch/powerpc/kernel/setup_64.c | 4 ++--
arch/powerpc/lib/feature-fixups.c | 17 ++++++++++++++---
4 files changed, 26 insertions(+), 6 deletions(-)

diff --git a/arch/powerpc/include/asm/setup.h b/arch/powerpc/include/asm/setup.h
index c7e9e66c2a38..92520d2483b8 100644
--- a/arch/powerpc/include/asm/setup.h
+++ b/arch/powerpc/include/asm/setup.h
@@ -58,7 +58,10 @@ enum spec_barrier_type {
void setup_rfi_flush(enum l1d_flush_type, bool enable);
void do_rfi_flush_fixups(enum l1d_flush_type types);
void setup_barrier_nospec(enum spec_barrier_type, bool enable);
-void do_barrier_nospec_fixups(enum spec_barrier_type type);
+void do_barrier_nospec_fixups_kernel(enum spec_barrier_type type);
+void do_barrier_nospec_fixups(enum spec_barrier_type type,
+ void *start, void *end);
+extern enum spec_barrier_type powerpc_barrier_nospec;

#endif /* !__ASSEMBLY__ */

diff --git a/arch/powerpc/kernel/module.c b/arch/powerpc/kernel/module.c
index 3f7ba0f5bf29..7b6d0ec06a21 100644
--- a/arch/powerpc/kernel/module.c
+++ b/arch/powerpc/kernel/module.c
@@ -72,6 +72,12 @@ int module_finalize(const Elf_Ehdr *hdr,
do_feature_fixups(powerpc_firmware_features,
(void *)sect->sh_addr,
(void *)sect->sh_addr + sect->sh_size);
+
+ sect = find_section(hdr, sechdrs, "__spec_barrier_fixup");
+ if (sect != NULL)
+ do_barrier_nospec_fixups(powerpc_barrier_nospec,
+ (void *)sect->sh_addr,
+ (void *)sect->sh_addr + sect->sh_size);
#endif

sect = find_section(hdr, sechdrs, "__lwsync_fixup");
diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c
index 767240074cad..f60e0e3b5ad2 100644
--- a/arch/powerpc/kernel/setup_64.c
+++ b/arch/powerpc/kernel/setup_64.c
@@ -910,11 +910,11 @@ void barrier_nospec_enable(bool enable)

if (enable) {
powerpc_barrier_nospec = barrier_nospec_type;
- do_barrier_nospec_fixups(powerpc_barrier_nospec);
+ do_barrier_nospec_fixups_kernel(powerpc_barrier_nospec);
on_each_cpu(do_nothing, NULL, 1);
} else {
powerpc_barrier_nospec = SPEC_BARRIER_NONE;
- do_barrier_nospec_fixups(powerpc_barrier_nospec);
+ do_barrier_nospec_fixups_kernel(powerpc_barrier_nospec);
}
}

diff --git a/arch/powerpc/lib/feature-fixups.c b/arch/powerpc/lib/feature-fixups.c
index dfeb7feeccef..a529ac6b2a5d 100644
--- a/arch/powerpc/lib/feature-fixups.c
+++ b/arch/powerpc/lib/feature-fixups.c
@@ -160,14 +160,15 @@ void do_rfi_flush_fixups(enum l1d_flush_type types)
: "unknown");
}

-void do_barrier_nospec_fixups(enum spec_barrier_type type)
+void do_barrier_nospec_fixups(enum spec_barrier_type type,
+ void *fixup_start, void *fixup_end)
{
unsigned int instr, *dest;
long *start, *end;
int i;

- start = PTRRELOC(&__start___spec_barrier_fixup),
- end = PTRRELOC(&__stop___spec_barrier_fixup);
+ start = fixup_start;
+ end = fixup_end;

instr = 0x60000000; /* nop */

@@ -186,6 +187,16 @@ void do_barrier_nospec_fixups(enum spec_barrier_type type)
printk(KERN_DEBUG "barrier-nospec: patched %d locations\n", i);
}

+void do_barrier_nospec_fixups_kernel(enum spec_barrier_type type)
+{
+ void *start, *end;
+
+ start = PTRRELOC(&__start___spec_barrier_fixup),
+ end = PTRRELOC(&__stop___spec_barrier_fixup);
+
+ do_barrier_nospec_fixups(type, start, end);
+}
+
#endif /* CONFIG_PPC_BOOK3S_64 */

void do_lwsync_fixups(unsigned long value, void *fixup_start, void *fixup_end)
--
2.13.6
\
 
 \ /
  Last update: 2018-03-15 20:17    [W:0.140 / U:6.268 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site