mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-08-14 22:34:26 +00:00
hv: vLAPIC ICR write and destination mask matching for x2APIC
When guest uses vLAPIC in x2APIC mode, ICR write is a single MSR write. Also, the destination field for device interrupts and IPIs should not be handled in the same way as xAPIC mode. This patch adds support for x2APIC mode operation of guest vLAPIC. Tracked-On: #1626 Signed-off-by: Sainath Grandhi <sainath.grandhi@intel.com> Reviewed-by: Xu Anthony <anthony.xu@intel.com>
This commit is contained in:
parent
6a4dcce390
commit
e9fe6efd81
@ -1009,6 +1009,26 @@ vlapic_calcdest(struct vm *vm, uint64_t *dmask, uint32_t dest,
|
||||
if (vcpu_id < vm->hw.created_vcpus) {
|
||||
bitmap_set_lock(vcpu_id, dmask);
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* Logical mode: match each APIC that has a bit set
|
||||
* in its LDR that matches a bit in the ldest.
|
||||
*/
|
||||
*dmask = 0UL;
|
||||
amask = vm_active_cpus(vm);
|
||||
for (vcpu_id = 0U; vcpu_id < vm->hw.created_vcpus; vcpu_id++) {
|
||||
if (amask & (1U << vcpu_id)) {
|
||||
vlapic = vm_lapic_from_vcpu_id(vm, vcpu_id);
|
||||
|
||||
if (is_x2apic_enabled(vlapic)){
|
||||
ldr = vlapic->apic_page.ldr.v;
|
||||
ldest = ldr & 0xFFFFU;
|
||||
|
||||
mda_cluster_id = (dest >> 16U) & 0xFFFFU;
|
||||
mda_ldest = dest & 0xFFFFU;
|
||||
if (mda_cluster_id != ((ldr >> 16U) & 0xFFFFU)) {
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* In the "Flat Model" the MDA is interpreted as an 8-bit wide
|
||||
@ -1023,15 +1043,6 @@ vlapic_calcdest(struct vm *vm, uint64_t *dmask, uint32_t dest,
|
||||
mda_cluster_id = (dest >> 4U) & 0xfU;
|
||||
mda_cluster_ldest = dest & 0xfU;
|
||||
|
||||
/*
|
||||
* Logical mode: match each APIC that has a bit set
|
||||
* in its LDR that matches a bit in the ldest.
|
||||
*/
|
||||
*dmask = 0UL;
|
||||
amask = vm_active_cpus(vm);
|
||||
for (vcpu_id = 0U; vcpu_id < vm->hw.created_vcpus; vcpu_id++) {
|
||||
if (amask & (1U << vcpu_id)) {
|
||||
vlapic = vm_lapic_from_vcpu_id(vm, vcpu_id);
|
||||
dfr = vlapic->apic_page.dfr.v;
|
||||
ldr = vlapic->apic_page.ldr.v;
|
||||
|
||||
@ -1060,7 +1071,7 @@ vlapic_calcdest(struct vm *vm, uint64_t *dmask, uint32_t dest,
|
||||
"vlapic has bad logical model %x", dfr);
|
||||
continue;
|
||||
}
|
||||
|
||||
}
|
||||
if ((mda_ldest & ldest) != 0U) {
|
||||
if (lowprio) {
|
||||
if (target == NULL) {
|
||||
@ -1152,7 +1163,11 @@ vlapic_icrlo_write_handler(struct acrn_vlapic *vlapic)
|
||||
|
||||
icr_low = lapic->icr_lo.v;
|
||||
icr_high = lapic->icr_hi.v;
|
||||
if (is_x2apic_enabled(vlapic)) {
|
||||
dest = icr_high;
|
||||
} else {
|
||||
dest = icr_high >> APIC_ID_SHIFT;
|
||||
}
|
||||
vec = icr_low & APIC_VECTOR_MASK;
|
||||
mode = icr_low & APIC_DELMODE_MASK;
|
||||
phys = ((icr_low & APIC_DESTMODE_LOG) == 0UL);
|
||||
@ -1542,7 +1557,12 @@ vlapic_write(struct acrn_vlapic *vlapic, uint32_t offset,
|
||||
vlapic_svr_write_handler(vlapic);
|
||||
break;
|
||||
case APIC_OFFSET_ICR_LOW:
|
||||
if (is_x2apic_enabled(vlapic)) {
|
||||
lapic->icr_hi.v = (uint32_t)(data >> 32U);
|
||||
lapic->icr_lo.v = data32;
|
||||
} else {
|
||||
lapic->icr_lo.v = data32;
|
||||
}
|
||||
retval = vlapic_icrlo_write_handler(vlapic);
|
||||
break;
|
||||
case APIC_OFFSET_ICR_HI:
|
||||
|
Loading…
Reference in New Issue
Block a user