mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-06-20 20:53:46 +00:00
hv: Move error checking for hypercall parameters out of assign module
Moving checks on validity of IOAPIC interrupt remapping hypercall parameters to hypercall module Tracked-On: #4151 Signed-off-by: Sainath Grandhi <sainath.grandhi@intel.com> Acked-by: Eddie Dong <eddie.dong@Intel.com>
This commit is contained in:
parent
37eb369f89
commit
9e21c5bda4
@ -350,51 +350,47 @@ static struct ptirq_remapping_info *add_intx_remapping(struct acrn_vm *vm, uint3
|
|||||||
DEFINE_INTX_SID(virt_sid, virt_pin, vpin_ctlr);
|
DEFINE_INTX_SID(virt_sid, virt_pin, vpin_ctlr);
|
||||||
uint32_t phys_irq = ioapic_pin_to_irq(phys_pin);
|
uint32_t phys_irq = ioapic_pin_to_irq(phys_pin);
|
||||||
|
|
||||||
if (((vpin_ctlr == INTX_CTLR_IOAPIC) && (virt_pin >= vioapic_pincount(vm))) || ((vpin_ctlr == INTX_CTLR_PIC) && (virt_pin >= vpic_pincount()))) {
|
entry = ptirq_lookup_entry_by_sid(PTDEV_INTR_INTX, &phys_sid, NULL);
|
||||||
pr_err("ptirq_add_intx_remapping fails!\n");
|
if (entry == NULL) {
|
||||||
} else if (!ioapic_irq_is_gsi(phys_irq)) {
|
if (ptirq_lookup_entry_by_sid(PTDEV_INTR_INTX, &virt_sid, vm) == NULL) {
|
||||||
pr_err("%s, invalid phys_pin: %d <-> irq: 0x%x is not a GSI\n", __func__, phys_pin, phys_irq);
|
entry = ptirq_alloc_entry(vm, PTDEV_INTR_INTX);
|
||||||
} else {
|
if (entry != NULL) {
|
||||||
entry = ptirq_lookup_entry_by_sid(PTDEV_INTR_INTX, &phys_sid, NULL);
|
entry->phys_sid.value = phys_sid.value;
|
||||||
if (entry == NULL) {
|
|
||||||
if (ptirq_lookup_entry_by_sid(PTDEV_INTR_INTX, &virt_sid, vm) == NULL) {
|
|
||||||
entry = ptirq_alloc_entry(vm, PTDEV_INTR_INTX);
|
|
||||||
if (entry != NULL) {
|
|
||||||
entry->phys_sid.value = phys_sid.value;
|
|
||||||
entry->virt_sid.value = virt_sid.value;
|
|
||||||
entry->release_cb = ptirq_free_irte;
|
|
||||||
|
|
||||||
/* activate entry */
|
|
||||||
if (ptirq_activate_entry(entry, phys_irq) < 0) {
|
|
||||||
ptirq_release_entry(entry);
|
|
||||||
entry = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
pr_err("INTX re-add vpin %d", virt_pin);
|
|
||||||
}
|
|
||||||
} else if (entry->vm != vm) {
|
|
||||||
if (is_sos_vm(entry->vm)) {
|
|
||||||
entry->vm = vm;
|
|
||||||
entry->virt_sid.value = virt_sid.value;
|
entry->virt_sid.value = virt_sid.value;
|
||||||
entry->polarity = 0U;
|
entry->release_cb = ptirq_free_irte;
|
||||||
} else {
|
|
||||||
pr_err("INTX pin%d already in vm%d with vpin%d, not able to add into vm%d with vpin%d",
|
/* activate entry */
|
||||||
phys_pin, entry->vm->vm_id, entry->virt_sid.intx_id.pin, vm->vm_id, virt_pin);
|
if (ptirq_activate_entry(entry, phys_irq) < 0) {
|
||||||
entry = NULL;
|
ptirq_release_entry(entry);
|
||||||
|
entry = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* The mapping has already been added to the VM. No action
|
pr_err("INTX re-add vpin %d", virt_pin);
|
||||||
* required. */
|
|
||||||
}
|
}
|
||||||
|
} else if (entry->vm != vm) {
|
||||||
|
if (is_sos_vm(entry->vm)) {
|
||||||
|
entry->vm = vm;
|
||||||
|
entry->virt_sid.value = virt_sid.value;
|
||||||
|
entry->polarity = 0U;
|
||||||
|
} else {
|
||||||
|
pr_err("INTX pin%d already in vm%d with vpin%d, not able to add into vm%d with vpin%d",
|
||||||
|
phys_pin, entry->vm->vm_id, entry->virt_sid.intx_id.pin, vm->vm_id, virt_pin);
|
||||||
|
entry = NULL;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* The mapping has already been added to the VM. No action
|
||||||
|
* required. */
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* ptirq entry is either created or transferred from SOS VM to Post-launched VM
|
/*
|
||||||
*/
|
* ptirq entry is either created or transferred from SOS VM to Post-launched VM
|
||||||
if (entry != NULL) {
|
*/
|
||||||
dev_dbg(DBG_LEVEL_IRQ, "VM%d INTX add pin mapping vpin%d:ppin%d",
|
|
||||||
entry->vm->vm_id, virt_pin, phys_pin);
|
if (entry != NULL) {
|
||||||
}
|
dev_dbg(DBG_LEVEL_IRQ, "VM%d INTX add pin mapping vpin%d:ppin%d",
|
||||||
|
entry->vm->vm_id, virt_pin, phys_pin);
|
||||||
}
|
}
|
||||||
|
|
||||||
return entry;
|
return entry;
|
||||||
@ -408,31 +404,27 @@ static void remove_intx_remapping(const struct acrn_vm *vm, uint32_t virt_pin, e
|
|||||||
struct intr_source intr_src;
|
struct intr_source intr_src;
|
||||||
DEFINE_INTX_SID(virt_sid, virt_pin, vpin_ctlr);
|
DEFINE_INTX_SID(virt_sid, virt_pin, vpin_ctlr);
|
||||||
|
|
||||||
if (((vpin_ctlr == INTX_CTLR_IOAPIC) && (virt_pin >= vioapic_pincount(vm))) || ((vpin_ctlr == INTX_CTLR_PIC) && (virt_pin >= vpic_pincount()))) {
|
entry = ptirq_lookup_entry_by_sid(PTDEV_INTR_INTX, &virt_sid, vm);
|
||||||
pr_err("virtual irq pin is invalid!\n");
|
if (entry != NULL) {
|
||||||
} else {
|
if (is_entry_active(entry)) {
|
||||||
entry = ptirq_lookup_entry_by_sid(PTDEV_INTR_INTX, &virt_sid, vm);
|
phys_irq = entry->allocated_pirq;
|
||||||
if (entry != NULL) {
|
/* disable interrupt */
|
||||||
if (is_entry_active(entry)) {
|
ioapic_gsi_mask_irq(phys_irq);
|
||||||
phys_irq = entry->allocated_pirq;
|
|
||||||
/* disable interrupt */
|
|
||||||
ioapic_gsi_mask_irq(phys_irq);
|
|
||||||
|
|
||||||
ptirq_deactivate_entry(entry);
|
ptirq_deactivate_entry(entry);
|
||||||
intr_src.is_msi = false;
|
intr_src.is_msi = false;
|
||||||
intr_src.src.ioapic_id = ioapic_irq_to_ioapic_id(phys_irq);
|
intr_src.src.ioapic_id = ioapic_irq_to_ioapic_id(phys_irq);
|
||||||
|
|
||||||
dmar_free_irte(intr_src, (uint16_t)phys_irq);
|
dmar_free_irte(intr_src, (uint16_t)phys_irq);
|
||||||
dev_dbg(DBG_LEVEL_IRQ,
|
dev_dbg(DBG_LEVEL_IRQ,
|
||||||
"deactive %s intx entry:ppin=%d, pirq=%d ",
|
"deactive %s intx entry:ppin=%d, pirq=%d ",
|
||||||
(vpin_ctlr == INTX_CTLR_PIC) ? "vPIC" : "vIOAPIC",
|
(vpin_ctlr == INTX_CTLR_PIC) ? "vPIC" : "vIOAPIC",
|
||||||
entry->phys_sid.intx_id.pin, phys_irq);
|
entry->phys_sid.intx_id.pin, phys_irq);
|
||||||
dev_dbg(DBG_LEVEL_IRQ, "from vm%d vpin=%d\n",
|
dev_dbg(DBG_LEVEL_IRQ, "from vm%d vpin=%d\n",
|
||||||
entry->vm->vm_id, virt_pin);
|
entry->vm->vm_id, virt_pin);
|
||||||
}
|
|
||||||
|
|
||||||
ptirq_release_entry(entry);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ptirq_release_entry(entry);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
#include <hypercall.h>
|
#include <hypercall.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <logmsg.h>
|
#include <logmsg.h>
|
||||||
|
#include <ioapic.h>
|
||||||
|
|
||||||
#define DBG_LEVEL_HYCALL 6U
|
#define DBG_LEVEL_HYCALL 6U
|
||||||
|
|
||||||
@ -905,8 +906,14 @@ int32_t hcall_set_ptdev_intr_info(struct acrn_vm *vm, uint16_t vmid, uint64_t pa
|
|||||||
vdev = pci_find_vdev(vpci, bdf);
|
vdev = pci_find_vdev(vpci, bdf);
|
||||||
spinlock_release(&vpci->lock);
|
spinlock_release(&vpci->lock);
|
||||||
if ((vdev != NULL) && (vdev->pdev->bdf.value == irq.phys_bdf)) {
|
if ((vdev != NULL) && (vdev->pdev->bdf.value == irq.phys_bdf)) {
|
||||||
ret = ptirq_add_intx_remapping(target_vm, irq.intx.virt_pin,
|
if ((((!irq.intx.pic_pin) && (irq.intx.virt_pin < vioapic_pincount(target_vm))) ||
|
||||||
irq.intx.phys_pin, irq.intx.pic_pin);
|
((irq.intx.pic_pin) && (irq.intx.virt_pin < vpic_pincount()))) &&
|
||||||
|
ioapic_irq_is_gsi(irq.intx.phys_pin)) {
|
||||||
|
ret = ptirq_add_intx_remapping(target_vm, irq.intx.virt_pin,
|
||||||
|
irq.intx.phys_pin, irq.intx.pic_pin);
|
||||||
|
} else {
|
||||||
|
pr_err("%s: Invalid phys pin or virt pin\n", __func__);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
pr_err("%s: Invalid irq type: %u\n", __func__, irq.type);
|
pr_err("%s: Invalid irq type: %u\n", __func__, irq.type);
|
||||||
@ -948,8 +955,13 @@ hcall_reset_ptdev_intr_info(struct acrn_vm *vm, uint16_t vmid, uint64_t param)
|
|||||||
vdev = pci_find_vdev(vpci, bdf);
|
vdev = pci_find_vdev(vpci, bdf);
|
||||||
spinlock_release(&vpci->lock);
|
spinlock_release(&vpci->lock);
|
||||||
if ((vdev != NULL) && (vdev->pdev->bdf.value == irq.phys_bdf)) {
|
if ((vdev != NULL) && (vdev->pdev->bdf.value == irq.phys_bdf)) {
|
||||||
ptirq_remove_intx_remapping(target_vm, irq.intx.virt_pin, irq.intx.pic_pin);
|
if (((!irq.intx.pic_pin) && (irq.intx.virt_pin < vioapic_pincount(target_vm))) ||
|
||||||
ret = 0;
|
((irq.intx.pic_pin) && (irq.intx.virt_pin < vpic_pincount()))) {
|
||||||
|
ptirq_remove_intx_remapping(target_vm, irq.intx.virt_pin, irq.intx.pic_pin);
|
||||||
|
ret = 0;
|
||||||
|
} else {
|
||||||
|
pr_err("%s: Invalid virt pin\n", __func__);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
pr_err("%s: Invalid irq type: %u\n", __func__, irq.type);
|
pr_err("%s: Invalid irq type: %u\n", __func__, irq.type);
|
||||||
|
Loading…
Reference in New Issue
Block a user