All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFC PATCH 0/8] arm64: move thread_info off of the task stack
@ 2016-09-15 13:49 ` Mark Rutland
  0 siblings, 0 replies; 54+ messages in thread
From: Mark Rutland @ 2016-09-15 13:49 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: akpm, ard.biesheuvel, catalin.marinas, james.morse, keescook,
	linux-kernel, lorenzo.pieralisi, luto, mark.rutland,
	suzuki.poulose, takahiro.akashi, will.deacon, kernel-hardening

Building atop of Andy's work on x86 and generic code, these patches move
arm64's thread_info off of the stack and into task_struct. This protects
thread_info from corruption in the face of stack overflow, and serves as
a step towards fully robust stack overflow handling will be addressed by
subsequent patches.

In contrast to x86, we can't place some critical data such as
preempt_count in percpu variables, and we must store these in some
per-task location. This, compounded with the way headers are organised
conspires to require us to still define our own thread_info. I
understand that the longer term plan is to kill off thread_info
entirely, hence I'm sending this as an RFC so we can figure out if/how
we can achieve that.

These patches are based on Andy's x86/vmap_stack branch [1,2], and I've
pushed a copy to me arm64/ti-stack-split branch [3,4]. The result of
these patches boots happily on platforms within reach of my desk, but
has not seen much stressing so far.

Thanks,
Mark.

[1] git://git.kernel.org/pub/scm/linux/kernel/git/luto/linux.git x86/vmap_stack
[2] https://git.kernel.org/cgit/linux/kernel/git/luto/linux.git/log/?h=x86/vmap_stack
[3] git://git.kernel.org/pub/scm/linux/kernel/git/mark/linux.git arm64/ti-stack-split
[4] https://git.kernel.org/cgit/linux/kernel/git/mark/linux.git/log/?h=arm64/ti-stack-split

Mark Rutland (8):
  thread_info: include <current.h> for THREAD_INFO_IN_TASK
  thread_info: allow custom in-task thread_info
  arm64: thread_info remove stale items
  arm64: asm-offsets: remove unused definitions
  arm64: assembler: introduce ldr_this_cpu
  arm64: traps: use task_struct instead of thread_info
  arm64: move sp_el0 and tpidr_el1 into cpu_suspend_ctx
  arm64: split thread_info from task stack

 arch/arm64/Kconfig                   |  2 ++
 arch/arm64/include/asm/Kbuild        |  1 -
 arch/arm64/include/asm/assembler.h   | 19 +++++++++++++++----
 arch/arm64/include/asm/current.h     | 22 ++++++++++++++++++++++
 arch/arm64/include/asm/smp.h         |  1 +
 arch/arm64/include/asm/suspend.h     |  2 +-
 arch/arm64/include/asm/thread_info.h | 21 ---------------------
 arch/arm64/kernel/asm-offsets.c      |  3 +--
 arch/arm64/kernel/entry.S            |  6 +++---
 arch/arm64/kernel/head.S             | 11 +++++------
 arch/arm64/kernel/process.c          | 31 ++++++++++++++++++++++++++-----
 arch/arm64/kernel/sleep.S            |  3 ---
 arch/arm64/kernel/smp.c              |  2 ++
 arch/arm64/kernel/stacktrace.c       |  5 +++++
 arch/arm64/kernel/suspend.c          |  6 ------
 arch/arm64/kernel/traps.c            | 12 ++++++------
 arch/arm64/mm/proc.S                 |  6 ++++++
 include/linux/thread_info.h          |  4 +++-
 init/Kconfig                         |  3 +++
 19 files changed, 101 insertions(+), 59 deletions(-)
 create mode 100644 arch/arm64/include/asm/current.h

-- 
1.9.1

^ permalink raw reply	[flat|nested] 54+ messages in thread

* [RFC PATCH 0/8] arm64: move thread_info off of the task stack
@ 2016-09-15 13:49 ` Mark Rutland
  0 siblings, 0 replies; 54+ messages in thread
From: Mark Rutland @ 2016-09-15 13:49 UTC (permalink / raw)
  To: linux-arm-kernel

Building atop of Andy's work on x86 and generic code, these patches move
arm64's thread_info off of the stack and into task_struct. This protects
thread_info from corruption in the face of stack overflow, and serves as
a step towards fully robust stack overflow handling will be addressed by
subsequent patches.

In contrast to x86, we can't place some critical data such as
preempt_count in percpu variables, and we must store these in some
per-task location. This, compounded with the way headers are organised
conspires to require us to still define our own thread_info. I
understand that the longer term plan is to kill off thread_info
entirely, hence I'm sending this as an RFC so we can figure out if/how
we can achieve that.

These patches are based on Andy's x86/vmap_stack branch [1,2], and I've
pushed a copy to me arm64/ti-stack-split branch [3,4]. The result of
these patches boots happily on platforms within reach of my desk, but
has not seen much stressing so far.

Thanks,
Mark.

[1] git://git.kernel.org/pub/scm/linux/kernel/git/luto/linux.git x86/vmap_stack
[2] https://git.kernel.org/cgit/linux/kernel/git/luto/linux.git/log/?h=x86/vmap_stack
[3] git://git.kernel.org/pub/scm/linux/kernel/git/mark/linux.git arm64/ti-stack-split
[4] https://git.kernel.org/cgit/linux/kernel/git/mark/linux.git/log/?h=arm64/ti-stack-split

Mark Rutland (8):
  thread_info: include <current.h> for THREAD_INFO_IN_TASK
  thread_info: allow custom in-task thread_info
  arm64: thread_info remove stale items
  arm64: asm-offsets: remove unused definitions
  arm64: assembler: introduce ldr_this_cpu
  arm64: traps: use task_struct instead of thread_info
  arm64: move sp_el0 and tpidr_el1 into cpu_suspend_ctx
  arm64: split thread_info from task stack

 arch/arm64/Kconfig                   |  2 ++
 arch/arm64/include/asm/Kbuild        |  1 -
 arch/arm64/include/asm/assembler.h   | 19 +++++++++++++++----
 arch/arm64/include/asm/current.h     | 22 ++++++++++++++++++++++
 arch/arm64/include/asm/smp.h         |  1 +
 arch/arm64/include/asm/suspend.h     |  2 +-
 arch/arm64/include/asm/thread_info.h | 21 ---------------------
 arch/arm64/kernel/asm-offsets.c      |  3 +--
 arch/arm64/kernel/entry.S            |  6 +++---
 arch/arm64/kernel/head.S             | 11 +++++------
 arch/arm64/kernel/process.c          | 31 ++++++++++++++++++++++++++-----
 arch/arm64/kernel/sleep.S            |  3 ---
 arch/arm64/kernel/smp.c              |  2 ++
 arch/arm64/kernel/stacktrace.c       |  5 +++++
 arch/arm64/kernel/suspend.c          |  6 ------
 arch/arm64/kernel/traps.c            | 12 ++++++------
 arch/arm64/mm/proc.S                 |  6 ++++++
 include/linux/thread_info.h          |  4 +++-
 init/Kconfig                         |  3 +++
 19 files changed, 101 insertions(+), 59 deletions(-)
 create mode 100644 arch/arm64/include/asm/current.h

-- 
1.9.1

^ permalink raw reply	[flat|nested] 54+ messages in thread

* [kernel-hardening] [RFC PATCH 0/8] arm64: move thread_info off of the task stack
@ 2016-09-15 13:49 ` Mark Rutland
  0 siblings, 0 replies; 54+ messages in thread
From: Mark Rutland @ 2016-09-15 13:49 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: akpm, ard.biesheuvel, catalin.marinas, james.morse, keescook,
	linux-kernel, lorenzo.pieralisi, luto, mark.rutland,
	suzuki.poulose, takahiro.akashi, will.deacon, kernel-hardening

Building atop of Andy's work on x86 and generic code, these patches move
arm64's thread_info off of the stack and into task_struct. This protects
thread_info from corruption in the face of stack overflow, and serves as
a step towards fully robust stack overflow handling will be addressed by
subsequent patches.

In contrast to x86, we can't place some critical data such as
preempt_count in percpu variables, and we must store these in some
per-task location. This, compounded with the way headers are organised
conspires to require us to still define our own thread_info. I
understand that the longer term plan is to kill off thread_info
entirely, hence I'm sending this as an RFC so we can figure out if/how
we can achieve that.

These patches are based on Andy's x86/vmap_stack branch [1,2], and I've
pushed a copy to me arm64/ti-stack-split branch [3,4]. The result of
these patches boots happily on platforms within reach of my desk, but
has not seen much stressing so far.

Thanks,
Mark.

[1] git://git.kernel.org/pub/scm/linux/kernel/git/luto/linux.git x86/vmap_stack
[2] https://git.kernel.org/cgit/linux/kernel/git/luto/linux.git/log/?h=x86/vmap_stack
[3] git://git.kernel.org/pub/scm/linux/kernel/git/mark/linux.git arm64/ti-stack-split
[4] https://git.kernel.org/cgit/linux/kernel/git/mark/linux.git/log/?h=arm64/ti-stack-split

Mark Rutland (8):
  thread_info: include <current.h> for THREAD_INFO_IN_TASK
  thread_info: allow custom in-task thread_info
  arm64: thread_info remove stale items
  arm64: asm-offsets: remove unused definitions
  arm64: assembler: introduce ldr_this_cpu
  arm64: traps: use task_struct instead of thread_info
  arm64: move sp_el0 and tpidr_el1 into cpu_suspend_ctx
  arm64: split thread_info from task stack

 arch/arm64/Kconfig                   |  2 ++
 arch/arm64/include/asm/Kbuild        |  1 -
 arch/arm64/include/asm/assembler.h   | 19 +++++++++++++++----
 arch/arm64/include/asm/current.h     | 22 ++++++++++++++++++++++
 arch/arm64/include/asm/smp.h         |  1 +
 arch/arm64/include/asm/suspend.h     |  2 +-
 arch/arm64/include/asm/thread_info.h | 21 ---------------------
 arch/arm64/kernel/asm-offsets.c      |  3 +--
 arch/arm64/kernel/entry.S            |  6 +++---
 arch/arm64/kernel/head.S             | 11 +++++------
 arch/arm64/kernel/process.c          | 31 ++++++++++++++++++++++++++-----
 arch/arm64/kernel/sleep.S            |  3 ---
 arch/arm64/kernel/smp.c              |  2 ++
 arch/arm64/kernel/stacktrace.c       |  5 +++++
 arch/arm64/kernel/suspend.c          |  6 ------
 arch/arm64/kernel/traps.c            | 12 ++++++------
 arch/arm64/mm/proc.S                 |  6 ++++++
 include/linux/thread_info.h          |  4 +++-
 init/Kconfig                         |  3 +++
 19 files changed, 101 insertions(+), 59 deletions(-)
 create mode 100644 arch/arm64/include/asm/current.h

-- 
1.9.1

^ permalink raw reply	[flat|nested] 54+ messages in thread

* [RFC PATCH 1/8] thread_info: include <current.h> for THREAD_INFO_IN_TASK
  2016-09-15 13:49 ` Mark Rutland
  (?)
@ 2016-09-15 13:49   ` Mark Rutland
  -1 siblings, 0 replies; 54+ messages in thread
From: Mark Rutland @ 2016-09-15 13:49 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: akpm, ard.biesheuvel, catalin.marinas, james.morse, keescook,
	linux-kernel, lorenzo.pieralisi, luto, mark.rutland,
	suzuki.poulose, takahiro.akashi, will.deacon, kernel-hardening

When CONFIG_THREAD_INFO_IN_TASK is selected, the current_thread_info()
macro relies on current having been defined prior to its use. However,
not all users of current_thread_info() include <asm/current.h>, and thus
current is not guaranteed to be defined.

When CONFIG_THREAD_INFO_IN_TASK is not selected, it's possible that
get_current() / current are based upon current_thread_info(), and
<asm/current.h> includes <asm/thread_info.h>. Thus always including
<asm/current.h> would result in circular dependences on some platforms.

To ensure both cases work, this patch includes <asm/current.h>, but only
when CONFIG_THREAD_INFO_IN_TASK is selected.

Signed-off-by: Mark Rutland <mark.rutland@arm.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Kees Cook <keescook@chromium.org>
Cc: Will Deacon <will.deacon@arm.com>
Cc: linux-kernel@vger.kernel.org
---
 include/linux/thread_info.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/include/linux/thread_info.h b/include/linux/thread_info.h
index cb0ed34..d9622f7 100644
--- a/include/linux/thread_info.h
+++ b/include/linux/thread_info.h
@@ -25,6 +25,7 @@ struct thread_info {
 #endif
 
 #ifdef CONFIG_THREAD_INFO_IN_TASK
+#include <asm/current.h>
 #define current_thread_info() ((struct thread_info *)current)
 #endif
 
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [RFC PATCH 1/8] thread_info: include <current.h> for THREAD_INFO_IN_TASK
@ 2016-09-15 13:49   ` Mark Rutland
  0 siblings, 0 replies; 54+ messages in thread
From: Mark Rutland @ 2016-09-15 13:49 UTC (permalink / raw)
  To: linux-arm-kernel

When CONFIG_THREAD_INFO_IN_TASK is selected, the current_thread_info()
macro relies on current having been defined prior to its use. However,
not all users of current_thread_info() include <asm/current.h>, and thus
current is not guaranteed to be defined.

When CONFIG_THREAD_INFO_IN_TASK is not selected, it's possible that
get_current() / current are based upon current_thread_info(), and
<asm/current.h> includes <asm/thread_info.h>. Thus always including
<asm/current.h> would result in circular dependences on some platforms.

To ensure both cases work, this patch includes <asm/current.h>, but only
when CONFIG_THREAD_INFO_IN_TASK is selected.

Signed-off-by: Mark Rutland <mark.rutland@arm.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Kees Cook <keescook@chromium.org>
Cc: Will Deacon <will.deacon@arm.com>
Cc: linux-kernel at vger.kernel.org
---
 include/linux/thread_info.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/include/linux/thread_info.h b/include/linux/thread_info.h
