Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch 'stable/xen-pcifront-0.8.2' of git://git.kernel.org/pub/scm/linux/kernel/git/konrad/xen and branch 'for-linus' of git://xenbits.xen.org/people/sstabellini/linux-pvhvm

* 'for-linus' of git://xenbits.xen.org/people/sstabellini/linux-pvhvm:
xen: register xen pci notifier
xen: initialize cpu masks for pv guests in xen_smp_init
xen: add a missing #include to arch/x86/pci/xen.c
xen: mask the MTRR feature from the cpuid
xen: make hvc_xen console work for dom0.
xen: add the direct mapping area for ISA bus access
xen: Initialize xenbus for dom0.
xen: use vcpu_ops to setup cpu masks
xen: map a dummy page for local apic and ioapic in xen_set_fixmap
xen: remap MSIs into pirqs when running as initial domain
xen: remap GSIs as pirqs when running as initial domain
xen: introduce XEN_DOM0 as a silent option
xen: map MSIs into pirqs
xen: support GSI -> pirq remapping in PV on HVM guests
xen: add xen hvm acpi_register_gsi variant
acpi: use indirect call to register gsi in different modes
xen: implement xen_hvm_register_pirq
xen: get the maximum number of pirqs from xen
xen: support pirq != irq

* 'stable/xen-pcifront-0.8.2' of git://git.kernel.org/pub/scm/linux/kernel/git/konrad/xen: (27 commits)
X86/PCI: Remove the dependency on isapnp_disable.
xen: Update Makefile with CONFIG_BLOCK dependency for biomerge.c
MAINTAINERS: Add myself to the Xen Hypervisor Interface and remove Chris Wright.
x86: xen: Sanitse irq handling (part two)
swiotlb-xen: On x86-32 builts, select SWIOTLB instead of depending on it.
MAINTAINERS: Add myself for Xen PCI and Xen SWIOTLB maintainer.
xen/pci: Request ACS when Xen-SWIOTLB is activated.
xen-pcifront: Xen PCI frontend driver.
xenbus: prevent warnings on unhandled enumeration values
xenbus: Xen paravirtualised PCI hotplug support.
xen/x86/PCI: Add support for the Xen PCI subsystem
x86: Introduce x86_msi_ops
msi: Introduce default_[teardown|setup]_msi_irqs with fallback.
x86/PCI: Export pci_walk_bus function.
x86/PCI: make sure _PAGE_IOMAP it set on pci mappings
x86/PCI: Clean up pci_cache_line_size
xen: fix shared irq device passthrough
xen: Provide a variant of xen_poll_irq with timeout.
xen: Find an unbound irq number in reverse order (high to low).
xen: statically initialize cpu_evtchn_mask_p
...

Fix up trivial conflicts in drivers/pci/Makefile

