--- /dev/null
+From 2d5030c98838e37be3c8b0f3568f91c8e0774fa2 Mon Sep 17 00:00:00 2001
+From: Daniel Borkmann <daniel@iogearbox.net>
+Date: Thu, 1 Nov 2018 22:30:38 +0100
+Subject: bpf: fix partial copy of map_ptr when dst is scalar
+
+commit 0962590e553331db2cc0aef2dc35c57f6300dbbe upstream.
+
+ALU operations on pointers such as scalar_reg += map_value_ptr are
+handled in adjust_ptr_min_max_vals(). Problem is however that map_ptr
+and range in the register state share a union, so transferring state
+through dst_reg->range = ptr_reg->range is just buggy as any new
+map_ptr in the dst_reg is then truncated (or null) for subsequent
+checks. Fix this by adding a raw member and use it for copying state
+over to dst_reg.
+
+Fixes: f1174f77b50c ("bpf/verifier: rework value tracking")
+Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
+Cc: Edward Cree <ecree@solarflare.com>
+Acked-by: Alexei Starovoitov <ast@kernel.org>
+Signed-off-by: Alexei Starovoitov <ast@kernel.org>
+Acked-by: Edward Cree <ecree@solarflare.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/bpf_verifier.h | 3 +++
+ kernel/bpf/verifier.c | 10 ++++++----
+ 2 files changed, 9 insertions(+), 4 deletions(-)
+
+diff --git a/include/linux/bpf_verifier.h b/include/linux/bpf_verifier.h
+index 73bec75b74c8..a3333004fd2b 100644
+--- a/include/linux/bpf_verifier.h
++++ b/include/linux/bpf_verifier.h
+@@ -50,6 +50,9 @@ struct bpf_reg_state {
+ * PTR_TO_MAP_VALUE_OR_NULL
+ */
+ struct bpf_map *map_ptr;
++
++ /* Max size from any of the above. */
++ unsigned long raw;
+ };
+ /* Fixed part of pointer offset, pointer types only */
+ s32 off;
+diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
+index a0ffc62e7677..013b0cd1958e 100644
+--- a/kernel/bpf/verifier.c
++++ b/kernel/bpf/verifier.c
+@@ -1935,7 +1935,7 @@ static int adjust_ptr_min_max_vals(struct bpf_verifier_env *env,
+ dst_reg->umax_value = umax_ptr;
+ dst_reg->var_off = ptr_reg->var_off;
+ dst_reg->off = ptr_reg->off + smin_val;
+- dst_reg->range = ptr_reg->range;
++ dst_reg->raw = ptr_reg->raw;
+ break;
+ }
+ /* A new variable offset is created. Note that off_reg->off
+@@ -1965,10 +1965,11 @@ static int adjust_ptr_min_max_vals(struct bpf_verifier_env *env,
+ }
+ dst_reg->var_off = tnum_add(ptr_reg->var_off, off_reg->var_off);
+ dst_reg->off = ptr_reg->off;
++ dst_reg->raw = ptr_reg->raw;
+ if (ptr_reg->type == PTR_TO_PACKET) {
+ dst_reg->id = ++env->id_gen;
+ /* something was added to pkt_ptr, set range to zero */
+- dst_reg->range = 0;
++ dst_reg->raw = 0;
+ }
+ break;
+ case BPF_SUB:
+@@ -1999,7 +2000,7 @@ static int adjust_ptr_min_max_vals(struct bpf_verifier_env *env,
+ dst_reg->var_off = ptr_reg->var_off;
+ dst_reg->id = ptr_reg->id;
+ dst_reg->off = ptr_reg->off - smin_val;
+- dst_reg->range = ptr_reg->range;
++ dst_reg->raw = ptr_reg->raw;
+ break;
+ }
+ /* A new variable offset is created. If the subtrahend is known
+@@ -2025,11 +2026,12 @@ static int adjust_ptr_min_max_vals(struct bpf_verifier_env *env,
+ }
+ dst_reg->var_off = tnum_sub(ptr_reg->var_off, off_reg->var_off);
+ dst_reg->off = ptr_reg->off;
++ dst_reg->raw = ptr_reg->raw;
+ if (ptr_reg->type == PTR_TO_PACKET) {
+ dst_reg->id = ++env->id_gen;
+ /* something was added to pkt_ptr, set range to zero */
+ if (smin_val < 0)
+- dst_reg->range = 0;
++ dst_reg->raw = 0;
+ }
+ break;
+ case BPF_AND:
+--
+2.17.1
+
--- /dev/null
+From 4cd924ba72d77eb135eef248b11c85106b58df3f Mon Sep 17 00:00:00 2001
+From: Dmitry Osipenko <digetx@gmail.com>
+Date: Tue, 8 May 2018 19:26:06 +0300
+Subject: clk: tegra: Add quirk for getting CDEV1/2 clocks on Tegra20
+
+[ Upstream commit 5d797111afe12e488e08432fd9b372fae2cc7e93 ]
+
+CDEV1 and CDEV2 clocks are a bit special case, their parent clock is
+created by the pinctrl driver. It should be possible for clk user to
+request these clocks before pinctrl driver got probed and hence user will
+get an orphaned clock. That might be undesirable because user may expect
+parent clock to be enabled by the child, so let's return -EPROBE_DEFER
+till parent clock appears.
+
+Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
+Acked-by: Peter De Schrijver <pdeschrijver@nvidia.com>
+Signed-off-by: Thierry Reding <treding@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/clk/tegra/clk-tegra114.c | 2 +-
+ drivers/clk/tegra/clk-tegra124.c | 2 +-
+ drivers/clk/tegra/clk-tegra20.c | 32 +++++++++++++++++++++++++++++++-
+ drivers/clk/tegra/clk-tegra210.c | 2 +-
+ drivers/clk/tegra/clk-tegra30.c | 2 +-
+ drivers/clk/tegra/clk.c | 5 +++--
+ drivers/clk/tegra/clk.h | 2 +-
+ 7 files changed, 39 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/clk/tegra/clk-tegra114.c b/drivers/clk/tegra/clk-tegra114.c
+index fd1a99c05c2d..f94d1c016643 100644
+--- a/drivers/clk/tegra/clk-tegra114.c
++++ b/drivers/clk/tegra/clk-tegra114.c
+@@ -1369,7 +1369,7 @@ static void __init tegra114_clock_init(struct device_node *np)
+ tegra_super_clk_gen4_init(clk_base, pmc_base, tegra114_clks,
+ &pll_x_params);
+
+- tegra_add_of_provider(np);
++ tegra_add_of_provider(np, of_clk_src_onecell_get);
+ tegra_register_devclks(devclks, ARRAY_SIZE(devclks));
+
+ tegra_clk_apply_init_table = tegra114_clock_apply_init_table;
+diff --git a/drivers/clk/tegra/clk-tegra124.c b/drivers/clk/tegra/clk-tegra124.c
+index e81ea5b11577..e08df2faafd7 100644
+--- a/drivers/clk/tegra/clk-tegra124.c
++++ b/drivers/clk/tegra/clk-tegra124.c
+@@ -1480,7 +1480,7 @@ static void __init tegra124_132_clock_init_post(struct device_node *np)
+ &pll_x_params);
+ tegra_init_special_resets(1, tegra124_reset_assert,
+ tegra124_reset_deassert);
+- tegra_add_of_provider(np);
++ tegra_add_of_provider(np, of_clk_src_onecell_get);
+
+ clks[TEGRA124_CLK_EMC] = tegra_clk_register_emc(clk_base, np,
+ &emc_lock);
+diff --git a/drivers/clk/tegra/clk-tegra20.c b/drivers/clk/tegra/clk-tegra20.c
+index 837e5cbd60e9..532322b3d717 100644
+--- a/drivers/clk/tegra/clk-tegra20.c
++++ b/drivers/clk/tegra/clk-tegra20.c
+@@ -1084,6 +1084,36 @@ static const struct of_device_id pmc_match[] __initconst = {
+ { },
+ };
+
++static struct clk *tegra20_clk_src_onecell_get(struct of_phandle_args *clkspec,
++ void *data)
++{
++ struct clk_hw *parent_hw;
++ struct clk_hw *hw;
++ struct clk *clk;
++
++ clk = of_clk_src_onecell_get(clkspec, data);
++ if (IS_ERR(clk))
++ return clk;
++
++ /*
++ * Tegra20 CDEV1 and CDEV2 clocks are a bit special case, their parent
++ * clock is created by the pinctrl driver. It is possible for clk user
++ * to request these clocks before pinctrl driver got probed and hence
++ * user will get an orphaned clock. That might be undesirable because
++ * user may expect parent clock to be enabled by the child.
++ */
++ if (clkspec->args[0] == TEGRA20_CLK_CDEV1 ||
++ clkspec->args[0] == TEGRA20_CLK_CDEV2) {
++ hw = __clk_get_hw(clk);
++
++ parent_hw = clk_hw_get_parent(hw);
++ if (!parent_hw)
++ return ERR_PTR(-EPROBE_DEFER);
++ }
++
++ return clk;
++}
++
+ static void __init tegra20_clock_init(struct device_node *np)
+ {
+ struct device_node *node;
+@@ -1122,7 +1152,7 @@ static void __init tegra20_clock_init(struct device_node *np)
+
+ tegra_init_dup_clks(tegra_clk_duplicates, clks, TEGRA20_CLK_CLK_MAX);
+
+- tegra_add_of_provider(np);
++ tegra_add_of_provider(np, tegra20_clk_src_onecell_get);
+ tegra_register_devclks(devclks, ARRAY_SIZE(devclks));
+
+ tegra_clk_apply_init_table = tegra20_clock_apply_init_table;
+diff --git a/drivers/clk/tegra/clk-tegra210.c b/drivers/clk/tegra/clk-tegra210.c
+index b92867814e2d..b57193fba643 100644
+--- a/drivers/clk/tegra/clk-tegra210.c
++++ b/drivers/clk/tegra/clk-tegra210.c
+@@ -3169,7 +3169,7 @@ static void __init tegra210_clock_init(struct device_node *np)
+ tegra_init_special_resets(2, tegra210_reset_assert,
+ tegra210_reset_deassert);
+
+- tegra_add_of_provider(np);
++ tegra_add_of_provider(np, of_clk_src_onecell_get);
+ tegra_register_devclks(devclks, ARRAY_SIZE(devclks));
+
+ tegra_cpu_car_ops = &tegra210_cpu_car_ops;
+diff --git a/drivers/clk/tegra/clk-tegra30.c b/drivers/clk/tegra/clk-tegra30.c
+index 07f5203df01c..80748e7925f8 100644
+--- a/drivers/clk/tegra/clk-tegra30.c
++++ b/drivers/clk/tegra/clk-tegra30.c
+@@ -1355,7 +1355,7 @@ static void __init tegra30_clock_init(struct device_node *np)
+
+ tegra_init_dup_clks(tegra_clk_duplicates, clks, TEGRA30_CLK_CLK_MAX);
+
+- tegra_add_of_provider(np);
++ tegra_add_of_provider(np, of_clk_src_onecell_get);
+ tegra_register_devclks(devclks, ARRAY_SIZE(devclks));
+
+ tegra_clk_apply_init_table = tegra30_clock_apply_init_table;
+diff --git a/drivers/clk/tegra/clk.c b/drivers/clk/tegra/clk.c
+index ba923f0d5953..593d76a114f9 100644
+--- a/drivers/clk/tegra/clk.c
++++ b/drivers/clk/tegra/clk.c
+@@ -298,7 +298,8 @@ static struct reset_controller_dev rst_ctlr = {
+ .of_reset_n_cells = 1,
+ };
+
+-void __init tegra_add_of_provider(struct device_node *np)
++void __init tegra_add_of_provider(struct device_node *np,
++ void *clk_src_onecell_get)
+ {
+ int i;
+
+@@ -314,7 +315,7 @@ void __init tegra_add_of_provider(struct device_node *np)
+
+ clk_data.clks = clks;
+ clk_data.clk_num = clk_num;
+- of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
++ of_clk_add_provider(np, clk_src_onecell_get, &clk_data);
+
+ rst_ctlr.of_node = np;
+ rst_ctlr.nr_resets = periph_banks * 32 + num_special_reset;
+diff --git a/drivers/clk/tegra/clk.h b/drivers/clk/tegra/clk.h
+index 872f1189ad7f..a282a12637e3 100644
+--- a/drivers/clk/tegra/clk.h
++++ b/drivers/clk/tegra/clk.h
+@@ -760,7 +760,7 @@ struct clk **tegra_clk_init(void __iomem *clk_base, int num, int periph_banks);
+
+ struct clk **tegra_lookup_dt_id(int clk_id, struct tegra_clk *tegra_clk);
+
+-void tegra_add_of_provider(struct device_node *np);
++void tegra_add_of_provider(struct device_node *np, void *clk_src_onecell_get);
+ void tegra_register_devclks(struct tegra_devclk *dev_clks, int num);
+
+ void tegra_audio_clk_init(void __iomem *clk_base,
+--
+2.17.1
+
--- /dev/null
+From c19378818ac5039ee186d90bc0ed8b0973fb1585 Mon Sep 17 00:00:00 2001
+From: Alan Chiang <alanx.chiang@intel.com>
+Date: Wed, 25 Jul 2018 11:20:22 +0800
+Subject: eeprom: at24: Add support for address-width property
+
+[ Upstream commit a2b3bf4846e5eed62ea6abb096af2c950961033c ]
+
+Provide a flexible way to determine the addressing bits of eeprom.
+Pass the addressing bits to driver through address-width property.
+
+Signed-off-by: Alan Chiang <alanx.chiang@intel.com>
+Signed-off-by: Andy Yeh <andy.yeh@intel.com>
+Signed-off-by: Bartosz Golaszewski <brgl@bgdev.pl>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/misc/eeprom/at24.c | 17 +++++++++++++++++
+ 1 file changed, 17 insertions(+)
+
+diff --git a/drivers/misc/eeprom/at24.c b/drivers/misc/eeprom/at24.c
+index 4cc0b42f2acc..ded48a0c77ee 100644
+--- a/drivers/misc/eeprom/at24.c
++++ b/drivers/misc/eeprom/at24.c
+@@ -577,6 +577,23 @@ static void at24_get_pdata(struct device *dev, struct at24_platform_data *chip)
+ if (device_property_present(dev, "read-only"))
+ chip->flags |= AT24_FLAG_READONLY;
+
++ err = device_property_read_u32(dev, "address-width", &val);
++ if (!err) {
++ switch (val) {
++ case 8:
++ if (chip->flags & AT24_FLAG_ADDR16)
++ dev_warn(dev, "Override address width to be 8, while default is 16\n");
++ chip->flags &= ~AT24_FLAG_ADDR16;
++ break;
++ case 16:
++ chip->flags |= AT24_FLAG_ADDR16;
++ break;
++ default:
++ dev_warn(dev, "Bad \"address-width\" property: %u\n",
++ val);
++ }
++ }
++
+ err = device_property_read_u32(dev, "pagesize", &val);
+ if (!err) {
+ chip->page_size = val;
+--
+2.17.1
+
--- /dev/null
+From 51f0dae5c989f0a025c78e98c51bf52ea280fa40 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 6 Nov 2018 01:23:39 -0500
+Subject: Revert "ARM: tegra: Fix ULPI regression on Tegra20"
+
+This reverts commit b39ac54215190bc178ae7de799e74d327a3c1a33.
+
+The issue was fixed by upstream commit 5d797111afe1 ("clk:
+tegra: Add quirk for getting CDEV1/2 clocks on Tegra20").
+
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/boot/dts/tegra20.dtsi | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/arm/boot/dts/tegra20.dtsi b/arch/arm/boot/dts/tegra20.dtsi
+index 2780e68a853b..914f59166a99 100644
+--- a/arch/arm/boot/dts/tegra20.dtsi
++++ b/arch/arm/boot/dts/tegra20.dtsi
+@@ -706,7 +706,7 @@
+ phy_type = "ulpi";
+ clocks = <&tegra_car TEGRA20_CLK_USB2>,
+ <&tegra_car TEGRA20_CLK_PLL_U>,
+- <&tegra_car TEGRA20_CLK_PLL_P_OUT4>;
++ <&tegra_car TEGRA20_CLK_CDEV2>;
+ clock-names = "reg", "pll_u", "ulpi-link";
+ resets = <&tegra_car 58>, <&tegra_car 22>;
+ reset-names = "usb", "utmi-pads";
+--
+2.17.1
+
--- /dev/null
+eeprom-at24-add-support-for-address-width-property.patch
+vfs-swap-names-of-do-vfs-_clone_file_range.patch
+usb-serial-option-improve-quectel-ep06-detection.patch
+usb-serial-option-add-two-endpoints-device-id-flag.patch
+bpf-fix-partial-copy-of-map_ptr-when-dst-is-scalar.patch
+revert-arm-tegra-fix-ulpi-regression-on-tegra20.patch
+clk-tegra-add-quirk-for-getting-cdev1-2-clocks-on-te.patch
--- /dev/null
+From 3c24b28e49f19c1fc255fcf9dae22c0e55a536b1 Mon Sep 17 00:00:00 2001
+From: Johan Hovold <johan@kernel.org>
+Date: Thu, 1 Nov 2018 20:52:47 +0100
+Subject: USB: serial: option: add two-endpoints device-id flag
+
+commit 35aecc02b5b621782111f64cbb032c7f6a90bb32 upstream
+
+Allow matching on interfaces having two endpoints by adding a new
+device-id flag.
+
+This allows for the handling of devices whose interface numbers can
+change (e.g. Quectel EP06) to be contained in the device-id table.
+
+The upstream commit removes a variable that is still in use in the 4.14
+version of the option-driver, so the removal is undone.
+
+Tested-by: Kristian Evensen <kristian.evensen@gmail.com>
+Cc: stable <stable@vger.kernel.org>
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Signed-off-by: Kristian Evensen <kristian.evensen@gmail.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/serial/option.c | 16 +++++++---------
+ 1 file changed, 7 insertions(+), 9 deletions(-)
+
+diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c
+index d8d3cb18e9ea..392fddc80c44 100644
+--- a/drivers/usb/serial/option.c
++++ b/drivers/usb/serial/option.c
+@@ -564,6 +564,9 @@ static void option_instat_callback(struct urb *urb);
+ /* Interface is reserved */
+ #define RSVD(ifnum) ((BIT(ifnum) & 0xff) << 0)
+
++/* Interface must have two endpoints */
++#define NUMEP2 BIT(16)
++
+
+ static const struct usb_device_id option_ids[] = {
+ { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COLT) },
+@@ -1085,7 +1088,7 @@ static const struct usb_device_id option_ids[] = {
+ { USB_DEVICE(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_BG96),
+ .driver_info = RSVD(4) },
+ { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EP06, 0xff, 0xff, 0xff),
+- .driver_info = RSVD(1) | RSVD(2) | RSVD(3) | RSVD(4) },
++ .driver_info = RSVD(1) | RSVD(2) | RSVD(3) | RSVD(4) | NUMEP2 },
+ { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EP06, 0xff, 0, 0) },
+ { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_6001) },
+ { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_CMU_300) },
+@@ -2012,16 +2015,11 @@ static int option_probe(struct usb_serial *serial,
+ return -ENODEV;
+
+ /*
+- * Don't bind to the QMI device of the Quectel EP06/EG06/EM06. Class,
+- * subclass and protocol is 0xff for both the diagnostic port and the
+- * QMI interface, but the diagnostic port only has two endpoints (QMI
+- * has three).
++ * Allow matching on bNumEndpoints for devices whose interface numbers
++ * can change (e.g. Quectel EP06).
+ */
+- if (dev_desc->idVendor == cpu_to_le16(QUECTEL_VENDOR_ID) &&
+- dev_desc->idProduct == cpu_to_le16(QUECTEL_PRODUCT_EP06) &&
+- iface_desc->bInterfaceSubClass && iface_desc->bNumEndpoints == 3) {
++ if (device_flags & NUMEP2 && iface_desc->bNumEndpoints != 2)
+ return -ENODEV;
+- }
+
+ /* Store the device flags so we can use them during attach. */
+ usb_set_serial_data(serial, (void *)device_flags);
+--
+2.17.1
+
--- /dev/null
+From ec28752505ed38b95d5a644957af2e3a2a3e3bb0 Mon Sep 17 00:00:00 2001
+From: Kristian Evensen <kristian.evensen@gmail.com>
+Date: Thu, 1 Nov 2018 20:52:46 +0100
+Subject: USB: serial: option: improve Quectel EP06 detection
+
+commit 36cae568404a298a19a6e8a3f18641075d4cab04 upstream
+
+The Quectel EP06 (and EM06/EG06) LTE modem supports updating the USB
+configuration, without the VID/PID or configuration number changing.
+When the configuration is updated and interfaces are added/removed, the
+interface numbers are updated. This causes our current code for matching
+EP06 not to work as intended, as the assumption about reserved
+interfaces no longer holds. If for example the diagnostic (first)
+interface is removed, option will (try to) bind to the QMI interface.
+
+This patch improves EP06 detection by replacing the current match with
+two matches, and those matches check class, subclass and protocol as
+well as VID and PID. The diag interface exports class, subclass and
+protocol as 0xff. For the other serial interfaces, class is 0xff and
+subclass and protocol are both 0x0.
+
+The modem can export the following devices and always in this order:
+diag, nmea, at, ppp. qmi and adb. This means that diag can only ever be
+interface 0, and interface numbers 1-5 should be marked as reserved. The
+three other serial devices can have interface numbers 0-3, but I have
+not marked any interfaces as reserved. The reason is that the serial
+devices are the only interfaces exported by the device where subclass
+and protocol is 0x0.
+
+QMI exports the same class, subclass and protocol values as the diag
+interface. However, the two interfaces have different number of
+endpoints, QMI has three and diag two. I have added a check for number
+of interfaces if VID/PID matches the EP06, and we ignore the device if
+number of interfaces equals three (and subclass is set).
+
+The upstream commit does not apply cleanly to the 4.14-tree because of
+differences in option_probe(). In order to make the commit apply, a
+slight reshuffeling of the code was needed.
+
+Signed-off-by: Kristian Evensen <kristian.evensen@gmail.com>
+Acked-by: Dan Williams <dcbw@redhat.com>
+[ johan: drop uneeded RSVD(5) for ADB ]
+Cc: stable <stable@vger.kernel.org>
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Signed-off-by: Kristian Evensen <kristian.evensen@gmail.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/serial/option.c | 17 +++++++++++++++--
+ 1 file changed, 15 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c
+index 0600dadd6a0c..d8d3cb18e9ea 100644
+--- a/drivers/usb/serial/option.c
++++ b/drivers/usb/serial/option.c
+@@ -1084,8 +1084,9 @@ static const struct usb_device_id option_ids[] = {
+ .driver_info = RSVD(4) },
+ { USB_DEVICE(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_BG96),
+ .driver_info = RSVD(4) },
+- { USB_DEVICE(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EP06),
+- .driver_info = RSVD(4) | RSVD(5) },
++ { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EP06, 0xff, 0xff, 0xff),
++ .driver_info = RSVD(1) | RSVD(2) | RSVD(3) | RSVD(4) },
++ { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EP06, 0xff, 0, 0) },
+ { 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),
+@@ -2010,6 +2011,18 @@ static int option_probe(struct usb_serial *serial,
+ iface_desc->bInterfaceClass != USB_CLASS_CDC_DATA)
+ return -ENODEV;
+
++ /*
++ * Don't bind to the QMI device of the Quectel EP06/EG06/EM06. Class,
++ * subclass and protocol is 0xff for both the diagnostic port and the
++ * QMI interface, but the diagnostic port only has two endpoints (QMI
++ * has three).
++ */
++ if (dev_desc->idVendor == cpu_to_le16(QUECTEL_VENDOR_ID) &&
++ dev_desc->idProduct == cpu_to_le16(QUECTEL_PRODUCT_EP06) &&
++ iface_desc->bInterfaceSubClass && iface_desc->bNumEndpoints == 3) {
++ return -ENODEV;
++ }
++
+ /* Store the device flags so we can use them during attach. */
+ usb_set_serial_data(serial, (void *)device_flags);
+
+--
+2.17.1
+
--- /dev/null
+From 0f36e7f8595b2be370eb4278c976108f093d6c8b Mon Sep 17 00:00:00 2001
+From: Amir Goldstein <amir73il@gmail.com>
+Date: Mon, 22 Oct 2018 20:56:46 +0300
+Subject: vfs: swap names of {do,vfs}_clone_file_range()
+
+commit a725356b6659469d182d662f22d770d83d3bc7b5 upstream.
+
+Commit 031a072a0b8a ("vfs: call vfs_clone_file_range() under freeze
+protection") created a wrapper do_clone_file_range() around
+vfs_clone_file_range() moving the freeze protection to former, so
+overlayfs could call the latter.
+
+The more common vfs practice is to call do_xxx helpers from vfs_xxx
+helpers, where freeze protecction is taken in the vfs_xxx helper, so
+this anomality could be a source of confusion.
+
+It seems that commit 8ede205541ff ("ovl: add reflink/copyfile/dedup
+support") may have fallen a victim to this confusion -
+ovl_clone_file_range() calls the vfs_clone_file_range() helper in the
+hope of getting freeze protection on upper fs, but in fact results in
+overlayfs allowing to bypass upper fs freeze protection.
+
+Swap the names of the two helpers to conform to common vfs practice
+and call the correct helpers from overlayfs and nfsd.
+
+Signed-off-by: Amir Goldstein <amir73il@gmail.com>
+Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
+Fixes: 031a072a0b8a ("vfs: call vfs_clone_file_range() under freeze...")
+Signed-off-by: Amir Goldstein <amir73il@gmail.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/ioctl.c | 2 +-
+ fs/nfsd/vfs.c | 3 ++-
+ fs/overlayfs/copy_up.c | 2 +-
+ fs/read_write.c | 17 +++++++++++++++--
+ include/linux/fs.h | 17 +++--------------
+ 5 files changed, 22 insertions(+), 19 deletions(-)
+
+diff --git a/fs/ioctl.c b/fs/ioctl.c
+index 5ace7efb0d04..9db5ddaf7ef0 100644
+--- a/fs/ioctl.c
++++ b/fs/ioctl.c
+@@ -229,7 +229,7 @@ static long ioctl_file_clone(struct file *dst_file, unsigned long srcfd,
+ ret = -EXDEV;
+ if (src_file.file->f_path.mnt != dst_file->f_path.mnt)
+ goto fdput;
+- ret = do_clone_file_range(src_file.file, off, dst_file, destoff, olen);
++ ret = vfs_clone_file_range(src_file.file, off, dst_file, destoff, olen);
+ fdput:
+ fdput(src_file);
+ return ret;
+diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
+index a3c9bfa77def..f55527ef21e8 100644
+--- a/fs/nfsd/vfs.c
++++ b/fs/nfsd/vfs.c
+@@ -541,7 +541,8 @@ __be32 nfsd4_set_nfs4_label(struct svc_rqst *rqstp, struct svc_fh *fhp,
+ __be32 nfsd4_clone_file_range(struct file *src, u64 src_pos, struct file *dst,
+ u64 dst_pos, u64 count)
+ {
+- return nfserrno(do_clone_file_range(src, src_pos, dst, dst_pos, count));
++ return nfserrno(vfs_clone_file_range(src, src_pos, dst, dst_pos,
++ count));
+ }
+
+ ssize_t nfsd_copy_file_range(struct file *src, u64 src_pos, struct file *dst,
+diff --git a/fs/overlayfs/copy_up.c b/fs/overlayfs/copy_up.c
+index c441f9387a1b..321eae740148 100644
+--- a/fs/overlayfs/copy_up.c
++++ b/fs/overlayfs/copy_up.c
+@@ -157,7 +157,7 @@ static int ovl_copy_up_data(struct path *old, struct path *new, loff_t len)
+ }
+
+ /* Try to use clone_file_range to clone up within the same fs */
+- error = vfs_clone_file_range(old_file, 0, new_file, 0, len);
++ error = do_clone_file_range(old_file, 0, new_file, 0, len);
+ if (!error)
+ goto out;
+ /* Couldn't clone, so now we try to copy the data */
+diff --git a/fs/read_write.c b/fs/read_write.c
+index 0046d72efe94..57a00ef895b2 100644
+--- a/fs/read_write.c
++++ b/fs/read_write.c
+@@ -1812,8 +1812,8 @@ int vfs_clone_file_prep_inodes(struct inode *inode_in, loff_t pos_in,
+ }
+ EXPORT_SYMBOL(vfs_clone_file_prep_inodes);
+
+-int vfs_clone_file_range(struct file *file_in, loff_t pos_in,
+- struct file *file_out, loff_t pos_out, u64 len)
++int do_clone_file_range(struct file *file_in, loff_t pos_in,
++ struct file *file_out, loff_t pos_out, u64 len)
+ {
+ struct inode *inode_in = file_inode(file_in);
+ struct inode *inode_out = file_inode(file_out);
+@@ -1860,6 +1860,19 @@ int vfs_clone_file_range(struct file *file_in, loff_t pos_in,
+
+ return ret;
+ }
++EXPORT_SYMBOL(do_clone_file_range);
++
++int vfs_clone_file_range(struct file *file_in, loff_t pos_in,
++ struct file *file_out, loff_t pos_out, u64 len)
++{
++ int ret;
++
++ file_start_write(file_out);
++ ret = do_clone_file_range(file_in, pos_in, file_out, pos_out, len);
++ file_end_write(file_out);
++
++ return ret;
++}
+ EXPORT_SYMBOL(vfs_clone_file_range);
+
+ /*
+diff --git a/include/linux/fs.h b/include/linux/fs.h
+index cc613f20e5a6..7374639f0aa0 100644
+--- a/include/linux/fs.h
++++ b/include/linux/fs.h
+@@ -1792,8 +1792,10 @@ extern ssize_t vfs_copy_file_range(struct file *, loff_t , struct file *,
+ extern int vfs_clone_file_prep_inodes(struct inode *inode_in, loff_t pos_in,
+ struct inode *inode_out, loff_t pos_out,
+ u64 *len, bool is_dedupe);
++extern int do_clone_file_range(struct file *file_in, loff_t pos_in,
++ struct file *file_out, loff_t pos_out, u64 len);
+ extern int vfs_clone_file_range(struct file *file_in, loff_t pos_in,
+- struct file *file_out, loff_t pos_out, u64 len);
++ struct file *file_out, loff_t pos_out, u64 len);
+ extern int vfs_dedupe_file_range_compare(struct inode *src, loff_t srcoff,
+ struct inode *dest, loff_t destoff,
+ loff_t len, bool *is_same);
+@@ -2712,19 +2714,6 @@ static inline void file_end_write(struct file *file)
+ __sb_end_write(file_inode(file)->i_sb, SB_FREEZE_WRITE);
+ }
+
+-static inline int do_clone_file_range(struct file *file_in, loff_t pos_in,
+- struct file *file_out, loff_t pos_out,
+- u64 len)
+-{
+- int ret;
+-
+- file_start_write(file_out);
+- ret = vfs_clone_file_range(file_in, pos_in, file_out, pos_out, len);
+- file_end_write(file_out);
+-
+- return ret;
+-}
+-
+ /*
+ * get_write_access() gets write permission for a file.
+ * put_write_access() releases this write permission.
+--
+2.17.1
+