Signed-off-by: Song Gao <gaosong@loongson.cn>
Signed-off-by: Xiaojuan Yang <yangxiaojuan@loongson.cn>
---
linux-user/loongarch64/signal.c | 162 +++++++++++++++++++++++++++++++++
linux-user/loongarch64/target_signal.h | 29 ++++++
2 files changed, 191 insertions(+)
create mode 100644 linux-user/loongarch64/signal.c
create mode 100644 linux-user/loongarch64/target_signal.h
diff --git a/linux-user/loongarch64/signal.c b/linux-user/loongarch64/signal.c
new file mode 100644
index 0000000..8fbc827
--- /dev/null
+++ b/linux-user/loongarch64/signal.c
@@ -0,0 +1,162 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * LoongArch emulation of Linux signals
+ *
+ * Copyright (c) 2021 Loongson Technology Corporation Limited
+ */
+
+#include "qemu/osdep.h"
+#include "qemu.h"
+#include "signal-common.h"
+#include "user-internals.h"
+#include "linux-user/trace.h"
+
+struct target_sigcontext {
+ uint64_t sc_pc;
+ uint64_t sc_gpr[32];
+ uint64_t sc_fpr[32];
+ uint64_t sc_fcc;
+ uint32_t sc_fcsr;
+ uint32_t sc_flags;
+};
+
+struct target_ucontext {
+ target_ulong tuc_flags;
+ target_ulong tuc_link;
+ target_stack_t tuc_stack;
+ target_ulong pad0;
+ struct target_sigcontext tuc_mcontext;
+ target_sigset_t tuc_sigmask;
+};
+
+struct target_rt_sigframe {
+ struct target_siginfo rs_info;
+ struct target_ucontext rs_uc;
+};
+
+static inline void setup_sigcontext(CPULoongArchState *env,
+ struct target_sigcontext *sc)
+{
+ int i;
+
+ __put_user(env->pc, &sc->sc_pc);
+
+ __put_user(0, &sc->sc_gpr[0]);
+ for (i = 1; i < 32; ++i) {
+ __put_user(env->gpr[i], &sc->sc_gpr[i]);
+ }
+
+ for (i = 0; i < 32; ++i) {
+ __put_user(env->fpr[i], &sc->sc_fpr[i]);
+ }
+}
+
+static inline void
+restore_sigcontext(CPULoongArchState *env, struct target_sigcontext *sc)
+{
+ int i;
+
+ __get_user(env->pc, &sc->sc_pc);
+
+ for (i = 1; i < 32; ++i) {
+ __get_user(env->gpr[i], &sc->sc_gpr[i]);
+ }
+
+ for (i = 0; i < 32; ++i) {
+ __get_user(env->fpr[i], &sc->sc_fpr[i]);
+ }
+}
+
+/*
+ * Determine which stack to use..
+ */
+static inline abi_ulong
+get_sigframe(struct target_sigaction *ka, CPULoongArchState *env,
+ size_t frame_size)
+{
+ unsigned long sp;
+
+ sp = target_sigsp(get_sp_from_cpustate(env) - 32, ka);
+
+ return (sp - frame_size) & ~7;
+}
+
+void setup_rt_frame(int sig, struct target_sigaction *ka,
+ target_siginfo_t *info,
+ target_sigset_t *set, CPULoongArchState *env)
+{
+ struct target_rt_sigframe *frame;
+ abi_ulong frame_addr;
+ int i;
+
+ frame_addr = get_sigframe(ka, env, sizeof(*frame));
+ trace_user_setup_rt_frame(env, frame_addr);
+ if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) {
+ goto give_sigsegv;
+ }
+
+ tswap_siginfo(&frame->rs_info, info);
+
+ __put_user(0, &frame->rs_uc.tuc_flags);
+ __put_user(0, &frame->rs_uc.tuc_link);
+ target_save_altstack(&frame->rs_uc.tuc_stack, env);
+
+ setup_sigcontext(env, &frame->rs_uc.tuc_mcontext);
+
+ for (i = 0; i < TARGET_NSIG_WORDS; i++) {
+ __put_user(set->sig[i], &frame->rs_uc.tuc_sigmask.sig[i]);
+ }
+
+ env->gpr[4] = sig;
+ env->gpr[5] = frame_addr + offsetof(struct target_rt_sigframe, rs_info);
+ env->gpr[6] = frame_addr + offsetof(struct target_rt_sigframe, rs_uc);
+ env->gpr[3] = frame_addr;
+ env->gpr[1] = default_rt_sigreturn;
+
+ env->pc = env->gpr[20] = ka->_sa_handler;
+ unlock_user_struct(frame, frame_addr, 1);
+ return;
+
+give_sigsegv:
+ unlock_user_struct(frame, frame_addr, 1);
+ force_sigsegv(sig);
+}
+
+long do_rt_sigreturn(CPULoongArchState *env)
+{
+ struct target_rt_sigframe *frame;
+ abi_ulong frame_addr;
+ sigset_t blocked;
+
+ frame_addr = env->gpr[3];
+ trace_user_do_rt_sigreturn(env, frame_addr);
+ if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1)) {
+ goto badframe;
+ }
+
+ target_to_host_sigset(&blocked, &frame->rs_uc.tuc_sigmask);
+ set_sigmask(&blocked);
+
+ restore_sigcontext(env, &frame->rs_uc.tuc_mcontext);
+ target_restore_altstack(&frame->rs_uc.tuc_stack, env);
+
+ unlock_user_struct(frame, frame_addr, 0);
+ return -TARGET_QEMU_ESIGRETURN;
+
+badframe:
+ unlock_user_struct(frame, frame_addr, 0);
+ force_sig(TARGET_SIGSEGV);
+ return -TARGET_QEMU_ESIGRETURN;
+}
+
+void setup_sigtramp(abi_ulong sigtramp_page)
+{
+ uint32_t *tramp = lock_user(VERIFY_WRITE, sigtramp_page, 8, 0);
+ assert(tramp != NULL);
+
+ __put_user(0x03822c0b, tramp + 0); /* ori a7, a7, 0x8b */
+ __put_user(0x002b0000, tramp + 1); /* syscall 0 */
+
+ default_rt_sigreturn = sigtramp_page;
+ unlock_user(tramp, sigtramp_page, 8);
+}
diff --git a/linux-user/loongarch64/target_signal.h b/linux-user/loongarch64/target_signal.h
new file mode 100644
index 0000000..c5f467b
--- /dev/null
+++ b/linux-user/loongarch64/target_signal.h
@@ -0,0 +1,29 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright (c) 2021 Loongson Technology Corporation Limited
+ */
+
+#ifndef LOONGARCH_TARGET_SIGNAL_H
+#define LOONGARCH_TARGET_SIGNAL_H
+
+/* this struct defines a stack used during syscall handling */
+typedef struct target_sigaltstack {
+ abi_long ss_sp;
+ abi_int ss_flags;
+ abi_ulong ss_size;
+} target_stack_t;
+
+/*
+ * sigaltstack controls
+ */
+#define TARGET_SS_ONSTACK 1
+#define TARGET_SS_DISABLE 2
+
+#define TARGET_MINSIGSTKSZ 2048
+#define TARGET_SIGSTKSZ 8192
+
+#include "../generic/signal.h"
+
+#define TARGET_ARCH_HAS_SIGTRAMP_PAGE 1
+
+#endif /* LOONGARCH_TARGET_SIGNAL_H */
--
1.8.3.1
On 11/19/21 7:13 AM, Song Gao wrote:
> Signed-off-by: Song Gao <gaosong@loongson.cn>
> Signed-off-by: Xiaojuan Yang <yangxiaojuan@loongson.cn>
> ---
> linux-user/loongarch64/signal.c | 162 +++++++++++++++++++++++++++++++++
> linux-user/loongarch64/target_signal.h | 29 ++++++
> 2 files changed, 191 insertions(+)
> create mode 100644 linux-user/loongarch64/signal.c
> create mode 100644 linux-user/loongarch64/target_signal.h
>
> diff --git a/linux-user/loongarch64/signal.c b/linux-user/loongarch64/signal.c
> new file mode 100644
> index 0000000..8fbc827
> --- /dev/null
> +++ b/linux-user/loongarch64/signal.c
> @@ -0,0 +1,162 @@
> +/* SPDX-License-Identifier: GPL-2.0-or-later */
> +/*
> + * LoongArch emulation of Linux signals
> + *
> + * Copyright (c) 2021 Loongson Technology Corporation Limited
> + */
> +
> +#include "qemu/osdep.h"
> +#include "qemu.h"
> +#include "signal-common.h"
> +#include "user-internals.h"
> +#include "linux-user/trace.h"
> +
> +struct target_sigcontext {
> + uint64_t sc_pc;
> + uint64_t sc_gpr[32];
> + uint64_t sc_fpr[32];
> + uint64_t sc_fcc;
> + uint32_t sc_fcsr;
> + uint32_t sc_flags;
> +};
Does not match
https://github.com/loongson/linux/blob/loongarch-next/arch/loongarch/include/uapi/asm/sigcontext.h
> +
> +struct target_ucontext {
> + target_ulong tuc_flags;
> + target_ulong tuc_link;
> + target_stack_t tuc_stack;
> + target_ulong pad0;
> + struct target_sigcontext tuc_mcontext;
> + target_sigset_t tuc_sigmask;
> +};
Does not match
https://github.com/loongson/linux/blob/loongarch-next/arch/loongarch/include/uapi/asm/ucontext.h
> +static inline void setup_sigcontext(CPULoongArchState *env,
> + struct target_sigcontext *sc)
Drop all of the the inline markers.
> +{
> + int i;
> +
> + __put_user(env->pc, &sc->sc_pc);
> +
> + __put_user(0, &sc->sc_gpr[0]);
> + for (i = 1; i < 32; ++i) {
> + __put_user(env->gpr[i], &sc->sc_gpr[i]);
> + }
> +
> + for (i = 0; i < 32; ++i) {
> + __put_user(env->fpr[i], &sc->sc_fpr[i]);
> + }
> +}
Missing fcsr and fcc.
I'll note that the kernel is missing sets of vscr and scr[0-3]. IMO they should at least
be zeroed in advance of supporting the vector extension.
> +static inline void
> +restore_sigcontext(CPULoongArchState *env, struct target_sigcontext *sc)
> +{
> + int i;
> +
> + __get_user(env->pc, &sc->sc_pc);
> +
> + for (i = 1; i < 32; ++i) {
> + __get_user(env->gpr[i], &sc->sc_gpr[i]);
> + }
> +
> + for (i = 0; i < 32; ++i) {
> + __get_user(env->fpr[i], &sc->sc_fpr[i]);
> + }
> +}
Similarly.
> + return (sp - frame_size) & ~7;
include/asm/asm.h:#define ALMASK ~15
kernel/signal.c: return (void __user *)((sp - frame_size) & ALMASK);
> + env->pc = env->gpr[20] = ka->_sa_handler;
There is no set of gpr[20].
> +void setup_sigtramp(abi_ulong sigtramp_page)
> +{
> + uint32_t *tramp = lock_user(VERIFY_WRITE, sigtramp_page, 8, 0);
> + assert(tramp != NULL);
> +
> + __put_user(0x03822c0b, tramp + 0); /* ori a7, a7, 0x8b */
The comment is incorrect: "ori a7, zero, 0x8b", but the hex is right.
> +/* this struct defines a stack used during syscall handling */
> +typedef struct target_sigaltstack {
> + abi_long ss_sp;
> + abi_int ss_flags;
> + abi_ulong ss_size;
> +} target_stack_t;
> +
> +/*
> + * sigaltstack controls
> + */
> +#define TARGET_SS_ONSTACK 1
> +#define TARGET_SS_DISABLE 2
> +
> +#define TARGET_MINSIGSTKSZ 2048
> +#define TARGET_SIGSTKSZ 8192
We should move these to generic/signal.h.
r~
Hi Richard,
On 2021/11/20 下午6:33, Richard Henderson wrote:
>> +{
>> + int i;
>> +
>> + __put_user(env->pc, &sc->sc_pc);
>> +
>> + __put_user(0, &sc->sc_gpr[0]);
>> + for (i = 1; i < 32; ++i) {
>> + __put_user(env->gpr[i], &sc->sc_gpr[i]);
>> + }
>> +
>> + for (i = 0; i < 32; ++i) {
>> + __put_user(env->fpr[i], &sc->sc_fpr[i]);
>> + }
>> +}
>
> Missing fcsr and fcc.
I see that kernel define the fcc used type uint64_t, and used
movgr2cf/movcf2gr save and restore the fcc0-fcc7.
but qemu define fcc0-fcc7 as bool cf[8] at target/loongarch/cpu.h,
how qemu can save/restore fcc, Do you have any idea?
Does we can define the fcc as bool cf[8] at struct target_sigcontext?
Thanks
Song Gao
On 11/24/21 11:22 AM, gaosong wrote:
> I see that kernel define the fcc used type uint64_t, and used movgr2cf/movcf2gr
> save and restore the fcc0-fcc7.
> but qemu define fcc0-fcc7 as bool cf[8] at target/loongarch/cpu.h, how qemu can
> save/restore fcc, Do you have any idea?
> Does we can define the fcc as bool cf[8] at struct target_sigcontext?
No, you need to leave the declaration the same.
To create the uint64_t, you do what the kernel does in sc_save_fcc: insert each bit into
the first bit of each byte.
static uint64_t read_all_fcc(CPULoongArchState *env)
{
uint64_t ret = 0;
for (int i = 0; i < 8; ++i) {
ret |= (uint64_t)env->cf[i] << (i * 8);
}
return ret;
}
And similarly from sc_restore_fcc:
static void write_all_fcc(CPULoongArchState *env, uint64_t val)
{
for (int i = 0; i < 8; ++i) {
env->cf[i] = (val >> (i * 8)) & 1;
}
}
Remembering that movcf2gr copies the least significant bit.
r~
Hi Richard,
On 2021/11/20 下午6:33, Richard Henderson wrote:
>> +/* this struct defines a stack used during syscall handling */
>> +typedef struct target_sigaltstack {
>> + abi_long ss_sp;
>> + abi_int ss_flags;
>> + abi_ulong ss_size;
>> +} target_stack_t;
>> +
>> +/*
>> + * sigaltstack controls
>> + */
>> +#define TARGET_SS_ONSTACK 1
>> +#define TARGET_SS_DISABLE 2
>> +
>> +#define TARGET_MINSIGSTKSZ 2048
>> +#define TARGET_SIGSTKSZ 8192
>
> We should move these to generic/signal.h.
Yes.
I also see that TARGET_SIGSTKSZ is not used. I think we should delete it.
Thanks
Song Gao
On 11/25/21 4:03 AM, gaosong wrote: > I also see that TARGET_SIGSTKSZ is not used. I think we should delete it. Agreed. This constant will have been baked into the guest executable. r~
Hi Richard,
On 2021/11/20 下午6:33, Richard Henderson wrote:
> On 11/19/21 7:13 AM, Song Gao wrote:
>>
>> +
>> +struct target_sigcontext {
>> + uint64_t sc_pc;
>> + uint64_t sc_gpr[32];
>> + uint64_t sc_fpr[32];
>> + uint64_t sc_fcc;
>> + uint32_t sc_fcsr;
>> + uint32_t sc_flags;
>> +};
>
> Does not match
> https://github.com/loongson/linux/blob/loongarch-next/arch/loongarch/include/uapi/asm/sigcontext.h
>
>
#define FPU_REG_WIDTH 256
union fpureg {
uint32_t val32[FPU_REG_WIDTH / 32];
uint64_t val64[FPU_REG_WIDTH / 64];
};
struct target_sigcontext {
uint64_t sc_pc;
uint64_t sc_regs[32];
uint32_t sc_flags;
uint32_t sc_fcsr;
uint32_t sc_vcsr;
uint64_t sc_fcc;
uint64_t scr[4];
union fpureg sc_fpregs[32] __attribute__((aligned(32)));
uint32_t sc_reserved;
};
Is this OK?
>> +
>> +struct target_ucontext {
>> + target_ulong tuc_flags;
>> + target_ulong tuc_link;
>> + target_stack_t tuc_stack;
>> + target_ulong pad0;
>> + struct target_sigcontext tuc_mcontext;
>> + target_sigset_t tuc_sigmask;
>> +};
>
> Does not match
> https://github.com/loongson/linux/blob/loongarch-next/arch/loongarch/include/uapi/asm/ucontext.h
>
>
struct target_ucontext {
target_ulong tuc_flags;
target_ulong tuc_link;
target_stack_t tuc_stack;
target_sigset_t tuc_sigmask;
target_ulong pad0;
struct target_sigcontext tuc_mcontext;
};
Is this OK?
Thanks
Song Gao
On 11/24/21 3:46 AM, gaosong wrote:
> Hi Richard,
>
> On 2021/11/20 下午6:33, Richard Henderson wrote:
>> On 11/19/21 7:13 AM, Song Gao wrote:
>>>
>>> +
>>> +struct target_sigcontext {
>>> + uint64_t sc_pc;
>>> + uint64_t sc_gpr[32];
>>> + uint64_t sc_fpr[32];
>>> + uint64_t sc_fcc;
>>> + uint32_t sc_fcsr;
>>> + uint32_t sc_flags;
>>> +};
>>
>> Does not match
>> https://github.com/loongson/linux/blob/loongarch-next/arch/loongarch/include/uapi/asm/sigcontext.h
>>
>>
> #define FPU_REG_WIDTH 256
> union fpureg {
> uint32_t val32[FPU_REG_WIDTH / 32];
> uint64_t val64[FPU_REG_WIDTH / 64];
> };
>
> struct target_sigcontext {
> uint64_t sc_pc;
> uint64_t sc_regs[32];
> uint32_t sc_flags;
>
> uint32_t sc_fcsr;
> uint32_t sc_vcsr;
> uint64_t sc_fcc;
> uint64_t scr[4];
> union fpureg sc_fpregs[32] __attribute__((aligned(32)));
>
> uint32_t sc_reserved;
> };
>
> Is this OK?
No, sc_reserved does not match.
>
>>> +
>>> +struct target_ucontext {
>>> + target_ulong tuc_flags;
>>> + target_ulong tuc_link;
>>> + target_stack_t tuc_stack;
>>> + target_ulong pad0;
>>> + struct target_sigcontext tuc_mcontext;
>>> + target_sigset_t tuc_sigmask;
>>> +};
>>
>> Does not match
>> https://github.com/loongson/linux/blob/loongarch-next/arch/loongarch/include/uapi/asm/ucontext.h
>>
>>
> struct target_ucontext {
> target_ulong tuc_flags;
> target_ulong tuc_link;
> target_stack_t tuc_stack;
> target_sigset_t tuc_sigmask;
> target_ulong pad0;
> struct target_sigcontext tuc_mcontext;
> };
>
> Is this OK?
No, pad0 does not match __unused.
r~
Hi Richard,
On 2021/11/24 下午3:27, Richard Henderson wrote:
> On 11/24/21 3:46 AM, gaosong wrote:
>> Hi Richard,
>>
>> On 2021/11/20 下午6:33, Richard Henderson wrote:
>>> On 11/19/21 7:13 AM, Song Gao wrote:
>>>>
>>>> +
>>>> +struct target_sigcontext {
>>>> + uint64_t sc_pc;
>>>> + uint64_t sc_gpr[32];
>>>> + uint64_t sc_fpr[32];
>>>> + uint64_t sc_fcc;
>>>> + uint32_t sc_fcsr;
>>>> + uint32_t sc_flags;
>>>> +};
>>>
>>> Does not match
>>> https://github.com/loongson/linux/blob/loongarch-next/arch/loongarch/include/uapi/asm/sigcontext.h
>>>
>>>
>> #define FPU_REG_WIDTH 256
>> union fpureg {
>> uint32_t val32[FPU_REG_WIDTH / 32];
>> uint64_t val64[FPU_REG_WIDTH / 64];
>> };
>>
>> struct target_sigcontext {
>> uint64_t sc_pc;
>> uint64_t sc_regs[32];
>> uint32_t sc_flags;
>>
>> uint32_t sc_fcsr;
>> uint32_t sc_vcsr;
>> uint64_t sc_fcc;
>> uint64_t scr[4];
>> union fpureg sc_fpregs[32] __attribute__((aligned(32)));
>>
>> uint32_t sc_reserved;
>> };
>>
>> Is this OK?
>
> No, sc_reserved does not match.
>
uint8 sc_reserved[4096] __attribute__((aligned(16)));
BTW, should we set scr[0-3] as 0 ?
>>
>>>> +
>>>> +struct target_ucontext {
>>>> + target_ulong tuc_flags;
>>>> + target_ulong tuc_link;
>>>> + target_stack_t tuc_stack;
>>>> + target_ulong pad0;
>>>> + struct target_sigcontext tuc_mcontext;
>>>> + target_sigset_t tuc_sigmask;
>>>> +};
>>>
>>> Does not match
>>> https://github.com/loongson/linux/blob/loongarch-next/arch/loongarch/include/uapi/asm/ucontext.h
>>>
>>>
>> struct target_ucontext {
>> target_ulong tuc_flags;
>> target_ulong tuc_link;
>> target_stack_t tuc_stack;
>> target_sigset_t tuc_sigmask;
>> target_ulong pad0;
>> struct target_sigcontext tuc_mcontext;
>> };
>>
>> Is this OK?
>
> No, pad0 does not match __unused.
>
uint8 unused[1024 / 8 - sizeof(target_sigset_t)];
Is this right?
Thanks
Song Gao
>
> r~
On 11/24/21 8:50 AM, gaosong wrote: >> No, sc_reserved does not match. >> > uint8 sc_reserved[4096] __attribute__((aligned(16))); Yes. > BTW, should we set scr[0-3] as 0 ? I think so. The LoongArch Reference Manual, Volume 3: Virtualization and Binary Translation Extensions, v1.00, is empty. But I do not imagine a world in which 0 is not a safe indication of "this field is empty/unused". >> No, pad0 does not match __unused. >> > uint8 unused[1024 / 8 - sizeof(target_sigset_t)]; > Is this right? Yes. r~
Hi Richard,
On 2021/11/20 下午6:33, Richard Henderson wrote:
>
> Drop all of the the inline markers.
>
>> +{
>> + int i;
>> +
>> + __put_user(env->pc, &sc->sc_pc);
>> +
>> + __put_user(0, &sc->sc_gpr[0]);
>> + for (i = 1; i < 32; ++i) {
>> + __put_user(env->gpr[i], &sc->sc_gpr[i]);
>> + }
>> +
>> + for (i = 0; i < 32; ++i) {
>> + __put_user(env->fpr[i], &sc->sc_fpr[i]);
>> + }
>> +}
>
> Missing fcsr and fcc.
>
> I'll note that the kernel is missing sets of vscr and scr[0-3]. IMO
> they should at least be zeroed in advance of supporting the vector
> extension.
I see that vcsr set at [1]:178.
[1]
https://github.com/loongson/linux/blob/loongarch-next/arch/loongarch/kernel/signal.c
and I also see that the kernel is missing sets of scr[0-3], Huacai is that right?
Thanks
Song Gao
Hi, all,
On Mon, Nov 22, 2021 at 7:41 PM gaosong <gaosong@loongson.cn> wrote:
>
> Hi Richard,
>
> On 2021/11/20 下午6:33, Richard Henderson wrote:
>
>
> Drop all of the the inline markers.
>
> +{
> + int i;
> +
> + __put_user(env->pc, &sc->sc_pc);
> +
> + __put_user(0, &sc->sc_gpr[0]);
> + for (i = 1; i < 32; ++i) {
> + __put_user(env->gpr[i], &sc->sc_gpr[i]);
> + }
> +
> + for (i = 0; i < 32; ++i) {
> + __put_user(env->fpr[i], &sc->sc_fpr[i]);
> + }
> +}
>
>
> Missing fcsr and fcc.
>
> I'll note that the kernel is missing sets of vscr and scr[0-3]. IMO they should at least be zeroed in advance of supporting the vector extension.
>
> I see that vcsr set at [1]:178.
> [1]
> https://github.com/loongson/linux/blob/loongarch-next/arch/loongarch/kernel/signal.c
>
> and I also see that the kernel is missing sets of scr[0-3], Huacai is that right?
scr[0-3] is reserved for binary translation, it doesn't need to be set now.
Huacai
>
> Thanks
> Song Gao
--
Huacai Chen
On 11/22/21 12:41 PM, gaosong wrote:
> Hi Richard,
>
> On 2021/11/20 下午6:33, Richard Henderson wrote:
>>
>> Drop all of the the inline markers.
>>
>>> +{
>>> + int i;
>>> +
>>> + __put_user(env->pc, &sc->sc_pc);
>>> +
>>> + __put_user(0, &sc->sc_gpr[0]);
>>> + for (i = 1; i < 32; ++i) {
>>> + __put_user(env->gpr[i], &sc->sc_gpr[i]);
>>> + }
>>> +
>>> + for (i = 0; i < 32; ++i) {
>>> + __put_user(env->fpr[i], &sc->sc_fpr[i]);
>>> + }
>>> +}
>>
>> Missing fcsr and fcc.
>>
>> I'll note that the kernel is missing sets of vscr and scr[0-3]. IMO they should at least
>> be zeroed in advance of supporting the vector extension.
>
> I see that vcsr set at [1]:178.
> [1]
> https://github.com/loongson/linux/blob/loongarch-next/arch/loongarch/kernel/signal.c
That happens after line 171:
if (likely(!err))
break;
It seems most unlikely that there would be an error...
There is a macro for sc_save_vcsr in fpu.S, but it isn't used.
r~
© 2016 - 2026 Red Hat, Inc.