// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright (C) 2021 Western Digital Corporation or its affiliates.
 * Copyright (C) 2022 Ventana Micro Systems Inc.
 *
 * Authors:
 *	Anup Patel <apatel@ventanamicro.com>
 */

#include <linux/atomic.h>
#include <linux/bitmap.h>
#include <linux/kvm_host.h>
#include <linux/math.h>
#include <linux/spinlock.h>
#include <linux/swab.h>
#include <kvm/iodev.h>
#include <asm/csr.h>
#include <asm/kvm_aia_imsic.h>

#define IMSIC_MAX_EIX	(IMSIC_MAX_ID / BITS_PER_TYPE(u64))

struct imsic_mrif_eix {
	unsigned long eip[BITS_PER_TYPE(u64) / BITS_PER_LONG];
	unsigned long eie[BITS_PER_TYPE(u64) / BITS_PER_LONG];
};

struct imsic_mrif {
	struct imsic_mrif_eix eix[IMSIC_MAX_EIX];
	unsigned long eithreshold;
	unsigned long eidelivery;
};

struct imsic {
	struct kvm_io_device iodev;

	u32 nr_msis;
	u32 nr_eix;
	u32 nr_hw_eix;

	/*
	 * At any point in time, the register state is in
	 * one of the following places:
	 *
	 * 1) Hardware: IMSIC VS-file (vsfile_cpu >= 0)
	 * 2) Software: IMSIC SW-file (vsfile_cpu < 0)
	 */

	/* IMSIC VS-file */
	rwlock_t vsfile_lock;
	int vsfile_cpu;
	int vsfile_hgei;
	void __iomem *vsfile_va;
	phys_addr_t vsfile_pa;

	/* IMSIC SW-file */
	struct imsic_mrif *swfile;
	phys_addr_t swfile_pa;
	spinlock_t swfile_extirq_lock;
};

#define imsic_vs_csr_read(__c)			\
({						\
	unsigned long __r;			\
	csr_write(CSR_VSISELECT, __c);		\
	__r = csr_read(CSR_VSIREG);		\
	__r;					\
})

#define imsic_read_switchcase(__ireg)			\
	case __ireg:					\
		return imsic_vs_csr_read(__ireg);
#define imsic_read_switchcase_2(__ireg)			\
	imsic_read_switchcase(__ireg + 0)		\
	imsic_read_switchcase(__ireg + 1)
#define imsic_read_switchcase_4(__ireg)			\
	imsic_read_switchcase_2(__ireg + 0)		\
	imsic_read_switchcase_2(__ireg + 2)
#define imsic_read_switchcase_8(__ireg)			\
	imsic_read_switchcase_4(__ireg + 0)		\
	imsic_read_switchcase_4(__ireg + 4)
#define imsic_read_switchcase_16(__ireg)		\
	imsic_read_switchcase_8(__ireg + 0)		\
	imsic_read_switchcase_8(__ireg + 8)
#define imsic_read_switchcase_32(__ireg)		\
	imsic_read_switchcase_16(__ireg + 0)		\
	imsic_read_switchcase_16(__ireg + 16)
#define imsic_read_switchcase_64(__ireg)		\
	imsic_read_switchcase_32(__ireg + 0)		\
	imsic_read_switchcase_32(__ireg + 32)

static unsigned long imsic_eix_read(int ireg)
{
	switch (ireg) {
	imsic_read_switchcase_64(IMSIC_EIP0)
	imsic_read_switchcase_64(IMSIC_EIE0)
	}

	return 0;
}

#define imsic_vs_csr_swap(__c, __v)		\
({						\
	unsigned long __r;			\
	csr_write(CSR_VSISELECT, __c);		\
	__r = csr_swap(CSR_VSIREG, __v);	\
	__r;					\
})

#define imsic_swap_switchcase(__ireg, __v)		\
	case __ireg:					\
		return imsic_vs_csr_swap(__ireg, __v);
#define imsic_swap_switchcase_2(__ireg, __v)		\
	imsic_swap_switchcase(__ireg + 0, __v)		\
	imsic_swap_switchcase(__ireg + 1, __v)
#define imsic_swap_switchcase_4(__ireg, __v)		\
	imsic_swap_switchcase_2(__ireg + 0, __v)	\
	imsic_swap_switchcase_2(__ireg + 2, __v)
#define imsic_swap_switchcase_8(__ireg, __v)		\
	imsic_swap_switchcase_4(__ireg + 0, __v)	\
	imsic_swap_switchcase_4(__ireg + 4, __v)
#define imsic_swap_switchcase_16(__ireg, __v)		\
	imsic_swap_switchcase_8(__ireg + 0, __v)	\
	imsic_swap_switchcase_8(__ireg + 8, __v)
#define imsic_swap_switchcase_32(__ireg, __v)		\
	imsic_swap_switchcase_16(__ireg + 0, __v)	\
	imsic_swap_switchcase_16(__ireg + 16, __v)
#define imsic_swap_switchcase_64(__ireg, __v)		\
	imsic_swap_switchcase_32(__ireg + 0, __v)	\
	imsic_swap_switchcase_32(__ireg + 32, __v)

static unsigned long imsic_eix_swap(int ireg, unsigned long val)
{
	switch (ireg) {
	imsic_swap_switchcase_64(IMSIC_EIP0, val)
	imsic_swap_switchcase_64(IMSIC_EIE0, val)
	}

	return 0;
}

#define imsic_vs_csr_write(__c, __v)		\
do {						\
	csr_write(CSR_VSISELECT, __c);		\
	csr_write(CSR_VSIREG, __v);		\
} while (0)

