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

Commit cf148998 authored by Martin Schwidefsky's avatar Martin Schwidefsky
Browse files

s390/alternative: use a copy of the facility bit mask



To be able to switch off specific CPU alternatives with kernel parameters
make a copy of the facility bit mask provided by STFLE and use the copy
for the decision to apply an alternative.

Reviewed-by: default avatarDavid Hildenbrand <david@redhat.com>
Reviewed-by: default avatarCornelia Huck <cohuck@redhat.com>
Signed-off-by: default avatarMartin Schwidefsky <schwidefsky@de.ibm.com>
parent e2dd8333
Loading
Loading
Loading
Loading
+18 −0
Original line number Diff line number Diff line
@@ -15,6 +15,24 @@

#define MAX_FACILITY_BIT (sizeof(((struct lowcore *)0)->stfle_fac_list) * 8)

static inline void __set_facility(unsigned long nr, void *facilities)
{
	unsigned char *ptr = (unsigned char *) facilities;

	if (nr >= MAX_FACILITY_BIT)
		return;
	ptr[nr >> 3] |= 0x80 >> (nr & 7);
}

static inline void __clear_facility(unsigned long nr, void *facilities)
{
	unsigned char *ptr = (unsigned char *) facilities;

	if (nr >= MAX_FACILITY_BIT)
		return;
	ptr[nr >> 3] &= ~(0x80 >> (nr & 7));
}

static inline int __test_facility(unsigned long nr, void *facilities)
{
	unsigned char *ptr;
+2 −1
Original line number Diff line number Diff line
@@ -151,7 +151,8 @@ struct lowcore {
	__u8	pad_0x0e20[0x0f00-0x0e20];	/* 0x0e20 */

	/* Extended facility list */
	__u64	stfle_fac_list[32];		/* 0x0f00 */
	__u64	stfle_fac_list[16];		/* 0x0f00 */
	__u64	alt_stfle_fac_list[16];		/* 0x0f80 */
	__u8	pad_0x1000[0x11b0-0x1000];	/* 0x1000 */

	/* Pointer to the machine check extended save area */
+2 −1
Original line number Diff line number Diff line
@@ -75,7 +75,8 @@ static void __init_or_module __apply_alternatives(struct alt_instr *start,
		instr = (u8 *)&a->instr_offset + a->instr_offset;
		replacement = (u8 *)&a->repl_offset + a->repl_offset;

		if (!test_facility(a->facility))
		if (!__test_facility(a->facility,
				     S390_lowcore.alt_stfle_fac_list))
			continue;

		if (unlikely(a->instrlen % 2 || a->replacementlen % 2)) {
+3 −0
Original line number Diff line number Diff line
@@ -193,6 +193,9 @@ static noinline __init void setup_facility_list(void)
{
	stfle(S390_lowcore.stfle_fac_list,
	      ARRAY_SIZE(S390_lowcore.stfle_fac_list));
	memcpy(S390_lowcore.alt_stfle_fac_list,
	       S390_lowcore.stfle_fac_list,
	       sizeof(S390_lowcore.alt_stfle_fac_list));
}

static __init void detect_diag9c(void)
+3 −1
Original line number Diff line number Diff line
@@ -340,7 +340,9 @@ static void __init setup_lowcore(void)
	lc->preempt_count = S390_lowcore.preempt_count;
	lc->stfl_fac_list = S390_lowcore.stfl_fac_list;
	memcpy(lc->stfle_fac_list, S390_lowcore.stfle_fac_list,
	       MAX_FACILITY_BIT/8);
	       sizeof(lc->stfle_fac_list));
	memcpy(lc->alt_stfle_fac_list, S390_lowcore.alt_stfle_fac_list,
	       sizeof(lc->alt_stfle_fac_list));
	nmi_alloc_boot_cpu(lc);
	vdso_alloc_boot_cpu(lc);
	lc->sync_enter_timer = S390_lowcore.sync_enter_timer;
Loading