1#include <xtf/asm_macros.h>
2#include <xtf/extable.h>
3#include <arch/segment.h>
5 .section .text.user, "ax", @progbits
7.macro GEN_ABS_STUB seg load_seg
9ENTRY(stub_\seg\()_abs) /* exinfo_t stub_\seg_abs(unsigned long addr) */
12 * Switch segment if necessary. The old segment is preserved on the
13 * stack for the duration of the test.
18 push $(GDTE_AVAIL1 << 3 | 3)
22 push $(GDTE_AVAIL1 << 3 | 3)
28 /* The bottom bit of 'addr' encodes FEP. */
36 * No exception if we don't fault.
37 * Reused by the 64bit case, and careful to not clobber flags.
481: movabsb %al, 0x8000000040000000
521: movb $0, %\seg:0xc0000000
541: movabsb %al, %\seg:0x8000000040000000
60 /* Restore the old segment if necessary. */
72 _ASM_EXTABLE_HANDLER(1b, 2b, ex_record_fault_eax)
73ENDFUNC(stub_\seg\()_abs)
76.macro GEN_REG_STUB seg reg load_seg preserve_reg
78ENTRY(stub_\seg\()_\reg) /* exinfo_t stub_\seg_\reg(unsigned long addr) */
82 * Switch segment if necessary. The old segment is preserved on the
83 * stack for the duration of the test.
88 push $(GDTE_AVAIL1 << 3 | 3)
92 push $(GDTE_AVAIL1 << 3 | 3)
98 /* Preserve the subject register if necessary. */
103 /* Move 'addr' into \reg */
110 /* The bottom bit of 'addr' encodes FEP. */
115 .ifeqs "\seg", "none"
1181: movb $0, %\seg:(%\reg)
121 /* No exception if we didn't fault. */
124 /* Restore the register if necessary. */
130 /* Restore the old segment if necessary. */
132 .ifeqs "\seg", "none"
142 _ASM_EXTABLE_HANDLER(1b, 2b, ex_record_fault_eax)
143ENDFUNC(stub_\seg\()_\reg)
147 * Instantiate `GEN_ABS_STUB foreach segment` and `GEN_REG_STUB foreach
148 * segment, foreach register`, calculaing whether the segment needs loading
149 * (implicit %ds, explicit %{e,d,f,g}s), and whether the register needs
150 * preserving (depends on the calling ABI).
152.local seg_mask, seg_idx, reg_mask, reg_idx
160.irp seg, none, es, cs, ss, ds, fs, gs
162 GEN_ABS_STUB \seg, (seg_mask & (1 << seg_idx))
165 reg_mask = 0b00011111
167 .irp reg, eax, ecx, edx, ebx, esp, ebp, esi, edi
169 reg_mask = 0b0001110000001111
171 .irp reg, rax, rcx, rdx, rbx, rsp, rbp, rsi, rdi, r8, r9, r10, r11, r12, r13, r14, r15
174 GEN_REG_STUB \seg, \reg, (seg_mask & (1 << seg_idx)), (reg_mask & (1 << reg_idx))
175 reg_idx = reg_idx - 1
178 seg_idx = seg_idx - 1
185 * indent-tabs-mode: nil