aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--MAINTAINERS20
-rw-r--r--arch/x86/Kconfig5
-rw-r--r--arch/x86/include/asm/acpi.h3
-rw-r--r--arch/x86/include/asm/io.h13
-rw-r--r--arch/x86/include/asm/io_apic.h1
-rw-r--r--arch/x86/include/asm/pci.h33
-rw-r--r--arch/x86/include/asm/pci_x86.h1
-rw-r--r--arch/x86/include/asm/x86_init.h9
-rw-r--r--arch/x86/include/asm/xen/pci.h65
-rw-r--r--arch/x86/kernel/acpi/boot.c60
-rw-r--r--arch/x86/kernel/apic/io_apic.c9
-rw-r--r--arch/x86/kernel/x86_init.c7
-rw-r--r--arch/x86/pci/Makefile1
-rw-r--r--arch/x86/pci/common.c17
-rw-r--r--arch/x86/pci/i386.c2
-rw-r--r--arch/x86/pci/xen.c414
-rw-r--r--arch/x86/xen/Kconfig10
-rw-r--r--arch/x86/xen/enlighten.c5
-rw-r--r--arch/x86/xen/mmu.c47
-rw-r--r--arch/x86/xen/pci-swiotlb-xen.c4
-rw-r--r--arch/x86/xen/setup.c5
-rw-r--r--arch/x86/xen/smp.c26
-rw-r--r--drivers/block/xen-blkfront.c2
-rw-r--r--drivers/char/hvc_xen.c98
-rw-r--r--drivers/input/xen-kbdfront.c2
-rw-r--r--drivers/net/xen-netfront.c2
-rw-r--r--drivers/pci/Kconfig21
-rw-r--r--drivers/pci/Makefile2
-rw-r--r--drivers/pci/bus.c1
-rw-r--r--drivers/pci/msi.c14
-rw-r--r--drivers/pci/xen-pcifront.c1148
-rw-r--r--drivers/video/xen-fbfront.c2
-rw-r--r--drivers/xen/Kconfig3
-rw-r--r--drivers/xen/Makefile2
-rw-r--r--drivers/xen/biomerge.c13
-rw-r--r--drivers/xen/events.c509
-rw-r--r--drivers/xen/pci.c117
-rw-r--r--drivers/xen/xenbus/xenbus_client.c2
-rw-r--r--drivers/xen/xenbus/xenbus_probe.c29
-rw-r--r--include/xen/events.h26
-rw-r--r--include/xen/interface/features.h3
-rw-r--r--include/xen/interface/io/pciif.h112
-rw-r--r--include/xen/interface/io/xenbus.h8
-rw-r--r--include/xen/interface/physdev.h67
44 files changed, 2845 insertions, 95 deletions
diff --git a/MAINTAINERS b/MAINTAINERS
index b60de4b2713c..cb8b58020352 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -6595,11 +6595,25 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/mjg59/platform-drivers-x86.
6595S: Maintained 6595S: Maintained
6596F: drivers/platform/x86 6596F: drivers/platform/x86
6597 6597
6598XEN PCI SUBSYSTEM
6599M: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
6600L: xen-devel@lists.xensource.com
6601S: Supported
6602F: arch/x86/pci/*xen*
6603F: drivers/pci/*xen*
6604
6605XEN SWIOTLB SUBSYSTEM
6606M: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
6607L: xen-devel@lists.xensource.com
6608S: Supported
6609F: arch/x86/xen/*swiotlb*
6610F: drivers/xen/*swiotlb*
6611
6598XEN HYPERVISOR INTERFACE 6612XEN HYPERVISOR INTERFACE
6599M: Jeremy Fitzhardinge <jeremy@xensource.com> 6613M: Jeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com>
6600M: Chris Wright <chrisw@sous-sol.org> 6614M: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
6615L: xen-devel@lists.xen.org
6601L: virtualization@lists.osdl.org 6616L: virtualization@lists.osdl.org
6602L: xen-devel@lists.xensource.com
6603S: Supported 6617S: Supported
6604F: arch/x86/xen/ 6618F: arch/x86/xen/
6605F: drivers/*/xen-*front.c 6619F: drivers/*/xen-*front.c
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index e0963f52bfdd..e8327686d3c5 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -1893,6 +1893,11 @@ config PCI_OLPC
1893 def_bool y 1893 def_bool y
1894 depends on PCI && OLPC && (PCI_GOOLPC || PCI_GOANY) 1894 depends on PCI && OLPC && (PCI_GOOLPC || PCI_GOANY)
1895 1895
1896config PCI_XEN
1897 def_bool y
1898 depends on PCI && XEN
1899 select SWIOTLB_XEN
1900
1896config PCI_DOMAINS 1901config PCI_DOMAINS
1897 def_bool y 1902 def_bool y
1898 depends on PCI 1903 depends on PCI
diff --git a/arch/x86/include/asm/acpi.h b/arch/x86/include/asm/acpi.h
index 92091de11113..55d106b5e31b 100644
--- a/arch/x86/include/asm/acpi.h
+++ b/arch/x86/include/asm/acpi.h
@@ -93,6 +93,9 @@ extern u8 acpi_sci_flags;
93extern int acpi_sci_override_gsi; 93extern int acpi_sci_override_gsi;
94void acpi_pic_sci_set_trigger(unsigned int, u16); 94void acpi_pic_sci_set_trigger(unsigned int, u16);
95 95
96extern int (*__acpi_register_gsi)(struct device *dev, u32 gsi,
97 int trigger, int polarity);
98
96static inline void disable_acpi(void) 99static inline void disable_acpi(void)
97{ 100{
98 acpi_disabled = 1; 101 acpi_disabled = 1;
diff --git a/arch/x86/include/asm/io.h b/arch/x86/include/asm/io.h
index f0203f4791a8..072273082528 100644
--- a/arch/x86/include/asm/io.h
+++ b/arch/x86/include/asm/io.h
@@ -41,6 +41,8 @@
41#include <asm-generic/int-ll64.h> 41#include <asm-generic/int-ll64.h>
42#include <asm/page.h> 42#include <asm/page.h>
43 43
44#include <xen/xen.h>
45
44#define build_mmio_read(name, size, type, reg, barrier) \ 46#define build_mmio_read(name, size, type, reg, barrier) \
45static inline type name(const volatile void __iomem *addr) \ 47static inline type name(const volatile void __iomem *addr) \
46{ type ret; asm volatile("mov" size " %1,%0":reg (ret) \ 48{ type ret; asm volatile("mov" size " %1,%0":reg (ret) \
@@ -351,6 +353,17 @@ extern void early_iounmap(void __iomem *addr, unsigned long size);
351extern void fixup_early_ioremap(void); 353extern void fixup_early_ioremap(void);
352extern bool is_early_ioremap_ptep(pte_t *ptep); 354extern bool is_early_ioremap_ptep(pte_t *ptep);
353 355
356#ifdef CONFIG_XEN
357struct bio_vec;
358
359extern bool xen_biovec_phys_mergeable(const struct bio_vec *vec1,
360 const struct bio_vec *vec2);
361
362#define BIOVEC_PHYS_MERGEABLE(vec1, vec2) \
363 (__BIOVEC_PHYS_MERGEABLE(vec1, vec2) && \
364 (!xen_domain() || xen_biovec_phys_mergeable(vec1, vec2)))
365#endif /* CONFIG_XEN */
366
354#define IO_SPACE_LIMIT 0xffff 367#define IO_SPACE_LIMIT 0xffff
355 368
356#endif /* _ASM_X86_IO_H */ 369#endif /* _ASM_X86_IO_H */
diff --git a/arch/x86/include/asm/io_apic.h b/arch/x86/include/asm/io_apic.h
index c8be4566c3d2..a6b28d017c2f 100644
--- a/arch/x86/include/asm/io_apic.h
+++ b/arch/x86/include/asm/io_apic.h
@@ -169,6 +169,7 @@ extern void mask_IO_APIC_setup(struct IO_APIC_route_entry **ioapic_entries);
169extern int restore_IO_APIC_setup(struct IO_APIC_route_entry **ioapic_entries); 169extern int restore_IO_APIC_setup(struct IO_APIC_route_entry **ioapic_entries);
170 170
171extern void probe_nr_irqs_gsi(void); 171extern void probe_nr_irqs_gsi(void);
172extern int get_nr_irqs_gsi(void);
172 173
173extern void setup_ioapic_ids_from_mpc(void); 174extern void setup_ioapic_ids_from_mpc(void);
174 175
diff --git a/arch/x86/include/asm/pci.h b/arch/x86/include/asm/pci.h
index d395540ff894..ca0437c714b2 100644
--- a/arch/x86/include/asm/pci.h
+++ b/arch/x86/include/asm/pci.h
@@ -7,6 +7,7 @@
7#include <linux/string.h> 7#include <linux/string.h>
8#include <asm/scatterlist.h> 8#include <asm/scatterlist.h>
9#include <asm/io.h> 9#include <asm/io.h>
10#include <asm/x86_init.h>
10 11
11#ifdef __KERNEL__ 12#ifdef __KERNEL__
12 13
@@ -94,8 +95,36 @@ static inline void early_quirks(void) { }
94 95
95extern void pci_iommu_alloc(void); 96extern void pci_iommu_alloc(void);
96 97
97/* MSI arch hook */ 98#ifdef CONFIG_PCI_MSI
98#define arch_setup_msi_irqs arch_setup_msi_irqs 99/* MSI arch specific hooks */
100static inline int x86_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
101{
102 return x86_msi.setup_msi_irqs(dev, nvec, type);
103}
104
105static inline void x86_teardown_msi_irqs(struct pci_dev *dev)
106{
107 x86_msi.teardown_msi_irqs(dev);
108}
109
110static inline void x86_teardown_msi_irq(unsigned int irq)
111{
112 x86_msi.teardown_msi_irq(irq);
113}
114#define arch_setup_msi_irqs x86_setup_msi_irqs
115#define arch_teardown_msi_irqs x86_teardown_msi_irqs
116#define arch_teardown_msi_irq x86_teardown_msi_irq
117/* implemented in arch/x86/kernel/apic/io_apic. */
118int native_setup_msi_irqs(struct pci_dev *dev, int nvec, int type);
119void native_teardown_msi_irq(unsigned int irq);
120/* default to the implementation in drivers/lib/msi.c */
121#define HAVE_DEFAULT_MSI_TEARDOWN_IRQS
122void default_teardown_msi_irqs(struct pci_dev *dev);
123#else
124#define native_setup_msi_irqs NULL
125#define native_teardown_msi_irq NULL
126#define default_teardown_msi_irqs NULL
127#endif
99 128
100#define PCI_DMA_BUS_IS_PHYS (dma_ops->is_phys) 129#define PCI_DMA_BUS_IS_PHYS (dma_ops->is_phys)
101 130
diff --git a/arch/x86/include/asm/pci_x86.h b/arch/x86/include/asm/pci_x86.h
index 49c7219826f9..704526734bef 100644
--- a/arch/x86/include/asm/pci_x86.h
+++ b/arch/x86/include/asm/pci_x86.h
@@ -47,6 +47,7 @@ enum pci_bf_sort_state {
47extern unsigned int pcibios_max_latency; 47extern unsigned int pcibios_max_latency;
48 48
49void pcibios_resource_survey(void); 49void pcibios_resource_survey(void);
50void pcibios_set_cache_line_size(void);
50 51
51/* pci-pc.c */ 52/* pci-pc.c */
52 53
diff --git a/arch/x86/include/asm/x86_init.h b/arch/x86/include/asm/x86_init.h
index baa579c8e038..64642ad019fb 100644
--- a/arch/x86/include/asm/x86_init.h
+++ b/arch/x86/include/asm/x86_init.h
@@ -154,9 +154,18 @@ struct x86_platform_ops {
154 int (*i8042_detect)(void); 154 int (*i8042_detect)(void);
155}; 155};
156 156
157struct pci_dev;
158
159struct 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
157extern struct x86_init_ops x86_init; 165extern struct x86_init_ops x86_init;
158extern struct x86_cpuinit_ops x86_cpuinit; 166extern struct x86_cpuinit_ops x86_cpuinit;
159extern struct x86_platform_ops x86_platform; 167extern struct x86_platform_ops x86_platform;
168extern struct x86_msi_ops x86_msi;
160 169
161extern void x86_init_noop(void); 170extern void x86_init_noop(void);
162extern void x86_init_uint_noop(unsigned int unused); 171extern void x86_init_uint_noop(unsigned int unused);
diff --git a/arch/x86/include/asm/xen/pci.h b/arch/x86/include/asm/xen/pci.h
new file mode 100644
index 000000000000..2329b3eaf8d3
--- /dev/null
+++ b/arch/x86/include/asm/xen/pci.h
@@ -0,0 +1,65 @@
1#ifndef _ASM_X86_XEN_PCI_H
2#define _ASM_X86_XEN_PCI_H
3
4#if defined(CONFIG_PCI_XEN)
5extern int __init pci_xen_init(void);
6extern 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)
11static inline int pci_xen_hvm_init(void)
12{
13 return -1;
14}
15#endif
16#if defined(CONFIG_XEN_DOM0)
17void __init xen_setup_pirqs(void);
18#else
19static 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 */
29struct 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
36extern struct xen_pci_frontend_ops *xen_pci_frontend;
37
38static 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}
45static 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}
50static 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}
57static 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 */
diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c
index c05872aa3ce0..71232b941b6c 100644
--- a/arch/x86/kernel/acpi/boot.c
+++ b/arch/x86/kernel/acpi/boot.c
@@ -513,35 +513,62 @@ int acpi_isa_irq_to_gsi(unsigned isa_irq, u32 *gsi)
513 return 0; 513 return 0;
514} 514}
515 515
516/* 516static int acpi_register_gsi_pic(struct device *dev, u32 gsi,
517 * success: return IRQ number (>=0) 517 int trigger, int polarity)
518 * failure: return < 0
519 */
520int acpi_register_gsi(struct device *dev, u32 gsi, int trigger, int polarity)
521{ 518{
522 unsigned int irq;
523 unsigned int plat_gsi = gsi;
524
525#ifdef CONFIG_PCI 519#ifdef CONFIG_PCI
526 /* 520 /*
527 * Make sure all (legacy) PCI IRQs are set as level-triggered. 521 * Make sure all (legacy) PCI IRQs are set as level-triggered.
528 */ 522 */
529 if (acpi_irq_model == ACPI_IRQ_MODEL_PIC) { 523 if (trigger == ACPI_LEVEL_SENSITIVE)
530 if (trigger == ACPI_LEVEL_SENSITIVE) 524 eisa_set_level_irq(gsi);
531 eisa_set_level_irq(gsi);
532 }
533#endif 525#endif
534 526
527 return gsi;
528}
529
530static int acpi_register_gsi_ioapic(struct device *dev, u32 gsi,
531 int trigger, int polarity)
532{
535#ifdef CONFIG_X86_IO_APIC 533#ifdef CONFIG_X86_IO_APIC
536 if (acpi_irq_model == ACPI_IRQ_MODEL_IOAPIC) { 534 gsi = mp_register_gsi(dev, gsi, trigger, polarity);
537 plat_gsi = mp_register_gsi(dev, gsi, trigger, polarity);
538 }
539#endif 535#endif
536
537 return gsi;
538}
539
540int (*__acpi_register_gsi)(struct device *dev, u32 gsi,
541 int trigger, int polarity) = acpi_register_gsi_pic;
542
543/*
544 * success: return IRQ number (>=0)
545 * failure: return < 0
546 */
547int acpi_register_gsi(struct device *dev, u32 gsi, int trigger, int polarity)
548{
549 unsigned int irq;
550 unsigned int plat_gsi = gsi;
551
552 plat_gsi = (*__acpi_register_gsi)(dev, gsi, trigger, polarity);
540 irq = gsi_to_irq(plat_gsi); 553 irq = gsi_to_irq(plat_gsi);
541 554
542 return irq; 555 return irq;
543} 556}
544 557
558void __init acpi_set_irq_model_pic(void)
559{
560 acpi_irq_model = ACPI_IRQ_MODEL_PIC;
561 __acpi_register_gsi = acpi_register_gsi_pic;
562 acpi_ioapic = 0;
563}
564
565void __init acpi_set_irq_model_ioapic(void)
566{
567 acpi_irq_model = ACPI_IRQ_MODEL_IOAPIC;
568 __acpi_register_gsi = acpi_register_gsi_ioapic;
569 acpi_ioapic = 1;
570}
571
545/* 572/*
546 * ACPI based hotplug support for CPU 573 * ACPI based hotplug support for CPU
547 */ 574 */
@@ -1259,8 +1286,7 @@ static void __init acpi_process_madt(void)
1259 */ 1286 */
1260 error = acpi_parse_madt_ioapic_entries(); 1287 error = acpi_parse_madt_ioapic_entries();
1261 if (!error) { 1288 if (!error) {
1262 acpi_irq_model = ACPI_IRQ_MODEL_IOAPIC; 1289 acpi_set_irq_model_ioapic();
1263 acpi_ioapic = 1;
1264 1290
1265 smp_found_config = 1; 1291 smp_found_config = 1;
1266 } 1292 }
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index 8ae808d110f4..0929191d83cf 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -3331,7 +3331,7 @@ static int setup_msi_irq(struct pci_dev *dev, struct msi_desc *msidesc, int irq)
3331 return 0; 3331 return 0;
3332} 3332}
3333 3333
3334int arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type) 3334int native_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
3335{ 3335{
3336 int node, ret, sub_handle, index = 0; 3336 int node, ret, sub_handle, index = 0;
3337 unsigned int irq, irq_want; 3337 unsigned int irq, irq_want;
@@ -3389,7 +3389,7 @@ error:
3389 return ret; 3389 return ret;
3390} 3390}
3391 3391
3392void arch_teardown_msi_irq(unsigned int irq) 3392void native_teardown_msi_irq(unsigned int irq)
3393{ 3393{
3394 destroy_irq(irq); 3394 destroy_irq(irq);
3395} 3395}
@@ -3650,6 +3650,11 @@ void __init probe_nr_irqs_gsi(void)
3650 printk(KERN_DEBUG "nr_irqs_gsi: %d\n", nr_irqs_gsi); 3650 printk(KERN_DEBUG "nr_irqs_gsi: %d\n", nr_irqs_gsi);
3651} 3651}
3652 3652
3653int get_nr_irqs_gsi(void)
3654{
3655 return nr_irqs_gsi;
3656}
3657
3653#ifdef CONFIG_SPARSE_IRQ 3658#ifdef CONFIG_SPARSE_IRQ
3654int __init arch_probe_nr_irqs(void) 3659int __init arch_probe_nr_irqs(void)
3655{ 3660{
diff --git a/arch/x86/kernel/x86_init.c b/arch/x86/kernel/x86_init.c
index cd6da6bf3eca..ceb2911aa439 100644
--- a/arch/x86/kernel/x86_init.c
+++ b/arch/x86/kernel/x86_init.c
@@ -6,10 +6,12 @@
6#include <linux/init.h> 6#include <linux/init.h>
7#include <linux/ioport.h> 7#include <linux/ioport.h>
8#include <linux/module.h> 8#include <linux/module.h>
9#include <linux/pci.h>
9 10
10#include <asm/bios_ebda.h> 11#include <asm/bios_ebda.h>
11#include <asm/paravirt.h> 12#include <asm/paravirt.h>
12#include <asm/pci_x86.h> 13#include <asm/pci_x86.h>
14#include <asm/pci.h>
13#include <asm/mpspec.h> 15#include <asm/mpspec.h>
14#include <asm/setup.h> 16#include <asm/setup.h>
15#include <asm/apic.h> 17#include <asm/apic.h>
@@ -99,3 +101,8 @@ struct x86_platform_ops x86_platform = {
99}; 101};
100 102
101EXPORT_SYMBOL_GPL(x86_platform); 103EXPORT_SYMBOL_GPL(x86_platform);
104struct x86_msi_ops x86_msi = {
105 .setup_msi_irqs = native_setup_msi_irqs,
106 .teardown_msi_irq = native_teardown_msi_irq,
107 .teardown_msi_irqs = default_teardown_msi_irqs,
108};
diff --git a/arch/x86/pci/Makefile b/arch/x86/pci/Makefile
index a0207a7fdf39..effd96e33f16 100644
--- a/arch/x86/pci/Makefile
+++ b/arch/x86/pci/Makefile
@@ -4,6 +4,7 @@ obj-$(CONFIG_PCI_BIOS) += pcbios.o
4obj-$(CONFIG_PCI_MMCONFIG) += mmconfig_$(BITS).o direct.o mmconfig-shared.o 4obj-$(CONFIG_PCI_MMCONFIG) += mmconfig_$(BITS).o direct.o mmconfig-shared.o
5obj-$(CONFIG_PCI_DIRECT) += direct.o 5obj-$(CONFIG_PCI_DIRECT) += direct.o
6obj-$(CONFIG_PCI_OLPC) += olpc.o 6obj-$(CONFIG_PCI_OLPC) += olpc.o
7obj-$(CONFIG_PCI_XEN) += xen.o
7 8
8obj-y += fixup.o 9obj-y += fixup.o
9obj-$(CONFIG_ACPI) += acpi.o 10obj-$(CONFIG_ACPI) += acpi.o
diff --git a/arch/x86/pci/common.c b/arch/x86/pci/common.c
index a0772af64efb..f7c8a399978c 100644
--- a/arch/x86/pci/common.c
+++ b/arch/x86/pci/common.c
@@ -421,16 +421,10 @@ struct pci_bus * __devinit pcibios_scan_root(int busnum)
421 421
422 return bus; 422 return bus;
423} 423}
424 424void __init pcibios_set_cache_line_size(void)
425int __init pcibios_init(void)
426{ 425{
427 struct cpuinfo_x86 *c = &boot_cpu_data; 426 struct cpuinfo_x86 *c = &boot_cpu_data;
428 427
429 if (!raw_pci_ops) {
430 printk(KERN_WARNING "PCI: System does not support PCI\n");
431 return 0;
432 }
433
434 /* 428 /*
435 * Set PCI cacheline size to that of the CPU if the CPU has reported it. 429 * Set PCI cacheline size to that of the CPU if the CPU has reported it.
436 * (For older CPUs that don't support cpuid, we se it to 32 bytes 430 * (For older CPUs that don't support cpuid, we se it to 32 bytes
@@ -445,7 +439,16 @@ int __init pcibios_init(void)
445 pci_dfl_cache_line_size = 32 >> 2; 439 pci_dfl_cache_line_size = 32 >> 2;
446 printk(KERN_DEBUG "PCI: Unknown cacheline size. Setting to 32 bytes\n"); 440 printk(KERN_DEBUG "PCI: Unknown cacheline size. Setting to 32 bytes\n");
447 } 441 }
442}
443
444int __init pcibios_init(void)
445{
446 if (!raw_pci_ops) {
447 printk(KERN_WARNING "PCI: System does not support PCI\n");
448 return 0;
449 }
448 450
451 pcibios_set_cache_line_size();
449 pcibios_resource_survey(); 452 pcibios_resource_survey();
450 453
451 if (pci_bf_sort >= pci_force_bf) 454 if (pci_bf_sort >= pci_force_bf)
diff --git a/arch/x86/pci/i386.c b/arch/x86/pci/i386.c
index 826140af3c3c..c4bb261c106e 100644
--- a/arch/x86/pci/i386.c
+++ b/arch/x86/pci/i386.c
@@ -316,6 +316,8 @@ int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,
316 */ 316 */
317 prot |= _PAGE_CACHE_UC_MINUS; 317 prot |= _PAGE_CACHE_UC_MINUS;
318 318
319 prot |= _PAGE_IOMAP; /* creating a mapping for IO */
320
319 vma->vm_page_prot = __pgprot(prot); 321 vma->vm_page_prot = __pgprot(prot);
320 322
321 if (io_remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff, 323 if (io_remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff,
diff --git a/arch/x86/pci/xen.c b/arch/x86/pci/xen.c
new file mode 100644
index 000000000000..117f5b8daf75
--- /dev/null
+++ b/arch/x86/pci/xen.c
@@ -0,0 +1,414 @@
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
23static 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
59static 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
70struct xen_pci_frontend_ops *xen_pci_frontend;
71EXPORT_SYMBOL_GPL(xen_pci_frontend);
72
73static 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
94static 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
114error_while:
115 unbind_from_irqhandler(irq, NULL);
116error:
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
129static 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
161error_while:
162 unbind_from_irqhandler(irq, NULL);
163error:
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
172static 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
183static void xen_teardown_msi_irq(unsigned int irq)
184{
185 xen_destroy_irq(irq);
186}
187
188static 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
204error:
205 xen_destroy_irq(irq);
206 return ret;
207}
208#endif
209
210static 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
232int __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
257int __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
278static 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
314out:
315 return irq;
316}
317
318static 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
346static __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
373static 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
379static 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
391void __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
diff --git a/arch/x86/xen/Kconfig b/arch/x86/xen/Kconfig
index 90a7f5ad6916..5b54892e4bc3 100644
--- a/arch/x86/xen/Kconfig
+++ b/arch/x86/xen/Kconfig
@@ -13,6 +13,16 @@ config XEN
13 kernel to boot in a paravirtualized environment under the 13 kernel to boot in a paravirtualized environment under the
14 Xen hypervisor. 14 Xen hypervisor.
15 15
16config 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.
23config XEN_PRIVILEGED_GUEST
24 def_bool XEN_DOM0
25
16config XEN_PVHVM 26config XEN_PVHVM
17 def_bool y 27 def_bool y
18 depends on XEN 28 depends on XEN
diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c
index 70ddeaeb1ef3..235c0f4d3861 100644
--- a/arch/x86/xen/enlighten.c
+++ b/arch/x86/xen/enlighten.c
@@ -46,6 +46,7 @@
46#include <asm/paravirt.h> 46#include <asm/paravirt.h>
47#include <asm/apic.h> 47#include <asm/apic.h>
48#include <asm/page.h> 48#include <asm/page.h>
49#include <asm/xen/pci.h>
49#include <asm/xen/hypercall.h> 50#include <asm/xen/hypercall.h>
50#include <asm/xen/hypervisor.h> 51#include <asm/xen/hypervisor.h>
51#include <asm/fixmap.h> 52#include <asm/fixmap.h>
@@ -236,6 +237,7 @@ static __init void xen_init_cpuid_mask(void)
236 cpuid_leaf1_edx_mask = 237 cpuid_leaf1_edx_mask =
237 ~((1 << X86_FEATURE_MCE) | /* disable MCE */ 238 ~((1 << X86_FEATURE_MCE) | /* disable MCE */
238 (1 << X86_FEATURE_MCA) | /* disable MCA */ 239 (1 << X86_FEATURE_MCA) | /* disable MCA */
240 (1 << X86_FEATURE_MTRR) | /* disable MTRR */
239 (1 << X86_FEATURE_ACC)); /* thermal monitoring */ 241 (1 << X86_FEATURE_ACC)); /* thermal monitoring */
240 242
241 if (!xen_initial_domain()) 243 if (!xen_initial_domain())
@@ -1184,6 +1186,7 @@ asmlinkage void __init xen_start_kernel(void)
1184 1186
1185 xen_raw_console_write("mapping kernel into physical memory\n"); 1187 xen_raw_console_write("mapping kernel into physical memory\n");
1186 pgd = xen_setup_kernel_pagetable(pgd, xen_start_info->nr_pages); 1188 pgd = xen_setup_kernel_pagetable(pgd, xen_start_info->nr_pages);
1189 xen_ident_map_ISA();
1187 1190
1188 /* Allocate and initialize top and mid mfn levels for p2m structure */ 1191 /* Allocate and initialize top and mid mfn levels for p2m structure */
1189 xen_build_mfn_list_list(); 1192 xen_build_mfn_list_list();
@@ -1222,6 +1225,8 @@ asmlinkage void __init xen_start_kernel(void)
1222 add_preferred_console("xenboot", 0, NULL); 1225 add_preferred_console("xenboot", 0, NULL);
1223 add_preferred_console("tty", 0, NULL); 1226 add_preferred_console("tty", 0, NULL);
1224 add_preferred_console("hvc", 0, NULL); 1227 add_preferred_console("hvc", 0, NULL);
1228 if (pci_xen)
1229 x86_init.pci.arch_init = pci_xen_init;
1225 } else { 1230 } else {
1226 /* Make sure ACS will be enabled */ 1231 /* Make sure ACS will be enabled */
1227 pci_request_acs(); 1232 pci_request_acs();
diff --git a/arch/x86/xen/mmu.c b/arch/x86/xen/mmu.c
index 9631c90907eb..c237b810b03f 100644
--- a/arch/x86/xen/mmu.c
+++ b/arch/x86/xen/mmu.c
@@ -1975,6 +1975,7 @@ static void *m2v(phys_addr_t maddr)
1975 return __ka(m2p(maddr)); 1975 return __ka(m2p(maddr));
1976} 1976}
1977 1977
1978/* Set the page permissions on an identity-mapped pages */
1978static void set_page_prot(void *addr, pgprot_t prot) 1979static void set_page_prot(void *addr, pgprot_t prot)
1979{ 1980{
1980 unsigned long pfn = __pa(addr) >> PAGE_SHIFT; 1981 unsigned long pfn = __pa(addr) >> PAGE_SHIFT;
@@ -2159,6 +2160,8 @@ __init pgd_t *xen_setup_kernel_pagetable(pgd_t *pgd,
2159} 2160}
2160#endif /* CONFIG_X86_64 */ 2161#endif /* CONFIG_X86_64 */
2161 2162
2163static unsigned char dummy_mapping[PAGE_SIZE] __page_aligned_bss;
2164
2162static void xen_set_fixmap(unsigned idx, phys_addr_t phys, pgprot_t prot) 2165static void xen_set_fixmap(unsigned idx, phys_addr_t phys, pgprot_t prot)
2163{ 2166{
2164 pte_t pte; 2167 pte_t pte;
@@ -2179,15 +2182,28 @@ static void xen_set_fixmap(unsigned idx, phys_addr_t phys, pgprot_t prot)
2179#else 2182#else
2180 case VSYSCALL_LAST_PAGE ... VSYSCALL_FIRST_PAGE: 2183 case VSYSCALL_LAST_PAGE ... VSYSCALL_FIRST_PAGE:
2181#endif 2184#endif
2182#ifdef CONFIG_X86_LOCAL_APIC
2183 case FIX_APIC_BASE: /* maps dummy local APIC */
2184#endif
2185 case FIX_TEXT_POKE0: 2185 case FIX_TEXT_POKE0:
2186 case FIX_TEXT_POKE1: 2186 case FIX_TEXT_POKE1:
2187 /* All local page mappings */ 2187 /* All local page mappings */
2188 pte = pfn_pte(phys, prot); 2188 pte = pfn_pte(phys, prot);
2189 break; 2189 break;
2190 2190
2191#ifdef CONFIG_X86_LOCAL_APIC
2192 case FIX_APIC_BASE: /* maps dummy local APIC */
2193 pte = pfn_pte(PFN_DOWN(__pa(dummy_mapping)), PAGE_KERNEL);
2194 break;
2195#endif
2196
2197#ifdef CONFIG_X86_IO_APIC
2198 case FIX_IO_APIC_BASE_0 ... FIX_IO_APIC_BASE_END:
2199 /*
2200 * We just don't map the IO APIC - all access is via
2201 * hypercalls. Keep the address in the pte for reference.
2202 */
2203 pte = pfn_pte(PFN_DOWN(__pa(dummy_mapping)), PAGE_KERNEL);
2204 break;
2205#endif
2206
2191 case FIX_PARAVIRT_BOOTMAP: 2207 case FIX_PARAVIRT_BOOTMAP:
2192 /* This is an MFN, but it isn't an IO mapping from the 2208 /* This is an MFN, but it isn't an IO mapping from the
2193 IO domain */ 2209 IO domain */
@@ -2212,6 +2228,29 @@ static void xen_set_fixmap(unsigned idx, phys_addr_t phys, pgprot_t prot)
2212#endif 2228#endif
2213} 2229}
2214 2230
2231__init void xen_ident_map_ISA(void)
2232{
2233 unsigned long pa;
2234
2235 /*
2236 * If we're dom0, then linear map the ISA machine addresses into
2237 * the kernel's address space.
2238 */
2239 if (!xen_initial_domain())
2240 return;
2241
2242 xen_raw_printk("Xen: setup ISA identity maps\n");
2243
2244 for (pa = ISA_START_ADDRESS; pa < ISA_END_ADDRESS; pa += PAGE_SIZE) {
2245 pte_t pte = mfn_pte(PFN_DOWN(pa), PAGE_KERNEL_IO);
2246
2247 if (HYPERVISOR_update_va_mapping(PAGE_OFFSET + pa, pte, 0))
2248 BUG();
2249 }
2250
2251 xen_flush_tlb();
2252}
2253
2215static __init void xen_post_allocator_init(void) 2254static __init void xen_post_allocator_init(void)
2216{ 2255{
2217 pv_mmu_ops.set_pte = xen_set_pte; 2256 pv_mmu_ops.set_pte = xen_set_pte;
@@ -2320,6 +2359,8 @@ void __init xen_init_mmu_ops(void)
2320 pv_mmu_ops = xen_mmu_ops; 2359 pv_mmu_ops = xen_mmu_ops;
2321 2360
2322 vmap_lazy_unmap = false; 2361 vmap_lazy_unmap = false;
2362
2363 memset(dummy_mapping, 0xff, PAGE_SIZE);
2323} 2364}
2324 2365
2325/* Protected by xen_reservation_lock. */ 2366/* Protected by xen_reservation_lock. */
diff --git a/arch/x86/xen/pci-swiotlb-xen.c b/arch/x86/xen/pci-swiotlb-xen.c
index 22471001b74c..bfd0632fe65e 100644
--- a/arch/x86/xen/pci-swiotlb-xen.c
+++ b/arch/x86/xen/pci-swiotlb-xen.c
@@ -1,6 +1,7 @@
1/* Glue code to lib/swiotlb-xen.c */ 1/* Glue code to lib/swiotlb-xen.c */
2 2
3#include <linux/dma-mapping.h> 3#include <linux/dma-mapping.h>
4#include <linux/pci.h>
4#include <xen/swiotlb-xen.h> 5#include <xen/swiotlb-xen.h>
5 6
6#include <asm/xen/hypervisor.h> 7#include <asm/xen/hypervisor.h>
@@ -55,6 +56,9 @@ void __init pci_xen_swiotlb_init(void)
55 if (xen_swiotlb) { 56 if (xen_swiotlb) {
56 xen_swiotlb_init(1); 57 xen_swiotlb_init(1);
57 dma_ops = &xen_swiotlb_dma_ops; 58 dma_ops = &xen_swiotlb_dma_ops;
59
60 /* Make sure ACS will be enabled */
61 pci_request_acs();
58 } 62 }
59} 63}
60IOMMU_INIT_FINISH(pci_xen_swiotlb_detect, 64IOMMU_INIT_FINISH(pci_xen_swiotlb_detect,
diff --git a/arch/x86/xen/setup.c b/arch/x86/xen/setup.c
index 105db2501050..b1dbdaa23ecc 100644
--- a/arch/x86/xen/setup.c
+++ b/arch/x86/xen/setup.c
@@ -204,6 +204,9 @@ char * __init xen_memory_setup(void)
204 * Even though this is normal, usable memory under Xen, reserve 204 * Even though this is normal, usable memory under Xen, reserve
205 * ISA memory anyway because too many things think they can poke 205 * ISA memory anyway because too many things think they can poke
206 * about in there. 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 e820_add_region(ISA_START_ADDRESS, ISA_END_ADDRESS - ISA_START_ADDRESS, 211 e820_add_region(ISA_START_ADDRESS, ISA_END_ADDRESS - ISA_START_ADDRESS,
209 E820_RESERVED); 212 E820_RESERVED);
@@ -367,7 +370,5 @@ void __init xen_arch_setup(void)
367 370
368 pm_idle = xen_idle; 371 pm_idle = xen_idle;
369 372
370 paravirt_disable_iospace();
371
372 fiddle_vdso(); 373 fiddle_vdso();
373} 374}
diff --git a/arch/x86/xen/smp.c b/arch/x86/xen/smp.c
index f4d010031465..72a4c7959045 100644
--- a/arch/x86/xen/smp.c
+++ b/arch/x86/xen/smp.c
@@ -28,6 +28,7 @@
28#include <asm/xen/interface.h> 28#include <asm/xen/interface.h>
29#include <asm/xen/hypercall.h> 29#include <asm/xen/hypercall.h>
30 30
31#include <xen/xen.h>
31#include <xen/page.h> 32#include <xen/page.h>
32#include <xen/events.h> 33#include <xen/events.h>
33 34
@@ -156,11 +157,35 @@ static void __init xen_fill_possible_map(void)
156{ 157{
157 int i, rc; 158 int i, rc;
158 159
160 if (xen_initial_domain())
161 return;
162
163 for (i = 0; i < nr_cpu_ids; i++) {
164 rc = HYPERVISOR_vcpu_op(VCPUOP_is_up, i, NULL);
165 if (rc >= 0) {
166 num_processors++;
167 set_cpu_possible(i, true);
168 }
169 }
170}
171
172static void __init xen_filter_cpu_maps(void)
173{
174 int i, rc;
175
176 if (!xen_initial_domain())
177 return;
178
179 num_processors = 0;
180 disabled_cpus = 0;
159 for (i = 0; i < nr_cpu_ids; i++) { 181 for (i = 0; i < nr_cpu_ids; i++) {
160 rc = HYPERVISOR_vcpu_op(VCPUOP_is_up, i, NULL); 182 rc = HYPERVISOR_vcpu_op(VCPUOP_is_up, i, NULL);
161 if (rc >= 0) { 183 if (rc >= 0) {
162 num_processors++; 184 num_processors++;
163 set_cpu_possible(i, true); 185 set_cpu_possible(i, true);
186 } else {
187 set_cpu_possible(i, false);
188 set_cpu_present(i, false);
164 } 189 }
165 } 190 }
166} 191}
@@ -174,6 +199,7 @@ static void __init xen_smp_prepare_boot_cpu(void)
174 old memory can be recycled */ 199 old memory can be recycled */
175 make_lowmem_page_readwrite(xen_initial_gdt); 200 make_lowmem_page_readwrite(xen_initial_gdt);
176 201
202 xen_filter_cpu_maps();
177 xen_setup_vcpu_info_placement(); 203 xen_setup_vcpu_info_placement();
178} 204}
179 205
diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c
index 4b33a18c32e0..06e2812ba124 100644
--- a/drivers/block/xen-blkfront.c
+++ b/drivers/block/xen-blkfront.c
@@ -1112,6 +1112,8 @@ static void blkback_changed(struct xenbus_device *dev,
1112 case XenbusStateInitialising: 1112 case XenbusStateInitialising:
1113 case XenbusStateInitWait: 1113 case XenbusStateInitWait:
1114 case XenbusStateInitialised: 1114 case XenbusStateInitialised:
1115 case XenbusStateReconfiguring:
1116 case XenbusStateReconfigured:
1115 case XenbusStateUnknown: 1117 case XenbusStateUnknown:
1116 case XenbusStateClosed: 1118 case XenbusStateClosed:
1117 break; 1119 break;
diff --git a/drivers/char/hvc_xen.c b/drivers/char/hvc_xen.c
index 6b8e6d18a8e6..3740e327f180 100644
--- a/drivers/char/hvc_xen.c
+++ b/drivers/char/hvc_xen.c
@@ -79,7 +79,7 @@ static int __write_console(const char *data, int len)
79 return sent; 79 return sent;
80} 80}
81 81
82static int write_console(uint32_t vtermno, const char *data, int len) 82static int domU_write_console(uint32_t vtermno, const char *data, int len)
83{ 83{
84 int ret = len; 84 int ret = len;
85 85
@@ -102,7 +102,7 @@ static int write_console(uint32_t vtermno, const char *data, int len)
102 return ret; 102 return ret;
103} 103}
104 104
105static int read_console(uint32_t vtermno, char *buf, int len) 105static int domU_read_console(uint32_t vtermno, char *buf, int len)
106{ 106{
107 struct xencons_interface *intf = xencons_interface(); 107 struct xencons_interface *intf = xencons_interface();
108 XENCONS_RING_IDX cons, prod; 108 XENCONS_RING_IDX cons, prod;
@@ -123,28 +123,62 @@ static int read_console(uint32_t vtermno, char *buf, int len)
123 return recv; 123 return recv;
124} 124}
125 125
126static const struct hv_ops hvc_ops = { 126static struct hv_ops domU_hvc_ops = {
127 .get_chars = read_console, 127 .get_chars = domU_read_console,
128 .put_chars = write_console, 128 .put_chars = domU_write_console,
129 .notifier_add = notifier_add_irq, 129 .notifier_add = notifier_add_irq,
130 .notifier_del = notifier_del_irq, 130 .notifier_del = notifier_del_irq,
131 .notifier_hangup = notifier_hangup_irq, 131 .notifier_hangup = notifier_hangup_irq,
132}; 132};
133 133
134static int __init xen_init(void) 134static 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 */
143static 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
152static 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
160static int __init xen_hvc_init(void)
135{ 161{
136 struct hvc_struct *hp; 162 struct hvc_struct *hp;
163 struct hv_ops *ops;
137 164
138 if (!xen_pv_domain() || 165 if (!xen_pv_domain())
139 xen_initial_domain() ||
140 !xen_start_info->console.domU.evtchn)
141 return -ENODEV; 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 if (xencons_irq < 0) 178 if (xencons_irq < 0)
145 xencons_irq = 0; /* NO_IRQ */ 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 if (IS_ERR(hp)) 182 if (IS_ERR(hp))
149 return PTR_ERR(hp); 183 return PTR_ERR(hp);
150 184
@@ -161,7 +195,7 @@ void xen_console_resume(void)
161 rebind_evtchn_irq(xen_start_info->console.domU.evtchn, xencons_irq); 195 rebind_evtchn_irq(xen_start_info->console.domU.evtchn, xencons_irq);
162} 196}
163 197
164static void __exit xen_fini(void) 198static void __exit xen_hvc_fini(void)
165{ 199{
166 if (hvc) 200 if (hvc)
167 hvc_remove(hvc); 201 hvc_remove(hvc);
@@ -169,29 +203,24 @@ static void __exit xen_fini(void)
169 203
170static int xen_cons_init(void) 204static int xen_cons_init(void)
171{ 205{
206 struct hv_ops *ops;
207
172 if (!xen_pv_domain()) 208 if (!xen_pv_domain())
173 return 0; 209 return 0;
174 210
175 hvc_instantiate(HVC_COOKIE, 0, &hvc_ops); 211 if (xen_initial_domain())
212 ops = &dom0_hvc_ops;
213 else
214 ops = &domU_hvc_ops;
215
216 hvc_instantiate(HVC_COOKIE, 0, ops);
176 return 0; 217 return 0;
177} 218}
178 219
179module_init(xen_init); 220module_init(xen_hvc_init);
180module_exit(xen_fini); 221module_exit(xen_hvc_fini);
181console_initcall(xen_cons_init); 222console_initcall(xen_cons_init);
182 223
183static void raw_console_write(const char *str, int len)
184{
185 while(len > 0) {
186 int rc = HYPERVISOR_console_io(CONSOLEIO_write, len, (char *)str);
187 if (rc <= 0)
188 break;
189
190 str += rc;
191 len -= rc;
192 }
193}
194
195#ifdef CONFIG_EARLY_PRINTK 224#ifdef CONFIG_EARLY_PRINTK
196static void xenboot_write_console(struct console *console, const char *string, 225static void xenboot_write_console(struct console *console, const char *string,
197 unsigned len) 226 unsigned len)
@@ -199,19 +228,22 @@ static void xenboot_write_console(struct console *console, const char *string,
199 unsigned int linelen, off = 0; 228 unsigned int linelen, off = 0;
200 const char *pos; 229 const char *pos;
201 230
202 raw_console_write(string, len); 231 dom0_write_console(0, string, len);
232
233 if (xen_initial_domain())
234 return;
203 235
204 write_console(0, "(early) ", 8); 236 domU_write_console(0, "(early) ", 8);
205 while (off < len && NULL != (pos = strchr(string+off, '\n'))) { 237 while (off < len && NULL != (pos = strchr(string+off, '\n'))) {
206 linelen = pos-string+off; 238 linelen = pos-string+off;
207 if (off + linelen > len) 239 if (off + linelen > len)
208 break; 240 break;
209 write_console(0, string+off, linelen); 241 domU_write_console(0, string+off, linelen);
210 write_console(0, "\r\n", 2); 242 domU_write_console(0, "\r\n", 2);
211 off += linelen + 1; 243 off += linelen + 1;
212 } 244 }
213 if (off < len) 245 if (off < len)
214 write_console(0, string+off, len-off); 246 domU_write_console(0, string+off, len-off);
215} 247}
216 248
217struct console xenboot_console = { 249struct console xenboot_console = {
@@ -223,7 +255,7 @@ struct console xenboot_console = {
223 255
224void xen_raw_console_write(const char *str) 256void xen_raw_console_write(const char *str)
225{ 257{
226 raw_console_write(str, strlen(str)); 258 dom0_write_console(0, str, strlen(str));
227} 259}
228 260
229void xen_raw_printk(const char *fmt, ...) 261void xen_raw_printk(const char *fmt, ...)
diff --git a/drivers/input/xen-kbdfront.c b/drivers/input/xen-kbdfront.c
index ebb11907d402..e0c024db2ca5 100644
--- a/drivers/input/xen-kbdfront.c
+++ b/drivers/input/xen-kbdfront.c
@@ -276,6 +276,8 @@ static void xenkbd_backend_changed(struct xenbus_device *dev,
276 switch (backend_state) { 276 switch (backend_state) {
277 case XenbusStateInitialising: 277 case XenbusStateInitialising:
278 case XenbusStateInitialised: 278 case XenbusStateInitialised:
279 case XenbusStateReconfiguring:
280 case XenbusStateReconfigured:
279 case XenbusStateUnknown: 281 case XenbusStateUnknown:
280 case XenbusStateClosed: 282 case XenbusStateClosed:
281 break; 283 break;
diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c
index 630fb8664768..458bb57914a3 100644
--- a/drivers/net/xen-netfront.c
+++ b/drivers/net/xen-netfront.c
@@ -1610,6 +1610,8 @@ static void netback_changed(struct xenbus_device *dev,
1610 switch (backend_state) { 1610 switch (backend_state) {
1611 case XenbusStateInitialising: 1611 case XenbusStateInitialising:
1612 case XenbusStateInitialised: 1612 case XenbusStateInitialised:
1613 case XenbusStateReconfiguring:
1614 case XenbusStateReconfigured:
1613 case XenbusStateConnected: 1615 case XenbusStateConnected:
1614 case XenbusStateUnknown: 1616 case XenbusStateUnknown:
1615 case XenbusStateClosed: 1617 case XenbusStateClosed:
diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig
index 34ef70d562b2..5b1630e4e9e3 100644
--- a/drivers/pci/Kconfig
+++ b/drivers/pci/Kconfig
@@ -40,6 +40,27 @@ config PCI_STUB
40 40
41 When in doubt, say N. 41 When in doubt, say N.
42 42
43config 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
53config 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
43config HT_IRQ 64config HT_IRQ
44 bool "Interrupts on hypertransport devices" 65 bool "Interrupts on hypertransport devices"
45 default y 66 default y
diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile
index dcd7ace9221e..f01e344cf4bd 100644
--- a/drivers/pci/Makefile
+++ b/drivers/pci/Makefile
@@ -65,4 +65,6 @@ obj-$(CONFIG_PCI_SYSCALL) += syscall.o
65 65
66obj-$(CONFIG_PCI_STUB) += pci-stub.o 66obj-$(CONFIG_PCI_STUB) += pci-stub.o
67 67
68obj-$(CONFIG_XEN_PCIDEV_FRONTEND) += xen-pcifront.o
69
68ccflags-$(CONFIG_PCI_DEBUG) := -DDEBUG 70ccflags-$(CONFIG_PCI_DEBUG) := -DDEBUG
diff --git a/drivers/pci/bus.c b/drivers/pci/bus.c
index 172bf26e0680..5624db8c9ad0 100644
--- a/drivers/pci/bus.c
+++ b/drivers/pci/bus.c
@@ -342,6 +342,7 @@ void pci_walk_bus(struct pci_bus *top, int (*cb)(struct pci_dev *, void *),
342 } 342 }
343 up_read(&pci_bus_sem); 343 up_read(&pci_bus_sem);
344} 344}
345EXPORT_SYMBOL_GPL(pci_walk_bus);
345 346
346EXPORT_SYMBOL(pci_bus_alloc_resource); 347EXPORT_SYMBOL(pci_bus_alloc_resource);
347EXPORT_SYMBOL_GPL(pci_bus_add_device); 348EXPORT_SYMBOL_GPL(pci_bus_add_device);
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
index 5fcf5aec680f..7c24dcef2989 100644
--- a/drivers/pci/msi.c
+++ b/drivers/pci/msi.c
@@ -35,7 +35,12 @@ int arch_msi_check_device(struct pci_dev *dev, int nvec, int type)
35#endif 35#endif
36 36
37#ifndef arch_setup_msi_irqs 37#ifndef arch_setup_msi_irqs
38int 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
43int default_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
39{ 44{
40 struct msi_desc *entry; 45 struct msi_desc *entry;
41 int ret; 46 int ret;
@@ -60,7 +65,12 @@ int arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
60#endif 65#endif
61 66
62#ifndef arch_teardown_msi_irqs 67#ifndef arch_teardown_msi_irqs
63void arch_teardown_msi_irqs(struct pci_dev *dev) 68# define arch_teardown_msi_irqs default_teardown_msi_irqs
69# define HAVE_DEFAULT_MSI_TEARDOWN_IRQS
70#endif
71
72#ifdef HAVE_DEFAULT_MSI_TEARDOWN_IRQS
73void default_teardown_msi_irqs(struct pci_dev *dev)
64{ 74{
65 struct msi_desc *entry; 75 struct msi_desc *entry;
66 76
diff --git a/drivers/pci/xen-pcifront.c b/drivers/pci/xen-pcifront.c
new file mode 100644
index 000000000000..a87c4985326e
--- /dev/null
+++ b/drivers/pci/xen-pcifront.c
@@ -0,0 +1,1148 @@
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
28struct 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
36struct 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
53struct pcifront_sd {
54 int domain;
55 struct pcifront_device *pdev;
56};
57
58static inline struct pcifront_device *
59pcifront_get_pdev(struct pcifront_sd *sd)
60{
61 return sd->pdev;
62}
63
64static 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
72static DEFINE_SPINLOCK(pcifront_dev_lock);
73static struct pcifront_device *pcifront_dev;
74
75static int verbose_request;
76module_param(verbose_request, int, 0644);
77
78static 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
100static 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
109static 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;
170out:
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 */
176static 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 */
215static 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
240struct pci_ops pcifront_bus_ops = {
241 .read = pcifront_bus_read,
242 .write = pcifront_bus_write,
243};
244
245#ifdef CONFIG_PCI_MSI
246static 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
295static 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
314static 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
337static 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
360static 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
367static 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
375static 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 */
379static 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
403static 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
432static 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
487err_out:
488 kfree(bus_entry);
489 kfree(sd);
490
491 return err;
492}
493
494static 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
529static 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
541static 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
561static 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
624static 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
654static 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}
660static 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
679static 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}
691static 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);
726out:
727 return pdev;
728}
729
730static 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
756static 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
779do_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
818out:
819 return err;
820}
821
822static 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
885out:
886 return err;
887}
888
889static 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
907out:
908
909 return err;
910}
911
912static 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
966out:
967 return err;
968}
969
970static 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
1048out:
1049 return err;
1050}
1051
1052static 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
1084static 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
1101out:
1102 return err;
1103}
1104
1105static 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
1114static const struct xenbus_device_id xenpci_ids[] = {
1115 {"pci"},
1116 {""},
1117};
1118
1119static 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
1128static 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
1138static void __exit pcifront_cleanup(void)
1139{
1140 xenbus_unregister_driver(&xenbus_pcifront_driver);
1141 pci_frontend_registrar(0 /* disable */);
1142}
1143module_init(pcifront_init);
1144module_exit(pcifront_cleanup);
1145
1146MODULE_DESCRIPTION("Xen PCI passthrough frontend.");
1147MODULE_LICENSE("GPL");
1148MODULE_ALIAS("xen:pci");
diff --git a/drivers/video/xen-fbfront.c b/drivers/video/xen-fbfront.c
index 7c7f42a12796..428d273be727 100644
--- a/drivers/video/xen-fbfront.c
+++ b/drivers/video/xen-fbfront.c
@@ -631,6 +631,8 @@ static void xenfb_backend_changed(struct xenbus_device *dev,
631 switch (backend_state) { 631 switch (backend_state) {
632 case XenbusStateInitialising: 632 case XenbusStateInitialising:
633 case XenbusStateInitialised: 633 case XenbusStateInitialised:
634 case XenbusStateReconfiguring:
635 case XenbusStateReconfigured:
634 case XenbusStateUnknown: 636 case XenbusStateUnknown:
635 case XenbusStateClosed: 637 case XenbusStateClosed:
636 break; 638 break;
diff --git a/drivers/xen/Kconfig b/drivers/xen/Kconfig
index 60d71e9abe9f..6e6180ccd726 100644
--- a/drivers/xen/Kconfig
+++ b/drivers/xen/Kconfig
@@ -74,6 +74,7 @@ config XEN_PLATFORM_PCI
74 74
75config SWIOTLB_XEN 75config SWIOTLB_XEN
76 def_bool y 76 def_bool y
77 depends on SWIOTLB 77 depends on PCI
78 select SWIOTLB
78 79
79endmenu 80endmenu
diff --git a/drivers/xen/Makefile b/drivers/xen/Makefile
index fcaf838f54be..eb8a78d77d9d 100644
--- a/drivers/xen/Makefile
+++ b/drivers/xen/Makefile
@@ -4,6 +4,7 @@ obj-y += xenbus/
4nostackp := $(call cc-option, -fno-stack-protector) 4nostackp := $(call cc-option, -fno-stack-protector)
5CFLAGS_features.o := $(nostackp) 5CFLAGS_features.o := $(nostackp)
6 6
7obj-$(CONFIG_BLOCK) += biomerge.o
7obj-$(CONFIG_HOTPLUG_CPU) += cpu_hotplug.o 8obj-$(CONFIG_HOTPLUG_CPU) += cpu_hotplug.o
8obj-$(CONFIG_XEN_XENCOMM) += xencomm.o 9obj-$(CONFIG_XEN_XENCOMM) += xencomm.o
9obj-$(CONFIG_XEN_BALLOON) += balloon.o 10obj-$(CONFIG_XEN_BALLOON) += balloon.o
@@ -12,3 +13,4 @@ obj-$(CONFIG_XENFS) += xenfs/
12obj-$(CONFIG_XEN_SYS_HYPERVISOR) += sys-hypervisor.o 13obj-$(CONFIG_XEN_SYS_HYPERVISOR) += sys-hypervisor.o
13obj-$(CONFIG_XEN_PLATFORM_PCI) += platform-pci.o 14obj-$(CONFIG_XEN_PLATFORM_PCI) += platform-pci.o
14obj-$(CONFIG_SWIOTLB_XEN) += swiotlb-xen.o 15obj-$(CONFIG_SWIOTLB_XEN) += swiotlb-xen.o
16obj-$(CONFIG_XEN_DOM0) += pci.o
diff --git a/drivers/xen/biomerge.c b/drivers/xen/biomerge.c
new file mode 100644
index 000000000000..ba6eda4b5143
--- /dev/null
+++ b/drivers/xen/biomerge.c
@@ -0,0 +1,13 @@
1#include <linux/bio.h>
2#include <linux/io.h>
3#include <xen/page.h>
4
5bool 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}
diff --git a/drivers/xen/events.c b/drivers/xen/events.c
index 347f17edad77..97612f548a8e 100644
--- a/drivers/xen/events.c
+++ b/drivers/xen/events.c
@@ -16,7 +16,7 @@
16 * (typically dom0). 16 * (typically dom0).
17 * 2. VIRQs, typically used for timers. These are per-cpu events. 17 * 2. VIRQs, typically used for timers. These are per-cpu events.
18 * 3. IPIs. 18 * 3. IPIs.
19 * 4. Hardware interrupts. Not supported at present. 19 * 4. PIRQs - Hardware interrupts.
20 * 20 *
21 * Jeremy Fitzhardinge <jeremy@xensource.com>, XenSource Inc, 2007 21 * Jeremy Fitzhardinge <jeremy@xensource.com>, XenSource Inc, 2007
22 */ 22 */
@@ -28,12 +28,16 @@
28#include <linux/string.h> 28#include <linux/string.h>
29#include <linux/bootmem.h> 29#include <linux/bootmem.h>
30#include <linux/slab.h> 30#include <linux/slab.h>
31#include <linux/irqnr.h>
32#include <linux/pci.h>
31 33
32#include <asm/desc.h> 34#include <asm/desc.h>
33#include <asm/ptrace.h> 35#include <asm/ptrace.h>
34#include <asm/irq.h> 36#include <asm/irq.h>
35#include <asm/idle.h> 37#include <asm/idle.h>
38#include <asm/io_apic.h>
36#include <asm/sync_bitops.h> 39#include <asm/sync_bitops.h>
40#include <asm/xen/pci.h>
37#include <asm/xen/hypercall.h> 41#include <asm/xen/hypercall.h>
38#include <asm/xen/hypervisor.h> 42#include <asm/xen/hypervisor.h>
39 43
@@ -73,7 +77,8 @@ enum xen_irq_type {
73 * event channel - irq->event channel mapping 77 * event channel - irq->event channel mapping
74 * cpu - cpu this event channel is bound to 78 * cpu - cpu this event channel is bound to
75 * index - type-specific information: 79 * index - type-specific information:
76 * PIRQ - vector, with MSB being "needs EIO" 80 * PIRQ - vector, with MSB being "needs EIO", or physical IRQ of the HVM
81 * guest, or GSI (real passthrough IRQ) of the device.
77 * VIRQ - virq number 82 * VIRQ - virq number
78 * IPI - IPI vector 83 * IPI - IPI vector
79 * EVTCHN - 84 * EVTCHN -
@@ -88,21 +93,30 @@ struct irq_info
88 unsigned short virq; 93 unsigned short virq;
89 enum ipi_vector ipi; 94 enum ipi_vector ipi;
90 struct { 95 struct {
96 unsigned short pirq;
91 unsigned short gsi; 97 unsigned short gsi;
92 unsigned short vector; 98 unsigned char vector;
99 unsigned char flags;
93 } pirq; 100 } pirq;
94 } u; 101 } u;
95}; 102};
103#define PIRQ_NEEDS_EOI (1 << 0)
104#define PIRQ_SHAREABLE (1 << 1)
96 105
97static struct irq_info irq_info[NR_IRQS]; 106static struct irq_info *irq_info;
107static int *pirq_to_irq;
108static int nr_pirqs;
98 109
99static int evtchn_to_irq[NR_EVENT_CHANNELS] = { 110static int *evtchn_to_irq;
100 [0 ... NR_EVENT_CHANNELS-1] = -1
101};
102struct cpu_evtchn_s { 111struct cpu_evtchn_s {
103 unsigned long bits[NR_EVENT_CHANNELS/BITS_PER_LONG]; 112 unsigned long bits[NR_EVENT_CHANNELS/BITS_PER_LONG];
104}; 113};
105static struct cpu_evtchn_s *cpu_evtchn_mask_p; 114
115static __initdata struct cpu_evtchn_s init_evtchn_mask = {
116 .bits[0 ... (NR_EVENT_CHANNELS/BITS_PER_LONG)-1] = ~0ul,
117};
118static struct cpu_evtchn_s *cpu_evtchn_mask_p = &init_evtchn_mask;
119
106static inline unsigned long *cpu_evtchn_mask(int cpu) 120static inline unsigned long *cpu_evtchn_mask(int cpu)
107{ 121{
108 return cpu_evtchn_mask_p[cpu].bits; 122 return cpu_evtchn_mask_p[cpu].bits;
@@ -113,6 +127,7 @@ static inline unsigned long *cpu_evtchn_mask(int cpu)
113 127
114static struct irq_chip xen_dynamic_chip; 128static struct irq_chip xen_dynamic_chip;
115static struct irq_chip xen_percpu_chip; 129static struct irq_chip xen_percpu_chip;
130static struct irq_chip xen_pirq_chip;
116 131
117/* Constructor for packed IRQ information. */ 132/* Constructor for packed IRQ information. */
118static struct irq_info mk_unbound_info(void) 133static struct irq_info mk_unbound_info(void)
@@ -138,11 +153,12 @@ static struct irq_info mk_virq_info(unsigned short evtchn, unsigned short virq)
138 .cpu = 0, .u.virq = virq }; 153 .cpu = 0, .u.virq = virq };
139} 154}
140 155
141static struct irq_info mk_pirq_info(unsigned short evtchn, 156static struct irq_info mk_pirq_info(unsigned short evtchn, unsigned short pirq,
142 unsigned short gsi, unsigned short vector) 157 unsigned short gsi, unsigned short vector)
143{ 158{
144 return (struct irq_info) { .type = IRQT_PIRQ, .evtchn = evtchn, 159 return (struct irq_info) { .type = IRQT_PIRQ, .evtchn = evtchn,
145 .cpu = 0, .u.pirq = { .gsi = gsi, .vector = vector } }; 160 .cpu = 0,
161 .u.pirq = { .pirq = pirq, .gsi = gsi, .vector = vector } };
146} 162}
147 163
148/* 164/*
@@ -184,6 +200,16 @@ static unsigned virq_from_irq(unsigned irq)
184 return info->u.virq; 200 return info->u.virq;
185} 201}
186 202
203static unsigned pirq_from_irq(unsigned irq)
204{
205 struct irq_info *info = info_for_irq(irq);
206
207 BUG_ON(info == NULL);
208 BUG_ON(info->type != IRQT_PIRQ);
209
210 return info->u.pirq.pirq;
211}
212
187static unsigned gsi_from_irq(unsigned irq) 213static unsigned gsi_from_irq(unsigned irq)
188{ 214{
189 struct irq_info *info = info_for_irq(irq); 215 struct irq_info *info = info_for_irq(irq);
@@ -225,6 +251,15 @@ static unsigned int cpu_from_evtchn(unsigned int evtchn)
225 return ret; 251 return ret;
226} 252}
227 253
254static bool pirq_needs_eoi(unsigned irq)
255{
256 struct irq_info *info = info_for_irq(irq);
257
258 BUG_ON(info->type != IRQT_PIRQ);
259
260 return info->u.pirq.flags & PIRQ_NEEDS_EOI;
261}
262
228static inline unsigned long active_evtchns(unsigned int cpu, 263static inline unsigned long active_evtchns(unsigned int cpu,
229 struct shared_info *sh, 264 struct shared_info *sh,
230 unsigned int idx) 265 unsigned int idx)
@@ -336,12 +371,40 @@ static void unmask_evtchn(int port)
336 put_cpu(); 371 put_cpu();
337} 372}
338 373
374static int get_nr_hw_irqs(void)
375{
376 int ret = 1;
377
378#ifdef CONFIG_X86_IO_APIC
379 ret = get_nr_irqs_gsi();
380#endif
381
382 return ret;
383}
384
385/* callers of this function should make sure that PHYSDEVOP_get_nr_pirqs
386 * succeeded otherwise nr_pirqs won't hold the right value */
387static int find_unbound_pirq(void)
388{
389 int i;
390 for (i = nr_pirqs-1; i >= 0; i--) {
391 if (pirq_to_irq[i] < 0)
392 return i;
393 }
394 return -1;
395}
396
339static int find_unbound_irq(void) 397static int find_unbound_irq(void)
340{ 398{
341 struct irq_data *data; 399 struct irq_data *data;
342 int irq, res; 400 int irq, res;
401 int start = get_nr_hw_irqs();
343 402
344 for (irq = 0; irq < nr_irqs; irq++) { 403 if (start == nr_irqs)
404 goto no_irqs;
405
406 /* nr_irqs is a magic value. Must not use it.*/
407 for (irq = nr_irqs-1; irq > start; irq--) {
345 data = irq_get_irq_data(irq); 408 data = irq_get_irq_data(irq);
346 /* only 0->15 have init'd desc; handle irq > 16 */ 409 /* only 0->15 have init'd desc; handle irq > 16 */
347 if (!data) 410 if (!data)
@@ -354,8 +417,8 @@ static int find_unbound_irq(void)
354 return irq; 417 return irq;
355 } 418 }
356 419
357 if (irq == nr_irqs) 420 if (irq == start)
358 panic("No available IRQ to bind to: increase nr_irqs!\n"); 421 goto no_irqs;
359 422
360 res = irq_alloc_desc_at(irq, 0); 423 res = irq_alloc_desc_at(irq, 0);
361 424
@@ -363,6 +426,357 @@ static int find_unbound_irq(void)
363 return -1; 426 return -1;
364 427
365 return irq; 428 return irq;
429
430no_irqs:
431 panic("No available IRQ to bind to: increase nr_irqs!\n");
432}
433
434static bool identity_mapped_irq(unsigned irq)
435{
436 /* identity map all the hardware irqs */
437 return irq < get_nr_hw_irqs();
438}
439
440static void pirq_unmask_notify(int irq)
441{
442 struct physdev_eoi eoi = { .irq = pirq_from_irq(irq) };
443
444 if (unlikely(pirq_needs_eoi(irq))) {
445 int rc = HYPERVISOR_physdev_op(PHYSDEVOP_eoi, &eoi);
446 WARN_ON(rc);
447 }
448}
449
450static void pirq_query_unmask(int irq)
451{
452 struct physdev_irq_status_query irq_status;
453 struct irq_info *info = info_for_irq(irq);
454
455 BUG_ON(info->type != IRQT_PIRQ);
456
457 irq_status.irq = pirq_from_irq(irq);
458 if (HYPERVISOR_physdev_op(PHYSDEVOP_irq_status_query, &irq_status))
459 irq_status.flags = 0;
460
461 info->u.pirq.flags &= ~PIRQ_NEEDS_EOI;
462 if (irq_status.flags & XENIRQSTAT_needs_eoi)
463 info->u.pirq.flags |= PIRQ_NEEDS_EOI;
464}
465
466static bool probing_irq(int irq)
467{
468 struct irq_desc *desc = irq_to_desc(irq);
469
470 return desc && desc->action == NULL;
471}
472
473static unsigned int startup_pirq(unsigned int irq)
474{
475 struct evtchn_bind_pirq bind_pirq;
476 struct irq_info *info = info_for_irq(irq);
477 int evtchn = evtchn_from_irq(irq);
478 int rc;
479
480 BUG_ON(info->type != IRQT_PIRQ);
481
482 if (VALID_EVTCHN(evtchn))
483 goto out;
484
485 bind_pirq.pirq = pirq_from_irq(irq);
486 /* NB. We are happy to share unless we are probing. */
487 bind_pirq.flags = info->u.pirq.flags & PIRQ_SHAREABLE ?
488 BIND_PIRQ__WILL_SHARE : 0;
489 rc = HYPERVISOR_event_channel_op(EVTCHNOP_bind_pirq, &bind_pirq);
490 if (rc != 0) {
491 if (!probing_irq(irq))
492 printk(KERN_INFO "Failed to obtain physical IRQ %d\n",
493 irq);
494 return 0;
495 }
496 evtchn = bind_pirq.port;
497
498 pirq_query_unmask(irq);
499
500 evtchn_to_irq[evtchn] = irq;
501 bind_evtchn_to_cpu(evtchn, 0);
502 info->evtchn = evtchn;
503
504out:
505 unmask_evtchn(evtchn);
506 pirq_unmask_notify(irq);
507
508 return 0;
509}
510
511static void shutdown_pirq(unsigned int irq)
512{
513 struct evtchn_close close;
514 struct irq_info *info = info_for_irq(irq);
515 int evtchn = evtchn_from_irq(irq);
516
517 BUG_ON(info->type != IRQT_PIRQ);
518
519 if (!VALID_EVTCHN(evtchn))
520 return;
521
522 mask_evtchn(evtchn);
523
524 close.port = evtchn;
525 if (HYPERVISOR_event_channel_op(EVTCHNOP_close, &close) != 0)
526 BUG();
527
528 bind_evtchn_to_cpu(evtchn, 0);
529 evtchn_to_irq[evtchn] = -1;
530 info->evtchn = 0;
531}
532
533static void enable_pirq(unsigned int irq)
534{
535 startup_pirq(irq);
536}
537
538static void disable_pirq(unsigned int irq)
539{
540}
541
542static void ack_pirq(unsigned int irq)
543{
544 int evtchn = evtchn_from_irq(irq);
545
546 move_native_irq(irq);
547
548 if (VALID_EVTCHN(evtchn)) {
549 mask_evtchn(evtchn);
550 clear_evtchn(evtchn);
551 }
552}
553
554static void end_pirq(unsigned int irq)
555{
556 int evtchn = evtchn_from_irq(irq);
557 struct irq_desc *desc = irq_to_desc(irq);
558
559 if (WARN_ON(!desc))
560 return;
561
562 if ((desc->status & (IRQ_DISABLED|IRQ_PENDING)) ==
563 (IRQ_DISABLED|IRQ_PENDING)) {
564 shutdown_pirq(irq);
565 } else if (VALID_EVTCHN(evtchn)) {
566 unmask_evtchn(evtchn);
567 pirq_unmask_notify(irq);
568 }
569}
570
571static int find_irq_by_gsi(unsigned gsi)
572{
573 int irq;
574
575 for (irq = 0; irq < nr_irqs; irq++) {
576 struct irq_info *info = info_for_irq(irq);
577
578 if (info == NULL || info->type != IRQT_PIRQ)
579 continue;
580
581 if (gsi_from_irq(irq) == gsi)
582 return irq;
583 }
584
585 return -1;
586}
587
588int xen_allocate_pirq(unsigned gsi, int shareable, char *name)
589{
590 return xen_map_pirq_gsi(gsi, gsi, shareable, name);
591}
592
593/* xen_map_pirq_gsi might allocate irqs from the top down, as a
594 * consequence don't assume that the irq number returned has a low value
595 * or can be used as a pirq number unless you know otherwise.
596 *
597 * One notable exception is when xen_map_pirq_gsi is called passing an
598 * hardware gsi as argument, in that case the irq number returned
599 * matches the gsi number passed as second argument.
600 *
601 * Note: We don't assign an event channel until the irq actually started
602 * up. Return an existing irq if we've already got one for the gsi.
603 */
604int xen_map_pirq_gsi(unsigned pirq, unsigned gsi, int shareable, char *name)
605{
606 int irq = 0;
607 struct physdev_irq irq_op;
608
609 spin_lock(&irq_mapping_update_lock);
610
611 if ((pirq > nr_pirqs) || (gsi > nr_irqs)) {
612 printk(KERN_WARNING "xen_map_pirq_gsi: %s %s is incorrect!\n",
613 pirq > nr_pirqs ? "nr_pirqs" :"",
614 gsi > nr_irqs ? "nr_irqs" : "");
615 goto out;
616 }
617
618 irq = find_irq_by_gsi(gsi);
619 if (irq != -1) {
620 printk(KERN_INFO "xen_map_pirq_gsi: returning irq %d for gsi %u\n",
621 irq, gsi);
622 goto out; /* XXX need refcount? */
623 }
624
625 /* If we are a PV guest, we don't have GSIs (no ACPI passed). Therefore
626 * we are using the !xen_initial_domain() to drop in the function.*/
627 if (identity_mapped_irq(gsi) || (!xen_initial_domain() &&
628 xen_pv_domain())) {
629 irq = gsi;
630 irq_alloc_desc_at(irq, 0);
631 } else
632 irq = find_unbound_irq();
633
634 set_irq_chip_and_handler_name(irq, &xen_pirq_chip,
635 handle_level_irq, name);
636
637 irq_op.irq = irq;
638 irq_op.vector = 0;
639
640 /* Only the privileged domain can do this. For non-priv, the pcifront
641 * driver provides a PCI bus that does the call to do exactly
642 * this in the priv domain. */
643 if (xen_initial_domain() &&
644 HYPERVISOR_physdev_op(PHYSDEVOP_alloc_irq_vector, &irq_op)) {
645 irq_free_desc(irq);
646 irq = -ENOSPC;
647 goto out;
648 }
649
650 irq_info[irq] = mk_pirq_info(0, pirq, gsi, irq_op.vector);
651 irq_info[irq].u.pirq.flags |= shareable ? PIRQ_SHAREABLE : 0;
652 pirq_to_irq[pirq] = irq;
653
654out:
655 spin_unlock(&irq_mapping_update_lock);
656
657 return irq;
658}
659
660#ifdef CONFIG_PCI_MSI
661#include <linux/msi.h>
662#include "../pci/msi.h"
663
664void xen_allocate_pirq_msi(char *name, int *irq, int *pirq)
665{
666 spin_lock(&irq_mapping_update_lock);
667
668 *irq = find_unbound_irq();
669 if (*irq == -1)
670 goto out;
671
672 *pirq = find_unbound_pirq();
673 if (*pirq == -1)
674 goto out;
675
676 set_irq_chip_and_handler_name(*irq, &xen_pirq_chip,
677 handle_level_irq, name);
678
679 irq_info[*irq] = mk_pirq_info(0, *pirq, 0, 0);
680 pirq_to_irq[*pirq] = *irq;
681
682out:
683 spin_unlock(&irq_mapping_update_lock);
684}
685
686int xen_create_msi_irq(struct pci_dev *dev, struct msi_desc *msidesc, int type)
687{
688 int irq = -1;
689 struct physdev_map_pirq map_irq;
690 int rc;
691 int pos;
692 u32 table_offset, bir;
693
694 memset(&map_irq, 0, sizeof(map_irq));
695 map_irq.domid = DOMID_SELF;
696 map_irq.type = MAP_PIRQ_TYPE_MSI;
697 map_irq.index = -1;
698 map_irq.pirq = -1;
699 map_irq.bus = dev->bus->number;
700 map_irq.devfn = dev->devfn;
701
702 if (type == PCI_CAP_ID_MSIX) {
703 pos = pci_find_capability(dev, PCI_CAP_ID_MSIX);
704
705 pci_read_config_dword(dev, msix_table_offset_reg(pos),
706 &table_offset);
707 bir = (u8)(table_offset & PCI_MSIX_FLAGS_BIRMASK);
708
709 map_irq.table_base = pci_resource_start(dev, bir);
710 map_irq.entry_nr = msidesc->msi_attrib.entry_nr;
711 }
712
713 spin_lock(&irq_mapping_update_lock);
714
715 irq = find_unbound_irq();
716
717 if (irq == -1)
718 goto out;
719
720 rc = HYPERVISOR_physdev_op(PHYSDEVOP_map_pirq, &map_irq);
721 if (rc) {
722 printk(KERN_WARNING "xen map irq failed %d\n", rc);
723
724 irq_free_desc(irq);
725
726 irq = -1;
727 goto out;
728 }
729 irq_info[irq] = mk_pirq_info(0, map_irq.pirq, 0, map_irq.index);
730
731 set_irq_chip_and_handler_name(irq, &xen_pirq_chip,
732 handle_level_irq,
733 (type == PCI_CAP_ID_MSIX) ? "msi-x":"msi");
734
735out:
736 spin_unlock(&irq_mapping_update_lock);
737 return irq;
738}
739#endif
740
741int xen_destroy_irq(int irq)
742{
743 struct irq_desc *desc;
744 struct physdev_unmap_pirq unmap_irq;
745 struct irq_info *info = info_for_irq(irq);
746 int rc = -ENOENT;
747
748 spin_lock(&irq_mapping_update_lock);
749
750 desc = irq_to_desc(irq);
751 if (!desc)
752 goto out;
753
754 if (xen_initial_domain()) {
755 unmap_irq.pirq = info->u.pirq.gsi;
756 unmap_irq.domid = DOMID_SELF;
757 rc = HYPERVISOR_physdev_op(PHYSDEVOP_unmap_pirq, &unmap_irq);
758 if (rc) {
759 printk(KERN_WARNING "unmap irq failed %d\n", rc);
760 goto out;
761 }
762 }
763 irq_info[irq] = mk_unbound_info();
764
765 irq_free_desc(irq);
766
767out:
768 spin_unlock(&irq_mapping_update_lock);
769 return rc;
770}
771
772int xen_vector_from_irq(unsigned irq)
773{
774 return vector_from_irq(irq);
775}
776
777int xen_gsi_from_irq(unsigned irq)
778{
779 return gsi_from_irq(irq);
366} 780}
367 781
368int bind_evtchn_to_irq(unsigned int evtchn) 782int bind_evtchn_to_irq(unsigned int evtchn)
@@ -425,7 +839,7 @@ static int bind_ipi_to_irq(unsigned int ipi, unsigned int cpu)
425} 839}
426 840
427 841
428static int bind_virq_to_irq(unsigned int virq, unsigned int cpu) 842int bind_virq_to_irq(unsigned int virq, unsigned int cpu)
429{ 843{
430 struct evtchn_bind_virq bind_virq; 844 struct evtchn_bind_virq bind_virq;
431 int evtchn, irq; 845 int evtchn, irq;
@@ -928,7 +1342,7 @@ void xen_clear_irq_pending(int irq)
928 if (VALID_EVTCHN(evtchn)) 1342 if (VALID_EVTCHN(evtchn))
929 clear_evtchn(evtchn); 1343 clear_evtchn(evtchn);
930} 1344}
931 1345EXPORT_SYMBOL(xen_clear_irq_pending);
932void xen_set_irq_pending(int irq) 1346void xen_set_irq_pending(int irq)
933{ 1347{
934 int evtchn = evtchn_from_irq(irq); 1348 int evtchn = evtchn_from_irq(irq);
@@ -948,9 +1362,9 @@ bool xen_test_irq_pending(int irq)
948 return ret; 1362 return ret;
949} 1363}
950 1364
951/* Poll waiting for an irq to become pending. In the usual case, the 1365/* Poll waiting for an irq to become pending with timeout. In the usual case,
952 irq will be disabled so it won't deliver an interrupt. */ 1366 * the irq will be disabled so it won't deliver an interrupt. */
953void xen_poll_irq(int irq) 1367void xen_poll_irq_timeout(int irq, u64 timeout)
954{ 1368{
955 evtchn_port_t evtchn = evtchn_from_irq(irq); 1369 evtchn_port_t evtchn = evtchn_from_irq(irq);
956 1370
@@ -958,13 +1372,20 @@ void xen_poll_irq(int irq)
958 struct sched_poll poll; 1372 struct sched_poll poll;
959 1373
960 poll.nr_ports = 1; 1374 poll.nr_ports = 1;
961 poll.timeout = 0; 1375 poll.timeout = timeout;
962 set_xen_guest_handle(poll.ports, &evtchn); 1376 set_xen_guest_handle(poll.ports, &evtchn);
963 1377
964 if (HYPERVISOR_sched_op(SCHEDOP_poll, &poll) != 0) 1378 if (HYPERVISOR_sched_op(SCHEDOP_poll, &poll) != 0)
965 BUG(); 1379 BUG();
966 } 1380 }
967} 1381}
1382EXPORT_SYMBOL(xen_poll_irq_timeout);
1383/* Poll waiting for an irq to become pending. In the usual case, the
1384 * irq will be disabled so it won't deliver an interrupt. */
1385void xen_poll_irq(int irq)
1386{
1387 xen_poll_irq_timeout(irq, 0 /* no timeout */);
1388}
968 1389
969void xen_irq_resume(void) 1390void xen_irq_resume(void)
970{ 1391{
@@ -1001,6 +1422,26 @@ static struct irq_chip xen_dynamic_chip __read_mostly = {
1001 .retrigger = retrigger_dynirq, 1422 .retrigger = retrigger_dynirq,
1002}; 1423};
1003 1424
1425static struct irq_chip xen_pirq_chip __read_mostly = {
1426 .name = "xen-pirq",
1427
1428 .startup = startup_pirq,
1429 .shutdown = shutdown_pirq,
1430
1431 .enable = enable_pirq,
1432 .unmask = enable_pirq,
1433
1434 .disable = disable_pirq,
1435 .mask = disable_pirq,
1436
1437 .ack = ack_pirq,
1438 .end = end_pirq,
1439
1440 .set_affinity = set_affinity_irq,
1441
1442 .retrigger = retrigger_dynirq,
1443};
1444
1004static struct irq_chip xen_percpu_chip __read_mostly = { 1445static struct irq_chip xen_percpu_chip __read_mostly = {
1005 .name = "xen-percpu", 1446 .name = "xen-percpu",
1006 1447
@@ -1051,11 +1492,32 @@ void xen_callback_vector(void) {}
1051 1492
1052void __init xen_init_IRQ(void) 1493void __init xen_init_IRQ(void)
1053{ 1494{
1054 int i; 1495 int i, rc;
1496 struct physdev_nr_pirqs op_nr_pirqs;
1055 1497
1056 cpu_evtchn_mask_p = kcalloc(nr_cpu_ids, sizeof(struct cpu_evtchn_s), 1498 cpu_evtchn_mask_p = kcalloc(nr_cpu_ids, sizeof(struct cpu_evtchn_s),
1057 GFP_KERNEL); 1499 GFP_KERNEL);
1058 BUG_ON(cpu_evtchn_mask_p == NULL); 1500 irq_info = kcalloc(nr_irqs, sizeof(*irq_info), GFP_KERNEL);
1501
1502 rc = HYPERVISOR_physdev_op(PHYSDEVOP_get_nr_pirqs, &op_nr_pirqs);
1503 if (rc < 0) {
1504 nr_pirqs = nr_irqs;
1505 if (rc != -ENOSYS)
1506 printk(KERN_WARNING "PHYSDEVOP_get_nr_pirqs returned rc=%d\n", rc);
1507 } else {
1508 if (xen_pv_domain() && !xen_initial_domain())
1509 nr_pirqs = max((int)op_nr_pirqs.nr_pirqs, nr_irqs);
1510 else
1511 nr_pirqs = op_nr_pirqs.nr_pirqs;
1512 }
1513 pirq_to_irq = kcalloc(nr_pirqs, sizeof(*pirq_to_irq), GFP_KERNEL);
1514 for (i = 0; i < nr_pirqs; i++)
1515 pirq_to_irq[i] = -1;
1516
1517 evtchn_to_irq = kcalloc(NR_EVENT_CHANNELS, sizeof(*evtchn_to_irq),
1518 GFP_KERNEL);
1519 for (i = 0; i < NR_EVENT_CHANNELS; i++)
1520 evtchn_to_irq[i] = -1;
1059 1521
1060 init_evtchn_cpu_bindings(); 1522 init_evtchn_cpu_bindings();
1061 1523
@@ -1066,7 +1528,12 @@ void __init xen_init_IRQ(void)
1066 if (xen_hvm_domain()) { 1528 if (xen_hvm_domain()) {
1067 xen_callback_vector(); 1529 xen_callback_vector();
1068 native_init_IRQ(); 1530 native_init_IRQ();
1531 /* pci_xen_hvm_init must be called after native_init_IRQ so that
1532 * __acpi_register_gsi can point at the right function */
1533 pci_xen_hvm_init();
1069 } else { 1534 } else {
1070 irq_ctx_init(smp_processor_id()); 1535 irq_ctx_init(smp_processor_id());
1536 if (xen_initial_domain())
1537 xen_setup_pirqs();
1071 } 1538 }
1072} 1539}
diff --git a/drivers/xen/pci.c b/drivers/xen/pci.c
new file mode 100644
index 000000000000..cef4bafc07dc
--- /dev/null
+++ b/drivers/xen/pci.c
@@ -0,0 +1,117 @@
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
29static 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
70static 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
85static 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
105struct notifier_block device_nb = {
106 .notifier_call = xen_pci_notifier,
107};
108
109static 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
117arch_initcall(register_xen_pci_notifier);
diff --git a/drivers/xen/xenbus/xenbus_client.c b/drivers/xen/xenbus/xenbus_client.c
index 7e49527189b6..cdacf923e073 100644
--- a/drivers/xen/xenbus/xenbus_client.c
+++ b/drivers/xen/xenbus/xenbus_client.c
@@ -50,6 +50,8 @@ const char *xenbus_strstate(enum xenbus_state state)
50 [ XenbusStateConnected ] = "Connected", 50 [ XenbusStateConnected ] = "Connected",
51 [ XenbusStateClosing ] = "Closing", 51 [ XenbusStateClosing ] = "Closing",
52 [ XenbusStateClosed ] = "Closed", 52 [ XenbusStateClosed ] = "Closed",
53 [XenbusStateReconfiguring] = "Reconfiguring",
54 [XenbusStateReconfigured] = "Reconfigured",
53 }; 55 };
54 return (state < ARRAY_SIZE(name)) ? name[state] : "INVALID"; 56 return (state < ARRAY_SIZE(name)) ? name[state] : "INVALID";
55} 57}
diff --git a/drivers/xen/xenbus/xenbus_probe.c b/drivers/xen/xenbus/xenbus_probe.c
index 132939f36020..deb9c4ba3a93 100644
--- a/drivers/xen/xenbus/xenbus_probe.c
+++ b/drivers/xen/xenbus/xenbus_probe.c
@@ -803,6 +803,7 @@ device_initcall(xenbus_probe_initcall);
803static int __init xenbus_init(void) 803static int __init xenbus_init(void)
804{ 804{
805 int err = 0; 805 int err = 0;
806 unsigned long page = 0;
806 807
807 DPRINTK(""); 808 DPRINTK("");
808 809
@@ -823,7 +824,31 @@ static int __init xenbus_init(void)
823 * Domain0 doesn't have a store_evtchn or store_mfn yet. 824 * Domain0 doesn't have a store_evtchn or store_mfn yet.
824 */ 825 */
825 if (xen_initial_domain()) { 826 if (xen_initial_domain()) {
826 /* dom0 not yet supported */ 827 struct evtchn_alloc_unbound alloc_unbound;
828
829 /* Allocate Xenstore page */
830 page = get_zeroed_page(GFP_KERNEL);
831 if (!page)
832 goto out_error;
833
834 xen_store_mfn = xen_start_info->store_mfn =
835 pfn_to_mfn(virt_to_phys((void *)page) >>
836 PAGE_SHIFT);
837
838 /* Next allocate a local port which xenstored can bind to */
839 alloc_unbound.dom = DOMID_SELF;
840 alloc_unbound.remote_dom = 0;
841
842 err = HYPERVISOR_event_channel_op(EVTCHNOP_alloc_unbound,
843 &alloc_unbound);
844 if (err == -ENOSYS)
845 goto out_error;
846
847 BUG_ON(err);
848 xen_store_evtchn = xen_start_info->store_evtchn =
849 alloc_unbound.port;
850
851 xen_store_interface = mfn_to_virt(xen_store_mfn);
827 } else { 852 } else {
828 if (xen_hvm_domain()) { 853 if (xen_hvm_domain()) {
829 uint64_t v = 0; 854 uint64_t v = 0;
@@ -869,6 +894,8 @@ static int __init xenbus_init(void)
869 bus_unregister(&xenbus_frontend.bus); 894 bus_unregister(&xenbus_frontend.bus);
870 895
871 out_error: 896 out_error:
897 if (page != 0)
898 free_page(page);
872 return err; 899 return err;
873} 900}
874 901
diff --git a/include/xen/events.h b/include/xen/events.h
index a15d93262e30..646dd17d3aa4 100644
--- a/include/xen/events.h
+++ b/include/xen/events.h
@@ -12,6 +12,7 @@ int bind_evtchn_to_irqhandler(unsigned int evtchn,
12 irq_handler_t handler, 12 irq_handler_t handler,
13 unsigned long irqflags, const char *devname, 13 unsigned long irqflags, const char *devname,
14 void *dev_id); 14 void *dev_id);
15int bind_virq_to_irq(unsigned int virq, unsigned int cpu);
15int bind_virq_to_irqhandler(unsigned int virq, unsigned int cpu, 16int bind_virq_to_irqhandler(unsigned int virq, unsigned int cpu,
16 irq_handler_t handler, 17 irq_handler_t handler,
17 unsigned long irqflags, const char *devname, 18 unsigned long irqflags, const char *devname,
@@ -53,6 +54,10 @@ bool xen_test_irq_pending(int irq);
53 irq will be disabled so it won't deliver an interrupt. */ 54 irq will be disabled so it won't deliver an interrupt. */
54void xen_poll_irq(int irq); 55void xen_poll_irq(int irq);
55 56
57/* Poll waiting for an irq to become pending with a timeout. In the usual case,
58 * the irq will be disabled so it won't deliver an interrupt. */
59void xen_poll_irq_timeout(int irq, u64 timeout);
60
56/* Determine the IRQ which is bound to an event channel */ 61/* Determine the IRQ which is bound to an event channel */
57unsigned irq_from_evtchn(unsigned int evtchn); 62unsigned irq_from_evtchn(unsigned int evtchn);
58 63
@@ -63,4 +68,25 @@ int xen_set_callback_via(uint64_t via);
63void xen_evtchn_do_upcall(struct pt_regs *regs); 68void xen_evtchn_do_upcall(struct pt_regs *regs);
64void xen_hvm_evtchn_do_upcall(void); 69void xen_hvm_evtchn_do_upcall(void);
65 70
71/* Allocate an irq for a physical interrupt, given a gsi. "Legacy"
72 * GSIs are identity mapped; others are dynamically allocated as
73 * usual. */
74int xen_allocate_pirq(unsigned gsi, int shareable, char *name);
75int xen_map_pirq_gsi(unsigned pirq, unsigned gsi, int shareable, char *name);
76
77#ifdef CONFIG_PCI_MSI
78/* Allocate an irq and a pirq to be used with MSIs. */
79void xen_allocate_pirq_msi(char *name, int *irq, int *pirq);
80int xen_create_msi_irq(struct pci_dev *dev, struct msi_desc *msidesc, int type);
81#endif
82
83/* De-allocates the above mentioned physical interrupt. */
84int xen_destroy_irq(int irq);
85
86/* Return vector allocated to pirq */
87int xen_vector_from_irq(unsigned pirq);
88
89/* Return gsi allocated to pirq */
90int xen_gsi_from_irq(unsigned pirq);
91
66#endif /* _XEN_EVENTS_H */ 92#endif /* _XEN_EVENTS_H */
diff --git a/include/xen/interface/features.h b/include/xen/interface/features.h
index 70d2563ab166..b6ca39a069d8 100644
--- a/include/xen/interface/features.h
+++ b/include/xen/interface/features.h
@@ -47,6 +47,9 @@
47/* x86: pvclock algorithm is safe to use on HVM */ 47/* x86: pvclock algorithm is safe to use on HVM */
48#define XENFEAT_hvm_safe_pvclock 9 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#define XENFEAT_NR_SUBMAPS 1 53#define XENFEAT_NR_SUBMAPS 1
51 54
52#endif /* __XEN_PUBLIC_FEATURES_H__ */ 55#endif /* __XEN_PUBLIC_FEATURES_H__ */
diff --git a/include/xen/interface/io/pciif.h b/include/xen/interface/io/pciif.h
new file mode 100644
index 000000000000..d9922ae36eb5
--- /dev/null
+++ b/include/xen/interface/io/pciif.h
@@ -0,0 +1,112 @@
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
65struct xen_msix_entry {
66 uint16_t vector;
67 uint16_t entry;
68};
69struct 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*/
94struct 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};
105struct 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__ */
diff --git a/include/xen/interface/io/xenbus.h b/include/xen/interface/io/xenbus.h
index 46508c7fa399..9fda532973a5 100644
--- a/include/xen/interface/io/xenbus.h
+++ b/include/xen/interface/io/xenbus.h
@@ -27,8 +27,14 @@ enum xenbus_state
27 XenbusStateClosing = 5, /* The device is being closed 27 XenbusStateClosing = 5, /* The device is being closed
28 due to an error or an unplug 28 due to an error or an unplug
29 event. */ 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#endif /* _XEN_PUBLIC_IO_XENBUS_H */ 40#endif /* _XEN_PUBLIC_IO_XENBUS_H */
diff --git a/include/xen/interface/physdev.h b/include/xen/interface/physdev.h
index cd6939147cb6..2b2c66c3df00 100644
--- a/include/xen/interface/physdev.h
+++ b/include/xen/interface/physdev.h
@@ -106,6 +106,57 @@ struct physdev_irq {
106 uint32_t vector; 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
114struct 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
133struct 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
141struct physdev_manage_pci {
142 /* IN */
143 uint8_t bus;
144 uint8_t devfn;
145};
146
147#define PHYSDEVOP_manage_pci_add_ext 20
148struct 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 * Argument to physdev_op_compat() hypercall. Superceded by new physdev_op() 161 * Argument to physdev_op_compat() hypercall. Superceded by new physdev_op()
111 * hypercall since 0x00030202. 162 * hypercall since 0x00030202.
@@ -121,6 +172,22 @@ struct physdev_op {
121 } u; 172 } u;
122}; 173};
123 174
175#define PHYSDEVOP_setup_gsi 21
176struct physdev_setup_gsi {
177 int gsi;
178 /* IN */
179 uint8_t triggering;
180 /* IN */
181 uint8_t polarity;
182 /* IN */
183};
184
185#define PHYSDEVOP_get_nr_pirqs 22
186struct physdev_nr_pirqs {
187 /* OUT */
188 uint32_t nr_pirqs;
189};
190
124/* 191/*
125 * Notify that some PIRQ-bound event channels have been unmasked. 192 * Notify that some PIRQ-bound event channels have been unmasked.
126 * ** This command is obsolete since interface version 0x00030202 and is ** 193 * ** This command is obsolete since interface version 0x00030202 and is **