// SPDX-License-Identifier: GPL-2.0-only
/*
 * GXP virtual device manager.
 *
 * Copyright (C) 2021 Google LLC
 */

#include <linux/atomic.h>
#include <linux/bitops.h>
#include <linux/idr.h>
#include <linux/iommu.h>
#include <linux/pm_runtime.h>
#include <linux/refcount.h>
#include <linux/slab.h>
#include <linux/spinlock.h>

#include <gcip/gcip-alloc-helper.h>
#include <gcip/gcip-image-config.h>
#include <gcip/gcip-iommu-reserve.h>
#include <gcip/gcip-iommu.h>

#include "gxp-config.h"
#include "gxp-core-telemetry.h"
#include "gxp-debug-dump.h"
#include "gxp-dma.h"
#include "gxp-domain-pool.h"
#include "gxp-doorbell.h"
#include "gxp-eventfd.h"
#include "gxp-firmware-data.h"
#include "gxp-firmware-loader.h"
#include "gxp-firmware.h"
#include "gxp-host-device-structs.h"
#include "gxp-internal.h"
#include "gxp-lpm.h"
#include "gxp-mailbox.h"
#include "gxp-notification.h"
#include "gxp-pm.h"
#include "gxp-vd.h"

#if GXP_HAS_MCU
#include <gcip/gcip-kci.h>

#include "gxp-kci.h"
#include "gxp-mcu.h"
#endif

#include <trace/events/gxp.h>

#define KCI_RETURN_CORE_LIST_MASK 0xFF00
#define KCI_RETURN_CORE_LIST_SHIFT 8
#define KCI_RETURN_ERROR_CODE_MASK (BIT(KCI_RETURN_CORE_LIST_SHIFT) - 1u)
#define KCI_RETURN_GET_CORE_LIST(ret)                                          \
	((KCI_RETURN_CORE_LIST_MASK & (ret)) >> KCI_RETURN_CORE_LIST_SHIFT)
#define KCI_RETURN_GET_ERROR_CODE(ret) (KCI_RETURN_ERROR_CODE_MASK & (ret))

static inline void hold_core_in_reset(struct gxp_dev *gxp, uint core)
{
	gxp_write_32(gxp, GXP_CORE_REG_ETM_PWRCTL(core),
		     BIT(GXP_REG_ETM_PWRCTL_CORE_RESET_SHIFT));
}

void gxp_vd_init(struct gxp_dev *gxp)
{
	uint core;

	init_rwsem(&gxp->vd_semaphore);

	/* All cores start as free */
	for (core = 0; core < GXP_NUM_CORES; core++)
		gxp->core_to_vd[core] = NULL;
	atomic_set(&gxp->next_vdid, 0);
	ida_init(&gxp->shared_slice_idp);
}

void gxp_vd_destroy(struct gxp_dev *gxp)
{
	ida_destroy(&gxp->shared_slice_idp);
}

/* Allocates an SGT and map @daddr to it. */
static int map_ns_region(struct gxp_virtual_device *vd, dma_addr_t daddr,
			 size_t size)
{
	struct gxp_dev *gxp = vd->gxp;
	struct sg_table *sgt;
	size_t idx;
	const size_t n_reg = ARRAY_SIZE(vd->ns_regions);
	u64 gcip_map_flags = GCIP_MAP_FLAGS_DMA_RW;

	for (idx = 0; idx < n_reg; idx++) {
		if (!vd->ns_regions[idx].sgt)
			break;
	}
	if (idx == n_reg) {
		dev_err(gxp->dev, "NS regions array %zx is full", n_reg);
		return -ENOSPC;
	}
	sgt = gcip_alloc_noncontiguous(gxp->dev, size, GFP_KERNEL);
	if (!sgt)
		return -ENOMEM;

	if (!gcip_iommu_domain_map_sgt_to_iova(vd->domain, sgt, daddr, &gcip_map_flags)) {
		dev_err(gxp->dev, "NS map %pad with size %#zx failed", &daddr, size);
		gcip_free_noncontiguous(sgt);
		return -EBUSY;
	}
	vd->ns_regions[idx].daddr = daddr;
	vd->ns_regions[idx].sgt = sgt;

	return 0;
}

static void unmap_ns_region(struct gxp_virtual_device *vd, dma_addr_t daddr)
{
	struct gxp_dev *gxp = vd->gxp;
	struct sg_table *sgt;
	size_t idx;
	const size_t n_reg = ARRAY_SIZE(vd->ns_regions);

	for (idx = 0; idx < n_reg; idx++) {
		if (daddr == vd->ns_regions[idx].daddr)
			break;
	}
	if (idx == n_reg) {
		dev_warn(gxp->dev, "unable to find NS mapping @ %pad", &daddr);
		return;
	}

	sgt = vd->ns_regions[idx].sgt;
	vd->ns_regions[idx].sgt = NULL;
	vd->ns_regions[idx].daddr = 0;
	gcip_iommu_domain_unmap_sgt_from_iova(vd->domain, sgt, GCIP_MAP_FLAGS_DMA_RW);
	gcip_free_noncontiguous(sgt);
}

/* Maps the shared buffer region to @vd->domain. */
static int map_core_shared_buffer(struct gxp_virtual_device *vd)
{
	struct gxp_dev *gxp = vd->gxp;
	const size_t shared_size = GXP_SHARED_SLICE_SIZE;

	if (!gxp->shared_buf.paddr)
		return 0;
	return gcip_iommu_map(vd->domain, gxp->shared_buf.daddr,
			      gxp->shared_buf.paddr + shared_size * vd->slice_index, shared_size,
			      GCIP_MAP_FLAGS_DMA_RW);
}

/* Reverts map_core_shared_buffer. */
static void unmap_core_shared_buffer(struct gxp_virtual_device *vd)
{
	struct gxp_dev *gxp = vd->gxp;
	const size_t shared_size = GXP_SHARED_SLICE_SIZE;

	if (!gxp->shared_buf.paddr)
		return;
	gcip_iommu_unmap(vd->domain, gxp->shared_buf.daddr, shared_size);
}

/* Maps @res->daddr to @res->paddr to @vd->domain. */
static int map_resource(struct gxp_virtual_device *vd, struct gxp_mapped_resource *res)
{
	if (res->daddr == 0)
		return 0;
	return gcip_iommu_map(vd->domain, res->daddr, res->paddr, res->size, GCIP_MAP_FLAGS_DMA_RW);
}

/* Reverts map_resource. */
static void unmap_resource(struct gxp_virtual_device *vd, struct gxp_mapped_resource *res)
{
	if (res->daddr == 0)
		return;
	gcip_iommu_unmap(vd->domain, res->daddr, res->size);
}

/*
 * System config region needs to be mapped as first page RO and remaining RW.
 *
 * Use unmap_resource() to release mapped resource.
 */
static int map_sys_cfg_resource(struct gxp_virtual_device *vd,
				struct gxp_mapped_resource *res)
{
	struct gxp_dev *gxp = vd->gxp;
	int ret;
	const size_t ro_size = GXP_FW_DATA_SYSCFG_SIZE / 2;

	if (res->daddr == 0)
		return 0;
	if (res->size != GXP_FW_DATA_SYSCFG_SIZE) {
		dev_err(gxp->dev, "invalid system cfg size: %#llx", res->size);
		return -EINVAL;
	}
	ret = gcip_iommu_map(vd->domain, res->daddr, res->paddr, ro_size, GCIP_MAP_FLAGS_DMA_RO);
	if (ret)
		return ret;
	ret = gcip_iommu_map(vd->domain, res->daddr + ro_size, res->paddr + ro_size,
			     res->size - ro_size, GCIP_MAP_FLAGS_DMA_RW);
	if (ret) {
		gcip_iommu_unmap(vd->domain, res->daddr, ro_size);
		return ret;
	}
	return 0;
}

