1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
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
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
|
/* $NetBSD: frameasm.h,v 1.35 2022/07/30 14:11:00 riastradh Exp $ */
#ifndef _I386_FRAMEASM_H_
#define _I386_FRAMEASM_H_
#ifdef _KERNEL_OPT
#include "opt_multiprocessor.h"
#include "opt_xen.h"
#endif
#ifdef XEN
/* XXX assym.h */
#define TRAP_INSTR int $0x82
#define XEN_BLOCK_EVENTS(reg) movb $1,EVTCHN_UPCALL_MASK(reg)
#define XEN_UNBLOCK_EVENTS(reg) movb $0,EVTCHN_UPCALL_MASK(reg)
#define XEN_TEST_PENDING(reg) testb $0xFF,EVTCHN_UPCALL_PENDING(reg)
#endif /* XEN */
#if defined(XENPV)
#define CLI(reg) movl CPUVAR(VCPU),reg ; \
XEN_BLOCK_EVENTS(reg)
#define STI(reg) movl CPUVAR(VCPU),reg ; \
XEN_UNBLOCK_EVENTS(reg)
#define STIC(reg) movl CPUVAR(VCPU),reg ; \
XEN_UNBLOCK_EVENTS(reg) ; \
testb $0xff,EVTCHN_UPCALL_PENDING(reg)
#define PUSHF(reg) movl CPUVAR(VCPU),reg ; \
movzbl EVTCHN_UPCALL_MASK(reg), reg; \
pushl reg
#define POPF(reg) call _C_LABEL(xen_write_psl); \
addl $4,%esp
#else
#define CLI(reg) cli
#define STI(reg) sti
#define PUSHF(reg) pushf
#define POPF(reg) popf
#ifdef XENPVHVM
#define STIC(reg) sti ; \
movl CPUVAR(VCPU),reg ; \
XEN_UNBLOCK_EVENTS(reg) ; \
testb $0xff,EVTCHN_UPCALL_PENDING(reg)
#endif /* XENPVHVM */
#endif /* XENPV */
#define HP_NAME_CLAC 1
#define HP_NAME_STAC 2
#define HP_NAME_NOLOCK 3
#define HP_NAME_RETFENCE 4
#define HP_NAME_CAS_64 5
#define HP_NAME_SPLLOWER 6
#define HP_NAME_MUTEX_EXIT 7
#define HOTPATCH(name, size) \
123: ; \
.pushsection .rodata.hotpatch, "a" ; \
.byte name ; \
.byte size ; \
.long 123b ; \
.popsection
#define SMAP_ENABLE \
HOTPATCH(HP_NAME_CLAC, 3) ; \
.byte 0x90, 0x90, 0x90
#define SMAP_DISABLE \
HOTPATCH(HP_NAME_STAC, 3) ; \
.byte 0x90, 0x90, 0x90
/*
* These are used on interrupt or trap entry or exit.
*/
#define INTRENTRY \
SMAP_ENABLE ; \
subl $TF_PUSHSIZE,%esp ; \
movw %gs,TF_GS(%esp) ; \
movw %fs,TF_FS(%esp) ; \
movl %eax,TF_EAX(%esp) ; \
movw %es,TF_ES(%esp) ; \
movw %ds,TF_DS(%esp) ; \
movl $GSEL(GDATA_SEL, SEL_KPL),%eax ; \
movl %edi,TF_EDI(%esp) ; \
movl %esi,TF_ESI(%esp) ; \
movw %ax,%ds ; \
movl %ebp,TF_EBP(%esp) ; \
movw %ax,%es ; \
movl %ebx,TF_EBX(%esp) ; \
movw %ax,%gs ; \
movl %edx,TF_EDX(%esp) ; \
movl $GSEL(GCPU_SEL, SEL_KPL),%eax ; \
movl %ecx,TF_ECX(%esp) ; \
movl %eax,%fs ; \
cld
#define INTRFASTEXIT \
jmp intrfastexit
#define INTR_RECURSE_HWFRAME \
pushfl ; \
pushl %cs ; \
pushl %esi ;
#define CHECK_DEFERRED_SWITCH \
cmpl $0, CPUVAR(WANT_PMAPLOAD)
#define CHECK_ASTPENDING(reg) movl CPUVAR(CURLWP),reg ; \
cmpl $0, L_MD_ASTPENDING(reg)
#define CLEAR_ASTPENDING(reg) movl $0, L_MD_ASTPENDING(reg)
/*
* If the FPU state is not in the CPU, restore it. Executed with interrupts
* disabled.
*
* %ebx must not be modified
*/
#define HANDLE_DEFERRED_FPU \
movl CPUVAR(CURLWP),%eax ; \
testl $MDL_FPU_IN_CPU,L_MD_FLAGS(%eax) ; \
jnz 1f ; \
pushl %eax ; \
call _C_LABEL(fpu_handle_deferred) ; \
popl %eax ; \
orl $MDL_FPU_IN_CPU,L_MD_FLAGS(%eax) ; \
1:
/*
* IDEPTH_INCR:
* increase ci_idepth and switch to the interrupt stack if necessary.
* note that the initial value of ci_idepth is -1.
*
* => should be called with interrupt disabled.
* => save the old value of %esp in %eax.
*/
#define IDEPTH_INCR \
incl CPUVAR(IDEPTH); \
movl %esp, %eax; \
jne 999f; \
movl CPUVAR(INTRSTACK), %esp; \
999: pushl %eax; /* eax == pointer to intrframe */ \
/*
* IDEPTH_DECR:
* decrement ci_idepth and switch back to
* the original stack saved by IDEPTH_INCR.
*
* => should be called with interrupt disabled.
*/
#define IDEPTH_DECR \
popl %esp; \
decl CPUVAR(IDEPTH)
#endif /* _I386_FRAMEASM_H_ */
|