]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
Fixes for 5.15
authorSasha Levin <sashal@kernel.org>
Sat, 19 Nov 2022 17:24:34 +0000 (12:24 -0500)
committerSasha Levin <sashal@kernel.org>
Sat, 19 Nov 2022 17:24:34 +0000 (12:24 -0500)
Signed-off-by: Sasha Levin <sashal@kernel.org>
queue-5.15/hugetlbfs-don-t-delete-error-page-from-pagecache.patch [new file with mode: 0644]
queue-5.15/kvm-x86-pmu-do-not-speculatively-query-intel-gp-pmcs.patch [new file with mode: 0644]
queue-5.15/mtd-spi-nor-intel-spi-disable-write-protection-only-.patch [new file with mode: 0644]
queue-5.15/series
queue-5.15/spi-intel-use-correct-mask-for-flash-and-protected-r.patch [new file with mode: 0644]

diff --git a/queue-5.15/hugetlbfs-don-t-delete-error-page-from-pagecache.patch b/queue-5.15/hugetlbfs-don-t-delete-error-page-from-pagecache.patch
new file mode 100644 (file)
index 0000000..628a8c4
--- /dev/null
@@ -0,0 +1,123 @@
+From 0a2add122582bf84c10561cad33fe3b36c1e4209 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 18 Oct 2022 20:01:25 +0000
+Subject: hugetlbfs: don't delete error page from pagecache
+
+From: James Houghton <jthoughton@google.com>
+
+[ Upstream commit 8625147cafaa9ba74713d682f5185eb62cb2aedb ]
+
+This change is very similar to the change that was made for shmem [1], and
+it solves the same problem but for HugeTLBFS instead.
+
+Currently, when poison is found in a HugeTLB page, the page is removed
+from the page cache.  That means that attempting to map or read that
+hugepage in the future will result in a new hugepage being allocated
+instead of notifying the user that the page was poisoned.  As [1] states,
+this is effectively memory corruption.
+
+The fix is to leave the page in the page cache.  If the user attempts to
+use a poisoned HugeTLB page with a syscall, the syscall will fail with
+EIO, the same error code that shmem uses.  For attempts to map the page,
+the thread will get a BUS_MCEERR_AR SIGBUS.
+
+[1]: commit a76054266661 ("mm: shmem: don't truncate page if memory failure happens")
+
+Link: https://lkml.kernel.org/r/20221018200125.848471-1-jthoughton@google.com
+Signed-off-by: James Houghton <jthoughton@google.com>
+Reviewed-by: Mike Kravetz <mike.kravetz@oracle.com>
+Reviewed-by: Naoya Horiguchi <naoya.horiguchi@nec.com>
+Tested-by: Naoya Horiguchi <naoya.horiguchi@nec.com>
+Reviewed-by: Yang Shi <shy828301@gmail.com>
+Cc: Axel Rasmussen <axelrasmussen@google.com>
+Cc: James Houghton <jthoughton@google.com>
+Cc: Miaohe Lin <linmiaohe@huawei.com>
+Cc: Muchun Song <songmuchun@bytedance.com>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/hugetlbfs/inode.c | 13 ++++++-------
+ mm/hugetlb.c         |  4 ++++
+ mm/memory-failure.c  |  5 ++++-
+ 3 files changed, 14 insertions(+), 8 deletions(-)
+
+diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c
+index d74a49b188c2..be8deec29ebe 100644
+--- a/fs/hugetlbfs/inode.c
++++ b/fs/hugetlbfs/inode.c
+@@ -361,6 +361,12 @@ static ssize_t hugetlbfs_read_iter(struct kiocb *iocb, struct iov_iter *to)
+               } else {
+                       unlock_page(page);
++                      if (PageHWPoison(page)) {
++                              put_page(page);
++                              retval = -EIO;
++                              break;
++                      }
++
+                       /*
+                        * We have the page, copy it to user space buffer.
+                        */
+@@ -984,13 +990,6 @@ static int hugetlbfs_migrate_page(struct address_space *mapping,
+ static int hugetlbfs_error_remove_page(struct address_space *mapping,
+                               struct page *page)
+ {
+-      struct inode *inode = mapping->host;
+-      pgoff_t index = page->index;
+-
+-      remove_huge_page(page);
+-      if (unlikely(hugetlb_unreserve_pages(inode, index, index + 1, 1)))
+-              hugetlb_fix_reserve_counts(inode);
+-
+       return 0;
+ }
+diff --git a/mm/hugetlb.c b/mm/hugetlb.c
+index dbb63ec3b5fa..e7bd42f23667 100644
+--- a/mm/hugetlb.c
++++ b/mm/hugetlb.c
+@@ -5350,6 +5350,10 @@ int hugetlb_mcopy_atomic_pte(struct mm_struct *dst_mm,
+       ptl = huge_pte_lockptr(h, dst_mm, dst_pte);
+       spin_lock(ptl);
++      ret = -EIO;
++      if (PageHWPoison(page))
++              goto out_release_unlock;
++
+       /*
+        * Recheck the i_size after holding PT lock to make sure not
+        * to leave any page mapped (as page_mapped()) beyond the end
+diff --git a/mm/memory-failure.c b/mm/memory-failure.c
+index 85b1a77e3a99..2ad0f4580091 100644
+--- a/mm/memory-failure.c
++++ b/mm/memory-failure.c
+@@ -1040,6 +1040,7 @@ static int me_huge_page(struct page_state *ps, struct page *p)
+       int res;
+       struct page *hpage = compound_head(p);
+       struct address_space *mapping;
++      bool extra_pins = false;
+       if (!PageHuge(hpage))
+               return MF_DELAYED;
+@@ -1047,6 +1048,8 @@ static int me_huge_page(struct page_state *ps, struct page *p)
+       mapping = page_mapping(hpage);
+       if (mapping) {
+               res = truncate_error_page(hpage, page_to_pfn(p), mapping);
++              /* The page is kept in page cache. */
++              extra_pins = true;
+               unlock_page(hpage);
+       } else {
+               res = MF_FAILED;
+@@ -1064,7 +1067,7 @@ static int me_huge_page(struct page_state *ps, struct page *p)
+               }
+       }
+-      if (has_extra_refcount(ps, p, false))
++      if (has_extra_refcount(ps, p, extra_pins))
+               res = MF_FAILED;
+       return res;
+-- 
+2.35.1
+
diff --git a/queue-5.15/kvm-x86-pmu-do-not-speculatively-query-intel-gp-pmcs.patch b/queue-5.15/kvm-x86-pmu-do-not-speculatively-query-intel-gp-pmcs.patch
new file mode 100644 (file)
index 0000000..6078da0
--- /dev/null
@@ -0,0 +1,82 @@
+From 8e36458495d4d2002a7dbf3fc4067a71128a4dd2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 19 Sep 2022 17:10:06 +0800
+Subject: KVM: x86/pmu: Do not speculatively query Intel GP PMCs that don't
+ exist yet
+
+From: Like Xu <likexu@tencent.com>
+
+[ Upstream commit 8631ef59b62290c7d88e7209e35dfb47f33f4902 ]
+
+The SDM lists an architectural MSR IA32_CORE_CAPABILITIES (0xCF)
+that limits the theoretical maximum value of the Intel GP PMC MSRs
+allocated at 0xC1 to 14; likewise the Intel April 2022 SDM adds
+IA32_OVERCLOCKING_STATUS at 0x195 which limits the number of event
+selection MSRs to 15 (0x186-0x194).
+
+Limiting the maximum number of counters to 14 or 18 based on the currently
+allocated MSRs is clearly fragile, and it seems likely that Intel will
+even place PMCs 8-15 at a completely different range of MSR indices.
+So stop at the maximum number of GP PMCs supported today on Intel
+processors.
+
+There are some machines, like Intel P4 with non Architectural PMU, that
+may indeed have 18 counters, but those counters are in a completely
+different MSR address range and are not supported by KVM.
+
+Cc: Vitaly Kuznetsov <vkuznets@redhat.com>
+Cc: stable@vger.kernel.org
+Fixes: cf05a67b68b8 ("KVM: x86: omit "impossible" pmu MSRs from MSR list")
+Suggested-by: Jim Mattson <jmattson@google.com>
+Signed-off-by: Like Xu <likexu@tencent.com>
+Reviewed-by: Jim Mattson <jmattson@google.com>
+Message-Id: <20220919091008.60695-1-likexu@tencent.com>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/kvm/x86.c | 14 ++------------
+ 1 file changed, 2 insertions(+), 12 deletions(-)
+
+diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
+index 7f41e1f9f0b4..c58e23e9b5ec 100644
+--- a/arch/x86/kvm/x86.c
++++ b/arch/x86/kvm/x86.c
+@@ -1347,20 +1347,10 @@ static const u32 msrs_to_save_all[] = {
+       MSR_ARCH_PERFMON_PERFCTR0 + 2, MSR_ARCH_PERFMON_PERFCTR0 + 3,
+       MSR_ARCH_PERFMON_PERFCTR0 + 4, MSR_ARCH_PERFMON_PERFCTR0 + 5,
+       MSR_ARCH_PERFMON_PERFCTR0 + 6, MSR_ARCH_PERFMON_PERFCTR0 + 7,
+-      MSR_ARCH_PERFMON_PERFCTR0 + 8, MSR_ARCH_PERFMON_PERFCTR0 + 9,
+-      MSR_ARCH_PERFMON_PERFCTR0 + 10, MSR_ARCH_PERFMON_PERFCTR0 + 11,
+-      MSR_ARCH_PERFMON_PERFCTR0 + 12, MSR_ARCH_PERFMON_PERFCTR0 + 13,
+-      MSR_ARCH_PERFMON_PERFCTR0 + 14, MSR_ARCH_PERFMON_PERFCTR0 + 15,
+-      MSR_ARCH_PERFMON_PERFCTR0 + 16, MSR_ARCH_PERFMON_PERFCTR0 + 17,
+       MSR_ARCH_PERFMON_EVENTSEL0, MSR_ARCH_PERFMON_EVENTSEL1,
+       MSR_ARCH_PERFMON_EVENTSEL0 + 2, MSR_ARCH_PERFMON_EVENTSEL0 + 3,
+       MSR_ARCH_PERFMON_EVENTSEL0 + 4, MSR_ARCH_PERFMON_EVENTSEL0 + 5,
+       MSR_ARCH_PERFMON_EVENTSEL0 + 6, MSR_ARCH_PERFMON_EVENTSEL0 + 7,
+-      MSR_ARCH_PERFMON_EVENTSEL0 + 8, MSR_ARCH_PERFMON_EVENTSEL0 + 9,
+-      MSR_ARCH_PERFMON_EVENTSEL0 + 10, MSR_ARCH_PERFMON_EVENTSEL0 + 11,
+-      MSR_ARCH_PERFMON_EVENTSEL0 + 12, MSR_ARCH_PERFMON_EVENTSEL0 + 13,
+-      MSR_ARCH_PERFMON_EVENTSEL0 + 14, MSR_ARCH_PERFMON_EVENTSEL0 + 15,
+-      MSR_ARCH_PERFMON_EVENTSEL0 + 16, MSR_ARCH_PERFMON_EVENTSEL0 + 17,
+       MSR_K7_EVNTSEL0, MSR_K7_EVNTSEL1, MSR_K7_EVNTSEL2, MSR_K7_EVNTSEL3,
+       MSR_K7_PERFCTR0, MSR_K7_PERFCTR1, MSR_K7_PERFCTR2, MSR_K7_PERFCTR3,
+@@ -6449,12 +6439,12 @@ static void kvm_init_msr_list(void)
+                               intel_pt_validate_hw_cap(PT_CAP_num_address_ranges) * 2)
+                               continue;
+                       break;
+-              case MSR_ARCH_PERFMON_PERFCTR0 ... MSR_ARCH_PERFMON_PERFCTR0 + 17:
++              case MSR_ARCH_PERFMON_PERFCTR0 ... MSR_ARCH_PERFMON_PERFCTR0 + 7:
+                       if (msrs_to_save_all[i] - MSR_ARCH_PERFMON_PERFCTR0 >=
+                           min(INTEL_PMC_MAX_GENERIC, x86_pmu.num_counters_gp))
+                               continue;
+                       break;
+-              case MSR_ARCH_PERFMON_EVENTSEL0 ... MSR_ARCH_PERFMON_EVENTSEL0 + 17:
++              case MSR_ARCH_PERFMON_EVENTSEL0 ... MSR_ARCH_PERFMON_EVENTSEL0 + 7:
+                       if (msrs_to_save_all[i] - MSR_ARCH_PERFMON_EVENTSEL0 >=
+                           min(INTEL_PMC_MAX_GENERIC, x86_pmu.num_counters_gp))
+                               continue;
+-- 
+2.35.1
+
diff --git a/queue-5.15/mtd-spi-nor-intel-spi-disable-write-protection-only-.patch b/queue-5.15/mtd-spi-nor-intel-spi-disable-write-protection-only-.patch
new file mode 100644 (file)
index 0000000..dbf54ee
--- /dev/null
@@ -0,0 +1,320 @@
+From a691a45af85b0a8225023e72296ac19ec689168b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 9 Feb 2022 15:27:04 +0300
+Subject: mtd: spi-nor: intel-spi: Disable write protection only if asked
+
+From: Mika Westerberg <mika.westerberg@linux.intel.com>
+
+[ Upstream commit cd149eff8d2201a63c074a6d9d03e52926aa535d ]
+
+Currently the driver tries to disable the BIOS write protection
+automatically even if this is not what the user wants. For this reason
+modify the driver so that by default it does not touch the write
+protection. Only if specifically asked by the user (setting writeable=1
+command line parameter) the driver tries to disable the BIOS write
+protection.
+
+Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
+Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Reviewed-by: Mauro Lima <mauro.lima@eclypsium.com>
+Reviewed-by: Tudor Ambarus <tudor.ambarus@microchip.com>
+Acked-by: Lee Jones <lee.jones@linaro.org>
+Link: https://lore.kernel.org/r/20220209122706.42439-2-mika.westerberg@linux.intel.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Stable-dep-of: 92a66cbf6b30 ("spi: intel: Use correct mask for flash and protected regions")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mfd/lpc_ich.c                         | 59 +++++++++++++++++--
+ .../mtd/spi-nor/controllers/intel-spi-pci.c   | 29 +++++----
+ drivers/mtd/spi-nor/controllers/intel-spi.c   | 41 ++++++-------
+ include/linux/platform_data/x86/intel-spi.h   |  6 +-
+ 4 files changed, 96 insertions(+), 39 deletions(-)
+
+diff --git a/drivers/mfd/lpc_ich.c b/drivers/mfd/lpc_ich.c
+index f10e53187f67..9ffab9aafd81 100644
+--- a/drivers/mfd/lpc_ich.c
++++ b/drivers/mfd/lpc_ich.c
+@@ -63,6 +63,8 @@
+ #define SPIBASE_BYT           0x54
+ #define SPIBASE_BYT_SZ                512
+ #define SPIBASE_BYT_EN                BIT(1)
++#define BYT_BCR                       0xfc
++#define BYT_BCR_WPD           BIT(0)
+ #define SPIBASE_LPT           0x3800
+ #define SPIBASE_LPT_SZ                512
+@@ -1084,12 +1086,57 @@ static int lpc_ich_init_wdt(struct pci_dev *dev)
+       return ret;
+ }
++static bool lpc_ich_byt_set_writeable(void __iomem *base, void *data)
++{
++      u32 val;
++
++      val = readl(base + BYT_BCR);
++      if (!(val & BYT_BCR_WPD)) {
++              val |= BYT_BCR_WPD;
++              writel(val, base + BYT_BCR);
++              val = readl(base + BYT_BCR);
++      }
++
++      return val & BYT_BCR_WPD;
++}
++
++static bool lpc_ich_lpt_set_writeable(void __iomem *base, void *data)
++{
++      struct pci_dev *pdev = data;
++      u32 bcr;
++
++      pci_read_config_dword(pdev, BCR, &bcr);
++      if (!(bcr & BCR_WPD)) {
++              bcr |= BCR_WPD;
++              pci_write_config_dword(pdev, BCR, bcr);
++              pci_read_config_dword(pdev, BCR, &bcr);
++      }
++
++      return bcr & BCR_WPD;
++}
++
++static bool lpc_ich_bxt_set_writeable(void __iomem *base, void *data)
++{
++      unsigned int spi = PCI_DEVFN(13, 2);
++      struct pci_bus *bus = data;
++      u32 bcr;
++
++      pci_bus_read_config_dword(bus, spi, BCR, &bcr);
++      if (!(bcr & BCR_WPD)) {
++              bcr |= BCR_WPD;
++              pci_bus_write_config_dword(bus, spi, BCR, bcr);
++              pci_bus_read_config_dword(bus, spi, BCR, &bcr);
++      }
++
++      return bcr & BCR_WPD;
++}
++
+ static int lpc_ich_init_spi(struct pci_dev *dev)
+ {
+       struct lpc_ich_priv *priv = pci_get_drvdata(dev);
+       struct resource *res = &intel_spi_res[0];
+       struct intel_spi_boardinfo *info;
+-      u32 spi_base, rcba, bcr;
++      u32 spi_base, rcba;
+       info = devm_kzalloc(&dev->dev, sizeof(*info), GFP_KERNEL);
+       if (!info)
+@@ -1103,6 +1150,8 @@ static int lpc_ich_init_spi(struct pci_dev *dev)
+               if (spi_base & SPIBASE_BYT_EN) {
+                       res->start = spi_base & ~(SPIBASE_BYT_SZ - 1);
+                       res->end = res->start + SPIBASE_BYT_SZ - 1;
++
++                      info->set_writeable = lpc_ich_byt_set_writeable;
+               }
+               break;
+@@ -1113,8 +1162,8 @@ static int lpc_ich_init_spi(struct pci_dev *dev)
+                       res->start = spi_base + SPIBASE_LPT;
+                       res->end = res->start + SPIBASE_LPT_SZ - 1;
+-                      pci_read_config_dword(dev, BCR, &bcr);
+-                      info->writeable = !!(bcr & BCR_WPD);
++                      info->set_writeable = lpc_ich_lpt_set_writeable;
++                      info->data = dev;
+               }
+               break;
+@@ -1135,8 +1184,8 @@ static int lpc_ich_init_spi(struct pci_dev *dev)
+                       res->start = spi_base & 0xfffffff0;
+                       res->end = res->start + SPIBASE_APL_SZ - 1;
+-                      pci_bus_read_config_dword(bus, spi, BCR, &bcr);
+-                      info->writeable = !!(bcr & BCR_WPD);
++                      info->set_writeable = lpc_ich_bxt_set_writeable;
++                      info->data = bus;
+               }
+               pci_bus_write_config_byte(bus, p2sb, 0xe1, 0x1);
+diff --git a/drivers/mtd/spi-nor/controllers/intel-spi-pci.c b/drivers/mtd/spi-nor/controllers/intel-spi-pci.c
+index 1bc53b8bb88a..508f7ca098ef 100644
+--- a/drivers/mtd/spi-nor/controllers/intel-spi-pci.c
++++ b/drivers/mtd/spi-nor/controllers/intel-spi-pci.c
+@@ -16,12 +16,30 @@
+ #define BCR           0xdc
+ #define BCR_WPD               BIT(0)
++static bool intel_spi_pci_set_writeable(void __iomem *base, void *data)
++{
++      struct pci_dev *pdev = data;
++      u32 bcr;
++
++      /* Try to make the chip read/write */
++      pci_read_config_dword(pdev, BCR, &bcr);
++      if (!(bcr & BCR_WPD)) {
++              bcr |= BCR_WPD;
++              pci_write_config_dword(pdev, BCR, bcr);
++              pci_read_config_dword(pdev, BCR, &bcr);
++      }
++
++      return bcr & BCR_WPD;
++}
++
+ static const struct intel_spi_boardinfo bxt_info = {
+       .type = INTEL_SPI_BXT,
++      .set_writeable = intel_spi_pci_set_writeable,
+ };
+ static const struct intel_spi_boardinfo cnl_info = {
+       .type = INTEL_SPI_CNL,
++      .set_writeable = intel_spi_pci_set_writeable,
+ };
+ static int intel_spi_pci_probe(struct pci_dev *pdev,
+@@ -29,7 +47,6 @@ static int intel_spi_pci_probe(struct pci_dev *pdev,
+ {
+       struct intel_spi_boardinfo *info;
+       struct intel_spi *ispi;
+-      u32 bcr;
+       int ret;
+       ret = pcim_enable_device(pdev);
+@@ -41,15 +58,7 @@ static int intel_spi_pci_probe(struct pci_dev *pdev,
+       if (!info)
+               return -ENOMEM;
+-      /* Try to make the chip read/write */
+-      pci_read_config_dword(pdev, BCR, &bcr);
+-      if (!(bcr & BCR_WPD)) {
+-              bcr |= BCR_WPD;
+-              pci_write_config_dword(pdev, BCR, bcr);
+-              pci_read_config_dword(pdev, BCR, &bcr);
+-      }
+-      info->writeable = !!(bcr & BCR_WPD);
+-
++      info->data = pdev;
+       ispi = intel_spi_probe(&pdev->dev, &pdev->resource[0], info);
+       if (IS_ERR(ispi))
+               return PTR_ERR(ispi);
+diff --git a/drivers/mtd/spi-nor/controllers/intel-spi.c b/drivers/mtd/spi-nor/controllers/intel-spi.c
+index 72dab5937df1..2b91249a4c3f 100644
+--- a/drivers/mtd/spi-nor/controllers/intel-spi.c
++++ b/drivers/mtd/spi-nor/controllers/intel-spi.c
+@@ -131,7 +131,6 @@
+  * @sregs: Start of software sequencer registers
+  * @nregions: Maximum number of regions
+  * @pr_num: Maximum number of protected range registers
+- * @writeable: Is the chip writeable
+  * @locked: Is SPI setting locked
+  * @swseq_reg: Use SW sequencer in register reads/writes
+  * @swseq_erase: Use SW sequencer in erase operation
+@@ -149,7 +148,6 @@ struct intel_spi {
+       void __iomem *sregs;
+       size_t nregions;
+       size_t pr_num;
+-      bool writeable;
+       bool locked;
+       bool swseq_reg;
+       bool swseq_erase;
+@@ -304,6 +302,14 @@ static int intel_spi_wait_sw_busy(struct intel_spi *ispi)
+                                 INTEL_SPI_TIMEOUT * 1000);
+ }
++static bool intel_spi_set_writeable(struct intel_spi *ispi)
++{
++      if (!ispi->info->set_writeable)
++              return false;
++
++      return ispi->info->set_writeable(ispi->base, ispi->info->data);
++}
++
+ static int intel_spi_init(struct intel_spi *ispi)
+ {
+       u32 opmenu0, opmenu1, lvscc, uvscc, val;
+@@ -316,19 +322,6 @@ static int intel_spi_init(struct intel_spi *ispi)
+               ispi->nregions = BYT_FREG_NUM;
+               ispi->pr_num = BYT_PR_NUM;
+               ispi->swseq_reg = true;
+-
+-              if (writeable) {
+-                      /* Disable write protection */
+-                      val = readl(ispi->base + BYT_BCR);
+-                      if (!(val & BYT_BCR_WPD)) {
+-                              val |= BYT_BCR_WPD;
+-                              writel(val, ispi->base + BYT_BCR);
+-                              val = readl(ispi->base + BYT_BCR);
+-                      }
+-
+-                      ispi->writeable = !!(val & BYT_BCR_WPD);
+-              }
+-
+               break;
+       case INTEL_SPI_LPT:
+@@ -358,6 +351,12 @@ static int intel_spi_init(struct intel_spi *ispi)
+               return -EINVAL;
+       }
++      /* Try to disable write protection if user asked to do so */
++      if (writeable && !intel_spi_set_writeable(ispi)) {
++              dev_warn(ispi->dev, "can't disable chip write protection\n");
++              writeable = false;
++      }
++
+       /* Disable #SMI generation from HW sequencer */
+       val = readl(ispi->base + HSFSTS_CTL);
+       val &= ~HSFSTS_CTL_FSMIE;
+@@ -884,9 +883,12 @@ static void intel_spi_fill_partition(struct intel_spi *ispi,
+               /*
+                * If any of the regions have protection bits set, make the
+                * whole partition read-only to be on the safe side.
++               *
++               * Also if the user did not ask the chip to be writeable
++               * mask the bit too.
+                */
+-              if (intel_spi_is_protected(ispi, base, limit))
+-                      ispi->writeable = false;
++              if (!writeable || intel_spi_is_protected(ispi, base, limit))
++                      part->mask_flags |= MTD_WRITEABLE;
+               end = (limit << 12) + 4096;
+               if (end > part->size)
+@@ -927,7 +929,6 @@ struct intel_spi *intel_spi_probe(struct device *dev,
+       ispi->dev = dev;
+       ispi->info = info;
+-      ispi->writeable = info->writeable;
+       ret = intel_spi_init(ispi);
+       if (ret)
+@@ -945,10 +946,6 @@ struct intel_spi *intel_spi_probe(struct device *dev,
+       intel_spi_fill_partition(ispi, &part);
+-      /* Prevent writes if not explicitly enabled */
+-      if (!ispi->writeable || !writeable)
+-              ispi->nor.mtd.flags &= ~MTD_WRITEABLE;
+-
+       ret = mtd_device_register(&ispi->nor.mtd, &part, 1);
+       if (ret)
+               return ERR_PTR(ret);
+diff --git a/include/linux/platform_data/x86/intel-spi.h b/include/linux/platform_data/x86/intel-spi.h
+index 7f53a5c6f35e..7dda3f690465 100644
+--- a/include/linux/platform_data/x86/intel-spi.h
++++ b/include/linux/platform_data/x86/intel-spi.h
+@@ -19,11 +19,13 @@ enum intel_spi_type {
+ /**
+  * struct intel_spi_boardinfo - Board specific data for Intel SPI driver
+  * @type: Type which this controller is compatible with
+- * @writeable: The chip is writeable
++ * @set_writeable: Try to make the chip writeable (optional)
++ * @data: Data to be passed to @set_writeable can be %NULL
+  */
+ struct intel_spi_boardinfo {
+       enum intel_spi_type type;
+-      bool writeable;
++      bool (*set_writeable)(void __iomem *base, void *data);
++      void *data;
+ };
+ #endif /* INTEL_SPI_PDATA_H */
+-- 
+2.35.1
+
index 335aabe7a1428db59e1fcfa62be3f646ad19a4a1..7d1e61a9091b37a0161c8a7c6e351ce326e3891f 100644 (file)
@@ -31,3 +31,7 @@ btrfs-remove-pointless-and-double-ulist-frees-in-err.patch
 bluetooth-l2cap-fix-l2cap_global_chan_by_psm.patch
 x86-cpu-add-several-intel-server-cpu-model-numbers.patch
 asoc-codecs-jz4725b-fix-spelling-mistake-sourc-sourc.patch
+mtd-spi-nor-intel-spi-disable-write-protection-only-.patch
+spi-intel-use-correct-mask-for-flash-and-protected-r.patch
+kvm-x86-pmu-do-not-speculatively-query-intel-gp-pmcs.patch
+hugetlbfs-don-t-delete-error-page-from-pagecache.patch
diff --git a/queue-5.15/spi-intel-use-correct-mask-for-flash-and-protected-r.patch b/queue-5.15/spi-intel-use-correct-mask-for-flash-and-protected-r.patch
new file mode 100644 (file)
index 0000000..071de69
--- /dev/null
@@ -0,0 +1,50 @@
+From ab044e24fce09694360c4c3ae16427e3da48a51f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 25 Oct 2022 09:28:00 +0300
+Subject: spi: intel: Use correct mask for flash and protected regions
+
+From: Mika Westerberg <mika.westerberg@linux.intel.com>
+
+[ Upstream commit 92a66cbf6b30eda5719fbdfb24cd15fb341bba32 ]
+
+The flash and protected region mask is actually 0x7fff (30:16 and 14:0)
+and not 0x3fff so fix this accordingly. While there use GENMASK() instead.
+
+Cc: stable@vger.kernel.org
+Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
+Link: https://lore.kernel.org/r/20221025062800.22357-1-mika.westerberg@linux.intel.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/mtd/spi-nor/controllers/intel-spi.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/mtd/spi-nor/controllers/intel-spi.c b/drivers/mtd/spi-nor/controllers/intel-spi.c
+index 2b91249a4c3f..6cb818feaf7f 100644
+--- a/drivers/mtd/spi-nor/controllers/intel-spi.c
++++ b/drivers/mtd/spi-nor/controllers/intel-spi.c
+@@ -52,17 +52,17 @@
+ #define FRACC                         0x50
+ #define FREG(n)                               (0x54 + ((n) * 4))
+-#define FREG_BASE_MASK                        0x3fff
++#define FREG_BASE_MASK                        GENMASK(14, 0)
+ #define FREG_LIMIT_SHIFT              16
+-#define FREG_LIMIT_MASK                       (0x03fff << FREG_LIMIT_SHIFT)
++#define FREG_LIMIT_MASK                       GENMASK(30, 16)
+ /* Offset is from @ispi->pregs */
+ #define PR(n)                         ((n) * 4)
+ #define PR_WPE                                BIT(31)
+ #define PR_LIMIT_SHIFT                        16
+-#define PR_LIMIT_MASK                 (0x3fff << PR_LIMIT_SHIFT)
++#define PR_LIMIT_MASK                 GENMASK(30, 16)
+ #define PR_RPE                                BIT(15)
+-#define PR_BASE_MASK                  0x3fff
++#define PR_BASE_MASK                  GENMASK(14, 0)
+ /* Offsets are from @ispi->sregs */
+ #define SSFSTS_CTL                    0x00
+-- 
+2.35.1
+