Commit 60d9212c authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'drm-fixes-2026-04-03' of https://gitlab.freedesktop.org/drm/kernel

Pull drm fixes from Dave Airlie:
 "Hopefully no Easter eggs in this bunch of fixes. Usual stuff across
  the amd/intel with some misc bits. Thanks to Thorsten and Alex for
  making sure a regression fix that was hanging around in process land
  finally made it in, that is probably the biggest change in here.

  core:
   - revert unplug/framebuffer fix as it caused problems
   - compat ioctl speculation fix

  bridge:
   - refcounting fix

  sysfb:
   - error handling fix

  amdgpu:
   - fix renoir audio regression
   - UserQ fixes
   - PASID handling fix
   - S4 fix for smu11 chips
   - Misc small fixes

  amdkfd:
   - Non-4K page fixes

  i915:
   - Fix for #12045: Huawei Matebook E (DRR-WXX): Persistent Black
     Screen on Boot with i915 and Gen11: Modesetting and Backlight
     Control Malfunction
   - Fix for #15826: i915: Raptor Lake-P [UHD Graphics] display
     flicker/corruption on eDP panel
   - Use crtc_state->enhanced_framing properly on ivb/hsw CPU eDP

  xe:
   - uapi: Accept canonical GPU addresses in xe_vm_madvise_ioctl
   - Disallow writes to read-only VMAs
   - PXP fixes
   - Disable garbage collector work item on SVM close
   - void memory allocations in xe_device_declare_wedged

  qaic:
   - hang fix

  ast:
   - initialisation fix"

* tag 'drm-fixes-2026-04-03' of https://gitlab.freedesktop.org/drm/kernel: (28 commits)
  drm/amd/display: Wire up dcn10_dio_construct() for all pre-DCN401 generations
  drm/ioc32: stop speculation on the drm_compat_ioctl path
  drm/sysfb: Fix efidrm error handling and memory type mismatch
  drm/i915/dp: Use crtc_state->enhanced_framing properly on ivb/hsw CPU eDP
  drm/i915/cdclk: Do the full CDCLK dance for min_voltage_level changes
  drm/amdkfd: Fix queue preemption/eviction failures by aligning control stack size to GPU page size
  drm/amdgpu: Fix wait after reset sequence in S4
  drm/amd/display: Fix NULL pointer dereference in dcn401_init_hw()
  drm/amdgpu: Change AMDGPU_VA_RESERVED_TRAP_SIZE to 64KB
  drm/amdgpu/userq: fix memory leak in MQD creation error paths
  drm/amd: Fix MQD and control stack alignment for non-4K
  drm/amdkfd: Align expected_queue_size to PAGE_SIZE
  drm/amdgpu: fix the idr allocation flags
  drm/amdgpu: validate doorbell_offset in user queue creation
  drm/amdgpu/pm: drop SMU driver if version not matched messages
  drm/xe: Avoid memory allocations in xe_device_declare_wedged()
  drm/xe: Disable garbage collector work item on SVM close
  drm/xe/pxp: Don't allow PXP on older PTL GSC FWs
  drm/xe/pxp: Clear restart flag in pxp_start after jumping back
  drm/xe/pxp: Remove incorrect handling of impossible state during suspend
  ...
parents d8a9a4b1 75f53c4b
Loading
Loading
Loading
Loading
+45 −2
Original line number Diff line number Diff line
@@ -914,7 +914,7 @@ static int decode_deactivate(struct qaic_device *qdev, void *trans, u32 *msg_len
		 */
		return -ENODEV;

	if (status) {
	if (usr && status) {
		/*
		 * Releasing resources failed on the device side, which puts
		 * us in a bind since they may still be in use, so enable the
@@ -1109,6 +1109,9 @@ static void *msg_xfer(struct qaic_device *qdev, struct wrapper_list *wrappers, u
	mutex_lock(&qdev->cntl_mutex);
	if (!list_empty(&elem.list))
		list_del(&elem.list);
	/* resp_worker() processed the response but the wait was interrupted */
	else if (ret == -ERESTARTSYS)
		ret = 0;
	if (!ret && !elem.buf)
		ret = -ETIMEDOUT;
	else if (ret > 0 && !elem.buf)
@@ -1419,9 +1422,49 @@ static void resp_worker(struct work_struct *work)
	}
	mutex_unlock(&qdev->cntl_mutex);

	if (!found)
	if (!found) {
		/*
		 * The user might have gone away at this point without waiting
		 * for QAIC_TRANS_DEACTIVATE_FROM_DEV transaction coming from
		 * the device. If this is not handled correctly, the host will
		 * not know that the DBC[n] has been freed on the device.
		 * Due to this failure in synchronization between the device and
		 * the host, if another user requests to activate a network, and
		 * the device assigns DBC[n] again, save_dbc_buf() will hang,
		 * waiting for dbc[n]->in_use to be set to false, which will not
		 * happen unless the qaic_dev_reset_clean_local_state() gets
		 * called by resetting the device (or re-inserting the module).
		 *
		 * As a solution, we look for QAIC_TRANS_DEACTIVATE_FROM_DEV
		 * transactions in the message before disposing of it, then
		 * handle releasing the DBC resources.
		 *
		 * Since the user has gone away, if the device could not
		 * deactivate the network (status != 0), there is no way to
		 * enable and reassign the DBC to the user. We can put trust in
		 * the device that it will release all the active DBCs in
		 * response to the QAIC_TRANS_TERMINATE_TO_DEV transaction,
		 * otherwise, the user can issue an soc_reset to the device.
		 */
		u32 msg_count = le32_to_cpu(msg->hdr.count);
		u32 msg_len = le32_to_cpu(msg->hdr.len);
		u32 len = 0;
		int j;

		for (j = 0; j < msg_count && len < msg_len; ++j) {
			struct wire_trans_hdr *trans_hdr;

			trans_hdr = (struct wire_trans_hdr *)(msg->data + len);
			if (le32_to_cpu(trans_hdr->type) == QAIC_TRANS_DEACTIVATE_FROM_DEV) {
				if (decode_deactivate(qdev, trans_hdr, &len, NULL))
					len += le32_to_cpu(trans_hdr->len);
			} else {
				len += le32_to_cpu(trans_hdr->len);
			}
		}
		/* request must have timed out, drop packet */
		kfree(msg);
	}

	kfree(resp);
}
+6 −2
Original line number Diff line number Diff line
@@ -2703,8 +2703,12 @@ static int amdgpu_pmops_freeze(struct device *dev)
	if (r)
		return r;

	if (amdgpu_acpi_should_gpu_reset(adev))
		return amdgpu_asic_reset(adev);
	if (amdgpu_acpi_should_gpu_reset(adev)) {
		amdgpu_device_lock_reset_domain(adev->reset_domain);
		r = amdgpu_asic_reset(adev);
		amdgpu_device_unlock_reset_domain(adev->reset_domain);
		return r;
	}
	return 0;
}

