hv: vlapic: call vlapic_accept_intr directly in vlapic_set_error

LVT ERROR is an edge and fixed mode interrupt. We could call vlapic_accept_intr
to fire it directly. Otherwise, if LVT ERR vector is invalid, an invalid
interrupt will be accepted in IRR.

Tracked-On: #1842
Signed-off-by: Li, Fei1 <fei1.li@intel.com>
This commit is contained in:
Li, Fei1 2019-03-01 23:39:11 +08:00 committed by wenlingz
parent 2b35c07857
commit e5d3a49894

View File

@ -793,7 +793,7 @@ vlapic_fire_lvt(struct acrn_vlapic *vlapic, uint32_t lvt)
switch (mode) { switch (mode) {
case APIC_LVT_DM_FIXED: case APIC_LVT_DM_FIXED:
if (vlapic_accept_intr(vlapic, vec, false)) { if (vlapic_accept_intr(vlapic, vec, LAPIC_TRIG_EDGE)) {
vcpu_make_request(vcpu, ACRN_REQUEST_EVENT); vcpu_make_request(vcpu, ACRN_REQUEST_EVENT);
} }
break; break;
@ -944,7 +944,7 @@ vlapic_process_eoi(struct acrn_vlapic *vlapic)
static void static void
vlapic_set_error(struct acrn_vlapic *vlapic, uint32_t mask) vlapic_set_error(struct acrn_vlapic *vlapic, uint32_t mask)
{ {
uint32_t lvt; uint32_t lvt, vec;
vlapic->esr_pending |= mask; vlapic->esr_pending |= mask;
if (vlapic->esr_firing == 0) { if (vlapic->esr_firing == 0) {
@ -952,7 +952,14 @@ vlapic_set_error(struct acrn_vlapic *vlapic, uint32_t mask)
/* The error LVT always uses the fixed delivery mode. */ /* The error LVT always uses the fixed delivery mode. */
lvt = vlapic_get_lvt(vlapic, APIC_OFFSET_ERROR_LVT); lvt = vlapic_get_lvt(vlapic, APIC_OFFSET_ERROR_LVT);
vlapic_fire_lvt(vlapic, lvt | APIC_LVT_DM_FIXED); if ((lvt & APIC_LVT_M) == 0U) {
vec = lvt & APIC_LVT_VECTOR;
if (vec >= 16U) {
if (vlapic_accept_intr(vlapic, vec, LAPIC_TRIG_EDGE)) {
vcpu_make_request(vlapic->vcpu, ACRN_REQUEST_EVENT);
}
}
}
vlapic->esr_firing = 0; vlapic->esr_firing = 0;
} }
} }