Merge patch series "RISC-V: Test th.sxstatus.MAEE bit before enabling MAEE"
authorPalmer Dabbelt <palmer@rivosinc.com>
Thu, 25 Apr 2024 17:22:36 +0000 (10:22 -0700)
committerPalmer Dabbelt <palmer@rivosinc.com>
Fri, 26 Apr 2024 17:21:57 +0000 (10:21 -0700)
Christoph Müllner <christoph.muellner@vrull.eu> says:

Currently, the Linux kernel suffers from a boot regression when running
on the c906 QEMU emulation. Details have been reported here by Björn Töpel:
  https://lists.gnu.org/archive/html/qemu-devel/2024-01/msg04766.html

The main issue is, that Linux enables XTheadMae for CPUs that have a T-Head
mvendorid but QEMU maintainers don't want to emulate a CPU that uses
reserved bits in PTEs. See also the following discussion for more
context:
  https://lists.gnu.org/archive/html/qemu-devel/2024-02/msg00775.html

This series renames "T-Head PBMT" to "MAE"/"XTheadMae" and only enables
it if the th.sxstatus.MAEE bit is set.

The th.sxstatus CSR is documented here:
  https://github.com/T-head-Semi/thead-extension-spec/blob/master/xtheadsxstatus.adoc

XTheadMae is documented here:
  https://github.com/T-head-Semi/thead-extension-spec/blob/master/xtheadmae.adoc

The QEMU patch to emulate th.sxstatus with the MAEE bit not set is here:
  https://lore.kernel.org/all/20240329120427.684677-1-christoph.muellner@vrull.eu/

After applying the referenced QEMU patch, this patchset allows to
successfully boot a C906 QEMU system emulation ("-cpu thead-c906").

* b4-shazam-lts:
  riscv: T-Head: Test availability bit before enabling MAE errata
  riscv: thead: Rename T-Head PBMT to MAE

Link: https://lore.kernel.org/r/20240407213236.2121592-1-christoph.muellner@vrull.eu
Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
arch/riscv/Kconfig.errata
arch/riscv/errata/thead/errata.c
arch/riscv/include/asm/errata_list.h

index 910ba8837add866f622fba84f7c0c3535ee175e6..2acc7d876e1fb6aa5dc14ad3c3150f587ba1edea 100644 (file)
@@ -82,14 +82,14 @@ config ERRATA_THEAD
 
          Otherwise, please say "N" here to avoid unnecessary overhead.
 
-config ERRATA_THEAD_PBMT
-       bool "Apply T-Head memory type errata"
+config ERRATA_THEAD_MAE
+       bool "Apply T-Head's memory attribute extension (XTheadMae) errata"
        depends on ERRATA_THEAD && 64BIT && MMU
        select RISCV_ALTERNATIVE_EARLY
        default y
        help
-         This will apply the memory type errata to handle the non-standard
-         memory type bits in page-table-entries on T-Head SoCs.
+         This will apply the memory attribute extension errata to handle the
+         non-standard PTE utilization on T-Head SoCs (XTheadMae).
 
          If you don't know what to do here, say "Y".
 
index b1c410bbc1aece3c1fe0bea8cbd68271c8c0e29a..bf6a0a6318ee307085c3cc04c4056a0b63a000e9 100644 (file)
 #include <asm/patch.h>
 #include <asm/vendorid_list.h>
 
