diff options
Diffstat (limited to 'arch/mips/kvm/emulate.c')
-rw-r--r-- | arch/mips/kvm/emulate.c | 36 |
1 files changed, 36 insertions, 0 deletions
diff --git a/arch/mips/kvm/emulate.c b/arch/mips/kvm/emulate.c index 838d3a6a5b7d..33e132dc7de8 100644 --- a/arch/mips/kvm/emulate.c +++ b/arch/mips/kvm/emulate.c | |||
@@ -1970,6 +1970,41 @@ enum emulation_result kvm_mips_emulate_bp_exc(unsigned long cause, | |||
1970 | return er; | 1970 | return er; |
1971 | } | 1971 | } |
1972 | 1972 | ||
1973 | enum emulation_result kvm_mips_emulate_trap_exc(unsigned long cause, | ||
1974 | uint32_t *opc, | ||
1975 | struct kvm_run *run, | ||
1976 | struct kvm_vcpu *vcpu) | ||
1977 | { | ||
1978 | struct mips_coproc *cop0 = vcpu->arch.cop0; | ||
1979 | struct kvm_vcpu_arch *arch = &vcpu->arch; | ||
1980 | enum emulation_result er = EMULATE_DONE; | ||
1981 | |||
1982 | if ((kvm_read_c0_guest_status(cop0) & ST0_EXL) == 0) { | ||
1983 | /* save old pc */ | ||
1984 | kvm_write_c0_guest_epc(cop0, arch->pc); | ||
1985 | kvm_set_c0_guest_status(cop0, ST0_EXL); | ||
1986 | |||
1987 | if (cause & CAUSEF_BD) | ||
1988 | kvm_set_c0_guest_cause(cop0, CAUSEF_BD); | ||
1989 | else | ||
1990 | kvm_clear_c0_guest_cause(cop0, CAUSEF_BD); | ||
1991 | |||
1992 | kvm_debug("Delivering TRAP @ pc %#lx\n", arch->pc); | ||
1993 | |||
1994 | kvm_change_c0_guest_cause(cop0, (0xff), | ||
1995 | (T_TRAP << CAUSEB_EXCCODE)); | ||
1996 | |||
1997 | /* Set PC to the exception entry point */ | ||
1998 | arch->pc = KVM_GUEST_KSEG0 + 0x180; | ||
1999 | |||
2000 | } else { | ||
2001 | kvm_err("Trying to deliver TRAP when EXL is already set\n"); | ||
2002 | er = EMULATE_FAIL; | ||
2003 | } | ||
2004 | |||
2005 | return er; | ||
2006 | } | ||
2007 | |||
1973 | /* ll/sc, rdhwr, sync emulation */ | 2008 | /* ll/sc, rdhwr, sync emulation */ |
1974 | 2009 | ||
1975 | #define OPCODE 0xfc000000 | 2010 | #define OPCODE 0xfc000000 |
@@ -2176,6 +2211,7 @@ enum emulation_result kvm_mips_check_privilege(unsigned long cause, | |||
2176 | case T_SYSCALL: | 2211 | case T_SYSCALL: |
2177 | case T_BREAK: | 2212 | case T_BREAK: |
2178 | case T_RES_INST: | 2213 | case T_RES_INST: |
2214 | case T_TRAP: | ||
2179 | case T_MSADIS: | 2215 | case T_MSADIS: |
2180 | break; | 2216 | break; |
2181 | 2217 | ||