diff --git a/hw/intc/arm_gic.c b/hw/intc/arm_gic.c index 0e1b23047e..7ee2e6bcbb 100644 --- a/hw/intc/arm_gic.c +++ b/hw/intc/arm_gic.c @@ -1555,6 +1555,23 @@ static MemTxResult gic_do_cpu_write(void *opaque, hwaddr addr, return gic_cpu_write(s, id, addr, value, attrs); } +static MemTxResult gic_thisvcpu_read(void *opaque, hwaddr addr, uint64_t *data, + unsigned size, MemTxAttrs attrs) +{ + GICState *s = (GICState *)opaque; + + return gic_cpu_read(s, gic_get_current_vcpu(s), addr, data, attrs); +} + +static MemTxResult gic_thisvcpu_write(void *opaque, hwaddr addr, + uint64_t value, unsigned size, + MemTxAttrs attrs) +{ + GICState *s = (GICState *)opaque; + + return gic_cpu_write(s, gic_get_current_vcpu(s), addr, value, attrs); +} + static const MemoryRegionOps gic_ops[2] = { { .read_with_attrs = gic_dist_read, @@ -1574,6 +1591,19 @@ static const MemoryRegionOps gic_cpu_ops = { .endianness = DEVICE_NATIVE_ENDIAN, }; +static const MemoryRegionOps gic_virt_ops[2] = { + { + .read_with_attrs = NULL, + .write_with_attrs = NULL, + .endianness = DEVICE_NATIVE_ENDIAN, + }, + { + .read_with_attrs = gic_thisvcpu_read, + .write_with_attrs = gic_thisvcpu_write, + .endianness = DEVICE_NATIVE_ENDIAN, + } +}; + static void arm_gic_realize(DeviceState *dev, Error **errp) { /* Device instance realize function for the GIC sysbus device */ @@ -1595,8 +1625,11 @@ static void arm_gic_realize(DeviceState *dev, Error **errp) return; } - /* This creates distributor and main CPU interface (s->cpuiomem[0]) */ - gic_init_irqs_and_mmio(s, gic_set_irq, gic_ops, NULL); + /* This creates distributor, main CPU interface (s->cpuiomem[0]) and if + * enabled, virtualization extensions related interfaces (main virtual + * interface (s->vifaceiomem[0]) and virtual CPU interface). + */ + gic_init_irqs_and_mmio(s, gic_set_irq, gic_ops, gic_virt_ops); /* Extra core-specific regions for the CPU interfaces. This is * necessary for "franken-GIC" implementations, for example on