Changeset View
Changeset View
Standalone View
Standalone View
sys/amd64/amd64/cpu_switch.S
Show First 20 Lines • Show All 209 Lines • ▼ Show 20 Lines | do_kthread: | ||||
testq %rdx,%rdx | testq %rdx,%rdx | ||||
cmovzq PCPU(COMMONTSSP),%rdx | cmovzq PCPU(COMMONTSSP),%rdx | ||||
cmpq %rax,%rdx | cmpq %rax,%rdx | ||||
jne do_tss | jne do_tss | ||||
done_tss: | done_tss: | ||||
movq %r8,PCPU(RSP0) | movq %r8,PCPU(RSP0) | ||||
movq %r8,PCPU(CURPCB) | movq %r8,PCPU(CURPCB) | ||||
/* Update the TSS_RSP0 pointer for the next interrupt */ | /* Update the TSS_RSP0 pointer for the next interrupt */ | ||||
cmpb $0,pti(%rip) | |||||
jne 1f | |||||
movq %r8,TSS_RSP0(%rdx) | movq %r8,TSS_RSP0(%rdx) | ||||
movq %r12,PCPU(CURTHREAD) /* into next thread */ | 1: movq %r12,PCPU(CURTHREAD) /* into next thread */ | ||||
/* Test if debug registers should be restored. */ | /* Test if debug registers should be restored. */ | ||||
jtl: I'm probably missing something obvious, but can you explain why this isn't needed when pti != 0? | |||||
Not Done Inline ActionsWhen PTI is enabled, inter-ring exceptions and interrupts use trampoline stack which is carved from the always mapped PCPU page, see pc_pti_stack member. It is per-cpu and is not changed on the context switch. Trap frame is copied from the trampoline stack to the thread kstack by the trampoline code. In non-PTI mode, kernel sets up the thread kstack as the interrupts stack directly. This instruction is what changes the CPU pointer to the ring 0 interrupt stack on context switch, so it must be avoided in PTI config. kib: When PTI is enabled, inter-ring exceptions and interrupts use trampoline stack which is carved… | |||||
testl $PCB_DBREGS,PCB_FLAGS(%r8) | testl $PCB_DBREGS,PCB_FLAGS(%r8) | ||||
jnz load_dr /* static predict not taken */ | jnz load_dr /* static predict not taken */ | ||||
done_load_dr: | done_load_dr: | ||||
/* Restore context. */ | /* Restore context. */ | ||||
movq PCB_R15(%r8),%r15 | movq PCB_R15(%r8),%r15 | ||||
movq PCB_R14(%r8),%r14 | movq PCB_R14(%r8),%r14 | ||||
movq PCB_R13(%r8),%r13 | movq PCB_R13(%r8),%r13 | ||||
▲ Show 20 Lines • Show All 58 Lines • ▼ Show 20 Lines | do_tss: movq %rdx,PCPU(TSSP) | ||||
movw %cx,2(%rax) | movw %cx,2(%rax) | ||||
shrq $16,%rcx | shrq $16,%rcx | ||||
movb %cl,4(%rax) | movb %cl,4(%rax) | ||||
shrq $8,%rcx | shrq $8,%rcx | ||||
movb %cl,7(%rax) | movb %cl,7(%rax) | ||||
shrq $8,%rcx | shrq $8,%rcx | ||||
movl %ecx,8(%rax) | movl %ecx,8(%rax) | ||||
movb $0x89,5(%rax) /* unset busy */ | movb $0x89,5(%rax) /* unset busy */ | ||||
movl $TSSSEL,%eax | cmpb $0,pti(%rip) | ||||
je 1f | |||||
movq PCPU(PRVSPACE),%rax | |||||
addq $PC_PTI_STACK+PC_PTI_STACK_SZ*8,%rax | |||||
movq %rax,TSS_RSP0(%rdx) | |||||
1: movl $TSSSEL,%eax | |||||
ltr %ax | ltr %ax | ||||
jmp done_tss | jmp done_tss | ||||
do_ldt: movq PCPU(LDT),%rax | do_ldt: movq PCPU(LDT),%rax | ||||
movq P_MD+MD_LDT_SD(%rcx),%rdx | movq P_MD+MD_LDT_SD(%rcx),%rdx | ||||
movq %rdx,(%rax) | movq %rdx,(%rax) | ||||
movq P_MD+MD_LDT_SD+8(%rcx),%rdx | movq P_MD+MD_LDT_SD+8(%rcx),%rdx | ||||
movq %rdx,8(%rax) | movq %rdx,8(%rax) | ||||
▲ Show 20 Lines • Show All 195 Lines • Show Last 20 Lines |
I'm probably missing something obvious, but can you explain why this isn't needed when pti != 0? Thanks in advance for educating me. :-)