Changeset View
Changeset View
Standalone View
Standalone View
head/sys/amd64/vmm/io/vlapic.c
Show First 20 Lines • Show All 549 Lines • ▼ Show 20 Lines | if (PRIO(tpr) >= PRIO(isrvec)) | ||||
ppr = tpr; | ppr = tpr; | ||||
else | else | ||||
ppr = isrvec & 0xf0; | ppr = isrvec & 0xf0; | ||||
vlapic->apic_page->ppr = ppr; | vlapic->apic_page->ppr = ppr; | ||||
VLAPIC_CTR1(vlapic, "vlapic_update_ppr 0x%02x", ppr); | VLAPIC_CTR1(vlapic, "vlapic_update_ppr 0x%02x", ppr); | ||||
} | } | ||||
void | |||||
vlapic_sync_tpr(struct vlapic *vlapic) | |||||
{ | |||||
vlapic_update_ppr(vlapic); | |||||
} | |||||
static VMM_STAT(VLAPIC_GRATUITOUS_EOI, "EOI without any in-service interrupt"); | static VMM_STAT(VLAPIC_GRATUITOUS_EOI, "EOI without any in-service interrupt"); | ||||
static void | static void | ||||
vlapic_process_eoi(struct vlapic *vlapic) | vlapic_process_eoi(struct vlapic *vlapic) | ||||
{ | { | ||||
struct LAPIC *lapic = vlapic->apic_page; | struct LAPIC *lapic = vlapic->apic_page; | ||||
uint32_t *isrptr, *tmrptr; | uint32_t *isrptr, *tmrptr; | ||||
int i, idx, bitpos, vector; | int i, idx, bitpos, vector; | ||||
▲ Show 20 Lines • Show All 508 Lines • ▼ Show 20 Lines | |||||
int | int | ||||
vlapic_pending_intr(struct vlapic *vlapic, int *vecptr) | vlapic_pending_intr(struct vlapic *vlapic, int *vecptr) | ||||
{ | { | ||||
struct LAPIC *lapic = vlapic->apic_page; | struct LAPIC *lapic = vlapic->apic_page; | ||||
int idx, i, bitpos, vector; | int idx, i, bitpos, vector; | ||||
uint32_t *irrptr, val; | uint32_t *irrptr, val; | ||||
vlapic_update_ppr(vlapic); | |||||
gusev.vitaliy_gmail.com: I guess vlapic_update_ppr() should be placed below ops.pending_intr() to avoid usage when… | |||||
grehanUnsubmitted Not Done Inline ActionsYes. It's harmless but does unnecessary work in that case. grehan: Yes. It's harmless but does unnecessary work in that case. | |||||
if (vlapic->ops.pending_intr) | if (vlapic->ops.pending_intr) | ||||
return ((*vlapic->ops.pending_intr)(vlapic, vecptr)); | return ((*vlapic->ops.pending_intr)(vlapic, vecptr)); | ||||
irrptr = &lapic->irr0; | irrptr = &lapic->irr0; | ||||
for (i = 7; i >= 0; i--) { | for (i = 7; i >= 0; i--) { | ||||
idx = i * 4; | idx = i * 4; | ||||
val = atomic_load_acq_int(&irrptr[idx]); | val = atomic_load_acq_int(&irrptr[idx]); | ||||
▲ Show 20 Lines • Show All 41 Lines • ▼ Show 20 Lines | vlapic_intr_accepted(struct vlapic *vlapic, int vector) | ||||
*/ | */ | ||||
vlapic->isrvec_stk_top++; | vlapic->isrvec_stk_top++; | ||||
stk_top = vlapic->isrvec_stk_top; | stk_top = vlapic->isrvec_stk_top; | ||||
if (stk_top >= ISRVEC_STK_SIZE) | if (stk_top >= ISRVEC_STK_SIZE) | ||||
panic("isrvec_stk_top overflow %d", stk_top); | panic("isrvec_stk_top overflow %d", stk_top); | ||||
vlapic->isrvec_stk[stk_top] = vector; | vlapic->isrvec_stk[stk_top] = vector; | ||||
vlapic_update_ppr(vlapic); | |||||
} | } | ||||
void | void | ||||
vlapic_svr_write_handler(struct vlapic *vlapic) | vlapic_svr_write_handler(struct vlapic *vlapic) | ||||
{ | { | ||||
struct LAPIC *lapic; | struct LAPIC *lapic; | ||||
uint32_t old, new, changed; | uint32_t old, new, changed; | ||||
▲ Show 20 Lines • Show All 498 Lines • Show Last 20 Lines |
I guess vlapic_update_ppr() should be placed below ops.pending_intr() to avoid usage when Virtual Interrupt Delivery is enabled?