Changeset View
Changeset View
Standalone View
Standalone View
sys/amd64/vmm/io/vlapic.c
Show First 20 Lines • Show All 832 Lines • ▼ Show 20 Lines | vlapic_calcdest(struct vm *vm, cpuset_t *dmask, uint32_t dest, bool phys, | ||||
} | } | ||||
if (phys) { | if (phys) { | ||||
/* | /* | ||||
* Physical mode: destination is APIC ID. | * Physical mode: destination is APIC ID. | ||||
*/ | */ | ||||
CPU_ZERO(dmask); | CPU_ZERO(dmask); | ||||
vcpuid = vm_apicid2vcpuid(vm, dest); | vcpuid = vm_apicid2vcpuid(vm, dest); | ||||
if (vcpuid < VM_MAXCPU) | if (vcpuid < vm_get_maxcpus(vm)) | ||||
CPU_SET(vcpuid, dmask); | CPU_SET(vcpuid, dmask); | ||||
} else { | } else { | ||||
/* | /* | ||||
* In the "Flat Model" the MDA is interpreted as an 8-bit wide | * In the "Flat Model" the MDA is interpreted as an 8-bit wide | ||||
* bitmask. This model is only available in the xAPIC mode. | * bitmask. This model is only available in the xAPIC mode. | ||||
*/ | */ | ||||
mda_flat_ldest = dest & 0xff; | mda_flat_ldest = dest & 0xff; | ||||
▲ Show 20 Lines • Show All 110 Lines • ▼ Show 20 Lines | vlapic_icrlo_write_handler(struct vlapic *vlapic, bool *retu) | ||||
int i; | int i; | ||||
bool phys; | bool phys; | ||||
cpuset_t dmask; | cpuset_t dmask; | ||||
uint64_t icrval; | uint64_t icrval; | ||||
uint32_t dest, vec, mode; | uint32_t dest, vec, mode; | ||||
struct vlapic *vlapic2; | struct vlapic *vlapic2; | ||||
struct vm_exit *vmexit; | struct vm_exit *vmexit; | ||||
struct LAPIC *lapic; | struct LAPIC *lapic; | ||||
uint16_t maxcpus; | |||||
lapic = vlapic->apic_page; | lapic = vlapic->apic_page; | ||||
lapic->icr_lo &= ~APIC_DELSTAT_PEND; | lapic->icr_lo &= ~APIC_DELSTAT_PEND; | ||||
icrval = ((uint64_t)lapic->icr_hi << 32) | lapic->icr_lo; | icrval = ((uint64_t)lapic->icr_hi << 32) | lapic->icr_lo; | ||||
if (x2apic(vlapic)) | if (x2apic(vlapic)) | ||||
dest = icrval >> 32; | dest = icrval >> 32; | ||||
else | else | ||||
▲ Show 20 Lines • Show All 45 Lines • ▼ Show 20 Lines | while ((i = CPU_FFS(&dmask)) != 0) { | ||||
VLAPIC_CTR1(vlapic, "vlapic sending ipi nmi " | VLAPIC_CTR1(vlapic, "vlapic sending ipi nmi " | ||||
"to vcpuid %d", i); | "to vcpuid %d", i); | ||||
} | } | ||||
} | } | ||||
return (0); /* handled completely in the kernel */ | return (0); /* handled completely in the kernel */ | ||||
} | } | ||||
maxcpus = vm_get_maxcpus(vlapic->vm); | |||||
if (mode == APIC_DELMODE_INIT) { | if (mode == APIC_DELMODE_INIT) { | ||||
if ((icrval & APIC_LEVEL_MASK) == APIC_LEVEL_DEASSERT) | if ((icrval & APIC_LEVEL_MASK) == APIC_LEVEL_DEASSERT) | ||||
return (0); | return (0); | ||||
if (vlapic->vcpuid == 0 && dest != 0 && dest < VM_MAXCPU) { | if (vlapic->vcpuid == 0 && dest != 0 && dest < maxcpus) { | ||||
vlapic2 = vm_lapic(vlapic->vm, dest); | vlapic2 = vm_lapic(vlapic->vm, dest); | ||||
/* move from INIT to waiting-for-SIPI state */ | /* move from INIT to waiting-for-SIPI state */ | ||||
if (vlapic2->boot_state == BS_INIT) { | if (vlapic2->boot_state == BS_INIT) { | ||||
vlapic2->boot_state = BS_SIPI; | vlapic2->boot_state = BS_SIPI; | ||||
} | } | ||||
return (0); | return (0); | ||||
} | } | ||||
} | } | ||||
if (mode == APIC_DELMODE_STARTUP) { | if (mode == APIC_DELMODE_STARTUP) { | ||||
if (vlapic->vcpuid == 0 && dest != 0 && dest < VM_MAXCPU) { | if (vlapic->vcpuid == 0 && dest != 0 && dest < maxcpus) { | ||||
vlapic2 = vm_lapic(vlapic->vm, dest); | vlapic2 = vm_lapic(vlapic->vm, dest); | ||||
/* | /* | ||||
* Ignore SIPIs in any state other than wait-for-SIPI | * Ignore SIPIs in any state other than wait-for-SIPI | ||||
*/ | */ | ||||
if (vlapic2->boot_state != BS_SIPI) | if (vlapic2->boot_state != BS_SIPI) | ||||
return (0); | return (0); | ||||
▲ Show 20 Lines • Show All 387 Lines • ▼ Show 20 Lines | vlapic_reset(struct vlapic *vlapic) | ||||
vlapic->svr_last = lapic->svr; | vlapic->svr_last = lapic->svr; | ||||
} | } | ||||
void | void | ||||
vlapic_init(struct vlapic *vlapic) | vlapic_init(struct vlapic *vlapic) | ||||
{ | { | ||||
KASSERT(vlapic->vm != NULL, ("vlapic_init: vm is not initialized")); | KASSERT(vlapic->vm != NULL, ("vlapic_init: vm is not initialized")); | ||||
KASSERT(vlapic->vcpuid >= 0 && vlapic->vcpuid < VM_MAXCPU, | KASSERT(vlapic->vcpuid >= 0 && | ||||
vlapic->vcpuid < vm_get_maxcpus(vlapic->vm), | |||||
("vlapic_init: vcpuid is not initialized")); | ("vlapic_init: vcpuid is not initialized")); | ||||
KASSERT(vlapic->apic_page != NULL, ("vlapic_init: apic_page is not " | KASSERT(vlapic->apic_page != NULL, ("vlapic_init: apic_page is not " | ||||
"initialized")); | "initialized")); | ||||
/* | /* | ||||
* If the vlapic is configured in x2apic mode then it will be | * If the vlapic is configured in x2apic mode then it will be | ||||
* accessed in the critical section via the MSR emulation code. | * accessed in the critical section via the MSR emulation code. | ||||
* | * | ||||
▲ Show 20 Lines • Show All 198 Lines • Show Last 20 Lines |