// SPDX-License-Identifier: MIT
/*
 * Copyright © 2021 Intel Corporation
 */

#include "xe_bo.h"

#include <linux/dma-buf.h>

#include <drm/drm_drv.h>
#include <drm/drm_gem_ttm_helper.h>
#include <drm/drm_managed.h>
#include <drm/ttm/ttm_device.h>
#include <drm/ttm/ttm_placement.h>
#include <drm/ttm/ttm_tt.h>
#include <drm/xe_drm.h>

#include "xe_device.h"
#include "xe_dma_buf.h"
#include "xe_drm_client.h"
#include "xe_ggtt.h"
#include "xe_gt.h"
#include "xe_map.h"
#include "xe_migrate.h"
#include "xe_preempt_fence.h"
#include "xe_res_cursor.h"
#include "xe_trace.h"
#include "xe_ttm_stolen_mgr.h"
#include "xe_vm.h"

const char *const xe_mem_type_to_name[TTM_NUM_MEM_TYPES]  = {
	[XE_PL_SYSTEM] = "system",
	[XE_PL_TT] = "gtt",
	[XE_PL_VRAM0] = "vram0",
	[XE_PL_VRAM1] = "vram1",
	[XE_PL_STOLEN] = "stolen"
};

static const struct ttm_place sys_placement_flags = {
	.fpfn = 0,
	.lpfn = 0,
	.mem_type = XE_PL_SYSTEM,
	.flags = 0,
};

static struct ttm_placement sys_placement = {
	.num_placement = 1,
	.placement = &sys_placement_flags,
	.num_busy_placement = 1,
	.busy_placement = &sys_placement_flags,
};

static const struct ttm_place tt_placement_flags = {
	.fpfn = 0,
	.lpfn = 0,
	.mem_type = XE_PL_TT,
	.flags = 0,
};

static struct ttm_placement tt_placement = {
	.num_placement = 1,
	.placement = &tt_placement_flags,
	.num_busy_placement = 1,
	.busy_placement = &sys_placement_flags,
};

bool mem_type_is_vram(u32 mem_type)
{
	return mem_type >= XE_PL_VRAM0 && mem_type != XE_PL_STOLEN;
}

static bool resource_is_stolen_vram(struct xe_device *xe, struct ttm_resource *res)
{
	return res->mem_type == XE_PL_STOLEN && IS_DGFX(xe);
}

static bool resource_is_vram(struct ttm_resource *res)
{
	return mem_type_is_vram(res->mem_type);
}

bool xe_bo_is_vram(struct xe_bo *bo)
{
	return resource_is_vram(bo->ttm.resource) ||
		resource_is_stolen_vram(xe_bo_device(bo), bo->ttm.resource);
}

bool xe_bo_is_stolen(struct xe_bo *bo)
{
	return bo->ttm.resource->mem_type == XE_PL_STOLEN;
}

/**
 * xe_bo_is_stolen_devmem - check if BO is of stolen type accessed via PCI BAR
 * @bo: The BO
 *
 * The stolen memory is accessed through the PCI BAR for both DGFX and some
 * integrated platforms that have a dedicated bit in the PTE for devmem (DM).
 *
 * Returns: true if it's stolen memory accessed via PCI BAR, false otherwise.
 */
bool xe_bo_is_stolen_devmem(struct xe_bo *bo)
{
	return xe_bo_is_stolen(bo) &&
		GRAPHICS_VERx100(xe_bo_device(bo)) >= 1270;
}

static bool xe_bo_is_user(struct xe_bo *bo)
{
	return bo->flags & XE_BO_CREATE_USER_BIT;
}

static struct xe_migrate *
mem_type_to_migrate(struct xe_device *xe, u32 mem_type)
{
	struct xe_tile *tile;

	xe_assert(xe, mem_type == XE_PL_STOLEN || mem_type_is_vram(mem_type));
	tile = &xe->tiles[mem_type == XE_PL_STOLEN ? 0 : (mem_type - XE_PL_VRAM0)];
	return tile->migrate;
}

static struct xe_mem_region *res_to_mem_region(struct ttm_resource *res)
{
	struct xe_device *xe = ttm_to_xe_device(res->bo->bdev);
	struct ttm_resource_manager *mgr;

	xe_assert(xe, resource_is_vram(res));
	mgr = ttm_manager_type(&xe->ttm, res->mem_type);
	return to_xe_ttm_vram_mgr(mgr)->vram;
}

static void try_add_system(struct xe_device *xe, struct xe_bo *bo,
			   u32 bo_flags, u32 *c)
{
	if (bo_flags & XE_BO_CREATE_SYSTEM_BIT) {
		xe_assert(xe, *c < ARRAY_SIZE(bo->placements));

		bo->placements[*c] = (struct ttm_place) {
			.mem_type = XE_PL_TT,
		};
		*c += 1;

		if (bo->props.preferred_mem_type == XE_BO_PROPS_INVALID)
			bo->props.preferred_mem_type = XE_PL_TT;
	}
}

static void add_vram(struct xe_device *xe, struct xe_bo *bo,
		     struct ttm_place *places, u32 bo_flags, u32 mem_type, u32 *c)
{
	struct ttm_place place = { .mem_type = mem_type };
	struct xe_mem_region *vram;
	u64 io_size;

	xe_assert(xe, *c < ARRAY_SIZE(bo->placements));

	vram = to_xe_ttm_vram_mgr(ttm_manager_type(&xe->ttm, mem_type))->vram;
	xe_assert(xe, vram && vram->usable_size);
	io_size = vram->io_size;

	/*
	 * For eviction / restore on suspend / resume objects
	 * pinned in VRAM must be contiguous
	 */
	if (bo_flags & (XE_BO_CREATE_PINNED_BIT |
			XE_BO_CREATE_GGTT_BIT))
		place.flags |= TTM_PL_FLAG_CONTIGUOUS;

	if (io_size < vram->usable_size) {
		if (bo_flags & XE_BO_NEEDS_CPU_ACCESS) {
			place.fpfn = 0;
			place.lpfn = io_size >> PAGE_SHIFT;
		} else {
			place.flags |= TTM_PL_FLAG_TOPDOWN;
		}
	}
	places[*c] = place;
	*c += 1;

	if (bo->props.preferred_mem_type == XE_BO_PROPS_INVALID)
		bo->props.preferred_mem_type = mem_type;
}

static void try_add_vram(struct xe_device *xe, struct xe_bo *bo,
			 u32 bo_flags, u32 *c)
{
	if (bo->props.preferred_gt == XE_GT1) {
		if (bo_flags & XE_BO_CREATE_VRAM1_BIT)
			add_vram(xe, bo, bo->placements, bo_flags, XE_PL_VRAM1, c);
		if (bo_flags & XE_BO_CREATE_VRAM0_BIT)
			add_vram(xe, bo, bo->placements, bo_flags, XE_PL_VRAM0, c);
	} else {
		if (bo_flags & XE_BO_CREATE_VRAM0_BIT)
			add_vram(xe, bo, bo->placements, bo_flags, XE_PL_VRAM0, c);
		if (bo_flags & XE_BO_CREATE_VRAM1_BIT)
			add_vram(xe, bo, bo->placements, bo_flags, XE_PL_VRAM1, c);
	}
}

static void try_add_stolen(struct xe_device *xe, struct xe_bo *bo,
			   u32 bo_flags, u32 *c)
{
	if (bo_flags & XE_BO_CREATE_STOLEN_BIT) {
		xe_assert(xe, *c < ARRAY_SIZE(bo->placements));

		bo->placements[*c] = (struct ttm_place) {
			.mem_type = XE_PL_STOLEN,
			.flags = bo_flags & (XE_BO_CREATE_PINNED_BIT |
					     XE_BO_CREATE_GGTT_BIT) ?
				TTM_PL_FLAG_CONTIGUOUS : 0,
		};
		*c += 1;
	}
}

static int __xe_bo_placement_for_flags(struct xe_device *xe, struct xe_bo *bo,
				       u32 bo_flags)
{
	u32 c = 0;

	bo->props.preferred_mem_type = XE_BO_PROPS_INVALID;

	/* The order of placements should indicate preferred location */

	if (bo->props.preferred_mem_class == DRM_XE_MEM_REGION_CLASS_SYSMEM) {
		try_add_system(xe, bo, bo_flags, &c);
		try_add_vram(xe, bo, bo_flags, &c);
	} else {
		try_add_vram(xe, bo, bo_flags, &c);
		try_add_system(xe, bo, bo_flags, &c);
	}
	try_add_stolen(xe, bo, bo_flags, &c);

	if (!c)
		return -EINVAL;

	bo->placement = (struct ttm_placement) {
		.num_placement = c,
		.placement = bo->placements,
		.num_busy_placement = c,
		.busy_placement = bo->placements,
	};

	return 0;
}

int xe_bo_placement_for_flags(struct xe_device *xe, struct xe_bo *bo,
			      u32 bo_flags)
{
	xe_bo_assert_held(bo);
	return __xe_bo_placement_for_flags(xe, bo, bo_flags);
}

static void xe_evict_flags(struct ttm_buffer_object *tbo,
			   struct ttm_placement *placement)
{
	if (!xe_bo_is_xe_bo(tbo)) {
		/* Don't handle scatter gather BOs */
		if (tbo->type == ttm_bo_type_sg) {
			placement->num_placement = 0;
			placement->num_busy_placement = 0;
			return;
		}

		*placement = sys_placement;
		return;
	}

	/*
	 * For xe, sg bos that are evicted to system just triggers a
	 * rebind of the sg list upon subsequent validation to XE_PL_TT.
	 */
	switch (tbo->resource->mem_type) {
	case XE_PL_VRAM0:
	case XE_PL_VRAM1:
	case XE_PL_STOLEN:
		*placement = tt_placement;
		break;
	case XE_PL_TT:
	default:
		*placement = sys_placement;
		break;
	}
}

