diff options
author | David Xu <davidxu@FreeBSD.org> | 2005-04-23 02:32:32 +0000 |
---|---|---|
committer | David Xu <davidxu@FreeBSD.org> | 2005-04-23 02:32:32 +0000 |
commit | 21fc3164307dc288ff6eb1f028a268f3c76cc6e5 (patch) | |
tree | e8274d07cfba3da625ef093c47b41f515a3a074f /sys/amd64/amd64/vm_machdep.c | |
parent | 0a5660df88347961063dfcef88f0712b672661c7 (diff) | |
download | src-21fc3164307dc288ff6eb1f028a268f3c76cc6e5.tar.gz src-21fc3164307dc288ff6eb1f028a268f3c76cc6e5.zip |
Change cpu_set_kse_upcall to more generic style, so we can reuse it
in other codes. Add cpu_set_user_tls, use it to tweak user register
and setup user TLS. I ever wanted to merge it into cpu_set_kse_upcall,
but since cpu_set_kse_upcall is also used by M:N threads which may
not need this feature, so I wrote a separated cpu_set_user_tls.
Notes
Notes:
svn path=/head/; revision=145433
Diffstat (limited to 'sys/amd64/amd64/vm_machdep.c')
-rw-r--r-- | sys/amd64/amd64/vm_machdep.c | 25 |
1 files changed, 20 insertions, 5 deletions
diff --git a/sys/amd64/amd64/vm_machdep.c b/sys/amd64/amd64/vm_machdep.c index dd1e4bf35266..d3cae91f6eec 100644 --- a/sys/amd64/amd64/vm_machdep.c +++ b/sys/amd64/amd64/vm_machdep.c @@ -310,7 +310,8 @@ cpu_set_upcall(struct thread *td, struct thread *td0) * in thread_userret() itself can be done as well. */ void -cpu_set_upcall_kse(struct thread *td, struct kse_upcall *ku) +cpu_set_upcall_kse(struct thread *td, void (*entry)(void *), void *arg, + stack_t *stack) { /* @@ -326,18 +327,32 @@ cpu_set_upcall_kse(struct thread *td, struct kse_upcall *ku) * Set the trap frame to point at the beginning of the uts * function. */ - td->td_frame->tf_rbp = 0; + td->td_frame->tf_rbp = 0; td->td_frame->tf_rsp = - ((register_t)ku->ku_stack.ss_sp + ku->ku_stack.ss_size) & ~0x0f; + ((register_t)stack->ss_sp + stack->ss_size) & ~0x0f; td->td_frame->tf_rsp -= 8; td->td_frame->tf_rbp = 0; - td->td_frame->tf_rip = (register_t)ku->ku_func; + td->td_frame->tf_rip = (register_t)entry; /* * Pass the address of the mailbox for this kse to the uts * function as a parameter on the stack. */ - td->td_frame->tf_rdi = (register_t)ku->ku_mailbox; + td->td_frame->tf_rdi = (register_t)arg; +} + +void +cpu_set_user_tls(struct thread *td, void *tls_base) +{ + + if (td == curthread) { + critical_enter(); + td->td_pcb->pcb_fsbase = (register_t)tls_base; + wrmsr(MSR_FSBASE, td->td_pcb->pcb_fsbase); + critical_exit(); + } else { + td->td_pcb->pcb_fsbase = (register_t)tls_base; + } } #ifdef SMP |