* [RFC PATCH V2 01/38] riscv: u64ilp32: Unify vdso32 & compat_vdso into vdso/Makefile
2023-11-12 6:14 [RFC PATCH V2 00/38] rv64ilp32: Running ILP32 on RV64 ISA guoren
@ 2023-11-12 6:14 ` guoren
2023-11-12 6:14 ` [RFC PATCH V2 02/38] riscv: u64ilp32: Remove compat_vdso/ guoren
` (39 subsequent siblings)
40 siblings, 0 replies; 42+ messages in thread
From: guoren @ 2023-11-12 6:14 UTC (permalink / raw)
To: arnd, guoren, palmer, tglx, conor.dooley, heiko, apatel, atishp,
bjorn, paul.walmsley, anup, jiawei, liweiwei, wefu, U2FsdGVkX1,
wangjunqiang, kito.cheng, andy.chiu, vincent.chen, greentime.hu,
wuwei2016, jrtc27, luto, fweimer, catalin.marinas, hjl.tools
Cc: linux-arch, linux-kernel, linux-riscv, Guo Ren
From: Guo Ren <guoren@linux.alibaba.com>
Linux kernel abi and vdso abi could be different, and current
vdso/Makefile force vdso use the same abi as the kernel. It isn't
suitable for the next s64ilp32 patch series because s64ilp32 uses
64ilp32 abi in the kernel but still uses 32ilp32 in the userspace. This
patch unifies vdso32 & compat_vdso into vdso/Makefile to solve this
problem, similar to Powerpc's vdso framework.
Before this:
- vdso/
- vdso/vdso.S
- vdso/gen_vdso_offsets.sh
- compat_vdso/compat_vdso.S
- compat_vdso/gen_compat_vdso_offsets.sh
- vdso.c
After this:
- vdso/
- vdso64.S
- vdso/gen_vdso64_offsets.sh
- vdso32.S
- vdso/gen_vdso32_offsets.sh
- vdso.c
Signed-off-by: Guo Ren <guoren@linux.alibaba.com>
Signed-off-by: Guo Ren <guoren@kernel.org>
---
arch/riscv/Kconfig | 11 ++
arch/riscv/Makefile | 15 +-
arch/riscv/include/asm/vdso.h | 34 +++-
arch/riscv/include/asm/vdso/gettimeofday.h | 7 +-
arch/riscv/kernel/Makefile | 3 +-
arch/riscv/kernel/compat_signal.c | 2 +-
arch/riscv/kernel/vdso.c | 4 +-
arch/riscv/kernel/vdso/Makefile | 179 ++++++++++++------
..._vdso_offsets.sh => gen_vdso32_offsets.sh} | 2 +-
arch/riscv/kernel/vdso/gen_vdso64_offsets.sh | 5 +
arch/riscv/kernel/vdso32.S | 8 +
arch/riscv/kernel/{vdso/vdso.S => vdso64.S} | 8 +-
12 files changed, 197 insertions(+), 81 deletions(-)
rename arch/riscv/kernel/vdso/{gen_vdso_offsets.sh => gen_vdso32_offsets.sh} (78%)
create mode 100755 arch/riscv/kernel/vdso/gen_vdso64_offsets.sh
create mode 100644 arch/riscv/kernel/vdso32.S
rename arch/riscv/kernel/{vdso/vdso.S => vdso64.S} (73%)
diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
index 4c07b9189c86..4b91e2ba7815 100644
--- a/arch/riscv/Kconfig
+++ b/arch/riscv/Kconfig
@@ -5,9 +5,11 @@
#
config 64BIT
+ select VDSO64
bool
config 32BIT
+ select VDSO32
bool
config RISCV
@@ -278,6 +280,14 @@ config AS_HAS_OPTION_ARCH
depends on $(as-instr, .option arch$(comma) +m)
depends on !$(as-instr, .option arch$(comma) -i)
+config VDSO32
+ bool
+ depends on MMU
+
+config VDSO64
+ bool
+ depends on MMU
+
source "arch/riscv/Kconfig.socs"
source "arch/riscv/Kconfig.errata"
@@ -696,6 +706,7 @@ config CRASH_DUMP
config COMPAT
bool "Kernel support for 32-bit U-mode"
default 64BIT
+ select VDSO32
depends on 64BIT && MMU
help
This option enables support for a 32-bit U-mode running under a 64-bit
diff --git a/arch/riscv/Makefile b/arch/riscv/Makefile
index 6ec6d52a4180..3b7d5ebf3c78 100644
--- a/arch/riscv/Makefile
+++ b/arch/riscv/Makefile
@@ -136,18 +136,19 @@ libs-$(CONFIG_EFI_STUB) += $(objtree)/drivers/firmware/efi/libstub/lib.a
PHONY += vdso_install
vdso_install:
- $(Q)$(MAKE) $(build)=arch/riscv/kernel/vdso $@
- $(if $(CONFIG_COMPAT),$(Q)$(MAKE) \
- $(build)=arch/riscv/kernel/compat_vdso compat_$@)
+ $(if $(CONFIG_VDSO32),$(Q)$(MAKE) \
+ $(build)=arch/riscv/kernel/vdso vdso32_install
+ $(if $(CONFIG_VDSO64),$(Q)$(MAKE) \
+ $(build)=arch/riscv/kernel/vdso vdso64_install
ifeq ($(KBUILD_EXTMOD),)
ifeq ($(CONFIG_MMU),y)
prepare: vdso_prepare
vdso_prepare: prepare0
- $(Q)$(MAKE) $(build)=arch/riscv/kernel/vdso include/generated/vdso-offsets.h
- $(if $(CONFIG_COMPAT),$(Q)$(MAKE) \
- $(build)=arch/riscv/kernel/compat_vdso include/generated/compat_vdso-offsets.h)
-
+ $(if $(CONFIG_VDSO32),$(Q)$(MAKE) \
+ $(build)=arch/riscv/kernel/vdso include/generated/vdso32-offsets.h)
+ $(if $(CONFIG_VDSO64),$(Q)$(MAKE) \
+ $(build)=arch/riscv/kernel/vdso include/generated/vdso64-offsets.h)
endif
endif
diff --git a/arch/riscv/include/asm/vdso.h b/arch/riscv/include/asm/vdso.h
index f891478829a5..305ddc6de21c 100644
--- a/arch/riscv/include/asm/vdso.h
+++ b/arch/riscv/include/asm/vdso.h
@@ -17,22 +17,36 @@
#define __VVAR_PAGES 2
#ifndef __ASSEMBLY__
-#include <generated/vdso-offsets.h>
-#define VDSO_SYMBOL(base, name) \
- (void __user *)((unsigned long)(base) + __vdso_##name##_offset)
+#ifdef CONFIG_VDSO64
+#include <generated/vdso64-offsets.h>
-#ifdef CONFIG_COMPAT
-#include <generated/compat_vdso-offsets.h>
+#define VDSO64_SYMBOL(base, name) \
+ (void __user *)((unsigned long)(base) + rv64__vdso_##name##_offset)
-#define COMPAT_VDSO_SYMBOL(base, name) \
- (void __user *)((unsigned long)(base) + compat__vdso_##name##_offset)
+extern char vdso64_start[], vdso64_end[];
-extern char compat_vdso_start[], compat_vdso_end[];
+#endif /* CONFIG_VDSO64 */
-#endif /* CONFIG_COMPAT */
+#ifdef CONFIG_VDSO32
+#include <generated/vdso32-offsets.h>
-extern char vdso_start[], vdso_end[];
+#define VDSO32_SYMBOL(base, name) \
+ (void __user *)((unsigned long)(base) + rv32__vdso_##name##_offset)
+
+extern char vdso32_start[], vdso32_end[];
+
+#endif /* CONFIG_VDSO32 */
+
+#ifdef CONFIG_64BIT
+#define vdso_start vdso64_start
+#define vdso_end vdso64_end
+#define VDSO_SYMBOL VDSO64_SYMBOL
+#else /* CONFIG_64BIT */
+#define vdso_start vdso32_start
+#define vdso_end vdso32_end
+#define VDSO_SYMBOL VDSO32_SYMBOL
+#endif /* CONFIG_64BIT */
#endif /* !__ASSEMBLY__ */
diff --git a/arch/riscv/include/asm/vdso/gettimeofday.h b/arch/riscv/include/asm/vdso/gettimeofday.h
index ba3283cf7acc..a7ae8576797b 100644
--- a/arch/riscv/include/asm/vdso/gettimeofday.h
+++ b/arch/riscv/include/asm/vdso/gettimeofday.h
@@ -17,6 +17,7 @@
#define VDSO_HAS_CLOCK_GETRES 1
+#ifdef __NR_gettimeofday
static __always_inline
int gettimeofday_fallback(struct __kernel_old_timeval *_tv,
struct timezone *_tz)
@@ -33,7 +34,9 @@ int gettimeofday_fallback(struct __kernel_old_timeval *_tv,
return ret;
}
+#endif
+#ifdef __NR_clock_gettime
static __always_inline
long clock_gettime_fallback(clockid_t _clkid, struct __kernel_timespec *_ts)
{
@@ -49,7 +52,9 @@ long clock_gettime_fallback(clockid_t _clkid, struct __kernel_timespec *_ts)
return ret;
}
+#endif
+#ifdef __NR_clock_getres
static __always_inline
int clock_getres_fallback(clockid_t _clkid, struct __kernel_timespec *_ts)
{
@@ -65,7 +70,7 @@ int clock_getres_fallback(clockid_t _clkid, struct __kernel_timespec *_ts)
return ret;
}
-
+#endif
#endif /* CONFIG_GENERIC_TIME_VSYSCALL */
static __always_inline u64 __arch_get_hw_counter(s32 clock_mode,
diff --git a/arch/riscv/kernel/Makefile b/arch/riscv/kernel/Makefile
index 506cc4a9a45a..23032ac7f51d 100644
--- a/arch/riscv/kernel/Makefile
+++ b/arch/riscv/kernel/Makefile
@@ -57,6 +57,8 @@ obj-y += cacheinfo.o
obj-y += patch.o
obj-y += probes/
obj-$(CONFIG_MMU) += vdso.o vdso/
+obj-$(CONFIG_VDSO64) += vdso64.o
+obj-$(CONFIG_VDSO32) += vdso32.o
obj-$(CONFIG_RISCV_M_MODE) += traps_misaligned.o
obj-$(CONFIG_FPU) += fpu.o
@@ -94,7 +96,6 @@ obj-$(CONFIG_JUMP_LABEL) += jump_label.o
obj-$(CONFIG_EFI) += efi.o
obj-$(CONFIG_COMPAT) += compat_syscall_table.o
obj-$(CONFIG_COMPAT) += compat_signal.o
-obj-$(CONFIG_COMPAT) += compat_vdso/
obj-$(CONFIG_64BIT) += pi/
obj-$(CONFIG_ACPI) += acpi.o
diff --git a/arch/riscv/kernel/compat_signal.c b/arch/riscv/kernel/compat_signal.c
index 6ec4e34255a9..8dea2012836e 100644
--- a/arch/riscv/kernel/compat_signal.c
+++ b/arch/riscv/kernel/compat_signal.c
@@ -217,7 +217,7 @@ int compat_setup_rt_frame(struct ksignal *ksig, sigset_t *set,
if (err)
return -EFAULT;
- regs->ra = (unsigned long)COMPAT_VDSO_SYMBOL(
+ regs->ra = (unsigned long)VDSO32_SYMBOL(
current->mm->context.vdso, rt_sigreturn);
/*
diff --git a/arch/riscv/kernel/vdso.c b/arch/riscv/kernel/vdso.c
index 2cf76218a5bd..dc03393bf900 100644
--- a/arch/riscv/kernel/vdso.c
+++ b/arch/riscv/kernel/vdso.c
@@ -194,8 +194,8 @@ static struct vm_special_mapping rv_compat_vdso_maps[] __ro_after_init = {
static struct __vdso_info compat_vdso_info __ro_after_init = {
.name = "compat_vdso",
- .vdso_code_start = compat_vdso_start,
- .vdso_code_end = compat_vdso_end,
+ .vdso_code_start = vdso32_start,
+ .vdso_code_end = vdso32_end,
.dm = &rv_compat_vdso_maps[RV_VDSO_MAP_VVAR],
.cm = &rv_compat_vdso_maps[RV_VDSO_MAP_VDSO],
};
diff --git a/arch/riscv/kernel/vdso/Makefile b/arch/riscv/kernel/vdso/Makefile
index 6b1dba11bf6d..a9720e816e1f 100644
--- a/arch/riscv/kernel/vdso/Makefile
+++ b/arch/riscv/kernel/vdso/Makefile
@@ -1,85 +1,156 @@
# SPDX-License-Identifier: GPL-2.0-only
-# Copied from arch/tile/kernel/vdso/Makefile
# Include the generic Makefile to check the built vdso.
include $(srctree)/lib/vdso/Makefile
-# Symbols present in the vdso
-vdso-syms = rt_sigreturn
-ifdef CONFIG_64BIT
-vdso-syms += vgettimeofday
-endif
-vdso-syms += getcpu
-vdso-syms += flush_icache
-vdso-syms += hwprobe
-vdso-syms += sys_hwprobe
-# Files to link into the vdso
-obj-vdso = $(patsubst %, %.o, $(vdso-syms)) note.o
+VDSO_CC := $(CC)
+VDSO_LD := $(LD)
+
+# Disable profiling and instrumentation for VDSO code
+GCOV_PROFILE := n
+KCOV_INSTRUMENT := n
+KASAN_SANITIZE := n
+UBSAN_SANITIZE := n
ccflags-y := -fno-stack-protector
ccflags-y += -DDISABLE_BRANCH_PROFILING
-ifneq ($(c-gettimeofday-y),)
- CFLAGS_vgettimeofday.o += -fPIC -include $(c-gettimeofday-y)
+CPPFLAGS_vdso.lds += -P -C -U$(ARCH)
+ifneq ($(filter vgettimeofday, $(vdso-cc-syms)),)
+ CPPFLAGS_vdso.lds += -DHAS_VGETTIMEOFDAY
endif
-CFLAGS_hwprobe.o += -fPIC
+# strip rule for the .so file
+$(obj)/%.so: OBJCOPYFLAGS := -S
+$(obj)/%.so: $(obj)/%.so.dbg FORCE
+ $(call if_changed,objcopy)
-# Build rules
-targets := $(obj-vdso) vdso.so vdso.so.dbg vdso.lds
-obj-vdso := $(addprefix $(obj)/, $(obj-vdso))
+# install commands for the unstripped file
+quiet_cmd_vdso_install = INSTALL $@
+ cmd_vdso_install = cp $(obj)/$@.dbg $(MODLIB)/vdso/$@
-obj-y += vdso.o
-CPPFLAGS_vdso.lds += -P -C -U$(ARCH)
-ifneq ($(filter vgettimeofday, $(vdso-syms)),)
-CPPFLAGS_vdso.lds += -DHAS_VGETTIMEOFDAY
-endif
+# Symbols present in the vdso
+ifdef CONFIG_VDSO64
+vdso64-as-syms = rt_sigreturn
+vdso64-as-syms += getcpu
+vdso64-as-syms += flush_icache
+vdso64-as-syms += sys_hwprobe
-# Disable -pg to prevent insert call site
-CFLAGS_REMOVE_vgettimeofday.o = $(CC_FLAGS_FTRACE)
+vdso64-cc-syms = vgettimeofday
+vdso64-cc-syms += hwprobe
-# Disable profiling and instrumentation for VDSO code
-GCOV_PROFILE := n
-KCOV_INSTRUMENT := n
-KASAN_SANITIZE := n
-UBSAN_SANITIZE := n
+obj-as-vdso64 = $(patsubst %, %-64.o, $(vdso64-as-syms)) note-64.o
+obj-as-vdso64 := $(addprefix $(obj)/, $(obj-as-vdso64))
-# Force dependency
-$(obj)/vdso.o: $(obj)/vdso.so
+obj-cc-vdso64 = $(patsubst %, %-64.o, $(vdso64-cc-syms))
+obj-cc-vdso64 := $(addprefix $(obj)/, $(obj-cc-vdso64))
-# link rule for the .so file, .lds has to be first
-$(obj)/vdso.so.dbg: $(obj)/vdso.lds $(obj-vdso) FORCE
- $(call if_changed,vdsold)
-LDFLAGS_vdso.so.dbg = -shared -S -soname=linux-vdso.so.1 \
+targets += $(obj-as-vdso64) $(obj-cc-vdso64) vdso64.so vdso64.so.dbg vdso64.lds
+
+$(obj)/vdso64.so.dbg: $(obj)/vdso.lds $(obj-as-vdso64) $(obj-cc-vdso64) FORCE
+ $(call if_changed,vdso64ld)
+LDFLAGS_vdso64.so.dbg = -shared -S -soname=linux-vdso64.so.1 \
--build-id=sha1 --hash-style=both --eh-frame-hdr
+# The DSO images are built using a special linker script
+# Make sure only to export the intended __vdso_xxx symbol offsets.
+quiet_cmd_vdso64ld = VDSO64LD $@
+ cmd_vdso64ld = $(VDSO_LD) $(ld_flags) $(VDSO64_LD_FLAGS) -T $(filter-out FORCE,$^) -o $@.tmp && \
+ $(OBJCOPY) $(patsubst %, -G __vdso_%, $(vdso64-as-syms) $(vdso64-cc-syms)) $@.tmp $@ && \
+ rm $@.tmp
-# strip rule for the .so file
-$(obj)/%.so: OBJCOPYFLAGS := -S
-$(obj)/%.so: $(obj)/%.so.dbg FORCE
- $(call if_changed,objcopy)
+# actual build commands
+quiet_cmd_vdso64as = VDSO64AS $@
+ cmd_vdso64as = $(VDSO_CC) $(a_flags) $(VDSO64_CC_FLAGS) -c -o $@ $<
+quiet_cmd_vdso64cc = VDSO64CC $@
+ cmd_vdso64cc = $(VDSO_CC) $(c_flags) $(VDSO64_CC_FLAGS) -c -o $@ $<
+
+# Force dependency
+$(obj)/vdso64.o: $(obj)/vdso64.so
+
+$(obj-as-vdso64): %-64.o: %.S FORCE
+ $(call if_changed_dep,vdso64as)
+$(obj-cc-vdso64): %-64.o: %.c FORCE
+ $(call if_changed_dep,vdso64cc)
+
+CFLAGS_vgettimeofday-64.o += -fPIC -include $(c-gettimeofday-y)
+# Disable -pg to prevent insert call site
+CFLAGS_REMOVE_vgettimeofday-64.o = $(CC_FLAGS_FTRACE)
+
+CFLAGS_hwprobe-64.o += -fPIC
# Generate VDSO offsets using helper script
-gen-vdsosym := $(srctree)/$(src)/gen_vdso_offsets.sh
-quiet_cmd_vdsosym = VDSOSYM $@
- cmd_vdsosym = $(NM) $< | $(gen-vdsosym) | LC_ALL=C sort > $@
+gen-vdso64sym := $(srctree)/$(src)/gen_vdso64_offsets.sh
+quiet_cmd_vdso64sym = VDSO64SYM $@
+ cmd_vdso64sym = $(NM) $< | $(gen-vdso64sym) | LC_ALL=C sort > $@
-include/generated/vdso-offsets.h: $(obj)/vdso.so.dbg FORCE
- $(call if_changed,vdsosym)
+include/generated/vdso64-offsets.h: $(obj)/vdso64.so.dbg $(obj)/vdso64.so FORCE
+ $(call if_changed,vdso64sym)
+
+vdso64.so: $(obj)/vdso64.so.dbg
+ @mkdir -p $(MODLIB)/vdso
+ $(call cmd,vdso_install)
+
+vdso64_install: vdso64.so
+endif
+
+ifdef CONFIG_VDSO32
+vdso32-as-syms = rt_sigreturn
+vdso32-as-syms += getcpu
+vdso32-as-syms += flush_icache
+vdso32-as-syms += sys_hwprobe
+
+vdso32-cc-syms += hwprobe
+
+VDSO32_CC_FLAGS := -march=rv32g -mabi=ilp32
+VDSO32_LD_FLAGS := -melf32lriscv
+
+obj-as-vdso32 = $(patsubst %, %-32.o, $(vdso32-as-syms)) note-32.o
+obj-as-vdso32 := $(addprefix $(obj)/, $(obj-as-vdso32))
+
+obj-cc-vdso32 = $(patsubst %, %-32.o, $(vdso32-cc-syms))
+obj-cc-vdso32 := $(addprefix $(obj)/, $(obj-cc-vdso32))
+
+targets += $(obj-as-vdso32) $(obj-cc-vdso32) vdso32.so vdso32.so.dbg vdso32.lds
+
+$(obj)/vdso32.so.dbg: $(obj)/vdso.lds $(obj-as-vdso32) $(obj-cc-vdso32) FORCE
+ $(call if_changed,vdso32ld)
+LDFLAGS_vdso32.so.dbg = -shared -S -soname=linux-vdso32.so.1 \
+ --build-id=sha1 --hash-style=both --eh-frame-hdr
-# actual build commands
# The DSO images are built using a special linker script
# Make sure only to export the intended __vdso_xxx symbol offsets.
-quiet_cmd_vdsold = VDSOLD $@
- cmd_vdsold = $(LD) $(ld_flags) -T $(filter-out FORCE,$^) -o $@.tmp && \
- $(OBJCOPY) $(patsubst %, -G __vdso_%, $(vdso-syms)) $@.tmp $@ && \
+quiet_cmd_vdso32ld = VDSO32LD $@
+ cmd_vdso32ld = $(VDSO_LD) $(ld_flags) $(VDSO32_LD_FLAGS) -T $(filter-out FORCE,$^) -o $@.tmp && \
+ $(OBJCOPY) $(patsubst %, -G __vdso_%, $(vdso32-as-syms) $(vdso32-cc-syms)) $@.tmp $@ && \
rm $@.tmp
-# install commands for the unstripped file
-quiet_cmd_vdso_install = INSTALL $@
- cmd_vdso_install = cp $(obj)/$@.dbg $(MODLIB)/vdso/$@
+# actual build commands
+quiet_cmd_vdso32as = VDSO32AS $@
+ cmd_vdso32as = $(VDSO_CC) $(a_flags) $(VDSO32_CC_FLAGS) -c -o $@ $<
+quiet_cmd_vdso32cc = VDSO32CC $@
+ cmd_vdso32cc = $(VDSO_CC) $(c_flags) $(VDSO32_CC_FLAGS) -c -o $@ $<
-vdso.so: $(obj)/vdso.so.dbg
+# Force dependency
+$(obj)/vdso32.o: $(obj)/vdso32.so
+
+$(obj-as-vdso32): %-32.o: %.S FORCE
+ $(call if_changed_dep,vdso32as)
+$(obj-cc-vdso32): %-32.o: %.c FORCE
+ $(call if_changed_dep,vdso32cc)
+
+CFLAGS_hwprobe-32.o += -fPIC
+
+# Generate VDSO offsets using helper script
+gen-vdso32sym := $(srctree)/$(src)/gen_vdso32_offsets.sh
+quiet_cmd_vdso32sym = VDSO32SYM $@
+ cmd_vdso32sym = $(NM) $< | $(gen-vdso32sym) | LC_ALL=C sort > $@
+
+include/generated/vdso32-offsets.h: $(obj)/vdso32.so.dbg $(obj)/vdso32.so FORCE
+ $(call if_changed,vdso32sym)
+
+vdso32.so: $(obj)/vdso32.so.dbg
@mkdir -p $(MODLIB)/vdso
$(call cmd,vdso_install)
-vdso_install: vdso.so
+vdso32_install: vdso32.so
+endif
diff --git a/arch/riscv/kernel/vdso/gen_vdso_offsets.sh b/arch/riscv/kernel/vdso/gen_vdso32_offsets.sh
similarity index 78%
rename from arch/riscv/kernel/vdso/gen_vdso_offsets.sh
rename to arch/riscv/kernel/vdso/gen_vdso32_offsets.sh
index c2e5613f3495..c0dee7361530 100755
--- a/arch/riscv/kernel/vdso/gen_vdso_offsets.sh
+++ b/arch/riscv/kernel/vdso/gen_vdso32_offsets.sh
@@ -2,4 +2,4 @@
# SPDX-License-Identifier: GPL-2.0
LC_ALL=C
-sed -n -e 's/^[0]\+\(0[0-9a-fA-F]*\) . \(__vdso_[a-zA-Z0-9_]*\)$/\#define \2_offset\t0x\1/p'
+sed -n -e 's/^[0]\+\(0[0-9a-fA-F]*\) . \(__vdso_[a-zA-Z0-9_]*\)$/\#define rv32\2_offset\t0x\1/p'
diff --git a/arch/riscv/kernel/vdso/gen_vdso64_offsets.sh b/arch/riscv/kernel/vdso/gen_vdso64_offsets.sh
new file mode 100755
index 000000000000..ac265ed49eaf
--- /dev/null
+++ b/arch/riscv/kernel/vdso/gen_vdso64_offsets.sh
@@ -0,0 +1,5 @@
+#!/bin/sh
+# SPDX-License-Identifier: GPL-2.0
+
+LC_ALL=C
+sed -n -e 's/^[0]\+\(0[0-9a-fA-F]*\) . \(__vdso_[a-zA-Z0-9_]*\)$/\#define rv64\2_offset\t0x\1/p'
diff --git a/arch/riscv/kernel/vdso32.S b/arch/riscv/kernel/vdso32.S
new file mode 100644
index 000000000000..9bdf3cb20ccb
--- /dev/null
+++ b/arch/riscv/kernel/vdso32.S
@@ -0,0 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#define vdso64_start vdso32_start
+#define vdso64_end vdso32_end
+
+#define __VDSO_PATH "arch/riscv/kernel/vdso/vdso32.so"
+
+#include "vdso64.S"
diff --git a/arch/riscv/kernel/vdso/vdso.S b/arch/riscv/kernel/vdso64.S
similarity index 73%
rename from arch/riscv/kernel/vdso/vdso.S
rename to arch/riscv/kernel/vdso64.S
index 83f1c899e8d8..498b73da0dbf 100644
--- a/arch/riscv/kernel/vdso/vdso.S
+++ b/arch/riscv/kernel/vdso64.S
@@ -8,16 +8,16 @@
#include <asm/page.h>
#ifndef __VDSO_PATH
-#define __VDSO_PATH "arch/riscv/kernel/vdso/vdso.so"
+#define __VDSO_PATH "arch/riscv/kernel/vdso/vdso64.so"
#endif
__PAGE_ALIGNED_DATA
- .globl vdso_start, vdso_end
+ .globl vdso64_start, vdso64_end
.balign PAGE_SIZE
-vdso_start:
+vdso64_start:
.incbin __VDSO_PATH
.balign PAGE_SIZE
-vdso_end:
+vdso64_end:
.previous
--
2.36.1
^ permalink raw reply related [flat|nested] 42+ messages in thread* [RFC PATCH V2 02/38] riscv: u64ilp32: Remove compat_vdso/
2023-11-12 6:14 [RFC PATCH V2 00/38] rv64ilp32: Running ILP32 on RV64 ISA guoren
2023-11-12 6:14 ` [RFC PATCH V2 01/38] riscv: u64ilp32: Unify vdso32 & compat_vdso into vdso/Makefile guoren
@ 2023-11-12 6:14 ` guoren
2023-11-12 6:14 ` [RFC PATCH V2 03/38] riscv: u64ilp32: Add time-related vDSO common flow for vdso32 guoren
` (38 subsequent siblings)
40 siblings, 0 replies; 42+ messages in thread
From: guoren @ 2023-11-12 6:14 UTC (permalink / raw)
To: arnd, guoren, palmer, tglx, conor.dooley, heiko, apatel, atishp,
bjorn, paul.walmsley, anup, jiawei, liweiwei, wefu, U2FsdGVkX1,
wangjunqiang, kito.cheng, andy.chiu, vincent.chen, greentime.hu,
wuwei2016, jrtc27, luto, fweimer, catalin.marinas, hjl.tools
Cc: linux-arch, linux-kernel, linux-riscv, Guo Ren
From: Guo Ren <guoren@linux.alibaba.com>
After unifying vdso32 & vdso64 into vdso/, we ever needn't compat_vdso
directory. This commit removes the whole compat_vdso/.
Signed-off-by: Guo Ren <guoren@linux.alibaba.com>
Signed-off-by: Guo Ren <guoren@kernel.org>
---
arch/riscv/kernel/compat_vdso/.gitignore | 2 --
arch/riscv/kernel/compat_vdso/compat_vdso.S | 8 --------
arch/riscv/kernel/compat_vdso/compat_vdso.lds.S | 3 ---
arch/riscv/kernel/compat_vdso/flush_icache.S | 3 ---
arch/riscv/kernel/compat_vdso/gen_compat_vdso_offsets.sh | 5 -----
arch/riscv/kernel/compat_vdso/getcpu.S | 3 ---
arch/riscv/kernel/compat_vdso/note.S | 3 ---
arch/riscv/kernel/compat_vdso/rt_sigreturn.S | 3 ---
8 files changed, 30 deletions(-)
delete mode 100644 arch/riscv/kernel/compat_vdso/.gitignore
delete mode 100644 arch/riscv/kernel/compat_vdso/compat_vdso.S
delete mode 100644 arch/riscv/kernel/compat_vdso/compat_vdso.lds.S
delete mode 100644 arch/riscv/kernel/compat_vdso/flush_icache.S
delete mode 100755 arch/riscv/kernel/compat_vdso/gen_compat_vdso_offsets.sh
delete mode 100644 arch/riscv/kernel/compat_vdso/getcpu.S
delete mode 100644 arch/riscv/kernel/compat_vdso/note.S
delete mode 100644 arch/riscv/kernel/compat_vdso/rt_sigreturn.S
diff --git a/arch/riscv/kernel/compat_vdso/.gitignore b/arch/riscv/kernel/compat_vdso/.gitignore
deleted file mode 100644
index 19d83d846c1e..000000000000
--- a/arch/riscv/kernel/compat_vdso/.gitignore
+++ /dev/null
@@ -1,2 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0-only
-compat_vdso.lds
diff --git a/arch/riscv/kernel/compat_vdso/compat_vdso.S b/arch/riscv/kernel/compat_vdso/compat_vdso.S
deleted file mode 100644
index ffd66237e091..000000000000
--- a/arch/riscv/kernel/compat_vdso/compat_vdso.S
+++ /dev/null
@@ -1,8 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-
-#define vdso_start compat_vdso_start
-#define vdso_end compat_vdso_end
-
-#define __VDSO_PATH "arch/riscv/kernel/compat_vdso/compat_vdso.so"
-
-#include "../vdso/vdso.S"
diff --git a/arch/riscv/kernel/compat_vdso/compat_vdso.lds.S b/arch/riscv/kernel/compat_vdso/compat_vdso.lds.S
deleted file mode 100644
index c7c9355d311e..000000000000
--- a/arch/riscv/kernel/compat_vdso/compat_vdso.lds.S
+++ /dev/null
@@ -1,3 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-
-#include "../vdso/vdso.lds.S"
diff --git a/arch/riscv/kernel/compat_vdso/flush_icache.S b/arch/riscv/kernel/compat_vdso/flush_icache.S
deleted file mode 100644
index 523dd8b96045..000000000000
--- a/arch/riscv/kernel/compat_vdso/flush_icache.S
+++ /dev/null
@@ -1,3 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-
-#include "../vdso/flush_icache.S"
diff --git a/arch/riscv/kernel/compat_vdso/gen_compat_vdso_offsets.sh b/arch/riscv/kernel/compat_vdso/gen_compat_vdso_offsets.sh
deleted file mode 100755
index 8ac070c783b3..000000000000
--- a/arch/riscv/kernel/compat_vdso/gen_compat_vdso_offsets.sh
+++ /dev/null
@@ -1,5 +0,0 @@
-#!/bin/sh
-# SPDX-License-Identifier: GPL-2.0
-
-LC_ALL=C
-sed -n -e 's/^[0]\+\(0[0-9a-fA-F]*\) . \(__vdso_[a-zA-Z0-9_]*\)$/\#define compat\2_offset\t0x\1/p'
diff --git a/arch/riscv/kernel/compat_vdso/getcpu.S b/arch/riscv/kernel/compat_vdso/getcpu.S
deleted file mode 100644
index 10f463efe271..000000000000
--- a/arch/riscv/kernel/compat_vdso/getcpu.S
+++ /dev/null
@@ -1,3 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-
-#include "../vdso/getcpu.S"
diff --git a/arch/riscv/kernel/compat_vdso/note.S b/arch/riscv/kernel/compat_vdso/note.S
deleted file mode 100644
index b10312907542..000000000000
--- a/arch/riscv/kernel/compat_vdso/note.S
+++ /dev/null
@@ -1,3 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-
-#include "../vdso/note.S"
diff --git a/arch/riscv/kernel/compat_vdso/rt_sigreturn.S b/arch/riscv/kernel/compat_vdso/rt_sigreturn.S
deleted file mode 100644
index 884aada4facc..000000000000
--- a/arch/riscv/kernel/compat_vdso/rt_sigreturn.S
+++ /dev/null
@@ -1,3 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-
-#include "../vdso/rt_sigreturn.S"
--
2.36.1
^ permalink raw reply related [flat|nested] 42+ messages in thread* [RFC PATCH V2 03/38] riscv: u64ilp32: Add time-related vDSO common flow for vdso32
2023-11-12 6:14 [RFC PATCH V2 00/38] rv64ilp32: Running ILP32 on RV64 ISA guoren
2023-11-12 6:14 ` [RFC PATCH V2 01/38] riscv: u64ilp32: Unify vdso32 & compat_vdso into vdso/Makefile guoren
2023-11-12 6:14 ` [RFC PATCH V2 02/38] riscv: u64ilp32: Remove compat_vdso/ guoren
@ 2023-11-12 6:14 ` guoren
2023-11-12 6:14 ` [RFC PATCH V2 04/38] riscv: u64ilp32: Introduce ILP32 vdso for UXL=64 guoren
` (37 subsequent siblings)
40 siblings, 0 replies; 42+ messages in thread
From: guoren @ 2023-11-12 6:14 UTC (permalink / raw)
To: arnd, guoren, palmer, tglx, conor.dooley, heiko, apatel, atishp,
bjorn, paul.walmsley, anup, jiawei, liweiwei, wefu, U2FsdGVkX1,
wangjunqiang, kito.cheng, andy.chiu, vincent.chen, greentime.hu,
wuwei2016, jrtc27, luto, fweimer, catalin.marinas, hjl.tools
Cc: linux-arch, linux-kernel, linux-riscv, Guo Ren
From: Guo Ren <guoren@linux.alibaba.com>
This patch adds time-related vDSO common flow for vdso32, and it's an
addition to commit: ad5d1122b82f ("riscv: use vDSO common flow to reduce
the latency of the time-related functions"). Then we could reduce the
latency of collecting clock information for u32ilp32 (native 32-bit
userspace ecosystem), just like what we've done for u64lp64.
Signed-off-by: Guo Ren <guoren@linux.alibaba.com>
Signed-off-by: Guo Ren <guoren@kernel.org>
---
arch/riscv/Kconfig | 4 +-
arch/riscv/include/asm/vdso/gettimeofday.h | 90 ++++++++++++++++++++++
arch/riscv/include/uapi/asm/unistd.h | 1 +
arch/riscv/kernel/vdso/Makefile | 42 +++++-----
arch/riscv/kernel/vdso/vdso.lds.S | 2 -
arch/riscv/kernel/vdso/vgettimeofday.c | 39 ++++++++--
6 files changed, 145 insertions(+), 33 deletions(-)
diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
index 4b91e2ba7815..24b1b6abf0a7 100644
--- a/arch/riscv/Kconfig
+++ b/arch/riscv/Kconfig
@@ -82,7 +82,7 @@ config RISCV
select GENERIC_PTDUMP if MMU
select GENERIC_SCHED_CLOCK
select GENERIC_SMP_IDLE_THREAD
- select GENERIC_TIME_VSYSCALL if MMU && 64BIT
+ select GENERIC_TIME_VSYSCALL if MMU
select GENERIC_VDSO_TIME_NS if HAVE_GENERIC_VDSO
select HARDIRQS_SW_RESEND
select HAS_IOPORT if MMU
@@ -118,7 +118,7 @@ config RISCV
select HAVE_FUNCTION_ARG_ACCESS_API
select HAVE_FUNCTION_ERROR_INJECTION
select HAVE_GCC_PLUGINS
- select HAVE_GENERIC_VDSO if MMU && 64BIT
+ select HAVE_GENERIC_VDSO if MMU
select HAVE_IRQ_TIME_ACCOUNTING
select HAVE_KPROBES if !XIP_KERNEL
select HAVE_KPROBES_ON_FTRACE if !XIP_KERNEL
diff --git a/arch/riscv/include/asm/vdso/gettimeofday.h b/arch/riscv/include/asm/vdso/gettimeofday.h
index a7ae8576797b..4c362bb9a16b 100644
--- a/arch/riscv/include/asm/vdso/gettimeofday.h
+++ b/arch/riscv/include/asm/vdso/gettimeofday.h
@@ -36,6 +36,7 @@ int gettimeofday_fallback(struct __kernel_old_timeval *_tv,
}
#endif
+#if __SIZEOF_POINTER__ == 8
#ifdef __NR_clock_gettime
static __always_inline
long clock_gettime_fallback(clockid_t _clkid, struct __kernel_timespec *_ts)
@@ -71,6 +72,84 @@ int clock_getres_fallback(clockid_t _clkid, struct __kernel_timespec *_ts)
return ret;
}
#endif
+
+#elif __SIZEOF_POINTER__ == 4
+
+#define BUILD_VDSO32 1
+
+#ifdef __NR_clock_gettime64
+static __always_inline
+long clock_gettime_fallback(clockid_t _clkid, struct __kernel_timespec *_ts)
+{
+ register clockid_t clkid asm("a0") = _clkid;
+ register struct __kernel_timespec *ts asm("a1") = _ts;
+ register long ret asm("a0");
+ register long nr asm("a7") = __NR_clock_gettime64;
+
+ asm volatile ("ecall\n"
+ : "=r" (ret)
+ : "r"(clkid), "r"(ts), "r"(nr)
+ : "memory");
+
+ return ret;
+}
+#endif
+
+#ifdef __NR_clock_getres_time64
+static __always_inline
+int clock_getres_fallback(clockid_t _clkid, struct __kernel_timespec *_ts)
+{
+ register clockid_t clkid asm("a0") = _clkid;
+ register struct __kernel_timespec *ts asm("a1") = _ts;
+ register long ret asm("a0");
+ register long nr asm("a7") = __NR_clock_getres_time64;
+
+ asm volatile ("ecall\n"
+ : "=r" (ret)
+ : "r"(clkid), "r"(ts), "r"(nr)
+ : "memory");
+
+ return ret;
+}
+#endif
+
+#ifdef __NR_clock_gettime
+static __always_inline
+int clock_gettime32_fallback(clockid_t _clkid, struct old_timespec32 *_ts)
+{
+ register clockid_t clkid asm("a0") = _clkid;
+ register struct old_timespec32 *ts asm("a1") = _ts;
+ register long ret asm("a0");
+ register long nr asm("a7") = __NR_clock_gettime;
+
+ asm volatile ("ecall\n"
+ : "=r" (ret)
+ : "r"(clkid), "r"(ts), "r"(nr)
+ : "memory");
+
+ return ret;
+}
+#endif
+
+#ifdef __NR_clock_getres
+static __always_inline
+int clock_getres32_fallback(clockid_t _clkid, struct old_timespec32 *_ts)
+{
+ register clockid_t clkid asm("a0") = _clkid;
+ register struct old_timespec32 *ts asm("a1") = _ts;
+ register long ret asm("a0");
+ register long nr asm("a7") = __NR_clock_getres;
+
+ asm volatile ("ecall\n"
+ : "=r" (ret)
+ : "r"(clkid), "r"(ts), "r"(nr)
+ : "memory");
+
+ return ret;
+}
+#endif
+
+#endif /* __SIZEOF_POINTER__ */
#endif /* CONFIG_GENERIC_TIME_VSYSCALL */
static __always_inline u64 __arch_get_hw_counter(s32 clock_mode,
@@ -81,7 +160,18 @@ static __always_inline u64 __arch_get_hw_counter(s32 clock_mode,
* M-mode to obtain the value of CSR_TIME. Hence, unlike other
* architecture, no fence instructions surround the csr_read()
*/
+#if __riscv_xlen == 64
return csr_read(CSR_TIME);
+#else
+ u32 hi, lo;
+
+ do {
+ hi = csr_read(CSR_TIMEH);
+ lo = csr_read(CSR_TIME);
+ } while (hi != csr_read(CSR_TIMEH));
+
+ return ((u64)hi << 32) | lo;
+#endif
}
static __always_inline const struct vdso_data *__arch_get_vdso_data(void)
diff --git a/arch/riscv/include/uapi/asm/unistd.h b/arch/riscv/include/uapi/asm/unistd.h
index 950ab3fd4409..0ee86ef907e4 100644
--- a/arch/riscv/include/uapi/asm/unistd.h
+++ b/arch/riscv/include/uapi/asm/unistd.h
@@ -22,6 +22,7 @@
#define __ARCH_WANT_SYS_CLONE3
#define __ARCH_WANT_MEMFD_SECRET
+#define __ARCH_WANT_TIME32_SYSCALLS
#include <asm-generic/unistd.h>
diff --git a/arch/riscv/kernel/vdso/Makefile b/arch/riscv/kernel/vdso/Makefile
index a9720e816e1f..df8f68bb0937 100644
--- a/arch/riscv/kernel/vdso/Makefile
+++ b/arch/riscv/kernel/vdso/Makefile
@@ -16,9 +16,6 @@ ccflags-y := -fno-stack-protector
ccflags-y += -DDISABLE_BRANCH_PROFILING
CPPFLAGS_vdso.lds += -P -C -U$(ARCH)
-ifneq ($(filter vgettimeofday, $(vdso-cc-syms)),)
- CPPFLAGS_vdso.lds += -DHAS_VGETTIMEOFDAY
-endif
# strip rule for the .so file
$(obj)/%.so: OBJCOPYFLAGS := -S
@@ -29,20 +26,20 @@ $(obj)/%.so: $(obj)/%.so.dbg FORCE
quiet_cmd_vdso_install = INSTALL $@
cmd_vdso_install = cp $(obj)/$@.dbg $(MODLIB)/vdso/$@
-# Symbols present in the vdso
-ifdef CONFIG_VDSO64
-vdso64-as-syms = rt_sigreturn
-vdso64-as-syms += getcpu
-vdso64-as-syms += flush_icache
-vdso64-as-syms += sys_hwprobe
+vdso-as-syms = rt_sigreturn
+vdso-as-syms += getcpu
+vdso-as-syms += flush_icache
+vdso-as-syms += sys_hwprobe
-vdso64-cc-syms = vgettimeofday
-vdso64-cc-syms += hwprobe
+vdso-cc-syms = vgettimeofday
+vdso-cc-syms += hwprobe
-obj-as-vdso64 = $(patsubst %, %-64.o, $(vdso64-as-syms)) note-64.o
+# Symbols present in the vdso
+ifdef CONFIG_VDSO64
+obj-as-vdso64 = $(patsubst %, %-64.o, $(vdso-as-syms)) note-64.o
obj-as-vdso64 := $(addprefix $(obj)/, $(obj-as-vdso64))
-obj-cc-vdso64 = $(patsubst %, %-64.o, $(vdso64-cc-syms))
+obj-cc-vdso64 = $(patsubst %, %-64.o, $(vdso-cc-syms))
obj-cc-vdso64 := $(addprefix $(obj)/, $(obj-cc-vdso64))
targets += $(obj-as-vdso64) $(obj-cc-vdso64) vdso64.so vdso64.so.dbg vdso64.lds
@@ -55,7 +52,7 @@ LDFLAGS_vdso64.so.dbg = -shared -S -soname=linux-vdso64.so.1 \
# Make sure only to export the intended __vdso_xxx symbol offsets.
quiet_cmd_vdso64ld = VDSO64LD $@
cmd_vdso64ld = $(VDSO_LD) $(ld_flags) $(VDSO64_LD_FLAGS) -T $(filter-out FORCE,$^) -o $@.tmp && \
- $(OBJCOPY) $(patsubst %, -G __vdso_%, $(vdso64-as-syms) $(vdso64-cc-syms)) $@.tmp $@ && \
+ $(OBJCOPY) $(patsubst %, -G __vdso_%, $(vdso-as-syms) $(vdso-cc-syms)) $@.tmp $@ && \
rm $@.tmp
# actual build commands
@@ -94,20 +91,13 @@ vdso64_install: vdso64.so
endif
ifdef CONFIG_VDSO32
-vdso32-as-syms = rt_sigreturn
-vdso32-as-syms += getcpu
-vdso32-as-syms += flush_icache
-vdso32-as-syms += sys_hwprobe
-
-vdso32-cc-syms += hwprobe
-
VDSO32_CC_FLAGS := -march=rv32g -mabi=ilp32
VDSO32_LD_FLAGS := -melf32lriscv
-obj-as-vdso32 = $(patsubst %, %-32.o, $(vdso32-as-syms)) note-32.o
+obj-as-vdso32 = $(patsubst %, %-32.o, $(vdso-as-syms)) note-32.o
obj-as-vdso32 := $(addprefix $(obj)/, $(obj-as-vdso32))
-obj-cc-vdso32 = $(patsubst %, %-32.o, $(vdso32-cc-syms))
+obj-cc-vdso32 = $(patsubst %, %-32.o, $(vdso-cc-syms))
obj-cc-vdso32 := $(addprefix $(obj)/, $(obj-cc-vdso32))
targets += $(obj-as-vdso32) $(obj-cc-vdso32) vdso32.so vdso32.so.dbg vdso32.lds
@@ -121,7 +111,7 @@ LDFLAGS_vdso32.so.dbg = -shared -S -soname=linux-vdso32.so.1 \
# Make sure only to export the intended __vdso_xxx symbol offsets.
quiet_cmd_vdso32ld = VDSO32LD $@
cmd_vdso32ld = $(VDSO_LD) $(ld_flags) $(VDSO32_LD_FLAGS) -T $(filter-out FORCE,$^) -o $@.tmp && \
- $(OBJCOPY) $(patsubst %, -G __vdso_%, $(vdso32-as-syms) $(vdso32-cc-syms)) $@.tmp $@ && \
+ $(OBJCOPY) $(patsubst %, -G __vdso_%, $(vdso-as-syms) $(vdso-cc-syms)) $@.tmp $@ && \
rm $@.tmp
# actual build commands
@@ -140,6 +130,10 @@ $(obj-cc-vdso32): %-32.o: %.c FORCE
CFLAGS_hwprobe-32.o += -fPIC
+CFLAGS_vgettimeofday-32.o += -fPIC -include $(c-gettimeofday-y)
+# Disable -pg to prevent insert call site
+CFLAGS_REMOVE_vgettimeofday-32.o = $(CC_FLAGS_FTRACE)
+
# Generate VDSO offsets using helper script
gen-vdso32sym := $(srctree)/$(src)/gen_vdso32_offsets.sh
quiet_cmd_vdso32sym = VDSO32SYM $@
diff --git a/arch/riscv/kernel/vdso/vdso.lds.S b/arch/riscv/kernel/vdso/vdso.lds.S
index 82ce64900f3d..d28202283b72 100644
--- a/arch/riscv/kernel/vdso/vdso.lds.S
+++ b/arch/riscv/kernel/vdso/vdso.lds.S
@@ -75,11 +75,9 @@ VERSION
LINUX_4.15 {
global:
__vdso_rt_sigreturn;
-#ifdef HAS_VGETTIMEOFDAY
__vdso_gettimeofday;
__vdso_clock_gettime;
__vdso_clock_getres;
-#endif
__vdso_getcpu;
__vdso_flush_icache;
#ifndef COMPAT_VDSO
diff --git a/arch/riscv/kernel/vdso/vgettimeofday.c b/arch/riscv/kernel/vdso/vgettimeofday.c
index cc0d80699c31..056b465eb161 100644
--- a/arch/riscv/kernel/vdso/vgettimeofday.c
+++ b/arch/riscv/kernel/vdso/vgettimeofday.c
@@ -9,6 +9,14 @@
#include <linux/time.h>
#include <linux/types.h>
+extern
+int __vdso_gettimeofday(struct __kernel_old_timeval *tv, struct timezone *tz);
+int __vdso_gettimeofday(struct __kernel_old_timeval *tv, struct timezone *tz)
+{
+ return __cvdso_gettimeofday(tv, tz);
+}
+
+#if __SIZEOF_POINTER__ == 8
extern
int __vdso_clock_gettime(clockid_t clock, struct __kernel_timespec *ts);
int __vdso_clock_gettime(clockid_t clock, struct __kernel_timespec *ts)
@@ -17,15 +25,36 @@ int __vdso_clock_gettime(clockid_t clock, struct __kernel_timespec *ts)
}
extern
-int __vdso_gettimeofday(struct __kernel_old_timeval *tv, struct timezone *tz);
-int __vdso_gettimeofday(struct __kernel_old_timeval *tv, struct timezone *tz)
+int __vdso_clock_getres(clockid_t clock_id, struct __kernel_timespec *res);
+int __vdso_clock_getres(clockid_t clock_id, struct __kernel_timespec *res)
{
- return __cvdso_gettimeofday(tv, tz);
+ return __cvdso_clock_getres(clock_id, res);
+}
+#elif __SIZEOF_POINTER__ == 4
+extern
+int __vdso_clock_gettime(clockid_t clock, struct old_timespec32 *ts);
+int __vdso_clock_gettime(clockid_t clock, struct old_timespec32 *ts)
+{
+ return __cvdso_clock_gettime32(clock, ts);
+}
+
+int __vdso_clock_gettime64(clockid_t clock, struct __kernel_timespec *ts);
+int __vdso_clock_gettime64(clockid_t clock, struct __kernel_timespec *ts)
+{
+ return __cvdso_clock_gettime(clock, ts);
}
extern
-int __vdso_clock_getres(clockid_t clock_id, struct __kernel_timespec *res);
-int __vdso_clock_getres(clockid_t clock_id, struct __kernel_timespec *res)
+int __vdso_clock_getres(clockid_t clock_id, struct old_timespec32 *res);
+int __vdso_clock_getres(clockid_t clock_id, struct old_timespec32 *res)
+{
+ return __cvdso_clock_getres_time32(clock_id, res);
+}
+
+extern
+int __vdso_clock_getres64(clockid_t clock_id, struct __kernel_timespec *res);
+int __vdso_clock_getres64(clockid_t clock_id, struct __kernel_timespec *res)
{
return __cvdso_clock_getres(clock_id, res);
}
+#endif
--
2.36.1
^ permalink raw reply related [flat|nested] 42+ messages in thread* [RFC PATCH V2 04/38] riscv: u64ilp32: Introduce ILP32 vdso for UXL=64
2023-11-12 6:14 [RFC PATCH V2 00/38] rv64ilp32: Running ILP32 on RV64 ISA guoren
` (2 preceding siblings ...)
2023-11-12 6:14 ` [RFC PATCH V2 03/38] riscv: u64ilp32: Add time-related vDSO common flow for vdso32 guoren
@ 2023-11-12 6:14 ` guoren
2023-11-12 6:14 ` [RFC PATCH V2 05/38] riscv: u64ilp32: Adjust vDSO kernel flow for 64ilp32 abi guoren
` (36 subsequent siblings)
40 siblings, 0 replies; 42+ messages in thread
From: guoren @ 2023-11-12 6:14 UTC (permalink / raw)
To: arnd, guoren, palmer, tglx, conor.dooley, heiko, apatel, atishp,
bjorn, paul.walmsley, anup, jiawei, liweiwei, wefu, U2FsdGVkX1,
wangjunqiang, kito.cheng, andy.chiu, vincent.chen, greentime.hu,
wuwei2016, jrtc27, luto, fweimer, catalin.marinas, hjl.tools
Cc: linux-arch, linux-kernel, linux-riscv, Guo Ren
From: Guo Ren <guoren@linux.alibaba.com>
This is the first patch to introduce ILP32 abi for RV64. Here is the
diagram:
+--------------------------------+------------+
| +-------------------+--------+ | +--------+ |
| | (compat)|(compat)| | | | |
| |u64lp64 u64ilp32|u32ilp32| | |u32ilp32| | ABI
| | ^^^^^^^^| | | | | |
| +-------------------+--------+ | +--------+ |
| +-------------------+--------+ | +--------+ |
| | UXL=64 | UXL=32 | | | UXL=32 | | ISA
| +-------------------+--------+ | +--------+ |
+--------------------------------+------------+-------
| +----------------------------+ | +--------+ |
| | 64BIT | | | 32BIT| | Kernel
| | s64lp64 | | |s32ilp32| | ABI
| +----------------------------+ | +--------+ |
| +----------------------------+ | +--------+ |
| | SXL=64 | | | SXL=32 | | ISA
| +----------------------------+ | +--------+ |
+--------------------------------+------------+
The 64ilp32 userspace needs another virtual dynamic shared object
independent from vdso32(32ilp32) and vdso64(64ilp32).
Signed-off-by: Guo Ren <guoren@linux.alibaba.com>
Signed-off-by: Guo Ren <guoren@kernel.org>
---
arch/riscv/Kconfig | 5 ++
arch/riscv/Makefile | 4 ++
arch/riscv/kernel/Makefile | 1 +
arch/riscv/kernel/vdso/Makefile | 59 +++++++++++++++++++
.../kernel/vdso/gen_vdso64ilp32_offsets.sh | 5 ++
arch/riscv/kernel/vdso64ilp32.S | 8 +++
6 files changed, 82 insertions(+)
create mode 100755 arch/riscv/kernel/vdso/gen_vdso64ilp32_offsets.sh
create mode 100644 arch/riscv/kernel/vdso64ilp32.S
diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
index 24b1b6abf0a7..5d770b8e2756 100644
--- a/arch/riscv/Kconfig
+++ b/arch/riscv/Kconfig
@@ -288,6 +288,10 @@ config VDSO64
bool
depends on MMU
+config VDSO64ILP32
+ bool
+ depends on MMU
+
source "arch/riscv/Kconfig.socs"
source "arch/riscv/Kconfig.errata"
@@ -707,6 +711,7 @@ config COMPAT
bool "Kernel support for 32-bit U-mode"
default 64BIT
select VDSO32
+ select VDSO64ILP32 if $(cc-option,-march=rv64g -mabi=ilp32)
depends on 64BIT && MMU
help
This option enables support for a 32-bit U-mode running under a 64-bit
diff --git a/arch/riscv/Makefile b/arch/riscv/Makefile
index 3b7d5ebf3c78..8605050bddd0 100644
--- a/arch/riscv/Makefile
+++ b/arch/riscv/Makefile
@@ -140,6 +140,8 @@ vdso_install:
$(build)=arch/riscv/kernel/vdso vdso32_install
$(if $(CONFIG_VDSO64),$(Q)$(MAKE) \
$(build)=arch/riscv/kernel/vdso vdso64_install
+ $(if $(CONFIG_VDSO64ILP32),$(Q)$(MAKE) \
+ $(build)=arch/riscv/kernel/vdso vdso64ilp32_install
ifeq ($(KBUILD_EXTMOD),)
ifeq ($(CONFIG_MMU),y)
@@ -149,6 +151,8 @@ vdso_prepare: prepare0
$(build)=arch/riscv/kernel/vdso include/generated/vdso32-offsets.h)
$(if $(CONFIG_VDSO64),$(Q)$(MAKE) \
$(build)=arch/riscv/kernel/vdso include/generated/vdso64-offsets.h)
+ $(if $(CONFIG_VDSO64ILP32),$(Q)$(MAKE) \
+ $(build)=arch/riscv/kernel/vdso include/generated/vdso64ilp32-offsets.h)
endif
endif
diff --git a/arch/riscv/kernel/Makefile b/arch/riscv/kernel/Makefile
index 23032ac7f51d..a4583a29b28b 100644
--- a/arch/riscv/kernel/Makefile
+++ b/arch/riscv/kernel/Makefile
@@ -59,6 +59,7 @@ obj-y += probes/
obj-$(CONFIG_MMU) += vdso.o vdso/
obj-$(CONFIG_VDSO64) += vdso64.o
obj-$(CONFIG_VDSO32) += vdso32.o
+obj-$(CONFIG_VDSO64ILP32) += vdso64ilp32.o
obj-$(CONFIG_RISCV_M_MODE) += traps_misaligned.o
obj-$(CONFIG_FPU) += fpu.o
diff --git a/arch/riscv/kernel/vdso/Makefile b/arch/riscv/kernel/vdso/Makefile
index df8f68bb0937..629989b1ad05 100644
--- a/arch/riscv/kernel/vdso/Makefile
+++ b/arch/riscv/kernel/vdso/Makefile
@@ -148,3 +148,62 @@ vdso32.so: $(obj)/vdso32.so.dbg
vdso32_install: vdso32.so
endif
+
+ifdef CONFIG_VDSO64ILP32
+VDSO64ILP32_CC_FLAGS := -march=rv64g -mabi=ilp32
+VDSO64ILP32_LD_FLAGS := -melf32lriscv
+
+obj-as-vdso64ilp32 = $(patsubst %, %-64ilp32.o, $(vdso-as-syms)) note-64ilp32.o
+obj-as-vdso64ilp32 := $(addprefix $(obj)/, $(obj-as-vdso64ilp32))
+
+obj-cc-vdso64ilp32 = $(patsubst %, %-64ilp32.o, $(vdso-cc-syms))
+obj-cc-vdso64ilp32 := $(addprefix $(obj)/, $(obj-cc-vdso64ilp32))
+
+targets += $(obj-as-vdso64ilp32) $(obj-cc-vdso64ilp32) vdso64ilp32.so vdso64ilp32.so.dbg vdso64ilp32.lds
+
+$(obj)/vdso64ilp32.so.dbg: $(obj)/vdso.lds $(obj-as-vdso64ilp32) $(obj-cc-vdso64ilp32) FORCE
+ $(call if_changed,vdso64ilp32ld)
+LDFLAGS_vdso64ilp32.so.dbg = -shared -S -soname=linux-vdso64ilp32.so.1 \
+ --build-id=sha1 --hash-style=both --eh-frame-hdr
+
+# The DSO images are built using a special linker script
+# Make sure only to export the intended __vdso_xxx symbol offsets.
+quiet_cmd_vdso64ilp32ld = VDSO64ILP32LD $@
+ cmd_vdso64ilp32ld = $(VDSO_LD) $(ld_flags) $(VDSO64ILP32_LD_FLAGS) -T $(filter-out FORCE,$^) -o $@.tmp && \
+ $(OBJCOPY) $(patsubst %, -G __vdso_%, $(vdso-as-syms) $(vdso-cc-syms)) $@.tmp $@ && \
+ rm $@.tmp
+
+# actual build commands
+quiet_cmd_vdso64ilp32as = VDSO64ILP32AS $@
+ cmd_vdso64ilp32as = $(VDSO_CC) $(a_flags) $(VDSO64ILP32_CC_FLAGS) -c -o $@ $<
+quiet_cmd_vdso64ilp32cc = VDSO64ILP32CC $@
+ cmd_vdso64ilp32cc = $(VDSO_CC) $(c_flags) $(VDSO64ILP32_CC_FLAGS) -c -o $@ $<
+
+# Force dependency
+$(obj)/vdso64ilp32.o: $(obj)/vdso64ilp32.so
+
+$(obj-as-vdso64ilp32): %-64ilp32.o: %.S FORCE
+ $(call if_changed_dep,vdso64ilp32as)
+$(obj-cc-vdso64ilp32): %-64ilp32.o: %.c FORCE
+ $(call if_changed_dep,vdso64ilp32cc)
+
+CFLAGS_hwprobe-64ilp32.o += -fPIC
+
+CFLAGS_vgettimeofday-64ilp32.o += -fPIC -include $(c-gettimeofday-y)
+# Disable -pg to prevent insert call site
+CFLAGS_REMOVE_vgettimeofday-64ilp32.o = $(CC_FLAGS_FTRACE)
+
+# Generate VDSO offsets using helper script
+gen-vdso64ilp32sym := $(srctree)/$(src)/gen_vdso64ilp32_offsets.sh
+quiet_cmd_vdso64ilp32sym = VDSO64ILP32SYM $@
+ cmd_vdso64ilp32sym = $(NM) $< | $(gen-vdso64ilp32sym) | LC_ALL=C sort > $@
+
+include/generated/vdso64ilp32-offsets.h: $(obj)/vdso64ilp32.so.dbg $(obj)/vdso64ilp32.so FORCE
+ $(call if_changed,vdso64ilp32sym)
+
+vdso64ilp32.so: $(obj)/vdso64ilp32.so.dbg
+ @mkdir -p $(MODLIB)/vdso
+ $(call cmd,vdso_install)
+
+vdso64ilp32_install: vdso64ilp32.so
+endif
diff --git a/arch/riscv/kernel/vdso/gen_vdso64ilp32_offsets.sh b/arch/riscv/kernel/vdso/gen_vdso64ilp32_offsets.sh
new file mode 100755
index 000000000000..6af2db7a26ad
--- /dev/null
+++ b/arch/riscv/kernel/vdso/gen_vdso64ilp32_offsets.sh
@@ -0,0 +1,5 @@
+#!/bin/sh
+# SPDX-License-Identifier: GPL-2.0
+
+LC_ALL=C
+sed -n -e 's/^[0]\+\(0[0-9a-fA-F]*\) . \(__vdso_[a-zA-Z0-9_]*\)$/\#define rv64ilp32\2_offset\t0x\1/p'
diff --git a/arch/riscv/kernel/vdso64ilp32.S b/arch/riscv/kernel/vdso64ilp32.S
new file mode 100644
index 000000000000..5b658da1eeef
--- /dev/null
+++ b/arch/riscv/kernel/vdso64ilp32.S
@@ -0,0 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#define vdso64_start vdso64ilp32_start
+#define vdso64_end vdso64ilp32_end
+
+#define __VDSO_PATH "arch/riscv/kernel/vdso/vdso64ilp32.so"
+
+#include "vdso64.S"
--
2.36.1
^ permalink raw reply related [flat|nested] 42+ messages in thread* [RFC PATCH V2 05/38] riscv: u64ilp32: Adjust vDSO kernel flow for 64ilp32 abi
2023-11-12 6:14 [RFC PATCH V2 00/38] rv64ilp32: Running ILP32 on RV64 ISA guoren
` (3 preceding siblings ...)
2023-11-12 6:14 ` [RFC PATCH V2 04/38] riscv: u64ilp32: Introduce ILP32 vdso for UXL=64 guoren
@ 2023-11-12 6:14 ` guoren
2023-11-12 6:14 ` [RFC PATCH V2 06/38] riscv: u64ilp32: Add signal support for compat guoren
` (35 subsequent siblings)
40 siblings, 0 replies; 42+ messages in thread
From: guoren @ 2023-11-12 6:14 UTC (permalink / raw)
To: arnd, guoren, palmer, tglx, conor.dooley, heiko, apatel, atishp,
bjorn, paul.walmsley, anup, jiawei, liweiwei, wefu, U2FsdGVkX1,
wangjunqiang, kito.cheng, andy.chiu, vincent.chen, greentime.hu,
wuwei2016, jrtc27, luto, fweimer, catalin.marinas, hjl.tools
Cc: linux-arch, linux-kernel, linux-riscv, Guo Ren
From: Guo Ren <guoren@linux.alibaba.com>
The 64ilp32 vDSO brings another new abi into riscv, and it needs to
adjust the current vDSO flow to enable it. This patch separates the
VDSO32 (32ILP32), VDSO64 (64LP64), and VDSO64ILP32 more clearly, and
enable VDSO64ILP32 as need.
Signed-off-by: Guo Ren <guoren@linux.alibaba.com>
Signed-off-by: Guo Ren <guoren@kernel.org>
---
arch/riscv/include/asm/vdso.h | 18 +++---
arch/riscv/kernel/alternative.c | 15 ++++-
arch/riscv/kernel/signal.c | 23 ++++++--
arch/riscv/kernel/vdso.c | 98 +++++++++++++++++++++++++++------
4 files changed, 121 insertions(+), 33 deletions(-)
diff --git a/arch/riscv/include/asm/vdso.h b/arch/riscv/include/asm/vdso.h
index 305ddc6de21c..77015edb1488 100644
--- a/arch/riscv/include/asm/vdso.h
+++ b/arch/riscv/include/asm/vdso.h
@@ -38,15 +38,15 @@ extern char vdso32_start[], vdso32_end[];
#endif /* CONFIG_VDSO32 */
-#ifdef CONFIG_64BIT
-#define vdso_start vdso64_start
-#define vdso_end vdso64_end
-#define VDSO_SYMBOL VDSO64_SYMBOL
-#else /* CONFIG_64BIT */
-#define vdso_start vdso32_start
-#define vdso_end vdso32_end
-#define VDSO_SYMBOL VDSO32_SYMBOL
-#endif /* CONFIG_64BIT */
+#ifdef CONFIG_VDSO64ILP32
+#include <generated/vdso64ilp32-offsets.h>
+
+#define VDSO64ILP32_SYMBOL(base, name) \
+ (void __user *)((unsigned long)(base) + rv64ilp32__vdso_##name##_offset)
+
+extern char vdso64ilp32_start[], vdso64ilp32_end[];
+
+#endif /* CONFIG_VDSO64ILP32 */
#endif /* !__ASSEMBLY__ */
diff --git a/arch/riscv/kernel/alternative.c b/arch/riscv/kernel/alternative.c
index 6b75788c18e6..73a2d7533806 100644
--- a/arch/riscv/kernel/alternative.c
+++ b/arch/riscv/kernel/alternative.c
@@ -182,7 +182,7 @@ static void __init_or_module _apply_alternatives(struct alt_entry *begin,
}
#ifdef CONFIG_MMU
-static void __init apply_vdso_alternatives(void)
+static void __init apply_vdso_alternatives(void *vdso_start)
{
const Elf_Ehdr *hdr;
const Elf_Shdr *shdr;
@@ -203,7 +203,7 @@ static void __init apply_vdso_alternatives(void)
RISCV_ALTERNATIVES_BOOT);
}
#else
-static void __init apply_vdso_alternatives(void) { }
+static void __init apply_vdso_alternatives(void *vdso_start) { }
#endif
void __init apply_boot_alternatives(void)
@@ -216,7 +216,16 @@ void __init apply_boot_alternatives(void)
(struct alt_entry *)__alt_end,
RISCV_ALTERNATIVES_BOOT);
- apply_vdso_alternatives();
+#ifdef CONFIG_VDSO64
+ apply_vdso_alternatives(vdso64_start);
+#endif
+#ifdef CONFIG_VDSO32
+ apply_vdso_alternatives(vdso32_start);
+#endif
+#ifdef CONFIG_VDSO64ILP32
+ apply_vdso_alternatives(vdso64ilp32_start);
+#endif
+
}
/*
diff --git a/arch/riscv/kernel/signal.c b/arch/riscv/kernel/signal.c
index 180d951d3624..95c4a8d8a3f5 100644
--- a/arch/riscv/kernel/signal.c
+++ b/arch/riscv/kernel/signal.c
@@ -345,10 +345,25 @@ static int setup_rt_frame(struct ksignal *ksig, sigset_t *set,
return -EFAULT;
/* Set up to return from userspace. */
-#ifdef CONFIG_MMU
- regs->ra = (unsigned long)VDSO_SYMBOL(
- current->mm->context.vdso, rt_sigreturn);
-#else
+#ifdef CONFIG_VDSO64
+ if (!test_thread_flag(TIF_32BIT))
+ regs->ra = (unsigned long)VDSO64_SYMBOL(
+ current->mm->context.vdso, rt_sigreturn);
+#endif /* CONFIG_VDSO64 */
+
+#ifdef CONFIG_VDSO32
+ if (test_thread_flag(TIF_32BIT) && !test_thread_flag(TIF_64ILP32))
+ regs->ra = (unsigned long)VDSO32_SYMBOL(
+ current->mm->context.vdso, rt_sigreturn);
+#endif /* CONFIG_VDSO32 */
+
+#ifdef CONFIG_VDSO64ILP32
+ if (test_thread_flag(TIF_32BIT) && test_thread_flag(TIF_64ILP32))
+ regs->ra = (unsigned long)VDSO64ILP32_SYMBOL(
+ current->mm->context.vdso, rt_sigreturn);
+#endif /* CONFIG_VDSO64ILP32 */
+
+#ifndef CONFIG_MMU
/*
* For the nommu case we don't have a VDSO. Instead we push two
* instructions to call the rt_sigreturn syscall onto the user stack.
diff --git a/arch/riscv/kernel/vdso.c b/arch/riscv/kernel/vdso.c
index dc03393bf900..6b5cfb7ddbae 100644
--- a/arch/riscv/kernel/vdso.c
+++ b/arch/riscv/kernel/vdso.c
@@ -50,9 +50,14 @@ struct __vdso_info {
struct vm_special_mapping *cm;
};
-static struct __vdso_info vdso_info;
-#ifdef CONFIG_COMPAT
-static struct __vdso_info compat_vdso_info;
+#ifdef CONFIG_VDSO64
+static struct __vdso_info vdso64_info;
+#endif
+#ifdef CONFIG_VDSO32
+static struct __vdso_info vdso32_info;
+#endif
+#ifdef CONFIG_VDSO64ILP32
+static struct __vdso_info vdso64ilp32_info;
#endif
static int vdso_mremap(const struct vm_special_mapping *sm,
@@ -114,10 +119,16 @@ int vdso_join_timens(struct task_struct *task, struct time_namespace *ns)
mmap_read_lock(mm);
for_each_vma(vmi, vma) {
- if (vma_is_special_mapping(vma, vdso_info.dm))
+#ifdef CONFIG_VDSO64
+ if (vma_is_special_mapping(vma, vdso64_info.dm))
zap_vma_pages(vma);
-#ifdef CONFIG_COMPAT
- if (vma_is_special_mapping(vma, compat_vdso_info.dm))
+#endif
+#ifdef CONFIG_VDSO32
+ if (vma_is_special_mapping(vma, vdso32_info.dm))
+ zap_vma_pages(vma);
+#endif
+#ifdef CONFIG_VDSO64ILP32
+ if (vma_is_special_mapping(vma, vdso64ilp32_info.dm))
zap_vma_pages(vma);
#endif
}
@@ -172,13 +183,15 @@ static struct vm_special_mapping rv_vdso_maps[] __ro_after_init = {
},
};
-static struct __vdso_info vdso_info __ro_after_init = {
+#ifdef CONFIG_VDSO64
+static struct __vdso_info vdso64_info __ro_after_init = {
.name = "vdso",
- .vdso_code_start = vdso_start,
- .vdso_code_end = vdso_end,
+ .vdso_code_start = vdso64_start,
+ .vdso_code_end = vdso64_end,
.dm = &rv_vdso_maps[RV_VDSO_MAP_VVAR],
.cm = &rv_vdso_maps[RV_VDSO_MAP_VDSO],
};
+#endif
#ifdef CONFIG_COMPAT
static struct vm_special_mapping rv_compat_vdso_maps[] __ro_after_init = {
@@ -191,21 +204,48 @@ static struct vm_special_mapping rv_compat_vdso_maps[] __ro_after_init = {
.mremap = vdso_mremap,
},
};
+#endif
-static struct __vdso_info compat_vdso_info __ro_after_init = {
- .name = "compat_vdso",
+#ifdef CONFIG_VDSO32
+static struct __vdso_info vdso32_info __ro_after_init = {
+ .name = "vdso32",
.vdso_code_start = vdso32_start,
.vdso_code_end = vdso32_end,
+#ifdef CONFIG_64BIT
.dm = &rv_compat_vdso_maps[RV_VDSO_MAP_VVAR],
.cm = &rv_compat_vdso_maps[RV_VDSO_MAP_VDSO],
+#else
+ .dm = &rv_vdso_maps[RV_VDSO_MAP_VVAR],
+ .cm = &rv_vdso_maps[RV_VDSO_MAP_VDSO],
+#endif
+};
+#endif
+
+#ifdef CONFIG_VDSO64ILP32
+static struct __vdso_info vdso64ilp32_info __ro_after_init = {
+ .name = "vdso64ilp32",
+ .vdso_code_start = vdso64ilp32_start,
+ .vdso_code_end = vdso64ilp32_end,
+#ifdef CONFIG_64BIT
+ .dm = &rv_compat_vdso_maps[RV_VDSO_MAP_VVAR],
+ .cm = &rv_compat_vdso_maps[RV_VDSO_MAP_VDSO],
+#else
+ .dm = &rv_vdso_maps[RV_VDSO_MAP_VVAR],
+ .cm = &rv_vdso_maps[RV_VDSO_MAP_VDSO],
+#endif
};
#endif
static int __init vdso_init(void)
{
- __vdso_init(&vdso_info);
-#ifdef CONFIG_COMPAT
- __vdso_init(&compat_vdso_info);
+#ifdef CONFIG_VDSO64
+ __vdso_init(&vdso64_info);
+#endif
+#ifdef CONFIG_VDSO32
+ __vdso_init(&vdso32_info);
+#endif
+#ifdef CONFIG_VDSO64ILP32
+ __vdso_init(&vdso64ilp32_info);
#endif
return 0;
@@ -265,8 +305,18 @@ int compat_arch_setup_additional_pages(struct linux_binprm *bprm,
if (mmap_write_lock_killable(mm))
return -EINTR;
- ret = __setup_additional_pages(mm, bprm, uses_interp,
- &compat_vdso_info);
+#ifdef CONFIG_VDSO32
+ if (test_thread_flag(TIF_32BIT) && !test_thread_flag(TIF_64ILP32))
+ ret = __setup_additional_pages(mm, bprm, uses_interp,
+ &vdso32_info);
+#endif
+
+#ifdef CONFIG_VDSO64ILP32
+ if (test_thread_flag(TIF_32BIT) && test_thread_flag(TIF_64ILP32))
+ ret = __setup_additional_pages(mm, bprm, uses_interp,
+ &vdso64ilp32_info);
+#endif
+
mmap_write_unlock(mm);
return ret;
@@ -281,7 +331,21 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
if (mmap_write_lock_killable(mm))
return -EINTR;
- ret = __setup_additional_pages(mm, bprm, uses_interp, &vdso_info);
+#ifdef CONFIG_VDSO64
+ if (!test_thread_flag(TIF_32BIT))
+ ret = __setup_additional_pages(mm, bprm, uses_interp, &vdso64_info);
+#endif
+
+#ifdef CONFIG_VDSO32
+ if (test_thread_flag(TIF_32BIT) && !test_thread_flag(TIF_64ILP32))
+ ret = __setup_additional_pages(mm, bprm, uses_interp, &vdso32_info);
+#endif
+
+#ifdef CONFIG_VDSO64ILP32
+ if (test_thread_flag(TIF_32BIT) && test_thread_flag(TIF_64ILP32))
+ ret = __setup_additional_pages(mm, bprm, uses_interp, &vdso64ilp32_info);
+#endif
+
mmap_write_unlock(mm);
return ret;
--
2.36.1
^ permalink raw reply related [flat|nested] 42+ messages in thread* [RFC PATCH V2 06/38] riscv: u64ilp32: Add signal support for compat
2023-11-12 6:14 [RFC PATCH V2 00/38] rv64ilp32: Running ILP32 on RV64 ISA guoren
` (4 preceding siblings ...)
2023-11-12 6:14 ` [RFC PATCH V2 05/38] riscv: u64ilp32: Adjust vDSO kernel flow for 64ilp32 abi guoren
@ 2023-11-12 6:14 ` guoren
2023-11-12 6:14 ` [RFC PATCH V2 07/38] riscv: u64ilp32: Add ptrace interface support guoren
` (34 subsequent siblings)
40 siblings, 0 replies; 42+ messages in thread
From: guoren @ 2023-11-12 6:14 UTC (permalink / raw)
To: arnd, guoren, palmer, tglx, conor.dooley, heiko, apatel, atishp,
bjorn, paul.walmsley, anup, jiawei, liweiwei, wefu, U2FsdGVkX1,
wangjunqiang, kito.cheng, andy.chiu, vincent.chen, greentime.hu,
wuwei2016, jrtc27, luto, fweimer, catalin.marinas, hjl.tools
Cc: linux-arch, linux-kernel, linux-riscv, Guo Ren
From: Guo Ren <guoren@linux.alibaba.com>
The u64ilp32 reuses compat mode on the 64-bit Linux kernel, but the
signal context is the same as the native 64-bit, not u32ilp32. So use
the native signal procedure for u64ilp32 applications.
Signed-off-by: Guo Ren <guoren@linux.alibaba.com>
Signed-off-by: Guo Ren <guoren@kernel.org>
---
arch/riscv/include/asm/signal32.h | 9 ++++++
arch/riscv/kernel/compat_signal.c | 21 ++++--------
arch/riscv/kernel/signal.c | 53 ++++++++++++++++++++++---------
3 files changed, 54 insertions(+), 29 deletions(-)
diff --git a/arch/riscv/include/asm/signal32.h b/arch/riscv/include/asm/signal32.h
index 96dc56932e76..cda62d7eb0a5 100644
--- a/arch/riscv/include/asm/signal32.h
+++ b/arch/riscv/include/asm/signal32.h
@@ -6,6 +6,7 @@
#if IS_ENABLED(CONFIG_COMPAT)
int compat_setup_rt_frame(struct ksignal *ksig, sigset_t *set,
struct pt_regs *regs);
+long __riscv_compat_rt_sigreturn(void);
#else
static inline
int compat_setup_rt_frame(struct ksignal *ksig, sigset_t *set,
@@ -13,6 +14,14 @@ int compat_setup_rt_frame(struct ksignal *ksig, sigset_t *set,
{
return -1;
}
+
+static inline
+long __riscv_compat_rt_sigreturn(void)
+{
+ return -1;
+}
#endif
+void __riscv_rt_sigreturn_badframe(void);
+
#endif
diff --git a/arch/riscv/kernel/compat_signal.c b/arch/riscv/kernel/compat_signal.c
index 8dea2012836e..955a638da2a4 100644
--- a/arch/riscv/kernel/compat_signal.c
+++ b/arch/riscv/kernel/compat_signal.c
@@ -116,18 +116,16 @@ static long compat_restore_sigcontext(struct pt_regs *regs,
return err;
}
-COMPAT_SYSCALL_DEFINE0(rt_sigreturn)
+long __riscv_compat_rt_sigreturn(void)
{
- struct pt_regs *regs = current_pt_regs();
- struct compat_rt_sigframe __user *frame;
- struct task_struct *task;
sigset_t set;
+ struct pt_regs *regs = current_pt_regs();
+ struct compat_rt_sigframe __user *frame =
+ (struct compat_rt_sigframe __user *)kernel_stack_pointer(regs);
/* Always make any pending restarted system calls return -EINTR */
current->restart_block.fn = do_no_restart_syscall;
- frame = (struct compat_rt_sigframe __user *)regs->sp;
-
if (!access_ok(frame, sizeof(*frame)))
goto badframe;
@@ -142,17 +140,12 @@ COMPAT_SYSCALL_DEFINE0(rt_sigreturn)
if (compat_restore_altstack(&frame->uc.uc_stack))
goto badframe;
+ regs->cause = -1UL;
+
return regs->a0;
badframe:
- task = current;
- if (show_unhandled_signals) {
- pr_info_ratelimited(
- "%s[%d]: bad frame in %s: frame=%p pc=%p sp=%p\n",
- task->comm, task_pid_nr(task), __func__,
- frame, (void *)regs->epc, (void *)regs->sp);
- }
- force_sig(SIGSEGV);
+ __riscv_rt_sigreturn_badframe();
return 0;
}
diff --git a/arch/riscv/kernel/signal.c b/arch/riscv/kernel/signal.c
index 95c4a8d8a3f5..1c51a6783c98 100644
--- a/arch/riscv/kernel/signal.c
+++ b/arch/riscv/kernel/signal.c
@@ -224,19 +224,34 @@ static size_t get_rt_frame_size(bool cal_all)
return frame_size;
}
-SYSCALL_DEFINE0(rt_sigreturn)
+void __riscv_rt_sigreturn_badframe(void)
+{
+ struct task_struct *task = current;
+ struct pt_regs *regs = task_pt_regs(task);
+
+ if (show_unhandled_signals) {
+ pr_info_ratelimited(
+ "%s[%d]: bad frame in %s: frame=%p pc=%p sp=%p\n",
+ task->comm, task_pid_nr(task), __func__,
+ (void *)kernel_stack_pointer(regs),
+ (void *)instruction_pointer(regs),
+ (void *)kernel_stack_pointer(regs));
+ }
+
+ force_sig(SIGSEGV);
+}
+
+static long __riscv_rt_sigreturn(void)
{
- struct pt_regs *regs = current_pt_regs();
- struct rt_sigframe __user *frame;
- struct task_struct *task;
sigset_t set;
size_t frame_size = get_rt_frame_size(false);
+ struct pt_regs *regs = current_pt_regs();
+ struct rt_sigframe __user *frame =
+ (struct rt_sigframe __user *)kernel_stack_pointer(regs);
/* Always make any pending restarted system calls return -EINTR */
current->restart_block.fn = do_no_restart_syscall;
- frame = (struct rt_sigframe __user *)regs->sp;
-
if (!access_ok(frame, frame_size))
goto badframe;
@@ -256,17 +271,25 @@ SYSCALL_DEFINE0(rt_sigreturn)
return regs->a0;
badframe:
- task = current;
- if (show_unhandled_signals) {
- pr_info_ratelimited(
- "%s[%d]: bad frame in %s: frame=%p pc=%p sp=%p\n",
- task->comm, task_pid_nr(task), __func__,
- frame, (void *)regs->epc, (void *)regs->sp);
- }
- force_sig(SIGSEGV);
+ __riscv_rt_sigreturn_badframe();
return 0;
}
+SYSCALL_DEFINE0(rt_sigreturn)
+{
+ return __riscv_rt_sigreturn();
+}
+
+#ifdef CONFIG_COMPAT
+COMPAT_SYSCALL_DEFINE0(rt_sigreturn)
+{
+ if (test_thread_flag(TIF_32BIT) && !test_thread_flag(TIF_64ILP32))
+ return __riscv_compat_rt_sigreturn();
+ else
+ return __riscv_rt_sigreturn();
+}
+#endif
+
static long setup_sigcontext(struct rt_sigframe __user *frame,
struct pt_regs *regs)
{
@@ -433,7 +456,7 @@ static void handle_signal(struct ksignal *ksig, struct pt_regs *regs)
rseq_signal_deliver(ksig, regs);
/* Set up the stack frame */
- if (is_compat_task())
+ if (test_thread_flag(TIF_32BIT) && !test_thread_flag(TIF_64ILP32))
ret = compat_setup_rt_frame(ksig, oldset, regs);
else
ret = setup_rt_frame(ksig, oldset, regs);
--
2.36.1
^ permalink raw reply related [flat|nested] 42+ messages in thread* [RFC PATCH V2 07/38] riscv: u64ilp32: Add ptrace interface support
2023-11-12 6:14 [RFC PATCH V2 00/38] rv64ilp32: Running ILP32 on RV64 ISA guoren
` (5 preceding siblings ...)
2023-11-12 6:14 ` [RFC PATCH V2 06/38] riscv: u64ilp32: Add signal support for compat guoren
@ 2023-11-12 6:14 ` guoren
2023-11-12 6:14 ` [RFC PATCH V2 08/38] riscv: u64ilp32: Adjust vDSO alternative for 64ilp32 abi guoren
` (33 subsequent siblings)
40 siblings, 0 replies; 42+ messages in thread
From: guoren @ 2023-11-12 6:14 UTC (permalink / raw)
To: arnd, guoren, palmer, tglx, conor.dooley, heiko, apatel, atishp,
bjorn, paul.walmsley, anup, jiawei, liweiwei, wefu, U2FsdGVkX1,
wangjunqiang, kito.cheng, andy.chiu, vincent.chen, greentime.hu,
wuwei2016, jrtc27, luto, fweimer, catalin.marinas, hjl.tools
Cc: linux-arch, linux-kernel, linux-riscv, Guo Ren
From: Guo Ren <guoren@linux.alibaba.com>
The pt_regs of u64ilp32 is the same as the 64-bit kernel's. So, change
to use native_view instead.
Signed-off-by: Guo Ren <guoren@linux.alibaba.com>
Signed-off-by: Guo Ren <guoren@kernel.org>
---
arch/riscv/kernel/ptrace.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/arch/riscv/kernel/ptrace.c b/arch/riscv/kernel/ptrace.c
index 1d572cf3140f..5471b12127da 100644
--- a/arch/riscv/kernel/ptrace.c
+++ b/arch/riscv/kernel/ptrace.c
@@ -369,7 +369,8 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
const struct user_regset_view *task_user_regset_view(struct task_struct *task)
{
#ifdef CONFIG_COMPAT
- if (test_tsk_thread_flag(task, TIF_32BIT))
+ if (test_tsk_thread_flag(task, TIF_32BIT) &&
+ !test_tsk_thread_flag(task, TIF_64ILP32))
return &compat_riscv_user_native_view;
else
#endif
--
2.36.1
^ permalink raw reply related [flat|nested] 42+ messages in thread* [RFC PATCH V2 08/38] riscv: u64ilp32: Adjust vDSO alternative for 64ilp32 abi
2023-11-12 6:14 [RFC PATCH V2 00/38] rv64ilp32: Running ILP32 on RV64 ISA guoren
` (6 preceding siblings ...)
2023-11-12 6:14 ` [RFC PATCH V2 07/38] riscv: u64ilp32: Add ptrace interface support guoren
@ 2023-11-12 6:14 ` guoren
2023-11-12 6:14 ` [RFC PATCH V2 09/38] riscv: u64ilp32: Add xlen_t in user_regs_struct guoren
` (32 subsequent siblings)
40 siblings, 0 replies; 42+ messages in thread
From: guoren @ 2023-11-12 6:14 UTC (permalink / raw)
To: arnd, guoren, palmer, tglx, conor.dooley, heiko, apatel, atishp,
bjorn, paul.walmsley, anup, jiawei, liweiwei, wefu, U2FsdGVkX1,
wangjunqiang, kito.cheng, andy.chiu, vincent.chen, greentime.hu,
wuwei2016, jrtc27, luto, fweimer, catalin.marinas, hjl.tools
Cc: linux-arch, linux-kernel, linux-riscv, Guo Ren
From: Guo Ren <guoren@linux.alibaba.com>
The 64ilp32 uses the same ELF32 as 32ilp32 and the 64lp64 uses ELF64, so
separate apply_vdso_alternatives into 64 and 32 versions and serve for
three kinds of vDSO - vdso32, vdso64, vdso64ilp32.
Signed-off-by: Guo Ren <guoren@linux.alibaba.com>
Signed-off-by: Guo Ren <guoren@kernel.org>
---
arch/riscv/include/asm/module.h | 30 ++++++++++++++++++++++
arch/riscv/kernel/alternative.c | 45 ++++++++++++++++++++++++---------
2 files changed, 63 insertions(+), 12 deletions(-)
diff --git a/arch/riscv/include/asm/module.h b/arch/riscv/include/asm/module.h
index 0f3baaa6a9a8..9f556435a1a4 100644
--- a/arch/riscv/include/asm/module.h
+++ b/arch/riscv/include/asm/module.h
@@ -127,4 +127,34 @@ static inline const Elf_Shdr *find_section(const Elf_Ehdr *hdr,
return NULL;
}
+static inline const Elf64_Shdr *find_section64(const Elf64_Ehdr *hdr,
+ const Elf64_Shdr *sechdrs,
+ const char *name)
+{
+ const Elf64_Shdr *s, *se;
+ const char *secstrs = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset;
+
+ for (s = sechdrs, se = sechdrs + hdr->e_shnum; s < se; s++) {
+ if (strcmp(name, secstrs + s->sh_name) == 0)
+ return s;
+ }
+
+ return NULL;
+}
+
+static inline const Elf32_Shdr *find_section32(const Elf32_Ehdr *hdr,
+ const Elf32_Shdr *sechdrs,
+ const char *name)
+{
+ const Elf32_Shdr *s, *se;
+ const char *secstrs = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset;
+
+ for (s = sechdrs, se = sechdrs + hdr->e_shnum; s < se; s++) {
+ if (strcmp(name, secstrs + s->sh_name) == 0)
+ return s;
+ }
+
+ return NULL;
+}
+
#endif /* _ASM_RISCV_MODULE_H */
diff --git a/arch/riscv/kernel/alternative.c b/arch/riscv/kernel/alternative.c
index 73a2d7533806..ab9eb42a5502 100644
--- a/arch/riscv/kernel/alternative.c
+++ b/arch/riscv/kernel/alternative.c
@@ -181,17 +181,40 @@ static void __init_or_module _apply_alternatives(struct alt_entry *begin,
stage);
}
-#ifdef CONFIG_MMU
-static void __init apply_vdso_alternatives(void *vdso_start)
+#ifdef CONFIG_VDSO64
+static void __init apply_vdso_alternatives64(void *vdso_start)
{
- const Elf_Ehdr *hdr;
- const Elf_Shdr *shdr;
- const Elf_Shdr *alt;
+ const Elf64_Ehdr *hdr;
+ const Elf64_Shdr *shdr;
+ const Elf64_Shdr *alt;
struct alt_entry *begin, *end;
- hdr = (Elf_Ehdr *)vdso_start;
+ hdr = (Elf64_Ehdr *)vdso_start;
shdr = (void *)hdr + hdr->e_shoff;
- alt = find_section(hdr, shdr, ".alternative");
+ alt = find_section64(hdr, shdr, ".alternative");
+ if (!alt)
+ return;
+
+ begin = (void *)hdr + alt->sh_offset,
+ end = (void *)hdr + alt->sh_offset + alt->sh_size,
+
+ _apply_alternatives((struct alt_entry *)begin,
+ (struct alt_entry *)end,
+ RISCV_ALTERNATIVES_BOOT);
+}
+#endif
+
+#if IS_ENABLED(CONFIG_VDSO32) || IS_ENABLED(CONFIG_VDSO64ILP32)
+static void __init apply_vdso_alternatives32(void *vdso_start)
+{
+ const Elf32_Ehdr *hdr;
+ const Elf32_Shdr *shdr;
+ const Elf32_Shdr *alt;
+ struct alt_entry *begin, *end;
+
+ hdr = (Elf32_Ehdr *)vdso_start;
+ shdr = (void *)hdr + hdr->e_shoff;
+ alt = find_section32(hdr, shdr, ".alternative");
if (!alt)
return;
@@ -202,8 +225,6 @@ static void __init apply_vdso_alternatives(void *vdso_start)
(struct alt_entry *)end,
RISCV_ALTERNATIVES_BOOT);
}
-#else
-static void __init apply_vdso_alternatives(void *vdso_start) { }
#endif
void __init apply_boot_alternatives(void)
@@ -217,13 +238,13 @@ void __init apply_boot_alternatives(void)
RISCV_ALTERNATIVES_BOOT);
#ifdef CONFIG_VDSO64
- apply_vdso_alternatives(vdso64_start);
+ apply_vdso_alternatives64(vdso64_start);
#endif
#ifdef CONFIG_VDSO32
- apply_vdso_alternatives(vdso32_start);
+ apply_vdso_alternatives32(vdso32_start);
#endif
#ifdef CONFIG_VDSO64ILP32
- apply_vdso_alternatives(vdso64ilp32_start);
+ apply_vdso_alternatives32(vdso64ilp32_start);
#endif
}
--
2.36.1
^ permalink raw reply related [flat|nested] 42+ messages in thread* [RFC PATCH V2 09/38] riscv: u64ilp32: Add xlen_t in user_regs_struct
2023-11-12 6:14 [RFC PATCH V2 00/38] rv64ilp32: Running ILP32 on RV64 ISA guoren
` (7 preceding siblings ...)
2023-11-12 6:14 ` [RFC PATCH V2 08/38] riscv: u64ilp32: Adjust vDSO alternative for 64ilp32 abi guoren
@ 2023-11-12 6:14 ` guoren
2023-11-12 6:14 ` [RFC PATCH V2 10/38] riscv: u64ilp32: Remove the restriction of UXL=32 guoren
` (31 subsequent siblings)
40 siblings, 0 replies; 42+ messages in thread
From: guoren @ 2023-11-12 6:14 UTC (permalink / raw)
To: arnd, guoren, palmer, tglx, conor.dooley, heiko, apatel, atishp,
bjorn, paul.walmsley, anup, jiawei, liweiwei, wefu, U2FsdGVkX1,
wangjunqiang, kito.cheng, andy.chiu, vincent.chen, greentime.hu,
wuwei2016, jrtc27, luto, fweimer, catalin.marinas, hjl.tools
Cc: linux-arch, linux-kernel, linux-riscv, Guo Ren
From: Guo Ren <guoren@linux.alibaba.com>
The u64ilp32 xlen is 64-bit, not the size of long, so change the
elements of user_regs_struct with xlen_t to match different
__riscv_xlen.
Signed-off-by: Guo Ren <guoren@linux.alibaba.com>
Signed-off-by: Guo Ren <guoren@kernel.org>
---
arch/riscv/include/uapi/asm/ptrace.h | 72 +++++++++++++++-------------
1 file changed, 40 insertions(+), 32 deletions(-)
diff --git a/arch/riscv/include/uapi/asm/ptrace.h b/arch/riscv/include/uapi/asm/ptrace.h
index e17c550986a6..39e8d10eebaf 100644
--- a/arch/riscv/include/uapi/asm/ptrace.h
+++ b/arch/riscv/include/uapi/asm/ptrace.h
@@ -10,6 +10,14 @@
#include <linux/types.h>
+#if __riscv_xlen == 64
+typedef __u64 xlen_t;
+#elif __riscv_xlen == 32
+typedef __u32 xlen_t;
+#else
+#error "Unexpected __riscv_xlen"
+#endif
+
/*
* User-mode register state for core dumps, ptrace, sigcontext
*
@@ -17,38 +25,38 @@
* struct user_regs_struct must form a prefix of struct pt_regs.
*/
struct user_regs_struct {
- unsigned long pc;
- unsigned long ra;
- unsigned long sp;
- unsigned long gp;
- unsigned long tp;
- unsigned long t0;
- unsigned long t1;
- unsigned long t2;
- unsigned long s0;
- unsigned long s1;
- unsigned long a0;
- unsigned long a1;
- unsigned long a2;
- unsigned long a3;
- unsigned long a4;
- unsigned long a5;
- unsigned long a6;
- unsigned long a7;
- unsigned long s2;
- unsigned long s3;
- unsigned long s4;
- unsigned long s5;
- unsigned long s6;
- unsigned long s7;
- unsigned long s8;
- unsigned long s9;
- unsigned long s10;
- unsigned long s11;
- unsigned long t3;
- unsigned long t4;
- unsigned long t5;
- unsigned long t6;
+ xlen_t pc;
+ xlen_t ra;
+ xlen_t sp;
+ xlen_t gp;
+ xlen_t tp;
+ xlen_t t0;
+ xlen_t t1;
+ xlen_t t2;
+ xlen_t s0;
+ xlen_t s1;
+ xlen_t a0;
+ xlen_t a1;
+ xlen_t a2;
+ xlen_t a3;
+ xlen_t a4;
+ xlen_t a5;
+ xlen_t a6;
+ xlen_t a7;
+ xlen_t s2;
+ xlen_t s3;
+ xlen_t s4;
+ xlen_t s5;
+ xlen_t s6;
+ xlen_t s7;
+ xlen_t s8;
+ xlen_t s9;
+ xlen_t s10;
+ xlen_t s11;
+ xlen_t t3;
+ xlen_t t4;
+ xlen_t t5;
+ xlen_t t6;
};
struct __riscv_f_ext_state {
--
2.36.1
^ permalink raw reply related [flat|nested] 42+ messages in thread* [RFC PATCH V2 10/38] riscv: u64ilp32: Remove the restriction of UXL=32
2023-11-12 6:14 [RFC PATCH V2 00/38] rv64ilp32: Running ILP32 on RV64 ISA guoren
` (8 preceding siblings ...)
2023-11-12 6:14 ` [RFC PATCH V2 09/38] riscv: u64ilp32: Add xlen_t in user_regs_struct guoren
@ 2023-11-12 6:14 ` guoren
2023-11-12 6:14 ` [RFC PATCH V2 11/38] riscv: u64ilp32: Enable user space runtime switch guoren
` (30 subsequent siblings)
40 siblings, 0 replies; 42+ messages in thread
From: guoren @ 2023-11-12 6:14 UTC (permalink / raw)
To: arnd, guoren, palmer, tglx, conor.dooley, heiko, apatel, atishp,
bjorn, paul.walmsley, anup, jiawei, liweiwei, wefu, U2FsdGVkX1,
wangjunqiang, kito.cheng, andy.chiu, vincent.chen, greentime.hu,
wuwei2016, jrtc27, luto, fweimer, catalin.marinas, hjl.tools
Cc: linux-arch, linux-kernel, linux-riscv, Guo Ren
From: Guo Ren <guoren@linux.alibaba.com>
The u64ilp32 needn't hardware support UXL=32, so remove the
restriction when EF_RISCV_64ILP32 is detected.
Reported-by: Junqiang Wang <wangjunqiang@iscas.ac.cn>
Signed-off-by: Guo Ren <guoren@linux.alibaba.com>
Signed-off-by: Guo Ren <guoren@kernel.org>
---
arch/riscv/kernel/process.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/riscv/kernel/process.c b/arch/riscv/kernel/process.c
index e32d737e039f..93057ca2e2a7 100644
--- a/arch/riscv/kernel/process.c
+++ b/arch/riscv/kernel/process.c
@@ -88,7 +88,7 @@ static bool compat_mode_supported __read_mostly;
bool compat_elf_check_arch(Elf32_Ehdr *hdr)
{
- return compat_mode_supported &&
+ return (compat_mode_supported || (hdr->e_flags & EF_RISCV_64ILP32)) &&
hdr->e_machine == EM_RISCV &&
hdr->e_ident[EI_CLASS] == ELFCLASS32;
}
--
2.36.1
^ permalink raw reply related [flat|nested] 42+ messages in thread* [RFC PATCH V2 11/38] riscv: u64ilp32: Enable user space runtime switch
2023-11-12 6:14 [RFC PATCH V2 00/38] rv64ilp32: Running ILP32 on RV64 ISA guoren
` (9 preceding siblings ...)
2023-11-12 6:14 ` [RFC PATCH V2 10/38] riscv: u64ilp32: Remove the restriction of UXL=32 guoren
@ 2023-11-12 6:14 ` guoren
2023-11-12 6:14 ` [RFC PATCH V2 12/38] riscv: s64ilp32: Unify ULL & UL into UXL in csr guoren
` (29 subsequent siblings)
40 siblings, 0 replies; 42+ messages in thread
From: guoren @ 2023-11-12 6:14 UTC (permalink / raw)
To: arnd, guoren, palmer, tglx, conor.dooley, heiko, apatel, atishp,
bjorn, paul.walmsley, anup, jiawei, liweiwei, wefu, U2FsdGVkX1,
wangjunqiang, kito.cheng, andy.chiu, vincent.chen, greentime.hu,
wuwei2016, jrtc27, luto, fweimer, catalin.marinas, hjl.tools
Cc: linux-arch, linux-kernel, linux-riscv, Guo Ren
From: Guo Ren <guoren@linux.alibaba.com>
This patch didn't introduce any new syscall table but reused the
existing rv32 implementation to ease the maintenance of the kernel side.
Unify the UXL mode setting by ELF e_flags to support u64ilp32 &
u32ilp32.
Signed-off-by: Guo Ren <guoren@linux.alibaba.com>
Signed-off-by: Guo Ren <guoren@kernel.org>
---
arch/riscv/include/asm/csr.h | 2 --
arch/riscv/include/asm/elf.h | 7 ++++++-
arch/riscv/include/asm/syscall.h | 2 +-
arch/riscv/include/asm/thread_info.h | 1 +
arch/riscv/kernel/process.c | 4 +---
5 files changed, 9 insertions(+), 7 deletions(-)
diff --git a/arch/riscv/include/asm/csr.h b/arch/riscv/include/asm/csr.h
index 7bac43a3176e..638b7a836acc 100644
--- a/arch/riscv/include/asm/csr.h
+++ b/arch/riscv/include/asm/csr.h
@@ -44,11 +44,9 @@
#define SR_SD _AC(0x8000000000000000, UL) /* FS/VS/XS dirty */
#endif
-#ifdef CONFIG_64BIT
#define SR_UXL _AC(0x300000000, UL) /* XLEN mask for U-mode */
#define SR_UXL_32 _AC(0x100000000, UL) /* XLEN = 32 for U-mode */
#define SR_UXL_64 _AC(0x200000000, UL) /* XLEN = 64 for U-mode */
-#endif
/* SATP flags */
#ifndef CONFIG_64BIT
diff --git a/arch/riscv/include/asm/elf.h b/arch/riscv/include/asm/elf.h
index c24280774caf..5b2bf1a7cb59 100644
--- a/arch/riscv/include/asm/elf.h
+++ b/arch/riscv/include/asm/elf.h
@@ -127,18 +127,23 @@ do { \
*(struct user_regs_struct *)regs; \
} while (0);
-#ifdef CONFIG_COMPAT
+#define EF_RISCV_64ILP32 0x20
#define SET_PERSONALITY(ex) \
do { if ((ex).e_ident[EI_CLASS] == ELFCLASS32) \
set_thread_flag(TIF_32BIT); \
else \
clear_thread_flag(TIF_32BIT); \
+ if ((ex).e_flags & EF_RISCV_64ILP32) \
+ set_thread_flag(TIF_64ILP32); \
+ else \
+ clear_thread_flag(TIF_64ILP32); \
if (personality(current->personality) != PER_LINUX32) \
set_personality(PER_LINUX | \
(current->personality & (~PER_MASK))); \
} while (0)
+#ifdef CONFIG_COMPAT
#define COMPAT_ELF_ET_DYN_BASE ((TASK_SIZE_32 / 3) * 2)
/* rv32 registers */
diff --git a/arch/riscv/include/asm/syscall.h b/arch/riscv/include/asm/syscall.h
index 0148c6bd9675..a1122b88c362 100644
--- a/arch/riscv/include/asm/syscall.h
+++ b/arch/riscv/include/asm/syscall.h
@@ -81,7 +81,7 @@ static inline void syscall_handler(struct pt_regs *regs, ulong syscall)
syscall_t fn;
#ifdef CONFIG_COMPAT
- if ((regs->status & SR_UXL) == SR_UXL_32)
+ if (test_thread_flag(TIF_32BIT))
fn = compat_sys_call_table[syscall];
else
#endif
diff --git a/arch/riscv/include/asm/thread_info.h b/arch/riscv/include/asm/thread_info.h
index 1833beb00489..61f7101aebb3 100644
--- a/arch/riscv/include/asm/thread_info.h
+++ b/arch/riscv/include/asm/thread_info.h
@@ -93,6 +93,7 @@ int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src);
#define TIF_NOTIFY_SIGNAL 9 /* signal notifications exist */
#define TIF_UPROBE 10 /* uprobe breakpoint or singlestep */
#define TIF_32BIT 11 /* compat-mode 32bit process */
+#define TIF_64ILP32 12 /* 64ILP32 process */
#define _TIF_NOTIFY_RESUME (1 << TIF_NOTIFY_RESUME)
#define _TIF_SIGPENDING (1 << TIF_SIGPENDING)
diff --git a/arch/riscv/kernel/process.c b/arch/riscv/kernel/process.c
index 93057ca2e2a7..87bdb0d6dbf3 100644
--- a/arch/riscv/kernel/process.c
+++ b/arch/riscv/kernel/process.c
@@ -126,14 +126,12 @@ void start_thread(struct pt_regs *regs, unsigned long pc,
regs->epc = pc;
regs->sp = sp;
-#ifdef CONFIG_64BIT
regs->status &= ~SR_UXL;
- if (is_compat_task())
+ if (test_thread_flag(TIF_32BIT) && !test_thread_flag(TIF_64ILP32))
regs->status |= SR_UXL_32;
else
regs->status |= SR_UXL_64;
-#endif
}
void flush_thread(void)
--
2.36.1
^ permalink raw reply related [flat|nested] 42+ messages in thread* [RFC PATCH V2 12/38] riscv: s64ilp32: Unify ULL & UL into UXL in csr
2023-11-12 6:14 [RFC PATCH V2 00/38] rv64ilp32: Running ILP32 on RV64 ISA guoren
` (10 preceding siblings ...)
2023-11-12 6:14 ` [RFC PATCH V2 11/38] riscv: u64ilp32: Enable user space runtime switch guoren
@ 2023-11-12 6:14 ` guoren
2023-11-12 6:14 ` [RFC PATCH V2 13/38] riscv: s64ilp32: Introduce xlen_t for 64ILP32 kernel guoren
` (28 subsequent siblings)
40 siblings, 0 replies; 42+ messages in thread
From: guoren @ 2023-11-12 6:14 UTC (permalink / raw)
To: arnd, guoren, palmer, tglx, conor.dooley, heiko, apatel, atishp,
bjorn, paul.walmsley, anup, jiawei, liweiwei, wefu, U2FsdGVkX1,
wangjunqiang, kito.cheng, andy.chiu, vincent.chen, greentime.hu,
wuwei2016, jrtc27, luto, fweimer, catalin.marinas, hjl.tools
Cc: linux-arch, linux-kernel, linux-riscv, Guo Ren
From: Guo Ren <guoren@linux.alibaba.com>
The 64ilp32's long size has been different from the csr xlen, so
introduce a new macro of UXL to distinguish UL & ULL.
Signed-off-by: Guo Ren <guoren@linux.alibaba.com>
Signed-off-by: Guo Ren <guoren@kernel.org>
---
arch/riscv/include/asm/csr.h | 166 +++++++++++++++++++----------------
1 file changed, 89 insertions(+), 77 deletions(-)
diff --git a/arch/riscv/include/asm/csr.h b/arch/riscv/include/asm/csr.h
index 638b7a836acc..051c017e1e5e 100644
--- a/arch/riscv/include/asm/csr.h
+++ b/arch/riscv/include/asm/csr.h
@@ -9,64 +9,76 @@
#include <asm/asm.h>
#include <linux/bits.h>
+#if __riscv_xlen == 32
+#define UXL UL
+#define GENMASK_UXL GENMASK
+#else
+#define UXL ULL
+#define GENMASK_UXL GENMASK_ULL
+#endif
+
/* Status register flags */
-#define SR_SIE _AC(0x00000002, UL) /* Supervisor Interrupt Enable */
-#define SR_MIE _AC(0x00000008, UL) /* Machine Interrupt Enable */
-#define SR_SPIE _AC(0x00000020, UL) /* Previous Supervisor IE */
-#define SR_MPIE _AC(0x00000080, UL) /* Previous Machine IE */
-#define SR_SPP _AC(0x00000100, UL) /* Previously Supervisor */
-#define SR_MPP _AC(0x00001800, UL) /* Previously Machine */
-#define SR_SUM _AC(0x00040000, UL) /* Supervisor User Memory Access */
-
-#define SR_FS _AC(0x00006000, UL) /* Floating-point Status */
-#define SR_FS_OFF _AC(0x00000000, UL)
-#define SR_FS_INITIAL _AC(0x00002000, UL)
-#define SR_FS_CLEAN _AC(0x00004000, UL)
-#define SR_FS_DIRTY _AC(0x00006000, UL)
-
-#define SR_VS _AC(0x00000600, UL) /* Vector Status */
-#define SR_VS_OFF _AC(0x00000000, UL)
-#define SR_VS_INITIAL _AC(0x00000200, UL)
-#define SR_VS_CLEAN _AC(0x00000400, UL)
-#define SR_VS_DIRTY _AC(0x00000600, UL)
-
-#define SR_XS _AC(0x00018000, UL) /* Extension Status */
-#define SR_XS_OFF _AC(0x00000000, UL)
-#define SR_XS_INITIAL _AC(0x00008000, UL)
-#define SR_XS_CLEAN _AC(0x00010000, UL)
-#define SR_XS_DIRTY _AC(0x00018000, UL)
+#define SR_SIE _AC(0x00000002, UXL) /* Supervisor Interrupt Enable */
+#define SR_MIE _AC(0x00000008, UXL) /* Machine Interrupt Enable */
+#define SR_SPIE _AC(0x00000020, UXL) /* Previous Supervisor IE */
+#define SR_MPIE _AC(0x00000080, UXL) /* Previous Machine IE */
+#define SR_SPP _AC(0x00000100, UXL) /* Previously Supervisor */
+#define SR_MPP _AC(0x00001800, UXL) /* Previously Machine */
+#define SR_SUM _AC(0x00040000, UXL) /* Supervisor User Memory Access */
+
+#define SR_FS _AC(0x00006000, UXL) /* Floating-point Status */
+#define SR_FS_OFF _AC(0x00000000, UXL)
+#define SR_FS_INITIAL _AC(0x00002000, UXL)
+#define SR_FS_CLEAN _AC(0x00004000, UXL)
+#define SR_FS_DIRTY _AC(0x00006000, UXL)
+
+#define SR_VS _AC(0x00000600, UXL) /* Vector Status */
+#define SR_VS_OFF _AC(0x00000000, UXL)
+#define SR_VS_INITIAL _AC(0x00000200, UXL)
+#define SR_VS_CLEAN _AC(0x00000400, UXL)
+#define SR_VS_DIRTY _AC(0x00000600, UXL)
+
+#define SR_XS _AC(0x00018000, UXL) /* Extension Status */
+#define SR_XS_OFF _AC(0x00000000, UXL)
+#define SR_XS_INITIAL _AC(0x00008000, UXL)
+#define SR_XS_CLEAN _AC(0x00010000, UXL)
+#define SR_XS_DIRTY _AC(0x00018000, UXL)
#define SR_FS_VS (SR_FS | SR_VS) /* Vector and Floating-Point Unit */
-#ifndef CONFIG_64BIT
-#define SR_SD _AC(0x80000000, UL) /* FS/VS/XS dirty */
+#if __riscv_xlen == 32
+#define SR_SD _AC(0x80000000, UXL) /* FS/VS/XS dirty */
#else
-#define SR_SD _AC(0x8000000000000000, UL) /* FS/VS/XS dirty */
+#define SR_SD _AC(0x8000000000000000, UXL) /* FS/VS/XS dirty */
#endif
-#define SR_UXL _AC(0x300000000, UL) /* XLEN mask for U-mode */
-#define SR_UXL_32 _AC(0x100000000, UL) /* XLEN = 32 for U-mode */
-#define SR_UXL_64 _AC(0x200000000, UL) /* XLEN = 64 for U-mode */
+#define SR_UXL _AC(0x300000000, UXL) /* XLEN mask for U-mode */
+#define SR_UXL_32 _AC(0x100000000, UXL) /* XLEN = 32 for U-mode */
+#define SR_UXL_64 _AC(0x200000000, UXL) /* XLEN = 64 for U-mode */
/* SATP flags */
-#ifndef CONFIG_64BIT
-#define SATP_PPN _AC(0x003FFFFF, UL)
-#define SATP_MODE_32 _AC(0x80000000, UL)
+#if __riscv_xlen == 32
+#define SATP_PPN _AC(0x003FFFFF, UXL)
+#define SATP_MODE_32 _AC(0x80000000, UXL)
#define SATP_ASID_BITS 9
#define SATP_ASID_SHIFT 22
-#define SATP_ASID_MASK _AC(0x1FF, UL)
+#define SATP_ASID_MASK _AC(0x1FF, UXL)
#else
-#define SATP_PPN _AC(0x00000FFFFFFFFFFF, UL)
-#define SATP_MODE_39 _AC(0x8000000000000000, UL)
-#define SATP_MODE_48 _AC(0x9000000000000000, UL)
-#define SATP_MODE_57 _AC(0xa000000000000000, UL)
+#define SATP_PPN _AC(0x00000FFFFFFFFFFF, UXL)
+#define SATP_MODE_39 _AC(0x8000000000000000, UXL)
+#define SATP_MODE_48 _AC(0x9000000000000000, UXL)
+#define SATP_MODE_57 _AC(0xa000000000000000, UXL)
#define SATP_ASID_BITS 16
#define SATP_ASID_SHIFT 44
-#define SATP_ASID_MASK _AC(0xFFFF, UL)
+#define SATP_ASID_MASK _AC(0xFFFF, UXL)
#endif
/* Exception cause high bit - is an interrupt if set */
-#define CAUSE_IRQ_FLAG (_AC(1, UL) << (__riscv_xlen - 1))
+#if __riscv_xlen == 32
+#define CAUSE_IRQ_FLAG (_AC(1, UXL) << (__riscv_xlen - 1))
+#else
+#define CAUSE_IRQ_FLAG (_AC(1, UXL) << (__riscv_xlen - 1))
+#endif
/* Interrupt causes (minus the high bit) */
#define IRQ_S_SOFT 1
@@ -81,7 +93,7 @@
#define IRQ_S_GEXT 12
#define IRQ_PMU_OVF 13
#define IRQ_LOCAL_MAX (IRQ_PMU_OVF + 1)
-#define IRQ_LOCAL_MASK GENMASK((IRQ_LOCAL_MAX - 1), 0)
+#define IRQ_LOCAL_MASK GENMASK_UXL((IRQ_LOCAL_MAX - 1), 0)
/* Exception causes */
#define EXC_INST_MISALIGNED 0
@@ -114,41 +126,41 @@
#define PMP_L 0x80
/* HSTATUS flags */
-#ifdef CONFIG_64BIT
-#define HSTATUS_VSXL _AC(0x300000000, UL)
+#if __riscv_xlen == 64
+#define HSTATUS_VSXL _AC(0x300000000, UXL)
#define HSTATUS_VSXL_SHIFT 32
#endif
-#define HSTATUS_VTSR _AC(0x00400000, UL)
-#define HSTATUS_VTW _AC(0x00200000, UL)
-#define HSTATUS_VTVM _AC(0x00100000, UL)
-#define HSTATUS_VGEIN _AC(0x0003f000, UL)
+#define HSTATUS_VTSR _AC(0x00400000, UXL)
+#define HSTATUS_VTW _AC(0x00200000, UXL)
+#define HSTATUS_VTVM _AC(0x00100000, UXL)
+#define HSTATUS_VGEIN _AC(0x0003f000, UXL)
#define HSTATUS_VGEIN_SHIFT 12
-#define HSTATUS_HU _AC(0x00000200, UL)
-#define HSTATUS_SPVP _AC(0x00000100, UL)
-#define HSTATUS_SPV _AC(0x00000080, UL)
-#define HSTATUS_GVA _AC(0x00000040, UL)
-#define HSTATUS_VSBE _AC(0x00000020, UL)
+#define HSTATUS_HU _AC(0x00000200, UXL)
+#define HSTATUS_SPVP _AC(0x00000100, UXL)
+#define HSTATUS_SPV _AC(0x00000080, UXL)
+#define HSTATUS_GVA _AC(0x00000040, UXL)
+#define HSTATUS_VSBE _AC(0x00000020, UXL)
/* HGATP flags */
-#define HGATP_MODE_OFF _AC(0, UL)
-#define HGATP_MODE_SV32X4 _AC(1, UL)
-#define HGATP_MODE_SV39X4 _AC(8, UL)
-#define HGATP_MODE_SV48X4 _AC(9, UL)
-#define HGATP_MODE_SV57X4 _AC(10, UL)
+#define HGATP_MODE_OFF _AC(0, UXL)
+#define HGATP_MODE_SV32X4 _AC(1, UXL)
+#define HGATP_MODE_SV39X4 _AC(8, UXL)
+#define HGATP_MODE_SV48X4 _AC(9, UXL)
+#define HGATP_MODE_SV57X4 _AC(10, UXL)
#define HGATP32_MODE_SHIFT 31
#define HGATP32_VMID_SHIFT 22
-#define HGATP32_VMID GENMASK(28, 22)
-#define HGATP32_PPN GENMASK(21, 0)
+#define HGATP32_VMID GENMASK_UXL(28, 22)
+#define HGATP32_PPN GENMASK_UXL(21, 0)
#define HGATP64_MODE_SHIFT 60
#define HGATP64_VMID_SHIFT 44
-#define HGATP64_VMID GENMASK(57, 44)
-#define HGATP64_PPN GENMASK(43, 0)
+#define HGATP64_VMID GENMASK_UXL(57, 44)
+#define HGATP64_PPN GENMASK_UXL(43, 0)
#define HGATP_PAGE_SHIFT 12
-#ifdef CONFIG_64BIT
+#if __riscv_xlen == 64
#define HGATP_PPN HGATP64_PPN
#define HGATP_VMID_SHIFT HGATP64_VMID_SHIFT
#define HGATP_VMID HGATP64_VMID
@@ -162,30 +174,30 @@
/* VSIP & HVIP relation */
#define VSIP_TO_HVIP_SHIFT (IRQ_VS_SOFT - IRQ_S_SOFT)
-#define VSIP_VALID_MASK ((_AC(1, UL) << IRQ_S_SOFT) | \
- (_AC(1, UL) << IRQ_S_TIMER) | \
- (_AC(1, UL) << IRQ_S_EXT))
+#define VSIP_VALID_MASK ((_AC(1, UXL) << IRQ_S_SOFT) | \
+ (_AC(1, UXL) << IRQ_S_TIMER) | \
+ (_AC(1, UXL) << IRQ_S_EXT))
/* AIA CSR bits */
#define TOPI_IID_SHIFT 16
-#define TOPI_IID_MASK GENMASK(11, 0)
-#define TOPI_IPRIO_MASK GENMASK(7, 0)
+#define TOPI_IID_MASK GENMASK_UXL(11, 0)
+#define TOPI_IPRIO_MASK GENMASK_UXL(7, 0)
#define TOPI_IPRIO_BITS 8
#define TOPEI_ID_SHIFT 16
-#define TOPEI_ID_MASK GENMASK(10, 0)
-#define TOPEI_PRIO_MASK GENMASK(10, 0)
+#define TOPEI_ID_MASK GENMASK_UXL(10, 0)
+#define TOPEI_PRIO_MASK GENMASK_UXL(10, 0)
#define ISELECT_IPRIO0 0x30
#define ISELECT_IPRIO15 0x3f
-#define ISELECT_MASK GENMASK(8, 0)
+#define ISELECT_MASK GENMASK_UXL(8, 0)
#define HVICTL_VTI BIT(30)
-#define HVICTL_IID GENMASK(27, 16)
+#define HVICTL_IID GENMASK_UXL(27, 16)
#define HVICTL_IID_SHIFT 16
#define HVICTL_DPR BIT(9)
#define HVICTL_IPRIOM BIT(8)
-#define HVICTL_IPRIO GENMASK(7, 0)
+#define HVICTL_IPRIO GENMASK_UXL(7, 0)
/* xENVCFG flags */
#define ENVCFG_STCE (_AC(1, ULL) << 63)
@@ -438,14 +450,14 @@
# define RV_IRQ_TIMER IRQ_S_TIMER
# define RV_IRQ_EXT IRQ_S_EXT
# define RV_IRQ_PMU IRQ_PMU_OVF
-# define SIP_LCOFIP (_AC(0x1, UL) << IRQ_PMU_OVF)
+# define SIP_LCOFIP (_AC(0x1, UXL) << IRQ_PMU_OVF)
#endif /* !CONFIG_RISCV_M_MODE */
/* IE/IP (Supervisor/Machine Interrupt Enable/Pending) flags */
-#define IE_SIE (_AC(0x1, UL) << RV_IRQ_SOFT)
-#define IE_TIE (_AC(0x1, UL) << RV_IRQ_TIMER)
-#define IE_EIE (_AC(0x1, UL) << RV_IRQ_EXT)
+#define IE_SIE (_AC(0x1, UXL) << RV_IRQ_SOFT)
+#define IE_TIE (_AC(0x1, UXL) << RV_IRQ_TIMER)
+#define IE_EIE (_AC(0x1, UXL) << RV_IRQ_EXT)
#ifndef __ASSEMBLY__
--
2.36.1
^ permalink raw reply related [flat|nested] 42+ messages in thread* [RFC PATCH V2 13/38] riscv: s64ilp32: Introduce xlen_t for 64ILP32 kernel
2023-11-12 6:14 [RFC PATCH V2 00/38] rv64ilp32: Running ILP32 on RV64 ISA guoren
` (11 preceding siblings ...)
2023-11-12 6:14 ` [RFC PATCH V2 12/38] riscv: s64ilp32: Unify ULL & UL into UXL in csr guoren
@ 2023-11-12 6:14 ` guoren
2023-11-12 6:14 ` [RFC PATCH V2 14/38] riscv: s64ilp32: Add sbi support guoren
` (27 subsequent siblings)
40 siblings, 0 replies; 42+ messages in thread
From: guoren @ 2023-11-12 6:14 UTC (permalink / raw)
To: arnd, guoren, palmer, tglx, conor.dooley, heiko, apatel, atishp,
bjorn, paul.walmsley, anup, jiawei, liweiwei, wefu, U2FsdGVkX1,
wangjunqiang, kito.cheng, andy.chiu, vincent.chen, greentime.hu,
wuwei2016, jrtc27, luto, fweimer, catalin.marinas, hjl.tools
Cc: linux-arch, linux-kernel, linux-riscv, Guo Ren
From: Guo Ren <guoren@linux.alibaba.com>
When s64ilp32 landed, we couldn't use CONFIG_64/32BIT to distingue XLEN
data types. Because the xlen is 64, but the long & pointer is 32 for
s64ilp32, and s64ilp32 is a 32BIT from the software view. So introduce a
new data type - "xlen_t" and use __riscv_xlen instead of CONFIG_64/32BIT
ifdef macro.
Signed-off-by: Guo Ren <guoren@linux.alibaba.com>
Signed-off-by: Guo Ren <guoren@kernel.org>
---
arch/riscv/include/asm/csr.h | 20 ++++---
arch/riscv/include/asm/processor.h | 8 +--
arch/riscv/include/asm/ptrace.h | 96 +++++++++++++++---------------
arch/riscv/include/asm/timex.h | 10 ++--
arch/riscv/kernel/process.c | 4 +-
arch/riscv/kernel/traps.c | 4 +-
arch/riscv/kernel/vector.c | 2 +-
arch/riscv/lib/memset.S | 4 +-
arch/riscv/mm/fault.c | 2 +-
9 files changed, 78 insertions(+), 72 deletions(-)
diff --git a/arch/riscv/include/asm/csr.h b/arch/riscv/include/asm/csr.h
index 051c017e1e5e..03acdedc100d 100644
--- a/arch/riscv/include/asm/csr.h
+++ b/arch/riscv/include/asm/csr.h
@@ -461,9 +461,15 @@
#ifndef __ASSEMBLY__
+#if __riscv_xlen == 64
+typedef u64 xlen_t;
+#else
+typedef u32 xlen_t;
+#endif
+
#define csr_swap(csr, val) \
({ \
- unsigned long __v = (unsigned long)(val); \
+ xlen_t __v = (xlen_t)(val); \
__asm__ __volatile__ ("csrrw %0, " __ASM_STR(csr) ", %1"\
: "=r" (__v) : "rK" (__v) \
: "memory"); \
@@ -472,7 +478,7 @@
#define csr_read(csr) \
({ \
- register unsigned long __v; \
+ register xlen_t __v; \
__asm__ __volatile__ ("csrr %0, " __ASM_STR(csr) \
: "=r" (__v) : \
: "memory"); \
@@ -481,7 +487,7 @@
#define csr_write(csr, val) \
({ \
- unsigned long __v = (unsigned long)(val); \
+ xlen_t __v = (xlen_t)(val); \
__asm__ __volatile__ ("csrw " __ASM_STR(csr) ", %0" \
: : "rK" (__v) \
: "memory"); \
@@ -489,7 +495,7 @@
#define csr_read_set(csr, val) \
({ \
- unsigned long __v = (unsigned long)(val); \
+ xlen_t __v = (xlen_t)(val); \
__asm__ __volatile__ ("csrrs %0, " __ASM_STR(csr) ", %1"\
: "=r" (__v) : "rK" (__v) \
: "memory"); \
@@ -498,7 +504,7 @@
#define csr_set(csr, val) \
({ \
- unsigned long __v = (unsigned long)(val); \
+ xlen_t __v = (xlen_t)(val); \
__asm__ __volatile__ ("csrs " __ASM_STR(csr) ", %0" \
: : "rK" (__v) \
: "memory"); \
@@ -506,7 +512,7 @@
#define csr_read_clear(csr, val) \
({ \
- unsigned long __v = (unsigned long)(val); \
+ xlen_t __v = (xlen_t)(val); \
__asm__ __volatile__ ("csrrc %0, " __ASM_STR(csr) ", %1"\
: "=r" (__v) : "rK" (__v) \
: "memory"); \
@@ -515,7 +521,7 @@
#define csr_clear(csr, val) \
({ \
- unsigned long __v = (unsigned long)(val); \
+ xlen_t __v = (xlen_t)(val); \
__asm__ __volatile__ ("csrc " __ASM_STR(csr) ", %0" \
: : "rK" (__v) \
: "memory"); \
diff --git a/arch/riscv/include/asm/processor.h b/arch/riscv/include/asm/processor.h
index c950a8d9edef..d8bfadaeea32 100644
--- a/arch/riscv/include/asm/processor.h
+++ b/arch/riscv/include/asm/processor.h
@@ -37,12 +37,12 @@ struct thread_struct {
/* Callee-saved registers */
unsigned long ra;
unsigned long sp; /* Kernel mode stack */
- unsigned long s[12]; /* s[0]: frame pointer */
+ xlen_t s[12]; /* s[0]: frame pointer */
struct __riscv_d_ext_state fstate;
unsigned long bad_cause;
unsigned long vstate_ctrl;
struct __riscv_v_ext_state vstate;
-};
+} __attribute__((__aligned__(sizeof(xlen_t))));
/* Whitelist the fstate from the task_struct for hardened usercopy */
static inline void arch_thread_struct_whitelist(unsigned long *offset,
@@ -60,8 +60,8 @@ static inline void arch_thread_struct_whitelist(unsigned long *offset,
((struct pt_regs *)(task_stack_page(tsk) + THREAD_SIZE \
- ALIGN(sizeof(struct pt_regs), STACK_ALIGN)))
-#define KSTK_EIP(tsk) (task_pt_regs(tsk)->epc)
-#define KSTK_ESP(tsk) (task_pt_regs(tsk)->sp)
+#define KSTK_EIP(tsk) (ulong)(task_pt_regs(tsk)->epc)
+#define KSTK_ESP(tsk) (ulong)(task_pt_regs(tsk)->sp)
/* Do necessary setup to start up a newly executed thread. */
diff --git a/arch/riscv/include/asm/ptrace.h b/arch/riscv/include/asm/ptrace.h
index b5b0adcc85c1..54cdeec8ee79 100644
--- a/arch/riscv/include/asm/ptrace.h
+++ b/arch/riscv/include/asm/ptrace.h
@@ -13,53 +13,53 @@
#ifndef __ASSEMBLY__
struct pt_regs {
- unsigned long epc;
- unsigned long ra;
- unsigned long sp;
- unsigned long gp;
- unsigned long tp;
- unsigned long t0;
- unsigned long t1;
- unsigned long t2;
- unsigned long s0;
- unsigned long s1;
- unsigned long a0;
- unsigned long a1;
- unsigned long a2;
- unsigned long a3;
- unsigned long a4;
- unsigned long a5;
- unsigned long a6;
- unsigned long a7;
- unsigned long s2;
- unsigned long s3;
- unsigned long s4;
- unsigned long s5;
- unsigned long s6;
- unsigned long s7;
- unsigned long s8;
- unsigned long s9;
- unsigned long s10;
- unsigned long s11;
- unsigned long t3;
- unsigned long t4;
- unsigned long t5;
- unsigned long t6;
+ xlen_t epc;
+ xlen_t ra;
+ xlen_t sp;
+ xlen_t gp;
+ xlen_t tp;
+ xlen_t t0;
+ xlen_t t1;
+ xlen_t t2;
+ xlen_t s0;
+ xlen_t s1;
+ xlen_t a0;
+ xlen_t a1;
+ xlen_t a2;
+ xlen_t a3;
+ xlen_t a4;
+ xlen_t a5;
+ xlen_t a6;
+ xlen_t a7;
+ xlen_t s2;
+ xlen_t s3;
+ xlen_t s4;
+ xlen_t s5;
+ xlen_t s6;
+ xlen_t s7;
+ xlen_t s8;
+ xlen_t s9;
+ xlen_t s10;
+ xlen_t s11;
+ xlen_t t3;
+ xlen_t t4;
+ xlen_t t5;
+ xlen_t t6;
/* Supervisor/Machine CSRs */
- unsigned long status;
- unsigned long badaddr;
- unsigned long cause;
+ xlen_t status;
+ xlen_t badaddr;
+ xlen_t cause;
/* a0 value before the syscall */
- unsigned long orig_a0;
+ xlen_t orig_a0;
};
#define PTRACE_SYSEMU 0x1f
#define PTRACE_SYSEMU_SINGLESTEP 0x20
-#ifdef CONFIG_64BIT
-#define REG_FMT "%016lx"
+#if __riscv_xlen == 64
+#define REG_FMT "%016llx"
#else
-#define REG_FMT "%08lx"
+#define REG_FMT "%08x"
#endif
#define user_mode(regs) (((regs)->status & SR_PP) == 0)
@@ -69,12 +69,12 @@ struct pt_regs {
/* Helpers for working with the instruction pointer */
static inline unsigned long instruction_pointer(struct pt_regs *regs)
{
- return regs->epc;
+ return (unsigned long)regs->epc;
}
static inline void instruction_pointer_set(struct pt_regs *regs,
unsigned long val)
{
- regs->epc = val;
+ regs->epc = (xlen_t)val;
}
#define profile_pc(regs) instruction_pointer(regs)
@@ -82,40 +82,40 @@ static inline void instruction_pointer_set(struct pt_regs *regs,
/* Helpers for working with the user stack pointer */
static inline unsigned long user_stack_pointer(struct pt_regs *regs)
{
- return regs->sp;
+ return (unsigned long)regs->sp;
}
static inline void user_stack_pointer_set(struct pt_regs *regs,
unsigned long val)
{
- regs->sp = val;
+ regs->sp = (xlen_t)val;
}
/* Valid only for Kernel mode traps. */
static inline unsigned long kernel_stack_pointer(struct pt_regs *regs)
{
- return regs->sp;
+ return (unsigned long)regs->sp;
}
/* Helpers for working with the frame pointer */
static inline unsigned long frame_pointer(struct pt_regs *regs)
{
- return regs->s0;
+ return (unsigned long)regs->s0;
}
static inline void frame_pointer_set(struct pt_regs *regs,
unsigned long val)
{
- regs->s0 = val;
+ regs->s0 = (xlen_t)val;
}
static inline unsigned long regs_return_value(struct pt_regs *regs)
{
- return regs->a0;
+ return (unsigned long)regs->a0;
}
static inline void regs_set_return_value(struct pt_regs *regs,
unsigned long val)
{
- regs->a0 = val;
+ regs->a0 = (xlen_t)val;
}
extern int regs_query_register_offset(const char *name);
diff --git a/arch/riscv/include/asm/timex.h b/arch/riscv/include/asm/timex.h
index a06697846e69..bc0d2708bcd6 100644
--- a/arch/riscv/include/asm/timex.h
+++ b/arch/riscv/include/asm/timex.h
@@ -8,7 +8,7 @@
#include <asm/csr.h>
-typedef unsigned long cycles_t;
+typedef xlen_t cycles_t;
#ifdef CONFIG_RISCV_M_MODE
@@ -62,12 +62,12 @@ static inline u32 get_cycles_hi(void)
#endif /* !CONFIG_RISCV_M_MODE */
-#ifdef CONFIG_64BIT
+#if __riscv_xlen == 64
static inline u64 get_cycles64(void)
{
return get_cycles();
}
-#else /* CONFIG_64BIT */
+#else /* __riscv_xlen == 64 */
static inline u64 get_cycles64(void)
{
u32 hi, lo;
@@ -79,12 +79,12 @@ static inline u64 get_cycles64(void)
return ((u64)hi << 32) | lo;
}
-#endif /* CONFIG_64BIT */
+#endif /* __riscv_xlen == 64 */
#define ARCH_HAS_READ_CURRENT_TIMER
static inline int read_current_timer(unsigned long *timer_val)
{
- *timer_val = get_cycles();
+ *timer_val = (unsigned long)get_cycles();
return 0;
}
diff --git a/arch/riscv/kernel/process.c b/arch/riscv/kernel/process.c
index 87bdb0d6dbf3..599b1966a166 100644
--- a/arch/riscv/kernel/process.c
+++ b/arch/riscv/kernel/process.c
@@ -46,8 +46,8 @@ void __show_regs(struct pt_regs *regs)
show_regs_print_info(KERN_DEFAULT);
if (!user_mode(regs)) {
- pr_cont("epc : %pS\n", (void *)regs->epc);
- pr_cont(" ra : %pS\n", (void *)regs->ra);
+ pr_cont("epc : %pS\n", (void *)(ulong)regs->epc);
+ pr_cont(" ra : %pS\n", (void *)(ulong)regs->ra);
}
pr_cont("epc : " REG_FMT " ra : " REG_FMT " sp : " REG_FMT "\n",
diff --git a/arch/riscv/kernel/traps.c b/arch/riscv/kernel/traps.c
index f910dfccbf5d..8fcef4fa43d0 100644
--- a/arch/riscv/kernel/traps.c
+++ b/arch/riscv/kernel/traps.c
@@ -100,7 +100,7 @@ void do_trap(struct pt_regs *regs, int signo, int code, unsigned long addr)
if (show_unhandled_signals && unhandled_signal(tsk, signo)
&& printk_ratelimit()) {
pr_info("%s[%d]: unhandled signal %d code 0x%x at 0x" REG_FMT,
- tsk->comm, task_pid_nr(tsk), signo, code, addr);
+ tsk->comm, task_pid_nr(tsk), signo, code, (xlen_t)addr);
print_vma_addr(KERN_CONT " in ", instruction_pointer(regs));
pr_cont("\n");
__show_regs(regs);
@@ -265,7 +265,7 @@ void handle_break(struct pt_regs *regs)
current->thread.bad_cause = regs->cause;
if (user_mode(regs))
- force_sig_fault(SIGTRAP, TRAP_BRKPT, (void __user *)regs->epc);
+ force_sig_fault(SIGTRAP, TRAP_BRKPT, (void __user *)instruction_pointer(regs));
#ifdef CONFIG_KGDB
else if (notify_die(DIE_TRAP, "EBREAK", regs, 0, regs->cause, SIGTRAP)
== NOTIFY_STOP)
diff --git a/arch/riscv/kernel/vector.c b/arch/riscv/kernel/vector.c
index 8d92fb6c522c..72ff3916eed6 100644
--- a/arch/riscv/kernel/vector.c
+++ b/arch/riscv/kernel/vector.c
@@ -133,7 +133,7 @@ EXPORT_SYMBOL_GPL(riscv_v_vstate_ctrl_user_allowed);
bool riscv_v_first_use_handler(struct pt_regs *regs)
{
- u32 __user *epc = (u32 __user *)regs->epc;
+ u32 __user *epc = (u32 __user *)(ulong)regs->epc;
u32 insn = (u32)regs->badaddr;
/* Do not handle if V is not supported, or disabled */
diff --git a/arch/riscv/lib/memset.S b/arch/riscv/lib/memset.S
index 34c5360c6705..34be7bf51731 100644
--- a/arch/riscv/lib/memset.S
+++ b/arch/riscv/lib/memset.S
@@ -38,7 +38,7 @@ WEAK(memset)
or a1, a3, a1
slli a3, a1, 16
or a1, a3, a1
-#ifdef CONFIG_64BIT
+#if __riscv_xlen == 64
slli a3, a1, 32
or a1, a3, a1
#endif
@@ -58,7 +58,7 @@ WEAK(memset)
/* Jump into loop body */
/* Assumes 32-bit instruction lengths */
la a5, 3f
-#ifdef CONFIG_64BIT
+#if __riscv_xlen == 64
srli a4, a4, 1
#endif
add a5, a5, a4
diff --git a/arch/riscv/mm/fault.c b/arch/riscv/mm/fault.c
index 6ea2cce4cc17..3d410dad28f8 100644
--- a/arch/riscv/mm/fault.c
+++ b/arch/riscv/mm/fault.c
@@ -28,7 +28,7 @@ static void die_kernel_fault(const char *msg, unsigned long addr,
bust_spinlocks(1);
pr_alert("Unable to handle kernel %s at virtual address " REG_FMT "\n", msg,
- addr);
+ (xlen_t)addr);
bust_spinlocks(0);
die(regs, "Oops");
--
2.36.1
^ permalink raw reply related [flat|nested] 42+ messages in thread* [RFC PATCH V2 14/38] riscv: s64ilp32: Add sbi support
2023-11-12 6:14 [RFC PATCH V2 00/38] rv64ilp32: Running ILP32 on RV64 ISA guoren
` (12 preceding siblings ...)
2023-11-12 6:14 ` [RFC PATCH V2 13/38] riscv: s64ilp32: Introduce xlen_t for 64ILP32 kernel guoren
@ 2023-11-12 6:14 ` guoren
2023-11-12 6:14 ` [RFC PATCH V2 15/38] riscv: s64ilp32: Add asid support guoren
` (26 subsequent siblings)
40 siblings, 0 replies; 42+ messages in thread
From: guoren @ 2023-11-12 6:14 UTC (permalink / raw)
To: arnd, guoren, palmer, tglx, conor.dooley, heiko, apatel, atishp,
bjorn, paul.walmsley, anup, jiawei, liweiwei, wefu, U2FsdGVkX1,
wangjunqiang, kito.cheng, andy.chiu, vincent.chen, greentime.hu,
wuwei2016, jrtc27, luto, fweimer, catalin.marinas, hjl.tools
Cc: linux-arch, linux-kernel, linux-riscv, Guo Ren
From: Guo Ren <guoren@linux.alibaba.com>
The sbi uses xlen as base argument elements to connect m-mode and
s-mode. The previous implementation assumes sizeof(xlen_t) =
sizeof(long), but the s64ilp32's are different. So modify the sbi code
suitable with the s64ilp32 change.
Signed-off-by: Guo Ren <guoren@linux.alibaba.com>
Signed-off-by: Guo Ren <guoren@kernel.org>
---
arch/riscv/include/asm/cpu_ops_sbi.h | 4 ++--
arch/riscv/include/asm/sbi.h | 24 ++++++++++++------------
arch/riscv/kernel/cpu_ops_sbi.c | 4 ++--
arch/riscv/kernel/sbi.c | 24 ++++++++++++------------
4 files changed, 28 insertions(+), 28 deletions(-)
diff --git a/arch/riscv/include/asm/cpu_ops_sbi.h b/arch/riscv/include/asm/cpu_ops_sbi.h
index d6e4665b3195..d967adad6b48 100644
--- a/arch/riscv/include/asm/cpu_ops_sbi.h
+++ b/arch/riscv/include/asm/cpu_ops_sbi.h
@@ -19,8 +19,8 @@ extern const struct cpu_operations cpu_ops_sbi;
* @stack_ptr: A pointer to the hart specific sp
*/
struct sbi_hart_boot_data {
- void *task_ptr;
- void *stack_ptr;
+ xlen_t task_ptr;
+ xlen_t stack_ptr;
};
#endif
diff --git a/arch/riscv/include/asm/sbi.h b/arch/riscv/include/asm/sbi.h
index 5b4a1bf5f439..501e06e52078 100644
--- a/arch/riscv/include/asm/sbi.h
+++ b/arch/riscv/include/asm/sbi.h
@@ -123,16 +123,16 @@ enum sbi_ext_pmu_fid {
};
union sbi_pmu_ctr_info {
- unsigned long value;
+ xlen_t value;
struct {
- unsigned long csr:12;
- unsigned long width:6;
+ xlen_t csr:12;
+ xlen_t width:6;
#if __riscv_xlen == 32
- unsigned long reserved:13;
+ xlen_t reserved:13;
#else
- unsigned long reserved:45;
+ xlen_t reserved:45;
#endif
- unsigned long type:1;
+ xlen_t type:1;
};
};
@@ -254,15 +254,15 @@ enum sbi_pmu_ctr_type {
extern unsigned long sbi_spec_version;
struct sbiret {
- long error;
- long value;
+ xlen_t error;
+ xlen_t value;
};
void sbi_init(void);
-struct sbiret sbi_ecall(int ext, int fid, unsigned long arg0,
- unsigned long arg1, unsigned long arg2,
- unsigned long arg3, unsigned long arg4,
- unsigned long arg5);
+struct sbiret sbi_ecall(int ext, int fid, xlen_t arg0,
+ xlen_t arg1, xlen_t arg2,
+ xlen_t arg3, xlen_t arg4,
+ xlen_t arg5);
void sbi_console_putchar(int ch);
int sbi_console_getchar(void);
diff --git a/arch/riscv/kernel/cpu_ops_sbi.c b/arch/riscv/kernel/cpu_ops_sbi.c
index efa0f0816634..01a1e270ec1d 100644
--- a/arch/riscv/kernel/cpu_ops_sbi.c
+++ b/arch/riscv/kernel/cpu_ops_sbi.c
@@ -71,8 +71,8 @@ static int sbi_cpu_start(unsigned int cpuid, struct task_struct *tidle)
/* Make sure tidle is updated */
smp_mb();
- bdata->task_ptr = tidle;
- bdata->stack_ptr = task_stack_page(tidle) + THREAD_SIZE;
+ bdata->task_ptr = (ulong)tidle;
+ bdata->stack_ptr = (ulong)task_stack_page(tidle) + THREAD_SIZE;
/* Make sure boot data is updated */
smp_mb();
hsm_data = __pa(bdata);
diff --git a/arch/riscv/kernel/sbi.c b/arch/riscv/kernel/sbi.c
index c672c8ba9a2a..88eea3a99ee0 100644
--- a/arch/riscv/kernel/sbi.c
+++ b/arch/riscv/kernel/sbi.c
@@ -22,21 +22,21 @@ static int (*__sbi_rfence)(int fid, const struct cpumask *cpu_mask,
unsigned long start, unsigned long size,
unsigned long arg4, unsigned long arg5) __ro_after_init;
-struct sbiret sbi_ecall(int ext, int fid, unsigned long arg0,
- unsigned long arg1, unsigned long arg2,
- unsigned long arg3, unsigned long arg4,
- unsigned long arg5)
+struct sbiret sbi_ecall(int ext, int fid, xlen_t arg0,
+ xlen_t arg1, xlen_t arg2,
+ xlen_t arg3, xlen_t arg4,
+ xlen_t arg5)
{
struct sbiret ret;
- register uintptr_t a0 asm ("a0") = (uintptr_t)(arg0);
- register uintptr_t a1 asm ("a1") = (uintptr_t)(arg1);
- register uintptr_t a2 asm ("a2") = (uintptr_t)(arg2);
- register uintptr_t a3 asm ("a3") = (uintptr_t)(arg3);
- register uintptr_t a4 asm ("a4") = (uintptr_t)(arg4);
- register uintptr_t a5 asm ("a5") = (uintptr_t)(arg5);
- register uintptr_t a6 asm ("a6") = (uintptr_t)(fid);
- register uintptr_t a7 asm ("a7") = (uintptr_t)(ext);
+ register xlen_t a0 asm ("a0") = arg0;
+ register xlen_t a1 asm ("a1") = arg1;
+ register xlen_t a2 asm ("a2") = arg2;
+ register xlen_t a3 asm ("a3") = arg3;
+ register xlen_t a4 asm ("a4") = arg4;
+ register xlen_t a5 asm ("a5") = arg5;
+ register xlen_t a6 asm ("a6") = fid;
+ register xlen_t a7 asm ("a7") = ext;
asm volatile ("ecall"
: "+r" (a0), "+r" (a1)
: "r" (a2), "r" (a3), "r" (a4), "r" (a5), "r" (a6), "r" (a7)
--
2.36.1
^ permalink raw reply related [flat|nested] 42+ messages in thread* [RFC PATCH V2 15/38] riscv: s64ilp32: Add asid support
2023-11-12 6:14 [RFC PATCH V2 00/38] rv64ilp32: Running ILP32 on RV64 ISA guoren
` (13 preceding siblings ...)
2023-11-12 6:14 ` [RFC PATCH V2 14/38] riscv: s64ilp32: Add sbi support guoren
@ 2023-11-12 6:14 ` guoren
2023-11-12 6:14 ` [RFC PATCH V2 16/38] riscv: s64ilp32: Introduce PTR_L and PTR_S guoren
` (25 subsequent siblings)
40 siblings, 0 replies; 42+ messages in thread
From: guoren @ 2023-11-12 6:14 UTC (permalink / raw)
To: arnd, guoren, palmer, tglx, conor.dooley, heiko, apatel, atishp,
bjorn, paul.walmsley, anup, jiawei, liweiwei, wefu, U2FsdGVkX1,
wangjunqiang, kito.cheng, andy.chiu, vincent.chen, greentime.hu,
wuwei2016, jrtc27, luto, fweimer, catalin.marinas, hjl.tools
Cc: linux-arch, linux-kernel, linux-riscv, Guo Ren
From: Guo Ren <guoren@linux.alibaba.com>
The s32ilp32 uses 9 bits as asid_bits because of the xlen=32
limitation of CSR. The xlen of s64ilp32 is 64 bits in width, and
the SATP CSR format is the same for Sv32, Sv39, Sv48, and Sv57. So
this patch makes asid mechanism support s64ilp32 with maximum
num_asids.
Signed-off-by: Guo Ren <guoren@linux.alibaba.com>
Signed-off-by: Guo Ren <guoren@kernel.org>
---
arch/riscv/include/asm/tlbflush.h | 2 +-
arch/riscv/mm/context.c | 16 ++++++++++------
2 files changed, 11 insertions(+), 7 deletions(-)
diff --git a/arch/riscv/include/asm/tlbflush.h b/arch/riscv/include/asm/tlbflush.h
index a09196f8de68..6793c3f835a0 100644
--- a/arch/riscv/include/asm/tlbflush.h
+++ b/arch/riscv/include/asm/tlbflush.h
@@ -12,7 +12,7 @@
#include <asm/errata_list.h>
#ifdef CONFIG_MMU
-extern unsigned long asid_mask;
+extern xlen_t asid_mask;
static inline void local_flush_tlb_all(void)
{
diff --git a/arch/riscv/mm/context.c b/arch/riscv/mm/context.c
index 12e22e7330e7..9eab9aa87dc6 100644
--- a/arch/riscv/mm/context.c
+++ b/arch/riscv/mm/context.c
@@ -20,9 +20,9 @@
DEFINE_STATIC_KEY_FALSE(use_asid_allocator);
-static unsigned long asid_bits;
+static xlen_t asid_bits;
static unsigned long num_asids;
-unsigned long asid_mask;
+xlen_t asid_mask;
static atomic_long_t current_version;
@@ -227,14 +227,18 @@ static inline void set_mm(struct mm_struct *prev,
static int __init asids_init(void)
{
- unsigned long old;
+ xlen_t old;
/* Figure-out number of ASID bits in HW */
old = csr_read(CSR_SATP);
asid_bits = old | (SATP_ASID_MASK << SATP_ASID_SHIFT);
csr_write(CSR_SATP, asid_bits);
asid_bits = (csr_read(CSR_SATP) >> SATP_ASID_SHIFT) & SATP_ASID_MASK;
- asid_bits = fls_long(asid_bits);
+#if __riscv_xlen == 64
+ asid_bits = fls64(asid_bits);
+#else
+ asid_bits = fls(asid_bits);
+#endif
csr_write(CSR_SATP, old);
/*
@@ -267,9 +271,9 @@ static int __init asids_init(void)
static_branch_enable(&use_asid_allocator);
pr_info("ASID allocator using %lu bits (%lu entries)\n",
- asid_bits, num_asids);
+ (ulong)asid_bits, num_asids);
} else {
- pr_info("ASID allocator disabled (%lu bits)\n", asid_bits);
+ pr_info("ASID allocator disabled (%lu bits)\n", (ulong)asid_bits);
}
return 0;
--
2.36.1
^ permalink raw reply related [flat|nested] 42+ messages in thread* [RFC PATCH V2 16/38] riscv: s64ilp32: Introduce PTR_L and PTR_S
2023-11-12 6:14 [RFC PATCH V2 00/38] rv64ilp32: Running ILP32 on RV64 ISA guoren
` (14 preceding siblings ...)
2023-11-12 6:14 ` [RFC PATCH V2 15/38] riscv: s64ilp32: Add asid support guoren
@ 2023-11-12 6:14 ` guoren
2023-11-12 6:14 ` [RFC PATCH V2 17/38] riscv: s64ilp32: Adjust TASK_SIZE for s64ilp32 kernel guoren
` (24 subsequent siblings)
40 siblings, 0 replies; 42+ messages in thread
From: guoren @ 2023-11-12 6:14 UTC (permalink / raw)
To: arnd, guoren, palmer, tglx, conor.dooley, heiko, apatel, atishp,
bjorn, paul.walmsley, anup, jiawei, liweiwei, wefu, U2FsdGVkX1,
wangjunqiang, kito.cheng, andy.chiu, vincent.chen, greentime.hu,
wuwei2016, jrtc27, luto, fweimer, catalin.marinas, hjl.tools
Cc: linux-arch, linux-kernel, linux-riscv, Guo Ren
From: Guo Ren <guoren@linux.alibaba.com>
REG_L and REG_S can't satisfy s64ilp32 situation, because its
__SIZEOF_POINTER__*8 != __riscv_xlen. So we introduce new PTR_L
and PTR_S macro to help head.S and entry.S deal with the pointer
data type and replace all REG_L/S by PTR_L/S to fit the current
algorithm in memcpy, memove, memset, strcmp, strlen and strncmp.
Signed-off-by: Guo Ren <guoren@linux.alibaba.com>
Signed-off-by: Guo Ren <guoren@kernel.org>
---
arch/riscv/include/asm/asm.h | 5 +++++
arch/riscv/kernel/entry.S | 24 ++++++++++++------------
arch/riscv/kernel/head.S | 8 ++++----
3 files changed, 21 insertions(+), 16 deletions(-)
diff --git a/arch/riscv/include/asm/asm.h b/arch/riscv/include/asm/asm.h
index 114bbadaef41..1cf20027bdbd 100644
--- a/arch/riscv/include/asm/asm.h
+++ b/arch/riscv/include/asm/asm.h
@@ -38,6 +38,7 @@
#define RISCV_SZPTR "8"
#define RISCV_LGPTR "3"
#endif
+#define __PTR_SEL(a, b) __ASM_STR(a)
#elif __SIZEOF_POINTER__ == 4
#ifdef __ASSEMBLY__
#define RISCV_PTR .word
@@ -48,10 +49,14 @@
#define RISCV_SZPTR "4"
#define RISCV_LGPTR "2"
#endif
+#define __PTR_SEL(a, b) __ASM_STR(b)
#else
#error "Unexpected __SIZEOF_POINTER__"
#endif
+#define PTR_L __PTR_SEL(ld, lw)
+#define PTR_S __PTR_SEL(sd, sw)
+
#if (__SIZEOF_INT__ == 4)
#define RISCV_INT __ASM_STR(.word)
#define RISCV_SZINT __ASM_STR(4)
diff --git a/arch/riscv/kernel/entry.S b/arch/riscv/kernel/entry.S
index 143a2bb3e697..7dc7603a86ba 100644
--- a/arch/riscv/kernel/entry.S
+++ b/arch/riscv/kernel/entry.S
@@ -25,19 +25,19 @@ SYM_CODE_START(handle_exception)
_restore_kernel_tpsp:
csrr tp, CSR_SCRATCH
- REG_S sp, TASK_TI_KERNEL_SP(tp)
+ PTR_S sp, TASK_TI_KERNEL_SP(tp)
#ifdef CONFIG_VMAP_STACK
addi sp, sp, -(PT_SIZE_ON_STACK)
srli sp, sp, THREAD_SHIFT
andi sp, sp, 0x1
bnez sp, handle_kernel_stack_overflow
- REG_L sp, TASK_TI_KERNEL_SP(tp)
+ PTR_L sp, TASK_TI_KERNEL_SP(tp)
#endif
_save_context:
- REG_S sp, TASK_TI_USER_SP(tp)
- REG_L sp, TASK_TI_KERNEL_SP(tp)
+ PTR_S sp, TASK_TI_USER_SP(tp)
+ PTR_L sp, TASK_TI_KERNEL_SP(tp)
addi sp, sp, -(PT_SIZE_ON_STACK)
REG_S x1, PT_RA(sp)
REG_S x3, PT_GP(sp)
@@ -53,7 +53,7 @@ _save_context:
*/
li t0, SR_SUM | SR_FS_VS
- REG_L s0, TASK_TI_USER_SP(tp)
+ PTR_L s0, TASK_TI_USER_SP(tp)
csrrc s1, CSR_STATUS, t0
csrr s2, CSR_EPC
csrr s3, CSR_TVAL
@@ -96,7 +96,7 @@ _save_context:
add t0, t1, t0
/* Check if exception code lies within bounds */
bgeu t0, t2, 1f
- REG_L t0, 0(t0)
+ PTR_L t0, 0(t0)
jr t0
1:
tail do_trap_unknown
@@ -121,7 +121,7 @@ SYM_CODE_START_NOALIGN(ret_from_exception)
/* Save unwound kernel stack pointer in thread_info */
addi s0, sp, PT_SIZE_ON_STACK
- REG_S s0, TASK_TI_KERNEL_SP(tp)
+ PTR_S s0, TASK_TI_KERNEL_SP(tp)
/*
* Save TP into the scratch register , so we can find the kernel data
@@ -239,7 +239,7 @@ restore_caller_reg:
REG_S x5, PT_T0(sp)
save_from_x6_to_x31
- REG_L s0, TASK_TI_KERNEL_SP(tp)
+ PTR_L s0, TASK_TI_KERNEL_SP(tp)
csrr s1, CSR_STATUS
csrr s2, CSR_EPC
csrr s3, CSR_TVAL
@@ -283,8 +283,8 @@ SYM_FUNC_START(__switch_to)
li a4, TASK_THREAD_RA
add a3, a0, a4
add a4, a1, a4
- REG_S ra, TASK_THREAD_RA_RA(a3)
- REG_S sp, TASK_THREAD_SP_RA(a3)
+ PTR_S ra, TASK_THREAD_RA_RA(a3)
+ PTR_S sp, TASK_THREAD_SP_RA(a3)
REG_S s0, TASK_THREAD_S0_RA(a3)
REG_S s1, TASK_THREAD_S1_RA(a3)
REG_S s2, TASK_THREAD_S2_RA(a3)
@@ -298,8 +298,8 @@ SYM_FUNC_START(__switch_to)
REG_S s10, TASK_THREAD_S10_RA(a3)
REG_S s11, TASK_THREAD_S11_RA(a3)
/* Restore context from next->thread */
- REG_L ra, TASK_THREAD_RA_RA(a4)
- REG_L sp, TASK_THREAD_SP_RA(a4)
+ PTR_L ra, TASK_THREAD_RA_RA(a4)
+ PTR_L sp, TASK_THREAD_SP_RA(a4)
REG_L s0, TASK_THREAD_S0_RA(a4)
REG_L s1, TASK_THREAD_S1_RA(a4)
REG_L s2, TASK_THREAD_S2_RA(a4)
diff --git a/arch/riscv/kernel/head.S b/arch/riscv/kernel/head.S
index 11c3b94c4534..bff21ad7f077 100644
--- a/arch/riscv/kernel/head.S
+++ b/arch/riscv/kernel/head.S
@@ -42,7 +42,7 @@ ENTRY(_start)
/* Image load offset (0MB) from start of RAM for M-mode */
.dword 0
#else
-#if __riscv_xlen == 64
+#ifdef CONFIG_64BIT
/* Image load offset(2MB) from start of RAM */
.dword 0x200000
#else
@@ -75,7 +75,7 @@ relocate_enable_mmu:
/* Relocate return address */
la a1, kernel_map
XIP_FIXUP_OFFSET a1
- REG_L a1, KERNEL_MAP_VIRT_ADDR(a1)
+ PTR_L a1, KERNEL_MAP_VIRT_ADDR(a1)
la a2, _start
sub a1, a1, a2
add ra, ra, a1
@@ -348,8 +348,8 @@ clear_bss_done:
*/
.Lwait_for_cpu_up:
/* FIXME: We should WFI to save some energy here. */
- REG_L sp, (a1)
- REG_L tp, (a2)
+ PTR_L sp, (a1)
+ PTR_L tp, (a2)
beqz sp, .Lwait_for_cpu_up
beqz tp, .Lwait_for_cpu_up
fence
--
2.36.1
^ permalink raw reply related [flat|nested] 42+ messages in thread* [RFC PATCH V2 17/38] riscv: s64ilp32: Adjust TASK_SIZE for s64ilp32 kernel
2023-11-12 6:14 [RFC PATCH V2 00/38] rv64ilp32: Running ILP32 on RV64 ISA guoren
` (15 preceding siblings ...)
2023-11-12 6:14 ` [RFC PATCH V2 16/38] riscv: s64ilp32: Introduce PTR_L and PTR_S guoren
@ 2023-11-12 6:14 ` guoren
2023-11-12 6:14 ` [RFC PATCH V2 18/38] riscv: s64ilp32: Add ebpf jit support guoren
` (23 subsequent siblings)
40 siblings, 0 replies; 42+ messages in thread
From: guoren @ 2023-11-12 6:14 UTC (permalink / raw)
To: arnd, guoren, palmer, tglx, conor.dooley, heiko, apatel, atishp,
bjorn, paul.walmsley, anup, jiawei, liweiwei, wefu, U2FsdGVkX1,
wangjunqiang, kito.cheng, andy.chiu, vincent.chen, greentime.hu,
wuwei2016, jrtc27, luto, fweimer, catalin.marinas, hjl.tools
Cc: linux-arch, linux-kernel, linux-riscv, Guo Ren
From: Guo Ren <guoren@linux.alibaba.com>
The RV64ILP32 32-bit Linux kernel uses the same userspace address range
as the 64-bit Linux compat mode, about 2GB. They have no difference from
the hardware view, and all are running ILP32 on a 64-bit ISA. But the
standard 32ilp32 Linux has a slightly bigger userspace address space,
about 2.4GB.
Signed-off-by: Guo Ren <guoren@linux.alibaba.com>
Signed-off-by: Guo Ren <guoren@kernel.org>
---
arch/riscv/include/asm/pgtable.h | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/arch/riscv/include/asm/pgtable.h b/arch/riscv/include/asm/pgtable.h
index 75970ee2bda2..e5e7a929949a 100644
--- a/arch/riscv/include/asm/pgtable.h
+++ b/arch/riscv/include/asm/pgtable.h
@@ -839,20 +839,25 @@ static inline pte_t pte_swp_clear_exclusive(pte_t pte)
* "load and store effective addresses, which are 64bits, must have bits
* 63–48 all equal to bit 47, or else a page-fault exception will occur."
*/
+#define TASK_SIZE_32 (_AC(0x80000000, UL) - PAGE_SIZE)
+
#ifdef CONFIG_64BIT
#define TASK_SIZE_64 (PGDIR_SIZE * PTRS_PER_PGD / 2)
#define TASK_SIZE_MIN (PGDIR_SIZE_L3 * PTRS_PER_PGD / 2)
#ifdef CONFIG_COMPAT
-#define TASK_SIZE_32 (_AC(0x80000000, UL) - PAGE_SIZE)
#define TASK_SIZE (test_thread_flag(TIF_32BIT) ? \
TASK_SIZE_32 : TASK_SIZE_64)
#else
#define TASK_SIZE TASK_SIZE_64
#endif
+#else
+#ifdef CONFIG_ARCH_RV64ILP32
+#define TASK_SIZE TASK_SIZE_32
#else
#define TASK_SIZE FIXADDR_START
+#endif
#define TASK_SIZE_MIN TASK_SIZE
#endif
--
2.36.1
^ permalink raw reply related [flat|nested] 42+ messages in thread* [RFC PATCH V2 18/38] riscv: s64ilp32: Add ebpf jit support
2023-11-12 6:14 [RFC PATCH V2 00/38] rv64ilp32: Running ILP32 on RV64 ISA guoren
` (16 preceding siblings ...)
2023-11-12 6:14 ` [RFC PATCH V2 17/38] riscv: s64ilp32: Adjust TASK_SIZE for s64ilp32 kernel guoren
@ 2023-11-12 6:14 ` guoren
2023-11-12 6:14 ` [RFC PATCH V2 19/38] riscv: s64ilp32: Add ELF32 support guoren
` (22 subsequent siblings)
40 siblings, 0 replies; 42+ messages in thread
From: guoren @ 2023-11-12 6:14 UTC (permalink / raw)
To: arnd, guoren, palmer, tglx, conor.dooley, heiko, apatel, atishp,
bjorn, paul.walmsley, anup, jiawei, liweiwei, wefu, U2FsdGVkX1,
wangjunqiang, kito.cheng, andy.chiu, vincent.chen, greentime.hu,
wuwei2016, jrtc27, luto, fweimer, catalin.marinas, hjl.tools
Cc: linux-arch, linux-kernel, linux-riscv, Guo Ren
From: Guo Ren <guoren@linux.alibaba.com>
The s64ilp32 uses the rv64 ISA instruction set, not the rv32 ISA. So
bpf_jit_comp32.c can't be used for s64ilp32, and we use bpf_jit_comp64.c
instead. This patch makes s64ilp32 ebpf jit correct and improves the
performance because bpf_jit_comp32.c has significant gaps in mapping
ebpf 64-bit ISA.
Signed-off-by: Guo Ren <guoren@linux.alibaba.com>
Signed-off-by: Guo Ren <guoren@kernel.org>
---
arch/riscv/include/asm/extable.h | 2 +-
arch/riscv/net/Makefile | 6 +++---
arch/riscv/net/bpf_jit_comp64.c | 6 +++---
3 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/arch/riscv/include/asm/extable.h b/arch/riscv/include/asm/extable.h
index 3eb5c1f7bf34..7e22bb520309 100644
--- a/arch/riscv/include/asm/extable.h
+++ b/arch/riscv/include/asm/extable.h
@@ -38,7 +38,7 @@ bool fixup_exception(struct pt_regs *regs);
static inline bool fixup_exception(struct pt_regs *regs) { return false; }
#endif
-#if defined(CONFIG_BPF_JIT) && defined(CONFIG_ARCH_RV64I)
+#if defined(CONFIG_BPF_JIT) && !defined(CONFIG_ARCH_RV32I)
bool ex_handler_bpf(const struct exception_table_entry *ex, struct pt_regs *regs);
#else
static inline bool
diff --git a/arch/riscv/net/Makefile b/arch/riscv/net/Makefile
index 9a1e5f0a94e5..907edce21acc 100644
--- a/arch/riscv/net/Makefile
+++ b/arch/riscv/net/Makefile
@@ -2,8 +2,8 @@
obj-$(CONFIG_BPF_JIT) += bpf_jit_core.o
-ifeq ($(CONFIG_ARCH_RV64I),y)
- obj-$(CONFIG_BPF_JIT) += bpf_jit_comp64.o
-else
+ifeq ($(CONFIG_ARCH_RV32I),y)
obj-$(CONFIG_BPF_JIT) += bpf_jit_comp32.o
+else
+ obj-$(CONFIG_BPF_JIT) += bpf_jit_comp64.o
endif
diff --git a/arch/riscv/net/bpf_jit_comp64.c b/arch/riscv/net/bpf_jit_comp64.c
index c648864c8cd1..ec0b7fb6982b 100644
--- a/arch/riscv/net/bpf_jit_comp64.c
+++ b/arch/riscv/net/bpf_jit_comp64.c
@@ -126,7 +126,7 @@ static u8 rv_tail_call_reg(struct rv_jit_context *ctx)
static bool is_32b_int(s64 val)
{
- return -(1L << 31) <= val && val < (1L << 31);
+ return -(1LL << 31) <= val && val < (1LL << 31);
}
static bool in_auipc_jalr_range(s64 val)
@@ -135,8 +135,8 @@ static bool in_auipc_jalr_range(s64 val)
* auipc+jalr can reach any signed PC-relative offset in the range
* [-2^31 - 2^11, 2^31 - 2^11).
*/
- return (-(1L << 31) - (1L << 11)) <= val &&
- val < ((1L << 31) - (1L << 11));
+ return (-(1LL << 31) - (1LL << 11)) <= val &&
+ val < ((1LL << 31) - (1LL << 11));
}
/* Emit fixed-length instructions for address */
--
2.36.1
^ permalink raw reply related [flat|nested] 42+ messages in thread* [RFC PATCH V2 19/38] riscv: s64ilp32: Add ELF32 support
2023-11-12 6:14 [RFC PATCH V2 00/38] rv64ilp32: Running ILP32 on RV64 ISA guoren
` (17 preceding siblings ...)
2023-11-12 6:14 ` [RFC PATCH V2 18/38] riscv: s64ilp32: Add ebpf jit support guoren
@ 2023-11-12 6:14 ` guoren
2023-11-12 6:14 ` [RFC PATCH V2 20/38] riscv: s64ilp32: Add ARCH_RV64ILP32 Kconfig option guoren
` (21 subsequent siblings)
40 siblings, 0 replies; 42+ messages in thread
From: guoren @ 2023-11-12 6:14 UTC (permalink / raw)
To: arnd, guoren, palmer, tglx, conor.dooley, heiko, apatel, atishp,
bjorn, paul.walmsley, anup, jiawei, liweiwei, wefu, U2FsdGVkX1,
wangjunqiang, kito.cheng, andy.chiu, vincent.chen, greentime.hu,
wuwei2016, jrtc27, luto, fweimer, catalin.marinas, hjl.tools
Cc: linux-arch, linux-kernel, linux-riscv, Guo Ren, Guo Ren
From: Guo Ren <guoren@linux.alibaba.com>
Use abi_len to distinct ELF32 and ELF64 because s64ilp32 is xlen=64 and
abi_len=32 (__SIZEOF_POINTER__=4). And s64ilp32 is an ELF32 based the
same as s32ilp32.
Signed-off-by: Guo Ren <guoren@linux.alibaba.com>
Signed-off-by: Guo Ren <guoren@kerenl.org>
---
arch/riscv/include/uapi/asm/elf.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/riscv/include/uapi/asm/elf.h b/arch/riscv/include/uapi/asm/elf.h
index d696d6610231..962e8ec8fe05 100644
--- a/arch/riscv/include/uapi/asm/elf.h
+++ b/arch/riscv/include/uapi/asm/elf.h
@@ -24,7 +24,7 @@ typedef __u64 elf_fpreg_t;
typedef union __riscv_fp_state elf_fpregset_t;
#define ELF_NFPREG (sizeof(struct __riscv_d_ext_state) / sizeof(elf_fpreg_t))
-#if __riscv_xlen == 64
+#if __SIZEOF_POINTER__ == 8
#define ELF_RISCV_R_SYM(r_info) ELF64_R_SYM(r_info)
#define ELF_RISCV_R_TYPE(r_info) ELF64_R_TYPE(r_info)
#else
--
2.36.1
^ permalink raw reply related [flat|nested] 42+ messages in thread* [RFC PATCH V2 20/38] riscv: s64ilp32: Add ARCH_RV64ILP32 Kconfig option
2023-11-12 6:14 [RFC PATCH V2 00/38] rv64ilp32: Running ILP32 on RV64 ISA guoren
` (18 preceding siblings ...)
2023-11-12 6:14 ` [RFC PATCH V2 19/38] riscv: s64ilp32: Add ELF32 support guoren
@ 2023-11-12 6:14 ` guoren
2023-11-12 6:14 ` [RFC PATCH V2 21/38] riscv: s64ilp32: Add MMU_SV32 mode support guoren
` (20 subsequent siblings)
40 siblings, 0 replies; 42+ messages in thread
From: guoren @ 2023-11-12 6:14 UTC (permalink / raw)
To: arnd, guoren, palmer, tglx, conor.dooley, heiko, apatel, atishp,
bjorn, paul.walmsley, anup, jiawei, liweiwei, wefu, U2FsdGVkX1,
wangjunqiang, kito.cheng, andy.chiu, vincent.chen, greentime.hu,
wuwei2016, jrtc27, luto, fweimer, catalin.marinas, hjl.tools
Cc: linux-arch, linux-kernel, linux-riscv, Guo Ren
From: Guo Ren <guoren@linux.alibaba.com>
Just the same as ARCH_RV64I & ARCH_RV32I, add ARCH_RV64ILP32 config
for s64ilp32 and turn on the s64ilp32 compile switch in the
arch/riscv/Makefile.
Signed-off-by: Guo Ren <guoren@linux.alibaba.com>
Signed-off-by: Guo Ren <guoren@kernel.org>
---
arch/riscv/Kconfig | 7 +++++++
arch/riscv/Makefile | 5 +++++
2 files changed, 12 insertions(+)
diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
index 5d770b8e2756..5a3eb5e7d67a 100644
--- a/arch/riscv/Kconfig
+++ b/arch/riscv/Kconfig
@@ -334,6 +334,13 @@ config ARCH_RV64I
select ARCH_SUPPORTS_INT128 if CC_HAS_INT128
select SWIOTLB if MMU
+config ARCH_RV64ILP32
+ bool "RV64ILP32"
+ depends on NONPORTABLE
+ select 32BIT
+ select MMU
+ select VDSO64ILP32
+
endchoice
# We must be able to map all physical memory into the kernel, but the compiler
diff --git a/arch/riscv/Makefile b/arch/riscv/Makefile
index 8605050bddd0..3b1435bade49 100644
--- a/arch/riscv/Makefile
+++ b/arch/riscv/Makefile
@@ -58,6 +58,7 @@ endif
# ISA string setting
riscv-march-$(CONFIG_ARCH_RV32I) := rv32ima
riscv-march-$(CONFIG_ARCH_RV64I) := rv64ima
+riscv-march-$(CONFIG_ARCH_RV64ILP32) := rv64ima
riscv-march-$(CONFIG_FPU) := $(riscv-march-y)fd
riscv-march-$(CONFIG_RISCV_ISA_C) := $(riscv-march-y)c
riscv-march-$(CONFIG_RISCV_ISA_V) := $(riscv-march-y)v
@@ -121,7 +122,11 @@ stack_protector_prepare: prepare0
endif
# arch specific predefines for sparse
+ifeq ($(CONFIG_ARCH_RV64ILP32),y)
+CHECKFLAGS += -D__riscv
+else
CHECKFLAGS += -D__riscv -D__riscv_xlen=$(BITS)
+endif
# Default target when executing plain make
boot := arch/riscv/boot
--
2.36.1
^ permalink raw reply related [flat|nested] 42+ messages in thread* [RFC PATCH V2 21/38] riscv: s64ilp32: Add MMU_SV32 mode support
2023-11-12 6:14 [RFC PATCH V2 00/38] rv64ilp32: Running ILP32 on RV64 ISA guoren
` (19 preceding siblings ...)
2023-11-12 6:14 ` [RFC PATCH V2 20/38] riscv: s64ilp32: Add ARCH_RV64ILP32 Kconfig option guoren
@ 2023-11-12 6:14 ` guoren
2023-11-12 6:14 ` [RFC PATCH V2 22/38] riscv: s64ilp32: Add MMU_SV39 " guoren
` (19 subsequent siblings)
40 siblings, 0 replies; 42+ messages in thread
From: guoren @ 2023-11-12 6:14 UTC (permalink / raw)
To: arnd, guoren, palmer, tglx, conor.dooley, heiko, apatel, atishp,
bjorn, paul.walmsley, anup, jiawei, liweiwei, wefu, U2FsdGVkX1,
wangjunqiang, kito.cheng, andy.chiu, vincent.chen, greentime.hu,
wuwei2016, jrtc27, luto, fweimer, catalin.marinas, hjl.tools
Cc: linux-arch, linux-kernel, linux-riscv, Guo Ren
From: Guo Ren <guoren@linux.alibaba.com>
This needs to add Sv32 mode in the SATP CSR of RV64 ISA, a novel
extension of 64-bit processors' MMU. It could save a bit of page
table footprint and improve the page table walk performance:
s64ilp32 with Sv39:
PageTables: 136 kB
s64ilp32 with Sv32:
PageTables: 60 kB
Signed-off-by: Guo Ren <guoren@linux.alibaba.com>
Signed-off-by: Guo Ren <guoren@kernel.org>
---
arch/riscv/Kconfig | 11 ++++++++++-
arch/riscv/Kconfig.errata | 2 +-
arch/riscv/include/asm/csr.h | 1 +
3 files changed, 12 insertions(+), 2 deletions(-)
diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
index 5a3eb5e7d67a..1d3a236d2c45 100644
--- a/arch/riscv/Kconfig
+++ b/arch/riscv/Kconfig
@@ -481,7 +481,7 @@ config RISCV_ISA_SVNAPOT
config RISCV_ISA_SVPBMT
bool "Svpbmt extension support for supervisor mode page-based memory types"
- depends on 64BIT && MMU
+ depends on !MMU_SV32 && MMU
depends on RISCV_ALTERNATIVE
default y
help
@@ -638,6 +638,15 @@ config THREAD_SIZE_ORDER
Specify the Pages of thread stack size (from 4KB to 64KB), which also
affects irq stack size, which is equal to thread stack size.
+config MMU_SV32
+ bool "MMU Sv32"
+ depends on 32BIT && MMU
+ help
+ ARCH_RV32I only supports MMU Sv32 mode, but ARCH_RV64ILP32 supports
+ MMU Sv39 & Sv32 (MMU Sv32 is optional for RV64 hardware).
+
+ If unsure, say N.
+
endmenu # "Platform type"
menu "Kernel features"
diff --git a/arch/riscv/Kconfig.errata b/arch/riscv/Kconfig.errata
index 0c8f4652cd82..1aa85a427ff3 100644
--- a/arch/riscv/Kconfig.errata
+++ b/arch/riscv/Kconfig.errata
@@ -44,7 +44,7 @@ config ERRATA_THEAD
config ERRATA_THEAD_PBMT
bool "Apply T-Head memory type errata"
- depends on ERRATA_THEAD && 64BIT && MMU
+ depends on ERRATA_THEAD && !MMU_SV32 && MMU
select RISCV_ALTERNATIVE_EARLY
default y
help
diff --git a/arch/riscv/include/asm/csr.h b/arch/riscv/include/asm/csr.h
index 03acdedc100d..aa78c5f20d75 100644
--- a/arch/riscv/include/asm/csr.h
+++ b/arch/riscv/include/asm/csr.h
@@ -65,6 +65,7 @@
#define SATP_ASID_MASK _AC(0x1FF, UXL)
#else
#define SATP_PPN _AC(0x00000FFFFFFFFFFF, UXL)
+#define SATP_MODE_32 _AC(0x1000000000000000, UXL)
#define SATP_MODE_39 _AC(0x8000000000000000, UXL)
#define SATP_MODE_48 _AC(0x9000000000000000, UXL)
#define SATP_MODE_57 _AC(0xa000000000000000, UXL)
--
2.36.1
^ permalink raw reply related [flat|nested] 42+ messages in thread* [RFC PATCH V2 22/38] riscv: s64ilp32: Add MMU_SV39 mode support
2023-11-12 6:14 [RFC PATCH V2 00/38] rv64ilp32: Running ILP32 on RV64 ISA guoren
` (20 preceding siblings ...)
2023-11-12 6:14 ` [RFC PATCH V2 21/38] riscv: s64ilp32: Add MMU_SV32 mode support guoren
@ 2023-11-12 6:14 ` guoren
2023-11-12 6:14 ` [RFC PATCH V2 23/38] riscv: s64ilp32: Enable native atomic64 guoren
` (18 subsequent siblings)
40 siblings, 0 replies; 42+ messages in thread
From: guoren @ 2023-11-12 6:14 UTC (permalink / raw)
To: arnd, guoren, palmer, tglx, conor.dooley, heiko, apatel, atishp,
bjorn, paul.walmsley, anup, jiawei, liweiwei, wefu, U2FsdGVkX1,
wangjunqiang, kito.cheng, andy.chiu, vincent.chen, greentime.hu,
wuwei2016, jrtc27, luto, fweimer, catalin.marinas, hjl.tools
Cc: linux-arch, linux-kernel, linux-riscv, Guo Ren
From: Guo Ren <guoren@linux.alibaba.com>
There is no MMU_SV32 support in xlen=64 ISA generally, but s64ilp32
selects 32BIT, which uses MMU_SV32 default. This commit enables MMU_SV39
for 32BIT to satisfy the 4GB mapping requirement. The Sv39 is the
mandatory MMU mode in RVA20S64 and RVA22S64, so we needn't care about
Sv48 & Sv57.
We use duplicate remapping to solve the address sign extension problem
from the compiler. Make the address of 0xffffffff80000000 equal to
0x80000000 by pg_dir[2] = pg_dir[510] and pg_dir[3] = pg_dir[511] of the
page table.
Why didn't we prevent address sign extension in the compiler?
- Additional zero extension reduces the performance
- Prevent complex and unnecessary work for compiler guys.
Signed-off-by: Guo Ren <guoren@linux.alibaba.com>
Signed-off-by: Guo Ren <guoren@kernel.org>
---
arch/riscv/Kconfig | 4 ++-
arch/riscv/include/asm/page.h | 24 ++++++++++----
arch/riscv/include/asm/pgtable-64.h | 50 ++++++++++++++---------------
arch/riscv/include/asm/pgtable.h | 19 ++++++++---
arch/riscv/kernel/cpu.c | 4 +--
arch/riscv/mm/fault.c | 11 +++++++
arch/riscv/mm/init.c | 24 +++++++++++---
7 files changed, 92 insertions(+), 44 deletions(-)
diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
index 1d3a236d2c45..f364d2436b1d 100644
--- a/arch/riscv/Kconfig
+++ b/arch/riscv/Kconfig
@@ -257,7 +257,7 @@ config FIX_EARLYCON_MEM
config PGTABLE_LEVELS
int
- default 5 if 64BIT
+ default 5 if !MMU_SV32
default 2
config LOCKDEP_SUPPORT
@@ -327,6 +327,8 @@ config ARCH_RV32I
select GENERIC_LIB_ASHRDI3
select GENERIC_LIB_LSHRDI3
select GENERIC_LIB_UCMPDI2
+ select MMU
+ select MMU_SV32
config ARCH_RV64I
bool "RV64I"
diff --git a/arch/riscv/include/asm/page.h b/arch/riscv/include/asm/page.h
index b55ba20903ec..7c535e88cf91 100644
--- a/arch/riscv/include/asm/page.h
+++ b/arch/riscv/include/asm/page.h
@@ -61,16 +61,28 @@ void clear_page(void *page);
/* Page Global Directory entry */
typedef struct {
- unsigned long pgd;
+#ifndef CONFIG_MMU_SV32
+ u64 pgd;
+#else
+ u32 pgd;
+#endif
} pgd_t;
/* Page Table entry */
typedef struct {
- unsigned long pte;
+#ifndef CONFIG_MMU_SV32
+ u64 pte;
+#else
+ u32 pte;
+#endif
} pte_t;
typedef struct {
- unsigned long pgprot;
+#ifndef CONFIG_MMU_SV32
+ u64 pgprot;
+#else
+ u32 pgprot;
+#endif
} pgprot_t;
typedef struct page *pgtable_t;
@@ -83,10 +95,10 @@ typedef struct page *pgtable_t;
#define __pgd(x) ((pgd_t) { (x) })
#define __pgprot(x) ((pgprot_t) { (x) })
-#ifdef CONFIG_64BIT
-#define PTE_FMT "%016lx"
+#ifndef CONFIG_MMU_SV32
+#define PTE_FMT "%016llx"
#else
-#define PTE_FMT "%08lx"
+#define PTE_FMT "%08x"
#endif
#ifdef CONFIG_64BIT
diff --git a/arch/riscv/include/asm/pgtable-64.h b/arch/riscv/include/asm/pgtable-64.h
index 7a5097202e15..2e57378731f4 100644
--- a/arch/riscv/include/asm/pgtable-64.h
+++ b/arch/riscv/include/asm/pgtable-64.h
@@ -16,12 +16,12 @@ extern bool pgtable_l5_enabled;
#define PGDIR_SHIFT_L3 30
#define PGDIR_SHIFT_L4 39
#define PGDIR_SHIFT_L5 48
-#define PGDIR_SIZE_L3 (_AC(1, UL) << PGDIR_SHIFT_L3)
+#define PGDIR_SIZE_L3 (_AC(1, ULL) << PGDIR_SHIFT_L3)
#define PGDIR_SHIFT (pgtable_l5_enabled ? PGDIR_SHIFT_L5 : \
(pgtable_l4_enabled ? PGDIR_SHIFT_L4 : PGDIR_SHIFT_L3))
/* Size of region mapped by a page global directory */
-#define PGDIR_SIZE (_AC(1, UL) << PGDIR_SHIFT)
+#define PGDIR_SIZE (_AC(1, ULL) << PGDIR_SHIFT)
#define PGDIR_MASK (~(PGDIR_SIZE - 1))
/* p4d is folded into pgd in case of 4-level page table */
@@ -30,7 +30,7 @@ extern bool pgtable_l5_enabled;
#define P4D_SHIFT_L5 39
#define P4D_SHIFT (pgtable_l5_enabled ? P4D_SHIFT_L5 : \
(pgtable_l4_enabled ? P4D_SHIFT_L4 : P4D_SHIFT_L3))
-#define P4D_SIZE (_AC(1, UL) << P4D_SHIFT)
+#define P4D_SIZE (_AC(1, ULL) << P4D_SHIFT)
#define P4D_MASK (~(P4D_SIZE - 1))
/* pud is folded into pgd in case of 3-level page table */
@@ -45,7 +45,7 @@ extern bool pgtable_l5_enabled;
/* Page 4th Directory entry */
typedef struct {
- unsigned long p4d;
+ u64 p4d;
} p4d_t;
#define p4d_val(x) ((x).p4d)
@@ -54,7 +54,7 @@ typedef struct {
/* Page Upper Directory entry */
typedef struct {
- unsigned long pud;
+ u64 pud;
} pud_t;
#define pud_val(x) ((x).pud)
@@ -63,7 +63,7 @@ typedef struct {
/* Page Middle Directory entry */
typedef struct {
- unsigned long pmd;
+ u64 pmd;
} pmd_t;
#define pmd_val(x) ((x).pmd)
@@ -76,7 +76,7 @@ typedef struct {
* | 63 | 62 61 | 60 54 | 53 10 | 9 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0
* N MT RSV PFN reserved for SW D A G U X W R V
*/
-#define _PAGE_PFN_MASK GENMASK(53, 10)
+#define _PAGE_PFN_MASK GENMASK_ULL(53, 10)
/*
* [63] Svnapot definitions:
@@ -103,7 +103,7 @@ enum napot_cont_order {
#define napot_cont_shift(order) ((order) + PAGE_SHIFT)
#define napot_cont_size(order) BIT(napot_cont_shift(order))
-#define napot_cont_mask(order) (~(napot_cont_size(order) - 1UL))
+#define napot_cont_mask(order) (~(napot_cont_size(order) - 1ULL))
#define napot_pte_num(order) BIT(order)
#ifdef CONFIG_RISCV_ISA_SVNAPOT
@@ -120,8 +120,8 @@ enum napot_cont_order {
* 10 - IO Non-cacheable, non-idempotent, strongly-ordered I/O memory
* 11 - Rsvd Reserved for future standard use
*/
-#define _PAGE_NOCACHE_SVPBMT (1UL << 61)
-#define _PAGE_IO_SVPBMT (1UL << 62)
+#define _PAGE_NOCACHE_SVPBMT (1ULL << 61)
+#define _PAGE_IO_SVPBMT (1ULL << 62)
#define _PAGE_MTMASK_SVPBMT (_PAGE_NOCACHE_SVPBMT | _PAGE_IO_SVPBMT)
/*
@@ -131,10 +131,10 @@ enum napot_cont_order {
* 01110 - PMA Weakly-ordered, Cacheable, Bufferable, Shareable, Non-trustable
* 10000 - IO Strongly-ordered, Non-cacheable, Non-bufferable, Non-shareable, Non-trustable
*/
-#define _PAGE_PMA_THEAD ((1UL << 62) | (1UL << 61) | (1UL << 60))
-#define _PAGE_NOCACHE_THEAD 0UL
-#define _PAGE_IO_THEAD (1UL << 63)
-#define _PAGE_MTMASK_THEAD (_PAGE_PMA_THEAD | _PAGE_IO_THEAD | (1UL << 59))
+#define _PAGE_PMA_THEAD ((1ULL << 62) | (1ULL << 61) | (1ULL << 60))
+#define _PAGE_NOCACHE_THEAD 0ULL
+#define _PAGE_IO_THEAD (1ULL << 63)
+#define _PAGE_MTMASK_THEAD (_PAGE_PMA_THEAD | _PAGE_IO_THEAD | (1ULL << 59))
static inline u64 riscv_page_mtmask(void)
{
@@ -165,7 +165,7 @@ static inline u64 riscv_page_io(void)
#define _PAGE_MTMASK riscv_page_mtmask()
/* Set of bits to preserve across pte_modify() */
-#define _PAGE_CHG_MASK (~(unsigned long)(_PAGE_PRESENT | _PAGE_READ | \
+#define _PAGE_CHG_MASK (~(u64)(_PAGE_PRESENT | _PAGE_READ | \
_PAGE_WRITE | _PAGE_EXEC | \
_PAGE_USER | _PAGE_GLOBAL | \
_PAGE_MTMASK))
@@ -206,12 +206,12 @@ static inline void pud_clear(pud_t *pudp)
set_pud(pudp, __pud(0));
}
-static inline pud_t pfn_pud(unsigned long pfn, pgprot_t prot)
+static inline pud_t pfn_pud(u64 pfn, pgprot_t prot)
{
return __pud((pfn << _PAGE_PFN_SHIFT) | pgprot_val(prot));
}
-static inline unsigned long _pud_pfn(pud_t pud)
+static inline u64 _pud_pfn(pud_t pud)
{
return __page_val_to_pfn(pud_val(pud));
}
@@ -246,16 +246,16 @@ static inline bool mm_pud_folded(struct mm_struct *mm)
#define pmd_index(addr) (((addr) >> PMD_SHIFT) & (PTRS_PER_PMD - 1))
-static inline pmd_t pfn_pmd(unsigned long pfn, pgprot_t prot)
+static inline pmd_t pfn_pmd(u64 pfn, pgprot_t prot)
{
- unsigned long prot_val = pgprot_val(prot);
+ u64 prot_val = pgprot_val(prot);
ALT_THEAD_PMA(prot_val);
return __pmd((pfn << _PAGE_PFN_SHIFT) | prot_val);
}
-static inline unsigned long _pmd_pfn(pmd_t pmd)
+static inline u64 _pmd_pfn(pmd_t pmd)
{
return __page_val_to_pfn(pmd_val(pmd));
}
@@ -263,13 +263,13 @@ static inline unsigned long _pmd_pfn(pmd_t pmd)
#define mk_pmd(page, prot) pfn_pmd(page_to_pfn(page), prot)
#define pmd_ERROR(e) \
- pr_err("%s:%d: bad pmd %016lx.\n", __FILE__, __LINE__, pmd_val(e))
+ pr_err("%s:%d: bad pmd " PTE_FMT ".\n", __FILE__, __LINE__, pmd_val(e))
#define pud_ERROR(e) \
- pr_err("%s:%d: bad pud %016lx.\n", __FILE__, __LINE__, pud_val(e))
+ pr_err("%s:%d: bad pud " PTE_FMT ".\n", __FILE__, __LINE__, pud_val(e))
#define p4d_ERROR(e) \
- pr_err("%s:%d: bad p4d %016lx.\n", __FILE__, __LINE__, p4d_val(e))
+ pr_err("%s:%d: bad p4d " PTE_FMT ".\n", __FILE__, __LINE__, p4d_val(e))
static inline void set_p4d(p4d_t *p4dp, p4d_t p4d)
{
@@ -309,12 +309,12 @@ static inline void p4d_clear(p4d_t *p4d)
set_p4d(p4d, __p4d(0));
}
-static inline p4d_t pfn_p4d(unsigned long pfn, pgprot_t prot)
+static inline p4d_t pfn_p4d(u64 pfn, pgprot_t prot)
{
return __p4d((pfn << _PAGE_PFN_SHIFT) | pgprot_val(prot));
}
-static inline unsigned long _p4d_pfn(p4d_t p4d)
+static inline u64 _p4d_pfn(p4d_t p4d)
{
return __page_val_to_pfn(p4d_val(p4d));
}
diff --git a/arch/riscv/include/asm/pgtable.h b/arch/riscv/include/asm/pgtable.h
index e5e7a929949a..645cc6e69373 100644
--- a/arch/riscv/include/asm/pgtable.h
+++ b/arch/riscv/include/asm/pgtable.h
@@ -34,7 +34,11 @@
* Half of the kernel address space (1/4 of the entries of the page global
* directory) is for the direct mapping.
*/
-#define KERN_VIRT_SIZE ((PTRS_PER_PGD / 2 * PGDIR_SIZE) / 2)
+#if IS_ENABLED(CONFIG_ARCH_RV64ILP32) && !IS_ENABLED(CONFIG_MMU_SV32)
+#define KERN_VIRT_SIZE (ulong)(PTRS_PER_PGD * PMD_SIZE)
+#else
+#define KERN_VIRT_SIZE (ulong)((PTRS_PER_PGD / 2 * PGDIR_SIZE) / 2)
+#endif
#define VMALLOC_SIZE (KERN_VIRT_SIZE >> 1)
#define VMALLOC_END PAGE_OFFSET
@@ -86,7 +90,7 @@
#define PCI_IO_START (PCI_IO_END - PCI_IO_SIZE)
#define FIXADDR_TOP PCI_IO_START
-#ifdef CONFIG_64BIT
+#ifndef CONFIG_MMU_SV32
#define MAX_FDT_SIZE PMD_SIZE
#define FIX_FDT_SIZE (MAX_FDT_SIZE + SZ_2M)
#define FIXADDR_SIZE (PMD_SIZE + FIX_FDT_SIZE)
@@ -114,11 +118,11 @@
#define __page_val_to_pfn(_val) (((_val) & _PAGE_PFN_MASK) >> _PAGE_PFN_SHIFT)
-#ifdef CONFIG_64BIT
+#ifndef CONFIG_MMU_SV32
#include <asm/pgtable-64.h>
#else
#include <asm/pgtable-32.h>
-#endif /* CONFIG_64BIT */
+#endif /* !CONFIG_MMU_SV32 */
#include <linux/page_table_check.h>
@@ -527,7 +531,11 @@ static inline int ptep_set_access_flags(struct vm_area_struct *vma,
static inline pte_t ptep_get_and_clear(struct mm_struct *mm,
unsigned long address, pte_t *ptep)
{
+#ifndef CONFIG_MMU_SV32
+ pte_t pte = __pte(atomic64_xchg((atomic64_t *)ptep, 0));
+#else
pte_t pte = __pte(atomic_long_xchg((atomic_long_t *)ptep, 0));
+#endif
page_table_check_pte_clear(mm, address, pte);
@@ -541,7 +549,8 @@ static inline int ptep_test_and_clear_young(struct vm_area_struct *vma,
{
if (!pte_young(*ptep))
return 0;
- return test_and_clear_bit(_PAGE_ACCESSED_OFFSET, &pte_val(*ptep));
+ return test_and_clear_bit(_PAGE_ACCESSED_OFFSET,
+ (unsigned long *)&pte_val(*ptep));
}
#define __HAVE_ARCH_PTEP_SET_WRPROTECT
diff --git a/arch/riscv/kernel/cpu.c b/arch/riscv/kernel/cpu.c
index a2fc952318e9..bc39fd16ab64 100644
--- a/arch/riscv/kernel/cpu.c
+++ b/arch/riscv/kernel/cpu.c
@@ -274,9 +274,9 @@ static void print_mmu(struct seq_file *f)
char sv_type[16];
#ifdef CONFIG_MMU
-#if defined(CONFIG_32BIT)
+#if defined(CONFIG_MMU_SV32)
strncpy(sv_type, "sv32", 5);
-#elif defined(CONFIG_64BIT)
+#else
if (pgtable_l5_enabled)
strncpy(sv_type, "sv57", 5);
else if (pgtable_l4_enabled)
diff --git a/arch/riscv/mm/fault.c b/arch/riscv/mm/fault.c
index 3d410dad28f8..85165fe438d8 100644
--- a/arch/riscv/mm/fault.c
+++ b/arch/riscv/mm/fault.c
@@ -140,7 +140,18 @@ static inline void vmalloc_fault(struct pt_regs *regs, int code, unsigned long a
no_context(regs, addr);
return;
}
+#if !IS_ENABLED(CONFIG_MMU_SV32) && IS_ENABLED(CONFIG_ARCH_RV64ILP32)
+ /*
+ * The pg_dir[2,510,3,511] has been set during early
+ * boot, so we only make a check here.
+ */
+ if (pgd_val(*pgd) != pgd_val(*pgd_k)) {
+ no_context(regs, addr);
+ return;
+ }
+#else
set_pgd(pgd, *pgd_k);
+#endif
p4d_k = p4d_offset(pgd_k, addr);
if (!p4d_present(*p4d_k)) {
diff --git a/arch/riscv/mm/init.c b/arch/riscv/mm/init.c
index 70fb31960b63..80c6c381f3f2 100644
--- a/arch/riscv/mm/init.c
+++ b/arch/riscv/mm/init.c
@@ -44,8 +44,12 @@ EXPORT_SYMBOL(kernel_map);
#ifdef CONFIG_64BIT
u64 satp_mode __ro_after_init = !IS_ENABLED(CONFIG_XIP_KERNEL) ? SATP_MODE_57 : SATP_MODE_39;
#else
+#ifndef CONFIG_MMU_SV32
+u64 satp_mode __ro_after_init = SATP_MODE_39;
+#else
u64 satp_mode __ro_after_init = SATP_MODE_32;
#endif
+#endif
EXPORT_SYMBOL(satp_mode);
bool pgtable_l4_enabled = IS_ENABLED(CONFIG_64BIT) && !IS_ENABLED(CONFIG_XIP_KERNEL);
@@ -639,16 +643,26 @@ void __init create_pgd_mapping(pgd_t *pgdp,
pgd_next_t *nextp;
phys_addr_t next_phys;
uintptr_t pgd_idx = pgd_index(va);
+#if !IS_ENABLED(CONFIG_MMU_SV32) && IS_ENABLED(CONFIG_ARCH_RV64ILP32)
+ uintptr_t pgd_idh = pgd_index(sign_extend64((u64)va, 31));
+#endif
if (sz == PGDIR_SIZE) {
- if (pgd_val(pgdp[pgd_idx]) == 0)
+ if (pgd_val(pgdp[pgd_idx]) == 0) {
pgdp[pgd_idx] = pfn_pgd(PFN_DOWN(pa), prot);
+#if !IS_ENABLED(CONFIG_MMU_SV32) && IS_ENABLED(CONFIG_ARCH_RV64ILP32)
+ pgdp[pgd_idh] = pfn_pgd(PFN_DOWN(pa), prot);
+#endif
+ }
return;
}
if (pgd_val(pgdp[pgd_idx]) == 0) {
next_phys = alloc_pgd_next(va);
pgdp[pgd_idx] = pfn_pgd(PFN_DOWN(next_phys), PAGE_TABLE);
+#if !IS_ENABLED(CONFIG_MMU_SV32) && IS_ENABLED(CONFIG_ARCH_RV64ILP32)
+ pgdp[pgd_idh] = pfn_pgd(PFN_DOWN(next_phys), PAGE_TABLE);
+#endif
nextp = get_pgd_next_virt(next_phys);
memset(nextp, 0, PAGE_SIZE);
} else {
@@ -930,7 +944,7 @@ static void __init create_fdt_early_page_table(uintptr_t fix_fdt_va,
BUILD_BUG_ON(FIX_FDT % (PMD_SIZE / PAGE_SIZE));
/* In 32-bit only, the fdt lies in its own PGD */
- if (!IS_ENABLED(CONFIG_64BIT)) {
+ if (IS_ENABLED(CONFIG_MMU_SV32)) {
create_pgd_mapping(early_pg_dir, fix_fdt_va,
pa, MAX_FDT_SIZE, PAGE_KERNEL);
} else {
@@ -1152,7 +1166,7 @@ asmlinkage void __init setup_vm(uintptr_t dtb_pa)
fix_bmap_epmd = fixmap_pmd[pmd_index(__fix_to_virt(FIX_BTMAP_END))];
if (pmd_val(fix_bmap_spmd) != pmd_val(fix_bmap_epmd)) {
WARN_ON(1);
- pr_warn("fixmap btmap start [%08lx] != end [%08lx]\n",
+ pr_warn("fixmap btmap start [" PTE_FMT "] != end [" PTE_FMT "]\n",
pmd_val(fix_bmap_spmd), pmd_val(fix_bmap_epmd));
pr_warn("fix_to_virt(FIX_BTMAP_BEGIN): %08lx\n",
fix_to_virt(FIX_BTMAP_BEGIN));
@@ -1248,7 +1262,7 @@ static void __init create_linear_mapping_page_table(void)
static void __init setup_vm_final(void)
{
/* Setup swapper PGD for fixmap */
-#if !defined(CONFIG_64BIT)
+#if defined(CONFIG_MMU_SV32)
/*
* In 32-bit, the device tree lies in a pgd entry, so it must be copied
* directly in swapper_pg_dir in addition to the pgd entry that points
@@ -1266,7 +1280,7 @@ static void __init setup_vm_final(void)
create_linear_mapping_page_table();
/* Map the kernel */
- if (IS_ENABLED(CONFIG_64BIT))
+ if (!IS_ENABLED(CONFIG_MMU_SV32))
create_kernel_page_table(swapper_pg_dir, false);
#ifdef CONFIG_KASAN
--
2.36.1
^ permalink raw reply related [flat|nested] 42+ messages in thread* [RFC PATCH V2 23/38] riscv: s64ilp32: Enable native atomic64
2023-11-12 6:14 [RFC PATCH V2 00/38] rv64ilp32: Running ILP32 on RV64 ISA guoren
` (21 preceding siblings ...)
2023-11-12 6:14 ` [RFC PATCH V2 22/38] riscv: s64ilp32: Add MMU_SV39 " guoren
@ 2023-11-12 6:14 ` guoren
2023-11-12 6:15 ` [RFC PATCH V2 24/38] riscv: s64ilp32: Add TImode (128 int) support guoren
` (17 subsequent siblings)
40 siblings, 0 replies; 42+ messages in thread
From: guoren @ 2023-11-12 6:14 UTC (permalink / raw)
To: arnd, guoren, palmer, tglx, conor.dooley, heiko, apatel, atishp,
bjorn, paul.walmsley, anup, jiawei, liweiwei, wefu, U2FsdGVkX1,
wangjunqiang, kito.cheng, andy.chiu, vincent.chen, greentime.hu,
wuwei2016, jrtc27, luto, fweimer, catalin.marinas, hjl.tools
Cc: linux-arch, linux-kernel, linux-riscv, Guo Ren
From: Guo Ren <guoren@linux.alibaba.com>
The traditional rv32 Linux (s32ilp32) uses a generic version of the
lib/atomic64.c, which are inaccurate atomic64 primitives and couldn't
co-work with READ_ONCE/WRITE_ONCE, atomic_8/16/32. The s64ilp32 could
use native AMO instructions to implement accurate atomic64 primitives.
Signed-off-by: Guo Ren <guoren@linux.alibaba.com>
Signed-off-by: Guo Ren <guoren@kernel.org>
---
arch/riscv/Kconfig | 2 +-
arch/riscv/include/asm/atomic.h | 6 ++++++
2 files changed, 7 insertions(+), 1 deletion(-)
diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
index f364d2436b1d..0fc03aa076e6 100644
--- a/arch/riscv/Kconfig
+++ b/arch/riscv/Kconfig
@@ -65,7 +65,7 @@ config RISCV
select CPU_PM if CPU_IDLE || HIBERNATION
select EDAC_SUPPORT
select GENERIC_ARCH_TOPOLOGY
- select GENERIC_ATOMIC64 if !64BIT
+ select GENERIC_ATOMIC64 if ARCH_RV32I
select GENERIC_CLOCKEVENTS_BROADCAST if SMP
select GENERIC_EARLY_IOREMAP
select GENERIC_ENTRY
diff --git a/arch/riscv/include/asm/atomic.h b/arch/riscv/include/asm/atomic.h
index f5dfef6c2153..8f6579b33ecc 100644
--- a/arch/riscv/include/asm/atomic.h
+++ b/arch/riscv/include/asm/atomic.h
@@ -16,6 +16,12 @@
# endif
#endif
+#ifdef CONFIG_ARCH_RV64ILP32
+typedef struct {
+ s64 counter;
+} atomic64_t;
+#endif
+
#include <asm/cmpxchg.h>
#include <asm/barrier.h>
--
2.36.1
^ permalink raw reply related [flat|nested] 42+ messages in thread* [RFC PATCH V2 24/38] riscv: s64ilp32: Add TImode (128 int) support
2023-11-12 6:14 [RFC PATCH V2 00/38] rv64ilp32: Running ILP32 on RV64 ISA guoren
` (22 preceding siblings ...)
2023-11-12 6:14 ` [RFC PATCH V2 23/38] riscv: s64ilp32: Enable native atomic64 guoren
@ 2023-11-12 6:15 ` guoren
2023-11-12 6:15 ` [RFC PATCH V2 25/38] riscv: s64ilp32: Implement cmpxchg_double guoren
` (16 subsequent siblings)
40 siblings, 0 replies; 42+ messages in thread
From: guoren @ 2023-11-12 6:15 UTC (permalink / raw)
To: arnd, guoren, palmer, tglx, conor.dooley, heiko, apatel, atishp,
bjorn, paul.walmsley, anup, jiawei, liweiwei, wefu, U2FsdGVkX1,
wangjunqiang, kito.cheng, andy.chiu, vincent.chen, greentime.hu,
wuwei2016, jrtc27, luto, fweimer, catalin.marinas, hjl.tools
Cc: linux-arch, linux-kernel, linux-riscv, Guo Ren
From: Guo Ren <guoren@linux.alibaba.com>
The s64ilp32 uses 64bit compiler, so it could support “Tetra
Integer” mode, which represents a sixteen-byte (128) integer.
It's the first 32BIT linux support TImode :)
Signed-off-by: Guo Ren <guoren@linux.alibaba.com>
Signed-off-by: Guo Ren <guoren@kernel.org>
---
arch/riscv/Kconfig | 1 +
arch/riscv/lib/Makefile | 1 +
2 files changed, 2 insertions(+)
diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
index 0fc03aa076e6..a45e31ef3b2c 100644
--- a/arch/riscv/Kconfig
+++ b/arch/riscv/Kconfig
@@ -339,6 +339,7 @@ config ARCH_RV64I
config ARCH_RV64ILP32
bool "RV64ILP32"
depends on NONPORTABLE
+ select ARCH_SUPPORTS_INT128 if !$(cc-option,$(m64-flag) -D__SIZEOF_INT128__=0)
select 32BIT
select MMU
select VDSO64ILP32
diff --git a/arch/riscv/lib/Makefile b/arch/riscv/lib/Makefile
index 26cb2502ecf8..68af463795e1 100644
--- a/arch/riscv/lib/Makefile
+++ b/arch/riscv/lib/Makefile
@@ -9,5 +9,6 @@ lib-y += strncmp.o
lib-$(CONFIG_MMU) += uaccess.o
lib-$(CONFIG_64BIT) += tishift.o
lib-$(CONFIG_RISCV_ISA_ZICBOZ) += clear_page.o
+lib-$(CONFIG_ARCH_RV64ILP32) += tishift.o
obj-$(CONFIG_FUNCTION_ERROR_INJECTION) += error-inject.o
--
2.36.1
^ permalink raw reply related [flat|nested] 42+ messages in thread* [RFC PATCH V2 25/38] riscv: s64ilp32: Implement cmpxchg_double
2023-11-12 6:14 [RFC PATCH V2 00/38] rv64ilp32: Running ILP32 on RV64 ISA guoren
` (23 preceding siblings ...)
2023-11-12 6:15 ` [RFC PATCH V2 24/38] riscv: s64ilp32: Add TImode (128 int) support guoren
@ 2023-11-12 6:15 ` guoren
2023-11-12 6:15 ` [RFC PATCH V2 26/38] riscv: s64ilp32: Disable KVM guoren
` (15 subsequent siblings)
40 siblings, 0 replies; 42+ messages in thread
From: guoren @ 2023-11-12 6:15 UTC (permalink / raw)
To: arnd, guoren, palmer, tglx, conor.dooley, heiko, apatel, atishp,
bjorn, paul.walmsley, anup, jiawei, liweiwei, wefu, U2FsdGVkX1,
wangjunqiang, kito.cheng, andy.chiu, vincent.chen, greentime.hu,
wuwei2016, jrtc27, luto, fweimer, catalin.marinas, hjl.tools
Cc: linux-arch, linux-kernel, linux-riscv, Guo Ren
From: Guo Ren <guoren@linux.alibaba.com>
The s64ilp32 has the ability to exclusively load and store (ld/sd)
a pair of words from an address. Then the SLUB can take advantage
of a cmpxchg_double implementation to avoid taking some locks.
This patch provides an implementation of cmpxchg_double for 64-bit
pairs, and activates the logic required for the SLUB to use these
functions (HAVE_ALIGNED_STRUCT_PAGE and HAVE_CMPXCHG_DOUBLE).
Similar commit: 5284e1b4bc8a ("arm64: xchg: Implement
cmpxchg_double")
Signed-off-by: Guo Ren <guoren@linux.alibaba.com>
Signed-off-by: Guo Ren <guoren@kernel.org>
---
arch/riscv/Kconfig | 2 ++
arch/riscv/include/asm/cmpxchg.h | 53 ++++++++++++++++++++++++++++++++
2 files changed, 55 insertions(+)
diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
index a45e31ef3b2c..57b98f1990b3 100644
--- a/arch/riscv/Kconfig
+++ b/arch/riscv/Kconfig
@@ -86,6 +86,7 @@ config RISCV
select GENERIC_VDSO_TIME_NS if HAVE_GENERIC_VDSO
select HARDIRQS_SW_RESEND
select HAS_IOPORT if MMU
+ select HAVE_ALIGNED_STRUCT_PAGE if SLUB && ARCH_RV64ILP32
select HAVE_ARCH_AUDITSYSCALL
select HAVE_ARCH_HUGE_VMALLOC if HAVE_ARCH_HUGE_VMAP
select HAVE_ARCH_HUGE_VMAP if MMU && 64BIT && !XIP_KERNEL
@@ -105,6 +106,7 @@ config RISCV
select HAVE_ARCH_USERFAULTFD_MINOR if 64BIT && USERFAULTFD
select HAVE_ARCH_VMAP_STACK if MMU && 64BIT
select HAVE_ASM_MODVERSIONS
+ select HAVE_CMPXCHG_DOUBLE if ARCH_RV64ILP32
select HAVE_CONTEXT_TRACKING_USER
select HAVE_DEBUG_KMEMLEAK
select HAVE_DMA_CONTIGUOUS if MMU
diff --git a/arch/riscv/include/asm/cmpxchg.h b/arch/riscv/include/asm/cmpxchg.h
index 2f4726d3cfcc..9f48a1da1c0a 100644
--- a/arch/riscv/include/asm/cmpxchg.h
+++ b/arch/riscv/include/asm/cmpxchg.h
@@ -7,6 +7,7 @@
#define _ASM_RISCV_CMPXCHG_H
#include <linux/bug.h>
+#include <linux/mmdebug.h>
#include <asm/barrier.h>
#include <asm/fence.h>
@@ -360,4 +361,56 @@
arch_cmpxchg_relaxed((ptr), (o), (n)); \
})
+#ifdef CONFIG_ARCH_RV64ILP32
+#define system_has_cmpxchg_double() 1
+
+#define __cmpxchg_double_check(ptr1, ptr2) \
+({ \
+ if (sizeof(*(ptr1)) != 4) \
+ BUILD_BUG(); \
+ if (sizeof(*(ptr2)) != 4) \
+ BUILD_BUG(); \
+ VM_BUG_ON((ulong *)(ptr2) - (ulong *)(ptr1) != 1); \
+ VM_BUG_ON(((ulong)ptr1 & 0x7) != 0); \
+})
+
+#define __cmpxchg_double(old1, old2, new1, new2, ptr) \
+({ \
+ __typeof__(ptr) __ptr = (ptr); \
+ register unsigned int __ret; \
+ u64 __old; \
+ u64 __new; \
+ u64 __tmp; \
+ switch (sizeof(*(ptr))) { \
+ case 4: \
+ __old = ((u64)old2 << 32) | (u64)old1; \
+ __new = ((u64)new2 << 32) | (u64)new1; \
+ __asm__ __volatile__ ( \
+ "0: lr.d %0, %2\n" \
+ " bne %0, %z3, 1f\n" \
+ " sc.d %1, %z4, %2\n" \
+ " bnez %1, 0b\n" \
+ "1:\n" \
+ : "=&r" (__tmp), "=&r" (__ret), "+A" (*__ptr) \
+ : "rJ" (__old), "rJ" (__new) \
+ : "memory"); \
+ __ret = (__old == __tmp); \
+ break; \
+ default: \
+ BUILD_BUG(); \
+ } \
+ __ret; \
+})
+
+#define arch_cmpxchg_double(ptr1, ptr2, o1, o2, n1, n2) \
+({ \
+ int __ret; \
+ __cmpxchg_double_check(ptr1, ptr2); \
+ __ret = __cmpxchg_double((ulong)(o1), (ulong)(o2), \
+ (ulong)(n1), (ulong)(n2), \
+ ptr1); \
+ __ret; \
+})
+#endif
+
#endif /* _ASM_RISCV_CMPXCHG_H */
--
2.36.1
^ permalink raw reply related [flat|nested] 42+ messages in thread* [RFC PATCH V2 26/38] riscv: s64ilp32: Disable KVM
2023-11-12 6:14 [RFC PATCH V2 00/38] rv64ilp32: Running ILP32 on RV64 ISA guoren
` (24 preceding siblings ...)
2023-11-12 6:15 ` [RFC PATCH V2 25/38] riscv: s64ilp32: Implement cmpxchg_double guoren
@ 2023-11-12 6:15 ` guoren
2023-11-12 6:15 ` [RFC PATCH V2 27/38] riscv: s64ilp32: Correct the rv64ilp32 stackframe layout guoren
` (14 subsequent siblings)
40 siblings, 0 replies; 42+ messages in thread
From: guoren @ 2023-11-12 6:15 UTC (permalink / raw)
To: arnd, guoren, palmer, tglx, conor.dooley, heiko, apatel, atishp,
bjorn, paul.walmsley, anup, jiawei, liweiwei, wefu, U2FsdGVkX1,
wangjunqiang, kito.cheng, andy.chiu, vincent.chen, greentime.hu,
wuwei2016, jrtc27, luto, fweimer, catalin.marinas, hjl.tools
Cc: linux-arch, linux-kernel, linux-riscv, Guo Ren
From: Guo Ren <guoren@linux.alibaba.com>
Disable the KVM host feature for s64ilp32 first, and let's work on this
feature after the s64ilp32 main feature is merged.
Signed-off-by: Guo Ren <guoren@linux.alibaba.com>
Signed-off-by: Guo Ren <guoren@kernel.org>
Cc: Anup Patel <anup@brainfault.org>
---
arch/riscv/kvm/Kconfig | 1 +
1 file changed, 1 insertion(+)
diff --git a/arch/riscv/kvm/Kconfig b/arch/riscv/kvm/Kconfig
index dfc237d7875b..3033fc1f7271 100644
--- a/arch/riscv/kvm/Kconfig
+++ b/arch/riscv/kvm/Kconfig
@@ -20,6 +20,7 @@ if VIRTUALIZATION
config KVM
tristate "Kernel-based Virtual Machine (KVM) support (EXPERIMENTAL)"
depends on RISCV_SBI && MMU
+ depends on !ARCH_RV64ILP32
select HAVE_KVM_EVENTFD
select HAVE_KVM_IRQCHIP
select HAVE_KVM_IRQFD
--
2.36.1
^ permalink raw reply related [flat|nested] 42+ messages in thread* [RFC PATCH V2 27/38] riscv: s64ilp32: Correct the rv64ilp32 stackframe layout
2023-11-12 6:14 [RFC PATCH V2 00/38] rv64ilp32: Running ILP32 on RV64 ISA guoren
` (25 preceding siblings ...)
2023-11-12 6:15 ` [RFC PATCH V2 26/38] riscv: s64ilp32: Disable KVM guoren
@ 2023-11-12 6:15 ` guoren
2023-11-12 6:15 ` [RFC PATCH V2 28/38] riscv: s64ilp32: Temporary workaround solution to gcc problem guoren
` (13 subsequent siblings)
40 siblings, 0 replies; 42+ messages in thread
From: guoren @ 2023-11-12 6:15 UTC (permalink / raw)
To: arnd, guoren, palmer, tglx, conor.dooley, heiko, apatel, atishp,
bjorn, paul.walmsley, anup, jiawei, liweiwei, wefu, U2FsdGVkX1,
wangjunqiang, kito.cheng, andy.chiu, vincent.chen, greentime.hu,
wuwei2016, jrtc27, luto, fweimer, catalin.marinas, hjl.tools
Cc: linux-arch, linux-kernel, linux-riscv, Guo Ren
From: Guo Ren <guoren@linux.alibaba.com>
The callee saved fp & ra are xlen size, not long size. This patch
corrects the layout for the struct stackframe.
echo c > /proc/sysrq-trigger
Before the patch:
sysrq: Trigger a crash
Kernel panic - not syncing: sysrq triggered crash
CPU: 0 PID: 102 Comm: sh Not tainted 6.3.0-rc1-00084-g9e2ba938797e-dirty #2
Hardware name: riscv-virtio,qemu (DT)
Call Trace:
---[ end Kernel panic - not syncing: sysrq triggered crash ]---
After the patch:
sysrq: Trigger a crash
Kernel panic - not syncing: sysrq triggered crash
CPU: 0 PID: 102 Comm: sh Not tainted 6.3.0-rc1-00084-g9e2ba938797e-dirty #1
Hardware name: riscv-virtio,qemu (DT)
Call Trace:
[<c00050c8>] dump_backtrace+0x1e/0x26
[<c086dcae>] show_stack+0x2e/0x3c
[<c0878e00>] dump_stack_lvl+0x40/0x5a
[<c0878e30>] dump_stack+0x16/0x1e
[<c086df7c>] panic+0x10c/0x2a8
[<c04f4c1e>] sysrq_reset_seq_param_set+0x0/0x76
[<c04f52cc>] __handle_sysrq+0x9c/0x19c
[<c04f5946>] write_sysrq_trigger+0x64/0x78
[<c020c7f6>] proc_reg_write+0x4a/0xa2
[<c01acf0a>] vfs_write+0xac/0x308
[<c01ad2b8>] ksys_write+0x62/0xda
[<c01ad33e>] sys_write+0xe/0x16
[<c0879860>] do_trap_ecall_u+0xd8/0xda
[<c00037de>] ret_from_exception+0x0/0x66
---[ end Kernel panic - not syncing: sysrq triggered crash ]---
Signed-off-by: Guo Ren <guoren@linux.alibaba.com>
Signed-off-by: Guo Ren <guoren@kernel.org>
---
arch/riscv/include/asm/stacktrace.h | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/arch/riscv/include/asm/stacktrace.h b/arch/riscv/include/asm/stacktrace.h
index f7e8ef2418b9..cea8aafbecca 100644
--- a/arch/riscv/include/asm/stacktrace.h
+++ b/arch/riscv/include/asm/stacktrace.h
@@ -8,7 +8,13 @@
struct stackframe {
unsigned long fp;
+#ifdef CONFIG_ARCH_RV64ILP32
+ unsigned long pad1;
+#endif
unsigned long ra;
+#ifdef CONFIG_ARCH_RV64ILP32
+ unsigned long pad2;
+#endif
};
extern void notrace walk_stackframe(struct task_struct *task, struct pt_regs *regs,
--
2.36.1
^ permalink raw reply related [flat|nested] 42+ messages in thread* [RFC PATCH V2 28/38] riscv: s64ilp32: Temporary workaround solution to gcc problem
2023-11-12 6:14 [RFC PATCH V2 00/38] rv64ilp32: Running ILP32 on RV64 ISA guoren
` (26 preceding siblings ...)
2023-11-12 6:15 ` [RFC PATCH V2 27/38] riscv: s64ilp32: Correct the rv64ilp32 stackframe layout guoren
@ 2023-11-12 6:15 ` guoren
2023-11-12 6:15 ` [RFC PATCH V2 29/38] riscv: s64ilp32: Introduce ARCH_HAS_64ILP32_KERNEL for syscall guoren
` (12 subsequent siblings)
40 siblings, 0 replies; 42+ messages in thread
From: guoren @ 2023-11-12 6:15 UTC (permalink / raw)
To: arnd, guoren, palmer, tglx, conor.dooley, heiko, apatel, atishp,
bjorn, paul.walmsley, anup, jiawei, liweiwei, wefu, U2FsdGVkX1,
wangjunqiang, kito.cheng, andy.chiu, vincent.chen, greentime.hu,
wuwei2016, jrtc27, luto, fweimer, catalin.marinas, hjl.tools
Cc: linux-arch, linux-kernel, linux-riscv, Guo Ren, LiaoShihua
From: Guo Ren <guoren@linux.alibaba.com>
There is an existing problem in 64ilp32 gcc that combines two pointers
in one register. Liao is solving that problem. Before he finishes the
job, we could prevent it with a simple noinline attribute, fortunately.
struct path {
struct vfsmount *mnt;
struct dentry *dentry;
} __randomize_layout;
struct nameidata {
struct path path;
struct qstr last;
struct path root;
...
} __randomize_layout;
struct nameidata *nd
...
nd->path = nd->root;
6c88 ld a0,24(s1)
^^ // Wrong arg of mntget
e088 sd a0,0(s1)
// Need inserting "lw a0,0(s1)" here
mntget(path->mnt);
2a6150ef jal c01ce946 <mntget>
Any gcc helps are welcome :)
Signed-off-by: Guo Ren <guoren@linux.alibaba.com>
Signed-off-by: Guo Ren <guoren@kernel.org>
Cc: LiaoShihua <shihua@iscas.ac.cn>
---
fs/namei.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/fs/namei.c b/fs/namei.c
index e56ff39a79bc..1285736dadc4 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -543,7 +543,7 @@ EXPORT_SYMBOL(inode_permission);
*
* Given a path increment the reference count to the dentry and the vfsmount.
*/
-void path_get(const struct path *path)
+void noinline path_get(const struct path *path)
{
mntget(path->mnt);
dget(path->dentry);
--
2.36.1
^ permalink raw reply related [flat|nested] 42+ messages in thread* [RFC PATCH V2 29/38] riscv: s64ilp32: Introduce ARCH_HAS_64ILP32_KERNEL for syscall
2023-11-12 6:14 [RFC PATCH V2 00/38] rv64ilp32: Running ILP32 on RV64 ISA guoren
` (27 preceding siblings ...)
2023-11-12 6:15 ` [RFC PATCH V2 28/38] riscv: s64ilp32: Temporary workaround solution to gcc problem guoren
@ 2023-11-12 6:15 ` guoren
2023-11-12 6:15 ` [RFC PATCH V2 30/38] riscv: s64ilp32: Add u32ilp32 ptrace support guoren
` (11 subsequent siblings)
40 siblings, 0 replies; 42+ messages in thread
From: guoren @ 2023-11-12 6:15 UTC (permalink / raw)
To: arnd, guoren, palmer, tglx, conor.dooley, heiko, apatel, atishp,
bjorn, paul.walmsley, anup, jiawei, liweiwei, wefu, U2FsdGVkX1,
wangjunqiang, kito.cheng, andy.chiu, vincent.chen, greentime.hu,
wuwei2016, jrtc27, luto, fweimer, catalin.marinas, hjl.tools
Cc: linux-arch, linux-kernel, linux-riscv, Guo Ren
From: Guo Ren <guoren@linux.alibaba.com>
When the kernel is built with ILP32 memory model on 64bit ISA and
supports ILP32 memory model on 32bit ISA in userspace, the ABIs are
different between kernel and userspace, similar to COMPAT, so the option
converts the 64-bit arguments of 32ILP32 syscalls to 64ILP32 calling
convention.
Signed-off-by: Guo Ren <guoren@linux.alibaba.com>
Signed-off-by: Guo Ren <guoren@kernel.org>
---
arch/Kconfig | 10 ++++++++++
arch/riscv/Kconfig | 1 +
fs/open.c | 22 ++++++++++++++++++++++
fs/read_write.c | 17 +++++++++++++++++
fs/sync.c | 22 ++++++++++++++++++++++
include/linux/syscalls.h | 35 +++++++++++++++++++++++++----------
mm/fadvise.c | 24 ++++++++++++++++++++++++
7 files changed, 121 insertions(+), 10 deletions(-)
diff --git a/arch/Kconfig b/arch/Kconfig
index aff2746c8af2..a77764d581cc 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -1479,6 +1479,16 @@ config ARCH_HAS_NONLEAF_PMD_YOUNG
address translations. Page table walkers that clear the accessed bit
may use this capability to reduce their search space.
+config ARCH_HAS_64ILP32_KERNEL
+ bool
+ depends on 32BIT
+ help
+ Architectures that select this option build the kernel with the ILP32 memory
+ model and support the ILP32 memory model on 32bit ISA in userspace, the ABIs
+ are different between kernel and userspace, similar to COMPAT, so the option
+ converts the 64-bit arguments of 32ILP32 syscalls to 64ILP32 calling
+ convention.
+
source "kernel/gcov/Kconfig"
source "scripts/gcc-plugins/Kconfig"
diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
index 57b98f1990b3..5106eab17811 100644
--- a/arch/riscv/Kconfig
+++ b/arch/riscv/Kconfig
@@ -345,6 +345,7 @@ config ARCH_RV64ILP32
select 32BIT
select MMU
select VDSO64ILP32
+ select ARCH_HAS_64ILP32_KERNEL
endchoice
diff --git a/fs/open.c b/fs/open.c
index 0c55c8e7f837..533938e11536 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -214,6 +214,17 @@ COMPAT_SYSCALL_DEFINE2(ftruncate, unsigned int, fd, compat_ulong_t, length)
/* LFS versions of truncate are only needed on 32 bit machines */
#if BITS_PER_LONG == 32
+#ifdef CONFIG_ARCH_HAS_64ILP32_KERNEL
+SYSCALL_DEFINE3(truncate64, const char __user *, path, compat_arg_u64_dual(length))
+{
+ return do_sys_truncate(path, compat_arg_u64_glue(length));
+}
+
+SYSCALL_DEFINE3(ftruncate64, unsigned int, fd, compat_arg_u64_dual(length))
+{
+ return do_sys_ftruncate(fd, compat_arg_u64_glue(length), 0);
+}
+#else
SYSCALL_DEFINE2(truncate64, const char __user *, path, loff_t, length)
{
return do_sys_truncate(path, length);
@@ -223,6 +234,7 @@ SYSCALL_DEFINE2(ftruncate64, unsigned int, fd, loff_t, length)
{
return do_sys_ftruncate(fd, length, 0);
}
+#endif
#endif /* BITS_PER_LONG == 32 */
#if defined(CONFIG_COMPAT) && defined(__ARCH_WANT_COMPAT_TRUNCATE64)
@@ -350,10 +362,20 @@ int ksys_fallocate(int fd, int mode, loff_t offset, loff_t len)
return error;
}
+#ifdef CONFIG_ARCH_HAS_64ILP32_KERNEL
+SYSCALL_DEFINE6(fallocate, int, fd, int, mode,
+ compat_arg_u64_dual(offset),
+ compat_arg_u64_dual(len))
+{
+ return ksys_fallocate(fd, mode, compat_arg_u64_glue(offset),
+ compat_arg_u64_glue(len));
+}
+#else
SYSCALL_DEFINE4(fallocate, int, fd, int, mode, loff_t, offset, loff_t, len)
{
return ksys_fallocate(fd, mode, offset, len);
}
+#endif
#if defined(CONFIG_COMPAT) && defined(__ARCH_WANT_COMPAT_FALLOCATE)
COMPAT_SYSCALL_DEFINE6(fallocate, int, fd, int, mode, compat_arg_u64_dual(offset),
diff --git a/fs/read_write.c b/fs/read_write.c
index b07de77ef126..f6d90d52dec9 100644
--- a/fs/read_write.c
+++ b/fs/read_write.c
@@ -669,11 +669,19 @@ ssize_t ksys_pread64(unsigned int fd, char __user *buf, size_t count,
return ret;
}
+#ifdef CONFIG_ARCH_HAS_64ILP32_KERNEL
+SYSCALL_DEFINE5(pread64, unsigned int, fd, char __user *, buf,
+ size_t, count, compat_arg_u64_dual(pos))
+{
+ return ksys_pread64(fd, buf, count, compat_arg_u64_glue(pos));
+}
+#else
SYSCALL_DEFINE4(pread64, unsigned int, fd, char __user *, buf,
size_t, count, loff_t, pos)
{
return ksys_pread64(fd, buf, count, pos);
}
+#endif
#if defined(CONFIG_COMPAT) && defined(__ARCH_WANT_COMPAT_PREAD64)
COMPAT_SYSCALL_DEFINE5(pread64, unsigned int, fd, char __user *, buf,
@@ -703,11 +711,20 @@ ssize_t ksys_pwrite64(unsigned int fd, const char __user *buf,
return ret;
}
+#ifdef CONFIG_ARCH_HAS_64ILP32_KERNEL
+SYSCALL_DEFINE5(pwrite64, unsigned int, fd, const char __user *, buf,
+ size_t, count, compat_arg_u64_dual(pos))
+{
+ return ksys_pwrite64(fd, buf, count, compat_arg_u64_glue(pos));
+}
+
+#else
SYSCALL_DEFINE4(pwrite64, unsigned int, fd, const char __user *, buf,
size_t, count, loff_t, pos)
{
return ksys_pwrite64(fd, buf, count, pos);
}
+#endif
#if defined(CONFIG_COMPAT) && defined(__ARCH_WANT_COMPAT_PWRITE64)
COMPAT_SYSCALL_DEFINE5(pwrite64, unsigned int, fd, const char __user *, buf,
diff --git a/fs/sync.c b/fs/sync.c
index dc725914e1ed..d25c95d13d96 100644
--- a/fs/sync.c
+++ b/fs/sync.c
@@ -367,11 +367,22 @@ int ksys_sync_file_range(int fd, loff_t offset, loff_t nbytes,
return ret;
}
+#ifdef CONFIG_ARCH_HAS_64ILP32_KERNEL
+SYSCALL_DEFINE6(sync_file_range, int, fd,
+ compat_arg_u64_dual(offset),
+ compat_arg_u64_dual(nbytes),
+ unsigned int, flags)
+{
+ return ksys_sync_file_range(fd, compat_arg_u64_glue(offset),
+ compat_arg_u64_glue(nbytes), flags);
+}
+#else
SYSCALL_DEFINE4(sync_file_range, int, fd, loff_t, offset, loff_t, nbytes,
unsigned int, flags)
{
return ksys_sync_file_range(fd, offset, nbytes, flags);
}
+#endif
#if defined(CONFIG_COMPAT) && defined(__ARCH_WANT_COMPAT_SYNC_FILE_RANGE)
COMPAT_SYSCALL_DEFINE6(sync_file_range, int, fd, compat_arg_u64_dual(offset),
@@ -384,8 +395,19 @@ COMPAT_SYSCALL_DEFINE6(sync_file_range, int, fd, compat_arg_u64_dual(offset),
/* It would be nice if people remember that not all the world's an i386
when they introduce new system calls */
+#ifdef CONFIG_ARCH_HAS_64ILP32_KERNEL
+SYSCALL_DEFINE6(sync_file_range2, int, fd, unsigned int, flags,
+ compat_arg_u64_dual(offset),
+ compat_arg_u64_dual(nbytes))
+{
+ return ksys_sync_file_range(fd, compat_arg_u64_glue(offset),
+ compat_arg_u64_glue(nbytes),
+ flags);
+}
+#else
SYSCALL_DEFINE4(sync_file_range2, int, fd, unsigned int, flags,
loff_t, offset, loff_t, nbytes)
{
return ksys_sync_file_range(fd, offset, nbytes, flags);
}
+#endif
diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h
index 03e3d0121d5e..b559b0e676a9 100644
--- a/include/linux/syscalls.h
+++ b/include/linux/syscalls.h
@@ -313,6 +313,13 @@ static inline void addr_limit_user_check(void)
* include the prototypes if CONFIG_ARCH_HAS_SYSCALL_WRAPPER is enabled.
*/
#ifndef CONFIG_ARCH_HAS_SYSCALL_WRAPPER
+
+#ifdef CONFIG_ARCH_HAS_64ILP32_KERNEL
+#define arg_loff_t(name) compat_arg_u64(name)
+#else
+#define arg_loff_t(name) loff_t name
+#endif
+
asmlinkage long sys_io_setup(unsigned nr_reqs, aio_context_t __user *ctx);
asmlinkage long sys_io_destroy(aio_context_t ctx);
asmlinkage long sys_io_submit(aio_context_t, long,
@@ -427,10 +434,11 @@ asmlinkage long sys_fstatfs64(unsigned int fd, size_t sz,
asmlinkage long sys_truncate(const char __user *path, long length);
asmlinkage long sys_ftruncate(unsigned int fd, unsigned long length);
#if BITS_PER_LONG == 32
-asmlinkage long sys_truncate64(const char __user *path, loff_t length);
-asmlinkage long sys_ftruncate64(unsigned int fd, loff_t length);
+asmlinkage long sys_truncate64(const char __user *path, arg_loff_t(length));
+asmlinkage long sys_ftruncate64(unsigned int fd, arg_loff_t(length));
#endif
-asmlinkage long sys_fallocate(int fd, int mode, loff_t offset, loff_t len);
+asmlinkage long sys_fallocate(int fd, int mode, arg_loff_t(offset),
+ arg_loff_t(len));
asmlinkage long sys_faccessat(int dfd, const char __user *filename, int mode);
asmlinkage long sys_faccessat2(int dfd, const char __user *filename, int mode,
int flags);
@@ -474,9 +482,9 @@ asmlinkage long sys_writev(unsigned long fd,
const struct iovec __user *vec,
unsigned long vlen);
asmlinkage long sys_pread64(unsigned int fd, char __user *buf,
- size_t count, loff_t pos);
+ size_t count, arg_loff_t(pos));
asmlinkage long sys_pwrite64(unsigned int fd, const char __user *buf,
- size_t count, loff_t pos);
+ size_t count, arg_loff_t(pos));
asmlinkage long sys_preadv(unsigned long fd, const struct iovec __user *vec,
unsigned long vlen, unsigned long pos_l, unsigned long pos_h);
asmlinkage long sys_pwritev(unsigned long fd, const struct iovec __user *vec,
@@ -516,9 +524,13 @@ asmlinkage long sys_sync(void);
asmlinkage long sys_fsync(unsigned int fd);
asmlinkage long sys_fdatasync(unsigned int fd);
asmlinkage long sys_sync_file_range2(int fd, unsigned int flags,
- loff_t offset, loff_t nbytes);
-asmlinkage long sys_sync_file_range(int fd, loff_t offset, loff_t nbytes,
- unsigned int flags);
+ arg_loff_t(offset),
+ arg_loff_t(nbytes));
+asmlinkage long sys_sync_file_range(int fd,
+ arg_loff_t(offset),
+ arg_loff_t(nbytes),
+ unsigned int flags);
+
asmlinkage long sys_timerfd_create(int clockid, int flags);
asmlinkage long sys_timerfd_settime(int ufd, int flags,
const struct __kernel_itimerspec __user *utmr,
@@ -795,7 +807,10 @@ asmlinkage long sys_clone3(struct clone_args __user *uargs, size_t size);
asmlinkage long sys_execve(const char __user *filename,
const char __user *const __user *argv,
const char __user *const __user *envp);
-asmlinkage long sys_fadvise64_64(int fd, loff_t offset, loff_t len, int advice);
+asmlinkage long sys_fadvise64_64(int fd,
+ arg_loff_t(offset),
+ arg_loff_t(len),
+ int advice);
/* CONFIG_MMU only */
asmlinkage long sys_swapon(const char __user *specialfile, int swap_flags);
@@ -1023,7 +1038,7 @@ asmlinkage long sys_newstat(const char __user *filename,
struct stat __user *statbuf);
asmlinkage long sys_newlstat(const char __user *filename,
struct stat __user *statbuf);
-asmlinkage long sys_fadvise64(int fd, loff_t offset, size_t len, int advice);
+asmlinkage long sys_fadvise64(int fd, arg_loff_t(offset), size_t len, int advice);
/* __ARCH_WANT_SYSCALL_DEPRECATED */
asmlinkage long sys_alarm(unsigned int seconds);
diff --git a/mm/fadvise.c b/mm/fadvise.c
index 6c39d42f16dc..0f56cbe8496b 100644
--- a/mm/fadvise.c
+++ b/mm/fadvise.c
@@ -202,18 +202,42 @@ int ksys_fadvise64_64(int fd, loff_t offset, loff_t len, int advice)
return ret;
}
+#ifdef CONFIG_ARCH_HAS_64ILP32_KERNEL
+
+SYSCALL_DEFINE6(fadvise64_64, int, fd, compat_arg_u64_dual(offset),
+ compat_arg_u64_dual(len), int, advice)
+{
+ return ksys_fadvise64_64(fd, compat_arg_u64_glue(offset),
+ compat_arg_u64_glue(len), advice);
+}
+
+#else
+
SYSCALL_DEFINE4(fadvise64_64, int, fd, loff_t, offset, loff_t, len, int, advice)
{
return ksys_fadvise64_64(fd, offset, len, advice);
}
+#endif
+
#ifdef __ARCH_WANT_SYS_FADVISE64
+#ifdef CONFIG_ARCH_HAS_64ILP32_KERNEL
+
+SYSCALL_DEFINE5(fadvise64, int, fd, loff_t, compat_arg_u64_dual(offset),
+ size_t, len, int, advice)
+{
+ return ksys_fadvise64_64(fd, compat_arg_u64_glue(offset), len, advice);
+}
+
+#else
+
SYSCALL_DEFINE4(fadvise64, int, fd, loff_t, offset, size_t, len, int, advice)
{
return ksys_fadvise64_64(fd, offset, len, advice);
}
+#endif
#endif
#if defined(CONFIG_COMPAT) && defined(__ARCH_WANT_COMPAT_FADVISE64_64)
--
2.36.1
^ permalink raw reply related [flat|nested] 42+ messages in thread* [RFC PATCH V2 30/38] riscv: s64ilp32: Add u32ilp32 ptrace support
2023-11-12 6:14 [RFC PATCH V2 00/38] rv64ilp32: Running ILP32 on RV64 ISA guoren
` (28 preceding siblings ...)
2023-11-12 6:15 ` [RFC PATCH V2 29/38] riscv: s64ilp32: Introduce ARCH_HAS_64ILP32_KERNEL for syscall guoren
@ 2023-11-12 6:15 ` guoren
2023-11-12 6:15 ` [RFC PATCH V2 31/38] riscv: s64ilp32: Add u32ilp32 signal support guoren
` (10 subsequent siblings)
40 siblings, 0 replies; 42+ messages in thread
From: guoren @ 2023-11-12 6:15 UTC (permalink / raw)
To: arnd, guoren, palmer, tglx, conor.dooley, heiko, apatel, atishp,
bjorn, paul.walmsley, anup, jiawei, liweiwei, wefu, U2FsdGVkX1,
wangjunqiang, kito.cheng, andy.chiu, vincent.chen, greentime.hu,
wuwei2016, jrtc27, luto, fweimer, catalin.marinas, hjl.tools
Cc: linux-arch, linux-kernel, linux-riscv, Guo Ren
From: Guo Ren <guoren@linux.alibaba.com>
The s64ilp32 supports both u64ilp32 and u32ilp32 ABIs, and their pt_regs
differ. So introduce the compat feature to help u32ilp32 ABI. Now
u64ilp32 and u32ilp32 applications could work with the s64ilp32 Linux
ptrace concurrently.
Signed-off-by: Guo Ren <guoren@linux.alibaba.com>
Signed-off-by: Guo Ren <guoren@kernel.org>
---
arch/riscv/include/asm/elf.h | 2 +-
arch/riscv/kernel/ptrace.c | 6 ++++--
2 files changed, 5 insertions(+), 3 deletions(-)
diff --git a/arch/riscv/include/asm/elf.h b/arch/riscv/include/asm/elf.h
index 5b2bf1a7cb59..58c2e5ef2b7a 100644
--- a/arch/riscv/include/asm/elf.h
+++ b/arch/riscv/include/asm/elf.h
@@ -143,13 +143,13 @@ do { if ((ex).e_ident[EI_CLASS] == ELFCLASS32) \
(current->personality & (~PER_MASK))); \
} while (0)
-#ifdef CONFIG_COMPAT
#define COMPAT_ELF_ET_DYN_BASE ((TASK_SIZE_32 / 3) * 2)
/* rv32 registers */
typedef compat_ulong_t compat_elf_greg_t;
typedef compat_elf_greg_t compat_elf_gregset_t[ELF_NGREG];
+#ifdef CONFIG_COMPAT
extern int compat_arch_setup_additional_pages(struct linux_binprm *bprm,
int uses_interp);
#define compat_arch_setup_additional_pages \
diff --git a/arch/riscv/kernel/ptrace.c b/arch/riscv/kernel/ptrace.c
index 5471b12127da..1078c0f454c1 100644
--- a/arch/riscv/kernel/ptrace.c
+++ b/arch/riscv/kernel/ptrace.c
@@ -295,7 +295,7 @@ long arch_ptrace(struct task_struct *child, long request,
return ret;
}
-#ifdef CONFIG_COMPAT
+#if IS_ENABLED(CONFIG_COMPAT) || IS_ENABLED(CONFIG_ARCH_RV64ILP32)
static int compat_riscv_gpr_get(struct task_struct *target,
const struct user_regset *regset,
struct membuf to)
@@ -350,7 +350,9 @@ static const struct user_regset_view compat_riscv_user_native_view = {
.regsets = compat_riscv_user_regset,
.n = ARRAY_SIZE(compat_riscv_user_regset),
};
+#endif
+#ifdef CONFIG_COMPAT
long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
compat_ulong_t caddr, compat_ulong_t cdata)
{
@@ -368,7 +370,7 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
const struct user_regset_view *task_user_regset_view(struct task_struct *task)
{
-#ifdef CONFIG_COMPAT
+#if IS_ENABLED(CONFIG_COMPAT) || IS_ENABLED(CONFIG_ARCH_RV64ILP32)
if (test_tsk_thread_flag(task, TIF_32BIT) &&
!test_tsk_thread_flag(task, TIF_64ILP32))
return &compat_riscv_user_native_view;
--
2.36.1
^ permalink raw reply related [flat|nested] 42+ messages in thread* [RFC PATCH V2 31/38] riscv: s64ilp32: Add u32ilp32 signal support
2023-11-12 6:14 [RFC PATCH V2 00/38] rv64ilp32: Running ILP32 on RV64 ISA guoren
` (29 preceding siblings ...)
2023-11-12 6:15 ` [RFC PATCH V2 30/38] riscv: s64ilp32: Add u32ilp32 ptrace support guoren
@ 2023-11-12 6:15 ` guoren
2023-11-12 6:15 ` [RFC PATCH V2 32/38] riscv: s64ilp32: Validate harts by architecture name guoren
` (9 subsequent siblings)
40 siblings, 0 replies; 42+ messages in thread
From: guoren @ 2023-11-12 6:15 UTC (permalink / raw)
To: arnd, guoren, palmer, tglx, conor.dooley, heiko, apatel, atishp,
bjorn, paul.walmsley, anup, jiawei, liweiwei, wefu, U2FsdGVkX1,
wangjunqiang, kito.cheng, andy.chiu, vincent.chen, greentime.hu,
wuwei2016, jrtc27, luto, fweimer, catalin.marinas, hjl.tools
Cc: linux-arch, linux-kernel, linux-riscv, Guo Ren
From: Guo Ren <guoren@linux.alibaba.com>
The u32ilp32 uses the compat_pt_regs instead of the native pt_regs, so
we borrow the compat code to support the u32ilp32 signal procedure in
the s64ilp32 kernel.
Signed-off-by: Guo Ren <guoren@linux.alibaba.com>
Signed-off-by: Guo Ren <guoren@kernel.org>
---
arch/riscv/include/asm/signal32.h | 2 +-
arch/riscv/kernel/Makefile | 1 +
arch/riscv/kernel/signal.c | 5 ++++-
kernel/signal.c | 24 ++++++++++++++----------
4 files changed, 20 insertions(+), 12 deletions(-)
diff --git a/arch/riscv/include/asm/signal32.h b/arch/riscv/include/asm/signal32.h
index cda62d7eb0a5..e47bb739e61a 100644
--- a/arch/riscv/include/asm/signal32.h
+++ b/arch/riscv/include/asm/signal32.h
@@ -3,7 +3,7 @@
#ifndef __ASM_SIGNAL32_H
#define __ASM_SIGNAL32_H
-#if IS_ENABLED(CONFIG_COMPAT)
+#if IS_ENABLED(CONFIG_COMPAT) || IS_ENABLED(CONFIG_ARCH_RV64ILP32)
int compat_setup_rt_frame(struct ksignal *ksig, sigset_t *set,
struct pt_regs *regs);
long __riscv_compat_rt_sigreturn(void);
diff --git a/arch/riscv/kernel/Makefile b/arch/riscv/kernel/Makefile
index a4583a29b28b..e8af95298e98 100644
--- a/arch/riscv/kernel/Makefile
+++ b/arch/riscv/kernel/Makefile
@@ -97,6 +97,7 @@ obj-$(CONFIG_JUMP_LABEL) += jump_label.o
obj-$(CONFIG_EFI) += efi.o
obj-$(CONFIG_COMPAT) += compat_syscall_table.o
obj-$(CONFIG_COMPAT) += compat_signal.o
+obj-$(CONFIG_ARCH_RV64ILP32) += compat_signal.o
obj-$(CONFIG_64BIT) += pi/
obj-$(CONFIG_ACPI) += acpi.o
diff --git a/arch/riscv/kernel/signal.c b/arch/riscv/kernel/signal.c
index 1c51a6783c98..95512af927dd 100644
--- a/arch/riscv/kernel/signal.c
+++ b/arch/riscv/kernel/signal.c
@@ -277,7 +277,10 @@ static long __riscv_rt_sigreturn(void)
SYSCALL_DEFINE0(rt_sigreturn)
{
- return __riscv_rt_sigreturn();
+ if (test_thread_flag(TIF_32BIT) && !test_thread_flag(TIF_64ILP32))
+ return __riscv_compat_rt_sigreturn();
+ else
+ return __riscv_rt_sigreturn();
}
#ifdef CONFIG_COMPAT
diff --git a/kernel/signal.c b/kernel/signal.c
index b5370fe5c198..3ac7fa4f1761 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -3390,7 +3390,7 @@ int copy_siginfo_from_user(kernel_siginfo_t *to, const siginfo_t __user *from)
return post_copy_siginfo_from_user(to, from);
}
-#ifdef CONFIG_COMPAT
+#if IS_ENABLED(CONFIG_COMPAT) || IS_ENABLED(CONFIG_ARCH_RV64ILP32)
/**
* copy_siginfo_to_external32 - copy a kernel siginfo into a compat user siginfo
* @to: compat siginfo destination
@@ -3556,6 +3556,7 @@ static int post_copy_siginfo_from_user32(kernel_siginfo_t *to,
return 0;
}
+#ifdef CONFIG_COMPAT
static int __copy_siginfo_from_user32(int signo, struct kernel_siginfo *to,
const struct compat_siginfo __user *ufrom)
{
@@ -3567,6 +3568,7 @@ static int __copy_siginfo_from_user32(int signo, struct kernel_siginfo *to,
from.si_signo = signo;
return post_copy_siginfo_from_user32(to, &from);
}
+#endif /* CONFIG_COMPAT */
int copy_siginfo_from_user32(struct kernel_siginfo *to,
const struct compat_siginfo __user *ufrom)
@@ -3578,7 +3580,7 @@ int copy_siginfo_from_user32(struct kernel_siginfo *to,
return post_copy_siginfo_from_user32(to, &from);
}
-#endif /* CONFIG_COMPAT */
+#endif
/**
* do_sigtimedwait - wait for queued signals specified in @which
@@ -4279,7 +4281,7 @@ int __save_altstack(stack_t __user *uss, unsigned long sp)
return err;
}
-#ifdef CONFIG_COMPAT
+#if IS_ENABLED(CONFIG_COMPAT) || IS_ENABLED(CONFIG_ARCH_HAS_64ILP32_KERNEL)
static int do_compat_sigaltstack(const compat_stack_t __user *uss_ptr,
compat_stack_t __user *uoss_ptr)
{
@@ -4309,13 +4311,6 @@ static int do_compat_sigaltstack(const compat_stack_t __user *uss_ptr,
return ret;
}
-COMPAT_SYSCALL_DEFINE2(sigaltstack,
- const compat_stack_t __user *, uss_ptr,
- compat_stack_t __user *, uoss_ptr)
-{
- return do_compat_sigaltstack(uss_ptr, uoss_ptr);
-}
-
int compat_restore_altstack(const compat_stack_t __user *uss)
{
int err = do_compat_sigaltstack(uss, NULL);
@@ -4335,6 +4330,15 @@ int __compat_save_altstack(compat_stack_t __user *uss, unsigned long sp)
}
#endif
+#ifdef CONFIG_COMPAT
+COMPAT_SYSCALL_DEFINE2(sigaltstack,
+ const compat_stack_t __user *, uss_ptr,
+ compat_stack_t __user *, uoss_ptr)
+{
+ return do_compat_sigaltstack(uss_ptr, uoss_ptr);
+}
+#endif
+
#ifdef __ARCH_WANT_SYS_SIGPENDING
/**
--
2.36.1
^ permalink raw reply related [flat|nested] 42+ messages in thread* [RFC PATCH V2 32/38] riscv: s64ilp32: Validate harts by architecture name
2023-11-12 6:14 [RFC PATCH V2 00/38] rv64ilp32: Running ILP32 on RV64 ISA guoren
` (30 preceding siblings ...)
2023-11-12 6:15 ` [RFC PATCH V2 31/38] riscv: s64ilp32: Add u32ilp32 signal support guoren
@ 2023-11-12 6:15 ` guoren
2023-11-12 6:15 ` [RFC PATCH V2 33/38] riscv: s64ilp32: Add rv64ilp32_defconfig guoren
` (8 subsequent siblings)
40 siblings, 0 replies; 42+ messages in thread
From: guoren @ 2023-11-12 6:15 UTC (permalink / raw)
To: arnd, guoren, palmer, tglx, conor.dooley, heiko, apatel, atishp,
bjorn, paul.walmsley, anup, jiawei, liweiwei, wefu, U2FsdGVkX1,
wangjunqiang, kito.cheng, andy.chiu, vincent.chen, greentime.hu,
wuwei2016, jrtc27, luto, fweimer, catalin.marinas, hjl.tools
Cc: linux-arch, linux-kernel, linux-riscv, Guo Ren
From: Guo Ren <guoren@linux.alibaba.com>
When rv64ilp32 was introduced, the 32BIT would work with rv64,isa. So
use the architecture name instead of the ABI width name. This is an
addition to the commit: 069b0d517077 ("RISC-V: validate riscv,isa at
boot, not during ISA string parsing").
Signed-off-by: Guo Ren <guoren@linux.alibaba.com>
Signed-off-by: Guo Ren <guoren@kernel.org>
---
arch/riscv/kernel/cpu.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/arch/riscv/kernel/cpu.c b/arch/riscv/kernel/cpu.c
index bc39fd16ab64..3c06ffc00fe0 100644
--- a/arch/riscv/kernel/cpu.c
+++ b/arch/riscv/kernel/cpu.c
@@ -66,10 +66,11 @@ int riscv_early_of_processor_hartid(struct device_node *node, unsigned long *har
return -ENODEV;
}
- if (IS_ENABLED(CONFIG_32BIT) && strncasecmp(isa, "rv32ima", 7))
+ if (IS_ENABLED(CONFIG_RV32I) && strncasecmp(isa, "rv32ima", 7))
return -ENODEV;
- if (IS_ENABLED(CONFIG_64BIT) && strncasecmp(isa, "rv64ima", 7))
+ if ((IS_ENABLED(CONFIG_RV64I) || IS_ENABLED(CONFIG_RV64IILP32))
+ && strncasecmp(isa, "rv64ima", 7))
return -ENODEV;
return 0;
--
2.36.1
^ permalink raw reply related [flat|nested] 42+ messages in thread* [RFC PATCH V2 33/38] riscv: s64ilp32: Add rv64ilp32_defconfig
2023-11-12 6:14 [RFC PATCH V2 00/38] rv64ilp32: Running ILP32 on RV64 ISA guoren
` (31 preceding siblings ...)
2023-11-12 6:15 ` [RFC PATCH V2 32/38] riscv: s64ilp32: Validate harts by architecture name guoren
@ 2023-11-12 6:15 ` guoren
2023-11-12 6:15 ` [RFC PATCH V2 34/38] riscv: Cleanup rv32_defconfig guoren
` (7 subsequent siblings)
40 siblings, 0 replies; 42+ messages in thread
From: guoren @ 2023-11-12 6:15 UTC (permalink / raw)
To: arnd, guoren, palmer, tglx, conor.dooley, heiko, apatel, atishp,
bjorn, paul.walmsley, anup, jiawei, liweiwei, wefu, U2FsdGVkX1,
wangjunqiang, kito.cheng, andy.chiu, vincent.chen, greentime.hu,
wuwei2016, jrtc27, luto, fweimer, catalin.marinas, hjl.tools
Cc: linux-arch, linux-kernel, linux-riscv, Guo Ren
From: Guo Ren <guoren@linux.alibaba.com>
Follow the rv32_defconfig rule to add rv64ilp32_defconfig; the only
difference is:
-CONFIG_ARCH_RV32I=y
+CONFIG_ARCH_RV64ILP32=y
Signed-off-by: Guo Ren <guoren@linux.alibaba.com>
Signed-off-by: Guo Ren <guoren@kernel.org>
---
arch/riscv/Makefile | 4 ++++
arch/riscv/configs/64ilp32.config | 2 ++
2 files changed, 6 insertions(+)
create mode 100644 arch/riscv/configs/64ilp32.config
diff --git a/arch/riscv/Makefile b/arch/riscv/Makefile
index 3b1435bade49..d01f41fdf57f 100644
--- a/arch/riscv/Makefile
+++ b/arch/riscv/Makefile
@@ -205,3 +205,7 @@ rv32_defconfig:
PHONY += rv32_nommu_virt_defconfig
rv32_nommu_virt_defconfig:
$(Q)$(MAKE) -f $(srctree)/Makefile nommu_virt_defconfig 32-bit.config
+
+PHONY += rv64ilp32_defconfig
+rv64ilp32_defconfig:
+ $(Q)$(MAKE) -f $(srctree)/Makefile defconfig 64ilp32.config
diff --git a/arch/riscv/configs/64ilp32.config b/arch/riscv/configs/64ilp32.config
new file mode 100644
index 000000000000..7d836aa2fae7
--- /dev/null
+++ b/arch/riscv/configs/64ilp32.config
@@ -0,0 +1,2 @@
+CONFIG_ARCH_RV64ILP32=y
+CONFIG_NONPORTABLE=y
--
2.36.1
^ permalink raw reply related [flat|nested] 42+ messages in thread* [RFC PATCH V2 34/38] riscv: Cleanup rv32_defconfig
2023-11-12 6:14 [RFC PATCH V2 00/38] rv64ilp32: Running ILP32 on RV64 ISA guoren
` (32 preceding siblings ...)
2023-11-12 6:15 ` [RFC PATCH V2 33/38] riscv: s64ilp32: Add rv64ilp32_defconfig guoren
@ 2023-11-12 6:15 ` guoren
2023-11-12 6:15 ` [RFC PATCH V2 35/38] clocksource: riscv: s64ilp32: Use __riscv_xlen instead of CONFIG_32BIT guoren
` (6 subsequent siblings)
40 siblings, 0 replies; 42+ messages in thread
From: guoren @ 2023-11-12 6:15 UTC (permalink / raw)
To: arnd, guoren, palmer, tglx, conor.dooley, heiko, apatel, atishp,
bjorn, paul.walmsley, anup, jiawei, liweiwei, wefu, U2FsdGVkX1,
wangjunqiang, kito.cheng, andy.chiu, vincent.chen, greentime.hu,
wuwei2016, jrtc27, luto, fweimer, catalin.marinas, hjl.tools
Cc: linux-arch, linux-kernel, linux-riscv, Guo Ren, Randy Dunlap
From: Guo Ren <guoren@linux.alibaba.com>
Remove unnecessary configs to make rv32_defconfig have a minimal
difference from the defconfig. CONFIG_ARCH_RV32I selects the
CONFIG_32BIT, so putting it in the file is unnecessary. Also, there is
no need to comment on CONFIG_PORTABLE; it should come from carelessness.
Next rv64ilp32_defconfig would like:
CONFIG_ARCH_RV64ILP32=y
CONFIG_NONPORTABLE=y
Signed-off-by: Guo Ren <guoren@linux.alibaba.com>
Signed-off-by: Guo Ren <guoren@kernel.org>
Cc: Randy Dunlap <rdunlap@infradead.org>
Cc: Palmer Dabbelt <palmer@rivosinc.com>
---
arch/riscv/configs/32-bit.config | 2 --
1 file changed, 2 deletions(-)
diff --git a/arch/riscv/configs/32-bit.config b/arch/riscv/configs/32-bit.config
index f6af0f708df4..eb87885c8640 100644
--- a/arch/riscv/configs/32-bit.config
+++ b/arch/riscv/configs/32-bit.config
@@ -1,4 +1,2 @@
CONFIG_ARCH_RV32I=y
-CONFIG_32BIT=y
-# CONFIG_PORTABLE is not set
CONFIG_NONPORTABLE=y
--
2.36.1
^ permalink raw reply related [flat|nested] 42+ messages in thread* [RFC PATCH V2 35/38] clocksource: riscv: s64ilp32: Use __riscv_xlen instead of CONFIG_32BIT
2023-11-12 6:14 [RFC PATCH V2 00/38] rv64ilp32: Running ILP32 on RV64 ISA guoren
` (33 preceding siblings ...)
2023-11-12 6:15 ` [RFC PATCH V2 34/38] riscv: Cleanup rv32_defconfig guoren
@ 2023-11-12 6:15 ` guoren
2023-11-12 6:15 ` [RFC PATCH V2 36/38] irqchip: " guoren
` (5 subsequent siblings)
40 siblings, 0 replies; 42+ messages in thread
From: guoren @ 2023-11-12 6:15 UTC (permalink / raw)
To: arnd, guoren, palmer, tglx, conor.dooley, heiko, apatel, atishp,
bjorn, paul.walmsley, anup, jiawei, liweiwei, wefu, U2FsdGVkX1,
wangjunqiang, kito.cheng, andy.chiu, vincent.chen, greentime.hu,
wuwei2016, jrtc27, luto, fweimer, catalin.marinas, hjl.tools
Cc: linux-arch, linux-kernel, linux-riscv, Guo Ren
From: Guo Ren <guoren@linux.alibaba.com>
When s64ilp32 enabled, CONFIG_32BIT=y but __riscv_xlen=64. So we
must use __riscv_xlen to detect real machine XLEN for CSR access.
Signed-off-by: Guo Ren <guoren@linux.alibaba.com>
Signed-off-by: Guo Ren <guoren@kernel.org>
---
drivers/clocksource/timer-riscv.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/clocksource/timer-riscv.c b/drivers/clocksource/timer-riscv.c
index da3071b387eb..fe83b4e2005a 100644
--- a/drivers/clocksource/timer-riscv.c
+++ b/drivers/clocksource/timer-riscv.c
@@ -38,7 +38,7 @@ static int riscv_clock_next_event(unsigned long delta,
csr_set(CSR_IE, IE_TIE);
if (static_branch_likely(&riscv_sstc_available)) {
-#if defined(CONFIG_32BIT)
+#if __riscv_xlen == 32
csr_write(CSR_STIMECMP, next_tval & 0xFFFFFFFF);
csr_write(CSR_STIMECMPH, next_tval >> 32);
#else
--
2.36.1
^ permalink raw reply related [flat|nested] 42+ messages in thread* [RFC PATCH V2 36/38] irqchip: riscv: s64ilp32: Use __riscv_xlen instead of CONFIG_32BIT
2023-11-12 6:14 [RFC PATCH V2 00/38] rv64ilp32: Running ILP32 on RV64 ISA guoren
` (34 preceding siblings ...)
2023-11-12 6:15 ` [RFC PATCH V2 35/38] clocksource: riscv: s64ilp32: Use __riscv_xlen instead of CONFIG_32BIT guoren
@ 2023-11-12 6:15 ` guoren
2023-11-12 6:15 ` [RFC PATCH V2 37/38] add tinylab defconfig guoren
` (4 subsequent siblings)
40 siblings, 0 replies; 42+ messages in thread
From: guoren @ 2023-11-12 6:15 UTC (permalink / raw)
To: arnd, guoren, palmer, tglx, conor.dooley, heiko, apatel, atishp,
bjorn, paul.walmsley, anup, jiawei, liweiwei, wefu, U2FsdGVkX1,
wangjunqiang, kito.cheng, andy.chiu, vincent.chen, greentime.hu,
wuwei2016, jrtc27, luto, fweimer, catalin.marinas, hjl.tools
Cc: linux-arch, linux-kernel, linux-riscv, Guo Ren
From: Guo Ren <guoren@linux.alibaba.com>
When s64ilp32 enabled, CONFIG_32BIT=y but __riscv_xlen=64. So we
must use __riscv_xlen to detect real machine XLEN for CSR access.
Signed-off-by: Guo Ren <guoren@linux.alibaba.com>
Signed-off-by: Guo Ren <guoren@kernel.org>
---
drivers/irqchip/irq-riscv-intc.c | 9 +++------
1 file changed, 3 insertions(+), 6 deletions(-)
diff --git a/drivers/irqchip/irq-riscv-intc.c b/drivers/irqchip/irq-riscv-intc.c
index 4adeee1bc391..ee3514ef4326 100644
--- a/drivers/irqchip/irq-riscv-intc.c
+++ b/drivers/irqchip/irq-riscv-intc.c
@@ -22,10 +22,7 @@ static struct irq_domain *intc_domain;
static asmlinkage void riscv_intc_irq(struct pt_regs *regs)
{
- unsigned long cause = regs->cause & ~CAUSE_IRQ_FLAG;
-
- if (unlikely(cause >= BITS_PER_LONG))
- panic("unexpected interrupt cause");
+ xlen_t cause = regs->cause & ~CAUSE_IRQ_FLAG;
generic_handle_domain_irq(intc_domain, cause);
}
@@ -117,7 +114,7 @@ static int __init riscv_intc_init_common(struct fwnode_handle *fn)
{
int rc;
- intc_domain = irq_domain_create_linear(fn, BITS_PER_LONG,
+ intc_domain = irq_domain_create_linear(fn, __riscv_xlen,
&riscv_intc_domain_ops, NULL);
if (!intc_domain) {
pr_err("unable to add IRQ domain\n");
@@ -132,7 +129,7 @@ static int __init riscv_intc_init_common(struct fwnode_handle *fn)
riscv_set_intc_hwnode_fn(riscv_intc_hwnode);
- pr_info("%d local interrupts mapped\n", BITS_PER_LONG);
+ pr_info("%d local interrupts mapped\n", __riscv_xlen);
return 0;
}
--
2.36.1
^ permalink raw reply related [flat|nested] 42+ messages in thread* [RFC PATCH V2 37/38] add tinylab defconfig
2023-11-12 6:14 [RFC PATCH V2 00/38] rv64ilp32: Running ILP32 on RV64 ISA guoren
` (35 preceding siblings ...)
2023-11-12 6:15 ` [RFC PATCH V2 36/38] irqchip: " guoren
@ 2023-11-12 6:15 ` guoren
2023-11-12 6:15 ` [RFC PATCH V2 38/38] 64ilp32 v.s. 64lp64 guoren
` (3 subsequent siblings)
40 siblings, 0 replies; 42+ messages in thread
From: guoren @ 2023-11-12 6:15 UTC (permalink / raw)
To: arnd, guoren, palmer, tglx, conor.dooley, heiko, apatel, atishp,
bjorn, paul.walmsley, anup, jiawei, liweiwei, wefu, U2FsdGVkX1,
wangjunqiang, kito.cheng, andy.chiu, vincent.chen, greentime.hu,
wuwei2016, jrtc27, luto, fweimer, catalin.marinas, hjl.tools
Cc: linux-arch, linux-kernel, linux-riscv, Guo Ren
From: Guo Ren <guoren@linux.alibaba.com>
Signed-off-by: Guo Ren <guoren@linux.alibaba.com>
---
arch/riscv/configs/tinylab32ilp32_defconfig | 88 ++++++++++++++++++++
arch/riscv/configs/tinylab64ilp32_defconfig | 89 +++++++++++++++++++++
arch/riscv/configs/tinylab_defconfig | 89 +++++++++++++++++++++
3 files changed, 266 insertions(+)
create mode 100644 arch/riscv/configs/tinylab32ilp32_defconfig
create mode 100644 arch/riscv/configs/tinylab64ilp32_defconfig
create mode 100644 arch/riscv/configs/tinylab_defconfig
diff --git a/arch/riscv/configs/tinylab32ilp32_defconfig b/arch/riscv/configs/tinylab32ilp32_defconfig
new file mode 100644
index 000000000000..64adbc788430
--- /dev/null
+++ b/arch/riscv/configs/tinylab32ilp32_defconfig
@@ -0,0 +1,88 @@
+# CONFIG_LOCALVERSION_AUTO is not set
+# CONFIG_CROSS_MEMORY_ATTACH is not set
+CONFIG_BLK_DEV_INITRD=y
+# CONFIG_RD_GZIP is not set
+# CONFIG_RD_BZIP2 is not set
+# CONFIG_RD_LZMA is not set
+# CONFIG_RD_XZ is not set
+# CONFIG_RD_LZO is not set
+# CONFIG_RD_LZ4 is not set
+# CONFIG_RD_ZSTD is not set
+# CONFIG_INITRAMFS_PRESERVE_MTIME is not set
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+# CONFIG_MULTIUSER is not set
+# CONFIG_SYSFS_SYSCALL is not set
+# CONFIG_FHANDLE is not set
+# CONFIG_POSIX_TIMERS is not set
+# CONFIG_BUG is not set
+# CONFIG_BASE_FULL is not set
+# CONFIG_FUTEX is not set
+# CONFIG_EPOLL is not set
+# CONFIG_SIGNALFD is not set
+# CONFIG_TIMERFD is not set
+# CONFIG_EVENTFD is not set
+# CONFIG_SHMEM is not set
+# CONFIG_AIO is not set
+# CONFIG_IO_URING is not set
+# CONFIG_ADVISE_SYSCALLS is not set
+# CONFIG_MEMBARRIER is not set
+# CONFIG_KALLSYMS is not set
+# CONFIG_RSEQ is not set
+CONFIG_EMBEDDED=y
+CONFIG_NONPORTABLE=y
+CONFIG_ARCH_RV32I=y
+CONFIG_CMODEL_MEDANY=y
+# CONFIG_RISCV_ISA_SVPBMT is not set
+# CONFIG_RISCV_ISA_ZICBOM is not set
+# CONFIG_RISCV_ISA_ZICBOZ is not set
+# CONFIG_FPU is not set
+# CONFIG_SECCOMP is not set
+# CONFIG_STACKPROTECTOR is not set
+# CONFIG_STRICT_KERNEL_RWX is not set
+# CONFIG_BLOCK is not set
+# CONFIG_BINFMT_SCRIPT is not set
+# CONFIG_COREDUMP is not set
+CONFIG_SLUB_TINY=y
+# CONFIG_COMPAT_BRK is not set
+# CONFIG_COMPACTION is not set
+# CONFIG_VM_EVENT_COUNTERS is not set
+# CONFIG_SECRETMEM is not set
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+# CONFIG_STANDALONE is not set
+# CONFIG_PREVENT_FIRMWARE_BUILD is not set
+# CONFIG_FW_LOADER is not set
+# CONFIG_ALLOW_DEV_COREDUMP is not set
+# CONFIG_INPUT is not set
+# CONFIG_SERIO is not set
+# CONFIG_VT is not set
+# CONFIG_UNIX98_PTYS is not set
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_LEGACY_TIOCSTI is not set
+# CONFIG_LDISC_AUTOLOAD is not set
+CONFIG_SERIAL_8250=y
+# CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set
+# CONFIG_SERIAL_8250_16550A_VARIANTS is not set
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_OF_PLATFORM=y
+# CONFIG_HW_RANDOM is not set
+# CONFIG_DEVMEM is not set
+# CONFIG_HWMON is not set
+# CONFIG_USB_SUPPORT is not set
+# CONFIG_VIRTIO_MENU is not set
+# CONFIG_VHOST_MENU is not set
+# CONFIG_IOMMU_SUPPORT is not set
+# CONFIG_FILE_LOCKING is not set
+# CONFIG_DNOTIFY is not set
+# CONFIG_INOTIFY_USER is not set
+# CONFIG_PROC_FS is not set
+# CONFIG_SYSFS is not set
+# CONFIG_EFIVAR_FS is not set
+# CONFIG_MISC_FILESYSTEMS is not set
+CONFIG_INIT_STACK_NONE=y
+# CONFIG_SYMBOLIC_ERRNAME is not set
+# CONFIG_DEBUG_MISC is not set
+# CONFIG_SECTION_MISMATCH_WARN_ONLY is not set
+CONFIG_PANIC_TIMEOUT=1
+# CONFIG_FTRACE is not set
+# CONFIG_RUNTIME_TESTING_MENU is not set
diff --git a/arch/riscv/configs/tinylab64ilp32_defconfig b/arch/riscv/configs/tinylab64ilp32_defconfig
new file mode 100644
index 000000000000..703778a13157
--- /dev/null
+++ b/arch/riscv/configs/tinylab64ilp32_defconfig
@@ -0,0 +1,89 @@
+# CONFIG_LOCALVERSION_AUTO is not set
+# CONFIG_CROSS_MEMORY_ATTACH is not set
+CONFIG_BLK_DEV_INITRD=y
+# CONFIG_RD_GZIP is not set
+# CONFIG_RD_BZIP2 is not set
+# CONFIG_RD_LZMA is not set
+# CONFIG_RD_XZ is not set
+# CONFIG_RD_LZO is not set
+# CONFIG_RD_LZ4 is not set
+# CONFIG_RD_ZSTD is not set
+# CONFIG_INITRAMFS_PRESERVE_MTIME is not set
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+# CONFIG_MULTIUSER is not set
+# CONFIG_SYSFS_SYSCALL is not set
+# CONFIG_FHANDLE is not set
+# CONFIG_POSIX_TIMERS is not set
+# CONFIG_BUG is not set
+# CONFIG_BASE_FULL is not set
+# CONFIG_FUTEX is not set
+# CONFIG_EPOLL is not set
+# CONFIG_SIGNALFD is not set
+# CONFIG_TIMERFD is not set
+# CONFIG_EVENTFD is not set
+# CONFIG_SHMEM is not set
+# CONFIG_AIO is not set
+# CONFIG_IO_URING is not set
+# CONFIG_ADVISE_SYSCALLS is not set
+# CONFIG_MEMBARRIER is not set
+# CONFIG_KALLSYMS is not set
+# CONFIG_RSEQ is not set
+CONFIG_EMBEDDED=y
+CONFIG_NONPORTABLE=y
+CONFIG_ARCH_RV64ILP32=y
+CONFIG_CMODEL_MEDANY=y
+# CONFIG_RISCV_ISA_C is not set
+# CONFIG_RISCV_ISA_SVPBMT is not set
+# CONFIG_RISCV_ISA_ZICBOM is not set
+# CONFIG_RISCV_ISA_ZICBOZ is not set
+# CONFIG_FPU is not set
+# CONFIG_EFI is not set
+# CONFIG_SECCOMP is not set
+# CONFIG_STACKPROTECTOR is not set
+# CONFIG_STRICT_KERNEL_RWX is not set
+# CONFIG_BLOCK is not set
+# CONFIG_BINFMT_SCRIPT is not set
+# CONFIG_COREDUMP is not set
+CONFIG_SLUB_TINY=y
+# CONFIG_COMPAT_BRK is not set
+# CONFIG_COMPACTION is not set
+# CONFIG_VM_EVENT_COUNTERS is not set
+# CONFIG_SECRETMEM is not set
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+# CONFIG_STANDALONE is not set
+# CONFIG_PREVENT_FIRMWARE_BUILD is not set
+# CONFIG_FW_LOADER is not set
+# CONFIG_ALLOW_DEV_COREDUMP is not set
+# CONFIG_INPUT is not set
+# CONFIG_SERIO is not set
+# CONFIG_VT is not set
+# CONFIG_UNIX98_PTYS is not set
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_LEGACY_TIOCSTI is not set
+# CONFIG_LDISC_AUTOLOAD is not set
+CONFIG_SERIAL_8250=y
+# CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set
+# CONFIG_SERIAL_8250_16550A_VARIANTS is not set
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_OF_PLATFORM=y
+# CONFIG_HW_RANDOM is not set
+# CONFIG_DEVMEM is not set
+# CONFIG_HWMON is not set
+# CONFIG_USB_SUPPORT is not set
+# CONFIG_VIRTIO_MENU is not set
+# CONFIG_VHOST_MENU is not set
+# CONFIG_IOMMU_SUPPORT is not set
+# CONFIG_FILE_LOCKING is not set
+# CONFIG_DNOTIFY is not set
+# CONFIG_INOTIFY_USER is not set
+# CONFIG_PROC_FS is not set
+# CONFIG_SYSFS is not set
+# CONFIG_MISC_FILESYSTEMS is not set
+CONFIG_INIT_STACK_NONE=y
+# CONFIG_SYMBOLIC_ERRNAME is not set
+# CONFIG_DEBUG_MISC is not set
+# CONFIG_SECTION_MISMATCH_WARN_ONLY is not set
+CONFIG_PANIC_TIMEOUT=1
+# CONFIG_FTRACE is not set
+# CONFIG_RUNTIME_TESTING_MENU is not set
diff --git a/arch/riscv/configs/tinylab_defconfig b/arch/riscv/configs/tinylab_defconfig
new file mode 100644
index 000000000000..6294c4590edd
--- /dev/null
+++ b/arch/riscv/configs/tinylab_defconfig
@@ -0,0 +1,89 @@
+# CONFIG_LOCALVERSION_AUTO is not set
+# CONFIG_CROSS_MEMORY_ATTACH is not set
+CONFIG_BLK_DEV_INITRD=y
+# CONFIG_RD_GZIP is not set
+# CONFIG_RD_BZIP2 is not set
+# CONFIG_RD_LZMA is not set
+# CONFIG_RD_XZ is not set
+# CONFIG_RD_LZO is not set
+# CONFIG_RD_LZ4 is not set
+# CONFIG_RD_ZSTD is not set
+# CONFIG_INITRAMFS_PRESERVE_MTIME is not set
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+# CONFIG_MULTIUSER is not set
+# CONFIG_SYSFS_SYSCALL is not set
+# CONFIG_FHANDLE is not set
+# CONFIG_POSIX_TIMERS is not set
+# CONFIG_BUG is not set
+# CONFIG_BASE_FULL is not set
+# CONFIG_FUTEX is not set
+# CONFIG_EPOLL is not set
+# CONFIG_SIGNALFD is not set
+# CONFIG_TIMERFD is not set
+# CONFIG_EVENTFD is not set
+# CONFIG_SHMEM is not set
+# CONFIG_AIO is not set
+# CONFIG_IO_URING is not set
+# CONFIG_ADVISE_SYSCALLS is not set
+# CONFIG_MEMBARRIER is not set
+# CONFIG_KALLSYMS is not set
+# CONFIG_RSEQ is not set
+CONFIG_EMBEDDED=y
+CONFIG_NONPORTABLE=y
+# CONFIG_RISCV_ISA_C is not set
+# CONFIG_RISCV_ISA_SVNAPOT is not set
+# CONFIG_RISCV_ISA_SVPBMT is not set
+# CONFIG_RISCV_ISA_ZICBOM is not set
+# CONFIG_RISCV_ISA_ZICBOZ is not set
+# CONFIG_FPU is not set
+# CONFIG_COMPAT is not set
+# CONFIG_EFI is not set
+# CONFIG_SECCOMP is not set
+# CONFIG_STACKPROTECTOR is not set
+# CONFIG_STRICT_KERNEL_RWX is not set
+# CONFIG_BLOCK is not set
+# CONFIG_BINFMT_SCRIPT is not set
+# CONFIG_COREDUMP is not set
+CONFIG_SLUB_TINY=y
+# CONFIG_COMPAT_BRK is not set
+# CONFIG_COMPACTION is not set
+# CONFIG_VM_EVENT_COUNTERS is not set
+# CONFIG_SECRETMEM is not set
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+# CONFIG_STANDALONE is not set
+# CONFIG_PREVENT_FIRMWARE_BUILD is not set
+# CONFIG_FW_LOADER is not set
+# CONFIG_ALLOW_DEV_COREDUMP is not set
+# CONFIG_INPUT is not set
+# CONFIG_SERIO is not set
+# CONFIG_VT is not set
+# CONFIG_UNIX98_PTYS is not set
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_LEGACY_TIOCSTI is not set
+# CONFIG_LDISC_AUTOLOAD is not set
+CONFIG_SERIAL_8250=y
+# CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set
+# CONFIG_SERIAL_8250_16550A_VARIANTS is not set
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_OF_PLATFORM=y
+# CONFIG_HW_RANDOM is not set
+# CONFIG_DEVMEM is not set
+# CONFIG_HWMON is not set
+# CONFIG_USB_SUPPORT is not set
+# CONFIG_VIRTIO_MENU is not set
+# CONFIG_VHOST_MENU is not set
+# CONFIG_IOMMU_SUPPORT is not set
+# CONFIG_FILE_LOCKING is not set
+# CONFIG_DNOTIFY is not set
+# CONFIG_INOTIFY_USER is not set
+# CONFIG_PROC_FS is not set
+# CONFIG_SYSFS is not set
+# CONFIG_MISC_FILESYSTEMS is not set
+CONFIG_INIT_STACK_NONE=y
+# CONFIG_SYMBOLIC_ERRNAME is not set
+# CONFIG_DEBUG_MISC is not set
+# CONFIG_SECTION_MISMATCH_WARN_ONLY is not set
+CONFIG_PANIC_TIMEOUT=1
+# CONFIG_FTRACE is not set
+# CONFIG_RUNTIME_TESTING_MENU is not set
--
2.36.1
^ permalink raw reply related [flat|nested] 42+ messages in thread* [RFC PATCH V2 38/38] 64ilp32 v.s. 64lp64
2023-11-12 6:14 [RFC PATCH V2 00/38] rv64ilp32: Running ILP32 on RV64 ISA guoren
` (36 preceding siblings ...)
2023-11-12 6:15 ` [RFC PATCH V2 37/38] add tinylab defconfig guoren
@ 2023-11-12 6:15 ` guoren
2023-11-13 4:13 ` [RFC PATCH V2 00/38] rv64ilp32: Running ILP32 on RV64 ISA Guo Ren
` (2 subsequent siblings)
40 siblings, 0 replies; 42+ messages in thread
From: guoren @ 2023-11-12 6:15 UTC (permalink / raw)
To: arnd, guoren, palmer, tglx, conor.dooley, heiko, apatel, atishp,
bjorn, paul.walmsley, anup, jiawei, liweiwei, wefu, U2FsdGVkX1,
wangjunqiang, kito.cheng, andy.chiu, vincent.chen, greentime.hu,
wuwei2016, jrtc27, luto, fweimer, catalin.marinas, hjl.tools
Cc: linux-arch, linux-kernel, linux-riscv, Guo Ren
From: Guo Ren <guoren@linux.alibaba.com>
Signed-off-by: Guo Ren <guoren@linux.alibaba.com>
---
arch/riscv/Kconfig | 1 -
arch/riscv/include/asm/page.h | 2 +-
init/main.c | 2 ++
3 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
index 5106eab17811..acd6aa60ed84 100644
--- a/arch/riscv/Kconfig
+++ b/arch/riscv/Kconfig
@@ -160,7 +160,6 @@ config RISCV
select THREAD_INFO_IN_TASK
select TRACE_IRQFLAGS_SUPPORT
select UACCESS_MEMCPY if !MMU
- select ZONE_DMA32 if 64BIT
config CLANG_SUPPORTS_DYNAMIC_FTRACE
def_bool CC_IS_CLANG
diff --git a/arch/riscv/include/asm/page.h b/arch/riscv/include/asm/page.h
index 7c535e88cf91..f9af3e6b6e21 100644
--- a/arch/riscv/include/asm/page.h
+++ b/arch/riscv/include/asm/page.h
@@ -106,7 +106,7 @@ typedef struct page *pgtable_t;
* We override this value as its generic definition uses __pa too early in
* the boot process (before kernel_map.va_pa_offset is set).
*/
-#define MIN_MEMBLOCK_ADDR 0
+#define MIN_MEMBLOCK_ADDR 0x60400000ULL
#endif
#ifdef CONFIG_MMU
diff --git a/init/main.c b/init/main.c
index ad920fac325c..f88f0227e398 100644
--- a/init/main.c
+++ b/init/main.c
@@ -1496,6 +1496,8 @@ static int __ref kernel_init(void *unused)
!try_to_run_init_process("/bin/sh"))
return 0;
+ show_mem(0, NULL);
+
panic("No working init found. Try passing init= option to kernel. "
"See Linux Documentation/admin-guide/init.rst for guidance.");
}
--
2.36.1
^ permalink raw reply related [flat|nested] 42+ messages in thread* Re: [RFC PATCH V2 00/38] rv64ilp32: Running ILP32 on RV64 ISA
2023-11-12 6:14 [RFC PATCH V2 00/38] rv64ilp32: Running ILP32 on RV64 ISA guoren
` (37 preceding siblings ...)
2023-11-12 6:15 ` [RFC PATCH V2 38/38] 64ilp32 v.s. 64lp64 guoren
@ 2023-11-13 4:13 ` Guo Ren
2023-11-13 4:22 ` Guo Ren
2023-12-03 15:31 ` Guo Ren
40 siblings, 0 replies; 42+ messages in thread
From: Guo Ren @ 2023-11-13 4:13 UTC (permalink / raw)
To: arnd, palmer, tglx, conor.dooley, heiko, apatel, atishp, bjorn,
paul.walmsley, anup, jiawei, liweiwei, wefu, U2FsdGVkX1,
wangjunqiang, kito.cheng, andy.chiu, vincent.chen, greentime.hu,
wuwei2016, jrtc27, luto, fweimer, catalin.marinas, hjl.tools
Cc: linux-arch, linux-kernel, linux-riscv, Guo Ren
On Sun, Nov 12, 2023 at 01:14:36AM -0500, guoren@kernel.org wrote:
> From: Guo Ren <guoren@linux.alibaba.com>
>
> This patch series adds s64ilp32 & u64ilp32 support to riscv. The term
> s64ilp32 means smode-xlen=64 and -mabi=ilp32 (ints, longs, and pointers
> are all 32-bit) and u64ilp32 means umode-xlen=64 and -mabi=ilp32, i.e.,
> running 32-bit Linux kernel on 64-bit supervisor mode or running 32-bit
> Linux applications on 32-bit user mode. There have been many 64ilp32
> abis existing, such as mips-n32 [1], arm-aarch64ilp32 [2], and x86-x32
> [3], but they are all about userspace. Thus, this should be the first
> time running a 32-bit Linux kernel with the 64ilp32 ABI at supervisor
> mode (If not, correct me).
>
> +--------------------------------+------------+
> | +-------------------+--------+ | +--------+ |
> | | (compat)|(compat)| | | | |
> | |u64lp64 u64ilp32|u32ilp32| | |u32ilp32| | ABI
> | | ^^^^^^^^| | | | | |
> | +-------------------+--------+ | +--------+ |
> | +-------------------+--------+ | +--------+ |
> | | UXL=64 | UXL=32 | | | UXL=32 | | ISA
> | +-------------------+--------+ | +--------+ |
> +--------------------------------+------------+-------
> | +----------------------------+ | +--------+ |
> | | 64BIT | | | 32BIT| | Kernel
> | | s64lp64 & s64ilp32 | | |s32ilp32| | ABI
> | | ^^^^^^^^ | | | | |
> | +----------------------------+ | +--------+ |
> | +----------------------------+ | +--------+ |
> | | SXL=64 | | | SXL=32 | | ISA
> | +----------------------------+ | +--------+ |
> +--------------------------------+------------+
>
> Motivation:
> ===========
> The current RISC-V has the 64-bit ISA profiles of RVA20, RVA22, and RVA23
> (ongoing) [4], but no 32-bit RVA profile exists or any ongoing plan. That
> means when a vendor wants to produce a 32-bit ISA RISC-V Application
> Processor, they have no shape to follow. Therefore, many cheap riscv
> chips have come out but follow the 64-bit RVA profiles, such as Allwinner
> D1/D1s/F133 [5], SOPHGO CV1800B [6], Canaan Kendryte k230 [7], and
> Bouffalo Lab BL808[3] which are typically cortex-a7 (arm 32-bit) product
> scenarios. So running ILP32 on rv64 ISA is the only choice for these
> chips.
>
> The ilp32 and lp64 have different scenarios, but if the address space
> and data range are under 2GB. The ilp32, compared to the lp64, has three
> advantages:
> - Better memory footprint cost.
> - Better benchmark performance (SPEC CPU 2006/2017).
> - Compatible with ilp32 code.
>
> Memory Footprint
> ================
> rv64lp64 has 25% more memory footprint than rv64ilp32!
>
> Calculation Process:
> rv64lp64 = (4096 - 3407) = 689
> rv64ilp32 = (4096 - 3231) = 865
Correct:
rv64ilp32 = (4096 - 3407) = 689
rv64lp64 = (4096 - 3231) = 865
> (865 - 689)/689 = 25.54426%
>
> Here are the ILP32 v.s. LP64 Linux kernel data type comparison:
> 32-bit 64-bit
> sizeof(page): 32bytes 64bytes
> sizeof(list_head): 8bytes 16bytes
> sizeof(hlist_head): 8bytes 16bytes
> sizeof(vm_area): 68bytes 136bytes
> ...
>
> The size of ilp32's long & pointer is just half of lp64's (rv64 default
> abi - longs and pointers are all 64-bit). This significant difference
> in data type causes different memory & cache footprint costs. Here is
> the comparison log between rv64ilp32 and rv64lp64 in the same 20MB(16MB
> for Linux) qemu system environment:
>
> rv64ilp32:
> Memory: 14008K/16384K available (1253K kernel code, 474K rwdata, 114K
> rodata, 134K init, 192K bss, 2376K reserved, 0K cma-reserved)
> Mem-Info:
> active_anon:0 inactive_anon:0 isolated_anon:0
> active_file:0 inactive_file:0 isolated_file:0
> unevictable:0 dirty:0 writeback:0
> slab_reclaimable:0 slab_unreclaimable:47
> mapped:0 shmem:0 pagetables:0
> sec_pagetables:0 bounce:0
> kernel_misc_reclaimable:0
> free:3407 free_pcp:45 free_cma:0
> ^^^^^^^^^
> Node 0 active_anon:0kB inactive_anon:0kB active_file:0kB
> inactive_file:0kB unevictable:0kB isolated(anon):0kB isolated(file):0kB
> mapped:0kB dirty:0kB writeback:0kB shmem:0kB writeback_tmp:0kB
> kernel_stack:104kB pagetables:0kB sec_pagetabl
> es:0kB all_unreclaimable? no
> Normal free:13628kB boost:0kB min:472kB low:588kB high:704kB
> reserved_highatomic:0KB active_anon:0kB inactive_anon:0kB
> active_file:0kB inactive_file:0kB unevictable:0kB writepending:0kB
> present:16384kB managed:14140kB mlocked:0kB bounce:0
> kB free_pcp:180kB local_pcp:180kB free_cma:0kB
> lowmem_reserve[]: 0 0
> Normal: 3*4kB (UM) 2*8kB (M) 2*16kB (M) 2*32kB (M) 3*64kB (M) 2*128kB
> (UM) 3*256kB (M) 4*512kB (UM) 2*1024kB (UM) 2*2048kB (UM) 1*4096kB (M) =
> 13628kB
> 0 total pagecache pages
> 4096 pages RAM
> 0 pages HighMem/MovableOnly
> 561 pages reserved
>
> rv64lp64:
> Memory: 13776K/16384K available (1234K kernel code, 539K rwdata, 129K
> rodata, 161K init, 207K bss, 2608K reserved, 0K cma-reserved)
> Mem-Info:
> active_anon:0 inactive_anon:0 isolated_anon:0
> active_file:0 inactive_file:0 isolated_file:0
> unevictable:0 dirty:0 writeback:0
> slab_reclaimable:0 slab_unreclaimable:69
> mapped:0 shmem:0 pagetables:1
> sec_pagetables:0 bounce:0
> kernel_misc_reclaimable:0
> free:3231 free_pcp:55 free_cma:0
> ^^^^^^^^^
> Node 0 active_anon:0kB inactive_anon:0kB active_file:0kB
> inactive_file:0kB unevictable:0kB isolated(anon):0kB isolated(file):0kB
> mapped:0kB dirty:0kB writeback:0kB shmem:0kB writeback_tmp:0kB
> kernel_stack:208kB pagetables:4kB sec_pagetabl
> es:0kB all_unreclaimable? no
> Normal free:12924kB boost:0kB min:468kB low:584kB high:700kB
> reserved_highatomic:0KB active_anon:0kB inactive_anon:0kB
> active_file:0kB inactive_file:0kB unevictable:0kB writepending:0kB
> present:16384kB managed:13936kB mlocked:0kB bounce:0
> kB free_pcp:220kB local_pcp:220kB free_cma:0kB
> lowmem_reserve[]: 0 0
> Normal: 3*4kB (UM) 4*8kB (UM) 3*16kB (M) 3*32kB (UM) 1*64kB (M) 3*128kB
> (UM) 2*256kB (M) 3*512kB (M) 2*1024kB (UM) 2*2048kB (UM) 1*4096kB (M) =
> 12924kB
> 0 total pagecache pages
> 4096 pages RAM
> 0 pages HighMem/MovableOnly
> 612 pages reserved
>
> Why rv64 isa?
> ==============
> Generally speaking, we should build a 32-bit hardware s-mode to run
> 32-bit Linux on a 64/32-bit processor (such as cortex-a35/a53).
> But, it can't reuse performance-related features and instructions of
> the 64-bit hardware, such as 64-bit ALU, AMO, and LD/SD, which would
> cause significant performance gaps on many Linux kernel features:
>
> - memcpy/memset/strcmp (s64ilp32 has half of the instructions count
> and double the bandwidth of load/store instructions than s32ilp32.)
>
> - ebpf JIT is a 64-bit Language virtual machine ISA, which is not
> suitable for mapping to s32ilp32.
>
> - Atomic64 (s64ilp32 has the exact native instructions mapping as
> s64lp64, but s32ilp32 only uses generic_atomic64, a tradeoff &
> limited software solution.)
>
> - Support cmxchg_double for slub (The 2nd 32-bit Linux
> supports the feature, the 1st is i386.)
>
> - ...
>
> Compared with the user space ecosystem, the 32-bit Linux kernel is more
> eager to need 64ilp32 to improve performance because the Linux kernel
> can't utilize float-point/vector features of the ISA.
>
> Simplifies CPU Design
> =====================
> Yes, there are a lot of runing 32-bit Linux on 64-bit hardware examples
> in history, such as arm cortex a35/a53/a55, which implements the 32-bit
> EL1/EL2/EL3 hardware mode to support 32-bit Linux. We could follow Arm's
> style, but riscv could choose another better way. Compared to UXL=32,
> the MXL=SXL=32 has many CSR-related hardware functionalities, which
> causes a lot of effort to mix them into 64-bit hardware. The s64ilp32
> works on MXL=SXL=64 mode, so the CPU vendors needn't implement 32-bit
> machine and supervisor modes.
>
> How does rv64ilp32 work?
> ========================
> The s64ilp32 is the same as the s64lp64 compat mode from a hardware
> view, i.e., MXL=SXL=64 + UXL=32. Because the s64ilp32 uses CONFIG_32BIT
> of Linux, it only supports u32ilp32 abi user space, the current standard
> rv32 software ecosystem, and it can't work with u64lp64 abi (I don't
> want that complex and useless stuff). But it may work with u64ilp32 in the
> future; now, the s64ilp32 depends on the UXL=32 feature of the hardware.
>
> The 64ilp32 gcc still uses sign-extend lw & auipc to generate address
> variables because inserting zero-extend instructions to mask the highest
> 32-bit would cause significant code size and performance problems. Thus,
> we invented an OS approach to solve the problem:
> - When satp=bare and start physical address < 2GB, there is no sign-extend
> address problem.
> - When satp=bare and start physical address > 2GB, we need zjpm liked
> hardware extensions to mask high 32bit.
> (Fortunately, all existed SoCs' (D1/D1s/F133, CV1800B, k230, BL808)
> start physical address < 2GB.)
> - When satp=sv39, we invent double mapping to make the sign-extended
> virtual address the same as the zero-extended virtual address.
>
> +--------+ +---------+ +--------+
> | | +--| 511:PUD1| | |
> | | | +---------+ | |
> | | | | 510:PUD0|--+ | |
> | | | +---------+ | | |
> | | | | | | | |
> | | | | | | | |
> | | | | | | | |
> | | | | INVALID | | | |
> | | | | | | | |
> | .... | | | | | | .... |
> | | | | | | | |
> | | | +---------+ | | |
> | | +--| 3:PUD1 | | | |
> | | | +---------+ | | |
> | | | | 2:PUD0 |--+ | |
> | | | +---------+ | | |
> | | | |1:USR_PUD| | | |
> | | | +---------+ | | |
> | | | |0:USR_PUD| | | |
> +--------+<--+ +---------+ +-->+--------+
> PUD1 ^ PGD PUD0
> 1GB | 4GB 1GB
> |
> +----------+
> | Sv39 PGDP|
> +----------+
> SATP
>
> The size of xlen was always equal to the pointer/long size before
> s64ilp32 emerged. So we need to introduce a new type of data - xlen_t,
> which could deal with CSR-related and callee-save/restore operations.
>
> Some kernel features use 32BIT/64BIT to determine the exact ISA, such as
> ebpf JIT would map to rv32 ISA when CONFIG_32BIT=y. But s64ilp32 needs
> the ebpf JIT map to rv64 ISA when CONFIG_32BIT=y and we need to use
> another config to distinguish the difference.
>
> More detials, please review the path series.
>
> How to run s64ilp32?
> ====================
>
> GNU toolchain
> -------------
> git clone https://github.com/Liaoshihua/riscv-gnu-toolchain.git
> cd riscv-gnu-toolchain
> ./configure --prefix="$PWD/opt-rv64-ilp32/" --with-arch=rv64imac --with-abi=ilp32
> make linux
> export PATH=$PATH:$PWD/opt-rv64-ilp32/bin/
>
> Opensbi
> -------
> git clone https://github.com/riscv-software-src/opensbi.git
> CROSS_COMPILE=riscv64-unknown-linux-gnu- make PLATFORM=generic
>
> Linux kernel
> ------------
> v6.5-rc1 + patches
> cd linux
> make ARCH=riscv CROSS_COMPILE=riscv64-unknown-linux-gnu- rv64ilp32_defconfig
> make ARCH=riscv CROSS_COMPILE=riscv64-unknown-linux-gnu- all
>
> Qemu
> ----
> git clone https://github.com/plctlab/plct-qemu.git -b plct-s64ilp32-dev
> cd plct-qemu
> mkdir build
> cd build
> ../qemu/configure --target-list="riscv64-softmmu riscv32-softmmu"
> make
>
> Patch organization
> ==================
> PATCH [ 1-11] u64ilp32: User space support
> PATCH [12-36] adds time-related vDSO common flow for vdso32
Correct:
PATCH [12-36] s64ilp32: Add s64ip32 linux kernel support
> PATCH [37] Add tiny defconfig for ilp32 v.s. lp64
> PATCH [38] Unify ilp32 & lp64 configs and memory
>
> Open issues
> ===========
>
> Callee saved the register width
> -------------------------------
> For 64-bit ISA (including 64lp64, 64ilp32), callee can't determine the
> correct width used in the register, so they saved the maximum width of
> the ISA register, i.e., xlen size. We also found this rule in x86-x32,
> mips-n32, and aarch64ilp32, which comes from 64lp64. See PATCH [20]
>
> Here are two downsides of this:
> - It would cause a difference with 32ilp32's stack frame, and s64ilp32
> reuses 32ilp32 software stack. Thus, many additional compatible
> problems would happen during the porting of 64ilp32 software.
> - It also increases the budget of the stack usage.
> <setup_vm>:
> auipc a3,0xff3fb
> add a3,a3,1234 # c0000000
> li a5,-1
> lui a4,0xc0000
> addw sp,sp,-96
> srl a5,a5,0x20
> subw a4,a4,a3
> auipc a2,0x111a
> add a2,a2,1212 # c1d1f000
> sd s0,80(sp)----+
> sd s1,72(sp) |
> sd s2,64(sp) |
> sd s7,24(sp) |
> sd s8,16(sp) |
> sd s9,8(sp) |-> All <= 32b widths, but occupy 64b
> sd ra,88(sp) | stack space.
> sd s3,56(sp) | Affect memory footprint & cache
> sd s4,48(sp) | performance.
> sd s5,40(sp) |
> sd s6,32(sp) |
> sd s10,0(sp)----+
> sll a1,a4,0x20
> subw a2,a2,a3
> and a4,a4,a5
>
> So here is a proposal to riscv 64ilp32 ABI:
> - Let the compiler prevent callee saving ">32b variables" in
> callee-registers. (Q: We need to measure, how the influence of
> 64b variables cross function call?)
>
> EF_RISCV_X32
> ------------
> We add an e_flag (EF_RISCV_X32) to distinguish the 32-bit ELF, which
> occupies BIT[6] of the e_flags layout.
>
> ELF Header:
> Magic: 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00
> Class: ELF32
> Data: 2's complement, little endian
> Version: 1 (current)
> OS/ABI: UNIX - System V
> ABI Version: 0
> Type: REL (Relocatable file)
> Machine: RISC-V
> Version: 0x1
> Entry point address: 0x0
> Start of program headers: 0 (bytes into file)
> Start of section headers: 24620 (bytes into file)
> Flags: 0x21, RVC, X32, soft-float ABI
> ^^^
> 64-bit Optimization problem
> ---------------------------
> There is an existing problem in 64ilp32 gcc that combines two pointers
> in one register. Liao is solving that problem. Before he finishes the
> job, we could prevent it with a simple noinline attribute, fortunately.
> struct path {
> struct vfsmount *mnt;
> struct dentry *dentry;
> } __randomize_layout;
>
> struct nameidata {
> struct path path;
> ...
> struct path root;
> ...
> } __randomize_layout;
>
> struct nameidata *nd
> ...
> nd->path = nd->root;
> 6c88 ld a0,24(s1)
> ^^ // a0 contains two pointers
> e088 sd a0,0(s1)
> mntget(path->mnt);
> // Need "lw a0,0(s1)" or "a0 << 32; a0 >> 32"
> 2a6150ef jal c01ce946 <mntget> // bug!
>
> Acknowledge
> ===========
> - GNU: LiaoShihua <shihua@iscas.ac.cn>
> Jiawe Chen<jiawei@iscas.ac.cn>
> - Qemu: Weiwei Li <liweiwei@iscas.ac.cn>
> - Benchmark: Junqiang Wang <wangjunqiang@iscas.ac.cn>
> XiaoOu Chen <chenxiaoou@iscas.ac.cn>
> - Fedora: Wei Fu <wefu@redhat.com>
> Songsong Zhang <U2FsdGVkX1@gmail.com>
>
> References
> ==========
> [1] https://techpubs.jurassic.nl/manuals/0630/developer/Mpro_...
> [2] https://wiki.debian.org/Arm64ilp32Port
> [3] https://lwn.net/Articles/456731/
> [4] https://github.com/riscv/riscv-profiles/releases
> [5] https://www.cnx-software.com/2021/10/25/allwinner-d1s-f13...
> [6] https://milkv.io/duo/
> [7] https://twitter.com/tphuang/status/1631308330256801793
> [8] https://www.cnx-software.com/2022/12/02/pine64-ox64-sbc-b...
>
> Changelog:
> V2:
> - Add u64ilp32 support
> - Rebase v6.5-rc1
> - Enable 64ilp32 vgettimeofday for benchmarking
>
> V1:
> https://lore.kernel.org/linux-riscv/20230518131013.3366406-1-guoren@kernel.org/
>
> Guo Ren (38):
> riscv: u64ilp32: Unify vdso32 & compat_vdso into vdso/Makefile
> riscv: u64ilp32: Remove compat_vdso/
> riscv: u64ilp32: Add time-related vDSO common flow for vdso32
> riscv: u64ilp32: Introduce ILP32 vdso for UXL=64
> riscv: u64ilp32: Adjust vDSO kernel flow for 64ilp32 abi
> riscv: u64ilp32: Add signal support for compat
> riscv: u64ilp32: Add ptrace interface support
> riscv: u64ilp32: Adjust vDSO alternative for 64ilp32 abi
> riscv: u64ilp32: Add xlen_t in user_regs_struct
> riscv: u64ilp32: Remove the restriction of UXL=32
> riscv: u64ilp32: Enable user space runtime switch
> riscv: s64ilp32: Unify ULL & UL into UXL in csr
> riscv: s64ilp32: Introduce xlen_t for 64ILP32 kernel
> riscv: s64ilp32: Add sbi support
> riscv: s64ilp32: Add asid support
> riscv: s64ilp32: Introduce PTR_L and PTR_S
> riscv: s64ilp32: Adjust TASK_SIZE for s64ilp32 kernel
> riscv: s64ilp32: Add ebpf jit support
> riscv: s64ilp32: Add ELF32 support
> riscv: s64ilp32: Add ARCH_RV64ILP32 Kconfig option
> riscv: s64ilp32: Add MMU_SV32 mode support
> riscv: s64ilp32: Add MMU_SV39 mode support
> riscv: s64ilp32: Enable native atomic64
> riscv: s64ilp32: Add TImode (128 int) support
> riscv: s64ilp32: Implement cmpxchg_double
> riscv: s64ilp32: Disable KVM
> riscv: s64ilp32: Correct the rv64ilp32 stackframe layout
> riscv: s64ilp32: Temporary workaround solution to gcc problem
> riscv: s64ilp32: Introduce ARCH_HAS_64ILP32_KERNEL for syscall
> riscv: s64ilp32: Add u32ilp32 ptrace support
> riscv: s64ilp32: Add u32ilp32 signal support
> riscv: s64ilp32: Validate harts by architecture name
> riscv: s64ilp32: Add rv64ilp32_defconfig
> riscv: Cleanup rv32_defconfig
> clocksource: riscv: s64ilp32: Use __riscv_xlen instead of CONFIG_32BIT
> irqchip: riscv: s64ilp32: Use __riscv_xlen instead of CONFIG_32BIT
> add tinylab defconfig
> 64ilp32 v.s. 64lp64
>
> arch/Kconfig | 10 +
> arch/riscv/Kconfig | 49 +++-
> arch/riscv/Kconfig.errata | 2 +-
> arch/riscv/Makefile | 28 ++-
> arch/riscv/configs/32-bit.config | 2 -
> arch/riscv/configs/64ilp32.config | 2 +
> arch/riscv/configs/tinylab32ilp32_defconfig | 88 +++++++
> arch/riscv/configs/tinylab64ilp32_defconfig | 89 +++++++
> arch/riscv/configs/tinylab_defconfig | 89 +++++++
> arch/riscv/include/asm/asm.h | 5 +
> arch/riscv/include/asm/atomic.h | 6 +
> arch/riscv/include/asm/cmpxchg.h | 53 ++++
> arch/riscv/include/asm/cpu_ops_sbi.h | 4 +-
> arch/riscv/include/asm/csr.h | 189 +++++++-------
> arch/riscv/include/asm/elf.h | 7 +-
> arch/riscv/include/asm/extable.h | 2 +-
> arch/riscv/include/asm/module.h | 30 +++
> arch/riscv/include/asm/page.h | 26 +-
> arch/riscv/include/asm/pgtable-64.h | 50 ++--
> arch/riscv/include/asm/pgtable.h | 26 +-
> arch/riscv/include/asm/processor.h | 8 +-
> arch/riscv/include/asm/ptrace.h | 96 ++++----
> arch/riscv/include/asm/sbi.h | 24 +-
> arch/riscv/include/asm/signal32.h | 11 +-
> arch/riscv/include/asm/stacktrace.h | 6 +
> arch/riscv/include/asm/syscall.h | 2 +-
> arch/riscv/include/asm/thread_info.h | 1 +
> arch/riscv/include/asm/timex.h | 10 +-
> arch/riscv/include/asm/tlbflush.h | 2 +-
> arch/riscv/include/asm/vdso.h | 34 ++-
> arch/riscv/include/asm/vdso/gettimeofday.h | 95 +++++++
> arch/riscv/include/uapi/asm/elf.h | 2 +-
> arch/riscv/include/uapi/asm/ptrace.h | 72 +++---
> arch/riscv/include/uapi/asm/unistd.h | 1 +
> arch/riscv/kernel/Makefile | 5 +-
> arch/riscv/kernel/alternative.c | 50 +++-
> arch/riscv/kernel/compat_signal.c | 23 +-
> arch/riscv/kernel/compat_vdso/.gitignore | 2 -
> arch/riscv/kernel/compat_vdso/compat_vdso.S | 8 -
> .../kernel/compat_vdso/compat_vdso.lds.S | 3 -
> arch/riscv/kernel/compat_vdso/flush_icache.S | 3 -
> arch/riscv/kernel/compat_vdso/getcpu.S | 3 -
> arch/riscv/kernel/compat_vdso/note.S | 3 -
> arch/riscv/kernel/compat_vdso/rt_sigreturn.S | 3 -
> arch/riscv/kernel/cpu.c | 9 +-
> arch/riscv/kernel/cpu_ops_sbi.c | 4 +-
> arch/riscv/kernel/entry.S | 24 +-
> arch/riscv/kernel/head.S | 8 +-
> arch/riscv/kernel/process.c | 10 +-
> arch/riscv/kernel/ptrace.c | 9 +-
> arch/riscv/kernel/sbi.c | 24 +-
> arch/riscv/kernel/signal.c | 79 ++++--
> arch/riscv/kernel/traps.c | 4 +-
> arch/riscv/kernel/vdso.c | 102 ++++++--
> arch/riscv/kernel/vdso/Makefile | 232 ++++++++++++++----
> ..._vdso_offsets.sh => gen_vdso32_offsets.sh} | 2 +-
> .../gen_vdso64_offsets.sh} | 2 +-
> .../kernel/vdso/gen_vdso64ilp32_offsets.sh | 5 +
> arch/riscv/kernel/vdso/vdso.lds.S | 2 -
> arch/riscv/kernel/vdso/vgettimeofday.c | 39 ++-
> arch/riscv/kernel/vdso32.S | 8 +
> arch/riscv/kernel/{vdso/vdso.S => vdso64.S} | 8 +-
> arch/riscv/kernel/vdso64ilp32.S | 8 +
> arch/riscv/kernel/vector.c | 2 +-
> arch/riscv/kvm/Kconfig | 1 +
> arch/riscv/lib/Makefile | 1 +
> arch/riscv/lib/memset.S | 4 +-
> arch/riscv/mm/context.c | 16 +-
> arch/riscv/mm/fault.c | 13 +-
> arch/riscv/mm/init.c | 24 +-
> arch/riscv/net/Makefile | 6 +-
> arch/riscv/net/bpf_jit_comp64.c | 6 +-
> drivers/clocksource/timer-riscv.c | 2 +-
> drivers/irqchip/irq-riscv-intc.c | 9 +-
> fs/namei.c | 2 +-
> fs/open.c | 22 ++
> fs/read_write.c | 17 ++
> fs/sync.c | 22 ++
> include/linux/syscalls.h | 35 ++-
> init/main.c | 2 +
> kernel/signal.c | 24 +-
> mm/fadvise.c | 24 ++
> 82 files changed, 1526 insertions(+), 509 deletions(-)
> create mode 100644 arch/riscv/configs/64ilp32.config
> create mode 100644 arch/riscv/configs/tinylab32ilp32_defconfig
> create mode 100644 arch/riscv/configs/tinylab64ilp32_defconfig
> create mode 100644 arch/riscv/configs/tinylab_defconfig
> delete mode 100644 arch/riscv/kernel/compat_vdso/.gitignore
> delete mode 100644 arch/riscv/kernel/compat_vdso/compat_vdso.S
> delete mode 100644 arch/riscv/kernel/compat_vdso/compat_vdso.lds.S
> delete mode 100644 arch/riscv/kernel/compat_vdso/flush_icache.S
> delete mode 100644 arch/riscv/kernel/compat_vdso/getcpu.S
> delete mode 100644 arch/riscv/kernel/compat_vdso/note.S
> delete mode 100644 arch/riscv/kernel/compat_vdso/rt_sigreturn.S
> rename arch/riscv/kernel/vdso/{gen_vdso_offsets.sh => gen_vdso32_offsets.sh} (78%)
> rename arch/riscv/kernel/{compat_vdso/gen_compat_vdso_offsets.sh => vdso/gen_vdso64_offsets.sh} (77%)
> create mode 100755 arch/riscv/kernel/vdso/gen_vdso64ilp32_offsets.sh
> create mode 100644 arch/riscv/kernel/vdso32.S
> rename arch/riscv/kernel/{vdso/vdso.S => vdso64.S} (73%)
> create mode 100644 arch/riscv/kernel/vdso64ilp32.S
>
> --
> 2.36.1
>
>
> _______________________________________________
> linux-riscv mailing list
> linux-riscv@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-riscv
>
^ permalink raw reply [flat|nested] 42+ messages in thread* Re: [RFC PATCH V2 00/38] rv64ilp32: Running ILP32 on RV64 ISA
2023-11-12 6:14 [RFC PATCH V2 00/38] rv64ilp32: Running ILP32 on RV64 ISA guoren
` (38 preceding siblings ...)
2023-11-13 4:13 ` [RFC PATCH V2 00/38] rv64ilp32: Running ILP32 on RV64 ISA Guo Ren
@ 2023-11-13 4:22 ` Guo Ren
2023-12-03 15:31 ` Guo Ren
40 siblings, 0 replies; 42+ messages in thread
From: Guo Ren @ 2023-11-13 4:22 UTC (permalink / raw)
To: arnd, palmer, tglx, conor.dooley, heiko, apatel, atishp, bjorn,
paul.walmsley, anup, jiawei, liweiwei, wefu, U2FsdGVkX1,
wangjunqiang, kito.cheng, andy.chiu, vincent.chen, greentime.hu,
wuwei2016, jrtc27, luto, fweimer, catalin.marinas, hjl.tools
Cc: linux-arch, linux-kernel, linux-riscv, Guo Ren
On Sun, Nov 12, 2023 at 01:14:36AM -0500, guoren@kernel.org wrote:
> From: Guo Ren <guoren@linux.alibaba.com>
>
> This patch series adds s64ilp32 & u64ilp32 support to riscv. The term
> s64ilp32 means smode-xlen=64 and -mabi=ilp32 (ints, longs, and pointers
> are all 32-bit) and u64ilp32 means umode-xlen=64 and -mabi=ilp32, i.e.,
> running 32-bit Linux kernel on 64-bit supervisor mode or running 32-bit
> Linux applications on 32-bit user mode. There have been many 64ilp32
> abis existing, such as mips-n32 [1], arm-aarch64ilp32 [2], and x86-x32
> [3], but they are all about userspace. Thus, this should be the first
> time running a 32-bit Linux kernel with the 64ilp32 ABI at supervisor
> mode (If not, correct me).
>
> +--------------------------------+------------+
> | +-------------------+--------+ | +--------+ |
> | | (compat)|(compat)| | | | |
> | |u64lp64 u64ilp32|u32ilp32| | |u32ilp32| | ABI
> | | ^^^^^^^^| | | | | |
> | +-------------------+--------+ | +--------+ |
> | +-------------------+--------+ | +--------+ |
> | | UXL=64 | UXL=32 | | | UXL=32 | | ISA
> | +-------------------+--------+ | +--------+ |
> +--------------------------------+------------+-------
> | +----------------------------+ | +--------+ |
> | | 64BIT | | | 32BIT| | Kernel
> | | s64lp64 & s64ilp32 | | |s32ilp32| | ABI
> | | ^^^^^^^^ | | | | |
> | +----------------------------+ | +--------+ |
> | +----------------------------+ | +--------+ |
> | | SXL=64 | | | SXL=32 | | ISA
> | +----------------------------+ | +--------+ |
> +--------------------------------+------------+
>
> Motivation:
> ===========
> The current RISC-V has the 64-bit ISA profiles of RVA20, RVA22, and RVA23
> (ongoing) [4], but no 32-bit RVA profile exists or any ongoing plan. That
> means when a vendor wants to produce a 32-bit ISA RISC-V Application
> Processor, they have no shape to follow. Therefore, many cheap riscv
> chips have come out but follow the 64-bit RVA profiles, such as Allwinner
> D1/D1s/F133 [5], SOPHGO CV1800B [6], Canaan Kendryte k230 [7], and
> Bouffalo Lab BL808[3] which are typically cortex-a7 (arm 32-bit) product
> scenarios. So running ILP32 on rv64 ISA is the only choice for these
> chips.
>
> The ilp32 and lp64 have different scenarios, but if the address space
> and data range are under 2GB. The ilp32, compared to the lp64, has three
> advantages:
> - Better memory footprint cost.
> - Better benchmark performance (SPEC CPU 2006/2017).
> - Compatible with ilp32 code.
>
> Memory Footprint
> ================
> rv64lp64 has 25% more memory footprint than rv64ilp32!
>
> Calculation Process:
> rv64lp64 = (4096 - 3407) = 689
> rv64ilp32 = (4096 - 3231) = 865
Correct:
rv64ilp32 = (4096 - 3407) = 689
rv64lp64 = (4096 - 3231) = 865
> (865 - 689)/689 = 25.54426%
>
> Here are the ILP32 v.s. LP64 Linux kernel data type comparison:
> 32-bit 64-bit
> sizeof(page): 32bytes 64bytes
> sizeof(list_head): 8bytes 16bytes
> sizeof(hlist_head): 8bytes 16bytes
> sizeof(vm_area): 68bytes 136bytes
> ...
>
> The size of ilp32's long & pointer is just half of lp64's (rv64 default
> abi - longs and pointers are all 64-bit). This significant difference
> in data type causes different memory & cache footprint costs. Here is
> the comparison log between rv64ilp32 and rv64lp64 in the same 20MB(16MB
> for Linux) qemu system environment:
>
> rv64ilp32:
> Memory: 14008K/16384K available (1253K kernel code, 474K rwdata, 114K
> rodata, 134K init, 192K bss, 2376K reserved, 0K cma-reserved)
> Mem-Info:
> active_anon:0 inactive_anon:0 isolated_anon:0
> active_file:0 inactive_file:0 isolated_file:0
> unevictable:0 dirty:0 writeback:0
> slab_reclaimable:0 slab_unreclaimable:47
> mapped:0 shmem:0 pagetables:0
> sec_pagetables:0 bounce:0
> kernel_misc_reclaimable:0
> free:3407 free_pcp:45 free_cma:0
> ^^^^^^^^^
> Node 0 active_anon:0kB inactive_anon:0kB active_file:0kB
> inactive_file:0kB unevictable:0kB isolated(anon):0kB isolated(file):0kB
> mapped:0kB dirty:0kB writeback:0kB shmem:0kB writeback_tmp:0kB
> kernel_stack:104kB pagetables:0kB sec_pagetabl
> es:0kB all_unreclaimable? no
> Normal free:13628kB boost:0kB min:472kB low:588kB high:704kB
> reserved_highatomic:0KB active_anon:0kB inactive_anon:0kB
> active_file:0kB inactive_file:0kB unevictable:0kB writepending:0kB
> present:16384kB managed:14140kB mlocked:0kB bounce:0
> kB free_pcp:180kB local_pcp:180kB free_cma:0kB
> lowmem_reserve[]: 0 0
> Normal: 3*4kB (UM) 2*8kB (M) 2*16kB (M) 2*32kB (M) 3*64kB (M) 2*128kB
> (UM) 3*256kB (M) 4*512kB (UM) 2*1024kB (UM) 2*2048kB (UM) 1*4096kB (M) =
> 13628kB
> 0 total pagecache pages
> 4096 pages RAM
> 0 pages HighMem/MovableOnly
> 561 pages reserved
>
> rv64lp64:
> Memory: 13776K/16384K available (1234K kernel code, 539K rwdata, 129K
> rodata, 161K init, 207K bss, 2608K reserved, 0K cma-reserved)
> Mem-Info:
> active_anon:0 inactive_anon:0 isolated_anon:0
> active_file:0 inactive_file:0 isolated_file:0
> unevictable:0 dirty:0 writeback:0
> slab_reclaimable:0 slab_unreclaimable:69
> mapped:0 shmem:0 pagetables:1
> sec_pagetables:0 bounce:0
> kernel_misc_reclaimable:0
> free:3231 free_pcp:55 free_cma:0
> ^^^^^^^^^
> Node 0 active_anon:0kB inactive_anon:0kB active_file:0kB
> inactive_file:0kB unevictable:0kB isolated(anon):0kB isolated(file):0kB
> mapped:0kB dirty:0kB writeback:0kB shmem:0kB writeback_tmp:0kB
> kernel_stack:208kB pagetables:4kB sec_pagetabl
> es:0kB all_unreclaimable? no
> Normal free:12924kB boost:0kB min:468kB low:584kB high:700kB
> reserved_highatomic:0KB active_anon:0kB inactive_anon:0kB
> active_file:0kB inactive_file:0kB unevictable:0kB writepending:0kB
> present:16384kB managed:13936kB mlocked:0kB bounce:0
> kB free_pcp:220kB local_pcp:220kB free_cma:0kB
> lowmem_reserve[]: 0 0
> Normal: 3*4kB (UM) 4*8kB (UM) 3*16kB (M) 3*32kB (UM) 1*64kB (M) 3*128kB
> (UM) 2*256kB (M) 3*512kB (M) 2*1024kB (UM) 2*2048kB (UM) 1*4096kB (M) =
> 12924kB
> 0 total pagecache pages
> 4096 pages RAM
> 0 pages HighMem/MovableOnly
> 612 pages reserved
>
> Why rv64 isa?
> ==============
> Generally speaking, we should build a 32-bit hardware s-mode to run
> 32-bit Linux on a 64/32-bit processor (such as cortex-a35/a53).
> But, it can't reuse performance-related features and instructions of
> the 64-bit hardware, such as 64-bit ALU, AMO, and LD/SD, which would
> cause significant performance gaps on many Linux kernel features:
>
> - memcpy/memset/strcmp (s64ilp32 has half of the instructions count
> and double the bandwidth of load/store instructions than s32ilp32.)
>
> - ebpf JIT is a 64-bit Language virtual machine ISA, which is not
> suitable for mapping to s32ilp32.
>
> - Atomic64 (s64ilp32 has the exact native instructions mapping as
> s64lp64, but s32ilp32 only uses generic_atomic64, a tradeoff &
> limited software solution.)
>
> - Support cmxchg_double for slub (The 2nd 32-bit Linux
> supports the feature, the 1st is i386.)
>
> - ...
>
> Compared with the user space ecosystem, the 32-bit Linux kernel is more
> eager to need 64ilp32 to improve performance because the Linux kernel
> can't utilize float-point/vector features of the ISA.
>
> Simplifies CPU Design
> =====================
> Yes, there are a lot of runing 32-bit Linux on 64-bit hardware examples
> in history, such as arm cortex a35/a53/a55, which implements the 32-bit
> EL1/EL2/EL3 hardware mode to support 32-bit Linux. We could follow Arm's
> style, but riscv could choose another better way. Compared to UXL=32,
> the MXL=SXL=32 has many CSR-related hardware functionalities, which
> causes a lot of effort to mix them into 64-bit hardware. The s64ilp32
> works on MXL=SXL=64 mode, so the CPU vendors needn't implement 32-bit
> machine and supervisor modes.
>
> How does rv64ilp32 work?
> ========================
> The s64ilp32 is the same as the s64lp64 compat mode from a hardware
> view, i.e., MXL=SXL=64 + UXL=32. Because the s64ilp32 uses CONFIG_32BIT
> of Linux, it only supports u32ilp32 abi user space, the current standard
> rv32 software ecosystem, and it can't work with u64lp64 abi (I don't
> want that complex and useless stuff). But it may work with u64ilp32 in the
> future; now, the s64ilp32 depends on the UXL=32 feature of the hardware.
>
> The 64ilp32 gcc still uses sign-extend lw & auipc to generate address
> variables because inserting zero-extend instructions to mask the highest
> 32-bit would cause significant code size and performance problems. Thus,
> we invented an OS approach to solve the problem:
> - When satp=bare and start physical address < 2GB, there is no sign-extend
> address problem.
> - When satp=bare and start physical address > 2GB, we need zjpm liked
> hardware extensions to mask high 32bit.
> (Fortunately, all existed SoCs' (D1/D1s/F133, CV1800B, k230, BL808)
> start physical address < 2GB.)
> - When satp=sv39, we invent double mapping to make the sign-extended
> virtual address the same as the zero-extended virtual address.
>
> +--------+ +---------+ +--------+
> | | +--| 511:PUD1| | |
> | | | +---------+ | |
> | | | | 510:PUD0|--+ | |
> | | | +---------+ | | |
> | | | | | | | |
> | | | | | | | |
> | | | | | | | |
> | | | | INVALID | | | |
> | | | | | | | |
> | .... | | | | | | .... |
> | | | | | | | |
> | | | +---------+ | | |
> | | +--| 3:PUD1 | | | |
> | | | +---------+ | | |
> | | | | 2:PUD0 |--+ | |
> | | | +---------+ | | |
> | | | |1:USR_PUD| | | |
> | | | +---------+ | | |
> | | | |0:USR_PUD| | | |
> +--------+<--+ +---------+ +-->+--------+
> PUD1 ^ PGD PUD0
> 1GB | 4GB 1GB
> |
> +----------+
> | Sv39 PGDP|
> +----------+
> SATP
>
> The size of xlen was always equal to the pointer/long size before
> s64ilp32 emerged. So we need to introduce a new type of data - xlen_t,
> which could deal with CSR-related and callee-save/restore operations.
>
> Some kernel features use 32BIT/64BIT to determine the exact ISA, such as
> ebpf JIT would map to rv32 ISA when CONFIG_32BIT=y. But s64ilp32 needs
> the ebpf JIT map to rv64 ISA when CONFIG_32BIT=y and we need to use
> another config to distinguish the difference.
>
> More detials, please review the path series.
>
> How to run s64ilp32?
> ====================
>
> GNU toolchain
> -------------
> git clone https://github.com/Liaoshihua/riscv-gnu-toolchain.git
> cd riscv-gnu-toolchain
> ./configure --prefix="$PWD/opt-rv64-ilp32/" --with-arch=rv64imac --with-abi=ilp32
> make linux
> export PATH=$PATH:$PWD/opt-rv64-ilp32/bin/
>
> Opensbi
> -------
> git clone https://github.com/riscv-software-src/opensbi.git
> CROSS_COMPILE=riscv64-unknown-linux-gnu- make PLATFORM=generic
>
> Linux kernel
> ------------
> v6.5-rc1 + patches
> cd linux
> make ARCH=riscv CROSS_COMPILE=riscv64-unknown-linux-gnu- rv64ilp32_defconfig
> make ARCH=riscv CROSS_COMPILE=riscv64-unknown-linux-gnu- all
>
> Qemu
> ----
> git clone https://github.com/plctlab/plct-qemu.git -b plct-s64ilp32-dev
> cd plct-qemu
> mkdir build
> cd build
> ../qemu/configure --target-list="riscv64-softmmu riscv32-softmmu"
> make
>
> Patch organization
> ==================
> PATCH [ 1-11] u64ilp32: User space support
> PATCH [12-36] adds time-related vDSO common flow for vdso32
Correct:
PATCH [12-36] s64ilp32: Add 64ilp32 linux kernel support2
> PATCH [37] Add tiny defconfig for ilp32 v.s. lp64
> PATCH [38] Unify ilp32 & lp64 configs and memory
>
> Open issues
> ===========
>
> Callee saved the register width
> -------------------------------
> For 64-bit ISA (including 64lp64, 64ilp32), callee can't determine the
> correct width used in the register, so they saved the maximum width of
> the ISA register, i.e., xlen size. We also found this rule in x86-x32,
> mips-n32, and aarch64ilp32, which comes from 64lp64. See PATCH [20]
>
> Here are two downsides of this:
> - It would cause a difference with 32ilp32's stack frame, and s64ilp32
> reuses 32ilp32 software stack. Thus, many additional compatible
> problems would happen during the porting of 64ilp32 software.
> - It also increases the budget of the stack usage.
> <setup_vm>:
> auipc a3,0xff3fb
> add a3,a3,1234 # c0000000
> li a5,-1
> lui a4,0xc0000
> addw sp,sp,-96
> srl a5,a5,0x20
> subw a4,a4,a3
> auipc a2,0x111a
> add a2,a2,1212 # c1d1f000
> sd s0,80(sp)----+
> sd s1,72(sp) |
> sd s2,64(sp) |
> sd s7,24(sp) |
> sd s8,16(sp) |
> sd s9,8(sp) |-> All <= 32b widths, but occupy 64b
> sd ra,88(sp) | stack space.
> sd s3,56(sp) | Affect memory footprint & cache
> sd s4,48(sp) | performance.
> sd s5,40(sp) |
> sd s6,32(sp) |
> sd s10,0(sp)----+
> sll a1,a4,0x20
> subw a2,a2,a3
> and a4,a4,a5
>
> So here is a proposal to riscv 64ilp32 ABI:
> - Let the compiler prevent callee saving ">32b variables" in
> callee-registers. (Q: We need to measure, how the influence of
> 64b variables cross function call?)
>
> EF_RISCV_X32
> ------------
> We add an e_flag (EF_RISCV_X32) to distinguish the 32-bit ELF, which
> occupies BIT[6] of the e_flags layout.
>
> ELF Header:
> Magic: 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00
> Class: ELF32
> Data: 2's complement, little endian
> Version: 1 (current)
> OS/ABI: UNIX - System V
> ABI Version: 0
> Type: REL (Relocatable file)
> Machine: RISC-V
> Version: 0x1
> Entry point address: 0x0
> Start of program headers: 0 (bytes into file)
> Start of section headers: 24620 (bytes into file)
> Flags: 0x21, RVC, X32, soft-float ABI
> ^^^
> 64-bit Optimization problem
> ---------------------------
> There is an existing problem in 64ilp32 gcc that combines two pointers
> in one register. Liao is solving that problem. Before he finishes the
> job, we could prevent it with a simple noinline attribute, fortunately.
> struct path {
> struct vfsmount *mnt;
> struct dentry *dentry;
> } __randomize_layout;
>
> struct nameidata {
> struct path path;
> ...
> struct path root;
> ...
> } __randomize_layout;
>
> struct nameidata *nd
> ...
> nd->path = nd->root;
> 6c88 ld a0,24(s1)
> ^^ // a0 contains two pointers
> e088 sd a0,0(s1)
> mntget(path->mnt);
> // Need "lw a0,0(s1)" or "a0 << 32; a0 >> 32"
> 2a6150ef jal c01ce946 <mntget> // bug!
>
> Acknowledge
> ===========
> - GNU: LiaoShihua <shihua@iscas.ac.cn>
> Jiawe Chen<jiawei@iscas.ac.cn>
> - Qemu: Weiwei Li <liweiwei@iscas.ac.cn>
> - Benchmark: Junqiang Wang <wangjunqiang@iscas.ac.cn>
> XiaoOu Chen <chenxiaoou@iscas.ac.cn>
> - Fedora: Wei Fu <wefu@redhat.com>
> Songsong Zhang <U2FsdGVkX1@gmail.com>
>
> References
> ==========
> [1] https://techpubs.jurassic.nl/manuals/0630/developer/Mpro_...
> [2] https://wiki.debian.org/Arm64ilp32Port
> [3] https://lwn.net/Articles/456731/
> [4] https://github.com/riscv/riscv-profiles/releases
> [5] https://www.cnx-software.com/2021/10/25/allwinner-d1s-f13...
> [6] https://milkv.io/duo/
> [7] https://twitter.com/tphuang/status/1631308330256801793
> [8] https://www.cnx-software.com/2022/12/02/pine64-ox64-sbc-b...
>
> Changelog:
> V2:
> - Add u64ilp32 support
> - Rebase v6.5-rc1
> - Enable 64ilp32 vgettimeofday for benchmarking
>
> V1:
> https://lore.kernel.org/linux-riscv/20230518131013.3366406-1-guoren@kernel.org/
>
> Guo Ren (38):
> riscv: u64ilp32: Unify vdso32 & compat_vdso into vdso/Makefile
> riscv: u64ilp32: Remove compat_vdso/
> riscv: u64ilp32: Add time-related vDSO common flow for vdso32
> riscv: u64ilp32: Introduce ILP32 vdso for UXL=64
> riscv: u64ilp32: Adjust vDSO kernel flow for 64ilp32 abi
> riscv: u64ilp32: Add signal support for compat
> riscv: u64ilp32: Add ptrace interface support
> riscv: u64ilp32: Adjust vDSO alternative for 64ilp32 abi
> riscv: u64ilp32: Add xlen_t in user_regs_struct
> riscv: u64ilp32: Remove the restriction of UXL=32
> riscv: u64ilp32: Enable user space runtime switch
> riscv: s64ilp32: Unify ULL & UL into UXL in csr
> riscv: s64ilp32: Introduce xlen_t for 64ILP32 kernel
> riscv: s64ilp32: Add sbi support
> riscv: s64ilp32: Add asid support
> riscv: s64ilp32: Introduce PTR_L and PTR_S
> riscv: s64ilp32: Adjust TASK_SIZE for s64ilp32 kernel
> riscv: s64ilp32: Add ebpf jit support
> riscv: s64ilp32: Add ELF32 support
> riscv: s64ilp32: Add ARCH_RV64ILP32 Kconfig option
> riscv: s64ilp32: Add MMU_SV32 mode support
> riscv: s64ilp32: Add MMU_SV39 mode support
> riscv: s64ilp32: Enable native atomic64
> riscv: s64ilp32: Add TImode (128 int) support
> riscv: s64ilp32: Implement cmpxchg_double
> riscv: s64ilp32: Disable KVM
> riscv: s64ilp32: Correct the rv64ilp32 stackframe layout
> riscv: s64ilp32: Temporary workaround solution to gcc problem
> riscv: s64ilp32: Introduce ARCH_HAS_64ILP32_KERNEL for syscall
> riscv: s64ilp32: Add u32ilp32 ptrace support
> riscv: s64ilp32: Add u32ilp32 signal support
> riscv: s64ilp32: Validate harts by architecture name
> riscv: s64ilp32: Add rv64ilp32_defconfig
> riscv: Cleanup rv32_defconfig
> clocksource: riscv: s64ilp32: Use __riscv_xlen instead of CONFIG_32BIT
> irqchip: riscv: s64ilp32: Use __riscv_xlen instead of CONFIG_32BIT
> add tinylab defconfig
> 64ilp32 v.s. 64lp64
>
> arch/Kconfig | 10 +
> arch/riscv/Kconfig | 49 +++-
> arch/riscv/Kconfig.errata | 2 +-
> arch/riscv/Makefile | 28 ++-
> arch/riscv/configs/32-bit.config | 2 -
> arch/riscv/configs/64ilp32.config | 2 +
> arch/riscv/configs/tinylab32ilp32_defconfig | 88 +++++++
> arch/riscv/configs/tinylab64ilp32_defconfig | 89 +++++++
> arch/riscv/configs/tinylab_defconfig | 89 +++++++
> arch/riscv/include/asm/asm.h | 5 +
> arch/riscv/include/asm/atomic.h | 6 +
> arch/riscv/include/asm/cmpxchg.h | 53 ++++
> arch/riscv/include/asm/cpu_ops_sbi.h | 4 +-
> arch/riscv/include/asm/csr.h | 189 +++++++-------
> arch/riscv/include/asm/elf.h | 7 +-
> arch/riscv/include/asm/extable.h | 2 +-
> arch/riscv/include/asm/module.h | 30 +++
> arch/riscv/include/asm/page.h | 26 +-
> arch/riscv/include/asm/pgtable-64.h | 50 ++--
> arch/riscv/include/asm/pgtable.h | 26 +-
> arch/riscv/include/asm/processor.h | 8 +-
> arch/riscv/include/asm/ptrace.h | 96 ++++----
> arch/riscv/include/asm/sbi.h | 24 +-
> arch/riscv/include/asm/signal32.h | 11 +-
> arch/riscv/include/asm/stacktrace.h | 6 +
> arch/riscv/include/asm/syscall.h | 2 +-
> arch/riscv/include/asm/thread_info.h | 1 +
> arch/riscv/include/asm/timex.h | 10 +-
> arch/riscv/include/asm/tlbflush.h | 2 +-
> arch/riscv/include/asm/vdso.h | 34 ++-
> arch/riscv/include/asm/vdso/gettimeofday.h | 95 +++++++
> arch/riscv/include/uapi/asm/elf.h | 2 +-
> arch/riscv/include/uapi/asm/ptrace.h | 72 +++---
> arch/riscv/include/uapi/asm/unistd.h | 1 +
> arch/riscv/kernel/Makefile | 5 +-
> arch/riscv/kernel/alternative.c | 50 +++-
> arch/riscv/kernel/compat_signal.c | 23 +-
> arch/riscv/kernel/compat_vdso/.gitignore | 2 -
> arch/riscv/kernel/compat_vdso/compat_vdso.S | 8 -
> .../kernel/compat_vdso/compat_vdso.lds.S | 3 -
> arch/riscv/kernel/compat_vdso/flush_icache.S | 3 -
> arch/riscv/kernel/compat_vdso/getcpu.S | 3 -
> arch/riscv/kernel/compat_vdso/note.S | 3 -
> arch/riscv/kernel/compat_vdso/rt_sigreturn.S | 3 -
> arch/riscv/kernel/cpu.c | 9 +-
> arch/riscv/kernel/cpu_ops_sbi.c | 4 +-
> arch/riscv/kernel/entry.S | 24 +-
> arch/riscv/kernel/head.S | 8 +-
> arch/riscv/kernel/process.c | 10 +-
> arch/riscv/kernel/ptrace.c | 9 +-
> arch/riscv/kernel/sbi.c | 24 +-
> arch/riscv/kernel/signal.c | 79 ++++--
> arch/riscv/kernel/traps.c | 4 +-
> arch/riscv/kernel/vdso.c | 102 ++++++--
> arch/riscv/kernel/vdso/Makefile | 232 ++++++++++++++----
> ..._vdso_offsets.sh => gen_vdso32_offsets.sh} | 2 +-
> .../gen_vdso64_offsets.sh} | 2 +-
> .../kernel/vdso/gen_vdso64ilp32_offsets.sh | 5 +
> arch/riscv/kernel/vdso/vdso.lds.S | 2 -
> arch/riscv/kernel/vdso/vgettimeofday.c | 39 ++-
> arch/riscv/kernel/vdso32.S | 8 +
> arch/riscv/kernel/{vdso/vdso.S => vdso64.S} | 8 +-
> arch/riscv/kernel/vdso64ilp32.S | 8 +
> arch/riscv/kernel/vector.c | 2 +-
> arch/riscv/kvm/Kconfig | 1 +
> arch/riscv/lib/Makefile | 1 +
> arch/riscv/lib/memset.S | 4 +-
> arch/riscv/mm/context.c | 16 +-
> arch/riscv/mm/fault.c | 13 +-
> arch/riscv/mm/init.c | 24 +-
> arch/riscv/net/Makefile | 6 +-
> arch/riscv/net/bpf_jit_comp64.c | 6 +-
> drivers/clocksource/timer-riscv.c | 2 +-
> drivers/irqchip/irq-riscv-intc.c | 9 +-
> fs/namei.c | 2 +-
> fs/open.c | 22 ++
> fs/read_write.c | 17 ++
> fs/sync.c | 22 ++
> include/linux/syscalls.h | 35 ++-
> init/main.c | 2 +
> kernel/signal.c | 24 +-
> mm/fadvise.c | 24 ++
> 82 files changed, 1526 insertions(+), 509 deletions(-)
> create mode 100644 arch/riscv/configs/64ilp32.config
> create mode 100644 arch/riscv/configs/tinylab32ilp32_defconfig
> create mode 100644 arch/riscv/configs/tinylab64ilp32_defconfig
> create mode 100644 arch/riscv/configs/tinylab_defconfig
> delete mode 100644 arch/riscv/kernel/compat_vdso/.gitignore
> delete mode 100644 arch/riscv/kernel/compat_vdso/compat_vdso.S
> delete mode 100644 arch/riscv/kernel/compat_vdso/compat_vdso.lds.S
> delete mode 100644 arch/riscv/kernel/compat_vdso/flush_icache.S
> delete mode 100644 arch/riscv/kernel/compat_vdso/getcpu.S
> delete mode 100644 arch/riscv/kernel/compat_vdso/note.S
> delete mode 100644 arch/riscv/kernel/compat_vdso/rt_sigreturn.S
> rename arch/riscv/kernel/vdso/{gen_vdso_offsets.sh => gen_vdso32_offsets.sh} (78%)
> rename arch/riscv/kernel/{compat_vdso/gen_compat_vdso_offsets.sh => vdso/gen_vdso64_offsets.sh} (77%)
> create mode 100755 arch/riscv/kernel/vdso/gen_vdso64ilp32_offsets.sh
> create mode 100644 arch/riscv/kernel/vdso32.S
> rename arch/riscv/kernel/{vdso/vdso.S => vdso64.S} (73%)
> create mode 100644 arch/riscv/kernel/vdso64ilp32.S
>
> --
> 2.36.1
>
>
> _______________________________________________
> linux-riscv mailing list
> linux-riscv@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-riscv
>
^ permalink raw reply [flat|nested] 42+ messages in thread* Re: [RFC PATCH V2 00/38] rv64ilp32: Running ILP32 on RV64 ISA
2023-11-12 6:14 [RFC PATCH V2 00/38] rv64ilp32: Running ILP32 on RV64 ISA guoren
` (39 preceding siblings ...)
2023-11-13 4:22 ` Guo Ren
@ 2023-12-03 15:31 ` Guo Ren
40 siblings, 0 replies; 42+ messages in thread
From: Guo Ren @ 2023-12-03 15:31 UTC (permalink / raw)
To: guoren; +Cc: linux-arch, linux-kernel, linux-riscv
On Sun, Nov 12, 2023 at 01:14:36AM -0500, guoren@kernel.org wrote:
> From: Guo Ren <guoren@linux.alibaba.com>
>
> This patch series adds s64ilp32 & u64ilp32 support to riscv. The term
> s64ilp32 means smode-xlen=64 and -mabi=ilp32 (ints, longs, and pointers
> are all 32-bit) and u64ilp32 means umode-xlen=64 and -mabi=ilp32, i.e.,
> running 32-bit Linux kernel on 64-bit supervisor mode or running 32-bit
> Linux applications on 32-bit user mode. There have been many 64ilp32
> abis existing, such as mips-n32 [1], arm-aarch64ilp32 [2], and x86-x32
> [3], but they are all about userspace. Thus, this should be the first
> time running a 32-bit Linux kernel with the 64ilp32 ABI at supervisor
> mode (If not, correct me).
>
> +--------------------------------+------------+
> | +-------------------+--------+ | +--------+ |
> | | (compat)|(compat)| | | | |
> | |u64lp64 u64ilp32|u32ilp32| | |u32ilp32| | ABI
> | | ^^^^^^^^| | | | | |
> | +-------------------+--------+ | +--------+ |
> | +-------------------+--------+ | +--------+ |
> | | UXL=64 | UXL=32 | | | UXL=32 | | ISA
> | +-------------------+--------+ | +--------+ |
> +--------------------------------+------------+-------
> | +----------------------------+ | +--------+ |
> | | 64BIT | | | 32BIT| | Kernel
> | | s64lp64 & s64ilp32 | | |s32ilp32| | ABI
> | | ^^^^^^^^ | | | | |
> | +----------------------------+ | +--------+ |
> | +----------------------------+ | +--------+ |
> | | SXL=64 | | | SXL=32 | | ISA
> | +----------------------------+ | +--------+ |
> +--------------------------------+------------+
>
> Motivation:
> ===========
> The current RISC-V has the 64-bit ISA profiles of RVA20, RVA22, and RVA23
> (ongoing) [4], but no 32-bit RVA profile exists or any ongoing plan. That
> means when a vendor wants to produce a 32-bit ISA RISC-V Application
> Processor, they have no shape to follow. Therefore, many cheap riscv
> chips have come out but follow the 64-bit RVA profiles, such as Allwinner
> D1/D1s/F133 [5], SOPHGO CV1800B [6], Canaan Kendryte k230 [7], and
> Bouffalo Lab BL808[3] which are typically cortex-a7 (arm 32-bit) product
> scenarios. So running ILP32 on rv64 ISA is the only choice for these
> chips.
>
> The ilp32 and lp64 have different scenarios, but if the address space
> and data range are under 2GB. The ilp32, compared to the lp64, has three
> advantages:
> - Better memory footprint cost.
> - Better benchmark performance (SPEC CPU 2006/2017).
> - Compatible with ilp32 code.
>
> Memory Footprint
> ================
> rv64lp64 has 25% more memory footprint than rv64ilp32!
>
> Calculation Process:
> rv64lp64 = (4096 - 3407) = 689
> rv64ilp32 = (4096 - 3231) = 865
> (865 - 689)/689 = 25.54426%
>
> Here are the ILP32 v.s. LP64 Linux kernel data type comparison:
> 32-bit 64-bit
> sizeof(page): 32bytes 64bytes
> sizeof(list_head): 8bytes 16bytes
> sizeof(hlist_head): 8bytes 16bytes
> sizeof(vm_area): 68bytes 136bytes
> ...
>
> The size of ilp32's long & pointer is just half of lp64's (rv64 default
> abi - longs and pointers are all 64-bit). This significant difference
> in data type causes different memory & cache footprint costs. Here is
> the comparison log between rv64ilp32 and rv64lp64 in the same 20MB(16MB
> for Linux) qemu system environment:
>
> rv64ilp32:
> Memory: 14008K/16384K available (1253K kernel code, 474K rwdata, 114K
> rodata, 134K init, 192K bss, 2376K reserved, 0K cma-reserved)
> Mem-Info:
> active_anon:0 inactive_anon:0 isolated_anon:0
> active_file:0 inactive_file:0 isolated_file:0
> unevictable:0 dirty:0 writeback:0
> slab_reclaimable:0 slab_unreclaimable:47
> mapped:0 shmem:0 pagetables:0
> sec_pagetables:0 bounce:0
> kernel_misc_reclaimable:0
> free:3407 free_pcp:45 free_cma:0
> ^^^^^^^^^
> Node 0 active_anon:0kB inactive_anon:0kB active_file:0kB
> inactive_file:0kB unevictable:0kB isolated(anon):0kB isolated(file):0kB
> mapped:0kB dirty:0kB writeback:0kB shmem:0kB writeback_tmp:0kB
> kernel_stack:104kB pagetables:0kB sec_pagetabl
> es:0kB all_unreclaimable? no
> Normal free:13628kB boost:0kB min:472kB low:588kB high:704kB
> reserved_highatomic:0KB active_anon:0kB inactive_anon:0kB
> active_file:0kB inactive_file:0kB unevictable:0kB writepending:0kB
> present:16384kB managed:14140kB mlocked:0kB bounce:0
> kB free_pcp:180kB local_pcp:180kB free_cma:0kB
> lowmem_reserve[]: 0 0
> Normal: 3*4kB (UM) 2*8kB (M) 2*16kB (M) 2*32kB (M) 3*64kB (M) 2*128kB
> (UM) 3*256kB (M) 4*512kB (UM) 2*1024kB (UM) 2*2048kB (UM) 1*4096kB (M) =
> 13628kB
> 0 total pagecache pages
> 4096 pages RAM
> 0 pages HighMem/MovableOnly
> 561 pages reserved
>
> rv64lp64:
> Memory: 13776K/16384K available (1234K kernel code, 539K rwdata, 129K
> rodata, 161K init, 207K bss, 2608K reserved, 0K cma-reserved)
> Mem-Info:
> active_anon:0 inactive_anon:0 isolated_anon:0
> active_file:0 inactive_file:0 isolated_file:0
> unevictable:0 dirty:0 writeback:0
> slab_reclaimable:0 slab_unreclaimable:69
> mapped:0 shmem:0 pagetables:1
> sec_pagetables:0 bounce:0
> kernel_misc_reclaimable:0
> free:3231 free_pcp:55 free_cma:0
> ^^^^^^^^^
> Node 0 active_anon:0kB inactive_anon:0kB active_file:0kB
> inactive_file:0kB unevictable:0kB isolated(anon):0kB isolated(file):0kB
> mapped:0kB dirty:0kB writeback:0kB shmem:0kB writeback_tmp:0kB
> kernel_stack:208kB pagetables:4kB sec_pagetabl
> es:0kB all_unreclaimable? no
> Normal free:12924kB boost:0kB min:468kB low:584kB high:700kB
> reserved_highatomic:0KB active_anon:0kB inactive_anon:0kB
> active_file:0kB inactive_file:0kB unevictable:0kB writepending:0kB
> present:16384kB managed:13936kB mlocked:0kB bounce:0
> kB free_pcp:220kB local_pcp:220kB free_cma:0kB
> lowmem_reserve[]: 0 0
> Normal: 3*4kB (UM) 4*8kB (UM) 3*16kB (M) 3*32kB (UM) 1*64kB (M) 3*128kB
> (UM) 2*256kB (M) 3*512kB (M) 2*1024kB (UM) 2*2048kB (UM) 1*4096kB (M) =
> 12924kB
> 0 total pagecache pages
> 4096 pages RAM
> 0 pages HighMem/MovableOnly
> 612 pages reserved
>
> Why rv64 isa?
> ==============
> Generally speaking, we should build a 32-bit hardware s-mode to run
> 32-bit Linux on a 64/32-bit processor (such as cortex-a35/a53).
> But, it can't reuse performance-related features and instructions of
> the 64-bit hardware, such as 64-bit ALU, AMO, and LD/SD, which would
> cause significant performance gaps on many Linux kernel features:
>
> - memcpy/memset/strcmp (s64ilp32 has half of the instructions count
> and double the bandwidth of load/store instructions than s32ilp32.)
>
> - ebpf JIT is a 64-bit Language virtual machine ISA, which is not
> suitable for mapping to s32ilp32.
>
> - Atomic64 (s64ilp32 has the exact native instructions mapping as
> s64lp64, but s32ilp32 only uses generic_atomic64, a tradeoff &
> limited software solution.)
>
> - Support cmxchg_double for slub (The 2nd 32-bit Linux
> supports the feature, the 1st is i386.)
>
> - ...
>
> Compared with the user space ecosystem, the 32-bit Linux kernel is more
> eager to need 64ilp32 to improve performance because the Linux kernel
> can't utilize float-point/vector features of the ISA.
>
> Simplifies CPU Design
> =====================
> Yes, there are a lot of runing 32-bit Linux on 64-bit hardware examples
> in history, such as arm cortex a35/a53/a55, which implements the 32-bit
> EL1/EL2/EL3 hardware mode to support 32-bit Linux. We could follow Arm's
> style, but riscv could choose another better way. Compared to UXL=32,
> the MXL=SXL=32 has many CSR-related hardware functionalities, which
> causes a lot of effort to mix them into 64-bit hardware. The s64ilp32
> works on MXL=SXL=64 mode, so the CPU vendors needn't implement 32-bit
> machine and supervisor modes.
>
> How does rv64ilp32 work?
> ========================
> The s64ilp32 is the same as the s64lp64 compat mode from a hardware
> view, i.e., MXL=SXL=64 + UXL=32. Because the s64ilp32 uses CONFIG_32BIT
> of Linux, it only supports u32ilp32 abi user space, the current standard
> rv32 software ecosystem, and it can't work with u64lp64 abi (I don't
> want that complex and useless stuff). But it may work with u64ilp32 in the
> future; now, the s64ilp32 depends on the UXL=32 feature of the hardware.
>
> The 64ilp32 gcc still uses sign-extend lw & auipc to generate address
> variables because inserting zero-extend instructions to mask the highest
> 32-bit would cause significant code size and performance problems. Thus,
> we invented an OS approach to solve the problem:
> - When satp=bare and start physical address < 2GB, there is no sign-extend
> address problem.
> - When satp=bare and start physical address > 2GB, we need zjpm liked
> hardware extensions to mask high 32bit.
> (Fortunately, all existed SoCs' (D1/D1s/F133, CV1800B, k230, BL808)
> start physical address < 2GB.)
> - When satp=sv39, we invent double mapping to make the sign-extended
> virtual address the same as the zero-extended virtual address.
Update diagram:
+--------+ +---------+ +--------+ +--------+
| | +--| PMDP511 | | | | |
| | | +---------+ | | | |
| | | | PMDP510 |--+ | | | |
| | | +---------+ | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
| | | | INVALID | | | | | |
| | | | | | | | | |
| .... | | | | | | .... | | .... |
| | | | | | | | | |
| | | +---------+ | | | | |
| | +--| PMDP3 | | | | | |
| | | +---------+ | | | | |
| | | | PMDP2 |--+ | | | |
| | | +---------+ | | | | |
| | | | PMDP1 | | | | | |
| | | +---------+ | +--------+ +--------+
| | | | PMDP0 | | | PTP0 |--+ | PTE0 |-->4KB
+--------+<--+ +---------+ +-->+--------+ +-->+--------+
PMD3 ^ PGD PMD2 PT0
1GB | 4GB 1GB 2MB
+---------+
| PGDP |
+---------+
SATP (Sv39)
> The size of xlen was always equal to the pointer/long size before
> s64ilp32 emerged. So we need to introduce a new type of data - xlen_t,
> which could deal with CSR-related and callee-save/restore operations.
>
> Some kernel features use 32BIT/64BIT to determine the exact ISA, such as
> ebpf JIT would map to rv32 ISA when CONFIG_32BIT=y. But s64ilp32 needs
> the ebpf JIT map to rv64 ISA when CONFIG_32BIT=y and we need to use
> another config to distinguish the difference.
>
> More detials, please review the path series.
>
> How to run s64ilp32?
> ====================
>
> GNU toolchain
> -------------
> git clone https://github.com/Liaoshihua/riscv-gnu-toolchain.git
> cd riscv-gnu-toolchain
> ./configure --prefix="$PWD/opt-rv64-ilp32/" --with-arch=rv64imac --with-abi=ilp32
> make linux
> export PATH=$PATH:$PWD/opt-rv64-ilp32/bin/
>
> Opensbi
> -------
> git clone https://github.com/riscv-software-src/opensbi.git
> CROSS_COMPILE=riscv64-unknown-linux-gnu- make PLATFORM=generic
>
> Linux kernel
> ------------
> v6.5-rc1 + patches
> cd linux
> make ARCH=riscv CROSS_COMPILE=riscv64-unknown-linux-gnu- rv64ilp32_defconfig
> make ARCH=riscv CROSS_COMPILE=riscv64-unknown-linux-gnu- all
>
> Qemu
> ----
> git clone https://github.com/plctlab/plct-qemu.git -b plct-s64ilp32-dev
> cd plct-qemu
> mkdir build
> cd build
> ../qemu/configure --target-list="riscv64-softmmu riscv32-softmmu"
> make
>
> Patch organization
> ==================
> PATCH [ 1-11] u64ilp32: User space support
> PATCH [12-36] adds time-related vDSO common flow for vdso32
> PATCH [37] Add tiny defconfig for ilp32 v.s. lp64
> PATCH [38] Unify ilp32 & lp64 configs and memory
>
> Open issues
> ===========
>
> Callee saved the register width
> -------------------------------
> For 64-bit ISA (including 64lp64, 64ilp32), callee can't determine the
> correct width used in the register, so they saved the maximum width of
> the ISA register, i.e., xlen size. We also found this rule in x86-x32,
> mips-n32, and aarch64ilp32, which comes from 64lp64. See PATCH [20]
>
> Here are two downsides of this:
> - It would cause a difference with 32ilp32's stack frame, and s64ilp32
> reuses 32ilp32 software stack. Thus, many additional compatible
> problems would happen during the porting of 64ilp32 software.
> - It also increases the budget of the stack usage.
> <setup_vm>:
> auipc a3,0xff3fb
> add a3,a3,1234 # c0000000
> li a5,-1
> lui a4,0xc0000
> addw sp,sp,-96
> srl a5,a5,0x20
> subw a4,a4,a3
> auipc a2,0x111a
> add a2,a2,1212 # c1d1f000
> sd s0,80(sp)----+
> sd s1,72(sp) |
> sd s2,64(sp) |
> sd s7,24(sp) |
> sd s8,16(sp) |
> sd s9,8(sp) |-> All <= 32b widths, but occupy 64b
> sd ra,88(sp) | stack space.
> sd s3,56(sp) | Affect memory footprint & cache
> sd s4,48(sp) | performance.
> sd s5,40(sp) |
> sd s6,32(sp) |
> sd s10,0(sp)----+
> sll a1,a4,0x20
> subw a2,a2,a3
> and a4,a4,a5
>
> So here is a proposal to riscv 64ilp32 ABI:
> - Let the compiler prevent callee saving ">32b variables" in
> callee-registers. (Q: We need to measure, how the influence of
> 64b variables cross function call?)
>
> EF_RISCV_X32
> ------------
> We add an e_flag (EF_RISCV_X32) to distinguish the 32-bit ELF, which
> occupies BIT[6] of the e_flags layout.
>
> ELF Header:
> Magic: 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00
> Class: ELF32
> Data: 2's complement, little endian
> Version: 1 (current)
> OS/ABI: UNIX - System V
> ABI Version: 0
> Type: REL (Relocatable file)
> Machine: RISC-V
> Version: 0x1
> Entry point address: 0x0
> Start of program headers: 0 (bytes into file)
> Start of section headers: 24620 (bytes into file)
> Flags: 0x21, RVC, X32, soft-float ABI
> ^^^
> 64-bit Optimization problem
> ---------------------------
> There is an existing problem in 64ilp32 gcc that combines two pointers
> in one register. Liao is solving that problem. Before he finishes the
> job, we could prevent it with a simple noinline attribute, fortunately.
> struct path {
> struct vfsmount *mnt;
> struct dentry *dentry;
> } __randomize_layout;
>
> struct nameidata {
> struct path path;
> ...
> struct path root;
> ...
> } __randomize_layout;
>
> struct nameidata *nd
> ...
> nd->path = nd->root;
> 6c88 ld a0,24(s1)
> ^^ // a0 contains two pointers
> e088 sd a0,0(s1)
> mntget(path->mnt);
> // Need "lw a0,0(s1)" or "a0 << 32; a0 >> 32"
> 2a6150ef jal c01ce946 <mntget> // bug!
>
> Acknowledge
> ===========
> - GNU: LiaoShihua <shihua@iscas.ac.cn>
> Jiawe Chen<jiawei@iscas.ac.cn>
> - Qemu: Weiwei Li <liweiwei@iscas.ac.cn>
> - Benchmark: Junqiang Wang <wangjunqiang@iscas.ac.cn>
> XiaoOu Chen <chenxiaoou@iscas.ac.cn>
> - Fedora: Wei Fu <wefu@redhat.com>
> Songsong Zhang <U2FsdGVkX1@gmail.com>
>
> References
> ==========
> [1] https://techpubs.jurassic.nl/manuals/0630/developer/Mpro_...
> [2] https://wiki.debian.org/Arm64ilp32Port
> [3] https://lwn.net/Articles/456731/
> [4] https://github.com/riscv/riscv-profiles/releases
> [5] https://www.cnx-software.com/2021/10/25/allwinner-d1s-f13...
> [6] https://milkv.io/duo/
> [7] https://twitter.com/tphuang/status/1631308330256801793
> [8] https://www.cnx-software.com/2022/12/02/pine64-ox64-sbc-b...
>
> Changelog:
> V2:
> - Add u64ilp32 support
> - Rebase v6.5-rc1
> - Enable 64ilp32 vgettimeofday for benchmarking
>
> V1:
> https://lore.kernel.org/linux-riscv/20230518131013.3366406-1-guoren@kernel.org/
>
> Guo Ren (38):
> riscv: u64ilp32: Unify vdso32 & compat_vdso into vdso/Makefile
> riscv: u64ilp32: Remove compat_vdso/
> riscv: u64ilp32: Add time-related vDSO common flow for vdso32
> riscv: u64ilp32: Introduce ILP32 vdso for UXL=64
> riscv: u64ilp32: Adjust vDSO kernel flow for 64ilp32 abi
> riscv: u64ilp32: Add signal support for compat
> riscv: u64ilp32: Add ptrace interface support
> riscv: u64ilp32: Adjust vDSO alternative for 64ilp32 abi
> riscv: u64ilp32: Add xlen_t in user_regs_struct
> riscv: u64ilp32: Remove the restriction of UXL=32
> riscv: u64ilp32: Enable user space runtime switch
> riscv: s64ilp32: Unify ULL & UL into UXL in csr
> riscv: s64ilp32: Introduce xlen_t for 64ILP32 kernel
> riscv: s64ilp32: Add sbi support
> riscv: s64ilp32: Add asid support
> riscv: s64ilp32: Introduce PTR_L and PTR_S
> riscv: s64ilp32: Adjust TASK_SIZE for s64ilp32 kernel
> riscv: s64ilp32: Add ebpf jit support
> riscv: s64ilp32: Add ELF32 support
> riscv: s64ilp32: Add ARCH_RV64ILP32 Kconfig option
> riscv: s64ilp32: Add MMU_SV32 mode support
> riscv: s64ilp32: Add MMU_SV39 mode support
> riscv: s64ilp32: Enable native atomic64
> riscv: s64ilp32: Add TImode (128 int) support
> riscv: s64ilp32: Implement cmpxchg_double
> riscv: s64ilp32: Disable KVM
> riscv: s64ilp32: Correct the rv64ilp32 stackframe layout
> riscv: s64ilp32: Temporary workaround solution to gcc problem
> riscv: s64ilp32: Introduce ARCH_HAS_64ILP32_KERNEL for syscall
> riscv: s64ilp32: Add u32ilp32 ptrace support
> riscv: s64ilp32: Add u32ilp32 signal support
> riscv: s64ilp32: Validate harts by architecture name
> riscv: s64ilp32: Add rv64ilp32_defconfig
> riscv: Cleanup rv32_defconfig
> clocksource: riscv: s64ilp32: Use __riscv_xlen instead of CONFIG_32BIT
> irqchip: riscv: s64ilp32: Use __riscv_xlen instead of CONFIG_32BIT
> add tinylab defconfig
> 64ilp32 v.s. 64lp64
>
> arch/Kconfig | 10 +
> arch/riscv/Kconfig | 49 +++-
> arch/riscv/Kconfig.errata | 2 +-
> arch/riscv/Makefile | 28 ++-
> arch/riscv/configs/32-bit.config | 2 -
> arch/riscv/configs/64ilp32.config | 2 +
> arch/riscv/configs/tinylab32ilp32_defconfig | 88 +++++++
> arch/riscv/configs/tinylab64ilp32_defconfig | 89 +++++++
> arch/riscv/configs/tinylab_defconfig | 89 +++++++
> arch/riscv/include/asm/asm.h | 5 +
> arch/riscv/include/asm/atomic.h | 6 +
> arch/riscv/include/asm/cmpxchg.h | 53 ++++
> arch/riscv/include/asm/cpu_ops_sbi.h | 4 +-
> arch/riscv/include/asm/csr.h | 189 +++++++-------
> arch/riscv/include/asm/elf.h | 7 +-
> arch/riscv/include/asm/extable.h | 2 +-
> arch/riscv/include/asm/module.h | 30 +++
> arch/riscv/include/asm/page.h | 26 +-
> arch/riscv/include/asm/pgtable-64.h | 50 ++--
> arch/riscv/include/asm/pgtable.h | 26 +-
> arch/riscv/include/asm/processor.h | 8 +-
> arch/riscv/include/asm/ptrace.h | 96 ++++----
> arch/riscv/include/asm/sbi.h | 24 +-
> arch/riscv/include/asm/signal32.h | 11 +-
> arch/riscv/include/asm/stacktrace.h | 6 +
> arch/riscv/include/asm/syscall.h | 2 +-
> arch/riscv/include/asm/thread_info.h | 1 +
> arch/riscv/include/asm/timex.h | 10 +-
> arch/riscv/include/asm/tlbflush.h | 2 +-
> arch/riscv/include/asm/vdso.h | 34 ++-
> arch/riscv/include/asm/vdso/gettimeofday.h | 95 +++++++
> arch/riscv/include/uapi/asm/elf.h | 2 +-
> arch/riscv/include/uapi/asm/ptrace.h | 72 +++---
> arch/riscv/include/uapi/asm/unistd.h | 1 +
> arch/riscv/kernel/Makefile | 5 +-
> arch/riscv/kernel/alternative.c | 50 +++-
> arch/riscv/kernel/compat_signal.c | 23 +-
> arch/riscv/kernel/compat_vdso/.gitignore | 2 -
> arch/riscv/kernel/compat_vdso/compat_vdso.S | 8 -
> .../kernel/compat_vdso/compat_vdso.lds.S | 3 -
> arch/riscv/kernel/compat_vdso/flush_icache.S | 3 -
> arch/riscv/kernel/compat_vdso/getcpu.S | 3 -
> arch/riscv/kernel/compat_vdso/note.S | 3 -
> arch/riscv/kernel/compat_vdso/rt_sigreturn.S | 3 -
> arch/riscv/kernel/cpu.c | 9 +-
> arch/riscv/kernel/cpu_ops_sbi.c | 4 +-
> arch/riscv/kernel/entry.S | 24 +-
> arch/riscv/kernel/head.S | 8 +-
> arch/riscv/kernel/process.c | 10 +-
> arch/riscv/kernel/ptrace.c | 9 +-
> arch/riscv/kernel/sbi.c | 24 +-
> arch/riscv/kernel/signal.c | 79 ++++--
> arch/riscv/kernel/traps.c | 4 +-
> arch/riscv/kernel/vdso.c | 102 ++++++--
> arch/riscv/kernel/vdso/Makefile | 232 ++++++++++++++----
> ..._vdso_offsets.sh => gen_vdso32_offsets.sh} | 2 +-
> .../gen_vdso64_offsets.sh} | 2 +-
> .../kernel/vdso/gen_vdso64ilp32_offsets.sh | 5 +
> arch/riscv/kernel/vdso/vdso.lds.S | 2 -
> arch/riscv/kernel/vdso/vgettimeofday.c | 39 ++-
> arch/riscv/kernel/vdso32.S | 8 +
> arch/riscv/kernel/{vdso/vdso.S => vdso64.S} | 8 +-
> arch/riscv/kernel/vdso64ilp32.S | 8 +
> arch/riscv/kernel/vector.c | 2 +-
> arch/riscv/kvm/Kconfig | 1 +
> arch/riscv/lib/Makefile | 1 +
> arch/riscv/lib/memset.S | 4 +-
> arch/riscv/mm/context.c | 16 +-
> arch/riscv/mm/fault.c | 13 +-
> arch/riscv/mm/init.c | 24 +-
> arch/riscv/net/Makefile | 6 +-
> arch/riscv/net/bpf_jit_comp64.c | 6 +-
> drivers/clocksource/timer-riscv.c | 2 +-
> drivers/irqchip/irq-riscv-intc.c | 9 +-
> fs/namei.c | 2 +-
> fs/open.c | 22 ++
> fs/read_write.c | 17 ++
> fs/sync.c | 22 ++
> include/linux/syscalls.h | 35 ++-
> init/main.c | 2 +
> kernel/signal.c | 24 +-
> mm/fadvise.c | 24 ++
> 82 files changed, 1526 insertions(+), 509 deletions(-)
> create mode 100644 arch/riscv/configs/64ilp32.config
> create mode 100644 arch/riscv/configs/tinylab32ilp32_defconfig
> create mode 100644 arch/riscv/configs/tinylab64ilp32_defconfig
> create mode 100644 arch/riscv/configs/tinylab_defconfig
> delete mode 100644 arch/riscv/kernel/compat_vdso/.gitignore
> delete mode 100644 arch/riscv/kernel/compat_vdso/compat_vdso.S
> delete mode 100644 arch/riscv/kernel/compat_vdso/compat_vdso.lds.S
> delete mode 100644 arch/riscv/kernel/compat_vdso/flush_icache.S
> delete mode 100644 arch/riscv/kernel/compat_vdso/getcpu.S
> delete mode 100644 arch/riscv/kernel/compat_vdso/note.S
> delete mode 100644 arch/riscv/kernel/compat_vdso/rt_sigreturn.S
> rename arch/riscv/kernel/vdso/{gen_vdso_offsets.sh => gen_vdso32_offsets.sh} (78%)
> rename arch/riscv/kernel/{compat_vdso/gen_compat_vdso_offsets.sh => vdso/gen_vdso64_offsets.sh} (77%)
> create mode 100755 arch/riscv/kernel/vdso/gen_vdso64ilp32_offsets.sh
> create mode 100644 arch/riscv/kernel/vdso32.S
> rename arch/riscv/kernel/{vdso/vdso.S => vdso64.S} (73%)
> create mode 100644 arch/riscv/kernel/vdso64ilp32.S
>
> --
> 2.36.1
>
>
> _______________________________________________
> linux-riscv mailing list
> linux-riscv@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-riscv
>
^ permalink raw reply [flat|nested] 42+ messages in thread