Commit 1982afd6 authored by Thomas Gleixner's avatar Thomas Gleixner
Browse files

x86/hyperv: Refactor hv_msi_domain_free_irqs()



No point in looking up things over and over. Just look up the associated
irq data and work from there.

No functional change.

Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
Reviewed-by: default avatarJason Gunthorpe <jgg@nvidia.com>
Acked-by: default avatarWei Liu <wei.liu@kernel.org>
Link: https://lore.kernel.org/r/20211206210224.429625690@linutronix.de
parent e58f2259
Loading
Loading
Loading
Loading
+17 −38
Original line number Diff line number Diff line
@@ -253,64 +253,43 @@ static int hv_unmap_msi_interrupt(struct pci_dev *dev, struct hv_interrupt_entry
	return hv_unmap_interrupt(hv_build_pci_dev_id(dev).as_uint64, old_entry);
}

static void hv_teardown_msi_irq_common(struct pci_dev *dev, struct msi_desc *msidesc, int irq)
static void hv_teardown_msi_irq(struct pci_dev *dev, struct irq_data *irqd)
{
	u64 status;
	struct hv_interrupt_entry old_entry;
	struct irq_desc *desc;
	struct irq_data *data;
	struct msi_msg msg;
	u64 status;

	desc = irq_to_desc(irq);
	if (!desc) {
		pr_debug("%s: no irq desc\n", __func__);
		return;
	}

	data = &desc->irq_data;
	if (!data) {
		pr_debug("%s: no irq data\n", __func__);
		return;
	}

	if (!data->chip_data) {
	if (!irqd->chip_data) {
		pr_debug("%s: no chip data\n!", __func__);
		return;
	}

	old_entry = *(struct hv_interrupt_entry *)data->chip_data;
	old_entry = *(struct hv_interrupt_entry *)irqd->chip_data;
	entry_to_msi_msg(&old_entry, &msg);

	kfree(data->chip_data);
	data->chip_data = NULL;
	kfree(irqd->chip_data);
	irqd->chip_data = NULL;

	status = hv_unmap_msi_interrupt(dev, &old_entry);

	if (status != HV_STATUS_SUCCESS) {
	if (status != HV_STATUS_SUCCESS)
		pr_err("%s: hypercall failed, status %lld\n", __func__, status);
		return;
	}
}

static void hv_msi_domain_free_irqs(struct irq_domain *domain, struct device *dev)
static void hv_msi_free_irq(struct irq_domain *domain,
			    struct msi_domain_info *info, unsigned int virq)
{
	int i;
	struct msi_desc *entry;
	struct pci_dev *pdev;
	struct irq_data *irqd = irq_get_irq_data(virq);
	struct msi_desc *desc;

	if (WARN_ON_ONCE(!dev_is_pci(dev)))
	if (!irqd)
		return;

	pdev = to_pci_dev(dev);
	desc = irq_data_get_msi_desc(irqd);
	if (!desc || !desc->irq || WARN_ON_ONCE(!dev_is_pci(desc->dev)))
		return;

	for_each_pci_msi_entry(entry, pdev) {
		if (entry->irq) {
			for (i = 0; i < entry->nvec_used; i++) {
				hv_teardown_msi_irq_common(pdev, entry, entry->irq + i);
				irq_domain_free_irqs(entry->irq + i, 1);
			}
		}
	}
	hv_teardown_msi_irq(to_pci_dev(desc->dev), irqd);
}

/*
@@ -329,7 +308,7 @@ static struct irq_chip hv_pci_msi_controller = {
};

static struct msi_domain_ops pci_msi_domain_ops = {
	.domain_free_irqs	= hv_msi_domain_free_irqs,
	.msi_free		= hv_msi_free_irq,
	.msi_prepare		= pci_msi_prepare,
};