summaryrefslogtreecommitdiff
path: root/include/kvm
diff options
context:
space:
mode:
Diffstat (limited to 'include/kvm')
-rw-r--r--include/kvm/arm_arch_timer.h68
1 files changed, 49 insertions, 19 deletions
diff --git a/include/kvm/arm_arch_timer.h b/include/kvm/arm_arch_timer.h
index 33771352dcd6..05a18dd265b5 100644
--- a/include/kvm/arm_arch_timer.h
+++ b/include/kvm/arm_arch_timer.h
@@ -22,7 +22,22 @@
#include <linux/clocksource.h>
#include <linux/hrtimer.h>
+enum kvm_arch_timers {
+ TIMER_PTIMER,
+ TIMER_VTIMER,
+ NR_KVM_TIMERS
+};
+
+enum kvm_arch_timer_regs {
+ TIMER_REG_CNT,
+ TIMER_REG_CVAL,
+ TIMER_REG_TVAL,
+ TIMER_REG_CTL,
+};
+
struct arch_timer_context {
+ struct kvm_vcpu *vcpu;
+
/* Registers: control register, timer value */
u32 cnt_ctl;
u64 cnt_cval;
@@ -30,30 +45,36 @@ struct arch_timer_context {
/* Timer IRQ */
struct kvm_irq_level irq;
+ /* Virtual offset */
+ u64 cntvoff;
+
+ /* Emulated Timer (may be unused) */
+ struct hrtimer hrtimer;
+
/*
- * We have multiple paths which can save/restore the timer state
- * onto the hardware, so we need some way of keeping track of
- * where the latest state is.
- *
- * loaded == true: State is loaded on the hardware registers.
- * loaded == false: State is stored in memory.
+ * We have multiple paths which can save/restore the timer state onto
+ * the hardware, so we need some way of keeping track of where the
+ * latest state is.
*/
- bool loaded;
+ bool loaded;
- /* Virtual offset */
- u64 cntvoff;
+ /* Duplicated state from arch_timer.c for convenience */
+ u32 host_timer_irq;
+ u32 host_timer_irq_flags;
+};
+
+struct timer_map {
+ struct arch_timer_context *direct_vtimer;
+ struct arch_timer_context *direct_ptimer;
+ struct arch_timer_context *emul_ptimer;
};
struct arch_timer_cpu {
- struct arch_timer_context vtimer;
- struct arch_timer_context ptimer;
+ struct arch_timer_context timers[NR_KVM_TIMERS];
/* Background timer used when the guest is not running */
struct hrtimer bg_timer;
- /* Physical timer emulation */
- struct hrtimer phys_timer;
-
/* Is the timer enabled */
bool enabled;
};
@@ -76,9 +97,6 @@ int kvm_arm_timer_has_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr);
bool kvm_timer_is_pending(struct kvm_vcpu *vcpu);
-void kvm_timer_schedule(struct kvm_vcpu *vcpu);
-void kvm_timer_unschedule(struct kvm_vcpu *vcpu);
-
u64 kvm_phys_timer_read(void);
void kvm_timer_vcpu_load(struct kvm_vcpu *vcpu);
@@ -88,7 +106,19 @@ void kvm_timer_init_vhe(void);
bool kvm_arch_timer_get_input_level(int vintid);
-#define vcpu_vtimer(v) (&(v)->arch.timer_cpu.vtimer)
-#define vcpu_ptimer(v) (&(v)->arch.timer_cpu.ptimer)
+#define vcpu_timer(v) (&(v)->arch.timer_cpu)
+#define vcpu_get_timer(v,t) (&vcpu_timer(v)->timers[(t)])
+#define vcpu_vtimer(v) (&(v)->arch.timer_cpu.timers[TIMER_VTIMER])
+#define vcpu_ptimer(v) (&(v)->arch.timer_cpu.timers[TIMER_PTIMER])
+
+#define arch_timer_ctx_index(ctx) ((ctx) - vcpu_timer((ctx)->vcpu)->timers)
+
+u64 kvm_arm_timer_read_sysreg(struct kvm_vcpu *vcpu,
+ enum kvm_arch_timers tmr,
+ enum kvm_arch_timer_regs treg);
+void kvm_arm_timer_write_sysreg(struct kvm_vcpu *vcpu,
+ enum kvm_arch_timers tmr,
+ enum kvm_arch_timer_regs treg,
+ u64 val);
#endif