/*
 * This file is subject to the terms and conditions of the GNU General Public
 * License.  See the file "COPYING" in the main directory of this archive
 * for more details.
 *
 * KVM/MIPS: Instruction/Exception emulation
 *
 * Copyright (C) 2012  MIPS Technologies, Inc.  All rights reserved.
 * Authors: Sanjay Lal <sanjayl@kymasys.com>
 */

#include <linux/errno.h>
#include <linux/err.h>
#include <linux/ktime.h>
#include <linux/kvm_host.h>
#include <linux/vmalloc.h>
#include <linux/fs.h>
#include <linux/memblock.h>
#include <linux/random.h>
#include <asm/page.h>
#include <asm/cacheflush.h>
#include <asm/cacheops.h>
#include <asm/cpu-info.h>
#include <asm/mmu_context.h>
#include <asm/tlbflush.h>
#include <asm/inst.h>

#undef CONFIG_MIPS_MT
#include <asm/r4kcache.h>
#define CONFIG_MIPS_MT

#include "interrupt.h"
#include "commpage.h"

#include "trace.h"

/*
 * Compute the return address and do emulate branch simulation, if required.
 * This function should be called only in branch delay slot active.
 */
static int kvm_compute_return_epc(struct kvm_vcpu *vcpu, unsigned long instpc,
				  unsigned long *out)
{
	unsigned int dspcontrol;
	union mips_instruction insn;
	struct kvm_vcpu_arch *arch = &vcpu->arch;
	long epc = instpc;
	long nextpc;
	int err;

	if (epc & 3) {
		kvm_err("%s: unaligned epc\n", __func__);
		return -EINVAL;
	}

	/* Read the instruction */
	err = kvm_get_badinstrp((u32 *)epc, vcpu, &insn.word);
	if (err)
		return err;

	switch (insn.i_format.opcode) {
		/* jr and jalr are in r_format format. */
	case spec_op:
		switch (insn.r_format.func) {
		case jalr_op:
			arch->gprs[insn.r_format.rd] = epc + 8;
			fallthrough;
		case jr_op:
			nextpc = arch->gprs[insn.r_format.rs];
			break;
		default:
			return -EINVAL;
		}
		break;

		/*
		 * This group contains:
		 * bltz_op, bgez_op, bltzl_op, bgezl_op,
		 * bltzal_op, bgezal_op, bltzall_op, bgezall_op.
		 */
	case bcond_op:
		switch (insn.i_format.rt) {
		case bltz_op:
		case bltzl_op:
			if ((long)arch->gprs[insn.i_format.rs] < 0)
				epc = epc + 4 + (insn.i_format.simmediate << 2);
			else
				epc += 8;
			nextpc = epc;
			break;

		case bgez_op:
		case bgezl_op:
			if ((long)arch->gprs[insn.i_format.rs] >= 0)
				epc = epc + 4 + (insn.i_format.simmediate << 2);
			else
				epc += 8;
			nextpc = epc;
			break;

		case bltzal_op:
		case bltzall_op:
			arch->gprs[31] = epc + 8;
			if ((long)arch->gprs[insn.i_format.rs] < 0)
				epc = epc + 4 + (insn.i_format.simmediate << 2);
			else
				epc += 8;
			nextpc = epc;
			break;

		case bgezal_op:
		case bgezall_op:
			arch->gprs[31] = epc + 8;
			if ((long)arch->gprs[insn.i_format.rs] >= 0)
				epc = epc + 4 + (insn.i_format.simmediate << 2);
			else
				epc += 8;
			nextpc = epc;
			break;
		case bposge32_op:
			if (!cpu_has_dsp) {
				kvm_err("%s: DSP branch but not DSP ASE\n",
					__func__);
				return -EINVAL;
			}

			dspcontrol = rddsp(0x01);

			if (dspcontrol >= 32)
				epc = epc + 4 + (insn.i_format.simmediate << 2);
			else
				epc += 8;
			nextpc = epc;
			break;
		default:
			return -EINVAL;
		}
		break;

		/* These are unconditional and in j_format. */
	case jal_op:
		arch->gprs[31] = instpc + 8;
		fallthrough;
	case j_op:
		epc += 4;
		epc >>= 28;
		epc <<= 28;
		epc |= (insn.j_format.target << 2);
		nextpc = epc;
		break;

		/* These are conditional and in i_format. */
	case beq_op:
	case beql_op:
		if (arch->gprs[insn.i_format.rs] ==
		    arch->gprs[insn.i_format.rt])
			epc = epc + 4 + (insn.i_format.simmediate << 2);
		else
			epc += 8;
		nextpc = epc;
		break;

	case bne_op:
	case bnel_op:
		if (arch->gprs[insn.i_format.rs] !=
		    arch->gprs[insn.i_format.rt])
			epc = epc + 4 + (insn.i_format.simmediate << 2);
		else
			epc += 8;
		nextpc = epc;
		break;

	case blez_op:	/* POP06 */
#ifndef CONFIG_CPU_MIPSR6
	case blezl_op:	/* removed in R6 */
#endif
		if (insn.i_format.rt != 0)
			goto compact_branch;
		if ((long)arch->gprs[insn.i_format.rs] <= 0)
			epc = epc + 4 + (insn.i_format.simmediate << 2);
		else
			epc += 8;
		nextpc = epc;
		break;

	case bgtz_op:	/* POP07 */
#ifndef CONFIG_CPU_MIPSR6
	case bgtzl_op:	/* removed in R6 */
#endif
		if (insn.i_format.rt != 0)
			goto compact_branch;
		if ((long)arch->gprs[insn.i_format.rs] > 0)
			epc = epc + 4 + (insn.i_format.simmediate << 2);
		else
			epc += 8;
		nextpc = epc;
		break;

		/* And now the FPA/cp1 branch instructions. */
	case cop1_op:
		kvm_err("%s: unsupported cop1_op\n", __func__);
		return -EINVAL;

#ifdef CONFIG_CPU_MIPSR6
	/* R6 added the following compact branches with forbidden slots */
	case blezl_op:	/* POP26 */
	case bgtzl_op:	/* POP27 */
		/* only rt == 0 isn't compact branch */
		if (insn.i_format.rt != 0)
			goto compact_branch;
		return -EINVAL;
	case pop10_op:
	case pop30_op:
		/* only rs == rt == 0 is reserved, rest are compact branches */
		if (insn.i_format.rs != 0 || insn.i_format.rt != 0)
			goto compact_branch;
		return -EINVAL;
	case pop66_op:
	case pop76_op:
		/* only rs == 0 isn't compact branch */
		if (insn.i_format.rs != 0)
			goto compact_branch;
		return -EINVAL;
compact_branch:
		/*
		 * If we've hit an exception on the forbidden slot, then
		 * the branch must not have been taken.
		 */
		epc += 8;
		nextpc = epc;
		break;
#else
compact_branch:
		/* Fall through - Compact branches not supported before R6 */
#endif
	default:
		return -EINVAL;
	}

	*out = nextpc;
	return 0;
}

enum emulation_result update_pc(struct kvm_vcpu *vcpu, u32 cause)
{
	int err;

	if (cause & CAUSEF_BD) {
		err = kvm_compute_return_epc(vcpu, vcpu->arch.pc,
					     &vcpu->arch.pc);
		if (err)
			return EMULATE_FAIL;
	} else {
		vcpu->arch.pc += 4;
	}

	kvm_debug("update_pc(): New PC: %#lx\n", vcpu->arch.pc);

	return EMULATE_DONE;
}

/**
 * kvm_get_badinstr() - Get bad instruction encoding.
 * @opc:	Guest pointer to faulting instruction.
 * @vcpu:	KVM VCPU information.
 *
 * Gets the instruction encoding of the faulting instruction, using the saved
 * BadInstr register value if it exists, otherwise falling back to reading guest
 * memory at @opc.
 *
 * Returns:	The instruction encoding of the faulting instruction.
 */
int kvm_get_badinstr(u32 *opc, struct kvm_vcpu *vcpu, u32 *out)
{
	if (cpu_has_badinstr) {
		*out = vcpu->arch.host_cp0_badinstr;
		return 0;
	} else {
		return kvm_get_inst(opc, vcpu, out);
	}
}

/**
 * kvm_get_badinstrp() - Get bad prior instruction encoding.
 * @opc:	Guest pointer to prior faulting instruction.
 * @vcpu:	KVM VCPU information.
 *
 * Gets the instruction encoding of the prior faulting instruction (the branch
 * containing the delay slot which faulted), using the saved BadInstrP register
 * value if it exists, otherwise falling back to reading guest memory at @opc.
 *
 * Returns:	The instruction encoding of the prior faulting instruction.
 */
int kvm_get_badinstrp(u32 *opc, struct kvm_vcpu *vcpu, u32 *out)
{
	if (cpu_has_badinstrp) {
		*out = vcpu->arch.host_cp0_badinstrp;
		return 0;
	} else {
		return kvm_get_inst(opc, vcpu, out);
	}
}

/**
 * kvm_mips_count_disabled() - Find whether the CP0_Count timer is disabled.
 * @vcpu:	Virtual CPU.
 *
 * Returns:	1 if the CP0_Count timer is disabled by either the guest
 *		CP0_Cause.DC bit or the count_ctl.DC bit.
 *		0 otherwise (in which case CP0_Count timer is running).
 */
int kvm_mips_count_disabled(struct kvm_vcpu *vcpu)
{
	struct mips_coproc *cop0 = vcpu->arch.cop0;

	return	(vcpu->arch.count_ctl & KVM_REG_MIPS_COUNT_CTL_DC) ||
		(kvm_read_c0_guest_cause(cop0) & CAUSEF_DC);
}

/**
 * kvm_mips_ktime_to_count() - Scale ktime_t to a 32-bit count.
 *
 * Caches the dynamic nanosecond bias in vcpu->arch.count_dyn_bias.
 *
 * Assumes !kvm_mips_count_disabled(@vcpu) (guest CP0_Count timer is running).
 */
static u32 kvm_mips_ktime_to_count(struct kvm_vcpu *vcpu, ktime_t now)
{
	s64 now_ns, periods;
	u64 delta;

	now_ns = ktime_to_ns(now);
	delta = now_ns + vcpu->arch.count_dyn_bias;

	if (delta >= vcpu->arch.count_period) {
		/* If delta is out of safe range the bias needs adjusting */
		periods = div64_s64(now_ns, vcpu->arch.count_period);
		vcpu->arch.count_dyn_bias = -periods * vcpu->arch.count_period;
		/* Recalculate delta with new bias */
		delta = now_ns + vcpu->arch.count_dyn_bias;
	}

	/*
	 * We've ensured that:
	 *   delta < count_period
	 *
	 * Therefore the intermediate delta*count_hz will never overflow since
	 * at the boundary condition:
	 *   delta = count_period
	 *   delta = NSEC_PER_SEC * 2^32 / count_hz
	 *   delta * count_hz = NSEC_PER_SEC * 2^32
	 */
	return div_u64(delta * vcpu->arch.count_hz, NSEC_PER_SEC);
}

/**
 * kvm_mips_count_time() - Get effective current time.
 * @vcpu:	Virtual CPU.
 *
 * Get effective monotonic ktime. This is usually a straightforward ktime_get(),
 * except when the master disable bit is set in count_ctl, in which case it is
 * count_resume, i.e. the time that the count was disabled.
 *
 * Returns:	Effective monotonic ktime for CP0_Count.
 */
static inline ktime_t kvm_mips_count_time(struct kvm_vcpu *vcpu)
{
	if (unlikely(vcpu->arch.count_ctl & KVM_REG_MIPS_COUNT_CTL_DC))
		return vcpu->arch.count_resume;

	return ktime_get();
}

/**
 * kvm_mips_read_count_running() - Read the current count value as if running.
 * @vcpu:	Virtual CPU.
 * @now:	Kernel time to read CP0_Count at.
 *
 * Returns the current guest CP0_Count register at time @now and handles if the
 * timer interrupt is pending and hasn't been handled yet.
 *
 * Returns:	The current value of the guest CP0_Count register.
 */
static u32 kvm_mips_read_count_running(struct kvm_vcpu *vcpu, ktime_t now)
{
	struct mips_coproc *cop0 = vcpu->arch.cop0;
	ktime_t expires, threshold;
	u32 count, compare;
	int running;

	/* Calculate the biased and scaled guest CP0_Count */
	count = vcpu->arch.count_bias + kvm_mips_ktime_to_count(vcpu, now);
	compare = kvm_read_c0_guest_compare(cop0);

	/*
	 * Find whether CP0_Count has reached the closest timer interrupt. If
	 * not, we shouldn't inject it.
	 */
	if ((s32)(count - compare) < 0)
		return count;

	/*
	 * The CP0_Count we're going to return has already reached the closest
	 * timer interrupt. Quickly check if it really is a new interrupt by
	 * looking at whether the interval until the hrtimer expiry time is
	 * less than 1/4 of the timer period.
	 */
	expires = hrtimer_get_expires(&vcpu->arch.comparecount_timer);
	threshold = ktime_add_ns(now, vcpu->arch.count_period / 4);
	if (ktime_before(expires, threshold)) {
		/*
		 * Cancel it while we handle it so there's no chance of
		 * interference with the timeout handler.
		 */
		running = hrtimer_cancel(&vcpu->arch.comparecount_timer);

		/* Nothing should be waiting on the timeout */
		kvm_mips_callbacks->queue_timer_int(vcpu);

		/*
		 * Restart the timer if it was running based on the expiry time
		 * we read, so that we don't push it back 2 periods.
		 */
		if (running) {
			expires = ktime_add_ns(expires,
					       vcpu->arch.count_period);
			hrtimer_start(&vcpu->arch.comparecount_timer, expires,
				      HRTIMER_MODE_ABS);
		}
	}

	return count;
}

/**
 * kvm_mips_read_count() - Read the current count value.
 * @vcpu:	Virtual CPU.
 *
 * Read the current guest CP0_Count value, taking into account whether the timer
 * is stopped.
 *
 * Returns:	The current guest CP0_Count value.
 */
u32 kvm_mips_read_count(struct kvm_vcpu *vcpu)
{
	struct mips_coproc *cop0 = vcpu->arch.cop0;

	/* If count disabled just read static copy of count */
	if (kvm_mips_count_disabled(vcpu))
		return kvm_read_c0_guest_count(cop0);

	return kvm_mips_read_count_running(vcpu, ktime_get());
}

/**
 * kvm_mips_freeze_hrtimer() - Safely stop the hrtimer.
 * @vcpu:	Virtual CPU.
 * @count:	Output pointer for CP0_Count value at point of freeze.
 *
 * Freeze the hrtimer safely and return both the ktime and the CP0_Count value
 * at the point it was frozen. It is guaranteed that any pending interrupts at
 * the point it was frozen are handled, and none after that point.
 *
 * This is useful where the time/CP0_Count is needed in the calculation of the
 * new parameters.
 *
 * Assumes !kvm_mips_count_disabled(@vcpu) (guest CP0_Count timer is running).
 *
 * Returns:	The ktime at the point of freeze.
 */
