Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

port to riscv64 #2234

Merged
merged 7 commits into from
Oct 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/cross-compile-daily.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
target: [armv7-stable-cross, aarch64-stable-cross, ppc64-stable-cross, mips64el-stable-cross]
target: [armv7-stable-cross, aarch64-stable-cross, ppc64-stable-cross, mips64el-stable-cross, riscv64-stable-cross]
branches: [criu-dev, master]

steps:
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/cross-compile.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ jobs:
aarch64-stable-cross,
ppc64-stable-cross,
mips64el-stable-cross,
riscv64-stable-cross,
]
include:
- experimental: true
Expand Down
6 changes: 5 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ endif

#
# Supported Architectures
ifneq ($(filter-out x86 arm aarch64 ppc64 s390 mips loongarch64,$(ARCH)),)
ifneq ($(filter-out x86 arm aarch64 ppc64 s390 mips loongarch64 riscv64,$(ARCH)),)
$(error "The architecture $(ARCH) isn't supported")
endif

Expand Down Expand Up @@ -84,6 +84,10 @@ ifeq ($(ARCH),loongarch64)
DEFINES := -DCONFIG_LOONGARCH64
endif

ifeq ($(ARCH),riscv64)
DEFINES := -DCONFIG_RISCV64
endif

#
# CFLAGS_PIE:
#
Expand Down
4 changes: 2 additions & 2 deletions compel/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@ ifeq ($(ARCH),x86)
lib-y += arch/$(ARCH)/src/lib/thread_area.o
endif

# handle_elf() has no support of ELF relocations on ARM (yet?)
ifneq ($(filter arm aarch64 loongarch64,$(ARCH)),)
# handle_elf() has no support of ELF relocations on ARM and RISCV64 (yet?)
ifneq ($(filter arm aarch64 loongarch64 riscv64,$(ARCH)),)
CFLAGS += -DNO_RELOCS
HOSTCFLAGS += -DNO_RELOCS
endif
Expand Down
35 changes: 35 additions & 0 deletions compel/arch/riscv64/plugins/include/asm/prologue.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#ifndef __ASM_PROLOGUE_H__
#define __ASM_PROLOGUE_H__

#ifndef __ASSEMBLY__

#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>

#include <errno.h>

#define sys_recv(sockfd, ubuf, size, flags) sys_recvfrom(sockfd, ubuf, size, flags, NULL, NULL)

typedef struct prologue_init_args {
struct sockaddr_un ctl_sock_addr;
unsigned int ctl_sock_addr_len;

unsigned int arg_s;
void *arg_p;

void *sigframe;
} prologue_init_args_t;

#endif /* __ASSEMBLY__ */

/*
* Reserve enough space for sigframe.
*
* FIXME It is rather should be taken from sigframe header.
*/
#define PROLOGUE_SGFRAME_SIZE 4096

#define PROLOGUE_INIT_ARGS_SIZE 1024

#endif /* __ASM_PROLOGUE_H__ */
28 changes: 28 additions & 0 deletions compel/arch/riscv64/plugins/include/asm/syscall-types.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#ifndef COMPEL_ARCH_SYSCALL_TYPES_H__
#define COMPEL_ARCH_SYSCALL_TYPES_H__

#define SA_RESTORER 0x04000000

typedef void rt_signalfn_t(int, siginfo_t *, void *);
typedef rt_signalfn_t *rt_sighandler_t;

typedef void rt_restorefn_t(void);
typedef rt_restorefn_t *rt_sigrestore_t;

#define _KNSIG 64 // number of signals
#define _NSIG_BPW 64 // number of signals per word

#define _KNSIG_WORDS (_KNSIG / _NSIG_BPW)

typedef struct {
unsigned long sig[_KNSIG_WORDS];
} k_rtsigset_t;

typedef struct {
rt_sighandler_t rt_sa_handler;
unsigned long rt_sa_flags;
rt_sigrestore_t rt_sa_restorer;
k_rtsigset_t rt_sa_mask;
} rt_sigaction_t;

#endif /* COMPEL_ARCH_SYSCALL_TYPES_H__ */
4 changes: 4 additions & 0 deletions compel/arch/riscv64/plugins/include/features.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#ifndef __COMPEL_ARCH_FEATURES_H
#define __COMPEL_ARCH_FEATURES_H

#endif /* __COMPEL_ARCH_FEATURES_H */
7 changes: 7 additions & 0 deletions compel/arch/riscv64/plugins/std/parasite-head.S
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#include "common/asm/linkage.h"

.section .head.text, "ax"
ENTRY(__export_parasite_head_start)
jal parasite_service
ebreak
END(__export_parasite_head_start)
59 changes: 59 additions & 0 deletions compel/arch/riscv64/plugins/std/syscalls/Makefile.syscalls
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
ccflags-y += -iquote $(PLUGIN_ARCH_DIR)/std/syscalls/
asflags-y += -iquote $(PLUGIN_ARCH_DIR)/std/syscalls/

