From 9da015b8759b082330459277058c014e71bff62b 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 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 | 152 ++++++++++++++++++++++++++++++++++++------ include/hw/arm/virt.h | 1 + 2 files changed, 134 insertions(+), 19 deletions(-) diff --git a/hw/arm/virt.c b/hw/arm/virt.c index 6d5ea31e46..12bf754b6a 100644 --- a/hw/arm/virt.c +++ b/hw/arm/virt.c @@ -93,6 +93,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() @@ -102,6 +128,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, ...) \ @@ -112,10 +140,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__) = \ @@ -131,10 +160,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 */ @@ -1708,14 +1737,21 @@ static void virt_build_smbios(VirtMachineState *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 = vmc->smbios_old_sys_ver ? "1.0" : mc->name; if (kvm_enabled()) { product = "KVM Virtual Machine"; } - smbios_set_defaults("QEMU", product, - vmc->smbios_old_sys_ver ? "1.0" : mc->name, + 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 */ @@ -2464,6 +2500,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); @@ -2491,6 +2528,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) { @@ -2506,6 +2544,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); @@ -2519,6 +2558,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) { @@ -2611,6 +2651,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); @@ -2624,6 +2665,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) { @@ -2707,6 +2749,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); @@ -2720,6 +2763,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) { @@ -3160,16 +3204,16 @@ static void virt_machine_class_init(ObjectClass *oc, 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); @@ -3181,11 +3225,7 @@ static void virt_machine_class_init(ObjectClass *oc, 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; @@ -3210,6 +3250,7 @@ static void virt_machine_class_init(ObjectClass *oc, 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", @@ -3222,6 +3263,7 @@ static void virt_machine_class_init(ObjectClass *oc, 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); @@ -3229,12 +3271,14 @@ static void virt_machine_class_init(ObjectClass *oc, 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, @@ -3270,7 +3314,7 @@ static void virt_machine_class_init(ObjectClass *oc, 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", @@ -3290,11 +3334,13 @@ static void virt_machine_class_init(ObjectClass *oc, 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); @@ -3302,6 +3348,7 @@ static void virt_machine_class_init(ObjectClass *oc, 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); @@ -3314,6 +3361,7 @@ static void virt_machine_class_init(ObjectClass *oc, 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, @@ -3679,3 +3727,69 @@ static void virt_machine_2_6_options(MachineClass *mc) } DEFINE_VIRT_MACHINE(2, 6) #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_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 c8e94e6aed..26cfdf1d41 100644 --- a/include/hw/arm/virt.h +++ b/include/hw/arm/virt.h @@ -135,6 +135,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