From: Sasha Levin Date: Thu, 3 Oct 2019 14:45:46 +0000 (-0400) Subject: fixes for 5.3 X-Git-Tag: v4.4.195~19 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=8946d4c6ed65019dd6f0afbcad0cb6853e900905;p=thirdparty%2Fkernel%2Fstable-queue.git fixes for 5.3 Signed-off-by: Sasha Levin --- diff --git a/queue-5.3/md-raid0-avoid-raid0-data-corruption-due-to-layout-c.patch b/queue-5.3/md-raid0-avoid-raid0-data-corruption-due-to-layout-c.patch new file mode 100644 index 00000000000..74d0ebe0413 --- /dev/null +++ b/queue-5.3/md-raid0-avoid-raid0-data-corruption-due-to-layout-c.patch @@ -0,0 +1,140 @@ +From 090ee88724fd9a33cf6fbc0a5f5663d633b262fd Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 9 Sep 2019 16:30:02 +1000 +Subject: md/raid0: avoid RAID0 data corruption due to layout confusion. + +From: NeilBrown + +[ Upstream commit c84a1372df929033cb1a0441fb57bd3932f39ac9 ] + +If the drives in a RAID0 are not all the same size, the array is +divided into zones. +The first zone covers all drives, to the size of the smallest. +The second zone covers all drives larger than the smallest, up to +the size of the second smallest - etc. + +A change in Linux 3.14 unintentionally changed the layout for the +second and subsequent zones. All the correct data is still stored, but +each chunk may be assigned to a different device than in pre-3.14 kernels. +This can lead to data corruption. + +It is not possible to determine what layout to use - it depends which +kernel the data was written by. +So we add a module parameter to allow the old (0) or new (1) layout to be +specified, and refused to assemble an affected array if that parameter is +not set. + +Fixes: 20d0189b1012 ("block: Introduce new bio_split()") +cc: stable@vger.kernel.org (3.14+) +Acked-by: Guoqing Jiang +Signed-off-by: NeilBrown +Signed-off-by: Song Liu +Signed-off-by: Sasha Levin +--- + drivers/md/raid0.c | 33 ++++++++++++++++++++++++++++++++- + drivers/md/raid0.h | 14 ++++++++++++++ + 2 files changed, 46 insertions(+), 1 deletion(-) + +diff --git a/drivers/md/raid0.c b/drivers/md/raid0.c +index bf5cf184a260b..297bbc0f41f05 100644 +--- a/drivers/md/raid0.c ++++ b/drivers/md/raid0.c +@@ -19,6 +19,9 @@ + #include "raid0.h" + #include "raid5.h" + ++static int default_layout = 0; ++module_param(default_layout, int, 0644); ++ + #define UNSUPPORTED_MDDEV_FLAGS \ + ((1L << MD_HAS_JOURNAL) | \ + (1L << MD_JOURNAL_CLEAN) | \ +@@ -139,6 +142,19 @@ static int create_strip_zones(struct mddev *mddev, struct r0conf **private_conf) + } + pr_debug("md/raid0:%s: FINAL %d zones\n", + mdname(mddev), conf->nr_strip_zones); ++ ++ if (conf->nr_strip_zones == 1) { ++ conf->layout = RAID0_ORIG_LAYOUT; ++ } else if (default_layout == RAID0_ORIG_LAYOUT || ++ default_layout == RAID0_ALT_MULTIZONE_LAYOUT) { ++ conf->layout = default_layout; ++ } else { ++ pr_err("md/raid0:%s: cannot assemble multi-zone RAID0 with default_layout setting\n", ++ mdname(mddev)); ++ pr_err("md/raid0: please set raid.default_layout to 1 or 2\n"); ++ err = -ENOTSUPP; ++ goto abort; ++ } + /* + * now since we have the hard sector sizes, we can make sure + * chunk size is a multiple of that sector size +@@ -547,10 +563,12 @@ static void raid0_handle_discard(struct mddev *mddev, struct bio *bio) + + static bool raid0_make_request(struct mddev *mddev, struct bio *bio) + { ++ struct r0conf *conf = mddev->private; + struct strip_zone *zone; + struct md_rdev *tmp_dev; + sector_t bio_sector; + sector_t sector; ++ sector_t orig_sector; + unsigned chunk_sects; + unsigned sectors; + +@@ -584,8 +602,21 @@ static bool raid0_make_request(struct mddev *mddev, struct bio *bio) + bio = split; + } + ++ orig_sector = sector; + zone = find_zone(mddev->private, §or); +- tmp_dev = map_sector(mddev, zone, sector, §or); ++ switch (conf->layout) { ++ case RAID0_ORIG_LAYOUT: ++ tmp_dev = map_sector(mddev, zone, orig_sector, §or); ++ break; ++ case RAID0_ALT_MULTIZONE_LAYOUT: ++ tmp_dev = map_sector(mddev, zone, sector, §or); ++ break; ++ default: ++ WARN("md/raid0:%s: Invalid layout\n", mdname(mddev)); ++ bio_io_error(bio); ++ return true; ++ } ++ + bio_set_dev(bio, tmp_dev->bdev); + bio->bi_iter.bi_sector = sector + zone->dev_start + + tmp_dev->data_offset; +diff --git a/drivers/md/raid0.h b/drivers/md/raid0.h +index 540e65d92642d..3816e5477db1e 100644 +--- a/drivers/md/raid0.h ++++ b/drivers/md/raid0.h +@@ -8,11 +8,25 @@ struct strip_zone { + int nb_dev; /* # of devices attached to the zone */ + }; + ++/* Linux 3.14 (20d0189b101) made an unintended change to ++ * the RAID0 layout for multi-zone arrays (where devices aren't all ++ * the same size. ++ * RAID0_ORIG_LAYOUT restores the original layout ++ * RAID0_ALT_MULTIZONE_LAYOUT uses the altered layout ++ * The layouts are identical when there is only one zone (all ++ * devices the same size). ++ */ ++ ++enum r0layout { ++ RAID0_ORIG_LAYOUT = 1, ++ RAID0_ALT_MULTIZONE_LAYOUT = 2, ++}; + struct r0conf { + struct strip_zone *strip_zone; + struct md_rdev **devlist; /* lists of rdevs, pointed to + * by strip_zone->dev */ + int nr_strip_zones; ++ enum r0layout layout; + }; + + #endif +-- +2.20.1 + diff --git a/queue-5.3/mt76-mt7615-always-release-sem-in-mt7615_load_patch.patch b/queue-5.3/mt76-mt7615-always-release-sem-in-mt7615_load_patch.patch new file mode 100644 index 00000000000..4d262175c0b --- /dev/null +++ b/queue-5.3/mt76-mt7615-always-release-sem-in-mt7615_load_patch.patch @@ -0,0 +1,47 @@ +From a4bfade20dbb3afd3d36c0268f4aa671da623d9d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 2 Jul 2019 11:24:51 +0200 +Subject: mt76: mt7615: always release sem in mt7615_load_patch + +From: Lorenzo Bianconi + +[ Upstream commit 2fc446487c364bf8bbd5f8f5f27e52d914fa1d72 ] + +Release patch semaphore even if request_firmware fails in +mt7615_load_patch + +Signed-off-by: Lorenzo Bianconi +Signed-off-by: Felix Fietkau +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/mediatek/mt76/mt7615/mcu.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7615/mcu.c +index cdad2c8dc2971..7ef681fea3f8f 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt7615/mcu.c ++++ b/drivers/net/wireless/mediatek/mt76/mt7615/mcu.c +@@ -257,9 +257,9 @@ static int mt7615_driver_own(struct mt7615_dev *dev) + + static int mt7615_load_patch(struct mt7615_dev *dev) + { +- const struct firmware *fw; +- const struct mt7615_patch_hdr *hdr; + const char *firmware = MT7615_ROM_PATCH; ++ const struct mt7615_patch_hdr *hdr; ++ const struct firmware *fw = NULL; + int len, ret, sem; + + sem = mt7615_mcu_patch_sem_ctrl(dev, 1); +@@ -275,7 +275,7 @@ static int mt7615_load_patch(struct mt7615_dev *dev) + + ret = request_firmware(&fw, firmware, dev->mt76.dev); + if (ret) +- return ret; ++ goto out; + + if (!fw || !fw->data || fw->size < sizeof(*hdr)) { + dev_err(dev->mt76.dev, "Invalid firmware\n"); +-- +2.20.1 + diff --git a/queue-5.3/mt76-mt7615-fix-mt7615-firmware-path-definitions.patch b/queue-5.3/mt76-mt7615-fix-mt7615-firmware-path-definitions.patch new file mode 100644 index 00000000000..95463d6697b --- /dev/null +++ b/queue-5.3/mt76-mt7615-fix-mt7615-firmware-path-definitions.patch @@ -0,0 +1,91 @@ +From 3da1aa824a0612c4a0ab2010abe0e3df7a354672 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 22 Sep 2019 15:36:03 +0200 +Subject: mt76: mt7615: fix mt7615 firmware path definitions + +From: Lorenzo Bianconi + +[ Upstream commit 9d4d0d06bbf9f7e576b0ebbb2f77672d0fc7f503 ] + +mt7615 patch/n9/cr4 firmwares are available in mediatek folder in +linux-firmware repository. Because of this mt7615 won't work on regular +distributions like Ubuntu. Fix path definitions. Moreover remove useless +firmware name pointers and use definitions directly + +Fixes: 04b8e65922f6 ("mt76: add mac80211 driver for MT7615 PCIe-based chipsets") +Cc: stable@vger.kernel.org +Signed-off-by: Lorenzo Bianconi +Signed-off-by: Kalle Valo +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/mediatek/mt76/mt7615/mcu.c | 11 ++++------- + drivers/net/wireless/mediatek/mt76/mt7615/mt7615.h | 6 +++--- + 2 files changed, 7 insertions(+), 10 deletions(-) + +diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7615/mcu.c +index 7ef681fea3f8f..b941fa4a1bcd0 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt7615/mcu.c ++++ b/drivers/net/wireless/mediatek/mt76/mt7615/mcu.c +@@ -257,7 +257,6 @@ static int mt7615_driver_own(struct mt7615_dev *dev) + + static int mt7615_load_patch(struct mt7615_dev *dev) + { +- const char *firmware = MT7615_ROM_PATCH; + const struct mt7615_patch_hdr *hdr; + const struct firmware *fw = NULL; + int len, ret, sem; +@@ -273,7 +272,7 @@ static int mt7615_load_patch(struct mt7615_dev *dev) + return -EAGAIN; + } + +- ret = request_firmware(&fw, firmware, dev->mt76.dev); ++ ret = request_firmware(&fw, MT7615_ROM_PATCH, dev->mt76.dev); + if (ret) + goto out; + +@@ -339,14 +338,12 @@ static u32 gen_dl_mode(u8 feature_set, bool is_cr4) + + static int mt7615_load_ram(struct mt7615_dev *dev) + { +- const struct firmware *fw; + const struct mt7615_fw_trailer *hdr; +- const char *n9_firmware = MT7615_FIRMWARE_N9; +- const char *cr4_firmware = MT7615_FIRMWARE_CR4; + u32 n9_ilm_addr, offset; + int i, ret; ++ const struct firmware *fw; + +- ret = request_firmware(&fw, n9_firmware, dev->mt76.dev); ++ ret = request_firmware(&fw, MT7615_FIRMWARE_N9, dev->mt76.dev); + if (ret) + return ret; + +@@ -394,7 +391,7 @@ static int mt7615_load_ram(struct mt7615_dev *dev) + + release_firmware(fw); + +- ret = request_firmware(&fw, cr4_firmware, dev->mt76.dev); ++ ret = request_firmware(&fw, MT7615_FIRMWARE_CR4, dev->mt76.dev); + if (ret) + return ret; + +diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/mt7615.h b/drivers/net/wireless/mediatek/mt76/mt7615/mt7615.h +index f02ffcffe6376..f83615dbe1c5d 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt7615/mt7615.h ++++ b/drivers/net/wireless/mediatek/mt76/mt7615/mt7615.h +@@ -25,9 +25,9 @@ + #define MT7615_RX_RING_SIZE 1024 + #define MT7615_RX_MCU_RING_SIZE 512 + +-#define MT7615_FIRMWARE_CR4 "mt7615_cr4.bin" +-#define MT7615_FIRMWARE_N9 "mt7615_n9.bin" +-#define MT7615_ROM_PATCH "mt7615_rom_patch.bin" ++#define MT7615_FIRMWARE_CR4 "mediatek/mt7615_cr4.bin" ++#define MT7615_FIRMWARE_N9 "mediatek/mt7615_n9.bin" ++#define MT7615_ROM_PATCH "mediatek/mt7615_rom_patch.bin" + + #define MT7615_EEPROM_SIZE 1024 + #define MT7615_TOKEN_SIZE 4096 +-- +2.20.1 + diff --git a/queue-5.3/platform-chrome-cros_ec_rpmsg-fix-race-with-host-com.patch b/queue-5.3/platform-chrome-cros_ec_rpmsg-fix-race-with-host-com.patch new file mode 100644 index 00000000000..5ba417053d6 --- /dev/null +++ b/queue-5.3/platform-chrome-cros_ec_rpmsg-fix-race-with-host-com.patch @@ -0,0 +1,126 @@ +From b8abca2072825716d13f7fe2eb985ff40ff977ab Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 4 Sep 2019 14:26:13 +0800 +Subject: platform/chrome: cros_ec_rpmsg: Fix race with host command when probe + failed + +From: Pi-Hsun Shih + +[ Upstream commit 71cddb7097e2b0feb855d7fd7d59afd12cbee4bb ] + +Since the rpmsg_endpoint is created before probe is called, it's +possible that a host event is received during cros_ec_register, and +there would be some pending work in the host_event_work workqueue while +cros_ec_register is called. + +If cros_ec_register fails, when the leftover work in host_event_work +run, the ec_dev from the drvdata of the rpdev could be already set to +NULL, causing kernel crash when trying to run cros_ec_get_next_event. + +Fix this by creating the rpmsg_endpoint by ourself, and when +cros_ec_register fails (or on remove), destroy the endpoint first (to +make sure there's no more new calls to cros_ec_rpmsg_callback), and then +cancel all works in the host_event_work workqueue. + +Cc: stable@vger.kernel.org +Fixes: 2de89fd98958 ("platform/chrome: cros_ec: Add EC host command support using rpmsg") +Signed-off-by: Pi-Hsun Shih +Signed-off-by: Enric Balletbo i Serra +Signed-off-by: Sasha Levin +--- + drivers/platform/chrome/cros_ec_rpmsg.c | 32 +++++++++++++++++++++---- + 1 file changed, 28 insertions(+), 4 deletions(-) + +diff --git a/drivers/platform/chrome/cros_ec_rpmsg.c b/drivers/platform/chrome/cros_ec_rpmsg.c +index 5d3fb2abad1d6..bec19d4814aba 100644 +--- a/drivers/platform/chrome/cros_ec_rpmsg.c ++++ b/drivers/platform/chrome/cros_ec_rpmsg.c +@@ -41,6 +41,7 @@ struct cros_ec_rpmsg { + struct rpmsg_device *rpdev; + struct completion xfer_ack; + struct work_struct host_event_work; ++ struct rpmsg_endpoint *ept; + }; + + /** +@@ -72,7 +73,6 @@ static int cros_ec_pkt_xfer_rpmsg(struct cros_ec_device *ec_dev, + struct cros_ec_command *ec_msg) + { + struct cros_ec_rpmsg *ec_rpmsg = ec_dev->priv; +- struct rpmsg_device *rpdev = ec_rpmsg->rpdev; + struct ec_host_response *response; + unsigned long timeout; + int len; +@@ -85,7 +85,7 @@ static int cros_ec_pkt_xfer_rpmsg(struct cros_ec_device *ec_dev, + dev_dbg(ec_dev->dev, "prepared, len=%d\n", len); + + reinit_completion(&ec_rpmsg->xfer_ack); +- ret = rpmsg_send(rpdev->ept, ec_dev->dout, len); ++ ret = rpmsg_send(ec_rpmsg->ept, ec_dev->dout, len); + if (ret) { + dev_err(ec_dev->dev, "rpmsg send failed\n"); + return ret; +@@ -196,11 +196,24 @@ static int cros_ec_rpmsg_callback(struct rpmsg_device *rpdev, void *data, + return 0; + } + ++static struct rpmsg_endpoint * ++cros_ec_rpmsg_create_ept(struct rpmsg_device *rpdev) ++{ ++ struct rpmsg_channel_info chinfo = {}; ++ ++ strscpy(chinfo.name, rpdev->id.name, RPMSG_NAME_SIZE); ++ chinfo.src = rpdev->src; ++ chinfo.dst = RPMSG_ADDR_ANY; ++ ++ return rpmsg_create_ept(rpdev, cros_ec_rpmsg_callback, NULL, chinfo); ++} ++ + static int cros_ec_rpmsg_probe(struct rpmsg_device *rpdev) + { + struct device *dev = &rpdev->dev; + struct cros_ec_rpmsg *ec_rpmsg; + struct cros_ec_device *ec_dev; ++ int ret; + + ec_dev = devm_kzalloc(dev, sizeof(*ec_dev), GFP_KERNEL); + if (!ec_dev) +@@ -225,7 +238,18 @@ static int cros_ec_rpmsg_probe(struct rpmsg_device *rpdev) + INIT_WORK(&ec_rpmsg->host_event_work, + cros_ec_rpmsg_host_event_function); + +- return cros_ec_register(ec_dev); ++ ec_rpmsg->ept = cros_ec_rpmsg_create_ept(rpdev); ++ if (!ec_rpmsg->ept) ++ return -ENOMEM; ++ ++ ret = cros_ec_register(ec_dev); ++ if (ret < 0) { ++ rpmsg_destroy_ept(ec_rpmsg->ept); ++ cancel_work_sync(&ec_rpmsg->host_event_work); ++ return ret; ++ } ++ ++ return 0; + } + + static void cros_ec_rpmsg_remove(struct rpmsg_device *rpdev) +@@ -233,6 +257,7 @@ static void cros_ec_rpmsg_remove(struct rpmsg_device *rpdev) + struct cros_ec_device *ec_dev = dev_get_drvdata(&rpdev->dev); + struct cros_ec_rpmsg *ec_rpmsg = ec_dev->priv; + ++ rpmsg_destroy_ept(ec_rpmsg->ept); + cancel_work_sync(&ec_rpmsg->host_event_work); + } + +@@ -249,7 +274,6 @@ static struct rpmsg_driver cros_ec_driver_rpmsg = { + }, + .probe = cros_ec_rpmsg_probe, + .remove = cros_ec_rpmsg_remove, +- .callback = cros_ec_rpmsg_callback, + }; + + module_rpmsg_driver(cros_ec_driver_rpmsg); +-- +2.20.1 + diff --git a/queue-5.3/series b/queue-5.3/series index 40c5f577541..5e4e482ed73 100644 --- a/queue-5.3/series +++ b/queue-5.3/series @@ -335,3 +335,7 @@ hwrng-core-don-t-wait-on-add_early_randomness.patch i2c-riic-clear-nack-in-tend-isr.patch cifs-fix-max-ea-value-size.patch cifs-fix-oplock-handling-for-smb-2.1-protocols.patch +md-raid0-avoid-raid0-data-corruption-due-to-layout-c.patch +mt76-mt7615-always-release-sem-in-mt7615_load_patch.patch +mt76-mt7615-fix-mt7615-firmware-path-definitions.patch +platform-chrome-cros_ec_rpmsg-fix-race-with-host-com.patch