Merge tag 'riscv-for-linus-5.20-mw0' of git://git.kernel.org/pub/scm/linux/kernel...
authorLinus Torvalds <torvalds@linux-foundation.org>
Sat, 6 Aug 2022 22:04:48 +0000 (15:04 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Sat, 6 Aug 2022 22:04:48 +0000 (15:04 -0700)
Pull RISC-V updates from Palmer Dabbelt:

 - Enabling the FPU is now a static_key

 - Improvements to the Svpbmt support

 - CPU topology bindings for a handful of systems

 - Support for systems with 64-bit hart IDs

 - Many settings have been enabled in the defconfig, including both
   support for the StarFive systems and many of the Docker requirements

There are also a handful of cleanups and improvements, as usual.

* tag 'riscv-for-linus-5.20-mw0' of git://git.kernel.org/pub/scm/linux/kernel/git/riscv/linux: (28 commits)
  riscv: enable Docker requirements in defconfig
  riscv: convert the t-head pbmt errata to use the __nops macro
  riscv: introduce nops and __nops macros for NOP sequences
  RISC-V: Add fast call path of crash_kexec()
  riscv: mmap with PROT_WRITE but no PROT_READ is invalid
  riscv/efi_stub: Add 64bit boot-hartid support on RV64
  riscv: cpu: Add 64bit hartid support on RV64
  riscv: smp: Add 64bit hartid support on RV64
  riscv: spinwait: Fix hartid variable type
  riscv: cpu_ops_sbi: Add 64bit hartid support on RV64
  riscv: dts: sifive: "fix" pmic watchdog node name
  riscv: dts: canaan: Add k210 topology information
  riscv: dts: sifive: Add fu740 topology information
  riscv: dts: sifive: Add fu540 topology information
  riscv: dts: starfive: Add JH7100 CPU topology
  RISC-V: Add CONFIG_{NON,}PORTABLE
  riscv: config: enable SOC_STARFIVE in defconfig
  riscv: dts: microchip: Add mpfs' topology information
  riscv: Kconfig.socs: Add comments
  riscv: Kconfig.erratas: Add comments
  ...

37 files changed:
arch/riscv/Kconfig
arch/riscv/Kconfig.erratas
arch/riscv/Kconfig.socs
arch/riscv/boot/dts/canaan/k210.dtsi
arch/riscv/boot/dts/microchip/mpfs.dtsi
arch/riscv/boot/dts/sifive/fu540-c000.dtsi
arch/riscv/boot/dts/sifive/fu740-c000.dtsi
arch/riscv/boot/dts/sifive/hifive-unmatched-a00.dts
arch/riscv/boot/dts/starfive/jh7100.dtsi
arch/riscv/configs/32-bit.config
arch/riscv/configs/defconfig
arch/riscv/configs/nommu_k210_defconfig
arch/riscv/configs/nommu_k210_sdcard_defconfig
arch/riscv/configs/nommu_virt_defconfig
arch/riscv/configs/rv32_defconfig
arch/riscv/errata/thead/errata.c
arch/riscv/include/asm/asm.h
arch/riscv/include/asm/barrier.h
arch/riscv/include/asm/errata_list.h
arch/riscv/include/asm/hwcap.h
arch/riscv/include/asm/pci.h
arch/riscv/include/asm/processor.h
arch/riscv/include/asm/smp.h
arch/riscv/include/asm/switch_to.h
arch/riscv/kernel/alternative.c
arch/riscv/kernel/cpu.c
arch/riscv/kernel/cpu_ops_sbi.c
arch/riscv/kernel/cpu_ops_spinwait.c
arch/riscv/kernel/cpufeature.c
arch/riscv/kernel/smp.c
arch/riscv/kernel/smpboot.c
arch/riscv/kernel/sys_riscv.c
arch/riscv/kernel/traps.c
drivers/clocksource/timer-riscv.c
drivers/firmware/efi/libstub/riscv-stub.c
drivers/irqchip/irq-riscv-intc.c
drivers/irqchip/irq-sifive-plic.c

index 51713e0..5c52a82 100644 (file)
@@ -223,6 +223,21 @@ source "arch/riscv/Kconfig.erratas"
 
 menu "Platform type"
 
+config NONPORTABLE
+       bool "Allow configurations that result in non-portable kernels"
+       help
+         RISC-V kernel binaries are compatible between all known systems
+         whenever possible, but there are some use cases that can only be
+         satisfied by configurations that result in kernel binaries that are
+         not portable between systems.
+
+         Selecting N does not guarantee kernels will be portable to all known
+         systems.  Selecting any of the options guarded by NONPORTABLE will
+         result in kernel binaries that are unlikely to be portable between
+         systems.
+
+         If unsure, say N.
+
 choice
        prompt "Base ISA"
        default ARCH_RV64I
@@ -232,6 +247,7 @@ choice
 
 config ARCH_RV32I
        bool "RV32I"
+       depends on NONPORTABLE
        select 32BIT
        select GENERIC_LIB_ASHLDI3
        select GENERIC_LIB_ASHRDI3
@@ -352,11 +368,11 @@ config RISCV_ISA_C
        bool "Emit compressed instructions when building Linux"
        default y
        help
-          Adds "C" to the ISA subsets that the toolchain is allowed to emit
-          when building Linux, which results in compressed instructions in the
-          Linux binary.
+         Adds "C" to the ISA subsets that the toolchain is allowed to emit
+         when building Linux, which results in compressed instructions in the
+         Linux binary.
 
-          If you don't know what to do here, say Y.
+         If you don't know what to do here, say Y.
 
 config RISCV_ISA_SVPBMT
        bool "SVPBMT extension support"
@@ -385,7 +401,7 @@ config FPU
 
          If you don't know what to do here, say Y.
 
-endmenu
+endmenu # "Platform type"
 
 menu "Kernel features"
 
@@ -474,7 +490,7 @@ config COMPAT
 
          If you want to execute 32-bit userspace applications, say Y.
 
-endmenu
+endmenu # "Kernel features"
 
 menu "Boot options"
 
@@ -510,7 +526,6 @@ config CMDLINE_EXTEND
          cases where the provided arguments are insufficient and
          you don't want to or cannot modify them.
 
-
 config CMDLINE_FORCE
        bool "Always use the default kernel command string"
        help
@@ -553,6 +568,7 @@ config STACKPROTECTOR_PER_TASK
 
 config PHYS_RAM_BASE_FIXED
        bool "Explicitly specified physical RAM address"
+       depends on NONPORTABLE
        default n
 
 config PHYS_RAM_BASE
@@ -566,7 +582,7 @@ config PHYS_RAM_BASE
 
 config XIP_KERNEL
        bool "Kernel Execute-In-Place from ROM"
-       depends on MMU && SPARSEMEM
+       depends on MMU && SPARSEMEM && NONPORTABLE
        # This prevents XIP from being enabled by all{yes,mod}config, which
        # fail to build since XIP doesn't support large kernels.
        depends on !COMPILE_TEST
@@ -602,23 +618,30 @@ config XIP_PHYS_ADDR
          be linked for and stored to.  This address is dependent on your
          own flash usage.
 
-endmenu
+endmenu # "Boot options"
 
 config BUILTIN_DTB
        bool
-       depends on OF
+       depends on OF && NONPORTABLE
        default y if XIP_KERNEL
 
+config PORTABLE
+       bool
+       default !NONPORTABLE
+       select EFI
+       select OF
+       select MMU
+
 menu "Power management options"
 
 source "kernel/power/Kconfig"
 
-endmenu
+endmenu # "Power management options"
 
 menu "CPU Power Management"
 
 source "drivers/cpuidle/Kconfig"
 
-endmenu
+endmenu # "CPU Power Management"
 
 source "arch/riscv/kvm/Kconfig"
index 457ac72..f62b628 100644 (file)
@@ -55,4 +55,4 @@ config ERRATA_THEAD_PBMT
 
          If you don't know what to do here, say "Y".
 
-endmenu
+endmenu # "CPU errata selection"
index 85670dc..69774bb 100644 (file)
@@ -78,6 +78,6 @@ config SOC_CANAAN_K210_DTB_SOURCE
          for the DTS file that will be used to produce the DTB linked into the
          kernel.
 
-endif
+endif # SOC_CANAAN
 
-endmenu
+endmenu # "SoC selection"
index 44d3385..ec944d1 100644 (file)
                                compatible = "riscv,cpu-intc";
                        };
                };
