hv: Introduce check_vm_vlapic_state API

This patch introduces check_vm_vlapic_state API instead of is_lapic_pt_enabled
to check if all the vCPUs of a VM are using x2APIC mode and LAPIC
pass-through is enabled on all of them.

When the VM is in VM_VLAPIC_TRANSITION or VM_VLAPIC_DISABLED state,
following conditions apply.
1) For pass-thru MSI interrupts, interrupt source is not programmed.
2) For DM emulated device MSI interrupts, interrupt is not delivered.
3) For IPIs, it will work only if the sender and destination are both in x2APIC mode.

Tracked-On: #3253
Signed-off-by: Sainath Grandhi <sainath.grandhi@intel.com>
Acked-by: Eddie Dong <eddie.dong@intel.com>
This commit is contained in:
Sainath Grandhi
2019-06-10 22:22:32 -07:00
committed by wenlingz
parent f3627d4839
commit 7d44cd5c28
9 changed files with 98 additions and 35 deletions

View File

@@ -2042,6 +2042,9 @@ vlapic_x2apic_pt_icr_access(struct acrn_vm *vm, uint64_t val)
if ((phys == false) || (shorthand != APIC_DEST_DESTFLD)) {
pr_err("Logical destination mode or shorthands \
not supported in ICR forpartition mode\n");
/*
* TODO: To support logical destination and shorthand modes
*/
} else {
vcpu_id = vm_apicid2vcpu_id(vm, vapic_id);
if ((vcpu_id < vm->hw.created_vcpus) && (vm->hw.vcpu_array[vcpu_id].state != VCPU_OFFLINE)) {
@@ -2056,11 +2059,13 @@ vlapic_x2apic_pt_icr_access(struct acrn_vm *vm, uint64_t val)
break;
default:
/* convert the dest from virtual apic_id to physical apic_id */
papic_id = per_cpu(lapic_id, target_vcpu->pcpu_id);
dev_dbg(ACRN_DBG_LAPICPT,
"%s vapic_id: 0x%08lx papic_id: 0x%08lx icr_low:0x%08lx",
__func__, vapic_id, papic_id, icr_low);
msr_write(MSR_IA32_EXT_APIC_ICR, (((uint64_t)papic_id) << 32U) | icr_low);
if (is_x2apic_enabled(vcpu_vlapic(target_vcpu))) {
papic_id = per_cpu(lapic_id, target_vcpu->pcpu_id);
dev_dbg(ACRN_DBG_LAPICPT,
"%s vapic_id: 0x%08lx papic_id: 0x%08lx icr_low:0x%08lx",
__func__, vapic_id, papic_id, icr_low);
msr_write(MSR_IA32_EXT_APIC_ICR, (((uint64_t)papic_id) << 32U) | icr_low);
}
break;
}
ret = 0;
@@ -2602,14 +2607,3 @@ void vlapic_set_apicv_ops(void)
apicv_ops = &apicv_basic_ops;
}
}
/**
* @pre vm != NULL
* @pre vm->vmid < CONFIG_MAX_VM_NUM
*/
bool is_lapic_pt_enabled(struct acrn_vm *vm)
{
struct acrn_vcpu *vcpu = vcpu_from_vid(vm, 0U);
return ((is_x2apic_enabled(vcpu_vlapic(vcpu))) && (is_lapic_pt_configured(vm)));
}