r4593 - in glibc-package/branches/eglibc-2.13/debian: . patches patches/i386
Author: aurel32
Date: 2011-03-26 18:50:00 +0000 (Sat, 26 Mar 2011)
New Revision: 4593
Added:
glibc-package/branches/eglibc-2.13/debian/patches/i386/cvs-cacheinfo.diff
Modified:
glibc-package/branches/eglibc-2.13/debian/changelog
glibc-package/branches/eglibc-2.13/debian/patches/series
Log:
* Add patches/i386/cvs-cacheinfo.diff to fix empty LEVEL*CACHE* getconf()
entries for some CPU. Closes: #609389.
Modified: glibc-package/branches/eglibc-2.13/debian/changelog
===================================================================
--- glibc-package/branches/eglibc-2.13/debian/changelog 2011-03-26 18:44:34 UTC (rev 4592)
+++ glibc-package/branches/eglibc-2.13/debian/changelog 2011-03-26 18:50:00 UTC (rev 4593)
@@ -141,6 +141,8 @@
* Add patches/alpha/submitted-____longjmp_chk.diff to fix longjmp() with
FORTIFY on alpha.
* Add patches/alpha/submitted-PTR_MANGLE.diff to fix exceptions on alpha.
+ * Add patches/i386/cvs-cacheinfo.diff to fix empty LEVEL*CACHE* getconf()
+ entries for some CPU. Closes: #609389.
[ Samuel Thibault ]
* Add patches/any/cvs-glro_dl_debug_mask.diff to fix build without
Added: glibc-package/branches/eglibc-2.13/debian/patches/i386/cvs-cacheinfo.diff
===================================================================
--- glibc-package/branches/eglibc-2.13/debian/patches/i386/cvs-cacheinfo.diff (rev 0)
+++ glibc-package/branches/eglibc-2.13/debian/patches/i386/cvs-cacheinfo.diff 2011-03-26 18:50:00 UTC (rev 4593)
@@ -0,0 +1,137 @@
+2011-03-22 Ulrich Drepper <drepper@gmail.com>
+
+ * sysdeps/unix/sysv/linux/i386/sysconf.c (intel_check_word): Increment
+ round counter.
+ * sysdeps/x86_64/cacheinfo.c (intel_check_word): Likewise.
+
+2011-03-20 Ulrich Drepper <drepper@gmail.com>
+
+ [BZ #12587]
+ * sysdeps/unix/sysv/linux/i386/sysconf.c (intel_check_word):
+ Handle cache information in CPU leaf 4.
+ * sysdeps/x86_64/cacheinfo.c (intel_check_word): Likewise.
+
+diff --git a/sysdeps/unix/sysv/linux/i386/sysconf.c b/sysdeps/unix/sysv/linux/i386/sysconf.c
+index ff3cf9f..1f5d3b0 100644
+--- a/sysdeps/unix/sysv/linux/i386/sysconf.c
++++ b/sysdeps/unix/sysv/linux/i386/sysconf.c
+@@ -186,6 +186,57 @@ intel_check_word (int name, unsigned int value, bool *has_level_2,
+ /* No need to look further. */
+ break;
+ }
++ else if (byte == 0xff)
++ {
++ /* CPUID leaf 0x4 contains all the information. We need to
++ iterate over it. */
++ unsigned int eax;
++ unsigned int ebx;
++ unsigned int ecx;
++ unsigned int edx;
++
++ unsigned int round = 0;
++ while (1)
++ {
++ asm volatile ("xchgl %%ebx, %1; cpuid; xchgl %%ebx, %1"
++ : "=a" (eax), "=r" (ebx), "=c" (ecx), "=d" (edx)
++ : "0" (4), "2" (round));
++
++ enum { null = 0, data = 1, inst = 2, uni = 3 } type = eax & 0x1f;
++ if (type == null)
++ /* That was the end. */
++ break;
++
++ unsigned int level = (eax >> 5) & 0x7;
++
++ if ((level == 1 && type == data
++ && folded_rel_name == M(_SC_LEVEL1_DCACHE_SIZE))
++ || (level == 1 && type == inst
++ && folded_rel_name == M(_SC_LEVEL1_ICACHE_SIZE))
++ || (level == 2 && folded_rel_name == M(_SC_LEVEL2_CACHE_SIZE))
++ || (level == 3 && folded_rel_name == M(_SC_LEVEL3_CACHE_SIZE))
++ || (level == 4 && folded_rel_name == M(_SC_LEVEL4_CACHE_SIZE)))
++ {
++ unsigned int offset = M(name) - folded_rel_name;
++
++ if (offset == 0)
++ /* Cache size. */
++ return (((ebx >> 22) + 1)
++ * (((ebx >> 12) & 0x3ff) + 1)
++ * ((ebx & 0xfff) + 1)
++ * (ecx + 1));
++ if (offset == 1)
++ return (ebx >> 22) + 1;
++
++ assert (offset == 2);
++ return (ebx & 0xfff) + 1;
++ }
++
++ ++round;
++ }
++ /* There is no other cache information anywhere else. */
++ break;
++ }
+ else
+ {
+ if (byte == 0x49 && folded_rel_name == M(_SC_LEVEL3_CACHE_SIZE))
+diff --git a/sysdeps/x86_64/cacheinfo.c b/sysdeps/x86_64/cacheinfo.c
+index 337444d..bd4be3d 100644
+--- a/sysdeps/x86_64/cacheinfo.c
++++ b/sysdeps/x86_64/cacheinfo.c
+@@ -181,6 +181,57 @@ intel_check_word (int name, unsigned int value, bool *has_level_2,
+ /* No need to look further. */
+ break;
+ }
++ else if (byte == 0xff)
++ {
++ /* CPUID leaf 0x4 contains all the information. We need to
++ iterate over it. */
++ unsigned int eax;
++ unsigned int ebx;
++ unsigned int ecx;
++ unsigned int edx;
++
++ unsigned int round = 0;
++ while (1)
++ {
++ asm volatile ("xchgl %%ebx, %1; cpuid; xchgl %%ebx, %1"
++ : "=a" (eax), "=r" (ebx), "=c" (ecx), "=d" (edx)
++ : "0" (4), "2" (round));
++
++ enum { null = 0, data = 1, inst = 2, uni = 3 } type = eax & 0x1f;
++ if (type == null)
++ /* That was the end. */
++ break;
++
++ unsigned int level = (eax >> 5) & 0x7;
++
++ if ((level == 1 && type == data
++ && folded_rel_name == M(_SC_LEVEL1_DCACHE_SIZE))
++ || (level == 1 && type == inst
++ && folded_rel_name == M(_SC_LEVEL1_ICACHE_SIZE))
++ || (level == 2 && folded_rel_name == M(_SC_LEVEL2_CACHE_SIZE))
++ || (level == 3 && folded_rel_name == M(_SC_LEVEL3_CACHE_SIZE))
++ || (level == 4 && folded_rel_name == M(_SC_LEVEL4_CACHE_SIZE)))
++ {
++ unsigned int offset = M(name) - folded_rel_name;
++
++ if (offset == 0)
++ /* Cache size. */
++ return (((ebx >> 22) + 1)
++ * (((ebx >> 12) & 0x3ff) + 1)
++ * ((ebx & 0xfff) + 1)
++ * (ecx + 1));
++ if (offset == 1)
++ return (ebx >> 22) + 1;
++
++ assert (offset == 2);
++ return (ebx & 0xfff) + 1;
++ }
++
++ ++round;
++ }
++ /* There is no other cache information anywhere else. */
++ break;
++ }
+ else
+ {
+ if (byte == 0x49 && folded_rel_name == M(_SC_LEVEL3_CACHE_SIZE))
Modified: glibc-package/branches/eglibc-2.13/debian/patches/series
===================================================================
--- glibc-package/branches/eglibc-2.13/debian/patches/series 2011-03-26 18:44:34 UTC (rev 4592)
+++ glibc-package/branches/eglibc-2.13/debian/patches/series 2011-03-26 18:50:00 UTC (rev 4593)
@@ -138,6 +138,7 @@
i386/local-linuxthreads-gscope.diff
i386/local-pthread_cond_wait.diff
i386/submitted-i686-timing.diff
+i386/cvs-cacheinfo.diff
m68k/local-compat.diff
m68k/local-dwarf2-buildfix.diff
Reply to: