svn commit: r313349 - in head/sys/boot/i386: btx/lib libi386
Toomas Soome
tsoome at FreeBSD.org
Mon Feb 6 18:44:17 UTC 2017
Author: tsoome
Date: Mon Feb 6 18:44:15 2017
New Revision: 313349
URL: https://svnweb.freebsd.org/changeset/base/313349
Log:
loader: disk io should not use alloca()
The alloca() does give us pointer and we have no practical way to check if the
area is actually available, resulting in corruption in corner cases.
Unfortunately we do not have too many options right now, but to use one page.
Reviewed by: allanjude
Approved by: allanjude (mentor)
Differential Revision: https://reviews.freebsd.org/D9455
Modified:
head/sys/boot/i386/btx/lib/btxv86.h
head/sys/boot/i386/libi386/bioscd.c
head/sys/boot/i386/libi386/biosdisk.c
Modified: head/sys/boot/i386/btx/lib/btxv86.h
==============================================================================
--- head/sys/boot/i386/btx/lib/btxv86.h Mon Feb 6 18:29:43 2017 (r313348)
+++ head/sys/boot/i386/btx/lib/btxv86.h Mon Feb 6 18:44:15 2017 (r313349)
@@ -23,6 +23,14 @@
#include <sys/types.h>
#include <machine/psl.h>
+/*
+ * Memory buffer space for real mode IO.
+ * Just one page is not much, but the space is rather limited.
+ * See ../btx/btx.S for details.
+ */
+#define V86_IO_BUFFER 0x8000
+#define V86_IO_BUFFER_SIZE 0x1000
+
#define V86_ADDR 0x10000 /* Segment:offset address */
#define V86_CALLF 0x20000 /* Emulate far call */
#define V86_FLAGS 0x40000 /* Return flags */
Modified: head/sys/boot/i386/libi386/bioscd.c
==============================================================================
--- head/sys/boot/i386/libi386/bioscd.c Mon Feb 6 18:29:43 2017 (r313348)
+++ head/sys/boot/i386/libi386/bioscd.c Mon Feb 6 18:44:15 2017 (r313349)
@@ -309,9 +309,6 @@ bc_realstrategy(void *devdata, int rw, d
return (0);
}
-/* Max number of sectors to bounce-buffer at a time. */
-#define CD_BOUNCEBUF 8
-
/* return negative value for an error, otherwise blocks read */
static int
bc_read(int unit, daddr_t dblk, int blks, caddr_t dest)
@@ -339,8 +336,9 @@ bc_read(int unit, daddr_t dblk, int blks
* physical memory so we have to arrange a suitable
* bounce buffer.
*/
- x = min(CD_BOUNCEBUF, (unsigned)blks);
- bbuf = alloca(x * BIOSCD_SECSIZE);
+ x = V86_IO_BUFFER_SIZE / BIOSCD_SECSIZE;
+ x = min(x, (unsigned)blks);
+ bbuf = PTOV(V86_IO_BUFFER);
maxfer = x;
} else {
bbuf = NULL;
Modified: head/sys/boot/i386/libi386/biosdisk.c
==============================================================================
--- head/sys/boot/i386/libi386/biosdisk.c Mon Feb 6 18:29:43 2017 (r313348)
+++ head/sys/boot/i386/libi386/biosdisk.c Mon Feb 6 18:44:15 2017 (r313349)
@@ -666,9 +666,6 @@ bd_realstrategy(void *devdata, int rw, d
return (0);
}
-/* Max number of sectors to bounce-buffer if the request crosses a 64k boundary */
-#define FLOPPY_BOUNCEBUF 18
-
static int
bd_edd_io(struct disk_devdesc *dev, daddr_t dblk, int blks, caddr_t dest,
int write)
@@ -732,7 +729,7 @@ static int
bd_io(struct disk_devdesc *dev, daddr_t dblk, int blks, caddr_t dest, int write)
{
u_int x, sec, result, resid, retry, maxfer;
- caddr_t p, xp, bbuf, breg;
+ caddr_t p, xp, bbuf;
/* Just in case some idiot actually tries to read/write -1 blocks... */
if (blks < 0)
@@ -754,17 +751,12 @@ bd_io(struct disk_devdesc *dev, daddr_t
* as we need to. Use the bottom half unless there is a break
* there, in which case we use the top half.
*/
- x = min(FLOPPY_BOUNCEBUF, (unsigned)blks);
- bbuf = alloca(x * 2 * BD(dev).bd_sectorsize);
- if (((u_int32_t)VTOP(bbuf) & 0xffff0000) ==
- ((u_int32_t)VTOP(bbuf + x * BD(dev).bd_sectorsize) & 0xffff0000)) {
- breg = bbuf;
- } else {
- breg = bbuf + x * BD(dev).bd_sectorsize;
- }
+ x = V86_IO_BUFFER_SIZE / BD(dev).bd_sectorsize;
+ x = min(x, (unsigned)blks);
+ bbuf = PTOV(V86_IO_BUFFER);
maxfer = x; /* limit transfers to bounce region size */
} else {
- breg = bbuf = NULL;
+ bbuf = NULL;
maxfer = 0;
}
@@ -779,14 +771,14 @@ bd_io(struct disk_devdesc *dev, daddr_t
x = min(x, maxfer); /* fit bounce buffer */
/* where do we transfer to? */
- xp = bbuf == NULL ? p : breg;
+ xp = bbuf == NULL ? p : bbuf;
/*
* Put your Data In, Put your Data out,
* Put your Data In, and shake it all about
*/
if (write && bbuf != NULL)
- bcopy(p, breg, x * BD(dev).bd_sectorsize);
+ bcopy(p, bbuf, x * BD(dev).bd_sectorsize);
/*
* Loop retrying the operation a couple of times. The BIOS
@@ -820,7 +812,7 @@ bd_io(struct disk_devdesc *dev, daddr_t
return(-1);
}
if (!write && bbuf != NULL)
- bcopy(breg, p, x * BD(dev).bd_sectorsize);
+ bcopy(bbuf, p, x * BD(dev).bd_sectorsize);
p += (x * BD(dev).bd_sectorsize);
dblk += x;
resid -= x;
More information about the svn-src-head
mailing list