summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authormarcel <marcel@FreeBSD.org>2003-05-31 20:42:35 +0000
committermarcel <marcel@FreeBSD.org>2003-05-31 20:42:35 +0000
commitbf9a37ed8338bf2dbce1e1e8880f698a482359ea (patch)
treeb15981299d48c7adb91668280dc2f188cae082fc /sys
parente4952b702ffa972e0987609708d139468da590f3 (diff)
downloadFreeBSD-src-bf9a37ed8338bf2dbce1e1e8880f698a482359ea.zip
FreeBSD-src-bf9a37ed8338bf2dbce1e1e8880f698a482359ea.tar.gz
Make sure we have all the dirty registers in user frames on the
backing store before we discard them. It is possible that we enter the kernel (due to an execve in this case) with a lot of dirty user registers and that the RSE has only partially spilled them (to make room for new frames). We cannot move the backing store pointer down (to discard user registers) when not all of the user registers are on the backing store. So, we flush the register stack IFF this happens. Unconditionally doing the flush is too costly, because the condition in which we need to flush is very rare. This change appears to fix the SIGSEGV that sometimes happen for newly executed processes and so far also appears to fix the last of the corruption. It is possible, although not likely, that this change prevents some other bug from happening, even though it is itself not a fix. Hence the uncertainty. We'll know in a couple of months I guess :-)
Diffstat (limited to 'sys')
-rw-r--r--sys/ia64/ia64/machdep.c14
1 files changed, 12 insertions, 2 deletions
diff --git a/sys/ia64/ia64/machdep.c b/sys/ia64/ia64/machdep.c
index cc6f407..9ff50d4 100644
--- a/sys/ia64/ia64/machdep.c
+++ b/sys/ia64/ia64/machdep.c
@@ -1074,8 +1074,18 @@ exec_setregs(struct thread *td, u_long entry, u_long stack, u_long ps_strings)
if (ndirty > 0) {
__asm __volatile("mov ar.rsc=0;;");
__asm __volatile("mov %0=ar.bspstore" : "=r"(bspst));
- rssz = bspst - kstack - ndirty;
- bcopy((void*)(kstack + ndirty), (void*)kstack, rssz);
+ /*
+ * Make sure we have all the user registers written out.
+ * We're doing culculations with ndirty and ar.bspstore
+ * and we better make sure ar.bspstore >= ndirty.
+ */
+ rssz = bspst - kstack;
+ if (rssz < ndirty) {
+ __asm __volatile("flushrs;;");
+ __asm __volatile("mov %0=ar.bspstore" : "=r"(bspst));
+ rssz = bspst - kstack;
+ }
+ bcopy((void*)(kstack + ndirty), (void*)kstack, rssz - ndirty);
bspst -= ndirty;
__asm __volatile("mov ar.bspstore=%0;;" :: "r"(bspst));
__asm __volatile("mov ar.rsc=3");
OpenPOWER on IntegriCloud