hv: refine msi interrupt injection functions

1. refine the prototype of 'inject_msi_lapic_pt()'
 2. rename below function:
    - rename 'vlapic_intr_msi()' to 'vlapic_inject_msi()'
    - rename 'inject_msi_lapic_pt()' to
      'inject_msi_for_lapic_pt()'
    - rename 'inject_msi_lapic_virt()' to
      'inject_msi_for_non_lapic_pt()'

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:34:10 +08:00 committed by wenlingz
parent 012927d0bd
commit 3ea1ae1e11
4 changed files with 54 additions and 37 deletions

View File

@ -512,7 +512,7 @@ void ptirq_softirq(uint16_t pcpu_id)
} else { } else {
if (vmsi != NULL) { if (vmsi != NULL) {
/* TODO: vmsi destmode check required */ /* TODO: vmsi destmode check required */
(void)vlapic_intr_msi(entry->vm, vmsi->addr.full, vmsi->data.full); (void)vlapic_inject_msi(entry->vm, vmsi->addr.full, vmsi->data.full);
dev_dbg(DBG_LEVEL_PTIRQ, "dev-assign: irq=0x%x MSI VR: 0x%x-0x%x", dev_dbg(DBG_LEVEL_PTIRQ, "dev-assign: irq=0x%x MSI VR: 0x%x-0x%x",
entry->allocated_pirq, vmsi->data.bits.vector, entry->allocated_pirq, vmsi->data.bits.vector,
irq_to_vector(entry->allocated_pirq)); irq_to_vector(entry->allocated_pirq));

View File

@ -1873,7 +1873,7 @@ vlapic_set_local_intr(struct acrn_vm *vm, uint16_t vcpu_id_arg, uint32_t lvt_ind
} }
/** /**
* @brief Inject MSI to target VM. * @brief Inject MSI to target VM for case that local APIC is virtualized.
* *
* @param[in] vm Pointer to VM data structure * @param[in] vm Pointer to VM data structure
* @param[in] addr MSI address. * @param[in] addr MSI address.
@ -1884,8 +1884,7 @@ vlapic_set_local_intr(struct acrn_vm *vm, uint16_t vcpu_id_arg, uint32_t lvt_ind
* *
* @pre vm != NULL * @pre vm != NULL
*/ */
int32_t static int32_t inject_msi_for_non_lapic_pt(struct acrn_vm *vm, uint64_t addr, uint64_t msg)
vlapic_intr_msi(struct acrn_vm *vm, uint64_t addr, uint64_t msg)
{ {
uint32_t delmode, vec; uint32_t delmode, vec;
uint32_t dest; uint32_t dest;
@ -1933,7 +1932,7 @@ vlapic_intr_msi(struct acrn_vm *vm, uint64_t addr, uint64_t msg)
/** /**
*@pre Pointer vm shall point to SOS_VM *@pre Pointer vm shall point to SOS_VM
*/ */
void inject_msi_lapic_pt(struct acrn_vm *vm, const struct acrn_msi_entry *vmsi) static void inject_msi_for_lapic_pt(struct acrn_vm *vm, uint64_t addr, uint64_t data)
{ {
union apic_icr icr; union apic_icr icr;
struct acrn_vcpu *vcpu; struct acrn_vcpu *vcpu;
@ -1944,11 +1943,11 @@ void inject_msi_lapic_pt(struct acrn_vm *vm, const struct acrn_msi_entry *vmsi)
uint16_t vcpu_id; uint16_t vcpu_id;
bool phys; bool phys;
vmsi_addr.full = vmsi->msi_addr; vmsi_addr.full = addr;
vmsi_data.full = (uint32_t)vmsi->msi_data; vmsi_data.full = (uint32_t)data;
dev_dbg(DBG_LEVEL_LAPICPT, "%s: msi_addr 0x%016lx, msi_data 0x%016lx", dev_dbg(DBG_LEVEL_LAPICPT, "%s: msi_addr 0x%016lx, msi_data 0x%016lx",
__func__, vmsi->msi_addr, vmsi->msi_data); __func__, addr, data);
if (vmsi_addr.bits.addr_base == MSI_ADDR_BASE) { if (vmsi_addr.bits.addr_base == MSI_ADDR_BASE) {
vdest = vmsi_addr.bits.dest_field; vdest = vmsi_addr.bits.dest_field;
@ -1980,6 +1979,49 @@ void inject_msi_lapic_pt(struct acrn_vm *vm, const struct acrn_msi_entry *vmsi)
} }
} }
/**
* @brief Inject MSI to target VM for both virtual local APIC and local APIC pass-through cases.
*
* @param[in] vm Pointer to VM data structure.
* @param[in] addr MSI address.
* @param[in] data MSI data.
*
* @retval 0 on success.
* @retval -1 on error that addr is invalid.
*
* @pre vm != NULL
*/
int32_t vlapic_inject_msi(struct acrn_vm *vm, uint64_t addr, uint64_t data)
{
int32_t ret = -1;
/* For target cpu with lapic pt, send ipi instead of injection via vlapic */
if (is_lapic_pt_configured(vm)) {
enum vm_vlapic_mode vlapic_mode = check_vm_vlapic_mode(vm);
if (vlapic_mode == VM_VLAPIC_X2APIC) {
/*
* All the vCPUs of VM are in x2APIC mode and LAPIC is PT
* Inject the vMSI as an IPI directly to VM
*/
inject_msi_for_lapic_pt(vm, addr, data);
ret = 0;
} else if (vlapic_mode == VM_VLAPIC_XAPIC) {
/*
* All the vCPUs of VM are in xAPIC and use vLAPIC
* Inject using vLAPIC
*/
ret = inject_msi_for_non_lapic_pt(vm, addr, data);
} else {
/* Returns error for VM_VLAPIC_DISABLED and VM_VLAPIC_TRANSITION cases*/
}
} else {
ret = inject_msi_for_non_lapic_pt(vm, addr, data);
}
return ret;
}
/* interrupt context */ /* interrupt context */
static void vlapic_timer_expired(void *data) static void vlapic_timer_expired(void *data)
{ {

View File

@ -438,32 +438,7 @@ int32_t hcall_inject_msi(struct acrn_vm *vm, struct acrn_vm *target_vm, __unused
struct acrn_msi_entry msi; struct acrn_msi_entry msi;
if (copy_from_gpa(vm, &msi, param2, sizeof(msi)) == 0) { if (copy_from_gpa(vm, &msi, param2, sizeof(msi)) == 0) {
/* For target cpu with lapic pt, send ipi instead of injection via vlapic */ ret = vlapic_inject_msi(target_vm, msi.msi_addr, msi.msi_data);
if (is_lapic_pt_configured(target_vm)) {
enum vm_vlapic_mode vlapic_mode = check_vm_vlapic_mode(target_vm);
if (vlapic_mode == VM_VLAPIC_X2APIC) {
/*
* All the vCPUs of VM are in x2APIC mode and LAPIC is PT
* Inject the vMSI as an IPI directly to VM
*/
inject_msi_lapic_pt(target_vm, &msi);
ret = 0;
} else if (vlapic_mode == VM_VLAPIC_XAPIC) {
/*
* All the vCPUs of VM are in xAPIC and use vLAPIC
* Inject using vLAPIC
*/
ret = vlapic_intr_msi(target_vm, msi.msi_addr, msi.msi_data);
} else {
/*
* For cases VM_VLAPIC_DISABLED and VM_VLAPIC_TRANSITION
* Silently drop interrupt
*/
}
} else {
ret = vlapic_intr_msi(target_vm, msi.msi_addr, msi.msi_data);
}
} }
} }

View File

@ -152,15 +152,15 @@ int32_t vlapic_set_local_intr(struct acrn_vm *vm, uint16_t vcpu_id_arg, uint32_t
* *
* @param[in] vm Pointer to VM data structure * @param[in] vm Pointer to VM data structure
* @param[in] addr MSI address. * @param[in] addr MSI address.
* @param[in] msg MSI data. * @param[in] data MSI data.
* *
* @retval 0 on success. * @retval 0 on success.
* @retval -1 on error that addr is invalid. * @retval -1 on error that addr is invalid.
* *
* @pre vm != NULL * @pre vm != NULL
*/ */
int32_t vlapic_intr_msi(struct acrn_vm *vm, uint64_t addr, uint64_t msg); int32_t vlapic_inject_msi(struct acrn_vm *vm, uint64_t addr, uint64_t data);
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);