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