#define imsic_write_switchcase(__ireg, __v)		\
	case __ireg:					\
		imsic_vs_csr_write(__ireg, __v);	\
		break;
#define imsic_write_switchcase_2(__ireg, __v)		\
	imsic_write_switchcase(__ireg + 0, __v)		\
	imsic_write_switchcase(__ireg + 1, __v)
#define imsic_write_switchcase_4(__ireg, __v)		\
	imsic_write_switchcase_2(__ireg + 0, __v)	\
	imsic_write_switchcase_2(__ireg + 2, __v)
#define imsic_write_switchcase_8(__ireg, __v)		\
	imsic_write_switchcase_4(__ireg + 0, __v)	\
	imsic_write_switchcase_4(__ireg + 4, __v)
#define imsic_write_switchcase_16(__ireg, __v)		\
	imsic_write_switchcase_8(__ireg + 0, __v)	\
	imsic_write_switchcase_8(__ireg + 8, __v)
#define imsic_write_switchcase_32(__ireg, __v)		\
	imsic_write_switchcase_16(__ireg + 0, __v)	\
	imsic_write_switchcase_16(__ireg + 16, __v)
#define imsic_write_switchcase_64(__ireg, __v)		\
	imsic_write_switchcase_32(__ireg + 0, __v)	\
	imsic_write_switchcase_32(__ireg + 32, __v)

static void imsic_eix_write(int ireg, unsigned long val)
{
	switch (ireg) {
	imsic_write_switchcase_64(IMSIC_EIP0, val)
	imsic_write_switchcase_64(IMSIC_EIE0, val)
	}
}

#define imsic_vs_csr_set(__c, __v)		\
do {						\
	csr_write(CSR_VSISELECT, __c);		\
	csr_set(CSR_VSIREG, __v);		\
} while (0)

#define imsic_set_switchcase(__ireg, __v)		\
	case __ireg:					\
		imsic_vs_csr_set(__ireg, __v);		\
		break;
#define imsic_set_switchcase_2(__ireg, __v)		\
	imsic_set_switchcase(__ireg + 0, __v)		\
	imsic_set_switchcase(__ireg + 1, __v)
#define imsic_set_switchcase_4(__ireg, __v)		\
	imsic_set_switchcase_2(__ireg + 0, __v)		\
	imsic_set_switchcase_2(__ireg + 2, __v)
#define imsic_set_switchcase_8(__ireg, __v)		\
	imsic_set_switchcase_4(__ireg + 0, __v)		\
	imsic_set_switchcase_4(__ireg + 4, __v)
#define imsic_set_switchcase_16(__ireg, __v)		\
	imsic_set_switchcase_8(__ireg + 0, __v)		\
	imsic_set_switchcase_8(__ireg + 8, __v)
#define imsic_set_switchcase_32(__ireg, __v)		\
	imsic_set_switchcase_16(__ireg + 0, __v)	\
	imsic_set_switchcase_16(__ireg + 16, __v)
#define imsic_set_switchcase_64(__ireg, __v)		\
	imsic_set_switchcase_32(__ireg + 0, __v)	\
	imsic_set_switchcase_32(__ireg + 32, __v)

static void imsic_eix_set(int ireg, unsigned long val)
{
	switch (ireg) {
	imsic_set_switchcase_64(IMSIC_EIP0, val)
	imsic_set_switchcase_64(IMSIC_EIE0, val)
	}
}

static unsigned long imsic_mrif_atomic_rmw(struct imsic_mrif *mrif,
					   unsigned long *ptr,
					   unsigned long new_val,
					   unsigned long wr_mask)
{
	unsigned long old_val = 0, tmp = 0;

	__asm__ __volatile__ (
		"0:	lr.w.aq   %1, %0\n"
		"	and       %2, %1, %3\n"
		"	or        %2, %2, %4\n"
		"	sc.w.rl   %2, %2, %0\n"
		"	bnez      %2, 0b"
		: "+A" (*ptr), "+r" (old_val), "+r" (tmp)
		: "r" (~wr_mask), "r" (new_val & wr_mask)
		: "memory");

	return old_val;
}

static unsigned long imsic_mrif_atomic_or(struct imsic_mrif *mrif,
					  unsigned long *ptr,
					  unsigned long val)
{
	return atomic_long_fetch_or(val, (atomic_long_t *)ptr);
}

#define imsic_mrif_atomic_write(__mrif, __ptr, __new_val)	\
		imsic_mrif_atomic_rmw(__mrif, __ptr, __new_val, -1UL)
#define imsic_mrif_atomic_read(__mrif, __ptr)			\
		imsic_mrif_atomic_or(__mrif, __ptr, 0)

static u32 imsic_mrif_topei(struct imsic_mrif *mrif, u32 nr_eix, u32 nr_msis)
{
	struct imsic_mrif_eix *eix;
	u32 i, imin, imax, ei, max_msi;
	unsigned long eipend[BITS_PER_TYPE(u64) / BITS_PER_LONG];
	unsigned long eithreshold = imsic_mrif_atomic_read(mrif,
							&mrif->eithreshold);

	max_msi = (eithreshold && (eithreshold <= nr_msis)) ?
		   eithreshold : nr_msis;
	for (ei = 0; ei < nr_eix; ei++) {
		eix = &mrif->eix[ei];
		eipend[0] = imsic_mrif_atomic_read(mrif, &eix->eie[0]) &
			    imsic_mrif_atomic_read(mrif, &eix->eip[0]);
#ifdef CONFIG_32BIT
		eipend[1] = imsic_mrif_atomic_read(mrif, &eix->eie[1]) &
			    imsic_mrif_atomic_read(mrif, &eix->eip[1]);
		if (!eipend[0] && !eipend[1])
#else
		if (!eipend[0])
#endif
			continue;

		imin = ei * BITS_PER_TYPE(u64);
		imax = ((imin + BITS_PER_TYPE(u64)) < max_msi) ?
			imin + BITS_PER_TYPE(u64) : max_msi;
		for (i = (!imin) ? 1 : imin; i < imax; i++) {
			if (test_bit(i - imin, eipend))
				return (i << TOPEI_ID_SHIFT) | i;
		}
	}

	return 0;
}

