From 84d8f1b027f552bd5a9daafdf72c0d115f4f92f9 Mon Sep 17 00:00:00 2001 From: Yaroslav Tykhiy Date: Thu, 9 Feb 2006 09:10:54 +0000 Subject: [PATCH] Avoid calling CPUID function 0x02 if the CPU reports no support for it. The former code used to hang older Intel CPUs by trying to get non-existent TLB info 2^32 times. Reduce code duplication around the calls to CPUID 0x02 by using do-while loops. PR: i386/92977 Tested by: cy --- sys/i386/i386/identcpu.c | 69 +++++++++++++--------------------------- 1 file changed, 22 insertions(+), 47 deletions(-) diff --git a/sys/i386/i386/identcpu.c b/sys/i386/i386/identcpu.c index 8c896b8e6c7e..462e6260849b 100644 --- a/sys/i386/i386/identcpu.c +++ b/sys/i386/i386/identcpu.c @@ -1235,34 +1235,23 @@ print_INTEL_info(void) u_int rounds, regnum; u_int nwaycode, nway; - do_cpuid(0x2, regs); + if (cpu_high >= 2) { + rounds = 0; + do { + do_cpuid(0x2, regs); + if (rounds == 0 && (rounds = (regs[0] & 0xff)) == 0) + break; /* we have a buggy CPU */ - rounds = (regs[0] & 0xff) - 1; - - for (regnum = 0; regnum <= 3; ++regnum) { - if ((regs[regnum] & (1<<31)) == 0) { - if (regnum != 0) - print_INTEL_TLB(regs[regnum] & 0xff); - print_INTEL_TLB((regs[regnum] >> 8) & 0xff); - print_INTEL_TLB((regs[regnum] >> 16) & 0xff); - print_INTEL_TLB((regs[regnum] >> 24) & 0xff); - } - } - - while (rounds > 0) { - do_cpuid(0x2, regs); - - for (regnum = 0; regnum <= 3; ++regnum) { - if ((regs[regnum] & (1<<31)) == 0) { + for (regnum = 0; regnum <= 3; ++regnum) { + if (regs[regnum] & (1<<31)) + continue; if (regnum != 0) print_INTEL_TLB(regs[regnum] & 0xff); print_INTEL_TLB((regs[regnum] >> 8) & 0xff); print_INTEL_TLB((regs[regnum] >> 16) & 0xff); print_INTEL_TLB((regs[regnum] >> 24) & 0xff); } - } - - --rounds; + } while (--rounds > 0); } if (cpu_exthigh >= 0x80000006) { @@ -1451,28 +1440,16 @@ setPQL2_INTEL(int *const size, int *const ways) u_int regs[4]; u_int nwaycode; - do_cpuid(0x2, regs); - rounds = (regs[0] & 0xff) - 1; + if (cpu_high >= 2) { + rounds = 0; + do { + do_cpuid(0x2, regs); + if (rounds == 0 && (rounds = (regs[0] & 0xff)) == 0) + break; /* we have a buggy CPU */ - for (regnum = 0; regnum <= 3; ++regnum) { - if ((regs[regnum] & (1<<31)) == 0) { - if (regnum != 0) - get_INTEL_TLB(regs[regnum] & 0xff, - size, ways); - get_INTEL_TLB((regs[regnum] >> 8) & 0xff, - size, ways); - get_INTEL_TLB((regs[regnum] >> 16) & 0xff, - size, ways); - get_INTEL_TLB((regs[regnum] >> 24) & 0xff, - size, ways); - } - } - - while (rounds > 0) { - do_cpuid(0x2, regs); - - for (regnum = 0; regnum <= 3; ++regnum) { - if ((regs[regnum] & (1<<31)) == 0) { + for (regnum = 0; regnum <= 3; ++regnum) { + if (regs[regnum] & (1<<31)) + continue; if (regnum != 0) get_INTEL_TLB(regs[regnum] & 0xff, size, ways); @@ -1482,11 +1459,9 @@ setPQL2_INTEL(int *const size, int *const ways) size, ways); get_INTEL_TLB((regs[regnum] >> 24) & 0xff, size, ways); - } - } - - --rounds; - } + } + } while (--rounds > 0); + } if (cpu_exthigh >= 0x80000006) { do_cpuid(0x80000006, regs);