// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright (C) 2020-2023 Loongson Technology Corporation Limited
 */

#include <linux/err.h>
#include <linux/errno.h>
#include <linux/kvm_host.h>
#include <linux/module.h>
#include <linux/preempt.h>
#include <linux/vmalloc.h>
#include <trace/events/kvm.h>
#include <asm/fpu.h>
#include <asm/inst.h>
#include <asm/loongarch.h>
#include <asm/mmzone.h>
#include <asm/numa.h>
#include <asm/time.h>
#include <asm/tlb.h>
#include <asm/kvm_csr.h>
#include <asm/kvm_vcpu.h>
#include "trace.h"

static int kvm_emu_cpucfg(struct kvm_vcpu *vcpu, larch_inst inst)
{
	int rd, rj;
	unsigned int index, ret;

	if (inst.reg2_format.opcode != cpucfg_op)
		return EMULATE_FAIL;

	rd = inst.reg2_format.rd;
	rj = inst.reg2_format.rj;
	++vcpu->stat.cpucfg_exits;
	index = vcpu->arch.gprs[rj];

	/*
	 * By LoongArch Reference Manual 2.2.10.5
	 * Return value is 0 for undefined CPUCFG index
	 *
	 * Disable preemption since hw gcsr is accessed
	 */
	preempt_disable();
	switch (index) {
	case 0 ... (KVM_MAX_CPUCFG_REGS - 1):
		vcpu->arch.gprs[rd] = vcpu->arch.cpucfg[index];
		break;
	case CPUCFG_KVM_SIG:
		/* CPUCFG emulation between 0x40000000 -- 0x400000ff */
		vcpu->arch.gprs[rd] = *(unsigned int *)KVM_SIGNATURE;
		break;
	case CPUCFG_KVM_FEATURE:
		ret = vcpu->kvm->arch.pv_features & LOONGARCH_PV_FEAT_MASK;
		vcpu->arch.gprs[rd] = ret;
		break;
	default:
		vcpu->arch.gprs[rd] = 0;
		break;
	}
	preempt_enable();

	return EMULATE_DONE;
}

static unsigned long kvm_emu_read_csr(struct kvm_vcpu *vcpu, int csrid)
{
	unsigned long val = 0;
	struct loongarch_csrs *csr = vcpu->arch.csr;

	/*
	 * From LoongArch Reference Manual Volume 1 Chapter 4.2.1
	 * For undefined CSR id, return value is 0
	 */
	if (get_gcsr_flag(csrid) & SW_GCSR)
		val = kvm_read_sw_gcsr(csr, csrid);
	else
		pr_warn_once("Unsupported csrrd 0x%x with pc %lx\n", csrid, vcpu->arch.pc);

	return val;
}

static unsigned long kvm_emu_write_csr(struct kvm_vcpu *vcpu, int csrid, unsigned long val)
{
	unsigned long old = 0;
	struct loongarch_csrs *csr = vcpu->arch.csr;

	if (get_gcsr_flag(csrid) & SW_GCSR) {
		old = kvm_read_sw_gcsr(csr, csrid);
		kvm_write_sw_gcsr(csr, csrid, val);
	} else
		pr_warn_once("Unsupported csrwr 0x%x with pc %lx\n", csrid, vcpu->arch.pc);

	return old;
}

static unsigned long kvm_emu_xchg_csr(struct kvm_vcpu *vcpu, int csrid,
				unsigned long csr_mask, unsigned long val)
{
	unsigned long old = 0;
	struct loongarch_csrs *csr = vcpu->arch.csr;

	if (get_gcsr_flag(csrid) & SW_GCSR) {
		old = kvm_read_sw_gcsr(csr, csrid);
		val = (old & ~csr_mask) | (val & csr_mask);
		kvm_write_sw_gcsr(csr, csrid, val);
		old = old & csr_mask;
	} else
		pr_warn_once("Unsupported csrxchg 0x%x with pc %lx\n", csrid, vcpu->arch.pc);

	return old;
}