struct xe_ttm_tt {
	struct ttm_tt ttm;
	struct device *dev;
	struct sg_table sgt;
	struct sg_table *sg;
};

static int xe_tt_map_sg(struct ttm_tt *tt)
{
	struct xe_ttm_tt *xe_tt = container_of(tt, struct xe_ttm_tt, ttm);
	unsigned long num_pages = tt->num_pages;
	int ret;

	XE_WARN_ON(tt->page_flags & TTM_TT_FLAG_EXTERNAL);

	if (xe_tt->sg)
		return 0;

	ret = sg_alloc_table_from_pages_segment(&xe_tt->sgt, tt->pages,
						num_pages, 0,
						(u64)num_pages << PAGE_SHIFT,
						xe_sg_segment_size(xe_tt->dev),
						GFP_KERNEL);
	if (ret)
		return ret;

	xe_tt->sg = &xe_tt->sgt;
	ret = dma_map_sgtable(xe_tt->dev, xe_tt->sg, DMA_BIDIRECTIONAL,
			      DMA_ATTR_SKIP_CPU_SYNC);
	if (ret) {
		sg_free_table(xe_tt->sg);
		xe_tt->sg = NULL;
		return ret;
	}

	return 0;
}

struct sg_table *xe_bo_sg(struct xe_bo *bo)
{
	struct ttm_tt *tt = bo->ttm.ttm;
	struct xe_ttm_tt *xe_tt = container_of(tt, struct xe_ttm_tt, ttm);

	return xe_tt->sg;
}

static struct ttm_tt *xe_ttm_tt_create(struct ttm_buffer_object *ttm_bo,
				       u32 page_flags)
{
	struct xe_bo *bo = ttm_to_xe_bo(ttm_bo);
	struct xe_device *xe = xe_bo_device(bo);
	struct xe_ttm_tt *tt;
	unsigned long extra_pages;
	enum ttm_caching caching;
	int err;

	tt = kzalloc(sizeof(*tt), GFP_KERNEL);
	if (!tt)
		return NULL;

	tt->dev = xe->drm.dev;

	extra_pages = 0;
	if (xe_bo_needs_ccs_pages(bo))
		extra_pages = DIV_ROUND_UP(xe_device_ccs_bytes(xe, bo->size),
					   PAGE_SIZE);

	switch (bo->cpu_caching) {
	case DRM_XE_GEM_CPU_CACHING_WC:
		caching = ttm_write_combined;
		break;
	default:
		caching = ttm_cached;
		break;
	}

	WARN_ON((bo->flags & XE_BO_CREATE_USER_BIT) && !bo->cpu_caching);

	/*
	 * Display scanout is always non-coherent with the CPU cache.
	 *
	 * For Xe_LPG and beyond, PPGTT PTE lookups are also non-coherent and
	 * require a CPU:WC mapping.
	 */
	if ((!bo->cpu_caching && bo->flags & XE_BO_SCANOUT_BIT) ||
	    (xe->info.graphics_verx100 >= 1270 && bo->flags & XE_BO_PAGETABLE))
		caching = ttm_write_combined;

	err = ttm_tt_init(&tt->ttm, &bo->ttm, page_flags, caching, extra_pages);
	if (err) {
		kfree(tt);
		return NULL;
	}

	return &tt->ttm;
}

static int xe_ttm_tt_populate(struct ttm_device *ttm_dev, struct ttm_tt *tt,
			      struct ttm_operation_ctx *ctx)
{
	int err;

	/*
	 * dma-bufs are not populated with pages, and the dma-
	 * addresses are set up when moved to XE_PL_TT.
	 */
	if (tt->page_flags & TTM_TT_FLAG_EXTERNAL)
		return 0;

	err = ttm_pool_alloc(&ttm_dev->pool, tt, ctx);
	if (err)
		return err;

	/* A follow up may move this xe_bo_move when BO is moved to XE_PL_TT */
	err = xe_tt_map_sg(tt);
	if (err)
		ttm_pool_free(&ttm_dev->pool, tt);

	return err;
}

static void xe_ttm_tt_unpopulate(struct ttm_device *ttm_dev, struct ttm_tt *tt)
{
	struct xe_ttm_tt *xe_tt = container_of(tt, struct xe_ttm_tt, ttm);

	if (tt->page_flags & TTM_TT_FLAG_EXTERNAL)
		return;

	if (xe_tt->sg) {
		dma_unmap_sgtable(xe_tt->dev, xe_tt->sg,
				  DMA_BIDIRECTIONAL, 0);
		sg_free_table(xe_tt->sg);
		xe_tt->sg = NULL;
	}

	return ttm_pool_free(&ttm_dev->pool, tt);
}

static void xe_ttm_tt_destroy(struct ttm_device *ttm_dev, struct ttm_tt *tt)
{
	ttm_tt_fini(tt);
	kfree(tt);
}

static int xe_ttm_io_mem_reserve(struct ttm_device *bdev,
				 struct ttm_resource *mem)
{
	struct xe_device *xe = ttm_to_xe_device(bdev);

	switch (mem->mem_type) {
	case XE_PL_SYSTEM:
	case XE_PL_TT:
		return 0;
	case XE_PL_VRAM0:
	case XE_PL_VRAM1: {
		struct xe_ttm_vram_mgr_resource *vres =
			to_xe_ttm_vram_mgr_resource(mem);
		struct xe_mem_region *vram = res_to_mem_region(mem);

		if (vres->used_visible_size < mem->size)
			return -EINVAL;

		mem->bus.offset = mem->start << PAGE_SHIFT;

		if (vram->mapping &&
		    mem->placement & TTM_PL_FLAG_CONTIGUOUS)
			mem->bus.addr = (u8 __force *)vram->mapping +
				mem->bus.offset;

		mem->bus.offset += vram->io_start;
		mem->bus.is_iomem = true;

#if  !defined(CONFIG_X86)
		mem->bus.caching = ttm_write_combined;
#endif
		return 0;
	} case XE_PL_STOLEN:
		return xe_ttm_stolen_io_mem_reserve(xe, mem);
	default:
		return -EINVAL;
	}
}

static int xe_bo_trigger_rebind(struct xe_device *xe, struct xe_bo *bo,
				const struct ttm_operation_ctx *ctx)
{
	struct dma_resv_iter cursor;
	struct dma_fence *fence;
	struct drm_gem_object *obj = &bo->ttm.base;
	struct drm_gpuvm_bo *vm_bo;
	bool idle = false;
	int ret = 0;

	dma_resv_assert_held(bo->ttm.base.resv);

	if (!list_empty(&bo->ttm.base.gpuva.list)) {
		dma_resv_iter_begin(&cursor, bo->ttm.base.resv,
				    DMA_RESV_USAGE_BOOKKEEP);
		dma_resv_for_each_fence_unlocked(&cursor, fence)
			dma_fence_enable_sw_signaling(fence);
		dma_resv_iter_end(&cursor);
	}

	drm_gem_for_each_gpuvm_bo(vm_bo, obj) {
		struct xe_vm *vm = gpuvm_to_vm(vm_bo->vm);
		struct drm_gpuva *gpuva;

		if (!xe_vm_in_fault_mode(vm)) {
			drm_gpuvm_bo_evict(vm_bo, true);
			continue;
		}

		if (!idle) {
			long timeout;

			if (ctx->no_wait_gpu &&
			    !dma_resv_test_signaled(bo->ttm.base.resv,
						    DMA_RESV_USAGE_BOOKKEEP))
				return -EBUSY;

			timeout = dma_resv_wait_timeout(bo->ttm.base.resv,
							DMA_RESV_USAGE_BOOKKEEP,
							ctx->interruptible,
							MAX_SCHEDULE_TIMEOUT);
			if (!timeout)
				return -ETIME;
			if (timeout < 0)
				return timeout;

			idle = true;
		}

		drm_gpuvm_bo_for_each_va(gpuva, vm_bo) {
			struct xe_vma *vma = gpuva_to_vma(gpuva);

			trace_xe_vma_evict(vma);
			ret = xe_vm_invalidate_vma(vma);
			if (XE_WARN_ON(ret))
				return ret;
		}
	}

	return ret;
}

/*
 * The dma-buf map_attachment() / unmap_attachment() is hooked up here.
 * Note that unmapping the attachment is deferred to the next
 * map_attachment time, or to bo destroy (after idling) whichever comes first.
 * This is to avoid syncing before unmap_attachment(), assuming that the
 * caller relies on idling the reservation object before moving the
 * backing store out. Should that assumption not hold, then we will be able
 * to unconditionally call unmap_attachment() when moving out to system.
 */
static int xe_bo_move_dmabuf(struct ttm_buffer_object *ttm_bo,
			     struct ttm_resource *new_res)
{
	struct dma_buf_attachment *attach = ttm_bo->base.import_attach;
	struct xe_ttm_tt *xe_tt = container_of(ttm_bo->ttm, struct xe_ttm_tt,
					       ttm);
	struct xe_device *xe = ttm_to_xe_device(ttm_bo->bdev);
	struct sg_table *sg;

	xe_assert(xe, attach);
	xe_assert(xe, ttm_bo->ttm);

	if (new_res->mem_type == XE_PL_SYSTEM)
		goto out;

	if (ttm_bo->sg) {
		dma_buf_unmap_attachment(attach, ttm_bo->sg, DMA_BIDIRECTIONAL);
		ttm_bo->sg = NULL;
	}

	sg = dma_buf_map_attachment(attach, DMA_BIDIRECTIONAL);
	if (IS_ERR(sg))
		return PTR_ERR(sg);

	ttm_bo->sg = sg;
	xe_tt->sg = sg;

out:
	ttm_bo_move_null(ttm_bo, new_res);

	return 0;
}

