(regs->eflags & X86_EFLAGS_IF) ? "" : ", IN INTERRUPT CONTEXT");
}
-static void do_guest_trap(
- int trapnr, const struct cpu_user_regs *regs, int use_error_code)
+static void do_guest_trap(unsigned int trapnr,
+ const struct cpu_user_regs *regs)
{
struct vcpu *v = current;
struct trap_bounce *tb;
const struct trap_info *ti;
+ bool_t use_error_code;
+
+ ASSERT(trapnr < 32);
+
+ use_error_code = (TRAP_HAVE_EC & (1u << trapnr));
trace_pv_trap(trapnr, regs->eip, use_error_code, regs->error_code);
current->arch.debugreg[6] |= bpmatch | DR_STATUS_RESERVED_ONE;
if ( regs->eflags & X86_EFLAGS_TF )
current->arch.debugreg[6] |= DR_STEP;
- do_guest_trap(TRAP_debug, regs, 0);
+ do_guest_trap(TRAP_debug, regs);
}
}
struct vcpu *v = current;
struct trap_bounce *tb = &v->arch.pv_vcpu.trap_bounce;
- do_guest_trap(TRAP_machine_check, guest_cpu_user_regs(), 0);
+ do_guest_trap(TRAP_machine_check, guest_cpu_user_regs());
tb->flags &= ~TBF_EXCEPTION; /* not needed for MCE delivery path */
return !null_trap_bounce(v, tb);
}
{
struct vcpu *v = current;
struct trap_bounce *tb = &v->arch.pv_vcpu.trap_bounce;
- do_guest_trap(TRAP_nmi, guest_cpu_user_regs(), 0);
+ do_guest_trap(TRAP_nmi, guest_cpu_user_regs());
tb->flags &= ~TBF_EXCEPTION; /* not needed for NMI delivery path */
return !null_trap_bounce(v, tb);
}
panic("FATAL RESERVED TRAP %#x: %s", trapnr, trapstr(trapnr));
}
-static void do_trap(struct cpu_user_regs *regs, int use_error_code)
+void do_trap(struct cpu_user_regs *regs)
{
struct vcpu *curr = current;
unsigned int trapnr = regs->entry_vector;
if ( guest_mode(regs) )
{
- do_guest_trap(trapnr, regs, use_error_code);
+ do_guest_trap(trapnr, regs);
return;
}
trapnr, trapstr(trapnr), regs->error_code);
}
-#define DO_ERROR_NOCODE(name) \
-void do_##name(struct cpu_user_regs *regs) \
-{ \
- do_trap(regs, 0); \
-}
-
-#define DO_ERROR(name) \
-void do_##name(struct cpu_user_regs *regs) \
-{ \
- do_trap(regs, 1); \
-}
-
-DO_ERROR_NOCODE(divide_error)
-DO_ERROR_NOCODE(overflow)
-DO_ERROR_NOCODE(bounds)
-DO_ERROR( invalid_TSS)
-DO_ERROR( segment_not_present)
-DO_ERROR( stack_segment)
-DO_ERROR_NOCODE(coprocessor_error)
-DO_ERROR( alignment_check)
-DO_ERROR_NOCODE(simd_coprocessor_error)
-
/* Returns 0 if not handled, and non-0 for success. */
int rdmsr_hypervisor_regs(uint32_t idx, uint64_t *val)
{
{
if ( !emulate_invalid_rdtscp(regs) &&
!emulate_forced_invalid_op(regs) )
- do_guest_trap(TRAP_invalid_op, regs, 0);
+ do_guest_trap(TRAP_invalid_op, regs);
return;
}
return;
}
- do_guest_trap(TRAP_int3, regs, 0);
+ do_guest_trap(TRAP_int3, regs);
}
static void reserved_bit_page_fault(
if ( lock || rep_prefix || opsize_prefix
|| !(v->arch.pv_vcpu.ctrlreg[4] & X86_CR4_OSXSAVE) )
{
- do_guest_trap(TRAP_invalid_op, regs, 0);
+ do_guest_trap(TRAP_invalid_op, regs);
goto skip;
}
(((ar >> 13) & 3) < (regs->cs & 3)) ||
((ar & _SEGMENT_TYPE) != 0xc00) )
{
- do_guest_trap(TRAP_gp_fault, regs, 1);
+ do_guest_trap(TRAP_gp_fault, regs);
return;
}
if ( !(ar & _SEGMENT_P) )
{
- do_guest_trap(TRAP_no_segment, regs, 1);
+ do_guest_trap(TRAP_no_segment, regs);
return;
}
dpl = (ar >> 13) & 3;
!(ar & _SEGMENT_P) ||
!(ar & _SEGMENT_CODE) )
{
- do_guest_trap(TRAP_gp_fault, regs, 1);
+ do_guest_trap(TRAP_gp_fault, regs);
return;
}
if ( jump < 0 )
{
fail:
- do_guest_trap(TRAP_gp_fault, regs, 1);
+ do_guest_trap(TRAP_gp_fault, regs);
skip:
return;
}
!(ar & _SEGMENT_P) ||
((ar & _SEGMENT_CODE) && !(ar & _SEGMENT_WR)) )
{
- do_guest_trap(TRAP_gp_fault, regs, 1);
+ do_guest_trap(TRAP_gp_fault, regs);
return;
}
ASSERT((opnd_sel & ~3) == regs->error_code);
if ( dpl < (opnd_sel & 3) )
{
- do_guest_trap(TRAP_gp_fault, regs, 1);
+ do_guest_trap(TRAP_gp_fault, regs);
return;
}
((ar >> 13) & 3) != (regs->cs & 3)) )
{
regs->error_code = sel;
- do_guest_trap(TRAP_gp_fault, regs, 1);
+ do_guest_trap(TRAP_gp_fault, regs);
return;
}
if ( !(ar & _SEGMENT_P) )
{
regs->error_code = sel;
- do_guest_trap(TRAP_no_segment, regs, 1);
+ do_guest_trap(TRAP_no_segment, regs);
return;
}
if ( off > limit )
{
regs->error_code = 0;
- do_guest_trap(TRAP_gp_fault, regs, 1);
+ do_guest_trap(TRAP_gp_fault, regs);
return;
}
/* Inner stack known only for kernel ring. */
if ( (sel & 3) != GUEST_KERNEL_RPL(v->domain) )
{
- do_guest_trap(TRAP_gp_fault, regs, 1);
+ do_guest_trap(TRAP_gp_fault, regs);
return;
}
esp = v->arch.pv_vcpu.kernel_sp;
!(ar & _SEGMENT_WR) )
{
regs->error_code = ss & ~3;
- do_guest_trap(TRAP_invalid_tss, regs, 1);
+ do_guest_trap(TRAP_invalid_tss, regs);
return;
}
if ( !(ar & _SEGMENT_P) ||
!check_stack_limit(ar, limit, esp, (4 + nparm) * 4) )
{
regs->error_code = ss & ~3;
- do_guest_trap(TRAP_stack_error, regs, 1);
+ do_guest_trap(TRAP_stack_error, regs);
return;
}
stkp = (unsigned int *)(unsigned long)((unsigned int)base + esp);
if ( !compat_access_ok(stkp - 4 - nparm, (4 + nparm) * 4) )
{
- do_guest_trap(TRAP_gp_fault, regs, 1);
+ do_guest_trap(TRAP_gp_fault, regs);
return;
}
push(regs->ss);
(ar & _SEGMENT_CODE) ||
!(ar & _SEGMENT_WR) ||
!check_stack_limit(ar, limit, esp + nparm * 4, nparm * 4) )
- return do_guest_trap(TRAP_gp_fault, regs, 1);
+ return do_guest_trap(TRAP_gp_fault, regs);
ustkp = (unsigned int *)(unsigned long)((unsigned int)base + regs->_esp + nparm * 4);
if ( !compat_access_ok(ustkp - nparm, nparm * 4) )
{
- do_guest_trap(TRAP_gp_fault, regs, 1);
+ do_guest_trap(TRAP_gp_fault, regs);
return;
}
do
if ( !read_descriptor(ss, v, regs, &base, &limit, &ar, 0) ||
((ar >> 13) & 3) != (sel & 3) )
{
- do_guest_trap(TRAP_gp_fault, regs, 1);
+ do_guest_trap(TRAP_gp_fault, regs);
return;
}
if ( !check_stack_limit(ar, limit, esp, 2 * 4) )
{
regs->error_code = 0;
- do_guest_trap(TRAP_stack_error, regs, 1);
+ do_guest_trap(TRAP_stack_error, regs);
return;
}
stkp = (unsigned int *)(unsigned long)((unsigned int)base + esp);
if ( !compat_access_ok(stkp - 2, 2 * 4) )
{
- do_guest_trap(TRAP_gp_fault, regs, 1);
+ do_guest_trap(TRAP_gp_fault, regs);
return;
}
}
if ( permit_softint(TI_GET_DPL(ti), v, regs) )
{
regs->eip += 2;
- do_guest_trap(vector, regs, 0);
+ do_guest_trap(vector, regs);
return;
}
}
}
/* Pass on GPF as is. */
- do_guest_trap(TRAP_gp_fault, regs, 1);
+ do_guest_trap(TRAP_gp_fault, regs);
return;
gp_in_kernel:
if ( curr->arch.pv_vcpu.ctrlreg[0] & X86_CR0_TS )
{
- do_guest_trap(TRAP_no_device, regs, 0);
+ do_guest_trap(TRAP_no_device, regs);
curr->arch.pv_vcpu.ctrlreg[0] &= ~X86_CR0_TS;
}
else
v->arch.debugreg[6] = read_debugreg(6);
ler_enable();
- do_guest_trap(TRAP_debug, regs, 0);
+ do_guest_trap(TRAP_debug, regs);
return;
out: