--- fio-1.41.6/crc/crc32c-intel.c 2010-07-09 13:48:14.000000000 +0200 +++ fio-1.41.4/crc/crc32c-intel.c 2010-06-24 10:39:02.000000000 +0200 @@ -74,30 +74,37 @@ return crc; } -static void do_cpuid(unsigned int *eax, unsigned int *ebx, unsigned int *ecx, - unsigned int *edx) +static void sig_ill(int sig) { - int id = *eax; - - asm("movl %4, %%eax;" - "cpuid;" - "movl %%eax, %0;" - "movl %%ebx, %1;" - "movl %%ecx, %2;" - "movl %%edx, %3;" - : "=r" (*eax), "=r" (*ebx), "=r" (*ecx), "=r" (*edx) - : "r" (id) - : "eax", "ebx", "ecx", "edx"); } -int crc32c_intel_works(void) +static void crc32c_test(void) { - unsigned int eax, ebx, ecx, edx; + unsigned char buf[4] = { 1, 2, 3, 4 }; + struct sigaction act; + + /* + * Check if hw accelerated crc32c is available + */ + memset(&act, 0, sizeof(act)); + act.sa_handler = sig_ill; + act.sa_flags = SA_RESETHAND; + sigaction(SIGILL, &act, NULL); - eax = 1; + (void) crc32c_intel(buf, sizeof(buf)); +} - do_cpuid(&eax, &ebx, &ecx, &edx); - return (ecx & (1 << 20)) != 0; +int crc32c_intel_works(void) +{ + if (!fork()) { + crc32c_test(); + exit(0); + } else { + int status; + + wait(&status); + return !WIFSIGNALED(status); + } } #endif /* ARCH_HAVE_SSE */