@@ -57,6 +57,7 @@ OBJS += guest_compat.o
OBJS += hw/rtc.o
OBJS += hw/serial.o
OBJS += ioport.o
+OBJS += irq.o
OBJS += kvm-cpu.o
OBJS += kvm.o
OBJS += main.o
@@ -7,18 +7,6 @@
#include <linux/byteorder.h>
#include <linux/kvm.h>
-static int irq_ids;
-
-int gic__alloc_irqnum(void)
-{
- int irq = GIC_SPI_IRQ_BASE + irq_ids++;
-
- if (irq > GIC_MAX_IRQ)
- die("GIC IRQ limit %d reached!", GIC_MAX_IRQ);
-
- return irq;
-}
-
int gic__init_irqchip(struct kvm *kvm)
{
int err;
@@ -5,6 +5,8 @@
#include <linux/const.h>
#include <linux/types.h>
+#include "arm-common/gic.h"
+
#define ARM_IOPORT_AREA _AC(0x0000000000000000, UL)
#define ARM_MMIO_AREA _AC(0x0000000000010000, UL)
#define ARM_AXI_AREA _AC(0x0000000040000000, UL)
@@ -28,6 +30,8 @@
#define KVM_PCI_MMIO_AREA (KVM_PCI_CFG_AREA + ARM_PCI_CFG_SIZE)
#define KVM_VIRTIO_MMIO_AREA ARM_MMIO_AREA
+#define KVM_IRQ_OFFSET GIC_SPI_IRQ_BASE
+
#define VIRTIO_DEFAULT_TRANS VIRTIO_MMIO
static inline bool arm_addr_in_ioport_region(u64 phys_addr)
@@ -1,6 +1,5 @@
#include "kvm/ioport.h"
-
-#include "arm-common/gic.h"
+#include "kvm/irq.h"
void ioport__setup_arch(struct kvm *kvm)
{
@@ -8,5 +7,5 @@ void ioport__setup_arch(struct kvm *kvm)
void ioport__map_irq(u8 *irq)
{
- *irq = gic__alloc_irqnum();
+ *irq = irq__alloc_line();
}
@@ -2,13 +2,6 @@
#include "kvm/kvm.h"
#include "kvm/util.h"
-#include "arm-common/gic.h"
-
-int irq__alloc_line(void)
-{
- return gic__alloc_irqnum();
-}
-
int irq__add_msix_route(struct kvm *kvm, struct msi_msg *msg)
{
die(__FUNCTION__);
new file mode 100644
@@ -0,0 +1,9 @@
+#include "kvm/irq.h"
+#include "kvm/kvm-arch.h"
+
+static u8 next_line = KVM_IRQ_OFFSET;
+
+int irq__alloc_line(void)
+{
+ return next_line++;
+}
@@ -42,6 +42,8 @@
#define KVM_PCI_MMIO_AREA 0x2000000
#define KVM_VIRTIO_MMIO_AREA 0x3000000
+#define KVM_IRQ_OFFSET 16
+
#define VIRTIO_DEFAULT_TRANS VIRTIO_PCI
struct spapr_phb;
@@ -24,23 +24,6 @@
#include "kvm/pci.h"
-#include "xics.h"
-#include "spapr_pci.h"
-
-/*
- * FIXME: The code in this file assumes an SPAPR guest, using XICS. Make
- * generic & cope with multiple PPC platform types.
- */
-
-int irq__alloc_line(void)
-{
- /*
- * Have I said how nasty I find this? Line should be dontcare... PHB
- * should determine which CPU/XICS IRQ to fire.
- */
- return xics_alloc_irqnum();
-}
-
int irq__add_msix_route(struct kvm *kvm, struct msi_msg *msg)
{
die(__FUNCTION__);
@@ -14,6 +14,7 @@
#include "spapr.h"
#include "xics.h"
#include "kvm/util.h"
+#include "kvm/kvm.h"
#include <stdio.h>
#include <malloc.h>
@@ -41,7 +42,7 @@ struct icp_server_state {
struct kvm_cpu *cpu;
};
-#define XICS_IRQ_OFFSET 16
+#define XICS_IRQ_OFFSET KVM_IRQ_OFFSET
#define XISR_MASK 0x00ffffff
#define CPPR_MASK 0xff000000
@@ -273,31 +274,6 @@ static void ics_eoi(struct ics_state *ics, int nr)
* Exported functions
*/
-static int allocated_irqnum = XICS_IRQ_OFFSET;
-
-/*
- * xics_alloc_irqnum(): This is hacky. The problem boils down to the PCI device
- * code which just calls kvm__irq_line( .. pcidev->pci_hdr.irq_line ..) at will.
- * Each PCI device's IRQ line is allocated by irq__alloc_line() (which
- * allocates an IRQ AND allocates a.. PCI device num..).
- *
- * In future I'd like to at least mimic some kind of 'upstream IRQ controller'
- * whereby PCI devices let their PHB know when they want to IRQ, and that
- * percolates up.
- *
- * For now, allocate a REAL xics irq number and (via irq__alloc_line) push
- * that into the config space. 8 bits only though!
- */
-int xics_alloc_irqnum(void)
-{
- int irq = allocated_irqnum++;
-
- if (irq > 255)
- die("Huge numbers of IRQs aren't supported with the daft kvmtool IRQ system.");
-
- return irq;
-}
-
static target_ulong h_cppr(struct kvm_cpu *vcpu,
target_ulong opcode, target_ulong *args)
{
@@ -25,6 +25,8 @@
#define KVM_PCI_MMIO_AREA (KVM_MMIO_START + 0x2000000)
#define KVM_VIRTIO_MMIO_AREA (KVM_MMIO_START + 0x3000000)
+#define KVM_IRQ_OFFSET 5
+
#define VIRTIO_DEFAULT_TRANS VIRTIO_PCI
struct kvm_arch {
@@ -16,8 +16,6 @@
#define IRQCHIP_SLAVE 1
#define IRQCHIP_IOAPIC 2
-static u8 next_line = 5;
-
/* First 24 GSIs are routed between IRQCHIPs and IOAPICs */
static u32 gsi = 24;
@@ -39,11 +37,6 @@ static int irq__add_routing(u32 gsi, u32 type, u32 irqchip, u32 pin)
return 0;
}
-int irq__alloc_line(void)
-{
- return next_line++;
-}
-
int irq__init(struct kvm *kvm)
{
int i, r;
All architectures are now doing the same thing for irq__alloc_line: 1. Initialise a global counter to some fixed offset 2. Return the current value of the counter and increment it This is better off in core code, with each architecture specifying the initial offset, which is specific to the interrupt controller being used by the guest. Signed-off-by: Will Deacon <will.deacon@arm.com> --- tools/kvm/Makefile | 1 + tools/kvm/arm/gic.c | 12 ------------ tools/kvm/arm/include/arm-common/kvm-arch.h | 4 ++++ tools/kvm/arm/ioport.c | 5 ++--- tools/kvm/arm/irq.c | 7 ------- tools/kvm/irq.c | 9 +++++++++ tools/kvm/powerpc/include/kvm/kvm-arch.h | 2 ++ tools/kvm/powerpc/irq.c | 17 ----------------- tools/kvm/powerpc/xics.c | 28 ++-------------------------- tools/kvm/x86/include/kvm/kvm-arch.h | 2 ++ tools/kvm/x86/irq.c | 7 ------- 11 files changed, 22 insertions(+), 72 deletions(-) create mode 100644 tools/kvm/irq.c