/**
 * xe_bo_move_notify - Notify subsystems of a pending move
 * @bo: The buffer object
 * @ctx: The struct ttm_operation_ctx controlling locking and waits.
 *
 * This function notifies subsystems of an upcoming buffer move.
 * Upon receiving such a notification, subsystems should schedule
 * halting access to the underlying pages and optionally add a fence
 * to the buffer object's dma_resv object, that signals when access is
 * stopped. The caller will wait on all dma_resv fences before
 * starting the move.
 *
 * A subsystem may commence access to the object after obtaining
 * bindings to the new backing memory under the object lock.
 *
 * Return: 0 on success, -EINTR or -ERESTARTSYS if interrupted in fault mode,
 * negative error code on error.
 */
static int xe_bo_move_notify(struct xe_bo *bo,
			     const struct ttm_operation_ctx *ctx)
{
	struct ttm_buffer_object *ttm_bo = &bo->ttm;
	struct xe_device *xe = ttm_to_xe_device(ttm_bo->bdev);
	int ret;

	/*
	 * If this starts to call into many components, consider
	 * using a notification chain here.
	 */

	if (xe_bo_is_pinned(bo))
		return -EINVAL;

	xe_bo_vunmap(bo);
	ret = xe_bo_trigger_rebind(xe, bo, ctx);
	if (ret)
		return ret;

	/* Don't call move_notify() for imported dma-bufs. */
	if (ttm_bo->base.dma_buf && !ttm_bo->base.import_attach)
		dma_buf_move_notify(ttm_bo->base.dma_buf);

	return 0;
}

static int xe_bo_move(struct ttm_buffer_object *ttm_bo, bool evict,
		      struct ttm_operation_ctx *ctx,
		      struct ttm_resource *new_mem,
		      struct ttm_place *hop)
{
	struct xe_device *xe = ttm_to_xe_device(ttm_bo->bdev);
	struct xe_bo *bo = ttm_to_xe_bo(ttm_bo);
	struct ttm_resource *old_mem = ttm_bo->resource;
	u32 old_mem_type = old_mem ? old_mem->mem_type : XE_PL_SYSTEM;
	struct ttm_tt *ttm = ttm_bo->ttm;
	struct xe_migrate *migrate = NULL;
	struct dma_fence *fence;
	bool move_lacks_source;
	bool tt_has_data;
	bool needs_clear;
	bool handle_system_ccs = (!IS_DGFX(xe) && xe_bo_needs_ccs_pages(bo) &&
				  ttm && ttm_tt_is_populated(ttm)) ? true : false;
	int ret = 0;
	/* Bo creation path, moving to system or TT. */
	if ((!old_mem && ttm) && !handle_system_ccs) {
		ttm_bo_move_null(ttm_bo, new_mem);
		return 0;
	}

	if (ttm_bo->type == ttm_bo_type_sg) {
		ret = xe_bo_move_notify(bo, ctx);
		if (!ret)
			ret = xe_bo_move_dmabuf(ttm_bo, new_mem);
		goto out;
	}

	tt_has_data = ttm && (ttm_tt_is_populated(ttm) ||
			      (ttm->page_flags & TTM_TT_FLAG_SWAPPED));

	move_lacks_source = handle_system_ccs ? (!bo->ccs_cleared)  :
						(!mem_type_is_vram(old_mem_type) && !tt_has_data);

	needs_clear = (ttm && ttm->page_flags & TTM_TT_FLAG_ZERO_ALLOC) ||
		(!ttm && ttm_bo->type == ttm_bo_type_device);

	if ((move_lacks_source && !needs_clear)) {
		ttm_bo_move_null(ttm_bo, new_mem);
		goto out;
	}

	if (old_mem_type == XE_PL_SYSTEM && new_mem->mem_type == XE_PL_TT && !handle_system_ccs) {
		ttm_bo_move_null(ttm_bo, new_mem);
		goto out;
	}

	/*
	 * Failed multi-hop where the old_mem is still marked as
	 * TTM_PL_FLAG_TEMPORARY, should just be a dummy move.
	 */
	if (old_mem_type == XE_PL_TT &&
	    new_mem->mem_type == XE_PL_TT) {
		ttm_bo_move_null(ttm_bo, new_mem);
		goto out;
	}

	if (!move_lacks_source && !xe_bo_is_pinned(bo)) {
		ret = xe_bo_move_notify(bo, ctx);
		if (ret)
			goto out;
	}

	if (old_mem_type == XE_PL_TT &&
	    new_mem->mem_type == XE_PL_SYSTEM) {
		long timeout = dma_resv_wait_timeout(ttm_bo->base.resv,
						     DMA_RESV_USAGE_BOOKKEEP,
						     true,
						     MAX_SCHEDULE_TIMEOUT);
		if (timeout < 0) {
			ret = timeout;
			goto out;
		}

		if (!handle_system_ccs) {
			ttm_bo_move_null(ttm_bo, new_mem);
			goto out;
		}
	}

	if (!move_lacks_source &&
	    ((old_mem_type == XE_PL_SYSTEM && resource_is_vram(new_mem)) ||
	     (mem_type_is_vram(old_mem_type) &&
	      new_mem->mem_type == XE_PL_SYSTEM))) {
		hop->fpfn = 0;
		hop->lpfn = 0;
		hop->mem_type = XE_PL_TT;
		hop->flags = TTM_PL_FLAG_TEMPORARY;
		ret = -EMULTIHOP;
		goto out;
	}

	if (bo->tile)
		migrate = bo->tile->migrate;
	else if (resource_is_vram(new_mem))
		migrate = mem_type_to_migrate(xe, new_mem->mem_type);
	else if (mem_type_is_vram(old_mem_type))
		migrate = mem_type_to_migrate(xe, old_mem_type);
	else
		migrate = xe->tiles[0].migrate;

	xe_assert(xe, migrate);
	trace_xe_bo_move(bo, new_mem->mem_type, old_mem_type, move_lacks_source);
	xe_device_mem_access_get(xe);

	if (xe_bo_is_pinned(bo) && !xe_bo_is_user(bo)) {
		/*
		 * Kernel memory that is pinned should only be moved on suspend
		 * / resume, some of the pinned memory is required for the
		 * device to resume / use the GPU to move other evicted memory
		 * (user memory) around. This likely could be optimized a bit
		 * futher where we find the minimum set of pinned memory
		 * required for resume but for simplity doing a memcpy for all
		 * pinned memory.
		 */
		ret = xe_bo_vmap(bo);
		if (!ret) {
			ret = ttm_bo_move_memcpy(ttm_bo, ctx, new_mem);

			/* Create a new VMAP once kernel BO back in VRAM */
			if (!ret && resource_is_vram(new_mem)) {
				struct xe_mem_region *vram = res_to_mem_region(new_mem);
				void __iomem *new_addr = vram->mapping +
					(new_mem->start << PAGE_SHIFT);

				if (XE_WARN_ON(new_mem->start == XE_BO_INVALID_OFFSET)) {
					ret = -EINVAL;
					xe_device_mem_access_put(xe);
					goto out;
				}

				xe_assert(xe, new_mem->start ==
					  bo->placements->fpfn);

				iosys_map_set_vaddr_iomem(&bo->vmap, new_addr);
			}
		}
	} else {
		if (move_lacks_source)
			fence = xe_migrate_clear(migrate, bo, new_mem);
		else
			fence = xe_migrate_copy(migrate, bo, bo, old_mem,
						new_mem, handle_system_ccs);
		if (IS_ERR(fence)) {
			ret = PTR_ERR(fence);
			xe_device_mem_access_put(xe);
			goto out;
		}
		if (!move_lacks_source) {
			ret = ttm_bo_move_accel_cleanup(ttm_bo, fence, evict,
							true, new_mem);
			if (ret) {
				dma_fence_wait(fence, false);
				ttm_bo_move_null(ttm_bo, new_mem);
				ret = 0;
			}
		} else {
			/*
			 * ttm_bo_move_accel_cleanup() may blow up if
			 * bo->resource == NULL, so just attach the
			 * fence and set the new resource.
			 */
			dma_resv_add_fence(ttm_bo->base.resv, fence,
					   DMA_RESV_USAGE_KERNEL);
			ttm_bo_move_null(ttm_bo, new_mem);
		}

		dma_fence_put(fence);
	}

	xe_device_mem_access_put(xe);

out:
	return ret;

}

/**
 * xe_bo_evict_pinned() - Evict a pinned VRAM object to system memory
 * @bo: The buffer object to move.
 *
 * On successful completion, the object memory will be moved to sytem memory.
 * This function blocks until the object has been fully moved.
 *
 * This is needed to for special handling of pinned VRAM object during
 * suspend-resume.
 *
 * Return: 0 on success. Negative error code on failure.
 */
int xe_bo_evict_pinned(struct xe_bo *bo)
{
	struct ttm_place place = {
		.mem_type = XE_PL_TT,
	};
	struct ttm_placement placement = {
		.placement = &place,
		.num_placement = 1,
	};
	struct ttm_operation_ctx ctx = {
		.interruptible = false,
	};
	struct ttm_resource *new_mem;
	int ret;

	xe_bo_assert_held(bo);

	if (WARN_ON(!bo->ttm.resource))
		return -EINVAL;

	if (WARN_ON(!xe_bo_is_pinned(bo)))
		return -EINVAL;

	if (WARN_ON(!xe_bo_is_vram(bo)))
		return -EINVAL;

	ret = ttm_bo_mem_space(&bo->ttm, &placement, &new_mem, &ctx);
	if (ret)
		return ret;

	if (!bo->ttm.ttm) {
		bo->ttm.ttm = xe_ttm_tt_create(&bo->ttm, 0);
		if (!bo->ttm.ttm) {
			ret = -ENOMEM;
			goto err_res_free;
		}
	}

	ret = ttm_tt_populate(bo->ttm.bdev, bo->ttm.ttm, &ctx);
	if (ret)
		goto err_res_free;

	ret = dma_resv_reserve_fences(bo->ttm.base.resv, 1);
	if (ret)
		goto err_res_free;

	ret = xe_bo_move(&bo->ttm, false, &ctx, new_mem, NULL);
	if (ret)
		goto err_res_free;

	dma_resv_wait_timeout(bo->ttm.base.resv, DMA_RESV_USAGE_KERNEL,
			      false, MAX_SCHEDULE_TIMEOUT);

	return 0;

err_res_free:
	ttm_resource_free(&bo->ttm, &new_mem);
	return ret;
}

