Merge tag 'riscv-for-linus-6.6-mw1' of git://git.kernel.org/pub/scm/linux/kernel...
authorLinus Torvalds <torvalds@linux-foundation.org>
Fri, 1 Sep 2023 15:09:48 +0000 (08:09 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 1 Sep 2023 15:09:48 +0000 (08:09 -0700)
Pull RISC-V updates from Palmer Dabbelt:

 - Support for the new "riscv,isa-extensions" and "riscv,isa-base"
   device tree interfaces for probing extensions

 - Support for userspace access to the performance counters

 - Support for more instructions in kprobes

 - Crash kernels can be allocated above 4GiB

 - Support for KCFI

 - Support for ELFs in !MMU configurations

 - ARCH_KMALLOC_MINALIGN has been reduced to 8

 - mmap() defaults to sv48-sized addresses, with longer addresses hidden
   behind a hint (similar to Arm and Intel)

 - Also various fixes and cleanups

* tag 'riscv-for-linus-6.6-mw1' of git://git.kernel.org/pub/scm/linux/kernel/git/riscv/linux: (51 commits)
  lib/Kconfig.debug: Restrict DEBUG_INFO_SPLIT for RISC-V
  riscv: support PREEMPT_DYNAMIC with static keys
  riscv: Move create_tmp_mapping() to init sections
  riscv: Mark KASAN tmp* page tables variables as static
  riscv: mm: use bitmap_zero() API
  riscv: enable DEBUG_FORCE_FUNCTION_ALIGN_64B
  riscv: remove redundant mv instructions
  RISC-V: mm: Document mmap changes
  RISC-V: mm: Update pgtable comment documentation
  RISC-V: mm: Add tests for RISC-V mm
  RISC-V: mm: Restrict address space for sv39,sv48,sv57
  riscv: enable DMA_BOUNCE_UNALIGNED_KMALLOC for !dma_coherent
  riscv: allow kmalloc() caches aligned to the smallest value
  riscv: support the elf-fdpic binfmt loader
  binfmt_elf_fdpic: support 64-bit systems
  riscv: Allow CONFIG_CFI_CLANG to be selected
  riscv/purgatory: Disable CFI
  riscv: Add CFI error handling
  riscv: Add ftrace_stub_graph
  riscv: Add types to indirectly called assembly functions
  ...

15 files changed:
1  2 
Documentation/admin-guide/kernel-parameters.txt
arch/riscv/Kconfig
arch/riscv/include/asm/cacheflush.h
arch/riscv/include/asm/insn.h
arch/riscv/include/asm/pgtable.h
arch/riscv/include/uapi/asm/ptrace.h
arch/riscv/kernel/cpu.c
arch/riscv/kernel/cpufeature.c
arch/riscv/kernel/traps.c
arch/riscv/mm/init.c
arch/riscv/mm/kasan_init.c
drivers/perf/riscv_pmu.c
include/linux/perf_event.h
lib/Kconfig.debug
tools/testing/selftests/riscv/Makefile

Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
index 3cc99e928744cd65b52febee98fa29cc982aad20,71fb840ee2469de8bc4446f43cbf7197983670b8..ef7b4fd9e87688f42a62345ba66b8ef0a2b61500
@@@ -152,170 -376,15 +375,8 @@@ static void __init riscv_fill_hwcap_fro
                        }
                }
  
