]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
6.1-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 14 Oct 2024 13:45:48 +0000 (15:45 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 14 Oct 2024 13:45:48 +0000 (15:45 +0200)
added patches:
revert-iommu-vt-d-retrieve-iommu-perfmon-capability-information.patch

queue-6.1/revert-iommu-vt-d-retrieve-iommu-perfmon-capability-information.patch [new file with mode: 0644]
queue-6.1/series

diff --git a/queue-6.1/revert-iommu-vt-d-retrieve-iommu-perfmon-capability-information.patch b/queue-6.1/revert-iommu-vt-d-retrieve-iommu-perfmon-capability-information.patch
new file mode 100644 (file)
index 0000000..d9dc882
--- /dev/null
@@ -0,0 +1,397 @@
+From 286b2d88de310423b2cda454f327b3fd3600b56d Mon Sep 17 00:00:00 2001
+From: Jack Wang <jinpu.wang@ionos.com>
+Date: Fri, 11 Oct 2024 07:10:34 +0200
+Subject: Revert "iommu/vt-d: Retrieve IOMMU perfmon capability information"
+
+From: Jack Wang <jinpu.wang@ionos.com>
+
+This reverts commit 586e19c88a0cb58b6ff45ae085b3dd200d862153 which is
+commit a6a5006dad572a53b5df3f47e1471d207ae9ba49 upstream.
+
+This commit is pulled in due to dependency for:
+8c91a4bfc7f8 ("iommu: Fix compilation without CONFIG_IOMMU_INTEL")
+
+But the patch itself is part of a patchset, should not only include one,
+and it lead to boot hang on on Kernel 6.1.83+ with Dell PowerEdge R770
+and Intel Xeon 6710E, so revert it for stable 6.1.112
+
+Signed-off-by: Jack Wang <jinpu.wang@ionos.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/iommu/intel/Kconfig   |   11 --
+ drivers/iommu/intel/Makefile  |    1 
+ drivers/iommu/intel/dmar.c    |    7 -
+ drivers/iommu/intel/iommu.h   |   43 ----------
+ drivers/iommu/intel/perfmon.c |  172 ------------------------------------------
+ drivers/iommu/intel/perfmon.h |   40 ---------
+ 6 files changed, 1 insertion(+), 273 deletions(-)
+ delete mode 100644 drivers/iommu/intel/perfmon.c
+ delete mode 100644 drivers/iommu/intel/perfmon.h
+
+--- a/drivers/iommu/intel/Kconfig
++++ b/drivers/iommu/intel/Kconfig
+@@ -96,15 +96,4 @@ config INTEL_IOMMU_SCALABLE_MODE_DEFAULT
+         passing intel_iommu=sm_on to the kernel. If not sure, please use
+         the default value.
+-config INTEL_IOMMU_PERF_EVENTS
+-      def_bool y
+-      bool "Intel IOMMU performance events"
+-      depends on INTEL_IOMMU && PERF_EVENTS
+-      help
+-        Selecting this option will enable the performance monitoring
+-        infrastructure in the Intel IOMMU. It collects information about
+-        key events occurring during operation of the remapping hardware,
+-        to aid performance tuning and debug. These are available on modern
+-        processors which support Intel VT-d 4.0 and later.
+-
+ endif # INTEL_IOMMU
+--- a/drivers/iommu/intel/Makefile
++++ b/drivers/iommu/intel/Makefile
+@@ -8,4 +8,3 @@ obj-$(CONFIG_INTEL_IOMMU_SVM) += svm.o
+ ifdef CONFIG_INTEL_IOMMU
+ obj-$(CONFIG_IRQ_REMAP) += irq_remapping.o
+ endif
+-obj-$(CONFIG_INTEL_IOMMU_PERF_EVENTS) += perfmon.o
+--- a/drivers/iommu/intel/dmar.c
++++ b/drivers/iommu/intel/dmar.c
+@@ -34,7 +34,6 @@
+ #include "../irq_remapping.h"
+ #include "perf.h"
+ #include "trace.h"
+-#include "perfmon.h"
+ typedef int (*dmar_res_handler_t)(struct acpi_dmar_header *, void *);
+ struct dmar_res_callback {
+@@ -1105,9 +1104,6 @@ static int alloc_iommu(struct dmar_drhd_
+       if (sts & DMA_GSTS_QIES)
+               iommu->gcmd |= DMA_GCMD_QIE;
+-      if (alloc_iommu_pmu(iommu))
+-              pr_debug("Cannot alloc PMU for iommu (seq_id = %d)\n", iommu->seq_id);
+-
+       raw_spin_lock_init(&iommu->register_lock);
+       /*
+@@ -1135,7 +1131,6 @@ static int alloc_iommu(struct dmar_drhd_
+ err_sysfs:
+       iommu_device_sysfs_remove(&iommu->iommu);
+ err_unmap:
+-      free_iommu_pmu(iommu);
+       unmap_iommu(iommu);
+ error_free_seq_id:
+       ida_free(&dmar_seq_ids, iommu->seq_id);
+@@ -1151,8 +1146,6 @@ static void free_iommu(struct intel_iomm
+               iommu_device_sysfs_remove(&iommu->iommu);
+       }
+-      free_iommu_pmu(iommu);
+-
+       if (iommu->irq) {
+               if (iommu->pr_irq) {
+                       free_irq(iommu->pr_irq, iommu);
+--- a/drivers/iommu/intel/iommu.h
++++ b/drivers/iommu/intel/iommu.h
+@@ -125,11 +125,6 @@
+ #define DMAR_MTRR_PHYSMASK8_REG 0x208
+ #define DMAR_MTRR_PHYSBASE9_REG 0x210
+ #define DMAR_MTRR_PHYSMASK9_REG 0x218
+-#define DMAR_PERFCAP_REG      0x300
+-#define DMAR_PERFCFGOFF_REG   0x310
+-#define DMAR_PERFOVFOFF_REG   0x318
+-#define DMAR_PERFCNTROFF_REG  0x31c
+-#define DMAR_PERFEVNTCAP_REG  0x380
+ #define DMAR_VCCAP_REG                0xe30 /* Virtual command capability register */
+ #define DMAR_VCMD_REG         0xe00 /* Virtual command register */
+ #define DMAR_VCRSP_REG                0xe10 /* Virtual command response register */
+@@ -153,7 +148,6 @@
+  */
+ #define cap_esrtps(c)         (((c) >> 63) & 1)
+ #define cap_esirtps(c)                (((c) >> 62) & 1)
+-#define cap_ecmds(c)          (((c) >> 61) & 1)
+ #define cap_fl5lp_support(c)  (((c) >> 60) & 1)
+ #define cap_pi_support(c)     (((c) >> 59) & 1)
+ #define cap_fl1gp_support(c)  (((c) >> 56) & 1)
+@@ -185,8 +179,7 @@
+  * Extended Capability Register
+  */
+-#define ecap_pms(e)           (((e) >> 51) & 0x1)
+-#define ecap_rps(e)           (((e) >> 49) & 0x1)
++#define       ecap_rps(e)             (((e) >> 49) & 0x1)
+ #define ecap_smpwc(e)         (((e) >> 48) & 0x1)
+ #define ecap_flts(e)          (((e) >> 47) & 0x1)
+ #define ecap_slts(e)          (((e) >> 46) & 0x1)
+@@ -217,22 +210,6 @@
+ #define ecap_max_handle_mask(e) (((e) >> 20) & 0xf)
+ #define ecap_sc_support(e)    (((e) >> 7) & 0x1) /* Snooping Control */
+-/*
+- * Decoding Perf Capability Register
+- */
+-#define pcap_num_cntr(p)      ((p) & 0xffff)
+-#define pcap_cntr_width(p)    (((p) >> 16) & 0x7f)
+-#define pcap_num_event_group(p)       (((p) >> 24) & 0x1f)
+-#define pcap_filters_mask(p)  (((p) >> 32) & 0x1f)
+-#define pcap_interrupt(p)     (((p) >> 50) & 0x1)
+-/* The counter stride is calculated as 2 ^ (x+10) bytes */
+-#define pcap_cntr_stride(p)   (1ULL << ((((p) >> 52) & 0x7) + 10))
+-
+-/*
+- * Decoding Perf Event Capability Register
+- */
+-#define pecap_es(p)           ((p) & 0xfffffff)
+-
+ /* Virtual command interface capability */
+ #define vccap_pasid(v)                (((v) & DMA_VCS_PAS)) /* PASID allocation */
+@@ -584,22 +561,6 @@ struct dmar_domain {
+                                          iommu core */
+ };
+-struct iommu_pmu {
+-      struct intel_iommu      *iommu;
+-      u32                     num_cntr;       /* Number of counters */
+-      u32                     num_eg;         /* Number of event group */
+-      u32                     cntr_width;     /* Counter width */
+-      u32                     cntr_stride;    /* Counter Stride */
+-      u32                     filter;         /* Bitmask of filter support */
+-      void __iomem            *base;          /* the PerfMon base address */
+-      void __iomem            *cfg_reg;       /* counter configuration base address */
+-      void __iomem            *cntr_reg;      /* counter 0 address*/
+-      void __iomem            *overflow;      /* overflow status register */
+-
+-      u64                     *evcap;         /* Indicates all supported events */
+-      u32                     **cntr_evcap;   /* Supported events of each counter. */
+-};
+-
+ struct intel_iommu {
+       void __iomem    *reg; /* Pointer to hardware regs, virtual addr */
+       u64             reg_phys; /* physical address of hw register set */
+@@ -647,8 +608,6 @@ struct intel_iommu {
+       struct dmar_drhd_unit *drhd;
+       void *perf_statistic;
+-
+-      struct iommu_pmu *pmu;
+ };
+ /* PCI domain-device relationship */
+--- a/drivers/iommu/intel/perfmon.c
++++ /dev/null
+@@ -1,172 +0,0 @@
+-// SPDX-License-Identifier: GPL-2.0-only
+-/*
+- * Support Intel IOMMU PerfMon
+- * Copyright(c) 2023 Intel Corporation.
+- */
+-#define pr_fmt(fmt)   "DMAR: " fmt
+-#define dev_fmt(fmt)  pr_fmt(fmt)
+-
+-#include <linux/dmar.h>
+-#include "iommu.h"
+-#include "perfmon.h"
+-
+-static inline void __iomem *
+-get_perf_reg_address(struct intel_iommu *iommu, u32 offset)
+-{
+-      u32 off = dmar_readl(iommu->reg + offset);
+-
+-      return iommu->reg + off;
+-}
+-
+-int alloc_iommu_pmu(struct intel_iommu *iommu)
+-{
+-      struct iommu_pmu *iommu_pmu;
+-      int i, j, ret;
+-      u64 perfcap;
+-      u32 cap;
+-
+-      if (!ecap_pms(iommu->ecap))
+-              return 0;
+-
+-      /* The IOMMU PMU requires the ECMD support as well */
+-      if (!cap_ecmds(iommu->cap))
+-              return -ENODEV;
+-
+-      perfcap = dmar_readq(iommu->reg + DMAR_PERFCAP_REG);
+-      /* The performance monitoring is not supported. */
+-      if (!perfcap)
+-              return -ENODEV;
+-
+-      /* Sanity check for the number of the counters and event groups */
+-      if (!pcap_num_cntr(perfcap) || !pcap_num_event_group(perfcap))
+-              return -ENODEV;
+-
+-      /* The interrupt on overflow is required */
+-      if (!pcap_interrupt(perfcap))
+-              return -ENODEV;
+-
+-      iommu_pmu = kzalloc(sizeof(*iommu_pmu), GFP_KERNEL);
+-      if (!iommu_pmu)
+-              return -ENOMEM;
+-
+-      iommu_pmu->num_cntr = pcap_num_cntr(perfcap);
+-      iommu_pmu->cntr_width = pcap_cntr_width(perfcap);
+-      iommu_pmu->filter = pcap_filters_mask(perfcap);
+-      iommu_pmu->cntr_stride = pcap_cntr_stride(perfcap);
+-      iommu_pmu->num_eg = pcap_num_event_group(perfcap);
+-
+-      iommu_pmu->evcap = kcalloc(iommu_pmu->num_eg, sizeof(u64), GFP_KERNEL);
+-      if (!iommu_pmu->evcap) {
+-              ret = -ENOMEM;
+-              goto free_pmu;
+-      }
+-
+-      /* Parse event group capabilities */
+-      for (i = 0; i < iommu_pmu->num_eg; i++) {
+-              u64 pcap;
+-
+-              pcap = dmar_readq(iommu->reg + DMAR_PERFEVNTCAP_REG +
+-                                i * IOMMU_PMU_CAP_REGS_STEP);
+-              iommu_pmu->evcap[i] = pecap_es(pcap);
+-      }
+-
+-      iommu_pmu->cntr_evcap = kcalloc(iommu_pmu->num_cntr, sizeof(u32 *), GFP_KERNEL);
+-      if (!iommu_pmu->cntr_evcap) {
+-              ret = -ENOMEM;
+-              goto free_pmu_evcap;
+-      }
+-      for (i = 0; i < iommu_pmu->num_cntr; i++) {
+-              iommu_pmu->cntr_evcap[i] = kcalloc(iommu_pmu->num_eg, sizeof(u32), GFP_KERNEL);
+-              if (!iommu_pmu->cntr_evcap[i]) {
+-                      ret = -ENOMEM;
+-                      goto free_pmu_cntr_evcap;
+-              }
+-              /*
+-               * Set to the global capabilities, will adjust according
+-               * to per-counter capabilities later.
+-               */
+-              for (j = 0; j < iommu_pmu->num_eg; j++)
+-                      iommu_pmu->cntr_evcap[i][j] = (u32)iommu_pmu->evcap[j];
+-      }
+-
+-      iommu_pmu->cfg_reg = get_perf_reg_address(iommu, DMAR_PERFCFGOFF_REG);
+-      iommu_pmu->cntr_reg = get_perf_reg_address(iommu, DMAR_PERFCNTROFF_REG);
+-      iommu_pmu->overflow = get_perf_reg_address(iommu, DMAR_PERFOVFOFF_REG);
+-
+-      /*
+-       * Check per-counter capabilities. All counters should have the
+-       * same capabilities on Interrupt on Overflow Support and Counter
+-       * Width.
+-       */
+-      for (i = 0; i < iommu_pmu->num_cntr; i++) {
+-              cap = dmar_readl(iommu_pmu->cfg_reg +
+-                               i * IOMMU_PMU_CFG_OFFSET +
+-                               IOMMU_PMU_CFG_CNTRCAP_OFFSET);
+-              if (!iommu_cntrcap_pcc(cap))
+-                      continue;
+-
+-              /*
+-               * It's possible that some counters have a different
+-               * capability because of e.g., HW bug. Check the corner
+-               * case here and simply drop those counters.
+-               */
+-              if ((iommu_cntrcap_cw(cap) != iommu_pmu->cntr_width) ||
+-                  !iommu_cntrcap_ios(cap)) {
+-                      iommu_pmu->num_cntr = i;
+-                      pr_warn("PMU counter capability inconsistent, counter number reduced to %d\n",
+-                              iommu_pmu->num_cntr);
+-              }
+-
+-              /* Clear the pre-defined events group */
+-              for (j = 0; j < iommu_pmu->num_eg; j++)
+-                      iommu_pmu->cntr_evcap[i][j] = 0;
+-
+-              /* Override with per-counter event capabilities */
+-              for (j = 0; j < iommu_cntrcap_egcnt(cap); j++) {
+-                      cap = dmar_readl(iommu_pmu->cfg_reg + i * IOMMU_PMU_CFG_OFFSET +
+-                                       IOMMU_PMU_CFG_CNTREVCAP_OFFSET +
+-                                       (j * IOMMU_PMU_OFF_REGS_STEP));
+-                      iommu_pmu->cntr_evcap[i][iommu_event_group(cap)] = iommu_event_select(cap);
+-                      /*
+-                       * Some events may only be supported by a specific counter.
+-                       * Track them in the evcap as well.
+-                       */
+-                      iommu_pmu->evcap[iommu_event_group(cap)] |= iommu_event_select(cap);
+-              }
+-      }
+-
+-      iommu_pmu->iommu = iommu;
+-      iommu->pmu = iommu_pmu;
+-
+-      return 0;
+-
+-free_pmu_cntr_evcap:
+-      for (i = 0; i < iommu_pmu->num_cntr; i++)
+-              kfree(iommu_pmu->cntr_evcap[i]);
+-      kfree(iommu_pmu->cntr_evcap);
+-free_pmu_evcap:
+-      kfree(iommu_pmu->evcap);
+-free_pmu:
+-      kfree(iommu_pmu);
+-
+-      return ret;
+-}
+-
+-void free_iommu_pmu(struct intel_iommu *iommu)
+-{
+-      struct iommu_pmu *iommu_pmu = iommu->pmu;
+-
+-      if (!iommu_pmu)
+-              return;
+-
+-      if (iommu_pmu->evcap) {
+-              int i;
+-
+-              for (i = 0; i < iommu_pmu->num_cntr; i++)
+-                      kfree(iommu_pmu->cntr_evcap[i]);
+-              kfree(iommu_pmu->cntr_evcap);
+-      }
+-      kfree(iommu_pmu->evcap);
+-      kfree(iommu_pmu);
+-      iommu->pmu = NULL;
+-}
+--- a/drivers/iommu/intel/perfmon.h
++++ /dev/null
+@@ -1,40 +0,0 @@
+-/* SPDX-License-Identifier: GPL-2.0 */
+-
+-/*
+- * PERFCFGOFF_REG, PERFFRZOFF_REG
+- * PERFOVFOFF_REG, PERFCNTROFF_REG
+- */
+-#define IOMMU_PMU_NUM_OFF_REGS                        4
+-#define IOMMU_PMU_OFF_REGS_STEP                       4
+-
+-#define IOMMU_PMU_CFG_OFFSET                  0x100
+-#define IOMMU_PMU_CFG_CNTRCAP_OFFSET          0x80
+-#define IOMMU_PMU_CFG_CNTREVCAP_OFFSET                0x84
+-#define IOMMU_PMU_CFG_SIZE                    0x8
+-#define IOMMU_PMU_CFG_FILTERS_OFFSET          0x4
+-
+-#define IOMMU_PMU_CAP_REGS_STEP                       8
+-
+-#define iommu_cntrcap_pcc(p)                  ((p) & 0x1)
+-#define iommu_cntrcap_cw(p)                   (((p) >> 8) & 0xff)
+-#define iommu_cntrcap_ios(p)                  (((p) >> 16) & 0x1)
+-#define iommu_cntrcap_egcnt(p)                        (((p) >> 28) & 0xf)
+-
+-#define iommu_event_select(p)                 ((p) & 0xfffffff)
+-#define iommu_event_group(p)                  (((p) >> 28) & 0xf)
+-
+-#ifdef CONFIG_INTEL_IOMMU_PERF_EVENTS
+-int alloc_iommu_pmu(struct intel_iommu *iommu);
+-void free_iommu_pmu(struct intel_iommu *iommu);
+-#else
+-static inline int
+-alloc_iommu_pmu(struct intel_iommu *iommu)
+-{
+-      return 0;
+-}
+-
+-static inline void
+-free_iommu_pmu(struct intel_iommu *iommu)
+-{
+-}
+-#endif /* CONFIG_INTEL_IOMMU_PERF_EVENTS */
index dbbfb90a343aac44ad1e2e53d37cd87532e2d025..820af86e3d4a37648f380f0e8830270436b8cf1f 100644 (file)
@@ -795,3 +795,4 @@ secretmem-disable-memfd_secret-if-arch-cannot-set-direct-map.patch
 net-ethernet-cortina-restore-tso-support.patch
 perf-lock-don-t-pass-an-err_ptr-directly-to-perf_session__delete.patch
 block-bfq-fix-uaf-for-accessing-waker_bfqq-after-splitting.patch
+revert-iommu-vt-d-retrieve-iommu-perfmon-capability-information.patch