From cf3dbe5dacb3a95d497ace9c714306d17cb05b11 Mon Sep 17 00:00:00 2001 From: Vasily Gorbik Date: Fri, 19 Oct 2018 12:13:58 +0200 Subject: [PATCH] s390/kasan: support preemptible kernel build When the kernel is built with: CONFIG_PREEMPT=y CONFIG_PREEMPT_COUNT=y "stfle" function used by kasan initialization code makes additional call to preempt_count_add/preempt_count_sub. To avoid removing kasan instrumentation from sched code where those functions leave split stfle function and provide __stfle variant without preemption handling to be used by Kasan. Reported-by: Benjamin Block Acked-by: Heiko Carstens Signed-off-by: Vasily Gorbik Signed-off-by: Martin Schwidefsky --- arch/s390/include/asm/facility.h | 9 +++++++-- arch/s390/mm/kasan_init.c | 4 ++-- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/arch/s390/include/asm/facility.h b/arch/s390/include/asm/facility.h index 99c8ce30b3cd..e78cda94456b 100644 --- a/arch/s390/include/asm/facility.h +++ b/arch/s390/include/asm/facility.h @@ -64,11 +64,10 @@ static inline int test_facility(unsigned long nr) * @stfle_fac_list: array where facility list can be stored * @size: size of passed in array in double words */ -static inline void stfle(u64 *stfle_fac_list, int size) +static inline void __stfle(u64 *stfle_fac_list, int size) { unsigned long nr; - preempt_disable(); asm volatile( " stfl 0(0)\n" : "=m" (S390_lowcore.stfl_fac_list)); @@ -85,6 +84,12 @@ static inline void stfle(u64 *stfle_fac_list, int size) nr = (reg0 + 1) * 8; /* # bytes stored by stfle */ } memset((char *) stfle_fac_list + nr, 0, size * 8 - nr); +} + +static inline void stfle(u64 *stfle_fac_list, int size) +{ + preempt_disable(); + __stfle(stfle_fac_list, size); preempt_enable(); } diff --git a/arch/s390/mm/kasan_init.c b/arch/s390/mm/kasan_init.c index 55982142b2b5..acb9645b762b 100644 --- a/arch/s390/mm/kasan_init.c +++ b/arch/s390/mm/kasan_init.c @@ -222,8 +222,8 @@ static void __init kasan_enable_dat(void) static void __init kasan_early_detect_facilities(void) { - stfle(S390_lowcore.stfle_fac_list, - ARRAY_SIZE(S390_lowcore.stfle_fac_list)); + __stfle(S390_lowcore.stfle_fac_list, + ARRAY_SIZE(S390_lowcore.stfle_fac_list)); if (test_facility(8)) { has_edat = true; __ctl_set_bit(0, 23);