static int kvm_handle_csr(struct kvm_vcpu *vcpu, larch_inst inst)
{
	unsigned int rd, rj, csrid;
	unsigned long csr_mask, val = 0;

	/*
	 * CSR value mask imm
	 * rj = 0 means csrrd
	 * rj = 1 means csrwr
	 * rj != 0,1 means csrxchg
	 */
	rd = inst.reg2csr_format.rd;
	rj = inst.reg2csr_format.rj;
	csrid = inst.reg2csr_format.csr;

	if (csrid >= LOONGARCH_CSR_PERFCTRL0 && csrid <= vcpu->arch.max_pmu_csrid) {
		if (kvm_guest_has_pmu(&vcpu->arch)) {
			vcpu->arch.pc -= 4;
			kvm_make_request(KVM_REQ_PMU, vcpu);
			return EMULATE_DONE;
		}
	}

	/* Process CSR ops */
	switch (rj) {
	case 0: /* process csrrd */
		val = kvm_emu_read_csr(vcpu, csrid);
		vcpu->arch.gprs[rd] = val;
		break;
	case 1: /* process csrwr */
		val = vcpu->arch.gprs[rd];
		val = kvm_emu_write_csr(vcpu, csrid, val);
		vcpu->arch.gprs[rd] = val;
		break;
	default: /* process csrxchg */
		val = vcpu->arch.gprs[rd];
		csr_mask = vcpu->arch.gprs[rj];
		val = kvm_emu_xchg_csr(vcpu, csrid, csr_mask, val);
		vcpu->arch.gprs[rd] = val;
	}

	return EMULATE_DONE;
}

int kvm_emu_iocsr(larch_inst inst, struct kvm_run *run, struct kvm_vcpu *vcpu)
{
	int idx, ret;
	unsigned long *val;
	u32 addr, rd, rj, opcode;

	/*
	 * Each IOCSR with different opcode
	 */
	rd = inst.reg2_format.rd;
	rj = inst.reg2_format.rj;
	opcode = inst.reg2_format.opcode;
	addr = vcpu->arch.gprs[rj];
	run->iocsr_io.phys_addr = addr;
	run->iocsr_io.is_write = 0;
	val = &vcpu->arch.gprs[rd];

	/* LoongArch is Little endian */
	switch (opcode) {
	case iocsrrdb_op:
		run->iocsr_io.len = 1;
		break;
	case iocsrrdh_op:
		run->iocsr_io.len = 2;
		break;
	case iocsrrdw_op:
		run->iocsr_io.len = 4;
		break;
	case iocsrrdd_op:
		run->iocsr_io.len = 8;
		break;
	case iocsrwrb_op:
		run->iocsr_io.len = 1;
		run->iocsr_io.is_write = 1;
		break;
	case iocsrwrh_op:
		run->iocsr_io.len = 2;
		run->iocsr_io.is_write = 1;
		break;
	case iocsrwrw_op:
		run->iocsr_io.len = 4;
		run->iocsr_io.is_write = 1;
		break;
	case iocsrwrd_op:
		run->iocsr_io.len = 8;
		run->iocsr_io.is_write = 1;
		break;
	default:
		return EMULATE_FAIL;
	}

	if (run->iocsr_io.is_write) {
		idx = srcu_read_lock(&vcpu->kvm->srcu);
		ret = kvm_io_bus_write(vcpu, KVM_IOCSR_BUS, addr, run->iocsr_io.len, val);
		srcu_read_unlock(&vcpu->kvm->srcu, idx);
		if (ret == 0)
			ret = EMULATE_DONE;
		else {
			ret = EMULATE_DO_IOCSR;
			/* Save data and let user space to write it */
			memcpy(run->iocsr_io.data, val, run->iocsr_io.len);
		}
		trace_kvm_iocsr(KVM_TRACE_IOCSR_WRITE, run->iocsr_io.len, addr, val);
	} else {
		vcpu->arch.io_gpr = rd; /* Set register id for iocsr read completion */
		idx = srcu_read_lock(&vcpu->kvm->srcu);
		ret = kvm_io_bus_read(vcpu, KVM_IOCSR_BUS, addr,
				      run->iocsr_io.len, run->iocsr_io.data);
		srcu_read_unlock(&vcpu->kvm->srcu, idx);
		if (ret == 0) {
			kvm_complete_iocsr_read(vcpu, run);
			ret = EMULATE_DONE;
		} else
			ret = EMULATE_DO_IOCSR;
		trace_kvm_iocsr(KVM_TRACE_IOCSR_READ, run->iocsr_io.len, addr, NULL);
	}

	return ret;
}

