From 94cbf48e332d87d85592cf774a45b5fa8e9ae027 Mon Sep 17 00:00:00 2001 From: Mark Wielaard Date: Wed, 23 Jun 2010 21:47:53 +0200 Subject: [PATCH] Correct testing for compat task. Always use our own test. is_compat_task(), when defined in the kernel, is really just for testing whether or not we are in a 32-compat syscall. It does not definitely tell us whether or not the current task is a 32bit compat task. So always use our own test_thread_flag() with the arch specific TIF_flag. * runtime/autoconf-is-compat-task.c: Removed. * buildrun.cxx (compile_pass): Remove is-compat-task check. * runtime/compatdefs.h: Detect s390 specific TIF flag. Always define _stp_is_compat_task() when CONFIG_COMPAT defined. * tapset/conversions.stp (user_long): Use _stp_is_compat_task(). (user_long_warn): Likewise. --- buildrun.cxx | 1 - runtime/autoconf-is-compat-task.c | 7 ------ runtime/compatdefs.h | 36 ++++++++++++++++++------------- tapset/conversions.stp | 4 ++-- 4 files changed, 23 insertions(+), 25 deletions(-) delete mode 100644 runtime/autoconf-is-compat-task.c diff --git a/buildrun.cxx b/buildrun.cxx index 5d42f4fdd..097961b6e 100644 --- a/buildrun.cxx +++ b/buildrun.cxx @@ -191,7 +191,6 @@ compile_pass (systemtap_session& s) output_autoconf(s, o, "autoconf-ring_buffer-flags.c", "STAPCONF_RING_BUFFER_FLAGS", NULL); output_autoconf(s, o, "autoconf-kallsyms-on-each-symbol.c", "STAPCONF_KALLSYMS_ON_EACH_SYMBOL", NULL); output_autoconf(s, o, "autoconf-walk-stack.c", "STAPCONF_WALK_STACK", NULL); - output_autoconf(s, o, "autoconf-is-compat-task.c", "STAPCONF_IS_COMPAT_TASK", NULL); o << module_cflags << " += -include $(STAPCONF_HEADER)" << endl; diff --git a/runtime/autoconf-is-compat-task.c b/runtime/autoconf-is-compat-task.c deleted file mode 100644 index ba8cc0dc5..000000000 --- a/runtime/autoconf-is-compat-task.c +++ /dev/null @@ -1,7 +0,0 @@ -#include - -void foo(void) -{ - (int) is_compat_task(); -} - diff --git a/runtime/compatdefs.h b/runtime/compatdefs.h index 9155aec59..03895e176 100644 --- a/runtime/compatdefs.h +++ b/runtime/compatdefs.h @@ -10,24 +10,30 @@ #ifndef _STP_COMPAT_H_ /* -*- linux-c -*- */ #define _STP_COMPAT_H -/* x86_64 has a different flag name from all other arches... */ +#ifdef CONFIG_COMPAT + +/* x86_64 has a different flag name from all other arches and s390... */ #include -#if defined(CONFIG_COMPAT) && !defined(TIF_32BIT) && defined (__x86_64__) +#if defined (__x86_64__) #define TIF_32BIT TIF_IA32 #endif - -/* is_compat_task - returns true if this is a 32-on-64 bit user task. */ -#if !defined(STAPCONF_IS_COMPAT_TASK) - #ifdef CONFIG_COMPAT - static inline int is_compat_task(void) - { - return test_thread_flag(TIF_32BIT); - } - #else - static inline int is_compat_task(void) { return 0; } - #endif -#else - #include +#if defined(__s390__) || defined(__s390x__) + #define TIF_32BIT TIF_31BIT +#endif +#if !defined(TIF_32BIT) +#error architecture not supported, no TIF_32BIT flag #endif +/* _stp_is_compat_task - returns true if this is a 32-on-64 bit user task. + Note that some kernels/architectures define a function called + is_compat_task(), but that just tests for being inside a 32bit compat + syscall. We want to test whether the current task is a 32 bit compat + task itself.*/ +static inline int _stp_is_compat_task(void) +{ + return test_thread_flag(TIF_32BIT); +} + +#endif /* CONFIG_COMPAT */ + #endif /* _STP_COMPAT_H_ */ diff --git a/tapset/conversions.stp b/tapset/conversions.stp index c68d480e8..33c993dfa 100644 --- a/tapset/conversions.stp +++ b/tapset/conversions.stp @@ -454,7 +454,7 @@ function user_long:long (addr:long) %{ /* pure */ /* unprivileged */ assert_is_myproc(); #ifdef CONFIG_COMPAT - if (is_compat_task()) + if (_stp_is_compat_task()) l_size = sizeof(compat_long_t); #endif @@ -497,7 +497,7 @@ function user_long_warn:long (addr:long) %{ /* pure */ /* unprivileged */ assert_is_myproc(); #ifdef CONFIG_COMPAT - if (is_compat_task()) + if (_stp_is_compat_task()) l_size = sizeof(compat_long_t); #endif -- 2.43.5