From patchwork Tue Nov 10 08:30:33 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Vivier X-Patchwork-Id: 321011 Delivered-To: patch@linaro.org Received: by 2002:a05:6e02:5ce:0:0:0:0 with SMTP id l14csp40224ils; Tue, 10 Nov 2020 00:33:53 -0800 (PST) X-Google-Smtp-Source: ABdhPJzTm/KRmCsdmbreLDfaov4eRudN5JZXquKGg08HqhZ5NA/LnMt15+rkRpH2lGFs7PhZoGSM X-Received: by 2002:a25:686:: with SMTP id 128mr25495766ybg.175.1604997233187; Tue, 10 Nov 2020 00:33:53 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1604997233; cv=none; d=google.com; s=arc-20160816; b=yy2xXuiNswRRMVK2fnaAmIE3emPOy1OG++Yt74patD75lD7ECiMUv2QochKNoWXWM8 Wb19aMHuuuslo7GeC6gDyoVRJ6pkMAnDZUZJSr+MLWfomLS+FofddIPRsFel0+NKousx 30otbmMatQR4Io9VXHFGHQ/mqCTQNSCZ1eE3hHoGDamFl5bEzY8NL/4uiAl9tIndA9hm zP/6xKDWQYjeaa4ASFT6NkUkbKmAqDyvetiFF9tQNX2iYaBJddpXtC6W/J7gCpVC0Kyi PniNhrhE8z3cA4L8qO7GVYRIuHB+ZXanOXE2ML0Yx3ZTIO6aAP5zOYFZwVK9WGh/6N/d yDuw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:to:from; bh=MlgCJt+2/G1JXq3ewIBl6TyXJRgVIZJkforyTJZSj1I=; b=p4l8zTUO3BzdWsMTi+/oi/PvlUQJZPmTKe40QmOkjNpNe/j6k0nq1py7U/8dMVLykj Y9ONZ8ock2Ejnt6M0A9U/mPAs0qiCodAtUItB82s2VNbMvp9+sIGIpUmek4pHdXALSTJ KXO3QMjgu6n9sF9zl1rQzljRxXDRX6knlRYgBZ9mV5t+uujadyIuqOC9kmBzfqNfNMDF j+n8XXzCb9Icui4Wj79Uvpy/D6WZC/pDORPeuhD0gsPqt/RwKK2nTqU4zzLeQPKBcQL/ UG4JgimWRBPOpr3azcnrfbJ92x9KTK7JL/l5uszh2ek7uuLYc4anMFY3ZhQoR8Zmp5AY R+Cg== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org" Return-Path: Received: from lists.gnu.org (lists.gnu.org. [209.51.188.17]) by mx.google.com with ESMTPS id e127si13090113yba.175.2020.11.10.00.33.53 for (version=TLS1_2 cipher=ECDHE-ECDSA-CHACHA20-POLY1305 bits=256/256); Tue, 10 Nov 2020 00:33:53 -0800 (PST) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; Authentication-Results: mx.google.com; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org" Received: from localhost ([::1]:46168 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kcP68-0003W8-MY for patch@linaro.org; Tue, 10 Nov 2020 03:33:52 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:37954) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kcP3A-0000mC-FW for qemu-devel@nongnu.org; Tue, 10 Nov 2020 03:30:48 -0500 Received: from mout.kundenserver.de ([212.227.17.10]:37919) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kcP33-00072Q-6s for qemu-devel@nongnu.org; Tue, 10 Nov 2020 03:30:48 -0500 Received: from localhost.localdomain ([82.252.154.198]) by mrelayeu.kundenserver.de (mreue109 [212.227.15.183]) with ESMTPSA (Nemesis) id 1Mbj3Y-1k1g3631F0-00dFdc; Tue, 10 Nov 2020 09:30:38 +0100 From: Laurent Vivier To: qemu-devel@nongnu.org Subject: [PULL 2/3] linux-user/sparc: Correct set/get_context handling of fp and i7 Date: Tue, 10 Nov 2020 09:30:33 +0100 Message-Id: <20201110083034.224832-3-laurent@vivier.eu> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20201110083034.224832-1-laurent@vivier.eu> References: <20201110083034.224832-1-laurent@vivier.eu> MIME-Version: 1.0 X-Provags-ID: V03:K1:JT4T9Y9GyDE9lgicWo6FjtB3XP+nELWswQm92onsqMjWca3RAyt axD+2A7oIi37Q7ElkM7xlmSm8ngkFrp7cRT0WmyjJneGKEde9NyETMt17owTBBvWrx52+2Z fl3D3/qnz3FV3cUy+8iA58I2K6W1bgq5Y2lviqAIoeV59FpAc9Wjz3OrCe261u2fhe5oiGz RjQdom2r3E4LIfN5v7jAg== X-UI-Out-Filterresults: notjunk:1; V03:K0:CMJsjlvygo4=:fElf4UZpvrzDFFaEzvU/ls 2+IlAXp4QiPbIJJg+kjRoKC5DHkmaFRNyj5rNrGLpsZhdOxtr1gvB9grC9Hk3+BtkOvDKUAMs l8unWyYRjBOyDJb8p0jC3ZZ7s6KAiDrTH35ucF2nv5uxnnsW8JVRfp9tDziOQnK+og4d8bSan gWfMbmYjhJv60V2qf/dDulmX/cRd995NId1c/o1O7c9YS3IXvvfBNbljbtt7CghrlLGV5Oo+Z lSad6G7fwytLiUWW2LTvxkKfNdletuLfS+yYV3gJLmDQf/JSykL2ey59zN4sZDARuKSXEM8b0 FDGCK0hYBudeaKWFexSGAIdGPanvJBCtyaKYEBXdoLR4WjWdIjL4aPkZutpgs+VGOcGI7nlM4 f6QxDwD4jUI2x5ScGpusw1b8oOraGPTkDUtDyIH6Hhw7hwDOdB9LA/aD4a80CbSLIx5Hc60TQ gEgu7gLkdw== Received-SPF: none client-ip=212.227.17.10; envelope-from=laurent@vivier.eu; helo=mout.kundenserver.de X-detected-operating-system: by eggs.gnu.org: First seen = 2020/11/10 03:30:38 X-ACL-Warn: Detected OS = Linux 2.2.x-3.x [generic] [fuzzy] X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H2=-0.001, SPF_HELO_NONE=0.001, SPF_NONE=0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Peter Maydell , Richard Henderson , Laurent Vivier Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" From: Peter Maydell Because QEMU's user-mode emulation just directly accesses guest CPU state, for SPARC the guest register window state is not the same in the sparc64_get_context() and sparc64_set_context() functions as it is for the real kernel's versions of those functions. Specifically, for the kernel it has saved the user space state such that the O* registers go into a pt_regs struct as UREG_I*, and the I* registers have been spilled onto the userspace stack. For QEMU, we haven't done that, so the guest's O* registers are still in WREG_O* and the I* registers in WREG_I*. The code was already accessing the O* registers correctly for QEMU, but had copied the kernel code for accessing the I* registers off the userspace stack. Replace this with direct accesses to fp and i7 in the CPU state, and add a comment explaining why we differ from the kernel code here. This fix is sufficient to get bash to a shell prompt. Signed-off-by: Peter Maydell Reviewed-by: Richard Henderson Message-Id: <20201105212314.9628-3-peter.maydell@linaro.org> Signed-off-by: Laurent Vivier --- linux-user/sparc/signal.c | 47 ++++++++++++++++++--------------------- 1 file changed, 22 insertions(+), 25 deletions(-) -- 2.28.0 diff --git a/linux-user/sparc/signal.c b/linux-user/sparc/signal.c index 57ea1593bfc9..c315704b3895 100644 --- a/linux-user/sparc/signal.c +++ b/linux-user/sparc/signal.c @@ -403,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]; @@ -447,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])); @@ -456,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: @@ -501,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; @@ -553,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])); @@ -562,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;