[PATCH V2 00/17] riscv: compat: Add COMPAT mode support for rv64
STALE1668d
Revision v2 of 7 in this series.
26 messages,
4 authors,
2022-01-11 · open the first message on its own page
From: Guo Ren <redacted>
Currently, most 64-bit architectures (x86, parisc, powerpc, arm64,
s390, mips, sparc) have supported COMPAT mode. But they all have
history issues and can't use standard linux unistd.h. RISC-V would
be first standard __SYSCALL_COMPAT user of include/uapi/asm-generic
/unistd.h.
The patchset are based on v5.16-rc6, you can compare rv64-compat32
v.s. rv32-whole in qemu with following step:
- Prepare rv32 rootfs & fw_jump.bin by buildroot.org
$ git clone git://git.busybox.net/buildroot
$ cd buildroot
$ make qemu_riscv32_virt_defconfig O=qemu_riscv32_virt_defconfig
$ make -C qemu_riscv32_virt_defconfig
$ make qemu_riscv64_virt_defconfig O=qemu_riscv64_virt_defconfig
$ make -C qemu_riscv64_virt_defconfig
(Got fw_jump.bin & rootfs.ext2 in qemu_riscvXX_virt_defconfig/images)
- Prepare Linux rv32 & rv64 Image
$ git clone git@github.com:c-sky/csky-linux.git -b riscv_compat_v2 linux
$ cd linux
$ echo "CONFIG_STRICT_KERNEL_RWX=n" >> arch/riscv/configs/defconfig
$ echo "CONFIG_STRICT_MODULE_RWX=n" >> arch/riscv/configs/defconfig
$ make ARCH=riscv CROSS_COMPILE=riscv32-buildroot-linux-gnu- O=../build-rv32/ rv32_defconfig
$ make ARCH=riscv CROSS_COMPILE=riscv32-buildroot-linux-gnu- O=../build-rv32/ Image
$ make ARCH=riscv CROSS_COMPILE=riscv64-buildroot-linux-gnu- O=../build-rv64/ defconfig
$ make ARCH=riscv CROSS_COMPILE=riscv64-buildroot-linux-gnu- O=../build-rv64/ Image
- Prepare Qemu: (made by LIU Zhiwei [off-list ref])
$ git clone https://github.com/romanheros/qemu.git -b riscv-upstream-uxl-v5
$ cd qemu
$ ./configure --target-list="riscv64-softmmu riscv32-softmmu"
$ make
- Run rv64 with rv32 rootfs in compat mode:
$ ./build/qemu-system-riscv64 -cpu rv64,x-h=true -M virt -m 64m -nographic -bios qemu_riscv64_virt_defconfig/images/fw_jump.bin -kernel build-rv64/Image -drive file qemu_riscv32_virt_defconfig/images/rootfs.ext2,format=raw,id=hd0 -device virtio-blk-device,drive=hd0 -append "rootwait root=/dev/vda ro console=ttyS0 earlycon=sbi" -netdev user,id=net0 -device virtio-net-device,netdev=net0
QEMU emulator version 6.2.50 (v6.2.0-29-g196d7182c8)
OpenSBI v0.9
[ 0.000000] Linux version 5.16.0-rc6-00017-g750f87086bdd-dirty (guoren@guoren-Z87-HD3) (riscv64-unknown-linux-gnu-gcc (GCC) 10.2.0, GNU ld (GNU Binutils) 2.37) #96 SMP Tue Dec 28 21:01:55 CST 2021
[ 0.000000] OF: fdt: Ignoring memory range 0x80000000 - 0x80200000
[ 0.000000] Machine model: riscv-virtio,qemu
[ 0.000000] earlycon: sbi0 at I/O port 0x0 (options '')
[ 0.000000] printk: bootconsole [sbi0] enabled
[ 0.000000] efi: UEFI not found.
[ 0.000000] Zone ranges:
[ 0.000000] DMA32 [mem 0x0000000080200000-0x0000000083ffffff]
[ 0.000000] Normal empty
[ 0.000000] Movable zone start for each node
[ 0.000000] Early memory node ranges
[ 0.000000] node 0: [mem 0x0000000080200000-0x0000000083ffffff]
[ 0.000000] Initmem setup node 0 [mem 0x0000000080200000-0x0000000083ffffff]
[ 0.000000] SBI specification v0.2 detected
[ 0.000000] SBI implementation ID=0x1 Version=0x9
[ 0.000000] SBI TIME extension detected
[ 0.000000] SBI IPI extension detected
[ 0.000000] SBI RFENCE extension detected
[ 0.000000] SBI v0.2 HSM extension detected
[ 0.000000] riscv: ISA extensions acdfhimsu
[ 0.000000] riscv: ELF capabilities acdfim
[ 0.000000] percpu: Embedded 17 pages/cpu s30696 r8192 d30744 u69632
[ 0.000000] Built 1 zonelists, mobility grouping on. Total pages: 15655
[ 0.000000] Kernel command line: rootwait root=/dev/vda ro console=ttyS0 earlycon=sbi
[ 0.000000] Dentry cache hash table entries: 8192 (order: 4, 65536 bytes, linear)
[ 0.000000] Inode-cache hash table entries: 4096 (order: 3, 32768 bytes, linear)
[ 0.000000] mem auto-init: stack:off, heap alloc:off, heap free:off
[ 0.000000] Virtual kernel memory layout:
[ 0.000000] fixmap : 0xffffffcefee00000 - 0xffffffceff000000 (2048 kB)
[ 0.000000] pci io : 0xffffffceff000000 - 0xffffffcf00000000 ( 16 MB)
[ 0.000000] vmemmap : 0xffffffcf00000000 - 0xffffffcfffffffff (4095 MB)
[ 0.000000] vmalloc : 0xffffffd000000000 - 0xffffffdfffffffff (65535 MB)
[ 0.000000] lowmem : 0xffffffe000000000 - 0xffffffe003e00000 ( 62 MB)
[ 0.000000] kernel : 0xffffffff80000000 - 0xffffffffffffffff (2047 MB)
[ 0.000000] Memory: 52788K/63488K available (6184K kernel code, 888K rwdata, 1917K rodata, 294K init, 297K bss, 10700K reserved, 0K cma-reserved)
[ 0.000000] SLUB: HWalign=64, Order=0-3, MinObjects=0, CPUs=1, Nodes=1
[ 0.000000] rcu: Hierarchical RCU implementation.
[ 0.000000] rcu: RCU restricting CPUs from NR_CPUS=8 to nr_cpu_ids=1.
[ 0.000000] rcu: RCU debug extended QS entry/exit.
[ 0.000000] Tracing variant of Tasks RCU enabled.
[ 0.000000] rcu: RCU calculated value of scheduler-enlistment delay is 25 jiffies.
[ 0.000000] rcu: Adjusting geometry for rcu_fanout_leaf=16, nr_cpu_ids=1
[ 0.000000] NR_IRQS: 64, nr_irqs: 64, preallocated irqs: 0
[ 0.000000] riscv-intc: 64 local interrupts mapped
[ 0.000000] plic: plic@c000000: mapped 53 interrupts with 1 handlers for 2 contexts.
...
Welcome to Buildroot
buildroot login: root
# cat /proc/cpuinfo
processor : 0
hart : 0
isa : rv64imafdcsuh
mmu : sv48
# file /bin/busybox
/bin/busybox: setuid ELF 32-bit LSB shared object, UCB RISC-V, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-riscv32-ilp32d.so.1, for GNU/Linux 5.15.0, stripped
# ca[ 78.386630] random: fast init done
# cat /proc/meminfo
MemTotal: 53076 kB
MemFree: 40264 kB
MemAvailable: 40244 kB
Buffers: 236 kB
Cached: 1560 kB
SwapCached: 0 kB
Active: 1700 kB
Inactive: 516 kB
Active(anon): 40 kB
Inactive(anon): 424 kB
Active(file): 1660 kB
Inactive(file): 92 kB
Unevictable: 0 kB
Mlocked: 0 kB
SwapTotal: 0 kB
SwapFree: 0 kB
Dirty: 0 kB
Writeback: 0 kB
AnonPages: 444 kB
Mapped: 1188 kB
Shmem: 44 kB
KReclaimable: 952 kB
Slab: 5744 kB
SReclaimable: 952 kB
SUnreclaim: 4792 kB
KernelStack: 624 kB
PageTables: 156 kB
NFS_Unstable: 0 kB
Bounce: 0 kB
WritebackTmp: 0 kB
CommitLimit: 26536 kB
Committed_AS: 1748 kB
VmallocTotal: 67108863 kB
VmallocUsed: 652 kB
VmallocChunk: 0 kB
Percpu: 80 kB
#
- Run rv32 with rv32 rootfs:
$ ./build/qemu-system-riscv32 -cpu rv32,x-h=true -M virt -m 64m -nographic -bios qemu_riscv32_virt_defconfig/images/fw_jump.bin -kernel build-rv32/Image -drive file qemu_riscv32_virt_defconfig/images/rootfs.ext2,format=raw,id=hd0 -device virtio-blk-device,drive=hd0 -append "rootwait root=/dev/vda ro console=ttyS0 earlycon=sbi" -netdev user,id=net0 -device virtio-net-device,netdev=net0
QEMU emulator version 6.2.50 (v6.2.0-29-g196d7182c8)
OpenSBI v0.9
[ 0.000000] Linux version 5.16.0-rc6-00017-g750f87086bdd-dirty (guoren@guoren-Z87-HD3) (riscv32-buildroot-linux-gnu-gcc.br_real (Buildroot 2021.11-201-g7600ca7960-dirty) 10.3.0, GNU ld (GNU Binutils) 2.36.1) #7 SMP Tue Dec 28 21:02:21 CST 2021
[ 0.000000] OF: fdt: Ignoring memory range 0x80000000 - 0x80400000
[ 0.000000] Machine model: riscv-virtio,qemu
[ 0.000000] earlycon: sbi0 at I/O port 0x0 (options '')
[ 0.000000] printk: bootconsole [sbi0] enabled
[ 0.000000] efi: UEFI not found.
[ 0.000000] Zone ranges:
[ 0.000000] Normal [mem 0x0000000080400000-0x0000000083ffffff]
[ 0.000000] Movable zone start for each node
[ 0.000000] Early memory node ranges
[ 0.000000] node 0: [mem 0x0000000080400000-0x0000000083ffffff]
[ 0.000000] Initmem setup node 0 [mem 0x0000000080400000-0x0000000083ffffff]
[ 0.000000] SBI specification v0.2 detected
[ 0.000000] SBI implementation ID=0x1 Version=0x9
[ 0.000000] SBI TIME extension detected
[ 0.000000] SBI IPI extension detected
[ 0.000000] SBI RFENCE extension detected
[ 0.000000] SBI v0.2 HSM extension detected
[ 0.000000] riscv: ISA extensions acdfhimsu
[ 0.000000] riscv: ELF capabilities acdfim
[ 0.000000] percpu: Embedded 12 pages/cpu s16600 r8192 d24360 u49152
[ 0.000000] Built 1 zonelists, mobility grouping on. Total pages: 15240
[ 0.000000] Kernel command line: rootwait root=/dev/vda ro console=ttyS0 earlycon=sbi
[ 0.000000] Dentry cache hash table entries: 8192 (order: 3, 32768 bytes, linear)
[ 0.000000] Inode-cache hash table entries: 4096 (order: 2, 16384 bytes, linear)
[ 0.000000] mem auto-init: stack:off, heap alloc:off, heap free:off
[ 0.000000] Virtual kernel memory layout:
[ 0.000000] fixmap : 0x9dc00000 - 0x9e000000 (4096 kB)
[ 0.000000] pci io : 0x9e000000 - 0x9f000000 ( 16 MB)
[ 0.000000] vmemmap : 0x9f000000 - 0x9fffffff ( 15 MB)
[ 0.000000] vmalloc : 0xa0000000 - 0xbfffffff ( 511 MB)
[ 0.000000] lowmem : 0xc0000000 - 0xc3c00000 ( 60 MB)
[ 0.000000] Memory: 51924K/61440K available (6117K kernel code, 695K rwdata, 1594K rodata, 255K init, 241K bss, 9516K reserved, 0K cma-reserved)
[ 0.000000] SLUB: HWalign=64, Order=0-3, MinObjects=0, CPUs=1, Nodes=1
[ 0.000000] rcu: Hierarchical RCU implementation.
[ 0.000000] rcu: RCU restricting CPUs from NR_CPUS=8 to nr_cpu_ids=1.
[ 0.000000] rcu: RCU debug extended QS entry/exit.
[ 0.000000] Tracing variant of Tasks RCU enabled.
[ 0.000000] rcu: RCU calculated value of scheduler-enlistment delay is 25 jiffies.
[ 0.000000] rcu: Adjusting geometry for rcu_fanout_leaf=16, nr_cpu_ids=1
[ 0.000000] NR_IRQS: 64, nr_irqs: 64, preallocated irqs: 0
[ 0.000000] riscv-intc: 32 local interrupts mapped
[ 0.000000] plic: plic@c000000: mapped 53 interrupts with 1 handlers for 2 contexts.
...
Welcome to Buildroot
buildroot login: root
# cat /proc/cpuinfo
processor : 0
hart : 0
isa : rv32imafdcsuh
mmu : sv32
# file /bin/busybox
/bin/busybox: setuid ELF 32-bit LSB shared object, UCB RISC-V, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-riscv32-ilp32d.so.1, for GNU/Linux 5.15.0, stripped
[ 79.320589] random: fast init done
# cat /proc/meminfo
MemTotal: 52176 kB
MemFree: 41012 kB
MemAvailable: 42176 kB
Buffers: 644 kB
Cached: 2724 kB
SwapCached: 0 kB
Active: 3128 kB
Inactive: 752 kB
Active(anon): 40 kB
Inactive(anon): 516 kB
Active(file): 3088 kB
Inactive(file): 236 kB
Unevictable: 0 kB
Mlocked: 0 kB
SwapTotal: 0 kB
SwapFree: 0 kB
Dirty: 4 kB
Writeback: 0 kB
AnonPages: 556 kB
Mapped: 2172 kB
Shmem: 44 kB
KReclaimable: 656 kB
Slab: 3684 kB
SReclaimable: 656 kB
SUnreclaim: 3028 kB
KernelStack: 312 kB
PageTables: 88 kB
NFS_Unstable: 0 kB
Bounce: 0 kB
WritebackTmp: 0 kB
CommitLimit: 26088 kB
Committed_AS: 2088 kB
VmallocTotal: 524287 kB
VmallocUsed: 12 kB
VmallocChunk: 0 kB
Percpu: 60 kB
#
Some conclusions:
- kernel statics:
64: Memory: 52788K/63488K available (6184K kernel code, 888K rwdata, 1917K rodata, 294K init, 297K bss, 10700K reserved)
32: Memory: 51924K/61440K available (6117K kernel code, 695K rwdata, 1594K rodata, 255K init, 241K bss, 9516K reserved)
rv32 better than rv64: 1% 22% 17% 13% 19% 11%
The code size is very similar, but data size rv32 would be better.
- rv32 kernel runtime KernelStack, Slab... are smaller,
rv64: MemTotal: 53076 kB, MemFree: 40264 kB
rv32: MemTotal: 52176 + 2048 kB, MemFree: 41012 + 2048 kB
rv32 better than rv64: 2% 6%
(Because opensbi problem, we could add another 2MB for rv32.)
Overall, rv64-compat is 6% worse than rv32-full at memory footprint.
If the user space memory usage increases, the gap will be further
reduced.
- Qemu, kernel, rv32 = rv64 defconfig, rootfs, opensbi
are the same in this comparison.
Changes in v2:
- Add __ARCH_WANT_COMPAT_STAT suggested
- Cleanup fcntl compatduplicate definitions
- Cleanup compat.h
- Move rv32_defconfig into Makefile
- Fixup rv64 rootfs boot failed, remove hw_compat_mode_detect
- Move SYSVIPC_COMPAT into init/Kconfig
- Simplify compat_elf_check
Guo Ren (17):
kconfig: Add SYSVIPC_COMPAT for all architectures
fs: stat: compat: Add __ARCH_WANT_COMPAT_STAT
asm-generic: fcntl: compat: Remove duplicate definitions
asm-generic: compat: Cleanup duplicate definitions
syscalls: compat: Fix the missing part for __SYSCALL_COMPAT
riscv: Fixup difference with defconfig
riscv: compat: Add basic compat date type implementation
riscv: compat: Re-implement TASK_SIZE for COMPAT_32BIT
riscv: compat: syscall: Add compat_sys_call_table implementation
riscv: compat: syscall: Add entry.S implementation
riscv: compat: Add elf.h implementation
riscv: compat: vdso: Add rv32 VDSO base code implementation
riscv: compat: vdso: Add setup additional pages implementation
riscv: compat: signal: Add rt_frame implementation
riscv: compat: ptrace: Add compat_arch_ptrace implement
riscv: compat: Add UXL_32 support in start_thread
riscv: compat: Add COMPAT Kbuild skeletal support
arch/arm64/Kconfig | 4 -
arch/arm64/include/asm/compat.h | 112 +-------
arch/arm64/include/asm/unistd.h | 1 +
arch/mips/Kconfig | 5 -
arch/mips/include/asm/compat.h | 24 +-
arch/mips/include/asm/unistd.h | 2 +
arch/parisc/Kconfig | 4 -
arch/parisc/include/asm/compat.h | 47 +---
arch/parisc/include/asm/unistd.h | 1 +
arch/powerpc/Kconfig | 5 -
arch/powerpc/include/asm/compat.h | 51 +---
arch/powerpc/include/asm/unistd.h | 1 +
arch/riscv/Kconfig | 19 ++
arch/riscv/Makefile | 9 +
arch/riscv/configs/rv32_defconfig | 135 ----------
arch/riscv/include/asm/compat.h | 132 ++++++++++
arch/riscv/include/asm/csr.h | 7 +
arch/riscv/include/asm/elf.h | 54 +++-
arch/riscv/include/asm/mmu.h | 1 +
arch/riscv/include/asm/pgtable.h | 11 +-
arch/riscv/include/asm/processor.h | 6 +
arch/riscv/include/asm/syscall.h | 3 +
arch/riscv/include/asm/thread_info.h | 1 +
arch/riscv/include/asm/vdso.h | 9 +
arch/riscv/include/uapi/asm/unistd.h | 2 +-
arch/riscv/kernel/Makefile | 3 +
arch/riscv/kernel/compat_signal.c | 243 ++++++++++++++++++
arch/riscv/kernel/compat_syscall_table.c | 72 ++++++
arch/riscv/kernel/compat_vdso/.gitignore | 2 +
arch/riscv/kernel/compat_vdso/Makefile | 68 +++++
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 +
.../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 +
arch/riscv/kernel/entry.S | 18 +-
arch/riscv/kernel/process.c | 5 +
arch/riscv/kernel/ptrace.c | 87 ++++++-
arch/riscv/kernel/signal.c | 13 +-
arch/riscv/kernel/sys_riscv.c | 6 +-
arch/riscv/kernel/vdso.c | 104 +++++---
arch/riscv/kernel/vdso/vdso.S | 6 +-
arch/s390/Kconfig | 3 -
arch/s390/include/asm/compat.h | 113 +-------
arch/s390/include/asm/unistd.h | 1 +
arch/sparc/Kconfig | 5 -
arch/sparc/include/asm/compat.h | 43 ++--
arch/sparc/include/asm/unistd.h | 1 +
arch/x86/Kconfig | 4 -
arch/x86/include/asm/compat.h | 118 +--------
arch/x86/include/asm/unistd.h | 1 +
drivers/firmware/efi/libstub/efi-stub.c | 2 +-
fs/stat.c | 2 +-
include/asm-generic/compat.h | 122 +++++++++
include/uapi/asm-generic/fcntl.h | 2 +-
include/uapi/asm-generic/unistd.h | 4 +-
init/Kconfig | 4 +
tools/include/uapi/asm-generic/unistd.h | 4 +-
60 files changed, 1076 insertions(+), 654 deletions(-)
delete mode 100644 arch/riscv/configs/rv32_defconfig
create mode 100644 arch/riscv/include/asm/compat.h
create mode 100644 arch/riscv/kernel/compat_signal.c
create mode 100644 arch/riscv/kernel/compat_syscall_table.c
create mode 100644 arch/riscv/kernel/compat_vdso/.gitignore
create mode 100644 arch/riscv/kernel/compat_vdso/Makefile
create mode 100644 arch/riscv/kernel/compat_vdso/compat_vdso.S
create mode 100644 arch/riscv/kernel/compat_vdso/compat_vdso.lds.S
create mode 100644 arch/riscv/kernel/compat_vdso/flush_icache.S
create mode 100755 arch/riscv/kernel/compat_vdso/gen_compat_vdso_offsets.sh
create mode 100644 arch/riscv/kernel/compat_vdso/getcpu.S
create mode 100644 arch/riscv/kernel/compat_vdso/note.S
create mode 100644 arch/riscv/kernel/compat_vdso/rt_sigreturn.S
--
2.25.1
From: Guo Ren <redacted>
The existing per-arch definitions are pretty much historic cruft.
Move SYSVIPC_COMPAT into init/Kconfig.
Signed-off-by: Guo Ren <redacted>
Signed-off-by: Guo Ren <guoren@kernel.org>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Christoph Hellwig <hch@infradead.org>
---
arch/arm64/Kconfig | 4 ----
arch/mips/Kconfig | 5 -----
arch/parisc/Kconfig | 4 ----
arch/powerpc/Kconfig | 5 -----
arch/s390/Kconfig | 3 ---
arch/sparc/Kconfig | 5 -----
arch/x86/Kconfig | 4 ----
init/Kconfig | 4 ++++
8 files changed, 4 insertions(+), 30 deletions(-)
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index c4207cf9bb17..8ca8cc6f3253 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig @@ -2028,10 +2028,6 @@ config DMI
endmenu
- config SYSVIPC_COMPAT
- def_bool y
- depends on COMPAT && SYSVIPC
-
menu "Power management options"
source "kernel/power/Kconfig" diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 0215dc1529e9..b84eba22fefe 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig @@ -3169,16 +3169,12 @@ config MIPS32_COMPAT
config COMPAT
bool
- config SYSVIPC_COMPAT
- bool
-
config MIPS32_O32
bool "Kernel support for o32 binaries"
depends on 64 BIT
select ARCH_WANT_OLD_COMPAT_IPC
select COMPAT
select MIPS32_COMPAT
- select SYSVIPC_COMPAT if SYSVIPC
help
Select this option if you want to run o32 binaries. These are pure
32 -bit binaries as used by the 32 -bit Linux/MIPS port. Most of @@ -3192,7 +3188,6 @@ config MIPS32_N32
select ARCH_WANT_COMPAT_IPC_PARSE_VERSION
select COMPAT
select MIPS32_COMPAT
- select SYSVIPC_COMPAT if SYSVIPC
help
Select this option if you want to run n32 binaries. These are
64 -bit binaries using 32 -bit quantities for addressing and certain diff --git a/arch/parisc/Kconfig b/arch/parisc/Kconfig
index b2188da09c73..bd72696cbd42 100644
--- a/arch/parisc/Kconfig
+++ b/arch/parisc/Kconfig @@ -364,10 +364,6 @@ config COMPAT
def_bool y
depends on 64 BIT
- config SYSVIPC_COMPAT
- def_bool y
- depends on COMPAT && SYSVIPC
-
config AUDIT_ARCH
def_bool y
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index dea74d7717c0..81d198daa998 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig @@ -296,11 +296,6 @@ config COMPAT
select ARCH_WANT_OLD_COMPAT_IPC
select COMPAT_OLD_SIGACTION
- config SYSVIPC_COMPAT
- bool
- depends on COMPAT && SYSVIPC
- default y
-
config SCHED_OMIT_FRAME_POINTER
bool
default y diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig
index 2a5bb4f29cfe..c1816ca7ae43 100644
--- a/arch/s390/Kconfig
+++ b/arch/s390/Kconfig @@ -461,9 +461,6 @@ config COMPAT
( and some other stuff like libraries and such) is needed for
executing 31 bit applications. It is safe to say "Y" .
- config SYSVIPC_COMPAT
- def_bool y if COMPAT && SYSVIPC
-
config SMP
def_bool y
diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig
index 66fc08646be5..45401b99d6cb 100644
--- a/arch/sparc/Kconfig
+++ b/arch/sparc/Kconfig @@ -494,9 +494,4 @@ config COMPAT
select ARCH_WANT_OLD_COMPAT_IPC
select COMPAT_OLD_SIGACTION
- config SYSVIPC_COMPAT
- bool
- depends on COMPAT && SYSVIPC
- default y
-
source "drivers/sbus/char/Kconfig" diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 5c2ccb85f2ef..569703122cce 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig @@ -2850,10 +2850,6 @@ config COMPAT
if COMPAT
config COMPAT_FOR_U64_ALIGNMENT
def_bool y
-
- config SYSVIPC_COMPAT
- def_bool y
- depends on SYSVIPC
endif
endmenu diff --git a/init/Kconfig b/init/Kconfig
index 4b7bac10c72d..aa0d63677c82 100644
--- a/init/Kconfig
+++ b/init/Kconfig @@ -386,6 +386,10 @@ config SYSVIPC_SYSCTL
depends on SYSCTL
default y
+ config SYSVIPC_COMPAT
+ def_bool y
+ depends on COMPAT && SYSVIPC
+
config POSIX_MQUEUE
bool "POSIX Message Queues"
depends on NET --
2.25.1
From: Guo Ren <redacted>
RISC-V doesn't neeed compat_stat, so using __ARCH_WANT_COMPAT_STAT
to exclude unnecessary SYSCALL functions.
Signed-off-by: Guo Ren <redacted>
Signed-off-by: Guo Ren <guoren@kernel.org>
Cc: Arnd Bergmann <arnd@arndb.de>
---
arch/arm64/include/asm/unistd.h | 1 +
arch/mips/include/asm/unistd.h | 2 ++
arch/parisc/include/asm/unistd.h | 1 +
arch/powerpc/include/asm/unistd.h | 1 +
arch/s390/include/asm/unistd.h | 1 +
arch/sparc/include/asm/unistd.h | 1 +
arch/x86/include/asm/unistd.h | 1 +
fs/stat.c | 2 +-
8 files changed, 9 insertions(+), 1 deletion(-)
diff --git a/arch/arm64/include/asm/unistd.h b/arch/arm64/include/asm/unistd.h
index 6bdb5f5db438..bc2c4c55bae6 100644
--- a/arch/arm64/include/asm/unistd.h
+++ b/arch/arm64/include/asm/unistd.h @@ -3,6 +3,7 @@
* Copyright ( C ) 2012 ARM Ltd .
*/
#ifdef CONFIG_COMPAT
+ #define __ARCH_WANT_COMPAT_STAT
#define __ARCH_WANT_COMPAT_STAT64
#define __ARCH_WANT_SYS_GETHOSTNAME
#define __ARCH_WANT_SYS_PAUSE diff --git a/arch/mips/include/asm/unistd.h b/arch/mips/include/asm/unistd.h
index c2196b1b6604..25a5253db7f4 100644
--- a/arch/mips/include/asm/unistd.h
+++ b/arch/mips/include/asm/unistd.h @@ -50,6 +50,8 @@
# ifdef CONFIG_32BIT
# define __ARCH_WANT_STAT64
# define __ARCH_WANT_SYS_TIME32
+ # else
+ # define __ARCH_WANT_COMPAT_STAT
# endif
# ifdef CONFIG_MIPS32_O32
# define __ARCH_WANT_SYS_TIME32 diff --git a/arch/parisc/include/asm/unistd.h b/arch/parisc/include/asm/unistd.h
index cd438e4150f6..14e0668184cb 100644
--- a/arch/parisc/include/asm/unistd.h
+++ b/arch/parisc/include/asm/unistd.h @@ -168,6 +168,7 @@ type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5) \
#define __ARCH_WANT_SYS_CLONE
#define __ARCH_WANT_SYS_CLONE3
#define __ARCH_WANT_COMPAT_SYS_SENDFILE
+ #define __ARCH_WANT_COMPAT_STAT
#ifdef CONFIG_64BIT
#define __ARCH_WANT_SYS_TIME diff --git a/arch/powerpc/include/asm/unistd.h b/arch/powerpc/include/asm/unistd.h
index 5eb462af6766..b1129b4ef57d 100644
--- a/arch/powerpc/include/asm/unistd.h
+++ b/arch/powerpc/include/asm/unistd.h @@ -44,6 +44,7 @@
#define __ARCH_WANT_SYS_TIME
#define __ARCH_WANT_SYS_UTIME
#define __ARCH_WANT_SYS_NEWFSTATAT
+ #define __ARCH_WANT_COMPAT_STAT
#define __ARCH_WANT_COMPAT_SYS_SENDFILE
#endif
#define __ARCH_WANT_SYS_FORK diff --git a/arch/s390/include/asm/unistd.h b/arch/s390/include/asm/unistd.h
index 9e9f75ef046a..4260bc5ce7f8 100644
--- a/arch/s390/include/asm/unistd.h
+++ b/arch/s390/include/asm/unistd.h @@ -28,6 +28,7 @@
#define __ARCH_WANT_SYS_SIGPENDING
#define __ARCH_WANT_SYS_SIGPROCMASK
# ifdef CONFIG_COMPAT
+ # define __ARCH_WANT_COMPAT_STAT
# define __ARCH_WANT_SYS_TIME32
# define __ARCH_WANT_SYS_UTIME32
# endif diff --git a/arch/sparc/include/asm/unistd.h b/arch/sparc/include/asm/unistd.h
index 1e66278ba4a5..d6bc76706a7a 100644
--- a/arch/sparc/include/asm/unistd.h
+++ b/arch/sparc/include/asm/unistd.h @@ -46,6 +46,7 @@
#define __ARCH_WANT_SYS_TIME
#define __ARCH_WANT_SYS_UTIME
#define __ARCH_WANT_COMPAT_SYS_SENDFILE
+ #define __ARCH_WANT_COMPAT_STAT
#endif
#ifdef __32bit_syscall_numbers__ diff --git a/arch/x86/include/asm/unistd.h b/arch/x86/include/asm/unistd.h
index 80e9d5206a71..761173ccc33c 100644
--- a/arch/x86/include/asm/unistd.h
+++ b/arch/x86/include/asm/unistd.h @@ -22,6 +22,7 @@
# include <asm/unistd_32_ia32.h>
# define __ARCH_WANT_SYS_TIME
# define __ARCH_WANT_SYS_UTIME
+ # define __ARCH_WANT_COMPAT_STAT
# define __ARCH_WANT_COMPAT_SYS_PREADV64
# define __ARCH_WANT_COMPAT_SYS_PWRITEV64
# define __ARCH_WANT_COMPAT_SYS_PREADV64V2 diff --git a/fs/stat.c b/fs/stat.c
index 28d2020ba1f4..ffdeb9065d53 100644
--- a/fs/stat.c
+++ b/fs/stat.c @@ -639,7 +639,7 @@ SYSCALL_DEFINE5(statx,
return do_statx ( dfd , filename , flags , mask , buffer );
}
- #ifdef CONFIG_COMPAT
+ #if defined(CONFIG_COMPAT) && defined(__ARCH_WANT_COMPAT_STAT)
static int cp_compat_stat ( struct kstat * stat , struct compat_stat __user * ubuf )
{
struct compat_stat tmp ; --
2.25.1
From: Guo Ren <redacted>
Remove duplicate F_GETLK64,F_SETLK64,F_SETLKW64 definitions in
arch/*/include/asm/compat.h.
Signed-off-by: Guo Ren <redacted>
Signed-off-by: Guo Ren <guoren@kernel.org>
Cc: Arnd Bergmann <arnd@arndb.de>
---
arch/arm64/include/asm/compat.h | 4 ----
arch/powerpc/include/asm/compat.h | 4 ----
arch/s390/include/asm/compat.h | 4 ----
arch/sparc/include/asm/compat.h | 4 ----
arch/x86/include/asm/compat.h | 4 ----
include/uapi/asm-generic/fcntl.h | 2 +-
6 files changed, 1 insertion(+), 21 deletions(-)
diff --git a/arch/arm64/include/asm/compat.h b/arch/arm64/include/asm/compat.h
index eaa6ca062d89..276328765408 100644
--- a/arch/arm64/include/asm/compat.h
+++ b/arch/arm64/include/asm/compat.h @@ -73,10 +73,6 @@ struct compat_flock {
compat_pid_t l_pid ;
};
- #define F_GETLK64 12 /* using 'struct flock64' */
- #define F_SETLK64 13
- #define F_SETLKW64 14
-
struct compat_flock64 {
short l_type ;
short l_whence ; diff --git a/arch/powerpc/include/asm/compat.h b/arch/powerpc/include/asm/compat.h
index 7afc96fb6524..83d8f70779cb 100644
--- a/arch/powerpc/include/asm/compat.h
+++ b/arch/powerpc/include/asm/compat.h @@ -52,10 +52,6 @@ struct compat_flock {
compat_pid_t l_pid ;
};
- #define F_GETLK64 12 /* using 'struct flock64' */
- #define F_SETLK64 13
- #define F_SETLKW64 14
-
struct compat_flock64 {
short l_type ;
short l_whence ; diff --git a/arch/s390/include/asm/compat.h b/arch/s390/include/asm/compat.h
index cdc7ae72529d..0f14b3188b1b 100644
--- a/arch/s390/include/asm/compat.h
+++ b/arch/s390/include/asm/compat.h @@ -110,10 +110,6 @@ struct compat_flock {
compat_pid_t l_pid ;
};
- #define F_GETLK64 12
- #define F_SETLK64 13
- #define F_SETLKW64 14
-
struct compat_flock64 {
short l_type ;
short l_whence ; diff --git a/arch/sparc/include/asm/compat.h b/arch/sparc/include/asm/compat.h
index bd949fcf9d63..108078751bb5 100644
--- a/arch/sparc/include/asm/compat.h
+++ b/arch/sparc/include/asm/compat.h @@ -84,10 +84,6 @@ struct compat_flock {
short __unused ;
};
- #define F_GETLK64 12
- #define F_SETLK64 13
- #define F_SETLKW64 14
-
struct compat_flock64 {
short l_type ;
short l_whence ; diff --git a/arch/x86/include/asm/compat.h b/arch/x86/include/asm/compat.h
index 7516e4199b3c..8d19a212f4f2 100644
--- a/arch/x86/include/asm/compat.h
+++ b/arch/x86/include/asm/compat.h @@ -58,10 +58,6 @@ struct compat_flock {
compat_pid_t l_pid ;
};
- #define F_GETLK64 12 /* using 'struct flock64' */
- #define F_SETLK64 13
- #define F_SETLKW64 14
-
/*
* IA32 uses 4 byte alignment for 64 bit quantities ,
* so we need to pack this structure . diff --git a/include/uapi/asm-generic/fcntl.h b/include/uapi/asm-generic/fcntl.h
index ecd0f5bdfc1d..5bc1e51d73b1 100644
--- a/include/uapi/asm-generic/fcntl.h
+++ b/include/uapi/asm-generic/fcntl.h @@ -116,7 +116,7 @@
#define F_GETSIG 11 /* for sockets. */
#endif
- #ifndef CONFIG_64BIT
+ #if !defined(CONFIG_64BIT) || defined(CONFIG_COMPAT)
#ifndef F_GETLK64
#define F_GETLK64 12 /* using 'struct flock64' */
#define F_SETLK64 13 --
2.25.1
From: Guo Ren <redacted>
There are 7 64bit architectures that support Linux COMPAT mode to
run 32bit applications. A lot of definitions are duplicate:
- COMPAT_USER_HZ
- COMPAT_RLIM_INFINITY
- COMPAT_OFF_T_MAX
- __compat_uid_t, __compat_uid_t
- compat_dev_t
- compat_ipc_pid_t
- struct compat_flock
- struct compat_flock64
- struct compat_statfs
- struct compat_ipc64_perm, compat_semid64_ds,
compat_msqid64_ds, compat_shmid64_ds
Cleanup duplicate definitions and merge them into asm-generic.
Signed-off-by: Guo Ren <redacted>
Signed-off-by: Guo Ren <guoren@kernel.org>
Cc: Arnd Bergmann <arnd@arndb.de>
---
arch/arm64/include/asm/compat.h | 108 +++-----------------------
arch/mips/include/asm/compat.h | 24 ++----
arch/parisc/include/asm/compat.h | 47 ++----------
arch/powerpc/include/asm/compat.h | 47 ++----------
arch/s390/include/asm/compat.h | 109 +++-----------------------
arch/sparc/include/asm/compat.h | 39 ++++------
arch/x86/include/asm/compat.h | 114 +++-------------------------
include/asm-generic/compat.h | 122 ++++++++++++++++++++++++++++++
8 files changed, 191 insertions(+), 419 deletions(-)
diff --git a/arch/arm64/include/asm/compat.h b/arch/arm64/include/asm/compat.h
index 276328765408..f896486c80a9 100644
--- a/arch/arm64/include/asm/compat.h
+++ b/arch/arm64/include/asm/compat.h @@ -5,9 +5,18 @@
#ifndef __ASM_COMPAT_H
#define __ASM_COMPAT_H
+ #define COMPAT_RLIM_INFINITY 0xffffffff
+
#define compat_mode_t compat_mode_t
typedef u16 compat_mode_t ;
+ #define __compat_uid_t __compat_uid_t
+ typedef u16 __compat_uid_t ;
+ typedef u16 __compat_gid_t ;
+
+ #define compat_ipc_pid_t compat_ipc_pid_t
+ typedef u16 compat_ipc_pid_t ;
+
#include <asm-generic/compat.h>
#ifdef CONFIG_COMPAT @@ -19,21 +28,15 @@ typedef u16 compat_mode_t;
#include <linux/sched.h>
#include <linux/sched/task_stack.h>
- #define COMPAT_USER_HZ 100
#ifdef __AARCH64EB__
#define COMPAT_UTS_MACHINE "armv8b\0\0"
#else
#define COMPAT_UTS_MACHINE "armv8l\0\0"
#endif
- typedef u16 __compat_uid_t ;
- typedef u16 __compat_gid_t ;
typedef u16 __compat_uid16_t ;
typedef u16 __compat_gid16_t ;
- typedef u32 compat_dev_t ;
typedef s32 compat_nlink_t ;
- typedef u16 compat_ipc_pid_t ;
- typedef __kernel_fsid_t compat_fsid_t ;
struct compat_stat {
#ifdef __AARCH64EB__ @@ -65,102 +68,9 @@ struct compat_stat {
compat_ulong_t __unused4 [ 2 ];
};
- struct compat_flock {
- short l_type ;
- short l_whence ;
- compat_off_t l_start ;
- compat_off_t l_len ;
- compat_pid_t l_pid ;
- };
-
- struct compat_flock64 {
- short l_type ;
- short l_whence ;
- compat_loff_t l_start ;
- compat_loff_t l_len ;
- compat_pid_t l_pid ;
- };
-
- struct compat_statfs {
- int f_type ;
- int f_bsize ;
- int f_blocks ;
- int f_bfree ;
- int f_bavail ;
- int f_files ;
- int f_ffree ;
- compat_fsid_t f_fsid ;
- int f_namelen ; /* SunOS ignores this field. */
- int f_frsize ;
- int f_flags ;
- int f_spare [ 4 ];
- };
-
- #define COMPAT_RLIM_INFINITY 0xffffffff
-
- #define COMPAT_OFF_T_MAX 0x7fffffff
-
#define compat_user_stack_pointer() (user_stack_pointer(task_pt_regs(current)))
#define COMPAT_MINSIGSTKSZ 2048
- struct compat_ipc64_perm {
- compat_key_t key ;
- __compat_uid32_t uid ;
- __compat_gid32_t gid ;
- __compat_uid32_t cuid ;
- __compat_gid32_t cgid ;
- unsigned short mode ;
- unsigned short __pad1 ;
- unsigned short seq ;
- unsigned short __pad2 ;
- compat_ulong_t unused1 ;
- compat_ulong_t unused2 ;
- };
-
- struct compat_semid64_ds {
- struct compat_ipc64_perm sem_perm ;
- compat_ulong_t sem_otime ;
- compat_ulong_t sem_otime_high ;
- compat_ulong_t sem_ctime ;
- compat_ulong_t sem_ctime_high ;
- compat_ulong_t sem_nsems ;
- compat_ulong_t __unused3 ;
- compat_ulong_t __unused4 ;
- };
-
- struct compat_msqid64_ds {
- struct compat_ipc64_perm msg_perm ;
- compat_ulong_t msg_stime ;
- compat_ulong_t msg_stime_high ;
- compat_ulong_t msg_rtime ;
- compat_ulong_t msg_rtime_high ;
- compat_ulong_t msg_ctime ;
- compat_ulong_t msg_ctime_high ;
- compat_ulong_t msg_cbytes ;
- compat_ulong_t msg_qnum ;
- compat_ulong_t msg_qbytes ;
- compat_pid_t msg_lspid ;
- compat_pid_t msg_lrpid ;
- compat_ulong_t __unused4 ;
- compat_ulong_t __unused5 ;
- };
-
- struct compat_shmid64_ds {
- struct compat_ipc64_perm shm_perm ;
- compat_size_t shm_segsz ;
- compat_ulong_t shm_atime ;
- compat_ulong_t shm_atime_high ;
- compat_ulong_t shm_dtime ;
- compat_ulong_t shm_dtime_high ;
- compat_ulong_t shm_ctime ;
- compat_ulong_t shm_ctime_high ;
- compat_pid_t shm_cpid ;
- compat_pid_t shm_lpid ;
- compat_ulong_t shm_nattch ;
- compat_ulong_t __unused4 ;
- compat_ulong_t __unused5 ;
- };
-
static inline int is_compat_task ( void )
{
return test_thread_flag ( TIF_32BIT ); diff --git a/arch/mips/include/asm/compat.h b/arch/mips/include/asm/compat.h
index bbb3bc5a42fd..cc2d76953792 100644
--- a/arch/mips/include/asm/compat.h
+++ b/arch/mips/include/asm/compat.h @@ -9,12 +9,17 @@
#include <asm/page.h>
#include <asm/ptrace.h>
+ #define __compat_uid_t __compat_uid_t
typedef s32 __compat_uid_t ;
typedef s32 __compat_gid_t ;
+
+ #define __compat_uid32_t __compat_uid32_t
typedef __compat_uid_t __compat_uid32_t ;
typedef __compat_gid_t __compat_gid32_t ;
- #define __compat_uid32_t __compat_uid32_t
- #define __compat_gid32_t __compat_gid32_t
+
+ #define compat_flock compat_flock
+ #define compat_statfs compat_statfs
+ #define compat_ipc64_perm compat_ipc64_perm
#define _COMPAT_NSIG 128 /* Don't ask !$@#% ... */
#define _COMPAT_NSIG_BPW 32 @@ -22,12 +27,9 @@ typedef u32 compat_sigset_word;
#include <asm-generic/compat.h>
- #define COMPAT_USER_HZ 100
#define COMPAT_UTS_MACHINE "mips\0\0\0"
- typedef u32 compat_dev_t ;
typedef u32 compat_nlink_t ;
- typedef s32 compat_ipc_pid_t ;
typedef struct {
s32 val [ 2 ];
} compat_fsid_t ; @@ -69,14 +71,6 @@ struct compat_flock {
#define F_SETLK64 34
#define F_SETLKW64 35
- struct compat_flock64 {
- short l_type ;
- short l_whence ;
- compat_loff_t l_start ;
- compat_loff_t l_len ;
- compat_pid_t l_pid ;
- };
-
struct compat_statfs {
int f_type ;
int f_bsize ; @@ -92,10 +86,6 @@ struct compat_statfs {
int f_spare [ 5 ];
};
- #define COMPAT_RLIM_INFINITY 0x7fffffffUL
-
- #define COMPAT_OFF_T_MAX 0x7fffffff
-
struct compat_ipc64_perm {
compat_key_t key ;
__compat_uid32_t uid ; diff --git a/arch/parisc/include/asm/compat.h b/arch/parisc/include/asm/compat.h
index c04f5a637c39..113476345c76 100644
--- a/arch/parisc/include/asm/compat.h
+++ b/arch/parisc/include/asm/compat.h @@ -8,19 +8,21 @@
#include <linux/sched.h>
#include <linux/thread_info.h>
+ #define COMPAT_RLIM_INFINITY 0xffffffff
+
#define compat_mode_t compat_mode_t
typedef u16 compat_mode_t ;
+ #define compat_ipc_pid_t compat_ipc_pid_t
+ typedef u16 compat_ipc_pid_t ;
+
+ #define compat_ipc64_perm compat_ipc64_perm
+
#include <asm-generic/compat.h>
- #define COMPAT_USER_HZ 100
#define COMPAT_UTS_MACHINE "parisc\0\0"
- typedef u32 __compat_uid_t ;
- typedef u32 __compat_gid_t ;
- typedef u32 compat_dev_t ;
typedef u16 compat_nlink_t ;
- typedef u16 compat_ipc_pid_t ;
struct compat_stat {
compat_dev_t st_dev ; /* dev_t is 32 bits on parisc */ @@ -53,37 +55,6 @@ struct compat_stat {
u32 st_spare4 [ 3 ];
};
- struct compat_flock {
- short l_type ;
- short l_whence ;
- compat_off_t l_start ;
- compat_off_t l_len ;
- compat_pid_t l_pid ;
- };
-
- struct compat_flock64 {
- short l_type ;
- short l_whence ;
- compat_loff_t l_start ;
- compat_loff_t l_len ;
- compat_pid_t l_pid ;
- };
-
- struct compat_statfs {
- s32 f_type ;
- s32 f_bsize ;
- s32 f_blocks ;
- s32 f_bfree ;
- s32 f_bavail ;
- s32 f_files ;
- s32 f_ffree ;
- __kernel_fsid_t f_fsid ;
- s32 f_namelen ;
- s32 f_frsize ;
- s32 f_flags ;
- s32 f_spare [ 4 ];
- };
-
struct compat_sigcontext {
compat_int_t sc_flags ;
compat_int_t sc_gr [ 32 ]; /* PSW in sc_gr[0] */ @@ -93,10 +64,6 @@ struct compat_sigcontext {
compat_int_t sc_sar ; /* cr11 */
};
- #define COMPAT_RLIM_INFINITY 0xffffffff
-
- #define COMPAT_OFF_T_MAX 0x7fffffff
-
struct compat_ipc64_perm {
compat_key_t key ;
__compat_uid_t uid ; diff --git a/arch/powerpc/include/asm/compat.h b/arch/powerpc/include/asm/compat.h
index 83d8f70779cb..cda6e6ef6478 100644
--- a/arch/powerpc/include/asm/compat.h
+++ b/arch/powerpc/include/asm/compat.h @@ -8,20 +8,22 @@
#include <linux/types.h>
#include <linux/sched.h>
+ #define COMPAT_RLIM_INFINITY 0xffffffff
+
+ #define compat_ipc_pid_t compat_ipc_pid_t
+ typedef u16 compat_ipc_pid_t ;
+
+ #define compat_ipc64_perm compat_ipc64_perm
+
#include <asm-generic/compat.h>
- #define COMPAT_USER_HZ 100
#ifdef __BIG_ENDIAN__
#define COMPAT_UTS_MACHINE "ppc\0\0"
#else
#define COMPAT_UTS_MACHINE "ppcle\0\0"
#endif
- typedef u32 __compat_uid_t ;
- typedef u32 __compat_gid_t ;
- typedef u32 compat_dev_t ;
typedef s16 compat_nlink_t ;
- typedef u16 compat_ipc_pid_t ;
typedef __kernel_fsid_t compat_fsid_t ;
struct compat_stat { @@ -44,41 +46,6 @@ struct compat_stat {
u32 __unused4 [ 2 ];
};
- struct compat_flock {
- short l_type ;
- short l_whence ;
- compat_off_t l_start ;
- compat_off_t l_len ;
- compat_pid_t l_pid ;
- };
-
- struct compat_flock64 {
- short l_type ;
- short l_whence ;
- compat_loff_t l_start ;
- compat_loff_t l_len ;
- compat_pid_t l_pid ;
- };
-
- struct compat_statfs {
- int f_type ;
- int f_bsize ;
- int f_blocks ;
- int f_bfree ;
- int f_bavail ;
- int f_files ;
- int f_ffree ;
- compat_fsid_t f_fsid ;
- int f_namelen ; /* SunOS ignores this field. */
- int f_frsize ;
- int f_flags ;
- int f_spare [ 4 ];
- };
-
- #define COMPAT_RLIM_INFINITY 0xffffffff
-
- #define COMPAT_OFF_T_MAX 0x7fffffff
-
/*
* ipc64_perm is actually 32 / 64 bit clean but since the compat layer refers to
* it we may as well define it . diff --git a/arch/s390/include/asm/compat.h b/arch/s390/include/asm/compat.h
index 0f14b3188b1b..23e27ca1439c 100644
--- a/arch/s390/include/asm/compat.h
+++ b/arch/s390/include/asm/compat.h @@ -9,9 +9,21 @@
#include <linux/sched/task_stack.h>
#include <linux/thread_info.h>
+ #define COMPAT_RLIM_INFINITY 0xffffffff
+
#define compat_mode_t compat_mode_t
typedef u16 compat_mode_t ;
+ #define __compat_uid_t __compat_uid_t
+ typedef u16 __compat_uid_t ;
+ typedef u16 __compat_gid_t ;
+
+ #define compat_dev_t compat_dev_t
+ typedef u16 compat_dev_t ;
+
+ #define compat_ipc_pid_t compat_ipc_pid_t
+ typedef u16 compat_ipc_pid_t ;
+
#include <asm-generic/compat.h>
#define __TYPE_IS_PTR(t) (!__builtin_types_compatible_p( \ @@ -53,14 +65,9 @@ typedef u16 compat_mode_t;
PSW32_MASK_MCHECK | PSW32_MASK_PSTATE | \
PSW32_ASC_PRIMARY )
- #define COMPAT_USER_HZ 100
#define COMPAT_UTS_MACHINE "s390\0\0\0\0"
- typedef u16 __compat_uid_t ;
- typedef u16 __compat_gid_t ;
- typedef u16 compat_dev_t ;
typedef u16 compat_nlink_t ;
- typedef u16 compat_ipc_pid_t ;
typedef __kernel_fsid_t compat_fsid_t ;
typedef struct { @@ -102,37 +109,6 @@ struct compat_stat {
u32 __unused5 ;
};
- struct compat_flock {
- short l_type ;
- short l_whence ;
- compat_off_t l_start ;
- compat_off_t l_len ;
- compat_pid_t l_pid ;
- };
-
- struct compat_flock64 {
- short l_type ;
- short l_whence ;
- compat_loff_t l_start ;
- compat_loff_t l_len ;
- compat_pid_t l_pid ;
- };
-
- struct compat_statfs {
- u32 f_type ;
- u32 f_bsize ;
- u32 f_blocks ;
- u32 f_bfree ;
- u32 f_bavail ;
- u32 f_files ;
- u32 f_ffree ;
- compat_fsid_t f_fsid ;
- u32 f_namelen ;
- u32 f_frsize ;
- u32 f_flags ;
- u32 f_spare [ 4 ];
- };
-
struct compat_statfs64 {
u32 f_type ;
u32 f_bsize ; @@ -148,10 +124,6 @@ struct compat_statfs64 {
u32 f_spare [ 4 ];
};
- #define COMPAT_RLIM_INFINITY 0xffffffff
-
- #define COMPAT_OFF_T_MAX 0x7fffffff
-
/*
* A pointer passed in from user mode . This should not
* be used for syscall parameters , just declare them @@ -174,61 +146,4 @@ static inline int is_compat_task(void)
#endif
- struct compat_ipc64_perm {
- compat_key_t key ;
- __compat_uid32_t uid ;
- __compat_gid32_t gid ;
- __compat_uid32_t cuid ;
- __compat_gid32_t cgid ;
- compat_mode_t mode ;
- unsigned short __pad1 ;
- unsigned short seq ;
- unsigned short __pad2 ;
- unsigned int __unused1 ;
- unsigned int __unused2 ;
- };
-
- struct compat_semid64_ds {
- struct compat_ipc64_perm sem_perm ;
- compat_ulong_t sem_otime ;
- compat_ulong_t sem_otime_high ;
- compat_ulong_t sem_ctime ;
- compat_ulong_t sem_ctime_high ;
- compat_ulong_t sem_nsems ;
- compat_ulong_t __unused1 ;
- compat_ulong_t __unused2 ;
- };
-
- struct compat_msqid64_ds {
- struct compat_ipc64_perm msg_perm ;
- compat_ulong_t msg_stime ;
- compat_ulong_t msg_stime_high ;
- compat_ulong_t msg_rtime ;
- compat_ulong_t msg_rtime_high ;
- compat_ulong_t msg_ctime ;
- compat_ulong_t msg_ctime_high ;
- compat_ulong_t msg_cbytes ;
- compat_ulong_t msg_qnum ;
- compat_ulong_t msg_qbytes ;
- compat_pid_t msg_lspid ;
- compat_pid_t msg_lrpid ;
- compat_ulong_t __unused1 ;
- compat_ulong_t __unused2 ;
- };
-
- struct compat_shmid64_ds {
- struct compat_ipc64_perm shm_perm ;
- compat_size_t shm_segsz ;
- compat_ulong_t shm_atime ;
- compat_ulong_t shm_atime_high ;
- compat_ulong_t shm_dtime ;
- compat_ulong_t shm_dtime_high ;
- compat_ulong_t shm_ctime ;
- compat_ulong_t shm_ctime_high ;
- compat_pid_t shm_cpid ;
- compat_pid_t shm_lpid ;
- compat_ulong_t shm_nattch ;
- compat_ulong_t __unused1 ;
- compat_ulong_t __unused2 ;
- };
#endif /* _ASM_S390X_COMPAT_H */ diff --git a/arch/sparc/include/asm/compat.h b/arch/sparc/include/asm/compat.h
index 108078751bb5..00650d21cc51 100644
--- a/arch/sparc/include/asm/compat.h
+++ b/arch/sparc/include/asm/compat.h @@ -9,16 +9,26 @@
#define compat_mode_t compat_mode_t
typedef u16 compat_mode_t ;
+ #define __compat_uid_t __compat_uid_t
+ typedef u16 __compat_uid_t ;
+ typedef u16 __compat_gid_t ;
+
+ #define compat_dev_t compat_dev_t
+ typedef u16 compat_dev_t ;
+
+ #define compat_ipc_pid_t compat_ipc_pid_t
+ typedef u16 compat_ipc_pid_t ;
+
+ #define compat_flock compat_flock
+ #define compat_flock64 compat_flock64
+
+ #define compat_ipc64_perm compat_ipc64_perm
+
#include <asm-generic/compat.h>
- #define COMPAT_USER_HZ 100
#define COMPAT_UTS_MACHINE "sparc\0\0"
- typedef u16 __compat_uid_t ;
- typedef u16 __compat_gid_t ;
- typedef u16 compat_dev_t ;
typedef s16 compat_nlink_t ;
- typedef u16 compat_ipc_pid_t ;
typedef __kernel_fsid_t compat_fsid_t ;
struct compat_stat { @@ -93,25 +103,6 @@ struct compat_flock64 {
short __unused ;
};
- struct compat_statfs {
- int f_type ;
- int f_bsize ;
- int f_blocks ;
- int f_bfree ;
- int f_bavail ;
- int f_files ;
- int f_ffree ;
- compat_fsid_t f_fsid ;
- int f_namelen ; /* SunOS ignores this field. */
- int f_frsize ;
- int f_flags ;
- int f_spare [ 4 ];
- };
-
- #define COMPAT_RLIM_INFINITY 0x7fffffff
-
- #define COMPAT_OFF_T_MAX 0x7fffffff
-
struct compat_ipc64_perm {
compat_key_t key ;
__compat_uid32_t uid ; diff --git a/arch/x86/include/asm/compat.h b/arch/x86/include/asm/compat.h
index 8d19a212f4f2..bd3d9a33ffd0 100644
--- a/arch/x86/include/asm/compat.h
+++ b/arch/x86/include/asm/compat.h @@ -12,19 +12,26 @@
#include <asm/user32.h>
#include <asm/unistd.h>
+ #define COMPAT_RLIM_INFINITY 0xffffffff
+
#define compat_mode_t compat_mode_t
typedef u16 compat_mode_t ;
+ #define __compat_uid_t __compat_uid_t
+ typedef u16 __compat_uid_t ;
+ typedef u16 __compat_gid_t ;
+
+ #define compat_dev_t compat_dev_t
+ typedef u16 compat_dev_t ;
+
+ #define compat_ipc_pid_t compat_ipc_pid_t
+ typedef u16 compat_ipc_pid_t ;
+
#include <asm-generic/compat.h>
- #define COMPAT_USER_HZ 100
#define COMPAT_UTS_MACHINE "i686\0\0"
- typedef u16 __compat_uid_t ;
- typedef u16 __compat_gid_t ;
- typedef u16 compat_dev_t ;
typedef u16 compat_nlink_t ;
- typedef u16 compat_ipc_pid_t ;
typedef __kernel_fsid_t compat_fsid_t ;
struct compat_stat { @@ -50,103 +57,6 @@ struct compat_stat {
u32 __unused5 ;
};
- struct compat_flock {
- short l_type ;
- short l_whence ;
- compat_off_t l_start ;
- compat_off_t l_len ;
- compat_pid_t l_pid ;
- };
-
- /*
- * IA32 uses 4 byte alignment for 64 bit quantities ,
- * so we need to pack this structure .
- */
- struct compat_flock64 {
- short l_type ;
- short l_whence ;
- compat_loff_t l_start ;
- compat_loff_t l_len ;
- compat_pid_t l_pid ;
- } __attribute__ (( packed ));
-
- struct compat_statfs {
- int f_type ;
- int f_bsize ;
- int f_blocks ;
- int f_bfree ;
- int f_bavail ;
- int f_files ;
- int f_ffree ;
- compat_fsid_t f_fsid ;
- int f_namelen ; /* SunOS ignores this field. */
- int f_frsize ;
- int f_flags ;
- int f_spare [ 4 ];
- };
-
- #define COMPAT_RLIM_INFINITY 0xffffffff
-
- #define COMPAT_OFF_T_MAX 0x7fffffff
-
- struct compat_ipc64_perm {
- compat_key_t key ;
- __compat_uid32_t uid ;
- __compat_gid32_t gid ;
- __compat_uid32_t cuid ;
- __compat_gid32_t cgid ;
- unsigned short mode ;
- unsigned short __pad1 ;
- unsigned short seq ;
- unsigned short __pad2 ;
- compat_ulong_t unused1 ;
- compat_ulong_t unused2 ;
- };
-
- struct compat_semid64_ds {
- struct compat_ipc64_perm sem_perm ;
- compat_ulong_t sem_otime ;
- compat_ulong_t sem_otime_high ;
- compat_ulong_t sem_ctime ;
- compat_ulong_t sem_ctime_high ;
- compat_ulong_t sem_nsems ;
- compat_ulong_t __unused3 ;
- compat_ulong_t __unused4 ;
- };
-
- struct compat_msqid64_ds {
- struct compat_ipc64_perm msg_perm ;
- compat_ulong_t msg_stime ;
- compat_ulong_t msg_stime_high ;
- compat_ulong_t msg_rtime ;
- compat_ulong_t msg_rtime_high ;
- compat_ulong_t msg_ctime ;
- compat_ulong_t msg_ctime_high ;
- compat_ulong_t msg_cbytes ;
- compat_ulong_t msg_qnum ;
- compat_ulong_t msg_qbytes ;
- compat_pid_t msg_lspid ;
- compat_pid_t msg_lrpid ;
- compat_ulong_t __unused4 ;
- compat_ulong_t __unused5 ;
- };
-
- struct compat_shmid64_ds {
- struct compat_ipc64_perm shm_perm ;
- compat_size_t shm_segsz ;
- compat_ulong_t shm_atime ;
- compat_ulong_t shm_atime_high ;
- compat_ulong_t shm_dtime ;
- compat_ulong_t shm_dtime_high ;
- compat_ulong_t shm_ctime ;
- compat_ulong_t shm_ctime_high ;
- compat_pid_t shm_cpid ;
- compat_pid_t shm_lpid ;
- compat_ulong_t shm_nattch ;
- compat_ulong_t __unused4 ;
- compat_ulong_t __unused5 ;
- };
-
#ifdef CONFIG_X86_X32_ABI
#define COMPAT_USE_64BIT_TIME \
( !! ( task_pt_regs ( current ) -> orig_ax & __X32_SYSCALL_BIT )) diff --git a/include/asm-generic/compat.h b/include/asm-generic/compat.h
index d46c0201cc34..5d4cb53e4dfc 100644
--- a/include/asm-generic/compat.h
+++ b/include/asm-generic/compat.h @@ -2,6 +2,18 @@
#ifndef __ASM_GENERIC_COMPAT_H
#define __ASM_GENERIC_COMPAT_H
+ #ifndef COMPAT_USER_HZ
+ #define COMPAT_USER_HZ 100
+ #endif
+
+ #ifndef COMPAT_RLIM_INFINITY
+ #define COMPAT_RLIM_INFINITY 0x7fffffff
+ #endif
+
+ #ifndef COMPAT_OFF_T_MAX
+ #define COMPAT_OFF_T_MAX 0x7fffffff
+ #endif
+
/* These types are common across all compat ABIs */
typedef u32 compat_size_t ;
typedef s32 compat_ssize_t ; @@ -24,6 +36,11 @@ typedef u32 compat_caddr_t;
typedef u32 compat_aio_context_t ;
typedef u32 compat_old_sigset_t ;
+ #ifndef __compat_uid_t
+ typedef u32 __compat_uid_t ;
+ typedef u32 __compat_gid_t ;
+ #endif
+
#ifndef __compat_uid32_t
typedef u32 __compat_uid32_t ;
typedef u32 __compat_gid32_t ; @@ -47,4 +64,109 @@ typedef u32 compat_sigset_word;
#define _COMPAT_NSIG_BPW 32
#endif
+ #ifndef compat_dev_t
+ typedef u32 compat_dev_t ;
+ #endif
+
+ #ifndef compat_ipc_pid_t
+ typedef s32 compat_ipc_pid_t ;
+ #endif
+
+ #ifndef compat_flock
+ struct compat_flock {
+ compat_short_t l_type ;
+ compat_short_t l_whence ;
+ compat_off_t l_start ;
+ compat_off_t l_len ;
+ compat_pid_t l_pid ;
+ } __attribute__ (( packed ));
+ #endif
+
+ #ifndef compat_flock64
+ struct compat_flock64 {
+ compat_short_t l_type ;
+ compat_short_t l_whence ;
+ compat_loff_t l_start ;
+ compat_loff_t l_len ;
+ compat_pid_t l_pid ;
+ } __attribute__ (( packed ));
+ #endif
+
+ #ifndef compat_statfs
+ struct compat_statfs {
+ compat_uint_t f_type ;
+ compat_uint_t f_bsize ;
+ compat_uint_t f_blocks ;
+ compat_uint_t f_bfree ;
+ compat_uint_t f_bavail ;
+ compat_uint_t f_files ;
+ compat_uint_t f_ffree ;
+ __kernel_fsid_t f_fsid ;
+ compat_uint_t f_namelen ;
+ compat_uint_t f_frsize ;
+ compat_uint_t f_flags ;
+ compat_uint_t f_spare [ 4 ];
+ } __attribute__ (( packed ));
+ #endif
+
+ #ifndef compat_ipc64_perm
+ struct compat_ipc64_perm {
+ compat_key_t key ;
+ __compat_uid32_t uid ;
+ __compat_gid32_t gid ;
+ __compat_uid32_t cuid ;
+ __compat_gid32_t cgid ;
+ compat_mode_t mode ;
+ unsigned char __pad1 [ 4 - sizeof ( compat_mode_t )];
+ compat_ushort_t seq ;
+ compat_ushort_t __pad2 ;
+ compat_ulong_t unused1 ;
+ compat_ulong_t unused2 ;
+ } __attribute__ (( packed ));
+
+ struct compat_semid64_ds {
+ struct compat_ipc64_perm sem_perm ;
+ compat_ulong_t sem_otime ;
+ compat_ulong_t sem_otime_high ;
+ compat_ulong_t sem_ctime ;
+ compat_ulong_t sem_ctime_high ;
+ compat_ulong_t sem_nsems ;
+ compat_ulong_t __unused3 ;
+ compat_ulong_t __unused4 ;
+ } __attribute__ (( packed ));
+
+ struct compat_msqid64_ds {
+ struct compat_ipc64_perm msg_perm ;
+ compat_ulong_t msg_stime ;
+ compat_ulong_t msg_stime_high ;
+ compat_ulong_t msg_rtime ;
+ compat_ulong_t msg_rtime_high ;
+ compat_ulong_t msg_ctime ;
+ compat_ulong_t msg_ctime_high ;
+ compat_ulong_t msg_cbytes ;
+ compat_ulong_t msg_qnum ;
+ compat_ulong_t msg_qbytes ;
+ compat_pid_t msg_lspid ;
+ compat_pid_t msg_lrpid ;
+ compat_ulong_t __unused4 ;
+ compat_ulong_t __unused5 ;
+ } __attribute__ (( packed ));
+
+ struct compat_shmid64_ds {
+ struct compat_ipc64_perm shm_perm ;
+ compat_size_t shm_segsz ;
+ compat_ulong_t shm_atime ;
+ compat_ulong_t shm_atime_high ;
+ compat_ulong_t shm_dtime ;
+ compat_ulong_t shm_dtime_high ;
+ compat_ulong_t shm_ctime ;
+ compat_ulong_t shm_ctime_high ;
+ compat_pid_t shm_cpid ;
+ compat_pid_t shm_lpid ;
+ compat_ulong_t shm_nattch ;
+ compat_ulong_t __unused4 ;
+ compat_ulong_t __unused5 ;
+ } __attribute__ (( packed ));
+ #endif
+
#endif --
2.25.1
From: Guo Ren <redacted>
Make "uapi asm unistd.h" could be used for architectures' COMPAT
mode. The __SYSCALL_COMPAT is first used in riscv.
Signed-off-by: Guo Ren <redacted>
Signed-off-by: Guo Ren <guoren@kernel.org>
Cc: Arnd Bergmann <arnd@arndb.de>
---
include/uapi/asm-generic/unistd.h | 4 ++--
tools/include/uapi/asm-generic/unistd.h | 4 ++--
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/include/uapi/asm-generic/unistd.h b/include/uapi/asm-generic/unistd.h
index 4557a8b6086f..aafe5cfeb27c 100644
--- a/include/uapi/asm-generic/unistd.h
+++ b/include/uapi/asm-generic/unistd.h @@ -383,7 +383,7 @@ __SYSCALL(__NR_syslog, sys_syslog)
/* kernel/ptrace.c */
#define __NR_ptrace 117
- __SYSCALL ( __NR_ptrace , sys_ptrace )
+ __SC_COMP ( __NR_ptrace , sys_ptrace , compat_sys_ptrace )
/* kernel/sched/core.c */
#define __NR_sched_setparam 118 @@ -779,7 +779,7 @@ __SYSCALL(__NR_rseq, sys_rseq)
#define __NR_kexec_file_load 294
__SYSCALL ( __NR_kexec_file_load , sys_kexec_file_load )
/* 295 through 402 are unassigned to sync up with generic numbers, don't use */
- #if __BITS_PER_LONG == 32
+ #if defined(__SYSCALL_COMPAT) || __BITS_PER_LONG == 32
#define __NR_clock_gettime64 403
__SYSCALL ( __NR_clock_gettime64 , sys_clock_gettime )
#define __NR_clock_settime64 404 diff --git a/tools/include/uapi/asm-generic/unistd.h b/tools/include/uapi/asm-generic/unistd.h
index 4557a8b6086f..aafe5cfeb27c 100644
--- a/tools/include/uapi/asm-generic/unistd.h
+++ b/tools/include/uapi/asm-generic/unistd.h @@ -383,7 +383,7 @@ __SYSCALL(__NR_syslog, sys_syslog)
/* kernel/ptrace.c */
#define __NR_ptrace 117
- __SYSCALL ( __NR_ptrace , sys_ptrace )
+ __SC_COMP ( __NR_ptrace , sys_ptrace , compat_sys_ptrace )
/* kernel/sched/core.c */
#define __NR_sched_setparam 118 @@ -779,7 +779,7 @@ __SYSCALL(__NR_rseq, sys_rseq)
#define __NR_kexec_file_load 294
__SYSCALL ( __NR_kexec_file_load , sys_kexec_file_load )
/* 295 through 402 are unassigned to sync up with generic numbers, don't use */
- #if __BITS_PER_LONG == 32
+ #if defined(__SYSCALL_COMPAT) || __BITS_PER_LONG == 32
#define __NR_clock_gettime64 403
__SYSCALL ( __NR_clock_gettime64 , sys_clock_gettime )
#define __NR_clock_settime64 404 --
2.25.1
From: Guo Ren <redacted>
Let's follow the origin patch's spirit:
The only difference between rv32_defconfig and defconfig is that
rv32_defconfig has CONFIG_ARCH_RV32I=y.
This is helpful to compare rv64-compat-rv32 v.s. rv32-linux.
Fixes: 1b937e8faa87ccfb ("RISC-V: Add separate defconfig for 32bit systems")
Signed-off-by: Guo Ren <redacted>
Signed-off-by: Guo Ren <guoren@kernel.org>
Cc: Anup Patel <redacted>
Cc: Palmer Dabbelt <palmer@dabbelt.com>
---
arch/riscv/Makefile | 4 +
arch/riscv/configs/rv32_defconfig | 135 ------------------------------
2 files changed, 4 insertions(+), 135 deletions(-)
delete mode 100644 arch/riscv/configs/rv32_defconfig
diff --git a/arch/riscv/Makefile b/arch/riscv/Makefile
index 8a107ed18b0d..a02e588c4947 100644
--- a/arch/riscv/Makefile
+++ b/arch/riscv/Makefile @@ -148,3 +148,7 @@ PHONY += rv64_randconfig
rv64_randconfig :
$( Q)$( MAKE) KCONFIG_ALLCONFIG = $( srctree) /arch/riscv/configs/64-bit.config \
-f $( srctree) /Makefile randconfig
+
+ PHONY += rv32_defconfig
+ rv32_defconfig :
+ $( Q)$( MAKE) -f $( srctree) /Makefile defconfig 32 -bit.configdiff --git a/arch/riscv/configs/rv32_defconfig b/arch/riscv/configs/rv32_defconfig
deleted file mode 100644
index 6e9f12ff968a..000000000000
--- a/arch/riscv/configs/rv32_defconfig
+++ /dev/null @@ -1,135 +0,0 @@
- CONFIG_SYSVIPC=y
- CONFIG_POSIX_MQUEUE=y
- CONFIG_NO_HZ_IDLE=y
- CONFIG_HIGH_RES_TIMERS=y
- CONFIG_IKCONFIG=y
- CONFIG_IKCONFIG_PROC=y
- CONFIG_CGROUPS=y
- CONFIG_CGROUP_SCHED=y
- CONFIG_CFS_BANDWIDTH=y
- CONFIG_CGROUP_BPF=y
- CONFIG_NAMESPACES=y
- CONFIG_USER_NS=y
- CONFIG_CHECKPOINT_RESTORE=y
- CONFIG_BLK_DEV_INITRD=y
- CONFIG_EXPERT=y
- CONFIG_BPF_SYSCALL=y
- CONFIG_SOC_SIFIVE=y
- CONFIG_SOC_VIRT=y
- CONFIG_ARCH_RV32I=y
- CONFIG_SMP=y
- CONFIG_HOTPLUG_CPU=y
- CONFIG_VIRTUALIZATION=y
- CONFIG_KVM=m
- CONFIG_JUMP_LABEL=y
- CONFIG_MODULES=y
- CONFIG_MODULE_UNLOAD=y
- CONFIG_NET=y
- CONFIG_PACKET=y
- CONFIG_UNIX=y
- CONFIG_INET=y
- CONFIG_IP_MULTICAST=y
- CONFIG_IP_ADVANCED_ROUTER=y
- CONFIG_IP_PNP=y
- CONFIG_IP_PNP_DHCP=y
- CONFIG_IP_PNP_BOOTP=y
- CONFIG_IP_PNP_RARP=y
- CONFIG_NETLINK_DIAG=y
- CONFIG_NET_9P=y
- CONFIG_NET_9P_VIRTIO=y
- CONFIG_PCI=y
- CONFIG_PCIEPORTBUS=y
- CONFIG_PCI_HOST_GENERIC=y
- CONFIG_PCIE_XILINX=y
- CONFIG_DEVTMPFS=y
- CONFIG_DEVTMPFS_MOUNT=y
- CONFIG_BLK_DEV_LOOP=y
- CONFIG_VIRTIO_BLK=y
- CONFIG_BLK_DEV_SD=y
- CONFIG_BLK_DEV_SR=y
- CONFIG_SCSI_VIRTIO=y
- CONFIG_ATA=y
- CONFIG_SATA_AHCI=y
- CONFIG_SATA_AHCI_PLATFORM=y
- CONFIG_NETDEVICES=y
- CONFIG_VIRTIO_NET=y
- CONFIG_MACB=y
- CONFIG_E1000E=y
- CONFIG_R8169=y
- CONFIG_MICROSEMI_PHY=y
- CONFIG_INPUT_MOUSEDEV=y
- CONFIG_SERIAL_8250=y
- CONFIG_SERIAL_8250_CONSOLE=y
- CONFIG_SERIAL_OF_PLATFORM=y
- CONFIG_SERIAL_EARLYCON_RISCV_SBI=y
- CONFIG_HVC_RISCV_SBI=y
- CONFIG_VIRTIO_CONSOLE=y
- CONFIG_HW_RANDOM=y
- CONFIG_HW_RANDOM_VIRTIO=y
- CONFIG_SPI=y
- CONFIG_SPI_SIFIVE=y
- # CONFIG_PTP_1588_CLOCK is not set
- CONFIG_POWER_RESET=y
- CONFIG_DRM=y
- CONFIG_DRM_RADEON=y
- CONFIG_DRM_VIRTIO_GPU=y
- CONFIG_FRAMEBUFFER_CONSOLE=y
- CONFIG_USB=y
- CONFIG_USB_XHCI_HCD=y
- CONFIG_USB_XHCI_PLATFORM=y
- CONFIG_USB_EHCI_HCD=y
- CONFIG_USB_EHCI_HCD_PLATFORM=y
- CONFIG_USB_OHCI_HCD=y
- CONFIG_USB_OHCI_HCD_PLATFORM=y
- CONFIG_USB_STORAGE=y
- CONFIG_USB_UAS=y
- CONFIG_MMC=y
- CONFIG_MMC_SPI=y
- CONFIG_RTC_CLASS=y
- CONFIG_VIRTIO_PCI=y
- CONFIG_VIRTIO_BALLOON=y
- CONFIG_VIRTIO_INPUT=y
- CONFIG_VIRTIO_MMIO=y
- CONFIG_RPMSG_CHAR=y
- CONFIG_RPMSG_VIRTIO=y
- CONFIG_EXT4_FS=y
- CONFIG_EXT4_FS_POSIX_ACL=y
- CONFIG_AUTOFS4_FS=y
- CONFIG_MSDOS_FS=y
- CONFIG_VFAT_FS=y
- CONFIG_TMPFS=y
- CONFIG_TMPFS_POSIX_ACL=y
- CONFIG_NFS_FS=y
- CONFIG_NFS_V4=y
- CONFIG_NFS_V4_1=y
- CONFIG_NFS_V4_2=y
- CONFIG_ROOT_NFS=y
- CONFIG_9P_FS=y
- CONFIG_CRYPTO_USER_API_HASH=y
- CONFIG_CRYPTO_DEV_VIRTIO=y
- CONFIG_PRINTK_TIME=y
- CONFIG_DEBUG_FS=y
- CONFIG_DEBUG_PAGEALLOC=y
- CONFIG_SCHED_STACK_END_CHECK=y
- CONFIG_DEBUG_VM=y
- CONFIG_DEBUG_VM_PGFLAGS=y
- CONFIG_DEBUG_MEMORY_INIT=y
- CONFIG_DEBUG_PER_CPU_MAPS=y
- CONFIG_SOFTLOCKUP_DETECTOR=y
- CONFIG_WQ_WATCHDOG=y
- CONFIG_DEBUG_TIMEKEEPING=y
- CONFIG_DEBUG_RT_MUTEXES=y
- CONFIG_DEBUG_SPINLOCK=y
- CONFIG_DEBUG_MUTEXES=y
- CONFIG_DEBUG_RWSEMS=y
- CONFIG_DEBUG_ATOMIC_SLEEP=y
- CONFIG_STACKTRACE=y
- CONFIG_DEBUG_LIST=y
- CONFIG_DEBUG_PLIST=y
- CONFIG_DEBUG_SG=y
- # CONFIG_RCU_TRACE is not set
- CONFIG_RCU_EQS_DEBUG=y
- # CONFIG_FTRACE is not set
- # CONFIG_RUNTIME_TESTING_MENU is not set
- CONFIG_MEMTEST=y
- # CONFIG_SYSFS_SYSCALL is not set--
2.25.1
From: Guo Ren <redacted>
Implement asm/compat.h for struct compat_xxx, RLIM_INFINITY,
OFF_T_MAX, is_compat_task, compat_user_regset, regset convert.
Signed-off-by: Guo Ren <redacted>
Signed-off-by: Guo Ren <guoren@kernel.org>
Cc: Arnd Bergmann <arnd@arndb.de>
---
arch/riscv/include/asm/compat.h | 132 +++++++++++++++++++++++++++
arch/riscv/include/asm/thread_info.h | 1 +
2 files changed, 133 insertions(+)
create mode 100644 arch/riscv/include/asm/compat.h
diff --git a/arch/riscv/include/asm/compat.h b/arch/riscv/include/asm/compat.h
new file mode 100644
index 000000000000..dcfd44fd2e21
--- /dev/null
+++ b/arch/riscv/include/asm/compat.h @@ -0,0 +1,132 @@
+ /* SPDX-License-Identifier: GPL-2.0-only */
+ #ifndef __ASM_COMPAT_H
+ #define __ASM_COMPAT_H
+
+ #define compat_mode_t compat_mode_t
+ typedef u16 compat_mode_t ;
+
+ #define COMPAT_UTS_MACHINE "riscv\0\0"
+
+ /*
+ * Architecture specific compatibility types
+ */
+ #include <linux/types.h>
+ #include <linux/sched.h>
+ #include <linux/sched/task_stack.h>
+ #include <asm-generic/compat.h>
+
+ static inline int is_compat_task ( void )
+ {
+ return test_thread_flag ( TIF_32BIT );
+ }
+
+ struct compat_user_regs_struct {
+ compat_ulong_t pc ;
+ compat_ulong_t ra ;
+ compat_ulong_t sp ;
+ compat_ulong_t gp ;
+ compat_ulong_t tp ;
+ compat_ulong_t t0 ;
+ compat_ulong_t t1 ;
+ compat_ulong_t t2 ;
+ compat_ulong_t s0 ;
+ compat_ulong_t s1 ;
+ compat_ulong_t a0 ;
+ compat_ulong_t a1 ;
+ compat_ulong_t a2 ;
+ compat_ulong_t a3 ;
+ compat_ulong_t a4 ;
+ compat_ulong_t a5 ;
+ compat_ulong_t a6 ;
+ compat_ulong_t a7 ;
+ compat_ulong_t s2 ;
+ compat_ulong_t s3 ;
+ compat_ulong_t s4 ;
+ compat_ulong_t s5 ;
+ compat_ulong_t s6 ;
+ compat_ulong_t s7 ;
+ compat_ulong_t s8 ;
+ compat_ulong_t s9 ;
+ compat_ulong_t s10 ;
+ compat_ulong_t s11 ;
+ compat_ulong_t t3 ;
+ compat_ulong_t t4 ;
+ compat_ulong_t t5 ;
+ compat_ulong_t t6 ;
+ };
+
+ static inline void regs_to_cregs ( struct compat_user_regs_struct * cregs ,
+ struct pt_regs * regs )
+ {
+ cregs -> pc = ( compat_ulong_t ) regs -> epc ;
+ cregs -> ra = ( compat_ulong_t ) regs -> ra ;
+ cregs -> sp = ( compat_ulong_t ) regs -> sp ;
+ cregs -> gp = ( compat_ulong_t ) regs -> gp ;
+ cregs -> tp = ( compat_ulong_t ) regs -> tp ;
+ cregs -> t0 = ( compat_ulong_t ) regs -> t0 ;
+ cregs -> t1 = ( compat_ulong_t ) regs -> t1 ;
+ cregs -> t2 = ( compat_ulong_t ) regs -> t2 ;
+ cregs -> s0 = ( compat_ulong_t ) regs -> s0 ;
+ cregs -> s1 = ( compat_ulong_t ) regs -> s1 ;
+ cregs -> a0 = ( compat_ulong_t ) regs -> a0 ;
+ cregs -> a1 = ( compat_ulong_t ) regs -> a1 ;
+ cregs -> a2 = ( compat_ulong_t ) regs -> a2 ;
+ cregs -> a3 = ( compat_ulong_t ) regs -> a3 ;
+ cregs -> a4 = ( compat_ulong_t ) regs -> a4 ;
+ cregs -> a5 = ( compat_ulong_t ) regs -> a5 ;
+ cregs -> a6 = ( compat_ulong_t ) regs -> a6 ;
+ cregs -> a7 = ( compat_ulong_t ) regs -> a7 ;
+ cregs -> s2 = ( compat_ulong_t ) regs -> s2 ;
+ cregs -> s3 = ( compat_ulong_t ) regs -> s3 ;
+ cregs -> s4 = ( compat_ulong_t ) regs -> s4 ;
+ cregs -> s5 = ( compat_ulong_t ) regs -> s5 ;
+ cregs -> s6 = ( compat_ulong_t ) regs -> s6 ;
+ cregs -> s7 = ( compat_ulong_t ) regs -> s7 ;
+ cregs -> s8 = ( compat_ulong_t ) regs -> s8 ;
+ cregs -> s9 = ( compat_ulong_t ) regs -> s9 ;
+ cregs -> s10 = ( compat_ulong_t ) regs -> s10 ;
+ cregs -> s11 = ( compat_ulong_t ) regs -> s11 ;
+ cregs -> t3 = ( compat_ulong_t ) regs -> t3 ;
+ cregs -> t4 = ( compat_ulong_t ) regs -> t4 ;
+ cregs -> t5 = ( compat_ulong_t ) regs -> t5 ;
+ cregs -> t6 = ( compat_ulong_t ) regs -> t6 ;
+ };
+
+ static inline void cregs_to_regs ( struct compat_user_regs_struct * cregs ,
+ struct pt_regs * regs )
+ {
+ regs -> epc = ( unsigned long ) cregs -> pc ;
+ regs -> ra = ( unsigned long ) cregs -> ra ;
+ regs -> sp = ( unsigned long ) cregs -> sp ;
+ regs -> gp = ( unsigned long ) cregs -> gp ;
+ regs -> tp = ( unsigned long ) cregs -> tp ;
+ regs -> t0 = ( unsigned long ) cregs -> t0 ;
+ regs -> t1 = ( unsigned long ) cregs -> t1 ;
+ regs -> t2 = ( unsigned long ) cregs -> t2 ;
+ regs -> s0 = ( unsigned long ) cregs -> s0 ;
+ regs -> s1 = ( unsigned long ) cregs -> s1 ;
+ regs -> a0 = ( unsigned long ) cregs -> a0 ;
+ regs -> a1 = ( unsigned long ) cregs -> a1 ;
+ regs -> a2 = ( unsigned long ) cregs -> a2 ;
+ regs -> a3 = ( unsigned long ) cregs -> a3 ;
+ regs -> a4 = ( unsigned long ) cregs -> a4 ;
+ regs -> a5 = ( unsigned long ) cregs -> a5 ;
+ regs -> a6 = ( unsigned long ) cregs -> a6 ;
+ regs -> a7 = ( unsigned long ) cregs -> a7 ;
+ regs -> s2 = ( unsigned long ) cregs -> s2 ;
+ regs -> s3 = ( unsigned long ) cregs -> s3 ;
+ regs -> s4 = ( unsigned long ) cregs -> s4 ;
+ regs -> s5 = ( unsigned long ) cregs -> s5 ;
+ regs -> s6 = ( unsigned long ) cregs -> s6 ;
+ regs -> s7 = ( unsigned long ) cregs -> s7 ;
+ regs -> s8 = ( unsigned long ) cregs -> s8 ;
+ regs -> s9 = ( unsigned long ) cregs -> s9 ;
+ regs -> s10 = ( unsigned long ) cregs -> s10 ;
+ regs -> s11 = ( unsigned long ) cregs -> s11 ;
+ regs -> t3 = ( unsigned long ) cregs -> t3 ;
+ regs -> t4 = ( unsigned long ) cregs -> t4 ;
+ regs -> t5 = ( unsigned long ) cregs -> t5 ;
+ regs -> t6 = ( unsigned long ) cregs -> t6 ;
+ };
+
+ #endif /* __ASM_COMPAT_H */ diff --git a/arch/riscv/include/asm/thread_info.h b/arch/riscv/include/asm/thread_info.h
index 60da0dcacf14..9392e35c689d 100644
--- a/arch/riscv/include/asm/thread_info.h
+++ b/arch/riscv/include/asm/thread_info.h @@ -91,6 +91,7 @@ struct thread_info {
#define TIF_SECCOMP 8 /* syscall secure computing */
#define TIF_NOTIFY_SIGNAL 9 /* signal notifications exist */
#define TIF_UPROBE 10 /* uprobe breakpoint or singlestep */
+ #define TIF_32BIT 11 /* 32bit process */
#define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE)
#define _TIF_NOTIFY_RESUME (1 << TIF_NOTIFY_RESUME) --
2.25.1
From: Guo Ren <redacted>
Make TASK_SIZE from const to dynamic detect TIF_32BIT flag
function. Refer to arm64 to implement DEFAULT_MAP_WINDOW_64 for
efi-stub.
Limit 32-bit compatible process in 0-2GB virtual address range
(which is enough for real scenarios), because it could avoid
address sign extend problem when 32-bit enter 64-bit and ease
software design.
The standard 32-bit TASK_SIZE is 0x9dc00000:FIXADDR_START, and
compared to a compatible 32-bit, it increases 476MB for the
application's virtual address.
Signed-off-by: Guo Ren <redacted>
Signed-off-by: Guo Ren <guoren@kernel.org>
Cc: Arnd Bergmann <arnd@arndb.de>
---
arch/riscv/include/asm/pgtable.h | 11 ++++++++++-
arch/riscv/include/asm/processor.h | 6 ++++++
drivers/firmware/efi/libstub/efi-stub.c | 2 +-
3 files changed, 17 insertions(+), 2 deletions(-)
diff --git a/arch/riscv/include/asm/pgtable.h b/arch/riscv/include/asm/pgtable.h
index bf204e7c1f74..2dd5b8674380 100644
--- a/arch/riscv/include/asm/pgtable.h
+++ b/arch/riscv/include/asm/pgtable.h @@ -663,7 +663,16 @@ static inline pmd_t pmdp_establish(struct vm_area_struct *vma,
* Note that PGDIR_SIZE must evenly divide TASK_SIZE .
*/
#ifdef CONFIG_64BIT
- #define TASK_SIZE (PGDIR_SIZE * PTRS_PER_PGD / 2)
+ #define TASK_SIZE_64 (PGDIR_SIZE * 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
#define TASK_SIZE FIXADDR_START
#endif diff --git a/arch/riscv/include/asm/processor.h b/arch/riscv/include/asm/processor.h
index 0749924d9e55..8649436b8fcf 100644
--- a/arch/riscv/include/asm/processor.h
+++ b/arch/riscv/include/asm/processor.h @@ -61,6 +61,12 @@ static inline void arch_thread_struct_whitelist(unsigned long *offset,
extern void start_thread ( struct pt_regs * regs ,
unsigned long pc , unsigned long sp );
+ #ifdef CONFIG_COMPAT
+ #define DEFAULT_MAP_WINDOW_64 TASK_SIZE_64
+ #else
+ #define DEFAULT_MAP_WINDOW_64 TASK_SIZE
+ #endif
+
/* Free all resources held by a thread. */
static inline void release_thread ( struct task_struct * dead_task )
{ diff --git a/drivers/firmware/efi/libstub/efi-stub.c b/drivers/firmware/efi/libstub/efi-stub.c
index 26e69788f27a..4075fd19d219 100644
--- a/drivers/firmware/efi/libstub/efi-stub.c
+++ b/drivers/firmware/efi/libstub/efi-stub.c @@ -38,7 +38,7 @@
#define EFI_RT_VIRTUAL_BASE SZ_512M
#define EFI_RT_VIRTUAL_SIZE SZ_512M
- #ifdef CONFIG_ARM64
+ #if defined(CONFIG_ARM64) || defined(CONFIG_RISCV)
# define EFI_RT_VIRTUAL_LIMIT DEFAULT_MAP_WINDOW_64
#else
# define EFI_RT_VIRTUAL_LIMIT TASK_SIZE --
2.25.1
From: Guo Ren <redacted>
Implement compat_syscall_table.c with compat_sys_call_table & fixup
system call such as truncate64,pread64,fallocate which need two
regs to indicate 64bit-arg (copied from arm64).
Signed-off-by: Guo Ren <redacted>
Signed-off-by: Guo Ren <guoren@kernel.org>
Cc: Arnd Bergmann <arnd@arndb.de>
---
arch/riscv/include/asm/syscall.h | 3 +
arch/riscv/include/uapi/asm/unistd.h | 2 +-
arch/riscv/kernel/Makefile | 1 +
arch/riscv/kernel/compat_syscall_table.c | 72 ++++++++++++++++++++++++
arch/riscv/kernel/sys_riscv.c | 6 +-
5 files changed, 81 insertions(+), 3 deletions(-)
create mode 100644 arch/riscv/kernel/compat_syscall_table.c
diff --git a/arch/riscv/include/asm/syscall.h b/arch/riscv/include/asm/syscall.h
index 7ac6a0e275f2..4ff98a22ef24 100644
--- a/arch/riscv/include/asm/syscall.h
+++ b/arch/riscv/include/asm/syscall.h @@ -16,6 +16,9 @@
/* The array of function pointers for syscalls. */
extern void * const sys_call_table [];
+ #ifdef CONFIG_COMPAT
+ extern void * const compat_sys_call_table [];
+ #endif
/*
* Only the low 32 bits of orig_r0 are meaningful , so we return int . diff --git a/arch/riscv/include/uapi/asm/unistd.h b/arch/riscv/include/uapi/asm/unistd.h
index 8062996c2dfd..c9e50eed14aa 100644
--- a/arch/riscv/include/uapi/asm/unistd.h
+++ b/arch/riscv/include/uapi/asm/unistd.h @@ -15,7 +15,7 @@
* along with this program . If not , see < https : //www.gnu.org/licenses/>.
*/
- #ifdef __LP64__
+ #if defined(__LP64__) && !defined(__SYSCALL_COMPAT)
#define __ARCH_WANT_NEW_STAT
#define __ARCH_WANT_SET_GET_RLIMIT
#endif /* __LP64__ */ diff --git a/arch/riscv/kernel/Makefile b/arch/riscv/kernel/Makefile
index 3397ddac1a30..1f2111179615 100644
--- a/arch/riscv/kernel/Makefile
+++ b/arch/riscv/kernel/Makefile @@ -65,3 +65,4 @@ obj-$(CONFIG_CRASH_DUMP) += crash_dump.o
obj-$(CONFIG_JUMP_LABEL) += jump_label.o
obj-$(CONFIG_EFI) += efi.o
+ obj-$(CONFIG_COMPAT) += compat_syscall_table.odiff --git a/arch/riscv/kernel/compat_syscall_table.c b/arch/riscv/kernel/compat_syscall_table.c
new file mode 100644
index 000000000000..53905947678e
--- /dev/null
+++ b/arch/riscv/kernel/compat_syscall_table.c @@ -0,0 +1,72 @@
+ // SPDX-License-Identifier: GPL-2.0-only
+
+ #define __SYSCALL_COMPAT
+
+ #include <linux/compat.h>
+ #include <linux/syscalls.h>
+ #include <asm-generic/mman-common.h>
+ #include <asm-generic/syscalls.h>
+ #include <asm/syscall.h>
+
+ #define arg_u32p(name) u32, name##_lo, u32, name##_hi
+
+ #define arg_u64(name) (((u64)name##_hi << 32) | \
+ (( u64 ) name ## _lo & 0xffffffff ))
+
+ COMPAT_SYSCALL_DEFINE3 ( truncate64 , const char __user * , pathname ,
+ arg_u32p ( length ))
+ {
+ return ksys_truncate ( pathname , arg_u64 ( length ));
+ }
+
+ COMPAT_SYSCALL_DEFINE3 ( ftruncate64 , unsigned int , fd , arg_u32p ( length ))
+ {
+ return ksys_ftruncate ( fd , arg_u64 ( length ));
+ }
+
+ COMPAT_SYSCALL_DEFINE6 ( fallocate , int , fd , int , mode ,
+ arg_u32p ( offset ), arg_u32p ( len ))
+ {
+ return ksys_fallocate ( fd , mode , arg_u64 ( offset ), arg_u64 ( len ));
+ }
+
+ COMPAT_SYSCALL_DEFINE5 ( pread64 , unsigned int , fd , char __user * , buf ,
+ size_t , count , arg_u32p ( pos ))
+ {
+ return ksys_pread64 ( fd , buf , count , arg_u64 ( pos ));
+ }
+
+ COMPAT_SYSCALL_DEFINE5 ( pwrite64 , unsigned int , fd ,
+ const char __user * , buf , size_t , count , arg_u32p ( pos ))
+ {
+ return ksys_pwrite64 ( fd , buf , count , arg_u64 ( pos ));
+ }
+
+ COMPAT_SYSCALL_DEFINE6 ( sync_file_range , int , fd , arg_u32p ( offset ),
+ arg_u32p ( nbytes ), unsigned int , flags )
+ {
+ return ksys_sync_file_range ( fd , arg_u64 ( offset ), arg_u64 ( nbytes ),
+ flags );
+ }
+
+ COMPAT_SYSCALL_DEFINE4 ( readahead , int , fd , arg_u32p ( offset ),
+ size_t , count )
+ {
+ return ksys_readahead ( fd , arg_u64 ( offset ), count );
+ }
+
+ COMPAT_SYSCALL_DEFINE6 ( fadvise64_64 , int , fd , int , advice , arg_u32p ( offset ),
+ arg_u32p ( len ))
+ {
+ return ksys_fadvise64_64 ( fd , arg_u64 ( offset ), arg_u64 ( len ), advice );
+ }
+
+ #undef __SYSCALL
+ #define __SYSCALL(nr, call) [nr] = (call),
+
+ asmlinkage long compat_sys_rt_sigreturn ( void );
+
+ void * const compat_sys_call_table [ __NR_syscalls ] = {
+ [ 0 ... __NR_syscalls - 1 ] = sys_ni_syscall ,
+ #include <asm/unistd.h>
+ }; diff --git a/arch/riscv/kernel/sys_riscv.c b/arch/riscv/kernel/sys_riscv.c
index 12f8a7fce78b..9c0194f176fc 100644
--- a/arch/riscv/kernel/sys_riscv.c
+++ b/arch/riscv/kernel/sys_riscv.c @@ -33,7 +33,9 @@ SYSCALL_DEFINE6(mmap, unsigned long, addr, unsigned long, len,
{
return riscv_sys_mmap ( addr , len , prot , flags , fd , offset , 0 );
}
- #else
+ #endif
+
+ #if defined(CONFIG_32BIT) || defined(CONFIG_COMPAT)
SYSCALL_DEFINE6 ( mmap2 , unsigned long , addr , unsigned long , len ,
unsigned long , prot , unsigned long , flags ,
unsigned long , fd , off_t , offset ) @@ -44,7 +46,7 @@ SYSCALL_DEFINE6(mmap2, unsigned long, addr, unsigned long, len,
*/
return riscv_sys_mmap ( addr , len , prot , flags , fd , offset , 12 );
}
- #endif /* !CONFIG_64BIT */
+ #endif
/*
* Allows the instruction cache to be flushed from userspace . Despite RISC - V --
2.25.1
From: Guo Ren <redacted>
Implement the entry of compat_sys_call_table[] in asm. Ref to
riscv-privileged spec 4.1.1 Supervisor Status Register (sstatus):
BIT[32:33] = UXL[1:0]:
- 1:32
- 2:64
- 3:128
Signed-off-by: Guo Ren <redacted>
Signed-off-by: Guo Ren <guoren@kernel.org>
Cc: Arnd Bergmann <arnd@arndb.de>
---
arch/riscv/include/asm/csr.h | 7 +++++++
arch/riscv/kernel/entry.S | 18 ++++++++++++++++--
2 files changed, 23 insertions(+), 2 deletions(-)
diff --git a/arch/riscv/include/asm/csr.h b/arch/riscv/include/asm/csr.h
index 5046f431645c..7dac12366833 100644
--- a/arch/riscv/include/asm/csr.h
+++ b/arch/riscv/include/asm/csr.h @@ -36,6 +36,13 @@
#define SR_SD _AC(0x8000000000000000, UL) /* FS/XS dirty */
#endif
+ #ifdef CONFIG_COMPAT
+ #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_SHIFT 32
+ #endif
+
/* SATP flags */
#ifndef CONFIG_64BIT
#define SATP_PPN _AC(0x003FFFFF, UL) diff --git a/arch/riscv/kernel/entry.S b/arch/riscv/kernel/entry.S
index ed29e9c8f660..1951743f09b3 100644
--- a/arch/riscv/kernel/entry.S
+++ b/arch/riscv/kernel/entry.S @@ -207,13 +207,27 @@ check_syscall_nr:
* Syscall number held in a7.
* If syscall number is above allowed value , redirect to ni_syscall.
*/
- bgeu a7 , t0 , 1 f
+ bgeu a7 , t0 , 3 f
+ #ifdef CONFIG_COMPAT
+ REG_L s0 , PT_STATUS ( sp )
+ srli s0 , s0 , SR_UXL_SHIFT
+ andi s0 , s0 , ( SR_UXL >> SR_UXL_SHIFT )
+ li t0 , ( SR_UXL_32 >> SR_UXL_SHIFT )
+ sub t0 , s0 , t0
+ bnez t0 , 1 f
+
+ /* Call compat_syscall */
+ la s0 , compat_sys_call_table
+ j 2 f
+ 1 :
+ #endif
/* Call syscall */
la s0 , sys_call_table
+ 2 :
slli t0 , a7 , RISCV_LGPTR
add s0 , s0 , t0
REG_L s0 , 0 ( s0 )
- 1 :
+ 3 :
jalr s0
ret_from_syscall : --
2.25.1
From: Guo Ren <redacted>
Implement necessary type and macro for compat elf. See the code
comment for detail.
Signed-off-by: Guo Ren <redacted>
Signed-off-by: Guo Ren <guoren@kernel.org>
Cc: Arnd Bergmann <arnd@arndb.de>
---
arch/riscv/include/asm/elf.h | 49 +++++++++++++++++++++++++++++++++++-
1 file changed, 48 insertions(+), 1 deletion(-)
diff --git a/arch/riscv/include/asm/elf.h b/arch/riscv/include/asm/elf.h
index f53c40026c7a..91b372d4e13b 100644
--- a/arch/riscv/include/asm/elf.h
+++ b/arch/riscv/include/asm/elf.h @@ -8,6 +8,8 @@
#ifndef _ASM_RISCV_ELF_H
#define _ASM_RISCV_ELF_H
+ #include <uapi/linux/elf.h>
+ #include <linux/compat.h>
#include <uapi/asm/elf.h>
#include <asm/auxvec.h>
#include <asm/byteorder.h> @@ -18,11 +20,13 @@
*/
#define ELF_ARCH EM_RISCV
+ #ifndef ELF_CLASS
#ifdef CONFIG_64BIT
#define ELF_CLASS ELFCLASS64
#else
#define ELF_CLASS ELFCLASS32
#endif
+ #endif
#define ELF_DATA ELFDATA2LSB
@@ -31,6 +35,15 @@
*/
#define elf_check_arch(x) ((x)->e_machine == EM_RISCV)
+ #ifdef CONFIG_COMPAT
+ /*
+ * Use the same code with elf_check_arch , because elf32_hdr &
+ * elf64_hdr e_machine ' s offset are different . The checker is
+ * a little bit simple compare to other architectures .
+ */
+ #define compat_elf_check_arch(x) ((x)->e_machine == EM_RISCV)
+ #endif
+
#define CORE_DUMP_USE_REGSET
#define ELF_EXEC_PAGESIZE (PAGE_SIZE)
@@ -43,8 +56,14 @@
#define ELF_ET_DYN_BASE ((TASK_SIZE / 3) * 2)
#ifdef CONFIG_64BIT
+ #ifdef CONFIG_COMPAT
+ #define STACK_RND_MASK (test_thread_flag(TIF_32BIT) ? \
+ 0x7ff >> ( PAGE_SHIFT - 12 ) : \
+ 0x3ffff >> ( PAGE_SHIFT - 12 ))
+ #else
#define STACK_RND_MASK (0x3ffff >> (PAGE_SHIFT - 12))
#endif
+ #endif
/*
* This yields a mask that user programs can use to figure out what
* instruction set this CPU supports . This could be done in user space , @@ -60,11 +79,19 @@ extern unsigned long elf_hwcap;
*/
#define ELF_PLATFORM (NULL)
+ #define COMPAT_ELF_PLATFORM (NULL)
+
#ifdef CONFIG_MMU
#define ARCH_DLINFO \
do { \
+ /* \
+ * Note that we add ulong after elf_addr_t because \
+ * casting current -> mm -> context . vdso triggers a cast \
+ * warning of cast from pointer to integer for \
+ * COMPAT ELFCLASS32 . \
+ */ \
NEW_AUX_ENT ( AT_SYSINFO_EHDR , \
- ( elf_addr_t ) current -> mm -> context . vdso ); \
+ ( elf_addr_t )( ulong ) current -> mm -> context . vdso ); \
NEW_AUX_ENT ( AT_L1I_CACHESIZE , \
get_cache_size ( 1 , CACHE_TYPE_INST )); \
NEW_AUX_ENT ( AT_L1I_CACHEGEOMETRY , \ @@ -90,4 +117,24 @@ do { \
* ( struct user_regs_struct * ) regs ; \
} while ( 0 );
+ #ifdef CONFIG_COMPAT
+
+ /*
+ * FIXME : not sure SET_PERSONALITY for compat process is right !
+ */
+ #define SET_PERSONALITY(ex) \
+ do { if (( ex ). e_ident [ EI_CLASS ] == ELFCLASS32 ) \
+ set_thread_flag ( TIF_32BIT ); \
+ else \
+ clear_thread_flag ( TIF_32BIT ); \
+ set_personality ( PER_LINUX | ( current -> personality & ( ~ PER_MASK ))); \
+ } while ( 0 )
+
+ #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 ];
+
+ #endif /* CONFIG_COMPAT */
#endif /* _ASM_RISCV_ELF_H */ --
2.25.1
From: Guo Ren <redacted>
There is no vgettimeofday supported in rv32 that makes simple to
generate rv32 vdso code which only needs riscv64 compiler. Other
architectures need change compiler or -m (machine parameter) to
support vdso32 compiling. If rv32 support vgettimeofday (which
cause C compile) in future, we would add CROSS_COMPILE to support
that makes more requirement on compiler enviornment.
linux-rv64/arch/riscv/kernel/compat_vdso/compat_vdso.so.dbg:
file format elf64-littleriscv
Disassembly of section .text:
0000000000000800 <__vdso_rt_sigreturn>:
800: 08b00893 li a7,139
804: 00000073 ecall
808: 0000 unimp
...
000000000000080c <__vdso_getcpu>:
80c: 0a800893 li a7,168
810: 00000073 ecall
814: 8082 ret
...
0000000000000818 <__vdso_flush_icache>:
818: 10300893 li a7,259
81c: 00000073 ecall
820: 8082 ret
linux-rv32/arch/riscv/kernel/vdso/vdso.so.dbg:
file format elf32-littleriscv
Disassembly of section .text:
00000800 <__vdso_rt_sigreturn>:
800: 08b00893 li a7,139
804: 00000073 ecall
808: 0000 unimp
...
0000080c <__vdso_getcpu>:
80c: 0a800893 li a7,168
810: 00000073 ecall
814: 8082 ret
...
00000818 <__vdso_flush_icache>:
818: 10300893 li a7,259
81c: 00000073 ecall
820: 8082 ret
Finally, reuse all *.S from vdso in compat_vdso that makes
implementation clear and readable.
Signed-off-by: Guo Ren <redacted>
Signed-off-by: Guo Ren <guoren@kernel.org>
Cc: Arnd Bergmann <arnd@arndb.de>
---
arch/riscv/Makefile | 5 ++
arch/riscv/include/asm/vdso.h | 9 +++
arch/riscv/kernel/Makefile | 1 +
arch/riscv/kernel/compat_vdso/.gitignore | 2 +
arch/riscv/kernel/compat_vdso/Makefile | 68 +++++++++++++++++++
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 +
.../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 +
arch/riscv/kernel/vdso/vdso.S | 6 +-
13 files changed, 118 insertions(+), 1 deletion(-)
create mode 100644 arch/riscv/kernel/compat_vdso/.gitignore
create mode 100644 arch/riscv/kernel/compat_vdso/Makefile
create mode 100644 arch/riscv/kernel/compat_vdso/compat_vdso.S
create mode 100644 arch/riscv/kernel/compat_vdso/compat_vdso.lds.S
create mode 100644 arch/riscv/kernel/compat_vdso/flush_icache.S
create mode 100755 arch/riscv/kernel/compat_vdso/gen_compat_vdso_offsets.sh
create mode 100644 arch/riscv/kernel/compat_vdso/getcpu.S
create mode 100644 arch/riscv/kernel/compat_vdso/note.S
create mode 100644 arch/riscv/kernel/compat_vdso/rt_sigreturn.S
diff --git a/arch/riscv/Makefile b/arch/riscv/Makefile
index a02e588c4947..f73d50552e09 100644
--- a/arch/riscv/Makefile
+++ b/arch/riscv/Makefile @@ -106,12 +106,17 @@ 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 $@ )
ifeq ($(KBUILD_EXTMOD),)
ifeq ($(CONFIG_MMU),y)
prepare : vdso_prepare
vdso_prepare : prepare 0
$( 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)
+
endif
endif
diff --git a/arch/riscv/include/asm/vdso.h b/arch/riscv/include/asm/vdso.h
index bc6f75f3a199..af981426fe0f 100644
--- a/arch/riscv/include/asm/vdso.h
+++ b/arch/riscv/include/asm/vdso.h @@ -21,6 +21,15 @@
#define VDSO_SYMBOL(base, name) \
( void __user * )(( unsigned long )( base ) + __vdso_ ## name ## _offset )
+
+ #ifdef CONFIG_COMPAT
+ #include <generated/compat_vdso-offsets.h>
+
+ #define COMPAT_VDSO_SYMBOL(base, name) \
+ ( void __user * )(( unsigned long )( base ) + compat__vdso_ ## name ## _offset )
+
+ #endif /* CONFIG_COMPAT */
+
#endif /* !__ASSEMBLY__ */
#endif /* CONFIG_MMU */ diff --git a/arch/riscv/kernel/Makefile b/arch/riscv/kernel/Makefile
index 1f2111179615..59cf97faddae 100644
--- a/arch/riscv/kernel/Makefile
+++ b/arch/riscv/kernel/Makefile @@ -66,3 +66,4 @@ obj-$(CONFIG_JUMP_LABEL) += jump_label.o
obj-$(CONFIG_EFI) += efi.o
obj-$(CONFIG_COMPAT) += compat_syscall_table.o
+ obj-$(CONFIG_COMPAT) += compat_vdso/diff --git a/arch/riscv/kernel/compat_vdso/.gitignore b/arch/riscv/kernel/compat_vdso/.gitignore
new file mode 100644
index 000000000000..19d83d846c1e
--- /dev/null
+++ b/arch/riscv/kernel/compat_vdso/.gitignore @@ -0,0 +1,2 @@
+ # SPDX-License-Identifier: GPL-2.0-only
+ compat_vdso.ldsdiff --git a/arch/riscv/kernel/compat_vdso/Makefile b/arch/riscv/kernel/compat_vdso/Makefile
new file mode 100644
index 000000000000..7bbbbf94307f
--- /dev/null
+++ b/arch/riscv/kernel/compat_vdso/Makefile @@ -0,0 +1,68 @@
+ # SPDX-License-Identifier: GPL-2.0-only
+
+ # Absolute relocation type $(ARCH_REL_TYPE_ABS) needs to be defined before
+ # the inclusion of generic Makefile.
+ ARCH_REL_TYPE_ABS := R_RISCV_32| R_RISCV_64| R_RISCV_JUMP_SLOT
+ include $(srctree)/lib/vdso/Makefile
+ # Symbols present in the compat_vdso
+ compat_vdso-syms = rt_sigreturn
+ compat_vdso-syms += getcpu
+ compat_vdso-syms += flush_icache
+
+ # Files to link into the compat_vdso
+ obj-compat_vdso = $( patsubst %, %.o, $( compat_vdso-syms)) note.o
+
+ ccflags-y := -fno-stack-protector
+
+ # Build rules
+ targets := $( obj-compat_vdso) compat_vdso.so compat_vdso.so.dbg compat_vdso.lds
+ obj-compat_vdso := $( addprefix $( obj) /, $( obj-compat_vdso))
+
+ obj-y += compat_vdso.o
+ CPPFLAGS_compat_vdso.lds += -P -C -U$( ARCH)
+
+ # Disable profiling and instrumentation for VDSO code
+ GCOV_PROFILE := n
+ KCOV_INSTRUMENT := n
+ KASAN_SANITIZE := n
+ UBSAN_SANITIZE := n
+
+ # Force dependency
+ $(obj)/compat_vdso.o : $( obj ) /compat_vdso .so
+
+ # link rule for the .so file, .lds has to be first
+ $(obj)/compat_vdso.so.dbg : $( obj ) /compat_vdso .lds $( obj-compat_vdso ) FORCE
+ $( call if_changed,compat_vdsold)
+ LDFLAGS_compat_vdso.so.dbg = -shared -S -soname= linux-compat_vdso.so.1 \
+ --build-id= sha1 --hash-style= both --eh-frame-hdr
+
+ # strip rule for the .so file
+ $(obj)/%.so : OBJCOPYFLAGS := -S
+ $(obj)/%.so : $( obj ) /%.so .dbg FORCE
+ $( call if_changed,objcopy)
+
+ # Generate VDSO offsets using helper script
+ gen-compat_vdsosym := $( srctree) /$( src) /gen_compat_vdso_offsets.sh
+ quiet_cmd_compat_vdsosym = VDSOSYM $@
+ cmd_compat_vdsosym = $( NM) $< | $( gen-compat_vdsosym) | LC_ALL = C sort > $@
+
+ include/generated/compat_vdso-offsets.h : $( obj ) /compat_vdso .so .dbg FORCE
+ $( call if_changed,compat_vdsosym)
+
+ # actual build commands
+ # The DSO images are built using a special linker script
+ # Make sure only to export the intended __compat_vdso_xxx symbol offsets.
+ quiet_cmd_compat_vdsold = VDSOLD $@
+ cmd_compat_vdsold = $( LD) $( ld_flags) -T $( filter-out FORCE,$^) -o $@ .tmp && \
+ $( OBJCOPY) $( patsubst %, -G __compat_vdso_%, $( compat_vdso-syms)) $@ .tmp $@ && \
+ rm $@ .tmp
+
+ # install commands for the unstripped file
+ quiet_cmd_compat_vdso_install = INSTALL $@
+ cmd_compat_vdso_install = cp $( obj) /$@ .dbg $( MODLIB) /compat_vdso/$@
+
+ compat_vdso.so : $( obj ) /compat_vdso .so .dbg
+ @mkdir -p $( MODLIB) /compat_vdso
+ $( call cmd,compat_vdso_install)
+
+ compat_vdso_install : compat_vdso .so diff --git a/arch/riscv/kernel/compat_vdso/compat_vdso.S b/arch/riscv/kernel/compat_vdso/compat_vdso.S
new file mode 100644
index 000000000000..fea4a8b0c45d
--- /dev/null
+++ b/arch/riscv/kernel/compat_vdso/compat_vdso.S @@ -0,0 +1,8 @@
+ /* 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
new file mode 100644
index 000000000000..02a9ec5dc7f6
--- /dev/null
+++ b/arch/riscv/kernel/compat_vdso/compat_vdso.lds.S @@ -0,0 +1,3 @@
+ /* 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
new file mode 100644
index 000000000000..88e21a84a974
--- /dev/null
+++ b/arch/riscv/kernel/compat_vdso/flush_icache.S @@ -0,0 +1,3 @@
+ /* 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
new file mode 100755
index 000000000000..8ac070c783b3
--- /dev/null
+++ b/arch/riscv/kernel/compat_vdso/gen_compat_vdso_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 compat\2_offset\t0x\1/p' diff --git a/arch/riscv/kernel/compat_vdso/getcpu.S b/arch/riscv/kernel/compat_vdso/getcpu.S
new file mode 100644
index 000000000000..946449a15a94
--- /dev/null
+++ b/arch/riscv/kernel/compat_vdso/getcpu.S @@ -0,0 +1,3 @@
+ /* 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
new file mode 100644
index 000000000000..67c50898b8e5
--- /dev/null
+++ b/arch/riscv/kernel/compat_vdso/note.S @@ -0,0 +1,3 @@
+ /* 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
new file mode 100644
index 000000000000..f4c98f18c053
--- /dev/null
+++ b/arch/riscv/kernel/compat_vdso/rt_sigreturn.S @@ -0,0 +1,3 @@
+ /* SPDX - License - Identifier : GPL -2.0 - only */
+
+ #include <../vdso/rt_sigreturn.S> diff --git a/arch/riscv/kernel/vdso/vdso.S b/arch/riscv/kernel/vdso/vdso.S
index df222245be05..83f1c899e8d8 100644
--- a/arch/riscv/kernel/vdso/vdso.S
+++ b/arch/riscv/kernel/vdso/vdso.S @@ -7,12 +7,16 @@
#include <linux/linkage.h>
#include <asm/page.h>
+ #ifndef __VDSO_PATH
+ #define __VDSO_PATH "arch/riscv/kernel/vdso/vdso.so"
+ #endif
+
__PAGE_ALIGNED_DATA
.globl vdso_start , vdso_end
.balign PAGE_SIZE
vdso_start :
- .incbin "arch/riscv/kernel/vdso/vdso.so"
+ .incbin __VDSO_PATH
.balign PAGE_SIZE
vdso_end :
--
2.25.1
From: Guo Ren <redacted>
Reconstruct __setup_additional_pages() by appending vdso info
pointer argument to meet compat_vdso_info requirement. And change
vm_special_mapping *dm, *cm initialization into static.
Signed-off-by: Guo Ren <redacted>
Signed-off-by: Guo Ren <guoren@kernel.org>
Cc: Arnd Bergmann <arnd@arndb.de>
---
arch/riscv/include/asm/elf.h | 5 ++
arch/riscv/include/asm/mmu.h | 1 +
arch/riscv/kernel/vdso.c | 104 +++++++++++++++++++++++++----------
3 files changed, 81 insertions(+), 29 deletions(-)
diff --git a/arch/riscv/include/asm/elf.h b/arch/riscv/include/asm/elf.h
index 91b372d4e13b..9d108cf84b99 100644
--- a/arch/riscv/include/asm/elf.h
+++ b/arch/riscv/include/asm/elf.h @@ -136,5 +136,10 @@ do { if ((ex).e_ident[EI_CLASS] == ELFCLASS32) \
typedef compat_ulong_t compat_elf_greg_t ;
typedef compat_elf_greg_t compat_elf_gregset_t [ ELF_NGREG ];
+ extern int compat_arch_setup_additional_pages ( struct linux_binprm * bprm ,
+ int uses_interp );
+ #define compat_arch_setup_additional_pages \
+ compat_arch_setup_additional_pages
+
#endif /* CONFIG_COMPAT */
#endif /* _ASM_RISCV_ELF_H */ diff --git a/arch/riscv/include/asm/mmu.h b/arch/riscv/include/asm/mmu.h
index 0099dc116168..cedcf8ea3c76 100644
--- a/arch/riscv/include/asm/mmu.h
+++ b/arch/riscv/include/asm/mmu.h @@ -16,6 +16,7 @@ typedef struct {
atomic_long_t id ;
#endif
void * vdso ;
+ void * vdso_info ;
#ifdef CONFIG_SMP
/* A local icache flush is needed before user execution can resume. */
cpumask_t icache_stale_mask ; diff --git a/arch/riscv/kernel/vdso.c b/arch/riscv/kernel/vdso.c
index a9436a65161a..deca69524799 100644
--- a/arch/riscv/kernel/vdso.c
+++ b/arch/riscv/kernel/vdso.c @@ -23,6 +23,9 @@ struct vdso_data {
#endif
extern char vdso_start [], vdso_end [];
+ #ifdef CONFIG_COMPAT
+ extern char compat_vdso_start [], compat_vdso_end [];
+ #endif
enum vvar_pages {
VVAR_DATA_PAGE_OFFSET , @@ -30,6 +33,11 @@ enum vvar_pages {
VVAR_NR_PAGES ,
};
+ enum rv_vdso_map {
+ RV_VDSO_MAP_VVAR ,
+ RV_VDSO_MAP_VDSO ,
+ };
+
#define VVAR_SIZE (VVAR_NR_PAGES << PAGE_SHIFT)
/* @@ -52,12 +60,6 @@ struct __vdso_info {
struct vm_special_mapping * cm ;
};
- static struct __vdso_info vdso_info __ro_after_init = {
- . name = "vdso" ,
- . vdso_code_start = vdso_start ,
- . vdso_code_end = vdso_end ,
- };
-
static int vdso_mremap ( const struct vm_special_mapping * sm ,
struct vm_area_struct * new_vma )
{ @@ -66,35 +68,35 @@ static int vdso_mremap(const struct vm_special_mapping *sm,
return 0 ;
}
- static int __init __vdso_init ( void )
+ static int __init __vdso_init ( struct __vdso_info * vdso_info )
{
unsigned int i ;
struct page ** vdso_pagelist ;
unsigned long pfn ;
- if ( memcmp ( vdso_info . vdso_code_start , " \177 ELF" , 4 )) {
+ if ( memcmp ( vdso_info -> vdso_code_start , " \177 ELF" , 4 )) {
pr_err ( "vDSO is not a valid ELF object! \n " );
return - EINVAL ;
}
- vdso_info . vdso_pages = (
- vdso_info . vdso_code_end -
- vdso_info . vdso_code_start ) >>
+ vdso_info -> vdso_pages = (
+ vdso_info -> vdso_code_end -
+ vdso_info -> vdso_code_start ) >>
PAGE_SHIFT ;
- vdso_pagelist = kcalloc ( vdso_info . vdso_pages ,
+ vdso_pagelist = kcalloc ( vdso_info -> vdso_pages ,
sizeof ( struct page * ),
GFP_KERNEL );
if ( vdso_pagelist == NULL )
return - ENOMEM ;
/* Grab the vDSO code pages. */
- pfn = sym_to_pfn ( vdso_info . vdso_code_start );
+ pfn = sym_to_pfn ( vdso_info -> vdso_code_start );
- for ( i = 0 ; i < vdso_info . vdso_pages ; i ++ )
+ for ( i = 0 ; i < vdso_info -> vdso_pages ; i ++ )
vdso_pagelist [ i ] = pfn_to_page ( pfn + i );
- vdso_info . cm -> pages = vdso_pagelist ;
+ vdso_info -> cm -> pages = vdso_pagelist ;
return 0 ;
} @@ -116,13 +118,14 @@ int vdso_join_timens(struct task_struct *task, struct time_namespace *ns)
{
struct mm_struct * mm = task -> mm ;
struct vm_area_struct * vma ;
+ struct __vdso_info * vdso_info = mm -> context . vdso_info ;
mmap_read_lock ( mm );
for ( vma = mm -> mmap ; vma ; vma = vma -> vm_next ) {
unsigned long size = vma -> vm_end - vma -> vm_start ;
- if ( vma_is_special_mapping ( vma , vdso_info . dm ))
+ if ( vma_is_special_mapping ( vma , vdso_info -> dm ))
zap_page_range ( vma , vma -> vm_start , size );
}
@@ -187,11 +190,6 @@ static vm_fault_t vvar_fault(const struct vm_special_mapping *sm,
return vmf_insert_pfn ( vma , vmf -> address , pfn );
}
- enum rv_vdso_map {
- RV_VDSO_MAP_VVAR ,
- RV_VDSO_MAP_VDSO ,
- };
-
static struct vm_special_mapping rv_vdso_maps [] __ro_after_init = {
[ RV_VDSO_MAP_VVAR ] = {
. name = "[vvar]" , @@ -203,25 +201,53 @@ static struct vm_special_mapping rv_vdso_maps[] __ro_after_init = {
},
};
+ static struct __vdso_info vdso_info __ro_after_init = {
+ . name = "vdso" ,
+ . vdso_code_start = vdso_start ,
+ . vdso_code_end = vdso_end ,
+ . dm = & rv_vdso_maps [ RV_VDSO_MAP_VVAR ],
+ . cm = & rv_vdso_maps [ RV_VDSO_MAP_VDSO ],
+ };
+
+ #ifdef CONFIG_COMPAT
+ 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 ,
+ . dm = & rv_vdso_maps [ RV_VDSO_MAP_VVAR ],
+ . cm = & rv_vdso_maps [ RV_VDSO_MAP_VDSO ],
+ };
+ #endif
+
static int __init vdso_init ( void )
{
- vdso_info . dm = & rv_vdso_maps [ RV_VDSO_MAP_VVAR ];
- vdso_info . cm = & rv_vdso_maps [ RV_VDSO_MAP_VDSO ];
+ int ret ;
+
+ ret = __vdso_init ( & vdso_info );
+ if ( ret )
+ goto out ;
- return __vdso_init ();
+ #ifdef CONFIG_COMPAT
+ ret = __vdso_init ( & compat_vdso_info );
+ if ( ret )
+ goto out ;
+ #endif
+ out :
+ return ret ;
}
arch_initcall ( vdso_init );
static int __setup_additional_pages ( struct mm_struct * mm ,
struct linux_binprm * bprm ,
- int uses_interp )
+ int uses_interp ,
+ struct __vdso_info * vdso_info )
{
unsigned long vdso_base , vdso_text_len , vdso_mapping_len ;
void * ret ;
BUILD_BUG_ON ( VVAR_NR_PAGES != __VVAR_PAGES );
- vdso_text_len = vdso_info . vdso_pages << PAGE_SHIFT ;
+ vdso_text_len = vdso_info -> vdso_pages << PAGE_SHIFT ;
/* Be sure to map the data page */
vdso_mapping_len = vdso_text_len + VVAR_SIZE ;
@@ -232,16 +258,18 @@ static int __setup_additional_pages(struct mm_struct *mm,
}
ret = _install_special_mapping ( mm , vdso_base , VVAR_SIZE ,
- ( VM_READ | VM_MAYREAD | VM_PFNMAP ), vdso_info . dm );
+ ( VM_READ | VM_MAYREAD | VM_PFNMAP ), vdso_info -> dm );
if ( IS_ERR ( ret ))
goto up_fail ;
vdso_base += VVAR_SIZE ;
mm -> context . vdso = ( void * ) vdso_base ;
+ mm -> context . vdso_info = ( void * ) vdso_info ;
+
ret =
_install_special_mapping ( mm , vdso_base , vdso_text_len ,
( VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC ),
- vdso_info . cm );
+ vdso_info -> cm );
if ( IS_ERR ( ret ))
goto up_fail ; @@ -253,6 +281,24 @@ static int __setup_additional_pages(struct mm_struct *mm,
return PTR_ERR ( ret );
}
+ #ifdef CONFIG_COMPAT
+ int compat_arch_setup_additional_pages ( struct linux_binprm * bprm ,
+ int uses_interp )
+ {
+ struct mm_struct * mm = current -> mm ;
+ int ret ;
+
+ if ( mmap_write_lock_killable ( mm ))
+ return - EINTR ;
+
+ ret = __setup_additional_pages ( mm , bprm , uses_interp ,
+ & compat_vdso_info );
+ mmap_write_unlock ( mm );
+
+ return ret ;
+ }
+ #endif
+
int arch_setup_additional_pages ( struct linux_binprm * bprm , int uses_interp )
{
struct mm_struct * mm = current -> mm ; @@ -261,7 +307,7 @@ 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 );
+ ret = __setup_additional_pages ( mm , bprm , uses_interp , & vdso_info );
mmap_write_unlock ( mm );
return ret ; --
2.25.1
From: Guo Ren <redacted>
Implement compat_setup_rt_frame for sigcontext save & restore. The
main process is the same with signal, but the rv32 pt_regs' size
is different from rv64's, so we needs convert them.
Signed-off-by: Guo Ren <redacted>
Signed-off-by: Guo Ren <guoren@kernel.org>
Cc: Arnd Bergmann <arnd@arndb.de>
---
arch/riscv/kernel/Makefile | 1 +
arch/riscv/kernel/compat_signal.c | 243 ++++++++++++++++++++++++++++++
arch/riscv/kernel/signal.c | 13 +-
3 files changed, 256 insertions(+), 1 deletion(-)
create mode 100644 arch/riscv/kernel/compat_signal.c
diff --git a/arch/riscv/kernel/Makefile b/arch/riscv/kernel/Makefile
index 59cf97faddae..ef47f7d5843f 100644
--- a/arch/riscv/kernel/Makefile
+++ b/arch/riscv/kernel/Makefile @@ -66,4 +66,5 @@ 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/ diff --git a/arch/riscv/kernel/compat_signal.c b/arch/riscv/kernel/compat_signal.c
new file mode 100644
index 000000000000..7041742ded08
--- /dev/null
+++ b/arch/riscv/kernel/compat_signal.c @@ -0,0 +1,243 @@
+ // SPDX-License-Identifier: GPL-2.0-or-later
+
+ #include <linux/compat.h>
+ #include <linux/signal.h>
+ #include <linux/uaccess.h>
+ #include <linux/syscalls.h>
+ #include <linux/tracehook.h>
+ #include <linux/linkage.h>
+
+ #include <asm/ucontext.h>
+ #include <asm/vdso.h>
+ #include <asm/switch_to.h>
+ #include <asm/csr.h>
+
+ #define COMPAT_DEBUG_SIG 0
+
+ struct compat_sigcontext {
+ struct compat_user_regs_struct sc_regs ;
+ union __riscv_fp_state sc_fpregs ;
+ };
+
+ struct compat_ucontext {
+ compat_ulong_t uc_flags ;
+ struct compat_ucontext * uc_link ;
+ compat_stack_t uc_stack ;
+ sigset_t uc_sigmask ;
+ /* There's some padding here to allow sigset_t to be expanded in the
+ * future . Though this is unlikely , other architectures put uc_sigmask
+ * at the end of this structure and explicitly state it can be
+ * expanded , so we didn ' t want to box ourselves in here . */
+ __u8 __unused [ 1024 / 8 - sizeof ( sigset_t )];
+ /* We can't put uc_sigmask at the end of this structure because we need
+ * to be able to expand sigcontext in the future . For example , the
+ * vector ISA extension will almost certainly add ISA state . We want
+ * to ensure all user - visible ISA state can be saved and restored via a
+ * ucontext , so we ' re putting this at the end in order to allow for
+ * infinite extensibility . Since we know this will be extended and we
+ * assume sigset_t won ' t be extended an extreme amount , we ' re
+ * prioritizing this . */
+ struct compat_sigcontext uc_mcontext ;
+ };
+
+ struct compat_rt_sigframe {
+ struct compat_siginfo info ;
+ struct compat_ucontext uc ;
+ };
+
+ #ifdef CONFIG_FPU
+ static long compat_restore_fp_state ( struct pt_regs * regs ,
+ union __riscv_fp_state __user * sc_fpregs )
+ {
+ long err ;
+ struct __riscv_d_ext_state __user * state = & sc_fpregs -> d ;
+ size_t i ;
+
+ err = __copy_from_user ( & current -> thread . fstate , state , sizeof ( * state ));
+ if ( unlikely ( err ))
+ return err ;
+
+ fstate_restore ( current , regs );
+
+ /* We support no other extension state at this time. */
+ for ( i = 0 ; i < ARRAY_SIZE ( sc_fpregs -> q . reserved ); i ++ ) {
+ u32 value ;
+
+ err = __get_user ( value , & sc_fpregs -> q . reserved [ i ]);
+ if ( unlikely ( err ))
+ break ;
+ if ( value != 0 )
+ return - EINVAL ;
+ }
+
+ return err ;
+ }
+
+ static long compat_save_fp_state ( struct pt_regs * regs ,
+ union __riscv_fp_state __user * sc_fpregs )
+ {
+ long err ;
+ struct __riscv_d_ext_state __user * state = & sc_fpregs -> d ;
+ size_t i ;
+
+ fstate_save ( current , regs );
+ err = __copy_to_user ( state , & current -> thread . fstate , sizeof ( * state ));
+ if ( unlikely ( err ))
+ return err ;
+
+ /* We support no other extension state at this time. */
+ for ( i = 0 ; i < ARRAY_SIZE ( sc_fpregs -> q . reserved ); i ++ ) {
+ err = __put_user ( 0 , & sc_fpregs -> q . reserved [ i ]);
+ if ( unlikely ( err ))
+ break ;
+ }
+
+ return err ;
+ }
+ #else
+ #define compat_save_fp_state(task, regs) (0)
+ #define compat_restore_fp_state(task, regs) (0)
+ #endif
+
+ static long compat_restore_sigcontext ( struct pt_regs * regs ,
+ struct compat_sigcontext __user * sc )
+ {
+ long err ;
+ struct compat_user_regs_struct cregs ;
+
+ /* sc_regs is structured the same as the start of pt_regs */
+ err = __copy_from_user ( & cregs , & sc -> sc_regs , sizeof ( sc -> sc_regs ));
+
+ cregs_to_regs ( & cregs , regs );
+
+ /* Restore the floating-point state. */
+ if ( has_fpu ())
+ err |= compat_restore_fp_state ( regs , & sc -> sc_fpregs );
+ return err ;
+ }
+
+ COMPAT_SYSCALL_DEFINE0 ( rt_sigreturn )
+ {
+ struct pt_regs * regs = current_pt_regs ();
+ struct compat_rt_sigframe __user * frame ;
+ struct task_struct * task ;
+ sigset_t set ;
+
+ /* 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 ;
+
+ if ( __copy_from_user ( & set , & frame -> uc . uc_sigmask , sizeof ( set )))
+ goto badframe ;
+
+ set_current_blocked ( & set );
+
+ if ( compat_restore_sigcontext ( regs , & frame -> uc . uc_mcontext ))
+ goto badframe ;
+
+ if ( compat_restore_altstack ( & frame -> uc . uc_stack ))
+ goto badframe ;
+
+ 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 );
+ return 0 ;
+ }
+
+ static long compat_setup_sigcontext ( struct compat_rt_sigframe __user * frame ,
+ struct pt_regs * regs )
+ {
+ struct compat_sigcontext __user * sc = & frame -> uc . uc_mcontext ;
+ struct compat_user_regs_struct cregs ;
+ long err ;
+
+ regs_to_cregs ( & cregs , regs );
+
+ /* sc_regs is structured the same as the start of pt_regs */
+ err = __copy_to_user ( & sc -> sc_regs , & cregs , sizeof ( sc -> sc_regs ));
+ /* Save the floating-point state. */
+ if ( has_fpu ())
+ err |= compat_save_fp_state ( regs , & sc -> sc_fpregs );
+ return err ;
+ }
+
+ static inline void __user * compat_get_sigframe ( struct ksignal * ksig ,
+ struct pt_regs * regs , size_t framesize )
+ {
+ unsigned long sp ;
+ /* Default to using normal stack */
+ sp = regs -> sp ;
+
+ /*
+ * If we are on the alternate signal stack and would overflow it , don ' t .
+ * Return an always - bogus address instead so we will die with SIGSEGV .
+ */
+ if ( on_sig_stack ( sp ) && ! likely ( on_sig_stack ( sp - framesize )))
+ return ( void __user __force * )( -1UL );
+
+ /* This is the X/Open sanctioned signal stack switching. */
+ sp = sigsp ( sp , ksig ) - framesize ;
+
+ /* Align the stack frame. */
+ sp &= ~ 0xfUL ;
+
+ return ( void __user * ) sp ;
+ }
+
+ int compat_setup_rt_frame ( struct ksignal * ksig , sigset_t * set ,
+ struct pt_regs * regs )
+ {
+ struct compat_rt_sigframe __user * frame ;
+ long err = 0 ;
+
+ frame = compat_get_sigframe ( ksig , regs , sizeof ( * frame ));
+ if ( ! access_ok ( frame , sizeof ( * frame )))
+ return - EFAULT ;
+
+ err |= copy_siginfo_to_user32 ( & frame -> info , & ksig -> info );
+
+ /* Create the ucontext. */
+ err |= __put_user ( 0 , & frame -> uc . uc_flags );
+ err |= __put_user ( NULL , & frame -> uc . uc_link );
+ err |= __compat_save_altstack ( & frame -> uc . uc_stack , regs -> sp );
+ err |= compat_setup_sigcontext ( frame , regs );
+ err |= __copy_to_user ( & frame -> uc . uc_sigmask , set , sizeof ( * set ));
+ if ( err )
+ return - EFAULT ;
+
+ regs -> ra = ( unsigned long ) COMPAT_VDSO_SYMBOL (
+ current -> mm -> context . vdso , rt_sigreturn );
+
+ /*
+ * Set up registers for signal handler .
+ * Registers that we don ' t modify keep the value they had from
+ * user - space at the time we took the signal .
+ * We always pass siginfo and mcontext , regardless of SA_SIGINFO ,
+ * since some things rely on this ( e . g . glibc ' s debug / segfault . c ).
+ */
+ regs -> epc = ( unsigned long ) ksig -> ka . sa . sa_handler ;
+ regs -> sp = ( unsigned long ) frame ;
+ regs -> a0 = ksig -> sig ; /* a0: signal number */
+ regs -> a1 = ( unsigned long )( & frame -> info ); /* a1: siginfo pointer */
+ regs -> a2 = ( unsigned long )( & frame -> uc ); /* a2: ucontext pointer */
+
+ #if COMPAT_DEBUG_SIG
+ pr_info ( "SIG deliver (%s:%d): sig=%d pc=%p ra=%p sp=%p \n " ,
+ current -> comm , task_pid_nr ( current ), ksig -> sig ,
+ ( void * ) regs -> epc , ( void * ) regs -> ra , frame );
+ #endif
+
+ return 0 ;
+ } diff --git a/arch/riscv/kernel/signal.c b/arch/riscv/kernel/signal.c
index c2d5ecbe5526..27d8f39228c4 100644
--- a/arch/riscv/kernel/signal.c
+++ b/arch/riscv/kernel/signal.c @@ -6,6 +6,7 @@
* Copyright ( C ) 2012 Regents of the University of California
*/
+ #include <linux/compat.h>
#include <linux/signal.h>
#include <linux/uaccess.h>
#include <linux/syscalls.h> @@ -229,6 +230,11 @@ static int setup_rt_frame(struct ksignal *ksig, sigset_t *set,
return 0 ;
}
+ #ifdef CONFIG_COMPAT
+ extern int compat_setup_rt_frame ( struct ksignal * ksig , sigset_t * set ,
+ struct pt_regs * regs );
+ #endif
+
static void handle_signal ( struct ksignal * ksig , struct pt_regs * regs )
{
sigset_t * oldset = sigmask_to_save (); @@ -258,8 +264,13 @@ static void handle_signal(struct ksignal *ksig, struct pt_regs *regs)
}
}
+ #ifdef CONFIG_COMPAT
/* Set up the stack frame */
- ret = setup_rt_frame ( ksig , oldset , regs );
+ if ( is_compat_task ())
+ ret = compat_setup_rt_frame ( ksig , oldset , regs );
+ else
+ #endif
+ ret = setup_rt_frame ( ksig , oldset , regs );
signal_setup_done ( ret , ksig , 0 );
} --
2.25.1
From: Guo Ren <redacted>
Now, you can use native gdb on riscv64 for rv32 app debugging.
$ uname -a
Linux buildroot 5.16.0-rc4-00036-gbef6b82fdf23-dirty #53 SMP Mon Dec 20 23:06:53 CST 2021 riscv64 GNU/Linux
$ cat /proc/cpuinfo
processor : 0
hart : 0
isa : rv64imafdcsuh
mmu : sv48
$ file /bin/busybox
/bin/busybox: setuid ELF 32-bit LSB shared object, UCB RISC-V, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-riscv32-ilp32d.so.1, for GNU/Linux 5.15.0, stripped
$ file /usr/bin/gdb
/usr/bin/gdb: ELF 32-bit LSB shared object, UCB RISC-V, version 1 (GNU/Linux), dynamically linked, interpreter /lib/ld-linux-riscv32-ilp32d.so.1, for GNU/Linux 5.15.0, stripped
$ /usr/bin/gdb /bin/busybox
GNU gdb (GDB) 10.2
Copyright (C) 2021 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html >
...
Reading symbols from /bin/busybox...
(No debugging symbols found in /bin/busybox)
(gdb) b main
Breakpoint 1 at 0x8ddc
(gdb) r
Starting program: /bin/busybox
Failed to read a valid object file image from memory.
Breakpoint 1, 0x555a8ddc in main ()
(gdb) i r
ra 0x77df0b74 0x77df0b74
sp 0x7fdd3d10 0x7fdd3d10
gp 0x5567e800 0x5567e800 <bb_common_bufsiz1+160>
tp 0x77f64280 0x77f64280
t0 0x0 0
t1 0x555a6fac 1431990188
t2 0x77dd8db4 2011008436
fp 0x7fdd3e34 0x7fdd3e34
s1 0x7fdd3e34 2145205812
a0 0xffffffff -1
a1 0x2000 8192
a2 0x7fdd3e3c 2145205820
a3 0x0 0
a4 0x7fdd3d30 2145205552
a5 0x555a8dc0 1431997888
a6 0x77f2c170 2012397936
a7 0x6a7c7a2f 1786542639
s2 0x0 0
s3 0x0 0
s4 0x555a8dc0 1431997888
s5 0x77f8a3a8 2012783528
s6 0x7fdd3e3c 2145205820
s7 0x5567cecc 1432866508
--Type <RET> for more, q to quit, c to continue without paging--
s8 0x1 1
s9 0x0 0
s10 0x55634448 1432568904
s11 0x0 0
t3 0x77df0bb8 2011106232
t4 0x42fc 17148
t5 0x0 0
t6 0x40 64
pc 0x555a8ddc 0x555a8ddc <main+28>
(gdb) si
0x555a78f0 in mallopt@plt ()
(gdb) c
Continuing.
BusyBox v1.34.1 (2021-12-19 22:39:48 CST) multi-call binary.
BusyBox is copyrighted by many authors between 1998-2015.
Licensed under GPLv2. See source distribution for detailed
copyright notices.
Usage: busybox [function [arguments]...]
or: busybox --list[-full]
...
[Inferior 1 (process 107) exited normally]
(gdb) q
Signed-off-by: Guo Ren <redacted>
Signed-off-by: Guo Ren <guoren@kernel.org>
Cc: Arnd Bergmann <arnd@arndb.de>
---
arch/riscv/kernel/ptrace.c | 87 +++++++++++++++++++++++++++++++++++---
1 file changed, 82 insertions(+), 5 deletions(-)
diff --git a/arch/riscv/kernel/ptrace.c b/arch/riscv/kernel/ptrace.c
index 9c0511119bad..76042ed861a3 100644
--- a/arch/riscv/kernel/ptrace.c
+++ b/arch/riscv/kernel/ptrace.c @@ -12,6 +12,7 @@
#include <asm/thread_info.h>
#include <asm/switch_to.h>
#include <linux/audit.h>
+ #include <linux/compat.h>
#include <linux/ptrace.h>
#include <linux/elf.h>
#include <linux/regset.h> @@ -113,11 +114,6 @@ static const struct user_regset_view riscv_user_native_view = {
. n = ARRAY_SIZE ( riscv_user_regset ),
};
- const struct user_regset_view * task_user_regset_view ( struct task_struct * task )
- {
- return & riscv_user_native_view ;
- }
-
struct pt_regs_offset {
const char * name ;
int offset ; @@ -275,3 +271,84 @@ __visible void do_syscall_trace_exit(struct pt_regs *regs)
trace_sys_exit ( regs , regs_return_value ( regs ));
#endif
}
+
+ #ifdef CONFIG_COMPAT
+ static int compat_riscv_gpr_get ( struct task_struct * target ,
+ const struct user_regset * regset ,
+ struct membuf to )
+ {
+ struct compat_user_regs_struct cregs ;
+
+ regs_to_cregs ( & cregs , task_pt_regs ( target ));
+
+ return membuf_write ( & to , & cregs ,
+ sizeof ( struct compat_user_regs_struct ));
+ }
+
+ static int compat_riscv_gpr_set ( struct task_struct * target ,
+ const struct user_regset * regset ,
+ unsigned int pos , unsigned int count ,
+ const void * kbuf , const void __user * ubuf )
+ {
+ int ret ;
+ struct compat_user_regs_struct cregs ;
+
+ ret = user_regset_copyin ( & pos , & count , & kbuf , & ubuf , & cregs , 0 , -1 );
+
+ cregs_to_regs ( & cregs , task_pt_regs ( target ));
+
+ return ret ;
+ }
+
+ static const struct user_regset compat_riscv_user_regset [] = {
+ [ REGSET_X ] = {
+ . core_note_type = NT_PRSTATUS ,
+ . n = ELF_NGREG ,
+ . size = sizeof ( compat_elf_greg_t ),
+ . align = sizeof ( compat_elf_greg_t ),
+ . regset_get = compat_riscv_gpr_get ,
+ . set = compat_riscv_gpr_set ,
+ },
+ #ifdef CONFIG_FPU
+ [ REGSET_F ] = {
+ . core_note_type = NT_PRFPREG ,
+ . n = ELF_NFPREG ,
+ . size = sizeof ( elf_fpreg_t ),
+ . align = sizeof ( elf_fpreg_t ),
+ . regset_get = riscv_fpr_get ,
+ . set = riscv_fpr_set ,
+ },
+ #endif
+ };
+
+ static const struct user_regset_view compat_riscv_user_native_view = {
+ . name = "riscv" ,
+ . e_machine = EM_RISCV ,
+ . regsets = compat_riscv_user_regset ,
+ . n = ARRAY_SIZE ( compat_riscv_user_regset ),
+ };
+
+ long compat_arch_ptrace ( struct task_struct * child , compat_long_t request ,
+ compat_ulong_t caddr , compat_ulong_t cdata )
+ {
+ long ret = - EIO ;
+
+ switch ( request ) {
+ default :
+ ret = compat_ptrace_request ( child , request , caddr , cdata );
+ break ;
+ }
+
+ return ret ;
+ }
+ #endif /* CONFIG_COMPAT */
+
+ const struct user_regset_view * task_user_regset_view ( struct task_struct * task )
+ {
+ #ifdef CONFIG_COMPAT
+ if ( test_tsk_thread_flag ( task , TIF_32BIT ))
+ return & compat_riscv_user_native_view ;
+ else
+ #endif
+ return & riscv_user_native_view ;
+ } --
2.25.1
From: Guo Ren <redacted>
If the current task is in COMPAT mode, set SR_UXL_32 in status for
returning userspace.
Signed-off-by: Guo Ren <redacted>
Signed-off-by: Guo Ren <guoren@kernel.org>
Cc: Arnd Bergmann <arnd@arndb.de>
---
arch/riscv/kernel/process.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/arch/riscv/kernel/process.c b/arch/riscv/kernel/process.c
index 03ac3aa611f5..1a666ad299b4 100644
--- a/arch/riscv/kernel/process.c
+++ b/arch/riscv/kernel/process.c @@ -97,6 +97,11 @@ void start_thread(struct pt_regs *regs, unsigned long pc,
}
regs -> epc = pc ;
regs -> sp = sp ;
+
+ #ifdef CONFIG_COMPAT
+ if ( is_compat_task ())
+ regs -> status |= SR_UXL_32 ;
+ #endif
}
void flush_thread ( void ) --
2.25.1
From: Guo Ren <redacted>
Adds initial skeletal COMPAT Kbuild (Runing 32bit U-mode on 64bit
S-mode) support.
- Setup kconfig & dummy functions for compiling.
- Implement compat_start_thread by the way.
Signed-off-by: Guo Ren <redacted>
Signed-off-by: Guo Ren <guoren@kernel.org>
Cc: Arnd Bergmann <arnd@arndb.de>
---
arch/riscv/Kconfig | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)
diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
index 821252b65f89..08f1f3ba3d77 100644
--- a/arch/riscv/Kconfig
+++ b/arch/riscv/Kconfig @@ -72,6 +72,7 @@ config RISCV
select HAVE_ARCH_KGDB if ! XIP_KERNEL
select HAVE_ARCH_KGDB_QXFER_PKT
select HAVE_ARCH_MMAP_RND_BITS if MMU
+ select HAVE_ARCH_MMAP_RND_COMPAT_BITS if COMPAT
select HAVE_ARCH_SECCOMP_FILTER
select HAVE_ARCH_TRACEHOOK
select HAVE_ARCH_TRANSPARENT_HUGEPAGE if 64 BIT && MMU @@ -122,12 +123,18 @@ config ARCH_MMAP_RND_BITS_MIN
default 18 if 64 BIT
default 8
+ config ARCH_MMAP_RND_COMPAT_BITS_MIN
+ default 8
+
# max bits determined by the following formula:
# VA_BITS - PAGE_SHIFT - 3
config ARCH_MMAP_RND_BITS_MAX
default 24 if 64 BIT # SV39 based
default 17
+ config ARCH_MMAP_RND_COMPAT_BITS_MAX
+ default 17
+
# set if we run in machine mode, cleared if we run in supervisor mode
config RISCV_M_MODE
bool @@ -427,6 +434,18 @@ config CRASH_DUMP
For more details see Documentation/admin-guide/kdump/kdump.rst
+ config COMPAT
+ bool "Kernel support for 32-bit U-mode"
+ default 64 BIT
+ depends on 64 BIT && MMU
+ help
+ This option enables support for a 32 -bit U-mode running under a 64 -bit
+ kernel at S-mode. riscv32-specific components such as system calls,
+ the user helper functions ( vdso), signal rt_frame functions and the
+ ptrace interface are handled appropriately by the kernel.
+
+ If you want to execute 32 -bit userspace applications, say Y.
+
endmenu
menu "Boot options" --
2.25.1
On Tue, Dec 28, 2021 at 3:39 PM [off-list ref] wrote:
From: Guo Ren <redacted>
The existing per-arch definitions are pretty much historic cruft.
Move SYSVIPC_COMPAT into init/Kconfig.
Signed-off-by: Guo Ren <redacted>
Signed-off-by: Guo Ren <guoren@kernel.org>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Christoph Hellwig <hch@infradead.org>
Acked-by: Arnd Bergmann <arnd@arndb.de>
On Tue, Dec 28, 2021 at 3:39 PM [off-list ref] wrote:
From: Guo Ren <redacted>
RISC-V doesn't neeed compat_stat, so using __ARCH_WANT_COMPAT_STAT
to exclude unnecessary SYSCALL functions.
Signed-off-by: Guo Ren <redacted>
Signed-off-by: Guo Ren <guoren@kernel.org>
Reviewed-by: Arnd Bergmann <arnd@arndb.de>
On Tue, Dec 28, 2021 at 3:39 PM [off-list ref] wrote:
From: Guo Ren <redacted>
Remove duplicate F_GETLK64,F_SETLK64,F_SETLKW64 definitions in
arch/*/include/asm/compat.h.
Signed-off-by: Guo Ren <redacted>
Signed-off-by: Guo Ren <guoren@kernel.org>
Cc: Arnd Bergmann <arnd@arndb.de>
Unfortunately, this one does not look correct to me:
quoted hunk @@ -116,7 +116,7 @@
#define F_GETSIG 11 /* for sockets. */
#endif
- #ifndef CONFIG_64BIT
+ #if !defined(CONFIG_64BIT) || defined(CONFIG_COMPAT)
#ifndef F_GETLK64
#define F_GETLK64 12 /* using 'struct flock64' */
#define F_SETLK64 13
The problem here is that include/uapi/ headers cannot contain checks for
CONFIG_* symbols because those may have different meanings in user space
compared to kernel.
This is a preexisting problem in the header, but I think the change
makes it worse.
With the current behavior, user space will always see the definitions,
unless it happens to have its own definition for CONFIG_64BIT already.
On 64-bit parisc, this has the effect of defining the macros to the
same values as F_SETOWN/F_SETSIG/F_GETSIG, which is potentially
harmful. On MIPS, it uses values that are different from the 32-bit numbers
but are otherwise unused. Everywhere else, we get the definition from
the 32-bit architecture in user space, which will do nothing in the kernel.
The correct check for a uapi header would be to test for
__BITS_PER_LONG==32. We should probably do that here, but
this won't help you move the definitions, and it is a user-visible change
as the incorrect definition will no longer be visible. [Adding Jeff and Bruce
(the flock mainainers) to Cc for additional feedback on this]
For your series, I would suggest just moving the macro definitions to
include/linux/compat.h along with the 'struct compat_flock64'
definition, and leaving the duplicate one in the uapi header unchanged
until we have decided on a solution.
Arnd
On Tue, Dec 28, 2021 at 3:39 PM [off-list ref] wrote:
From: Guo Ren <redacted>
Implement necessary type and macro for compat elf. See the code
comment for detail.
Signed-off-by: Guo Ren <redacted>
Signed-off-by: Guo Ren <guoren@kernel.org>
Cc: Arnd Bergmann <arnd@arndb.de>
This looks mostly correct,
+/*
+ * FIXME: not sure SET_PERSONALITY for compat process is right!
+ */
+#define SET_PERSONALITY(ex) \
+do { if ((ex).e_ident[EI_CLASS] == ELFCLASS32) \
+ set_thread_flag(TIF_32BIT); \
+ else \
+ clear_thread_flag(TIF_32BIT); \
+ set_personality(PER_LINUX | (current->personality & (~PER_MASK))); \
+} while (0)
This means the personality after exec is always set to PER_LINUX, not
PER_LINUX32, which I think is wrong: you want the PER_LINUX32
setting to stick, just like the upper bits do in the default implementation.
What the other ones do is:
| arch/parisc/include/asm/elf.h-
set_personality((current->personality & ~PER_MASK) | PER_LINUX); \
This looks like the same problem you introduce here: always forcing PER_LINUX
instead of PER_LINUX32 makes it impossible to use PER_LINUX32.
| arch/alpha/include/asm/elf.h:#define SET_PERSONALITY(EX)
\
| arch/alpha/include/asm/elf.h- set_personality(((EX).e_flags &
EF_ALPHA_32BIT) \
| arch/alpha/include/asm/elf.h- ? PER_LINUX_32BIT : PER_LINUX)
| arch/csky/include/asm/elf.h:#define SET_PERSONALITY(ex)
set_personality(PER_LINUX)
| arch/nds32/include/asm/elf.h:#define SET_PERSONALITY(ex)
set_personality(PER_LINUX)
These look even worse: instead of forcing the lower bits to
PER_LINUX/PER_LINUX32 and
leaving the upper bits untouched, these also clear the upper bits
unconditionally.
| arch/arm64/include/asm/elf.h:#define SET_PERSONALITY(ex)
\
| arch/arm64/include/asm/elf.h- current->personality &=
~READ_IMPLIES_EXEC; \
| arch/x86/um/asm/elf.h:#define SET_PERSONALITY(ex) do {} while(0)
| arch/x86/include/asm/elf.h:#define set_personality_64bit() do {
} while (0)
| arch/x86/kernel/process_64.c:static void __set_personality_ia32(void)
| current->personality |= force_personality32;
Inconsistent: does not enforce PER_LINUX/PER_LINUX32 as the default
implementation
does, but just leaves the value untouched (other than (re)setting
READ_IMPLIES_EXEC).
I think this is harmless otherwise, as we generally ignore the lower
bits, except for the
bit of code that checks for PER_LINUX32 in override_architecture() to mangle the
output of sys_newuname() or in /proc/cpuinfo.
| arch/s390/include/asm/elf.h- if
(personality(current->personality) != PER_LINUX32) \
| arch/s390/include/asm/elf.h- set_personality(PER_LINUX |
\
| arch/s390/include/asm/elf.h-
(current->personality & ~PER_MASK)); \
| arch/powerpc/include/asm/elf.h- if
(personality(current->personality) != PER_LINUX32) \
| arch/powerpc/include/asm/elf.h- set_personality(PER_LINUX |
\
| arch/powerpc/include/asm/elf.h-
(current->personality & (~PER_MASK))); \
| arch/sparc/include/asm/elf_64.h- if
(personality(current->personality) != PER_LINUX32) \
| arch/sparc/include/asm/elf_64.h-
set_personality(PER_LINUX | \
| arch/sparc/include/asm/elf_64.h-
(current->personality & (~PER_MASK))); \
This is probably the behavior you want to copy.
Arnd
Le 28/12/2021 à 15:39, guoren@kernel.org a écrit : From: Guo Ren <redacted>
Remove duplicate F_GETLK64,F_SETLK64,F_SETLKW64 definitions in
arch/*/include/asm/compat.h.
Signed-off-by: Guo Ren <redacted>
Signed-off-by: Guo Ren <guoren@kernel.org>
Cc: Arnd Bergmann <arnd@arndb.de>
---
arch/arm64/include/asm/compat.h | 4 ----
arch/powerpc/include/asm/compat.h | 4 ----
arch/s390/include/asm/compat.h | 4 ----
arch/sparc/include/asm/compat.h | 4 ----
arch/x86/include/asm/compat.h | 4 ----
include/uapi/asm-generic/fcntl.h | 2 +-
6 files changed, 1 insertion(+), 21 deletions(-)
...
quoted hunk diff --git a/include/uapi/asm-generic/fcntl.h b/include/uapi/asm-generic/fcntl.h
index ecd0f5bdfc1d..5bc1e51d73b1 100644
--- a/include/uapi/asm-generic/fcntl.h
+++ b/include/uapi/asm-generic/fcntl.h @@ -116,7 +116,7 @@
#define F_GETSIG 11 /* for sockets. */
#endif
- #ifndef CONFIG_64BIT
+ #if !defined(CONFIG_64BIT) || defined(CONFIG_COMPAT)
#ifndef F_GETLK64
#define F_GETLK64 12 /* using 'struct flock64' */
#define F_SETLK64 13
There seems to be a problem with this change:
error: /linux/include/uapi/asm-generic/fcntl.h: leak CONFIG_COMPAT to
user-space
make[3]: *** [/linux/scripts/Makefile.headersinst:63:
usr/include/asm-generic/fcntl.h] Error 1
make[3]: *** Waiting for unfinished jobs....
make[2]: *** [/linux/Makefile:1283: headers] Error 2
make[1]: *** [Makefile:219: __sub-make] Error 2
make[2]: Leaving directory '/output'
make[1]: Leaving directory '/linux'
make: *** [Makefile:157: khdr] Error 2
make: Leaving directory '/linux/tools/testing/selftests'
## Selftest build completed rc = 2
## Found 2 binaries
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! Error build failed rc 2
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
Error: Process completed with exit code 2.
On Mon, Jan 10, 2022 at 02:35:19PM +0100, Arnd Bergmann wrote: quoted +#if !defined(CONFIG_64BIT) || defined(CONFIG_COMPAT)
#ifndef F_GETLK64
#define F_GETLK64 12 /* using 'struct flock64' */
#define F_SETLK64 13
The problem here is that include/uapi/ headers cannot contain checks for
CONFIG_* symbols because those may have different meanings in user space
compared to kernel.
This is a preexisting problem in the header, but I think the change
makes it worse.
FYI, this is what I did in my old branch, which also sidesteps the
duplicate value problem on parisc. The rebase is untested so far,
but I can spend some cycles on finishing it:
http://git.infradead.org/users/hch/misc.git/shortlog/refs/heads/fcntl-asm-generic-cleanup
On Mon, Jan 10, 2022 at 10:29 PM Arnd Bergmann [off-list ref] wrote:
On Tue, Dec 28, 2021 at 3:39 PM [off-list ref] wrote: quoted
From: Guo Ren <redacted>
Implement necessary type and macro for compat elf. See the code
comment for detail.
Signed-off-by: Guo Ren <redacted>
Signed-off-by: Guo Ren <guoren@kernel.org>
Cc: Arnd Bergmann <arnd@arndb.de>
This looks mostly correct,
quoted +/*
+ * FIXME: not sure SET_PERSONALITY for compat process is right!
+ */
+#define SET_PERSONALITY(ex) \
+do { if ((ex).e_ident[EI_CLASS] == ELFCLASS32) \
+ set_thread_flag(TIF_32BIT); \
+ else \
+ clear_thread_flag(TIF_32BIT); \
+ set_personality(PER_LINUX | (current->personality & (~PER_MASK))); \
+} while (0)
This means the personality after exec is always set to PER_LINUX, not
PER_LINUX32, which I think is wrong: you want the PER_LINUX32
setting to stick, just like the upper bits do in the default implementation.
What the other ones do is:
| arch/parisc/include/asm/elf.h-
set_personality((current->personality & ~PER_MASK) | PER_LINUX); \
This looks like the same problem you introduce here: always forcing PER_LINUX
instead of PER_LINUX32 makes it impossible to use PER_LINUX32.
| arch/alpha/include/asm/elf.h:#define SET_PERSONALITY(EX)
\
| arch/alpha/include/asm/elf.h- set_personality(((EX).e_flags &
EF_ALPHA_32BIT) \
| arch/alpha/include/asm/elf.h- ? PER_LINUX_32BIT : PER_LINUX)
| arch/csky/include/asm/elf.h:#define SET_PERSONALITY(ex)
set_personality(PER_LINUX)
| arch/nds32/include/asm/elf.h:#define SET_PERSONALITY(ex)
set_personality(PER_LINUX)
These look even worse: instead of forcing the lower bits to
PER_LINUX/PER_LINUX32 and
leaving the upper bits untouched, these also clear the upper bits
unconditionally.
| arch/arm64/include/asm/elf.h:#define SET_PERSONALITY(ex)
\
| arch/arm64/include/asm/elf.h- current->personality &=
~READ_IMPLIES_EXEC; \
| arch/x86/um/asm/elf.h:#define SET_PERSONALITY(ex) do {} while(0)
| arch/x86/include/asm/elf.h:#define set_personality_64bit() do {
} while (0)
| arch/x86/kernel/process_64.c:static void __set_personality_ia32(void)
| current->personality |= force_personality32;
Inconsistent: does not enforce PER_LINUX/PER_LINUX32 as the default
implementation
does, but just leaves the value untouched (other than (re)setting
READ_IMPLIES_EXEC).
I think this is harmless otherwise, as we generally ignore the lower
bits, except for the
bit of code that checks for PER_LINUX32 in override_architecture() to mangle the
output of sys_newuname() or in /proc/cpuinfo.
| arch/s390/include/asm/elf.h- if
(personality(current->personality) != PER_LINUX32) \
| arch/s390/include/asm/elf.h- set_personality(PER_LINUX |
\
| arch/s390/include/asm/elf.h-
(current->personality & ~PER_MASK)); \
| arch/powerpc/include/asm/elf.h- if
(personality(current->personality) != PER_LINUX32) \
| arch/powerpc/include/asm/elf.h- set_personality(PER_LINUX |
\
| arch/powerpc/include/asm/elf.h-
(current->personality & (~PER_MASK))); \
| arch/sparc/include/asm/elf_64.h- if
(personality(current->personality) != PER_LINUX32) \
| arch/sparc/include/asm/elf_64.h-
set_personality(PER_LINUX | \
| arch/sparc/include/asm/elf_64.h-
(current->personality & (~PER_MASK))); \
This is probably the behavior you want to copy. Thank you very much for your detailed explanation. Here is my modification.
+#define SET_PERSONALITY(ex) \
+do { if ((ex).e_ident[EI_CLASS] == ELFCLASS32) \
+ set_thread_flag(TIF_32BIT); \
+ else \
+ clear_thread_flag(TIF_32BIT); \
+ if (personality(current->personality) != PER_LINUX32) \
+ set_personality(PER_LINUX | \
+ (current->personality & (~PER_MASK))); \
+} while (0)
Arnd
--
Best Regards
Guo Ren
ML: https://lore.kernel.org/linux-csky/
On Mon, Jan 10, 2022 at 9:35 PM Arnd Bergmann [off-list ref] wrote:
On Tue, Dec 28, 2021 at 3:39 PM [off-list ref] wrote: quoted
From: Guo Ren <redacted>
Remove duplicate F_GETLK64,F_SETLK64,F_SETLKW64 definitions in
arch/*/include/asm/compat.h.
Signed-off-by: Guo Ren <redacted>
Signed-off-by: Guo Ren <guoren@kernel.org>
Cc: Arnd Bergmann <arnd@arndb.de>
Unfortunately, this one does not look correct to me:
quoted @@ -116,7 +116,7 @@
#define F_GETSIG 11 /* for sockets. */
#endif
- #ifndef CONFIG_64BIT
+ #if !defined(CONFIG_64BIT) || defined(CONFIG_COMPAT)
#ifndef F_GETLK64
#define F_GETLK64 12 /* using 'struct flock64' */
#define F_SETLK64 13
The problem here is that include/uapi/ headers cannot contain checks for
CONFIG_* symbols because those may have different meanings in user space
compared to kernel.
This is a preexisting problem in the header, but I think the change
makes it worse.
With the current behavior, user space will always see the definitions,
unless it happens to have its own definition for CONFIG_64BIT already.
On 64-bit parisc, this has the effect of defining the macros to the
same values as F_SETOWN/F_SETSIG/F_GETSIG, which is potentially
harmful. On MIPS, it uses values that are different from the 32-bit numbers
but are otherwise unused. Everywhere else, we get the definition from
the 32-bit architecture in user space, which will do nothing in the kernel.
The correct check for a uapi header would be to test for
__BITS_PER_LONG==32. We should probably do that here, but
this won't help you move the definitions, and it is a user-visible change
as the incorrect definition will no longer be visible. [Adding Jeff and Bruce
(the flock mainainers) to Cc for additional feedback on this]
For your series, I would suggest just moving the macro definitions to
include/linux/compat.h along with the 'struct compat_flock64'
definition, and leaving the duplicate one in the uapi header unchanged
until we have decided on a solution. Okay.
Arnd
--
Best Regards
Guo Ren
ML: https://lore.kernel.org/linux-csky/