/*
 * ARM Generic Interrupt Controller using KVM in-kernel support
 *
 * Copyright (c) 2015 Samsung Electronics Co., Ltd.
 * Written by Pavel Fedin
 * Based on vGICv2 code by Peter Maydell
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 2 of the License, or
 * (at your option) any later version.
 *
 * 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.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, see <http://www.gnu.org/licenses/>.
 */

#include "qemu/osdep.h"
#include "qapi/error.h"
#include "hw/intc/arm_gicv3_common.h"
#include "hw/sysbus.h"
#include "qemu/error-report.h"
#include "qemu/module.h"
#include "sysemu/kvm.h"
#include "sysemu/runstate.h"
#include "kvm_arm.h"
#include "gicv3_internal.h"
#include "vgic_common.h"
#include "migration/blocker.h"
#include "qom/object.h"

#ifdef DEBUG_GICV3_KVM
#define DPRINTF(fmt, ...) \
    do { fprintf(stderr, "kvm_gicv3: " fmt, ## __VA_ARGS__); } while (0)
#else
#define DPRINTF(fmt, ...) \
    do { } while (0)
#endif

#define TYPE_KVM_ARM_GICV3 "kvm-arm-gicv3"
typedef struct KVMARMGICv3Class KVMARMGICv3Class;
/* This is reusing the GICv3State typedef from ARM_GICV3_ITS_COMMON */
DECLARE_OBJ_CHECKERS(GICv3State, KVMARMGICv3Class,
                     KVM_ARM_GICV3, TYPE_KVM_ARM_GICV3)

#define   KVM_DEV_ARM_VGIC_SYSREG(op0, op1, crn, crm, op2)         \
                             (ARM64_SYS_REG_SHIFT_MASK(op0, OP0) | \
                              ARM64_SYS_REG_SHIFT_MASK(op1, OP1) | \
                              ARM64_SYS_REG_SHIFT_MASK(crn, CRN) | \
                              ARM64_SYS_REG_SHIFT_MASK(crm, CRM) | \
                              ARM64_SYS_REG_SHIFT_MASK(op2, OP2))

#define ICC_PMR_EL1     \
    KVM_DEV_ARM_VGIC_SYSREG(3, 0, 4, 6, 0)
#define ICC_BPR0_EL1    \
    KVM_DEV_ARM_VGIC_SYSREG(3, 0, 12, 8, 3)
#define ICC_AP0R_EL1(n) \
    KVM_DEV_ARM_VGIC_SYSREG(3, 0, 12, 8, 4 | n)
#define ICC_AP1R_EL1(n) \
    KVM_DEV_ARM_VGIC_SYSREG(3, 0, 12, 9, n)
#define ICC_BPR1_EL1    \
    KVM_DEV_ARM_VGIC_SYSREG(3, 0, 12, 12, 3)
#define ICC_CTLR_EL1    \
    KVM_DEV_ARM_VGIC_SYSREG(3, 0, 12, 12, 4)
#define ICC_SRE_EL1 \
    KVM_DEV_ARM_VGIC_SYSREG(3, 0, 12, 12, 5)
#define ICC_IGRPEN0_EL1 \
    KVM_DEV_ARM_VGIC_SYSREG(3, 0, 12, 12, 6)
#define ICC_IGRPEN1_EL1 \
    KVM_DEV_ARM_VGIC_SYSREG(3, 0, 12, 12, 7)

struct KVMARMGICv3Class {
    ARMGICv3CommonClass parent_class;
    DeviceRealize parent_realize;
    void (*parent_reset)(DeviceState *dev);
};

static void kvm_arm_gicv3_set_irq(void *opaque, int irq, int level)
{
    GICv3State *s = (GICv3State *)opaque;

    kvm_arm_gic_set_irq(s->num_irq, irq, level);
}

#define KVM_VGIC_ATTR(reg, typer) \
    ((typer & KVM_DEV_ARM_VGIC_V3_MPIDR_MASK) | (reg))

static inline void kvm_gicd_access(GICv3State *s, int offset,
                                   uint32_t *val, bool write)
{
    kvm_device_access(s->dev_fd, KVM_DEV_ARM_VGIC_GRP_DIST_REGS,
                      KVM_VGIC_ATTR(offset, 0),
                      val, write, &error_abort);
}

static inline void kvm_gicr_access(GICv3State *s, int offset, int cpu,
                                   uint32_t *val, bool write)
{
    kvm_device_access(s->dev_fd, KVM_DEV_ARM_VGIC_GRP_REDIST_REGS,
                      KVM_VGIC_ATTR(offset, s->cpu[cpu].gicr_typer),
                      val, write, &error_abort);
}

static inline void kvm_gicc_access(GICv3State *s, uint64_t reg, int cpu,
                                   uint64_t *val, bool write)
{
    kvm_device_access(s->dev_fd, KVM_DEV_ARM_VGIC_GRP_CPU_SYSREGS,
                      KVM_VGIC_ATTR(reg, s->cpu[cpu].gicr_typer),
                      val, write, &error_abort);
}

static inline void kvm_gic_line_level_access(GICv3State *s, int irq, int cpu,
                                             uint32_t *val, bool write)
{
    kvm_device_access(s->dev_fd, KVM_DEV_ARM_VGIC_GRP_LEVEL_INFO,
                      KVM_VGIC_ATTR(irq, s->cpu[cpu].gicr_typer) |
                      (VGIC_LEVEL_INFO_LINE_LEVEL <<
                       KVM_DEV_ARM_VGIC_LINE_LEVEL_INFO_SHIFT),
                      val, write, &error_abort);
}

/* Loop through each distributor IRQ related register; since bits
 * corresponding to SPIs and PPIs are RAZ/WI when affinity routing
 * is enabled, we skip those.
 */
#define for_each_dist_irq_reg(_irq, _max, _field_width) \
    for (_irq = GIC_INTERNAL; _irq < _max; _irq += (32 / _field_width))

static void kvm_dist_get_priority(GICv3State *s, uint32_t offset, uint8_t *bmp)
{
    uint32_t reg, *field;
    int irq;

    /* For the KVM GICv3, affinity routing is always enabled, and the first 8
     * GICD_IPRIORITYR<n> registers are always RAZ/WI. The corresponding
     * functionality is replaced by GICR_IPRIORITYR<n>. It doesn't need to
     * sync them. So it needs to skip the field of GIC_INTERNAL irqs in bmp and
     * offset.
     */
    field = (uint32_t *)(bmp + GIC_INTERNAL);
    offset += (GIC_INTERNAL * 8) / 8;
    for_each_dist_irq_reg(irq, s->num_irq, 8) {
        kvm_gicd_access(s, offset, &reg, false);
        *field = reg;
        offset += 4;
        field++;
    }
}

static void kvm_dist_put_priority(GICv3State *s, uint32_t offset, uint8_t *bmp)
{
    uint32_t reg, *field;
    int irq;

    /* For the KVM GICv3, affinity routing is always enabled, and the first 8
     * GICD_IPRIORITYR<n> registers are always RAZ/WI. The corresponding
     * functionality is replaced by GICR_IPRIORITYR<n>. It doesn't need to
     * sync them. So it needs to skip the field of GIC_INTERNAL irqs in bmp and
     * offset.
     */
    field = (uint32_t *)(bmp + GIC_INTERNAL);
    offset += (GIC_INTERNAL * 8) / 8;
    for_each_dist_irq_reg(irq, s->num_irq, 8) {
        reg = *field;
        kvm_gicd_access(s, offset, &reg, true);
        offset += 4;
        field++;
    }
}

static void kvm_dist_get_edge_trigger(GICv3State *s, uint32_t offset,
                                      uint32_t *bmp)
{
    uint32_t reg;
    int irq;

    /* For the KVM GICv3, affinity routing is always enabled, and the first 2
     * GICD_ICFGR<n> registers are always RAZ/WI. The corresponding
     * functionality is replaced by GICR_ICFGR<n>. It doesn't need to sync
     * them. So it should increase the offset to skip GIC_INTERNAL irqs.
     * This matches the for_each_dist_irq_reg() macro which also skips the
     * first GIC_INTERNAL irqs.
     */
    offset += (GIC_INTERNAL * 2) / 8;
    for_each_dist_irq_reg(irq, s->num_irq, 2) {
        kvm_gicd_access(s, offset, &reg, false);
        reg = half_unshuffle32(reg >> 1);
        if (irq % 32 != 0) {
            reg = (reg << 16);
        }
        *gic_bmp_ptr32(bmp, irq) |=  reg;
        offset += 4;
    }
}

static void kvm_dist_put_edge_trigger(GICv3State *s, uint32_t offset,
                                      uint32_t *bmp)
{
    uint32_t reg;
    int irq;

    /* For the KVM GICv3, affinity routing is always enabled, and the first 2
     * GICD_ICFGR<n> registers are always RAZ/WI. The corresponding
     * functionality is replaced by GICR_ICFGR<n>. It doesn't need to sync
     * them. So it should increase the offset to skip GIC_INTERNAL irqs.
     * This matches the for_each_dist_irq_reg() macro which also skips the
     * first GIC_INTERNAL irqs.
     */
    offset += (GIC_INTERNAL * 2) / 8;
    for_each_dist_irq_reg(irq, s->num_irq, 2) {
        reg = *gic_bmp_ptr32(bmp, irq);
        if (irq % 32 != 0) {
            reg = (reg & 0xffff0000) >> 16;
        } else {
            reg = reg & 0xffff;
        }
        reg = half_shuffle32(reg) << 1;
        kvm_gicd_access(s, offset, &reg, true);
        offset += 4;
    }
}

static void kvm_gic_get_line_level_bmp(GICv3State *s, uint32_t *bmp)
{
    uint32_t reg;
    int irq;

    for_each_dist_irq_reg(irq, s->num_irq, 1) {
        kvm_gic_line_level_access(s, irq, 0, &reg, false);
        *gic_bmp_ptr32(bmp, irq) = reg;
    }
}

static void kvm_gic_put_line_level_bmp(GICv3State *s, uint32_t *bmp)
{
    uint32_t reg;
    int irq;

    for_each_dist_irq_reg(irq, s->num_irq, 1) {
        reg = *gic_bmp_ptr32(bmp, irq);
        kvm_gic_line_level_access(s, irq, 0, &reg, true);
    }
}

/* Read a bitmap register group from the kernel VGIC. */
static void kvm_dist_getbmp(GICv3State *s, uint32_t offset, uint32_t *bmp)
{
    uint32_t reg;
    int irq;

    /* For the KVM GICv3, affinity routing is always enabled, and the
     * GICD_IGROUPR0/GICD_IGRPMODR0/GICD_ISENABLER0/GICD_ISPENDR0/
     * GICD_ISACTIVER0 registers are always RAZ/WI. The corresponding
     * functionality is replaced by the GICR registers. It doesn't need to sync
     * them. So it should increase the offset to skip GIC_INTERNAL irqs.
     * This matches the for_each_dist_irq_reg() macro which also skips the
     * first GIC_INTERNAL irqs.
     */
    offset += (GIC_INTERNAL * 1) / 8;
    for_each_dist_irq_reg(irq, s->num_irq, 1) {
        kvm_gicd_access(s, offset, &reg, false);
        *gic_bmp_ptr32(bmp, irq) = reg;
        offset += 4;
    }
}

static void kvm_dist_putbmp(GICv3State *s, uint32_t offset,
                            uint32_t clroffset, uint32_t *bmp)
{
    uint32_t reg;
    int irq;

    /* For the KVM GICv3, affinity routing is always enabled, and the
     * GICD_IGROUPR0/GICD_IGRPMODR0/GICD_ISENABLER0/GICD_ISPENDR0/
     * GICD_ISACTIVER0 registers are always RAZ/WI. The corresponding
     * functionality is replaced by the GICR registers. It doesn't need to sync
     * them. So it should increase the offset and clroffset to skip GIC_INTERNAL
     * irqs. This matches the for_each_dist_irq_reg() macro which also skips the
     * first GIC_INTERNAL irqs.
     */
    offset += (GIC_INTERNAL * 1) / 8;
    if (clroffset != 0) {
        clroffset += (GIC_INTERNAL * 1) / 8;
    }

    for_each_dist_irq_reg(irq, s->num_irq, 1) {
        /* If this bitmap is a set/clear register pair, first write to the
         * clear-reg to clear all bits before using the set-reg to write
         * the 1 bits.
         */
        if (clroffset != 0) {
            reg = 0;
            kvm_gicd_access(s, clroffset, &reg, true);
            clroffset += 4;
        }
        reg = *gic_bmp_ptr32(bmp, irq);
        kvm_gicd_access(s, offset, &reg, true);
        offset += 4;
    }
}

static void kvm_arm_gicv3_check(GICv3State *s)
{
    uint32_t reg;
    uint32_t num_irq;

    /* Sanity checking s->num_irq */
    kvm_gicd_access(s, GICD_TYPER, &reg, false);
    num_irq = ((reg & 0x1f) + 1) * 32;

    if (num_irq < s->num_irq) {
        error_report("Model requests %u IRQs, but kernel supports max %u",
                     s->num_irq, num_irq);
        abort();
    }
}

static void kvm_arm_gicv3_put(GICv3State *s)
{
    uint32_t regl, regh, reg;
    uint64_t reg64, redist_typer;
    int ncpu, i;

    kvm_arm_gicv3_check(s);

    kvm_gicr_access(s, GICR_TYPER, 0, &regl, false);
    kvm_gicr_access(s, GICR_TYPER + 4, 0, &regh, false);
    redist_typer = ((uint64_t)regh << 32) | regl;

    reg = s->gicd_ctlr;
    kvm_gicd_access(s, GICD_CTLR, &reg, true);

    if (redist_typer & GICR_TYPER_PLPIS) {
        /*
         * Restore base addresses before LPIs are potentially enabled by
         * GICR_CTLR write
         */
        for (ncpu = 0; ncpu < s->num_cpu; ncpu++) {
            GICv3CPUState *c = &s->cpu[ncpu];

            reg64 = c->gicr_propbaser;
            regl = (uint32_t)reg64;
            kvm_gicr_access(s, GICR_PROPBASER, ncpu, &regl, true);
            regh = (uint32_t)(reg64 >> 32);
            kvm_gicr_access(s, GICR_PROPBASER + 4, ncpu, &regh, true);

            reg64 = c->gicr_pendbaser;
            regl = (uint32_t)reg64;
            kvm_gicr_access(s, GICR_PENDBASER, ncpu, &regl, true);
            regh = (uint32_t)(reg64 >> 32);
            kvm_gicr_access(s, GICR_PENDBASER + 4, ncpu, &regh, true);
        }
    }

    /* Redistributor state (one per CPU) */

    for (ncpu = 0; ncpu < s->num_cpu; ncpu++) {
        GICv3CPUState *c = &s->cpu[ncpu];

        reg = c->gicr_ctlr;
        kvm_gicr_access(s, GICR_CTLR, ncpu, &reg, true);

        reg = c->gicr_statusr[GICV3_NS];
        kvm_gicr_access(s, GICR_STATUSR, ncpu, &reg, true);

        reg = c->gicr_waker;
        kvm_gicr_access(s, GICR_WAKER, ncpu, &reg, true);

        reg = c->gicr_igroupr0;
        kvm_gicr_access(s, GICR_IGROUPR0, ncpu, &reg, true);

        reg = ~0;
        kvm_gicr_access(s, GICR_ICENABLER0, ncpu, &reg, true);
        reg = c->gicr_ienabler0;
        kvm_gicr_access(s, GICR_ISENABLER0, ncpu, &reg, true);

        /* Restore config before pending so we treat level/edge correctly */
        reg = half_shuffle32(c->edge_trigger >> 16) << 1;
        kvm_gicr_access(s, GICR_ICFGR1, ncpu, &reg, true);

        reg = c->level;
        kvm_gic_line_level_access(s, 0, ncpu, &reg, true);

        reg = ~0;
        kvm_gicr_access(s, GICR_ICPENDR0, ncpu, &reg, true);
        reg = c->gicr_ipendr0;
        kvm_gicr_access(s, GICR_ISPENDR0, ncpu, &reg, true);

        reg = ~0;
        kvm_gicr_access(s, GICR_ICACTIVER0, ncpu, &reg, true);
        reg = c->gicr_iactiver0;
        kvm_gicr_access(s, GICR_ISACTIVER0, ncpu, &reg, true);

        for (i = 0; i < GIC_INTERNAL; i += 4) {
            reg = c->gicr_ipriorityr[i] |
                (c->gicr_ipriorityr[i + 1] << 8) |
                (c->gicr_ipriorityr[i + 2] << 16) |
                (c->gicr_ipriorityr[i + 3] << 24);
            kvm_gicr_access(s, GICR_IPRIORITYR + i, ncpu, &reg, true);
        }
    }

    /* Distributor state (shared between all CPUs */
    reg = s->gicd_statusr[GICV3_NS];
    kvm_gicd_access(s, GICD_STATUSR, &reg, true);

    /* s->enable bitmap -> GICD_ISENABLERn */
    kvm_dist_putbmp(s, GICD_ISENABLER, GICD_ICENABLER, s->enabled);

    /* s->group bitmap -> GICD_IGROUPRn */
    kvm_dist_putbmp(s, GICD_IGROUPR, 0, s->group);

    /* Restore targets before pending to ensure the pending state is set on
     * the appropriate CPU interfaces in the kernel
     */

    /* s->gicd_irouter[irq] -> GICD_IROUTERn
     * We can't use kvm_dist_put() here because the registers are 64-bit
     */
    for (i = GIC_INTERNAL; i < s->num_irq; i++) {
        uint32_t offset;

        offset = GICD_IROUTER + (sizeof(uint32_t) * i);
        reg = (uint32_t)s->gicd_irouter[i];
        kvm_gicd_access(s, offset, &reg, true);

        offset = GICD_IROUTER + (sizeof(uint32_t) * i) + 4;
        reg = (uint32_t)(s->gicd_irouter[i] >> 32);
        kvm_gicd_access(s, offset, &reg, true);
    }

    /* s->trigger bitmap -> GICD_ICFGRn
     * (restore configuration registers before pending IRQs so we treat
     * level/edge correctly)
     */
    kvm_dist_put_edge_trigger(s, GICD_ICFGR, s->edge_trigger);

    /* s->level bitmap ->  line_level */
    kvm_gic_put_line_level_bmp(s, s->level);

    /* s->pending bitmap -> GICD_ISPENDRn */
    kvm_dist_putbmp(s, GICD_ISPENDR, GICD_ICPENDR, s->pending);

    /* s->active bitmap -> GICD_ISACTIVERn */
    kvm_dist_putbmp(s, GICD_ISACTIVER, GICD_ICACTIVER, s->active);

    /* s->gicd_ipriority[] -> GICD_IPRIORITYRn */
    kvm_dist_put_priority(s, GICD_IPRIORITYR, s->gicd_ipriority);

    /* CPU Interface state (one per CPU) */

    for (ncpu = 0; ncpu < s->num_cpu; ncpu++) {
        GICv3CPUState *c = &s->cpu[ncpu];
        int num_pri_bits;

        kvm_gicc_access(s, ICC_SRE_EL1, ncpu, &c->icc_sre_el1, true);
        kvm_gicc_access(s, ICC_CTLR_EL1, ncpu,
                        &c->icc_ctlr_el1[GICV3_NS], true);
        kvm_gicc_access(s, ICC_IGRPEN0_EL1, ncpu,
                        &c->icc_igrpen[GICV3_G0], true);
        kvm_gicc_access(s, ICC_IGRPEN1_EL1, ncpu,
                        &c->icc_igrpen[GICV3_G1NS], true);
        kvm_gicc_access(s, ICC_PMR_EL1, ncpu, &c->icc_pmr_el1, true);
        kvm_gicc_access(s, ICC_BPR0_EL1, ncpu, &c->icc_bpr[GICV3_G0], true);
        kvm_gicc_access(s, ICC_BPR1_EL1, ncpu, &c->icc_bpr[GICV3_G1NS], true);

        num_pri_bits = ((c->icc_ctlr_el1[GICV3_NS] &
                        ICC_CTLR_EL1_PRIBITS_MASK) >>
                        ICC_CTLR_EL1_PRIBITS_SHIFT) + 1;

        switch (num_pri_bits) {
        case 7:
            reg64 = c->icc_apr[GICV3_G0][3];
            kvm_gicc_access(s, ICC_AP0R_EL1(3), ncpu, &reg64, true);
            reg64 = c->icc_apr[GICV3_G0][2];
            kvm_gicc_access(s, ICC_AP0R_EL1(2), ncpu, &reg64, true);
            /* fall through */
        case 6:
            reg64 = c->icc_apr[GICV3_G0][1];
            kvm_gicc_access(s, ICC_AP0R_EL1(1), ncpu, &reg64, true);
            /* fall through */
        default:
            reg64 = c->icc_apr[GICV3_G0][0];
            kvm_gicc_access(s, ICC_AP0R_EL1(0), ncpu, &reg64, true);
        }

        switch (num_pri_bits) {
        case 7:
            reg64 = c->icc_apr[GICV3_G1NS][3];
            kvm_gicc_access(s, ICC_AP1R_EL1(3), ncpu, &reg64, true);
            reg64 = c->icc_apr[GICV3_G1NS][2];
            kvm_gicc_access(s, ICC_AP1R_EL1(2), ncpu, &reg64, true);
            /* fall through */
        case 6:
            reg64 = c->icc_apr[GICV3_G1NS][1];
            kvm_gicc_access(s, ICC_AP1R_EL1(1), ncpu, &reg64, true);
            /* fall through */
        default:
            reg64 = c->icc_apr[GICV3_G1NS][0];
            kvm_gicc_access(s, ICC_AP1R_EL1(0), ncpu, &reg64, true);
        }
    }
}

static void kvm_arm_gicv3_get(GICv3State *s)
{
    uint32_t regl, regh, reg;
    uint64_t reg64, redist_typer;
    int ncpu, i;

    kvm_arm_gicv3_check(s);

    kvm_gicr_access(s, GICR_TYPER, 0, &regl, false);
    kvm_gicr_access(s, GICR_TYPER + 4, 0, &regh, false);
    redist_typer = ((uint64_t)regh << 32) | regl;

    kvm_gicd_access(s, GICD_CTLR, &reg, false);
    s->gicd_ctlr = reg;

    /* Redistributor state (one per CPU) */

    for (ncpu = 0; ncpu < s->num_cpu; ncpu++) {
        GICv3CPUState *c = &s->cpu[ncpu];

        kvm_gicr_access(s, GICR_CTLR, ncpu, &reg, false);
        c->gicr_ctlr = reg;

        kvm_gicr_access(s, GICR_STATUSR, ncpu, &reg, false);
        c->gicr_statusr[GICV3_NS] = reg;

        kvm_gicr_access(s, GICR_WAKER, ncpu, &reg, false);
        c->gicr_waker = reg;

        kvm_gicr_access(s, GICR_IGROUPR0, ncpu, &reg, false);
        c->gicr_igroupr0 = reg;
        kvm_gicr_access(s, GICR_ISENABLER0, ncpu, &reg, false);
        c->gicr_ienabler0 = reg;
        kvm_gicr_access(s, GICR_ICFGR1, ncpu, &reg, false);
        c->edge_trigger = half_unshuffle32(reg >> 1) << 16;
        kvm_gic_line_level_access(s, 0, ncpu, &reg, false);
        c->level = reg;
        kvm_gicr_access(s, GICR_ISPENDR0, ncpu, &reg, false);
        c->gicr_ipendr0 = reg;
        kvm_gicr_access(s, GICR_ISACTIVER0, ncpu, &reg, false);
        c->gicr_iactiver0 = reg;

        for (i = 0; i < GIC_INTERNAL; i += 4) {
            kvm_gicr_access(s, GICR_IPRIORITYR + i, ncpu, &reg, false);
            c->gicr_ipriorityr[i] = extract32(reg, 0, 8);
            c->gicr_ipriorityr[i + 1] = extract32(reg, 8, 8);
            c->gicr_ipriorityr[i + 2] = extract32(reg, 16, 8);
            c->gicr_ipriorityr[i + 3] = extract32(reg, 24, 8);
        }
    }

    if (redist_typer & GICR_TYPER_PLPIS) {
        for (ncpu = 0; ncpu < s->num_cpu; ncpu++) {
            GICv3CPUState *c = &s->cpu[ncpu];

            kvm_gicr_access(s, GICR_PROPBASER, ncpu, &regl, false);
            kvm_gicr_access(s, GICR_PROPBASER + 4, ncpu, &regh, false);
            c->gicr_propbaser = ((uint64_t)regh << 32) | regl;

            kvm_gicr_access(s, GICR_PENDBASER, ncpu, &regl, false);
            kvm_gicr_access(s, GICR_PENDBASER + 4, ncpu, &regh, false);
            c->gicr_pendbaser = ((uint64_t)regh << 32) | regl;
        }
    }

    /* Distributor state (shared between all CPUs */

    kvm_gicd_access(s, GICD_STATUSR, &reg, false);
    s->gicd_statusr[GICV3_NS] = reg;

    /* GICD_IGROUPRn -> s->group bitmap */
    kvm_dist_getbmp(s, GICD_IGROUPR, s->group);

    /* GICD_ISENABLERn -> s->enabled bitmap */
    kvm_dist_getbmp(s, GICD_ISENABLER, s->enabled);

    /* Line level of irq */
    kvm_gic_get_line_level_bmp(s, s->level);
    /* GICD_ISPENDRn -> s->pending bitmap */
    kvm_dist_getbmp(s, GICD_ISPENDR, s->pending);

    /* GICD_ISACTIVERn -> s->active bitmap */
    kvm_dist_getbmp(s, GICD_ISACTIVER, s->active);

    /* GICD_ICFGRn -> s->trigger bitmap */
    kvm_dist_get_edge_trigger(s, GICD_ICFGR, s->edge_trigger);

    /* GICD_IPRIORITYRn -> s->gicd_ipriority[] */
    kvm_dist_get_priority(s, GICD_IPRIORITYR, s->gicd_ipriority);

    /* GICD_IROUTERn -> s->gicd_irouter[irq] */
    for (i = GIC_INTERNAL; i < s->num_irq; i++) {
        uint32_t offset;

        offset = GICD_IROUTER + (sizeof(uint32_t) * i);
        kvm_gicd_access(s, offset, &regl, false);
        offset = GICD_IROUTER + (sizeof(uint32_t) * i) + 4;
        kvm_gicd_access(s, offset, &regh, false);
        s->gicd_irouter[i] = ((uint64_t)regh << 32) | regl;
    }

    /*****************************************************************
     * CPU Interface(s) State
     */

    for (ncpu = 0; ncpu < s->num_cpu; ncpu++) {
        GICv3CPUState *c = &s->cpu[ncpu];
        int num_pri_bits;

        kvm_gicc_access(s, ICC_SRE_EL1, ncpu, &c->icc_sre_el1, false);
        kvm_gicc_access(s, ICC_CTLR_EL1, ncpu,
                        &c->icc_ctlr_el1[GICV3_NS], false);
        kvm_gicc_access(s, ICC_IGRPEN0_EL1, ncpu,
                        &c->icc_igrpen[GICV3_G0], false);
        kvm_gicc_access(s, ICC_IGRPEN1_EL1, ncpu,
                        &c->icc_igrpen[GICV3_G1NS], false);
        kvm_gicc_access(s, ICC_PMR_EL1, ncpu, &c->icc_pmr_el1, false);
        kvm_gicc_access(s, ICC_BPR0_EL1, ncpu, &c->icc_bpr[GICV3_G0], false);
        kvm_gicc_access(s, ICC_BPR1_EL1, ncpu, &c->icc_bpr[GICV3_G1NS], false);
        num_pri_bits = ((c->icc_ctlr_el1[GICV3_NS] &
                        ICC_CTLR_EL1_PRIBITS_MASK) >>
                        ICC_CTLR_EL1_PRIBITS_SHIFT) + 1;

        switch (num_pri_bits) {
        case 7:
            kvm_gicc_access(s, ICC_AP0R_EL1(3), ncpu, &reg64, false);
            c->icc_apr[GICV3_G0][3] = reg64;
            kvm_gicc_access(s, ICC_AP0R_EL1(2), ncpu, &reg64, false);
            c->icc_apr[GICV3_G0][2] = reg64;
            /* fall through */
        case 6:
            kvm_gicc_access(s, ICC_AP0R_EL1(1), ncpu, &reg64, false);
            c->icc_apr[GICV3_G0][1] = reg64;
            /* fall through */
        default:
            kvm_gicc_access(s, ICC_AP0R_EL1(0), ncpu, &reg64, false);
            c->icc_apr[GICV3_G0][0] = reg64;
        }

        switch (num_pri_bits) {
        case 7:
            kvm_gicc_access(s, ICC_AP1R_EL1(3), ncpu, &reg64, false);
            c->icc_apr[GICV3_G1NS][3] = reg64;
            kvm_gicc_access(s, ICC_AP1R_EL1(2), ncpu, &reg64, false);
            c->icc_apr[GICV3_G1NS][2] = reg64;
            /* fall through */
        case 6:
            kvm_gicc_access(s, ICC_AP1R_EL1(1), ncpu, &reg64, false);
            c->icc_apr[GICV3_G1NS][1] = reg64;
            /* fall through */
        default:
            kvm_gicc_access(s, ICC_AP1R_EL1(0), ncpu, &reg64, false);
            c->icc_apr[GICV3_G1NS][0] = reg64;
        }
    }
}

static void arm_gicv3_icc_reset(CPUARMState *env, const ARMCPRegInfo *ri)
{
    GICv3State *s;
    GICv3CPUState *c;

    c = (GICv3CPUState *)env->gicv3state;
    s = c->gic;

    c->icc_pmr_el1 = 0;
    c->icc_bpr[GICV3_G0] = GIC_MIN_BPR;
    c->icc_bpr[GICV3_G1] = GIC_MIN_BPR;
    c->icc_bpr[GICV3_G1NS] = GIC_MIN_BPR;

    c->icc_sre_el1 = 0x7;
    memset(c->icc_apr, 0, sizeof(c->icc_apr));
    memset(c->icc_igrpen, 0, sizeof(c->icc_igrpen));

    if (s->migration_blocker) {
        return;
    }

    /* Initialize to actual HW supported configuration */
    kvm_device_access(s->dev_fd, KVM_DEV_ARM_VGIC_GRP_CPU_SYSREGS,
                      KVM_VGIC_ATTR(ICC_CTLR_EL1, c->gicr_typer),
                      &c->icc_ctlr_el1[GICV3_NS], false, &error_abort);

    c->icc_ctlr_el1[GICV3_S] = c->icc_ctlr_el1[GICV3_NS];
}

static void kvm_arm_gicv3_reset(DeviceState *dev)
{
    GICv3State *s = ARM_GICV3_COMMON(dev);
    KVMARMGICv3Class *kgc = KVM_ARM_GICV3_GET_CLASS(s);

    DPRINTF("Reset\n");

    kgc->parent_reset(dev);

    if (s->migration_blocker) {
        DPRINTF("Cannot put kernel gic state, no kernel interface\n");
        return;
    }

    kvm_arm_gicv3_put(s);
}

/*
 * CPU interface registers of GIC needs to be reset on CPU reset.
 * For the calling arm_gicv3_icc_reset() on CPU reset, we register
 * below ARMCPRegInfo. As we reset the whole cpu interface under single
 * register reset, we define only one register of CPU interface instead
 * of defining all the registers.
 */
static const ARMCPRegInfo gicv3_cpuif_reginfo[] = {
    { .name = "ICC_CTLR_EL1", .state = ARM_CP_STATE_BOTH,
      .opc0 = 3, .opc1 = 0, .crn = 12, .crm = 12, .opc2 = 4,
      /*
       * If ARM_CP_NOP is used, resetfn is not called,
       * So ARM_CP_NO_RAW is appropriate type.
       */
      .type = ARM_CP_NO_RAW,
      .access = PL1_RW,
      .readfn = arm_cp_read_zero,
      .writefn = arm_cp_write_ignore,
      /*
       * We hang the whole cpu interface reset routine off here
       * rather than parcelling it out into one little function
       * per register
       */
      .resetfn = arm_gicv3_icc_reset,
    },
    REGINFO_SENTINEL
};

/**
 * vm_change_state_handler - VM change state callback aiming at flushing
 * RDIST pending tables into guest RAM
 *
 * The tables get flushed to guest RAM whenever the VM gets stopped.
 */
static void vm_change_state_handler(void *opaque, bool running,
                                    RunState state)
{
    GICv3State *s = (GICv3State *)opaque;
    Error *err = NULL;
    int ret;

    if (running) {
        return;
    }

    ret = kvm_device_access(s->dev_fd, KVM_DEV_ARM_VGIC_GRP_CTRL,
                           KVM_DEV_ARM_VGIC_SAVE_PENDING_TABLES,
                           NULL, true, &err);
    if (err) {
        error_report_err(err);
    }
    if (ret < 0 && ret != -EFAULT) {
        abort();
    }
}


static void kvm_arm_gicv3_realize(DeviceState *dev, Error **errp)
{
    GICv3State *s = KVM_ARM_GICV3(dev);
    KVMARMGICv3Class *kgc = KVM_ARM_GICV3_GET_CLASS(s);
    bool multiple_redist_region_allowed;
    Error *local_err = NULL;
    int i;

    DPRINTF("kvm_arm_gicv3_realize\n");

    kgc->parent_realize(dev, &local_err);
    if (local_err) {
        error_propagate(errp, local_err);
        return;
    }

    if (s->security_extn) {
        error_setg(errp, "the in-kernel VGICv3 does not implement the "
                   "security extensions");
        return;
    }

    gicv3_init_irqs_and_mmio(s, kvm_arm_gicv3_set_irq, NULL, &local_err);
    if (local_err) {
        error_propagate(errp, local_err);
        return;
    }

    for (i = 0; i < s->num_cpu; i++) {
        ARMCPU *cpu = ARM_CPU(qemu_get_cpu(i));

        define_arm_cp_regs(cpu, gicv3_cpuif_reginfo);
    }

    /* Try to create the device via the device control API */
    s->dev_fd = kvm_create_device(kvm_state, KVM_DEV_TYPE_ARM_VGIC_V3, false);
    if (s->dev_fd < 0) {
        error_setg_errno(errp, -s->dev_fd, "error creating in-kernel VGIC");
        return;
    }

    multiple_redist_region_allowed =
        kvm_device_check_attr(s->dev_fd, KVM_DEV_ARM_VGIC_GRP_ADDR,
                              KVM_VGIC_V3_ADDR_TYPE_REDIST_REGION);

    if (!multiple_redist_region_allowed && s->nb_redist_regions > 1) {
        error_setg(errp, "Multiple VGICv3 redistributor regions are not "
                   "supported by this host kernel");
        error_append_hint(errp, "A maximum of %d VCPUs can be used",
                          s->redist_region_count[0]);
        return;
    }

    kvm_device_access(s->dev_fd, KVM_DEV_ARM_VGIC_GRP_NR_IRQS,
                      0, &s->num_irq, true, &error_abort);

    /* Tell the kernel to complete VGIC initialization now */
    kvm_device_access(s->dev_fd, KVM_DEV_ARM_VGIC_GRP_CTRL,
                      KVM_DEV_ARM_VGIC_CTRL_INIT, NULL, true, &error_abort);

    kvm_arm_register_device(&s->iomem_dist, -1, KVM_DEV_ARM_VGIC_GRP_ADDR,
                            KVM_VGIC_V3_ADDR_TYPE_DIST, s->dev_fd, 0);

    if (!multiple_redist_region_allowed) {
        kvm_arm_register_device(&s->iomem_redist[0], -1,
                                KVM_DEV_ARM_VGIC_GRP_ADDR,
                                KVM_VGIC_V3_ADDR_TYPE_REDIST, s->dev_fd, 0);
    } else {
        /* we register regions in reverse order as "devices" are inserted at
         * the head of a QSLIST and the list is then popped from the head
         * onwards by kvm_arm_machine_init_done()
         */
        for (i = s->nb_redist_regions - 1; i >= 0; i--) {
            /* Address mask made of the rdist region index and count */
            uint64_t addr_ormask =
                        i | ((uint64_t)s->redist_region_count[i] << 52);

            kvm_arm_register_device(&s->iomem_redist[i], -1,
                                    KVM_DEV_ARM_VGIC_GRP_ADDR,
                                    KVM_VGIC_V3_ADDR_TYPE_REDIST_REGION,
                                    s->dev_fd, addr_ormask);
        }
    }

    if (kvm_has_gsi_routing()) {
        /* set up irq routing */
        for (i = 0; i < s->num_irq - GIC_INTERNAL; ++i) {
            kvm_irqchip_add_irq_route(kvm_state, i, 0, i);
        }

        kvm_gsi_routing_allowed = true;

        kvm_irqchip_commit_routes(kvm_state);
    }

    if (!kvm_device_check_attr(s->dev_fd, KVM_DEV_ARM_VGIC_GRP_DIST_REGS,
                               GICD_CTLR)) {
        error_setg(&s->migration_blocker, "This operating system kernel does "
                                          "not support vGICv3 migration");
        if (migrate_add_blocker(s->migration_blocker, errp) < 0) {
            error_free(s->migration_blocker);
            return;
        }
    }
    if (kvm_device_check_attr(s->dev_fd, KVM_DEV_ARM_VGIC_GRP_CTRL,
                              KVM_DEV_ARM_VGIC_SAVE_PENDING_TABLES)) {
        qemu_add_vm_change_state_handler(vm_change_state_handler, s);
    }
}

static void kvm_arm_gicv3_class_init(ObjectClass *klass, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);
    ARMGICv3CommonClass *agcc = ARM_GICV3_COMMON_CLASS(klass);
    KVMARMGICv3Class *kgc = KVM_ARM_GICV3_CLASS(klass);

    agcc->pre_save = kvm_arm_gicv3_get;
    agcc->post_load = kvm_arm_gicv3_put;
    device_class_set_parent_realize(dc, kvm_arm_gicv3_realize,
                                    &kgc->parent_realize);
    device_class_set_parent_reset(dc, kvm_arm_gicv3_reset, &kgc->parent_reset);
}

static const TypeInfo kvm_arm_gicv3_info = {
    .name = TYPE_KVM_ARM_GICV3,
    .parent = TYPE_ARM_GICV3_COMMON,
    .instance_size = sizeof(GICv3State),
    .class_init = kvm_arm_gicv3_class_init,
    .class_size = sizeof(KVMARMGICv3Class),
};

static void kvm_arm_gicv3_register_types(void)
{
    type_register_static(&kvm_arm_gicv3_info);
}

type_init(kvm_arm_gicv3_register_types)
