Commit ac3a75bd authored by Dave Airlie's avatar Dave Airlie
Browse files

Merge tag 'drm-misc-fixes-2025-03-06' of...

Merge tag 'drm-misc-fixes-2025-03-06' of https://gitlab.freedesktop.org/drm/misc/kernel

 into drm-fixes

A Kconfig fix for nouveau, locking and timestamp fixes for imagination,
a header guard fix for sched and a DPMS regression fix for bochs.

Signed-off-by: default avatarDave Airlie <airlied@redhat.com>

From: Maxime Ripard <mripard@redhat.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20250306-antelope-of-imminent-anger-bca19e@houat
parents 7eb17214 80da96d7
Loading
Loading
Loading
Loading
+4 −2
Original line number Diff line number Diff line
@@ -527,8 +527,10 @@ pvr_meta_vm_map(struct pvr_device *pvr_dev, struct pvr_fw_object *fw_obj)
static void
pvr_meta_vm_unmap(struct pvr_device *pvr_dev, struct pvr_fw_object *fw_obj)
{
	pvr_vm_unmap(pvr_dev->kernel_vm_ctx, fw_obj->fw_mm_node.start,
		     fw_obj->fw_mm_node.size);
	struct pvr_gem_object *pvr_obj = fw_obj->gem;

	pvr_vm_unmap_obj(pvr_dev->kernel_vm_ctx, pvr_obj,
			 fw_obj->fw_mm_node.start, fw_obj->fw_mm_node.size);
}

static bool
+2 −2
Original line number Diff line number Diff line
@@ -333,8 +333,8 @@ static int fw_trace_seq_show(struct seq_file *s, void *v)
	if (sf_id == ROGUE_FW_SF_LAST)
		return -EINVAL;

	timestamp = read_fw_trace(trace_seq_data, 1) |
		((u64)read_fw_trace(trace_seq_data, 2) << 32);
	timestamp = ((u64)read_fw_trace(trace_seq_data, 1) << 32) |
		read_fw_trace(trace_seq_data, 2);
	timestamp = (timestamp & ~ROGUE_FWT_TIMESTAMP_TIME_CLRMSK) >>
		ROGUE_FWT_TIMESTAMP_TIME_SHIFT;

+14 −4
Original line number Diff line number Diff line
@@ -109,12 +109,20 @@ pvr_queue_fence_get_driver_name(struct dma_fence *f)
	return PVR_DRIVER_NAME;
}

static void pvr_queue_fence_release_work(struct work_struct *w)
{
	struct pvr_queue_fence *fence = container_of(w, struct pvr_queue_fence, release_work);

	pvr_context_put(fence->queue->ctx);
	dma_fence_free(&fence->base);
}

static void pvr_queue_fence_release(struct dma_fence *f)
{
	struct pvr_queue_fence *fence = container_of(f, struct pvr_queue_fence, base);
	struct pvr_device *pvr_dev = fence->queue->ctx->pvr_dev;

	pvr_context_put(fence->queue->ctx);
	dma_fence_free(f);
	queue_work(pvr_dev->sched_wq, &fence->release_work);
}

static const char *
@@ -268,6 +276,7 @@ pvr_queue_fence_init(struct dma_fence *f,

	pvr_context_get(queue->ctx);
	fence->queue = queue;
	INIT_WORK(&fence->release_work, pvr_queue_fence_release_work);
	dma_fence_init(&fence->base, fence_ops,
		       &fence_ctx->lock, fence_ctx->id,
		       atomic_inc_return(&fence_ctx->seqno));
@@ -304,6 +313,7 @@ pvr_queue_cccb_fence_init(struct dma_fence *fence, struct pvr_queue *queue)
static void
pvr_queue_job_fence_init(struct dma_fence *fence, struct pvr_queue *queue)
{
	if (!fence->ops)
		pvr_queue_fence_init(fence, queue, &pvr_queue_job_fence_ops,
				     &queue->job_fence_ctx);
}
+4 −0
Original line number Diff line number Diff line
@@ -5,6 +5,7 @@
#define PVR_QUEUE_H

#include <drm/gpu_scheduler.h>
#include <linux/workqueue.h>

#include "pvr_cccb.h"
#include "pvr_device.h"
@@ -63,6 +64,9 @@ struct pvr_queue_fence {

	/** @queue: Queue that created this fence. */
	struct pvr_queue *queue;

	/** @release_work: Fence release work structure. */
	struct work_struct release_work;
};

/**
+108 −26
Original line number Diff line number Diff line
@@ -293,8 +293,9 @@ pvr_vm_bind_op_map_init(struct pvr_vm_bind_op *bind_op,

static int
pvr_vm_bind_op_unmap_init(struct pvr_vm_bind_op *bind_op,
			  struct pvr_vm_context *vm_ctx, u64 device_addr,
			  u64 size)
			  struct pvr_vm_context *vm_ctx,
			  struct pvr_gem_object *pvr_obj,
			  u64 device_addr, u64 size)
{
	int err;

@@ -318,6 +319,7 @@ pvr_vm_bind_op_unmap_init(struct pvr_vm_bind_op *bind_op,
		goto err_bind_op_fini;
	}

	bind_op->pvr_obj = pvr_obj;
	bind_op->vm_ctx = vm_ctx;
	bind_op->device_addr = device_addr;
	bind_op->size = size;
@@ -597,20 +599,6 @@ pvr_vm_create_context(struct pvr_device *pvr_dev, bool is_userspace_context)
	return ERR_PTR(err);
}

/**
 * pvr_vm_unmap_all() - Unmap all mappings associated with a VM context.
 * @vm_ctx: Target VM context.
 *
 * This function ensures that no mappings are left dangling by unmapping them
 * all in order of ascending device-virtual address.
 */
void
pvr_vm_unmap_all(struct pvr_vm_context *vm_ctx)
{
	WARN_ON(pvr_vm_unmap(vm_ctx, vm_ctx->gpuvm_mgr.mm_start,
			     vm_ctx->gpuvm_mgr.mm_range));
}

/**
 * pvr_vm_context_release() - Teardown a VM context.
 * @ref_count: Pointer to reference counter of the VM context.
@@ -703,11 +691,7 @@ pvr_vm_lock_extra(struct drm_gpuvm_exec *vm_exec)
	struct pvr_vm_bind_op *bind_op = vm_exec->extra.priv;
	struct pvr_gem_object *pvr_obj = bind_op->pvr_obj;

	/* Unmap operations don't have an object to lock. */
	if (!pvr_obj)
		return 0;

	/* Acquire lock on the GEM being mapped. */
	/* Acquire lock on the GEM object being mapped/unmapped. */
	return drm_exec_lock_obj(&vm_exec->exec, gem_from_pvr_gem(pvr_obj));
}

@@ -772,8 +756,10 @@ pvr_vm_map(struct pvr_vm_context *vm_ctx, struct pvr_gem_object *pvr_obj,
}

/**
 * pvr_vm_unmap() - Unmap an already mapped section of device-virtual memory.
 * pvr_vm_unmap_obj_locked() - Unmap an already mapped section of device-virtual
 * memory.
 * @vm_ctx: Target VM context.
 * @pvr_obj: Target PowerVR memory object.
 * @device_addr: Virtual device address at the start of the target mapping.
 * @size: Size of the target mapping.
 *
@@ -784,9 +770,13 @@ pvr_vm_map(struct pvr_vm_context *vm_ctx, struct pvr_gem_object *pvr_obj,
 *  * Any error encountered while performing internal operations required to
 *    destroy the mapping (returned from pvr_vm_gpuva_unmap or
 *    pvr_vm_gpuva_remap).
 *
 * The vm_ctx->lock must be held when calling this function.
 */
