From: Oliver Upton <oliver.upton@linux.dev>
To: Marc Zyngier <maz@kernel.org>
Cc: kvmarm@lists.linux.dev, kvm@vger.kernel.org,
linux-arm-kernel@lists.infradead.org,
James Morse <james.morse@arm.com>,
Suzuki K Poulose <suzuki.poulose@arm.com>,
Zenghui Yu <yuzenghui@huawei.com>,
Ricardo Koller <ricarkol@google.com>,
Simon Veith <sveith@amazon.de>,
Reiji Watanabe <reijiw@google.com>,
Colton Lewis <coltonlewis@google.com>,
Joey Gouly <joey.gouly@arm.com>,
dwmw2@infradead.org
Subject: Re: [PATCH v3 07/18] KVM: arm64: timers: Allow userspace to set the global counter offset
Date: Thu, 30 Mar 2023 06:26:48 +0000 [thread overview]
Message-ID: <ZCUrqIwNNdcAUSv3@linux.dev> (raw)
In-Reply-To: <20230324144704.4193635-8-maz@kernel.org>
Hi Marc,
On Fri, Mar 24, 2023 at 02:46:53PM +0000, Marc Zyngier wrote:
> And this is the moment you have all been waiting for: setting the
> counter offset from userspace.
>
> We expose a brand new capability that reports the ability to set
> the offset for both the virtual and physical sides.
>
> In keeping with the architecture, the offset is expressed as
> a delta that is substracted from the physical counter value.
>
> Once this new API is used, there is no going back, and the counters
> cannot be written to to set the offsets implicitly (the writes
> are instead ignored).
>
> Reviewed-by: Colton Lewis <coltonlewis@google.com>
> Signed-off-by: Marc Zyngier <maz@kernel.org>
> ---
> arch/arm64/include/asm/kvm_host.h | 4 +++
> arch/arm64/include/uapi/asm/kvm.h | 9 ++++++
> arch/arm64/kvm/arch_timer.c | 46 +++++++++++++++++++++++++++----
> arch/arm64/kvm/arm.c | 8 ++++++
> include/uapi/linux/kvm.h | 3 ++
> 5 files changed, 65 insertions(+), 5 deletions(-)
>
> diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
> index 002a10cbade2..116233a390e9 100644
> --- a/arch/arm64/include/asm/kvm_host.h
> +++ b/arch/arm64/include/asm/kvm_host.h
> @@ -221,6 +221,8 @@ struct kvm_arch {
> #define KVM_ARCH_FLAG_EL1_32BIT 4
> /* PSCI SYSTEM_SUSPEND enabled for the guest */
> #define KVM_ARCH_FLAG_SYSTEM_SUSPEND_ENABLED 5
> + /* VM counter offset */
> +#define KVM_ARCH_FLAG_VM_COUNTER_OFFSET 6
>
> unsigned long flags;
>
> @@ -1010,6 +1012,8 @@ int kvm_arm_vcpu_arch_has_attr(struct kvm_vcpu *vcpu,
>
> long kvm_vm_ioctl_mte_copy_tags(struct kvm *kvm,
> struct kvm_arm_copy_mte_tags *copy_tags);
> +int kvm_vm_ioctl_set_counter_offset(struct kvm *kvm,
> + struct kvm_arm_counter_offset *offset);
>
> /* Guest/host FPSIMD coordination helpers */
> int kvm_arch_vcpu_run_map_fp(struct kvm_vcpu *vcpu);
> diff --git a/arch/arm64/include/uapi/asm/kvm.h b/arch/arm64/include/uapi/asm/kvm.h
> index f8129c624b07..12fb0d8a760a 100644
> --- a/arch/arm64/include/uapi/asm/kvm.h
> +++ b/arch/arm64/include/uapi/asm/kvm.h
> @@ -198,6 +198,15 @@ struct kvm_arm_copy_mte_tags {
> __u64 reserved[2];
> };
>
> +/*
> + * Counter/Timer offset structure. Describe the virtual/physical offset.
> + * To be used with KVM_ARM_SET_COUNTER_OFFSET.
> + */
> +struct kvm_arm_counter_offset {
> + __u64 counter_offset;
> + __u64 reserved;
> +};
> +
> #define KVM_ARM_TAGS_TO_GUEST 0
> #define KVM_ARM_TAGS_FROM_GUEST 1
>
> diff --git a/arch/arm64/kvm/arch_timer.c b/arch/arm64/kvm/arch_timer.c
> index bb64a71ae193..25625e1d6d89 100644
> --- a/arch/arm64/kvm/arch_timer.c
> +++ b/arch/arm64/kvm/arch_timer.c
> @@ -851,9 +851,11 @@ void kvm_timer_vcpu_init(struct kvm_vcpu *vcpu)
> ptimer->vcpu = vcpu;
> ptimer->offset.vm_offset = &vcpu->kvm->arch.timer_data.poffset;
>
> - /* Synchronize cntvoff across all vtimers of a VM. */
> - timer_set_offset(vtimer, kvm_phys_timer_read());
> - timer_set_offset(ptimer, 0);
> + /* Synchronize offsets across timers of a VM if not already provided */
> + if (!test_bit(KVM_ARCH_FLAG_VM_COUNTER_OFFSET, &vcpu->kvm->arch.flags)) {
> + timer_set_offset(vtimer, kvm_phys_timer_read());
> + timer_set_offset(ptimer, 0);
> + }
>
> hrtimer_init(&timer->bg_timer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS_HARD);
> timer->bg_timer.function = kvm_bg_timer_expire;
> @@ -897,8 +899,11 @@ int kvm_arm_timer_set_reg(struct kvm_vcpu *vcpu, u64 regid, u64 value)
> kvm_arm_timer_write(vcpu, timer, TIMER_REG_CTL, value);
> break;
> case KVM_REG_ARM_TIMER_CNT:
> - timer = vcpu_vtimer(vcpu);
> - timer_set_offset(timer, kvm_phys_timer_read() - value);
> + if (!test_bit(KVM_ARCH_FLAG_VM_COUNTER_OFFSET,
> + &vcpu->kvm->arch.flags)) {
> + timer = vcpu_vtimer(vcpu);
> + timer_set_offset(timer, kvm_phys_timer_read() - value);
> + }
> break;
> case KVM_REG_ARM_TIMER_CVAL:
> timer = vcpu_vtimer(vcpu);
> @@ -908,6 +913,13 @@ int kvm_arm_timer_set_reg(struct kvm_vcpu *vcpu, u64 regid, u64 value)
> timer = vcpu_ptimer(vcpu);
> kvm_arm_timer_write(vcpu, timer, TIMER_REG_CTL, value);
> break;
> + case KVM_REG_ARM_PTIMER_CNT:
> + if (!test_bit(KVM_ARCH_FLAG_VM_COUNTER_OFFSET,
> + &vcpu->kvm->arch.flags)) {
> + timer = vcpu_ptimer(vcpu);
> + timer_set_offset(timer, kvm_phys_timer_read() - value);
> + }
> + break;
> case KVM_REG_ARM_PTIMER_CVAL:
> timer = vcpu_ptimer(vcpu);
> kvm_arm_timer_write(vcpu, timer, TIMER_REG_CVAL, value);
> @@ -1443,3 +1455,27 @@ int kvm_arm_timer_has_attr(struct kvm_vcpu *vcpu, struct kvm_device_attr *attr)
>
> return -ENXIO;
> }
> +
> +int kvm_vm_ioctl_set_counter_offset(struct kvm *kvm,
> + struct kvm_arm_counter_offset *offset)
> +{
> + if (offset->reserved)
> + return -EINVAL;
> +
> + if (!lock_all_vcpus(kvm))
> + return -EBUSY;
Similar to what you had mentioned over on the lock (un)inversion series,
doesn't this risk racing with vCPU creation w/o holding the kvm->lock?
Alternatively you could require this ioctl to be issued before any vCPUs
are created to avoid the need to lock them all here. But, if you see
value in poking this at runtime then fine by me.
--
Thanks,
Oliver
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
next prev parent reply other threads:[~2023-03-30 6:28 UTC|newest]
Thread overview: 27+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-03-24 14:46 [PATCH v3 00/18] KVM: arm64: Rework timer offsetting for fun and profit Marc Zyngier
2023-03-24 14:46 ` [PATCH v3 01/18] KVM: arm64: timers: Use a per-vcpu, per-timer accumulator for fractional ns Marc Zyngier
2023-03-24 14:46 ` [PATCH v3 02/18] arm64: Add CNTPOFF_EL2 register definition Marc Zyngier
2023-03-24 14:46 ` [PATCH v3 03/18] arm64: Add HAS_ECV_CNTPOFF capability Marc Zyngier
2023-03-24 14:46 ` [PATCH v3 04/18] KVM: arm64: timers: Use CNTPOFF_EL2 to offset the physical timer Marc Zyngier
2023-03-24 14:46 ` [PATCH v3 05/18] KVM: arm64: timers: Allow physical offset without CNTPOFF_EL2 Marc Zyngier
2023-03-30 6:42 ` Oliver Upton
2023-03-30 10:09 ` Marc Zyngier
2023-03-24 14:46 ` [PATCH v3 06/18] KVM: arm64: Expose {un,}lock_all_vcpus() to the rest of KVM Marc Zyngier
2023-03-24 14:46 ` [PATCH v3 07/18] KVM: arm64: timers: Allow userspace to set the global counter offset Marc Zyngier
2023-03-30 6:26 ` Oliver Upton [this message]
2023-03-30 10:15 ` Marc Zyngier
2023-03-24 14:46 ` [PATCH v3 08/18] KVM: arm64: timers: Allow save/restoring of the physical timer Marc Zyngier
2023-03-24 14:46 ` [PATCH v3 09/18] KVM: arm64: timers: Rationalise per-vcpu timer init Marc Zyngier
2023-03-24 14:46 ` [PATCH v3 10/18] KVM: arm64: timers: Abstract per-timer IRQ access Marc Zyngier
2023-03-24 14:46 ` [PATCH v3 11/18] KVM: arm64: timers: Move the timer IRQs into arch_timer_vm_data Marc Zyngier
2023-03-30 7:02 ` Oliver Upton
2023-03-30 10:19 ` Marc Zyngier
2023-03-24 14:46 ` [PATCH v3 12/18] KVM: arm64: Abstract the number of valid timers per vcpu Marc Zyngier
2023-03-24 14:46 ` [PATCH v3 13/18] KVM: arm64: Document KVM_ARM_SET_CNT_OFFSETS and co Marc Zyngier
2023-03-24 14:47 ` [PATCH v3 14/18] KVM: arm64: nv: timers: Add a per-timer, per-vcpu offset Marc Zyngier
2023-03-24 14:47 ` [PATCH v3 15/18] KVM: arm64: nv: timers: Support hyp timer emulation Marc Zyngier
2023-03-24 14:47 ` [PATCH v3 16/18] KVM: arm64: selftests: Add physical timer registers to the sysreg list Marc Zyngier
2023-03-24 14:47 ` [PATCH v3 17/18] KVM: arm64: selftests: Deal with spurious timer interrupts Marc Zyngier
2023-03-24 14:47 ` [PATCH v3 18/18] KVM: arm64: selftests: Augment existing timer test to handle variable offset Marc Zyngier
2023-03-29 5:41 ` [PATCH v3 00/18] KVM: arm64: Rework timer offsetting for fun and profit Veith, Simon
2023-03-30 17:46 ` Marc Zyngier
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=ZCUrqIwNNdcAUSv3@linux.dev \
--to=oliver.upton@linux.dev \
--cc=coltonlewis@google.com \
--cc=dwmw2@infradead.org \
--cc=james.morse@arm.com \
--cc=joey.gouly@arm.com \
--cc=kvm@vger.kernel.org \
--cc=kvmarm@lists.linux.dev \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=maz@kernel.org \
--cc=reijiw@google.com \
--cc=ricarkol@google.com \
--cc=suzuki.poulose@arm.com \
--cc=sveith@amazon.de \
--cc=yuzenghui@huawei.com \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).