diff options
author | kib <kib@FreeBSD.org> | 2014-12-16 18:28:33 +0000 |
---|---|---|
committer | kib <kib@FreeBSD.org> | 2014-12-16 18:28:33 +0000 |
commit | 42d5fa98d30175edd5c387fa437ec4d956cb2300 (patch) | |
tree | 5bab7bd32ecb7998e9cf2d68dfbc476532a3c1cc /sys/amd64/amd64/exception.S | |
parent | ed7560000fc3fb90198b801920bef29f4195e861 (diff) | |
download | FreeBSD-src-42d5fa98d30175edd5c387fa437ec4d956cb2300.zip FreeBSD-src-42d5fa98d30175edd5c387fa437ec4d956cb2300.tar.gz |
The iret instruction may generate #np and #ss fault, besides #gp.
When returning to usermode, the handler for that exceptions is also
executed with wrong gs base. Handle all three possible faults in the
same way, checking for iret fault, and performing full iret.
Sponsored by: The FreeBSD Foundation
MFC after: 3 days
Diffstat (limited to 'sys/amd64/amd64/exception.S')
-rw-r--r-- | sys/amd64/amd64/exception.S | 9 |
1 files changed, 7 insertions, 2 deletions
diff --git a/sys/amd64/amd64/exception.S b/sys/amd64/amd64/exception.S index 2a908a9..71f1674 100644 --- a/sys/amd64/amd64/exception.S +++ b/sys/amd64/amd64/exception.S @@ -153,9 +153,13 @@ IDTVEC(xmm) IDTVEC(tss) TRAP_ERR(T_TSSFLT) IDTVEC(missing) - TRAP_ERR(T_SEGNPFLT) + subq $TF_ERR,%rsp + movl $T_SEGNPFLT,TF_TRAPNO(%rsp) + jmp prot_addrf IDTVEC(stk) - TRAP_ERR(T_STKFLT) + subq $TF_ERR,%rsp + movl $T_STKFLT,TF_TRAPNO(%rsp) + jmp prot_addrf IDTVEC(align) TRAP_ERR(T_ALIGNFLT) @@ -318,6 +322,7 @@ IDTVEC(page) IDTVEC(prot) subq $TF_ERR,%rsp movl $T_PROTFLT,TF_TRAPNO(%rsp) +prot_addrf: movq $0,TF_ADDR(%rsp) movq %rdi,TF_RDI(%rsp) /* free up a GP register */ leaq doreti_iret(%rip),%rdi |