/*
 * Assigns @res's IOVA, size from image config.
 */
static void assign_resource(struct gxp_mapped_resource *res,
			    struct gcip_image_config *img_cfg,
			    enum gxp_imgcfg_idx idx)
{
	res->daddr = img_cfg->iommu_mappings[idx].virt_address;
	res->size = gcip_config_to_size(
		img_cfg->iommu_mappings[idx].image_config_value);
}

/*
 * This function does follows:
 *  - Get CORE_CFG, VD_CFG, SYS_CFG's IOVAs and sizes from image config.
 *  - Map above regions with this layout:
 * Pool
 *  +------------------------------------+
 *  |          SLICE_0: CORE_CFG         |
 *  |           SLICE_0: VD_CFG          |
 *  | <padding to GXP_SHARED_SLICE_SIZE> |
 *  +------------------------------------+
 *  |          SLICE_1: CORE_CFG         |
 *  |           SLICE_1: VD_CFG          |
 *  | <padding to GXP_SHARED_SLICE_SIZE> |
 *  +------------------------------------+
 *  |            ... SLICE_N             |
 *  +------------------------------------+
 *  |             <padding>              |
 *  +------------------------------------+
 *  |              SYS_CFG               |
 *  +------------------------------------+
 *
 * To keep compatibility, if not both mapping[0, 1] present then this function
 * falls back to map the MCU-core shared region with hard-coded IOVA and size.
 */
static int map_cfg_regions(struct gxp_virtual_device *vd,
			   struct gcip_image_config *img_cfg)
{
	struct gxp_dev *gxp = vd->gxp;
	struct gxp_mapped_resource pool;
	struct gxp_mapped_resource res;
	size_t offset;
	int ret;

	if (img_cfg->num_iommu_mappings < 3)
		return map_core_shared_buffer(vd);
	pool = gxp_fw_data_resource(gxp);

	assign_resource(&res, img_cfg, CORE_CFG_REGION_IDX);
	offset = vd->slice_index * GXP_SHARED_SLICE_SIZE;
	res.vaddr = pool.vaddr + offset;
	res.paddr = pool.paddr + offset;
	ret = map_resource(vd, &res);
	if (ret) {
		dev_err(gxp->dev, "map core config %pad -> offset %#zx failed",
			&res.daddr, offset);
		return ret;
	}
	vd->core_cfg = res;

	assign_resource(&res, img_cfg, VD_CFG_REGION_IDX);
	offset += vd->core_cfg.size;
	res.vaddr = pool.vaddr + offset;
	res.paddr = pool.paddr + offset;
	ret = map_resource(vd, &res);
	if (ret) {
		dev_err(gxp->dev, "map VD config %pad -> offset %#zx failed",
			&res.daddr, offset);
		goto err_unmap_core;
	}
	vd->vd_cfg = res;
	/* image config correctness check */
	if (vd->core_cfg.size + vd->vd_cfg.size > GXP_SHARED_SLICE_SIZE) {
		dev_err(gxp->dev,
			"Core CFG (%#llx) + VD CFG (%#llx) exceeds %#x",
			vd->core_cfg.size, vd->vd_cfg.size,
			GXP_SHARED_SLICE_SIZE);
		ret = -ENOSPC;
		goto err_unmap_vd;
	}
	assign_resource(&res, img_cfg, SYS_CFG_REGION_IDX);
	res.vaddr = gxp_fw_data_system_cfg(gxp);
	offset = res.vaddr - pool.vaddr;
	res.paddr = pool.paddr + offset;
	ret = map_sys_cfg_resource(vd, &res);
	if (ret) {
		dev_err(gxp->dev, "map sys config %pad -> offset %#zx failed",
			&res.daddr, offset);
		goto err_unmap_vd;
	}
	vd->sys_cfg = res;

	return 0;

err_unmap_vd:
	unmap_resource(vd, &vd->vd_cfg);
	vd->vd_cfg.daddr = 0;
err_unmap_core:
	unmap_resource(vd, &vd->core_cfg);
	vd->core_cfg.daddr = 0;
	return ret;
}

static void unmap_cfg_regions(struct gxp_virtual_device *vd)
{
	if (vd->core_cfg.daddr == 0)
		return unmap_core_shared_buffer(vd);

	unmap_resource(vd, &vd->sys_cfg);
	unmap_resource(vd, &vd->vd_cfg);
	unmap_resource(vd, &vd->core_cfg);
}

static int gxp_vd_imgcfg_map(void *data, dma_addr_t daddr, phys_addr_t paddr,
			     size_t size, unsigned int flags)
{
	struct gxp_virtual_device *vd = data;

	if (flags & GCIP_IMAGE_CONFIG_FLAGS_SECURE)
		return 0;

	return map_ns_region(vd, daddr, size);
}

static void gxp_vd_imgcfg_unmap(void *data, dma_addr_t daddr, size_t size,
				unsigned int flags)
{
	struct gxp_virtual_device *vd = data;

	if (flags & GCIP_IMAGE_CONFIG_FLAGS_SECURE)
		return;

	unmap_ns_region(vd, daddr);
}

/* TODO(b/299037074): Remove core's accesses to LPM. */
static int map_remote_lpm(struct gxp_virtual_device *vd,
			  struct gcip_image_config *img_cfg)
{
	struct gxp_mapped_resource res;
	int ret;

	if (img_cfg->num_iommu_mappings != REMOTE_LPM_IDX + 1)
		/* Core doesn't require remote lpm */
		return 0;

	res.daddr = img_cfg->iommu_mappings[REMOTE_LPM_IDX].virt_address;
	res.paddr = (img_cfg->iommu_mappings[REMOTE_LPM_IDX].image_config_value) &
		    GCIP_IMG_CFG_ADDR_MASK;
	res.size = gcip_config_to_size(img_cfg->iommu_mappings[REMOTE_LPM_IDX].image_config_value);
	ret = map_resource(vd, &res);
	if (ret)
		return ret;

	vd->lpm = res;
	return 0;
}

static void unmap_remote_lpm(struct gxp_virtual_device *vd)
{
	unmap_resource(vd, &vd->lpm);
}

static int
map_fw_image_config(struct gxp_dev *gxp, struct gxp_virtual_device *vd,
		    struct gxp_firmware_loader_manager *fw_loader_mgr)
{
	int ret;
	struct gcip_image_config *cfg;
	static const struct gcip_image_config_ops gxp_vd_imgcfg_ops = {
		.map = gxp_vd_imgcfg_map,
		.unmap = gxp_vd_imgcfg_unmap,
	};

	cfg = &fw_loader_mgr->core_img_cfg;
	ret = gcip_image_config_parser_init(&vd->cfg_parser, &gxp_vd_imgcfg_ops,
					    gxp->dev, vd);
	/* parser_init() never fails unless we pass invalid OPs. */
	if (unlikely(ret))
		return ret;
	ret = gcip_image_config_parse(&vd->cfg_parser, cfg);
	if (ret) {
		dev_err(gxp->dev, "Image config mapping failed");
		return ret;
	}
	ret = map_cfg_regions(vd, cfg);
	if (ret) {
		dev_err(gxp->dev, "Config regions mapping failed");
		goto err;
	}

	ret = map_remote_lpm(vd, cfg);
	if (ret) {
		dev_err(gxp->dev, "Remote LPM mapping failed");
		unmap_cfg_regions(vd);
		goto err;
	}

	return 0;
err:
	gcip_image_config_clear(&vd->cfg_parser);
	return ret;
}

static void unmap_fw_image_config(struct gxp_dev *gxp,
				  struct gxp_virtual_device *vd)
{
	unmap_remote_lpm(vd);
	unmap_cfg_regions(vd);
	gcip_image_config_clear(&vd->cfg_parser);
}

