xref: /kvm-unit-tests/lib/arm/asm/thread_info.h (revision 0cc3a351b925928827baa4b69cf0e46ff5837083)
11693644dSAndrew Jones #ifndef _ASMARM_THREAD_INFO_H_
21693644dSAndrew Jones #define _ASMARM_THREAD_INFO_H_
31693644dSAndrew Jones /*
41693644dSAndrew Jones  * Adapted from arch/arm64/include/asm/thread_info.h
51693644dSAndrew Jones  *
649f758b8SAndrew Jones  * Copyright (C) 2017, Red Hat Inc, Andrew Jones <drjones@redhat.com>
71693644dSAndrew Jones  *
849f758b8SAndrew Jones  * This work is licensed under the terms of the GNU GPL, version 2.
91693644dSAndrew Jones  */
10ad14f089SAndrew Jones #include <asm/page.h>
111693644dSAndrew Jones 
1268ea0e0bSAndrew Jones #define MIN_THREAD_SHIFT	14	/* THREAD_SIZE == 16K */
1368ea0e0bSAndrew Jones #if PAGE_SHIFT > MIN_THREAD_SHIFT
1468ea0e0bSAndrew Jones #define THREAD_SHIFT		PAGE_SHIFT
15ad14f089SAndrew Jones #define THREAD_SIZE		PAGE_SIZE
1668ea0e0bSAndrew Jones #define THREAD_MASK		PAGE_MASK
17a2d06852SNikos Nikoleris #define THREAD_ALIGNMENT	PAGE_SIZE
18ad14f089SAndrew Jones #else
1968ea0e0bSAndrew Jones #define THREAD_SHIFT		MIN_THREAD_SHIFT
2068ea0e0bSAndrew Jones #define THREAD_SIZE		(_AC(1,UL) << THREAD_SHIFT)
2168ea0e0bSAndrew Jones #define THREAD_MASK		(~(THREAD_SIZE-1))
22a2d06852SNikos Nikoleris #define THREAD_ALIGNMENT	THREAD_SIZE
23ad14f089SAndrew Jones #endif
2468ea0e0bSAndrew Jones 
25*0cc3a351SSean Christopherson #ifndef __ASSEMBLER__
2668ea0e0bSAndrew Jones #include <asm/processor.h>
27632f935cSAndrew Jones #include <alloc.h>
2868ea0e0bSAndrew Jones 
2968ea0e0bSAndrew Jones #ifdef __arm__
3068ea0e0bSAndrew Jones #include <asm/ptrace.h>
3168ea0e0bSAndrew Jones /*
3268ea0e0bSAndrew Jones  * arm needs room left at the top for the exception stacks,
3368ea0e0bSAndrew Jones  * and the stack needs to be 8-byte aligned
3468ea0e0bSAndrew Jones  */
3568ea0e0bSAndrew Jones #define THREAD_START_SP \
3668ea0e0bSAndrew Jones 	((THREAD_SIZE - (sizeof(struct pt_regs) * 8)) & ~7)
3768ea0e0bSAndrew Jones #else
381693644dSAndrew Jones #define THREAD_START_SP		(THREAD_SIZE - 16)
3968ea0e0bSAndrew Jones #endif
401693644dSAndrew Jones 
thread_stack_alloc(void)41632f935cSAndrew Jones static inline void *thread_stack_alloc(void)
42632f935cSAndrew Jones {
43a2d06852SNikos Nikoleris 	void *sp = memalign(THREAD_ALIGNMENT, THREAD_SIZE);
44632f935cSAndrew Jones 	return sp + THREAD_START_SP;
45632f935cSAndrew Jones }
46632f935cSAndrew Jones 
47f6d10793SAndrew Jones #define TIF_USER_MODE		(1U << 0)
48f6d10793SAndrew Jones 
491693644dSAndrew Jones struct thread_info {
501693644dSAndrew Jones 	int cpu;
51f6d10793SAndrew Jones 	unsigned int flags;
5236b50de9SAndrew Jones 	void *pgtable;
53ad14f089SAndrew Jones #ifdef __arm__
54ad14f089SAndrew Jones 	exception_fn exception_handlers[EXCPTN_MAX];
55ad14f089SAndrew Jones #else
56ad14f089SAndrew Jones 	vector_fn vector_handlers[VECTOR_MAX];
57ad14f089SAndrew Jones 	exception_fn exception_handlers[VECTOR_MAX][EC_MAX];
58ad14f089SAndrew Jones #endif
591693644dSAndrew Jones 	char ext[0];		/* allow unit tests to add extended info */
601693644dSAndrew Jones };
611693644dSAndrew Jones 
thread_info_sp(unsigned long sp)62f6d10793SAndrew Jones static inline struct thread_info *thread_info_sp(unsigned long sp)
63f6d10793SAndrew Jones {
64f6d10793SAndrew Jones 	return (struct thread_info *)(sp & ~(THREAD_SIZE - 1));
65f6d10793SAndrew Jones }
66f6d10793SAndrew Jones 
671693644dSAndrew Jones register unsigned long current_stack_pointer asm("sp");
681693644dSAndrew Jones 
current_thread_info(void)691693644dSAndrew Jones static inline struct thread_info *current_thread_info(void)
701693644dSAndrew Jones {
71f6d10793SAndrew Jones 	return thread_info_sp(current_stack_pointer);
721693644dSAndrew Jones }
731693644dSAndrew Jones 
74f6d10793SAndrew Jones extern void thread_info_init(struct thread_info *ti, unsigned int flags);
75f6d10793SAndrew Jones 
76*0cc3a351SSean Christopherson #endif /* !__ASSEMBLER__ */
771693644dSAndrew Jones #endif /* _ASMARM_THREAD_INFO_H_ */
78