lkml.org 
[lkml]   [2010]   [Aug]   [30]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 3/7] xen: implement xen_hvm_register_pirq
    Date
    From: Stefano Stabellini <stefano.stabellini@eu.citrix.com>

    xen_hvm_register_pirq allows the kernel to map a GSI into a Xen pirq and
    receive the interrupt as an event channel from that point on.

    Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
    Reviewed-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
    ---
    arch/x86/include/asm/xen/pci.h | 5 +++++
    arch/x86/pci/xen.c | 36 ++++++++++++++++++++++++++++++++++++
    drivers/xen/events.c | 4 +++-
    include/xen/interface/physdev.h | 30 ++++++++++++++++++++++++++++++
    4 files changed, 74 insertions(+), 1 deletions(-)

    diff --git a/arch/x86/include/asm/xen/pci.h b/arch/x86/include/asm/xen/pci.h
    index 449c82f..b4d908b 100644
    --- a/arch/x86/include/asm/xen/pci.h
    +++ b/arch/x86/include/asm/xen/pci.h
    @@ -3,10 +3,15 @@

    #if defined(CONFIG_PCI_XEN)
    extern int __init pci_xen_init(void);
    +int xen_hvm_register_pirq(u32 gsi, int triggering);
    #define pci_xen 1
    #else
    #define pci_xen 0
    #define pci_xen_init (0)
    +static inline int xen_hvm_register_pirq(u32 gsi, int triggering)
    +{
    + return -1;
    +}
    #endif

    #if defined(CONFIG_PCI_MSI)
    diff --git a/arch/x86/pci/xen.c b/arch/x86/pci/xen.c
    index b19c873..d6fd58f 100644
    --- a/arch/x86/pci/xen.c
    +++ b/arch/x86/pci/xen.c
    @@ -17,6 +17,42 @@
    #include <xen/events.h>
    #include <asm/xen/pci.h>

    +int xen_hvm_register_pirq(u32 gsi, int triggering)
    +{
    + int rc, irq;
    + struct physdev_map_pirq map_irq;
    + int shareable = 0;
    + char *name;
    +
    + if (!xen_hvm_domain())
    + return -1;
    +
    + map_irq.domid = DOMID_SELF;
    + map_irq.type = MAP_PIRQ_TYPE_GSI;
    + map_irq.index = gsi;
    + map_irq.pirq = -1;
    +
    + rc = HYPERVISOR_physdev_op(PHYSDEVOP_map_pirq, &map_irq);
    + if (rc) {
    + printk(KERN_WARNING "xen map irq failed %d\n", rc);
    + return -1;
    + }
    +
    + if (triggering == ACPI_EDGE_SENSITIVE) {
    + shareable = 0;
    + name = "ioapic-edge";
    + } else {
    + shareable = 1;
    + name = "ioapic-level";
    + }
    +
    + irq = xen_map_pirq_gsi(map_irq.pirq, gsi, shareable, name);
    +
    + printk(KERN_DEBUG "xen: --> irq=%d, pirq=%d\n", irq, map_irq.pirq);
    +
    + return irq;
    +}
    +
    #if defined(CONFIG_PCI_MSI)
    #include <linux/msi.h>

    diff --git a/drivers/xen/events.c b/drivers/xen/events.c
    index aca7230..302dad1 100644
    --- a/drivers/xen/events.c
    +++ b/drivers/xen/events.c
    @@ -36,6 +36,7 @@
    #include <asm/idle.h>
    #include <asm/io_apic.h>
    #include <asm/sync_bitops.h>
    +#include <asm/xen/pci.h>
    #include <asm/xen/hypercall.h>
    #include <asm/xen/hypervisor.h>

    @@ -75,7 +76,8 @@ enum xen_irq_type {
    * event channel - irq->event channel mapping
    * cpu - cpu this event channel is bound to
    * index - type-specific information:
    - * PIRQ - vector, with MSB being "needs EIO"
    + * PIRQ - vector, with MSB being "needs EIO", or physical IRQ of the HVM
    + * guest, or GSI (real passthrough IRQ) of the device.
    * VIRQ - virq number
    * IPI - IPI vector
    * EVTCHN -
    diff --git a/include/xen/interface/physdev.h b/include/xen/interface/physdev.h
    index fbb5883..69a72b9 100644
    --- a/include/xen/interface/physdev.h
    +++ b/include/xen/interface/physdev.h
    @@ -106,6 +106,36 @@ struct physdev_irq {
    uint32_t vector;
    };

    +#define MAP_PIRQ_TYPE_MSI 0x0
    +#define MAP_PIRQ_TYPE_GSI 0x1
    +#define MAP_PIRQ_TYPE_UNKNOWN 0x2
    +
    +#define PHYSDEVOP_map_pirq 13
    +struct physdev_map_pirq {
    + domid_t domid;
    + /* IN */
    + int type;
    + /* IN */
    + int index;
    + /* IN or OUT */
    + int pirq;
    + /* IN */
    + int bus;
    + /* IN */
    + int devfn;
    + /* IN */
    + int entry_nr;
    + /* IN */
    + uint64_t table_base;
    +};
    +
    +#define PHYSDEVOP_unmap_pirq 14
    +struct physdev_unmap_pirq {
    + domid_t domid;
    + /* IN */
    + int pirq;
    +};
    +
    /*
    * Argument to physdev_op_compat() hypercall. Superceded by new physdev_op()
    * hypercall since 0x00030202.
    --
    1.5.6.5


    \
     
     \ /
      Last update: 2010-08-30 13:23    [W:0.027 / U:29.324 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site