int kvm_complete_iocsr_read(struct kvm_vcpu *vcpu, struct kvm_run *run)
{
	enum emulation_result er = EMULATE_DONE;
	unsigned long *gpr = &vcpu->arch.gprs[vcpu->arch.io_gpr];

	switch (run->iocsr_io.len) {
	case 1:
		*gpr = *(s8 *)run->iocsr_io.data;
		break;
	case 2:
		*gpr = *(s16 *)run->iocsr_io.data;
		break;
	case 4:
		*gpr = *(s32 *)run->iocsr_io.data;
		break;
	case 8:
		*gpr = *(s64 *)run->iocsr_io.data;
		break;
	default:
		kvm_err("Bad IOCSR length: %d, addr is 0x%lx\n",
				run->iocsr_io.len, vcpu->arch.badv);
		er = EMULATE_FAIL;
		break;
	}

	return er;
}

int kvm_emu_idle(struct kvm_vcpu *vcpu)
{
	++vcpu->stat.idle_exits;
	trace_kvm_exit_idle(vcpu, KVM_TRACE_EXIT_IDLE);

	if (!kvm_arch_vcpu_runnable(vcpu))
		kvm_vcpu_halt(vcpu);

	return EMULATE_DONE;
}

static int kvm_trap_handle_gspr(struct kvm_vcpu *vcpu)
{
	unsigned long curr_pc;
	larch_inst inst;
	enum emulation_result er = EMULATE_DONE;
	struct kvm_run *run = vcpu->run;

	/* Fetch the instruction */
	inst.word = vcpu->arch.badi;
	curr_pc = vcpu->arch.pc;
	update_pc(&vcpu->arch);

	trace_kvm_exit_gspr(vcpu, inst.word);
	er = EMULATE_FAIL;
	switch (((inst.word >> 24) & 0xff)) {
	case 0x0: /* CPUCFG GSPR */
		trace_kvm_exit_cpucfg(vcpu, KVM_TRACE_EXIT_CPUCFG);
		er = kvm_emu_cpucfg(vcpu, inst);
		break;
	case 0x4: /* CSR{RD,WR,XCHG} GSPR */
		trace_kvm_exit_csr(vcpu, KVM_TRACE_EXIT_CSR);
		er = kvm_handle_csr(vcpu, inst);
		break;
	case 0x6: /* Cache, Idle and IOCSR GSPR */
		switch (((inst.word >> 22) & 0x3ff)) {
		case 0x18: /* Cache GSPR */
			er = EMULATE_DONE;
			trace_kvm_exit_cache(vcpu, KVM_TRACE_EXIT_CACHE);
			break;
		case 0x19: /* Idle/IOCSR GSPR */
			switch (((inst.word >> 15) & 0x1ffff)) {
			case 0xc90: /* IOCSR GSPR */
				er = kvm_emu_iocsr(inst, run, vcpu);
				break;
			case 0xc91: /* Idle GSPR */
				er = kvm_emu_idle(vcpu);
				break;
			default:
				er = EMULATE_FAIL;
				break;
			}
			break;
		default:
			er = EMULATE_FAIL;
			break;
		}
		break;
	default:
		er = EMULATE_FAIL;
		break;
	}

	/* Rollback PC only if emulation was unsuccessful */
	if (er == EMULATE_FAIL) {
		kvm_err("[%#lx]%s: unsupported gspr instruction 0x%08x\n",
			curr_pc, __func__, inst.word);

		kvm_arch_vcpu_dump_regs(vcpu);
		vcpu->arch.pc = curr_pc;
	}

	return er;
}

/*
 * Trigger GSPR:
 * 1) Execute CPUCFG instruction;
 * 2) Execute CACOP/IDLE instructions;
 * 3) Access to unimplemented CSRs/IOCSRs.
 */
static int kvm_handle_gspr(struct kvm_vcpu *vcpu, int ecode)
{
	int ret = RESUME_GUEST;
	enum emulation_result er = EMULATE_DONE;

	er = kvm_trap_handle_gspr(vcpu);

	if (er == EMULATE_DONE) {
		ret = RESUME_GUEST;
	} else if (er == EMULATE_DO_MMIO) {
		vcpu->run->exit_reason = KVM_EXIT_MMIO;
		ret = RESUME_HOST;
	} else if (er == EMULATE_DO_IOCSR) {
		vcpu->run->exit_reason = KVM_EXIT_LOONGARCH_IOCSR;
		ret = RESUME_HOST;
	} else {
		kvm_queue_exception(vcpu, EXCCODE_INE, 0);
		ret = RESUME_GUEST;
	}

	return ret;
}