+
+               cpu-map {
+                       cluster0 {
+                               core0 {
+                                       cpu = <&cpu0>;
+                               };
+
+                               core1 {
+                                       cpu = <&cpu1>;
+                               };
+                       };
+               };
        };
 
        sram: memory@80000000 {
index 3c83e98..499c2e6 100644 (file)
                                interrupt-controller;
                        };
                };
+
+               cpu-map {
+                       cluster0 {
+                               core0 {
+                                       cpu = <&cpu0>;
+                               };
+
+                               core1 {
+                                       cpu = <&cpu1>;
+                               };
+
+                               core2 {
+                                       cpu = <&cpu2>;
+                               };
+
+                               core3 {
+                                       cpu = <&cpu3>;
+                               };
+
+                               core4 {
+                                       cpu = <&cpu4>;
+                               };
+                       };
+               };
        };
 
        refclk: mssrefclk {
                        interrupt-parent = <&plic>;
                        interrupts = <54>;
                        clocks = <&clkcfg CLK_SPI0>;
-                       spi-max-frequency = <25000000>;
                        status = "disabled";
                };
 
                        interrupt-parent = <&plic>;
                        interrupts = <55>;
                        clocks = <&clkcfg CLK_SPI1>;
-                       spi-max-frequency = <25000000>;
                        status = "disabled";
                };
 
                        interrupt-parent = <&plic>;
                        interrupts = <85>;
                        clocks = <&clkcfg CLK_QSPI>;
-                       spi-max-frequency = <25000000>;
                        status = "disabled";
                };
 
index e3172d0..24bba83 100644 (file)
                                interrupt-controller;
                        };
                };
+
+               cpu-map {
+                       cluster0 {
+                               core0 {
+                                       cpu = <&cpu0>;
+                               };
+
+                               core1 {
+                                       cpu = <&cpu1>;
+                               };
+
+                               core2 {
+                                       cpu = <&cpu2>;
+                               };
+
+                               core3 {
+                                       cpu = <&cpu3>;
+                               };
+
+                               core4 {
+                                       cpu = <&cpu4>;
+                               };
+                       };
+               };
        };
        soc {
                #address-cells = <2>;
index 7b77c13..43bed6c 100644 (file)
                                interrupt-controller;
                        };
                };
+
+               cpu-map {
+                       cluster0 {
+                               core0 {
+                                       cpu = <&cpu0>;
+                               };
+
+                               core1 {
+                                       cpu = <&cpu1>;
+                               };
+
+                               core2 {
+                                       cpu = <&cpu2>;
+                               };
+
+                               core3 {
+                                       cpu = <&cpu3>;
+                               };
+
+                               core4 {
+                                       cpu = <&cpu4>;
+                               };
+                       };
+               };
        };
        soc {
                #address-cells = <2>;
index c4ed9ef..1f386b0 100644 (file)
@@ -90,7 +90,7 @@
                        compatible = "dlg,da9063-rtc";
                };
 
-               wdt {
+               watchdog {
                        compatible = "dlg,da9063-watchdog";
                };
 
index 69f22f9..c617a61 100644 (file)
@@ -17,7 +17,7 @@
                #address-cells = <1>;
                #size-cells = <0>;
 
-               cpu@0 {
+               U74_0: cpu@0 {
                        compatible = "sifive,u74-mc", "riscv";
                        reg = <0>;
                        d-cache-block-size = <64>;
@@ -42,7 +42,7 @@
                        };
                };
 
-               cpu@1 {
+               U74_1: cpu@1 {
                        compatible = "sifive,u74-mc", "riscv";
                        reg = <1>;
                        d-cache-block-size = <64>;
                                #interrupt-cells = <1>;
                        };
                };
+
+               cpu-map {
+                       cluster0 {
+                               core0 {
+                                       cpu = <&U74_0>;
+                               };
+
+                               core1 {
+                                       cpu = <&U74_1>;
+                               };
+                       };
+               };
        };
 
        osc_sys: osc_sys {
index 43f4132..f6af0f7 100644 (file)
@@ -1,2 +1,4 @@
 CONFIG_ARCH_RV32I=y
 CONFIG_32BIT=y
+# CONFIG_PORTABLE is not set
+CONFIG_NONPORTABLE=y
index 0cc17db..aed332a 100644 (file)
@@ -6,8 +6,17 @@ CONFIG_BPF_SYSCALL=y
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_CGROUPS=y
+CONFIG_MEMCG=y
 CONFIG_CGROUP_SCHED=y
 CONFIG_CFS_BANDWIDTH=y
+CONFIG_RT_GROUP_SCHED=y
+CONFIG_CGROUP_PIDS=y
+CONFIG_CGROUP_FREEZER=y
+CONFIG_CGROUP_HUGETLB=y
+CONFIG_CPUSETS=y
+CONFIG_CGROUP_DEVICE=y
+CONFIG_CGROUP_CPUACCT=y
+CONFIG_CGROUP_PERF=y
 CONFIG_CGROUP_BPF=y
 CONFIG_NAMESPACES=y
 CONFIG_USER_NS=y
@@ -18,6 +27,7 @@ CONFIG_EXPERT=y
 CONFIG_PROFILING=y
 CONFIG_SOC_MICROCHIP_POLARFIRE=y
 CONFIG_SOC_SIFIVE=y
+CONFIG_SOC_STARFIVE=y
 CONFIG_SOC_VIRT=y
 CONFIG_SMP=y
 CONFIG_HOTPLUG_CPU=y
@@ -28,9 +38,11 @@ CONFIG_KVM=m
 CONFIG_JUMP_LABEL=y
 CONFIG_MODULES=y
 CONFIG_MODULE_UNLOAD=y
+CONFIG_BLK_DEV_THROTTLING=y
 CONFIG_NET=y
 CONFIG_PACKET=y
 CONFIG_UNIX=y
+CONFIG_XFRM_USER=m
 CONFIG_INET=y
 CONFIG_IP_MULTICAST=y
 CONFIG_IP_ADVANCED_ROUTER=y
@@ -38,7 +50,43 @@ CONFIG_IP_PNP=y
 CONFIG_IP_PNP_DHCP=y
 CONFIG_IP_PNP_BOOTP=y
 CONFIG_IP_PNP_RARP=y
+CONFIG_INET_ESP=m
+CONFIG_NETFILTER=y
+CONFIG_BRIDGE_NETFILTER=m
+CONFIG_NF_CONNTRACK=m
+CONFIG_NF_CONNTRACK_FTP=m
+CONFIG_NF_CONNTRACK_TFTP=m
+CONFIG_NETFILTER_XT_MARK=m
+CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=m
+CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m
+CONFIG_NETFILTER_XT_MATCH_IPVS=m
+CONFIG_IP_VS=m
+CONFIG_IP_VS_PROTO_TCP=y
+CONFIG_IP_VS_PROTO_UDP=y
+CONFIG_IP_VS_RR=m
+CONFIG_IP_VS_NFCT=y
+CONFIG_NF_LOG_ARP=m
+CONFIG_NF_LOG_IPV4=m
+CONFIG_IP_NF_IPTABLES=m
+CONFIG_IP_NF_FILTER=m
+CONFIG_IP_NF_TARGET_REJECT=m
+CONFIG_IP_NF_NAT=m
+CONFIG_IP_NF_TARGET_MASQUERADE=m
+CONFIG_IP_NF_TARGET_REDIRECT=m
+CONFIG_IP_NF_MANGLE=m
+CONFIG_NF_LOG_IPV6=m
+CONFIG_IP6_NF_IPTABLES=m
+CONFIG_IP6_NF_MATCH_IPV6HEADER=m
+CONFIG_IP6_NF_FILTER=m
+CONFIG_IP6_NF_TARGET_REJECT=m
+CONFIG_IP6_NF_MANGLE=m
+CONFIG_BRIDGE=m
+CONFIG_BRIDGE_VLAN_FILTERING=y
+CONFIG_VLAN_8021Q=m
+CONFIG_NET_SCHED=y
+CONFIG_NET_CLS_CGROUP=m
 CONFIG_NETLINK_DIAG=y
+CONFIG_CGROUP_NET_PRIO=y
 CONFIG_NET_9P=y
 CONFIG_NET_9P_VIRTIO=y
 CONFIG_PCI=y
@@ -57,7 +105,15 @@ CONFIG_SCSI_VIRTIO=y
 CONFIG_ATA=y
 CONFIG_SATA_AHCI=y
 CONFIG_SATA_AHCI_PLATFORM=y
+CONFIG_MD=y
+CONFIG_BLK_DEV_DM=m
+CONFIG_DM_THIN_PROVISIONING=m
 CONFIG_NETDEVICES=y
+CONFIG_DUMMY=m
+CONFIG_MACVLAN=m
+CONFIG_IPVLAN=m
+CONFIG_VXLAN=m
+CONFIG_VETH=m
 CONFIG_VIRTIO_NET=y
 CONFIG_MACB=y
 CONFIG_E1000E=y
@@ -105,7 +161,11 @@ CONFIG_RPMSG_CTRL=y
 CONFIG_RPMSG_VIRTIO=y
 CONFIG_EXT4_FS=y
 CONFIG_EXT4_FS_POSIX_ACL=y
+CONFIG_EXT4_FS_SECURITY=y
+CONFIG_BTRFS_FS=m
+CONFIG_BTRFS_FS_POSIX_ACL=y
 CONFIG_AUTOFS4_FS=y
+CONFIG_OVERLAY_FS=m
 CONFIG_MSDOS_FS=y
 CONFIG_VFAT_FS=y
 CONFIG_TMPFS=y
@@ -119,6 +179,10 @@ CONFIG_ROOT_NFS=y
 CONFIG_9P_FS=y
 CONFIG_NLS_CODEPAGE_437=y
 CONFIG_NLS_ISO8859_1=m
+CONFIG_SECURITY=y
+CONFIG_SECURITY_SELINUX=y
+CONFIG_SECURITY_APPARMOR=y
+CONFIG_DEFAULT_SECURITY_DAC=y
 CONFIG_CRYPTO_USER_API_HASH=y
 CONFIG_CRYPTO_DEV_VIRTIO=y
 CONFIG_PRINTK_TIME=y
@@ -137,7 +201,6 @@ CONFIG_DEBUG_SPINLOCK=y
 CONFIG_DEBUG_MUTEXES=y
 CONFIG_DEBUG_RWSEMS=y
 CONFIG_DEBUG_ATOMIC_SLEEP=y
-CONFIG_STACKTRACE=y
 CONFIG_DEBUG_LIST=y
 CONFIG_DEBUG_PLIST=y
 CONFIG_DEBUG_SG=y
index 2438fa3..96fe8de 100644 (file)
@@ -28,6 +28,7 @@ CONFIG_EMBEDDED=y
 CONFIG_SLOB=y
 # CONFIG_MMU is not set
 CONFIG_SOC_CANAAN=y
+CONFIG_NONPORTABLE=y
 CONFIG_SMP=y
 CONFIG_NR_CPUS=2
 CONFIG_CMDLINE="earlycon console=ttySIF0"
index 9a133e6..3797406 100644 (file)
@@ -20,6 +20,7 @@ CONFIG_EMBEDDED=y
 CONFIG_SLOB=y
 # CONFIG_MMU is not set
 CONFIG_SOC_CANAAN=y
+CONFIG_NONPORTABLE=y
 CONFIG_SMP=y
 CONFIG_NR_CPUS=2
 CONFIG_CMDLINE="earlycon console=ttySIF0 root=/dev/mmcblk0p1 rootwait ro"
index 5269fbb..1a56eda 100644 (file)
@@ -25,6 +25,7 @@ CONFIG_EXPERT=y
 CONFIG_SLOB=y
 # CONFIG_MMU is not set
 CONFIG_SOC_VIRT=y
+CONFIG_NONPORTABLE=y
 CONFIG_SMP=y
 CONFIG_CMDLINE="root=/dev/vda rw earlycon=uart8250,mmio,0x10000000,115200n8 console=ttyS0"
 CONFIG_CMDLINE_FORCE=y
index 6cd9d84..38760e4 100644 (file)
@@ -18,6 +18,7 @@ CONFIG_EXPERT=y
 CONFIG_PROFILING=y
 CONFIG_SOC_SIFIVE=y
 CONFIG_SOC_VIRT=y
+CONFIG_NONPORTABLE=y
 CONFIG_ARCH_RV32I=y
 CONFIG_SMP=y
 CONFIG_HOTPLUG_CPU=y
index e5d7527..b37b6fe 100644 (file)
 #include <asm/patch.h>
 #include <asm/vendorid_list.h>
 
-struct errata_info {
-       char name[ERRATA_STRING_LENGTH_MAX];
-       bool (*check_func)(unsigned long arch_id, unsigned long impid);
-       unsigned int stage;
-};
-
-static bool errata_mt_check_func(unsigned long  arch_id, unsigned long impid)
+static bool errata_probe_pbmt(unsigned int stage,
+                             unsigned long arch_id, unsigned long impid)
 {
        if (arch_id != 0 || impid != 0)
                return false;
-       return true;
-}
 
-static const struct errata_info errata_list[ERRATA_THEAD_NUMBER] = {
-       {
-               .name = "memory-types",
-               .stage = RISCV_ALTERNATIVES_EARLY_BOOT,
-               .check_func = errata_mt_check_func
-       },
-};
+       if (stage == RISCV_ALTERNATIVES_EARLY_BOOT ||
+           stage == RISCV_ALTERNATIVES_MODULE)
+               return true;
+
+       return false;
+}
 
