Subject: port-i386/13399: Bugs in post-1.5 memory probe
To: None <gnats-bugs@gnats.netbsd.org>
From: None <entropy@tappedin.com>
List: netbsd-bugs
Date: 07/07/2001 00:25:03
>Number: 13399
>Category: port-i386
>Synopsis: Bugs in post-1.5 memory probe
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: port-i386-maintainer
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Fri Jul 06 21:23:01 PDT 2001
>Closed-Date:
>Last-Modified:
>Originator:
>Release: <NetBSD-current source date>20010706
>Organization:
entropy -- it's not just a good idea, it's the second law.
>Environment:
System: NetBSD tardis.local 1.5W NetBSD 1.5W (TARDIS) #8: Sat Jul 7 00:04:13 EDT 2001 entropy@zippy.local:/usr/src/sys/arch/i386/compile/TARDIS i386
Architecture: i386
Machine: i386
>Description:
When booting post-1.5 kernels on an old machine, I got crashes immediately
after startup. The following warnings were printed:
>How-To-Repeat:
Try to boot -current on a DECpc XL 590.
>Fix:
The following patch fixes several bugs in the post-1.5 BIOS memory probes.
- If the BIOS reports the same memory cluster multiple times, only allocate
the extent once.
- If we fail to allocate an extent, don't add it to mem_clusters and don't
increment mem_cluster_cnt.
- When loading the physical extents, make sure we don't try to add an
extent with zero length (seg_start == tmp)
Index: machdep.c
===================================================================
RCS file: /cvsroot/syssrc/sys/arch/i386/i386/machdep.c,v
retrieving revision 1.446
diff -u -u -r1.446 machdep.c
--- machdep.c 2001/06/19 15:54:48 1.446
+++ machdep.c 2001/07/07 04:03:48
@@ -2144,6 +2144,7 @@
u_int32_t type;
{
extern struct extent *iomem_ex;
+ int i;
if (seg_end > 0x100000000ULL) {
printf("WARNING: skipping large "
@@ -2165,6 +2166,17 @@
if (seg_end <= seg_start)
return;
+ for (i = 0; i < mem_cluster_cnt; i++) {
+ if ((mem_clusters[i].start == round_page(seg_start))
+ && (mem_clusters[i].size
+ == trunc_page(seg_end) - mem_clusters[i].start)) {
+#ifdef DEBUG_MEMLOAD
+ printf("WARNING: skipping duplicate segment entry\n");
+#endif
+ return;
+ }
+ }
+
/*
* Allocate the physical addresses used by RAM
* from the iomem extent map. This is done before
@@ -2179,6 +2191,7 @@
"(0x%qx/0x%qx/0x%x) FROM "
"IOMEM EXTENT MAP!\n",
seg_start, seg_end - seg_start, type);
+ return;
}
/*
@@ -2331,6 +2344,10 @@
}
#endif /* ! REALBASEMEM && ! REALEXTMEM */
+#ifdef DEBUG_MEMLOAD
+ printf("mem_cluster_count: %d\n", mem_cluster_cnt);
+#endif
+
/*
* If the loop above didn't find any valid segment, fall back to
* former code.
@@ -2449,14 +2466,17 @@
tmp = (16 * 1024 * 1024);
else
tmp = seg_end;
+
+ if (tmp != seg_start) {
#if DEBUG_MEMLOAD
- printf("loading 0x%qx-0x%qx (0x%lx-0x%lx)\n",
+ printf("loading 0x%qx-0x%qx (0x%lx-0x%lx)\n",
seg_start, tmp,
atop(seg_start), atop(tmp));
#endif
- uvm_page_physload(atop(seg_start),
+ uvm_page_physload(atop(seg_start),
atop(tmp), atop(seg_start),
atop(tmp), first16q);
+ }
seg_start = tmp;
}
@@ -2482,14 +2502,16 @@
tmp = (16 * 1024 * 1024);
else
tmp = seg_end1;
+ if (tmp != seg_start1) {
#if DEBUG_MEMLOAD
- printf("loading 0x%qx-0x%qx (0x%lx-0x%lx)\n",
+ printf("loading 0x%qx-0x%qx (0x%lx-0x%lx)\n",
seg_start1, tmp,
atop(seg_start1), atop(tmp));
#endif
- uvm_page_physload(atop(seg_start1),
+ uvm_page_physload(atop(seg_start1),
atop(tmp), atop(seg_start1),
atop(tmp), first16q);
+ }
seg_start1 = tmp;
}
>Release-Note:
>Audit-Trail:
>Unformatted:
>> NetBSD/i386 BIOS Boot, Revision 2.10
>> (entropy@zippy.local, Thu Jul 5 05:13:48 EDT 2001)
>> Memory: 635/48128 k
Press return to boot now, any other key for boot menu
booting fd0a:netbsd - starting in 0
type "?" or "help" for help.
> boot hd0a:netbsd -s
booting hd0a:netbsd (howto 0x2)
4532951+83004+324460 [65+263168+216671]=0x52c6f0
WARNING: CAN'T ALLOCATE MEMORY SEGMENT (0x100000/0xf00000/0x1) FROM IOMEM EXTENT MAP!
WARNING: CAN'T ALLOCATE MEMORY SEGMENT (0x1000000/0x2000000/0x1) FROM IOMEM EXTENT MAP!
(At this point the system resets immediately).
The machine is a DECpc XL 590 with 48M memory.