/**
 * xe_bo_restore_pinned() - Restore a pinned VRAM object
 * @bo: The buffer object to move.
 *
 * On successful completion, the object memory will be moved back to VRAM.
 * This function blocks until the object has been fully moved.
 *
 * This is needed to for special handling of pinned VRAM object during
 * suspend-resume.
 *
 * Return: 0 on success. Negative error code on failure.
 */
int xe_bo_restore_pinned(struct xe_bo *bo)
{
	struct ttm_operation_ctx ctx = {
		.interruptible = false,
	};
	struct ttm_resource *new_mem;
	int ret;

	xe_bo_assert_held(bo);

	if (WARN_ON(!bo->ttm.resource))
		return -EINVAL;

	if (WARN_ON(!xe_bo_is_pinned(bo)))
		return -EINVAL;

	if (WARN_ON(xe_bo_is_vram(bo) || !bo->ttm.ttm))
		return -EINVAL;

	ret = ttm_bo_mem_space(&bo->ttm, &bo->placement, &new_mem, &ctx);
	if (ret)
		return ret;

	ret = ttm_tt_populate(bo->ttm.bdev, bo->ttm.ttm, &ctx);
	if (ret)
		goto err_res_free;

	ret = dma_resv_reserve_fences(bo->ttm.base.resv, 1);
	if (ret)
		goto err_res_free;

	ret = xe_bo_move(&bo->ttm, false, &ctx, new_mem, NULL);
	if (ret)
		goto err_res_free;

	dma_resv_wait_timeout(bo->ttm.base.resv, DMA_RESV_USAGE_KERNEL,
			      false, MAX_SCHEDULE_TIMEOUT);

	return 0;

err_res_free:
	ttm_resource_free(&bo->ttm, &new_mem);
	return ret;
}

static unsigned long xe_ttm_io_mem_pfn(struct ttm_buffer_object *ttm_bo,
				       unsigned long page_offset)
{
	struct xe_bo *bo = ttm_to_xe_bo(ttm_bo);
	struct xe_res_cursor cursor;
	struct xe_mem_region *vram;

	if (ttm_bo->resource->mem_type == XE_PL_STOLEN)
		return xe_ttm_stolen_io_offset(bo, page_offset << PAGE_SHIFT) >> PAGE_SHIFT;

	vram = res_to_mem_region(ttm_bo->resource);
	xe_res_first(ttm_bo->resource, (u64)page_offset << PAGE_SHIFT, 0, &cursor);
	return (vram->io_start + cursor.start) >> PAGE_SHIFT;
}

static void __xe_bo_vunmap(struct xe_bo *bo);

/*
 * TODO: Move this function to TTM so we don't rely on how TTM does its
 * locking, thereby abusing TTM internals.
 */
static bool xe_ttm_bo_lock_in_destructor(struct ttm_buffer_object *ttm_bo)
{
	struct xe_device *xe = ttm_to_xe_device(ttm_bo->bdev);
	bool locked;

	xe_assert(xe, !kref_read(&ttm_bo->kref));

	/*
	 * We can typically only race with TTM trylocking under the
	 * lru_lock, which will immediately be unlocked again since
	 * the ttm_bo refcount is zero at this point. So trylocking *should*
	 * always succeed here, as long as we hold the lru lock.
	 */
	spin_lock(&ttm_bo->bdev->lru_lock);
	locked = dma_resv_trylock(ttm_bo->base.resv);
	spin_unlock(&ttm_bo->bdev->lru_lock);
	xe_assert(xe, locked);

	return locked;
}

static void xe_ttm_bo_release_notify(struct ttm_buffer_object *ttm_bo)
{
	struct dma_resv_iter cursor;
	struct dma_fence *fence;
	struct dma_fence *replacement = NULL;
	struct xe_bo *bo;

	if (!xe_bo_is_xe_bo(ttm_bo))
		return;

	bo = ttm_to_xe_bo(ttm_bo);
	xe_assert(xe_bo_device(bo), !(bo->created && kref_read(&ttm_bo->base.refcount)));

	/*
	 * Corner case where TTM fails to allocate memory and this BOs resv
	 * still points the VMs resv
	 */
	if (ttm_bo->base.resv != &ttm_bo->base._resv)
		return;

	if (!xe_ttm_bo_lock_in_destructor(ttm_bo))
		return;

	/*
	 * Scrub the preempt fences if any. The unbind fence is already
	 * attached to the resv.
	 * TODO: Don't do this for external bos once we scrub them after
	 * unbind.
	 */
	dma_resv_for_each_fence(&cursor, ttm_bo->base.resv,
				DMA_RESV_USAGE_BOOKKEEP, fence) {
		if (xe_fence_is_xe_preempt(fence) &&
		    !dma_fence_is_signaled(fence)) {
			if (!replacement)
				replacement = dma_fence_get_stub();

			dma_resv_replace_fences(ttm_bo->base.resv,
						fence->context,
						replacement,
						DMA_RESV_USAGE_BOOKKEEP);
		}
	}
	dma_fence_put(replacement);

	dma_resv_unlock(ttm_bo->base.resv);
}

static void xe_ttm_bo_delete_mem_notify(struct ttm_buffer_object *ttm_bo)
{
	if (!xe_bo_is_xe_bo(ttm_bo))
		return;

	/*
	 * Object is idle and about to be destroyed. Release the
	 * dma-buf attachment.
	 */
	if (ttm_bo->type == ttm_bo_type_sg && ttm_bo->sg) {
		struct xe_ttm_tt *xe_tt = container_of(ttm_bo->ttm,
						       struct xe_ttm_tt, ttm);

		dma_buf_unmap_attachment(ttm_bo->base.import_attach, ttm_bo->sg,
					 DMA_BIDIRECTIONAL);
		ttm_bo->sg = NULL;
		xe_tt->sg = NULL;
	}
}

struct ttm_device_funcs xe_ttm_funcs = {
	.ttm_tt_create = xe_ttm_tt_create,
	.ttm_tt_populate = xe_ttm_tt_populate,
	.ttm_tt_unpopulate = xe_ttm_tt_unpopulate,
	.ttm_tt_destroy = xe_ttm_tt_destroy,
	.evict_flags = xe_evict_flags,
	.move = xe_bo_move,
	.io_mem_reserve = xe_ttm_io_mem_reserve,
	.io_mem_pfn = xe_ttm_io_mem_pfn,
	.release_notify = xe_ttm_bo_release_notify,
	.eviction_valuable = ttm_bo_eviction_valuable,
	.delete_mem_notify = xe_ttm_bo_delete_mem_notify,
};

static void xe_ttm_bo_destroy(struct ttm_buffer_object *ttm_bo)
{
	struct xe_bo *bo = ttm_to_xe_bo(ttm_bo);
	struct xe_device *xe = ttm_to_xe_device(ttm_bo->bdev);

	if (bo->ttm.base.import_attach)
		drm_prime_gem_destroy(&bo->ttm.base, NULL);
	drm_gem_object_release(&bo->ttm.base);

	xe_assert(xe, list_empty(&ttm_bo->base.gpuva.list));

	if (bo->ggtt_node.size)
		xe_ggtt_remove_bo(bo->tile->mem.ggtt, bo);

#ifdef CONFIG_PROC_FS
	if (bo->client)
		xe_drm_client_remove_bo(bo);
#endif

	if (bo->vm && xe_bo_is_user(bo))
		xe_vm_put(bo->vm);

	kfree(bo);
}

static void xe_gem_object_free(struct drm_gem_object *obj)
{
	/* Our BO reference counting scheme works as follows:
	 *
	 * The gem object kref is typically used throughout the driver,
	 * and the gem object holds a ttm_buffer_object refcount, so
	 * that when the last gem object reference is put, which is when
	 * we end up in this function, we put also that ttm_buffer_object
	 * refcount. Anything using gem interfaces is then no longer
	 * allowed to access the object in a way that requires a gem
	 * refcount, including locking the object.
	 *
	 * driver ttm callbacks is allowed to use the ttm_buffer_object
	 * refcount directly if needed.
	 */
	__xe_bo_vunmap(gem_to_xe_bo(obj));
	ttm_bo_put(container_of(obj, struct ttm_buffer_object, base));
}

static void xe_gem_object_close(struct drm_gem_object *obj,
				struct drm_file *file_priv)
{
	struct xe_bo *bo = gem_to_xe_bo(obj);

	if (bo->vm && !xe_vm_in_fault_mode(bo->vm)) {
		xe_assert(xe_bo_device(bo), xe_bo_is_user(bo));

		xe_bo_lock(bo, false);
		ttm_bo_set_bulk_move(&bo->ttm, NULL);
		xe_bo_unlock(bo);
	}
}

static bool should_migrate_to_system(struct xe_bo *bo)
{
	struct xe_device *xe = xe_bo_device(bo);

	return xe_device_in_fault_mode(xe) && bo->props.cpu_atomic;
}

static vm_fault_t xe_gem_fault(struct vm_fault *vmf)
{
	struct ttm_buffer_object *tbo = vmf->vma->vm_private_data;
	struct drm_device *ddev = tbo->base.dev;
	vm_fault_t ret;
	int idx, r = 0;

	ret = ttm_bo_vm_reserve(tbo, vmf);
	if (ret)
		return ret;

	if (drm_dev_enter(ddev, &idx)) {
		struct xe_bo *bo = ttm_to_xe_bo(tbo);

		trace_xe_bo_cpu_fault(bo);

		if (should_migrate_to_system(bo)) {
			r = xe_bo_migrate(bo, XE_PL_TT);
			if (r == -EBUSY || r == -ERESTARTSYS || r == -EINTR)
				ret = VM_FAULT_NOPAGE;
			else if (r)
				ret = VM_FAULT_SIGBUS;
		}
		if (!ret)
			ret = ttm_bo_vm_fault_reserved(vmf,
						       vmf->vma->vm_page_prot,
						       TTM_BO_VM_NUM_PREFAULT);
		drm_dev_exit(idx);
	} else {
		ret = ttm_bo_vm_dummy_page(vmf, vmf->vma->vm_page_prot);
	}
	if (ret == VM_FAULT_RETRY && !(vmf->flags & FAULT_FLAG_RETRY_NOWAIT))
		return ret;

	dma_resv_unlock(tbo->base.resv);
	return ret;
}

static const struct vm_operations_struct xe_gem_vm_ops = {
	.fault = xe_gem_fault,
	.open = ttm_bo_vm_open,
	.close = ttm_bo_vm_close,
	.access = ttm_bo_vm_access
};

static const struct drm_gem_object_funcs xe_gem_object_funcs = {
	.free = xe_gem_object_free,
	.close = xe_gem_object_close,
	.mmap = drm_gem_ttm_mmap,
	.export = xe_gem_prime_export,
	.vm_ops = &xe_gem_vm_ops,
};

/**
 * xe_bo_alloc - Allocate storage for a struct xe_bo
 *
 * This funcition is intended to allocate storage to be used for input
 * to __xe_bo_create_locked(), in the case a pointer to the bo to be
 * created is needed before the call to __xe_bo_create_locked().
 * If __xe_bo_create_locked ends up never to be called, then the
 * storage allocated with this function needs to be freed using
 * xe_bo_free().
 *
 * Return: A pointer to an uninitialized struct xe_bo on success,
 * ERR_PTR(-ENOMEM) on error.
 */
struct xe_bo *xe_bo_alloc(void)
{
	struct xe_bo *bo = kzalloc(sizeof(*bo), GFP_KERNEL);

	if (!bo)
		return ERR_PTR(-ENOMEM);

	return bo;
}

/**
 * xe_bo_free - Free storage allocated using xe_bo_alloc()
 * @bo: The buffer object storage.
 *
 * Refer to xe_bo_alloc() documentation for valid use-cases.
 */
void xe_bo_free(struct xe_bo *bo)
{
	kfree(bo);
}

struct xe_bo *___xe_bo_create_locked(struct xe_device *xe, struct xe_bo *bo,
				     struct xe_tile *tile, struct dma_resv *resv,
				     struct ttm_lru_bulk_move *bulk, size_t size,
				     u16 cpu_caching, enum ttm_bo_type type,
				     u32 flags)
{
	struct ttm_operation_ctx ctx = {
		.interruptible = true,
		.no_wait_gpu = false,
	};
	struct ttm_placement *placement;
	uint32_t alignment;
	size_t aligned_size;
	int err;

	/* Only kernel objects should set GT */
	xe_assert(xe, !tile || type == ttm_bo_type_kernel);

	if (XE_WARN_ON(!size)) {
		xe_bo_free(bo);
		return ERR_PTR(-EINVAL);
	}

	if (flags & (XE_BO_CREATE_VRAM_MASK | XE_BO_CREATE_STOLEN_BIT) &&
	    !(flags & XE_BO_CREATE_IGNORE_MIN_PAGE_SIZE_BIT) &&
	    xe->info.vram_flags & XE_VRAM_FLAGS_NEED64K) {
		aligned_size = ALIGN(size, SZ_64K);
		if (type != ttm_bo_type_device)
			size = ALIGN(size, SZ_64K);
		flags |= XE_BO_INTERNAL_64K;
		alignment = SZ_64K >> PAGE_SHIFT;

	} else {
		aligned_size = ALIGN(size, SZ_4K);
		flags &= ~XE_BO_INTERNAL_64K;
		alignment = SZ_4K >> PAGE_SHIFT;
	}

	if (type == ttm_bo_type_device && aligned_size != size)
		return ERR_PTR(-EINVAL);

	if (!bo) {
		bo = xe_bo_alloc();
		if (IS_ERR(bo))
			return bo;
	}

	bo->ccs_cleared = false;
	bo->tile = tile;
	bo->size = size;
	bo->flags = flags;
	bo->cpu_caching = cpu_caching;
	bo->ttm.base.funcs = &xe_gem_object_funcs;
	bo->props.preferred_mem_class = XE_BO_PROPS_INVALID;
	bo->props.preferred_gt = XE_BO_PROPS_INVALID;
	bo->props.preferred_mem_type = XE_BO_PROPS_INVALID;
	bo->ttm.priority = XE_BO_PRIORITY_NORMAL;
	INIT_LIST_HEAD(&bo->pinned_link);
#ifdef CONFIG_PROC_FS
	INIT_LIST_HEAD(&bo->client_link);
#endif

	drm_gem_private_object_init(&xe->drm, &bo->ttm.base, size);

	if (resv) {
		ctx.allow_res_evict = !(flags & XE_BO_CREATE_NO_RESV_EVICT);
		ctx.resv = resv;
	}

	if (!(flags & XE_BO_FIXED_PLACEMENT_BIT)) {
		err = __xe_bo_placement_for_flags(xe, bo, bo->flags);
		if (WARN_ON(err)) {
			xe_ttm_bo_destroy(&bo->ttm);
			return ERR_PTR(err);
		}
	}

	/* Defer populating type_sg bos */
	placement = (type == ttm_bo_type_sg ||
		     bo->flags & XE_BO_DEFER_BACKING) ? &sys_placement :
		&bo->placement;
	err = ttm_bo_init_reserved(&xe->ttm, &bo->ttm, type,
				   placement, alignment,
				   &ctx, NULL, resv, xe_ttm_bo_destroy);
	if (err)
		return ERR_PTR(err);

	/*
	 * The VRAM pages underneath are potentially still being accessed by the
	 * GPU, as per async GPU clearing and async evictions. However TTM makes
	 * sure to add any corresponding move/clear fences into the objects
	 * dma-resv using the DMA_RESV_USAGE_KERNEL slot.
	 *
	 * For KMD internal buffers we don't care about GPU clearing, however we
	 * still need to handle async evictions, where the VRAM is still being
	 * accessed by the GPU. Most internal callers are not expecting this,
	 * since they are missing the required synchronisation before accessing
	 * the memory. To keep things simple just sync wait any kernel fences
	 * here, if the buffer is designated KMD internal.
	 *
	 * For normal userspace objects we should already have the required
	 * pipelining or sync waiting elsewhere, since we already have to deal
	 * with things like async GPU clearing.
	 */
	if (type == ttm_bo_type_kernel) {
		long timeout = dma_resv_wait_timeout(bo->ttm.base.resv,
						     DMA_RESV_USAGE_KERNEL,
						     ctx.interruptible,
						     MAX_SCHEDULE_TIMEOUT);

		if (timeout < 0) {
			if (!resv)
				dma_resv_unlock(bo->ttm.base.resv);
			xe_bo_put(bo);
			return ERR_PTR(timeout);
		}
	}

	bo->created = true;
	if (bulk)
		ttm_bo_set_bulk_move(&bo->ttm, bulk);
	else
		ttm_bo_move_to_lru_tail_unlocked(&bo->ttm);

	return bo;
}

static int __xe_bo_fixed_placement(struct xe_device *xe,
				   struct xe_bo *bo,
				   u32 flags,
				   u64 start, u64 end, u64 size)
{
	struct ttm_place *place = bo->placements;

	if (flags & (XE_BO_CREATE_USER_BIT|XE_BO_CREATE_SYSTEM_BIT))
		return -EINVAL;

	place->flags = TTM_PL_FLAG_CONTIGUOUS;
	place->fpfn = start >> PAGE_SHIFT;
	place->lpfn = end >> PAGE_SHIFT;

	switch (flags & (XE_BO_CREATE_STOLEN_BIT | XE_BO_CREATE_VRAM_MASK)) {
	case XE_BO_CREATE_VRAM0_BIT:
		place->mem_type = XE_PL_VRAM0;
		break;
	case XE_BO_CREATE_VRAM1_BIT:
		place->mem_type = XE_PL_VRAM1;
		break;
	case XE_BO_CREATE_STOLEN_BIT:
		place->mem_type = XE_PL_STOLEN;
		break;

	default:
		/* 0 or multiple of the above set */
		return -EINVAL;
	}

	bo->placement = (struct ttm_placement) {
		.num_placement = 1,
		.placement = place,
		.num_busy_placement = 1,
		.busy_placement = place,
	};

	return 0;
}

static struct xe_bo *
__xe_bo_create_locked(struct xe_device *xe,
		      struct xe_tile *tile, struct xe_vm *vm,
		      size_t size, u64 start, u64 end,
		      u16 cpu_caching, enum ttm_bo_type type, u32 flags)
{
	struct xe_bo *bo = NULL;
	int err;

	if (vm)
		xe_vm_assert_held(vm);

	if (start || end != ~0ULL) {
		bo = xe_bo_alloc();
		if (IS_ERR(bo))
			return bo;

		flags |= XE_BO_FIXED_PLACEMENT_BIT;
		err = __xe_bo_fixed_placement(xe, bo, flags, start, end, size);
		if (err) {
			xe_bo_free(bo);
			return ERR_PTR(err);
		}
	}

	bo = ___xe_bo_create_locked(xe, bo, tile, vm ? xe_vm_resv(vm) : NULL,
				    vm && !xe_vm_in_fault_mode(vm) &&
				    flags & XE_BO_CREATE_USER_BIT ?
				    &vm->lru_bulk_move : NULL, size,
				    cpu_caching, type, flags);
	if (IS_ERR(bo))
		return bo;

	/*
	 * Note that instead of taking a reference no the drm_gpuvm_resv_bo(),
	 * to ensure the shared resv doesn't disappear under the bo, the bo
	 * will keep a reference to the vm, and avoid circular references
	 * by having all the vm's bo refereferences released at vm close
	 * time.
	 */
	if (vm && xe_bo_is_user(bo))
		xe_vm_get(vm);
	bo->vm = vm;

	if (bo->flags & XE_BO_CREATE_GGTT_BIT) {
		if (!tile && flags & XE_BO_CREATE_STOLEN_BIT)
			tile = xe_device_get_root_tile(xe);

		xe_assert(xe, tile);

		if (flags & XE_BO_FIXED_PLACEMENT_BIT) {
			err = xe_ggtt_insert_bo_at(tile->mem.ggtt, bo,
						   start + bo->size, U64_MAX);
		} else {
			err = xe_ggtt_insert_bo(tile->mem.ggtt, bo);
		}
		if (err)
			goto err_unlock_put_bo;
	}

	return bo;

err_unlock_put_bo:
	__xe_bo_unset_bulk_move(bo);
	xe_bo_unlock_vm_held(bo);
	xe_bo_put(bo);
	return ERR_PTR(err);
}

