]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
fixes for 5.3
authorSasha Levin <sashal@kernel.org>
Thu, 3 Oct 2019 14:45:46 +0000 (10:45 -0400)
committerSasha Levin <sashal@kernel.org>
Thu, 3 Oct 2019 14:45:46 +0000 (10:45 -0400)
Signed-off-by: Sasha Levin <sashal@kernel.org>
queue-5.3/md-raid0-avoid-raid0-data-corruption-due-to-layout-c.patch [new file with mode: 0644]
queue-5.3/mt76-mt7615-always-release-sem-in-mt7615_load_patch.patch [new file with mode: 0644]
queue-5.3/mt76-mt7615-fix-mt7615-firmware-path-definitions.patch [new file with mode: 0644]
queue-5.3/platform-chrome-cros_ec_rpmsg-fix-race-with-host-com.patch [new file with mode: 0644]
queue-5.3/series

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 (file)
index 0000000..74d0ebe
--- /dev/null
@@ -0,0 +1,140 @@
+From 090ee88724fd9a33cf6fbc0a5f5663d633b262fd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 9 Sep 2019 16:30:02 +1000
+Subject: md/raid0: avoid RAID0 data corruption due to layout confusion.
+
+From: NeilBrown <neilb@suse.de>
+
+[ 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 <guoqing.jiang@cloud.ionos.com>
+Signed-off-by: NeilBrown <neilb@suse.de>
+Signed-off-by: Song Liu <songliubraving@fb.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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, &sector);
+-      tmp_dev = map_sector(mddev, zone, sector, &sector);
++      switch (conf->layout) {
++      case RAID0_ORIG_LAYOUT:
++              tmp_dev = map_sector(mddev, zone, orig_sector, &sector);
++              break;
++      case RAID0_ALT_MULTIZONE_LAYOUT:
++              tmp_dev = map_sector(mddev, zone, sector, &sector);
++              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 (file)
index 0000000..4d26217
--- /dev/null
@@ -0,0 +1,47 @@
+From a4bfade20dbb3afd3d36c0268f4aa671da623d9d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 2 Jul 2019 11:24:51 +0200
+Subject: mt76: mt7615: always release sem in mt7615_load_patch
+
+From: Lorenzo Bianconi <lorenzo@kernel.org>
+
+[ Upstream commit 2fc446487c364bf8bbd5f8f5f27e52d914fa1d72 ]
+
+Release patch semaphore even if request_firmware fails in
+mt7615_load_patch
+
+Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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 (file)
index 0000000..95463d6
--- /dev/null
@@ -0,0 +1,91 @@
+From 3da1aa824a0612c4a0ab2010abe0e3df7a354672 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 22 Sep 2019 15:36:03 +0200
+Subject: mt76: mt7615: fix mt7615 firmware path definitions
+
+From: Lorenzo Bianconi <lorenzo@kernel.org>
+
+[ 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 <lorenzo@kernel.org>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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 (file)
index 0000000..5ba4170
--- /dev/null
@@ -0,0 +1,126 @@
+From b8abca2072825716d13f7fe2eb985ff40ff977ab Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+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 <pihsun@chromium.org>
+
+[ 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 <pihsun@chromium.org>
+Signed-off-by: Enric Balletbo i Serra <enric.balletbo@collabora.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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
+
index 40c5f577541fd2aa3d3768170e9f7f0d87ec1264..5e4e482ed73e6fa28aef1204b061b277d5405b75 100644 (file)
@@ -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