static int imsic_mrif_isel_check(u32 nr_eix, unsigned long isel)
{
	u32 num = 0;

	switch (isel) {
	case IMSIC_EIDELIVERY:
	case IMSIC_EITHRESHOLD:
		break;
	case IMSIC_EIP0 ... IMSIC_EIP63:
		num = isel - IMSIC_EIP0;
		break;
	case IMSIC_EIE0 ... IMSIC_EIE63:
		num = isel - IMSIC_EIE0;
		break;
	default:
		return -ENOENT;
	}
#ifndef CONFIG_32BIT
	if (num & 0x1)
		return -EINVAL;
#endif
	if ((num / 2) >= nr_eix)
		return -EINVAL;

	return 0;
}

static int imsic_mrif_rmw(struct imsic_mrif *mrif, u32 nr_eix,
			  unsigned long isel, unsigned long *val,
			  unsigned long new_val, unsigned long wr_mask)
{
	bool pend;
	struct imsic_mrif_eix *eix;
	unsigned long *ei, num, old_val = 0;

	switch (isel) {
	case IMSIC_EIDELIVERY:
		old_val = imsic_mrif_atomic_rmw(mrif, &mrif->eidelivery,
						new_val, wr_mask & 0x1);
		break;
	case IMSIC_EITHRESHOLD:
		old_val = imsic_mrif_atomic_rmw(mrif, &mrif->eithreshold,
				new_val, wr_mask & (IMSIC_MAX_ID - 1));
		break;
	case IMSIC_EIP0 ... IMSIC_EIP63:
	case IMSIC_EIE0 ... IMSIC_EIE63:
		if (isel >= IMSIC_EIP0 && isel <= IMSIC_EIP63) {
			pend = true;
			num = isel - IMSIC_EIP0;
		} else {
			pend = false;
			num = isel - IMSIC_EIE0;
		}

		if ((num / 2) >= nr_eix)
			return -EINVAL;
		eix = &mrif->eix[num / 2];

#ifndef CONFIG_32BIT
		if (num & 0x1)
			return -EINVAL;
		ei = (pend) ? &eix->eip[0] : &eix->eie[0];
#else
		ei = (pend) ? &eix->eip[num & 0x1] : &eix->eie[num & 0x1];
#endif

		/* Bit0 of EIP0 or EIE0 is read-only */
		if (!num)
			wr_mask &= ~BIT(0);

		old_val = imsic_mrif_atomic_rmw(mrif, ei, new_val, wr_mask);
		break;
	default:
		return -ENOENT;
	}

	if (val)
		*val = old_val;

	return 0;
}

struct imsic_vsfile_read_data {
	int hgei;
	u32 nr_eix;
	bool clear;
	struct imsic_mrif *mrif;
};

static void imsic_vsfile_local_read(void *data)
{
	u32 i;
	struct imsic_mrif_eix *eix;
	struct imsic_vsfile_read_data *idata = data;
	struct imsic_mrif *mrif = idata->mrif;
	unsigned long new_hstatus, old_hstatus, old_vsiselect;

	old_vsiselect = csr_read(CSR_VSISELECT);
	old_hstatus = csr_read(CSR_HSTATUS);
	new_hstatus = old_hstatus & ~HSTATUS_VGEIN;
	new_hstatus |= ((unsigned long)idata->hgei) << HSTATUS_VGEIN_SHIFT;
	csr_write(CSR_HSTATUS, new_hstatus);

	/*
	 * We don't use imsic_mrif_atomic_xyz() functions to store
	 * values in MRIF because imsic_vsfile_read() is always called
	 * with pointer to temporary MRIF on stack.
	 */

	if (idata->clear) {
		mrif->eidelivery = imsic_vs_csr_swap(IMSIC_EIDELIVERY, 0);
		mrif->eithreshold = imsic_vs_csr_swap(IMSIC_EITHRESHOLD, 0);
		for (i = 0; i < idata->nr_eix; i++) {
			eix = &mrif->eix[i];
			eix->eip[0] = imsic_eix_swap(IMSIC_EIP0 + i * 2, 0);
			eix->eie[0] = imsic_eix_swap(IMSIC_EIE0 + i * 2, 0);
#ifdef CONFIG_32BIT
			eix->eip[1] = imsic_eix_swap(IMSIC_EIP0 + i * 2 + 1, 0);
			eix->eie[1] = imsic_eix_swap(IMSIC_EIE0 + i * 2 + 1, 0);
#endif
		}
	} else {
		mrif->eidelivery = imsic_vs_csr_read(IMSIC_EIDELIVERY);
		mrif->eithreshold = imsic_vs_csr_read(IMSIC_EITHRESHOLD);
		for (i = 0; i < idata->nr_eix; i++) {
			eix = &mrif->eix[i];
			eix->eip[0] = imsic_eix_read(IMSIC_EIP0 + i * 2);
			eix->eie[0] = imsic_eix_read(IMSIC_EIE0 + i * 2);
#ifdef CONFIG_32BIT
			eix->eip[1] = imsic_eix_read(IMSIC_EIP0 + i * 2 + 1);
			eix->eie[1] = imsic_eix_read(IMSIC_EIE0 + i * 2 + 1);
#endif
		}
	}

	csr_write(CSR_HSTATUS, old_hstatus);
	csr_write(CSR_VSISELECT, old_vsiselect);
}

