From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755533AbbIUHN4 (ORCPT ); Mon, 21 Sep 2015 03:13:56 -0400 Received: from terminus.zytor.com ([198.137.202.10]:56588 "EHLO terminus.zytor.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751740AbbIUHNz (ORCPT ); Mon, 21 Sep 2015 03:13:55 -0400 Date: Mon, 21 Sep 2015 00:12:34 -0700 From: tip-bot for Denys Vlasenko Message-ID: Cc: mingo@kernel.org, bp@alien8.de, hpa@zytor.com, peterz@infradead.org, brgerst@gmail.com, luto@amacapital.net, shuahkh@osg.samsung.com, dvlasenk@redhat.com, torvalds@linux-foundation.org, tglx@linutronix.de, linux-kernel@vger.kernel.org, keescook@chromium.org Reply-To: luto@amacapital.net, peterz@infradead.org, brgerst@gmail.com, hpa@zytor.com, bp@alien8.de, mingo@kernel.org, keescook@chromium.org, linux-kernel@vger.kernel.org, torvalds@linux-foundation.org, tglx@linutronix.de, shuahkh@osg.samsung.com, dvlasenk@redhat.com In-Reply-To: <1442757790-27233-1-git-send-email-dvlasenk@redhat.com> References: <1442757790-27233-1-git-send-email-dvlasenk@redhat.com> To: linux-tip-commits@vger.kernel.org Subject: [tip:x86/fpu] x86/fpu/math-emu, selftests: Add test for FISTTP instructions Git-Commit-ID: a58e2ecd019d9ffb9f1813faf6151716fdecbae5 X-Mailer: tip-git-log-daemon Robot-ID: Robot-Unsubscribe: Contact to get blacklisted from these emails MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Content-Type: text/plain; charset=UTF-8 Content-Disposition: inline Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Commit-ID: a58e2ecd019d9ffb9f1813faf6151716fdecbae5 Gitweb: http://git.kernel.org/tip/a58e2ecd019d9ffb9f1813faf6151716fdecbae5 Author: Denys Vlasenko AuthorDate: Sun, 20 Sep 2015 16:03:10 +0200 Committer: Ingo Molnar CommitDate: Sun, 20 Sep 2015 16:19:01 +0200 x86/fpu/math-emu, selftests: Add test for FISTTP instructions $ ./test_FISTTP_32 [RUN] Testing fisttp instructions [OK] fisttp Signed-off-by: Denys Vlasenko Cc: Andy Lutomirski Cc: Borislav Petkov Cc: Brian Gerst Cc: H. Peter Anvin Cc: Kees Cook Cc: Linus Torvalds Cc: Peter Zijlstra Cc: Shuah Khan Cc: Thomas Gleixner Cc: linux-kernel@vger.kernel.org Link: http://lkml.kernel.org/r/1442757790-27233-1-git-send-email-dvlasenk@redhat.com Signed-off-by: Ingo Molnar --- tools/testing/selftests/x86/Makefile | 2 +- tools/testing/selftests/x86/test_FISTTP.c | 137 ++++++++++++++++++++++++++++++ 2 files changed, 138 insertions(+), 1 deletion(-) diff --git a/tools/testing/selftests/x86/Makefile b/tools/testing/selftests/x86/Makefile index c4c9b90..7145b3d 100644 --- a/tools/testing/selftests/x86/Makefile +++ b/tools/testing/selftests/x86/Makefile @@ -6,7 +6,7 @@ include ../lib.mk TARGETS_C_BOTHBITS := single_step_syscall sysret_ss_attrs ldt_gdt syscall_nt TARGETS_C_32BIT_ONLY := entry_from_vm86 syscall_arg_fault sigreturn \ - test_FCMOV test_FCOMI + test_FCMOV test_FCOMI test_FISTTP TARGETS_C_32BIT_ALL := $(TARGETS_C_BOTHBITS) $(TARGETS_C_32BIT_ONLY) BINARIES_32 := $(TARGETS_C_32BIT_ALL:%=%_32) diff --git a/tools/testing/selftests/x86/test_FISTTP.c b/tools/testing/selftests/x86/test_FISTTP.c new file mode 100644 index 0000000..b8e61a0 --- /dev/null +++ b/tools/testing/selftests/x86/test_FISTTP.c @@ -0,0 +1,137 @@ +#undef _GNU_SOURCE +#define _GNU_SOURCE 1 +#undef __USE_GNU +#define __USE_GNU 1 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +unsigned long long res64 = -1; +unsigned int res32 = -1; +unsigned short res16 = -1; + +int test(void) +{ + int ex; + + feclearexcept(FE_DIVBYZERO|FE_INEXACT|FE_INVALID|FE_OVERFLOW|FE_UNDERFLOW); + asm volatile ("\n" + " fld1""\n" + " fisttp res16""\n" + " fld1""\n" + " fisttpl res32""\n" + " fld1""\n" + " fisttpll res64""\n" + : : : "memory" + ); + if (res16 != 1 || res32 != 1 || res64 != 1) { + printf("[BAD]\tfisttp 1\n"); + return 1; + } + ex = fetestexcept(FE_DIVBYZERO|FE_INEXACT|FE_INVALID|FE_OVERFLOW|FE_UNDERFLOW); + if (ex != 0) { + printf("[BAD]\tfisttp 1: wrong exception state\n"); + return 1; + } + + feclearexcept(FE_DIVBYZERO|FE_INEXACT|FE_INVALID|FE_OVERFLOW|FE_UNDERFLOW); + asm volatile ("\n" + " fldpi""\n" + " fisttp res16""\n" + " fldpi""\n" + " fisttpl res32""\n" + " fldpi""\n" + " fisttpll res64""\n" + : : : "memory" + ); + if (res16 != 3 || res32 != 3 || res64 != 3) { + printf("[BAD]\tfisttp pi\n"); + return 1; + } + ex = fetestexcept(FE_DIVBYZERO|FE_INEXACT|FE_INVALID|FE_OVERFLOW|FE_UNDERFLOW); + if (ex != FE_INEXACT) { + printf("[BAD]\tfisttp pi: wrong exception state\n"); + return 1; + } + + feclearexcept(FE_DIVBYZERO|FE_INEXACT|FE_INVALID|FE_OVERFLOW|FE_UNDERFLOW); + asm volatile ("\n" + " fldpi""\n" + " fchs""\n" + " fisttp res16""\n" + " fldpi""\n" + " fchs""\n" + " fisttpl res32""\n" + " fldpi""\n" + " fchs""\n" + " fisttpll res64""\n" + : : : "memory" + ); + if (res16 != 0xfffd || res32 != 0xfffffffd || res64 != 0xfffffffffffffffdULL) { + printf("[BAD]\tfisttp -pi\n"); + return 1; + } + ex = fetestexcept(FE_DIVBYZERO|FE_INEXACT|FE_INVALID|FE_OVERFLOW|FE_UNDERFLOW); + if (ex != FE_INEXACT) { + printf("[BAD]\tfisttp -pi: wrong exception state\n"); + return 1; + } + + feclearexcept(FE_DIVBYZERO|FE_INEXACT|FE_INVALID|FE_OVERFLOW|FE_UNDERFLOW); + asm volatile ("\n" + " fldln2""\n" + " fisttp res16""\n" + " fldln2""\n" + " fisttpl res32""\n" + " fldln2""\n" + " fisttpll res64""\n" + : : : "memory" + ); + /* Test truncation to zero (round-to-nearest would give 1 here) */ + if (res16 != 0 || res32 != 0 || res64 != 0) { + printf("[BAD]\tfisttp ln2\n"); + return 1; + } + ex = fetestexcept(FE_DIVBYZERO|FE_INEXACT|FE_INVALID|FE_OVERFLOW|FE_UNDERFLOW); + if (ex != FE_INEXACT) { + printf("[BAD]\tfisttp ln2: wrong exception state\n"); + return 1; + } + + return 0; +} + +void sighandler(int sig) +{ + printf("[FAIL]\tGot signal %d, exiting\n", sig); + exit(1); +} + +int main(int argc, char **argv, char **envp) +{ + int err = 0; + + /* SIGILL triggers on 32-bit kernels w/o fisttp emulation + * when run with "no387 nofxsr". Other signals are caught + * just in case. + */ + signal(SIGILL, sighandler); + signal(SIGFPE, sighandler); + signal(SIGSEGV, sighandler); + + printf("[RUN]\tTesting fisttp instructions\n"); + err |= test(); + if (!err) + printf("[OK]\tfisttp\n"); + else + printf("[FAIL]\tfisttp errors: %d\n", err); + + return err; +}