int kvm_emu_mmio_read(struct kvm_vcpu *vcpu, larch_inst inst)
{
	int idx, ret;
	unsigned int op8, opcode, rd;
	struct kvm_run *run = vcpu->run;

	run->mmio.phys_addr = vcpu->arch.badv;
	vcpu->mmio_needed = 2;	/* signed */
	op8 = (inst.word >> 24) & 0xff;
	ret = EMULATE_DO_MMIO;

	switch (op8) {
	case 0x24 ... 0x27:	/* ldptr.w/d process */
		rd = inst.reg2i14_format.rd;
		opcode = inst.reg2i14_format.opcode;

		switch (opcode) {
		case ldptrw_op:
			run->mmio.len = 4;
			break;
		case ldptrd_op:
			run->mmio.len = 8;
			break;
		default:
			ret = EMULATE_FAIL;
			break;
		}
		break;
	case 0x28 ... 0x2e:	/* ld.b/h/w/d, ld.bu/hu/wu process */
		rd = inst.reg2i12_format.rd;
		opcode = inst.reg2i12_format.opcode;

		switch (opcode) {
		case ldb_op:
			run->mmio.len = 1;
			break;
		case ldbu_op:
			vcpu->mmio_needed = 1;	/* unsigned */
			run->mmio.len = 1;
			break;
		case ldh_op:
			run->mmio.len = 2;
			break;
		case ldhu_op:
			vcpu->mmio_needed = 1;	/* unsigned */
			run->mmio.len = 2;
			break;
		case ldw_op:
			run->mmio.len = 4;
			break;
		case ldwu_op:
			vcpu->mmio_needed = 1;	/* unsigned */
			run->mmio.len = 4;
			break;
		case ldd_op:
			run->mmio.len = 8;
			break;
		default:
			ret = EMULATE_FAIL;
			break;
		}
		break;
	case 0x38:	/* ldx.b/h/w/d, ldx.bu/hu/wu process */
		rd = inst.reg3_format.rd;
		opcode = inst.reg3_format.opcode;

		switch (opcode) {
		case ldxb_op:
			run->mmio.len = 1;
			break;
		case ldxbu_op:
			run->mmio.len = 1;
			vcpu->mmio_needed = 1;	/* unsigned */
			break;
		case ldxh_op:
			run->mmio.len = 2;
			break;
		case ldxhu_op:
			run->mmio.len = 2;
			vcpu->mmio_needed = 1;	/* unsigned */
			break;
		case ldxw_op:
			run->mmio.len = 4;
			break;
		case ldxwu_op:
			run->mmio.len = 4;
			vcpu->mmio_needed = 1;	/* unsigned */
			break;
		case ldxd_op:
			run->mmio.len = 8;
			break;
		default:
			ret = EMULATE_FAIL;
			break;
		}
		break;
	default:
		ret = EMULATE_FAIL;
	}

	if (ret == EMULATE_DO_MMIO) {
		trace_kvm_mmio(KVM_TRACE_MMIO_READ, run->mmio.len, run->mmio.phys_addr, NULL);

		vcpu->arch.io_gpr = rd; /* Set for kvm_complete_mmio_read() use */

		/*
		 * If mmio device such as PCH-PIC is emulated in KVM,
		 * it need not return to user space to handle the mmio
		 * exception.
		 */
		idx = srcu_read_lock(&vcpu->kvm->srcu);
		ret = kvm_io_bus_read(vcpu, KVM_MMIO_BUS, vcpu->arch.badv,
				      run->mmio.len, run->mmio.data);
		srcu_read_unlock(&vcpu->kvm->srcu, idx);
		if (!ret) {
			kvm_complete_mmio_read(vcpu, run);
			update_pc(&vcpu->arch);
			vcpu->mmio_needed = 0;
			return EMULATE_DONE;
		}

		run->mmio.is_write = 0;
		vcpu->mmio_is_write = 0;
		return EMULATE_DO_MMIO;
	}

	kvm_err("Read not supported Inst=0x%08x @%lx BadVaddr:%#lx\n",
			inst.word, vcpu->arch.pc, vcpu->arch.badv);
	kvm_arch_vcpu_dump_regs(vcpu);
	vcpu->mmio_needed = 0;

	return ret;
}

