From: marc.zyngier@arm.com (Marc Zyngier)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH v4 4/5] ARM: KVM: arch_timers: Add timer world switch
Date: Fri, 23 Nov 2012 17:04:15 +0000 [thread overview]
Message-ID: <50AFAC8F.6050902@arm.com> (raw)
In-Reply-To: <20121123163026.GL32200@mudshark.cambridge.arm.com>
On 23/11/12 16:30, Will Deacon wrote:
> On Sat, Nov 10, 2012 at 03:46:25PM +0000, Christoffer Dall wrote:
>> From: Marc Zyngier <marc.zyngier@arm.com>
>>
>> Do the necessary save/restore dance for the timers in the world
>> switch code. In the process, allow the guest to read the physical
>> counter, which is useful for its own clock_event_device.
>>
>> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
>> Signed-off-by: Christoffer Dall <c.dall@virtualopensystems.com>
>> ---
>> arch/arm/kernel/asm-offsets.c | 8 ++++++++
>> arch/arm/kvm/arm.c | 3 +++
>> arch/arm/kvm/interrupts_head.S | 41 ++++++++++++++++++++++++++++++++++++++++
>> 3 files changed, 52 insertions(+)
>>
>> diff --git a/arch/arm/kernel/asm-offsets.c b/arch/arm/kernel/asm-offsets.c
>> index 39b6221..50df318 100644
>> --- a/arch/arm/kernel/asm-offsets.c
>> +++ b/arch/arm/kernel/asm-offsets.c
>> @@ -177,6 +177,14 @@ int main(void)
>> DEFINE(VGIC_CPU_APR, offsetof(struct vgic_cpu, vgic_apr));
>> DEFINE(VGIC_CPU_LR, offsetof(struct vgic_cpu, vgic_lr));
>> DEFINE(VGIC_CPU_NR_LR, offsetof(struct vgic_cpu, nr_lr));
>> +#ifdef CONFIG_KVM_ARM_TIMER
>> + DEFINE(VCPU_TIMER_CNTV_CTL, offsetof(struct kvm_vcpu, arch.timer_cpu.cntv_ctl));
>> + DEFINE(VCPU_TIMER_CNTV_CVALH, offsetof(struct kvm_vcpu, arch.timer_cpu.cntv_cval32.high));
>> + DEFINE(VCPU_TIMER_CNTV_CVALL, offsetof(struct kvm_vcpu, arch.timer_cpu.cntv_cval32.low));
>> + DEFINE(KVM_TIMER_CNTVOFF_H, offsetof(struct kvm, arch.timer.cntvoff32.high));
>> + DEFINE(KVM_TIMER_CNTVOFF_L, offsetof(struct kvm, arch.timer.cntvoff32.low));
>> + DEFINE(KVM_TIMER_ENABLED, offsetof(struct kvm, arch.timer.enabled));
>> +#endif
>> DEFINE(KVM_VGIC_VCTRL, offsetof(struct kvm, arch.vgic.vctrl_base));
>> #endif
>> DEFINE(KVM_VTTBR, offsetof(struct kvm, arch.vttbr));
>> diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
>> index 1716f12..8cdef69 100644
>> --- a/arch/arm/kvm/arm.c
>> +++ b/arch/arm/kvm/arm.c
>> @@ -661,6 +661,7 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run)
>> update_vttbr(vcpu->kvm);
>>
>> kvm_vgic_sync_to_cpu(vcpu);
>> + kvm_timer_sync_to_cpu(vcpu);
>>
>> local_irq_disable();
>>
>> @@ -674,6 +675,7 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run)
>>
>> if (ret <= 0 || need_new_vmid_gen(vcpu->kvm)) {
>> local_irq_enable();
>> + kvm_timer_sync_from_cpu(vcpu);
>> kvm_vgic_sync_from_cpu(vcpu);
>> continue;
>> }
>> @@ -713,6 +715,7 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run)
>> * Back from guest
>> *************************************************************/
>>
>> + kvm_timer_sync_from_cpu(vcpu);
>> kvm_vgic_sync_from_cpu(vcpu);
>>
>> ret = handle_exit(vcpu, run, ret);
>> diff --git a/arch/arm/kvm/interrupts_head.S b/arch/arm/kvm/interrupts_head.S
>> index 0003aab..ece84d1 100644
>> --- a/arch/arm/kvm/interrupts_head.S
>> +++ b/arch/arm/kvm/interrupts_head.S
>> @@ -422,6 +422,25 @@
>> #define CNTHCTL_PL1PCEN (1 << 1)
>>
>> .macro save_timer_state vcpup
>> +#ifdef CONFIG_KVM_ARM_TIMER
>> + ldr r4, [\vcpup, #VCPU_KVM]
>> + ldr r2, [r4, #KVM_TIMER_ENABLED]
>> + cmp r2, #0
>> + beq 1f
>> +
>> + mrc p15, 0, r2, c14, c3, 1 @ CNTV_CTL
>> + and r2, #3
>
> Why do you need this and (you do the masking on the restore path)?
Probably not necessary. We could just clear the enable below.
>
>> + str r2, [\vcpup, #VCPU_TIMER_CNTV_CTL]
>> + bic r2, #1 @ Clear ENABLE
>> + mcr p15, 0, r2, c14, c3, 1 @ CNTV_CTL
>> + isb
>> +
>> + mrrc p15, 3, r2, r3, c14 @ CNTV_CVAL
>> + str r3, [\vcpup, #VCPU_TIMER_CNTV_CVALH]
>> + str r2, [\vcpup, #VCPU_TIMER_CNTV_CVALL]
>> +
>> +1:
>> +#endif
>> @ Allow physical timer/counter access for the host
>> mrc p15, 4, r2, c14, c1, 0 @ CNTHCTL
>> orr r2, r2, #(CNTHCTL_PL1PCEN | CNTHCTL_PL1PCTEN)
>> @@ -435,6 +454,28 @@
>> orr r2, r2, #CNTHCTL_PL1PCTEN
>> bic r2, r2, #CNTHCTL_PL1PCEN
>> mcr p15, 4, r2, c14, c1, 0 @ CNTHCTL
>> +
>> +#ifdef CONFIG_KVM_ARM_TIMER
>> + ldr r4, [\vcpup, #VCPU_KVM]
>> + ldr r2, [r4, #KVM_TIMER_ENABLED]
>> + cmp r2, #0
>> + beq 1f
>> +
>> + ldr r3, [r4, #KVM_TIMER_CNTVOFF_H]
>> + ldr r2, [r4, #KVM_TIMER_CNTVOFF_L]
>> + mcrr p15, 4, r2, r3, c14 @ CNTVOFF
>> + isb
>> +
>> + ldr r3, [\vcpup, #VCPU_TIMER_CNTV_CVALH]
>> + ldr r2, [\vcpup, #VCPU_TIMER_CNTV_CVALL]
>> + mcrr p15, 3, r2, r3, c14 @ CNTV_CVAL
>> +
>> + ldr r2, [\vcpup, #VCPU_TIMER_CNTV_CTL]
>> + and r2, #3
>
> Please use the long form syntax for these instructions (and r2, r2, #3) as
> toolchains have historically been picky about accepting these when not
> targetting Thumb and it also makes it consistent with the rest of arch/arm/.
OK.
>
>> + mcr p15, 0, r2, c14, c3, 1 @ CNTV_CTL
>> + isb
>> +1:
>> +#endif
>
> It's pretty horrible to take a macro argument (vcpup) and then open-code all
> the other register numbers without moving the argument somewhere nice. Are
> callers just expected to understand that you clobber {r2,r3,r4} and avoid
> them? If so, why not just use the PCS so that people don't have to learn a
> new convention?
I'm happy to remove this vcpup and stick to r0/r1 (depending on the
path). All macros have to know about the side effects anyway, as we
switch all the registers.
M.
--
Jazz is not dead. It just smells funny...
WARNING: multiple messages have this Message-ID (diff)
From: Marc Zyngier <marc.zyngier@arm.com>
To: Will Deacon <will.deacon@arm.com>
Cc: Christoffer Dall <c.dall@virtualopensystems.com>,
"kvm@vger.kernel.org" <kvm@vger.kernel.org>,
"linux-arm-kernel@lists.infradead.org"
<linux-arm-kernel@lists.infradead.org>,
"kvmarm@lists.cs.columbia.edu" <kvmarm@lists.cs.columbia.edu>
Subject: Re: [PATCH v4 4/5] ARM: KVM: arch_timers: Add timer world switch
Date: Fri, 23 Nov 2012 17:04:15 +0000 [thread overview]
Message-ID: <50AFAC8F.6050902@arm.com> (raw)
In-Reply-To: <20121123163026.GL32200@mudshark.cambridge.arm.com>
On 23/11/12 16:30, Will Deacon wrote:
> On Sat, Nov 10, 2012 at 03:46:25PM +0000, Christoffer Dall wrote:
>> From: Marc Zyngier <marc.zyngier@arm.com>
>>
>> Do the necessary save/restore dance for the timers in the world
>> switch code. In the process, allow the guest to read the physical
>> counter, which is useful for its own clock_event_device.
>>
>> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
>> Signed-off-by: Christoffer Dall <c.dall@virtualopensystems.com>
>> ---
>> arch/arm/kernel/asm-offsets.c | 8 ++++++++
>> arch/arm/kvm/arm.c | 3 +++
>> arch/arm/kvm/interrupts_head.S | 41 ++++++++++++++++++++++++++++++++++++++++
>> 3 files changed, 52 insertions(+)
>>
>> diff --git a/arch/arm/kernel/asm-offsets.c b/arch/arm/kernel/asm-offsets.c
>> index 39b6221..50df318 100644
>> --- a/arch/arm/kernel/asm-offsets.c
>> +++ b/arch/arm/kernel/asm-offsets.c
>> @@ -177,6 +177,14 @@ int main(void)
>> DEFINE(VGIC_CPU_APR, offsetof(struct vgic_cpu, vgic_apr));
>> DEFINE(VGIC_CPU_LR, offsetof(struct vgic_cpu, vgic_lr));
>> DEFINE(VGIC_CPU_NR_LR, offsetof(struct vgic_cpu, nr_lr));
>> +#ifdef CONFIG_KVM_ARM_TIMER
>> + DEFINE(VCPU_TIMER_CNTV_CTL, offsetof(struct kvm_vcpu, arch.timer_cpu.cntv_ctl));
>> + DEFINE(VCPU_TIMER_CNTV_CVALH, offsetof(struct kvm_vcpu, arch.timer_cpu.cntv_cval32.high));
>> + DEFINE(VCPU_TIMER_CNTV_CVALL, offsetof(struct kvm_vcpu, arch.timer_cpu.cntv_cval32.low));
>> + DEFINE(KVM_TIMER_CNTVOFF_H, offsetof(struct kvm, arch.timer.cntvoff32.high));
>> + DEFINE(KVM_TIMER_CNTVOFF_L, offsetof(struct kvm, arch.timer.cntvoff32.low));
>> + DEFINE(KVM_TIMER_ENABLED, offsetof(struct kvm, arch.timer.enabled));
>> +#endif
>> DEFINE(KVM_VGIC_VCTRL, offsetof(struct kvm, arch.vgic.vctrl_base));
>> #endif
>> DEFINE(KVM_VTTBR, offsetof(struct kvm, arch.vttbr));
>> diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
>> index 1716f12..8cdef69 100644
>> --- a/arch/arm/kvm/arm.c
>> +++ b/arch/arm/kvm/arm.c
>> @@ -661,6 +661,7 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run)
>> update_vttbr(vcpu->kvm);
>>
>> kvm_vgic_sync_to_cpu(vcpu);
>> + kvm_timer_sync_to_cpu(vcpu);
>>
>> local_irq_disable();
>>
>> @@ -674,6 +675,7 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run)
>>
>> if (ret <= 0 || need_new_vmid_gen(vcpu->kvm)) {
>> local_irq_enable();
>> + kvm_timer_sync_from_cpu(vcpu);
>> kvm_vgic_sync_from_cpu(vcpu);
>> continue;
>> }
>> @@ -713,6 +715,7 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run)
>> * Back from guest
>> *************************************************************/
>>
>> + kvm_timer_sync_from_cpu(vcpu);
>> kvm_vgic_sync_from_cpu(vcpu);
>>
>> ret = handle_exit(vcpu, run, ret);
>> diff --git a/arch/arm/kvm/interrupts_head.S b/arch/arm/kvm/interrupts_head.S
>> index 0003aab..ece84d1 100644
>> --- a/arch/arm/kvm/interrupts_head.S
>> +++ b/arch/arm/kvm/interrupts_head.S
>> @@ -422,6 +422,25 @@
>> #define CNTHCTL_PL1PCEN (1 << 1)
>>
>> .macro save_timer_state vcpup
>> +#ifdef CONFIG_KVM_ARM_TIMER
>> + ldr r4, [\vcpup, #VCPU_KVM]
>> + ldr r2, [r4, #KVM_TIMER_ENABLED]
>> + cmp r2, #0
>> + beq 1f
>> +
>> + mrc p15, 0, r2, c14, c3, 1 @ CNTV_CTL
>> + and r2, #3
>
> Why do you need this and (you do the masking on the restore path)?
Probably not necessary. We could just clear the enable below.
>
>> + str r2, [\vcpup, #VCPU_TIMER_CNTV_CTL]
>> + bic r2, #1 @ Clear ENABLE
>> + mcr p15, 0, r2, c14, c3, 1 @ CNTV_CTL
>> + isb
>> +
>> + mrrc p15, 3, r2, r3, c14 @ CNTV_CVAL
>> + str r3, [\vcpup, #VCPU_TIMER_CNTV_CVALH]
>> + str r2, [\vcpup, #VCPU_TIMER_CNTV_CVALL]
>> +
>> +1:
>> +#endif
>> @ Allow physical timer/counter access for the host
>> mrc p15, 4, r2, c14, c1, 0 @ CNTHCTL
>> orr r2, r2, #(CNTHCTL_PL1PCEN | CNTHCTL_PL1PCTEN)
>> @@ -435,6 +454,28 @@
>> orr r2, r2, #CNTHCTL_PL1PCTEN
>> bic r2, r2, #CNTHCTL_PL1PCEN
>> mcr p15, 4, r2, c14, c1, 0 @ CNTHCTL
>> +
>> +#ifdef CONFIG_KVM_ARM_TIMER
>> + ldr r4, [\vcpup, #VCPU_KVM]
>> + ldr r2, [r4, #KVM_TIMER_ENABLED]
>> + cmp r2, #0
>> + beq 1f
>> +
>> + ldr r3, [r4, #KVM_TIMER_CNTVOFF_H]
>> + ldr r2, [r4, #KVM_TIMER_CNTVOFF_L]
>> + mcrr p15, 4, r2, r3, c14 @ CNTVOFF
>> + isb
>> +
>> + ldr r3, [\vcpup, #VCPU_TIMER_CNTV_CVALH]
>> + ldr r2, [\vcpup, #VCPU_TIMER_CNTV_CVALL]
>> + mcrr p15, 3, r2, r3, c14 @ CNTV_CVAL
>> +
>> + ldr r2, [\vcpup, #VCPU_TIMER_CNTV_CTL]
>> + and r2, #3
>
> Please use the long form syntax for these instructions (and r2, r2, #3) as
> toolchains have historically been picky about accepting these when not
> targetting Thumb and it also makes it consistent with the rest of arch/arm/.
OK.
>
>> + mcr p15, 0, r2, c14, c3, 1 @ CNTV_CTL
>> + isb
>> +1:
>> +#endif
>
> It's pretty horrible to take a macro argument (vcpup) and then open-code all
> the other register numbers without moving the argument somewhere nice. Are
> callers just expected to understand that you clobber {r2,r3,r4} and avoid
> them? If so, why not just use the PCS so that people don't have to learn a
> new convention?
I'm happy to remove this vcpup and stick to r0/r1 (depending on the
path). All macros have to know about the side effects anyway, as we
switch all the registers.
M.
--
Jazz is not dead. It just smells funny...
next prev parent reply other threads:[~2012-11-23 17:04 UTC|newest]
Thread overview: 38+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-11-10 15:45 [PATCH v4 0/5] KVM/ARM Architected Timers support Christoffer Dall
2012-11-10 15:45 ` Christoffer Dall
2012-11-10 15:46 ` [PATCH v4 1/5] ARM: arch_timers: switch to physical timers if HYP mode is available Christoffer Dall
2012-11-10 15:46 ` Christoffer Dall
2012-11-23 15:18 ` Will Deacon
2012-11-23 15:18 ` Will Deacon
2012-11-10 15:46 ` [PATCH v4 2/5] ARM: KVM: arch_timers: Add minimal infrastructure Christoffer Dall
2012-11-10 15:46 ` Christoffer Dall
2012-11-23 15:23 ` Will Deacon
2012-11-23 15:23 ` Will Deacon
2012-11-30 22:24 ` Christoffer Dall
2012-11-30 22:24 ` Christoffer Dall
2012-11-10 15:46 ` [PATCH v4 3/5] ARM: KVM: arch_timers: Add guest timer core support Christoffer Dall
2012-11-10 15:46 ` Christoffer Dall
2012-11-23 16:17 ` Will Deacon
2012-11-23 16:17 ` Will Deacon
2012-11-23 16:52 ` Marc Zyngier
2012-11-23 16:52 ` Marc Zyngier
2012-11-23 17:00 ` Will Deacon
2012-11-23 17:00 ` Will Deacon
2012-11-23 17:11 ` Marc Zyngier
2012-11-23 17:11 ` Marc Zyngier
2012-11-30 23:11 ` Christoffer Dall
2012-11-30 23:11 ` Christoffer Dall
2012-11-10 15:46 ` [PATCH v4 4/5] ARM: KVM: arch_timers: Add timer world switch Christoffer Dall
2012-11-10 15:46 ` Christoffer Dall
2012-11-23 16:30 ` Will Deacon
2012-11-23 16:30 ` Will Deacon
2012-11-23 17:04 ` Marc Zyngier [this message]
2012-11-23 17:04 ` Marc Zyngier
2012-12-01 0:56 ` Christoffer Dall
2012-12-01 0:56 ` Christoffer Dall
2012-11-10 15:46 ` [PATCH v4 5/5] ARM: KVM: arch_timers: Wire the init code and config option Christoffer Dall
2012-11-10 15:46 ` Christoffer Dall
2012-11-23 16:31 ` Will Deacon
2012-11-23 16:31 ` Will Deacon
2012-12-01 1:05 ` Christoffer Dall
2012-12-01 1:05 ` Christoffer Dall
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=50AFAC8F.6050902@arm.com \
--to=marc.zyngier@arm.com \
--cc=linux-arm-kernel@lists.infradead.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.