diff options
| author | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2026-07-24 16:17:26 +0200 |
|---|---|---|
| committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2026-07-24 16:17:26 +0200 |
| commit | b62ed4c93ad71374b54d2c3a72cbc67b506f580c (patch) | |
| tree | 6ca6ab974bbce902fc9de300fea6aa056170850f /drivers/gpu/drm | |
| parent | 5895db67c12464003afd16c08049b73aa09e58ea (diff) | |
| parent | 221fc2f4d0eda59d02af2e751a9282fa013a8e97 (diff) | |
Merge v6.18.40linux-rolling-lts
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/gpu/drm')
54 files changed, 389 insertions, 227 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c index 0ab85d0a6a43..285c35545ebb 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c @@ -1896,13 +1896,6 @@ int amdgpu_amdkfd_gpuvm_free_memory_of_gpu( mutex_lock(&mem->lock); - /* Unpin MMIO/DOORBELL BO's that were pinned during allocation */ - if (mem->alloc_flags & - (KFD_IOC_ALLOC_MEM_FLAGS_DOORBELL | - KFD_IOC_ALLOC_MEM_FLAGS_MMIO_REMAP)) { - amdgpu_amdkfd_gpuvm_unpin_bo(mem->bo); - } - mapped_to_gpu_memory = mem->mapped_to_gpu_memory; is_imported = mem->is_imported; mutex_unlock(&mem->lock); @@ -1916,6 +1909,15 @@ int amdgpu_amdkfd_gpuvm_free_memory_of_gpu( return -EBUSY; } + /* At this point the BO is guaranteed to be freed, so unpin the + * MMIO/DOORBELL BOs that were pinned during allocation. + */ + if (mem->alloc_flags & + (KFD_IOC_ALLOC_MEM_FLAGS_DOORBELL | + KFD_IOC_ALLOC_MEM_FLAGS_MMIO_REMAP)) { + amdgpu_amdkfd_gpuvm_unpin_bo(mem->bo); + } + /* Make sure restore workers don't access the BO any more */ mutex_lock(&process_info->lock); list_del(&mem->validate_list); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index c22aea46efcd..d0cb300cd382 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -1736,7 +1736,9 @@ int amdgpu_device_resize_fb_bar(struct amdgpu_device *adev) pci_release_resource(adev->pdev, 0); - r = pci_resize_resource(adev->pdev, 0, rbar_size); + r = pci_resize_resource(adev->pdev, 0, rbar_size, + (adev->asic_type >= CHIP_BONAIRE) ? 1 << 5 + : 1 << 2); if (r == -ENOSPC) dev_info(adev->dev, "Not enough PCI address space for a large BAR."); @@ -4504,6 +4506,8 @@ int amdgpu_device_init(struct amdgpu_device *adev, mutex_init(&adev->vcn.workload_profile_mutex); mutex_init(&adev->userq_mutex); + spin_lock_init(&adev->irq.lock); + amdgpu_device_init_apu_flags(adev); r = amdgpu_device_check_arguments(adev); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c index 1bc1233487a0..cd52ddd27c58 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c @@ -27,6 +27,7 @@ */ #include <linux/ktime.h> #include <linux/module.h> +#include <linux/overflow.h> #include <linux/pagemap.h> #include <linux/pci.h> #include <linux/dma-buf.h> @@ -1209,13 +1210,14 @@ int amdgpu_gem_list_handles_ioctl(struct drm_device *dev, void *data, return ret; } -static int amdgpu_gem_align_pitch(struct amdgpu_device *adev, - int width, - int cpp, - bool tiled) +static unsigned int amdgpu_gem_align_pitch(struct amdgpu_device *adev, + unsigned int width, + unsigned int cpp, + bool tiled) { - int aligned = width; - int pitch_mask = 0; + unsigned int aligned = width; + unsigned int pitch_mask = 0; + unsigned int pitch; switch (cpp) { case 1: @@ -1230,9 +1232,12 @@ static int amdgpu_gem_align_pitch(struct amdgpu_device *adev, break; } - aligned += pitch_mask; + if (check_add_overflow(aligned, pitch_mask, &aligned)) + return 0; aligned &= ~pitch_mask; - return aligned * cpp; + if (check_mul_overflow(aligned, cpp, &pitch)) + return 0; + return pitch; } int amdgpu_mode_dumb_create(struct drm_file *file_priv, @@ -1259,8 +1264,12 @@ int amdgpu_mode_dumb_create(struct drm_file *file_priv, args->pitch = amdgpu_gem_align_pitch(adev, args->width, DIV_ROUND_UP(args->bpp, 8), 0); + if (!args->pitch) + return -EINVAL; args->size = (u64)args->pitch * args->height; args->size = ALIGN(args->size, PAGE_SIZE); + if (!args->size) + return -EINVAL; domain = amdgpu_bo_get_preferred_domain(adev, amdgpu_display_supported_domains(adev, flags)); r = amdgpu_gem_object_create(adev, args->size, 0, domain, flags, diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c index 8112ffc85995..8d7f97eed5a9 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c @@ -274,8 +274,6 @@ int amdgpu_irq_init(struct amdgpu_device *adev) unsigned int irq, flags; int r; - spin_lock_init(&adev->irq.lock); - /* Enable MSI if not disabled by module parameter */ adev->irq.msi_enabled = false; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mca.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_mca.c index 3ca03b5e0f91..e1e4a61b1301 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mca.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mca.c @@ -99,6 +99,7 @@ int amdgpu_mca_mp0_ras_sw_init(struct amdgpu_device *adev) strcpy(ras->ras_block.ras_comm.name, "mca.mp0"); ras->ras_block.ras_comm.block = AMDGPU_RAS_BLOCK__MCA; + ras->ras_block.ras_comm.sub_block_index = AMDGPU_RAS_MCA_BLOCK__MP0; ras->ras_block.ras_comm.type = AMDGPU_RAS_ERROR__MULTI_UNCORRECTABLE; adev->mca.mp0.ras_if = &ras->ras_block.ras_comm; @@ -123,6 +124,7 @@ int amdgpu_mca_mp1_ras_sw_init(struct amdgpu_device *adev) strcpy(ras->ras_block.ras_comm.name, "mca.mp1"); ras->ras_block.ras_comm.block = AMDGPU_RAS_BLOCK__MCA; + ras->ras_block.ras_comm.sub_block_index = AMDGPU_RAS_MCA_BLOCK__MP1; ras->ras_block.ras_comm.type = AMDGPU_RAS_ERROR__MULTI_UNCORRECTABLE; adev->mca.mp1.ras_if = &ras->ras_block.ras_comm; @@ -147,6 +149,7 @@ int amdgpu_mca_mpio_ras_sw_init(struct amdgpu_device *adev) strcpy(ras->ras_block.ras_comm.name, "mca.mpio"); ras->ras_block.ras_comm.block = AMDGPU_RAS_BLOCK__MCA; + ras->ras_block.ras_comm.sub_block_index = AMDGPU_RAS_MCA_BLOCK__MPIO; ras->ras_block.ras_comm.type = AMDGPU_RAS_ERROR__MULTI_UNCORRECTABLE; adev->mca.mpio.ras_if = &ras->ras_block.ras_comm; diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c index 09ebfe8a3062..c2100fd78b52 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c @@ -2315,6 +2315,9 @@ static int criu_restore_memory_of_gpu(struct kfd_process_device *pdd, const bool criu_resume = true; u64 offset; + if (bo_priv->idr_handle > INT_MAX) + return -EINVAL; + if (bo_bucket->alloc_flags & KFD_IOC_ALLOC_MEM_FLAGS_DOORBELL) { if (bo_bucket->size != kfd_doorbell_process_slice(pdd->dev->kfd)) diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c index fa183a9db09b..18d03f33c620 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c @@ -3073,32 +3073,24 @@ int kfd_dqm_suspend_bad_queue_mes(struct kfd_node *knode, u32 pasid, u32 doorbel list_for_each_entry(q, &qpd->queues_list, list) { if (q->doorbell_id == doorbell_id && q->properties.is_active) { - ret = suspend_all_queues_mes(dqm); - if (ret) { - dev_err(dev, "Suspending all queues failed"); - goto out; - } + /* suspend all queues will save any good queues and mark the rest as bad */ + suspend_all_queues_mes(dqm); q->properties.is_evicted = true; q->properties.is_active = false; decrement_queue_count(dqm, qpd, q); + /* this will remove the bad queue and sched a GPU reset if needed */ ret = remove_queue_mes(dqm, q, qpd); - if (ret) { - dev_err(dev, "Removing bad queue failed"); - goto out; - } - - ret = resume_all_queues_mes(dqm); if (ret) - dev_err(dev, "Resuming all queues failed"); - + dev_err(dev, "Removing bad queue failed"); + /* resume the good queues */ + resume_all_queues_mes(dqm); break; } } } -out: dqm_unlock(dqm); kfd_unref_process(p); return ret; diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_events.c b/drivers/gpu/drm/amd/amdkfd/kfd_events.c index 261db87e86fe..63039035b194 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_events.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_events.c @@ -480,6 +480,11 @@ int kfd_criu_restore_event(struct file *devkfd, } *priv_data_offset += sizeof(*ev_priv); + if (ev_priv->event_id > INT_MAX) { + ret = -EINVAL; + goto exit; + } + if (ev_priv->user_handle) { ret = kfd_kmap_event_page(p, ev_priv->user_handle); if (ret) diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_svm.c b/drivers/gpu/drm/amd/amdkfd/kfd_svm.c index 04e4bf41ccf7..202ed1c45632 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_svm.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_svm.c @@ -4063,6 +4063,7 @@ exit: list_for_each_entry_safe(criu_svm_md, next, &svms->criu_svm_metadata_list, list) { pr_debug("freeing criu_svm_md[]\n\tstart: 0x%llx\n", criu_svm_md->data.start_addr); + list_del(&criu_svm_md->list); kfree(criu_svm_md); } diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index ae10e8365ae1..a2ca1de6b43c 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -12177,13 +12177,11 @@ static bool amdgpu_dm_crtc_mem_type_changed(struct drm_device *dev, struct drm_plane_state *new_plane_state, *old_plane_state; drm_for_each_plane_mask(plane, dev, crtc_state->plane_mask) { - new_plane_state = drm_atomic_get_plane_state(state, plane); - old_plane_state = drm_atomic_get_plane_state(state, plane); + new_plane_state = drm_atomic_get_new_plane_state(state, plane); + old_plane_state = drm_atomic_get_old_plane_state(state, plane); - if (IS_ERR(new_plane_state) || IS_ERR(old_plane_state)) { - drm_err(dev, "Failed to get plane state for plane %s\n", plane->name); - return false; - } + if (!old_plane_state || !new_plane_state) + continue; if (old_plane_state->fb && new_plane_state->fb && get_mem_type(old_plane_state->fb) != get_mem_type(new_plane_state->fb)) diff --git a/drivers/gpu/drm/amd/display/modules/info_packet/info_packet.c b/drivers/gpu/drm/amd/display/modules/info_packet/info_packet.c index b3d55cac3569..ae858a43c35f 100644 --- a/drivers/gpu/drm/amd/display/modules/info_packet/info_packet.c +++ b/drivers/gpu/drm/amd/display/modules/info_packet/info_packet.c @@ -447,6 +447,8 @@ void mod_build_vsc_infopacket(const struct dc_stream_state *stream, * * @stream: contains data we may need to construct VSIF (i.e. timing_3d_format, etc.) * @info_packet: output structure where to store VSIF + * @ALLMEnabled: indicates whether ALLM HF-VSIF should be generated + * @ALLMValue: ALLM bit value to advertise in HF-VSIF */ void mod_build_hf_vsif_infopacket(const struct dc_stream_state *stream, struct dc_info_packet *info_packet) diff --git a/drivers/gpu/drm/amd/pm/amdgpu_pm.c b/drivers/gpu/drm/amd/pm/amdgpu_pm.c index a7e6d7854b7b..0d72118a12b4 100644 --- a/drivers/gpu/drm/amd/pm/amdgpu_pm.c +++ b/drivers/gpu/drm/amd/pm/amdgpu_pm.c @@ -2463,12 +2463,12 @@ static ssize_t amdgpu_set_pm_policy_attr(struct device *dev, .dev_attr = __ATTR(_name, 0644, amdgpu_get_pm_policy_attr, \ amdgpu_set_pm_policy_attr), \ .id = PP_PM_POLICY_##_id, \ - }; + } #define AMDGPU_PM_POLICY_ATTR_VAR(_name) pm_policy_attr_##_name.dev_attr.attr -AMDGPU_PM_POLICY_ATTR(soc_pstate, SOC_PSTATE) -AMDGPU_PM_POLICY_ATTR(xgmi_plpd, XGMI_PLPD) +AMDGPU_PM_POLICY_ATTR(soc_pstate, SOC_PSTATE); +AMDGPU_PM_POLICY_ATTR(xgmi_plpd, XGMI_PLPD); static struct attribute *pm_policy_attrs[] = { &AMDGPU_PM_POLICY_ATTR_VAR(soc_pstate), diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c index e2e85345aa9a..046b5e86a787 100644 --- a/drivers/gpu/drm/drm_edid.c +++ b/drivers/gpu/drm/drm_edid.c @@ -7500,6 +7500,14 @@ static void drm_parse_tiled_block(struct drm_connector *connector, u8 num_v_tile, num_h_tile; struct drm_tile_group *tg; + /* tiled block payload per spec: cap 1 + topo 3 + size 4 + bezel 5 + id 9 = 22 */ + if (block->num_bytes < 22) { + drm_dbg_kms(connector->dev, + "[CONNECTOR:%d:%s] Unexpected tiled block size %u\n", + connector->base.id, connector->name, block->num_bytes); + return; + } + w = tile->tile_size[0] | tile->tile_size[1] << 8; h = tile->tile_size[2] | tile->tile_size[3] << 8; diff --git a/drivers/gpu/drm/drm_gpusvm.c b/drivers/gpu/drm/drm_gpusvm.c index 853ca57800d3..4cde5bf4aedd 100644 --- a/drivers/gpu/drm/drm_gpusvm.c +++ b/drivers/gpu/drm/drm_gpusvm.c @@ -944,6 +944,11 @@ drm_gpusvm_range_find_or_insert(struct drm_gpusvm *gpusvm, goto err_notifier_remove; } + if (vas->vm_flags & (VM_IO | VM_PFNMAP)) { + err = -EIO; + goto err_notifier_remove; + } + range = drm_gpusvm_range_find(notifier, fault_addr, fault_addr + 1); if (range) goto out_mmunlock; diff --git a/drivers/gpu/drm/drm_gpuvm.c b/drivers/gpu/drm/drm_gpuvm.c index af63f4d00315..5c8bf010cd96 100644 --- a/drivers/gpu/drm/drm_gpuvm.c +++ b/drivers/gpu/drm/drm_gpuvm.c @@ -25,6 +25,7 @@ * */ +#include <drm/drm_drv.h> #include <drm/drm_gpuvm.h> #include <linux/export.h> @@ -1089,6 +1090,7 @@ drm_gpuvm_init(struct drm_gpuvm *gpuvm, const char *name, gpuvm->drm = drm; gpuvm->r_obj = r_obj; + drm_dev_get(drm); drm_gem_object_get(r_obj); drm_gpuvm_warn_check_overflow(gpuvm, start_offset, range); @@ -1130,13 +1132,15 @@ static void drm_gpuvm_free(struct kref *kref) { struct drm_gpuvm *gpuvm = container_of(kref, struct drm_gpuvm, kref); + struct drm_device *drm = gpuvm->drm; drm_gpuvm_fini(gpuvm); - if (drm_WARN_ON(gpuvm->drm, !gpuvm->ops->vm_free)) + if (drm_WARN_ON(drm, !gpuvm->ops->vm_free)) return; gpuvm->ops->vm_free(gpuvm); + drm_dev_put(drm); } /** @@ -1289,6 +1293,9 @@ drm_gpuvm_prepare_range(struct drm_gpuvm *gpuvm, struct drm_exec *exec, drm_gpuvm_for_each_va_range(va, gpuvm, addr, end) { struct drm_gem_object *obj = va->gem.obj; + if (unlikely(!obj)) + continue; + ret = exec_prepare_obj(exec, obj, num_fences); if (ret) return ret; diff --git a/drivers/gpu/drm/drm_syncobj.c b/drivers/gpu/drm/drm_syncobj.c index 7eb2cdbc574a..c0cb7d79672d 100644 --- a/drivers/gpu/drm/drm_syncobj.c +++ b/drivers/gpu/drm/drm_syncobj.c @@ -442,13 +442,15 @@ int drm_syncobj_find_fence(struct drm_file *file_private, u64 timeout = nsecs_to_jiffies64(DRM_SYNCOBJ_WAIT_FOR_SUBMIT_TIMEOUT); int ret; - if (flags & ~DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT) - return -EINVAL; - if (!syncobj) return -ENOENT; - /* Waiting for userspace with locks help is illegal cause that can + if (flags & ~DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT) { + ret = -EINVAL; + goto out; + } + + /* Waiting for userspace with locks held is illegal cause that can * trivial deadlock with page faults for example. Make lockdep complain * about it early on. */ diff --git a/drivers/gpu/drm/hisilicon/hibmc/dp/dp_comm.h b/drivers/gpu/drm/hisilicon/hibmc/dp/dp_comm.h index f9ee7ebfec55..f53dac256ee0 100644 --- a/drivers/gpu/drm/hisilicon/hibmc/dp/dp_comm.h +++ b/drivers/gpu/drm/hisilicon/hibmc/dp/dp_comm.h @@ -69,5 +69,6 @@ int hibmc_dp_link_training(struct hibmc_dp_dev *dp); int hibmc_dp_serdes_init(struct hibmc_dp_dev *dp); int hibmc_dp_serdes_rate_switch(u8 rate, struct hibmc_dp_dev *dp); int hibmc_dp_serdes_set_tx_cfg(struct hibmc_dp_dev *dp, u8 train_set[HIBMC_DP_LANE_NUM_MAX]); +void hibmc_dp_update_caps(struct hibmc_dp_dev *dp); #endif diff --git a/drivers/gpu/drm/hisilicon/hibmc/dp/dp_hw.h b/drivers/gpu/drm/hisilicon/hibmc/dp/dp_hw.h index 31316fe1ea8d..0f3662d8737e 100644 --- a/drivers/gpu/drm/hisilicon/hibmc/dp/dp_hw.h +++ b/drivers/gpu/drm/hisilicon/hibmc/dp/dp_hw.h @@ -55,6 +55,7 @@ struct hibmc_dp { struct drm_dp_aux aux; struct hibmc_dp_cbar_cfg cfg; u32 irq_status; + int phys_status; }; int hibmc_dp_hw_init(struct hibmc_dp *dp); diff --git a/drivers/gpu/drm/hisilicon/hibmc/dp/dp_link.c b/drivers/gpu/drm/hisilicon/hibmc/dp/dp_link.c index 0726cb5b736e..8c53f16db516 100644 --- a/drivers/gpu/drm/hisilicon/hibmc/dp/dp_link.c +++ b/drivers/gpu/drm/hisilicon/hibmc/dp/dp_link.c @@ -325,7 +325,7 @@ static int hibmc_dp_link_downgrade_training_eq(struct hibmc_dp_dev *dp) return hibmc_dp_link_reduce_rate(dp); } -static void hibmc_dp_update_caps(struct hibmc_dp_dev *dp) +void hibmc_dp_update_caps(struct hibmc_dp_dev *dp) { dp->link.cap.link_rate = dp->dpcd[DP_MAX_LINK_RATE]; if (dp->link.cap.link_rate > DP_LINK_BW_8_1 || !dp->link.cap.link_rate) diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_de.c b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_de.c index 89bed78f1466..db7fce4e8cc3 100644 --- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_de.c +++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_de.c @@ -32,26 +32,43 @@ struct hibmc_display_panel_pll { struct hibmc_dislay_pll_config { u64 hdisplay; u64 vdisplay; + int clock; u32 pll1_config_value; u32 pll2_config_value; }; static const struct hibmc_dislay_pll_config hibmc_pll_table[] = { - {640, 480, CRT_PLL1_HS_25MHZ, CRT_PLL2_HS_25MHZ}, - {800, 600, CRT_PLL1_HS_40MHZ, CRT_PLL2_HS_40MHZ}, - {1024, 768, CRT_PLL1_HS_65MHZ, CRT_PLL2_HS_65MHZ}, - {1152, 864, CRT_PLL1_HS_80MHZ_1152, CRT_PLL2_HS_80MHZ}, - {1280, 768, CRT_PLL1_HS_80MHZ, CRT_PLL2_HS_80MHZ}, - {1280, 720, CRT_PLL1_HS_74MHZ, CRT_PLL2_HS_74MHZ}, - {1280, 960, CRT_PLL1_HS_108MHZ, CRT_PLL2_HS_108MHZ}, - {1280, 1024, CRT_PLL1_HS_108MHZ, CRT_PLL2_HS_108MHZ}, - {1440, 900, CRT_PLL1_HS_106MHZ, CRT_PLL2_HS_106MHZ}, - {1600, 900, CRT_PLL1_HS_108MHZ, CRT_PLL2_HS_108MHZ}, - {1600, 1200, CRT_PLL1_HS_162MHZ, CRT_PLL2_HS_162MHZ}, - {1920, 1080, CRT_PLL1_HS_148MHZ, CRT_PLL2_HS_148MHZ}, - {1920, 1200, CRT_PLL1_HS_193MHZ, CRT_PLL2_HS_193MHZ}, + {640, 480, 25000, CRT_PLL1_HS_25MHZ, CRT_PLL2_HS_25MHZ}, + {800, 600, 40000, CRT_PLL1_HS_40MHZ, CRT_PLL2_HS_40MHZ}, + {1024, 768, 65000, CRT_PLL1_HS_65MHZ, CRT_PLL2_HS_65MHZ}, + {1152, 864, 78750, CRT_PLL1_HS_80MHZ_1152, CRT_PLL2_HS_80MHZ}, + {1280, 768, 80000, CRT_PLL1_HS_80MHZ, CRT_PLL2_HS_80MHZ}, + {1280, 720, 74375, CRT_PLL1_HS_74MHZ, CRT_PLL2_HS_74MHZ}, + {1280, 960, 108000, CRT_PLL1_HS_108MHZ, CRT_PLL2_HS_108MHZ}, + {1280, 1024, 108000, CRT_PLL1_HS_108MHZ, CRT_PLL2_HS_108MHZ}, + {1440, 900, 105952, CRT_PLL1_HS_106MHZ, CRT_PLL2_HS_106MHZ}, + {1600, 900, 108000, CRT_PLL1_HS_108MHZ, CRT_PLL2_HS_108MHZ}, + {1600, 1200, 162500, CRT_PLL1_HS_162MHZ, CRT_PLL2_HS_162MHZ}, + {1920, 1080, 148750, CRT_PLL1_HS_148MHZ, CRT_PLL2_HS_148MHZ}, + {1920, 1200, 193750, CRT_PLL1_HS_193MHZ, CRT_PLL2_HS_193MHZ}, }; +static int hibmc_get_best_clock_idx(const struct drm_display_mode *mode) +{ + int i, diff; + + for (i = 0; i < ARRAY_SIZE(hibmc_pll_table); i++) { + if (hibmc_pll_table[i].hdisplay == mode->hdisplay && + hibmc_pll_table[i].vdisplay == mode->vdisplay) { + diff = abs(mode->clock - hibmc_pll_table[i].clock); + if (diff < mode->clock / 100) /* tolerance 1/100 */ + return i; + } + } + + return -MODE_CLOCK_RANGE; +} + static int hibmc_plane_atomic_check(struct drm_plane *plane, struct drm_atomic_state *state) { @@ -214,19 +231,15 @@ static enum drm_mode_status hibmc_crtc_mode_valid(struct drm_crtc *crtc, const struct drm_display_mode *mode) { - size_t i = 0; int vrefresh = drm_mode_vrefresh(mode); if (vrefresh < 59 || vrefresh > 61) return MODE_NOCLOCK; - for (i = 0; i < ARRAY_SIZE(hibmc_pll_table); i++) { - if (hibmc_pll_table[i].hdisplay == mode->hdisplay && - hibmc_pll_table[i].vdisplay == mode->vdisplay) - return MODE_OK; - } + if (hibmc_get_best_clock_idx(mode) >= 0) + return MODE_OK; - return MODE_BAD; + return MODE_CLOCK_RANGE; } static u32 format_pll_reg(void) @@ -281,23 +294,20 @@ static void set_vclock_hisilicon(struct drm_device *dev, u64 pll) writel(val, priv->mmio + CRT_PLL1_HS); } -static void get_pll_config(u64 x, u64 y, u32 *pll1, u32 *pll2) +static void get_pll_config(struct drm_display_mode *mode, u32 *pll1, u32 *pll2) { - size_t i; - size_t count = ARRAY_SIZE(hibmc_pll_table); - - for (i = 0; i < count; i++) { - if (hibmc_pll_table[i].hdisplay == x && - hibmc_pll_table[i].vdisplay == y) { - *pll1 = hibmc_pll_table[i].pll1_config_value; - *pll2 = hibmc_pll_table[i].pll2_config_value; - return; - } + int idx; + + idx = hibmc_get_best_clock_idx(mode); + if (idx < 0) { + /* if found none, we use default value */ + *pll1 = CRT_PLL1_HS_25MHZ; + *pll2 = CRT_PLL2_HS_25MHZ; + return; } - /* if found none, we use default value */ - *pll1 = CRT_PLL1_HS_25MHZ; - *pll2 = CRT_PLL2_HS_25MHZ; + *pll1 = hibmc_pll_table[idx].pll1_config_value; + *pll2 = hibmc_pll_table[idx].pll2_config_value; } /* @@ -319,7 +329,7 @@ static u32 display_ctrl_adjust(struct drm_device *dev, x = mode->hdisplay; y = mode->vdisplay; - get_pll_config(x, y, &pll1, &pll2); + get_pll_config(mode, &pll1, &pll2); writel(pll2, priv->mmio + CRT_PLL2_HS); set_vclock_hisilicon(dev, pll1); diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_dp.c b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_dp.c index 616821e3c933..596c5bfe32d8 100644 --- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_dp.c +++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_dp.c @@ -41,6 +41,8 @@ static bool hibmc_dp_get_dpcd(struct hibmc_dp_dev *dp_dev) if (ret) return false; + hibmc_dp_update_caps(dp_dev); + dp_dev->is_branch = drm_dp_is_branch(dp_dev->dpcd); ret = drm_dp_read_desc(dp_dev->aux, &dp_dev->desc, dp_dev->is_branch); @@ -59,27 +61,38 @@ static int hibmc_dp_detect(struct drm_connector *connector, { struct hibmc_dp *dp = to_hibmc_dp(connector); struct hibmc_dp_dev *dp_dev = dp->dp_dev; - int ret; + int ret = connector_status_disconnected; if (dp->irq_status) { - if (dp_dev->hpd_status != HIBMC_HPD_IN) - return connector_status_disconnected; + if (dp_dev->hpd_status != HIBMC_HPD_IN) { + ret = connector_status_disconnected; + goto exit; + } } - if (!hibmc_dp_get_dpcd(dp_dev)) - return connector_status_disconnected; + if (!hibmc_dp_get_dpcd(dp_dev)) { + ret = connector_status_disconnected; + goto exit; + } - if (!dp_dev->is_branch) - return connector_status_connected; + if (!dp_dev->is_branch) { + ret = connector_status_connected; + goto exit; + } if (drm_dp_read_sink_count_cap(connector, dp_dev->dpcd, &dp_dev->desc) && dp_dev->downstream_ports[0] & DP_DS_PORT_HPD) { ret = drm_dp_read_sink_count(dp_dev->aux); - if (ret > 0) - return connector_status_connected; + if (ret > 0) { + ret = connector_status_connected; + goto exit; + } } - return connector_status_disconnected; +exit: + dp->phys_status = ret; + + return ret; } static int hibmc_dp_mode_valid(struct drm_connector *connector, @@ -241,5 +254,7 @@ int hibmc_dp_init(struct hibmc_drm_private *priv) connector->polled = DRM_CONNECTOR_POLL_HPD; + dp->phys_status = connector_status_disconnected; + return 0; } diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c index 289304500ab0..99b36de1fe13 100644 --- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c +++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c @@ -24,6 +24,7 @@ #include <drm/drm_managed.h> #include <drm/drm_module.h> #include <drm/drm_vblank.h> +#include <drm/drm_probe_helper.h> #include "hibmc_drm_drv.h" #include "hibmc_drm_regs.h" @@ -214,6 +215,15 @@ void hibmc_set_current_gate(struct hibmc_drm_private *priv, unsigned int gate) writel(gate, mmio + gate_reg); } +static void hibmc_display_ctrl(struct hibmc_drm_private *priv) +{ + u32 reg; + + reg = readl(priv->mmio + HIBMC_DISPLAY_CONTROL_HISILE); + reg |= HIBMC_DISPLAY_CONTROL_PANELDATE(1); + writel(reg, priv->mmio + HIBMC_DISPLAY_CONTROL_HISILE); +} + static void hibmc_hw_config(struct hibmc_drm_private *priv) { u32 reg; @@ -245,6 +255,8 @@ static void hibmc_hw_config(struct hibmc_drm_private *priv) reg |= HIBMC_MSCCTL_LOCALMEM_RESET(1); writel(reg, priv->mmio + HIBMC_MISC_CTRL); + + hibmc_display_ctrl(priv); } static int hibmc_hw_map(struct hibmc_drm_private *priv) @@ -355,6 +367,8 @@ static int hibmc_load(struct drm_device *dev) /* reset all the states of crtc/plane/encoder/connector */ drm_mode_config_reset(dev); + drmm_kms_helper_poll_init(dev); + return 0; err: diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h index ca8502e2760c..cd3a3fca1fe6 100644 --- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h +++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h @@ -31,6 +31,7 @@ struct hibmc_vdac { struct drm_connector connector; struct i2c_adapter adapter; struct i2c_algo_bit_data bit_data; + int phys_status; }; struct hibmc_drm_private { diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c index 841e81f47b68..b9bd6d33fb0f 100644 --- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c +++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c @@ -24,28 +24,21 @@ static int hibmc_connector_get_modes(struct drm_connector *connector) { + struct drm_mode_config *mode_config = &connector->dev->mode_config; struct hibmc_vdac *vdac = to_hibmc_vdac(connector); - const struct drm_edid *drm_edid; int count; - drm_edid = drm_edid_read_ddc(connector, &vdac->adapter); - - drm_edid_connector_update(connector, drm_edid); - - if (drm_edid) { - count = drm_edid_connector_add_modes(connector); + if (vdac->phys_status == connector_status_connected) { + count = drm_connector_helper_get_modes(connector); + } else { + drm_edid_connector_update(connector, NULL); + count = drm_add_modes_noedid(connector, + mode_config->max_width, + mode_config->max_height); if (count) - goto out; + drm_set_preferred_mode(connector, 1024, 768); } - count = drm_add_modes_noedid(connector, - connector->dev->mode_config.max_width, - connector->dev->mode_config.max_height); - drm_set_preferred_mode(connector, 1024, 768); - -out: - drm_edid_free(drm_edid); - return count; } @@ -57,10 +50,34 @@ static void hibmc_connector_destroy(struct drm_connector *connector) drm_connector_cleanup(connector); } +static int hibmc_vdac_detect(struct drm_connector *connector, + struct drm_modeset_acquire_ctx *ctx, + bool force) +{ + struct hibmc_drm_private *priv = to_hibmc_drm_private(connector->dev); + int status = drm_connector_helper_detect_from_ddc(connector, ctx, + force); + struct hibmc_vdac *vdac = to_hibmc_vdac(connector); + + if (priv->dp.phys_status == connector_status_connected) { + vdac->phys_status = status; + return status; + } + + if (status != vdac->phys_status) + ++connector->epoch_counter; + vdac->phys_status = status; + + /* When both the DP and VDAC physical status are disconnected, + * the "connected" status is returned to support KVM display. + */ + return connector_status_connected; +} + static const struct drm_connector_helper_funcs hibmc_connector_helper_funcs = { .get_modes = hibmc_connector_get_modes, - .detect_ctx = drm_connector_helper_detect_from_ddc, + .detect_ctx = hibmc_vdac_detect, }; static const struct drm_connector_funcs hibmc_connector_funcs = { @@ -71,26 +88,6 @@ static const struct drm_connector_funcs hibmc_connector_funcs = { .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, }; -static void hibmc_encoder_mode_set(struct drm_encoder *encoder, - struct drm_display_mode *mode, - struct drm_display_mode *adj_mode) -{ - u32 reg; - struct drm_device *dev = encoder->dev; - struct hibmc_drm_private *priv = to_hibmc_drm_private(dev); - - reg = readl(priv->mmio + HIBMC_DISPLAY_CONTROL_HISILE); - reg |= HIBMC_DISPLAY_CONTROL_FPVDDEN(1); - reg |= HIBMC_DISPLAY_CONTROL_PANELDATE(1); - reg |= HIBMC_DISPLAY_CONTROL_FPEN(1); - reg |= HIBMC_DISPLAY_CONTROL_VBIASEN(1); - writel(reg, priv->mmio + HIBMC_DISPLAY_CONTROL_HISILE); -} - -static const struct drm_encoder_helper_funcs hibmc_encoder_helper_funcs = { - .mode_set = hibmc_encoder_mode_set, -}; - int hibmc_vdac_init(struct hibmc_drm_private *priv) { struct drm_device *dev = &priv->dev; @@ -113,8 +110,6 @@ int hibmc_vdac_init(struct hibmc_drm_private *priv) goto err; } - drm_encoder_helper_add(encoder, &hibmc_encoder_helper_funcs); - ret = drm_connector_init_with_ddc(dev, connector, &hibmc_connector_funcs, DRM_MODE_CONNECTOR_VGA, @@ -130,6 +125,8 @@ int hibmc_vdac_init(struct hibmc_drm_private *priv) connector->polled = DRM_CONNECTOR_POLL_CONNECT | DRM_CONNECTOR_POLL_DISCONNECT; + vdac->phys_status = connector_status_disconnected; + return 0; err: diff --git a/drivers/gpu/drm/i915/display/intel_atomic.c b/drivers/gpu/drm/i915/display/intel_atomic.c index 348b1655435e..5b6e3605732e 100644 --- a/drivers/gpu/drm/i915/display/intel_atomic.c +++ b/drivers/gpu/drm/i915/display/intel_atomic.c @@ -289,6 +289,12 @@ static void intel_crtc_put_color_blobs(struct intel_crtc_state *crtc_state) drm_property_blob_put(crtc_state->pre_csc_lut); drm_property_blob_put(crtc_state->post_csc_lut); + + crtc_state->hw.degamma_lut = NULL; + crtc_state->hw.gamma_lut = NULL; + crtc_state->hw.ctm = NULL; + crtc_state->pre_csc_lut = NULL; + crtc_state->post_csc_lut = NULL; } void intel_crtc_free_hw_state(struct intel_crtc_state *crtc_state) diff --git a/drivers/gpu/drm/i915/gt/intel_region_lmem.c b/drivers/gpu/drm/i915/gt/intel_region_lmem.c index 51bb27e10a4f..7699e8fcf5ed 100644 --- a/drivers/gpu/drm/i915/gt/intel_region_lmem.c +++ b/drivers/gpu/drm/i915/gt/intel_region_lmem.c @@ -37,7 +37,7 @@ _resize_bar(struct drm_i915_private *i915, int resno, resource_size_t size) _release_bars(pdev); - ret = pci_resize_resource(pdev, resno, bar_size); + ret = pci_resize_resource(pdev, resno, bar_size, 0); if (ret) { drm_info(&i915->drm, "Failed to resize BAR%d to %dM (%pe)\n", resno, 1 << bar_size, ERR_PTR(ret)); diff --git a/drivers/gpu/drm/msm/dp/dp_display.c b/drivers/gpu/drm/msm/dp/dp_display.c index c79e624c1175..c6f5422b60dd 100644 --- a/drivers/gpu/drm/msm/dp/dp_display.c +++ b/drivers/gpu/drm/msm/dp/dp_display.c @@ -38,9 +38,9 @@ enum { ISR_DISCONNECTED, ISR_CONNECT_PENDING, ISR_CONNECTED, - ISR_HPD_REPLUG_COUNT, + ISR_HPD_IO_GLITCH_COUNT, ISR_IRQ_HPD_PULSE_COUNT, - ISR_HPD_LO_GLITH_COUNT, + ISR_HPD_REPLUG_COUNT, }; /* event thread connection state */ diff --git a/drivers/gpu/drm/msm/dp/dp_reg.h b/drivers/gpu/drm/msm/dp/dp_reg.h index 7c44d4e2cf13..3689642b7fc0 100644 --- a/drivers/gpu/drm/msm/dp/dp_reg.h +++ b/drivers/gpu/drm/msm/dp/dp_reg.h @@ -68,8 +68,8 @@ #define DP_DP_IRQ_HPD_INT_ACK (0x00000002) #define DP_DP_HPD_REPLUG_INT_ACK (0x00000004) #define DP_DP_HPD_UNPLUG_INT_ACK (0x00000008) -#define DP_DP_HPD_STATE_STATUS_BITS_MASK (0x0000000F) -#define DP_DP_HPD_STATE_STATUS_BITS_SHIFT (0x1C) +#define DP_DP_HPD_STATE_STATUS_BITS_MASK (0x00000007) +#define DP_DP_HPD_STATE_STATUS_BITS_SHIFT (0x1D) #define REG_DP_DP_HPD_INT_MASK (0x0000000C) #define DP_DP_HPD_PLUG_INT_MASK (0x00000001) diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/shadowramin.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/shadowramin.c index 023ddc7c5399..a295e94e4cb8 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/shadowramin.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/shadowramin.c @@ -65,13 +65,14 @@ pramin_init(struct nvkm_bios *bios, const char *name) /* we can't get the bios image pointer without PDISP */ if (device->card_type >= GA100) - addr = device->chipset == 0x170; /*XXX: find the fuse reg for this */ + addr = nvkm_rd32(device, 0x820c04); else if (device->card_type >= GM100) addr = nvkm_rd32(device, 0x021c04); else if (device->card_type >= NV_C0) addr = nvkm_rd32(device, 0x022500); + if (addr & 0x00000001) { nvkm_debug(subdev, "... display disabled\n"); return ERR_PTR(-ENODEV); diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig index 407c5f6a268b..1516c6fa265d 100644 --- a/drivers/gpu/drm/panel/Kconfig +++ b/drivers/gpu/drm/panel/Kconfig @@ -810,11 +810,18 @@ config DRM_PANEL_SAMSUNG_S6E3HA2 config DRM_PANEL_SAMSUNG_S6E3HA8 tristate "Samsung S6E3HA8 DSI video mode panel" + depends on GPIOLIB depends on OF depends on DRM_MIPI_DSI depends on BACKLIGHT_CLASS_DEVICE select DRM_DISPLAY_DSC_HELPER - select VIDEOMODE_HELPERS + help + Say Y or M here if you want to enable support for the + Samsung S6E3HA8 DDIC and connected MIPI DSI panel. + Currently supported panels: + + Samsung AMB577PX01 (found in the Samsung S9 smartphone) + config DRM_PANEL_SAMSUNG_S6E63J0X03 tristate "Samsung S6E63J0X03 DSI command mode panel" diff --git a/drivers/gpu/drm/panthor/panthor_sched.c b/drivers/gpu/drm/panthor/panthor_sched.c index 6930053009d5..85e24ca47448 100644 --- a/drivers/gpu/drm/panthor/panthor_sched.c +++ b/drivers/gpu/drm/panthor/panthor_sched.c @@ -1039,7 +1039,8 @@ group_unbind_locked(struct panthor_group *group) /* Tiler OOM events will be re-issued next time the group is scheduled. */ atomic_set(&group->tiler_oom, 0); - cancel_work(&group->tiler_oom_work); + if (cancel_work(&group->tiler_oom_work)) + group_put(group); for (u32 i = 0; i < group->queue_count; i++) group->queues[i]->doorbell_id = -1; @@ -1488,7 +1489,10 @@ static int group_process_tiler_oom(struct panthor_group *group, u32 cs_id) if (unlikely(csg_id < 0)) return 0; - if (IS_ERR(heaps) || frag_end > vt_end || vt_end >= vt_start) { + if (IS_ERR(heaps)) { + ret = -EINVAL; + heaps = NULL; + } else if (frag_end > vt_end || vt_end >= vt_start) { ret = -EINVAL; } else { /* We do the allocation without holding the scheduler lock to avoid @@ -2285,7 +2289,13 @@ tick_ctx_apply(struct panthor_scheduler *sched, struct panthor_sched_tick_ctx *c csg_iface = panthor_fw_get_csg_iface(ptdev, csg_id); csg_slot = &sched->csg_slots[csg_id]; - group_bind_locked(group, csg_id); + ret = group_bind_locked(group, csg_id); + if (ret) { + panthor_device_schedule_reset(ptdev); + ctx->csg_upd_failed_mask |= BIT(csg_id); + return; + } + csg_slot_prog_locked(ptdev, csg_id, new_csg_prio--); csgs_upd_ctx_queue_reqs(ptdev, &upd_ctx, csg_id, group->state == PANTHOR_CS_GROUP_SUSPENDED ? @@ -2585,7 +2595,14 @@ static void sched_resume_tick(struct panthor_device *ptdev) else delay_jiffies = 0; - sched_queue_delayed_work(sched, tick, delay_jiffies); + /* We schedule immediate ticks when we need to process events on CSGs, + * but those don't change the resched_target because we want the other + * groups to stay scheduled for the remaining of the GPU timeslot they + * were given. Make sure those immediate ticks don't get overruled by + * a sched_queue_delayed_work() that would delay the tick execution. + */ + if (!delayed_work_pending(&sched->tick_work)) + sched_queue_delayed_work(sched, tick, delay_jiffies); } static void group_schedule_locked(struct panthor_group *group, u32 queue_mask) diff --git a/drivers/gpu/drm/radeon/radeon_gem.c b/drivers/gpu/drm/radeon/radeon_gem.c index f86773f3db20..1e84342ac051 100644 --- a/drivers/gpu/drm/radeon/radeon_gem.c +++ b/drivers/gpu/drm/radeon/radeon_gem.c @@ -28,6 +28,7 @@ #include <linux/debugfs.h> #include <linux/iosys-map.h> +#include <linux/overflow.h> #include <linux/pci.h> #include <drm/drm_device.h> @@ -812,6 +813,7 @@ int radeon_align_pitch(struct radeon_device *rdev, int width, int cpp, bool tile int aligned = width; int align_large = (ASIC_IS_AVIVO(rdev)) || tiled; int pitch_mask = 0; + int pitch; switch (cpp) { case 1: @@ -826,9 +828,12 @@ int radeon_align_pitch(struct radeon_device *rdev, int width, int cpp, bool tile break; } - aligned += pitch_mask; + if (check_add_overflow(aligned, pitch_mask, &aligned)) + return 0; aligned &= ~pitch_mask; - return aligned * cpp; + if (check_mul_overflow(aligned, cpp, &pitch)) + return 0; + return pitch; } int radeon_mode_dumb_create(struct drm_file *file_priv, @@ -842,8 +847,12 @@ int radeon_mode_dumb_create(struct drm_file *file_priv, args->pitch = radeon_align_pitch(rdev, args->width, DIV_ROUND_UP(args->bpp, 8), 0); + if (!args->pitch) + return -EINVAL; args->size = (u64)args->pitch * args->height; args->size = ALIGN(args->size, PAGE_SIZE); + if (!args->size) + return -EINVAL; r = radeon_gem_object_create(rdev, args->size, 0, RADEON_GEM_DOMAIN_VRAM, 0, diff --git a/drivers/gpu/drm/radeon/radeon_ring.c b/drivers/gpu/drm/radeon/radeon_ring.c index 581ae20c46e4..a5dff072c1ac 100644 --- a/drivers/gpu/drm/radeon/radeon_ring.c +++ b/drivers/gpu/drm/radeon/radeon_ring.c @@ -356,8 +356,10 @@ int radeon_ring_restore(struct radeon_device *rdev, struct radeon_ring *ring, /* restore the saved ring content */ r = radeon_ring_lock(rdev, ring, size); - if (r) + if (r) { + kvfree(data); return r; + } for (i = 0; i < size; ++i) { radeon_ring_write(ring, data[i]); diff --git a/drivers/gpu/drm/renesas/rz-du/rzg2l_mipi_dsi.c b/drivers/gpu/drm/renesas/rz-du/rzg2l_mipi_dsi.c index b164e3a62cc2..cbd898a182b5 100644 --- a/drivers/gpu/drm/renesas/rz-du/rzg2l_mipi_dsi.c +++ b/drivers/gpu/drm/renesas/rz-du/rzg2l_mipi_dsi.c @@ -1002,6 +1002,11 @@ static int rzg2l_mipi_dsi_probe(struct platform_device *pdev) return dev_err_probe(dsi->dev, PTR_ERR(dsi->prstc), "failed to get prst\n"); + dsi->dcs_buf_virt = dmam_alloc_coherent(dsi->dev, RZG2L_DCS_BUF_SIZE, + &dsi->dcs_buf_phys, GFP_KERNEL); + if (!dsi->dcs_buf_virt) + return -ENOMEM; + platform_set_drvdata(pdev, dsi); pm_runtime_enable(dsi->dev); @@ -1034,11 +1039,6 @@ static int rzg2l_mipi_dsi_probe(struct platform_device *pdev) if (ret < 0) goto err_pm_disable; - dsi->dcs_buf_virt = dma_alloc_coherent(dsi->host.dev, RZG2L_DCS_BUF_SIZE, - &dsi->dcs_buf_phys, GFP_KERNEL); - if (!dsi->dcs_buf_virt) - return -ENOMEM; - return 0; err_phy: @@ -1053,8 +1053,6 @@ static void rzg2l_mipi_dsi_remove(struct platform_device *pdev) { struct rzg2l_mipi_dsi *dsi = platform_get_drvdata(pdev); - dma_free_coherent(dsi->host.dev, RZG2L_DCS_BUF_SIZE, dsi->dcs_buf_virt, - dsi->dcs_buf_phys); mipi_dsi_host_unregister(&dsi->host); pm_runtime_disable(&pdev->dev); } diff --git a/drivers/gpu/drm/rockchip/dw_dp-rockchip.c b/drivers/gpu/drm/rockchip/dw_dp-rockchip.c index 25ab4e46301e..6d57e1c74627 100644 --- a/drivers/gpu/drm/rockchip/dw_dp-rockchip.c +++ b/drivers/gpu/drm/rockchip/dw_dp-rockchip.c @@ -13,6 +13,7 @@ #include <drm/drm_atomic_helper.h> #include <drm/drm_bridge.h> #include <drm/drm_bridge_connector.h> +#include <drm/drm_managed.h> #include <drm/drm_of.h> #include <drm/drm_print.h> #include <drm/drm_probe_helper.h> @@ -82,7 +83,7 @@ static int dw_dp_rockchip_bind(struct device *dev, struct device *master, void * struct drm_connector *connector; int ret; - dp = devm_kzalloc(dev, sizeof(*dp), GFP_KERNEL); + dp = drmm_kzalloc(drm_dev, sizeof(*dp), GFP_KERNEL); if (!dp) return -ENOMEM; @@ -129,9 +130,7 @@ static int dw_dp_probe(struct platform_device *pdev) static void dw_dp_remove(struct platform_device *pdev) { - struct rockchip_dw_dp *dp = platform_get_drvdata(pdev); - - component_del(dp->dev, &dw_dp_rockchip_component_ops); + component_del(&pdev->dev, &dw_dp_rockchip_component_ops); } static const struct of_device_id dw_dp_of_match[] = { diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_gem.c b/drivers/gpu/drm/rockchip/rockchip_drm_gem.c index 6330b883efc3..e44396d46dc1 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_gem.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_gem.c @@ -332,7 +332,7 @@ void rockchip_gem_free_object(struct drm_gem_object *obj) struct rockchip_drm_private *private = drm->dev_private; struct rockchip_gem_object *rk_obj = to_rockchip_obj(obj); - if (obj->import_attach) { + if (drm_gem_is_imported(obj)) { if (private->domain) { rockchip_gem_iommu_unmap(rk_obj); } else { diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/drm/tegra/dc.c index 6c84bd69b11f..dc69c8873693 100644 --- a/drivers/gpu/drm/tegra/dc.c +++ b/drivers/gpu/drm/tegra/dc.c @@ -100,8 +100,10 @@ bool tegra_dc_has_output(struct tegra_dc *dc, struct device *dev) int err; of_for_each_phandle(&it, err, np, "nvidia,outputs", NULL, 0) - if (it.node == dev->of_node) + if (it.node == dev->of_node) { + of_node_put(it.node); return true; + } return false; } diff --git a/drivers/gpu/drm/tegra/gem.c b/drivers/gpu/drm/tegra/gem.c index 8ede07fb7a21..abfac20d63fd 100644 --- a/drivers/gpu/drm/tegra/gem.c +++ b/drivers/gpu/drm/tegra/gem.c @@ -68,7 +68,7 @@ static struct host1x_bo_mapping *tegra_bo_pin(struct device *dev, struct host1x_ return ERR_PTR(-ENOMEM); kref_init(&map->ref); - map->bo = host1x_bo_get(bo); + map->bo = bo; map->direction = direction; map->dev = dev; @@ -169,7 +169,6 @@ static void tegra_bo_unpin(struct host1x_bo_mapping *map) kfree(map->sgt); } - host1x_bo_put(map->bo); kfree(map); } @@ -234,6 +233,7 @@ static const struct host1x_bo_ops tegra_bo_ops = { static int tegra_bo_iommu_map(struct tegra_drm *tegra, struct tegra_bo *bo) { int prot = IOMMU_READ | IOMMU_WRITE; + ssize_t size; int err; if (bo->mm) @@ -255,13 +255,15 @@ static int tegra_bo_iommu_map(struct tegra_drm *tegra, struct tegra_bo *bo) bo->iova = bo->mm->start; - bo->size = iommu_map_sgtable(tegra->domain, bo->iova, bo->sgt, prot); - if (!bo->size) { + size = iommu_map_sgtable(tegra->domain, bo->iova, bo->sgt, prot); + if (size < 0) { dev_err(tegra->drm->dev, "failed to map buffer\n"); - err = -ENOMEM; + err = size; goto remove; } + bo->size = size; + mutex_unlock(&tegra->mm_lock); return 0; @@ -508,17 +510,9 @@ free: void tegra_bo_free_object(struct drm_gem_object *gem) { struct tegra_drm *tegra = gem->dev->dev_private; - struct host1x_bo_mapping *mapping, *tmp; struct tegra_bo *bo = to_tegra_bo(gem); - /* remove all mappings of this buffer object from any caches */ - list_for_each_entry_safe(mapping, tmp, &bo->base.mappings, list) { - if (mapping->cache) - host1x_bo_unpin(mapping); - else - dev_err(gem->dev->dev, "mapping %p stale for device %s\n", mapping, - dev_name(mapping->dev)); - } + host1x_bo_clear_cached_mappings(&bo->base); if (tegra->domain) { tegra_bo_iommu_unmap(tegra, bo); diff --git a/drivers/gpu/drm/tegra/gr2d.c b/drivers/gpu/drm/tegra/gr2d.c index 21f4dd0fa6af..892e3450b281 100644 --- a/drivers/gpu/drm/tegra/gr2d.c +++ b/drivers/gpu/drm/tegra/gr2d.c @@ -100,9 +100,6 @@ static int gr2d_exit(struct host1x_client *client) if (err < 0) return err; - pm_runtime_dont_use_autosuspend(client->dev); - pm_runtime_force_suspend(client->dev); - host1x_client_iommu_detach(client); host1x_syncpt_put(client->syncpts[0]); host1x_channel_put(gr2d->channel); @@ -276,15 +273,21 @@ static int gr2d_probe(struct platform_device *pdev) if (err) return err; + /* initialize address register map */ + for (i = 0; i < ARRAY_SIZE(gr2d_addr_regs); i++) + set_bit(gr2d_addr_regs[i], gr2d->addr_regs); + + pm_runtime_enable(dev); + err = host1x_client_register(&gr2d->client.base); if (err < 0) { + pm_runtime_disable(dev); dev_err(dev, "failed to register host1x client: %d\n", err); return err; } - /* initialize address register map */ - for (i = 0; i < ARRAY_SIZE(gr2d_addr_regs); i++) - set_bit(gr2d_addr_regs[i], gr2d->addr_regs); + pm_runtime_use_autosuspend(dev); + pm_runtime_set_autosuspend_delay(dev, 500); return 0; } @@ -367,10 +370,6 @@ static int __maybe_unused gr2d_runtime_resume(struct device *dev) goto disable_clk; } - pm_runtime_enable(dev); - pm_runtime_use_autosuspend(dev); - pm_runtime_set_autosuspend_delay(dev, 500); - return 0; disable_clk: diff --git a/drivers/gpu/drm/tegra/gr3d.c b/drivers/gpu/drm/tegra/gr3d.c index 42e9656ab80c..388e47943d5e 100644 --- a/drivers/gpu/drm/tegra/gr3d.c +++ b/drivers/gpu/drm/tegra/gr3d.c @@ -109,9 +109,6 @@ static int gr3d_exit(struct host1x_client *client) if (err < 0) return err; - pm_runtime_dont_use_autosuspend(client->dev); - pm_runtime_force_suspend(client->dev); - host1x_client_iommu_detach(client); host1x_syncpt_put(client->syncpts[0]); host1x_channel_put(gr3d->channel); @@ -506,16 +503,22 @@ static int gr3d_probe(struct platform_device *pdev) if (err) return err; + /* initialize address register map */ + for (i = 0; i < ARRAY_SIZE(gr3d_addr_regs); i++) + set_bit(gr3d_addr_regs[i], gr3d->addr_regs); + + pm_runtime_enable(&pdev->dev); + err = host1x_client_register(&gr3d->client.base); if (err < 0) { + pm_runtime_disable(&pdev->dev); dev_err(&pdev->dev, "failed to register host1x client: %d\n", err); return err; } - /* initialize address register map */ - for (i = 0; i < ARRAY_SIZE(gr3d_addr_regs); i++) - set_bit(gr3d_addr_regs[i], gr3d->addr_regs); + pm_runtime_use_autosuspend(&pdev->dev); + pm_runtime_set_autosuspend_delay(&pdev->dev, 500); return 0; } @@ -578,10 +581,6 @@ static int __maybe_unused gr3d_runtime_resume(struct device *dev) goto disable_clk; } - pm_runtime_enable(dev); - pm_runtime_use_autosuspend(dev); - pm_runtime_set_autosuspend_delay(dev, 500); - return 0; disable_clk: diff --git a/drivers/gpu/drm/tegra/submit.c b/drivers/gpu/drm/tegra/submit.c index 2430fcc97448..705382035f5f 100644 --- a/drivers/gpu/drm/tegra/submit.c +++ b/drivers/gpu/drm/tegra/submit.c @@ -76,7 +76,7 @@ gather_bo_pin(struct device *dev, struct host1x_bo *bo, enum dma_data_direction return ERR_PTR(-ENOMEM); kref_init(&map->ref); - map->bo = host1x_bo_get(bo); + map->bo = bo; map->direction = direction; map->dev = dev; @@ -117,7 +117,6 @@ static void gather_bo_unpin(struct host1x_bo_mapping *map) dma_unmap_sgtable(map->dev, map->sgt, map->direction, 0); sg_free_table(map->sgt); kfree(map->sgt); - host1x_bo_put(map->bo); kfree(map); } diff --git a/drivers/gpu/drm/tidss/tidss_kms.c b/drivers/gpu/drm/tidss/tidss_kms.c index 9f5f98e707f2..838111e11186 100644 --- a/drivers/gpu/drm/tidss/tidss_kms.c +++ b/drivers/gpu/drm/tidss/tidss_kms.c @@ -291,8 +291,6 @@ int tidss_modeset_init(struct tidss_device *tidss) if (ret) return ret; - drm_mode_config_reset(ddev); - dev_dbg(tidss->dev, "%s done\n", __func__); return 0; diff --git a/drivers/gpu/drm/v3d/v3d_submit.c b/drivers/gpu/drm/v3d/v3d_submit.c index 95b9e68b0dfe..1274e6010bea 100644 --- a/drivers/gpu/drm/v3d/v3d_submit.c +++ b/drivers/gpu/drm/v3d/v3d_submit.c @@ -462,6 +462,8 @@ v3d_get_cpu_indirect_csd_params(struct drm_file *file_priv, sizeof(indirect_csd.wg_uniform_offsets)); info->indirect = drm_gem_object_lookup(file_priv, indirect_csd.indirect); + if (!info->indirect) + return -ENOENT; return v3d_setup_csd_jobs_and_bos(file_priv, v3d, &indirect_csd.submit, &info->job, &info->clean_job, diff --git a/drivers/gpu/drm/xe/Makefile b/drivers/gpu/drm/xe/Makefile index d9c6cf0f189e..ee52b751623f 100644 --- a/drivers/gpu/drm/xe/Makefile +++ b/drivers/gpu/drm/xe/Makefile @@ -16,14 +16,14 @@ subdir-ccflags-y += -I$(obj) -I$(src) hostprogs := xe_gen_wa_oob generated_oob := $(obj)/generated/xe_wa_oob.c $(obj)/generated/xe_wa_oob.h quiet_cmd_wa_oob = GEN $(notdir $(generated_oob)) - cmd_wa_oob = mkdir -p $(@D); $^ $(generated_oob) + cmd_wa_oob = mkdir -p $(@D); $(obj)/xe_gen_wa_oob $(src)/xe_wa_oob.rules $(generated_oob) $(obj)/generated/%_wa_oob.c $(obj)/generated/%_wa_oob.h: $(obj)/xe_gen_wa_oob \ $(src)/xe_wa_oob.rules $(call cmd,wa_oob) generated_device_oob := $(obj)/generated/xe_device_wa_oob.c $(obj)/generated/xe_device_wa_oob.h quiet_cmd_device_wa_oob = GEN $(notdir $(generated_device_oob)) - cmd_device_wa_oob = mkdir -p $(@D); $^ $(generated_device_oob) + cmd_device_wa_oob = mkdir -p $(@D); $(obj)/xe_gen_wa_oob $(src)/xe_device_wa_oob.rules $(generated_device_oob) $(obj)/generated/%_device_wa_oob.c $(obj)/generated/%_device_wa_oob.h: $(obj)/xe_gen_wa_oob \ $(src)/xe_device_wa_oob.rules $(call cmd,device_wa_oob) diff --git a/drivers/gpu/drm/xe/tests/xe_pci.c b/drivers/gpu/drm/xe/tests/xe_pci.c index 663a79ec960d..b607d9422ef8 100644 --- a/drivers/gpu/drm/xe/tests/xe_pci.c +++ b/drivers/gpu/drm/xe/tests/xe_pci.c @@ -9,7 +9,6 @@ #include <kunit/test-bug.h> #include <kunit/test.h> -#include <kunit/test-bug.h> #include <kunit/visibility.h> #define PLATFORM_CASE(platform__, graphics_step__) \ diff --git a/drivers/gpu/drm/xe/xe_debugfs.c b/drivers/gpu/drm/xe/xe_debugfs.c index 7b48bf90cab8..bbd7c5938a04 100644 --- a/drivers/gpu/drm/xe/xe_debugfs.c +++ b/drivers/gpu/drm/xe/xe_debugfs.c @@ -45,7 +45,7 @@ static void read_residency_counter(struct xe_device *xe, struct xe_mmio *mmio, u64 residency = 0; int ret; - ret = xe_pmt_telem_read(to_pci_dev(xe->drm.dev), + ret = xe_pmt_telem_read(xe->drm.dev, xe_mmio_read32(mmio, PUNIT_TELEMETRY_GUID), &residency, offset, sizeof(residency)); if (ret != sizeof(residency)) { diff --git a/drivers/gpu/drm/xe/xe_guc_relay.c b/drivers/gpu/drm/xe/xe_guc_relay.c index e5dc94f3e618..09febc2b152e 100644 --- a/drivers/gpu/drm/xe/xe_guc_relay.c +++ b/drivers/gpu/drm/xe/xe_guc_relay.c @@ -677,12 +677,17 @@ static int relay_action_handler(struct xe_guc_relay *relay, u32 origin, return relay_testloop_action_handler(relay, origin, msg, len, response, size); type = FIELD_GET(GUC_HXG_MSG_0_TYPE, msg[0]); + relay_assert(relay, guc_hxg_type_is_action(type)); - if (IS_SRIOV_PF(relay_to_xe(relay))) - ret = xe_gt_sriov_pf_service_process_request(gt, origin, msg, len, response, size); - else + if (IS_SRIOV_PF(relay_to_xe(relay))) { + if (type == GUC_HXG_TYPE_REQUEST) + ret = xe_gt_sriov_pf_service_process_request(gt, origin, msg, len, + response, size); + else + ret = -EOPNOTSUPP; + } else { ret = -EOPNOTSUPP; - + } if (type == GUC_HXG_TYPE_EVENT) relay_assert(relay, ret <= 0); diff --git a/drivers/gpu/drm/xe/xe_hw_engine.c b/drivers/gpu/drm/xe/xe_hw_engine.c index d8f16e25b817..d88770370eeb 100644 --- a/drivers/gpu/drm/xe/xe_hw_engine.c +++ b/drivers/gpu/drm/xe/xe_hw_engine.c @@ -619,7 +619,7 @@ static int hw_engine_init(struct xe_gt *gt, struct xe_hw_engine *hwe, hwe->exl_port = xe_execlist_port_create(xe, hwe); if (IS_ERR(hwe->exl_port)) { err = PTR_ERR(hwe->exl_port); - goto err_hwsp; + goto err_name; } } else { /* GSCCS has a special interrupt for reset */ @@ -639,8 +639,6 @@ static int hw_engine_init(struct xe_gt *gt, struct xe_hw_engine *hwe, return devm_add_action_or_reset(xe->drm.dev, hw_engine_fini, hwe); -err_hwsp: - xe_bo_unpin_map_no_vm(hwe->hwsp); err_name: hwe->name = NULL; diff --git a/drivers/gpu/drm/xe/xe_hwmon.c b/drivers/gpu/drm/xe/xe_hwmon.c index b6790589e623..65621775878b 100644 --- a/drivers/gpu/drm/xe/xe_hwmon.c +++ b/drivers/gpu/drm/xe/xe_hwmon.c @@ -464,7 +464,7 @@ xe_hwmon_energy_get(struct xe_hwmon *hwmon, int channel, long *energy) if (hwmon->xe->info.platform == XE_BATTLEMAGE) { u64 pmt_val; - ret = xe_pmt_telem_read(to_pci_dev(hwmon->xe->drm.dev), + ret = xe_pmt_telem_read(hwmon->xe->drm.dev, xe_mmio_read32(mmio, PUNIT_TELEMETRY_GUID), &pmt_val, BMG_ENERGY_STATUS_PMT_OFFSET, sizeof(pmt_val)); if (ret != sizeof(pmt_val)) { diff --git a/drivers/gpu/drm/xe/xe_pt.c b/drivers/gpu/drm/xe/xe_pt.c index a21383fba1e8..1f0262adc3ae 100644 --- a/drivers/gpu/drm/xe/xe_pt.c +++ b/drivers/gpu/drm/xe/xe_pt.c @@ -860,13 +860,21 @@ static int xe_pt_zap_ptes_entry(struct xe_ptw *parent, pgoff_t offset, { struct xe_pt_zap_ptes_walk *xe_walk = container_of(walk, typeof(*xe_walk), base); - struct xe_pt *xe_child = container_of(*child, typeof(*xe_child), base); + struct xe_pt *xe_child; pgoff_t end_offset; - XE_WARN_ON(!*child); XE_WARN_ON(!level); /* + * Below would be unexpected behavior that needs to be root caused + * but better warn and bail than crash the driver. + */ + if (XE_WARN_ON(!*child)) + return 0; + + xe_child = container_of(*child, typeof(*xe_child), base); + + /* * Note that we're called from an entry callback, and we're dealing * with the child of that entry rather than the parent, so need to * adjust level down. @@ -1053,7 +1061,7 @@ static void xe_pt_commit_locks_assert(struct xe_vma *vma) xe_pt_commit_prepare_locks_assert(vma); if (xe_vma_is_userptr(vma)) - xe_svm_assert_held_read(vm); + xe_svm_assert_held_read_or_inject_write(vm); } static void xe_pt_commit(struct xe_vma *vma, @@ -1381,6 +1389,38 @@ static int xe_pt_pre_commit(struct xe_migrate_pt_update *pt_update) } #if IS_ENABLED(CONFIG_DRM_GPUSVM) +/* + * Acquire/release the svm notifier_lock around xe_pt_svm_userptr_pre_commit() + * and the matching late release in xe_pt_update_ops_run(). Read mode by + * default; write mode when CONFIG_DRM_XE_USERPTR_INVAL_INJECT is on, + * because a userptr op in this critical section may invoke the injected + * xe_vma_userptr_force_invalidate() path that calls + * drm_gpusvm_unmap_pages() with ctx->in_notifier=true, which requires the + * lock held for write. + */ +static void xe_pt_svm_userptr_notifier_lock(struct xe_vm *vm) +{ +#if IS_ENABLED(CONFIG_DRM_XE_USERPTR_INVAL_INJECT) + down_write(&vm->svm.gpusvm.notifier_lock); +#else + xe_svm_notifier_lock(vm); +#endif +} + +static void xe_pt_svm_userptr_notifier_unlock(struct xe_vm *vm) +{ +#if IS_ENABLED(CONFIG_DRM_XE_USERPTR_INVAL_INJECT) + up_write(&vm->svm.gpusvm.notifier_lock); +#else + xe_svm_notifier_unlock(vm); +#endif +} +#else +static inline void xe_pt_svm_userptr_notifier_lock(struct xe_vm *vm) { } +static inline void xe_pt_svm_userptr_notifier_unlock(struct xe_vm *vm) { } +#endif + +#if IS_ENABLED(CONFIG_DRM_GPUSVM) #ifdef CONFIG_DRM_XE_USERPTR_INVAL_INJECT static bool xe_pt_userptr_inject_eagain(struct xe_userptr_vma *uvma) @@ -1411,7 +1451,7 @@ static int vma_check_userptr(struct xe_vm *vm, struct xe_vma *vma, struct xe_userptr_vma *uvma; unsigned long notifier_seq; - xe_svm_assert_held_read(vm); + xe_svm_assert_held_read_or_inject_write(vm); if (!xe_vma_is_userptr(vma)) return 0; @@ -1441,7 +1481,7 @@ static int op_check_svm_userptr(struct xe_vm *vm, struct xe_vma_op *op, { int err = 0; - xe_svm_assert_held_read(vm); + xe_svm_assert_held_read_or_inject_write(vm); switch (op->base.op) { case DRM_GPUVA_OP_MAP: @@ -1513,12 +1553,12 @@ static int xe_pt_svm_userptr_pre_commit(struct xe_migrate_pt_update *pt_update) if (err) return err; - xe_svm_notifier_lock(vm); + xe_pt_svm_userptr_notifier_lock(vm); list_for_each_entry(op, &vops->list, link) { err = op_check_svm_userptr(vm, op, pt_update_ops); if (err) { - xe_svm_notifier_unlock(vm); + xe_pt_svm_userptr_notifier_unlock(vm); break; } } @@ -2184,7 +2224,7 @@ static void bind_op_commit(struct xe_vm *vm, struct xe_tile *tile, vma->tile_invalidated & ~BIT(tile->id)); vma->tile_staged &= ~BIT(tile->id); if (xe_vma_is_userptr(vma)) { - xe_svm_assert_held_read(vm); + xe_svm_assert_held_read_or_inject_write(vm); to_userptr_vma(vma)->userptr.initial_bind = true; } @@ -2220,7 +2260,7 @@ static void unbind_op_commit(struct xe_vm *vm, struct xe_tile *tile, if (!vma->tile_present) { list_del_init(&vma->combined_links.rebind); if (xe_vma_is_userptr(vma)) { - xe_svm_assert_held_read(vm); + xe_svm_assert_held_read_or_inject_write(vm); spin_lock(&vm->userptr.invalidated_lock); list_del_init(&to_userptr_vma(vma)->userptr.invalidate_link); @@ -2509,7 +2549,7 @@ xe_pt_update_ops_run(struct xe_tile *tile, struct xe_vma_ops *vops) } if (pt_update_ops->needs_svm_lock) - xe_svm_notifier_unlock(vm); + xe_pt_svm_userptr_notifier_unlock(vm); xe_tlb_inval_job_put(mjob); xe_tlb_inval_job_put(ijob); diff --git a/drivers/gpu/drm/xe/xe_svm.h b/drivers/gpu/drm/xe/xe_svm.h index fa757dd07954..45bf10f86660 100644 --- a/drivers/gpu/drm/xe/xe_svm.h +++ b/drivers/gpu/drm/xe/xe_svm.h @@ -353,8 +353,19 @@ static inline void xe_svm_flush(struct xe_vm *vm) #define xe_svm_assert_in_notifier(vm__) \ lockdep_assert_held_write(&(vm__)->svm.gpusvm.notifier_lock) -#define xe_svm_assert_held_read(vm__) \ +/* + * Assert the svm notifier_lock is held. Read mode by default; write mode + * when CONFIG_DRM_XE_USERPTR_INVAL_INJECT is on, because that path forces + * a userptr invalidation that ends in drm_gpusvm_unmap_pages() with + * ctx->in_notifier=true, which requires the lock held for write. + */ +#if IS_ENABLED(CONFIG_DRM_XE_USERPTR_INVAL_INJECT) +#define xe_svm_assert_held_read_or_inject_write(vm__) \ + lockdep_assert_held_write(&(vm__)->svm.gpusvm.notifier_lock) +#else +#define xe_svm_assert_held_read_or_inject_write(vm__) \ lockdep_assert_held_read(&(vm__)->svm.gpusvm.notifier_lock) +#endif #define xe_svm_notifier_lock(vm__) \ drm_gpusvm_notifier_lock(&(vm__)->svm.gpusvm) @@ -368,7 +379,7 @@ static inline void xe_svm_flush(struct xe_vm *vm) #else #define xe_svm_assert_in_notifier(...) do {} while (0) -static inline void xe_svm_assert_held_read(struct xe_vm *vm) +static inline void xe_svm_assert_held_read_or_inject_write(struct xe_vm *vm) { } diff --git a/drivers/gpu/drm/xe/xe_vram.c b/drivers/gpu/drm/xe/xe_vram.c index 652df7a5f4f6..a4076f56a3c9 100644 --- a/drivers/gpu/drm/xe/xe_vram.c +++ b/drivers/gpu/drm/xe/xe_vram.c @@ -56,7 +56,7 @@ static void resize_bar(struct xe_device *xe, int resno, resource_size_t size) release_bars(pdev); - ret = pci_resize_resource(pdev, resno, bar_size); + ret = pci_resize_resource(pdev, resno, bar_size, 0); if (ret) { drm_info(&xe->drm, "Failed to resize BAR%d to %dM (%pe). Consider enabling 'Resizable BAR' support in your BIOS\n", resno, 1 << bar_size, ERR_PTR(ret)); diff --git a/drivers/gpu/drm/xe/xe_vsec.c b/drivers/gpu/drm/xe/xe_vsec.c index 8f23a27871b6..997fe0c8858e 100644 --- a/drivers/gpu/drm/xe/xe_vsec.c +++ b/drivers/gpu/drm/xe/xe_vsec.c @@ -141,10 +141,10 @@ static int xe_guid_decode(u32 guid, int *index, u32 *offset) return 0; } -int xe_pmt_telem_read(struct pci_dev *pdev, u32 guid, u64 *data, loff_t user_offset, +int xe_pmt_telem_read(struct device *dev, u32 guid, u64 *data, loff_t user_offset, u32 count) { - struct xe_device *xe = pdev_to_xe_device(pdev); + struct xe_device *xe = kdev_to_xe_device(dev); void __iomem *telem_addr = xe->mmio.regs + BMG_TELEMETRY_OFFSET; u32 mem_region; u32 offset; @@ -197,7 +197,6 @@ void xe_vsec_init(struct xe_device *xe) { struct intel_vsec_platform_info *info; struct device *dev = xe->drm.dev; - struct pci_dev *pdev = to_pci_dev(dev); enum xe_vsec platform; platform = get_platform_info(xe); @@ -220,6 +219,6 @@ void xe_vsec_init(struct xe_device *xe) * Register a VSEC. Cleanup is handled using device managed * resources. */ - intel_vsec_register(pdev, info); + intel_vsec_register(dev, info); } MODULE_IMPORT_NS("INTEL_VSEC"); diff --git a/drivers/gpu/drm/xe/xe_vsec.h b/drivers/gpu/drm/xe/xe_vsec.h index dabfb4e02d70..a25b4e6e681b 100644 --- a/drivers/gpu/drm/xe/xe_vsec.h +++ b/drivers/gpu/drm/xe/xe_vsec.h @@ -6,10 +6,10 @@ #include <linux/types.h> -struct pci_dev; +struct device; struct xe_device; void xe_vsec_init(struct xe_device *xe); -int xe_pmt_telem_read(struct pci_dev *pdev, u32 guid, u64 *data, loff_t user_offset, u32 count); +int xe_pmt_telem_read(struct device *dev, u32 guid, u64 *data, loff_t user_offset, u32 count); #endif |
