mirror of
https://github.com/qemu/qemu.git
synced 2026-07-08 17:46:10 +00:00
accel, hw/arm, include/system/hvf: infrastructure changes for HVF vGIC
Misc changes needed for HVF vGIC enablement. Note: x86_64 macOS exposes interrupt controller virtualisation since macOS 12. Keeping an #ifdef here in case we end up supporting that... However, given that x86_64 macOS is on its way out, it'll probably (?) not be supported in QEMU. Signed-off-by: Mohamed Mediouni <mohamed@unpredictable.fr> Message-id: 20260429190532.26538-4-mohamed@unpredictable.fr Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
committed by
Peter Maydell
parent
48396ad6ce
commit
2a3c965516
@@ -10,6 +10,8 @@
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
#include "qemu/error-report.h"
|
||||
#include "qapi/error.h"
|
||||
#include "qapi/qapi-visit-common.h"
|
||||
#include "accel/accel-ops.h"
|
||||
#include "exec/cpu-common.h"
|
||||
#include "system/address-spaces.h"
|
||||
@@ -21,6 +23,7 @@
|
||||
#include "trace.h"
|
||||
|
||||
bool hvf_allowed;
|
||||
bool hvf_kernel_irqchip;
|
||||
|
||||
const char *hvf_return_string(hv_return_t ret)
|
||||
{
|
||||
@@ -216,6 +219,43 @@ static int hvf_gdbstub_sstep_flags(AccelState *as)
|
||||
return SSTEP_ENABLE | SSTEP_NOIRQ;
|
||||
}
|
||||
|
||||
static void hvf_set_kernel_irqchip(Object *obj, Visitor *v,
|
||||
const char *name, void *opaque,
|
||||
Error **errp)
|
||||
{
|
||||
OnOffSplit mode;
|
||||
if (!visit_type_OnOffSplit(v, name, &mode, errp)) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch (mode) {
|
||||
case ON_OFF_SPLIT_ON:
|
||||
#ifdef HOST_X86_64
|
||||
/* macOS 12 onwards exposes an HVF virtual APIC. */
|
||||
error_setg(errp, "HVF: kernel irqchip is not currently implemented for x86.");
|
||||
break;
|
||||
#else
|
||||
hvf_kernel_irqchip = true;
|
||||
break;
|
||||
#endif
|
||||
|
||||
case ON_OFF_SPLIT_OFF:
|
||||
hvf_kernel_irqchip = false;
|
||||
break;
|
||||
|
||||
case ON_OFF_SPLIT_SPLIT:
|
||||
error_setg(errp, "HVF: split irqchip is not supported on HVF.");
|
||||
break;
|
||||
|
||||
default:
|
||||
/*
|
||||
* The value was checked in visit_type_OnOffSplit() above. If
|
||||
* we get here, then something is wrong in QEMU.
|
||||
*/
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
static void hvf_accel_class_init(ObjectClass *oc, const void *data)
|
||||
{
|
||||
AccelClass *ac = ACCEL_CLASS(oc);
|
||||
@@ -223,6 +263,12 @@ static void hvf_accel_class_init(ObjectClass *oc, const void *data)
|
||||
ac->init_machine = hvf_accel_init;
|
||||
ac->allowed = &hvf_allowed;
|
||||
ac->gdbstub_supported_sstep_flags = hvf_gdbstub_sstep_flags;
|
||||
hvf_kernel_irqchip = false;
|
||||
object_class_property_add(oc, "kernel-irqchip", "on|off|split",
|
||||
NULL, hvf_set_kernel_irqchip,
|
||||
NULL, NULL);
|
||||
object_class_property_set_description(oc, "kernel-irqchip",
|
||||
"Configure HVF irqchip");
|
||||
}
|
||||
|
||||
static const TypeInfo hvf_accel_type = {
|
||||
|
||||
@@ -10,3 +10,4 @@
|
||||
#include "system/hvf.h"
|
||||
|
||||
bool hvf_allowed;
|
||||
bool hvf_kernel_irqchip;
|
||||
|
||||
@@ -1163,7 +1163,7 @@ static void create_gic(VirtMachineState *vms, MemoryRegion *mem)
|
||||
* interrupts; there are always 32 of the former (mandated by GIC spec).
|
||||
*/
|
||||
qdev_prop_set_uint32(vms->gic, "num-irq", NUM_IRQS + 32);
|
||||
if (!kvm_irqchip_in_kernel()) {
|
||||
if (!kvm_irqchip_in_kernel() && !hvf_irqchip_in_kernel()) {
|
||||
qdev_prop_set_bit(vms->gic, "has-security-extensions", vms->secure);
|
||||
}
|
||||
|
||||
@@ -1186,7 +1186,8 @@ static void create_gic(VirtMachineState *vms, MemoryRegion *mem)
|
||||
qdev_prop_set_array(vms->gic, "redist-region-count",
|
||||
redist_region_count);
|
||||
|
||||
if (!kvm_irqchip_in_kernel()) {
|
||||
if (!kvm_irqchip_in_kernel() &&
|
||||
!(hvf_enabled() && hvf_irqchip_in_kernel())) {
|
||||
if (vms->tcg_its) {
|
||||
object_property_set_link(OBJECT(vms->gic), "sysmem",
|
||||
OBJECT(mem), &error_fatal);
|
||||
@@ -1197,7 +1198,7 @@ static void create_gic(VirtMachineState *vms, MemoryRegion *mem)
|
||||
ARCH_GIC_MAINT_IRQ);
|
||||
}
|
||||
} else {
|
||||
if (!kvm_irqchip_in_kernel()) {
|
||||
if (!kvm_irqchip_in_kernel() && !hvf_irqchip_in_kernel()) {
|
||||
qdev_prop_set_bit(vms->gic, "has-virtualization-extensions",
|
||||
vms->virt);
|
||||
}
|
||||
@@ -2444,7 +2445,15 @@ static void finalize_gic_version(VirtMachineState *vms)
|
||||
accel_name = "KVM with kernel-irqchip=off";
|
||||
} else if (whpx_enabled()) {
|
||||
gics_supported |= VIRT_GIC_VERSION_3_MASK;
|
||||
} else if (tcg_enabled() || hvf_enabled() || qtest_enabled()) {
|
||||
} else if (hvf_enabled()) {
|
||||
if (!hvf_irqchip_in_kernel()) {
|
||||
gics_supported |= VIRT_GIC_VERSION_2_MASK;
|
||||
}
|
||||
/* Hypervisor.framework doesn't expose EL2<->1 transition notifiers */
|
||||
if (!(!hvf_irqchip_in_kernel() && vms->virt)) {
|
||||
gics_supported |= VIRT_GIC_VERSION_3_MASK;
|
||||
}
|
||||
} else if (tcg_enabled() || qtest_enabled()) {
|
||||
gics_supported |= VIRT_GIC_VERSION_2_MASK;
|
||||
if (module_object_class_by_name("arm-gicv3")) {
|
||||
gics_supported |= VIRT_GIC_VERSION_3_MASK;
|
||||
@@ -2486,6 +2495,8 @@ static void finalize_msi_controller(VirtMachineState *vms)
|
||||
vms->msi_controller = VIRT_MSI_CTRL_GICV2M;
|
||||
} else if (whpx_enabled()) {
|
||||
vms->msi_controller = VIRT_MSI_CTRL_GICV2M;
|
||||
} else if (hvf_enabled() && hvf_irqchip_in_kernel()) {
|
||||
vms->msi_controller = VIRT_MSI_CTRL_GICV2M;
|
||||
} else {
|
||||
vms->msi_controller = VIRT_MSI_CTRL_ITS;
|
||||
}
|
||||
@@ -2505,6 +2516,10 @@ static void finalize_msi_controller(VirtMachineState *vms)
|
||||
error_report("ITS not supported on WHPX.");
|
||||
exit(1);
|
||||
}
|
||||
if (hvf_enabled() && hvf_irqchip_in_kernel()) {
|
||||
error_report("ITS not supported on HVF when using the hardware vGIC.");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
assert(vms->msi_controller != VIRT_MSI_CTRL_AUTO);
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
#include "hw/arm/linux-boot-if.h"
|
||||
#include "system/kvm.h"
|
||||
#include "system/whpx.h"
|
||||
#include "system/hvf.h"
|
||||
|
||||
|
||||
static void gicv3_gicd_no_migration_shift_bug_post_load(GICv3State *cs)
|
||||
@@ -659,6 +660,8 @@ const char *gicv3_class_name(void)
|
||||
return "kvm-arm-gicv3";
|
||||
} else if (whpx_enabled()) {
|
||||
return TYPE_WHPX_GICV3;
|
||||
} else if (hvf_enabled() && hvf_irqchip_in_kernel()) {
|
||||
return TYPE_HVF_GICV3;
|
||||
} else {
|
||||
if (kvm_enabled()) {
|
||||
error_report("Userspace GICv3 is not supported with KVM");
|
||||
|
||||
@@ -26,8 +26,11 @@
|
||||
#ifdef CONFIG_HVF_IS_POSSIBLE
|
||||
extern bool hvf_allowed;
|
||||
#define hvf_enabled() (hvf_allowed)
|
||||
extern bool hvf_kernel_irqchip;
|
||||
#define hvf_irqchip_in_kernel() (hvf_kernel_irqchip)
|
||||
#else /* !CONFIG_HVF_IS_POSSIBLE */
|
||||
#define hvf_enabled() 0
|
||||
#define hvf_irqchip_in_kernel() 0
|
||||
#endif /* !CONFIG_HVF_IS_POSSIBLE */
|
||||
|
||||
#define TYPE_HVF_ACCEL ACCEL_CLASS_NAME("hvf")
|
||||
|
||||
@@ -1781,6 +1781,8 @@ static void qemu_apply_legacy_machine_options(QDict *qdict)
|
||||
false);
|
||||
object_register_sugar_prop(ACCEL_CLASS_NAME("whpx"), "kernel-irqchip", value,
|
||||
false);
|
||||
object_register_sugar_prop(ACCEL_CLASS_NAME("hvf"), "kernel-irqchip", value,
|
||||
false);
|
||||
qdict_del(qdict, "kernel-irqchip");
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user