static void imsic_vsfile_read(int vsfile_hgei, int vsfile_cpu, u32 nr_eix,
			      bool clear, struct imsic_mrif *mrif)
{
	struct imsic_vsfile_read_data idata;

	/* We can only read clear if we have a IMSIC VS-file */
	if (vsfile_cpu < 0 || vsfile_hgei <= 0)
		return;

	/* We can only read clear on local CPU */
	idata.hgei = vsfile_hgei;
	idata.nr_eix = nr_eix;
	idata.clear = clear;
	idata.mrif = mrif;
	on_each_cpu_mask(cpumask_of(vsfile_cpu),
			 imsic_vsfile_local_read, &idata, 1);
}

struct imsic_vsfile_rw_data {
	int hgei;
	int isel;
	bool write;
	unsigned long val;
};

static void imsic_vsfile_local_rw(void *data)
{
	struct imsic_vsfile_rw_data *idata = data;
	unsigned long new_hstatus, old_hstatus, old_vsiselect;

	old_vsiselect = csr_read(CSR_VSISELECT);
	old_hstatus = csr_read(CSR_HSTATUS);
	new_hstatus = old_hstatus & ~HSTATUS_VGEIN;
	new_hstatus |= ((unsigned long)idata->hgei) << HSTATUS_VGEIN_SHIFT;
	csr_write(CSR_HSTATUS, new_hstatus);

	switch (idata->isel) {
	case IMSIC_EIDELIVERY:
		if (idata->write)
			imsic_vs_csr_write(IMSIC_EIDELIVERY, idata->val);
		else
			idata->val = imsic_vs_csr_read(IMSIC_EIDELIVERY);
		break;
	case IMSIC_EITHRESHOLD:
		if (idata->write)
			imsic_vs_csr_write(IMSIC_EITHRESHOLD, idata->val);
		else
			idata->val = imsic_vs_csr_read(IMSIC_EITHRESHOLD);
		break;
	case IMSIC_EIP0 ... IMSIC_EIP63:
	case IMSIC_EIE0 ... IMSIC_EIE63:
#ifndef CONFIG_32BIT
		if (idata->isel & 0x1)
			break;
#endif
		if (idata->write)
			imsic_eix_write(idata->isel, idata->val);
		else
			idata->val = imsic_eix_read(idata->isel);
		break;
	default:
		break;
	}

	csr_write(CSR_HSTATUS, old_hstatus);
	csr_write(CSR_VSISELECT, old_vsiselect);
}

static int imsic_vsfile_rw(int vsfile_hgei, int vsfile_cpu, u32 nr_eix,
			   unsigned long isel, bool write,
			   unsigned long *val)
{
	int rc;
	struct imsic_vsfile_rw_data rdata;

	/* We can only access register if we have a IMSIC VS-file */
	if (vsfile_cpu < 0 || vsfile_hgei <= 0)
		return -EINVAL;

	/* Check IMSIC register iselect */
	rc = imsic_mrif_isel_check(nr_eix, isel);
	if (rc)
		return rc;

	/* We can only access register on local CPU */
	rdata.hgei = vsfile_hgei;
	rdata.isel = isel;
	rdata.write = write;
	rdata.val = (write) ? *val : 0;
	on_each_cpu_mask(cpumask_of(vsfile_cpu),
			 imsic_vsfile_local_rw, &rdata, 1);

	if (!write)
		*val = rdata.val;

	return 0;
}

static void imsic_vsfile_local_clear(int vsfile_hgei, u32 nr_eix)
{
	u32 i;
	unsigned long new_hstatus, old_hstatus, old_vsiselect;

	/* We can only zero-out if we have a IMSIC VS-file */
	if (vsfile_hgei <= 0)
		return;

	old_vsiselect = csr_read(CSR_VSISELECT);
	old_hstatus = csr_read(CSR_HSTATUS);
	new_hstatus = old_hstatus & ~HSTATUS_VGEIN;
	new_hstatus |= ((unsigned long)vsfile_hgei) << HSTATUS_VGEIN_SHIFT;
	csr_write(CSR_HSTATUS, new_hstatus);

	imsic_vs_csr_write(IMSIC_EIDELIVERY, 0);
	imsic_vs_csr_write(IMSIC_EITHRESHOLD, 0);
	for (i = 0; i < nr_eix; i++) {
		imsic_eix_write(IMSIC_EIP0 + i * 2, 0);
		imsic_eix_write(IMSIC_EIE0 + i * 2, 0);
#ifdef CONFIG_32BIT
		imsic_eix_write(IMSIC_EIP0 + i * 2 + 1, 0);
		imsic_eix_write(IMSIC_EIE0 + i * 2 + 1, 0);
#endif
	}

	csr_write(CSR_HSTATUS, old_hstatus);
	csr_write(CSR_VSISELECT, old_vsiselect);
}

static void imsic_vsfile_local_update(int vsfile_hgei, u32 nr_eix,
				      struct imsic_mrif *mrif)
{
	u32 i;
	struct imsic_mrif_eix *eix;
	unsigned long new_hstatus, old_hstatus, old_vsiselect;

