From be3ca54f04ade6a20265f9aeeb46662caa6d16dc Mon Sep 17 00:00:00 2001 From: Miroslav Rezanina Date: Fri, 19 Oct 2018 12:53:31 +0200 Subject: Add aarch64 machine types Adding changes to add RHEL machine types for aarch64 architecture. Signed-off-by: Miroslav Rezanina Rebase notes (4.0.0): - Use upstream compat handling Rebase notes (4.1.0-rc0): - Removed a15memmap (upstream) - Use virt_flash_create in rhel800_virt_instance_init Rebase notes (4.2.0-rc0): - Set numa_mem_supported Rebase notes (4.2.0-rc3): - aarch64: Add virt-rhel8.2.0 machine type for ARM (patch 92246) - aarch64: virt: Allow more than 1TB of RAM (patch 92249) - aarch64: virt: Allow PCDIMM instantiation (patch 92247) - aarch64: virt: Enhance the comment related to gic-version (patch 92248) Rebase notes (5.0.0): - Set default_ram_id in rhel_machine_class_init - Added setting acpi properties Rebase notes (5.1.0): - Added ras property - Added to virt_machine_device_unplug_cb to machine type (upstream) - added mte property (upstream) Merged patches (4.0.0): - 7bfdb4c aarch64: Add virt-rhel8.0.0 machine type for ARM - 3433e69 aarch64: Set virt-rhel8.0.0 max_cpus to 512 - 4d20863 aarch64: Use 256MB ECAM region by default Merged patches (4.1.0): - c3e39ef aarch64: Add virt-rhel8.1.0 machine type for ARM - 59a46d1 aarch64: Allow ARM VIRT iommu option in RHEL8.1 machine Merged patches (5.2.0 rc0): - 12990ad hw/arm: Changes to rhel820 machine - 46d5a79 hw/arm: Introduce rhel_virt_instance_init() helper - 098954a hw/arm: Add rhel830 machine type - ee8e99d arm: Set correct max_cpus value on virt-rhel* machine types - e5edd38 RHEL-only: arm/virt: Allow the TPM_TIS_SYSBUS device dynamic allocation in machvirt - 6d7ba66 machine types/numa: set numa_mem_supported on old machine types (partialy) - 25c5644 machine_types/numa: compatibility for auto_enable_numa_with_memdev (partialy) --- hw/arm/virt.c | 191 +++++++++++++++++++++++++++++++++++++++++++++++++- include/hw/arm/virt.h | 8 +++ 2 files changed, 196 insertions(+), 3 deletions(-) diff --git a/hw/arm/virt.c b/hw/arm/virt.c index c908b5f..21e0485 100644 --- a/hw/arm/virt.c +++ b/hw/arm/virt.c @@ -79,6 +79,7 @@ #include "hw/char/pl011.h" #include "qemu/guest-random.h" +#if 0 /* Disabled for Red Hat Enterprise Linux */ #define DEFINE_VIRT_MACHINE_LATEST(major, minor, latest) \ static void virt_##major##_##minor##_class_init(ObjectClass *oc, \ void *data) \ @@ -105,7 +106,49 @@ DEFINE_VIRT_MACHINE_LATEST(major, minor, true) #define DEFINE_VIRT_MACHINE(major, minor) \ DEFINE_VIRT_MACHINE_LATEST(major, minor, false) - +#endif /* disabled for RHEL */ + +#define DEFINE_RHEL_MACHINE_LATEST(m, n, s, latest) \ + static void rhel##m##n##s##_virt_class_init(ObjectClass *oc, \ + void *data) \ + { \ + MachineClass *mc = MACHINE_CLASS(oc); \ + rhel##m##n##s##_virt_options(mc); \ + mc->desc = "RHEL " # m "." # n "." # s " ARM Virtual Machine"; \ + if (latest) { \ + mc->alias = "virt"; \ + mc->is_default = 1; \ + } \ + } \ + static const TypeInfo rhel##m##n##s##_machvirt_info = { \ + .name = MACHINE_TYPE_NAME("virt-rhel" # m "." # n "." # s), \ + .parent = TYPE_RHEL_MACHINE, \ + .instance_init = rhel##m##n##s##_virt_instance_init, \ + .class_init = rhel##m##n##s##_virt_class_init, \ + }; \ + static void rhel##m##n##s##_machvirt_init(void) \ + { \ + type_register_static(&rhel##m##n##s##_machvirt_info); \ + } \ + type_init(rhel##m##n##s##_machvirt_init); + +#define DEFINE_RHEL_MACHINE_AS_LATEST(major, minor, subminor) \ + DEFINE_RHEL_MACHINE_LATEST(major, minor, subminor, true) +#define DEFINE_RHEL_MACHINE(major, minor, subminor) \ + DEFINE_RHEL_MACHINE_LATEST(major, minor, subminor, false) + +/* 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. + */ +GlobalProperty arm_rhel_compat[] = { + { + .driver = "virtio-net-pci", + .property = "romfile", + .value = "", + }, +}; +const size_t arm_rhel_compat_len = G_N_ELEMENTS(arm_rhel_compat); /* Number of external interrupt lines to configure the GIC with */ #define NUM_IRQS 256 @@ -2027,6 +2070,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); @@ -2055,6 +2099,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) { VirtMachineState *vms = VIRT_MACHINE(obj); @@ -2108,6 +2153,7 @@ static void virt_set_acpi(Object *obj, Visitor *v, const char *name, visit_type_OnOffAuto(v, name, &vms->acpi, errp); } +#if 0 /* Disabled for Red Hat Enterprise Linux */ static bool virt_get_ras(Object *obj, Error **errp) { VirtMachineState *vms = VIRT_MACHINE(obj); @@ -2121,13 +2167,14 @@ 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); return vms->mte; } +#endif /* disabled for RHEL */ static void virt_set_mte(Object *obj, bool value, Error **errp) { @@ -2135,7 +2182,7 @@ static void virt_set_mte(Object *obj, bool value, Error **errp) vms->mte = value; } - +#endif static char *virt_get_gic_version(Object *obj, Error **errp) { VirtMachineState *vms = VIRT_MACHINE(obj); @@ -2442,6 +2489,7 @@ static int virt_kvm_type(MachineState *ms, const char *type_str) return requested_pa_size > 40 ? requested_pa_size : 0; } +#if 0 /* Disabled for Red Hat Enterprise Linux */ static void virt_machine_class_init(ObjectClass *oc, void *data) { MachineClass *mc = MACHINE_CLASS(oc); @@ -2730,3 +2778,140 @@ static void virt_machine_2_6_options(MachineClass *mc) vmc->no_pmu = true; } DEFINE_VIRT_MACHINE(2, 6) +#endif /* disabled for RHEL */ + +static void rhel_machine_class_init(ObjectClass *oc, void *data) +{ + MachineClass *mc = MACHINE_CLASS(oc); + HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(oc); + + mc->family = "virt-rhel-Z"; + mc->init = machvirt_init; + /* Maximum supported VCPU count for all virt-rhel* machines */ + mc->max_cpus = 384; + machine_class_allow_dynamic_sysbus_dev(mc, TYPE_TPM_TIS_SYSBUS); + mc->block_default_type = IF_VIRTIO; + mc->no_cdrom = 1; + mc->pci_allow_0_address = true; + /* We know we will never create a pre-ARMv7 CPU which needs 1K pages */ + 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; + mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-a57"); + mc->get_default_cpu_node_id = virt_get_default_cpu_node_id; + mc->kvm_type = virt_kvm_type; + assert(!mc->get_hotplug_handler); + mc->get_hotplug_handler = virt_machine_get_hotplug_handler; + hc->pre_plug = virt_machine_device_pre_plug_cb; + hc->plug = virt_machine_device_plug_cb; + hc->unplug_request = virt_machine_device_unplug_request_cb; + hc->unplug = virt_machine_device_unplug_cb; + mc->nvdimm_supported = true; + mc->auto_enable_numa_with_memhp = true; + mc->auto_enable_numa_with_memdev = true; + mc->default_ram_id = "mach-virt.ram"; + + object_class_property_add(oc, "acpi", "OnOffAuto", + virt_get_acpi, virt_set_acpi, + NULL, NULL); + object_class_property_set_description(oc, "acpi", + "Enable ACPI"); +} + +static const TypeInfo rhel_machine_info = { + .name = TYPE_RHEL_MACHINE, + .parent = TYPE_MACHINE, + .abstract = true, + .instance_size = sizeof(VirtMachineState), + .class_size = sizeof(VirtMachineClass), + .class_init = rhel_machine_class_init, + .interfaces = (InterfaceInfo[]) { + { TYPE_HOTPLUG_HANDLER }, + { } + }, +}; + +static void rhel_machine_init(void) +{ + type_register_static(&rhel_machine_info); +} +type_init(rhel_machine_init); + +static void rhel_virt_instance_init(Object *obj) +{ + VirtMachineState *vms = VIRT_MACHINE(obj); + VirtMachineClass *vmc = VIRT_MACHINE_GET_CLASS(vms); + + /* EL3 is disabled by default and non-configurable for RHEL */ + vms->secure = false; + /* EL2 is disabled by default and non-configurable for RHEL */ + vms->virt = false; + /* High memory is enabled by default for RHEL */ + vms->highmem = true; + object_property_add_bool(obj, "highmem", virt_get_highmem, + virt_set_highmem); + object_property_set_description(obj, "highmem", + "Set on/off to enable/disable using " + "physical address space above 32 bits"); + + vms->gic_version = VIRT_GIC_VERSION_NOSEL; + object_property_add_str(obj, "gic-version", virt_get_gic_version, + virt_set_gic_version); + object_property_set_description(obj, "gic-version", + "Set GIC version. " + "Valid values are 2, 3 and host"); + + vms->highmem_ecam = !vmc->no_highmem_ecam; + + if (vmc->no_its) { + vms->its = false; + } else { + /* Default allows ITS instantiation */ + vms->its = true; + object_property_add_bool(obj, "its", virt_get_its, + virt_set_its); + object_property_set_description(obj, "its", + "Set on/off to enable/disable " + "ITS instantiation"); + } + + /* Default disallows iommu instantiation */ + vms->iommu = VIRT_IOMMU_NONE; + object_property_add_str(obj, "iommu", virt_get_iommu, virt_set_iommu); + object_property_set_description(obj, "iommu", + "Set the IOMMU type. " + "Valid values are none and smmuv3"); + + vms->ras = false; + /* MTE is disabled by default. */ + vms->mte = false; + + vms->irqmap=a15irqmap; + virt_flash_create(vms); +} + +static void rhel830_virt_instance_init(Object *obj) +{ + rhel_virt_instance_init(obj); +} + +static void rhel830_virt_options(MachineClass *mc) +{ + compat_props_add(mc->compat_props, arm_rhel_compat, arm_rhel_compat_len); +} +DEFINE_RHEL_MACHINE_AS_LATEST(8, 3, 0) + +static void rhel820_virt_instance_init(Object *obj) +{ + rhel_virt_instance_init(obj); +} + +static void rhel820_virt_options(MachineClass *mc) +{ + rhel830_virt_options(mc); + compat_props_add(mc->compat_props, hw_compat_rhel_8_2, + hw_compat_rhel_8_2_len); + mc->numa_mem_supported = true; + mc->auto_enable_numa_with_memdev = false; +} +DEFINE_RHEL_MACHINE(8, 2, 0) diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h index aad6d69..745b76b 100644 --- a/include/hw/arm/virt.h +++ b/include/hw/arm/virt.h @@ -167,9 +167,17 @@ struct VirtMachineState { #define VIRT_ECAM_ID(high) (high ? VIRT_HIGH_PCIE_ECAM : VIRT_PCIE_ECAM) +#if 0 /* disabled for Red Hat Enterprise Linux */ #define TYPE_VIRT_MACHINE MACHINE_TYPE_NAME("virt") OBJECT_DECLARE_TYPE(VirtMachineState, VirtMachineClass, VIRT_MACHINE) +#else +#define TYPE_RHEL_MACHINE MACHINE_TYPE_NAME("virt-rhel") +typedef struct VirtMachineClass VirtMachineClass; +typedef struct VirtMachineState VirtMachineState; +DECLARE_OBJ_CHECKERS(VirtMachineState, VirtMachineClass, VIRT_MACHINE, TYPE_RHEL_MACHINE) +#endif + void virt_acpi_setup(VirtMachineState *vms); bool virt_is_acpi_enabled(VirtMachineState *vms); -- 1.8.3.1