--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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
+
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
--- /dev/null
+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
+
--- /dev/null
+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
+