mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2025-01-07 21:53:44 +00: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
@ -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 New Issue
Block a user