Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 24 Sep 2013 00:37:30 +0300
From:      Konstantin Belousov <kostikbel@gmail.com>
To:        Tijl Coosemans <tijl@coosemans.org>
Cc:        freebsd-current@FreeBSD.org, Russ Cox <rsc@swtch.com>
Subject:   Re: restarting SYSCALL system call on amd64 loses arguments
Message-ID:  <20130923213730.GX41229@kib.kiev.ua>
In-Reply-To: <20130923222613.548860a3@kalimero.tijl.coosemans.org>
References:  <20130923222613.548860a3@kalimero.tijl.coosemans.org>

next in thread | previous in thread | raw e-mail | index | archive | help

--0QZ35bX9xAXmZuwY
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
Content-Transfer-Encoding: quoted-printable

On Mon, Sep 23, 2013 at 10:26:13PM +0200, Tijl Coosemans wrote:
> Has anyone taken a look at this PR yet?
>=20
> http://www.freebsd.org/cgi/query-pr.cgi?pr=3D182161

This looks like a valid bug, but probably not a valid testcase.

Let me elaborate.  When a signal is delivered, return from the signal
handler is performed by the sigreturn(2), which reloads the whole
register file when crossing kernel->user boundary due to sys_sigreturn(9)
setting PCB_FULL_IRET flag.  As result, the whole trap frame at the
time of the syscall entry is restored, and ERESTART return is not
exercised.

I was not able to reproduce the issue with the supplied test program
on HEAD.  I suspect that the program actually exposed the bug in the
signal delivery in the threaded processes, which I introduced for 9.1
and fixed in r251047 & r251365.

On the other hand, I agree that at least arguments should be restored
for ERESTART case, but in fact it is easier and probably less error-prone
to restore whole register file again.  Please try the patch below for
your Go code.

diff --git a/sys/amd64/amd64/vm_machdep.c b/sys/amd64/amd64/vm_machdep.c
index b7c2b67..1e3d8f5 100644
--- a/sys/amd64/amd64/vm_machdep.c
+++ b/sys/amd64/amd64/vm_machdep.c
@@ -400,9 +400,13 @@ cpu_set_syscall_retval(struct thread *td, int error)
 		 * for the next iteration.
 		 * %r10 restore is only required for freebsd/amd64 processes,
 		 * but shall be innocent for any ia32 ABI.
+		 *
+		 * Require full context restore to get the arguments
+		 * in the registers reloaded at return to usermode.
 		 */
 		td->td_frame->tf_rip -=3D td->td_frame->tf_err;
 		td->td_frame->tf_r10 =3D td->td_frame->tf_rcx;
+		set_pcb_flags(td->td_pcb, PCB_FULL_IRET);
 		break;
=20
 	case EJUSTRETURN:

--0QZ35bX9xAXmZuwY
Content-Type: application/pgp-signature

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.21 (FreeBSD)

iQIcBAEBAgAGBQJSQLSZAAoJEJDCuSvBvK1B+XAP/A/myszBMjClt+E41gilgIjo
O9hCqr/7tUZR4ZtIa7QcIdOF9NPJgLYtDJo8dfBSr4ITPBVzNP5v7P6gRej40z/p
aCnwPy3rzatJIOfZQtIo/4NAU3N4DFNizqLWt+6eJuSfym1ATKLZfuI5DBmKeKbP
6CV6F2noy7t5hPnCSWUYce9u82FanKJpS/La/ccxttSES5V0MKSPF3hpugGpUoU2
/i/5zVC5MgJ2sLeoYzOtkkI/dwYN5LhUDilg55uSAv4hY++lpdc9mUm2RLYJOV/S
/ZwnXW9rym2rRzWXg6/S0cZXXGL2YsUGuRcfLVdLiFdHaxsUzuKGCDSSnAt6MGy8
GFEnal/23I/ULsDSjHfsqDpM95ucOmNj3I7BL6aF8P82Oib4g1rfo7JCTMYouQm5
BV2JDGcQi/lqKrGY1xhjk535SthLpw87tQv/PqiXdRLApc4w0y3ILwvttR5Qe+6k
v6zG4t2p24zl8UCGN3yFwfMJOLXRy4bturLGVURd7uPib/M2T2Q5TOei049sXT3d
X+QQz/jbTFOE7IASG7JKWU5BI29D4awF8ijFGuU/50RObW/xCfa5YYKleCE37LXL
4YRemRX0ONihAneP3n0XexsZpEMqZ/4E+vfqlvbvghNIq8tFwVaGl2RxyQMk7VU5
DYI7pWV/bF0paiEIWHnN
=q7Lk
-----END PGP SIGNATURE-----

--0QZ35bX9xAXmZuwY--



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20130923213730.GX41229>