+44 −0
Original line number Diff line number Diff line
@@ -403,6 +403,50 @@ void amdgpu_gart_map_vram_range(struct amdgpu_device *adev, uint64_t pa,
	drm_dev_exit(idx);
}

/**
 * amdgpu_gart_map_gfx9_mqd - map mqd and ctrl_stack dma_addresses into GART entries
 *
 * @adev: amdgpu_device pointer
 * @offset: offset into the GPU's gart aperture
 * @pages: number of pages to bind
 * @dma_addr: DMA addresses of pages
 * @flags: page table entry flags
 *
 * Map the MQD and control stack addresses into GART entries with the correct
 * memory types on gfxv9. The MQD occupies the first 4KB and is followed by
 * the control stack. The MQD uses UC (uncached) memory, while the control stack
 * uses NC (non-coherent) memory.
 */
void amdgpu_gart_map_gfx9_mqd(struct amdgpu_device *adev, uint64_t offset,
			int pages, dma_addr_t *dma_addr, uint64_t flags)
{
	uint64_t page_base;
	unsigned int i, j, t;
	int idx;
	uint64_t ctrl_flags = AMDGPU_PTE_MTYPE_VG10(flags, AMDGPU_MTYPE_NC);
	void *dst;

	if (!adev->gart.ptr)
		return;

	if (!drm_dev_enter(adev_to_drm(adev), &idx))
		return;

	t = offset / AMDGPU_GPU_PAGE_SIZE;
	dst = adev->gart.ptr;
	for (i = 0; i < pages; i++) {
		page_base = dma_addr[i];
		for (j = 0; j < AMDGPU_GPU_PAGES_IN_CPU_PAGE; j++, t++) {
			if ((i == 0) && (j == 0))
				amdgpu_gmc_set_pte_pde(adev, dst, t, page_base, flags);
			else
				amdgpu_gmc_set_pte_pde(adev, dst, t, page_base, ctrl_flags);
			page_base += AMDGPU_GPU_PAGE_SIZE;
		}
	}
	drm_dev_exit(idx);
}

/**
 * amdgpu_gart_bind - bind pages into the gart page table
 *
+2 −0
Original line number Diff line number Diff line
@@ -62,6 +62,8 @@ void amdgpu_gart_unbind(struct amdgpu_device *adev, uint64_t offset,
void amdgpu_gart_map(struct amdgpu_device *adev, uint64_t offset,
		     int pages, dma_addr_t *dma_addr, uint64_t flags,
		     void *dst);
void amdgpu_gart_map_gfx9_mqd(struct amdgpu_device *adev, uint64_t offset,
			int pages, dma_addr_t *dma_addr, uint64_t flags);
void amdgpu_gart_bind(struct amdgpu_device *adev, uint64_t offset,
		      int pages, dma_addr_t *dma_addr, uint64_t flags);
void amdgpu_gart_map_vram_range(struct amdgpu_device *adev, uint64_t pa,
+4 −1
Original line number Diff line number Diff line
@@ -68,8 +68,11 @@ int amdgpu_pasid_alloc(unsigned int bits)
		return -EINVAL;

	spin_lock(&amdgpu_pasid_idr_lock);
	/* TODO: Need to replace the idr with an xarry, and then
	 * handle the internal locking with ATOMIC safe paths.
	 */
	pasid = idr_alloc_cyclic(&amdgpu_pasid_idr, NULL, 1,
				 1U << bits, GFP_KERNEL);
				 1U << bits, GFP_ATOMIC);
	spin_unlock(&amdgpu_pasid_idr_lock);

	if (pasid >= 0)
Loading