Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 27 Apr 100 20:32:44 +0100 (METDST)
From:      Martin Butkus <y0001415@rzbcosv0.rz.tu-bs.de>
To:        freebsd-gnats-submit@freebsd.org, jin@gracie.lbl.gov, freebsd-bugs@freebsd.org
Subject:   Re: kern/16767: open("/dev/ppi0") will crash machine without sync disk
Message-ID:  <200004271832.UAA26106@rzbcosv0.rz.tu-bs.de>

next in thread | raw e-mail | index | archive | help
Hi!

A friend of mine has the same problem as described in said PR, and
I was able to reproduce it on my box. We use a recent 4.0-STABLE
with src/sys/dev/ppbus/ppi.c rev 1.21.

I had a look at the source code and found that in ppi_attach(), 
the interrupt failed to allocate for some reason (line 173ff):

        /* declare our interrupt handler */
        ppi->intr_resource = bus_alloc_resource(dev, SYS_RES_IRQ,
                                                &zero, irq, irq, 1, RF_ACTIVE);

This results in ppi->intr_resource being NULL.

In ppiopen() this caused BUS_SETUP_INTR()'s third argument to be NULL 
(line 282ff): 

                /* register our interrupt handler */
                BUS_SETUP_INTR(device_get_parent(ppidev), ppidev, ppi->intr_reso
urce,
                               INTR_TYPE_TTY, ppiintr, dev, &ppi->intr_cookie);

BUS_SETUP_INTR seems to be a function pointer to nexus_setup_intr(),
which checks for this condition and causes the panic.

Revision 1.22 (present in -CURRENT, but not in -STABLE) adds a
check for failed interrupt allocation to ppi_attach():

<<<< snip <<<<
===================================================================
RCS file: /home/ncvs/src/sys/dev/ppbus/ppi.c,v
retrieving revision 1.21
retrieving revision 1.22
diff -p -u -r1.21 -r1.22
- --- src/sys/dev/ppbus/ppi.c     2000/01/23 14:41:04     1.21
+++ /home/ncvs/src/sys/dev/ppbus/ppi.c  2000/04/07 00:09:24     1.22
@@ -23,7 +23,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- - * $FreeBSD: src/sys/dev/ppbus/ppi.c,v 1.21 2000/01/23 14:41:04 peter Exp $
+ * $FreeBSD: src/sys/dev/ppbus/ppi.c,v 1.22 2000/04/07 00:09:24 jlemon Exp $
  *
  */
 #include "opt_ppb_1284.h"
@@ -173,6 +173,10 @@ ppi_attach(device_t dev)
        /* declare our interrupt handler */
        ppi->intr_resource = bus_alloc_resource(dev, SYS_RES_IRQ,
                                                &zero, irq, irq, 1, RF_ACTIVE);
