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;
|
uint16_t vid;
|
||||||
struct acrn_vcpu *vcpu = NULL;
|
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->addr.bits.dest_mode == MSI_ADDR_DESTMODE_PHYS),
|
||||||
(bool)(info->data.bits.delivery_mode == MSI_DATA_DELMODE_LOPRI));
|
(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;
|
dest = entry->vmsi.addr.bits.dest_field;
|
||||||
phys = (entry->vmsi.addr.bits.dest_mode == MSI_ADDR_DESTMODE_PHYS);
|
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);
|
pdmask = vcpumask2pcpumask(vm, vdmask);
|
||||||
|
|
||||||
/* get physical delivery mode */
|
/* 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 */
|
/* physical destination cpu mask */
|
||||||
phys = (virt_rte.bits.dest_mode == IOAPIC_RTE_DESTMODE_PHY);
|
phys = (virt_rte.bits.dest_mode == IOAPIC_RTE_DESTMODE_PHY);
|
||||||
dest = (uint32_t)virt_rte.bits.dest_field;
|
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);
|
pdmask = vcpumask2pcpumask(vm, vdmask);
|
||||||
|
|
||||||
/* physical delivery mode */
|
/* 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
|
* This function populates 'dmask' with the set of vcpus that match the
|
||||||
* addressing specified by the (dest, phys, lowprio) tuple.
|
* addressing specified by the (dest, phys, lowprio) tuple.
|
||||||
*/
|
*/
|
||||||
void
|
uint64_t
|
||||||
vlapic_calc_dest(struct acrn_vm *vm, uint64_t *dmask, bool is_broadcast,
|
vlapic_calc_dest_noshort(struct acrn_vm *vm, bool is_broadcast,
|
||||||
uint32_t dest, bool phys, bool lowprio)
|
uint32_t dest, bool phys, bool lowprio)
|
||||||
{
|
{
|
||||||
|
uint64_t dmask = 0UL;
|
||||||
struct acrn_vlapic *vlapic, *lowprio_dest = NULL;
|
struct acrn_vlapic *vlapic, *lowprio_dest = NULL;
|
||||||
struct acrn_vcpu *vcpu;
|
struct acrn_vcpu *vcpu;
|
||||||
uint16_t vcpu_id;
|
uint16_t vcpu_id;
|
||||||
|
|
||||||
*dmask = 0UL;
|
|
||||||
if (is_broadcast) {
|
if (is_broadcast) {
|
||||||
/* Broadcast in both logical and physical modes. */
|
/* Broadcast in both logical and physical modes. */
|
||||||
*dmask = vm_active_cpus(vm);
|
dmask = vm_active_cpus(vm);
|
||||||
} else if (phys) {
|
} else if (phys) {
|
||||||
/* Physical mode: "dest" is local APIC ID. */
|
/* Physical mode: "dest" is local APIC ID. */
|
||||||
set_dest_mask_phys(vm, dmask, dest);
|
set_dest_mask_phys(vm, &dmask, dest);
|
||||||
} else {
|
} else {
|
||||||
/*
|
/*
|
||||||
* Logical mode: "dest" is message destination addr
|
* 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 */
|
/* No other state currently, do nothing */
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
bitmap_set_nolock(vcpu_id, dmask);
|
bitmap_set_nolock(vcpu_id, &dmask);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lowprio && (lowprio_dest != NULL)) {
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
uint64_t
|
||||||
* This function populates 'dmask' with the set of "possible" destination vcpu when lapic is passthru.
|
vlapic_calc_dest(struct acrn_vcpu *vcpu, uint32_t shorthand, bool is_broadcast,
|
||||||
* Hardware will handle the real delivery mode among all "possible" dest processors:
|
uint32_t dest, bool phys, bool lowprio)
|
||||||
* 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)
|
|
||||||
{
|
{
|
||||||
struct acrn_vlapic *vlapic;
|
uint64_t dmask = 0UL;
|
||||||
struct acrn_vcpu *vcpu;
|
|
||||||
uint16_t vcpu_id;
|
|
||||||
|
|
||||||
*dmask = 0UL;
|
switch (shorthand) {
|
||||||
if (is_broadcast) {
|
case APIC_DEST_NOSHORT:
|
||||||
/* Broadcast in both logical and physical modes. */
|
dmask = vlapic_calc_dest_noshort(vcpu->vm, is_broadcast, dest, phys, lowprio);
|
||||||
*dmask = vm_active_cpus(vm);
|
break;
|
||||||
} else if (phys) {
|
case APIC_DEST_SELF:
|
||||||
/* Physical mode: "dest" is local APIC ID. */
|
bitmap_set_nolock(vcpu->vcpu_id, &dmask);
|
||||||
set_dest_mask_phys(vm, dmask, dest);
|
break;
|
||||||
} else {
|
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
|
* All possible values of 'shorthand' has been handled in prior
|
||||||
* to be compared with the logical APIC ID in LDR.
|
* case clauses.
|
||||||
*/
|
*/
|
||||||
foreach_vcpu(vcpu_id, vm, vcpu) {
|
break;
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return dmask;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -1139,7 +1134,7 @@ static void vlapic_write_icrlo(struct acrn_vlapic *vlapic)
|
|||||||
{
|
{
|
||||||
uint16_t vcpu_id;
|
uint16_t vcpu_id;
|
||||||
bool phys = false, is_broadcast = false;
|
bool phys = false, is_broadcast = false;
|
||||||
uint64_t dmask = 0UL;
|
uint64_t dmask;
|
||||||
uint32_t icr_low, icr_high, dest;
|
uint32_t icr_low, icr_high, dest;
|
||||||
uint32_t vec, mode, shorthand;
|
uint32_t vec, mode, shorthand;
|
||||||
struct lapic_regs *lapic;
|
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",
|
"icrlo 0x%08x icrhi 0x%08x triggered ipi %u",
|
||||||
icr_low, icr_high, vec);
|
icr_low, icr_high, vec);
|
||||||
|
|
||||||
switch (shorthand) {
|
dmask = vlapic_calc_dest(vcpu, shorthand, is_broadcast, dest, phys, false);
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (vcpu_id = 0U; vcpu_id < vcpu->vm->hw.created_vcpus; vcpu_id++) {
|
for (vcpu_id = 0U; vcpu_id < vcpu->vm->hw.created_vcpus; vcpu_id++) {
|
||||||
if ((dmask & (1UL << vcpu_id)) != 0UL) {
|
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
|
* all interrupts originating from the ioapic or MSI specify the
|
||||||
* 'dest' in the legacy xAPIC format.
|
* '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++) {
|
for (vcpu_id = 0U; vcpu_id < vm->hw.created_vcpus; vcpu_id++) {
|
||||||
struct acrn_vlapic *vlapic;
|
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
|
* the delivery mode of vmsi will be forwarded to ICR delievry field
|
||||||
* and handled by hardware.
|
* 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);
|
dev_dbg(DBG_LEVEL_LAPICPT, "%s: vcpu destination mask 0x%016lx", __func__, vdmask);
|
||||||
|
|
||||||
vcpu_id = ffs64(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);
|
phys = ((icr_low & APIC_DESTMODE_LOG) == 0UL);
|
||||||
shorthand = icr_low & APIC_DEST_MASK;
|
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 \
|
pr_err("Logical destination mode or shorthands \
|
||||||
not supported in ICR forpartition mode\n");
|
not supported in ICR forpartition mode\n");
|
||||||
/*
|
/*
|
||||||
|
@ -325,7 +325,7 @@ union ioapic_rte {
|
|||||||
#define APIC_RRSTAT_RESV 0x00030000U
|
#define APIC_RRSTAT_RESV 0x00030000U
|
||||||
|
|
||||||
#define APIC_DEST_MASK 0x000c0000U
|
#define APIC_DEST_MASK 0x000c0000U
|
||||||
#define APIC_DEST_DESTFLD 0x00000000U
|
#define APIC_DEST_NOSHORT 0x00000000U
|
||||||
#define APIC_DEST_SELF 0x00040000U
|
#define APIC_DEST_SELF 0x00040000U
|
||||||
#define APIC_DEST_ALLISELF 0x00080000U
|
#define APIC_DEST_ALLISELF 0x00080000U
|
||||||
#define APIC_DEST_ALLESELF 0x000c0000U
|
#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);
|
int32_t veoi_vmexit_handler(struct acrn_vcpu *vcpu);
|
||||||
void vlapic_update_tpr_threshold(const struct acrn_vlapic *vlapic);
|
void vlapic_update_tpr_threshold(const struct acrn_vlapic *vlapic);
|
||||||
int32_t tpr_below_threshold_vmexit_handler(struct acrn_vcpu *vcpu);
|
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);
|
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_x2apic_enabled(const struct acrn_vlapic *vlapic);
|
||||||
bool is_xapic_enabled(const struct acrn_vlapic *vlapic);
|
bool is_xapic_enabled(const struct acrn_vlapic *vlapic);
|
||||||
/**
|
/**
|
||||||
|
Loading…
Reference in New Issue
Block a user