diff options
author | Andre Przywara <andre.przywara@linaro.org> | 2013-12-13 08:23:26 -0500 |
---|---|---|
committer | Christoffer Dall <christoffer.dall@linaro.org> | 2013-12-21 13:00:15 -0500 |
commit | 39735a3a390431bcf60f9174b7d64f787fd6afa9 (patch) | |
tree | fcae2ccc844be34f24043b7d14b4a373ecfd5e4a /virt/kvm | |
parent | a1a64387adeeba7a34ce06f2774e81f496ee803b (diff) |
ARM/KVM: save and restore generic timer registers
For migration to work we need to save (and later restore) the state of
each core's virtual generic timer.
Since this is per VCPU, we can use the [gs]et_one_reg ioctl and export
the three needed registers (control, counter, compare value).
Though they live in cp15 space, we don't use the existing list, since
they need special accessor functions and the arch timer is optional.
Acked-by: Marc Zynger <marc.zyngier@arm.com>
Signed-off-by: Andre Przywara <andre.przywara@linaro.org>
Signed-off-by: Christoffer Dall <christoffer.dall@linaro.org>
Diffstat (limited to 'virt/kvm')
-rw-r--r-- | virt/kvm/arm/arch_timer.c | 34 |
1 files changed, 34 insertions, 0 deletions
diff --git a/virt/kvm/arm/arch_timer.c b/virt/kvm/arm/arch_timer.c index c2e1ef4604e8..5081e809821f 100644 --- a/virt/kvm/arm/arch_timer.c +++ b/virt/kvm/arm/arch_timer.c | |||
@@ -182,6 +182,40 @@ static void kvm_timer_init_interrupt(void *info) | |||
182 | enable_percpu_irq(host_vtimer_irq, 0); | 182 | enable_percpu_irq(host_vtimer_irq, 0); |
183 | } | 183 | } |
184 | 184 | ||
185 | int kvm_arm_timer_set_reg(struct kvm_vcpu *vcpu, u64 regid, u64 value) | ||
186 | { | ||
187 | struct arch_timer_cpu *timer = &vcpu->arch.timer_cpu; | ||
188 | |||
189 | switch (regid) { | ||
190 | case KVM_REG_ARM_TIMER_CTL: | ||
191 | timer->cntv_ctl = value; | ||
192 | break; | ||
193 | case KVM_REG_ARM_TIMER_CNT: | ||
194 | vcpu->kvm->arch.timer.cntvoff = kvm_phys_timer_read() - value; | ||
195 | break; | ||
196 | case KVM_REG_ARM_TIMER_CVAL: | ||
197 | timer->cntv_cval = value; | ||
198 | break; | ||
199 | default: | ||
200 | return -1; | ||
201 | } | ||
202 | return 0; | ||
203 | } | ||
204 | |||
205 | u64 kvm_arm_timer_get_reg(struct kvm_vcpu *vcpu, u64 regid) | ||
206 | { | ||
207 | struct arch_timer_cpu *timer = &vcpu->arch.timer_cpu; | ||
208 | |||
209 | switch (regid) { | ||
210 | case KVM_REG_ARM_TIMER_CTL: | ||
211 | return timer->cntv_ctl; | ||
212 | case KVM_REG_ARM_TIMER_CNT: | ||
213 | return kvm_phys_timer_read() - vcpu->kvm->arch.timer.cntvoff; | ||
214 | case KVM_REG_ARM_TIMER_CVAL: | ||
215 | return timer->cntv_cval; | ||
216 | } | ||
217 | return (u64)-1; | ||
218 | } | ||
185 | 219 | ||
186 | static int kvm_timer_cpu_notify(struct notifier_block *self, | 220 | static int kvm_timer_cpu_notify(struct notifier_block *self, |
187 | unsigned long action, void *cpu) | 221 | unsigned long action, void *cpu) |