Subject: Re: port-alpha/36628: cdhdtape image panics with memory management
To: None <tsutsui@NetBSD.org, gnats-admin@netbsd.org,>
From: Izumi Tsutsui <tsutsui@ceres.dti.ne.jp>
List: netbsd-bugs
Date: 07/17/2007 10:15:06
The following reply was made to PR port-alpha/36628; it has been noted by GNATS.

From: Izumi Tsutsui <tsutsui@ceres.dti.ne.jp>
To: ChristophFranzen@gmx.net
Cc: gnats-bugs@NetBSD.org, port-alpha-maintainer@NetBSD.org,
	tsutsui@ceres.dti.ne.jp
Subject: Re: port-alpha/36628: cdhdtape image panics with memory management
	 trap on Jensen
Date: Tue, 17 Jul 2007 19:10:56 +0900

 ChristophFranzen@gmx.net wrote:
 
 > >  Could you try this one?
 > >  http://www.ceres.dti.ne.jp/~tsutsui/netbsd/cdhdtape-20070716.gz
 > 
 > Thank you, but there is still something broken. Now it says "eisa irq 
 > 1" instead of "bad vector 0x1" while the other items all look like 
 > "interupting at vector 0x###":
 
 "eisa irq 1" is okay according to this (old but working) dmesg:
 http://mail-index.netbsd.org/port-alpha/2000/07/12/0002.html
 
 > com1: interrupting at vector 0x920
 > lpt0 at jensenio0 port 0x3bc
 > lpt0: interrupting at eisa irq 1
 > mcclock0 at jensenio0 port 0x170: mc146818 or compatible
 > eisa0 at jensenio0
 > 
 > CPU 0: fatal kernel trap:
 > 
 > CPU 0    trap entry = 0x2 (memory management fault)
 > CPU 0    a0         = 0xfffffe0000058000
 > CPU 0    a1         = 0x1
 > CPU 0    a2         = 0x0
 > CPU 0    pc         = 0xfffffc000058fa10
 > CPU 0    ra         = 0xfffffc000058ffa8
 
 This is another failure in alpha/eisa/eisa_machdep.c:eisa_read_config_bytes()
 called from eisa_init() and there was the similar report:
 http://mail-index.netbsd.org/port-alpha/2000/12/07/0009.html
 
 I'm not sure how such NULL pointer deference could happen,
 but could you try this debug kernel?
 
 http://www.ceres.dti.ne.jp/~tsutsui/netbsd/cdhdtape-20070717.gz
 
 
 Index: eisa/eisa_machdep.c
 ===================================================================
 RCS file: /cvsroot/src/sys/arch/alpha/eisa/eisa_machdep.c,v
 retrieving revision 1.5
 diff -u -r1.5 eisa_machdep.c
 --- eisa/eisa_machdep.c	1 Jun 2002 23:50:53 -0000	1.5
 +++ eisa/eisa_machdep.c	17 Jul 2007 10:02:05 -0000
 @@ -162,7 +162,7 @@
  	int i;
  
  	for (i = 0; i < ECUF_MEM_ENTRY_CNT; i++) {
 -		ecum = malloc(sizeof(*ecum), M_DEVBUF, M_WAITOK);
 +		ecum = malloc(sizeof(*ecum), M_DEVBUF, M_ZERO|M_WAITOK);
  
  		ecum->ecum_mem.ecm_isram = dp[0] & 0x1;
  		ecum->ecum_mem.ecm_unitsize = dp[1] & 0x3;
 @@ -174,7 +174,7 @@
  			ecum->ecum_mem.ecm_size = (1 << 26);
  		SIMPLEQ_INSERT_TAIL(&ecuf->ecuf_mem, ecum, ecum_list);
  
 -#if 0
 +#ifdef EISA_DEBUG
  		printf("MEM 0x%lx 0x%lx %d %d %d\n",
  		    ecum->ecum_mem.ecm_addr, ecum->ecum_mem.ecm_size,
  		    ecum->ecum_mem.ecm_isram, ecum->ecum_mem.ecm_unitsize,
 @@ -194,17 +194,17 @@
  	int i;
  
  	for (i = 0; i < ECUF_IRQ_ENTRY_CNT; i++) {
 -		ecui = malloc(sizeof(*ecui), M_DEVBUF, M_WAITOK);
 +		ecui = malloc(sizeof(*ecui), M_DEVBUF, M_ZERO|M_WAITOK);
  
  		ecui->ecui_irq.eci_irq = dp[0] & 0xf;
  		ecui->ecui_irq.eci_ist = (dp[0] & 0x20) ? IST_LEVEL : IST_EDGE;
  		ecui->ecui_irq.eci_shared = (dp[0] & 0x40) ? 1 : 0;
  		SIMPLEQ_INSERT_TAIL(&ecuf->ecuf_irq, ecui, ecui_list);
  
 -#if 0
 -		printf("IRQ %d %s%s\n", ecui->eci_irq.ecui_irq,
 -		    ecui->eci_irq.ecui_ist == IST_LEVEL ? "level" : "edge",
 -		    ecui->eci_irq.ecui_shared ? " shared" : "");
 +#ifdef EISA_DEBUG
 +		printf("IRQ %d %s%s\n", ecui->ecui_irq.eci_irq,
 +		    ecui->ecui_irq.eci_ist == IST_LEVEL ? "level" : "edge",
 +		    ecui->ecui_irq.eci_shared ? " shared" : "");
  #endif
  
  		if ((dp[0] & 0x80) == 0)
 @@ -220,7 +220,7 @@
  	int i;
  
  	for (i = 0; i < ECUF_DMA_ENTRY_CNT; i++) {
 -		ecud = malloc(sizeof(*ecud), M_DEVBUF, M_WAITOK);
 +		ecud = malloc(sizeof(*ecud), M_DEVBUF, M_ZERO|M_WAITOK);
  
  		ecud->ecud_dma.ecd_drq = dp[0] & 0x7;
  		ecud->ecud_dma.ecd_shared = dp[0] & 0x40;
 @@ -228,7 +228,7 @@
  		ecud->ecud_dma.ecd_timing = (dp[1] >> 4) & 0x3;
  		SIMPLEQ_INSERT_TAIL(&ecuf->ecuf_dma, ecud, ecud_list);
  
 -#if 0
 +#ifdef EISA_DEBUG
  		printf("DRQ %d%s %d %d\n", ecud->ecud_dma.ecd_drq,
  		    ecud->ecud_dma.ecd_shared ? " shared" : "",
  		    ecud->ecud_dma.ecd_size, ecud->ecud_dma.ecd_timing);
 @@ -247,13 +247,13 @@
  	int i;
  
  	for (i = 0; i < ECUF_IO_ENTRY_CNT; i++) {
 -		ecuio = malloc(sizeof(*ecuio), M_DEVBUF, M_WAITOK);
 +		ecuio = malloc(sizeof(*ecuio), M_DEVBUF, M_ZERO|M_WAITOK);
  
  		ecuio->ecuio_io.ecio_addr = dp[1] | (dp[2] << 8);
  		ecuio->ecuio_io.ecio_size = (dp[0] & 0x1f) + 1;
  		ecuio->ecuio_io.ecio_shared = (dp[0] & 0x40) ? 1 : 0;
  
 -#if 0
 +#ifdef EISA_DEBUG
  		printf("IO 0x%lx 0x%lx%s\n", ecuio->ecuio_io.ecio_addr,
  		    ecuio->ecuio_io.ecio_size,
  		    ecuio->ecuio_io.ecio_shared ? " shared" : "");
 @@ -340,11 +340,15 @@
  	}
  
  	eisa_config_header_addr = hwrpb->rpb_condat_off;
 -#if 0
 +#ifdef EISA_DEBUG
  	printf("\nEISA config header at 0x%lx\n", eisa_config_header_addr);
  #endif
  	if (eisa_config_stride == 0)
  		eisa_config_stride = 1;
 +#ifdef EISA_DEBUG
 +	printf("EISA config at 0x%lx\n", eisa_config_addr);
 +	printf("EISA config stride: %ld\n", eisa_config_stride);
 +#endif
  
  	/*
  	 * Read the slot headers, and allocate config structures for
 @@ -358,12 +362,14 @@
  		cfgaddr += sizeof(offset) * eisa_config_stride;
  
  		if (offset != 0) {
 -#if 0
 +#ifdef EISA_DEBUG
  			printf("SLOT %d: offset 0x%08x eisaid %s\n",
  			    i, offset, eisaid);
  #endif
 -			ecud = malloc(sizeof(*ecud), M_DEVBUF, M_WAITOK);
 -			memset(ecud, 0, sizeof(*ecud));
 +			ecud = malloc(sizeof(*ecud), M_DEVBUF, M_ZERO|M_WAITOK);
 +			if (ecud == NULL)
 +				panic("%s: can't allocate memory for ecud",
 +				    __func__);
  
  			SIMPLEQ_INIT(&ecud->ecud_funcs);
  
 @@ -378,22 +384,33 @@
  	 * Now traverse the valid slots and read the info.
  	 */
  
 -	cdata = malloc(512, M_TEMP, M_WAITOK);
 -	data = malloc(512, M_TEMP, M_WAITOK);
 +	cdata = malloc(512, M_TEMP, M_ZERO|M_WAITOK);
 +	if (cdata == NULL)
 +		panic("%s: can't allocate memory for cdata", __func__);
 +	data = malloc(512, M_TEMP, M_ZERO|M_WAITOK);
 +	if (data == NULL)
 +		panic("%s: can't allocate memory for data", __func__);
  
  	SIMPLEQ_FOREACH(ecud, &ecu_data_list, ecud_list) {
  		cfgaddr = eisa_config_addr + ecud->ecud_offset;
 +#ifdef EISA_DEBUG
 +		printf("Reading config bytes to cdata[0] at 0x%lx\n", cfgaddr);
 +#endif
  		eisa_read_config_bytes(cfgaddr, &cdata[0], 1);
  		cfgaddr += eisa_config_stride;
  
  		for (i = 1; ; cfgaddr += eisa_config_stride, i++) {
 +#ifdef EISA_DEBUG
 +			printf("Reading config bytes to cdata[%d] at 0x%lx\n",
 +			    i, cfgaddr);
 +#endif
  			eisa_read_config_bytes(cfgaddr, &cdata[i], 1);
  			if (cdata[i - 1] == 0 && cdata[i] == 0)
  				break;
  		}
  		i++;	/* index -> length */
  
 -#if 0
 +#ifdef EISA_DEBUG
  		printf("SLOT %d compressed data length %d:",
  		    ecud->ecud_slot, i);
  		{
 @@ -413,7 +430,7 @@
  
  		/* Uncompress the slot header. */
  		cdp += eisa_uncompress(cdp, dp, EISA_SLOT_HEADER_SIZE);
 -#if 0
 +#ifdef EISA_DEBUG
  		printf("SLOT %d uncompressed header data:",
  		    ecud->ecud_slot);
  		{
 @@ -439,7 +456,7 @@
  		memcpy(&ecud->ecud_comp_id, dp, sizeof(ecud->ecud_comp_id));
  		dp += sizeof(ecud->ecud_comp_id);
  
 -#if 0
 +#ifdef EISA_DEBUG
  		printf("SLOT %d: ndevfuncs %d\n", ecud->ecud_slot,
  		    ecud->ecud_ndevfuncs);
  #endif
 @@ -447,7 +464,7 @@
  		for (func = 0; func < ecud->ecud_ndevfuncs; func++) {
  			dp = data;
  			cdp += eisa_uncompress(cdp, dp, EISA_CONFIG_BLOCK_SIZE);
 -#if 0
 +#ifdef EISA_DEBUG
  			printf("SLOT %d:%d uncompressed data:",
  			    ecud->ecud_slot, func);
  			{
 @@ -464,7 +481,7 @@
  
  			/* Skip disabled functions. */
  			if (dp[EISA_FUNC_INFO_OFFSET] & ECUF_DISABLED) {
 -#if 0
 +#ifdef EISA_DEBUG
  				printf("SLOT %d:%d disabled\n",
  				    ecud->ecud_slot, func);
  #endif
 
 
 ---
 Izumi Tsutsui