static int map_fw_image(struct gxp_dev *gxp, struct gxp_virtual_device *vd)
{
	/* Maps all FW regions together. */
	return gcip_iommu_map(vd->domain, gxp->fwbufs[0].daddr, gxp->fwbufs[0].paddr,
			      gxp->fwbufs[0].size * GXP_NUM_CORES, GCIP_MAP_FLAGS_DMA_RO);
}

static void unmap_fw_image(struct gxp_dev *gxp, struct gxp_virtual_device *vd)
{
	gcip_iommu_unmap(vd->domain, gxp->fwbufs[0].daddr, gxp->fwbufs[0].size * GXP_NUM_CORES);
}

static int map_core_telemetry_buffers(struct gxp_dev *gxp,
				      struct gxp_virtual_device *vd,
				      uint core_list)
{
	struct buffer_data *data;
	int core, ret;

	if (!gxp->core_telemetry_mgr)
		return 0;

	mutex_lock(&gxp->core_telemetry_mgr->lock);
	data = gxp->core_telemetry_mgr->buff_data;

	if (!data || !data->is_enabled)
		goto out_unlock;
	for (core = 0; core < GXP_NUM_CORES; core++) {
		if (!(BIT(core) & core_list))
			continue;
		ret = gxp_dma_map_allocated_coherent_buffer(gxp, &data->buffers[core], vd->domain,
							    0);
		if (ret) {
			dev_err(gxp->dev, "Mapping core telemetry buffer to core %d failed", core);
			goto error;
		}
	}

out_unlock:
	mutex_unlock(&gxp->core_telemetry_mgr->lock);
	return 0;

error:
	while (core--) {
		if (!(BIT(core) & core_list))
			continue;
		gxp_dma_unmap_allocated_coherent_buffer(gxp, vd->domain, &data->buffers[core]);
	}
	mutex_unlock(&gxp->core_telemetry_mgr->lock);
	return ret;
}

static void unmap_core_telemetry_buffers(struct gxp_dev *gxp,
					 struct gxp_virtual_device *vd,
					 uint core_list)
{
	struct buffer_data *data;
	int core;

	if (!gxp->core_telemetry_mgr)
		return;
	mutex_lock(&gxp->core_telemetry_mgr->lock);
	data = gxp->core_telemetry_mgr->buff_data;

	if (!data || !data->is_enabled)
		goto out_unlock;
	for (core = 0; core < GXP_NUM_CORES; core++) {
		if (!(BIT(core) & core_list))
			continue;
		gxp_dma_unmap_allocated_coherent_buffer(gxp, vd->domain, &data->buffers[core]);
	}

out_unlock:
	mutex_unlock(&gxp->core_telemetry_mgr->lock);
}

static int map_debug_dump_buffer(struct gxp_dev *gxp,
				 struct gxp_virtual_device *vd)
{
	if (!gxp->debug_dump_mgr)
		return 0;

	return gxp_dma_map_allocated_coherent_buffer(
		gxp, &gxp->debug_dump_mgr->buf, vd->domain, 0);
}

static void unmap_debug_dump_buffer(struct gxp_dev *gxp,
				    struct gxp_virtual_device *vd)
{
	if (!gxp->debug_dump_mgr)
		return;

	gxp_dma_unmap_allocated_coherent_buffer(gxp, vd->domain,
						&gxp->debug_dump_mgr->buf);
}

static int assign_cores(struct gxp_virtual_device *vd)
{
	struct gxp_dev *gxp = vd->gxp;
	uint core;
	uint available_cores = 0;

	if (!gxp_is_direct_mode(gxp)) {
		/* We don't do core assignment when cores are managed by MCU. */
		vd->core_list = BIT(GXP_NUM_CORES) - 1;
		return 0;
	}
	vd->core_list = 0;
	for (core = 0; core < GXP_NUM_CORES; core++) {
		if (gxp->core_to_vd[core] == NULL) {
			if (available_cores < vd->num_cores)
				vd->core_list |= BIT(core);
			available_cores++;
		}
	}
	if (available_cores < vd->num_cores) {
		dev_err(gxp->dev,
			"Insufficient available cores. Available: %u. Requested: %u\n",
			available_cores, vd->num_cores);
		return -EBUSY;
	}
	for (core = 0; core < GXP_NUM_CORES; core++)
		if (vd->core_list & BIT(core))
			gxp->core_to_vd[core] = vd;
	return 0;
}

static void unassign_cores(struct gxp_virtual_device *vd)
{
	struct gxp_dev *gxp = vd->gxp;
	uint core;

	if (!gxp_is_direct_mode(gxp))
		return;
	for (core = 0; core < GXP_NUM_CORES; core++) {
		if (gxp->core_to_vd[core] == vd)
			gxp->core_to_vd[core] = NULL;
	}
}

/* Saves the state of this VD's doorbells and clears them. */
static void vd_save_doorbells(struct gxp_virtual_device *vd)
{
	struct gxp_dev *gxp = vd->gxp;
	uint base_doorbell;
	uint i;

	base_doorbell = GXP_DOORBELLS_START +
			gxp_vd_hw_slot_id(vd) * GXP_NUM_DOORBELLS_PER_VD;
	for (i = 0; i < ARRAY_SIZE(vd->doorbells_state); i++) {
		vd->doorbells_state[i] =
			gxp_doorbell_status(gxp, base_doorbell + i);
		gxp_doorbell_clear(gxp, base_doorbell + i);
	}
}

/* Restores the state of this VD's doorbells. */
static void vd_restore_doorbells(struct gxp_virtual_device *vd)
{
	struct gxp_dev *gxp = vd->gxp;
	uint base_doorbell;
	uint i;

	base_doorbell = GXP_DOORBELLS_START +
			gxp_vd_hw_slot_id(vd) * GXP_NUM_DOORBELLS_PER_VD;
	for (i = 0; i < ARRAY_SIZE(vd->doorbells_state); i++)
		if (vd->doorbells_state[i])
			gxp_doorbell_set(gxp, base_doorbell + i);
		else
			gxp_doorbell_clear(gxp, base_doorbell + i);
}

static void debug_dump_lock(struct gxp_dev *gxp, struct gxp_virtual_device *vd)
{
	if (!mutex_trylock(&vd->debug_dump_lock)) {
		/*
		 * Release @gxp->vd_semaphore to let other virtual devices proceed
		 * their works and wait for the debug dump to finish.
		 */
		up_write(&gxp->vd_semaphore);
		mutex_lock(&vd->debug_dump_lock);
		down_write(&gxp->vd_semaphore);
	}
}

static inline void debug_dump_unlock(struct gxp_virtual_device *vd)
{
	mutex_unlock(&vd->debug_dump_lock);
}

/* TODO(b/298143784):  Remove when we don't require domain finalisation before map operation. */
#if GXP_MMU_REQUIRE_ATTACH
static int gxp_attach_mmu_domain(struct gxp_dev *gxp, struct gxp_virtual_device *vd)
{
	int ret;

	/*
	 * Domain attach requires block to be in on state.
	 * TODO(b/298143784):  Remove when we have official resolution on attach/detach domain.
	 */
	ret = pm_runtime_resume_and_get(gxp->dev);
	if (ret) {
		dev_err(gxp->dev, "Failed to power on during domain attach: %d", ret);
		return ret;
	}

	ret = gxp_dma_domain_attach_device(gxp, vd->domain, vd->core_list);
	if (ret)
		dev_err(gxp->dev, "Failed to attach domain: %d", ret);
	ret = pm_runtime_put_sync(gxp->dev);
	if (ret)
		dev_err(gxp->dev, "Failed to power off during domain attach: %d", ret);

	return ret;
}

