# Kernel bug? /proc/cpuinfo shows pni when there is none ...

## Birtz

I have been doing some research and frankly, I am surprised that noone raised this issue before. On all Athlon64 hardware I have seen (including some auxillary /proc/cpuinfo's on the net), one could read (since cca. kernel 2.6.8 );

```
flags           : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 pni syscall nx mmxext lm 3dnowext 3dnow
```

Notice the "pni" flag. I don't know any other nomenclature for the flag other than "PrescottNewInstructions" aka SSE3. Of course, the simple test fails miserably;

```
cat << "EOF" >test_pni.c

#include <stdint.h>

uint8_t __attribute__((aligned(64))) current[64];

uint8_t previous[64];

int main()

{

   int i;

   uint64_t result;

   uint32_t ecx;

   uint8_t *ptr0 = current;

   uint8_t *ptr1 = previous;

   __asm__ __volatile__ (

         "mov $0, %%eax\n"

         "cpuid\n"

         "mov %%ecx, %0\n"

         : "=m" (ecx) : : "eax", "ebx", "ecx" );

   printf( "cpuid(1) returns %x\n", ecx );

   memset( current, 0xaa, 64 );

   memset( previous, 0x55, 64 );

   for( i = 0; i < 4; i ++ ) {

      __asm__ __volatile__ (

            "movdqa %0, %%xmm0\n"

            "movdqu %1, %%xmm1\n"

            "psadbw %%xmm1, %%xmm0\n"

            "paddw  %%xmm0, %%xmm2\n"

            "haddps %%xmm2, %%xmm2\n"

            "haddps %%xmm2, %%xmm2\n"

            : : "m" (*ptr0), 

            "m" (*ptr1) : "xmm0", "xmm1", "xmm2" );

      ptr0 += 16;

      ptr1 += 16;

   }

   __asm__ __volatile__ (

         "movq %%xmm2, %0\n"

         : "=m" (result) );

   printf( "Result is %llu\n", result );

}

EOF
```

'haddps' being SSE3 instruction;

```
gcc -o test_pni test_pni.c

./test_pni

cpuid(1) returns 444d4163

Illegal instruction

```

I have tried to post on the LKM, but I haven't got an account, could someone raise this issue upstream? Or at least prove my stupidity  :Shocked: 

Regards

----------

## Birtz

Edit: The CPUID part was bogus, after correcting it;

```
cat << "EOF" > test_pni.c

#include <stdint.h>

uint8_t __attribute__((aligned(64))) current[64];

uint8_t previous[64];

int main()

{

   int i;

   uint64_t result;

   uint32_t _eax, _ebx, _ecx, _edx;

   uint8_t _cpuid[13];

   uint32_t *_cpuid0 = (uint32_t*) _cpuid;

   uint32_t *_cpuid1 = (uint32_t*) ( _cpuid + 4 );

   uint32_t *_cpuid2 = (uint32_t*) ( _cpuid + 8 );

   uint8_t *ptr0 = current;

   uint8_t *ptr1 = previous;

   __asm__ __volatile__ (

         "cpuid\n"

         : "=a" (_eax), 

         "=b" (*_cpuid0), "=d" (*_cpuid1), "=c" (*_cpuid2)

         : "a" (0) );

   _cpuid[12] = 0;

   printf( "cpuid(0) returns %d (%s)\n", _eax, _cpuid );

   __asm__ __volatile__ (

         "cpuid\n"

         : "=a" (_eax), "=b" (_ebx), "=c" (_ecx), "=d" (_edx)

         : "a" (1) );

   printf( "cpuid(1) returns %08x %08x %08x %08x\n", 

         _eax, _ebx, _ecx, _edx );

   memset( current, 0xaa, 64 );

   memset( previous, 0x55, 64 );

   for( i = 0; i < 4; i ++ ) {

      __asm__ __volatile__ (

            "movdqa %0, %%xmm0\n"

            "movdqu %1, %%xmm1\n"

            "psadbw %%xmm1, %%xmm0\n"

            "paddw  %%xmm0, %%xmm2\n"

            "haddps %%xmm2, %%xmm2\n"

            "haddps %%xmm2, %%xmm2\n"

            : : "m" (*ptr0), 

            "m" (*ptr1) : "xmm0", "xmm1", "xmm2" );

      ptr0 += 16;

      ptr1 += 16;

   }

   __asm__ __volatile__ (

         "movq %%xmm2, %0\n"

         : "=m" (result) );

   printf( "Result is %llu\n", result );

}

EOF
```

```
gcc -o test_pni test_pni.c

./test_pni

cpuid(0) returns 1 (AuthenticAMD)

cpuid(1) returns 00000ff0 00000800 00000000 078bfbff

Illegal instruction

```

According to http://sandpile.org/ia32/cpuid.htm sse3(pni) is bit 0 in the ecx register after cpuid with eax=1. The result shows bit 0 clear which obviously means no sse3 (as suspected from the start). The fact that kernel shows pni may be cosmetic errata, but I am pretty much annoyed with it (which is obvious).

Regards

----------

## dsd

you dont need a subscription to post to the linux kernel list. just write an email to it.

----------

## Birtz

Followup for the interested parties;

I reported this to both maintainer of the CPUID/MSR part of the kernel, and to the kernel list (thanks dsd). I've got the following answer;

 *Quote:*   

> This bug has been reported here 
> 
> (http://bugme.osdl.org/show_bug.cgi?id=4426) as well and a patch has been 
> 
> submitted.
> ...

 

In the bugtracker it is obvious that this affects not only Athlon64 but AthlonXP also.

Regards

----------

