From d11f37ce9f7d19cebae5f512669593ee9798622b Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 8 May 2018 09:23:05 +0200 Subject: [PATCH] 4.16-stable patches added patches: clocksource-allow-clocksource_mark_unstable-on-unregistered-clocksources.patch clocksource-consistent-de-rate-when-marking-unstable.patch clocksource-initialize-cs-wd_list.patch irqchip-qcom-fix-check-for-spurious-interrupts.patch kvm-x86-remove-apic-timer-periodic-oneshot-spikes.patch platform-x86-asus-wireless-fix-null-pointer-dereference.patch platform-x86-kconfig-fix-dell-laptop-dependency-chain.patch tracing-fix-bad-use-of-igrab-in-trace_uprobe.c.patch usb-accept-bulk-endpoints-with-1024-byte-maxpacket.patch usb-dwc3-gadget-fix-list_del-corruption-in-dwc3_ep_dequeue.patch usb-musb-host-fix-potential-null-pointer-dereference.patch usb-musb-trace-fix-null-pointer-dereference-in-musb_g_tx.patch usb-serial-option-adding-support-for-ublox-r410m.patch usb-serial-option-reimplement-interface-masking.patch usb-serial-visor-handle-potential-invalid-device-configuration.patch x86-tsc-always-unregister-clocksource_tsc_early.patch x86-tsc-fix-mark_tsc_unstable.patch xhci-fix-use-after-free-in-xhci_free_virt_device.patch --- ...nstable-on-unregistered-clocksources.patch | 213 +++++ ...istent-de-rate-when-marking-unstable.patch | 51 ++ .../clocksource-initialize-cs-wd_list.patch | 40 + ...om-fix-check-for-spurious-interrupts.patch | 49 + ...e-apic-timer-periodic-oneshot-spikes.patch | 106 +++ ...ireless-fix-null-pointer-dereference.patch | 95 ++ ...fig-fix-dell-laptop-dependency-chain.patch | 49 + queue-4.16/series | 18 + ...x-bad-use-of-igrab-in-trace_uprobe.c.patch | 149 +++ ...k-endpoints-with-1024-byte-maxpacket.patch | 42 + ...st_del-corruption-in-dwc3_ep_dequeue.patch | 44 + ...x-potential-null-pointer-dereference.patch | 38 + ...ull-pointer-dereference-in-musb_g_tx.patch | 44 + ...ption-adding-support-for-ublox-r410m.patch | 52 ++ ...option-reimplement-interface-masking.patch | 857 ++++++++++++++++++ ...tential-invalid-device-configuration.patch | 115 +++ ...ays-unregister-clocksource_tsc_early.patch | 77 ++ .../x86-tsc-fix-mark_tsc_unstable.patch | 67 ++ ...-after-free-in-xhci_free_virt_device.patch | 45 + 19 files changed, 2151 insertions(+) create mode 100644 queue-4.16/clocksource-allow-clocksource_mark_unstable-on-unregistered-clocksources.patch create mode 100644 queue-4.16/clocksource-consistent-de-rate-when-marking-unstable.patch create mode 100644 queue-4.16/clocksource-initialize-cs-wd_list.patch create mode 100644 queue-4.16/irqchip-qcom-fix-check-for-spurious-interrupts.patch create mode 100644 queue-4.16/kvm-x86-remove-apic-timer-periodic-oneshot-spikes.patch create mode 100644 queue-4.16/platform-x86-asus-wireless-fix-null-pointer-dereference.patch create mode 100644 queue-4.16/platform-x86-kconfig-fix-dell-laptop-dependency-chain.patch create mode 100644 queue-4.16/tracing-fix-bad-use-of-igrab-in-trace_uprobe.c.patch create mode 100644 queue-4.16/usb-accept-bulk-endpoints-with-1024-byte-maxpacket.patch create mode 100644 queue-4.16/usb-dwc3-gadget-fix-list_del-corruption-in-dwc3_ep_dequeue.patch create mode 100644 queue-4.16/usb-musb-host-fix-potential-null-pointer-dereference.patch create mode 100644 queue-4.16/usb-musb-trace-fix-null-pointer-dereference-in-musb_g_tx.patch create mode 100644 queue-4.16/usb-serial-option-adding-support-for-ublox-r410m.patch create mode 100644 queue-4.16/usb-serial-option-reimplement-interface-masking.patch create mode 100644 queue-4.16/usb-serial-visor-handle-potential-invalid-device-configuration.patch create mode 100644 queue-4.16/x86-tsc-always-unregister-clocksource_tsc_early.patch create mode 100644 queue-4.16/x86-tsc-fix-mark_tsc_unstable.patch create mode 100644 queue-4.16/xhci-fix-use-after-free-in-xhci_free_virt_device.patch diff --git a/queue-4.16/clocksource-allow-clocksource_mark_unstable-on-unregistered-clocksources.patch b/queue-4.16/clocksource-allow-clocksource_mark_unstable-on-unregistered-clocksources.patch new file mode 100644 index 00000000000..f56288b027c --- /dev/null +++ b/queue-4.16/clocksource-allow-clocksource_mark_unstable-on-unregistered-clocksources.patch @@ -0,0 +1,213 @@ +From 2aae7bcfa4104b770e6f612356adb8d66c6144d6 Mon Sep 17 00:00:00 2001 +From: Peter Zijlstra +Date: Mon, 23 Apr 2018 17:28:55 +0200 +Subject: clocksource: Allow clocksource_mark_unstable() on unregistered clocksources + +From: Peter Zijlstra + +commit 2aae7bcfa4104b770e6f612356adb8d66c6144d6 upstream. + +Because of how the code flips between tsc-early and tsc clocksources +it might need to mark one or both unstable. The current code in +mark_tsc_unstable() only worked because previously it registered the +tsc clocksource once and then never touched it. + +Since it now unregisters the tsc-early clocksource, it needs to know +if a clocksource got unregistered and the current cs->mult test +doesn't work for that. Instead use list_empty(&cs->list) to test for +registration. + +Furthermore, since clocksource_mark_unstable() needs to place the cs +on the wd_list, it links the cs->list and cs->wd_list serialization. +It must not see a clocsource registered (!empty cs->list) but already +past dequeue_watchdog(). So place {en,de}queue{,_watchdog}() under the +same lock. + +Provided cs->list is initialized to empty, this then allows us to +unconditionally use clocksource_mark_unstable(), regardless of the +registration state. + +Fixes: aa83c45762a2 ("x86/tsc: Introduce early tsc clocksource") +Signed-off-by: Peter Zijlstra (Intel) +Signed-off-by: Thomas Gleixner +Reviewed-by: Rafael J. Wysocki +Tested-by: Diego Viola +Cc: len.brown@intel.com +Cc: rjw@rjwysocki.net +Cc: diego.viola@gmail.com +Cc: rui.zhang@intel.com +Cc: stable@vger.kernel.org +Link: https://lkml.kernel.org/r/20180502135312.GS12217@hirez.programming.kicks-ass.net +Signed-off-by: Greg Kroah-Hartman + +--- + kernel/time/clocksource.c | 50 +++++++++++++++++++++++++++++++--------------- + 1 file changed, 34 insertions(+), 16 deletions(-) + +--- a/kernel/time/clocksource.c ++++ b/kernel/time/clocksource.c +@@ -119,6 +119,16 @@ static DEFINE_SPINLOCK(watchdog_lock); + static int watchdog_running; + static atomic_t watchdog_reset_pending; + ++static void inline clocksource_watchdog_lock(unsigned long *flags) ++{ ++ spin_lock_irqsave(&watchdog_lock, *flags); ++} ++ ++static void inline clocksource_watchdog_unlock(unsigned long *flags) ++{ ++ spin_unlock_irqrestore(&watchdog_lock, *flags); ++} ++ + static int clocksource_watchdog_kthread(void *data); + static void __clocksource_change_rating(struct clocksource *cs, int rating); + +@@ -142,6 +152,9 @@ static void __clocksource_unstable(struc + cs->flags &= ~(CLOCK_SOURCE_VALID_FOR_HRES | CLOCK_SOURCE_WATCHDOG); + cs->flags |= CLOCK_SOURCE_UNSTABLE; + ++ if (list_empty(&cs->list)) ++ return; ++ + if (cs->mark_unstable) + cs->mark_unstable(cs); + +@@ -164,7 +177,7 @@ void clocksource_mark_unstable(struct cl + + spin_lock_irqsave(&watchdog_lock, flags); + if (!(cs->flags & CLOCK_SOURCE_UNSTABLE)) { +- if (list_empty(&cs->wd_list)) ++ if (!list_empty(&cs->list) && list_empty(&cs->wd_list)) + list_add(&cs->wd_list, &watchdog_list); + __clocksource_unstable(cs); + } +@@ -319,9 +332,6 @@ static void clocksource_resume_watchdog( + + static void clocksource_enqueue_watchdog(struct clocksource *cs) + { +- unsigned long flags; +- +- spin_lock_irqsave(&watchdog_lock, flags); + if (cs->flags & CLOCK_SOURCE_MUST_VERIFY) { + /* cs is a clocksource to be watched. */ + list_add(&cs->wd_list, &watchdog_list); +@@ -331,7 +341,6 @@ static void clocksource_enqueue_watchdog + if (cs->flags & CLOCK_SOURCE_IS_CONTINUOUS) + cs->flags |= CLOCK_SOURCE_VALID_FOR_HRES; + } +- spin_unlock_irqrestore(&watchdog_lock, flags); + } + + static void clocksource_select_watchdog(bool fallback) +@@ -373,9 +382,6 @@ static void clocksource_select_watchdog( + + static void clocksource_dequeue_watchdog(struct clocksource *cs) + { +- unsigned long flags; +- +- spin_lock_irqsave(&watchdog_lock, flags); + if (cs != watchdog) { + if (cs->flags & CLOCK_SOURCE_MUST_VERIFY) { + /* cs is a watched clocksource. */ +@@ -384,21 +390,19 @@ static void clocksource_dequeue_watchdog + clocksource_stop_watchdog(); + } + } +- spin_unlock_irqrestore(&watchdog_lock, flags); + } + + static int __clocksource_watchdog_kthread(void) + { + struct clocksource *cs, *tmp; + unsigned long flags; +- LIST_HEAD(unstable); + int select = 0; + + spin_lock_irqsave(&watchdog_lock, flags); + list_for_each_entry_safe(cs, tmp, &watchdog_list, wd_list) { + if (cs->flags & CLOCK_SOURCE_UNSTABLE) { + list_del_init(&cs->wd_list); +- list_add(&cs->wd_list, &unstable); ++ __clocksource_change_rating(cs, 0); + select = 1; + } + if (cs->flags & CLOCK_SOURCE_RESELECT) { +@@ -410,11 +414,6 @@ static int __clocksource_watchdog_kthrea + clocksource_stop_watchdog(); + spin_unlock_irqrestore(&watchdog_lock, flags); + +- /* Needs to be done outside of watchdog lock */ +- list_for_each_entry_safe(cs, tmp, &unstable, wd_list) { +- list_del_init(&cs->wd_list); +- __clocksource_change_rating(cs, 0); +- } + return select; + } + +@@ -447,6 +446,9 @@ static inline int __clocksource_watchdog + static bool clocksource_is_watchdog(struct clocksource *cs) { return false; } + void clocksource_mark_unstable(struct clocksource *cs) { } + ++static void inline clocksource_watchdog_lock(unsigned long *flags) { } ++static void inline clocksource_watchdog_unlock(unsigned long *flags) { } ++ + #endif /* CONFIG_CLOCKSOURCE_WATCHDOG */ + + /** +@@ -775,14 +777,19 @@ EXPORT_SYMBOL_GPL(__clocksource_update_f + */ + int __clocksource_register_scale(struct clocksource *cs, u32 scale, u32 freq) + { ++ unsigned long flags; + + /* Initialize mult/shift and max_idle_ns */ + __clocksource_update_freq_scale(cs, scale, freq); + + /* Add clocksource to the clocksource list */ + mutex_lock(&clocksource_mutex); ++ ++ clocksource_watchdog_lock(&flags); + clocksource_enqueue(cs); + clocksource_enqueue_watchdog(cs); ++ clocksource_watchdog_unlock(&flags); ++ + clocksource_select(); + clocksource_select_watchdog(false); + mutex_unlock(&clocksource_mutex); +@@ -804,8 +811,13 @@ static void __clocksource_change_rating( + */ + void clocksource_change_rating(struct clocksource *cs, int rating) + { ++ unsigned long flags; ++ + mutex_lock(&clocksource_mutex); ++ clocksource_watchdog_lock(&flags); + __clocksource_change_rating(cs, rating); ++ clocksource_watchdog_unlock(&flags); ++ + clocksource_select(); + clocksource_select_watchdog(false); + mutex_unlock(&clocksource_mutex); +@@ -817,6 +829,8 @@ EXPORT_SYMBOL(clocksource_change_rating) + */ + static int clocksource_unbind(struct clocksource *cs) + { ++ unsigned long flags; ++ + if (clocksource_is_watchdog(cs)) { + /* Select and try to install a replacement watchdog. */ + clocksource_select_watchdog(true); +@@ -830,8 +844,12 @@ static int clocksource_unbind(struct clo + if (curr_clocksource == cs) + return -EBUSY; + } ++ ++ clocksource_watchdog_lock(&flags); + clocksource_dequeue_watchdog(cs); + list_del_init(&cs->list); ++ clocksource_watchdog_unlock(&flags); ++ + return 0; + } + diff --git a/queue-4.16/clocksource-consistent-de-rate-when-marking-unstable.patch b/queue-4.16/clocksource-consistent-de-rate-when-marking-unstable.patch new file mode 100644 index 00000000000..26007d3d46b --- /dev/null +++ b/queue-4.16/clocksource-consistent-de-rate-when-marking-unstable.patch @@ -0,0 +1,51 @@ +From cd2af07d823e5287cd6c91d54337348c2a873462 Mon Sep 17 00:00:00 2001 +From: Peter Zijlstra +Date: Mon, 30 Apr 2018 12:00:13 +0200 +Subject: clocksource: Consistent de-rate when marking unstable + +From: Peter Zijlstra + +commit cd2af07d823e5287cd6c91d54337348c2a873462 upstream. + +When a registered clocksource gets marked unstable the watchdog_kthread +will de-rate and re-select the clocksource. Ensure it also de-rates +when getting called on an unregistered clocksource. + +Signed-off-by: Peter Zijlstra (Intel) +Signed-off-by: Thomas Gleixner +Reviewed-by: Rafael J. Wysocki +Cc: len.brown@intel.com +Cc: rjw@rjwysocki.net +Cc: diego.viola@gmail.com +Cc: rui.zhang@intel.com +Cc: stable@vger.kernel.org +Link: https://lkml.kernel.org/r/20180430100344.594904898@infradead.org +Signed-off-by: Greg Kroah-Hartman + +--- + kernel/time/clocksource.c | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +--- a/kernel/time/clocksource.c ++++ b/kernel/time/clocksource.c +@@ -152,12 +152,19 @@ static void __clocksource_unstable(struc + cs->flags &= ~(CLOCK_SOURCE_VALID_FOR_HRES | CLOCK_SOURCE_WATCHDOG); + cs->flags |= CLOCK_SOURCE_UNSTABLE; + +- if (list_empty(&cs->list)) ++ /* ++ * If the clocksource is registered clocksource_watchdog_kthread() will ++ * re-rate and re-select. ++ */ ++ if (list_empty(&cs->list)) { ++ cs->rating = 0; + return; ++ } + + if (cs->mark_unstable) + cs->mark_unstable(cs); + ++ /* kick clocksource_watchdog_kthread() */ + if (finished_booting) + schedule_work(&watchdog_work); + } diff --git a/queue-4.16/clocksource-initialize-cs-wd_list.patch b/queue-4.16/clocksource-initialize-cs-wd_list.patch new file mode 100644 index 00000000000..8c1dd0a9e4c --- /dev/null +++ b/queue-4.16/clocksource-initialize-cs-wd_list.patch @@ -0,0 +1,40 @@ +From 5b9e886a4af97574ca3ce1147f35545da0e7afc7 Mon Sep 17 00:00:00 2001 +From: Peter Zijlstra +Date: Mon, 30 Apr 2018 12:00:11 +0200 +Subject: clocksource: Initialize cs->wd_list + +From: Peter Zijlstra + +commit 5b9e886a4af97574ca3ce1147f35545da0e7afc7 upstream. + +A number of places relies on list_empty(&cs->wd_list), however the +list_head does not get initialized. Do so upon registration, such that +thereafter it is possible to rely on list_empty() correctly reflecting +the list membership status. + +Signed-off-by: Peter Zijlstra (Intel) +Signed-off-by: Thomas Gleixner +Tested-by: Diego Viola +Reviewed-by: Rafael J. Wysocki +Cc: stable@vger.kernel.org +Cc: len.brown@intel.com +Cc: rjw@rjwysocki.net +Cc: rui.zhang@intel.com +Link: https://lkml.kernel.org/r/20180430100344.472662715@infradead.org +Signed-off-by: Greg Kroah-Hartman + +--- + kernel/time/clocksource.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/kernel/time/clocksource.c ++++ b/kernel/time/clocksource.c +@@ -332,6 +332,8 @@ static void clocksource_resume_watchdog( + + static void clocksource_enqueue_watchdog(struct clocksource *cs) + { ++ INIT_LIST_HEAD(&cs->wd_list); ++ + if (cs->flags & CLOCK_SOURCE_MUST_VERIFY) { + /* cs is a clocksource to be watched. */ + list_add(&cs->wd_list, &watchdog_list); diff --git a/queue-4.16/irqchip-qcom-fix-check-for-spurious-interrupts.patch b/queue-4.16/irqchip-qcom-fix-check-for-spurious-interrupts.patch new file mode 100644 index 00000000000..d1c53532062 --- /dev/null +++ b/queue-4.16/irqchip-qcom-fix-check-for-spurious-interrupts.patch @@ -0,0 +1,49 @@ +From 1bc2463cee92ef0e2034c813d5e511adeb58b5fd Mon Sep 17 00:00:00 2001 +From: Agustin Vega-Frias +Date: Tue, 1 May 2018 10:14:50 -0400 +Subject: irqchip/qcom: Fix check for spurious interrupts + +From: Agustin Vega-Frias + +commit 1bc2463cee92ef0e2034c813d5e511adeb58b5fd upstream. + +When the interrupts for a combiner span multiple registers it must be +checked if any interrupts have been asserted on each register before +checking for spurious interrupts. + +Checking each register seperately leads to false positive warnings. + +[ tglx: Massaged changelog ] + +Fixes: f20cc9b00c7b ("irqchip/qcom: Add IRQ combiner driver") +Signed-off-by: Agustin Vega-Frias +Signed-off-by: Thomas Gleixner +Cc: Jason Cooper +Cc: Marc Zyngier +Cc: timur@codeaurora.org +Cc: linux-arm-kernel@lists.infradead.org +Cc: stable@vger.kernel.org +Link: https://lkml.kernel.org/r/1525184090-26143-1-git-send-email-agustinv@codeaurora.org +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/irqchip/qcom-irq-combiner.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/irqchip/qcom-irq-combiner.c ++++ b/drivers/irqchip/qcom-irq-combiner.c +@@ -1,4 +1,4 @@ +-/* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved. ++/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and +@@ -68,7 +68,7 @@ static void combiner_handle_irq(struct i + + bit = readl_relaxed(combiner->regs[reg].addr); + status = bit & combiner->regs[reg].enabled; +- if (!status) ++ if (bit && !status) + pr_warn_ratelimited("Unexpected IRQ on CPU%d: (%08x %08lx %p)\n", + smp_processor_id(), bit, + combiner->regs[reg].enabled, diff --git a/queue-4.16/kvm-x86-remove-apic-timer-periodic-oneshot-spikes.patch b/queue-4.16/kvm-x86-remove-apic-timer-periodic-oneshot-spikes.patch new file mode 100644 index 00000000000..4df5db4828d --- /dev/null +++ b/queue-4.16/kvm-x86-remove-apic-timer-periodic-oneshot-spikes.patch @@ -0,0 +1,106 @@ +From ecf08dad723d3e000aecff6c396f54772d124733 Mon Sep 17 00:00:00 2001 +From: Anthoine Bourgeois +Date: Sun, 29 Apr 2018 22:05:58 +0000 +Subject: KVM: x86: remove APIC Timer periodic/oneshot spikes +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Anthoine Bourgeois + +commit ecf08dad723d3e000aecff6c396f54772d124733 upstream. + +Since the commit "8003c9ae204e: add APIC Timer periodic/oneshot mode VMX +preemption timer support", a Windows 10 guest has some erratic timer +spikes. + +Here the results on a 150000 times 1ms timer without any load: + Before 8003c9ae204e | After 8003c9ae204e +Max 1834us | 86000us +Mean 1100us | 1021us +Deviation 59us | 149us +Here the results on a 150000 times 1ms timer with a cpu-z stress test: + Before 8003c9ae204e | After 8003c9ae204e +Max 32000us | 140000us +Mean 1006us | 1997us +Deviation 140us | 11095us + +The root cause of the problem is starting hrtimer with an expiry time +already in the past can take more than 20 milliseconds to trigger the +timer function. It can be solved by forward such past timers +immediately, rather than submitting them to hrtimer_start(). +In case the timer is periodic, update the target expiration and call +hrtimer_start with it. + +v2: Check if the tsc deadline is already expired. Thank you Mika. +v3: Execute the past timers immediately rather than submitting them to +hrtimer_start(). +v4: Rearm the periodic timer with advance_periodic_target_expiration() a +simpler version of set_target_expiration(). Thank you Paolo. + +Cc: Mika Penttilä +Cc: Wanpeng Li +Cc: Paolo Bonzini +Cc: stable@vger.kernel.org +Signed-off-by: Anthoine Bourgeois +8003c9ae204e ("KVM: LAPIC: add APIC Timer periodic/oneshot mode VMX preemption timer support") +Signed-off-by: Radim Krčmář +Signed-off-by: Greg Kroah-Hartman + +--- + arch/x86/kvm/lapic.c | 37 ++++++++++++++++++++----------------- + 1 file changed, 20 insertions(+), 17 deletions(-) + +--- a/arch/x86/kvm/lapic.c ++++ b/arch/x86/kvm/lapic.c +@@ -1455,23 +1455,6 @@ static void start_sw_tscdeadline(struct + local_irq_restore(flags); + } + +-static void start_sw_period(struct kvm_lapic *apic) +-{ +- if (!apic->lapic_timer.period) +- return; +- +- if (apic_lvtt_oneshot(apic) && +- ktime_after(ktime_get(), +- apic->lapic_timer.target_expiration)) { +- apic_timer_expired(apic); +- return; +- } +- +- hrtimer_start(&apic->lapic_timer.timer, +- apic->lapic_timer.target_expiration, +- HRTIMER_MODE_ABS_PINNED); +-} +- + static void update_target_expiration(struct kvm_lapic *apic, uint32_t old_divisor) + { + ktime_t now, remaining; +@@ -1538,6 +1521,26 @@ static void advance_periodic_target_expi + apic->lapic_timer.period); + } + ++static void start_sw_period(struct kvm_lapic *apic) ++{ ++ if (!apic->lapic_timer.period) ++ return; ++ ++ if (ktime_after(ktime_get(), ++ apic->lapic_timer.target_expiration)) { ++ apic_timer_expired(apic); ++ ++ if (apic_lvtt_oneshot(apic)) ++ return; ++ ++ advance_periodic_target_expiration(apic); ++ } ++ ++ hrtimer_start(&apic->lapic_timer.timer, ++ apic->lapic_timer.target_expiration, ++ HRTIMER_MODE_ABS_PINNED); ++} ++ + bool kvm_lapic_hv_timer_in_use(struct kvm_vcpu *vcpu) + { + if (!lapic_in_kernel(vcpu)) diff --git a/queue-4.16/platform-x86-asus-wireless-fix-null-pointer-dereference.patch b/queue-4.16/platform-x86-asus-wireless-fix-null-pointer-dereference.patch new file mode 100644 index 00000000000..dbe68dbf048 --- /dev/null +++ b/queue-4.16/platform-x86-asus-wireless-fix-null-pointer-dereference.patch @@ -0,0 +1,95 @@ +From 9f0a93de9139c2b0a59299cd36b61564522458f8 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Jo=C3=A3o=20Paulo=20Rechi=20Vita?= +Date: Thu, 19 Apr 2018 07:04:34 -0700 +Subject: platform/x86: asus-wireless: Fix NULL pointer dereference +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: João Paulo Rechi Vita + +commit 9f0a93de9139c2b0a59299cd36b61564522458f8 upstream. + +When the module is removed the led workqueue is destroyed in the remove +callback, before the led device is unregistered from the led subsystem. + +This leads to a NULL pointer derefence when the led device is +unregistered automatically later as part of the module removal cleanup. +Bellow is the backtrace showing the problem. + + BUG: unable to handle kernel NULL pointer dereference at (null) + IP: __queue_work+0x8c/0x410 + PGD 0 P4D 0 + Oops: 0000 [#1] SMP NOPTI + Modules linked in: ccm edac_mce_amd kvm_amd kvm irqbypass crct10dif_pclmul crc32_pclmul ghash_clmulni_intel pcbc aesni_intel aes_x86_64 joydev crypto_simd asus_nb_wmi glue_helper uvcvideo snd_hda_codec_conexant snd_hda_codec_generic snd_hda_codec_hdmi snd_hda_intel asus_wmi snd_hda_codec cryptd snd_hda_core sparse_keymap videobuf2_vmalloc arc4 videobuf2_memops snd_hwdep input_leds videobuf2_v4l2 ath9k psmouse videobuf2_core videodev ath9k_common snd_pcm ath9k_hw media fam15h_power ath k10temp snd_timer mac80211 i2c_piix4 r8169 mii mac_hid cfg80211 asus_wireless(-) snd soundcore wmi shpchp 8250_dw ip_tables x_tables amdkfd amd_iommu_v2 amdgpu radeon chash i2c_algo_bit drm_kms_helper syscopyarea serio_raw sysfillrect sysimgblt fb_sys_fops ahci ttm libahci drm video + CPU: 3 PID: 2177 Comm: rmmod Not tainted 4.15.0-5-generic #6+dev94.b4287e5bem1-Endless + Hardware name: ASUSTeK COMPUTER INC. X555DG/X555DG, BIOS 5.011 05/05/2015 + RIP: 0010:__queue_work+0x8c/0x410 + RSP: 0018:ffffbe8cc249fcd8 EFLAGS: 00010086 + RAX: ffff992ac6810800 RBX: 0000000000000000 RCX: 0000000000000008 + RDX: 0000000000000000 RSI: 0000000000000008 RDI: ffff992ac6400e18 + RBP: ffffbe8cc249fd18 R08: ffff992ac6400db0 R09: 0000000000000000 + R10: 0000000000000040 R11: ffff992ac6400dd8 R12: 0000000000002000 + R13: ffff992abd762e00 R14: ffff992abd763e38 R15: 000000000001ebe0 + FS: 00007f318203e700(0000) GS:ffff992aced80000(0000) knlGS:0000000000000000 + CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 + CR2: 0000000000000000 CR3: 00000001c720e000 CR4: 00000000001406e0 + Call Trace: + queue_work_on+0x38/0x40 + led_state_set+0x2c/0x40 [asus_wireless] + led_set_brightness_nopm+0x14/0x40 + led_set_brightness+0x37/0x60 + led_trigger_set+0xfc/0x1d0 + led_classdev_unregister+0x32/0xd0 + devm_led_classdev_release+0x11/0x20 + release_nodes+0x109/0x1f0 + devres_release_all+0x3c/0x50 + device_release_driver_internal+0x16d/0x220 + driver_detach+0x3f/0x80 + bus_remove_driver+0x55/0xd0 + driver_unregister+0x2c/0x40 + acpi_bus_unregister_driver+0x15/0x20 + asus_wireless_driver_exit+0x10/0xb7c [asus_wireless] + SyS_delete_module+0x1da/0x2b0 + entry_SYSCALL_64_fastpath+0x24/0x87 + RIP: 0033:0x7f3181b65fd7 + RSP: 002b:00007ffe74bcbe18 EFLAGS: 00000206 ORIG_RAX: 00000000000000b0 + RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 00007f3181b65fd7 + RDX: 000000000000000a RSI: 0000000000000800 RDI: 0000555ea2559258 + RBP: 0000555ea25591f0 R08: 00007ffe74bcad91 R09: 000000000000000a + R10: 0000000000000000 R11: 0000000000000206 R12: 0000000000000003 + R13: 00007ffe74bcae00 R14: 0000000000000000 R15: 0000555ea25591f0 + Code: 01 00 00 02 0f 85 7d 01 00 00 48 63 45 d4 48 c7 c6 00 f4 fa 87 49 8b 9d 08 01 00 00 48 03 1c c6 4c 89 f7 e8 87 fb ff ff 48 85 c0 <48> 8b 3b 0f 84 c5 01 00 00 48 39 f8 0f 84 bc 01 00 00 48 89 c7 + RIP: __queue_work+0x8c/0x410 RSP: ffffbe8cc249fcd8 + CR2: 0000000000000000 + ---[ end trace 7aa4f4a232e9c39c ]--- + +Unregistering the led device on the remove callback before destroying the +workqueue avoids this problem. + +https://bugzilla.kernel.org/show_bug.cgi?id=196097 + +Reported-by: Dun Hum +Cc: stable@vger.kernel.org +Signed-off-by: João Paulo Rechi Vita +Signed-off-by: Darren Hart (VMware) +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/platform/x86/asus-wireless.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/drivers/platform/x86/asus-wireless.c ++++ b/drivers/platform/x86/asus-wireless.c +@@ -178,8 +178,10 @@ static int asus_wireless_remove(struct a + { + struct asus_wireless_data *data = acpi_driver_data(adev); + +- if (data->wq) ++ if (data->wq) { ++ devm_led_classdev_unregister(&adev->dev, &data->led); + destroy_workqueue(data->wq); ++ } + return 0; + } + diff --git a/queue-4.16/platform-x86-kconfig-fix-dell-laptop-dependency-chain.patch b/queue-4.16/platform-x86-kconfig-fix-dell-laptop-dependency-chain.patch new file mode 100644 index 00000000000..d0e05133b15 --- /dev/null +++ b/queue-4.16/platform-x86-kconfig-fix-dell-laptop-dependency-chain.patch @@ -0,0 +1,49 @@ +From 7fe3fa3b5ec8e75389cce4bf5d052a52e6198d59 Mon Sep 17 00:00:00 2001 +From: Mario Limonciello +Date: Fri, 20 Apr 2018 12:42:11 -0500 +Subject: platform/x86: Kconfig: Fix dell-laptop dependency chain. + +From: Mario Limonciello + +commit 7fe3fa3b5ec8e75389cce4bf5d052a52e6198d59 upstream. + +As reported by Randy Dunlap: +>> WARNING: unmet direct dependencies detected for DELL_SMBIOS +>> Depends on [m]: X86 [=y] && X86_PLATFORM_DEVICES [=y] +>> && (DCDBAS [=m] || +>> DCDBAS [=m]=n) && (ACPI_WMI [=n] || ACPI_WMI [=n]=n) +>> Selected by [y]: +>> - DELL_LAPTOP [=y] && X86 [=y] && X86_PLATFORM_DEVICES [=y] +>> && DMI [=y] +>> && BACKLIGHT_CLASS_DEVICE [=y] && (ACPI_VIDEO [=n] || +>> ACPI_VIDEO [=n]=n) +>> && (RFKILL [=n] || RFKILL [=n]=n) && SERIO_I8042 [=y] +>> + +Right now it's possible to set dell laptop to compile in but this +causes dell-smbios to compile in which breaks if dcdbas is a module. + +Dell laptop shouldn't select dell-smbios anymore, but depend on it. + +Fixes: 32d7b19bad96 (platform/x86: dell-smbios: Resolve dependency error on DCDBAS) +Reported-by: Randy Dunlap +Signed-off-by: Mario Limonciello +Cc: stable@vger.kernel.org +Signed-off-by: Darren Hart (VMware) +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/platform/x86/Kconfig | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/platform/x86/Kconfig ++++ b/drivers/platform/x86/Kconfig +@@ -154,7 +154,7 @@ config DELL_LAPTOP + depends on ACPI_VIDEO || ACPI_VIDEO = n + depends on RFKILL || RFKILL = n + depends on SERIO_I8042 +- select DELL_SMBIOS ++ depends on DELL_SMBIOS + select POWER_SUPPLY + select LEDS_CLASS + select NEW_LEDS diff --git a/queue-4.16/series b/queue-4.16/series index ff44f4b24cf..c5ad3ea11e4 100644 --- a/queue-4.16/series +++ b/queue-4.16/series @@ -32,3 +32,21 @@ drm-vc4-make-sure-vc4_bo_-inc-dec-_usecnt-calls-are-balanced.patch drm-vmwgfx-fix-a-buffer-object-leak.patch drm-bridge-vga-dac-fix-edid-memory-leak.patch test_firmware-fix-setting-old-custom-fw-path-back-on-exit-second-try.patch +xhci-fix-use-after-free-in-xhci_free_virt_device.patch +usb-serial-visor-handle-potential-invalid-device-configuration.patch +usb-dwc3-gadget-fix-list_del-corruption-in-dwc3_ep_dequeue.patch +usb-accept-bulk-endpoints-with-1024-byte-maxpacket.patch +usb-serial-option-reimplement-interface-masking.patch +usb-serial-option-adding-support-for-ublox-r410m.patch +usb-musb-host-fix-potential-null-pointer-dereference.patch +usb-musb-trace-fix-null-pointer-dereference-in-musb_g_tx.patch +platform-x86-asus-wireless-fix-null-pointer-dereference.patch +platform-x86-kconfig-fix-dell-laptop-dependency-chain.patch +kvm-x86-remove-apic-timer-periodic-oneshot-spikes.patch +x86-tsc-always-unregister-clocksource_tsc_early.patch +x86-tsc-fix-mark_tsc_unstable.patch +irqchip-qcom-fix-check-for-spurious-interrupts.patch +clocksource-allow-clocksource_mark_unstable-on-unregistered-clocksources.patch +clocksource-initialize-cs-wd_list.patch +clocksource-consistent-de-rate-when-marking-unstable.patch +tracing-fix-bad-use-of-igrab-in-trace_uprobe.c.patch diff --git a/queue-4.16/tracing-fix-bad-use-of-igrab-in-trace_uprobe.c.patch b/queue-4.16/tracing-fix-bad-use-of-igrab-in-trace_uprobe.c.patch new file mode 100644 index 00000000000..335c2043ebb --- /dev/null +++ b/queue-4.16/tracing-fix-bad-use-of-igrab-in-trace_uprobe.c.patch @@ -0,0 +1,149 @@ +From 0c92c7a3c5d416f47b32c5f20a611dfeca5d5f2e Mon Sep 17 00:00:00 2001 +From: Song Liu +Date: Mon, 23 Apr 2018 10:21:34 -0700 +Subject: tracing: Fix bad use of igrab in trace_uprobe.c + +From: Song Liu + +commit 0c92c7a3c5d416f47b32c5f20a611dfeca5d5f2e upstream. + +As Miklos reported and suggested: + + This pattern repeats two times in trace_uprobe.c and in + kernel/events/core.c as well: + + ret = kern_path(filename, LOOKUP_FOLLOW, &path); + if (ret) + goto fail_address_parse; + + inode = igrab(d_inode(path.dentry)); + path_put(&path); + + And it's wrong. You can only hold a reference to the inode if you + have an active ref to the superblock as well (which is normally + through path.mnt) or holding s_umount. + + This way unmounting the containing filesystem while the tracepoint is + active will give you the "VFS: Busy inodes after unmount..." message + and a crash when the inode is finally put. + + Solution: store path instead of inode. + +This patch fixes two instances in trace_uprobe.c. struct path is added to +struct trace_uprobe to keep the inode and containing mount point +referenced. + +Link: http://lkml.kernel.org/r/20180423172135.4050588-1-songliubraving@fb.com + +Fixes: f3f096cfedf8 ("tracing: Provide trace events interface for uprobes") +Fixes: 33ea4b24277b ("perf/core: Implement the 'perf_uprobe' PMU") +Cc: stable@vger.kernel.org +Cc: Ingo Molnar +Cc: Howard McLauchlan +Cc: Josef Bacik +Cc: Srikar Dronamraju +Acked-by: Miklos Szeredi +Reported-by: Miklos Szeredi +Signed-off-by: Song Liu +Signed-off-by: Steven Rostedt (VMware) +Signed-off-by: Greg Kroah-Hartman + +--- + kernel/trace/trace_uprobe.c | 24 ++++++++++-------------- + 1 file changed, 10 insertions(+), 14 deletions(-) + +--- a/kernel/trace/trace_uprobe.c ++++ b/kernel/trace/trace_uprobe.c +@@ -55,6 +55,7 @@ struct trace_uprobe { + struct list_head list; + struct trace_uprobe_filter filter; + struct uprobe_consumer consumer; ++ struct path path; + struct inode *inode; + char *filename; + unsigned long offset; +@@ -287,7 +288,7 @@ static void free_trace_uprobe(struct tra + for (i = 0; i < tu->tp.nr_args; i++) + traceprobe_free_probe_arg(&tu->tp.args[i]); + +- iput(tu->inode); ++ path_put(&tu->path); + kfree(tu->tp.call.class->system); + kfree(tu->tp.call.name); + kfree(tu->filename); +@@ -361,7 +362,6 @@ end: + static int create_trace_uprobe(int argc, char **argv) + { + struct trace_uprobe *tu; +- struct inode *inode; + char *arg, *event, *group, *filename; + char buf[MAX_EVENT_NAME_LEN]; + struct path path; +@@ -369,7 +369,6 @@ static int create_trace_uprobe(int argc, + bool is_delete, is_return; + int i, ret; + +- inode = NULL; + ret = 0; + is_delete = false; + is_return = false; +@@ -435,21 +434,16 @@ static int create_trace_uprobe(int argc, + } + /* Find the last occurrence, in case the path contains ':' too. */ + arg = strrchr(argv[1], ':'); +- if (!arg) { +- ret = -EINVAL; +- goto fail_address_parse; +- } ++ if (!arg) ++ return -EINVAL; + + *arg++ = '\0'; + filename = argv[1]; + ret = kern_path(filename, LOOKUP_FOLLOW, &path); + if (ret) +- goto fail_address_parse; +- +- inode = igrab(d_inode(path.dentry)); +- path_put(&path); ++ return ret; + +- if (!inode || !S_ISREG(inode->i_mode)) { ++ if (!d_is_reg(path.dentry)) { + ret = -EINVAL; + goto fail_address_parse; + } +@@ -488,7 +482,7 @@ static int create_trace_uprobe(int argc, + goto fail_address_parse; + } + tu->offset = offset; +- tu->inode = inode; ++ tu->path = path; + tu->filename = kstrdup(filename, GFP_KERNEL); + + if (!tu->filename) { +@@ -556,7 +550,7 @@ error: + return ret; + + fail_address_parse: +- iput(inode); ++ path_put(&path); + + pr_info("Failed to parse address or file.\n"); + +@@ -935,6 +929,7 @@ probe_event_enable(struct trace_uprobe * + goto err_flags; + + tu->consumer.filter = filter; ++ tu->inode = d_real_inode(tu->path.dentry); + ret = uprobe_register(tu->inode, tu->offset, &tu->consumer); + if (ret) + goto err_buffer; +@@ -980,6 +975,7 @@ probe_event_disable(struct trace_uprobe + WARN_ON(!uprobe_filter_is_empty(&tu->filter)); + + uprobe_unregister(tu->inode, tu->offset, &tu->consumer); ++ tu->inode = NULL; + tu->tp.flags &= file ? ~TP_FLAG_TRACE : ~TP_FLAG_PROFILE; + + uprobe_buffer_disable(); diff --git a/queue-4.16/usb-accept-bulk-endpoints-with-1024-byte-maxpacket.patch b/queue-4.16/usb-accept-bulk-endpoints-with-1024-byte-maxpacket.patch new file mode 100644 index 00000000000..a48a26233b8 --- /dev/null +++ b/queue-4.16/usb-accept-bulk-endpoints-with-1024-byte-maxpacket.patch @@ -0,0 +1,42 @@ +From fb5ee84ea72c5f1b6cabdd1c9d6e8648995ca7c6 Mon Sep 17 00:00:00 2001 +From: Alan Stern +Date: Thu, 3 May 2018 11:04:48 -0400 +Subject: USB: Accept bulk endpoints with 1024-byte maxpacket + +From: Alan Stern + +commit fb5ee84ea72c5f1b6cabdd1c9d6e8648995ca7c6 upstream. + +Some non-compliant high-speed USB devices have bulk endpoints with a +1024-byte maxpacket size. Although such endpoints don't work with +xHCI host controllers, they do work with EHCI controllers. We used to +accept these invalid sizes (with a warning), but we no longer do +because of an unintentional change introduced by commit aed9d65ac327 +("USB: validate wMaxPacketValue entries in endpoint descriptors"). + +This patch restores the old behavior, so that people with these +peculiar devices can use them without patching their kernels by hand. + +Signed-off-by: Alan Stern +Suggested-by: Elvinas +Fixes: aed9d65ac327 ("USB: validate wMaxPacketValue entries in endpoint descriptors") +CC: +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/core/config.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/drivers/usb/core/config.c ++++ b/drivers/usb/core/config.c +@@ -191,7 +191,9 @@ static const unsigned short full_speed_m + static const unsigned short high_speed_maxpacket_maxes[4] = { + [USB_ENDPOINT_XFER_CONTROL] = 64, + [USB_ENDPOINT_XFER_ISOC] = 1024, +- [USB_ENDPOINT_XFER_BULK] = 512, ++ ++ /* Bulk should be 512, but some devices use 1024: we will warn below */ ++ [USB_ENDPOINT_XFER_BULK] = 1024, + [USB_ENDPOINT_XFER_INT] = 1024, + }; + static const unsigned short super_speed_maxpacket_maxes[4] = { diff --git a/queue-4.16/usb-dwc3-gadget-fix-list_del-corruption-in-dwc3_ep_dequeue.patch b/queue-4.16/usb-dwc3-gadget-fix-list_del-corruption-in-dwc3_ep_dequeue.patch new file mode 100644 index 00000000000..b33a3418192 --- /dev/null +++ b/queue-4.16/usb-dwc3-gadget-fix-list_del-corruption-in-dwc3_ep_dequeue.patch @@ -0,0 +1,44 @@ +From 96bd39df29c29d348d65311e5954c0b7d3a2a790 Mon Sep 17 00:00:00 2001 +From: Mayank Rana +Date: Fri, 23 Mar 2018 10:05:33 -0700 +Subject: usb: dwc3: gadget: Fix list_del corruption in dwc3_ep_dequeue + +From: Mayank Rana + +commit 96bd39df29c29d348d65311e5954c0b7d3a2a790 upstream. + +dwc3_ep_dequeue() waits for completion of End Transfer command using +wait_event_lock_irq(), which will release the dwc3->lock while waiting +and reacquire after completion. This allows a potential race condition +with ep_disable() which also removes all requests from started_list +and pending_list. + +The check for NULL r->trb should catch this but currently it exits to +the wrong 'out1' label which calls dwc3_gadget_giveback(). Since its +list entry was already removed, if CONFIG_DEBUG_LIST is enabled a +'list_del corruption' bug is thrown since its next/prev pointers are +already LIST_POISON1/2. If r->trb is NULL it should simply exit to +'out0'. + +Fixes: cf3113d893d4 ("usb: dwc3: gadget: properly increment dequeue pointer on ep_dequeue") +Cc: stable@vger.kernel.org # v4.12+ +Signed-off-by: Mayank Rana +Signed-off-by: Jack Pham +Signed-off-by: Felipe Balbi +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/dwc3/gadget.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/usb/dwc3/gadget.c ++++ b/drivers/usb/dwc3/gadget.c +@@ -1424,7 +1424,7 @@ static int dwc3_gadget_ep_dequeue(struct + dwc->lock); + + if (!r->trb) +- goto out1; ++ goto out0; + + if (r->num_pending_sgs) { + struct dwc3_trb *trb; diff --git a/queue-4.16/usb-musb-host-fix-potential-null-pointer-dereference.patch b/queue-4.16/usb-musb-host-fix-potential-null-pointer-dereference.patch new file mode 100644 index 00000000000..2b4a17f4397 --- /dev/null +++ b/queue-4.16/usb-musb-host-fix-potential-null-pointer-dereference.patch @@ -0,0 +1,38 @@ +From 2b63f1329df2cd814c1f8353fae4853ace6521d1 Mon Sep 17 00:00:00 2001 +From: Bin Liu +Date: Mon, 30 Apr 2018 11:20:53 -0500 +Subject: usb: musb: host: fix potential NULL pointer dereference + +From: Bin Liu + +commit 2b63f1329df2cd814c1f8353fae4853ace6521d1 upstream. + +musb_start_urb() doesn't check the pass-in parameter if it is NULL. But +in musb_bulk_nak_timeout() the parameter passed to musb_start_urb() is +returned from first_qh(), which could be NULL. + +So wrap the musb_start_urb() call here with a if condition check to +avoid the potential NULL pointer dereference. + +Fixes: f283862f3b5c ("usb: musb: NAK timeout scheme on bulk TX endpoint") +Cc: stable@vger.kernel.org # v3.7+ +Signed-off-by: Bin Liu +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/musb/musb_host.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/drivers/usb/musb/musb_host.c ++++ b/drivers/usb/musb/musb_host.c +@@ -996,7 +996,9 @@ static void musb_bulk_nak_timeout(struct + /* set tx_reinit and schedule the next qh */ + ep->tx_reinit = 1; + } +- musb_start_urb(musb, is_in, next_qh); ++ ++ if (next_qh) ++ musb_start_urb(musb, is_in, next_qh); + } + } + diff --git a/queue-4.16/usb-musb-trace-fix-null-pointer-dereference-in-musb_g_tx.patch b/queue-4.16/usb-musb-trace-fix-null-pointer-dereference-in-musb_g_tx.patch new file mode 100644 index 00000000000..f490ce3ae03 --- /dev/null +++ b/queue-4.16/usb-musb-trace-fix-null-pointer-dereference-in-musb_g_tx.patch @@ -0,0 +1,44 @@ +From 9aea9b6cc78d2b99b23d84fb2e0bc6e464c6569e Mon Sep 17 00:00:00 2001 +From: Bin Liu +Date: Mon, 30 Apr 2018 11:20:54 -0500 +Subject: usb: musb: trace: fix NULL pointer dereference in musb_g_tx() + +From: Bin Liu + +commit 9aea9b6cc78d2b99b23d84fb2e0bc6e464c6569e upstream. + +The usb_request pointer could be NULL in musb_g_tx(), where the +tracepoint call would trigger the NULL pointer dereference failure when +parsing the members of the usb_request pointer. + +Move the tracepoint call to where the usb_request pointer is already +checked to solve the issue. + +Fixes: fc78003e5345 ("usb: musb: gadget: add usb-request tracepoints") +Cc: stable@vger.kernel.org # v4.8+ +Signed-off-by: Bin Liu +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/musb/musb_gadget.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/usb/musb/musb_gadget.c ++++ b/drivers/usb/musb/musb_gadget.c +@@ -417,7 +417,6 @@ void musb_g_tx(struct musb *musb, u8 epn + req = next_request(musb_ep); + request = &req->request; + +- trace_musb_req_tx(req); + csr = musb_readw(epio, MUSB_TXCSR); + musb_dbg(musb, "<== %s, txcsr %04x", musb_ep->end_point.name, csr); + +@@ -456,6 +455,8 @@ void musb_g_tx(struct musb *musb, u8 epn + u8 is_dma = 0; + bool short_packet = false; + ++ trace_musb_req_tx(req); ++ + if (dma && (csr & MUSB_TXCSR_DMAENAB)) { + is_dma = 1; + csr |= MUSB_TXCSR_P_WZC_BITS; diff --git a/queue-4.16/usb-serial-option-adding-support-for-ublox-r410m.patch b/queue-4.16/usb-serial-option-adding-support-for-ublox-r410m.patch new file mode 100644 index 00000000000..89b4b4484ee --- /dev/null +++ b/queue-4.16/usb-serial-option-adding-support-for-ublox-r410m.patch @@ -0,0 +1,52 @@ +From 4205cb01f6e9ef2ae6daa7be4e8ac1edeb4c9d64 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?SZ=20Lin=20=28=E6=9E=97=E4=B8=8A=E6=99=BA=29?= + +Date: Thu, 26 Apr 2018 14:28:31 +0800 +Subject: USB: serial: option: adding support for ublox R410M +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: SZ Lin (林上智) + +commit 4205cb01f6e9ef2ae6daa7be4e8ac1edeb4c9d64 upstream. + +This patch adds support for ublox R410M PID 0x90b2 USB modem to option +driver, this module supports LTE Cat M1 / NB1. + +Interface layout: +0: QCDM/DIAG +1: ADB +2: AT +3: RMNET + +Signed-off-by: SZ Lin (林上智) +Cc: stable +Signed-off-by: Johan Hovold +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/serial/option.c | 5 +++++ + 1 file changed, 5 insertions(+) + +--- a/drivers/usb/serial/option.c ++++ b/drivers/usb/serial/option.c +@@ -233,6 +233,8 @@ static void option_instat_callback(struc + /* These Quectel products use Qualcomm's vendor ID */ + #define QUECTEL_PRODUCT_UC20 0x9003 + #define QUECTEL_PRODUCT_UC15 0x9090 ++/* These u-blox products use Qualcomm's vendor ID */ ++#define UBLOX_PRODUCT_R410M 0x90b2 + /* These Yuga products use Qualcomm's vendor ID */ + #define YUGA_PRODUCT_CLM920_NC5 0x9625 + +@@ -1065,6 +1067,9 @@ static const struct usb_device_id option + /* Yuga products use Qualcomm vendor ID */ + { USB_DEVICE(QUALCOMM_VENDOR_ID, YUGA_PRODUCT_CLM920_NC5), + .driver_info = RSVD(1) | RSVD(4) }, ++ /* u-blox products using Qualcomm vendor ID */ ++ { USB_DEVICE(QUALCOMM_VENDOR_ID, UBLOX_PRODUCT_R410M), ++ .driver_info = RSVD(1) | RSVD(3) }, + /* Quectel products using Quectel vendor ID */ + { USB_DEVICE(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EC21), + .driver_info = RSVD(4) }, diff --git a/queue-4.16/usb-serial-option-reimplement-interface-masking.patch b/queue-4.16/usb-serial-option-reimplement-interface-masking.patch new file mode 100644 index 00000000000..273321b5c4c --- /dev/null +++ b/queue-4.16/usb-serial-option-reimplement-interface-masking.patch @@ -0,0 +1,857 @@ +From c3a65808f04a8426481b63a4fbd9392f009f6330 Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Wed, 7 Mar 2018 17:40:48 +0100 +Subject: USB: serial: option: reimplement interface masking + +From: Johan Hovold + +commit c3a65808f04a8426481b63a4fbd9392f009f6330 upstream. + +Reimplement interface masking using device flags stored directly in the +device-id table. This will make it easier to add and maintain device-id +entries by using a more compact and readable notation compared to the +current implementation (which manages pairs of masks in separate +blacklist structs). + +Two convenience macros are used to flag an interface as either reserved +or as not supporting modem-control requests: + + { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_ME910_DUAL_MODEM), + .driver_info = NCTRL(0) | RSVD(3) }, + +For now, we limit the highest maskable interface number to seven, which +allows for (up to 16) additional device flags to be added later should +need arise. + +Note that this will likely need to be backported to stable in order to +make future device-id backports more manageable. + +Reviewed-by: Greg Kroah-Hartman +Signed-off-by: Johan Hovold +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/serial/option.c | 446 ++++++++++++++------------------------------ + 1 file changed, 152 insertions(+), 294 deletions(-) + +--- a/drivers/usb/serial/option.c ++++ b/drivers/usb/serial/option.c +@@ -548,151 +548,15 @@ static void option_instat_callback(struc + #define WETELECOM_PRODUCT_6802 0x6802 + #define WETELECOM_PRODUCT_WMD300 0x6803 + +-struct option_blacklist_info { +- /* bitmask of interface numbers blacklisted for send_setup */ +- const unsigned long sendsetup; +- /* bitmask of interface numbers that are reserved */ +- const unsigned long reserved; +-}; +- +-static const struct option_blacklist_info four_g_w14_blacklist = { +- .sendsetup = BIT(0) | BIT(1), +-}; +- +-static const struct option_blacklist_info four_g_w100_blacklist = { +- .sendsetup = BIT(1) | BIT(2), +- .reserved = BIT(3), +-}; +- +-static const struct option_blacklist_info alcatel_x200_blacklist = { +- .sendsetup = BIT(0) | BIT(1), +- .reserved = BIT(4), +-}; +- +-static const struct option_blacklist_info zte_0037_blacklist = { +- .sendsetup = BIT(0) | BIT(1), +-}; +- +-static const struct option_blacklist_info zte_k3765_z_blacklist = { +- .sendsetup = BIT(0) | BIT(1) | BIT(2), +- .reserved = BIT(4), +-}; +- +-static const struct option_blacklist_info zte_ad3812_z_blacklist = { +- .sendsetup = BIT(0) | BIT(1) | BIT(2), +-}; +- +-static const struct option_blacklist_info zte_mc2718_z_blacklist = { +- .sendsetup = BIT(1) | BIT(2) | BIT(3) | BIT(4), +-}; +- +-static const struct option_blacklist_info zte_mc2716_z_blacklist = { +- .sendsetup = BIT(1) | BIT(2) | BIT(3), +-}; +- +-static const struct option_blacklist_info zte_me3620_mbim_blacklist = { +- .reserved = BIT(2) | BIT(3) | BIT(4), +-}; +- +-static const struct option_blacklist_info zte_me3620_xl_blacklist = { +- .reserved = BIT(3) | BIT(4) | BIT(5), +-}; +- +-static const struct option_blacklist_info zte_zm8620_x_blacklist = { +- .reserved = BIT(3) | BIT(4) | BIT(5), +-}; +- +-static const struct option_blacklist_info huawei_cdc12_blacklist = { +- .reserved = BIT(1) | BIT(2), +-}; +- +-static const struct option_blacklist_info net_intf0_blacklist = { +- .reserved = BIT(0), +-}; +- +-static const struct option_blacklist_info net_intf1_blacklist = { +- .reserved = BIT(1), +-}; +- +-static const struct option_blacklist_info net_intf2_blacklist = { +- .reserved = BIT(2), +-}; +- +-static const struct option_blacklist_info net_intf3_blacklist = { +- .reserved = BIT(3), +-}; +- +-static const struct option_blacklist_info net_intf4_blacklist = { +- .reserved = BIT(4), +-}; +- +-static const struct option_blacklist_info net_intf5_blacklist = { +- .reserved = BIT(5), +-}; +- +-static const struct option_blacklist_info net_intf6_blacklist = { +- .reserved = BIT(6), +-}; +- +-static const struct option_blacklist_info zte_mf626_blacklist = { +- .sendsetup = BIT(0) | BIT(1), +- .reserved = BIT(4), +-}; +- +-static const struct option_blacklist_info zte_1255_blacklist = { +- .reserved = BIT(3) | BIT(4), +-}; +- +-static const struct option_blacklist_info simcom_sim7100e_blacklist = { +- .reserved = BIT(5) | BIT(6), +-}; +- +-static const struct option_blacklist_info telit_me910_blacklist = { +- .sendsetup = BIT(0), +- .reserved = BIT(1) | BIT(3), +-}; +- +-static const struct option_blacklist_info telit_me910_dual_modem_blacklist = { +- .sendsetup = BIT(0), +- .reserved = BIT(3), +-}; +- +-static const struct option_blacklist_info telit_le910_blacklist = { +- .sendsetup = BIT(0), +- .reserved = BIT(1) | BIT(2), +-}; +- +-static const struct option_blacklist_info telit_le920_blacklist = { +- .sendsetup = BIT(0), +- .reserved = BIT(1) | BIT(5), +-}; +- +-static const struct option_blacklist_info telit_le920a4_blacklist_1 = { +- .sendsetup = BIT(0), +- .reserved = BIT(1), +-}; +- +-static const struct option_blacklist_info telit_le922_blacklist_usbcfg0 = { +- .sendsetup = BIT(2), +- .reserved = BIT(0) | BIT(1) | BIT(3), +-}; + +-static const struct option_blacklist_info telit_le922_blacklist_usbcfg3 = { +- .sendsetup = BIT(0), +- .reserved = BIT(1) | BIT(2) | BIT(3), +-}; ++/* Device flags */ + +-static const struct option_blacklist_info cinterion_rmnet2_blacklist = { +- .reserved = BIT(4) | BIT(5), +-}; ++/* Interface does not support modem-control requests */ ++#define NCTRL(ifnum) ((BIT(ifnum) & 0xff) << 8) + +-static const struct option_blacklist_info yuga_clm920_nc5_blacklist = { +- .reserved = BIT(1) | BIT(4), +-}; ++/* Interface is reserved */ ++#define RSVD(ifnum) ((BIT(ifnum) & 0xff) << 0) + +-static const struct option_blacklist_info quectel_ep06_blacklist = { +- .reserved = BIT(4) | BIT(5), +-}; + + static const struct usb_device_id option_ids[] = { + { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COLT) }, +@@ -726,26 +590,26 @@ static const struct usb_device_id option + { USB_DEVICE(QUANTA_VENDOR_ID, QUANTA_PRODUCT_GKE) }, + { USB_DEVICE(QUANTA_VENDOR_ID, QUANTA_PRODUCT_GLE) }, + { USB_DEVICE(QUANTA_VENDOR_ID, 0xea42), +- .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, ++ .driver_info = RSVD(4) }, + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0x1c05, USB_CLASS_COMM, 0x02, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0x1c1f, USB_CLASS_COMM, 0x02, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0x1c23, USB_CLASS_COMM, 0x02, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E173, 0xff, 0xff, 0xff), +- .driver_info = (kernel_ulong_t) &net_intf1_blacklist }, ++ .driver_info = RSVD(1) }, + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E173S6, 0xff, 0xff, 0xff), +- .driver_info = (kernel_ulong_t) &net_intf1_blacklist }, ++ .driver_info = RSVD(1) }, + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1750, 0xff, 0xff, 0xff), +- .driver_info = (kernel_ulong_t) &net_intf2_blacklist }, ++ .driver_info = RSVD(2) }, + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0x1441, USB_CLASS_COMM, 0x02, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0x1442, USB_CLASS_COMM, 0x02, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K4505, 0xff, 0xff, 0xff), +- .driver_info = (kernel_ulong_t) &huawei_cdc12_blacklist }, ++ .driver_info = RSVD(1) | RSVD(2) }, + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K3765, 0xff, 0xff, 0xff), +- .driver_info = (kernel_ulong_t) &huawei_cdc12_blacklist }, ++ .driver_info = RSVD(1) | RSVD(2) }, + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0x14ac, 0xff, 0xff, 0xff), /* Huawei E1820 */ +- .driver_info = (kernel_ulong_t) &net_intf1_blacklist }, ++ .driver_info = RSVD(1) }, + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K4605, 0xff, 0xff, 0xff), +- .driver_info = (kernel_ulong_t) &huawei_cdc12_blacklist }, ++ .driver_info = RSVD(1) | RSVD(2) }, + { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0xff, 0xff) }, + { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x01) }, + { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x02) }, +@@ -1190,67 +1054,67 @@ static const struct usb_device_id option + { USB_DEVICE(KYOCERA_VENDOR_ID, KYOCERA_PRODUCT_KPC680) }, + { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x6000)}, /* ZTE AC8700 */ + { USB_DEVICE_AND_INTERFACE_INFO(QUALCOMM_VENDOR_ID, 0x6001, 0xff, 0xff, 0xff), /* 4G LTE usb-modem U901 */ +- .driver_info = (kernel_ulong_t)&net_intf3_blacklist }, ++ .driver_info = RSVD(3) }, + { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x6613)}, /* Onda H600/ZTE MF330 */ + { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x0023)}, /* ONYX 3G device */ + { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x9000)}, /* SIMCom SIM5218 */ + /* Quectel products using Qualcomm vendor ID */ + { USB_DEVICE(QUALCOMM_VENDOR_ID, QUECTEL_PRODUCT_UC15)}, + { USB_DEVICE(QUALCOMM_VENDOR_ID, QUECTEL_PRODUCT_UC20), +- .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, ++ .driver_info = RSVD(4) }, + /* Yuga products use Qualcomm vendor ID */ + { USB_DEVICE(QUALCOMM_VENDOR_ID, YUGA_PRODUCT_CLM920_NC5), +- .driver_info = (kernel_ulong_t)&yuga_clm920_nc5_blacklist }, ++ .driver_info = RSVD(1) | RSVD(4) }, + /* Quectel products using Quectel vendor ID */ + { USB_DEVICE(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EC21), +- .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, ++ .driver_info = RSVD(4) }, + { USB_DEVICE(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EC25), +- .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, ++ .driver_info = RSVD(4) }, + { USB_DEVICE(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_BG96), +- .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, ++ .driver_info = RSVD(4) }, + { USB_DEVICE(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EP06), +- .driver_info = (kernel_ulong_t)&quectel_ep06_blacklist }, ++ .driver_info = RSVD(4) | RSVD(5) }, + { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_6001) }, + { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_CMU_300) }, + { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_6003), +- .driver_info = (kernel_ulong_t)&net_intf0_blacklist }, ++ .driver_info = RSVD(0) }, + { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_6004) }, + { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_6005) }, + { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_CGU_628A) }, + { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_CHE_628S), +- .driver_info = (kernel_ulong_t)&net_intf0_blacklist }, ++ .driver_info = RSVD(0) }, + { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_CMU_301), +- .driver_info = (kernel_ulong_t)&net_intf0_blacklist }, ++ .driver_info = RSVD(0) }, + { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_CHU_628), +- .driver_info = (kernel_ulong_t)&net_intf0_blacklist }, ++ .driver_info = RSVD(0) }, + { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_CHU_628S) }, + { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_CDU_680) }, + { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_CDU_685A) }, + { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_CHU_720S), +- .driver_info = (kernel_ulong_t)&net_intf0_blacklist }, ++ .driver_info = RSVD(0) }, + { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_7002), +- .driver_info = (kernel_ulong_t)&net_intf0_blacklist }, ++ .driver_info = RSVD(0) }, + { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_CHU_629K), +- .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, ++ .driver_info = RSVD(4) }, + { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_7004), +- .driver_info = (kernel_ulong_t)&net_intf3_blacklist }, ++ .driver_info = RSVD(3) }, + { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_7005) }, + { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_CGU_629), +- .driver_info = (kernel_ulong_t)&net_intf5_blacklist }, ++ .driver_info = RSVD(5) }, + { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_CHU_629S), +- .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, ++ .driver_info = RSVD(4) }, + { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_CHU_720I), +- .driver_info = (kernel_ulong_t)&net_intf0_blacklist }, ++ .driver_info = RSVD(0) }, + { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_7212), +- .driver_info = (kernel_ulong_t)&net_intf0_blacklist }, ++ .driver_info = RSVD(0) }, + { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_7213), +- .driver_info = (kernel_ulong_t)&net_intf0_blacklist }, ++ .driver_info = RSVD(0) }, + { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_7251), +- .driver_info = (kernel_ulong_t)&net_intf1_blacklist }, ++ .driver_info = RSVD(1) }, + { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_7252), +- .driver_info = (kernel_ulong_t)&net_intf1_blacklist }, ++ .driver_info = RSVD(1) }, + { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_7253), +- .driver_info = (kernel_ulong_t)&net_intf1_blacklist }, ++ .driver_info = RSVD(1) }, + { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_UC864E) }, + { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_UC864G) }, + { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_CC864_DUAL) }, +@@ -1258,38 +1122,38 @@ static const struct usb_device_id option + { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_DE910_DUAL) }, + { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_UE910_V2) }, + { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE922_USBCFG0), +- .driver_info = (kernel_ulong_t)&telit_le922_blacklist_usbcfg0 }, ++ .driver_info = RSVD(0) | RSVD(1) | NCTRL(2) | RSVD(3) }, + { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE922_USBCFG1), +- .driver_info = (kernel_ulong_t)&telit_le910_blacklist }, ++ .driver_info = NCTRL(0) | RSVD(1) | RSVD(2) }, + { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE922_USBCFG2), +- .driver_info = (kernel_ulong_t)&telit_le922_blacklist_usbcfg3 }, ++ .driver_info = NCTRL(0) | RSVD(1) | RSVD(2) | RSVD(3) }, + { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE922_USBCFG3), +- .driver_info = (kernel_ulong_t)&telit_le922_blacklist_usbcfg3 }, ++ .driver_info = NCTRL(0) | RSVD(1) | RSVD(2) | RSVD(3) }, + { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, TELIT_PRODUCT_LE922_USBCFG5, 0xff), +- .driver_info = (kernel_ulong_t)&telit_le922_blacklist_usbcfg0 }, ++ .driver_info = RSVD(0) | RSVD(1) | NCTRL(2) | RSVD(3) }, + { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_ME910), +- .driver_info = (kernel_ulong_t)&telit_me910_blacklist }, ++ .driver_info = NCTRL(0) | RSVD(1) | RSVD(3) }, + { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_ME910_DUAL_MODEM), +- .driver_info = (kernel_ulong_t)&telit_me910_dual_modem_blacklist }, ++ .driver_info = NCTRL(0) | RSVD(3) }, + { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE910), +- .driver_info = (kernel_ulong_t)&telit_le910_blacklist }, ++ .driver_info = NCTRL(0) | RSVD(1) | RSVD(2) }, + { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE910_USBCFG4), +- .driver_info = (kernel_ulong_t)&telit_le922_blacklist_usbcfg3 }, ++ .driver_info = NCTRL(0) | RSVD(1) | RSVD(2) | RSVD(3) }, + { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE920), +- .driver_info = (kernel_ulong_t)&telit_le920_blacklist }, ++ .driver_info = NCTRL(0) | RSVD(1) | RSVD(5) }, + { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE920A4_1207) }, + { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE920A4_1208), +- .driver_info = (kernel_ulong_t)&telit_le920a4_blacklist_1 }, ++ .driver_info = NCTRL(0) | RSVD(1) }, + { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE920A4_1211), +- .driver_info = (kernel_ulong_t)&telit_le922_blacklist_usbcfg3 }, ++ .driver_info = NCTRL(0) | RSVD(1) | RSVD(2) | RSVD(3) }, + { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE920A4_1212), +- .driver_info = (kernel_ulong_t)&telit_le920a4_blacklist_1 }, ++ .driver_info = NCTRL(0) | RSVD(1) }, + { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, TELIT_PRODUCT_LE920A4_1213, 0xff) }, + { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE920A4_1214), +- .driver_info = (kernel_ulong_t)&telit_le922_blacklist_usbcfg3 }, ++ .driver_info = NCTRL(0) | RSVD(1) | RSVD(2) | RSVD(3) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MF622, 0xff, 0xff, 0xff) }, /* ZTE WCDMA products */ + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0002, 0xff, 0xff, 0xff), +- .driver_info = (kernel_ulong_t)&net_intf1_blacklist }, ++ .driver_info = RSVD(1) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0003, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0004, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0005, 0xff, 0xff, 0xff) }, +@@ -1305,58 +1169,58 @@ static const struct usb_device_id option + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0010, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0011, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0012, 0xff, 0xff, 0xff), +- .driver_info = (kernel_ulong_t)&net_intf1_blacklist }, ++ .driver_info = RSVD(1) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0013, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MF628, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0016, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0017, 0xff, 0xff, 0xff), +- .driver_info = (kernel_ulong_t)&net_intf3_blacklist }, ++ .driver_info = RSVD(3) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0018, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0019, 0xff, 0xff, 0xff), +- .driver_info = (kernel_ulong_t)&net_intf3_blacklist }, ++ .driver_info = RSVD(3) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0020, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0021, 0xff, 0xff, 0xff), +- .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, ++ .driver_info = RSVD(4) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0022, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0023, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0024, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0025, 0xff, 0xff, 0xff), +- .driver_info = (kernel_ulong_t)&net_intf1_blacklist }, ++ .driver_info = RSVD(1) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0028, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0029, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0030, 0xff, 0xff, 0xff) }, +- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MF626, 0xff, +- 0xff, 0xff), .driver_info = (kernel_ulong_t)&zte_mf626_blacklist }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MF626, 0xff, 0xff, 0xff), ++ .driver_info = NCTRL(0) | NCTRL(1) | RSVD(4) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0032, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0033, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0034, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0037, 0xff, 0xff, 0xff), +- .driver_info = (kernel_ulong_t)&zte_0037_blacklist }, ++ .driver_info = NCTRL(0) | NCTRL(1) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0038, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0039, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0040, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0042, 0xff, 0xff, 0xff), +- .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, ++ .driver_info = RSVD(4) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0043, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0044, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0048, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0049, 0xff, 0xff, 0xff), +- .driver_info = (kernel_ulong_t)&net_intf5_blacklist }, ++ .driver_info = RSVD(5) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0050, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0051, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0052, 0xff, 0xff, 0xff), +- .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, ++ .driver_info = RSVD(4) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0054, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0055, 0xff, 0xff, 0xff), +- .driver_info = (kernel_ulong_t)&net_intf1_blacklist }, ++ .driver_info = RSVD(1) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0056, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0057, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0058, 0xff, 0xff, 0xff), +- .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, ++ .driver_info = RSVD(4) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0061, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0062, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0063, 0xff, 0xff, 0xff), +- .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, ++ .driver_info = RSVD(4) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0064, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0065, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0066, 0xff, 0xff, 0xff) }, +@@ -1381,26 +1245,26 @@ static const struct usb_device_id option + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0096, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0097, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0104, 0xff, 0xff, 0xff), +- .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, ++ .driver_info = RSVD(4) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0105, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0106, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0108, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0113, 0xff, 0xff, 0xff), +- .driver_info = (kernel_ulong_t)&net_intf5_blacklist }, ++ .driver_info = RSVD(5) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0117, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0118, 0xff, 0xff, 0xff), +- .driver_info = (kernel_ulong_t)&net_intf5_blacklist }, ++ .driver_info = RSVD(5) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0121, 0xff, 0xff, 0xff), +- .driver_info = (kernel_ulong_t)&net_intf5_blacklist }, ++ .driver_info = RSVD(5) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0122, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0123, 0xff, 0xff, 0xff), +- .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, ++ .driver_info = RSVD(4) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0124, 0xff, 0xff, 0xff), +- .driver_info = (kernel_ulong_t)&net_intf5_blacklist }, ++ .driver_info = RSVD(5) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0125, 0xff, 0xff, 0xff), +- .driver_info = (kernel_ulong_t)&net_intf6_blacklist }, ++ .driver_info = RSVD(6) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0126, 0xff, 0xff, 0xff), +- .driver_info = (kernel_ulong_t)&net_intf5_blacklist }, ++ .driver_info = RSVD(5) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0128, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0135, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0136, 0xff, 0xff, 0xff) }, +@@ -1416,50 +1280,50 @@ static const struct usb_device_id option + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0155, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0156, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0157, 0xff, 0xff, 0xff), +- .driver_info = (kernel_ulong_t)&net_intf5_blacklist }, ++ .driver_info = RSVD(5) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0158, 0xff, 0xff, 0xff), +- .driver_info = (kernel_ulong_t)&net_intf3_blacklist }, ++ .driver_info = RSVD(3) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0159, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0161, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0162, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0164, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0165, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0167, 0xff, 0xff, 0xff), +- .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, ++ .driver_info = RSVD(4) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0189, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0191, 0xff, 0xff, 0xff), /* ZTE EuFi890 */ +- .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, ++ .driver_info = RSVD(4) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0196, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0197, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0199, 0xff, 0xff, 0xff), /* ZTE MF820S */ +- .driver_info = (kernel_ulong_t)&net_intf1_blacklist }, ++ .driver_info = RSVD(1) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0200, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0201, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0254, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0257, 0xff, 0xff, 0xff), /* ZTE MF821 */ +- .driver_info = (kernel_ulong_t)&net_intf3_blacklist }, ++ .driver_info = RSVD(3) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0265, 0xff, 0xff, 0xff), /* ONDA MT8205 */ +- .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, ++ .driver_info = RSVD(4) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0284, 0xff, 0xff, 0xff), /* ZTE MF880 */ +- .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, ++ .driver_info = RSVD(4) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0317, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0326, 0xff, 0xff, 0xff), +- .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, ++ .driver_info = RSVD(4) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0330, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0395, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0412, 0xff, 0xff, 0xff), /* Telewell TW-LTE 4G */ +- .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, ++ .driver_info = RSVD(4) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0414, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0417, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1008, 0xff, 0xff, 0xff), +- .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, ++ .driver_info = RSVD(4) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1010, 0xff, 0xff, 0xff), +- .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, ++ .driver_info = RSVD(4) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1012, 0xff, 0xff, 0xff), +- .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, ++ .driver_info = RSVD(4) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1018, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1021, 0xff, 0xff, 0xff), +- .driver_info = (kernel_ulong_t)&net_intf2_blacklist }, ++ .driver_info = RSVD(2) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1057, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1058, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1059, 0xff, 0xff, 0xff) }, +@@ -1576,23 +1440,23 @@ static const struct usb_device_id option + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1170, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1244, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1245, 0xff, 0xff, 0xff), +- .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, ++ .driver_info = RSVD(4) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1246, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1247, 0xff, 0xff, 0xff), +- .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, ++ .driver_info = RSVD(4) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1248, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1249, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1250, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1251, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1252, 0xff, 0xff, 0xff), +- .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, ++ .driver_info = RSVD(4) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1253, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1254, 0xff, 0xff, 0xff), +- .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, ++ .driver_info = RSVD(4) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1255, 0xff, 0xff, 0xff), +- .driver_info = (kernel_ulong_t)&zte_1255_blacklist }, ++ .driver_info = RSVD(3) | RSVD(4) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1256, 0xff, 0xff, 0xff), +- .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, ++ .driver_info = RSVD(4) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1257, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1258, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1259, 0xff, 0xff, 0xff) }, +@@ -1607,7 +1471,7 @@ static const struct usb_device_id option + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1268, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1269, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1270, 0xff, 0xff, 0xff), +- .driver_info = (kernel_ulong_t)&net_intf5_blacklist }, ++ .driver_info = RSVD(5) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1271, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1272, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1273, 0xff, 0xff, 0xff) }, +@@ -1643,17 +1507,17 @@ static const struct usb_device_id option + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1303, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1333, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1401, 0xff, 0xff, 0xff), +- .driver_info = (kernel_ulong_t)&net_intf2_blacklist }, ++ .driver_info = RSVD(2) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1402, 0xff, 0xff, 0xff), +- .driver_info = (kernel_ulong_t)&net_intf2_blacklist }, ++ .driver_info = RSVD(2) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1424, 0xff, 0xff, 0xff), +- .driver_info = (kernel_ulong_t)&net_intf2_blacklist }, ++ .driver_info = RSVD(2) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1425, 0xff, 0xff, 0xff), +- .driver_info = (kernel_ulong_t)&net_intf2_blacklist }, ++ .driver_info = RSVD(2) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1426, 0xff, 0xff, 0xff), /* ZTE MF91 */ +- .driver_info = (kernel_ulong_t)&net_intf2_blacklist }, ++ .driver_info = RSVD(2) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1428, 0xff, 0xff, 0xff), /* Telewell TW-LTE 4G v2 */ +- .driver_info = (kernel_ulong_t)&net_intf2_blacklist }, ++ .driver_info = RSVD(2) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1533, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1534, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1535, 0xff, 0xff, 0xff) }, +@@ -1671,8 +1535,8 @@ static const struct usb_device_id option + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1596, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1598, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1600, 0xff, 0xff, 0xff) }, +- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x2002, 0xff, +- 0xff, 0xff), .driver_info = (kernel_ulong_t)&zte_k3765_z_blacklist }, ++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x2002, 0xff, 0xff, 0xff), ++ .driver_info = NCTRL(0) | NCTRL(1) | NCTRL(2) | RSVD(4) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x2003, 0xff, 0xff, 0xff) }, + + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0014, 0xff, 0xff, 0xff) }, /* ZTE CDMA products */ +@@ -1683,20 +1547,20 @@ static const struct usb_device_id option + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0073, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0094, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0130, 0xff, 0xff, 0xff), +- .driver_info = (kernel_ulong_t)&net_intf1_blacklist }, ++ .driver_info = RSVD(1) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0133, 0xff, 0xff, 0xff), +- .driver_info = (kernel_ulong_t)&net_intf3_blacklist }, ++ .driver_info = RSVD(3) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0141, 0xff, 0xff, 0xff), +- .driver_info = (kernel_ulong_t)&net_intf5_blacklist }, ++ .driver_info = RSVD(5) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0147, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0152, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0168, 0xff, 0xff, 0xff), +- .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, ++ .driver_info = RSVD(4) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0170, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0176, 0xff, 0xff, 0xff), +- .driver_info = (kernel_ulong_t)&net_intf3_blacklist }, ++ .driver_info = RSVD(3) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0178, 0xff, 0xff, 0xff), +- .driver_info = (kernel_ulong_t)&net_intf3_blacklist }, ++ .driver_info = RSVD(3) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff42, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff43, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff44, 0xff, 0xff, 0xff) }, +@@ -1848,19 +1712,19 @@ static const struct usb_device_id option + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AC2726, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AC8710T, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MC2718, 0xff, 0xff, 0xff), +- .driver_info = (kernel_ulong_t)&zte_mc2718_z_blacklist }, ++ .driver_info = NCTRL(1) | NCTRL(2) | NCTRL(3) | NCTRL(4) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AD3812, 0xff, 0xff, 0xff), +- .driver_info = (kernel_ulong_t)&zte_ad3812_z_blacklist }, ++ .driver_info = NCTRL(0) | NCTRL(1) | NCTRL(2) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MC2716, 0xff, 0xff, 0xff), +- .driver_info = (kernel_ulong_t)&zte_mc2716_z_blacklist }, ++ .driver_info = NCTRL(1) | NCTRL(2) | NCTRL(3) }, + { USB_DEVICE(ZTE_VENDOR_ID, ZTE_PRODUCT_ME3620_L), +- .driver_info = (kernel_ulong_t)&zte_me3620_xl_blacklist }, ++ .driver_info = RSVD(3) | RSVD(4) | RSVD(5) }, + { USB_DEVICE(ZTE_VENDOR_ID, ZTE_PRODUCT_ME3620_MBIM), +- .driver_info = (kernel_ulong_t)&zte_me3620_mbim_blacklist }, ++ .driver_info = RSVD(2) | RSVD(3) | RSVD(4) }, + { USB_DEVICE(ZTE_VENDOR_ID, ZTE_PRODUCT_ME3620_X), +- .driver_info = (kernel_ulong_t)&zte_me3620_xl_blacklist }, ++ .driver_info = RSVD(3) | RSVD(4) | RSVD(5) }, + { USB_DEVICE(ZTE_VENDOR_ID, ZTE_PRODUCT_ZM8620_X), +- .driver_info = (kernel_ulong_t)&zte_zm8620_x_blacklist }, ++ .driver_info = RSVD(3) | RSVD(4) | RSVD(5) }, + { USB_VENDOR_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff, 0x02, 0x01) }, + { USB_VENDOR_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff, 0x02, 0x05) }, + { USB_VENDOR_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff, 0x86, 0x10) }, +@@ -1880,37 +1744,34 @@ static const struct usb_device_id option + { USB_DEVICE(ALINK_VENDOR_ID, ALINK_PRODUCT_PH300) }, + { USB_DEVICE_AND_INTERFACE_INFO(ALINK_VENDOR_ID, ALINK_PRODUCT_3GU, 0xff, 0xff, 0xff) }, + { USB_DEVICE(ALINK_VENDOR_ID, SIMCOM_PRODUCT_SIM7100E), +- .driver_info = (kernel_ulong_t)&simcom_sim7100e_blacklist }, ++ .driver_info = RSVD(5) | RSVD(6) }, + { USB_DEVICE(ALCATEL_VENDOR_ID, ALCATEL_PRODUCT_X060S_X200), +- .driver_info = (kernel_ulong_t)&alcatel_x200_blacklist +- }, ++ .driver_info = NCTRL(0) | NCTRL(1) | RSVD(4) }, + { USB_DEVICE(ALCATEL_VENDOR_ID, ALCATEL_PRODUCT_X220_X500D), +- .driver_info = (kernel_ulong_t)&net_intf6_blacklist }, ++ .driver_info = RSVD(6) }, + { USB_DEVICE(ALCATEL_VENDOR_ID, 0x0052), +- .driver_info = (kernel_ulong_t)&net_intf6_blacklist }, ++ .driver_info = RSVD(6) }, + { USB_DEVICE(ALCATEL_VENDOR_ID, 0x00b6), +- .driver_info = (kernel_ulong_t)&net_intf3_blacklist }, ++ .driver_info = RSVD(3) }, + { USB_DEVICE(ALCATEL_VENDOR_ID, 0x00b7), +- .driver_info = (kernel_ulong_t)&net_intf5_blacklist }, ++ .driver_info = RSVD(5) }, + { USB_DEVICE(ALCATEL_VENDOR_ID, ALCATEL_PRODUCT_L100V), +- .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, ++ .driver_info = RSVD(4) }, + { USB_DEVICE(ALCATEL_VENDOR_ID, ALCATEL_PRODUCT_L800MA), +- .driver_info = (kernel_ulong_t)&net_intf2_blacklist }, ++ .driver_info = RSVD(2) }, + { USB_DEVICE(AIRPLUS_VENDOR_ID, AIRPLUS_PRODUCT_MCD650) }, + { USB_DEVICE(TLAYTECH_VENDOR_ID, TLAYTECH_PRODUCT_TEU800) }, + { USB_DEVICE(LONGCHEER_VENDOR_ID, FOUR_G_SYSTEMS_PRODUCT_W14), +- .driver_info = (kernel_ulong_t)&four_g_w14_blacklist +- }, ++ .driver_info = NCTRL(0) | NCTRL(1) }, + { USB_DEVICE(LONGCHEER_VENDOR_ID, FOUR_G_SYSTEMS_PRODUCT_W100), +- .driver_info = (kernel_ulong_t)&four_g_w100_blacklist +- }, ++ .driver_info = NCTRL(1) | NCTRL(2) | RSVD(3) }, + {USB_DEVICE(LONGCHEER_VENDOR_ID, FUJISOFT_PRODUCT_FS040U), +- .driver_info = (kernel_ulong_t)&net_intf3_blacklist}, ++ .driver_info = RSVD(3)}, + { USB_DEVICE_INTERFACE_CLASS(LONGCHEER_VENDOR_ID, SPEEDUP_PRODUCT_SU9800, 0xff) }, + { USB_DEVICE_INTERFACE_CLASS(LONGCHEER_VENDOR_ID, 0x9801, 0xff), +- .driver_info = (kernel_ulong_t)&net_intf3_blacklist }, ++ .driver_info = RSVD(3) }, + { USB_DEVICE_INTERFACE_CLASS(LONGCHEER_VENDOR_ID, 0x9803, 0xff), +- .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, ++ .driver_info = RSVD(4) }, + { USB_DEVICE(LONGCHEER_VENDOR_ID, ZOOM_PRODUCT_4597) }, + { USB_DEVICE(LONGCHEER_VENDOR_ID, IBALL_3_5G_CONNECT) }, + { USB_DEVICE(HAIER_VENDOR_ID, HAIER_PRODUCT_CE100) }, +@@ -1936,14 +1797,14 @@ static const struct usb_device_id option + { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_EU3_E) }, + { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_EU3_P) }, + { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_PH8), +- .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, ++ .driver_info = RSVD(4) }, + { USB_DEVICE_INTERFACE_CLASS(CINTERION_VENDOR_ID, CINTERION_PRODUCT_AHXX, 0xff) }, + { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_PLXX), +- .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, ++ .driver_info = RSVD(4) }, + { USB_DEVICE_INTERFACE_CLASS(CINTERION_VENDOR_ID, CINTERION_PRODUCT_PH8_2RMNET, 0xff), +- .driver_info = (kernel_ulong_t)&cinterion_rmnet2_blacklist }, ++ .driver_info = RSVD(4) | RSVD(5) }, + { USB_DEVICE_INTERFACE_CLASS(CINTERION_VENDOR_ID, CINTERION_PRODUCT_PH8_AUDIO, 0xff), +- .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, ++ .driver_info = RSVD(4) }, + { USB_DEVICE_INTERFACE_CLASS(CINTERION_VENDOR_ID, CINTERION_PRODUCT_AHXX_2RMNET, 0xff) }, + { USB_DEVICE_INTERFACE_CLASS(CINTERION_VENDOR_ID, CINTERION_PRODUCT_AHXX_AUDIO, 0xff) }, + { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_HC28_MDM) }, +@@ -1953,20 +1814,20 @@ static const struct usb_device_id option + { USB_DEVICE(SIEMENS_VENDOR_ID, CINTERION_PRODUCT_HC28_MDM) }, /* HC28 enumerates with Siemens or Cinterion VID depending on FW revision */ + { USB_DEVICE(SIEMENS_VENDOR_ID, CINTERION_PRODUCT_HC28_MDMNET) }, + { USB_DEVICE(OLIVETTI_VENDOR_ID, OLIVETTI_PRODUCT_OLICARD100), +- .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, ++ .driver_info = RSVD(4) }, + { USB_DEVICE(OLIVETTI_VENDOR_ID, OLIVETTI_PRODUCT_OLICARD120), +- .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, ++ .driver_info = RSVD(4) }, + { USB_DEVICE(OLIVETTI_VENDOR_ID, OLIVETTI_PRODUCT_OLICARD140), +- .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, ++ .driver_info = RSVD(4) }, + { USB_DEVICE(OLIVETTI_VENDOR_ID, OLIVETTI_PRODUCT_OLICARD145) }, + { USB_DEVICE(OLIVETTI_VENDOR_ID, OLIVETTI_PRODUCT_OLICARD155), +- .driver_info = (kernel_ulong_t)&net_intf6_blacklist }, ++ .driver_info = RSVD(6) }, + { USB_DEVICE(OLIVETTI_VENDOR_ID, OLIVETTI_PRODUCT_OLICARD200), +- .driver_info = (kernel_ulong_t)&net_intf6_blacklist }, ++ .driver_info = RSVD(6) }, + { USB_DEVICE(OLIVETTI_VENDOR_ID, OLIVETTI_PRODUCT_OLICARD160), +- .driver_info = (kernel_ulong_t)&net_intf6_blacklist }, ++ .driver_info = RSVD(6) }, + { USB_DEVICE(OLIVETTI_VENDOR_ID, OLIVETTI_PRODUCT_OLICARD500), +- .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, ++ .driver_info = RSVD(4) }, + { USB_DEVICE(CELOT_VENDOR_ID, CELOT_PRODUCT_CT680M) }, /* CT-650 CDMA 450 1xEVDO modem */ + { USB_DEVICE_AND_INTERFACE_INFO(SAMSUNG_VENDOR_ID, SAMSUNG_PRODUCT_GT_B3730, USB_CLASS_CDC_DATA, 0x00, 0x00) }, /* Samsung GT-B3730 LTE USB modem.*/ + { USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CEM600) }, +@@ -2043,9 +1904,9 @@ static const struct usb_device_id option + { USB_DEVICE(PETATEL_VENDOR_ID, PETATEL_PRODUCT_NP10T_600E) }, + { USB_DEVICE_AND_INTERFACE_INFO(TPLINK_VENDOR_ID, TPLINK_PRODUCT_LTE, 0xff, 0x00, 0x00) }, /* TP-Link LTE Module */ + { USB_DEVICE(TPLINK_VENDOR_ID, TPLINK_PRODUCT_MA180), +- .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, ++ .driver_info = RSVD(4) }, + { USB_DEVICE(TPLINK_VENDOR_ID, 0x9000), /* TP-Link MA260 */ +- .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, ++ .driver_info = RSVD(4) }, + { USB_DEVICE(CHANGHONG_VENDOR_ID, CHANGHONG_PRODUCT_CH690) }, + { USB_DEVICE_INTERFACE_CLASS(0x2001, 0x7d01, 0xff) }, /* D-Link DWM-156 (variant) */ + { USB_DEVICE_INTERFACE_CLASS(0x2001, 0x7d02, 0xff) }, +@@ -2053,9 +1914,9 @@ static const struct usb_device_id option + { USB_DEVICE_INTERFACE_CLASS(0x2001, 0x7d04, 0xff) }, /* D-Link DWM-158 */ + { USB_DEVICE_INTERFACE_CLASS(0x2001, 0x7d0e, 0xff) }, /* D-Link DWM-157 C1 */ + { USB_DEVICE_INTERFACE_CLASS(0x2001, 0x7e19, 0xff), /* D-Link DWM-221 B1 */ +- .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, ++ .driver_info = RSVD(4) }, + { USB_DEVICE_INTERFACE_CLASS(0x2001, 0x7e35, 0xff), /* D-Link DWM-222 */ +- .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, ++ .driver_info = RSVD(4) }, + { USB_DEVICE_AND_INTERFACE_INFO(0x07d1, 0x3e01, 0xff, 0xff, 0xff) }, /* D-Link DWM-152/C1 */ + { USB_DEVICE_AND_INTERFACE_INFO(0x07d1, 0x3e02, 0xff, 0xff, 0xff) }, /* D-Link DWM-156/C1 */ + { USB_DEVICE_AND_INTERFACE_INFO(0x07d1, 0x7e11, 0xff, 0xff, 0xff) }, /* D-Link DWM-156/A3 */ +@@ -2115,7 +1976,7 @@ static int option_probe(struct usb_seria + struct usb_interface_descriptor *iface_desc = + &serial->interface->cur_altsetting->desc; + struct usb_device_descriptor *dev_desc = &serial->dev->descriptor; +- const struct option_blacklist_info *blacklist; ++ unsigned long device_flags = id->driver_info; + + /* Never bind to the CD-Rom emulation interface */ + if (iface_desc->bInterfaceClass == 0x08) +@@ -2126,9 +1987,7 @@ static int option_probe(struct usb_seria + * the same class/subclass/protocol as the serial interfaces. Look at + * the Windows driver .INF files for reserved interface numbers. + */ +- blacklist = (void *)id->driver_info; +- if (blacklist && test_bit(iface_desc->bInterfaceNumber, +- &blacklist->reserved)) ++ if (device_flags & RSVD(iface_desc->bInterfaceNumber)) + return -ENODEV; + /* + * Don't bind network interface on Samsung GT-B3730, it is handled by +@@ -2139,8 +1998,8 @@ static int option_probe(struct usb_seria + iface_desc->bInterfaceClass != USB_CLASS_CDC_DATA) + return -ENODEV; + +- /* Store the blacklist info so we can use it during attach. */ +- usb_set_serial_data(serial, (void *)blacklist); ++ /* Store the device flags so we can use them during attach. */ ++ usb_set_serial_data(serial, (void *)device_flags); + + return 0; + } +@@ -2148,22 +2007,21 @@ static int option_probe(struct usb_seria + static int option_attach(struct usb_serial *serial) + { + struct usb_interface_descriptor *iface_desc; +- const struct option_blacklist_info *blacklist; + struct usb_wwan_intf_private *data; ++ unsigned long device_flags; + + data = kzalloc(sizeof(struct usb_wwan_intf_private), GFP_KERNEL); + if (!data) + return -ENOMEM; + +- /* Retrieve blacklist info stored at probe. */ +- blacklist = usb_get_serial_data(serial); ++ /* Retrieve device flags stored at probe. */ ++ device_flags = (unsigned long)usb_get_serial_data(serial); + + iface_desc = &serial->interface->cur_altsetting->desc; + +- if (!blacklist || !test_bit(iface_desc->bInterfaceNumber, +- &blacklist->sendsetup)) { ++ if (!(device_flags & NCTRL(iface_desc->bInterfaceNumber))) + data->use_send_setup = 1; +- } ++ + spin_lock_init(&data->susp_lock); + + usb_set_serial_data(serial, data); diff --git a/queue-4.16/usb-serial-visor-handle-potential-invalid-device-configuration.patch b/queue-4.16/usb-serial-visor-handle-potential-invalid-device-configuration.patch new file mode 100644 index 00000000000..d3c14fac911 --- /dev/null +++ b/queue-4.16/usb-serial-visor-handle-potential-invalid-device-configuration.patch @@ -0,0 +1,115 @@ +From 4842ed5bfcb9daf6660537d70503c18d38dbdbb8 Mon Sep 17 00:00:00 2001 +From: Greg Kroah-Hartman +Date: Sun, 29 Apr 2018 17:41:55 +0200 +Subject: USB: serial: visor: handle potential invalid device configuration + +From: Greg Kroah-Hartman + +commit 4842ed5bfcb9daf6660537d70503c18d38dbdbb8 upstream. + +If we get an invalid device configuration from a palm 3 type device, we +might incorrectly parse things, and we have the potential to crash in +"interesting" ways. + +Fix this up by verifying the size of the configuration passed to us by +the device, and only if it is correct, will we handle it. + +Note that this also fixes an information leak of slab data. + +Reported-by: Andrey Konovalov +Reviewed-by: Andrey Konovalov +Signed-off-by: Greg Kroah-Hartman +[ johan: add comment about the info leak ] +Cc: stable +Signed-off-by: Johan Hovold +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/serial/visor.c | 69 ++++++++++++++++++++++----------------------- + 1 file changed, 35 insertions(+), 34 deletions(-) + +--- a/drivers/usb/serial/visor.c ++++ b/drivers/usb/serial/visor.c +@@ -335,47 +335,48 @@ static int palm_os_3_probe(struct usb_se + goto exit; + } + +- if (retval == sizeof(*connection_info)) { +- connection_info = (struct visor_connection_info *) +- transfer_buffer; +- +- num_ports = le16_to_cpu(connection_info->num_ports); +- for (i = 0; i < num_ports; ++i) { +- switch ( +- connection_info->connections[i].port_function_id) { +- case VISOR_FUNCTION_GENERIC: +- string = "Generic"; +- break; +- case VISOR_FUNCTION_DEBUGGER: +- string = "Debugger"; +- break; +- case VISOR_FUNCTION_HOTSYNC: +- string = "HotSync"; +- break; +- case VISOR_FUNCTION_CONSOLE: +- string = "Console"; +- break; +- case VISOR_FUNCTION_REMOTE_FILE_SYS: +- string = "Remote File System"; +- break; +- default: +- string = "unknown"; +- break; +- } +- dev_info(dev, "%s: port %d, is for %s use\n", +- serial->type->description, +- connection_info->connections[i].port, string); +- } ++ if (retval != sizeof(*connection_info)) { ++ dev_err(dev, "Invalid connection information received from device\n"); ++ retval = -ENODEV; ++ goto exit; + } +- /* +- * Handle devices that report invalid stuff here. +- */ ++ ++ connection_info = (struct visor_connection_info *)transfer_buffer; ++ ++ num_ports = le16_to_cpu(connection_info->num_ports); ++ ++ /* Handle devices that report invalid stuff here. */ + if (num_ports == 0 || num_ports > 2) { + dev_warn(dev, "%s: No valid connect info available\n", + serial->type->description); + num_ports = 2; + } + ++ for (i = 0; i < num_ports; ++i) { ++ switch (connection_info->connections[i].port_function_id) { ++ case VISOR_FUNCTION_GENERIC: ++ string = "Generic"; ++ break; ++ case VISOR_FUNCTION_DEBUGGER: ++ string = "Debugger"; ++ break; ++ case VISOR_FUNCTION_HOTSYNC: ++ string = "HotSync"; ++ break; ++ case VISOR_FUNCTION_CONSOLE: ++ string = "Console"; ++ break; ++ case VISOR_FUNCTION_REMOTE_FILE_SYS: ++ string = "Remote File System"; ++ break; ++ default: ++ string = "unknown"; ++ break; ++ } ++ dev_info(dev, "%s: port %d, is for %s use\n", ++ serial->type->description, ++ connection_info->connections[i].port, string); ++ } + dev_info(dev, "%s: Number of ports: %d\n", serial->type->description, + num_ports); + diff --git a/queue-4.16/x86-tsc-always-unregister-clocksource_tsc_early.patch b/queue-4.16/x86-tsc-always-unregister-clocksource_tsc_early.patch new file mode 100644 index 00000000000..2f0a557c221 --- /dev/null +++ b/queue-4.16/x86-tsc-always-unregister-clocksource_tsc_early.patch @@ -0,0 +1,77 @@ +From e9088adda13cd23249d4b0abb97ff8a81bf5573a Mon Sep 17 00:00:00 2001 +From: Peter Zijlstra +Date: Mon, 30 Apr 2018 12:00:09 +0200 +Subject: x86/tsc: Always unregister clocksource_tsc_early + +From: Peter Zijlstra + +commit e9088adda13cd23249d4b0abb97ff8a81bf5573a upstream. + +Don't leave the tsc-early clocksource registered if it errors out +early. + +This was reported by Diego, who on his Core2 era machine got TSC +invalidated while it was running with tsc-early (due to C-states). +This results in keeping tsc-early with very bad effects. + +Reported-and-Tested-by: Diego Viola +Fixes: aa83c45762a2 ("x86/tsc: Introduce early tsc clocksource") +Signed-off-by: Peter Zijlstra (Intel) +Signed-off-by: Thomas Gleixner +Reviewed-by: Rafael J. Wysocki +Cc: len.brown@intel.com +Cc: rjw@rjwysocki.net +Cc: diego.viola@gmail.com +Cc: rui.zhang@intel.com +Cc: stable@vger.kernel.org +Link: https://lkml.kernel.org/r/20180430100344.350507853@infradead.org +Signed-off-by: Greg Kroah-Hartman + +--- + arch/x86/kernel/tsc.c | 10 ++++++---- + 1 file changed, 6 insertions(+), 4 deletions(-) + +--- a/arch/x86/kernel/tsc.c ++++ b/arch/x86/kernel/tsc.c +@@ -1205,7 +1205,7 @@ static void tsc_refine_calibration_work( + + /* Don't bother refining TSC on unstable systems */ + if (tsc_unstable) +- return; ++ goto unreg; + + /* + * Since the work is started early in boot, we may be +@@ -1258,11 +1258,12 @@ static void tsc_refine_calibration_work( + + out: + if (tsc_unstable) +- return; ++ goto unreg; + + if (boot_cpu_has(X86_FEATURE_ART)) + art_related_clocksource = &clocksource_tsc; + clocksource_register_khz(&clocksource_tsc, tsc_khz); ++unreg: + clocksource_unregister(&clocksource_tsc_early); + } + +@@ -1272,8 +1273,8 @@ static int __init init_tsc_clocksource(v + if (!boot_cpu_has(X86_FEATURE_TSC) || tsc_disabled > 0 || !tsc_khz) + return 0; + +- if (check_tsc_unstable()) +- return 0; ++ if (tsc_unstable) ++ goto unreg; + + if (tsc_clocksource_reliable) + clocksource_tsc.flags &= ~CLOCK_SOURCE_MUST_VERIFY; +@@ -1289,6 +1290,7 @@ static int __init init_tsc_clocksource(v + if (boot_cpu_has(X86_FEATURE_ART)) + art_related_clocksource = &clocksource_tsc; + clocksource_register_khz(&clocksource_tsc, tsc_khz); ++unreg: + clocksource_unregister(&clocksource_tsc_early); + return 0; + } diff --git a/queue-4.16/x86-tsc-fix-mark_tsc_unstable.patch b/queue-4.16/x86-tsc-fix-mark_tsc_unstable.patch new file mode 100644 index 00000000000..f509cbd9882 --- /dev/null +++ b/queue-4.16/x86-tsc-fix-mark_tsc_unstable.patch @@ -0,0 +1,67 @@ +From e3b4f79025e0a4eb7e2a2c7d24dadfa1e38893b0 Mon Sep 17 00:00:00 2001 +From: Peter Zijlstra +Date: Mon, 30 Apr 2018 12:00:12 +0200 +Subject: x86/tsc: Fix mark_tsc_unstable() + +From: Peter Zijlstra + +commit e3b4f79025e0a4eb7e2a2c7d24dadfa1e38893b0 upstream. + +mark_tsc_unstable() also needs to affect tsc_early, Now that +clocksource_mark_unstable() can be used on a clocksource irrespective of +its registration state, use it on both tsc_early and tsc. + +This does however require cs->list to be initialized empty, otherwise it +cannot tell the registation state before registation. + +Fixes: aa83c45762a2 ("x86/tsc: Introduce early tsc clocksource") +Signed-off-by: Peter Zijlstra (Intel) +Signed-off-by: Thomas Gleixner +Tested-by: Diego Viola +Reviewed-by: Rafael J. Wysocki +Cc: len.brown@intel.com +Cc: rjw@rjwysocki.net +Cc: rui.zhang@intel.com +Cc: stable@vger.kernel.org +Link: https://lkml.kernel.org/r/20180430100344.533326547@infradead.org +Signed-off-by: Greg Kroah-Hartman + +--- + arch/x86/kernel/tsc.c | 12 +++++------- + 1 file changed, 5 insertions(+), 7 deletions(-) + +--- a/arch/x86/kernel/tsc.c ++++ b/arch/x86/kernel/tsc.c +@@ -1067,6 +1067,7 @@ static struct clocksource clocksource_ts + .resume = tsc_resume, + .mark_unstable = tsc_cs_mark_unstable, + .tick_stable = tsc_cs_tick_stable, ++ .list = LIST_HEAD_INIT(clocksource_tsc_early.list), + }; + + /* +@@ -1086,6 +1087,7 @@ static struct clocksource clocksource_ts + .resume = tsc_resume, + .mark_unstable = tsc_cs_mark_unstable, + .tick_stable = tsc_cs_tick_stable, ++ .list = LIST_HEAD_INIT(clocksource_tsc.list), + }; + + void mark_tsc_unstable(char *reason) +@@ -1098,13 +1100,9 @@ void mark_tsc_unstable(char *reason) + clear_sched_clock_stable(); + disable_sched_clock_irqtime(); + pr_info("Marking TSC unstable due to %s\n", reason); +- /* Change only the rating, when not registered */ +- if (clocksource_tsc.mult) { +- clocksource_mark_unstable(&clocksource_tsc); +- } else { +- clocksource_tsc.flags |= CLOCK_SOURCE_UNSTABLE; +- clocksource_tsc.rating = 0; +- } ++ ++ clocksource_mark_unstable(&clocksource_tsc_early); ++ clocksource_mark_unstable(&clocksource_tsc); + } + + EXPORT_SYMBOL_GPL(mark_tsc_unstable); diff --git a/queue-4.16/xhci-fix-use-after-free-in-xhci_free_virt_device.patch b/queue-4.16/xhci-fix-use-after-free-in-xhci_free_virt_device.patch new file mode 100644 index 00000000000..54d5f9b36aa --- /dev/null +++ b/queue-4.16/xhci-fix-use-after-free-in-xhci_free_virt_device.patch @@ -0,0 +1,45 @@ +From 44a182b9d17765514fa2b1cc911e4e65134eef93 Mon Sep 17 00:00:00 2001 +From: Mathias Nyman +Date: Thu, 3 May 2018 17:30:07 +0300 +Subject: xhci: Fix use-after-free in xhci_free_virt_device + +From: Mathias Nyman + +commit 44a182b9d17765514fa2b1cc911e4e65134eef93 upstream. + +KASAN found a use-after-free in xhci_free_virt_device+0x33b/0x38e +where xhci_free_virt_device() sets slot id to 0 if udev exists: +if (dev->udev && dev->udev->slot_id) + dev->udev->slot_id = 0; + +dev->udev will be true even if udev is freed because dev->udev is +not set to NULL. + +set dev->udev pointer to NULL in xhci_free_dev() + +The original patch went to stable so this fix needs to be applied +there as well. + +Fixes: a400efe455f7 ("xhci: zero usb device slot_id member when disabling and freeing a xhci slot") +Cc: +Reported-by: Guenter Roeck +Reviewed-by: Guenter Roeck +Tested-by: Guenter Roeck +Signed-off-by: Mathias Nyman +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/host/xhci.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/usb/host/xhci.c ++++ b/drivers/usb/host/xhci.c +@@ -3548,6 +3548,7 @@ static void xhci_free_dev(struct usb_hcd + del_timer_sync(&virt_dev->eps[i].stop_cmd_timer); + } + xhci_debugfs_remove_slot(xhci, udev->slot_id); ++ virt_dev->udev = NULL; + ret = xhci_disable_slot(xhci, udev->slot_id); + if (ret) + xhci_free_virt_device(xhci, udev->slot_id); -- 2.47.2