Merge branch kvm-arm64/nv-timer-improvements into kvmarm/next
authorOliver Upton <oliver.upton@linux.dev>
Mon, 13 Feb 2023 23:26:21 +0000 (23:26 +0000)
committerOliver Upton <oliver.upton@linux.dev>
Mon, 13 Feb 2023 23:26:21 +0000 (23:26 +0000)
* kvm-arm64/nv-timer-improvements:
  : Timer emulation improvements, courtesy of Marc Zyngier.
  :
  :  - Avoid re-arming an hrtimer for a guest timer that is already pending
  :
  :  - Only reload the affected timer context when emulating a sysreg access
  :    instead of both the virtual/physical timers.
  KVM: arm64: timers: Don't BUG() on unhandled timer trap
  KVM: arm64: Reduce overhead of trapped timer sysreg accesses
  KVM: arm64: Don't arm a hrtimer for an already pending timer

Signed-off-by: Oliver Upton <oliver.upton@linux.dev>
1  2 
arch/arm64/kvm/arch_timer.c
arch/arm64/kvm/sys_regs.c

@@@ -975,15 -979,36 +987,24 @@@ void kvm_arm_timer_write_sysreg(struct 
                                enum kvm_arch_timer_regs treg,
                                u64 val)
  {
-       preempt_disable();
-       kvm_timer_vcpu_put(vcpu);
-       kvm_arm_timer_write(vcpu, vcpu_get_timer(vcpu, tmr), treg, val);
+       struct arch_timer_context *timer;
+       struct timer_map map;
  
-       kvm_timer_vcpu_load(vcpu);
-       preempt_enable();
+       get_timer_map(vcpu, &map);
+       timer = vcpu_get_timer(vcpu, tmr);
+       if (timer == map.emul_ptimer) {
+               soft_timer_cancel(&timer->hrtimer);
+               kvm_arm_timer_write(vcpu, timer, treg, val);
+               timer_emulate(timer);
+       } else {
+               preempt_disable();
+               timer_save_state(timer);
+               kvm_arm_timer_write(vcpu, timer, treg, val);
+               timer_restore_state(timer);
+               preempt_enable();
+       }
  }
  
 -static int kvm_timer_starting_cpu(unsigned int cpu)
 -{
 -      kvm_timer_init_interrupt(NULL);
 -      return 0;
 -}
 -
 -static int kvm_timer_dying_cpu(unsigned int cpu)
 -{
 -      disable_percpu_irq(host_vtimer_irq);
 -      return 0;
 -}
 -
  static int timer_irq_set_vcpu_affinity(struct irq_data *d, void *vcpu)
  {
        if (vcpu)
Simple merge