* Sample usage:
* <pre>
* asm volatile ("1: $INSN; 2:"
- * _ASM_EXTABLE_HANDLER(1b, 2b, ex_record_fault_eax)
- * : "=a" (fault) : "0" (0));
+ * _ASM_EXTABLE_HANDLER(1b, 2b, @%c[ex])
+ * : "=a" (fault) : "0" (0), [ex] "i" (ex_record_fault_eax));
* </pre>
*/
bool ex_record_fault_eax(struct cpu_regs *regs, const struct extable_entry *ex);
* Sample usage:
* <pre>
* asm volatile ("1: $INSN; 2:"
- * _ASM_EXTABLE_HANDLER(1b, 2b, ex_record_fault_edi)
- * : "=D" (fault) : "0" (0));
+ * _ASM_EXTABLE_HANDLER(1b, 2b, @%c[ex])
+ * : "=D" (fault) : "0" (0), [ex] "i" (ex_record_fault_edi));
* </pre>
*/
bool ex_record_fault_edi(struct cpu_regs *regs, const struct extable_entry *ex);
uint32_t lo, hi, new_idx;
asm volatile("1: rdmsr; 2:"
- _ASM_EXTABLE_HANDLER(1b, 2b, ex_rdmsr_safe)
+ _ASM_EXTABLE_HANDLER(1b, 2b, %c[ex])
: "=a" (lo), "=d" (hi), "=c" (new_idx)
- : "c" (idx));
+ : "c" (idx), [ex] "i" (ex_rdmsr_safe));
bool fault = idx != new_idx;
uint32_t new_idx;
asm volatile ("1: wrmsr; 2:"
- _ASM_EXTABLE_HANDLER(1b, 2b, ex_wrmsr_safe)
+ _ASM_EXTABLE_HANDLER(1b, 2b, %c[ex])
: "=c" (new_idx)
: "c" (idx), "a" ((uint32_t)val),
- "d" ((uint32_t)(val >> 32)));
+ "d" ((uint32_t)(val >> 32)),
+ [ex] "i" (ex_wrmsr_safe));
return idx != new_idx;
}
unsigned int fault = 0, tmp;
asm volatile("1: cpuid; 2:"
- _ASM_EXTABLE_HANDLER(1b, 2b, ex_record_fault_edi)
+ _ASM_EXTABLE_HANDLER(1b, 2b, %c[ex])
: "=a" (tmp), "+D" (fault)
- : "a" (0)
+ : "a" (0), [ex] "i" (ex_record_fault_edi)
: "ebx", "ecx", "edx");
return fault;
asm volatile(_ASM_XEN_FEP
"1: cpuid; 2:"
- _ASM_EXTABLE_HANDLER(1b, 2b, ex_record_fault_edi)
+ _ASM_EXTABLE_HANDLER(1b, 2b, %c[ex])
: "=a" (tmp), "+D" (fault)
- : "a" (0)
+ : "a" (0), [ex] "i" (ex_record_fault_edi)
: "ebx", "ecx", "edx");
return fault;
"jz 1f;"
_ASM_XEN_FEP
"1: fnop; 2:"
- _ASM_EXTABLE_HANDLER(1b, 2b, ex_record_fault_eax)
+ _ASM_EXTABLE_HANDLER(1b, 2b, %c[ex])
: "+a" (fault)
- : [fep] "q" (force));
+ : [fep] "q" (force),
+ [ex] "i" (ex_record_fault_eax));
return fault;
}
"jz 1f;"
_ASM_XEN_FEP
"1: wait; 2:"
- _ASM_EXTABLE_HANDLER(1b, 2b, ex_record_fault_eax)
+ _ASM_EXTABLE_HANDLER(1b, 2b, %c[ex])
: "+a" (fault)
- : [fep] "q" (force));
+ : [fep] "q" (force),
+ [ex] "i" (ex_record_fault_eax));
return fault;
}
"jz 1f;"
_ASM_XEN_FEP
"1: movq %%mm0, %%mm0; 2:"
- _ASM_EXTABLE_HANDLER(1b, 2b, ex_record_fault_eax)
+ _ASM_EXTABLE_HANDLER(1b, 2b, %c[ex])
: "+a" (fault)
- : [fep] "q" (force));
+ : [fep] "q" (force),
+ [ex] "i" (ex_record_fault_eax));
return fault;
}
"jz 1f;"
_ASM_XEN_FEP
"1: movups %%xmm0, %%xmm0; 2:"
- _ASM_EXTABLE_HANDLER(1b, 2b, ex_record_fault_eax)
+ _ASM_EXTABLE_HANDLER(1b, 2b, %c[ex])
: "+a" (fault)
- : [fep] "q" (force));
+ : [fep] "q" (force),
+ [ex] "i" (ex_record_fault_eax));
return fault;
}
static bool seen_fault;
-bool ex_fault(struct cpu_regs *regs, const struct extable_entry *ex)
+static bool ex_fault(struct cpu_regs *regs, const struct extable_entry *ex)
{
/* Expect to see #PF indicating that a reserved bits was set. */
if ( regs->entry_vector == X86_EXC_PF &&
ptr = _p((4ULL << PAE_L3_PT_SHIFT) + MB(1));
asm volatile ("1:mov (%[ptr]), %[val]; 2:"
- _ASM_EXTABLE_HANDLER(1b, 2b, ex_fault)
+ _ASM_EXTABLE_HANDLER(1b, 2b, %c[ex])
: [val] "=q" (val)
- : [ptr] "r" (ptr)
+ : [ptr] "r" (ptr),
+ [ex] "i" (ex_fault)
: "memory");
if ( seen_fault )
"insn_stub_end:;"
);
-bool ex_fault(struct cpu_regs *regs, const struct extable_entry *ex)
+static bool ex_fault(struct cpu_regs *regs, const struct extable_entry *ex)
{
if ( regs->entry_vector == X86_EXC_GP && regs->error_code == 0 )
{
* instructions don't get lost.
*/
asm volatile ("call *%[ptr];"
- _ASM_EXTABLE_HANDLER(-1, 0, ex_fault)
+ _ASM_EXTABLE_HANDLER(-1, 0, %c[ex])
: "=a" (res)
: "0" (0),
- [ptr] "r" (stub)
+ [ptr] "r" (stub),
+ [ex] "i" (ex_fault)
: "memory");
if ( res != 0xc0de )
write_fs(0);
asm volatile (_ASM_XEN_FEP
"1: mov %%fs:0, %[dst]; 2:"
- _ASM_EXTABLE_HANDLER(1b, 2b, ex_record_fault_edi)
+ _ASM_EXTABLE_HANDLER(1b, 2b, %c[ex])
: "=D" (fault),
[dst] "=r" (tmp)
- : "D" (0));
+ : "D" (0),
+ [ex] "i" (ex_record_fault_edi));
switch ( fault )
{
asm volatile (_ASM_XEN_FEP
"1: mov %[sel], %%fs; 2:"
- _ASM_EXTABLE_HANDLER(1b, 2b, ex_record_fault_eax)
+ _ASM_EXTABLE_HANDLER(1b, 2b, %c[ex])
: "=a" (fault)
: "a" (0),
- [sel] "r" (4));
+ [sel] "r" (4),
+ [ex] "i" (ex_record_fault_eax));
switch ( fault )
{
/* Attempt to load %fs from the LDT. */
asm volatile ("1: mov %[sel], %%fs; 2:"
- _ASM_EXTABLE_HANDLER(1b, 2b, ex_record_fault_eax)
+ _ASM_EXTABLE_HANDLER(1b, 2b, %c[ex])
: "+a" (fault)
- : [sel] "r" (LDT_SEL));
+ : [sel] "r" (LDT_SEL),
+ [ex] "i" (ex_record_fault_eax));
return fault;
}
"start_32bit:;"
_ASM_XEN_FEP
"1: int $%c[df]; 2:"
- _ASM_EXTABLE_HANDLER(1b, 2b, ex_record_fault_eax)
+ _ASM_EXTABLE_HANDLER(1b, 2b, %c[ex])
/* Return to 64bit. */
"ljmpl $%c[cs], $1f;"
: "+a" (fault)
: [df] "i" (X86_EXC_DF),
[cs32] "i" (GDTE_CS32_DPL3 * 8 + 3),
- [cs] "i" (__USER_CS));
+ [cs] "i" (__USER_CS),
+ [ex] "i" (ex_record_fault_eax));
return fault;
}
{
/* Poke the emulator. */
asm volatile (_ASM_XEN_FEP "1: .byte 0x66; cmpxchg8b %[ptr]; 2:"
- _ASM_EXTABLE_HANDLER(1b, 2b, ex_record_fault_edi)
+ _ASM_EXTABLE_HANDLER(1b, 2b, %c[ex])
: "=A" (prev), [ptr] "+m" (mem), "+D" (fault)
: "c" ((uint32_t)(new >> 32)), "b" ((uint32_t)new),
- "0" (old));
+ "0" (old), [ex] "i" (ex_record_fault_edi));
if ( fault == EXINFO_SYM(UD, 0) )
return xtf_success("Success: Not vulnerable to XSA-200\n");