summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/src/9/pc64/l.s53
-rw-r--r--sys/src/9/pc64/trap.c25
2 files changed, 41 insertions, 37 deletions
diff --git a/sys/src/9/pc64/l.s b/sys/src/9/pc64/l.s
index 40233a768..fe3de017b 100644
--- a/sys/src/9/pc64/l.s
+++ b/sys/src/9/pc64/l.s
@@ -686,15 +686,20 @@ f3:
TEXT touser(SB), 1, $-4
CLI
SWAPGS
- MOVQ $UDSEL, AX
+
+ MOVW $UDSEL, AX
MOVW AX, DS
MOVW AX, ES
+
+ MOVW $NULLSEL, AX
MOVW AX, FS
MOVW AX, GS
- MOVQ $(UTZERO+0x28), CX /* ip */
- MOVQ $0x200, R11 /* flags */
+ MOVL $0, RMACH
+ MOVL $0, RUSER
+ MOVQ $(UTZERO+0x28), CX /* ip */
+ MOVL $0x200, R11 /* flags */
MOVQ RARG, SP /* sp */
BYTE $0x48; SYSRET /* SYSRETQ */
@@ -703,45 +708,55 @@ TEXT touser(SB), 1, $-4
*/
TEXT syscallentry(SB), 1, $-4
SWAPGS
- BYTE $0x65; MOVQ 0, RMACH /* m-> (MOVQ GS:0x0, R15) */
- MOVQ 16(RMACH), RUSER /* m->proc */
+ BYTE $0x65; MOVQ 0, AX /* m-> (MOVQ GS:0x0, AX) */
+ MOVQ 16(AX), BX /* m->proc */
MOVQ SP, R13
- MOVQ 16(RUSER), SP /* m->proc->kstack */
+ MOVQ 16(BX), SP /* m->proc->kstack */
ADDQ $KSTACK, SP
+
PUSHQ $UDSEL /* old stack segment */
PUSHQ R13 /* old sp */
PUSHQ R11 /* old flags */
PUSHQ $UESEL /* old code segment */
PUSHQ CX /* old ip */
- SUBQ $(17*8), SP /* unsaved registers */
- PUSHQ RARG /* system call number */
+ SUBQ $(16+16*8), SP /* unsaved registers */
MOVW $UDSEL, (15*8+0)(SP)
MOVW ES, (15*8+2)(SP)
MOVW FS, (15*8+4)(SP)
MOVW GS, (15*8+6)(SP)
+ MOVQ RMACH, (14*8)(SP)
+ MOVQ RUSER, (13*8)(SP)
+
+ MOVQ RARG, (6*8)(SP) /* system call number */
+
+ MOVQ AX, RMACH /* m */
+ MOVQ BX, RUSER /* up */
+
MOVQ SP, RARG
- PUSHQ SP /* Ureg* */
+ PUSHQ SP
CALL syscall(SB)
TEXT forkret(SB), 1, $-4
- MOVQ 8(SP), AX /* Ureg.ax */
- MOVQ (8+6*8)(SP), BP /* Ureg.bp */
- ADDQ $(16*8), SP /* registers + arguments */
+ MOVQ 8(SP), AX
+ ADDQ $(8+13*8), SP /* unsaved registers */
CLI
SWAPGS
- MOVW 0(SP), DS
- MOVW 2(SP), ES
- MOVW 4(SP), FS
- MOVW 6(SP), GS
- MOVQ 24(SP), CX /* ip */
- MOVQ 40(SP), R11 /* flags */
+ MOVW 22(SP), GS
+ MOVW 20(SP), FS
+ MOVW 18(SP), ES
+ MOVW 16(SP), DS
+
+ MOVQ 8(SP), RMACH
+ MOVQ 0(SP), RUSER
- MOVQ 48(SP), SP /* sp */
+ MOVQ 40(SP), CX /* ip */
+ MOVQ 56(SP), R11 /* flags */
+ MOVQ 64(SP), SP /* sp */
BYTE $0x48; SYSRET /* SYSRETQ */
diff --git a/sys/src/9/pc64/trap.c b/sys/src/9/pc64/trap.c
index 2c2001115..6f6f95f96 100644
--- a/sys/src/9/pc64/trap.c
+++ b/sys/src/9/pc64/trap.c
@@ -686,7 +686,7 @@ syscall(Ureg* ureg)
up->dbgreg = ureg;
sp = ureg->sp;
- scallnr = ureg->ax;
+ scallnr = ureg->bp; /* RARG */
up->scallnr = scallnr;
spllo();
@@ -735,13 +735,6 @@ syscall(Ureg* ureg)
up->errlab[i].sp, up->errlab[i].pc);
panic("error stack");
}
-
- /*
- * Put return value in frame. On the x86 the syscall is
- * just another trap and the return value from syscall is
- * ignored. On other machines the return value is put into
- * the results register by caller of syscall.
- */
ureg->ax = ret;
if(0){
@@ -902,12 +895,8 @@ noted(Ureg* ureg, ulong arg0)
pexit("Suicide", 0);
}
- /* don't let user change system flags */
- nureg->flags = (ureg->flags & ~0xCD5) | (nureg->flags & 0xCD5);
- nureg->cs |= 3;
- nureg->ss |= 3;
-
- memmove(ureg, nureg, sizeof(Ureg));
+ /* don't let user change system flags or segment registers */
+ setregisters(ureg, (char*)ureg, (char*)nureg, sizeof(Ureg));
switch(arg0){
case NCONT:
@@ -965,6 +954,7 @@ execregs(uintptr entry, ulong ssize, ulong nargs)
ureg->cs = UESEL;
ureg->ss = ureg->ds = ureg->es = UDSEL;
ureg->fs = ureg->gs = NULLSEL;
+ ureg->r14 = ureg->r15 = 0; /* extern user registers */
return (uintptr)USTKTOP-sizeof(Tos); /* address of kernel/user shared data */
}
@@ -981,7 +971,7 @@ userpc(void)
}
/* This routine must save the values of registers the user is not permitted
- * to write from devproc and then restore the saved values before returning.
+ * to write from devproc and noted() and then restore the saved values before returning.
*/
void
setregisters(Ureg* ureg, char* pureg, char* uva, int n)
@@ -995,7 +985,7 @@ setregisters(Ureg* ureg, char* pureg, char* uva, int n)
if(ureg->fs != UDSEL)
ureg->fs = NULLSEL;
if(ureg->gs != UDSEL)
- ureg->gs = 0;
+ ureg->gs = NULLSEL;
ureg->flags = (ureg->flags & 0x00ff) | (flags & 0xff00);
ureg->pc &= UADDRMASK;
}
@@ -1063,8 +1053,7 @@ dbgpc(Proc *p)
Ureg *ureg;
ureg = p->dbgreg;
- if(ureg == 0)
+ if(ureg == nil)
return 0;
-
return ureg->pc;
}