mirror of
				https://github.com/torvalds/linux.git
				synced 2025-10-31 08:38:45 +02:00 
			
		
		
		
	s390/facilities: move stfl information from lowcore to global data
With gcc-11, there are a lot of warnings because the facility functions are accessing lowcore through a null pointer. Fix this by moving the facility arrays away from lowcore. Signed-off-by: Sven Schnelle <svens@linux.ibm.com> Signed-off-by: Heiko Carstens <hca@linux.ibm.com> Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
This commit is contained in:
		
							parent
							
								
									af9ad82290
								
							
						
					
					
						commit
						17e89e1340
					
				
					 14 changed files with 40 additions and 50 deletions
				
			
		|  | @ -68,7 +68,7 @@ void print_missing_facilities(void) | |||
| 
 | ||||
| 	first = 1; | ||||
| 	for (i = 0; i < ARRAY_SIZE(als); i++) { | ||||
| 		val = ~S390_lowcore.stfle_fac_list[i] & als[i]; | ||||
| 		val = ~stfle_fac_list[i] & als[i]; | ||||
| 		for (j = 0; j < BITS_PER_LONG; j++) { | ||||
| 			if (!(val & (1UL << (BITS_PER_LONG - 1 - j)))) | ||||
| 				continue; | ||||
|  | @ -106,9 +106,9 @@ void verify_facilities(void) | |||
| { | ||||
| 	int i; | ||||
| 
 | ||||
| 	__stfle(S390_lowcore.stfle_fac_list, ARRAY_SIZE(S390_lowcore.stfle_fac_list)); | ||||
| 	__stfle(stfle_fac_list, ARRAY_SIZE(stfle_fac_list)); | ||||
| 	for (i = 0; i < ARRAY_SIZE(als); i++) { | ||||
| 		if ((S390_lowcore.stfle_fac_list[i] & als[i]) != als[i]) | ||||
| 		if ((stfle_fac_list[i] & als[i]) != als[i]) | ||||
| 			facility_mismatch(); | ||||
| 	} | ||||
| } | ||||
|  |  | |||
|  | @ -180,9 +180,9 @@ void setup_boot_command_line(void) | |||
| static void modify_facility(unsigned long nr, bool clear) | ||||
| { | ||||
| 	if (clear) | ||||
| 		__clear_facility(nr, S390_lowcore.stfle_fac_list); | ||||
| 		__clear_facility(nr, stfle_fac_list); | ||||
| 	else | ||||
| 		__set_facility(nr, S390_lowcore.stfle_fac_list); | ||||
| 		__set_facility(nr, stfle_fac_list); | ||||
| } | ||||
| 
 | ||||
| static void check_cleared_facilities(void) | ||||
|  | @ -191,7 +191,7 @@ static void check_cleared_facilities(void) | |||
| 	int i; | ||||
| 
 | ||||
| 	for (i = 0; i < ARRAY_SIZE(als); i++) { | ||||
| 		if ((S390_lowcore.stfle_fac_list[i] & als[i]) != als[i]) { | ||||
| 		if ((stfle_fac_list[i] & als[i]) != als[i]) { | ||||
| 			sclp_early_printk("Warning: The Linux kernel requires facilities cleared via command line option\n"); | ||||
| 			print_missing_facilities(); | ||||
| 			break; | ||||
|  |  | |||
|  | @ -17,6 +17,9 @@ extern char __boot_data_preserved_start[], __boot_data_preserved_end[]; | |||
| unsigned long __bootdata_preserved(__kaslr_offset); | ||||
| unsigned long __bootdata(ident_map_size); | ||||
| 
 | ||||
| u64 __bootdata_preserved(stfle_fac_list[16]); | ||||
| u64 __bootdata_preserved(alt_stfle_fac_list[16]); | ||||
| 
 | ||||
| /*
 | ||||
|  * Some code and data needs to stay below 2 GB, even when the kernel would be | ||||
|  * relocated above 2 GB, because it has to use 31 bit addresses. | ||||
|  |  | |||
|  | @ -13,7 +13,10 @@ | |||
| #include <linux/preempt.h> | ||||
| #include <asm/lowcore.h> | ||||
| 
 | ||||
| #define MAX_FACILITY_BIT (sizeof(((struct lowcore *)0)->stfle_fac_list) * 8) | ||||
| #define MAX_FACILITY_BIT (sizeof(stfle_fac_list) * 8) | ||||
| 
 | ||||
| extern u64 stfle_fac_list[16]; | ||||
| extern u64 alt_stfle_fac_list[16]; | ||||
| 
 | ||||
| static inline void __set_facility(unsigned long nr, void *facilities) | ||||
| { | ||||
|  | @ -56,7 +59,7 @@ static inline int test_facility(unsigned long nr) | |||
| 		if (__test_facility(nr, &facilities_als)) | ||||
| 			return 1; | ||||
| 	} | ||||
| 	return __test_facility(nr, &S390_lowcore.stfle_fac_list); | ||||
| 	return __test_facility(nr, &stfle_fac_list); | ||||
| } | ||||
| 
 | ||||
| static inline unsigned long __stfle_asm(u64 *stfle_fac_list, int size) | ||||
|  | @ -79,13 +82,15 @@ static inline unsigned long __stfle_asm(u64 *stfle_fac_list, int size) | |||
| static inline void __stfle(u64 *stfle_fac_list, int size) | ||||
| { | ||||
| 	unsigned long nr; | ||||
| 	u32 stfl_fac_list; | ||||
| 
 | ||||
| 	asm volatile( | ||||
| 		"	stfl	0(0)\n" | ||||
| 		: "=m" (S390_lowcore.stfl_fac_list)); | ||||
| 	stfl_fac_list = S390_lowcore.stfl_fac_list; | ||||
| 	memcpy(stfle_fac_list, &stfl_fac_list, 4); | ||||
| 	nr = 4; /* bytes stored by stfl */ | ||||
| 	memcpy(stfle_fac_list, &S390_lowcore.stfl_fac_list, 4); | ||||
| 	if (S390_lowcore.stfl_fac_list & 0x01000000) { | ||||
| 	if (stfl_fac_list & 0x01000000) { | ||||
| 		/* More facility bits available with stfle */ | ||||
| 		nr = __stfle_asm(stfle_fac_list, size); | ||||
| 		nr = min_t(unsigned long, (nr + 1) * 8, size * 8); | ||||
|  |  | |||
|  | @ -153,12 +153,7 @@ struct lowcore { | |||
| 	__u64	vmcore_info;			/* 0x0e0c */ | ||||
| 	__u8	pad_0x0e14[0x0e18-0x0e14];	/* 0x0e14 */ | ||||
| 	__u64	os_info;			/* 0x0e18 */ | ||||
| 	__u8	pad_0x0e20[0x0f00-0x0e20];	/* 0x0e20 */ | ||||
| 
 | ||||
| 	/* Extended facility list */ | ||||
| 	__u64	stfle_fac_list[16];		/* 0x0f00 */ | ||||
| 	__u64	alt_stfle_fac_list[16];		/* 0x0f80 */ | ||||
| 	__u8	pad_0x1000[0x11b0-0x1000];	/* 0x1000 */ | ||||
| 	__u8	pad_0x0e20[0x11b0-0x0e20];	/* 0x0e20 */ | ||||
| 
 | ||||
| 	/* Pointer to the machine check extended save area */ | ||||
| 	__u64	mcesad;				/* 0x11b0 */ | ||||
|  |  | |||
|  | @ -76,8 +76,7 @@ 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, | ||||
| 				     S390_lowcore.alt_stfle_fac_list)) | ||||
| 		if (!__test_facility(a->facility, alt_stfle_fac_list)) | ||||
| 			continue; | ||||
| 
 | ||||
| 		if (unlikely(a->instrlen % 2 || a->replacementlen % 2)) { | ||||
|  |  | |||
|  | @ -75,8 +75,6 @@ int main(void) | |||
| 	OFFSET(__LC_SUBCHANNEL_NR, lowcore, subchannel_nr); | ||||
| 	OFFSET(__LC_IO_INT_PARM, lowcore, io_int_parm); | ||||
| 	OFFSET(__LC_IO_INT_WORD, lowcore, io_int_word); | ||||
| 	OFFSET(__LC_STFL_FAC_LIST, lowcore, stfl_fac_list); | ||||
| 	OFFSET(__LC_STFLE_FAC_LIST, lowcore, stfle_fac_list); | ||||
| 	OFFSET(__LC_MCCK_CODE, lowcore, mcck_interruption_code); | ||||
| 	OFFSET(__LC_EXT_DAMAGE_CODE, lowcore, external_damage_code); | ||||
| 	OFFSET(__LC_MCCK_FAIL_STOR_ADDR, lowcore, failing_storage_address); | ||||
|  |  | |||
|  | @ -180,11 +180,9 @@ static noinline __init void setup_lowcore_early(void) | |||
| 
 | ||||
| static noinline __init void setup_facility_list(void) | ||||
| { | ||||
| 	memcpy(S390_lowcore.alt_stfle_fac_list, | ||||
| 	       S390_lowcore.stfle_fac_list, | ||||
| 	       sizeof(S390_lowcore.alt_stfle_fac_list)); | ||||
| 	memcpy(alt_stfle_fac_list, stfle_fac_list, sizeof(alt_stfle_fac_list)); | ||||
| 	if (!IS_ENABLED(CONFIG_KERNEL_NOBP)) | ||||
| 		__clear_facility(82, S390_lowcore.alt_stfle_fac_list); | ||||
| 		__clear_facility(82, alt_stfle_fac_list); | ||||
| } | ||||
| 
 | ||||
| static __init void detect_diag9c(void) | ||||
|  |  | |||
|  | @ -17,11 +17,11 @@ static int __init nobp_setup_early(char *str) | |||
| 		 * The user explicitely requested nobp=1, enable it and | ||||
| 		 * disable the expoline support. | ||||
| 		 */ | ||||
| 		__set_facility(82, S390_lowcore.alt_stfle_fac_list); | ||||
| 		__set_facility(82, alt_stfle_fac_list); | ||||
| 		if (IS_ENABLED(CONFIG_EXPOLINE)) | ||||
| 			nospec_disable = 1; | ||||
| 	} else { | ||||
| 		__clear_facility(82, S390_lowcore.alt_stfle_fac_list); | ||||
| 		__clear_facility(82, alt_stfle_fac_list); | ||||
| 	} | ||||
| 	return 0; | ||||
| } | ||||
|  | @ -29,7 +29,7 @@ early_param("nobp", nobp_setup_early); | |||
| 
 | ||||
| static int __init nospec_setup_early(char *str) | ||||
| { | ||||
| 	__clear_facility(82, S390_lowcore.alt_stfle_fac_list); | ||||
| 	__clear_facility(82, alt_stfle_fac_list); | ||||
| 	return 0; | ||||
| } | ||||
| early_param("nospec", nospec_setup_early); | ||||
|  | @ -40,7 +40,7 @@ static int __init nospec_report(void) | |||
| 		pr_info("Spectre V2 mitigation: etokens\n"); | ||||
| 	if (__is_defined(CC_USING_EXPOLINE) && !nospec_disable) | ||||
| 		pr_info("Spectre V2 mitigation: execute trampolines\n"); | ||||
| 	if (__test_facility(82, S390_lowcore.alt_stfle_fac_list)) | ||||
| 	if (__test_facility(82, alt_stfle_fac_list)) | ||||
| 		pr_info("Spectre V2 mitigation: limited branch prediction\n"); | ||||
| 	return 0; | ||||
| } | ||||
|  | @ -66,14 +66,14 @@ void __init nospec_auto_detect(void) | |||
| 		 */ | ||||
| 		if (__is_defined(CC_USING_EXPOLINE)) | ||||
| 			nospec_disable = 1; | ||||
| 		__clear_facility(82, S390_lowcore.alt_stfle_fac_list); | ||||
| 		__clear_facility(82, alt_stfle_fac_list); | ||||
| 	} else if (__is_defined(CC_USING_EXPOLINE)) { | ||||
| 		/*
 | ||||
| 		 * The kernel has been compiled with expolines. | ||||
| 		 * Keep expolines enabled and disable nobp. | ||||
| 		 */ | ||||
| 		nospec_disable = 0; | ||||
| 		__clear_facility(82, S390_lowcore.alt_stfle_fac_list); | ||||
| 		__clear_facility(82, alt_stfle_fac_list); | ||||
| 	} | ||||
| 	/*
 | ||||
| 	 * If the kernel has not been compiled with expolines the | ||||
|  | @ -86,7 +86,7 @@ static int __init spectre_v2_setup_early(char *str) | |||
| { | ||||
| 	if (str && !strncmp(str, "on", 2)) { | ||||
| 		nospec_disable = 0; | ||||
| 		__clear_facility(82, S390_lowcore.alt_stfle_fac_list); | ||||
| 		__clear_facility(82, alt_stfle_fac_list); | ||||
| 	} | ||||
| 	if (str && !strncmp(str, "off", 3)) | ||||
| 		nospec_disable = 1; | ||||
|  |  | |||
|  | @ -17,7 +17,7 @@ ssize_t cpu_show_spectre_v2(struct device *dev, | |||
| 		return sprintf(buf, "Mitigation: etokens\n"); | ||||
| 	if (__is_defined(CC_USING_EXPOLINE) && !nospec_disable) | ||||
| 		return sprintf(buf, "Mitigation: execute trampolines\n"); | ||||
| 	if (__test_facility(82, S390_lowcore.alt_stfle_fac_list)) | ||||
| 	if (__test_facility(82, alt_stfle_fac_list)) | ||||
| 		return sprintf(buf, "Mitigation: limited branch prediction\n"); | ||||
| 	return sprintf(buf, "Vulnerable\n"); | ||||
| } | ||||
|  |  | |||
|  | @ -103,11 +103,9 @@ EXPORT_SYMBOL(cpu_have_feature); | |||
| static void show_facilities(struct seq_file *m) | ||||
| { | ||||
| 	unsigned int bit; | ||||
| 	long *facilities; | ||||
| 
 | ||||
| 	facilities = (long *)&S390_lowcore.stfle_fac_list; | ||||
| 	seq_puts(m, "facilities      :"); | ||||
| 	for_each_set_bit_inv(bit, facilities, MAX_FACILITY_BIT) | ||||
| 	for_each_set_bit_inv(bit, (long *)&stfle_fac_list, MAX_FACILITY_BIT) | ||||
| 		seq_printf(m, " %d", bit); | ||||
| 	seq_putc(m, '\n'); | ||||
| } | ||||
|  |  | |||
|  | @ -108,6 +108,9 @@ unsigned long __bootdata_preserved(__edma); | |||
| unsigned long __bootdata_preserved(__kaslr_offset); | ||||
| unsigned int __bootdata_preserved(zlib_dfltcc_support); | ||||
| EXPORT_SYMBOL(zlib_dfltcc_support); | ||||
| u64 __bootdata_preserved(stfle_fac_list[16]); | ||||
| EXPORT_SYMBOL(stfle_fac_list); | ||||
| u64 __bootdata_preserved(alt_stfle_fac_list[16]); | ||||
| 
 | ||||
| unsigned long VMALLOC_START; | ||||
| EXPORT_SYMBOL(VMALLOC_START); | ||||
|  | @ -413,11 +416,6 @@ static void __init setup_lowcore_dat_off(void) | |||
| 	lc->lpp = LPP_MAGIC; | ||||
| 	lc->machine_flags = S390_lowcore.machine_flags; | ||||
| 	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, | ||||
| 	       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); | ||||
| 	lc->sys_enter_timer = S390_lowcore.sys_enter_timer; | ||||
| 	lc->exit_timer = S390_lowcore.exit_timer; | ||||
|  |  | |||
|  | @ -275,10 +275,6 @@ static void pcpu_prepare_secondary(struct pcpu *pcpu, int cpu) | |||
| 	lc->cregs_save_area[1] = lc->kernel_asce; | ||||
| 	lc->cregs_save_area[7] = lc->user_asce; | ||||
| 	save_access_regs((unsigned int *) lc->access_regs_save_area); | ||||
| 	memcpy(lc->stfle_fac_list, S390_lowcore.stfle_fac_list, | ||||
| 	       sizeof(lc->stfle_fac_list)); | ||||
| 	memcpy(lc->alt_stfle_fac_list, S390_lowcore.alt_stfle_fac_list, | ||||
| 	       sizeof(lc->alt_stfle_fac_list)); | ||||
| 	arch_spin_lock_setup(cpu); | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -214,7 +214,7 @@ static unsigned long kvm_s390_fac_size(void) | |||
| 	BUILD_BUG_ON(SIZE_INTERNAL > S390_ARCH_FAC_MASK_SIZE_U64); | ||||
| 	BUILD_BUG_ON(SIZE_INTERNAL > S390_ARCH_FAC_LIST_SIZE_U64); | ||||
| 	BUILD_BUG_ON(SIZE_INTERNAL * sizeof(unsigned long) > | ||||
| 		sizeof(S390_lowcore.stfle_fac_list)); | ||||
| 		sizeof(stfle_fac_list)); | ||||
| 
 | ||||
| 	return SIZE_INTERNAL; | ||||
| } | ||||
|  | @ -1458,8 +1458,8 @@ static int kvm_s390_get_machine(struct kvm *kvm, struct kvm_device_attr *attr) | |||
| 	mach->ibc = sclp.ibc; | ||||
| 	memcpy(&mach->fac_mask, kvm->arch.model.fac_mask, | ||||
| 	       S390_ARCH_FAC_LIST_SIZE_BYTE); | ||||
| 	memcpy((unsigned long *)&mach->fac_list, S390_lowcore.stfle_fac_list, | ||||
| 	       sizeof(S390_lowcore.stfle_fac_list)); | ||||
| 	memcpy((unsigned long *)&mach->fac_list, stfle_fac_list, | ||||
| 	       sizeof(stfle_fac_list)); | ||||
| 	VM_EVENT(kvm, 3, "GET: host ibc:  0x%4.4x, host cpuid:  0x%16.16llx", | ||||
| 		 kvm->arch.model.ibc, | ||||
| 		 kvm->arch.model.cpuid); | ||||
|  | @ -2683,10 +2683,10 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type) | |||
| 	kvm->arch.model.fac_list = kvm->arch.sie_page2->fac_list; | ||||
| 
 | ||||
| 	for (i = 0; i < kvm_s390_fac_size(); i++) { | ||||
| 		kvm->arch.model.fac_mask[i] = S390_lowcore.stfle_fac_list[i] & | ||||
| 		kvm->arch.model.fac_mask[i] = stfle_fac_list[i] & | ||||
| 					      (kvm_s390_fac_base[i] | | ||||
| 					       kvm_s390_fac_ext[i]); | ||||
| 		kvm->arch.model.fac_list[i] = S390_lowcore.stfle_fac_list[i] & | ||||
| 		kvm->arch.model.fac_list[i] = stfle_fac_list[i] & | ||||
| 					      kvm_s390_fac_base[i]; | ||||
| 	} | ||||
| 	kvm->arch.model.subfuncs = kvm_s390_available_subfunc; | ||||
|  | @ -5055,7 +5055,7 @@ static int __init kvm_s390_init(void) | |||
| 
 | ||||
| 	for (i = 0; i < 16; i++) | ||||
| 		kvm_s390_fac_base[i] |= | ||||
| 			S390_lowcore.stfle_fac_list[i] & nonhyp_mask(i); | ||||
| 			stfle_fac_list[i] & nonhyp_mask(i); | ||||
| 
 | ||||
| 	return kvm_init(NULL, sizeof(struct kvm_vcpu), 0, THIS_MODULE); | ||||
| } | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue
	
	 Sven Schnelle
						Sven Schnelle