mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 02:01:24 +01:00
x86: Introduce X86_ET_* constants in x86-defns.h
The FRED spec architecturalises the Event Type encoding, previously exposed only in VMCB/VMCS fields. Introduce the constants in x86-defns.h, making them a bit more concise, and retire enum x86_event_type. Take the opportunity to introduce X86_ET_OTHER. It's absence appears to be a bug in Introspection's Monitor Trap Flag support, when considering VECTORING events during another VMExit. No functional change. Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com> Reviewed-by: Jan Beulich <jbeulich@suse.com>
This commit is contained in:
1 parent
7fd80df2bf
commit
1eeb7c3379
15 files changed
+96
-102
No files matched your search
@@ -308,7 +308,7 @@ int xendevicemodel_set_mem_type(
|
||||
* @parm domid the domain id to be serviced
|
||||
* @parm vcpu the vcpu id
|
||||
* @parm vector the interrupt vector
|
||||
* @parm type the event type (see the definition of enum x86_event_type)
|
||||
* @parm type the event type (see x86-defns.h:X86_ET_*)
|
||||
* @parm error_code the error code or ~0 to skip
|
||||
* @parm insn_len the instruction length
|
||||
* @parm extra type-specific extra data (%cr2 for #PF, pending_dbg for #DB)
|
||||
|
||||
@@ -219,10 +219,10 @@ int hvm_event_needs_reinjection(uint8_t type, uint8_t vector)
|
||||
{
|
||||
switch ( type )
|
||||
{
|
||||
case X86_EVENTTYPE_EXT_INTR:
|
||||
case X86_EVENTTYPE_NMI:
|
||||
case X86_ET_EXT_INTR:
|
||||
case X86_ET_NMI:
|
||||
return 1;
|
||||
case X86_EVENTTYPE_HW_EXCEPTION:
|
||||
case X86_ET_HW_EXC:
|
||||
/*
|
||||
* SVM uses type 3 ("HW Exception") for #OF and #BP. We explicitly
|
||||
* check for these vectors, as they are really SW Exceptions. SVM has
|
||||
@@ -1738,7 +1738,7 @@ void hvm_inject_event(const struct x86_event *event)
|
||||
{
|
||||
struct vcpu *curr = current;
|
||||
const uint8_t vector = event->vector;
|
||||
const bool has_ec = ((event->type == X86_EVENTTYPE_HW_EXCEPTION) &&
|
||||
const bool has_ec = ((event->type == X86_ET_HW_EXC) &&
|
||||
(vector < 32) && ((X86_EXC_HAVE_EC & (1u << vector))));
|
||||
|
||||
ASSERT(vector == event->vector); /* Confirm no truncation. */
|
||||
|
||||
@@ -35,7 +35,7 @@ static void svm_inject_nmi(struct vcpu *v)
|
||||
|
||||
event.raw = 0;
|
||||
event.v = true;
|
||||
event.type = X86_EVENTTYPE_NMI;
|
||||
event.type = X86_ET_NMI;
|
||||
event.vector = X86_EXC_NMI;
|
||||
|
||||
ASSERT(!vmcb->event_inj.v);
|
||||
@@ -56,7 +56,7 @@ static void svm_inject_extint(struct vcpu *v, int vector)
|
||||
|
||||
event.raw = 0;
|
||||
event.v = true;
|
||||
event.type = X86_EVENTTYPE_EXT_INTR;
|
||||
event.type = X86_ET_EXT_INTR;
|
||||
event.vector = vector;
|
||||
|
||||
ASSERT(!vmcb->event_inj.v);
|
||||
|
||||
+23
-24
@@ -1185,7 +1185,7 @@ static void svm_emul_swint_injection(struct x86_event *event)
|
||||
|
||||
/* ICEBP sets the External Event bit despite being an instruction. */
|
||||
ec = (trap << 3) | X86_XEC_IDT |
|
||||
(type == X86_EVENTTYPE_PRI_SW_EXCEPTION ? X86_XEC_EXT : 0);
|
||||
(type == X86_ET_PRIV_SW_EXC ? X86_XEC_EXT : 0);
|
||||
|
||||
/*
|
||||
* TODO: This does not cover the v8086 mode with CR4.VME case
|
||||
@@ -1243,7 +1243,7 @@ static void svm_emul_swint_injection(struct x86_event *event)
|
||||
goto raise_exception;
|
||||
|
||||
/* ICEBP counts as a hardware event, and bypasses the dpl check. */
|
||||
if ( type != X86_EVENTTYPE_PRI_SW_EXCEPTION &&
|
||||
if ( type != X86_ET_PRIV_SW_EXC &&
|
||||
vmcb_get_cpl(vmcb) > ((idte.b >> 13) & 3) )
|
||||
goto raise_exception;
|
||||
|
||||
@@ -1264,7 +1264,7 @@ static void svm_emul_swint_injection(struct x86_event *event)
|
||||
|
||||
raise_exception:
|
||||
event->vector = fault;
|
||||
event->type = X86_EVENTTYPE_HW_EXCEPTION;
|
||||
event->type = X86_ET_HW_EXC;
|
||||
event->insn_len = 0;
|
||||
event->error_code = ec;
|
||||
}
|
||||
@@ -1285,11 +1285,11 @@ static void cf_check svm_inject_event(const struct x86_event *event)
|
||||
* further fault shouldn't occur during delivery. This covers the fact
|
||||
* that hardware doesn't perform DPL checking on injection.
|
||||
*/
|
||||
if ( event->type == X86_EVENTTYPE_PRI_SW_EXCEPTION ||
|
||||
(!cpu_has_svm_nrips && (event->type >= X86_EVENTTYPE_SW_INTERRUPT)) )
|
||||
if ( event->type == X86_ET_PRIV_SW_EXC ||
|
||||
(!cpu_has_svm_nrips && (event->type >= X86_ET_SW_INT)) )
|
||||
svm_emul_swint_injection(&_event);
|
||||
|
||||
switch ( _event.vector | -(_event.type == X86_EVENTTYPE_SW_INTERRUPT) )
|
||||
switch ( _event.vector | -(_event.type == X86_ET_SW_INT) )
|
||||
{
|
||||
case X86_EXC_DB:
|
||||
if ( regs->eflags & X86_EFLAGS_TF )
|
||||
@@ -1308,13 +1308,13 @@ static void cf_check svm_inject_event(const struct x86_event *event)
|
||||
break;
|
||||
|
||||
case X86_EXC_PF:
|
||||
ASSERT(_event.type == X86_EVENTTYPE_HW_EXCEPTION);
|
||||
ASSERT(_event.type == X86_ET_HW_EXC);
|
||||
curr->arch.hvm.guest_cr[2] = _event.cr2;
|
||||
vmcb_set_cr2(vmcb, _event.cr2);
|
||||
break;
|
||||
}
|
||||
|
||||
if ( eventinj.v && (eventinj.type == X86_EVENTTYPE_HW_EXCEPTION) )
|
||||
if ( eventinj.v && (eventinj.type == X86_ET_HW_EXC) )
|
||||
{
|
||||
_event.vector = hvm_combine_hw_exceptions(
|
||||
eventinj.vector, _event.vector);
|
||||
@@ -1339,15 +1339,15 @@ static void cf_check svm_inject_event(const struct x86_event *event)
|
||||
*/
|
||||
switch ( _event.type )
|
||||
{
|
||||
case X86_EVENTTYPE_SW_INTERRUPT: /* int $n */
|
||||
case X86_ET_SW_INT: /* int $n */
|
||||
if ( cpu_has_svm_nrips )
|
||||
vmcb->nextrip = regs->rip + _event.insn_len;
|
||||
else
|
||||
regs->rip += _event.insn_len;
|
||||
eventinj.type = X86_EVENTTYPE_SW_INTERRUPT;
|
||||
eventinj.type = X86_ET_SW_INT;
|
||||
break;
|
||||
|
||||
case X86_EVENTTYPE_PRI_SW_EXCEPTION: /* icebp */
|
||||
case X86_ET_PRIV_SW_EXC: /* icebp */
|
||||
/*
|
||||
* icebp's injection must always be emulated, as hardware does not
|
||||
* special case HW_EXCEPTION with vector 1 (#DB) as having trap
|
||||
@@ -1356,10 +1356,10 @@ static void cf_check svm_inject_event(const struct x86_event *event)
|
||||
regs->rip += _event.insn_len;
|
||||
if ( cpu_has_svm_nrips )
|
||||
vmcb->nextrip = regs->rip;
|
||||
eventinj.type = X86_EVENTTYPE_HW_EXCEPTION;
|
||||
eventinj.type = X86_ET_HW_EXC;
|
||||
break;
|
||||
|
||||
case X86_EVENTTYPE_SW_EXCEPTION: /* int3, into */
|
||||
case X86_ET_SW_EXC: /* int3, into */
|
||||
/*
|
||||
* Hardware special cases HW_EXCEPTION with vectors 3 and 4 as having
|
||||
* trap semantics, and will perform DPL checks.
|
||||
@@ -1368,11 +1368,11 @@ static void cf_check svm_inject_event(const struct x86_event *event)
|
||||
vmcb->nextrip = regs->rip + _event.insn_len;
|
||||
else
|
||||
regs->rip += _event.insn_len;
|
||||
eventinj.type = X86_EVENTTYPE_HW_EXCEPTION;
|
||||
eventinj.type = X86_ET_HW_EXC;
|
||||
break;
|
||||
|
||||
default:
|
||||
eventinj.type = X86_EVENTTYPE_HW_EXCEPTION;
|
||||
eventinj.type = X86_ET_HW_EXC;
|
||||
eventinj.ev = (_event.error_code != X86_EVENT_NO_EC);
|
||||
eventinj.ec = _event.error_code;
|
||||
break;
|
||||
@@ -1391,8 +1391,7 @@ static void cf_check svm_inject_event(const struct x86_event *event)
|
||||
ASSERT(!eventinj.ev || eventinj.ec == (uint16_t)eventinj.ec);
|
||||
vmcb->event_inj = eventinj;
|
||||
|
||||
if ( _event.vector == X86_EXC_PF &&
|
||||
_event.type == X86_EVENTTYPE_HW_EXCEPTION )
|
||||
if ( _event.vector == X86_EXC_PF && _event.type == X86_ET_HW_EXC )
|
||||
TRACE(TRC_HVM_PF_INJECT64, _event.error_code,
|
||||
_event.cr2, _event.cr2 >> 32);
|
||||
else
|
||||
@@ -2694,12 +2693,12 @@ void asmlinkage svm_vmexit_handler(void)
|
||||
|
||||
if ( likely(exit_reason != VMEXIT_ICEBP) )
|
||||
{
|
||||
trap_type = X86_EVENTTYPE_HW_EXCEPTION;
|
||||
trap_type = X86_ET_HW_EXC;
|
||||
insn_len = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
trap_type = X86_EVENTTYPE_PRI_SW_EXCEPTION;
|
||||
trap_type = X86_ET_PRIV_SW_EXC;
|
||||
insn_len = svm_get_insn_len(v, INSTR_ICEBP);
|
||||
|
||||
if ( !insn_len )
|
||||
@@ -2736,13 +2735,13 @@ void asmlinkage svm_vmexit_handler(void)
|
||||
{
|
||||
rc = hvm_monitor_debug(regs->rip,
|
||||
HVM_MONITOR_SOFTWARE_BREAKPOINT,
|
||||
X86_EVENTTYPE_SW_EXCEPTION,
|
||||
X86_ET_SW_EXC,
|
||||
insn_len, 0);
|
||||
if ( rc < 0 )
|
||||
goto unexpected_exit_type;
|
||||
if ( !rc )
|
||||
hvm_inject_exception(X86_EXC_BP,
|
||||
X86_EVENTTYPE_SW_EXCEPTION,
|
||||
X86_ET_SW_EXC,
|
||||
insn_len, X86_EVENT_NO_EC);
|
||||
}
|
||||
break;
|
||||
@@ -2835,13 +2834,13 @@ void asmlinkage svm_vmexit_handler(void)
|
||||
* ICEBP is handled specially, and already has fault
|
||||
* semantics.
|
||||
*/
|
||||
case X86_EVENTTYPE_HW_EXCEPTION:
|
||||
case X86_ET_HW_EXC:
|
||||
if ( vmcb->exit_int_info.vector == X86_EXC_BP ||
|
||||
vmcb->exit_int_info.vector == X86_EXC_OF )
|
||||
break;
|
||||
/* Fallthrough */
|
||||
case X86_EVENTTYPE_EXT_INTR:
|
||||
case X86_EVENTTYPE_NMI:
|
||||
case X86_ET_EXT_INTR:
|
||||
case X86_ET_NMI:
|
||||
insn_len = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
+19
-23
@@ -1994,14 +1994,13 @@ void vmx_inject_extint(int trap, uint8_t source)
|
||||
if ( pin_based_cntrl & PIN_BASED_EXT_INTR_MASK ) {
|
||||
nvmx_enqueue_n2_exceptions (v,
|
||||
INTR_INFO_VALID_MASK |
|
||||
MASK_INSR(X86_EVENTTYPE_EXT_INTR, INTR_INFO_INTR_TYPE_MASK) |
|
||||
MASK_INSR(X86_ET_EXT_INTR, INTR_INFO_INTR_TYPE_MASK) |
|
||||
MASK_INSR(trap, INTR_INFO_VECTOR_MASK),
|
||||
X86_EVENT_NO_EC, source);
|
||||
return;
|
||||
}
|
||||
}
|
||||
__vmx_inject_exception(trap, X86_EVENTTYPE_EXT_INTR,
|
||||
X86_EVENT_NO_EC);
|
||||
__vmx_inject_exception(trap, X86_ET_EXT_INTR, X86_EVENT_NO_EC);
|
||||
}
|
||||
|
||||
void vmx_inject_nmi(void)
|
||||
@@ -2014,23 +2013,22 @@ void vmx_inject_nmi(void)
|
||||
if ( pin_based_cntrl & PIN_BASED_NMI_EXITING ) {
|
||||
nvmx_enqueue_n2_exceptions (v,
|
||||
INTR_INFO_VALID_MASK |
|
||||
MASK_INSR(X86_EVENTTYPE_NMI, INTR_INFO_INTR_TYPE_MASK) |
|
||||
MASK_INSR(X86_ET_NMI, INTR_INFO_INTR_TYPE_MASK) |
|
||||
MASK_INSR(X86_EXC_NMI, INTR_INFO_VECTOR_MASK),
|
||||
X86_EVENT_NO_EC, hvm_intsrc_nmi);
|
||||
return;
|
||||
}
|
||||
}
|
||||
__vmx_inject_exception(2, X86_EVENTTYPE_NMI,
|
||||
X86_EVENT_NO_EC);
|
||||
__vmx_inject_exception(2, X86_ET_NMI, X86_EVENT_NO_EC);
|
||||
}
|
||||
|
||||
/*
|
||||
* Generate a virtual event in the guest.
|
||||
* NOTES:
|
||||
* - INT 3 (CC) and INTO (CE) are X86_EVENTTYPE_SW_EXCEPTION;
|
||||
* - INT nn (CD nn) is X86_EVENTTYPE_SW_INTERRUPT;
|
||||
* - #DB is X86_EVENTTYPE_HW_EXCEPTION, except when generated by
|
||||
* opcode 0xf1 (which is X86_EVENTTYPE_PRI_SW_EXCEPTION)
|
||||
* - INT3 (CC) and INTO (CE) are X86_ET_SW_EXC;
|
||||
* - INT $n (CD nn) is X86_ET_SW_INT;
|
||||
* - #DB is X86_ET_HW_EXC, except when generated by
|
||||
* ICEBP/INT1 (which is X86_ET_PRIV_SW_EXC)
|
||||
*/
|
||||
static void cf_check vmx_inject_event(const struct x86_event *event)
|
||||
{
|
||||
@@ -2038,7 +2036,7 @@ static void cf_check vmx_inject_event(const struct x86_event *event)
|
||||
struct vcpu *curr = current;
|
||||
struct x86_event _event = *event;
|
||||
|
||||
switch ( _event.vector | -(_event.type == X86_EVENTTYPE_SW_INTERRUPT) )
|
||||
switch ( _event.vector | -(_event.type == X86_ET_SW_INT) )
|
||||
{
|
||||
case X86_EXC_DB:
|
||||
if ( guest_cpu_user_regs()->eflags & X86_EFLAGS_TF )
|
||||
@@ -2069,7 +2067,7 @@ static void cf_check vmx_inject_event(const struct x86_event *event)
|
||||
break;
|
||||
|
||||
case X86_EXC_PF:
|
||||
ASSERT(_event.type == X86_EVENTTYPE_HW_EXCEPTION);
|
||||
ASSERT(_event.type == X86_ET_HW_EXC);
|
||||
curr->arch.hvm.guest_cr[2] = _event.cr2;
|
||||
break;
|
||||
}
|
||||
@@ -2080,8 +2078,7 @@ static void cf_check vmx_inject_event(const struct x86_event *event)
|
||||
__vmread(VM_ENTRY_INTR_INFO, &intr_info);
|
||||
|
||||
if ( unlikely(intr_info & INTR_INFO_VALID_MASK) &&
|
||||
(MASK_EXTR(intr_info, INTR_INFO_INTR_TYPE_MASK) ==
|
||||
X86_EVENTTYPE_HW_EXCEPTION) )
|
||||
(MASK_EXTR(intr_info, INTR_INFO_INTR_TYPE_MASK) == X86_ET_HW_EXC) )
|
||||
{
|
||||
_event.vector = hvm_combine_hw_exceptions(
|
||||
(uint8_t)intr_info, _event.vector);
|
||||
@@ -2089,7 +2086,7 @@ static void cf_check vmx_inject_event(const struct x86_event *event)
|
||||
_event.error_code = 0;
|
||||
}
|
||||
|
||||
if ( _event.type >= X86_EVENTTYPE_SW_INTERRUPT )
|
||||
if ( _event.type >= X86_ET_SW_INT )
|
||||
__vmwrite(VM_ENTRY_INSTRUCTION_LEN, _event.insn_len);
|
||||
|
||||
if ( nestedhvm_vcpu_in_guestmode(curr) &&
|
||||
@@ -2105,8 +2102,7 @@ static void cf_check vmx_inject_event(const struct x86_event *event)
|
||||
else
|
||||
__vmx_inject_exception(_event.vector, _event.type, _event.error_code);
|
||||
|
||||
if ( (_event.vector == X86_EXC_PF) &&
|
||||
(_event.type == X86_EVENTTYPE_HW_EXCEPTION) )
|
||||
if ( (_event.vector == X86_EXC_PF) && (_event.type == X86_ET_HW_EXC) )
|
||||
TRACE(TRC_HVM_PF_INJECT64, _event.error_code,
|
||||
curr->arch.hvm.guest_cr[2], curr->arch.hvm.guest_cr[2] >> 32);
|
||||
else
|
||||
@@ -3951,7 +3947,7 @@ static void vmx_propagate_intr(unsigned long intr)
|
||||
else
|
||||
event.error_code = X86_EVENT_NO_EC;
|
||||
|
||||
if ( event.type >= X86_EVENTTYPE_SW_INTERRUPT )
|
||||
if ( event.type >= X86_ET_SW_INT )
|
||||
{
|
||||
__vmread(VM_EXIT_INSTRUCTION_LEN, &tmp);
|
||||
event.insn_len = tmp;
|
||||
@@ -3990,7 +3986,7 @@ static void vmx_idtv_reinject(unsigned long idtv_info)
|
||||
*/
|
||||
if ( cpu_has_vmx_vnmi &&
|
||||
((idtv_info & INTR_INFO_INTR_TYPE_MASK) ==
|
||||
MASK_INSR(X86_EVENTTYPE_NMI, INTR_INFO_INTR_TYPE_MASK)) )
|
||||
MASK_INSR(X86_ET_NMI, INTR_INFO_INTR_TYPE_MASK)) )
|
||||
{
|
||||
unsigned long intr_info;
|
||||
|
||||
@@ -4115,7 +4111,7 @@ void asmlinkage vmx_vmexit_handler(struct cpu_user_regs *regs)
|
||||
do_machine_check(regs);
|
||||
if ( (vector == X86_EXC_NMI) &&
|
||||
((intr_info & INTR_INFO_INTR_TYPE_MASK) ==
|
||||
MASK_INSR(X86_EVENTTYPE_NMI, INTR_INFO_INTR_TYPE_MASK)) )
|
||||
MASK_INSR(X86_ET_NMI, INTR_INFO_INTR_TYPE_MASK)) )
|
||||
{
|
||||
do_nmi(regs);
|
||||
enable_nmis();
|
||||
@@ -4317,7 +4313,7 @@ void asmlinkage vmx_vmexit_handler(struct cpu_user_regs *regs)
|
||||
unsigned long trap_type = MASK_EXTR(intr_info,
|
||||
INTR_INFO_INTR_TYPE_MASK);
|
||||
|
||||
if ( trap_type >= X86_EVENTTYPE_SW_INTERRUPT )
|
||||
if ( trap_type >= X86_ET_SW_INT )
|
||||
__vmread(VM_EXIT_INSTRUCTION_LEN, &insn_len);
|
||||
|
||||
rc = hvm_monitor_debug(regs->rip,
|
||||
@@ -4342,7 +4338,7 @@ void asmlinkage vmx_vmexit_handler(struct cpu_user_regs *regs)
|
||||
__vmread(VM_EXIT_INSTRUCTION_LEN, &insn_len);
|
||||
rc = hvm_monitor_debug(regs->rip,
|
||||
HVM_MONITOR_SOFTWARE_BREAKPOINT,
|
||||
X86_EVENTTYPE_SW_EXCEPTION,
|
||||
X86_ET_SW_EXC,
|
||||
insn_len, 0);
|
||||
|
||||
if ( rc < 0 )
|
||||
@@ -4391,7 +4387,7 @@ void asmlinkage vmx_vmexit_handler(struct cpu_user_regs *regs)
|
||||
break;
|
||||
case X86_EXC_NMI:
|
||||
if ( MASK_EXTR(intr_info, INTR_INFO_INTR_TYPE_MASK) !=
|
||||
X86_EVENTTYPE_NMI )
|
||||
X86_ET_NMI )
|
||||
goto exit_and_crash;
|
||||
TRACE(TRC_HVM_NMI);
|
||||
/* Already handled above. */
|
||||
|
||||
@@ -1346,7 +1346,7 @@ static void sync_exception_state(struct vcpu *v)
|
||||
|
||||
switch ( MASK_EXTR(nvmx->intr.intr_info, INTR_INFO_INTR_TYPE_MASK) )
|
||||
{
|
||||
case X86_EVENTTYPE_EXT_INTR:
|
||||
case X86_ET_EXT_INTR:
|
||||
/* rename exit_reason to EXTERNAL_INTERRUPT */
|
||||
set_vvmcs(v, VM_EXIT_REASON, EXIT_REASON_EXTERNAL_INTERRUPT);
|
||||
set_vvmcs(v, EXIT_QUALIFICATION, 0);
|
||||
@@ -1355,14 +1355,14 @@ static void sync_exception_state(struct vcpu *v)
|
||||
: 0);
|
||||
break;
|
||||
|
||||
case X86_EVENTTYPE_HW_EXCEPTION:
|
||||
case X86_EVENTTYPE_SW_INTERRUPT:
|
||||
case X86_EVENTTYPE_SW_EXCEPTION:
|
||||
case X86_ET_HW_EXC:
|
||||
case X86_ET_SW_INT:
|
||||
case X86_ET_SW_EXC:
|
||||
/* throw to L1 */
|
||||
set_vvmcs(v, VM_EXIT_INTR_INFO, nvmx->intr.intr_info);
|
||||
set_vvmcs(v, VM_EXIT_INTR_ERROR_CODE, nvmx->intr.error_code);
|
||||
break;
|
||||
case X86_EVENTTYPE_NMI:
|
||||
case X86_ET_NMI:
|
||||
set_vvmcs(v, VM_EXIT_REASON, EXIT_REASON_EXCEPTION_NMI);
|
||||
set_vvmcs(v, EXIT_QUALIFICATION, 0);
|
||||
set_vvmcs(v, VM_EXIT_INTR_INFO, nvmx->intr.intr_info);
|
||||
@@ -2445,7 +2445,7 @@ int nvmx_n2_vmexit_handler(struct cpu_user_regs *regs,
|
||||
case EXIT_REASON_EXCEPTION_NMI:
|
||||
{
|
||||
unsigned long intr_info;
|
||||
u32 valid_mask = MASK_INSR(X86_EVENTTYPE_HW_EXCEPTION,
|
||||
u32 valid_mask = MASK_INSR(X86_ET_HW_EXC,
|
||||
INTR_INFO_INTR_TYPE_MASK) |
|
||||
INTR_INFO_VALID_MASK;
|
||||
u64 exec_bitmap;
|
||||
|
||||
@@ -724,7 +724,7 @@ static inline void pv_inject_hw_exception(unsigned int vector, int errcode)
|
||||
{
|
||||
const struct x86_event event = {
|
||||
.vector = vector,
|
||||
.type = X86_EVENTTYPE_HW_EXCEPTION,
|
||||
.type = X86_ET_HW_EXC,
|
||||
.error_code = errcode,
|
||||
};
|
||||
|
||||
@@ -735,7 +735,7 @@ static inline void pv_inject_DB(unsigned long pending_dbg)
|
||||
{
|
||||
struct x86_event event = {
|
||||
.vector = X86_EXC_DB,
|
||||
.type = X86_EVENTTYPE_HW_EXCEPTION,
|
||||
.type = X86_ET_HW_EXC,
|
||||
.error_code = X86_EVENT_NO_EC,
|
||||
};
|
||||
|
||||
@@ -748,7 +748,7 @@ static inline void pv_inject_page_fault(int errcode, unsigned long cr2)
|
||||
{
|
||||
struct x86_event event = {
|
||||
.vector = X86_EXC_PF,
|
||||
.type = X86_EVENTTYPE_HW_EXCEPTION,
|
||||
.type = X86_ET_HW_EXC,
|
||||
.error_code = errcode,
|
||||
};
|
||||
|
||||
@@ -761,7 +761,7 @@ static inline void pv_inject_sw_interrupt(unsigned int vector)
|
||||
{
|
||||
const struct x86_event event = {
|
||||
.vector = vector,
|
||||
.type = X86_EVENTTYPE_SW_INTERRUPT,
|
||||
.type = X86_ET_SW_INT,
|
||||
.error_code = X86_EVENT_NO_EC,
|
||||
};
|
||||
|
||||
|
||||
@@ -522,7 +522,7 @@ static inline void hvm_inject_hw_exception(unsigned int vector, int errcode)
|
||||
{
|
||||
struct x86_event event = {
|
||||
.vector = vector,
|
||||
.type = X86_EVENTTYPE_HW_EXCEPTION,
|
||||
.type = X86_ET_HW_EXC,
|
||||
.error_code = errcode,
|
||||
};
|
||||
|
||||
@@ -533,7 +533,7 @@ static inline void hvm_inject_page_fault(int errcode, unsigned long cr2)
|
||||
{
|
||||
struct x86_event event = {
|
||||
.vector = X86_EXC_PF,
|
||||
.type = X86_EVENTTYPE_HW_EXCEPTION,
|
||||
.type = X86_ET_HW_EXC,
|
||||
.error_code = errcode,
|
||||
};
|
||||
|
||||
|
||||
@@ -204,4 +204,18 @@
|
||||
#define X86_MT_UCM 0x07 /* UC- */
|
||||
#define X86_NUM_MT 0x08
|
||||
|
||||
/*
|
||||
* Event Types.
|
||||
*
|
||||
* These encodings were first used in VMCB/VMCS fields, but have become
|
||||
* architectural in the FRED spec.
|
||||
*/
|
||||
#define X86_ET_EXT_INTR 0 /* External Interrupt */
|
||||
#define X86_ET_NMI 2 /* NMI */
|
||||
#define X86_ET_HW_EXC 3 /* Hardware Exception (#PF/#GP/etc) */
|
||||
#define X86_ET_SW_INT 4 /* Software Interrupt (INT $n) */
|
||||
#define X86_ET_PRIV_SW_EXC 5 /* Privileged Software Exception (ICEBP/INT1) */
|
||||
#define X86_ET_SW_EXC 6 /* Software Exception (INT3, INTO) */
|
||||
#define X86_ET_OTHER 7 /* Misc event: MTF=0, SYSCALL=1, SYSENTER=2 */
|
||||
|
||||
#endif /* __XEN_X86_DEFNS_H__ */
|
||||
@@ -2701,7 +2701,7 @@ static int cf_check sh_page_fault(
|
||||
* else is an emulation bug, or a guest playing with the instruction
|
||||
* stream under Xen's feet.
|
||||
*/
|
||||
if ( emul_ctxt.ctxt.event.type == X86_EVENTTYPE_HW_EXCEPTION &&
|
||||
if ( emul_ctxt.ctxt.event.type == X86_ET_HW_EXC &&
|
||||
((emul_ctxt.ctxt.event.vector == X86_EXC_PF) ||
|
||||
(((emul_ctxt.ctxt.event.vector == X86_EXC_GP) ||
|
||||
(emul_ctxt.ctxt.event.vector == X86_EXC_SS)) &&
|
||||
|
||||
@@ -379,7 +379,7 @@ int pv_ro_page_fault(unsigned long addr, struct cpu_user_regs *regs)
|
||||
* concurrent pagetable update). Anything else is an emulation bug,
|
||||
* or a guest playing with the instruction stream under Xen's feet.
|
||||
*/
|
||||
if ( ctxt.event.type == X86_EVENTTYPE_HW_EXCEPTION &&
|
||||
if ( ctxt.event.type == X86_ET_HW_EXC &&
|
||||
ctxt.event.vector == X86_EXC_PF )
|
||||
pv_inject_event(&ctxt.event);
|
||||
else
|
||||
|
||||
@@ -29,14 +29,14 @@ void pv_inject_event(const struct x86_event *event)
|
||||
bool use_error_code;
|
||||
|
||||
ASSERT(vector == event->vector); /* Confirm no truncation. */
|
||||
if ( event->type == X86_EVENTTYPE_HW_EXCEPTION )
|
||||
if ( event->type == X86_ET_HW_EXC )
|
||||
{
|
||||
ASSERT(vector < 32);
|
||||
use_error_code = X86_EXC_HAVE_EC & (1u << vector);
|
||||
}
|
||||
else
|
||||
{
|
||||
ASSERT(event->type == X86_EVENTTYPE_SW_INTERRUPT);
|
||||
ASSERT(event->type == X86_ET_SW_INT);
|
||||
use_error_code = false;
|
||||
}
|
||||
if ( use_error_code )
|
||||
@@ -51,7 +51,7 @@ void pv_inject_event(const struct x86_event *event)
|
||||
tb->cs = ti->cs;
|
||||
tb->eip = ti->address;
|
||||
|
||||
switch ( vector | -(event->type == X86_EVENTTYPE_SW_INTERRUPT) )
|
||||
switch ( vector | -(event->type == X86_ET_SW_INT) )
|
||||
{
|
||||
case X86_EXC_PF:
|
||||
curr->arch.pv.ctrlreg[2] = event->cr2;
|
||||
|
||||
@@ -2372,19 +2372,19 @@ x86_emulate(
|
||||
{
|
||||
case 0xcc: /* int3 */
|
||||
ctxt->event.vector = X86_EXC_BP;
|
||||
ctxt->event.type = X86_EVENTTYPE_SW_EXCEPTION;
|
||||
ctxt->event.type = X86_ET_SW_EXC;
|
||||
break;
|
||||
case 0xcd: /* int imm8 */
|
||||
ctxt->event.vector = imm1;
|
||||
ctxt->event.type = X86_EVENTTYPE_SW_INTERRUPT;
|
||||
ctxt->event.type = X86_ET_SW_INT;
|
||||
break;
|
||||
case 0xce: /* into */
|
||||
ctxt->event.vector = X86_EXC_OF;
|
||||
ctxt->event.type = X86_EVENTTYPE_SW_EXCEPTION;
|
||||
ctxt->event.type = X86_ET_SW_EXC;
|
||||
break;
|
||||
case 0xf1: /* icebp */
|
||||
ctxt->event.vector = X86_EXC_DB;
|
||||
ctxt->event.type = X86_EVENTTYPE_PRI_SW_EXCEPTION;
|
||||
ctxt->event.type = X86_ET_PRIV_SW_EXC;
|
||||
break;
|
||||
}
|
||||
ctxt->event.error_code = X86_EVENT_NO_EC;
|
||||
@@ -8597,16 +8597,14 @@ static void __init __maybe_unused build_assertions(void)
|
||||
BUILD_BUG_ON(x86_seg_fs != 4);
|
||||
BUILD_BUG_ON(x86_seg_gs != 5);
|
||||
|
||||
/*
|
||||
* Check X86_EVENTTYPE_* against VMCB EVENTINJ and VMCS INTR_INFO type
|
||||
* fields.
|
||||
*/
|
||||
BUILD_BUG_ON(X86_EVENTTYPE_EXT_INTR != 0);
|
||||
BUILD_BUG_ON(X86_EVENTTYPE_NMI != 2);
|
||||
BUILD_BUG_ON(X86_EVENTTYPE_HW_EXCEPTION != 3);
|
||||
BUILD_BUG_ON(X86_EVENTTYPE_SW_INTERRUPT != 4);
|
||||
BUILD_BUG_ON(X86_EVENTTYPE_PRI_SW_EXCEPTION != 5);
|
||||
BUILD_BUG_ON(X86_EVENTTYPE_SW_EXCEPTION != 6);
|
||||
/* Check X86_ET_* against VMCB EVENTINJ and VMCS INTR_INFO type fields. */
|
||||
BUILD_BUG_ON(X86_ET_EXT_INTR != 0);
|
||||
BUILD_BUG_ON(X86_ET_NMI != 2);
|
||||
BUILD_BUG_ON(X86_ET_HW_EXC != 3);
|
||||
BUILD_BUG_ON(X86_ET_SW_INT != 4);
|
||||
BUILD_BUG_ON(X86_ET_PRIV_SW_EXC != 5);
|
||||
BUILD_BUG_ON(X86_ET_SW_EXC != 6);
|
||||
BUILD_BUG_ON(X86_ET_OTHER != 7);
|
||||
}
|
||||
|
||||
#ifndef NDEBUG
|
||||
|
||||
@@ -59,24 +59,11 @@ static inline bool is_x86_system_segment(enum x86_segment seg)
|
||||
return seg >= x86_seg_tr && seg < x86_seg_none;
|
||||
}
|
||||
|
||||
/*
|
||||
* x86 event types. This enumeration is valid for:
|
||||
* Intel VMX: {VM_ENTRY,VM_EXIT,IDT_VECTORING}_INTR_INFO[10:8]
|
||||
* AMD SVM: eventinj[10:8] and exitintinfo[10:8] (types 0-4 only)
|
||||
*/
|
||||
enum x86_event_type {
|
||||
X86_EVENTTYPE_EXT_INTR, /* External interrupt */
|
||||
X86_EVENTTYPE_NMI = 2, /* NMI */
|
||||
X86_EVENTTYPE_HW_EXCEPTION, /* Hardware exception */
|
||||
X86_EVENTTYPE_SW_INTERRUPT, /* Software interrupt (CD nn) */
|
||||
X86_EVENTTYPE_PRI_SW_EXCEPTION, /* ICEBP (F1) */
|
||||
X86_EVENTTYPE_SW_EXCEPTION, /* INT3 (CC), INTO (CE) */
|
||||
};
|
||||
#define X86_EVENT_NO_EC (-1) /* No error code. */
|
||||
|
||||
struct x86_event {
|
||||
int16_t vector;
|
||||
uint8_t type; /* X86_EVENTTYPE_* */
|
||||
uint8_t type; /* X86_ET_* */
|
||||
uint8_t insn_len; /* Instruction length */
|
||||
int32_t error_code; /* X86_EVENT_NO_EC if n/a */
|
||||
union {
|
||||
@@ -821,7 +808,7 @@ static inline void x86_emul_hw_exception(
|
||||
ASSERT(!ctxt->event_pending);
|
||||
|
||||
ctxt->event.vector = vector;
|
||||
ctxt->event.type = X86_EVENTTYPE_HW_EXCEPTION;
|
||||
ctxt->event.type = X86_ET_HW_EXC;
|
||||
ctxt->event.error_code = error_code;
|
||||
|
||||
ctxt->event_pending = true;
|
||||
@@ -833,7 +820,7 @@ static inline void x86_emul_pagefault(
|
||||
ASSERT(!ctxt->event_pending);
|
||||
|
||||
ctxt->event.vector = X86_EXC_PF;
|
||||
ctxt->event.type = X86_EVENTTYPE_HW_EXCEPTION;
|
||||
ctxt->event.type = X86_ET_HW_EXC;
|
||||
ctxt->event.error_code = error_code;
|
||||
ctxt->event.cr2 = cr2;
|
||||
|
||||
|
||||
@@ -302,7 +302,7 @@ struct xen_dm_op_inject_event {
|
||||
uint8_t vector;
|
||||
/* IN - event type (DMOP_EVENT_* ) */
|
||||
uint8_t type;
|
||||
/* NB. This enumeration precisely matches hvm.h:X86_EVENTTYPE_* */
|
||||
/* NB. This enumeration precisely matches x86-defns.h:X86_ET_* */
|
||||
# define XEN_DMOP_EVENT_ext_int 0 /* external interrupt */
|
||||
# define XEN_DMOP_EVENT_nmi 2 /* nmi */
|
||||
# define XEN_DMOP_EVENT_hw_exc 3 /* hardware exception */
|
||||
|
||||