@@ -88,6 +88,10 @@ typedef enum {
#define ARM_EL_ISV_SHIFT 24
#define ARM_EL_IL (1 << ARM_EL_IL_SHIFT)
#define ARM_EL_ISV (1 << ARM_EL_ISV_SHIFT)
+#define ARM_EL_ISS_SHIFT 0
+#define ARM_EL_ISS_LENGTH 25
+#define ARM_EL_ISS2_SHIFT 32
+#define ARM_EL_ISS2_LENGTH 24
/* In the Data Abort syndrome */
#define ARM_EL_VNCR (1 << 13)
@@ -60,6 +60,11 @@ void kvm_arm_add_vcpu_properties(ARMCPU *cpu)
g_assert_not_reached();
}
+int kvm_arm_get_type(MachineState *ms)
+{
+ g_assert_not_reached();
+}
+
int kvm_arm_get_max_vm_ipa_size(MachineState *ms, bool *fixed_ipa)
{
g_assert_not_reached();
@@ -1414,6 +1414,43 @@ static bool kvm_arm_handle_debug(ARMCPU *cpu,
return false;
}
+/**
+ * kvm_arm_handle_hard_trap:
+ * @cpu: ARMCPU
+ * @esr: full exception state register
+ * @elr: exception link return address
+ * @far: fault address (if used)
+ *
+ * Returns: 0 if the exception has been handled, < 0 otherwise
+ */
+static int kvm_arm_handle_hard_trap(ARMCPU *cpu,
+ uint64_t esr,
+ uint64_t elr,
+ uint64_t far)
+{
+ CPUState *cs = CPU(cpu);
+ int esr_ec = extract64(esr, ARM_EL_EC_SHIFT, ARM_EL_EC_LENGTH);
+ int esr_iss = extract64(esr, ARM_EL_ISS_SHIFT, ARM_EL_ISS_LENGTH);
+ int esr_iss2 = extract64(esr, ARM_EL_ISS2_SHIFT, ARM_EL_ISS2_LENGTH);
+ int esr_il = extract64(esr, ARM_EL_IL_SHIFT, 1);
+
+ /*
+ * Ensure register state is synchronised
+ *
+ * This sets vcpu->vcpu_dirty which should ensure the registers
+ * are synced back to KVM before we restart.
+ */
+ kvm_cpu_synchronize_state(cs);
+
+ switch (esr_ec) {
+ default:
+ qemu_log_mask(LOG_UNIMP, "%s: unhandled EC: %x/%x/%x/%d\n",
+ __func__, esr_ec, esr_iss, esr_iss2, esr_il);
+ return -1;
+ }
+}
+
+
int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run)
{
ARMCPU *cpu = ARM_CPU(cs);
@@ -1430,9 +1467,16 @@ int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run)
ret = kvm_arm_handle_dabt_nisv(cpu, run->arm_nisv.esr_iss,
run->arm_nisv.fault_ipa);
break;
+ case KVM_EXIT_ARM_TRAP_HARDER:
+ ret = kvm_arm_handle_hard_trap(cpu,
+ run->arm_trap_harder.esr,
+ run->arm_trap_harder.elr,
+ run->arm_trap_harder.far);
+ break;
default:
qemu_log_mask(LOG_UNIMP, "%s: un-handled exit reason %d\n",
__func__, run->exit_reason);
+ ret = -1;
break;
}
return ret;
Currently we do nothing but report we don't handle anything and let KVM come to a halt. Signed-off-by: Alex Bennée <alex.bennee@linaro.org> --- target/arm/syndrome.h | 4 ++++ target/arm/kvm-stub.c | 5 +++++ target/arm/kvm.c | 44 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 53 insertions(+)