int kvm_complete_mmio_read(struct kvm_vcpu *vcpu, struct kvm_run *run)
{
	enum emulation_result er = EMULATE_DONE;
	unsigned long *gpr = &vcpu->arch.gprs[vcpu->arch.io_gpr];

	/* Update with new PC */
	update_pc(&vcpu->arch);
	switch (run->mmio.len) {
	case 1:
		if (vcpu->mmio_needed == 2)
			*gpr = *(s8 *)run->mmio.data;
		else
			*gpr = *(u8 *)run->mmio.data;
		break;
	case 2:
		if (vcpu->mmio_needed == 2)
			*gpr = *(s16 *)run->mmio.data;
		else
			*gpr = *(u16 *)run->mmio.data;
		break;
	case 4:
		if (vcpu->mmio_needed == 2)
			*gpr = *(s32 *)run->mmio.data;
		else
			*gpr = *(u32 *)run->mmio.data;
		break;
	case 8:
		*gpr = *(s64 *)run->mmio.data;
		break;
	default:
		kvm_err("Bad MMIO length: %d, addr is 0x%lx\n",
				run->mmio.len, vcpu->arch.badv);
		er = EMULATE_FAIL;
		break;
	}

	trace_kvm_mmio(KVM_TRACE_MMIO_READ, run->mmio.len,
			run->mmio.phys_addr, run->mmio.data);

	return er;
}

int kvm_emu_mmio_write(struct kvm_vcpu *vcpu, larch_inst inst)
{
	int idx, ret;
	unsigned int rd, op8, opcode;
	unsigned long curr_pc, rd_val = 0;
	struct kvm_run *run = vcpu->run;
	void *data = run->mmio.data;

	/*
	 * Update PC and hold onto current PC in case there is
	 * an error and we want to rollback the PC
	 */
	curr_pc = vcpu->arch.pc;
	update_pc(&vcpu->arch);

	op8 = (inst.word >> 24) & 0xff;
	run->mmio.phys_addr = vcpu->arch.badv;
	ret = EMULATE_DO_MMIO;
	switch (op8) {
	case 0x24 ... 0x27:	/* stptr.w/d process */
		rd = inst.reg2i14_format.rd;
		opcode = inst.reg2i14_format.opcode;

		switch (opcode) {
		case stptrw_op:
			run->mmio.len = 4;
			*(unsigned int *)data = vcpu->arch.gprs[rd];
			break;
		case stptrd_op:
			run->mmio.len = 8;
			*(unsigned long *)data = vcpu->arch.gprs[rd];
			break;
		default:
			ret = EMULATE_FAIL;
			break;
		}
		break;
	case 0x28 ... 0x2e:	/* st.b/h/w/d  process */
		rd = inst.reg2i12_format.rd;
		opcode = inst.reg2i12_format.opcode;
		rd_val = vcpu->arch.gprs[rd];

		switch (opcode) {
		case stb_op:
			run->mmio.len = 1;
			*(unsigned char *)data = rd_val;
			break;
		case sth_op:
			run->mmio.len = 2;
			*(unsigned short *)data = rd_val;
			break;
		case stw_op:
			run->mmio.len = 4;
			*(unsigned int *)data = rd_val;
			break;
		case std_op:
			run->mmio.len = 8;
			*(unsigned long *)data = rd_val;
			break;
		default:
			ret = EMULATE_FAIL;
			break;
		}
		break;
	case 0x38:	/* stx.b/h/w/d process */
		rd = inst.reg3_format.rd;
		opcode = inst.reg3_format.opcode;

		switch (opcode) {
		case stxb_op:
			run->mmio.len = 1;
			*(unsigned char *)data = vcpu->arch.gprs[rd];
			break;
		case stxh_op:
			run->mmio.len = 2;
			*(unsigned short *)data = vcpu->arch.gprs[rd];
			break;
		case stxw_op:
			run->mmio.len = 4;
			*(unsigned int *)data = vcpu->arch.gprs[rd];
			break;
		case stxd_op:
			run->mmio.len = 8;
			*(unsigned long *)data = vcpu->arch.gprs[rd];
			break;
		default:
			ret = EMULATE_FAIL;
			break;
		}
		break;
	default:
		ret = EMULATE_FAIL;
	}

	if (ret == EMULATE_DO_MMIO) {
		trace_kvm_mmio(KVM_TRACE_MMIO_WRITE, run->mmio.len, run->mmio.phys_addr, data);

		/*
		 * If mmio device such as PCH-PIC is emulated in KVM,
		 * it need not return to user space to handle the mmio
		 * exception.
		 */
		idx = srcu_read_lock(&vcpu->kvm->srcu);
		ret = kvm_io_bus_write(vcpu, KVM_MMIO_BUS, vcpu->arch.badv, run->mmio.len, data);
		srcu_read_unlock(&vcpu->kvm->srcu, idx);
		if (!ret)
			return EMULATE_DONE;

		run->mmio.is_write = 1;
		vcpu->mmio_needed = 1;
		vcpu->mmio_is_write = 1;
		return EMULATE_DO_MMIO;
	}

	vcpu->arch.pc = curr_pc;
	kvm_err("Write not supported Inst=0x%08x @%lx BadVaddr:%#lx\n",
			inst.word, vcpu->arch.pc, vcpu->arch.badv);
	kvm_arch_vcpu_dump_regs(vcpu);
	/* Rollback PC if emulation was unsuccessful */

	return ret;
}

