HV: update destination shorthand during x2apic ICR emulation

Currently, in RTVM with multi vCPUs, lapic pass through is
configured, each vCPU works in x2apic mode. When one vCPU sends
IPI to all other vCPUs through writes ICR register with virtual
value 0x00000000000c00f8, this ICR writting will be intercepted,
the hypervisor passes destination shorthand field 11B (All Excluding
Self) in the virtual ICR value into physical ICR value during IPI
emulation, this IPI will be sent to each physical CPU core
in the platform according to 10.6.1 Interrupt Command Register (ICR),
Vol 3, SDM.
One vCPU in User VM with lapic pass through configuration can
send IPI with destination shorthand (10B or 11B) and any vector
(such as NMI or reboot vector) to other vCPUs, this IPI will sent
other VMs in the platform by hypervisor, this interference may
cause other VMs hang.

In this patch, set "Destination Shorthand" field of the
ICR value as 00B (No Shorthand) since the emulation is done
through sending IPI to each VCPU in dmask one by one.

Tracked-On: #6908

Signed-off-by: Xiangyang Wu <xiangyang.wu@intel.com>
Reviewed-by: Chen, Jason CJ <jason.cj.chen@intel.com>
This commit is contained in:
Xiangyang Wu 2021-11-29 14:38:17 +08:00 committed by wenlingz
parent 50a0fb9ea6
commit d16d0f00bc
1 changed files with 5 additions and 0 deletions

View File

@ -2058,6 +2058,11 @@ vlapic_x2apic_pt_icr_access(struct acrn_vcpu *vcpu, uint64_t val)
} else {
dmask = vlapic_calc_dest(vcpu, shorthand, (dest == 0xffffffffU), dest, phys, false);
/**
* The hypervisor sets the "Destination Shorthand" field to 00B (No Shorthand)
* since the emulation is done through sending IPI to each VCPU in dmask one by one.
*/
icr_low = icr_low & (~APIC_DEST_MASK);
for (vcpu_id = 0U; vcpu_id < vcpu->vm->hw.created_vcpus; vcpu_id++) {
if (((dmask & (1UL << vcpu_id)) != 0UL) &&
(vcpu->vm->hw.vcpu_array[vcpu_id].state != VCPU_OFFLINE)) {