qemu

FORK: QEMU emulator
git clone https://git.neptards.moe/neptards/qemu.git
Log | Files | Refs | Submodules | LICENSE

arm_gic_kvm.c (19776B)


      1 /*
      2  * ARM Generic Interrupt Controller using KVM in-kernel support
      3  *
      4  * Copyright (c) 2012 Linaro Limited
      5  * Written by Peter Maydell
      6  * Save/Restore logic added by Christoffer Dall.
      7  *
      8  * This program is free software; you can redistribute it and/or modify
      9  * it under the terms of the GNU General Public License as published by
     10  * the Free Software Foundation, either version 2 of the License, or
     11  * (at your option) any later version.
     12  *
     13  * This program is distributed in the hope that it will be useful,
     14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     16  * GNU General Public License for more details.
     17  *
     18  * You should have received a copy of the GNU General Public License along
     19  * with this program; if not, see <http://www.gnu.org/licenses/>.
     20  */
     21 
     22 #include "qemu/osdep.h"
     23 #include "qapi/error.h"
     24 #include "qemu/module.h"
     25 #include "migration/blocker.h"
     26 #include "sysemu/kvm.h"
     27 #include "kvm_arm.h"
     28 #include "gic_internal.h"
     29 #include "vgic_common.h"
     30 #include "qom/object.h"
     31 
     32 #define TYPE_KVM_ARM_GIC "kvm-arm-gic"
     33 typedef struct KVMARMGICClass KVMARMGICClass;
     34 /* This is reusing the GICState typedef from ARM_GIC_COMMON */
     35 DECLARE_OBJ_CHECKERS(GICState, KVMARMGICClass,
     36                      KVM_ARM_GIC, TYPE_KVM_ARM_GIC)
     37 
     38 struct KVMARMGICClass {
     39     ARMGICCommonClass parent_class;
     40     DeviceRealize parent_realize;
     41     void (*parent_reset)(DeviceState *dev);
     42 };
     43 
     44 void kvm_arm_gic_set_irq(uint32_t num_irq, int irq, int level)
     45 {
     46     /* Meaning of the 'irq' parameter:
     47      *  [0..N-1] : external interrupts
     48      *  [N..N+31] : PPI (internal) interrupts for CPU 0
     49      *  [N+32..N+63] : PPI (internal interrupts for CPU 1
     50      *  ...
     51      * Convert this to the kernel's desired encoding, which
     52      * has separate fields in the irq number for type,
     53      * CPU number and interrupt number.
     54      */
     55     int irqtype, cpu;
     56 
     57     if (irq < (num_irq - GIC_INTERNAL)) {
     58         /* External interrupt. The kernel numbers these like the GIC
     59          * hardware, with external interrupt IDs starting after the
     60          * internal ones.
     61          */
     62         irqtype = KVM_ARM_IRQ_TYPE_SPI;
     63         cpu = 0;
     64         irq += GIC_INTERNAL;
     65     } else {
     66         /* Internal interrupt: decode into (cpu, interrupt id) */
     67         irqtype = KVM_ARM_IRQ_TYPE_PPI;
     68         irq -= (num_irq - GIC_INTERNAL);
     69         cpu = irq / GIC_INTERNAL;
     70         irq %= GIC_INTERNAL;
     71     }
     72     kvm_arm_set_irq(cpu, irqtype, irq, !!level);
     73 }
     74 
     75 static void kvm_arm_gicv2_set_irq(void *opaque, int irq, int level)
     76 {
     77     GICState *s = (GICState *)opaque;
     78 
     79     kvm_arm_gic_set_irq(s->num_irq, irq, level);
     80 }
     81 
     82 static bool kvm_arm_gic_can_save_restore(GICState *s)
     83 {
     84     return s->dev_fd >= 0;
     85 }
     86 
     87 #define KVM_VGIC_ATTR(offset, cpu) \
     88     ((((uint64_t)(cpu) << KVM_DEV_ARM_VGIC_CPUID_SHIFT) & \
     89       KVM_DEV_ARM_VGIC_CPUID_MASK) | \
     90      (((uint64_t)(offset) << KVM_DEV_ARM_VGIC_OFFSET_SHIFT) & \
     91       KVM_DEV_ARM_VGIC_OFFSET_MASK))
     92 
     93 static void kvm_gicd_access(GICState *s, int offset, int cpu,
     94                             uint32_t *val, bool write)
     95 {
     96     kvm_device_access(s->dev_fd, KVM_DEV_ARM_VGIC_GRP_DIST_REGS,
     97                       KVM_VGIC_ATTR(offset, cpu), val, write, &error_abort);
     98 }
     99 
    100 static void kvm_gicc_access(GICState *s, int offset, int cpu,
    101                             uint32_t *val, bool write)
    102 {
    103     kvm_device_access(s->dev_fd, KVM_DEV_ARM_VGIC_GRP_CPU_REGS,
    104                       KVM_VGIC_ATTR(offset, cpu), val, write, &error_abort);
    105 }
    106 
    107 #define for_each_irq_reg(_ctr, _max_irq, _field_width) \
    108     for (_ctr = 0; _ctr < ((_max_irq) / (32 / (_field_width))); _ctr++)
    109 
    110 /*
    111  * Translate from the in-kernel field for an IRQ value to/from the qemu
    112  * representation.
    113  */
    114 typedef void (*vgic_translate_fn)(GICState *s, int irq, int cpu,
    115                                   uint32_t *field, bool to_kernel);
    116 
    117 /* synthetic translate function used for clear/set registers to completely
    118  * clear a setting using a clear-register before setting the remaining bits
    119  * using a set-register */
    120 static void translate_clear(GICState *s, int irq, int cpu,
    121                             uint32_t *field, bool to_kernel)
    122 {
    123     if (to_kernel) {
    124         *field = ~0;
    125     } else {
    126         /* does not make sense: qemu model doesn't use set/clear regs */
    127         abort();
    128     }
    129 }
    130 
    131 static void translate_group(GICState *s, int irq, int cpu,
    132                             uint32_t *field, bool to_kernel)
    133 {
    134     int cm = (irq < GIC_INTERNAL) ? (1 << cpu) : ALL_CPU_MASK;
    135 
    136     if (to_kernel) {
    137         *field = GIC_DIST_TEST_GROUP(irq, cm);
    138     } else {
    139         if (*field & 1) {
    140             GIC_DIST_SET_GROUP(irq, cm);
    141         }
    142     }
    143 }
    144 
    145 static void translate_enabled(GICState *s, int irq, int cpu,
    146                               uint32_t *field, bool to_kernel)
    147 {
    148     int cm = (irq < GIC_INTERNAL) ? (1 << cpu) : ALL_CPU_MASK;
    149 
    150     if (to_kernel) {
    151         *field = GIC_DIST_TEST_ENABLED(irq, cm);
    152     } else {
    153         if (*field & 1) {
    154             GIC_DIST_SET_ENABLED(irq, cm);
    155         }
    156     }
    157 }
    158 
    159 static void translate_pending(GICState *s, int irq, int cpu,
    160                               uint32_t *field, bool to_kernel)
    161 {
    162     int cm = (irq < GIC_INTERNAL) ? (1 << cpu) : ALL_CPU_MASK;
    163 
    164     if (to_kernel) {
    165         *field = gic_test_pending(s, irq, cm);
    166     } else {
    167         if (*field & 1) {
    168             GIC_DIST_SET_PENDING(irq, cm);
    169             /* TODO: Capture is level-line is held high in the kernel */
    170         }
    171     }
    172 }
    173 
    174 static void translate_active(GICState *s, int irq, int cpu,
    175                              uint32_t *field, bool to_kernel)
    176 {
    177     int cm = (irq < GIC_INTERNAL) ? (1 << cpu) : ALL_CPU_MASK;
    178 
    179     if (to_kernel) {
    180         *field = GIC_DIST_TEST_ACTIVE(irq, cm);
    181     } else {
    182         if (*field & 1) {
    183             GIC_DIST_SET_ACTIVE(irq, cm);
    184         }
    185     }
    186 }
    187 
    188 static void translate_trigger(GICState *s, int irq, int cpu,
    189                               uint32_t *field, bool to_kernel)
    190 {
    191     if (to_kernel) {
    192         *field = (GIC_DIST_TEST_EDGE_TRIGGER(irq)) ? 0x2 : 0x0;
    193     } else {
    194         if (*field & 0x2) {
    195             GIC_DIST_SET_EDGE_TRIGGER(irq);
    196         }
    197     }
    198 }
    199 
    200 static void translate_priority(GICState *s, int irq, int cpu,
    201                                uint32_t *field, bool to_kernel)
    202 {
    203     if (to_kernel) {
    204         *field = GIC_DIST_GET_PRIORITY(irq, cpu) & 0xff;
    205     } else {
    206         gic_dist_set_priority(s, cpu, irq,
    207                               *field & 0xff, MEMTXATTRS_UNSPECIFIED);
    208     }
    209 }
    210 
    211 static void translate_targets(GICState *s, int irq, int cpu,
    212                               uint32_t *field, bool to_kernel)
    213 {
    214     if (to_kernel) {
    215         *field = s->irq_target[irq] & 0xff;
    216     } else {
    217         s->irq_target[irq] = *field & 0xff;
    218     }
    219 }
    220 
    221 static void translate_sgisource(GICState *s, int irq, int cpu,
    222                                 uint32_t *field, bool to_kernel)
    223 {
    224     if (to_kernel) {
    225         *field = s->sgi_pending[irq][cpu] & 0xff;
    226     } else {
    227         s->sgi_pending[irq][cpu] = *field & 0xff;
    228     }
    229 }
    230 
    231 /* Read a register group from the kernel VGIC */
    232 static void kvm_dist_get(GICState *s, uint32_t offset, int width,
    233                          int maxirq, vgic_translate_fn translate_fn)
    234 {
    235     uint32_t reg;
    236     int i;
    237     int j;
    238     int irq;
    239     int cpu;
    240     int regsz = 32 / width; /* irqs per kernel register */
    241     uint32_t field;
    242 
    243     for_each_irq_reg(i, maxirq, width) {
    244         irq = i * regsz;
    245         cpu = 0;
    246         while ((cpu < s->num_cpu && irq < GIC_INTERNAL) || cpu == 0) {
    247             kvm_gicd_access(s, offset, cpu, &reg, false);
    248             for (j = 0; j < regsz; j++) {
    249                 field = extract32(reg, j * width, width);
    250                 translate_fn(s, irq + j, cpu, &field, false);
    251             }
    252 
    253             cpu++;
    254         }
    255         offset += 4;
    256     }
    257 }
    258 
    259 /* Write a register group to the kernel VGIC */
    260 static void kvm_dist_put(GICState *s, uint32_t offset, int width,
    261                          int maxirq, vgic_translate_fn translate_fn)
    262 {
    263     uint32_t reg;
    264     int i;
    265     int j;
    266     int irq;
    267     int cpu;
    268     int regsz = 32 / width; /* irqs per kernel register */
    269     uint32_t field;
    270 
    271     for_each_irq_reg(i, maxirq, width) {
    272         irq = i * regsz;
    273         cpu = 0;
    274         while ((cpu < s->num_cpu && irq < GIC_INTERNAL) || cpu == 0) {
    275             reg = 0;
    276             for (j = 0; j < regsz; j++) {
    277                 translate_fn(s, irq + j, cpu, &field, true);
    278                 reg = deposit32(reg, j * width, width, field);
    279             }
    280             kvm_gicd_access(s, offset, cpu, &reg, true);
    281 
    282             cpu++;
    283         }
    284         offset += 4;
    285     }
    286 }
    287 
    288 static void kvm_arm_gic_put(GICState *s)
    289 {
    290     uint32_t reg;
    291     int i;
    292     int cpu;
    293     int num_cpu;
    294     int num_irq;
    295 
    296     /* Note: We do the restore in a slightly different order than the save
    297      * (where the order doesn't matter and is simply ordered according to the
    298      * register offset values */
    299 
    300     /*****************************************************************
    301      * Distributor State
    302      */
    303 
    304     /* s->ctlr -> GICD_CTLR */
    305     reg = s->ctlr;
    306     kvm_gicd_access(s, 0x0, 0, &reg, true);
    307 
    308     /* Sanity checking on GICD_TYPER and s->num_irq, s->num_cpu */
    309     kvm_gicd_access(s, 0x4, 0, &reg, false);
    310     num_irq = ((reg & 0x1f) + 1) * 32;
    311     num_cpu = ((reg & 0xe0) >> 5) + 1;
    312 
    313     if (num_irq < s->num_irq) {
    314             fprintf(stderr, "Restoring %u IRQs, but kernel supports max %d\n",
    315                     s->num_irq, num_irq);
    316             abort();
    317     } else if (num_cpu != s->num_cpu) {
    318             fprintf(stderr, "Restoring %u CPU interfaces, kernel only has %d\n",
    319                     s->num_cpu, num_cpu);
    320             /* Did we not create the VCPUs in the kernel yet? */
    321             abort();
    322     }
    323 
    324     /* TODO: Consider checking compatibility with the IIDR ? */
    325 
    326     /* irq_state[n].enabled -> GICD_ISENABLERn */
    327     kvm_dist_put(s, 0x180, 1, s->num_irq, translate_clear);
    328     kvm_dist_put(s, 0x100, 1, s->num_irq, translate_enabled);
    329 
    330     /* irq_state[n].group -> GICD_IGROUPRn */
    331     kvm_dist_put(s, 0x80, 1, s->num_irq, translate_group);
    332 
    333     /* s->irq_target[irq] -> GICD_ITARGETSRn
    334      * (restore targets before pending to ensure the pending state is set on
    335      * the appropriate CPU interfaces in the kernel) */
    336     kvm_dist_put(s, 0x800, 8, s->num_irq, translate_targets);
    337 
    338     /* irq_state[n].trigger -> GICD_ICFGRn
    339      * (restore configuration registers before pending IRQs so we treat
    340      * level/edge correctly) */
    341     kvm_dist_put(s, 0xc00, 2, s->num_irq, translate_trigger);
    342 
    343     /* irq_state[n].pending + irq_state[n].level -> GICD_ISPENDRn */
    344     kvm_dist_put(s, 0x280, 1, s->num_irq, translate_clear);
    345     kvm_dist_put(s, 0x200, 1, s->num_irq, translate_pending);
    346 
    347     /* irq_state[n].active -> GICD_ISACTIVERn */
    348     kvm_dist_put(s, 0x380, 1, s->num_irq, translate_clear);
    349     kvm_dist_put(s, 0x300, 1, s->num_irq, translate_active);
    350 
    351 
    352     /* s->priorityX[irq] -> ICD_IPRIORITYRn */
    353     kvm_dist_put(s, 0x400, 8, s->num_irq, translate_priority);
    354 
    355     /* s->sgi_pending -> ICD_CPENDSGIRn */
    356     kvm_dist_put(s, 0xf10, 8, GIC_NR_SGIS, translate_clear);
    357     kvm_dist_put(s, 0xf20, 8, GIC_NR_SGIS, translate_sgisource);
    358 
    359 
    360     /*****************************************************************
    361      * CPU Interface(s) State
    362      */
    363 
    364     for (cpu = 0; cpu < s->num_cpu; cpu++) {
    365         /* s->cpu_ctlr[cpu] -> GICC_CTLR */
    366         reg = s->cpu_ctlr[cpu];
    367         kvm_gicc_access(s, 0x00, cpu, &reg, true);
    368 
    369         /* s->priority_mask[cpu] -> GICC_PMR */
    370         reg = (s->priority_mask[cpu] & 0xff);
    371         kvm_gicc_access(s, 0x04, cpu, &reg, true);
    372 
    373         /* s->bpr[cpu] -> GICC_BPR */
    374         reg = (s->bpr[cpu] & 0x7);
    375         kvm_gicc_access(s, 0x08, cpu, &reg, true);
    376 
    377         /* s->abpr[cpu] -> GICC_ABPR */
    378         reg = (s->abpr[cpu] & 0x7);
    379         kvm_gicc_access(s, 0x1c, cpu, &reg, true);
    380 
    381         /* s->apr[n][cpu] -> GICC_APRn */
    382         for (i = 0; i < 4; i++) {
    383             reg = s->apr[i][cpu];
    384             kvm_gicc_access(s, 0xd0 + i * 4, cpu, &reg, true);
    385         }
    386     }
    387 }
    388 
    389 static void kvm_arm_gic_get(GICState *s)
    390 {
    391     uint32_t reg;
    392     int i;
    393     int cpu;
    394 
    395     /*****************************************************************
    396      * Distributor State
    397      */
    398 
    399     /* GICD_CTLR -> s->ctlr */
    400     kvm_gicd_access(s, 0x0, 0, &reg, false);
    401     s->ctlr = reg;
    402 
    403     /* Sanity checking on GICD_TYPER -> s->num_irq, s->num_cpu */
    404     kvm_gicd_access(s, 0x4, 0, &reg, false);
    405     s->num_irq = ((reg & 0x1f) + 1) * 32;
    406     s->num_cpu = ((reg & 0xe0) >> 5) + 1;
    407 
    408     if (s->num_irq > GIC_MAXIRQ) {
    409             fprintf(stderr, "Too many IRQs reported from the kernel: %d\n",
    410                     s->num_irq);
    411             abort();
    412     }
    413 
    414     /* GICD_IIDR -> ? */
    415     kvm_gicd_access(s, 0x8, 0, &reg, false);
    416 
    417     /* Clear all the IRQ settings */
    418     for (i = 0; i < s->num_irq; i++) {
    419         memset(&s->irq_state[i], 0, sizeof(s->irq_state[0]));
    420     }
    421 
    422     /* GICD_IGROUPRn -> irq_state[n].group */
    423     kvm_dist_get(s, 0x80, 1, s->num_irq, translate_group);
    424 
    425     /* GICD_ISENABLERn -> irq_state[n].enabled */
    426     kvm_dist_get(s, 0x100, 1, s->num_irq, translate_enabled);
    427 
    428     /* GICD_ISPENDRn -> irq_state[n].pending + irq_state[n].level */
    429     kvm_dist_get(s, 0x200, 1, s->num_irq, translate_pending);
    430 
    431     /* GICD_ISACTIVERn -> irq_state[n].active */
    432     kvm_dist_get(s, 0x300, 1, s->num_irq, translate_active);
    433 
    434     /* GICD_ICFRn -> irq_state[n].trigger */
    435     kvm_dist_get(s, 0xc00, 2, s->num_irq, translate_trigger);
    436 
    437     /* GICD_IPRIORITYRn -> s->priorityX[irq] */
    438     kvm_dist_get(s, 0x400, 8, s->num_irq, translate_priority);
    439 
    440     /* GICD_ITARGETSRn -> s->irq_target[irq] */
    441     kvm_dist_get(s, 0x800, 8, s->num_irq, translate_targets);
    442 
    443     /* GICD_CPENDSGIRn -> s->sgi_pending */
    444     kvm_dist_get(s, 0xf10, 8, GIC_NR_SGIS, translate_sgisource);
    445 
    446 
    447     /*****************************************************************
    448      * CPU Interface(s) State
    449      */
    450 
    451     for (cpu = 0; cpu < s->num_cpu; cpu++) {
    452         /* GICC_CTLR -> s->cpu_ctlr[cpu] */
    453         kvm_gicc_access(s, 0x00, cpu, &reg, false);
    454         s->cpu_ctlr[cpu] = reg;
    455 
    456         /* GICC_PMR -> s->priority_mask[cpu] */
    457         kvm_gicc_access(s, 0x04, cpu, &reg, false);
    458         s->priority_mask[cpu] = (reg & 0xff);
    459 
    460         /* GICC_BPR -> s->bpr[cpu] */
    461         kvm_gicc_access(s, 0x08, cpu, &reg, false);
    462         s->bpr[cpu] = (reg & 0x7);
    463 
    464         /* GICC_ABPR -> s->abpr[cpu] */
    465         kvm_gicc_access(s, 0x1c, cpu, &reg, false);
    466         s->abpr[cpu] = (reg & 0x7);
    467 
    468         /* GICC_APRn -> s->apr[n][cpu] */
    469         for (i = 0; i < 4; i++) {
    470             kvm_gicc_access(s, 0xd0 + i * 4, cpu, &reg, false);
    471             s->apr[i][cpu] = reg;
    472         }
    473     }
    474 }
    475 
    476 static void kvm_arm_gic_reset(DeviceState *dev)
    477 {
    478     GICState *s = ARM_GIC_COMMON(dev);
    479     KVMARMGICClass *kgc = KVM_ARM_GIC_GET_CLASS(s);
    480 
    481     kgc->parent_reset(dev);
    482 
    483     if (kvm_arm_gic_can_save_restore(s)) {
    484         kvm_arm_gic_put(s);
    485     }
    486 }
    487 
    488 static void kvm_arm_gic_realize(DeviceState *dev, Error **errp)
    489 {
    490     int i;
    491     GICState *s = KVM_ARM_GIC(dev);
    492     KVMARMGICClass *kgc = KVM_ARM_GIC_GET_CLASS(s);
    493     Error *local_err = NULL;
    494     int ret;
    495 
    496     kgc->parent_realize(dev, &local_err);
    497     if (local_err) {
    498         error_propagate(errp, local_err);
    499         return;
    500     }
    501 
    502     if (s->security_extn) {
    503         error_setg(errp, "the in-kernel VGIC does not implement the "
    504                    "security extensions");
    505         return;
    506     }
    507 
    508     if (s->virt_extn) {
    509         error_setg(errp, "the in-kernel VGIC does not implement the "
    510                    "virtualization extensions");
    511         return;
    512     }
    513 
    514     if (!kvm_arm_gic_can_save_restore(s)) {
    515         error_setg(&s->migration_blocker, "This operating system kernel does "
    516                                           "not support vGICv2 migration");
    517         if (migrate_add_blocker(s->migration_blocker, errp) < 0) {
    518             error_free(s->migration_blocker);
    519             return;
    520         }
    521     }
    522 
    523     gic_init_irqs_and_mmio(s, kvm_arm_gicv2_set_irq, NULL, NULL);
    524 
    525     for (i = 0; i < s->num_irq - GIC_INTERNAL; i++) {
    526         qemu_irq irq = qdev_get_gpio_in(dev, i);
    527         kvm_irqchip_set_qemuirq_gsi(kvm_state, irq, i);
    528     }
    529 
    530     /* Try to create the device via the device control API */
    531     s->dev_fd = -1;
    532     ret = kvm_create_device(kvm_state, KVM_DEV_TYPE_ARM_VGIC_V2, false);
    533     if (ret >= 0) {
    534         s->dev_fd = ret;
    535 
    536         /* Newstyle API is used, we may have attributes */
    537         if (kvm_device_check_attr(s->dev_fd, KVM_DEV_ARM_VGIC_GRP_NR_IRQS, 0)) {
    538             uint32_t numirqs = s->num_irq;
    539             kvm_device_access(s->dev_fd, KVM_DEV_ARM_VGIC_GRP_NR_IRQS, 0,
    540                               &numirqs, true, &error_abort);
    541         }
    542         /* Tell the kernel to complete VGIC initialization now */
    543         if (kvm_device_check_attr(s->dev_fd, KVM_DEV_ARM_VGIC_GRP_CTRL,
    544                                   KVM_DEV_ARM_VGIC_CTRL_INIT)) {
    545             kvm_device_access(s->dev_fd, KVM_DEV_ARM_VGIC_GRP_CTRL,
    546                               KVM_DEV_ARM_VGIC_CTRL_INIT, NULL, true,
    547                               &error_abort);
    548         }
    549     } else if (kvm_check_extension(kvm_state, KVM_CAP_DEVICE_CTRL)) {
    550         error_setg_errno(errp, -ret, "error creating in-kernel VGIC");
    551         error_append_hint(errp,
    552                           "Perhaps the host CPU does not support GICv2?\n");
    553     } else if (ret != -ENODEV && ret != -ENOTSUP) {
    554         /*
    555          * Very ancient kernel without KVM_CAP_DEVICE_CTRL: assume that
    556          * ENODEV or ENOTSUP mean "can't create GICv2 with KVM_CREATE_DEVICE",
    557          * and that we will get a GICv2 via KVM_CREATE_IRQCHIP.
    558          */
    559         error_setg_errno(errp, -ret, "error creating in-kernel VGIC");
    560         return;
    561     }
    562 
    563     /* Distributor */
    564     kvm_arm_register_device(&s->iomem,
    565                             (KVM_ARM_DEVICE_VGIC_V2 << KVM_ARM_DEVICE_ID_SHIFT)
    566                             | KVM_VGIC_V2_ADDR_TYPE_DIST,
    567                             KVM_DEV_ARM_VGIC_GRP_ADDR,
    568                             KVM_VGIC_V2_ADDR_TYPE_DIST,
    569                             s->dev_fd, 0);
    570     /* CPU interface for current core. Unlike arm_gic, we don't
    571      * provide the "interface for core #N" memory regions, because
    572      * cores with a VGIC don't have those.
    573      */
    574     kvm_arm_register_device(&s->cpuiomem[0],
    575                             (KVM_ARM_DEVICE_VGIC_V2 << KVM_ARM_DEVICE_ID_SHIFT)
    576                             | KVM_VGIC_V2_ADDR_TYPE_CPU,
    577                             KVM_DEV_ARM_VGIC_GRP_ADDR,
    578                             KVM_VGIC_V2_ADDR_TYPE_CPU,
    579                             s->dev_fd, 0);
    580 
    581     if (kvm_has_gsi_routing()) {
    582         /* set up irq routing */
    583         for (i = 0; i < s->num_irq - GIC_INTERNAL; ++i) {
    584             kvm_irqchip_add_irq_route(kvm_state, i, 0, i);
    585         }
    586 
    587         kvm_gsi_routing_allowed = true;
    588 
    589         kvm_irqchip_commit_routes(kvm_state);
    590     }
    591 }
    592 
    593 static void kvm_arm_gic_class_init(ObjectClass *klass, void *data)
    594 {
    595     DeviceClass *dc = DEVICE_CLASS(klass);
    596     ARMGICCommonClass *agcc = ARM_GIC_COMMON_CLASS(klass);
    597     KVMARMGICClass *kgc = KVM_ARM_GIC_CLASS(klass);
    598 
    599     agcc->pre_save = kvm_arm_gic_get;
    600     agcc->post_load = kvm_arm_gic_put;
    601     device_class_set_parent_realize(dc, kvm_arm_gic_realize,
    602                                     &kgc->parent_realize);
    603     device_class_set_parent_reset(dc, kvm_arm_gic_reset, &kgc->parent_reset);
    604 }
    605 
    606 static const TypeInfo kvm_arm_gic_info = {
    607     .name = TYPE_KVM_ARM_GIC,
    608     .parent = TYPE_ARM_GIC_COMMON,
    609     .instance_size = sizeof(GICState),
    610     .class_init = kvm_arm_gic_class_init,
    611     .class_size = sizeof(KVMARMGICClass),
    612 };
    613 
    614 static void kvm_arm_gic_register_types(void)
    615 {
    616     type_register_static(&kvm_arm_gic_info);
    617 }
    618 
    619 type_init(kvm_arm_gic_register_types)