Blame SOURCES/glibc-rh692177.patch

b40826
2011-03-22  Ulrich Drepper  <drepper@gmail.com>
b40826
b40826
	* sysdeps/unix/sysv/linux/i386/sysconf.c (intel_check_word): Increment
b40826
	round counter.
b40826
	* sysdeps/x86_64/cacheinfo.c (intel_check_word): Likewise.
b40826
b40826
2011-03-20  Ulrich Drepper  <drepper@gmail.com>
b40826
b40826
	[BZ #12587]
b40826
	* sysdeps/unix/sysv/linux/i386/sysconf.c (intel_check_word):
b40826
	Handle cache information in CPU leaf 4.
b40826
	* sysdeps/x86_64/cacheinfo.c (intel_check_word): Likewise.
b40826
b40826
Index: glibc-2.12-2-gc4ccff1/sysdeps/unix/sysv/linux/i386/sysconf.c
b40826
===================================================================
b40826
--- glibc-2.12-2-gc4ccff1.orig/sysdeps/unix/sysv/linux/i386/sysconf.c
b40826
+++ glibc-2.12-2-gc4ccff1/sysdeps/unix/sysv/linux/i386/sysconf.c
b40826
@@ -186,6 +186,57 @@ intel_check_word (int name, unsigned int
b40826
 	    /* No need to look further.  */
b40826
 	    break;
b40826
 	}
b40826
+      else if (byte == 0xff)
b40826
+	{
b40826
+	  /* CPUID leaf 0x4 contains all the information.  We need to
b40826
+	     iterate over it.  */
b40826
+	  unsigned int eax;
b40826
+	  unsigned int ebx;
b40826
+	  unsigned int ecx;
b40826
+	  unsigned int edx;
b40826
+
b40826
+	  unsigned int round = 0;
b40826
+	  while (1)
b40826
+	    {
b40826
+	      asm volatile ("xchgl %%ebx, %1; cpuid; xchgl %%ebx, %1"
b40826
+			    : "=a" (eax), "=r" (ebx), "=c" (ecx), "=d" (edx)
b40826
+			    : "0" (4), "2" (round));
b40826
+
b40826
+	      enum { null = 0, data = 1, inst = 2, uni = 3 } type = eax & 0x1f;
b40826
+	      if (type == null)
b40826
+		/* That was the end.  */
b40826
+		break;
b40826
+
b40826
+	      unsigned int level = (eax >> 5) & 0x7;
b40826
+
b40826
+	      if ((level == 1 && type == data
b40826
+		   && folded_rel_name == M(_SC_LEVEL1_DCACHE_SIZE))
b40826
+		  || (level == 1 && type == inst
b40826
+		      && folded_rel_name == M(_SC_LEVEL1_ICACHE_SIZE))
b40826
+		  || (level == 2 && folded_rel_name == M(_SC_LEVEL2_CACHE_SIZE))
b40826
+		  || (level == 3 && folded_rel_name == M(_SC_LEVEL3_CACHE_SIZE))
b40826
+		  || (level == 4 && folded_rel_name == M(_SC_LEVEL4_CACHE_SIZE)))
b40826
+		{
b40826
+		  unsigned int offset = M(name) - folded_rel_name;
b40826
+
b40826
+		  if (offset == 0)
b40826
+		    /* Cache size.  */
b40826
+		    return (((ebx >> 22) + 1)
b40826
+			    * (((ebx >> 12) & 0x3ff) + 1)
b40826
+			    * ((ebx & 0xfff) + 1)
b40826
+			    * (ecx + 1));
b40826
+		  if (offset == 1)
b40826
+		    return (ebx >> 22) + 1;
b40826
+
b40826
+		  assert (offset == 2);
b40826
+		  return (ebx & 0xfff) + 1;
b40826
+		}
b40826
+
b40826
+	      ++round;
b40826
+	    }
b40826
+	  /* There is no other cache information anywhere else.  */
b40826
+	  break;
b40826
+	}
b40826
       else
b40826
 	{
b40826
 	  if (byte == 0x49 && folded_rel_name == M(_SC_LEVEL3_CACHE_SIZE))
b40826
Index: glibc-2.12-2-gc4ccff1/sysdeps/x86_64/cacheinfo.c
b40826
===================================================================
b40826
--- glibc-2.12-2-gc4ccff1.orig/sysdeps/x86_64/cacheinfo.c
b40826
+++ glibc-2.12-2-gc4ccff1/sysdeps/x86_64/cacheinfo.c
b40826
@@ -181,6 +181,57 @@ intel_check_word (int name, unsigned int
b40826
 	    /* No need to look further.  */
b40826
 	    break;
b40826
 	}
b40826
+      else if (byte == 0xff)
b40826
+	{
b40826
+	  /* CPUID leaf 0x4 contains all the information.  We need to
b40826
+	     iterate over it.  */
b40826
+	  unsigned int eax;
b40826
+	  unsigned int ebx;
b40826
+	  unsigned int ecx;
b40826
+	  unsigned int edx;
b40826
+
b40826
+	  unsigned int round = 0;
b40826
+	  while (1)
b40826
+	    {
b40826
+	      asm volatile ("xchgl %%ebx, %1; cpuid; xchgl %%ebx, %1"
b40826
+			    : "=a" (eax), "=r" (ebx), "=c" (ecx), "=d" (edx)
b40826
+			    : "0" (4), "2" (round));
b40826
+
b40826
+	      enum { null = 0, data = 1, inst = 2, uni = 3 } type = eax & 0x1f;
b40826
+	      if (type == null)
b40826
+		/* That was the end.  */
b40826
+		break;
b40826
+
b40826
+	      unsigned int level = (eax >> 5) & 0x7;
b40826
+
b40826
+	      if ((level == 1 && type == data
b40826
+		   && folded_rel_name == M(_SC_LEVEL1_DCACHE_SIZE))
b40826
+		  || (level == 1 && type == inst
b40826
+		      && folded_rel_name == M(_SC_LEVEL1_ICACHE_SIZE))
b40826
+		  || (level == 2 && folded_rel_name == M(_SC_LEVEL2_CACHE_SIZE))
b40826
+		  || (level == 3 && folded_rel_name == M(_SC_LEVEL3_CACHE_SIZE))
b40826
+		  || (level == 4 && folded_rel_name == M(_SC_LEVEL4_CACHE_SIZE)))
b40826
+		{
b40826
+		  unsigned int offset = M(name) - folded_rel_name;
b40826
+
b40826
+		  if (offset == 0)
b40826
+		    /* Cache size.  */
b40826
+		    return (((ebx >> 22) + 1)
b40826
+			    * (((ebx >> 12) & 0x3ff) + 1)
b40826
+			    * ((ebx & 0xfff) + 1)
b40826
+			    * (ecx + 1));
b40826
+		  if (offset == 1)
b40826
+		    return (ebx >> 22) + 1;
b40826
+
b40826
+		  assert (offset == 2);
b40826
+		  return (ebx & 0xfff) + 1;
b40826
+		}
b40826
+
b40826
+	      ++round;
b40826
+	    }
b40826
+	  /* There is no other cache information anywhere else.  */
b40826
+	  break;
b40826
+	}
b40826
       else
b40826
 	{
b40826
 	  if (byte == 0x49 && folded_rel_name == M(_SC_LEVEL3_CACHE_SIZE))