[PATCH 1/1] drivers:hv: Allow for MMIO claims that span ACPI _CRS records

2015-11-09 Thread jakeo
From: Jake Oshins 

This patch makes 16GB GPUs work in Hyper-V VMs, since, for
compatibility reasons, the Hyper-V BIOS lists MMIO ranges in 2GB
chunks in its root bus's _CRS object.

Signed-off-by: Jake Oshins 
---
 drivers/hv/vmbus_drv.c | 16 
 1 file changed, 16 insertions(+)

diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c
index c89d0e5..aef5fae 100644
--- a/drivers/hv/vmbus_drv.c
+++ b/drivers/hv/vmbus_drv.c
@@ -1075,12 +1075,28 @@ static acpi_status vmbus_walk_resources(struct 
acpi_resource *res, void *ctx)
new_res->start = start;
new_res->end = end;
 
+   /*
+* Stick ranges from higher in address space at the front of the list.
+* If two ranges are adjacent, merge them.
+*/
do {
if (!*old_res) {
*old_res = new_res;
break;
}
 
+   if (((*old_res)->end + 1) == new_res->start) {
+   (*old_res)->end = new_res->end;
+   kfree(new_res);
+   break;
+   }
+
+   if ((*old_res)->start == new_res->end + 1) {
+   (*old_res)->start = new_res->start;
+   kfree(new_res);
+   break;
+   }
+
if ((*old_res)->end < new_res->start) {
new_res->sibling = *old_res;
if (prev_res)
-- 
1.9.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH v7 6/7] drivers:hv: Define the channel type of Hyper-V PCI Express pass-through

2015-12-04 Thread jakeo
From: Jake Oshins 

This defines the channel type for PCI front-ends in Hyper-V VMs.

Signed-off-by: Jake Oshins 
---
 include/linux/hyperv.h | 11 +++
 1 file changed, 11 insertions(+)

diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h
index 24d0b65..c9a9eed 100644
--- a/include/linux/hyperv.h
+++ b/include/linux/hyperv.h
@@ -1141,6 +1141,17 @@ u64 hv_do_hypercall(u64 control, void *input, void 
*output);
}
 
 /*
+ * PCI Express Pass Through
+ * {44C4F61D--4400-9D52-802E27EDE19F}
+ */
+
+#define HV_PCIE_GUID \
+   .guid = { \
+   0x1D, 0xF6, 0xC4, 0x44, 0x44, 0x44, 0x00, 0x44, \
+   0x9D, 0x52, 0x80, 0x2E, 0x27, 0xED, 0xE1, 0x9F \
+   }
+
+/*
  * Common header for Hyper-V ICs
  */
 
-- 
1.9.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH v7 2/7] drivers:hv: Export hv_do_hypercall()

2015-12-04 Thread jakeo
From: Jake Oshins 

This patch exposes the function that hv_vmbus.ko uses to make hypercalls.
This is necessary for retargeting an interrupt when it is given a new
affinity and vector.

Signed-off-by: Jake Oshins 
---
 drivers/hv/hv.c   | 20 ++--
 drivers/hv/hyperv_vmbus.h |  2 +-
 include/linux/hyperv.h|  1 +
 3 files changed, 12 insertions(+), 11 deletions(-)

diff --git a/drivers/hv/hv.c b/drivers/hv/hv.c
index 6341be8..7a06933 100644
--- a/drivers/hv/hv.c
+++ b/drivers/hv/hv.c
@@ -89,9 +89,9 @@ static int query_hypervisor_info(void)
 }
 
 /*
- * do_hypercall- Invoke the specified hypercall
+ * hv_do_hypercall- Invoke the specified hypercall
  */
-static u64 do_hypercall(u64 control, void *input, void *output)
+u64 hv_do_hypercall(u64 control, void *input, void *output)
 {
u64 input_address = (input) ? virt_to_phys(input) : 0;
u64 output_address = (output) ? virt_to_phys(output) : 0;
@@ -132,6 +132,7 @@ static u64 do_hypercall(u64 control, void *input, void 
*output)
return hv_status_lo | ((u64)hv_status_hi << 32);
 #endif /* !x86_64 */
 }
+EXPORT_SYMBOL_GPL(hv_do_hypercall);
 
 #ifdef CONFIG_X86_64
 static cycle_t read_hv_clock_tsc(struct clocksource *arg)
@@ -315,7 +316,7 @@ int hv_post_message(union hv_connection_id connection_id,
 {
 
struct hv_input_post_message *aligned_msg;
-   u16 status;
+   u64 status;
 
if (payload_size > HV_MESSAGE_PAYLOAD_BYTE_COUNT)
return -EMSGSIZE;
@@ -329,11 +330,10 @@ int hv_post_message(union hv_connection_id connection_id,
aligned_msg->payload_size = payload_size;
memcpy((void *)aligned_msg->payload, payload, payload_size);
 
-   status = do_hypercall(HVCALL_POST_MESSAGE, aligned_msg, NULL)
-   & 0x;
+   status = hv_do_hypercall(HVCALL_POST_MESSAGE, aligned_msg, NULL);
 
put_cpu();
-   return status;
+   return status & 0x;
 }
 
 
@@ -343,13 +343,13 @@ int hv_post_message(union hv_connection_id connection_id,
  *
  * This involves a hypercall.
  */
-u16 hv_signal_event(void *con_id)
+int hv_signal_event(void *con_id)
 {
-   u16 status;
+   u64 status;
 
-   status = (do_hypercall(HVCALL_SIGNAL_EVENT, con_id, NULL) & 0x);
+   status = hv_do_hypercall(HVCALL_SIGNAL_EVENT, con_id, NULL);
 
-   return status;
+   return status & 0x;
 }
 
 static int hv_ce_set_next_event(unsigned long delta,
diff --git a/drivers/hv/hyperv_vmbus.h b/drivers/hv/hyperv_vmbus.h
index 3782636..cc2fb53 100644
--- a/drivers/hv/hyperv_vmbus.h
+++ b/drivers/hv/hyperv_vmbus.h
@@ -582,7 +582,7 @@ extern int hv_post_message(union hv_connection_id 
connection_id,
 enum hv_message_type message_type,
 void *payload, size_t payload_size);
 
-extern u16 hv_signal_event(void *con_id);
+extern int hv_signal_event(void *con_id);
 
 extern int hv_synic_alloc(void);
 
diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h
index fddb3e0..24d0b65 100644
--- a/include/linux/hyperv.h
+++ b/include/linux/hyperv.h
@@ -984,6 +984,7 @@ int vmbus_allocate_mmio(struct resource **new, struct 
hv_device *device_obj,
bool fb_overlap_ok);
 
 int vmbus_cpu_number_to_vp_number(int cpu_number);
+u64 hv_do_hypercall(u64 control, void *input, void *output);
 
 /**
  * VMBUS_DEVICE - macro used to describe a specific hyperv vmbus device
-- 
1.9.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH v7 0/7] PCI: hv: New paravirtual PCI front-end for Hyper-V VMs

2015-12-04 Thread jakeo
From: Jake Oshins 

This version of the patch series incorporates feedback from Gerry Liu.

First, export functions that allow correlating Hyper-V virtual processors
and Linux cpus, along with the means for invoking a hypercall that targets
interrupts at chosen vectors on specific cpus.

Second, mark various parts of IRQ domain related code as exported, so that
this PCI front-end can implement an IRQ domain as part of a module.  (The
alternative would be to pull all tyhis into the kernel, which would pull
in a lot of other Hyper-V related code, as this IRQ domain depends on
vmbus.ko.)

Third, modify PCI so that new root PCI buses can be marked with an associated
fwnode_handle, and so that root PCI buses can look up their associated IRQ
domain by that handle.

Fourth, introduce a new driver, hv_pcifront, which exposes root PCI buses in
a Hyper-V VM.  These root PCI buses expose real PCIe device, or PCI Virtual
Functions.

Jake Oshins (7):
  drivers:hv: Export a function that maps Linux CPU num onto Hyper-V
proc num
  drivers:hv: Export hv_do_hypercall()
  PCI: Make it possible to implement a PCI MSI IRQ Domain in a module.
  PCI: Add fwnode_handle to pci_sysdata
  PCI: irqdomain: Look up IRQ domain by fwnode_handle
  drivers:hv: Define the channel type of Hyper-V PCI Express
pass-through
  PCI: hv: New paravirtual PCI front-end for Hyper-V VMs

 MAINTAINERS|1 +
 arch/x86/include/asm/msi.h |6 +
 arch/x86/include/asm/pci.h |   15 +
 arch/x86/kernel/apic/msi.c |8 +-
 arch/x86/kernel/apic/vector.c  |2 +
 drivers/hv/hv.c|   20 +-
 drivers/hv/hyperv_vmbus.h  |2 +-
 drivers/hv/vmbus_drv.c |   17 +
 drivers/pci/Kconfig|7 +
 drivers/pci/host/Makefile  |1 +
 drivers/pci/host/hv_pcifront.c | 2241 
 drivers/pci/msi.c  |4 +
 drivers/pci/probe.c|   14 +
 include/asm-generic/pci.h  |4 +
 include/linux/hyperv.h |   14 +
 kernel/irq/chip.c  |1 +
 kernel/irq/irqdomain.c |4 +
 17 files changed, 2347 insertions(+), 14 deletions(-)
 create mode 100644 drivers/pci/host/hv_pcifront.c

-- 
1.9.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH v7 5/7] PCI: irqdomain: Look up IRQ domain by fwnode_handle

2015-12-04 Thread jakeo
From: Jake Oshins 

This patch adds a second way of finding an IRQ domain associated with
a root PCI bus.  After looking to see if one can be found through
the OF tree, it attempts to look up the IRQ domain through an
fwnode_handle stored in the pci_sysdata struct.

Signed-off-by: Jake Oshins 
---
 drivers/pci/probe.c | 14 ++
 1 file changed, 14 insertions(+)

diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index edb1984..8f3d056 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -673,6 +673,20 @@ static struct irq_domain 
*pci_host_bridge_msi_domain(struct pci_bus *bus)
 */
d = pci_host_bridge_of_msi_domain(bus);
 
+#ifdef CONFIG_PCI_MSI_IRQ_DOMAIN
+   /*
+* If no IRQ domain was found via the OF tree, try looking it up
+* directly through the fwnode_handle.
+*/
+   if (!d) {
+   struct fwnode_handle *fwnode = pci_root_bus_fwnode(bus);
+
+   if (fwnode)
+   d = irq_find_matching_fwnode(fwnode,
+DOMAIN_BUS_PCI_MSI);
+   }
+#endif
+
return d;
 }
 
-- 
1.9.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH v7 3/7] PCI: Make it possible to implement a PCI MSI IRQ Domain in a module.

2015-12-04 Thread jakeo
From: Jake Oshins 

The Linux kernel already has the concpet of IRQ domain, wherein a
component can expose a set of IRQs which are managed by a particular
interrupt controller chip or other subsystem. The PCI driver exposes
the notion of an IRQ domain for Message-Signaled Interrupts (MSI) from
PCI Express devices. This patch exposes the functions which are
necessary for making an MSI IRQ domain within a module.

Signed-off-by: Jake Oshins 
---
 arch/x86/include/asm/msi.h| 6 ++
 arch/x86/kernel/apic/msi.c| 8 +---
 arch/x86/kernel/apic/vector.c | 2 ++
 drivers/pci/msi.c | 4 
 kernel/irq/chip.c | 1 +
 kernel/irq/irqdomain.c| 4 
 6 files changed, 22 insertions(+), 3 deletions(-)

diff --git a/arch/x86/include/asm/msi.h b/arch/x86/include/asm/msi.h
index 93724cc..eb4b09b 100644
--- a/arch/x86/include/asm/msi.h
+++ b/arch/x86/include/asm/msi.h
@@ -1,7 +1,13 @@
 #ifndef _ASM_X86_MSI_H
 #define _ASM_X86_MSI_H
 #include 
+#include 
 
 typedef struct irq_alloc_info msi_alloc_info_t;
 
+int pci_msi_prepare(struct irq_domain *domain, struct device *dev, int nvec,
+   msi_alloc_info_t *arg);
+
+void pci_msi_set_desc(msi_alloc_info_t *arg, struct msi_desc *desc);
+
 #endif /* _ASM_X86_MSI_H */
diff --git a/arch/x86/kernel/apic/msi.c b/arch/x86/kernel/apic/msi.c
index 5f1feb6..ade2532 100644
--- a/arch/x86/kernel/apic/msi.c
+++ b/arch/x86/kernel/apic/msi.c
@@ -96,8 +96,8 @@ static irq_hw_number_t pci_msi_get_hwirq(struct 
msi_domain_info *info,
return arg->msi_hwirq;
 }
 
-static int pci_msi_prepare(struct irq_domain *domain, struct device *dev,
-  int nvec, msi_alloc_info_t *arg)
+int pci_msi_prepare(struct irq_domain *domain, struct device *dev, int nvec,
+   msi_alloc_info_t *arg)
 {
struct pci_dev *pdev = to_pci_dev(dev);
struct msi_desc *desc = first_pci_msi_entry(pdev);
@@ -113,11 +113,13 @@ static int pci_msi_prepare(struct irq_domain *domain, 
struct device *dev,
 
return 0;
 }
+EXPORT_SYMBOL_GPL(pci_msi_prepare);
 
-static void pci_msi_set_desc(msi_alloc_info_t *arg, struct msi_desc *desc)
+void pci_msi_set_desc(msi_alloc_info_t *arg, struct msi_desc *desc)
 {
arg->msi_hwirq = pci_msi_domain_calc_hwirq(arg->msi_dev, desc);
 }
+EXPORT_SYMBOL_GPL(pci_msi_set_desc);
 
 static struct msi_domain_ops pci_msi_domain_ops = {
.get_hwirq  = pci_msi_get_hwirq,
diff --git a/arch/x86/kernel/apic/vector.c b/arch/x86/kernel/apic/vector.c
index 861bc59..908cb37 100644
--- a/arch/x86/kernel/apic/vector.c
+++ b/arch/x86/kernel/apic/vector.c
@@ -29,6 +29,7 @@ struct apic_chip_data {
 };
 
 struct irq_domain *x86_vector_domain;
+EXPORT_SYMBOL_GPL(x86_vector_domain);
 static DEFINE_RAW_SPINLOCK(vector_lock);
 static cpumask_var_t vector_cpumask;
 static struct irq_chip lapic_controller;
@@ -66,6 +67,7 @@ struct irq_cfg *irqd_cfg(struct irq_data *irq_data)
 
return data ? &data->cfg : NULL;
 }
+EXPORT_SYMBOL_GPL(irqd_cfg);
 
 struct irq_cfg *irq_cfg(unsigned int irq)
 {
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
index 53e4632..3915a99 100644
--- a/drivers/pci/msi.c
+++ b/drivers/pci/msi.c
@@ -257,6 +257,7 @@ void pci_msi_mask_irq(struct irq_data *data)
 {
msi_set_mask_bit(data, 1);
 }
+EXPORT_SYMBOL_GPL(pci_msi_mask_irq);
 
 /**
  * pci_msi_unmask_irq - Generic irq chip callback to unmask PCI/MSI interrupts
@@ -266,6 +267,7 @@ void pci_msi_unmask_irq(struct irq_data *data)
 {
msi_set_mask_bit(data, 0);
 }
+EXPORT_SYMBOL_GPL(pci_msi_unmask_irq);
 
 void default_restore_msi_irqs(struct pci_dev *dev)
 {
@@ -1126,6 +1128,7 @@ struct pci_dev *msi_desc_to_pci_dev(struct msi_desc *desc)
 {
return to_pci_dev(desc->dev);
 }
+EXPORT_SYMBOL(msi_desc_to_pci_dev);
 
 void *msi_desc_to_pci_sysdata(struct msi_desc *desc)
 {
@@ -1285,6 +1288,7 @@ struct irq_domain *pci_msi_create_irq_domain(struct 
fwnode_handle *fwnode,
domain->bus_token = DOMAIN_BUS_PCI_MSI;
return domain;
 }
+EXPORT_SYMBOL_GPL(pci_msi_create_irq_domain);
 
 /**
  * pci_msi_domain_alloc_irqs - Allocate interrupts for @dev in @domain
diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c
index 05e29de..5797909 100644
--- a/kernel/irq/chip.c
+++ b/kernel/irq/chip.c
@@ -950,6 +950,7 @@ void irq_chip_ack_parent(struct irq_data *data)
data = data->parent_data;
data->chip->irq_ack(data);
 }
+EXPORT_SYMBOL_GPL(irq_chip_ack_parent);
 
 /**
  * irq_chip_mask_parent - Mask the parent interrupt
diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
index 22aa961..aa6ac44 100644
--- a/kernel/irq/irqdomain.c
+++ b/kernel/irq/irqdomain.c
@@ -60,6 +60,7 @@ struct fwnode_handle *irq_domain_alloc_fwnode(void *data)
fwid->fwnode.type = FWNODE_IRQCHIP;
return &fwid->fwnode;
 }
+EXPORT_SYMBOL_GPL(irq_domain_alloc_fwnode);
 
 /**
  * irq_domain_free_fwnode - Free a non-OF-backed fwnode_handle
@@ -77,6 +78,7 @@ void irq_domain_free_fwnode(struct fwnode_

[PATCH v7 4/7] PCI: Add fwnode_handle to pci_sysdata

2015-12-04 Thread jakeo
From: Jake Oshins 

This patch adds an fwnode_handle to struct pci_sysdata, which is
used by the next patch in the series when trying to locate an
IRQ domain associated with a root PCI bus.

Signed-off-by: Jake Oshins 
---
 arch/x86/include/asm/pci.h | 15 +++
 include/asm-generic/pci.h  |  4 
 2 files changed, 19 insertions(+)

diff --git a/arch/x86/include/asm/pci.h b/arch/x86/include/asm/pci.h
index 4625943..6fc3c7c 100644
--- a/arch/x86/include/asm/pci.h
+++ b/arch/x86/include/asm/pci.h
@@ -20,6 +20,9 @@ struct pci_sysdata {
 #ifdef CONFIG_X86_64
void*iommu; /* IOMMU private data */
 #endif
+#ifdef CONFIG_PCI_MSI_IRQ_DOMAIN
+   void*fwnode;/* IRQ domain for MSI assignment */
+#endif
 };
 
 extern int pci_routeirq;
@@ -32,6 +35,7 @@ extern int noioapicreroute;
 static inline int pci_domain_nr(struct pci_bus *bus)
 {
struct pci_sysdata *sd = bus->sysdata;
+
return sd->domain;
 }
 
@@ -41,6 +45,17 @@ static inline int pci_proc_domain(struct pci_bus *bus)
 }
 #endif
 
+#ifdef CONFIG_PCI_MSI_IRQ_DOMAIN
+static inline void *_pci_root_bus_fwnode(struct pci_bus *bus)
+{
+   struct pci_sysdata *sd = bus->sysdata;
+
+   return sd->fwnode;
+}
+
+#define pci_root_bus_fwnode_pci_root_bus_fwnode
+#endif
+
 /* Can be used to override the logic in pci_scan_bus for skipping
already-configured bus numbers - to be used for buggy BIOSes
or architectures with incomplete PCI setup by the loader */
diff --git a/include/asm-generic/pci.h b/include/asm-generic/pci.h
index f24bc51..4092886 100644
--- a/include/asm-generic/pci.h
+++ b/include/asm-generic/pci.h
@@ -21,4 +21,8 @@ static inline int pci_get_legacy_ide_irq(struct pci_dev *dev, 
int channel)
 #define PCI_DMA_BUS_IS_PHYS(1)
 #endif
 
+#ifndef pci_root_bus_fwnode
+#define pci_root_bus_fwnode(bus)   ((void)(bus), NULL)
+#endif
+
 #endif /* _ASM_GENERIC_PCI_H */
-- 
1.9.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH v7 1/7] drivers:hv: Export a function that maps Linux CPU num onto Hyper-V proc num

2015-12-04 Thread jakeo
From: Jake Oshins 

This patch exposes the mapping between Linux CPU number and Hyper-V
virtual processor number. This is necessary because the hypervisor needs
to know which virtual processor to target when making a mapping in the
Interrupt Redirection Table in the I/O MMU.

Signed-off-by: Jake Oshins 
---
 drivers/hv/vmbus_drv.c | 17 +
 include/linux/hyperv.h |  2 ++
 2 files changed, 19 insertions(+)

diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c
index f19b6f7..c89d0e5 100644
--- a/drivers/hv/vmbus_drv.c
+++ b/drivers/hv/vmbus_drv.c
@@ -1191,6 +1191,23 @@ int vmbus_allocate_mmio(struct resource **new, struct 
hv_device *device_obj,
 }
 EXPORT_SYMBOL_GPL(vmbus_allocate_mmio);
 
+/**
+ * vmbus_cpu_number_to_vp_number() - Map CPU to VP.
+ * @cpu_number: CPU number in Linux terms
+ *
+ * This function returns the mapping between the Linux processor
+ * number and the hypervisor's virtual processor number, useful
+ * in making hypercalls and such that talk about specific
+ * processors.
+ *
+ * Return: Virtual processor number in Hyper-V terms
+ */
+int vmbus_cpu_number_to_vp_number(int cpu_number)
+{
+   return hv_context.vp_index[cpu_number];
+}
+EXPORT_SYMBOL_GPL(vmbus_cpu_number_to_vp_number);
+
 static int vmbus_acpi_add(struct acpi_device *device)
 {
acpi_status result;
diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h
index 8fdc17b..fddb3e0 100644
--- a/include/linux/hyperv.h
+++ b/include/linux/hyperv.h
@@ -983,6 +983,8 @@ int vmbus_allocate_mmio(struct resource **new, struct 
hv_device *device_obj,
resource_size_t size, resource_size_t align,
bool fb_overlap_ok);
 
+int vmbus_cpu_number_to_vp_number(int cpu_number);
+
 /**
  * VMBUS_DEVICE - macro used to describe a specific hyperv vmbus device
  *
-- 
1.9.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH v7 7/7] PCI: hv: New paravirtual PCI front-end for Hyper-V VMs

2015-12-04 Thread jakeo
From: Jake Oshins 

This patch introduces a new driver which exposes a root PCI bus whenever a
PCI Express device is passed through to a guest VM under Hyper-V. The
device can be single- or multi-function. The interrupts for the devices
are managed by an IRQ domain, implemented within the driver.

Signed-off-by: Jake Oshins 
---
 MAINTAINERS|1 +
 drivers/pci/Kconfig|7 +
 drivers/pci/host/Makefile  |1 +
 drivers/pci/host/hv_pcifront.c | 2241 
 4 files changed, 2250 insertions(+)
 create mode 100644 drivers/pci/host/hv_pcifront.c

diff --git a/MAINTAINERS b/MAINTAINERS
index f3de001..9fd37fc 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -5126,6 +5126,7 @@ F:arch/x86/kernel/cpu/mshyperv.c
 F: drivers/hid/hid-hyperv.c
 F: drivers/hv/
 F: drivers/input/serio/hyperv-keyboard.c
+F: drivers/pci/host/hv_pcifront.c
 F: drivers/net/hyperv/
 F: drivers/scsi/storvsc_drv.c
 F: drivers/video/fbdev/hyperv_fb.c
diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig
index 73de4ef..9b82d93 100644
--- a/drivers/pci/Kconfig
+++ b/drivers/pci/Kconfig
@@ -118,4 +118,11 @@ config PCI_LABEL
def_bool y if (DMI || ACPI)
select NLS
 
+config HYPERV_VPCI
+tristate "Hyper-V PCI Frontend"
+depends on PCI && X86 && HYPERV && PCI_MSI && PCI_MSI_IRQ_DOMAIN
+help
+  The PCI device frontend driver allows the kernel to import arbitrary
+  PCI devices from a PCI backend to support PCI driver domains.
+
 source "drivers/pci/host/Kconfig"
diff --git a/drivers/pci/host/Makefile b/drivers/pci/host/Makefile
index 9d4d3c6..d9abd2a 100644
--- a/drivers/pci/host/Makefile
+++ b/drivers/pci/host/Makefile
@@ -2,6 +2,7 @@ obj-$(CONFIG_PCIE_DW) += pcie-designware.o
 obj-$(CONFIG_PCI_DRA7XX) += pci-dra7xx.o
 obj-$(CONFIG_PCI_EXYNOS) += pci-exynos.o
 obj-$(CONFIG_PCI_IMX6) += pci-imx6.o
+obj-$(CONFIG_HYPERV_VPCI) += hv_pcifront.o
 obj-$(CONFIG_PCI_MVEBU) += pci-mvebu.o
 obj-$(CONFIG_PCI_TEGRA) += pci-tegra.o
 obj-$(CONFIG_PCI_RCAR_GEN2) += pci-rcar-gen2.o
diff --git a/drivers/pci/host/hv_pcifront.c b/drivers/pci/host/hv_pcifront.c
new file mode 100644
index 000..6023dea
--- /dev/null
+++ b/drivers/pci/host/hv_pcifront.c
@@ -0,0 +1,2241 @@
+/*
+ * Copyright (c) Microsoft Corporation.
+ *
+ * Author:
+ *   Jake Oshins 
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+ * NON INFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+/*
+ * Protocol versions. The low word is the minor version, the high word the 
major
+ * version.
+ */
+
+#define PCI_MAKE_VERSION(major, minor) ((__u32)(((major) << 16) | (major)))
+#define PCI_MAJOR_VERSION(version) ((__u32)(version) >> 16)
+#define PCI_MINOR_VERSION(version) ((__u32)(version) & 0xff)
+
+enum {
+   PCI_PROTOCOL_VERSION_1_1 = PCI_MAKE_VERSION(1, 1),
+   PCI_PROTOCOL_VERSION_CURRENT = PCI_PROTOCOL_VERSION_1_1
+};
+
+#define PCI_CONFIG_MMIO_LENGTH 0x2000
+#define MAX_SUPPORTED_MSI_MESSAGES 0x400
+
+/*
+ * Message Types
+ */
+
+enum pci_message_type {
+   /*
+* Version 1.1
+*/
+   PCI_MESSAGE_BASE= 0x4249,
+   PCI_BUS_RELATIONS   = PCI_MESSAGE_BASE + 0,
+   PCI_QUERY_BUS_RELATIONS = PCI_MESSAGE_BASE + 1,
+   PCI_POWER_STATE_CHANGE  = PCI_MESSAGE_BASE + 4,
+   PCI_QUERY_RESOURCE_REQUIREMENTS = PCI_MESSAGE_BASE + 5,
+   PCI_QUERY_RESOURCE_RESOURCES= PCI_MESSAGE_BASE + 6,
+   PCI_BUS_D0ENTRY = PCI_MESSAGE_BASE + 7,
+   PCI_BUS_D0EXIT  = PCI_MESSAGE_BASE + 8,
+   PCI_READ_BLOCK  = PCI_MESSAGE_BASE + 9,
+   PCI_WRITE_BLOCK = PCI_MESSAGE_BASE + 0xA,
+   PCI_EJECT   = PCI_MESSAGE_BASE + 0xB,
+   PCI_QUERY_STOP  = PCI_MESSAGE_BASE + 0xC,
+   PCI_REENABLE= PCI_MESSAGE_BASE + 0xD,
+   PCI_QUERY_STOP_FAILED   = PCI_MESSAGE_BASE + 0xE,
+   PCI_EJECTION_COMPLETE   = PCI_MESSAGE_BASE + 0xF,
+   PCI_RESOURCES_ASSIGNED  = PCI_MESSAGE_BASE + 0x10,
+   PCI_RESOURCES_RELEASED  = PCI_MESSAGE_BASE + 0x11,
+   PCI_INVALIDATE_BLOCK= PCI_MESSAGE_BASE + 0x12,
+   PCI_QUERY_PROTOCOL_VERSION  = PCI_MESSAGE_BASE + 0x13,
+   PCI_CREATE_INTERRUPT_MESSAGE= PCI_MESSAGE_BASE + 0x14,
+   PCI_DELETE_INTERRUPT_MESSAGE= 

[PATCH v8 1/7] drivers:hv: Export a function that maps Linux CPU num onto Hyper-V proc num

2015-12-09 Thread jakeo
From: Jake Oshins 

This patch exposes the mapping between Linux CPU number and Hyper-V
virtual processor number. This is necessary because the hypervisor needs
to know which virtual processor to target when making a mapping in the
Interrupt Redirection Table in the I/O MMU.

Signed-off-by: Jake Oshins 
---
 drivers/hv/vmbus_drv.c | 17 +
 include/linux/hyperv.h |  2 ++
 2 files changed, 19 insertions(+)

diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c
index f19b6f7..c89d0e5 100644
--- a/drivers/hv/vmbus_drv.c
+++ b/drivers/hv/vmbus_drv.c
@@ -1191,6 +1191,23 @@ int vmbus_allocate_mmio(struct resource **new, struct 
hv_device *device_obj,
 }
 EXPORT_SYMBOL_GPL(vmbus_allocate_mmio);
 
+/**
+ * vmbus_cpu_number_to_vp_number() - Map CPU to VP.
+ * @cpu_number: CPU number in Linux terms
+ *
+ * This function returns the mapping between the Linux processor
+ * number and the hypervisor's virtual processor number, useful
+ * in making hypercalls and such that talk about specific
+ * processors.
+ *
+ * Return: Virtual processor number in Hyper-V terms
+ */
+int vmbus_cpu_number_to_vp_number(int cpu_number)
+{
+   return hv_context.vp_index[cpu_number];
+}
+EXPORT_SYMBOL_GPL(vmbus_cpu_number_to_vp_number);
+
 static int vmbus_acpi_add(struct acpi_device *device)
 {
acpi_status result;
diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h
index 8fdc17b..fddb3e0 100644
--- a/include/linux/hyperv.h
+++ b/include/linux/hyperv.h
@@ -983,6 +983,8 @@ int vmbus_allocate_mmio(struct resource **new, struct 
hv_device *device_obj,
resource_size_t size, resource_size_t align,
bool fb_overlap_ok);
 
+int vmbus_cpu_number_to_vp_number(int cpu_number);
+
 /**
  * VMBUS_DEVICE - macro used to describe a specific hyperv vmbus device
  *
-- 
1.9.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH v8 5/7] PCI: irqdomain: Look up IRQ domain by fwnode_handle

2015-12-09 Thread jakeo
From: Jake Oshins 

This patch adds a second way of finding an IRQ domain associated with
a root PCI bus.  After looking to see if one can be found through
the OF tree, it attempts to look up the IRQ domain through an
fwnode_handle stored in the pci_sysdata struct.

Signed-off-by: Jake Oshins 
---
 drivers/pci/probe.c | 14 ++
 1 file changed, 14 insertions(+)

diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index 750f907..c6369dd 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -674,6 +674,20 @@ static struct irq_domain 
*pci_host_bridge_msi_domain(struct pci_bus *bus)
 */
d = pci_host_bridge_of_msi_domain(bus);
 
+#ifdef CONFIG_PCI_MSI_IRQ_DOMAIN
+   /*
+* If no IRQ domain was found via the OF tree, try looking it up
+* directly through the fwnode_handle.
+*/
+   if (!d) {
+   struct fwnode_handle *fwnode = pci_root_bus_fwnode(bus);
+
+   if (fwnode)
+   d = irq_find_matching_fwnode(fwnode,
+DOMAIN_BUS_PCI_MSI);
+   }
+#endif
+
return d;
 }
 
-- 
1.9.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH v8 4/7] PCI: Add fwnode_handle to pci_sysdata

2015-12-09 Thread jakeo
From: Jake Oshins 

This patch adds an fwnode_handle to struct pci_sysdata, which is
used by the next patch in the series when trying to locate an
IRQ domain associated with a root PCI bus.

Signed-off-by: Jake Oshins 
---
 arch/x86/include/asm/pci.h | 15 +++
 drivers/pci/probe.c|  1 +
 include/linux/pci.h|  4 
 3 files changed, 20 insertions(+)

diff --git a/arch/x86/include/asm/pci.h b/arch/x86/include/asm/pci.h
index 4625943..6fc3c7c 100644
--- a/arch/x86/include/asm/pci.h
+++ b/arch/x86/include/asm/pci.h
@@ -20,6 +20,9 @@ struct pci_sysdata {
 #ifdef CONFIG_X86_64
void*iommu; /* IOMMU private data */
 #endif
+#ifdef CONFIG_PCI_MSI_IRQ_DOMAIN
+   void*fwnode;/* IRQ domain for MSI assignment */
+#endif
 };
 
 extern int pci_routeirq;
@@ -32,6 +35,7 @@ extern int noioapicreroute;
 static inline int pci_domain_nr(struct pci_bus *bus)
 {
struct pci_sysdata *sd = bus->sysdata;
+
return sd->domain;
 }
 
@@ -41,6 +45,17 @@ static inline int pci_proc_domain(struct pci_bus *bus)
 }
 #endif
 
+#ifdef CONFIG_PCI_MSI_IRQ_DOMAIN
+static inline void *_pci_root_bus_fwnode(struct pci_bus *bus)
+{
+   struct pci_sysdata *sd = bus->sysdata;
+
+   return sd->fwnode;
+}
+
+#define pci_root_bus_fwnode_pci_root_bus_fwnode
+#endif
+
 /* Can be used to override the logic in pci_scan_bus for skipping
already-configured bus numbers - to be used for buggy BIOSes
or architectures with incomplete PCI setup by the loader */
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index edb1984..750f907 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -15,6 +15,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include "pci.h"
 
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 6ae25aa..b414422 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -1517,6 +1517,10 @@ static inline int pci_get_new_domain_nr(void) { return 
-ENOSYS; }
 
 #include 
 
+#ifndef pci_root_bus_fwnode
+#define pci_root_bus_fwnode(bus)   ((void)(bus), NULL)
+#endif
+
 /* these helpers provide future and backwards compatibility
  * for accessing popular PCI BAR info */
 #define pci_resource_start(dev, bar)   ((dev)->resource[(bar)].start)
-- 
1.9.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH v8 3/7] PCI: Make it possible to implement a PCI MSI IRQ Domain in a module.

2015-12-09 Thread jakeo
From: Jake Oshins 

The Linux kernel already has the concpet of IRQ domain, wherein a
component can expose a set of IRQs which are managed by a particular
interrupt controller chip or other subsystem. The PCI driver exposes
the notion of an IRQ domain for Message-Signaled Interrupts (MSI) from
PCI Express devices. This patch exposes the functions which are
necessary for making an MSI IRQ domain within a module.

Signed-off-by: Jake Oshins 
---
 arch/x86/include/asm/msi.h| 6 ++
 arch/x86/kernel/apic/msi.c| 8 +---
 arch/x86/kernel/apic/vector.c | 2 ++
 drivers/pci/msi.c | 4 
 kernel/irq/chip.c | 1 +
 kernel/irq/irqdomain.c| 4 
 6 files changed, 22 insertions(+), 3 deletions(-)

diff --git a/arch/x86/include/asm/msi.h b/arch/x86/include/asm/msi.h
index 93724cc..eb4b09b 100644
--- a/arch/x86/include/asm/msi.h
+++ b/arch/x86/include/asm/msi.h
@@ -1,7 +1,13 @@
 #ifndef _ASM_X86_MSI_H
 #define _ASM_X86_MSI_H
 #include 
+#include 
 
 typedef struct irq_alloc_info msi_alloc_info_t;
 
+int pci_msi_prepare(struct irq_domain *domain, struct device *dev, int nvec,
+   msi_alloc_info_t *arg);
+
+void pci_msi_set_desc(msi_alloc_info_t *arg, struct msi_desc *desc);
+
 #endif /* _ASM_X86_MSI_H */
diff --git a/arch/x86/kernel/apic/msi.c b/arch/x86/kernel/apic/msi.c
index 5f1feb6..ade2532 100644
--- a/arch/x86/kernel/apic/msi.c
+++ b/arch/x86/kernel/apic/msi.c
@@ -96,8 +96,8 @@ static irq_hw_number_t pci_msi_get_hwirq(struct 
msi_domain_info *info,
return arg->msi_hwirq;
 }
 
