Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 42a1de56 authored by Stefano Stabellini's avatar Stefano Stabellini
Browse files

xen: implement xen_hvm_register_pirq



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: default avatarStefano Stabellini <stefano.stabellini@eu.citrix.com>
Reviewed-by: default avatarKonrad Rzeszutek Wilk <konrad.wilk@oracle.com>
parent 01557baf
Loading
Loading
Loading
Loading
+38 −0
Original line number Diff line number Diff line
@@ -17,6 +17,44 @@
#include <xen/events.h>
#include <asm/xen/pci.h>

#ifdef CONFIG_ACPI
static 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;
}
#endif

#if defined(CONFIG_PCI_MSI)
#include <linux/msi.h>

+3 −1
Original line number Diff line number Diff line
@@ -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 -
+30 −0
Original line number Diff line number Diff line
@@ -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.