Lines Matching +full:cpu +full:- +full:to +full:- +full:pci

1 // SPDX-License-Identifier: GPL-2.0
4 * Irqdomain for Linux to run as the root partition on Microsoft Hypervisor.
11 #include <linux/pci.h>
16 int cpu, int vector, struct hv_interrupt_entry *entry) in hv_map_interrupt() argument
30 intr_desc = &input->interrupt_descriptor; in hv_map_interrupt()
32 input->partition_id = hv_current_partition_id; in hv_map_interrupt()
33 input->device_id = device_id.as_uint64; in hv_map_interrupt()
34 intr_desc->interrupt_type = HV_X64_INTERRUPT_TYPE_FIXED; in hv_map_interrupt()
35 intr_desc->vector_count = 1; in hv_map_interrupt()
36 intr_desc->target.vector = vector; in hv_map_interrupt()
39 intr_desc->trigger_mode = HV_INTERRUPT_TRIGGER_MODE_LEVEL; in hv_map_interrupt()
41 intr_desc->trigger_mode = HV_INTERRUPT_TRIGGER_MODE_EDGE; in hv_map_interrupt()
43 intr_desc->target.vp_set.valid_bank_mask = 0; in hv_map_interrupt()
44 intr_desc->target.vp_set.format = HV_GENERIC_SET_SPARSE_4K; in hv_map_interrupt()
45 nr_bank = cpumask_to_vpset(&(intr_desc->target.vp_set), cpumask_of(cpu)); in hv_map_interrupt()
48 pr_err("%s: unable to generate VP set\n", __func__); in hv_map_interrupt()
51 intr_desc->target.flags = HV_DEVICE_INTERRUPT_TARGET_PROCESSOR_SET; in hv_map_interrupt()
54 * var-sized hypercall, var-size starts after vp_mask (thus in hv_map_interrupt()
62 *entry = output->interrupt_entry; in hv_map_interrupt()
83 intr_entry = &input->interrupt_entry; in hv_unmap_interrupt()
84 input->partition_id = hv_current_partition_id; in hv_unmap_interrupt()
85 input->device_id = id; in hv_unmap_interrupt()
103 u8 bus = PCI_BUS_NUM(rd->rid); in get_rid_cb()
105 if (pdev->bus->number != bus || PCI_BUS_NUM(alias) != bus) { in get_rid_cb()
106 rd->bridge = pdev; in get_rid_cb()
107 rd->rid = alias; in get_rid_cb()
118 .rid = PCI_DEVID(dev->bus->number, dev->devfn) in hv_build_pci_dev_id()
125 dev_id.pci.segment = pci_domain_nr(dev->bus); in hv_build_pci_dev_id()
127 dev_id.pci.bdf.bus = PCI_BUS_NUM(data.rid); in hv_build_pci_dev_id()
128 dev_id.pci.bdf.device = PCI_SLOT(data.rid); in hv_build_pci_dev_id()
129 dev_id.pci.bdf.function = PCI_FUNC(data.rid); in hv_build_pci_dev_id()
130 dev_id.pci.source_shadow = HV_SOURCE_SHADOW_NONE; in hv_build_pci_dev_id()
137 * running in PCI-X mode. in hv_build_pci_dev_id()
139 * To distinguish conventional vs PCI-X bridge, we can check in hv_build_pci_dev_id()
140 * the bridge's PCI-X Secondary Status Register, Secondary Bus in hv_build_pci_dev_id()
141 * Mode and Frequency bits. See PCI Express to PCI/PCI-X Bridge in hv_build_pci_dev_id()
145 * in PCI-X mode. in hv_build_pci_dev_id()
156 /* Non-zero, PCI-X mode */ in hv_build_pci_dev_id()
159 dev_id.pci.source_shadow = HV_SOURCE_SHADOW_BRIDGE_BUS_RANGE; in hv_build_pci_dev_id()
162 dev_id.pci.shadow_bus_range.secondary_bus = sec_bus; in hv_build_pci_dev_id()
164 dev_id.pci.shadow_bus_range.subordinate_bus = sub_bus; in hv_build_pci_dev_id()
172 static int hv_map_msi_interrupt(struct pci_dev *dev, int cpu, int vector, in hv_map_msi_interrupt() argument
177 return hv_map_interrupt(device_id, false, cpu, vector, entry); in hv_map_msi_interrupt()
183 msg->address_hi = 0; in entry_to_msi_msg()
184 msg->address_lo = entry->msi_entry.address.as_uint32; in entry_to_msi_msg()
185 msg->data = entry->msi_entry.data.as_uint32; in entry_to_msi_msg()
196 int cpu; in hv_irq_compose_msi_msg() local
208 cpu = cpumask_first_and(affinity, cpu_online_mask); in hv_irq_compose_msi_msg()
210 if (data->chip_data) { in hv_irq_compose_msi_msg()
215 * Microsoft Hypervisor doens't allow root to change the vector in hv_irq_compose_msi_msg()
219 stored_entry = data->chip_data; in hv_irq_compose_msi_msg()
220 data->chip_data = NULL; in hv_irq_compose_msi_msg()
227 pr_debug("%s: failed to unmap, status %lld", __func__, status); in hv_irq_compose_msi_msg()
234 pr_debug("%s: failed to allocate chip data\n", __func__); in hv_irq_compose_msi_msg()
238 status = hv_map_msi_interrupt(dev, cpu, cfg->vector, &out_entry); in hv_irq_compose_msi_msg()
245 data->chip_data = stored_entry; in hv_irq_compose_msi_msg()
262 if (!irqd->chip_data) { in hv_teardown_msi_irq()
267 old_entry = *(struct hv_interrupt_entry *)irqd->chip_data; in hv_teardown_msi_irq()
270 kfree(irqd->chip_data); in hv_teardown_msi_irq()
271 irqd->chip_data = NULL; in hv_teardown_msi_irq()
289 if (!desc || !desc->irq || WARN_ON_ONCE(!dev_is_pci(desc->dev))) in hv_msi_free_irq()
292 hv_teardown_msi_irq(to_pci_dev(desc->dev), irqd); in hv_msi_free_irq()
296 * IRQ Chip for MSI PCI/PCI-X/PCI-Express Devices,
297 * which implement the MSI or MSI-X Capability Structure.
300 .name = "HV-PCI-MSI",
329 fn = irq_domain_alloc_named_fwnode("HV-PCI-MSI"); in hv_create_pci_msi_domain()
353 int hv_map_ioapic_interrupt(int ioapic_id, bool level, int cpu, int vector, in hv_map_ioapic_interrupt() argument
362 return hv_map_interrupt(device_id, level, cpu, vector, entry); in hv_map_ioapic_interrupt()