Commit ce944f3f authored by Linus Torvalds's avatar Linus Torvalds
Browse files

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

Pull drm fixes from Dave Airlie:
 "Regular week of fixes, seems to be about right for this time in the
  release cycle, amdgpu, and nouveau are the main one with some
  scattered fixes otherwise.

  ttm:
   - Stop pooling cached NUMA pages

  amdgpu:
   - Fix invalid resource->start check
   - USB-C DSC fix
   - Fix a potential UAF in VA IOCTL
   - Fix visible VRAM handling during faults

  amdkfd:
   - Fix memory leak in create_process failure

  radeon:
   - Silence UBSAN warnings from variable sized arrays

  nouveau:
   - dp: Don't probe DP ports twice
   - nv04: Fix OOB access
   - nv50: Disable AUX bus for disconnected DP ports
   - nvkm: Fix instmem race condition

  panel:
   - Don't unregister DSI devices in several drivers

  v3d:
   - Fix enabled_ns increment

  xe:
   - Fix bo leak on error path during fb init
   - Fix use-after-free due to order vm is put and destroyed"

* tag 'drm-fixes-2024-04-19' of https://gitlab.freedesktop.org/drm/kernel:
  drm/radeon: silence UBSAN warning (v3)
  drm/radeon: make -fstrict-flex-arrays=3 happy
  drm/amdgpu: fix visible VRAM handling during faults
  drm/amdgpu: validate the parameters of bo mapping operations more clearly
  Revert "drm/amd/display: fix USB-C flag update after enc10 feature init"
  drm/amdkfd: Fix memory leak in create_process failure
  drm/amdgpu: remove invalid resource->start check v2
  drm/xe/vm: prevent UAF with asid based lookup
  drm/xe: Fix bo leak in intel_fb_bo_framebuffer_init
  drm/panel: novatek-nt36682e: don't unregister DSI device
  drm/panel: visionox-rm69299: don't unregister DSI device
  drm/nouveau/dp: Don't probe eDP ports twice harder
  drm/nouveau/kms/nv50-: Disable AUX bus for disconnected DP ports
  drm/v3d: Don't increment `enabled_ns` twice
  drm/vmwgfx: Sort primary plane formats by order of preference
  drm/vmwgfx: Fix crtc's atomic check conditional
  drm/vmwgfx: Fix prime import/export
  drm/ttm: stop pooling cached NUMA pages v2
  drm: nv04: Fix out of bounds access
  nouveau: fix instmem race condition around ptr stores
parents 54c23548 52c8b6e1
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -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) {
+11 −11
Original line number Diff line number Diff line
@@ -617,8 +617,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
@@ -1272,23 +1271,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;
@@ -1389,10 +1390,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 */
@@ -1415,7 +1413,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);
@@ -1579,6 +1577,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;
@@ -1587,10 +1586,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";
+0 −22
Original line number Diff line number Diff line
@@ -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
 */
+38 −27
Original line number Diff line number Diff line
@@ -133,7 +133,7 @@ static void amdgpu_evict_flags(struct ttm_buffer_object *bo,

		} 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
@@ -403,40 +403,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)
/*
 * 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;
}

/*
@@ -529,8 +544,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;
		}
@@ -557,7 +572,6 @@ static int amdgpu_ttm_io_mem_reserve(struct ttm_device *bdev,
				     struct ttm_resource *mem)
{
	struct amdgpu_device *adev = amdgpu_ttm_adev(bdev);
	size_t bus_size = (size_t)mem->size;

	switch (mem->mem_type) {
	case TTM_PL_SYSTEM:
@@ -568,9 +582,6 @@ static int amdgpu_ttm_io_mem_reserve(struct ttm_device *bdev,
		break;
	case TTM_PL_VRAM:
		mem->bus.offset = mem->start << PAGE_SHIFT;
		/* check if it's visible */
		if ((mem->bus.offset + bus_size) > adev->gmc.visible_vram_size)
			return -EINVAL;

		if (adev->mman.aper_base_kaddr &&
		    mem->placement & TTM_PL_FLAG_CONTIGUOUS)
+3 −0
Original line number Diff line number Diff line
@@ -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,
Loading