From: Sasha Levin Date: Tue, 6 Nov 2018 06:33:18 +0000 (-0500) Subject: 4.14-stable patches X-Git-Tag: v3.18.125~21 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=14b0229679cdc2f635c14516d5ea9977f4561c29;p=thirdparty%2Fkernel%2Fstable-queue.git 4.14-stable patches Signed-off-by: Sasha Levin --- 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 index 00000000000..ebeee7665b9 --- /dev/null +++ b/queue-4.14/bpf-fix-partial-copy-of-map_ptr-when-dst-is-scalar.patch @@ -0,0 +1,93 @@ +From 2d5030c98838e37be3c8b0f3568f91c8e0774fa2 Mon Sep 17 00:00:00 2001 +From: Daniel Borkmann +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 +Cc: Edward Cree +Acked-by: Alexei Starovoitov +Signed-off-by: Alexei Starovoitov +Acked-by: Edward Cree +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..0415b44e6f2 --- /dev/null +++ b/queue-4.14/clk-tegra-add-quirk-for-getting-cdev1-2-clocks-on-te.patch @@ -0,0 +1,169 @@ +From 4cd924ba72d77eb135eef248b11c85106b58df3f Mon Sep 17 00:00:00 2001 +From: Dmitry Osipenko +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 +Acked-by: Peter De Schrijver +Signed-off-by: Thierry Reding +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..ef9473e670f --- /dev/null +++ b/queue-4.14/eeprom-at24-add-support-for-address-width-property.patch @@ -0,0 +1,49 @@ +From c19378818ac5039ee186d90bc0ed8b0973fb1585 Mon Sep 17 00:00:00 2001 +From: Alan Chiang +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 +Signed-off-by: Andy Yeh +Signed-off-by: Bartosz Golaszewski +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..b16da5422b6 --- /dev/null +++ b/queue-4.14/revert-arm-tegra-fix-ulpi-regression-on-tegra20.patch @@ -0,0 +1,31 @@ +From 51f0dae5c989f0a025c78e98c51bf52ea280fa40 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 +--- + 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 index 00000000000..6efac4eb8e9 --- /dev/null +++ b/queue-4.14/series @@ -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 index 00000000000..9212a208c63 --- /dev/null +++ b/queue-4.14/usb-serial-option-add-two-endpoints-device-id-flag.patch @@ -0,0 +1,71 @@ +From 3c24b28e49f19c1fc255fcf9dae22c0e55a536b1 Mon Sep 17 00:00:00 2001 +From: Johan Hovold +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 +Cc: stable +Signed-off-by: Johan Hovold +Signed-off-by: Kristian Evensen +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..1fbdf1b86e4 --- /dev/null +++ b/queue-4.14/usb-serial-option-improve-quectel-ep06-detection.patch @@ -0,0 +1,88 @@ +From ec28752505ed38b95d5a644957af2e3a2a3e3bb0 Mon Sep 17 00:00:00 2001 +From: Kristian Evensen +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 +Acked-by: Dan Williams +[ johan: drop uneeded RSVD(5) for ADB ] +Cc: stable +Signed-off-by: Johan Hovold +Signed-off-by: Kristian Evensen +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..fa32505098d --- /dev/null +++ b/queue-4.14/vfs-swap-names-of-do-vfs-_clone_file_range.patch @@ -0,0 +1,152 @@ +From 0f36e7f8595b2be370eb4278c976108f093d6c8b Mon Sep 17 00:00:00 2001 +From: Amir Goldstein +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 +Signed-off-by: Miklos Szeredi +Fixes: 031a072a0b8a ("vfs: call vfs_clone_file_range() under freeze...") +Signed-off-by: Amir Goldstein +Signed-off-by: Sasha Levin +--- + 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 +