ktime_t kvm_mips_freeze_hrtimer(struct kvm_vcpu *vcpu, u32 *count)
{
	ktime_t now;

	/* stop hrtimer before finding time */
	hrtimer_cancel(&vcpu->arch.comparecount_timer);
	now = ktime_get();

	/* find count at this point and handle pending hrtimer */
	*count = kvm_mips_read_count_running(vcpu, now);

	return now;
}

/**
 * kvm_mips_resume_hrtimer() - Resume hrtimer, updating expiry.
 * @vcpu:	Virtual CPU.
 * @now:	ktime at point of resume.
 * @count:	CP0_Count at point of resume.
 *
 * Resumes the timer and updates the timer expiry based on @now and @count.
 * This can be used in conjunction with kvm_mips_freeze_timer() when timer
 * parameters need to be changed.
 *
 * It is guaranteed that a timer interrupt immediately after resume will be
 * handled, but not if CP_Compare is exactly at @count. That case is already
 * handled by kvm_mips_freeze_timer().
 *
 * Assumes !kvm_mips_count_disabled(@vcpu) (guest CP0_Count timer is running).
 */
static void kvm_mips_resume_hrtimer(struct kvm_vcpu *vcpu,
				    ktime_t now, u32 count)
{
	struct mips_coproc *cop0 = vcpu->arch.cop0;
	u32 compare;
	u64 delta;
	ktime_t expire;

	/* Calculate timeout (wrap 0 to 2^32) */
	compare = kvm_read_c0_guest_compare(cop0);
	delta = (u64)(u32)(compare - count - 1) + 1;
	delta = div_u64(delta * NSEC_PER_SEC, vcpu->arch.count_hz);
	expire = ktime_add_ns(now, delta);

	/* Update hrtimer to use new timeout */
	hrtimer_cancel(&vcpu->arch.comparecount_timer);
	hrtimer_start(&vcpu->arch.comparecount_timer, expire, HRTIMER_MODE_ABS);
}

/**
 * kvm_mips_restore_hrtimer() - Restore hrtimer after a gap, updating expiry.
 * @vcpu:	Virtual CPU.
 * @before:	Time before Count was saved, lower bound of drift calculation.
 * @count:	CP0_Count at point of restore.
 * @min_drift:	Minimum amount of drift permitted before correction.
 *		Must be <= 0.
 *
 * Restores the timer from a particular @count, accounting for drift. This can
 * be used in conjunction with kvm_mips_freeze_timer() when a hardware timer is
 * to be used for a period of time, but the exact ktime corresponding to the
 * final Count that must be restored is not known.
 *
 * It is gauranteed that a timer interrupt immediately after restore will be
 * handled, but not if CP0_Compare is exactly at @count. That case should
 * already be handled when the hardware timer state is saved.
 *
 * Assumes !kvm_mips_count_disabled(@vcpu) (guest CP0_Count timer is not
 * stopped).
 *
 * Returns:	Amount of correction to count_bias due to drift.
 */
int kvm_mips_restore_hrtimer(struct kvm_vcpu *vcpu, ktime_t before,
			     u32 count, int min_drift)
{
	ktime_t now, count_time;
	u32 now_count, before_count;
	u64 delta;
	int drift, ret = 0;

	/* Calculate expected count at before */
	before_count = vcpu->arch.count_bias +
			kvm_mips_ktime_to_count(vcpu, before);

	/*
	 * Detect significantly negative drift, where count is lower than
	 * expected. Some negative drift is expected when hardware counter is
	 * set after kvm_mips_freeze_timer(), and it is harmless to allow the
	 * time to jump forwards a little, within reason. If the drift is too
	 * significant, adjust the bias to avoid a big Guest.CP0_Count jump.
	 */
	drift = count - before_count;
	if (drift < min_drift) {
		count_time = before;
		vcpu->arch.count_bias += drift;
		ret = drift;
		goto resume;
	}

	/* Calculate expected count right now */
	now = ktime_get();
	now_count = vcpu->arch.count_bias + kvm_mips_ktime_to_count(vcpu, now);

	/*
	 * Detect positive drift, where count is higher than expected, and
	 * adjust the bias to avoid guest time going backwards.
	 */
	drift = count - now_count;
	if (drift > 0) {
		count_time = now;
		vcpu->arch.count_bias += drift;
		ret = drift;
		goto resume;
	}

	/* Subtract nanosecond delta to find ktime when count was read */
	delta = (u64)(u32)(now_count - count);
	delta = div_u64(delta * NSEC_PER_SEC, vcpu->arch.count_hz);
	count_time = ktime_sub_ns(now, delta);

resume:
	/* Resume using the calculated ktime */
	kvm_mips_resume_hrtimer(vcpu, count_time, count);
	return ret;
}

/**
 * kvm_mips_write_count() - Modify the count and update timer.
 * @vcpu:	Virtual CPU.
 * @count:	Guest CP0_Count value to set.
 *
 * Sets the CP0_Count value and updates the timer accordingly.
 */
void kvm_mips_write_count(struct kvm_vcpu *vcpu, u32 count)
{
	struct mips_coproc *cop0 = vcpu->arch.cop0;
	ktime_t now;

	/* Calculate bias */
	now = kvm_mips_count_time(vcpu);
	vcpu->arch.count_bias = count - kvm_mips_ktime_to_count(vcpu, now);

	if (kvm_mips_count_disabled(vcpu))
		/* The timer's disabled, adjust the static count */
		kvm_write_c0_guest_count(cop0, count);
	else
		/* Update timeout */
		kvm_mips_resume_hrtimer(vcpu, now, count);
}

/**
 * kvm_mips_init_count() - Initialise timer.
 * @vcpu:	Virtual CPU.
 * @count_hz:	Frequency of timer.
 *
 * Initialise the timer to the specified frequency, zero it, and set it going if
 * it's enabled.
 */
void kvm_mips_init_count(struct kvm_vcpu *vcpu, unsigned long count_hz)
{
	vcpu->arch.count_hz = count_hz;
	vcpu->arch.count_period = div_u64((u64)NSEC_PER_SEC << 32, count_hz);
	vcpu->arch.count_dyn_bias = 0;

	/* Starting at 0 */
	kvm_mips_write_count(vcpu, 0);
}

/**
 * kvm_mips_set_count_hz() - Update the frequency of the timer.
 * @vcpu:	Virtual CPU.
 * @count_hz:	Frequency of CP0_Count timer in Hz.
 *
 * Change the frequency of the CP0_Count timer. This is done atomically so that
 * CP0_Count is continuous and no timer interrupt is lost.
 *
 * Returns:	-EINVAL if @count_hz is out of range.
 *		0 on success.
 */
int kvm_mips_set_count_hz(struct kvm_vcpu *vcpu, s64 count_hz)
{
	struct mips_coproc *cop0 = vcpu->arch.cop0;
	int dc;
	ktime_t now;
	u32 count;

	/* ensure the frequency is in a sensible range... */
	if (count_hz <= 0 || count_hz > NSEC_PER_SEC)
		return -EINVAL;
	/* ... and has actually changed */
	if (vcpu->arch.count_hz == count_hz)
		return 0;

	/* Safely freeze timer so we can keep it continuous */
	dc = kvm_mips_count_disabled(vcpu);
	if (dc) {
		now = kvm_mips_count_time(vcpu);
		count = kvm_read_c0_guest_count(cop0);
	} else {
		now = kvm_mips_freeze_hrtimer(vcpu, &count);
	}

	/* Update the frequency */
	vcpu->arch.count_hz = count_hz;
	vcpu->arch.count_period = div_u64((u64)NSEC_PER_SEC << 32, count_hz);
	vcpu->arch.count_dyn_bias = 0;

	/* Calculate adjusted bias so dynamic count is unchanged */
	vcpu->arch.count_bias = count - kvm_mips_ktime_to_count(vcpu, now);

	/* Update and resume hrtimer */
	if (!dc)
		kvm_mips_resume_hrtimer(vcpu, now, count);
	return 0;
}

/**
 * kvm_mips_write_compare() - Modify compare and update timer.
 * @vcpu:	Virtual CPU.
 * @compare:	New CP0_Compare value.
 * @ack:	Whether to acknowledge timer interrupt.
 *
 * Update CP0_Compare to a new value and update the timeout.
 * If @ack, atomically acknowledge any pending timer interrupt, otherwise ensure
 * any pending timer interrupt is preserved.
 */
void kvm_mips_write_compare(struct kvm_vcpu *vcpu, u32 compare, bool ack)
{
	struct mips_coproc *cop0 = vcpu->arch.cop0;
	int dc;
	u32 old_compare = kvm_read_c0_guest_compare(cop0);
	s32 delta = compare - old_compare;
	u32 cause;
	ktime_t now = ktime_set(0, 0); /* silence bogus GCC warning */
	u32 count;

	/* if unchanged, must just be an ack */
	if (old_compare == compare) {
		if (!ack)
			return;
		kvm_mips_callbacks->dequeue_timer_int(vcpu);
		kvm_write_c0_guest_compare(cop0, compare);
		return;
	}

	/*
	 * If guest CP0_Compare moves forward, CP0_GTOffset should be adjusted
	 * too to prevent guest CP0_Count hitting guest CP0_Compare.
	 *
	 * The new GTOffset corresponds to the new value of CP0_Compare, and is
	 * set prior to it being written into the guest context. We disable
	 * preemption until the new value is written to prevent restore of a
	 * GTOffset corresponding to the old CP0_Compare value.
	 */
	if (IS_ENABLED(CONFIG_KVM_MIPS_VZ) && delta > 0) {
		preempt_disable();
		write_c0_gtoffset(compare - read_c0_count());
		back_to_back_c0_hazard();
	}

	/* freeze_hrtimer() takes care of timer interrupts <= count */
	dc = kvm_mips_count_disabled(vcpu);
	if (!dc)
		now = kvm_mips_freeze_hrtimer(vcpu, &count);

	if (ack)
		kvm_mips_callbacks->dequeue_timer_int(vcpu);
	else if (IS_ENABLED(CONFIG_KVM_MIPS_VZ))
		/*
		 * With VZ, writing CP0_Compare acks (clears) CP0_Cause.TI, so
		 * preserve guest CP0_Cause.TI if we don't want to ack it.
		 */
		cause = kvm_read_c0_guest_cause(cop0);

	kvm_write_c0_guest_compare(cop0, compare);

	if (IS_ENABLED(CONFIG_KVM_MIPS_VZ)) {
		if (delta > 0)
			preempt_enable();

		back_to_back_c0_hazard();

		if (!ack && cause & CAUSEF_TI)
			kvm_write_c0_guest_cause(cop0, cause);
	}

	/* resume_hrtimer() takes care of timer interrupts > count */
	if (!dc)
		kvm_mips_resume_hrtimer(vcpu, now, count);

	/*
	 * If guest CP0_Compare is moving backward, we delay CP0_GTOffset change
	 * until after the new CP0_Compare is written, otherwise new guest
	 * CP0_Count could hit new guest CP0_Compare.
	 */
	if (IS_ENABLED(CONFIG_KVM_MIPS_VZ) && delta <= 0)
		write_c0_gtoffset(compare - read_c0_count());
}

/**
 * kvm_mips_count_disable() - Disable count.
 * @vcpu:	Virtual CPU.
 *
 * Disable the CP0_Count timer. A timer interrupt on or before the final stop
 * time will be handled but not after.
 *
 * Assumes CP0_Count was previously enabled but now Guest.CP0_Cause.DC or
 * count_ctl.DC has been set (count disabled).
 *
 * Returns:	The time that the timer was stopped.
 */
static ktime_t kvm_mips_count_disable(struct kvm_vcpu *vcpu)
{
	struct mips_coproc *cop0 = vcpu->arch.cop0;
	u32 count;
	ktime_t now;

	/* Stop hrtimer */
	hrtimer_cancel(&vcpu->arch.comparecount_timer);

	/* Set the static count from the dynamic count, handling pending TI */
	now = ktime_get();
	count = kvm_mips_read_count_running(vcpu, now);
	kvm_write_c0_guest_count(cop0, count);

	return now;
}

/**
 * kvm_mips_count_disable_cause() - Disable count using CP0_Cause.DC.
 * @vcpu:	Virtual CPU.
 *
 * Disable the CP0_Count timer and set CP0_Cause.DC. A timer interrupt on or
 * before the final stop time will be handled if the timer isn't disabled by
 * count_ctl.DC, but not after.
 *
 * Assumes CP0_Cause.DC is clear (count enabled).
 */
void kvm_mips_count_disable_cause(struct kvm_vcpu *vcpu)
{
	struct mips_coproc *cop0 = vcpu->arch.cop0;

	kvm_set_c0_guest_cause(cop0, CAUSEF_DC);
	if (!(vcpu->arch.count_ctl & KVM_REG_MIPS_COUNT_CTL_DC))
		kvm_mips_count_disable(vcpu);
}

/**
 * kvm_mips_count_enable_cause() - Enable count using CP0_Cause.DC.
 * @vcpu:	Virtual CPU.
 *
 * Enable the CP0_Count timer and clear CP0_Cause.DC. A timer interrupt after
 * the start time will be handled if the timer isn't disabled by count_ctl.DC,
 * potentially before even returning, so the caller should be careful with
 * ordering of CP0_Cause modifications so as not to lose it.
 *
 * Assumes CP0_Cause.DC is set (count disabled).
 */
void kvm_mips_count_enable_cause(struct kvm_vcpu *vcpu)
{
	struct mips_coproc *cop0 = vcpu->arch.cop0;
	u32 count;

	kvm_clear_c0_guest_cause(cop0, CAUSEF_DC);

	/*
	 * Set the dynamic count to match the static count.
	 * This starts the hrtimer if count_ctl.DC allows it.
	 * Otherwise it conveniently updates the biases.
	 */
	count = kvm_read_c0_guest_count(cop0);
	kvm_mips_write_count(vcpu, count);
}

/**
 * kvm_mips_set_count_ctl() - Update the count control KVM register.
 * @vcpu:	Virtual CPU.
 * @count_ctl:	Count control register new value.
 *
 * Set the count control KVM register. The timer is updated accordingly.
 *
 * Returns:	-EINVAL if reserved bits are set.
 *		0 on success.
 */
int kvm_mips_set_count_ctl(struct kvm_vcpu *vcpu, s64 count_ctl)
{
	struct mips_coproc *cop0 = vcpu->arch.cop0;
	s64 changed = count_ctl ^ vcpu->arch.count_ctl;
	s64 delta;
	ktime_t expire, now;
	u32 count, compare;

	/* Only allow defined bits to be changed */
	if (changed & ~(s64)(KVM_REG_MIPS_COUNT_CTL_DC))
		return -EINVAL;

	/* Apply new value */
	vcpu->arch.count_ctl = count_ctl;

	/* Master CP0_Count disable */
	if (changed & KVM_REG_MIPS_COUNT_CTL_DC) {
		/* Is CP0_Cause.DC already disabling CP0_Count? */
		if (kvm_read_c0_guest_cause(cop0) & CAUSEF_DC) {
			if (count_ctl & KVM_REG_MIPS_COUNT_CTL_DC)
				/* Just record the current time */
				vcpu->arch.count_resume = ktime_get();
		} else if (count_ctl & KVM_REG_MIPS_COUNT_CTL_DC) {
			/* disable timer and record current time */
			vcpu->arch.count_resume = kvm_mips_count_disable(vcpu);
		} else {
			/*
			 * Calculate timeout relative to static count at resume
			 * time (wrap 0 to 2^32).
			 */
			count = kvm_read_c0_guest_count(cop0);
			compare = kvm_read_c0_guest_compare(cop0);
			delta = (u64)(u32)(compare - count - 1) + 1;
			delta = div_u64(delta * NSEC_PER_SEC,
					vcpu->arch.count_hz);
			expire = ktime_add_ns(vcpu->arch.count_resume, delta);

			/* Handle pending interrupt */
			now = ktime_get();
			if (ktime_compare(now, expire) >= 0)
				/* Nothing should be waiting on the timeout */
				kvm_mips_callbacks->queue_timer_int(vcpu);

			/* Resume hrtimer without changing bias */
			count = kvm_mips_read_count_running(vcpu, now);
			kvm_mips_resume_hrtimer(vcpu, now, count);
		}
	}

	return 0;
}

/**
 * kvm_mips_set_count_resume() - Update the count resume KVM register.
 * @vcpu:		Virtual CPU.
 * @count_resume:	Count resume register new value.
 *
 * Set the count resume KVM register.
 *
 * Returns:	-EINVAL if out of valid range (0..now).
 *		0 on success.
 */
int kvm_mips_set_count_resume(struct kvm_vcpu *vcpu, s64 count_resume)
{
	/*
	 * It doesn't make sense for the resume time to be in the future, as it
	 * would be possible for the next interrupt to be more than a full
	 * period in the future.
	 */
	if (count_resume < 0 || count_resume > ktime_to_ns(ktime_get()))
		return -EINVAL;

	vcpu->arch.count_resume = ns_to_ktime(count_resume);
	return 0;
}

/**
 * kvm_mips_count_timeout() - Push timer forward on timeout.
 * @vcpu:	Virtual CPU.
 *
 * Handle an hrtimer event by push the hrtimer forward a period.
 *
 * Returns:	The hrtimer_restart value to return to the hrtimer subsystem.
 */
enum hrtimer_restart kvm_mips_count_timeout(struct kvm_vcpu *vcpu)
{
	/* Add the Count period to the current expiry time */
	hrtimer_add_expires_ns(&vcpu->arch.comparecount_timer,
			       vcpu->arch.count_period);
	return HRTIMER_RESTART;
}

enum emulation_result kvm_mips_emul_eret(struct kvm_vcpu *vcpu)
{
	struct mips_coproc *cop0 = vcpu->arch.cop0;
	enum emulation_result er = EMULATE_DONE;

	if (kvm_read_c0_guest_status(cop0) & ST0_ERL) {
		kvm_clear_c0_guest_status(cop0, ST0_ERL);
		vcpu->arch.pc = kvm_read_c0_guest_errorepc(cop0);
	} else if (kvm_read_c0_guest_status(cop0) & ST0_EXL) {
		kvm_debug("[%#lx] ERET to %#lx\n", vcpu->arch.pc,
			  kvm_read_c0_guest_epc(cop0));
		kvm_clear_c0_guest_status(cop0, ST0_EXL);
		vcpu->arch.pc = kvm_read_c0_guest_epc(cop0);

	} else {
		kvm_err("[%#lx] ERET when MIPS_SR_EXL|MIPS_SR_ERL == 0\n",
			vcpu->arch.pc);
		er = EMULATE_FAIL;
	}

	return er;
}

enum emulation_result kvm_mips_emul_wait(struct kvm_vcpu *vcpu)
{
	kvm_debug("[%#lx] !!!WAIT!!! (%#lx)\n", vcpu->arch.pc,
		  vcpu->arch.pending_exceptions);

	++vcpu->stat.wait_exits;
	trace_kvm_exit(vcpu, KVM_TRACE_EXIT_WAIT);
	if (!vcpu->arch.pending_exceptions) {
		kvm_vz_lose_htimer(vcpu);
		vcpu->arch.wait = 1;
		kvm_vcpu_block(vcpu);

		/*
		 * We we are runnable, then definitely go off to user space to
		 * check if any I/O interrupts are pending.
		 */
		if (kvm_check_request(KVM_REQ_UNHALT, vcpu)) {
			kvm_clear_request(KVM_REQ_UNHALT, vcpu);
			vcpu->run->exit_reason = KVM_EXIT_IRQ_WINDOW_OPEN;
		}
	}

	return EMULATE_DONE;
}

static void kvm_mips_change_entryhi(struct kvm_vcpu *vcpu,
				    unsigned long entryhi)
{
	struct mips_coproc *cop0 = vcpu->arch.cop0;
	struct mm_struct *kern_mm = &vcpu->arch.guest_kernel_mm;
	int cpu, i;
	u32 nasid = entryhi & KVM_ENTRYHI_ASID;

	if (((kvm_read_c0_guest_entryhi(cop0) & KVM_ENTRYHI_ASID) != nasid)) {
		trace_kvm_asid_change(vcpu, kvm_read_c0_guest_entryhi(cop0) &
				      KVM_ENTRYHI_ASID, nasid);

		/*
		 * Flush entries from the GVA page tables.
		 * Guest user page table will get flushed lazily on re-entry to
		 * guest user if the guest ASID actually changes.
		 */
		kvm_mips_flush_gva_pt(kern_mm->pgd, KMF_KERN);

		/*
		 * Regenerate/invalidate kernel MMU context.
		 * The user MMU context will be regenerated lazily on re-entry
		 * to guest user if the guest ASID actually changes.
		 */
		preempt_disable();
		cpu = smp_processor_id();
		get_new_mmu_context(kern_mm);
		for_each_possible_cpu(i)
			if (i != cpu)
				set_cpu_context(i, kern_mm, 0);
		preempt_enable();
	}
	kvm_write_c0_guest_entryhi(cop0, entryhi);
}

enum emulation_result kvm_mips_emul_tlbr(struct kvm_vcpu *vcpu)
{
	struct mips_coproc *cop0 = vcpu->arch.cop0;
	struct kvm_mips_tlb *tlb;
	unsigned long pc = vcpu->arch.pc;
	int index;

	index = kvm_read_c0_guest_index(cop0);
	if (index < 0 || index >= KVM_MIPS_GUEST_TLB_SIZE) {
		/* UNDEFINED */
		kvm_debug("[%#lx] TLBR Index %#x out of range\n", pc, index);
		index &= KVM_MIPS_GUEST_TLB_SIZE - 1;
	}

	tlb = &vcpu->arch.guest_tlb[index];
	kvm_write_c0_guest_pagemask(cop0, tlb->tlb_mask);
	kvm_write_c0_guest_entrylo0(cop0, tlb->tlb_lo[0]);
	kvm_write_c0_guest_entrylo1(cop0, tlb->tlb_lo[1]);
	kvm_mips_change_entryhi(vcpu, tlb->tlb_hi);

	return EMULATE_DONE;
}

/**
 * kvm_mips_invalidate_guest_tlb() - Indicates a change in guest MMU map.
 * @vcpu:	VCPU with changed mappings.
 * @tlb:	TLB entry being removed.
 *
 * This is called to indicate a single change in guest MMU mappings, so that we
 * can arrange TLB flushes on this and other CPUs.
 */
static void kvm_mips_invalidate_guest_tlb(struct kvm_vcpu *vcpu,
					  struct kvm_mips_tlb *tlb)
{
	struct mm_struct *kern_mm = &vcpu->arch.guest_kernel_mm;
	struct mm_struct *user_mm = &vcpu->arch.guest_user_mm;
	int cpu, i;
	bool user;

	/* No need to flush for entries which are already invalid */
	if (!((tlb->tlb_lo[0] | tlb->tlb_lo[1]) & ENTRYLO_V))
		return;
	/* Don't touch host kernel page tables or TLB mappings */
	if ((unsigned long)tlb->tlb_hi > 0x7fffffff)
		return;
	/* User address space doesn't need flushing for KSeg2/3 changes */
	user = tlb->tlb_hi < KVM_GUEST_KSEG0;

	preempt_disable();

	/* Invalidate page table entries */
	kvm_trap_emul_invalidate_gva(vcpu, tlb->tlb_hi & VPN2_MASK, user);

	/*
	 * Probe the shadow host TLB for the entry being overwritten, if one
	 * matches, invalidate it
	 */
	kvm_mips_host_tlb_inv(vcpu, tlb->tlb_hi, user, true);

	/* Invalidate the whole ASID on other CPUs */
	cpu = smp_processor_id();
	for_each_possible_cpu(i) {
		if (i == cpu)
			continue;
		if (user)
			set_cpu_context(i, user_mm, 0);
		set_cpu_context(i, kern_mm, 0);
	}

	preempt_enable();
}

/* Write Guest TLB Entry @ Index */
enum emulation_result kvm_mips_emul_tlbwi(struct kvm_vcpu *vcpu)
{
	struct mips_coproc *cop0 = vcpu->arch.cop0;
	int index = kvm_read_c0_guest_index(cop0);
	struct kvm_mips_tlb *tlb = NULL;
	unsigned long pc = vcpu->arch.pc;

	if (index < 0 || index >= KVM_MIPS_GUEST_TLB_SIZE) {
		kvm_debug("%s: illegal index: %d\n", __func__, index);
		kvm_debug("[%#lx] COP0_TLBWI [%d] (entryhi: %#lx, entrylo0: %#lx entrylo1: %#lx, mask: %#lx)\n",
			  pc, index, kvm_read_c0_guest_entryhi(cop0),
			  kvm_read_c0_guest_entrylo0(cop0),
			  kvm_read_c0_guest_entrylo1(cop0),
			  kvm_read_c0_guest_pagemask(cop0));
		index = (index & ~0x80000000) % KVM_MIPS_GUEST_TLB_SIZE;
	}

	tlb = &vcpu->arch.guest_tlb[index];

	kvm_mips_invalidate_guest_tlb(vcpu, tlb);

	tlb->tlb_mask = kvm_read_c0_guest_pagemask(cop0);
	tlb->tlb_hi = kvm_read_c0_guest_entryhi(cop0);
	tlb->tlb_lo[0] = kvm_read_c0_guest_entrylo0(cop0);
	tlb->tlb_lo[1] = kvm_read_c0_guest_entrylo1(cop0);

	kvm_debug("[%#lx] COP0_TLBWI [%d] (entryhi: %#lx, entrylo0: %#lx entrylo1: %#lx, mask: %#lx)\n",
		  pc, index, kvm_read_c0_guest_entryhi(cop0),
		  kvm_read_c0_guest_entrylo0(cop0),
		  kvm_read_c0_guest_entrylo1(cop0),
		  kvm_read_c0_guest_pagemask(cop0));

	return EMULATE_DONE;
}

/* Write Guest TLB Entry @ Random Index */
enum emulation_result kvm_mips_emul_tlbwr(struct kvm_vcpu *vcpu)
{
	struct mips_coproc *cop0 = vcpu->arch.cop0;
	struct kvm_mips_tlb *tlb = NULL;
	unsigned long pc = vcpu->arch.pc;
	int index;

	index = prandom_u32_max(KVM_MIPS_GUEST_TLB_SIZE);
	tlb = &vcpu->arch.guest_tlb[index];

	kvm_mips_invalidate_guest_tlb(vcpu, tlb);

	tlb->tlb_mask = kvm_read_c0_guest_pagemask(cop0);
	tlb->tlb_hi = kvm_read_c0_guest_entryhi(cop0);
	tlb->tlb_lo[0] = kvm_read_c0_guest_entrylo0(cop0);
	tlb->tlb_lo[1] = kvm_read_c0_guest_entrylo1(cop0);

	kvm_debug("[%#lx] COP0_TLBWR[%d] (entryhi: %#lx, entrylo0: %#lx entrylo1: %#lx)\n",
		  pc, index, kvm_read_c0_guest_entryhi(cop0),
		  kvm_read_c0_guest_entrylo0(cop0),
		  kvm_read_c0_guest_entrylo1(cop0));

	return EMULATE_DONE;
}

enum emulation_result kvm_mips_emul_tlbp(struct kvm_vcpu *vcpu)
{
	struct mips_coproc *cop0 = vcpu->arch.cop0;
	long entryhi = kvm_read_c0_guest_entryhi(cop0);
	unsigned long pc = vcpu->arch.pc;
	int index = -1;

	index = kvm_mips_guest_tlb_lookup(vcpu, entryhi);

	kvm_write_c0_guest_index(cop0, index);

	kvm_debug("[%#lx] COP0_TLBP (entryhi: %#lx), index: %d\n", pc, entryhi,
		  index);

	return EMULATE_DONE;
}

/**
 * kvm_mips_config1_wrmask() - Find mask of writable bits in guest Config1
 * @vcpu:	Virtual CPU.
 *
 * Finds the mask of bits which are writable in the guest's Config1 CP0
 * register, by userland (currently read-only to the guest).
 */
unsigned int kvm_mips_config1_wrmask(struct kvm_vcpu *vcpu)
{
	unsigned int mask = 0;

	/* Permit FPU to be present if FPU is supported */
	if (kvm_mips_guest_can_have_fpu(&vcpu->arch))
		mask |= MIPS_CONF1_FP;

	return mask;
}

/**
 * kvm_mips_config3_wrmask() - Find mask of writable bits in guest Config3
 * @vcpu:	Virtual CPU.
 *
 * Finds the mask of bits which are writable in the guest's Config3 CP0
 * register, by userland (currently read-only to the guest).
 */
unsigned int kvm_mips_config3_wrmask(struct kvm_vcpu *vcpu)
{
	/* Config4 and ULRI are optional */
	unsigned int mask = MIPS_CONF_M | MIPS_CONF3_ULRI;

	/* Permit MSA to be present if MSA is supported */
	if (kvm_mips_guest_can_have_msa(&vcpu->arch))
		mask |= MIPS_CONF3_MSA;

	return mask;
}

/**
 * kvm_mips_config4_wrmask() - Find mask of writable bits in guest Config4
 * @vcpu:	Virtual CPU.
 *
 * Finds the mask of bits which are writable in the guest's Config4 CP0
 * register, by userland (currently read-only to the guest).
 */
unsigned int kvm_mips_config4_wrmask(struct kvm_vcpu *vcpu)
{
	/* Config5 is optional */
	unsigned int mask = MIPS_CONF_M;

	/* KScrExist */
	mask |= 0xfc << MIPS_CONF4_KSCREXIST_SHIFT;

	return mask;
}

/**
 * kvm_mips_config5_wrmask() - Find mask of writable bits in guest Config5
 * @vcpu:	Virtual CPU.
 *
 * Finds the mask of bits which are writable in the guest's Config5 CP0
 * register, by the guest itself.
 */
unsigned int kvm_mips_config5_wrmask(struct kvm_vcpu *vcpu)
{
	unsigned int mask = 0;

	/* Permit MSAEn changes if MSA supported and enabled */
	if (kvm_mips_guest_has_msa(&vcpu->arch))
		mask |= MIPS_CONF5_MSAEN;

	/*
	 * Permit guest FPU mode changes if FPU is enabled and the relevant
	 * feature exists according to FIR register.
	 */
	if (kvm_mips_guest_has_fpu(&vcpu->arch)) {
		if (cpu_has_fre)
			mask |= MIPS_CONF5_FRE;
		/* We don't support UFR or UFE */
	}

	return mask;
}

enum emulation_result kvm_mips_emulate_CP0(union mips_instruction inst,
					   u32 *opc, u32 cause,
					   struct kvm_run *run,
					   struct kvm_vcpu *vcpu)
{
	struct mips_coproc *cop0 = vcpu->arch.cop0;
	enum emulation_result er = EMULATE_DONE;
	u32 rt, rd, sel;
	unsigned long curr_pc;

	/*
	 * 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;
	er = update_pc(vcpu, cause);
	if (er == EMULATE_FAIL)
		return er;

	if (inst.co_format.co) {
		switch (inst.co_format.func) {
		case tlbr_op:	/*  Read indexed TLB entry  */
			er = kvm_mips_emul_tlbr(vcpu);
			break;
		case tlbwi_op:	/*  Write indexed  */
			er = kvm_mips_emul_tlbwi(vcpu);
			break;
		case tlbwr_op:	/*  Write random  */
			er = kvm_mips_emul_tlbwr(vcpu);
			break;
		case tlbp_op:	/* TLB Probe */
			er = kvm_mips_emul_tlbp(vcpu);
			break;
		case rfe_op:
			kvm_err("!!!COP0_RFE!!!\n");
			break;
		case eret_op:
			er = kvm_mips_emul_eret(vcpu);
			goto dont_update_pc;
		case wait_op:
			er = kvm_mips_emul_wait(vcpu);
			break;
		case hypcall_op:
			er = kvm_mips_emul_hypcall(vcpu, inst);
			break;
		}
	} else {
		rt = inst.c0r_format.rt;
		rd = inst.c0r_format.rd;
		sel = inst.c0r_format.sel;

		switch (inst.c0r_format.rs) {
		case mfc_op:
#ifdef CONFIG_KVM_MIPS_DEBUG_COP0_COUNTERS
			cop0->stat[rd][sel]++;
#endif
			/* Get reg */
			if ((rd == MIPS_CP0_COUNT) && (sel == 0)) {
				vcpu->arch.gprs[rt] =
				    (s32)kvm_mips_read_count(vcpu);
			} else if ((rd == MIPS_CP0_ERRCTL) && (sel == 0)) {
				vcpu->arch.gprs[rt] = 0x0;
#ifdef CONFIG_KVM_MIPS_DYN_TRANS
				kvm_mips_trans_mfc0(inst, opc, vcpu);
#endif
			} else {
				vcpu->arch.gprs[rt] = (s32)cop0->reg[rd][sel];

#ifdef CONFIG_KVM_MIPS_DYN_TRANS
				kvm_mips_trans_mfc0(inst, opc, vcpu);
#endif
			}

			trace_kvm_hwr(vcpu, KVM_TRACE_MFC0,
				      KVM_TRACE_COP0(rd, sel),
				      vcpu->arch.gprs[rt]);
			break;

		case dmfc_op:
			vcpu->arch.gprs[rt] = cop0->reg[rd][sel];

			trace_kvm_hwr(vcpu, KVM_TRACE_DMFC0,
				      KVM_TRACE_COP0(rd, sel),
				      vcpu->arch.gprs[rt]);
			break;

		case mtc_op:
#ifdef CONFIG_KVM_MIPS_DEBUG_COP0_COUNTERS
			cop0->stat[rd][sel]++;
#endif
			trace_kvm_hwr(vcpu, KVM_TRACE_MTC0,
				      KVM_TRACE_COP0(rd, sel),
				      vcpu->arch.gprs[rt]);

			if ((rd == MIPS_CP0_TLB_INDEX)
			    && (vcpu->arch.gprs[rt] >=
				KVM_MIPS_GUEST_TLB_SIZE)) {
				kvm_err("Invalid TLB Index: %ld",
					vcpu->arch.gprs[rt]);
				er = EMULATE_FAIL;
				break;
			}
			if ((rd == MIPS_CP0_PRID) && (sel == 1)) {
				/*
				 * Preserve core number, and keep the exception
				 * base in guest KSeg0.
				 */
				kvm_change_c0_guest_ebase(cop0, 0x1ffff000,
							  vcpu->arch.gprs[rt]);
			} else if (rd == MIPS_CP0_TLB_HI && sel == 0) {
				kvm_mips_change_entryhi(vcpu,
							vcpu->arch.gprs[rt]);
			}
			/* Are we writing to COUNT */
			else if ((rd == MIPS_CP0_COUNT) && (sel == 0)) {
				kvm_mips_write_count(vcpu, vcpu->arch.gprs[rt]);
				goto done;
			} else if ((rd == MIPS_CP0_COMPARE) && (sel == 0)) {
				/* If we are writing to COMPARE */
				/* Clear pending timer interrupt, if any */
				kvm_mips_write_compare(vcpu,
						       vcpu->arch.gprs[rt],
						       true);
			} else if ((rd == MIPS_CP0_STATUS) && (sel == 0)) {
				unsigned int old_val, val, change;

				old_val = kvm_read_c0_guest_status(cop0);
				val = vcpu->arch.gprs[rt];
				change = val ^ old_val;

				/* Make sure that the NMI bit is never set */
				val &= ~ST0_NMI;

				/*
				 * Don't allow CU1 or FR to be set unless FPU
				 * capability enabled and exists in guest
				 * configuration.
				 */
				if (!kvm_mips_guest_has_fpu(&vcpu->arch))
					val &= ~(ST0_CU1 | ST0_FR);

				/*
				 * Also don't allow FR to be set if host doesn't
				 * support it.
				 */
				if (!(current_cpu_data.fpu_id & MIPS_FPIR_F64))
					val &= ~ST0_FR;


				/* Handle changes in FPU mode */
				preempt_disable();

				/*
				 * FPU and Vector register state is made
				 * UNPREDICTABLE by a change of FR, so don't
				 * even bother saving it.
				 */
				if (change & ST0_FR)
					kvm_drop_fpu(vcpu);

				/*
				 * If MSA state is already live, it is undefined
				 * how it interacts with FR=0 FPU state, and we
				 * don't want to hit reserved instruction
				 * exceptions trying to save the MSA state later
				 * when CU=1 && FR=1, so play it safe and save
				 * it first.
				 */
				if (change & ST0_CU1 && !(val & ST0_FR) &&
				    vcpu->arch.aux_inuse & KVM_MIPS_AUX_MSA)
					kvm_lose_fpu(vcpu);

				/*
				 * Propagate CU1 (FPU enable) changes
				 * immediately if the FPU context is already
				 * loaded. When disabling we leave the context
				 * loaded so it can be quickly enabled again in
				 * the near future.
				 */
				if (change & ST0_CU1 &&
				    vcpu->arch.aux_inuse & KVM_MIPS_AUX_FPU)
					change_c0_status(ST0_CU1, val);

				preempt_enable();

				kvm_write_c0_guest_status(cop0, val);

#ifdef CONFIG_KVM_MIPS_DYN_TRANS
				/*
				 * If FPU present, we need CU1/FR bits to take
				 * effect fairly soon.
				 */
				if (!kvm_mips_guest_has_fpu(&vcpu->arch))
					kvm_mips_trans_mtc0(inst, opc, vcpu);
#endif
			} else if ((rd == MIPS_CP0_CONFIG) && (sel == 5)) {
				unsigned int old_val, val, change, wrmask;

				old_val = kvm_read_c0_guest_config5(cop0);
				val = vcpu->arch.gprs[rt];

				/* Only a few bits are writable in Config5 */
				wrmask = kvm_mips_config5_wrmask(vcpu);
				change = (val ^ old_val) & wrmask;
				val = old_val ^ change;


				/* Handle changes in FPU/MSA modes */
				preempt_disable();

				/*
				 * Propagate FRE changes immediately if the FPU
				 * context is already loaded.
				 */
				if (change & MIPS_CONF5_FRE &&
				    vcpu->arch.aux_inuse & KVM_MIPS_AUX_FPU)
					change_c0_config5(MIPS_CONF5_FRE, val);

				/*
				 * Propagate MSAEn changes immediately if the
				 * MSA context is already loaded. When disabling
				 * we leave the context loaded so it can be
				 * quickly enabled again in the near future.
				 */
				if (change & MIPS_CONF5_MSAEN &&
				    vcpu->arch.aux_inuse & KVM_MIPS_AUX_MSA)
					change_c0_config5(MIPS_CONF5_MSAEN,
							  val);

				preempt_enable();

				kvm_write_c0_guest_config5(cop0, val);
			} else if ((rd == MIPS_CP0_CAUSE) && (sel == 0)) {
				u32 old_cause, new_cause;

				old_cause = kvm_read_c0_guest_cause(cop0);
				new_cause = vcpu->arch.gprs[rt];
				/* Update R/W bits */
				kvm_change_c0_guest_cause(cop0, 0x08800300,
							  new_cause);
				/* DC bit enabling/disabling timer? */
				if ((old_cause ^ new_cause) & CAUSEF_DC) {
					if (new_cause & CAUSEF_DC)
						kvm_mips_count_disable_cause(vcpu);
					else
						kvm_mips_count_enable_cause(vcpu);
				}
			} else if ((rd == MIPS_CP0_HWRENA) && (sel == 0)) {
				u32 mask = MIPS_HWRENA_CPUNUM |
					   MIPS_HWRENA_SYNCISTEP |
					   MIPS_HWRENA_CC |
					   MIPS_HWRENA_CCRES;

				if (kvm_read_c0_guest_config3(cop0) &
				    MIPS_CONF3_ULRI)
					mask |= MIPS_HWRENA_ULR;
				cop0->reg[rd][sel] = vcpu->arch.gprs[rt] & mask;
			} else {
				cop0->reg[rd][sel] = vcpu->arch.gprs[rt];
#ifdef CONFIG_KVM_MIPS_DYN_TRANS
				kvm_mips_trans_mtc0(inst, opc, vcpu);
#endif
			}
			break;

		case dmtc_op:
			kvm_err("!!!!!!![%#lx]dmtc_op: rt: %d, rd: %d, sel: %d!!!!!!\n",
				vcpu->arch.pc, rt, rd, sel);
			trace_kvm_hwr(vcpu, KVM_TRACE_DMTC0,
				      KVM_TRACE_COP0(rd, sel),
				      vcpu->arch.gprs[rt]);
			er = EMULATE_FAIL;
			break;

		case mfmc0_op:
#ifdef KVM_MIPS_DEBUG_COP0_COUNTERS
			cop0->stat[MIPS_CP0_STATUS][0]++;
#endif
			if (rt != 0)
				vcpu->arch.gprs[rt] =
				    kvm_read_c0_guest_status(cop0);
			/* EI */
			if (inst.mfmc0_format.sc) {
				kvm_debug("[%#lx] mfmc0_op: EI\n",
					  vcpu->arch.pc);
				kvm_set_c0_guest_status(cop0, ST0_IE);
			} else {
				kvm_debug("[%#lx] mfmc0_op: DI\n",
					  vcpu->arch.pc);
				kvm_clear_c0_guest_status(cop0, ST0_IE);
			}

			break;

		case wrpgpr_op:
			{
				u32 css = cop0->reg[MIPS_CP0_STATUS][2] & 0xf;
				u32 pss =
				    (cop0->reg[MIPS_CP0_STATUS][2] >> 6) & 0xf;
				/*
				 * We don't support any shadow register sets, so
				 * SRSCtl[PSS] == SRSCtl[CSS] = 0
				 */
				if (css || pss) {
					er = EMULATE_FAIL;
					break;
				}
				kvm_debug("WRPGPR[%d][%d] = %#lx\n", pss, rd,
					  vcpu->arch.gprs[rt]);
				vcpu->arch.gprs[rd] = vcpu->arch.gprs[rt];
			}
			break;
		default:
			kvm_err("[%#lx]MachEmulateCP0: unsupported COP0, copz: 0x%x\n",
				vcpu->arch.pc, inst.c0r_format.rs);
			er = EMULATE_FAIL;
			break;
		}
	}

done:
	/* Rollback PC only if emulation was unsuccessful */
	if (er == EMULATE_FAIL)
		vcpu->arch.pc = curr_pc;

dont_update_pc:
	/*
	 * This is for special instructions whose emulation
	 * updates the PC, so do not overwrite the PC under
	 * any circumstances
	 */

	return er;
}

enum emulation_result kvm_mips_emulate_store(union mips_instruction inst,
					     u32 cause,
					     struct kvm_run *run,
					     struct kvm_vcpu *vcpu)
{
	int r;
	enum emulation_result er;
	u32 rt;
	void *data = run->mmio.data;
	unsigned int imme;
	unsigned long curr_pc;

	/*
	 * 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;
	er = update_pc(vcpu, cause);
	if (er == EMULATE_FAIL)
		return er;

	rt = inst.i_format.rt;

	run->mmio.phys_addr = kvm_mips_callbacks->gva_to_gpa(
						vcpu->arch.host_cp0_badvaddr);
	if (run->mmio.phys_addr == KVM_INVALID_ADDR)
		goto out_fail;

	switch (inst.i_format.opcode) {
#if defined(CONFIG_64BIT) && defined(CONFIG_KVM_MIPS_VZ)
	case sd_op:
		run->mmio.len = 8;
		*(u64 *)data = vcpu->arch.gprs[rt];

		kvm_debug("[%#lx] OP_SD: eaddr: %#lx, gpr: %#lx, data: %#llx\n",
			  vcpu->arch.pc, vcpu->arch.host_cp0_badvaddr,
			  vcpu->arch.gprs[rt], *(u64 *)data);
		break;
#endif

	case sw_op:
		run->mmio.len = 4;
		*(u32 *)data = vcpu->arch.gprs[rt];

		kvm_debug("[%#lx] OP_SW: eaddr: %#lx, gpr: %#lx, data: %#x\n",
			  vcpu->arch.pc, vcpu->arch.host_cp0_badvaddr,
			  vcpu->arch.gprs[rt], *(u32 *)data);
		break;

	case sh_op:
		run->mmio.len = 2;
		*(u16 *)data = vcpu->arch.gprs[rt];

		kvm_debug("[%#lx] OP_SH: eaddr: %#lx, gpr: %#lx, data: %#x\n",
			  vcpu->arch.pc, vcpu->arch.host_cp0_badvaddr,
			  vcpu->arch.gprs[rt], *(u16 *)data);
		break;

	case sb_op:
		run->mmio.len = 1;
		*(u8 *)data = vcpu->arch.gprs[rt];

		kvm_debug("[%#lx] OP_SB: eaddr: %#lx, gpr: %#lx, data: %#x\n",
			  vcpu->arch.pc, vcpu->arch.host_cp0_badvaddr,
			  vcpu->arch.gprs[rt], *(u8 *)data);
		break;

	case swl_op:
		run->mmio.phys_addr = kvm_mips_callbacks->gva_to_gpa(
					vcpu->arch.host_cp0_badvaddr) & (~0x3);
		run->mmio.len = 4;
		imme = vcpu->arch.host_cp0_badvaddr & 0x3;
		switch (imme) {
		case 0:
			*(u32 *)data = ((*(u32 *)data) & 0xffffff00) |
					(vcpu->arch.gprs[rt] >> 24);
			break;
		case 1:
			*(u32 *)data = ((*(u32 *)data) & 0xffff0000) |
					(vcpu->arch.gprs[rt] >> 16);
			break;
		case 2:
			*(u32 *)data = ((*(u32 *)data) & 0xff000000) |
					(vcpu->arch.gprs[rt] >> 8);
			break;
		case 3:
			*(u32 *)data = vcpu->arch.gprs[rt];
			break;
		default:
			break;
		}

		kvm_debug("[%#lx] OP_SWL: eaddr: %#lx, gpr: %#lx, data: %#x\n",
			  vcpu->arch.pc, vcpu->arch.host_cp0_badvaddr,
			  vcpu->arch.gprs[rt], *(u32 *)data);
		break;

	case swr_op:
		run->mmio.phys_addr = kvm_mips_callbacks->gva_to_gpa(
					vcpu->arch.host_cp0_badvaddr) & (~0x3);
		run->mmio.len = 4;
		imme = vcpu->arch.host_cp0_badvaddr & 0x3;
		switch (imme) {
		case 0:
			*(u32 *)data = vcpu->arch.gprs[rt];
			break;
		case 1:
			*(u32 *)data = ((*(u32 *)data) & 0xff) |
					(vcpu->arch.gprs[rt] << 8);
			break;
		case 2:
			*(u32 *)data = ((*(u32 *)data) & 0xffff) |
					(vcpu->arch.gprs[rt] << 16);
			break;
		case 3:
			*(u32 *)data = ((*(u32 *)data) & 0xffffff) |
					(vcpu->arch.gprs[rt] << 24);
			break;
		default:
			break;
		}

		kvm_debug("[%#lx] OP_SWR: eaddr: %#lx, gpr: %#lx, data: %#x\n",
			  vcpu->arch.pc, vcpu->arch.host_cp0_badvaddr,
			  vcpu->arch.gprs[rt], *(u32 *)data);
		break;

	case sdl_op:
		run->mmio.phys_addr = kvm_mips_callbacks->gva_to_gpa(
					vcpu->arch.host_cp0_badvaddr) & (~0x7);

		run->mmio.len = 8;
		imme = vcpu->arch.host_cp0_badvaddr & 0x7;
		switch (imme) {
		case 0:
			*(u64 *)data = ((*(u64 *)data) & 0xffffffffffffff00) |
					((vcpu->arch.gprs[rt] >> 56) & 0xff);
			break;
		case 1:
			*(u64 *)data = ((*(u64 *)data) & 0xffffffffffff0000) |
					((vcpu->arch.gprs[rt] >> 48) & 0xffff);
			break;
		case 2:
			*(u64 *)data = ((*(u64 *)data) & 0xffffffffff000000) |
					((vcpu->arch.gprs[rt] >> 40) & 0xffffff);
			break;
		case 3:
			*(u64 *)data = ((*(u64 *)data) & 0xffffffff00000000) |
					((vcpu->arch.gprs[rt] >> 32) & 0xffffffff);
			break;
		case 4:
			*(u64 *)data = ((*(u64 *)data) & 0xffffff0000000000) |
					((vcpu->arch.gprs[rt] >> 24) & 0xffffffffff);
			break;
		case 5:
			*(u64 *)data = ((*(u64 *)data) & 0xffff000000000000) |
					((vcpu->arch.gprs[rt] >> 16) & 0xffffffffffff);
			break;
		case 6:
			*(u64 *)data = ((*(u64 *)data) & 0xff00000000000000) |
					((vcpu->arch.gprs[rt] >> 8) & 0xffffffffffffff);
			break;
		case 7:
			*(u64 *)data = vcpu->arch.gprs[rt];
			break;
		default:
			break;
		}

		kvm_debug("[%#lx] OP_SDL: eaddr: %#lx, gpr: %#lx, data: %llx\n",
			  vcpu->arch.pc, vcpu->arch.host_cp0_badvaddr,
			  vcpu->arch.gprs[rt], *(u64 *)data);
		break;

	case sdr_op:
		run->mmio.phys_addr = kvm_mips_callbacks->gva_to_gpa(
					vcpu->arch.host_cp0_badvaddr) & (~0x7);

		run->mmio.len = 8;
		imme = vcpu->arch.host_cp0_badvaddr & 0x7;
		switch (imme) {
		case 0:
			*(u64 *)data = vcpu->arch.gprs[rt];
			break;
		case 1:
			*(u64 *)data = ((*(u64 *)data) & 0xff) |
					(vcpu->arch.gprs[rt] << 8);
			break;
		case 2:
			*(u64 *)data = ((*(u64 *)data) & 0xffff) |
					(vcpu->arch.gprs[rt] << 16);
			break;
		case 3:
			*(u64 *)data = ((*(u64 *)data) & 0xffffff) |
					(vcpu->arch.gprs[rt] << 24);
			break;
		case 4:
			*(u64 *)data = ((*(u64 *)data) & 0xffffffff) |
					(vcpu->arch.gprs[rt] << 32);
			break;
		case 5:
			*(u64 *)data = ((*(u64 *)data) & 0xffffffffff) |
					(vcpu->arch.gprs[rt] << 40);
			break;
		case 6:
			*(u64 *)data = ((*(u64 *)data) & 0xffffffffffff) |
					(vcpu->arch.gprs[rt] << 48);
			break;
		case 7:
			*(u64 *)data = ((*(u64 *)data) & 0xffffffffffffff) |
					(vcpu->arch.gprs[rt] << 56);
			break;
		default:
			break;
		}

		kvm_debug("[%#lx] OP_SDR: eaddr: %#lx, gpr: %#lx, data: %llx\n",
			  vcpu->arch.pc, vcpu->arch.host_cp0_badvaddr,
			  vcpu->arch.gprs[rt], *(u64 *)data);
		break;

#ifdef CONFIG_CPU_LOONGSON64
	case sdc2_op:
		rt = inst.loongson3_lsdc2_format.rt;
		switch (inst.loongson3_lsdc2_format.opcode1) {
		/*
		 * Loongson-3 overridden sdc2 instructions.
		 * opcode1              instruction
		 *   0x0          gssbx: store 1 bytes from GPR
		 *   0x1          gsshx: store 2 bytes from GPR
		 *   0x2          gsswx: store 4 bytes from GPR
		 *   0x3          gssdx: store 8 bytes from GPR
		 */
		case 0x0:
			run->mmio.len = 1;
			*(u8 *)data = vcpu->arch.gprs[rt];

			kvm_debug("[%#lx] OP_GSSBX: eaddr: %#lx, gpr: %#lx, data: %#x\n",
				  vcpu->arch.pc, vcpu->arch.host_cp0_badvaddr,
				  vcpu->arch.gprs[rt], *(u8 *)data);
			break;
		case 0x1:
			run->mmio.len = 2;
			*(u16 *)data = vcpu->arch.gprs[rt];

			kvm_debug("[%#lx] OP_GSSSHX: eaddr: %#lx, gpr: %#lx, data: %#x\n",
				  vcpu->arch.pc, vcpu->arch.host_cp0_badvaddr,
				  vcpu->arch.gprs[rt], *(u16 *)data);
			break;
		case 0x2:
			run->mmio.len = 4;
			*(u32 *)data = vcpu->arch.gprs[rt];

			kvm_debug("[%#lx] OP_GSSWX: eaddr: %#lx, gpr: %#lx, data: %#x\n",
				  vcpu->arch.pc, vcpu->arch.host_cp0_badvaddr,
				  vcpu->arch.gprs[rt], *(u32 *)data);
			break;
		case 0x3:
			run->mmio.len = 8;
			*(u64 *)data = vcpu->arch.gprs[rt];

			kvm_debug("[%#lx] OP_GSSDX: eaddr: %#lx, gpr: %#lx, data: %#llx\n",
				  vcpu->arch.pc, vcpu->arch.host_cp0_badvaddr,
				  vcpu->arch.gprs[rt], *(u64 *)data);
			break;
		default:
			kvm_err("Godson Exteneded GS-Store not yet supported (inst=0x%08x)\n",
				inst.word);
			break;
		}
		break;
#endif
	default:
		kvm_err("Store not yet supported (inst=0x%08x)\n",
			inst.word);
		goto out_fail;
	}

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

	r = kvm_io_bus_write(vcpu, KVM_MMIO_BUS,
			run->mmio.phys_addr, run->mmio.len, data);

	if (!r) {
		vcpu->mmio_needed = 0;
		return EMULATE_DONE;
	}

	return EMULATE_DO_MMIO;

out_fail:
	/* Rollback PC if emulation was unsuccessful */
	vcpu->arch.pc = curr_pc;
	return EMULATE_FAIL;
}

enum emulation_result kvm_mips_emulate_load(union mips_instruction inst,
					    u32 cause, struct kvm_run *run,
					    struct kvm_vcpu *vcpu)
{
	int r;
	enum emulation_result er;
	unsigned long curr_pc;
	u32 op, rt;
	unsigned int imme;

	rt = inst.i_format.rt;
	op = inst.i_format.opcode;

	/*
	 * Find the resume PC now while we have safe and easy access to the
	 * prior branch instruction, and save it for
	 * kvm_mips_complete_mmio_load() to restore later.
	 */
	curr_pc = vcpu->arch.pc;
	er = update_pc(vcpu, cause);
	if (er == EMULATE_FAIL)
		return er;
	vcpu->arch.io_pc = vcpu->arch.pc;
	vcpu->arch.pc = curr_pc;

	vcpu->arch.io_gpr = rt;

	run->mmio.phys_addr = kvm_mips_callbacks->gva_to_gpa(
						vcpu->arch.host_cp0_badvaddr);
	if (run->mmio.phys_addr == KVM_INVALID_ADDR)
		return EMULATE_FAIL;

	vcpu->mmio_needed = 2;	/* signed */
	switch (op) {
#if defined(CONFIG_64BIT) && defined(CONFIG_KVM_MIPS_VZ)
	case ld_op:
		run->mmio.len = 8;
		break;

	case lwu_op:
		vcpu->mmio_needed = 1;	/* unsigned */
		/* fall through */
#endif
	case lw_op:
		run->mmio.len = 4;
		break;

	case lhu_op:
		vcpu->mmio_needed = 1;	/* unsigned */
		fallthrough;
	case lh_op:
		run->mmio.len = 2;
		break;

	case lbu_op:
		vcpu->mmio_needed = 1;	/* unsigned */
		fallthrough;
	case lb_op:
		run->mmio.len = 1;
		break;

	case lwl_op:
		run->mmio.phys_addr = kvm_mips_callbacks->gva_to_gpa(
					vcpu->arch.host_cp0_badvaddr) & (~0x3);

		run->mmio.len = 4;
		imme = vcpu->arch.host_cp0_badvaddr & 0x3;
		switch (imme) {
		case 0:
			vcpu->mmio_needed = 3;	/* 1 byte */
			break;
		case 1:
			vcpu->mmio_needed = 4;	/* 2 bytes */
			break;
		case 2:
			vcpu->mmio_needed = 5;	/* 3 bytes */
			break;
		case 3:
			vcpu->mmio_needed = 6;	/* 4 bytes */
			break;
		default:
			break;
		}
		break;

	case lwr_op:
		run->mmio.phys_addr = kvm_mips_callbacks->gva_to_gpa(
					vcpu->arch.host_cp0_badvaddr) & (~0x3);

		run->mmio.len = 4;
		imme = vcpu->arch.host_cp0_badvaddr & 0x3;
		switch (imme) {
		case 0:
			vcpu->mmio_needed = 7;	/* 4 bytes */
			break;
		case 1:
			vcpu->mmio_needed = 8;	/* 3 bytes */
			break;
		case 2:
			vcpu->mmio_needed = 9;	/* 2 bytes */
			break;
		case 3:
			vcpu->mmio_needed = 10;	/* 1 byte */
			break;
		default:
			break;
		}
		break;

	case ldl_op:
		run->mmio.phys_addr = kvm_mips_callbacks->gva_to_gpa(
					vcpu->arch.host_cp0_badvaddr) & (~0x7);

		run->mmio.len = 8;
		imme = vcpu->arch.host_cp0_badvaddr & 0x7;
		switch (imme) {
		case 0:
			vcpu->mmio_needed = 11;	/* 1 byte */
			break;
		case 1:
			vcpu->mmio_needed = 12;	/* 2 bytes */
			break;
		case 2:
			vcpu->mmio_needed = 13;	/* 3 bytes */
			break;
		case 3:
			vcpu->mmio_needed = 14;	/* 4 bytes */
			break;
		case 4:
			vcpu->mmio_needed = 15;	/* 5 bytes */
			break;
		case 5:
			vcpu->mmio_needed = 16;	/* 6 bytes */
			break;
		case 6:
			vcpu->mmio_needed = 17;	/* 7 bytes */
			break;
		case 7:
			vcpu->mmio_needed = 18;	/* 8 bytes */
			break;
		default:
			break;
		}
		break;

	case ldr_op:
		run->mmio.phys_addr = kvm_mips_callbacks->gva_to_gpa(
					vcpu->arch.host_cp0_badvaddr) & (~0x7);

		run->mmio.len = 8;
		imme = vcpu->arch.host_cp0_badvaddr & 0x7;
		switch (imme) {
		case 0:
			vcpu->mmio_needed = 19;	/* 8 bytes */
			break;
		case 1:
			vcpu->mmio_needed = 20;	/* 7 bytes */
			break;
		case 2:
			vcpu->mmio_needed = 21;	/* 6 bytes */
			break;
		case 3:
			vcpu->mmio_needed = 22;	/* 5 bytes */
			break;
		case 4:
			vcpu->mmio_needed = 23;	/* 4 bytes */
			break;
		case 5:
			vcpu->mmio_needed = 24;	/* 3 bytes */
			break;
		case 6:
			vcpu->mmio_needed = 25;	/* 2 bytes */
			break;
		case 7:
			vcpu->mmio_needed = 26;	/* 1 byte */
			break;
		default:
			break;
		}
		break;

#ifdef CONFIG_CPU_LOONGSON64
	case ldc2_op:
		rt = inst.loongson3_lsdc2_format.rt;
		switch (inst.loongson3_lsdc2_format.opcode1) {
		/*
		 * Loongson-3 overridden ldc2 instructions.
		 * opcode1              instruction
		 *   0x0          gslbx: store 1 bytes from GPR
		 *   0x1          gslhx: store 2 bytes from GPR
		 *   0x2          gslwx: store 4 bytes from GPR
		 *   0x3          gsldx: store 8 bytes from GPR
		 */
		case 0x0:
			run->mmio.len = 1;
			vcpu->mmio_needed = 27;	/* signed */
			break;
		case 0x1:
			run->mmio.len = 2;
			vcpu->mmio_needed = 28;	/* signed */
			break;
		case 0x2:
			run->mmio.len = 4;
			vcpu->mmio_needed = 29;	/* signed */
			break;
		case 0x3:
			run->mmio.len = 8;
			vcpu->mmio_needed = 30;	/* signed */
			break;
		default:
			kvm_err("Godson Exteneded GS-Load for float not yet supported (inst=0x%08x)\n",
				inst.word);
			break;
		}
		break;
#endif

	default:
		kvm_err("Load not yet supported (inst=0x%08x)\n",
			inst.word);
		vcpu->mmio_needed = 0;
		return EMULATE_FAIL;
	}

