NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

port-i386/49741: Unconditional use of cpuid instruction causes illegal instruction trap

>Number:         49741
>Category:       port-i386
>Synopsis:       Unconditional use of cpuid instruction causes illegal instruction trap
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    port-i386-maintainer
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Tue Mar 10 16:55:00 +0000 2015
>Originator:     Jarle Greipsland
>Release:        NetBSD 6.1_STABLE
System: NetBSD 7.99.4 NetBSD 7.99.4 (DARLING) #3: Wed Feb 25 16:05:46 CET 2015 i386
Architecture: i386
Machine: i386

Install -current on an old i486 system.  Note that all dynamically linked
programs faults with an illegal instruction trap in, a dynamic
library with support functions for all dynamically linked programs compiled
by the system's gcc compiler.

The code in the __cpu_indicator_init in
src/external/gpl3/gcc/dist/libgcc/config/i386/cpuinfo.c calls the
__get_cpuid_output function with parameters that makes it always issue the
cpuid instruction.  This instruction is not implemented on the old i486
CPUs, and thus the program executing receives a SIGILL signal (and dies).

Install NetBSD/i386 -current on an old system with a real 486 CPU.


I have run my system for more than a week with the patch below applied, and
observed no ill effects.  Someone with more knowledge about Intel
processors and gcc's run time requirements should double check that the
patch makes sense, in particular on more modern CPUs.

Index: external/gpl3/gcc/dist/libgcc/config/i386/cpuinfo.c
RCS file: /cvsroot/src/external/gpl3/gcc/dist/libgcc/config/i386/cpuinfo.c,v
retrieving revision
diff -u -u -r1.1.1.1 cpuinfo.c
--- external/gpl3/gcc/dist/libgcc/config/i386/cpuinfo.c 1 Mar 2014 08:41:47 -0000
+++ external/gpl3/gcc/dist/libgcc/config/i386/cpuinfo.c 10 Mar 2015 16:51:55 -0000
@@ -281,8 +281,7 @@
   if (__cpu_model.__cpu_vendor)
     return 0;
-  /* Assume cpuid insn present. Run in level 0 to get vendor id. */
-  if (!__get_cpuid_output (0, &eax, &ebx, &ecx, &edx))
+  if (!__get_cpuid_output (1, &eax, &ebx, &ecx, &edx))
       __cpu_model.__cpu_vendor = VENDOR_OTHER;
       return -1;


Home | Main Index | Thread Index | Old Index