Message ID | 20231010033701.385725-1-gaosong@loongson.cn (mailing list archive) |
---|---|
Headers | show |
Series | linux-user/loongarch64: Add LSX/LASX sigcontext | expand |
Ping ! 在 2023/10/10 上午11:36, Song Gao 写道: > Hi, All. > > This series adds save/restore sigcontext. > > We use extctx_flags to choces which sigcontext need save/restore. > > The extctx_flags default value is EXTCTX_FLAGS_FPU, we need > save/restore fpu context. > > After a LSX/LASX instruction is execed, extctx_flags value change to > EXTCTX_FLAGS_LSX/LASX, we always need save/restore lsx/lasx context. > > > The test_signal.c is a simple test. > > The default vreg len is 64. After execed a LSX instruction, the vreg len is > 128, and then we exec a FPU instruction, the vreg len is also 128. After > execed a LASX instruction, the vreg len is 256, and then we exec a FPU > instruction, the vreg len is also 256. > > test_signal.c: > > #include <unistd.h> > #include <stdio.h> > #include <stdlib.h> > #include <errno.h> > #include <signal.h> > #include <asm/ucontext.h> > #include <setjmp.h> > #include <stdint.h> > #include <string.h> > > static sigjmp_buf jmpbuf; > > struct _ctx_layout { > struct sctx_info *addr; > unsigned int size; > }; > > struct extctx_layout { > unsigned long size; > unsigned int flags; > struct _ctx_layout fpu; > struct _ctx_layout lsx; > struct _ctx_layout lasx; > struct _ctx_layout end; > }; > static int parse_extcontext(struct sigcontext *sc, struct extctx_layout *extctx) > { > uint32_t magic, size; > struct sctx_info *info = (struct sctx_info *)&sc->sc_extcontext; > > while(1) { > magic = (uint32_t)info->magic; > size = (uint32_t)info->size; > > printf("magic is %lx\n", magic); > printf("size is %lx\n", size); > switch (magic) { > case 0: /* END*/ > return 0; > case FPU_CTX_MAGIC: > if (size < (sizeof(struct sctx_info) + > sizeof(struct fpu_context))) { > return -1; > } > extctx->fpu.addr = info; > break; > case LSX_CTX_MAGIC: > if (size < (sizeof(struct sctx_info) + > sizeof(struct lsx_context))) { > return -1; > } > extctx->lsx.addr = info; > break; > case LASX_CTX_MAGIC: > if (size < (sizeof(struct sctx_info) + > sizeof(struct lasx_context))) { > return -1; > } > extctx->lasx.addr = info; > break; > default: > return -1; > } > info = (struct sctx_info *)((char *)info +size); > } > return 0; > } > > static int n = 0; > > static void do_signal(int sig, siginfo_t *info, void *ucontext) > { > int i; > struct ucontext *uc = (struct ucontext *)ucontext; > struct extctx_layout extctx; > > memset(&extctx, 0, sizeof(struct extctx_layout)); > > printf("pc : %016lx\n", uc->uc_mcontext.sc_pc); > > parse_extcontext(&uc->uc_mcontext, &extctx); > > if (n < 5) { > printf("extctx.lasx.addr is %lx\n", extctx.lasx.addr); > printf("extctx.lsx.addr is %lx\n", extctx.lsx.addr); > printf("extctx.fpu.addr is %lx\n", extctx.fpu.addr); > > if (extctx.lasx.addr) { > struct sctx_info *info = extctx.lasx.addr; > struct lasx_context *lasx_ctx = (struct lasx_context *)((char *)info + > sizeof(struct sctx_info)); > printf("vl : %016lx\n", 256); > } else if (extctx.lsx.addr) { > struct sctx_info *info = extctx.lsx.addr; > struct lsx_context *lsx_ctx = (struct lsx_context *)((char *)info + > sizeof(struct sctx_info)); > printf("vl : %016lx\n", 128); > } else if (extctx.fpu.addr) { > struct sctx_info *info = extctx.fpu.addr; > struct fpu_context *fpu_ctx = (struct fpu_context *)((char *)info + > sizeof(struct sctx_info)); > printf("vl : %016lx\n", 64); > } > } > n++; > > printf("n is -------------- %d\n", n); > if (n == 1) { > // vaddwev.w.hu $vr27, $vr22, $vr29 > asm volatile(".word 0x702ef6db"); > printf("After execed LSX instructons vaddwev.w.hu\n"); > } > > if (n == 2) { > // 0101395e fadd.d $fs6, $ft2, $ft6 > asm volatile(".word 0x0101395e"); > printf("After execed FPU instructions fadd\n"); > } > > if (n == 3) { > // xvextrins.d $xr13, $xr15, 0x59 > asm volatile(".word 0x778165ed"); > printf("After execed LASX instructions xvextrins.d\n"); > } > > if (n == 4) { > // 0101395e fadd.d $fs6, $ft2, $ft6 > asm volatile(".word 0x0101395e"); > printf("After execed FPU instructions fadd\n"); > } > > if (n == 5) { > exit(0); > } > > siglongjmp(jmpbuf, 1); > } > > static int setup_signal(int sig, void (*fn) (int, siginfo_t *, void *)) > { > struct sigaction my_act; > int ret; > > my_act.sa_sigaction = fn; > my_act.sa_flags = SA_SIGINFO; > sigemptyset(&my_act.sa_mask); > > ret = sigaction(sig, &my_act, NULL); > if (ret != 0) { > printf("FAIL: signal %d\n", sig); > return SIG_ERR; > } > } > > int main() > { > setup_signal(SIGSEGV, do_signal); > > sigsetjmp(jmpbuf, 1); > > int result = 0; > void *addr = 0x00012; > result = *(int *)addr; > > return 0; > } > > > On 3A5000 machine: > > [root@archlinux LASX]# ./test_signal > pc : 0000000120000b44 > magic is 46505501 > size is 120 > magic is 0 > size is 0 > extctx.lasx.addr is 0 > extctx.lsx.addr is 0 > extctx.fpu.addr is 7ffffbdd2120 > vl : 0000000000000040 > n is -------------- 1 > After execed LSX instructons vaddwev.w.hu > pc : 0000000120000b44 > magic is 53580001 > size is 220 > magic is 0 > size is 0 > extctx.lasx.addr is 0 > extctx.lsx.addr is 7ffffbdd2020 > extctx.fpu.addr is 0 > vl : 0000000000000080 > n is -------------- 2 > After execed FPU instructions fadd > pc : 0000000120000b44 > magic is 53580001 > size is 220 > magic is 0 > size is 0 > extctx.lasx.addr is 0 > extctx.lsx.addr is 7ffffbdd2020 > extctx.fpu.addr is 0 > vl : 0000000000000080 > n is -------------- 3 > After execed LASX instructions xvextrins.d > pc : 0000000120000b44 > magic is 41535801 > size is 430 > magic is 0 > size is 0 > extctx.lasx.addr is 7ffffbdd1e10 > extctx.lsx.addr is 0 > extctx.fpu.addr is 0 > vl : 0000000000000100 > n is -------------- 4 > After execed FPU instructions fadd > pc : 0000000120000b44 > magic is 41535801 > size is 430 > magic is 0 > size is 0 > extctx.lasx.addr is 7ffffbdd1e10 > extctx.lsx.addr is 0 > extctx.fpu.addr is 0 > vl : 0000000000000100 > n is -------------- 5 > > QEMU user-mode on X86: > > root@loongson-KVM:~/work/code/qemu# ./build/qemu-loongarch64 test_signal > pc : 0000000120000b44 > magic is 46505501 > size is 120 > magic is 0 > size is 0 > extctx.lasx.addr is 0 > extctx.lsx.addr is 0 > extctx.fpu.addr is 7fd92279f110 > vl : 0000000000000040 > n is -------------- 1 > After exec LSX instructons vaddwev.w.hu > pc : 0000000120000b44 > magic is 53580001 > size is 220 > magic is 0 > size is 0 > extctx.lasx.addr is 0 > extctx.lsx.addr is 7fd92279f010 > extctx.fpu.addr is 0 > vl : 0000000000000080 > n is -------------- 2 > After execed FPU instructions fadd > pc : 0000000120000b44 > magic is 53580001 > size is 220 > magic is 0 > size is 0 > extctx.lasx.addr is 0 > extctx.lsx.addr is 7fd92279f010 > extctx.fpu.addr is 0 > vl : 0000000000000080 > n is -------------- 3 > After execed LASX instructions xvextrins.d > pc : 0000000120000b44 > magic is 41535801 > size is 430 > magic is 0 > size is 0 > extctx.lasx.addr is 7fd92279ee00 > extctx.lsx.addr is 0 > extctx.fpu.addr is 0 > vl : 0000000000000100 > n is -------------- 4 > After execed FPU instructions fadd > pc : 0000000120000b44 > magic is 41535801 > size is 430 > magic is 0 > size is 0 > extctx.lasx.addr is 7fd92279ee00 > extctx.lsx.addr is 0 > extctx.fpu.addr is 0 > vl : 0000000000000100 > n is -------------- 5 > > > Please review, thanks. > > Song Gao (6): > target/loongarch: Add env->extctx_flags for user-mode setup extcontext > target/loongarch: Add set_vec_extctx to set LSX/LASX instructions > extctx_flags > linux-user/loongarch64: Fix setup_extcontext alloc wrong fpu_context > size > linux-user/loongarch64: setup_sigframe() set 'end' context size 0 > linux-user/loongarch64: Add LSX sigcontext save/restore > linux-user/loongarch64: Add LASX sigcontext save/restore > > linux-user/loongarch64/signal.c | 168 +++++++++++++++++--- > target/loongarch/cpu.c | 2 + > target/loongarch/cpu.h | 2 + > target/loongarch/insn_trans/trans_vec.c.inc | 12 ++ > target/loongarch/internals.h | 4 + > target/loongarch/translate.c | 3 + > target/loongarch/translate.h | 1 + > 7 files changed, 170 insertions(+), 22 deletions(-) >