/* * Irqdomain for Linux to run as the root partition on Microsoft Hypervisor. * * Authors: * Sunil Muthuswamy <sunilmut@microsoft.com> * Wei Liu <wei.liu@kernel.org>
*/
/* * Microsoft Hypervisor requires a bus range when the bridge is * running in PCI-X mode. * * To distinguish conventional vs PCI-X bridge, we can check * the bridge's PCI-X Secondary Status Register, Secondary Bus * Mode and Frequency bits. See PCI Express to PCI/PCI-X Bridge * Specification Revision 1.0 5.2.2.1.3. * * Value zero means it is in conventional mode, otherwise it is * in PCI-X mode.
*/
pos = pci_find_capability(data.bridge, PCI_CAP_ID_PCIX); if (pos) {
u16 status;
/** * hv_map_msi_interrupt() - "Map" the MSI IRQ in the hypervisor. * @data: Describes the IRQ * @out_entry: Hypervisor (MSI) interrupt entry (can be NULL) * * Map the IRQ in the hypervisor by issuing a MAP_DEVICE_INTERRUPT hypercall. * * Return: 0 on success, -errno on failure
*/ int hv_map_msi_interrupt(struct irq_data *data, struct hv_interrupt_entry *out_entry)
{ struct irq_cfg *cfg = irqd_cfg(data); struct hv_interrupt_entry dummy; union hv_device_id device_id; struct msi_desc *msidesc; struct pci_dev *dev; int cpu;
msidesc = irq_data_get_msi_desc(data);
dev = msi_desc_to_pci_dev(msidesc);
device_id = hv_build_pci_dev_id(dev);
cpu = cpumask_first(irq_data_get_effective_affinity_mask(data));
msidesc = irq_data_get_msi_desc(data);
dev = msi_desc_to_pci_dev(msidesc);
if (!cfg) {
pr_debug("%s: cfg is NULL", __func__); return;
}
if (data->chip_data) { /* * This interrupt is already mapped. Let's unmap first. * * We don't use retarget interrupt hypercalls here because * Microsoft Hypervisor doesn't allow root to change the vector * or specify VPs outside of the set that is initially used * during mapping.
*/
stored_entry = data->chip_data;
data->chip_data = NULL;
ret = hv_unmap_msi_interrupt(dev, stored_entry);
kfree(stored_entry);
if (ret) return;
}
stored_entry = kzalloc(sizeof(*stored_entry), GFP_ATOMIC); if (!stored_entry) {
pr_debug("%s: failed to allocate chip data\n", __func__); return;
}
ret = hv_map_msi_interrupt(data, stored_entry); if (ret) {
kfree(stored_entry); return;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.