For VPIPT I-caches, we need I-cache maintenance on VMID rollover to
avoid an ABA problem. Consider a single vCPU VM, with a pinned stage-2,
running with an idmap VA->IPA and idmap IPA->PA. If we don't do
maintenance on rollover:
        // VMID A
        Writes insn X to PA 0xF
        Invalidates PA 0xF (for VMID A)
        I$ contains [{A,F}->X]
        [VMID ROLLOVER]
        // VMID B
        Writes insn Y to PA 0xF
        Invalidates PA 0xF (for VMID B)
        I$ contains [{A,F}->X, {B,F}->Y]
        [VMID ROLLOVER]
        // VMID A
        I$ contains [{A,F}->X, {B,F}->Y]
        Unexpectedly hits stale I$ line {A,F}->X.
However, for PIPT and VIPT I-caches, the VMID doesn't affect lookup or
constrain maintenance. Given the VMID doesn't affect PIPT and VIPT
I-caches, and given VMID rollover is independent of changes to stage-2
mappings, I-cache maintenance cannot be necessary on VMID rollover for
PIPT or VIPT I-caches.
This patch removes the maintenance on rollover for VIPT and PIPT
I-caches. At the same time, the unnecessary colons are removed from the
asm statement to make it more legible.
Signed-off-by: Mark Rutland <mark.rutland@arm.com>
Cc: Christoffer Dall <christoffer.dall@arm.com>
Reviewed-by: James Morse <james.morse@arm.com>
Cc: Julien Thierry <julien.thierry.kdev@gmail.com>
Cc: Suzuki K Poulose <suzuki.poulose@arm.com>
Cc: kvmarm@lists.cs.columbia.edu
Signed-off-by: Marc Zyngier <maz@kernel.org>
 {
        dsb(ishst);
        __tlbi(alle1is);
-       asm volatile("ic ialluis" : : );
+
+       /*
+        * VIPT and PIPT caches are not affected by VMID, so no maintenance
+        * is necessary across a VMID rollover.
+        *
+        * VPIPT caches constrain lookup and maintenance to the active VMID,
+        * so we need to invalidate lines with a stale VMID to avoid an ABA
+        * race after multiple rollovers.
+        *
+        */
+       if (icache_is_vpipt())
+               asm volatile("ic ialluis");
+
        dsb(ish);
 }