From nobody Fri Nov 14 18:21:17 2025 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=reject dis=none) header.from=unpredictable.fr ARC-Seal: i=1; a=rsa-sha256; t=1760634198; cv=none; d=zohomail.com; s=zohoarc; b=Thy6Lh11A2HhvL5H1a3tQ2jPFVcgFt0wVnp1ElULmWW2Qe0RDUIMN31DrKPjjIaLdZ48CQ6szBnEr4mEqJzYNDh9qXgnQ4lZM7SYuW3ByK75JZnl6MOaD94x3DcBRn93hgkoKjyeVXtQ4uLjXzu23YQd6hbNbbiejaAl6M2Imhk= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1760634198; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=f1Z0855rxWC8aWlMygVlNk2Raub+pFBguy0c0e+7YsA=; b=HtOcvRmEhuF3EyhLYcmdsmHKQqaC0H5BKRBzP0OQF6u7QIi61qGaCmMpcu82SgFSInj+6WWhnNkzsUDsogFRHxhGxh2kqDqfLGbH993stoUdZcHU5Ep+JHF5+fmpVt+vsWs8he8rRK1qQQp53yK0D+/Vg1ksRwDjvMCGjAYYmJc= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=reject dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1760634198080482.9452807061408; Thu, 16 Oct 2025 10:03:18 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1v9RIT-00014h-Ug; Thu, 16 Oct 2025 12:57:50 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1v9RIR-00013c-1A for qemu-devel@nongnu.org; Thu, 16 Oct 2025 12:57:47 -0400 Received: from p-east2-cluster1-host10-snip4-10.eps.apple.com ([57.103.76.123] helo=outbound.st.icloud.com) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1v9RI0-0001bQ-5P for qemu-devel@nongnu.org; Thu, 16 Oct 2025 12:57:46 -0400 Received: from outbound.st.icloud.com (unknown [127.0.0.2]) by p00-icloudmta-asmtp-us-east-1a-100-percent-2 (Postfix) with ESMTPS id 65D9E18015F4; Thu, 16 Oct 2025 16:57:12 +0000 (UTC) Received: from localhost.localdomain (unknown [17.42.251.67]) by p00-icloudmta-asmtp-us-east-1a-100-percent-2 (Postfix) with ESMTPSA id 9C55818024C3; Thu, 16 Oct 2025 16:56:00 +0000 (UTC) Dkim-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=unpredictable.fr; s=sig1; bh=f1Z0855rxWC8aWlMygVlNk2Raub+pFBguy0c0e+7YsA=; h=From:To:Subject:Date:Message-ID:MIME-Version:x-icloud-hme; b=gKOFTBCdqnc/l+gHJuSOi1G+az8kuGPbkRL8PptoqA8qj7Yu+MHeZyR2UXbjpOlrm7d3qEegQuaFCzI1bz5UFcundX9IR+WOcXwTyYACGoINVFS04GSj8tVX+SXlSIlGPvu7zNtMmurhbFvGwS7enXGGk270SfLn42P/8W8n9Caxkzdty2RYOCrOOt0rHskKNYTqiImYUVFIR//wTOxZYjIHbW2tlH9eS80+PCSb9mxjs20GnltxyvOzyY0lgl3BA+Udt1zF+HF2ooUreLOfUTEJom9aGetQK3Mzfwb4uGX84tuJbpC3W/F1/CVCHob0M6yp3t8sypZuS9gJlrkDjg== mail-alias-created-date: 1752046281608 From: Mohamed Mediouni To: qemu-devel@nongnu.org Cc: Alexander Graf , Richard Henderson , Cameron Esfahani , Mads Ynddal , qemu-arm@nongnu.org, =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Ani Sinha , Phil Dennis-Jordan , Mohamed Mediouni , Eduardo Habkost , Sunil Muthuswamy , "Michael S. Tsirkin" , Igor Mammedov , Paolo Bonzini , Yanan Wang , =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= , Shannon Zhao , kvm@vger.kernel.org, Peter Maydell , Marcel Apfelbaum , =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= , Pedro Barbuda , Zhao Liu , Roman Bolshakov , Pierrick Bouvier Subject: [PATCH v7 11/24] whpx: interrupt controller support Date: Thu, 16 Oct 2025 18:55:07 +0200 Message-ID: <20251016165520.62532-12-mohamed@unpredictable.fr> X-Mailer: git-send-email 2.50.1 In-Reply-To: <20251016165520.62532-1-mohamed@unpredictable.fr> References: <20251016165520.62532-1-mohamed@unpredictable.fr> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Proofpoint-GUID: ij9Jl4SlC-7INuxTJ1mUi_3iDZUqeDH6 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjUxMDE2MDEyMyBTYWx0ZWRfX/QrxNaeeQTdy fHlUdk0wH9Aj+aun2W3mhu3hs+LGFUgNGeKvGAgWfEnVCzkZy1MfMtMYISG/BPwdWPo5KUNaotE 3z9sTdnvqD+oT0x1sC5YNT8jqcPBX0BcQI3AUPIYVnd+cc8vo5RrXVeUveMaCPDMCCQPlswjfEZ 6Q3XGCESNN1kFqQw86zK+mBQ5dF1CRg9v+4s90UzxeN8KQaBi7zNXCVlQZgQehQtVJJvX70E1DN 91//cLF/x3xpB7F7ryDPIRKnc6FPLj0p5xqVN4wSwBfKKA8toOqK5hs68313H4cLloDYob7Vw= X-Proofpoint-ORIG-GUID: ij9Jl4SlC-7INuxTJ1mUi_3iDZUqeDH6 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1121,Hydra:6.1.9,FMLib:17.12.80.40 definitions=2025-10-16_03,2025-10-13_01,2025-03-28_01 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 mlxscore=0 bulkscore=0 clxscore=1030 mlxlogscore=999 malwarescore=0 adultscore=0 phishscore=0 spamscore=0 suspectscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.22.0-2506270000 definitions=main-2510160123 X-JNJ: AAAAAAABY7+4GDdIDw5GQUEgFW2BnkK/l9SsyT4vf/BiQONJKlv48y5DY/rta7xhC+rlUXZWptZUmucCnLQI6ycerXL89EU67pA69LqhdBG/wEkSogh2sV4Wf8+2+dz6z6o5bhLlnqu5aHHoDsP/QHWnBdyl35gBzVww7TYyvl4Eo3/LSes8TKu//nJfcFS92+EIrWlrLWpKiJNxMG95PoMxEw4IzAQ0sTt2VMyfCPBn4J9HNj1zYJ8Ven92utiuMGsyQS3iWDSgFV+CV8sIZ5yPBx8V6bIB5ueuJStr/hqEYUDR2QOHxcx8Yz5LpljqcQVJpHbA+WeI2Pd066ZXezm14VpNgWM6kF4w3H9i9xBFHlusyldlyn5okR23jWu9R7SUosPxPTSBfMcR90Lz+9Csmz4rjBZpmIxf/A+7A4CaFh+QcSO4CWFMSAGtiLq8DTgLCS9C+xc30vTw0uAx1OsNdtHOW/nGreYcRapRUJxzatk32tc6k0wFMForIqp8OdjBFK6FbQ9EsAn5QSIS4xJ8MXocb5/pv2/pP9NuBYrCvk5ffwnX0PfazT+ZhPG0xEP3yrnTWivqLf+hQ1P0sTa4UVHM1baSqw3t/6FVWMPZAfmVbOr6KBnxiJgs0h46ea39TbHr/VHtsXpPfLXDln0NqFevFUGwR450dklDpwIrhyyyvXQEjAZTXkMWZt1PFzGiQ+hOWE5o7zP39yDVqmo7hv4Qid3VMAu5FIt7SmAWCnm+nxgAKFOz90HUEj7KcDdMUwdrCzwQpQxNbTh5PZ1kn57N9NRrgx5r64uSyuc6qzGxQwQgqNcslhVioXt5Y/csFFyx6Jt+6Xy1wDiHCMuQWd0SFNQHrwkjvaCerqTxjPDyItlZChlWjBLet9w/A17AhxRtjvAusdvxt2paOKY1jBFI9Jn9UQPA8Q== Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=57.103.76.123; envelope-from=mohamed@unpredictable.fr; helo=outbound.st.icloud.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_VALIDITY_CERTIFIED_BLOCKED=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @unpredictable.fr) X-ZM-MESSAGEID: 1760634198669158500 Content-Type: text/plain; charset="utf-8" Signed-off-by: Mohamed Mediouni Reviewed-by: Pierrick Bouvier --- hw/arm/virt.c | 3 + hw/intc/arm_gicv3_common.c | 3 + hw/intc/arm_gicv3_whpx.c | 239 +++++++++++++++++++++++++++++ hw/intc/meson.build | 1 + include/hw/intc/arm_gicv3_common.h | 3 + 5 files changed, 249 insertions(+) create mode 100644 hw/intc/arm_gicv3_whpx.c diff --git a/hw/arm/virt.c b/hw/arm/virt.c index 61d7bab803..9121eb37eb 100644 --- a/hw/arm/virt.c +++ b/hw/arm/virt.c @@ -47,6 +47,7 @@ #include "system/tcg.h" #include "system/kvm.h" #include "system/hvf.h" +#include "system/whpx.h" #include "system/qtest.h" #include "system/system.h" #include "hw/loader.h" @@ -2105,6 +2106,8 @@ static void finalize_gic_version(VirtMachineState *vm= s) /* KVM w/o kernel irqchip can only deal with GICv2 */ gics_supported |=3D VIRT_GIC_VERSION_2_MASK; accel_name =3D "KVM with kernel-irqchip=3Doff"; + } else if (whpx_enabled()) { + gics_supported |=3D VIRT_GIC_VERSION_3_MASK; } else if (tcg_enabled() || hvf_enabled() || qtest_enabled()) { gics_supported |=3D VIRT_GIC_VERSION_2_MASK; if (module_object_class_by_name("arm-gicv3")) { diff --git a/hw/intc/arm_gicv3_common.c b/hw/intc/arm_gicv3_common.c index 2d0df6da86..1fd1e329e8 100644 --- a/hw/intc/arm_gicv3_common.c +++ b/hw/intc/arm_gicv3_common.c @@ -32,6 +32,7 @@ #include "gicv3_internal.h" #include "hw/arm/linux-boot-if.h" #include "system/kvm.h" +#include "system/whpx.h" =20 =20 static void gicv3_gicd_no_migration_shift_bug_post_load(GICv3State *cs) @@ -663,6 +664,8 @@ const char *gicv3_class_name(void) { if (kvm_irqchip_in_kernel()) { return "kvm-arm-gicv3"; + } else if (whpx_enabled()) { + return TYPE_WHPX_GICV3; } else { if (kvm_enabled()) { error_report("Userspace GICv3 is not supported with KVM"); diff --git a/hw/intc/arm_gicv3_whpx.c b/hw/intc/arm_gicv3_whpx.c new file mode 100644 index 0000000000..88a05e5901 --- /dev/null +++ b/hw/intc/arm_gicv3_whpx.c @@ -0,0 +1,239 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * ARM Generic Interrupt Controller using HVF platform support + * + * Copyright (c) 2025 Mohamed Mediouni + * Based on vGICv3 KVM code by Pavel Fedin + * + */ + +#include "qemu/osdep.h" +#include "qapi/error.h" +#include "hw/intc/arm_gicv3_common.h" +#include "qemu/error-report.h" +#include "qemu/module.h" +#include "system/runstate.h" +#include "system/whpx.h" +#include "system/whpx-internal.h" +#include "gicv3_internal.h" +#include "vgic_common.h" +#include "qom/object.h" +#include "target/arm/cpregs.h" + +#include "hw/arm/bsa.h" +#include +#include +#include + +struct WHPXARMGICv3Class { + ARMGICv3CommonClass parent_class; + DeviceRealize parent_realize; + ResettablePhases parent_phases; +}; + +typedef struct WHPXARMGICv3Class WHPXARMGICv3Class; + +/* This is reusing the GICv3State typedef from ARM_GICV3_ITS_COMMON */ +DECLARE_OBJ_CHECKERS(GICv3State, WHPXARMGICv3Class, + WHPX_GICV3, TYPE_WHPX_GICV3); + +/* TODO: Implement GIC state save-restore */ +static void whpx_gicv3_check(GICv3State *s) +{ +} + +static void whpx_gicv3_put(GICv3State *s) +{ + whpx_gicv3_check(s); +} + +static void whpx_gicv3_get(GICv3State *s) +{ +} + +static void whpx_gicv3_set_irq(void *opaque, int irq, int level) +{ + struct whpx_state *whpx =3D &whpx_global; + + GICv3State *s =3D (GICv3State *)opaque; + if (irq > s->num_irq) { + return; + } + WHV_INTERRUPT_TYPE interrupt_type =3D WHvArm64InterruptTypeFixed; + WHV_INTERRUPT_CONTROL interrupt_control =3D { + interrupt_type =3D WHvArm64InterruptTypeFixed, + .RequestedVector =3D GIC_INTERNAL + irq, .InterruptControl.Asserted = =3D level}; + + whp_dispatch.WHvRequestInterrupt(whpx->partition, &interrupt_control, + sizeof(interrupt_control)); +} + +static void whpx_gicv3_icc_reset(CPUARMState *env, const ARMCPRegInfo *ri) +{ + GICv3State *s; + GICv3CPUState *c; + + c =3D (GICv3CPUState *)env->gicv3state; + s =3D c->gic; + + c->icc_pmr_el1 =3D 0; + /* + * Architecturally the reset value of the ICC_BPR registers + * is UNKNOWN. We set them all to 0 here; when the kernel + * uses these values to program the ICH_VMCR_EL2 fields that + * determine the guest-visible ICC_BPR register values, the + * hardware's "writing a value less than the minimum sets + * the field to the minimum value" behaviour will result in + * them effectively resetting to the correct minimum value + * for the host GIC. + */ + c->icc_bpr[GICV3_G0] =3D 0; + c->icc_bpr[GICV3_G1] =3D 0; + c->icc_bpr[GICV3_G1NS] =3D 0; + + c->icc_sre_el1 =3D 0x7; + memset(c->icc_apr, 0, sizeof(c->icc_apr)); + memset(c->icc_igrpen, 0, sizeof(c->icc_igrpen)); + + if (s->migration_blocker) { + return; + } + + c->icc_ctlr_el1[GICV3_S] =3D c->icc_ctlr_el1[GICV3_NS]; +} + +static void whpx_gicv3_reset_hold(Object *obj, ResetType type) +{ + GICv3State *s =3D ARM_GICV3_COMMON(obj); + WHPXARMGICv3Class *kgc =3D WHPX_GICV3_GET_CLASS(s); + + if (kgc->parent_phases.hold) { + kgc->parent_phases.hold(obj, type); + } + + whpx_gicv3_put(s); +} + + +/* + * CPU interface registers of GIC needs to be reset on CPU reset. + * For the calling arm_gicv3_icc_reset() on CPU reset, we register + * below ARMCPRegInfo. As we reset the whole cpu interface under single + * register reset, we define only one register of CPU interface instead + * of defining all the registers. + */ +static const ARMCPRegInfo gicv3_cpuif_reginfo[] =3D { + { .name =3D "ICC_CTLR_EL1", .state =3D ARM_CP_STATE_BOTH, + .opc0 =3D 3, .opc1 =3D 0, .crn =3D 12, .crm =3D 12, .opc2 =3D 4, + /* + * If ARM_CP_NOP is used, resetfn is not called, + * So ARM_CP_NO_RAW is appropriate type. + */ + .type =3D ARM_CP_NO_RAW, + .access =3D PL1_RW, + .readfn =3D arm_cp_read_zero, + .writefn =3D arm_cp_write_ignore, + /* + * We hang the whole cpu interface reset routine off here + * rather than parcelling it out into one little function + * per register + */ + .resetfn =3D whpx_gicv3_icc_reset, + }, +}; + +static void whpx_set_reg(CPUState *cpu, WHV_REGISTER_NAME reg, WHV_REGISTE= R_VALUE val) +{ + struct whpx_state *whpx =3D &whpx_global; + HRESULT hr; + hr =3D whp_dispatch.WHvSetVirtualProcessorRegisters(whpx->partition, c= pu->cpu_index, + ®, 1, &val); + + if (FAILED(hr)) { + error_report("WHPX: Failed to set register %08x, hr=3D%08lx", reg,= hr); + } +} + +static void whpx_gicv3_realize(DeviceState *dev, Error **errp) +{ + GICv3State *s =3D WHPX_GICV3(dev); + WHPXARMGICv3Class *kgc =3D WHPX_GICV3_GET_CLASS(s); + Error *local_err =3D NULL; + int i; + + kgc->parent_realize(dev, &local_err); + if (local_err) { + error_propagate(errp, local_err); + return; + } + + if (s->revision !=3D 3) { + error_setg(errp, "unsupported GIC revision %d for platform GIC", + s->revision); + } + + if (s->security_extn) { + error_setg(errp, "the platform vGICv3 does not implement the " + "security extensions"); + return; + } + + if (s->nmi_support) { + error_setg(errp, "NMI is not supported with the platform GIC"); + return; + } + + if (s->nb_redist_regions > 1) { + error_setg(errp, "Multiple VGICv3 redistributor regions are not " + "supported by WHPX"); + error_append_hint(errp, "A maximum of %d VCPUs can be used", + s->redist_region_count[0]); + return; + } + + gicv3_init_irqs_and_mmio(s, whpx_gicv3_set_irq, NULL); + + for (i =3D 0; i < s->num_cpu; i++) { + CPUState *cpu_state =3D qemu_get_cpu(i); + ARMCPU *cpu =3D ARM_CPU(cpu_state); + WHV_REGISTER_VALUE val =3D {.Reg64 =3D 0x080A0000 + (GICV3_REDIST_= SIZE * i)}; + whpx_set_reg(cpu_state, WHvArm64RegisterGicrBaseGpa, val); + define_arm_cp_regs(cpu, gicv3_cpuif_reginfo); + } + + if (s->maint_irq) { + error_setg(errp, "Nested virtualisation not currently supported by= WHPX."); + return; + } +} + +static void whpx_gicv3_class_init(ObjectClass *klass, const void *data) +{ + DeviceClass *dc =3D DEVICE_CLASS(klass); + ResettableClass *rc =3D RESETTABLE_CLASS(klass); + ARMGICv3CommonClass *agcc =3D ARM_GICV3_COMMON_CLASS(klass); + WHPXARMGICv3Class *kgc =3D WHPX_GICV3_CLASS(klass); + + agcc->pre_save =3D whpx_gicv3_get; + agcc->post_load =3D whpx_gicv3_put; + + device_class_set_parent_realize(dc, whpx_gicv3_realize, + &kgc->parent_realize); + resettable_class_set_parent_phases(rc, NULL, whpx_gicv3_reset_hold, NU= LL, + &kgc->parent_phases); +} + +static const TypeInfo whpx_arm_gicv3_info =3D { + .name =3D TYPE_WHPX_GICV3, + .parent =3D TYPE_ARM_GICV3_COMMON, + .instance_size =3D sizeof(GICv3State), + .class_init =3D whpx_gicv3_class_init, + .class_size =3D sizeof(WHPXARMGICv3Class), +}; + +static void whpx_gicv3_register_types(void) +{ + type_register_static(&whpx_arm_gicv3_info); +} + +type_init(whpx_gicv3_register_types) diff --git a/hw/intc/meson.build b/hw/intc/meson.build index faae20b93d..96742df090 100644 --- a/hw/intc/meson.build +++ b/hw/intc/meson.build @@ -41,6 +41,7 @@ specific_ss.add(when: 'CONFIG_APIC', if_true: files('apic= .c', 'apic_common.c')) arm_common_ss.add(when: 'CONFIG_ARM_GIC', if_true: files('arm_gicv3_cpuif_= common.c')) arm_common_ss.add(when: 'CONFIG_ARM_GICV3', if_true: files('arm_gicv3_cpui= f.c')) specific_ss.add(when: 'CONFIG_ARM_GIC_KVM', if_true: files('arm_gic_kvm.c'= )) +specific_ss.add(when: ['CONFIG_WHPX', 'TARGET_AARCH64'], if_true: files('a= rm_gicv3_whpx.c')) specific_ss.add(when: ['CONFIG_ARM_GIC_KVM', 'TARGET_AARCH64'], if_true: f= iles('arm_gicv3_kvm.c', 'arm_gicv3_its_kvm.c')) arm_common_ss.add(when: 'CONFIG_ARM_V7M', if_true: files('armv7m_nvic.c')) specific_ss.add(when: 'CONFIG_GRLIB', if_true: files('grlib_irqmp.c')) diff --git a/include/hw/intc/arm_gicv3_common.h b/include/hw/intc/arm_gicv3= _common.h index 38aa1961c5..5f4af811f6 100644 --- a/include/hw/intc/arm_gicv3_common.h +++ b/include/hw/intc/arm_gicv3_common.h @@ -310,6 +310,9 @@ typedef struct ARMGICv3CommonClass ARMGICv3CommonClass; DECLARE_OBJ_CHECKERS(GICv3State, ARMGICv3CommonClass, ARM_GICV3_COMMON, TYPE_ARM_GICV3_COMMON) =20 +/* Types for GICv3 kernel-irqchip */ +#define TYPE_WHPX_GICV3 "whpx-arm-gicv3" + struct ARMGICv3CommonClass { /*< private >*/ SysBusDeviceClass parent_class; --=20 2.50.1 (Apple Git-155)