Skip to content

Commit 578592b

Browse files
fyin1wenlingz
authored andcommitted
vlapic: refine IPI broadcast to support x2APIC mode
According to SDM 10.6.1, if dest fields is 0xffU for register ICR operation, that means the IPI is for broadcast. According to SDM 10.12.9, 0xffffffffU of dest fields for x2APIC means IPI is for broadcast. We add new parameter to vlapic_calc_dest() to show whether the dest is for broadcast. For IPI, we will set it according to dest fields. For ioapic and MSI, we hardcode it to false because no broadcast for ioapic and MSI. Tracked-On: #3003 Signed-off-by: Yin Fengwei <fengwei.yin@intel.com> Acked-by: Eddie Dong <eddie.dong@intel.com>
1 parent 581c0a2 commit 578592b

File tree

4 files changed

+18
-12
lines changed

4 files changed

+18
-12
lines changed

hypervisor/arch/x86/guest/assign.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ static void ptirq_build_physical_msi(struct acrn_vm *vm, struct ptirq_msi_info *
8989
dest = info->vmsi_addr.bits.dest_field;
9090
phys = (info->vmsi_addr.bits.dest_mode == MSI_ADDR_DESTMODE_PHYS);
9191

92-
vlapic_calc_dest(vm, &vdmask, dest, phys, false);
92+
vlapic_calc_dest(vm, &vdmask, false, dest, phys, false);
9393
pdmask = vcpumask2pcpumask(vm, vdmask);
9494

9595
/* get physical delivery mode */
@@ -183,7 +183,7 @@ ptirq_build_physical_rte(struct acrn_vm *vm, struct ptirq_remapping_info *entry)
183183
/* physical destination cpu mask */
184184
phys = (virt_rte.bits.dest_mode == IOAPIC_RTE_DESTMODE_PHY);
185185
dest = (uint32_t)virt_rte.bits.dest_field;
186-
vlapic_calc_dest(vm, &vdmask, dest, phys, false);
186+
vlapic_calc_dest(vm, &vdmask, false, dest, phys, false);
187187
pdmask = vcpumask2pcpumask(vm, vdmask);
188188

189189
/* physical delivery mode */

hypervisor/arch/x86/guest/vlapic.c

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1094,14 +1094,15 @@ static inline bool is_dest_field_matched(const struct acrn_vlapic *vlapic, uint3
10941094
* addressing specified by the (dest, phys, lowprio) tuple.
10951095
*/
10961096
void
1097-
vlapic_calc_dest(struct acrn_vm *vm, uint64_t *dmask, uint32_t dest, bool phys, bool lowprio)
1097+
vlapic_calc_dest(struct acrn_vm *vm, uint64_t *dmask, bool is_broadcast,
1098+
uint32_t dest, bool phys, bool lowprio)
10981099
{
10991100
struct acrn_vlapic *vlapic, *lowprio_dest = NULL;
11001101
struct acrn_vcpu *vcpu;
11011102
uint16_t vcpu_id;
11021103

11031104
*dmask = 0UL;
1104-
if (dest == 0xffU) {
1105+
if (is_broadcast) {
11051106
/* Broadcast in both logical and physical modes. */
11061107
*dmask = vm_active_cpus(vm);
11071108
} else if (phys) {
@@ -1149,14 +1150,15 @@ vlapic_calc_dest(struct acrn_vm *vm, uint64_t *dmask, uint32_t dest, bool phys,
11491150
* @pre is_x2apic_enabled(vlapic) == true
11501151
*/
11511152
void
1152-
vlapic_calc_dest_lapic_pt(struct acrn_vm *vm, uint64_t *dmask, uint32_t dest, bool phys)
1153+
vlapic_calc_dest_lapic_pt(struct acrn_vm *vm, uint64_t *dmask, bool is_broadcast,
1154+
uint32_t dest, bool phys)
11531155
{
11541156
struct acrn_vlapic *vlapic;
11551157
struct acrn_vcpu *vcpu;
11561158
uint16_t vcpu_id;
11571159

11581160
*dmask = 0UL;
1159-
if (dest == 0xffU) {
1161+
if (is_broadcast) {
11601162
/* Broadcast in both logical and physical modes. */
11611163
*dmask = vm_active_cpus(vm);
11621164
} else if (phys) {
@@ -1227,7 +1229,7 @@ vlapic_process_init_sipi(struct acrn_vcpu* target_vcpu, uint32_t mode,
12271229
static void vlapic_icrlo_write_handler(struct acrn_vlapic *vlapic)
12281230
{
12291231
uint16_t vcpu_id;
1230-
bool phys;
1232+
bool phys = false, is_broadcast = false;
12311233
uint64_t dmask = 0UL;
12321234
uint32_t icr_low, icr_high, dest;
12331235
uint32_t vec, mode, shorthand;
@@ -1241,8 +1243,10 @@ static void vlapic_icrlo_write_handler(struct acrn_vlapic *vlapic)
12411243
icr_high = lapic->icr_hi.v;
12421244
if (is_x2apic_enabled(vlapic)) {
12431245
dest = icr_high;
1246+
is_broadcast = (dest == 0xffffffffU);
12441247
} else {
12451248
dest = icr_high >> APIC_ID_SHIFT;
1249+
is_broadcast = (dest == 0xffU);
12461250
}
12471251
vec = icr_low & APIC_VECTOR_MASK;
12481252
mode = icr_low & APIC_DELMODE_MASK;
@@ -1264,7 +1268,7 @@ static void vlapic_icrlo_write_handler(struct acrn_vlapic *vlapic)
12641268

12651269
switch (shorthand) {
12661270
case APIC_DEST_DESTFLD:
1267-
vlapic_calc_dest(vlapic->vm, &dmask, dest, phys, false);
1271+
vlapic_calc_dest(vlapic->vm, &dmask, is_broadcast, dest, phys, false);
12681272
break;
12691273
case APIC_DEST_SELF:
12701274
bitmap_set_nolock(vlapic->vcpu->vcpu_id, &dmask);
@@ -1802,7 +1806,7 @@ vlapic_receive_intr(struct acrn_vm *vm, bool level, uint32_t dest, bool phys,
18021806
* all interrupts originating from the ioapic or MSI specify the
18031807
* 'dest' in the legacy xAPIC format.
18041808
*/
1805-
vlapic_calc_dest(vm, &dmask, dest, phys, lowprio);
1809+
vlapic_calc_dest(vm, &dmask, false, dest, phys, lowprio);
18061810

18071811
for (vcpu_id = 0U; vcpu_id < vm->hw.created_vcpus; vcpu_id++) {
18081812
struct acrn_vlapic *vlapic;

hypervisor/common/hypercall.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -432,7 +432,7 @@ static void inject_msi_lapic_pt(struct acrn_vm *vm, const struct acrn_msi_entry
432432
* the delivery mode of vmsi will be forwarded to ICR delievry field
433433
* and handled by hardware.
434434
*/
435-
vlapic_calc_dest_lapic_pt(vm, &vdmask, vdest, phys);
435+
vlapic_calc_dest_lapic_pt(vm, &vdmask, false, vdest, phys);
436436
dev_dbg(ACRN_DBG_LAPICPT, "%s: vcpu destination mask 0x%016llx", __func__, vdmask);
437437

438438
vcpu_id = ffs64(vdmask);

hypervisor/include/arch/x86/guest/vlapic.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -206,8 +206,10 @@ int32_t apic_write_vmexit_handler(struct acrn_vcpu *vcpu);
206206
int32_t veoi_vmexit_handler(struct acrn_vcpu *vcpu);
207207
void vlapic_update_tpr_threshold(const struct acrn_vlapic *vlapic);
208208
int32_t tpr_below_threshold_vmexit_handler(struct acrn_vcpu *vcpu);
209-
void vlapic_calc_dest(struct acrn_vm *vm, uint64_t *dmask, uint32_t dest, bool phys, bool lowprio);
210-
void vlapic_calc_dest_lapic_pt(struct acrn_vm *vm, uint64_t *dmask, uint32_t dest, bool phys);
209+
void vlapic_calc_dest(struct acrn_vm *vm, uint64_t *dmask, bool is_broadcast,
210+
uint32_t dest, bool phys, bool lowprio);
211+
void vlapic_calc_dest_lapic_pt(struct acrn_vm *vm, uint64_t *dmask, bool is_broadcast,
212+
uint32_t dest, bool phys);
211213

212214
/**
213215
* @}

0 commit comments

Comments
 (0)