Some linux-user/sparc fixes
-----BEGIN PGP SIGNATURE----- iQJGBAABCAAwFiEEzS913cjjpNwuT1Fz8ww4vT8vvjwFAl+qT5kSHGxhdXJlbnRA dml2aWVyLmV1AAoJEPMMOL0/L748PWIP/iBQgmTEd++g54aIvB/qWRMKPPXpqT3i YIX6yAPEKKaYFdQfHIZd1XLUd85Q33uu7Qeh55wIwjiFcFfnYRou6oDxiF9w3Ds1 Ltl1DQZbi63Kif13aTbFlBQC1ggHmCLFXY7E7upNCvOv9mSq87rOoOviC60hWgXg 9E2u2qhqy1wk9fJOj3t2+VjGAdNQHnBlyQRVGgJhqejC33hrZOPyMEwRlkXFBogY h3LPjOLgbAl5R8sDE4p4ugmWnhqoLF9qUQiXCNT93ol8Boj3BNyym88ptBlOdBdE UW4UTuT0VMItPNZG2aGOPqDiHLPM4AqBRtJfeMHg2Gxk7fm+oA5GhASQwtrbvGBf ND4+aJF+roqfrFe/oKQIU3PgLd8I7blpChu+Qo0K9bWIrt7/JGgx1AR5iX8n+2GV Av6r45xsJmRRlfIsZbhmNWLmSxs/80rowbABqUrdU3bgvs8S0Fjy2dZyAc6eiGjd KuXOKoNeZk8Q0XqLPWTfXeqom+uUqvP8bDHcUnxJj98+Xqi/WdzKAl70QDU5X+MO xOYR0mJ096aRtCwTf+36fO3ayrypzFsoiumXEowXuDI7ww8FCmbm3uoeRm/3at8X FmW94J3V9iHyNkqofzhWjxNkAUt6OpefIiHcNJAg0/ROlKv17BgjYRIjFIc6KFge JYd4mnk3CbjU =9iAg -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/vivier2/tags/linux-user-for-5.2-pull-request' into staging Some linux-user/sparc fixes # gpg: Signature made Tue 10 Nov 2020 08:30:17 GMT # gpg: using RSA key CD2F75DDC8E3A4DC2E4F5173F30C38BD3F2FBE3C # gpg: issuer "laurent@vivier.eu" # gpg: Good signature from "Laurent Vivier <lvivier@redhat.com>" [full] # gpg: aka "Laurent Vivier <laurent@vivier.eu>" [full] # gpg: aka "Laurent Vivier (Red Hat) <lvivier@redhat.com>" [full] # Primary key fingerprint: CD2F 75DD C8E3 A4DC 2E4F 5173 F30C 38BD 3F2F BE3C * remotes/vivier2/tags/linux-user-for-5.2-pull-request: linux-user/sparc: Don't zero high half of PC, NPC, PSR in sigreturn linux-user/sparc: Correct set/get_context handling of fp and i7 linux-user/sparc: Fix errors in target_ucontext structures Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
6c8e801f07
|
@ -247,7 +247,7 @@ long do_sigreturn(CPUSPARCState *env)
|
|||
{
|
||||
abi_ulong sf_addr;
|
||||
struct target_signal_frame *sf;
|
||||
uint32_t up_psr, pc, npc;
|
||||
abi_ulong up_psr, pc, npc;
|
||||
target_sigset_t set;
|
||||
sigset_t host_set;
|
||||
int i;
|
||||
|
@ -349,10 +349,15 @@ typedef abi_ulong target_mc_greg_t;
|
|||
typedef target_mc_greg_t target_mc_gregset_t[SPARC_MC_NGREG];
|
||||
|
||||
struct target_mc_fq {
|
||||
abi_ulong *mcfq_addr;
|
||||
abi_ulong mcfq_addr;
|
||||
uint32_t mcfq_insn;
|
||||
};
|
||||
|
||||
/*
|
||||
* Note the manual 16-alignment; the kernel gets this because it
|
||||
* includes a "long double qregs[16]" in the mcpu_fregs union,
|
||||
* which we can't do.
|
||||
*/
|
||||
struct target_mc_fpu {
|
||||
union {
|
||||
uint32_t sregs[32];
|
||||
|
@ -362,11 +367,11 @@ struct target_mc_fpu {
|
|||
abi_ulong mcfpu_fsr;
|
||||
abi_ulong mcfpu_fprs;
|
||||
abi_ulong mcfpu_gsr;
|
||||
struct target_mc_fq *mcfpu_fq;
|
||||
abi_ulong mcfpu_fq;
|
||||
unsigned char mcfpu_qcnt;
|
||||
unsigned char mcfpu_qentsz;
|
||||
unsigned char mcfpu_enab;
|
||||
};
|
||||
} __attribute__((aligned(16)));
|
||||
typedef struct target_mc_fpu target_mc_fpu_t;
|
||||
|
||||
typedef struct {
|
||||
|
@ -377,7 +382,7 @@ typedef struct {
|
|||
} target_mcontext_t;
|
||||
|
||||
struct target_ucontext {
|
||||
struct target_ucontext *tuc_link;
|
||||
abi_ulong tuc_link;
|
||||
abi_ulong tuc_flags;
|
||||
target_sigset_t tuc_sigmask;
|
||||
target_mcontext_t tuc_mcontext;
|
||||
|
@ -398,7 +403,6 @@ void sparc64_set_context(CPUSPARCState *env)
|
|||
struct target_ucontext *ucp;
|
||||
target_mc_gregset_t *grp;
|
||||
abi_ulong pc, npc, tstate;
|
||||
abi_ulong fp, i7, w_addr;
|
||||
unsigned int i;
|
||||
|
||||
ucp_addr = env->regwptr[WREG_O0];
|
||||
|
@ -442,6 +446,15 @@ void sparc64_set_context(CPUSPARCState *env)
|
|||
__get_user(env->gregs[5], (&(*grp)[SPARC_MC_G5]));
|
||||
__get_user(env->gregs[6], (&(*grp)[SPARC_MC_G6]));
|
||||
__get_user(env->gregs[7], (&(*grp)[SPARC_MC_G7]));
|
||||
|
||||
/*
|
||||
* Note that unlike the kernel, we didn't need to mess with the
|
||||
* guest register window state to save it into a pt_regs to run
|
||||
* the kernel. So for us the guest's O regs are still in WREG_O*
|
||||
* (unlike the kernel which has put them in UREG_I* in a pt_regs)
|
||||
* and the fp and i7 are still in WREG_I6 and WREG_I7 and don't
|
||||
* need to be written back to userspace memory.
|
||||
*/
|
||||
__get_user(env->regwptr[WREG_O0], (&(*grp)[SPARC_MC_O0]));
|
||||
__get_user(env->regwptr[WREG_O1], (&(*grp)[SPARC_MC_O1]));
|
||||
__get_user(env->regwptr[WREG_O2], (&(*grp)[SPARC_MC_O2]));
|
||||
|
@ -451,18 +464,9 @@ void sparc64_set_context(CPUSPARCState *env)
|
|||
__get_user(env->regwptr[WREG_O6], (&(*grp)[SPARC_MC_O6]));
|
||||
__get_user(env->regwptr[WREG_O7], (&(*grp)[SPARC_MC_O7]));
|
||||
|
||||
__get_user(fp, &(ucp->tuc_mcontext.mc_fp));
|
||||
__get_user(i7, &(ucp->tuc_mcontext.mc_i7));
|
||||
__get_user(env->regwptr[WREG_FP], &(ucp->tuc_mcontext.mc_fp));
|
||||
__get_user(env->regwptr[WREG_I7], &(ucp->tuc_mcontext.mc_i7));
|
||||
|
||||
w_addr = TARGET_STACK_BIAS + env->regwptr[WREG_O6];
|
||||
if (put_user(fp, w_addr + offsetof(struct target_reg_window, ins[6]),
|
||||
abi_ulong) != 0) {
|
||||
goto do_sigsegv;
|
||||
}
|
||||
if (put_user(i7, w_addr + offsetof(struct target_reg_window, ins[7]),
|
||||
abi_ulong) != 0) {
|
||||
goto do_sigsegv;
|
||||
}
|
||||
/* FIXME this does not match how the kernel handles the FPU in
|
||||
* its sparc64_set_context implementation. In particular the FPU
|
||||
* is only restored if fenab is non-zero in:
|
||||
|
@ -496,7 +500,6 @@ void sparc64_get_context(CPUSPARCState *env)
|
|||
struct target_ucontext *ucp;
|
||||
target_mc_gregset_t *grp;
|
||||
target_mcontext_t *mcp;
|
||||
abi_ulong fp, i7, w_addr;
|
||||
int err;
|
||||
unsigned int i;
|
||||
target_sigset_t target_set;
|
||||
|
@ -548,6 +551,15 @@ void sparc64_get_context(CPUSPARCState *env)
|
|||
__put_user(env->gregs[5], &((*grp)[SPARC_MC_G5]));
|
||||
__put_user(env->gregs[6], &((*grp)[SPARC_MC_G6]));
|
||||
__put_user(env->gregs[7], &((*grp)[SPARC_MC_G7]));
|
||||
|
||||
/*
|
||||
* Note that unlike the kernel, we didn't need to mess with the
|
||||
* guest register window state to save it into a pt_regs to run
|
||||
* the kernel. So for us the guest's O regs are still in WREG_O*
|
||||
* (unlike the kernel which has put them in UREG_I* in a pt_regs)
|
||||
* and the fp and i7 are still in WREG_I6 and WREG_I7 and don't
|
||||
* need to be fished out of userspace memory.
|
||||
*/
|
||||
__put_user(env->regwptr[WREG_O0], &((*grp)[SPARC_MC_O0]));
|
||||
__put_user(env->regwptr[WREG_O1], &((*grp)[SPARC_MC_O1]));
|
||||
__put_user(env->regwptr[WREG_O2], &((*grp)[SPARC_MC_O2]));
|
||||
|
@ -557,18 +569,8 @@ void sparc64_get_context(CPUSPARCState *env)
|
|||
__put_user(env->regwptr[WREG_O6], &((*grp)[SPARC_MC_O6]));
|
||||
__put_user(env->regwptr[WREG_O7], &((*grp)[SPARC_MC_O7]));
|
||||
|
||||
w_addr = TARGET_STACK_BIAS + env->regwptr[WREG_O6];
|
||||
fp = i7 = 0;
|
||||
if (get_user(fp, w_addr + offsetof(struct target_reg_window, ins[6]),
|
||||
abi_ulong) != 0) {
|
||||
goto do_sigsegv;
|
||||
}
|
||||
if (get_user(i7, w_addr + offsetof(struct target_reg_window, ins[7]),
|
||||
abi_ulong) != 0) {
|
||||
goto do_sigsegv;
|
||||
}
|
||||
__put_user(fp, &(mcp->mc_fp));
|
||||
__put_user(i7, &(mcp->mc_i7));
|
||||
__put_user(env->regwptr[WREG_FP], &(mcp->mc_fp));
|
||||
__put_user(env->regwptr[WREG_I7], &(mcp->mc_i7));
|
||||
|
||||
{
|
||||
uint32_t *dst = ucp->tuc_mcontext.mc_fpregs.mcfpu_fregs.sregs;
|
||||
|
|
Loading…
Reference in a new issue