The IA32 Emulation support can be either removed from the kernel, disabled by default or disabled at runtime. Some of x86 selftests are crashing for all of above thus is_32bit_syscall_supported() helper is added to skip int80 syscalls if they are not supported.
Slawomir Rosek (2): selftests/x86/ldt_gdt: Skip int80 if not supported selftests/x86/ptrace_syscall: Skip int80 if not supported
tools/testing/selftests/x86/ldt_gdt.c | 21 +++++++++++++++++++- tools/testing/selftests/x86/ptrace_syscall.c | 20 +++++++++++++++++-- 2 files changed, 38 insertions(+), 3 deletions(-)
The IA32 Emulation support can be either removed from the kernel, disabled by default or disabled at runtime. The x86/ldt_gdt selftest crashes for all of above thus is_32bit_syscall_supported() helper is added to skip int80 syscalls if they are not supported.
Signed-off-by: Slawomir Rosek srosek@google.com --- tools/testing/selftests/x86/ldt_gdt.c | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-)
diff --git a/tools/testing/selftests/x86/ldt_gdt.c b/tools/testing/selftests/x86/ldt_gdt.c index bb99a71380a5..b178392e50c0 100644 --- a/tools/testing/selftests/x86/ldt_gdt.c +++ b/tools/testing/selftests/x86/ldt_gdt.c @@ -62,6 +62,18 @@ static struct user_desc *low_user_desc; static struct user_desc *low_user_desc_clear; /* Use to delete GDT entry */ static int gdt_entry_num;
+static bool is_32bit_syscall_supported(void) +{ +#ifdef __x86_64__ + return system("((zcat /proc/config.gz | grep CONFIG_IA32_EMULATION=y) &&" + "((test -z $(zcat /proc/config.gz | grep CONFIG_IA32_EMULATION_DEFAULT_DISABLED=y)) || (grep ia32_emulation=true /proc/cmdline)) &&" + "(test -z $(grep ia32_emulation=false /proc/cmdline))) >/dev/null 2>&1" + ) == 0; +#else + return true; +#endif +} + static void check_invalid_segment(uint16_t index, int ldt) { uint32_t has_limit = 0, has_ar = 0, limit, ar; @@ -147,6 +159,7 @@ static bool install_valid_mode(const struct user_desc *d, uint32_t ar, if (!ldt) { #ifndef __i386__ /* No point testing set_thread_area in a 64-bit build */ + printf("[SKIP]\tNo point testing set_thread_area in a 64-bit build\n"); return false; #endif if (!gdt_entry_num) @@ -676,6 +689,10 @@ static void setup_counter_page(void) static int invoke_set_thread_area(void) { int ret; + if (!is_32bit_syscall_supported()) { + printf("[SKIP]\tNo 32bit syscall support in a 64-bit build\n"); + return -1; + } asm volatile ("int $0x80" : "=a" (ret), "+m" (low_user_desc) : "a" (243), "b" (low_user_desc) @@ -716,8 +733,10 @@ static void setup_low_user_desc(void)
static void test_gdt_invalidation(void) { - if (!gdt_entry_num) + if (!gdt_entry_num) { + printf("[SKIP]\tNo set_thread_area support in a 64-bit only system\n"); return; /* 64-bit only system -- we can't use set_thread_area */ + }
unsigned short prev_sel; unsigned short sel;
The IA32 Emulation support can be either removed from the kernel, disabled by default or disabled at runtime. The x86/ptrace_syscall selftest crashes for all of above thus is_32bit_syscall_supported() helper is added to skip int80 syscalls if they are not supported.
Signed-off-by: Slawomir Rosek srosek@google.com --- tools/testing/selftests/x86/ptrace_syscall.c | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-)
diff --git a/tools/testing/selftests/x86/ptrace_syscall.c b/tools/testing/selftests/x86/ptrace_syscall.c index 360ec88d5432..6c19bea485c6 100644 --- a/tools/testing/selftests/x86/ptrace_syscall.c +++ b/tools/testing/selftests/x86/ptrace_syscall.c @@ -51,6 +51,18 @@ extern void sys32_helper(struct syscall_args32 *, void *); extern void int80_and_ret(void); #endif
+static bool is_32bit_syscall_supported(void) +{ +#ifdef __x86_64__ + return system("((zcat /proc/config.gz | grep CONFIG_IA32_EMULATION=y) &&" + "((test -z $(zcat /proc/config.gz | grep CONFIG_IA32_EMULATION_DEFAULT_DISABLED=y)) || (grep ia32_emulation=true /proc/cmdline)) &&" + "(test -z $(grep ia32_emulation=false /proc/cmdline))) >/dev/null 2>&1" + ) == 0; +#else + return true; +#endif +} + /* * Helper to invoke int80 with controlled regs and capture the final regs. */ @@ -389,8 +401,12 @@ static void test_restart_under_ptrace(void)
int main() { - printf("[RUN]\tCheck int80 return regs\n"); - test_sys32_regs(do_full_int80); + if (is_32bit_syscall_supported()) { + printf("[RUN]\tCheck int80 return regs\n"); + test_sys32_regs(do_full_int80); + } else { + printf("[SKIP]\t32bit syscall support is not available\n"); + }
#if defined(__i386__) && (!defined(__GLIBC__) || __GLIBC__ > 2 || __GLIBC_MINOR__ >= 16) vsyscall32 = (void *)getauxval(AT_SYSINFO);
linux-kselftest-mirror@lists.linaro.org