-static int pci_msi_prepare(struct irq_domain *domain, struct device *dev,
-  int nvec, msi_alloc_info_t *arg)
+int pci_msi_prepare(struct irq_domain *domain, struct device *dev, int nvec,
+   msi_alloc_info_t *arg)
 {
struct pci_dev *pdev = to_pci_dev(dev);
struct msi_desc *desc = first_pci_msi_entry(pdev);
@@ -113,11 +113,13 @@ static int pci_msi_prepare(struct irq_domain *domain, 
struct device *dev,
 
return 0;
 }
+EXPORT_SYMBOL_GPL(pci_msi_prepare);
 
-static void pci_msi_set_desc(msi_alloc_info_t *arg, struct msi_desc *desc)
+void pci_msi_set_desc(msi_alloc_info_t *arg, struct msi_desc *desc)
 {
arg->msi_hwirq = pci_msi_domain_calc_hwirq(arg->msi_dev, desc);
 }
+EXPORT_SYMBOL_GPL(pci_msi_set_desc);
 
 static struct msi_domain_ops pci_msi_domain_ops = {
.get_hwirq  = pci_msi_get_hwirq,
diff --git a/arch/x86/kernel/apic/vector.c b/arch/x86/kernel/apic/vector.c
index 861bc59..908cb37 100644
--- a/arch/x86/kernel/apic/vector.c
+++ b/arch/x86/kernel/apic/vector.c
@@ -29,6 +29,7 @@ struct apic_chip_data {
 };
 
 struct irq_domain *x86_vector_domain;
+EXPORT_SYMBOL_GPL(x86_vector_domain);
 static DEFINE_RAW_SPINLOCK(vector_lock);
 static cpumask_var_t vector_cpumask;
 static struct irq_chip lapic_controller;
@@ -66,6 +67,7 @@ struct irq_cfg *irqd_cfg(struct irq_data *irq_data)
 
return data ? &data->cfg : NULL;
 }
+EXPORT_SYMBOL_GPL(irqd_cfg);
 
 struct irq_cfg *irq_cfg(unsigned int irq)
 {
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
index 7eaa4c8..7a0df3f 100644
--- a/drivers/pci/msi.c
+++ b/drivers/pci/msi.c
@@ -257,6 +257,7 @@ void pci_msi_mask_irq(struct irq_data *data)
 {
msi_set_mask_bit(data, 1);
 }
+EXPORT_SYMBOL_GPL(pci_msi_mask_irq);
 
 /**
  * pci_msi_unmask_irq - Generic irq chip callback to unmask PCI/MSI interrupts
@@ -266,6 +267,7 @@ void pci_msi_unmask_irq(struct irq_data *data)
 {
msi_set_mask_bit(data, 0);
 }
+EXPORT_SYMBOL_GPL(pci_msi_unmask_irq);
 
 void default_restore_msi_irqs(struct pci_dev *dev)
 {
@@ -1126,6 +1128,7 @@ struct pci_dev *msi_desc_to_pci_dev(struct msi_desc *desc)
 {
return to_pci_dev(desc->dev);
 }
+EXPORT_SYMBOL(msi_desc_to_pci_dev);
 
 void *msi_desc_to_pci_sysdata(struct msi_desc *desc)
 {
@@ -1285,6 +1288,7 @@ struct irq_domain *pci_msi_create_irq_domain(struct 
fwnode_handle *fwnode,
domain->bus_token = DOMAIN_BUS_PCI_MSI;
return domain;
 }
+EXPORT_SYMBOL_GPL(pci_msi_create_irq_domain);
 
 /**
  * pci_msi_domain_alloc_irqs - Allocate interrupts for @dev in @domain
diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c
index 05e29de..5797909 100644
--- a/kernel/irq/chip.c
+++ b/kernel/irq/chip.c
@@ -950,6 +950,7 @@ void irq_chip_ack_parent(struct irq_data *data)
data = data->parent_data;
data->chip->irq_ack(data);
 }
+EXPORT_SYMBOL_GPL(irq_chip_ack_parent);
 
 /**
  * irq_chip_mask_parent - Mask the parent interrupt
diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
index 22aa961..aa6ac44 100644
--- a/kernel/irq/irqdomain.c
+++ b/kernel/irq/irqdomain.c
@@ -60,6 +60,7 @@ struct fwnode_handle *irq_domain_alloc_fwnode(void *data)
fwid->fwnode.type = FWNODE_IRQCHIP;
return &fwid->fwnode;
 }
+EXPORT_SYMBOL_GPL(irq_domain_alloc_fwnode);
 
 /**
  * irq_domain_free_fwnode - Free a non-OF-backed fwnode_handle
@@ -77,6 +78,7 @@ void irq_domain_free_fwnode(struct fwnode_

[PATCH v8 7/7] PCI: hv: New paravirtual PCI front-end for Hyper-V VMs

2015-12-09 Thread jakeo
From: Jake Oshins 

This patch introduces a new driver which exposes a root PCI bus whenever a
PCI Express device is passed through to a guest VM under Hyper-V. The
device can be single- or multi-function. The interrupts for the devices
are managed by an IRQ domain, implemented within the driver.

Signed-off-by: Jake Oshins 
---
 MAINTAINERS|1 +
 drivers/pci/Kconfig|7 +
 drivers/pci/host/Makefile  |1 +
 drivers/pci/host/hv_pcifront.c | 2249 
 4 files changed, 2258 insertions(+)
 create mode 100644 drivers/pci/host/hv_pcifront.c

diff --git a/MAINTAINERS b/MAINTAINERS
index e6ec986..40747e8 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -5115,6 +5115,7 @@ F:arch/x86/kernel/cpu/mshyperv.c
 F: drivers/hid/hid-hyperv.c
 F: drivers/hv/
 F: drivers/input/serio/hyperv-keyboard.c
+F: drivers/pci/host/hv_pcifront.c
 F: drivers/net/hyperv/
 F: drivers/scsi/storvsc_drv.c
 F: drivers/video/fbdev/hyperv_fb.c
diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig
index 73de4ef..9b82d93 100644
--- a/drivers/pci/Kconfig
+++ b/drivers/pci/Kconfig
@@ -118,4 +118,11 @@ config PCI_LABEL
def_bool y if (DMI || ACPI)
select NLS
 
+config HYPERV_VPCI
+tristate "Hyper-V PCI Frontend"
+depends on PCI && X86 && HYPERV && PCI_MSI && PCI_MSI_IRQ_DOMAIN
+help
+  The PCI device frontend driver allows the kernel to import arbitrary
+  PCI devices from a PCI backend to support PCI driver domains.
+
 source "drivers/pci/host/Kconfig"
diff --git a/drivers/pci/host/Makefile b/drivers/pci/host/Makefile
index 9d4d3c6..d9abd2a 100644
--- a/drivers/pci/host/Makefile
+++ b/drivers/pci/host/Makefile
@@ -2,6 +2,7 @@ obj-$(CONFIG_PCIE_DW) += pcie-designware.o
 obj-$(CONFIG_PCI_DRA7XX) += pci-dra7xx.o
 obj-$(CONFIG_PCI_EXYNOS) += pci-exynos.o
 obj-$(CONFIG_PCI_IMX6) += pci-imx6.o
+obj-$(CONFIG_HYPERV_VPCI) += hv_pcifront.o
 obj-$(CONFIG_PCI_MVEBU) += pci-mvebu.o
 obj-$(CONFIG_PCI_TEGRA) += pci-tegra.o
 obj-$(CONFIG_PCI_RCAR_GEN2) += pci-rcar-gen2.o
diff --git a/drivers/pci/host/hv_pcifront.c b/drivers/pci/host/hv_pcifront.c
new file mode 100644
index 000..56da07e
--- /dev/null
+++ b/drivers/pci/host/hv_pcifront.c
@@ -0,0 +1,2249 @@
+/*
+ * Copyright (c) Microsoft Corporation.
+ *
+ * Author:
+ *   Jake Oshins 
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+ * NON INFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+/*
+ * Protocol versions. The low word is the minor version, the high word the 
major
+ * version.
+ */
+
+#define PCI_MAKE_VERSION(major, minor) ((__u32)(((major) << 16) | (major)))
+#define PCI_MAJOR_VERSION(version) ((__u32)(version) >> 16)
+#define PCI_MINOR_VERSION(version) ((__u32)(version) & 0xff)
+
+enum {
+   PCI_PROTOCOL_VERSION_1_1 = PCI_MAKE_VERSION(1, 1),
+   PCI_PROTOCOL_VERSION_CURRENT = PCI_PROTOCOL_VERSION_1_1
+};
+
+#define PCI_CONFIG_MMIO_LENGTH 0x2000
+#define MAX_SUPPORTED_MSI_MESSAGES 0x400
+
+/*
+ * Message Types
+ */
+
+enum pci_message_type {
+   /*
+* Version 1.1
+*/
+   PCI_MESSAGE_BASE= 0x4249,
+   PCI_BUS_RELATIONS   = PCI_MESSAGE_BASE + 0,
+   PCI_QUERY_BUS_RELATIONS = PCI_MESSAGE_BASE + 1,
+   PCI_POWER_STATE_CHANGE  = PCI_MESSAGE_BASE + 4,
+   PCI_QUERY_RESOURCE_REQUIREMENTS = PCI_MESSAGE_BASE + 5,
+   PCI_QUERY_RESOURCE_RESOURCES= PCI_MESSAGE_BASE + 6,
+   PCI_BUS_D0ENTRY = PCI_MESSAGE_BASE + 7,
+   PCI_BUS_D0EXIT  = PCI_MESSAGE_BASE + 8,
+   PCI_READ_BLOCK  = PCI_MESSAGE_BASE + 9,
+   PCI_WRITE_BLOCK = PCI_MESSAGE_BASE + 0xA,
+   PCI_EJECT   = PCI_MESSAGE_BASE + 0xB,
+   PCI_QUERY_STOP  = PCI_MESSAGE_BASE + 0xC,
+   PCI_REENABLE= PCI_MESSAGE_BASE + 0xD,
+   PCI_QUERY_STOP_FAILED   = PCI_MESSAGE_BASE + 0xE,
+   PCI_EJECTION_COMPLETE   = PCI_MESSAGE_BASE + 0xF,
+   PCI_RESOURCES_ASSIGNED  = PCI_MESSAGE_BASE + 0x10,
+   PCI_RESOURCES_RELEASED  = PCI_MESSAGE_BASE + 0x11,
+   PCI_INVALIDATE_BLOCK= PCI_MESSAGE_BASE + 0x12,
+   PCI_QUERY_PROTOCOL_VERSION  = PCI_MESSAGE_BASE + 0x13,
+   PCI_CREATE_INTERRUPT_MESSAGE= PCI_MESSAGE_BASE + 0x14,
+   PCI_DELETE_INTERRUPT_MESSAGE= 

[PATCH v8 0/7] PCI: hv: New paravirtual PCI front-end for Hyper-V VMs

2015-12-09 Thread jakeo
From: Jake Oshins 

This version of the patch series incorporates feedback from Mark Zyngier,
making this build on arm/arm64.

First, export functions that allow correlating Hyper-V virtual processors
and Linux cpus, along with the means for invoking a hypercall that targets
interrupts at chosen vectors on specific cpus.

Second, mark various parts of IRQ domain related code as exported, so that
this PCI front-end can implement an IRQ domain as part of a module.  (The
alternative would be to pull all tyhis into the kernel, which would pull
in a lot of other Hyper-V related code, as this IRQ domain depends on
vmbus.ko.)

Third, modify PCI so that new root PCI buses can be marked with an associated
fwnode_handle, and so that root PCI buses can look up their associated IRQ
domain by that handle.

Fourth, introduce a new driver, hv_pcifront, which exposes root PCI buses in
a Hyper-V VM.  These root PCI buses expose real PCIe device, or PCI Virtual
Functions.

Jake Oshins (7):
  drivers:hv: Export a function that maps Linux CPU num onto Hyper-V
proc num
  drivers:hv: Export hv_do_hypercall()
  PCI: Make it possible to implement a PCI MSI IRQ Domain in a module.
  PCI: Add fwnode_handle to pci_sysdata
  PCI: irqdomain: Look up IRQ domain by fwnode_handle
  drivers:hv: Define the channel type of Hyper-V PCI Express
pass-through
  PCI: hv: New paravirtual PCI front-end for Hyper-V VMs

 MAINTAINERS|1 +
 arch/x86/include/asm/msi.h |6 +
 arch/x86/include/asm/pci.h |   15 +
 arch/x86/kernel/apic/msi.c |8 +-
 arch/x86/kernel/apic/vector.c  |2 +
 drivers/hv/hv.c|   20 +-
 drivers/hv/hyperv_vmbus.h  |2 +-
 drivers/hv/vmbus_drv.c |   17 +
 drivers/pci/Kconfig|7 +
 drivers/pci/host/Makefile  |1 +
 drivers/pci/host/hv_pcifront.c | 2249 
 drivers/pci/msi.c  |4 +
 drivers/pci/probe.c|   15 +
 include/linux/hyperv.h |   14 +
 include/linux/pci.h|4 +
 kernel/irq/chip.c  |1 +
 kernel/irq/irqdomain.c |4 +
 17 files changed, 2356 insertions(+), 14 deletions(-)
 create mode 100644 drivers/pci/host/hv_pcifront.c

-- 
1.9.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH v8 2/7] drivers:hv: Export hv_do_hypercall()

2015-12-09 Thread jakeo
From: Jake Oshins 

This patch exposes the function that hv_vmbus.ko uses to make hypercalls.
This is necessary for retargeting an interrupt when it is given a new
affinity and vector.

Signed-off-by: Jake Oshins 
---
 drivers/hv/hv.c   | 20 ++--
 drivers/hv/hyperv_vmbus.h |  2 +-
 include/linux/hyperv.h|  1 +
 3 files changed, 12 insertions(+), 11 deletions(-)

diff --git a/drivers/hv/hv.c b/drivers/hv/hv.c
index 6341be8..7a06933 100644
--- a/drivers/hv/hv.c
+++ b/drivers/hv/hv.c
@@ -89,9 +89,9 @@ static int query_hypervisor_info(void)
 }
 
 /*
- * do_hypercall- Invoke the specified hypercall
+ * hv_do_hypercall- Invoke the specified hypercall
  */
-static u64 do_hypercall(u64 control, void *input, void *output)
+u64 hv_do_hypercall(u64 control, void *input, void *output)
 {
u64 input_address = (input) ? virt_to_phys(input) : 0;
u64 output_address = (output) ? virt_to_phys(output) : 0;
@@ -132,6 +132,7 @@ static u64 do_hypercall(u64 control, void *input, void 
*output)
return hv_status_lo | ((u64)hv_status_hi << 32);
 #endif /* !x86_64 */
 }
+EXPORT_SYMBOL_GPL(hv_do_hypercall);
 
 #ifdef CONFIG_X86_64
 static cycle_t read_hv_clock_tsc(struct clocksource *arg)
@@ -315,7 +316,7 @@ int hv_post_message(union hv_connection_id connection_id,
 {
 
struct hv_input_post_message *aligned_msg;
-   u16 status;
+   u64 status;
 
if (payload_size > HV_MESSAGE_PAYLOAD_BYTE_COUNT)
return -EMSGSIZE;
@@ -329,11 +330,10 @@ int hv_post_message(union hv_connection_id connection_id,
aligned_msg->payload_size = payload_size;
memcpy((void *)aligned_msg->payload, payload, payload_size);
 
-   status = do_hypercall(HVCALL_POST_MESSAGE, aligned_msg, NULL)
-   & 0x;
+   status = hv_do_hypercall(HVCALL_POST_MESSAGE, aligned_msg, NULL);
 
put_cpu();
-   return status;
+   return status & 0x;
 }
 
 
@@ -343,13 +343,13 @@ int hv_post_message(union hv_connection_id connection_id,
  *
  * This involves a hypercall.
  */
-u16 hv_signal_event(void *con_id)
+int hv_signal_event(void *con_id)
 {
-   u16 status;
+   u64 status;
 
-   status = (do_hypercall(HVCALL_SIGNAL_EVENT, con_id, NULL) & 0x);
+   status = hv_do_hypercall(HVCALL_SIGNAL_EVENT, con_id, NULL);
 
-   return status;
+   return status & 0x;
 }
 
 static int hv_ce_set_next_event(unsigned long delta,
diff --git a/drivers/hv/hyperv_vmbus.h b/drivers/hv/hyperv_vmbus.h
index 3782636..cc2fb53 100644
--- a/drivers/hv/hyperv_vmbus.h
+++ b/drivers/hv/hyperv_vmbus.h
@@ -582,7 +582,7 @@ extern int hv_post_message(union hv_connection_id 
connection_id,
 enum hv_message_type message_type,
 void *payload, size_t payload_size);
 
-extern u16 hv_signal_event(void *con_id);
+extern int hv_signal_event(void *con_id);
 
 extern int hv_synic_alloc(void);
 
diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h
index fddb3e0..24d0b65 100644
--- a/include/linux/hyperv.h
+++ b/include/linux/hyperv.h
@@ -984,6 +984,7 @@ int vmbus_allocate_mmio(struct resource **new, struct 
hv_device *device_obj,
bool fb_overlap_ok);
 
 int vmbus_cpu_number_to_vp_number(int cpu_number);
+u64 hv_do_hypercall(u64 control, void *input, void *output);
 
 /**
  * VMBUS_DEVICE - macro used to describe a specific hyperv vmbus device
-- 
1.9.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH v8 6/7] drivers:hv: Define the channel type of Hyper-V PCI Express pass-through

2015-12-09 Thread jakeo
From: Jake Oshins 

This defines the channel type for PCI front-ends in Hyper-V VMs.

Signed-off-by: Jake Oshins 
---
 include/linux/hyperv.h | 11 +++
 1 file changed, 11 insertions(+)

diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h
index 24d0b65..c9a9eed 100644
--- a/include/linux/hyperv.h
+++ b/include/linux/hyperv.h
@@ -1141,6 +1141,17 @@ u64 hv_do_hypercall(u64 control, void *input, void 
*output);
}
 
 /*
+ * PCI Express Pass Through
+ * {44C4F61D--4400-9D52-802E27EDE19F}
+ */
+
+#define HV_PCIE_GUID \
+   .guid = { \
+   0x1D, 0xF6, 0xC4, 0x44, 0x44, 0x44, 0x00, 0x44, \
+   0x9D, 0x52, 0x80, 0x2E, 0x27, 0xED, 0xE1, 0x9F \
+   }
+
+/*
  * Common header for Hyper-V ICs
  */
 
-- 
1.9.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH v9 2/7] drivers:hv: Export hv_do_hypercall()

2015-12-09 Thread jakeo
From: Jake Oshins 

This patch exposes the function that hv_vmbus.ko uses to make hypercalls.
This is necessary for retargeting an interrupt when it is given a new
affinity and vector.

Signed-off-by: Jake Oshins 
---
 drivers/hv/hv.c   | 20 ++--
 drivers/hv/hyperv_vmbus.h |  2 +-
 include/linux/hyperv.h|  1 +
 3 files changed, 12 insertions(+), 11 deletions(-)

diff --git a/drivers/hv/hv.c b/drivers/hv/hv.c
index 6341be8..7a06933 100644
--- a/drivers/hv/hv.c
+++ b/drivers/hv/hv.c
@@ -89,9 +89,9 @@ static int query_hypervisor_info(void)
 }
 
 /*
- * do_hypercall- Invoke the specified hypercall
+ * hv_do_hypercall- Invoke the specified hypercall
  */
-static u64 do_hypercall(u64 control, void *input, void *output)
+u64 hv_do_hypercall(u64 control, void *input, void *output)
 {
u64 input_address = (input) ? virt_to_phys(input) : 0;
u64 output_address = (output) ? virt_to_phys(output) : 0;
@@ -132,6 +132,7 @@ static u64 do_hypercall(u64 control, void *input, void 
*output)
return hv_status_lo | ((u64)hv_status_hi << 32);
 #endif /* !x86_64 */
 }
+EXPORT_SYMBOL_GPL(hv_do_hypercall);
 
 #ifdef CONFIG_X86_64
 static cycle_t read_hv_clock_tsc(struct clocksource *arg)
@@ -315,7 +316,7 @@ int hv_post_message(union hv_connection_id connection_id,
 {
 
struct hv_input_post_message *aligned_msg;
-   u16 status;
+   u64 status;
 
if (payload_size > HV_MESSAGE_PAYLOAD_BYTE_COUNT)
return -EMSGSIZE;
@@ -329,11 +330,10 @@ int hv_post_message(union hv_connection_id connection_id,
aligned_msg->payload_size = payload_size;
memcpy((void *)aligned_msg->payload, payload, payload_size);
 
-   status = do_hypercall(HVCALL_POST_MESSAGE, aligned_msg, NULL)
-   & 0x;
+   status = hv_do_hypercall(HVCALL_POST_MESSAGE, aligned_msg, NULL);
 
put_cpu();
-   return status;
+   return status & 0x;
 }
 
 
@@ -343,13 +343,13 @@ int hv_post_message(union hv_connection_id connection_id,
  *
  * This involves a hypercall.
  */
-u16 hv_signal_event(void *con_id)
+int hv_signal_event(void *con_id)
 {
-   u16 status;
+   u64 status;
 
-   status = (do_hypercall(HVCALL_SIGNAL_EVENT, con_id, NULL) & 0x);
+   status = hv_do_hypercall(HVCALL_SIGNAL_EVENT, con_id, NULL);
 
-   return status;
+   return status & 0x;
 }
 
 static int hv_ce_set_next_event(unsigned long delta,
diff --git a/drivers/hv/hyperv_vmbus.h b/drivers/hv/hyperv_vmbus.h
index 3782636..cc2fb53 100644
--- a/drivers/hv/hyperv_vmbus.h
+++ b/drivers/hv/hyperv_vmbus.h
@@ -582,7 +582,7 @@ extern int hv_post_message(union hv_connection_id 
connection_id,
 enum hv_message_type message_type,
 void *payload, size_t payload_size);
 
-extern u16 hv_signal_event(void *con_id);
+extern int hv_signal_event(void *con_id);
 
 extern int hv_synic_alloc(void);
 
diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h
index fddb3e0..24d0b65 100644
--- a/include/linux/hyperv.h
+++ b/include/linux/hyperv.h
@@ -984,6 +984,7 @@ int vmbus_allocate_mmio(struct resource **new, struct 
hv_device *device_obj,
bool fb_overlap_ok);
 
 int vmbus_cpu_number_to_vp_number(int cpu_number);
+u64 hv_do_hypercall(u64 control, void *input, void *output);
 
 /**
  * VMBUS_DEVICE - macro used to describe a specific hyperv vmbus device
-- 
1.9.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH v9 6/7] drivers:hv: Define the channel type of Hyper-V PCI Express pass-through

2015-12-09 Thread jakeo
From: Jake Oshins 

This defines the channel type for PCI front-ends in Hyper-V VMs.

Signed-off-by: Jake Oshins 
---
 include/linux/hyperv.h | 11 +++
 1 file changed, 11 insertions(+)

diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h
index 24d0b65..c9a9eed 100644
--- a/include/linux/hyperv.h
+++ b/include/linux/hyperv.h
@@ -1141,6 +1141,17 @@ u64 hv_do_hypercall(u64 control, void *input, void 
*output);
}
 
 /*
+ * PCI Express Pass Through
+ * {44C4F61D--4400-9D52-802E27EDE19F}
+ */
+
+#define HV_PCIE_GUID \
+   .guid = { \
+   0x1D, 0xF6, 0xC4, 0x44, 0x44, 0x44, 0x00, 0x44, \
+   0x9D, 0x52, 0x80, 0x2E, 0x27, 0xED, 0xE1, 0x9F \
+   }
+
+/*
  * Common header for Hyper-V ICs
  */
 
-- 
1.9.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH v9 3/7] PCI: Make it possible to implement a PCI MSI IRQ Domain in a module.

2015-12-09 Thread jakeo
From: Jake Oshins 

The Linux kernel already has the concpet of IRQ domain, wherein a
component can expose a set of IRQs which are managed by a particular
interrupt controller chip or other subsystem. The PCI driver exposes
the notion of an IRQ domain for Message-Signaled Interrupts (MSI) from
PCI Express devices. This patch exposes the functions which are
necessary for making an MSI IRQ domain within a module.

Signed-off-by: Jake Oshins 
---
 arch/x86/include/asm/msi.h| 6 ++
 arch/x86/kernel/apic/msi.c| 8 +---
 arch/x86/kernel/apic/vector.c | 2 ++
 drivers/pci/msi.c | 4 
 kernel/irq/chip.c | 1 +
 kernel/irq/irqdomain.c| 4 
 6 files changed, 22 insertions(+), 3 deletions(-)

diff --git a/arch/x86/include/asm/msi.h b/arch/x86/include/asm/msi.h
index 93724cc..eb4b09b 100644
--- a/arch/x86/include/asm/msi.h
+++ b/arch/x86/include/asm/msi.h
@@ -1,7 +1,13 @@
 #ifndef _ASM_X86_MSI_H
 #define _ASM_X86_MSI_H
 #include 
+#include 
 
 typedef struct irq_alloc_info msi_alloc_info_t;
 
+int pci_msi_prepare(struct irq_domain *domain, struct device *dev, int nvec,
+   msi_alloc_info_t *arg);
+
+void pci_msi_set_desc(msi_alloc_info_t *arg, struct msi_desc *desc);
+
 #endif /* _ASM_X86_MSI_H */
diff --git a/arch/x86/kernel/apic/msi.c b/arch/x86/kernel/apic/msi.c
index 5f1feb6..ade2532 100644
--- a/arch/x86/kernel/apic/msi.c
+++ b/arch/x86/kernel/apic/msi.c
@@ -96,8 +96,8 @@ static irq_hw_number_t pci_msi_get_hwirq(struct 
msi_domain_info *info,
return arg->msi_hwirq;
 }
 
-static int pci_msi_prepare(struct irq_domain *domain, struct device *dev,
-  int nvec, msi_alloc_info_t *arg)
+int pci_msi_prepare(struct irq_domain *domain, struct device *dev, int nvec,
+   msi_alloc_info_t *arg)
 {
struct pci_dev *pdev = to_pci_dev(dev);
struct msi_desc *desc = first_pci_msi_entry(pdev);
@@ -113,11 +113,13 @@ static int pci_msi_prepare(struct irq_domain *domain, 
struct device *dev,
 
return 0;
 }
+EXPORT_SYMBOL_GPL(pci_msi_prepare);
 
-static void pci_msi_set_desc(msi_alloc_info_t *arg, struct msi_desc *desc)
+void pci_msi_set_desc(msi_alloc_info_t *arg, struct msi_desc *desc)
 {
arg->msi_hwirq = pci_msi_domain_calc_hwirq(arg->msi_dev, desc);
 }
+EXPORT_SYMBOL_GPL(pci_msi_set_desc);
 
 static struct msi_domain_ops pci_msi_domain_ops = {
.get_hwirq  = pci_msi_get_hwirq,
diff --git a/arch/x86/kernel/apic/vector.c b/arch/x86/kernel/apic/vector.c
index 861bc59..908cb37 100644
--- a/arch/x86/kernel/apic/vector.c
+++ b/arch/x86/kernel/apic/vector.c
@@ -29,6 +29,7 @@ struct apic_chip_data {
 };
 
 struct irq_domain *x86_vector_domain;
+EXPORT_SYMBOL_GPL(x86_vector_domain);
 static DEFINE_RAW_SPINLOCK(vector_lock);
 static cpumask_var_t vector_cpumask;
 static struct irq_chip lapic_controller;
@@ -66,6 +67,7 @@ struct irq_cfg *irqd_cfg(struct irq_data *irq_data)
 
return data ? &data->cfg : NULL;
 }
+EXPORT_SYMBOL_GPL(irqd_cfg);
 
 struct irq_cfg *irq_cfg(unsigned int irq)
 {
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
index 7eaa4c8..7a0df3f 100644
--- a/drivers/pci/msi.c
+++ b/drivers/pci/msi.c
@@ -257,6 +257,7 @@ void pci_msi_mask_irq(struct irq_data *data)
 {
msi_set_mask_bit(data, 1);
 }
+EXPORT_SYMBOL_GPL(pci_msi_mask_irq);
 
 /**
  * pci_msi_unmask_irq - Generic irq chip callback to unmask PCI/MSI interrupts
@@ -266,6 +267,7 @@ void pci_msi_unmask_irq(struct irq_data *data)
 {
msi_set_mask_bit(data, 0);
 }
+EXPORT_SYMBOL_GPL(pci_msi_unmask_irq);
 
 void default_restore_msi_irqs(struct pci_dev *dev)
 {
@@ -1126,6 +1128,7 @@ struct pci_dev *msi_desc_to_pci_dev(struct msi_desc *desc)
 {
return to_pci_dev(desc->dev);
 }
+EXPORT_SYMBOL(msi_desc_to_pci_dev);
 
 void *msi_desc_to_pci_sysdata(struct msi_desc *desc)
 {
@@ -1285,6 +1288,7 @@ struct irq_domain *pci_msi_create_irq_domain(struct 
fwnode_handle *fwnode,
domain->bus_token = DOMAIN_BUS_PCI_MSI;
return domain;
 }
+EXPORT_SYMBOL_GPL(pci_msi_create_irq_domain);
 
 /**
  * pci_msi_domain_alloc_irqs - Allocate interrupts for @dev in @domain
diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c
index 05e29de..5797909 100644
--- a/kernel/irq/chip.c
+++ b/kernel/irq/chip.c
@@ -950,6 +950,7 @@ void irq_chip_ack_parent(struct irq_data *data)
data = data->parent_data;
data->chip->irq_ack(data);
 }
+EXPORT_SYMBOL_GPL(irq_chip_ack_parent);
 
 /**
  * irq_chip_mask_parent - Mask the parent interrupt
diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
index 22aa961..aa6ac44 100644
--- a/kernel/irq/irqdomain.c
+++ b/kernel/irq/irqdomain.c
@@ -60,6 +60,7 @@ struct fwnode_handle *irq_domain_alloc_fwnode(void *data)
fwid->fwnode.type = FWNODE_IRQCHIP;
return &fwid->fwnode;
 }
+EXPORT_SYMBOL_GPL(irq_domain_alloc_fwnode);
 
 /**
  * irq_domain_free_fwnode - Free a non-OF-backed fwnode_handle
@@ -77,6 +78,7 @@ void irq_domain_free_fwnode(struct fwnode_

[PATCH v9 4/7] PCI: Add fwnode_handle to pci_sysdata

2015-12-09 Thread jakeo
From: Jake Oshins 

This patch adds an fwnode_handle to struct pci_sysdata, which is
used by the next patch in the series when trying to locate an
IRQ domain associated with a root PCI bus.

Signed-off-by: Jake Oshins 
---
 arch/x86/include/asm/pci.h | 15 +++
 drivers/pci/probe.c|  1 +
 include/linux/pci.h|  4 
 3 files changed, 20 insertions(+)

diff --git a/arch/x86/include/asm/pci.h b/arch/x86/include/asm/pci.h
index 4625943..6fc3c7c 100644
--- a/arch/x86/include/asm/pci.h
+++ b/arch/x86/include/asm/pci.h
@@ -20,6 +20,9 @@ struct pci_sysdata {
 #ifdef CONFIG_X86_64
void*iommu; /* IOMMU private data */
 #endif
+#ifdef CONFIG_PCI_MSI_IRQ_DOMAIN
+   void*fwnode;/* IRQ domain for MSI assignment */
+#endif
 };
 
 extern int pci_routeirq;
@@ -32,6 +35,7 @@ extern int noioapicreroute;
 static inline int pci_domain_nr(struct pci_bus *bus)
 {
struct pci_sysdata *sd = bus->sysdata;
+
return sd->domain;
 }
 
@@ -41,6 +45,17 @@ static inline int pci_proc_domain(struct pci_bus *bus)
 }
 #endif
 
+#ifdef CONFIG_PCI_MSI_IRQ_DOMAIN
+static inline void *_pci_root_bus_fwnode(struct pci_bus *bus)
+{
+   struct pci_sysdata *sd = bus->sysdata;
+
+   return sd->fwnode;
+}
+
+#define pci_root_bus_fwnode_pci_root_bus_fwnode
+#endif
+
 /* Can be used to override the logic in pci_scan_bus for skipping
already-configured bus numbers - to be used for buggy BIOSes
or architectures with incomplete PCI setup by the loader */
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index edb1984..750f907 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -15,6 +15,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include "pci.h"
 
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 6ae25aa..b414422 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -1517,6 +1517,10 @@ static inline int pci_get_new_domain_nr(void) { return 
-ENOSYS; }
 
 #include 
 
+#ifndef pci_root_bus_fwnode
+#define pci_root_bus_fwnode(bus)   ((void)(bus), NULL)
+#endif
+
 /* these helpers provide future and backwards compatibility
  * for accessing popular PCI BAR info */
 #define pci_resource_start(dev, bar)   ((dev)->resource[(bar)].start)
-- 
1.9.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH v9 1/7] drivers:hv: Export a function that maps Linux CPU num onto Hyper-V proc num

2015-12-09 Thread jakeo
From: Jake Oshins 

This patch exposes the mapping between Linux CPU number and Hyper-V
virtual processor number. This is necessary because the hypervisor needs
to know which virtual processor to target when making a mapping in the
Interrupt Redirection Table in the I/O MMU.

Signed-off-by: Jake Oshins 
---
 drivers/hv/vmbus_drv.c | 17 +
 include/linux/hyperv.h |  2 ++
 2 files changed, 19 insertions(+)

diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c
index f19b6f7..c89d0e5 100644
--- a/drivers/hv/vmbus_drv.c
+++ b/drivers/hv/vmbus_drv.c
@@ -1191,6 +1191,23 @@ int vmbus_allocate_mmio(struct resource **new, struct 
hv_device *device_obj,
 }
 EXPORT_SYMBOL_GPL(vmbus_allocate_mmio);
 
+/**
+ * vmbus_cpu_number_to_vp_number() - Map CPU to VP.
+ * @cpu_number: CPU number in Linux terms
+ *
+ * This function returns the mapping between the Linux processor
+ * number and the hypervisor's virtual processor number, useful
+ * in making hypercalls and such that talk about specific
+ * processors.
+ *
+ * Return: Virtual processor number in Hyper-V terms
+ */
+int vmbus_cpu_number_to_vp_number(int cpu_number)
+{
+   return hv_context.vp_index[cpu_number];
+}
+EXPORT_SYMBOL_GPL(vmbus_cpu_number_to_vp_number);
+
 static int vmbus_acpi_add(struct acpi_device *device)
 {
acpi_status result;
diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h
index 8fdc17b..fddb3e0 100644
--- a/include/linux/hyperv.h
+++ b/include/linux/hyperv.h
@@ -983,6 +983,8 @@ int vmbus_allocate_mmio(struct resource **new, struct 
hv_device *device_obj,
resource_size_t size, resource_size_t align,
bool fb_overlap_ok);
 
+int vmbus_cpu_number_to_vp_number(int cpu_number);
+
 /**
  * VMBUS_DEVICE - macro used to describe a specific hyperv vmbus device
  *
-- 
1.9.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH v9 5/7] PCI: irqdomain: Look up IRQ domain by fwnode_handle

2015-12-09 Thread jakeo
From: Jake Oshins 

This patch adds a second way of finding an IRQ domain associated with
a root PCI bus.  After looking to see if one can be found through
the OF tree, it attempts to look up the IRQ domain through an
fwnode_handle stored in the pci_sysdata struct.

Signed-off-by: Jake Oshins 
---
 drivers/pci/probe.c | 14 ++
 1 file changed, 14 insertions(+)

diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index 750f907..c6369dd 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -674,6 +674,20 @@ static struct irq_domain 
*pci_host_bridge_msi_domain(struct pci_bus *bus)
 */
d = pci_host_bridge_of_msi_domain(bus);
 
+#ifdef CONFIG_PCI_MSI_IRQ_DOMAIN
+   /*
+* If no IRQ domain was found via the OF tree, try looking it up
+* directly through the fwnode_handle.
+*/
+   if (!d) {
+   struct fwnode_handle *fwnode = pci_root_bus_fwnode(bus);
+
+   if (fwnode)
+   d = irq_find_matching_fwnode(fwnode,
+DOMAIN_BUS_PCI_MSI);
+   }
+#endif
+
return d;
 }
 
-- 
1.9.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH v9 0/7] PCI: hv: New paravirtual PCI front-end for Hyper-V VMs

2015-12-09 Thread jakeo
From: Jake Oshins 

This version of the patch series removes warning when compiling x86
32-bit.

First, export functions that allow correlating Hyper-V virtual processors
and Linux cpus, along with the means for invoking a hypercall that targets
interrupts at chosen vectors on specific cpus.

Second, mark various parts of IRQ domain related code as exported, so that
this PCI front-end can implement an IRQ domain as part of a module.  (The
alternative would be to pull all tyhis into the kernel, which would pull
in a lot of other Hyper-V related code, as this IRQ domain depends on
vmbus.ko.)

Third, modify PCI so that new root PCI buses can be marked with an associated
fwnode_handle, and so that root PCI buses can look up their associated IRQ
domain by that handle.

Fourth, introduce a new driver, hv_pcifront, which exposes root PCI buses in
a Hyper-V VM.  These root PCI buses expose real PCIe device, or PCI Virtual
Functions.


Jake Oshins (7):
  drivers:hv: Export a function that maps Linux CPU num onto Hyper-V
proc num
  drivers:hv: Export hv_do_hypercall()
  PCI: Make it possible to implement a PCI MSI IRQ Domain in a module.
  PCI: Add fwnode_handle to pci_sysdata
  PCI: irqdomain: Look up IRQ domain by fwnode_handle
  drivers:hv: Define the channel type of Hyper-V PCI Express
pass-through
  PCI: hv: New paravirtual PCI front-end for Hyper-V VMs

 MAINTAINERS|1 +
 arch/x86/include/asm/msi.h |6 +
 arch/x86/include/asm/pci.h |   15 +
 arch/x86/kernel/apic/msi.c |8 +-
 arch/x86/kernel/apic/vector.c  |2 +
 drivers/hv/hv.c|   20 +-
 drivers/hv/hyperv_vmbus.h  |2 +-
 drivers/hv/vmbus_drv.c |   17 +
 drivers/pci/Kconfig|7 +
 drivers/pci/host/Makefile  |1 +
 drivers/pci/host/hv_pcifront.c | 2250 
 drivers/pci/msi.c  |4 +
 drivers/pci/probe.c|   15 +
 include/linux/hyperv.h |   14 +
 include/linux/pci.h|4 +
 kernel/irq/chip.c  |1 +
 kernel/irq/irqdomain.c |4 +
 17 files changed, 2357 insertions(+), 14 deletions(-)
 create mode 100644 drivers/pci/host/hv_pcifront.c

-- 
1.9.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH v9 7/7] PCI: hv: New paravirtual PCI front-end for Hyper-V VMs

2015-12-09 Thread jakeo
From: Jake Oshins 

This patch introduces a new driver which exposes a root PCI bus whenever a
PCI Express device is passed through to a guest VM under Hyper-V. The
device can be single- or multi-function. The interrupts for the devices
are managed by an IRQ domain, implemented within the driver.

Signed-off-by: Jake Oshins 
---
 MAINTAINERS|1 +
 drivers/pci/Kconfig|7 +
 drivers/pci/host/Makefile  |1 +
 drivers/pci/host/hv_pcifront.c | 2250 
 4 files changed, 2259 insertions(+)
 create mode 100644 drivers/pci/host/hv_pcifront.c

diff --git a/MAINTAINERS b/MAINTAINERS
index e6ec986..40747e8 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -5115,6 +5115,7 @@ F:arch/x86/kernel/cpu/mshyperv.c
 F: drivers/hid/hid-hyperv.c
 F: drivers/hv/
 F: drivers/input/serio/hyperv-keyboard.c
+F: drivers/pci/host/hv_pcifront.c
 F: drivers/net/hyperv/
 F: drivers/scsi/storvsc_drv.c
 F: drivers/video/fbdev/hyperv_fb.c
diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig
index 73de4ef..573b8d6 100644
--- a/drivers/pci/Kconfig
+++ b/drivers/pci/Kconfig
@@ -118,4 +118,11 @@ config PCI_LABEL
def_bool y if (DMI || ACPI)
select NLS
 
+config HYPERV_VPCI
+tristate "Hyper-V PCI Frontend"
+depends on PCI && X86 && HYPERV && PCI_MSI && PCI_MSI_IRQ_DOMAIN && 
X86_64
+help
+  The PCI device frontend driver allows the kernel to import arbitrary
+  PCI devices from a PCI backend to support PCI driver domains.
+
 source "drivers/pci/host/Kconfig"
diff --git a/drivers/pci/host/Makefile b/drivers/pci/host/Makefile
index 9d4d3c6..d9abd2a 100644
--- a/drivers/pci/host/Makefile
+++ b/drivers/pci/host/Makefile
@@ -2,6 +2,7 @@ obj-$(CONFIG_PCIE_DW) += pcie-designware.o
 obj-$(CONFIG_PCI_DRA7XX) += pci-dra7xx.o
 obj-$(CONFIG_PCI_EXYNOS) += pci-exynos.o
 obj-$(CONFIG_PCI_IMX6) += pci-imx6.o
+obj-$(CONFIG_HYPERV_VPCI) += hv_pcifront.o
 obj-$(CONFIG_PCI_MVEBU) += pci-mvebu.o
 obj-$(CONFIG_PCI_TEGRA) += pci-tegra.o
 obj-$(CONFIG_PCI_RCAR_GEN2) += pci-rcar-gen2.o
diff --git a/drivers/pci/host/hv_pcifront.c b/drivers/pci/host/hv_pcifront.c
new file mode 100644
index 000..25bfe60
--- /dev/null
+++ b/drivers/pci/host/hv_pcifront.c
@@ -0,0 +1,2250 @@
+/*
+ * Copyright (c) Microsoft Corporation.
+ *
+ * Author:
+ *   Jake Oshins 
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+ * NON INFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+/*
+ * Protocol versions. The low word is the minor version, the high word the 
major
+ * version.
+ */
+
+#define PCI_MAKE_VERSION(major, minor) ((__u32)(((major) << 16) | (major)))
+#define PCI_MAJOR_VERSION(version) ((__u32)(version) >> 16)
+#define PCI_MINOR_VERSION(version) ((__u32)(version) & 0xff)
+
+enum {
+   PCI_PROTOCOL_VERSION_1_1 = PCI_MAKE_VERSION(1, 1),
+   PCI_PROTOCOL_VERSION_CURRENT = PCI_PROTOCOL_VERSION_1_1
+};
+
+#define PCI_CONFIG_MMIO_LENGTH 0x2000
+#define MAX_SUPPORTED_MSI_MESSAGES 0x400
+
+/*
+ * Message Types
+ */
+
+enum pci_message_type {
+   /*
+* Version 1.1
+*/
+   PCI_MESSAGE_BASE= 0x4249,
+   PCI_BUS_RELATIONS   = PCI_MESSAGE_BASE + 0,
+   PCI_QUERY_BUS_RELATIONS = PCI_MESSAGE_BASE + 1,
+   PCI_POWER_STATE_CHANGE  = PCI_MESSAGE_BASE + 4,
+   PCI_QUERY_RESOURCE_REQUIREMENTS = PCI_MESSAGE_BASE + 5,
+   PCI_QUERY_RESOURCE_RESOURCES= PCI_MESSAGE_BASE + 6,
+   PCI_BUS_D0ENTRY = PCI_MESSAGE_BASE + 7,
+   PCI_BUS_D0EXIT  = PCI_MESSAGE_BASE + 8,
+   PCI_READ_BLOCK  = PCI_MESSAGE_BASE + 9,
+   PCI_WRITE_BLOCK = PCI_MESSAGE_BASE + 0xA,
+   PCI_EJECT   = PCI_MESSAGE_BASE + 0xB,
+   PCI_QUERY_STOP  = PCI_MESSAGE_BASE + 0xC,
+   PCI_REENABLE= PCI_MESSAGE_BASE + 0xD,
+   PCI_QUERY_STOP_FAILED   = PCI_MESSAGE_BASE + 0xE,
+   PCI_EJECTION_COMPLETE   = PCI_MESSAGE_BASE + 0xF,
+   PCI_RESOURCES_ASSIGNED  = PCI_MESSAGE_BASE + 0x10,
+   PCI_RESOURCES_RELEASED  = PCI_MESSAGE_BASE + 0x11,
+   PCI_INVALIDATE_BLOCK= PCI_MESSAGE_BASE + 0x12,
+   PCI_QUERY_PROTOCOL_VERSION  = PCI_MESSAGE_BASE + 0x13,
+   PCI_CREATE_INTERRUPT_MESSAGE= PCI_MESSAGE_BASE + 0x14,
+   PCI_DELETE_INTERRUPT_ME

[PATCH v10 2/7] drivers:hv: Export hv_do_hypercall()

2015-12-10 Thread jakeo
From: Jake Oshins 

This patch exposes the function that hv_vmbus.ko uses to make hypercalls.
This is necessary for retargeting an interrupt when it is given a new
affinity and vector.

Signed-off-by: Jake Oshins 
---
 drivers/hv/hv.c   | 20 ++--
 drivers/hv/hyperv_vmbus.h |  2 +-
 include/linux/hyperv.h|  1 +
 3 files changed, 12 insertions(+), 11 deletions(-)

diff --git a/drivers/hv/hv.c b/drivers/hv/hv.c
index 6341be8..7a06933 100644
--- a/drivers/hv/hv.c
+++ b/drivers/hv/hv.c
@@ -89,9 +89,9 @@ static int query_hypervisor_info(void)
 }
 
 /*
- * do_hypercall- Invoke the specified hypercall
+ * hv_do_hypercall- Invoke the specified hypercall
  */
-static u64 do_hypercall(u64 control, void *input, void *output)
+u64 hv_do_hypercall(u64 control, void *input, void *output)
 {
u64 input_address = (input) ? virt_to_phys(input) : 0;
u64 output_address = (output) ? virt_to_phys(output) : 0;
@@ -132,6 +132,7 @@ static u64 do_hypercall(u64 control, void *input, void 
*output)
return hv_status_lo | ((u64)hv_status_hi << 32);
 #endif /* !x86_64 */
 }
+EXPORT_SYMBOL_GPL(hv_do_hypercall);
 
 #ifdef CONFIG_X86_64
 static cycle_t read_hv_clock_tsc(struct clocksource *arg)
@@ -315,7 +316,7 @@ int hv_post_message(union hv_connection_id connection_id,
 {
 
struct hv_input_post_message *aligned_msg;
-   u16 status;
+   u64 status;
 
if (payload_size > HV_MESSAGE_PAYLOAD_BYTE_COUNT)
return -EMSGSIZE;
@@ -329,11 +330,10 @@ int hv_post_message(union hv_connection_id connection_id,
aligned_msg->payload_size = payload_size;
memcpy((void *)aligned_msg->payload, payload, payload_size);
 
-   status = do_hypercall(HVCALL_POST_MESSAGE, aligned_msg, NULL)
-   & 0x;
+   status = hv_do_hypercall(HVCALL_POST_MESSAGE, aligned_msg, NULL);
 
put_cpu();
-   return status;
+   return status & 0x;
 }
 
 
@@ -343,13 +343,13 @@ int hv_post_message(union hv_connection_id connection_id,
  *
  * This involves a hypercall.
  */
-u16 hv_signal_event(void *con_id)
+int hv_signal_event(void *con_id)
 {
-   u16 status;
+   u64 status;
 
-   status = (do_hypercall(HVCALL_SIGNAL_EVENT, con_id, NULL) & 0x);
+   status = hv_do_hypercall(HVCALL_SIGNAL_EVENT, con_id, NULL);
 
-   return status;
+   return status & 0x;
 }
 
 static int hv_ce_set_next_event(unsigned long delta,
diff --git a/drivers/hv/hyperv_vmbus.h b/drivers/hv/hyperv_vmbus.h
index 3782636..cc2fb53 100644
--- a/drivers/hv/hyperv_vmbus.h
+++ b/drivers/hv/hyperv_vmbus.h
@@ -582,7 +582,7 @@ extern int hv_post_message(union hv_connection_id 
connection_id,
 enum hv_message_type message_type,
 void *payload, size_t payload_size);
 
-extern u16 hv_signal_event(void *con_id);
+extern int hv_signal_event(void *con_id);
 
 extern int hv_synic_alloc(void);
 
diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h
index fddb3e0..24d0b65 100644
--- a/include/linux/hyperv.h
+++ b/include/linux/hyperv.h
@@ -984,6 +984,7 @@ int vmbus_allocate_mmio(struct resource **new, struct 
hv_device *device_obj,
bool fb_overlap_ok);
 
 int vmbus_cpu_number_to_vp_number(int cpu_number);
+u64 hv_do_hypercall(u64 control, void *input, void *output);
 
 /**
  * VMBUS_DEVICE - macro used to describe a specific hyperv vmbus device
-- 
1.9.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH v10 7/7] PCI: hv: New paravirtual PCI front-end for Hyper-V VMs

2015-12-10 Thread jakeo
From: Jake Oshins 

This patch introduces a new driver which exposes a root PCI bus whenever a
PCI Express device is passed through to a guest VM under Hyper-V. The
device can be single- or multi-function. The interrupts for the devices
are managed by an IRQ domain, implemented within the driver.

Signed-off-by: Jake Oshins 
---
 MAINTAINERS|1 +
 drivers/pci/Kconfig|7 +
 drivers/pci/host/Makefile  |1 +
 drivers/pci/host/hv_pcifront.c | 2249 
 4 files changed, 2258 insertions(+)
 create mode 100644 drivers/pci/host/hv_pcifront.c

diff --git a/MAINTAINERS b/MAINTAINERS
index e6ec986..40747e8 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -5115,6 +5115,7 @@ F:arch/x86/kernel/cpu/mshyperv.c
 F: drivers/hid/hid-hyperv.c
 F: drivers/hv/
 F: drivers/input/serio/hyperv-keyboard.c
+F: drivers/pci/host/hv_pcifront.c
 F: drivers/net/hyperv/
 F: drivers/scsi/storvsc_drv.c
 F: drivers/video/fbdev/hyperv_fb.c
diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig
index 73de4ef..573b8d6 100644
--- a/drivers/pci/Kconfig
+++ b/drivers/pci/Kconfig
@@ -118,4 +118,11 @@ config PCI_LABEL
def_bool y if (DMI || ACPI)
select NLS
 
+config HYPERV_VPCI
+tristate "Hyper-V PCI Frontend"
+depends on PCI && X86 && HYPERV && PCI_MSI && PCI_MSI_IRQ_DOMAIN && 
X86_64
+help
+  The PCI device frontend driver allows the kernel to import arbitrary
+  PCI devices from a PCI backend to support PCI driver domains.
+
 source "drivers/pci/host/Kconfig"
diff --git a/drivers/pci/host/Makefile b/drivers/pci/host/Makefile
index 9d4d3c6..d9abd2a 100644
--- a/drivers/pci/host/Makefile
+++ b/drivers/pci/host/Makefile
@@ -2,6 +2,7 @@ obj-$(CONFIG_PCIE_DW) += pcie-designware.o
 obj-$(CONFIG_PCI_DRA7XX) += pci-dra7xx.o
 obj-$(CONFIG_PCI_EXYNOS) += pci-exynos.o
 obj-$(CONFIG_PCI_IMX6) += pci-imx6.o
+obj-$(CONFIG_HYPERV_VPCI) += hv_pcifront.o
 obj-$(CONFIG_PCI_MVEBU) += pci-mvebu.o
 obj-$(CONFIG_PCI_TEGRA) += pci-tegra.o
 obj-$(CONFIG_PCI_RCAR_GEN2) += pci-rcar-gen2.o
diff --git a/drivers/pci/host/hv_pcifront.c b/drivers/pci/host/hv_pcifront.c
new file mode 100644
index 000..56da07e
--- /dev/null
+++ b/drivers/pci/host/hv_pcifront.c
@@ -0,0 +1,2249 @@
+/*
+ * Copyright (c) Microsoft Corporation.
+ *
+ * Author:
+ *   Jake Oshins 
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+ * NON INFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+/*
+ * Protocol versions. The low word is the minor version, the high word the 
major
+ * version.
+ */
+
+#define PCI_MAKE_VERSION(major, minor) ((__u32)(((major) << 16) | (major)))
+#define PCI_MAJOR_VERSION(version) ((__u32)(version) >> 16)
+#define PCI_MINOR_VERSION(version) ((__u32)(version) & 0xff)
+
+enum {
+   PCI_PROTOCOL_VERSION_1_1 = PCI_MAKE_VERSION(1, 1),
+   PCI_PROTOCOL_VERSION_CURRENT = PCI_PROTOCOL_VERSION_1_1
+};
+
+#define PCI_CONFIG_MMIO_LENGTH 0x2000
+#define MAX_SUPPORTED_MSI_MESSAGES 0x400
+
+/*
+ * Message Types
+ */
+
+enum pci_message_type {
+   /*
+* Version 1.1
+*/
+   PCI_MESSAGE_BASE= 0x4249,
+   PCI_BUS_RELATIONS   = PCI_MESSAGE_BASE + 0,
+   PCI_QUERY_BUS_RELATIONS = PCI_MESSAGE_BASE + 1,
+   PCI_POWER_STATE_CHANGE  = PCI_MESSAGE_BASE + 4,
+   PCI_QUERY_RESOURCE_REQUIREMENTS = PCI_MESSAGE_BASE + 5,
+   PCI_QUERY_RESOURCE_RESOURCES= PCI_MESSAGE_BASE + 6,
+   PCI_BUS_D0ENTRY = PCI_MESSAGE_BASE + 7,
+   PCI_BUS_D0EXIT  = PCI_MESSAGE_BASE + 8,
+   PCI_READ_BLOCK  = PCI_MESSAGE_BASE + 9,
+   PCI_WRITE_BLOCK = PCI_MESSAGE_BASE + 0xA,
+   PCI_EJECT   = PCI_MESSAGE_BASE + 0xB,
+   PCI_QUERY_STOP  = PCI_MESSAGE_BASE + 0xC,
+   PCI_REENABLE= PCI_MESSAGE_BASE + 0xD,
+   PCI_QUERY_STOP_FAILED   = PCI_MESSAGE_BASE + 0xE,
+   PCI_EJECTION_COMPLETE   = PCI_MESSAGE_BASE + 0xF,
+   PCI_RESOURCES_ASSIGNED  = PCI_MESSAGE_BASE + 0x10,
+   PCI_RESOURCES_RELEASED  = PCI_MESSAGE_BASE + 0x11,
+   PCI_INVALIDATE_BLOCK= PCI_MESSAGE_BASE + 0x12,
+   PCI_QUERY_PROTOCOL_VERSION  = PCI_MESSAGE_BASE + 0x13,
+   PCI_CREATE_INTERRUPT_MESSAGE= PCI_MESSAGE_BASE + 0x14,
+   PCI_DELETE_INTERRUPT_ME

[PATCH v10 5/7] PCI: irqdomain: Look up IRQ domain by fwnode_handle

2015-12-10 Thread jakeo
From: Jake Oshins 

This patch adds a second way of finding an IRQ domain associated with
a root PCI bus.  After looking to see if one can be found through
the OF tree, it attempts to look up the IRQ domain through an
fwnode_handle stored in the pci_sysdata struct.

Signed-off-by: Jake Oshins 
---
 drivers/pci/probe.c | 14 ++
 1 file changed, 14 insertions(+)

diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index 750f907..c6369dd 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -674,6 +674,20 @@ static struct irq_domain 
*pci_host_bridge_msi_domain(struct pci_bus *bus)
 */
d = pci_host_bridge_of_msi_domain(bus);
 
+#ifdef CONFIG_PCI_MSI_IRQ_DOMAIN
+   /*
+* If no IRQ domain was found via the OF tree, try looking it up
+* directly through the fwnode_handle.
+*/
+   if (!d) {
+   struct fwnode_handle *fwnode = pci_root_bus_fwnode(bus);
+
+   if (fwnode)
+   d = irq_find_matching_fwnode(fwnode,
+DOMAIN_BUS_PCI_MSI);
+   }
+#endif
+
return d;
 }
 
-- 
1.9.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH v10 3/7] PCI: Make it possible to implement a PCI MSI IRQ Domain in a module.

2015-12-10 Thread jakeo
From: Jake Oshins 

The Linux kernel already has the concpet of IRQ domain, wherein a
component can expose a set of IRQs which are managed by a particular
interrupt controller chip or other subsystem. The PCI driver exposes
the notion of an IRQ domain for Message-Signaled Interrupts (MSI) from
PCI Express devices. This patch exposes the functions which are
necessary for making an MSI IRQ domain within a module.

Signed-off-by: Jake Oshins 
---
 arch/x86/include/asm/msi.h| 6 ++
 arch/x86/kernel/apic/msi.c| 8 +---
 arch/x86/kernel/apic/vector.c | 2 ++
 drivers/pci/msi.c | 4 
 kernel/irq/chip.c | 1 +
 kernel/irq/irqdomain.c| 4 
 6 files changed, 22 insertions(+), 3 deletions(-)

diff --git a/arch/x86/include/asm/msi.h b/arch/x86/include/asm/msi.h
index 93724cc..eb4b09b 100644
--- a/arch/x86/include/asm/msi.h
+++ b/arch/x86/include/asm/msi.h
@@ -1,7 +1,13 @@
 #ifndef _ASM_X86_MSI_H
 #define _ASM_X86_MSI_H
 #include 
+#include 
 
 typedef struct irq_alloc_info msi_alloc_info_t;
 
+int pci_msi_prepare(struct irq_domain *domain, struct device *dev, int nvec,
+   msi_alloc_info_t *arg);
+
+void pci_msi_set_desc(msi_alloc_info_t *arg, struct msi_desc *desc);
+
 #endif /* _ASM_X86_MSI_H */
diff --git a/arch/x86/kernel/apic/msi.c b/arch/x86/kernel/apic/msi.c
index 5f1feb6..ade2532 100644
--- a/arch/x86/kernel/apic/msi.c
+++ b/arch/x86/kernel/apic/msi.c
@@ -96,8 +96,8 @@ static irq_hw_number_t pci_msi_get_hwirq(struct 
msi_domain_info *info,
return arg->msi_hwirq;
 }
 
-static int pci_msi_prepare(struct irq_domain *domain, struct device *dev,
-  int nvec, msi_alloc_info_t *arg)
+int pci_msi_prepare(struct irq_domain *domain, struct device *dev, int nvec,
+   msi_alloc_info_t *arg)
 {
struct pci_dev *pdev = to_pci_dev(dev);
struct msi_desc *desc = first_pci_msi_entry(pdev);
@@ -113,11 +113,13 @@ static int pci_msi_prepare(struct irq_domain *domain, 
struct device *dev,
 
return 0;
 }
+EXPORT_SYMBOL_GPL(pci_msi_prepare);
 
-static void pci_msi_set_desc(msi_alloc_info_t *arg, struct msi_desc *desc)
+void pci_msi_set_desc(msi_alloc_info_t *arg, struct msi_desc *desc)
 {
arg->msi_hwirq = pci_msi_domain_calc_hwirq(arg->msi_dev, desc);
 }
+EXPORT_SYMBOL_GPL(pci_msi_set_desc);
 
 static struct msi_domain_ops pci_msi_domain_ops = {
.get_hwirq  = pci_msi_get_hwirq,
diff --git a/arch/x86/kernel/apic/vector.c b/arch/x86/kernel/apic/vector.c
index 861bc59..908cb37 100644
--- a/arch/x86/kernel/apic/vector.c
+++ b/arch/x86/kernel/apic/vector.c
@@ -29,6 +29,7 @@ struct apic_chip_data {
 };
 
 struct irq_domain *x86_vector_domain;
+EXPORT_SYMBOL_GPL(x86_vector_domain);
 static DEFINE_RAW_SPINLOCK(vector_lock);
 static cpumask_var_t vector_cpumask;
 static struct irq_chip lapic_controller;
@@ -66,6 +67,7 @@ struct irq_cfg *irqd_cfg(struct irq_data *irq_data)
 
return data ? &data->cfg : NULL;
 }
+EXPORT_SYMBOL_GPL(irqd_cfg);
 
 struct irq_cfg *irq_cfg(unsigned int irq)
 {
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
index 7eaa4c8..7a0df3f 100644
--- a/drivers/pci/msi.c
+++ b/drivers/pci/msi.c
@@ -257,6 +257,7 @@ void pci_msi_mask_irq(struct irq_data *data)
 {
msi_set_mask_bit(data, 1);
 }
+EXPORT_SYMBOL_GPL(pci_msi_mask_irq);
 
 /**
  * pci_msi_unmask_irq - Generic irq chip callback to unmask PCI/MSI interrupts
@@ -266,6 +267,7 @@ void pci_msi_unmask_irq(struct irq_data *data)
 {
msi_set_mask_bit(data, 0);
 }
+EXPORT_SYMBOL_GPL(pci_msi_unmask_irq);
 
 void default_restore_msi_irqs(struct pci_dev *dev)
 {
@@ -1126,6 +1128,7 @@ struct pci_dev *msi_desc_to_pci_dev(struct msi_desc *desc)
 {
return to_pci_dev(desc->dev);
 }
+EXPORT_SYMBOL(msi_desc_to_pci_dev);
 
 void *msi_desc_to_pci_sysdata(struct msi_desc *desc)
 {
@@ -1285,6 +1288,7 @@ struct irq_domain *pci_msi_create_irq_domain(struct 
fwnode_handle *fwnode,
domain->bus_token = DOMAIN_BUS_PCI_MSI;
return domain;
 }
+EXPORT_SYMBOL_GPL(pci_msi_create_irq_domain);
 
 /**
  * pci_msi_domain_alloc_irqs - Allocate interrupts for @dev in @domain
diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c
index 05e29de..5797909 100644
--- a/kernel/irq/chip.c
+++ b/kernel/irq/chip.c
@@ -950,6 +950,7 @@ void irq_chip_ack_parent(struct irq_data *data)
data = data->parent_data;
data->chip->irq_ack(data);
 }
+EXPORT_SYMBOL_GPL(irq_chip_ack_parent);
 
 /**
  * irq_chip_mask_parent - Mask the parent interrupt
diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
index 22aa961..aa6ac44 100644
--- a/kernel/irq/irqdomain.c
+++ b/kernel/irq/irqdomain.c
@@ -60,6 +60,7 @@ struct fwnode_handle *irq_domain_alloc_fwnode(void *data)
fwid->fwnode.type = FWNODE_IRQCHIP;
return &fwid->fwnode;
 }
+EXPORT_SYMBOL_GPL(irq_domain_alloc_fwnode);
 
 /**
  * irq_domain_free_fwnode - Free a non-OF-backed fwnode_handle
@@ -77,6 +78,7 @@ void irq_domain_free_fwnode(struct fwnode_

[PATCH v10 1/7] drivers:hv: Export a function that maps Linux CPU num onto Hyper-V proc num

2015-12-10 Thread jakeo
From: Jake Oshins 

This patch exposes the mapping between Linux CPU number and Hyper-V
virtual processor number. This is necessary because the hypervisor needs
to know which virtual processor to target when making a mapping in the
Interrupt Redirection Table in the I/O MMU.

Signed-off-by: Jake Oshins 
---
 drivers/hv/vmbus_drv.c | 17 +
 include/linux/hyperv.h |  2 ++
 2 files changed, 19 insertions(+)

diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c
index f19b6f7..c89d0e5 100644
--- a/drivers/hv/vmbus_drv.c
+++ b/drivers/hv/vmbus_drv.c
@@ -1191,6 +1191,23 @@ int vmbus_allocate_mmio(struct resource **new, struct 
hv_device *device_obj,
 }
 EXPORT_SYMBOL_GPL(vmbus_allocate_mmio);
 
+/**
+ * vmbus_cpu_number_to_vp_number() - Map CPU to VP.
+ * @cpu_number: CPU number in Linux terms
+ *
+ * This function returns the mapping between the Linux processor
+ * number and the hypervisor's virtual processor number, useful
+ * in making hypercalls and such that talk about specific
+ * processors.
+ *
+ * Return: Virtual processor number in Hyper-V terms
+ */
+int vmbus_cpu_number_to_vp_number(int cpu_number)
+{
+   return hv_context.vp_index[cpu_number];
+}
+EXPORT_SYMBOL_GPL(vmbus_cpu_number_to_vp_number);
+
 static int vmbus_acpi_add(struct acpi_device *device)
 {
acpi_status result;
diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h
index 8fdc17b..fddb3e0 100644
--- a/include/linux/hyperv.h
+++ b/include/linux/hyperv.h
@@ -983,6 +983,8 @@ int vmbus_allocate_mmio(struct resource **new, struct 
hv_device *device_obj,
resource_size_t size, resource_size_t align,
bool fb_overlap_ok);
 
+int vmbus_cpu_number_to_vp_number(int cpu_number);
+
 /**
  * VMBUS_DEVICE - macro used to describe a specific hyperv vmbus device
  *
-- 
1.9.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH v10 0/7] PCI: hv: New paravirtual PCI front-end for Hyper-V VMs

2015-12-10 Thread jakeo
From: Jake Oshins 

This version of the patch series removes warning when compiling x86
32-bit while still making it build cleanly for x64.

First, export functions that allow correlating Hyper-V virtual processors
and Linux cpus, along with the means for invoking a hypercall that targets
interrupts at chosen vectors on specific cpus.

Second, mark various parts of IRQ domain related code as exported, so that
this PCI front-end can implement an IRQ domain as part of a module.  (The
alternative would be to pull all tyhis into the kernel, which would pull
in a lot of other Hyper-V related code, as this IRQ domain depends on
vmbus.ko.)

Third, modify PCI so that new root PCI buses can be marked with an associated
fwnode_handle, and so that root PCI buses can look up their associated IRQ
domain by that handle.

Fourth, introduce a new driver, hv_pcifront, which exposes root PCI buses in
a Hyper-V VM.  These root PCI buses expose real PCIe device, or PCI Virtual
Functions.


Jake Oshins (7):
  drivers:hv: Export a function that maps Linux CPU num onto Hyper-V
proc num
  drivers:hv: Export hv_do_hypercall()
  PCI: Make it possible to implement a PCI MSI IRQ Domain in a module.
  PCI: Add fwnode_handle to pci_sysdata
  PCI: irqdomain: Look up IRQ domain by fwnode_handle
  drivers:hv: Define the channel type of Hyper-V PCI Express
pass-through
  PCI: hv: New paravirtual PCI front-end for Hyper-V VMs

 MAINTAINERS|1 +
 arch/x86/include/asm/msi.h |6 +
 arch/x86/include/asm/pci.h |   15 +
 arch/x86/kernel/apic/msi.c |8 +-
 arch/x86/kernel/apic/vector.c  |2 +
 drivers/hv/hv.c|   20 +-
 drivers/hv/hyperv_vmbus.h  |2 +-
 drivers/hv/vmbus_drv.c |   17 +
 drivers/pci/Kconfig|7 +
 drivers/pci/host/Makefile  |1 +
 drivers/pci/host/hv_pcifront.c | 2249 
 drivers/pci/msi.c  |4 +
 drivers/pci/probe.c|   15 +
 include/linux/hyperv.h |   14 +
 include/linux/pci.h|4 +
 kernel/irq/chip.c  |1 +
 kernel/irq/irqdomain.c |4 +
 17 files changed, 2356 insertions(+), 14 deletions(-)
 create mode 100644 drivers/pci/host/hv_pcifront.c

-- 
1.9.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH v10 4/7] PCI: Add fwnode_handle to pci_sysdata

2015-12-10 Thread jakeo
From: Jake Oshins 

This patch adds an fwnode_handle to struct pci_sysdata, which is
used by the next patch in the series when trying to locate an
IRQ domain associated with a root PCI bus.

Signed-off-by: Jake Oshins 
---
 arch/x86/include/asm/pci.h | 15 +++
 drivers/pci/probe.c|  1 +
 include/linux/pci.h|  4 
 3 files changed, 20 insertions(+)

diff --git a/arch/x86/include/asm/pci.h b/arch/x86/include/asm/pci.h
index 4625943..6fc3c7c 100644
--- a/arch/x86/include/asm/pci.h
+++ b/arch/x86/include/asm/pci.h
@@ -20,6 +20,9 @@ struct pci_sysdata {
 #ifdef CONFIG_X86_64
void*iommu; /* IOMMU private data */
 #endif
+#ifdef CONFIG_PCI_MSI_IRQ_DOMAIN
+   void*fwnode;/* IRQ domain for MSI assignment */
+#endif
 };
 
 extern int pci_routeirq;
@@ -32,6 +35,7 @@ extern int noioapicreroute;
 static inline int pci_domain_nr(struct pci_bus *bus)
 {
struct pci_sysdata *sd = bus->sysdata;
+
return sd->domain;
 }
 
@@ -41,6 +45,17 @@ static inline int pci_proc_domain(struct pci_bus *bus)
 }
 #endif
 
+#ifdef CONFIG_PCI_MSI_IRQ_DOMAIN
+static inline void *_pci_root_bus_fwnode(struct pci_bus *bus)
+{
+   struct pci_sysdata *sd = bus->sysdata;
+
+   return sd->fwnode;
+}
+
+#define pci_root_bus_fwnode_pci_root_bus_fwnode
+#endif
+
 /* Can be used to override the logic in pci_scan_bus for skipping
already-configured bus numbers - to be used for buggy BIOSes
or architectures with incomplete PCI setup by the loader */
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index edb1984..750f907 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -15,6 +15,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include "pci.h"
 
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 6ae25aa..b414422 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -1517,6 +1517,10 @@ static inline int pci_get_new_domain_nr(void) { return 
-ENOSYS; }
 
 #include 
 
+#ifndef pci_root_bus_fwnode
+#define pci_root_bus_fwnode(bus)   ((void)(bus), NULL)
+#endif
+
 /* these helpers provide future and backwards compatibility
  * for accessing popular PCI BAR info */
 #define pci_resource_start(dev, bar)   ((dev)->resource[(bar)].start)
-- 
1.9.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH v10 6/7] drivers:hv: Define the channel type of Hyper-V PCI Express pass-through

2015-12-10 Thread jakeo
From: Jake Oshins 

This defines the channel type for PCI front-ends in Hyper-V VMs.

Signed-off-by: Jake Oshins 
---
 include/linux/hyperv.h | 11 +++
 1 file changed, 11 insertions(+)

diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h
index 24d0b65..c9a9eed 100644
--- a/include/linux/hyperv.h
+++ b/include/linux/hyperv.h
@@ -1141,6 +1141,17 @@ u64 hv_do_hypercall(u64 control, void *input, void 
*output);
}
 
 /*
+ * PCI Express Pass Through
+ * {44C4F61D--4400-9D52-802E27EDE19F}
+ */
+
+#define HV_PCIE_GUID \
+   .guid = { \
+   0x1D, 0xF6, 0xC4, 0x44, 0x44, 0x44, 0x00, 0x44, \
+   0x9D, 0x52, 0x80, 0x2E, 0x27, 0xED, 0xE1, 0x9F \
+   }
+
+/*
  * Common header for Hyper-V ICs
  */
 
-- 
1.9.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH RESEND 1/3] PCI: Add fwnode_handle to pci_sysdata

2016-02-02 Thread jakeo
From: Jake Oshins 

This patch adds an fwnode_handle to struct pci_sysdata, which is
used by the next patch in the series when trying to locate an
IRQ domain associated with a root PCI bus.

Signed-off-by: Jake Oshins 
---
 arch/x86/include/asm/pci.h | 15 +++
 drivers/pci/probe.c|  1 +
 include/linux/pci.h|  4 
 3 files changed, 20 insertions(+)

diff --git a/arch/x86/include/asm/pci.h b/arch/x86/include/asm/pci.h
index 4625943..6fc3c7c 100644
--- a/arch/x86/include/asm/pci.h
+++ b/arch/x86/include/asm/pci.h
@@ -20,6 +20,9 @@ struct pci_sysdata {
 #ifdef CONFIG_X86_64
void*iommu; /* IOMMU private data */
 #endif
+#ifdef CONFIG_PCI_MSI_IRQ_DOMAIN
+   void*fwnode;/* IRQ domain for MSI assignment */
+#endif
 };
 
 extern int pci_routeirq;
@@ -32,6 +35,7 @@ extern int noioapicreroute;
 static inline int pci_domain_nr(struct pci_bus *bus)
 {
struct pci_sysdata *sd = bus->sysdata;
+
return sd->domain;
 }
 
@@ -41,6 +45,17 @@ static inline int pci_proc_domain(struct pci_bus *bus)
 }
 #endif
 
+#ifdef CONFIG_PCI_MSI_IRQ_DOMAIN
+static inline void *_pci_root_bus_fwnode(struct pci_bus *bus)
+{
+   struct pci_sysdata *sd = bus->sysdata;
+
+   return sd->fwnode;
+}
+
+#define pci_root_bus_fwnode_pci_root_bus_fwnode
+#endif
+
 /* Can be used to override the logic in pci_scan_bus for skipping
already-configured bus numbers - to be used for buggy BIOSes
or architectures with incomplete PCI setup by the loader */
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index 6d7ab9b..b207e74 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -15,6 +15,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include "pci.h"
 
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 27df4a6..cd05a8e 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -1515,6 +1515,10 @@ static inline int pci_get_new_domain_nr(void) { return 
-ENOSYS; }
 
 #include 
 
+#ifndef pci_root_bus_fwnode
+#define pci_root_bus_fwnode(bus)   ((void)(bus), NULL)
+#endif
+
 /* these helpers provide future and backwards compatibility
  * for accessing popular PCI BAR info */
 #define pci_resource_start(dev, bar)   ((dev)->resource[(bar)].start)
-- 
1.9.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH RESEND 0/3] PCI: hv: New paravirtual PCI front-end driver

2016-02-02 Thread jakeo
From: Jake Oshins 

This is a resend of patches that enable PCI pass-through within Hyper-V
VMs.  This patch series only includes those which were deemed appropriate
for being incorportated via the PCI tree.  All other patches in previous
patch series have gone through other trees and are now in mainline.

The first two patches modify PCI so that new root PCI buses can be marked with
an associated fwnode_handle, and so that root PCI buses can look up their
associated IRQ domain by that handle.

The last patch, introduces a new driver, hv_pcifront, which exposes root PCI
buses in a Hyper-V VM.  These root PCI buses expose real PCIe devices, or PCI
Virtual Functions.


Jake Oshins (3):
  PCI: Add fwnode_handle to pci_sysdata
  PCI: irqdomain: Look up IRQ domain by fwnode_handle
  PCI: hv: New paravirtual PCI front-end for Hyper-V VMs

 MAINTAINERS|1 +
 arch/x86/include/asm/pci.h |   15 +
 drivers/pci/Kconfig|7 +
 drivers/pci/host/Makefile  |1 +
 drivers/pci/host/hv_pcifront.c | 2248 
 drivers/pci/probe.c|   15 +
 include/linux/pci.h|4 +
 7 files changed, 2291 insertions(+)
 create mode 100644 drivers/pci/host/hv_pcifront.c

-- 
1.9.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH RESEND 2/3] PCI: irqdomain: Look up IRQ domain by fwnode_handle

2016-02-02 Thread jakeo
From: Jake Oshins 

This patch adds a second way of finding an IRQ domain associated with
a root PCI bus.  After looking to see if one can be found through
the OF tree, it attempts to look up the IRQ domain through an
fwnode_handle stored in the pci_sysdata struct.

Signed-off-by: Jake Oshins 
---
 drivers/pci/probe.c | 14 ++
 1 file changed, 14 insertions(+)

diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index b207e74..1e34d21 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -676,6 +676,20 @@ static struct irq_domain 
*pci_host_bridge_msi_domain(struct pci_bus *bus)
if (!d)
d = pci_host_bridge_acpi_msi_domain(bus);
 
+#ifdef CONFIG_PCI_MSI_IRQ_DOMAIN
+   /*
+* If no IRQ domain was found via the OF tree, try looking it up
+* directly through the fwnode_handle.
+*/
+   if (!d) {
+   struct fwnode_handle *fwnode = pci_root_bus_fwnode(bus);
+
+   if (fwnode)
+   d = irq_find_matching_fwnode(fwnode,
+DOMAIN_BUS_PCI_MSI);
+   }
+#endif
+
return d;
 }
 