static int gxp_detach_mmu_domain(struct gxp_dev *gxp, struct gxp_virtual_device *vd)
{
	int ret;

	/*
	 * Domain detach requires block to be in on state.
	 * TODO(b/298143784):  Remove when we have official resolution on attach/detach domain.
	 */
	ret = pm_runtime_resume_and_get(gxp->dev);
	if (ret) {
		dev_err(gxp->dev, "Failed to power on during domain attach: %d", ret);
		return ret;
	}

	gxp_dma_domain_detach_device(gxp, vd->domain, vd->core_list);
	ret = pm_runtime_put_sync(gxp->dev);
	if (ret)
		dev_err(gxp->dev, "Failed to power off during domain attach: %d", ret);

	return ret;

}
#endif /* GXP_MMU_REQUIRE_ATTACH */


static void gxp_vd_iommu_reserve_manager_unmap(struct gcip_iommu_reserve_manager *mgr,
					       struct gcip_iommu_mapping *mapping, void *data)
{
	gxp_vd_mapping_remove(mgr->data, data);
}

static const struct gcip_iommu_reserve_manager_ops iommu_reserve_manager_ops = {
	.unmap = gxp_vd_iommu_reserve_manager_unmap,
};

struct gxp_virtual_device *gxp_vd_allocate(struct gxp_dev *gxp,
					   u16 requested_cores)
{
	struct gxp_virtual_device *vd;
	int i;
	int err;

	trace_gxp_vd_allocate_start(requested_cores);

	lockdep_assert_held_write(&gxp->vd_semaphore);
	/* Assumes 0 < requested_cores <= GXP_NUM_CORES */
	if (requested_cores == 0 || requested_cores > GXP_NUM_CORES)
		return ERR_PTR(-EINVAL);

	vd = kzalloc(sizeof(*vd), GFP_KERNEL);
	if (!vd)
		return ERR_PTR(-ENOMEM);

	vd->gxp = gxp;
	vd->num_cores = requested_cores;
	vd->state = GXP_VD_OFF;
	vd->slice_index = -1;
	vd->client_id = -1;
	vd->tpu_client_id = -1;
	spin_lock_init(&vd->credit_lock);
	refcount_set(&vd->refcount, 1);
	vd->credit = GXP_COMMAND_CREDIT_PER_VD;
	vd->first_open = true;
	vd->vdid = atomic_inc_return(&gxp->next_vdid);
	mutex_init(&vd->fence_list_lock);
	INIT_LIST_HEAD(&vd->gxp_fence_list);
	mutex_init(&vd->debug_dump_lock);

#ifdef GXP_USE_DEFAULT_DOMAIN
	vd->domain = gxp_iommu_get_domain_for_dev(gxp);
#else
	vd->domain = gxp_domain_pool_alloc(gxp->domain_pool);
#endif
	if (!vd->domain) {
		err = -EBUSY;
		goto error_free_vd;
	}

	vd->slice_index = ida_alloc_max(&gxp->shared_slice_idp,
					GXP_NUM_SHARED_SLICES - 1, GFP_KERNEL);
	if (vd->slice_index < 0) {
		err = vd->slice_index;
		goto error_free_domain;
	}

	vd->mailbox_resp_queues = kcalloc(
		vd->num_cores, sizeof(*vd->mailbox_resp_queues), GFP_KERNEL);
	if (!vd->mailbox_resp_queues) {
		err = -ENOMEM;
		goto error_free_slice_index;
	}

	for (i = 0; i < vd->num_cores; i++) {
		INIT_LIST_HEAD(&vd->mailbox_resp_queues[i].wait_queue);
		INIT_LIST_HEAD(&vd->mailbox_resp_queues[i].dest_queue);
		spin_lock_init(&vd->mailbox_resp_queues[i].lock);
		init_waitqueue_head(&vd->mailbox_resp_queues[i].waitq);
	}

	vd->mappings_root = RB_ROOT;
	init_rwsem(&vd->mappings_semaphore);

	err = assign_cores(vd);
	if (err)
		goto error_free_resp_queues;

#if GXP_MMU_REQUIRE_ATTACH
	err = gxp_attach_mmu_domain(gxp, vd);
	if (err)
		goto error_unassign_cores;
#endif

	/*
	 * Here assumes firmware is requested before allocating a VD, which is
	 * true because we request firmware on first GXP device open.
	 */
	err = map_fw_image_config(gxp, vd, gxp->fw_loader_mgr);
	if (err)
		goto error_detach_domain;

	/* After map_fw_image_config because it needs vd->vd/core_cfg. */
	gxp_fw_data_populate_vd_cfg(gxp, vd);
	err = gxp_dma_map_core_resources(gxp, vd->domain, vd->core_list,
					 vd->slice_index);
	if (err)
		goto error_unmap_imgcfg;
	err = map_fw_image(gxp, vd);
	if (err)
		goto error_unmap_core_resources;
	err = map_core_telemetry_buffers(gxp, vd, vd->core_list);
	if (err)
		goto error_unmap_fw_data;
	err = map_debug_dump_buffer(gxp, vd);
	if (err)
		goto error_unmap_core_telemetry_buffer;

	vd->iommu_reserve_mgr =
		gcip_iommu_reserve_manager_create(vd->domain, &iommu_reserve_manager_ops, vd);
	if (IS_ERR(vd->iommu_reserve_mgr)) {
		err = PTR_ERR(vd->iommu_reserve_mgr);
		goto error_unmap_debug_dump_buffer;
	}

	trace_gxp_vd_allocate_end(vd->vdid);

	return vd;

error_unmap_debug_dump_buffer:
	unmap_debug_dump_buffer(gxp, vd);
error_unmap_core_telemetry_buffer:
	unmap_core_telemetry_buffers(gxp, vd, vd->core_list);
error_unmap_fw_data:
	unmap_fw_image(gxp, vd);
error_unmap_core_resources:
	gxp_dma_unmap_core_resources(gxp, vd->domain, vd->core_list);
error_unmap_imgcfg:
	unmap_fw_image_config(gxp, vd);
error_detach_domain:
#if GXP_MMU_REQUIRE_ATTACH
	gxp_detach_mmu_domain(gxp, vd);
error_unassign_cores:
#endif
	unassign_cores(vd);
error_free_resp_queues:
	kfree(vd->mailbox_resp_queues);
error_free_slice_index:
	if (vd->slice_index >= 0)
		ida_free(&gxp->shared_slice_idp, vd->slice_index);
error_free_domain:
#ifndef GXP_USE_DEFAULT_DOMAIN
	gxp_domain_pool_free(gxp->domain_pool, vd->domain);
#endif
error_free_vd:
	kfree(vd);

	return ERR_PTR(err);
}

