OSDN Git Service

s390/kasan: support preemptible kernel build
authorVasily Gorbik <gor@linux.ibm.com>
Fri, 19 Oct 2018 10:13:58 +0000 (12:13 +0200)
committerMartin Schwidefsky <schwidefsky@de.ibm.com>
Mon, 22 Oct 2018 06:37:45 +0000 (08:37 +0200)
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 <bblock@linux.ibm.com>
Acked-by: Heiko Carstens <heiko.carstens@de.ibm.com>
Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
arch/s390/include/asm/facility.h
arch/s390/mm/kasan_init.c

index 99c8ce3..e78cda9 100644 (file)
@@ -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();
 }
 
index 5598214..acb9645 100644 (file)
@@ -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);