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

Commit 6e179d64 authored by Martin Schwidefsky's avatar Martin Schwidefsky
Browse files

s390: add automatic detection of the spectre defense



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>
parent b2e2f43a
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -576,7 +576,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
@@ -81,7 +81,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
@@ -2,6 +2,7 @@
#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
@@ -159,7 +159,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;
	}
@@ -318,8 +318,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 +
@@ -440,7 +439,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 +
@@ -467,11 +466,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