mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-08-01 07:49:39 +00:00
hv: move function 'inject_msi_lapic_pt()' to vlapic.c
This function can be used by other modules instead of hypercall handling only, hence move it to vlapic.c Tracked-On: #5407 Signed-off-by: Yonghua Huang <yonghua.huang@intel.com> Reviewed-by: Li, Fei <fei1.li@intel.com> Reviewed-by: Wang, Yu1 <yu1.wang@intel.com> Acked-by: Eddie Dong <eddie.dong@intel.com>
This commit is contained in:
parent
f511a71c4e
commit
012927d0bd
@ -1930,6 +1930,56 @@ vlapic_intr_msi(struct acrn_vm *vm, uint64_t addr, uint64_t msg)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*@pre Pointer vm shall point to SOS_VM
|
||||||
|
*/
|
||||||
|
void inject_msi_lapic_pt(struct acrn_vm *vm, const struct acrn_msi_entry *vmsi)
|
||||||
|
{
|
||||||
|
union apic_icr icr;
|
||||||
|
struct acrn_vcpu *vcpu;
|
||||||
|
union msi_addr_reg vmsi_addr;
|
||||||
|
union msi_data_reg vmsi_data;
|
||||||
|
uint64_t vdmask = 0UL;
|
||||||
|
uint32_t vdest, dest = 0U;
|
||||||
|
uint16_t vcpu_id;
|
||||||
|
bool phys;
|
||||||
|
|
||||||
|
vmsi_addr.full = vmsi->msi_addr;
|
||||||
|
vmsi_data.full = (uint32_t)vmsi->msi_data;
|
||||||
|
|
||||||
|
dev_dbg(DBG_LEVEL_LAPICPT, "%s: msi_addr 0x%016lx, msi_data 0x%016lx",
|
||||||
|
__func__, vmsi->msi_addr, vmsi->msi_data);
|
||||||
|
|
||||||
|
if (vmsi_addr.bits.addr_base == MSI_ADDR_BASE) {
|
||||||
|
vdest = vmsi_addr.bits.dest_field;
|
||||||
|
phys = (vmsi_addr.bits.dest_mode == MSI_ADDR_DESTMODE_PHYS);
|
||||||
|
/*
|
||||||
|
* calculate all reachable destination vcpu.
|
||||||
|
* 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);
|
||||||
|
dev_dbg(DBG_LEVEL_LAPICPT, "%s: vcpu destination mask 0x%016lx", __func__, vdmask);
|
||||||
|
|
||||||
|
vcpu_id = ffs64(vdmask);
|
||||||
|
while (vcpu_id != INVALID_BIT_INDEX) {
|
||||||
|
bitmap_clear_nolock(vcpu_id, &vdmask);
|
||||||
|
vcpu = vcpu_from_vid(vm, vcpu_id);
|
||||||
|
dest |= per_cpu(lapic_ldr, pcpuid_from_vcpu(vcpu));
|
||||||
|
vcpu_id = ffs64(vdmask);
|
||||||
|
}
|
||||||
|
|
||||||
|
icr.value = 0UL;
|
||||||
|
icr.bits.dest_field = dest;
|
||||||
|
icr.bits.vector = vmsi_data.bits.vector;
|
||||||
|
icr.bits.delivery_mode = vmsi_data.bits.delivery_mode;
|
||||||
|
icr.bits.destination_mode = MSI_ADDR_DESTMODE_LOGICAL;
|
||||||
|
|
||||||
|
msr_write(MSR_IA32_EXT_APIC_ICR, icr.value);
|
||||||
|
dev_dbg(DBG_LEVEL_LAPICPT, "%s: icr.value 0x%016lx", __func__, icr.value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* interrupt context */
|
/* interrupt context */
|
||||||
static void vlapic_timer_expired(void *data)
|
static void vlapic_timer_expired(void *data)
|
||||||
{
|
{
|
||||||
|
@ -417,56 +417,6 @@ int32_t hcall_set_irqline(struct acrn_vm *vm, struct acrn_vm *target_vm, __unuse
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
*@pre Pointer vm shall point to SOS_VM
|
|
||||||
*/
|
|
||||||
static void inject_msi_lapic_pt(struct acrn_vm *vm, const struct acrn_msi_entry *vmsi)
|
|
||||||
{
|
|
||||||
union apic_icr icr;
|
|
||||||
struct acrn_vcpu *vcpu;
|
|
||||||
union msi_addr_reg vmsi_addr;
|
|
||||||
union msi_data_reg vmsi_data;
|
|
||||||
uint64_t vdmask = 0UL;
|
|
||||||
uint32_t vdest, dest = 0U;
|
|
||||||
uint16_t vcpu_id;
|
|
||||||
bool phys;
|
|
||||||
|
|
||||||
vmsi_addr.full = vmsi->msi_addr;
|
|
||||||
vmsi_data.full = (uint32_t)vmsi->msi_data;
|
|
||||||
|
|
||||||
dev_dbg(DBG_LEVEL_LAPICPT, "%s: msi_addr 0x%016lx, msi_data 0x%016lx",
|
|
||||||
__func__, vmsi->msi_addr, vmsi->msi_data);
|
|
||||||
|
|
||||||
if (vmsi_addr.bits.addr_base == MSI_ADDR_BASE) {
|
|
||||||
vdest = vmsi_addr.bits.dest_field;
|
|
||||||
phys = (vmsi_addr.bits.dest_mode == MSI_ADDR_DESTMODE_PHYS);
|
|
||||||
/*
|
|
||||||
* calculate all reachable destination vcpu.
|
|
||||||
* 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);
|
|
||||||
dev_dbg(DBG_LEVEL_LAPICPT, "%s: vcpu destination mask 0x%016lx", __func__, vdmask);
|
|
||||||
|
|
||||||
vcpu_id = ffs64(vdmask);
|
|
||||||
while (vcpu_id != INVALID_BIT_INDEX) {
|
|
||||||
bitmap_clear_nolock(vcpu_id, &vdmask);
|
|
||||||
vcpu = vcpu_from_vid(vm, vcpu_id);
|
|
||||||
dest |= per_cpu(lapic_ldr, pcpuid_from_vcpu(vcpu));
|
|
||||||
vcpu_id = ffs64(vdmask);
|
|
||||||
}
|
|
||||||
|
|
||||||
icr.value = 0UL;
|
|
||||||
icr.bits.dest_field = dest;
|
|
||||||
icr.bits.vector = vmsi_data.bits.vector;
|
|
||||||
icr.bits.delivery_mode = vmsi_data.bits.delivery_mode;
|
|
||||||
icr.bits.destination_mode = MSI_ADDR_DESTMODE_LOGICAL;
|
|
||||||
|
|
||||||
msr_write(MSR_IA32_EXT_APIC_ICR, icr.value);
|
|
||||||
dev_dbg(DBG_LEVEL_LAPICPT, "%s: icr.value 0x%016lx", __func__, icr.value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief inject MSI interrupt
|
* @brief inject MSI interrupt
|
||||||
*
|
*
|
||||||
|
@ -160,6 +160,7 @@ int32_t vlapic_set_local_intr(struct acrn_vm *vm, uint16_t vcpu_id_arg, uint32_t
|
|||||||
* @pre vm != NULL
|
* @pre vm != NULL
|
||||||
*/
|
*/
|
||||||
int32_t vlapic_intr_msi(struct acrn_vm *vm, uint64_t addr, uint64_t msg);
|
int32_t vlapic_intr_msi(struct acrn_vm *vm, uint64_t addr, uint64_t msg);
|
||||||
|
void inject_msi_lapic_pt(struct acrn_vm *vm, const struct acrn_msi_entry *vmsi);
|
||||||
|
|
||||||
void vlapic_receive_intr(struct acrn_vm *vm, bool level, uint32_t dest,
|
void vlapic_receive_intr(struct acrn_vm *vm, bool level, uint32_t dest,
|
||||||
bool phys, uint32_t delmode, uint32_t vec, bool rh);
|
bool phys, uint32_t delmode, uint32_t vec, bool rh);
|
||||||
|
Loading…
Reference in New Issue
Block a user