Commit 47837a5c authored by Heiko Carstens's avatar Heiko Carstens Committed by Vasily Gorbik
Browse files

s390/nospec: Push down alternative handling



The nospec implementation is deeply integrated into the alternatives
code: only for nospec an alternative facility list is implemented and
used by the alternative code, while it is modified by nospec specific
needs.

Push down the nospec alternative handling into the nospec by
introducing a new alternative type and a specific nospec callback to
decide if alternatives should be applied.

Also introduce a new global nobp variable which together with facility
82 can be used to decide if nobp is enabled or not.

Acked-by: default avatarAlexander Gordeev <agordeev@linux.ibm.com>
Tested-by: default avatarSven Schnelle <svens@linux.ibm.com>
Signed-off-by: default avatarHeiko Carstens <hca@linux.ibm.com>
Signed-off-by: default avatarVasily Gorbik <gor@linux.ibm.com>
parent 7f9d8599
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -33,6 +33,7 @@

#define ALT_TYPE_FACILITY_EARLY	0
#define ALT_TYPE_FACILITY	1
#define ALT_TYPE_SPEC		2

#define ALT_DATA_SHIFT		0
#define ALT_TYPE_SHIFT		20
@@ -46,6 +47,10 @@
					 ALT_TYPE_FACILITY << ALT_TYPE_SHIFT	| \
					 (facility) << ALT_DATA_SHIFT)

#define ALT_SPEC(facility)		(ALT_CTX_LATE << ALT_CTX_SHIFT		| \
					 ALT_TYPE_SPEC << ALT_TYPE_SHIFT	| \
					 (facility) << ALT_DATA_SHIFT)

#ifndef __ASSEMBLY__

#include <linux/types.h>
+9 −0
Original line number Diff line number Diff line
@@ -5,8 +5,17 @@
#ifndef __ASSEMBLY__

#include <linux/types.h>
#include <asm/facility.h>

extern int nospec_disable;
extern int nobp;

static inline bool nobp_enabled(void)
{
	if (__is_defined(__DECOMPRESSOR))
		return false;
	return nobp && test_facility(82);
}

void nospec_init_branches(void);
void nospec_auto_detect(void);
+1 −1
Original line number Diff line number Diff line
@@ -419,7 +419,7 @@ static __always_inline bool regs_irqs_disabled(struct pt_regs *regs)

static __always_inline void bpon(void)
{
	asm volatile(ALTERNATIVE("nop", ".insn	rrf,0xb2e80000,0,0,13,0", ALT_FACILITY(82)));
	asm volatile(ALTERNATIVE("nop", ".insn	rrf,0xb2e80000,0,0,13,0", ALT_SPEC(82)));
}

#endif /* __ASSEMBLY__ */
+4 −0
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0

#include <linux/uaccess.h>
#include <asm/nospec-branch.h>
#include <asm/alternative.h>
#include <asm/facility.h>

@@ -26,6 +27,9 @@ void __apply_alternatives(struct alt_instr *start, struct alt_instr *end, unsign
			replace = __test_facility(a->data, alt_stfle_fac_list);
			break;
#endif
		case ALT_TYPE_SPEC:
			replace = nobp_enabled();
			break;
		default:
			replace = false;
		}
+0 −2
Original line number Diff line number Diff line
@@ -193,8 +193,6 @@ static noinline __init void setup_lowcore_early(void)
static noinline __init void setup_facility_list(void)
{
	memcpy(alt_stfle_fac_list, stfle_fac_list, sizeof(alt_stfle_fac_list));
	if (!IS_ENABLED(CONFIG_KERNEL_NOBP))
		__clear_facility(82, alt_stfle_fac_list);
}

static __init void detect_diag9c(void)
Loading