Magellan Linux

Annotation of /trunk/kernel-alx/patches-4.4/0138-4.4.39-all-fixes.patch

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2874 - (hide annotations) (download)
Mon Mar 27 13:49:15 2017 UTC (7 years, 1 month ago) by niro
File size: 16674 byte(s)
linux-4.4.39
1 niro 2874 diff --git a/Makefile b/Makefile
2     index 6876efe0d735..88d26a632bef 100644
3     --- a/Makefile
4     +++ b/Makefile
5     @@ -1,6 +1,6 @@
6     VERSION = 4
7     PATCHLEVEL = 4
8     -SUBLEVEL = 38
9     +SUBLEVEL = 39
10     EXTRAVERSION =
11     NAME = Blurry Fish Butt
12    
13     diff --git a/arch/arm64/include/asm/futex.h b/arch/arm64/include/asm/futex.h
14     index 007a69fc4f40..5f3ab8c1db55 100644
15     --- a/arch/arm64/include/asm/futex.h
16     +++ b/arch/arm64/include/asm/futex.h
17     @@ -121,6 +121,7 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr,
18     return -EFAULT;
19    
20     asm volatile("// futex_atomic_cmpxchg_inatomic\n"
21     +ALTERNATIVE("nop", SET_PSTATE_PAN(0), ARM64_HAS_PAN, CONFIG_ARM64_PAN)
22     " prfm pstl1strm, %2\n"
23     "1: ldxr %w1, %2\n"
24     " sub %w3, %w1, %w4\n"
25     @@ -137,6 +138,7 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr,
26     " .align 3\n"
27     " .quad 1b, 4b, 2b, 4b\n"
28     " .popsection\n"
29     +ALTERNATIVE("nop", SET_PSTATE_PAN(1), ARM64_HAS_PAN, CONFIG_ARM64_PAN)
30     : "+r" (ret), "=&r" (val), "+Q" (*uaddr), "=&r" (tmp)
31     : "r" (oldval), "r" (newval), "Ir" (-EFAULT)
32     : "memory");
33     diff --git a/arch/m68k/include/asm/delay.h b/arch/m68k/include/asm/delay.h
34     index d28fa8fe26fe..c598d847d56b 100644
35     --- a/arch/m68k/include/asm/delay.h
36     +++ b/arch/m68k/include/asm/delay.h
37     @@ -114,6 +114,6 @@ static inline void __udelay(unsigned long usecs)
38     */
39     #define HZSCALE (268435456 / (1000000 / HZ))
40    
41     -#define ndelay(n) __delay(DIV_ROUND_UP((n) * ((((HZSCALE) >> 11) * (loops_per_jiffy >> 11)) >> 6), 1000));
42     +#define ndelay(n) __delay(DIV_ROUND_UP((n) * ((((HZSCALE) >> 11) * (loops_per_jiffy >> 11)) >> 6), 1000))
43    
44     #endif /* defined(_M68K_DELAY_H) */
45     diff --git a/arch/parisc/include/asm/pgtable.h b/arch/parisc/include/asm/pgtable.h
46     index c2c43f714684..3a4ed9f91d57 100644
47     --- a/arch/parisc/include/asm/pgtable.h
48     +++ b/arch/parisc/include/asm/pgtable.h
49     @@ -65,9 +65,9 @@ static inline void purge_tlb_entries(struct mm_struct *mm, unsigned long addr)
50     unsigned long flags; \
51     spin_lock_irqsave(&pa_tlb_lock, flags); \
52     old_pte = *ptep; \
53     - set_pte(ptep, pteval); \
54     if (pte_inserted(old_pte)) \
55     purge_tlb_entries(mm, addr); \
56     + set_pte(ptep, pteval); \
57     spin_unlock_irqrestore(&pa_tlb_lock, flags); \
58     } while (0)
59    
60     @@ -478,8 +478,8 @@ static inline int ptep_test_and_clear_young(struct vm_area_struct *vma, unsigned
61     spin_unlock_irqrestore(&pa_tlb_lock, flags);
62     return 0;
63     }
64     - set_pte(ptep, pte_mkold(pte));
65     purge_tlb_entries(vma->vm_mm, addr);
66     + set_pte(ptep, pte_mkold(pte));
67     spin_unlock_irqrestore(&pa_tlb_lock, flags);
68     return 1;
69     }
70     @@ -492,9 +492,9 @@ static inline pte_t ptep_get_and_clear(struct mm_struct *mm, unsigned long addr,
71    
72     spin_lock_irqsave(&pa_tlb_lock, flags);
73     old_pte = *ptep;
74     - set_pte(ptep, __pte(0));
75     if (pte_inserted(old_pte))
76     purge_tlb_entries(mm, addr);
77     + set_pte(ptep, __pte(0));
78     spin_unlock_irqrestore(&pa_tlb_lock, flags);
79    
80     return old_pte;
81     @@ -504,8 +504,8 @@ static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr,
82     {
83     unsigned long flags;
84     spin_lock_irqsave(&pa_tlb_lock, flags);
85     - set_pte(ptep, pte_wrprotect(*ptep));
86     purge_tlb_entries(mm, addr);
87     + set_pte(ptep, pte_wrprotect(*ptep));
88     spin_unlock_irqrestore(&pa_tlb_lock, flags);
89     }
90    
91     diff --git a/arch/parisc/kernel/cache.c b/arch/parisc/kernel/cache.c
92     index fd5979f28ada..6857a104b2f9 100644
93     --- a/arch/parisc/kernel/cache.c
94     +++ b/arch/parisc/kernel/cache.c
95     @@ -375,6 +375,15 @@ void __init parisc_setup_cache_timing(void)
96    
97     /* calculate TLB flush threshold */
98    
99     + /* On SMP machines, skip the TLB measure of kernel text which
100     + * has been mapped as huge pages. */
101     + if (num_online_cpus() > 1 && !parisc_requires_coherency()) {
102     + threshold = max(cache_info.it_size, cache_info.dt_size);
103     + threshold *= PAGE_SIZE;
104     + threshold /= num_online_cpus();
105     + goto set_tlb_threshold;
106     + }
107     +
108     alltime = mfctl(16);
109     flush_tlb_all();
110     alltime = mfctl(16) - alltime;
111     @@ -393,6 +402,8 @@ void __init parisc_setup_cache_timing(void)
112     alltime, size, rangetime);
113    
114     threshold = PAGE_ALIGN(num_online_cpus() * size * alltime / rangetime);
115     +
116     +set_tlb_threshold:
117     if (threshold)
118     parisc_tlb_flush_threshold = threshold;
119     printk(KERN_INFO "TLB flush threshold set to %lu KiB\n",
120     diff --git a/arch/parisc/kernel/pacache.S b/arch/parisc/kernel/pacache.S
121     index 675521919229..a4761b772406 100644
122     --- a/arch/parisc/kernel/pacache.S
123     +++ b/arch/parisc/kernel/pacache.S
124     @@ -886,19 +886,10 @@ ENTRY(flush_dcache_page_asm)
125     fdc,m r31(%r28)
126     fdc,m r31(%r28)
127     fdc,m r31(%r28)
128     - cmpb,COND(<<) %r28, %r25,1b
129     + cmpb,COND(<<) %r28, %r25,1b
130     fdc,m r31(%r28)
131    
132     sync
133     -
134     -#ifdef CONFIG_PA20
135     - pdtlb,l %r0(%r25)
136     -#else
137     - tlb_lock %r20,%r21,%r22
138     - pdtlb %r0(%r25)
139     - tlb_unlock %r20,%r21,%r22
140     -#endif
141     -
142     bv %r0(%r2)
143     nop
144     .exit
145     @@ -973,17 +964,6 @@ ENTRY(flush_icache_page_asm)
146     fic,m %r31(%sr4,%r28)
147    
148     sync
149     -
150     -#ifdef CONFIG_PA20
151     - pdtlb,l %r0(%r28)
152     - pitlb,l %r0(%sr4,%r25)
153     -#else
154     - tlb_lock %r20,%r21,%r22
155     - pdtlb %r0(%r28)
156     - pitlb %r0(%sr4,%r25)
157     - tlb_unlock %r20,%r21,%r22
158     -#endif
159     -
160     bv %r0(%r2)
161     nop
162     .exit
163     diff --git a/arch/powerpc/kernel/eeh_driver.c b/arch/powerpc/kernel/eeh_driver.c
164     index c07bfb52275e..300382e5a2cc 100644
165     --- a/arch/powerpc/kernel/eeh_driver.c
166     +++ b/arch/powerpc/kernel/eeh_driver.c
167     @@ -612,8 +612,10 @@ static int eeh_reset_device(struct eeh_pe *pe, struct pci_bus *bus)
168    
169     /* Clear frozen state */
170     rc = eeh_clear_pe_frozen_state(pe, false);
171     - if (rc)
172     + if (rc) {
173     + pci_unlock_rescan_remove();
174     return rc;
175     + }
176    
177     /* Give the system 5 seconds to finish running the user-space
178     * hotplug shutdown scripts, e.g. ifdown for ethernet. Yes,
179     diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c
180     index a3aeb2cc361e..1a8256dd6729 100644
181     --- a/arch/x86/kernel/cpu/perf_event.c
182     +++ b/arch/x86/kernel/cpu/perf_event.c
183     @@ -67,7 +67,7 @@ u64 x86_perf_event_update(struct perf_event *event)
184     int shift = 64 - x86_pmu.cntval_bits;
185     u64 prev_raw_count, new_raw_count;
186     int idx = hwc->idx;
187     - s64 delta;
188     + u64 delta;
189    
190     if (idx == INTEL_PMC_IDX_FIXED_BTS)
191     return 0;
192     diff --git a/arch/x86/kernel/cpu/perf_event_intel.c b/arch/x86/kernel/cpu/perf_event_intel.c
193     index 5f82cd59f0e5..5cc2242d77c6 100644
194     --- a/arch/x86/kernel/cpu/perf_event_intel.c
195     +++ b/arch/x86/kernel/cpu/perf_event_intel.c
196     @@ -3636,7 +3636,7 @@ __init int intel_pmu_init(void)
197    
198     /* Support full width counters using alternative MSR range */
199     if (x86_pmu.intel_cap.full_width_write) {
200     - x86_pmu.max_period = x86_pmu.cntval_mask;
201     + x86_pmu.max_period = x86_pmu.cntval_mask >> 1;
202     x86_pmu.perfctr = MSR_IA32_PMC0;
203     pr_cont("full-width counters, ");
204     }
205     diff --git a/crypto/Makefile b/crypto/Makefile
206     index f7aba923458d..82fbff180ad3 100644
207     --- a/crypto/Makefile
208     +++ b/crypto/Makefile
209     @@ -33,6 +33,7 @@ obj-$(CONFIG_CRYPTO_AKCIPHER2) += akcipher.o
210    
211     $(obj)/rsapubkey-asn1.o: $(obj)/rsapubkey-asn1.c $(obj)/rsapubkey-asn1.h
212     $(obj)/rsaprivkey-asn1.o: $(obj)/rsaprivkey-asn1.c $(obj)/rsaprivkey-asn1.h
213     +$(obj)/rsa_helper.o: $(obj)/rsapubkey-asn1.h $(obj)/rsaprivkey-asn1.h
214     clean-files += rsapubkey-asn1.c rsapubkey-asn1.h
215     clean-files += rsaprivkey-asn1.c rsaprivkey-asn1.h
216    
217     diff --git a/crypto/mcryptd.c b/crypto/mcryptd.c
218     index fe5b495a434d..a0ceb41d5ccc 100644
219     --- a/crypto/mcryptd.c
220     +++ b/crypto/mcryptd.c
221     @@ -258,18 +258,22 @@ out_free_inst:
222     goto out;
223     }
224    
225     -static inline void mcryptd_check_internal(struct rtattr **tb, u32 *type,
226     +static inline bool mcryptd_check_internal(struct rtattr **tb, u32 *type,
227     u32 *mask)
228     {
229     struct crypto_attr_type *algt;
230    
231     algt = crypto_get_attr_type(tb);
232     if (IS_ERR(algt))
233     - return;
234     - if ((algt->type & CRYPTO_ALG_INTERNAL))
235     - *type |= CRYPTO_ALG_INTERNAL;
236     - if ((algt->mask & CRYPTO_ALG_INTERNAL))
237     - *mask |= CRYPTO_ALG_INTERNAL;
238     + return false;
239     +
240     + *type |= algt->type & CRYPTO_ALG_INTERNAL;
241     + *mask |= algt->mask & CRYPTO_ALG_INTERNAL;
242     +
243     + if (*type & *mask & CRYPTO_ALG_INTERNAL)
244     + return true;
245     + else
246     + return false;
247     }
248    
249     static int mcryptd_hash_init_tfm(struct crypto_tfm *tfm)
250     @@ -498,7 +502,8 @@ static int mcryptd_create_hash(struct crypto_template *tmpl, struct rtattr **tb,
251     u32 mask = 0;
252     int err;
253    
254     - mcryptd_check_internal(tb, &type, &mask);
255     + if (!mcryptd_check_internal(tb, &type, &mask))
256     + return -EINVAL;
257    
258     salg = shash_attr_alg(tb[1], type, mask);
259     if (IS_ERR(salg))
260     diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c
261     index 1770c455dfdd..1648de80e230 100644
262     --- a/drivers/block/zram/zram_drv.c
263     +++ b/drivers/block/zram/zram_drv.c
264     @@ -1378,8 +1378,14 @@ static ssize_t hot_remove_store(struct class *class,
265     return ret ? ret : count;
266     }
267    
268     +/*
269     + * NOTE: hot_add attribute is not the usual read-only sysfs attribute. In a
270     + * sense that reading from this file does alter the state of your system -- it
271     + * creates a new un-initialized zram device and returns back this device's
272     + * device_id (or an error code if it fails to create a new device).
273     + */
274     static struct class_attribute zram_control_class_attrs[] = {
275     - __ATTR_RO(hot_add),
276     + __ATTR(hot_add, 0400, hot_add_show, NULL),
277     __ATTR_WO(hot_remove),
278     __ATTR_NULL,
279     };
280     diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_core.c b/drivers/net/can/usb/peak_usb/pcan_usb_core.c
281     index 5a2e341a6d1e..91be4575b524 100644
282     --- a/drivers/net/can/usb/peak_usb/pcan_usb_core.c
283     +++ b/drivers/net/can/usb/peak_usb/pcan_usb_core.c
284     @@ -872,23 +872,25 @@ lbl_free_candev:
285     static void peak_usb_disconnect(struct usb_interface *intf)
286     {
287     struct peak_usb_device *dev;
288     + struct peak_usb_device *dev_prev_siblings;
289    
290     /* unregister as many netdev devices as siblings */
291     - for (dev = usb_get_intfdata(intf); dev; dev = dev->prev_siblings) {
292     + for (dev = usb_get_intfdata(intf); dev; dev = dev_prev_siblings) {
293     struct net_device *netdev = dev->netdev;
294     char name[IFNAMSIZ];
295    
296     + dev_prev_siblings = dev->prev_siblings;
297     dev->state &= ~PCAN_USB_STATE_CONNECTED;
298     strncpy(name, netdev->name, IFNAMSIZ);
299    
300     unregister_netdev(netdev);
301     - free_candev(netdev);
302    
303     kfree(dev->cmd_buf);
304     dev->next_siblings = NULL;
305     if (dev->adapter->dev_free)
306     dev->adapter->dev_free(dev);
307    
308     + free_candev(netdev);
309     dev_info(&intf->dev, "%s removed\n", name);
310     }
311    
312     diff --git a/include/linux/cpu.h b/include/linux/cpu.h
313     index d2ca8c38f9c4..3ea9aae2387d 100644
314     --- a/include/linux/cpu.h
315     +++ b/include/linux/cpu.h
316     @@ -131,22 +131,16 @@ enum {
317     { .notifier_call = fn, .priority = pri }; \
318     __register_cpu_notifier(&fn##_nb); \
319     }
320     -#else /* #if defined(CONFIG_HOTPLUG_CPU) || !defined(MODULE) */
321     -#define cpu_notifier(fn, pri) do { (void)(fn); } while (0)
322     -#define __cpu_notifier(fn, pri) do { (void)(fn); } while (0)
323     -#endif /* #else #if defined(CONFIG_HOTPLUG_CPU) || !defined(MODULE) */
324    
325     -#ifdef CONFIG_HOTPLUG_CPU
326     extern int register_cpu_notifier(struct notifier_block *nb);
327     extern int __register_cpu_notifier(struct notifier_block *nb);
328     extern void unregister_cpu_notifier(struct notifier_block *nb);
329     extern void __unregister_cpu_notifier(struct notifier_block *nb);
330     -#else
331    
332     -#ifndef MODULE
333     -extern int register_cpu_notifier(struct notifier_block *nb);
334     -extern int __register_cpu_notifier(struct notifier_block *nb);
335     -#else
336     +#else /* #if defined(CONFIG_HOTPLUG_CPU) || !defined(MODULE) */
337     +#define cpu_notifier(fn, pri) do { (void)(fn); } while (0)
338     +#define __cpu_notifier(fn, pri) do { (void)(fn); } while (0)
339     +
340     static inline int register_cpu_notifier(struct notifier_block *nb)
341     {
342     return 0;
343     @@ -156,7 +150,6 @@ static inline int __register_cpu_notifier(struct notifier_block *nb)
344     {
345     return 0;
346     }
347     -#endif
348    
349     static inline void unregister_cpu_notifier(struct notifier_block *nb)
350     {
351     diff --git a/include/uapi/linux/can.h b/include/uapi/linux/can.h
352     index 9692cda5f8fc..c48d93a28d1a 100644
353     --- a/include/uapi/linux/can.h
354     +++ b/include/uapi/linux/can.h
355     @@ -196,5 +196,6 @@ struct can_filter {
356     };
357    
358     #define CAN_INV_FILTER 0x20000000U /* to be set in can_filter.can_id */
359     +#define CAN_RAW_FILTER_MAX 512 /* maximum number of can_filter set via setsockopt() */
360    
361     #endif /* !_UAPI_CAN_H */
362     diff --git a/kernel/cpu.c b/kernel/cpu.c
363     index 85ff5e26e23b..cd6d1258554e 100644
364     --- a/kernel/cpu.c
365     +++ b/kernel/cpu.c
366     @@ -223,8 +223,6 @@ static int cpu_notify(unsigned long val, void *v)
367     return __cpu_notify(val, v, -1, NULL);
368     }
369    
370     -#ifdef CONFIG_HOTPLUG_CPU
371     -
372     static void cpu_notify_nofail(unsigned long val, void *v)
373     {
374     BUG_ON(cpu_notify(val, v));
375     @@ -246,6 +244,7 @@ void __unregister_cpu_notifier(struct notifier_block *nb)
376     }
377     EXPORT_SYMBOL(__unregister_cpu_notifier);
378    
379     +#ifdef CONFIG_HOTPLUG_CPU
380     /**
381     * clear_tasks_mm_cpumask - Safely clear tasks' mm_cpumask for a CPU
382     * @cpu: a CPU id
383     diff --git a/kernel/locking/rtmutex.c b/kernel/locking/rtmutex.c
384     index 8251e75dd9c0..b066724d7a5b 100644
385     --- a/kernel/locking/rtmutex.c
386     +++ b/kernel/locking/rtmutex.c
387     @@ -65,8 +65,72 @@ static inline void clear_rt_mutex_waiters(struct rt_mutex *lock)
388    
389     static void fixup_rt_mutex_waiters(struct rt_mutex *lock)
390     {
391     - if (!rt_mutex_has_waiters(lock))
392     - clear_rt_mutex_waiters(lock);
393     + unsigned long owner, *p = (unsigned long *) &lock->owner;
394     +
395     + if (rt_mutex_has_waiters(lock))
396     + return;
397     +
398     + /*
399     + * The rbtree has no waiters enqueued, now make sure that the
400     + * lock->owner still has the waiters bit set, otherwise the
401     + * following can happen:
402     + *
403     + * CPU 0 CPU 1 CPU2
404     + * l->owner=T1
405     + * rt_mutex_lock(l)
406     + * lock(l->lock)
407     + * l->owner = T1 | HAS_WAITERS;
408     + * enqueue(T2)
409     + * boost()
410     + * unlock(l->lock)
411     + * block()
412     + *
413     + * rt_mutex_lock(l)
414     + * lock(l->lock)
415     + * l->owner = T1 | HAS_WAITERS;
416     + * enqueue(T3)
417     + * boost()
418     + * unlock(l->lock)
419     + * block()
420     + * signal(->T2) signal(->T3)
421     + * lock(l->lock)
422     + * dequeue(T2)
423     + * deboost()
424     + * unlock(l->lock)
425     + * lock(l->lock)
426     + * dequeue(T3)
427     + * ==> wait list is empty
428     + * deboost()
429     + * unlock(l->lock)
430     + * lock(l->lock)
431     + * fixup_rt_mutex_waiters()
432     + * if (wait_list_empty(l) {
433     + * l->owner = owner
434     + * owner = l->owner & ~HAS_WAITERS;
435     + * ==> l->owner = T1
436     + * }
437     + * lock(l->lock)
438     + * rt_mutex_unlock(l) fixup_rt_mutex_waiters()
439     + * if (wait_list_empty(l) {
440     + * owner = l->owner & ~HAS_WAITERS;
441     + * cmpxchg(l->owner, T1, NULL)
442     + * ===> Success (l->owner = NULL)
443     + *
444     + * l->owner = owner
445     + * ==> l->owner = T1
446     + * }
447     + *
448     + * With the check for the waiter bit in place T3 on CPU2 will not
449     + * overwrite. All tasks fiddling with the waiters bit are
450     + * serialized by l->lock, so nothing else can modify the waiters
451     + * bit. If the bit is set then nothing can change l->owner either
452     + * so the simple RMW is safe. The cmpxchg() will simply fail if it
453     + * happens in the middle of the RMW because the waiters bit is
454     + * still set.
455     + */
456     + owner = READ_ONCE(*p);
457     + if (owner & RT_MUTEX_HAS_WAITERS)
458     + WRITE_ONCE(*p, owner & ~RT_MUTEX_HAS_WAITERS);
459     }
460    
461     /*
462     diff --git a/kernel/locking/rtmutex_common.h b/kernel/locking/rtmutex_common.h
463     index 4f5f83c7d2d3..e317e1cbb3eb 100644
464     --- a/kernel/locking/rtmutex_common.h
465     +++ b/kernel/locking/rtmutex_common.h
466     @@ -75,8 +75,9 @@ task_top_pi_waiter(struct task_struct *p)
467    
468     static inline struct task_struct *rt_mutex_owner(struct rt_mutex *lock)
469     {
470     - return (struct task_struct *)
471     - ((unsigned long)lock->owner & ~RT_MUTEX_OWNER_MASKALL);
472     + unsigned long owner = (unsigned long) READ_ONCE(lock->owner);
473     +
474     + return (struct task_struct *) (owner & ~RT_MUTEX_OWNER_MASKALL);
475     }
476    
477     /*
478     diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c
479     index 83b0ca27a45e..f2079acb555d 100644
480     --- a/net/batman-adv/translation-table.c
481     +++ b/net/batman-adv/translation-table.c
482     @@ -2764,7 +2764,7 @@ static bool batadv_send_my_tt_response(struct batadv_priv *bat_priv,
483     &tvlv_tt_data,
484     &tt_change,
485     &tt_len);
486     - if (!tt_len)
487     + if (!tt_len || !tvlv_len)
488     goto unlock;
489    
490     /* Copy the last orig_node's OGM buffer */
491     @@ -2782,7 +2782,7 @@ static bool batadv_send_my_tt_response(struct batadv_priv *bat_priv,
492     &tvlv_tt_data,
493     &tt_change,
494     &tt_len);
495     - if (!tt_len)
496     + if (!tt_len || !tvlv_len)
497     goto out;
498    
499     /* fill the rest of the tvlv with the real TT entries */
500     diff --git a/net/can/raw.c b/net/can/raw.c
501     index 2e67b1423cd3..56af689ca999 100644
502     --- a/net/can/raw.c
503     +++ b/net/can/raw.c
504     @@ -499,6 +499,9 @@ static int raw_setsockopt(struct socket *sock, int level, int optname,
505     if (optlen % sizeof(struct can_filter) != 0)
506     return -EINVAL;
507    
508     + if (optlen > CAN_RAW_FILTER_MAX * sizeof(struct can_filter))
509     + return -EINVAL;
510     +
511     count = optlen / sizeof(struct can_filter);
512    
513     if (count > 1) {