void gxp_vd_release(struct gxp_virtual_device *vd)
{
	struct rb_node *node;
	struct gxp_mapping *mapping;
	struct gxp_dev *gxp = vd->gxp;
	uint core_list = vd->core_list;
	int vdid = vd->vdid;

	trace_gxp_vd_release_start(vdid);

	lockdep_assert_held_write(&gxp->vd_semaphore);
	debug_dump_lock(gxp, vd);

	if (vd->is_secure) {
		mutex_lock(&gxp->secure_vd_lock);
		gxp->secure_vd = NULL;
		mutex_unlock(&gxp->secure_vd_lock);
	}

	gcip_iommu_reserve_manager_retire(vd->iommu_reserve_mgr);
	unmap_debug_dump_buffer(gxp, vd);
	unmap_core_telemetry_buffers(gxp, vd, core_list);
	unmap_fw_image(gxp, vd);
	gxp_dma_unmap_core_resources(gxp, vd->domain, core_list);
	unmap_fw_image_config(gxp, vd);
#if GXP_MMU_REQUIRE_ATTACH
	gxp_detach_mmu_domain(gxp, vd);
#endif
	unassign_cores(vd);

	vd->gxp->mailbox_mgr->release_unconsumed_async_resps(vd);

	/*
	 * Release any un-mapped mappings
	 * Once again, it's not necessary to lock the mappings_semaphore here
	 * but do it anyway for consistency.
	 */
	down_write(&vd->mappings_semaphore);
	while ((node = rb_first(&vd->mappings_root))) {
		mapping = rb_entry(node, struct gxp_mapping, node);
		rb_erase(node, &vd->mappings_root);
		gxp_mapping_put(mapping);
	}
	up_write(&vd->mappings_semaphore);

	kfree(vd->mailbox_resp_queues);
	if (vd->slice_index >= 0)
		ida_free(&vd->gxp->shared_slice_idp, vd->slice_index);
#ifndef GXP_USE_DEFAULT_DOMAIN
	gxp_domain_pool_free(vd->gxp->domain_pool, vd->domain);
#endif

	if (vd->invalidate_eventfd)
		gxp_eventfd_put(vd->invalidate_eventfd);
	vd->invalidate_eventfd = NULL;

	vd->state = GXP_VD_RELEASED;
	debug_dump_unlock(vd);
	gxp_vd_put(vd);

	trace_gxp_vd_release_end(vdid);
}

int gxp_vd_block_ready(struct gxp_virtual_device *vd)
{
	struct gxp_dev *gxp = vd->gxp;
	enum gxp_virtual_device_state orig_state;
	int ret;

	trace_gxp_vd_block_ready_start(vd->vdid);

	lockdep_assert_held_write(&gxp->vd_semaphore);

	orig_state = vd->state;
	if (orig_state != GXP_VD_OFF && orig_state != GXP_VD_SUSPENDED)
		return -EINVAL;
	ret = gxp_dma_domain_attach_device(gxp, vd->domain, vd->core_list);
	if (ret)
		return ret;
	if (orig_state == GXP_VD_OFF)
		vd->state = GXP_VD_READY;
	if (gxp->after_vd_block_ready) {
		ret = gxp->after_vd_block_ready(gxp, vd);
		if (ret) {
			gxp_dma_domain_detach_device(gxp, vd->domain, vd->core_list);
			vd->state = orig_state;
			return ret;
		}
	}

	/*
	 * We don't know when would the secure world issue requests. Using high frequency as long
	 * as a block wakelock is held by a secure VD.
	 */
	if (vd->is_secure)
		gxp_pm_busy(gxp);
	trace_gxp_vd_block_ready_end(vd->vdid);

	return 0;
}

void gxp_vd_block_unready(struct gxp_virtual_device *vd)
{
	struct gxp_dev *gxp = vd->gxp;

	trace_gxp_vd_block_unready_start(vd->vdid);

	lockdep_assert_held_write(&gxp->vd_semaphore);

	if (gxp->before_vd_block_unready)
		gxp->before_vd_block_unready(gxp, vd);
	if (vd->state == GXP_VD_READY)
		vd->state = GXP_VD_OFF;
	gxp_dma_domain_detach_device(gxp, vd->domain, vd->core_list);

	if (vd->is_secure)
		gxp_pm_idle(gxp);
	trace_gxp_vd_block_unready_end(vd->vdid);
}

int gxp_vd_run(struct gxp_virtual_device *vd)
{
	struct gxp_dev *gxp = vd->gxp;
	int ret;
	enum gxp_virtual_device_state orig_state = vd->state;

	if (!gxp_is_direct_mode(gxp))
		return 0;

	lockdep_assert_held_write(&gxp->vd_semaphore);
	if (orig_state != GXP_VD_READY && orig_state != GXP_VD_OFF)
		return -EINVAL;
	if (orig_state == GXP_VD_OFF) {
		ret = gxp_vd_block_ready(vd);
		/*
		 * The failure of `gxp_vd_block_ready` function means following two things:
		 *
		 * 1. The MCU firmware is not working for some reason and if it was crash,
		 *    @vd->state would be set to UNAVAILABLE by the crash handler. However, by the
		 *    race, if this function holds @gxp->vd_semaphore earlier than that handler,
		 *    it is reasonable to set @vd->state to UNAVAILABLE from here.
		 *
		 * 2. Some information of vd (or client) such as client_id, slice_index are
		 *    incorrect or not allowed by the MCU firmware for some reasons and the
		 *    `allocate_vmbox` or `link_offload_vmbox` has been failed. In this case,
		 *    setting the @vd->state to UNAVAILABLE and letting the runtime close its fd
		 *    and reallocate a vd would be better than setting @vd->state to OFF.
		 *
		 * Therefore, let's set @vd->state to UNAVAILABLE if it returns an error.
		 */
		if (ret)
			goto err_vd_unavailable;
	}

	debug_dump_lock(gxp, vd);
	/* Clear all doorbells */
	vd_restore_doorbells(vd);
	ret = gxp_firmware_run(gxp, vd, vd->core_list);
	if (ret)
		goto err_vd_block_unready;
	vd->state = GXP_VD_RUNNING;
	debug_dump_unlock(vd);

	return 0;

err_vd_block_unready:
	debug_dump_unlock(vd);
	/* Run this only when gxp_vd_block_ready was executed. */
	if (orig_state == GXP_VD_OFF)
		gxp_vd_block_unready(vd);
err_vd_unavailable:
	vd->state = GXP_VD_UNAVAILABLE;
	return ret;
}

/*
 * Caller must hold gxp->vd_semaphore.
 *
 * This function will be called from the `gxp_client_destroy` function if @vd->state is not
 * GXP_VD_OFF.
 *
 * Note for the case of the MCU firmware crahses:
 *
 * In the MCU mode, the `gxp_vd_suspend` function will redirect to this function, but it will not
 * happen when the @vd->state is GXP_VD_UNAVAILABLE. Therefore, if the MCU firmware crashes,
 * @vd->state will be changed to GXP_VD_UNAVAILABLE and this function will not be called even
 * though the runtime is going to release the vd wakelock.
 *
 * It means @vd->state will not be changed to GXP_VD_OFF when the vd wkelock is released (i.e., the
 * state will be kept as GXP_VD_UNAVAILABLE) and when the `gxp_vd_block_unready` function is called
 * by releasing the block wakelock, it will not send `release_vmbox` and `unlink_offload_vmbox` KCI
 * commands to the crashed MCU firmware. This function will be finally called when the runtime
 * closes the fd of the device file.
 */
void gxp_vd_stop(struct gxp_virtual_device *vd)
{
	struct gxp_dev *gxp = vd->gxp;
	uint phys_core;
	uint core_list = vd->core_list;
	uint lpm_state;

	if (!gxp_is_direct_mode(gxp))
		return;

	lockdep_assert_held_write(&gxp->vd_semaphore);
	debug_dump_lock(gxp, vd);

	if ((vd->state == GXP_VD_OFF || vd->state == GXP_VD_READY || vd->state == GXP_VD_RUNNING) &&
	    gxp_pm_get_blk_state(gxp) != AUR_OFF) {
		for (phys_core = 0; phys_core < GXP_NUM_CORES; phys_core++) {
			if (core_list & BIT(phys_core)) {

				lpm_state = gxp_lpm_get_state(gxp, CORE_TO_PSM(phys_core));

				if (lpm_state == LPM_ACTIVE_STATE) {
					/*
					 * If the core is in PS0 (not idle), it should
					 * be held in reset before attempting SW PG.
					 */
					hold_core_in_reset(gxp, phys_core);
				} else {
					/*
					 * If the core is idle and has already transtioned to PS1,
					 * we can attempt HW PG. In this case, we should ensure
					 * that the core doesn't get awakened by an external
					 * interrupt source before we attempt to HW PG the core.
					 */
					gxp_firmware_disable_ext_interrupts(gxp, phys_core);
				}
			}
		}
	}

	gxp_firmware_stop(gxp, vd, core_list);
	if (vd->state != GXP_VD_UNAVAILABLE)
		vd->state = GXP_VD_OFF;

	debug_dump_unlock(vd);
}

