Skip to content

Commit

Permalink
Merge remote-tracking branch 'remotes/vivier2/tags/linux-user-for-5.2…
Browse files Browse the repository at this point in the history
…-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>
  • Loading branch information
pm215 committed Nov 10, 2020
2 parents f7e1914 + c3ab5df commit 6c8e801
Showing 1 changed file with 32 additions and 30 deletions.
62 changes: 32 additions & 30 deletions linux-user/sparc/signal.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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];
Expand All @@ -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 {
Expand All @@ -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;
Expand All @@ -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];
Expand Down Expand Up @@ -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]));
Expand All @@ -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:
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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]));
Expand All @@ -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;
Expand Down

0 comments on commit 6c8e801

Please sign in to comment.