ChanServ changed the topic of #armlinux to: ARM kernel talk [Upstream kernel, find your vendor forums for questions about their kernels] | https://libera.irclog.whitequark.org/armlinux
apritzel has quit [Ping timeout: 244 seconds]
robmur01 has quit [Ping timeout: 276 seconds]
jclsn has quit [Ping timeout: 272 seconds]
jclsn has joined #armlinux
nsaenz has joined #armlinux
nsaenz has quit [Ping timeout: 260 seconds]
_whitelogger has joined #armlinux
pikapika_lunar_a has joined #armlinux
pikapika_lunar has quit [Read error: Connection reset by peer]
System_Error has quit [Remote host closed the connection]
System_Error has joined #armlinux
monstr has joined #armlinux
mwalle has joined #armlinux
monstr has quit [Ping timeout: 252 seconds]
gclement has joined #armlinux
vingu has quit [Ping timeout: 265 seconds]
haritz has quit [Remote host closed the connection]
vingu has joined #armlinux
monstr has joined #armlinux
cbeznea_ has joined #armlinux
grahamn has joined #armlinux
headless has joined #armlinux
apritzel has joined #armlinux
nsaenz has joined #armlinux
monstr has quit [Ping timeout: 252 seconds]
apritzel has quit [Ping timeout: 260 seconds]
headless has quit [Quit: Konversation terminated!]
apritzel has joined #armlinux
<mrutland>
arnd: that's because on arm64 the ASID is in TTBR1, and we have to ensure that the old TTBR0 tables aren't ever live at the same time as the *new* ASID we're switching to. So we point TTBR0 at the (empty) reserved TTBR0 tables, then switch the ASID in TTBR1, then switch to the new TTB0 tables
<mrutland>
i.e. this is needed for any swtich, not only on rollover
<arnd>
mrutland: got it, thanks! Is there any reason for having the ASID in TTBR1 other than CONFIG_QCOM_FALKOR_ERRATUM_1003?
<mrutland>
arnd: it was moved there for KPTI; it's a bit painful to conditionally move it at runtime
<mrutland>
The QCOM erratum is just something we have to handle, and wasn't the reason for moving the ASID into TTB1
f_|DEPRECATED has quit [Remote host closed the connection]
bjoto has joined #armlinux
<arnd>
mrutland: ok, I think I understand how this works for KPTI now, not sure about the non-KPTI case yet. So the isb() would prevent fetching a TLB with the wrong ASID, but doesn't prevent an IRQ between the two write_sysreg(ttbr?, ...), and an interrupt handler might speculatively fetch from userspace, where the access gets prevented by PAN but the invalid TLB load does not?
apritzel has quit [Ping timeout: 248 seconds]
<mrutland>
arnd: Unusually for the archtiecture, writes to TTBR0 and TTBR1 are ordered w.r.t. one another without an ISB; see commit b9293d457ff3de415fa07d7e35978bceb29c3827
<mrutland>
... so the trailing SB is just to ensure the final state has taken effect
<mrutland>
* the trailing ISB, not SB
<mrutland>
Interrupts are masked over calls to cpu_do_switch_mm() by virtue of callers having IRQs masked, and we rely on that to avoid a bunch of races
<mrutland>
(I'm a bit worried about that last point; double-checking that's really true now, or we have other problems regardless of TTBR writes)
<mrutland>
Ugh, we probably need CONFIG_ARCH_WANT_IRQS_OFF_ACTIVATE_MM, and I need to dig into that more
<mrutland>
If we taken an IRQ mid-sequence which *doesn't* preempt and doesn't perform an explicit uaccess, there won't be a problem, the reserved TTBR value just prevents allocating new TLB entries for the TTBR0 range. Speculation can't do anything harmful in that state; if it could, that would be possible even without an IRQ.
<arnd>
I'm still struggling to understand what could go wrong without an irq if the reserved ttbr0 wasn't set first: why isn't the isb sufficient to prevent allocating a TLB with the wrong ASID/ttb pair?
<mrutland>
arnd: ISB where?
<mrutland>
arnd: asynchronous translation table walks, as a result of prefetching or speculation, could occur *before* the trailing ISB
<mrutland>
arnd: basically, the same problem as you were asking about for IRQs, but no IRQ needed
<mrutland>
The CPU can jsut do that at any time, for any reason at all
<mrutland>
From a quick test, core code calls switch_mm() with IRQs enabled, so we have a bigger bug there that needs to be fixed
sszy has joined #armlinux
<mrutland>
I'm just going to grab lunch, then I'll take another look
<arnd>
in the object code, I see that the three isntructions are always consecutive: "msr ttbr1_el1, x2; msr ttbr0_el1, x0; isb". My understanding was that any instruction from before the ttbr1_el1 store would be guaranteed to still use the old ttbr* value, even for prefetching. Any instruction after the isb would only prefetch use both the new ttbr0 and ttbr1 values because of the isb
<arnd>
between the ttbr1_el1 access and the isb, I would expect no TLB fetch to happen because there are no load/store or even branch instructions that could be speculatively executed. What am I missing?
apritzel has joined #armlinux
grahamn has quit [Ping timeout: 265 seconds]
apritzel has quit [Ping timeout: 276 seconds]
<mrutland>
Your understanding is incorrect: the CPU is allowed to start using the new TTBR value immediately upon it being written, but is only guaranteed to be using the new value consistently after a subsequent ISB.
<mrutland>
between the write and the ISB, it could speculate/prefetch using either the old or new values (and e.g. could go old->new->old), but has to use a consistent snapshot
<mrutland>
TLB lookups and translation table walks can happen *at any time* and *for any reason* (e.g. the CPU might start prefetching a VA range or start prewalking the translation tables), and that's not limited by the specific instruction stream
<mrutland>
The writes are ordered to avoid performing translation table walks or TLB allocation with an *inconsistent* snapshot of ASID + BADDR
<mrutland>
*the TTBR writes are ordered the way they are
<mrutland>
arnd: ^ does that make sense to you now?
apritzel has joined #armlinux
<arnd>
mrutland: yes, the example of immediately prefilling the TLB on TTBR update makes snese, and I guess if it traps to EL2 or EL3, before the isb, it's easy to construct more cases that actually fill the TLB the same way
<mrutland>
Cool!
System_Error has quit [Remote host closed the connection]
sakman has joined #armlinux
headless has joined #armlinux
System_Error has joined #armlinux
grahamn has joined #armlinux
haritz has joined #armlinux
haritz has joined #armlinux
haritz has quit [Changing host]
apritzel has quit [Ping timeout: 272 seconds]
gclement has quit [Quit: Leaving.]
headless has quit [Quit: Konversation terminated!]
jfsimon1981a has quit [Remote host closed the connection]
jfsimon1981a has joined #armlinux
mingdao has joined #armlinux
jfsimon1981a has quit [Remote host closed the connection]
jfsimon1981a has joined #armlinux
jfsimon1981a has quit [Remote host closed the connection]