Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 719b84c9 authored by Martin Schwidefsky's avatar Martin Schwidefsky Committed by Greg Kroah-Hartman
Browse files

s390: add automatic detection of the spectre defense



[ Upstream commit 6e179d64 ]

Automatically decide between nobp vs. expolines if the spectre_v2=auto
kernel parameter is specified or CONFIG_EXPOLINE_AUTO=y is set.

The decision made at boot time due to CONFIG_EXPOLINE_AUTO=y being set
can be overruled with the nobp, nospec and spectre_v2 kernel parameters.

Signed-off-by: default avatarMartin Schwidefsky <schwidefsky@de.ibm.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent ea1bbd53
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -575,7 +575,7 @@ choice
config EXPOLINE_OFF
	bool "spectre_v2=off"

config EXPOLINE_MEDIUM
config EXPOLINE_AUTO
	bool "spectre_v2=auto"

config EXPOLINE_FULL
+1 −1
Original line number Diff line number Diff line
@@ -87,7 +87,7 @@ ifdef CONFIG_EXPOLINE
    CC_FLAGS_EXPOLINE += -mfunction-return=thunk
    CC_FLAGS_EXPOLINE += -mindirect-branch-table
    export CC_FLAGS_EXPOLINE
    cflags-y += $(CC_FLAGS_EXPOLINE)
    cflags-y += $(CC_FLAGS_EXPOLINE) -DCC_USING_EXPOLINE
  endif
endif

+2 −4
Original line number Diff line number Diff line
@@ -6,12 +6,10 @@

#include <linux/types.h>

extern int nospec_call_disable;
extern int nospec_return_disable;
extern int nospec_disable;

void nospec_init_branches(void);
void nospec_call_revert(s32 *start, s32 *end);
void nospec_return_revert(s32 *start, s32 *end);
void nospec_revert(s32 *start, s32 *end);

#endif /* __ASSEMBLY__ */

+1 −0
Original line number Diff line number Diff line
#include <linux/module.h>
#include <asm/alternative.h>
#include <asm/facility.h>
#include <asm/nospec-branch.h>

#define MAX_PATCH_LEN (255 - 1)

+5 −6
Original line number Diff line number Diff line
@@ -172,7 +172,7 @@ int module_frob_arch_sections(Elf_Ehdr *hdr, Elf_Shdr *sechdrs,
	me->core_layout.size += me->arch.got_size;
	me->arch.plt_offset = me->core_layout.size;
	if (me->arch.plt_size) {
		if (IS_ENABLED(CONFIG_EXPOLINE) && !nospec_call_disable)
		if (IS_ENABLED(CONFIG_EXPOLINE) && !nospec_disable)
			me->arch.plt_size += PLT_ENTRY_SIZE;
		me->core_layout.size += me->arch.plt_size;
	}
@@ -331,8 +331,7 @@ static int apply_rela(Elf_Rela *rela, Elf_Addr base, Elf_Sym *symtab,
				info->plt_offset;
			ip[0] = 0x0d10e310;	/* basr 1,0  */
			ip[1] = 0x100a0004;	/* lg	1,10(1) */
			if (IS_ENABLED(CONFIG_EXPOLINE) &&
			    !nospec_call_disable) {
			if (IS_ENABLED(CONFIG_EXPOLINE) && !nospec_disable) {
				unsigned int *ij;
				ij = me->core_layout.base +
					me->arch.plt_offset +
@@ -453,7 +452,7 @@ int module_finalize(const Elf_Ehdr *hdr,
	void *aseg;

	if (IS_ENABLED(CONFIG_EXPOLINE) &&
	    !nospec_call_disable && me->arch.plt_size) {
	    !nospec_disable && me->arch.plt_size) {
		unsigned int *ij;

		ij = me->core_layout.base + me->arch.plt_offset +
@@ -480,11 +479,11 @@ int module_finalize(const Elf_Ehdr *hdr,

		if (IS_ENABLED(CONFIG_EXPOLINE) &&
		    (!strcmp(".nospec_call_table", secname)))
			nospec_call_revert(aseg, aseg + s->sh_size);
			nospec_revert(aseg, aseg + s->sh_size);

		if (IS_ENABLED(CONFIG_EXPOLINE) &&
		    (!strcmp(".nospec_return_table", secname)))
			nospec_return_revert(aseg, aseg + s->sh_size);
			nospec_revert(aseg, aseg + s->sh_size);
	}

	jump_label_apply_nops(me);
Loading