Changeset View
Changeset View
Standalone View
Standalone View
head/sys/amd64/vmm/intel/vmx.c
Show First 20 Lines • Show All 3,168 Lines • ▼ Show 20 Lines | vmx_pending_intr(struct vlapic *vlapic, int *vecptr) | ||||
* handler which does not care about the vector that is pending. | * handler which does not care about the vector that is pending. | ||||
*/ | */ | ||||
KASSERT(vecptr == NULL, ("vmx_pending_intr: vecptr must be NULL")); | KASSERT(vecptr == NULL, ("vmx_pending_intr: vecptr must be NULL")); | ||||
vlapic_vtx = (struct vlapic_vtx *)vlapic; | vlapic_vtx = (struct vlapic_vtx *)vlapic; | ||||
pir_desc = vlapic_vtx->pir_desc; | pir_desc = vlapic_vtx->pir_desc; | ||||
pending = atomic_load_acq_long(&pir_desc->pending); | pending = atomic_load_acq_long(&pir_desc->pending); | ||||
if (!pending) | if (!pending) { | ||||
return (0); /* common case */ | /* | ||||
* While a virtual interrupt may have already been | |||||
* processed the actual delivery maybe pending the | |||||
* interruptibility of the guest. Recognize a pending | |||||
* interrupt by reevaluating virtual interrupts | |||||
* following Section 29.2.1 in the Intel SDM Volume 3. | |||||
*/ | |||||
uint64_t val; | |||||
uint8_t rvi, ppr; | |||||
vmx_getreg(vlapic_vtx->vmx, vlapic->vcpuid, | |||||
VMCS_IDENT(VMCS_GUEST_INTR_STATUS), &val); | |||||
rvi = val & APIC_TPR_INT; | |||||
lapic = vlapic->apic_page; | |||||
ppr = lapic->ppr & APIC_TPR_INT; | |||||
if (rvi > ppr) { | |||||
return (1); | |||||
} | |||||
return (0); | |||||
} | |||||
/* | /* | ||||
* If there is an interrupt pending then it will be recognized only | * If there is an interrupt pending then it will be recognized only | ||||
* if its priority is greater than the processor priority. | * if its priority is greater than the processor priority. | ||||
* | * | ||||
* Special case: if the processor priority is zero then any pending | * Special case: if the processor priority is zero then any pending | ||||
* interrupt will be recognized. | * interrupt will be recognized. | ||||
*/ | */ | ||||
lapic = vlapic->apic_page; | lapic = vlapic->apic_page; | ||||
ppr = lapic->ppr & 0xf0; | ppr = lapic->ppr & APIC_TPR_INT; | ||||
if (ppr == 0) | if (ppr == 0) | ||||
return (1); | return (1); | ||||
VCPU_CTR1(vlapic->vm, vlapic->vcpuid, "HLT with non-zero PPR %d", | VCPU_CTR1(vlapic->vm, vlapic->vcpuid, "HLT with non-zero PPR %d", | ||||
lapic->ppr); | lapic->ppr); | ||||
for (i = 3; i >= 0; i--) { | for (i = 3; i >= 0; i--) { | ||||
pirval = pir_desc->pir[i]; | pirval = pir_desc->pir[i]; | ||||
if (pirval != 0) { | if (pirval != 0) { | ||||
vpr = (i * 64 + flsl(pirval) - 1) & 0xf0; | vpr = (i * 64 + flsl(pirval) - 1) & APIC_TPR_INT; | ||||
return (vpr > ppr); | return (vpr > ppr); | ||||
} | } | ||||
} | } | ||||
return (0); | return (0); | ||||
} | } | ||||
static void | static void | ||||
vmx_intr_accepted(struct vlapic *vlapic, int vector) | vmx_intr_accepted(struct vlapic *vlapic, int vector) | ||||
▲ Show 20 Lines • Show All 236 Lines • Show Last 20 Lines |