kvm_timer_blocking(vcpu);
 }
 
+void kvm_timer_sync_nested(struct kvm_vcpu *vcpu)
+{
+       /*
+        * When NV2 is on, guest hypervisors have their EL1 timer register
+        * accesses redirected to the VNCR page. Any guest action taken on
+        * the timer is postponed until the next exit, leading to a very
+        * poor quality of emulation.
+        */
+       if (!is_hyp_ctxt(vcpu))
+               return;
+
+       if (!vcpu_el2_e2h_is_set(vcpu)) {
+               /*
+                * A non-VHE guest hypervisor doesn't have any direct access
+                * to its timers: the EL2 registers trap (and the HW is
+                * fully emulated), while the EL0 registers access memory
+                * despite the access being notionally direct. Boo.
+                *
+                * We update the hardware timer registers with the
+                * latest value written by the guest to the VNCR page
+                * and let the hardware take care of the rest.
+                */
+               write_sysreg_el0(__vcpu_sys_reg(vcpu, CNTV_CTL_EL0),  SYS_CNTV_CTL);
+               write_sysreg_el0(__vcpu_sys_reg(vcpu, CNTV_CVAL_EL0), SYS_CNTV_CVAL);
+               write_sysreg_el0(__vcpu_sys_reg(vcpu, CNTP_CTL_EL0),  SYS_CNTP_CTL);
+               write_sysreg_el0(__vcpu_sys_reg(vcpu, CNTP_CVAL_EL0), SYS_CNTP_CVAL);
+       } else {
+               /*
+                * For a VHE guest hypervisor, the EL2 state is directly
+                * stored in the host EL1 timers, while the emulated EL0
+                * state is stored in the VNCR page. The latter could have
+                * been updated behind our back, and we must reset the
+                * emulation of the timers.
+                */
+               struct timer_map map;
+               get_timer_map(vcpu, &map);
+
+               soft_timer_cancel(&map.emul_vtimer->hrtimer);
+               soft_timer_cancel(&map.emul_ptimer->hrtimer);
+               timer_emulate(map.emul_vtimer);
+               timer_emulate(map.emul_ptimer);
+       }
+}
+
 /*
  * With a userspace irqchip we have to check if the guest de-asserted the
  * timer and if so, unmask the timer irq signal on the host interrupt
 
 int kvm_timer_enable(struct kvm_vcpu *vcpu);
 void kvm_timer_vcpu_reset(struct kvm_vcpu *vcpu);
 void kvm_timer_vcpu_init(struct kvm_vcpu *vcpu);
+void kvm_timer_sync_nested(struct kvm_vcpu *vcpu);
 void kvm_timer_sync_user(struct kvm_vcpu *vcpu);
 bool kvm_timer_should_notify_user(struct kvm_vcpu *vcpu);
 void kvm_timer_update_run(struct kvm_vcpu *vcpu);