xref: /kvm-unit-tests/lib/arm/asm/thread_info.h (revision 0cc3a351b925928827baa4b69cf0e46ff5837083)
1 #ifndef _ASMARM_THREAD_INFO_H_
2 #define _ASMARM_THREAD_INFO_H_
3 /*
4  * Adapted from arch/arm64/include/asm/thread_info.h
5  *
6  * Copyright (C) 2017, Red Hat Inc, Andrew Jones <drjones@redhat.com>
7  *
8  * This work is licensed under the terms of the GNU GPL, version 2.
9  */
10 #include <asm/page.h>
11 
12 #define MIN_THREAD_SHIFT	14	/* THREAD_SIZE == 16K */
13 #if PAGE_SHIFT > MIN_THREAD_SHIFT
14 #define THREAD_SHIFT		PAGE_SHIFT
15 #define THREAD_SIZE		PAGE_SIZE
16 #define THREAD_MASK		PAGE_MASK
17 #define THREAD_ALIGNMENT	PAGE_SIZE
18 #else
19 #define THREAD_SHIFT		MIN_THREAD_SHIFT
20 #define THREAD_SIZE		(_AC(1,UL) << THREAD_SHIFT)
21 #define THREAD_MASK		(~(THREAD_SIZE-1))
22 #define THREAD_ALIGNMENT	THREAD_SIZE
23 #endif
24 
25 #ifndef __ASSEMBLER__
26 #include <asm/processor.h>
27 #include <alloc.h>
28 
29 #ifdef __arm__
30 #include <asm/ptrace.h>
31 /*
32  * arm needs room left at the top for the exception stacks,
33  * and the stack needs to be 8-byte aligned
34  */
35 #define THREAD_START_SP \
36 	((THREAD_SIZE - (sizeof(struct pt_regs) * 8)) & ~7)
37 #else
38 #define THREAD_START_SP		(THREAD_SIZE - 16)
39 #endif
40 
thread_stack_alloc(void)41 static inline void *thread_stack_alloc(void)
42 {
43 	void *sp = memalign(THREAD_ALIGNMENT, THREAD_SIZE);
44 	return sp + THREAD_START_SP;
45 }
46 
47 #define TIF_USER_MODE		(1U << 0)
48 
49 struct thread_info {
50 	int cpu;
51 	unsigned int flags;
52 	void *pgtable;
53 #ifdef __arm__
54 	exception_fn exception_handlers[EXCPTN_MAX];
55 #else
56 	vector_fn vector_handlers[VECTOR_MAX];
57 	exception_fn exception_handlers[VECTOR_MAX][EC_MAX];
58 #endif
59 	char ext[0];		/* allow unit tests to add extended info */
60 };
61 
thread_info_sp(unsigned long sp)62 static inline struct thread_info *thread_info_sp(unsigned long sp)
63 {
64 	return (struct thread_info *)(sp & ~(THREAD_SIZE - 1));
65 }
66 
67 register unsigned long current_stack_pointer asm("sp");
68 
current_thread_info(void)69 static inline struct thread_info *current_thread_info(void)
70 {
71 	return thread_info_sp(current_stack_pointer);
72 }
73 
74 extern void thread_info_init(struct thread_info *ti, unsigned int flags);
75 
76 #endif /* !__ASSEMBLER__ */
77 #endif /* _ASMARM_THREAD_INFO_H_ */
78