	run->mmio.is_write = 0;
	vcpu->mmio_is_write = 0;

	r = kvm_io_bus_read(vcpu, KVM_MMIO_BUS,
			run->mmio.phys_addr, run->mmio.len, run->mmio.data);

	if (!r) {
		kvm_mips_complete_mmio_load(vcpu, run);
		vcpu->mmio_needed = 0;
		return EMULATE_DONE;
	}

	return EMULATE_DO_MMIO;
}

#ifndef CONFIG_KVM_MIPS_VZ
static enum emulation_result kvm_mips_guest_cache_op(int (*fn)(unsigned long),
						     unsigned long curr_pc,
						     unsigned long addr,
						     struct kvm_run *run,
						     struct kvm_vcpu *vcpu,
						     u32 cause)
{
	int err;

	for (;;) {
		/* Carefully attempt the cache operation */
		kvm_trap_emul_gva_lockless_begin(vcpu);
		err = fn(addr);
		kvm_trap_emul_gva_lockless_end(vcpu);

		if (likely(!err))
			return EMULATE_DONE;

		/*
		 * Try to handle the fault and retry, maybe we just raced with a
		 * GVA invalidation.
		 */
		switch (kvm_trap_emul_gva_fault(vcpu, addr, false)) {
		case KVM_MIPS_GVA:
		case KVM_MIPS_GPA:
			/* bad virtual or physical address */
			return EMULATE_FAIL;
		case KVM_MIPS_TLB:
			/* no matching guest TLB */
			vcpu->arch.host_cp0_badvaddr = addr;
			vcpu->arch.pc = curr_pc;
			kvm_mips_emulate_tlbmiss_ld(cause, NULL, run, vcpu);
			return EMULATE_EXCEPT;
		case KVM_MIPS_TLBINV:
			/* invalid matching guest TLB */
			vcpu->arch.host_cp0_badvaddr = addr;
			vcpu->arch.pc = curr_pc;
			kvm_mips_emulate_tlbinv_ld(cause, NULL, run, vcpu);
			return EMULATE_EXCEPT;
		default:
			break;
		}
	}
}

enum emulation_result kvm_mips_emulate_cache(union mips_instruction inst,
					     u32 *opc, u32 cause,
					     struct kvm_run *run,
					     struct kvm_vcpu *vcpu)
{
	enum emulation_result er = EMULATE_DONE;
	u32 cache, op_inst, op, base;
	s16 offset;
	struct kvm_vcpu_arch *arch = &vcpu->arch;
	unsigned long va;
	unsigned long curr_pc;

	/*
	 * 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;
	er = update_pc(vcpu, cause);
	if (er == EMULATE_FAIL)
		return er;

	base = inst.i_format.rs;
	op_inst = inst.i_format.rt;
	if (cpu_has_mips_r6)
		offset = inst.spec3_format.simmediate;
	else
		offset = inst.i_format.simmediate;
	cache = op_inst & CacheOp_Cache;
	op = op_inst & CacheOp_Op;

	va = arch->gprs[base] + offset;

	kvm_debug("CACHE (cache: %#x, op: %#x, base[%d]: %#lx, offset: %#x\n",
		  cache, op, base, arch->gprs[base], offset);

	/*
	 * Treat INDEX_INV as a nop, basically issued by Linux on startup to
	 * invalidate the caches entirely by stepping through all the
	 * ways/indexes
	 */
	if (op == Index_Writeback_Inv) {
		kvm_debug("@ %#lx/%#lx CACHE (cache: %#x, op: %#x, base[%d]: %#lx, offset: %#x\n",
			  vcpu->arch.pc, vcpu->arch.gprs[31], cache, op, base,
			  arch->gprs[base], offset);

		if (cache == Cache_D) {
#ifdef CONFIG_CPU_R4K_CACHE_TLB
			r4k_blast_dcache();
#else
			switch (boot_cpu_type()) {
			case CPU_CAVIUM_OCTEON3:
				/* locally flush icache */
				local_flush_icache_range(0, 0);
				break;
			default:
				__flush_cache_all();
				break;
			}
#endif
		} else if (cache == Cache_I) {
#ifdef CONFIG_CPU_R4K_CACHE_TLB
			r4k_blast_icache();
#else
			switch (boot_cpu_type()) {
			case CPU_CAVIUM_OCTEON3:
				/* locally flush icache */
				local_flush_icache_range(0, 0);
				break;
			default:
				flush_icache_all();
				break;
			}
#endif
		} else {
			kvm_err("%s: unsupported CACHE INDEX operation\n",
				__func__);
			return EMULATE_FAIL;
		}

#ifdef CONFIG_KVM_MIPS_DYN_TRANS
		kvm_mips_trans_cache_index(inst, opc, vcpu);
#endif
		goto done;
	}

	/* XXXKYMA: Only a subset of cache ops are supported, used by Linux */
	if (op_inst == Hit_Writeback_Inv_D || op_inst == Hit_Invalidate_D) {
		/*
		 * Perform the dcache part of icache synchronisation on the
		 * guest's behalf.
		 */
		er = kvm_mips_guest_cache_op(protected_writeback_dcache_line,
					     curr_pc, va, run, vcpu, cause);
		if (er != EMULATE_DONE)
			goto done;
#ifdef CONFIG_KVM_MIPS_DYN_TRANS
		/*
		 * Replace the CACHE instruction, with a SYNCI, not the same,
		 * but avoids a trap
		 */
		kvm_mips_trans_cache_va(inst, opc, vcpu);
#endif
	} else if (op_inst == Hit_Invalidate_I) {
		/* Perform the icache synchronisation on the guest's behalf */
		er = kvm_mips_guest_cache_op(protected_writeback_dcache_line,
					     curr_pc, va, run, vcpu, cause);
		if (er != EMULATE_DONE)
			goto done;
		er = kvm_mips_guest_cache_op(protected_flush_icache_line,
					     curr_pc, va, run, vcpu, cause);
		if (er != EMULATE_DONE)
			goto done;

#ifdef CONFIG_KVM_MIPS_DYN_TRANS
		/* Replace the CACHE instruction, with a SYNCI */
		kvm_mips_trans_cache_va(inst, opc, vcpu);
#endif
	} else {
		kvm_err("NO-OP CACHE (cache: %#x, op: %#x, base[%d]: %#lx, offset: %#x\n",
			cache, op, base, arch->gprs[base], offset);
		er = EMULATE_FAIL;
	}

done:
	/* Rollback PC only if emulation was unsuccessful */
	if (er == EMULATE_FAIL)
		vcpu->arch.pc = curr_pc;
	/* Guest exception needs guest to resume */
	if (er == EMULATE_EXCEPT)
		er = EMULATE_DONE;

	return er;
}

enum emulation_result kvm_mips_emulate_inst(u32 cause, u32 *opc,
					    struct kvm_run *run,
					    struct kvm_vcpu *vcpu)
{
	union mips_instruction inst;
	enum emulation_result er = EMULATE_DONE;
	int err;

	/* Fetch the instruction. */
	if (cause & CAUSEF_BD)
		opc += 1;
	err = kvm_get_badinstr(opc, vcpu, &inst.word);
	if (err)
		return EMULATE_FAIL;

	switch (inst.r_format.opcode) {
	case cop0_op:
		er = kvm_mips_emulate_CP0(inst, opc, cause, run, vcpu);
		break;

#ifndef CONFIG_CPU_MIPSR6
	case cache_op:
		++vcpu->stat.cache_exits;
		trace_kvm_exit(vcpu, KVM_TRACE_EXIT_CACHE);
		er = kvm_mips_emulate_cache(inst, opc, cause, run, vcpu);
		break;
#else
	case spec3_op:
		switch (inst.spec3_format.func) {
		case cache6_op:
			++vcpu->stat.cache_exits;
			trace_kvm_exit(vcpu, KVM_TRACE_EXIT_CACHE);
			er = kvm_mips_emulate_cache(inst, opc, cause, run,
						    vcpu);
			break;
		default:
			goto unknown;
		}
		break;
unknown:
#endif

	default:
		kvm_err("Instruction emulation not supported (%p/%#x)\n", opc,
			inst.word);
		kvm_arch_vcpu_dump_regs(vcpu);
		er = EMULATE_FAIL;
		break;
	}

	return er;
}
#endif /* CONFIG_KVM_MIPS_VZ */

/**
 * kvm_mips_guest_exception_base() - Find guest exception vector base address.
 *
 * Returns:	The base address of the current guest exception vector, taking
 *		both Guest.CP0_Status.BEV and Guest.CP0_EBase into account.
 */
long kvm_mips_guest_exception_base(struct kvm_vcpu *vcpu)
{
	struct mips_coproc *cop0 = vcpu->arch.cop0;

	if (kvm_read_c0_guest_status(cop0) & ST0_BEV)
		return KVM_GUEST_CKSEG1ADDR(0x1fc00200);
	else
		return kvm_read_c0_guest_ebase(cop0) & MIPS_EBASE_BASE;
}

enum emulation_result kvm_mips_emulate_syscall(u32 cause,
					       u32 *opc,
					       struct kvm_run *run,
					       struct kvm_vcpu *vcpu)
{
	struct mips_coproc *cop0 = vcpu->arch.cop0;
	struct kvm_vcpu_arch *arch = &vcpu->arch;
	enum emulation_result er = EMULATE_DONE;

	if ((kvm_read_c0_guest_status(cop0) & ST0_EXL) == 0) {
		/* save old pc */
		kvm_write_c0_guest_epc(cop0, arch->pc);
		kvm_set_c0_guest_status(cop0, ST0_EXL);

		if (cause & CAUSEF_BD)
			kvm_set_c0_guest_cause(cop0, CAUSEF_BD);
		else
			kvm_clear_c0_guest_cause(cop0, CAUSEF_BD);

		kvm_debug("Delivering SYSCALL @ pc %#lx\n", arch->pc);

		kvm_change_c0_guest_cause(cop0, (0xff),
					  (EXCCODE_SYS << CAUSEB_EXCCODE));

		/* Set PC to the exception entry point */
		arch->pc = kvm_mips_guest_exception_base(vcpu) + 0x180;

	} else {
		kvm_err("Trying to deliver SYSCALL when EXL is already set\n");
		er = EMULATE_FAIL;
	}

	return er;
}

enum emulation_result kvm_mips_emulate_tlbmiss_ld(u32 cause,
						  u32 *opc,
						  struct kvm_run *run,
						  struct kvm_vcpu *vcpu)
{
	struct mips_coproc *cop0 = vcpu->arch.cop0;
	struct kvm_vcpu_arch *arch = &vcpu->arch;
	unsigned long entryhi = (vcpu->arch.  host_cp0_badvaddr & VPN2_MASK) |
			(kvm_read_c0_guest_entryhi(cop0) & KVM_ENTRYHI_ASID);

	if ((kvm_read_c0_guest_status(cop0) & ST0_EXL) == 0) {
		/* save old pc */
		kvm_write_c0_guest_epc(cop0, arch->pc);
		kvm_set_c0_guest_status(cop0, ST0_EXL);

		if (cause & CAUSEF_BD)
			kvm_set_c0_guest_cause(cop0, CAUSEF_BD);
		else
			kvm_clear_c0_guest_cause(cop0, CAUSEF_BD);

		kvm_debug("[EXL == 0] delivering TLB MISS @ pc %#lx\n",
			  arch->pc);

		/* set pc to the exception entry point */
		arch->pc = kvm_mips_guest_exception_base(vcpu) + 0x0;

	} else {
		kvm_debug("[EXL == 1] delivering TLB MISS @ pc %#lx\n",
			  arch->pc);

		arch->pc = kvm_mips_guest_exception_base(vcpu) + 0x180;
	}

	kvm_change_c0_guest_cause(cop0, (0xff),
				  (EXCCODE_TLBL << CAUSEB_EXCCODE));

	/* setup badvaddr, context and entryhi registers for the guest */
	kvm_write_c0_guest_badvaddr(cop0, vcpu->arch.host_cp0_badvaddr);
	/* XXXKYMA: is the context register used by linux??? */
	kvm_write_c0_guest_entryhi(cop0, entryhi);

	return EMULATE_DONE;
}

enum emulation_result kvm_mips_emulate_tlbinv_ld(u32 cause,
						 u32 *opc,
						 struct kvm_run *run,
						 struct kvm_vcpu *vcpu)
{
	struct mips_coproc *cop0 = vcpu->arch.cop0;
	struct kvm_vcpu_arch *arch = &vcpu->arch;
	unsigned long entryhi =
		(vcpu->arch.host_cp0_badvaddr & VPN2_MASK) |
		(kvm_read_c0_guest_entryhi(cop0) & KVM_ENTRYHI_ASID);

	if ((kvm_read_c0_guest_status(cop0) & ST0_EXL) == 0) {
		/* save old pc */
		kvm_write_c0_guest_epc(cop0, arch->pc);
		kvm_set_c0_guest_status(cop0, ST0_EXL);

		if (cause & CAUSEF_BD)
			kvm_set_c0_guest_cause(cop0, CAUSEF_BD);
		else
			kvm_clear_c0_guest_cause(cop0, CAUSEF_BD);

		kvm_debug("[EXL == 0] delivering TLB INV @ pc %#lx\n",
			  arch->pc);
	} else {
		kvm_debug("[EXL == 1] delivering TLB MISS @ pc %#lx\n",
			  arch->pc);
	}

	/* set pc to the exception entry point */
	arch->pc = kvm_mips_guest_exception_base(vcpu) + 0x180;

	kvm_change_c0_guest_cause(cop0, (0xff),
				  (EXCCODE_TLBL << CAUSEB_EXCCODE));

	/* setup badvaddr, context and entryhi registers for the guest */
	kvm_write_c0_guest_badvaddr(cop0, vcpu->arch.host_cp0_badvaddr);
	/* XXXKYMA: is the context register used by linux??? */
	kvm_write_c0_guest_entryhi(cop0, entryhi);

	return EMULATE_DONE;
}

enum emulation_result kvm_mips_emulate_tlbmiss_st(u32 cause,
						  u32 *opc,
						  struct kvm_run *run,
						  struct kvm_vcpu *vcpu)
{
	struct mips_coproc *cop0 = vcpu->arch.cop0;
	struct kvm_vcpu_arch *arch = &vcpu->arch;
	unsigned long entryhi = (vcpu->arch.host_cp0_badvaddr & VPN2_MASK) |
			(kvm_read_c0_guest_entryhi(cop0) & KVM_ENTRYHI_ASID);

	if ((kvm_read_c0_guest_status(cop0) & ST0_EXL) == 0) {
		/* save old pc */
		kvm_write_c0_guest_epc(cop0, arch->pc);
		kvm_set_c0_guest_status(cop0, ST0_EXL);

		if (cause & CAUSEF_BD)
			kvm_set_c0_guest_cause(cop0, CAUSEF_BD);
		else
			kvm_clear_c0_guest_cause(cop0, CAUSEF_BD);

		kvm_debug("[EXL == 0] Delivering TLB MISS @ pc %#lx\n",
			  arch->pc);

		/* Set PC to the exception entry point */
		arch->pc = kvm_mips_guest_exception_base(vcpu) + 0x0;
	} else {
		kvm_debug("[EXL == 1] Delivering TLB MISS @ pc %#lx\n",
			  arch->pc);
		arch->pc = kvm_mips_guest_exception_base(vcpu) + 0x180;
	}

