summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authordyson <dyson@FreeBSD.org>1996-06-26 05:52:15 +0000
committerdyson <dyson@FreeBSD.org>1996-06-26 05:52:15 +0000
commite2f426dc1b0fb18a48ef0de15a04f0588e32f27e (patch)
tree58040758fb53585e2e6cb0cd317176c89b632e36 /sys
parentf345bebc3296865457028897f6766ea365ce23d9 (diff)
downloadFreeBSD-src-e2f426dc1b0fb18a48ef0de15a04f0588e32f27e.zip
FreeBSD-src-e2f426dc1b0fb18a48ef0de15a04f0588e32f27e.tar.gz
Fix a problem that caused system crashes after physio. This problem
was due to non-aligned 64K transfers taking 17 pages. We currently do not support >16 page transfers. The transfer is unfortunately truncated, but since buffers are usually malloced, this is a problem only once in a while. Savecore is a culprit, but tar/cpio usually aren't. This is NOT the final fix (which is likely a bouncing scheme), but will at least keep the system from crashing.
Diffstat (limited to 'sys')
-rw-r--r--sys/kern/kern_physio.c17
1 files changed, 11 insertions, 6 deletions
diff --git a/sys/kern/kern_physio.c b/sys/kern/kern_physio.c
index 7f8324b..ed4920c 100644
--- a/sys/kern/kern_physio.c
+++ b/sys/kern/kern_physio.c
@@ -16,7 +16,7 @@
* 4. Modifications may be freely made to this file if the above conditions
* are met.
*
- * $Id: kern_physio.c,v 1.15 1995/12/07 12:46:46 davidg Exp $
+ * $Id: kern_physio.c,v 1.16 1995/12/13 15:12:59 julian Exp $
*/
#include <sys/param.h>
@@ -78,13 +78,13 @@ physio(strategy, bp, dev, rw, minp, uio)
while( uio->uio_iov[i].iov_len) {
bp->b_bcount = uio->uio_iov[i].iov_len;
+ bp->b_flags = B_BUSY | B_PHYS | B_CALL | bufflags;
+ bp->b_iodone = physwakeup;
+ bp->b_data = uio->uio_iov[i].iov_base;
bp->b_bcount = minp( bp);
if( minp != minphys)
bp->b_bcount = minphys( bp);
bp->b_bufsize = bp->b_bcount;
- bp->b_flags = B_BUSY | B_PHYS | B_CALL | bufflags;
- bp->b_iodone = physwakeup;
- bp->b_data = uio->uio_iov[i].iov_base;
/*
* pass in the kva from the physical buffer
* for the temporary kernel mapping.
@@ -164,9 +164,14 @@ doerror:
u_int
minphys(struct buf *bp)
{
+ u_int maxphys = MAXPHYS;
+
+ if( ((vm_offset_t) bp->b_data) & PAGE_MASK) {
+ maxphys = MAXPHYS - PAGE_SIZE;
+ }
- if( bp->b_bcount > MAXPHYS) {
- bp->b_bcount = MAXPHYS;
+ if( bp->b_bcount > maxphys) {
+ bp->b_bcount = maxphys;
}
return bp->b_bcount;
}
OpenPOWER on IntegriCloud