From patchwork Wed Nov 24 15:20:05 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 72899 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [199.232.76.165]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 4DABFB6F10 for ; Thu, 25 Nov 2010 02:23:18 +1100 (EST) Received: from localhost ([127.0.0.1]:51698 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1PLHBj-0008A2-6y for incoming@patchwork.ozlabs.org; Wed, 24 Nov 2010 10:23:15 -0500 Received: from [140.186.70.92] (port=34740 helo=eggs.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1PLH8p-0006w9-I3 for qemu-devel@nongnu.org; Wed, 24 Nov 2010 10:20:19 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1PLH8l-00047o-OG for qemu-devel@nongnu.org; Wed, 24 Nov 2010 10:20:15 -0500 Received: from mnementh.archaic.org.uk ([81.2.115.146]:16641) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1PLH8l-00045l-FZ for qemu-devel@nongnu.org; Wed, 24 Nov 2010 10:20:11 -0500 Received: from pm215 by mnementh.archaic.org.uk with local (Exim 4.69) (envelope-from ) id 1PLH8i-0004s1-EI for qemu-devel@nongnu.org; Wed, 24 Nov 2010 15:20:08 +0000 From: Peter Maydell To: qemu-devel@nongnu.org Date: Wed, 24 Nov 2010 15:20:05 +0000 Message-Id: <1290612008-18693-4-git-send-email-peter.maydell@linaro.org> X-Mailer: git-send-email 1.7.1 In-Reply-To: <1290612008-18693-1-git-send-email-peter.maydell@linaro.org> References: <1290612008-18693-1-git-send-email-peter.maydell@linaro.org> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6 (newer, 2) Subject: [Qemu-devel] [PATCH 3/6] ARM: linux-user: Expose VFP registers to signal handlers X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org For ARM linux-user mode signal handlers, fill in the ucontext with VFP register contents in the same way that the kernel does. We only do this for v2 format sigframe (2.6.12 and above); this is actually bug-for-bug compatible with the older kernels, which don't save and restore VFP registers either. Signed-off-by: Peter Maydell Reviewed-by: Nathan Froyd --- linux-user/signal.c | 47 ++++++++++++++++++++++++++++++++++++++++++++++- 1 files changed, 46 insertions(+), 1 deletions(-) diff --git a/linux-user/signal.c b/linux-user/signal.c index da0ba50..71cc2cd 100644 --- a/linux-user/signal.c +++ b/linux-user/signal.c @@ -1112,6 +1112,26 @@ struct target_ucontext_v2 { abi_ulong tuc_regspace[128] __attribute__((__aligned__(8))); }; +struct target_user_vfp { + uint64_t fpregs[32]; + abi_ulong fpscr; +}; + +struct target_user_vfp_exc { + abi_ulong fpexc; + abi_ulong fpinst; + abi_ulong fpinst2; +}; + +struct target_vfp_sigframe { + abi_ulong magic; + abi_ulong size; + struct target_user_vfp ufp; + struct target_user_vfp_exc ufp_exc; +} __attribute__((__aligned__(8))); + +#define TARGET_VFP_MAGIC 0x56465001 + struct sigframe_v1 { struct target_sigcontext sc; @@ -1255,11 +1275,29 @@ setup_return(CPUState *env, struct target_sigaction *ka, return 0; } +static abi_ulong *setup_sigframe_v2_vfp(abi_ulong *regspace, CPUState *env) +{ + int i; + struct target_vfp_sigframe *vfpframe; + vfpframe = (struct target_vfp_sigframe *)regspace; + __put_user(TARGET_VFP_MAGIC, &vfpframe->magic); + __put_user(sizeof(*vfpframe), &vfpframe->size); + for (i = 0; i < 32; i++) { + __put_user(env->vfp.regs[i], &vfpframe->ufp.fpregs[i]); + } + __put_user(vfp_get_fpscr(env), &vfpframe->ufp.fpscr); + __put_user(env->vfp.xregs[ARM_VFP_FPEXC], &vfpframe->ufp_exc.fpexc); + __put_user(env->vfp.xregs[ARM_VFP_FPINST], &vfpframe->ufp_exc.fpinst); + __put_user(env->vfp.xregs[ARM_VFP_FPINST2], &vfpframe->ufp_exc.fpinst2); + return (abi_ulong*)(vfpframe+1); +} + static void setup_sigframe_v2(struct target_ucontext_v2 *uc, target_sigset_t *set, CPUState *env) { struct target_sigaltstack stack; int i; + abi_ulong *regspace; /* Clear all the bits of the ucontext we don't use. */ memset(uc, 0, offsetof(struct target_ucontext_v2, tuc_mcontext)); @@ -1271,7 +1309,14 @@ static void setup_sigframe_v2(struct target_ucontext_v2 *uc, memcpy(&uc->tuc_stack, &stack, sizeof(stack)); setup_sigcontext(&uc->tuc_mcontext, env, set->sig[0]); - /* FIXME: Save coprocessor signal frame. */ + /* Save coprocessor signal frame. */ + regspace = uc->tuc_regspace; + if (arm_feature(env, ARM_FEATURE_VFP)) { + regspace = setup_sigframe_v2_vfp(regspace, env); + } + /* Write terminating magic word */ + __put_user(0, regspace); + for(i = 0; i < TARGET_NSIG_WORDS; i++) { __put_user(set->sig[i], &uc->tuc_sigmask.sig[i]); }