Commit 4d1044fc authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'riscv-for-linus-5.20-mw0' of git://git.kernel.org/pub/scm/linux/kernel/git/riscv/linux

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
  ...
parents ea0c3926 ba6cfef0
...@@ -223,6 +223,21 @@ source "arch/riscv/Kconfig.erratas" ...@@ -223,6 +223,21 @@ source "arch/riscv/Kconfig.erratas"
menu "Platform type" 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 choice
prompt "Base ISA" prompt "Base ISA"
default ARCH_RV64I default ARCH_RV64I
...@@ -232,6 +247,7 @@ choice ...@@ -232,6 +247,7 @@ choice
config ARCH_RV32I config ARCH_RV32I
bool "RV32I" bool "RV32I"
depends on NONPORTABLE
select 32BIT select 32BIT
select GENERIC_LIB_ASHLDI3 select GENERIC_LIB_ASHLDI3
select GENERIC_LIB_ASHRDI3 select GENERIC_LIB_ASHRDI3
...@@ -352,11 +368,11 @@ config RISCV_ISA_C ...@@ -352,11 +368,11 @@ config RISCV_ISA_C
bool "Emit compressed instructions when building Linux" bool "Emit compressed instructions when building Linux"
default y default y
help help
Adds "C" to the ISA subsets that the toolchain is allowed to emit Adds "C" to the ISA subsets that the toolchain is allowed to emit
when building Linux, which results in compressed instructions in the when building Linux, which results in compressed instructions in the
Linux binary. 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 config RISCV_ISA_SVPBMT
bool "SVPBMT extension support" bool "SVPBMT extension support"
...@@ -385,7 +401,7 @@ config FPU ...@@ -385,7 +401,7 @@ config FPU
If you don't know what to do here, say Y. If you don't know what to do here, say Y.
endmenu endmenu # "Platform type"
menu "Kernel features" menu "Kernel features"
...@@ -474,7 +490,7 @@ config COMPAT ...@@ -474,7 +490,7 @@ config COMPAT
If you want to execute 32-bit userspace applications, say Y. If you want to execute 32-bit userspace applications, say Y.
endmenu endmenu # "Kernel features"
menu "Boot options" menu "Boot options"
...@@ -510,7 +526,6 @@ config CMDLINE_EXTEND ...@@ -510,7 +526,6 @@ config CMDLINE_EXTEND
cases where the provided arguments are insufficient and cases where the provided arguments are insufficient and
you don't want to or cannot modify them. you don't want to or cannot modify them.
config CMDLINE_FORCE config CMDLINE_FORCE
bool "Always use the default kernel command string" bool "Always use the default kernel command string"
help help
...@@ -553,6 +568,7 @@ config STACKPROTECTOR_PER_TASK ...@@ -553,6 +568,7 @@ config STACKPROTECTOR_PER_TASK
config PHYS_RAM_BASE_FIXED config PHYS_RAM_BASE_FIXED
bool "Explicitly specified physical RAM address" bool "Explicitly specified physical RAM address"
depends on NONPORTABLE
default n default n
config PHYS_RAM_BASE config PHYS_RAM_BASE
...@@ -566,7 +582,7 @@ config PHYS_RAM_BASE ...@@ -566,7 +582,7 @@ config PHYS_RAM_BASE
config XIP_KERNEL config XIP_KERNEL
bool "Kernel Execute-In-Place from ROM" 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 # This prevents XIP from being enabled by all{yes,mod}config, which
# fail to build since XIP doesn't support large kernels. # fail to build since XIP doesn't support large kernels.
depends on !COMPILE_TEST depends on !COMPILE_TEST
...@@ -602,23 +618,30 @@ config XIP_PHYS_ADDR ...@@ -602,23 +618,30 @@ config XIP_PHYS_ADDR
be linked for and stored to. This address is dependent on your be linked for and stored to. This address is dependent on your
own flash usage. own flash usage.
endmenu endmenu # "Boot options"
config BUILTIN_DTB config BUILTIN_DTB
bool bool
depends on OF depends on OF && NONPORTABLE
default y if XIP_KERNEL default y if XIP_KERNEL
config PORTABLE
bool
default !NONPORTABLE
select EFI
select OF
select MMU
menu "Power management options" menu "Power management options"
source "kernel/power/Kconfig" source "kernel/power/Kconfig"
endmenu endmenu # "Power management options"
menu "CPU Power Management" menu "CPU Power Management"
source "drivers/cpuidle/Kconfig" source "drivers/cpuidle/Kconfig"
endmenu endmenu # "CPU Power Management"
source "arch/riscv/kvm/Kconfig" source "arch/riscv/kvm/Kconfig"
...@@ -55,4 +55,4 @@ config ERRATA_THEAD_PBMT ...@@ -55,4 +55,4 @@ config ERRATA_THEAD_PBMT
If you don't know what to do here, say "Y". If you don't know what to do here, say "Y".
endmenu endmenu # "CPU errata selection"
...@@ -78,6 +78,6 @@ config SOC_CANAAN_K210_DTB_SOURCE ...@@ -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 for the DTS file that will be used to produce the DTB linked into the
kernel. kernel.
endif endif # SOC_CANAAN
endmenu endmenu # "SoC selection"
...@@ -65,6 +65,18 @@ cpu1_intc: interrupt-controller { ...@@ -65,6 +65,18 @@ cpu1_intc: interrupt-controller {
compatible = "riscv,cpu-intc"; compatible = "riscv,cpu-intc";
}; };
}; };
cpu-map {
cluster0 {
core0 {
cpu = <&cpu0>;
};
core1 {
cpu = <&cpu1>;
};
};
};
}; };
sram: memory@80000000 { sram: memory@80000000 {
......
...@@ -142,6 +142,30 @@ cpu4_intc: interrupt-controller { ...@@ -142,6 +142,30 @@ cpu4_intc: interrupt-controller {
interrupt-controller; interrupt-controller;
}; };
}; };
cpu-map {
cluster0 {
core0 {
cpu = <&cpu0>;
};
core1 {
cpu = <&cpu1>;
};
core2 {
cpu = <&cpu2>;
};
core3 {
cpu = <&cpu3>;
};
core4 {
cpu = <&cpu4>;
};
};
};
}; };
refclk: mssrefclk { refclk: mssrefclk {
...@@ -291,7 +315,6 @@ spi0: spi@20108000 { ...@@ -291,7 +315,6 @@ spi0: spi@20108000 {
interrupt-parent = <&plic>; interrupt-parent = <&plic>;
interrupts = <54>; interrupts = <54>;
clocks = <&clkcfg CLK_SPI0>; clocks = <&clkcfg CLK_SPI0>;
spi-max-frequency = <25000000>;
status = "disabled"; status = "disabled";
}; };
...@@ -303,7 +326,6 @@ spi1: spi@20109000 { ...@@ -303,7 +326,6 @@ spi1: spi@20109000 {
interrupt-parent = <&plic>; interrupt-parent = <&plic>;
interrupts = <55>; interrupts = <55>;
clocks = <&clkcfg CLK_SPI1>; clocks = <&clkcfg CLK_SPI1>;
spi-max-frequency = <25000000>;
status = "disabled"; status = "disabled";
}; };
...@@ -315,7 +337,6 @@ qspi: spi@21000000 { ...@@ -315,7 +337,6 @@ qspi: spi@21000000 {
interrupt-parent = <&plic>; interrupt-parent = <&plic>;
interrupts = <85>; interrupts = <85>;
clocks = <&clkcfg CLK_QSPI>; clocks = <&clkcfg CLK_QSPI>;
spi-max-frequency = <25000000>;
status = "disabled"; status = "disabled";
}; };
......
...@@ -133,6 +133,30 @@ cpu4_intc: interrupt-controller { ...@@ -133,6 +133,30 @@ cpu4_intc: interrupt-controller {
interrupt-controller; interrupt-controller;
}; };
}; };
cpu-map {
cluster0 {
core0 {
cpu = <&cpu0>;
};
core1 {
cpu = <&cpu1>;
};
core2 {
cpu = <&cpu2>;
};
core3 {
cpu = <&cpu3>;
};
core4 {
cpu = <&cpu4>;
};
};
};
}; };
soc { soc {
#address-cells = <2>; #address-cells = <2>;
......
...@@ -134,6 +134,30 @@ cpu4_intc: interrupt-controller { ...@@ -134,6 +134,30 @@ cpu4_intc: interrupt-controller {
interrupt-controller; interrupt-controller;
}; };
}; };
cpu-map {
cluster0 {
core0 {
cpu = <&cpu0>;
};
core1 {
cpu = <&cpu1>;
};
core2 {
cpu = <&cpu2>;
};
core3 {
cpu = <&cpu3>;
};
core4 {
cpu = <&cpu4>;
};
};
};
}; };
soc { soc {
#address-cells = <2>; #address-cells = <2>;
......
...@@ -90,7 +90,7 @@ rtc { ...@@ -90,7 +90,7 @@ rtc {
compatible = "dlg,da9063-rtc"; compatible = "dlg,da9063-rtc";
}; };
wdt { watchdog {
compatible = "dlg,da9063-watchdog"; compatible = "dlg,da9063-watchdog";
}; };
......
...@@ -17,7 +17,7 @@ cpus { ...@@ -17,7 +17,7 @@ cpus {
#address-cells = <1>; #address-cells = <1>;
#size-cells = <0>; #size-cells = <0>;
cpu@0 { U74_0: cpu@0 {
compatible = "sifive,u74-mc", "riscv"; compatible = "sifive,u74-mc", "riscv";
reg = <0>; reg = <0>;
d-cache-block-size = <64>; d-cache-block-size = <64>;
...@@ -42,7 +42,7 @@ cpu0_intc: interrupt-controller { ...@@ -42,7 +42,7 @@ cpu0_intc: interrupt-controller {
}; };
}; };
cpu@1 { U74_1: cpu@1 {
compatible = "sifive,u74-mc", "riscv"; compatible = "sifive,u74-mc", "riscv";
reg = <1>; reg = <1>;
d-cache-block-size = <64>; d-cache-block-size = <64>;
...@@ -66,6 +66,18 @@ cpu1_intc: interrupt-controller { ...@@ -66,6 +66,18 @@ cpu1_intc: interrupt-controller {
#interrupt-cells = <1>; #interrupt-cells = <1>;
}; };
}; };
cpu-map {
cluster0 {
core0 {
cpu = <&U74_0>;
};
core1 {
cpu = <&U74_1>;
};
};
};
}; };
osc_sys: osc_sys { osc_sys: osc_sys {
......
CONFIG_ARCH_RV32I=y CONFIG_ARCH_RV32I=y
CONFIG_32BIT=y CONFIG_32BIT=y
# CONFIG_PORTABLE is not set
CONFIG_NONPORTABLE=y
...@@ -6,8 +6,17 @@ CONFIG_BPF_SYSCALL=y ...@@ -6,8 +6,17 @@ CONFIG_BPF_SYSCALL=y
CONFIG_IKCONFIG=y CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y CONFIG_IKCONFIG_PROC=y
CONFIG_CGROUPS=y CONFIG_CGROUPS=y
CONFIG_MEMCG=y
CONFIG_CGROUP_SCHED=y CONFIG_CGROUP_SCHED=y
CONFIG_CFS_BANDWIDTH=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_CGROUP_BPF=y
CONFIG_NAMESPACES=y CONFIG_NAMESPACES=y
CONFIG_USER_NS=y CONFIG_USER_NS=y
...@@ -18,6 +27,7 @@ CONFIG_EXPERT=y ...@@ -18,6 +27,7 @@ CONFIG_EXPERT=y
CONFIG_PROFILING=y CONFIG_PROFILING=y
CONFIG_SOC_MICROCHIP_POLARFIRE=y CONFIG_SOC_MICROCHIP_POLARFIRE=y
CONFIG_SOC_SIFIVE=y CONFIG_SOC_SIFIVE=y
CONFIG_SOC_STARFIVE=y
CONFIG_SOC_VIRT=y CONFIG_SOC_VIRT=y
CONFIG_SMP=y CONFIG_SMP=y
CONFIG_HOTPLUG_CPU=y CONFIG_HOTPLUG_CPU=y
...@@ -28,9 +38,11 @@ CONFIG_KVM=m ...@@ -28,9 +38,11 @@ CONFIG_KVM=m
CONFIG_JUMP_LABEL=y CONFIG_JUMP_LABEL=y
CONFIG_MODULES=y CONFIG_MODULES=y
CONFIG_MODULE_UNLOAD=y CONFIG_MODULE_UNLOAD=y
CONFIG_BLK_DEV_THROTTLING=y
CONFIG_NET=y CONFIG_NET=y
CONFIG_PACKET=y CONFIG_PACKET=y
CONFIG_UNIX=y CONFIG_UNIX=y
CONFIG_XFRM_USER=m
CONFIG_INET=y CONFIG_INET=y
CONFIG_IP_MULTICAST=y CONFIG_IP_MULTICAST=y
CONFIG_IP_ADVANCED_ROUTER=y CONFIG_IP_ADVANCED_ROUTER=y
...@@ -38,7 +50,43 @@ CONFIG_IP_PNP=y ...@@ -38,7 +50,43 @@ CONFIG_IP_PNP=y
CONFIG_IP_PNP_DHCP=y CONFIG_IP_PNP_DHCP=y
CONFIG_IP_PNP_BOOTP=y CONFIG_IP_PNP_BOOTP=y
CONFIG_IP_PNP_RARP=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_NETLINK_DIAG=y
CONFIG_CGROUP_NET_PRIO=y
CONFIG_NET_9P=y CONFIG_NET_9P=y
CONFIG_NET_9P_VIRTIO=y CONFIG_NET_9P_VIRTIO=y
CONFIG_PCI=y CONFIG_PCI=y
...@@ -57,7 +105,15 @@ CONFIG_SCSI_VIRTIO=y ...@@ -57,7 +105,15 @@ CONFIG_SCSI_VIRTIO=y
CONFIG_ATA=y CONFIG_ATA=y
CONFIG_SATA_AHCI=y CONFIG_SATA_AHCI=y
CONFIG_SATA_AHCI_PLATFORM=y CONFIG_SATA_AHCI_PLATFORM=y
CONFIG_MD=y
CONFIG_BLK_DEV_DM=m
CONFIG_DM_THIN_PROVISIONING=m
CONFIG_NETDEVICES=y CONFIG_NETDEVICES=y
CONFIG_DUMMY=m
CONFIG_MACVLAN=m
CONFIG_IPVLAN=m
CONFIG_VXLAN=m
CONFIG_VETH=m
CONFIG_VIRTIO_NET=y CONFIG_VIRTIO_NET=y
CONFIG_MACB=y CONFIG_MACB=y
CONFIG_E1000E=y CONFIG_E1000E=y
...@@ -105,7 +161,11 @@ CONFIG_RPMSG_CTRL=y ...@@ -105,7 +161,11 @@ CONFIG_RPMSG_CTRL=y
CONFIG_RPMSG_VIRTIO=y CONFIG_RPMSG_VIRTIO=y
CONFIG_EXT4_FS=y CONFIG_EXT4_FS=y
CONFIG_EXT4_FS_POSIX_ACL=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_AUTOFS4_FS=y
CONFIG_OVERLAY_FS=m
CONFIG_MSDOS_FS=y CONFIG_MSDOS_FS=y
CONFIG_VFAT_FS=y CONFIG_VFAT_FS=y
CONFIG_TMPFS=y CONFIG_TMPFS=y
...@@ -119,6 +179,10 @@ CONFIG_ROOT_NFS=y ...@@ -119,6 +179,10 @@ CONFIG_ROOT_NFS=y
CONFIG_9P_FS=y CONFIG_9P_FS=y
CONFIG_NLS_CODEPAGE_437=y CONFIG_NLS_CODEPAGE_437=y
CONFIG_NLS_ISO8859_1=m 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_USER_API_HASH=y
CONFIG_CRYPTO_DEV_VIRTIO=y CONFIG_CRYPTO_DEV_VIRTIO=y
CONFIG_PRINTK_TIME=y CONFIG_PRINTK_TIME=y
...@@ -137,7 +201,6 @@ CONFIG_DEBUG_SPINLOCK=y ...@@ -137,7 +201,6 @@ CONFIG_DEBUG_SPINLOCK=y
CONFIG_DEBUG_MUTEXES=y CONFIG_DEBUG_MUTEXES=y
CONFIG_DEBUG_RWSEMS=y CONFIG_DEBUG_RWSEMS=y
CONFIG_DEBUG_ATOMIC_SLEEP=y CONFIG_DEBUG_ATOMIC_SLEEP=y
CONFIG_STACKTRACE=y
CONFIG_DEBUG_LIST=y CONFIG_DEBUG_LIST=y
CONFIG_DEBUG_PLIST=y CONFIG_DEBUG_PLIST=y
CONFIG_DEBUG_SG=y CONFIG_DEBUG_SG=y
......
...@@ -28,6 +28,7 @@ CONFIG_EMBEDDED=y ...@@ -28,6 +28,7 @@ CONFIG_EMBEDDED=y
CONFIG_SLOB=y CONFIG_SLOB=y
# CONFIG_MMU is not set # CONFIG_MMU is not set
CONFIG_SOC_CANAAN=y CONFIG_SOC_CANAAN=y
CONFIG_NONPORTABLE=y
CONFIG_SMP=y CONFIG_SMP=y
CONFIG_NR_CPUS=2 CONFIG_NR_CPUS=2
CONFIG_CMDLINE="earlycon console=ttySIF0" CONFIG_CMDLINE="earlycon console=ttySIF0"
......
...@@ -20,6 +20,7 @@ CONFIG_EMBEDDED=y ...@@ -20,6 +20,7 @@ CONFIG_EMBEDDED=y
CONFIG_SLOB=y CONFIG_SLOB=y
# CONFIG_MMU is not set # CONFIG_MMU is not set
CONFIG_SOC_CANAAN=y CONFIG_SOC_CANAAN=y
CONFIG_NONPORTABLE=y
CONFIG_SMP=y CONFIG_SMP=y
CONFIG_NR_CPUS=2 CONFIG_NR_CPUS=2
CONFIG_CMDLINE="earlycon console=ttySIF0 root=/dev/mmcblk0p1 rootwait ro" CONFIG_CMDLINE="earlycon console=ttySIF0 root=/dev/mmcblk0p1 rootwait ro"
......
...@@ -25,6 +25,7 @@ CONFIG_EXPERT=y ...@@ -25,6 +25,7 @@ CONFIG_EXPERT=y
CONFIG_SLOB=y CONFIG_SLOB=y
# CONFIG_MMU is not set # CONFIG_MMU is not set
CONFIG_SOC_VIRT=y CONFIG_SOC_VIRT=y
CONFIG_NONPORTABLE=y
CONFIG_SMP=y CONFIG_SMP=y
CONFIG_CMDLINE="root=/dev/vda rw earlycon=uart8250,mmio,0x10000000,115200n8 console=ttyS0" CONFIG_CMDLINE="root=/dev/vda rw earlycon=uart8250,mmio,0x10000000,115200n8 console=ttyS0"
CONFIG_CMDLINE_FORCE=y CONFIG_CMDLINE_FORCE=y
......
...@@ -18,6 +18,7 @@ CONFIG_EXPERT=y ...@@ -18,6 +18,7 @@ CONFIG_EXPERT=y
CONFIG_PROFILING=y CONFIG_PROFILING=y
CONFIG_SOC_SIFIVE=y CONFIG_SOC_SIFIVE=y
CONFIG_SOC_VIRT=y CONFIG_SOC_VIRT=y
CONFIG_NONPORTABLE=y
CONFIG_ARCH_RV32I=y CONFIG_ARCH_RV32I=y
CONFIG_SMP=y CONFIG_SMP=y
CONFIG_HOTPLUG_CPU=y CONFIG_HOTPLUG_CPU=y
......
...@@ -14,40 +14,26 @@ ...@@ -14,40 +14,26 @@
#include <asm/patch.h> #include <asm/patch.h>
#include <asm/vendorid_list.h> #include <asm/vendorid_list.h>
struct errata_info { static bool errata_probe_pbmt(unsigned int stage,
char name[ERRATA_STRING_LENGTH_MAX]; unsigned long arch_id, unsigned long impid)
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)
{ {
if (arch_id != 0 || impid != 0) if (arch_id != 0 || impid != 0)
return false; return false;
return true;
}
static const struct errata_info errata_list[ERRATA_THEAD_NUMBER] = { if (stage == RISCV_ALTERNATIVES_EARLY_BOOT ||
{ stage == RISCV_ALTERNATIVES_MODULE)
.name = "memory-types", return true;
.stage = RISCV_ALTERNATIVES_EARLY_BOOT,
.check_func = errata_mt_check_func 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; u32 cpu_req_errata = 0;
int idx;
for (idx = 0; idx < ERRATA_THEAD_NUMBER; idx++) {
info = &errata_list[idx];
if ((stage == RISCV_ALTERNATIVES_MODULE || if (errata_probe_pbmt(stage, archid, impid))
info->stage == stage) && info->check_func(archid, impid)) cpu_req_errata |= (1U << ERRATA_THEAD_PBMT);
cpu_req_errata |= (1U << idx);
}
return cpu_req_errata; return cpu_req_errata;
} }
......
...@@ -67,4 +67,19 @@ ...@@ -67,4 +67,19 @@
#error "Unexpected __SIZEOF_SHORT__" #error "Unexpected __SIZEOF_SHORT__"
#endif #endif
#ifdef __ASSEMBLY__
/* Common assembly source macros */
/*
* NOP sequence
*/
.macro nops, num
.rept \num
nop
.endr
.endm
#endif /* __ASSEMBLY__ */
#endif /* _ASM_RISCV_ASM_H */ #endif /* _ASM_RISCV_ASM_H */
...@@ -13,6 +13,8 @@ ...@@ -13,6 +13,8 @@
#ifndef __ASSEMBLY__ #ifndef __ASSEMBLY__
#define nop() __asm__ __volatile__ ("nop") #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) \ #define RISCV_FENCE(p, s) \
__asm__ __volatile__ ("fence " #p "," #s : : : "memory") __asm__ __volatile__ ("fence " #p "," #s : : : "memory")
......
...@@ -68,13 +68,7 @@ asm(ALTERNATIVE_2("li %0, 0\t\nnop", \ ...@@ -68,13 +68,7 @@ asm(ALTERNATIVE_2("li %0, 0\t\nnop", \
*/ */
#define ALT_THEAD_PMA(_val) \ #define ALT_THEAD_PMA(_val) \
asm volatile(ALTERNATIVE( \ asm volatile(ALTERNATIVE( \
"nop\n\t" \ __nops(7), \
"nop\n\t" \
"nop\n\t" \
"nop\n\t" \
"nop\n\t" \
"nop\n\t" \
"nop", \
"li t3, %1\n\t" \ "li t3, %1\n\t" \
"slli t3, t3, %3\n\t" \ "slli t3, t3, %3\n\t" \
"and t3, %0, t3\n\t" \ "and t3, %0, t3\n\t" \
......
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#include <uapi/asm/hwcap.h> #include <uapi/asm/hwcap.h>
#ifndef __ASSEMBLY__ #ifndef __ASSEMBLY__
#include <linux/jump_label.h>
/* /*
* This yields a mask that user programs can use to figure out what * This yields a mask that user programs can use to figure out what
* instruction set this cpu supports. * instruction set this cpu supports.
...@@ -56,6 +57,16 @@ enum riscv_isa_ext_id { ...@@ -56,6 +57,16 @@ enum riscv_isa_ext_id {
RISCV_ISA_EXT_ID_MAX = RISCV_ISA_EXT_MAX, 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 { struct riscv_isa_ext_data {
/* Name of the extension displayed to userspace via /proc/cpuinfo */ /* Name of the extension displayed to userspace via /proc/cpuinfo */
char uprop[RISCV_ISA_EXT_NAME_LEN_MAX]; char uprop[RISCV_ISA_EXT_NAME_LEN_MAX];
...@@ -63,6 +74,20 @@ struct riscv_isa_ext_data { ...@@ -63,6 +74,20 @@ struct riscv_isa_ext_data {
unsigned int isa_ext_id; 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); unsigned long riscv_isa_extension_base(const unsigned long *isa_bitmap);
#define riscv_isa_extension_mask(ext) BIT_MASK(RISCV_ISA_EXT_##ext) #define riscv_isa_extension_mask(ext) BIT_MASK(RISCV_ISA_EXT_##ext)
......
...@@ -12,6 +12,9 @@ ...@@ -12,6 +12,9 @@
#include <asm/io.h> #include <asm/io.h>
#define PCIBIOS_MIN_IO 4
#define PCIBIOS_MIN_MEM 16
#if defined(CONFIG_PCI) && defined(CONFIG_NUMA) #if defined(CONFIG_PCI) && defined(CONFIG_NUMA)
static inline int pcibus_to_node(struct pci_bus *bus) static inline int pcibus_to_node(struct pci_bus *bus)
{ {
......
...@@ -79,8 +79,8 @@ static inline void wait_for_interrupt(void) ...@@ -79,8 +79,8 @@ static inline void wait_for_interrupt(void)
} }
struct device_node; struct device_node;
int riscv_of_processor_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); int riscv_of_parent_hartid(struct device_node *node, unsigned long *hartid);
extern void riscv_fill_hwcap(void); extern void riscv_fill_hwcap(void);
extern int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src); extern int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src);
......
...@@ -42,7 +42,7 @@ void arch_send_call_function_ipi_mask(struct cpumask *mask); ...@@ -42,7 +42,7 @@ void arch_send_call_function_ipi_mask(struct cpumask *mask);
/* Hook for the generic smp_call_function_single() routine. */ /* Hook for the generic smp_call_function_single() routine. */
void arch_send_call_function_single_ipi(int cpu); 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 */ /* Set custom IPI operations */
void riscv_set_ipi_ops(const struct riscv_ipi_ops *ops); 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) ...@@ -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) if (hartid == boot_cpu_hartid)
return 0; return 0;
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#include <linux/jump_label.h> #include <linux/jump_label.h>
#include <linux/sched/task_stack.h> #include <linux/sched/task_stack.h>
#include <asm/hwcap.h>
#include <asm/processor.h> #include <asm/processor.h>
#include <asm/ptrace.h> #include <asm/ptrace.h>
#include <asm/csr.h> #include <asm/csr.h>
...@@ -56,10 +57,9 @@ static inline void __switch_to_aux(struct task_struct *prev, ...@@ -56,10 +57,9 @@ static inline void __switch_to_aux(struct task_struct *prev,
fstate_restore(next, task_pt_regs(next)); fstate_restore(next, task_pt_regs(next));
} }
extern struct static_key_false cpu_hwcap_fpu;
static __always_inline bool has_fpu(void) 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 #else
static __always_inline bool has_fpu(void) { return false; } static __always_inline bool has_fpu(void) { return false; }
......
...@@ -20,7 +20,7 @@ struct cpu_manufacturer_info_t { ...@@ -20,7 +20,7 @@ struct cpu_manufacturer_info_t {
unsigned long vendor_id; unsigned long vendor_id;
unsigned long arch_id; unsigned long arch_id;
unsigned long imp_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 long archid, unsigned long impid,
unsigned int stage); unsigned int stage);
}; };
...@@ -40,16 +40,16 @@ static void __init_or_module riscv_fill_cpu_mfr_info(struct cpu_manufacturer_inf ...@@ -40,16 +40,16 @@ static void __init_or_module riscv_fill_cpu_mfr_info(struct cpu_manufacturer_inf
switch (cpu_mfr_info->vendor_id) { switch (cpu_mfr_info->vendor_id) {
#ifdef CONFIG_ERRATA_SIFIVE #ifdef CONFIG_ERRATA_SIFIVE
case SIFIVE_VENDOR_ID: case SIFIVE_VENDOR_ID:
cpu_mfr_info->vendor_patch_func = sifive_errata_patch_func; cpu_mfr_info->patch_func = sifive_errata_patch_func;
break; break;
#endif #endif
#ifdef CONFIG_ERRATA_THEAD #ifdef CONFIG_ERRATA_THEAD
case THEAD_VENDOR_ID: case THEAD_VENDOR_ID:
cpu_mfr_info->vendor_patch_func = thead_errata_patch_func; cpu_mfr_info->patch_func = thead_errata_patch_func;
break; break;
#endif #endif
default: 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, ...@@ -68,13 +68,13 @@ static void __init_or_module _apply_alternatives(struct alt_entry *begin,
riscv_cpufeature_patch_func(begin, end, stage); riscv_cpufeature_patch_func(begin, end, stage);
if (!cpu_mfr_info.vendor_patch_func) if (!cpu_mfr_info.patch_func)
return; return;
cpu_mfr_info.vendor_patch_func(begin, end, cpu_mfr_info.patch_func(begin, end,
cpu_mfr_info.arch_id, cpu_mfr_info.arch_id,
cpu_mfr_info.imp_id, cpu_mfr_info.imp_id,
stage); stage);
} }
void __init apply_boot_alternatives(void) void __init apply_boot_alternatives(void)
......
...@@ -14,37 +14,36 @@ ...@@ -14,37 +14,36 @@
* Returns the hart ID of the given device tree node, or -ENODEV if the node * 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. * 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; const char *isa;
u32 hart;
if (!of_device_is_compatible(node, "riscv")) { if (!of_device_is_compatible(node, "riscv")) {
pr_warn("Found incompatible CPU\n"); pr_warn("Found incompatible CPU\n");
return -ENODEV; return -ENODEV;
} }
hart = of_get_cpu_hwid(node, 0); *hart = (unsigned long) of_get_cpu_hwid(node, 0);
if (hart == ~0U) { if (*hart == ~0UL) {
pr_warn("Found CPU without hart ID\n"); pr_warn("Found CPU without hart ID\n");
return -ENODEV; return -ENODEV;
} }
if (!of_device_is_available(node)) { 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; return -ENODEV;
} }
if (of_property_read_string(node, "riscv,isa", &isa)) { 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; return -ENODEV;
} }
if (isa[0] != 'r' || isa[1] != 'v') { 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 -ENODEV;
} }
return hart; return 0;
} }
/* /*
...@@ -53,11 +52,16 @@ int riscv_of_processor_hartid(struct device_node *node) ...@@ -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 * 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. * 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) { for (; node; node = node->parent) {
if (of_device_is_compatible(node, "riscv")) if (of_device_is_compatible(node, "riscv")) {
return riscv_of_processor_hartid(node); rc = riscv_of_processor_hartid(node, hartid);
if (!rc)
return 0;
}
} }
return -1; return -1;
......
...@@ -65,7 +65,7 @@ static int sbi_hsm_hart_get_status(unsigned long hartid) ...@@ -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) static int sbi_cpu_start(unsigned int cpuid, struct task_struct *tidle)
{ {
unsigned long boot_addr = __pa_symbol(secondary_start_sbi); 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; unsigned long hsm_data;
struct sbi_hart_boot_data *bdata = &per_cpu(boot_data, cpuid); struct sbi_hart_boot_data *bdata = &per_cpu(boot_data, cpuid);
...@@ -107,7 +107,7 @@ static void sbi_cpu_stop(void) ...@@ -107,7 +107,7 @@ static void sbi_cpu_stop(void)
static int sbi_cpu_is_stopped(unsigned int cpuid) static int sbi_cpu_is_stopped(unsigned int cpuid)
{ {
int rc; int rc;
int hartid = cpuid_to_hartid_map(cpuid); unsigned long hartid = cpuid_to_hartid_map(cpuid);
rc = sbi_hsm_hart_get_status(hartid); rc = sbi_hsm_hart_get_status(hartid);
......
...@@ -18,7 +18,7 @@ void *__cpu_spinwait_task_pointer[NR_CPUS] __section(".data"); ...@@ -18,7 +18,7 @@ void *__cpu_spinwait_task_pointer[NR_CPUS] __section(".data");
static void cpu_update_secondary_bootdata(unsigned int cpuid, static void cpu_update_secondary_bootdata(unsigned int cpuid,
struct task_struct *tidle) 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 * 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, ...@@ -27,7 +27,7 @@ static void cpu_update_secondary_bootdata(unsigned int cpuid,
* spinwait booting is not the recommended approach for any platforms * spinwait booting is not the recommended approach for any platforms
* booting Linux in S-mode and can be disabled in the future. * 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; return;
/* Make sure tidle is updated */ /* Make sure tidle is updated */
......
...@@ -27,9 +27,8 @@ unsigned long elf_hwcap __read_mostly; ...@@ -27,9 +27,8 @@ unsigned long elf_hwcap __read_mostly;
/* Host ISA bitmap */ /* Host ISA bitmap */
static DECLARE_BITMAP(riscv_isa, RISCV_ISA_EXT_MAX) __read_mostly; static DECLARE_BITMAP(riscv_isa, RISCV_ISA_EXT_MAX) __read_mostly;
#ifdef CONFIG_FPU __ro_after_init DEFINE_STATIC_KEY_ARRAY_FALSE(riscv_isa_ext_keys, RISCV_ISA_EXT_KEY_MAX);
__ro_after_init DEFINE_STATIC_KEY_FALSE(cpu_hwcap_fpu); EXPORT_SYMBOL(riscv_isa_ext_keys);
#endif
/** /**
* riscv_isa_extension_base() - Get base extension word * riscv_isa_extension_base() - Get base extension word
...@@ -73,8 +72,9 @@ void __init riscv_fill_hwcap(void) ...@@ -73,8 +72,9 @@ void __init riscv_fill_hwcap(void)
struct device_node *node; struct device_node *node;
const char *isa; const char *isa;
char print_str[NUM_ALPHA_EXTS + 1]; char print_str[NUM_ALPHA_EXTS + 1];
int i, j; int i, j, rc;
static unsigned long isa2hwcap[256] = {0}; static unsigned long isa2hwcap[256] = {0};
unsigned long hartid;
isa2hwcap['i'] = isa2hwcap['I'] = COMPAT_HWCAP_ISA_I; isa2hwcap['i'] = isa2hwcap['I'] = COMPAT_HWCAP_ISA_I;
isa2hwcap['m'] = isa2hwcap['M'] = COMPAT_HWCAP_ISA_M; isa2hwcap['m'] = isa2hwcap['M'] = COMPAT_HWCAP_ISA_M;
...@@ -92,7 +92,8 @@ void __init riscv_fill_hwcap(void) ...@@ -92,7 +92,8 @@ void __init riscv_fill_hwcap(void)
DECLARE_BITMAP(this_isa, RISCV_ISA_EXT_MAX); DECLARE_BITMAP(this_isa, RISCV_ISA_EXT_MAX);
const char *temp; const char *temp;
if (riscv_of_processor_hartid(node) < 0) rc = riscv_of_processor_hartid(node, &hartid);
if (rc < 0)
continue; continue;
if (of_property_read_string(node, "riscv,isa", &isa)) { if (of_property_read_string(node, "riscv,isa", &isa)) {
...@@ -238,19 +239,15 @@ void __init riscv_fill_hwcap(void) ...@@ -238,19 +239,15 @@ void __init riscv_fill_hwcap(void)
print_str[j++] = (char)('a' + i); print_str[j++] = (char)('a' + i);
pr_info("riscv: ELF capabilities %s\n", print_str); pr_info("riscv: ELF capabilities %s\n", print_str);
#ifdef CONFIG_FPU for_each_set_bit(i, riscv_isa, RISCV_ISA_EXT_MAX) {
if (elf_hwcap & (COMPAT_HWCAP_ISA_F | COMPAT_HWCAP_ISA_D)) j = riscv_isa_ext2key(i);
static_branch_enable(&cpu_hwcap_fpu); if (j >= 0)
#endif static_branch_enable(&riscv_isa_ext_keys[j]);
}
} }
#ifdef CONFIG_RISCV_ALTERNATIVE #ifdef CONFIG_RISCV_ALTERNATIVE
struct cpufeature_info { static bool __init_or_module cpufeature_probe_svpbmt(unsigned int stage)
char name[ERRATA_STRING_LENGTH_MAX];
bool (*check_func)(unsigned int stage);
};
static bool __init_or_module cpufeature_svpbmt_check_func(unsigned int stage)
{ {
#ifdef CONFIG_RISCV_ISA_SVPBMT #ifdef CONFIG_RISCV_ISA_SVPBMT
switch (stage) { switch (stage) {
...@@ -264,26 +261,19 @@ static bool __init_or_module cpufeature_svpbmt_check_func(unsigned int stage) ...@@ -264,26 +261,19 @@ static bool __init_or_module cpufeature_svpbmt_check_func(unsigned int stage)
return false; return false;
} }
static const struct cpufeature_info __initdata_or_module /*
cpufeature_list[CPUFEATURE_NUMBER] = { * Probe presence of individual extensions.
{ *
.name = "svpbmt", * This code may also be executed before kernel relocation, so we cannot use
.check_func = cpufeature_svpbmt_check_func * 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) static u32 __init_or_module cpufeature_probe(unsigned int stage)
{ {
const struct cpufeature_info *info;
u32 cpu_req_feature = 0; u32 cpu_req_feature = 0;
int idx;
for (idx = 0; idx < CPUFEATURE_NUMBER; idx++) { if (cpufeature_probe_svpbmt(stage))
info = &cpufeature_list[idx]; cpu_req_feature |= (1U << CPUFEATURE_SVPBMT);
if (info->check_func(stage))
cpu_req_feature |= (1U << idx);
}
return cpu_req_feature; return cpu_req_feature;
} }
......
...@@ -47,7 +47,7 @@ static struct { ...@@ -47,7 +47,7 @@ static struct {
unsigned long bits ____cacheline_aligned; unsigned long bits ____cacheline_aligned;
} ipi_data[NR_CPUS] __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; int i;
...@@ -55,7 +55,7 @@ int riscv_hartid_to_cpuid(int hartid) ...@@ -55,7 +55,7 @@ int riscv_hartid_to_cpuid(int hartid)
if (cpuid_to_hartid_map(i) == hartid) if (cpuid_to_hartid_map(i) == hartid)
return i; 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; return -ENOENT;
} }
......
...@@ -72,15 +72,16 @@ void __init smp_prepare_cpus(unsigned int max_cpus) ...@@ -72,15 +72,16 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
void __init setup_smp(void) void __init setup_smp(void)
{ {
struct device_node *dn; struct device_node *dn;
int hart; unsigned long hart;
bool found_boot_cpu = false; bool found_boot_cpu = false;
int cpuid = 1; int cpuid = 1;
int rc;
cpu_set_ops(0); cpu_set_ops(0);
for_each_of_cpu_node(dn) { for_each_of_cpu_node(dn) {
hart = riscv_of_processor_hartid(dn); rc = riscv_of_processor_hartid(dn, &hart);
if (hart < 0) if (rc < 0)
continue; continue;
if (hart == cpuid_to_hartid_map(0)) { if (hart == cpuid_to_hartid_map(0)) {
...@@ -90,7 +91,7 @@ void __init setup_smp(void) ...@@ -90,7 +91,7 @@ void __init setup_smp(void)
continue; continue;
} }
if (cpuid >= NR_CPUS) { if (cpuid >= NR_CPUS) {
pr_warn("Invalid cpuid [%d] for hartid [%d]\n", pr_warn("Invalid cpuid [%d] for hartid [%lu]\n",
cpuid, hart); cpuid, hart);
continue; continue;
} }
......
...@@ -18,9 +18,8 @@ static long riscv_sys_mmap(unsigned long addr, unsigned long len, ...@@ -18,9 +18,8 @@ static long riscv_sys_mmap(unsigned long addr, unsigned long len,
if (unlikely(offset & (~PAGE_MASK >> page_shift_offset))) if (unlikely(offset & (~PAGE_MASK >> page_shift_offset)))
return -EINVAL; return -EINVAL;
if ((prot & PROT_WRITE) && (prot & PROT_EXEC)) if (unlikely((prot & PROT_WRITE) && !(prot & PROT_READ)))
if (unlikely(!(prot & PROT_READ))) return -EINVAL;
return -EINVAL;
return ksys_mmap_pgoff(addr, len, prot, flags, fd, return ksys_mmap_pgoff(addr, len, prot, flags, fd,
offset >> (PAGE_SHIFT - page_shift_offset)); offset >> (PAGE_SHIFT - page_shift_offset));
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
#include <linux/mm.h> #include <linux/mm.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/irq.h> #include <linux/irq.h>
#include <linux/kexec.h>
#include <asm/asm-prototypes.h> #include <asm/asm-prototypes.h>
#include <asm/bug.h> #include <asm/bug.h>
...@@ -44,6 +45,9 @@ void die(struct pt_regs *regs, const char *str) ...@@ -44,6 +45,9 @@ void die(struct pt_regs *regs, const char *str)
ret = notify_die(DIE_OOPS, str, regs, 0, regs->cause, SIGSEGV); ret = notify_die(DIE_OOPS, str, regs, 0, regs->cause, SIGSEGV);
if (regs && kexec_should_crash(current))
crash_kexec(regs);
bust_spinlocks(0); bust_spinlocks(0);
add_taint(TAINT_DIE, LOCKDEP_NOW_UNRELIABLE); add_taint(TAINT_DIE, LOCKDEP_NOW_UNRELIABLE);
spin_unlock_irq(&die_lock); spin_unlock_irq(&die_lock);
......
...@@ -101,20 +101,21 @@ static irqreturn_t riscv_timer_interrupt(int irq, void *dev_id) ...@@ -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) 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 device_node *child;
struct irq_domain *domain; struct irq_domain *domain;
hartid = riscv_of_processor_hartid(n); error = riscv_of_processor_hartid(n, &hartid);
if (hartid < 0) { if (error < 0) {
pr_warn("Not valid hartid for node [%pOF] error = [%d]\n", pr_warn("Not valid hartid for node [%pOF] error = [%lu]\n",
n, hartid); n, hartid);
return hartid; return error;
} }
cpuid = riscv_hartid_to_cpuid(hartid); cpuid = riscv_hartid_to_cpuid(hartid);
if (cpuid < 0) { if (cpuid < 0) {
pr_warn("Invalid cpuid for hartid [%d]\n", hartid); pr_warn("Invalid cpuid for hartid [%lu]\n", hartid);
return cpuid; return cpuid;
} }
...@@ -140,7 +141,7 @@ static int __init riscv_timer_init_dt(struct device_node *n) ...@@ -140,7 +141,7 @@ static int __init riscv_timer_init_dt(struct device_node *n)
return -ENODEV; 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); __func__, cpuid, hartid);
error = clocksource_register_hz(&riscv_clocksource, riscv_timebase); error = clocksource_register_hz(&riscv_clocksource, riscv_timebase);
if (error) { if (error) {
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#include <asm/efi.h> #include <asm/efi.h>
#include <asm/sections.h> #include <asm/sections.h>
#include <asm/unaligned.h>
#include "efistub.h" #include "efistub.h"
...@@ -29,7 +30,7 @@ static int get_boot_hartid_from_fdt(void) ...@@ -29,7 +30,7 @@ static int get_boot_hartid_from_fdt(void)
{ {
const void *fdt; const void *fdt;
int chosen_node, len; int chosen_node, len;
const fdt32_t *prop; const void *prop;
fdt = get_efi_config_table(DEVICE_TREE_GUID); fdt = get_efi_config_table(DEVICE_TREE_GUID);
if (!fdt) if (!fdt)
...@@ -40,10 +41,16 @@ static int get_boot_hartid_from_fdt(void) ...@@ -40,10 +41,16 @@ static int get_boot_hartid_from_fdt(void)
return -EINVAL; return -EINVAL;
prop = fdt_getprop((void *)fdt, chosen_node, "boot-hartid", &len); 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; return -EINVAL;
hartid = fdt32_to_cpu(*prop);
return 0; return 0;
} }
......
...@@ -95,10 +95,11 @@ static const struct irq_domain_ops riscv_intc_domain_ops = { ...@@ -95,10 +95,11 @@ static const struct irq_domain_ops riscv_intc_domain_ops = {
static int __init riscv_intc_init(struct device_node *node, static int __init riscv_intc_init(struct device_node *node,
struct device_node *parent) struct device_node *parent)
{ {
int rc, hartid; int rc;
unsigned long hartid;
hartid = riscv_of_parent_hartid(node); rc = riscv_of_parent_hartid(node, &hartid);
if (hartid < 0) { if (rc < 0) {
pr_warn("unable to find hart id for %pOF\n", node); pr_warn("unable to find hart id for %pOF\n", node);
return 0; return 0;
} }
......
...@@ -374,7 +374,8 @@ static int __init __plic_init(struct device_node *node, ...@@ -374,7 +374,8 @@ static int __init __plic_init(struct device_node *node,
for (i = 0; i < nr_contexts; i++) { for (i = 0; i < nr_contexts; i++) {
struct of_phandle_args parent; struct of_phandle_args parent;
irq_hw_number_t hwirq; irq_hw_number_t hwirq;
int cpu, hartid; int cpu;
unsigned long hartid;
if (of_irq_parse_one(node, i, &parent)) { if (of_irq_parse_one(node, i, &parent)) {
pr_err("failed to parse parent for context %d.\n", i); pr_err("failed to parse parent for context %d.\n", i);
...@@ -398,8 +399,8 @@ static int __init __plic_init(struct device_node *node, ...@@ -398,8 +399,8 @@ static int __init __plic_init(struct device_node *node,
continue; continue;
} }
hartid = riscv_of_parent_hartid(parent.np); error = riscv_of_parent_hartid(parent.np, &hartid);
if (hartid < 0) { if (error < 0) {
pr_warn("failed to parse hart ID for context %d.\n", i); pr_warn("failed to parse hart ID for context %d.\n", i);
continue; continue;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment