]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
Fixes for 6.8
authorSasha Levin <sashal@kernel.org>
Mon, 29 Apr 2024 01:53:52 +0000 (21:53 -0400)
committerSasha Levin <sashal@kernel.org>
Mon, 29 Apr 2024 01:53:52 +0000 (21:53 -0400)
Signed-off-by: Sasha Levin <sashal@kernel.org>
queue-6.8/drm-add-drm_gem_object_is_shared_for_memory_stats-he.patch [new file with mode: 0644]
queue-6.8/drm-amd-display-check-dp-alt-mode-dpcs-state-via-dmu.patch [new file with mode: 0644]
queue-6.8/drm-amdgpu-add-shared-fdinfo-stats.patch [new file with mode: 0644]
queue-6.8/drm-amdgpu-fix-visible-vram-handling-during-faults.patch [new file with mode: 0644]
queue-6.8/kvm-x86-pmu-set-enable-bits-for-gp-counters-in-perf_.patch [new file with mode: 0644]
queue-6.8/kvm-x86-pmu-zero-out-pmu-metadata-on-amd-if-pmu-is-d.patch [new file with mode: 0644]
queue-6.8/revert-drm-amd-display-fix-usb-c-flag-update-after-e.patch [new file with mode: 0644]
queue-6.8/series
queue-6.8/usb-xhci-correct-return-value-in-case-of-sts_hce.patch [new file with mode: 0644]
queue-6.8/xhci-move-event-processing-for-one-interrupter-to-a-.patch [new file with mode: 0644]