sys-types := $(obj)/include/uapi/std/syscall-types.h
sys-codes := $(obj)/include/uapi/std/syscall-codes.h
sys-proto := $(obj)/include/uapi/std/syscall.h

sys-def := $(PLUGIN_ARCH_DIR)/std/syscalls/syscall.def
sys-asm-common-name := std/syscalls/syscall-common.S
sys-asm-common := $(PLUGIN_ARCH_DIR)/$(sys-asm-common-name)
sys-asm-types := $(obj)/include/uapi/std/asm/syscall-types.h
sys-exec-tbl = $(PLUGIN_ARCH_DIR)/std/sys-exec-tbl.c

sys-gen := $(PLUGIN_ARCH_DIR)/std/syscalls/gen-syscalls.pl
sys-gen-tbl := $(PLUGIN_ARCH_DIR)/std/syscalls/gen-sys-exec-tbl.pl

sys-asm := ./$(PLUGIN_ARCH_DIR)/std/syscalls/syscalls.S
std-lib-y += $(sys-asm:.S=).o

ifeq ($(ARCH),arm)
arch_bits := 32
else
arch_bits := 64
endif

sys-exec-tbl := sys-exec-tbl.c

$(sys-asm) $(sys-types) $(sys-codes) $(sys-proto): $(sys-gen) $(sys-def) $(sys-asm-common) $(sys-asm-types)
$(E) " GEN " $@
$(Q) perl \
$(sys-gen) \
$(sys-def) \
$(sys-codes) \
$(sys-proto) \
$(sys-asm) \
$(sys-asm-common-name) \
$(sys-types) \
$(arch_bits)

$(sys-asm:.S=).o: $(sys-asm)

$(sys-exec-tbl): $(sys-gen-tbl) $(sys-def)
$(E) " GEN " $@
$(Q) perl \
$(sys-gen-tbl) \
$(sys-def) \
$(sys-exec-tbl) \
$(arch_bits)

$(sys-asm-types): $(PLUGIN_ARCH_DIR)/include/asm/syscall-types.h
$(call msg-gen, $@)
$(Q) ln -s ../../../../../../$(PLUGIN_ARCH_DIR)/include/asm/syscall-types.h $(sys-asm-types)
$(Q) ln -s ../../../../../$(PLUGIN_ARCH_DIR)/std/syscalls/syscall-aux.S $(obj)/include/uapi/std/syscall-aux.S
$(Q) ln -s ../../../../../$(PLUGIN_ARCH_DIR)/std/syscalls/syscall-aux.h $(obj)/include/uapi/std/syscall-aux.h

std-headers-deps += $(sys-asm) $(sys-codes) $(sys-proto) $(sys-asm-types) $(sys-codes)
mrproper-y += $(std-headers-deps)
mrproper-y += $(obj)/include/uapi/std/syscall-aux.S
mrproper-y += $(obj)/include/uapi/std/syscall-aux.h
43 changes: 43 additions & 0 deletions compel/arch/riscv64/plugins/std/syscalls/gen-sys-exec-tbl.pl
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
#!/usr/bin/perl

use strict;
use warnings;

my $in = $ARGV[0];
my $tblout = $ARGV[1];
my $bits = $ARGV[2];

my $code = "code$bits";

open TBLOUT, ">", $tblout or die $!;
open IN, "<", $in or die $!;

print TBLOUT "/* Autogenerated, don't edit */\n";
print TBLOUT "static struct syscall_exec_desc sc_exec_table[] = {\n";

for (<IN>) {
if ($_ =~ /\#/) {
next;
}

my $sys_name;
my $sys_num;

if (/(?<name>\S+)\s+(?<alias>\S+)\s+(?<code64>\d+|\!)\s+(?<code32>(?:\d+|\!))\s+\((?<args>.+)\)/) {
$sys_name = $+{alias};
} elsif (/(?<name>\S+)\s+(?<code64>\d+|\!)\s+(?<code32>(?:\d+|\!))\s+\((?<args>.+)\)/) {
$sys_name = $+{name};
} else {
unlink $tblout;
die "Invalid syscall definition file: invalid entry $_\n";
}

$sys_num = $+{$code};

if ($sys_num ne "!") {
print TBLOUT "SYSCALL($sys_name, $sys_num)\n";
}
}

print TBLOUT " { }, /* terminator */";
print TBLOUT "};"
99 changes: 99 additions & 0 deletions compel/arch/riscv64/plugins/std/syscalls/gen-syscalls.pl
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
#!/usr/bin/perl

use strict;
use warnings;

