Skip to content

Commit 35b3077

Browse files
ancientmodernfelicitiapicostove
authored andcommitted
criu: add riscv64 support to parasite and restorer
Co-authored-by: Yixue Zhao <[email protected]> Co-authored-by: stove <[email protected]> Signed-off-by: Haorong Lu <[email protected]>
1 parent 1a42f63 commit 35b3077

19 files changed

+751
-0
lines changed

criu/arch/riscv64/Makefile

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
builtin-name := crtools.built-in.o
2+
3+
ldflags-y += -r
4+
5+
obj-y += cpu.o
6+
obj-y += crtools.o
7+
obj-y += sigframe.o
8+
obj-y += vdso-lookup.o

criu/arch/riscv64/cpu.c

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
#undef LOG_PREFIX
2+
#define LOG_PREFIX "cpu: "
3+
4+
#include <errno.h>
5+
#include "cpu.h"
6+
7+
int cpu_init(void)
8+
{
9+
return 0;
10+
}
11+
12+
int cpu_dump_cpuinfo(void)
13+
{
14+
return 0;
15+
}
16+
17+
int cpu_validate_cpuinfo(void)
18+
{
19+
return 0;
20+
}
21+
22+
int cpu_dump_cpuinfo_single(void)
23+
{
24+
return -ENOTSUP;
25+
}
26+
27+
int cpu_validate_image_cpuinfo_single(void)
28+
{
29+
return -ENOTSUP;
30+
}
31+
32+
int cpuinfo_dump(void)
33+
{
34+
return -ENOTSUP;
35+
}
36+
37+
int cpuinfo_check(void)
38+
{
39+
return -ENOTSUP;
40+
}

criu/arch/riscv64/crtools.c

Lines changed: 171 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,171 @@
1+
#include <string.h>
2+
#include <unistd.h>
3+
4+
#include <linux/elf.h>
5+
6+
#include "types.h"
7+
#include <compel/asm/processor-flags.h>
8+
9+
#include <compel/asm/infect-types.h>
10+
#include "asm/restorer.h"
11+
#include "common/compiler.h"
12+
#include <compel/ptrace.h>
13+
#include "asm/dump.h"
14+
#include "protobuf.h"
15+
#include "images/core.pb-c.h"
16+
#include "images/creds.pb-c.h"
17+
#include "parasite-syscall.h"
18+
#include "log.h"
19+
#include "util.h"
20+
#include "cpu.h"
21+
#include "restorer.h"
22+
#include "compel/infect.h"
23+
24+
#define assign_reg(dst, src, e) dst->e = (__typeof__(dst->e))(src)->e
25+
26+
int save_task_regs(void *x, user_regs_struct_t *regs, user_fpregs_struct_t *fpsimd)
27+
{
28+
int i;
29+
CoreEntry *core = x;
30+
31+
// Save riscv64 gprs
32+
assign_reg(core->ti_riscv64->gpregs, regs, pc);
33+
assign_reg(core->ti_riscv64->gpregs, regs, ra);
34+
assign_reg(core->ti_riscv64->gpregs, regs, sp);
35+
assign_reg(core->ti_riscv64->gpregs, regs, gp);
36+
assign_reg(core->ti_riscv64->gpregs, regs, tp);
37+
assign_reg(core->ti_riscv64->gpregs, regs, t0);
38+
assign_reg(core->ti_riscv64->gpregs, regs, t1);
39+
assign_reg(core->ti_riscv64->gpregs, regs, t2);
40+
assign_reg(core->ti_riscv64->gpregs, regs, s0);
41+
assign_reg(core->ti_riscv64->gpregs, regs, s1);
42+
assign_reg(core->ti_riscv64->gpregs, regs, a0);
43+
assign_reg(core->ti_riscv64->gpregs, regs, a1);
44+
assign_reg(core->ti_riscv64->gpregs, regs, a2);
45+
assign_reg(core->ti_riscv64->gpregs, regs, a3);
46+
assign_reg(core->ti_riscv64->gpregs, regs, a4);
47+
assign_reg(core->ti_riscv64->gpregs, regs, a5);
48+
assign_reg(core->ti_riscv64->gpregs, regs, a6);
49+
assign_reg(core->ti_riscv64->gpregs, regs, a7);
50+
assign_reg(core->ti_riscv64->gpregs, regs, s2);
51+
assign_reg(core->ti_riscv64->gpregs, regs, s3);
52+
assign_reg(core->ti_riscv64->gpregs, regs, s4);
53+
assign_reg(core->ti_riscv64->gpregs, regs, s5);
54+
assign_reg(core->ti_riscv64->gpregs, regs, s6);
55+
assign_reg(core->ti_riscv64->gpregs, regs, s7);
56+
assign_reg(core->ti_riscv64->gpregs, regs, s8);
57+
assign_reg(core->ti_riscv64->gpregs, regs, s9);
58+
assign_reg(core->ti_riscv64->gpregs, regs, s10);
59+
assign_reg(core->ti_riscv64->gpregs, regs, s11);
60+
assign_reg(core->ti_riscv64->gpregs, regs, t3);
61+
assign_reg(core->ti_riscv64->gpregs, regs, t4);
62+
assign_reg(core->ti_riscv64->gpregs, regs, t5);
63+
assign_reg(core->ti_riscv64->gpregs, regs, t6);
64+
65+
// Save riscv64 fprs
66+
for (i = 0; i < 32; ++i)
67+
assign_reg(core->ti_riscv64->fpsimd, fpsimd, f[i]);
68+
assign_reg(core->ti_riscv64->fpsimd, fpsimd, fcsr);
69+
70+
return 0;
71+
}
72+
73+
int arch_alloc_thread_info(CoreEntry *core)
74+
{
75+
ThreadInfoRiscv64 *ti_riscv64;
76+
UserRiscv64RegsEntry *gpregs;
77+
UserRiscv64DExtEntry *fpsimd;
78+
79+
ti_riscv64 = xmalloc(sizeof(*ti_riscv64));
80+
if (!ti_riscv64)
81+
goto err;
82+
thread_info_riscv64__init(ti_riscv64);
83+
core->ti_riscv64 = ti_riscv64;
84+
85+
gpregs = xmalloc(sizeof(*gpregs));
86+
if (!gpregs)
87+
goto err;
88+
user_riscv64_regs_entry__init(gpregs);
89+
90+
ti_riscv64->gpregs = gpregs;
91+
92+
fpsimd = xmalloc(sizeof(*fpsimd));
93+
if (!fpsimd)
94+
goto err;
95+
user_riscv64_d_ext_entry__init(fpsimd);
96+
ti_riscv64->fpsimd = fpsimd;
97+
fpsimd->f = xmalloc(32 * sizeof(fpsimd->f[0]));
98+
fpsimd->n_f = 32;
99+
if (!fpsimd->f)
100+
goto err;
101+
102+
return 0;
103+
err:
104+
return -1;
105+
}
106+
107+
void arch_free_thread_info(CoreEntry *core)
108+
{
109+
if (core->ti_riscv64) {
110+
if (core->ti_riscv64->fpsimd) {
111+
xfree(core->ti_riscv64->fpsimd->f);
112+
xfree(core->ti_riscv64->fpsimd);
113+
}
114+
xfree(core->ti_riscv64->gpregs);
115+
xfree(core->ti_riscv64);
116+
core->ti_riscv64 = NULL;
117+
}
118+
}
119+
120+
int restore_fpu(struct rt_sigframe *sigframe, CoreEntry *core)
121+
{
122+
int i;
123+
UserRiscv64DExtEntry *fpsimd = core->ti_riscv64->fpsimd;
124+
125+
if (fpsimd->n_f != 32)
126+
return 1;
127+
128+
for (i = 0; i < 32; ++i)
129+
sigframe->uc.uc_mcontext.__fpregs.__d.__f[i] = fpsimd->f[i];
130+
sigframe->uc.uc_mcontext.__fpregs.__d.__fcsr = fpsimd->fcsr;
131+
132+
return 0;
133+
}
134+
135+
int restore_gpregs(struct rt_sigframe *f, UserRiscv64RegsEntry *r)
136+
{
137+
f->uc.uc_mcontext.__gregs[0] = r->pc;
138+
f->uc.uc_mcontext.__gregs[1] = r->ra;
139+
f->uc.uc_mcontext.__gregs[2] = r->sp;
140+
f->uc.uc_mcontext.__gregs[3] = r->gp;
141+
f->uc.uc_mcontext.__gregs[4] = r->tp;
142+
f->uc.uc_mcontext.__gregs[5] = r->t0;
143+
f->uc.uc_mcontext.__gregs[6] = r->t1;
144+
f->uc.uc_mcontext.__gregs[7] = r->t2;
145+
f->uc.uc_mcontext.__gregs[8] = r->s0;
146+
f->uc.uc_mcontext.__gregs[9] = r->s1;
147+
f->uc.uc_mcontext.__gregs[10] = r->a0;
148+
f->uc.uc_mcontext.__gregs[11] = r->a1;
149+
f->uc.uc_mcontext.__gregs[12] = r->a2;
150+
f->uc.uc_mcontext.__gregs[13] = r->a3;
151+
f->uc.uc_mcontext.__gregs[14] = r->a4;
152+
f->uc.uc_mcontext.__gregs[15] = r->a5;
153+
f->uc.uc_mcontext.__gregs[16] = r->a6;
154+
f->uc.uc_mcontext.__gregs[17] = r->a7;
155+
f->uc.uc_mcontext.__gregs[18] = r->s2;
156+
f->uc.uc_mcontext.__gregs[19] = r->s3;
157+
f->uc.uc_mcontext.__gregs[20] = r->s4;
158+
f->uc.uc_mcontext.__gregs[21] = r->s5;
159+
f->uc.uc_mcontext.__gregs[22] = r->s6;
160+
f->uc.uc_mcontext.__gregs[23] = r->s7;
161+
f->uc.uc_mcontext.__gregs[24] = r->s8;
162+
f->uc.uc_mcontext.__gregs[25] = r->s9;
163+
f->uc.uc_mcontext.__gregs[26] = r->s10;
164+
f->uc.uc_mcontext.__gregs[27] = r->s11;
165+
f->uc.uc_mcontext.__gregs[28] = r->t3;
166+
f->uc.uc_mcontext.__gregs[29] = r->t4;
167+
f->uc.uc_mcontext.__gregs[30] = r->t5;
168+
f->uc.uc_mcontext.__gregs[31] = r->t6;
169+
170+
return 0;
171+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
#ifndef __CR_ASM_DUMP_H__
2+
#define __CR_ASM_DUMP_H__
3+
4+
extern int save_task_regs(void *, user_regs_struct_t *, user_fpregs_struct_t *);
5+
extern int arch_alloc_thread_info(CoreEntry *core);
6+
extern void arch_free_thread_info(CoreEntry *core);
7+
8+
static inline void core_put_tls(CoreEntry *core, tls_t tls)
9+
{
10+
core->ti_riscv64->tls = tls;
11+
}
12+
13+
#define get_task_futex_robust_list_compat(pid, info) -1
14+
15+
#endif
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
#ifndef __CR_ASM_INT_H__
2+
#define __CR_ASM_INT_H__
3+
4+
#include "asm-generic/int.h"
5+
6+
#endif /* __CR_ASM_INT_H__ */
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
#ifndef __CR_ASM_KERNDAT_H__
2+
#define __CR_ASM_KERNDAT_H__
3+
4+
#define kdat_compatible_cr() 0
5+
#define kdat_can_map_vdso() 0
6+
7+
#endif /* __CR_ASM_KERNDAT_H__ */
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
#ifndef __CR_ASM_PARASITE_SYSCALL_H__
2+
#define __CR_ASM_PARASITE_SYSCALL_H__
3+
4+
struct parasite_ctl;
5+
6+
#endif
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
#ifndef __ASM_PARASITE_H__
2+
#define __ASM_PARASITE_H__
3+
4+
/*
5+
* This function is used to retrieve the value of the thread pointer (tp)
6+
* in RISC-V architecture, which is typically used for thread-local storage (TLS).
7+
* The value is then stored in the provided tls_t pointer.
8+
*/
9+
static inline void arch_get_tls(tls_t *ptls)
10+
{
11+
tls_t tls;
12+
asm("mv %0, tp" : "=r"(tls));
13+
*ptls = tls;
14+
}
15+
16+
#endif
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
#ifndef __CR_ASM_RESTORE_H__
2+
#define __CR_ASM_RESTORE_H__
3+
4+
#include "asm/restorer.h"
5+
6+
#include "images/core.pb-c.h"
7+
8+
/* clang-format off */
9+
#define JUMP_TO_RESTORER_BLOB(new_sp, restore_task_exec_start, \
10+
task_args) \
11+
asm volatile( \
12+
"and sp, %0, ~15 \n" \
13+
"mv a0, %2 \n" \
14+
"jr %1 \n" \
15+
: \
16+
: "r"(new_sp), \
17+
"r"(restore_task_exec_start), \
18+
"r"(task_args) \
19+
: "a0", "memory")
20+
/* clang-format on */
21+
22+
static inline void core_get_tls(CoreEntry *pcore, tls_t *ptls)
23+
{
24+
*ptls = pcore->ti_riscv64->tls;
25+
}
26+
27+
int restore_fpu(struct rt_sigframe *sigframe, CoreEntry *core);
28+
29+
#endif

0 commit comments

Comments
 (0)