Merge branch 'work.splice_read' of git://git.kernel.org/pub/scm/linux/kernel/git...
[cascardo/linux.git] / arch / arm / kvm / handle_exit.c
index 863fdf4..4e40d19 100644 (file)
 
 typedef int (*exit_handle_fn)(struct kvm_vcpu *, struct kvm_run *);
 
-static int handle_svc_hyp(struct kvm_vcpu *vcpu, struct kvm_run *run)
-{
-       /* SVC called from Hyp mode should never get here */
-       kvm_debug("SVC called from Hyp mode shouldn't go here\n");
-       BUG();
-       return -EINVAL; /* Squash warning */
-}
-
 static int handle_hvc(struct kvm_vcpu *vcpu, struct kvm_run *run)
 {
        int ret;
@@ -59,22 +51,6 @@ static int handle_smc(struct kvm_vcpu *vcpu, struct kvm_run *run)
        return 1;
 }
 
-static int handle_pabt_hyp(struct kvm_vcpu *vcpu, struct kvm_run *run)
-{
-       /* The hypervisor should never cause aborts */
-       kvm_err("Prefetch Abort taken from Hyp mode at %#08lx (HSR: %#08x)\n",
-               kvm_vcpu_get_hfar(vcpu), kvm_vcpu_get_hsr(vcpu));
-       return -EFAULT;
-}
-
-static int handle_dabt_hyp(struct kvm_vcpu *vcpu, struct kvm_run *run)
-{
-       /* This is either an error in the ws. code or an external abort */
-       kvm_err("Data Abort taken from Hyp mode at %#08lx (HSR: %#08x)\n",
-               kvm_vcpu_get_hfar(vcpu), kvm_vcpu_get_hsr(vcpu));
-       return -EFAULT;
-}
-
 /**
  * kvm_handle_wfx - handle a WFI or WFE instructions trapped in guests
  * @vcpu:      the vcpu pointer
@@ -112,13 +88,10 @@ static exit_handle_fn arm_exit_handlers[] = {
        [HSR_EC_CP14_64]        = kvm_handle_cp14_access,
        [HSR_EC_CP_0_13]        = kvm_handle_cp_0_13_access,
        [HSR_EC_CP10_ID]        = kvm_handle_cp10_id,
-       [HSR_EC_SVC_HYP]        = handle_svc_hyp,
        [HSR_EC_HVC]            = handle_hvc,
        [HSR_EC_SMC]            = handle_smc,
        [HSR_EC_IABT]           = kvm_handle_guest_abort,
-       [HSR_EC_IABT_HYP]       = handle_pabt_hyp,
        [HSR_EC_DABT]           = kvm_handle_guest_abort,
-       [HSR_EC_DABT_HYP]       = handle_dabt_hyp,
 };
 
 static exit_handle_fn kvm_get_exit_handler(struct kvm_vcpu *vcpu)
@@ -144,6 +117,25 @@ int handle_exit(struct kvm_vcpu *vcpu, struct kvm_run *run,
 {
        exit_handle_fn exit_handler;
 
+       if (ARM_ABORT_PENDING(exception_index)) {
+               u8 hsr_ec = kvm_vcpu_trap_get_class(vcpu);
+
+               /*
+                * HVC/SMC already have an adjusted PC, which we need
+                * to correct in order to return to after having
+                * injected the abort.
+                */
+               if (hsr_ec == HSR_EC_HVC || hsr_ec == HSR_EC_SMC) {
+                       u32 adj =  kvm_vcpu_trap_il_is32bit(vcpu) ? 4 : 2;
+                       *vcpu_pc(vcpu) -= adj;
+               }
+
+               kvm_inject_vabt(vcpu);
+               return 1;
+       }
+
+       exception_index = ARM_EXCEPTION_CODE(exception_index);
+
        switch (exception_index) {
        case ARM_EXCEPTION_IRQ:
                return 1;