|
@@ -330,6 +330,33 @@ static int kvm_trap_emul_handle_break(struct kvm_vcpu *vcpu)
|
|
return ret;
|
|
return ret;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+static int kvm_trap_emul_handle_msa_disabled(struct kvm_vcpu *vcpu)
|
|
|
|
+{
|
|
|
|
+ struct kvm_run *run = vcpu->run;
|
|
|
|
+ uint32_t __user *opc = (uint32_t __user *) vcpu->arch.pc;
|
|
|
|
+ unsigned long cause = vcpu->arch.host_cp0_cause;
|
|
|
|
+ enum emulation_result er = EMULATE_DONE;
|
|
|
|
+ int ret = RESUME_GUEST;
|
|
|
|
+
|
|
|
|
+ /* No MSA supported in guest, guest reserved instruction exception */
|
|
|
|
+ er = kvm_mips_emulate_ri_exc(cause, opc, run, vcpu);
|
|
|
|
+
|
|
|
|
+ switch (er) {
|
|
|
|
+ case EMULATE_DONE:
|
|
|
|
+ ret = RESUME_GUEST;
|
|
|
|
+ break;
|
|
|
|
+
|
|
|
|
+ case EMULATE_FAIL:
|
|
|
|
+ run->exit_reason = KVM_EXIT_INTERNAL_ERROR;
|
|
|
|
+ ret = RESUME_HOST;
|
|
|
|
+ break;
|
|
|
|
+
|
|
|
|
+ default:
|
|
|
|
+ BUG();
|
|
|
|
+ }
|
|
|
|
+ return ret;
|
|
|
|
+}
|
|
|
|
+
|
|
static int kvm_trap_emul_vm_init(struct kvm *kvm)
|
|
static int kvm_trap_emul_vm_init(struct kvm *kvm)
|
|
{
|
|
{
|
|
return 0;
|
|
return 0;
|
|
@@ -470,6 +497,7 @@ static struct kvm_mips_callbacks kvm_trap_emul_callbacks = {
|
|
.handle_syscall = kvm_trap_emul_handle_syscall,
|
|
.handle_syscall = kvm_trap_emul_handle_syscall,
|
|
.handle_res_inst = kvm_trap_emul_handle_res_inst,
|
|
.handle_res_inst = kvm_trap_emul_handle_res_inst,
|
|
.handle_break = kvm_trap_emul_handle_break,
|
|
.handle_break = kvm_trap_emul_handle_break,
|
|
|
|
+ .handle_msa_disabled = kvm_trap_emul_handle_msa_disabled,
|
|
|
|
|
|
.vm_init = kvm_trap_emul_vm_init,
|
|
.vm_init = kvm_trap_emul_vm_init,
|
|
.vcpu_init = kvm_trap_emul_vcpu_init,
|
|
.vcpu_init = kvm_trap_emul_vcpu_init,
|