From 957b1c136865876fb3234b8d06cb7472b0f69127 Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Tue, 25 Feb 2020 18:07:50 +0000 Subject: hw/intc/arm_gic_kvm: Don't assume kernel can provide a GICv2 In our KVM GICv2 realize function, we try to cope with old kernels that don't provide the device control API (KVM_CAP_DEVICE_CTRL): we try to use the device control, and if that fails we fall back to assuming that the kernel has the old style KVM_CREATE_IRQCHIP and that it will provide a GICv2. This doesn't cater for the possibility of a kernel and hardware which only provide a GICv3, which is very common now. On that setup we will abort() later on in kvm_arm_pmu_set_irq() when we try to wire up an interrupt to the GIC we failed to create. If the kernel advertises KVM_CAP_DEVICE_CTRL we should trust it if it says it can't create a GICv2, rather than assuming it has one. We can then produce a more helpful error message including a hint about the most probable reason for the failure. If the kernel doesn't advertise KVM_CAP_DEVICE_CTRL then it is truly ancient by this point but we might as well still fall back to a KVM_CREATE_IRQCHIP GICv2. Signed-off-by: Peter Maydell --- hw/intc/arm_gic_kvm.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'hw/intc/arm_gic_kvm.c') diff --git a/hw/intc/arm_gic_kvm.c b/hw/intc/arm_gic_kvm.c index 9deb15e7e6..d7df423a7a 100644 --- a/hw/intc/arm_gic_kvm.c +++ b/hw/intc/arm_gic_kvm.c @@ -551,7 +551,16 @@ static void kvm_arm_gic_realize(DeviceState *dev, Error **errp) KVM_DEV_ARM_VGIC_CTRL_INIT, NULL, true, &error_abort); } + } else if (kvm_check_extension(kvm_state, KVM_CAP_DEVICE_CTRL)) { + error_setg_errno(errp, -ret, "error creating in-kernel VGIC"); + error_append_hint(errp, + "Perhaps the host CPU does not support GICv2?\n"); } else if (ret != -ENODEV && ret != -ENOTSUP) { + /* + * Very ancient kernel without KVM_CAP_DEVICE_CTRL: assume that + * ENODEV or ENOTSUP mean "can't create GICv2 with KVM_CREATE_DEVICE", + * and that we will get a GICv2 via KVM_CREATE_IRQCHIP. + */ error_setg_errno(errp, -ret, "error creating in-kernel VGIC"); return; } -- cgit v1.2.3