	kvm_change_c0_guest_cause(cop0, (0xff),
				  (EXCCODE_TLBS << CAUSEB_EXCCODE));

	/* setup badvaddr, context and entryhi registers for the guest */
	kvm_write_c0_guest_badvaddr(cop0, vcpu->arch.host_cp0_badvaddr);
	/* XXXKYMA: is the context register used by linux??? */
	kvm_write_c0_guest_entryhi(cop0, entryhi);

	return EMULATE_DONE;
}

enum emulation_result kvm_mips_emulate_tlbinv_st(u32 cause,
						 u32 *opc,
						 struct kvm_run *run,
						 struct kvm_vcpu *vcpu)
{
	struct mips_coproc *cop0 = vcpu->arch.cop0;
	struct kvm_vcpu_arch *arch = &vcpu->arch;
	unsigned long entryhi = (vcpu->arch.host_cp0_badvaddr & VPN2_MASK) |
		(kvm_read_c0_guest_entryhi(cop0) & KVM_ENTRYHI_ASID);

	if ((kvm_read_c0_guest_status(cop0) & ST0_EXL) == 0) {
		/* save old pc */
		kvm_write_c0_guest_epc(cop0, arch->pc);
		kvm_set_c0_guest_status(cop0, ST0_EXL);

		if (cause & CAUSEF_BD)
			kvm_set_c0_guest_cause(cop0, CAUSEF_BD);
		else
			kvm_clear_c0_guest_cause(cop0, CAUSEF_BD);

		kvm_debug("[EXL == 0] Delivering TLB MISS @ pc %#lx\n",
			  arch->pc);
	} else {
		kvm_debug("[EXL == 1] Delivering TLB MISS @ pc %#lx\n",
			  arch->pc);
	}

	/* Set PC to the exception entry point */
	arch->pc = kvm_mips_guest_exception_base(vcpu) + 0x180;

	kvm_change_c0_guest_cause(cop0, (0xff),
				  (EXCCODE_TLBS << CAUSEB_EXCCODE));

	/* setup badvaddr, context and entryhi registers for the guest */
	kvm_write_c0_guest_badvaddr(cop0, vcpu->arch.host_cp0_badvaddr);
	/* XXXKYMA: is the context register used by linux??? */
	kvm_write_c0_guest_entryhi(cop0, entryhi);

	return EMULATE_DONE;
}

enum emulation_result kvm_mips_emulate_tlbmod(u32 cause,
					      u32 *opc,
					      struct kvm_run *run,
					      struct kvm_vcpu *vcpu)
{
	struct mips_coproc *cop0 = vcpu->arch.cop0;
	unsigned long entryhi = (vcpu->arch.host_cp0_badvaddr & VPN2_MASK) |
			(kvm_read_c0_guest_entryhi(cop0) & KVM_ENTRYHI_ASID);
	struct kvm_vcpu_arch *arch = &vcpu->arch;

	if ((kvm_read_c0_guest_status(cop0) & ST0_EXL) == 0) {
		/* save old pc */
		kvm_write_c0_guest_epc(cop0, arch->pc);
		kvm_set_c0_guest_status(cop0, ST0_EXL);

		if (cause & CAUSEF_BD)
			kvm_set_c0_guest_cause(cop0, CAUSEF_BD);
		else
			kvm_clear_c0_guest_cause(cop0, CAUSEF_BD);

		kvm_debug("[EXL == 0] Delivering TLB MOD @ pc %#lx\n",
			  arch->pc);
	} else {
		kvm_debug("[EXL == 1] Delivering TLB MOD @ pc %#lx\n",
			  arch->pc);
	}

	arch->pc = kvm_mips_guest_exception_base(vcpu) + 0x180;

	kvm_change_c0_guest_cause(cop0, (0xff),
				  (EXCCODE_MOD << CAUSEB_EXCCODE));

	/* setup badvaddr, context and entryhi registers for the guest */
	kvm_write_c0_guest_badvaddr(cop0, vcpu->arch.host_cp0_badvaddr);
	/* XXXKYMA: is the context register used by linux??? */
	kvm_write_c0_guest_entryhi(cop0, entryhi);

	return EMULATE_DONE;
}

enum emulation_result kvm_mips_emulate_fpu_exc(u32 cause,
					       u32 *opc,
					       struct kvm_run *run,
					       struct kvm_vcpu *vcpu)
{
	struct mips_coproc *cop0 = vcpu->arch.cop0;
	struct kvm_vcpu_arch *arch = &vcpu->arch;

	if ((kvm_read_c0_guest_status(cop0) & ST0_EXL) == 0) {
		/* save old pc */
		kvm_write_c0_guest_epc(cop0, arch->pc);
		kvm_set_c0_guest_status(cop0, ST0_EXL);

		if (cause & CAUSEF_BD)
			kvm_set_c0_guest_cause(cop0, CAUSEF_BD);
		else
			kvm_clear_c0_guest_cause(cop0, CAUSEF_BD);

	}

	arch->pc = kvm_mips_guest_exception_base(vcpu) + 0x180;

	kvm_change_c0_guest_cause(cop0, (0xff),
				  (EXCCODE_CPU << CAUSEB_EXCCODE));
	kvm_change_c0_guest_cause(cop0, (CAUSEF_CE), (0x1 << CAUSEB_CE));

	return EMULATE_DONE;
}

enum emulation_result kvm_mips_emulate_ri_exc(u32 cause,
					      u32 *opc,
					      struct kvm_run *run,
					      struct kvm_vcpu *vcpu)
{
	struct mips_coproc *cop0 = vcpu->arch.cop0;
	struct kvm_vcpu_arch *arch = &vcpu->arch;
	enum emulation_result er = EMULATE_DONE;

	if ((kvm_read_c0_guest_status(cop0) & ST0_EXL) == 0) {
		/* save old pc */
		kvm_write_c0_guest_epc(cop0, arch->pc);
		kvm_set_c0_guest_status(cop0, ST0_EXL);

		if (cause & CAUSEF_BD)
			kvm_set_c0_guest_cause(cop0, CAUSEF_BD);
		else
			kvm_clear_c0_guest_cause(cop0, CAUSEF_BD);

		kvm_debug("Delivering RI @ pc %#lx\n", arch->pc);

		kvm_change_c0_guest_cause(cop0, (0xff),
					  (EXCCODE_RI << CAUSEB_EXCCODE));

		/* Set PC to the exception entry point */
		arch->pc = kvm_mips_guest_exception_base(vcpu) + 0x180;

	} else {
		kvm_err("Trying to deliver RI when EXL is already set\n");
		er = EMULATE_FAIL;
	}

	return er;
}

enum emulation_result kvm_mips_emulate_bp_exc(u32 cause,
					      u32 *opc,
					      struct kvm_run *run,
					      struct kvm_vcpu *vcpu)
{
	struct mips_coproc *cop0 = vcpu->arch.cop0;
	struct kvm_vcpu_arch *arch = &vcpu->arch;
	enum emulation_result er = EMULATE_DONE;

	if ((kvm_read_c0_guest_status(cop0) & ST0_EXL) == 0) {
		/* save old pc */
		kvm_write_c0_guest_epc(cop0, arch->pc);
		kvm_set_c0_guest_status(cop0, ST0_EXL);

		if (cause & CAUSEF_BD)
			kvm_set_c0_guest_cause(cop0, CAUSEF_BD);
		else
			kvm_clear_c0_guest_cause(cop0, CAUSEF_BD);

		kvm_debug("Delivering BP @ pc %#lx\n", arch->pc);

		kvm_change_c0_guest_cause(cop0, (0xff),
					  (EXCCODE_BP << CAUSEB_EXCCODE));

		/* Set PC to the exception entry point */
		arch->pc = kvm_mips_guest_exception_base(vcpu) + 0x180;

	} else {
		kvm_err("Trying to deliver BP when EXL is already set\n");
		er = EMULATE_FAIL;
	}

	return er;
}

enum emulation_result kvm_mips_emulate_trap_exc(u32 cause,
						u32 *opc,
						struct kvm_run *run,
						struct kvm_vcpu *vcpu)
{
	struct mips_coproc *cop0 = vcpu->arch.cop0;
	struct kvm_vcpu_arch *arch = &vcpu->arch;
	enum emulation_result er = EMULATE_DONE;

	if ((kvm_read_c0_guest_status(cop0) & ST0_EXL) == 0) {
		/* save old pc */
		kvm_write_c0_guest_epc(cop0, arch->pc);
		kvm_set_c0_guest_status(cop0, ST0_EXL);

		if (cause & CAUSEF_BD)
			kvm_set_c0_guest_cause(cop0, CAUSEF_BD);
		else
			kvm_clear_c0_guest_cause(cop0, CAUSEF_BD);

		kvm_debug("Delivering TRAP @ pc %#lx\n", arch->pc);

		kvm_change_c0_guest_cause(cop0, (0xff),
					  (EXCCODE_TR << CAUSEB_EXCCODE));

		/* Set PC to the exception entry point */
		arch->pc = kvm_mips_guest_exception_base(vcpu) + 0x180;

	} else {
		kvm_err("Trying to deliver TRAP when EXL is already set\n");
		er = EMULATE_FAIL;
	}

	return er;
}

enum emulation_result kvm_mips_emulate_msafpe_exc(u32 cause,
						  u32 *opc,
						  struct kvm_run *run,
						  struct kvm_vcpu *vcpu)
{
	struct mips_coproc *cop0 = vcpu->arch.cop0;
	struct kvm_vcpu_arch *arch = &vcpu->arch;
	enum emulation_result er = EMULATE_DONE;

	if ((kvm_read_c0_guest_status(cop0) & ST0_EXL) == 0) {
		/* save old pc */
		kvm_write_c0_guest_epc(cop0, arch->pc);
		kvm_set_c0_guest_status(cop0, ST0_EXL);

		if (cause & CAUSEF_BD)
			kvm_set_c0_guest_cause(cop0, CAUSEF_BD);
		else
			kvm_clear_c0_guest_cause(cop0, CAUSEF_BD);

		kvm_debug("Delivering MSAFPE @ pc %#lx\n", arch->pc);

		kvm_change_c0_guest_cause(cop0, (0xff),
					  (EXCCODE_MSAFPE << CAUSEB_EXCCODE));

		/* Set PC to the exception entry point */
		arch->pc = kvm_mips_guest_exception_base(vcpu) + 0x180;

	} else {
		kvm_err("Trying to deliver MSAFPE when EXL is already set\n");
		er = EMULATE_FAIL;
	}

	return er;
}

enum emulation_result kvm_mips_emulate_fpe_exc(u32 cause,
					       u32 *opc,
					       struct kvm_run *run,
					       struct kvm_vcpu *vcpu)
{
	struct mips_coproc *cop0 = vcpu->arch.cop0;
	struct kvm_vcpu_arch *arch = &vcpu->arch;
	enum emulation_result er = EMULATE_DONE;

	if ((kvm_read_c0_guest_status(cop0) & ST0_EXL) == 0) {
		/* save old pc */
		kvm_write_c0_guest_epc(cop0, arch->pc);
		kvm_set_c0_guest_status(cop0, ST0_EXL);

		if (cause & CAUSEF_BD)
			kvm_set_c0_guest_cause(cop0, CAUSEF_BD);
		else
			kvm_clear_c0_guest_cause(cop0, CAUSEF_BD);

		kvm_debug("Delivering FPE @ pc %#lx\n", arch->pc);

		kvm_change_c0_guest_cause(cop0, (0xff),
					  (EXCCODE_FPE << CAUSEB_EXCCODE));

		/* Set PC to the exception entry point */
		arch->pc = kvm_mips_guest_exception_base(vcpu) + 0x180;

	} else {
		kvm_err("Trying to deliver FPE when EXL is already set\n");
		er = EMULATE_FAIL;
	}

	return er;
}

enum emulation_result kvm_mips_emulate_msadis_exc(u32 cause,
						  u32 *opc,
						  struct kvm_run *run,
						  struct kvm_vcpu *vcpu)
{
	struct mips_coproc *cop0 = vcpu->arch.cop0;
	struct kvm_vcpu_arch *arch = &vcpu->arch;
	enum emulation_result er = EMULATE_DONE;

	if ((kvm_read_c0_guest_status(cop0) & ST0_EXL) == 0) {
		/* save old pc */
		kvm_write_c0_guest_epc(cop0, arch->pc);
		kvm_set_c0_guest_status(cop0, ST0_EXL);

		if (cause & CAUSEF_BD)
			kvm_set_c0_guest_cause(cop0, CAUSEF_BD);
		else
			kvm_clear_c0_guest_cause(cop0, CAUSEF_BD);

		kvm_debug("Delivering MSADIS @ pc %#lx\n", arch->pc);

		kvm_change_c0_guest_cause(cop0, (0xff),
					  (EXCCODE_MSADIS << CAUSEB_EXCCODE));

		/* Set PC to the exception entry point */
		arch->pc = kvm_mips_guest_exception_base(vcpu) + 0x180;

	} else {
		kvm_err("Trying to deliver MSADIS when EXL is already set\n");
		er = EMULATE_FAIL;
	}

	return er;
}

enum emulation_result kvm_mips_handle_ri(u32 cause, u32 *opc,
					 struct kvm_run *run,
					 struct kvm_vcpu *vcpu)
{
	struct mips_coproc *cop0 = vcpu->arch.cop0;
	struct kvm_vcpu_arch *arch = &vcpu->arch;
	enum emulation_result er = EMULATE_DONE;
	unsigned long curr_pc;
	union mips_instruction inst;
	int err;

	/*
	 * 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;
	er = update_pc(vcpu, cause);
	if (er == EMULATE_FAIL)
		return er;

	/* Fetch the instruction. */
	if (cause & CAUSEF_BD)
		opc += 1;
	err = kvm_get_badinstr(opc, vcpu, &inst.word);
	if (err) {
		kvm_err("%s: Cannot get inst @ %p (%d)\n", __func__, opc, err);
		return EMULATE_FAIL;
	}