struct xe_bo *
xe_bo_create_locked_range(struct xe_device *xe,
			  struct xe_tile *tile, struct xe_vm *vm,
			  size_t size, u64 start, u64 end,
			  enum ttm_bo_type type, u32 flags)
{
	return __xe_bo_create_locked(xe, tile, vm, size, start, end, 0, type, flags);
}

struct xe_bo *xe_bo_create_locked(struct xe_device *xe, struct xe_tile *tile,
				  struct xe_vm *vm, size_t size,
				  enum ttm_bo_type type, u32 flags)
{
	return __xe_bo_create_locked(xe, tile, vm, size, 0, ~0ULL, 0, type, flags);
}

struct xe_bo *xe_bo_create_user(struct xe_device *xe, struct xe_tile *tile,
				struct xe_vm *vm, size_t size,
				u16 cpu_caching,
				enum ttm_bo_type type,
				u32 flags)
{
	struct xe_bo *bo = __xe_bo_create_locked(xe, tile, vm, size, 0, ~0ULL,
						 cpu_caching, type,
						 flags | XE_BO_CREATE_USER_BIT);
	if (!IS_ERR(bo))
		xe_bo_unlock_vm_held(bo);

	return bo;
}

struct xe_bo *xe_bo_create(struct xe_device *xe, struct xe_tile *tile,
			   struct xe_vm *vm, size_t size,
			   enum ttm_bo_type type, u32 flags)
{
	struct xe_bo *bo = xe_bo_create_locked(xe, tile, vm, size, type, flags);

	if (!IS_ERR(bo))
		xe_bo_unlock_vm_held(bo);

	return bo;
}

struct xe_bo *xe_bo_create_pin_map_at(struct xe_device *xe, struct xe_tile *tile,
				      struct xe_vm *vm,
				      size_t size, u64 offset,
				      enum ttm_bo_type type, u32 flags)
{
	struct xe_bo *bo;
	int err;
	u64 start = offset == ~0ull ? 0 : offset;
	u64 end = offset == ~0ull ? offset : start + size;

	if (flags & XE_BO_CREATE_STOLEN_BIT &&
	    xe_ttm_stolen_cpu_access_needs_ggtt(xe))
		flags |= XE_BO_CREATE_GGTT_BIT;

	bo = xe_bo_create_locked_range(xe, tile, vm, size, start, end, type,
				       flags | XE_BO_NEEDS_CPU_ACCESS);
	if (IS_ERR(bo))
		return bo;

	err = xe_bo_pin(bo);
	if (err)
		goto err_put;

	err = xe_bo_vmap(bo);
	if (err)
		goto err_unpin;

	xe_bo_unlock_vm_held(bo);

	return bo;

err_unpin:
	xe_bo_unpin(bo);
err_put:
	xe_bo_unlock_vm_held(bo);
	xe_bo_put(bo);
	return ERR_PTR(err);
}

struct xe_bo *xe_bo_create_pin_map(struct xe_device *xe, struct xe_tile *tile,
				   struct xe_vm *vm, size_t size,
				   enum ttm_bo_type type, u32 flags)
{
	return xe_bo_create_pin_map_at(xe, tile, vm, size, ~0ull, type, flags);
}

struct xe_bo *xe_bo_create_from_data(struct xe_device *xe, struct xe_tile *tile,
				     const void *data, size_t size,
				     enum ttm_bo_type type, u32 flags)
{
	struct xe_bo *bo = xe_bo_create_pin_map(xe, tile, NULL,
						ALIGN(size, PAGE_SIZE),
						type, flags);
	if (IS_ERR(bo))
		return bo;

	xe_map_memcpy_to(xe, &bo->vmap, 0, data, size);

	return bo;
}

static void __xe_bo_unpin_map_no_vm(struct drm_device *drm, void *arg)
{
	xe_bo_unpin_map_no_vm(arg);
}

struct xe_bo *xe_managed_bo_create_pin_map(struct xe_device *xe, struct xe_tile *tile,
					   size_t size, u32 flags)
{
	struct xe_bo *bo;
	int ret;

	bo = xe_bo_create_pin_map(xe, tile, NULL, size, ttm_bo_type_kernel, flags);
	if (IS_ERR(bo))
		return bo;

	ret = drmm_add_action_or_reset(&xe->drm, __xe_bo_unpin_map_no_vm, bo);
	if (ret)
		return ERR_PTR(ret);

	return bo;
}

struct xe_bo *xe_managed_bo_create_from_data(struct xe_device *xe, struct xe_tile *tile,
					     const void *data, size_t size, u32 flags)
{
	struct xe_bo *bo = xe_managed_bo_create_pin_map(xe, tile, ALIGN(size, PAGE_SIZE), flags);

	if (IS_ERR(bo))
		return bo;

	xe_map_memcpy_to(xe, &bo->vmap, 0, data, size);

	return bo;
}

/*
 * XXX: This is in the VM bind data path, likely should calculate this once and
 * store, with a recalculation if the BO is moved.
 */
uint64_t vram_region_gpu_offset(struct ttm_resource *res)
{
	struct xe_device *xe = ttm_to_xe_device(res->bo->bdev);

	if (res->mem_type == XE_PL_STOLEN)
		return xe_ttm_stolen_gpu_offset(xe);

	return res_to_mem_region(res)->dpa_base;
}

/**
 * xe_bo_pin_external - pin an external BO
 * @bo: buffer object to be pinned
 *
 * Pin an external (not tied to a VM, can be exported via dma-buf / prime FD)
 * BO. Unique call compared to xe_bo_pin as this function has it own set of
 * asserts and code to ensure evict / restore on suspend / resume.
 *
 * Returns 0 for success, negative error code otherwise.
 */
int xe_bo_pin_external(struct xe_bo *bo)
{
	struct xe_device *xe = xe_bo_device(bo);
	int err;

	xe_assert(xe, !bo->vm);
	xe_assert(xe, xe_bo_is_user(bo));

	if (!xe_bo_is_pinned(bo)) {
		err = xe_bo_validate(bo, NULL, false);
		if (err)
			return err;

		if (xe_bo_is_vram(bo)) {
			spin_lock(&xe->pinned.lock);
			list_add_tail(&bo->pinned_link,
				      &xe->pinned.external_vram);
			spin_unlock(&xe->pinned.lock);
		}
	}

	ttm_bo_pin(&bo->ttm);

	/*
	 * FIXME: If we always use the reserve / unreserve functions for locking
	 * we do not need this.
	 */
	ttm_bo_move_to_lru_tail_unlocked(&bo->ttm);

	return 0;
}

int xe_bo_pin(struct xe_bo *bo)
{
	struct xe_device *xe = xe_bo_device(bo);
	int err;

	/* We currently don't expect user BO to be pinned */
	xe_assert(xe, !xe_bo_is_user(bo));

	/* Pinned object must be in GGTT or have pinned flag */
	xe_assert(xe, bo->flags & (XE_BO_CREATE_PINNED_BIT |
				   XE_BO_CREATE_GGTT_BIT));

	/*
	 * No reason we can't support pinning imported dma-bufs we just don't
	 * expect to pin an imported dma-buf.
	 */
	xe_assert(xe, !bo->ttm.base.import_attach);

	/* We only expect at most 1 pin */
	xe_assert(xe, !xe_bo_is_pinned(bo));

	err = xe_bo_validate(bo, NULL, false);
	if (err)
		return err;

	/*
	 * For pinned objects in on DGFX, which are also in vram, we expect
	 * these to be in contiguous VRAM memory. Required eviction / restore
	 * during suspend / resume (force restore to same physical address).
	 */
	if (IS_DGFX(xe) && !(IS_ENABLED(CONFIG_DRM_XE_DEBUG) &&
	    bo->flags & XE_BO_INTERNAL_TEST)) {
		struct ttm_place *place = &(bo->placements[0]);

		if (mem_type_is_vram(place->mem_type)) {
			xe_assert(xe, place->flags & TTM_PL_FLAG_CONTIGUOUS);

			place->fpfn = (xe_bo_addr(bo, 0, PAGE_SIZE) -
				       vram_region_gpu_offset(bo->ttm.resource)) >> PAGE_SHIFT;
			place->lpfn = place->fpfn + (bo->size >> PAGE_SHIFT);

			spin_lock(&xe->pinned.lock);
			list_add_tail(&bo->pinned_link, &xe->pinned.kernel_bo_present);
			spin_unlock(&xe->pinned.lock);
		}
	}

	ttm_bo_pin(&bo->ttm);

	/*
	 * FIXME: If we always use the reserve / unreserve functions for locking
	 * we do not need this.
	 */
	ttm_bo_move_to_lru_tail_unlocked(&bo->ttm);

	return 0;
}

/**
 * xe_bo_unpin_external - unpin an external BO
 * @bo: buffer object to be unpinned
 *
 * Unpin an external (not tied to a VM, can be exported via dma-buf / prime FD)
 * BO. Unique call compared to xe_bo_unpin as this function has it own set of
 * asserts and code to ensure evict / restore on suspend / resume.
 *
 * Returns 0 for success, negative error code otherwise.
 */
void xe_bo_unpin_external(struct xe_bo *bo)
{
	struct xe_device *xe = xe_bo_device(bo);

	xe_assert(xe, !bo->vm);
	xe_assert(xe, xe_bo_is_pinned(bo));
	xe_assert(xe, xe_bo_is_user(bo));

	if (bo->ttm.pin_count == 1 && !list_empty(&bo->pinned_link)) {
		spin_lock(&xe->pinned.lock);
		list_del_init(&bo->pinned_link);
		spin_unlock(&xe->pinned.lock);
	}

	ttm_bo_unpin(&bo->ttm);

	/*
	 * FIXME: If we always use the reserve / unreserve functions for locking
	 * we do not need this.
	 */
	ttm_bo_move_to_lru_tail_unlocked(&bo->ttm);
}

void xe_bo_unpin(struct xe_bo *bo)
{
	struct xe_device *xe = xe_bo_device(bo);

	xe_assert(xe, !bo->ttm.base.import_attach);
	xe_assert(xe, xe_bo_is_pinned(bo));

	if (IS_DGFX(xe) && !(IS_ENABLED(CONFIG_DRM_XE_DEBUG) &&
	    bo->flags & XE_BO_INTERNAL_TEST)) {
		struct ttm_place *place = &(bo->placements[0]);

		if (mem_type_is_vram(place->mem_type)) {
			xe_assert(xe, !list_empty(&bo->pinned_link));

			spin_lock(&xe->pinned.lock);
			list_del_init(&bo->pinned_link);
			spin_unlock(&xe->pinned.lock);
		}
	}

	ttm_bo_unpin(&bo->ttm);
}

/**
 * xe_bo_validate() - Make sure the bo is in an allowed placement
 * @bo: The bo,
 * @vm: Pointer to a the vm the bo shares a locked dma_resv object with, or
 *      NULL. Used together with @allow_res_evict.
 * @allow_res_evict: Whether it's allowed to evict bos sharing @vm's
 *                   reservation object.
 *
 * Make sure the bo is in allowed placement, migrating it if necessary. If
 * needed, other bos will be evicted. If bos selected for eviction shares
 * the @vm's reservation object, they can be evicted iff @allow_res_evict is
 * set to true, otherwise they will be bypassed.
 *
 * Return: 0 on success, negative error code on failure. May return
 * -EINTR or -ERESTARTSYS if internal waits are interrupted by a signal.
 */
int xe_bo_validate(struct xe_bo *bo, struct xe_vm *vm, bool allow_res_evict)
{
	struct ttm_operation_ctx ctx = {
		.interruptible = true,
		.no_wait_gpu = false,
	};

	if (vm) {
		lockdep_assert_held(&vm->lock);
		xe_vm_assert_held(vm);

		ctx.allow_res_evict = allow_res_evict;
		ctx.resv = xe_vm_resv(vm);
	}

	return ttm_bo_validate(&bo->ttm, &bo->placement, &ctx);
}

bool xe_bo_is_xe_bo(struct ttm_buffer_object *bo)
{
	if (bo->destroy == &xe_ttm_bo_destroy)
		return true;

	return false;
}

/*
 * Resolve a BO address. There is no assert to check if the proper lock is held
 * so it should only be used in cases where it is not fatal to get the wrong
 * address, such as printing debug information, but not in cases where memory is
 * written based on this result.
 */
dma_addr_t __xe_bo_addr(struct xe_bo *bo, u64 offset, size_t page_size)
{
	struct xe_device *xe = xe_bo_device(bo);
	struct xe_res_cursor cur;
	u64 page;

	xe_assert(xe, page_size <= PAGE_SIZE);
	page = offset >> PAGE_SHIFT;
	offset &= (PAGE_SIZE - 1);

	if (!xe_bo_is_vram(bo) && !xe_bo_is_stolen(bo)) {
		xe_assert(xe, bo->ttm.ttm);

		xe_res_first_sg(xe_bo_sg(bo), page << PAGE_SHIFT,
				page_size, &cur);
		return xe_res_dma(&cur) + offset;
	} else {
		struct xe_res_cursor cur;

		xe_res_first(bo->ttm.resource, page << PAGE_SHIFT,
			     page_size, &cur);
		return cur.start + offset + vram_region_gpu_offset(bo->ttm.resource);
	}
}

dma_addr_t xe_bo_addr(struct xe_bo *bo, u64 offset, size_t page_size)
{
	if (!READ_ONCE(bo->ttm.pin_count))
		xe_bo_assert_held(bo);
	return __xe_bo_addr(bo, offset, page_size);
}

int xe_bo_vmap(struct xe_bo *bo)
{
	void *virtual;
	bool is_iomem;
	int ret;

	xe_bo_assert_held(bo);

	if (!(bo->flags & XE_BO_NEEDS_CPU_ACCESS))
		return -EINVAL;

	if (!iosys_map_is_null(&bo->vmap))
		return 0;

	/*
	 * We use this more or less deprecated interface for now since
	 * ttm_bo_vmap() doesn't offer the optimization of kmapping
	 * single page bos, which is done here.
	 * TODO: Fix up ttm_bo_vmap to do that, or fix up ttm_bo_kmap
	 * to use struct iosys_map.
	 */
	ret = ttm_bo_kmap(&bo->ttm, 0, bo->size >> PAGE_SHIFT, &bo->kmap);
	if (ret)
		return ret;

	virtual = ttm_kmap_obj_virtual(&bo->kmap, &is_iomem);
	if (is_iomem)
		iosys_map_set_vaddr_iomem(&bo->vmap, (void __iomem *)virtual);
	else
		iosys_map_set_vaddr(&bo->vmap, virtual);

	return 0;
}

static void __xe_bo_vunmap(struct xe_bo *bo)
{
	if (!iosys_map_is_null(&bo->vmap)) {
		iosys_map_clear(&bo->vmap);
		ttm_bo_kunmap(&bo->kmap);
	}
}

void xe_bo_vunmap(struct xe_bo *bo)
{
	xe_bo_assert_held(bo);
	__xe_bo_vunmap(bo);
}

int xe_gem_create_ioctl(struct drm_device *dev, void *data,
			struct drm_file *file)
{
	struct xe_device *xe = to_xe_device(dev);
	struct xe_file *xef = to_xe_file(file);
	struct drm_xe_gem_create *args = data;
	struct xe_vm *vm = NULL;
	struct xe_bo *bo;
	unsigned int bo_flags;
	u32 handle;
	int err;

	if (XE_IOCTL_DBG(xe, args->extensions) ||
	    XE_IOCTL_DBG(xe, args->pad[0] || args->pad[1] || args->pad[2]) ||
	    XE_IOCTL_DBG(xe, args->reserved[0] || args->reserved[1]))
		return -EINVAL;

	/* at least one valid memory placement must be specified */
	if (XE_IOCTL_DBG(xe, (args->placement & ~xe->info.mem_region_mask) ||
			 !args->placement))
		return -EINVAL;

	if (XE_IOCTL_DBG(xe, args->flags &
			 ~(DRM_XE_GEM_CREATE_FLAG_DEFER_BACKING |
			   DRM_XE_GEM_CREATE_FLAG_SCANOUT |
			   DRM_XE_GEM_CREATE_FLAG_NEEDS_VISIBLE_VRAM)))
		return -EINVAL;

	if (XE_IOCTL_DBG(xe, args->handle))
		return -EINVAL;

	if (XE_IOCTL_DBG(xe, !args->size))
		return -EINVAL;

	if (XE_IOCTL_DBG(xe, args->size > SIZE_MAX))
		return -EINVAL;

	if (XE_IOCTL_DBG(xe, args->size & ~PAGE_MASK))
		return -EINVAL;

	bo_flags = 0;
	if (args->flags & DRM_XE_GEM_CREATE_FLAG_DEFER_BACKING)
		bo_flags |= XE_BO_DEFER_BACKING;

	if (args->flags & DRM_XE_GEM_CREATE_FLAG_SCANOUT)
		bo_flags |= XE_BO_SCANOUT_BIT;

	bo_flags |= args->placement << (ffs(XE_BO_CREATE_SYSTEM_BIT) - 1);

	if (args->flags & DRM_XE_GEM_CREATE_FLAG_NEEDS_VISIBLE_VRAM) {
		if (XE_IOCTL_DBG(xe, !(bo_flags & XE_BO_CREATE_VRAM_MASK)))
			return -EINVAL;

		bo_flags |= XE_BO_NEEDS_CPU_ACCESS;
	}

	if (XE_IOCTL_DBG(xe, !args->cpu_caching ||
			 args->cpu_caching > DRM_XE_GEM_CPU_CACHING_WC))
		return -EINVAL;

	if (XE_IOCTL_DBG(xe, bo_flags & XE_BO_CREATE_VRAM_MASK &&
			 args->cpu_caching != DRM_XE_GEM_CPU_CACHING_WC))
		return -EINVAL;

	if (XE_IOCTL_DBG(xe, bo_flags & XE_BO_SCANOUT_BIT &&
			 args->cpu_caching == DRM_XE_GEM_CPU_CACHING_WB))
		return -EINVAL;

	if (args->vm_id) {
		vm = xe_vm_lookup(xef, args->vm_id);
		if (XE_IOCTL_DBG(xe, !vm))
			return -ENOENT;
		err = xe_vm_lock(vm, true);
		if (err)
			goto out_vm;
	}

	bo = xe_bo_create_user(xe, NULL, vm, args->size, args->cpu_caching,
			       ttm_bo_type_device, bo_flags);

	if (vm)
		xe_vm_unlock(vm);

	if (IS_ERR(bo)) {
		err = PTR_ERR(bo);
		goto out_vm;
	}

	err = drm_gem_handle_create(file, &bo->ttm.base, &handle);
	if (err)
		goto out_bulk;

