From 59b7559dfa658e325e8c1e23f13f48cf6952ac2e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= Date: Wed, 3 Jul 2024 13:25:47 +0100 Subject: Add downstream aarch64 versioned 'virt' machine types Adding changes to add RHEL machine types for aarch64 architecture. Signed-off-by: Miroslav Rezanina --- Rebase notes (9.1.0): - Merge copy+pasted base machine definition back with upstream base machine definition to reduce RHEL delta, as is done with other targets - Convert to new DEFINE_VIRT_MACHINE macros - do not remove cpu validation (review comment) - use ifdef instead of removal for disabling unwanted upstream code Rebase notes (10.0.0) - Removed unwanted sysbus dev - Set no_nested_smmu - Use upstream compat Rebase notes (10.1.0): - Use rebase compat Merged patches (9.1.0): - 043ad5ce97 Add upstream compatibility bits (partial) Merged patches (10.0.0 rc0): - 03502faf70 Add upstream compatibility bits - 17c3bccf2f arm: ensure compatibility of virt-rhel9* - 12e5b038be arm: create new virt machine type for rhel 9.6 - fb1bc2766e arm: create virt machine type for rhel10 - 727307e5ed hw/arm/virt: Fix Manufacturer and Product Name in emulated SMBIOS mode - d93fcb3940 virtio-net: disable USO for all RHEL9 (partial) - 0440f3d003 arm: disable pauth for virt-rhel9* in RHEL10 --- hw/arm/virt.c | 154 +++++++++++++++++++++++++++++++++++++----- include/hw/arm/virt.h | 1 + 2 files changed, 137 insertions(+), 18 deletions(-) diff --git a/hw/arm/virt.c b/hw/arm/virt.c index e6e98fef1c..d37d1bb3cf 100644 --- a/hw/arm/virt.c +++ b/hw/arm/virt.c @@ -97,6 +97,32 @@ static GlobalProperty arm_virt_compat[] = { }; static const size_t arm_virt_compat_len = G_N_ELEMENTS(arm_virt_compat); +/* + * RHEL9 kernels have pauth disabled while RHEL10 has it enabled, + * since qemu will setup the VM with pauth when KVM supports it we + * have to disable it for virt-rhel9* to support upgrades / migration. + */ +GlobalProperty arm_rhel9_compat[] = { + {TYPE_ARM_CPU, "pauth", "off", .optional = true}, +}; +const size_t arm_rhel9_compat_len = G_N_ELEMENTS(arm_rhel9_compat); + +/* + * This variable is for changes to properties that are RHEL specific, + * different to the current upstream and to be applied to the latest + * machine type. They may be overriden by older machine compats. + * + * virtio-net-pci variant romfiles are not needed because edk2 does + * fully support the pxe boot. Besides virtio romfiles are not shipped + * on rhel/aarch64. + */ +GlobalProperty arm_rhel_compat[] = { + {"virtio-net-pci", "romfile", "" }, + {"virtio-net-pci-transitional", "romfile", "" }, + {"virtio-net-pci-non-transitional", "romfile", "" }, +}; +const size_t arm_rhel_compat_len = G_N_ELEMENTS(arm_rhel_compat); + /* * This cannot be called from the virt_machine_class_init() because * TYPE_VIRT_MACHINE is abstract and mc->compat_props g_ptr_array_new() @@ -106,6 +132,8 @@ static void arm_virt_compat_set(MachineClass *mc) { compat_props_add(mc->compat_props, arm_virt_compat, arm_virt_compat_len); + compat_props_add(mc->compat_props, arm_rhel_compat, + arm_rhel_compat_len); } #define DEFINE_VIRT_MACHINE_IMPL(latest, ...) \ @@ -116,10 +144,11 @@ static void arm_virt_compat_set(MachineClass *mc) MachineClass *mc = MACHINE_CLASS(oc); \ arm_virt_compat_set(mc); \ MACHINE_VER_SYM(options, virt, __VA_ARGS__)(mc); \ - mc->desc = "QEMU " MACHINE_VER_STR(__VA_ARGS__) " ARM Virtual Machine"; \ + mc->desc = "RHEL " MACHINE_VER_STR(__VA_ARGS__) " ARM Virtual Machine"; \ MACHINE_VER_DEPRECATION(__VA_ARGS__); \ if (latest) { \ mc->alias = "virt"; \ + mc->is_default = 1; \ } \ } \ static const TypeInfo MACHINE_VER_SYM(info, virt, __VA_ARGS__) = \ @@ -135,10 +164,10 @@ static void arm_virt_compat_set(MachineClass *mc) } \ type_init(MACHINE_VER_SYM(register, virt, __VA_ARGS__)); -#define DEFINE_VIRT_MACHINE_AS_LATEST(major, minor) \ - DEFINE_VIRT_MACHINE_IMPL(true, major, minor) -#define DEFINE_VIRT_MACHINE(major, minor) \ - DEFINE_VIRT_MACHINE_IMPL(false, major, minor) +#define DEFINE_VIRT_MACHINE_AS_LATEST(major, minor, micro) \ + DEFINE_VIRT_MACHINE_IMPL(true, major, minor, micro) +#define DEFINE_VIRT_MACHINE(major, minor, micro) \ + DEFINE_VIRT_MACHINE_IMPL(false, major, minor, micro) /* Number of external interrupt lines to configure the GIC with */ @@ -1746,16 +1775,26 @@ static void virt_build_smbios(VirtMachineState *vms) { MachineClass *mc = MACHINE_GET_CLASS(vms); MachineState *ms = MACHINE(vms); + VirtMachineClass *vmc = VIRT_MACHINE_GET_CLASS(vms); uint8_t *smbios_tables, *smbios_anchor; size_t smbios_tables_len, smbios_anchor_len; struct smbios_phys_mem_area mem_array; + const char *manufacturer = "QEMU"; const char *product = "QEMU Virtual Machine"; + const char *version = mc->name; if (kvm_enabled()) { product = "KVM Virtual Machine"; } - smbios_set_defaults("QEMU", product, mc->name, NULL, NULL); + if (!vmc->manufacturer_product_compat) { + manufacturer = "Red Hat"; + product = "KVM"; + version = mc->desc; + } + + smbios_set_defaults(manufacturer, product, version, + NULL, NULL); /* build the array of physical mem area from base_memmap */ mem_array.address = vms->memmap[VIRT_MEM].base; @@ -2517,6 +2556,7 @@ static void machvirt_init(MachineState *machine) qemu_add_machine_init_done_notifier(&vms->machine_done); } +#if 0 /* Disabled for Red Hat Enterprise Linux */ static bool virt_get_secure(Object *obj, Error **errp) { VirtMachineState *vms = VIRT_MACHINE(obj); @@ -2544,6 +2584,7 @@ static void virt_set_virt(Object *obj, bool value, Error **errp) vms->virt = value; } +#endif /* disabled for RHEL */ static bool virt_get_highmem(Object *obj, Error **errp) { @@ -2559,6 +2600,7 @@ static void virt_set_highmem(Object *obj, bool value, Error **errp) vms->highmem = value; } +#if 0 /* Disabled for Red Hat Enterprise Linux */ static bool virt_get_compact_highmem(Object *obj, Error **errp) { VirtMachineState *vms = VIRT_MACHINE(obj); @@ -2572,6 +2614,7 @@ static void virt_set_compact_highmem(Object *obj, bool value, Error **errp) vms->highmem_compact = value; } +#endif /* disabled for RHEL */ static bool virt_get_highmem_redists(Object *obj, Error **errp) { @@ -2664,6 +2707,7 @@ static void virt_set_its(Object *obj, bool value, Error **errp) vms->its = value; } +#if 0 /* Disabled for Red Hat Enterprise Linux */ static bool virt_get_dtb_randomness(Object *obj, Error **errp) { VirtMachineState *vms = VIRT_MACHINE(obj); @@ -2677,6 +2721,7 @@ static void virt_set_dtb_randomness(Object *obj, bool value, Error **errp) vms->dtb_randomness = value; } +#endif /* disabled for RHEL */ static char *virt_get_oem_id(Object *obj, Error **errp) { @@ -2760,6 +2805,7 @@ static void virt_set_ras(Object *obj, bool value, Error **errp) vms->ras = value; } +#if 0 /* Disabled for Red Hat Enterprise Linux */ static bool virt_get_mte(Object *obj, Error **errp) { VirtMachineState *vms = VIRT_MACHINE(obj); @@ -2773,6 +2819,7 @@ static void virt_set_mte(Object *obj, bool value, Error **errp) vms->mte = value; } +#endif /* disabled for RHEL */ static char *virt_get_gic_version(Object *obj, Error **errp) { @@ -3213,16 +3260,16 @@ static void virt_machine_class_init(ObjectClass *oc, const void *data) NULL }; + mc->family = "virt-rhel-Z"; mc->init = machvirt_init; - /* Start with max_cpus set to 512, which is the maximum supported by KVM. - * The value may be reduced later when we have more information about the - * configuration of the particular instance. - */ - mc->max_cpus = 512; + /* Maximum supported VCPU count for all virt-rhel* machines */ + mc->max_cpus = 384; +#if 0 /* Disabled for Red Hat Enterprise Linux */ machine_class_allow_dynamic_sysbus_dev(mc, TYPE_VFIO_CALXEDA_XGMAC); machine_class_allow_dynamic_sysbus_dev(mc, TYPE_VFIO_AMD_XGBE); - machine_class_allow_dynamic_sysbus_dev(mc, TYPE_RAMFB_DEVICE); machine_class_allow_dynamic_sysbus_dev(mc, TYPE_VFIO_PLATFORM); +#endif + machine_class_allow_dynamic_sysbus_dev(mc, TYPE_RAMFB_DEVICE); machine_class_allow_dynamic_sysbus_dev(mc, TYPE_UEFI_VARS_SYSBUS); #ifdef CONFIG_TPM machine_class_allow_dynamic_sysbus_dev(mc, TYPE_TPM_TIS_SYSBUS); @@ -3234,11 +3281,7 @@ static void virt_machine_class_init(ObjectClass *oc, const void *data) mc->minimum_page_bits = 12; mc->possible_cpu_arch_ids = virt_possible_cpu_arch_ids; mc->cpu_index_to_instance_props = virt_cpu_index_to_props; -#ifdef CONFIG_TCG - mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-a15"); -#else - mc->default_cpu_type = ARM_CPU_TYPE_NAME("max"); -#endif + mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-a57"); mc->valid_cpu_types = valid_cpu_types; mc->get_default_cpu_node_id = virt_get_default_cpu_node_id; mc->kvm_type = virt_kvm_type; @@ -3263,6 +3306,7 @@ static void virt_machine_class_init(ObjectClass *oc, const void *data) NULL, NULL); object_class_property_set_description(oc, "acpi", "Enable ACPI"); +#if 0 /* disabled for RHEL */ object_class_property_add_bool(oc, "secure", virt_get_secure, virt_set_secure); object_class_property_set_description(oc, "secure", @@ -3275,6 +3319,7 @@ static void virt_machine_class_init(ObjectClass *oc, const void *data) "Set on/off to enable/disable emulating a " "guest CPU which implements the ARM " "Virtualization Extensions"); +#endif /* disabled for RHEL */ object_class_property_add_bool(oc, "highmem", virt_get_highmem, virt_set_highmem); @@ -3282,12 +3327,14 @@ static void virt_machine_class_init(ObjectClass *oc, const void *data) "Set on/off to enable/disable using " "physical address space above 32 bits"); +#if 0 /* disabled for RHEL */ object_class_property_add_bool(oc, "compact-highmem", virt_get_compact_highmem, virt_set_compact_highmem); object_class_property_set_description(oc, "compact-highmem", "Set on/off to enable/disable compact " "layout for high memory regions"); +#endif /* disabled for RHEL */ object_class_property_add_bool(oc, "highmem-redists", virt_get_highmem_redists, @@ -3323,7 +3370,7 @@ static void virt_machine_class_init(ObjectClass *oc, const void *data) virt_set_gic_version); object_class_property_set_description(oc, "gic-version", "Set GIC version. " - "Valid values are 2, 3, 4, host and max"); + "Valid values are 2, 3, host and max"); object_class_property_add_str(oc, "iommu", virt_get_iommu, virt_set_iommu); object_class_property_set_description(oc, "iommu", @@ -3343,11 +3390,13 @@ static void virt_machine_class_init(ObjectClass *oc, const void *data) "Set on/off to enable/disable reporting host memory errors " "to a KVM guest using ACPI and guest external abort exceptions"); +#if 0 /* disabled for RHEL */ object_class_property_add_bool(oc, "mte", virt_get_mte, virt_set_mte); object_class_property_set_description(oc, "mte", "Set on/off to enable/disable emulating a " "guest CPU which implements the ARM " "Memory Tagging Extension"); +#endif /* disabled for RHEL */ object_class_property_add_bool(oc, "its", virt_get_its, virt_set_its); @@ -3355,6 +3404,7 @@ static void virt_machine_class_init(ObjectClass *oc, const void *data) "Set on/off to enable/disable " "ITS instantiation"); +#if 0 /* disabled for RHEL */ object_class_property_add_bool(oc, "dtb-randomness", virt_get_dtb_randomness, virt_set_dtb_randomness); @@ -3367,6 +3417,7 @@ static void virt_machine_class_init(ObjectClass *oc, const void *data) virt_set_dtb_randomness); object_class_property_set_description(oc, "dtb-kaslr-seed", "Deprecated synonym of dtb-randomness"); +#endif /* disabled for RHEL */ object_class_property_add_str(oc, "x-oem-id", virt_get_oem_id, @@ -3636,3 +3687,70 @@ static void virt_machine_4_1_options(MachineClass *mc) } DEFINE_VIRT_MACHINE(4, 1) #endif /* disabled for RHEL */ + +static void virt_rhel_machine_10_0_0_options(MachineClass *mc) +{ + VirtMachineClass *vmc = VIRT_MACHINE_CLASS(OBJECT_CLASS(mc)); + + /* QEMU 9.1 and earlier have only a stage-1 SMMU, not a nested s1+2 one */ + vmc->no_nested_smmu = true; + compat_props_add(mc->compat_props, hw_compat_rhel_10_2, hw_compat_rhel_10_2_len); + compat_props_add(mc->compat_props, hw_compat_rhel_10_1, hw_compat_rhel_10_1_len); +} +DEFINE_VIRT_MACHINE_AS_LATEST(10, 0, 0) + +static void virt_rhel_machine_9_6_0_options(MachineClass *mc) +{ + virt_rhel_machine_10_0_0_options(mc); + + compat_props_add(mc->compat_props, arm_rhel9_compat, arm_rhel9_compat_len); + /* NB: remember to move this line to the *latest* RHEL 9 machine */ + compat_props_add(mc->compat_props, hw_compat_rhel_9, hw_compat_rhel_9_len); +} +DEFINE_VIRT_MACHINE(9, 6, 0) + +static void virt_rhel_machine_9_4_0_options(MachineClass *mc) +{ + VirtMachineClass *vmc = VIRT_MACHINE_CLASS(OBJECT_CLASS(mc)); + + virt_rhel_machine_9_6_0_options(mc); + + /* From virt_machine_9_0_options() */ + mc->smbios_memory_device_size = 16 * GiB; + + compat_props_add(mc->compat_props, hw_compat_rhel_10_0, hw_compat_rhel_10_0_len); + compat_props_add(mc->compat_props, hw_compat_rhel_9_5, hw_compat_rhel_9_5_len); + + vmc->manufacturer_product_compat = true; +} +DEFINE_VIRT_MACHINE(9, 4, 0) + +static void virt_rhel_machine_9_2_0_options(MachineClass *mc) +{ + virt_rhel_machine_9_4_0_options(mc); + + compat_props_add(mc->compat_props, hw_compat_rhel_9_4, hw_compat_rhel_9_4_len); + compat_props_add(mc->compat_props, hw_compat_rhel_9_3, hw_compat_rhel_9_3_len); + compat_props_add(mc->compat_props, hw_compat_rhel_9_2, hw_compat_rhel_9_2_len); + + /* RHEL 9.4 is the first supported release */ + mc->deprecation_reason = + "machine types for versions prior to 9.4 are deprecated"; +} +DEFINE_VIRT_MACHINE(9, 2, 0) + +static void virt_rhel_machine_9_0_0_options(MachineClass *mc) +{ + VirtMachineClass *vmc = VIRT_MACHINE_CLASS(OBJECT_CLASS(mc)); + + virt_rhel_machine_9_2_0_options(mc); + + compat_props_add(mc->compat_props, hw_compat_rhel_9_1, hw_compat_rhel_9_1_len); + compat_props_add(mc->compat_props, hw_compat_rhel_9_0, hw_compat_rhel_9_0_len); + + /* Disable FEAT_LPA2 since old kernels (<= v5.12) don't boot with that feature */ + vmc->no_tcg_lpa2 = true; + /* Compact layout for high memory regions was introduced with 9.2.0 */ + vmc->no_highmem_compact = true; +} +DEFINE_VIRT_MACHINE(9, 0, 0) diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h index 365a28b082..94c79d6c6d 100644 --- a/include/hw/arm/virt.h +++ b/include/hw/arm/virt.h @@ -132,6 +132,7 @@ struct VirtMachineClass { bool no_tcg_lpa2; bool no_ns_el2_virt_timer_irq; bool no_nested_smmu; + bool manufacturer_product_compat; }; struct VirtMachineState { -- 2.39.3