enter_exit.h 3.6 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
/*
 * enter_exit.h
 *
 * These functions should be invoked when an LCD/thread starts
 * executing, and before the thread exits (or when the thread
 * exits).
 *
 * Copyright: University of Utah
 */
#ifndef LCD_DOMAINS_ENTER_EXIT_H
#define LCD_DOMAINS_ENTER_EXIT_H

Charles Jacobsen's avatar
Charles Jacobsen committed
13
14
#include <linux/kernel.h>

15
16
17
18
19
20
21
22
23
24
25
26
#ifdef LCD_ISOLATE
#define LCD_MAYBE_NORETURN __noreturn
#else
#define LCD_MAYBE_NORETURN
#endif

/**
 * lcd_enter -- Initializes runtime environment for an LCD
 *
 * No matter if you are isolated or non-isolated, this should be called 
 * before you invoked any other functions in the liblcd interface.
 *
27
28
29
 * IMPORTANT: It is highly recommended that you use the LCD_MAIN macro
 * (see below).
 *
30
31
32
33
34
35
36
37
38
 * Semantics:
 *
 *    -- Isolated code: this bootstraps the environment inside the container
 *    -- Non-isolated code: this switches a non-isolated thread into
 *                          "LCD mode": initializes a cspace and other data 
 *                          structures for the caller, so that it can
 *                          start creating LCDs, doing ipc, etc.
 */
int lcd_enter(void);
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
/**
 * LCD_MAIN -- Tweaks the stack so that libasync works correctly
 *
 * Here is a usage example:
 *
 *        static int my_main(void)
 *        {
 *                 int ret;
 *
 *                 ret = lcd_enter();
 *
 *                 // Do some things
 *
 *                 lcd_exit(ret);
 *
 *                 return ret; // lcd_exit returns for non-isolated
 *        }
 *
 *        int __init my_module_init(void)
 *        {
 *             int ret;
 *
 *             LCD_MAIN({
 *
 *                     ret = my_main();
 *
 *             });
 *
 *             return ret;
 *        }
 *        module_init(my_module_init);
 *
71
72
73
 * Implementation Note: Isolated code has a 0 return address at the
 * top (beginning) of every stack, so this hack is only necessary for
 * non-isolated code right now.
74
 */
75
76
77
#ifdef LCD_ISOLATE
#define LCD_MAIN(_CODE)	do { _CODE } while(0)
#else
Vikram Narayanan's avatar
Vikram Narayanan committed
78
79
80
#define LCD_MAIN(_CODE)	do { _CODE } while(0)
#endif
#if 0
81
#define LCD_MAIN(_CODE)	do {						\
82
83
84
									\
		/* NULL out return address on stack so that libasync */ \
		/* will stop stack walk here.			     */ \
85
86
87
88
89
90
91
92
93
94
95
		/*						     */	\
		/* XXX: A touch of arch-dependent code here, but     */	\
		/* no biggie. When I used gcc's			     */	\
		/* __builtin_frame_address it broke (gcc null'd out  */	\
		/* the return address, but didn't restore it ... ?)  */	\
		/*						     */	\
		volatile void **__frame_ptr;				\
		volatile void *__saved_ret_addr;			\
		asm ("movq %%rbp, %0" : "=g"(__frame_ptr) ::);		\
		__saved_ret_addr = *(__frame_ptr + 1);			\
		*(__frame_ptr + 1) = NULL;				\
96
97
98
99
									\
		do { _CODE } while(0);					\
									\
		/* Restore old return address to stack. */		\
100
		*(__frame_ptr + 1) = __saved_ret_addr;			\
101
102
									\
	} while (0);
103
#endif
104
105
106
107
108
109
110
111
112
113
114
115
/**
 * lcd_exit -- Exit from LCD (mode) with return value
 *
 * This should be invoked when you are exiting an isolated LCD 
 * (think: user-level exit call), or when you are a non-isolated
 * thread and want to exit out of LCD mode. Tears down all data
 * structures associated with LCD.
 *
 * For isolated code, this function does not return (just like
 * regular user-level exit).
 */
void LCD_MAYBE_NORETURN lcd_exit(int retval);
116
117
118
119
#define LCD_EXIT() ({							\
	*((volatile void**)__builtin_frame_address(0) + 1) = NULL;	\
	lcd_enter();							\
		})
120
121
122
123
124
125
126
127
128
129
130
131
/**
 * lcd_abort -- Abruptly exit from LCD
 *
 * For non-isolated code, this is equivalent to lcd_exit.
 *
 * For isolated code, this immediately exits out of the LCD without
 * trying to tear down its environment.
 */
void LCD_MAYBE_NORETURN lcd_abort(void);

#endif /* LCD_DOMAINS_ENTER_EXIT_H */