From 3602e97d70b31e6f0ae7e1d6fdcd52f4c0e0fbaf Mon Sep 17 00:00:00 2001 From: Toomas Soome Date: Fri, 2 Nov 2018 11:49:45 +0200 Subject: 9949 loader: do not probe floppy devices for zfs Reviewed by: Yuri Pankov Approved by: Dan McDonald --- usr/src/boot/sys/boot/i386/loader/main.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/usr/src/boot/sys/boot/i386/loader/main.c b/usr/src/boot/sys/boot/i386/loader/main.c index b398505a5b..443a523cfd 100644 --- a/usr/src/boot/sys/boot/i386/loader/main.c +++ b/usr/src/boot/sys/boot/i386/loader/main.c @@ -424,6 +424,8 @@ i386_zfs_probe(void) for (unit = 0; unit < MAXBDDEV; unit++) { if (bd_unit2bios(unit) == -1) break; + if (bd_unit2bios(unit) < 0x80) + continue; sprintf(devname, "disk%d:", unit); zfs_probe_dev(devname, NULL); } -- cgit v1.2.3 From b75eb7e6b5e51c1d1a8023c478487c4f4542768f Mon Sep 17 00:00:00 2001 From: Toomas Soome Date: Sat, 3 Jun 2017 01:58:24 +0300 Subject: 9840 loader: do not repeat int13 calls when we have no media 9841 loader: issue edd probe before legacy ah=08 Reviewed by: Yuri Pankov Reviewed by: Andy Fiddaman Approved by: Dan McDonald --- usr/src/boot/sys/boot/i386/libi386/biosdisk.c | 278 +++++++++++++++++++------- 1 file changed, 203 insertions(+), 75 deletions(-) diff --git a/usr/src/boot/sys/boot/i386/libi386/biosdisk.c b/usr/src/boot/sys/boot/i386/libi386/biosdisk.c index e286a7e29f..3db2144763 100644 --- a/usr/src/boot/sys/boot/i386/libi386/biosdisk.c +++ b/usr/src/boot/sys/boot/i386/libi386/biosdisk.c @@ -79,8 +79,10 @@ static struct bdinfo #define BD_MODEINT13 0x0000 #define BD_MODEEDD1 0x0001 #define BD_MODEEDD3 0x0002 +#define BD_MODEEDD (BD_MODEEDD1 | BD_MODEEDD3) #define BD_MODEMASK 0x0003 #define BD_FLOPPY 0x0004 +#define BD_NO_MEDIA 0x0008 int bd_type; /* BIOS 'drive type' (floppy only) */ uint16_t bd_sectorsize; /* Sector size */ uint64_t bd_sectors; /* Disk size */ @@ -188,60 +190,83 @@ bd_init(void) } /* - * Try to detect a device supported by the legacy int13 BIOS + * Return EDD version or 0 if EDD is not supported on this drive. */ static int -bd_int13probe(struct bdinfo *bd) +bd_check_extensions(int unit) { - struct edd_params params; - int ret = 1; /* assume success */ + /* Determine if we can use EDD with this device. */ + v86.ctl = V86_FLAGS; + v86.addr = 0x13; + v86.eax = 0x4100; + v86.edx = unit; + v86.ebx = 0x55aa; + v86int(); + + if (V86_CY(v86.efl) || /* carry set */ + (v86.ebx & 0xffff) != 0xaa55) /* signature */ + return (0); + + /* extended disk access functions (AH=42h-44h,47h,48h) supported */ + if ((v86.ecx & EDD_INTERFACE_FIXED_DISK) == 0) + return (0); + return ((v86.eax >> 8) & 0xff); +} + +static void +bd_reset_disk(int unit) +{ + /* reset disk */ + v86.ctl = V86_FLAGS; + v86.addr = 0x13; + v86.eax = 0; + v86.edx = unit; + v86int(); +} + +/* + * Read CHS info. Return 0 on success, error otherwise. + */ +static int +bd_get_diskinfo_std(struct bdinfo *bd) +{ + bzero(&v86, sizeof (v86)); v86.ctl = V86_FLAGS; v86.addr = 0x13; v86.eax = 0x800; v86.edx = bd->bd_unit; v86int(); - /* Don't error out if we get bad sector number, try EDD as well */ - if (V86_CY(v86.efl) || /* carry set */ - (v86.edx & 0xff) <= (unsigned)(bd->bd_unit & 0x7f)) /* unit # bad */ - return (0); /* skip device */ + if (V86_CY(v86.efl) && ((v86.eax & 0xff00) != 0)) + return ((v86.eax & 0xff00) >> 8); - if ((v86.ecx & 0x3f) == 0) /* absurd sector number */ - ret = 0; /* set error */ + /* return custom error on absurd sector number */ + if ((v86.ecx & 0x3f) == 0) + return (0x60); - /* Convert max cyl # -> # of cylinders */ bd->bd_cyl = ((v86.ecx & 0xc0) << 2) + ((v86.ecx & 0xff00) >> 8) + 1; /* Convert max head # -> # of heads */ bd->bd_hds = ((v86.edx & 0xff00) >> 8) + 1; bd->bd_sec = v86.ecx & 0x3f; - bd->bd_type = v86.ebx & 0xff; - bd->bd_flags |= BD_MODEINT13; + bd->bd_type = v86.ebx; + bd->bd_sectors = (uint64_t)bd->bd_cyl * bd->bd_hds * bd->bd_sec; - /* Calculate sectors count from the geometry */ - bd->bd_sectors = bd->bd_cyl * bd->bd_hds * bd->bd_sec; - bd->bd_sectorsize = BIOSDISK_SECSIZE; - DEBUG("unit 0x%x geometry %d/%d/%d", bd->bd_unit, bd->bd_cyl, - bd->bd_hds, bd->bd_sec); + return (0); +} + +/* + * Read EDD info. Return 0 on success, error otherwise. + */ +static int +bd_get_diskinfo_ext(struct bdinfo *bd) +{ + struct edd_params params; + uint64_t total; - /* Determine if we can use EDD with this device. */ - v86.ctl = V86_FLAGS; - v86.addr = 0x13; - v86.eax = 0x4100; - v86.edx = bd->bd_unit; - v86.ebx = 0x55aa; - v86int(); - if (V86_CY(v86.efl) || /* carry set */ - (v86.ebx & 0xffff) != 0xaa55 || /* signature */ - (v86.ecx & EDD_INTERFACE_FIXED_DISK) == 0) - return (ret); /* return code from int13 AH=08 */ - - /* EDD supported */ - bd->bd_flags |= BD_MODEEDD1; - if ((v86.eax & 0xff00) >= 0x3000) - bd->bd_flags |= BD_MODEEDD3; /* Get disk params */ - params.len = sizeof (struct edd_params); + bzero(¶ms, sizeof (params)); + params.len = sizeof (params); v86.ctl = V86_FLAGS; v86.addr = 0x13; v86.eax = 0x4800; @@ -249,36 +274,120 @@ bd_int13probe(struct bdinfo *bd) v86.ds = VTOPSEG(¶ms); v86.esi = VTOPOFF(¶ms); v86int(); - if (!V86_CY(v86.efl)) { - uint64_t total; - /* - * Sector size must be a multiple of 512 bytes. - * An alternate test would be to check power of 2, - * powerof2(params.sector_size). - */ - if (params.sector_size % BIOSDISK_SECSIZE) - bd->bd_sectorsize = BIOSDISK_SECSIZE; - else - bd->bd_sectorsize = params.sector_size; + if (V86_CY(v86.efl) && ((v86.eax & 0xff00) != 0)) + return ((v86.eax & 0xff00) >> 8); - total = bd->bd_sectorsize * params.sectors; - if (params.sectors != 0) { - /* Only update if we did not overflow. */ - if (total > params.sectors) - bd->bd_sectors = params.sectors; - } + /* + * Sector size must be a multiple of 512 bytes. + * An alternate test would be to check power of 2, + * powerof2(params.sector_size). + * 4K is largest read buffer we can use at this time. + */ + if (params.sector_size >= 512 && + params.sector_size <= 4096 && + (params.sector_size % BIOSDISK_SECSIZE) == 0) + bd->bd_sectorsize = params.sector_size; + bd->bd_cyl = params.cylinders; + bd->bd_hds = params.heads; + bd->bd_sec = params.sectors_per_track; + + if (params.sectors != 0) { + total = params.sectors; + } else { total = (uint64_t)params.cylinders * params.heads * params.sectors_per_track; - if (total > 0 && bd->bd_sectors > total) - bd->bd_sectors = total; + } + bd->bd_sectors = total; + + return (0); +} + +/* + * Try to detect a device supported by the legacy int13 BIOS + */ +static int +bd_int13probe(struct bdinfo *bd) +{ + int edd; + int ret; - ret = 1; + bd->bd_flags &= ~BD_NO_MEDIA; + + edd = bd_check_extensions(bd->bd_unit); + if (edd == 0) + bd->bd_flags |= BD_MODEINT13; + else if (edd < 0x30) + bd->bd_flags |= BD_MODEEDD1; + else + bd->bd_flags |= BD_MODEEDD3; + + /* Default sector size */ + bd->bd_sectorsize = BIOSDISK_SECSIZE; + + /* + * Test if the floppy device is present, so we can avoid receiving + * bogus information from bd_get_diskinfo_std(). + */ + if (bd->bd_unit < 0x80) { + /* reset disk */ + bd_reset_disk(bd->bd_unit); + + /* Get disk type */ + v86.ctl = V86_FLAGS; + v86.addr = 0x13; + v86.eax = 0x1500; + v86.edx = bd->bd_unit; + v86int(); + if (V86_CY(v86.efl) || (v86.eax & 0x300) == 0) + return (0); } - DEBUG("unit 0x%x flags %x, sectors %llu, sectorsize %u", - bd->bd_unit, bd->bd_flags, bd->bd_sectors, bd->bd_sectorsize); - return (ret); + + ret = 1; + if (edd != 0) + ret = bd_get_diskinfo_ext(bd); + if (ret != 0 || bd->bd_sectors == 0) + ret = bd_get_diskinfo_std(bd); + + if (ret != 0 && bd->bd_unit < 0x80) { + /* Set defaults for 1.44 floppy */ + bd->bd_cyl = 80; + bd->bd_hds = 2; + bd->bd_sec = 18; + bd->bd_type = 4; + bd->bd_sectors = 2880; + /* Since we are there, there most likely is no media */ + bd->bd_flags |= BD_NO_MEDIA; + ret = 0; + } + + if (ret != 0) { + if (bd->bd_sectors != 0 && edd != 0) { + bd->bd_sec = 63; + bd->bd_hds = 255; + bd->bd_cyl = + (bd->bd_sectors + bd->bd_sec * bd->bd_hds - 1) / + bd->bd_sec * bd->bd_hds; + } else { + printf("Can not get information about %s unit %#x\n", + biosdisk.dv_name, bd->bd_unit); + return (0); + } + } + + if (bd->bd_sec == 0) + bd->bd_sec = 63; + if (bd->bd_hds == 0) + bd->bd_hds = 255; + + if (bd->bd_sectors == 0) + bd->bd_sectors = (uint64_t)bd->bd_cyl * bd->bd_hds * bd->bd_sec; + + DEBUG("unit 0x%x geometry %d/%d/%d", bd->bd_unit, bd->bd_cyl, + bd->bd_hds, bd->bd_sec); + + return (1); } /* @@ -300,14 +409,19 @@ bd_print(int verbose) for (i = 0; i < nbdinfo; i++) { snprintf(line, sizeof (line), - " disk%d: BIOS drive %c (%ju X %u):\n", i, + " disk%d: BIOS drive %c (%s%ju X %u):\n", i, (bdinfo[i].bd_unit < 0x80) ? ('A' + bdinfo[i].bd_unit): ('C' + bdinfo[i].bd_unit - 0x80), + (bdinfo[i].bd_flags & BD_NO_MEDIA) == BD_NO_MEDIA ? + "no media, " : "", (uintmax_t)bdinfo[i].bd_sectors, bdinfo[i].bd_sectorsize); if ((ret = pager_output(line)) != 0) break; + if ((bdinfo[i].bd_flags & BD_NO_MEDIA) == BD_NO_MEDIA) + continue; + dev.dd.d_dev = &biosdisk; dev.dd.d_unit = i; dev.d_slice = -1; @@ -350,6 +464,13 @@ bd_open(struct open_file *f, ...) if (dev->dd.d_unit < 0 || dev->dd.d_unit >= nbdinfo) return (EIO); + + if ((BD(dev).bd_flags & BD_NO_MEDIA) == BD_NO_MEDIA) { + if (!bd_int13probe(&BD(dev))) + return (EIO); + if ((BD(dev).bd_flags & BD_NO_MEDIA) == BD_NO_MEDIA) + return (EIO); + } BD(dev).bd_open++; if (BD(dev).bd_bcache == NULL) BD(dev).bd_bcache = bcache_allocate(); @@ -454,6 +575,9 @@ bd_realstrategy(void *devdata, int rw, daddr_t dblk, size_t size, caddr_t bbuf; int rc; + if ((BD(dev).bd_flags & BD_NO_MEDIA) == BD_NO_MEDIA) + return (EIO); + /* * First make sure the IO size is a multiple of 512 bytes. While we do * process partial reads below, the strategy mechanism is built @@ -684,29 +808,33 @@ bd_io(struct disk_devdesc *dev, daddr_t dblk, int blks, caddr_t dest, if (dowrite == BD_RD && dblk >= 0x100000000) bd_io_workaround(dev); for (retry = 0; retry < 3; retry++) { - /* if retrying, reset the drive */ - if (retry > 0) { - v86.ctl = V86_FLAGS; - v86.addr = 0x13; - v86.eax = 0; - v86.edx = BD(dev).bd_unit; - v86int(); - } - - if (BD(dev).bd_flags & BD_MODEEDD1) + if (BD(dev).bd_flags & BD_MODEEDD) result = bd_edd_io(dev, dblk, blks, dest, dowrite); else result = bd_chs_io(dev, dblk, blks, dest, dowrite); - if (result == 0) + if (result == 0) { + if (BD(dev).bd_flags & BD_NO_MEDIA) + BD(dev).bd_flags &= ~BD_NO_MEDIA; + break; + } + + bd_reset_disk(BD(dev).bd_unit); + + /* + * Error codes: + * 20h controller failure + * 31h no media in drive (IBM/MS INT 13 extensions) + * 80h no media in drive, VMWare (Fusion) + * There is no reason to repeat the IO with errors above. + */ + if (result == 0x20 || result == 0x31 || result == 0x80) { + BD(dev).bd_flags |= BD_NO_MEDIA; break; + } } - /* - * 0x20 - Controller failure. This is common error when the - * media is not present. - */ - if (result != 0 && result != 0x20) { + if (result != 0 && (BD(dev).bd_flags & BD_NO_MEDIA) == 0) { if (dowrite == BD_WR) { printf("%s%d: Write %d sector(s) from %p (0x%x) " "to %lld: 0x%x\n", dev->dd.d_dev->dv_name, -- cgit v1.2.3 From b6c711cc370ad66a5c9391c71936f34bb8616e93 Mon Sep 17 00:00:00 2001 From: Richard Lowe Date: Mon, 29 Oct 2018 23:45:11 +0000 Subject: 9939 Need to stop GCC reordering functions Reviewed by: John Levon Reviewed by: Toomas Soome Approved by: Dan McDonald --- usr/src/Makefile.master | 22 +++++++++++++++------- usr/src/uts/Makefile.uts | 7 ++++--- 2 files changed, 19 insertions(+), 10 deletions(-) diff --git a/usr/src/Makefile.master b/usr/src/Makefile.master index e706a75789..85870b0d79 100644 --- a/usr/src/Makefile.master +++ b/usr/src/Makefile.master @@ -341,13 +341,21 @@ CCNOAUTOINLINE= \ -_gcc=-fno-inline-small-functions \ -_gcc=-fno-inline-functions-called-once \ -_gcc=-fno-ipa-cp \ - -_gcc6=-fno-ipa-icf \ -_gcc7=-fno-ipa-icf \ -_gcc8=-fno-ipa-icf \ - -_gcc6=-fno-clone-functions \ -_gcc7=-fno-clone-functions \ -_gcc8=-fno-clone-functions +# GCC may put functions in different named sub-sections of .text based on +# their presumed calling frequency. At least in the kernel, where we actually +# deliver relocatable objects, we don't want this to happen. +# +# Since at present we don't benefit from this even in userland, we disable it globally, +# but the application of this may move into usr/src/uts/ in future. +CCNOREORDER= \ + -_gcc7=-fno-reorder-functions \ + -_gcc8=-fno-reorder-functions + # One optimization the compiler might perform is to turn this: # #pragma weak foo # extern int foo; @@ -566,12 +574,12 @@ $(SRCDBGBLD)CCSOURCEDEBUGFLAGS = -g -xs CFLAGS= $(COPTFLAG) $($(MACH)_CFLAGS) $(SPACEFLAG) $(CCMODE) \ $(ILDOFF) $(CERRWARN) $(CSTD) $(CCUNBOUND) $(IROPTFLAG) \ - $(CGLOBALSTATIC) $(CCNOAUTOINLINE) $(CSOURCEDEBUGFLAGS) \ - $(CUSERFLAGS) + $(CGLOBALSTATIC) $(CCNOAUTOINLINE) $(CCNOREORDER) \ + $(CSOURCEDEBUGFLAGS) $(CUSERFLAGS) CFLAGS64= $(COPTFLAG64) $($(MACH64)_CFLAGS) $(SPACEFLAG64) $(CCMODE64) \ $(ILDOFF) $(CERRWARN) $(CSTD) $(CCUNBOUND) $(IROPTFLAG64) \ - $(CGLOBALSTATIC) $(CCNOAUTOINLINE) $(CSOURCEDEBUGFLAGS) \ - $(CUSERFLAGS64) + $(CGLOBALSTATIC) $(CCNOAUTOINLINE) $(CCNOREORDER) \ + $(CSOURCEDEBUGFLAGS) $(CUSERFLAGS64) # # Flags that are used to build parts of the code that are subsequently # run on the build machine (also known as the NATIVE_BUILD). @@ -579,7 +587,7 @@ CFLAGS64= $(COPTFLAG64) $($(MACH64)_CFLAGS) $(SPACEFLAG64) $(CCMODE64) \ NATIVE_CFLAGS= $(COPTFLAG) $($(NATIVE_MACH)_CFLAGS) $(CCMODE) \ $(ILDOFF) $(CERRWARN) $(CSTD) $($(NATIVE_MACH)_CCUNBOUND) \ $(IROPTFLAG) $(CGLOBALSTATIC) $(CCNOAUTOINLINE) \ - $(CSOURCEDEBUGFLAGS) $(CUSERFLAGS) + $(CCNOREORDER) $(CSOURCEDEBUGFLAGS) $(CUSERFLAGS) DTEXTDOM=-DTEXT_DOMAIN=\"$(TEXT_DOMAIN)\" # For messaging. DTS_ERRNO=-D_TS_ERRNO diff --git a/usr/src/uts/Makefile.uts b/usr/src/uts/Makefile.uts index f9eeb946fa..58bd509f19 100644 --- a/usr/src/uts/Makefile.uts +++ b/usr/src/uts/Makefile.uts @@ -43,7 +43,7 @@ include $(SRC)/Makefile.master DTEXTDOM = # -# Keep references to $(SRC)/common relative. +# Keep references to $(SRC)/common relative. COMMONBASE= $(UTSBASE)/../common # @@ -183,7 +183,7 @@ LINT_MODULE= $(MODULE) # # Build the compile/assemble lines: # -EXTRA_OPTIONS = +EXTRA_OPTIONS = AS_DEFS = -D_ASM -D__STDC__=0 ALWAYS_DEFS_32 = -D_KERNEL -D_SYSCALL32 -D_DDI_STRICT @@ -236,6 +236,7 @@ CFLAGS_uts += $(XAOPT) CFLAGS_uts += $(CTF_FLAGS_$(CLASS)) CFLAGS_uts += $(CERRWARN) CFLAGS_uts += $(CCNOAUTOINLINE) +CFLAGS_uts += $(CCNOREORDER) CFLAGS_uts += $(CGLOBALSTATIC) CFLAGS_uts += $(EXTRA_CFLAGS) CFLAGS_uts += $(CSOURCEDEBUGFLAGS) @@ -324,7 +325,7 @@ CTFMERGE_GUDIR_sparc = sun4u CTFMERGE_GUDIR_i386 = intel CTFMERGE_GUDIR = $(CTFMERGE_GUDIR_$(MACH)) -CTFMERGE_GENUNIX = \ +CTFMERGE_GENUNIX = \ $(UTSBASE)/$(CTFMERGE_GUDIR)/genunix/$(OBJS_DIR)/genunix # -- cgit v1.2.3 From c540c5554db983fb615df293797142edc10b4c62 Mon Sep 17 00:00:00 2001 From: Richard Lowe Date: Mon, 29 Oct 2018 23:45:23 +0000 Subject: 9927 refetch_read_once() would like a p please bob Reviewed by: John Levon Reviewed by: Toomas Soome Approved by: Dan McDonald --- usr/src/uts/intel/asm/cpu.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/usr/src/uts/intel/asm/cpu.h b/usr/src/uts/intel/asm/cpu.h index b8b6d9f5bf..a96d8ab6b6 100644 --- a/usr/src/uts/intel/asm/cpu.h +++ b/usr/src/uts/intel/asm/cpu.h @@ -63,7 +63,7 @@ prefetch_read_many(void *addr) } extern __GNU_INLINE void -refetch_read_once(void *addr) +prefetch_read_once(void *addr) { #if defined(__amd64) __asm__( -- cgit v1.2.3