i386 copyout/in_fast: handle page fault from KVA access
by delegating the work to the slow path. Some kernel memory, like pipe buffers, is pageable. We must not enable interrupts, and consequently, preemption, while in critical section in the fast copyout path, because we use pcpu buffers. If page fault occurs while copying from the pcpu copyout_buf to kernel memory, abort fast path and delegate work to the slow implementation. In collaboration with: pho, tijl Sponsored by: The FreeBSD Foundation MFC after: 1 week
This commit is contained in:
parent
fd25c62278
commit
49587b8fb4
@ -47,32 +47,30 @@ ENTRY(copyout_fast)
|
||||
pushl %ebx
|
||||
|
||||
movl 20(%ebp),%ebx /* KCR3 */
|
||||
movl PCPU(CURPCB),%edx
|
||||
movl PCB_CR3(%edx),%edx /* UCR3 */
|
||||
/* bcopy(%esi = kaddr, %edi = PCPU(copyout_buf), %ecx = len) */
|
||||
movl 16(%ebp),%ecx
|
||||
movl 8(%ebp),%esi
|
||||
movl %esp,%eax
|
||||
movl $copyout_fault,%edx
|
||||
|
||||
cli
|
||||
movl PCPU(COPYOUT_BUF),%edi
|
||||
rep; movsb
|
||||
pf_y1: rep; movsb
|
||||
|
||||
movl 16(%ebp),%ecx /* len */
|
||||
movl PCPU(COPYOUT_BUF),%esi /* kaddr */
|
||||
movl 12(%ebp),%edi /* uaddr */
|
||||
|
||||
movl %esp,%eax
|
||||
movl PCPU(TRAMPSTK),%esp
|
||||
|
||||
movl PCPU(CURPCB),%edx
|
||||
movl PCB_CR3(%edx),%edx /* UCR3 */
|
||||
movl %edx,%cr3
|
||||
movl $copyout_fault,%edx
|
||||
|
||||
/* bcopy(%esi = PCPU(copyout_buf), %edi = udaddr, %ecx = len) */
|
||||
pf_x1: rep; movsb
|
||||
|
||||
movl %ebx,%cr3
|
||||
movl %eax,%esp
|
||||
sti
|
||||
|
||||
xorl %eax,%eax
|
||||
popl %ebx
|
||||
popl %edi
|
||||
@ -93,10 +91,10 @@ ENTRY(copyin_fast)
|
||||
movl PCB_CR3(%eax),%edx /* UCR3 */
|
||||
movl 16(%ebp),%ecx /* len */
|
||||
movl 8(%ebp),%esi /* udaddr */
|
||||
movl %esp,%eax
|
||||
|
||||
cli
|
||||
movl PCPU(COPYOUT_BUF),%edi /* kaddr */
|
||||
|
||||
movl %esp,%eax
|
||||
movl PCPU(TRAMPSTK),%esp
|
||||
movl %edx,%cr3
|
||||
movl $copyout_fault,%edx
|
||||
@ -110,10 +108,9 @@ pf_x2: rep; movsb
|
||||
movl 16(%ebp),%ecx
|
||||
movl 12(%ebp),%edi
|
||||
movl PCPU(COPYOUT_BUF),%esi
|
||||
rep; movsb
|
||||
pf_y2: rep; movsb
|
||||
|
||||
sti
|
||||
|
||||
xorl %eax,%eax
|
||||
popl %ebx
|
||||
popl %edi
|
||||
|
@ -130,15 +130,15 @@ IDTVEC(prot)
|
||||
jmp irettraps
|
||||
IDTVEC(page)
|
||||
testl $PSL_VM, TF_EFLAGS-TF_ERR(%esp)
|
||||
jnz 4f
|
||||
jnz 5f
|
||||
testb $SEL_RPL_MASK, TF_CS-TF_ERR(%esp)
|
||||
jnz 4f
|
||||
jnz 5f
|
||||
cmpl $PMAP_TRM_MIN_ADDRESS, TF_EIP-TF_ERR(%esp)
|
||||
jb 4f
|
||||
jb 5f
|
||||
pushl %eax
|
||||
movl TF_EIP-TF_ERR+4(%esp), %eax
|
||||
addl $1f, %eax
|
||||
call 5f
|
||||
call 6f
|
||||
1: cmpl $pf_x1, %eax
|
||||
je 2f
|
||||
cmpl $pf_x2, %eax
|
||||
@ -154,16 +154,21 @@ IDTVEC(page)
|
||||
cmpl $pf_x7, %eax
|
||||
je 2f
|
||||
cmpl $pf_x8, %eax
|
||||
jne 3f
|
||||
2: popl %eax
|
||||
movl %ebx, %cr3
|
||||
je 2f
|
||||
cmpl $pf_y1, %eax
|
||||
je 3f
|
||||
cmpl $pf_y2, %eax
|
||||
je 3f
|
||||
jmp 4f
|
||||
2: movl %ebx, %cr3
|
||||
3: popl %eax
|
||||
movl %edx, TF_EIP-TF_ERR(%esp)
|
||||
addl $4, %esp
|
||||
iret
|
||||
3: popl %eax
|
||||
4: pushl $T_PAGEFLT
|
||||
4: popl %eax
|
||||
5: pushl $T_PAGEFLT
|
||||
jmp alltraps
|
||||
5: subl (%esp), %eax
|
||||
6: subl (%esp), %eax
|
||||
retl
|
||||
IDTVEC(rsvd_pti)
|
||||
IDTVEC(rsvd)
|
||||
|
Loading…
Reference in New Issue
Block a user