int
pvr_vm_unmap(struct pvr_vm_context *vm_ctx, u64 device_addr, u64 size)
static int
pvr_vm_unmap_obj_locked(struct pvr_vm_context *vm_ctx,
			struct pvr_gem_object *pvr_obj,
			u64 device_addr, u64 size)
{
	struct pvr_vm_bind_op bind_op = {0};
	struct drm_gpuvm_exec vm_exec = {
@@ -799,11 +789,13 @@ pvr_vm_unmap(struct pvr_vm_context *vm_ctx, u64 device_addr, u64 size)
		},
	};

	int err = pvr_vm_bind_op_unmap_init(&bind_op, vm_ctx, device_addr,
					    size);
	int err = pvr_vm_bind_op_unmap_init(&bind_op, vm_ctx, pvr_obj,
					    device_addr, size);
	if (err)
		return err;

	pvr_gem_object_get(pvr_obj);

	err = drm_gpuvm_exec_lock(&vm_exec);
	if (err)
		goto err_cleanup;
@@ -818,6 +810,96 @@ pvr_vm_unmap(struct pvr_vm_context *vm_ctx, u64 device_addr, u64 size)
	return err;
}

/**
 * pvr_vm_unmap_obj() - Unmap an already mapped section of device-virtual
 * memory.
 * @vm_ctx: Target VM context.
 * @pvr_obj: Target PowerVR memory object.
 * @device_addr: Virtual device address at the start of the target mapping.
 * @size: Size of the target mapping.
 *
 * Return:
 *  * 0 on success,
 *  * Any error encountered by pvr_vm_unmap_obj_locked.
 */
int
pvr_vm_unmap_obj(struct pvr_vm_context *vm_ctx, struct pvr_gem_object *pvr_obj,
		 u64 device_addr, u64 size)
{
	int err;

	mutex_lock(&vm_ctx->lock);
	err = pvr_vm_unmap_obj_locked(vm_ctx, pvr_obj, device_addr, size);
	mutex_unlock(&vm_ctx->lock);

	return err;
}

/**
 * pvr_vm_unmap() - Unmap an already mapped section of device-virtual memory.
 * @vm_ctx: Target VM context.
 * @device_addr: Virtual device address at the start of the target mapping.
 * @size: Size of the target mapping.
 *
 * Return:
 *  * 0 on success,
 *  * Any error encountered by drm_gpuva_find,
 *  * Any error encountered by pvr_vm_unmap_obj_locked.
 */
int
pvr_vm_unmap(struct pvr_vm_context *vm_ctx, u64 device_addr, u64 size)
{
	struct pvr_gem_object *pvr_obj;
	struct drm_gpuva *va;
	int err;

	mutex_lock(&vm_ctx->lock);

	va = drm_gpuva_find(&vm_ctx->gpuvm_mgr, device_addr, size);
	if (va) {
		pvr_obj = gem_to_pvr_gem(va->gem.obj);
		err = pvr_vm_unmap_obj_locked(vm_ctx, pvr_obj,
					      va->va.addr, va->va.range);
	} else {
		err = -ENOENT;
	}

	mutex_unlock(&vm_ctx->lock);

	return err;
}

/**
 * pvr_vm_unmap_all() - Unmap all mappings associated with a VM context.
 * @vm_ctx: Target VM context.
 *
 * This function ensures that no mappings are left dangling by unmapping them
 * all in order of ascending device-virtual address.
 */
void
pvr_vm_unmap_all(struct pvr_vm_context *vm_ctx)
{
	mutex_lock(&vm_ctx->lock);

	for (;;) {
		struct pvr_gem_object *pvr_obj;
		struct drm_gpuva *va;

		va = drm_gpuva_find_first(&vm_ctx->gpuvm_mgr,
					  vm_ctx->gpuvm_mgr.mm_start,
					  vm_ctx->gpuvm_mgr.mm_range);
		if (!va)
			break;

		pvr_obj = gem_to_pvr_gem(va->gem.obj);

		WARN_ON(pvr_vm_unmap_obj_locked(vm_ctx, pvr_obj,
						va->va.addr, va->va.range));
	}

	mutex_unlock(&vm_ctx->lock);
}

/* Static data areas are determined by firmware. */
static const struct drm_pvr_static_data_area static_data_areas[] = {
	{
Loading