diff options
author | marcel <marcel@FreeBSD.org> | 2003-08-06 21:32:38 +0000 |
---|---|---|
committer | marcel <marcel@FreeBSD.org> | 2003-08-06 21:32:38 +0000 |
commit | f8309da488304d559ddb59b62ddec3d210c8c4c5 (patch) | |
tree | 9a78576d974d54d10bb58dc8207962e41e349105 /sys/ia64 | |
parent | e6a614bea6abaf47e2ea0979810ff2792315df2a (diff) | |
download | FreeBSD-src-f8309da488304d559ddb59b62ddec3d210c8c4c5.zip FreeBSD-src-f8309da488304d559ddb59b62ddec3d210c8c4c5.tar.gz |
o In revision 1.45 of exception.S we changed exception_restore to
unconditionally restore ar.k7 (kernel memory stack) and ar.k6
(kernel register stack). I don't know what I was smoking then,
but if you unconditionally restore ar.k6, you also want to
compute its value unconditionally. By having the computation
predicated and dependent on whether we return to user mode, we
would end up writing junk (= invalid value for ar.bspstore) if
we would return to kernel mode. But the whole point of the
unconditional restoration was that there is a grey area where
we still need to have ar.k6 restored. If we restore with a junk
value, we would end up wedging the machine on the next interrupt.
So, unconditionally calculate the value we unconditionally write
to ar.k6.
o The previous braino was found while making the following change:
We used to clear the lower 9 bits of the value we write to ar.k6.
The meaning being that we know that the kernel register stack is
at least 512 byte aligned and simply clearing the lower 9 bits
allows us to return to a context of which we don't have dirty
registers on the kernel stack, even though the context that
entered the kernel does have dirty registers on the kernel stack.
By masking-off the lower bits, we correctly obtain the base of
the register stack without having to worry that we didn't actually
reached the base while unwinding it.
The change is to mask off the lower 13 bits, knowing that the
kernel register stack is always 8KB aligned. The advantage is that
we don't have to worry anymore if there's more than 512 bytes of
dirty registers on the kernel stack. A situation that frequently
occurs. In exec_setregs() in machdep.c:1.147 or older, we had to
deal with that situation by copying the active portion of the
register stack down in multiples of 512 bytes. Now that we mask off
the lower 13 bits we don't have to do that at all. Contemporary
IPF processors have a register file that can hold up to 96 stacked
registers (=784 bytes [incl. 2 NaT collections]). With no indication
that register files grow beyond a couple of hundred registers, we
should not have to worry about it anymore... and yes, 640KB is
enough for everybody :-)
This change helps setcontext(2) and cpu_set_upcall_kse() in that
they can return to completely different contexts without having to
mess with the kernel stack. Of course exec_setregs() doesn't need
to do that anymore as well.
Diffstat (limited to 'sys/ia64')
-rw-r--r-- | sys/ia64/ia64/exception.S | 4 | ||||
-rw-r--r-- | sys/ia64/ia64/syscall.S | 4 |
2 files changed, 4 insertions, 4 deletions
diff --git a/sys/ia64/ia64/exception.S b/sys/ia64/ia64/exception.S index a5cba96..fbbf7b6 100644 --- a/sys/ia64/ia64/exception.S +++ b/sys/ia64/ia64/exception.S @@ -535,10 +535,10 @@ exception_restore_restart: ;; } { .mmi -(p15) mov r31=ar.bspstore + mov r31=ar.bspstore ;; mov ar.bspstore=r20 -(p15) dep r31=0,r31,0,9 + dep r31=0,r31,0,13 // 8KB aligned ;; } { .mmb diff --git a/sys/ia64/ia64/syscall.S b/sys/ia64/ia64/syscall.S index f68002d..9a73ee4 100644 --- a/sys/ia64/ia64/syscall.S +++ b/sys/ia64/ia64/syscall.S @@ -486,7 +486,7 @@ epc_syscall_return: mov r30=ar.bspstore ;; mov r14=ar.k5 - dep r30=0,r30,0,9 + dep r30=0,r30,0,13 // 8KB aligned. ;; } { .mmi @@ -518,7 +518,7 @@ epc_syscall_setup_ia32: mov r30=ar.bspstore ;; mov ar.unat=r17 - dep r30=0,r30,0,9 + dep r30=0,r30,0,13 // 8KB aligned ;; } { .mmi |