From: Marc Zyngier <maz@kernel.org>
To: Colton Lewis <coltonlewis@google.com>
Cc: kvmarm@lists.linux.dev, kvm@vger.kernel.org,
linux-arm-kernel@lists.infradead.org, james.morse@arm.com,
suzuki.poulose@arm.com, oliver.upton@linux.dev,
yuzenghui@huawei.com, ricarkol@google.com, sveith@amazon.de,
dwmw2@infradead.org
Subject: Re: [PATCH 07/16] KVM: arm64: timers: Allow physical offset without CNTPOFF_EL2
Date: Fri, 24 Feb 2023 10:54:52 +0000 [thread overview]
Message-ID: <86356vxrib.wl-maz@kernel.org> (raw)
In-Reply-To: <gsnty1oo80py.fsf@coltonlewis-kvm.c.googlers.com>
On Thu, 23 Feb 2023 22:40:25 +0000,
Colton Lewis <coltonlewis@google.com> wrote:
>
>
> Marc Zyngier <maz@kernel.org> writes:
>
> > +/* If _pred is true, set bit in _set, otherwise set it in _clr */
> > +#define assign_clear_set_bit(_pred, _bit, _clr, _set) \
> > + do { \
> > + if (_pred) \
> > + (_set) |= (_bit); \
> > + else \
> > + (_clr) |= (_bit); \
> > + } while (0)
> > +
>
> I don't think the do-while wrapper is necessary. Is there any reason
> besides style guide conformance?
It is if you want to avoid a stray ';'.
> > + /*
> > + * We have two possibility to deal with a physical offset:
> > + *
> > + * - Either we have CNTPOFF (yay!) or the offset is 0:
> > + * we let the guest freely access the HW
> > + *
> > + * - or neither of these condition apply:
> > + * we trap accesses to the HW, but still use it
> > + * after correcting the physical offset
> > + */
> > + if (!has_cntpoff() && timer_get_offset(map->direct_ptimer))
> > + tpt = tpc = true;
>
> If there are only two possibilites, then two different booleans makes
> things more complicated than it has to be.
Each boolean denotes a different architectural state. They are
separate so that someone can:
- easily understand what is going on
- affect one without affecting the other when extending this code
The "common state" is what we had before, and it was a real pig to
reverse engineer *my own code*. Yes, this is job security, but I don't
think that's a good enough reason! ;-)
So I contend that two bools make things far simpler to reason about
these things.
>
> > + assign_clear_set_bit(tpt, CNTHCTL_EL1PCEN << 10, set, clr);
> > + assign_clear_set_bit(tpc, CNTHCTL_EL1PCTEN << 10, set, clr);
>
> Might be good to name the 10 something like VHE_SHIFT so people know why
> it is applied.
VHE_SHIFT really doesn't mean more that '10' because it doesn't tell
you *why* you have to do this.
The real way of solving that one is it move everything to the sysreg
generation *and* have a way to contextualise the sysreg generation
based on features and other controls (see the discussion about
FEAT_CCIDX as an example).
>
> > +
> > +
> > + timer_set_traps(vcpu, &map);
> > }
>
> > bool kvm_timer_should_notify_user(struct kvm_vcpu *vcpu)
> > @@ -1293,27 +1363,12 @@ int kvm_timer_enable(struct kvm_vcpu *vcpu)
> > }
>
> > /*
> > - * On VHE system, we only need to configure the EL2 timer trap
> > register once,
> > - * not for every world switch.
> > - * The host kernel runs at EL2 with HCR_EL2.TGE == 1,
> > - * and this makes those bits have no effect for the host kernel
> > execution.
> > + * If we have CNTPOFF, permanently set ECV to enable it.
> > */
> > void kvm_timer_init_vhe(void)
> > {
> > - /* When HCR_EL2.E2H ==1, EL1PCEN and EL1PCTEN are shifted by 10 */
> > - u32 cnthctl_shift = 10;
> > - u64 val;
> > -
> > - /*
> > - * VHE systems allow the guest direct access to the EL1 physical
> > - * timer/counter.
> > - */
> > - val = read_sysreg(cnthctl_el2);
> > - val |= (CNTHCTL_EL1PCEN << cnthctl_shift);
> > - val |= (CNTHCTL_EL1PCTEN << cnthctl_shift);
> > if (cpus_have_final_cap(ARM64_HAS_ECV_CNTPOFF))
> > - val |= CNTHCTL_ECV;
> > - write_sysreg(val, cnthctl_el2);
> > + sysreg_clear_set(cntkctl_el1, 0, CNTHCTL_ECV);
> > }
>
> What is the reason for moving these register writes from initialization
> to vcpu load time? This contradicts the comment that says this is only
> needed once and not at every world switch. Seems like doing more work
> for no reason.
You did notice that the comment got *removed*, so that there is no
contradiction?
You also understand that with a physical offset, and in the absence of
CNTPOFF, we cannot grant access to the physical counter/timer to the
guest?
Finally, given that we always have to write various bits of
CNTKCTL_EL1 for other reasons, moving this settings shouldn't result
in any extra work (specially considering that they don't require any
extra synchronisation).
Thanks,
M.
--
Without deviation from the norm, progress is not possible.
WARNING: multiple messages have this Message-ID (diff)
From: Marc Zyngier <maz@kernel.org>
To: Colton Lewis <coltonlewis@google.com>
Cc: kvmarm@lists.linux.dev, kvm@vger.kernel.org,
linux-arm-kernel@lists.infradead.org, james.morse@arm.com,
suzuki.poulose@arm.com, oliver.upton@linux.dev,
yuzenghui@huawei.com, ricarkol@google.com, sveith@amazon.de,
dwmw2@infradead.org
Subject: Re: [PATCH 07/16] KVM: arm64: timers: Allow physical offset without CNTPOFF_EL2
Date: Fri, 24 Feb 2023 10:54:52 +0000 [thread overview]
Message-ID: <86356vxrib.wl-maz@kernel.org> (raw)
In-Reply-To: <gsnty1oo80py.fsf@coltonlewis-kvm.c.googlers.com>
On Thu, 23 Feb 2023 22:40:25 +0000,
Colton Lewis <coltonlewis@google.com> wrote:
>
>
> Marc Zyngier <maz@kernel.org> writes:
>
> > +/* If _pred is true, set bit in _set, otherwise set it in _clr */
> > +#define assign_clear_set_bit(_pred, _bit, _clr, _set) \
> > + do { \
> > + if (_pred) \
> > + (_set) |= (_bit); \
> > + else \
> > + (_clr) |= (_bit); \
> > + } while (0)
> > +
>
> I don't think the do-while wrapper is necessary. Is there any reason
> besides style guide conformance?
It is if you want to avoid a stray ';'.
> > + /*
> > + * We have two possibility to deal with a physical offset:
> > + *
> > + * - Either we have CNTPOFF (yay!) or the offset is 0:
> > + * we let the guest freely access the HW
> > + *
> > + * - or neither of these condition apply:
> > + * we trap accesses to the HW, but still use it
> > + * after correcting the physical offset
> > + */
> > + if (!has_cntpoff() && timer_get_offset(map->direct_ptimer))
> > + tpt = tpc = true;
>
> If there are only two possibilites, then two different booleans makes
> things more complicated than it has to be.
Each boolean denotes a different architectural state. They are
separate so that someone can:
- easily understand what is going on
- affect one without affecting the other when extending this code
The "common state" is what we had before, and it was a real pig to
reverse engineer *my own code*. Yes, this is job security, but I don't
think that's a good enough reason! ;-)
So I contend that two bools make things far simpler to reason about
these things.
>
> > + assign_clear_set_bit(tpt, CNTHCTL_EL1PCEN << 10, set, clr);
> > + assign_clear_set_bit(tpc, CNTHCTL_EL1PCTEN << 10, set, clr);
>
> Might be good to name the 10 something like VHE_SHIFT so people know why
> it is applied.
VHE_SHIFT really doesn't mean more that '10' because it doesn't tell
you *why* you have to do this.
The real way of solving that one is it move everything to the sysreg
generation *and* have a way to contextualise the sysreg generation
based on features and other controls (see the discussion about
FEAT_CCIDX as an example).
>
> > +
> > +
> > + timer_set_traps(vcpu, &map);
> > }
>
> > bool kvm_timer_should_notify_user(struct kvm_vcpu *vcpu)
> > @@ -1293,27 +1363,12 @@ int kvm_timer_enable(struct kvm_vcpu *vcpu)
> > }
>
> > /*
> > - * On VHE system, we only need to configure the EL2 timer trap
> > register once,
> > - * not for every world switch.
> > - * The host kernel runs at EL2 with HCR_EL2.TGE == 1,
> > - * and this makes those bits have no effect for the host kernel
> > execution.
> > + * If we have CNTPOFF, permanently set ECV to enable it.
> > */
> > void kvm_timer_init_vhe(void)
> > {
> > - /* When HCR_EL2.E2H ==1, EL1PCEN and EL1PCTEN are shifted by 10 */
> > - u32 cnthctl_shift = 10;
> > - u64 val;
> > -
> > - /*
> > - * VHE systems allow the guest direct access to the EL1 physical
> > - * timer/counter.
> > - */
> > - val = read_sysreg(cnthctl_el2);
> > - val |= (CNTHCTL_EL1PCEN << cnthctl_shift);
> > - val |= (CNTHCTL_EL1PCTEN << cnthctl_shift);
> > if (cpus_have_final_cap(ARM64_HAS_ECV_CNTPOFF))
> > - val |= CNTHCTL_ECV;
> > - write_sysreg(val, cnthctl_el2);
> > + sysreg_clear_set(cntkctl_el1, 0, CNTHCTL_ECV);
> > }
>
> What is the reason for moving these register writes from initialization
> to vcpu load time? This contradicts the comment that says this is only
> needed once and not at every world switch. Seems like doing more work
> for no reason.
You did notice that the comment got *removed*, so that there is no
contradiction?
You also understand that with a physical offset, and in the absence of
CNTPOFF, we cannot grant access to the physical counter/timer to the
guest?
Finally, given that we always have to write various bits of
CNTKCTL_EL1 for other reasons, moving this settings shouldn't result
in any extra work (specially considering that they don't require any
extra synchronisation).
Thanks,
M.
--
Without deviation from the norm, progress is not possible.
_______________________________________________
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-02-24 10:54 UTC|newest]
Thread overview: 110+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-02-16 14:21 [PATCH 00/16] KVM: arm64: Rework timer offsetting for fun and profit Marc Zyngier
2023-02-16 14:21 ` Marc Zyngier
2023-02-16 14:21 ` [PATCH 01/16] arm64: Add CNTPOFF_EL2 register definition Marc Zyngier
2023-02-16 14:21 ` Marc Zyngier
2023-02-16 14:21 ` [PATCH 02/16] arm64: Add HAS_ECV_CNTPOFF capability Marc Zyngier
2023-02-16 14:21 ` Marc Zyngier
2023-02-22 4:30 ` Reiji Watanabe
2023-02-22 4:30 ` Reiji Watanabe
2023-02-22 10:47 ` Marc Zyngier
2023-02-22 10:47 ` Marc Zyngier
2023-02-16 14:21 ` [PATCH 03/16] kvm: arm64: Expose {un,}lock_all_vcpus() to the reset of KVM Marc Zyngier
2023-02-16 14:21 ` Marc Zyngier
2023-02-23 22:30 ` Colton Lewis
2023-02-23 22:30 ` Colton Lewis
2023-02-16 14:21 ` [PATCH 04/16] KVM: arm64: timers: Use a per-vcpu, per-timer accumulator for fractional ns Marc Zyngier
2023-02-16 14:21 ` Marc Zyngier
2023-02-23 22:30 ` Colton Lewis
2023-02-23 22:30 ` Colton Lewis
2023-02-16 14:21 ` [PATCH 05/16] KVM: arm64: timers: Convert per-vcpu virtual offset to a global value Marc Zyngier
2023-02-16 14:21 ` Marc Zyngier
2023-02-22 6:15 ` Reiji Watanabe
2023-02-22 6:15 ` Reiji Watanabe
2023-02-22 10:54 ` Marc Zyngier
2023-02-22 10:54 ` Marc Zyngier
2023-02-16 14:21 ` [PATCH 06/16] KVM: arm64: timers: Use CNTPOFF_EL2 to offset the physical timer Marc Zyngier
2023-02-16 14:21 ` Marc Zyngier
2023-02-23 22:34 ` Colton Lewis
2023-02-23 22:34 ` Colton Lewis
2023-02-24 8:59 ` Marc Zyngier
2023-02-24 8:59 ` Marc Zyngier
2023-02-16 14:21 ` [PATCH 07/16] KVM: arm64: timers: Allow physical offset without CNTPOFF_EL2 Marc Zyngier
2023-02-16 14:21 ` Marc Zyngier
2023-02-23 22:40 ` Colton Lewis
2023-02-23 22:40 ` Colton Lewis
2023-02-24 10:54 ` Marc Zyngier [this message]
2023-02-24 10:54 ` Marc Zyngier
2023-02-16 14:21 ` [PATCH 08/16] KVM: arm64: timers: Allow userspace to set the counter offsets Marc Zyngier
2023-02-16 14:21 ` Marc Zyngier
2023-02-16 22:09 ` Oliver Upton
2023-02-16 22:09 ` Oliver Upton
2023-02-17 10:17 ` Marc Zyngier
2023-02-17 10:17 ` Marc Zyngier
2023-02-17 22:11 ` Oliver Upton
2023-02-17 22:11 ` Oliver Upton
2023-02-22 11:56 ` Marc Zyngier
2023-02-22 11:56 ` Marc Zyngier
2023-02-22 16:34 ` Oliver Upton
2023-02-22 16:34 ` Oliver Upton
2023-02-23 18:25 ` Marc Zyngier
2023-02-23 18:25 ` Marc Zyngier
2023-03-08 7:46 ` Oliver Upton
2023-03-08 7:46 ` Oliver Upton
2023-03-08 7:53 ` Oliver Upton
2023-03-08 7:53 ` Oliver Upton
2023-03-09 8:29 ` Marc Zyngier
2023-03-09 8:29 ` Marc Zyngier
2023-03-09 8:25 ` Marc Zyngier
2023-03-09 8:25 ` Marc Zyngier
2023-02-23 22:41 ` Colton Lewis
2023-02-23 22:41 ` Colton Lewis
2023-02-24 11:24 ` Marc Zyngier
2023-02-24 11:24 ` Marc Zyngier
2023-02-16 14:21 ` [PATCH 09/16] KVM: arm64: timers: Allow save/restoring of the physical timer Marc Zyngier
2023-02-16 14:21 ` Marc Zyngier
2023-02-16 14:21 ` [PATCH 10/16] KVM: arm64: timers: Rationalise per-vcpu timer init Marc Zyngier
2023-02-16 14:21 ` Marc Zyngier
2023-02-16 14:21 ` [PATCH 11/16] KVM: arm64: Document KVM_ARM_SET_CNT_OFFSETS and co Marc Zyngier
2023-02-16 14:21 ` Marc Zyngier
2023-02-16 14:21 ` [PATCH 12/16] KVM: arm64: nv: timers: Add a per-timer, per-vcpu offset Marc Zyngier
2023-02-16 14:21 ` Marc Zyngier
2023-02-24 20:07 ` Colton Lewis
2023-02-24 20:07 ` Colton Lewis
2023-02-25 10:32 ` Marc Zyngier
2023-02-25 10:32 ` Marc Zyngier
2023-02-16 14:21 ` [PATCH 13/16] KVM: arm64: nv: timers: Support hyp timer emulation Marc Zyngier
2023-02-16 14:21 ` Marc Zyngier
2023-02-24 20:08 ` Colton Lewis
2023-02-24 20:08 ` Colton Lewis
2023-02-25 10:34 ` Marc Zyngier
2023-02-25 10:34 ` Marc Zyngier
2023-02-16 14:21 ` [PATCH 14/16] KVM: arm64: selftests: Add physical timer registers to the sysreg list Marc Zyngier
2023-02-16 14:21 ` Marc Zyngier
2023-02-16 14:21 ` [PATCH 15/16] KVM: arm64: selftests: Augment existing timer test to handle variable offsets Marc Zyngier
2023-02-16 14:21 ` Marc Zyngier
2023-03-06 22:08 ` Colton Lewis
2023-03-06 22:08 ` Colton Lewis
2023-03-09 9:01 ` Marc Zyngier
2023-03-09 9:01 ` Marc Zyngier
2023-03-10 19:26 ` Colton Lewis
2023-03-10 19:26 ` Colton Lewis
2023-03-12 15:53 ` Marc Zyngier
2023-03-12 15:53 ` Marc Zyngier
2023-03-13 11:43 ` Marc Zyngier
2023-03-13 11:43 ` Marc Zyngier
2023-03-14 17:47 ` Colton Lewis
2023-03-14 17:47 ` Colton Lewis
2023-03-14 18:18 ` Marc Zyngier
2023-03-14 18:18 ` Marc Zyngier
2023-02-16 14:21 ` [PATCH 16/16] KVM: arm64: selftests: Deal with spurious timer interrupts Marc Zyngier
2023-02-16 14:21 ` Marc Zyngier
2023-02-21 16:28 ` [PATCH 00/16] KVM: arm64: Rework timer offsetting for fun and profit Veith, Simon
2023-02-21 16:28 ` Veith, Simon
2023-02-21 22:17 ` Marc Zyngier
2023-02-21 22:17 ` Marc Zyngier
2023-02-23 22:29 ` Colton Lewis
2023-02-23 22:29 ` Colton Lewis
2023-02-24 8:45 ` Marc Zyngier
2023-02-24 8:45 ` Marc Zyngier
2023-02-24 20:07 ` Colton Lewis
2023-02-24 20:07 ` Colton Lewis
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=86356vxrib.wl-maz@kernel.org \
--to=maz@kernel.org \
--cc=coltonlewis@google.com \
--cc=dwmw2@infradead.org \
--cc=james.morse@arm.com \
--cc=kvm@vger.kernel.org \
--cc=kvmarm@lists.linux.dev \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=oliver.upton@linux.dev \
--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 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.