-static bool errata_probe_pbmt(unsigned int stage,
-                             unsigned long arch_id, unsigned long impid)
+#define CSR_TH_SXSTATUS                0x5c0
+#define SXSTATUS_MAEE          _AC(0x200000, UL)
+
+static bool errata_probe_mae(unsigned int stage,
+                            unsigned long arch_id, unsigned long impid)
 {
-       if (!IS_ENABLED(CONFIG_ERRATA_THEAD_PBMT))
+       if (!IS_ENABLED(CONFIG_ERRATA_THEAD_MAE))
                return false;
 
        if (arch_id != 0 || impid != 0)
                return false;
 
-       if (stage == RISCV_ALTERNATIVES_EARLY_BOOT ||
-           stage == RISCV_ALTERNATIVES_MODULE)
-               return true;
+       if (stage != RISCV_ALTERNATIVES_EARLY_BOOT &&
+           stage != RISCV_ALTERNATIVES_MODULE)
+               return false;
+
+       if (!(csr_read(CSR_TH_SXSTATUS) & SXSTATUS_MAEE))
+               return false;
 
-       return false;
+       return true;
 }
 
 /*
@@ -140,8 +146,8 @@ static u32 thead_errata_probe(unsigned int stage,
 {
        u32 cpu_req_errata = 0;
 
-       if (errata_probe_pbmt(stage, archid, impid))
-               cpu_req_errata |= BIT(ERRATA_THEAD_PBMT);
+       if (errata_probe_mae(stage, archid, impid))
+               cpu_req_errata |= BIT(ERRATA_THEAD_MAE);
 
        errata_probe_cmo(stage, archid, impid);
 
index 1f2dbfb8a8bfc8c9f5d46b9129c26756941c4918..efd851e1b48321e1f098008ce8fe7755ab49339d 100644 (file)
@@ -23,7 +23,7 @@
 #endif
 
 #ifdef CONFIG_ERRATA_THEAD
-#define        ERRATA_THEAD_PBMT 0
+#define        ERRATA_THEAD_MAE 0
 #define        ERRATA_THEAD_PMU 1
 #define        ERRATA_THEAD_NUMBER 2
 #endif
@@ -53,20 +53,20 @@ asm(ALTERNATIVE("sfence.vma %0", "sfence.vma", SIFIVE_VENDOR_ID,    \
  * in the default case.
  */
 #define ALT_SVPBMT_SHIFT 61
-#define ALT_THEAD_PBMT_SHIFT 59
+#define ALT_THEAD_MAE_SHIFT 59
 #define ALT_SVPBMT(_val, prot)                                         \
 asm(ALTERNATIVE_2("li %0, 0\t\nnop",                                   \
                  "li %0, %1\t\nslli %0,%0,%3", 0,                      \
                        RISCV_ISA_EXT_SVPBMT, CONFIG_RISCV_ISA_SVPBMT,  \
                  "li %0, %2\t\nslli %0,%0,%4", THEAD_VENDOR_ID,        \
-                       ERRATA_THEAD_PBMT, CONFIG_ERRATA_THEAD_PBMT)    \
+                       ERRATA_THEAD_MAE, CONFIG_ERRATA_THEAD_MAE)      \
                : "=r"(_val)                                            \
                : "I"(prot##_SVPBMT >> ALT_SVPBMT_SHIFT),               \
-                 "I"(prot##_THEAD >> ALT_THEAD_PBMT_SHIFT),            \
+                 "I"(prot##_THEAD >> ALT_THEAD_MAE_SHIFT),             \
                  "I"(ALT_SVPBMT_SHIFT),                                \
-                 "I"(ALT_THEAD_PBMT_SHIFT))
+                 "I"(ALT_THEAD_MAE_SHIFT))
 
-#ifdef CONFIG_ERRATA_THEAD_PBMT
+#ifdef CONFIG_ERRATA_THEAD_MAE
 /*
  * IO/NOCACHE memory types are handled together with svpbmt,
  * so on T-Head chips, check if no other memory type is set,
@@ -83,11 +83,11 @@ asm volatile(ALTERNATIVE(                                           \
        "slli    t3, t3, %3\n\t"                                        \
        "or      %0, %0, t3\n\t"                                        \
        "2:",  THEAD_VENDOR_ID,                                         \
-               ERRATA_THEAD_PBMT, CONFIG_ERRATA_THEAD_PBMT)            \
+               ERRATA_THEAD_MAE, CONFIG_ERRATA_THEAD_MAE)              \
        : "+r"(_val)                                                    \
-       : "I"(_PAGE_MTMASK_THEAD >> ALT_THEAD_PBMT_SHIFT),              \
-         "I"(_PAGE_PMA_THEAD >> ALT_THEAD_PBMT_SHIFT),                 \
-         "I"(ALT_THEAD_PBMT_SHIFT)                                     \
+       : "I"(_PAGE_MTMASK_THEAD >> ALT_THEAD_MAE_SHIFT),               \
+         "I"(_PAGE_PMA_THEAD >> ALT_THEAD_MAE_SHIFT),                  \
+         "I"(ALT_THEAD_MAE_SHIFT)                                      \
        : "t3")
 #else
 #define ALT_THEAD_PMA(_val)