lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <200712021930.34413.bzolnier@gmail.com>
Date:	Sun, 2 Dec 2007 19:30:34 +0100
From:	Bartlomiej Zolnierkiewicz <bzolnier@...il.com>
To:	Randy Dunlap <randy.dunlap@...cle.com>
Cc:	Mark Lord <lkml@....ca>, Nick Warne <nick@...sn.org>,
	linux-kernel@...r.kernel.org, linux-ide@...r.kernel.org
Subject: Re: Peculiar out-of-sync boot log lines

On Sunday 02 December 2007, Randy Dunlap wrote:
> On Sat, 1 Dec 2007 22:59:35 +0100 Bartlomiej Zolnierkiewicz wrote:
> 
> > Thanks for reporting/debugging it guys!
> > 
> > > Something in there needs to insert a '\n' before the "skipping word" message.
> > > Since it doesn't do that right now, the KERN_DEBUG string appears as "<7>"
> > 
> > This seems like a good occasion to fix ide_dma_verbose() for good so... :)
> > 
> > [ patch is against current Linus tree so might not apply to 2.6.23.9 ]
> > 
> > [PATCH] ide: DMA reporting and validity checking fixes
> > 
> > * ide_xfer_verbose() fixups:
> >   - beautify returned mode names
> >   - fix PIO5 reporting
> >   - make it return 'const char *'
> > 
> > * Change printk() level from KERN_DEBUG to KERN_INFO in ide_find_dma_mode().
> > 
> > * Add ide_id_dma_bug() helper based on ide_dma_verbose() to check for invalid
> >   DMA info in identify block.
> > 
> > * Use ide_id_dma_bug() in ide_tune_dma() and ide_driveid_update().
> > 
> >   As a result DMA won't be tuned or will be disabled after tuning if device
> >   reports inconsistent info about enabled DMA mode (ide_dma_verbose() does the
> >   same checks while the IDE device is probed by ide-{cd,disk} device driver).
> > 
> > * Since (id->capability & 1) && id->tDMA is a valid configuration handle
> >   it correctly in ide_id_dma_bug().
> > 
> > * Remove no longer needed ide_dma_verbose().
> > 
> > This patch should fix the following problem with out-of-sync IDE messages
> > reported by Nick Warned:
> > 
> >        hdd: ATAPI 48X DVD-ROM DVD-R-RAM CD-R/RW drive, 2048kB Cache<7>hdd:
> >        skipping word 93 validity check
> >         , UDMA(66)
> > 
> > and later debugged by Mark Lord to be caused by:
> > 
> >         ide_dma_verbose()
> >                 printk( ... "2048kB Cache");
> >         eighty_ninty_three()
> >                 printk(KERN_DEBUG "%s: skipping word 93 validity check\n");
> >         ide_dma_verbose()
> >                 printk(", UDMA(66)"
> > 
> > Please note that as a result ide-{cd,disk} device drivers won't report the
> > DMA speed used but this is intended since now DMA mode being used is always
> > reported by IDE core code.
> > 
> > Cc: Nick Warne <nick@...sn.org>
> > Cc: Mark Lord <lkml@....ca>
> > Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@...il.com>
> > ---
> >  drivers/ide/ide-cd.c   |    7 ------
> >  drivers/ide/ide-disk.c |    5 ----
> >  drivers/ide/ide-dma.c  |   57 ++++++++++++-------------------------------------
> >  drivers/ide/ide-iops.c |    3 ++
> >  drivers/ide/ide-lib.c  |   55 ++++++++++++++++++++++++-----------------------
> >  include/linux/ide.h    |    6 ++---
> >  6 files changed, 51 insertions(+), 82 deletions(-)
> > 
> > Index: b/drivers/ide/ide-cd.c
> > ===================================================================
> > --- a/drivers/ide/ide-cd.c
> > +++ b/drivers/ide/ide-cd.c
> > @@ -3049,12 +3049,7 @@ int ide_cdrom_probe_capabilities (ide_dr
> >          else 	
> >          	printk(" drive");
> >  
> > -	printk(", %dkB Cache", be16_to_cpu(cap.buffer_size));
> > -
> > -	if (drive->using_dma)
> > -		ide_dma_verbose(drive);
> > -
> > -	printk("\n");
> > +	printk(", %dkB Cache\n", be16_to_cpu(cap.buffer_size));
> 
> Use
> 	printk(KERN_CONT ...
> so that someone won't try to add another KERN_* facility level to it.
> (same for other continued printk calls in this patch)

good idea, fixed

[ I keep forgetting that there is KERN_CONT... ]

> >  
> >  	return nslots;
> >  }
> > Index: b/drivers/ide/ide-disk.c
> > ===================================================================
> > --- a/drivers/ide/ide-disk.c
> > +++ b/drivers/ide/ide-disk.c
> > @@ -961,11 +961,8 @@ static void idedisk_setup (ide_drive_t *
> >  	if (id->buf_size)
> >  		printk (" w/%dKiB Cache", id->buf_size/2);
> >  
> > -	printk(", CHS=%d/%d/%d", 
> > +	printk(", CHS=%d/%d/%d\n",
> 
> Ditto.

fixed

> >  	       drive->bios_cyl, drive->bios_head, drive->bios_sect);
> > -	if (drive->using_dma)
> > -		ide_dma_verbose(drive);
> > -	printk("\n");
> >  
> >  	/* write cache enabled? */
> >  	if ((id->csfo & 1) || (id->cfs_enable_1 & (1 << 5)))
> 
> > Index: b/include/linux/ide.h
> > ===================================================================
> > --- a/include/linux/ide.h
> > +++ b/include/linux/ide.h
> 
> > @@ -1333,8 +1334,7 @@ static inline void ide_set_hwifdata (ide
> >  	hwif->hwif_data = data;
> >  }
> >  
> > -/* ide-lib.c */
> > -extern char *ide_xfer_verbose(u8 xfer_rate);
> > +const char *ide_xfer_verbose(u8);
> >  extern void ide_toggle_bounce(ide_drive_t *drive, int on);
> >  extern int ide_set_xfer_rate(ide_drive_t *drive, u8 rate);
> 
> Ideally function prototypes would include variable names, not just
> types, as a helpful hint to readers of them.

fixed

Thanks Randy!

[PATCH] ide: DMA reporting and validity checking fixes (take 2)

* ide_xfer_verbose() fixups:
  - beautify returned mode names
  - fix PIO5 reporting
  - make it return 'const char *'

* Change printk() level from KERN_DEBUG to KERN_INFO in ide_find_dma_mode().

* Add ide_id_dma_bug() helper based on ide_dma_verbose() to check for invalid
  DMA info in identify block.

* Use ide_id_dma_bug() in ide_tune_dma() and ide_driveid_update().

  As a result DMA won't be tuned or will be disabled after tuning if device
  reports inconsistent info about enabled DMA mode (ide_dma_verbose() does the
  same checks while the IDE device is probed by ide-{cd,disk} device driver).

* Since (id->capability & 1) && id->tDMA is a valid configuration handle
  it correctly in ide_id_dma_bug().

* Remove no longer needed ide_dma_verbose().

This patch should fix the following problem with out-of-sync IDE messages
reported by Nick Warne:

       hdd: ATAPI 48X DVD-ROM DVD-R-RAM CD-R/RW drive, 2048kB Cache<7>hdd:
       skipping word 93 validity check
        , UDMA(66)

and later debugged by Mark Lord to be caused by:

        ide_dma_verbose()
                printk( ... "2048kB Cache");
        eighty_ninty_three()
                printk(KERN_DEBUG "%s: skipping word 93 validity check\n");
        ide_dma_verbose()
                printk(", UDMA(66)"

Please note that as a result ide-{cd,disk} device drivers won't report the
DMA speed used but this is intended since now DMA mode being used is always
reported by IDE core code.

v2:
* fixes suggested by Randy:
  - use KERN_CONT for printk()-s in ide-{cd,disk}.c
  - don't remove argument name from ide_xfer_verbose() declaration

Cc: Nick Warne <nick@...sn.org>
Cc: Mark Lord <lkml@....ca>
Cc: Randy Dunlap <randy.dunlap@...cle.com>
Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@...il.com>
---
 drivers/ide/ide-cd.c   |    7 ------
 drivers/ide/ide-disk.c |    7 +-----
 drivers/ide/ide-dma.c  |   57 ++++++++++++-------------------------------------
 drivers/ide/ide-iops.c |    3 ++
 drivers/ide/ide-lib.c  |   55 ++++++++++++++++++++++++-----------------------
 include/linux/ide.h    |    6 ++---
 6 files changed, 52 insertions(+), 83 deletions(-)

Index: b/drivers/ide/ide-cd.c
===================================================================
--- a/drivers/ide/ide-cd.c
+++ b/drivers/ide/ide-cd.c
@@ -3049,12 +3049,7 @@ int ide_cdrom_probe_capabilities (ide_dr
         else 	
         	printk(" drive");
 
-	printk(", %dkB Cache", be16_to_cpu(cap.buffer_size));
-
-	if (drive->using_dma)
-		ide_dma_verbose(drive);
-
-	printk("\n");
+	printk(KERN_CONT ", %dkB Cache\n", be16_to_cpu(cap.buffer_size));
 
 	return nslots;
 }
Index: b/drivers/ide/ide-disk.c
===================================================================
--- a/drivers/ide/ide-disk.c
+++ b/drivers/ide/ide-disk.c
@@ -961,11 +961,8 @@ static void idedisk_setup (ide_drive_t *
 	if (id->buf_size)
 		printk (" w/%dKiB Cache", id->buf_size/2);
 
-	printk(", CHS=%d/%d/%d", 
-	       drive->bios_cyl, drive->bios_head, drive->bios_sect);
-	if (drive->using_dma)
-		ide_dma_verbose(drive);
-	printk("\n");
+	printk(KERN_CONT ", CHS=%d/%d/%d\n",
+			 drive->bios_cyl, drive->bios_head, drive->bios_sect);
 
 	/* write cache enabled? */
 	if ((id->csfo & 1) || (id->cfs_enable_1 & (1 << 5)))
Index: b/drivers/ide/ide-dma.c
===================================================================
--- a/drivers/ide/ide-dma.c
+++ b/drivers/ide/ide-dma.c
@@ -753,7 +753,7 @@ u8 ide_find_dma_mode(ide_drive_t *drive,
 			mode = XFER_MW_DMA_1;
 	}
 
-	printk(KERN_DEBUG "%s: %s mode selected\n", drive->name,
+	printk(KERN_INFO "%s: %s mode selected\n", drive->name,
 			  mode ? ide_xfer_verbose(mode) : "no DMA");
 
 	return min(mode, req_mode);
@@ -772,6 +772,9 @@ static int ide_tune_dma(ide_drive_t *dri
 	if (__ide_dma_bad_drive(drive))
 		return 0;
 
+	if (ide_id_dma_bug(drive))
+		return 0;
+
 	if (drive->hwif->host_flags & IDE_HFLAG_TRUST_BIOS_FOR_DMA)
 		return config_drive_for_dma(drive);
 
@@ -806,58 +809,26 @@ static int ide_dma_check(ide_drive_t *dr
 	return vdma ? 0 : -1;
 }
 
-void ide_dma_verbose(ide_drive_t *drive)
+int ide_id_dma_bug(ide_drive_t *drive)
 {
-	struct hd_driveid *id	= drive->id;
-	ide_hwif_t *hwif	= HWIF(drive);
+	struct hd_driveid *id = drive->id;
 
 	if (id->field_valid & 4) {
 		if ((id->dma_ultra >> 8) && (id->dma_mword >> 8))
-			goto bug_dma_off;
-		if (id->dma_ultra & ((id->dma_ultra >> 8) & hwif->ultra_mask)) {
-			if (((id->dma_ultra >> 11) & 0x1F) &&
-			    eighty_ninty_three(drive)) {
-				if ((id->dma_ultra >> 15) & 1) {
-					printk(", UDMA(mode 7)");
-				} else if ((id->dma_ultra >> 14) & 1) {
-					printk(", UDMA(133)");
-				} else if ((id->dma_ultra >> 13) & 1) {
-					printk(", UDMA(100)");
-				} else if ((id->dma_ultra >> 12) & 1) {
-					printk(", UDMA(66)");
-				} else if ((id->dma_ultra >> 11) & 1) {
-					printk(", UDMA(44)");
-				} else
-					goto mode_two;
-			} else {
-		mode_two:
-				if ((id->dma_ultra >> 10) & 1) {
-					printk(", UDMA(33)");
-				} else if ((id->dma_ultra >> 9) & 1) {
-					printk(", UDMA(25)");
-				} else if ((id->dma_ultra >> 8) & 1) {
-					printk(", UDMA(16)");
-				}
-			}
-		} else {
-			printk(", (U)DMA");	/* Can be BIOS-enabled! */
-		}
+			goto err_out;
 	} else if (id->field_valid & 2) {
 		if ((id->dma_mword >> 8) && (id->dma_1word >> 8))
-			goto bug_dma_off;
-		printk(", DMA");
+			goto err_out;
 	} else if (id->field_valid & 1) {
-		goto bug_dma_off;
+		if (id->tDMA == 0)
+			goto err_out;
 	}
-	return;
-bug_dma_off:
-	printk(", BUG DMA OFF");
-	hwif->dma_off_quietly(drive);
-	return;
+	return 0;
+err_out:
+	printk(KERN_ERR "%s: bad DMA info in identify block\n", drive->name);
+	return 1;
 }
 
-EXPORT_SYMBOL(ide_dma_verbose);
-
 int ide_set_dma(ide_drive_t *drive)
 {
 	ide_hwif_t *hwif = drive->hwif;
Index: b/drivers/ide/ide-iops.c
===================================================================
--- a/drivers/ide/ide-iops.c
+++ b/drivers/ide/ide-iops.c
@@ -748,6 +748,9 @@ int ide_driveid_update(ide_drive_t *driv
 		drive->id->dma_1word = id->dma_1word;
 		/* anything more ? */
 		kfree(id);
+
+		if (drive->using_dma && ide_id_dma_bug(drive))
+			ide_dma_off(drive);
 	}
 
 	return 1;
Index: b/drivers/ide/ide-lib.c
===================================================================
--- a/drivers/ide/ide-lib.c
+++ b/drivers/ide/ide-lib.c
@@ -29,41 +29,44 @@
  *	Add common non I/O op stuff here. Make sure it has proper
  *	kernel-doc function headers or your patch will be rejected
  */
- 
+
+static const char *udma_str[] =
+	 { "UDMA/16", "UDMA/25",  "UDMA/33",  "UDMA/44",
+	   "UDMA/66", "UDMA/100", "UDMA/133", "UDMA7" };
+static const char *mwdma_str[] =
+	{ "MWDMA0", "MWDMA1", "MWDMA2" };
+static const char *swdma_str[] =
+	{ "SWDMA0", "SWDMA1", "SWDMA2" };
+static const char *pio_str[] =
+	{ "PIO0", "PIO1", "PIO2", "PIO3", "PIO4", "PIO5" };
 
 /**
  *	ide_xfer_verbose	-	return IDE mode names
- *	@xfer_rate: rate to name
+ *	@mode: transfer mode
  *
  *	Returns a constant string giving the name of the mode
  *	requested.
  */
 
-char *ide_xfer_verbose (u8 xfer_rate)
+const char *ide_xfer_verbose(u8 mode)
 {
-        switch(xfer_rate) {
-                case XFER_UDMA_7:	return("UDMA 7");
-                case XFER_UDMA_6:	return("UDMA 6");
-                case XFER_UDMA_5:	return("UDMA 5");
-                case XFER_UDMA_4:	return("UDMA 4");
-                case XFER_UDMA_3:	return("UDMA 3");
-                case XFER_UDMA_2:	return("UDMA 2");
-                case XFER_UDMA_1:	return("UDMA 1");
-                case XFER_UDMA_0:	return("UDMA 0");
-                case XFER_MW_DMA_2:	return("MW DMA 2");
-                case XFER_MW_DMA_1:	return("MW DMA 1");
-                case XFER_MW_DMA_0:	return("MW DMA 0");
-                case XFER_SW_DMA_2:	return("SW DMA 2");
-                case XFER_SW_DMA_1:	return("SW DMA 1");
-                case XFER_SW_DMA_0:	return("SW DMA 0");
-                case XFER_PIO_4:	return("PIO 4");
-                case XFER_PIO_3:	return("PIO 3");
-                case XFER_PIO_2:	return("PIO 2");
-                case XFER_PIO_1:	return("PIO 1");
-                case XFER_PIO_0:	return("PIO 0");
-                case XFER_PIO_SLOW:	return("PIO SLOW");
-                default:		return("XFER ERROR");
-        }
+	const char *s;
+	u8 i = mode & 0xf;
+
+	if (mode >= XFER_UDMA_0 && mode <= XFER_UDMA_7)
+		s = udma_str[i];
+	else if (mode >= XFER_MW_DMA_0 && mode <= XFER_MW_DMA_2)
+		s = mwdma_str[i];
+	else if (mode >= XFER_SW_DMA_0 && mode <= XFER_SW_DMA_2)
+		s = swdma_str[i];
+	else if (mode >= XFER_PIO_0 && mode <= XFER_PIO_5)
+		s = pio_str[i & 0x7];
+	else if (mode == XFER_PIO_SLOW)
+		s = "XFER SLOW";
+	else
+		s = "XFER ERROR";
+
+	return s;
 }
 
 EXPORT_SYMBOL(ide_xfer_verbose);
Index: b/include/linux/ide.h
===================================================================
--- a/include/linux/ide.h
+++ b/include/linux/ide.h
@@ -1255,6 +1255,7 @@ int ide_in_drive_list(struct hd_driveid 
 
 #ifdef CONFIG_BLK_DEV_IDEDMA
 int __ide_dma_bad_drive(ide_drive_t *);
+int ide_id_dma_bug(ide_drive_t *);
 
 u8 ide_find_dma_mode(ide_drive_t *, u8);
 
@@ -1264,7 +1265,6 @@ static inline u8 ide_max_dma_mode(ide_dr
 }
 
 void ide_dma_off(ide_drive_t *);
-void ide_dma_verbose(ide_drive_t *);
 int ide_set_dma(ide_drive_t *);
 ide_startstop_t ide_dma_intr(ide_drive_t *);
 
@@ -1287,6 +1287,7 @@ extern void ide_dma_timeout(ide_drive_t 
 #endif /* CONFIG_BLK_DEV_IDEDMA_PCI */
 
 #else
+static inline int ide_id_dma_bug(ide_drive_t *drive) { return 0; }
 static inline u8 ide_find_dma_mode(ide_drive_t *drive, u8 speed) { return 0; }
 static inline u8 ide_max_dma_mode(ide_drive_t *drive) { return 0; }
 static inline void ide_dma_off(ide_drive_t *drive) { ; }
@@ -1333,8 +1334,7 @@ static inline void ide_set_hwifdata (ide
 	hwif->hwif_data = data;
 }
 
-/* ide-lib.c */
-extern char *ide_xfer_verbose(u8 xfer_rate);
+const char *ide_xfer_verbose(u8 mode);
 extern void ide_toggle_bounce(ide_drive_t *drive, int on);
 extern int ide_set_xfer_rate(ide_drive_t *drive, u8 rate);
 

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