kvm_pmu_flush_hwstate(vcpu);
 
+               local_irq_disable();
+
                kvm_timer_flush_hwstate(vcpu);
                kvm_vgic_flush_hwstate(vcpu);
 
-               local_irq_disable();
-
                /*
                 * If we have a singal pending, or need to notify a userspace
                 * irqchip about timer or PMU level changes, then we exit (and
                if (ret <= 0 || need_new_vmid_gen(vcpu->kvm) ||
                    kvm_request_pending(vcpu)) {
                        vcpu->mode = OUTSIDE_GUEST_MODE;
-                       local_irq_enable();
                        kvm_pmu_sync_hwstate(vcpu);
                        kvm_timer_sync_hwstate(vcpu);
                        kvm_vgic_sync_hwstate(vcpu);
+                       local_irq_enable();
                        preempt_enable();
                        continue;
                }
 
                kvm_arm_clear_debug(vcpu);
 
+               /*
+                * We must sync the PMU and timer state before the vgic state so
+                * that the vgic can properly sample the updated state of the
+                * interrupt line.
+                */
+               kvm_pmu_sync_hwstate(vcpu);
+               kvm_timer_sync_hwstate(vcpu);
+
+               kvm_vgic_sync_hwstate(vcpu);
+
                /*
                 * We may have taken a host interrupt in HYP mode (ie
                 * while executing the guest). This interrupt is still
                guest_exit();
                trace_kvm_exit(ret, kvm_vcpu_trap_get_class(vcpu), *vcpu_pc(vcpu));
 
-               /*
-                * We must sync the PMU and timer state before the vgic state so
-                * that the vgic can properly sample the updated state of the
-                * interrupt line.
-                */
-               kvm_pmu_sync_hwstate(vcpu);
-               kvm_timer_sync_hwstate(vcpu);
-
-               kvm_vgic_sync_hwstate(vcpu);
-
                preempt_enable();
 
                ret = handle_exit(vcpu, run, ret);