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:
Yonghua Huang 2020-10-11 19:17:50 +08:00 committed by wenlingz
parent f511a71c4e
commit 012927d0bd
3 changed files with 51 additions and 50 deletions

View File

@ -1930,6 +1930,56 @@ vlapic_intr_msi(struct acrn_vm *vm, uint64_t addr, uint64_t msg)
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 */
static void vlapic_timer_expired(void *data)
{

View File

@ -417,56 +417,6 @@ int32_t hcall_set_irqline(struct acrn_vm *vm, struct acrn_vm *target_vm, __unuse
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
*

View File

@ -160,6 +160,7 @@ int32_t vlapic_set_local_intr(struct acrn_vm *vm, uint16_t vcpu_id_arg, uint32_t
* @pre vm != NULL
*/
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,
bool phys, uint32_t delmode, uint32_t vec, bool rh);