	if (inst.r_format.opcode == spec3_op &&
	    inst.r_format.func == rdhwr_op &&
	    inst.r_format.rs == 0 &&
	    (inst.r_format.re >> 3) == 0) {
		int usermode = !KVM_GUEST_KERNEL_MODE(vcpu);
		int rd = inst.r_format.rd;
		int rt = inst.r_format.rt;
		int sel = inst.r_format.re & 0x7;

		/* If usermode, check RDHWR rd is allowed by guest HWREna */
		if (usermode && !(kvm_read_c0_guest_hwrena(cop0) & BIT(rd))) {
			kvm_debug("RDHWR %#x disallowed by HWREna @ %p\n",
				  rd, opc);
			goto emulate_ri;
		}
		switch (rd) {
		case MIPS_HWR_CPUNUM:		/* CPU number */
			arch->gprs[rt] = vcpu->vcpu_id;
			break;
		case MIPS_HWR_SYNCISTEP:	/* SYNCI length */
			arch->gprs[rt] = min(current_cpu_data.dcache.linesz,
					     current_cpu_data.icache.linesz);
			break;
		case MIPS_HWR_CC:		/* Read count register */
			arch->gprs[rt] = (s32)kvm_mips_read_count(vcpu);
			break;
		case MIPS_HWR_CCRES:		/* Count register resolution */
			switch (current_cpu_data.cputype) {
			case CPU_20KC:
			case CPU_25KF:
				arch->gprs[rt] = 1;
				break;
			default:
				arch->gprs[rt] = 2;
			}
			break;
		case MIPS_HWR_ULR:		/* Read UserLocal register */
			arch->gprs[rt] = kvm_read_c0_guest_userlocal(cop0);
			break;

		default:
			kvm_debug("RDHWR %#x not supported @ %p\n", rd, opc);
			goto emulate_ri;
		}

		trace_kvm_hwr(vcpu, KVM_TRACE_RDHWR, KVM_TRACE_HWR(rd, sel),
			      vcpu->arch.gprs[rt]);
	} else {
		kvm_debug("Emulate RI not supported @ %p: %#x\n",
			  opc, inst.word);
		goto emulate_ri;
	}

	return EMULATE_DONE;

emulate_ri:
	/*
	 * Rollback PC (if in branch delay slot then the PC already points to
	 * branch target), and pass the RI exception to the guest OS.
	 */
	vcpu->arch.pc = curr_pc;
	return kvm_mips_emulate_ri_exc(cause, opc, run, vcpu);
}

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

	if (run->mmio.len > sizeof(*gpr)) {
		kvm_err("Bad MMIO length: %d", run->mmio.len);
		er = EMULATE_FAIL;
		goto done;
	}

	/* Restore saved resume PC */
	vcpu->arch.pc = vcpu->arch.io_pc;

	switch (run->mmio.len) {
	case 8:
		switch (vcpu->mmio_needed) {
		case 11:
			*gpr = (vcpu->arch.gprs[vcpu->arch.io_gpr] & 0xffffffffffffff) |
				(((*(s64 *)run->mmio.data) & 0xff) << 56);
			break;
		case 12:
			*gpr = (vcpu->arch.gprs[vcpu->arch.io_gpr] & 0xffffffffffff) |
				(((*(s64 *)run->mmio.data) & 0xffff) << 48);
			break;
		case 13:
			*gpr = (vcpu->arch.gprs[vcpu->arch.io_gpr] & 0xffffffffff) |
				(((*(s64 *)run->mmio.data) & 0xffffff) << 40);
			break;
		case 14:
			*gpr = (vcpu->arch.gprs[vcpu->arch.io_gpr] & 0xffffffff) |
				(((*(s64 *)run->mmio.data) & 0xffffffff) << 32);
			break;
		case 15:
			*gpr = (vcpu->arch.gprs[vcpu->arch.io_gpr] & 0xffffff) |
				(((*(s64 *)run->mmio.data) & 0xffffffffff) << 24);
			break;
		case 16:
			*gpr = (vcpu->arch.gprs[vcpu->arch.io_gpr] & 0xffff) |
				(((*(s64 *)run->mmio.data) & 0xffffffffffff) << 16);
			break;
		case 17:
			*gpr = (vcpu->arch.gprs[vcpu->arch.io_gpr] & 0xff) |
				(((*(s64 *)run->mmio.data) & 0xffffffffffffff) << 8);
			break;
		case 18:
		case 19:
			*gpr = *(s64 *)run->mmio.data;
			break;
		case 20:
			*gpr = (vcpu->arch.gprs[vcpu->arch.io_gpr] & 0xff00000000000000) |
				((((*(s64 *)run->mmio.data)) >> 8) & 0xffffffffffffff);
			break;
		case 21:
			*gpr = (vcpu->arch.gprs[vcpu->arch.io_gpr] & 0xffff000000000000) |
				((((*(s64 *)run->mmio.data)) >> 16) & 0xffffffffffff);
			break;
		case 22:
			*gpr = (vcpu->arch.gprs[vcpu->arch.io_gpr] & 0xffffff0000000000) |
				((((*(s64 *)run->mmio.data)) >> 24) & 0xffffffffff);
			break;
		case 23:
			*gpr = (vcpu->arch.gprs[vcpu->arch.io_gpr] & 0xffffffff00000000) |
				((((*(s64 *)run->mmio.data)) >> 32) & 0xffffffff);
			break;
		case 24:
			*gpr = (vcpu->arch.gprs[vcpu->arch.io_gpr] & 0xffffffffff000000) |
				((((*(s64 *)run->mmio.data)) >> 40) & 0xffffff);
			break;
		case 25:
			*gpr = (vcpu->arch.gprs[vcpu->arch.io_gpr] & 0xffffffffffff0000) |
				((((*(s64 *)run->mmio.data)) >> 48) & 0xffff);
			break;
		case 26:
			*gpr = (vcpu->arch.gprs[vcpu->arch.io_gpr] & 0xffffffffffffff00) |
				((((*(s64 *)run->mmio.data)) >> 56) & 0xff);
			break;
		default:
			*gpr = *(s64 *)run->mmio.data;
		}
		break;

	case 4:
		switch (vcpu->mmio_needed) {
		case 1:
			*gpr = *(u32 *)run->mmio.data;
			break;
		case 2:
			*gpr = *(s32 *)run->mmio.data;
			break;
		case 3:
			*gpr = (vcpu->arch.gprs[vcpu->arch.io_gpr] & 0xffffff) |
				(((*(s32 *)run->mmio.data) & 0xff) << 24);
			break;
		case 4:
			*gpr = (vcpu->arch.gprs[vcpu->arch.io_gpr] & 0xffff) |
				(((*(s32 *)run->mmio.data) & 0xffff) << 16);
			break;
		case 5:
			*gpr = (vcpu->arch.gprs[vcpu->arch.io_gpr] & 0xff) |
				(((*(s32 *)run->mmio.data) & 0xffffff) << 8);
			break;
		case 6:
		case 7:
			*gpr = *(s32 *)run->mmio.data;
			break;
		case 8:
			*gpr = (vcpu->arch.gprs[vcpu->arch.io_gpr] & 0xff000000) |
				((((*(s32 *)run->mmio.data)) >> 8) & 0xffffff);
			break;
		case 9:
			*gpr = (vcpu->arch.gprs[vcpu->arch.io_gpr] & 0xffff0000) |
				((((*(s32 *)run->mmio.data)) >> 16) & 0xffff);
			break;
		case 10:
			*gpr = (vcpu->arch.gprs[vcpu->arch.io_gpr] & 0xffffff00) |
				((((*(s32 *)run->mmio.data)) >> 24) & 0xff);
			break;
		default:
			*gpr = *(s32 *)run->mmio.data;
		}
		break;

	case 2:
		if (vcpu->mmio_needed == 1)
			*gpr = *(u16 *)run->mmio.data;
		else
			*gpr = *(s16 *)run->mmio.data;

		break;
	case 1:
		if (vcpu->mmio_needed == 1)
			*gpr = *(u8 *)run->mmio.data;
		else
			*gpr = *(s8 *)run->mmio.data;
		break;
	}

done:
	return er;
}

static enum emulation_result kvm_mips_emulate_exc(u32 cause,
						  u32 *opc,
						  struct kvm_run *run,
						  struct kvm_vcpu *vcpu)
{
	u32 exccode = (cause >> CAUSEB_EXCCODE) & 0x1f;
	struct mips_coproc *cop0 = vcpu->arch.cop0;
	struct kvm_vcpu_arch *arch = &vcpu->arch;
	enum emulation_result er = EMULATE_DONE;

	if ((kvm_read_c0_guest_status(cop0) & ST0_EXL) == 0) {
		/* save old pc */
		kvm_write_c0_guest_epc(cop0, arch->pc);
		kvm_set_c0_guest_status(cop0, ST0_EXL);

		if (cause & CAUSEF_BD)
			kvm_set_c0_guest_cause(cop0, CAUSEF_BD);
		else
			kvm_clear_c0_guest_cause(cop0, CAUSEF_BD);

		kvm_change_c0_guest_cause(cop0, (0xff),
					  (exccode << CAUSEB_EXCCODE));

		/* Set PC to the exception entry point */
		arch->pc = kvm_mips_guest_exception_base(vcpu) + 0x180;
		kvm_write_c0_guest_badvaddr(cop0, vcpu->arch.host_cp0_badvaddr);

		kvm_debug("Delivering EXC %d @ pc %#lx, badVaddr: %#lx\n",
			  exccode, kvm_read_c0_guest_epc(cop0),
			  kvm_read_c0_guest_badvaddr(cop0));
	} else {
		kvm_err("Trying to deliver EXC when EXL is already set\n");
		er = EMULATE_FAIL;
	}

	return er;
}

enum emulation_result kvm_mips_check_privilege(u32 cause,
					       u32 *opc,
					       struct kvm_run *run,
					       struct kvm_vcpu *vcpu)
{
	enum emulation_result er = EMULATE_DONE;
	u32 exccode = (cause >> CAUSEB_EXCCODE) & 0x1f;
	unsigned long badvaddr = vcpu->arch.host_cp0_badvaddr;

	int usermode = !KVM_GUEST_KERNEL_MODE(vcpu);

	if (usermode) {
		switch (exccode) {
		case EXCCODE_INT:
		case EXCCODE_SYS:
		case EXCCODE_BP:
		case EXCCODE_RI:
		case EXCCODE_TR:
		case EXCCODE_MSAFPE:
		case EXCCODE_FPE:
		case EXCCODE_MSADIS:
			break;

		case EXCCODE_CPU:
			if (((cause & CAUSEF_CE) >> CAUSEB_CE) == 0)
				er = EMULATE_PRIV_FAIL;
			break;

		case EXCCODE_MOD:
			break;

		case EXCCODE_TLBL:
			/*
			 * We we are accessing Guest kernel space, then send an
			 * address error exception to the guest
			 */
			if (badvaddr >= (unsigned long) KVM_GUEST_KSEG0) {
				kvm_debug("%s: LD MISS @ %#lx\n", __func__,
					  badvaddr);
				cause &= ~0xff;
				cause |= (EXCCODE_ADEL << CAUSEB_EXCCODE);
				er = EMULATE_PRIV_FAIL;
			}
			break;

		case EXCCODE_TLBS:
			/*
			 * We we are accessing Guest kernel space, then send an
			 * address error exception to the guest
			 */
			if (badvaddr >= (unsigned long) KVM_GUEST_KSEG0) {
				kvm_debug("%s: ST MISS @ %#lx\n", __func__,
					  badvaddr);
				cause &= ~0xff;
				cause |= (EXCCODE_ADES << CAUSEB_EXCCODE);
				er = EMULATE_PRIV_FAIL;
			}
			break;

		case EXCCODE_ADES:
			kvm_debug("%s: address error ST @ %#lx\n", __func__,
				  badvaddr);
			if ((badvaddr & PAGE_MASK) == KVM_GUEST_COMMPAGE_ADDR) {
				cause &= ~0xff;
				cause |= (EXCCODE_TLBS << CAUSEB_EXCCODE);
			}
			er = EMULATE_PRIV_FAIL;
			break;
		case EXCCODE_ADEL:
			kvm_debug("%s: address error LD @ %#lx\n", __func__,
				  badvaddr);
			if ((badvaddr & PAGE_MASK) == KVM_GUEST_COMMPAGE_ADDR) {
				cause &= ~0xff;
				cause |= (EXCCODE_TLBL << CAUSEB_EXCCODE);
			}
			er = EMULATE_PRIV_FAIL;
			break;
		default:
			er = EMULATE_PRIV_FAIL;
			break;
		}
	}

	if (er == EMULATE_PRIV_FAIL)
		kvm_mips_emulate_exc(cause, opc, run, vcpu);

	return er;
}

/*
 * User Address (UA) fault, this could happen if
 * (1) TLB entry not present/valid in both Guest and shadow host TLBs, in this
 *     case we pass on the fault to the guest kernel and let it handle it.
 * (2) TLB entry is present in the Guest TLB but not in the shadow, in this
 *     case we inject the TLB from the Guest TLB into the shadow host TLB
 */
enum emulation_result kvm_mips_handle_tlbmiss(u32 cause,
					      u32 *opc,
					      struct kvm_run *run,
					      struct kvm_vcpu *vcpu,
					      bool write_fault)
{
	enum emulation_result er = EMULATE_DONE;
	u32 exccode = (cause >> CAUSEB_EXCCODE) & 0x1f;
	unsigned long va = vcpu->arch.host_cp0_badvaddr;
	int index;

	kvm_debug("kvm_mips_handle_tlbmiss: badvaddr: %#lx\n",
		  vcpu->arch.host_cp0_badvaddr);

	/*
	 * KVM would not have got the exception if this entry was valid in the
	 * shadow host TLB. Check the Guest TLB, if the entry is not there then
	 * send the guest an exception. The guest exc handler should then inject
	 * an entry into the guest TLB.
	 */
	index = kvm_mips_guest_tlb_lookup(vcpu,
		      (va & VPN2_MASK) |
		      (kvm_read_c0_guest_entryhi(vcpu->arch.cop0) &
		       KVM_ENTRYHI_ASID));
	if (index < 0) {
		if (exccode == EXCCODE_TLBL) {
			er = kvm_mips_emulate_tlbmiss_ld(cause, opc, run, vcpu);
		} else if (exccode == EXCCODE_TLBS) {
			er = kvm_mips_emulate_tlbmiss_st(cause, opc, run, vcpu);
		} else {
			kvm_err("%s: invalid exc code: %d\n", __func__,
				exccode);
			er = EMULATE_FAIL;
		}
	} else {
		struct kvm_mips_tlb *tlb = &vcpu->arch.guest_tlb[index];

		/*
		 * Check if the entry is valid, if not then setup a TLB invalid
		 * exception to the guest
		 */
		if (!TLB_IS_VALID(*tlb, va)) {
			if (exccode == EXCCODE_TLBL) {
				er = kvm_mips_emulate_tlbinv_ld(cause, opc, run,
								vcpu);
			} else if (exccode == EXCCODE_TLBS) {
				er = kvm_mips_emulate_tlbinv_st(cause, opc, run,
								vcpu);
			} else {
				kvm_err("%s: invalid exc code: %d\n", __func__,
					exccode);
				er = EMULATE_FAIL;
			}
		} else {
			kvm_debug("Injecting hi: %#lx, lo0: %#lx, lo1: %#lx into shadow host TLB\n",
				  tlb->tlb_hi, tlb->tlb_lo[0], tlb->tlb_lo[1]);
			/*
			 * OK we have a Guest TLB entry, now inject it into the
			 * shadow host TLB
			 */
			if (kvm_mips_handle_mapped_seg_tlb_fault(vcpu, tlb, va,
								 write_fault)) {
				kvm_err("%s: handling mapped seg tlb fault for %lx, index: %u, vcpu: %p, ASID: %#lx\n",
					__func__, va, index, vcpu,
					read_c0_entryhi());
				er = EMULATE_FAIL;
			}
		}
	}

	return er;
}
