Changeset View
Changeset View
Standalone View
Standalone View
head/sys/arm64/arm64/vm_machdep.c
Show First 20 Lines • Show All 147 Lines • ▼ Show 20 Lines | cpu_set_syscall_retval(struct thread *td, int error) | ||||
default: | default: | ||||
frame->tf_spsr |= PSR_C; /* carry bit */ | frame->tf_spsr |= PSR_C; /* carry bit */ | ||||
frame->tf_x[0] = error; | frame->tf_x[0] = error; | ||||
break; | break; | ||||
} | } | ||||
} | } | ||||
/* | /* | ||||
* Initialize machine state (pcb and trap frame) for a new thread about to | * Initialize machine state, mostly pcb and trap frame for a new | ||||
* upcall. Put enough state in the new thread's PCB to get it to go back | * thread, about to return to userspace. Put enough state in the new | ||||
* userret(), where we can intercept it again to set the return (upcall) | * thread's PCB to get it to go back to the fork_return(), which | ||||
* Address and stack, along with those from upcals that are from other sources | * finalizes the thread state and handles peculiarities of the first | ||||
* such as those generated in thread_userret() itself. | * return to userspace for the new thread. | ||||
*/ | */ | ||||
void | void | ||||
cpu_set_upcall(struct thread *td, struct thread *td0) | cpu_copy_thread(struct thread *td, struct thread *td0) | ||||
{ | { | ||||
bcopy(td0->td_frame, td->td_frame, sizeof(struct trapframe)); | bcopy(td0->td_frame, td->td_frame, sizeof(struct trapframe)); | ||||
bcopy(td0->td_pcb, td->td_pcb, sizeof(struct pcb)); | bcopy(td0->td_pcb, td->td_pcb, sizeof(struct pcb)); | ||||
td->td_pcb->pcb_x[8] = (uintptr_t)fork_return; | td->td_pcb->pcb_x[8] = (uintptr_t)fork_return; | ||||
td->td_pcb->pcb_x[9] = (uintptr_t)td; | td->td_pcb->pcb_x[9] = (uintptr_t)td; | ||||
td->td_pcb->pcb_x[PCB_LR] = (uintptr_t)fork_trampoline; | td->td_pcb->pcb_x[PCB_LR] = (uintptr_t)fork_trampoline; | ||||
td->td_pcb->pcb_sp = (uintptr_t)td->td_frame; | td->td_pcb->pcb_sp = (uintptr_t)td->td_frame; | ||||
td->td_pcb->pcb_vfpcpu = UINT_MAX; | td->td_pcb->pcb_vfpcpu = UINT_MAX; | ||||
/* Setup to release spin count in fork_exit(). */ | /* Setup to release spin count in fork_exit(). */ | ||||
td->td_md.md_spinlock_count = 1; | td->td_md.md_spinlock_count = 1; | ||||
td->td_md.md_saved_daif = 0; | td->td_md.md_saved_daif = 0; | ||||
} | } | ||||
/* | /* | ||||
* Set that machine state for performing an upcall that has to | * Set that machine state for performing an upcall that starts | ||||
* be done in thread_userret() so that those upcalls generated | * the entry function with the given argument. | ||||
* in thread_userret() itself can be done as well. | |||||
*/ | */ | ||||
void | void | ||||
cpu_set_upcall_kse(struct thread *td, void (*entry)(void *), void *arg, | cpu_set_upcall(struct thread *td, void (*entry)(void *), void *arg, | ||||
stack_t *stack) | stack_t *stack) | ||||
{ | { | ||||
struct trapframe *tf = td->td_frame; | struct trapframe *tf = td->td_frame; | ||||
tf->tf_sp = STACKALIGN((uintptr_t)stack->ss_sp + stack->ss_size); | tf->tf_sp = STACKALIGN((uintptr_t)stack->ss_sp + stack->ss_size); | ||||
tf->tf_elr = (register_t)entry; | tf->tf_elr = (register_t)entry; | ||||
tf->tf_x[0] = (register_t)arg; | tf->tf_x[0] = (register_t)arg; | ||||
} | } | ||||
Show All 39 Lines | |||||
/* | /* | ||||
* Intercept the return address from a freshly forked process that has NOT | * Intercept the return address from a freshly forked process that has NOT | ||||
* been scheduled yet. | * been scheduled yet. | ||||
* | * | ||||
* This is needed to make kernel threads stay in kernel mode. | * This is needed to make kernel threads stay in kernel mode. | ||||
*/ | */ | ||||
void | void | ||||
cpu_set_fork_handler(struct thread *td, void (*func)(void *), void *arg) | cpu_fork_kthread_handler(struct thread *td, void (*func)(void *), void *arg) | ||||
{ | { | ||||
td->td_pcb->pcb_x[8] = (uintptr_t)func; | td->td_pcb->pcb_x[8] = (uintptr_t)func; | ||||
td->td_pcb->pcb_x[9] = (uintptr_t)arg; | td->td_pcb->pcb_x[9] = (uintptr_t)arg; | ||||
td->td_pcb->pcb_x[PCB_LR] = (uintptr_t)fork_trampoline; | td->td_pcb->pcb_x[PCB_LR] = (uintptr_t)fork_trampoline; | ||||
td->td_pcb->pcb_sp = (uintptr_t)td->td_frame; | td->td_pcb->pcb_sp = (uintptr_t)td->td_frame; | ||||
td->td_pcb->pcb_vfpcpu = UINT_MAX; | td->td_pcb->pcb_vfpcpu = UINT_MAX; | ||||
} | } | ||||
Show All 13 Lines |