summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authormarcel <marcel@FreeBSD.org>2003-08-06 23:28:19 +0000
committermarcel <marcel@FreeBSD.org>2003-08-06 23:28:19 +0000
commit023428afce06cb7f268eed26a16af53e5957d03b (patch)
treecb7c494e27ba10689cc765c86d1ab08cf2c02bcf /sys
parent48f920ff7000bab252e9d11c4b2beb5ff4777c93 (diff)
downloadFreeBSD-src-023428afce06cb7f268eed26a16af53e5957d03b.zip
FreeBSD-src-023428afce06cb7f268eed26a16af53e5957d03b.tar.gz
In cpu_set_upcall_kse(), create the upcall according to the entry
path into the kernel. Normally it's due to a syscall, but one can also be created as the result of a clock interrupt (for example). This now even more looks like exec_setregs(). While here, add an assert that we don't expect more than 8KB of dirty registers on the kernel stack.
Diffstat (limited to 'sys')
-rw-r--r--sys/ia64/ia64/vm_machdep.c31
1 files changed, 19 insertions, 12 deletions
diff --git a/sys/ia64/ia64/vm_machdep.c b/sys/ia64/ia64/vm_machdep.c
index b8aa99a..5a4dbca 100644
--- a/sys/ia64/ia64/vm_machdep.c
+++ b/sys/ia64/ia64/vm_machdep.c
@@ -156,18 +156,15 @@ cpu_set_upcall_kse(struct thread *td, struct kse_upcall *ku)
uint64_t stack;
tf = td->td_frame;
- KASSERT(tf->tf_flags & FRAME_SYSCALL, ("foo"));
- bzero(&tf->tf_special, sizeof(tf->tf_special));
- /*
- * ku->ku_func of course points to a function descriptor. Fetch the
- * code address and GP value from userland.
- */
+
+ KASSERT((tf->tf_special.ndirty & ~PAGE_MASK) == 0,
+ ("Whoa there! We have more than 8KB of dirty registers!"));
+
fd = ku->ku_func;
- tf->tf_special.rp = fuword(&fd->func);
- tf->tf_special.gp = fuword(&fd->gp);
- tf->tf_special.pfs = (3UL<<62) | (1UL<<7) | 1UL;
stack = (uint64_t)ku->ku_stack.ss_sp;
- tf->tf_special.bspstore = stack + 8;
+
+ bzero(&tf->tf_special, sizeof(tf->tf_special));
+ tf->tf_special.gp = fuword(&fd->gp);
tf->tf_special.sp = (stack + ku->ku_stack.ss_size - 16) & ~15;
tf->tf_special.rsc = 0xf;
tf->tf_special.fpsr = IA64_FPSR_DEFAULT;
@@ -175,8 +172,18 @@ cpu_set_upcall_kse(struct thread *td, struct kse_upcall *ku)
IA64_PSR_DT | IA64_PSR_RT | IA64_PSR_DFH | IA64_PSR_BN |
IA64_PSR_CPL_USER;
- /* XXX assumes that (bspstore & 0x1f8) < 0x1e0. */
- suword((caddr_t)tf->tf_special.bspstore - 8, (uint64_t)ku->ku_mailbox);
+ if (tf->tf_flags & FRAME_SYSCALL) {
+ tf->tf_special.rp = fuword(&fd->func);
+ tf->tf_special.pfs = (3UL<<62) | (1UL<<7) | 1UL;
+ tf->tf_special.bspstore = stack + 8;
+ suword((caddr_t)stack, (uint64_t)ku->ku_mailbox);
+ } else {
+ tf->tf_special.iip = fuword(&fd->func);
+ tf->tf_special.cfm = (1UL<<63) | (1UL<<7) | 1UL;
+ tf->tf_special.bspstore = stack;
+ tf->tf_special.ndirty = 8;
+ *(uint64_t*)stack = (uint64_t)ku->ku_mailbox;
+ }
}
/*
OpenPOWER on IntegriCloud