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