* [PATCH 0/3] Fix a misaligned load inside ptrace_attach()
@ 2015-05-01 4:19 Palmer Dabbelt
2015-05-01 4:19 ` [PATCH 1/3] " Palmer Dabbelt
` (3 more replies)
0 siblings, 4 replies; 8+ messages in thread
From: Palmer Dabbelt @ 2015-05-01 4:19 UTC (permalink / raw)
To: mingo, peterz, oleg, akpm, richard, paulmck, bobby.prani,
vdavydov
Cc: linux-kernel
I ran across what I believe is a bug in some asm-generic code while
working on the RISC-V Linux port. Essentially the problem is that
wait_on_bit() takes a void *, but then perfroms long-aligned
operation. As far as I can tell, this bug could manifest on any other
architecture that doesn't support misaligned operations and uses this
particular asm-generic implementation.
The patch set is split into three parts:
* #1 fixes the bug by making task_struct.jobctl an unsigned long,
which ensures wait_on_bit() always ends up with a long-aligned
argument.
* #2 changes the prototype of wait_on_bit() and friends to take a
"unsigned long *" instead of a "void *", with the intent of
ensuring these problems don't happen again.
* #3 is a bit more intrusive: it goes and changes all uses of
task_struct.jobctl from int to long.
I'm not sure if #3 has gone too far, but I think #1 and #2 are sane.
The cost is making task_struct larger on machines where
sizeof(long)>sizeof(int), but since it's so big already this isn't too
much cost. I thought about making test_bit() perform byte-aligned
accesses to avoid this cost, but since there are very similar looking
atomic functions I thought that would be too odd.
^ permalink raw reply [flat|nested] 8+ messages in thread* [PATCH 1/3] Fix a misaligned load inside ptrace_attach() 2015-05-01 4:19 [PATCH 0/3] Fix a misaligned load inside ptrace_attach() Palmer Dabbelt @ 2015-05-01 4:19 ` Palmer Dabbelt 2015-05-08 13:21 ` [tip:sched/core] signals, ptrace, sched: " tip-bot for Palmer Dabbelt 2015-05-01 4:19 ` [PATCH 2/3] Change wait_on_bit*() to take an unsigned long*, not a void* Palmer Dabbelt ` (2 subsequent siblings) 3 siblings, 1 reply; 8+ messages in thread From: Palmer Dabbelt @ 2015-05-01 4:19 UTC (permalink / raw) To: mingo, peterz, oleg, akpm, richard, paulmck, bobby.prani, vdavydov Cc: linux-kernel, Palmer Dabbelt The misaligned load exception arises when running ptrace_attach() on the RISC-V (which hasn't been upstreamed yet). The problem is that wait_on_bit() takes a void* but then proceeds to call test_bit(), which takes a long*. This allows an int-aligned pointer to be passed to test_bit(), which promptly fails. This will manifest on any other asm-generic port where unaligned loads trap, where sizeof(long) > sizeof(int), and where task_struct.jobctl ends up not being long-aligned. This patch changes task_struct.jobctl to be a long, which ensures it has the correct alignment. Reviewed-by: Chris Metcalf <cmetcalf@ezchip.com> Signed-off-by: Palmer Dabbelt <palmer@dabbelt.com> --- include/linux/sched.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/linux/sched.h b/include/linux/sched.h index 26a2e6122734..391827db0a2d 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -1369,7 +1369,7 @@ struct task_struct { int exit_state; int exit_code, exit_signal; int pdeath_signal; /* The signal sent when the parent dies */ - unsigned int jobctl; /* JOBCTL_*, siglock protected */ + unsigned long jobctl; /* JOBCTL_*, siglock protected */ /* Used for emulating ABI behavior of previous Linux versions */ unsigned int personality; -- 2.0.5 ^ permalink raw reply related [flat|nested] 8+ messages in thread
* [tip:sched/core] signals, ptrace, sched: Fix a misaligned load inside ptrace_attach() 2015-05-01 4:19 ` [PATCH 1/3] " Palmer Dabbelt @ 2015-05-08 13:21 ` tip-bot for Palmer Dabbelt 0 siblings, 0 replies; 8+ messages in thread From: tip-bot for Palmer Dabbelt @ 2015-05-08 13:21 UTC (permalink / raw) To: linux-tip-commits Cc: torvalds, hpa, akpm, bp, cmetcalf, mingo, linux-kernel, peterz, palmer, tglx Commit-ID: e7cc4173115347bcdaa5de2824dd46ef2c58425f Gitweb: http://git.kernel.org/tip/e7cc4173115347bcdaa5de2824dd46ef2c58425f Author: Palmer Dabbelt <palmer@dabbelt.com> AuthorDate: Thu, 30 Apr 2015 21:19:55 -0700 Committer: Ingo Molnar <mingo@kernel.org> CommitDate: Fri, 8 May 2015 12:06:57 +0200 signals, ptrace, sched: Fix a misaligned load inside ptrace_attach() The misaligned load exception arises when running ptrace_attach() on the RISC-V (which hasn't been upstreamed yet). The problem is that wait_on_bit() takes a void* but then proceeds to call test_bit(), which takes a long*. This allows an int-aligned pointer to be passed to test_bit(), which promptly fails. This will manifest on any other asm-generic port where unaligned loads trap, where sizeof(long) > sizeof(int), and where task_struct.jobctl ends up not being long-aligned. This patch changes task_struct.jobctl to be a long, which ensures it has the correct alignment. Signed-off-by: Palmer Dabbelt <palmer@dabbelt.com> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Reviewed-by: Chris Metcalf <cmetcalf@ezchip.com> Cc: Andrew Morton <akpm@linux-foundation.org> Cc: Borislav Petkov <bp@alien8.de> Cc: H. Peter Anvin <hpa@zytor.com> Cc: Linus Torvalds <torvalds@linux-foundation.org> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: bobby.prani@gmail.com Cc: oleg@redhat.com Cc: paulmck@linux.vnet.ibm.com Cc: richard@nod.at Cc: vdavydov@parallels.com Link: http://lkml.kernel.org/r/1430453997-32459-2-git-send-email-palmer@dabbelt.com Signed-off-by: Ingo Molnar <mingo@kernel.org> --- include/linux/sched.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/linux/sched.h b/include/linux/sched.h index 4f066cb..fb650a2 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -1374,7 +1374,7 @@ struct task_struct { int exit_state; int exit_code, exit_signal; int pdeath_signal; /* The signal sent when the parent dies */ - unsigned int jobctl; /* JOBCTL_*, siglock protected */ + unsigned long jobctl; /* JOBCTL_*, siglock protected */ /* Used for emulating ABI behavior of previous Linux versions */ unsigned int personality; ^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH 2/3] Change wait_on_bit*() to take an unsigned long*, not a void* 2015-05-01 4:19 [PATCH 0/3] Fix a misaligned load inside ptrace_attach() Palmer Dabbelt 2015-05-01 4:19 ` [PATCH 1/3] " Palmer Dabbelt @ 2015-05-01 4:19 ` Palmer Dabbelt 2015-05-08 13:21 ` [tip:sched/core] sched/wait: Change wait_on_bit*() to take an unsigned long *, not a void * tip-bot for Palmer Dabbelt 2015-05-01 4:19 ` [PATCH 3/3] Change all uses of JOBCTL_* from int to long Palmer Dabbelt 2015-05-01 9:19 ` [PATCH 0/3] Fix a misaligned load inside ptrace_attach() Peter Zijlstra 3 siblings, 1 reply; 8+ messages in thread From: Palmer Dabbelt @ 2015-05-01 4:19 UTC (permalink / raw) To: mingo, peterz, oleg, akpm, richard, paulmck, bobby.prani, vdavydov Cc: linux-kernel, Palmer Dabbelt The implementations of wait_on_bit*() will only work with long-aligned memory on systems that don't support misaligned loads and stores. This patch changes the function prototypes to ensure that the compiler will enforce alignment. Running make defconfig make KFLAGS="-Werror" seems to indicate that, as of c56fb6564dcd ("Fix a misaligned load inside ptrace_attach()"), there are now no users of non-long-aligned calls to wait_on_bit*(). I additionally tried a few "make randconfig" attempts, none of which failed to compile for this reason. Reviewed-by: Chris Metcalf <cmetcalf@ezchip.com> Signed-off-by: Palmer Dabbelt <palmer@dabbelt.com> --- include/linux/wait.h | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/include/linux/wait.h b/include/linux/wait.h index 2db83349865b..d69ac4ecc88b 100644 --- a/include/linux/wait.h +++ b/include/linux/wait.h @@ -969,7 +969,7 @@ extern int bit_wait_io_timeout(struct wait_bit_key *); * on that signal. */ static inline int -wait_on_bit(void *word, int bit, unsigned mode) +wait_on_bit(unsigned long *word, int bit, unsigned mode) { might_sleep(); if (!test_bit(bit, word)) @@ -994,7 +994,7 @@ wait_on_bit(void *word, int bit, unsigned mode) * on that signal. */ static inline int -wait_on_bit_io(void *word, int bit, unsigned mode) +wait_on_bit_io(unsigned long *word, int bit, unsigned mode) { might_sleep(); if (!test_bit(bit, word)) @@ -1020,7 +1020,8 @@ wait_on_bit_io(void *word, int bit, unsigned mode) * received a signal and the mode permitted wakeup on that signal. */ static inline int -wait_on_bit_timeout(void *word, int bit, unsigned mode, unsigned long timeout) +wait_on_bit_timeout(unsigned long *word, int bit, unsigned mode, + unsigned long timeout) { might_sleep(); if (!test_bit(bit, word)) @@ -1047,7 +1048,8 @@ wait_on_bit_timeout(void *word, int bit, unsigned mode, unsigned long timeout) * on that signal. */ static inline int -wait_on_bit_action(void *word, int bit, wait_bit_action_f *action, unsigned mode) +wait_on_bit_action(unsigned long *word, int bit, wait_bit_action_f *action, + unsigned mode) { might_sleep(); if (!test_bit(bit, word)) @@ -1075,7 +1077,7 @@ wait_on_bit_action(void *word, int bit, wait_bit_action_f *action, unsigned mode * the @mode allows that signal to wake the process. */ static inline int -wait_on_bit_lock(void *word, int bit, unsigned mode) +wait_on_bit_lock(unsigned long *word, int bit, unsigned mode) { might_sleep(); if (!test_and_set_bit(bit, word)) @@ -1099,7 +1101,7 @@ wait_on_bit_lock(void *word, int bit, unsigned mode) * the @mode allows that signal to wake the process. */ static inline int -wait_on_bit_lock_io(void *word, int bit, unsigned mode) +wait_on_bit_lock_io(unsigned long *word, int bit, unsigned mode) { might_sleep(); if (!test_and_set_bit(bit, word)) @@ -1125,7 +1127,8 @@ wait_on_bit_lock_io(void *word, int bit, unsigned mode) * the @mode allows that signal to wake the process. */ static inline int -wait_on_bit_lock_action(void *word, int bit, wait_bit_action_f *action, unsigned mode) +wait_on_bit_lock_action(unsigned long *word, int bit, wait_bit_action_f *action, + unsigned mode) { might_sleep(); if (!test_and_set_bit(bit, word)) -- 2.0.5 ^ permalink raw reply related [flat|nested] 8+ messages in thread
* [tip:sched/core] sched/wait: Change wait_on_bit*() to take an unsigned long *, not a void * 2015-05-01 4:19 ` [PATCH 2/3] Change wait_on_bit*() to take an unsigned long*, not a void* Palmer Dabbelt @ 2015-05-08 13:21 ` tip-bot for Palmer Dabbelt 0 siblings, 0 replies; 8+ messages in thread From: tip-bot for Palmer Dabbelt @ 2015-05-08 13:21 UTC (permalink / raw) To: linux-tip-commits Cc: torvalds, hpa, peterz, palmer, bp, akpm, linux-kernel, mingo, cmetcalf, tglx Commit-ID: 7e60598785f30cf3dc9e476cc0fc3feeb37a0c63 Gitweb: http://git.kernel.org/tip/7e60598785f30cf3dc9e476cc0fc3feeb37a0c63 Author: Palmer Dabbelt <palmer@dabbelt.com> AuthorDate: Thu, 30 Apr 2015 21:19:56 -0700 Committer: Ingo Molnar <mingo@kernel.org> CommitDate: Fri, 8 May 2015 12:05:41 +0200 sched/wait: Change wait_on_bit*() to take an unsigned long *, not a void * The implementations of wait_on_bit*() will only work with long-aligned memory on systems that don't support misaligned loads and stores. This patch changes the function prototypes to ensure that the compiler will enforce alignment. Running make defconfig make KFLAGS="-Werror" seems to indicate that, as of c56fb6564dcd ("Fix a misaligned load inside ptrace_attach()"), there are now no users of non-long-aligned calls to wait_on_bit*(). I additionally tried a few "make randconfig" attempts, none of which failed to compile for this reason. Signed-off-by: Palmer Dabbelt <palmer@dabbelt.com> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Reviewed-by: Chris Metcalf <cmetcalf@ezchip.com> Cc: Andrew Morton <akpm@linux-foundation.org> Cc: Borislav Petkov <bp@alien8.de> Cc: H. Peter Anvin <hpa@zytor.com> Cc: Linus Torvalds <torvalds@linux-foundation.org> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: bobby.prani@gmail.com Cc: oleg@redhat.com Cc: paulmck@linux.vnet.ibm.com Cc: richard@nod.at Cc: vdavydov@parallels.com Link: http://lkml.kernel.org/r/1430453997-32459-3-git-send-email-palmer@dabbelt.com Signed-off-by: Ingo Molnar <mingo@kernel.org> --- include/linux/wait.h | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/include/linux/wait.h b/include/linux/wait.h index 2db8334..d69ac4e 100644 --- a/include/linux/wait.h +++ b/include/linux/wait.h @@ -969,7 +969,7 @@ extern int bit_wait_io_timeout(struct wait_bit_key *); * on that signal. */ static inline int -wait_on_bit(void *word, int bit, unsigned mode) +wait_on_bit(unsigned long *word, int bit, unsigned mode) { might_sleep(); if (!test_bit(bit, word)) @@ -994,7 +994,7 @@ wait_on_bit(void *word, int bit, unsigned mode) * on that signal. */ static inline int -wait_on_bit_io(void *word, int bit, unsigned mode) +wait_on_bit_io(unsigned long *word, int bit, unsigned mode) { might_sleep(); if (!test_bit(bit, word)) @@ -1020,7 +1020,8 @@ wait_on_bit_io(void *word, int bit, unsigned mode) * received a signal and the mode permitted wakeup on that signal. */ static inline int -wait_on_bit_timeout(void *word, int bit, unsigned mode, unsigned long timeout) +wait_on_bit_timeout(unsigned long *word, int bit, unsigned mode, + unsigned long timeout) { might_sleep(); if (!test_bit(bit, word)) @@ -1047,7 +1048,8 @@ wait_on_bit_timeout(void *word, int bit, unsigned mode, unsigned long timeout) * on that signal. */ static inline int -wait_on_bit_action(void *word, int bit, wait_bit_action_f *action, unsigned mode) +wait_on_bit_action(unsigned long *word, int bit, wait_bit_action_f *action, + unsigned mode) { might_sleep(); if (!test_bit(bit, word)) @@ -1075,7 +1077,7 @@ wait_on_bit_action(void *word, int bit, wait_bit_action_f *action, unsigned mode * the @mode allows that signal to wake the process. */ static inline int -wait_on_bit_lock(void *word, int bit, unsigned mode) +wait_on_bit_lock(unsigned long *word, int bit, unsigned mode) { might_sleep(); if (!test_and_set_bit(bit, word)) @@ -1099,7 +1101,7 @@ wait_on_bit_lock(void *word, int bit, unsigned mode) * the @mode allows that signal to wake the process. */ static inline int -wait_on_bit_lock_io(void *word, int bit, unsigned mode) +wait_on_bit_lock_io(unsigned long *word, int bit, unsigned mode) { might_sleep(); if (!test_and_set_bit(bit, word)) @@ -1125,7 +1127,8 @@ wait_on_bit_lock_io(void *word, int bit, unsigned mode) * the @mode allows that signal to wake the process. */ static inline int -wait_on_bit_lock_action(void *word, int bit, wait_bit_action_f *action, unsigned mode) +wait_on_bit_lock_action(unsigned long *word, int bit, wait_bit_action_f *action, + unsigned mode) { might_sleep(); if (!test_and_set_bit(bit, word)) ^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH 3/3] Change all uses of JOBCTL_* from int to long 2015-05-01 4:19 [PATCH 0/3] Fix a misaligned load inside ptrace_attach() Palmer Dabbelt 2015-05-01 4:19 ` [PATCH 1/3] " Palmer Dabbelt 2015-05-01 4:19 ` [PATCH 2/3] Change wait_on_bit*() to take an unsigned long*, not a void* Palmer Dabbelt @ 2015-05-01 4:19 ` Palmer Dabbelt 2015-05-08 13:20 ` [tip:sched/core] signals, sched: Change all uses of JOBCTL_* from 'int' to 'long' tip-bot for Palmer Dabbelt 2015-05-01 9:19 ` [PATCH 0/3] Fix a misaligned load inside ptrace_attach() Peter Zijlstra 3 siblings, 1 reply; 8+ messages in thread From: Palmer Dabbelt @ 2015-05-01 4:19 UTC (permalink / raw) To: mingo, peterz, oleg, akpm, richard, paulmck, bobby.prani, vdavydov Cc: linux-kernel, Palmer Dabbelt c56fb6564dcd ("Fix a misaligned load inside ptrace_attach()") makes jobctl an "unsigned long". It makes sense to have the masks applied to it match that type. This is currently just a cosmetic change, but it will prevent the mask from being unexpectedly truncated if we ever end up with masks with more bits. One instance of "signr" is an int, but I left this alone because the mask ensures that it will never overflow. Reviewed-by: Chris Metcalf <cmetcalf@ezchip.com> Signed-off-by: Palmer Dabbelt <palmer@dabbelt.com> --- include/linux/sched.h | 18 +++++++++--------- kernel/signal.c | 6 +++--- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/include/linux/sched.h b/include/linux/sched.h index 391827db0a2d..9251155bf27f 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -2077,22 +2077,22 @@ TASK_PFA_CLEAR(SPREAD_SLAB, spread_slab) #define JOBCTL_TRAPPING_BIT 21 /* switching to TRACED */ #define JOBCTL_LISTENING_BIT 22 /* ptracer is listening for events */ -#define JOBCTL_STOP_DEQUEUED (1 << JOBCTL_STOP_DEQUEUED_BIT) -#define JOBCTL_STOP_PENDING (1 << JOBCTL_STOP_PENDING_BIT) -#define JOBCTL_STOP_CONSUME (1 << JOBCTL_STOP_CONSUME_BIT) -#define JOBCTL_TRAP_STOP (1 << JOBCTL_TRAP_STOP_BIT) -#define JOBCTL_TRAP_NOTIFY (1 << JOBCTL_TRAP_NOTIFY_BIT) -#define JOBCTL_TRAPPING (1 << JOBCTL_TRAPPING_BIT) -#define JOBCTL_LISTENING (1 << JOBCTL_LISTENING_BIT) +#define JOBCTL_STOP_DEQUEUED (1UL << JOBCTL_STOP_DEQUEUED_BIT) +#define JOBCTL_STOP_PENDING (1UL << JOBCTL_STOP_PENDING_BIT) +#define JOBCTL_STOP_CONSUME (1UL << JOBCTL_STOP_CONSUME_BIT) +#define JOBCTL_TRAP_STOP (1UL << JOBCTL_TRAP_STOP_BIT) +#define JOBCTL_TRAP_NOTIFY (1UL << JOBCTL_TRAP_NOTIFY_BIT) +#define JOBCTL_TRAPPING (1UL << JOBCTL_TRAPPING_BIT) +#define JOBCTL_LISTENING (1UL << JOBCTL_LISTENING_BIT) #define JOBCTL_TRAP_MASK (JOBCTL_TRAP_STOP | JOBCTL_TRAP_NOTIFY) #define JOBCTL_PENDING_MASK (JOBCTL_STOP_PENDING | JOBCTL_TRAP_MASK) extern bool task_set_jobctl_pending(struct task_struct *task, - unsigned int mask); + unsigned long mask); extern void task_clear_jobctl_trapping(struct task_struct *task); extern void task_clear_jobctl_pending(struct task_struct *task, - unsigned int mask); + unsigned long mask); static inline void rcu_copy_process(struct task_struct *p) { diff --git a/kernel/signal.c b/kernel/signal.c index d51c5ddd855c..f19833b5db3c 100644 --- a/kernel/signal.c +++ b/kernel/signal.c @@ -245,7 +245,7 @@ static inline void print_dropped_signal(int sig) * RETURNS: * %true if @mask is set, %false if made noop because @task was dying. */ -bool task_set_jobctl_pending(struct task_struct *task, unsigned int mask) +bool task_set_jobctl_pending(struct task_struct *task, unsigned long mask) { BUG_ON(mask & ~(JOBCTL_PENDING_MASK | JOBCTL_STOP_CONSUME | JOBCTL_STOP_SIGMASK | JOBCTL_TRAPPING)); @@ -297,7 +297,7 @@ void task_clear_jobctl_trapping(struct task_struct *task) * CONTEXT: * Must be called with @task->sighand->siglock held. */ -void task_clear_jobctl_pending(struct task_struct *task, unsigned int mask) +void task_clear_jobctl_pending(struct task_struct *task, unsigned long mask) { BUG_ON(mask & ~JOBCTL_PENDING_MASK); @@ -2000,7 +2000,7 @@ static bool do_signal_stop(int signr) struct signal_struct *sig = current->signal; if (!(current->jobctl & JOBCTL_STOP_PENDING)) { - unsigned int gstop = JOBCTL_STOP_PENDING | JOBCTL_STOP_CONSUME; + unsigned long gstop = JOBCTL_STOP_PENDING | JOBCTL_STOP_CONSUME; struct task_struct *t; /* signr will be recorded in task->jobctl for retries */ -- 2.0.5 ^ permalink raw reply related [flat|nested] 8+ messages in thread
* [tip:sched/core] signals, sched: Change all uses of JOBCTL_* from 'int' to 'long' 2015-05-01 4:19 ` [PATCH 3/3] Change all uses of JOBCTL_* from int to long Palmer Dabbelt @ 2015-05-08 13:20 ` tip-bot for Palmer Dabbelt 0 siblings, 0 replies; 8+ messages in thread From: tip-bot for Palmer Dabbelt @ 2015-05-08 13:20 UTC (permalink / raw) To: linux-tip-commits Cc: hpa, peterz, tglx, torvalds, linux-kernel, bp, palmer, akpm, mingo, cmetcalf Commit-ID: b76808e6808e34e7e78131d2b8cb0535622b8e9f Gitweb: http://git.kernel.org/tip/b76808e6808e34e7e78131d2b8cb0535622b8e9f Author: Palmer Dabbelt <palmer@dabbelt.com> AuthorDate: Thu, 30 Apr 2015 21:19:57 -0700 Committer: Ingo Molnar <mingo@kernel.org> CommitDate: Fri, 8 May 2015 12:04:36 +0200 signals, sched: Change all uses of JOBCTL_* from 'int' to 'long' c56fb6564dcd ("Fix a misaligned load inside ptrace_attach()") makes jobctl an "unsigned long". It makes sense to have the masks applied to it match that type. This is currently just a cosmetic change, but it will prevent the mask from being unexpectedly truncated if we ever end up with masks with more bits. One instance of "signr" is an int, but I left this alone because the mask ensures that it will never overflow. Signed-off-by: Palmer Dabbelt <palmer@dabbelt.com> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Reviewed-by: Chris Metcalf <cmetcalf@ezchip.com> Cc: Andrew Morton <akpm@linux-foundation.org> Cc: Borislav Petkov <bp@alien8.de> Cc: H. Peter Anvin <hpa@zytor.com> Cc: Linus Torvalds <torvalds@linux-foundation.org> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: bobby.prani@gmail.com Cc: oleg@redhat.com Cc: paulmck@linux.vnet.ibm.com Cc: richard@nod.at Cc: vdavydov@parallels.com Link: http://lkml.kernel.org/r/1430453997-32459-4-git-send-email-palmer@dabbelt.com Signed-off-by: Ingo Molnar <mingo@kernel.org> --- include/linux/sched.h | 18 +++++++++--------- kernel/signal.c | 6 +++--- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/include/linux/sched.h b/include/linux/sched.h index 85cf253..4f066cb 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -2082,22 +2082,22 @@ TASK_PFA_CLEAR(SPREAD_SLAB, spread_slab) #define JOBCTL_TRAPPING_BIT 21 /* switching to TRACED */ #define JOBCTL_LISTENING_BIT 22 /* ptracer is listening for events */ -#define JOBCTL_STOP_DEQUEUED (1 << JOBCTL_STOP_DEQUEUED_BIT) -#define JOBCTL_STOP_PENDING (1 << JOBCTL_STOP_PENDING_BIT) -#define JOBCTL_STOP_CONSUME (1 << JOBCTL_STOP_CONSUME_BIT) -#define JOBCTL_TRAP_STOP (1 << JOBCTL_TRAP_STOP_BIT) -#define JOBCTL_TRAP_NOTIFY (1 << JOBCTL_TRAP_NOTIFY_BIT) -#define JOBCTL_TRAPPING (1 << JOBCTL_TRAPPING_BIT) -#define JOBCTL_LISTENING (1 << JOBCTL_LISTENING_BIT) +#define JOBCTL_STOP_DEQUEUED (1UL << JOBCTL_STOP_DEQUEUED_BIT) +#define JOBCTL_STOP_PENDING (1UL << JOBCTL_STOP_PENDING_BIT) +#define JOBCTL_STOP_CONSUME (1UL << JOBCTL_STOP_CONSUME_BIT) +#define JOBCTL_TRAP_STOP (1UL << JOBCTL_TRAP_STOP_BIT) +#define JOBCTL_TRAP_NOTIFY (1UL << JOBCTL_TRAP_NOTIFY_BIT) +#define JOBCTL_TRAPPING (1UL << JOBCTL_TRAPPING_BIT) +#define JOBCTL_LISTENING (1UL << JOBCTL_LISTENING_BIT) #define JOBCTL_TRAP_MASK (JOBCTL_TRAP_STOP | JOBCTL_TRAP_NOTIFY) #define JOBCTL_PENDING_MASK (JOBCTL_STOP_PENDING | JOBCTL_TRAP_MASK) extern bool task_set_jobctl_pending(struct task_struct *task, - unsigned int mask); + unsigned long mask); extern void task_clear_jobctl_trapping(struct task_struct *task); extern void task_clear_jobctl_pending(struct task_struct *task, - unsigned int mask); + unsigned long mask); static inline void rcu_copy_process(struct task_struct *p) { diff --git a/kernel/signal.c b/kernel/signal.c index d51c5dd..f19833b 100644 --- a/kernel/signal.c +++ b/kernel/signal.c @@ -245,7 +245,7 @@ static inline void print_dropped_signal(int sig) * RETURNS: * %true if @mask is set, %false if made noop because @task was dying. */ -bool task_set_jobctl_pending(struct task_struct *task, unsigned int mask) +bool task_set_jobctl_pending(struct task_struct *task, unsigned long mask) { BUG_ON(mask & ~(JOBCTL_PENDING_MASK | JOBCTL_STOP_CONSUME | JOBCTL_STOP_SIGMASK | JOBCTL_TRAPPING)); @@ -297,7 +297,7 @@ void task_clear_jobctl_trapping(struct task_struct *task) * CONTEXT: * Must be called with @task->sighand->siglock held. */ -void task_clear_jobctl_pending(struct task_struct *task, unsigned int mask) +void task_clear_jobctl_pending(struct task_struct *task, unsigned long mask) { BUG_ON(mask & ~JOBCTL_PENDING_MASK); @@ -2000,7 +2000,7 @@ static bool do_signal_stop(int signr) struct signal_struct *sig = current->signal; if (!(current->jobctl & JOBCTL_STOP_PENDING)) { - unsigned int gstop = JOBCTL_STOP_PENDING | JOBCTL_STOP_CONSUME; + unsigned long gstop = JOBCTL_STOP_PENDING | JOBCTL_STOP_CONSUME; struct task_struct *t; /* signr will be recorded in task->jobctl for retries */ ^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH 0/3] Fix a misaligned load inside ptrace_attach() 2015-05-01 4:19 [PATCH 0/3] Fix a misaligned load inside ptrace_attach() Palmer Dabbelt ` (2 preceding siblings ...) 2015-05-01 4:19 ` [PATCH 3/3] Change all uses of JOBCTL_* from int to long Palmer Dabbelt @ 2015-05-01 9:19 ` Peter Zijlstra 3 siblings, 0 replies; 8+ messages in thread From: Peter Zijlstra @ 2015-05-01 9:19 UTC (permalink / raw) To: Palmer Dabbelt Cc: mingo, oleg, akpm, richard, paulmck, bobby.prani, vdavydov, linux-kernel On Thu, Apr 30, 2015 at 09:19:54PM -0700, Palmer Dabbelt wrote: > I ran across what I believe is a bug in some asm-generic code while > working on the RISC-V Linux port. Essentially the problem is that > wait_on_bit() takes a void *, but then perfroms long-aligned > operation. As far as I can tell, this bug could manifest on any other > architecture that doesn't support misaligned operations and uses this > particular asm-generic implementation. > > The patch set is split into three parts: > > * #1 fixes the bug by making task_struct.jobctl an unsigned long, > which ensures wait_on_bit() always ends up with a long-aligned > argument. > > * #2 changes the prototype of wait_on_bit() and friends to take a > "unsigned long *" instead of a "void *", with the intent of > ensuring these problems don't happen again. > > * #3 is a bit more intrusive: it goes and changes all uses of > task_struct.jobctl from int to long. > > I'm not sure if #3 has gone too far, but I think #1 and #2 are sane. > The cost is making task_struct larger on machines where > sizeof(long)>sizeof(int), but since it's so big already this isn't too > much cost. I thought about making test_bit() perform byte-aligned > accesses to avoid this cost, but since there are very similar looking > atomic functions I thought that would be too odd. Fair enough. Thanks! ^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2015-05-08 13:22 UTC | newest] Thread overview: 8+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2015-05-01 4:19 [PATCH 0/3] Fix a misaligned load inside ptrace_attach() Palmer Dabbelt 2015-05-01 4:19 ` [PATCH 1/3] " Palmer Dabbelt 2015-05-08 13:21 ` [tip:sched/core] signals, ptrace, sched: " tip-bot for Palmer Dabbelt 2015-05-01 4:19 ` [PATCH 2/3] Change wait_on_bit*() to take an unsigned long*, not a void* Palmer Dabbelt 2015-05-08 13:21 ` [tip:sched/core] sched/wait: Change wait_on_bit*() to take an unsigned long *, not a void * tip-bot for Palmer Dabbelt 2015-05-01 4:19 ` [PATCH 3/3] Change all uses of JOBCTL_* from int to long Palmer Dabbelt 2015-05-08 13:20 ` [tip:sched/core] signals, sched: Change all uses of JOBCTL_* from 'int' to 'long' tip-bot for Palmer Dabbelt 2015-05-01 9:19 ` [PATCH 0/3] Fix a misaligned load inside ptrace_attach() Peter Zijlstra
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox