qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH v1 0/6] linux-user/loongarch64: Add LSX/LASX sigcontext


From: gaosong
Subject: Re: [PATCH v1 0/6] linux-user/loongarch64: Add LSX/LASX sigcontext
Date: Mon, 23 Oct 2023 10:47:07 +0800
User-agent: Mozilla/5.0 (X11; Linux loongarch64; rv:68.0) Gecko/20100101 Thunderbird/68.7.0

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(-)





reply via email to

[Prev in Thread] Current Thread [Next in Thread]