From dd6c80c3059b0eca3a42ff8cef094a8ff1102c16 Mon Sep 17 00:00:00 2001 From: Sainath Grandhi Date: Sun, 10 Nov 2019 22:02:47 -0800 Subject: [PATCH] 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 Acked-by: Eddie Dong --- hypervisor/arch/x86/guest/assign.c | 116 ++++++++++++++--------------- hypervisor/common/hypercall.c | 20 ++++- 2 files changed, 70 insertions(+), 66 deletions(-) diff --git a/hypervisor/arch/x86/guest/assign.c b/hypervisor/arch/x86/guest/assign.c index 8c514ba58..09a42a5de 100644 --- a/hypervisor/arch/x86/guest/assign.c +++ b/hypervisor/arch/x86/guest/assign.c @@ -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); 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()))) { - pr_err("ptirq_add_intx_remapping fails!\n"); - } else if (!ioapic_irq_is_gsi(phys_irq)) { - pr_err("%s, invalid phys_pin: %d <-> irq: 0x%x is not a GSI\n", __func__, phys_pin, phys_irq); - } else { - entry = ptirq_lookup_entry_by_sid(PTDEV_INTR_INTX, &phys_sid, NULL); - 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 = ptirq_lookup_entry_by_sid(PTDEV_INTR_INTX, &phys_sid, NULL); + 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->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; + entry->release_cb = ptirq_free_irte; + + /* activate entry */ + if (ptirq_activate_entry(entry, phys_irq) < 0) { + ptirq_release_entry(entry); + entry = NULL; + } } } else { - /* The mapping has already been added to the VM. No action - * required. */ + 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->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 - */ - 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); - } + + /* + * 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); } 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; 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()))) { - pr_err("virtual irq pin is invalid!\n"); - } else { - entry = ptirq_lookup_entry_by_sid(PTDEV_INTR_INTX, &virt_sid, vm); - if (entry != NULL) { - if (is_entry_active(entry)) { - phys_irq = entry->allocated_pirq; - /* disable interrupt */ - ioapic_gsi_mask_irq(phys_irq); + entry = ptirq_lookup_entry_by_sid(PTDEV_INTR_INTX, &virt_sid, vm); + if (entry != NULL) { + if (is_entry_active(entry)) { + phys_irq = entry->allocated_pirq; + /* disable interrupt */ + ioapic_gsi_mask_irq(phys_irq); - ptirq_deactivate_entry(entry); - intr_src.is_msi = false; - intr_src.src.ioapic_id = ioapic_irq_to_ioapic_id(phys_irq); + ptirq_deactivate_entry(entry); + intr_src.is_msi = false; + intr_src.src.ioapic_id = ioapic_irq_to_ioapic_id(phys_irq); - dmar_free_irte(intr_src, (uint16_t)phys_irq); - dev_dbg(DBG_LEVEL_IRQ, - "deactive %s intx entry:ppin=%d, pirq=%d ", - (vpin_ctlr == INTX_CTLR_PIC) ? "vPIC" : "vIOAPIC", - entry->phys_sid.intx_id.pin, phys_irq); - dev_dbg(DBG_LEVEL_IRQ, "from vm%d vpin=%d\n", - entry->vm->vm_id, virt_pin); - } - - ptirq_release_entry(entry); + dmar_free_irte(intr_src, (uint16_t)phys_irq); + dev_dbg(DBG_LEVEL_IRQ, + "deactive %s intx entry:ppin=%d, pirq=%d ", + (vpin_ctlr == INTX_CTLR_PIC) ? "vPIC" : "vIOAPIC", + entry->phys_sid.intx_id.pin, phys_irq); + dev_dbg(DBG_LEVEL_IRQ, "from vm%d vpin=%d\n", + entry->vm->vm_id, virt_pin); } + + ptirq_release_entry(entry); } } diff --git a/hypervisor/common/hypercall.c b/hypervisor/common/hypercall.c index 538b343bd..d53ec370a 100644 --- a/hypervisor/common/hypercall.c +++ b/hypervisor/common/hypercall.c @@ -18,6 +18,7 @@ #include #include #include +#include #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); spinlock_release(&vpci->lock); if ((vdev != NULL) && (vdev->pdev->bdf.value == irq.phys_bdf)) { - ret = ptirq_add_intx_remapping(target_vm, irq.intx.virt_pin, - irq.intx.phys_pin, irq.intx.pic_pin); + if ((((!irq.intx.pic_pin) && (irq.intx.virt_pin < vioapic_pincount(target_vm))) || + ((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 { 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); spinlock_release(&vpci->lock); if ((vdev != NULL) && (vdev->pdev->bdf.value == irq.phys_bdf)) { - ptirq_remove_intx_remapping(target_vm, irq.intx.virt_pin, irq.intx.pic_pin); - ret = 0; + if (((!irq.intx.pic_pin) && (irq.intx.virt_pin < vioapic_pincount(target_vm))) || + ((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 { pr_err("%s: Invalid irq type: %u\n", __func__, irq.type);