@@ -795,6 +795,9 @@ static void create_gic(VirtMachineState *vms, MemoryRegion *mem)
OBJECT(mem), &error_fatal);
qdev_prop_set_bit(vms->gic, "has-lpi", true);
}
+ } else {
+ qdev_prop_set_uint32(vms->gic, "maintenance-interrupt-id",
+ ARCH_GIC_MAINT_IRQ);
}
} else {
if (!kvm_irqchip_in_kernel()) {
@@ -564,6 +564,7 @@ static Property arm_gicv3_common_properties[] = {
DEFINE_PROP_UINT32("revision", GICv3State, revision, 3),
DEFINE_PROP_BOOL("has-lpi", GICv3State, lpi_enable, 0),
DEFINE_PROP_BOOL("has-security-extensions", GICv3State, security_extn, 0),
+ DEFINE_PROP_UINT32("maintenance-interrupt-id", GICv3State, maint_irq, 0),
/*
* Compatibility property: force 8 bits of physical priority, even
* if the CPU being emulated should have fewer.
@@ -22,6 +22,7 @@
#include "qemu/osdep.h"
#include "qapi/error.h"
#include "hw/intc/arm_gicv3_common.h"
+#include "hw/arm/virt.h"
#include "qemu/error-report.h"
#include "qemu/module.h"
#include "sysemu/kvm.h"
@@ -820,6 +821,26 @@ static void kvm_arm_gicv3_realize(DeviceState *dev, Error **errp)
return;
}
+ if (s->maint_irq) {
+ int ret;
+
+ ret = kvm_device_check_attr(s->dev_fd,
+ KVM_DEV_ARM_VGIC_GRP_MAINT_IRQ, 0);
+ if (!ret) {
+ error_setg_errno(errp, errno,
+ "VGICv3 setting maintenance IRQ is not "
+ "supported by this host kernel");
+ return;
+ }
+
+ ret = kvm_device_access(s->dev_fd, KVM_DEV_ARM_VGIC_GRP_MAINT_IRQ, 0,
+ &s->maint_irq, true, errp);
+ if (ret) {
+ error_setg_errno(errp, errno, "Failed to set VGIC maintenance IRQ");
+ 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);
@@ -246,6 +246,7 @@ struct GICv3State {
uint32_t num_cpu;
uint32_t num_irq;
uint32_t revision;
+ uint32_t maint_irq;
bool lpi_enable;
bool security_extn;
bool force_8bit_prio;