	/* We can only update if we have a HW IMSIC context */
	if (vsfile_hgei <= 0)
		return;

	/*
	 * We don't use imsic_mrif_atomic_xyz() functions to read values
	 * from MRIF in this function because it is always called with
	 * pointer to temporary MRIF on stack.
	 */

	old_vsiselect = csr_read(CSR_VSISELECT);
	old_hstatus = csr_read(CSR_HSTATUS);
	new_hstatus = old_hstatus & ~HSTATUS_VGEIN;
	new_hstatus |= ((unsigned long)vsfile_hgei) << HSTATUS_VGEIN_SHIFT;
	csr_write(CSR_HSTATUS, new_hstatus);

	for (i = 0; i < nr_eix; i++) {
		eix = &mrif->eix[i];
		imsic_eix_set(IMSIC_EIP0 + i * 2, eix->eip[0]);
		imsic_eix_set(IMSIC_EIE0 + i * 2, eix->eie[0]);
#ifdef CONFIG_32BIT
		imsic_eix_set(IMSIC_EIP0 + i * 2 + 1, eix->eip[1]);
		imsic_eix_set(IMSIC_EIE0 + i * 2 + 1, eix->eie[1]);
#endif
	}
	imsic_vs_csr_write(IMSIC_EITHRESHOLD, mrif->eithreshold);
	imsic_vs_csr_write(IMSIC_EIDELIVERY, mrif->eidelivery);

	csr_write(CSR_HSTATUS, old_hstatus);
	csr_write(CSR_VSISELECT, old_vsiselect);
}

static void imsic_vsfile_cleanup(struct imsic *imsic)
{
	int old_vsfile_hgei, old_vsfile_cpu;
	unsigned long flags;

	/*
	 * We don't use imsic_mrif_atomic_xyz() functions to clear the
	 * SW-file in this function because it is always called when the
	 * VCPU is being destroyed.
	 */

	write_lock_irqsave(&imsic->vsfile_lock, flags);
	old_vsfile_hgei = imsic->vsfile_hgei;
	old_vsfile_cpu = imsic->vsfile_cpu;
	imsic->vsfile_cpu = imsic->vsfile_hgei = -1;
	imsic->vsfile_va = NULL;
	imsic->vsfile_pa = 0;
	write_unlock_irqrestore(&imsic->vsfile_lock, flags);

	memset(imsic->swfile, 0, sizeof(*imsic->swfile));

	if (old_vsfile_cpu >= 0)
		kvm_riscv_aia_free_hgei(old_vsfile_cpu, old_vsfile_hgei);
}

static void imsic_swfile_extirq_update(struct kvm_vcpu *vcpu)
{
	struct imsic *imsic = vcpu->arch.aia_context.imsic_state;
	struct imsic_mrif *mrif = imsic->swfile;
	unsigned long flags;

	/*
	 * The critical section is necessary during external interrupt
	 * updates to avoid the risk of losing interrupts due to potential
	 * interruptions between reading topei and updating pending status.
	 */

	spin_lock_irqsave(&imsic->swfile_extirq_lock, flags);

	if (imsic_mrif_atomic_read(mrif, &mrif->eidelivery) &&
	    imsic_mrif_topei(mrif, imsic->nr_eix, imsic->nr_msis))
		kvm_riscv_vcpu_set_interrupt(vcpu, IRQ_VS_EXT);
	else
		kvm_riscv_vcpu_unset_interrupt(vcpu, IRQ_VS_EXT);

	spin_unlock_irqrestore(&imsic->swfile_extirq_lock, flags);
}

static void imsic_swfile_read(struct kvm_vcpu *vcpu, bool clear,
			      struct imsic_mrif *mrif)
{
	struct imsic *imsic = vcpu->arch.aia_context.imsic_state;

	/*
	 * We don't use imsic_mrif_atomic_xyz() functions to read and
	 * write SW-file and MRIF in this function because it is always
	 * called when VCPU is not using SW-file and the MRIF points to
	 * a temporary MRIF on stack.
	 */

	memcpy(mrif, imsic->swfile, sizeof(*mrif));
	if (clear) {
		memset(imsic->swfile, 0, sizeof(*imsic->swfile));
		kvm_riscv_vcpu_unset_interrupt(vcpu, IRQ_VS_EXT);
	}
}

static void imsic_swfile_update(struct kvm_vcpu *vcpu,
				struct imsic_mrif *mrif)
{
	u32 i;
	struct imsic_mrif_eix *seix, *eix;
	struct imsic *imsic = vcpu->arch.aia_context.imsic_state;
	struct imsic_mrif *smrif = imsic->swfile;

	imsic_mrif_atomic_write(smrif, &smrif->eidelivery, mrif->eidelivery);
	imsic_mrif_atomic_write(smrif, &smrif->eithreshold, mrif->eithreshold);
	for (i = 0; i < imsic->nr_eix; i++) {
		seix = &smrif->eix[i];
		eix = &mrif->eix[i];
		imsic_mrif_atomic_or(smrif, &seix->eip[0], eix->eip[0]);
		imsic_mrif_atomic_or(smrif, &seix->eie[0], eix->eie[0]);
#ifdef CONFIG_32BIT
		imsic_mrif_atomic_or(smrif, &seix->eip[1], eix->eip[1]);
		imsic_mrif_atomic_or(smrif, &seix->eie[1], eix->eie[1]);
#endif
	}

	imsic_swfile_extirq_update(vcpu);
}

