Date: Thu, 23 Jun 2005 08:34:09 GMT From: Peter Wemm <peter@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 78852 for review Message-ID: <200506230834.j5N8Y90n016894@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=78852 Change 78852 by peter@peter_overcee on 2005/06/23 08:33:41 Attempt to recover from the wrong gsbase state after a fault from doreti()::iretq. Even though we're coming from kernel mode we have to swapgs and friends before enabling interrupts. XXX may need to move load_gs and load_fs from C to asm in order to do the magic there too. Affected files ... .. //depot/projects/hammer/sys/amd64/amd64/exception.S#38 edit Differences ... ==== //depot/projects/hammer/sys/amd64/amd64/exception.S#38 (text+ko) ==== @@ -126,8 +126,6 @@ TRAP_ERR(T_SEGNPFLT) IDTVEC(stk) TRAP_ERR(T_STKFLT) -IDTVEC(prot) - TRAP_ERR(T_PROTFLT) IDTVEC(align) TRAP_ERR(T_ALIGNFLT) @@ -203,7 +201,8 @@ testb $SEL_RPL_MASK,TF_CS(%rsp) /* Did we come from kernel? */ jz 1f /* already running with kernel GS.base */ swapgs -1: movq %rdi,TF_RDI(%rsp) /* free up a GP register */ +1: + movq %rdi,TF_RDI(%rsp) /* free up a GP register */ movq %cr2,%rdi /* preserve %cr2 before .. */ movq %rdi,TF_ADDR(%rsp) /* enabling interrupts. */ testl $PSL_I,TF_RFLAGS(%rsp) @@ -211,6 +210,30 @@ sti jmp alltraps_pushregs_no_rdi + /* + * We have to special-case this one. If we get a trap in doreti() at + * the iretq stage, we'll reenter with the wrong gs state. We'll have + * to do a special the swapgs in this case even coming from the kernel. + * XXX linux has a trap handler for their equivalent of load_gs(). + */ +IDTVEC(prot) + subq $TF_ERR,%rsp + movq $T_PROTFLT,TF_TRAPNO(%rsp) + movq $0,TF_ADDR(%rsp) + movq %rdi,TF_RDI(%rsp) /* free up a GP register */ + leaq doreti_iret(%rip),%rdi + cmpq %rdi,TF_RIP(%rsp) + je 2f /* kernel but with user gsbase!! */ + testb $SEL_RPL_MASK,TF_CS(%rsp) /* Did we come from kernel? */ + jz 1f /* already running with kernel GS.base */ +2: + swapgs +1: + testl $PSL_I,TF_RFLAGS(%rsp) + jz alltraps_pushregs_no_rdi + sti + jmp alltraps_pushregs_no_rdi + /* * Fast syscall entry point. We enter here with just our new %cs/%ss set, * and the new privilige level. We are still running on the old user stack
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200506230834.j5N8Y90n016894>