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; _______________________________________________ svn-src-head@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/svn-src-head To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"