-- 
1.9.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH RESEND 3/3] PCI: hv: New paravirtual PCI front-end for Hyper-V VMs

2016-02-02 Thread jakeo
From: Jake Oshins 

This patch introduces a new driver which exposes a root PCI bus whenever a
PCI Express device is passed through to a guest VM under Hyper-V. The
device can be single- or multi-function. The interrupts for the devices
are managed by an IRQ domain, implemented within the driver.

Signed-off-by: Jake Oshins 
---
 MAINTAINERS|1 +
 drivers/pci/Kconfig|7 +
 drivers/pci/host/Makefile  |1 +
 drivers/pci/host/hv_pcifront.c | 2248 
 4 files changed, 2257 insertions(+)
 create mode 100644 drivers/pci/host/hv_pcifront.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 5161fb9..53f0959 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -5185,6 +5185,7 @@ F:arch/x86/kernel/cpu/mshyperv.c
 F: drivers/hid/hid-hyperv.c
 F: drivers/hv/
 F: drivers/input/serio/hyperv-keyboard.c
+F: drivers/pci/host/hv_pcifront.c
 F: drivers/net/hyperv/
 F: drivers/scsi/storvsc_drv.c
 F: drivers/video/fbdev/hyperv_fb.c
diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig
index 73de4ef..573b8d6 100644
--- a/drivers/pci/Kconfig
+++ b/drivers/pci/Kconfig
@@ -118,4 +118,11 @@ config PCI_LABEL
def_bool y if (DMI || ACPI)
select NLS
 
+config HYPERV_VPCI
+tristate "Hyper-V PCI Frontend"
+depends on PCI && X86 && HYPERV && PCI_MSI && PCI_MSI_IRQ_DOMAIN && 
X86_64
+help
+  The PCI device frontend driver allows the kernel to import arbitrary
+  PCI devices from a PCI backend to support PCI driver domains.
+
 source "drivers/pci/host/Kconfig"
diff --git a/drivers/pci/host/Makefile b/drivers/pci/host/Makefile
index 7b2f20c..6102aa9 100644
--- a/drivers/pci/host/Makefile
+++ b/drivers/pci/host/Makefile
@@ -2,6 +2,7 @@ obj-$(CONFIG_PCIE_DW) += pcie-designware.o
 obj-$(CONFIG_PCI_DRA7XX) += pci-dra7xx.o
 obj-$(CONFIG_PCI_EXYNOS) += pci-exynos.o
 obj-$(CONFIG_PCI_IMX6) += pci-imx6.o
+obj-$(CONFIG_HYPERV_VPCI) += hv_pcifront.o
 obj-$(CONFIG_PCI_MVEBU) += pci-mvebu.o
 obj-$(CONFIG_PCI_TEGRA) += pci-tegra.o
 obj-$(CONFIG_PCI_RCAR_GEN2) += pci-rcar-gen2.o
diff --git a/drivers/pci/host/hv_pcifront.c b/drivers/pci/host/hv_pcifront.c
new file mode 100644
index 000..d2ed1be
--- /dev/null
+++ b/drivers/pci/host/hv_pcifront.c
@@ -0,0 +1,2248 @@
+/*
+ * Copyright (c) Microsoft Corporation.
+ *
+ * Author:
+ *   Jake Oshins 
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+ * NON INFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+/*
+ * Protocol versions. The low word is the minor version, the high word the 
major
+ * version.
+ */
+
+#define PCI_MAKE_VERSION(major, minor) ((__u32)(((major) << 16) | (major)))
+#define PCI_MAJOR_VERSION(version) ((__u32)(version) >> 16)
+#define PCI_MINOR_VERSION(version) ((__u32)(version) & 0xff)
+
+enum {
+   PCI_PROTOCOL_VERSION_1_1 = PCI_MAKE_VERSION(1, 1),
+   PCI_PROTOCOL_VERSION_CURRENT = PCI_PROTOCOL_VERSION_1_1
+};
+
+#define PCI_CONFIG_MMIO_LENGTH 0x2000
+#define MAX_SUPPORTED_MSI_MESSAGES 0x400
+
+/*
+ * Message Types
+ */
+
+enum pci_message_type {
+   /*
+* Version 1.1
+*/
+   PCI_MESSAGE_BASE= 0x4249,
+   PCI_BUS_RELATIONS   = PCI_MESSAGE_BASE + 0,
+   PCI_QUERY_BUS_RELATIONS = PCI_MESSAGE_BASE + 1,
+   PCI_POWER_STATE_CHANGE  = PCI_MESSAGE_BASE + 4,
+   PCI_QUERY_RESOURCE_REQUIREMENTS = PCI_MESSAGE_BASE + 5,
+   PCI_QUERY_RESOURCE_RESOURCES= PCI_MESSAGE_BASE + 6,
+   PCI_BUS_D0ENTRY = PCI_MESSAGE_BASE + 7,
+   PCI_BUS_D0EXIT  = PCI_MESSAGE_BASE + 8,
+   PCI_READ_BLOCK  = PCI_MESSAGE_BASE + 9,
+   PCI_WRITE_BLOCK = PCI_MESSAGE_BASE + 0xA,
+   PCI_EJECT   = PCI_MESSAGE_BASE + 0xB,
+   PCI_QUERY_STOP  = PCI_MESSAGE_BASE + 0xC,
+   PCI_REENABLE= PCI_MESSAGE_BASE + 0xD,
+   PCI_QUERY_STOP_FAILED   = PCI_MESSAGE_BASE + 0xE,
+   PCI_EJECTION_COMPLETE   = PCI_MESSAGE_BASE + 0xF,
+   PCI_RESOURCES_ASSIGNED  = PCI_MESSAGE_BASE + 0x10,
+   PCI_RESOURCES_RELEASED  = PCI_MESSAGE_BASE + 0x11,
+   PCI_INVALIDATE_BLOCK= PCI_MESSAGE_BASE + 0x12,
+   PCI_QUERY_PROTOCOL_VERSION  = PCI_MESSAGE_BASE + 0x13,
+   PCI_CREATE_INTERRUPT_MESSAGE= PCI_MESSAGE_BASE + 0x14,
+   PCI_DELETE_INTERRUPT_ME

[PATCH RESEND v2 0/3] PCI: hv: New paravirtual PCI front-end driver

2016-02-09 Thread jakeo
From: Jake Oshins 

This version incorporates feedback from Bjorn Helgaas and fixes a build
break reported by the kbuild test robot.

This is a resend of patches that enable PCI pass-through within Hyper-V
VMs.  This patch series only includes those which were deemed appropriate
for being incorportated via the PCI tree.  All other patches in previous
patch series have gone through other trees and are now in mainline.

The first two patches modify PCI so that new root PCI buses can be marked with
an associated fwnode_handle, and so that root PCI buses can look up their
associated IRQ domain by that handle.

The last patch, introduces a new driver, hv_pcifront, which exposes root PCI
buses in a Hyper-V VM.  These root PCI buses expose real PCIe devices, or PCI
Virtual Functions.

Jake Oshins (3):
  PCI: Add fwnode_handle to pci_sysdata
  PCI: irqdomain: Look up IRQ domain by fwnode_handle
  PCI: hv: New paravirtual PCI front-end for Hyper-V VMs

 MAINTAINERS   |1 +
 arch/x86/include/asm/pci.h|   15 +
 drivers/pci/Kconfig   |7 +
 drivers/pci/host/Makefile |1 +
 drivers/pci/host/pci-hyperv.c | 2373 +
 drivers/pci/probe.c   |   15 +
 include/linux/pci.h   |4 +
 7 files changed, 2416 insertions(+)
 create mode 100644 drivers/pci/host/pci-hyperv.c

--
1.9.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH RESEND v2 2/3] PCI: irqdomain: Look up IRQ domain by fwnode_handle