+       if (ppi->intr_resource == NULL) {
+               device_printf(dev, "can't allocate irq\n");
+               return (ENOMEM);
+       }
 
        make_dev(&ppi_cdevsw, device_get_unit(dev),     /* XXX cleanup */
                 UID_ROOT, GID_WHEEL,
>>>> snap >>>>

But this does not really solve the problem, IMHO, since the interrupt
allocation should not have failed in the first place. This way,
the ppi device fails to attach completely. From dmesg(8):

> ppc0: <Parallel port> at port 0x278-0x27f irq 5 on isa0
> ppc0: SMC-like chipset (ECP/EPP/PS2/NIBBLE) in COMPATIBLE mode
> ppc0: FIFO with 16/16/16 bytes threshold
> ppi0: <Parallel I/O> on ppbus0
> ppi0: can't allocate irq
> device_probe_and_attach: ppi0 attach returned 12

I have then tried changing RF_ACTIVE to RF_SHAREABLE.  
This flag is used in lpt.c for interrupt allocation 
(see sys/dev/ppbus/lpt.c, rev 1.15.2.1, line 460ff):

        /* retrieve the ppbus irq */
        BUS_READ_IVAR(ppbus, dev, PPBUS_IVAR_IRQ, &irq);

        if (irq > 0) {
                /* declare our interrupt handler */
                sc->intr_resource = bus_alloc_resource(dev, SYS_RES_IRQ,
                                                       &zero, irq, irq, 1, RF_SHAREABLE);
        }

I don't know whether this is the "right" thing to do because I
don't quite understand the meaning of these flags. However, things
seem to work now.  My friend has tested the modified ppi driver
with the example from /usr/share/examples/ppi/ppilcd.c (he actually
has the LCD hardware).

This is the diff of my kernel changes, relative to ppi.c rev 1.21. 
It also contains the NULL pointer check from rev 1.22.

<<<< snip <<<<
- --- sys/dev/ppbus/ppi.c.orig	Wed Apr 26 22:08:37 2000
+++ sys/dev/ppbus/ppi.c	Wed Apr 26 22:14:31 2000
@@ -172,7 +172,11 @@
 
 	/* declare our interrupt handler */
 	ppi->intr_resource = bus_alloc_resource(dev, SYS_RES_IRQ,
- -						&zero, irq, irq, 1, RF_ACTIVE);
+						&zero, irq, irq, 1, RF_SHAREABL
E);
+	if (ppi->intr_resource == NULL) {
+		device_printf(dev, "can't allocate irq\n");
+		return (ENOMEM);
+	}
 
 	make_dev(&ppi_cdevsw, device_get_unit(dev),	/* XXX cleanup */
 		 UID_ROOT, GID_WHEEL,
>>>> snap >>>>

Also, I had to make the following changes to ppilcd to make it compile.
This patch is relative to:

$FreeBSD: src/share/examples/ppi/Makefile,v 1.2 1999/08/28 00:19:27 peter Exp 
$FreeBSD: src/share/examples/ppi/ppilcd.c,v 1.2 1999/08/28 00:19:28 peter Exp


<<<< snip <<<<
*** share/examples/ppi/Makefile.orig	Thu Apr 27 11:15:36 2000
- --- share/examples/ppi/Makefile	Thu Apr 27 11:15:48 2000
***************
*** 5,8 ****
- --- 5,10 ----
  PROG=	ppilcd
  NOMAN=	YES
  
+ CFLAGS +=-I/sys/dev/ppbus
+ 
  .include <bsd.prog.mk>
*** share/examples/ppi/ppilcd.c.orig	Thu Apr 27 11:15:28 2000
- --- share/examples/ppi/ppilcd.c	Thu Apr 27 11:17:08 2000
***************
*** 14,19 ****
- --- 14,21 ----
  #include <err.h>
  #include <sysexits.h>
  
+ typedef void *device_t;
+ 
  /* XXX should be in <machine/> */
  #include "ppbconf.h"
  #include "ppi.h"
***************
*** 89,95 ****
  int	debuglevel = 0;
  int	vflag = 0;
  
! void
  main(int argc, char *argv[]) 
  {
      extern char		*optarg;
- --- 91,97 ----
  int	debuglevel = 0;
  int	vflag = 0;
  
! int
  main(int argc, char *argv[]) 
  {
      extern char		*optarg;
>>>> snap >>>>

In case it matters, this is the dmesg(8) output of my box:

<<<< snip <<<<
Copyright (c) 1992-2000 The FreeBSD Project.
Copyright (c) 1982, 1986, 1989, 1991, 1993
	The Regents of the University of California. All rights reserved.
FreeBSD 4.0-STABLE #9: Tue Apr 25 23:25:47 CEST 2000
    root@bagheera.ts.rz.tu-bs.de:/usr/src/sys/compile/BAGHEERA
Timecounter "i8254"  frequency 1193182 Hz
CPU: Pentium/P55C (165.79-MHz 586-class CPU)
  Origin = "GenuineIntel"  Id = 0x543  Stepping = 3
  Features=0x8001bf<FPU,VME,DE,PSE,TSC,MSR,MCE,CX8,MMX>
real memory  = 67108864 (65536K bytes)
avail memory = 61960192 (60508K bytes)
Preloaded elf kernel "kernel" at 0xc034b000.
Preloaded userconfig_script "/boot/kernel.conf" at 0xc034b09c.
Intel Pentium detected, installing workaround for F00F bug
md0: Malloc disk
npx0: <math processor> on motherboard
npx0: INT 16 interface
pcib0: <Host to PCI bridge> on motherboard
pci0: <PCI bus> on pcib0
isab0: <Intel 82371FB PCI to ISA bridge> at device 7.0 on pci0
isa0: <ISA bus> on isab0
atapci0: <Intel PIIX ATA controller> port 0xe800-0xe80f at device 7.1 on pci0
ata0: at 0x1f0 irq 14 on atapci0
ncr0: <ncr 53c810 fast10 scsi> port 0xe400-0xe4ff mem 0xe6000000-0xe60000ff irq 12 at device 9.0 on pci0
ncr0: driver is using old-style compatability shims
ed0: <NE2000 PCI Ethernet (RealTek 8029)> port 0xe000-0xe01f irq 10 at device 10.0 on pci0
ed0: supplying EUI64: 00:00:21:ff:fe:48:36:b9
ed0: address 00:00:21:48:36:b9, type NE2000 (16 bit) 
pci0: <ATI Mach64-GP graphics accelerator> at 12.0
fdc0: <NEC 72065B or clone> at port 0x3f0-0x3f5,0x3f7 irq 6 drq 2 on isa0
fdc0: FIFO enabled, 8 bytes threshold
fd0: <1440-KB 3.5" drive> on fdc0 drive 0
atkbdc0: <Keyboard controller (i8042)> at port 0x60,0x64 on isa0
atkbd0: <AT Keyboard> irq 1 on atkbdc0
vga0: <Generic ISA VGA> at port 0x3c0-0x3df iomem 0xa0000-0xbffff on isa0
sc0: <System console> on isa0
sc0: VGA <16 virtual consoles, flags=0x200>
sio0 at port 0x3f8-0x3ff irq 4 flags 0x10 on isa0
sio0: type 16550A
sio1 at port 0x2f8-0x2ff irq 3 on isa0
sio1: type 16550A
ppc0: <Parallel port> at port 0x278-0x27f irq 5 on isa0
ppc0: SMC-like chipset (ECP/EPP/PS2/NIBBLE) in COMPATIBLE mode
ppc0: FIFO with 16/16/16 bytes threshold
ppi0: <Parallel I/O> on ppbus0
ppi0: can't allocate irq
device_probe_and_attach: ppi0 attach returned 12
lpt0: <Printer> on ppbus0
lpt0: Interrupt-driven port
plip0: <PLIP network interface> on ppbus0
pcm0: <AD1816> at port 0x220-0x22f,0x388-0x38b,0x100-0x10f irq 7 drq 1,0 on isa0
unknown0: <Analog Devices AD1815> at port 0x330-0x331 irq 9 on isa0
unknown1: <Analog Devices AD1815> at port 0x200-0x207 on isa0
ad0: 14664MB <IBM-DJNA-351520> [29795/16/63] at ata0-master using WDMA2
Waiting 5 seconds for SCSI devices to settle
sa0 at ncr0 bus 0 target 4 lun 0
sa0: <HP HP35470A T603> Removable Sequential Access SCSI-2 device 
sa0: 5.000MB/s transfers (5.000MHz, offset 8)
Mounting root from ufs:/dev/ad0s1a
cd0 at ncr0 bus 0 target 2 lun 0
cd0: <SONY CD-ROM CDU-8002 1.8g> Removable CD-ROM SCSI-CCS device 
cd0: 3.300MB/s transfers
cd0: Attempt to query device size failed: NOT READY, Vendor Specific ASC
IP packet filtering initialized, divert disabled, rule-based forwarding disabled, default to deny, logging disabled
>>>> snap >>>>

It would be nice if someone commited this fix/workaround (or a better one) 
to -CURRENT and -STABLE. Thanks!

Yours,
	Martin


To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-bugs" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200004271832.UAA26106>