[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-arm] [RFC 5/8] hw/intc/arm_gicv3_kvm: Allow multiple redistributor
From: |
Eric Auger |
Subject: |
[Qemu-arm] [RFC 5/8] hw/intc/arm_gicv3_kvm: Allow multiple redistributor regions |
Date: |
Tue, 27 Mar 2018 16:15:19 +0200 |
If the host kernel supports it, let's allow the regitration of more
than one redistributor region through the new GICv3 group/attribute:
KVM_DEV_ARM_VGIC_GRP_ADDR/KVM_VGIC_V3_ADDR_TYPE_REDIST_REGION.
In that case we don't use kvm_arm_register_device anymore. this latter
registers the kvm device memory listener which resolves the absolute
gpa of the base address in kvm_arm_devlistener_add(). Then
kvm_arm_set_device_addr() is called on machine init done and invokes
the ioctl with the resolved absolute GPA.
In our case we know the absolute GPA at registration time and the
attribute value needs to be combined with the region index and
size of the region. So this does not nicely fit the current
infrastructure.
Signed-off-by: Eric Auger <address@hidden>
---
hw/intc/arm_gicv3_kvm.c | 32 ++++++++++++++++++++++++++------
1 file changed, 26 insertions(+), 6 deletions(-)
diff --git a/hw/intc/arm_gicv3_kvm.c b/hw/intc/arm_gicv3_kvm.c
index b6a3faf..811d809 100644
--- a/hw/intc/arm_gicv3_kvm.c
+++ b/hw/intc/arm_gicv3_kvm.c
@@ -789,14 +789,21 @@ static int
kvm_arm_gicv3_register_redist_region(GICv3State *s, hwaddr base,
uint32_t count)
{
SysBusDevice *sbd = SYS_BUS_DEVICE(s);
+ bool multiple_redist_region_allowed;
int n = s->nb_redist_regions;
+ Error **local_err = NULL;
char *name;
+ int ret;
if (!s->dev_fd) {
return -ENODEV;
}
- if (n > 0) {
+ 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 (n > 0 && !multiple_redist_region_allowed) {
return -EINVAL;
}
@@ -808,15 +815,28 @@ static int
kvm_arm_gicv3_register_redist_region(GICv3State *s, hwaddr base,
NULL, s, name, count * 0x20000);
sysbus_init_mmio(sbd, &s->redist_region[n].mr);
- kvm_arm_register_device(&s->redist_region[n].mr, -1,
- KVM_DEV_ARM_VGIC_GRP_ADDR,
- KVM_VGIC_V3_ADDR_TYPE_REDIST, s->dev_fd);
-
+ if (!multiple_redist_region_allowed) {
+ /* use the legacy API */
+ kvm_arm_register_device(&s->redist_region[n].mr, -1,
+ KVM_DEV_ARM_VGIC_GRP_ADDR,
+ KVM_VGIC_V3_ADDR_TYPE_REDIST, s->dev_fd);
+ } else {
+ uint64_t val = base | n;
+
+ val = deposit64(val, 52, 12, count);
+ ret = kvm_device_access(s->dev_fd, KVM_DEV_ARM_VGIC_GRP_ADDR,
+ KVM_VGIC_V3_ADDR_TYPE_REDIST_REGION,
+ &val, true, local_err);
+ if (ret) {
+ goto out;
+ }
+ }
sysbus_mmio_map(sbd, n + 1, base); /* first region is DIST */
s->nb_redist_regions++;
+out:
g_free(name);
- return 0;
+ return ret;
}
static void kvm_arm_gicv3_class_init(ObjectClass *klass, void *data)
--
2.5.5
- [Qemu-arm] [RFC 0/8] KVM/ARM: Relax the max 123 vcpus limitation along with KVM GICv3, Eric Auger, 2018/03/27
- [Qemu-arm] [RFC 3/8] kvm: Expose kvm_max_vcpus(), Eric Auger, 2018/03/27
- [Qemu-arm] [RFC 2/8] hw/intc/arm_gicv3: Use an array of redistributor regions, Eric Auger, 2018/03/27
- [Qemu-arm] [RFC 1/8] linux-headers: Partial update for KVM/ARM multiple redistributor region registration, Eric Auger, 2018/03/27
- [Qemu-arm] [RFC 5/8] hw/intc/arm_gicv3_kvm: Allow multiple redistributor regions,
Eric Auger <=
- [Qemu-arm] [RFC 4/8] hw/intc/arm_gicv3: Implement register_redist_region API, Eric Auger, 2018/03/27
- [Qemu-arm] [RFC 6/8] hw/arm/virt: Allow GICv3 DT node with multiple redistributor regions, Eric Auger, 2018/03/27
- [Qemu-arm] [RFC 7/8] hw/arm/virt-acpi-build: Handle multiple GICR structures, Eric Auger, 2018/03/27
- [Qemu-arm] [RFC 8/8] hw/arm/virt: Allow up to 512 vcpus along with KVM VGICv3, Eric Auger, 2018/03/27