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 <drjo...@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 <drjo...@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

--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to