static inline uint select_core(struct gxp_virtual_device *vd, uint virt_core,
			       uint phys_core)
{
	return virt_core;
}

static bool boot_state_is_suspend(struct gxp_dev *gxp,
				  struct gxp_virtual_device *vd, uint core,
				  u32 *boot_state)
{
	*boot_state = gxp_firmware_get_boot_status(gxp, vd, core);
	return *boot_state == GXP_BOOT_STATUS_SUSPENDED;
}

static bool boot_state_is_active(struct gxp_dev *gxp,
				 struct gxp_virtual_device *vd, uint core,
				 u32 *boot_state)
{
	*boot_state = gxp_firmware_get_boot_status(gxp, vd, core);
	return *boot_state == GXP_BOOT_STATUS_ACTIVE;
}

/*
 * Caller must have locked `gxp->vd_semaphore` for writing.
 *
 * This function will be called from the `gxp_client_release_vd_wakelock` function when the runtime
 * is going to release the vd wakelock only if the @vd->state is not GXP_VD_UNAVAILABLE.
 *
 * In the MCU mode, this function will redirect to the `gxp_vd_stop` function.
 */
void gxp_vd_suspend(struct gxp_virtual_device *vd)
{
	uint virt_core, phys_core;
	struct gxp_dev *gxp = vd->gxp;
	uint core_list = vd->core_list;
	u32 boot_state;
	uint failed_cores = 0;

	if (!gxp_is_direct_mode(gxp))
		return;

	lockdep_assert_held_write(&gxp->vd_semaphore);
	debug_dump_lock(gxp, vd);

	dev_info(gxp->dev, "Suspending VD vdid=%d client_id=%d...\n", vd->vdid,
		 vd->client_id);
	if (vd->state == GXP_VD_SUSPENDED) {
		dev_err(gxp->dev,
			"Attempt to suspend a virtual device twice\n");
		goto out;
	}
	gxp_pm_force_clkmux_normal(gxp);
	/*
	 * Start the suspend process for all of this VD's cores without waiting
	 * for completion.
	 */
	virt_core = 0;
	for (phys_core = 0; phys_core < GXP_NUM_CORES; phys_core++) {
		uint core = select_core(vd, virt_core, phys_core);

		if (!(core_list & BIT(phys_core)))
			continue;
		if (!gxp_lpm_wait_state_ne(gxp, CORE_TO_PSM(phys_core),
					   LPM_ACTIVE_STATE)) {
			vd->state = GXP_VD_UNAVAILABLE;
			failed_cores |= BIT(phys_core);
			hold_core_in_reset(gxp, phys_core);
			dev_err(gxp->dev, "Core %u stuck at LPM_ACTIVE_STATE",
				phys_core);
			continue;
		}
		/* Mark the boot mode as a suspend event */
		gxp_firmware_set_boot_status(gxp, vd, core, GXP_BOOT_STATUS_NONE);
		gxp_firmware_set_boot_mode(gxp, vd, core, GXP_BOOT_MODE_SUSPEND);
		/*
		 * Request a suspend event by sending a mailbox
		 * notification.
		 */
		gxp_notification_send(gxp, phys_core,
				      CORE_NOTIF_SUSPEND_REQUEST);
		virt_core++;
	}
	/* Wait for all cores to complete core suspension. */
	virt_core = 0;
	for (phys_core = 0; phys_core < GXP_NUM_CORES; phys_core++) {
		uint core = select_core(vd, virt_core, phys_core);

		if (!(core_list & BIT(phys_core)))
			continue;
		virt_core++;
		if (failed_cores & BIT(phys_core))
			continue;
		if (!gxp_lpm_wait_state_eq(gxp, CORE_TO_PSM(phys_core),
					   LPM_PG_STATE)) {
			if (!boot_state_is_suspend(gxp, vd, core,
						   &boot_state)) {
				dev_err(gxp->dev,
					"Suspension request on core %u failed (status: %u)",
					phys_core, boot_state);
				vd->state = GXP_VD_UNAVAILABLE;
				failed_cores |= BIT(phys_core);
				hold_core_in_reset(gxp, phys_core);
			}
		} else {
			/* Re-set PS1 as the default low power state. */
			gxp_lpm_enable_state(gxp, CORE_TO_PSM(phys_core),
					     LPM_CG_STATE);
		}
	}
	if (vd->state == GXP_VD_UNAVAILABLE) {
		/* shutdown all cores if virtual device is unavailable */
		for (phys_core = 0; phys_core < GXP_NUM_CORES; phys_core++)
			if (core_list & BIT(phys_core))
				gxp_pm_core_off(gxp, phys_core);
	} else {
		/* Save and clear all doorbells. */
		vd_save_doorbells(vd);
		vd->blk_switch_count_when_suspended =
			gxp_pm_get_blk_switch_count(gxp);
		vd->state = GXP_VD_SUSPENDED;
	}
	gxp_pm_resume_clkmux(gxp);
out:
	debug_dump_unlock(vd);
}

/*
 * Caller must have locked `gxp->vd_semaphore` for writing.
 */
int gxp_vd_resume(struct gxp_virtual_device *vd)
{
	int ret = 0;
	uint phys_core, virt_core;
	uint core_list = vd->core_list;
	uint timeout;
	u32 boot_state;
	struct gxp_dev *gxp = vd->gxp;
	u64 curr_blk_switch_count;
	uint failed_cores = 0;

	if (!gxp_is_direct_mode(gxp))
		return 0;

	lockdep_assert_held_write(&gxp->vd_semaphore);
	debug_dump_lock(gxp, vd);
	dev_info(gxp->dev, "Resuming VD vdid=%d client_id=%d...\n", vd->vdid,
		 vd->client_id);
	if (vd->state != GXP_VD_SUSPENDED) {
		dev_err(gxp->dev,
			"Attempt to resume a virtual device which was not suspended\n");
		ret = -EBUSY;
		goto out;
	}
	gxp_pm_force_clkmux_normal(gxp);
	curr_blk_switch_count = gxp_pm_get_blk_switch_count(gxp);

	/* Restore the doorbells state for this VD. */
	vd_restore_doorbells(vd);

	/*
	 * Start the resume process for all of this VD's cores without waiting
	 * for completion.
	 */
	virt_core = 0;
	for (phys_core = 0; phys_core < GXP_NUM_CORES; phys_core++) {
		uint core = select_core(vd, virt_core, phys_core);

		if (!(core_list & BIT(phys_core)))
			continue;
		/*
		 * The comparison is to check if blk_switch_count is
		 * changed. If it's changed, it means the block is rebooted and
		 * therefore we need to set up the hardware again.
		 */
		if (vd->blk_switch_count_when_suspended !=
		    curr_blk_switch_count) {
			ret = gxp_firmware_setup_hw_after_block_off(
				gxp, core, phys_core,
				/*verbose=*/false);
			if (ret) {
				vd->state = GXP_VD_UNAVAILABLE;
				failed_cores |= BIT(phys_core);
				dev_err(gxp->dev,
					"Failed to power up core %u\n",
					phys_core);
				continue;
			}
		}
		/* Mark this as a resume power-up event. */
		gxp_firmware_set_boot_status(gxp, vd, core, GXP_BOOT_STATUS_NONE);
		gxp_firmware_set_boot_mode(gxp, vd, core, GXP_BOOT_MODE_RESUME);
		/*
		 * Power on the core by explicitly switching its PSM to
		 * PS0 (LPM_ACTIVE_STATE).
		 */
		gxp_lpm_set_state(gxp, CORE_TO_PSM(phys_core), LPM_ACTIVE_STATE,
				  /*verbose=*/false);
		virt_core++;
	}
	/* Wait for all cores to complete core resumption. */
	virt_core = 0;
	for (phys_core = 0; phys_core < GXP_NUM_CORES; phys_core++) {
		uint core = select_core(vd, virt_core, phys_core);

		if (!(core_list & BIT(phys_core)))
			continue;

		if (!(failed_cores & BIT(phys_core))) {
			/* in microseconds */
			timeout = 1000000;
			while (--timeout) {
				if (boot_state_is_active(gxp, vd, core,
							 &boot_state))
					break;
				udelay(1 * GXP_TIME_DELAY_FACTOR);
			}
			if (timeout == 0) {
				dev_err(gxp->dev,
					"Resume request on core %u failed (status: %u)",
					phys_core, boot_state);
				ret = -EBUSY;
				vd->state = GXP_VD_UNAVAILABLE;
				failed_cores |= BIT(phys_core);
			}
		}
		virt_core++;
	}
	if (vd->state == GXP_VD_UNAVAILABLE) {
		/* shutdown all cores if virtual device is unavailable */
		for (phys_core = 0; phys_core < GXP_NUM_CORES; phys_core++) {
			if (core_list & BIT(phys_core))
				gxp_pm_core_off(gxp, phys_core);
		}
	} else {
		vd->state = GXP_VD_RUNNING;
	}
	gxp_pm_resume_clkmux(gxp);
out:
	debug_dump_unlock(vd);
	return ret;
}

