aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLong Li <longli@microsoft.com>2016-11-08 17:04:38 -0500
committerBjorn Helgaas <bhelgaas@google.com>2016-11-29 18:22:43 -0500
commit0de8ce3ee8e38cc66683438f715c79a2cc69539e (patch)
tree7defffab1a2a78f999764dcc89424f519dc89038
parente74d2ebdda33b3bdd1826b5b92e9aa45bdf92bb3 (diff)
PCI: hv: Allocate physically contiguous hypercall params buffer
hv_do_hypercall() assumes that we pass a segment from a physically contiguous buffer. A buffer allocated on the stack may not work if CONFIG_VMAP_STACK=y is set. Use kmalloc() to allocate this buffer. Reported-by: Haiyang Zhang <haiyangz@microsoft.com> Signed-off-by: Long Li <longli@microsoft.com> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> Acked-by: K. Y. Srinivasan <kys@microsoft.com>
-rw-r--r--drivers/pci/host/pci-hyperv.c29
1 files changed, 19 insertions, 10 deletions
diff --git a/drivers/pci/host/pci-hyperv.c b/drivers/pci/host/pci-hyperv.c
index a63c3a4f6c7c..3efcc7bdc5fb 100644
--- a/drivers/pci/host/pci-hyperv.c
+++ b/drivers/pci/host/pci-hyperv.c
@@ -378,6 +378,8 @@ struct hv_pcibus_device {
378 struct msi_domain_info msi_info; 378 struct msi_domain_info msi_info;
379 struct msi_controller msi_chip; 379 struct msi_controller msi_chip;
380 struct irq_domain *irq_domain; 380 struct irq_domain *irq_domain;
381 struct retarget_msi_interrupt retarget_msi_interrupt_params;
382 spinlock_t retarget_msi_interrupt_lock;
381}; 383};
382 384
383/* 385/*
@@ -774,34 +776,40 @@ static void hv_irq_unmask(struct irq_data *data)
774{ 776{
775 struct msi_desc *msi_desc = irq_data_get_msi_desc(data); 777 struct msi_desc *msi_desc = irq_data_get_msi_desc(data);
776 struct irq_cfg *cfg = irqd_cfg(data); 778 struct irq_cfg *cfg = irqd_cfg(data);
777 struct retarget_msi_interrupt params; 779 struct retarget_msi_interrupt *params;
778 struct hv_pcibus_device *hbus; 780 struct hv_pcibus_device *hbus;
779 struct cpumask *dest; 781 struct cpumask *dest;
780 struct pci_bus *pbus; 782 struct pci_bus *pbus;
781 struct pci_dev *pdev; 783 struct pci_dev *pdev;
782 int cpu; 784 int cpu;
785 unsigned long flags;
783 786
784 dest = irq_data_get_affinity_mask(data); 787 dest = irq_data_get_affinity_mask(data);
785 pdev = msi_desc_to_pci_dev(msi_desc); 788 pdev = msi_desc_to_pci_dev(msi_desc);
786 pbus = pdev->bus; 789 pbus = pdev->bus;
787 hbus = container_of(pbus->sysdata, struct hv_pcibus_device, sysdata); 790 hbus = container_of(pbus->sysdata, struct hv_pcibus_device, sysdata);
788 791
789 memset(&params, 0, sizeof(params)); 792 spin_lock_irqsave(&hbus->retarget_msi_interrupt_lock, flags);
790 params.partition_id = HV_PARTITION_ID_SELF; 793
791 params.source = 1; /* MSI(-X) */ 794 params = &hbus->retarget_msi_interrupt_params;
792 params.address = msi_desc->msg.address_lo; 795 memset(params, 0, sizeof(*params));
793 params.data = msi_desc->msg.data; 796 params->partition_id = HV_PARTITION_ID_SELF;
794 params.device_id = (hbus->hdev->dev_instance.b[5] << 24) | 797 params->source = 1; /* MSI(-X) */
798 params->address = msi_desc->msg.address_lo;
799 params->data = msi_desc->msg.data;
800 params->device_id = (hbus->hdev->dev_instance.b[5] << 24) |
795 (hbus->hdev->dev_instance.b[4] << 16) | 801 (hbus->hdev->dev_instance.b[4] << 16) |
796 (hbus->hdev->dev_instance.b[7] << 8) | 802 (hbus->hdev->dev_instance.b[7] << 8) |
797 (hbus->hdev->dev_instance.b[6] & 0xf8) | 803 (hbus->hdev->dev_instance.b[6] & 0xf8) |
798 PCI_FUNC(pdev->devfn); 804 PCI_FUNC(pdev->devfn);
799 params.vector = cfg->vector; 805 params->vector = cfg->vector;
800 806
801 for_each_cpu_and(cpu, dest, cpu_online_mask) 807 for_each_cpu_and(cpu, dest, cpu_online_mask)
802 params.vp_mask |= (1ULL << vmbus_cpu_number_to_vp_number(cpu)); 808 params->vp_mask |= (1ULL << vmbus_cpu_number_to_vp_number(cpu));
809
810 hv_do_hypercall(HVCALL_RETARGET_INTERRUPT, params, NULL);
803 811
804 hv_do_hypercall(HVCALL_RETARGET_INTERRUPT, &params, NULL); 812 spin_unlock_irqrestore(&hbus->retarget_msi_interrupt_lock, flags);
805 813
806 pci_msi_unmask_irq(data); 814 pci_msi_unmask_irq(data);
807} 815}
@@ -2186,6 +2194,7 @@ static int hv_pci_probe(struct hv_device *hdev,
2186 INIT_LIST_HEAD(&hbus->resources_for_children); 2194 INIT_LIST_HEAD(&hbus->resources_for_children);
2187 spin_lock_init(&hbus->config_lock); 2195 spin_lock_init(&hbus->config_lock);
2188 spin_lock_init(&hbus->device_list_lock); 2196 spin_lock_init(&hbus->device_list_lock);
2197 spin_lock_init(&hbus->retarget_msi_interrupt_lock);
2189 sema_init(&hbus->enum_sem, 1); 2198 sema_init(&hbus->enum_sem, 1);
2190 init_completion(&hbus->remove_event); 2199 init_completion(&hbus->remove_event);
2191 2200