summaryrefslogtreecommitdiffstats
path: root/sys/amd64
diff options
context:
space:
mode:
authorpeter <peter@FreeBSD.org>2003-06-02 21:56:08 +0000
committerpeter <peter@FreeBSD.org>2003-06-02 21:56:08 +0000
commit54294f1739a4b46f029cab4511f55cd9eba1b196 (patch)
tree8afdc45e166e9dbfabb5cc78ea699d5505295862 /sys/amd64
parent458ad34341ff5b8d4e26424d48fdb0e21d5c67eb (diff)
downloadFreeBSD-src-54294f1739a4b46f029cab4511f55cd9eba1b196.zip
FreeBSD-src-54294f1739a4b46f029cab4511f55cd9eba1b196.tar.gz
Fix restarted syscalls. When we rewind %rip, we also need to restore
all the argument registers etc since we have almost certainly have trashed them by now. Take particular car of %r10 since it held the original value of %rcx (which we saved in tf_rcx on entry and doreti doesn't know this).
Diffstat (limited to 'sys/amd64')
-rw-r--r--sys/amd64/amd64/trap.c8
1 files changed, 6 insertions, 2 deletions
diff --git a/sys/amd64/amd64/trap.c b/sys/amd64/amd64/trap.c
index 72ba590..c4e7f16 100644
--- a/sys/amd64/amd64/trap.c
+++ b/sys/amd64/amd64/trap.c
@@ -751,10 +751,14 @@ syscall(frame)
case ERESTART:
/*
- * Reconstruct pc, assuming lcall $X,y is 7 bytes,
- * int 0x80 is 2 bytes. We saved this in tf_err.
+ * Reconstruct pc, we know that 'syscall' is 2 bytes.
+ * We have to do a full context restore so that %r10
+ * (which was holding the value of %rcx) is restored for
+ * the next iteration.
*/
frame.tf_rip -= frame.tf_err;
+ frame.tf_r10 = frame.tf_rcx;
+ td->td_pcb->pcb_flags |= PCB_FULLCTX;
break;
case EJUSTRETURN:
OpenPOWER on IntegriCloud