Merge branch 'kvm-arm64/erratum-1319367' of git://git.kernel.org/pub/scm/linux/kernel...
authorCatalin Marinas <catalin.marinas@arm.com>
Mon, 28 Oct 2019 16:22:49 +0000 (16:22 +0000)
committerCatalin Marinas <catalin.marinas@arm.com>
Mon, 28 Oct 2019 16:22:49 +0000 (16:22 +0000)
Similarly to erratum 1165522 that affects Cortex-A76, A57 and A72
respectively suffer from errata 1319537 and 1319367, potentially
resulting in TLB corruption if the CPU speculates an AT instruction
while switching guests.

The fix is slightly more involved since we don't have VHE to help us
here, but the idea is the same: when switching a guest in, we must
prevent any speculated AT from being able to parse the page tables
until S2 is up and running. Only at this stage can we allow AT to take
place.

For this, we always restore the guest sysregs first, except for its
SCTLR and TCR registers, which must be set with SCTLR.M=1 and
TCR.EPD{0,1} = {1, 1}, effectively disabling the PTW and TLB
allocation. Once S2 is setup, we restore the guest's SCTLR and
TCR. Similar things must be done on TLB invalidation...

* 'kvm-arm64/erratum-1319367' of git://git.kernel.org/pub/scm/linux/kernel/git/maz/arm-platforms:
  arm64: Enable and document ARM errata 1319367 and 1319537
  arm64: KVM: Prevent speculative S1 PTW when restoring vcpu context
  arm64: KVM: Disable EL1 PTW when invalidating S2 TLBs
  arm64: KVM: Reorder system register restoration and stage-2 activation
  arm64: Add ARM64_WORKAROUND_1319367 for all A57 and A72 versions

1  2 
Documentation/arm64/silicon-errata.rst
arch/arm64/Kconfig
arch/arm64/include/asm/cpucaps.h
arch/arm64/kernel/cpu_errata.c
arch/arm64/kvm/hyp/switch.c

Simple merge
  #define ARM64_HAS_IRQ_PRIO_MASKING            42
  #define ARM64_HAS_DCPODP                      43
  #define ARM64_WORKAROUND_1463225              44
 -#define ARM64_WORKAROUND_1319367              45
 +#define ARM64_WORKAROUND_CAVIUM_TX2_219_TVM   45
 +#define ARM64_WORKAROUND_CAVIUM_TX2_219_PRFM  46
 +#define ARM64_WORKAROUND_1542419              47
++#define ARM64_WORKAROUND_1319367              48
  
- #define ARM64_NCAPS                           48
 -#define ARM64_NCAPS                           46
++#define ARM64_NCAPS                           49
  
  #endif /* __ASM_CPUCAPS_H */
@@@ -632,45 -623,9 +632,45 @@@ check_branch_predictor(const struct arm
        return (need_wa > 0);
  }
  
- #ifdef CONFIG_HARDEN_EL2_VECTORS
 +static const __maybe_unused struct midr_range tx2_family_cpus[] = {
 +      MIDR_ALL_VERSIONS(MIDR_BRCM_VULCAN),
 +      MIDR_ALL_VERSIONS(MIDR_CAVIUM_THUNDERX2),
 +      {},
 +};
 +
 +static bool __maybe_unused
 +needs_tx2_tvm_workaround(const struct arm64_cpu_capabilities *entry,
 +                       int scope)
 +{
 +      int i;
 +
 +      if (!is_affected_midr_range_list(entry, scope) ||
 +          !is_hyp_mode_available())
 +              return false;
 +
 +      for_each_possible_cpu(i) {
 +              if (MPIDR_AFFINITY_LEVEL(cpu_logical_map(i), 0) != 0)
 +                      return true;
 +      }
 +
 +      return false;
 +}
 +
 +static bool __maybe_unused
 +has_neoverse_n1_erratum_1542419(const struct arm64_cpu_capabilities *entry,
 +                              int scope)
 +{
 +      u32 midr = read_cpuid_id();
 +      bool has_dic = read_cpuid_cachetype() & BIT(CTR_DIC_SHIFT);
 +      const struct midr_range range = MIDR_ALL_VERSIONS(MIDR_NEOVERSE_N1);
 +
 +      WARN_ON(scope != SCOPE_LOCAL_CPU || preemptible());
 +      return is_midr_in_range(midr, &range) && has_dic;
 +}
 +
+ #if defined(CONFIG_HARDEN_EL2_VECTORS) || defined(CONFIG_ARM64_ERRATUM_1319367)
  
- static const struct midr_range arm64_harden_el2_vectors[] = {
+ static const struct midr_range ca57_a72[] = {
        MIDR_ALL_VERSIONS(MIDR_CORTEX_A57),
        MIDR_ALL_VERSIONS(MIDR_CORTEX_A72),
        {},
@@@ -897,29 -852,13 +897,36 @@@ const struct arm64_cpu_capabilities arm
                .matches = has_cortex_a76_erratum_1463225,
        },
  #endif
 +#ifdef CONFIG_CAVIUM_TX2_ERRATUM_219
 +      {
 +              .desc = "Cavium ThunderX2 erratum 219 (KVM guest sysreg trapping)",
 +              .capability = ARM64_WORKAROUND_CAVIUM_TX2_219_TVM,
 +              ERRATA_MIDR_RANGE_LIST(tx2_family_cpus),
 +              .matches = needs_tx2_tvm_workaround,
 +      },
 +      {
 +              .desc = "Cavium ThunderX2 erratum 219 (PRFM removal)",
 +              .capability = ARM64_WORKAROUND_CAVIUM_TX2_219_PRFM,
 +              ERRATA_MIDR_RANGE_LIST(tx2_family_cpus),
 +      },
 +#endif
 +#ifdef CONFIG_ARM64_ERRATUM_1542419
 +      {
 +              /* we depend on the firmware portion for correctness */
 +              .desc = "ARM erratum 1542419 (kernel portion)",
 +              .capability = ARM64_WORKAROUND_1542419,
 +              .type = ARM64_CPUCAP_LOCAL_CPU_ERRATUM,
 +              .matches = has_neoverse_n1_erratum_1542419,
 +              .cpu_enable = cpu_enable_trap_ctr_access,
 +      },
 +#endif
+ #ifdef CONFIG_ARM64_ERRATUM_1319367
+       {
+               .desc = "ARM erratum 1319367",
+               .capability = ARM64_WORKAROUND_1319367,
+               ERRATA_MIDR_RANGE_LIST(ca57_a72),
+       },
+ #endif
        {
        }
  };
Simple merge