From 4784955a5270f30c569fa95899979fd1805caf6c Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Mon, 2 Sep 2013 13:08:25 +0200 Subject: s390/bpf,jit: fix address randomization Add misssing braces to hole calculation. This resulted in an addition instead of an substraction. Which in turn means that the jit compiler could try to write out of bounds of the allocated piece of memory. This bug was introduced with aa2d2c73 "s390/bpf,jit: address randomize and write protect jit code". Fixes this one: [ 37.320956] Unable to handle kernel pointer dereference at virtual kernel address 000003ff80231000 [ 37.320984] Oops: 0011 [#1] PREEMPT SMP DEBUG_PAGEALLOC [ 37.320993] Modules linked in: dm_multipath scsi_dh eadm_sch dm_mod ctcm fsm autofs4 [ 37.321007] CPU: 28 PID: 6443 Comm: multipathd Not tainted 3.10.9-61.x.20130829-s390xdefault #1 [ 37.321011] task: 0000004ada778000 ti: 0000004ae3304000 task.ti: 0000004ae3304000 [ 37.321014] Krnl PSW : 0704c00180000000 000000000012d1de (bpf_jit_compile+0x198e/0x23d0) [ 37.321022] R:0 T:1 IO:1 EX:1 Key:0 M:1 W:0 P:0 AS:3 CC:0 PM:0 EA:3 Krnl GPRS: 000000004350207d 0000004a00000001 0000000000000007 000003ff80231002 [ 37.321029] 0000000000000007 000003ff80230ffe 00000000a7740000 000003ff80230f76 [ 37.321032] 000003ffffffffff 000003ff00000000 000003ff0000007d 000000000071e820 [ 37.321035] 0000004adbe99950 000000000071ea18 0000004af3d9e7c0 0000004ae3307b80 [ 37.321046] Krnl Code: 000000000012d1d0: 41305004 la %r3,4(%r5) 000000000012d1d4: e330f0f80021 clg %r3,248(%r15) #000000000012d1da: a7240009 brc 2,12d1ec >000000000012d1de: 50805000 st %r8,0(%r5) 000000000012d1e2: e330f0f00004 lg %r3,240(%r15) 000000000012d1e8: 41303004 la %r3,4(%r3) 000000000012d1ec: e380f0e00004 lg %r8,224(%r15) 000000000012d1f2: e330f0f00024 stg %r3,240(%r15) [ 37.321074] Call Trace: [ 37.321077] ([<000000000012da78>] bpf_jit_compile+0x2228/0x23d0) [ 37.321083] [<00000000006007c2>] sk_attach_filter+0xfe/0x214 [ 37.321090] [<00000000005d2d92>] sock_setsockopt+0x926/0xbdc [ 37.321097] [<00000000005cbfb6>] SyS_setsockopt+0x8a/0xe8 [ 37.321101] [<00000000005ccaa8>] SyS_socketcall+0x264/0x364 [ 37.321106] [<0000000000713f1c>] sysc_nr_ok+0x22/0x28 [ 37.321113] [<000003fffce10ea8>] 0x3fffce10ea8 [ 37.321118] INFO: lockdep is turned off. [ 37.321121] Last Breaking-Event-Address: [ 37.321124] [<000000000012d192>] bpf_jit_compile+0x1942/0x23d0 [ 37.321132] [ 37.321135] Kernel panic - not syncing: Fatal exception: panic_on_oops Cc: stable@vger.kernel.org # v3.11 Signed-off-by: Heiko Carstens --- arch/s390/net/bpf_jit_comp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch/s390') diff --git a/arch/s390/net/bpf_jit_comp.c b/arch/s390/net/bpf_jit_comp.c index d5f10a43a58..70923928586 100644 --- a/arch/s390/net/bpf_jit_comp.c +++ b/arch/s390/net/bpf_jit_comp.c @@ -805,7 +805,7 @@ static struct bpf_binary_header *bpf_alloc_binary(unsigned int bpfsize, return NULL; memset(header, 0, sz); header->pages = sz / PAGE_SIZE; - hole = sz - bpfsize + sizeof(*header); + hole = sz - (bpfsize + sizeof(*header)); /* Insert random number of illegal instructions before BPF code * and make sure the first instruction starts at an even address. */ -- cgit v1.2.3-70-g09d2 From 3b459c542193189f4165e86881f0ecf09f527bcf Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Wed, 4 Sep 2013 14:13:18 +0200 Subject: s390: update defconfig Signed-off-by: Heiko Carstens --- arch/s390/defconfig | 39 +++++++++++++++++++++++++++------------ 1 file changed, 27 insertions(+), 12 deletions(-) (limited to 'arch/s390') diff --git a/arch/s390/defconfig b/arch/s390/defconfig index b74400e3e03..d204c65bf72 100644 --- a/arch/s390/defconfig +++ b/arch/s390/defconfig @@ -1,14 +1,13 @@ -CONFIG_EXPERIMENTAL=y CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y CONFIG_FHANDLE=y +CONFIG_AUDIT=y +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y CONFIG_TASKSTATS=y CONFIG_TASK_DELAY_ACCT=y CONFIG_TASK_XACCT=y CONFIG_TASK_IO_ACCOUNTING=y -CONFIG_AUDIT=y -CONFIG_NO_HZ=y -CONFIG_HIGH_RES_TIMERS=y CONFIG_RCU_FAST_NO_HZ=y CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y @@ -27,6 +26,7 @@ CONFIG_RD_BZIP2=y CONFIG_RD_LZMA=y CONFIG_RD_XZ=y CONFIG_RD_LZO=y +CONFIG_RD_LZ4=y CONFIG_EXPERT=y # CONFIG_COMPAT_BRK is not set CONFIG_PROFILING=y @@ -38,11 +38,13 @@ CONFIG_MODULE_UNLOAD=y CONFIG_MODVERSIONS=y CONFIG_PARTITION_ADVANCED=y CONFIG_IBM_PARTITION=y +# CONFIG_EFI_PARTITION is not set CONFIG_DEFAULT_DEADLINE=y CONFIG_HZ_100=y CONFIG_MEMORY_HOTPLUG=y CONFIG_MEMORY_HOTREMOVE=y CONFIG_KSM=y +CONFIG_TRANSPARENT_HUGEPAGE=y CONFIG_CRASH_DUMP=y CONFIG_BINFMT_MISC=m CONFIG_HIBERNATION=y @@ -92,40 +94,49 @@ CONFIG_SCSI_CONSTANTS=y CONFIG_SCSI_LOGGING=y CONFIG_SCSI_SCAN_ASYNC=y CONFIG_ZFCP=y +CONFIG_SCSI_VIRTIO=y CONFIG_NETDEVICES=y CONFIG_BONDING=m CONFIG_DUMMY=m CONFIG_EQUALIZER=m CONFIG_TUN=m CONFIG_VIRTIO_NET=y +# CONFIG_INPUT is not set +# CONFIG_SERIO is not set CONFIG_RAW_DRIVER=m CONFIG_VIRTIO_BALLOON=y -CONFIG_EXT2_FS=y -CONFIG_EXT3_FS=y -# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set CONFIG_EXT4_FS=y CONFIG_EXT4_FS_POSIX_ACL=y CONFIG_EXT4_FS_SECURITY=y +CONFIG_XFS_FS=y +CONFIG_XFS_QUOTA=y +CONFIG_XFS_POSIX_ACL=y +CONFIG_XFS_RT=y +CONFIG_BTRFS_FS=y +CONFIG_BTRFS_FS_POSIX_ACL=y +CONFIG_FANOTIFY=y +CONFIG_FUSE_FS=y CONFIG_PROC_KCORE=y CONFIG_TMPFS=y CONFIG_TMPFS_POSIX_ACL=y +CONFIG_HUGETLBFS=y # CONFIG_NETWORK_FILESYSTEMS is not set +CONFIG_DEBUG_FORCE_WEAK_PER_CPU=y CONFIG_MAGIC_SYSRQ=y +CONFIG_DEBUG_PAGEALLOC=y CONFIG_TIMER_STATS=y CONFIG_PROVE_LOCKING=y -CONFIG_PROVE_RCU=y CONFIG_LOCK_STAT=y CONFIG_DEBUG_LOCKDEP=y CONFIG_DEBUG_LIST=y CONFIG_DEBUG_NOTIFIERS=y +CONFIG_PROVE_RCU=y +CONFIG_RCU_CPU_STALL_TIMEOUT=60 CONFIG_RCU_TRACE=y -CONFIG_KPROBES_SANITY_TEST=y -CONFIG_DEBUG_FORCE_WEAK_PER_CPU=y CONFIG_LATENCYTOP=y -CONFIG_DEBUG_PAGEALLOC=y CONFIG_BLK_DEV_IO_TRACE=y +CONFIG_KPROBES_SANITY_TEST=y # CONFIG_STRICT_DEVMEM is not set -CONFIG_CRYPTO_NULL=m CONFIG_CRYPTO_CRYPTD=m CONFIG_CRYPTO_AUTHENC=m CONFIG_CRYPTO_TEST=m @@ -137,8 +148,10 @@ CONFIG_CRYPTO_ECB=m CONFIG_CRYPTO_LRW=m CONFIG_CRYPTO_PCBC=m CONFIG_CRYPTO_XTS=m +CONFIG_CRYPTO_CMAC=m CONFIG_CRYPTO_XCBC=m CONFIG_CRYPTO_VMAC=m +CONFIG_CRYPTO_CRC32=m CONFIG_CRYPTO_MD4=m CONFIG_CRYPTO_MICHAEL_MIC=m CONFIG_CRYPTO_RMD128=m @@ -165,6 +178,8 @@ CONFIG_CRYPTO_TWOFISH=m CONFIG_CRYPTO_DEFLATE=m CONFIG_CRYPTO_ZLIB=m CONFIG_CRYPTO_LZO=m +CONFIG_CRYPTO_LZ4=m +CONFIG_CRYPTO_LZ4HC=m CONFIG_ZCRYPT=m CONFIG_CRYPTO_SHA1_S390=m CONFIG_CRYPTO_SHA256_S390=m -- cgit v1.2.3-70-g09d2 From ae6834c1e4bdfede56eee815595a19c690fddcae Mon Sep 17 00:00:00 2001 From: Hendrik Brueckner Date: Mon, 2 Sep 2013 09:48:48 +0200 Subject: s390/perf: Remove print_hex_dump_bytes() debug output Signed-off-by: Hendrik Brueckner Signed-off-by: Heiko Carstens --- arch/s390/kernel/perf_event.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'arch/s390') diff --git a/arch/s390/kernel/perf_event.c b/arch/s390/kernel/perf_event.c index 500aa1029bc..2343c218b8f 100644 --- a/arch/s390/kernel/perf_event.c +++ b/arch/s390/kernel/perf_event.c @@ -105,13 +105,10 @@ void perf_event_print_debug(void) cpu = smp_processor_id(); memset(&cf_info, 0, sizeof(cf_info)); - if (!qctri(&cf_info)) { + if (!qctri(&cf_info)) pr_info("CPU[%i] CPUM_CF: ver=%u.%u A=%04x E=%04x C=%04x\n", cpu, cf_info.cfvn, cf_info.csvn, cf_info.auth_ctl, cf_info.enable_ctl, cf_info.act_ctl); - print_hex_dump_bytes("CPUMF Query: ", DUMP_PREFIX_OFFSET, - &cf_info, sizeof(cf_info)); - } local_irq_restore(flags); } -- cgit v1.2.3-70-g09d2 From 8237ac3c4c827a187538fab1ca370e34addc922d Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Mon, 2 Sep 2013 11:20:00 +0200 Subject: s390/dumpstack: convert print_symbol to %pSR This is the same as what other architectures did. The change has also the advantage that there won't be any interleaving messages between printk() and print_symbol(). Signed-off-by: Heiko Carstens --- arch/s390/kernel/dumpstack.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'arch/s390') diff --git a/arch/s390/kernel/dumpstack.c b/arch/s390/kernel/dumpstack.c index 87acc38f73c..99e7f603589 100644 --- a/arch/s390/kernel/dumpstack.c +++ b/arch/s390/kernel/dumpstack.c @@ -40,14 +40,15 @@ __show_trace(unsigned long sp, unsigned long low, unsigned long high) { struct stack_frame *sf; struct pt_regs *regs; + unsigned long addr; while (1) { sp = sp & PSW_ADDR_INSN; if (sp < low || sp > high - sizeof(*sf)) return sp; sf = (struct stack_frame *) sp; - printk("([<%016lx>] ", sf->gprs[8] & PSW_ADDR_INSN); - print_symbol("%s)\n", sf->gprs[8] & PSW_ADDR_INSN); + addr = sf->gprs[8] & PSW_ADDR_INSN; + printk("([<%016lx>] %pSR)\n", addr, (void *)addr); /* Follow the backchain. */ while (1) { low = sp; @@ -57,16 +58,16 @@ __show_trace(unsigned long sp, unsigned long low, unsigned long high) if (sp <= low || sp > high - sizeof(*sf)) return sp; sf = (struct stack_frame *) sp; - printk(" [<%016lx>] ", sf->gprs[8] & PSW_ADDR_INSN); - print_symbol("%s\n", sf->gprs[8] & PSW_ADDR_INSN); + addr = sf->gprs[8] & PSW_ADDR_INSN; + printk(" [<%016lx>] %pSR\n", addr, (void *)addr); } /* Zero backchain detected, check for interrupt frame. */ sp = (unsigned long) (sf + 1); if (sp <= low || sp > high - sizeof(*regs)) return sp; regs = (struct pt_regs *) sp; - printk(" [<%016lx>] ", regs->psw.addr & PSW_ADDR_INSN); - print_symbol("%s\n", regs->psw.addr & PSW_ADDR_INSN); + addr = regs->psw.addr & PSW_ADDR_INSN; + printk(" [<%016lx>] %pSR\n", addr, (void *)addr); low = sp; sp = regs->gprs[15]; } @@ -128,8 +129,7 @@ static void show_last_breaking_event(struct pt_regs *regs) { #ifdef CONFIG_64BIT printk("Last Breaking-Event-Address:\n"); - printk(" [<%016lx>] ", regs->args[0] & PSW_ADDR_INSN); - print_symbol("%s\n", regs->args[0] & PSW_ADDR_INSN); + printk(" [<%016lx>] %pSR\n", regs->args[0], (void *)regs->args[0]); #endif } @@ -143,10 +143,10 @@ void show_registers(struct pt_regs *regs) char *mode; mode = user_mode(regs) ? "User" : "Krnl"; - printk("%s PSW : %p %p", + printk("%s PSW : %p %p (%pSR)\n", mode, (void *) regs->psw.mask, + (void *) regs->psw.addr, (void *) regs->psw.addr); - print_symbol(" (%s)\n", regs->psw.addr & PSW_ADDR_INSN); printk(" R:%x T:%x IO:%x EX:%x Key:%x M:%x W:%x " "P:%x AS:%x CC:%x PM:%x", mask_bits(regs, PSW_MASK_PER), mask_bits(regs, PSW_MASK_DAT), mask_bits(regs, PSW_MASK_IO), -- cgit v1.2.3-70-g09d2 From 50ce749d0d107aaed8c2d702b987529f978a40f7 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Tue, 3 Sep 2013 14:12:07 +0200 Subject: s390/irq: use hlists for external interrupt handler array Use hlists for the hashed array of external interrupt handlers. Reduces the size of the array by 50% (2KB). Signed-off-by: Heiko Carstens --- arch/s390/kernel/irq.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) (limited to 'arch/s390') diff --git a/arch/s390/kernel/irq.c b/arch/s390/kernel/irq.c index b34ba0ea96a..4ecf017f697 100644 --- a/arch/s390/kernel/irq.c +++ b/arch/s390/kernel/irq.c @@ -196,13 +196,13 @@ asmlinkage void do_softirq(void) * ext_int_hash[index] is the list head for all external interrupts that hash * to this index. */ -static struct list_head ext_int_hash[256]; +static struct hlist_head ext_int_hash[256]; struct ext_int_info { ext_int_handler_t handler; - u16 code; - struct list_head entry; + struct hlist_node entry; struct rcu_head rcu; + u16 code; }; /* ext_int_hash_lock protects the handler lists for external interrupts */ @@ -227,7 +227,7 @@ int register_external_interrupt(u16 code, ext_int_handler_t handler) index = ext_hash(code); spin_lock_irqsave(&ext_int_hash_lock, flags); - list_add_rcu(&p->entry, &ext_int_hash[index]); + hlist_add_head_rcu(&p->entry, &ext_int_hash[index]); spin_unlock_irqrestore(&ext_int_hash_lock, flags); return 0; } @@ -240,9 +240,9 @@ int unregister_external_interrupt(u16 code, ext_int_handler_t handler) int index = ext_hash(code); spin_lock_irqsave(&ext_int_hash_lock, flags); - list_for_each_entry_rcu(p, &ext_int_hash[index], entry) { + hlist_for_each_entry_rcu(p, &ext_int_hash[index], entry) { if (p->code == code && p->handler == handler) { - list_del_rcu(&p->entry); + hlist_del_rcu(&p->entry); kfree_rcu(p, rcu); } } @@ -264,12 +264,12 @@ static irqreturn_t do_ext_interrupt(int irq, void *dummy) index = ext_hash(ext_code.code); rcu_read_lock(); - list_for_each_entry_rcu(p, &ext_int_hash[index], entry) - if (likely(p->code == ext_code.code)) - p->handler(ext_code, regs->int_parm, - regs->int_parm_long); + hlist_for_each_entry_rcu(p, &ext_int_hash[index], entry) { + if (unlikely(p->code != ext_code.code)) + continue; + p->handler(ext_code, regs->int_parm, regs->int_parm_long); + } rcu_read_unlock(); - return IRQ_HANDLED; } @@ -283,7 +283,7 @@ void __init init_ext_interrupts(void) int idx; for (idx = 0; idx < ARRAY_SIZE(ext_int_hash); idx++) - INIT_LIST_HEAD(&ext_int_hash[idx]); + INIT_HLIST_HEAD(&ext_int_hash[idx]); irq_set_chip_and_handler(EXT_INTERRUPT, &dummy_irq_chip, handle_percpu_irq); -- cgit v1.2.3-70-g09d2 From 82003c3e606905ca20c78a0ceca9f412e6f71474 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Wed, 4 Sep 2013 13:35:45 +0200 Subject: s390/irq: rework irq subclass handling Let's not add a function for every external interrupt subclass for which we need reference counting. Just have two register/unregister functions which have a subclass parameter: void irq_subclass_register(enum irq_subclass subclass); void irq_subclass_unregister(enum irq_subclass subclass); Signed-off-by: Heiko Carstens --- arch/s390/include/asm/irq.h | 12 ++++++--- arch/s390/kernel/irq.c | 55 ++++++++++++---------------------------- arch/s390/kernel/perf_cpum_cf.c | 4 +-- arch/s390/kernel/runtime_instr.c | 4 +-- arch/s390/mm/fault.c | 2 +- arch/s390/oprofile/hwsampler.c | 6 ++--- drivers/s390/block/dasd_diag.c | 4 +-- drivers/s390/char/sclp.c | 6 ++--- drivers/s390/kvm/kvm_virtio.c | 2 +- 9 files changed, 38 insertions(+), 57 deletions(-) (limited to 'arch/s390') diff --git a/arch/s390/include/asm/irq.h b/arch/s390/include/asm/irq.h index 1eaa3625803..5f8bcc5fe42 100644 --- a/arch/s390/include/asm/irq.h +++ b/arch/s390/include/asm/irq.h @@ -78,10 +78,14 @@ typedef void (*ext_int_handler_t)(struct ext_code, unsigned int, unsigned long); int register_external_interrupt(u16 code, ext_int_handler_t handler); int unregister_external_interrupt(u16 code, ext_int_handler_t handler); -void service_subclass_irq_register(void); -void service_subclass_irq_unregister(void); -void measurement_alert_subclass_register(void); -void measurement_alert_subclass_unregister(void); + +enum irq_subclass { + IRQ_SUBCLASS_MEASUREMENT_ALERT = 5, + IRQ_SUBCLASS_SERVICE_SIGNAL = 9, +}; + +void irq_subclass_register(enum irq_subclass subclass); +void irq_subclass_unregister(enum irq_subclass subclass); #define irq_canonicalize(irq) (irq) diff --git a/arch/s390/kernel/irq.c b/arch/s390/kernel/irq.c index 4ecf017f697..6834277124c 100644 --- a/arch/s390/kernel/irq.c +++ b/arch/s390/kernel/irq.c @@ -290,48 +290,25 @@ void __init init_ext_interrupts(void) setup_irq(EXT_INTERRUPT, &external_interrupt); } -static DEFINE_SPINLOCK(sc_irq_lock); -static int sc_irq_refcount; +static DEFINE_SPINLOCK(irq_subclass_lock); +static unsigned char irq_subclass_refcount[64]; -void service_subclass_irq_register(void) +void irq_subclass_register(enum irq_subclass subclass) { - spin_lock(&sc_irq_lock); - if (!sc_irq_refcount) - ctl_set_bit(0, 9); - sc_irq_refcount++; - spin_unlock(&sc_irq_lock); + spin_lock(&irq_subclass_lock); + if (!irq_subclass_refcount[subclass]) + ctl_set_bit(0, subclass); + irq_subclass_refcount[subclass]++; + spin_unlock(&irq_subclass_lock); } -EXPORT_SYMBOL(service_subclass_irq_register); +EXPORT_SYMBOL(irq_subclass_register); -void service_subclass_irq_unregister(void) +void irq_subclass_unregister(enum irq_subclass subclass) { - spin_lock(&sc_irq_lock); - sc_irq_refcount--; - if (!sc_irq_refcount) - ctl_clear_bit(0, 9); - spin_unlock(&sc_irq_lock); + spin_lock(&irq_subclass_lock); + irq_subclass_refcount[subclass]--; + if (!irq_subclass_refcount[subclass]) + ctl_clear_bit(0, subclass); + spin_unlock(&irq_subclass_lock); } -EXPORT_SYMBOL(service_subclass_irq_unregister); - -static DEFINE_SPINLOCK(ma_subclass_lock); -static int ma_subclass_refcount; - -void measurement_alert_subclass_register(void) -{ - spin_lock(&ma_subclass_lock); - if (!ma_subclass_refcount) - ctl_set_bit(0, 5); - ma_subclass_refcount++; - spin_unlock(&ma_subclass_lock); -} -EXPORT_SYMBOL(measurement_alert_subclass_register); - -void measurement_alert_subclass_unregister(void) -{ - spin_lock(&ma_subclass_lock); - ma_subclass_refcount--; - if (!ma_subclass_refcount) - ctl_clear_bit(0, 5); - spin_unlock(&ma_subclass_lock); -} -EXPORT_SYMBOL(measurement_alert_subclass_unregister); +EXPORT_SYMBOL(irq_subclass_unregister); diff --git a/arch/s390/kernel/perf_cpum_cf.c b/arch/s390/kernel/perf_cpum_cf.c index fb99c2057b8..1105502bf6e 100644 --- a/arch/s390/kernel/perf_cpum_cf.c +++ b/arch/s390/kernel/perf_cpum_cf.c @@ -274,7 +274,7 @@ static int reserve_pmc_hardware(void) int flags = PMC_INIT; on_each_cpu(setup_pmc_cpu, &flags, 1); - measurement_alert_subclass_register(); + irq_subclass_register(IRQ_SUBCLASS_MEASUREMENT_ALERT); return 0; } @@ -285,7 +285,7 @@ static void release_pmc_hardware(void) int flags = PMC_RELEASE; on_each_cpu(setup_pmc_cpu, &flags, 1); - measurement_alert_subclass_unregister(); + irq_subclass_unregister(IRQ_SUBCLASS_MEASUREMENT_ALERT); } /* Release the PMU if event is the last perf event */ diff --git a/arch/s390/kernel/runtime_instr.c b/arch/s390/kernel/runtime_instr.c index 077a99389b0..e1c9d1c292f 100644 --- a/arch/s390/kernel/runtime_instr.c +++ b/arch/s390/kernel/runtime_instr.c @@ -139,10 +139,10 @@ static int __init runtime_instr_init(void) if (!runtime_instr_avail()) return 0; - measurement_alert_subclass_register(); + irq_subclass_register(IRQ_SUBCLASS_MEASUREMENT_ALERT); rc = register_external_interrupt(0x1407, runtime_instr_int_handler); if (rc) - measurement_alert_subclass_unregister(); + irq_subclass_unregister(IRQ_SUBCLASS_MEASUREMENT_ALERT); else pr_info("Runtime instrumentation facility initialized\n"); return rc; diff --git a/arch/s390/mm/fault.c b/arch/s390/mm/fault.c index f00aefb66a4..7de4469915f 100644 --- a/arch/s390/mm/fault.c +++ b/arch/s390/mm/fault.c @@ -673,7 +673,7 @@ static int __init pfault_irq_init(void) rc = pfault_init() == 0 ? 0 : -EOPNOTSUPP; if (rc) goto out_pfault; - service_subclass_irq_register(); + irq_subclass_register(IRQ_SUBCLASS_SERVICE_SIGNAL); hotcpu_notifier(pfault_cpu_notify, 0); return 0; diff --git a/arch/s390/oprofile/hwsampler.c b/arch/s390/oprofile/hwsampler.c index b5b2916895e..231cecafc2f 100644 --- a/arch/s390/oprofile/hwsampler.c +++ b/arch/s390/oprofile/hwsampler.c @@ -1001,7 +1001,7 @@ int hwsampler_deallocate(void) if (hws_state != HWS_STOPPED) goto deallocate_exit; - measurement_alert_subclass_unregister(); + irq_subclass_unregister(IRQ_SUBCLASS_MEASUREMENT_ALERT); deallocate_sdbt(); hws_state = HWS_DEALLOCATED; @@ -1115,7 +1115,7 @@ int hwsampler_shutdown(void) mutex_lock(&hws_sem); if (hws_state == HWS_STOPPED) { - measurement_alert_subclass_unregister(); + irq_subclass_unregister(IRQ_SUBCLASS_MEASUREMENT_ALERT); deallocate_sdbt(); } if (hws_wq) { @@ -1190,7 +1190,7 @@ start_all_exit: hws_oom = 1; hws_flush_all = 0; /* now let them in, 1407 CPUMF external interrupts */ - measurement_alert_subclass_register(); + irq_subclass_register(IRQ_SUBCLASS_MEASUREMENT_ALERT); return 0; } diff --git a/drivers/s390/block/dasd_diag.c b/drivers/s390/block/dasd_diag.c index feca317b33d..92bd22ce676 100644 --- a/drivers/s390/block/dasd_diag.c +++ b/drivers/s390/block/dasd_diag.c @@ -645,7 +645,7 @@ dasd_diag_init(void) } ASCEBC(dasd_diag_discipline.ebcname, 4); - service_subclass_irq_register(); + irq_subclass_register(IRQ_SUBCLASS_SERVICE_SIGNAL); register_external_interrupt(0x2603, dasd_ext_handler); dasd_diag_discipline_pointer = &dasd_diag_discipline; return 0; @@ -655,7 +655,7 @@ static void __exit dasd_diag_cleanup(void) { unregister_external_interrupt(0x2603, dasd_ext_handler); - service_subclass_irq_unregister(); + irq_subclass_unregister(IRQ_SUBCLASS_SERVICE_SIGNAL); dasd_diag_discipline_pointer = NULL; } diff --git a/drivers/s390/char/sclp.c b/drivers/s390/char/sclp.c index 3e4fb4e858d..a3aa374799d 100644 --- a/drivers/s390/char/sclp.c +++ b/drivers/s390/char/sclp.c @@ -910,12 +910,12 @@ sclp_check_interface(void) spin_unlock_irqrestore(&sclp_lock, flags); /* Enable service-signal interruption - needs to happen * with IRQs enabled. */ - service_subclass_irq_register(); + irq_subclass_register(IRQ_SUBCLASS_SERVICE_SIGNAL); /* Wait for signal from interrupt or timeout */ sclp_sync_wait(); /* Disable service-signal interruption - needs to happen * with IRQs enabled. */ - service_subclass_irq_unregister(); + irq_subclass_unregister(IRQ_SUBCLASS_SERVICE_SIGNAL); spin_lock_irqsave(&sclp_lock, flags); del_timer(&sclp_request_timer); if (sclp_init_req.status == SCLP_REQ_DONE && @@ -1131,7 +1131,7 @@ sclp_init(void) spin_unlock_irqrestore(&sclp_lock, flags); /* Enable service-signal external interruption - needs to happen with * IRQs enabled. */ - service_subclass_irq_register(); + irq_subclass_register(IRQ_SUBCLASS_SERVICE_SIGNAL); sclp_init_mask(1); return 0; diff --git a/drivers/s390/kvm/kvm_virtio.c b/drivers/s390/kvm/kvm_virtio.c index 2ea6165366b..af2166fa515 100644 --- a/drivers/s390/kvm/kvm_virtio.c +++ b/drivers/s390/kvm/kvm_virtio.c @@ -472,7 +472,7 @@ static int __init kvm_devices_init(void) INIT_WORK(&hotplug_work, hotplug_devices); - service_subclass_irq_register(); + irq_subclass_register(IRQ_SUBCLASS_SERVICE_SIGNAL); register_external_interrupt(0x2603, kvm_extint_handler); scan_devices(); -- cgit v1.2.3-70-g09d2 From 93bead4369c0a9e41327f2f7eb19d3c767f271c6 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Fri, 6 Sep 2013 10:03:30 +0200 Subject: s390: keep Kconfig sorted Signed-off-by: Heiko Carstens --- arch/s390/Kconfig | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'arch/s390') diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig index 8b7892bf6d8..665c8a20365 100644 --- a/arch/s390/Kconfig +++ b/arch/s390/Kconfig @@ -62,6 +62,7 @@ config S390 def_bool y select ARCH_DISCARD_MEMBLOCK select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE + select ARCH_HAS_DEBUG_STRICT_USER_COPY_CHECKS select ARCH_HAVE_NMI_SAFE_CMPXCHG select ARCH_INLINE_READ_LOCK select ARCH_INLINE_READ_LOCK_BH @@ -91,7 +92,6 @@ config S390 select ARCH_INLINE_WRITE_UNLOCK_BH select ARCH_INLINE_WRITE_UNLOCK_IRQ select ARCH_INLINE_WRITE_UNLOCK_IRQRESTORE - select ARCH_HAS_DEBUG_STRICT_USER_COPY_CHECKS select ARCH_SAVE_PAGE_KEYS if HIBERNATION select ARCH_WANT_IPC_PARSE_VERSION select BUILDTIME_EXTABLE_SORT @@ -135,15 +135,15 @@ config S390 select HAVE_SYSCALL_TRACEPOINTS select HAVE_UID16 if 32BIT select HAVE_VIRT_CPU_ACCOUNTING - select VIRT_TO_BUS select INIT_ALL_POSSIBLE select KTIME_SCALAR if 32BIT select MODULES_USE_ELF_RELA - select OLD_SIGSUSPEND3 select OLD_SIGACTION + select OLD_SIGSUSPEND3 select SYSCTL_EXCEPTION_TRACE select USE_GENERIC_SMP_HELPERS if SMP select VIRT_CPU_ACCOUNTING + select VIRT_TO_BUS config SCHED_OMIT_FRAME_POINTER def_bool y -- cgit v1.2.3-70-g09d2 From 984e2a5975e538a6475f7453523896319a1cb597 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Fri, 6 Sep 2013 18:48:58 +0200 Subject: s390/mm: add __releases()/__acquires() annotations to gmap_alloc_table() Let sparse not incorrectly complain about unbalanced locking. Signed-off-by: Heiko Carstens --- arch/s390/mm/pgtable.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'arch/s390') diff --git a/arch/s390/mm/pgtable.c b/arch/s390/mm/pgtable.c index 6d16132d085..1224db4a405 100644 --- a/arch/s390/mm/pgtable.c +++ b/arch/s390/mm/pgtable.c @@ -245,7 +245,9 @@ EXPORT_SYMBOL_GPL(gmap_disable); * gmap_alloc_table is assumed to be called with mmap_sem held */ static int gmap_alloc_table(struct gmap *gmap, - unsigned long *table, unsigned long init) + unsigned long *table, unsigned long init) + __releases(&gmap->mm->page_table_lock) + __acquires(&gmap->mm->page_table_lock) { struct page *page; unsigned long *new; -- cgit v1.2.3-70-g09d2 From 5b512beb0f18024e32e228976e3690d349b05b6a Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Fri, 6 Sep 2013 18:52:31 +0200 Subject: s390/compat signal: add couple of __force annotations Add __force annotations to get rid of a couple of sparse warnings: arch/s390/kernel/compat_signal.c:335:35: warning: cast removes address space of expression Signed-off-by: Heiko Carstens --- arch/s390/kernel/compat_signal.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'arch/s390') diff --git a/arch/s390/kernel/compat_signal.c b/arch/s390/kernel/compat_signal.c index c439ac9ced0..1389b637dae 100644 --- a/arch/s390/kernel/compat_signal.c +++ b/arch/s390/kernel/compat_signal.c @@ -332,9 +332,9 @@ static int setup_frame32(int sig, struct k_sigaction *ka, /* Set up to return from userspace. If provided, use a stub already in userspace. */ if (ka->sa.sa_flags & SA_RESTORER) { - regs->gprs[14] = (__u64) ka->sa.sa_restorer | PSW32_ADDR_AMODE; + regs->gprs[14] = (__u64 __force) ka->sa.sa_restorer | PSW32_ADDR_AMODE; } else { - regs->gprs[14] = (__u64) frame->retcode | PSW32_ADDR_AMODE; + regs->gprs[14] = (__u64 __force) frame->retcode | PSW32_ADDR_AMODE; if (__put_user(S390_SYSCALL_OPCODE | __NR_sigreturn, (u16 __force __user *)(frame->retcode))) goto give_sigsegv; @@ -400,9 +400,9 @@ static int setup_rt_frame32(int sig, struct k_sigaction *ka, siginfo_t *info, /* Set up to return from userspace. If provided, use a stub already in userspace. */ if (ka->sa.sa_flags & SA_RESTORER) { - regs->gprs[14] = (__u64) ka->sa.sa_restorer | PSW32_ADDR_AMODE; + regs->gprs[14] = (__u64 __force) ka->sa.sa_restorer | PSW32_ADDR_AMODE; } else { - regs->gprs[14] = (__u64) frame->retcode | PSW32_ADDR_AMODE; + regs->gprs[14] = (__u64 __force) frame->retcode | PSW32_ADDR_AMODE; err |= __put_user(S390_SYSCALL_OPCODE | __NR_rt_sigreturn, (u16 __force __user *)(frame->retcode)); } @@ -417,7 +417,7 @@ static int setup_rt_frame32(int sig, struct k_sigaction *ka, siginfo_t *info, regs->psw.mask = PSW_MASK_BA | (psw_user_bits & PSW_MASK_ASC) | (regs->psw.mask & ~PSW_MASK_ASC); - regs->psw.addr = (__u64) ka->sa.sa_handler; + regs->psw.addr = (__u64 __force) ka->sa.sa_handler; regs->gprs[2] = map_signal(sig); regs->gprs[3] = (__force __u64) &frame->info; -- cgit v1.2.3-70-g09d2 From 63df41d663fc27e96571bfea86d3f9ee81289e07 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Fri, 6 Sep 2013 19:10:48 +0200 Subject: s390: make various functions static, add declarations to header files Make various functions static, add declarations to header files to fix a couple of sparse findings. Signed-off-by: Heiko Carstens --- arch/s390/kernel/entry.h | 18 ++++++------------ arch/s390/kernel/ftrace.c | 1 + arch/s390/kernel/irq.c | 2 +- arch/s390/kernel/machine_kexec.c | 2 +- arch/s390/kernel/smp.c | 2 +- arch/s390/kernel/suspend.c | 1 + arch/s390/mm/maccess.c | 1 + arch/s390/mm/pgtable.c | 2 +- drivers/s390/char/fs3270.c | 6 +++--- drivers/s390/char/tty3270.c | 6 +++--- 10 files changed, 19 insertions(+), 22 deletions(-) (limited to 'arch/s390') diff --git a/arch/s390/kernel/entry.h b/arch/s390/kernel/entry.h index 3ddbc26d246..e9b04c33d38 100644 --- a/arch/s390/kernel/entry.h +++ b/arch/s390/kernel/entry.h @@ -53,27 +53,21 @@ void handle_signal32(unsigned long sig, struct k_sigaction *ka, siginfo_t *info, sigset_t *oldset, struct pt_regs *regs); void do_notify_resume(struct pt_regs *regs); -struct ext_code; -void do_extint(struct pt_regs *regs); +void __init init_IRQ(void); +void do_IRQ(struct pt_regs *regs, int irq); void do_restart(void); void __init startup_init(void); void die(struct pt_regs *regs, const char *str); - +int setup_profiling_timer(unsigned int multiplier); void __init time_init(void); +int pfn_is_nosave(unsigned long); +void s390_early_resume(void); +unsigned long prepare_ftrace_return(unsigned long parent, unsigned long ip); struct s390_mmap_arg_struct; struct fadvise64_64_args; struct old_sigaction; -long sys_mmap2(struct s390_mmap_arg_struct __user *arg); -long sys_s390_ipc(uint call, int first, unsigned long second, - unsigned long third, void __user *ptr); -long sys_s390_personality(unsigned int personality); -long sys_s390_fadvise64(int fd, u32 offset_high, u32 offset_low, - size_t len, int advice); -long sys_s390_fadvise64_64(struct fadvise64_64_args __user *args); -long sys_s390_fallocate(int fd, int mode, loff_t offset, u32 len_high, - u32 len_low); long sys_sigreturn(void); long sys_rt_sigreturn(void); long sys32_sigreturn(void); diff --git a/arch/s390/kernel/ftrace.c b/arch/s390/kernel/ftrace.c index e3043aef87a..4c807206812 100644 --- a/arch/s390/kernel/ftrace.c +++ b/arch/s390/kernel/ftrace.c @@ -15,6 +15,7 @@ #include #include #include +#include "entry.h" #ifdef CONFIG_DYNAMIC_FTRACE diff --git a/arch/s390/kernel/irq.c b/arch/s390/kernel/irq.c index 6834277124c..6eba6fd8a8e 100644 --- a/arch/s390/kernel/irq.c +++ b/arch/s390/kernel/irq.c @@ -206,7 +206,7 @@ struct ext_int_info { }; /* ext_int_hash_lock protects the handler lists for external interrupts */ -DEFINE_SPINLOCK(ext_int_hash_lock); +static DEFINE_SPINLOCK(ext_int_hash_lock); static inline int ext_hash(u16 code) { diff --git a/arch/s390/kernel/machine_kexec.c b/arch/s390/kernel/machine_kexec.c index ac2178161ec..719e27b2cf2 100644 --- a/arch/s390/kernel/machine_kexec.c +++ b/arch/s390/kernel/machine_kexec.c @@ -50,7 +50,7 @@ static void add_elf_notes(int cpu) /* * Initialize CPU ELF notes */ -void setup_regs(void) +static void setup_regs(void) { unsigned long sa = S390_lowcore.prefixreg_save_area + SAVE_AREA_BASE; int cpu, this_cpu; diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c index d386c4e9d2e..1a4313a1b60 100644 --- a/arch/s390/kernel/smp.c +++ b/arch/s390/kernel/smp.c @@ -362,7 +362,7 @@ void smp_yield_cpu(int cpu) * Send cpus emergency shutdown signal. This gives the cpus the * opportunity to complete outstanding interrupts. */ -void smp_emergency_stop(cpumask_t *cpumask) +static void smp_emergency_stop(cpumask_t *cpumask) { u64 end; int cpu; diff --git a/arch/s390/kernel/suspend.c b/arch/s390/kernel/suspend.c index 737bff38e3e..a7a7537ce1e 100644 --- a/arch/s390/kernel/suspend.c +++ b/arch/s390/kernel/suspend.c @@ -13,6 +13,7 @@ #include #include #include +#include "entry.h" /* * References to section boundaries diff --git a/arch/s390/mm/maccess.c b/arch/s390/mm/maccess.c index 921fa541dc0..d1e0e0c7a7e 100644 --- a/arch/s390/mm/maccess.c +++ b/arch/s390/mm/maccess.c @@ -14,6 +14,7 @@ #include #include #include +#include /* * This function writes to kernel memory bypassing DAT and possible diff --git a/arch/s390/mm/pgtable.c b/arch/s390/mm/pgtable.c index 1224db4a405..4645fafa42c 100644 --- a/arch/s390/mm/pgtable.c +++ b/arch/s390/mm/pgtable.c @@ -958,7 +958,7 @@ void page_table_free_rcu(struct mmu_gather *tlb, unsigned long *table) tlb_remove_table(tlb, table); } -void __tlb_remove_table(void *_table) +static void __tlb_remove_table(void *_table) { const unsigned long mask = (FRAG_MASK << 4) | FRAG_MASK; void *table = (void *)((unsigned long) _table & ~mask); diff --git a/drivers/s390/char/fs3270.c b/drivers/s390/char/fs3270.c index 96e52bf7593..f93cc32eb81 100644 --- a/drivers/s390/char/fs3270.c +++ b/drivers/s390/char/fs3270.c @@ -524,20 +524,20 @@ static const struct file_operations fs3270_fops = { .llseek = no_llseek, }; -void fs3270_create_cb(int minor) +static void fs3270_create_cb(int minor) { __register_chrdev(IBM_FS3270_MAJOR, minor, 1, "tub", &fs3270_fops); device_create(class3270, NULL, MKDEV(IBM_FS3270_MAJOR, minor), NULL, "3270/tub%d", minor); } -void fs3270_destroy_cb(int minor) +static void fs3270_destroy_cb(int minor) { device_destroy(class3270, MKDEV(IBM_FS3270_MAJOR, minor)); __unregister_chrdev(IBM_FS3270_MAJOR, minor, 1, "tub"); } -struct raw3270_notifier fs3270_notifier = +static struct raw3270_notifier fs3270_notifier = { .create = fs3270_create_cb, .destroy = fs3270_destroy_cb, diff --git a/drivers/s390/char/tty3270.c b/drivers/s390/char/tty3270.c index cee69dac3e1..a0f47c83fd6 100644 --- a/drivers/s390/char/tty3270.c +++ b/drivers/s390/char/tty3270.c @@ -1845,17 +1845,17 @@ static const struct tty_operations tty3270_ops = { .set_termios = tty3270_set_termios }; -void tty3270_create_cb(int minor) +static void tty3270_create_cb(int minor) { tty_register_device(tty3270_driver, minor - RAW3270_FIRSTMINOR, NULL); } -void tty3270_destroy_cb(int minor) +static void tty3270_destroy_cb(int minor) { tty_unregister_device(tty3270_driver, minor - RAW3270_FIRSTMINOR); } -struct raw3270_notifier tty3270_notifier = +static struct raw3270_notifier tty3270_notifier = { .create = tty3270_create_cb, .destroy = tty3270_destroy_cb, -- cgit v1.2.3-70-g09d2 From 5eb8ae503e13c6eee3545e3e3be986db000ae8c2 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Fri, 6 Sep 2013 19:16:14 +0200 Subject: s390/ftrace: avoid pointer arithmetics with function pointers Pointer arithmetics with function pointers is not really defined, but seems to do the right thing. Let's cast to a void pointer to have a defined behaviour, at least when using gcc. Signed-off-by: Heiko Carstens --- arch/s390/kernel/ftrace.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch/s390') diff --git a/arch/s390/kernel/ftrace.c b/arch/s390/kernel/ftrace.c index 4c807206812..1014ad5f769 100644 --- a/arch/s390/kernel/ftrace.c +++ b/arch/s390/kernel/ftrace.c @@ -178,7 +178,7 @@ int ftrace_enable_ftrace_graph_caller(void) offset = ((void *) prepare_ftrace_return - (void *) ftrace_graph_caller) / 2; - return probe_kernel_write(ftrace_graph_caller + 2, + return probe_kernel_write((void *) ftrace_graph_caller + 2, &offset, sizeof(offset)); } @@ -186,7 +186,7 @@ int ftrace_disable_ftrace_graph_caller(void) { static unsigned short offset = 0x0002; - return probe_kernel_write(ftrace_graph_caller + 2, + return probe_kernel_write((void *) ftrace_graph_caller + 2, &offset, sizeof(offset)); } -- cgit v1.2.3-70-g09d2 From 2ec7f4aec4d459ef443151ecc875bfbb3a2788f8 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Sat, 7 Sep 2013 10:19:55 +0200 Subject: s390/compat,uid16: use current_cred() 86a264ab "CRED: Wrap current->cred and a few other accessors" converted all uses of current->cred into current_cred() but left s390 alone. So let's convert s390 finally as well, only five years later. This way we also get rid of a sparse warning which complains about a possible invalid rcu dereference which however is a false positive. Signed-off-by: Heiko Carstens --- arch/s390/kernel/compat_linux.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'arch/s390') diff --git a/arch/s390/kernel/compat_linux.c b/arch/s390/kernel/compat_linux.c index 8b6e4f5288a..1f1b8c70ab9 100644 --- a/arch/s390/kernel/compat_linux.c +++ b/arch/s390/kernel/compat_linux.c @@ -221,25 +221,26 @@ static int groups16_from_user(struct group_info *group_info, u16 __user *groupli asmlinkage long sys32_getgroups16(int gidsetsize, u16 __user *grouplist) { + const struct cred *cred = current_cred(); int i; if (gidsetsize < 0) return -EINVAL; - get_group_info(current->cred->group_info); - i = current->cred->group_info->ngroups; + get_group_info(cred->group_info); + i = cred->group_info->ngroups; if (gidsetsize) { if (i > gidsetsize) { i = -EINVAL; goto out; } - if (groups16_to_user(grouplist, current->cred->group_info)) { + if (groups16_to_user(grouplist, cred->group_info)) { i = -EFAULT; goto out; } } out: - put_group_info(current->cred->group_info); + put_group_info(cred->group_info); return i; } -- cgit v1.2.3-70-g09d2 From 9e75c6274a7365ad493fc3e75c8dd35f0185b7ca Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Mon, 9 Sep 2013 07:44:43 +0200 Subject: s390/irq: reduce size of external interrupt handler hash array Change the hash algorithm a bit so it produces only values in the range of 0..31. This allows to reduce the size of the external interrupt handler hash array even further while making sure that each of the known interrupt sources keeps its unique hash with the slightly modified algorithm: 0x1004 --> 12 0x1201 --> 10 0x1202 --> 11 0x1406 --> 16 0x1407 --> 17 0x2401 --> 19 0x2603 --> 22 0x4000 --> 0 This also means that the entire array now fits into exactly one cache line; so add a proper align statement as well. Signed-off-by: Heiko Carstens --- arch/s390/kernel/irq.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'arch/s390') diff --git a/arch/s390/kernel/irq.c b/arch/s390/kernel/irq.c index 6eba6fd8a8e..8ac2097f13d 100644 --- a/arch/s390/kernel/irq.c +++ b/arch/s390/kernel/irq.c @@ -196,7 +196,7 @@ asmlinkage void do_softirq(void) * ext_int_hash[index] is the list head for all external interrupts that hash * to this index. */ -static struct hlist_head ext_int_hash[256]; +static struct hlist_head ext_int_hash[32] ____cacheline_aligned; struct ext_int_info { ext_int_handler_t handler; @@ -210,7 +210,9 @@ static DEFINE_SPINLOCK(ext_int_hash_lock); static inline int ext_hash(u16 code) { - return (code + (code >> 9)) & 0xff; + BUILD_BUG_ON(!is_power_of_2(ARRAY_SIZE(ext_int_hash))); + + return (code + (code >> 9)) & (ARRAY_SIZE(ext_int_hash) - 1); } int register_external_interrupt(u16 code, ext_int_handler_t handler) -- cgit v1.2.3-70-g09d2