Serious mapping problem with 2.9

ps at uok.UUCP ps at uok.UUCP
Wed Oct 24 09:41:00 AEST 1984


Subject: panic: trap type 11
Index:	/usr/include/sys/seg.h 2.9bsd

Description:
	The system crashes with a 'panic: trap type 11'.  This is
	quite possible on a system compiled with NOKA5 undefined
	and data extending up into the fifth segment. (> 40K data+bss)
	The machine may also just stop without saying very much (anything?)
	if you get two segmentation violations in a short period of time.
	In this last case, the machine will not even reboot itself because
	it is spinning in trap().

Repeat-By:
	Hard to repeat on demand.  This problem seems to be timing
	dependant.  A possible scenario is:

		buffer gets mapped in:
			*KDSD5 = (BSIZE << 2) | RW
			*KDSA5 = click address in buffer pool
			... (copying buffer)
		clock interrupts: 
			map[0].se_addr = *KDSA5;
			map[0].se_desc = *KDSD5;
			*KDSD5 = seg5.se_desc;
			*KDSA5 = seg5.se_addr;
			... (handle 1 second clock processing)
			...	((++lbolt >= hz) && BASEPRI(ps)) is true
			...	drop the priority to spl1().
			... finish processing, start the restormap stuff
			*KDSD5 = map[0].se_desc;
		disk interrupts:
			calls wakeup to notify process of completion of I/O
			no Savemap() done because *KDSA5 == seg5.se_addr
			and KDSD5 is not checked.
				(notice, KDSD5 wrong, KDSA5 correct)
			wakeup tries to reference something beyond the size
			of a buffer in the fifth segment,
				segmentation violation!

Fix:
	The solution appears to be to change the savemap() macro
	in /usr/include/sys/seg.h.  Both the address and descriptor
	registers need to be checked when deciding whether to call
	Savemap().

	It was:
	#define	savemap(map)	{if (*KDSA5 != seg5.se_addr) Savemap(map); \
			 	else map[0].se_desc = NOMAP; }

	It should be changed to:
	#define	savemap(map) \
		{\
		if (*KDSA5 != seg5.se_addr || *KDSD5 != seg5.se_desc)\
			Savemap(map);\
		else\
			map[0].se_desc = NOMAP;\
		}

	There is also a small problem in sys/machdep.c in the Restormap()
	routine.  The code to restore the values of KDS?5 is done in the
	wrong order and should be reversed.

	It was:
		*KDSA5 = map[0].se_addr;
		*KDSD5 = map[0].se_desc;

	It should be:
		*KDSD5 = map[0].se_desc;
		*KDSA5 = map[0].se_addr;


	We have been running on a kernel with these changes for about two
	weeks with no apparent problems.  Prior to making these changes,
	we would crash at random times, varying from about 5 minutes to 48
	hours.



More information about the Comp.bugs.2bsd mailing list