-               /*
-                * For all possible cpus, we have already validated in
-                * the boot process that they at least contain "rv" and
-                * whichever of "32"/"64" this kernel supports, and so this
-                * section can be skipped.
-                */
-               isa += 4;
-               while (*isa) {
-                       const char *ext = isa++;
-                       const char *ext_end = isa;
-                       bool ext_long = false, ext_err = false;
-                       switch (*ext) {
-                       case 's':
-                               /*
-                                * Workaround for invalid single-letter 's' & 'u'(QEMU).
-                                * No need to set the bit in riscv_isa as 's' & 'u' are
-                                * not valid ISA extensions. It works until multi-letter
-                                * extension starting with "Su" appears.
-                                */
-                               if (ext[-1] != '_' && ext[1] == 'u') {
-                                       ++isa;
-                                       ext_err = true;
-                                       break;
-                               }
-                               fallthrough;
-                       case 'S':
-                       case 'x':
-                       case 'X':
-                       case 'z':
-                       case 'Z':
-                               /*
-                                * Before attempting to parse the extension itself, we find its end.
-                                * As multi-letter extensions must be split from other multi-letter
-                                * extensions with an "_", the end of a multi-letter extension will
-                                * either be the null character or the "_" at the start of the next
-                                * multi-letter extension.
-                                *
-                                * Next, as the extensions version is currently ignored, we
-                                * eliminate that portion. This is done by parsing backwards from
-                                * the end of the extension, removing any numbers. This may be a
-                                * major or minor number however, so the process is repeated if a
-                                * minor number was found.
-                                *
-                                * ext_end is intended to represent the first character *after* the
-                                * name portion of an extension, but will be decremented to the last
-                                * character itself while eliminating the extensions version number.
-                                * A simple re-increment solves this problem.
-                                */
-                               ext_long = true;
-                               for (; *isa && *isa != '_'; ++isa)
-                                       if (unlikely(!isalnum(*isa)))
-                                               ext_err = true;
-                               ext_end = isa;
-                               if (unlikely(ext_err))
-                                       break;
-                               if (!isdigit(ext_end[-1]))
-                                       break;
-                               while (isdigit(*--ext_end))
-                                       ;
-                               if (tolower(ext_end[0]) != 'p' || !isdigit(ext_end[-1])) {
-                                       ++ext_end;
-                                       break;
-                               }
-                               while (isdigit(*--ext_end))
-                                       ;
-                               ++ext_end;
-                               break;
-                       default:
-                               /*
-                                * Things are a little easier for single-letter extensions, as they
-                                * are parsed forwards.
-                                *
-                                * After checking that our starting position is valid, we need to
-                                * ensure that, when isa was incremented at the start of the loop,
-                                * that it arrived at the start of the next extension.
-                                *
-                                * If we are already on a non-digit, there is nothing to do. Either
-                                * we have a multi-letter extension's _, or the start of an
-                                * extension.
-                                *
-                                * Otherwise we have found the current extension's major version
-                                * number. Parse past it, and a subsequent p/minor version number
-                                * if present. The `p` extension must not appear immediately after
-                                * a number, so there is no fear of missing it.
-                                *
-                                */
-                               if (unlikely(!isalpha(*ext))) {
-                                       ext_err = true;
-                                       break;
-                               }
-                               if (!isdigit(*isa))
-                                       break;
-                               while (isdigit(*++isa))
-                                       ;
-                               if (tolower(*isa) != 'p')
-                                       break;
-                               if (!isdigit(*++isa)) {
-                                       --isa;
-                                       break;
-                               }
-                               while (isdigit(*++isa))
-                                       ;
-                               break;
-                       }
-                       /*
-                        * The parser expects that at the start of an iteration isa points to the
-                        * first character of the next extension. As we stop parsing an extension
-                        * on meeting a non-alphanumeric character, an extra increment is needed
-                        * where the succeeding extension is a multi-letter prefixed with an "_".
-                        */
-                       if (*isa == '_')
-                               ++isa;
- #define SET_ISA_EXT_MAP(name, bit)                                                    \
-                       do {                                                            \
-                               if ((ext_end - ext == sizeof(name) - 1) &&              \
-                                    !strncasecmp(ext, name, sizeof(name) - 1) &&       \
-                                    riscv_isa_extension_check(bit))                    \
-                                       set_bit(bit, isainfo->isa);                     \
-                       } while (false)                                                 \
-                       if (unlikely(ext_err))
-                               continue;
-                       if (!ext_long) {
-                               int nr = tolower(*ext) - 'a';
-                               if (riscv_isa_extension_check(nr)) {
-                                       this_hwcap |= isa2hwcap[nr];
-                                       set_bit(nr, isainfo->isa);
-                               }
-                       } else {
-                               /* sorted alphabetically */
-                               SET_ISA_EXT_MAP("smaia", RISCV_ISA_EXT_SMAIA);
-                               SET_ISA_EXT_MAP("ssaia", RISCV_ISA_EXT_SSAIA);
-                               SET_ISA_EXT_MAP("sscofpmf", RISCV_ISA_EXT_SSCOFPMF);
-                               SET_ISA_EXT_MAP("sstc", RISCV_ISA_EXT_SSTC);
-                               SET_ISA_EXT_MAP("svinval", RISCV_ISA_EXT_SVINVAL);
-                               SET_ISA_EXT_MAP("svnapot", RISCV_ISA_EXT_SVNAPOT);
-                               SET_ISA_EXT_MAP("svpbmt", RISCV_ISA_EXT_SVPBMT);
-                               SET_ISA_EXT_MAP("zba", RISCV_ISA_EXT_ZBA);
-                               SET_ISA_EXT_MAP("zbb", RISCV_ISA_EXT_ZBB);
-                               SET_ISA_EXT_MAP("zbs", RISCV_ISA_EXT_ZBS);
-                               SET_ISA_EXT_MAP("zicbom", RISCV_ISA_EXT_ZICBOM);
-                               SET_ISA_EXT_MAP("zicboz", RISCV_ISA_EXT_ZICBOZ);
-                               SET_ISA_EXT_MAP("zihintpause", RISCV_ISA_EXT_ZIHINTPAUSE);
-                       }
- #undef SET_ISA_EXT_MAP
-               }
+               riscv_parse_isa_string(&this_hwcap, isainfo, isa2hwcap, isa);
  
 -              /*
 -               * Linux requires the following extensions, so we may as well
 -               * always set them.
 -               */
 -              set_bit(RISCV_ISA_EXT_ZICSR, isainfo->isa);
 -              set_bit(RISCV_ISA_EXT_ZIFENCEI, isainfo->isa);
 -
                /*
                 * These ones were as they were part of the base ISA when the
                 * port & dt-bindings were upstreamed, and so can be set
Simple merge
Simple merge
index a01bc15dce2441d82b1508d16fb827364183fe29,435e94a5b1bb2a277eba3af4a7befb9675744997..5e39dcf23fdbc15e12cedcf6b75a51ccfea6cf9d
   * region is not and then we have to go down to the PUD level.
   */
  
- pgd_t tmp_pg_dir[PTRS_PER_PGD] __page_aligned_bss;
- p4d_t tmp_p4d[PTRS_PER_P4D] __page_aligned_bss;
- pud_t tmp_pud[PTRS_PER_PUD] __page_aligned_bss;
 -extern pgd_t early_pg_dir[PTRS_PER_PGD];
+ static pgd_t tmp_pg_dir[PTRS_PER_PGD] __page_aligned_bss;
+ static p4d_t tmp_p4d[PTRS_PER_P4D] __page_aligned_bss;
+ static pud_t tmp_pud[PTRS_PER_PUD] __page_aligned_bss;
  
  static void __init kasan_populate_pte(pmd_t *pmd, unsigned long vaddr, unsigned long end)
  {
Simple merge
Simple merge
Simple merge