void kvm_riscv_vcpu_aia_imsic_release(struct kvm_vcpu *vcpu)
{
	unsigned long flags;
	struct imsic_mrif tmrif;
	int old_vsfile_hgei, old_vsfile_cpu;
	struct imsic *imsic = vcpu->arch.aia_context.imsic_state;

	/* Read and clear IMSIC VS-file details */
	write_lock_irqsave(&imsic->vsfile_lock, flags);
	old_vsfile_hgei = imsic->vsfile_hgei;
	old_vsfile_cpu = imsic->vsfile_cpu;
	imsic->vsfile_cpu = imsic->vsfile_hgei = -1;
	imsic->vsfile_va = NULL;
	imsic->vsfile_pa = 0;
	write_unlock_irqrestore(&imsic->vsfile_lock, flags);

	/* Do nothing, if no IMSIC VS-file to release */
	if (old_vsfile_cpu < 0)
		return;

	/*
	 * At this point, all interrupt producers are still using
	 * the old IMSIC VS-file so we first re-direct all interrupt
	 * producers.
	 */

	/* Purge the G-stage mapping */
	kvm_riscv_gstage_iounmap(vcpu->kvm,
				 vcpu->arch.aia_context.imsic_addr,
				 IMSIC_MMIO_PAGE_SZ);

	/* TODO: Purge the IOMMU mapping ??? */

	/*
	 * At this point, all interrupt producers have been re-directed
	 * to somewhere else so we move register state from the old IMSIC
	 * VS-file to the IMSIC SW-file.
	 */

	/* Read and clear register state from old IMSIC VS-file */
	memset(&tmrif, 0, sizeof(tmrif));
	imsic_vsfile_read(old_vsfile_hgei, old_vsfile_cpu, imsic->nr_hw_eix,
			  true, &tmrif);

	/* Update register state in IMSIC SW-file */
	imsic_swfile_update(vcpu, &tmrif);

	/* Free-up old IMSIC VS-file */
	kvm_riscv_aia_free_hgei(old_vsfile_cpu, old_vsfile_hgei);
}

int kvm_riscv_vcpu_aia_imsic_update(struct kvm_vcpu *vcpu)
{
	unsigned long flags;
	phys_addr_t new_vsfile_pa;
	struct imsic_mrif tmrif;
	void __iomem *new_vsfile_va;
	struct kvm *kvm = vcpu->kvm;
	struct kvm_run *run = vcpu->run;
	struct kvm_vcpu_aia *vaia = &vcpu->arch.aia_context;
	struct imsic *imsic = vaia->imsic_state;
	int ret = 0, new_vsfile_hgei = -1, old_vsfile_hgei, old_vsfile_cpu;

	/* Do nothing for emulation mode */
	if (kvm->arch.aia.mode == KVM_DEV_RISCV_AIA_MODE_EMUL)
		return 1;

	/* Read old IMSIC VS-file details */
	read_lock_irqsave(&imsic->vsfile_lock, flags);
	old_vsfile_hgei = imsic->vsfile_hgei;
	old_vsfile_cpu = imsic->vsfile_cpu;
	read_unlock_irqrestore(&imsic->vsfile_lock, flags);

	/* Do nothing if we are continuing on same CPU */
	if (old_vsfile_cpu == vcpu->cpu)
		return 1;

	/* Allocate new IMSIC VS-file */
	ret = kvm_riscv_aia_alloc_hgei(vcpu->cpu, vcpu,
				       &new_vsfile_va, &new_vsfile_pa);
	if (ret <= 0) {
		/* For HW acceleration mode, we can't continue */
		if (kvm->arch.aia.mode == KVM_DEV_RISCV_AIA_MODE_HWACCEL) {
			run->fail_entry.hardware_entry_failure_reason =
								CSR_HSTATUS;
			run->fail_entry.cpu = vcpu->cpu;
			run->exit_reason = KVM_EXIT_FAIL_ENTRY;
			return 0;
		}

		/* Release old IMSIC VS-file */
		if (old_vsfile_cpu >= 0)
			kvm_riscv_vcpu_aia_imsic_release(vcpu);

		/* For automatic mode, we continue */
		goto done;
	}
	new_vsfile_hgei = ret;

	/*
	 * At this point, all interrupt producers are still using
	 * to the old IMSIC VS-file so we first move all interrupt
	 * producers to the new IMSIC VS-file.
	 */

	/* Zero-out new IMSIC VS-file */
	imsic_vsfile_local_clear(new_vsfile_hgei, imsic->nr_hw_eix);

	/* Update G-stage mapping for the new IMSIC VS-file */
	ret = kvm_riscv_gstage_ioremap(kvm, vcpu->arch.aia_context.imsic_addr,
				       new_vsfile_pa, IMSIC_MMIO_PAGE_SZ,
				       true, true);
	if (ret)
		goto fail_free_vsfile_hgei;

	/* TODO: Update the IOMMU mapping ??? */

	/* Update new IMSIC VS-file details in IMSIC context */
	write_lock_irqsave(&imsic->vsfile_lock, flags);
	imsic->vsfile_hgei = new_vsfile_hgei;
	imsic->vsfile_cpu = vcpu->cpu;
	imsic->vsfile_va = new_vsfile_va;
	imsic->vsfile_pa = new_vsfile_pa;
	write_unlock_irqrestore(&imsic->vsfile_lock, flags);

	/*
	 * At this point, all interrupt producers have been moved
	 * to the new IMSIC VS-file so we move register state from
	 * the old IMSIC VS/SW-file to the new IMSIC VS-file.
	 */

	memset(&tmrif, 0, sizeof(tmrif));
	if (old_vsfile_cpu >= 0) {
		/* Read and clear register state from old IMSIC VS-file */
		imsic_vsfile_read(old_vsfile_hgei, old_vsfile_cpu,
				  imsic->nr_hw_eix, true, &tmrif);

		/* Free-up old IMSIC VS-file */
		kvm_riscv_aia_free_hgei(old_vsfile_cpu, old_vsfile_hgei);
	} else {
		/* Read and clear register state from IMSIC SW-file */
		imsic_swfile_read(vcpu, true, &tmrif);
	}

	/* Restore register state in the new IMSIC VS-file */
	imsic_vsfile_local_update(new_vsfile_hgei, imsic->nr_hw_eix, &tmrif);

done:
	/* Set VCPU HSTATUS.VGEIN to new IMSIC VS-file */
	vcpu->arch.guest_context.hstatus &= ~HSTATUS_VGEIN;
	if (new_vsfile_hgei > 0)
		vcpu->arch.guest_context.hstatus |=
			((unsigned long)new_vsfile_hgei) << HSTATUS_VGEIN_SHIFT;

	/* Continue run-loop */
	return 1;

fail_free_vsfile_hgei:
	kvm_riscv_aia_free_hgei(vcpu->cpu, new_vsfile_hgei);
	return ret;
}

