arm_arch_timer.h 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. /* SPDX-License-Identifier: GPL-2.0-only */
  2. /*
  3. * Copyright (C) 2012 ARM Ltd.
  4. * Author: Marc Zyngier <marc.zyngier@arm.com>
  5. */
  6. #ifndef __ASM_ARM_KVM_ARCH_TIMER_H
  7. #define __ASM_ARM_KVM_ARCH_TIMER_H
  8. #include <linux/clocksource.h>
  9. #include <linux/hrtimer.h>
  10. enum kvm_arch_timers {
  11. TIMER_PTIMER,
  12. TIMER_VTIMER,
  13. NR_KVM_EL0_TIMERS,
  14. TIMER_HVTIMER = NR_KVM_EL0_TIMERS,
  15. TIMER_HPTIMER,
  16. NR_KVM_TIMERS
  17. };
  18. enum kvm_arch_timer_regs {
  19. TIMER_REG_CNT,
  20. TIMER_REG_CVAL,
  21. TIMER_REG_TVAL,
  22. TIMER_REG_CTL,
  23. TIMER_REG_VOFF,
  24. };
  25. struct arch_timer_offset {
  26. /*
  27. * If set, pointer to one of the offsets in the kvm's offset
  28. * structure. If NULL, assume a zero offset.
  29. */
  30. u64 *vm_offset;
  31. /*
  32. * If set, pointer to one of the offsets in the vcpu's sysreg
  33. * array. If NULL, assume a zero offset.
  34. */
  35. u64 *vcpu_offset;
  36. };
  37. struct arch_timer_vm_data {
  38. /* Offset applied to the virtual timer/counter */
  39. u64 voffset;
  40. /* Offset applied to the physical timer/counter */
  41. u64 poffset;
  42. /* The PPI for each timer, global to the VM */
  43. u8 ppi[NR_KVM_TIMERS];
  44. };
  45. struct arch_timer_context {
  46. /* Emulated Timer (may be unused) */
  47. struct hrtimer hrtimer;
  48. u64 ns_frac;
  49. /* Offset for this counter/timer */
  50. struct arch_timer_offset offset;
  51. /*
  52. * We have multiple paths which can save/restore the timer state onto
  53. * the hardware, so we need some way of keeping track of where the
  54. * latest state is.
  55. */
  56. bool loaded;
  57. /* Output level of the timer IRQ */
  58. struct {
  59. bool level;
  60. } irq;
  61. /* Who am I? */
  62. enum kvm_arch_timers timer_id;
  63. /* Duplicated state from arch_timer.c for convenience */
  64. u32 host_timer_irq;
  65. };
  66. struct timer_map {
  67. struct arch_timer_context *direct_vtimer;
  68. struct arch_timer_context *direct_ptimer;
  69. struct arch_timer_context *emul_vtimer;
  70. struct arch_timer_context *emul_ptimer;
  71. };
  72. void get_timer_map(struct kvm_vcpu *vcpu, struct timer_map *map);
  73. struct arch_timer_cpu {
  74. struct arch_timer_context timers[NR_KVM_TIMERS];
  75. /* Background timer used when the guest is not running */
  76. struct hrtimer bg_timer;
  77. /* Is the timer enabled */
  78. bool enabled;
  79. };
  80. int __init kvm_timer_hyp_init(bool has_gic);
  81. int kvm_timer_enable(struct kvm_vcpu *vcpu);
  82. void kvm_timer_vcpu_reset(struct kvm_vcpu *vcpu);
  83. void kvm_timer_vcpu_init(struct kvm_vcpu *vcpu);
  84. void kvm_timer_sync_nested(struct kvm_vcpu *vcpu);
  85. void kvm_timer_sync_user(struct kvm_vcpu *vcpu);
  86. bool kvm_timer_should_notify_user(struct kvm_vcpu *vcpu);
  87. void kvm_timer_update_run(struct kvm_vcpu *vcpu);
  88. void kvm_timer_vcpu_terminate(struct kvm_vcpu *vcpu);
  89. void kvm_timer_init_vm(struct kvm *kvm);
  90. int kvm_arm_timer_set_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr);
  91. int kvm_arm_timer_get_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr);
  92. int kvm_arm_timer_has_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr);
  93. u64 kvm_phys_timer_read(void);
  94. void kvm_timer_vcpu_load(struct kvm_vcpu *vcpu);
  95. void kvm_timer_vcpu_put(struct kvm_vcpu *vcpu);
  96. void kvm_timer_init_vhe(void);
  97. #define vcpu_timer(v) (&(v)->arch.timer_cpu)
  98. #define vcpu_get_timer(v,t) (&vcpu_timer(v)->timers[(t)])
  99. #define vcpu_vtimer(v) (&(v)->arch.timer_cpu.timers[TIMER_VTIMER])
  100. #define vcpu_ptimer(v) (&(v)->arch.timer_cpu.timers[TIMER_PTIMER])
  101. #define vcpu_hvtimer(v) (&(v)->arch.timer_cpu.timers[TIMER_HVTIMER])
  102. #define vcpu_hptimer(v) (&(v)->arch.timer_cpu.timers[TIMER_HPTIMER])
  103. #define arch_timer_ctx_index(ctx) ((ctx)->timer_id)
  104. #define timer_context_to_vcpu(ctx) container_of((ctx), struct kvm_vcpu, arch.timer_cpu.timers[(ctx)->timer_id])
  105. #define timer_vm_data(ctx) (&(timer_context_to_vcpu(ctx)->kvm->arch.timer_data))
  106. #define timer_irq(ctx) (timer_vm_data(ctx)->ppi[arch_timer_ctx_index(ctx)])
  107. u64 kvm_arm_timer_read_sysreg(struct kvm_vcpu *vcpu,
  108. enum kvm_arch_timers tmr,
  109. enum kvm_arch_timer_regs treg);
  110. void kvm_arm_timer_write_sysreg(struct kvm_vcpu *vcpu,
  111. enum kvm_arch_timers tmr,
  112. enum kvm_arch_timer_regs treg,
  113. u64 val);
  114. /* Needed for tracing */
  115. u32 timer_get_ctl(struct arch_timer_context *ctxt);
  116. u64 timer_get_cval(struct arch_timer_context *ctxt);
  117. /* CPU HP callbacks */
  118. void kvm_timer_cpu_up(void);
  119. void kvm_timer_cpu_down(void);
  120. /* CNTKCTL_EL1 valid bits as of DDI0487J.a */
  121. #define CNTKCTL_VALID_BITS (BIT(17) | GENMASK_ULL(9, 0))
  122. DECLARE_STATIC_KEY_FALSE(broken_cntvoff_key);
  123. static inline bool has_broken_cntvoff(void)
  124. {
  125. return static_branch_unlikely(&broken_cntvoff_key);
  126. }
  127. static inline bool has_cntpoff(void)
  128. {
  129. return (has_vhe() && cpus_have_final_cap(ARM64_HAS_ECV_CNTPOFF));
  130. }
  131. static inline u64 timer_get_offset(struct arch_timer_context *ctxt)
  132. {
  133. u64 offset = 0;
  134. if (!ctxt)
  135. return 0;
  136. if (ctxt->offset.vm_offset)
  137. offset += *ctxt->offset.vm_offset;
  138. if (ctxt->offset.vcpu_offset)
  139. offset += *ctxt->offset.vcpu_offset;
  140. return offset;
  141. }
  142. static inline void timer_set_offset(struct arch_timer_context *ctxt, u64 offset)
  143. {
  144. if (!ctxt->offset.vm_offset) {
  145. WARN(offset, "timer %d\n", arch_timer_ctx_index(ctxt));
  146. return;
  147. }
  148. WRITE_ONCE(*ctxt->offset.vm_offset, offset);
  149. }
  150. #endif