Changeset View
Changeset View
Standalone View
Standalone View
head/sys/amd64/amd64/support.S
Show First 20 Lines • Show All 570 Lines • ▼ Show 20 Lines | |||||
.macro SMAP_ENABLE smap | .macro SMAP_ENABLE smap | ||||
.if \smap | .if \smap | ||||
clac | clac | ||||
.endif | .endif | ||||
.endm | .endm | ||||
.macro COPYINOUT_BEGIN | |||||
.endm | |||||
.macro COPYINOUT_END | |||||
movq %rax,PCB_ONFAULT(%r11) | |||||
POP_FRAME_POINTER | |||||
.endm | |||||
.macro COPYINOUT_SMAP_END | |||||
SMAP_ENABLE smap=1 | |||||
COPYINOUT_END | |||||
.endm | |||||
/* | /* | ||||
* copyout(from_kernel, to_user, len) | * copyout(from_kernel, to_user, len) | ||||
* %rdi, %rsi, %rdx | * %rdi, %rsi, %rdx | ||||
*/ | */ | ||||
.macro COPYOUT smap erms | .macro COPYOUT smap erms | ||||
PUSH_FRAME_POINTER | PUSH_FRAME_POINTER | ||||
movq PCPU(CURPCB),%r9 | movq PCPU(CURPCB),%r11 | ||||
movq $copy_fault,PCB_ONFAULT(%r9) | movq $copy_fault,PCB_ONFAULT(%r11) | ||||
/* | /* | ||||
* Check explicitly for non-user addresses. If 486 write protection | * Check explicitly for non-user addresses. If 486 write protection | ||||
* is being used, this check is essential because we are in kernel | * is being used, this check is essential because we are in kernel | ||||
* mode so the h/w does not provide any protection against writing | * mode so the h/w does not provide any protection against writing | ||||
* kernel addresses. | * kernel addresses. | ||||
*/ | */ | ||||
Show All 9 Lines | |||||
* looks like there is an off by one error, and of course it caused an off | * looks like there is an off by one error, and of course it caused an off | ||||
* by one error in several places. | * by one error in several places. | ||||
*/ | */ | ||||
movq $VM_MAXUSER_ADDRESS,%rcx | movq $VM_MAXUSER_ADDRESS,%rcx | ||||
cmpq %rcx,%rax | cmpq %rcx,%rax | ||||
ja copy_fault | ja copy_fault | ||||
/* | /* | ||||
* Set up arguments for rep movs*. | * Set return value to zero. Remaining failure mode goes through | ||||
* copy_fault. | |||||
*/ | */ | ||||
xorl %eax,%eax | |||||
/* | |||||
* Set up arguments for MEMMOVE. | |||||
*/ | |||||
movq %rdi,%r8 | movq %rdi,%r8 | ||||
movq %rsi,%rdi | movq %rsi,%rdi | ||||
movq %r8,%rsi | movq %r8,%rsi | ||||
movq %rdx,%rcx | movq %rdx,%rcx | ||||
/* | |||||
* Set return value to zero. Remaining failure mode goes through | |||||
* copy_fault. | |||||
*/ | |||||
xorl %eax,%eax | |||||
SMAP_DISABLE \smap | SMAP_DISABLE \smap | ||||
.if \erms == 0 | .if \smap == 1 | ||||
cmpq $15,%rcx | MEMMOVE erms=\erms overlap=0 begin=COPYINOUT_BEGIN end=COPYINOUT_SMAP_END | ||||
jbe 1f | .else | ||||
shrq $3,%rcx | MEMMOVE erms=\erms overlap=0 begin=COPYINOUT_BEGIN end=COPYINOUT_END | ||||
rep | |||||
movsq | |||||
movb %dl,%cl | |||||
andb $7,%cl | |||||
jne 1f | |||||
SMAP_ENABLE \smap | |||||
movq %rax,PCB_ONFAULT(%r9) | |||||
POP_FRAME_POINTER | |||||
ret | |||||
ALIGN_TEXT | |||||
1: | |||||
.endif | .endif | ||||
rep | /* NOTREACHED */ | ||||
movsb | |||||
SMAP_ENABLE \smap | |||||
movq %rax,PCB_ONFAULT(%r9) | |||||
POP_FRAME_POINTER | |||||
ret | |||||
.endm | .endm | ||||
ENTRY(copyout_nosmap_std) | ENTRY(copyout_nosmap_std) | ||||
COPYOUT smap=0 erms=0 | COPYOUT smap=0 erms=0 | ||||
END(copyout_nosmap_std) | END(copyout_nosmap_std) | ||||
ENTRY(copyout_smap_std) | ENTRY(copyout_smap_std) | ||||
COPYOUT smap=1 erms=0 | COPYOUT smap=1 erms=0 | ||||
END(copyout_smap_std) | END(copyout_smap_std) | ||||
ENTRY(copyout_nosmap_erms) | ENTRY(copyout_nosmap_erms) | ||||
COPYOUT smap=0 erms=1 | COPYOUT smap=0 erms=1 | ||||
END(copyout_nosmap_erms) | END(copyout_nosmap_erms) | ||||
ENTRY(copyout_smap_erms) | ENTRY(copyout_smap_erms) | ||||
COPYOUT smap=1 erms=1 | COPYOUT smap=1 erms=1 | ||||
END(copyout_smap_erms) | END(copyout_smap_erms) | ||||
/* | /* | ||||
* copyin(from_user, to_kernel, len) | * copyin(from_user, to_kernel, len) | ||||
* %rdi, %rsi, %rdx | * %rdi, %rsi, %rdx | ||||
*/ | */ | ||||
.macro COPYIN smap erms | .macro COPYIN smap erms | ||||
PUSH_FRAME_POINTER | PUSH_FRAME_POINTER | ||||
movq PCPU(CURPCB),%r9 | movq PCPU(CURPCB),%r11 | ||||
movq $copy_fault,PCB_ONFAULT(%r9) | movq $copy_fault,PCB_ONFAULT(%r11) | ||||
/* | /* | ||||
* make sure address is valid | * make sure address is valid | ||||
*/ | */ | ||||
movq %rdi,%rax | movq %rdi,%rax | ||||
addq %rdx,%rax | addq %rdx,%rax | ||||
jc copy_fault | jc copy_fault | ||||
movq $VM_MAXUSER_ADDRESS,%rcx | movq $VM_MAXUSER_ADDRESS,%rcx | ||||
cmpq %rcx,%rax | cmpq %rcx,%rax | ||||
ja copy_fault | ja copy_fault | ||||
xorl %eax,%eax | |||||
movq %rdi,%r8 | movq %rdi,%r8 | ||||
movq %rsi,%rdi | movq %rsi,%rdi | ||||
movq %r8,%rsi | movq %r8,%rsi | ||||
movq %rdx,%rcx | movq %rdx,%rcx | ||||
xorl %eax,%eax | |||||
SMAP_DISABLE \smap | SMAP_DISABLE \smap | ||||
.if \erms == 0 | .if \smap == 1 | ||||
cmpq $15,%rcx | MEMMOVE erms=\erms overlap=0 begin=COPYINOUT_BEGIN end=COPYINOUT_SMAP_END | ||||
jbe 1f | .else | ||||
shrq $3,%rcx /* copy longword-wise */ | MEMMOVE erms=\erms overlap=0 begin=COPYINOUT_BEGIN end=COPYINOUT_END | ||||
rep | |||||
movsq | |||||
movb %dl,%cl | |||||
andb $7,%cl /* copy remaining bytes */ | |||||
jne 1f | |||||
SMAP_ENABLE \smap | |||||
movq %rax,PCB_ONFAULT(%r9) | |||||
POP_FRAME_POINTER | |||||
ret | |||||
ALIGN_TEXT | |||||
1: | |||||
.endif | .endif | ||||
rep | /* NOTREACHED */ | ||||
movsb | |||||
SMAP_ENABLE \smap | |||||
movq %rax,PCB_ONFAULT(%r9) | |||||
POP_FRAME_POINTER | |||||
ret | |||||
.endm | .endm | ||||
ENTRY(copyin_nosmap_std) | ENTRY(copyin_nosmap_std) | ||||
COPYIN smap=0 erms=0 | COPYIN smap=0 erms=0 | ||||
END(copyin_nosmap_std) | END(copyin_nosmap_std) | ||||
ENTRY(copyin_smap_std) | ENTRY(copyin_smap_std) | ||||
COPYIN smap=1 erms=0 | COPYIN smap=1 erms=0 | ||||
END(copyin_smap_std) | END(copyin_smap_std) | ||||
ENTRY(copyin_nosmap_erms) | ENTRY(copyin_nosmap_erms) | ||||
COPYIN smap=0 erms=1 | COPYIN smap=0 erms=1 | ||||
END(copyin_nosmap_erms) | END(copyin_nosmap_erms) | ||||
ENTRY(copyin_smap_erms) | ENTRY(copyin_smap_erms) | ||||
COPYIN smap=1 erms=1 | COPYIN smap=1 erms=1 | ||||
END(copyin_smap_erms) | END(copyin_smap_erms) | ||||
ALIGN_TEXT | ALIGN_TEXT | ||||
/* Trap entry clears PSL.AC */ | /* Trap entry clears PSL.AC */ | ||||
copy_fault: | copy_fault: | ||||
movq $0,PCB_ONFAULT(%r9) | movq $0,PCB_ONFAULT(%r11) | ||||
movl $EFAULT,%eax | movl $EFAULT,%eax | ||||
POP_FRAME_POINTER | POP_FRAME_POINTER | ||||
ret | ret | ||||
/* | /* | ||||
* casueword32. Compare and set user integer. Returns -1 on fault, | * casueword32. Compare and set user integer. Returns -1 on fault, | ||||
* 0 if access was successful. Old value is written to *oldp. | * 0 if access was successful. Old value is written to *oldp. | ||||
* dst = %rdi, old = %esi, oldp = %rdx, new = %ecx | * dst = %rdi, old = %esi, oldp = %rdx, new = %ecx | ||||
▲ Show 20 Lines • Show All 832 Lines • Show Last 20 Lines |