From: Sasha Levin Date: Mon, 29 Apr 2024 01:53:52 +0000 (-0400) Subject: Fixes for 6.8 X-Git-Tag: v6.1.89~8 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=66547bf7eb9515c16fea66a5d799a6ee2d13073c;p=thirdparty%2Fkernel%2Fstable-queue.git Fixes for 6.8 Signed-off-by: Sasha Levin --- 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 index 00000000000..c04202dab38 --- /dev/null +++ b/queue-6.8/drm-add-drm_gem_object_is_shared_for_memory_stats-he.patch @@ -0,0 +1,59 @@ +From d9c801ad20b4d1b705fe38b1ca35dea9556afa1b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 (v1) +Signed-off-by: Alex Deucher +Reviewed-by: Christian König +Signed-off-by: Christian König +Stable-dep-of: a6ff969fe9cb ("drm/amdgpu: fix visible VRAM handling during faults") +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..c6033bb467e --- /dev/null +++ b/queue-6.8/drm-amd-display-check-dp-alt-mode-dpcs-state-via-dmu.patch @@ -0,0 +1,185 @@ +From ed7b01af92635117899f64d730fa4313f71c5ee7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 6 Feb 2024 16:08:49 -0500 +Subject: drm/amd/display: Check DP Alt mode DPCS state via DMUB + +From: George Shen + +[ 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 +Acked-by: Rodrigo Siqueira +Tested-by: Daniel Wheeler +Signed-off-by: George Shen +Signed-off-by: Alex Deucher +Stable-dep-of: 91f10a3d21f2 ("Revert "drm/amd/display: fix USB-C flag update after enc10 feature init"") +Signed-off-by: Sasha Levin +--- + .../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 index 00000000000..de6b0706121 --- /dev/null +++ b/queue-6.8/drm-amdgpu-add-shared-fdinfo-stats.patch @@ -0,0 +1,112 @@ +From 6406341d33b2e7d252fc66a4acfa89afc58d1b71 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Cc: Rob Clark +Reviewed-by: Christian König +Signed-off-by: Christian König +Stable-dep-of: a6ff969fe9cb ("drm/amdgpu: fix visible VRAM handling during faults") +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..3a455584b87 --- /dev/null +++ b/queue-6.8/drm-amdgpu-fix-visible-vram-handling-during-faults.patch @@ -0,0 +1,283 @@ +From ae56a2096a6856572c355353867f3beb317a1916 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Fixes: aed01a68047b ("drm/amdgpu: Remove TTM resource->start visible VRAM condition v2") +Reviewed-by: Alex Deucher +Signed-off-by: Alex Deucher +CC: stable@vger.kernel.org +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..6f7951a61f0 --- /dev/null +++ b/queue-6.8/kvm-x86-pmu-set-enable-bits-for-gp-counters-in-perf_.patch @@ -0,0 +1,135 @@ +From ded52e5c57148ed18f624fd16882dc2821cec9cf Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Cc: Sandipan Das +Cc: Like Xu +Cc: Mingwei Zhang +Cc: Dapeng Mi +Cc: stable@vger.kernel.org +Reviewed-by: Dapeng Mi +Tested-by: Dapeng Mi +Link: https://lore.kernel.org/r/20240309013641.1413400-2-seanjc@google.com +Signed-off-by: Sean Christopherson +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..aa771a70558 --- /dev/null +++ b/queue-6.8/kvm-x86-pmu-zero-out-pmu-metadata-on-amd-if-pmu-is-d.patch @@ -0,0 +1,109 @@ +From 6d2709c88a3a728025bd1be7a69873024c6790dc Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +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 +Stable-dep-of: de120e1d692d ("KVM: x86/pmu: Set enable bits for GP counters in PERF_GLOBAL_CTRL at "RESET"") +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..f097ba147d9 --- /dev/null +++ b/queue-6.8/revert-drm-amd-display-fix-usb-c-flag-update-after-e.patch @@ -0,0 +1,76 @@ +From 23b1811dd76d33e6e69d417cdff830f70dbb1951 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Signed-off-by: Alex Deucher +Cc: Muhammad Ahmed +Cc: Tom Chung +Cc: Charlene Liu +Cc: Hamza Mahfooz +Cc: Harry Wentland +Cc: stable@vger.kernel.org +Signed-off-by: Sasha Levin +--- + .../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 + diff --git a/queue-6.8/series b/queue-6.8/series index 012e2fba611..265541a188c 100644 --- a/queue-6.8/series +++ b/queue-6.8/series @@ -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 index 00000000000..648350102bb --- /dev/null +++ b/queue-6.8/usb-xhci-correct-return-value-in-case-of-sts_hce.patch @@ -0,0 +1,72 @@ +From de0d344473a2caa16715e8b8b3d1b0241ecc5800 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 4 Apr 2024 15:11:05 +0300 +Subject: usb: xhci: correct return value in case of STS_HCE + +From: Oliver Neukum + +[ 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 +Signed-off-by: Mathias Nyman +Link: https://lore.kernel.org/r/20240404121106.2842417-2-mathias.nyman@linux.intel.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + 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 index 00000000000..0a89ec1b526 --- /dev/null +++ b/queue-6.8/xhci-move-event-processing-for-one-interrupter-to-a-.patch @@ -0,0 +1,144 @@ +From a48cb7d64ed88bb3eacb9bd5485e7e432d173896 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 16 Feb 2024 16:09:32 -0800 +Subject: xhci: move event processing for one interrupter to a separate + function + +From: Mathias Nyman + +[ 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 +Signed-off-by: Wesley Cheng +Link: https://lore.kernel.org/r/20240217001017.29969-7-quic_wcheng@quicinc.com +Signed-off-by: Greg Kroah-Hartman +Stable-dep-of: 5bfc311dd6c3 ("usb: xhci: correct return value in case of STS_HCE") +Signed-off-by: Sasha Levin +--- + 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 +