[PATCH 07/18] arm/arm64: introduce thread_info

Andrew Jones
2015-02-01T18:35:05Z

For smp we need a way to maintain thread local state. The bottom
of the thread stack is a good place, and is where Linux puts it.
So we just steal the concept of the thread_info structure that
lives at the bottom of the stack in Linux, and introduce it to
kvm-unit-tests/arm[64]. For starters we just have cpu index for
state, and that's implicitly initialized to zero for CPU0 already.
So, as we don't have secondary cpus yet, there's not much to do.

Additionally, sneak a small fixup in to the initial stack setup
for arm64. We were assuming that spsel is EL1 after reset, which
has been true so far, but let's not assume.

Signed-off-by: Andrew Jones <drjones@redhat.com>
---
arm/cstart.S | 2 +-
arm/cstart64.S | 5 ++++-
arm/flat.lds | 6 ++++++
arm/selftest.c | 8 ++++----
lib/arm/asm/thread_info.h | 27 +++++++++++++++++++++++++++
lib/arm64/asm/thread_info.h | 1 +
6 files changed, 43 insertions(+), 6 deletions(-)
create mode 100644 lib/arm/asm/thread_info.h
create mode 100644 lib/arm64/asm/thread_info.h

diff --git a/arm/cstart.S b/arm/cstart.S
index 39fac8f1e1bd8..fd02aaab268d7 100644
--- a/arm/cstart.S
+++ b/arm/cstart.S
@@ -27,7 +27,7 @@ start:
* put the dtb in r0. This allows setup to be consistent
* with arm64.
*/
- ldr sp, =stacktop
+ ldr sp, =stackptr
mov r0, r2
push {r0-r1}

diff --git a/arm/cstart64.S b/arm/cstart64.S
index 9047e7ef14646..2fe15eb1d3972 100644
--- a/arm/cstart64.S
+++ b/arm/cstart64.S
@@ -21,7 +21,10 @@ start:
* The physical address of the dtb is in x0, x1-x3 are reserved
* See the kernel doc Documentation/arm64/booting.txt
*/
- adr x4, stacktop
+ mov x4, #1
+ msr spsel, x4
+ isb
+ adr x4, stackptr
mov sp, x4
stp x0, x1, [sp, #-16]!

diff --git a/arm/flat.lds b/arm/flat.lds
index a8849ee0939a8..df80d3678e556 100644
--- a/arm/flat.lds
+++ b/arm/flat.lds
@@ -18,6 +18,12 @@ SECTIONS
edata = .;
. += 64K;
. = ALIGN(64K);
+ /*
+ * stack depth is ~16K, see THREAD_SIZE
+ * sp must be 16 byte aligned for arm64, and 8 byte aligned for arm
+ * sp must always be strictly less than the true stacktop
+ */
+ stackptr = . - 16;
stacktop = .;
}

diff --git a/arm/selftest.c b/arm/selftest.c
index de816f8142c54..05ca7efe95f83 100644
--- a/arm/selftest.c
+++ b/arm/selftest.c
@@ -11,7 +11,7 @@
#include <asm/ptrace.h>
#include <asm/asm-offsets.h>
#include <asm/processor.h>
-#include <asm/page.h>
+#include <asm/thread_info.h>

static void assert_args(int num_args, int needed_args)
{
@@ -313,9 +313,9 @@ int main(int argc, char **argv)

} else if (strcmp(argv[0], "vectors-user") == 0) {

- void *sp = memalign(PAGE_SIZE, PAGE_SIZE);
- memset(sp, 0, PAGE_SIZE);
- start_usr(check_vectors, NULL, (unsigned long)sp + PAGE_SIZE);
+ void *sp = memalign(THREAD_SIZE, THREAD_SIZE);
+ start_usr(check_vectors, NULL,
+ (unsigned long)sp + THREAD_START_SP);
}

return report_summary();
diff --git a/lib/arm/asm/thread_info.h b/lib/arm/asm/thread_info.h
new file mode 100644
index 0000000000000..ea86f142a7d93
--- /dev/null
+++ b/lib/arm/asm/thread_info.h
@@ -0,0 +1,27 @@
+#ifndef _ASMARM_THREAD_INFO_H_
+#define _ASMARM_THREAD_INFO_H_
+/*
+ * Adapted from arch/arm64/include/asm/thread_info.h
+ *
+ * Copyright (C) 2015, Red Hat Inc, Andrew Jones <drjones@redhat.com>
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.
+ */
+
+#define THREAD_SIZE 16384
+#define THREAD_START_SP (THREAD_SIZE - 16)
+
+struct thread_info {
+ int cpu;
+ char ext[0]; /* allow unit tests to add extended info */
+};
+
+register unsigned long current_stack_pointer asm("sp");
+
+static inline struct thread_info *current_thread_info(void)
+{
+ return (struct thread_info *)
+ (current_stack_pointer & ~(THREAD_SIZE - 1));
+}
+
+#endif /* _ASMARM_THREAD_INFO_H_ */
diff --git a/lib/arm64/asm/thread_info.h b/lib/arm64/asm/thread_info.h
new file mode 100644
index 0000000000000..b01fa8f34b3bf
--- /dev/null
+++ b/lib/arm64/asm/thread_info.h
@@ -0,0 +1 @@
+#include "../../arm/asm/thread_info.h"
--
1.9.3