static int kvm_handle_rdwr_fault(struct kvm_vcpu *vcpu, bool write, int ecode)
{
	int ret;
	larch_inst inst;
	enum emulation_result er = EMULATE_DONE;
	struct kvm_run *run = vcpu->run;
	unsigned long badv = vcpu->arch.badv;

	/* Inject ADE exception if exceed max GPA size */
	if (unlikely(badv >= vcpu->kvm->arch.gpa_size)) {
		kvm_queue_exception(vcpu, EXCCODE_ADE, EXSUBCODE_ADEM);
		return RESUME_GUEST;
	}

	ret = kvm_handle_mm_fault(vcpu, badv, write, ecode);
	if (ret) {
		/* Treat as MMIO */
		inst.word = vcpu->arch.badi;
		if (write) {
			er = kvm_emu_mmio_write(vcpu, inst);
		} else {
			/* A code fetch fault doesn't count as an MMIO */
			if (kvm_is_ifetch_fault(&vcpu->arch)) {
				kvm_queue_exception(vcpu, EXCCODE_ADE, EXSUBCODE_ADEF);
				return RESUME_GUEST;
			}

			er = kvm_emu_mmio_read(vcpu, inst);
		}
	}

	if (er == EMULATE_DONE) {
		ret = RESUME_GUEST;
	} else if (er == EMULATE_DO_MMIO) {
		run->exit_reason = KVM_EXIT_MMIO;
		ret = RESUME_HOST;
	} else {
		kvm_queue_exception(vcpu, EXCCODE_ADE, EXSUBCODE_ADEM);
		ret = RESUME_GUEST;
	}

	return ret;
}

static int kvm_handle_read_fault(struct kvm_vcpu *vcpu, int ecode)
{
	return kvm_handle_rdwr_fault(vcpu, false, ecode);
}

static int kvm_handle_write_fault(struct kvm_vcpu *vcpu, int ecode)
{
	return kvm_handle_rdwr_fault(vcpu, true, ecode);
}

int kvm_complete_user_service(struct kvm_vcpu *vcpu, struct kvm_run *run)
{
	update_pc(&vcpu->arch);
	kvm_write_reg(vcpu, LOONGARCH_GPR_A0, run->hypercall.ret);

	return 0;
}

/**
 * kvm_handle_fpu_disabled() - Guest used fpu however it is disabled at host
 * @vcpu:	Virtual CPU context.
 * @ecode:	Exception code.
 *
 * Handle when the guest attempts to use fpu which hasn't been allowed
 * by the root context.
 */
static int kvm_handle_fpu_disabled(struct kvm_vcpu *vcpu, int ecode)
{
	struct kvm_run *run = vcpu->run;

	if (!kvm_guest_has_fpu(&vcpu->arch)) {
		kvm_queue_exception(vcpu, EXCCODE_INE, 0);
		return RESUME_GUEST;
	}

	/*
	 * If guest FPU not present, the FPU operation should have been
	 * treated as a reserved instruction!
	 * If FPU already in use, we shouldn't get this at all.
	 */
	if (WARN_ON(vcpu->arch.aux_inuse & KVM_LARCH_FPU)) {
		kvm_err("%s internal error\n", __func__);
		run->exit_reason = KVM_EXIT_INTERNAL_ERROR;
		return RESUME_HOST;
	}

	vcpu->arch.aux_ldtype = KVM_LARCH_FPU;
	kvm_make_request(KVM_REQ_AUX_LOAD, vcpu);

	return RESUME_GUEST;
}

static long kvm_save_notify(struct kvm_vcpu *vcpu)
{
	unsigned long id, data;

	id   = kvm_read_reg(vcpu, LOONGARCH_GPR_A1);
	data = kvm_read_reg(vcpu, LOONGARCH_GPR_A2);
	switch (id) {
	case BIT(KVM_FEATURE_STEAL_TIME):
		if (data & ~(KVM_STEAL_PHYS_MASK | KVM_STEAL_PHYS_VALID))
			return KVM_HCALL_INVALID_PARAMETER;

		vcpu->arch.st.guest_addr = data;
		if (!(data & KVM_STEAL_PHYS_VALID))
			return 0;

		vcpu->arch.st.last_steal = current->sched_info.run_delay;
		kvm_make_request(KVM_REQ_STEAL_UPDATE, vcpu);
		return 0;
	default:
		return KVM_HCALL_INVALID_CODE;
	}
}

/*
 * kvm_handle_lsx_disabled() - Guest used LSX while disabled in root.
 * @vcpu:      Virtual CPU context.
 * @ecode:	Exception code.
 *
 * Handle when the guest attempts to use LSX when it is disabled in the root
 * context.
 */
static int kvm_handle_lsx_disabled(struct kvm_vcpu *vcpu, int ecode)
{
	if (!kvm_guest_has_lsx(&vcpu->arch))
		kvm_queue_exception(vcpu, EXCCODE_INE, 0);
	else {
		vcpu->arch.aux_ldtype = KVM_LARCH_LSX;
		kvm_make_request(KVM_REQ_AUX_LOAD, vcpu);
	}

	return RESUME_GUEST;
}

/*
 * kvm_handle_lasx_disabled() - Guest used LASX while disabled in root.
 * @vcpu:	Virtual CPU context.
 * @ecode:	Exception code.
 *
 * Handle when the guest attempts to use LASX when it is disabled in the root
 * context.
 */
static int kvm_handle_lasx_disabled(struct kvm_vcpu *vcpu, int ecode)
{
	if (!kvm_guest_has_lasx(&vcpu->arch))
		kvm_queue_exception(vcpu, EXCCODE_INE, 0);
	else {
		vcpu->arch.aux_ldtype = KVM_LARCH_LASX;
		kvm_make_request(KVM_REQ_AUX_LOAD, vcpu);
	}

	return RESUME_GUEST;
}

static int kvm_handle_lbt_disabled(struct kvm_vcpu *vcpu, int ecode)
{
	if (!kvm_guest_has_lbt(&vcpu->arch))
		kvm_queue_exception(vcpu, EXCCODE_INE, 0);
	else {
		vcpu->arch.aux_ldtype = KVM_LARCH_LBT;
		kvm_make_request(KVM_REQ_AUX_LOAD, vcpu);
	}

	return RESUME_GUEST;
}

static void kvm_send_pv_ipi(struct kvm_vcpu *vcpu)
{
	unsigned int min, cpu;
	struct kvm_vcpu *dest;
	DECLARE_BITMAP(ipi_bitmap, BITS_PER_LONG * 2) = {
		kvm_read_reg(vcpu, LOONGARCH_GPR_A1),
		kvm_read_reg(vcpu, LOONGARCH_GPR_A2)
	};

	min = kvm_read_reg(vcpu, LOONGARCH_GPR_A3);
	for_each_set_bit(cpu, ipi_bitmap, BITS_PER_LONG * 2) {
		dest = kvm_get_vcpu_by_cpuid(vcpu->kvm, cpu + min);
		if (!dest)
			continue;

		/* Send SWI0 to dest vcpu to emulate IPI interrupt */
		kvm_queue_irq(dest, INT_SWI0);
		kvm_vcpu_kick(dest);
	}
}

/*
 * Hypercall emulation always return to guest, Caller should check retval.
 */
static void kvm_handle_service(struct kvm_vcpu *vcpu)
{
	long ret = KVM_HCALL_INVALID_CODE;
	unsigned long func = kvm_read_reg(vcpu, LOONGARCH_GPR_A0);

	switch (func) {
	case KVM_HCALL_FUNC_IPI:
		if (kvm_guest_has_pv_feature(vcpu, KVM_FEATURE_IPI)) {
			kvm_send_pv_ipi(vcpu);
			ret = KVM_HCALL_SUCCESS;
		}
		break;
	case KVM_HCALL_FUNC_NOTIFY:
		if (kvm_guest_has_pv_feature(vcpu, KVM_FEATURE_STEAL_TIME))
			ret = kvm_save_notify(vcpu);
		break;
	default:
		break;
	}

	kvm_write_reg(vcpu, LOONGARCH_GPR_A0, ret);
}

static int kvm_handle_hypercall(struct kvm_vcpu *vcpu, int ecode)
{
	int ret;
	larch_inst inst;
	unsigned int code;

	inst.word = vcpu->arch.badi;
	code = inst.reg0i15_format.immediate;
	ret = RESUME_GUEST;

	switch (code) {
	case KVM_HCALL_SERVICE:
		vcpu->stat.hypercall_exits++;
		kvm_handle_service(vcpu);
		break;
	case KVM_HCALL_USER_SERVICE:
		if (!kvm_guest_has_pv_feature(vcpu, KVM_FEATURE_USER_HCALL)) {
			kvm_write_reg(vcpu, LOONGARCH_GPR_A0, KVM_HCALL_INVALID_CODE);
			break;
		}

		vcpu->stat.hypercall_exits++;
		vcpu->run->exit_reason = KVM_EXIT_HYPERCALL;
		vcpu->run->hypercall.nr = KVM_HCALL_USER_SERVICE;
		vcpu->run->hypercall.args[0] = kvm_read_reg(vcpu, LOONGARCH_GPR_A0);
		vcpu->run->hypercall.args[1] = kvm_read_reg(vcpu, LOONGARCH_GPR_A1);
		vcpu->run->hypercall.args[2] = kvm_read_reg(vcpu, LOONGARCH_GPR_A2);
		vcpu->run->hypercall.args[3] = kvm_read_reg(vcpu, LOONGARCH_GPR_A3);
		vcpu->run->hypercall.args[4] = kvm_read_reg(vcpu, LOONGARCH_GPR_A4);
		vcpu->run->hypercall.args[5] = kvm_read_reg(vcpu, LOONGARCH_GPR_A5);
		vcpu->run->hypercall.flags = 0;
		/*
		 * Set invalid return value by default, let user-mode VMM modify it.
		 */
		vcpu->run->hypercall.ret = KVM_HCALL_INVALID_CODE;
		ret = RESUME_HOST;
		break;
	case KVM_HCALL_SWDBG:
		/* KVM_HCALL_SWDBG only in effective when SW_BP is enabled */
		if (vcpu->guest_debug & KVM_GUESTDBG_SW_BP_MASK) {
			vcpu->run->exit_reason = KVM_EXIT_DEBUG;
			ret = RESUME_HOST;
			break;
		}
		fallthrough;
	default:
		/* Treat it as noop intruction, only set return value */
		kvm_write_reg(vcpu, LOONGARCH_GPR_A0, KVM_HCALL_INVALID_CODE);
		break;
	}

	if (ret == RESUME_GUEST)
		update_pc(&vcpu->arch);

	return ret;
}

/*
 * LoongArch KVM callback handling for unimplemented guest exiting
 */
static int kvm_fault_ni(struct kvm_vcpu *vcpu, int ecode)
{
	unsigned int inst;
	unsigned long badv;

	/* Fetch the instruction */
	inst = vcpu->arch.badi;
	badv = vcpu->arch.badv;
	kvm_err("ECode: %d PC=%#lx Inst=0x%08x BadVaddr=%#lx ESTAT=%#lx\n",
			ecode, vcpu->arch.pc, inst, badv, read_gcsr_estat());
	kvm_arch_vcpu_dump_regs(vcpu);
	kvm_queue_exception(vcpu, EXCCODE_INE, 0);

	return RESUME_GUEST;
}

static exit_handle_fn kvm_fault_tables[EXCCODE_INT_START] = {
	[0 ... EXCCODE_INT_START - 1]	= kvm_fault_ni,
	[EXCCODE_TLBI]			= kvm_handle_read_fault,
	[EXCCODE_TLBL]			= kvm_handle_read_fault,
	[EXCCODE_TLBS]			= kvm_handle_write_fault,
	[EXCCODE_TLBM]			= kvm_handle_write_fault,
	[EXCCODE_FPDIS]			= kvm_handle_fpu_disabled,
	[EXCCODE_LSXDIS]		= kvm_handle_lsx_disabled,
	[EXCCODE_LASXDIS]		= kvm_handle_lasx_disabled,
	[EXCCODE_BTDIS]			= kvm_handle_lbt_disabled,
	[EXCCODE_GSPR]			= kvm_handle_gspr,
	[EXCCODE_HVC]			= kvm_handle_hypercall,
};

int kvm_handle_fault(struct kvm_vcpu *vcpu, int fault)
{
	return kvm_fault_tables[fault](vcpu, fault);
}