/* Caller must have locked `gxp->vd_semaphore` for reading */
int gxp_vd_virt_core_to_phys_core(struct gxp_virtual_device *vd, u16 virt_core)
{
	struct gxp_dev *gxp = vd->gxp;
	uint phys_core;
	uint virt_core_index = 0;

	for (phys_core = 0; phys_core < GXP_NUM_CORES; phys_core++) {
		if (vd->core_list & BIT(phys_core)) {
			if (virt_core_index == virt_core)
				return phys_core;

			virt_core_index++;
		}
	}

	dev_dbg(gxp->dev, "No mapping for virtual core %u\n", virt_core);
	return -EINVAL;
}

int gxp_vd_phys_core_to_virt_core(struct gxp_virtual_device *vd, u32 phys_core)
{
	struct gxp_dev *gxp = vd->gxp;

	lockdep_assert_held(&vd->debug_dump_lock);

	if (!gxp_is_direct_mode(gxp)) {
		dev_dbg(gxp->dev, "%s supported only in direct mode.\n",
			__func__);
		return -EINVAL;
	}

	if (!(vd->core_list & BIT(phys_core))) {
		dev_dbg(gxp->dev, "No mapping for physical core %u\n",
			phys_core);
		return -EINVAL;
	}
	return hweight_long(vd->core_list & (BIT(phys_core) - 1));
}

int gxp_vd_mapping_store(struct gxp_virtual_device *vd, struct gxp_mapping *map)
{
	struct rb_node **link;
	struct rb_node *parent = NULL;
	dma_addr_t device_address = map->gcip_mapping->device_address;
	struct gxp_mapping *mapping;

	link = &vd->mappings_root.rb_node;

	down_write(&vd->mappings_semaphore);

	/* Figure out where to put the new node */
	while (*link) {
		parent = *link;
		mapping = rb_entry(parent, struct gxp_mapping, node);

		if (mapping->gcip_mapping->device_address > device_address)
			link = &(*link)->rb_left;
		else if (mapping->gcip_mapping->device_address < device_address)
			link = &(*link)->rb_right;
		else
			goto out;
	}

	/* Add new node and rebalance the tree. */
	rb_link_node(&map->node, parent, link);
	rb_insert_color(&map->node, &vd->mappings_root);

	/* Acquire a reference to the mapping */
	gxp_mapping_get(map);

	up_write(&vd->mappings_semaphore);

	return 0;

out:
	up_write(&vd->mappings_semaphore);
	dev_err(vd->gxp->dev, "Duplicate mapping: %pad\n", &map->gcip_mapping->device_address);
	return -EEXIST;
}

void gxp_vd_mapping_remove(struct gxp_virtual_device *vd,
			   struct gxp_mapping *map)
{
	down_write(&vd->mappings_semaphore);
	gxp_vd_mapping_remove_locked(vd, map);
	up_write(&vd->mappings_semaphore);
}

void gxp_vd_mapping_remove_locked(struct gxp_virtual_device *vd, struct gxp_mapping *map)
{
	lockdep_assert_held_write(&vd->mappings_semaphore);

	if (RB_EMPTY_NODE(&map->node))
		return;

	/* Drop the mapping from this virtual device's records */
	rb_erase(&map->node, &vd->mappings_root);
	RB_CLEAR_NODE(&map->node);

	/* Release the reference obtained in gxp_vd_mapping_store() */
	gxp_mapping_put(map);
}

static bool is_device_address_in_mapping(struct gxp_mapping *mapping,
					 dma_addr_t device_address)
{
	return ((device_address >= mapping->gcip_mapping->device_address) &&
		(device_address <
		((mapping->gcip_mapping->device_address & PAGE_MASK) +
		mapping->gcip_mapping->size)));
}

static struct gxp_mapping *
gxp_vd_mapping_internal_search(struct gxp_virtual_device *vd,
			       dma_addr_t device_address, bool check_range)
{
	struct rb_node *node;
	struct gxp_mapping *mapping;

	lockdep_assert_held(&vd->mappings_semaphore);

	node = vd->mappings_root.rb_node;

	while (node) {
		mapping = rb_entry(node, struct gxp_mapping, node);
		if ((mapping->gcip_mapping->device_address == device_address) ||
		    (check_range && is_device_address_in_mapping(mapping, device_address))) {
			gxp_mapping_get(mapping);
			return mapping; /* Found it */
		} else if (mapping->gcip_mapping->device_address > device_address) {
			node = node->rb_left;
		} else {
			node = node->rb_right;
		}
	}

	return NULL;
}

struct gxp_mapping *gxp_vd_mapping_search(struct gxp_virtual_device *vd,
					  dma_addr_t device_address)
{
	struct gxp_mapping *mapping;

	down_read(&vd->mappings_semaphore);
	mapping = gxp_vd_mapping_search_locked(vd, device_address);
	up_read(&vd->mappings_semaphore);

	return mapping;
}

struct gxp_mapping *gxp_vd_mapping_search_locked(struct gxp_virtual_device *vd,
						 dma_addr_t device_address)
{
	return gxp_vd_mapping_internal_search(vd, device_address, false);
}

struct gxp_mapping *
gxp_vd_mapping_search_in_range(struct gxp_virtual_device *vd,
			       dma_addr_t device_address)
{
	struct gxp_mapping *mapping;

	down_read(&vd->mappings_semaphore);
	mapping = gxp_vd_mapping_internal_search(vd, device_address, true);
	up_read(&vd->mappings_semaphore);

	return mapping;
}