2016-02-09 Thread jakeo
From: Jake Oshins 

This patch adds a second way of finding an IRQ domain associated with
a root PCI bus.  After looking to see if one can be found through
the OF tree, it attempts to look up the IRQ domain through an
fwnode_handle stored in the pci_sysdata struct.

Signed-off-by: Jake Oshins 
---
 drivers/pci/probe.c | 15 +++
 1 file changed, 15 insertions(+)

diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index 6d7ab9b..1e34d21 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -15,6 +15,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include "pci.h"
 
@@ -675,6 +676,20 @@ static struct irq_domain 
*pci_host_bridge_msi_domain(struct pci_bus *bus)
if (!d)
d = pci_host_bridge_acpi_msi_domain(bus);
 
+#ifdef CONFIG_PCI_MSI_IRQ_DOMAIN
+   /*
+* If no IRQ domain was found via the OF tree, try looking it up
+* directly through the fwnode_handle.
+*/
+   if (!d) {
+   struct fwnode_handle *fwnode = pci_root_bus_fwnode(bus);
+
+   if (fwnode)
+   d = irq_find_matching_fwnode(fwnode,
+DOMAIN_BUS_PCI_MSI);
+   }
+#endif
+
return d;
 }
 
-- 
1.9.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH RESEND v2 1/3] PCI: Add fwnode_handle to pci_sysdata

2016-02-09 Thread jakeo
From: Jake Oshins 

This patch adds an fwnode_handle to struct pci_sysdata, which is
used by the next patch in the series when trying to locate an
IRQ domain associated with a root PCI bus.

Signed-off-by: Jake Oshins 
---
 arch/x86/include/asm/pci.h | 15 +++
 include/linux/pci.h|  4 
 2 files changed, 19 insertions(+)

diff --git a/arch/x86/include/asm/pci.h b/arch/x86/include/asm/pci.h
index 4625943..6fc3c7c 100644
--- a/arch/x86/include/asm/pci.h
+++ b/arch/x86/include/asm/pci.h
@@ -20,6 +20,9 @@ struct pci_sysdata {
 #ifdef CONFIG_X86_64
void*iommu; /* IOMMU private data */
 #endif
+#ifdef CONFIG_PCI_MSI_IRQ_DOMAIN
+   void*fwnode;/* IRQ domain for MSI assignment */
+#endif
 };
 
 extern int pci_routeirq;
@@ -32,6 +35,7 @@ extern int noioapicreroute;
 static inline int pci_domain_nr(struct pci_bus *bus)
 {
struct pci_sysdata *sd = bus->sysdata;
+
return sd->domain;
 }
 
@@ -41,6 +45,17 @@ static inline int pci_proc_domain(struct pci_bus *bus)
 }
 #endif
 
+#ifdef CONFIG_PCI_MSI_IRQ_DOMAIN
+static inline void *_pci_root_bus_fwnode(struct pci_bus *bus)
+{
+   struct pci_sysdata *sd = bus->sysdata;
+
+   return sd->fwnode;
+}
+
+#define pci_root_bus_fwnode_pci_root_bus_fwnode
+#endif
+
 /* Can be used to override the logic in pci_scan_bus for skipping
already-configured bus numbers - to be used for buggy BIOSes
or architectures with incomplete PCI setup by the loader */
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 27df4a6..1bb44af 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -1515,6 +1515,10 @@ static inline int pci_get_new_domain_nr(void) { return 
-ENOSYS; }
 
 #include 
 
+#ifndef pci_root_bus_fwnode
+#define pci_root_bus_fwnode(bus)   NULL
+#endif
+
 /* these helpers provide future and backwards compatibility
  * for accessing popular PCI BAR info */
 #define pci_resource_start(dev, bar)   ((dev)->resource[(bar)].start)
-- 
1.9.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH RESEND v2 3/3] PCI: hv: New paravirtual PCI front-end for Hyper-V VMs

2016-02-09 Thread jakeo
From: Jake Oshins 

This patch introduces a new driver which exposes a root PCI bus whenever a
PCI Express device is passed through to a guest VM under Hyper-V. The
device can be single- or multi-function. The interrupts for the devices
are managed by an IRQ domain, implemented within the driver.

Signed-off-by: Jake Oshins 
---
 MAINTAINERS   |1 +
 drivers/pci/Kconfig   |7 +
 drivers/pci/host/Makefile |1 +
 drivers/pci/host/pci-hyperv.c | 2373 +
 4 files changed, 2382 insertions(+)
 create mode 100644 drivers/pci/host/pci-hyperv.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 30aca4a..b68c015 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -5193,6 +5193,7 @@ F:arch/x86/kernel/cpu/mshyperv.c
 F: drivers/hid/hid-hyperv.c
 F: drivers/hv/
 F: drivers/input/serio/hyperv-keyboard.c
+F: drivers/pci/host/pci-hyperv.c
 F: drivers/net/hyperv/
 F: drivers/scsi/storvsc_drv.c
 F: drivers/video/fbdev/hyperv_fb.c
diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig
index 73de4ef..54a5441 100644
--- a/drivers/pci/Kconfig
+++ b/drivers/pci/Kconfig
@@ -118,4 +118,11 @@ config PCI_LABEL
def_bool y if (DMI || ACPI)
select NLS
 
+config PCI_HYPERV
+tristate "Hyper-V PCI Frontend"
+depends on PCI && X86 && HYPERV && PCI_MSI && PCI_MSI_IRQ_DOMAIN && 
X86_64
+help
+  The PCI device frontend driver allows the kernel to import arbitrary
+  PCI devices from a PCI backend to support PCI driver domains.
+
 source "drivers/pci/host/Kconfig"
diff --git a/drivers/pci/host/Makefile b/drivers/pci/host/Makefile
index 7b2f20c..152daf9 100644
--- a/drivers/pci/host/Makefile
+++ b/drivers/pci/host/Makefile
@@ -2,6 +2,7 @@ obj-$(CONFIG_PCIE_DW) += pcie-designware.o
 obj-$(CONFIG_PCI_DRA7XX) += pci-dra7xx.o
 obj-$(CONFIG_PCI_EXYNOS) += pci-exynos.o
 obj-$(CONFIG_PCI_IMX6) += pci-imx6.o
+obj-$(CONFIG_PCI_HYPERV) += pci-hyperv.o
 obj-$(CONFIG_PCI_MVEBU) += pci-mvebu.o
 obj-$(CONFIG_PCI_TEGRA) += pci-tegra.o
 obj-$(CONFIG_PCI_RCAR_GEN2) += pci-rcar-gen2.o
diff --git a/drivers/pci/host/pci-hyperv.c b/drivers/pci/host/pci-hyperv.c
new file mode 100644
index 000..2ca43f1
--- /dev/null
+++ b/drivers/pci/host/pci-hyperv.c
@@ -0,0 +1,2373 @@
+/*
+ * Copyright (c) Microsoft Corporation.
+ *
+ * Author:
+ *   Jake Oshins 
+ *
+ * This driver acts as a paravirtual front-end for PCI Express root buses.
+ * When a PCI Express function (either an entire device or an SR-IOV
+ * Virtual Function) is being passed through to the VM, this driver exposes
+ * a new bus to the guest VM.  This is modeled as a root PCI bus because
+ * no bridges are being exposed to the VM.  In fact, with a "Generation 2"
+ * VM within Hyper-V, there may seem to be no PCI bus at all in the VM
+ * until a device as been exposed using this driver.
+ *
+ * Each root PCI bus has its own PCI domain, which is called "Segment" in
+ * the PCI Firmware Specifications.  Thus while each device passed through
+ * to the VM using this front-end will appear at "device 0", the domain will
+ * be unique.  Typically, each bus will have one PCI function on it, though
+ * this driver does support more than one.
+ *
+ * In order to map the interrupts from the device through to the guest VM,
+ * this driver also implements an IRQ Domain, which handles interrupts (either
+ * MSI or MSI-X) associated with the functions on the bus.  As interrupts are
+ * set up, torn down, or reaffined, this driver communicates with the
+ * underlying hypervisor to adjust the mappings in the I/O MMU so that each
+ * interrupt will be delivered to the correct virtual processor at the right
+ * vector.  This driver does not support level-triggered (line-based)
+ * interrupts, and will report that the Interrupt Line register in the
+ * function's configuration space is zero.
+ *
+ * The rest of this driver mostly maps PCI concepts onto underlying Hyper-V
+ * facilities.  For instance, the configuration space of a function exposed
+ * by Hyper-V is mapped into a single page of memory space, and the
+ * read and write handlers for config space must be aware of this mechanism.
+ * Similarly, device setup and teardown involves messages sent to and from
+ * the PCI back-end driver in Hyper-V.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+ * NON INFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+/*
+ * Protocol versions. The low word is the minor version, the high wor

[PATCH RESEND v3 0/3] PCI: hv: New paravirtual PCI front-end driver

2016-02-16 Thread jakeo
From: Jake Oshins 

This version incorporates more feedback from Bjorn Helgaas.  Most notably,
I removed some debugging code and I consistently used architectural
means for getting the PCI domain instead of just reaching into the sysdata.

This is a resend of patches that enable PCI pass-through within Hyper-V
VMs.  This patch series only includes those which were deemed appropriate
for being incorportated via the PCI tree.  All other patches in previous
patch series have gone through other trees and are now in mainline.

The first two patches modify PCI so that new root PCI buses can be marked with
an associated fwnode_handle, and so that root PCI buses can look up their
associated IRQ domain by that handle.

The last patch, introduces a new driver, hv_pcifront, which exposes root PCI
buses in a Hyper-V VM.  These root PCI buses expose real PCIe devices, or PCI
Virtual Functions.

Jake Oshins (3):
  PCI: Add fwnode_handle to pci_sysdata
  PCI: irqdomain: Look up IRQ domain by fwnode_handle
  PCI: hv: New paravirtual PCI front-end for Hyper-V VMs

 MAINTAINERS   |1 +
 arch/x86/include/asm/pci.h|   15 +
 drivers/pci/Kconfig   |7 +
 drivers/pci/host/Makefile |1 +
 drivers/pci/host/pci-hyperv.c | 2359 +
 drivers/pci/probe.c   |   15 +
 include/linux/pci.h   |4 +
 7 files changed, 2402 insertions(+)
 create mode 100644 drivers/pci/host/pci-hyperv.c

--
1.9.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH RESEND v3 1/3] PCI: Add fwnode_handle to pci_sysdata

2016-02-16 Thread jakeo
From: Jake Oshins 

This patch adds an fwnode_handle to struct pci_sysdata, which is
used by the next patch in the series when trying to locate an
IRQ domain associated with a root PCI bus.

Signed-off-by: Jake Oshins 
---
 arch/x86/include/asm/pci.h | 15 +++
 include/linux/pci.h|  4 
 2 files changed, 19 insertions(+)

diff --git a/arch/x86/include/asm/pci.h b/arch/x86/include/asm/pci.h
index 4625943..6fc3c7c 100644
--- a/arch/x86/include/asm/pci.h
+++ b/arch/x86/include/asm/pci.h
@@ -20,6 +20,9 @@ struct pci_sysdata {
 #ifdef CONFIG_X86_64
void*iommu; /* IOMMU private data */
 #endif
+#ifdef CONFIG_PCI_MSI_IRQ_DOMAIN
+   void*fwnode;/* IRQ domain for MSI assignment */
+#endif
 };
 
 extern int pci_routeirq;
@@ -32,6 +35,7 @@ extern int noioapicreroute;
 static inline int pci_domain_nr(struct pci_bus *bus)
 {
struct pci_sysdata *sd = bus->sysdata;
+
return sd->domain;
 }
 
@@ -41,6 +45,17 @@ static inline int pci_proc_domain(struct pci_bus *bus)
 }
 #endif
 
+#ifdef CONFIG_PCI_MSI_IRQ_DOMAIN
+static inline void *_pci_root_bus_fwnode(struct pci_bus *bus)
+{
+   struct pci_sysdata *sd = bus->sysdata;
+
+   return sd->fwnode;
+}
+
+#define pci_root_bus_fwnode_pci_root_bus_fwnode
+#endif
+
 /* Can be used to override the logic in pci_scan_bus for skipping
already-configured bus numbers - to be used for buggy BIOSes
or architectures with incomplete PCI setup by the loader */
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 27df4a6..1bb44af 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -1515,6 +1515,10 @@ static inline int pci_get_new_domain_nr(void) { return 
-ENOSYS; }
 
 #include 
 
+#ifndef pci_root_bus_fwnode
+#define pci_root_bus_fwnode(bus)   NULL
+#endif
+
 /* these helpers provide future and backwards compatibility
  * for accessing popular PCI BAR info */
 #define pci_resource_start(dev, bar)   ((dev)->resource[(bar)].start)
-- 
1.9.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH RESEND v3 2/3] PCI: irqdomain: Look up IRQ domain by fwnode_handle

2016-02-16 Thread jakeo
From: Jake Oshins 

This patch adds a second way of finding an IRQ domain associated with
a root PCI bus.  After looking to see if one can be found through
the OF tree, it attempts to look up the IRQ domain through an
fwnode_handle stored in the pci_sysdata struct.

Signed-off-by: Jake Oshins 
---
 drivers/pci/probe.c | 15 +++
 1 file changed, 15 insertions(+)

diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index 6d7ab9b..1e34d21 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -15,6 +15,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include "pci.h"
 
@@ -675,6 +676,20 @@ static struct irq_domain 
*pci_host_bridge_msi_domain(struct pci_bus *bus)
if (!d)
d = pci_host_bridge_acpi_msi_domain(bus);
 
+#ifdef CONFIG_PCI_MSI_IRQ_DOMAIN
+   /*
+* If no IRQ domain was found via the OF tree, try looking it up
+* directly through the fwnode_handle.
+*/
+   if (!d) {
+   struct fwnode_handle *fwnode = pci_root_bus_fwnode(bus);
+
+   if (fwnode)
+   d = irq_find_matching_fwnode(fwnode,
+DOMAIN_BUS_PCI_MSI);
+   }
+#endif
+
return d;
 }
 
-- 
1.9.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH RESEND v3 3/3] PCI: hv: New paravirtual PCI front-end for Hyper-V VMs

2016-02-16 Thread jakeo
From: Jake Oshins 

This patch introduces a new driver which exposes a root PCI bus whenever a
PCI Express device is passed through to a guest VM under Hyper-V. The
device can be single- or multi-function. The interrupts for the devices
are managed by an IRQ domain, implemented within the driver.

Signed-off-by: Jake Oshins 
---
 MAINTAINERS   |1 +
 drivers/pci/Kconfig   |7 +
 drivers/pci/host/Makefile |1 +
 drivers/pci/host/pci-hyperv.c | 2359 +
 4 files changed, 2368 insertions(+)
 create mode 100644 drivers/pci/host/pci-hyperv.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 30aca4a..b68c015 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -5193,6 +5193,7 @@ F:arch/x86/kernel/cpu/mshyperv.c
 F: drivers/hid/hid-hyperv.c
 F: drivers/hv/
 F: drivers/input/serio/hyperv-keyboard.c
+F: drivers/pci/host/pci-hyperv.c
 F: drivers/net/hyperv/
 F: drivers/scsi/storvsc_drv.c
 F: drivers/video/fbdev/hyperv_fb.c
diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig
index 73de4ef..54a5441 100644
--- a/drivers/pci/Kconfig
+++ b/drivers/pci/Kconfig
@@ -118,4 +118,11 @@ config PCI_LABEL
def_bool y if (DMI || ACPI)
select NLS
 
+config PCI_HYPERV
+tristate "Hyper-V PCI Frontend"
+depends on PCI && X86 && HYPERV && PCI_MSI && PCI_MSI_IRQ_DOMAIN && 
X86_64
+help
+  The PCI device frontend driver allows the kernel to import arbitrary
+  PCI devices from a PCI backend to support PCI driver domains.
+
 source "drivers/pci/host/Kconfig"
diff --git a/drivers/pci/host/Makefile b/drivers/pci/host/Makefile
index 7b2f20c..152daf9 100644
--- a/drivers/pci/host/Makefile
+++ b/drivers/pci/host/Makefile
@@ -2,6 +2,7 @@ obj-$(CONFIG_PCIE_DW) += pcie-designware.o
 obj-$(CONFIG_PCI_DRA7XX) += pci-dra7xx.o
 obj-$(CONFIG_PCI_EXYNOS) += pci-exynos.o
 obj-$(CONFIG_PCI_IMX6) += pci-imx6.o
+obj-$(CONFIG_PCI_HYPERV) += pci-hyperv.o
 obj-$(CONFIG_PCI_MVEBU) += pci-mvebu.o
 obj-$(CONFIG_PCI_TEGRA) += pci-tegra.o
 obj-$(CONFIG_PCI_RCAR_GEN2) += pci-rcar-gen2.o
diff --git a/drivers/pci/host/pci-hyperv.c b/drivers/pci/host/pci-hyperv.c
new file mode 100644
index 000..ba1e4c2
--- /dev/null
+++ b/drivers/pci/host/pci-hyperv.c
@@ -0,0 +1,2359 @@
+/*
+ * Copyright (c) Microsoft Corporation.
+ *
+ * Author:
+ *   Jake Oshins 
+ *
+ * This driver acts as a paravirtual front-end for PCI Express root buses.
+ * When a PCI Express function (either an entire device or an SR-IOV
+ * Virtual Function) is being passed through to the VM, this driver exposes
+ * a new bus to the guest VM.  This is modeled as a root PCI bus because
+ * no bridges are being exposed to the VM.  In fact, with a "Generation 2"
+ * VM within Hyper-V, there may seem to be no PCI bus at all in the VM
+ * until a device as been exposed using this driver.
+ *
+ * Each root PCI bus has its own PCI domain, which is called "Segment" in
+ * the PCI Firmware Specifications.  Thus while each device passed through
+ * to the VM using this front-end will appear at "device 0", the domain will
+ * be unique.  Typically, each bus will have one PCI function on it, though
+ * this driver does support more than one.
+ *
+ * In order to map the interrupts from the device through to the guest VM,
+ * this driver also implements an IRQ Domain, which handles interrupts (either
+ * MSI or MSI-X) associated with the functions on the bus.  As interrupts are
+ * set up, torn down, or reaffined, this driver communicates with the
+ * underlying hypervisor to adjust the mappings in the I/O MMU so that each
+ * interrupt will be delivered to the correct virtual processor at the right
+ * vector.  This driver does not support level-triggered (line-based)
+ * interrupts, and will report that the Interrupt Line register in the
+ * function's configuration space is zero.
+ *
+ * The rest of this driver mostly maps PCI concepts onto underlying Hyper-V
+ * facilities.  For instance, the configuration space of a function exposed
+ * by Hyper-V is mapped into a single page of memory space, and the
+ * read and write handlers for config space must be aware of this mechanism.
+ * Similarly, device setup and teardown involves messages sent to and from
+ * the PCI back-end driver in Hyper-V.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+ * NON INFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+/*
+ * Protocol versions. The low word is the minor version, the high wor

[PATCH] PCI: Remove usage of pci_domain_nr when the PCI bus doesn't yet exist

2016-02-24 Thread jakeo
From: Jake Oshins 

This patch fixes a race condition in this driver.  Using the
function pci_domain_nr() only works if the PCI bus has already
been fully created.  This patch just deletes one call site,
as it was in debug prints which aren't strictly necessary.
Another call site is changed to look for the data in the same
structure that is passed in when creating the PCI bus in the
first place.

Signed-off-by: Jake Oshins 
---
 drivers/pci/host/pci-hyperv.c | 15 ---
 1 file changed, 8 insertions(+), 7 deletions(-)

diff --git a/drivers/pci/host/pci-hyperv.c b/drivers/pci/host/pci-hyperv.c
index 9391dee..ed651ba 100644
--- a/drivers/pci/host/pci-hyperv.c
+++ b/drivers/pci/host/pci-hyperv.c
@@ -1265,11 +1265,6 @@ static struct hv_pci_dev *new_pcichild_device(struct 
hv_pcibus_device *hbus,
if (!hpdev)
return NULL;
 
-   dev_info(&hbus->hdev->device,
-"New child device (%p) [%04x:%04x] at %04x:00:00.%02x\n",
-hpdev, desc->v_id, desc->d_id, pci_domain_nr(hbus->pci_bus),
-desc->win_slot.bits.func);
-
hpdev->hbus = hbus;
 
memset(&pkt, 0, sizeof(pkt));
@@ -1558,9 +1553,15 @@ static void hv_eject_device_work(struct work_struct 
*work)
return;
}
 
+   /*
+* Ejection can come before or after the PCI bus has been set up, so
+* attempt to find it and tear down the bus state, if it exists.  This
+* must be done without constructs like pci_domain_nr(hbus->pci_bus)
+* because hbus->pci_bus may not exist yet.
+*/
wslot = wslot_to_devfn(hpdev->desc.win_slot.slot);
-   pdev = pci_get_domain_bus_and_slot(pci_domain_nr(hpdev->hbus->pci_bus),
-  0, wslot);
+   pdev = pci_get_domain_bus_and_slot(hpdev->hbus->sysdata.domain, 0,
+  wslot);
if (pdev) {
pci_stop_and_remove_bus_device(pdev);
pci_dev_put(pdev);
-- 
1.9.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH 2/5] hv: Lock access to hyperv_mmio resource tree

2016-02-24 Thread jakeo
From: Jake Oshins 

In existing code, this tree of resources is created
in single-threaded code and never modified after it is
created, and thus needs no locking.  This patch introduces
a semaphore for tree access, as other patches in this
series introduce run-time modifications of this resource
tree which can happen on multiple threads.

Signed-off-by: Jake Oshins 
---
 drivers/hv/vmbus_drv.c | 16 
 1 file changed, 12 insertions(+), 4 deletions(-)

diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c
index 69393ff..1da18e1 100644
--- a/drivers/hv/vmbus_drv.c
+++ b/drivers/hv/vmbus_drv.c
@@ -103,6 +103,7 @@ static struct notifier_block hyperv_panic_block = {
 };
 
 struct resource *hyperv_mmio;
+DEFINE_SEMAPHORE(hyperv_mmio_lock);
 
 static int vmbus_exists(void)
 {
@@ -1173,7 +1174,10 @@ int vmbus_allocate_mmio(struct resource **new, struct 
hv_device *device_obj,
resource_size_t range_min, range_max, start, local_min, local_max;
const char *dev_n = dev_name(&device_obj->device);
u32 fb_end = screen_info.lfb_base + (screen_info.lfb_size << 1);
-   int i;
+   int i, retval;
+
+   retval = -ENXIO;
+   down(&hyperv_mmio_lock);
 
for (iter = hyperv_mmio; iter; iter = iter->sibling) {
if ((iter->start >= max) || (iter->end <= min))
@@ -1210,13 +1214,17 @@ int vmbus_allocate_mmio(struct resource **new, struct 
hv_device *device_obj,
for (; start + size - 1 <= local_max; start += align) {
*new = request_mem_region_exclusive(start, size,
dev_n);
-   if (*new)
-   return 0;
+   if (*new) {
+   retval = 0;
+   goto exit;
+   }
}
}
}
 
-   return -ENXIO;
+exit:
+   up(&hyperv_mmio_lock);
+   return retval;
 }
 EXPORT_SYMBOL_GPL(vmbus_allocate_mmio);
 
-- 
1.9.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH 0/5] hv: drivers: Ensure that bridge windows don't overlap

2016-02-24 Thread jakeo
From: Jake Oshins 

Hyper-V VMs expose paravirtual drivers through a mechanism called
VMBus, which is managed by hv_vmbus.ko.  For each paravirtual service
instance, this driver exposes a new child device.  Some of these child
devices need memory address space, into which Hyper-V will map things
like the virtual video framebuffer.  This memory-mapped address space
is chosen by the guest OS, not the hypervisor.

This is difficult to map onto the Linux pnp layer, as the code in the
pnp layer to choose MMIO space keys off of bus type and it doesn't know
anything about VMBus.  The maintainers of the pnp layer have asked that
we not offer patches to it that make it understand VMBus, but that we
rather find ways of using the code in its current state.  So hv_vmbus.ko
exports a function, vmbus_allocate_mmio() for choosing the address space
for any child driver that needs this facility.

The recently introduced PCI front-end driver for Hyper-V VMs
(pci-hyperv.ko) uses vmbus_allocate_mmio() for choosing both the region
of memory into which PCI configuration space can be mapped and the
region of memory into which real PCI Express devices which are passed
through to the VM should occupy.  The regions allocated are made to look
like root PCI bus bridge windows to the PCI driver, reusing all the code
in the PCI driver for the rest of the PCI device management.

The problem is that these bridge windows are marked in such a way that
devices can still allocate from the memory space spanned by them, and
this means that if two different PCI buses are created in the VM, each
with devices under them, they may allocate the same memory space, leading
to PCI Base Address Registers which overlap.

This patch series fixes the problem by tracking allocations to child
devices in a separate resource tree, marking them such that the bridge
windows can't overlap.  The main memory resource tree, iomem_resource,
contains resources properly marked as bridge windows, allowing their
children to overlap with them.

Jake Oshins (5):
  hv: Make a function to free mmio regions through vmbus
  hv: Lock access to hyperv_mmio resource tree
  hv: Use new vmbus_mmio_free() from client drivers.
  hv: Reverse order of resources in hyperv_mmio
  hv: Track allocations of children of hv_vmbus in private resource tree

 drivers/hv/vmbus_drv.c  | 56 +++--
 drivers/pci/host/pci-hyperv.c   | 14 +--
 drivers/video/fbdev/hyperv_fb.c |  4 +--
 include/linux/hyperv.h  |  2 +-
 4 files changed, 59 insertions(+), 17 deletions(-)

--
1.9.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH 3/5] hv: Use new vmbus_mmio_free() from client drivers.

2016-02-24 Thread jakeo
From: Jake Oshins 

This patch modifies all the callers of vmbus_mmio_allocate()
to call vmbus_mmio_free() instead of release_mem_region().

Signed-off-by: Jake Oshins 
---
 drivers/pci/host/pci-hyperv.c   | 14 +++---
 drivers/video/fbdev/hyperv_fb.c |  4 ++--
 2 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/drivers/pci/host/pci-hyperv.c b/drivers/pci/host/pci-hyperv.c
index 6f77d52..177bbec 100644
--- a/drivers/pci/host/pci-hyperv.c
+++ b/drivers/pci/host/pci-hyperv.c
@@ -2034,14 +2034,14 @@ static void hv_pci_free_bridge_windows(struct 
hv_pcibus_device *hbus)
 
if (hbus->low_mmio_space && hbus->low_mmio_res) {
hbus->low_mmio_res->flags |= IORESOURCE_BUSY;
-   release_mem_region(hbus->low_mmio_res->start,
-  resource_size(hbus->low_mmio_res));
+   vmbus_free_mmio(hbus->low_mmio_res->start,
+   resource_size(hbus->low_mmio_res));
}
 
if (hbus->high_mmio_space && hbus->high_mmio_res) {
hbus->high_mmio_res->flags |= IORESOURCE_BUSY;
-   release_mem_region(hbus->high_mmio_res->start,
-  resource_size(hbus->high_mmio_res));
+   vmbus_free_mmio(hbus->high_mmio_res->start,
+   resource_size(hbus->high_mmio_res));
}
 }
 
@@ -2119,8 +2119,8 @@ static int hv_pci_allocate_bridge_windows(struct 
hv_pcibus_device *hbus)
 
 release_low_mmio:
if (hbus->low_mmio_res) {
-   release_mem_region(hbus->low_mmio_res->start,
-  resource_size(hbus->low_mmio_res));
+   vmbus_free_mmio(hbus->low_mmio_res->start,
+   resource_size(hbus->low_mmio_res));
}
 
return ret;
@@ -2163,7 +2163,7 @@ static int hv_allocate_config_window(struct 
hv_pcibus_device *hbus)
 
 static void hv_free_config_window(struct hv_pcibus_device *hbus)
 {
-   release_mem_region(hbus->mem_config->start, PCI_CONFIG_MMIO_LENGTH);
+   vmbus_free_mmio(hbus->mem_config->start, PCI_CONFIG_MMIO_LENGTH);
 }
 
 /**
diff --git a/drivers/video/fbdev/hyperv_fb.c b/drivers/video/fbdev/hyperv_fb.c
index e2451bd..2fd49b2 100644
--- a/drivers/video/fbdev/hyperv_fb.c
+++ b/drivers/video/fbdev/hyperv_fb.c
@@ -743,7 +743,7 @@ static int hvfb_getmem(struct hv_device *hdev, struct 
fb_info *info)
 err3:
iounmap(fb_virt);
 err2:
-   release_mem_region(par->mem->start, screen_fb_size);
+   vmbus_free_mmio(par->mem->start, screen_fb_size);
par->mem = NULL;
 err1:
if (!gen2vm)
@@ -758,7 +758,7 @@ static void hvfb_putmem(struct fb_info *info)
struct hvfb_par *par = info->par;
 
iounmap(info->screen_base);
-   release_mem_region(par->mem->start, screen_fb_size);
+   vmbus_free_mmio(par->mem->start, screen_fb_size);
par->mem = NULL;
 }
 
-- 
1.9.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH 5/5] hv: Track allocations of children of hv_vmbus in private resource tree

2016-02-24 Thread jakeo
From: Jake Oshins 

This patch changes vmbus_allocate_mmio() and vmbus_free_mmio() so
that when child paravirtual devices allocate memory-mapped I/O
space, they allocate it privately from a resource tree pointed
at by hyperv_mmio and also by the public resource tree
iomem_resource.  This allows the region to be marked as "busy"
in the private tree, but a "bridge window" in the public tree,
guaranteeing that no two bridge windows will overlap each other
but while also allowing the PCI device children of the bridge
windows to overlap that window.

One might conclude that this belongs in the pnp layer, rather
than in this driver.  Rafael Wysocki, the maintainter of the
pnp layer, has previously asked that we not modify the pnp layer
as it is considered deprecated.  This patch is thus essentially
a workaround.

Signed-off-by: Jake Oshins 
---
 drivers/hv/vmbus_drv.c | 22 +-
 1 file changed, 21 insertions(+), 1 deletion(-)

diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c
index b090548..2a7eb3f 100644
--- a/drivers/hv/vmbus_drv.c
+++ b/drivers/hv/vmbus_drv.c
@@ -1169,7 +1169,7 @@ int vmbus_allocate_mmio(struct resource **new, struct 
hv_device *device_obj,
resource_size_t size, resource_size_t align,
bool fb_overlap_ok)
 {
-   struct resource *iter;
+   struct resource *iter, *shadow;
resource_size_t range_min, range_max, start, local_min, local_max;
const char *dev_n = dev_name(&device_obj->device);
u32 fb_end = screen_info.lfb_base + (screen_info.lfb_size << 1);
@@ -1211,12 +1211,22 @@ int vmbus_allocate_mmio(struct resource **new, struct 
hv_device *device_obj,
 
start = (local_min + align - 1) & ~(align - 1);
for (; start + size - 1 <= local_max; start += align) {
+   shadow = __request_region(iter, start,
+ size,
+ NULL,
+ IORESOURCE_BUSY);
+   if (!shadow)
+   continue;
+
*new = request_mem_region_exclusive(start, size,
dev_n);
if (*new) {
+   shadow->name = (char*)*new;
retval = 0;
goto exit;
}
+
+   __release_region(iter, start, size);
}
}
}
@@ -1237,7 +1247,17 @@ EXPORT_SYMBOL_GPL(vmbus_allocate_mmio);
  */
 void vmbus_free_mmio(resource_size_t start, resource_size_t size)
 {
+   struct resource *iter;
+
+   down(&hyperv_mmio_lock);
+   for (iter = hyperv_mmio; iter; iter = iter->sibling) {
+   if ((iter->start >= start + size) || (iter->end <= start))
+   continue;
+
+   __release_region(iter, start, size);
+   }
release_mem_region(start, size);
+   up(&hyperv_mmio_lock);
 
 }
 EXPORT_SYMBOL_GPL(vmbus_free_mmio);
-- 
1.9.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH 1/5] hv: Make a function to free mmio regions through vmbus

2016-02-24 Thread jakeo
From: Jake Oshins 

This patch introduces a function that reverses everything
done by vmbus_allocate_mmio().  Existing code just called
release_mem_region().  Future patches in this series
require a more complex sequence of actions, so this function
is introduced to wrap those actions.

Signed-off-by: Jake Oshins 
---
 drivers/hv/vmbus_drv.c | 15 +++
 include/linux/hyperv.h |  2 +-
 2 files changed, 16 insertions(+), 1 deletion(-)

diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c
index 063e5f5..69393ff 100644
--- a/drivers/hv/vmbus_drv.c
+++ b/drivers/hv/vmbus_drv.c
@@ -1221,6 +1221,21 @@ int vmbus_allocate_mmio(struct resource **new, struct 
hv_device *device_obj,
 EXPORT_SYMBOL_GPL(vmbus_allocate_mmio);
 
 /**
+ * vmbus_free_mmio() - Free a memory-mapped I/O range.
+ * @start: Base address of region to release.
+ * @size:  Size of the range to be allocated
+ *
+ * This function releases anything requested by
+ * vmbus_mmio_allocate().
+ */
+void vmbus_free_mmio(resource_size_t start, resource_size_t size)
+{
+   release_mem_region(start, size);
+
+}
+EXPORT_SYMBOL_GPL(vmbus_free_mmio);
+
+/**
  * vmbus_cpu_number_to_vp_number() - Map CPU to VP.
  * @cpu_number: CPU number in Linux terms
  *
diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h
index a32704d..f3e0c71 100644
--- a/include/linux/hyperv.h
+++ b/include/linux/hyperv.h
@@ -1091,7 +1091,7 @@ int vmbus_allocate_mmio(struct resource **new, struct 
hv_device *device_obj,
resource_size_t min, resource_size_t max,
resource_size_t size, resource_size_t align,
bool fb_overlap_ok);
-
+void vmbus_free_mmio(resource_size_t start, resource_size_t size);
 int vmbus_cpu_number_to_vp_number(int cpu_number);
 u64 hv_do_hypercall(u64 control, void *input, void *output);
 
-- 
1.9.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH 4/5] hv: Reverse order of resources in hyperv_mmio

2016-02-24 Thread jakeo
From: Jake Oshins 

A patch later in this series allocates child nodes
in this resource tree.  For that to work, this tree
needs to be sorted in ascending order.

Signed-off-by: Jake Oshins 
---
 drivers/hv/vmbus_drv.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c
index 1da18e1..b090548 100644
--- a/drivers/hv/vmbus_drv.c
+++ b/drivers/hv/vmbus_drv.c
@@ -1090,7 +1090,6 @@ static acpi_status vmbus_walk_resources(struct 
acpi_resource *res, void *ctx)
new_res->end = end;
 
/*
-* Stick ranges from higher in address space at the front of the list.
 * If two ranges are adjacent, merge them.
 */
do {
@@ -,7 +1110,7 @@ static acpi_status vmbus_walk_resources(struct 
acpi_resource *res, void *ctx)
break;
}
 
-   if ((*old_res)->end < new_res->start) {
+   if ((*old_res)->start > new_res->end) {
new_res->sibling = *old_res;
if (prev_res)
(*prev_res)->sibling = new_res;
-- 
1.9.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH 0/6] Front-end driver for PCIe Pass-through on Hyper-V

2015-06-11 Thread jakeo
From: Jake Oshins 

This patch does some slight refactoring on the hv_vmbus driver and its
dependents and then introduces a new paravirtual front-end driver for PCI
which supports PCI Express devices passed through to a Linux guest running
in a Hyper-V VM.

To support this front-end, several new mechanisms are introduced:

1 - A common way of finding free memory-mapped I/O space in a Hyper-V VM, 
available to all Hyper-V-related drivers.

2 - A way of handling PCI Message-Signaled Interrupt (MSI and MSI-X)
creation and formatting when Hyper-V is running.

3 - A mapping function from Linux processor number to Hyper-V virtual
processor number, available to drivers, which is necessary for MSI(-X)
creation.

The Hyper-V Frame Buffer driver is modified to use the MMIO space
allocation function so that its allocations both don't collide with the
PCI front end and so that the chosen range can come from any available
part of MMIO space.

Finally, the new PCI front-end driver is the last patch in the series.

Jake Oshins (6):
  drivers:hv: Modify vmbus to search for all MMIO ranges available
  drivers:hv: Move MMIO range picking from hyper_fb.mod to hv_vmbus.mod
  arch:x86:hv: Add mechanism for Hyper-V paravirt drivers to hook msi
message creation
  drivers:hv: Export a function that maps Linux proc num onto Hyper-V
proc num
  drivers:hv: Define the channel type for Hyper-V PCI Express
pass-through
  drivers:pci:hv: New paravirtual PCI front-end for Hyper-V VMs

 MAINTAINERS |1 +
 arch/x86/include/asm/mshyperv.h |2 +
 arch/x86/kernel/cpu/mshyperv.c  |   30 +
 drivers/hv/vmbus_drv.c  |  208 +++-
 drivers/pci/Kconfig |9 +
 drivers/pci/host/Makefile   |1 +
 drivers/pci/host/hv_pcifront.c  | 2177 +++
 drivers/video/fbdev/hyperv_fb.c |   46 +-
 include/linux/hyperv.h  |   38 +-
 9 files changed, 2469 insertions(+), 43 deletions(-)
 create mode 100644 drivers/pci/host/hv_pcifront.c

-- 
1.9.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH 5/6] drivers:hv: Define the channel type for Hyper-V PCI Express pass-through

2015-06-11 Thread jakeo
From: Jake Oshins 

Signed-off-by: Jake Oshins 
---
 include/linux/hyperv.h | 11 +++
 1 file changed, 11 insertions(+)

diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h
index 6fec42d..1903238 100644
--- a/include/linux/hyperv.h
+++ b/include/linux/hyperv.h
@@ -1144,6 +1144,17 @@ int vmbus_procnum_to_vpnum(int procnum);
}
 
 /*
+ * PCI Express Pass Through
+ * {44C4F61D--4400-9D52-802E27EDE19F}
+ */
+
+#define HV_PCIE_GUID \
+   .guid = { \
+   0x1D, 0xF6, 0xC4, 0x44, 0x44, 0x44, 0x00, 0x44, \
+   0x9D, 0x52, 0x80, 0x2E, 0x27, 0xED, 0xE1, 0x9F \
+   }
+
+/*
  * Common header for Hyper-V ICs
  */
 
-- 
1.9.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH 4/6] drivers:hv: Export a function that maps Linux proc num onto Hyper-V proc num

2015-06-11 Thread jakeo
From: Jake Oshins 

Signed-off-by: Jake Oshins 
---
 drivers/hv/vmbus_drv.c | 16 
 include/linux/hyperv.h |  2 ++
 2 files changed, 18 insertions(+)

diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c
index 067a469..65e4eb6 100644
--- a/drivers/hv/vmbus_drv.c
+++ b/drivers/hv/vmbus_drv.c
@@ -1158,6 +1158,22 @@ int vmbus_allocate_mmio(struct resource **new, struct 
hv_device *device_obj,
 }
 EXPORT_SYMBOL_GPL(vmbus_allocate_mmio);
 
+/**
+ * This function returns the mapping between the Linux processor
+ * number and
+ * the hypervisor's virtual processor number, useful in making
+ * hypercalls and such that talk about specific processors.
+ *
+ * @param procnum - in Linux terms
+ *
+ * @return int - in Hyper-V terms
+ */
+int vmbus_procnum_to_vpnum(int procnum)
+{
+   return hv_context.vp_index[procnum];
+}
+EXPORT_SYMBOL_GPL(vmbus_procnum_to_vpnum);
+
 static int vmbus_acpi_add(struct acpi_device *device)
 {
acpi_status result;
diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h
index ffd98d7..6fec42d 100644
--- a/include/linux/hyperv.h
+++ b/include/linux/hyperv.h
@@ -987,6 +987,8 @@ int vmbus_allocate_mmio(struct resource **new, struct 
hv_device *device_obj,
resource_size_t size, resource_size_t align,
bool fb_overlap_ok);
 
+int vmbus_procnum_to_vpnum(int procnum);
+
 /**
  * VMBUS_DEVICE - macro used to describe a specific hyperv vmbus device
  *
-- 
1.9.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH 2/6] drivers:hv: Move MMIO range picking from hyper_fb.mod to hv_vmbus.mod

2015-06-11 Thread jakeo
From: Jake Oshins 

Signed-off-by: Jake Oshins 
---
 drivers/hv/vmbus_drv.c  | 87 -
 drivers/video/fbdev/hyperv_fb.c | 46 ++
 include/linux/hyperv.h  |  7 +++-
 3 files changed, 112 insertions(+), 28 deletions(-)

diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c
index d0e8832..067a469 100644
--- a/drivers/hv/vmbus_drv.c
+++ b/drivers/hv/vmbus_drv.c
@@ -39,6 +39,7 @@
 #include 
 #include 
 #include 
+#include 
 #include "hyperv_vmbus.h"
 
 static struct acpi_device  *hv_acpi_dev;
@@ -73,7 +74,6 @@ static struct notifier_block hyperv_panic_block = {
 };
 
 struct resource *hyperv_mmio;
-EXPORT_SYMBOL_GPL(hyperv_mmio);
 
 static int vmbus_exists(void)
 {
@@ -1073,6 +1073,91 @@ static int vmbus_acpi_remove(struct acpi_device *device)
return 0;
 }
 
+/**
+ * This function walks the resources granted to VMBus by the
+ * _CRS object in the ACPI namespace underneath the parent
+ * "bridge" whether that's a root PCI bus in the Generation 1
+ * case or a Module Device in the Generation 2 case.  It then
+ * attempts to allocate from the global MMIO pool in a way that
+ * matches the constraints supplied in these parameters and by
+ * that _CRS.
+ *
+ * @param new - If successful, supplied a pointer to the
+ *allocated MMIO space.
+ * @param device_obj - Identifies the caller
+ * @param min - Minimum guest physical address of the allocation
+ * @param max - Maximum guest physical address
+ * @param size - Size of the range to be allocated
+ * @param align - Alignment of the range to be allocated
+ * @param fb_overlap_ok - Whether this allocation can be allowed
+ * to overlap the video frame buffer.
+ *
+ * @return int
+ */
+int vmbus_allocate_mmio(struct resource **new, struct hv_device *device_obj,
+   resource_size_t min, resource_size_t max,
+   resource_size_t size, resource_size_t align,
+   bool fb_overlap_ok)
+{
+   struct resource *iter;
+   resource_size_t range_min, range_max, start, local_min, local_max;
+   const char *dev_n = dev_name(&device_obj->device);
+   u32 fb_end = screen_info.lfb_base + (screen_info.lfb_size << 1);
+   int i;
+
+   pr_devel("allocating %llxx bytes alignment %llx in %llx->%llx for %s\n",
+size, align, min, max, dev_n);
+
+   for (iter = hyperv_mmio; iter; iter = iter->sibling) {
+
+   if ((iter->start >= max) || (iter->end <= min))
+   continue;
+
+   range_min = iter->start;
+   range_max = iter->end;
+
+   /* If this range overlaps the frame buffer, split it into
+  two tries. */
+   for (i = 0; i < 2; i++) {
+   local_min = range_min;
+   local_max = range_max;
+   if (fb_overlap_ok || ((range_min >= fb_end) ||
+ (range_max <= screen_info.lfb_base))) {
+   i++;
+   } else {
+   if ((range_min <= screen_info.lfb_base) &&
+   (range_max >= screen_info.lfb_base)) {
+
+   /*
+* The frame buffer is in this window,
+* so trim this into the part that
+* preceeds the frame buffer.
+*/
+   local_max = screen_info.lfb_base-1;
+   range_min = fb_end;
+   } else {
+   range_min = fb_end;
+   continue;
+   }
+   }
+
+   pr_devel("looking between %llx:%llx\n", range_min,
+range_max);
+   start = (local_min + align - 1) & ~(align - 1);
+   for (; start + size - 1 <= local_max; start += align) {
+   *new = request_mem_region_exclusive(start, size,
+   dev_n);
+   if (*new)
+   return 0;
+   }
+   }
+   }
+
+   pr_warn("vmbus_allocate_mmio failed\n");
+   return -ENXIO;
+}
+EXPORT_SYMBOL_GPL(vmbus_allocate_mmio);
+
 static int vmbus_acpi_add(struct acpi_device *device)
 {
acpi_status result;
diff --git a/drivers/video/fbdev/hyperv_fb.c b/drivers/video/fbdev/hyperv_fb.c
index b54ee1c..e2451bd 100644
--- a/drivers/video/fbdev/hyperv_fb.c
+++ b/drivers/video/fbdev/hyperv_fb.c
@@ -213,7 +213,7 @@ struct synthvid_msg {
 
 struct hvfb_par {
struct fb_info *info;
-   struct

[PATCH 3/6] arch:x86:hv: Add mechanism for Hyper-V paravirt drivers to hook msi message creation

2015-06-11 Thread jakeo
From: Jake Oshins 

Signed-off-by: Jake Oshins 
---
 arch/x86/include/asm/mshyperv.h |  2 ++
 arch/x86/kernel/cpu/mshyperv.c  | 30 ++
 2 files changed, 32 insertions(+)

diff --git a/arch/x86/include/asm/mshyperv.h b/arch/x86/include/asm/mshyperv.h
index c163215..bf7789e 100644
--- a/arch/x86/include/asm/mshyperv.h
+++ b/arch/x86/include/asm/mshyperv.h
@@ -19,5 +19,7 @@ void hyperv_callback_vector(void);
 void hyperv_vector_handler(struct pt_regs *regs);
 void hv_setup_vmbus_irq(void (*handler)(void));
 void hv_remove_vmbus_irq(void);
+void hyperv_install_interrupt_translation(struct x86_msi_ops *new_ops);
+void hyperv_uninstall_interrupt_translation(void);
 
 #endif
diff --git a/arch/x86/kernel/cpu/mshyperv.c b/arch/x86/kernel/cpu/mshyperv.c
index 939155f..816e329 100644
--- a/arch/x86/kernel/cpu/mshyperv.c
+++ b/arch/x86/kernel/cpu/mshyperv.c
@@ -69,6 +69,36 @@ void hv_remove_vmbus_irq(void)
 }
 EXPORT_SYMBOL_GPL(hv_setup_vmbus_irq);
 EXPORT_SYMBOL_GPL(hv_remove_vmbus_irq);
+
+struct x86_msi_ops old_msi_ops;
+
+void hyperv_install_interrupt_translation(struct x86_msi_ops *new_ops)
+{
+   old_msi_ops.setup_msi_irqs = xchg(&(x86_msi.setup_msi_irqs),
+ new_ops->setup_msi_irqs);
+   old_msi_ops.compose_msi_msg = xchg(&(x86_msi.compose_msi_msg),
+  new_ops->compose_msi_msg);
+   old_msi_ops.teardown_msi_irqs = xchg(&(x86_msi.teardown_msi_irqs),
+new_ops->teardown_msi_irqs);
+   old_msi_ops.restore_msi_irqs = xchg(&(x86_msi.restore_msi_irqs),
+   new_ops->restore_msi_irqs);
+
+   new_ops->setup_msi_irqs = old_msi_ops.setup_msi_irqs;
+   new_ops->compose_msi_msg = old_msi_ops.compose_msi_msg;
+   new_ops->teardown_msi_irqs = old_msi_ops.teardown_msi_irqs;
+   new_ops->restore_msi_irqs = old_msi_ops.restore_msi_irqs;
+}
+EXPORT_SYMBOL_GPL(hyperv_install_interrupt_translation);
+
+void hyperv_uninstall_interrupt_translation(void)
+{
+   xchg(&(x86_msi.setup_msi_irqs), old_msi_ops.setup_msi_irqs);
+   xchg(&(x86_msi.compose_msi_msg), old_msi_ops.compose_msi_msg);
+   xchg(&(x86_msi.teardown_msi_irqs), old_msi_ops.teardown_msi_irqs);
+   xchg(&(x86_msi.restore_msi_irqs), old_msi_ops.restore_msi_irqs);
+}
+EXPORT_SYMBOL_GPL(hyperv_uninstall_interrupt_translation);
+
 #endif
 
 static uint32_t  __init ms_hyperv_platform(void)
-- 
1.9.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH 1/6] drivers:hv: Modify vmbus to search for all MMIO ranges available

2015-06-11 Thread jakeo
From: Jake Oshins 

Signed-off-by: Jake Oshins 
---
 drivers/hv/vmbus_drv.c  | 105 ++--
 drivers/video/fbdev/hyperv_fb.c |   2 +-
 include/linux/hyperv.h  |   2 +-
 3 files changed, 92 insertions(+), 17 deletions(-)

diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c
index c85235e..d0e8832 100644
--- a/drivers/hv/vmbus_drv.c
+++ b/drivers/hv/vmbus_drv.c
@@ -72,10 +72,7 @@ static struct notifier_block hyperv_panic_block = {
.notifier_call = hyperv_panic_event,
 };
 
-struct resource hyperv_mmio = {
-   .name  = "hyperv mmio",
-   .flags = IORESOURCE_MEM,
-};
+struct resource *hyperv_mmio;
 EXPORT_SYMBOL_GPL(hyperv_mmio);
 
 static int vmbus_exists(void)
@@ -982,30 +979,105 @@ void vmbus_device_unregister(struct hv_device 
*device_obj)
 
 
 /*
- * VMBUS is an acpi enumerated device. Get the the information we
+ * VMBUS is an acpi enumerated device. Get the information we
  * need from DSDT.
  */
-
+#define VTPM_BASE_ADDRESS 0xfed4
 static acpi_status vmbus_walk_resources(struct acpi_resource *res, void *ctx)
 {
+   resource_size_t start = 0;
+   resource_size_t end = 0;
+   struct resource *new_res;
+   struct resource **old_res = &hyperv_mmio;
+   struct resource **prev_res = NULL;
+
switch (res->type) {
case ACPI_RESOURCE_TYPE_IRQ:
irq = res->data.irq.interrupts[0];
+   return AE_OK;
+
+   /*
+* "Address" descriptors are for bus windows. Ignore
+* "memory" descriptors, which are for registers on
+* devices.
+*/
+   case ACPI_RESOURCE_TYPE_ADDRESS32:
+   start = res->data.address32.address.minimum;
+   end = res->data.address32.address.maximum;
break;
 
case ACPI_RESOURCE_TYPE_ADDRESS64:
-   hyperv_mmio.start = res->data.address64.address.minimum;
-   hyperv_mmio.end = res->data.address64.address.maximum;
+   start = res->data.address64.address.minimum;
+   end = res->data.address64.address.maximum;
break;
+
+   default:
+   /* Unused resource type */
+   return AE_OK;
+
}
+   /*
+* Ignore ranges that are below 1MB, as they're not
+* necessary or useful here.
+*/
+   if (end < 0x10)
+   return AE_OK;
+
+   new_res = kzalloc(sizeof(*new_res), GFP_ATOMIC);
+   if (!new_res)
+   return AE_NO_MEMORY;
+
+   /* If this range overlaps the virtual TPM, truncate it. */
+   if (end > VTPM_BASE_ADDRESS && start < VTPM_BASE_ADDRESS)
+   end = VTPM_BASE_ADDRESS;
+
+   new_res->name = "hyperv mmio";
+   new_res->flags = IORESOURCE_MEM;
+   new_res->start = start;
+   new_res->end = end;
+
+   do {
+   if (!*old_res) {
+   *old_res = new_res;
+   break;
+   }
+
+   if ((*old_res)->end < new_res->start) {
+   new_res->sibling = *old_res;
+   if (prev_res)
+   (*prev_res)->sibling = new_res;
+   *old_res = new_res;
+   break;
+   }
+
+   prev_res = old_res;
+   old_res = &(*old_res)->sibling;
+
+   } while (1);
 
return AE_OK;
 }
 
+static int vmbus_acpi_remove(struct acpi_device *device)
+{
+   struct resource *cur_res;
+   struct resource *next_res;
+
+   if (hyperv_mmio) {
+   for (cur_res = hyperv_mmio; cur_res; cur_res = next_res) {
+   next_res = cur_res->sibling;
+   kfree(cur_res);
+   }
+   }
+
+   return 0;
+}
+
 static int vmbus_acpi_add(struct acpi_device *device)
 {
acpi_status result;
int ret_val = -ENODEV;
+   struct acpi_device *ancestor;
 
hv_acpi_dev = device;
 
@@ -1015,23 +1087,25 @@ static int vmbus_acpi_add(struct acpi_device *device)
if (ACPI_FAILURE(result))
goto acpi_walk_err;
/*
-* The parent of the vmbus acpi device (Gen2 firmware) is the VMOD that
-* has the mmio ranges. Get that.
+* Some ancestor of the vmbus acpi device (Gen1 or Gen2
+* firmware) is the VMOD that has the mmio ranges. Get that.
 */
-   if (device->parent) {
-   result = acpi_walk_resources(device->parent->handle,
+   for (ancestor = device->parent; ancestor; ancestor = ancestor->parent) {
+   result = acpi_walk_resources(ancestor->handle,
METHOD_NAME__CRS,
vmbus_walk_resources, NULL);
 
if (ACPI_FAILURE(result))
-   goto acpi_walk_err;
-   if (hyperv_mmio.start && hyperv_mmio.end)
-   request_resource(&iomem_re

[PATCH 6/6] drivers:pci:hv: New paravirtual PCI front-end for Hyper-V VMs

2015-06-11 Thread jakeo
From: Jake Oshins 

drivers:pci:hv: Update MAINTAINERS

drivers:pci:hv: New paravirtual PCI front-end for Hyper-V VMs
Signed-off-by: Jake Oshins 
---
 MAINTAINERS|1 +
 drivers/pci/Kconfig|9 +
 drivers/pci/host/Makefile  |1 +
 drivers/pci/host/hv_pcifront.c | 2177 
 include/linux/hyperv.h |   18 +
 5 files changed, 2206 insertions(+)
 create mode 100644 drivers/pci/host/hv_pcifront.c

diff --git a/MAINTAINERS b/MAINTAINERS
index d8afd29..ed8d991 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -4759,6 +4759,7 @@ F:arch/x86/kernel/cpu/mshyperv.c
 F: drivers/hid/hid-hyperv.c
 F: drivers/hv/
 F: drivers/input/serio/hyperv-keyboard.c
+F: drivers/pci/host/hv_pcifront.c
 F: drivers/net/hyperv/
 F: drivers/scsi/storvsc_drv.c
 F: drivers/video/fbdev/hyperv_fb.c
diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig
index 7a8f1c5..e008f68 100644
--- a/drivers/pci/Kconfig
+++ b/drivers/pci/Kconfig
@@ -114,4 +114,13 @@ config PCI_LABEL
def_bool y if (DMI || ACPI)
select NLS
 
+config HYPERV_VPCI
+tristate "Hyper-V PCI Frontend"
+depends on PCI && X86 && HYPERV
+select PCI_HV
+default y
+help
+  The PCI device frontend driver allows the kernel to import arbitrary
+  PCI devices from a PCI backend to support PCI driver domains.
+
 source "drivers/pci/host/Kconfig"
diff --git a/drivers/pci/host/Makefile b/drivers/pci/host/Makefile
index f733b4e..7bf8442 100644
--- a/drivers/pci/host/Makefile
+++ b/drivers/pci/host/Makefile
@@ -2,6 +2,7 @@ obj-$(CONFIG_PCIE_DW) += pcie-designware.o
 obj-$(CONFIG_PCI_DRA7XX) += pci-dra7xx.o
 obj-$(CONFIG_PCI_EXYNOS) += pci-exynos.o
 obj-$(CONFIG_PCI_IMX6) += pci-imx6.o
+obj-$(CONFIG_HYPERV_VPCI) += hv_pcifront.o
 obj-$(CONFIG_PCI_MVEBU) += pci-mvebu.o
 obj-$(CONFIG_PCI_TEGRA) += pci-tegra.o
 obj-$(CONFIG_PCI_RCAR_GEN2) += pci-rcar-gen2.o
diff --git a/drivers/pci/host/hv_pcifront.c b/drivers/pci/host/hv_pcifront.c
new file mode 100644
index 000..1bdfdd5
--- /dev/null
+++ b/drivers/pci/host/hv_pcifront.c
@@ -0,0 +1,2177 @@
+/*
+ * Copyright (c) Microsoft Corporation.
+ *
+ * Author:
+ *   Jake Oshins 
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+ * NON INFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+
+/*
+ * We begin with definitions supporting the Virtual PCI Express protocol
+ * with the host.
+ *
+ * Begin protocol definitions.
+ */
+
+
+/*
+ * Protocol versions. The low word is the minor version, the high word the 
major
+ * version.
+ */
+
+#define PCI_MAKE_VERSION(Major, Minor) ((__u32)(((Major) << 16) | (Minor)))
+#define PCI_MAJOR_VERSION(Version) ((__u32)(Version) >> 16)
+#define PCI_MINOR_VERSION(Version) ((__u32)(Version) & 0xff)
+
+enum {
+   PCI_PROTOCOL_VERSION_1_1 = PCI_MAKE_VERSION(1, 1),
+   PCI_PROTOCOL_VERSION_CURRENT = PCI_PROTOCOL_VERSION_1_1
+};
+
+#define PCI_CONFIG_MMIO_LENGTH 0x2000
+
+/*
+ * Message Types
+ */
+
+enum pci_message_type {
+   /*
+* Version 1.1
+*/
+   PCI_MESSAGE_BASE= 0x4249,
+   PCI_BUS_RELATIONS   = PCI_MESSAGE_BASE + 0,
+   PCI_QUERY_BUS_RELATIONS = PCI_MESSAGE_BASE + 1,
+   PCI_POWER_STATE_CHANGE  = PCI_MESSAGE_BASE + 4,
+   PCI_QUERY_RESOURCE_REQUIREMENTS = PCI_MESSAGE_BASE + 5,
+   PCI_QUERY_RESOURCE_RESOURCES= PCI_MESSAGE_BASE + 6,
+   PCI_BUS_D0ENTRY = PCI_MESSAGE_BASE + 7,
+   PCI_BUS_D0EXIT  = PCI_MESSAGE_BASE + 8,
+   PCI_READ_BLOCK  = PCI_MESSAGE_BASE + 9,
+   PCI_WRITE_BLOCK = PCI_MESSAGE_BASE + 0xA,
+   PCI_EJECT   = PCI_MESSAGE_BASE + 0xB,
+   PCI_QUERY_STOP  = PCI_MESSAGE_BASE + 0xC,
+   PCI_REENABLE= PCI_MESSAGE_BASE + 0xD,
+   PCI_QUERY_STOP_FAILED   = PCI_MESSAGE_BASE + 0xE,
+   PCI_EJECTION_COMPLETE   = PCI_MESSAGE_BASE + 0xF,
+   PCI_RESOURCES_ASSIGNED  = PCI_MESSAGE_BASE + 0x10,
+   PCI_RESOURCES_RELEASED  = PCI_MESSAGE_BASE + 0x11,
+   PCI_INVALIDATE_BLOCK= PCI_MESSAGE_BASE + 0x12,
+   PCI_QUERY_PROTOCOL_VERSION  = PCI_MESSAGE_BASE + 0x13,
+   PCI_CREATE_INTERRUPT_MESSAGE= PCI_MESSAGE_BASE + 

[PATCH v2 2/6] drivers:hv: Move MMIO range picking from hyper_fb.mod to hv_vmbus.mod

2015-06-15 Thread jakeo
From: Jake Oshins 

Currently, hv_vmbus finds the ranges of memory-mapped I/O space that are
designated for paravirtual (and fully virtual) devices by the virtual
firmware (BIOS or UEFI) and exports the answer.  The hyperv_fb video
driver then takes that information and uses it to claim a range of MMIO
space.

This patch moves the logic for deciding which sub-range of MMIO space to
claim from hyperv_fb to hv_vmbus, so that other drivers can share the
same logic.  It is also slightly expanded so that it searches all of the
potential MMIO ranges described by the ACPI namespace.

Signed-off-by: Jake Oshins 
---
 drivers/hv/vmbus_drv.c  | 87 -
 drivers/video/fbdev/hyperv_fb.c | 46 ++
 include/linux/hyperv.h  |  7 +++-
 3 files changed, 112 insertions(+), 28 deletions(-)

diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c
index d0e8832..067a469 100644
--- a/drivers/hv/vmbus_drv.c
+++ b/drivers/hv/vmbus_drv.c
@@ -39,6 +39,7 @@
 #include 
 #include 
 #include 
+#include 
 #include "hyperv_vmbus.h"
 
 static struct acpi_device  *hv_acpi_dev;
@@ -73,7 +74,6 @@ static struct notifier_block hyperv_panic_block = {
 };
 
 struct resource *hyperv_mmio;
-EXPORT_SYMBOL_GPL(hyperv_mmio);
 
 static int vmbus_exists(void)
 {
@@ -1073,6 +1073,91 @@ static int vmbus_acpi_remove(struct acpi_device *device)
return 0;
 }
 
+/**
+ * This function walks the resources granted to VMBus by the
+ * _CRS object in the ACPI namespace underneath the parent
+ * "bridge" whether that's a root PCI bus in the Generation 1
+ * case or a Module Device in the Generation 2 case.  It then
+ * attempts to allocate from the global MMIO pool in a way that
+ * matches the constraints supplied in these parameters and by
+ * that _CRS.
+ *
+ * @param new - If successful, supplied a pointer to the
+ *allocated MMIO space.
+ * @param device_obj - Identifies the caller
+ * @param min - Minimum guest physical address of the allocation
+ * @param max - Maximum guest physical address
+ * @param size - Size of the range to be allocated
+ * @param align - Alignment of the range to be allocated
+ * @param fb_overlap_ok - Whether this allocation can be allowed
+ * to overlap the video frame buffer.
+ *
+ * @return int
+ */
+int vmbus_allocate_mmio(struct resource **new, struct hv_device *device_obj,
+   resource_size_t min, resource_size_t max,
+   resource_size_t size, resource_size_t align,
+   bool fb_overlap_ok)
+{
+   struct resource *iter;
+   resource_size_t range_min, range_max, start, local_min, local_max;
+   const char *dev_n = dev_name(&device_obj->device);
+   u32 fb_end = screen_info.lfb_base + (screen_info.lfb_size << 1);
+   int i;
+
+   pr_devel("allocating %llxx bytes alignment %llx in %llx->%llx for %s\n",
+size, align, min, max, dev_n);
+
+   for (iter = hyperv_mmio; iter; iter = iter->sibling) {
+
+   if ((iter->start >= max) || (iter->end <= min))
+   continue;
+
+   range_min = iter->start;
+   range_max = iter->end;
+
+   /* If this range overlaps the frame buffer, split it into
+  two tries. */
+   for (i = 0; i < 2; i++) {
+   local_min = range_min;
+   local_max = range_max;
+   if (fb_overlap_ok || ((range_min >= fb_end) ||
+ (range_max <= screen_info.lfb_base))) {
+   i++;
+   } else {
+   if ((range_min <= screen_info.lfb_base) &&
+   (range_max >= screen_info.lfb_base)) {
+
+   /*
+* The frame buffer is in this window,
+* so trim this into the part that
+* preceeds the frame buffer.
+*/
+   local_max = screen_info.lfb_base-1;
+   range_min = fb_end;
+   } else {
+   range_min = fb_end;
+   continue;
+   }
+   }
+
+   pr_devel("looking between %llx:%llx\n", range_min,
+range_max);
+   start = (local_min + align - 1) & ~(align - 1);
+   for (; start + size - 1 <= local_max; start += align) {
+   *new = request_mem_region_exclusive(start, size,
+   dev_n);
+   if (*new)
+ 

[PATCH v2 5/6] drivers:hv: Define the channel type for Hyper-V PCI Express pass-through

2015-06-15 Thread jakeo
From: Jake Oshins 

This patch updates the list of VMBus channel GUIDs, defining the one
for PCI Express pass-through.

Signed-off-by: Jake Oshins 
---
 include/linux/hyperv.h | 11 +++
 1 file changed, 11 insertions(+)

diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h
index 6fec42d..1903238 100644
--- a/include/linux/hyperv.h
+++ b/include/linux/hyperv.h
@@ -1144,6 +1144,17 @@ int vmbus_procnum_to_vpnum(int procnum);
}
 
 /*
+ * PCI Express Pass Through
+ * {44C4F61D--4400-9D52-802E27EDE19F}
+ */
+
+#define HV_PCIE_GUID \
+   .guid = { \
+   0x1D, 0xF6, 0xC4, 0x44, 0x44, 0x44, 0x00, 0x44, \
+   0x9D, 0x52, 0x80, 0x2E, 0x27, 0xED, 0xE1, 0x9F \
+   }
+
+/*
  * Common header for Hyper-V ICs
  */
 
-- 
1.9.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH v2 3/6] arch:x86:hv: Add mechanism for Hyper-V paravirt drivers to hook msi message creation

2015-06-15 Thread jakeo
From: Jake Oshins 

This patch, when the kernel is built with CONFIG_HYPERV, exposes functions
that would allow a paravirtual PCI front-end driver to hook MSI (message-
signaled interrupt) message creation.

Signed-off-by: Jake Oshins 
---
 arch/x86/include/asm/mshyperv.h |  2 ++
 arch/x86/kernel/cpu/mshyperv.c  | 30 ++
 2 files changed, 32 insertions(+)

diff --git a/arch/x86/include/asm/mshyperv.h b/arch/x86/include/asm/mshyperv.h
index c163215..bf7789e 100644
--- a/arch/x86/include/asm/mshyperv.h
+++ b/arch/x86/include/asm/mshyperv.h
@@ -19,5 +19,7 @@ void hyperv_callback_vector(void);
 void hyperv_vector_handler(struct pt_regs *regs);
 void hv_setup_vmbus_irq(void (*handler)(void));
 void hv_remove_vmbus_irq(void);
+void hyperv_install_interrupt_translation(struct x86_msi_ops *new_ops);
+void hyperv_uninstall_interrupt_translation(void);
 
 #endif
diff --git a/arch/x86/kernel/cpu/mshyperv.c b/arch/x86/kernel/cpu/mshyperv.c
index 939155f..816e329 100644
--- a/arch/x86/kernel/cpu/mshyperv.c
+++ b/arch/x86/kernel/cpu/mshyperv.c
@@ -69,6 +69,36 @@ void hv_remove_vmbus_irq(void)
 }
 EXPORT_SYMBOL_GPL(hv_setup_vmbus_irq);
 EXPORT_SYMBOL_GPL(hv_remove_vmbus_irq);
+
+struct x86_msi_ops old_msi_ops;
+
+void hyperv_install_interrupt_translation(struct x86_msi_ops *new_ops)
+{
+   old_msi_ops.setup_msi_irqs = xchg(&(x86_msi.setup_msi_irqs),
+ new_ops->setup_msi_irqs);
+   old_msi_ops.compose_msi_msg = xchg(&(x86_msi.compose_msi_msg),
+  new_ops->compose_msi_msg);
+   old_msi_ops.teardown_msi_irqs = xchg(&(x86_msi.teardown_msi_irqs),
+new_ops->teardown_msi_irqs);
+   old_msi_ops.restore_msi_irqs = xchg(&(x86_msi.restore_msi_irqs),
+   new_ops->restore_msi_irqs);
+
+   new_ops->setup_msi_irqs = old_msi_ops.setup_msi_irqs;
+   new_ops->compose_msi_msg = old_msi_ops.compose_msi_msg;
+   new_ops->teardown_msi_irqs = old_msi_ops.teardown_msi_irqs;
+   new_ops->restore_msi_irqs = old_msi_ops.restore_msi_irqs;
+}
+EXPORT_SYMBOL_GPL(hyperv_install_interrupt_translation);
+
+void hyperv_uninstall_interrupt_translation(void)
+{
+   xchg(&(x86_msi.setup_msi_irqs), old_msi_ops.setup_msi_irqs);
+   xchg(&(x86_msi.compose_msi_msg), old_msi_ops.compose_msi_msg);
+   xchg(&(x86_msi.teardown_msi_irqs), old_msi_ops.teardown_msi_irqs);
+   xchg(&(x86_msi.restore_msi_irqs), old_msi_ops.restore_msi_irqs);
+}
+EXPORT_SYMBOL_GPL(hyperv_uninstall_interrupt_translation);
+
 #endif
 
 static uint32_t  __init ms_hyperv_platform(void)
-- 
1.9.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH v2 4/6] drivers:hv: Export a function that maps Linux proc num onto Hyper-V proc num

2015-06-15 Thread jakeo
From: Jake Oshins 

This patch exports a function which maps Linux processor number onto Hyper-V
virtual processor number.  This is necessary in order to map message-
signaled interrupts (MSIs) into a VM, as the hypervisor needs to know the
right target VP.

Signed-off-by: Jake Oshins 
---
 drivers/hv/vmbus_drv.c | 16 
 include/linux/hyperv.h |  2 ++
 2 files changed, 18 insertions(+)

diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c
index 067a469..65e4eb6 100644
--- a/drivers/hv/vmbus_drv.c
+++ b/drivers/hv/vmbus_drv.c
@@ -1158,6 +1158,22 @@ int vmbus_allocate_mmio(struct resource **new, struct 
hv_device *device_obj,
 }
 EXPORT_SYMBOL_GPL(vmbus_allocate_mmio);
 
+/**
+ * This function returns the mapping between the Linux processor
+ * number and
+ * the hypervisor's virtual processor number, useful in making
+ * hypercalls and such that talk about specific processors.
+ *
+ * @param procnum - in Linux terms
+ *
+ * @return int - in Hyper-V terms
+ */
+int vmbus_procnum_to_vpnum(int procnum)
+{
+   return hv_context.vp_index[procnum];
+}
+EXPORT_SYMBOL_GPL(vmbus_procnum_to_vpnum);
+
 static int vmbus_acpi_add(struct acpi_device *device)
 {
acpi_status result;
diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h
index ffd98d7..6fec42d 100644
--- a/include/linux/hyperv.h
+++ b/include/linux/hyperv.h
@@ -987,6 +987,8 @@ int vmbus_allocate_mmio(struct resource **new, struct 
hv_device *device_obj,
resource_size_t size, resource_size_t align,
bool fb_overlap_ok);
 
+int vmbus_procnum_to_vpnum(int procnum);
+
 /**
  * VMBUS_DEVICE - macro used to describe a specific hyperv vmbus device
  *
-- 
1.9.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH v2 6/6] drivers:pci:hv: New paravirtual PCI front-end for Hyper-V VMs

2015-06-15 Thread jakeo
From: Jake Oshins 

This patch supplies a new driver, hv_pcifront, which exposes new root PCI
buses.  When a Hyper-V VM running Linux is offered a paravirtual PCI bus
in order to expose a device passed through on that bus, this drver
registers a new bus with the PCI driver.  This new bus is bus "zero"
within a new PCI domain.  This is done so that there's no overlap between
the emulated, or fully virtualized, PCI that may be in the VM and a real
PCIe device that will be exposed.

This PCI front-end only supports PCIe devices which do not use I/O BARs and
which do not need a legacy INTx# interrupt (relying on MSI or MSI-X).
Multifunction devices are supported, but devices with Type 1 or Type 2
config headers are not supported.  (These are bridges to other PCI buses.)

The content of this patch differs from the one sent previously in that it
incorporates feedback related to unused code (which has been removed) and
GPL license (which has been updated.)  It also removes Kconfig lines that
had been copied from the Xen PCI front-end entry, but which shouldn't be
used here.

Signed-off-by: Jake Oshins 
---
 MAINTAINERS|1 +
 drivers/pci/Kconfig|7 +
 drivers/pci/host/Makefile  |1 +
 drivers/pci/host/hv_pcifront.c | 1984 
 4 files changed, 1993 insertions(+)
 create mode 100644 drivers/pci/host/hv_pcifront.c

diff --git a/MAINTAINERS b/MAINTAINERS
index d8afd29..ed8d991 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -4759,6 +4759,7 @@ F:arch/x86/kernel/cpu/mshyperv.c
 F: drivers/hid/hid-hyperv.c
 F: drivers/hv/
 F: drivers/input/serio/hyperv-keyboard.c
+F: drivers/pci/host/hv_pcifront.c
 F: drivers/net/hyperv/
 F: drivers/scsi/storvsc_drv.c
 F: drivers/video/fbdev/hyperv_fb.c
diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig
index 7a8f1c5..3ee97a9 100644
--- a/drivers/pci/Kconfig
+++ b/drivers/pci/Kconfig
@@ -114,4 +114,11 @@ config PCI_LABEL
def_bool y if (DMI || ACPI)
select NLS
 
+config HYPERV_VPCI
+tristate "Hyper-V PCI Frontend"
+depends on PCI && X86 && HYPERV
+help
+  The PCI device frontend driver allows the kernel to import arbitrary
+  PCI devices from a PCI backend to support PCI driver domains.
+
 source "drivers/pci/host/Kconfig"
diff --git a/drivers/pci/host/Makefile b/drivers/pci/host/Makefile
index f733b4e..7bf8442 100644
--- a/drivers/pci/host/Makefile
+++ b/drivers/pci/host/Makefile
@@ -2,6 +2,7 @@ obj-$(CONFIG_PCIE_DW) += pcie-designware.o
 obj-$(CONFIG_PCI_DRA7XX) += pci-dra7xx.o
 obj-$(CONFIG_PCI_EXYNOS) += pci-exynos.o
 obj-$(CONFIG_PCI_IMX6) += pci-imx6.o
+obj-$(CONFIG_HYPERV_VPCI) += hv_pcifront.o
 obj-$(CONFIG_PCI_MVEBU) += pci-mvebu.o
 obj-$(CONFIG_PCI_TEGRA) += pci-tegra.o
 obj-$(CONFIG_PCI_RCAR_GEN2) += pci-rcar-gen2.o
diff --git a/drivers/pci/host/hv_pcifront.c b/drivers/pci/host/hv_pcifront.c
new file mode 100644
index 000..2c01fc2
--- /dev/null
+++ b/drivers/pci/host/hv_pcifront.c
@@ -0,0 +1,1984 @@
+/*
+ * Copyright (c) Microsoft Corporation.
+ *
+ * Author:
+ *   Jake Oshins 
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+ * NON INFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+
+/*
+ * We begin with definitions supporting the Virtual PCI Express protocol
+ * with the host.
+ *
+ * Begin protocol definitions.
+ */
+
+
+/*
+ * Protocol versions. The low word is the minor version, the high word the 
major
+ * version.
+ */
+
+#define PCI_MAKE_VERSION(Major, Minor) ((__u32)(((Major) << 16) | (Minor)))
+#define PCI_MAJOR_VERSION(Version) ((__u32)(Version) >> 16)
+#define PCI_MINOR_VERSION(Version) ((__u32)(Version) & 0xff)
+
+enum {
+   PCI_PROTOCOL_VERSION_1_1 = PCI_MAKE_VERSION(1, 1),
+   PCI_PROTOCOL_VERSION_CURRENT = PCI_PROTOCOL_VERSION_1_1
+};
+
+#define PCI_CONFIG_MMIO_LENGTH 0x2000
+
+/*
+ * Message Types
+ */
+
+enum pci_message_type {
+   /*
+* Version 1.1
+*/
+   PCI_MESSAGE_BASE= 0x4249,
+   PCI_BUS_RELATIONS   = PCI_MESSAGE_BASE + 0,
+   PCI_QUERY_BUS_RELATIONS = PCI_MESSAGE_BASE + 1,
+   PCI_POWER_STATE_CHANGE  = PCI_MESSAGE_BASE + 4,
+   PCI_QUERY_RESOURCE_REQUIREMENTS = PCI_MESSAGE_BASE + 5,
+   PCI_QUERY_RESOURCE_RESOURCES= PCI_MESSAGE_BASE + 6,
+   PCI_BUS_D0ENTRY  

[PATCH v2 0/6] hv: Front-end driver for PCIe Pass-through on Hyper-V

2015-06-15 Thread jakeo
From: Jake Oshins 

This patch does some slight refactoring on the hv_vmbus driver and its
dependents and then introduces a new paravirtual front-end driver for PCI
which supports PCI Express devices passed through to a Linux guest running
in a Hyper-V VM.

To support this front-end, several new mechanisms are introduced:

1 - A common way of finding free memory-mapped I/O space in a Hyper-V VM, 
available to all Hyper-V-related drivers.

2 - A way of handling PCI Message-Signaled Interrupt (MSI and MSI-X)
creation and formatting when Hyper-V is running.

3 - A mapping function from Linux processor number to Hyper-V virtual
processor number, available to drivers, which is necessary for MSI(-X)
creation.

The Hyper-V Frame Buffer driver is modified to use the MMIO space
allocation function so that its allocations both don't collide with the
PCI front end and so that the chosen range can come from any available
part of MMIO space.

Finally, the new PCI front-end driver is the last patch in the series.

This patch series incorporates feedback from Greg K-H and Paul Bolle, and
it differs from the the first version in that it:

- Removes code that has no callers
- Updates the MODULE_LICENSE macro
- Provides explanations in each of the patches
- Fixes the Kconfig so that the defaults and depends are reasonable

Jake Oshins (6):
  drivers:hv: Modify vmbus to search for all MMIO ranges available
  drivers:hv: Move MMIO range picking from hyper_fb.mod to hv_vmbus.mod
  arch:x86:hv: Add mechanism for Hyper-V paravirt drivers to hook msi
message creation
  drivers:hv: Export a function that maps Linux proc num onto Hyper-V
proc num
  drivers:hv: Define the channel type for Hyper-V PCI Express
pass-through
  drivers:pci:hv: New paravirtual PCI front-end for Hyper-V VMs

 MAINTAINERS |1 +
 arch/x86/include/asm/mshyperv.h |2 +
 arch/x86/kernel/cpu/mshyperv.c  |   30 +
 drivers/hv/vmbus_drv.c  |  208 +++-
 drivers/pci/Kconfig |7 +
 drivers/pci/host/Makefile   |1 +
 drivers/pci/host/hv_pcifront.c  | 1984 +++
 drivers/video/fbdev/hyperv_fb.c |   46 +-
 include/linux/hyperv.h  |   20 +-
 9 files changed, 2256 insertions(+), 43 deletions(-)
 create mode 100644 drivers/pci/host/hv_pcifront.c

-- 
1.9.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH v2 1/6] drivers:hv: Modify vmbus to search for all MMIO ranges available

2015-06-15 Thread jakeo
From: Jake Oshins 

Before this patch, hv_vmbus would search the ACPI namespace above its
device looking for a _CRS (current resources) object, and hunt through
the list of resources in there looking for one that described memory-
mapped I/O space above the 4GB line.  It then exported the result for
use in the hyperv_fb (frame buffer) driver.

With this patch, hv_vmbus looks for all usable MMIO ranges above 1GB
and makes a list of them, with the highest range first in the list,
as drivers which can allocate from that range should allocate from it.

Hyperv_fb is slightly modified to use this change.

This change is necessary for supporting other Hyper-V related drivers,
which might need MMIO space below 4GB.

Signed-off-by: Jake Oshins 
---
 drivers/hv/vmbus_drv.c  | 105 ++--
 drivers/video/fbdev/hyperv_fb.c |   2 +-
 include/linux/hyperv.h  |   2 +-
 3 files changed, 92 insertions(+), 17 deletions(-)

diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c
index c85235e..d0e8832 100644
--- a/drivers/hv/vmbus_drv.c
+++ b/drivers/hv/vmbus_drv.c
@@ -72,10 +72,7 @@ static struct notifier_block hyperv_panic_block = {
.notifier_call = hyperv_panic_event,
 };
 
-struct resource hyperv_mmio = {
-   .name  = "hyperv mmio",
-   .flags = IORESOURCE_MEM,
-};
+struct resource *hyperv_mmio;
 EXPORT_SYMBOL_GPL(hyperv_mmio);
 
 static int vmbus_exists(void)
@@ -982,30 +979,105 @@ void vmbus_device_unregister(struct hv_device 
*device_obj)
 
 
 /*
- * VMBUS is an acpi enumerated device. Get the the information we
+ * VMBUS is an acpi enumerated device. Get the information we
  * need from DSDT.
  */
-
+#define VTPM_BASE_ADDRESS 0xfed4
 static acpi_status vmbus_walk_resources(struct acpi_resource *res, void *ctx)
 {
+   resource_size_t start = 0;
+   resource_size_t end = 0;
+   struct resource *new_res;
+   struct resource **old_res = &hyperv_mmio;
+   struct resource **prev_res = NULL;
+
switch (res->type) {
case ACPI_RESOURCE_TYPE_IRQ:
irq = res->data.irq.interrupts[0];
+   return AE_OK;
+
+   /*
+* "Address" descriptors are for bus windows. Ignore
+* "memory" descriptors, which are for registers on
+* devices.
+*/
+   case ACPI_RESOURCE_TYPE_ADDRESS32:
+   start = res->data.address32.address.minimum;
+   end = res->data.address32.address.maximum;
break;
 
case ACPI_RESOURCE_TYPE_ADDRESS64:
-   hyperv_mmio.start = res->data.address64.address.minimum;
-   hyperv_mmio.end = res->data.address64.address.maximum;
+   start = res->data.address64.address.minimum;
+   end = res->data.address64.address.maximum;
break;
+
+   default:
+   /* Unused resource type */
+   return AE_OK;
+
}
+   /*
+* Ignore ranges that are below 1MB, as they're not
+* necessary or useful here.
+*/
+   if (end < 0x10)
+   return AE_OK;
+
+   new_res = kzalloc(sizeof(*new_res), GFP_ATOMIC);
+   if (!new_res)
+   return AE_NO_MEMORY;
+
+   /* If this range overlaps the virtual TPM, truncate it. */
+   if (end > VTPM_BASE_ADDRESS && start < VTPM_BASE_ADDRESS)
+   end = VTPM_BASE_ADDRESS;
+
+   new_res->name = "hyperv mmio";
+   new_res->flags = IORESOURCE_MEM;
+   new_res->start = start;
+   new_res->end = end;
+
+   do {
+   if (!*old_res) {
+   *old_res = new_res;
+   break;
+   }
+
+   if ((*old_res)->end < new_res->start) {
+   new_res->sibling = *old_res;
+   if (prev_res)
+   (*prev_res)->sibling = new_res;
+   *old_res = new_res;
+   break;
+   }
+
+   prev_res = old_res;
+   old_res = &(*old_res)->sibling;
+
+   } while (1);
 
return AE_OK;
 }
 
+static int vmbus_acpi_remove(struct acpi_device *device)
+{
+   struct resource *cur_res;
+   struct resource *next_res;
+
+   if (hyperv_mmio) {
+   for (cur_res = hyperv_mmio; cur_res; cur_res = next_res) {
+   next_res = cur_res->sibling;
+   kfree(cur_res);
+   }
+   }
+
+   return 0;
+}
+
 static int vmbus_acpi_add(struct acpi_device *device)
 {
acpi_status result;
int ret_val = -ENODEV;
+   struct acpi_device *ancestor;
 
hv_acpi_dev = device;
 
@@ -1015,23 +1087,25 @@ static int vmbus_acpi_add(struct acpi_device *device)
if (ACPI_FAILURE(result))
goto acpi_walk_err;
/*
-* The parent of the vmbus acpi device (Gen2 firmware) is the VMOD that
-* has the mmio ranges. Get that.
+* So

[PATCH v3 0/6] hv: Front-end driver for PCIe Pass-through on Hyper-V

2015-06-17 Thread jakeo
From: Jake Oshins 

This patch series differs from the previous one (v2) in that it fixes
kernel-doc commenting style and changes a few variable and function
names to be more understandable.

These patches do some slight refactoring on the hv_vmbus driver and its
dependents and then introduces a new paravirtual front-end driver for PCI
which supports PCI Express devices passed through to a Linux guest running
in a Hyper-V VM.

To support this front-end, several new mechanisms are introduced:

1 - A common way of finding free memory-mapped I/O space in a Hyper-V VM, 
available to all Hyper-V-related drivers.

2 - A way of handling PCI Message-Signaled Interrupt (MSI and MSI-X)
creation and formatting when Hyper-V is running.

3 - A mapping function from Linux processor number to Hyper-V virtual
processor number, available to drivers, which is necessary for MSI(-X)
creation.

The Hyper-V Frame Buffer driver is modified to use the MMIO space
allocation function so that its allocations both don't collide with the
PCI front end and so that the chosen range can come from any available
part of MMIO space.

Finally, the new PCI front-end driver is the last patch in the series.

Jake Oshins (6):
  hv: Modify vmbus to search for all MMIO ranges available
  drivers:hv: Move MMIO range picking from hyper_fb.mod to hv_vmbus.mod
  arch:x86:hv: Add mechanism for Hyper-V paravirt drivers to hook msi
creation
  drivers:hv: Export a function that maps Linux proc num onto Hyper-V
proc num
  drivers:hv: Define the channel type for Hyper-V PCI Express
pass-through
  drivers:pci:hv: New paravirtual PCI front-end for Hyper-V VMs

 MAINTAINERS |1 +
 arch/x86/include/asm/mshyperv.h |2 +
 arch/x86/kernel/cpu/mshyperv.c  |   30 +
 drivers/hv/vmbus_drv.c  |  205 +++-
 drivers/pci/Kconfig |7 +
 drivers/pci/host/Makefile   |1 +
 drivers/pci/host/hv_pcifront.c  | 2101 +++
 drivers/video/fbdev/hyperv_fb.c |   46 +-
 include/linux/hyperv.h  |   20 +-
 9 files changed, 2370 insertions(+), 43 deletions(-)
 create mode 100644 drivers/pci/host/hv_pcifront.c

-- 
1.9.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH v3 5/6] drivers:hv: Define the channel type for Hyper-V PCI Express pass-through

2015-06-17 Thread jakeo
From: Jake Oshins 

This patch updates the list of VMBus channel GUIDs, defining the one
for PCI Express pass-through.

Signed-off-by: Jake Oshins 
---
 include/linux/hyperv.h | 11 +++
 1 file changed, 11 insertions(+)

diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h
index 2e40f4d..43ce082 100644
--- a/include/linux/hyperv.h
+++ b/include/linux/hyperv.h
@@ -1144,6 +1144,17 @@ int vmbus_cpu_number_to_vp_number(int cpu_number);
}
 
 /*
+ * PCI Express Pass Through
+ * {44C4F61D--4400-9D52-802E27EDE19F}
+ */
+
+#define HV_PCIE_GUID \
+   .guid = { \
+   0x1D, 0xF6, 0xC4, 0x44, 0x44, 0x44, 0x00, 0x44, \
+   0x9D, 0x52, 0x80, 0x2E, 0x27, 0xED, 0xE1, 0x9F \
+   }
+
+/*
  * Common header for Hyper-V ICs
  */
 
-- 
1.9.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH v3 1/6] hv: Modify vmbus to search for all MMIO ranges available

2015-06-17 Thread jakeo
From: Jake Oshins 

Before this patch, hv_vmbus would search the ACPI namespace above its
device looking for a _CRS (current resources) object, and hunt through
the list of resources in there looking for one that described memory-
mapped I/O space above the 4GB line.  It then exported the result for
use in the hyperv_fb (frame buffer) driver.

With this patch, hv_vmbus looks for all usable MMIO ranges above 1GB
and makes a list of them, with the highest range first in the list,
as drivers which can allocate from that range should allocate from it.

Hyperv_fb is slightly modified to use this change.

This change is necessary for supporting other Hyper-V related drivers,
which might need MMIO space below 4GB.

Signed-off-by: Jake Oshins 
---
 drivers/hv/vmbus_drv.c  | 105 ++--
 drivers/video/fbdev/hyperv_fb.c |   2 +-
 include/linux/hyperv.h  |   2 +-
 3 files changed, 92 insertions(+), 17 deletions(-)

diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c
index c85235e..d0e8832 100644
--- a/drivers/hv/vmbus_drv.c
+++ b/drivers/hv/vmbus_drv.c
@@ -72,10 +72,7 @@ static struct notifier_block hyperv_panic_block = {
.notifier_call = hyperv_panic_event,
 };
 
-struct resource hyperv_mmio = {
-   .name  = "hyperv mmio",
-   .flags = IORESOURCE_MEM,
-};
+struct resource *hyperv_mmio;
 EXPORT_SYMBOL_GPL(hyperv_mmio);
 
 static int vmbus_exists(void)
@@ -982,30 +979,105 @@ void vmbus_device_unregister(struct hv_device 
*device_obj)
 
 
 /*
- * VMBUS is an acpi enumerated device. Get the the information we
+ * VMBUS is an acpi enumerated device. Get the information we
  * need from DSDT.
  */
-
+#define VTPM_BASE_ADDRESS 0xfed4
 static acpi_status vmbus_walk_resources(struct acpi_resource *res, void *ctx)
 {
+   resource_size_t start = 0;
+   resource_size_t end = 0;
+   struct resource *new_res;
+   struct resource **old_res = &hyperv_mmio;
+   struct resource **prev_res = NULL;
+
switch (res->type) {
case ACPI_RESOURCE_TYPE_IRQ:
irq = res->data.irq.interrupts[0];
+   return AE_OK;
+
+   /*
+* "Address" descriptors are for bus windows. Ignore
+* "memory" descriptors, which are for registers on
+* devices.
+*/
+   case ACPI_RESOURCE_TYPE_ADDRESS32:
+   start = res->data.address32.address.minimum;
+   end = res->data.address32.address.maximum;
break;
 
case ACPI_RESOURCE_TYPE_ADDRESS64:
-   hyperv_mmio.start = res->data.address64.address.minimum;
-   hyperv_mmio.end = res->data.address64.address.maximum;
+   start = res->data.address64.address.minimum;
+   end = res->data.address64.address.maximum;
break;
+
+   default:
+   /* Unused resource type */
+   return AE_OK;
+
}
+   /*
+* Ignore ranges that are below 1MB, as they're not
+* necessary or useful here.
+*/
+   if (end < 0x10)
+   return AE_OK;
+
+   new_res = kzalloc(sizeof(*new_res), GFP_ATOMIC);
+   if (!new_res)
+   return AE_NO_MEMORY;
+
+   /* If this range overlaps the virtual TPM, truncate it. */
+   if (end > VTPM_BASE_ADDRESS && start < VTPM_BASE_ADDRESS)
+   end = VTPM_BASE_ADDRESS;
+
+   new_res->name = "hyperv mmio";
+   new_res->flags = IORESOURCE_MEM;
+   new_res->start = start;
+   new_res->end = end;
+
+   do {
+   if (!*old_res) {
+   *old_res = new_res;
+   break;
+   }
+
+   if ((*old_res)->end < new_res->start) {
+   new_res->sibling = *old_res;
+   if (prev_res)
+   (*prev_res)->sibling = new_res;
+   *old_res = new_res;
+   break;
+   }
+
+   prev_res = old_res;
+   old_res = &(*old_res)->sibling;
+
+   } while (1);
 
return AE_OK;
 }
 
+static int vmbus_acpi_remove(struct acpi_device *device)
+{
+   struct resource *cur_res;
+   struct resource *next_res;
+
+   if (hyperv_mmio) {
+   for (cur_res = hyperv_mmio; cur_res; cur_res = next_res) {
+   next_res = cur_res->sibling;
+   kfree(cur_res);
+   }
+   }
+
+   return 0;
+}
+
 static int vmbus_acpi_add(struct acpi_device *device)
 {
acpi_status result;
int ret_val = -ENODEV;
+   struct acpi_device *ancestor;
 
hv_acpi_dev = device;
 
@@ -1015,23 +1087,25 @@ static int vmbus_acpi_add(struct acpi_device *device)
if (ACPI_FAILURE(result))
goto acpi_walk_err;
/*
-* The parent of the vmbus acpi device (Gen2 firmware) is the VMOD that
-* has the mmio ranges. Get that.
+* So

[PATCH v3 2/6] drivers:hv: Move MMIO range picking from hyper_fb.mod to hv_vmbus.mod

2015-06-17 Thread jakeo
From: Jake Oshins 

Currently, hv_vmbus finds the ranges of memory-mapped I/O space that are
designated for paravirtual (and fully virtual) devices by the virtual
firmware (BIOS or UEFI) and exports the answer.  The hyperv_fb video
driver then takes that information and uses it to claim a range of MMIO
space.

This patch moves the logic for deciding which sub-range of MMIO space to
claim from hyperv_fb to hv_vmbus, so that other drivers can share the
same logic.  It is also slightly expanded so that it searches all of the
potential MMIO ranges described by the ACPI namespace.

Signed-off-by: Jake Oshins 
---
 drivers/hv/vmbus_drv.c  | 83 -
 drivers/video/fbdev/hyperv_fb.c | 46 +++
 include/linux/hyperv.h  |  7 +++-
 3 files changed, 108 insertions(+), 28 deletions(-)

diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c
index d0e8832..9b4fc1a 100644
--- a/drivers/hv/vmbus_drv.c
+++ b/drivers/hv/vmbus_drv.c
@@ -39,6 +39,7 @@
 #include 
 #include 
 #include 
+#include 
 #include "hyperv_vmbus.h"
 
 static struct acpi_device  *hv_acpi_dev;
@@ -73,7 +74,6 @@ static struct notifier_block hyperv_panic_block = {
 };
 
 struct resource *hyperv_mmio;
-EXPORT_SYMBOL_GPL(hyperv_mmio);
 
 static int vmbus_exists(void)
 {
@@ -1073,6 +1073,87 @@ static int vmbus_acpi_remove(struct acpi_device *device)
return 0;
 }
 
+/**
+ * vmbus_allocate_mmio() - Pick a memory-mapped I/O range.
+ * @new: If successful, supplied a pointer to the allocated MMIO
+ * space.
+ * @device_obj: Identifies the caller
+ * @min: Minimum guest physical address of the allocation
+ * @max: Maximum guest physical address
+ * @size: Size of the range to be allocated
+ * @align: Alignment of the range to be allocated
+ * @fb_overlap_ok: Whether this allocation can be allowed to
+ *  overlap the video frame buffer.
+ *
+ * This function walks the resources granted to VMBus by the
+ * _CRS object in the ACPI namespace underneath the parent
+ * "bridge" whether that's a root PCI bus in the Generation 1
+ * case or a Module Device in the Generation 2 case.  It then
+ * attempts to allocate from the global MMIO pool in a way that
+ * matches the constraints supplied in these parameters and by
+ * that _CRS.
+ *
+ * Return: 0 on success, -errno on failure
+ *
+ */
+int vmbus_allocate_mmio(struct resource **new, struct hv_device *device_obj,
+   resource_size_t min, resource_size_t max,
+   resource_size_t size, resource_size_t align,
+   bool fb_overlap_ok)
+{
+   struct resource *iter;
+   resource_size_t range_min, range_max, start, local_min, local_max;
+   const char *dev_n = dev_name(&device_obj->device);
+   u32 fb_end = screen_info.lfb_base + (screen_info.lfb_size << 1);
+   int i;
+
+   for (iter = hyperv_mmio; iter; iter = iter->sibling) {
+
+   if ((iter->start >= max) || (iter->end <= min))
+   continue;
+
+   range_min = iter->start;
+   range_max = iter->end;
+
+   /* If this range overlaps the frame buffer, split it into
+  two tries. */
+   for (i = 0; i < 2; i++) {
+   local_min = range_min;
+   local_max = range_max;
+   if (fb_overlap_ok || ((range_min >= fb_end) ||
+ (range_max <= screen_info.lfb_base))) {
+   i++;
+   } else {
+   if ((range_min <= screen_info.lfb_base) &&
+   (range_max >= screen_info.lfb_base)) {
+
+   /*
+* The frame buffer is in this window,
+* so trim this into the part that
+* preceeds the frame buffer.
+*/
+   local_max = screen_info.lfb_base-1;
+   range_min = fb_end;
+   } else {
+   range_min = fb_end;
+   continue;
+   }
+   }
+
+   start = (local_min + align - 1) & ~(align - 1);
+   for (; start + size - 1 <= local_max; start += align) {
+   *new = request_mem_region_exclusive(start, size,
+   dev_n);
+   if (*new)
+   return 0;
+   }
+   }
+   }
+
+   return -ENXIO;
+}
+EXPORT_SYMBOL_GPL(vmbus_allocate_mmio);
+
 static int vmbus_acpi_add(struct acpi_device *device)
 {
acpi_status result

[PATCH v3 3/6] arch:x86:hv: Add mechanism for Hyper-V paravirt drivers to hook msi creation

2015-06-17 Thread jakeo
From: Jake Oshins 

This patch, when the kernel is built with CONFIG_HYPERV, exposes functions
that would allow a paravirtual PCI front-end driver to hook MSI (message-
signaled interrupt) message creation.

Signed-off-by: Jake Oshins 
---
 arch/x86/include/asm/mshyperv.h |  2 ++
 arch/x86/kernel/cpu/mshyperv.c  | 30 ++
 2 files changed, 32 insertions(+)

diff --git a/arch/x86/include/asm/mshyperv.h b/arch/x86/include/asm/mshyperv.h
index c163215..bf7789e 100644
--- a/arch/x86/include/asm/mshyperv.h
+++ b/arch/x86/include/asm/mshyperv.h
@@ -19,5 +19,7 @@ void hyperv_callback_vector(void);
 void hyperv_vector_handler(struct pt_regs *regs);
 void hv_setup_vmbus_irq(void (*handler)(void));
 void hv_remove_vmbus_irq(void);
+void hyperv_install_interrupt_translation(struct x86_msi_ops *new_ops);
+void hyperv_uninstall_interrupt_translation(void);
 
 #endif
diff --git a/arch/x86/kernel/cpu/mshyperv.c b/arch/x86/kernel/cpu/mshyperv.c
index 939155f..816e329 100644
--- a/arch/x86/kernel/cpu/mshyperv.c
+++ b/arch/x86/kernel/cpu/mshyperv.c
@@ -69,6 +69,36 @@ void hv_remove_vmbus_irq(void)
 }
 EXPORT_SYMBOL_GPL(hv_setup_vmbus_irq);
 EXPORT_SYMBOL_GPL(hv_remove_vmbus_irq);
+
+struct x86_msi_ops old_msi_ops;
+
+void hyperv_install_interrupt_translation(struct x86_msi_ops *new_ops)
+{
+   old_msi_ops.setup_msi_irqs = xchg(&(x86_msi.setup_msi_irqs),
+ new_ops->setup_msi_irqs);
+   old_msi_ops.compose_msi_msg = xchg(&(x86_msi.compose_msi_msg),
+  new_ops->compose_msi_msg);
+   old_msi_ops.teardown_msi_irqs = xchg(&(x86_msi.teardown_msi_irqs),
+new_ops->teardown_msi_irqs);
+   old_msi_ops.restore_msi_irqs = xchg(&(x86_msi.restore_msi_irqs),
+   new_ops->restore_msi_irqs);
+
+   new_ops->setup_msi_irqs = old_msi_ops.setup_msi_irqs;
+   new_ops->compose_msi_msg = old_msi_ops.compose_msi_msg;
+   new_ops->teardown_msi_irqs = old_msi_ops.teardown_msi_irqs;
+   new_ops->restore_msi_irqs = old_msi_ops.restore_msi_irqs;
+}
+EXPORT_SYMBOL_GPL(hyperv_install_interrupt_translation);
+
+void hyperv_uninstall_interrupt_translation(void)
+{
+   xchg(&(x86_msi.setup_msi_irqs), old_msi_ops.setup_msi_irqs);
+   xchg(&(x86_msi.compose_msi_msg), old_msi_ops.compose_msi_msg);
+   xchg(&(x86_msi.teardown_msi_irqs), old_msi_ops.teardown_msi_irqs);
+   xchg(&(x86_msi.restore_msi_irqs), old_msi_ops.restore_msi_irqs);
+}
+EXPORT_SYMBOL_GPL(hyperv_uninstall_interrupt_translation);
+
 #endif
 
 static uint32_t  __init ms_hyperv_platform(void)
-- 
1.9.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH v3 4/6] drivers:hv: Export a function that maps Linux proc num onto Hyper-V proc num

2015-06-17 Thread jakeo
From: Jake Oshins 

This patch exports a function which maps Linux CPU number onto Hyper-V
virtual processor number.  This is necessary in order to map message-
signaled interrupts (MSIs) into a VM, as the hypervisor needs to know the
right target VP.

Signed-off-by: Jake Oshins 
---
 drivers/hv/vmbus_drv.c | 17 +
 include/linux/hyperv.h |  2 ++
 2 files changed, 19 insertions(+)

diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c
index 9b4fc1a..3a95786 100644
--- a/drivers/hv/vmbus_drv.c
+++ b/drivers/hv/vmbus_drv.c
@@ -1154,6 +1154,23 @@ int vmbus_allocate_mmio(struct resource **new, struct 
hv_device *device_obj,
 }
 EXPORT_SYMBOL_GPL(vmbus_allocate_mmio);
 
+/**
+ * vmbus_cpu_number_to_vp_number() - Map CPU to VP.
+ * @cpu_number: CPU number in Linux terms
+ *
+ * This function returns the mapping between the Linux processor
+ * number and the hypervisor's virtual processor number, useful
+ * in making hypercalls and such that talk about specific
+ * processors.
+ *
+ * Return: Virtual processor number in Hyper-V terms
+ */
+int vmbus_cpu_number_to_vp_number(int cpu_number)
+{
+   return hv_context.vp_index[cpu_number];
+}
+EXPORT_SYMBOL_GPL(vmbus_cpu_number_to_vp_number);
+
 static int vmbus_acpi_add(struct acpi_device *device)
 {
acpi_status result;
diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h
index ffd98d7..2e40f4d 100644
--- a/include/linux/hyperv.h
+++ b/include/linux/hyperv.h
@@ -987,6 +987,8 @@ int vmbus_allocate_mmio(struct resource **new, struct 
hv_device *device_obj,
resource_size_t size, resource_size_t align,
bool fb_overlap_ok);
 
+int vmbus_cpu_number_to_vp_number(int cpu_number);
+
 /**
  * VMBUS_DEVICE - macro used to describe a specific hyperv vmbus device
  *
-- 
1.9.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH v3 6/6] drivers:pci:hv: New paravirtual PCI front-end for Hyper-V VMs

2015-06-17 Thread jakeo
From: Jake Oshins 

This patch supplies a new driver, hv_pcifront, which exposes new root PCI
buses.  When a Hyper-V VM running Linux is offered a paravirtual PCI bus
in order to expose a device passed through on that bus, this drver
registers a new bus with the PCI driver.  This new bus is bus "zero"
within a new PCI domain.  This is done so that there's no overlap between
the emulated, or fully virtualized, PCI that may be in the VM and a real
PCIe device that will be exposed.

This PCI front-end only supports PCIe devices which do not use I/O BARs and
which do not need a legacy INTx# interrupt (relying on MSI or MSI-X).
Multifunction devices are supported, but devices with Type 1 or Type 2
config headers are not supported.  (These are bridges to other PCI buses.)

The content of this patch differs from the one sent previously in that it
incorporates feedback related to unused code (which has been removed) and
GPL license (which has been updated.)  It also removes Kconfig lines that
had been copied from the Xen PCI front-end entry, but which shouldn't be
used here.

Signed-off-by: Jake Oshins 
---
 MAINTAINERS|1 +
 drivers/pci/Kconfig|7 +
 drivers/pci/host/Makefile  |1 +
 drivers/pci/host/hv_pcifront.c | 2101 
 4 files changed, 2110 insertions(+)
 create mode 100644 drivers/pci/host/hv_pcifront.c

diff --git a/MAINTAINERS b/MAINTAINERS
index d8afd29..ed8d991 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -4759,6 +4759,7 @@ F:arch/x86/kernel/cpu/mshyperv.c
 F: drivers/hid/hid-hyperv.c
 F: drivers/hv/
 F: drivers/input/serio/hyperv-keyboard.c
+F: drivers/pci/host/hv_pcifront.c
 F: drivers/net/hyperv/
 F: drivers/scsi/storvsc_drv.c
 F: drivers/video/fbdev/hyperv_fb.c
diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig
index 7a8f1c5..3ee97a9 100644
--- a/drivers/pci/Kconfig
+++ b/drivers/pci/Kconfig
@@ -114,4 +114,11 @@ config PCI_LABEL
def_bool y if (DMI || ACPI)
select NLS
 
+config HYPERV_VPCI
+tristate "Hyper-V PCI Frontend"
+depends on PCI && X86 && HYPERV
+help
+  The PCI device frontend driver allows the kernel to import arbitrary
+  PCI devices from a PCI backend to support PCI driver domains.
+
 source "drivers/pci/host/Kconfig"
diff --git a/drivers/pci/host/Makefile b/drivers/pci/host/Makefile
index f733b4e..7bf8442 100644
--- a/drivers/pci/host/Makefile
+++ b/drivers/pci/host/Makefile
@@ -2,6 +2,7 @@ obj-$(CONFIG_PCIE_DW) += pcie-designware.o
 obj-$(CONFIG_PCI_DRA7XX) += pci-dra7xx.o
 obj-$(CONFIG_PCI_EXYNOS) += pci-exynos.o
 obj-$(CONFIG_PCI_IMX6) += pci-imx6.o
+obj-$(CONFIG_HYPERV_VPCI) += hv_pcifront.o
 obj-$(CONFIG_PCI_MVEBU) += pci-mvebu.o
 obj-$(CONFIG_PCI_TEGRA) += pci-tegra.o
 obj-$(CONFIG_PCI_RCAR_GEN2) += pci-rcar-gen2.o
diff --git a/drivers/pci/host/hv_pcifront.c b/drivers/pci/host/hv_pcifront.c
new file mode 100644
index 000..14c37c2
--- /dev/null
+++ b/drivers/pci/host/hv_pcifront.c
@@ -0,0 +1,2101 @@
+/*
+ * Copyright (c) Microsoft Corporation.
+ *
+ * Author:
+ *   Jake Oshins 
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+ * NON INFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+
+/*
+ * We begin with definitions supporting the Virtual PCI Express protocol
+ * with the host.
+ */
+
+
+/*
+ * Protocol versions. The low word is the minor version, the high word the 
major
+ * version.
+ */
+
+#define PCI_MAKE_VERSION(Major, Minor) ((__u32)(((Major) << 16) | (Minor)))
+#define PCI_MAJOR_VERSION(Version) ((__u32)(Version) >> 16)
+#define PCI_MINOR_VERSION(Version) ((__u32)(Version) & 0xff)
+
+enum {
+   PCI_PROTOCOL_VERSION_1_1 = PCI_MAKE_VERSION(1, 1),
+   PCI_PROTOCOL_VERSION_CURRENT = PCI_PROTOCOL_VERSION_1_1
+};
+
+#define PCI_CONFIG_MMIO_LENGTH 0x2000
+
+/*
+ * Message Types
+ */
+
+enum pci_message_type {
+   /*
+* Version 1.1
+*/
+   PCI_MESSAGE_BASE= 0x4249,
+   PCI_BUS_RELATIONS   = PCI_MESSAGE_BASE + 0,
+   PCI_QUERY_BUS_RELATIONS = PCI_MESSAGE_BASE + 1,
+   PCI_POWER_STATE_CHANGE  = PCI_MESSAGE_BASE + 4,
+   PCI_QUERY_RESOURCE_REQUIREMENTS = PCI_MESSAGE_BASE + 5,
+   PCI_QUERY_RESOURCE_RESOURCES= PCI_MESSAGE_BASE + 6,
+   PCI_BUS_D0ENTRY = PCI_MESSAGE_BASE + 7,
+

[PATCH 1/2] drivers:hv: Modify hv_vmbus to search for all MMIO ranges available.

2015-06-25 Thread jakeo
From: Jake Oshins 

This patch changes the logic in hv_vmbus to record all of the ranges in the
VM's firmware (BIOS or UEFI) that offer regions of memory-mapped I/O space for
use by paravirtual front-end drivers.  The old logic just found one range
above 4GB and called it good.  This logic will find any ranges above 1MB.

Signed-off-by: Jake Oshins 
---
 drivers/hv/vmbus_drv.c  | 116 +++-
 drivers/video/fbdev/hyperv_fb.c |   2 +-
 include/linux/hyperv.h  |   2 +-
 3 files changed, 92 insertions(+), 28 deletions(-)

diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c
index cf20400..398edc9 100644
--- a/drivers/hv/vmbus_drv.c
+++ b/drivers/hv/vmbus_drv.c
@@ -72,10 +72,7 @@ static struct notifier_block hyperv_panic_block = {
.notifier_call = hyperv_panic_event,
 };
 
-struct resource hyperv_mmio = {
-   .name  = "hyperv mmio",
-   .flags = IORESOURCE_MEM,
-};
+struct resource *hyperv_mmio;
 EXPORT_SYMBOL_GPL(hyperv_mmio);
 
 static int vmbus_exists(void)
@@ -982,30 +979,105 @@ void vmbus_device_unregister(struct hv_device 
*device_obj)
 
 
 /*
- * VMBUS is an acpi enumerated device. Get the the information we
+ * VMBUS is an acpi enumerated device. Get the information we
  * need from DSDT.
  */
-
+#define VTPM_BASE_ADDRESS 0xfed4
 static acpi_status vmbus_walk_resources(struct acpi_resource *res, void *ctx)
 {
+   resource_size_t start = 0;
+   resource_size_t end = 0;
+   struct resource *new_res;
+   struct resource **old_res = &hyperv_mmio;
+   struct resource **prev_res = NULL;
+
switch (res->type) {
case ACPI_RESOURCE_TYPE_IRQ:
irq = res->data.irq.interrupts[0];
+   return AE_OK;
+
+   /*
+* "Address" descriptors are for bus windows. Ignore
+* "memory" descriptors, which are for registers on
+* devices.
+*/
+   case ACPI_RESOURCE_TYPE_ADDRESS32:
+   start = res->data.address32.address.minimum;
+   end = res->data.address32.address.maximum;
break;
 
case ACPI_RESOURCE_TYPE_ADDRESS64:
-   hyperv_mmio.start = res->data.address64.address.minimum;
-   hyperv_mmio.end = res->data.address64.address.maximum;
+   start = res->data.address64.address.minimum;
+   end = res->data.address64.address.maximum;
break;
+
+   default:
+   /* Unused resource type */
+   return AE_OK;
+
}
+   /*
+* Ignore ranges that are below 1MB, as they're not
+* necessary or useful here.
+*/
+   if (end < 0x10)
+   return AE_OK;
+
+   new_res = kzalloc(sizeof(*new_res), GFP_ATOMIC);
+   if (!new_res)
+   return AE_NO_MEMORY;
+
+   /* If this range overlaps the virtual TPM, truncate it. */
+   if (end > VTPM_BASE_ADDRESS && start < VTPM_BASE_ADDRESS)
+   end = VTPM_BASE_ADDRESS;
+
+   new_res->name = "hyperv mmio";
+   new_res->flags = IORESOURCE_MEM;
+   new_res->start = start;
+   new_res->end = end;
+
+   do {
+   if (!*old_res) {
+   *old_res = new_res;
+   break;
+   }
+
+   if ((*old_res)->end < new_res->start) {
+   new_res->sibling = *old_res;
+   if (prev_res)
+   (*prev_res)->sibling = new_res;
+   *old_res = new_res;
+   break;
+   }
+
+   prev_res = old_res;
+   old_res = &(*old_res)->sibling;
+
+   } while (1);
 
return AE_OK;
 }
 
+static int vmbus_acpi_remove(struct acpi_device *device)
+{
+   struct resource *cur_res;
+   struct resource *next_res;
+
+   if (hyperv_mmio) {
+   for (cur_res = hyperv_mmio; cur_res; cur_res = next_res) {
+   next_res = cur_res->sibling;
+   kfree(cur_res);
+   }
+   }
+
+   return 0;
+}
+
 static int vmbus_acpi_add(struct acpi_device *device)
 {
acpi_status result;
int ret_val = -ENODEV;
+   struct acpi_device *ancestor;
 
hv_acpi_dev = device;
 
@@ -1015,35 +1087,27 @@ static int vmbus_acpi_add(struct acpi_device *device)
if (ACPI_FAILURE(result))
goto acpi_walk_err;
/*
-* The parent of the vmbus acpi device (Gen2 firmware) is the VMOD that
-* has the mmio ranges. Get that.
+* Some ancestor of the vmbus acpi device (Gen1 or Gen2
+* firmware) is the VMOD that has the mmio ranges. Get that.
 */
-   if (device->parent) {
-   result = acpi_walk_resources(device->parent->handle,
-   METHOD_NAME__CRS,
-   vmbus_walk_resources, NULL);
+   for (ancestor = device->pare

[PATCH 2/2] drivers:hv: Move MMIO range picking from hyper_fb to hv_vmbus

2015-06-25 Thread jakeo
From: Jake Oshins 

This patch deletes the logic from hyperv_fb which picked a range of MMIO space
for the frame buffer and adds new logic to hv_vmbus which picks ranges for
child drivers.  The new logic isn't quite the same as the old, as it considers
more possible ranges.

Signed-off-by: Jake Oshins 
---
 drivers/hv/vmbus_drv.c  | 88 +++--
 drivers/video/fbdev/hyperv_fb.c | 46 ++---
 include/linux/hyperv.h  |  7 +++-
 3 files changed, 110 insertions(+), 31 deletions(-)

diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c
index 398edc9..2064f31 100644
--- a/drivers/hv/vmbus_drv.c
+++ b/drivers/hv/vmbus_drv.c
@@ -39,6 +39,7 @@
 #include 
 #include 
 #include 
+#include 
 #include "hyperv_vmbus.h"
 
 static struct acpi_device  *hv_acpi_dev;
@@ -73,7 +74,6 @@ static struct notifier_block hyperv_panic_block = {
 };
 
 struct resource *hyperv_mmio;
-EXPORT_SYMBOL_GPL(hyperv_mmio);
 
 static int vmbus_exists(void)
 {
@@ -860,8 +860,8 @@ err_cleanup:
 }
 
 /**
- * __vmbus_child_driver_register - Register a vmbus's driver
- * @drv: Pointer to driver structure you want to register
+ * __vmbus_child_driver_register() - Register a vmbus's driver
+ * @hv_driver: Pointer to driver structure you want to register
  * @owner: owner module of the drv
  * @mod_name: module name string
  *
@@ -893,7 +893,8 @@ EXPORT_SYMBOL_GPL(__vmbus_driver_register);
 
 /**
  * vmbus_driver_unregister() - Unregister a vmbus's driver
- * @drv: Pointer to driver structure you want to un-register
+ * @hv_driver: Pointer to driver structure you want to
+ * un-register
  *
  * Un-register the given driver that was previous registered with a call to
  * vmbus_driver_register()
@@ -1073,6 +1074,85 @@ static int vmbus_acpi_remove(struct acpi_device *device)
return 0;
 }
 
+/**
+ * vmbus_allocate_mmio() - Pick a memory-mapped I/O range.
+ * @new:   If successful, supplied a pointer to the
+ * allocated MMIO space.
+ * @device_obj:Identifies the caller
+ * @min:   Minimum guest physical address of the
+ * allocation
+ * @max:   Maximum guest physical address
+ * @size:  Size of the range to be allocated
+ * @align: Alignment of the range to be allocated
+ * @fb_overlap_ok: Whether this allocation can be allowed
+ * to overlap the video frame buffer.
+ *
+ * This function walks the resources granted to VMBus by the
+ * _CRS object in the ACPI namespace underneath the parent
+ * "bridge" whether that's a root PCI bus in the Generation 1
+ * case or a Module Device in the Generation 2 case.  It then
+ * attempts to allocate from the global MMIO pool in a way that
+ * matches the constraints supplied in these parameters and by
+ * that _CRS.
+ *
+ * Return: 0 on success, -errno on failure
+ */
+int vmbus_allocate_mmio(struct resource **new, struct hv_device *device_obj,
+   resource_size_t min, resource_size_t max,
+   resource_size_t size, resource_size_t align,
+   bool fb_overlap_ok)
+{
+   struct resource *iter;
+   resource_size_t range_min, range_max, start, local_min, local_max;
+   const char *dev_n = dev_name(&device_obj->device);
+   u32 fb_end = screen_info.lfb_base + (screen_info.lfb_size << 1);
+   int i;
+
+   for (iter = hyperv_mmio; iter; iter = iter->sibling) {
+   if ((iter->start >= max) || (iter->end <= min))
+   continue;
+
+   range_min = iter->start;
+   range_max = iter->end;
+
+   /* If this range overlaps the frame buffer, split it into
+  two tries. */
+   for (i = 0; i < 2; i++) {
+   local_min = range_min;
+   local_max = range_max;
+   if (fb_overlap_ok || (range_min >= fb_end) ||
+   (range_max <= screen_info.lfb_base)) {
+   i++;
+   } else {
+   if ((range_min <= screen_info.lfb_base) &&
+   (range_max >= screen_info.lfb_base)) {
+   /*
+* The frame buffer is in this window,
+* so trim this into the part that
+* preceeds the frame buffer.
+*/
+   local_max = screen_info.lfb_base - 1;
+   range_min = fb_end;
+   } else {
+   range_min = fb_end;
+   continue;
+   }
+   }
+
+   start = (local_min +

[PATCH 0/2] Change memory-mapped I/O management for Hyper-V paravirt

2015-06-25 Thread jakeo
From: Jake Oshins 

This patch series changes the way that hv_vmbus searches for ranges of 
memory-mapped I/O space (MMIO) which can be used by its children.  The old
way just found the one and only range above 4GB.  This one makes all ranges
exposed in the VM's firmware potential candidates.  It also moves the code
which chooses ranges from hyperv_fb (the video front-end driver for Hyper-V)
to hv_vmbus.

KY Srinivasan asked me to split this off from the previously submitted patch
series which introduced another front-end driver which needs this, because this
part stands on its own and constitutes a useful change in behavior.

Jake Oshins (2):
  drivers:hv: Modify hv_vmbus to search for all MMIO ranges available.
  drivers:hv: Move MMIO range picking from hyper_fb to hv_vmbus

 drivers/hv/vmbus_drv.c  | 204 ++--
 drivers/video/fbdev/hyperv_fb.c |  46 +
 include/linux/hyperv.h  |   7 +-
 3 files changed, 200 insertions(+), 57 deletions(-)

-- 
1.9.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH 2/4] drivers:hv: Define the channel type for Hyper-V PCI Express pass-through

2015-08-01 Thread jakeo
From: Jake Oshins 

This patch defines the channel type for a paravirtual PCI front-end within
a Hyper-V VM.

Signed-off-by: Jake Oshins 
---
 include/linux/hyperv.h | 11 +++
 1 file changed, 11 insertions(+)

diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h
index 02393b6..ab17332 100644
--- a/include/linux/hyperv.h
+++ b/include/linux/hyperv.h
@@ -1139,6 +1139,17 @@ int vmbus_cpu_number_to_vp_number(int cpu_number);
}
 
 /*
+ * PCI Express Pass Through
+ * {44C4F61D--4400-9D52-802E27EDE19F}
+ */
+
+#define HV_PCIE_GUID \
+   .guid = { \
+   0x1D, 0xF6, 0xC4, 0x44, 0x44, 0x44, 0x00, 0x44, \
+   0x9D, 0x52, 0x80, 0x2E, 0x27, 0xED, 0xE1, 0x9F \
+   }
+
+/*
  * Common header for Hyper-V ICs
  */
 
-- 
1.9.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH 4/4] drivers:pci:hv: New paravirtual PCI front-end for Hyper-V VMs

2015-08-01 Thread jakeo
From: Jake Oshins 

This patch introduces a driver which exposes a root PCI bus whenever a PCI
Express device is passed through to a Hyper-V VM.  The device can be single-
or multi-function.  The interrupts for the devices are managed by an IRQ
domain, implemented within this driver.

Signed-off-by: Jake Oshins 
---
 MAINTAINERS|1 +
 drivers/pci/Kconfig|7 +
 drivers/pci/host/Makefile  |1 +
 drivers/pci/host/hv_pcifront.c | 2228 
 4 files changed, 2237 insertions(+)
 create mode 100644 drivers/pci/host/hv_pcifront.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 1b7917d..fa3a818 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -4957,6 +4957,7 @@ F:arch/x86/kernel/cpu/mshyperv.c
 F: drivers/hid/hid-hyperv.c
 F: drivers/hv/
 F: drivers/input/serio/hyperv-keyboard.c
+F: drivers/pci/host/hv_pcifront.c
 F: drivers/net/hyperv/
 F: drivers/scsi/storvsc_drv.c
 F: drivers/video/fbdev/hyperv_fb.c
diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig
index 73de4ef..9b82d93 100644
--- a/drivers/pci/Kconfig
+++ b/drivers/pci/Kconfig
@@ -118,4 +118,11 @@ config PCI_LABEL
def_bool y if (DMI || ACPI)
select NLS
 
+config HYPERV_VPCI
+tristate "Hyper-V PCI Frontend"
+depends on PCI && X86 && HYPERV && PCI_MSI && PCI_MSI_IRQ_DOMAIN
+help
+  The PCI device frontend driver allows the kernel to import arbitrary
+  PCI devices from a PCI backend to support PCI driver domains.
+
 source "drivers/pci/host/Kconfig"
diff --git a/drivers/pci/host/Makefile b/drivers/pci/host/Makefile
index 140d66f..39581fb 100644
--- a/drivers/pci/host/Makefile
+++ b/drivers/pci/host/Makefile
@@ -2,6 +2,7 @@ obj-$(CONFIG_PCIE_DW) += pcie-designware.o
 obj-$(CONFIG_PCI_DRA7XX) += pci-dra7xx.o
 obj-$(CONFIG_PCI_EXYNOS) += pci-exynos.o
 obj-$(CONFIG_PCI_IMX6) += pci-imx6.o
+obj-$(CONFIG_HYPERV_VPCI) += hv_pcifront.o
 obj-$(CONFIG_PCI_MVEBU) += pci-mvebu.o
 obj-$(CONFIG_PCI_TEGRA) += pci-tegra.o
 obj-$(CONFIG_PCI_RCAR_GEN2) += pci-rcar-gen2.o
diff --git a/drivers/pci/host/hv_pcifront.c b/drivers/pci/host/hv_pcifront.c
new file mode 100644
index 000..24c252a
--- /dev/null
+++ b/drivers/pci/host/hv_pcifront.c
@@ -0,0 +1,2228 @@
+/*
+ * Copyright (c) Microsoft Corporation.
+ *
+ * Author:
+ *   Jake Oshins 
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+ * NON INFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+
+/*
+ * Protocol versions. The low word is the minor version, the high word the 
major
+ * version.
+ */
+
+#define PCI_MAKE_VERSION(major, minor) ((__u32)(((major) << 16) | (major)))
+#define PCI_MAJOR_VERSION(version) ((__u32)(version) >> 16)
+#define PCI_MINOR_VERSION(version) ((__u32)(version) & 0xff)
+
+enum {
+   PCI_PROTOCOL_VERSION_1_1 = PCI_MAKE_VERSION(1, 1),
+   PCI_PROTOCOL_VERSION_CURRENT = PCI_PROTOCOL_VERSION_1_1
+};
+
+#define PCI_CONFIG_MMIO_LENGTH 0x2000
+#define MAX_SUPPORTED_MSI_MESSAGES 0x400
+
+/*
+ * Message Types
+ */
+
+enum pci_message_type {
+   /*
+* Version 1.1
+*/
+   PCI_MESSAGE_BASE= 0x4249,
+   PCI_BUS_RELATIONS   = PCI_MESSAGE_BASE + 0,
+   PCI_QUERY_BUS_RELATIONS = PCI_MESSAGE_BASE + 1,
+   PCI_POWER_STATE_CHANGE  = PCI_MESSAGE_BASE + 4,
+   PCI_QUERY_RESOURCE_REQUIREMENTS = PCI_MESSAGE_BASE + 5,
+   PCI_QUERY_RESOURCE_RESOURCES= PCI_MESSAGE_BASE + 6,
+   PCI_BUS_D0ENTRY = PCI_MESSAGE_BASE + 7,
+   PCI_BUS_D0EXIT  = PCI_MESSAGE_BASE + 8,
+   PCI_READ_BLOCK  = PCI_MESSAGE_BASE + 9,
+   PCI_WRITE_BLOCK = PCI_MESSAGE_BASE + 0xA,
+   PCI_EJECT   = PCI_MESSAGE_BASE + 0xB,
+   PCI_QUERY_STOP  = PCI_MESSAGE_BASE + 0xC,
+   PCI_REENABLE= PCI_MESSAGE_BASE + 0xD,
+   PCI_QUERY_STOP_FAILED   = PCI_MESSAGE_BASE + 0xE,
+   PCI_EJECTION_COMPLETE   = PCI_MESSAGE_BASE + 0xF,
+   PCI_RESOURCES_ASSIGNED  = PCI_MESSAGE_BASE + 0x10,
+   PCI_RESOURCES_RELEASED  = PCI_MESSAGE_BASE + 0x11,
+   PCI_INVALIDATE_BLOCK= PCI_MESSAGE_BASE + 0x12,
+   PCI_QUERY_PROTOCOL_VERSION  = PCI_MESSAGE_BASE + 0x13,
+   PC

[PATCH 3/4] drivers:x86:pci: Make it possible to implement a PCI MSI IRQ Domain in a module.

2015-08-01 Thread jakeo
From: Jake Oshins 

The Linux kernel already has the concept of IRQ domain, wherein a component
can expose a set of IRQs which are managed by a particular interrupt controller
chip or other subsystem.  The PCI driver exposes the notion of an IRQ domain
for Message-Signaled Interrupts (MSI) from PCI Express devices.  This patch
exposes the functions which are necessary to do this within a module, rather
than just linked into the kernel itself.

I felt it made more sense to deliver an MSI IRQ domain as a module both so that
the code wouldn't be loaded except when needed and also because the driver
which needs this (which is the next patch in this series) is a module and itself
depends on another module.

Signed-off-by: Jake Oshins 
---
 arch/x86/kernel/apic/vector.c | 2 ++
 drivers/pci/msi.c | 1 +
 kernel/irq/chip.c | 1 +
 3 files changed, 4 insertions(+)

diff --git a/arch/x86/kernel/apic/vector.c b/arch/x86/kernel/apic/vector.c
index f47069e..67f7e68 100644
--- a/arch/x86/kernel/apic/vector.c
+++ b/arch/x86/kernel/apic/vector.c
@@ -29,6 +29,7 @@ struct apic_chip_data {
 };
 
 struct irq_domain *x86_vector_domain;
+EXPORT_SYMBOL_GPL(x86_vector_domain);
 static DEFINE_RAW_SPINLOCK(vector_lock);
 static cpumask_var_t vector_cpumask;
 static struct irq_chip lapic_controller;
@@ -66,6 +67,7 @@ struct irq_cfg *irqd_cfg(struct irq_data *irq_data)
 
return data ? &data->cfg : NULL;
 }
+EXPORT_SYMBOL_GPL(irqd_cfg);
 
 struct irq_cfg *irq_cfg(unsigned int irq)
 {
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
index 566de05..b118be1 100644
--- a/drivers/pci/msi.c
+++ b/drivers/pci/msi.c
@@ -1276,6 +1276,7 @@ struct irq_domain *pci_msi_create_irq_domain(struct 
device_node *node,
 
return msi_create_irq_domain(node, info, parent);
 }
+EXPORT_SYMBOL_GPL(pci_msi_create_irq_domain);
 
 /**
  * pci_msi_domain_alloc_irqs - Allocate interrupts for @dev in @domain
diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c
index 76f199d..3c82c44 100644
--- a/kernel/irq/chip.c
+++ b/kernel/irq/chip.c
@@ -935,6 +935,7 @@ void irq_chip_ack_parent(struct irq_data *data)
data = data->parent_data;
data->chip->irq_ack(data);
 }
+EXPORT_SYMBOL_GPL(irq_chip_ack_parent);
 
 /**
  * irq_chip_mask_parent - Mask the parent interrupt
-- 
1.9.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH 1/4] drivers:hv: Export a function that maps Linux CPU num onto Hyper-V proc num

2015-08-01 Thread jakeo
From: Jake Oshins 

This patch exposes the mapping between Linux CPU number and Hyper-V virtual
processor number.  This is necessary because the hypervisor needs to know which
virtual processors to target when making a mapping in the Interrupt Redirection
Table in the I/O MMU.

Signed-off-by: Jake Oshins 
---
 drivers/hv/vmbus_drv.c | 17 +
 include/linux/hyperv.h |  2 ++
 2 files changed, 19 insertions(+)

diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c
index 2064f31..5b1a019 100644
--- a/drivers/hv/vmbus_drv.c
+++ b/drivers/hv/vmbus_drv.c
@@ -1153,6 +1153,23 @@ int vmbus_allocate_mmio(struct resource **new, struct 
hv_device *device_obj,
 }
 EXPORT_SYMBOL_GPL(vmbus_allocate_mmio);
 
+/**
+ * vmbus_cpu_number_to_vp_number() - Map CPU to VP.
+ * @cpu_number: CPU number in Linux terms
+ *
+ * This function returns the mapping between the Linux processor
+ * number and the hypervisor's virtual processor number, useful
+ * in making hypercalls and such that talk about specific
+ * processors.
+ *
+ * Return: Virtual processor number in Hyper-V terms
+ */
+int vmbus_cpu_number_to_vp_number(int cpu_number)
+{
+   return hv_context.vp_index[cpu_number];
+}
+EXPORT_SYMBOL_GPL(vmbus_cpu_number_to_vp_number);
+
 static int vmbus_acpi_add(struct acpi_device *device)
 {
acpi_status result;
diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h
index 54733d5..02393b6 100644
--- a/include/linux/hyperv.h
+++ b/include/linux/hyperv.h
@@ -982,6 +982,8 @@ int vmbus_allocate_mmio(struct resource **new, struct 
hv_device *device_obj,
resource_size_t size, resource_size_t align,
bool fb_overlap_ok);
 
+int vmbus_cpu_number_to_vp_number(int cpu_number);
+
 /**
  * VMBUS_DEVICE - macro used to describe a specific hyperv vmbus device
  *
-- 
1.9.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH 0/4] New Paravirtual front-end for PCI in a Hyper-V VM

2015-08-01 Thread jakeo
From: Jake Oshins 

This patch series exposes the primitives necessary for an interrupt domain
in a module and then introduces a new driver.  This driver exposes a root
PCI bus when running in a Hyper-V VM for each device which is passed through
to the VM from the physical host.

This patch series differs from an earlier patch series in that the way
interrupts are managed for the devices has been rewritten, this time to use
IRQ domains, which allows the patches to be applied to the linux-next tree.

Jake Oshins (4):
  drivers:hv: Export a function that maps Linux CPU num onto Hyper-V
proc num
  drivers:hv: Define the channel type for Hyper-V PCI Express
pass-through
  drivers:x86:pci: Make it possible to implement a PCI MSI IRQ Domain in
a module.
  drivers:pci:hv: New paravirtual PCI front-end for Hyper-V VMs

 MAINTAINERS|1 +
 arch/x86/kernel/apic/vector.c  |2 +
 drivers/hv/vmbus_drv.c |   17 +
 drivers/pci/Kconfig|7 +
 drivers/pci/host/Makefile  |1 +
 drivers/pci/host/hv_pcifront.c | 2228 
 drivers/pci/msi.c  |1 +
 include/linux/hyperv.h |   13 +
 kernel/irq/chip.c  |1 +
 9 files changed, 2271 insertions(+)
 create mode 100644 drivers/pci/host/hv_pcifront.c

-- 
1.9.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH v3 4/7] PCI: Record an fwnode associated with root PCI buses, optionally

2015-10-26 Thread jakeo
From: Jake Oshins 

This patch allows a PCI front-end implementation to supply an fwnode_handle
associated with a root PCI bus, optionally.  If supplied, the PCI driver
records this.

This patch supports the next patch in the series, which looks up an IRQ domain
through this handle.

Signed-off-by: Jake Oshins 
---
 arch/sparc/kernel/pci.c   | 2 +-
 drivers/acpi/pci_root.c   | 2 +-
 drivers/parisc/lba_pci.c  | 2 +-
 drivers/pci/host/pci-xgene.c  | 2 +-
 drivers/pci/host/pcie-iproc.c | 3 ++-
 drivers/pci/probe.c   | 8 +---
 include/linux/pci.h   | 4 +++-
 7 files changed, 14 insertions(+), 9 deletions(-)

diff --git a/arch/sparc/kernel/pci.c b/arch/sparc/kernel/pci.c
index b91d7f1..3d4e9f9 100644
--- a/arch/sparc/kernel/pci.c
+++ b/arch/sparc/kernel/pci.c
@@ -660,7 +660,7 @@ struct pci_bus *pci_scan_one_pbm(struct pci_pbm_info *pbm,
pbm->busn.flags = IORESOURCE_BUS;
pci_add_resource(&resources, &pbm->busn);
bus = pci_create_root_bus(parent, pbm->pci_first_busno, pbm->pci_ops,
- pbm, &resources);
+ pbm, &resources, NULL);
if (!bus) {
printk(KERN_ERR "Failed to create bus for %s\n",
   node->full_name);
diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
index 850d7bf..eab95bc 100644
--- a/drivers/acpi/pci_root.c
+++ b/drivers/acpi/pci_root.c
@@ -840,7 +840,7 @@ struct pci_bus *acpi_pci_root_create(struct acpi_pci_root 
*root,
pci_acpi_root_add_resources(info);
pci_add_resource(&info->resources, &root->secondary);
bus = pci_create_root_bus(NULL, busnum, ops->pci_ops,
- sysdata, &info->resources);
+ sysdata, &info->resources, NULL);
if (!bus)
goto out_release_info;
 
diff --git a/drivers/parisc/lba_pci.c b/drivers/parisc/lba_pci.c
index a32c1f6..a7b9d5c 100644
--- a/drivers/parisc/lba_pci.c
+++ b/drivers/parisc/lba_pci.c
@@ -1567,7 +1567,7 @@ lba_driver_probe(struct parisc_device *dev)
dev->dev.platform_data = lba_dev;
lba_bus = lba_dev->hba.hba_bus =
pci_create_root_bus(&dev->dev, lba_dev->hba.bus_num.start,
-   cfg_ops, NULL, &resources);
+   cfg_ops, NULL, &resources, NULL);
if (!lba_bus) {
pci_free_resource_list(&resources);
return 0;
diff --git a/drivers/pci/host/pci-xgene.c b/drivers/pci/host/pci-xgene.c
index ae00ce2..95c20c8 100644
--- a/drivers/pci/host/pci-xgene.c
+++ b/drivers/pci/host/pci-xgene.c
@@ -545,7 +545,7 @@ static int xgene_pcie_probe_bridge(struct platform_device 
*pdev)
return ret;
 
bus = pci_create_root_bus(&pdev->dev, 0,
-   &xgene_pcie_ops, port, &res);
+   &xgene_pcie_ops, port, &res, NULL);
if (!bus)
return -ENOMEM;
 
diff --git a/drivers/pci/host/pcie-iproc.c b/drivers/pci/host/pcie-iproc.c
index 9193951..bc999b7 100644
--- a/drivers/pci/host/pcie-iproc.c
+++ b/drivers/pci/host/pcie-iproc.c
@@ -357,7 +357,8 @@ int iproc_pcie_setup(struct iproc_pcie *pcie, struct 
list_head *res)
sysdata = pcie;
 #endif
 
-   bus = pci_create_root_bus(pcie->dev, 0, &iproc_pcie_ops, sysdata, res);
+   bus = pci_create_root_bus(pcie->dev, 0, &iproc_pcie_ops, sysdata, res,
+ NULL);
if (!bus) {
dev_err(pcie->dev, "unable to create PCI root bus\n");
ret = -ENOMEM;
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index f441d1b..c0f2e44 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -2039,7 +2039,8 @@ void __weak pcibios_remove_bus(struct pci_bus *bus)
 }
 
 struct pci_bus *pci_create_root_bus(struct device *parent, int bus,
-   struct pci_ops *ops, void *sysdata, struct list_head *resources)
+   struct pci_ops *ops, void *sysdata, struct list_head *resources,
+   struct fwnode_handle *fwnode)
 {
int error;
struct pci_host_bridge *bridge;
@@ -2069,6 +2070,7 @@ struct pci_bus *pci_create_root_bus(struct device 
*parent, int bus,
if (!bridge)
goto err_out;
 
+   bridge->fwnode = fwnode;
bridge->dev.parent = parent;
bridge->dev.release = pci_release_host_bridge_dev;
dev_set_name(&bridge->dev, "pci%04x:%02x", pci_domain_nr(b), bus);
@@ -2223,7 +2225,7 @@ struct pci_bus *pci_scan_root_bus_msi(struct device 
*parent, int bus,
break;
}
 
-   b = pci_create_root_bus(parent, bus, ops, sysdata, resources);
+   b = pci_create_root_bus(parent, bus, ops, sysdata, resources, NULL);
if (!b)
return NULL;
 
@@ -2261,7 +2263,7 @@ struct pci_bus *pci_scan_bus(int bus, struct pci_ops *ops,
pci_add_resourc

[PATCH v3 5/7] PCI: irqdomain: Look up IRQ domain by fwnode_handle

2015-10-26 Thread jakeo
From: Jake Oshins 

The existing PCI code looks for an IRQ domain associated with a root PCI bus
by looking in the Open Firmware tree.  This patch introduces a second way
to identify the associated IRQ domain, if the lookup in the OF tree fails.
The handle used for the IRQ domain lookup was introduced in the previous patch
in the series.

Signed-off-by: Jake Oshins 
---
 drivers/pci/probe.c | 13 +
 1 file changed, 13 insertions(+)

diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index c0f2e44..62c9ac7 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -664,6 +664,7 @@ static void pci_set_bus_speed(struct pci_bus *bus)
 static struct irq_domain *pci_host_bridge_msi_domain(struct pci_bus *bus)
 {
struct irq_domain *d;
+   struct pci_host_bridge *host_bridge;
 
/*
 * Any firmware interface that can resolve the msi_domain
@@ -671,6 +672,18 @@ static struct irq_domain 
*pci_host_bridge_msi_domain(struct pci_bus *bus)
 */
d = pci_host_bridge_of_msi_domain(bus);
 
+   /*
+* If no IRQ domain was found via the OF tree, try looking it up
+* directly through the fwnode_handle.
+*/
+   if (!d) {
+   host_bridge = to_pci_host_bridge(bus->bridge);
+   if (host_bridge->fwnode) {
+   d = irq_find_matching_fwnode(host_bridge->fwnode,
+DOMAIN_BUS_ANY);
+   }
+   }
+
return d;
 }
 
-- 
1.9.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH v3 2/7] drivers:hv: Export hv_do_hypercall()

2015-10-26 Thread jakeo
From: Jake Oshins 

This patch exposes the function that hv_vmbus.ko uses to make hypercalls. This
is necessary for retargeting an interrupt when it is given a new affinity.

Signed-off-by: Jake Oshins 
---
 drivers/hv/hv.c   | 20 ++--
 drivers/hv/hyperv_vmbus.h |  2 +-
 include/linux/hyperv.h|  1 +
 3 files changed, 12 insertions(+), 11 deletions(-)

diff --git a/drivers/hv/hv.c b/drivers/hv/hv.c
index 6341be8..7a06933 100644
--- a/drivers/hv/hv.c
+++ b/drivers/hv/hv.c
@@ -89,9 +89,9 @@ static int query_hypervisor_info(void)
 }
 
 /*
- * do_hypercall- Invoke the specified hypercall
+ * hv_do_hypercall- Invoke the specified hypercall
  */
-static u64 do_hypercall(u64 control, void *input, void *output)
+u64 hv_do_hypercall(u64 control, void *input, void *output)
 {
u64 input_address = (input) ? virt_to_phys(input) : 0;
u64 output_address = (output) ? virt_to_phys(output) : 0;
@@ -132,6 +132,7 @@ static u64 do_hypercall(u64 control, void *input, void 
*output)
return hv_status_lo | ((u64)hv_status_hi << 32);
 #endif /* !x86_64 */
 }
+EXPORT_SYMBOL_GPL(hv_do_hypercall);
 
 #ifdef CONFIG_X86_64
 static cycle_t read_hv_clock_tsc(struct clocksource *arg)
@@ -315,7 +316,7 @@ int hv_post_message(union hv_connection_id connection_id,
 {
 
struct hv_input_post_message *aligned_msg;
-   u16 status;
+   u64 status;
 
if (payload_size > HV_MESSAGE_PAYLOAD_BYTE_COUNT)
return -EMSGSIZE;
@@ -329,11 +330,10 @@ int hv_post_message(union hv_connection_id connection_id,
aligned_msg->payload_size = payload_size;
memcpy((void *)aligned_msg->payload, payload, payload_size);
 
-   status = do_hypercall(HVCALL_POST_MESSAGE, aligned_msg, NULL)
-   & 0x;
+   status = hv_do_hypercall(HVCALL_POST_MESSAGE, aligned_msg, NULL);
 
put_cpu();
-   return status;
+   return status & 0x;
 }
 
 
@@ -343,13 +343,13 @@ int hv_post_message(union hv_connection_id connection_id,
  *
  * This involves a hypercall.
  */
-u16 hv_signal_event(void *con_id)
+int hv_signal_event(void *con_id)
 {
-   u16 status;
+   u64 status;
 
-   status = (do_hypercall(HVCALL_SIGNAL_EVENT, con_id, NULL) & 0x);
+   status = hv_do_hypercall(HVCALL_SIGNAL_EVENT, con_id, NULL);
 
-   return status;
+   return status & 0x;
 }
 
 static int hv_ce_set_next_event(unsigned long delta,
diff --git a/drivers/hv/hyperv_vmbus.h b/drivers/hv/hyperv_vmbus.h
index 3d70e36..18c66fc 100644
--- a/drivers/hv/hyperv_vmbus.h
+++ b/drivers/hv/hyperv_vmbus.h
@@ -587,7 +587,7 @@ extern int hv_post_message(union hv_connection_id 
connection_id,
 enum hv_message_type message_type,
 void *payload, size_t payload_size);
 
-extern u16 hv_signal_event(void *con_id);
+extern int hv_signal_event(void *con_id);
 
 extern int hv_synic_alloc(void);
 
diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h
index 02393b6..ea0a0e3 100644
--- a/include/linux/hyperv.h
+++ b/include/linux/hyperv.h
@@ -983,6 +983,7 @@ int vmbus_allocate_mmio(struct resource **new, struct 
hv_device *device_obj,
bool fb_overlap_ok);
 
 int vmbus_cpu_number_to_vp_number(int cpu_number);
+u64 hv_do_hypercall(u64 control, void *input, void *output);
 
 /**
  * VMBUS_DEVICE - macro used to describe a specific hyperv vmbus device
-- 
1.9.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH v3 6/7] drivers:hv: Define the channel type for Hyper-V PCI Express pass-through

2015-10-26 Thread jakeo
From: Jake Oshins 

This defines the channel type for PCI front-ends in Hyper-V VMs.

Signed-off-by: Jake Oshins 
---
 include/linux/hyperv.h | 11 +++
 1 file changed, 11 insertions(+)

diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h
index ea0a0e3..5587899 100644
--- a/include/linux/hyperv.h
+++ b/include/linux/hyperv.h
@@ -1140,6 +1140,17 @@ u64 hv_do_hypercall(u64 control, void *input, void 
*output);
}
 
 /*
+ * PCI Express Pass Through
+ * {44C4F61D--4400-9D52-802E27EDE19F}
+ */
+
+#define HV_PCIE_GUID \
+   .guid = { \
+   0x1D, 0xF6, 0xC4, 0x44, 0x44, 0x44, 0x00, 0x44, \
+   0x9D, 0x52, 0x80, 0x2E, 0x27, 0xED, 0xE1, 0x9F \
+   }
+
+/*
  * Common header for Hyper-V ICs
  */
 
-- 
1.9.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH v3 3/7] PCI: Make it possible to implement a PCI MSI IRQ Domain in a module.

2015-10-26 Thread jakeo
From: Jake Oshins 

The Linux kernel already has the concept of IRQ domain, wherein a component
can expose a set of IRQs which are managed by a particular interrupt controller
chip or other subsystem. The PCI driver exposes the notion of an IRQ domain
for Message-Signaled Interrupts (MSI) from PCI Express devices. This patch
exposes the functions which are necessary for making an MSI IRQ domain within
a module.

The same goal could be accomplished by building an MSI IRQ domain for Hyper-V
into the kernel itself, but this would have required pulling in a lot of other
code which currently exists in modules, and it seemed cleaner to avoid that.

Signed-off-by: Jake Oshins 
---
 arch/x86/include/asm/msi.h| 4 
 arch/x86/kernel/apic/msi.c| 5 +++--
 arch/x86/kernel/apic/vector.c | 2 ++
 drivers/pci/msi.c | 4 
 kernel/irq/chip.c | 1 +
 kernel/irq/irqdomain.c| 2 ++
 6 files changed, 16 insertions(+), 2 deletions(-)

diff --git a/arch/x86/include/asm/msi.h b/arch/x86/include/asm/msi.h
index 93724cc..e8b7924 100644
--- a/arch/x86/include/asm/msi.h
+++ b/arch/x86/include/asm/msi.h
@@ -1,7 +1,11 @@
 #ifndef _ASM_X86_MSI_H
 #define _ASM_X86_MSI_H
 #include 
+#include 
 
 typedef struct irq_alloc_info msi_alloc_info_t;
 
+int pci_msi_prepare(struct irq_domain *domain, struct device *dev, int nvec,
+   msi_alloc_info_t *arg);
+
 #endif /* _ASM_X86_MSI_H */
diff --git a/arch/x86/kernel/apic/msi.c b/arch/x86/kernel/apic/msi.c
index 5f1feb6..bdb28fc 100644
--- a/arch/x86/kernel/apic/msi.c
+++ b/arch/x86/kernel/apic/msi.c
@@ -96,8 +96,8 @@ static irq_hw_number_t pci_msi_get_hwirq(struct 
msi_domain_info *info,
return arg->msi_hwirq;
 }
 
-static int pci_msi_prepare(struct irq_domain *domain, struct device *dev,
-  int nvec, msi_alloc_info_t *arg)
+int pci_msi_prepare(struct irq_domain *domain, struct device *dev, int nvec,
+   msi_alloc_info_t *arg)
 {
struct pci_dev *pdev = to_pci_dev(dev);
struct msi_desc *desc = first_pci_msi_entry(pdev);
@@ -113,6 +113,7 @@ static int pci_msi_prepare(struct irq_domain *domain, 
struct device *dev,
 
return 0;
 }
+EXPORT_SYMBOL_GPL(pci_msi_prepare);
 
 static void pci_msi_set_desc(msi_alloc_info_t *arg, struct msi_desc *desc)
 {
diff --git a/arch/x86/kernel/apic/vector.c b/arch/x86/kernel/apic/vector.c
index 836d11b..f3ac5e1 100644
--- a/arch/x86/kernel/apic/vector.c
+++ b/arch/x86/kernel/apic/vector.c
@@ -29,6 +29,7 @@ struct apic_chip_data {
 };
 
 struct irq_domain *x86_vector_domain;
+EXPORT_SYMBOL_GPL(x86_vector_domain);
 static DEFINE_RAW_SPINLOCK(vector_lock);
 static cpumask_var_t vector_cpumask;
 static struct irq_chip lapic_controller;
@@ -66,6 +67,7 @@ struct irq_cfg *irqd_cfg(struct irq_data *irq_data)
 
return data ? &data->cfg : NULL;
 }
+EXPORT_SYMBOL_GPL(irqd_cfg);
 
 struct irq_cfg *irq_cfg(unsigned int irq)
 {
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
index 53e4632..3915a99 100644
--- a/drivers/pci/msi.c
+++ b/drivers/pci/msi.c
@@ -257,6 +257,7 @@ void pci_msi_mask_irq(struct irq_data *data)
 {
msi_set_mask_bit(data, 1);
 }
+EXPORT_SYMBOL_GPL(pci_msi_mask_irq);
 
 /**
  * pci_msi_unmask_irq - Generic irq chip callback to unmask PCI/MSI interrupts
@@ -266,6 +267,7 @@ void pci_msi_unmask_irq(struct irq_data *data)
 {
msi_set_mask_bit(data, 0);
 }
+EXPORT_SYMBOL_GPL(pci_msi_unmask_irq);
 
 void default_restore_msi_irqs(struct pci_dev *dev)
 {
@@ -1126,6 +1128,7 @@ struct pci_dev *msi_desc_to_pci_dev(struct msi_desc *desc)
 {
return to_pci_dev(desc->dev);
 }
+EXPORT_SYMBOL(msi_desc_to_pci_dev);
 
 void *msi_desc_to_pci_sysdata(struct msi_desc *desc)
 {
@@ -1285,6 +1288,7 @@ struct irq_domain *pci_msi_create_irq_domain(struct 
fwnode_handle *fwnode,
domain->bus_token = DOMAIN_BUS_PCI_MSI;
return domain;
 }
+EXPORT_SYMBOL_GPL(pci_msi_create_irq_domain);
 
 /**
  * pci_msi_domain_alloc_irqs - Allocate interrupts for @dev in @domain
diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c
index 1520645..2414775 100644
--- a/kernel/irq/chip.c
+++ b/kernel/irq/chip.c
@@ -950,6 +950,7 @@ void irq_chip_ack_parent(struct irq_data *data)
data = data->parent_data;
data->chip->irq_ack(data);
 }
+EXPORT_SYMBOL_GPL(irq_chip_ack_parent);
 
 /**
  * irq_chip_mask_parent - Mask the parent interrupt
diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
index 22aa961..174d7e0 100644
--- a/kernel/irq/irqdomain.c
+++ b/kernel/irq/irqdomain.c
@@ -60,6 +60,7 @@ struct fwnode_handle *irq_domain_alloc_fwnode(void *data)
fwid->fwnode.type = FWNODE_IRQCHIP;
return &fwid->fwnode;
 }
+EXPORT_SYMBOL_GPL(irq_domain_alloc_fwnode);
 
 /**
  * irq_domain_free_fwnode - Free a non-OF-backed fwnode_handle
@@ -77,6 +78,7 @@ void irq_domain_free_fwnode(struct fwnode_handle *fwnode)
kfree(fwid->name);
kfree(fwid);
 }
+EXPORT_SYMBOL_GPL(irq_domain_free_fwnode);
 
 /**
  * __irq_

[PATCH v3 0/7] New paravirtual PCI front-end for Hyper-V VMs

2015-10-26 Thread jakeo
From: Jake Oshins 

This patch series updates the one sent on Sept. 10, mostly by rebasing on
Mark Zyngier's changes around IRQ domains and the OF tree.

First, export functions that allow correlating Hyper-V virtual processors
and Linux cpus, along with the means for invoking a hypercall that targets
interrupts at chosen vectors on specfic cpus.

Second, mark various parts of IRQ domain related code as exported, so that
this PCI front-end can implement an IRQ domain as part of a module.  (The
alternative would be to pull all this into the kernel, which would pull
in a lot of other Hyper-V related code, as this IRQ domain depends on
hv_vmbus.ko.)

Third, modify PCI so that new root PCI buses can be marked with an associated
fwnode_handle, and so that root PCI buses can look up their associated IRQ
domain by that handle.

Fourth, introduce a new driver, hv_pcifront, which eposes root PCI buses in
a Hyper-V VM.  These root PCI buses expose real PCIe devices, or PCI Virtual
Functions.



Jake Oshins (7):
  drivers:hv: Export a function that maps Linux CPU num onto Hyper-V
proc num
  drivers:hv: Export hv_do_hypercall()
  PCI: Make it possible to implement a PCI MSI IRQ Domain in a module.
  PCI: Record an fwnode associated with root PCI buses, optionally
  PCI: irqdomain: Look up IRQ domain by fwnode_handle
  drivers:hv: Define the channel type for Hyper-V PCI Express
pass-through
  PCI: hv: New paravirtual PCI front-end for Hyper-V VMs

 MAINTAINERS|1 +
 arch/sparc/kernel/pci.c|2 +-
 arch/x86/include/asm/msi.h |4 +
 arch/x86/kernel/apic/msi.c |5 +-
 arch/x86/kernel/apic/vector.c  |2 +
 drivers/acpi/pci_root.c|2 +-
 drivers/hv/hv.c|   20 +-
 drivers/hv/hyperv_vmbus.h  |2 +-
 drivers/hv/vmbus_drv.c |   17 +
 drivers/parisc/lba_pci.c   |2 +-
 drivers/pci/Kconfig|7 +
 drivers/pci/host/Makefile  |1 +
 drivers/pci/host/hv_pcifront.c | 2262 
 drivers/pci/host/pci-xgene.c   |2 +-
 drivers/pci/host/pcie-iproc.c  |3 +-
 drivers/pci/msi.c  |4 +
 drivers/pci/probe.c|   21 +-
 include/linux/hyperv.h |   14 +
 include/linux/pci.h|4 +-
 kernel/irq/chip.c  |1 +
 kernel/irq/irqdomain.c |2 +
 21 files changed, 2356 insertions(+), 22 deletions(-)
 create mode 100644 drivers/pci/host/hv_pcifront.c

-- 
1.9.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH v3 1/7] drivers:hv: Export a function that maps Linux CPU num onto Hyper-V proc num

2015-10-26 Thread jakeo
From: Jake Oshins 

This patch exposes the mapping between Linux CPU number and Hyper-V virtual
processor number. This is necessary because the hypervisor needs to know which
virtual processors to target when making a mapping in the Interrupt Redirection
Table in the I/O MMU.

Signed-off-by: Jake Oshins 
---
 drivers/hv/vmbus_drv.c | 17 +
 include/linux/hyperv.h |  2 ++
 2 files changed, 19 insertions(+)

diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c
index f19b6f7..c89d0e5 100644
--- a/drivers/hv/vmbus_drv.c
+++ b/drivers/hv/vmbus_drv.c
@@ -1191,6 +1191,23 @@ int vmbus_allocate_mmio(struct resource **new, struct 
hv_device *device_obj,
 }
 EXPORT_SYMBOL_GPL(vmbus_allocate_mmio);
 
+/**
+ * vmbus_cpu_number_to_vp_number() - Map CPU to VP.
+ * @cpu_number: CPU number in Linux terms
+ *
+ * This function returns the mapping between the Linux processor
+ * number and the hypervisor's virtual processor number, useful
+ * in making hypercalls and such that talk about specific
+ * processors.
+ *
+ * Return: Virtual processor number in Hyper-V terms
+ */
+int vmbus_cpu_number_to_vp_number(int cpu_number)
+{
+   return hv_context.vp_index[cpu_number];
+}
+EXPORT_SYMBOL_GPL(vmbus_cpu_number_to_vp_number);
+
 static int vmbus_acpi_add(struct acpi_device *device)
 {
acpi_status result;
diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h
index 54733d5..02393b6 100644
--- a/include/linux/hyperv.h
+++ b/include/linux/hyperv.h
@@ -982,6 +982,8 @@ int vmbus_allocate_mmio(struct resource **new, struct 
hv_device *device_obj,
resource_size_t size, resource_size_t align,
bool fb_overlap_ok);
 
+int vmbus_cpu_number_to_vp_number(int cpu_number);
+
 /**
  * VMBUS_DEVICE - macro used to describe a specific hyperv vmbus device
  *
-- 
1.9.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH v3 7/7] PCI: hv: New paravirtual PCI front-end for Hyper-V VMs

2015-10-26 Thread jakeo
From: Jake Oshins 

This patch introduces a new driver which exposes a root PCI bus whenever a PCI
Express device is passed through to a guest VM under Hyper-V. The device can
be single- or multi-function. The interrupts for the devices are managed by an
IRQ domain, implemented within the driver.

Signed-off-by: Jake Oshins 
---
 MAINTAINERS|1 +
 drivers/pci/Kconfig|7 +
 drivers/pci/host/Makefile  |1 +
 drivers/pci/host/hv_pcifront.c | 2262 
 4 files changed, 2271 insertions(+)
 create mode 100644 drivers/pci/host/hv_pcifront.c

diff --git a/MAINTAINERS b/MAINTAINERS
index a2d50fe..a1205b4 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -5073,6 +5073,7 @@ F:arch/x86/kernel/cpu/mshyperv.c
 F: drivers/hid/hid-hyperv.c
 F: drivers/hv/
 F: drivers/input/serio/hyperv-keyboard.c
+F: drivers/pci/host/hv_pcifront.c
 F: drivers/net/hyperv/
 F: drivers/scsi/storvsc_drv.c
 F: drivers/video/fbdev/hyperv_fb.c
diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig
index 73de4ef..9b82d93 100644
--- a/drivers/pci/Kconfig
+++ b/drivers/pci/Kconfig
@@ -118,4 +118,11 @@ config PCI_LABEL
def_bool y if (DMI || ACPI)
select NLS
 
+config HYPERV_VPCI
+tristate "Hyper-V PCI Frontend"
+depends on PCI && X86 && HYPERV && PCI_MSI && PCI_MSI_IRQ_DOMAIN
+help
+  The PCI device frontend driver allows the kernel to import arbitrary
+  PCI devices from a PCI backend to support PCI driver domains.
+
 source "drivers/pci/host/Kconfig"
diff --git a/drivers/pci/host/Makefile b/drivers/pci/host/Makefile
index 140d66f..39581fb 100644
--- a/drivers/pci/host/Makefile
+++ b/drivers/pci/host/Makefile
@@ -2,6 +2,7 @@ obj-$(CONFIG_PCIE_DW) += pcie-designware.o
 obj-$(CONFIG_PCI_DRA7XX) += pci-dra7xx.o
 obj-$(CONFIG_PCI_EXYNOS) += pci-exynos.o
 obj-$(CONFIG_PCI_IMX6) += pci-imx6.o
+obj-$(CONFIG_HYPERV_VPCI) += hv_pcifront.o
 obj-$(CONFIG_PCI_MVEBU) += pci-mvebu.o
 obj-$(CONFIG_PCI_TEGRA) += pci-tegra.o
 obj-$(CONFIG_PCI_RCAR_GEN2) += pci-rcar-gen2.o
diff --git a/drivers/pci/host/hv_pcifront.c b/drivers/pci/host/hv_pcifront.c
new file mode 100644
index 000..2a09f16
--- /dev/null
+++ b/drivers/pci/host/hv_pcifront.c
@@ -0,0 +1,2262 @@
+/*
+ * Copyright (c) Microsoft Corporation.
+ *
+ * Author:
+ *   Jake Oshins 
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+ * NON INFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+/*
+ * Protocol versions. The low word is the minor version, the high word the 
major
+ * version.
+ */
+
+#define PCI_MAKE_VERSION(major, minor) ((__u32)(((major) << 16) | (major)))
+#define PCI_MAJOR_VERSION(version) ((__u32)(version) >> 16)
+#define PCI_MINOR_VERSION(version) ((__u32)(version) & 0xff)
+
+enum {
+   PCI_PROTOCOL_VERSION_1_1 = PCI_MAKE_VERSION(1, 1),
+   PCI_PROTOCOL_VERSION_CURRENT = PCI_PROTOCOL_VERSION_1_1
+};
+
+#define PCI_CONFIG_MMIO_LENGTH 0x2000
+#define MAX_SUPPORTED_MSI_MESSAGES 0x400
+
+/*
+ * Message Types
+ */
+
+enum pci_message_type {
+   /*
+* Version 1.1
+*/
+   PCI_MESSAGE_BASE= 0x4249,
+   PCI_BUS_RELATIONS   = PCI_MESSAGE_BASE + 0,
+   PCI_QUERY_BUS_RELATIONS = PCI_MESSAGE_BASE + 1,
+   PCI_POWER_STATE_CHANGE  = PCI_MESSAGE_BASE + 4,
+   PCI_QUERY_RESOURCE_REQUIREMENTS = PCI_MESSAGE_BASE + 5,
+   PCI_QUERY_RESOURCE_RESOURCES= PCI_MESSAGE_BASE + 6,
+   PCI_BUS_D0ENTRY = PCI_MESSAGE_BASE + 7,
+   PCI_BUS_D0EXIT  = PCI_MESSAGE_BASE + 8,
+   PCI_READ_BLOCK  = PCI_MESSAGE_BASE + 9,
+   PCI_WRITE_BLOCK = PCI_MESSAGE_BASE + 0xA,
+   PCI_EJECT   = PCI_MESSAGE_BASE + 0xB,
+   PCI_QUERY_STOP  = PCI_MESSAGE_BASE + 0xC,
+   PCI_REENABLE= PCI_MESSAGE_BASE + 0xD,
+   PCI_QUERY_STOP_FAILED   = PCI_MESSAGE_BASE + 0xE,
+   PCI_EJECTION_COMPLETE   = PCI_MESSAGE_BASE + 0xF,
+   PCI_RESOURCES_ASSIGNED  = PCI_MESSAGE_BASE + 0x10,
+   PCI_RESOURCES_RELEASED  = PCI_MESSAGE_BASE + 0x11,
+   PCI_INVALIDATE_BLOCK= PCI_MESSAGE_BASE + 0x12,
+   PCI_QUERY_PROTOCOL_VERSION  = PCI_MESSAGE_BASE + 0x13,
+   PCI_CREATE_INTERRUPT_MESSAGE= PCI_MESSAGE_BASE + 0x14,
+   PCI_DELETE_INTERRUPT_MESSAGE= 

[PATCH v4 1/7] drivers:hv: Export a function that maps Linux CPU num onto Hyper-V proc num

2015-10-29 Thread jakeo
From: Jake Oshins 

This patch exposes the mapping between Linux CPU number and Hyper-V virtual
processor number. This is necessary because the hypervisor needs to know which
virtual processor to target when making a mapping in the Interrupt Redirection
Table in the I/O MMU.

Signed-off-by: Jake Oshins 
---
 drivers/hv/vmbus_drv.c | 17 +
 include/linux/hyperv.h |  2 ++
 2 files changed, 19 insertions(+)

diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c
index f19b6f7..c89d0e5 100644
--- a/drivers/hv/vmbus_drv.c
+++ b/drivers/hv/vmbus_drv.c
@@ -1191,6 +1191,23 @@ int vmbus_allocate_mmio(struct resource **new, struct 
hv_device *device_obj,
 }
 EXPORT_SYMBOL_GPL(vmbus_allocate_mmio);
 
+/**
+ * vmbus_cpu_number_to_vp_number() - Map CPU to VP.
+ * @cpu_number: CPU number in Linux terms
+ *
+ * This function returns the mapping between the Linux processor
+ * number and the hypervisor's virtual processor number, useful
+ * in making hypercalls and such that talk about specific
+ * processors.
+ *
+ * Return: Virtual processor number in Hyper-V terms
+ */
+int vmbus_cpu_number_to_vp_number(int cpu_number)
+{
+   return hv_context.vp_index[cpu_number];
+}
+EXPORT_SYMBOL_GPL(vmbus_cpu_number_to_vp_number);
+
 static int vmbus_acpi_add(struct acpi_device *device)
 {
acpi_status result;
diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h
index 54733d5..02393b6 100644
--- a/include/linux/hyperv.h
+++ b/include/linux/hyperv.h
@@ -982,6 +982,8 @@ int vmbus_allocate_mmio(struct resource **new, struct 
hv_device *device_obj,
resource_size_t size, resource_size_t align,
bool fb_overlap_ok);
 
+int vmbus_cpu_number_to_vp_number(int cpu_number);
+
 /**
  * VMBUS_DEVICE - macro used to describe a specific hyperv vmbus device
  *
-- 
1.9.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH v4 4/7] PCI: Add fwnode_handle to pci_sysdata

2015-10-29 Thread jakeo
From: Jake Oshins 

This patch adds an fwnode_handle to struct pci_sysdata, which is
used by the next patch in the series when trying to locate an
IRQ domain associated with a root PCI bus.

Signed-off-by: Jake Oshins 
---
 arch/x86/include/asm/pci.h | 11 +++
 1 file changed, 11 insertions(+)

diff --git a/arch/x86/include/asm/pci.h b/arch/x86/include/asm/pci.h
index 4625943..10213a1 100644
--- a/arch/x86/include/asm/pci.h
+++ b/arch/x86/include/asm/pci.h
@@ -20,6 +20,9 @@ struct pci_sysdata {
 #ifdef CONFIG_X86_64
void*iommu; /* IOMMU private data */
 #endif
+#ifdef CONFIG_PCI_MSI_IRQ_DOMAIN
+   void*fwnode;/* IRQ domain for MSI assignment */
+#endif
 };
 
 extern int pci_routeirq;
@@ -41,6 +44,14 @@ static inline int pci_proc_domain(struct pci_bus *bus)
 }
 #endif
 
+#ifdef CONFIG_PCI_MSI_IRQ_DOMAIN
+static inline void *pci_fwnode(struct pci_bus *bus)
+{
+   struct pci_sysdata *sd = bus->sysdata;
+   return sd->fwnode;
+}
+#endif
+
 /* Can be used to override the logic in pci_scan_bus for skipping
already-configured bus numbers - to be used for buggy BIOSes
or architectures with incomplete PCI setup by the loader */
-- 
1.9.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH v4 0/7] PCI: hv: New paravirtual PCI front-end for Hyper-V VMs

2015-10-29 Thread jakeo
From: Jake Oshins 

This patch series incorporates feedback from Gerry Liu
(jiang@linux.intel.com).

First, export functions that allow correlating Hyper-V virtual processors
and Linux cpus, along with the means for invoking a hypercall that targets
interrupts at chosen vectors on specfic cpus.

Second, mark various parts of IRQ domain related code as exported, so that
this PCI front-end can implement an IRQ domain as part of a module.  (The
alternative would be to pull all this into the kernel, which would pull
in a lot of other Hyper-V related code, as this IRQ domain depends on
hv_vmbus.ko.)

Third, modify PCI so that new root PCI buses can be marked with an associated
fwnode_handle, and so that root PCI buses can look up their associated IRQ
domain by that handle.

Fourth, introduce a new driver, hv_pcifront, which eposes root PCI buses in
a Hyper-V VM.  These root PCI buses expose real PCIe devices, or PCI Virtual
Functions.


Jake Oshins (7):
  drivers:hv: Export a function that maps Linux CPU num onto Hyper-V
proc num
  drivers:hv: Export hv_do_hypercall()
  PCI: Make it possible to implement a PCI MSI IRQ Domain in a module.
  PCI: Add fwnode_handle to pci_sysdata
  PCI: irqdomain: Look up IRQ domain by fwnode_handle
  drivers:hv: Define the channel type for Hyper-V PCI Express
pass-through
  PCI: hv: New paravirtual PCI front-end for Hyper-V VMs

 MAINTAINERS|1 +
 arch/x86/include/asm/msi.h |4 +
 arch/x86/include/asm/pci.h |   11 +
 arch/x86/kernel/apic/msi.c |5 +-
 arch/x86/kernel/apic/vector.c  |2 +
 drivers/hv/hv.c|   20 +-
 drivers/hv/hyperv_vmbus.h  |2 +-
 drivers/hv/vmbus_drv.c |   17 +
 drivers/pci/Kconfig|7 +
 drivers/pci/host/Makefile  |1 +
 drivers/pci/host/hv_pcifront.c | 2267 
 drivers/pci/msi.c  |4 +
 drivers/pci/probe.c|   13 +
 include/linux/hyperv.h |   14 +
 kernel/irq/chip.c  |1 +
 kernel/irq/irqdomain.c |2 +
 16 files changed, 2358 insertions(+), 13 deletions(-)
 create mode 100644 drivers/pci/host/hv_pcifront.c

-- 
1.9.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH v4 2/7] drivers:hv: Export hv_do_hypercall()

2015-10-29 Thread jakeo
From: Jake Oshins 

This patch exposes the function that hv_vmbus.ko uses to make hypercalls. This
is necessary for retargeting an interrupt when it is given a new affinity and
vector.

Signed-off-by: Jake Oshins 
---
 drivers/hv/hv.c   | 20 ++--
 drivers/hv/hyperv_vmbus.h |  2 +-
 include/linux/hyperv.h|  1 +
 3 files changed, 12 insertions(+), 11 deletions(-)

diff --git a/drivers/hv/hv.c b/drivers/hv/hv.c
index 6341be8..7a06933 100644
--- a/drivers/hv/hv.c
+++ b/drivers/hv/hv.c
@@ -89,9 +89,9 @@ static int query_hypervisor_info(void)
 }
 
 /*
- * do_hypercall- Invoke the specified hypercall
+ * hv_do_hypercall- Invoke the specified hypercall
  */
-static u64 do_hypercall(u64 control, void *input, void *output)
+u64 hv_do_hypercall(u64 control, void *input, void *output)
 {
u64 input_address = (input) ? virt_to_phys(input) : 0;
u64 output_address = (output) ? virt_to_phys(output) : 0;
@@ -132,6 +132,7 @@ static u64 do_hypercall(u64 control, void *input, void 
*output)
return hv_status_lo | ((u64)hv_status_hi << 32);
 #endif /* !x86_64 */
 }
+EXPORT_SYMBOL_GPL(hv_do_hypercall);
 
 #ifdef CONFIG_X86_64
 static cycle_t read_hv_clock_tsc(struct clocksource *arg)
@@ -315,7 +316,7 @@ int hv_post_message(union hv_connection_id connection_id,
 {
 
struct hv_input_post_message *aligned_msg;
-   u16 status;
+   u64 status;
 
if (payload_size > HV_MESSAGE_PAYLOAD_BYTE_COUNT)
return -EMSGSIZE;
@@ -329,11 +330,10 @@ int hv_post_message(union hv_connection_id connection_id,
aligned_msg->payload_size = payload_size;
memcpy((void *)aligned_msg->payload, payload, payload_size);
 
-   status = do_hypercall(HVCALL_POST_MESSAGE, aligned_msg, NULL)
-   & 0x;
+   status = hv_do_hypercall(HVCALL_POST_MESSAGE, aligned_msg, NULL);
 
put_cpu();
-   return status;
+   return status & 0x;
 }
 
 
@@ -343,13 +343,13 @@ int hv_post_message(union hv_connection_id connection_id,
  *
  * This involves a hypercall.
  */
-u16 hv_signal_event(void *con_id)
+int hv_signal_event(void *con_id)
 {
-   u16 status;
+   u64 status;
 
-   status = (do_hypercall(HVCALL_SIGNAL_EVENT, con_id, NULL) & 0x);
+   status = hv_do_hypercall(HVCALL_SIGNAL_EVENT, con_id, NULL);
 
-   return status;
+   return status & 0x;
 }
 
 static int hv_ce_set_next_event(unsigned long delta,
diff --git a/drivers/hv/hyperv_vmbus.h b/drivers/hv/hyperv_vmbus.h
index 3d70e36..18c66fc 100644
--- a/drivers/hv/hyperv_vmbus.h
+++ b/drivers/hv/hyperv_vmbus.h
@@ -587,7 +587,7 @@ extern int hv_post_message(union hv_connection_id 
connection_id,
 enum hv_message_type message_type,
 void *payload, size_t payload_size);
 
-extern u16 hv_signal_event(void *con_id);
+extern int hv_signal_event(void *con_id);
 
 extern int hv_synic_alloc(void);
 
diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h
index 02393b6..ea0a0e3 100644
--- a/include/linux/hyperv.h
+++ b/include/linux/hyperv.h
@@ -983,6 +983,7 @@ int vmbus_allocate_mmio(struct resource **new, struct 
hv_device *device_obj,
bool fb_overlap_ok);
 
 int vmbus_cpu_number_to_vp_number(int cpu_number);
+u64 hv_do_hypercall(u64 control, void *input, void *output);
 
 /**
  * VMBUS_DEVICE - macro used to describe a specific hyperv vmbus device
-- 
1.9.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH v4 5/7] PCI: irqdomain: Look up IRQ domain by fwnode_handle

2015-10-29 Thread jakeo
From: Jake Oshins 

This patch adds a second way of finding an IRQ domain associated with
a root PCI bus.  After looking to see if one can be found through
the OF tree, it attempts to look up the IRQ domain through an
fwnode_handle stored in the pci_sysdata struct.

Signed-off-by: Jake Oshins 
---
 drivers/pci/probe.c | 13 +
 1 file changed, 13 insertions(+)

diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index f441d1b..3d5d7d6 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -671,6 +671,19 @@ static struct irq_domain 
*pci_host_bridge_msi_domain(struct pci_bus *bus)
 */
d = pci_host_bridge_of_msi_domain(bus);
 
+#ifdef CONFIG_PCI_MSI_IRQ_DOMAIN
+   /*
+* If no IRQ domain was found via the OF tree, try looking it up
+* directly through the fwnode_handle.
+*/
+   if (!d) {
+   if (pci_fwnode(bus)) {
+   d = irq_find_matching_fwnode(pci_fwnode(bus),
+DOMAIN_BUS_PCI_MSI);
+   }
+   }
+#endif
+
return d;
 }
 
-- 
1.9.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH v4 3/7] PCI: Make it possible to implement a PCI MSI IRQ Domain in a module.

2015-10-29 Thread jakeo
From: Jake Oshins 

The Linux kernel already has the concpet of IRQ domain, whereing a component
can expose a set of IRQs which are managed by a particular interrupt controller
chip or other subsystem. The PCI driver exposes the notion of an IRQ domain
for Message-Signaled Interrupts (MSI) from PCI Express devices. This patch
exposes the functions which are necessary for making an MSI IRQ domain within
a module.

Signed-off-by: Jake Oshins 
---
 arch/x86/include/asm/msi.h| 4 
 arch/x86/kernel/apic/msi.c| 5 +++--
 arch/x86/kernel/apic/vector.c | 2 ++
 drivers/pci/msi.c | 4 
 kernel/irq/chip.c | 1 +
 kernel/irq/irqdomain.c| 2 ++
 6 files changed, 16 insertions(+), 2 deletions(-)

diff --git a/arch/x86/include/asm/msi.h b/arch/x86/include/asm/msi.h
index 93724cc..e8b7924 100644
--- a/arch/x86/include/asm/msi.h
+++ b/arch/x86/include/asm/msi.h
@@ -1,7 +1,11 @@
 #ifndef _ASM_X86_MSI_H
 #define _ASM_X86_MSI_H
 #include 
+#include 
 
 typedef struct irq_alloc_info msi_alloc_info_t;
 
+int pci_msi_prepare(struct irq_domain *domain, struct device *dev, int nvec,
+   msi_alloc_info_t *arg);
+
 #endif /* _ASM_X86_MSI_H */
diff --git a/arch/x86/kernel/apic/msi.c b/arch/x86/kernel/apic/msi.c
index 5f1feb6..bdb28fc 100644
--- a/arch/x86/kernel/apic/msi.c
+++ b/arch/x86/kernel/apic/msi.c
@@ -96,8 +96,8 @@ static irq_hw_number_t pci_msi_get_hwirq(struct 
msi_domain_info *info,
return arg->msi_hwirq;
 }
 
-static int pci_msi_prepare(struct irq_domain *domain, struct device *dev,
-  int nvec, msi_alloc_info_t *arg)
+int pci_msi_prepare(struct irq_domain *domain, struct device *dev, int nvec,
+   msi_alloc_info_t *arg)
 {
struct pci_dev *pdev = to_pci_dev(dev);
struct msi_desc *desc = first_pci_msi_entry(pdev);
@@ -113,6 +113,7 @@ static int pci_msi_prepare(struct irq_domain *domain, 
struct device *dev,
 
return 0;
 }
+EXPORT_SYMBOL_GPL(pci_msi_prepare);
 
 static void pci_msi_set_desc(msi_alloc_info_t *arg, struct msi_desc *desc)
 {
diff --git a/arch/x86/kernel/apic/vector.c b/arch/x86/kernel/apic/vector.c
index 836d11b..f3ac5e1 100644
--- a/arch/x86/kernel/apic/vector.c
+++ b/arch/x86/kernel/apic/vector.c
@@ -29,6 +29,7 @@ struct apic_chip_data {
 };
 
 struct irq_domain *x86_vector_domain;
+EXPORT_SYMBOL_GPL(x86_vector_domain);
 static DEFINE_RAW_SPINLOCK(vector_lock);
 static cpumask_var_t vector_cpumask;
 static struct irq_chip lapic_controller;
@@ -66,6 +67,7 @@ struct irq_cfg *irqd_cfg(struct irq_data *irq_data)
 
return data ? &data->cfg : NULL;
 }
+EXPORT_SYMBOL_GPL(irqd_cfg);
 
 struct irq_cfg *irq_cfg(unsigned int irq)
 {
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
index 53e4632..3915a99 100644
--- a/drivers/pci/msi.c
+++ b/drivers/pci/msi.c
@@ -257,6 +257,7 @@ void pci_msi_mask_irq(struct irq_data *data)
 {
msi_set_mask_bit(data, 1);
 }
+EXPORT_SYMBOL_GPL(pci_msi_mask_irq);
 
 /**
  * pci_msi_unmask_irq - Generic irq chip callback to unmask PCI/MSI interrupts
@@ -266,6 +267,7 @@ void pci_msi_unmask_irq(struct irq_data *data)
 {
msi_set_mask_bit(data, 0);
 }
+EXPORT_SYMBOL_GPL(pci_msi_unmask_irq);
 
 void default_restore_msi_irqs(struct pci_dev *dev)
 {
@@ -1126,6 +1128,7 @@ struct pci_dev *msi_desc_to_pci_dev(struct msi_desc *desc)
 {
return to_pci_dev(desc->dev);
 }
+EXPORT_SYMBOL(msi_desc_to_pci_dev);
 
 void *msi_desc_to_pci_sysdata(struct msi_desc *desc)
 {
@@ -1285,6 +1288,7 @@ struct irq_domain *pci_msi_create_irq_domain(struct 
fwnode_handle *fwnode,
domain->bus_token = DOMAIN_BUS_PCI_MSI;
return domain;
 }
+EXPORT_SYMBOL_GPL(pci_msi_create_irq_domain);
 
 /**
  * pci_msi_domain_alloc_irqs - Allocate interrupts for @dev in @domain
diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c
index 1520645..2414775 100644
--- a/kernel/irq/chip.c
+++ b/kernel/irq/chip.c
@@ -950,6 +950,7 @@ void irq_chip_ack_parent(struct irq_data *data)
data = data->parent_data;
data->chip->irq_ack(data);
 }
+EXPORT_SYMBOL_GPL(irq_chip_ack_parent);
 
 /**
  * irq_chip_mask_parent - Mask the parent interrupt
diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
index 22aa961..174d7e0 100644
--- a/kernel/irq/irqdomain.c
+++ b/kernel/irq/irqdomain.c
@@ -60,6 +60,7 @@ struct fwnode_handle *irq_domain_alloc_fwnode(void *data)
fwid->fwnode.type = FWNODE_IRQCHIP;
return &fwid->fwnode;
 }
+EXPORT_SYMBOL_GPL(irq_domain_alloc_fwnode);
 
 /**
  * irq_domain_free_fwnode - Free a non-OF-backed fwnode_handle
@@ -77,6 +78,7 @@ void irq_domain_free_fwnode(struct fwnode_handle *fwnode)
kfree(fwid->name);
kfree(fwid);
 }
+EXPORT_SYMBOL_GPL(irq_domain_free_fwnode);
 
 /**
  * __irq_domain_add() - Allocate a new irq_domain data structure
-- 
1.9.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-deve

[PATCH v4 7/7] PCI: hv: New paravirtual PCI front-end for Hyper-V VMs

2015-10-29 Thread jakeo
From: Jake Oshins 

This patch introduces a new driver which exposes a root PCI bus whenever a PCI
Express device is passed through to a guest VM under Hyper-V. The device can
be single- or multi-function. The interrupts for the devices are managed by an
IRQ domain, implemented within the driver.

Signed-off-by: Jake Oshins 
---
 MAINTAINERS|1 +
 drivers/pci/Kconfig|7 +
 drivers/pci/host/Makefile  |1 +
 drivers/pci/host/hv_pcifront.c | 2267 
 4 files changed, 2276 insertions(+)
 create mode 100644 drivers/pci/host/hv_pcifront.c

diff --git a/MAINTAINERS b/MAINTAINERS
index a2d50fe..a1205b4 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -5073,6 +5073,7 @@ F:arch/x86/kernel/cpu/mshyperv.c
 F: drivers/hid/hid-hyperv.c
 F: drivers/hv/
 F: drivers/input/serio/hyperv-keyboard.c
+F: drivers/pci/host/hv_pcifront.c
 F: drivers/net/hyperv/
 F: drivers/scsi/storvsc_drv.c
 F: drivers/video/fbdev/hyperv_fb.c
diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig
index 73de4ef..9b82d93 100644
--- a/drivers/pci/Kconfig
+++ b/drivers/pci/Kconfig
@@ -118,4 +118,11 @@ config PCI_LABEL
def_bool y if (DMI || ACPI)
select NLS
 
+config HYPERV_VPCI
+tristate "Hyper-V PCI Frontend"
+depends on PCI && X86 && HYPERV && PCI_MSI && PCI_MSI_IRQ_DOMAIN
+help
+  The PCI device frontend driver allows the kernel to import arbitrary
+  PCI devices from a PCI backend to support PCI driver domains.
+
 source "drivers/pci/host/Kconfig"
diff --git a/drivers/pci/host/Makefile b/drivers/pci/host/Makefile
index 140d66f..39581fb 100644
--- a/drivers/pci/host/Makefile
+++ b/drivers/pci/host/Makefile
@@ -2,6 +2,7 @@ obj-$(CONFIG_PCIE_DW) += pcie-designware.o
 obj-$(CONFIG_PCI_DRA7XX) += pci-dra7xx.o
 obj-$(CONFIG_PCI_EXYNOS) += pci-exynos.o
 obj-$(CONFIG_PCI_IMX6) += pci-imx6.o
+obj-$(CONFIG_HYPERV_VPCI) += hv_pcifront.o
 obj-$(CONFIG_PCI_MVEBU) += pci-mvebu.o
 obj-$(CONFIG_PCI_TEGRA) += pci-tegra.o
 obj-$(CONFIG_PCI_RCAR_GEN2) += pci-rcar-gen2.o
diff --git a/drivers/pci/host/hv_pcifront.c b/drivers/pci/host/hv_pcifront.c
new file mode 100644
index 000..73f296e
--- /dev/null
+++ b/drivers/pci/host/hv_pcifront.c
@@ -0,0 +1,2267 @@
+/*
+ * Copyright (c) Microsoft Corporation.
+ *
+ * Author:
+ *   Jake Oshins 
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+ * NON INFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ *
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+/*
+ * Protocol versions. The low word is the minor version, the high word the 
major
+ * version.
+ */
+
+#define PCI_MAKE_VERSION(major, minor) ((__u32)(((major) << 16) | (major)))
+#define PCI_MAJOR_VERSION(version) ((__u32)(version) >> 16)
+#define PCI_MINOR_VERSION(version) ((__u32)(version) & 0xff)
+
+enum {
+   PCI_PROTOCOL_VERSION_1_1 = PCI_MAKE_VERSION(1, 1),
+   PCI_PROTOCOL_VERSION_CURRENT = PCI_PROTOCOL_VERSION_1_1
+};
+
+#define PCI_CONFIG_MMIO_LENGTH 0x2000
+#define MAX_SUPPORTED_MSI_MESSAGES 0x400
+
+/*
+ * Message Types
+ */
+
+enum pci_message_type {
+   /*
+* Version 1.1
+*/
+   PCI_MESSAGE_BASE= 0x4249,
+   PCI_BUS_RELATIONS   = PCI_MESSAGE_BASE + 0,
+   PCI_QUERY_BUS_RELATIONS = PCI_MESSAGE_BASE + 1,
+   PCI_POWER_STATE_CHANGE  = PCI_MESSAGE_BASE + 4,
+   PCI_QUERY_RESOURCE_REQUIREMENTS = PCI_MESSAGE_BASE + 5,
+   PCI_QUERY_RESOURCE_RESOURCES= PCI_MESSAGE_BASE + 6,
+   PCI_BUS_D0ENTRY = PCI_MESSAGE_BASE + 7,
+   PCI_BUS_D0EXIT  = PCI_MESSAGE_BASE + 8,
+   PCI_READ_BLOCK  = PCI_MESSAGE_BASE + 9,
+   PCI_WRITE_BLOCK = PCI_MESSAGE_BASE + 0xA,
+   PCI_EJECT   = PCI_MESSAGE_BASE + 0xB,
+   PCI_QUERY_STOP  = PCI_MESSAGE_BASE + 0xC,
+   PCI_REENABLE= PCI_MESSAGE_BASE + 0xD,
+   PCI_QUERY_STOP_FAILED   = PCI_MESSAGE_BASE + 0xE,
+   PCI_EJECTION_COMPLETE   = PCI_MESSAGE_BASE + 0xF,
+   PCI_RESOURCES_ASSIGNED  = PCI_MESSAGE_BASE + 0x10,
+   PCI_RESOURCES_RELEASED  = PCI_MESSAGE_BASE + 0x11,
+   PCI_INVALIDATE_BLOCK= PCI_MESSAGE_BASE + 0x12,
+   PCI_QUERY_PROTOCOL_VERSION  = PCI_MESSAGE_BASE + 0x13,
+   PCI_CREATE_INTERRUPT_MESSAGE= PCI_MESSAGE_BASE + 0x14,
+   PCI_DELETE_INTERRUPT_MESSAGE= 

[PATCH v4 6/7] drivers:hv: Define the channel type for Hyper-V PCI Express pass-through

2015-10-29 Thread jakeo
From: Jake Oshins 

This defines the channel type for PCI front-ends in Hyper-V VMs.

Signed-off-by: Jake Oshins 
---
 include/linux/hyperv.h | 11 +++
 1 file changed, 11 insertions(+)

diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h
index ea0a0e3..5587899 100644
--- a/include/linux/hyperv.h
+++ b/include/linux/hyperv.h
@@ -1140,6 +1140,17 @@ u64 hv_do_hypercall(u64 control, void *input, void 
*output);
}
 
 /*
+ * PCI Express Pass Through
+ * {44C4F61D--4400-9D52-802E27EDE19F}
+ */
+
+#define HV_PCIE_GUID \
+   .guid = { \
+   0x1D, 0xF6, 0xC4, 0x44, 0x44, 0x44, 0x00, 0x44, \
+   0x9D, 0x52, 0x80, 0x2E, 0x27, 0xED, 0xE1, 0x9F \
+   }
+
+/*
  * Common header for Hyper-V ICs
  */
 
-- 
1.9.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH v5 0/7] PCI: hv: New paravirtual PCI front-end for Hyper-V VMs

2015-10-30 Thread jakeo
From: Jake Oshins 

This patch series incorporates feedback related to the version sent yesterday.

First, export functions that allow correlating Hyper-V virtual processors
and Linux cpus, along with the means for invoking a hypercall that targets
interrupts at chosen vectors on specfic cpus.

Second, mark various parts of IRQ domain related code as exported, so that
this PCI front-end can implement an IRQ domain as part of a module.  (The
alternative would be to pull all this into the kernel, which would pull
in a lot of other Hyper-V related code, as this IRQ domain depends on
hv_vmbus.ko.)

Third, modify PCI so that new root PCI buses can be marked with an associated
fwnode_handle, and so that root PCI buses can look up their associated IRQ
domain by that handle.

Fourth, introduce a new driver, hv_pcifront, which eposes root PCI buses in
a Hyper-V VM.  These root PCI buses expose real PCIe devices, or PCI Virtual
Functions.

Jake Oshins (7):
  drivers:hv: Export a function that maps Linux CPU num onto Hyper-V
proc num
  drivers:hv: Export hv_do_hypercall()
  PCI: Make it possible to implement a PCI MSI IRQ Domain in a module.
  PCI: Add fwnode_handle to pci_sysdata
  PCI: irqdomain: Look up IRQ domain by fwnode_handle
  drivers:hv: Define the channel type for Hyper-V PCI Express
pass-through
  PCI: hv: New paravirtual PCI front-end for Hyper-V VMs

 MAINTAINERS|1 +
 arch/x86/include/asm/msi.h |4 +
 arch/x86/include/asm/pci.h |   13 +
 arch/x86/kernel/apic/msi.c |5 +-
 arch/x86/kernel/apic/vector.c  |2 +
 drivers/hv/hv.c|   20 +-
 drivers/hv/hyperv_vmbus.h  |2 +-
 drivers/hv/vmbus_drv.c |   17 +
 drivers/pci/Kconfig|7 +
 drivers/pci/host/Makefile  |1 +
 drivers/pci/host/hv_pcifront.c | 2267 
 drivers/pci/msi.c  |4 +
 drivers/pci/probe.c|   11 +
 include/asm-generic/pci.h  |4 +
 include/linux/hyperv.h |   14 +
 kernel/irq/chip.c  |1 +
 kernel/irq/irqdomain.c |2 +
 17 files changed, 2362 insertions(+), 13 deletions(-)
 create mode 100644 drivers/pci/host/hv_pcifront.c

-- 
1.9.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH v5 3/7] PCI: Make it possible to implement a PCI MSI IRQ Domain in a module.

2015-10-30 Thread jakeo
From: Jake Oshins 

The Linux kernel already has the concpet of IRQ domain, whereing a component
can expose a set of IRQs which are managed by a particular interrupt controller
chip or other subsystem. The PCI driver exposes the notion of an IRQ domain
for Message-Signaled Interrupts (MSI) from PCI Express devices. This patch
exposes the functions which are necessary for making an MSI IRQ domain within
a module.

Signed-off-by: Jake Oshins 
---
 arch/x86/include/asm/msi.h| 4 
 arch/x86/kernel/apic/msi.c| 5 +++--
 arch/x86/kernel/apic/vector.c | 2 ++
 drivers/pci/msi.c | 4 
 kernel/irq/chip.c | 1 +
 kernel/irq/irqdomain.c| 2 ++
 6 files changed, 16 insertions(+), 2 deletions(-)

diff --git a/arch/x86/include/asm/msi.h b/arch/x86/include/asm/msi.h
index 93724cc..e8b7924 100644
--- a/arch/x86/include/asm/msi.h
+++ b/arch/x86/include/asm/msi.h
@@ -1,7 +1,11 @@
 #ifndef _ASM_X86_MSI_H
 #define _ASM_X86_MSI_H
 #include 
+#include 
 
 typedef struct irq_alloc_info msi_alloc_info_t;
 
+int pci_msi_prepare(struct irq_domain *domain, struct device *dev, int nvec,
+   msi_alloc_info_t *arg);
+
 #endif /* _ASM_X86_MSI_H */
diff --git a/arch/x86/kernel/apic/msi.c b/arch/x86/kernel/apic/msi.c
index 5f1feb6..bdb28fc 100644
--- a/arch/x86/kernel/apic/msi.c
+++ b/arch/x86/kernel/apic/msi.c
@@ -96,8 +96,8 @@ static irq_hw_number_t pci_msi_get_hwirq(struct 
msi_domain_info *info,
return arg->msi_hwirq;
 }
 
-static int pci_msi_prepare(struct irq_domain *domain, struct device *dev,
-  int nvec, msi_alloc_info_t *arg)
+int pci_msi_prepare(struct irq_domain *domain, struct device *dev, int nvec,
+   msi_alloc_info_t *arg)
 {
struct pci_dev *pdev = to_pci_dev(dev);
struct msi_desc *desc = first_pci_msi_entry(pdev);
@@ -113,6 +113,7 @@ static int pci_msi_prepare(struct irq_domain *domain, 
struct device *dev,
 
return 0;
 }
+EXPORT_SYMBOL_GPL(pci_msi_prepare);
 
 static void pci_msi_set_desc(msi_alloc_info_t *arg, struct msi_desc *desc)
 {
diff --git a/arch/x86/kernel/apic/vector.c b/arch/x86/kernel/apic/vector.c
index 836d11b..f3ac5e1 100644
--- a/arch/x86/kernel/apic/vector.c
+++ b/arch/x86/kernel/apic/vector.c
@@ -29,6 +29,7 @@ struct apic_chip_data {
 };
 
 struct irq_domain *x86_vector_domain;
+EXPORT_SYMBOL_GPL(x86_vector_domain);
 static DEFINE_RAW_SPINLOCK(vector_lock);
 static cpumask_var_t vector_cpumask;
 static struct irq_chip lapic_controller;
@@ -66,6 +67,7 @@ struct irq_cfg *irqd_cfg(struct irq_data *irq_data)
 
return data ? &data->cfg : NULL;
 }
+EXPORT_SYMBOL_GPL(irqd_cfg);
 
 struct irq_cfg *irq_cfg(unsigned int irq)
 {
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
index 53e4632..3915a99 100644
--- a/drivers/pci/msi.c
+++ b/drivers/pci/msi.c
@@ -257,6 +257,7 @@ void pci_msi_mask_irq(struct irq_data *data)
 {
msi_set_mask_bit(data, 1);
 }
+EXPORT_SYMBOL_GPL(pci_msi_mask_irq);
 
 /**
  * pci_msi_unmask_irq - Generic irq chip callback to unmask PCI/MSI interrupts
@@ -266,6 +267,7 @@ void pci_msi_unmask_irq(struct irq_data *data)
 {
msi_set_mask_bit(data, 0);
 }
+EXPORT_SYMBOL_GPL(pci_msi_unmask_irq);
 
 void default_restore_msi_irqs(struct pci_dev *dev)
 {
@@ -1126,6 +1128,7 @@ struct pci_dev *msi_desc_to_pci_dev(struct msi_desc *desc)
 {
return to_pci_dev(desc->dev);
 }
+EXPORT_SYMBOL(msi_desc_to_pci_dev);
 
 void *msi_desc_to_pci_sysdata(struct msi_desc *desc)
 {
@@ -1285,6 +1288,7 @@ struct irq_domain *pci_msi_create_irq_domain(struct 
fwnode_handle *fwnode,
domain->bus_token = DOMAIN_BUS_PCI_MSI;
return domain;
 }
+EXPORT_SYMBOL_GPL(pci_msi_create_irq_domain);
 
 /**
  * pci_msi_domain_alloc_irqs - Allocate interrupts for @dev in @domain
diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c
index 1520645..2414775 100644
--- a/kernel/irq/chip.c
+++ b/kernel/irq/chip.c
@@ -950,6 +950,7 @@ void irq_chip_ack_parent(struct irq_data *data)
data = data->parent_data;
data->chip->irq_ack(data);
 }
+EXPORT_SYMBOL_GPL(irq_chip_ack_parent);
 
 /**
  * irq_chip_mask_parent - Mask the parent interrupt
diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
index 22aa961..174d7e0 100644
--- a/kernel/irq/irqdomain.c
+++ b/kernel/irq/irqdomain.c
@@ -60,6 +60,7 @@ struct fwnode_handle *irq_domain_alloc_fwnode(void *data)
fwid->fwnode.type = FWNODE_IRQCHIP;
return &fwid->fwnode;
 }
+EXPORT_SYMBOL_GPL(irq_domain_alloc_fwnode);
 
 /**
  * irq_domain_free_fwnode - Free a non-OF-backed fwnode_handle
@@ -77,6 +78,7 @@ void irq_domain_free_fwnode(struct fwnode_handle *fwnode)
kfree(fwid->name);
kfree(fwid);
 }
+EXPORT_SYMBOL_GPL(irq_domain_free_fwnode);
 
 /**
  * __irq_domain_add() - Allocate a new irq_domain data structure
-- 
1.9.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-deve

[PATCH v5 4/7] PCI: Add fwnode_handle to pci_sysdata

2015-10-30 Thread jakeo
From: Jake Oshins 

This patch adds an fwnode_handle to struct pci_sysdata, which is
used by the next patch in the series when trying to locate an
IRQ domain associated with a root PCI bus.

Signed-off-by: Jake Oshins 
---
 arch/x86/include/asm/pci.h | 11 +++
 1 file changed, 11 insertions(+)

diff --git a/arch/x86/include/asm/pci.h b/arch/x86/include/asm/pci.h
index 4625943..10213a1 100644
--- a/arch/x86/include/asm/pci.h
+++ b/arch/x86/include/asm/pci.h
@@ -20,6 +20,9 @@ struct pci_sysdata {
 #ifdef CONFIG_X86_64
void*iommu; /* IOMMU private data */
 #endif
+#ifdef CONFIG_PCI_MSI_IRQ_DOMAIN
+   void*fwnode;/* IRQ domain for MSI assignment */
+#endif
 };
 
 extern int pci_routeirq;
@@ -41,6 +44,14 @@ static inline int pci_proc_domain(struct pci_bus *bus)
 }
 #endif
 
+#ifdef CONFIG_PCI_MSI_IRQ_DOMAIN
+static inline void *pci_fwnode(struct pci_bus *bus)
+{
+   struct pci_sysdata *sd = bus->sysdata;
+   return sd->fwnode;
+}
+#endif
+
 /* Can be used to override the logic in pci_scan_bus for skipping
already-configured bus numbers - to be used for buggy BIOSes
or architectures with incomplete PCI setup by the loader */
-- 
1.9.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


  1   2   >