+First, relevent system config:
+Asus P55T2P4 Rev. 3.10.
+AMD K6/233 running at 233mhz (3.5x66)
+96MB LGS non-parity EDO DRAM
+Asus heatsink/fan on processor
+Extra fan blowing on voltage regulators
+The problem:
+Kernel compiles segfault around one of every 5-10 times
+(well, sig11, sig4, sig6...)
+The solution:
+compile your kernel for a 386. my theory is that the problem is
+pentium 4MB pages, but i'm still testing.
Ha! Computers will never seize to amaze me (if this indeed solves
the K6 problem). Did it make it through the burnit script?
As I said the problem with my K5lite and gcc is related to the invlpg
instruction. I traced the offending code in mm/memory.c. Changing
exactly one flush_tlb_page() call to flush_tlb() is sufficient to get
rid it of the gcc headache. It might be worthwhile to give it a try
on the K6.
Someone pointed out to me there is no reason for the K6 to have
similar problems as the K5 since the latter was developed by a
completely different team (NexGen). Cross-species jump, creepy...
Are bugs alive or what?
Anyway, the truth is that most commercial code out there is compiled
to run on 386's. This is certainly true for the "mainstream" operating
systems. As a result, it is not surprising that a processor can be
"certified" compatible (e.g., by XXCAL) even with bugs lurking in the
background. Hell, even the Linux distributions out there are all compiled
for 386's.
The following piece of code is from the 2.0.30 kernel source tree,
but it hasn't changed all the way to 2.1.51 (in case you are using
the development kernels). A more general solution is to always
invalidate the tlb by defining the flush_tlb_one() macro in
include/asm-i386/pgtbl.h to flush_tlb() (as it is for the 386's).
It may be possible that invlpg is totally broken but the error is
never encountered because of TLB replacements when going through
all the other paths.
pipa# diff -c memory.c memory.c.original
*** memory.c Wed Aug 20 22:13:50 1997
--- memory.c.original Wed Aug 20 22:00:14 1997
***************
*** 638,645 ****
flush_cache_page(vma, address);
set_pte(page_table, pte_mkwrite(pte_mkdirty(mk_pte(new_page, vma->vm_page_prot))));
free_page(old_page);
! if (vma->vm_mm == current->mm)
! flush_tlb();
return;
}
flush_cache_page(vma, address);
--- 638,644 ----
flush_cache_page(vma, address);
set_pte(page_table, pte_mkwrite(pte_mkdirty(mk_pte(new_page, vma->vm_page_prot))));
free_page(old_page);
! flush_tlb_page(vma, address);
return;
}
flush_cache_page(vma, address);