* [PATCH v2 1/6] linux-user/loongarch64: Use traps to track LSX/LASX usage
2023-11-01 3:08 [PATCH v2 0/6] linux-user/loongarch64: Add LSX/LASX sigcontext Song Gao
@ 2023-11-01 3:08 ` Song Gao
2023-11-01 3:08 ` [PATCH v2 2/6] linux-user/loongarch64: Fix setup_extcontext alloc wrong fpu_context size Song Gao
` (4 subsequent siblings)
5 siblings, 0 replies; 10+ messages in thread
From: Song Gao @ 2023-11-01 3:08 UTC (permalink / raw)
To: qemu-devel; +Cc: richard.henderson, philmd, laurent, maobibo
From: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
linux-user/loongarch64/cpu_loop.c | 13 +++++++++++++
target/loongarch/insn_trans/trans_vec.c.inc | 11 -----------
2 files changed, 13 insertions(+), 11 deletions(-)
diff --git a/linux-user/loongarch64/cpu_loop.c b/linux-user/loongarch64/cpu_loop.c
index 894fdd111a..73d7b6796a 100644
--- a/linux-user/loongarch64/cpu_loop.c
+++ b/linux-user/loongarch64/cpu_loop.c
@@ -72,6 +72,19 @@ void cpu_loop(CPULoongArchState *env)
case EXCCODE_BCE:
force_sig_fault(TARGET_SIGSYS, TARGET_SI_KERNEL, env->pc);
break;
+
+ /*
+ * Begin with LSX and LASX disabled, then enable on the first trap.
+ * In this way we can tell if the unit is in use. This is used to
+ * choose the layout of any signal frame.
+ */
+ case EXCCODE_SXD:
+ env->CSR_EUEN |= R_CSR_EUEN_SXE_MASK;
+ break;
+ case EXCCODE_ASXD:
+ env->CSR_EUEN |= R_CSR_EUEN_ASXE_MASK;
+ break;
+
case EXCP_ATOMIC:
cpu_exec_step_atomic(cs);
break;
diff --git a/target/loongarch/insn_trans/trans_vec.c.inc b/target/loongarch/insn_trans/trans_vec.c.inc
index 98f856bb29..92b1d22e28 100644
--- a/target/loongarch/insn_trans/trans_vec.c.inc
+++ b/target/loongarch/insn_trans/trans_vec.c.inc
@@ -4,8 +4,6 @@
* Copyright (c) 2022-2023 Loongson Technology Corporation Limited
*/
-#ifndef CONFIG_USER_ONLY
-
static bool check_vec(DisasContext *ctx, uint32_t oprsz)
{
if ((oprsz == 16) && ((ctx->base.tb->flags & HW_FLAGS_EUEN_SXE) == 0)) {
@@ -21,15 +19,6 @@ static bool check_vec(DisasContext *ctx, uint32_t oprsz)
return true;
}
-#else
-
-static bool check_vec(DisasContext *ctx, uint32_t oprsz)
-{
- return true;
-}
-
-#endif
-
static bool gen_vvvv_ptr_vl(DisasContext *ctx, arg_vvvv *a, uint32_t oprsz,
gen_helper_gvec_4_ptr *fn)
{
--
2.25.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH v2 2/6] linux-user/loongarch64: Fix setup_extcontext alloc wrong fpu_context size
2023-11-01 3:08 [PATCH v2 0/6] linux-user/loongarch64: Add LSX/LASX sigcontext Song Gao
2023-11-01 3:08 ` [PATCH v2 1/6] linux-user/loongarch64: Use traps to track LSX/LASX usage Song Gao
@ 2023-11-01 3:08 ` Song Gao
2023-11-01 3:08 ` [PATCH v2 3/6] linux-user/loongarch64: setup_sigframe() set 'end' context size 0 Song Gao
` (3 subsequent siblings)
5 siblings, 0 replies; 10+ messages in thread
From: Song Gao @ 2023-11-01 3:08 UTC (permalink / raw)
To: qemu-devel; +Cc: richard.henderson, philmd, laurent, maobibo
See:
https://github.com/torvalds/linux/blob/master/arch/loongarch/kernel/signal.c
The alloc size is sizeof(struct target_fpu_context).
Signed-off-by: Song Gao <gaosong@loongson.cn>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
---
linux-user/loongarch64/signal.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/linux-user/loongarch64/signal.c b/linux-user/loongarch64/signal.c
index afcee641a6..6844f187ee 100644
--- a/linux-user/loongarch64/signal.c
+++ b/linux-user/loongarch64/signal.c
@@ -115,7 +115,7 @@ static abi_ptr setup_extcontext(struct extctx_layout *extctx, abi_ptr sp)
/* For qemu, there is no lazy fp context switch, so fp always present. */
extctx->flags = SC_USED_FP;
sp = extframe_alloc(extctx, &extctx->fpu,
- sizeof(struct target_rt_sigframe), FPU_CTX_ALIGN, sp);
+ sizeof(struct target_fpu_context), FPU_CTX_ALIGN, sp);
return sp;
}
--
2.25.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH v2 3/6] linux-user/loongarch64: setup_sigframe() set 'end' context size 0
2023-11-01 3:08 [PATCH v2 0/6] linux-user/loongarch64: Add LSX/LASX sigcontext Song Gao
2023-11-01 3:08 ` [PATCH v2 1/6] linux-user/loongarch64: Use traps to track LSX/LASX usage Song Gao
2023-11-01 3:08 ` [PATCH v2 2/6] linux-user/loongarch64: Fix setup_extcontext alloc wrong fpu_context size Song Gao
@ 2023-11-01 3:08 ` Song Gao
2023-11-01 3:08 ` [PATCH v2 4/6] linux-user/loongarch64: Use abi_{ulong,uint} types Song Gao
` (2 subsequent siblings)
5 siblings, 0 replies; 10+ messages in thread
From: Song Gao @ 2023-11-01 3:08 UTC (permalink / raw)
To: qemu-devel; +Cc: richard.henderson, philmd, laurent, maobibo
See:
https://github.com/torvalds/linux/blob/master/arch/loongarch/kernel/signal.c
The kernel setup_sigcontext() set end context size 0.
Signed-off-by: Song Gao <gaosong@loongson.cn>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
---
linux-user/loongarch64/signal.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/linux-user/loongarch64/signal.c b/linux-user/loongarch64/signal.c
index 6844f187ee..cc8324b4b3 100644
--- a/linux-user/loongarch64/signal.c
+++ b/linux-user/loongarch64/signal.c
@@ -154,7 +154,7 @@ static void setup_sigframe(CPULoongArchState *env,
*/
info = extctx->end.haddr;
__put_user(0, &info->magic);
- __put_user(extctx->end.size, &info->size);
+ __put_user(0, &info->size);
}
static bool parse_extcontext(struct extctx_layout *extctx, abi_ptr frame)
--
2.25.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH v2 4/6] linux-user/loongarch64: Use abi_{ulong,uint} types
2023-11-01 3:08 [PATCH v2 0/6] linux-user/loongarch64: Add LSX/LASX sigcontext Song Gao
` (2 preceding siblings ...)
2023-11-01 3:08 ` [PATCH v2 3/6] linux-user/loongarch64: setup_sigframe() set 'end' context size 0 Song Gao
@ 2023-11-01 3:08 ` Song Gao
2023-11-01 3:10 ` [PATCH v2 4/6] linux-user/loongarch64: Use abi_{ulong, uint} types Richard Henderson
2023-11-01 3:08 ` [PATCH v2 5/6] linux-user/loongarch64: Add LSX sigcontext save/restore Song Gao
2023-11-01 3:08 ` [PATCH v2 6/6] linux-user/loongarch64: Add LASX " Song Gao
5 siblings, 1 reply; 10+ messages in thread
From: Song Gao @ 2023-11-01 3:08 UTC (permalink / raw)
To: qemu-devel; +Cc: richard.henderson, philmd, laurent, maobibo
Signed-off-by: Song Gao <gaosong@loongson.cn>
---
linux-user/loongarch64/signal.c | 24 ++++++++++++------------
1 file changed, 12 insertions(+), 12 deletions(-)
diff --git a/linux-user/loongarch64/signal.c b/linux-user/loongarch64/signal.c
index cc8324b4b3..9336f40ffe 100644
--- a/linux-user/loongarch64/signal.c
+++ b/linux-user/loongarch64/signal.c
@@ -18,10 +18,10 @@
#define SC_USED_FP (1 << 0)
struct target_sigcontext {
- uint64_t sc_pc;
- uint64_t sc_regs[32];
- uint32_t sc_flags;
- uint64_t sc_extcontext[0] QEMU_ALIGNED(16);
+ abi_ulong sc_pc;
+ abi_ulong sc_regs[32];
+ abi_uint sc_flags;
+ abi_ulong sc_extcontext[0] QEMU_ALIGNED(16);
};
QEMU_BUILD_BUG_ON(sizeof(struct target_sigcontext) != sizeof_sigcontext);
@@ -33,9 +33,9 @@ QEMU_BUILD_BUG_ON(offsetof(struct target_sigcontext, sc_regs)
#define FPU_CTX_MAGIC 0x46505501
#define FPU_CTX_ALIGN 8
struct target_fpu_context {
- uint64_t regs[32];
- uint64_t fcc;
- uint32_t fcsr;
+ abi_ulong regs[32];
+ abi_ulong fcc;
+ abi_uint fcsr;
} QEMU_ALIGNED(FPU_CTX_ALIGN);
QEMU_BUILD_BUG_ON(offsetof(struct target_fpu_context, regs)
@@ -43,9 +43,9 @@ QEMU_BUILD_BUG_ON(offsetof(struct target_fpu_context, regs)
#define CONTEXT_INFO_ALIGN 16
struct target_sctx_info {
- uint32_t magic;
- uint32_t size;
- uint64_t padding;
+ abi_uint magic;
+ abi_uint size;
+ abi_ulong padding;
} QEMU_ALIGNED(CONTEXT_INFO_ALIGN);
QEMU_BUILD_BUG_ON(sizeof(struct target_sctx_info) != sizeof_sctx_info);
@@ -162,7 +162,7 @@ static bool parse_extcontext(struct extctx_layout *extctx, abi_ptr frame)
memset(extctx, 0, sizeof(*extctx));
while (1) {
- uint32_t magic, size;
+ abi_uint magic, size;
if (get_user_u32(magic, frame) || get_user_u32(size, frame + 4)) {
return false;
@@ -206,7 +206,7 @@ static void restore_sigframe(CPULoongArchState *env,
if (extctx->fpu.haddr) {
struct target_fpu_context *fpu_ctx =
extctx->fpu.haddr + sizeof(struct target_sctx_info);
- uint64_t fcc;
+ abi_ulong fcc;
for (i = 0; i < 32; ++i) {
__get_user(env->fpr[i].vreg.D(0), &fpu_ctx->regs[i]);
--
2.25.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH v2 5/6] linux-user/loongarch64: Add LSX sigcontext save/restore
2023-11-01 3:08 [PATCH v2 0/6] linux-user/loongarch64: Add LSX/LASX sigcontext Song Gao
` (3 preceding siblings ...)
2023-11-01 3:08 ` [PATCH v2 4/6] linux-user/loongarch64: Use abi_{ulong,uint} types Song Gao
@ 2023-11-01 3:08 ` Song Gao
2023-11-01 3:13 ` Richard Henderson
2023-11-01 3:08 ` [PATCH v2 6/6] linux-user/loongarch64: Add LASX " Song Gao
5 siblings, 1 reply; 10+ messages in thread
From: Song Gao @ 2023-11-01 3:08 UTC (permalink / raw)
To: qemu-devel; +Cc: richard.henderson, philmd, laurent, maobibo
Signed-off-by: Song Gao <gaosong@loongson.cn>
---
linux-user/loongarch64/signal.c | 107 ++++++++++++++++++++++++++------
1 file changed, 87 insertions(+), 20 deletions(-)
diff --git a/linux-user/loongarch64/signal.c b/linux-user/loongarch64/signal.c
index 9336f40ffe..9c9b446a91 100644
--- a/linux-user/loongarch64/signal.c
+++ b/linux-user/loongarch64/signal.c
@@ -41,6 +41,14 @@ struct target_fpu_context {
QEMU_BUILD_BUG_ON(offsetof(struct target_fpu_context, regs)
!= offsetof_fpucontext_fr);
+#define LSX_CTX_MAGIC 0x53580001
+#define LSX_CTX_ALIGN 16
+struct target_lsx_context {
+ abi_ulong regs[2 * 32];
+ abi_ulong fcc;
+ abi_uint fcsr;
+} QEMU_ALIGNED(LSX_CTX_ALIGN);
+
#define CONTEXT_INFO_ALIGN 16
struct target_sctx_info {
abi_uint magic;
@@ -81,9 +89,10 @@ struct ctx_layout {
};
struct extctx_layout {
- unsigned int size;
+ unsigned long size;
unsigned int flags;
struct ctx_layout fpu;
+ struct ctx_layout lsx;
struct ctx_layout end;
};
@@ -105,7 +114,8 @@ static abi_ptr extframe_alloc(struct extctx_layout *extctx,
return sp;
}
-static abi_ptr setup_extcontext(struct extctx_layout *extctx, abi_ptr sp)
+static abi_ptr setup_extcontext(CPULoongArchState *env,
+ struct extctx_layout *extctx, abi_ptr sp)
{
memset(extctx, 0, sizeof(struct extctx_layout));
@@ -114,8 +124,15 @@ static abi_ptr setup_extcontext(struct extctx_layout *extctx, abi_ptr sp)
/* For qemu, there is no lazy fp context switch, so fp always present. */
extctx->flags = SC_USED_FP;
- sp = extframe_alloc(extctx, &extctx->fpu,
+
+ if (FIELD_EX64(env->CSR_EUEN, CSR_EUEN, SXE)) {
+ sp = extframe_alloc(extctx, &extctx->lsx,
+ sizeof(struct target_lsx_context), LSX_CTX_ALIGN, sp);
+
+ } else {
+ sp = extframe_alloc(extctx, &extctx->fpu,
sizeof(struct target_fpu_context), FPU_CTX_ALIGN, sp);
+ }
return sp;
}
@@ -125,7 +142,6 @@ static void setup_sigframe(CPULoongArchState *env,
struct extctx_layout *extctx)
{
struct target_sctx_info *info;
- struct target_fpu_context *fpu_ctx;
int i;
__put_user(extctx->flags, &sc->sc_flags);
@@ -136,18 +152,39 @@ static void setup_sigframe(CPULoongArchState *env,
}
/*
- * Set fpu context
+ * Set extension context
*/
- info = extctx->fpu.haddr;
- __put_user(FPU_CTX_MAGIC, &info->magic);
- __put_user(extctx->fpu.size, &info->size);
- fpu_ctx = (struct target_fpu_context *)(info + 1);
- for (i = 0; i < 32; ++i) {
- __put_user(env->fpr[i].vreg.D(0), &fpu_ctx->regs[i]);
+ if (FIELD_EX64(env->CSR_EUEN, CSR_EUEN, SXE)) {
+ struct target_lsx_context *lsx_ctx;
+ info = extctx->lsx.haddr;
+
+ __put_user(LSX_CTX_MAGIC, &info->magic);
+ __put_user(extctx->lsx.size, &info->size);
+
+ lsx_ctx = (struct target_lsx_context *)(info + 1);
+
+ for (i = 0; i < 32; ++i) {
+ __put_user(env->fpr[i].vreg.UD(0), &lsx_ctx->regs[2 * i]);
+ __put_user(env->fpr[i].vreg.UD(1), &lsx_ctx->regs[2 * i + 1]);
+ }
+ __put_user(read_fcc(env), &lsx_ctx->fcc);
+ __put_user(env->fcsr0, &lsx_ctx->fcsr);
+ } else {
+ struct target_fpu_context *fpu_ctx;
+ info = extctx->fpu.haddr;
+
+ __put_user(FPU_CTX_MAGIC, &info->magic);
+ __put_user(extctx->fpu.size, &info->size);
+
+ fpu_ctx = (struct target_fpu_context *)(info + 1);
+
+ for (i = 0; i < 32; ++i) {
+ __put_user(env->fpr[i].vreg.UD(0), &fpu_ctx->regs[i]);
+ }
+ __put_user(read_fcc(env), &fpu_ctx->fcc);
+ __put_user(env->fcsr0, &fpu_ctx->fcsr);
}
- __put_user(read_fcc(env), &fpu_ctx->fcc);
- __put_user(env->fcsr0, &fpu_ctx->fcsr);
/*
* Set end context
@@ -184,6 +221,15 @@ static bool parse_extcontext(struct extctx_layout *extctx, abi_ptr frame)
extctx->fpu.size = size;
extctx->size += size;
break;
+ case LSX_CTX_MAGIC:
+ if (size < (sizeof(struct target_sctx_info) +
+ sizeof(struct target_lsx_context))) {
+ return false;
+ }
+ extctx->lsx.gaddr = frame;
+ extctx->lsx.size = size;
+ extctx->size += size;
+ break;
default:
return false;
}
@@ -197,19 +243,31 @@ static void restore_sigframe(CPULoongArchState *env,
struct extctx_layout *extctx)
{
int i;
+ abi_ulong fcc;
__get_user(env->pc, &sc->sc_pc);
for (i = 1; i < 32; ++i) {
__get_user(env->gpr[i], &sc->sc_regs[i]);
}
- if (extctx->fpu.haddr) {
+ if (extctx->lsx.haddr) {
+ struct target_lsx_context *lsx_ctx =
+ extctx->lsx.haddr + sizeof(struct target_sctx_info);
+
+ for (i = 0; i < 32; ++i) {
+ __get_user(env->fpr[i].vreg.UD(0), &lsx_ctx->regs[2 * i]);
+ __get_user(env->fpr[i].vreg.UD(1), &lsx_ctx->regs[2 * i + 1]);
+ }
+ __get_user(fcc, &lsx_ctx->fcc);
+ write_fcc(env, fcc);
+ __get_user(env->fcsr0, &lsx_ctx->fcsr);
+ restore_fp_status(env);
+ } else if (extctx->fpu.haddr) {
struct target_fpu_context *fpu_ctx =
extctx->fpu.haddr + sizeof(struct target_sctx_info);
- abi_ulong fcc;
for (i = 0; i < 32; ++i) {
- __get_user(env->fpr[i].vreg.D(0), &fpu_ctx->regs[i]);
+ __get_user(env->fpr[i].vreg.UD(0), &fpu_ctx->regs[i]);
}
__get_user(fcc, &fpu_ctx->fcc);
write_fcc(env, fcc);
@@ -229,7 +287,7 @@ static abi_ptr get_sigframe(struct target_sigaction *ka,
sp = target_sigsp(get_sp_from_cpustate(env), ka);
sp = ROUND_DOWN(sp, 16);
- sp = setup_extcontext(extctx, sp);
+ sp = setup_extcontext(env, extctx, sp);
sp -= sizeof(struct target_rt_sigframe);
assert(QEMU_IS_ALIGNED(sp, 16));
@@ -255,8 +313,14 @@ void setup_rt_frame(int sig, struct target_sigaction *ka,
force_sigsegv(sig);
return;
}
- extctx.fpu.haddr = (void *)frame + (extctx.fpu.gaddr - frame_addr);
- extctx.end.haddr = (void *)frame + (extctx.end.gaddr - frame_addr);
+
+ if (FIELD_EX64(env->CSR_EUEN, CSR_EUEN, SXE)) {
+ extctx.lsx.haddr = (void *)frame + (extctx.lsx.gaddr - frame_addr);
+ extctx.end.haddr = (void *)frame + (extctx.end.gaddr - frame_addr);
+ } else {
+ extctx.fpu.haddr = (void *)frame + (extctx.fpu.gaddr - frame_addr);
+ extctx.end.haddr = (void *)frame + (extctx.end.gaddr - frame_addr);
+ }
tswap_siginfo(&frame->rs_info, info);
@@ -299,7 +363,10 @@ long do_rt_sigreturn(CPULoongArchState *env)
if (!frame) {
goto badframe;
}
- if (extctx.fpu.gaddr) {
+
+ if (extctx.lsx.gaddr) {
+ extctx.lsx.haddr = (void *)frame + (extctx.lsx.gaddr - frame_addr);
+ } else if (extctx.fpu.gaddr) {
extctx.fpu.haddr = (void *)frame + (extctx.fpu.gaddr - frame_addr);
}
--
2.25.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH v2 6/6] linux-user/loongarch64: Add LASX sigcontext save/restore
2023-11-01 3:08 [PATCH v2 0/6] linux-user/loongarch64: Add LSX/LASX sigcontext Song Gao
` (4 preceding siblings ...)
2023-11-01 3:08 ` [PATCH v2 5/6] linux-user/loongarch64: Add LSX sigcontext save/restore Song Gao
@ 2023-11-01 3:08 ` Song Gao
2023-11-01 3:14 ` Richard Henderson
5 siblings, 1 reply; 10+ messages in thread
From: Song Gao @ 2023-11-01 3:08 UTC (permalink / raw)
To: qemu-devel; +Cc: richard.henderson, philmd, laurent, maobibo
Signed-off-by: Song Gao <gaosong@loongson.cn>
---
linux-user/loongarch64/signal.c | 68 ++++++++++++++++++++++++++++++---
1 file changed, 62 insertions(+), 6 deletions(-)
diff --git a/linux-user/loongarch64/signal.c b/linux-user/loongarch64/signal.c
index 9c9b446a91..39ea82c814 100644
--- a/linux-user/loongarch64/signal.c
+++ b/linux-user/loongarch64/signal.c
@@ -49,6 +49,14 @@ struct target_lsx_context {
abi_uint fcsr;
} QEMU_ALIGNED(LSX_CTX_ALIGN);
+#define LASX_CTX_MAGIC 0x41535801
+#define LASX_CTX_ALIGN 32
+struct target_lasx_context {
+ abi_ulong regs[4 * 32];
+ abi_ulong fcc;
+ abi_uint fcsr;
+} QEMU_ALIGNED(LASX_CTX_ALIGN);
+
#define CONTEXT_INFO_ALIGN 16
struct target_sctx_info {
abi_uint magic;
@@ -93,6 +101,7 @@ struct extctx_layout {
unsigned int flags;
struct ctx_layout fpu;
struct ctx_layout lsx;
+ struct ctx_layout lasx;
struct ctx_layout end;
};
@@ -125,10 +134,12 @@ static abi_ptr setup_extcontext(CPULoongArchState *env,
/* For qemu, there is no lazy fp context switch, so fp always present. */
extctx->flags = SC_USED_FP;
- if (FIELD_EX64(env->CSR_EUEN, CSR_EUEN, SXE)) {
+ if (FIELD_EX64(env->CSR_EUEN, CSR_EUEN, ASXE)) {
+ sp = extframe_alloc(extctx, &extctx->lasx,
+ sizeof(struct target_lasx_context), LASX_CTX_ALIGN, sp);
+ } else if (FIELD_EX64(env->CSR_EUEN, CSR_EUEN, SXE)) {
sp = extframe_alloc(extctx, &extctx->lsx,
sizeof(struct target_lsx_context), LSX_CTX_ALIGN, sp);
-
} else {
sp = extframe_alloc(extctx, &extctx->fpu,
sizeof(struct target_fpu_context), FPU_CTX_ALIGN, sp);
@@ -155,7 +166,24 @@ static void setup_sigframe(CPULoongArchState *env,
* Set extension context
*/
- if (FIELD_EX64(env->CSR_EUEN, CSR_EUEN, SXE)) {
+ if (FIELD_EX64(env->CSR_EUEN, CSR_EUEN, ASXE)) {
+ struct target_lasx_context *lasx_ctx;
+ info = extctx->lasx.haddr;
+
+ __put_user(LASX_CTX_MAGIC, &info->magic);
+ __put_user(extctx->lasx.size, &info->size);
+
+ lasx_ctx = (struct target_lasx_context *)(info + 1);
+
+ for (i = 0; i < 32; ++i) {
+ __put_user(env->fpr[i].vreg.UD(0), &lasx_ctx->regs[4 * i]);
+ __put_user(env->fpr[i].vreg.UD(1), &lasx_ctx->regs[4 * i + 1]);
+ __put_user(env->fpr[i].vreg.UD(2), &lasx_ctx->regs[4 * i + 2]);
+ __put_user(env->fpr[i].vreg.UD(3), &lasx_ctx->regs[4 * i + 3]);
+ }
+ __put_user(read_fcc(env), &lasx_ctx->fcc);
+ __put_user(env->fcsr0, &lasx_ctx->fcsr);
+ } else if (FIELD_EX64(env->CSR_EUEN, CSR_EUEN, SXE)) {
struct target_lsx_context *lsx_ctx;
info = extctx->lsx.haddr;
@@ -230,6 +258,15 @@ static bool parse_extcontext(struct extctx_layout *extctx, abi_ptr frame)
extctx->lsx.size = size;
extctx->size += size;
break;
+ case LASX_CTX_MAGIC:
+ if (size < (sizeof(struct target_sctx_info) +
+ sizeof(struct target_lasx_context))) {
+ return false;
+ }
+ extctx->lasx.gaddr = frame;
+ extctx->lasx.size = size;
+ extctx->size += size;
+ break;
default:
return false;
}
@@ -250,7 +287,21 @@ static void restore_sigframe(CPULoongArchState *env,
__get_user(env->gpr[i], &sc->sc_regs[i]);
}
- if (extctx->lsx.haddr) {
+ if (extctx->lasx.haddr) {
+ struct target_lasx_context *lasx_ctx =
+ extctx->lasx.haddr + sizeof(struct target_sctx_info);
+
+ for (i = 0; i < 32; ++i) {
+ __get_user(env->fpr[i].vreg.UD(0), &lasx_ctx->regs[4 * i]);
+ __get_user(env->fpr[i].vreg.UD(1), &lasx_ctx->regs[4 * i + 1]);
+ __get_user(env->fpr[i].vreg.UD(2), &lasx_ctx->regs[4 * i + 2]);
+ __get_user(env->fpr[i].vreg.UD(3), &lasx_ctx->regs[4 * i + 3]);
+ }
+ __get_user(fcc, &lasx_ctx->fcc);
+ write_fcc(env, fcc);
+ __get_user(env->fcsr0, &lasx_ctx->fcsr);
+ restore_fp_status(env);
+ } else if (extctx->lsx.haddr) {
struct target_lsx_context *lsx_ctx =
extctx->lsx.haddr + sizeof(struct target_sctx_info);
@@ -314,7 +365,10 @@ void setup_rt_frame(int sig, struct target_sigaction *ka,
return;
}
- if (FIELD_EX64(env->CSR_EUEN, CSR_EUEN, SXE)) {
+ if (FIELD_EX64(env->CSR_EUEN, CSR_EUEN, ASXE)) {
+ extctx.lasx.haddr = (void *)frame + (extctx.lasx.gaddr - frame_addr);
+ extctx.end.haddr = (void *)frame + (extctx.end.gaddr - frame_addr);
+ } else if (FIELD_EX64(env->CSR_EUEN, CSR_EUEN, SXE)) {
extctx.lsx.haddr = (void *)frame + (extctx.lsx.gaddr - frame_addr);
extctx.end.haddr = (void *)frame + (extctx.end.gaddr - frame_addr);
} else {
@@ -364,7 +418,9 @@ long do_rt_sigreturn(CPULoongArchState *env)
goto badframe;
}
- if (extctx.lsx.gaddr) {
+ if (extctx.lasx.gaddr) {
+ extctx.lasx.haddr = (void *)frame + (extctx.lasx.gaddr - frame_addr);
+ } else if (extctx.lsx.gaddr) {
extctx.lsx.haddr = (void *)frame + (extctx.lsx.gaddr - frame_addr);
} else if (extctx.fpu.gaddr) {
extctx.fpu.haddr = (void *)frame + (extctx.fpu.gaddr - frame_addr);
--
2.25.1
^ permalink raw reply related [flat|nested] 10+ messages in thread