From patchwork Wed Apr 28 03:32:02 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 1470957 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.a=rsa-sha256 header.s=google header.b=Y+yz7IZ1; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4FVPNF4nzSz9sWD for ; Wed, 28 Apr 2021 13:33:01 +1000 (AEST) Received: from localhost ([::1]:43944 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lbawd-000819-M9 for incoming@patchwork.ozlabs.org; Tue, 27 Apr 2021 23:32:59 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:52526) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lbavy-0007zo-2Z for qemu-devel@nongnu.org; Tue, 27 Apr 2021 23:32:18 -0400 Received: from mail-pg1-x532.google.com ([2607:f8b0:4864:20::532]:42604) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1lbavv-0008Uy-Sq for qemu-devel@nongnu.org; Tue, 27 Apr 2021 23:32:17 -0400 Received: by mail-pg1-x532.google.com with SMTP id m12so3038213pgr.9 for ; Tue, 27 Apr 2021 20:32:15 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=Uu7E7D4g2MoU0eqIdSF7egrQbawxP33jY9TUWvyJdgc=; b=Y+yz7IZ1G0iZLUKL7PEMpyZNrEo3XH15xWe7Y6G8+n6+QyDDkAd/ji46fhGmKr12q/ ePPxuiIomPpJlwlWynWR4f7feJ8qohiPIY8xtFawjlXW5CU2iR8ZqqMzBKOLDCIjf+aY O/VyzLsYAPTNjOHaAk4jyyRhEi6QRq5cIOL84gH9W0R2TVfMPuNxD4P4nu7NNAZCUA3T gfIbWzRg+NWXA9H+m7hDIa2RXjsZKZ+2AGqZP+hgBKQgai4xxiCd7CdZ3pbP+9pvROZo GgrUqb3o0MqtQUowEwpooUq7r+YrauT1ePRiSL/fFbAyCGhiAgXT03GxNrY+8FPSZK6x ULxQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=Uu7E7D4g2MoU0eqIdSF7egrQbawxP33jY9TUWvyJdgc=; b=Iwl2t+uTO8eHCKd3V13LPaphS9zyypCakWpn0LV+ivxkf7zCHrLB38Mxkhvq0EB62W j7to5BWkfZiEAvtq3DxWtjQ7buHx1nLHX8tQ/vQCShmQ+vDGzULu0aAstyYqixQjvxBK LmCOXdIa/utvNkJEsy3FZaQi/bdljbGZ0rQLcEmM4cBUCmAOISLH9gXUb5nUTvKSdZQE HekQM4zCdVRjM5GOWVlHHXM9fSTNafRg7m465uNt4/KUskSfQ4iUeuBejANW/9y5/W+2 O5+HfoYN4DsRvul1sWLXH4Zaavp6zRumY00NQpEvm53KQKVxxyvzhzjcH8LhDLWrd5sB jk1A== X-Gm-Message-State: AOAM531/n+4TzfITGeE4N9m9FFBui0dncn2A4VqOIW/tl4o+0zJBmhrq WRBl9ulqcOB8f8S9cgh5z+DQgKvQuSbrIg== X-Google-Smtp-Source: ABdhPJzadtlDlHAjGf1yB3CSlxcC+4rHeZtXkhY1pUSPTnEx7cg7rBgvkFyCQDDrGWy7IzaM9+DVEQ== X-Received: by 2002:aa7:9a8d:0:b029:27c:a7c8:b7b0 with SMTP id w13-20020aa79a8d0000b029027ca7c8b7b0mr1941305pfi.17.1619580734634; Tue, 27 Apr 2021 20:32:14 -0700 (PDT) Received: from localhost.localdomain ([71.212.144.24]) by smtp.gmail.com with ESMTPSA id 18sm3572335pji.30.2021.04.27.20.32.11 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 27 Apr 2021 20:32:14 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Subject: [PATCH 1/3] linux-user/s390x: Fix sigframe types Date: Tue, 27 Apr 2021 20:32:02 -0700 Message-Id: <20210428033204.133471-2-richard.henderson@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210428033204.133471-1-richard.henderson@linaro.org> References: <20210428033204.133471-1-richard.henderson@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::532; envelope-from=richard.henderson@linaro.org; helo=mail-pg1-x532.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-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: thuth@redhat.com, qemu-s390x@nongnu.org, cohuck@redhat.com, laurent@vivier.eu, david@redhat.com Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" Noticed via gitlab clang-user job: TEST signals on s390x ../linux-user/s390x/signal.c:258:9: runtime error: \ 1.84467e+19 is outside the range of representable values of \ type 'unsigned long' Which points to the fact that we were performing a double-to-uint64_t conversion while storing the fp registers, instead of just copying the data across. Turns out there are several errors: target_ulong is the size of the target register, whereas abi_ulong is the target 'unsigned long' type. Not a big deal here, since we only support 64-bit s390x, but not correct either. In target_sigcontext and target ucontext, we used a host pointer instead of a target pointer, aka abi_ulong. Signed-off-by: Richard Henderson Reviewed-by: David Hildenbrand --- linux-user/s390x/signal.c | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/linux-user/s390x/signal.c b/linux-user/s390x/signal.c index b68b44ae7e..e5bc4f0358 100644 --- a/linux-user/s390x/signal.c +++ b/linux-user/s390x/signal.c @@ -37,13 +37,14 @@ typedef struct { target_psw_t psw; - target_ulong gprs[__NUM_GPRS]; - unsigned int acrs[__NUM_ACRS]; + abi_ulong gprs[__NUM_GPRS]; + abi_uint acrs[__NUM_ACRS]; } target_s390_regs_common; typedef struct { - unsigned int fpc; - double fprs[__NUM_FPRS]; + uint32_t fpc; + uint32_t pad; + uint64_t fprs[__NUM_FPRS]; } target_s390_fp_regs; typedef struct { @@ -51,22 +52,22 @@ typedef struct { target_s390_fp_regs fpregs; } target_sigregs; -struct target_sigcontext { - target_ulong oldmask[_SIGCONTEXT_NSIG_WORDS]; - target_sigregs *sregs; -}; +typedef struct { + abi_ulong oldmask[_SIGCONTEXT_NSIG_WORDS]; + abi_ulong sregs; +} target_sigcontext; typedef struct { uint8_t callee_used_stack[__SIGNAL_FRAMESIZE]; - struct target_sigcontext sc; + target_sigcontext sc; target_sigregs sregs; int signo; uint8_t retcode[S390_SYSCALL_SIZE]; } sigframe; struct target_ucontext { - target_ulong tuc_flags; - struct target_ucontext *tuc_link; + abi_ulong tuc_flags; + abi_ulong tuc_link; target_stack_t tuc_stack; target_sigregs tuc_mcontext; target_sigset_t tuc_sigmask; /* mask last for extensibility */ From patchwork Wed Apr 28 03:32:03 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 1470960 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.a=rsa-sha256 header.s=google header.b=FCDXF6Ot; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4FVPQ42kJ2z9sWC for ; Wed, 28 Apr 2021 13:34:36 +1000 (AEST) Received: from localhost ([::1]:50278 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lbayA-0002DK-Dx for incoming@patchwork.ozlabs.org; Tue, 27 Apr 2021 23:34:34 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:52558) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lbaw1-00082Q-Sc for qemu-devel@nongnu.org; Tue, 27 Apr 2021 23:32:22 -0400 Received: from mail-pf1-x42c.google.com ([2607:f8b0:4864:20::42c]:44852) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1lbavz-00006f-Hr for qemu-devel@nongnu.org; Tue, 27 Apr 2021 23:32:21 -0400 Received: by mail-pf1-x42c.google.com with SMTP id m11so1617432pfc.11 for ; Tue, 27 Apr 2021 20:32:19 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=iq2xxJ2kcU7wwoLubib7cAkUK4oynZtXYi/2qrC2n1c=; b=FCDXF6Ot2ieA+iNhYuQPRKRrvTER+4+UBOuIg72COEOb6A/2jIjTQ6D9RwsZJ6uko8 ImOhzM6fDe+b2BT9J3n/T2CSkqITSURppHPMITIYyKwVJAZrWQP0N7pUoua2gV2zBY3t /9E7gkHuxSQswkHB/IFAJy0qVkAputTdHXtnQCHHeifhsPUYe5QFc3Gma5gbDcfFBmk4 Y/K3hwQTfynqacC+z+UG3nJpkk0/Y/hAfXv7savewi0b0sg9bUq+595K3XRYUbxpdLzn SxA2LC+v4D8DUDgqGkF4fMU+6u7M6/rSk1feRo0eRkQZ8dKtbHzL1bd7A0Iqvx5F3Yu/ VVDA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=iq2xxJ2kcU7wwoLubib7cAkUK4oynZtXYi/2qrC2n1c=; b=LV7sSnd4sbwU+k5oBiA97ytuI8q6wqfRYvbwsdUYX+shun4ZPfaeI+CYrdm+0cb5j6 4xwk0QwESEiR3YL88gTTgwBa/zpQcPA09wE7j5d6zl4pmahMqhX36FDtQhf8VsAEmpWW 7pMjlSk5odKCo4PxAMkzgk6pmOoti4z+tNNBvH5vKI5csCoDuGoxSL//08/8s1FVRZe+ HSDiBp1e4SOSc/U+inRxR/TCTKPbnSs0kec8xabjg80TGg+iBnk1EOwnlpnLnbXlQZaf /dvCcZROnbFZiHAzNk7FFgZEPT/8c0KUhldhVXd0G9oSlSDeY1ddfL+oYQWl9TPsWZcT Oamw== X-Gm-Message-State: AOAM533x9fJObUl9rrMJyeEwmnSKQHv5WlDR2s9qVN07+axlHoBpUTuK AXVVc9ynVJkhKEkGp9Jus0ky696GEN96vQ== X-Google-Smtp-Source: ABdhPJw6Vw8Tba5BXfaLDYOLWSi20weo0hL3MQsJHrWSfkLgTKrhrhf13jIONZ9biymmkNfDnhUpNQ== X-Received: by 2002:aa7:82ce:0:b029:242:deb4:9442 with SMTP id f14-20020aa782ce0000b0290242deb49442mr26444715pfn.73.1619580738051; Tue, 27 Apr 2021 20:32:18 -0700 (PDT) Received: from localhost.localdomain ([71.212.144.24]) by smtp.gmail.com with ESMTPSA id 18sm3572335pji.30.2021.04.27.20.32.14 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 27 Apr 2021 20:32:17 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Subject: [PATCH 2/3] linux-user/s390x: Clean up signal.c Date: Tue, 27 Apr 2021 20:32:03 -0700 Message-Id: <20210428033204.133471-3-richard.henderson@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210428033204.133471-1-richard.henderson@linaro.org> References: <20210428033204.133471-1-richard.henderson@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::42c; envelope-from=richard.henderson@linaro.org; helo=mail-pf1-x42c.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-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: thuth@redhat.com, qemu-s390x@nongnu.org, cohuck@redhat.com, laurent@vivier.eu, david@redhat.com Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" The "save" routines from the kernel, which are currently commented out, are unnecessary in qemu. We can copy from env where the kernel needs special instructions. Drop the return value from restore_sigregs, as it cannot fail. Use __get_user return as input to trace, so that we properly bswap the value for the host. Reorder the function bodies to correspond to the kernel source. Fix the use of host addresses where guest addresses are needed. Drop the use of PSW_ADDR_AMODE, since we only support 64-bit. Set psw.mask properly for the signal handler. Use tswap_sigset in setup_rt_frame. Signed-off-by: Richard Henderson --- linux-user/s390x/signal.c | 184 ++++++++++++++++++-------------------- 1 file changed, 89 insertions(+), 95 deletions(-) diff --git a/linux-user/s390x/signal.c b/linux-user/s390x/signal.c index e5bc4f0358..fb7065f243 100644 --- a/linux-user/s390x/signal.c +++ b/linux-user/s390x/signal.c @@ -32,7 +32,6 @@ #define _SIGCONTEXT_NSIG_BPW 64 /* FIXME: 31-bit mode -> 32 */ #define _SIGCONTEXT_NSIG_WORDS (_SIGCONTEXT_NSIG / _SIGCONTEXT_NSIG_BPW) #define _SIGMASK_COPY_SIZE (sizeof(unsigned long)*_SIGCONTEXT_NSIG_WORDS) -#define PSW_ADDR_AMODE 0x0000000000000000UL /* 0x80000000UL for 31-bit */ #define S390_SYSCALL_OPCODE ((uint16_t)0x0a00) typedef struct { @@ -106,23 +105,25 @@ get_sigframe(struct target_sigaction *ka, CPUS390XState *env, size_t frame_size) static void save_sigregs(CPUS390XState *env, target_sigregs *sregs) { int i; - //save_access_regs(current->thread.acrs); FIXME - /* Copy a 'clean' PSW mask to the user to avoid leaking - information about whether PER is currently on. */ + /* + * Copy a 'clean' PSW mask to the user to avoid leaking + * information about whether PER is currently on. + */ __put_user(env->psw.mask, &sregs->regs.psw.mask); __put_user(env->psw.addr, &sregs->regs.psw.addr); + for (i = 0; i < 16; i++) { __put_user(env->regs[i], &sregs->regs.gprs[i]); } for (i = 0; i < 16; i++) { __put_user(env->aregs[i], &sregs->regs.acrs[i]); } + /* * We have to store the fp registers to current->thread.fp_regs * to merge them with the emulated registers. */ - //save_fp_regs(¤t->thread.fp_regs); FIXME for (i = 0; i < 16; i++) { __put_user(*get_freg(env, i), &sregs->fpregs.fprs[i]); } @@ -137,120 +138,124 @@ void setup_frame(int sig, struct target_sigaction *ka, frame_addr = get_sigframe(ka, env, sizeof(*frame)); trace_user_setup_frame(env, frame_addr); if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) { - goto give_sigsegv; - } - - __put_user(set->sig[0], &frame->sc.oldmask[0]); - - save_sigregs(env, &frame->sregs); - - __put_user((abi_ulong)(unsigned long)&frame->sregs, - (abi_ulong *)&frame->sc.sregs); - - /* Set up to return from userspace. If provided, use a stub - already in userspace. */ - if (ka->sa_flags & TARGET_SA_RESTORER) { - env->regs[14] = (unsigned long) - ka->sa_restorer | PSW_ADDR_AMODE; - } else { - env->regs[14] = (frame_addr + offsetof(sigframe, retcode)) - | PSW_ADDR_AMODE; - __put_user(S390_SYSCALL_OPCODE | TARGET_NR_sigreturn, - (uint16_t *)(frame->retcode)); + force_sigsegv(sig); + return; } /* Set up backchain. */ __put_user(env->regs[15], (abi_ulong *) frame); + /* Create struct sigcontext on the signal stack. */ + for (int i = 0; i < ARRAY_SIZE(frame->sc.oldmask); ++i) { + __put_user(set->sig[i], &frame->sc.oldmask[i]); + } + + save_sigregs(env, &frame->sregs); + __put_user(frame_addr + offsetof(sigframe, sregs), &frame->sc.sregs); + + /* Place signal number on stack to allow backtrace from handler. */ + __put_user(sig, &frame->signo); + + /* + * Set up to return from userspace. + * If provided, use a stub already in userspace. + */ + if (ka->sa_flags & TARGET_SA_RESTORER) { + env->regs[14] = ka->sa_restorer; + } else { + env->regs[14] = frame_addr + offsetof(sigframe, retcode); + __put_user(S390_SYSCALL_OPCODE | TARGET_NR_sigreturn, + (uint16_t *)(frame->retcode)); + } + /* Set up registers for signal handler */ env->regs[15] = frame_addr; - env->psw.addr = (target_ulong) ka->_sa_handler | PSW_ADDR_AMODE; + + /* Force default amode and default user address space control. */ + env->psw.mask = PSW_MASK_64 | PSW_MASK_32 | PSW_ASC_PRIMARY + | (env->psw.mask & ~PSW_MASK_ASC); + env->psw.addr = ka->_sa_handler; env->regs[2] = sig; //map_signal(sig); env->regs[3] = frame_addr += offsetof(typeof(*frame), sc); - /* We forgot to include these in the sigcontext. - To avoid breaking binary compatibility, they are passed as args. */ - env->regs[4] = 0; // FIXME: no clue... current->thread.trap_no; - env->regs[5] = 0; // FIXME: no clue... current->thread.prot_addr; + /* + * We forgot to include these in the sigcontext. + * To avoid breaking binary compatibility, they are passed as args. + */ + env->regs[4] = 0; /* FIXME: regs->int_code & 127 */ + env->regs[5] = 0; /* FIXME: regs->int_parm_long */ + env->regs[6] = 0; /* FIXME: current->thread.last_break */ - /* Place signal number on stack to allow backtrace from handler. */ - __put_user(env->regs[2], &frame->signo); unlock_user_struct(frame, frame_addr, 1); - return; - -give_sigsegv: - force_sigsegv(sig); } void setup_rt_frame(int sig, struct target_sigaction *ka, target_siginfo_t *info, target_sigset_t *set, CPUS390XState *env) { - int i; rt_sigframe *frame; abi_ulong frame_addr; 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->info, info); - - /* Create the ucontext. */ - __put_user(0, &frame->uc.tuc_flags); - __put_user((abi_ulong)0, (abi_ulong *)&frame->uc.tuc_link); - target_save_altstack(&frame->uc.tuc_stack, env); - save_sigregs(env, &frame->uc.tuc_mcontext); - for (i = 0; i < TARGET_NSIG_WORDS; i++) { - __put_user((abi_ulong)set->sig[i], - (abi_ulong *)&frame->uc.tuc_sigmask.sig[i]); - } - - /* Set up to return from userspace. If provided, use a stub - already in userspace. */ - if (ka->sa_flags & TARGET_SA_RESTORER) { - env->regs[14] = ka->sa_restorer | PSW_ADDR_AMODE; - } else { - env->regs[14] = (frame_addr + offsetof(typeof(*frame), retcode)) - | PSW_ADDR_AMODE; - __put_user(S390_SYSCALL_OPCODE | TARGET_NR_rt_sigreturn, - (uint16_t *)(frame->retcode)); + force_sigsegv(sig); + return; } /* Set up backchain. */ __put_user(env->regs[15], (abi_ulong *) frame); + /* + * Set up to return from userspace. + * If provided, use a stub already in userspace. + */ + if (ka->sa_flags & TARGET_SA_RESTORER) { + env->regs[14] = ka->sa_restorer; + } else { + env->regs[14] = frame_addr + offsetof(typeof(*frame), retcode); + __put_user(S390_SYSCALL_OPCODE | TARGET_NR_rt_sigreturn, + (uint16_t *)(frame->retcode)); + } + + /* Create siginfo on the signal stack. */ + tswap_siginfo(&frame->info, info); + + /* Create the ucontext. */ + __put_user(0, &frame->uc.tuc_flags); + __put_user(0, &frame->uc.tuc_link); + target_save_altstack(&frame->uc.tuc_stack, env); + save_sigregs(env, &frame->uc.tuc_mcontext); + tswap_sigset(&frame->uc.tuc_sigmask, set); + /* Set up registers for signal handler */ env->regs[15] = frame_addr; - env->psw.addr = (target_ulong) ka->_sa_handler | PSW_ADDR_AMODE; - env->regs[2] = sig; //map_signal(sig); + /* Force default amode and default user address space control. */ + env->psw.mask = PSW_MASK_64 | PSW_MASK_32 | PSW_ASC_PRIMARY + | (env->psw.mask & ~PSW_MASK_ASC); + env->psw.addr = ka->_sa_handler; + + env->regs[2] = sig; env->regs[3] = frame_addr + offsetof(typeof(*frame), info); env->regs[4] = frame_addr + offsetof(typeof(*frame), uc); - return; - -give_sigsegv: - force_sigsegv(sig); + env->regs[5] = 0; /* FIXME: current->thread.last_break */ } -static int -restore_sigregs(CPUS390XState *env, target_sigregs *sc) +static void restore_sigregs(CPUS390XState *env, target_sigregs *sc) { - int err = 0; + target_ulong prev_addr; int i; for (i = 0; i < 16; i++) { __get_user(env->regs[i], &sc->regs.gprs[i]); } + prev_addr = env->psw.addr; __get_user(env->psw.mask, &sc->regs.psw.mask); - trace_user_s390x_restore_sigregs(env, (unsigned long long)sc->regs.psw.addr, - (unsigned long long)env->psw.addr); __get_user(env->psw.addr, &sc->regs.psw.addr); - /* FIXME: 31-bit -> | PSW_ADDR_AMODE */ + trace_user_s390x_restore_sigregs(env, env->psw.addr, prev_addr); for (i = 0; i < 16; i++) { __get_user(env->aregs[i], &sc->regs.acrs[i]); @@ -258,8 +263,6 @@ restore_sigregs(CPUS390XState *env, target_sigregs *sc) for (i = 0; i < 16; i++) { __get_user(*get_freg(env, i), &sc->fpregs.fprs[i]); } - - return err; } long do_sigreturn(CPUS390XState *env) @@ -271,23 +274,21 @@ long do_sigreturn(CPUS390XState *env) trace_user_do_sigreturn(env, frame_addr); if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1)) { - goto badframe; + force_sig(TARGET_SIGSEGV); + return -TARGET_QEMU_ESIGRETURN; } - __get_user(target_set.sig[0], &frame->sc.oldmask[0]); + QEMU_BUILD_BUG_ON(sizeof(target_set) != sizeof(frame->sc.oldmask)); + for (int i = 0; i < ARRAY_SIZE(frame->sc.oldmask); ++i) { + __get_user(target_set.sig[i], &frame->sc.oldmask[i]); + } target_to_host_sigset_internal(&set, &target_set); set_sigmask(&set); /* ~_BLOCKABLE? */ - if (restore_sigregs(env, &frame->sregs)) { - goto badframe; - } + restore_sigregs(env, &frame->sregs); unlock_user_struct(frame, frame_addr, 0); return -TARGET_QEMU_ESIGRETURN; - -badframe: - force_sig(TARGET_SIGSEGV); - return -TARGET_QEMU_ESIGRETURN; } long do_rt_sigreturn(CPUS390XState *env) @@ -298,23 +299,16 @@ long do_rt_sigreturn(CPUS390XState *env) trace_user_do_rt_sigreturn(env, frame_addr); if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1)) { - goto badframe; + force_sig(TARGET_SIGSEGV); + return -TARGET_QEMU_ESIGRETURN; } - target_to_host_sigset(&set, &frame->uc.tuc_sigmask); + target_to_host_sigset(&set, &frame->uc.tuc_sigmask); set_sigmask(&set); /* ~_BLOCKABLE? */ - if (restore_sigregs(env, &frame->uc.tuc_mcontext)) { - goto badframe; - } - target_restore_altstack(&frame->uc.tuc_stack, env); + restore_sigregs(env, &frame->uc.tuc_mcontext); 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; } From patchwork Wed Apr 28 03:32:04 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 1470959 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.a=rsa-sha256 header.s=google header.b=fcFoqTBj; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4FVPNK13bJz9sWC for ; Wed, 28 Apr 2021 13:33:05 +1000 (AEST) Received: from localhost ([::1]:44216 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lbawh-0008Az-2G for incoming@patchwork.ozlabs.org; Tue, 27 Apr 2021 23:33:03 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:52590) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lbaw4-000858-P0 for qemu-devel@nongnu.org; Tue, 27 Apr 2021 23:32:26 -0400 Received: from mail-pj1-x1029.google.com ([2607:f8b0:4864:20::1029]:44973) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1lbaw1-00008y-QF for qemu-devel@nongnu.org; Tue, 27 Apr 2021 23:32:24 -0400 Received: by mail-pj1-x1029.google.com with SMTP id m6-20020a17090a8586b02901507e1acf0fso8361027pjn.3 for ; Tue, 27 Apr 2021 20:32:21 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=UK1YbqqlmWYWZ3nCDAZqXJgWrK622W4kr3AfSUK6QPg=; b=fcFoqTBjCqcj/0QvoQKQBtF/pBlujHhlzsVqEmlvQNSRyO2OnpnrgUkBrgLEyz5uhv ZitYcppbUHDNACe3rU7NIy7fBz9zSK6bEGSwl9VMcke8N5KbQ69H/cMyGA5hXp197k0y G7oSLQEBvxVVSqI3zNQO4fhoCjO+E2Xk6dk5tNo4aekxhK7uEgzzWQoT6srTGEb6VdYF 4BbOlK17g6yvE0xlQAqQDrLqf7v7ejSLsKrBFcNvYSc2XFowaC9uZq/e965KKp2Vs487 gr+P6uMwYv1/9YfMSEJLc1d/6o1JYnhDNwUETYjegcxSIlnUkA2W57TWYOjHpnotSrUx Viug== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=UK1YbqqlmWYWZ3nCDAZqXJgWrK622W4kr3AfSUK6QPg=; b=tAX4GmDd8Ri5p6Q+XPI5HustC3BWeETyhVboG84XtBfW/Or0ia9WCRNNs6j4UNlqfL sDqMyrF+K6lJAdtt4BPDJFKSBEbrKzjYItDfkMx9SdtcfJUztmStHsd6oWoBHhCg3rpQ UmwsYQ4EVEN+fpzFPa19bWJfw3z7hlqK0WnYX81LJ0lQxHoDeT9fXzjzrnfvKvP+SkVN qJ846nLsu/itGFbmTN0HRVWI1xnVdR9E9SQlC6S0ZPK8uqT+kXJYrFf0bXL/1UZc54df mbF9cQHkj/wbStvvTMCxwT006M9X/scjewwnOf42UTzv0AIY07XFmQabe8dnXcuks4F4 A02Q== X-Gm-Message-State: AOAM530LXd/JzO5yJurhezPQawdsSQcCKKRYOJLeNfTbqmfm7m2rc0sF +LrJUPg/ayhLYjgYvXeMn64kzNime4wFdg== X-Google-Smtp-Source: ABdhPJzvAkX9JMGz2G8tClGHd5HivNN99Dk4FjTY1FEj9LfO7wHnIHx48toxy0kTO9eYNCx3Hc0H6w== X-Received: by 2002:a17:902:7b8e:b029:ec:982d:7a7e with SMTP id w14-20020a1709027b8eb02900ec982d7a7emr27912209pll.55.1619580740428; Tue, 27 Apr 2021 20:32:20 -0700 (PDT) Received: from localhost.localdomain ([71.212.144.24]) by smtp.gmail.com with ESMTPSA id 18sm3572335pji.30.2021.04.27.20.32.18 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 27 Apr 2021 20:32:20 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Subject: [PATCH 3/3] linux-user/s390x: Handle vector regs in signal stack Date: Tue, 27 Apr 2021 20:32:04 -0700 Message-Id: <20210428033204.133471-4-richard.henderson@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210428033204.133471-1-richard.henderson@linaro.org> References: <20210428033204.133471-1-richard.henderson@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::1029; envelope-from=richard.henderson@linaro.org; helo=mail-pj1-x1029.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=unavailable 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: thuth@redhat.com, qemu-s390x@nongnu.org, cohuck@redhat.com, laurent@vivier.eu, david@redhat.com Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" Signed-off-by: Richard Henderson --- linux-user/s390x/signal.c | 62 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 60 insertions(+), 2 deletions(-) diff --git a/linux-user/s390x/signal.c b/linux-user/s390x/signal.c index fb7065f243..57752a2a96 100644 --- a/linux-user/s390x/signal.c +++ b/linux-user/s390x/signal.c @@ -51,6 +51,12 @@ typedef struct { target_s390_fp_regs fpregs; } target_sigregs; +typedef struct { + uint64_t vxrs_low[16]; + uint64_t vxrs_high[16][2]; + uint8_t reserved[128]; +} target_sigregs_ext; + typedef struct { abi_ulong oldmask[_SIGCONTEXT_NSIG_WORDS]; abi_ulong sregs; @@ -61,15 +67,20 @@ typedef struct { target_sigcontext sc; target_sigregs sregs; int signo; + target_sigregs_ext sregs_ext; uint8_t retcode[S390_SYSCALL_SIZE]; } sigframe; +#define TARGET_UC_VXRS 2 + struct target_ucontext { abi_ulong tuc_flags; abi_ulong tuc_link; target_stack_t tuc_stack; target_sigregs tuc_mcontext; - target_sigset_t tuc_sigmask; /* mask last for extensibility */ + target_sigset_t tuc_sigmask; + uint8_t reserved[128 - sizeof(target_sigset_t)]; + target_sigregs_ext tuc_mcontext_ext; }; typedef struct { @@ -129,6 +140,24 @@ static void save_sigregs(CPUS390XState *env, target_sigregs *sregs) } } +static void save_sigregs_ext(CPUS390XState *env, target_sigregs_ext *ext) +{ + int i; + + /* + * if (MACHINE_HAS_VX) ... + * That said, we always allocate the stack storage and the + * space is always available in env. + */ + for (i = 0; i < 16; ++i) { + __put_user(env->vregs[i][1], &ext->vxrs_low[i]); + } + for (i = 0; i < 16; ++i) { + __put_user(env->vregs[i + 16][0], &ext->vxrs_high[i][0]); + __put_user(env->vregs[i + 16][1], &ext->vxrs_high[i][1]); + } +} + void setup_frame(int sig, struct target_sigaction *ka, target_sigset_t *set, CPUS390XState *env) { @@ -156,6 +185,9 @@ void setup_frame(int sig, struct target_sigaction *ka, /* Place signal number on stack to allow backtrace from handler. */ __put_user(sig, &frame->signo); + /* Create sigregs_ext on the signal stack. */ + save_sigregs_ext(env, &frame->sregs_ext); + /* * Set up to return from userspace. * If provided, use a stub already in userspace. @@ -196,6 +228,7 @@ void setup_rt_frame(int sig, struct target_sigaction *ka, { rt_sigframe *frame; abi_ulong frame_addr; + abi_ulong uc_flags; frame_addr = get_sigframe(ka, env, sizeof *frame); trace_user_setup_rt_frame(env, frame_addr); @@ -223,10 +256,15 @@ void setup_rt_frame(int sig, struct target_sigaction *ka, tswap_siginfo(&frame->info, info); /* Create the ucontext. */ - __put_user(0, &frame->uc.tuc_flags); + uc_flags = 0; + if (s390_has_feat(S390_FEAT_VECTOR)) { + uc_flags |= TARGET_UC_VXRS; + } + __put_user(uc_flags, &frame->uc.tuc_flags); __put_user(0, &frame->uc.tuc_link); target_save_altstack(&frame->uc.tuc_stack, env); save_sigregs(env, &frame->uc.tuc_mcontext); + save_sigregs_ext(env, &frame->uc.tuc_mcontext_ext); tswap_sigset(&frame->uc.tuc_sigmask, set); /* Set up registers for signal handler */ @@ -265,6 +303,24 @@ static void restore_sigregs(CPUS390XState *env, target_sigregs *sc) } } +static void restore_sigregs_ext(CPUS390XState *env, target_sigregs_ext *ext) +{ + int i; + + /* + * if (MACHINE_HAS_VX) ... + * That said, we always allocate the stack storage and the + * space is always available in env. + */ + for (i = 0; i < 16; ++i) { + __get_user(env->vregs[i][1], &ext->vxrs_low[i]); + } + for (i = 0; i < 16; ++i) { + __get_user(env->vregs[i + 16][0], &ext->vxrs_high[i][0]); + __get_user(env->vregs[i + 16][1], &ext->vxrs_high[i][1]); + } +} + long do_sigreturn(CPUS390XState *env) { sigframe *frame; @@ -286,6 +342,7 @@ long do_sigreturn(CPUS390XState *env) set_sigmask(&set); /* ~_BLOCKABLE? */ restore_sigregs(env, &frame->sregs); + restore_sigregs_ext(env, &frame->sregs_ext); unlock_user_struct(frame, frame_addr, 0); return -TARGET_QEMU_ESIGRETURN; @@ -308,6 +365,7 @@ long do_rt_sigreturn(CPUS390XState *env) target_restore_altstack(&frame->uc.tuc_stack, env); restore_sigregs(env, &frame->uc.tuc_mcontext); + restore_sigregs_ext(env, &frame->uc.tuc_mcontext_ext); unlock_user_struct(frame, frame_addr, 0); return -TARGET_QEMU_ESIGRETURN;