-static u32 thead_errata_probe(unsigned int stage, unsigned long archid, unsigned long impid)
+static u32 thead_errata_probe(unsigned int stage,
+                             unsigned long archid, unsigned long impid)
 {
-       const struct errata_info *info;
        u32 cpu_req_errata = 0;
-       int idx;
-
-       for (idx = 0; idx < ERRATA_THEAD_NUMBER; idx++) {
-               info = &errata_list[idx];
 
-               if ((stage == RISCV_ALTERNATIVES_MODULE ||
-                    info->stage == stage) && info->check_func(archid, impid))
-                       cpu_req_errata |= (1U << idx);
-       }
+       if (errata_probe_pbmt(stage, archid, impid))
+               cpu_req_errata |= (1U << ERRATA_THEAD_PBMT);
 
        return cpu_req_errata;
 }
index 618d7c5..1b471ff 100644 (file)
 #error "Unexpected __SIZEOF_SHORT__"
 #endif
 
+#ifdef __ASSEMBLY__
+
+/* Common assembly source macros */
+
+/*
+ * NOP sequence
+ */
+.macro nops, num
+       .rept   \num
+       nop
+       .endr
+.endm
+
+#endif /* __ASSEMBLY__ */
+
 #endif /* _ASM_RISCV_ASM_H */
index d0e24aa..1107525 100644 (file)
@@ -13,6 +13,8 @@
 #ifndef __ASSEMBLY__
 
 #define nop()          __asm__ __volatile__ ("nop")
