mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-08-03 17:31:42 +00:00
hv: vlapic: wrap a function to calculate destination vcpu mask by shorthand
1. Rename vlapic_calc_dest to vlapic_calc_dest_noshort 2. Remove vlapic_calc_dest_lapic_pt, use vlapic_calc_dest_noshort instead 3. Wrap vlapic_calc_dest to calculate destination vcpu mask according shorthand Tracked-On: #5923 Signed-off-by: Zide Chen <zide.chen@intel.com> Signed-off-by: Li Fei1 <fei1.li@intel.com> Acked-by: Eddie Dong <eddie.dong@intel.com>
This commit is contained in:
parent
b068656e71
commit
a69e67b58b
@ -32,7 +32,7 @@ static struct acrn_vcpu *is_single_destination(struct acrn_vm *vm, const struct
|
||||
uint16_t vid;
|
||||
struct acrn_vcpu *vcpu = NULL;
|
||||
|
||||
vlapic_calc_dest(vm, &vdmask, false, (uint32_t)(info->addr.bits.dest_field),
|
||||
vdmask = vlapic_calc_dest_noshort(vm, false, (uint32_t)(info->addr.bits.dest_field),
|
||||
(bool)(info->addr.bits.dest_mode == MSI_ADDR_DESTMODE_PHYS),
|
||||
(bool)(info->data.bits.delivery_mode == MSI_DATA_DELMODE_LOPRI));
|
||||
|
||||
@ -105,7 +105,7 @@ static void ptirq_build_physical_msi(struct acrn_vm *vm,
|
||||
dest = entry->vmsi.addr.bits.dest_field;
|
||||
phys = (entry->vmsi.addr.bits.dest_mode == MSI_ADDR_DESTMODE_PHYS);
|
||||
|
||||
vlapic_calc_dest(vm, &vdmask, false, dest, phys, false);
|
||||
vdmask = vlapic_calc_dest_noshort(vm, false, dest, phys, false);
|
||||
pdmask = vcpumask2pcpumask(vm, vdmask);
|
||||
|
||||
/* get physical delivery mode */
|
||||
@ -204,7 +204,7 @@ ptirq_build_physical_rte(struct acrn_vm *vm, struct ptirq_remapping_info *entry)
|
||||
/* physical destination cpu mask */
|
||||
phys = (virt_rte.bits.dest_mode == IOAPIC_RTE_DESTMODE_PHY);
|
||||
dest = (uint32_t)virt_rte.bits.dest_field;
|
||||
vlapic_calc_dest(vm, &vdmask, false, dest, phys, false);
|
||||
vdmask = vlapic_calc_dest_noshort(vm, false, dest, phys, false);
|
||||
pdmask = vcpumask2pcpumask(vm, vdmask);
|
||||
|
||||
/* physical delivery mode */
|
||||
|
@ -997,21 +997,21 @@ static inline bool is_dest_field_matched(const struct acrn_vlapic *vlapic, uint3
|
||||
* This function populates 'dmask' with the set of vcpus that match the
|
||||
* addressing specified by the (dest, phys, lowprio) tuple.
|
||||
*/
|
||||
void
|
||||
vlapic_calc_dest(struct acrn_vm *vm, uint64_t *dmask, bool is_broadcast,
|
||||
uint64_t
|
||||
vlapic_calc_dest_noshort(struct acrn_vm *vm, bool is_broadcast,
|
||||
uint32_t dest, bool phys, bool lowprio)
|
||||
{
|
||||
uint64_t dmask = 0UL;
|
||||
struct acrn_vlapic *vlapic, *lowprio_dest = NULL;
|
||||
struct acrn_vcpu *vcpu;
|
||||
uint16_t vcpu_id;
|
||||
|
||||
*dmask = 0UL;
|
||||
if (is_broadcast) {
|
||||
/* Broadcast in both logical and physical modes. */
|
||||
*dmask = vm_active_cpus(vm);
|
||||
dmask = vm_active_cpus(vm);
|
||||
} else if (phys) {
|
||||
/* Physical mode: "dest" is local APIC ID. */
|
||||
set_dest_mask_phys(vm, dmask, dest);
|
||||
set_dest_mask_phys(vm, &dmask, dest);
|
||||
} else {
|
||||
/*
|
||||
* Logical mode: "dest" is message destination addr
|
||||
@ -1036,52 +1036,47 @@ vlapic_calc_dest(struct acrn_vm *vm, uint64_t *dmask, bool is_broadcast,
|
||||
/* No other state currently, do nothing */
|
||||
}
|
||||
} else {
|
||||
bitmap_set_nolock(vcpu_id, dmask);
|
||||
bitmap_set_nolock(vcpu_id, &dmask);
|
||||
}
|
||||
}
|
||||
|
||||
if (lowprio && (lowprio_dest != NULL)) {
|
||||
bitmap_set_nolock(vlapic2vcpu(lowprio_dest)->vcpu_id, dmask);
|
||||
bitmap_set_nolock(vlapic2vcpu(lowprio_dest)->vcpu_id, &dmask);
|
||||
}
|
||||
}
|
||||
|
||||
return dmask;
|
||||
}
|
||||
|
||||
/*
|
||||
* This function populates 'dmask' with the set of "possible" destination vcpu when lapic is passthru.
|
||||
* Hardware will handle the real delivery mode among all "possible" dest processors:
|
||||
* deliver to the lowprio one for lowprio mode.
|
||||
*
|
||||
* @pre is_x2apic_enabled(vlapic) == true
|
||||
*/
|
||||
void
|
||||
vlapic_calc_dest_lapic_pt(struct acrn_vm *vm, uint64_t *dmask, bool is_broadcast,
|
||||
uint32_t dest, bool phys)
|
||||
uint64_t
|
||||
vlapic_calc_dest(struct acrn_vcpu *vcpu, uint32_t shorthand, bool is_broadcast,
|
||||
uint32_t dest, bool phys, bool lowprio)
|
||||
{
|
||||
struct acrn_vlapic *vlapic;
|
||||
struct acrn_vcpu *vcpu;
|
||||
uint16_t vcpu_id;
|
||||
uint64_t dmask = 0UL;
|
||||
|
||||
*dmask = 0UL;
|
||||
if (is_broadcast) {
|
||||
/* Broadcast in both logical and physical modes. */
|
||||
*dmask = vm_active_cpus(vm);
|
||||
} else if (phys) {
|
||||
/* Physical mode: "dest" is local APIC ID. */
|
||||
set_dest_mask_phys(vm, dmask, dest);
|
||||
} else {
|
||||
switch (shorthand) {
|
||||
case APIC_DEST_NOSHORT:
|
||||
dmask = vlapic_calc_dest_noshort(vcpu->vm, is_broadcast, dest, phys, lowprio);
|
||||
break;
|
||||
case APIC_DEST_SELF:
|
||||
bitmap_set_nolock(vcpu->vcpu_id, &dmask);
|
||||
break;
|
||||
case APIC_DEST_ALLISELF:
|
||||
dmask = vm_active_cpus(vcpu->vm);
|
||||
break;
|
||||
case APIC_DEST_ALLESELF:
|
||||
dmask = vm_active_cpus(vcpu->vm);
|
||||
bitmap_clear_nolock(vcpu->vcpu_id, &dmask);
|
||||
break;
|
||||
default:
|
||||
/*
|
||||
* Logical mode: "dest" is message destination addr
|
||||
* to be compared with the logical APIC ID in LDR.
|
||||
* All possible values of 'shorthand' has been handled in prior
|
||||
* case clauses.
|
||||
*/
|
||||
foreach_vcpu(vcpu_id, vm, vcpu) {
|
||||
vlapic = vm_lapic_from_vcpu_id(vm, vcpu_id);
|
||||
if (!is_dest_field_matched(vlapic, dest)) {
|
||||
continue;
|
||||
}
|
||||
bitmap_set_nolock(vcpu_id, dmask);
|
||||
}
|
||||
dev_dbg(DBG_LEVEL_LAPICPT, "%s: logical destmod, dmask: 0x%016lx", __func__, *dmask);
|
||||
break;
|
||||
}
|
||||
|
||||
return dmask;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -1139,7 +1134,7 @@ static void vlapic_write_icrlo(struct acrn_vlapic *vlapic)
|
||||
{
|
||||
uint16_t vcpu_id;
|
||||
bool phys = false, is_broadcast = false;
|
||||
uint64_t dmask = 0UL;
|
||||
uint64_t dmask;
|
||||
uint32_t icr_low, icr_high, dest;
|
||||
uint32_t vec, mode, shorthand;
|
||||
struct lapic_regs *lapic;
|
||||
@ -1176,27 +1171,7 @@ static void vlapic_write_icrlo(struct acrn_vlapic *vlapic)
|
||||
"icrlo 0x%08x icrhi 0x%08x triggered ipi %u",
|
||||
icr_low, icr_high, vec);
|
||||
|
||||
switch (shorthand) {
|
||||
case APIC_DEST_DESTFLD:
|
||||
vlapic_calc_dest(vcpu->vm, &dmask, is_broadcast, dest, phys, false);
|
||||
break;
|
||||
case APIC_DEST_SELF:
|
||||
bitmap_set_nolock(vcpu->vcpu_id, &dmask);
|
||||
break;
|
||||
case APIC_DEST_ALLISELF:
|
||||
dmask = vm_active_cpus(vcpu->vm);
|
||||
break;
|
||||
case APIC_DEST_ALLESELF:
|
||||
dmask = vm_active_cpus(vcpu->vm);
|
||||
bitmap_clear_nolock(vlapic2vcpu(vlapic)->vcpu_id, &dmask);
|
||||
break;
|
||||
default:
|
||||
/*
|
||||
* All possible values of 'shorthand' has been handled in prior
|
||||
* case clauses.
|
||||
*/
|
||||
break;
|
||||
}
|
||||
dmask = vlapic_calc_dest(vcpu, shorthand, is_broadcast, dest, phys, false);
|
||||
|
||||
for (vcpu_id = 0U; vcpu_id < vcpu->vm->hw.created_vcpus; vcpu_id++) {
|
||||
if ((dmask & (1UL << vcpu_id)) != 0UL) {
|
||||
@ -1774,7 +1749,7 @@ vlapic_receive_intr(struct acrn_vm *vm, bool level, uint32_t dest, bool phys,
|
||||
* all interrupts originating from the ioapic or MSI specify the
|
||||
* 'dest' in the legacy xAPIC format.
|
||||
*/
|
||||
vlapic_calc_dest(vm, &dmask, false, dest, phys, lowprio);
|
||||
dmask = vlapic_calc_dest_noshort(vm, false, dest, phys, lowprio);
|
||||
|
||||
for (vcpu_id = 0U; vcpu_id < vm->hw.created_vcpus; vcpu_id++) {
|
||||
struct acrn_vlapic *vlapic;
|
||||
@ -1943,7 +1918,7 @@ static void inject_msi_for_lapic_pt(struct acrn_vm *vm, uint64_t addr, uint64_t
|
||||
* the delivery mode of vmsi will be forwarded to ICR delievry field
|
||||
* and handled by hardware.
|
||||
*/
|
||||
vlapic_calc_dest_lapic_pt(vm, &vdmask, false, vdest, phys);
|
||||
vdmask = vlapic_calc_dest_noshort(vm, false, vdest, phys, false);
|
||||
dev_dbg(DBG_LEVEL_LAPICPT, "%s: vcpu destination mask 0x%016lx", __func__, vdmask);
|
||||
|
||||
vcpu_id = ffs64(vdmask);
|
||||
@ -2077,7 +2052,7 @@ vlapic_x2apic_pt_icr_access(struct acrn_vm *vm, uint64_t val)
|
||||
phys = ((icr_low & APIC_DESTMODE_LOG) == 0UL);
|
||||
shorthand = icr_low & APIC_DEST_MASK;
|
||||
|
||||
if (!phys || (shorthand != APIC_DEST_DESTFLD)) {
|
||||
if (!phys || (shorthand != APIC_DEST_NOSHORT)) {
|
||||
pr_err("Logical destination mode or shorthands \
|
||||
not supported in ICR forpartition mode\n");
|
||||
/*
|
||||
|
@ -325,7 +325,7 @@ union ioapic_rte {
|
||||
#define APIC_RRSTAT_RESV 0x00030000U
|
||||
|
||||
#define APIC_DEST_MASK 0x000c0000U
|
||||
#define APIC_DEST_DESTFLD 0x00000000U
|
||||
#define APIC_DEST_NOSHORT 0x00000000U
|
||||
#define APIC_DEST_SELF 0x00040000U
|
||||
#define APIC_DEST_ALLISELF 0x00080000U
|
||||
#define APIC_DEST_ALLESELF 0x000c0000U
|
||||
|
@ -188,10 +188,8 @@ int32_t apic_write_vmexit_handler(struct acrn_vcpu *vcpu);
|
||||
int32_t veoi_vmexit_handler(struct acrn_vcpu *vcpu);
|
||||
void vlapic_update_tpr_threshold(const struct acrn_vlapic *vlapic);
|
||||
int32_t tpr_below_threshold_vmexit_handler(struct acrn_vcpu *vcpu);
|
||||
void vlapic_calc_dest(struct acrn_vm *vm, uint64_t *dmask, bool is_broadcast,
|
||||
uint64_t vlapic_calc_dest_noshort(struct acrn_vm *vm, bool is_broadcast,
|
||||
uint32_t dest, bool phys, bool lowprio);
|
||||
void vlapic_calc_dest_lapic_pt(struct acrn_vm *vm, uint64_t *dmask, bool is_broadcast,
|
||||
uint32_t dest, bool phys);
|
||||
bool is_x2apic_enabled(const struct acrn_vlapic *vlapic);
|
||||
bool is_xapic_enabled(const struct acrn_vlapic *vlapic);
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user