int kvm_riscv_vcpu_aia_imsic_rmw(struct kvm_vcpu *vcpu, unsigned long isel,
				 unsigned long *val, unsigned long new_val,
				 unsigned long wr_mask)
{
	u32 topei;
	struct imsic_mrif_eix *eix;
	int r, rc = KVM_INSN_CONTINUE_NEXT_SEPC;
	struct imsic *imsic = vcpu->arch.aia_context.imsic_state;

	if (isel == KVM_RISCV_AIA_IMSIC_TOPEI) {
		/* Read pending and enabled interrupt with highest priority */
		topei = imsic_mrif_topei(imsic->swfile, imsic->nr_eix,
					 imsic->nr_msis);
		if (val)
			*val = topei;

		/* Writes ignore value and clear top pending interrupt */
		if (topei && wr_mask) {
			topei >>= TOPEI_ID_SHIFT;
			if (topei) {
				eix = &imsic->swfile->eix[topei /
							  BITS_PER_TYPE(u64)];
				clear_bit(topei & (BITS_PER_TYPE(u64) - 1),
					  eix->eip);
			}
		}
	} else {
		r = imsic_mrif_rmw(imsic->swfile, imsic->nr_eix, isel,
				   val, new_val, wr_mask);
		/* Forward unknown IMSIC register to user-space */
		if (r)
			rc = (r == -ENOENT) ? 0 : KVM_INSN_ILLEGAL_TRAP;
	}

	if (wr_mask)
		imsic_swfile_extirq_update(vcpu);

	return rc;
}

int kvm_riscv_aia_imsic_rw_attr(struct kvm *kvm, unsigned long type,
				bool write, unsigned long *val)
{
	u32 isel, vcpu_id;
	unsigned long flags;
	struct imsic *imsic;
	struct kvm_vcpu *vcpu;
	int rc, vsfile_hgei, vsfile_cpu;

	if (!kvm_riscv_aia_initialized(kvm))
		return -ENODEV;

	vcpu_id = KVM_DEV_RISCV_AIA_IMSIC_GET_VCPU(type);
	vcpu = kvm_get_vcpu_by_id(kvm, vcpu_id);
	if (!vcpu)
		return -ENODEV;

	isel = KVM_DEV_RISCV_AIA_IMSIC_GET_ISEL(type);
	imsic = vcpu->arch.aia_context.imsic_state;

	read_lock_irqsave(&imsic->vsfile_lock, flags);

	rc = 0;
	vsfile_hgei = imsic->vsfile_hgei;
	vsfile_cpu = imsic->vsfile_cpu;
	if (vsfile_cpu < 0) {
		if (write) {
			rc = imsic_mrif_rmw(imsic->swfile, imsic->nr_eix,
					    isel, NULL, *val, -1UL);
			imsic_swfile_extirq_update(vcpu);
		} else
			rc = imsic_mrif_rmw(imsic->swfile, imsic->nr_eix,
					    isel, val, 0, 0);
	}

	read_unlock_irqrestore(&imsic->vsfile_lock, flags);

	if (!rc && vsfile_cpu >= 0)
		rc = imsic_vsfile_rw(vsfile_hgei, vsfile_cpu, imsic->nr_eix,
				     isel, write, val);

	return rc;
}

int kvm_riscv_aia_imsic_has_attr(struct kvm *kvm, unsigned long type)
{
	u32 isel, vcpu_id;
	struct imsic *imsic;
	struct kvm_vcpu *vcpu;

	if (!kvm_riscv_aia_initialized(kvm))
		return -ENODEV;

	vcpu_id = KVM_DEV_RISCV_AIA_IMSIC_GET_VCPU(type);
	vcpu = kvm_get_vcpu_by_id(kvm, vcpu_id);
	if (!vcpu)
		return -ENODEV;

	isel = KVM_DEV_RISCV_AIA_IMSIC_GET_ISEL(type);
	imsic = vcpu->arch.aia_context.imsic_state;
	return imsic_mrif_isel_check(imsic->nr_eix, isel);
}

void kvm_riscv_vcpu_aia_imsic_reset(struct kvm_vcpu *vcpu)
{
	struct imsic *imsic = vcpu->arch.aia_context.imsic_state;

	if (!imsic)
		return;

	kvm_riscv_vcpu_aia_imsic_release(vcpu);

	memset(imsic->swfile, 0, sizeof(*imsic->swfile));
}

int kvm_riscv_vcpu_aia_imsic_inject(struct kvm_vcpu *vcpu,
				    u32 guest_index, u32 offset, u32 iid)
{
	unsigned long flags;
	struct imsic_mrif_eix *eix;
	struct imsic *imsic = vcpu->arch.aia_context.imsic_state;

	/* We only emulate one IMSIC MMIO page for each Guest VCPU */
	if (!imsic || !iid || guest_index ||
	    (offset != IMSIC_MMIO_SETIPNUM_LE &&
	     offset != IMSIC_MMIO_SETIPNUM_BE))
		return -ENODEV;

	iid = (offset == IMSIC_MMIO_SETIPNUM_BE) ? __swab32(iid) : iid;
	if (imsic->nr_msis <= iid)
		return -EINVAL;

	read_lock_irqsave(&imsic->vsfile_lock, flags);

	if (imsic->vsfile_cpu >= 0) {
		writel(iid, imsic->vsfile_va + IMSIC_MMIO_SETIPNUM_LE);
		kvm_vcpu_kick(vcpu);
	} else {
		eix = &imsic->swfile->eix[iid / BITS_PER_TYPE(u64)];
		set_bit(iid & (BITS_PER_TYPE(u64) - 1), eix->eip);
		imsic_swfile_extirq_update(vcpu);
	}

	read_unlock_irqrestore(&imsic->vsfile_lock, flags);

	return 0;
}

static int imsic_mmio_read(struct kvm_vcpu *vcpu, struct kvm_io_device *dev,
			   gpa_t addr, int len, void *val)
{
	if (len != 4 || (addr & 0x3) != 0)
		return -EOPNOTSUPP;

	*((u32 *)val) = 0;

	return 0;
}

static int imsic_mmio_write(struct kvm_vcpu *vcpu, struct kvm_io_device *dev,
			    gpa_t addr, int len, const void *val)
{
	struct kvm_msi msi = { 0 };

	if (len != 4 || (addr & 0x3) != 0)
		return -EOPNOTSUPP;

	msi.address_hi = addr >> 32;
	msi.address_lo = (u32)addr;
	msi.data = *((const u32 *)val);
	kvm_riscv_aia_inject_msi(vcpu->kvm, &msi);

	return 0;
};

static struct kvm_io_device_ops imsic_iodoev_ops = {
	.read = imsic_mmio_read,
	.write = imsic_mmio_write,
};

int kvm_riscv_vcpu_aia_imsic_init(struct kvm_vcpu *vcpu)
{
	int ret = 0;
	struct imsic *imsic;
	struct page *swfile_page;
	struct kvm *kvm = vcpu->kvm;

	/* Fail if we have zero IDs */
	if (!kvm->arch.aia.nr_ids)
		return -EINVAL;

	/* Allocate IMSIC context */
	imsic = kzalloc(sizeof(*imsic), GFP_KERNEL);
	if (!imsic)
		return -ENOMEM;
	vcpu->arch.aia_context.imsic_state = imsic;

	/* Setup IMSIC context  */
	imsic->nr_msis = kvm->arch.aia.nr_ids + 1;
	rwlock_init(&imsic->vsfile_lock);
	imsic->nr_eix = BITS_TO_U64(imsic->nr_msis);
	imsic->nr_hw_eix = BITS_TO_U64(kvm_riscv_aia_max_ids);
	imsic->vsfile_hgei = imsic->vsfile_cpu = -1;

	/* Setup IMSIC SW-file */
	swfile_page = alloc_pages(GFP_KERNEL | __GFP_ZERO,
				  get_order(sizeof(*imsic->swfile)));
	if (!swfile_page) {
		ret = -ENOMEM;
		goto fail_free_imsic;
	}
	imsic->swfile = page_to_virt(swfile_page);
	imsic->swfile_pa = page_to_phys(swfile_page);
	spin_lock_init(&imsic->swfile_extirq_lock);

	/* Setup IO device */
	kvm_iodevice_init(&imsic->iodev, &imsic_iodoev_ops);
	mutex_lock(&kvm->slots_lock);
	ret = kvm_io_bus_register_dev(kvm, KVM_MMIO_BUS,
				      vcpu->arch.aia_context.imsic_addr,
				      KVM_DEV_RISCV_IMSIC_SIZE,
				      &imsic->iodev);
	mutex_unlock(&kvm->slots_lock);
	if (ret)
		goto fail_free_swfile;

	return 0;

fail_free_swfile:
	free_pages((unsigned long)imsic->swfile,
		   get_order(sizeof(*imsic->swfile)));
fail_free_imsic:
	vcpu->arch.aia_context.imsic_state = NULL;
	kfree(imsic);
	return ret;
}

void kvm_riscv_vcpu_aia_imsic_cleanup(struct kvm_vcpu *vcpu)
{
	struct kvm *kvm = vcpu->kvm;
	struct imsic *imsic = vcpu->arch.aia_context.imsic_state;

	if (!imsic)
		return;

	imsic_vsfile_cleanup(imsic);

	mutex_lock(&kvm->slots_lock);
	kvm_io_bus_unregister_dev(kvm, KVM_MMIO_BUS, &imsic->iodev);
	mutex_unlock(&kvm->slots_lock);

	free_pages((unsigned long)imsic->swfile,
		   get_order(sizeof(*imsic->swfile)));

	vcpu->arch.aia_context.imsic_state = NULL;
	kfree(imsic);
}
