#ifndef _I386_FRAMEASM_H_
#define _I386_FRAMEASM_H_
#ifdef _KERNEL_OPT
#include "opt_multiprocessor.h"
#include "opt_xen.h"
#endif
#ifdef XEN
#define TRAP_INSTR int $0x82
#endif
#if defined(XENPV)
#ifdef DIAGNOSTIC
#define CLI(reg) \
movl CPUVAR(CURLWP),reg ; \
cmpl $0, L_NOPREEMPT(reg); \
jne 199f; \
cmpb $0, CPUVAR(ILEVEL); \
jne 199f; \
movl CPUVAR(IDEPTH), reg; \
test reg, reg; \
jns 199f; \
movl $panicstr,reg ; \
cmpl $0, 0(reg); \
jne 199f; \
pushl $199f; \
movl $_C_LABEL(cli_panic), reg; \
pushl 0(reg); \
call _C_LABEL(panic); \
addl $8,%esp; \
199: movl CPUVAR(VCPU),reg ; \
movb $1,EVTCHN_UPCALL_MASK(reg)
#define STI(reg) \
movl CPUVAR(VCPU),reg ; \
cmpb $0, EVTCHN_UPCALL_MASK(reg) ; \
jne 198f ; \
movl $panicstr,reg ; \
cmpl $0, 0(reg); \
jne 198f; \
pushl $198f; \
movl $_C_LABEL(sti_panic), reg; \
pushl 0(reg); \
call _C_LABEL(panic); \
addl $8,%esp; \
198: movb $0,EVTCHN_UPCALL_MASK(reg)
#define STIC(reg) \
movl CPUVAR(VCPU),reg ; \
cmpb $0, EVTCHN_UPCALL_MASK(reg) ; \
jne 197f ; \
movl $panicstr,reg ; \
cmpl $0, 0(reg); \
jne 197f; \
pushl $197f; \
movl $_C_LABEL(sti_panic), reg; \
pushl 0(reg); \
call _C_LABEL(panic); \
addl $8,%esp; \
197: movl CPUVAR(VCPU),reg ; \
movb $0,EVTCHN_UPCALL_MASK(reg); \
testb $0xff,EVTCHN_UPCALL_PENDING(reg)
#else
#define CLI(reg) \
movl CPUVAR(VCPU),reg ; \
movb $1,EVTCHN_UPCALL_MASK(reg)
#define STI(reg) \
movl CPUVAR(VCPU),reg ; \
movb $0,EVTCHN_UPCALL_MASK(reg)
#define STIC(reg) \
movl CPUVAR(VCPU),reg ; \
movb $0,EVTCHN_UPCALL_MASK(reg); \
testb $0xff,EVTCHN_UPCALL_PENDING(reg)
#endif
#define CLI2(reg, reg2) \
movl CPUVAR(CURLWP),reg; \
incl L_NOPREEMPT(reg); \
movl CPUVAR(VCPU),reg2 ; \
movb $1,EVTCHN_UPCALL_MASK(reg2); \
decl L_NOPREEMPT(reg);
#define PUSHFCLI(reg, reg2) \
movl CPUVAR(CURLWP),reg; \
incl L_NOPREEMPT(reg); \
movl CPUVAR(VCPU),reg2 ; \
movzbl EVTCHN_UPCALL_MASK(reg2), reg2; \
pushl reg2 ; \
movl CPUVAR(VCPU),reg2 ; \
movb $1,EVTCHN_UPCALL_MASK(reg2); \
decl L_NOPREEMPT(reg);
#define POPF(reg) call _C_LABEL(xen_write_psl); \
addl $4,%esp
#else
#define CLI(reg) cli
#define CLI2(reg, reg2) cli
#define STI(reg) sti
#define PUSHFCLI(reg, reg2) pushf ; cli
#define POPF(reg) popf
#endif
#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
#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)
#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:
#define IDEPTH_INCR \
incl CPUVAR(IDEPTH); \
movl %esp, %eax; \
jne 999f; \
movl CPUVAR(INTRSTACK), %esp; \
999: pushl %eax; \
#define IDEPTH_DECR \
popl %esp; \
decl CPUVAR(IDEPTH)
#endif