my $in = $ARGV[0];
my $codesout = $ARGV[1];
my $codes = $ARGV[1];
$codes =~ s/.*include\/uapi\//compel\/plugins\//g;
my $protosout = $ARGV[2];
my $protos = $ARGV[2];
$protos =~ s/.*include\/uapi\//compel\/plugins\//g;
my $asmout = $ARGV[3];
my $asmcommon = $ARGV[4];
my $prototypes = $ARGV[5];
$prototypes =~ s/.*include\/uapi\//compel\/plugins\//g;
my $bits = $ARGV[6];

my $codesdef = $codes;
$codesdef =~ tr/.\-\//_/;
my $protosdef = $protos;
$protosdef =~ tr/.\-\//_/;
my $code = "code$bits";
my $need_aux = 0;

unlink $codesout;
unlink $protosout;
unlink $asmout;

open CODESOUT, ">", $codesout or die $!;
open PROTOSOUT, ">", $protosout or die $!;
open ASMOUT, ">", $asmout or die $!;
open IN, "<", $in or die $!;

print CODESOUT <<"END";
/* Autogenerated, don't edit */
#ifndef $codesdef
#define $codesdef
END

print PROTOSOUT <<"END";
/* Autogenerated, don't edit */
#ifndef $protosdef
#define $protosdef
#include <$prototypes>
#include <$codes>
END

print ASMOUT <<"END";
/* Autogenerated, don't edit */
#include <$codes>
#include "$asmcommon"
END


for (<IN>) {
if ($_ =~ /\#/) {
next;
}

my $code_macro;
my $sys_macro;
my $sys_name;

if (/(?<name>\S+)\s+(?<alias>\S+)\s+(?<code64>\d+|\!)\s+(?<code32>(?:\d+|\!))\s+\((?<args>.+)\)/) {
$code_macro = "__NR_$+{name}";
$sys_macro = "SYS_$+{name}";
$sys_name = "sys_$+{alias}";
} elsif (/(?<name>\S+)\s+(?<code64>\d+|\!)\s+(?<code32>(?:\d+|\!))\s+\((?<args>.+)\)/) {
$code_macro = "__NR_$+{name}";
$sys_macro = "SYS_$+{name}";
$sys_name = "sys_$+{name}";
} else {
unlink $codesout;
unlink $protosout;
unlink $asmout;

die "Invalid syscall definition file: invalid entry $_\n";
}

if ($+{$code} ne "!") {
print CODESOUT "#ifndef $code_macro\n#define $code_macro $+{$code}\n#endif\n";
print CODESOUT "#ifndef $sys_macro\n#define $sys_macro $code_macro\n#endif\n";
print ASMOUT "syscall $sys_name, $code_macro\n";

} else {
$need_aux = 1;
}

print PROTOSOUT "extern long $sys_name($+{args});\n";
}

if ($need_aux == 1) {
print ASMOUT "#include <compel/plugins/std/syscall-aux.S>\n";
print CODESOUT "#include <compel/plugins/std/syscall-aux.h>\n";
}

print CODESOUT "#endif /* $codesdef */";
print PROTOSOUT "#endif /* $protosdef */";
37 changes: 37 additions & 0 deletions compel/arch/riscv64/plugins/std/syscalls/syscall-aux.S
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/**
* This source contains emulation of syscalls
* that are not implemented in the riscv64 Linux kernel
*/

ENTRY(sys_open)
add a3, x0, a2
add a2, x0, a1
add a1, x0, a0
addi a0, x0, -100
j sys_openat
END(sys_open)


ENTRY(sys_mkdir)
add a3,x0, a2
add a2, x0, a1
add a1, x0, a0
addi a0, x0, -100
j sys_mkdirat
END(sys_mkdir)


ENTRY(sys_rmdir)
addi a2, x0, 0x200 // flags = AT_REMOVEDIR
add a1, x0, a0
addi a0, x0, -100
j sys_unlinkat
END(sys_rmdir)


ENTRY(sys_unlink)
addi a2, x0, 0 // flags = 0
add a1, x0, a0
addi a0, x0, -100
j sys_unlinkat
END(sys_unlink)
3 changes: 3 additions & 0 deletions compel/arch/riscv64/plugins/std/syscalls/syscall-aux.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#ifndef __NR_openat
#define __NR_openat 56
#endif
17 changes: 17 additions & 0 deletions compel/arch/riscv64/plugins/std/syscalls/syscall-common.S
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#include "common/asm/linkage.h"

syscall_common:
ecall
ret

.macro syscall name, nr
ENTRY(\name)
li a7, \nr
j syscall_common
END(\name)
.endm

ENTRY(__cr_restore_rt)
li a7, __NR_rt_sigreturn
ecall
END(__cr_restore_rt)
Loading
Loading