	args->handle = handle;
	goto out_put;

out_bulk:
	if (vm && !xe_vm_in_fault_mode(vm)) {
		xe_vm_lock(vm, false);
		__xe_bo_unset_bulk_move(bo);
		xe_vm_unlock(vm);
	}
out_put:
	xe_bo_put(bo);
out_vm:
	if (vm)
		xe_vm_put(vm);

	return err;
}

int xe_gem_mmap_offset_ioctl(struct drm_device *dev, void *data,
			     struct drm_file *file)
{
	struct xe_device *xe = to_xe_device(dev);
	struct drm_xe_gem_mmap_offset *args = data;
	struct drm_gem_object *gem_obj;

	if (XE_IOCTL_DBG(xe, args->extensions) ||
	    XE_IOCTL_DBG(xe, args->reserved[0] || args->reserved[1]))
		return -EINVAL;

	if (XE_IOCTL_DBG(xe, args->flags))
		return -EINVAL;

	gem_obj = drm_gem_object_lookup(file, args->handle);
	if (XE_IOCTL_DBG(xe, !gem_obj))
		return -ENOENT;

	/* The mmap offset was set up at BO allocation time. */
	args->offset = drm_vma_node_offset_addr(&gem_obj->vma_node);

	xe_bo_put(gem_to_xe_bo(gem_obj));
	return 0;
}

/**
 * xe_bo_lock() - Lock the buffer object's dma_resv object
 * @bo: The struct xe_bo whose lock is to be taken
 * @intr: Whether to perform any wait interruptible
 *
 * Locks the buffer object's dma_resv object. If the buffer object is
 * pointing to a shared dma_resv object, that shared lock is locked.
 *
 * Return: 0 on success, -EINTR if @intr is true and the wait for a
 * contended lock was interrupted. If @intr is set to false, the
 * function always returns 0.
 */
int xe_bo_lock(struct xe_bo *bo, bool intr)
{
	if (intr)
		return dma_resv_lock_interruptible(bo->ttm.base.resv, NULL);

	dma_resv_lock(bo->ttm.base.resv, NULL);

	return 0;
}

/**
 * xe_bo_unlock() - Unlock the buffer object's dma_resv object
 * @bo: The struct xe_bo whose lock is to be released.
 *
 * Unlock a buffer object lock that was locked by xe_bo_lock().
 */
void xe_bo_unlock(struct xe_bo *bo)
{
	dma_resv_unlock(bo->ttm.base.resv);
}

/**
 * xe_bo_can_migrate - Whether a buffer object likely can be migrated
 * @bo: The buffer object to migrate
 * @mem_type: The TTM memory type intended to migrate to
 *
 * Check whether the buffer object supports migration to the
 * given memory type. Note that pinning may affect the ability to migrate as
 * returned by this function.
 *
 * This function is primarily intended as a helper for checking the
 * possibility to migrate buffer objects and can be called without
 * the object lock held.
 *
 * Return: true if migration is possible, false otherwise.
 */
bool xe_bo_can_migrate(struct xe_bo *bo, u32 mem_type)
{
	unsigned int cur_place;

	if (bo->ttm.type == ttm_bo_type_kernel)
		return true;

	if (bo->ttm.type == ttm_bo_type_sg)
		return false;

	for (cur_place = 0; cur_place < bo->placement.num_placement;
	     cur_place++) {
		if (bo->placements[cur_place].mem_type == mem_type)
			return true;
	}

	return false;
}

static void xe_place_from_ttm_type(u32 mem_type, struct ttm_place *place)
{
	memset(place, 0, sizeof(*place));
	place->mem_type = mem_type;
}

/**
 * xe_bo_migrate - Migrate an object to the desired region id
 * @bo: The buffer object to migrate.
 * @mem_type: The TTM region type to migrate to.
 *
 * Attempt to migrate the buffer object to the desired memory region. The
 * buffer object may not be pinned, and must be locked.
 * On successful completion, the object memory type will be updated,
 * but an async migration task may not have completed yet, and to
 * accomplish that, the object's kernel fences must be signaled with
 * the object lock held.
 *
 * Return: 0 on success. Negative error code on failure. In particular may
 * return -EINTR or -ERESTARTSYS if signal pending.
 */
int xe_bo_migrate(struct xe_bo *bo, u32 mem_type)
{
	struct xe_device *xe = ttm_to_xe_device(bo->ttm.bdev);
	struct ttm_operation_ctx ctx = {
		.interruptible = true,
		.no_wait_gpu = false,
	};
	struct ttm_placement placement;
	struct ttm_place requested;

	xe_bo_assert_held(bo);

	if (bo->ttm.resource->mem_type == mem_type)
		return 0;

	if (xe_bo_is_pinned(bo))
		return -EBUSY;

	if (!xe_bo_can_migrate(bo, mem_type))
		return -EINVAL;

	xe_place_from_ttm_type(mem_type, &requested);
	placement.num_placement = 1;
	placement.num_busy_placement = 1;
	placement.placement = &requested;
	placement.busy_placement = &requested;

	/*
	 * Stolen needs to be handled like below VRAM handling if we ever need
	 * to support it.
	 */
	drm_WARN_ON(&xe->drm, mem_type == XE_PL_STOLEN);

	if (mem_type_is_vram(mem_type)) {
		u32 c = 0;

		add_vram(xe, bo, &requested, bo->flags, mem_type, &c);
	}

	return ttm_bo_validate(&bo->ttm, &placement, &ctx);
}

/**
 * xe_bo_evict - Evict an object to evict placement
 * @bo: The buffer object to migrate.
 * @force_alloc: Set force_alloc in ttm_operation_ctx
 *
 * On successful completion, the object memory will be moved to evict
 * placement. Ths function blocks until the object has been fully moved.
 *
 * Return: 0 on success. Negative error code on failure.
 */
int xe_bo_evict(struct xe_bo *bo, bool force_alloc)
{
	struct ttm_operation_ctx ctx = {
		.interruptible = false,
		.no_wait_gpu = false,
		.force_alloc = force_alloc,
	};
	struct ttm_placement placement;
	int ret;

	xe_evict_flags(&bo->ttm, &placement);
	ret = ttm_bo_validate(&bo->ttm, &placement, &ctx);
	if (ret)
		return ret;

	dma_resv_wait_timeout(bo->ttm.base.resv, DMA_RESV_USAGE_KERNEL,
			      false, MAX_SCHEDULE_TIMEOUT);

	return 0;
}

/**
 * xe_bo_needs_ccs_pages - Whether a bo needs to back up CCS pages when
 * placed in system memory.
 * @bo: The xe_bo
 *
 * Return: true if extra pages need to be allocated, false otherwise.
 */
bool xe_bo_needs_ccs_pages(struct xe_bo *bo)
{
	struct xe_device *xe = xe_bo_device(bo);

	if (!xe_device_has_flat_ccs(xe) || bo->ttm.type != ttm_bo_type_device)
		return false;

	/* On discrete GPUs, if the GPU can access this buffer from
	 * system memory (i.e., it allows XE_PL_TT placement), FlatCCS
	 * can't be used since there's no CCS storage associated with
	 * non-VRAM addresses.
	 */
	if (IS_DGFX(xe) && (bo->flags & XE_BO_CREATE_SYSTEM_BIT))
		return false;

	return true;
}

/**
 * __xe_bo_release_dummy() - Dummy kref release function
 * @kref: The embedded struct kref.
 *
 * Dummy release function for xe_bo_put_deferred(). Keep off.
 */
void __xe_bo_release_dummy(struct kref *kref)
{
}

/**
 * xe_bo_put_commit() - Put bos whose put was deferred by xe_bo_put_deferred().
 * @deferred: The lockless list used for the call to xe_bo_put_deferred().
 *
 * Puts all bos whose put was deferred by xe_bo_put_deferred().
 * The @deferred list can be either an onstack local list or a global
 * shared list used by a workqueue.
 */
void xe_bo_put_commit(struct llist_head *deferred)
{
	struct llist_node *freed;
	struct xe_bo *bo, *next;

	if (!deferred)
		return;

	freed = llist_del_all(deferred);
	if (!freed)
		return;

	llist_for_each_entry_safe(bo, next, freed, freed)
		drm_gem_object_free(&bo->ttm.base.refcount);
}

/**
 * xe_bo_dumb_create - Create a dumb bo as backing for a fb
 * @file_priv: ...
 * @dev: ...
 * @args: ...
 *
 * See dumb_create() hook in include/drm/drm_drv.h
 *
 * Return: ...
 */
int xe_bo_dumb_create(struct drm_file *file_priv,
		      struct drm_device *dev,
		      struct drm_mode_create_dumb *args)
{
	struct xe_device *xe = to_xe_device(dev);
	struct xe_bo *bo;
	uint32_t handle;
	int cpp = DIV_ROUND_UP(args->bpp, 8);
	int err;
	u32 page_size = max_t(u32, PAGE_SIZE,
		xe->info.vram_flags & XE_VRAM_FLAGS_NEED64K ? SZ_64K : SZ_4K);

	args->pitch = ALIGN(args->width * cpp, 64);
	args->size = ALIGN(mul_u32_u32(args->pitch, args->height),
			   page_size);

	bo = xe_bo_create_user(xe, NULL, NULL, args->size,
			       DRM_XE_GEM_CPU_CACHING_WC,
			       ttm_bo_type_device,
			       XE_BO_CREATE_VRAM_IF_DGFX(xe_device_get_root_tile(xe)) |
			       XE_BO_CREATE_USER_BIT | XE_BO_SCANOUT_BIT |
			       XE_BO_NEEDS_CPU_ACCESS);
	if (IS_ERR(bo))
		return PTR_ERR(bo);

	err = drm_gem_handle_create(file_priv, &bo->ttm.base, &handle);
	/* drop reference from allocate - handle holds it now */
	drm_gem_object_put(&bo->ttm.base);
	if (!err)
		args->handle = handle;
	return err;
}

#if IS_ENABLED(CONFIG_DRM_XE_KUNIT_TEST)
#include "tests/xe_bo.c"
#endif
