From 6f28047e0f4d78af4a712e6f1f2824e9a030a888 Mon Sep 17 00:00:00 2001 From: Jan Kiszka Date: Thu, 16 Jun 2016 18:25:58 +0200 Subject: [PATCH] arm: Enable / disable maintenance interrupt in distributor We did not get any maintenance interrupts so far because we didn't enable the source in the distributor so far. Fix this, but also disable it again when shutting down. Signed-off-by: Jan Kiszka --- hypervisor/arch/arm/gic-v2.c | 22 +++++++++++++++------- hypervisor/arch/arm/gic-v3.c | 21 +++++++++++++-------- 2 files changed, 28 insertions(+), 15 deletions(-) diff --git a/hypervisor/arch/arm/gic-v2.c b/hypervisor/arch/arm/gic-v2.c index aae5c0e..8f5fc0b 100644 --- a/hypervisor/arch/arm/gic-v2.c +++ b/hypervisor/arch/arm/gic-v2.c @@ -76,11 +76,18 @@ static int gic_cpu_reset(struct per_cpu *cpu_data, bool is_shutdown) mmio_write32(gicc_base + GICC_DIR, i); } - /* Disable PPIs if necessary */ - if (!root_shutdown) - mmio_write32(gicd_base + GICD_ICENABLER, 0xffff0000); - /* Ensure IPIs are enabled */ - mmio_write32(gicd_base + GICD_ISENABLER, 0x0000ffff); + /* Ensure all IPIs and the maintenance PPI are enabled */ + mmio_write32(gicd_base + GICD_ISENABLER, + 0x0000ffff | (1 << MAINTENANCE_IRQ)); + + /* + * Disable PPIs, except for the maintenance interrupt. + * On shutdown, the root cell expects to find all its PPIs still + * enabled - except for the maintenance interrupt we used. + */ + mmio_write32(gicd_base + GICD_ICENABLER, + root_shutdown ? 1 << MAINTENANCE_IRQ : + 0xffff0000 & ~(1 << MAINTENANCE_IRQ)); if (is_shutdown) mmio_write32(gich_base + GICH_HCR, 0); @@ -110,8 +117,9 @@ static int gic_cpu_init(struct per_cpu *cpu_data) u32 vtr, vmcr; u32 cell_gicc_ctlr, cell_gicc_pmr; - /* Ensure all IPIs are enabled */ - mmio_write32(gicd_base + GICD_ISENABLER, 0x0000ffff); + /* Ensure all IPIs and the maintenance PPI are enabled. */ + mmio_write32(gicd_base + GICD_ISENABLER, + 0x0000ffff | (1 << MAINTENANCE_IRQ)); cell_gicc_ctlr = mmio_read32(gicc_base + GICC_CTLR); cell_gicc_pmr = mmio_read32(gicc_base + GICC_PMR); diff --git a/hypervisor/arch/arm/gic-v3.c b/hypervisor/arch/arm/gic-v3.c index 65f326c..4ab03ad 100644 --- a/hypervisor/arch/arm/gic-v3.c +++ b/hypervisor/arch/arm/gic-v3.c @@ -92,14 +92,18 @@ static int gic_cpu_reset(struct per_cpu *cpu_data, bool is_shutdown) arm_write_sysreg(ICC_DIR_EL1, i); } + /* Ensure all IPIs and the maintenance PPI are enabled. */ + mmio_write32(gicr + GICR_ISENABLER, + 0x0000ffff | (1 << MAINTENANCE_IRQ)); + /* - * Disable all PPIs, ensure IPIs are enabled. - * On shutdown, the root cell expects to find all its PPIs still enabled - * when returning to the driver. + * Disable PPIs, except for the maintenance interrupt. + * On shutdown, the root cell expects to find all its PPIs still + * enabled - except for the maintenance interrupt we used. */ - if (!root_shutdown) - mmio_write32(gicr + GICR_ICENABLER, 0xffff0000); - mmio_write32(gicr + GICR_ISENABLER, 0x0000ffff); + mmio_write32(gicr + GICR_ICENABLER, + root_shutdown ? 1 << MAINTENANCE_IRQ : + 0xffff0000 & ~(1 << MAINTENANCE_IRQ)); if (root_shutdown) { /* Restore the root config */ @@ -152,8 +156,9 @@ static int gic_cpu_init(struct per_cpu *cpu_data) return -ENODEV; } - /* Ensure all IPIs are enabled */ - mmio_write32(redist_base + GICR_SGI_BASE + GICR_ISENABLER, 0x0000ffff); + /* Ensure all IPIs and the maintenance PPI are enabled. */ + mmio_write32(redist_base + GICR_SGI_BASE + GICR_ISENABLER, + 0x0000ffff | (1 << MAINTENANCE_IRQ)); /* * Set EOIMode to 1 -- 2.39.2