-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
selftests/x86: Add syscall_nt selftest
I've had this sitting around for a while. Add it to the selftests tree. Far Cry running under Wine depends on this behavior. Signed-off-by: Andy Lutomirski <luto@kernel.org> Cc: Andy Lutomirski <luto@amacapital.net> Cc: Borislav Petkov <bp@alien8.de> Cc: Brian Gerst <brgerst@gmail.com> Cc: Denys Vlasenko <dvlasenk@redhat.com> Cc: H. Peter Anvin <hpa@zytor.com> Cc: Linus Torvalds <torvalds@linux-foundation.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Shuah Khan <shuahkh@osg.samsung.com> Cc: Thomas Gleixner <tglx@linutronix.de> Link: http://lkml.kernel.org/r/ee4d63799a9e5294b70930618b71d04d2770eb2d.1439838962.git.luto@kernel.org Signed-off-by: Ingo Molnar <mingo@kernel.org>
- Loading branch information
Andy Lutomirski
authored and
Ingo Molnar
committed
Aug 18, 2015
1 parent
33f3df4
commit a9c909c
Showing
2 changed files
with
55 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
/* | ||
* syscall_nt.c - checks syscalls with NT set | ||
* Copyright (c) 2014-2015 Andrew Lutomirski | ||
* | ||
* This program is free software; you can redistribute it and/or modify | ||
* it under the terms and conditions of the GNU General Public License, | ||
* version 2, as published by the Free Software Foundation. | ||
* | ||
* This program is distributed in the hope it will be useful, but | ||
* WITHOUT ANY WARRANTY; without even the implied warranty of | ||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
* General Public License for more details. | ||
* | ||
* Some obscure user-space code requires the ability to make system calls | ||
* with FLAGS.NT set. Make sure it works. | ||
*/ | ||
|
||
#include <stdio.h> | ||
#include <unistd.h> | ||
#include <sys/syscall.h> | ||
#include <asm/processor-flags.h> | ||
|
||
#ifdef __x86_64__ | ||
# define WIDTH "q" | ||
#else | ||
# define WIDTH "l" | ||
#endif | ||
|
||
static unsigned long get_eflags(void) | ||
{ | ||
unsigned long eflags; | ||
asm volatile ("pushf" WIDTH "\n\tpop" WIDTH " %0" : "=rm" (eflags)); | ||
return eflags; | ||
} | ||
|
||
static void set_eflags(unsigned long eflags) | ||
{ | ||
asm volatile ("push" WIDTH " %0\n\tpopf" WIDTH | ||
: : "rm" (eflags) : "flags"); | ||
} | ||
|
||
int main() | ||
{ | ||
printf("[RUN]\tSet NT and issue a syscall\n"); | ||
set_eflags(get_eflags() | X86_EFLAGS_NT); | ||
syscall(SYS_getpid); | ||
if (get_eflags() & X86_EFLAGS_NT) { | ||
printf("[OK]\tThe syscall worked and NT is still set\n"); | ||
return 0; | ||
} else { | ||
printf("[FAIL]\tThe syscall worked but NT was cleared\n"); | ||
return 1; | ||
} | ||
} |