struct gxp_mapping *gxp_vd_mapping_search_host(struct gxp_virtual_device *vd,
					       u64 host_address)
{
	struct rb_node *node;
	struct gxp_mapping *mapping;

	/*
	 * dma-buf mappings can not be looked-up by host address since they are
	 * not mapped from a user-space address.
	 */
	if (!host_address) {
		dev_dbg(vd->gxp->dev,
			"Unable to get dma-buf mapping by host address\n");
		return NULL;
	}

	down_read(&vd->mappings_semaphore);

	/* Iterate through the elements in the rbtree */
	for (node = rb_first(&vd->mappings_root); node; node = rb_next(node)) {
		mapping = rb_entry(node, struct gxp_mapping, node);
		if (mapping->host_address == host_address) {
			gxp_mapping_get(mapping);
			up_read(&vd->mappings_semaphore);
			return mapping;
		}
	}

	up_read(&vd->mappings_semaphore);

	return NULL;
}

bool gxp_vd_has_and_use_credit(struct gxp_virtual_device *vd)
{
	bool ret = true;
	unsigned long flags;

	spin_lock_irqsave(&vd->credit_lock, flags);
	if (vd->credit == 0) {
		ret = false;
	} else {
		vd->credit--;
		gxp_pm_busy(vd->gxp);
	}
	spin_unlock_irqrestore(&vd->credit_lock, flags);

	return ret;
}

void gxp_vd_release_credit(struct gxp_virtual_device *vd)
{
	unsigned long flags;

	spin_lock_irqsave(&vd->credit_lock, flags);
	if (unlikely(vd->credit >= GXP_COMMAND_CREDIT_PER_VD)) {
		dev_err(vd->gxp->dev, "unbalanced VD credit");
	} else {
		gxp_pm_idle(vd->gxp);
		vd->credit++;
	}
	spin_unlock_irqrestore(&vd->credit_lock, flags);
}

void gxp_vd_put(struct gxp_virtual_device *vd)
{
	if (!vd)
		return;
	if (refcount_dec_and_test(&vd->refcount))
		kfree(vd);
}

static void gxp_vd_invalidate_locked(struct gxp_dev *gxp, struct gxp_virtual_device *vd, u32 reason)
{
	lockdep_assert_held_write(&gxp->vd_semaphore);

	dev_err(gxp->dev, "Invalidate a VD, VDID=%d, client_id=%d", vd->vdid,
		vd->client_id);

	if (vd->state != GXP_VD_UNAVAILABLE) {
		vd->state = GXP_VD_UNAVAILABLE;
		vd->invalidated_reason = reason;
		if (vd->invalidate_eventfd)
			gxp_eventfd_signal(vd->invalidate_eventfd);
	} else {
		dev_dbg(gxp->dev, "This VD is already invalidated");
	}
}

void gxp_vd_invalidate_with_client_id(struct gxp_dev *gxp, int client_id, bool release_vmbox)
{
	struct gxp_client *client = NULL, *c;

	/*
	 * Prevent @gxp->client_list is being changed while handling the crash.
	 * The user cannot open or close an FD until this function releases the lock.
	 */
	mutex_lock(&gxp->client_list_lock);

	/*
	 * Find corresponding vd with client_id.
	 * If it holds a block wakelock, we should discard all pending/unconsumed UCI responses
	 * and change the state of the vd to GXP_VD_UNAVAILABLE.
	 */
	list_for_each_entry (c, &gxp->client_list, list_entry) {
		down_write(&c->semaphore);
		down_write(&gxp->vd_semaphore);
		if (c->vd && c->vd->client_id == client_id) {
			client = c;
			break;
		}
		up_write(&gxp->vd_semaphore);
		up_write(&c->semaphore);
	}

	mutex_unlock(&gxp->client_list_lock);

	if (!client) {
		dev_err(gxp->dev, "Failed to find a VD, client_id=%d", client_id);
		return;
	}

	gxp_vd_invalidate_locked(gxp, client->vd, GXP_INVALIDATED_CLIENT_CRASH);

	/*
	 * Release @client->semaphore first because we need this lock to block ioctls while
	 * changing the state of @client->vd to UNAVAILABLE which is already done above.
	 */
	up_write(&client->semaphore);

	if (release_vmbox)
		gxp_vd_release_vmbox(gxp, client->vd);

	up_write(&gxp->vd_semaphore);
}

void gxp_vd_invalidate(struct gxp_dev *gxp, struct gxp_virtual_device *vd, u32 reason)
{
	down_write(&gxp->vd_semaphore);
	gxp_vd_invalidate_locked(gxp, vd, reason);
	up_write(&gxp->vd_semaphore);
}

void gxp_vd_generate_debug_dump(struct gxp_dev *gxp,
				struct gxp_virtual_device *vd, uint core_list)
{
	int ret;

	if (!gxp_debug_dump_is_enabled() || !core_list)
		return;

	lockdep_assert_held_write(&gxp->vd_semaphore);

	/*
	 * We should increase the refcount of @vd because @gxp->vd_semaphore will be
	 * released below and the client can release it asynchronously.
	 */
	vd = gxp_vd_get(vd);

	/*
	 * Release @gxp->vd_semaphore before generating a debug dump and hold it
	 * again after completing debug dump to not block other virtual devices
	 * proceeding their work.
	 */
	up_write(&gxp->vd_semaphore);
	mutex_lock(&vd->debug_dump_lock);

	/*
	 * Process debug dump if its enabled and core_list is not empty.
	 * Keep on hold the client lock while processing the dumps. vd
	 * lock would be taken and released inside the debug dump
	 * implementation logic ahead.
	 */
	ret = gxp_debug_dump_process_dump_mcu_mode(gxp, core_list, vd);
	if (ret)
		dev_err(gxp->dev, "debug dump processing failed (ret=%d).\n",
			ret);

	mutex_unlock(&vd->debug_dump_lock);
	down_write(&gxp->vd_semaphore);
	gxp_vd_put(vd);
}

#if GXP_HAS_MCU
void gxp_vd_release_vmbox(struct gxp_dev *gxp, struct gxp_virtual_device *vd)
{
	struct gxp_kci *kci = &(gxp_mcu_of(gxp)->kci);
	uint core_list;
	int ret;

	if (vd->client_id < 0 || vd->mcu_crashed)
		goto out;

	gxp_vd_unlink_offload_vmbox(gxp, vd, vd->tpu_client_id, GCIP_KCI_OFFLOAD_CHIP_TYPE_TPU);

	ret = gxp_kci_release_vmbox(kci, vd->client_id);
	if (!ret)
		goto out;
	if (ret > 0 && KCI_RETURN_GET_ERROR_CODE(ret) == GCIP_KCI_ERROR_ABORTED) {
		core_list = KCI_RETURN_GET_CORE_LIST(ret);
		dev_err(gxp->dev,
			"Firmware failed to gracefully release a VMBox for client %d, core_list=%d",
			vd->client_id, core_list);
		gxp_vd_invalidate_locked(gxp, vd, GXP_INVALIDATED_VMBOX_RELEASE_FAILED);
		gxp_vd_generate_debug_dump(gxp, vd, core_list);
	} else {
		dev_err(gxp->dev, "Failed to request releasing VMBox for client %d: %d",
			vd->client_id, ret);
	}
out:
	vd->client_id = -1;
}

void gxp_vd_unlink_offload_vmbox(struct gxp_dev *gxp, struct gxp_virtual_device *vd,
				 u32 offload_client_id, u8 offload_chip_type)
{
	struct gxp_kci *kci = &(gxp_mcu_of(gxp)->kci);
	int ret;

	if (vd->client_id < 0 || vd->tpu_client_id < 0 || !vd->tpu_linked || vd->mcu_crashed)
		return;

	ret = gxp_kci_link_unlink_offload_vmbox(kci, vd->client_id, offload_client_id,
						offload_chip_type, false);
	if (ret)
		dev_err(gxp->dev,
			"Failed to unlink offload VMBox for client %d, offload client %u, offload chip type %d: %d",
			vd->client_id, offload_client_id, offload_chip_type, ret);

	vd->tpu_linked = false;
}
#endif /* GXP_HAS_MCU */