+#define __nops(n)      ".rept  " #n "\nnop\n.endr\n"
+#define nops(n)                __asm__ __volatile__ (__nops(n))
 
 #define RISCV_FENCE(p, s) \
        __asm__ __volatile__ ("fence " #p "," #s : : : "memory")
index 416ead0..398e351 100644 (file)
@@ -68,13 +68,7 @@ asm(ALTERNATIVE_2("li %0, 0\t\nnop",                                 \
  */
 #define ALT_THEAD_PMA(_val)                                            \
 asm volatile(ALTERNATIVE(                                              \
-       "nop\n\t"                                                       \
-       "nop\n\t"                                                       \
-       "nop\n\t"                                                       \
-       "nop\n\t"                                                       \
-       "nop\n\t"                                                       \
-       "nop\n\t"                                                       \
-       "nop",                                                          \
+       __nops(7),                                                      \
        "li      t3, %1\n\t"                                            \
        "slli    t3, t3, %3\n\t"                                        \
        "and     t3, %0, t3\n\t"                                        \
index 4e24868..e48eebd 100644 (file)
@@ -12,6 +12,7 @@
 #include <uapi/asm/hwcap.h>
 
 #ifndef __ASSEMBLY__
+#include <linux/jump_label.h>
 /*
  * This yields a mask that user programs can use to figure out what
  * instruction set this cpu supports.
@@ -56,6 +57,16 @@ enum riscv_isa_ext_id {
        RISCV_ISA_EXT_ID_MAX = RISCV_ISA_EXT_MAX,
 };
 
+/*
+ * This enum represents the logical ID for each RISC-V ISA extension static
+ * keys. We can use static key to optimize code path if some ISA extensions
+ * are available.
+ */
+enum riscv_isa_ext_key {
+       RISCV_ISA_EXT_KEY_FPU,          /* For 'F' and 'D' */
+       RISCV_ISA_EXT_KEY_MAX,
+};
+
 struct riscv_isa_ext_data {
        /* Name of the extension displayed to userspace via /proc/cpuinfo */
        char uprop[RISCV_ISA_EXT_NAME_LEN_MAX];
@@ -63,6 +74,20 @@ struct riscv_isa_ext_data {
        unsigned int isa_ext_id;
 };
 
+extern struct static_key_false riscv_isa_ext_keys[RISCV_ISA_EXT_KEY_MAX];
+
+static __always_inline int riscv_isa_ext2key(int num)
+{
+       switch (num) {
+       case RISCV_ISA_EXT_f:
+               return RISCV_ISA_EXT_KEY_FPU;
+       case RISCV_ISA_EXT_d:
+               return RISCV_ISA_EXT_KEY_FPU;
+       default:
+               return -EINVAL;
+       }
+}
+
 unsigned long riscv_isa_extension_base(const unsigned long *isa_bitmap);
 
 #define riscv_isa_extension_mask(ext) BIT_MASK(RISCV_ISA_EXT_##ext)
index 6ef4a14..cc2a184 100644 (file)
@@ -12,6 +12,9 @@
 
 #include <asm/io.h>
 
+#define PCIBIOS_MIN_IO         4
+#define PCIBIOS_MIN_MEM                16
+
 #if defined(CONFIG_PCI) && defined(CONFIG_NUMA)
 static inline int pcibus_to_node(struct pci_bus *bus)
 {
index 21c8072..19eedd4 100644 (file)
@@ -79,8 +79,8 @@ static inline void wait_for_interrupt(void)
 }
 
 struct device_node;
-int riscv_of_processor_hartid(struct device_node *node);
-int riscv_of_parent_hartid(struct device_node *node);
+int riscv_of_processor_hartid(struct device_node *node, unsigned long *hartid);
+int riscv_of_parent_hartid(struct device_node *node, unsigned long *hartid);
 
 extern void riscv_fill_hwcap(void);
 extern int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src);
index 23170c9..d3443be 100644 (file)
@@ -42,7 +42,7 @@ void arch_send_call_function_ipi_mask(struct cpumask *mask);
 /* Hook for the generic smp_call_function_single() routine. */
 void arch_send_call_function_single_ipi(int cpu);
 
-int riscv_hartid_to_cpuid(int hartid);
+int riscv_hartid_to_cpuid(unsigned long hartid);
 
 /* Set custom IPI operations */
 void riscv_set_ipi_ops(const struct riscv_ipi_ops *ops);
@@ -70,7 +70,7 @@ static inline void show_ipi_stats(struct seq_file *p, int prec)
 {
 }
 
-static inline int riscv_hartid_to_cpuid(int hartid)
+static inline int riscv_hartid_to_cpuid(unsigned long hartid)
 {
        if (hartid == boot_cpu_hartid)
                return 0;
index 0a3f4f9..1146348 100644 (file)
@@ -8,6 +8,7 @@
 
 #include <linux/jump_label.h>
 #include <linux/sched/task_stack.h>
+#include <asm/hwcap.h>
 #include <asm/processor.h>
 #include <asm/ptrace.h>
 #include <asm/csr.h>
@@ -56,10 +57,9 @@ static inline void __switch_to_aux(struct task_struct *prev,
        fstate_restore(next, task_pt_regs(next));
 }
 
-extern struct static_key_false cpu_hwcap_fpu;
 static __always_inline bool has_fpu(void)
 {
-       return static_branch_likely(&cpu_hwcap_fpu);
+       return static_branch_likely(&riscv_isa_ext_keys[RISCV_ISA_EXT_KEY_FPU]);
 }
 #else
 static __always_inline bool has_fpu(void) { return false; }
index c9d0d3c..a7d26a0 100644 (file)
@@ -20,7 +20,7 @@ struct cpu_manufacturer_info_t {
        unsigned long vendor_id;
        unsigned long arch_id;
        unsigned long imp_id;
-       void (*vendor_patch_func)(struct alt_entry *begin, struct alt_entry *end,
+       void (*patch_func)(struct alt_entry *begin, struct alt_entry *end,
                                  unsigned long archid, unsigned long impid,
                                  unsigned int stage);
 };
@@ -40,16 +40,16 @@ static void __init_or_module riscv_fill_cpu_mfr_info(struct cpu_manufacturer_inf
        switch (cpu_mfr_info->vendor_id) {
 #ifdef CONFIG_ERRATA_SIFIVE
        case SIFIVE_VENDOR_ID:
-               cpu_mfr_info->vendor_patch_func = sifive_errata_patch_func;
+               cpu_mfr_info->patch_func = sifive_errata_patch_func;
                break;
 #endif
 #ifdef CONFIG_ERRATA_THEAD
        case THEAD_VENDOR_ID:
-               cpu_mfr_info->vendor_patch_func = thead_errata_patch_func;
+               cpu_mfr_info->patch_func = thead_errata_patch_func;
                break;
 #endif
        default:
-               cpu_mfr_info->vendor_patch_func = NULL;
+               cpu_mfr_info->patch_func = NULL;
        }
 }
 
@@ -68,13 +68,13 @@ static void __init_or_module _apply_alternatives(struct alt_entry *begin,
 
        riscv_cpufeature_patch_func(begin, end, stage);
 
-       if (!cpu_mfr_info.vendor_patch_func)
+       if (!cpu_mfr_info.patch_func)
                return;
 
-       cpu_mfr_info.vendor_patch_func(begin, end,
-                                  cpu_mfr_info.arch_id,
-                                  cpu_mfr_info.imp_id,
-                                  stage);
+       cpu_mfr_info.patch_func(begin, end,
+                               cpu_mfr_info.arch_id,
+                               cpu_mfr_info.imp_id,
+                               stage);
 }
 
 void __init apply_boot_alternatives(void)
index fba9e9f..022fd18 100644 (file)
  * Returns the hart ID of the given device tree node, or -ENODEV if the node
  * isn't an enabled and valid RISC-V hart node.
  */
-int riscv_of_processor_hartid(struct device_node *node)
+int riscv_of_processor_hartid(struct device_node *node, unsigned long *hart)
 {
        const char *isa;
-       u32 hart;
 
        if (!of_device_is_compatible(node, "riscv")) {
                pr_warn("Found incompatible CPU\n");
                return -ENODEV;
        }
 
-       hart = of_get_cpu_hwid(node, 0);
-       if (hart == ~0U) {
+       *hart = (unsigned long) of_get_cpu_hwid(node, 0);
+       if (*hart == ~0UL) {
                pr_warn("Found CPU without hart ID\n");
                return -ENODEV;
        }
 
        if (!of_device_is_available(node)) {
-               pr_info("CPU with hartid=%d is not available\n", hart);
+               pr_info("CPU with hartid=%lu is not available\n", *hart);
                return -ENODEV;
        }
 
        if (of_property_read_string(node, "riscv,isa", &isa)) {
-               pr_warn("CPU with hartid=%d has no \"riscv,isa\" property\n", hart);
+               pr_warn("CPU with hartid=%lu has no \"riscv,isa\" property\n", *hart);
                return -ENODEV;
        }
        if (isa[0] != 'r' || isa[1] != 'v') {
-               pr_warn("CPU with hartid=%d has an invalid ISA of \"%s\"\n", hart, isa);
+               pr_warn("CPU with hartid=%lu has an invalid ISA of \"%s\"\n", *hart, isa);
                return -ENODEV;
        }
 
-       return hart;
+       return 0;
 }
 
 /*
@@ -53,11 +52,16 @@ int riscv_of_processor_hartid(struct device_node *node)
  * To achieve this, we walk up the DT tree until we find an active
  * RISC-V core (HART) node and extract the cpuid from it.
  */
-int riscv_of_parent_hartid(struct device_node *node)
+int riscv_of_parent_hartid(struct device_node *node, unsigned long *hartid)
 {
+       int rc;
+
        for (; node; node = node->parent) {
-               if (of_device_is_compatible(node, "riscv"))
-                       return riscv_of_processor_hartid(node);
+               if (of_device_is_compatible(node, "riscv")) {
+                       rc = riscv_of_processor_hartid(node, hartid);
+                       if (!rc)
+                               return 0;
+               }
        }
 
        return -1;
index 4f5a6f8..efa0f08 100644 (file)
@@ -65,7 +65,7 @@ static int sbi_hsm_hart_get_status(unsigned long hartid)
 static int sbi_cpu_start(unsigned int cpuid, struct task_struct *tidle)
 {
        unsigned long boot_addr = __pa_symbol(secondary_start_sbi);
-       int hartid = cpuid_to_hartid_map(cpuid);
+       unsigned long hartid = cpuid_to_hartid_map(cpuid);
        unsigned long hsm_data;
        struct sbi_hart_boot_data *bdata = &per_cpu(boot_data, cpuid);
 
@@ -107,7 +107,7 @@ static void sbi_cpu_stop(void)
 static int sbi_cpu_is_stopped(unsigned int cpuid)
 {
        int rc;
-       int hartid = cpuid_to_hartid_map(cpuid);
+       unsigned long hartid = cpuid_to_hartid_map(cpuid);
 
        rc = sbi_hsm_hart_get_status(hartid);
 
index 346847f..3ade915 100644 (file)
@@ -18,7 +18,7 @@ void *__cpu_spinwait_task_pointer[NR_CPUS] __section(".data");
 static void cpu_update_secondary_bootdata(unsigned int cpuid,
                                   struct task_struct *tidle)
 {
-       int hartid = cpuid_to_hartid_map(cpuid);
+       unsigned long hartid = cpuid_to_hartid_map(cpuid);
 
        /*
         * The hartid must be less than NR_CPUS to avoid out-of-bound access
@@ -27,7 +27,7 @@ static void cpu_update_secondary_bootdata(unsigned int cpuid,
         * spinwait booting is not the recommended approach for any platforms
         * booting Linux in S-mode and can be disabled in the future.
         */
-       if (hartid == INVALID_HARTID || hartid >= NR_CPUS)
+       if (hartid == INVALID_HARTID || hartid >= (unsigned long) NR_CPUS)
                return;
 
        /* Make sure tidle is updated */
index 12b05ce..e233fe1 100644 (file)
@@ -27,9 +27,8 @@ unsigned long elf_hwcap __read_mostly;
 /* Host ISA bitmap */
 static DECLARE_BITMAP(riscv_isa, RISCV_ISA_EXT_MAX) __read_mostly;
 
-#ifdef CONFIG_FPU
-__ro_after_init DEFINE_STATIC_KEY_FALSE(cpu_hwcap_fpu);
-#endif
+__ro_after_init DEFINE_STATIC_KEY_ARRAY_FALSE(riscv_isa_ext_keys, RISCV_ISA_EXT_KEY_MAX);
+EXPORT_SYMBOL(riscv_isa_ext_keys);
 
 /**
  * riscv_isa_extension_base() - Get base extension word
@@ -73,8 +72,9 @@ void __init riscv_fill_hwcap(void)
        struct device_node *node;
        const char *isa;
        char print_str[NUM_ALPHA_EXTS + 1];
-       int i, j;
+       int i, j, rc;
        static unsigned long isa2hwcap[256] = {0};
+       unsigned long hartid;
 
        isa2hwcap['i'] = isa2hwcap['I'] = COMPAT_HWCAP_ISA_I;
        isa2hwcap['m'] = isa2hwcap['M'] = COMPAT_HWCAP_ISA_M;
@@ -92,7 +92,8 @@ void __init riscv_fill_hwcap(void)
                DECLARE_BITMAP(this_isa, RISCV_ISA_EXT_MAX);
                const char *temp;
 
-               if (riscv_of_processor_hartid(node) < 0)
+               rc = riscv_of_processor_hartid(node, &hartid);
+               if (rc < 0)
                        continue;
 
                if (of_property_read_string(node, "riscv,isa", &isa)) {
@@ -238,19 +239,15 @@ void __init riscv_fill_hwcap(void)
                        print_str[j++] = (char)('a' + i);
        pr_info("riscv: ELF capabilities %s\n", print_str);
 
-#ifdef CONFIG_FPU
-       if (elf_hwcap & (COMPAT_HWCAP_ISA_F | COMPAT_HWCAP_ISA_D))
-               static_branch_enable(&cpu_hwcap_fpu);
-#endif
+       for_each_set_bit(i, riscv_isa, RISCV_ISA_EXT_MAX) {
+               j = riscv_isa_ext2key(i);
+               if (j >= 0)
+                       static_branch_enable(&riscv_isa_ext_keys[j]);
+       }
 }
 
 #ifdef CONFIG_RISCV_ALTERNATIVE
-struct cpufeature_info {
-       char name[ERRATA_STRING_LENGTH_MAX];
-       bool (*check_func)(unsigned int stage);
-};
-
-static bool __init_or_module cpufeature_svpbmt_check_func(unsigned int stage)
+static bool __init_or_module cpufeature_probe_svpbmt(unsigned int stage)
 {
 #ifdef CONFIG_RISCV_ISA_SVPBMT
        switch (stage) {
@@ -264,26 +261,19 @@ static bool __init_or_module cpufeature_svpbmt_check_func(unsigned int stage)
        return false;
 }
 
-static const struct cpufeature_info __initdata_or_module
-cpufeature_list[CPUFEATURE_NUMBER] = {
-       {
-               .name = "svpbmt",
-               .check_func = cpufeature_svpbmt_check_func
-       },
-};
-
+/*
+ * Probe presence of individual extensions.
+ *
+ * This code may also be executed before kernel relocation, so we cannot use
+ * addresses generated by the address-of operator as they won't be valid in
+ * this context.
+ */
 static u32 __init_or_module cpufeature_probe(unsigned int stage)
 {
-       const struct cpufeature_info *info;
        u32 cpu_req_feature = 0;
-       int idx;
 
-       for (idx = 0; idx < CPUFEATURE_NUMBER; idx++) {
-               info = &cpufeature_list[idx];
-
-               if (info->check_func(stage))
-                       cpu_req_feature |= (1U << idx);
-       }
+       if (cpufeature_probe_svpbmt(stage))
+               cpu_req_feature |= (1U << CPUFEATURE_SVPBMT);
 
        return cpu_req_feature;
 }
index b5d30ea..018e7dc 100644 (file)
@@ -47,7 +47,7 @@ static struct {
        unsigned long bits ____cacheline_aligned;
 } ipi_data[NR_CPUS] __cacheline_aligned;
 
-int riscv_hartid_to_cpuid(int hartid)
+int riscv_hartid_to_cpuid(unsigned long hartid)
 {
        int i;
 
@@ -55,7 +55,7 @@ int riscv_hartid_to_cpuid(int hartid)
                if (cpuid_to_hartid_map(i) == hartid)
                        return i;
 
-       pr_err("Couldn't find cpu id for hartid [%d]\n", hartid);
+       pr_err("Couldn't find cpu id for hartid [%lu]\n", hartid);
        return -ENOENT;
 }
 
index f1e4948..a752c7b 100644 (file)
@@ -72,15 +72,16 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
 void __init setup_smp(void)
 {
        struct device_node *dn;
-       int hart;
+       unsigned long hart;
        bool found_boot_cpu = false;
        int cpuid = 1;
+       int rc;
 
        cpu_set_ops(0);
 
        for_each_of_cpu_node(dn) {
-               hart = riscv_of_processor_hartid(dn);
-               if (hart < 0)
+               rc = riscv_of_processor_hartid(dn, &hart);
+               if (rc < 0)
                        continue;
 
                if (hart == cpuid_to_hartid_map(0)) {
@@ -90,7 +91,7 @@ void __init setup_smp(void)
                        continue;
                }
                if (cpuid >= NR_CPUS) {
-                       pr_warn("Invalid cpuid [%d] for hartid [%d]\n",
+                       pr_warn("Invalid cpuid [%d] for hartid [%lu]\n",
                                cpuid, hart);
                        continue;
                }
index 9c0194f..571556b 100644 (file)
@@ -18,9 +18,8 @@ static long riscv_sys_mmap(unsigned long addr, unsigned long len,
        if (unlikely(offset & (~PAGE_MASK >> page_shift_offset)))
                return -EINVAL;
 
-       if ((prot & PROT_WRITE) && (prot & PROT_EXEC))
-               if (unlikely(!(prot & PROT_READ)))
-                       return -EINVAL;
+       if (unlikely((prot & PROT_WRITE) && !(prot & PROT_READ)))
+               return -EINVAL;
 
        return ksys_mmap_pgoff(addr, len, prot, flags, fd,
                               offset >> (PAGE_SHIFT - page_shift_offset));
index b404265..39d0f8b 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/mm.h>
 #include <linux/module.h>
 #include <linux/irq.h>
+#include <linux/kexec.h>
 
 #include <asm/asm-prototypes.h>
 #include <asm/bug.h>
@@ -44,6 +45,9 @@ void die(struct pt_regs *regs, const char *str)
 
        ret = notify_die(DIE_OOPS, str, regs, 0, regs->cause, SIGSEGV);
 
+       if (regs && kexec_should_crash(current))
+               crash_kexec(regs);
+
        bust_spinlocks(0);
        add_taint(TAINT_DIE, LOCKDEP_NOW_UNRELIABLE);
        spin_unlock_irq(&die_lock);
index 593d5a9..e460df7 100644 (file)
@@ -101,20 +101,21 @@ static irqreturn_t riscv_timer_interrupt(int irq, void *dev_id)
 
 static int __init riscv_timer_init_dt(struct device_node *n)
 {
-       int cpuid, hartid, error;
+       int cpuid, error;
+       unsigned long hartid;
        struct device_node *child;
        struct irq_domain *domain;
 
-       hartid = riscv_of_processor_hartid(n);
-       if (hartid < 0) {
-               pr_warn("Not valid hartid for node [%pOF] error = [%d]\n",
+       error = riscv_of_processor_hartid(n, &hartid);
+       if (error < 0) {
+               pr_warn("Not valid hartid for node [%pOF] error = [%lu]\n",
                        n, hartid);
-               return hartid;
+               return error;
        }
 
        cpuid = riscv_hartid_to_cpuid(hartid);
        if (cpuid < 0) {
-               pr_warn("Invalid cpuid for hartid [%d]\n", hartid);
+               pr_warn("Invalid cpuid for hartid [%lu]\n", hartid);
                return cpuid;
        }
 
@@ -140,7 +141,7 @@ static int __init riscv_timer_init_dt(struct device_node *n)
                return -ENODEV;
        }
 
-       pr_info("%s: Registering clocksource cpuid [%d] hartid [%d]\n",
+       pr_info("%s: Registering clocksource cpuid [%d] hartid [%lu]\n",
               __func__, cpuid, hartid);
        error = clocksource_register_hz(&riscv_clocksource, riscv_timebase);
        if (error) {
index 9e85e58..b450ebf 100644 (file)
@@ -8,6 +8,7 @@
 
 #include <asm/efi.h>
 #include <asm/sections.h>
+#include <asm/unaligned.h>
 
 #include "efistub.h"
 
@@ -29,7 +30,7 @@ static int get_boot_hartid_from_fdt(void)
 {
        const void *fdt;
        int chosen_node, len;
-       const fdt32_t *prop;
+       const void *prop;
 
        fdt = get_efi_config_table(DEVICE_TREE_GUID);
        if (!fdt)
@@ -40,10 +41,16 @@ static int get_boot_hartid_from_fdt(void)
                return -EINVAL;
 
        prop = fdt_getprop((void *)fdt, chosen_node, "boot-hartid", &len);
-       if (!prop || len != sizeof(u32))
+       if (!prop)
+               return -EINVAL;
+
+       if (len == sizeof(u32))
+               hartid = (unsigned long) fdt32_to_cpu(*(fdt32_t *)prop);
+       else if (len == sizeof(u64))
+               hartid = (unsigned long) fdt64_to_cpu(__get_unaligned_t(fdt64_t, prop));
+       else
                return -EINVAL;
 
-       hartid = fdt32_to_cpu(*prop);
        return 0;
 }
 
index b65bd88..499e5f8 100644 (file)
@@ -95,10 +95,11 @@ static const struct irq_domain_ops riscv_intc_domain_ops = {
 static int __init riscv_intc_init(struct device_node *node,
                                  struct device_node *parent)
 {
-       int rc, hartid;
+       int rc;
+       unsigned long hartid;
 
-       hartid = riscv_of_parent_hartid(node);
-       if (hartid < 0) {
+       rc = riscv_of_parent_hartid(node, &hartid);
+       if (rc < 0) {
                pr_warn("unable to find hart id for %pOF\n", node);
                return 0;
        }
index ba49381..2f47848 100644 (file)
@@ -374,7 +374,8 @@ static int __init __plic_init(struct device_node *node,
        for (i = 0; i < nr_contexts; i++) {
                struct of_phandle_args parent;
                irq_hw_number_t hwirq;
-               int cpu, hartid;
+               int cpu;
+               unsigned long hartid;
 
                if (of_irq_parse_one(node, i, &parent)) {
                        pr_err("failed to parse parent for context %d.\n", i);
@@ -398,8 +399,8 @@ static int __init __plic_init(struct device_node *node,
                        continue;
                }
 
-               hartid = riscv_of_parent_hartid(parent.np);
-               if (hartid < 0) {
+               error = riscv_of_parent_hartid(parent.np, &hartid);
+               if (error < 0) {
                        pr_warn("failed to parse hart ID for context %d.\n", i);
                        continue;
                }