diff --git a/queue-6.8/drm-add-drm_gem_object_is_shared_for_memory_stats-he.patch b/queue-6.8/drm-add-drm_gem_object_is_shared_for_memory_stats-he.patch
new file mode 100644 (file)
index 0000000..c04202d
--- /dev/null
@@ -0,0 +1,59 @@
+From d9c801ad20b4d1b705fe38b1ca35dea9556afa1b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 12 Feb 2024 16:04:24 -0500
+Subject: drm: add drm_gem_object_is_shared_for_memory_stats() helper
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Alex Deucher <alexander.deucher@amd.com>
+
+[ Upstream commit b31f5eba32ae8cc28e7cfa5a55ec8670d8c718e2 ]
+
+Add a helper so that drm drivers can consistently report
+shared status via the fdinfo shared memory stats interface.
+
+In addition to handle count, show buffers as shared if they
+are shared via dma-buf as well (e.g., shared with v4l or some
+other subsystem).
+
+v2: switch to inline function
+
+Link: https://lore.kernel.org/all/20231207180225.439482-1-alexander.deucher@amd.com/
+Reviewed-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com> (v1)
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Reviewed-by: Christian König <christian.keonig@amd.com>
+Signed-off-by: Christian König <christian.koenig@amd.com>
+Stable-dep-of: a6ff969fe9cb ("drm/amdgpu: fix visible VRAM handling during faults")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/drm/drm_gem.h | 13 +++++++++++++
+ 1 file changed, 13 insertions(+)
+
+diff --git a/include/drm/drm_gem.h b/include/drm/drm_gem.h
+index 369505447acd8..2ebec3984cd44 100644
+--- a/include/drm/drm_gem.h
++++ b/include/drm/drm_gem.h
+@@ -553,6 +553,19 @@ unsigned long drm_gem_lru_scan(struct drm_gem_lru *lru,
+ int drm_gem_evict(struct drm_gem_object *obj);
++/**
++ * drm_gem_object_is_shared_for_memory_stats - helper for shared memory stats
++ *
++ * This helper should only be used for fdinfo shared memory stats to determine
++ * if a GEM object is shared.
++ *
++ * @obj: obj in question
++ */
++static inline bool drm_gem_object_is_shared_for_memory_stats(struct drm_gem_object *obj)
++{
++      return (obj->handle_count > 1) || obj->dma_buf;
++}
++
+ #ifdef CONFIG_LOCKDEP
+ /**
+  * drm_gem_gpuva_set_lock() - Set the lock protecting accesses to the gpuva list.
+-- 
+2.43.0
+
diff --git a/queue-6.8/drm-amd-display-check-dp-alt-mode-dpcs-state-via-dmu.patch b/queue-6.8/drm-amd-display-check-dp-alt-mode-dpcs-state-via-dmu.patch
new file mode 100644 (file)
index 0000000..c6033bb
--- /dev/null
@@ -0,0 +1,185 @@
+From ed7b01af92635117899f64d730fa4313f71c5ee7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 6 Feb 2024 16:08:49 -0500
+Subject: drm/amd/display: Check DP Alt mode DPCS state via DMUB
+
+From: George Shen <george.shen@amd.com>
+
+[ Upstream commit 7d1e9d0369e4d45738d4b905c3ec92f76d7f91e6 ]
+
+[Why]
+Currently, driver state for DCN3.2 is not strictly matching HW state for
+the USBC port. To reduce inconsistencies while debugging, the driver
+should match HW configuration.
+
+[How]
+Update link encoder flag to indicate USBC port. Call into DMUB to check
+when DP Alt mode is entered, and also to check for 2-lane versuse 4-lane
+mode.
+
+Reviewed-by: Charlene Liu <charlene.liu@amd.com>
+Acked-by: Rodrigo Siqueira <rodrigo.siqueira@amd.com>
+Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
+Signed-off-by: George Shen <george.shen@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Stable-dep-of: 91f10a3d21f2 ("Revert "drm/amd/display: fix USB-C flag update after enc10 feature init"")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../display/dc/dcn32/dcn32_dio_link_encoder.c | 85 ++++++++++++++-----
+ .../display/dc/dcn32/dcn32_dio_link_encoder.h |  5 ++
+ 2 files changed, 71 insertions(+), 19 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dio_link_encoder.c b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dio_link_encoder.c
+index d761b0df28784..e224a028d68ac 100644
+--- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dio_link_encoder.c
++++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dio_link_encoder.c
+@@ -34,6 +34,7 @@
+ #include "dc_bios_types.h"
+ #include "link_enc_cfg.h"
++#include "dc_dmub_srv.h"
+ #include "gpio_service_interface.h"
+ #ifndef MIN
+@@ -61,6 +62,38 @@
+ #define AUX_REG_WRITE(reg_name, val) \
+                       dm_write_reg(CTX, AUX_REG(reg_name), val)
++static uint8_t phy_id_from_transmitter(enum transmitter t)
++{
++      uint8_t phy_id;
++
++      switch (t) {
++      case TRANSMITTER_UNIPHY_A:
++              phy_id = 0;
++              break;
++      case TRANSMITTER_UNIPHY_B:
++              phy_id = 1;
++              break;
++      case TRANSMITTER_UNIPHY_C:
++              phy_id = 2;
++              break;
++      case TRANSMITTER_UNIPHY_D:
++              phy_id = 3;
++              break;
++      case TRANSMITTER_UNIPHY_E:
++              phy_id = 4;
++              break;
++      case TRANSMITTER_UNIPHY_F:
++              phy_id = 5;
++              break;
++      case TRANSMITTER_UNIPHY_G:
++              phy_id = 6;
++              break;
++      default:
++              phy_id = 0;
++              break;
++      }
++      return phy_id;
++}
+ void enc32_hw_init(struct link_encoder *enc)
+ {
+@@ -117,38 +150,50 @@ void dcn32_link_encoder_enable_dp_output(
+       }
+ }
+-static bool dcn32_link_encoder_is_in_alt_mode(struct link_encoder *enc)
++static bool query_dp_alt_from_dmub(struct link_encoder *enc,
++      union dmub_rb_cmd *cmd)
+ {
+       struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc);
+-      uint32_t dp_alt_mode_disable = 0;
+-      bool is_usb_c_alt_mode = false;
+-      if (enc->features.flags.bits.DP_IS_USB_C) {
+-              /* if value == 1 alt mode is disabled, otherwise it is enabled */
+-              REG_GET(RDPCSPIPE_PHY_CNTL6, RDPCS_PHY_DPALT_DISABLE, &dp_alt_mode_disable);
+-              is_usb_c_alt_mode = (dp_alt_mode_disable == 0);
+-      }
++      memset(cmd, 0, sizeof(*cmd));
++      cmd->query_dp_alt.header.type = DMUB_CMD__VBIOS;
++      cmd->query_dp_alt.header.sub_type =
++              DMUB_CMD__VBIOS_TRANSMITTER_QUERY_DP_ALT;
++      cmd->query_dp_alt.header.payload_bytes = sizeof(cmd->query_dp_alt.data);
++      cmd->query_dp_alt.data.phy_id = phy_id_from_transmitter(enc10->base.transmitter);
++
++      if (!dc_wake_and_execute_dmub_cmd(enc->ctx, cmd, DM_DMUB_WAIT_TYPE_WAIT_WITH_REPLY))
++              return false;
+-      return is_usb_c_alt_mode;
++      return true;
+ }
+-static void dcn32_link_encoder_get_max_link_cap(struct link_encoder *enc,
++bool dcn32_link_encoder_is_in_alt_mode(struct link_encoder *enc)
++{
++      union dmub_rb_cmd cmd;
++
++      if (!query_dp_alt_from_dmub(enc, &cmd))
++              return false;
++
++      return (cmd.query_dp_alt.data.is_dp_alt_disable == 0);
++}
++
++void dcn32_link_encoder_get_max_link_cap(struct link_encoder *enc,
+       struct dc_link_settings *link_settings)
+ {
+-      struct dcn10_link_encoder *enc10 = TO_DCN10_LINK_ENC(enc);
+-      uint32_t is_in_usb_c_dp4_mode = 0;
++      union dmub_rb_cmd cmd;
+       dcn10_link_encoder_get_max_link_cap(enc, link_settings);
+-      /* in usb c dp2 mode, max lane count is 2 */
+-      if (enc->funcs->is_in_alt_mode && enc->funcs->is_in_alt_mode(enc)) {
+-              REG_GET(RDPCSPIPE_PHY_CNTL6, RDPCS_PHY_DPALT_DP4, &is_in_usb_c_dp4_mode);
+-              if (!is_in_usb_c_dp4_mode)
+-                      link_settings->lane_count = MIN(LANE_COUNT_TWO, link_settings->lane_count);
+-      }
++      if (!query_dp_alt_from_dmub(enc, &cmd))
++              return;
++      if (cmd.query_dp_alt.data.is_usb &&
++                      cmd.query_dp_alt.data.is_dp4 == 0)
++              link_settings->lane_count = MIN(LANE_COUNT_TWO, link_settings->lane_count);
+ }
++
+ static const struct link_encoder_funcs dcn32_link_enc_funcs = {
+       .read_state = link_enc2_read_state,
+       .validate_output_with_stream =
+@@ -203,13 +248,15 @@ void dcn32_link_encoder_construct(
+       enc10->base.hpd_source = init_data->hpd_source;
+       enc10->base.connector = init_data->connector;
+-
+       enc10->base.preferred_engine = ENGINE_ID_UNKNOWN;
+       enc10->base.features = *enc_features;
+       if (enc10->base.connector.id == CONNECTOR_ID_USBC)
+               enc10->base.features.flags.bits.DP_IS_USB_C = 1;
++      if (enc10->base.connector.id == CONNECTOR_ID_USBC)
++              enc10->base.features.flags.bits.DP_IS_USB_C = 1;
++
+       enc10->base.transmitter = init_data->transmitter;
+       /* set the flag to indicate whether driver poll the I2C data pin
+diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dio_link_encoder.h b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dio_link_encoder.h
+index bbcfce06bec01..2d5f25290ed14 100644
+--- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dio_link_encoder.h
++++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dio_link_encoder.h
+@@ -53,4 +53,9 @@ void dcn32_link_encoder_enable_dp_output(
+       const struct dc_link_settings *link_settings,
+       enum clock_source_id clock_source);
++bool dcn32_link_encoder_is_in_alt_mode(struct link_encoder *enc);
++
++void dcn32_link_encoder_get_max_link_cap(struct link_encoder *enc,
++      struct dc_link_settings *link_settings);
++
+ #endif /* __DC_LINK_ENCODER__DCN32_H__ */
+-- 
+2.43.0
+
diff --git a/queue-6.8/drm-amdgpu-add-shared-fdinfo-stats.patch b/queue-6.8/drm-amdgpu-add-shared-fdinfo-stats.patch
new file mode 100644 (file)
index 0000000..de6b070
--- /dev/null
@@ -0,0 +1,112 @@
+From 6406341d33b2e7d252fc66a4acfa89afc58d1b71 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 12 Feb 2024 16:04:26 -0500
+Subject: drm/amdgpu: add shared fdinfo stats
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Alex Deucher <alexander.deucher@amd.com>
+
+[ Upstream commit ba1a58d5b907bdf1814f8f57434aebc86233430f ]
+
+Add shared stats.  Useful for seeing shared memory.
+
+v2: take dma-buf into account as well
+v3: use the new gem helper
+
+Link: https://lore.kernel.org/all/20231207180225.439482-1-alexander.deucher@amd.com/
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Cc: Rob Clark <robdclark@gmail.com>
+Reviewed-by: Christian König <christian.keonig@amd.com>
+Signed-off-by: Christian König <christian.koenig@amd.com>
+Stable-dep-of: a6ff969fe9cb ("drm/amdgpu: fix visible VRAM handling during faults")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/amdgpu/amdgpu_fdinfo.c |  4 ++++
+ drivers/gpu/drm/amd/amdgpu/amdgpu_object.c | 11 +++++++++++
+ drivers/gpu/drm/amd/amdgpu/amdgpu_object.h |  6 ++++++
+ 3 files changed, 21 insertions(+)
+
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_fdinfo.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_fdinfo.c
+index 5706b282a0c7e..c7df7fa3459f1 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_fdinfo.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_fdinfo.c
+@@ -97,6 +97,10 @@ void amdgpu_show_fdinfo(struct drm_printer *p, struct drm_file *file)
+                  stats.requested_visible_vram/1024UL);
+       drm_printf(p, "amd-requested-gtt:\t%llu KiB\n",
+                  stats.requested_gtt/1024UL);
++      drm_printf(p, "drm-shared-vram:\t%llu KiB\n", stats.vram_shared/1024UL);
++      drm_printf(p, "drm-shared-gtt:\t%llu KiB\n", stats.gtt_shared/1024UL);
++      drm_printf(p, "drm-shared-cpu:\t%llu KiB\n", stats.cpu_shared/1024UL);
++
+       for (hw_ip = 0; hw_ip < AMDGPU_HW_IP_NUM; ++hw_ip) {
+               if (!usage[hw_ip])
+                       continue;
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
+index 425cebcc5cbff..e6f69fce539b5 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
+@@ -1276,25 +1276,36 @@ void amdgpu_bo_get_memory(struct amdgpu_bo *bo,
+                         struct amdgpu_mem_stats *stats)
+ {
+       uint64_t size = amdgpu_bo_size(bo);
++      struct drm_gem_object *obj;
+       unsigned int domain;
++      bool shared;
+       /* Abort if the BO doesn't currently have a backing store */
+       if (!bo->tbo.resource)
+               return;
++      obj = &bo->tbo.base;
++      shared = drm_gem_object_is_shared_for_memory_stats(obj);
++
+       domain = amdgpu_mem_type_to_domain(bo->tbo.resource->mem_type);
+       switch (domain) {
+       case AMDGPU_GEM_DOMAIN_VRAM:
+               stats->vram += size;
+               if (amdgpu_bo_in_cpu_visible_vram(bo))
+                       stats->visible_vram += size;
++              if (shared)
++                      stats->vram_shared += size;
+               break;
+       case AMDGPU_GEM_DOMAIN_GTT:
+               stats->gtt += size;
++              if (shared)
++                      stats->gtt_shared += size;
+               break;
+       case AMDGPU_GEM_DOMAIN_CPU:
+       default:
+               stats->cpu += size;
++              if (shared)
++                      stats->cpu_shared += size;
+               break;
+       }
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h
+index a3ea8a82db23a..be679c42b0b8c 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h
+@@ -138,12 +138,18 @@ struct amdgpu_bo_vm {
+ struct amdgpu_mem_stats {
+       /* current VRAM usage, includes visible VRAM */
+       uint64_t vram;
++      /* current shared VRAM usage, includes visible VRAM */
++      uint64_t vram_shared;
+       /* current visible VRAM usage */
+       uint64_t visible_vram;
+       /* current GTT usage */
+       uint64_t gtt;
++      /* current shared GTT usage */
++      uint64_t gtt_shared;
+       /* current system memory usage */
+       uint64_t cpu;
++      /* current shared system memory usage */
++      uint64_t cpu_shared;
+       /* sum of evicted buffers, includes visible VRAM */
+       uint64_t evicted_vram;
+       /* sum of evicted buffers due to CPU access */
+-- 
+2.43.0
+
diff --git a/queue-6.8/drm-amdgpu-fix-visible-vram-handling-during-faults.patch b/queue-6.8/drm-amdgpu-fix-visible-vram-handling-during-faults.patch
new file mode 100644 (file)
index 0000000..3a45558
--- /dev/null
@@ -0,0 +1,283 @@
+From ae56a2096a6856572c355353867f3beb317a1916 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 4 Apr 2024 16:25:40 +0200
+Subject: drm/amdgpu: fix visible VRAM handling during faults
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Christian König <christian.koenig@amd.com>
+
+[ Upstream commit a6ff969fe9cbf369e3cd0ac54261fec1122682ec ]
+
+When we removed the hacky start code check we actually didn't took into
+account that *all* VRAM pages needs to be CPU accessible.
+
+Clean up the code and unify the handling into a single helper which
+checks if the whole resource is CPU accessible.
+
+The only place where a partial check would make sense is during
+eviction, but that is neglitible.
+
+Signed-off-by: Christian König <christian.koenig@amd.com>
+Fixes: aed01a68047b ("drm/amdgpu: Remove TTM resource->start visible VRAM condition v2")
+Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+CC: stable@vger.kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c     |  2 +-
+ drivers/gpu/drm/amd/amdgpu/amdgpu_object.c | 22 ++++----
+ drivers/gpu/drm/amd/amdgpu/amdgpu_object.h | 22 --------
+ drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c    | 61 ++++++++++++++--------
+ drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h    |  3 ++
+ 5 files changed, 53 insertions(+), 57 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
+index 6adeddfb3d564..116d3756c9c35 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
+@@ -819,7 +819,7 @@ static int amdgpu_cs_bo_validate(void *param, struct amdgpu_bo *bo)
+       p->bytes_moved += ctx.bytes_moved;
+       if (!amdgpu_gmc_vram_full_visible(&adev->gmc) &&
+-          amdgpu_bo_in_cpu_visible_vram(bo))
++          amdgpu_res_cpu_visible(adev, bo->tbo.resource))
+               p->bytes_moved_vis += ctx.bytes_moved;
+       if (unlikely(r == -ENOMEM) && domain != bo->allowed_domains) {
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
+index e6f69fce539b5..866bfde1ca6f9 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
+@@ -620,8 +620,7 @@ int amdgpu_bo_create(struct amdgpu_device *adev,
+               return r;
+       if (!amdgpu_gmc_vram_full_visible(&adev->gmc) &&
+-          bo->tbo.resource->mem_type == TTM_PL_VRAM &&
+-          amdgpu_bo_in_cpu_visible_vram(bo))
++          amdgpu_res_cpu_visible(adev, bo->tbo.resource))
+               amdgpu_cs_report_moved_bytes(adev, ctx.bytes_moved,
+                                            ctx.bytes_moved);
+       else
+@@ -1275,23 +1274,25 @@ void amdgpu_bo_move_notify(struct ttm_buffer_object *bo, bool evict)
+ void amdgpu_bo_get_memory(struct amdgpu_bo *bo,
+                         struct amdgpu_mem_stats *stats)
+ {
++      struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev);
++      struct ttm_resource *res = bo->tbo.resource;
+       uint64_t size = amdgpu_bo_size(bo);
+       struct drm_gem_object *obj;
+       unsigned int domain;
+       bool shared;
+       /* Abort if the BO doesn't currently have a backing store */
+-      if (!bo->tbo.resource)
++      if (!res)
+               return;
+       obj = &bo->tbo.base;
+       shared = drm_gem_object_is_shared_for_memory_stats(obj);
+-      domain = amdgpu_mem_type_to_domain(bo->tbo.resource->mem_type);
++      domain = amdgpu_mem_type_to_domain(res->mem_type);
+       switch (domain) {
+       case AMDGPU_GEM_DOMAIN_VRAM:
+               stats->vram += size;
+-              if (amdgpu_bo_in_cpu_visible_vram(bo))
++              if (amdgpu_res_cpu_visible(adev, bo->tbo.resource))
+                       stats->visible_vram += size;
+               if (shared)
+                       stats->vram_shared += size;
+@@ -1392,10 +1393,7 @@ vm_fault_t amdgpu_bo_fault_reserve_notify(struct ttm_buffer_object *bo)
+       /* Remember that this BO was accessed by the CPU */
+       abo->flags |= AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED;
+-      if (bo->resource->mem_type != TTM_PL_VRAM)
+-              return 0;
+-
+-      if (amdgpu_bo_in_cpu_visible_vram(abo))
++      if (amdgpu_res_cpu_visible(adev, bo->resource))
+               return 0;
+       /* Can't move a pinned BO to visible VRAM */
+@@ -1419,7 +1417,7 @@ vm_fault_t amdgpu_bo_fault_reserve_notify(struct ttm_buffer_object *bo)
+       /* this should never happen */
+       if (bo->resource->mem_type == TTM_PL_VRAM &&
+-          !amdgpu_bo_in_cpu_visible_vram(abo))
++          !amdgpu_res_cpu_visible(adev, bo->resource))
+               return VM_FAULT_SIGBUS;
+       ttm_bo_move_to_lru_tail_unlocked(bo);
+@@ -1583,6 +1581,7 @@ uint32_t amdgpu_bo_get_preferred_domain(struct amdgpu_device *adev,
+  */
+ u64 amdgpu_bo_print_info(int id, struct amdgpu_bo *bo, struct seq_file *m)
+ {
++      struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev);
+       struct dma_buf_attachment *attachment;
+       struct dma_buf *dma_buf;
+       const char *placement;
+@@ -1591,10 +1590,11 @@ u64 amdgpu_bo_print_info(int id, struct amdgpu_bo *bo, struct seq_file *m)
+       if (dma_resv_trylock(bo->tbo.base.resv)) {
+               unsigned int domain;
++
+               domain = amdgpu_mem_type_to_domain(bo->tbo.resource->mem_type);
+               switch (domain) {
+               case AMDGPU_GEM_DOMAIN_VRAM:
+-                      if (amdgpu_bo_in_cpu_visible_vram(bo))
++                      if (amdgpu_res_cpu_visible(adev, bo->tbo.resource))
+                               placement = "VRAM VISIBLE";
+                       else
+                               placement = "VRAM";
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h
+index be679c42b0b8c..fa03d9e4874cc 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h
+@@ -250,28 +250,6 @@ static inline u64 amdgpu_bo_mmap_offset(struct amdgpu_bo *bo)
+       return drm_vma_node_offset_addr(&bo->tbo.base.vma_node);
+ }
+-/**
+- * amdgpu_bo_in_cpu_visible_vram - check if BO is (partly) in visible VRAM
+- */
+-static inline bool amdgpu_bo_in_cpu_visible_vram(struct amdgpu_bo *bo)
+-{
+-      struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev);
+-      struct amdgpu_res_cursor cursor;
+-
+-      if (!bo->tbo.resource || bo->tbo.resource->mem_type != TTM_PL_VRAM)
+-              return false;
+-
+-      amdgpu_res_first(bo->tbo.resource, 0, amdgpu_bo_size(bo), &cursor);
+-      while (cursor.remaining) {
+-              if (cursor.start < adev->gmc.visible_vram_size)
+-                      return true;
+-
+-              amdgpu_res_next(&cursor, cursor.size);
+-      }
+-
+-      return false;
+-}
+-
+ /**
+  * amdgpu_bo_explicit_sync - return whether the bo is explicitly synced
+  */
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
+index a5ceec7820cfa..851509c6e90eb 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
+@@ -137,7 +137,7 @@ static void amdgpu_evict_flags(struct ttm_buffer_object *bo,
+                       amdgpu_bo_placement_from_domain(abo, AMDGPU_GEM_DOMAIN_CPU);
+               } else if (!amdgpu_gmc_vram_full_visible(&adev->gmc) &&
+                          !(abo->flags & AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED) &&
+-                         amdgpu_bo_in_cpu_visible_vram(abo)) {
++                         amdgpu_res_cpu_visible(adev, bo->resource)) {
+                       /* Try evicting to the CPU inaccessible part of VRAM
+                        * first, but only set GTT as busy placement, so this
+@@ -408,40 +408,55 @@ static int amdgpu_move_blit(struct ttm_buffer_object *bo,
+       return r;
+ }
+-/*
+- * amdgpu_mem_visible - Check that memory can be accessed by ttm_bo_move_memcpy
++/**
++ * amdgpu_res_cpu_visible - Check that resource can be accessed by CPU
++ * @adev: amdgpu device
++ * @res: the resource to check
+  *
+- * Called by amdgpu_bo_move()
++ * Returns: true if the full resource is CPU visible, false otherwise.
+  */
+-static bool amdgpu_mem_visible(struct amdgpu_device *adev,
+-                             struct ttm_resource *mem)
++bool amdgpu_res_cpu_visible(struct amdgpu_device *adev,
++                          struct ttm_resource *res)
+ {
+-      u64 mem_size = (u64)mem->size;
+       struct amdgpu_res_cursor cursor;
+-      u64 end;
+-      if (mem->mem_type == TTM_PL_SYSTEM ||
+-          mem->mem_type == TTM_PL_TT)
++      if (!res)
++              return false;
++
++      if (res->mem_type == TTM_PL_SYSTEM || res->mem_type == TTM_PL_TT ||
++          res->mem_type == AMDGPU_PL_PREEMPT)
+               return true;
+-      if (mem->mem_type != TTM_PL_VRAM)
++
++      if (res->mem_type != TTM_PL_VRAM)
+               return false;
+-      amdgpu_res_first(mem, 0, mem_size, &cursor);
+-      end = cursor.start + cursor.size;
++      amdgpu_res_first(res, 0, res->size, &cursor);
+       while (cursor.remaining) {
++              if ((cursor.start + cursor.size) >= adev->gmc.visible_vram_size)
++                      return false;
+               amdgpu_res_next(&cursor, cursor.size);
++      }
+-              if (!cursor.remaining)
+-                      break;
++      return true;
++}
+-              /* ttm_resource_ioremap only supports contiguous memory */
+-              if (end != cursor.start)
+-                      return false;
++/*
++ * amdgpu_res_copyable - Check that memory can be accessed by ttm_bo_move_memcpy
++ *
++ * Called by amdgpu_bo_move()
++ */
++static bool amdgpu_res_copyable(struct amdgpu_device *adev,
++                              struct ttm_resource *mem)
++{
++      if (!amdgpu_res_cpu_visible(adev, mem))
++              return false;
+-              end = cursor.start + cursor.size;
+-      }
++      /* ttm_resource_ioremap only supports contiguous memory */
++      if (mem->mem_type == TTM_PL_VRAM &&
++          !(mem->placement & TTM_PL_FLAG_CONTIGUOUS))
++              return false;
+-      return end <= adev->gmc.visible_vram_size;
++      return true;
+ }
+ /*
+@@ -534,8 +549,8 @@ static int amdgpu_bo_move(struct ttm_buffer_object *bo, bool evict,
+       if (r) {
+               /* Check that all memory is CPU accessible */
+-              if (!amdgpu_mem_visible(adev, old_mem) ||
+-                  !amdgpu_mem_visible(adev, new_mem)) {
++              if (!amdgpu_res_copyable(adev, old_mem) ||
++                  !amdgpu_res_copyable(adev, new_mem)) {
+                       pr_err("Move buffer fallback to memcpy unavailable\n");
+                       return r;
+               }
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h
+index 65ec82141a8e0..32cf6b6f6efd9 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h
+@@ -139,6 +139,9 @@ int amdgpu_vram_mgr_reserve_range(struct amdgpu_vram_mgr *mgr,
+ int amdgpu_vram_mgr_query_page_status(struct amdgpu_vram_mgr *mgr,
+                                     uint64_t start);
++bool amdgpu_res_cpu_visible(struct amdgpu_device *adev,
++                          struct ttm_resource *res);
++
+ int amdgpu_ttm_init(struct amdgpu_device *adev);
+ void amdgpu_ttm_fini(struct amdgpu_device *adev);
+ void amdgpu_ttm_set_buffer_funcs_status(struct amdgpu_device *adev,
+-- 
+2.43.0
+
diff --git a/queue-6.8/kvm-x86-pmu-set-enable-bits-for-gp-counters-in-perf_.patch b/queue-6.8/kvm-x86-pmu-set-enable-bits-for-gp-counters-in-perf_.patch
new file mode 100644 (file)
index 0000000..6f7951a
--- /dev/null
@@ -0,0 +1,135 @@
+From ded52e5c57148ed18f624fd16882dc2821cec9cf Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 8 Mar 2024 17:36:40 -0800
+Subject: KVM: x86/pmu: Set enable bits for GP counters in PERF_GLOBAL_CTRL at
+ "RESET"
+
+From: Sean Christopherson <seanjc@google.com>
+
+[ Upstream commit de120e1d692d73c7eefa3278837b1eb68f90728a ]
+
+Set the enable bits for general purpose counters in IA32_PERF_GLOBAL_CTRL
+when refreshing the PMU to emulate the MSR's architecturally defined
+post-RESET behavior.  Per Intel's SDM:
+
+  IA32_PERF_GLOBAL_CTRL:  Sets bits n-1:0 and clears the upper bits.
+
+and
+
+  Where "n" is the number of general-purpose counters available in the processor.
+
+AMD also documents this behavior for PerfMonV2 CPUs in one of AMD's many
+PPRs.
+
+Do not set any PERF_GLOBAL_CTRL bits if there are no general purpose
+counters, although a literal reading of the SDM would require the CPU to
+set either bits 63:0 or 31:0.  The intent of the behavior is to globally
+enable all GP counters; honor the intent, if not the letter of the law.
+
+Leaving PERF_GLOBAL_CTRL '0' effectively breaks PMU usage in guests that
+haven't been updated to work with PMUs that support PERF_GLOBAL_CTRL.
+This bug was recently exposed when KVM added supported for AMD's
+PerfMonV2, i.e. when KVM started exposing a vPMU with PERF_GLOBAL_CTRL to
+guest software that only knew how to program v1 PMUs (that don't support
+PERF_GLOBAL_CTRL).
+
+Failure to emulate the post-RESET behavior results in such guests
+unknowingly leaving all general purpose counters globally disabled (the
+entire reason the post-RESET value sets the GP counter enable bits is to
+maintain backwards compatibility).
+
+The bug has likely gone unnoticed because PERF_GLOBAL_CTRL has been
+supported on Intel CPUs for as long as KVM has existed, i.e. hardly anyone
+is running guest software that isn't aware of PERF_GLOBAL_CTRL on Intel
+PMUs.  And because up until v6.0, KVM _did_ emulate the behavior for Intel
+CPUs, although the old behavior was likely dumb luck.
+
+Because (a) that old code was also broken in its own way (the history of
+this code is a comedy of errors), and (b) PERF_GLOBAL_CTRL was documented
+as having a value of '0' post-RESET in all SDMs before March 2023.
+
+Initial vPMU support in commit f5132b01386b ("KVM: Expose a version 2
+architectural PMU to a guests") *almost* got it right (again likely by
+dumb luck), but for some reason only set the bits if the guest PMU was
+advertised as v1:
+
+        if (pmu->version == 1) {
+                pmu->global_ctrl = (1 << pmu->nr_arch_gp_counters) - 1;
+                return;
+        }
+
+Commit f19a0c2c2e6a ("KVM: PMU emulation: GLOBAL_CTRL MSR should be
+enabled on reset") then tried to remedy that goof, presumably because
+guest PMUs were leaving PERF_GLOBAL_CTRL '0', i.e. weren't enabling
+counters.
+
+        pmu->global_ctrl = ((1 << pmu->nr_arch_gp_counters) - 1) |
+                (((1ull << pmu->nr_arch_fixed_counters) - 1) << X86_PMC_IDX_FIXED);
+        pmu->global_ctrl_mask = ~pmu->global_ctrl;
+
+That was KVM's behavior up until commit c49467a45fe0 ("KVM: x86/pmu:
+Don't overwrite the pmu->global_ctrl when refreshing") removed
+*everything*.  However, it did so based on the behavior defined by the
+SDM , which at the time stated that "Global Perf Counter Controls" is
+'0' at Power-Up and RESET.
+
+But then the March 2023 SDM (325462-079US), stealthily changed its
+"IA-32 and Intel 64 Processor States Following Power-up, Reset, or INIT"
+table to say:
+
+  IA32_PERF_GLOBAL_CTRL: Sets bits n-1:0 and clears the upper bits.
+
+Note, kvm_pmu_refresh() can be invoked multiple times, i.e. it's not a
+"pure" RESET flow.  But it can only be called prior to the first KVM_RUN,
+i.e. the guest will only ever observe the final value.
+
+Note #2, KVM has always cleared global_ctrl during refresh (see commit
+f5132b01386b ("KVM: Expose a version 2 architectural PMU to a guests")),
+i.e. there is no danger of breaking existing setups by clobbering a value
+set by userspace.
+
+Reported-by: Babu Moger <babu.moger@amd.com>
+Cc: Sandipan Das <sandipan.das@amd.com>
+Cc: Like Xu <like.xu.linux@gmail.com>
+Cc: Mingwei Zhang <mizhang@google.com>
+Cc: Dapeng Mi <dapeng1.mi@linux.intel.com>
+Cc: stable@vger.kernel.org
+Reviewed-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
+Tested-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
+Link: https://lore.kernel.org/r/20240309013641.1413400-2-seanjc@google.com
+Signed-off-by: Sean Christopherson <seanjc@google.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/kvm/pmu.c | 16 ++++++++++++++--
+ 1 file changed, 14 insertions(+), 2 deletions(-)
+
+diff --git a/arch/x86/kvm/pmu.c b/arch/x86/kvm/pmu.c
+index 38512954ec267..2ab2d5213f52f 100644
+--- a/arch/x86/kvm/pmu.c
++++ b/arch/x86/kvm/pmu.c
+@@ -766,8 +766,20 @@ void kvm_pmu_refresh(struct kvm_vcpu *vcpu)
+       pmu->pebs_data_cfg_mask = ~0ull;
+       bitmap_zero(pmu->all_valid_pmc_idx, X86_PMC_IDX_MAX);
+-      if (vcpu->kvm->arch.enable_pmu)
+-              static_call(kvm_x86_pmu_refresh)(vcpu);
++      if (!vcpu->kvm->arch.enable_pmu)
++              return;
++
++      static_call(kvm_x86_pmu_refresh)(vcpu);
++
++      /*
++       * At RESET, both Intel and AMD CPUs set all enable bits for general
++       * purpose counters in IA32_PERF_GLOBAL_CTRL (so that software that
++       * was written for v1 PMUs don't unknowingly leave GP counters disabled
++       * in the global controls).  Emulate that behavior when refreshing the
++       * PMU so that userspace doesn't need to manually set PERF_GLOBAL_CTRL.
++       */
++      if (kvm_pmu_has_perf_global_ctrl(pmu) && pmu->nr_arch_gp_counters)
++              pmu->global_ctrl = GENMASK_ULL(pmu->nr_arch_gp_counters - 1, 0);
+ }
+ void kvm_pmu_init(struct kvm_vcpu *vcpu)
+-- 
+2.43.0
+
diff --git a/queue-6.8/kvm-x86-pmu-zero-out-pmu-metadata-on-amd-if-pmu-is-d.patch b/queue-6.8/kvm-x86-pmu-zero-out-pmu-metadata-on-amd-if-pmu-is-d.patch
new file mode 100644 (file)
index 0000000..aa771a7
--- /dev/null
@@ -0,0 +1,109 @@
+From 6d2709c88a3a728025bd1be7a69873024c6790dc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 9 Nov 2023 18:28:48 -0800
+Subject: KVM: x86/pmu: Zero out PMU metadata on AMD if PMU is disabled
+
+From: Sean Christopherson <seanjc@google.com>
+
+[ Upstream commit f933b88e20150f15787390e2a1754a7e412754ed ]
+
+Move the purging of common PMU metadata from intel_pmu_refresh() to
+kvm_pmu_refresh(), and invoke the vendor refresh() hook if and only if
+the VM is supposed to have a vPMU.
+
+KVM already denies access to the PMU based on kvm->arch.enable_pmu, as
+get_gp_pmc_amd() returns NULL for all PMCs in that case, i.e. KVM already
+violates AMD's architecture by not virtualizing a PMU (kernels have long
+since learned to not panic when the PMU is unavailable).  But configuring
+the PMU as if it were enabled causes unwanted side effects, e.g. calls to
+kvm_pmu_trigger_event() waste an absurd number of cycles due to the
+all_valid_pmc_idx bitmap being non-zero.
+
+Fixes: b1d66dad65dc ("KVM: x86/svm: Add module param to control PMU virtualization")
+Reported-by: Konstantin Khorenko <khorenko@virtuozzo.com>
+Closes: https://lore.kernel.org/all/20231109180646.2963718-2-khorenko@virtuozzo.com
+Link: https://lore.kernel.org/r/20231110022857.1273836-2-seanjc@google.com
+Signed-off-by: Sean Christopherson <seanjc@google.com>
+Stable-dep-of: de120e1d692d ("KVM: x86/pmu: Set enable bits for GP counters in PERF_GLOBAL_CTRL at "RESET"")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/kvm/pmu.c           | 20 ++++++++++++++++++--
+ arch/x86/kvm/vmx/pmu_intel.c | 16 ++--------------
+ 2 files changed, 20 insertions(+), 16 deletions(-)
+
+diff --git a/arch/x86/kvm/pmu.c b/arch/x86/kvm/pmu.c
+index 87cc6c8809ad8..38512954ec267 100644
+--- a/arch/x86/kvm/pmu.c
++++ b/arch/x86/kvm/pmu.c
+@@ -741,6 +741,8 @@ static void kvm_pmu_reset(struct kvm_vcpu *vcpu)
+  */
+ void kvm_pmu_refresh(struct kvm_vcpu *vcpu)
+ {
++      struct kvm_pmu *pmu = vcpu_to_pmu(vcpu);
++
+       if (KVM_BUG_ON(kvm_vcpu_has_run(vcpu), vcpu->kvm))
+               return;
+@@ -750,8 +752,22 @@ void kvm_pmu_refresh(struct kvm_vcpu *vcpu)
+        */
+       kvm_pmu_reset(vcpu);
+-      bitmap_zero(vcpu_to_pmu(vcpu)->all_valid_pmc_idx, X86_PMC_IDX_MAX);
+-      static_call(kvm_x86_pmu_refresh)(vcpu);
++      pmu->version = 0;
++      pmu->nr_arch_gp_counters = 0;
++      pmu->nr_arch_fixed_counters = 0;
++      pmu->counter_bitmask[KVM_PMC_GP] = 0;
++      pmu->counter_bitmask[KVM_PMC_FIXED] = 0;
++      pmu->reserved_bits = 0xffffffff00200000ull;
++      pmu->raw_event_mask = X86_RAW_EVENT_MASK;
++      pmu->global_ctrl_mask = ~0ull;
++      pmu->global_status_mask = ~0ull;
++      pmu->fixed_ctr_ctrl_mask = ~0ull;
++      pmu->pebs_enable_mask = ~0ull;
++      pmu->pebs_data_cfg_mask = ~0ull;
++      bitmap_zero(pmu->all_valid_pmc_idx, X86_PMC_IDX_MAX);
++
++      if (vcpu->kvm->arch.enable_pmu)
++              static_call(kvm_x86_pmu_refresh)(vcpu);
+ }
+ void kvm_pmu_init(struct kvm_vcpu *vcpu)
+diff --git a/arch/x86/kvm/vmx/pmu_intel.c b/arch/x86/kvm/vmx/pmu_intel.c
+index 315c7c2ba89b1..600a021ae958b 100644
+--- a/arch/x86/kvm/vmx/pmu_intel.c
++++ b/arch/x86/kvm/vmx/pmu_intel.c
+@@ -491,19 +491,6 @@ static void intel_pmu_refresh(struct kvm_vcpu *vcpu)
+       u64 counter_mask;
+       int i;
+-      pmu->nr_arch_gp_counters = 0;
+-      pmu->nr_arch_fixed_counters = 0;
+-      pmu->counter_bitmask[KVM_PMC_GP] = 0;
+-      pmu->counter_bitmask[KVM_PMC_FIXED] = 0;
+-      pmu->version = 0;
+-      pmu->reserved_bits = 0xffffffff00200000ull;
+-      pmu->raw_event_mask = X86_RAW_EVENT_MASK;
+-      pmu->global_ctrl_mask = ~0ull;
+-      pmu->global_status_mask = ~0ull;
+-      pmu->fixed_ctr_ctrl_mask = ~0ull;
+-      pmu->pebs_enable_mask = ~0ull;
+-      pmu->pebs_data_cfg_mask = ~0ull;
+-
+       memset(&lbr_desc->records, 0, sizeof(lbr_desc->records));
+       /*
+@@ -515,8 +502,9 @@ static void intel_pmu_refresh(struct kvm_vcpu *vcpu)
+               return;
+       entry = kvm_find_cpuid_entry(vcpu, 0xa);
+-      if (!entry || !vcpu->kvm->arch.enable_pmu)
++      if (!entry)
+               return;
++
+       eax.full = entry->eax;
+       edx.full = entry->edx;
+-- 
+2.43.0
+
diff --git a/queue-6.8/revert-drm-amd-display-fix-usb-c-flag-update-after-e.patch b/queue-6.8/revert-drm-amd-display-fix-usb-c-flag-update-after-e.patch
new file mode 100644 (file)
index 0000000..f097ba1
--- /dev/null
@@ -0,0 +1,76 @@
+From 23b1811dd76d33e6e69d417cdff830f70dbb1951 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 29 Mar 2024 18:03:03 -0400
+Subject: Revert "drm/amd/display: fix USB-C flag update after enc10 feature
+ init"
+
+From: Alex Deucher <alexander.deucher@amd.com>
+
+[ Upstream commit 91f10a3d21f2313485178d49efef8a3ba02bd8c7 ]
+
+This reverts commit b5abd7f983e14054593dc91d6df2aa5f8cc67652.
+
+This change breaks DSC on 4k monitors at 144Hz over USB-C.
+
+Closes: https://gitlab.freedesktop.org/drm/amd/-/issues/3254
+Reviewed-by: Harry Wentland <harry.wentland@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Cc: Muhammad Ahmed <ahmed.ahmed@amd.com>
+Cc: Tom Chung <chiahsuan.chung@amd.com>
+Cc: Charlene Liu <charlene.liu@amd.com>
+Cc: Hamza Mahfooz <hamza.mahfooz@amd.com>
+Cc: Harry Wentland <harry.wentland@amd.com>
+Cc: stable@vger.kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../gpu/drm/amd/display/dc/dcn32/dcn32_dio_link_encoder.c | 8 +++-----
+ .../gpu/drm/amd/display/dc/dcn35/dcn35_dio_link_encoder.c | 4 ++--
+ 2 files changed, 5 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dio_link_encoder.c b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dio_link_encoder.c
+index e224a028d68ac..8a0460e863097 100644
+--- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dio_link_encoder.c
++++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_dio_link_encoder.c
+@@ -248,14 +248,12 @@ void dcn32_link_encoder_construct(
+       enc10->base.hpd_source = init_data->hpd_source;
+       enc10->base.connector = init_data->connector;
+-      enc10->base.preferred_engine = ENGINE_ID_UNKNOWN;
+-
+-      enc10->base.features = *enc_features;
+       if (enc10->base.connector.id == CONNECTOR_ID_USBC)
+               enc10->base.features.flags.bits.DP_IS_USB_C = 1;
+-      if (enc10->base.connector.id == CONNECTOR_ID_USBC)
+-              enc10->base.features.flags.bits.DP_IS_USB_C = 1;
++      enc10->base.preferred_engine = ENGINE_ID_UNKNOWN;
++
++      enc10->base.features = *enc_features;
+       enc10->base.transmitter = init_data->transmitter;
+diff --git a/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_dio_link_encoder.c b/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_dio_link_encoder.c
+index 81e349d5835bb..da94e5309fbaf 100644
+--- a/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_dio_link_encoder.c
++++ b/drivers/gpu/drm/amd/display/dc/dcn35/dcn35_dio_link_encoder.c
+@@ -184,6 +184,8 @@ void dcn35_link_encoder_construct(
+       enc10->base.hpd_source = init_data->hpd_source;
+       enc10->base.connector = init_data->connector;
++      if (enc10->base.connector.id == CONNECTOR_ID_USBC)
++              enc10->base.features.flags.bits.DP_IS_USB_C = 1;
+       enc10->base.preferred_engine = ENGINE_ID_UNKNOWN;
+@@ -238,8 +240,6 @@ void dcn35_link_encoder_construct(
+       }
+       enc10->base.features.flags.bits.HDMI_6GB_EN = 1;
+-      if (enc10->base.connector.id == CONNECTOR_ID_USBC)
+-              enc10->base.features.flags.bits.DP_IS_USB_C = 1;
+       if (bp_funcs->get_connector_speed_cap_info)
+               result = bp_funcs->get_connector_speed_cap_info(enc10->base.ctx->dc_bios,
+-- 
+2.43.0
+
index 012e2fba6114c2eb548cdb1579ede04408486f43..265541a188c27826145cfb1f316a251e5f8a5b3d 100644 (file)
@@ -117,3 +117,12 @@ dpll-fix-dpll_pin_on_pin_register-for-multiple-paren.patch
 tls-fix-lockless-read-of-strp-msg_ready-in-poll.patch
 af_unix-suppress-false-positive-lockdep-splat-for-sp.patch
 netfs-fix-the-pre-flush-when-appending-to-a-file-in-.patch
+drm-amd-display-check-dp-alt-mode-dpcs-state-via-dmu.patch
+revert-drm-amd-display-fix-usb-c-flag-update-after-e.patch
+xhci-move-event-processing-for-one-interrupter-to-a-.patch
+usb-xhci-correct-return-value-in-case-of-sts_hce.patch
+kvm-x86-pmu-zero-out-pmu-metadata-on-amd-if-pmu-is-d.patch
+kvm-x86-pmu-set-enable-bits-for-gp-counters-in-perf_.patch
+drm-add-drm_gem_object_is_shared_for_memory_stats-he.patch
+drm-amdgpu-add-shared-fdinfo-stats.patch
+drm-amdgpu-fix-visible-vram-handling-during-faults.patch
diff --git a/queue-6.8/usb-xhci-correct-return-value-in-case-of-sts_hce.patch b/queue-6.8/usb-xhci-correct-return-value-in-case-of-sts_hce.patch
new file mode 100644 (file)
index 0000000..6483501
--- /dev/null
@@ -0,0 +1,72 @@
+From de0d344473a2caa16715e8b8b3d1b0241ecc5800 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 4 Apr 2024 15:11:05 +0300
+Subject: usb: xhci: correct return value in case of STS_HCE
+
+From: Oliver Neukum <oneukum@suse.com>
+
+[ Upstream commit 5bfc311dd6c376d350b39028b9000ad766ddc934 ]
+
+If we get STS_HCE we give up on the interrupt, but for the purpose
+of IRQ handling that still counts as ours. We may return IRQ_NONE
+only if we are positive that it wasn't ours. Hence correct the default.
+
+Fixes: 2a25e66d676d ("xhci: print warning when HCE was set")
+Cc: stable@vger.kernel.org # v6.2+
+Signed-off-by: Oliver Neukum <oneukum@suse.com>
+Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
+Link: https://lore.kernel.org/r/20240404121106.2842417-2-mathias.nyman@linux.intel.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/host/xhci-ring.c | 9 ++++-----
+ 1 file changed, 4 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
+index 2306a95d6251a..b2868217de941 100644
+--- a/drivers/usb/host/xhci-ring.c
++++ b/drivers/usb/host/xhci-ring.c
+@@ -3123,7 +3123,7 @@ static int xhci_handle_events(struct xhci_hcd *xhci, struct xhci_interrupter *ir
+ irqreturn_t xhci_irq(struct usb_hcd *hcd)
+ {
+       struct xhci_hcd *xhci = hcd_to_xhci(hcd);
+-      irqreturn_t ret = IRQ_NONE;
++      irqreturn_t ret = IRQ_HANDLED;
+       u32 status;
+       spin_lock(&xhci->lock);
+@@ -3131,12 +3131,13 @@ irqreturn_t xhci_irq(struct usb_hcd *hcd)
+       status = readl(&xhci->op_regs->status);
+       if (status == ~(u32)0) {
+               xhci_hc_died(xhci);
+-              ret = IRQ_HANDLED;
+               goto out;
+       }
+-      if (!(status & STS_EINT))
++      if (!(status & STS_EINT)) {
++              ret = IRQ_NONE;
+               goto out;
++      }
+       if (status & STS_HCE) {
+               xhci_warn(xhci, "WARNING: Host Controller Error\n");
+@@ -3146,7 +3147,6 @@ irqreturn_t xhci_irq(struct usb_hcd *hcd)
+       if (status & STS_FATAL) {
+               xhci_warn(xhci, "WARNING: Host System Error\n");
+               xhci_halt(xhci);
+-              ret = IRQ_HANDLED;
+               goto out;
+       }
+@@ -3157,7 +3157,6 @@ irqreturn_t xhci_irq(struct usb_hcd *hcd)
+        */
+       status |= STS_EINT;
+       writel(status, &xhci->op_regs->status);
+-      ret = IRQ_HANDLED;
+       /* This is the handler of the primary interrupter */
+       xhci_handle_events(xhci, xhci->interrupters[0]);
+-- 
+2.43.0
+
diff --git a/queue-6.8/xhci-move-event-processing-for-one-interrupter-to-a-.patch b/queue-6.8/xhci-move-event-processing-for-one-interrupter-to-a-.patch
new file mode 100644 (file)
index 0000000..0a89ec1
--- /dev/null
@@ -0,0 +1,144 @@
+From a48cb7d64ed88bb3eacb9bd5485e7e432d173896 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 16 Feb 2024 16:09:32 -0800
+Subject: xhci: move event processing for one interrupter to a separate
+ function
+
+From: Mathias Nyman <mathias.nyman@linux.intel.com>
+
+[ Upstream commit 84ac5e4fa517f5d1da0054547a82ce905678dc08 ]
+
+Split the main XHCI interrupt handler into a different API, so that other
+potential interrupters can utilize similar event ring handling.  A scenario
+would be if a secondary interrupter required to skip pending events in the
+event ring, which would warrant a similar set of operations.
+
+Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
+Signed-off-by: Wesley Cheng <quic_wcheng@quicinc.com>
+Link: https://lore.kernel.org/r/20240217001017.29969-7-quic_wcheng@quicinc.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Stable-dep-of: 5bfc311dd6c3 ("usb: xhci: correct return value in case of STS_HCE")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/usb/host/xhci-ring.c | 87 +++++++++++++++++-------------------
+ 1 file changed, 42 insertions(+), 45 deletions(-)
+
+diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
+index 61bd29dd71a2f..2306a95d6251a 100644
+--- a/drivers/usb/host/xhci-ring.c
++++ b/drivers/usb/host/xhci-ring.c
+@@ -3075,6 +3075,46 @@ static void xhci_clear_interrupt_pending(struct xhci_hcd *xhci,
+       }
+ }
++static int xhci_handle_events(struct xhci_hcd *xhci, struct xhci_interrupter *ir)
++{
++      int event_loop = 0;
++      u64 temp;
++
++      xhci_clear_interrupt_pending(xhci, ir);
++
++      if (xhci->xhc_state & XHCI_STATE_DYING ||
++          xhci->xhc_state & XHCI_STATE_HALTED) {
++              xhci_dbg(xhci, "xHCI dying, ignoring interrupt. Shouldn't IRQs be disabled?\n");
++
++              /* Clear the event handler busy flag (RW1C) */
++              temp = xhci_read_64(xhci, &ir->ir_set->erst_dequeue);
++              xhci_write_64(xhci, temp | ERST_EHB, &ir->ir_set->erst_dequeue);
++              return -ENODEV;
++      }
++
++      while (xhci_handle_event(xhci, ir) > 0) {
++              /*
++               * If half a segment of events have been handled in one go then
++               * update ERDP, and force isoc trbs to interrupt more often
++               */
++              if (event_loop++ > TRBS_PER_SEGMENT / 2) {
++                      xhci_update_erst_dequeue(xhci, ir, false);
++
++                      if (ir->isoc_bei_interval > AVOID_BEI_INTERVAL_MIN)
++                              ir->isoc_bei_interval = ir->isoc_bei_interval / 2;
++
++                      event_loop = 0;
++              }
++
++              /* Update SW event ring dequeue pointer */
++              inc_deq(xhci, ir->event_ring);
++      }
++
++      xhci_update_erst_dequeue(xhci, ir, true);
++
++      return 0;
++}
++
+ /*
+  * xHCI spec says we can get an interrupt, and if the HC has an error condition,
+  * we might get bad data out of the event ring.  Section 4.10.2.7 has a list of
+@@ -3083,11 +3123,8 @@ static void xhci_clear_interrupt_pending(struct xhci_hcd *xhci,
+ irqreturn_t xhci_irq(struct usb_hcd *hcd)
+ {
+       struct xhci_hcd *xhci = hcd_to_xhci(hcd);
+-      struct xhci_interrupter *ir;
+       irqreturn_t ret = IRQ_NONE;
+-      u64 temp_64;
+       u32 status;
+-      int event_loop = 0;
+       spin_lock(&xhci->lock);
+       /* Check if the xHC generated the interrupt, or the irq is shared */
+@@ -3120,50 +3157,10 @@ irqreturn_t xhci_irq(struct usb_hcd *hcd)
+        */
+       status |= STS_EINT;
+       writel(status, &xhci->op_regs->status);
+-
+-      /* This is the handler of the primary interrupter */
+-      ir = xhci->interrupters[0];
+-
+-      xhci_clear_interrupt_pending(xhci, ir);
+-
+-      if (xhci->xhc_state & XHCI_STATE_DYING ||
+-          xhci->xhc_state & XHCI_STATE_HALTED) {
+-              xhci_dbg(xhci, "xHCI dying, ignoring interrupt. "
+-                              "Shouldn't IRQs be disabled?\n");
+-              /* Clear the event handler busy flag (RW1C);
+-               * the event ring should be empty.
+-               */
+-              temp_64 = xhci_read_64(xhci, &ir->ir_set->erst_dequeue);
+-              xhci_write_64(xhci, temp_64 | ERST_EHB,
+-                              &ir->ir_set->erst_dequeue);
+-              ret = IRQ_HANDLED;
+-              goto out;
+-      }
+-
+-      /* FIXME this should be a delayed service routine
+-       * that clears the EHB.
+-       */
+-      while (xhci_handle_event(xhci, ir) > 0) {
+-              /*
+-               * If half a segment of events have been handled in one go then
+-               * update ERDP, and force isoc trbs to interrupt more often
+-               */
+-              if (event_loop++ > TRBS_PER_SEGMENT / 2) {
+-                      xhci_update_erst_dequeue(xhci, ir, false);
+-
+-                      if (ir->isoc_bei_interval > AVOID_BEI_INTERVAL_MIN)
+-                              ir->isoc_bei_interval = ir->isoc_bei_interval / 2;
+-
+-                      event_loop = 0;
+-              }
+-
+-              /* Update SW event ring dequeue pointer */
+-              inc_deq(xhci, ir->event_ring);
+-      }
+-
+-      xhci_update_erst_dequeue(xhci, ir, true);
+       ret = IRQ_HANDLED;
++      /* This is the handler of the primary interrupter */
++      xhci_handle_events(xhci, xhci->interrupters[0]);
+ out:
+       spin_unlock(&xhci->lock);
+-- 
+2.43.0
+