]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.14-stable patches
authorSasha Levin <sashal@kernel.org>
Tue, 6 Nov 2018 06:33:18 +0000 (01:33 -0500)
committerSasha Levin <sashal@kernel.org>
Tue, 6 Nov 2018 06:33:18 +0000 (01:33 -0500)
Signed-off-by: Sasha Levin <sashal@kernel.org>
queue-4.14/bpf-fix-partial-copy-of-map_ptr-when-dst-is-scalar.patch [new file with mode: 0644]
queue-4.14/clk-tegra-add-quirk-for-getting-cdev1-2-clocks-on-te.patch [new file with mode: 0644]
queue-4.14/eeprom-at24-add-support-for-address-width-property.patch [new file with mode: 0644]
queue-4.14/revert-arm-tegra-fix-ulpi-regression-on-tegra20.patch [new file with mode: 0644]
queue-4.14/series [new file with mode: 0644]
queue-4.14/usb-serial-option-add-two-endpoints-device-id-flag.patch [new file with mode: 0644]
queue-4.14/usb-serial-option-improve-quectel-ep06-detection.patch [new file with mode: 0644]
queue-4.14/vfs-swap-names-of-do-vfs-_clone_file_range.patch [new file with mode: 0644]

diff --git a/queue-4.14/bpf-fix-partial-copy-of-map_ptr-when-dst-is-scalar.patch b/queue-4.14/bpf-fix-partial-copy-of-map_ptr-when-dst-is-scalar.patch
new file mode 100644 (file)
index 0000000..ebeee76
--- /dev/null
@@ -0,0 +1,93 @@
+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
+
diff --git a/queue-4.14/clk-tegra-add-quirk-for-getting-cdev1-2-clocks-on-te.patch b/queue-4.14/clk-tegra-add-quirk-for-getting-cdev1-2-clocks-on-te.patch
new file mode 100644 (file)
index 0000000..0415b44
--- /dev/null
@@ -0,0 +1,169 @@
+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
+
diff --git a/queue-4.14/eeprom-at24-add-support-for-address-width-property.patch b/queue-4.14/eeprom-at24-add-support-for-address-width-property.patch
new file mode 100644 (file)
index 0000000..ef9473e
--- /dev/null
@@ -0,0 +1,49 @@
+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
+
diff --git a/queue-4.14/revert-arm-tegra-fix-ulpi-regression-on-tegra20.patch b/queue-4.14/revert-arm-tegra-fix-ulpi-regression-on-tegra20.patch
new file mode 100644 (file)
index 0000000..b16da54
--- /dev/null
@@ -0,0 +1,31 @@
+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
+
diff --git a/queue-4.14/series b/queue-4.14/series
new file mode 100644 (file)
index 0000000..6efac4e
--- /dev/null
@@ -0,0 +1,7 @@
+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
diff --git a/queue-4.14/usb-serial-option-add-two-endpoints-device-id-flag.patch b/queue-4.14/usb-serial-option-add-two-endpoints-device-id-flag.patch
new file mode 100644 (file)
index 0000000..9212a20
--- /dev/null
@@ -0,0 +1,71 @@
+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
+
diff --git a/queue-4.14/usb-serial-option-improve-quectel-ep06-detection.patch b/queue-4.14/usb-serial-option-improve-quectel-ep06-detection.patch
new file mode 100644 (file)
index 0000000..1fbdf1b
--- /dev/null
@@ -0,0 +1,88 @@
+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
+
diff --git a/queue-4.14/vfs-swap-names-of-do-vfs-_clone_file_range.patch b/queue-4.14/vfs-swap-names-of-do-vfs-_clone_file_range.patch
new file mode 100644 (file)
index 0000000..fa32505
--- /dev/null
@@ -0,0 +1,152 @@
+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
+