From: oss@buserror.net (Scott Wood)
To: linux-arm-kernel@lists.infradead.org
Subject: [RFC PATCH 1/2] ARM/ARM64: arch_timer: Work around QorIQ Erratum A-008585
Date: Tue, 12 Apr 2016 00:48:48 -0500 [thread overview]
Message-ID: <1460440128.32510.106.camel@buserror.net> (raw)
In-Reply-To: <570B73CF.6070502@arm.com>
On Mon, 2016-04-11 at 10:52 +0100, Marc Zyngier wrote:
> Hi Scott,
>
> On 11/04/16 03:22, Scott Wood wrote:
> > +static __always_inline
> > +u32 arch_timer_reg_read_cp15(int access, enum arch_timer_reg reg)
> > +{
> > + if (arm_arch_timer_reread && reg == ARCH_TIMER_REG_TVAL)
> > + return arch_timer_reg_tval_reread(access, reg);
>
> I'm really not keen on this. Please implement this workaround as a
> static_key, and branch to the workaround in the slow path.
OK, I'll look into that.
> > -static inline u64 arch_counter_get_cntpct(void)
> > +static __always_inline u64 arch_counter_get_cnt(int opcode, bool reread)
>
> Why the __always_inline? The compiler should already do the right thing.
The "i" asm constraint requires that it be inline. Maybe GCC is likely to
inline it anyway, but it's better to be explicit when it's required for
correctness.
> > - u64 cval;
> > + u64 val, val_new;
> > + int timeout = 200;
> >
> > isb();
> > - asm volatile("mrrc p15, 0, %Q0, %R0, c14" : "=r" (cval));
> > - return cval;
> > +
> > + if (reread) {
> > + do {
> > + asm volatile("mrrc p15, %2, %Q0, %R0, c14;"
> > + "mrrc p15, %2, %Q1, %R1, c14"
> > + : "=r" (val), "=r" (val_new)
> > + : "i" (opcode));
> > + timeout--;
> > + } while (val != val_new && timeout);
> > +
> > + BUG_ON(!timeout);
>
> BUG_ON()? Really? Is there any condition where you wouldn't be able to
> converge to a single value?
This function is used from the vdso, and thus WARN causes a link error.
> > + /*
> > + * Erratum A-008585 requires back-to-back reads to be identical
> > + * in order to avoid glitches.
> > + */
> > + cmp w17, #0
> > + b.eq 2f
> > +1: mrs x15, cntvct_el0
> > + mrs x16, cntvct_el0
> > + cmp x16, x15
> > + b.ne 1b
> > +2:
>
> Could userspace lock-up here? If it can, you need to be able to bail
> out. If not, then your BUG_ON() sprinkling is bogus.
It *shouldn't* be possible for these loops to time out -- it would not be a
viable workaround if it's not guaranteed to resolve quickly -- but if there
are situations where the workaround fails (e.g. unusual clock speeds) it would
be useful to get that diagnostic rather than have to hunt down a hang. I can
remove them if you want, though.
As for the VDSO, it seems quite unlikely that failures would be seen only in
userspace and not in the kernel, so the utility of adding a timeout here was
less, especially relative to the hassle. Will Deacon asked that we leave the
VDSO alone and set use_syscall instead, though, so adding a timeout here is
moot.
> > /* Calculate cycle delta and convert to ns. */
> > sub x10, x15, x10
> > diff --git a/drivers/clocksource/arm_arch_timer.c
> > b/drivers/clocksource/arm_arch_timer.c
> > index 5152b38..5ed7c7f 100644
> > --- a/drivers/clocksource/arm_arch_timer.c
> > +++ b/drivers/clocksource/arm_arch_timer.c
> > @@ -79,6 +79,9 @@ static enum ppi_nr arch_timer_uses_ppi = VIRT_PPI;
> > static bool arch_timer_c3stop;
> > static bool arch_timer_mem_use_virtual;
> >
> > +bool arm_arch_timer_reread; /* QorIQ erratum A-008585 */
> > +EXPORT_SYMBOL(arm_arch_timer_reread);
> > +
> > /*
> > * Architected system timer support.
> > */
> > @@ -762,6 +765,8 @@ static void __init arch_timer_of_init(struct
> > device_node *np)
> > arch_timer_detect_rate(NULL, np);
> >
> > arch_timer_c3stop = !of_property_read_bool(np, "always-on");
> > + arm_arch_timer_reread =
> > + of_property_read_bool(np, "fsl,erratum-a008585");
> >
> > /*
> > * If we cannot rely on firmware initializing the timer registers
> > then
> >
>
> The elephant in the room is KVM. I'm pretty sure it suffers from the
> same erratum, yet you did not handle it at all. I'd expect to see
> something in an upcoming version of the patch.
cval isn't listed in the erratum description as being affected. I looked
around a bit and couldn't find the KVM code directly accessing tval or count.
Am I missing something?
-Scott
next prev parent reply other threads:[~2016-04-12 5:48 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-04-11 2:22 [RFC PATCH 0/2] ARM/ARM64: arch_timer: QorIQ errata Scott Wood
2016-04-11 2:22 ` [RFC PATCH 1/2] ARM/ARM64: arch_timer: Work around QorIQ Erratum A-008585 Scott Wood
2016-04-11 9:19 ` Will Deacon
2016-04-11 9:52 ` Marc Zyngier
2016-04-12 5:48 ` Scott Wood [this message]
2016-04-12 9:07 ` Marc Zyngier
2016-04-13 5:41 ` Scott Wood
2016-04-13 7:36 ` Marc Zyngier
2016-04-13 13:22 ` Rob Herring
2016-04-17 0:58 ` Scott Wood
2016-04-11 2:22 ` [RFC PATCH 2/2] ARM64: arch_timer: Work around QorIQ Erratum A-009971 Scott Wood
2016-04-11 9:55 ` Marc Zyngier
2016-04-12 5:54 ` Scott Wood
2016-04-12 8:22 ` Marc Zyngier
2016-04-17 1:32 ` Scott Wood
2016-04-18 9:28 ` 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=1460440128.32510.106.camel@buserror.net \
--to=oss@buserror.net \
--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.