index cb0ed34..d9622f7 100644
--- a/include/linux/thread_info.h
+++ b/include/linux/thread_info.h
@@ -25,6 +25,7 @@ struct thread_info {
 #endif
 
 #ifdef CONFIG_THREAD_INFO_IN_TASK
+#include <asm/current.h>
 #define current_thread_info() ((struct thread_info *)current)
 #endif
 
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [kernel-hardening] [RFC PATCH 1/8] thread_info: include <current.h> for THREAD_INFO_IN_TASK
@ 2016-09-15 13:49   ` Mark Rutland
  0 siblings, 0 replies; 54+ messages in thread
From: Mark Rutland @ 2016-09-15 13:49 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: akpm, ard.biesheuvel, catalin.marinas, james.morse, keescook,
	linux-kernel, lorenzo.pieralisi, luto, mark.rutland,
	suzuki.poulose, takahiro.akashi, will.deacon, kernel-hardening

When CONFIG_THREAD_INFO_IN_TASK is selected, the current_thread_info()
macro relies on current having been defined prior to its use. However,
not all users of current_thread_info() include <asm/current.h>, and thus
current is not guaranteed to be defined.

When CONFIG_THREAD_INFO_IN_TASK is not selected, it's possible that
get_current() / current are based upon current_thread_info(), and
<asm/current.h> includes <asm/thread_info.h>. Thus always including
<asm/current.h> would result in circular dependences on some platforms.

To ensure both cases work, this patch includes <asm/current.h>, but only
when CONFIG_THREAD_INFO_IN_TASK is selected.

Signed-off-by: Mark Rutland <mark.rutland@arm.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Kees Cook <keescook@chromium.org>
Cc: Will Deacon <will.deacon@arm.com>
Cc: linux-kernel@vger.kernel.org
---
 include/linux/thread_info.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/include/linux/thread_info.h b/include/linux/thread_info.h
index cb0ed34..d9622f7 100644
--- a/include/linux/thread_info.h
+++ b/include/linux/thread_info.h
@@ -25,6 +25,7 @@ struct thread_info {
 #endif
 
 #ifdef CONFIG_THREAD_INFO_IN_TASK
+#include <asm/current.h>
 #define current_thread_info() ((struct thread_info *)current)
 #endif
 
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [RFC PATCH 2/8] thread_info: allow custom in-task thread_info
  2016-09-15 13:49 ` Mark Rutland
  (?)
@ 2016-09-15 13:49   ` Mark Rutland
  -1 siblings, 0 replies; 54+ messages in thread
From: Mark Rutland @ 2016-09-15 13:49 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: akpm, ard.biesheuvel, catalin.marinas, james.morse, keescook,
	linux-kernel, lorenzo.pieralisi, luto, mark.rutland,
	suzuki.poulose, takahiro.akashi, will.deacon, kernel-hardening

Currently, task_struct is defined in <linux/sched.h>, which (indirectly)
pulls in a number of low-level arch headers such as <asm/preempt.h>
through a number of other headers. Thus, code and structures in these
headers can't rely on the definition of task_struct. Some of these
headers are necessary for the definition of task_struct, so moving
task_struct into its own header is insufficient tio avoid circular
includes.

With CONFIG_THREAD_INFO_IN_TASK, arch code needs to implement its own
get_current() for the generic get_thread_info(). To avoid header
dependency issues, this relies on thread_info being the first member of
task_struct. This can be used by low-level arch code, as it doesn't
depend on the definition of task_struct.

For architectures without preempt-safe this_cpu ops, some data required
by low-level arch code (e.g. preempt_count) has to be stored per-thread,
and for the reasons above, we cannot place this in task_struct (or
thread_struct, since we cannot know its offset from within task_struct).
The only practical location for these is thread_info.

This patch allows architectures with CONFIG_ARCH_HAS_OWN_THREAD_INFO to
define their own thread_info, avoiding the problems described above.

Signed-off-by: Mark Rutland <mark.rutland@arm.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Kees Cook <keescook@chromium.org>
Cc: Will Deacon <will.deacon@arm.com>
Cc: linux-kernel@vger.kernel.org
---
 include/linux/thread_info.h | 3 ++-
 init/Kconfig                | 3 +++
 2 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/include/linux/thread_info.h b/include/linux/thread_info.h
index d9622f7..7984f87 100644
--- a/include/linux/thread_info.h
+++ b/include/linux/thread_info.h
@@ -13,7 +13,8 @@
 struct timespec;
 struct compat_timespec;
 
-#ifdef CONFIG_THREAD_INFO_IN_TASK
+#if defined(CONFIG_THREAD_INFO_IN_TASK) && \
+    !defined(CONFIG_ARCH_HAS_OWN_THREAD_INFO)
 struct thread_info {
 	u32			flags;		/* low level flags */
 };
diff --git a/init/Kconfig b/init/Kconfig
index 3b9a47f..f812098 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -26,6 +26,9 @@ config IRQ_WORK
 config BUILDTIME_EXTABLE_SORT
 	bool
 
+config ARCH_HAS_OWN_THREAD_INFO
+	bool
+
 config THREAD_INFO_IN_TASK
 	bool
 	help
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [RFC PATCH 2/8] thread_info: allow custom in-task thread_info
@ 2016-09-15 13:49   ` Mark Rutland
  0 siblings, 0 replies; 54+ messages in thread
From: Mark Rutland @ 2016-09-15 13:49 UTC (permalink / raw)
  To: linux-arm-kernel

Currently, task_struct is defined in <linux/sched.h>, which (indirectly)
pulls in a number of low-level arch headers such as <asm/preempt.h>
through a number of other headers. Thus, code and structures in these
headers can't rely on the definition of task_struct. Some of these
headers are necessary for the definition of task_struct, so moving
task_struct into its own header is insufficient tio avoid circular
includes.

With CONFIG_THREAD_INFO_IN_TASK, arch code needs to implement its own
get_current() for the generic get_thread_info(). To avoid header
dependency issues, this relies on thread_info being the first member of
task_struct. This can be used by low-level arch code, as it doesn't
depend on the definition of task_struct.

For architectures without preempt-safe this_cpu ops, some data required
by low-level arch code (e.g. preempt_count) has to be stored per-thread,
and for the reasons above, we cannot place this in task_struct (or
thread_struct, since we cannot know its offset from within task_struct).
The only practical location for these is thread_info.

This patch allows architectures with CONFIG_ARCH_HAS_OWN_THREAD_INFO to
define their own thread_info, avoiding the problems described above.

Signed-off-by: Mark Rutland <mark.rutland@arm.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Kees Cook <keescook@chromium.org>
Cc: Will Deacon <will.deacon@arm.com>
Cc: linux-kernel at vger.kernel.org
---
 include/linux/thread_info.h | 3 ++-
 init/Kconfig                | 3 +++
 2 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/include/linux/thread_info.h b/include/linux/thread_info.h
index d9622f7..7984f87 100644
--- a/include/linux/thread_info.h
+++ b/include/linux/thread_info.h
@@ -13,7 +13,8 @@
 struct timespec;
 struct compat_timespec;
 
-#ifdef CONFIG_THREAD_INFO_IN_TASK
+#if defined(CONFIG_THREAD_INFO_IN_TASK) && \
+    !defined(CONFIG_ARCH_HAS_OWN_THREAD_INFO)
 struct thread_info {
 	u32			flags;		/* low level flags */
 };
diff --git a/init/Kconfig b/init/Kconfig
index 3b9a47f..f812098 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -26,6 +26,9 @@ config IRQ_WORK
 config BUILDTIME_EXTABLE_SORT
 	bool
 
+config ARCH_HAS_OWN_THREAD_INFO
+	bool
+
 config THREAD_INFO_IN_TASK
 	bool
 	help
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [kernel-hardening] [RFC PATCH 2/8] thread_info: allow custom in-task thread_info
@ 2016-09-15 13:49   ` Mark Rutland
  0 siblings, 0 replies; 54+ messages in thread
From: Mark Rutland @ 2016-09-15 13:49 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: akpm, ard.biesheuvel, catalin.marinas, james.morse, keescook,
	linux-kernel, lorenzo.pieralisi, luto, mark.rutland,
	suzuki.poulose, takahiro.akashi, will.deacon, kernel-hardening

Currently, task_struct is defined in <linux/sched.h>, which (indirectly)
pulls in a number of low-level arch headers such as <asm/preempt.h>
through a number of other headers. Thus, code and structures in these
headers can't rely on the definition of task_struct. Some of these
headers are necessary for the definition of task_struct, so moving
task_struct into its own header is insufficient tio avoid circular
includes.

With CONFIG_THREAD_INFO_IN_TASK, arch code needs to implement its own
get_current() for the generic get_thread_info(). To avoid header
dependency issues, this relies on thread_info being the first member of
task_struct. This can be used by low-level arch code, as it doesn't
depend on the definition of task_struct.

For architectures without preempt-safe this_cpu ops, some data required
by low-level arch code (e.g. preempt_count) has to be stored per-thread,
and for the reasons above, we cannot place this in task_struct (or
thread_struct, since we cannot know its offset from within task_struct).
The only practical location for these is thread_info.

This patch allows architectures with CONFIG_ARCH_HAS_OWN_THREAD_INFO to
define their own thread_info, avoiding the problems described above.

Signed-off-by: Mark Rutland <mark.rutland@arm.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Kees Cook <keescook@chromium.org>
Cc: Will Deacon <will.deacon@arm.com>
Cc: linux-kernel@vger.kernel.org
---
 include/linux/thread_info.h | 3 ++-
 init/Kconfig                | 3 +++
 2 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/include/linux/thread_info.h b/include/linux/thread_info.h
index d9622f7..7984f87 100644
--- a/include/linux/thread_info.h
+++ b/include/linux/thread_info.h
@@ -13,7 +13,8 @@
 struct timespec;
 struct compat_timespec;
 
-#ifdef CONFIG_THREAD_INFO_IN_TASK
+#if defined(CONFIG_THREAD_INFO_IN_TASK) && \
+    !defined(CONFIG_ARCH_HAS_OWN_THREAD_INFO)
 struct thread_info {
 	u32			flags;		/* low level flags */
 };
diff --git a/init/Kconfig b/init/Kconfig
index 3b9a47f..f812098 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -26,6 +26,9 @@ config IRQ_WORK
 config BUILDTIME_EXTABLE_SORT
 	bool
 
+config ARCH_HAS_OWN_THREAD_INFO
+	bool
+
 config THREAD_INFO_IN_TASK
 	bool
 	help
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [RFC PATCH 3/8] arm64: thread_info remove stale items
  2016-09-15 13:49 ` Mark Rutland
  (?)
@ 2016-09-15 13:49   ` Mark Rutland
  -1 siblings, 0 replies; 54+ messages in thread
From: Mark Rutland @ 2016-09-15 13:49 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: akpm, ard.biesheuvel, catalin.marinas, james.morse, keescook,
	linux-kernel, lorenzo.pieralisi, luto, mark.rutland,
	suzuki.poulose, takahiro.akashi, will.deacon, kernel-hardening

We have a comment claiming __switch_to() cares about where cpu_context
is located relative to cpu_domain in thread_info. However arm64 has
never had a thread_info::cpu_domain field, and neither __switch_to nor
cpu_switch_to care where the cpu_context field is relative to others.

Additionally, the init_thread_info alias is never used anywhere in the
kernel, and will shortly become problematic when thread_info is moved
into task_struct.

This patch removes both.

Signed-off-by: Mark Rutland <mark.rutland@arm.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: James Morse <james.morse@arm.com>
Cc: Will Deacon <will.deacon@arm.com>
---
 arch/arm64/include/asm/thread_info.h | 2 --
 1 file changed, 2 deletions(-)

diff --git a/arch/arm64/include/asm/thread_info.h b/arch/arm64/include/asm/thread_info.h
index abd64bd..796af24 100644
--- a/arch/arm64/include/asm/thread_info.h
+++ b/arch/arm64/include/asm/thread_info.h
@@ -42,7 +42,6 @@ typedef unsigned long mm_segment_t;
 
 /*
  * low level task data that entry.S needs immediate access to.
- * __switch_to() assumes cpu_context follows immediately after cpu_domain.
  */
 struct thread_info {
 	unsigned long		flags;		/* low level flags */
@@ -60,7 +59,6 @@ struct thread_info {
 	.addr_limit	= KERNEL_DS,					\
 }
 
-#define init_thread_info	(init_thread_union.thread_info)
 #define init_stack		(init_thread_union.stack)
 
 /*
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [RFC PATCH 3/8] arm64: thread_info remove stale items
@ 2016-09-15 13:49   ` Mark Rutland
  0 siblings, 0 replies; 54+ messages in thread
From: Mark Rutland @ 2016-09-15 13:49 UTC (permalink / raw)
  To: linux-arm-kernel

We have a comment claiming __switch_to() cares about where cpu_context
is located relative to cpu_domain in thread_info. However arm64 has
never had a thread_info::cpu_domain field, and neither __switch_to nor
cpu_switch_to care where the cpu_context field is relative to others.

Additionally, the init_thread_info alias is never used anywhere in the
kernel, and will shortly become problematic when thread_info is moved
into task_struct.

This patch removes both.

Signed-off-by: Mark Rutland <mark.rutland@arm.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: James Morse <james.morse@arm.com>
Cc: Will Deacon <will.deacon@arm.com>
---
 arch/arm64/include/asm/thread_info.h | 2 --
 1 file changed, 2 deletions(-)

diff --git a/arch/arm64/include/asm/thread_info.h b/arch/arm64/include/asm/thread_info.h
index abd64bd..796af24 100644
--- a/arch/arm64/include/asm/thread_info.h
+++ b/arch/arm64/include/asm/thread_info.h
@@ -42,7 +42,6 @@ typedef unsigned long mm_segment_t;
 
 /*
  * low level task data that entry.S needs immediate access to.
- * __switch_to() assumes cpu_context follows immediately after cpu_domain.
  */
 struct thread_info {
 	unsigned long		flags;		/* low level flags */
@@ -60,7 +59,6 @@ struct thread_info {
 	.addr_limit	= KERNEL_DS,					\
 }
 
-#define init_thread_info	(init_thread_union.thread_info)
 #define init_stack		(init_thread_union.stack)
 
 /*
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [kernel-hardening] [RFC PATCH 3/8] arm64: thread_info remove stale items
@ 2016-09-15 13:49   ` Mark Rutland
  0 siblings, 0 replies; 54+ messages in thread
From: Mark Rutland @ 2016-09-15 13:49 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: akpm, ard.biesheuvel, catalin.marinas, james.morse, keescook,
	linux-kernel, lorenzo.pieralisi, luto, mark.rutland,
	suzuki.poulose, takahiro.akashi, will.deacon, kernel-hardening

We have a comment claiming __switch_to() cares about where cpu_context
is located relative to cpu_domain in thread_info. However arm64 has
never had a thread_info::cpu_domain field, and neither __switch_to nor
cpu_switch_to care where the cpu_context field is relative to others.

Additionally, the init_thread_info alias is never used anywhere in the
kernel, and will shortly become problematic when thread_info is moved
into task_struct.

This patch removes both.

Signed-off-by: Mark Rutland <mark.rutland@arm.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: James Morse <james.morse@arm.com>
Cc: Will Deacon <will.deacon@arm.com>
---
 arch/arm64/include/asm/thread_info.h | 2 --
 1 file changed, 2 deletions(-)

diff --git a/arch/arm64/include/asm/thread_info.h b/arch/arm64/include/asm/thread_info.h
index abd64bd..796af24 100644
--- a/arch/arm64/include/asm/thread_info.h
+++ b/arch/arm64/include/asm/thread_info.h
@@ -42,7 +42,6 @@ typedef unsigned long mm_segment_t;
 
 /*
  * low level task data that entry.S needs immediate access to.
- * __switch_to() assumes cpu_context follows immediately after cpu_domain.
  */
 struct thread_info {
 	unsigned long		flags;		/* low level flags */
@@ -60,7 +59,6 @@ struct thread_info {
 	.addr_limit	= KERNEL_DS,					\
 }
 
-#define init_thread_info	(init_thread_union.thread_info)
 #define init_stack		(init_thread_union.stack)
 
 /*
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [RFC PATCH 4/8] arm64: asm-offsets: remove unused definitions
  2016-09-15 13:49 ` Mark Rutland
  (?)
@ 2016-09-15 13:49   ` Mark Rutland
  -1 siblings, 0 replies; 54+ messages in thread
From: Mark Rutland @ 2016-09-15 13:49 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: akpm, ard.biesheuvel, catalin.marinas, james.morse, keescook,
	linux-kernel, lorenzo.pieralisi, luto, mark.rutland,
	suzuki.poulose, takahiro.akashi, will.deacon, kernel-hardening

Subsequent patches will move the thread_info::{task,cpu} fields, and the
current TI_{TASK,CPU} offset definitions are not used anywhere.

This patch removes the redundant definitions.

Signed-off-by: Mark Rutland <mark.rutland@arm.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: James Morse <james.morse@arm.com>
Cc: Will Deacon <will.deacon@arm.com>
---
 arch/arm64/kernel/asm-offsets.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/arch/arm64/kernel/asm-offsets.c b/arch/arm64/kernel/asm-offsets.c
index 05070b7..ee764eb 100644
--- a/arch/arm64/kernel/asm-offsets.c
+++ b/arch/arm64/kernel/asm-offsets.c
@@ -38,8 +38,6 @@ int main(void)
   DEFINE(TI_FLAGS,		offsetof(struct thread_info, flags));
   DEFINE(TI_PREEMPT,		offsetof(struct thread_info, preempt_count));
   DEFINE(TI_ADDR_LIMIT,		offsetof(struct thread_info, addr_limit));
-  DEFINE(TI_TASK,		offsetof(struct thread_info, task));
-  DEFINE(TI_CPU,		offsetof(struct thread_info, cpu));
   BLANK();
   DEFINE(THREAD_CPU_CONTEXT,	offsetof(struct task_struct, thread.cpu_context));
   BLANK();
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [RFC PATCH 4/8] arm64: asm-offsets: remove unused definitions
@ 2016-09-15 13:49   ` Mark Rutland
  0 siblings, 0 replies; 54+ messages in thread
From: Mark Rutland @ 2016-09-15 13:49 UTC (permalink / raw)
  To: linux-arm-kernel

Subsequent patches will move the thread_info::{task,cpu} fields, and the
current TI_{TASK,CPU} offset definitions are not used anywhere.

This patch removes the redundant definitions.

Signed-off-by: Mark Rutland <mark.rutland@arm.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: James Morse <james.morse@arm.com>
Cc: Will Deacon <will.deacon@arm.com>
---
 arch/arm64/kernel/asm-offsets.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/arch/arm64/kernel/asm-offsets.c b/arch/arm64/kernel/asm-offsets.c
index 05070b7..ee764eb 100644
--- a/arch/arm64/kernel/asm-offsets.c
+++ b/arch/arm64/kernel/asm-offsets.c
@@ -38,8 +38,6 @@ int main(void)
   DEFINE(TI_FLAGS,		offsetof(struct thread_info, flags));
   DEFINE(TI_PREEMPT,		offsetof(struct thread_info, preempt_count));
   DEFINE(TI_ADDR_LIMIT,		offsetof(struct thread_info, addr_limit));
-  DEFINE(TI_TASK,		offsetof(struct thread_info, task));
-  DEFINE(TI_CPU,		offsetof(struct thread_info, cpu));
   BLANK();
   DEFINE(THREAD_CPU_CONTEXT,	offsetof(struct task_struct, thread.cpu_context));
   BLANK();
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [kernel-hardening] [RFC PATCH 4/8] arm64: asm-offsets: remove unused definitions
@ 2016-09-15 13:49   ` Mark Rutland
  0 siblings, 0 replies; 54+ messages in thread
From: Mark Rutland @ 2016-09-15 13:49 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: akpm, ard.biesheuvel, catalin.marinas, james.morse, keescook,
	linux-kernel, lorenzo.pieralisi, luto, mark.rutland,
	suzuki.poulose, takahiro.akashi, will.deacon, kernel-hardening

Subsequent patches will move the thread_info::{task,cpu} fields, and the
current TI_{TASK,CPU} offset definitions are not used anywhere.

This patch removes the redundant definitions.

Signed-off-by: Mark Rutland <mark.rutland@arm.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: James Morse <james.morse@arm.com>
Cc: Will Deacon <will.deacon@arm.com>
---
 arch/arm64/kernel/asm-offsets.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/arch/arm64/kernel/asm-offsets.c b/arch/arm64/kernel/asm-offsets.c
index 05070b7..ee764eb 100644
--- a/arch/arm64/kernel/asm-offsets.c
+++ b/arch/arm64/kernel/asm-offsets.c
@@ -38,8 +38,6 @@ int main(void)
   DEFINE(TI_FLAGS,		offsetof(struct thread_info, flags));
   DEFINE(TI_PREEMPT,		offsetof(struct thread_info, preempt_count));
   DEFINE(TI_ADDR_LIMIT,		offsetof(struct thread_info, addr_limit));
-  DEFINE(TI_TASK,		offsetof(struct thread_info, task));
-  DEFINE(TI_CPU,		offsetof(struct thread_info, cpu));
   BLANK();
   DEFINE(THREAD_CPU_CONTEXT,	offsetof(struct task_struct, thread.cpu_context));
   BLANK();
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [RFC PATCH 5/8] arm64: assembler: introduce ldr_this_cpu
  2016-09-15 13:49 ` Mark Rutland
  (?)
@ 2016-09-15 13:49   ` Mark Rutland
  -1 siblings, 0 replies; 54+ messages in thread
From: Mark Rutland @ 2016-09-15 13:49 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: akpm, ard.biesheuvel, catalin.marinas, james.morse, keescook,
	linux-kernel, lorenzo.pieralisi, luto, mark.rutland,
	suzuki.poulose, takahiro.akashi, will.deacon, kernel-hardening

Shortly we will want to load a percpu variable in the return from
userspace path. We can save an instruction by folding the addition of
the percpu offset into the load instruction, and this patch adds a new
helper to do so.

At the same time, we clean up this_cpu_ptr for consistency. As with
{adr,ldr,str}_l, we change the template to take the destination register
first, and name this dst. Secondly, we rename the macro to adr_this_cpu,
following the scheme of adr_l, and matching the newly added
ldr_this_cpu.

Signed-off-by: Mark Rutland <mark.rutland@arm.com>
Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: James Morse <james.morse@arm.com>
Cc: Will Deacon <will.deacon@arm.com>
---
 arch/arm64/include/asm/assembler.h | 19 +++++++++++++++----
 arch/arm64/kernel/entry.S          |  2 +-
 2 files changed, 16 insertions(+), 5 deletions(-)

diff --git a/arch/arm64/include/asm/assembler.h b/arch/arm64/include/asm/assembler.h
index d5025c6..265fd81 100644
--- a/arch/arm64/include/asm/assembler.h
+++ b/arch/arm64/include/asm/assembler.h
@@ -193,14 +193,25 @@ lr	.req	x30		// link register
 	.endm
 
 	/*
+	 * @dst: Result of per_cpu(sym, smp_processor_id())
 	 * @sym: The name of the per-cpu variable
-	 * @reg: Result of per_cpu(sym, smp_processor_id())
 	 * @tmp: scratch register
 	 */
-	.macro this_cpu_ptr, sym, reg, tmp
-	adr_l	\reg, \sym
+	.macro adr_this_cpu, dst, sym, tmp
+	adr_l	\dst, \sym
 	mrs	\tmp, tpidr_el1
-	add	\reg, \reg, \tmp
+	add	\dst, \dst, \tmp
+	.endm
+
+	/*
+	 * @dst: Result of READ_ONCE(per_cpu(sym, smp_processor_id()))
+	 * @sym: The name of the per-cpu variable
+	 * @tmp: scratch register
+	 */
+	.macro ldr_this_cpu dst, sym, tmp
+	adr_l	\dst, \sym
+	mrs	\tmp, tpidr_el1
+	ldr	\dst, [\dst, \tmp]
 	.endm
 
 /*
diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S
index 441420c..52b4241 100644
--- a/arch/arm64/kernel/entry.S
+++ b/arch/arm64/kernel/entry.S
@@ -206,7 +206,7 @@ alternative_endif
 	cmp	x25, tsk
 	b.ne	9998f
 
-	this_cpu_ptr irq_stack, x25, x26
+	adr_this_cpu x25, irq_stack, x26
 	mov	x26, #IRQ_STACK_START_SP
 	add	x26, x25, x26
 
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [RFC PATCH 5/8] arm64: assembler: introduce ldr_this_cpu
@ 2016-09-15 13:49   ` Mark Rutland
  0 siblings, 0 replies; 54+ messages in thread
From: Mark Rutland @ 2016-09-15 13:49 UTC (permalink / raw)
  To: linux-arm-kernel

Shortly we will want to load a percpu variable in the return from
userspace path. We can save an instruction by folding the addition of
the percpu offset into the load instruction, and this patch adds a new
helper to do so.

At the same time, we clean up this_cpu_ptr for consistency. As with
{adr,ldr,str}_l, we change the template to take the destination register
first, and name this dst. Secondly, we rename the macro to adr_this_cpu,
following the scheme of adr_l, and matching the newly added
ldr_this_cpu.

Signed-off-by: Mark Rutland <mark.rutland@arm.com>
Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: James Morse <james.morse@arm.com>
Cc: Will Deacon <will.deacon@arm.com>
---
 arch/arm64/include/asm/assembler.h | 19 +++++++++++++++----
 arch/arm64/kernel/entry.S          |  2 +-
 2 files changed, 16 insertions(+), 5 deletions(-)

diff --git a/arch/arm64/include/asm/assembler.h b/arch/arm64/include/asm/assembler.h
index d5025c6..265fd81 100644
--- a/arch/arm64/include/asm/assembler.h
+++ b/arch/arm64/include/asm/assembler.h
@@ -193,14 +193,25 @@ lr	.req	x30		// link register
 	.endm
 
 	/*
+	 * @dst: Result of per_cpu(sym, smp_processor_id())
 	 * @sym: The name of the per-cpu variable
-	 * @reg: Result of per_cpu(sym, smp_processor_id())
 	 * @tmp: scratch register
 	 */
-	.macro this_cpu_ptr, sym, reg, tmp
-	adr_l	\reg, \sym
+	.macro adr_this_cpu, dst, sym, tmp
+	adr_l	\dst, \sym
 	mrs	\tmp, tpidr_el1
-	add	\reg, \reg, \tmp
+	add	\dst, \dst, \tmp
+	.endm
+
+	/*
+	 * @dst: Result of READ_ONCE(per_cpu(sym, smp_processor_id()))
+	 * @sym: The name of the per-cpu variable
+	 * @tmp: scratch register
+	 */
+	.macro ldr_this_cpu dst, sym, tmp
+	adr_l	\dst, \sym
+	mrs	\tmp, tpidr_el1
+	ldr	\dst, [\dst, \tmp]
 	.endm
 
 /*
diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S
index 441420c..52b4241 100644
--- a/arch/arm64/kernel/entry.S
+++ b/arch/arm64/kernel/entry.S
@@ -206,7 +206,7 @@ alternative_endif
 	cmp	x25, tsk
 	b.ne	9998f
 
-	this_cpu_ptr irq_stack, x25, x26
+	adr_this_cpu x25, irq_stack, x26
 	mov	x26, #IRQ_STACK_START_SP
 	add	x26, x25, x26
 
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [kernel-hardening] [RFC PATCH 5/8] arm64: assembler: introduce ldr_this_cpu
@ 2016-09-15 13:49   ` Mark Rutland
  0 siblings, 0 replies; 54+ messages in thread
From: Mark Rutland @ 2016-09-15 13:49 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: akpm, ard.biesheuvel, catalin.marinas, james.morse, keescook,
	linux-kernel, lorenzo.pieralisi, luto, mark.rutland,
	suzuki.poulose, takahiro.akashi, will.deacon, kernel-hardening

Shortly we will want to load a percpu variable in the return from
userspace path. We can save an instruction by folding the addition of
the percpu offset into the load instruction, and this patch adds a new
helper to do so.

At the same time, we clean up this_cpu_ptr for consistency. As with
{adr,ldr,str}_l, we change the template to take the destination register
first, and name this dst. Secondly, we rename the macro to adr_this_cpu,
following the scheme of adr_l, and matching the newly added
ldr_this_cpu.

Signed-off-by: Mark Rutland <mark.rutland@arm.com>
Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: James Morse <james.morse@arm.com>
Cc: Will Deacon <will.deacon@arm.com>
---
 arch/arm64/include/asm/assembler.h | 19 +++++++++++++++----
 arch/arm64/kernel/entry.S          |  2 +-
 2 files changed, 16 insertions(+), 5 deletions(-)

diff --git a/arch/arm64/include/asm/assembler.h b/arch/arm64/include/asm/assembler.h
index d5025c6..265fd81 100644
--- a/arch/arm64/include/asm/assembler.h
+++ b/arch/arm64/include/asm/assembler.h
@@ -193,14 +193,25 @@ lr	.req	x30		// link register
 	.endm
 
 	/*
+	 * @dst: Result of per_cpu(sym, smp_processor_id())
 	 * @sym: The name of the per-cpu variable
-	 * @reg: Result of per_cpu(sym, smp_processor_id())
 	 * @tmp: scratch register
 	 */
-	.macro this_cpu_ptr, sym, reg, tmp
-	adr_l	\reg, \sym
+	.macro adr_this_cpu, dst, sym, tmp
+	adr_l	\dst, \sym
 	mrs	\tmp, tpidr_el1
-	add	\reg, \reg, \tmp
+	add	\dst, \dst, \tmp
+	.endm
+
+	/*
+	 * @dst: Result of READ_ONCE(per_cpu(sym, smp_processor_id()))
+	 * @sym: The name of the per-cpu variable
+	 * @tmp: scratch register
+	 */
+	.macro ldr_this_cpu dst, sym, tmp
+	adr_l	\dst, \sym
+	mrs	\tmp, tpidr_el1
+	ldr	\dst, [\dst, \tmp]
 	.endm
 
 /*
diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S
index 441420c..52b4241 100644
--- a/arch/arm64/kernel/entry.S
+++ b/arch/arm64/kernel/entry.S
@@ -206,7 +206,7 @@ alternative_endif
 	cmp	x25, tsk
 	b.ne	9998f
 
-	this_cpu_ptr irq_stack, x25, x26
+	adr_this_cpu x25, irq_stack, x26
 	mov	x26, #IRQ_STACK_START_SP
 	add	x26, x25, x26
 
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [RFC PATCH 6/8] arm64: traps: use task_struct instead of thread_info
  2016-09-15 13:49 ` Mark Rutland
  (?)
@ 2016-09-15 13:49   ` Mark Rutland
  -1 siblings, 0 replies; 54+ messages in thread
From: Mark Rutland @ 2016-09-15 13:49 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: akpm, ard.biesheuvel, catalin.marinas, james.morse, keescook,
	linux-kernel, lorenzo.pieralisi, luto, mark.rutland,
	suzuki.poulose, takahiro.akashi, will.deacon, kernel-hardening

In arm64's die and __die routines we pass around a thread_info, and
subsequently use this to determine either the relevant task_struct, or
the end of the thread's stack. This will shortly become problematic when
we move the thread_info out of the thread's stack.

Instead, pass around the task_struct, and use the new end_of_stack
helper, which will work regardless of where thread_info is located.

Signed-off-by: Mark Rutland <mark.rutland@arm.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Will Deacon <will.deacon@arm.com>
---
 arch/arm64/kernel/traps.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/arch/arm64/kernel/traps.c b/arch/arm64/kernel/traps.c
index e04f838..e9409a9 100644
--- a/arch/arm64/kernel/traps.c
+++ b/arch/arm64/kernel/traps.c
@@ -227,10 +227,9 @@ void show_stack(struct task_struct *tsk, unsigned long *sp)
 #endif
 #define S_SMP " SMP"
 
-static int __die(const char *str, int err, struct thread_info *thread,
+static int __die(const char *str, int err, struct task_struct *tsk,
 		 struct pt_regs *regs)
 {
-	struct task_struct *tsk = thread->task;
 	static int die_counter;
 	int ret;
 
@@ -245,7 +244,8 @@ static int __die(const char *str, int err, struct thread_info *thread,
 	print_modules();
 	__show_regs(regs);
 	pr_emerg("Process %.*s (pid: %d, stack limit = 0x%p)\n",
-		 TASK_COMM_LEN, tsk->comm, task_pid_nr(tsk), thread + 1);
+		 TASK_COMM_LEN, tsk->comm, task_pid_nr(tsk),
+		 end_of_stack(tsk));
 
 	if (!user_mode(regs)) {
 		dump_mem(KERN_EMERG, "Stack: ", regs->sp,
@@ -264,7 +264,7 @@ static DEFINE_RAW_SPINLOCK(die_lock);
  */
 void die(const char *str, struct pt_regs *regs, int err)
 {
-	struct thread_info *thread = current_thread_info();
+	struct task_struct *tsk = current;
 	int ret;
 
 	oops_enter();
@@ -272,9 +272,9 @@ void die(const char *str, struct pt_regs *regs, int err)
 	raw_spin_lock_irq(&die_lock);
 	console_verbose();
 	bust_spinlocks(1);
-	ret = __die(str, err, thread, regs);
+	ret = __die(str, err, tsk, regs);
 
-	if (regs && kexec_should_crash(thread->task))
+	if (regs && kexec_should_crash(tsk))
 		crash_kexec(regs);
 
 	bust_spinlocks(0);
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [RFC PATCH 6/8] arm64: traps: use task_struct instead of thread_info
@ 2016-09-15 13:49   ` Mark Rutland
  0 siblings, 0 replies; 54+ messages in thread
From: Mark Rutland @ 2016-09-15 13:49 UTC (permalink / raw)
  To: linux-arm-kernel

In arm64's die and __die routines we pass around a thread_info, and
subsequently use this to determine either the relevant task_struct, or
the end of the thread's stack. This will shortly become problematic when
we move the thread_info out of the thread's stack.

Instead, pass around the task_struct, and use the new end_of_stack
helper, which will work regardless of where thread_info is located.

Signed-off-by: Mark Rutland <mark.rutland@arm.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Will Deacon <will.deacon@arm.com>
---
 arch/arm64/kernel/traps.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/arch/arm64/kernel/traps.c b/arch/arm64/kernel/traps.c
index e04f838..e9409a9 100644
--- a/arch/arm64/kernel/traps.c
+++ b/arch/arm64/kernel/traps.c
@@ -227,10 +227,9 @@ void show_stack(struct task_struct *tsk, unsigned long *sp)
 #endif
 #define S_SMP " SMP"
 
-static int __die(const char *str, int err, struct thread_info *thread,
+static int __die(const char *str, int err, struct task_struct *tsk,
 		 struct pt_regs *regs)
 {
-	struct task_struct *tsk = thread->task;
 	static int die_counter;
 	int ret;
 
@@ -245,7 +244,8 @@ static int __die(const char *str, int err, struct thread_info *thread,
 	print_modules();
 	__show_regs(regs);
 	pr_emerg("Process %.*s (pid: %d, stack limit = 0x%p)\n",
-		 TASK_COMM_LEN, tsk->comm, task_pid_nr(tsk), thread + 1);
+		 TASK_COMM_LEN, tsk->comm, task_pid_nr(tsk),
+		 end_of_stack(tsk));
 
 	if (!user_mode(regs)) {
 		dump_mem(KERN_EMERG, "Stack: ", regs->sp,
@@ -264,7 +264,7 @@ static DEFINE_RAW_SPINLOCK(die_lock);
  */
 void die(const char *str, struct pt_regs *regs, int err)
 {
-	struct thread_info *thread = current_thread_info();
+	struct task_struct *tsk = current;
 	int ret;
 
 	oops_enter();
@@ -272,9 +272,9 @@ void die(const char *str, struct pt_regs *regs, int err)
 	raw_spin_lock_irq(&die_lock);
 	console_verbose();
 	bust_spinlocks(1);
-	ret = __die(str, err, thread, regs);
+	ret = __die(str, err, tsk, regs);
 
-	if (regs && kexec_should_crash(thread->task))
+	if (regs && kexec_should_crash(tsk))
 		crash_kexec(regs);
 
 	bust_spinlocks(0);
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [kernel-hardening] [RFC PATCH 6/8] arm64: traps: use task_struct instead of thread_info
@ 2016-09-15 13:49   ` Mark Rutland
  0 siblings, 0 replies; 54+ messages in thread
From: Mark Rutland @ 2016-09-15 13:49 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: akpm, ard.biesheuvel, catalin.marinas, james.morse, keescook,
	linux-kernel, lorenzo.pieralisi, luto, mark.rutland,
	suzuki.poulose, takahiro.akashi, will.deacon, kernel-hardening

In arm64's die and __die routines we pass around a thread_info, and
subsequently use this to determine either the relevant task_struct, or
the end of the thread's stack. This will shortly become problematic when
we move the thread_info out of the thread's stack.

Instead, pass around the task_struct, and use the new end_of_stack
helper, which will work regardless of where thread_info is located.

Signed-off-by: Mark Rutland <mark.rutland@arm.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Will Deacon <will.deacon@arm.com>
---
 arch/arm64/kernel/traps.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/arch/arm64/kernel/traps.c b/arch/arm64/kernel/traps.c
index e04f838..e9409a9 100644
--- a/arch/arm64/kernel/traps.c
+++ b/arch/arm64/kernel/traps.c
@@ -227,10 +227,9 @@ void show_stack(struct task_struct *tsk, unsigned long *sp)
 #endif
 #define S_SMP " SMP"
 
-static int __die(const char *str, int err, struct thread_info *thread,
+static int __die(const char *str, int err, struct task_struct *tsk,
 		 struct pt_regs *regs)
 {
-	struct task_struct *tsk = thread->task;
 	static int die_counter;
 	int ret;
 
@@ -245,7 +244,8 @@ static int __die(const char *str, int err, struct thread_info *thread,
 	print_modules();
 	__show_regs(regs);
 	pr_emerg("Process %.*s (pid: %d, stack limit = 0x%p)\n",
-		 TASK_COMM_LEN, tsk->comm, task_pid_nr(tsk), thread + 1);
+		 TASK_COMM_LEN, tsk->comm, task_pid_nr(tsk),
+		 end_of_stack(tsk));
 
 	if (!user_mode(regs)) {
 		dump_mem(KERN_EMERG, "Stack: ", regs->sp,
@@ -264,7 +264,7 @@ static DEFINE_RAW_SPINLOCK(die_lock);
  */
 void die(const char *str, struct pt_regs *regs, int err)
 {
-	struct thread_info *thread = current_thread_info();
+	struct task_struct *tsk = current;
 	int ret;
 
 	oops_enter();
@@ -272,9 +272,9 @@ void die(const char *str, struct pt_regs *regs, int err)
 	raw_spin_lock_irq(&die_lock);
 	console_verbose();
 	bust_spinlocks(1);
-	ret = __die(str, err, thread, regs);
+	ret = __die(str, err, tsk, regs);
 
-	if (regs && kexec_should_crash(thread->task))
+	if (regs && kexec_should_crash(tsk))
 		crash_kexec(regs);
 
 	bust_spinlocks(0);
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [RFC PATCH 7/8] arm64: move sp_el0 and tpidr_el1 into cpu_suspend_ctx
  2016-09-15 13:49 ` Mark Rutland
  (?)
@ 2016-09-15 13:49   ` Mark Rutland
  -1 siblings, 0 replies; 54+ messages in thread
From: Mark Rutland @ 2016-09-15 13:49 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: akpm, ard.biesheuvel, catalin.marinas, james.morse, keescook,
	linux-kernel, lorenzo.pieralisi, luto, mark.rutland,
	suzuki.poulose, takahiro.akashi, will.deacon, kernel-hardening

When returning from idle, we rely on the fact that thread_info lives at
the end of the kernel stack, and restore this by masking the saved stack
pointer. Subsequent patches will sever the relationship between the
stack and thread_info, and to cater for this we must save/restore sp_el0
explicitly, storing it in cpu_suspend_ctx.

As cpu_suspend_ctx must be doubleword aligned, this leaves us with an
extra slot in cpu_suspend_ctx. We can use this to save/restore tpidr_el1
in the same way, which simplifies the code, avoiding pointer chasing on
the restore path (as we no longer need to load thread_info::cpu followed
by the relevant slot in __per_cpu_offset based on this).

This patch stashes both registers in cpu_suspend_ctx.

Signed-off-by: Mark Rutland <mark.rutland@arm.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: James Morse <james.morse@arm.com>
Cc: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Cc: Will Deacon <will.deacon@arm.com>
---
 arch/arm64/include/asm/suspend.h | 2 +-
 arch/arm64/kernel/sleep.S        | 3 ---
 arch/arm64/kernel/suspend.c      | 6 ------
 arch/arm64/mm/proc.S             | 6 ++++++
 4 files changed, 7 insertions(+), 10 deletions(-)

diff --git a/arch/arm64/include/asm/suspend.h b/arch/arm64/include/asm/suspend.h
index 024d623..92d6a62 100644
--- a/arch/arm64/include/asm/suspend.h
+++ b/arch/arm64/include/asm/suspend.h
@@ -1,7 +1,7 @@
 #ifndef __ASM_SUSPEND_H
 #define __ASM_SUSPEND_H
 
-#define NR_CTX_REGS 10
+#define NR_CTX_REGS 12
 #define NR_CALLEE_SAVED_REGS 12
 
 /*
diff --git a/arch/arm64/kernel/sleep.S b/arch/arm64/kernel/sleep.S
index ccf79d8..74e6e19 100644
--- a/arch/arm64/kernel/sleep.S
+++ b/arch/arm64/kernel/sleep.S
@@ -132,9 +132,6 @@ ENTRY(_cpu_resume)
 	/* load sp from context */
 	ldr	x2, [x0, #CPU_CTX_SP]
 	mov	sp, x2
-	/* save thread_info */
-	and	x2, x2, #~(THREAD_SIZE - 1)
-	msr	sp_el0, x2
 	/*
 	 * cpu_do_resume expects x0 to contain context address pointer
 	 */
diff --git a/arch/arm64/kernel/suspend.c b/arch/arm64/kernel/suspend.c
index b616e365..9c33a49 100644
--- a/arch/arm64/kernel/suspend.c
+++ b/arch/arm64/kernel/suspend.c
@@ -42,12 +42,6 @@ void notrace __cpu_suspend_exit(void)
 	cpu_uninstall_idmap();
 
 	/*
-	 * Restore per-cpu offset before any kernel
-	 * subsystem relying on it has a chance to run.
-	 */
-	set_my_cpu_offset(per_cpu_offset(smp_processor_id()));
-
-	/*
 	 * Restore HW breakpoint registers to sane values
 	 * before debug exceptions are possibly reenabled
 	 * through local_dbg_restore.
diff --git a/arch/arm64/mm/proc.S b/arch/arm64/mm/proc.S
index 5bb61de..0293db1 100644
--- a/arch/arm64/mm/proc.S
+++ b/arch/arm64/mm/proc.S
@@ -70,11 +70,14 @@ ENTRY(cpu_do_suspend)
 	mrs	x8, mdscr_el1
 	mrs	x9, oslsr_el1
 	mrs	x10, sctlr_el1
+	mrs	x11, tpidr_el1
+	mrs	x12, sp_el0
 	stp	x2, x3, [x0]
 	stp	x4, xzr, [x0, #16]
 	stp	x5, x6, [x0, #32]
 	stp	x7, x8, [x0, #48]
 	stp	x9, x10, [x0, #64]
+	stp	x11, x12, [x0, #80]
 	ret
 ENDPROC(cpu_do_suspend)
 
@@ -89,6 +92,7 @@ ENTRY(cpu_do_resume)
 	ldp	x6, x8, [x0, #32]
 	ldp	x9, x10, [x0, #48]
 	ldp	x11, x12, [x0, #64]
+	ldp	x13, x14, [x0, #80]
 	msr	tpidr_el0, x2
 	msr	tpidrro_el0, x3
 	msr	contextidr_el1, x4
@@ -102,6 +106,8 @@ ENTRY(cpu_do_resume)
 	msr	vbar_el1, x9
 	msr	mdscr_el1, x10
 	msr	sctlr_el1, x12
+	msr	tpidr_el1, x13
+	msr	sp_el0, x14
 	/*
 	 * Restore oslsr_el1 by writing oslar_el1
 	 */
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [RFC PATCH 7/8] arm64: move sp_el0 and tpidr_el1 into cpu_suspend_ctx
@ 2016-09-15 13:49   ` Mark Rutland
  0 siblings, 0 replies; 54+ messages in thread
From: Mark Rutland @ 2016-09-15 13:49 UTC (permalink / raw)
  To: linux-arm-kernel

When returning from idle, we rely on the fact that thread_info lives at
the end of the kernel stack, and restore this by masking the saved stack
pointer. Subsequent patches will sever the relationship between the
stack and thread_info, and to cater for this we must save/restore sp_el0
explicitly, storing it in cpu_suspend_ctx.

As cpu_suspend_ctx must be doubleword aligned, this leaves us with an
extra slot in cpu_suspend_ctx. We can use this to save/restore tpidr_el1
in the same way, which simplifies the code, avoiding pointer chasing on
the restore path (as we no longer need to load thread_info::cpu followed
by the relevant slot in __per_cpu_offset based on this).

This patch stashes both registers in cpu_suspend_ctx.

Signed-off-by: Mark Rutland <mark.rutland@arm.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: James Morse <james.morse@arm.com>
Cc: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Cc: Will Deacon <will.deacon@arm.com>
---
 arch/arm64/include/asm/suspend.h | 2 +-
 arch/arm64/kernel/sleep.S        | 3 ---
 arch/arm64/kernel/suspend.c      | 6 ------
 arch/arm64/mm/proc.S             | 6 ++++++
 4 files changed, 7 insertions(+), 10 deletions(-)

diff --git a/arch/arm64/include/asm/suspend.h b/arch/arm64/include/asm/suspend.h
index 024d623..92d6a62 100644
--- a/arch/arm64/include/asm/suspend.h
+++ b/arch/arm64/include/asm/suspend.h
@@ -1,7 +1,7 @@
 #ifndef __ASM_SUSPEND_H
 #define __ASM_SUSPEND_H
 
-#define NR_CTX_REGS 10
+#define NR_CTX_REGS 12
 #define NR_CALLEE_SAVED_REGS 12
 
 /*
diff --git a/arch/arm64/kernel/sleep.S b/arch/arm64/kernel/sleep.S
index ccf79d8..74e6e19 100644
--- a/arch/arm64/kernel/sleep.S
+++ b/arch/arm64/kernel/sleep.S
@@ -132,9 +132,6 @@ ENTRY(_cpu_resume)
 	/* load sp from context */
 	ldr	x2, [x0, #CPU_CTX_SP]
 	mov	sp, x2
-	/* save thread_info */
-	and	x2, x2, #~(THREAD_SIZE - 1)
-	msr	sp_el0, x2
 	/*
 	 * cpu_do_resume expects x0 to contain context address pointer
 	 */
diff --git a/arch/arm64/kernel/suspend.c b/arch/arm64/kernel/suspend.c
index b616e365..9c33a49 100644
--- a/arch/arm64/kernel/suspend.c
+++ b/arch/arm64/kernel/suspend.c
@@ -42,12 +42,6 @@ void notrace __cpu_suspend_exit(void)
 	cpu_uninstall_idmap();
 
 	/*
-	 * Restore per-cpu offset before any kernel
-	 * subsystem relying on it has a chance to run.
-	 */
-	set_my_cpu_offset(per_cpu_offset(smp_processor_id()));
-
-	/*
 	 * Restore HW breakpoint registers to sane values
 	 * before debug exceptions are possibly reenabled
 	 * through local_dbg_restore.
diff --git a/arch/arm64/mm/proc.S b/arch/arm64/mm/proc.S
index 5bb61de..0293db1 100644
--- a/arch/arm64/mm/proc.S
+++ b/arch/arm64/mm/proc.S
@@ -70,11 +70,14 @@ ENTRY(cpu_do_suspend)
 	mrs	x8, mdscr_el1
 	mrs	x9, oslsr_el1
 	mrs	x10, sctlr_el1
+	mrs	x11, tpidr_el1
+	mrs	x12, sp_el0
 	stp	x2, x3, [x0]
 	stp	x4, xzr, [x0, #16]
 	stp	x5, x6, [x0, #32]
 	stp	x7, x8, [x0, #48]
 	stp	x9, x10, [x0, #64]
+	stp	x11, x12, [x0, #80]
 	ret
 ENDPROC(cpu_do_suspend)
 
@@ -89,6 +92,7 @@ ENTRY(cpu_do_resume)
 	ldp	x6, x8, [x0, #32]
 	ldp	x9, x10, [x0, #48]
 	ldp	x11, x12, [x0, #64]
+	ldp	x13, x14, [x0, #80]
 	msr	tpidr_el0, x2
 	msr	tpidrro_el0, x3
 	msr	contextidr_el1, x4
@@ -102,6 +106,8 @@ ENTRY(cpu_do_resume)
 	msr	vbar_el1, x9
 	msr	mdscr_el1, x10
 	msr	sctlr_el1, x12
+	msr	tpidr_el1, x13
+	msr	sp_el0, x14
 	/*
 	 * Restore oslsr_el1 by writing oslar_el1
 	 */
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [kernel-hardening] [RFC PATCH 7/8] arm64: move sp_el0 and tpidr_el1 into cpu_suspend_ctx
@ 2016-09-15 13:49   ` Mark Rutland
  0 siblings, 0 replies; 54+ messages in thread
From: Mark Rutland @ 2016-09-15 13:49 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: akpm, ard.biesheuvel, catalin.marinas, james.morse, keescook,
	linux-kernel, lorenzo.pieralisi, luto, mark.rutland,
	suzuki.poulose, takahiro.akashi, will.deacon, kernel-hardening

When returning from idle, we rely on the fact that thread_info lives at
the end of the kernel stack, and restore this by masking the saved stack
pointer. Subsequent patches will sever the relationship between the
stack and thread_info, and to cater for this we must save/restore sp_el0
explicitly, storing it in cpu_suspend_ctx.

As cpu_suspend_ctx must be doubleword aligned, this leaves us with an
extra slot in cpu_suspend_ctx. We can use this to save/restore tpidr_el1
in the same way, which simplifies the code, avoiding pointer chasing on
the restore path (as we no longer need to load thread_info::cpu followed
by the relevant slot in __per_cpu_offset based on this).

This patch stashes both registers in cpu_suspend_ctx.

Signed-off-by: Mark Rutland <mark.rutland@arm.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: James Morse <james.morse@arm.com>
Cc: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Cc: Will Deacon <will.deacon@arm.com>
---
 arch/arm64/include/asm/suspend.h | 2 +-
 arch/arm64/kernel/sleep.S        | 3 ---
 arch/arm64/kernel/suspend.c      | 6 ------
 arch/arm64/mm/proc.S             | 6 ++++++
 4 files changed, 7 insertions(+), 10 deletions(-)

diff --git a/arch/arm64/include/asm/suspend.h b/arch/arm64/include/asm/suspend.h
index 024d623..92d6a62 100644
--- a/arch/arm64/include/asm/suspend.h
+++ b/arch/arm64/include/asm/suspend.h
@@ -1,7 +1,7 @@
 #ifndef __ASM_SUSPEND_H
 #define __ASM_SUSPEND_H
 
-#define NR_CTX_REGS 10
+#define NR_CTX_REGS 12
 #define NR_CALLEE_SAVED_REGS 12
 
 /*
diff --git a/arch/arm64/kernel/sleep.S b/arch/arm64/kernel/sleep.S
index ccf79d8..74e6e19 100644
--- a/arch/arm64/kernel/sleep.S
+++ b/arch/arm64/kernel/sleep.S
@@ -132,9 +132,6 @@ ENTRY(_cpu_resume)
 	/* load sp from context */
 	ldr	x2, [x0, #CPU_CTX_SP]
 	mov	sp, x2
-	/* save thread_info */
-	and	x2, x2, #~(THREAD_SIZE - 1)
-	msr	sp_el0, x2
 	/*
 	 * cpu_do_resume expects x0 to contain context address pointer
 	 */
diff --git a/arch/arm64/kernel/suspend.c b/arch/arm64/kernel/suspend.c
index b616e365..9c33a49 100644
--- a/arch/arm64/kernel/suspend.c
+++ b/arch/arm64/kernel/suspend.c
@@ -42,12 +42,6 @@ void notrace __cpu_suspend_exit(void)
 	cpu_uninstall_idmap();
 
 	/*
-	 * Restore per-cpu offset before any kernel
-	 * subsystem relying on it has a chance to run.
-	 */
-	set_my_cpu_offset(per_cpu_offset(smp_processor_id()));
-
-	/*
 	 * Restore HW breakpoint registers to sane values
 	 * before debug exceptions are possibly reenabled
 	 * through local_dbg_restore.
diff --git a/arch/arm64/mm/proc.S b/arch/arm64/mm/proc.S
index 5bb61de..0293db1 100644
--- a/arch/arm64/mm/proc.S
+++ b/arch/arm64/mm/proc.S
@@ -70,11 +70,14 @@ ENTRY(cpu_do_suspend)
 	mrs	x8, mdscr_el1
 	mrs	x9, oslsr_el1
 	mrs	x10, sctlr_el1
+	mrs	x11, tpidr_el1
+	mrs	x12, sp_el0
 	stp	x2, x3, [x0]
 	stp	x4, xzr, [x0, #16]
 	stp	x5, x6, [x0, #32]
 	stp	x7, x8, [x0, #48]
 	stp	x9, x10, [x0, #64]
+	stp	x11, x12, [x0, #80]
 	ret
 ENDPROC(cpu_do_suspend)
 
@@ -89,6 +92,7 @@ ENTRY(cpu_do_resume)
 	ldp	x6, x8, [x0, #32]
 	ldp	x9, x10, [x0, #48]
 	ldp	x11, x12, [x0, #64]
+	ldp	x13, x14, [x0, #80]
 	msr	tpidr_el0, x2
 	msr	tpidrro_el0, x3
 	msr	contextidr_el1, x4
@@ -102,6 +106,8 @@ ENTRY(cpu_do_resume)
 	msr	vbar_el1, x9
 	msr	mdscr_el1, x10
 	msr	sctlr_el1, x12
+	msr	tpidr_el1, x13
+	msr	sp_el0, x14
 	/*
 	 * Restore oslsr_el1 by writing oslar_el1
 	 */
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [RFC PATCH 8/8] arm64: split thread_info from task stack
  2016-09-15 13:49 ` Mark Rutland
  (?)
@ 2016-09-15 13:49   ` Mark Rutland
  -1 siblings, 0 replies; 54+ messages in thread
From: Mark Rutland @ 2016-09-15 13:49 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: akpm, ard.biesheuvel, catalin.marinas, james.morse, keescook,
	linux-kernel, lorenzo.pieralisi, luto, mark.rutland,
	suzuki.poulose, takahiro.akashi, will.deacon, kernel-hardening

This patch moves arm64's struct thread_info from the task stack into
task_struct. This protects thread_info from corruption in the case of
stack overflows, and makes its address harder to determine if stack
addresses are leaked, making a number of attacks more difficult. Precise
detection and handling of overflow is left for subsequent patches.

Largely, this involves changing code to store the task_struct in sp_el0,
and acquire the thread_info from the task struct (which is the opposite
way around to the current code). Both secondary entry and idle are
updated to stash the sp and task pointer separately.

Userspace clobbers sp_el0, and we can no longer restore this from the
stack. Instead, the current task is cached in a per-cpu variable that we
can safely access from early assembly as interrupts are disabled (and we
are thus not preemptible).

There remain opportunities for improvement. Currently we cannot remove
thread_info::cpu and always use task_struct::cpu, as this would result
in a circular include dependency for raw_smp_processor_id():

  <asm/smp.h> -> <linux/sched.h> -> <linux/smp.h> -> <asm/smp.h>

Signed-off-by: Mark Rutland <mark.rutland@arm.com>
Cc: AKASHI Takahiro <takahiro.akashi@linaro.org>
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: James Morse <james.morse@arm.com>
Cc: Kees Cook <keescook@chromium.org>
Cc: Suzuki K Poulose <suzuki.poulose@arm.com>
Cc: Will Deacon <will.deacon@arm.com>
---
 arch/arm64/Kconfig                   |  2 ++
 arch/arm64/include/asm/Kbuild        |  1 -
 arch/arm64/include/asm/current.h     | 22 ++++++++++++++++++++++
 arch/arm64/include/asm/smp.h         |  1 +
 arch/arm64/include/asm/thread_info.h | 19 -------------------
 arch/arm64/kernel/asm-offsets.c      |  1 +
 arch/arm64/kernel/entry.S            |  4 ++--
 arch/arm64/kernel/head.S             | 11 +++++------
 arch/arm64/kernel/process.c          | 31 ++++++++++++++++++++++++++-----
 arch/arm64/kernel/smp.c              |  2 ++
 arch/arm64/kernel/stacktrace.c       |  5 +++++
 11 files changed, 66 insertions(+), 33 deletions(-)
 create mode 100644 arch/arm64/include/asm/current.h

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index bc3f00f..9f57318 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -11,6 +11,7 @@ config ARM64
 	select ARCH_HAS_GCOV_PROFILE_ALL
 	select ARCH_HAS_KCOV
 	select ARCH_HAS_SG_CHAIN
+	select ARCH_HAS_OWN_THREAD_INFO
 	select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST
 	select ARCH_USE_CMPXCHG_LOCKREF
 	select ARCH_SUPPORTS_ATOMIC_RMW
@@ -110,6 +111,7 @@ config ARM64
 	select POWER_SUPPLY
 	select SPARSE_IRQ
 	select SYSCTL_EXCEPTION_TRACE
+	select THREAD_INFO_IN_TASK
 	help
 	  ARM 64-bit (AArch64) Linux support.
 
diff --git a/arch/arm64/include/asm/Kbuild b/arch/arm64/include/asm/Kbuild
index f43d2c4..a716c6f 100644
--- a/arch/arm64/include/asm/Kbuild
+++ b/arch/arm64/include/asm/Kbuild
@@ -2,7 +2,6 @@ generic-y += bug.h
 generic-y += bugs.h
 generic-y += clkdev.h
 generic-y += cputime.h
-generic-y += current.h
 generic-y += delay.h
 generic-y += div64.h
 generic-y += dma.h
diff --git a/arch/arm64/include/asm/current.h b/arch/arm64/include/asm/current.h
new file mode 100644
index 0000000..f2bcbe2
--- /dev/null
+++ b/arch/arm64/include/asm/current.h
@@ -0,0 +1,22 @@
+#ifndef __ASM_CURRENT_H
+#define __ASM_CURRENT_H
+
+#include <linux/compiler.h>
+
+#include <asm/sysreg.h>
+
+#ifndef __ASSEMBLY__
+
+struct task_struct;
+
+static __always_inline struct task_struct *get_current(void)
+{
+	return (struct task_struct *)read_sysreg(sp_el0);
+}
+
+#define current get_current()
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* __ASM_CURRENT_H */
+
diff --git a/arch/arm64/include/asm/smp.h b/arch/arm64/include/asm/smp.h
index 0226447..fef90c0 100644
--- a/arch/arm64/include/asm/smp.h
+++ b/arch/arm64/include/asm/smp.h
@@ -73,6 +73,7 @@ asmlinkage void secondary_start_kernel(void);
  */
 struct secondary_data {
 	void *stack;
+	struct task_struct *task;
 	long status;
 };
 
diff --git a/arch/arm64/include/asm/thread_info.h b/arch/arm64/include/asm/thread_info.h
index 796af24..5b16b34 100644
--- a/arch/arm64/include/asm/thread_info.h
+++ b/arch/arm64/include/asm/thread_info.h
@@ -46,14 +46,12 @@ typedef unsigned long mm_segment_t;
 struct thread_info {
 	unsigned long		flags;		/* low level flags */
 	mm_segment_t		addr_limit;	/* address limit */
-	struct task_struct	*task;		/* main task structure */
 	int			preempt_count;	/* 0 => preemptable, <0 => bug */
 	int			cpu;		/* cpu */
 };
 
 #define INIT_THREAD_INFO(tsk)						\
 {									\
-	.task		= &tsk,						\
 	.flags		= 0,						\
 	.preempt_count	= INIT_PREEMPT_COUNT,				\
 	.addr_limit	= KERNEL_DS,					\
@@ -66,23 +64,6 @@ struct thread_info {
  */
 register unsigned long current_stack_pointer asm ("sp");
 
-/*
- * how to get the thread information struct from C
- */
-static inline struct thread_info *current_thread_info(void) __attribute_const__;
-
-/*
- * struct thread_info can be accessed directly via sp_el0.
- */
-static inline struct thread_info *current_thread_info(void)
-{
-	unsigned long sp_el0;
-
-	asm ("mrs %0, sp_el0" : "=r" (sp_el0));
-
-	return (struct thread_info *)sp_el0;
-}
-
 #define thread_saved_pc(tsk)	\
 	((unsigned long)(tsk->thread.cpu_context.pc))
 #define thread_saved_sp(tsk)	\
diff --git a/arch/arm64/kernel/asm-offsets.c b/arch/arm64/kernel/asm-offsets.c
index ee764eb..242fe909 100644
--- a/arch/arm64/kernel/asm-offsets.c
+++ b/arch/arm64/kernel/asm-offsets.c
@@ -120,6 +120,7 @@ int main(void)
   DEFINE(TZ_DSTTIME,		offsetof(struct timezone, tz_dsttime));
   BLANK();
   DEFINE(CPU_BOOT_STACK,	offsetof(struct secondary_data, stack));
+  DEFINE(CPU_BOOT_TASK,		offsetof(struct secondary_data, task));
   BLANK();
 #ifdef CONFIG_KVM_ARM_HOST
   DEFINE(VCPU_CONTEXT,		offsetof(struct kvm_vcpu, arch.ctxt));
diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S
index 52b4241..f844e7f 100644
--- a/arch/arm64/kernel/entry.S
+++ b/arch/arm64/kernel/entry.S
@@ -123,6 +123,7 @@
 	 * Set sp_el0 to current thread_info.
 	 */
 	.if	\el == 0
+	ldr_this_cpu	tsk, __entry_task, x21
 	msr	sp_el0, tsk
 	.endif
 
@@ -680,8 +681,7 @@ ENTRY(cpu_switch_to)
 	ldp	x29, x9, [x8], #16
 	ldr	lr, [x8]
 	mov	sp, x9
-	and	x9, x9, #~(THREAD_SIZE - 1)
-	msr	sp_el0, x9
+	msr	sp_el0, x1
 	ret
 ENDPROC(cpu_switch_to)
 
diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S
index b77f583..abc7330 100644
--- a/arch/arm64/kernel/head.S
+++ b/arch/arm64/kernel/head.S
@@ -433,8 +433,7 @@ __primary_switched:
 	dsb	ishst				// Make zero page visible to PTW
 
 	adr_l	sp, initial_sp, x4
-	mov	x4, sp
-	and	x4, x4, #~(THREAD_SIZE - 1)
+	adr_l	x4, init_task
 	msr	sp_el0, x4			// Save thread_info
 	str_l	x21, __fdt_pointer, x5		// Save FDT pointer
 
@@ -680,10 +679,10 @@ __secondary_switched:
 	isb
 
 	adr_l	x0, secondary_data
-	ldr	x0, [x0, #CPU_BOOT_STACK]	// get secondary_data.stack
-	mov	sp, x0
-	and	x0, x0, #~(THREAD_SIZE - 1)
-	msr	sp_el0, x0			// save thread_info
+	ldr	x1, [x0, #CPU_BOOT_STACK]	// get secondary_data.stack
+	mov	sp, x1
+	ldr	x2, [x0, #CPU_BOOT_TASK]
+	msr	sp_el0, x2
 	mov	x29, #0
 	b	secondary_start_kernel
 ENDPROC(__secondary_switched)
diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c
index 6cd2612..e35043d 100644
--- a/arch/arm64/kernel/process.c
+++ b/arch/arm64/kernel/process.c
@@ -45,6 +45,7 @@
 #include <linux/personality.h>
 #include <linux/notifier.h>
 #include <trace/events/power.h>
+#include <linux/percpu.h>
 
 #include <asm/alternative.h>
 #include <asm/compat.h>
@@ -314,6 +315,17 @@ static void uao_thread_switch(struct task_struct *next)
 }
 
 /*
+ * We store our current task in sp_el0, which is clobbered by userspace. Keep a
+ * shadow copy so that we can restore this upon entry from userspace.
+ */
+DEFINE_PER_CPU(struct task_struct *, __entry_task) = &init_task;
+
+static void entry_task_switch(struct task_struct *next)
+{
+	__this_cpu_write(__entry_task, next);
+}
+
+/*
  * Thread switching.
  */
 struct task_struct *__switch_to(struct task_struct *prev,
@@ -325,6 +337,7 @@ struct task_struct *__switch_to(struct task_struct *prev,
 	tls_thread_switch(next);
 	hw_breakpoint_thread_switch(next);
 	contextidr_thread_switch(next);
+	entry_task_switch(next);
 	uao_thread_switch(next);
 
 	/*
@@ -342,11 +355,14 @@ struct task_struct *__switch_to(struct task_struct *prev,
 unsigned long get_wchan(struct task_struct *p)
 {
 	struct stackframe frame;
-	unsigned long stack_page;
+	unsigned long stack_page, ret = 0;
 	int count = 0;
 	if (!p || p == current || p->state == TASK_RUNNING)
 		return 0;
 
+	if (!try_get_task_stack(p))
+		return 0;
+
 	frame.fp = thread_saved_fp(p);
 	frame.sp = thread_saved_sp(p);
 	frame.pc = thread_saved_pc(p);
@@ -358,11 +374,16 @@ unsigned long get_wchan(struct task_struct *p)
 		if (frame.sp < stack_page ||
 		    frame.sp >= stack_page + THREAD_SIZE ||
 		    unwind_frame(p, &frame))
-			return 0;
-		if (!in_sched_functions(frame.pc))
-			return frame.pc;
+			goto out;
+		if (!in_sched_functions(frame.pc)) {
+			ret = frame.pc;
+			goto out;
+		}
 	} while (count ++ < 16);
-	return 0;
+
+out:
+	put_task_stack(p);
+	return ret;
 }
 
 unsigned long arch_align_stack(unsigned long sp)
diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c
index d93d433..d84be9db 100644
--- a/arch/arm64/kernel/smp.c
+++ b/arch/arm64/kernel/smp.c
@@ -146,6 +146,7 @@ int __cpu_up(unsigned int cpu, struct task_struct *idle)
 	 * We need to tell the secondary core where to find its stack and the
 	 * page tables.
 	 */
+	secondary_data.task = idle;
 	secondary_data.stack = task_stack_page(idle) + THREAD_START_SP;
 	update_cpu_boot_status(CPU_MMU_OFF);
 	__flush_dcache_area(&secondary_data, sizeof(secondary_data));
@@ -170,6 +171,7 @@ int __cpu_up(unsigned int cpu, struct task_struct *idle)
 		pr_err("CPU%u: failed to boot: %d\n", cpu, ret);
 	}
 
+	secondary_data.task = NULL;
 	secondary_data.stack = NULL;
 	status = READ_ONCE(secondary_data.status);
 	if (ret && status) {
diff --git a/arch/arm64/kernel/stacktrace.c b/arch/arm64/kernel/stacktrace.c
index d9751a4..4e0efe8 100644
--- a/arch/arm64/kernel/stacktrace.c
+++ b/arch/arm64/kernel/stacktrace.c
@@ -157,6 +157,9 @@ void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace)
 	struct stack_trace_data data;
 	struct stackframe frame;
 
+	if (!try_get_task_stack(tsk))
+		return;
+
 	data.trace = trace;
 	data.skip = trace->skip;
 
@@ -178,6 +181,8 @@ void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace)
 	walk_stackframe(tsk, &frame, save_trace, &data);
 	if (trace->nr_entries < trace->max_entries)
 		trace->entries[trace->nr_entries++] = ULONG_MAX;
+
+	put_task_stack(tsk);
 }
 
 void save_stack_trace(struct stack_trace *trace)
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [RFC PATCH 8/8] arm64: split thread_info from task stack
@ 2016-09-15 13:49   ` Mark Rutland
  0 siblings, 0 replies; 54+ messages in thread
From: Mark Rutland @ 2016-09-15 13:49 UTC (permalink / raw)
  To: linux-arm-kernel

This patch moves arm64's struct thread_info from the task stack into
task_struct. This protects thread_info from corruption in the case of
stack overflows, and makes its address harder to determine if stack
addresses are leaked, making a number of attacks more difficult. Precise
detection and handling of overflow is left for subsequent patches.

Largely, this involves changing code to store the task_struct in sp_el0,
and acquire the thread_info from the task struct (which is the opposite
way around to the current code). Both secondary entry and idle are
updated to stash the sp and task pointer separately.

Userspace clobbers sp_el0, and we can no longer restore this from the
stack. Instead, the current task is cached in a per-cpu variable that we
can safely access from early assembly as interrupts are disabled (and we
are thus not preemptible).

There remain opportunities for improvement. Currently we cannot remove
thread_info::cpu and always use task_struct::cpu, as this would result
in a circular include dependency for raw_smp_processor_id():

  <asm/smp.h> -> <linux/sched.h> -> <linux/smp.h> -> <asm/smp.h>

Signed-off-by: Mark Rutland <mark.rutland@arm.com>
Cc: AKASHI Takahiro <takahiro.akashi@linaro.org>
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: James Morse <james.morse@arm.com>
Cc: Kees Cook <keescook@chromium.org>
Cc: Suzuki K Poulose <suzuki.poulose@arm.com>
Cc: Will Deacon <will.deacon@arm.com>
---
 arch/arm64/Kconfig                   |  2 ++
 arch/arm64/include/asm/Kbuild        |  1 -
 arch/arm64/include/asm/current.h     | 22 ++++++++++++++++++++++
 arch/arm64/include/asm/smp.h         |  1 +
 arch/arm64/include/asm/thread_info.h | 19 -------------------
 arch/arm64/kernel/asm-offsets.c      |  1 +
 arch/arm64/kernel/entry.S            |  4 ++--
 arch/arm64/kernel/head.S             | 11 +++++------
 arch/arm64/kernel/process.c          | 31 ++++++++++++++++++++++++++-----
 arch/arm64/kernel/smp.c              |  2 ++
 arch/arm64/kernel/stacktrace.c       |  5 +++++
 11 files changed, 66 insertions(+), 33 deletions(-)
 create mode 100644 arch/arm64/include/asm/current.h

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index bc3f00f..9f57318 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -11,6 +11,7 @@ config ARM64
 	select ARCH_HAS_GCOV_PROFILE_ALL
 	select ARCH_HAS_KCOV
 	select ARCH_HAS_SG_CHAIN
+	select ARCH_HAS_OWN_THREAD_INFO
 	select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST
 	select ARCH_USE_CMPXCHG_LOCKREF
 	select ARCH_SUPPORTS_ATOMIC_RMW
@@ -110,6 +111,7 @@ config ARM64
 	select POWER_SUPPLY
 	select SPARSE_IRQ
 	select SYSCTL_EXCEPTION_TRACE
+	select THREAD_INFO_IN_TASK
 	help
 	  ARM 64-bit (AArch64) Linux support.
 
diff --git a/arch/arm64/include/asm/Kbuild b/arch/arm64/include/asm/Kbuild
index f43d2c4..a716c6f 100644
--- a/arch/arm64/include/asm/Kbuild
+++ b/arch/arm64/include/asm/Kbuild
@@ -2,7 +2,6 @@ generic-y += bug.h
 generic-y += bugs.h
 generic-y += clkdev.h
 generic-y += cputime.h
-generic-y += current.h
 generic-y += delay.h
 generic-y += div64.h
 generic-y += dma.h
diff --git a/arch/arm64/include/asm/current.h b/arch/arm64/include/asm/current.h
new file mode 100644
index 0000000..f2bcbe2
--- /dev/null
+++ b/arch/arm64/include/asm/current.h
@@ -0,0 +1,22 @@
+#ifndef __ASM_CURRENT_H
+#define __ASM_CURRENT_H
+
+#include <linux/compiler.h>
+
+#include <asm/sysreg.h>
+
+#ifndef __ASSEMBLY__
+
+struct task_struct;
+
+static __always_inline struct task_struct *get_current(void)
+{
+	return (struct task_struct *)read_sysreg(sp_el0);
+}
+
+#define current get_current()
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* __ASM_CURRENT_H */
+
diff --git a/arch/arm64/include/asm/smp.h b/arch/arm64/include/asm/smp.h
index 0226447..fef90c0 100644
--- a/arch/arm64/include/asm/smp.h
+++ b/arch/arm64/include/asm/smp.h
@@ -73,6 +73,7 @@ asmlinkage void secondary_start_kernel(void);
  */
 struct secondary_data {
 	void *stack;
+	struct task_struct *task;
 	long status;
 };
 
diff --git a/arch/arm64/include/asm/thread_info.h b/arch/arm64/include/asm/thread_info.h
index 796af24..5b16b34 100644
--- a/arch/arm64/include/asm/thread_info.h
+++ b/arch/arm64/include/asm/thread_info.h
@@ -46,14 +46,12 @@ typedef unsigned long mm_segment_t;
 struct thread_info {
 	unsigned long		flags;		/* low level flags */
 	mm_segment_t		addr_limit;	/* address limit */
-	struct task_struct	*task;		/* main task structure */
 	int			preempt_count;	/* 0 => preemptable, <0 => bug */
 	int			cpu;		/* cpu */
 };
 
 #define INIT_THREAD_INFO(tsk)						\
 {									\
-	.task		= &tsk,						\
 	.flags		= 0,						\
 	.preempt_count	= INIT_PREEMPT_COUNT,				\
 	.addr_limit	= KERNEL_DS,					\
@@ -66,23 +64,6 @@ struct thread_info {
  */
 register unsigned long current_stack_pointer asm ("sp");
 
-/*
- * how to get the thread information struct from C
- */
-static inline struct thread_info *current_thread_info(void) __attribute_const__;
-
-/*
- * struct thread_info can be accessed directly via sp_el0.
- */
-static inline struct thread_info *current_thread_info(void)
-{
-	unsigned long sp_el0;
-
-	asm ("mrs %0, sp_el0" : "=r" (sp_el0));
-
-	return (struct thread_info *)sp_el0;
-}
-
 #define thread_saved_pc(tsk)	\
 	((unsigned long)(tsk->thread.cpu_context.pc))
 #define thread_saved_sp(tsk)	\
diff --git a/arch/arm64/kernel/asm-offsets.c b/arch/arm64/kernel/asm-offsets.c
index ee764eb..242fe909 100644
--- a/arch/arm64/kernel/asm-offsets.c
+++ b/arch/arm64/kernel/asm-offsets.c
@@ -120,6 +120,7 @@ int main(void)
   DEFINE(TZ_DSTTIME,		offsetof(struct timezone, tz_dsttime));
   BLANK();
   DEFINE(CPU_BOOT_STACK,	offsetof(struct secondary_data, stack));
+  DEFINE(CPU_BOOT_TASK,		offsetof(struct secondary_data, task));
   BLANK();
 #ifdef CONFIG_KVM_ARM_HOST
   DEFINE(VCPU_CONTEXT,		offsetof(struct kvm_vcpu, arch.ctxt));
diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S
index 52b4241..f844e7f 100644
--- a/arch/arm64/kernel/entry.S
+++ b/arch/arm64/kernel/entry.S
@@ -123,6 +123,7 @@
 	 * Set sp_el0 to current thread_info.
 	 */
 	.if	\el == 0
+	ldr_this_cpu	tsk, __entry_task, x21
 	msr	sp_el0, tsk
 	.endif
 
@@ -680,8 +681,7 @@ ENTRY(cpu_switch_to)
 	ldp	x29, x9, [x8], #16
 	ldr	lr, [x8]
 	mov	sp, x9
-	and	x9, x9, #~(THREAD_SIZE - 1)
-	msr	sp_el0, x9
+	msr	sp_el0, x1
 	ret
 ENDPROC(cpu_switch_to)
 
diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S
index b77f583..abc7330 100644
--- a/arch/arm64/kernel/head.S
+++ b/arch/arm64/kernel/head.S
@@ -433,8 +433,7 @@ __primary_switched:
 	dsb	ishst				// Make zero page visible to PTW
 
 	adr_l	sp, initial_sp, x4
-	mov	x4, sp
-	and	x4, x4, #~(THREAD_SIZE - 1)
+	adr_l	x4, init_task
 	msr	sp_el0, x4			// Save thread_info
 	str_l	x21, __fdt_pointer, x5		// Save FDT pointer
 
@@ -680,10 +679,10 @@ __secondary_switched:
 	isb
 
 	adr_l	x0, secondary_data
-	ldr	x0, [x0, #CPU_BOOT_STACK]	// get secondary_data.stack
-	mov	sp, x0
-	and	x0, x0, #~(THREAD_SIZE - 1)
-	msr	sp_el0, x0			// save thread_info
+	ldr	x1, [x0, #CPU_BOOT_STACK]	// get secondary_data.stack
+	mov	sp, x1
+	ldr	x2, [x0, #CPU_BOOT_TASK]
+	msr	sp_el0, x2
 	mov	x29, #0
 	b	secondary_start_kernel
 ENDPROC(__secondary_switched)
diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c
index 6cd2612..e35043d 100644
--- a/arch/arm64/kernel/process.c
+++ b/arch/arm64/kernel/process.c
@@ -45,6 +45,7 @@
 #include <linux/personality.h>
 #include <linux/notifier.h>
 #include <trace/events/power.h>
+#include <linux/percpu.h>
 
 #include <asm/alternative.h>
 #include <asm/compat.h>
@@ -314,6 +315,17 @@ static void uao_thread_switch(struct task_struct *next)
 }
 
 /*
+ * We store our current task in sp_el0, which is clobbered by userspace. Keep a
+ * shadow copy so that we can restore this upon entry from userspace.
+ */
+DEFINE_PER_CPU(struct task_struct *, __entry_task) = &init_task;
+
+static void entry_task_switch(struct task_struct *next)
+{
+	__this_cpu_write(__entry_task, next);
+}
+
+/*
  * Thread switching.
  */
 struct task_struct *__switch_to(struct task_struct *prev,
@@ -325,6 +337,7 @@ struct task_struct *__switch_to(struct task_struct *prev,
 	tls_thread_switch(next);
 	hw_breakpoint_thread_switch(next);
 	contextidr_thread_switch(next);
+	entry_task_switch(next);
 	uao_thread_switch(next);
 
 	/*
@@ -342,11 +355,14 @@ struct task_struct *__switch_to(struct task_struct *prev,
 unsigned long get_wchan(struct task_struct *p)
 {
 	struct stackframe frame;
-	unsigned long stack_page;
+	unsigned long stack_page, ret = 0;
 	int count = 0;
 	if (!p || p == current || p->state == TASK_RUNNING)
 		return 0;
 
+	if (!try_get_task_stack(p))
+		return 0;
+
 	frame.fp = thread_saved_fp(p);
 	frame.sp = thread_saved_sp(p);
 	frame.pc = thread_saved_pc(p);
@@ -358,11 +374,16 @@ unsigned long get_wchan(struct task_struct *p)
 		if (frame.sp < stack_page ||
 		    frame.sp >= stack_page + THREAD_SIZE ||
 		    unwind_frame(p, &frame))
-			return 0;
-		if (!in_sched_functions(frame.pc))
-			return frame.pc;
+			goto out;
+		if (!in_sched_functions(frame.pc)) {
+			ret = frame.pc;
+			goto out;
+		}
 	} while (count ++ < 16);
-	return 0;
+
+out:
+	put_task_stack(p);
+	return ret;
 }
 
 unsigned long arch_align_stack(unsigned long sp)
diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c
index d93d433..d84be9db 100644
--- a/arch/arm64/kernel/smp.c
+++ b/arch/arm64/kernel/smp.c
@@ -146,6 +146,7 @@ int __cpu_up(unsigned int cpu, struct task_struct *idle)
 	 * We need to tell the secondary core where to find its stack and the
 	 * page tables.
 	 */
+	secondary_data.task = idle;
 	secondary_data.stack = task_stack_page(idle) + THREAD_START_SP;
 	update_cpu_boot_status(CPU_MMU_OFF);
 	__flush_dcache_area(&secondary_data, sizeof(secondary_data));
@@ -170,6 +171,7 @@ int __cpu_up(unsigned int cpu, struct task_struct *idle)
 		pr_err("CPU%u: failed to boot: %d\n", cpu, ret);
 	}
 
+	secondary_data.task = NULL;
 	secondary_data.stack = NULL;
 	status = READ_ONCE(secondary_data.status);
 	if (ret && status) {
diff --git a/arch/arm64/kernel/stacktrace.c b/arch/arm64/kernel/stacktrace.c
index d9751a4..4e0efe8 100644
--- a/arch/arm64/kernel/stacktrace.c
+++ b/arch/arm64/kernel/stacktrace.c
@@ -157,6 +157,9 @@ void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace)
 	struct stack_trace_data data;
 	struct stackframe frame;
 
+	if (!try_get_task_stack(tsk))
+		return;
+
 	data.trace = trace;
 	data.skip = trace->skip;
 
@@ -178,6 +181,8 @@ void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace)
 	walk_stackframe(tsk, &frame, save_trace, &data);
 	if (trace->nr_entries < trace->max_entries)
 		trace->entries[trace->nr_entries++] = ULONG_MAX;
+
+	put_task_stack(tsk);
 }
 
 void save_stack_trace(struct stack_trace *trace)
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [kernel-hardening] [RFC PATCH 8/8] arm64: split thread_info from task stack
@ 2016-09-15 13:49   ` Mark Rutland
  0 siblings, 0 replies; 54+ messages in thread
From: Mark Rutland @ 2016-09-15 13:49 UTC (permalink / raw)
  To: linux-arm-kernel
  Cc: akpm, ard.biesheuvel, catalin.marinas, james.morse, keescook,
	linux-kernel, lorenzo.pieralisi, luto, mark.rutland,
	suzuki.poulose, takahiro.akashi, will.deacon, kernel-hardening

This patch moves arm64's struct thread_info from the task stack into
task_struct. This protects thread_info from corruption in the case of
stack overflows, and makes its address harder to determine if stack
addresses are leaked, making a number of attacks more difficult. Precise
detection and handling of overflow is left for subsequent patches.

Largely, this involves changing code to store the task_struct in sp_el0,
and acquire the thread_info from the task struct (which is the opposite
way around to the current code). Both secondary entry and idle are
updated to stash the sp and task pointer separately.

Userspace clobbers sp_el0, and we can no longer restore this from the
stack. Instead, the current task is cached in a per-cpu variable that we
can safely access from early assembly as interrupts are disabled (and we
are thus not preemptible).

There remain opportunities for improvement. Currently we cannot remove
thread_info::cpu and always use task_struct::cpu, as this would result
in a circular include dependency for raw_smp_processor_id():

  <asm/smp.h> -> <linux/sched.h> -> <linux/smp.h> -> <asm/smp.h>

Signed-off-by: Mark Rutland <mark.rutland@arm.com>
Cc: AKASHI Takahiro <takahiro.akashi@linaro.org>
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: James Morse <james.morse@arm.com>
Cc: Kees Cook <keescook@chromium.org>
Cc: Suzuki K Poulose <suzuki.poulose@arm.com>
Cc: Will Deacon <will.deacon@arm.com>
---
 arch/arm64/Kconfig                   |  2 ++
 arch/arm64/include/asm/Kbuild        |  1 -
 arch/arm64/include/asm/current.h     | 22 ++++++++++++++++++++++
 arch/arm64/include/asm/smp.h         |  1 +
 arch/arm64/include/asm/thread_info.h | 19 -------------------
 arch/arm64/kernel/asm-offsets.c      |  1 +
 arch/arm64/kernel/entry.S            |  4 ++--
 arch/arm64/kernel/head.S             | 11 +++++------
 arch/arm64/kernel/process.c          | 31 ++++++++++++++++++++++++++-----
 arch/arm64/kernel/smp.c              |  2 ++
 arch/arm64/kernel/stacktrace.c       |  5 +++++
 11 files changed, 66 insertions(+), 33 deletions(-)
 create mode 100644 arch/arm64/include/asm/current.h

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index bc3f00f..9f57318 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -11,6 +11,7 @@ config ARM64
 	select ARCH_HAS_GCOV_PROFILE_ALL
 	select ARCH_HAS_KCOV
 	select ARCH_HAS_SG_CHAIN
+	select ARCH_HAS_OWN_THREAD_INFO
 	select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST
 	select ARCH_USE_CMPXCHG_LOCKREF
 	select ARCH_SUPPORTS_ATOMIC_RMW
@@ -110,6 +111,7 @@ config ARM64
 	select POWER_SUPPLY
 	select SPARSE_IRQ
 	select SYSCTL_EXCEPTION_TRACE
+	select THREAD_INFO_IN_TASK
 	help
 	  ARM 64-bit (AArch64) Linux support.
 
diff --git a/arch/arm64/include/asm/Kbuild b/arch/arm64/include/asm/Kbuild
index f43d2c4..a716c6f 100644
--- a/arch/arm64/include/asm/Kbuild
+++ b/arch/arm64/include/asm/Kbuild
@@ -2,7 +2,6 @@ generic-y += bug.h
 generic-y += bugs.h
 generic-y += clkdev.h
 generic-y += cputime.h
-generic-y += current.h
 generic-y += delay.h
 generic-y += div64.h
 generic-y += dma.h
diff --git a/arch/arm64/include/asm/current.h b/arch/arm64/include/asm/current.h
new file mode 100644
index 0000000..f2bcbe2
--- /dev/null
+++ b/arch/arm64/include/asm/current.h
@@ -0,0 +1,22 @@
+#ifndef __ASM_CURRENT_H
+#define __ASM_CURRENT_H
+
+#include <linux/compiler.h>
+
+#include <asm/sysreg.h>
+
+#ifndef __ASSEMBLY__
+
+struct task_struct;
+
+static __always_inline struct task_struct *get_current(void)
+{
+	return (struct task_struct *)read_sysreg(sp_el0);
+}
+
+#define current get_current()
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* __ASM_CURRENT_H */
+
diff --git a/arch/arm64/include/asm/smp.h b/arch/arm64/include/asm/smp.h
index 0226447..fef90c0 100644
--- a/arch/arm64/include/asm/smp.h
+++ b/arch/arm64/include/asm/smp.h
@@ -73,6 +73,7 @@ asmlinkage void secondary_start_kernel(void);
  */
 struct secondary_data {
 	void *stack;
+	struct task_struct *task;
 	long status;
 };
 
diff --git a/arch/arm64/include/asm/thread_info.h b/arch/arm64/include/asm/thread_info.h
index 796af24..5b16b34 100644
--- a/arch/arm64/include/asm/thread_info.h
+++ b/arch/arm64/include/asm/thread_info.h
@@ -46,14 +46,12 @@ typedef unsigned long mm_segment_t;
 struct thread_info {
 	unsigned long		flags;		/* low level flags */
 	mm_segment_t		addr_limit;	/* address limit */
-	struct task_struct	*task;		/* main task structure */
 	int			preempt_count;	/* 0 => preemptable, <0 => bug */
 	int			cpu;		/* cpu */
 };
 
 #define INIT_THREAD_INFO(tsk)						\
 {									\
-	.task		= &tsk,						\
 	.flags		= 0,						\
 	.preempt_count	= INIT_PREEMPT_COUNT,				\
 	.addr_limit	= KERNEL_DS,					\
@@ -66,23 +64,6 @@ struct thread_info {
  */
 register unsigned long current_stack_pointer asm ("sp");
 
-/*
- * how to get the thread information struct from C
- */
-static inline struct thread_info *current_thread_info(void) __attribute_const__;
-
-/*
- * struct thread_info can be accessed directly via sp_el0.
- */
-static inline struct thread_info *current_thread_info(void)
-{
-	unsigned long sp_el0;
-
-	asm ("mrs %0, sp_el0" : "=r" (sp_el0));
-
-	return (struct thread_info *)sp_el0;
-}
-
 #define thread_saved_pc(tsk)	\
 	((unsigned long)(tsk->thread.cpu_context.pc))
 #define thread_saved_sp(tsk)	\
diff --git a/arch/arm64/kernel/asm-offsets.c b/arch/arm64/kernel/asm-offsets.c
index ee764eb..242fe909 100644
--- a/arch/arm64/kernel/asm-offsets.c
+++ b/arch/arm64/kernel/asm-offsets.c
@@ -120,6 +120,7 @@ int main(void)
   DEFINE(TZ_DSTTIME,		offsetof(struct timezone, tz_dsttime));
   BLANK();
   DEFINE(CPU_BOOT_STACK,	offsetof(struct secondary_data, stack));
+  DEFINE(CPU_BOOT_TASK,		offsetof(struct secondary_data, task));
   BLANK();
 #ifdef CONFIG_KVM_ARM_HOST
   DEFINE(VCPU_CONTEXT,		offsetof(struct kvm_vcpu, arch.ctxt));
diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S
index 52b4241..f844e7f 100644
--- a/arch/arm64/kernel/entry.S
+++ b/arch/arm64/kernel/entry.S
@@ -123,6 +123,7 @@
 	 * Set sp_el0 to current thread_info.
 	 */
 	.if	\el == 0
+	ldr_this_cpu	tsk, __entry_task, x21
 	msr	sp_el0, tsk
 	.endif
 
@@ -680,8 +681,7 @@ ENTRY(cpu_switch_to)
 	ldp	x29, x9, [x8], #16
 	ldr	lr, [x8]
 	mov	sp, x9
-	and	x9, x9, #~(THREAD_SIZE - 1)
-	msr	sp_el0, x9
+	msr	sp_el0, x1
 	ret
 ENDPROC(cpu_switch_to)
 
diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S
index b77f583..abc7330 100644
--- a/arch/arm64/kernel/head.S
+++ b/arch/arm64/kernel/head.S
@@ -433,8 +433,7 @@ __primary_switched:
 	dsb	ishst				// Make zero page visible to PTW
 
 	adr_l	sp, initial_sp, x4
-	mov	x4, sp
-	and	x4, x4, #~(THREAD_SIZE - 1)
+	adr_l	x4, init_task
 	msr	sp_el0, x4			// Save thread_info
 	str_l	x21, __fdt_pointer, x5		// Save FDT pointer
 
@@ -680,10 +679,10 @@ __secondary_switched:
 	isb
 
 	adr_l	x0, secondary_data
-	ldr	x0, [x0, #CPU_BOOT_STACK]	// get secondary_data.stack
-	mov	sp, x0
-	and	x0, x0, #~(THREAD_SIZE - 1)
-	msr	sp_el0, x0			// save thread_info
+	ldr	x1, [x0, #CPU_BOOT_STACK]	// get secondary_data.stack
+	mov	sp, x1
+	ldr	x2, [x0, #CPU_BOOT_TASK]
+	msr	sp_el0, x2
 	mov	x29, #0
 	b	secondary_start_kernel
 ENDPROC(__secondary_switched)
diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c
index 6cd2612..e35043d 100644
--- a/arch/arm64/kernel/process.c
+++ b/arch/arm64/kernel/process.c
@@ -45,6 +45,7 @@
 #include <linux/personality.h>
 #include <linux/notifier.h>
 #include <trace/events/power.h>
+#include <linux/percpu.h>
 
 #include <asm/alternative.h>
 #include <asm/compat.h>
@@ -314,6 +315,17 @@ static void uao_thread_switch(struct task_struct *next)
 }
 
 /*
+ * We store our current task in sp_el0, which is clobbered by userspace. Keep a
+ * shadow copy so that we can restore this upon entry from userspace.
+ */
+DEFINE_PER_CPU(struct task_struct *, __entry_task) = &init_task;
+
+static void entry_task_switch(struct task_struct *next)
+{
+	__this_cpu_write(__entry_task, next);
+}
+
+/*
  * Thread switching.
  */
 struct task_struct *__switch_to(struct task_struct *prev,
@@ -325,6 +337,7 @@ struct task_struct *__switch_to(struct task_struct *prev,
 	tls_thread_switch(next);
 	hw_breakpoint_thread_switch(next);
 	contextidr_thread_switch(next);
+	entry_task_switch(next);
 	uao_thread_switch(next);
 
 	/*
@@ -342,11 +355,14 @@ struct task_struct *__switch_to(struct task_struct *prev,
 unsigned long get_wchan(struct task_struct *p)
 {
 	struct stackframe frame;
-	unsigned long stack_page;
+	unsigned long stack_page, ret = 0;
 	int count = 0;
 	if (!p || p == current || p->state == TASK_RUNNING)
 		return 0;
 
+	if (!try_get_task_stack(p))
+		return 0;
+
 	frame.fp = thread_saved_fp(p);
 	frame.sp = thread_saved_sp(p);
 	frame.pc = thread_saved_pc(p);
@@ -358,11 +374,16 @@ unsigned long get_wchan(struct task_struct *p)
 		if (frame.sp < stack_page ||
 		    frame.sp >= stack_page + THREAD_SIZE ||
 		    unwind_frame(p, &frame))
-			return 0;
-		if (!in_sched_functions(frame.pc))
-			return frame.pc;
+			goto out;
+		if (!in_sched_functions(frame.pc)) {
+			ret = frame.pc;
+			goto out;
+		}
 	} while (count ++ < 16);
-	return 0;
+
+out:
+	put_task_stack(p);
+	return ret;
 }
 
 unsigned long arch_align_stack(unsigned long sp)
diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c
index d93d433..d84be9db 100644
--- a/arch/arm64/kernel/smp.c
+++ b/arch/arm64/kernel/smp.c
@@ -146,6 +146,7 @@ int __cpu_up(unsigned int cpu, struct task_struct *idle)
 	 * We need to tell the secondary core where to find its stack and the
 	 * page tables.
 	 */
+	secondary_data.task = idle;
 	secondary_data.stack = task_stack_page(idle) + THREAD_START_SP;
 	update_cpu_boot_status(CPU_MMU_OFF);
 	__flush_dcache_area(&secondary_data, sizeof(secondary_data));
@@ -170,6 +171,7 @@ int __cpu_up(unsigned int cpu, struct task_struct *idle)
 		pr_err("CPU%u: failed to boot: %d\n", cpu, ret);
 	}
 
+	secondary_data.task = NULL;
 	secondary_data.stack = NULL;
 	status = READ_ONCE(secondary_data.status);
 	if (ret && status) {
diff --git a/arch/arm64/kernel/stacktrace.c b/arch/arm64/kernel/stacktrace.c
index d9751a4..4e0efe8 100644
--- a/arch/arm64/kernel/stacktrace.c
+++ b/arch/arm64/kernel/stacktrace.c
@@ -157,6 +157,9 @@ void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace)
 	struct stack_trace_data data;
 	struct stackframe frame;
 
+	if (!try_get_task_stack(tsk))
+		return;
+
 	data.trace = trace;
 	data.skip = trace->skip;
 
@@ -178,6 +181,8 @@ void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace)
 	walk_stackframe(tsk, &frame, save_trace, &data);
 	if (trace->nr_entries < trace->max_entries)
 		trace->entries[trace->nr_entries++] = ULONG_MAX;
+
+	put_task_stack(tsk);
 }
 
 void save_stack_trace(struct stack_trace *trace)
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 54+ messages in thread

* Re: [RFC PATCH 2/8] thread_info: allow custom in-task thread_info
  2016-09-15 13:49   ` Mark Rutland
  (?)
@ 2016-09-15 18:37     ` Andy Lutomirski
  -1 siblings, 0 replies; 54+ messages in thread
From: Andy Lutomirski @ 2016-09-15 18:37 UTC (permalink / raw)
  To: Mark Rutland
  Cc: linux-arm-kernel, Andrew Morton, Ard Biesheuvel, Catalin Marinas,
	james.morse, Kees Cook, linux-kernel, lorenzo.pieralisi,
	Andrew Lutomirski, suzuki.poulose, Takahiro Akashi, Will Deacon,
	kernel-hardening

On Thu, Sep 15, 2016 at 6:49 AM, Mark Rutland <mark.rutland@arm.com> wrote:
> Currently, task_struct is defined in <linux/sched.h>, which (indirectly)
> pulls in a number of low-level arch headers such as <asm/preempt.h>
> through a number of other headers. Thus, code and structures in these
> headers can't rely on the definition of task_struct. Some of these
> headers are necessary for the definition of task_struct, so moving
> task_struct into its own header is insufficient tio avoid circular
> includes.

The flippant answer is to fix the headers, but I tried that myself and
gave up :(

But how about this slightly less duplicative alternative:

struct thread_info {
#ifdef arch_thread_info
  struct arch_thread_info arch_ti;
#endif
};

^ permalink raw reply	[flat|nested] 54+ messages in thread

* [RFC PATCH 2/8] thread_info: allow custom in-task thread_info
@ 2016-09-15 18:37     ` Andy Lutomirski
  0 siblings, 0 replies; 54+ messages in thread
From: Andy Lutomirski @ 2016-09-15 18:37 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Sep 15, 2016 at 6:49 AM, Mark Rutland <mark.rutland@arm.com> wrote:
> Currently, task_struct is defined in <linux/sched.h>, which (indirectly)
> pulls in a number of low-level arch headers such as <asm/preempt.h>
> through a number of other headers. Thus, code and structures in these
> headers can't rely on the definition of task_struct. Some of these
> headers are necessary for the definition of task_struct, so moving
> task_struct into its own header is insufficient tio avoid circular
> includes.

The flippant answer is to fix the headers, but I tried that myself and
gave up :(

But how about this slightly less duplicative alternative:

struct thread_info {
#ifdef arch_thread_info
  struct arch_thread_info arch_ti;
#endif
};

^ permalink raw reply	[flat|nested] 54+ messages in thread

* [kernel-hardening] Re: [RFC PATCH 2/8] thread_info: allow custom in-task thread_info
@ 2016-09-15 18:37     ` Andy Lutomirski
  0 siblings, 0 replies; 54+ messages in thread
From: Andy Lutomirski @ 2016-09-15 18:37 UTC (permalink / raw)
  To: Mark Rutland
  Cc: linux-arm-kernel, Andrew Morton, Ard Biesheuvel, Catalin Marinas,
	james.morse, Kees Cook, linux-kernel, lorenzo.pieralisi,
	Andrew Lutomirski, suzuki.poulose, Takahiro Akashi, Will Deacon,
	kernel-hardening

On Thu, Sep 15, 2016 at 6:49 AM, Mark Rutland <mark.rutland@arm.com> wrote:
> Currently, task_struct is defined in <linux/sched.h>, which (indirectly)
> pulls in a number of low-level arch headers such as <asm/preempt.h>
> through a number of other headers. Thus, code and structures in these
> headers can't rely on the definition of task_struct. Some of these
> headers are necessary for the definition of task_struct, so moving
> task_struct into its own header is insufficient tio avoid circular
> includes.

The flippant answer is to fix the headers, but I tried that myself and
gave up :(

But how about this slightly less duplicative alternative:

struct thread_info {
#ifdef arch_thread_info
  struct arch_thread_info arch_ti;
#endif
};

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [RFC PATCH 2/8] thread_info: allow custom in-task thread_info
  2016-09-15 18:37     ` Andy Lutomirski
  (?)
@ 2016-09-16 10:33       ` Mark Rutland
  -1 siblings, 0 replies; 54+ messages in thread
From: Mark Rutland @ 2016-09-16 10:33 UTC (permalink / raw)
  To: Andy Lutomirski
  Cc: linux-arm-kernel, Andrew Morton, Ard Biesheuvel, Catalin Marinas,
	james.morse, Kees Cook, linux-kernel, lorenzo.pieralisi,
	Andrew Lutomirski, suzuki.poulose, Takahiro Akashi, Will Deacon,
	kernel-hardening

On Thu, Sep 15, 2016 at 11:37:47AM -0700, Andy Lutomirski wrote:
> On Thu, Sep 15, 2016 at 6:49 AM, Mark Rutland <mark.rutland@arm.com> wrote:
> > Currently, task_struct is defined in <linux/sched.h>, which (indirectly)
> > pulls in a number of low-level arch headers such as <asm/preempt.h>
> > through a number of other headers. Thus, code and structures in these
> > headers can't rely on the definition of task_struct. Some of these
> > headers are necessary for the definition of task_struct, so moving
> > task_struct into its own header is insufficient tio avoid circular
> > includes.
> 
> The flippant answer is to fix the headers, but I tried that myself and
> gave up :(

Agreed; likewise (though I gave up quicker, I suspect). :(

Longer-term I'd still hope that we can do this.

> But how about this slightly less duplicative alternative:
> 
> struct thread_info {
> #ifdef arch_thread_info
>   struct arch_thread_info arch_ti;
> #endif
> };

I'm happy to have an arch_thread_info.

Just to check, what do you mean to happen with the flags field? Should
that always be in the generic thread_info? e.g.

struct thread_info {
	u32 flags;
#ifdef arch_thread_info
	struct arch_thread_info arch_ti;
#endif
};

Thanks,
Mark,

^ permalink raw reply	[flat|nested] 54+ messages in thread

* [RFC PATCH 2/8] thread_info: allow custom in-task thread_info
@ 2016-09-16 10:33       ` Mark Rutland
  0 siblings, 0 replies; 54+ messages in thread
From: Mark Rutland @ 2016-09-16 10:33 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Sep 15, 2016 at 11:37:47AM -0700, Andy Lutomirski wrote:
> On Thu, Sep 15, 2016 at 6:49 AM, Mark Rutland <mark.rutland@arm.com> wrote:
> > Currently, task_struct is defined in <linux/sched.h>, which (indirectly)
> > pulls in a number of low-level arch headers such as <asm/preempt.h>
> > through a number of other headers. Thus, code and structures in these
> > headers can't rely on the definition of task_struct. Some of these
> > headers are necessary for the definition of task_struct, so moving
> > task_struct into its own header is insufficient tio avoid circular
> > includes.
> 
> The flippant answer is to fix the headers, but I tried that myself and
> gave up :(

Agreed; likewise (though I gave up quicker, I suspect). :(

Longer-term I'd still hope that we can do this.

> But how about this slightly less duplicative alternative:
> 
> struct thread_info {
> #ifdef arch_thread_info
>   struct arch_thread_info arch_ti;
> #endif
> };

I'm happy to have an arch_thread_info.

Just to check, what do you mean to happen with the flags field? Should
that always be in the generic thread_info? e.g.

struct thread_info {
	u32 flags;
#ifdef arch_thread_info
	struct arch_thread_info arch_ti;
#endif
};

Thanks,
Mark,

^ permalink raw reply	[flat|nested] 54+ messages in thread

* [kernel-hardening] Re: [RFC PATCH 2/8] thread_info: allow custom in-task thread_info
@ 2016-09-16 10:33       ` Mark Rutland
  0 siblings, 0 replies; 54+ messages in thread
From: Mark Rutland @ 2016-09-16 10:33 UTC (permalink / raw)
  To: Andy Lutomirski
  Cc: linux-arm-kernel, Andrew Morton, Ard Biesheuvel, Catalin Marinas,
	james.morse, Kees Cook, linux-kernel, lorenzo.pieralisi,
	Andrew Lutomirski, suzuki.poulose, Takahiro Akashi, Will Deacon,
	kernel-hardening

On Thu, Sep 15, 2016 at 11:37:47AM -0700, Andy Lutomirski wrote:
> On Thu, Sep 15, 2016 at 6:49 AM, Mark Rutland <mark.rutland@arm.com> wrote:
> > Currently, task_struct is defined in <linux/sched.h>, which (indirectly)
> > pulls in a number of low-level arch headers such as <asm/preempt.h>
> > through a number of other headers. Thus, code and structures in these
> > headers can't rely on the definition of task_struct. Some of these
> > headers are necessary for the definition of task_struct, so moving
> > task_struct into its own header is insufficient tio avoid circular
> > includes.
> 
> The flippant answer is to fix the headers, but I tried that myself and
> gave up :(

Agreed; likewise (though I gave up quicker, I suspect). :(

Longer-term I'd still hope that we can do this.

> But how about this slightly less duplicative alternative:
> 
> struct thread_info {
> #ifdef arch_thread_info
>   struct arch_thread_info arch_ti;
> #endif
> };

I'm happy to have an arch_thread_info.

Just to check, what do you mean to happen with the flags field? Should
that always be in the generic thread_info? e.g.

struct thread_info {
	u32 flags;
#ifdef arch_thread_info
	struct arch_thread_info arch_ti;
#endif
};

Thanks,
Mark,

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [RFC PATCH 2/8] thread_info: allow custom in-task thread_info
  2016-09-16 10:33       ` Mark Rutland
  (?)
@ 2016-09-16 15:11         ` Andy Lutomirski
  -1 siblings, 0 replies; 54+ messages in thread
From: Andy Lutomirski @ 2016-09-16 15:11 UTC (permalink / raw)
  To: Mark Rutland
  Cc: linux-arm-kernel, Andrew Morton, Ard Biesheuvel, Catalin Marinas,
	james.morse, Kees Cook, linux-kernel, lorenzo.pieralisi,
	Andrew Lutomirski, suzuki.poulose, Takahiro Akashi, Will Deacon,
	kernel-hardening

> On Thu, Sep 15, 2016 at 11:37:47AM -0700, Andy Lutomirski wrote:
> > On Thu, Sep 15, 2016 at 6:49 AM, Mark Rutland <mark.rutland@arm.com> wrote:
> > > Currently, task_struct is defined in <linux/sched.h>, which (indirectly)
> > > pulls in a number of low-level arch headers such as <asm/preempt.h>
> > > through a number of other headers. Thus, code and structures in these
> > > headers can't rely on the definition of task_struct. Some of these
> > > headers are necessary for the definition of task_struct, so moving
> > > task_struct into its own header is insufficient tio avoid circular
> > > includes.
> >
> > The flippant answer is to fix the headers, but I tried that myself and
> > gave up :(
>
> Agreed; likewise (though I gave up quicker, I suspect). :(
>
> Longer-term I'd still hope that we can do this.
>
> > But how about this slightly less duplicative alternative:
> >
> > struct thread_info {
> > #ifdef arch_thread_info
> >   struct arch_thread_info arch_ti;
> > #endif
> > };
>
> I'm happy to have an arch_thread_info.
>
> Just to check, what do you mean to happen with the flags field? Should
> that always be in the generic thread_info? e.g.
>
> struct thread_info {
>         u32 flags;
> #ifdef arch_thread_info
>         struct arch_thread_info arch_ti;
> #endif
> };

Exactly.  Possibly with a comment that using thread_struct should be
preferred and that arch_thread_info should be used only if some header
file requires access via current_thread_info() or task_thread_info().

--Andy

>
> Thanks,
> Mark,

^ permalink raw reply	[flat|nested] 54+ messages in thread

* [RFC PATCH 2/8] thread_info: allow custom in-task thread_info
@ 2016-09-16 15:11         ` Andy Lutomirski
  0 siblings, 0 replies; 54+ messages in thread
From: Andy Lutomirski @ 2016-09-16 15:11 UTC (permalink / raw)
  To: linux-arm-kernel

> On Thu, Sep 15, 2016 at 11:37:47AM -0700, Andy Lutomirski wrote:
> > On Thu, Sep 15, 2016 at 6:49 AM, Mark Rutland <mark.rutland@arm.com> wrote:
> > > Currently, task_struct is defined in <linux/sched.h>, which (indirectly)
> > > pulls in a number of low-level arch headers such as <asm/preempt.h>
> > > through a number of other headers. Thus, code and structures in these
> > > headers can't rely on the definition of task_struct. Some of these
> > > headers are necessary for the definition of task_struct, so moving
> > > task_struct into its own header is insufficient tio avoid circular
> > > includes.
> >
> > The flippant answer is to fix the headers, but I tried that myself and
> > gave up :(
>
> Agreed; likewise (though I gave up quicker, I suspect). :(
>
> Longer-term I'd still hope that we can do this.
>
> > But how about this slightly less duplicative alternative:
> >
> > struct thread_info {
> > #ifdef arch_thread_info
> >   struct arch_thread_info arch_ti;
> > #endif
> > };
>
> I'm happy to have an arch_thread_info.
>
> Just to check, what do you mean to happen with the flags field? Should
> that always be in the generic thread_info? e.g.
>
> struct thread_info {
>         u32 flags;
> #ifdef arch_thread_info
>         struct arch_thread_info arch_ti;
> #endif
> };

Exactly.  Possibly with a comment that using thread_struct should be
preferred and that arch_thread_info should be used only if some header
file requires access via current_thread_info() or task_thread_info().

--Andy

>
> Thanks,
> Mark,

^ permalink raw reply	[flat|nested] 54+ messages in thread

* [kernel-hardening] Re: [RFC PATCH 2/8] thread_info: allow custom in-task thread_info
@ 2016-09-16 15:11         ` Andy Lutomirski
  0 siblings, 0 replies; 54+ messages in thread
From: Andy Lutomirski @ 2016-09-16 15:11 UTC (permalink / raw)
  To: Mark Rutland
  Cc: linux-arm-kernel, Andrew Morton, Ard Biesheuvel, Catalin Marinas,
	james.morse, Kees Cook, linux-kernel, lorenzo.pieralisi,
	Andrew Lutomirski, suzuki.poulose, Takahiro Akashi, Will Deacon,
	kernel-hardening

> On Thu, Sep 15, 2016 at 11:37:47AM -0700, Andy Lutomirski wrote:
> > On Thu, Sep 15, 2016 at 6:49 AM, Mark Rutland <mark.rutland@arm.com> wrote:
> > > Currently, task_struct is defined in <linux/sched.h>, which (indirectly)
> > > pulls in a number of low-level arch headers such as <asm/preempt.h>
> > > through a number of other headers. Thus, code and structures in these
> > > headers can't rely on the definition of task_struct. Some of these
> > > headers are necessary for the definition of task_struct, so moving
> > > task_struct into its own header is insufficient tio avoid circular
> > > includes.
> >
> > The flippant answer is to fix the headers, but I tried that myself and
> > gave up :(
>
> Agreed; likewise (though I gave up quicker, I suspect). :(
>
> Longer-term I'd still hope that we can do this.
>
> > But how about this slightly less duplicative alternative:
> >
> > struct thread_info {
> > #ifdef arch_thread_info
> >   struct arch_thread_info arch_ti;
> > #endif
> > };
>
> I'm happy to have an arch_thread_info.
>
> Just to check, what do you mean to happen with the flags field? Should
> that always be in the generic thread_info? e.g.
>
> struct thread_info {
>         u32 flags;
> #ifdef arch_thread_info
>         struct arch_thread_info arch_ti;
> #endif
> };

Exactly.  Possibly with a comment that using thread_struct should be
preferred and that arch_thread_info should be used only if some header
file requires access via current_thread_info() or task_thread_info().

--Andy

>
> Thanks,
> Mark,

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [RFC PATCH 2/8] thread_info: allow custom in-task thread_info
  2016-09-16 15:11         ` Andy Lutomirski
  (?)
@ 2016-09-19 10:44           ` Mark Rutland
  -1 siblings, 0 replies; 54+ messages in thread
From: Mark Rutland @ 2016-09-19 10:44 UTC (permalink / raw)
  To: Andy Lutomirski, Yoshinori Sato
  Cc: linux-arm-kernel, Andrew Morton, Ard Biesheuvel, Catalin Marinas,
	james.morse, Kees Cook, linux-kernel, lorenzo.pieralisi,
	Andrew Lutomirski, suzuki.poulose, Takahiro Akashi, Will Deacon,
	kernel-hardening

[Adding Yosinori Sato for h8300]

On Fri, Sep 16, 2016 at 08:11:14AM -0700, Andy Lutomirski wrote:
> > On Thu, Sep 15, 2016 at 11:37:47AM -0700, Andy Lutomirski wrote:
> > > On Thu, Sep 15, 2016 at 6:49 AM, Mark Rutland <mark.rutland@arm.com> wrote:
> > Just to check, what do you mean to happen with the flags field? Should
> > that always be in the generic thread_info? e.g.
> >
> > struct thread_info {
> >         u32 flags;
> > #ifdef arch_thread_info
> >         struct arch_thread_info arch_ti;
> > #endif
> > };
> 
> Exactly.  Possibly with a comment that using thread_struct should be
> preferred and that arch_thread_info should be used only if some header
> file requires access via current_thread_info() or task_thread_info().

Sure thing.

While looking at that, I spotted that would cause a circular include on
h8300, but that appears to be because of a larger bug anyhow. It seems
h8300 has thread_info::restart_block, and manipulates this in its signal
code, yet core code manipulates task_struct::restart_block.

I think we need something like the below (which is completely untested).

Thanks,
Mark.

---->8----
>From 4dfbdc7706bfb03a48999ff69e85e0c7361adffe Mon Sep 17 00:00:00 2001
From: Mark Rutland <mark.rutland@arm.com>
Date: Mon, 19 Sep 2016 11:33:42 +0100
Subject: [PATCH] h8300: fix syscall restarting

Back in commit f56141e3e2d9aabf ("all arches, signal: move restart_block
to struct task_struct"), all architectures and core code were changed to
use task_struct::restart_block. However, when h8300 support was
subsequently restored in v4.2, it was not updated to account for this,
and maintains thread_info::restart_block, which is not kept in sync.

This patch drops the redundant restart_block from thread_info, and moves
h8300 to the common one in task_struct, ensuring that syscall restarting
always works as expected.

Signed-off-by: Mark Rutland <mark.rutland@arm.com>
Cc: Andy Lutomirski <luto@amacapital.net>
Cc: Yoshinori Sato <ysato@users.sourceforge.jp>
Cc: stable@vger.kernel.org # v4.2+
---
 arch/h8300/include/asm/thread_info.h | 4 ----
 arch/h8300/kernel/signal.c           | 2 +-
 2 files changed, 1 insertion(+), 5 deletions(-)

diff --git a/arch/h8300/include/asm/thread_info.h b/arch/h8300/include/asm/thread_info.h
index b408fe6..3cef068 100644
--- a/arch/h8300/include/asm/thread_info.h
+++ b/arch/h8300/include/asm/thread_info.h
@@ -31,7 +31,6 @@ struct thread_info {
 	int		   cpu;			/* cpu we're on */
 	int		   preempt_count;	/* 0 => preemptable, <0 => BUG */
 	mm_segment_t		addr_limit;
-	struct restart_block restart_block;
 };
 
 /*
@@ -44,9 +43,6 @@ struct thread_info {
 	.cpu =		0,			\
 	.preempt_count = INIT_PREEMPT_COUNT,	\
 	.addr_limit	= KERNEL_DS,		\
-	.restart_block	= {			\
-		.fn = do_no_restart_syscall,	\
-	},					\
 }
 
 #define init_thread_info	(init_thread_union.thread_info)
diff --git a/arch/h8300/kernel/signal.c b/arch/h8300/kernel/signal.c
index ad1f81f..7138303 100644
--- a/arch/h8300/kernel/signal.c
+++ b/arch/h8300/kernel/signal.c
@@ -79,7 +79,7 @@ restore_sigcontext(struct sigcontext *usc, int *pd0)
 	unsigned int er0;
 
 	/* Always make any pending restarted system calls return -EINTR */
-	current_thread_info()->restart_block.fn = do_no_restart_syscall;
+	current->restart_block.fn = do_no_restart_syscall;
 
 	/* restore passed registers */
 #define COPY(r)  do { err |= get_user(regs->r, &usc->sc_##r); } while (0)
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [RFC PATCH 2/8] thread_info: allow custom in-task thread_info
@ 2016-09-19 10:44           ` Mark Rutland
  0 siblings, 0 replies; 54+ messages in thread
From: Mark Rutland @ 2016-09-19 10:44 UTC (permalink / raw)
  To: linux-arm-kernel

[Adding Yosinori Sato for h8300]

On Fri, Sep 16, 2016 at 08:11:14AM -0700, Andy Lutomirski wrote:
> > On Thu, Sep 15, 2016 at 11:37:47AM -0700, Andy Lutomirski wrote:
> > > On Thu, Sep 15, 2016 at 6:49 AM, Mark Rutland <mark.rutland@arm.com> wrote:
> > Just to check, what do you mean to happen with the flags field? Should
> > that always be in the generic thread_info? e.g.
> >
> > struct thread_info {
> >         u32 flags;
> > #ifdef arch_thread_info
> >         struct arch_thread_info arch_ti;
> > #endif
> > };
> 
> Exactly.  Possibly with a comment that using thread_struct should be
> preferred and that arch_thread_info should be used only if some header
> file requires access via current_thread_info() or task_thread_info().

Sure thing.

While looking at that, I spotted that would cause a circular include on
h8300, but that appears to be because of a larger bug anyhow. It seems
h8300 has thread_info::restart_block, and manipulates this in its signal
code, yet core code manipulates task_struct::restart_block.

I think we need something like the below (which is completely untested).

Thanks,
Mark.

---->8----
>From 4dfbdc7706bfb03a48999ff69e85e0c7361adffe Mon Sep 17 00:00:00 2001
From: Mark Rutland <mark.rutland@arm.com>
Date: Mon, 19 Sep 2016 11:33:42 +0100
Subject: [PATCH] h8300: fix syscall restarting

Back in commit f56141e3e2d9aabf ("all arches, signal: move restart_block
to struct task_struct"), all architectures and core code were changed to
use task_struct::restart_block. However, when h8300 support was
subsequently restored in v4.2, it was not updated to account for this,
and maintains thread_info::restart_block, which is not kept in sync.

This patch drops the redundant restart_block from thread_info, and moves
h8300 to the common one in task_struct, ensuring that syscall restarting
always works as expected.

Signed-off-by: Mark Rutland <mark.rutland@arm.com>
Cc: Andy Lutomirski <luto@amacapital.net>
Cc: Yoshinori Sato <ysato@users.sourceforge.jp>
Cc: stable at vger.kernel.org # v4.2+
---
 arch/h8300/include/asm/thread_info.h | 4 ----
 arch/h8300/kernel/signal.c           | 2 +-
 2 files changed, 1 insertion(+), 5 deletions(-)

diff --git a/arch/h8300/include/asm/thread_info.h b/arch/h8300/include/asm/thread_info.h
index b408fe6..3cef068 100644
--- a/arch/h8300/include/asm/thread_info.h
+++ b/arch/h8300/include/asm/thread_info.h
@@ -31,7 +31,6 @@ struct thread_info {
 	int		   cpu;			/* cpu we're on */
 	int		   preempt_count;	/* 0 => preemptable, <0 => BUG */
 	mm_segment_t		addr_limit;
-	struct restart_block restart_block;
 };
 
 /*
@@ -44,9 +43,6 @@ struct thread_info {
 	.cpu =		0,			\
 	.preempt_count = INIT_PREEMPT_COUNT,	\
 	.addr_limit	= KERNEL_DS,		\
-	.restart_block	= {			\
-		.fn = do_no_restart_syscall,	\
-	},					\
 }
 
 #define init_thread_info	(init_thread_union.thread_info)
diff --git a/arch/h8300/kernel/signal.c b/arch/h8300/kernel/signal.c
index ad1f81f..7138303 100644
--- a/arch/h8300/kernel/signal.c
+++ b/arch/h8300/kernel/signal.c
@@ -79,7 +79,7 @@ restore_sigcontext(struct sigcontext *usc, int *pd0)
 	unsigned int er0;
 
 	/* Always make any pending restarted system calls return -EINTR */
-	current_thread_info()->restart_block.fn = do_no_restart_syscall;
+	current->restart_block.fn = do_no_restart_syscall;
 
 	/* restore passed registers */
 #define COPY(r)  do { err |= get_user(regs->r, &usc->sc_##r); } while (0)
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [kernel-hardening] Re: [RFC PATCH 2/8] thread_info: allow custom in-task thread_info
@ 2016-09-19 10:44           ` Mark Rutland
  0 siblings, 0 replies; 54+ messages in thread
From: Mark Rutland @ 2016-09-19 10:44 UTC (permalink / raw)
  To: Andy Lutomirski, Yoshinori Sato
  Cc: linux-arm-kernel, Andrew Morton, Ard Biesheuvel, Catalin Marinas,
	james.morse, Kees Cook, linux-kernel, lorenzo.pieralisi,
	Andrew Lutomirski, suzuki.poulose, Takahiro Akashi, Will Deacon,
	kernel-hardening

[Adding Yosinori Sato for h8300]

On Fri, Sep 16, 2016 at 08:11:14AM -0700, Andy Lutomirski wrote:
> > On Thu, Sep 15, 2016 at 11:37:47AM -0700, Andy Lutomirski wrote:
> > > On Thu, Sep 15, 2016 at 6:49 AM, Mark Rutland <mark.rutland@arm.com> wrote:
> > Just to check, what do you mean to happen with the flags field? Should
> > that always be in the generic thread_info? e.g.
> >
> > struct thread_info {
> >         u32 flags;
> > #ifdef arch_thread_info
> >         struct arch_thread_info arch_ti;
> > #endif
> > };
> 
> Exactly.  Possibly with a comment that using thread_struct should be
> preferred and that arch_thread_info should be used only if some header
> file requires access via current_thread_info() or task_thread_info().

Sure thing.

While looking at that, I spotted that would cause a circular include on
h8300, but that appears to be because of a larger bug anyhow. It seems
h8300 has thread_info::restart_block, and manipulates this in its signal
code, yet core code manipulates task_struct::restart_block.

I think we need something like the below (which is completely untested).

Thanks,
Mark.

---->8----
>From 4dfbdc7706bfb03a48999ff69e85e0c7361adffe Mon Sep 17 00:00:00 2001
From: Mark Rutland <mark.rutland@arm.com>
Date: Mon, 19 Sep 2016 11:33:42 +0100
Subject: [PATCH] h8300: fix syscall restarting

Back in commit f56141e3e2d9aabf ("all arches, signal: move restart_block
to struct task_struct"), all architectures and core code were changed to
use task_struct::restart_block. However, when h8300 support was
subsequently restored in v4.2, it was not updated to account for this,
and maintains thread_info::restart_block, which is not kept in sync.

This patch drops the redundant restart_block from thread_info, and moves
h8300 to the common one in task_struct, ensuring that syscall restarting
always works as expected.

Signed-off-by: Mark Rutland <mark.rutland@arm.com>
Cc: Andy Lutomirski <luto@amacapital.net>
Cc: Yoshinori Sato <ysato@users.sourceforge.jp>
Cc: stable@vger.kernel.org # v4.2+
---
 arch/h8300/include/asm/thread_info.h | 4 ----
 arch/h8300/kernel/signal.c           | 2 +-
 2 files changed, 1 insertion(+), 5 deletions(-)

diff --git a/arch/h8300/include/asm/thread_info.h b/arch/h8300/include/asm/thread_info.h
index b408fe6..3cef068 100644
--- a/arch/h8300/include/asm/thread_info.h
+++ b/arch/h8300/include/asm/thread_info.h
@@ -31,7 +31,6 @@ struct thread_info {
 	int		   cpu;			/* cpu we're on */
 	int		   preempt_count;	/* 0 => preemptable, <0 => BUG */
 	mm_segment_t		addr_limit;
-	struct restart_block restart_block;
 };
 
 /*
@@ -44,9 +43,6 @@ struct thread_info {
 	.cpu =		0,			\
 	.preempt_count = INIT_PREEMPT_COUNT,	\
 	.addr_limit	= KERNEL_DS,		\
-	.restart_block	= {			\
-		.fn = do_no_restart_syscall,	\
-	},					\
 }
 
 #define init_thread_info	(init_thread_union.thread_info)
diff --git a/arch/h8300/kernel/signal.c b/arch/h8300/kernel/signal.c
index ad1f81f..7138303 100644
--- a/arch/h8300/kernel/signal.c
+++ b/arch/h8300/kernel/signal.c
@@ -79,7 +79,7 @@ restore_sigcontext(struct sigcontext *usc, int *pd0)
 	unsigned int er0;
 
 	/* Always make any pending restarted system calls return -EINTR */
-	current_thread_info()->restart_block.fn = do_no_restart_syscall;
+	current->restart_block.fn = do_no_restart_syscall;
 
 	/* restore passed registers */
 #define COPY(r)  do { err |= get_user(regs->r, &usc->sc_##r); } while (0)
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 54+ messages in thread

* Re: [RFC PATCH 0/8] arm64: move thread_info off of the task stack
  2016-09-15 13:49 ` Mark Rutland
  (?)
@ 2016-09-21  1:26   ` Laura Abbott
  -1 siblings, 0 replies; 54+ messages in thread
From: Laura Abbott @ 2016-09-21  1:26 UTC (permalink / raw)
  To: Mark Rutland, linux-arm-kernel
  Cc: akpm, ard.biesheuvel, catalin.marinas, james.morse, keescook,
	linux-kernel, lorenzo.pieralisi, luto, suzuki.poulose,
	takahiro.akashi, will.deacon, kernel-hardening

On 09/15/2016 06:49 AM, Mark Rutland wrote:
> Building atop of Andy's work on x86 and generic code, these patches move
> arm64's thread_info off of the stack and into task_struct. This protects
> thread_info from corruption in the face of stack overflow, and serves as
> a step towards fully robust stack overflow handling will be addressed by
> subsequent patches.
>
> In contrast to x86, we can't place some critical data such as
> preempt_count in percpu variables, and we must store these in some
> per-task location. This, compounded with the way headers are organised
> conspires to require us to still define our own thread_info. I
> understand that the longer term plan is to kill off thread_info
> entirely, hence I'm sending this as an RFC so we can figure out if/how
> we can achieve that.
>
> These patches are based on Andy's x86/vmap_stack branch [1,2], and I've
> pushed a copy to me arm64/ti-stack-split branch [3,4]. The result of
> these patches boots happily on platforms within reach of my desk, but
> has not seen much stressing so far.
>

FWIW, I used your ti-stack-split branch while running some kernel builds
and it seems to work well enough. You can take that as a Tested-by or I
can re-test with a non-RFC version.

> Thanks,
> Mark.
>
> [1] git://git.kernel.org/pub/scm/linux/kernel/git/luto/linux.git x86/vmap_stack
> [2] https://git.kernel.org/cgit/linux/kernel/git/luto/linux.git/log/?h=x86/vmap_stack
> [3] git://git.kernel.org/pub/scm/linux/kernel/git/mark/linux.git arm64/ti-stack-split
> [4] https://git.kernel.org/cgit/linux/kernel/git/mark/linux.git/log/?h=arm64/ti-stack-split
>
> Mark Rutland (8):
>   thread_info: include <current.h> for THREAD_INFO_IN_TASK
>   thread_info: allow custom in-task thread_info
>   arm64: thread_info remove stale items
>   arm64: asm-offsets: remove unused definitions
>   arm64: assembler: introduce ldr_this_cpu
>   arm64: traps: use task_struct instead of thread_info
>   arm64: move sp_el0 and tpidr_el1 into cpu_suspend_ctx
>   arm64: split thread_info from task stack
>
>  arch/arm64/Kconfig                   |  2 ++
>  arch/arm64/include/asm/Kbuild        |  1 -
>  arch/arm64/include/asm/assembler.h   | 19 +++++++++++++++----
>  arch/arm64/include/asm/current.h     | 22 ++++++++++++++++++++++
>  arch/arm64/include/asm/smp.h         |  1 +
>  arch/arm64/include/asm/suspend.h     |  2 +-
>  arch/arm64/include/asm/thread_info.h | 21 ---------------------
>  arch/arm64/kernel/asm-offsets.c      |  3 +--
>  arch/arm64/kernel/entry.S            |  6 +++---
>  arch/arm64/kernel/head.S             | 11 +++++------
>  arch/arm64/kernel/process.c          | 31 ++++++++++++++++++++++++++-----
>  arch/arm64/kernel/sleep.S            |  3 ---
>  arch/arm64/kernel/smp.c              |  2 ++
>  arch/arm64/kernel/stacktrace.c       |  5 +++++
>  arch/arm64/kernel/suspend.c          |  6 ------
>  arch/arm64/kernel/traps.c            | 12 ++++++------
>  arch/arm64/mm/proc.S                 |  6 ++++++
>  include/linux/thread_info.h          |  4 +++-
>  init/Kconfig                         |  3 +++
>  19 files changed, 101 insertions(+), 59 deletions(-)
>  create mode 100644 arch/arm64/include/asm/current.h
>

^ permalink raw reply	[flat|nested] 54+ messages in thread

* [RFC PATCH 0/8] arm64: move thread_info off of the task stack
@ 2016-09-21  1:26   ` Laura Abbott
  0 siblings, 0 replies; 54+ messages in thread
From: Laura Abbott @ 2016-09-21  1:26 UTC (permalink / raw)
  To: linux-arm-kernel

On 09/15/2016 06:49 AM, Mark Rutland wrote:
> Building atop of Andy's work on x86 and generic code, these patches move
> arm64's thread_info off of the stack and into task_struct. This protects
> thread_info from corruption in the face of stack overflow, and serves as
> a step towards fully robust stack overflow handling will be addressed by
> subsequent patches.
>
> In contrast to x86, we can't place some critical data such as
> preempt_count in percpu variables, and we must store these in some
> per-task location. This, compounded with the way headers are organised
> conspires to require us to still define our own thread_info. I
> understand that the longer term plan is to kill off thread_info
> entirely, hence I'm sending this as an RFC so we can figure out if/how
> we can achieve that.
>
> These patches are based on Andy's x86/vmap_stack branch [1,2], and I've
> pushed a copy to me arm64/ti-stack-split branch [3,4]. The result of
> these patches boots happily on platforms within reach of my desk, but
> has not seen much stressing so far.
>

FWIW, I used your ti-stack-split branch while running some kernel builds
and it seems to work well enough. You can take that as a Tested-by or I
can re-test with a non-RFC version.

> Thanks,
> Mark.
>
> [1] git://git.kernel.org/pub/scm/linux/kernel/git/luto/linux.git x86/vmap_stack
> [2] https://git.kernel.org/cgit/linux/kernel/git/luto/linux.git/log/?h=x86/vmap_stack
> [3] git://git.kernel.org/pub/scm/linux/kernel/git/mark/linux.git arm64/ti-stack-split
> [4] https://git.kernel.org/cgit/linux/kernel/git/mark/linux.git/log/?h=arm64/ti-stack-split
>
> Mark Rutland (8):
>   thread_info: include <current.h> for THREAD_INFO_IN_TASK
>   thread_info: allow custom in-task thread_info
>   arm64: thread_info remove stale items
>   arm64: asm-offsets: remove unused definitions
>   arm64: assembler: introduce ldr_this_cpu
>   arm64: traps: use task_struct instead of thread_info
>   arm64: move sp_el0 and tpidr_el1 into cpu_suspend_ctx
>   arm64: split thread_info from task stack
>
>  arch/arm64/Kconfig                   |  2 ++
>  arch/arm64/include/asm/Kbuild        |  1 -
>  arch/arm64/include/asm/assembler.h   | 19 +++++++++++++++----
>  arch/arm64/include/asm/current.h     | 22 ++++++++++++++++++++++
>  arch/arm64/include/asm/smp.h         |  1 +
>  arch/arm64/include/asm/suspend.h     |  2 +-
>  arch/arm64/include/asm/thread_info.h | 21 ---------------------
>  arch/arm64/kernel/asm-offsets.c      |  3 +--
>  arch/arm64/kernel/entry.S            |  6 +++---
>  arch/arm64/kernel/head.S             | 11 +++++------
>  arch/arm64/kernel/process.c          | 31 ++++++++++++++++++++++++++-----
>  arch/arm64/kernel/sleep.S            |  3 ---
>  arch/arm64/kernel/smp.c              |  2 ++
>  arch/arm64/kernel/stacktrace.c       |  5 +++++
>  arch/arm64/kernel/suspend.c          |  6 ------
>  arch/arm64/kernel/traps.c            | 12 ++++++------
>  arch/arm64/mm/proc.S                 |  6 ++++++
>  include/linux/thread_info.h          |  4 +++-
>  init/Kconfig                         |  3 +++
>  19 files changed, 101 insertions(+), 59 deletions(-)
>  create mode 100644 arch/arm64/include/asm/current.h
>

^ permalink raw reply	[flat|nested] 54+ messages in thread

* [kernel-hardening] Re: [RFC PATCH 0/8] arm64: move thread_info off of the task stack
@ 2016-09-21  1:26   ` Laura Abbott
  0 siblings, 0 replies; 54+ messages in thread
From: Laura Abbott @ 2016-09-21  1:26 UTC (permalink / raw)
  To: Mark Rutland, linux-arm-kernel
  Cc: akpm, ard.biesheuvel, catalin.marinas, james.morse, keescook,
	linux-kernel, lorenzo.pieralisi, luto, suzuki.poulose,
	takahiro.akashi, will.deacon, kernel-hardening

On 09/15/2016 06:49 AM, Mark Rutland wrote:
> Building atop of Andy's work on x86 and generic code, these patches move
> arm64's thread_info off of the stack and into task_struct. This protects
> thread_info from corruption in the face of stack overflow, and serves as
> a step towards fully robust stack overflow handling will be addressed by
> subsequent patches.
>
> In contrast to x86, we can't place some critical data such as
> preempt_count in percpu variables, and we must store these in some
> per-task location. This, compounded with the way headers are organised
> conspires to require us to still define our own thread_info. I
> understand that the longer term plan is to kill off thread_info
> entirely, hence I'm sending this as an RFC so we can figure out if/how
> we can achieve that.
>
> These patches are based on Andy's x86/vmap_stack branch [1,2], and I've
> pushed a copy to me arm64/ti-stack-split branch [3,4]. The result of
> these patches boots happily on platforms within reach of my desk, but
> has not seen much stressing so far.
>

FWIW, I used your ti-stack-split branch while running some kernel builds
and it seems to work well enough. You can take that as a Tested-by or I
can re-test with a non-RFC version.

> Thanks,
> Mark.
>
> [1] git://git.kernel.org/pub/scm/linux/kernel/git/luto/linux.git x86/vmap_stack
> [2] https://git.kernel.org/cgit/linux/kernel/git/luto/linux.git/log/?h=x86/vmap_stack
> [3] git://git.kernel.org/pub/scm/linux/kernel/git/mark/linux.git arm64/ti-stack-split
> [4] https://git.kernel.org/cgit/linux/kernel/git/mark/linux.git/log/?h=arm64/ti-stack-split
>
> Mark Rutland (8):
>   thread_info: include <current.h> for THREAD_INFO_IN_TASK
>   thread_info: allow custom in-task thread_info
>   arm64: thread_info remove stale items
>   arm64: asm-offsets: remove unused definitions
>   arm64: assembler: introduce ldr_this_cpu
>   arm64: traps: use task_struct instead of thread_info
>   arm64: move sp_el0 and tpidr_el1 into cpu_suspend_ctx
>   arm64: split thread_info from task stack
>
>  arch/arm64/Kconfig                   |  2 ++
>  arch/arm64/include/asm/Kbuild        |  1 -
>  arch/arm64/include/asm/assembler.h   | 19 +++++++++++++++----
>  arch/arm64/include/asm/current.h     | 22 ++++++++++++++++++++++
>  arch/arm64/include/asm/smp.h         |  1 +
>  arch/arm64/include/asm/suspend.h     |  2 +-
>  arch/arm64/include/asm/thread_info.h | 21 ---------------------
>  arch/arm64/kernel/asm-offsets.c      |  3 +--
>  arch/arm64/kernel/entry.S            |  6 +++---
>  arch/arm64/kernel/head.S             | 11 +++++------
>  arch/arm64/kernel/process.c          | 31 ++++++++++++++++++++++++++-----
>  arch/arm64/kernel/sleep.S            |  3 ---
>  arch/arm64/kernel/smp.c              |  2 ++
>  arch/arm64/kernel/stacktrace.c       |  5 +++++
>  arch/arm64/kernel/suspend.c          |  6 ------
>  arch/arm64/kernel/traps.c            | 12 ++++++------
>  arch/arm64/mm/proc.S                 |  6 ++++++
>  include/linux/thread_info.h          |  4 +++-
>  init/Kconfig                         |  3 +++
>  19 files changed, 101 insertions(+), 59 deletions(-)
>  create mode 100644 arch/arm64/include/asm/current.h
>

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [RFC PATCH 2/8] thread_info: allow custom in-task thread_info
  2016-09-16 15:11         ` Andy Lutomirski
  (?)
@ 2016-09-21 10:28           ` Mark Rutland
  -1 siblings, 0 replies; 54+ messages in thread
From: Mark Rutland @ 2016-09-21 10:28 UTC (permalink / raw)
  To: Andy Lutomirski
  Cc: linux-arm-kernel, Andrew Morton, Ard Biesheuvel, Catalin Marinas,
	james.morse, Kees Cook, linux-kernel, lorenzo.pieralisi,
	Andrew Lutomirski, suzuki.poulose, Takahiro Akashi, Will Deacon,
	kernel-hardening

Hi Andy,

On Fri, Sep 16, 2016 at 08:11:14AM -0700, Andy Lutomirski wrote:
> > On Thu, Sep 15, 2016 at 11:37:47AM -0700, Andy Lutomirski wrote:
> > Just to check, what do you mean to happen with the flags field? Should
> > that always be in the generic thread_info? e.g.
> >
> > struct thread_info {
> >         u32 flags;
> > #ifdef arch_thread_info
> >         struct arch_thread_info arch_ti;
> > #endif
> > };
> 
> Exactly.  Possibly with a comment that using thread_struct should be
> preferred and that arch_thread_info should be used only if some header
> file requires access via current_thread_info() or task_thread_info().

While fixing up these patches, I realised that I'm somewhat concerned by 
flags becoming a u32 (where it was previously an unsigned long for
arm64).

The generic {test,set,*}_ti_thread_flag() helpers use the usual bitops,
which perform accesses of sizeof(unsigned long) at a time, and for arm64
these need to be naturally-aligned.

We happen to get that alignment from subsequent fields in task_struct
and/or thread_info, and for arm64 we don't seem to have a problem with
tearing, but it feels somewhat fragile, and leaves me uneasy.

Looking at the git log, it seems that x86 also use unsigned long until
commit affa219b60a11b32 ("x86: change thread_info's flag field back to
32 bits"), where if I'm reading correctly, this was done to get rid of
unnecessary padding. With THREAD_INFO_IN_STACK, thread_info::flags is
immediately followed by a long on x86, so we save no padding.

Given all that, can we make the generic thread_info::flags an unsigned
long, matching what the thread flag helpers implicitly assume?

Thanks,
Mark.

^ permalink raw reply	[flat|nested] 54+ messages in thread

* [RFC PATCH 2/8] thread_info: allow custom in-task thread_info
@ 2016-09-21 10:28           ` Mark Rutland
  0 siblings, 0 replies; 54+ messages in thread
From: Mark Rutland @ 2016-09-21 10:28 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Andy,

On Fri, Sep 16, 2016 at 08:11:14AM -0700, Andy Lutomirski wrote:
> > On Thu, Sep 15, 2016 at 11:37:47AM -0700, Andy Lutomirski wrote:
> > Just to check, what do you mean to happen with the flags field? Should
> > that always be in the generic thread_info? e.g.
> >
> > struct thread_info {
> >         u32 flags;
> > #ifdef arch_thread_info
> >         struct arch_thread_info arch_ti;
> > #endif
> > };
> 
> Exactly.  Possibly with a comment that using thread_struct should be
> preferred and that arch_thread_info should be used only if some header
> file requires access via current_thread_info() or task_thread_info().

While fixing up these patches, I realised that I'm somewhat concerned by 
flags becoming a u32 (where it was previously an unsigned long for
arm64).

The generic {test,set,*}_ti_thread_flag() helpers use the usual bitops,
which perform accesses of sizeof(unsigned long) at a time, and for arm64
these need to be naturally-aligned.

We happen to get that alignment from subsequent fields in task_struct
and/or thread_info, and for arm64 we don't seem to have a problem with
tearing, but it feels somewhat fragile, and leaves me uneasy.

Looking at the git log, it seems that x86 also use unsigned long until
commit affa219b60a11b32 ("x86: change thread_info's flag field back to
32 bits"), where if I'm reading correctly, this was done to get rid of
unnecessary padding. With THREAD_INFO_IN_STACK, thread_info::flags is
immediately followed by a long on x86, so we save no padding.

Given all that, can we make the generic thread_info::flags an unsigned
long, matching what the thread flag helpers implicitly assume?

Thanks,
Mark.

^ permalink raw reply	[flat|nested] 54+ messages in thread

* [kernel-hardening] Re: [RFC PATCH 2/8] thread_info: allow custom in-task thread_info
@ 2016-09-21 10:28           ` Mark Rutland
  0 siblings, 0 replies; 54+ messages in thread
From: Mark Rutland @ 2016-09-21 10:28 UTC (permalink / raw)
  To: Andy Lutomirski
  Cc: linux-arm-kernel, Andrew Morton, Ard Biesheuvel, Catalin Marinas,
	james.morse, Kees Cook, linux-kernel, lorenzo.pieralisi,
	Andrew Lutomirski, suzuki.poulose, Takahiro Akashi, Will Deacon,
	kernel-hardening

Hi Andy,

On Fri, Sep 16, 2016 at 08:11:14AM -0700, Andy Lutomirski wrote:
> > On Thu, Sep 15, 2016 at 11:37:47AM -0700, Andy Lutomirski wrote:
> > Just to check, what do you mean to happen with the flags field? Should
> > that always be in the generic thread_info? e.g.
> >
> > struct thread_info {
> >         u32 flags;
> > #ifdef arch_thread_info
> >         struct arch_thread_info arch_ti;
> > #endif
> > };
> 
> Exactly.  Possibly with a comment that using thread_struct should be
> preferred and that arch_thread_info should be used only if some header
> file requires access via current_thread_info() or task_thread_info().

While fixing up these patches, I realised that I'm somewhat concerned by 
flags becoming a u32 (where it was previously an unsigned long for
arm64).

The generic {test,set,*}_ti_thread_flag() helpers use the usual bitops,
which perform accesses of sizeof(unsigned long) at a time, and for arm64
these need to be naturally-aligned.

We happen to get that alignment from subsequent fields in task_struct
and/or thread_info, and for arm64 we don't seem to have a problem with
tearing, but it feels somewhat fragile, and leaves me uneasy.

Looking at the git log, it seems that x86 also use unsigned long until
commit affa219b60a11b32 ("x86: change thread_info's flag field back to
32 bits"), where if I'm reading correctly, this was done to get rid of
unnecessary padding. With THREAD_INFO_IN_STACK, thread_info::flags is
immediately followed by a long on x86, so we save no padding.

Given all that, can we make the generic thread_info::flags an unsigned
long, matching what the thread flag helpers implicitly assume?

Thanks,
Mark.

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [RFC PATCH 0/8] arm64: move thread_info off of the task stack
  2016-09-21  1:26   ` Laura Abbott
  (?)
@ 2016-09-21 10:31     ` Mark Rutland
  -1 siblings, 0 replies; 54+ messages in thread
From: Mark Rutland @ 2016-09-21 10:31 UTC (permalink / raw)
  To: Laura Abbott
  Cc: linux-arm-kernel, akpm, ard.biesheuvel, catalin.marinas,
	james.morse, keescook, linux-kernel, lorenzo.pieralisi, luto,
	suzuki.poulose, takahiro.akashi, will.deacon, kernel-hardening

On Tue, Sep 20, 2016 at 06:26:54PM -0700, Laura Abbott wrote:
> On 09/15/2016 06:49 AM, Mark Rutland wrote:
> >Building atop of Andy's work on x86 and generic code, these patches move
> >arm64's thread_info off of the stack and into task_struct. This protects
> >thread_info from corruption in the face of stack overflow, and serves as
> >a step towards fully robust stack overflow handling will be addressed by
> >subsequent patches.
> >
> >In contrast to x86, we can't place some critical data such as
> >preempt_count in percpu variables, and we must store these in some
> >per-task location. This, compounded with the way headers are organised
> >conspires to require us to still define our own thread_info. I
> >understand that the longer term plan is to kill off thread_info
> >entirely, hence I'm sending this as an RFC so we can figure out if/how
> >we can achieve that.
> >
> >These patches are based on Andy's x86/vmap_stack branch [1,2], and I've
> >pushed a copy to me arm64/ti-stack-split branch [3,4]. The result of
> >these patches boots happily on platforms within reach of my desk, but
> >has not seen much stressing so far.
> 
> FWIW, I used your ti-stack-split branch while running some kernel builds
> and it seems to work well enough. You can take that as a Tested-by or I
> can re-test with a non-RFC version.

Thanks for testing, and many thanks for the offer!

Based on Andy's feedback some core bits are changing, and I'm hoping to
have a non-RFC version out soon once I've fixed up the remaining
fallout. I'll make sure you're Cc'd!

Thanks,
Mark.

^ permalink raw reply	[flat|nested] 54+ messages in thread

* [RFC PATCH 0/8] arm64: move thread_info off of the task stack
@ 2016-09-21 10:31     ` Mark Rutland
  0 siblings, 0 replies; 54+ messages in thread
From: Mark Rutland @ 2016-09-21 10:31 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Sep 20, 2016 at 06:26:54PM -0700, Laura Abbott wrote:
> On 09/15/2016 06:49 AM, Mark Rutland wrote:
> >Building atop of Andy's work on x86 and generic code, these patches move
> >arm64's thread_info off of the stack and into task_struct. This protects
> >thread_info from corruption in the face of stack overflow, and serves as
> >a step towards fully robust stack overflow handling will be addressed by
> >subsequent patches.
> >
> >In contrast to x86, we can't place some critical data such as
> >preempt_count in percpu variables, and we must store these in some
> >per-task location. This, compounded with the way headers are organised
> >conspires to require us to still define our own thread_info. I
> >understand that the longer term plan is to kill off thread_info
> >entirely, hence I'm sending this as an RFC so we can figure out if/how
> >we can achieve that.
> >
> >These patches are based on Andy's x86/vmap_stack branch [1,2], and I've
> >pushed a copy to me arm64/ti-stack-split branch [3,4]. The result of
> >these patches boots happily on platforms within reach of my desk, but
> >has not seen much stressing so far.
> 
> FWIW, I used your ti-stack-split branch while running some kernel builds
> and it seems to work well enough. You can take that as a Tested-by or I
> can re-test with a non-RFC version.

Thanks for testing, and many thanks for the offer!

Based on Andy's feedback some core bits are changing, and I'm hoping to
have a non-RFC version out soon once I've fixed up the remaining
fallout. I'll make sure you're Cc'd!

Thanks,
Mark.

^ permalink raw reply	[flat|nested] 54+ messages in thread

* [kernel-hardening] Re: [RFC PATCH 0/8] arm64: move thread_info off of the task stack
@ 2016-09-21 10:31     ` Mark Rutland
  0 siblings, 0 replies; 54+ messages in thread
From: Mark Rutland @ 2016-09-21 10:31 UTC (permalink / raw)
  To: Laura Abbott
  Cc: linux-arm-kernel, akpm, ard.biesheuvel, catalin.marinas,
	james.morse, keescook, linux-kernel, lorenzo.pieralisi, luto,
	suzuki.poulose, takahiro.akashi, will.deacon, kernel-hardening

On Tue, Sep 20, 2016 at 06:26:54PM -0700, Laura Abbott wrote:
> On 09/15/2016 06:49 AM, Mark Rutland wrote:
> >Building atop of Andy's work on x86 and generic code, these patches move
> >arm64's thread_info off of the stack and into task_struct. This protects
> >thread_info from corruption in the face of stack overflow, and serves as
> >a step towards fully robust stack overflow handling will be addressed by
> >subsequent patches.
> >
> >In contrast to x86, we can't place some critical data such as
> >preempt_count in percpu variables, and we must store these in some
> >per-task location. This, compounded with the way headers are organised
> >conspires to require us to still define our own thread_info. I
> >understand that the longer term plan is to kill off thread_info
> >entirely, hence I'm sending this as an RFC so we can figure out if/how
> >we can achieve that.
> >
> >These patches are based on Andy's x86/vmap_stack branch [1,2], and I've
> >pushed a copy to me arm64/ti-stack-split branch [3,4]. The result of
> >these patches boots happily on platforms within reach of my desk, but
> >has not seen much stressing so far.
> 
> FWIW, I used your ti-stack-split branch while running some kernel builds
> and it seems to work well enough. You can take that as a Tested-by or I
> can re-test with a non-RFC version.

Thanks for testing, and many thanks for the offer!

Based on Andy's feedback some core bits are changing, and I'm hoping to
have a non-RFC version out soon once I've fixed up the remaining
fallout. I'll make sure you're Cc'd!

Thanks,
Mark.

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [RFC PATCH 2/8] thread_info: allow custom in-task thread_info
  2016-09-21 10:28           ` Mark Rutland
  (?)
@ 2016-09-22 22:23             ` Andy Lutomirski
  -1 siblings, 0 replies; 54+ messages in thread
From: Andy Lutomirski @ 2016-09-22 22:23 UTC (permalink / raw)
  To: Mark Rutland
  Cc: james.morse, AKASHI Takahiro, Kees Cook, Andrew Morton,
	linux-arm-kernel, lorenzo.pieralisi, kernel-hardening,
	suzuki.poulose, linux-kernel, Catalin Marinas, Ard Biesheuvel,
	Will Deacon

On Sep 21, 2016 12:28 AM, "Mark Rutland" <mark.rutland@arm.com> wrote:
>
> Hi Andy,
>
> On Fri, Sep 16, 2016 at 08:11:14AM -0700, Andy Lutomirski wrote:
> > > On Thu, Sep 15, 2016 at 11:37:47AM -0700, Andy Lutomirski wrote:
> > > Just to check, what do you mean to happen with the flags field? Should
> > > that always be in the generic thread_info? e.g.
> > >
> > > struct thread_info {
> > >         u32 flags;
> > > #ifdef arch_thread_info
> > >         struct arch_thread_info arch_ti;
> > > #endif
> > > };
> >
> > Exactly.  Possibly with a comment that using thread_struct should be
> > preferred and that arch_thread_info should be used only if some header
> > file requires access via current_thread_info() or task_thread_info().
>
> While fixing up these patches, I realised that I'm somewhat concerned by
> flags becoming a u32 (where it was previously an unsigned long for
> arm64).
>
> The generic {test,set,*}_ti_thread_flag() helpers use the usual bitops,
> which perform accesses of sizeof(unsigned long) at a time, and for arm64
> these need to be naturally-aligned.
>
> We happen to get that alignment from subsequent fields in task_struct
> and/or thread_info, and for arm64 we don't seem to have a problem with
> tearing, but it feels somewhat fragile, and leaves me uneasy.
>
> Looking at the git log, it seems that x86 also use unsigned long until
> commit affa219b60a11b32 ("x86: change thread_info's flag field back to
> 32 bits"), where if I'm reading correctly, this was done to get rid of
> unnecessary padding. With THREAD_INFO_IN_STACK, thread_info::flags is
> immediately followed by a long on x86, so we save no padding.
>
> Given all that, can we make the generic thread_info::flags an unsigned
> long, matching what the thread flag helpers implicitly assume?
>

Yes.  Want to send the patch or should I?

--Andy

^ permalink raw reply	[flat|nested] 54+ messages in thread

* [RFC PATCH 2/8] thread_info: allow custom in-task thread_info
@ 2016-09-22 22:23             ` Andy Lutomirski
  0 siblings, 0 replies; 54+ messages in thread
From: Andy Lutomirski @ 2016-09-22 22:23 UTC (permalink / raw)
  To: linux-arm-kernel

On Sep 21, 2016 12:28 AM, "Mark Rutland" <mark.rutland@arm.com> wrote:
>
> Hi Andy,
>
> On Fri, Sep 16, 2016 at 08:11:14AM -0700, Andy Lutomirski wrote:
> > > On Thu, Sep 15, 2016 at 11:37:47AM -0700, Andy Lutomirski wrote:
> > > Just to check, what do you mean to happen with the flags field? Should
> > > that always be in the generic thread_info? e.g.
> > >
> > > struct thread_info {
> > >         u32 flags;
> > > #ifdef arch_thread_info
> > >         struct arch_thread_info arch_ti;
> > > #endif
> > > };
> >
> > Exactly.  Possibly with a comment that using thread_struct should be
> > preferred and that arch_thread_info should be used only if some header
> > file requires access via current_thread_info() or task_thread_info().
>
> While fixing up these patches, I realised that I'm somewhat concerned by
> flags becoming a u32 (where it was previously an unsigned long for
> arm64).
>
> The generic {test,set,*}_ti_thread_flag() helpers use the usual bitops,
> which perform accesses of sizeof(unsigned long) at a time, and for arm64
> these need to be naturally-aligned.
>
> We happen to get that alignment from subsequent fields in task_struct
> and/or thread_info, and for arm64 we don't seem to have a problem with
> tearing, but it feels somewhat fragile, and leaves me uneasy.
>
> Looking at the git log, it seems that x86 also use unsigned long until
> commit affa219b60a11b32 ("x86: change thread_info's flag field back to
> 32 bits"), where if I'm reading correctly, this was done to get rid of
> unnecessary padding. With THREAD_INFO_IN_STACK, thread_info::flags is
> immediately followed by a long on x86, so we save no padding.
>
> Given all that, can we make the generic thread_info::flags an unsigned
> long, matching what the thread flag helpers implicitly assume?
>

Yes.  Want to send the patch or should I?

--Andy

^ permalink raw reply	[flat|nested] 54+ messages in thread

* [kernel-hardening] Re: [RFC PATCH 2/8] thread_info: allow custom in-task thread_info
@ 2016-09-22 22:23             ` Andy Lutomirski
  0 siblings, 0 replies; 54+ messages in thread
From: Andy Lutomirski @ 2016-09-22 22:23 UTC (permalink / raw)
  To: Mark Rutland
  Cc: james.morse, AKASHI Takahiro, Kees Cook, Andrew Morton,
	linux-arm-kernel, lorenzo.pieralisi, kernel-hardening,
	suzuki.poulose, linux-kernel, Catalin Marinas, Ard Biesheuvel,
	Will Deacon

On Sep 21, 2016 12:28 AM, "Mark Rutland" <mark.rutland@arm.com> wrote:
>
> Hi Andy,
>
> On Fri, Sep 16, 2016 at 08:11:14AM -0700, Andy Lutomirski wrote:
> > > On Thu, Sep 15, 2016 at 11:37:47AM -0700, Andy Lutomirski wrote:
> > > Just to check, what do you mean to happen with the flags field? Should
> > > that always be in the generic thread_info? e.g.
> > >
> > > struct thread_info {
> > >         u32 flags;
> > > #ifdef arch_thread_info
> > >         struct arch_thread_info arch_ti;
> > > #endif
> > > };
> >
> > Exactly.  Possibly with a comment that using thread_struct should be
> > preferred and that arch_thread_info should be used only if some header
> > file requires access via current_thread_info() or task_thread_info().
>
> While fixing up these patches, I realised that I'm somewhat concerned by
> flags becoming a u32 (where it was previously an unsigned long for
> arm64).
>
> The generic {test,set,*}_ti_thread_flag() helpers use the usual bitops,
> which perform accesses of sizeof(unsigned long) at a time, and for arm64
> these need to be naturally-aligned.
>
> We happen to get that alignment from subsequent fields in task_struct
> and/or thread_info, and for arm64 we don't seem to have a problem with
> tearing, but it feels somewhat fragile, and leaves me uneasy.
>
> Looking at the git log, it seems that x86 also use unsigned long until
> commit affa219b60a11b32 ("x86: change thread_info's flag field back to
> 32 bits"), where if I'm reading correctly, this was done to get rid of
> unnecessary padding. With THREAD_INFO_IN_STACK, thread_info::flags is
> immediately followed by a long on x86, so we save no padding.
>
> Given all that, can we make the generic thread_info::flags an unsigned
> long, matching what the thread flag helpers implicitly assume?
>

Yes.  Want to send the patch or should I?

--Andy

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [RFC PATCH 2/8] thread_info: allow custom in-task thread_info
  2016-09-22 22:23             ` Andy Lutomirski
  (?)
@ 2016-09-23 17:31               ` Mark Rutland
  -1 siblings, 0 replies; 54+ messages in thread
From: Mark Rutland @ 2016-09-23 17:31 UTC (permalink / raw)
  To: Andy Lutomirski
  Cc: james.morse, AKASHI Takahiro, Kees Cook, Andrew Morton,
	linux-arm-kernel, lorenzo.pieralisi, kernel-hardening,
	suzuki.poulose, linux-kernel, Catalin Marinas, Ard Biesheuvel,
	Will Deacon

On Thu, Sep 22, 2016 at 03:23:59PM -0700, Andy Lutomirski wrote:
> On Sep 21, 2016 12:28 AM, "Mark Rutland" <mark.rutland@arm.com> wrote:

> > Given all that, can we make the generic thread_info::flags an unsigned
> > long, matching what the thread flag helpers implicitly assume?
> 
> Yes.  Want to send the patch or should I?

I've sent a patch out to LKML [1], though if that doesn't look right I'm
more than happy for you to send a correct one. ;)

Thanks,
Mark.

[1] http://lkml.kernel.org/r/1474651447-30447-1-git-send-email-mark.rutland@arm.com

^ permalink raw reply	[flat|nested] 54+ messages in thread

* [RFC PATCH 2/8] thread_info: allow custom in-task thread_info
@ 2016-09-23 17:31               ` Mark Rutland
  0 siblings, 0 replies; 54+ messages in thread
From: Mark Rutland @ 2016-09-23 17:31 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Sep 22, 2016 at 03:23:59PM -0700, Andy Lutomirski wrote:
> On Sep 21, 2016 12:28 AM, "Mark Rutland" <mark.rutland@arm.com> wrote:

> > Given all that, can we make the generic thread_info::flags an unsigned
> > long, matching what the thread flag helpers implicitly assume?
> 
> Yes.  Want to send the patch or should I?

I've sent a patch out to LKML [1], though if that doesn't look right I'm
more than happy for you to send a correct one. ;)

Thanks,
Mark.

[1] http://lkml.kernel.org/r/1474651447-30447-1-git-send-email-mark.rutland at arm.com

^ permalink raw reply	[flat|nested] 54+ messages in thread

* [kernel-hardening] Re: [RFC PATCH 2/8] thread_info: allow custom in-task thread_info
@ 2016-09-23 17:31               ` Mark Rutland
  0 siblings, 0 replies; 54+ messages in thread
From: Mark Rutland @ 2016-09-23 17:31 UTC (permalink / raw)
  To: Andy Lutomirski
  Cc: james.morse, AKASHI Takahiro, Kees Cook, Andrew Morton,
	linux-arm-kernel, lorenzo.pieralisi, kernel-hardening,
	suzuki.poulose, linux-kernel, Catalin Marinas, Ard Biesheuvel,
	Will Deacon

On Thu, Sep 22, 2016 at 03:23:59PM -0700, Andy Lutomirski wrote:
> On Sep 21, 2016 12:28 AM, "Mark Rutland" <mark.rutland@arm.com> wrote:

> > Given all that, can we make the generic thread_info::flags an unsigned
> > long, matching what the thread flag helpers implicitly assume?
> 
> Yes.  Want to send the patch or should I?

I've sent a patch out to LKML [1], though if that doesn't look right I'm
more than happy for you to send a correct one. ;)

Thanks,
Mark.

[1] http://lkml.kernel.org/r/1474651447-30447-1-git-send-email-mark.rutland@arm.com

^ permalink raw reply	[flat|nested] 54+ messages in thread

end of thread, other threads:[~2016-09-23 17:32 UTC | newest]

Thread overview: 54+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-09-15 13:49 [RFC PATCH 0/8] arm64: move thread_info off of the task stack Mark Rutland
2016-09-15 13:49 ` [kernel-hardening] " Mark Rutland
2016-09-15 13:49 ` Mark Rutland
2016-09-15 13:49 ` [RFC PATCH 1/8] thread_info: include <current.h> for THREAD_INFO_IN_TASK Mark Rutland
2016-09-15 13:49   ` [kernel-hardening] " Mark Rutland
2016-09-15 13:49   ` Mark Rutland
2016-09-15 13:49 ` [RFC PATCH 2/8] thread_info: allow custom in-task thread_info Mark Rutland
2016-09-15 13:49   ` [kernel-hardening] " Mark Rutland
2016-09-15 13:49   ` Mark Rutland
2016-09-15 18:37   ` Andy Lutomirski
2016-09-15 18:37     ` [kernel-hardening] " Andy Lutomirski
2016-09-15 18:37     ` Andy Lutomirski
2016-09-16 10:33     ` Mark Rutland
2016-09-16 10:33       ` [kernel-hardening] " Mark Rutland
2016-09-16 10:33       ` Mark Rutland
2016-09-16 15:11       ` Andy Lutomirski
2016-09-16 15:11         ` [kernel-hardening] " Andy Lutomirski
2016-09-16 15:11         ` Andy Lutomirski
2016-09-19 10:44         ` Mark Rutland
2016-09-19 10:44           ` [kernel-hardening] " Mark Rutland
2016-09-19 10:44           ` Mark Rutland
2016-09-21 10:28         ` Mark Rutland
2016-09-21 10:28           ` [kernel-hardening] " Mark Rutland
2016-09-21 10:28           ` Mark Rutland
2016-09-22 22:23           ` Andy Lutomirski
2016-09-22 22:23             ` [kernel-hardening] " Andy Lutomirski
2016-09-22 22:23             ` Andy Lutomirski
2016-09-23 17:31             ` Mark Rutland
2016-09-23 17:31               ` [kernel-hardening] " Mark Rutland
2016-09-23 17:31               ` Mark Rutland
2016-09-15 13:49 ` [RFC PATCH 3/8] arm64: thread_info remove stale items Mark Rutland
2016-09-15 13:49   ` [kernel-hardening] " Mark Rutland
2016-09-15 13:49   ` Mark Rutland
2016-09-15 13:49 ` [RFC PATCH 4/8] arm64: asm-offsets: remove unused definitions Mark Rutland
2016-09-15 13:49   ` [kernel-hardening] " Mark Rutland
2016-09-15 13:49   ` Mark Rutland
2016-09-15 13:49 ` [RFC PATCH 5/8] arm64: assembler: introduce ldr_this_cpu Mark Rutland
2016-09-15 13:49   ` [kernel-hardening] " Mark Rutland
2016-09-15 13:49   ` Mark Rutland
2016-09-15 13:49 ` [RFC PATCH 6/8] arm64: traps: use task_struct instead of thread_info Mark Rutland
2016-09-15 13:49   ` [kernel-hardening] " Mark Rutland
2016-09-15 13:49   ` Mark Rutland
2016-09-15 13:49 ` [RFC PATCH 7/8] arm64: move sp_el0 and tpidr_el1 into cpu_suspend_ctx Mark Rutland
2016-09-15 13:49   ` [kernel-hardening] " Mark Rutland
2016-09-15 13:49   ` Mark Rutland
2016-09-15 13:49 ` [RFC PATCH 8/8] arm64: split thread_info from task stack Mark Rutland
2016-09-15 13:49   ` [kernel-hardening] " Mark Rutland
2016-09-15 13:49   ` Mark Rutland
2016-09-21  1:26 ` [RFC PATCH 0/8] arm64: move thread_info off of the " Laura Abbott
2016-09-21  1:26   ` [kernel-hardening] " Laura Abbott
2016-09-21  1:26   ` Laura Abbott
2016-09-21 10:31   ` Mark Rutland
2016-09-21 10:31     ` [kernel-hardening] " Mark Rutland
2016-09-21 10:31     ` Mark Rutland

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.