+2846 -96
+18 -4
MAINTAINERS
··· 6595 6595 S: Maintained 6596 6596 F: drivers/platform/x86 6597 6597 6598 - XEN HYPERVISOR INTERFACE 6599 - M: Jeremy Fitzhardinge <jeremy@xensource.com> 6600 - M: Chris Wright <chrisw@sous-sol.org> 6601 - L: virtualization@lists.osdl.org 6598 + XEN PCI SUBSYSTEM 6599 + M: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> 6602 6600 L: xen-devel@lists.xensource.com 6601 + S: Supported 6602 + F: arch/x86/pci/*xen* 6603 + F: drivers/pci/*xen* 6604 + 6605 + XEN SWIOTLB SUBSYSTEM 6606 + M: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> 6607 + L: xen-devel@lists.xensource.com 6608 + S: Supported 6609 + F: arch/x86/xen/*swiotlb* 6610 + F: drivers/xen/*swiotlb* 6611 + 6612 + XEN HYPERVISOR INTERFACE 6613 + M: Jeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com> 6614 + M: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> 6615 + L: xen-devel@lists.xen.org 6616 + L: virtualization@lists.osdl.org 6603 6617 S: Supported 6604 6618 F: arch/x86/xen/ 6605 6619 F: drivers/*/xen-*front.c
+5
arch/x86/Kconfig
··· 1893 1893 def_bool y 1894 1894 depends on PCI && OLPC && (PCI_GOOLPC || PCI_GOANY) 1895 1895 1896 + config PCI_XEN 1897 + def_bool y 1898 + depends on PCI && XEN 1899 + select SWIOTLB_XEN 1900 + 1896 1901 config PCI_DOMAINS 1897 1902 def_bool y 1898 1903 depends on PCI
+3
arch/x86/include/asm/acpi.h
··· 93 93 extern int acpi_sci_override_gsi; 94 94 void acpi_pic_sci_set_trigger(unsigned int, u16); 95 95 96 + extern int (*__acpi_register_gsi)(struct device *dev, u32 gsi, 97 + int trigger, int polarity); 98 + 96 99 static inline void disable_acpi(void) 97 100 { 98 101 acpi_disabled = 1;
+13
arch/x86/include/asm/io.h
··· 41 41 #include <asm-generic/int-ll64.h> 42 42 #include <asm/page.h> 43 43 44 + #include <xen/xen.h> 45 + 44 46 #define build_mmio_read(name, size, type, reg, barrier) \ 45 47 static inline type name(const volatile void __iomem *addr) \ 46 48 { type ret; asm volatile("mov" size " %1,%0":reg (ret) \ ··· 352 350 extern void early_iounmap(void __iomem *addr, unsigned long size); 353 351 extern void fixup_early_ioremap(void); 354 352 extern bool is_early_ioremap_ptep(pte_t *ptep); 353 + 354 + #ifdef CONFIG_XEN 355 + struct bio_vec; 356 + 357 + extern bool xen_biovec_phys_mergeable(const struct bio_vec *vec1, 358 + const struct bio_vec *vec2); 359 + 360 + #define BIOVEC_PHYS_MERGEABLE(vec1, vec2) \ 361 + (__BIOVEC_PHYS_MERGEABLE(vec1, vec2) && \ 362 + (!xen_domain() || xen_biovec_phys_mergeable(vec1, vec2))) 363 + #endif /* CONFIG_XEN */ 355 364 356 365 #define IO_SPACE_LIMIT 0xffff 357 366
+1
arch/x86/include/asm/io_apic.h
··· 169 169 extern int restore_IO_APIC_setup(struct IO_APIC_route_entry **ioapic_entries); 170 170 171 171 extern void probe_nr_irqs_gsi(void); 172 + extern int get_nr_irqs_gsi(void); 172 173 173 174 extern void setup_ioapic_ids_from_mpc(void); 174 175
+31 -2
arch/x86/include/asm/pci.h
··· 7 7 #include <linux/string.h> 8 8 #include <asm/scatterlist.h> 9 9 #include <asm/io.h> 10 + #include <asm/x86_init.h> 10 11 11 12 #ifdef __KERNEL__ 12 13 ··· 95 94 96 95 extern void pci_iommu_alloc(void); 97 96 98 - /* MSI arch hook */ 99 - #define arch_setup_msi_irqs arch_setup_msi_irqs 97 + #ifdef CONFIG_PCI_MSI 98 + /* MSI arch specific hooks */ 99 + static inline int x86_setup_msi_irqs(struct pci_dev *dev, int nvec, int type) 100 + { 101 + return x86_msi.setup_msi_irqs(dev, nvec, type); 102 + } 103 + 104 + static inline void x86_teardown_msi_irqs(struct pci_dev *dev) 105 + { 106 + x86_msi.teardown_msi_irqs(dev); 107 + } 108 + 109 + static inline void x86_teardown_msi_irq(unsigned int irq) 110 + { 111 + x86_msi.teardown_msi_irq(irq); 112 + } 113 + #define arch_setup_msi_irqs x86_setup_msi_irqs 114 + #define arch_teardown_msi_irqs x86_teardown_msi_irqs 115 + #define arch_teardown_msi_irq x86_teardown_msi_irq 116 + /* implemented in arch/x86/kernel/apic/io_apic. */ 117 + int native_setup_msi_irqs(struct pci_dev *dev, int nvec, int type); 118 + void native_teardown_msi_irq(unsigned int irq); 119 + /* default to the implementation in drivers/lib/msi.c */ 120 + #define HAVE_DEFAULT_MSI_TEARDOWN_IRQS 121 + void default_teardown_msi_irqs(struct pci_dev *dev); 122 + #else 123 + #define native_setup_msi_irqs NULL 124 + #define native_teardown_msi_irq NULL 125 + #define default_teardown_msi_irqs NULL 126 + #endif 100 127 101 128 #define PCI_DMA_BUS_IS_PHYS (dma_ops->is_phys) 102 129
+1
arch/x86/include/asm/pci_x86.h
··· 47 47 extern unsigned int pcibios_max_latency; 48 48 49 49 void pcibios_resource_survey(void); 50 + void pcibios_set_cache_line_size(void); 50 51 51 52 /* pci-pc.c */ 52 53
+9
arch/x86/include/asm/x86_init.h
··· 154 154 int (*i8042_detect)(void); 155 155 }; 156 156 157 + struct pci_dev; 158 + 159 + struct x86_msi_ops { 160 + int (*setup_msi_irqs)(struct pci_dev *dev, int nvec, int type); 161 + void (*teardown_msi_irq)(unsigned int irq); 162 + void (*teardown_msi_irqs)(struct pci_dev *dev); 163 + }; 164 + 157 165 extern struct x86_init_ops x86_init; 158 166 extern struct x86_cpuinit_ops x86_cpuinit; 159 167 extern struct x86_platform_ops x86_platform; 168 + extern struct x86_msi_ops x86_msi; 160 169 161 170 extern void x86_init_noop(void); 162 171 extern void x86_init_uint_noop(unsigned int unused);
+65
arch/x86/include/asm/xen/pci.h
··· 1 + #ifndef _ASM_X86_XEN_PCI_H 2 + #define _ASM_X86_XEN_PCI_H 3 + 4 + #if defined(CONFIG_PCI_XEN) 5 + extern int __init pci_xen_init(void); 6 + extern int __init pci_xen_hvm_init(void); 7 + #define pci_xen 1 8 + #else 9 + #define pci_xen 0 10 + #define pci_xen_init (0) 11 + static inline int pci_xen_hvm_init(void) 12 + { 13 + return -1; 14 + } 15 + #endif 16 + #if defined(CONFIG_XEN_DOM0) 17 + void __init xen_setup_pirqs(void); 18 + #else 19 + static inline void __init xen_setup_pirqs(void) 20 + { 21 + } 22 + #endif 23 + 24 + #if defined(CONFIG_PCI_MSI) 25 + #if defined(CONFIG_PCI_XEN) 26 + /* The drivers/pci/xen-pcifront.c sets this structure to 27 + * its own functions. 28 + */ 29 + struct xen_pci_frontend_ops { 30 + int (*enable_msi)(struct pci_dev *dev, int **vectors); 31 + void (*disable_msi)(struct pci_dev *dev); 32 + int (*enable_msix)(struct pci_dev *dev, int **vectors, int nvec); 33 + void (*disable_msix)(struct pci_dev *dev); 34 + }; 35 + 36 + extern struct xen_pci_frontend_ops *xen_pci_frontend; 37 + 38 + static inline int xen_pci_frontend_enable_msi(struct pci_dev *dev, 39 + int **vectors) 40 + { 41 + if (xen_pci_frontend && xen_pci_frontend->enable_msi) 42 + return xen_pci_frontend->enable_msi(dev, vectors); 43 + return -ENODEV; 44 + } 45 + static inline void xen_pci_frontend_disable_msi(struct pci_dev *dev) 46 + { 47 + if (xen_pci_frontend && xen_pci_frontend->disable_msi) 48 + xen_pci_frontend->disable_msi(dev); 49 + } 50 + static inline int xen_pci_frontend_enable_msix(struct pci_dev *dev, 51 + int **vectors, int nvec) 52 + { 53 + if (xen_pci_frontend && xen_pci_frontend->enable_msix) 54 + return xen_pci_frontend->enable_msix(dev, vectors, nvec); 55 + return -ENODEV; 56 + } 57 + static inline void xen_pci_frontend_disable_msix(struct pci_dev *dev) 58 + { 59 + if (xen_pci_frontend && xen_pci_frontend->disable_msix) 60 + xen_pci_frontend->disable_msix(dev); 61 + } 62 + #endif /* CONFIG_PCI_XEN */ 63 + #endif /* CONFIG_PCI_MSI */ 64 + 65 + #endif /* _ASM_X86_XEN_PCI_H */
+43 -17
arch/x86/kernel/acpi/boot.c
··· 513 513 return 0; 514 514 } 515 515 516 + static int acpi_register_gsi_pic(struct device *dev, u32 gsi, 517 + int trigger, int polarity) 518 + { 519 + #ifdef CONFIG_PCI 520 + /* 521 + * Make sure all (legacy) PCI IRQs are set as level-triggered. 522 + */ 523 + if (trigger == ACPI_LEVEL_SENSITIVE) 524 + eisa_set_level_irq(gsi); 525 + #endif 526 + 527 + return gsi; 528 + } 529 + 530 + static int acpi_register_gsi_ioapic(struct device *dev, u32 gsi, 531 + int trigger, int polarity) 532 + { 533 + #ifdef CONFIG_X86_IO_APIC 534 + gsi = mp_register_gsi(dev, gsi, trigger, polarity); 535 + #endif 536 + 537 + return gsi; 538 + } 539 + 540 + int (*__acpi_register_gsi)(struct device *dev, u32 gsi, 541 + int trigger, int polarity) = acpi_register_gsi_pic; 542 + 516 543 /* 517 544 * success: return IRQ number (>=0) 518 545 * failure: return < 0 ··· 549 522 unsigned int irq; 550 523 unsigned int plat_gsi = gsi; 551 524 552 - #ifdef CONFIG_PCI 553 - /* 554 - * Make sure all (legacy) PCI IRQs are set as level-triggered. 555 - */ 556 - if (acpi_irq_model == ACPI_IRQ_MODEL_PIC) { 557 - if (trigger == ACPI_LEVEL_SENSITIVE) 558 - eisa_set_level_irq(gsi); 559 - } 560 - #endif 561 - 562 - #ifdef CONFIG_X86_IO_APIC 563 - if (acpi_irq_model == ACPI_IRQ_MODEL_IOAPIC) { 564 - plat_gsi = mp_register_gsi(dev, gsi, trigger, polarity); 565 - } 566 - #endif 525 + plat_gsi = (*__acpi_register_gsi)(dev, gsi, trigger, polarity); 567 526 irq = gsi_to_irq(plat_gsi); 568 527 569 528 return irq; 529 + } 530 + 531 + void __init acpi_set_irq_model_pic(void) 532 + { 533 + acpi_irq_model = ACPI_IRQ_MODEL_PIC; 534 + __acpi_register_gsi = acpi_register_gsi_pic; 535 + acpi_ioapic = 0; 536 + } 537 + 538 + void __init acpi_set_irq_model_ioapic(void) 539 + { 540 + acpi_irq_model = ACPI_IRQ_MODEL_IOAPIC; 541 + __acpi_register_gsi = acpi_register_gsi_ioapic; 542 + acpi_ioapic = 1; 570 543 } 571 544 572 545 /* ··· 1286 1259 */ 1287 1260 error = acpi_parse_madt_ioapic_entries(); 1288 1261 if (!error) { 1289 - acpi_irq_model = ACPI_IRQ_MODEL_IOAPIC; 1290 - acpi_ioapic = 1; 1262 + acpi_set_irq_model_ioapic(); 1291 1263 1292 1264 smp_found_config = 1; 1293 1265 }
+7 -2
arch/x86/kernel/apic/io_apic.c
··· 3331 3331 return 0; 3332 3332 } 3333 3333 3334 - int arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type) 3334 + int native_setup_msi_irqs(struct pci_dev *dev, int nvec, int type) 3335 3335 { 3336 3336 int node, ret, sub_handle, index = 0; 3337 3337 unsigned int irq, irq_want; ··· 3389 3389 return ret; 3390 3390 } 3391 3391 3392 - void arch_teardown_msi_irq(unsigned int irq) 3392 + void native_teardown_msi_irq(unsigned int irq) 3393 3393 { 3394 3394 destroy_irq(irq); 3395 3395 } ··· 3648 3648 nr_irqs_gsi = nr; 3649 3649 3650 3650 printk(KERN_DEBUG "nr_irqs_gsi: %d\n", nr_irqs_gsi); 3651 + } 3652 + 3653 + int get_nr_irqs_gsi(void) 3654 + { 3655 + return nr_irqs_gsi; 3651 3656 } 3652 3657 3653 3658 #ifdef CONFIG_SPARSE_IRQ
+7
arch/x86/kernel/x86_init.c
··· 6 6 #include <linux/init.h> 7 7 #include <linux/ioport.h> 8 8 #include <linux/module.h> 9 + #include <linux/pci.h> 9 10 10 11 #include <asm/bios_ebda.h> 11 12 #include <asm/paravirt.h> 12 13 #include <asm/pci_x86.h> 14 + #include <asm/pci.h> 13 15 #include <asm/mpspec.h> 14 16 #include <asm/setup.h> 15 17 #include <asm/apic.h> ··· 101 99 }; 102 100 103 101 EXPORT_SYMBOL_GPL(x86_platform); 102 + struct x86_msi_ops x86_msi = { 103 + .setup_msi_irqs = native_setup_msi_irqs, 104 + .teardown_msi_irq = native_teardown_msi_irq, 105 + .teardown_msi_irqs = default_teardown_msi_irqs, 106 + };
+1
arch/x86/pci/Makefile
··· 4 4 obj-$(CONFIG_PCI_MMCONFIG) += mmconfig_$(BITS).o direct.o mmconfig-shared.o 5 5 obj-$(CONFIG_PCI_DIRECT) += direct.o 6 6 obj-$(CONFIG_PCI_OLPC) += olpc.o 7 + obj-$(CONFIG_PCI_XEN) += xen.o 7 8 8 9 obj-y += fixup.o 9 10 obj-$(CONFIG_ACPI) += acpi.o
+10 -7
arch/x86/pci/common.c
··· 421 421 422 422 return bus; 423 423 } 424 - 425 - int __init pcibios_init(void) 424 + void __init pcibios_set_cache_line_size(void) 426 425 { 427 426 struct cpuinfo_x86 *c = &boot_cpu_data; 428 - 429 - if (!raw_pci_ops) { 430 - printk(KERN_WARNING "PCI: System does not support PCI\n"); 431 - return 0; 432 - } 433 427 434 428 /* 435 429 * Set PCI cacheline size to that of the CPU if the CPU has reported it. ··· 439 445 pci_dfl_cache_line_size = 32 >> 2; 440 446 printk(KERN_DEBUG "PCI: Unknown cacheline size. Setting to 32 bytes\n"); 441 447 } 448 + } 442 449 450 + int __init pcibios_init(void) 451 + { 452 + if (!raw_pci_ops) { 453 + printk(KERN_WARNING "PCI: System does not support PCI\n"); 454 + return 0; 455 + } 456 + 457 + pcibios_set_cache_line_size(); 443 458 pcibios_resource_survey(); 444 459 445 460 if (pci_bf_sort >= pci_force_bf)
+2
arch/x86/pci/i386.c
··· 316 316 */ 317 317 prot |= _PAGE_CACHE_UC_MINUS; 318 318 319 + prot |= _PAGE_IOMAP; /* creating a mapping for IO */ 320 + 319 321 vma->vm_page_prot = __pgprot(prot); 320 322 321 323 if (io_remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff,
+414
arch/x86/pci/xen.c
··· 1 + /* 2 + * Xen PCI Frontend Stub - puts some "dummy" functions in to the Linux 3 + * x86 PCI core to support the Xen PCI Frontend 4 + * 5 + * Author: Ryan Wilson <hap9@epoch.ncsc.mil> 6 + */ 7 + #include <linux/module.h> 8 + #include <linux/init.h> 9 + #include <linux/pci.h> 10 + #include <linux/acpi.h> 11 + 12 + #include <linux/io.h> 13 + #include <asm/io_apic.h> 14 + #include <asm/pci_x86.h> 15 + 16 + #include <asm/xen/hypervisor.h> 17 + 18 + #include <xen/features.h> 19 + #include <xen/events.h> 20 + #include <asm/xen/pci.h> 21 + 22 + #ifdef CONFIG_ACPI 23 + static int xen_hvm_register_pirq(u32 gsi, int triggering) 24 + { 25 + int rc, irq; 26 + struct physdev_map_pirq map_irq; 27 + int shareable = 0; 28 + char *name; 29 + 30 + if (!xen_hvm_domain()) 31 + return -1; 32 + 33 + map_irq.domid = DOMID_SELF; 34 + map_irq.type = MAP_PIRQ_TYPE_GSI; 35 + map_irq.index = gsi; 36 + map_irq.pirq = -1; 37 + 38 + rc = HYPERVISOR_physdev_op(PHYSDEVOP_map_pirq, &map_irq); 39 + if (rc) { 40 + printk(KERN_WARNING "xen map irq failed %d\n", rc); 41 + return -1; 42 + } 43 + 44 + if (triggering == ACPI_EDGE_SENSITIVE) { 45 + shareable = 0; 46 + name = "ioapic-edge"; 47 + } else { 48 + shareable = 1; 49 + name = "ioapic-level"; 50 + } 51 + 52 + irq = xen_map_pirq_gsi(map_irq.pirq, gsi, shareable, name); 53 + 54 + printk(KERN_DEBUG "xen: --> irq=%d, pirq=%d\n", irq, map_irq.pirq); 55 + 56 + return irq; 57 + } 58 + 59 + static int acpi_register_gsi_xen_hvm(struct device *dev, u32 gsi, 60 + int trigger, int polarity) 61 + { 62 + return xen_hvm_register_pirq(gsi, trigger); 63 + } 64 + #endif 65 + 66 + #if defined(CONFIG_PCI_MSI) 67 + #include <linux/msi.h> 68 + #include <asm/msidef.h> 69 + 70 + struct xen_pci_frontend_ops *xen_pci_frontend; 71 + EXPORT_SYMBOL_GPL(xen_pci_frontend); 72 + 73 + static void xen_msi_compose_msg(struct pci_dev *pdev, unsigned int pirq, 74 + struct msi_msg *msg) 75 + { 76 + /* We set vector == 0 to tell the hypervisor we don't care about it, 77 + * but we want a pirq setup instead. 78 + * We use the dest_id field to pass the pirq that we want. */ 79 + msg->address_hi = MSI_ADDR_BASE_HI | MSI_ADDR_EXT_DEST_ID(pirq); 80 + msg->address_lo = 81 + MSI_ADDR_BASE_LO | 82 + MSI_ADDR_DEST_MODE_PHYSICAL | 83 + MSI_ADDR_REDIRECTION_CPU | 84 + MSI_ADDR_DEST_ID(pirq); 85 + 86 + msg->data = 87 + MSI_DATA_TRIGGER_EDGE | 88 + MSI_DATA_LEVEL_ASSERT | 89 + /* delivery mode reserved */ 90 + (3 << 8) | 91 + MSI_DATA_VECTOR(0); 92 + } 93 + 94 + static int xen_hvm_setup_msi_irqs(struct pci_dev *dev, int nvec, int type) 95 + { 96 + int irq, pirq, ret = 0; 97 + struct msi_desc *msidesc; 98 + struct msi_msg msg; 99 + 100 + list_for_each_entry(msidesc, &dev->msi_list, list) { 101 + xen_allocate_pirq_msi((type == PCI_CAP_ID_MSIX) ? 102 + "msi-x" : "msi", &irq, &pirq); 103 + if (irq < 0 || pirq < 0) 104 + goto error; 105 + printk(KERN_DEBUG "xen: msi --> irq=%d, pirq=%d\n", irq, pirq); 106 + xen_msi_compose_msg(dev, pirq, &msg); 107 + ret = set_irq_msi(irq, msidesc); 108 + if (ret < 0) 109 + goto error_while; 110 + write_msi_msg(irq, &msg); 111 + } 112 + return 0; 113 + 114 + error_while: 115 + unbind_from_irqhandler(irq, NULL); 116 + error: 117 + if (ret == -ENODEV) 118 + dev_err(&dev->dev, "Xen PCI frontend has not registered" \ 119 + " MSI/MSI-X support!\n"); 120 + 121 + return ret; 122 + } 123 + 124 + /* 125 + * For MSI interrupts we have to use drivers/xen/event.s functions to 126 + * allocate an irq_desc and setup the right */ 127 + 128 + 129 + static int xen_setup_msi_irqs(struct pci_dev *dev, int nvec, int type) 130 + { 131 + int irq, ret, i; 132 + struct msi_desc *msidesc; 133 + int *v; 134 + 135 + v = kzalloc(sizeof(int) * max(1, nvec), GFP_KERNEL); 136 + if (!v) 137 + return -ENOMEM; 138 + 139 + if (type == PCI_CAP_ID_MSIX) 140 + ret = xen_pci_frontend_enable_msix(dev, &v, nvec); 141 + else 142 + ret = xen_pci_frontend_enable_msi(dev, &v); 143 + if (ret) 144 + goto error; 145 + i = 0; 146 + list_for_each_entry(msidesc, &dev->msi_list, list) { 147 + irq = xen_allocate_pirq(v[i], 0, /* not sharable */ 148 + (type == PCI_CAP_ID_MSIX) ? 149 + "pcifront-msi-x" : "pcifront-msi"); 150 + if (irq < 0) 151 + return -1; 152 + 153 + ret = set_irq_msi(irq, msidesc); 154 + if (ret) 155 + goto error_while; 156 + i++; 157 + } 158 + kfree(v); 159 + return 0; 160 + 161 + error_while: 162 + unbind_from_irqhandler(irq, NULL); 163 + error: 164 + if (ret == -ENODEV) 165 + dev_err(&dev->dev, "Xen PCI frontend has not registered" \ 166 + " MSI/MSI-X support!\n"); 167 + 168 + kfree(v); 169 + return ret; 170 + } 171 + 172 + static void xen_teardown_msi_irqs(struct pci_dev *dev) 173 + { 174 + struct msi_desc *msidesc; 175 + 176 + msidesc = list_entry(dev->msi_list.next, struct msi_desc, list); 177 + if (msidesc->msi_attrib.is_msix) 178 + xen_pci_frontend_disable_msix(dev); 179 + else 180 + xen_pci_frontend_disable_msi(dev); 181 + } 182 + 183 + static void xen_teardown_msi_irq(unsigned int irq) 184 + { 185 + xen_destroy_irq(irq); 186 + } 187 + 188 + static int xen_initdom_setup_msi_irqs(struct pci_dev *dev, int nvec, int type) 189 + { 190 + int irq, ret; 191 + struct msi_desc *msidesc; 192 + 193 + list_for_each_entry(msidesc, &dev->msi_list, list) { 194 + irq = xen_create_msi_irq(dev, msidesc, type); 195 + if (irq < 0) 196 + return -1; 197 + 198 + ret = set_irq_msi(irq, msidesc); 199 + if (ret) 200 + goto error; 201 + } 202 + return 0; 203 + 204 + error: 205 + xen_destroy_irq(irq); 206 + return ret; 207 + } 208 + #endif 209 + 210 + static int xen_pcifront_enable_irq(struct pci_dev *dev) 211 + { 212 + int rc; 213 + int share = 1; 214 + 215 + dev_info(&dev->dev, "Xen PCI enabling IRQ: %d\n", dev->irq); 216 + 217 + if (dev->irq < 0) 218 + return -EINVAL; 219 + 220 + if (dev->irq < NR_IRQS_LEGACY) 221 + share = 0; 222 + 223 + rc = xen_allocate_pirq(dev->irq, share, "pcifront"); 224 + if (rc < 0) { 225 + dev_warn(&dev->dev, "Xen PCI IRQ: %d, failed to register:%d\n", 226 + dev->irq, rc); 227 + return rc; 228 + } 229 + return 0; 230 + } 231 + 232 + int __init pci_xen_init(void) 233 + { 234 + if (!xen_pv_domain() || xen_initial_domain()) 235 + return -ENODEV; 236 + 237 + printk(KERN_INFO "PCI: setting up Xen PCI frontend stub\n"); 238 + 239 + pcibios_set_cache_line_size(); 240 + 241 + pcibios_enable_irq = xen_pcifront_enable_irq; 242 + pcibios_disable_irq = NULL; 243 + 244 + #ifdef CONFIG_ACPI 245 + /* Keep ACPI out of the picture */ 246 + acpi_noirq = 1; 247 + #endif 248 + 249 + #ifdef CONFIG_PCI_MSI 250 + x86_msi.setup_msi_irqs = xen_setup_msi_irqs; 251 + x86_msi.teardown_msi_irq = xen_teardown_msi_irq; 252 + x86_msi.teardown_msi_irqs = xen_teardown_msi_irqs; 253 + #endif 254 + return 0; 255 + } 256 + 257 + int __init pci_xen_hvm_init(void) 258 + { 259 + if (!xen_feature(XENFEAT_hvm_pirqs)) 260 + return 0; 261 + 262 + #ifdef CONFIG_ACPI 263 + /* 264 + * We don't want to change the actual ACPI delivery model, 265 + * just how GSIs get registered. 266 + */ 267 + __acpi_register_gsi = acpi_register_gsi_xen_hvm; 268 + #endif 269 + 270 + #ifdef CONFIG_PCI_MSI 271 + x86_msi.setup_msi_irqs = xen_hvm_setup_msi_irqs; 272 + x86_msi.teardown_msi_irq = xen_teardown_msi_irq; 273 + #endif 274 + return 0; 275 + } 276 + 277 + #ifdef CONFIG_XEN_DOM0 278 + static int xen_register_pirq(u32 gsi, int triggering) 279 + { 280 + int rc, irq; 281 + struct physdev_map_pirq map_irq; 282 + int shareable = 0; 283 + char *name; 284 + 285 + if (!xen_pv_domain()) 286 + return -1; 287 + 288 + if (triggering == ACPI_EDGE_SENSITIVE) { 289 + shareable = 0; 290 + name = "ioapic-edge"; 291 + } else { 292 + shareable = 1; 293 + name = "ioapic-level"; 294 + } 295 + 296 + irq = xen_allocate_pirq(gsi, shareable, name); 297 + 298 + printk(KERN_DEBUG "xen: --> irq=%d\n", irq); 299 + 300 + if (irq < 0) 301 + goto out; 302 + 303 + map_irq.domid = DOMID_SELF; 304 + map_irq.type = MAP_PIRQ_TYPE_GSI; 305 + map_irq.index = gsi; 306 + map_irq.pirq = irq; 307 + 308 + rc = HYPERVISOR_physdev_op(PHYSDEVOP_map_pirq, &map_irq); 309 + if (rc) { 310 + printk(KERN_WARNING "xen map irq failed %d\n", rc); 311 + return -1; 312 + } 313 + 314 + out: 315 + return irq; 316 + } 317 + 318 + static int xen_register_gsi(u32 gsi, int triggering, int polarity) 319 + { 320 + int rc, irq; 321 + struct physdev_setup_gsi setup_gsi; 322 + 323 + if (!xen_pv_domain()) 324 + return -1; 325 + 326 + printk(KERN_DEBUG "xen: registering gsi %u triggering %d polarity %d\n", 327 + gsi, triggering, polarity); 328 + 329 + irq = xen_register_pirq(gsi, triggering); 330 + 331 + setup_gsi.gsi = gsi; 332 + setup_gsi.triggering = (triggering == ACPI_EDGE_SENSITIVE ? 0 : 1); 333 + setup_gsi.polarity = (polarity == ACPI_ACTIVE_HIGH ? 0 : 1); 334 + 335 + rc = HYPERVISOR_physdev_op(PHYSDEVOP_setup_gsi, &setup_gsi); 336 + if (rc == -EEXIST) 337 + printk(KERN_INFO "Already setup the GSI :%d\n", gsi); 338 + else if (rc) { 339 + printk(KERN_ERR "Failed to setup GSI :%d, err_code:%d\n", 340 + gsi, rc); 341 + } 342 + 343 + return irq; 344 + } 345 + 346 + static __init void xen_setup_acpi_sci(void) 347 + { 348 + int rc; 349 + int trigger, polarity; 350 + int gsi = acpi_sci_override_gsi; 351 + 352 + if (!gsi) 353 + return; 354 + 355 + rc = acpi_get_override_irq(gsi, &trigger, &polarity); 356 + if (rc) { 357 + printk(KERN_WARNING "xen: acpi_get_override_irq failed for acpi" 358 + " sci, rc=%d\n", rc); 359 + return; 360 + } 361 + trigger = trigger ? ACPI_LEVEL_SENSITIVE : ACPI_EDGE_SENSITIVE; 362 + polarity = polarity ? ACPI_ACTIVE_LOW : ACPI_ACTIVE_HIGH; 363 + 364 + printk(KERN_INFO "xen: sci override: global_irq=%d trigger=%d " 365 + "polarity=%d\n", gsi, trigger, polarity); 366 + 367 + gsi = xen_register_gsi(gsi, trigger, polarity); 368 + printk(KERN_INFO "xen: acpi sci %d\n", gsi); 369 + 370 + return; 371 + } 372 + 373 + static int acpi_register_gsi_xen(struct device *dev, u32 gsi, 374 + int trigger, int polarity) 375 + { 376 + return xen_register_gsi(gsi, trigger, polarity); 377 + } 378 + 379 + static int __init pci_xen_initial_domain(void) 380 + { 381 + #ifdef CONFIG_PCI_MSI 382 + x86_msi.setup_msi_irqs = xen_initdom_setup_msi_irqs; 383 + x86_msi.teardown_msi_irq = xen_teardown_msi_irq; 384 + #endif 385 + xen_setup_acpi_sci(); 386 + __acpi_register_gsi = acpi_register_gsi_xen; 387 + 388 + return 0; 389 + } 390 + 391 + void __init xen_setup_pirqs(void) 392 + { 393 + int irq; 394 + 395 + pci_xen_initial_domain(); 396 + 397 + if (0 == nr_ioapics) { 398 + for (irq = 0; irq < NR_IRQS_LEGACY; irq++) 399 + xen_allocate_pirq(irq, 0, "xt-pic"); 400 + return; 401 + } 402 + 403 + /* Pre-allocate legacy irqs */ 404 + for (irq = 0; irq < NR_IRQS_LEGACY; irq++) { 405 + int trigger, polarity; 406 + 407 + if (acpi_get_override_irq(irq, &trigger, &polarity) == -1) 408 + continue; 409 + 410 + xen_register_pirq(irq, 411 + trigger ? ACPI_LEVEL_SENSITIVE : ACPI_EDGE_SENSITIVE); 412 + } 413 + } 414 + #endif
+10
arch/x86/xen/Kconfig
··· 13 13 kernel to boot in a paravirtualized environment under the 14 14 Xen hypervisor. 15 15 16 + config XEN_DOM0 17 + def_bool y 18 + depends on XEN && PCI_XEN && SWIOTLB_XEN 19 + depends on X86_LOCAL_APIC && X86_IO_APIC && ACPI && PCI 20 + 21 + # Dummy symbol since people have come to rely on the PRIVILEGED_GUEST 22 + # name in tools. 23 + config XEN_PRIVILEGED_GUEST 24 + def_bool XEN_DOM0 25 + 16 26 config XEN_PVHVM 17 27 def_bool y 18 28 depends on XEN
+5
arch/x86/xen/enlighten.c
··· 46 46 #include <asm/paravirt.h> 47 47 #include <asm/apic.h> 48 48 #include <asm/page.h> 49 + #include <asm/xen/pci.h> 49 50 #include <asm/xen/hypercall.h> 50 51 #include <asm/xen/hypervisor.h> 51 52 #include <asm/fixmap.h> ··· 237 236 cpuid_leaf1_edx_mask = 238 237 ~((1 << X86_FEATURE_MCE) | /* disable MCE */ 239 238 (1 << X86_FEATURE_MCA) | /* disable MCA */ 239 + (1 << X86_FEATURE_MTRR) | /* disable MTRR */ 240 240 (1 << X86_FEATURE_ACC)); /* thermal monitoring */ 241 241 242 242 if (!xen_initial_domain()) ··· 1186 1184 1187 1185 xen_raw_console_write("mapping kernel into physical memory\n"); 1188 1186 pgd = xen_setup_kernel_pagetable(pgd, xen_start_info->nr_pages); 1187 + xen_ident_map_ISA(); 1189 1188 1190 1189 /* Allocate and initialize top and mid mfn levels for p2m structure */ 1191 1190 xen_build_mfn_list_list(); ··· 1225 1222 add_preferred_console("xenboot", 0, NULL); 1226 1223 add_preferred_console("tty", 0, NULL); 1227 1224 add_preferred_console("hvc", 0, NULL); 1225 + if (pci_xen) 1226 + x86_init.pci.arch_init = pci_xen_init; 1228 1227 } else { 1229 1228 /* Make sure ACS will be enabled */ 1230 1229 pci_request_acs();
+44 -3
arch/x86/xen/mmu.c
··· 1975 1975 return __ka(m2p(maddr)); 1976 1976 } 1977 1977 1978 + /* Set the page permissions on an identity-mapped pages */ 1978 1979 static void set_page_prot(void *addr, pgprot_t prot) 1979 1980 { 1980 1981 unsigned long pfn = __pa(addr) >> PAGE_SHIFT; ··· 2160 2159 } 2161 2160 #endif /* CONFIG_X86_64 */ 2162 2161 2162 + static unsigned char dummy_mapping[PAGE_SIZE] __page_aligned_bss; 2163 + 2163 2164 static void xen_set_fixmap(unsigned idx, phys_addr_t phys, pgprot_t prot) 2164 2165 { 2165 2166 pte_t pte; ··· 2182 2179 #else 2183 2180 case VSYSCALL_LAST_PAGE ... VSYSCALL_FIRST_PAGE: 2184 2181 #endif 2185 - #ifdef CONFIG_X86_LOCAL_APIC 2186 - case FIX_APIC_BASE: /* maps dummy local APIC */ 2187 - #endif 2188 2182 case FIX_TEXT_POKE0: 2189 2183 case FIX_TEXT_POKE1: 2190 2184 /* All local page mappings */ 2191 2185 pte = pfn_pte(phys, prot); 2192 2186 break; 2187 + 2188 + #ifdef CONFIG_X86_LOCAL_APIC 2189 + case FIX_APIC_BASE: /* maps dummy local APIC */ 2190 + pte = pfn_pte(PFN_DOWN(__pa(dummy_mapping)), PAGE_KERNEL); 2191 + break; 2192 + #endif 2193 + 2194 + #ifdef CONFIG_X86_IO_APIC 2195 + case FIX_IO_APIC_BASE_0 ... FIX_IO_APIC_BASE_END: 2196 + /* 2197 + * We just don't map the IO APIC - all access is via 2198 + * hypercalls. Keep the address in the pte for reference. 2199 + */ 2200 + pte = pfn_pte(PFN_DOWN(__pa(dummy_mapping)), PAGE_KERNEL); 2201 + break; 2202 + #endif 2193 2203 2194 2204 case FIX_PARAVIRT_BOOTMAP: 2195 2205 /* This is an MFN, but it isn't an IO mapping from the ··· 2226 2210 set_pte_vaddr_pud(level3_user_vsyscall, vaddr, pte); 2227 2211 } 2228 2212 #endif 2213 + } 2214 + 2215 + __init void xen_ident_map_ISA(void) 2216 + { 2217 + unsigned long pa; 2218 + 2219 + /* 2220 + * If we're dom0, then linear map the ISA machine addresses into 2221 + * the kernel's address space. 2222 + */ 2223 + if (!xen_initial_domain()) 2224 + return; 2225 + 2226 + xen_raw_printk("Xen: setup ISA identity maps\n"); 2227 + 2228 + for (pa = ISA_START_ADDRESS; pa < ISA_END_ADDRESS; pa += PAGE_SIZE) { 2229 + pte_t pte = mfn_pte(PFN_DOWN(pa), PAGE_KERNEL_IO); 2230 + 2231 + if (HYPERVISOR_update_va_mapping(PAGE_OFFSET + pa, pte, 0)) 2232 + BUG(); 2233 + } 2234 + 2235 + xen_flush_tlb(); 2229 2236 } 2230 2237 2231 2238 static __init void xen_post_allocator_init(void) ··· 2359 2320 pv_mmu_ops = xen_mmu_ops; 2360 2321 2361 2322 vmap_lazy_unmap = false; 2323 + 2324 + memset(dummy_mapping, 0xff, PAGE_SIZE); 2362 2325 } 2363 2326 2364 2327 /* Protected by xen_reservation_lock. */
+4
arch/x86/xen/pci-swiotlb-xen.c
··· 1 1 /* Glue code to lib/swiotlb-xen.c */ 2 2 3 3 #include <linux/dma-mapping.h> 4 + #include <linux/pci.h> 4 5 #include <xen/swiotlb-xen.h> 5 6 6 7 #include <asm/xen/hypervisor.h> ··· 56 55 if (xen_swiotlb) { 57 56 xen_swiotlb_init(1); 58 57 dma_ops = &xen_swiotlb_dma_ops; 58 + 59 + /* Make sure ACS will be enabled */ 60 + pci_request_acs(); 59 61 } 60 62 } 61 63 IOMMU_INIT_FINISH(pci_xen_swiotlb_detect,
+3 -2
arch/x86/xen/setup.c
··· 204 204 * Even though this is normal, usable memory under Xen, reserve 205 205 * ISA memory anyway because too many things think they can poke 206 206 * about in there. 207 + * 208 + * In a dom0 kernel, this region is identity mapped with the 209 + * hardware ISA area, so it really is out of bounds. 207 210 */ 208 211 e820_add_region(ISA_START_ADDRESS, ISA_END_ADDRESS - ISA_START_ADDRESS, 209 212 E820_RESERVED); ··· 369 366 COMMAND_LINE_SIZE : MAX_GUEST_CMDLINE); 370 367 371 368 pm_idle = xen_idle; 372 - 373 - paravirt_disable_iospace(); 374 369 375 370 fiddle_vdso(); 376 371 }
+26
arch/x86/xen/smp.c
··· 28 28 #include <asm/xen/interface.h> 29 29 #include <asm/xen/hypercall.h> 30 30 31 + #include <xen/xen.h> 31 32 #include <xen/page.h> 32 33 #include <xen/events.h> 33 34 ··· 157 156 { 158 157 int i, rc; 159 158 159 + if (xen_initial_domain()) 160 + return; 161 + 160 162 for (i = 0; i < nr_cpu_ids; i++) { 161 163 rc = HYPERVISOR_vcpu_op(VCPUOP_is_up, i, NULL); 162 164 if (rc >= 0) { 163 165 num_processors++; 164 166 set_cpu_possible(i, true); 167 + } 168 + } 169 + } 170 + 171 + static void __init xen_filter_cpu_maps(void) 172 + { 173 + int i, rc; 174 + 175 + if (!xen_initial_domain()) 176 + return; 177 + 178 + num_processors = 0; 179 + disabled_cpus = 0; 180 + for (i = 0; i < nr_cpu_ids; i++) { 181 + rc = HYPERVISOR_vcpu_op(VCPUOP_is_up, i, NULL); 182 + if (rc >= 0) { 183 + num_processors++; 184 + set_cpu_possible(i, true); 185 + } else { 186 + set_cpu_possible(i, false); 187 + set_cpu_present(i, false); 165 188 } 166 189 } 167 190 } ··· 199 174 old memory can be recycled */ 200 175 make_lowmem_page_readwrite(xen_initial_gdt); 201 176 177 + xen_filter_cpu_maps(); 202 178 xen_setup_vcpu_info_placement(); 203 179 } 204 180
+2
drivers/block/xen-blkfront.c
··· 1112 1112 case XenbusStateInitialising: 1113 1113 case XenbusStateInitWait: 1114 1114 case XenbusStateInitialised: 1115 + case XenbusStateReconfiguring: 1116 + case XenbusStateReconfigured: 1115 1117 case XenbusStateUnknown: 1116 1118 case XenbusStateClosed: 1117 1119 break;
+65 -33
drivers/char/hvc_xen.c
··· 79 79 return sent; 80 80 } 81 81 82 - static int write_console(uint32_t vtermno, const char *data, int len) 82 + static int domU_write_console(uint32_t vtermno, const char *data, int len) 83 83 { 84 84 int ret = len; 85 85 ··· 102 102 return ret; 103 103 } 104 104 105 - static int read_console(uint32_t vtermno, char *buf, int len) 105 + static int domU_read_console(uint32_t vtermno, char *buf, int len) 106 106 { 107 107 struct xencons_interface *intf = xencons_interface(); 108 108 XENCONS_RING_IDX cons, prod; ··· 123 123 return recv; 124 124 } 125 125 126 - static const struct hv_ops hvc_ops = { 127 - .get_chars = read_console, 128 - .put_chars = write_console, 126 + static struct hv_ops domU_hvc_ops = { 127 + .get_chars = domU_read_console, 128 + .put_chars = domU_write_console, 129 129 .notifier_add = notifier_add_irq, 130 130 .notifier_del = notifier_del_irq, 131 131 .notifier_hangup = notifier_hangup_irq, 132 132 }; 133 133 134 - static int __init xen_init(void) 134 + static int dom0_read_console(uint32_t vtermno, char *buf, int len) 135 + { 136 + return HYPERVISOR_console_io(CONSOLEIO_read, len, buf); 137 + } 138 + 139 + /* 140 + * Either for a dom0 to write to the system console, or a domU with a 141 + * debug version of Xen 142 + */ 143 + static int dom0_write_console(uint32_t vtermno, const char *str, int len) 144 + { 145 + int rc = HYPERVISOR_console_io(CONSOLEIO_write, len, (char *)str); 146 + if (rc < 0) 147 + return 0; 148 + 149 + return len; 150 + } 151 + 152 + static struct hv_ops dom0_hvc_ops = { 153 + .get_chars = dom0_read_console, 154 + .put_chars = dom0_write_console, 155 + .notifier_add = notifier_add_irq, 156 + .notifier_del = notifier_del_irq, 157 + .notifier_hangup = notifier_hangup_irq, 158 + }; 159 + 160 + static int __init xen_hvc_init(void) 135 161 { 136 162 struct hvc_struct *hp; 163 + struct hv_ops *ops; 137 164 138 - if (!xen_pv_domain() || 139 - xen_initial_domain() || 140 - !xen_start_info->console.domU.evtchn) 165 + if (!xen_pv_domain()) 141 166 return -ENODEV; 142 167 143 - xencons_irq = bind_evtchn_to_irq(xen_start_info->console.domU.evtchn); 168 + if (xen_initial_domain()) { 169 + ops = &dom0_hvc_ops; 170 + xencons_irq = bind_virq_to_irq(VIRQ_CONSOLE, 0); 171 + } else { 172 + if (!xen_start_info->console.domU.evtchn) 173 + return -ENODEV; 174 + 175 + ops = &domU_hvc_ops; 176 + xencons_irq = bind_evtchn_to_irq(xen_start_info->console.domU.evtchn); 177 + } 144 178 if (xencons_irq < 0) 145 179 xencons_irq = 0; /* NO_IRQ */ 146 180 147 - hp = hvc_alloc(HVC_COOKIE, xencons_irq, &hvc_ops, 256); 181 + hp = hvc_alloc(HVC_COOKIE, xencons_irq, ops, 256); 148 182 if (IS_ERR(hp)) 149 183 return PTR_ERR(hp); 150 184 ··· 195 161 rebind_evtchn_irq(xen_start_info->console.domU.evtchn, xencons_irq); 196 162 } 197 163 198 - static void __exit xen_fini(void) 164 + static void __exit xen_hvc_fini(void) 199 165 { 200 166 if (hvc) 201 167 hvc_remove(hvc); ··· 203 169 204 170 static int xen_cons_init(void) 205 171 { 172 + struct hv_ops *ops; 173 + 206 174 if (!xen_pv_domain()) 207 175 return 0; 208 176 209 - hvc_instantiate(HVC_COOKIE, 0, &hvc_ops); 177 + if (xen_initial_domain()) 178 + ops = &dom0_hvc_ops; 179 + else 180 + ops = &domU_hvc_ops; 181 + 182 + hvc_instantiate(HVC_COOKIE, 0, ops); 210 183 return 0; 211 184 } 212 185 213 - module_init(xen_init); 214 - module_exit(xen_fini); 186 + module_init(xen_hvc_init); 187 + module_exit(xen_hvc_fini); 215 188 console_initcall(xen_cons_init); 216 - 217 - static void raw_console_write(const char *str, int len) 218 - { 219 - while(len > 0) { 220 - int rc = HYPERVISOR_console_io(CONSOLEIO_write, len, (char *)str); 221 - if (rc <= 0) 222 - break; 223 - 224 - str += rc; 225 - len -= rc; 226 - } 227 - } 228 189 229 190 #ifdef CONFIG_EARLY_PRINTK 230 191 static void xenboot_write_console(struct console *console, const char *string, ··· 228 199 unsigned int linelen, off = 0; 229 200 const char *pos; 230 201 231 - raw_console_write(string, len); 202 + dom0_write_console(0, string, len); 232 203 233 - write_console(0, "(early) ", 8); 204 + if (xen_initial_domain()) 205 + return; 206 + 207 + domU_write_console(0, "(early) ", 8); 234 208 while (off < len && NULL != (pos = strchr(string+off, '\n'))) { 235 209 linelen = pos-string+off; 236 210 if (off + linelen > len) 237 211 break; 238 - write_console(0, string+off, linelen); 239 - write_console(0, "\r\n", 2); 212 + domU_write_console(0, string+off, linelen); 213 + domU_write_console(0, "\r\n", 2); 240 214 off += linelen + 1; 241 215 } 242 216 if (off < len) 243 - write_console(0, string+off, len-off); 217 + domU_write_console(0, string+off, len-off); 244 218 } 245 219 246 220 struct console xenboot_console = { ··· 255 223 256 224 void xen_raw_console_write(const char *str) 257 225 { 258 - raw_console_write(str, strlen(str)); 226 + dom0_write_console(0, str, strlen(str)); 259 227 } 260 228 261 229 void xen_raw_printk(const char *fmt, ...)
+2
drivers/input/xen-kbdfront.c
··· 276 276 switch (backend_state) { 277 277 case XenbusStateInitialising: 278 278 case XenbusStateInitialised: 279 + case XenbusStateReconfiguring: 280 + case XenbusStateReconfigured: 279 281 case XenbusStateUnknown: 280 282 case XenbusStateClosed: 281 283 break;
+2
drivers/net/xen-netfront.c
··· 1610 1610 switch (backend_state) { 1611 1611 case XenbusStateInitialising: 1612 1612 case XenbusStateInitialised: 1613 + case XenbusStateReconfiguring: 1614 + case XenbusStateReconfigured: 1613 1615 case XenbusStateConnected: 1614 1616 case XenbusStateUnknown: 1615 1617 case XenbusStateClosed:
+21
drivers/pci/Kconfig
··· 40 40 41 41 When in doubt, say N. 42 42 43 + config XEN_PCIDEV_FRONTEND 44 + tristate "Xen PCI Frontend" 45 + depends on PCI && X86 && XEN 46 + select HOTPLUG 47 + select PCI_XEN 48 + default y 49 + help 50 + The PCI device frontend driver allows the kernel to import arbitrary 51 + PCI devices from a PCI backend to support PCI driver domains. 52 + 53 + config XEN_PCIDEV_FE_DEBUG 54 + bool "Xen PCI Frontend debugging" 55 + depends on XEN_PCIDEV_FRONTEND && PCI_DEBUG 56 + help 57 + Say Y here if you want the Xen PCI frontend to produce a bunch of debug 58 + messages to the system log. Select this if you are having a 59 + problem with Xen PCI frontend support and want to see more of what is 60 + going on. 61 + 62 + When in doubt, say N. 63 + 43 64 config HT_IRQ 44 65 bool "Interrupts on hypertransport devices" 45 66 default y
+2
drivers/pci/Makefile
··· 65 65 66 66 obj-$(CONFIG_PCI_STUB) += pci-stub.o 67 67 68 + obj-$(CONFIG_XEN_PCIDEV_FRONTEND) += xen-pcifront.o 69 + 68 70 ccflags-$(CONFIG_PCI_DEBUG) := -DDEBUG
+1
drivers/pci/bus.c
··· 342 342 } 343 343 up_read(&pci_bus_sem); 344 344 } 345 + EXPORT_SYMBOL_GPL(pci_walk_bus); 345 346 346 347 EXPORT_SYMBOL(pci_bus_alloc_resource); 347 348 EXPORT_SYMBOL_GPL(pci_bus_add_device);
+12 -2
drivers/pci/msi.c
··· 35 35 #endif 36 36 37 37 #ifndef arch_setup_msi_irqs 38 - int arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type) 38 + # define arch_setup_msi_irqs default_setup_msi_irqs 39 + # define HAVE_DEFAULT_MSI_SETUP_IRQS 40 + #endif 41 + 42 + #ifdef HAVE_DEFAULT_MSI_SETUP_IRQS 43 + int default_setup_msi_irqs(struct pci_dev *dev, int nvec, int type) 39 44 { 40 45 struct msi_desc *entry; 41 46 int ret; ··· 65 60 #endif 66 61 67 62 #ifndef arch_teardown_msi_irqs 68 - void arch_teardown_msi_irqs(struct pci_dev *dev) 63 + # define arch_teardown_msi_irqs default_teardown_msi_irqs 64 + # define HAVE_DEFAULT_MSI_TEARDOWN_IRQS 65 + #endif 66 + 67 + #ifdef HAVE_DEFAULT_MSI_TEARDOWN_IRQS 68 + void default_teardown_msi_irqs(struct pci_dev *dev) 69 69 { 70 70 struct msi_desc *entry; 71 71
+1148
drivers/pci/xen-pcifront.c
··· 1 + /* 2 + * Xen PCI Frontend. 3 + * 4 + * Author: Ryan Wilson <hap9@epoch.ncsc.mil> 5 + */ 6 + #include <linux/module.h> 7 + #include <linux/init.h> 8 + #include <linux/mm.h> 9 + #include <xen/xenbus.h> 10 + #include <xen/events.h> 11 + #include <xen/grant_table.h> 12 + #include <xen/page.h> 13 + #include <linux/spinlock.h> 14 + #include <linux/pci.h> 15 + #include <linux/msi.h> 16 + #include <xen/xenbus.h> 17 + #include <xen/interface/io/pciif.h> 18 + #include <asm/xen/pci.h> 19 + #include <linux/interrupt.h> 20 + #include <asm/atomic.h> 21 + #include <linux/workqueue.h> 22 + #include <linux/bitops.h> 23 + #include <linux/time.h> 24 + 25 + #define INVALID_GRANT_REF (0) 26 + #define INVALID_EVTCHN (-1) 27 + 28 + struct pci_bus_entry { 29 + struct list_head list; 30 + struct pci_bus *bus; 31 + }; 32 + 33 + #define _PDEVB_op_active (0) 34 + #define PDEVB_op_active (1 << (_PDEVB_op_active)) 35 + 36 + struct pcifront_device { 37 + struct xenbus_device *xdev; 38 + struct list_head root_buses; 39 + 40 + int evtchn; 41 + int gnt_ref; 42 + 43 + int irq; 44 + 45 + /* Lock this when doing any operations in sh_info */ 46 + spinlock_t sh_info_lock; 47 + struct xen_pci_sharedinfo *sh_info; 48 + struct work_struct op_work; 49 + unsigned long flags; 50 + 51 + }; 52 + 53 + struct pcifront_sd { 54 + int domain; 55 + struct pcifront_device *pdev; 56 + }; 57 + 58 + static inline struct pcifront_device * 59 + pcifront_get_pdev(struct pcifront_sd *sd) 60 + { 61 + return sd->pdev; 62 + } 63 + 64 + static inline void pcifront_init_sd(struct pcifront_sd *sd, 65 + unsigned int domain, unsigned int bus, 66 + struct pcifront_device *pdev) 67 + { 68 + sd->domain = domain; 69 + sd->pdev = pdev; 70 + } 71 + 72 + static DEFINE_SPINLOCK(pcifront_dev_lock); 73 + static struct pcifront_device *pcifront_dev; 74 + 75 + static int verbose_request; 76 + module_param(verbose_request, int, 0644); 77 + 78 + static int errno_to_pcibios_err(int errno) 79 + { 80 + switch (errno) { 81 + case XEN_PCI_ERR_success: 82 + return PCIBIOS_SUCCESSFUL; 83 + 84 + case XEN_PCI_ERR_dev_not_found: 85 + return PCIBIOS_DEVICE_NOT_FOUND; 86 + 87 + case XEN_PCI_ERR_invalid_offset: 88 + case XEN_PCI_ERR_op_failed: 89 + return PCIBIOS_BAD_REGISTER_NUMBER; 90 + 91 + case XEN_PCI_ERR_not_implemented: 92 + return PCIBIOS_FUNC_NOT_SUPPORTED; 93 + 94 + case XEN_PCI_ERR_access_denied: 95 + return PCIBIOS_SET_FAILED; 96 + } 97 + return errno; 98 + } 99 + 100 + static inline void schedule_pcifront_aer_op(struct pcifront_device *pdev) 101 + { 102 + if (test_bit(_XEN_PCIB_active, (unsigned long *)&pdev->sh_info->flags) 103 + && !test_and_set_bit(_PDEVB_op_active, &pdev->flags)) { 104 + dev_dbg(&pdev->xdev->dev, "schedule aer frontend job\n"); 105 + schedule_work(&pdev->op_work); 106 + } 107 + } 108 + 109 + static int do_pci_op(struct pcifront_device *pdev, struct xen_pci_op *op) 110 + { 111 + int err = 0; 112 + struct xen_pci_op *active_op = &pdev->sh_info->op; 113 + unsigned long irq_flags; 114 + evtchn_port_t port = pdev->evtchn; 115 + unsigned irq = pdev->irq; 116 + s64 ns, ns_timeout; 117 + struct timeval tv; 118 + 119 + spin_lock_irqsave(&pdev->sh_info_lock, irq_flags); 120 + 121 + memcpy(active_op, op, sizeof(struct xen_pci_op)); 122 + 123 + /* Go */ 124 + wmb(); 125 + set_bit(_XEN_PCIF_active, (unsigned long *)&pdev->sh_info->flags); 126 + notify_remote_via_evtchn(port); 127 + 128 + /* 129 + * We set a poll timeout of 3 seconds but give up on return after 130 + * 2 seconds. It is better to time out too late rather than too early 131 + * (in the latter case we end up continually re-executing poll() with a 132 + * timeout in the past). 1s difference gives plenty of slack for error. 133 + */ 134 + do_gettimeofday(&tv); 135 + ns_timeout = timeval_to_ns(&tv) + 2 * (s64)NSEC_PER_SEC; 136 + 137 + xen_clear_irq_pending(irq); 138 + 139 + while (test_bit(_XEN_PCIF_active, 140 + (unsigned long *)&pdev->sh_info->flags)) { 141 + xen_poll_irq_timeout(irq, jiffies + 3*HZ); 142 + xen_clear_irq_pending(irq); 143 + do_gettimeofday(&tv); 144 + ns = timeval_to_ns(&tv); 145 + if (ns > ns_timeout) { 146 + dev_err(&pdev->xdev->dev, 147 + "pciback not responding!!!\n"); 148 + clear_bit(_XEN_PCIF_active, 149 + (unsigned long *)&pdev->sh_info->flags); 150 + err = XEN_PCI_ERR_dev_not_found; 151 + goto out; 152 + } 153 + } 154 + 155 + /* 156 + * We might lose backend service request since we 157 + * reuse same evtchn with pci_conf backend response. So re-schedule 158 + * aer pcifront service. 159 + */ 160 + if (test_bit(_XEN_PCIB_active, 161 + (unsigned long *)&pdev->sh_info->flags)) { 162 + dev_err(&pdev->xdev->dev, 163 + "schedule aer pcifront service\n"); 164 + schedule_pcifront_aer_op(pdev); 165 + } 166 + 167 + memcpy(op, active_op, sizeof(struct xen_pci_op)); 168 + 169 + err = op->err; 170 + out: 171 + spin_unlock_irqrestore(&pdev->sh_info_lock, irq_flags); 172 + return err; 173 + } 174 + 175 + /* Access to this function is spinlocked in drivers/pci/access.c */ 176 + static int pcifront_bus_read(struct pci_bus *bus, unsigned int devfn, 177 + int where, int size, u32 *val) 178 + { 179 + int err = 0; 180 + struct xen_pci_op op = { 181 + .cmd = XEN_PCI_OP_conf_read, 182 + .domain = pci_domain_nr(bus), 183 + .bus = bus->number, 184 + .devfn = devfn, 185 + .offset = where, 186 + .size = size, 187 + }; 188 + struct pcifront_sd *sd = bus->sysdata; 189 + struct pcifront_device *pdev = pcifront_get_pdev(sd); 190 + 191 + if (verbose_request) 192 + dev_info(&pdev->xdev->dev, 193 + "read dev=%04x:%02x:%02x.%01x - offset %x size %d\n", 194 + pci_domain_nr(bus), bus->number, PCI_SLOT(devfn), 195 + PCI_FUNC(devfn), where, size); 196 + 197 + err = do_pci_op(pdev, &op); 198 + 199 + if (likely(!err)) { 200 + if (verbose_request) 201 + dev_info(&pdev->xdev->dev, "read got back value %x\n", 202 + op.value); 203 + 204 + *val = op.value; 205 + } else if (err == -ENODEV) { 206 + /* No device here, pretend that it just returned 0 */ 207 + err = 0; 208 + *val = 0; 209 + } 210 + 211 + return errno_to_pcibios_err(err); 212 + } 213 + 214 + /* Access to this function is spinlocked in drivers/pci/access.c */ 215 + static int pcifront_bus_write(struct pci_bus *bus, unsigned int devfn, 216 + int where, int size, u32 val) 217 + { 218 + struct xen_pci_op op = { 219 + .cmd = XEN_PCI_OP_conf_write, 220 + .domain = pci_domain_nr(bus), 221 + .bus = bus->number, 222 + .devfn = devfn, 223 + .offset = where, 224 + .size = size, 225 + .value = val, 226 + }; 227 + struct pcifront_sd *sd = bus->sysdata; 228 + struct pcifront_device *pdev = pcifront_get_pdev(sd); 229 + 230 + if (verbose_request) 231 + dev_info(&pdev->xdev->dev, 232 + "write dev=%04x:%02x:%02x.%01x - " 233 + "offset %x size %d val %x\n", 234 + pci_domain_nr(bus), bus->number, 235 + PCI_SLOT(devfn), PCI_FUNC(devfn), where, size, val); 236 + 237 + return errno_to_pcibios_err(do_pci_op(pdev, &op)); 238 + } 239 + 240 + struct pci_ops pcifront_bus_ops = { 241 + .read = pcifront_bus_read, 242 + .write = pcifront_bus_write, 243 + }; 244 + 245 + #ifdef CONFIG_PCI_MSI 246 + static int pci_frontend_enable_msix(struct pci_dev *dev, 247 + int **vector, int nvec) 248 + { 249 + int err; 250 + int i; 251 + struct xen_pci_op op = { 252 + .cmd = XEN_PCI_OP_enable_msix, 253 + .domain = pci_domain_nr(dev->bus), 254 + .bus = dev->bus->number, 255 + .devfn = dev->devfn, 256 + .value = nvec, 257 + }; 258 + struct pcifront_sd *sd = dev->bus->sysdata; 259 + struct pcifront_device *pdev = pcifront_get_pdev(sd); 260 + struct msi_desc *entry; 261 + 262 + if (nvec > SH_INFO_MAX_VEC) { 263 + dev_err(&dev->dev, "too much vector for pci frontend: %x." 264 + " Increase SH_INFO_MAX_VEC.\n", nvec); 265 + return -EINVAL; 266 + } 267 + 268 + i = 0; 269 + list_for_each_entry(entry, &dev->msi_list, list) { 270 + op.msix_entries[i].entry = entry->msi_attrib.entry_nr; 271 + /* Vector is useless at this point. */ 272 + op.msix_entries[i].vector = -1; 273 + i++; 274 + } 275 + 276 + err = do_pci_op(pdev, &op); 277 + 278 + if (likely(!err)) { 279 + if (likely(!op.value)) { 280 + /* we get the result */ 281 + for (i = 0; i < nvec; i++) 282 + *(*vector+i) = op.msix_entries[i].vector; 283 + return 0; 284 + } else { 285 + printk(KERN_DEBUG "enable msix get value %x\n", 286 + op.value); 287 + return op.value; 288 + } 289 + } else { 290 + dev_err(&dev->dev, "enable msix get err %x\n", err); 291 + return err; 292 + } 293 + } 294 + 295 + static void pci_frontend_disable_msix(struct pci_dev *dev) 296 + { 297 + int err; 298 + struct xen_pci_op op = { 299 + .cmd = XEN_PCI_OP_disable_msix, 300 + .domain = pci_domain_nr(dev->bus), 301 + .bus = dev->bus->number, 302 + .devfn = dev->devfn, 303 + }; 304 + struct pcifront_sd *sd = dev->bus->sysdata; 305 + struct pcifront_device *pdev = pcifront_get_pdev(sd); 306 + 307 + err = do_pci_op(pdev, &op); 308 + 309 + /* What should do for error ? */ 310 + if (err) 311 + dev_err(&dev->dev, "pci_disable_msix get err %x\n", err); 312 + } 313 + 314 + static int pci_frontend_enable_msi(struct pci_dev *dev, int **vector) 315 + { 316 + int err; 317 + struct xen_pci_op op = { 318 + .cmd = XEN_PCI_OP_enable_msi, 319 + .domain = pci_domain_nr(dev->bus), 320 + .bus = dev->bus->number, 321 + .devfn = dev->devfn, 322 + }; 323 + struct pcifront_sd *sd = dev->bus->sysdata; 324 + struct pcifront_device *pdev = pcifront_get_pdev(sd); 325 + 326 + err = do_pci_op(pdev, &op); 327 + if (likely(!err)) { 328 + *(*vector) = op.value; 329 + } else { 330 + dev_err(&dev->dev, "pci frontend enable msi failed for dev " 331 + "%x:%x\n", op.bus, op.devfn); 332 + err = -EINVAL; 333 + } 334 + return err; 335 + } 336 + 337 + static void pci_frontend_disable_msi(struct pci_dev *dev) 338 + { 339 + int err; 340 + struct xen_pci_op op = { 341 + .cmd = XEN_PCI_OP_disable_msi, 342 + .domain = pci_domain_nr(dev->bus), 343 + .bus = dev->bus->number, 344 + .devfn = dev->devfn, 345 + }; 346 + struct pcifront_sd *sd = dev->bus->sysdata; 347 + struct pcifront_device *pdev = pcifront_get_pdev(sd); 348 + 349 + err = do_pci_op(pdev, &op); 350 + if (err == XEN_PCI_ERR_dev_not_found) { 351 + /* XXX No response from backend, what shall we do? */ 352 + printk(KERN_DEBUG "get no response from backend for disable MSI\n"); 353 + return; 354 + } 355 + if (err) 356 + /* how can pciback notify us fail? */ 357 + printk(KERN_DEBUG "get fake response frombackend\n"); 358 + } 359 + 360 + static struct xen_pci_frontend_ops pci_frontend_ops = { 361 + .enable_msi = pci_frontend_enable_msi, 362 + .disable_msi = pci_frontend_disable_msi, 363 + .enable_msix = pci_frontend_enable_msix, 364 + .disable_msix = pci_frontend_disable_msix, 365 + }; 366 + 367 + static void pci_frontend_registrar(int enable) 368 + { 369 + if (enable) 370 + xen_pci_frontend = &pci_frontend_ops; 371 + else 372 + xen_pci_frontend = NULL; 373 + }; 374 + #else 375 + static inline void pci_frontend_registrar(int enable) { }; 376 + #endif /* CONFIG_PCI_MSI */ 377 + 378 + /* Claim resources for the PCI frontend as-is, backend won't allow changes */ 379 + static int pcifront_claim_resource(struct pci_dev *dev, void *data) 380 + { 381 + struct pcifront_device *pdev = data; 382 + int i; 383 + struct resource *r; 384 + 385 + for (i = 0; i < PCI_NUM_RESOURCES; i++) { 386 + r = &dev->resource[i]; 387 + 388 + if (!r->parent && r->start && r->flags) { 389 + dev_info(&pdev->xdev->dev, "claiming resource %s/%d\n", 390 + pci_name(dev), i); 391 + if (pci_claim_resource(dev, i)) { 392 + dev_err(&pdev->xdev->dev, "Could not claim " 393 + "resource %s/%d! Device offline. Try " 394 + "giving less than 4GB to domain.\n", 395 + pci_name(dev), i); 396 + } 397 + } 398 + } 399 + 400 + return 0; 401 + } 402 + 403 + static int __devinit pcifront_scan_bus(struct pcifront_device *pdev, 404 + unsigned int domain, unsigned int bus, 405 + struct pci_bus *b) 406 + { 407 + struct pci_dev *d; 408 + unsigned int devfn; 409 + 410 + /* Scan the bus for functions and add. 411 + * We omit handling of PCI bridge attachment because pciback prevents 412 + * bridges from being exported. 413 + */ 414 + for (devfn = 0; devfn < 0x100; devfn++) { 415 + d = pci_get_slot(b, devfn); 416 + if (d) { 417 + /* Device is already known. */ 418 + pci_dev_put(d); 419 + continue; 420 + } 421 + 422 + d = pci_scan_single_device(b, devfn); 423 + if (d) 424 + dev_info(&pdev->xdev->dev, "New device on " 425 + "%04x:%02x:%02x.%02x found.\n", domain, bus, 426 + PCI_SLOT(devfn), PCI_FUNC(devfn)); 427 + } 428 + 429 + return 0; 430 + } 431 + 432 + static int __devinit pcifront_scan_root(struct pcifront_device *pdev, 433 + unsigned int domain, unsigned int bus) 434 + { 435 + struct pci_bus *b; 436 + struct pcifront_sd *sd = NULL; 437 + struct pci_bus_entry *bus_entry = NULL; 438 + int err = 0; 439 + 440 + #ifndef CONFIG_PCI_DOMAINS 441 + if (domain != 0) { 442 + dev_err(&pdev->xdev->dev, 443 + "PCI Root in non-zero PCI Domain! domain=%d\n", domain); 444 + dev_err(&pdev->xdev->dev, 445 + "Please compile with CONFIG_PCI_DOMAINS\n"); 446 + err = -EINVAL; 447 + goto err_out; 448 + } 449 + #endif 450 + 451 + dev_info(&pdev->xdev->dev, "Creating PCI Frontend Bus %04x:%02x\n", 452 + domain, bus); 453 + 454 + bus_entry = kmalloc(sizeof(*bus_entry), GFP_KERNEL); 455 + sd = kmalloc(sizeof(*sd), GFP_KERNEL); 456 + if (!bus_entry || !sd) { 457 + err = -ENOMEM; 458 + goto err_out; 459 + } 460 + pcifront_init_sd(sd, domain, bus, pdev); 461 + 462 + b = pci_scan_bus_parented(&pdev->xdev->dev, bus, 463 + &pcifront_bus_ops, sd); 464 + if (!b) { 465 + dev_err(&pdev->xdev->dev, 466 + "Error creating PCI Frontend Bus!\n"); 467 + err = -ENOMEM; 468 + goto err_out; 469 + } 470 + 471 + bus_entry->bus = b; 472 + 473 + list_add(&bus_entry->list, &pdev->root_buses); 474 + 475 + /* pci_scan_bus_parented skips devices which do not have a have 476 + * devfn==0. The pcifront_scan_bus enumerates all devfn. */ 477 + err = pcifront_scan_bus(pdev, domain, bus, b); 478 + 479 + /* Claim resources before going "live" with our devices */ 480 + pci_walk_bus(b, pcifront_claim_resource, pdev); 481 + 482 + /* Create SysFS and notify udev of the devices. Aka: "going live" */ 483 + pci_bus_add_devices(b); 484 + 485 + return err; 486 + 487 + err_out: 488 + kfree(bus_entry); 489 + kfree(sd); 490 + 491 + return err; 492 + } 493 + 494 + static int __devinit pcifront_rescan_root(struct pcifront_device *pdev, 495 + unsigned int domain, unsigned int bus) 496 + { 497 + int err; 498 + struct pci_bus *b; 499 + 500 + #ifndef CONFIG_PCI_DOMAINS 501 + if (domain != 0) { 502 + dev_err(&pdev->xdev->dev, 503 + "PCI Root in non-zero PCI Domain! domain=%d\n", domain); 504 + dev_err(&pdev->xdev->dev, 505 + "Please compile with CONFIG_PCI_DOMAINS\n"); 506 + return -EINVAL; 507 + } 508 + #endif 509 + 510 + dev_info(&pdev->xdev->dev, "Rescanning PCI Frontend Bus %04x:%02x\n", 511 + domain, bus); 512 + 513 + b = pci_find_bus(domain, bus); 514 + if (!b) 515 + /* If the bus is unknown, create it. */ 516 + return pcifront_scan_root(pdev, domain, bus); 517 + 518 + err = pcifront_scan_bus(pdev, domain, bus, b); 519 + 520 + /* Claim resources before going "live" with our devices */ 521 + pci_walk_bus(b, pcifront_claim_resource, pdev); 522 + 523 + /* Create SysFS and notify udev of the devices. Aka: "going live" */ 524 + pci_bus_add_devices(b); 525 + 526 + return err; 527 + } 528 + 529 + static void free_root_bus_devs(struct pci_bus *bus) 530 + { 531 + struct pci_dev *dev; 532 + 533 + while (!list_empty(&bus->devices)) { 534 + dev = container_of(bus->devices.next, struct pci_dev, 535 + bus_list); 536 + dev_dbg(&dev->dev, "removing device\n"); 537 + pci_remove_bus_device(dev); 538 + } 539 + } 540 + 541 + static void pcifront_free_roots(struct pcifront_device *pdev) 542 + { 543 + struct pci_bus_entry *bus_entry, *t; 544 + 545 + dev_dbg(&pdev->xdev->dev, "cleaning up root buses\n"); 546 + 547 + list_for_each_entry_safe(bus_entry, t, &pdev->root_buses, list) { 548 + list_del(&bus_entry->list); 549 + 550 + free_root_bus_devs(bus_entry->bus); 551 + 552 + kfree(bus_entry->bus->sysdata); 553 + 554 + device_unregister(bus_entry->bus->bridge); 555 + pci_remove_bus(bus_entry->bus); 556 + 557 + kfree(bus_entry); 558 + } 559 + } 560 + 561 + static pci_ers_result_t pcifront_common_process(int cmd, 562 + struct pcifront_device *pdev, 563 + pci_channel_state_t state) 564 + { 565 + pci_ers_result_t result; 566 + struct pci_driver *pdrv; 567 + int bus = pdev->sh_info->aer_op.bus; 568 + int devfn = pdev->sh_info->aer_op.devfn; 569 + struct pci_dev *pcidev; 570 + int flag = 0; 571 + 572 + dev_dbg(&pdev->xdev->dev, 573 + "pcifront AER process: cmd %x (bus:%x, devfn%x)", 574 + cmd, bus, devfn); 575 + result = PCI_ERS_RESULT_NONE; 576 + 577 + pcidev = pci_get_bus_and_slot(bus, devfn); 578 + if (!pcidev || !pcidev->driver) { 579 + dev_err(&pcidev->dev, 580 + "device or driver is NULL\n"); 581 + return result; 582 + } 583 + pdrv = pcidev->driver; 584 + 585 + if (get_driver(&pdrv->driver)) { 586 + if (pdrv->err_handler && pdrv->err_handler->error_detected) { 587 + dev_dbg(&pcidev->dev, 588 + "trying to call AER service\n"); 589 + if (pcidev) { 590 + flag = 1; 591 + switch (cmd) { 592 + case XEN_PCI_OP_aer_detected: 593 + result = pdrv->err_handler-> 594 + error_detected(pcidev, state); 595 + break; 596 + case XEN_PCI_OP_aer_mmio: 597 + result = pdrv->err_handler-> 598 + mmio_enabled(pcidev); 599 + break; 600 + case XEN_PCI_OP_aer_slotreset: 601 + result = pdrv->err_handler-> 602 + slot_reset(pcidev); 603 + break; 604 + case XEN_PCI_OP_aer_resume: 605 + pdrv->err_handler->resume(pcidev); 606 + break; 607 + default: 608 + dev_err(&pdev->xdev->dev, 609 + "bad request in aer recovery " 610 + "operation!\n"); 611 + 612 + } 613 + } 614 + } 615 + put_driver(&pdrv->driver); 616 + } 617 + if (!flag) 618 + result = PCI_ERS_RESULT_NONE; 619 + 620 + return result; 621 + } 622 + 623 + 624 + static void pcifront_do_aer(struct work_struct *data) 625 + { 626 + struct pcifront_device *pdev = 627 + container_of(data, struct pcifront_device, op_work); 628 + int cmd = pdev->sh_info->aer_op.cmd; 629 + pci_channel_state_t state = 630 + (pci_channel_state_t)pdev->sh_info->aer_op.err; 631 + 632 + /*If a pci_conf op is in progress, 633 + we have to wait until it is done before service aer op*/ 634 + dev_dbg(&pdev->xdev->dev, 635 + "pcifront service aer bus %x devfn %x\n", 636 + pdev->sh_info->aer_op.bus, pdev->sh_info->aer_op.devfn); 637 + 638 + pdev->sh_info->aer_op.err = pcifront_common_process(cmd, pdev, state); 639 + 640 + /* Post the operation to the guest. */ 641 + wmb(); 642 + clear_bit(_XEN_PCIB_active, (unsigned long *)&pdev->sh_info->flags); 643 + notify_remote_via_evtchn(pdev->evtchn); 644 + 645 + /*in case of we lost an aer request in four lines time_window*/ 646 + smp_mb__before_clear_bit(); 647 + clear_bit(_PDEVB_op_active, &pdev->flags); 648 + smp_mb__after_clear_bit(); 649 + 650 + schedule_pcifront_aer_op(pdev); 651 + 652 + } 653 + 654 + static irqreturn_t pcifront_handler_aer(int irq, void *dev) 655 + { 656 + struct pcifront_device *pdev = dev; 657 + schedule_pcifront_aer_op(pdev); 658 + return IRQ_HANDLED; 659 + } 660 + static int pcifront_connect(struct pcifront_device *pdev) 661 + { 662 + int err = 0; 663 + 664 + spin_lock(&pcifront_dev_lock); 665 + 666 + if (!pcifront_dev) { 667 + dev_info(&pdev->xdev->dev, "Installing PCI frontend\n"); 668 + pcifront_dev = pdev; 669 + } else { 670 + dev_err(&pdev->xdev->dev, "PCI frontend already installed!\n"); 671 + err = -EEXIST; 672 + } 673 + 674 + spin_unlock(&pcifront_dev_lock); 675 + 676 + return err; 677 + } 678 + 679 + static void pcifront_disconnect(struct pcifront_device *pdev) 680 + { 681 + spin_lock(&pcifront_dev_lock); 682 + 683 + if (pdev == pcifront_dev) { 684 + dev_info(&pdev->xdev->dev, 685 + "Disconnecting PCI Frontend Buses\n"); 686 + pcifront_dev = NULL; 687 + } 688 + 689 + spin_unlock(&pcifront_dev_lock); 690 + } 691 + static struct pcifront_device *alloc_pdev(struct xenbus_device *xdev) 692 + { 693 + struct pcifront_device *pdev; 694 + 695 + pdev = kzalloc(sizeof(struct pcifront_device), GFP_KERNEL); 696 + if (pdev == NULL) 697 + goto out; 698 + 699 + pdev->sh_info = 700 + (struct xen_pci_sharedinfo *)__get_free_page(GFP_KERNEL); 701 + if (pdev->sh_info == NULL) { 702 + kfree(pdev); 703 + pdev = NULL; 704 + goto out; 705 + } 706 + pdev->sh_info->flags = 0; 707 + 708 + /*Flag for registering PV AER handler*/ 709 + set_bit(_XEN_PCIB_AERHANDLER, (void *)&pdev->sh_info->flags); 710 + 711 + dev_set_drvdata(&xdev->dev, pdev); 712 + pdev->xdev = xdev; 713 + 714 + INIT_LIST_HEAD(&pdev->root_buses); 715 + 716 + spin_lock_init(&pdev->sh_info_lock); 717 + 718 + pdev->evtchn = INVALID_EVTCHN; 719 + pdev->gnt_ref = INVALID_GRANT_REF; 720 + pdev->irq = -1; 721 + 722 + INIT_WORK(&pdev->op_work, pcifront_do_aer); 723 + 724 + dev_dbg(&xdev->dev, "Allocated pdev @ 0x%p pdev->sh_info @ 0x%p\n", 725 + pdev, pdev->sh_info); 726 + out: 727 + return pdev; 728 + } 729 + 730 + static void free_pdev(struct pcifront_device *pdev) 731 + { 732 + dev_dbg(&pdev->xdev->dev, "freeing pdev @ 0x%p\n", pdev); 733 + 734 + pcifront_free_roots(pdev); 735 + 736 + /*For PCIE_AER error handling job*/ 737 + flush_scheduled_work(); 738 + 739 + if (pdev->irq >= 0) 740 + unbind_from_irqhandler(pdev->irq, pdev); 741 + 742 + if (pdev->evtchn != INVALID_EVTCHN) 743 + xenbus_free_evtchn(pdev->xdev, pdev->evtchn); 744 + 745 + if (pdev->gnt_ref != INVALID_GRANT_REF) 746 + gnttab_end_foreign_access(pdev->gnt_ref, 0 /* r/w page */, 747 + (unsigned long)pdev->sh_info); 748 + else 749 + free_page((unsigned long)pdev->sh_info); 750 + 751 + dev_set_drvdata(&pdev->xdev->dev, NULL); 752 + 753 + kfree(pdev); 754 + } 755 + 756 + static int pcifront_publish_info(struct pcifront_device *pdev) 757 + { 758 + int err = 0; 759 + struct xenbus_transaction trans; 760 + 761 + err = xenbus_grant_ring(pdev->xdev, virt_to_mfn(pdev->sh_info)); 762 + if (err < 0) 763 + goto out; 764 + 765 + pdev->gnt_ref = err; 766 + 767 + err = xenbus_alloc_evtchn(pdev->xdev, &pdev->evtchn); 768 + if (err) 769 + goto out; 770 + 771 + err = bind_evtchn_to_irqhandler(pdev->evtchn, pcifront_handler_aer, 772 + 0, "pcifront", pdev); 773 + 774 + if (err < 0) 775 + return err; 776 + 777 + pdev->irq = err; 778 + 779 + do_publish: 780 + err = xenbus_transaction_start(&trans); 781 + if (err) { 782 + xenbus_dev_fatal(pdev->xdev, err, 783 + "Error writing configuration for backend " 784 + "(start transaction)"); 785 + goto out; 786 + } 787 + 788 + err = xenbus_printf(trans, pdev->xdev->nodename, 789 + "pci-op-ref", "%u", pdev->gnt_ref); 790 + if (!err) 791 + err = xenbus_printf(trans, pdev->xdev->nodename, 792 + "event-channel", "%u", pdev->evtchn); 793 + if (!err) 794 + err = xenbus_printf(trans, pdev->xdev->nodename, 795 + "magic", XEN_PCI_MAGIC); 796 + 797 + if (err) { 798 + xenbus_transaction_end(trans, 1); 799 + xenbus_dev_fatal(pdev->xdev, err, 800 + "Error writing configuration for backend"); 801 + goto out; 802 + } else { 803 + err = xenbus_transaction_end(trans, 0); 804 + if (err == -EAGAIN) 805 + goto do_publish; 806 + else if (err) { 807 + xenbus_dev_fatal(pdev->xdev, err, 808 + "Error completing transaction " 809 + "for backend"); 810 + goto out; 811 + } 812 + } 813 + 814 + xenbus_switch_state(pdev->xdev, XenbusStateInitialised); 815 + 816 + dev_dbg(&pdev->xdev->dev, "publishing successful!\n"); 817 + 818 + out: 819 + return err; 820 + } 821 + 822 + static int __devinit pcifront_try_connect(struct pcifront_device *pdev) 823 + { 824 + int err = -EFAULT; 825 + int i, num_roots, len; 826 + char str[64]; 827 + unsigned int domain, bus; 828 + 829 + 830 + /* Only connect once */ 831 + if (xenbus_read_driver_state(pdev->xdev->nodename) != 832 + XenbusStateInitialised) 833 + goto out; 834 + 835 + err = pcifront_connect(pdev); 836 + if (err) { 837 + xenbus_dev_fatal(pdev->xdev, err, 838 + "Error connecting PCI Frontend"); 839 + goto out; 840 + } 841 + 842 + err = xenbus_scanf(XBT_NIL, pdev->xdev->otherend, 843 + "root_num", "%d", &num_roots); 844 + if (err == -ENOENT) { 845 + xenbus_dev_error(pdev->xdev, err, 846 + "No PCI Roots found, trying 0000:00"); 847 + err = pcifront_scan_root(pdev, 0, 0); 848 + num_roots = 0; 849 + } else if (err != 1) { 850 + if (err == 0) 851 + err = -EINVAL; 852 + xenbus_dev_fatal(pdev->xdev, err, 853 + "Error reading number of PCI roots"); 854 + goto out; 855 + } 856 + 857 + for (i = 0; i < num_roots; i++) { 858 + len = snprintf(str, sizeof(str), "root-%d", i); 859 + if (unlikely(len >= (sizeof(str) - 1))) { 860 + err = -ENOMEM; 861 + goto out; 862 + } 863 + 864 + err = xenbus_scanf(XBT_NIL, pdev->xdev->otherend, str, 865 + "%x:%x", &domain, &bus); 866 + if (err != 2) { 867 + if (err >= 0) 868 + err = -EINVAL; 869 + xenbus_dev_fatal(pdev->xdev, err, 870 + "Error reading PCI root %d", i); 871 + goto out; 872 + } 873 + 874 + err = pcifront_scan_root(pdev, domain, bus); 875 + if (err) { 876 + xenbus_dev_fatal(pdev->xdev, err, 877 + "Error scanning PCI root %04x:%02x", 878 + domain, bus); 879 + goto out; 880 + } 881 + } 882 + 883 + err = xenbus_switch_state(pdev->xdev, XenbusStateConnected); 884 + 885 + out: 886 + return err; 887 + } 888 + 889 + static int pcifront_try_disconnect(struct pcifront_device *pdev) 890 + { 891 + int err = 0; 892 + enum xenbus_state prev_state; 893 + 894 + 895 + prev_state = xenbus_read_driver_state(pdev->xdev->nodename); 896 + 897 + if (prev_state >= XenbusStateClosing) 898 + goto out; 899 + 900 + if (prev_state == XenbusStateConnected) { 901 + pcifront_free_roots(pdev); 902 + pcifront_disconnect(pdev); 903 + } 904 + 905 + err = xenbus_switch_state(pdev->xdev, XenbusStateClosed); 906 + 907 + out: 908 + 909 + return err; 910 + } 911 + 912 + static int __devinit pcifront_attach_devices(struct pcifront_device *pdev) 913 + { 914 + int err = -EFAULT; 915 + int i, num_roots, len; 916 + unsigned int domain, bus; 917 + char str[64]; 918 + 919 + if (xenbus_read_driver_state(pdev->xdev->nodename) != 920 + XenbusStateReconfiguring) 921 + goto out; 922 + 923 + err = xenbus_scanf(XBT_NIL, pdev->xdev->otherend, 924 + "root_num", "%d", &num_roots); 925 + if (err == -ENOENT) { 926 + xenbus_dev_error(pdev->xdev, err, 927 + "No PCI Roots found, trying 0000:00"); 928 + err = pcifront_rescan_root(pdev, 0, 0); 929 + num_roots = 0; 930 + } else if (err != 1) { 931 + if (err == 0) 932 + err = -EINVAL; 933 + xenbus_dev_fatal(pdev->xdev, err, 934 + "Error reading number of PCI roots"); 935 + goto out; 936 + } 937 + 938 + for (i = 0; i < num_roots; i++) { 939 + len = snprintf(str, sizeof(str), "root-%d", i); 940 + if (unlikely(len >= (sizeof(str) - 1))) { 941 + err = -ENOMEM; 942 + goto out; 943 + } 944 + 945 + err = xenbus_scanf(XBT_NIL, pdev->xdev->otherend, str, 946 + "%x:%x", &domain, &bus); 947 + if (err != 2) { 948 + if (err >= 0) 949 + err = -EINVAL; 950 + xenbus_dev_fatal(pdev->xdev, err, 951 + "Error reading PCI root %d", i); 952 + goto out; 953 + } 954 + 955 + err = pcifront_rescan_root(pdev, domain, bus); 956 + if (err) { 957 + xenbus_dev_fatal(pdev->xdev, err, 958 + "Error scanning PCI root %04x:%02x", 959 + domain, bus); 960 + goto out; 961 + } 962 + } 963 + 964 + xenbus_switch_state(pdev->xdev, XenbusStateConnected); 965 + 966 + out: 967 + return err; 968 + } 969 + 970 + static int pcifront_detach_devices(struct pcifront_device *pdev) 971 + { 972 + int err = 0; 973 + int i, num_devs; 974 + unsigned int domain, bus, slot, func; 975 + struct pci_bus *pci_bus; 976 + struct pci_dev *pci_dev; 977 + char str[64]; 978 + 979 + if (xenbus_read_driver_state(pdev->xdev->nodename) != 980 + XenbusStateConnected) 981 + goto out; 982 + 983 + err = xenbus_scanf(XBT_NIL, pdev->xdev->otherend, "num_devs", "%d", 984 + &num_devs); 985 + if (err != 1) { 986 + if (err >= 0) 987 + err = -EINVAL; 988 + xenbus_dev_fatal(pdev->xdev, err, 989 + "Error reading number of PCI devices"); 990 + goto out; 991 + } 992 + 993 + /* Find devices being detached and remove them. */ 994 + for (i = 0; i < num_devs; i++) { 995 + int l, state; 996 + l = snprintf(str, sizeof(str), "state-%d", i); 997 + if (unlikely(l >= (sizeof(str) - 1))) { 998 + err = -ENOMEM; 999 + goto out; 1000 + } 1001 + err = xenbus_scanf(XBT_NIL, pdev->xdev->otherend, str, "%d", 1002 + &state); 1003 + if (err != 1) 1004 + state = XenbusStateUnknown; 1005 + 1006 + if (state != XenbusStateClosing) 1007 + continue; 1008 + 1009 + /* Remove device. */ 1010 + l = snprintf(str, sizeof(str), "vdev-%d", i); 1011 + if (unlikely(l >= (sizeof(str) - 1))) { 1012 + err = -ENOMEM; 1013 + goto out; 1014 + } 1015 + err = xenbus_scanf(XBT_NIL, pdev->xdev->otherend, str, 1016 + "%x:%x:%x.%x", &domain, &bus, &slot, &func); 1017 + if (err != 4) { 1018 + if (err >= 0) 1019 + err = -EINVAL; 1020 + xenbus_dev_fatal(pdev->xdev, err, 1021 + "Error reading PCI device %d", i); 1022 + goto out; 1023 + } 1024 + 1025 + pci_bus = pci_find_bus(domain, bus); 1026 + if (!pci_bus) { 1027 + dev_dbg(&pdev->xdev->dev, "Cannot get bus %04x:%02x\n", 1028 + domain, bus); 1029 + continue; 1030 + } 1031 + pci_dev = pci_get_slot(pci_bus, PCI_DEVFN(slot, func)); 1032 + if (!pci_dev) { 1033 + dev_dbg(&pdev->xdev->dev, 1034 + "Cannot get PCI device %04x:%02x:%02x.%02x\n", 1035 + domain, bus, slot, func); 1036 + continue; 1037 + } 1038 + pci_remove_bus_device(pci_dev); 1039 + pci_dev_put(pci_dev); 1040 + 1041 + dev_dbg(&pdev->xdev->dev, 1042 + "PCI device %04x:%02x:%02x.%02x removed.\n", 1043 + domain, bus, slot, func); 1044 + } 1045 + 1046 + err = xenbus_switch_state(pdev->xdev, XenbusStateReconfiguring); 1047 + 1048 + out: 1049 + return err; 1050 + } 1051 + 1052 + static void __init_refok pcifront_backend_changed(struct xenbus_device *xdev, 1053 + enum xenbus_state be_state) 1054 + { 1055 + struct pcifront_device *pdev = dev_get_drvdata(&xdev->dev); 1056 + 1057 + switch (be_state) { 1058 + case XenbusStateUnknown: 1059 + case XenbusStateInitialising: 1060 + case XenbusStateInitWait: 1061 + case XenbusStateInitialised: 1062 + case XenbusStateClosed: 1063 + break; 1064 + 1065 + case XenbusStateConnected: 1066 + pcifront_try_connect(pdev); 1067 + break; 1068 + 1069 + case XenbusStateClosing: 1070 + dev_warn(&xdev->dev, "backend going away!\n"); 1071 + pcifront_try_disconnect(pdev); 1072 + break; 1073 + 1074 + case XenbusStateReconfiguring: 1075 + pcifront_detach_devices(pdev); 1076 + break; 1077 + 1078 + case XenbusStateReconfigured: 1079 + pcifront_attach_devices(pdev); 1080 + break; 1081 + } 1082 + } 1083 + 1084 + static int pcifront_xenbus_probe(struct xenbus_device *xdev, 1085 + const struct xenbus_device_id *id) 1086 + { 1087 + int err = 0; 1088 + struct pcifront_device *pdev = alloc_pdev(xdev); 1089 + 1090 + if (pdev == NULL) { 1091 + err = -ENOMEM; 1092 + xenbus_dev_fatal(xdev, err, 1093 + "Error allocating pcifront_device struct"); 1094 + goto out; 1095 + } 1096 + 1097 + err = pcifront_publish_info(pdev); 1098 + if (err) 1099 + free_pdev(pdev); 1100 + 1101 + out: 1102 + return err; 1103 + } 1104 + 1105 + static int pcifront_xenbus_remove(struct xenbus_device *xdev) 1106 + { 1107 + struct pcifront_device *pdev = dev_get_drvdata(&xdev->dev); 1108 + if (pdev) 1109 + free_pdev(pdev); 1110 + 1111 + return 0; 1112 + } 1113 + 1114 + static const struct xenbus_device_id xenpci_ids[] = { 1115 + {"pci"}, 1116 + {""}, 1117 + }; 1118 + 1119 + static struct xenbus_driver xenbus_pcifront_driver = { 1120 + .name = "pcifront", 1121 + .owner = THIS_MODULE, 1122 + .ids = xenpci_ids, 1123 + .probe = pcifront_xenbus_probe, 1124 + .remove = pcifront_xenbus_remove, 1125 + .otherend_changed = pcifront_backend_changed, 1126 + }; 1127 + 1128 + static int __init pcifront_init(void) 1129 + { 1130 + if (!xen_pv_domain() || xen_initial_domain()) 1131 + return -ENODEV; 1132 + 1133 + pci_frontend_registrar(1 /* enable */); 1134 + 1135 + return xenbus_register_frontend(&xenbus_pcifront_driver); 1136 + } 1137 + 1138 + static void __exit pcifront_cleanup(void) 1139 + { 1140 + xenbus_unregister_driver(&xenbus_pcifront_driver); 1141 + pci_frontend_registrar(0 /* disable */); 1142 + } 1143 + module_init(pcifront_init); 1144 + module_exit(pcifront_cleanup); 1145 + 1146 + MODULE_DESCRIPTION("Xen PCI passthrough frontend."); 1147 + MODULE_LICENSE("GPL"); 1148 + MODULE_ALIAS("xen:pci");
+2
drivers/video/xen-fbfront.c
··· 631 631 switch (backend_state) { 632 632 case XenbusStateInitialising: 633 633 case XenbusStateInitialised: 634 + case XenbusStateReconfiguring: 635 + case XenbusStateReconfigured: 634 636 case XenbusStateUnknown: 635 637 case XenbusStateClosed: 636 638 break;
+2 -1
drivers/xen/Kconfig
··· 74 74 75 75 config SWIOTLB_XEN 76 76 def_bool y 77 - depends on SWIOTLB 77 + depends on PCI 78 + select SWIOTLB 78 79 79 80 endmenu
+2
drivers/xen/Makefile
··· 4 4 nostackp := $(call cc-option, -fno-stack-protector) 5 5 CFLAGS_features.o := $(nostackp) 6 6 7 + obj-$(CONFIG_BLOCK) += biomerge.o 7 8 obj-$(CONFIG_HOTPLUG_CPU) += cpu_hotplug.o 8 9 obj-$(CONFIG_XEN_XENCOMM) += xencomm.o 9 10 obj-$(CONFIG_XEN_BALLOON) += balloon.o ··· 13 12 obj-$(CONFIG_XEN_SYS_HYPERVISOR) += sys-hypervisor.o 14 13 obj-$(CONFIG_XEN_PLATFORM_PCI) += platform-pci.o 15 14 obj-$(CONFIG_SWIOTLB_XEN) += swiotlb-xen.o 15 + obj-$(CONFIG_XEN_DOM0) += pci.o
+13
drivers/xen/biomerge.c
··· 1 + #include <linux/bio.h> 2 + #include <linux/io.h> 3 + #include <xen/page.h> 4 + 5 + bool xen_biovec_phys_mergeable(const struct bio_vec *vec1, 6 + const struct bio_vec *vec2) 7 + { 8 + unsigned long mfn1 = pfn_to_mfn(page_to_pfn(vec1->bv_page)); 9 + unsigned long mfn2 = pfn_to_mfn(page_to_pfn(vec2->bv_page)); 10 + 11 + return __BIOVEC_PHYS_MERGEABLE(vec1, vec2) && 12 + ((mfn1 == mfn2) || ((mfn1+1) == mfn2)); 13 + }
+488 -21
drivers/xen/events.c
··· 16 16 * (typically dom0). 17 17 * 2. VIRQs, typically used for timers. These are per-cpu events. 18 18 * 3. IPIs. 19 - * 4. Hardware interrupts. Not supported at present. 19 + * 4. PIRQs - Hardware interrupts. 20 20 * 21 21 * Jeremy Fitzhardinge <jeremy@xensource.com>, XenSource Inc, 2007 22 22 */ ··· 28 28 #include <linux/string.h> 29 29 #include <linux/bootmem.h> 30 30 #include <linux/slab.h> 31 + #include <linux/irqnr.h> 32 + #include <linux/pci.h> 31 33 32 34 #include <asm/desc.h> 33 35 #include <asm/ptrace.h> 34 36 #include <asm/irq.h> 35 37 #include <asm/idle.h> 38 + #include <asm/io_apic.h> 36 39 #include <asm/sync_bitops.h> 40 + #include <asm/xen/pci.h> 37 41 #include <asm/xen/hypercall.h> 38 42 #include <asm/xen/hypervisor.h> 39 43 ··· 77 73 * event channel - irq->event channel mapping 78 74 * cpu - cpu this event channel is bound to 79 75 * index - type-specific information: 80 - * PIRQ - vector, with MSB being "needs EIO" 76 + * PIRQ - vector, with MSB being "needs EIO", or physical IRQ of the HVM 77 + * guest, or GSI (real passthrough IRQ) of the device. 81 78 * VIRQ - virq number 82 79 * IPI - IPI vector 83 80 * EVTCHN - ··· 93 88 unsigned short virq; 94 89 enum ipi_vector ipi; 95 90 struct { 91 + unsigned short pirq; 96 92 unsigned short gsi; 97 - unsigned short vector; 93 + unsigned char vector; 94 + unsigned char flags; 98 95 } pirq; 99 96 } u; 100 97 }; 98 + #define PIRQ_NEEDS_EOI (1 << 0) 99 + #define PIRQ_SHAREABLE (1 << 1) 101 100 102 - static struct irq_info irq_info[NR_IRQS]; 101 + static struct irq_info *irq_info; 102 + static int *pirq_to_irq; 103 + static int nr_pirqs; 103 104 104 - static int evtchn_to_irq[NR_EVENT_CHANNELS] = { 105 - [0 ... NR_EVENT_CHANNELS-1] = -1 106 - }; 105 + static int *evtchn_to_irq; 107 106 struct cpu_evtchn_s { 108 107 unsigned long bits[NR_EVENT_CHANNELS/BITS_PER_LONG]; 109 108 }; 110 - static struct cpu_evtchn_s *cpu_evtchn_mask_p; 109 + 110 + static __initdata struct cpu_evtchn_s init_evtchn_mask = { 111 + .bits[0 ... (NR_EVENT_CHANNELS/BITS_PER_LONG)-1] = ~0ul, 112 + }; 113 + static struct cpu_evtchn_s *cpu_evtchn_mask_p = &init_evtchn_mask; 114 + 111 115 static inline unsigned long *cpu_evtchn_mask(int cpu) 112 116 { 113 117 return cpu_evtchn_mask_p[cpu].bits; ··· 127 113 128 114 static struct irq_chip xen_dynamic_chip; 129 115 static struct irq_chip xen_percpu_chip; 116 + static struct irq_chip xen_pirq_chip; 130 117 131 118 /* Constructor for packed IRQ information. */ 132 119 static struct irq_info mk_unbound_info(void) ··· 153 138 .cpu = 0, .u.virq = virq }; 154 139 } 155 140 156 - static struct irq_info mk_pirq_info(unsigned short evtchn, 141 + static struct irq_info mk_pirq_info(unsigned short evtchn, unsigned short pirq, 157 142 unsigned short gsi, unsigned short vector) 158 143 { 159 144 return (struct irq_info) { .type = IRQT_PIRQ, .evtchn = evtchn, 160 - .cpu = 0, .u.pirq = { .gsi = gsi, .vector = vector } }; 145 + .cpu = 0, 146 + .u.pirq = { .pirq = pirq, .gsi = gsi, .vector = vector } }; 161 147 } 162 148 163 149 /* ··· 200 184 return info->u.virq; 201 185 } 202 186 187 + static unsigned pirq_from_irq(unsigned irq) 188 + { 189 + struct irq_info *info = info_for_irq(irq); 190 + 191 + BUG_ON(info == NULL); 192 + BUG_ON(info->type != IRQT_PIRQ); 193 + 194 + return info->u.pirq.pirq; 195 + } 196 + 203 197 static unsigned gsi_from_irq(unsigned irq) 204 198 { 205 199 struct irq_info *info = info_for_irq(irq); ··· 249 223 ret = cpu_from_irq(irq); 250 224 251 225 return ret; 226 + } 227 + 228 + static bool pirq_needs_eoi(unsigned irq) 229 + { 230 + struct irq_info *info = info_for_irq(irq); 231 + 232 + BUG_ON(info->type != IRQT_PIRQ); 233 + 234 + return info->u.pirq.flags & PIRQ_NEEDS_EOI; 252 235 } 253 236 254 237 static inline unsigned long active_evtchns(unsigned int cpu, ··· 371 336 put_cpu(); 372 337 } 373 338 339 + static int get_nr_hw_irqs(void) 340 + { 341 + int ret = 1; 342 + 343 + #ifdef CONFIG_X86_IO_APIC 344 + ret = get_nr_irqs_gsi(); 345 + #endif 346 + 347 + return ret; 348 + } 349 + 350 + /* callers of this function should make sure that PHYSDEVOP_get_nr_pirqs 351 + * succeeded otherwise nr_pirqs won't hold the right value */ 352 + static int find_unbound_pirq(void) 353 + { 354 + int i; 355 + for (i = nr_pirqs-1; i >= 0; i--) { 356 + if (pirq_to_irq[i] < 0) 357 + return i; 358 + } 359 + return -1; 360 + } 361 + 374 362 static int find_unbound_irq(void) 375 363 { 376 364 struct irq_data *data; 377 365 int irq, res; 366 + int start = get_nr_hw_irqs(); 378 367 379 - for (irq = 0; irq < nr_irqs; irq++) { 368 + if (start == nr_irqs) 369 + goto no_irqs; 370 + 371 + /* nr_irqs is a magic value. Must not use it.*/ 372 + for (irq = nr_irqs-1; irq > start; irq--) { 380 373 data = irq_get_irq_data(irq); 381 374 /* only 0->15 have init'd desc; handle irq > 16 */ 382 375 if (!data) ··· 417 354 return irq; 418 355 } 419 356 420 - if (irq == nr_irqs) 421 - panic("No available IRQ to bind to: increase nr_irqs!\n"); 357 + if (irq == start) 358 + goto no_irqs; 422 359 423 360 res = irq_alloc_desc_at(irq, 0); 424 361 ··· 426 363 return -1; 427 364 428 365 return irq; 366 + 367 + no_irqs: 368 + panic("No available IRQ to bind to: increase nr_irqs!\n"); 369 + } 370 + 371 + static bool identity_mapped_irq(unsigned irq) 372 + { 373 + /* identity map all the hardware irqs */ 374 + return irq < get_nr_hw_irqs(); 375 + } 376 + 377 + static void pirq_unmask_notify(int irq) 378 + { 379 + struct physdev_eoi eoi = { .irq = pirq_from_irq(irq) }; 380 + 381 + if (unlikely(pirq_needs_eoi(irq))) { 382 + int rc = HYPERVISOR_physdev_op(PHYSDEVOP_eoi, &eoi); 383 + WARN_ON(rc); 384 + } 385 + } 386 + 387 + static void pirq_query_unmask(int irq) 388 + { 389 + struct physdev_irq_status_query irq_status; 390 + struct irq_info *info = info_for_irq(irq); 391 + 392 + BUG_ON(info->type != IRQT_PIRQ); 393 + 394 + irq_status.irq = pirq_from_irq(irq); 395 + if (HYPERVISOR_physdev_op(PHYSDEVOP_irq_status_query, &irq_status)) 396 + irq_status.flags = 0; 397 + 398 + info->u.pirq.flags &= ~PIRQ_NEEDS_EOI; 399 + if (irq_status.flags & XENIRQSTAT_needs_eoi) 400 + info->u.pirq.flags |= PIRQ_NEEDS_EOI; 401 + } 402 + 403 + static bool probing_irq(int irq) 404 + { 405 + struct irq_desc *desc = irq_to_desc(irq); 406 + 407 + return desc && desc->action == NULL; 408 + } 409 + 410 + static unsigned int startup_pirq(unsigned int irq) 411 + { 412 + struct evtchn_bind_pirq bind_pirq; 413 + struct irq_info *info = info_for_irq(irq); 414 + int evtchn = evtchn_from_irq(irq); 415 + int rc; 416 + 417 + BUG_ON(info->type != IRQT_PIRQ); 418 + 419 + if (VALID_EVTCHN(evtchn)) 420 + goto out; 421 + 422 + bind_pirq.pirq = pirq_from_irq(irq); 423 + /* NB. We are happy to share unless we are probing. */ 424 + bind_pirq.flags = info->u.pirq.flags & PIRQ_SHAREABLE ? 425 + BIND_PIRQ__WILL_SHARE : 0; 426 + rc = HYPERVISOR_event_channel_op(EVTCHNOP_bind_pirq, &bind_pirq); 427 + if (rc != 0) { 428 + if (!probing_irq(irq)) 429 + printk(KERN_INFO "Failed to obtain physical IRQ %d\n", 430 + irq); 431 + return 0; 432 + } 433 + evtchn = bind_pirq.port; 434 + 435 + pirq_query_unmask(irq); 436 + 437 + evtchn_to_irq[evtchn] = irq; 438 + bind_evtchn_to_cpu(evtchn, 0); 439 + info->evtchn = evtchn; 440 + 441 + out: 442 + unmask_evtchn(evtchn); 443 + pirq_unmask_notify(irq); 444 + 445 + return 0; 446 + } 447 + 448 + static void shutdown_pirq(unsigned int irq) 449 + { 450 + struct evtchn_close close; 451 + struct irq_info *info = info_for_irq(irq); 452 + int evtchn = evtchn_from_irq(irq); 453 + 454 + BUG_ON(info->type != IRQT_PIRQ); 455 + 456 + if (!VALID_EVTCHN(evtchn)) 457 + return; 458 + 459 + mask_evtchn(evtchn); 460 + 461 + close.port = evtchn; 462 + if (HYPERVISOR_event_channel_op(EVTCHNOP_close, &close) != 0) 463 + BUG(); 464 + 465 + bind_evtchn_to_cpu(evtchn, 0); 466 + evtchn_to_irq[evtchn] = -1; 467 + info->evtchn = 0; 468 + } 469 + 470 + static void enable_pirq(unsigned int irq) 471 + { 472 + startup_pirq(irq); 473 + } 474 + 475 + static void disable_pirq(unsigned int irq) 476 + { 477 + } 478 + 479 + static void ack_pirq(unsigned int irq) 480 + { 481 + int evtchn = evtchn_from_irq(irq); 482 + 483 + move_native_irq(irq); 484 + 485 + if (VALID_EVTCHN(evtchn)) { 486 + mask_evtchn(evtchn); 487 + clear_evtchn(evtchn); 488 + } 489 + } 490 + 491 + static void end_pirq(unsigned int irq) 492 + { 493 + int evtchn = evtchn_from_irq(irq); 494 + struct irq_desc *desc = irq_to_desc(irq); 495 + 496 + if (WARN_ON(!desc)) 497 + return; 498 + 499 + if ((desc->status & (IRQ_DISABLED|IRQ_PENDING)) == 500 + (IRQ_DISABLED|IRQ_PENDING)) { 501 + shutdown_pirq(irq); 502 + } else if (VALID_EVTCHN(evtchn)) { 503 + unmask_evtchn(evtchn); 504 + pirq_unmask_notify(irq); 505 + } 506 + } 507 + 508 + static int find_irq_by_gsi(unsigned gsi) 509 + { 510 + int irq; 511 + 512 + for (irq = 0; irq < nr_irqs; irq++) { 513 + struct irq_info *info = info_for_irq(irq); 514 + 515 + if (info == NULL || info->type != IRQT_PIRQ) 516 + continue; 517 + 518 + if (gsi_from_irq(irq) == gsi) 519 + return irq; 520 + } 521 + 522 + return -1; 523 + } 524 + 525 + int xen_allocate_pirq(unsigned gsi, int shareable, char *name) 526 + { 527 + return xen_map_pirq_gsi(gsi, gsi, shareable, name); 528 + } 529 + 530 + /* xen_map_pirq_gsi might allocate irqs from the top down, as a 531 + * consequence don't assume that the irq number returned has a low value 532 + * or can be used as a pirq number unless you know otherwise. 533 + * 534 + * One notable exception is when xen_map_pirq_gsi is called passing an 535 + * hardware gsi as argument, in that case the irq number returned 536 + * matches the gsi number passed as second argument. 537 + * 538 + * Note: We don't assign an event channel until the irq actually started 539 + * up. Return an existing irq if we've already got one for the gsi. 540 + */ 541 + int xen_map_pirq_gsi(unsigned pirq, unsigned gsi, int shareable, char *name) 542 + { 543 + int irq = 0; 544 + struct physdev_irq irq_op; 545 + 546 + spin_lock(&irq_mapping_update_lock); 547 + 548 + if ((pirq > nr_pirqs) || (gsi > nr_irqs)) { 549 + printk(KERN_WARNING "xen_map_pirq_gsi: %s %s is incorrect!\n", 550 + pirq > nr_pirqs ? "nr_pirqs" :"", 551 + gsi > nr_irqs ? "nr_irqs" : ""); 552 + goto out; 553 + } 554 + 555 + irq = find_irq_by_gsi(gsi); 556 + if (irq != -1) { 557 + printk(KERN_INFO "xen_map_pirq_gsi: returning irq %d for gsi %u\n", 558 + irq, gsi); 559 + goto out; /* XXX need refcount? */ 560 + } 561 + 562 + /* If we are a PV guest, we don't have GSIs (no ACPI passed). Therefore 563 + * we are using the !xen_initial_domain() to drop in the function.*/ 564 + if (identity_mapped_irq(gsi) || (!xen_initial_domain() && 565 + xen_pv_domain())) { 566 + irq = gsi; 567 + irq_alloc_desc_at(irq, 0); 568 + } else 569 + irq = find_unbound_irq(); 570 + 571 + set_irq_chip_and_handler_name(irq, &xen_pirq_chip, 572 + handle_level_irq, name); 573 + 574 + irq_op.irq = irq; 575 + irq_op.vector = 0; 576 + 577 + /* Only the privileged domain can do this. For non-priv, the pcifront 578 + * driver provides a PCI bus that does the call to do exactly 579 + * this in the priv domain. */ 580 + if (xen_initial_domain() && 581 + HYPERVISOR_physdev_op(PHYSDEVOP_alloc_irq_vector, &irq_op)) { 582 + irq_free_desc(irq); 583 + irq = -ENOSPC; 584 + goto out; 585 + } 586 + 587 + irq_info[irq] = mk_pirq_info(0, pirq, gsi, irq_op.vector); 588 + irq_info[irq].u.pirq.flags |= shareable ? PIRQ_SHAREABLE : 0; 589 + pirq_to_irq[pirq] = irq; 590 + 591 + out: 592 + spin_unlock(&irq_mapping_update_lock); 593 + 594 + return irq; 595 + } 596 + 597 + #ifdef CONFIG_PCI_MSI 598 + #include <linux/msi.h> 599 + #include "../pci/msi.h" 600 + 601 + void xen_allocate_pirq_msi(char *name, int *irq, int *pirq) 602 + { 603 + spin_lock(&irq_mapping_update_lock); 604 + 605 + *irq = find_unbound_irq(); 606 + if (*irq == -1) 607 + goto out; 608 + 609 + *pirq = find_unbound_pirq(); 610 + if (*pirq == -1) 611 + goto out; 612 + 613 + set_irq_chip_and_handler_name(*irq, &xen_pirq_chip, 614 + handle_level_irq, name); 615 + 616 + irq_info[*irq] = mk_pirq_info(0, *pirq, 0, 0); 617 + pirq_to_irq[*pirq] = *irq; 618 + 619 + out: 620 + spin_unlock(&irq_mapping_update_lock); 621 + } 622 + 623 + int xen_create_msi_irq(struct pci_dev *dev, struct msi_desc *msidesc, int type) 624 + { 625 + int irq = -1; 626 + struct physdev_map_pirq map_irq; 627 + int rc; 628 + int pos; 629 + u32 table_offset, bir; 630 + 631 + memset(&map_irq, 0, sizeof(map_irq)); 632 + map_irq.domid = DOMID_SELF; 633 + map_irq.type = MAP_PIRQ_TYPE_MSI; 634 + map_irq.index = -1; 635 + map_irq.pirq = -1; 636 + map_irq.bus = dev->bus->number; 637 + map_irq.devfn = dev->devfn; 638 + 639 + if (type == PCI_CAP_ID_MSIX) { 640 + pos = pci_find_capability(dev, PCI_CAP_ID_MSIX); 641 + 642 + pci_read_config_dword(dev, msix_table_offset_reg(pos), 643 + &table_offset); 644 + bir = (u8)(table_offset & PCI_MSIX_FLAGS_BIRMASK); 645 + 646 + map_irq.table_base = pci_resource_start(dev, bir); 647 + map_irq.entry_nr = msidesc->msi_attrib.entry_nr; 648 + } 649 + 650 + spin_lock(&irq_mapping_update_lock); 651 + 652 + irq = find_unbound_irq(); 653 + 654 + if (irq == -1) 655 + goto out; 656 + 657 + rc = HYPERVISOR_physdev_op(PHYSDEVOP_map_pirq, &map_irq); 658 + if (rc) { 659 + printk(KERN_WARNING "xen map irq failed %d\n", rc); 660 + 661 + irq_free_desc(irq); 662 + 663 + irq = -1; 664 + goto out; 665 + } 666 + irq_info[irq] = mk_pirq_info(0, map_irq.pirq, 0, map_irq.index); 667 + 668 + set_irq_chip_and_handler_name(irq, &xen_pirq_chip, 669 + handle_level_irq, 670 + (type == PCI_CAP_ID_MSIX) ? "msi-x":"msi"); 671 + 672 + out: 673 + spin_unlock(&irq_mapping_update_lock); 674 + return irq; 675 + } 676 + #endif 677 + 678 + int xen_destroy_irq(int irq) 679 + { 680 + struct irq_desc *desc; 681 + struct physdev_unmap_pirq unmap_irq; 682 + struct irq_info *info = info_for_irq(irq); 683 + int rc = -ENOENT; 684 + 685 + spin_lock(&irq_mapping_update_lock); 686 + 687 + desc = irq_to_desc(irq); 688 + if (!desc) 689 + goto out; 690 + 691 + if (xen_initial_domain()) { 692 + unmap_irq.pirq = info->u.pirq.gsi; 693 + unmap_irq.domid = DOMID_SELF; 694 + rc = HYPERVISOR_physdev_op(PHYSDEVOP_unmap_pirq, &unmap_irq); 695 + if (rc) { 696 + printk(KERN_WARNING "unmap irq failed %d\n", rc); 697 + goto out; 698 + } 699 + } 700 + irq_info[irq] = mk_unbound_info(); 701 + 702 + irq_free_desc(irq); 703 + 704 + out: 705 + spin_unlock(&irq_mapping_update_lock); 706 + return rc; 707 + } 708 + 709 + int xen_vector_from_irq(unsigned irq) 710 + { 711 + return vector_from_irq(irq); 712 + } 713 + 714 + int xen_gsi_from_irq(unsigned irq) 715 + { 716 + return gsi_from_irq(irq); 429 717 } 430 718 431 719 int bind_evtchn_to_irq(unsigned int evtchn) ··· 839 425 } 840 426 841 427 842 - static int bind_virq_to_irq(unsigned int virq, unsigned int cpu) 428 + int bind_virq_to_irq(unsigned int virq, unsigned int cpu) 843 429 { 844 430 struct evtchn_bind_virq bind_virq; 845 431 int evtchn, irq; ··· 1342 928 if (VALID_EVTCHN(evtchn)) 1343 929 clear_evtchn(evtchn); 1344 930 } 1345 - 931 + EXPORT_SYMBOL(xen_clear_irq_pending); 1346 932 void xen_set_irq_pending(int irq) 1347 933 { 1348 934 int evtchn = evtchn_from_irq(irq); ··· 1362 948 return ret; 1363 949 } 1364 950 1365 - /* Poll waiting for an irq to become pending. In the usual case, the 1366 - irq will be disabled so it won't deliver an interrupt. */ 1367 - void xen_poll_irq(int irq) 951 + /* Poll waiting for an irq to become pending with timeout. In the usual case, 952 + * the irq will be disabled so it won't deliver an interrupt. */ 953 + void xen_poll_irq_timeout(int irq, u64 timeout) 1368 954 { 1369 955 evtchn_port_t evtchn = evtchn_from_irq(irq); 1370 956 ··· 1372 958 struct sched_poll poll; 1373 959 1374 960 poll.nr_ports = 1; 1375 - poll.timeout = 0; 961 + poll.timeout = timeout; 1376 962 set_xen_guest_handle(poll.ports, &evtchn); 1377 963 1378 964 if (HYPERVISOR_sched_op(SCHEDOP_poll, &poll) != 0) 1379 965 BUG(); 1380 966 } 967 + } 968 + EXPORT_SYMBOL(xen_poll_irq_timeout); 969 + /* Poll waiting for an irq to become pending. In the usual case, the 970 + * irq will be disabled so it won't deliver an interrupt. */ 971 + void xen_poll_irq(int irq) 972 + { 973 + xen_poll_irq_timeout(irq, 0 /* no timeout */); 1381 974 } 1382 975 1383 976 void xen_irq_resume(void) ··· 1419 998 1420 999 .eoi = ack_dynirq, 1421 1000 .set_affinity = set_affinity_irq, 1001 + .retrigger = retrigger_dynirq, 1002 + }; 1003 + 1004 + static struct irq_chip xen_pirq_chip __read_mostly = { 1005 + .name = "xen-pirq", 1006 + 1007 + .startup = startup_pirq, 1008 + .shutdown = shutdown_pirq, 1009 + 1010 + .enable = enable_pirq, 1011 + .unmask = enable_pirq, 1012 + 1013 + .disable = disable_pirq, 1014 + .mask = disable_pirq, 1015 + 1016 + .ack = ack_pirq, 1017 + .end = end_pirq, 1018 + 1019 + .set_affinity = set_affinity_irq, 1020 + 1422 1021 .retrigger = retrigger_dynirq, 1423 1022 }; 1424 1023 ··· 1492 1051 1493 1052 void __init xen_init_IRQ(void) 1494 1053 { 1495 - int i; 1054 + int i, rc; 1055 + struct physdev_nr_pirqs op_nr_pirqs; 1496 1056 1497 1057 cpu_evtchn_mask_p = kcalloc(nr_cpu_ids, sizeof(struct cpu_evtchn_s), 1498 1058 GFP_KERNEL); 1499 - BUG_ON(cpu_evtchn_mask_p == NULL); 1059 + irq_info = kcalloc(nr_irqs, sizeof(*irq_info), GFP_KERNEL); 1060 + 1061 + rc = HYPERVISOR_physdev_op(PHYSDEVOP_get_nr_pirqs, &op_nr_pirqs); 1062 + if (rc < 0) { 1063 + nr_pirqs = nr_irqs; 1064 + if (rc != -ENOSYS) 1065 + printk(KERN_WARNING "PHYSDEVOP_get_nr_pirqs returned rc=%d\n", rc); 1066 + } else { 1067 + if (xen_pv_domain() && !xen_initial_domain()) 1068 + nr_pirqs = max((int)op_nr_pirqs.nr_pirqs, nr_irqs); 1069 + else 1070 + nr_pirqs = op_nr_pirqs.nr_pirqs; 1071 + } 1072 + pirq_to_irq = kcalloc(nr_pirqs, sizeof(*pirq_to_irq), GFP_KERNEL); 1073 + for (i = 0; i < nr_pirqs; i++) 1074 + pirq_to_irq[i] = -1; 1075 + 1076 + evtchn_to_irq = kcalloc(NR_EVENT_CHANNELS, sizeof(*evtchn_to_irq), 1077 + GFP_KERNEL); 1078 + for (i = 0; i < NR_EVENT_CHANNELS; i++) 1079 + evtchn_to_irq[i] = -1; 1500 1080 1501 1081 init_evtchn_cpu_bindings(); 1502 1082 ··· 1528 1066 if (xen_hvm_domain()) { 1529 1067 xen_callback_vector(); 1530 1068 native_init_IRQ(); 1069 + /* pci_xen_hvm_init must be called after native_init_IRQ so that 1070 + * __acpi_register_gsi can point at the right function */ 1071 + pci_xen_hvm_init(); 1531 1072 } else { 1532 1073 irq_ctx_init(smp_processor_id()); 1074 + if (xen_initial_domain()) 1075 + xen_setup_pirqs(); 1533 1076 } 1534 1077 }
+117
drivers/xen/pci.c
··· 1 + /* 2 + * Copyright (c) 2009, Intel Corporation. 3 + * 4 + * This program is free software; you can redistribute it and/or modify it 5 + * under the terms and conditions of the GNU General Public License, 6 + * version 2, as published by the Free Software Foundation. 7 + * 8 + * This program is distributed in the hope it will be useful, but WITHOUT 9 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 10 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 11 + * more details. 12 + * 13 + * You should have received a copy of the GNU General Public License along with 14 + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple 15 + * Place - Suite 330, Boston, MA 02111-1307 USA. 16 + * 17 + * Author: Weidong Han <weidong.han@intel.com> 18 + */ 19 + 20 + #include <linux/pci.h> 21 + #include <xen/xen.h> 22 + #include <xen/interface/physdev.h> 23 + #include <xen/interface/xen.h> 24 + 25 + #include <asm/xen/hypervisor.h> 26 + #include <asm/xen/hypercall.h> 27 + #include "../pci/pci.h" 28 + 29 + static int xen_add_device(struct device *dev) 30 + { 31 + int r; 32 + struct pci_dev *pci_dev = to_pci_dev(dev); 33 + 34 + #ifdef CONFIG_PCI_IOV 35 + if (pci_dev->is_virtfn) { 36 + struct physdev_manage_pci_ext manage_pci_ext = { 37 + .bus = pci_dev->bus->number, 38 + .devfn = pci_dev->devfn, 39 + .is_virtfn = 1, 40 + .physfn.bus = pci_dev->physfn->bus->number, 41 + .physfn.devfn = pci_dev->physfn->devfn, 42 + }; 43 + 44 + r = HYPERVISOR_physdev_op(PHYSDEVOP_manage_pci_add_ext, 45 + &manage_pci_ext); 46 + } else 47 + #endif 48 + if (pci_ari_enabled(pci_dev->bus) && PCI_SLOT(pci_dev->devfn)) { 49 + struct physdev_manage_pci_ext manage_pci_ext = { 50 + .bus = pci_dev->bus->number, 51 + .devfn = pci_dev->devfn, 52 + .is_extfn = 1, 53 + }; 54 + 55 + r = HYPERVISOR_physdev_op(PHYSDEVOP_manage_pci_add_ext, 56 + &manage_pci_ext); 57 + } else { 58 + struct physdev_manage_pci manage_pci = { 59 + .bus = pci_dev->bus->number, 60 + .devfn = pci_dev->devfn, 61 + }; 62 + 63 + r = HYPERVISOR_physdev_op(PHYSDEVOP_manage_pci_add, 64 + &manage_pci); 65 + } 66 + 67 + return r; 68 + } 69 + 70 + static int xen_remove_device(struct device *dev) 71 + { 72 + int r; 73 + struct pci_dev *pci_dev = to_pci_dev(dev); 74 + struct physdev_manage_pci manage_pci; 75 + 76 + manage_pci.bus = pci_dev->bus->number; 77 + manage_pci.devfn = pci_dev->devfn; 78 + 79 + r = HYPERVISOR_physdev_op(PHYSDEVOP_manage_pci_remove, 80 + &manage_pci); 81 + 82 + return r; 83 + } 84 + 85 + static int xen_pci_notifier(struct notifier_block *nb, 86 + unsigned long action, void *data) 87 + { 88 + struct device *dev = data; 89 + int r = 0; 90 + 91 + switch (action) { 92 + case BUS_NOTIFY_ADD_DEVICE: 93 + r = xen_add_device(dev); 94 + break; 95 + case BUS_NOTIFY_DEL_DEVICE: 96 + r = xen_remove_device(dev); 97 + break; 98 + default: 99 + break; 100 + } 101 + 102 + return r; 103 + } 104 + 105 + struct notifier_block device_nb = { 106 + .notifier_call = xen_pci_notifier, 107 + }; 108 + 109 + static int __init register_xen_pci_notifier(void) 110 + { 111 + if (!xen_initial_domain()) 112 + return 0; 113 + 114 + return bus_register_notifier(&pci_bus_type, &device_nb); 115 + } 116 + 117 + arch_initcall(register_xen_pci_notifier);
+2
drivers/xen/xenbus/xenbus_client.c
··· 50 50 [ XenbusStateConnected ] = "Connected", 51 51 [ XenbusStateClosing ] = "Closing", 52 52 [ XenbusStateClosed ] = "Closed", 53 + [XenbusStateReconfiguring] = "Reconfiguring", 54 + [XenbusStateReconfigured] = "Reconfigured", 53 55 }; 54 56 return (state < ARRAY_SIZE(name)) ? name[state] : "INVALID"; 55 57 }
+28 -1
drivers/xen/xenbus/xenbus_probe.c
··· 803 803 static int __init xenbus_init(void) 804 804 { 805 805 int err = 0; 806 + unsigned long page = 0; 806 807 807 808 DPRINTK(""); 808 809 ··· 824 823 * Domain0 doesn't have a store_evtchn or store_mfn yet. 825 824 */ 826 825 if (xen_initial_domain()) { 827 - /* dom0 not yet supported */ 826 + struct evtchn_alloc_unbound alloc_unbound; 827 + 828 + /* Allocate Xenstore page */ 829 + page = get_zeroed_page(GFP_KERNEL); 830 + if (!page) 831 + goto out_error; 832 + 833 + xen_store_mfn = xen_start_info->store_mfn = 834 + pfn_to_mfn(virt_to_phys((void *)page) >> 835 + PAGE_SHIFT); 836 + 837 + /* Next allocate a local port which xenstored can bind to */ 838 + alloc_unbound.dom = DOMID_SELF; 839 + alloc_unbound.remote_dom = 0; 840 + 841 + err = HYPERVISOR_event_channel_op(EVTCHNOP_alloc_unbound, 842 + &alloc_unbound); 843 + if (err == -ENOSYS) 844 + goto out_error; 845 + 846 + BUG_ON(err); 847 + xen_store_evtchn = xen_start_info->store_evtchn = 848 + alloc_unbound.port; 849 + 850 + xen_store_interface = mfn_to_virt(xen_store_mfn); 828 851 } else { 829 852 if (xen_hvm_domain()) { 830 853 uint64_t v = 0; ··· 894 869 bus_unregister(&xenbus_frontend.bus); 895 870 896 871 out_error: 872 + if (page != 0) 873 + free_page(page); 897 874 return err; 898 875 } 899 876
+26
include/xen/events.h
··· 12 12 irq_handler_t handler, 13 13 unsigned long irqflags, const char *devname, 14 14 void *dev_id); 15 + int bind_virq_to_irq(unsigned int virq, unsigned int cpu); 15 16 int bind_virq_to_irqhandler(unsigned int virq, unsigned int cpu, 16 17 irq_handler_t handler, 17 18 unsigned long irqflags, const char *devname, ··· 54 53 irq will be disabled so it won't deliver an interrupt. */ 55 54 void xen_poll_irq(int irq); 56 55 56 + /* Poll waiting for an irq to become pending with a timeout. In the usual case, 57 + * the irq will be disabled so it won't deliver an interrupt. */ 58 + void xen_poll_irq_timeout(int irq, u64 timeout); 59 + 57 60 /* Determine the IRQ which is bound to an event channel */ 58 61 unsigned irq_from_evtchn(unsigned int evtchn); 59 62 ··· 67 62 int xen_set_callback_via(uint64_t via); 68 63 void xen_evtchn_do_upcall(struct pt_regs *regs); 69 64 void xen_hvm_evtchn_do_upcall(void); 65 + 66 + /* Allocate an irq for a physical interrupt, given a gsi. "Legacy" 67 + * GSIs are identity mapped; others are dynamically allocated as 68 + * usual. */ 69 + int xen_allocate_pirq(unsigned gsi, int shareable, char *name); 70 + int xen_map_pirq_gsi(unsigned pirq, unsigned gsi, int shareable, char *name); 71 + 72 + #ifdef CONFIG_PCI_MSI 73 + /* Allocate an irq and a pirq to be used with MSIs. */ 74 + void xen_allocate_pirq_msi(char *name, int *irq, int *pirq); 75 + int xen_create_msi_irq(struct pci_dev *dev, struct msi_desc *msidesc, int type); 76 + #endif 77 + 78 + /* De-allocates the above mentioned physical interrupt. */ 79 + int xen_destroy_irq(int irq); 80 + 81 + /* Return vector allocated to pirq */ 82 + int xen_vector_from_irq(unsigned pirq); 83 + 84 + /* Return gsi allocated to pirq */ 85 + int xen_gsi_from_irq(unsigned pirq); 70 86 71 87 #endif /* _XEN_EVENTS_H */
+3
include/xen/interface/features.h
··· 47 47 /* x86: pvclock algorithm is safe to use on HVM */ 48 48 #define XENFEAT_hvm_safe_pvclock 9 49 49 50 + /* x86: pirq can be used by HVM guests */ 51 + #define XENFEAT_hvm_pirqs 10 52 + 50 53 #define XENFEAT_NR_SUBMAPS 1 51 54 52 55 #endif /* __XEN_PUBLIC_FEATURES_H__ */
+112
include/xen/interface/io/pciif.h
··· 1 + /* 2 + * PCI Backend/Frontend Common Data Structures & Macros 3 + * 4 + * Permission is hereby granted, free of charge, to any person obtaining a copy 5 + * of this software and associated documentation files (the "Software"), to 6 + * deal in the Software without restriction, including without limitation the 7 + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 8 + * sell copies of the Software, and to permit persons to whom the Software is 9 + * furnished to do so, subject to the following conditions: 10 + * 11 + * The above copyright notice and this permission notice shall be included in 12 + * all copies or substantial portions of the Software. 13 + * 14 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 20 + * DEALINGS IN THE SOFTWARE. 21 + * 22 + * Author: Ryan Wilson <hap9@epoch.ncsc.mil> 23 + */ 24 + #ifndef __XEN_PCI_COMMON_H__ 25 + #define __XEN_PCI_COMMON_H__ 26 + 27 + /* Be sure to bump this number if you change this file */ 28 + #define XEN_PCI_MAGIC "7" 29 + 30 + /* xen_pci_sharedinfo flags */ 31 + #define _XEN_PCIF_active (0) 32 + #define XEN_PCIF_active (1<<_XEN_PCIF_active) 33 + #define _XEN_PCIB_AERHANDLER (1) 34 + #define XEN_PCIB_AERHANDLER (1<<_XEN_PCIB_AERHANDLER) 35 + #define _XEN_PCIB_active (2) 36 + #define XEN_PCIB_active (1<<_XEN_PCIB_active) 37 + 38 + /* xen_pci_op commands */ 39 + #define XEN_PCI_OP_conf_read (0) 40 + #define XEN_PCI_OP_conf_write (1) 41 + #define XEN_PCI_OP_enable_msi (2) 42 + #define XEN_PCI_OP_disable_msi (3) 43 + #define XEN_PCI_OP_enable_msix (4) 44 + #define XEN_PCI_OP_disable_msix (5) 45 + #define XEN_PCI_OP_aer_detected (6) 46 + #define XEN_PCI_OP_aer_resume (7) 47 + #define XEN_PCI_OP_aer_mmio (8) 48 + #define XEN_PCI_OP_aer_slotreset (9) 49 + 50 + /* xen_pci_op error numbers */ 51 + #define XEN_PCI_ERR_success (0) 52 + #define XEN_PCI_ERR_dev_not_found (-1) 53 + #define XEN_PCI_ERR_invalid_offset (-2) 54 + #define XEN_PCI_ERR_access_denied (-3) 55 + #define XEN_PCI_ERR_not_implemented (-4) 56 + /* XEN_PCI_ERR_op_failed - backend failed to complete the operation */ 57 + #define XEN_PCI_ERR_op_failed (-5) 58 + 59 + /* 60 + * it should be PAGE_SIZE-sizeof(struct xen_pci_op))/sizeof(struct msix_entry)) 61 + * Should not exceed 128 62 + */ 63 + #define SH_INFO_MAX_VEC 128 64 + 65 + struct xen_msix_entry { 66 + uint16_t vector; 67 + uint16_t entry; 68 + }; 69 + struct xen_pci_op { 70 + /* IN: what action to perform: XEN_PCI_OP_* */ 71 + uint32_t cmd; 72 + 73 + /* OUT: will contain an error number (if any) from errno.h */ 74 + int32_t err; 75 + 76 + /* IN: which device to touch */ 77 + uint32_t domain; /* PCI Domain/Segment */ 78 + uint32_t bus; 79 + uint32_t devfn; 80 + 81 + /* IN: which configuration registers to touch */ 82 + int32_t offset; 83 + int32_t size; 84 + 85 + /* IN/OUT: Contains the result after a READ or the value to WRITE */ 86 + uint32_t value; 87 + /* IN: Contains extra infor for this operation */ 88 + uint32_t info; 89 + /*IN: param for msi-x */ 90 + struct xen_msix_entry msix_entries[SH_INFO_MAX_VEC]; 91 + }; 92 + 93 + /*used for pcie aer handling*/ 94 + struct xen_pcie_aer_op { 95 + /* IN: what action to perform: XEN_PCI_OP_* */ 96 + uint32_t cmd; 97 + /*IN/OUT: return aer_op result or carry error_detected state as input*/ 98 + int32_t err; 99 + 100 + /* IN: which device to touch */ 101 + uint32_t domain; /* PCI Domain/Segment*/ 102 + uint32_t bus; 103 + uint32_t devfn; 104 + }; 105 + struct xen_pci_sharedinfo { 106 + /* flags - XEN_PCIF_* */ 107 + uint32_t flags; 108 + struct xen_pci_op op; 109 + struct xen_pcie_aer_op aer_op; 110 + }; 111 + 112 + #endif /* __XEN_PCI_COMMON_H__ */
+7 -1
include/xen/interface/io/xenbus.h
··· 27 27 XenbusStateClosing = 5, /* The device is being closed 28 28 due to an error or an unplug 29 29 event. */ 30 - XenbusStateClosed = 6 30 + XenbusStateClosed = 6, 31 31 32 + /* 33 + * Reconfiguring: The device is being reconfigured. 34 + */ 35 + XenbusStateReconfiguring = 7, 36 + 37 + XenbusStateReconfigured = 8 32 38 }; 33 39 34 40 #endif /* _XEN_PUBLIC_IO_XENBUS_H */
+67
include/xen/interface/physdev.h
··· 106 106 uint32_t vector; 107 107 }; 108 108 109 + #define MAP_PIRQ_TYPE_MSI 0x0 110 + #define MAP_PIRQ_TYPE_GSI 0x1 111 + #define MAP_PIRQ_TYPE_UNKNOWN 0x2 112 + 113 + #define PHYSDEVOP_map_pirq 13 114 + struct physdev_map_pirq { 115 + domid_t domid; 116 + /* IN */ 117 + int type; 118 + /* IN */ 119 + int index; 120 + /* IN or OUT */ 121 + int pirq; 122 + /* IN */ 123 + int bus; 124 + /* IN */ 125 + int devfn; 126 + /* IN */ 127 + int entry_nr; 128 + /* IN */ 129 + uint64_t table_base; 130 + }; 131 + 132 + #define PHYSDEVOP_unmap_pirq 14 133 + struct physdev_unmap_pirq { 134 + domid_t domid; 135 + /* IN */ 136 + int pirq; 137 + }; 138 + 139 + #define PHYSDEVOP_manage_pci_add 15 140 + #define PHYSDEVOP_manage_pci_remove 16 141 + struct physdev_manage_pci { 142 + /* IN */ 143 + uint8_t bus; 144 + uint8_t devfn; 145 + }; 146 + 147 + #define PHYSDEVOP_manage_pci_add_ext 20 148 + struct physdev_manage_pci_ext { 149 + /* IN */ 150 + uint8_t bus; 151 + uint8_t devfn; 152 + unsigned is_extfn; 153 + unsigned is_virtfn; 154 + struct { 155 + uint8_t bus; 156 + uint8_t devfn; 157 + } physfn; 158 + }; 159 + 109 160 /* 110 161 * Argument to physdev_op_compat() hypercall. Superceded by new physdev_op() 111 162 * hypercall since 0x00030202. ··· 170 119 struct physdev_apic apic_op; 171 120 struct physdev_irq irq_op; 172 121 } u; 122 + }; 123 + 124 + #define PHYSDEVOP_setup_gsi 21 125 + struct physdev_setup_gsi { 126 + int gsi; 127 + /* IN */ 128 + uint8_t triggering; 129 + /* IN */ 130 + uint8_t polarity; 131 + /* IN */ 132 + }; 133 + 134 + #define PHYSDEVOP_get_nr_pirqs 22 135 + struct physdev_nr_pirqs { 136 + /* OUT */ 137 + uint32_t nr_pirqs; 173 138 }; 174 139 175 140 /*