From e289655cea93bd50856a0896e2d49e5c7ed10c3b Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Fri, 29 May 2020 09:39:54 +0200 Subject: [PATCH 1/4] microvm: use 3G split unconditionally MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Looks like the logic was copied over from q35. q35 does this for backward compatibility, there is no reason to do this on microvm though. Also microvm doesn't need much mmio space, 1G is more than enough. Using an mmio window smaller than 1G is bad for gigabyte alignment and hugepages though. So split @ 3G unconditionally. Signed-off-by: Gerd Hoffmann Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Igor Mammedov Acked-by: Paolo Bonzini Reviewed-by: Michael S. Tsirkin Message-id: 20200529073957.8018-2-kraxel@redhat.com --- hw/i386/microvm.c | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) diff --git a/hw/i386/microvm.c b/hw/i386/microvm.c index 937db10ae6..44f940813b 100644 --- a/hw/i386/microvm.c +++ b/hw/i386/microvm.c @@ -170,23 +170,9 @@ static void microvm_memory_init(MicrovmMachineState *mms) MemoryRegion *ram_below_4g, *ram_above_4g; MemoryRegion *system_memory = get_system_memory(); FWCfgState *fw_cfg; - ram_addr_t lowmem; + ram_addr_t lowmem = 0xc0000000; /* 3G */ int i; - /* - * Check whether RAM fits below 4G (leaving 1/2 GByte for IO memory - * and 256 Mbytes for PCI Express Enhanced Configuration Access Mapping - * also known as MMCFG). - * If it doesn't, we need to split it in chunks below and above 4G. - * In any case, try to make sure that guest addresses aligned at - * 1G boundaries get mapped to host addresses aligned at 1G boundaries. - */ - if (machine->ram_size >= 0xb0000000) { - lowmem = 0x80000000; - } else { - lowmem = 0xb0000000; - } - /* * Handle the machine opt max-ram-below-4g. It is basically doing * min(qemu limit, user limit). From 3235936e306b5eae6291907e4d675f226707fd14 Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Fri, 29 May 2020 09:39:55 +0200 Subject: [PATCH 2/4] microvm: drop max-ram-below-4g support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Not useful for microvm and allows users to shoot themself into the foot (make ram + mmio overlap). Signed-off-by: Gerd Hoffmann Reviewed-by: Igor Mammedov Acked-by: Paolo Bonzini Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Michael S. Tsirkin Message-id: 20200529073957.8018-3-kraxel@redhat.com --- hw/i386/microvm.c | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/hw/i386/microvm.c b/hw/i386/microvm.c index 44f940813b..5e931975a0 100644 --- a/hw/i386/microvm.c +++ b/hw/i386/microvm.c @@ -173,25 +173,6 @@ static void microvm_memory_init(MicrovmMachineState *mms) ram_addr_t lowmem = 0xc0000000; /* 3G */ int i; - /* - * Handle the machine opt max-ram-below-4g. It is basically doing - * min(qemu limit, user limit). - */ - if (!x86ms->max_ram_below_4g) { - x86ms->max_ram_below_4g = 4 * GiB; - } - if (lowmem > x86ms->max_ram_below_4g) { - lowmem = x86ms->max_ram_below_4g; - if (machine->ram_size - lowmem > lowmem && - lowmem & (1 * GiB - 1)) { - warn_report("There is possibly poor performance as the ram size " - " (0x%" PRIx64 ") is more then twice the size of" - " max-ram-below-4g (%"PRIu64") and" - " max-ram-below-4g is not a multiple of 1G.", - (uint64_t)machine->ram_size, x86ms->max_ram_below_4g); - } - } - if (machine->ram_size > lowmem) { x86ms->above_4g_mem_size = machine->ram_size - lowmem; x86ms->below_4g_mem_size = lowmem; From 9a45729d3bfcc87a23efaab84092473e770d900b Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Fri, 29 May 2020 09:39:56 +0200 Subject: [PATCH 3/4] x86: move max-ram-below-4g to pc MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Move from X86MachineClass to PCMachineClass so it disappears from microvm machine type property list. Signed-off-by: Gerd Hoffmann Reviewed-by: Philippe Mathieu-Daudé Acked-by: Paolo Bonzini Reviewed-by: Michael S. Tsirkin Reviewed-by: Igor Mammedov Reviewed-by: Paul Durrant Message-id: 20200529073957.8018-4-kraxel@redhat.com --- hw/i386/pc.c | 46 +++++++++++++++++++++++++++++++++++++++++++ hw/i386/pc_piix.c | 10 +++++----- hw/i386/pc_q35.c | 10 +++++----- hw/i386/x86.c | 46 ------------------------------------------- hw/i386/xen/xen-hvm.c | 2 +- include/hw/i386/pc.h | 2 ++ include/hw/i386/x86.h | 4 ---- 7 files changed, 59 insertions(+), 61 deletions(-) diff --git a/hw/i386/pc.c b/hw/i386/pc.c index ec39741c87..d103b8c0ab 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -1857,6 +1857,45 @@ static void pc_machine_set_pit(Object *obj, bool value, Error **errp) pcms->pit_enabled = value; } +static void pc_machine_get_max_ram_below_4g(Object *obj, Visitor *v, + const char *name, void *opaque, + Error **errp) +{ + PCMachineState *pcms = PC_MACHINE(obj); + uint64_t value = pcms->max_ram_below_4g; + + visit_type_size(v, name, &value, errp); +} + +static void pc_machine_set_max_ram_below_4g(Object *obj, Visitor *v, + const char *name, void *opaque, + Error **errp) +{ + PCMachineState *pcms = PC_MACHINE(obj); + Error *error = NULL; + uint64_t value; + + visit_type_size(v, name, &value, &error); + if (error) { + error_propagate(errp, error); + return; + } + if (value > 4 * GiB) { + error_setg(&error, + "Machine option 'max-ram-below-4g=%"PRIu64 + "' expects size less than or equal to 4G", value); + error_propagate(errp, error); + return; + } + + if (value < 1 * MiB) { + warn_report("Only %" PRIu64 " bytes of RAM below the 4GiB boundary," + "BIOS may not work with less than 1MiB", value); + } + + pcms->max_ram_below_4g = value; +} + static void pc_machine_initfn(Object *obj) { PCMachineState *pcms = PC_MACHINE(obj); @@ -1866,6 +1905,7 @@ static void pc_machine_initfn(Object *obj) #else pcms->vmport = ON_OFF_AUTO_OFF; #endif /* CONFIG_VMPORT */ + pcms->max_ram_below_4g = 0; /* use default */ /* acpi build is enabled by default if machine supports it */ pcms->acpi_build_enabled = PC_MACHINE_GET_CLASS(pcms)->has_acpi_build; pcms->smbus_enabled = true; @@ -1964,6 +2004,12 @@ static void pc_machine_class_init(ObjectClass *oc, void *data) mc->numa_mem_supported = true; mc->default_ram_id = "pc.ram"; + object_class_property_add(oc, PC_MACHINE_MAX_RAM_BELOW_4G, "size", + pc_machine_get_max_ram_below_4g, pc_machine_set_max_ram_below_4g, + NULL, NULL); + object_class_property_set_description(oc, PC_MACHINE_MAX_RAM_BELOW_4G, + "Maximum ram below the 4G boundary (32bit boundary)"); + object_class_property_add(oc, PC_MACHINE_DEVMEM_REGION_SIZE, "int", pc_machine_get_device_memory_region_size, NULL, NULL, NULL); diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c index 054d3aa9f7..1497d0e4ae 100644 --- a/hw/i386/pc_piix.c +++ b/hw/i386/pc_piix.c @@ -129,11 +129,11 @@ static void pc_init1(MachineState *machine, if (xen_enabled()) { xen_hvm_init(pcms, &ram_memory); } else { - if (!x86ms->max_ram_below_4g) { - x86ms->max_ram_below_4g = 0xe0000000; /* default: 3.5G */ + if (!pcms->max_ram_below_4g) { + pcms->max_ram_below_4g = 0xe0000000; /* default: 3.5G */ } - lowmem = x86ms->max_ram_below_4g; - if (machine->ram_size >= x86ms->max_ram_below_4g) { + lowmem = pcms->max_ram_below_4g; + if (machine->ram_size >= pcms->max_ram_below_4g) { if (pcmc->gigabyte_align) { if (lowmem > 0xc0000000) { lowmem = 0xc0000000; @@ -142,7 +142,7 @@ static void pc_init1(MachineState *machine, warn_report("Large machine and max_ram_below_4g " "(%" PRIu64 ") not a multiple of 1G; " "possible bad performance.", - x86ms->max_ram_below_4g); + pcms->max_ram_below_4g); } } } diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c index 18d2fad9c5..46cd06524c 100644 --- a/hw/i386/pc_q35.c +++ b/hw/i386/pc_q35.c @@ -156,18 +156,18 @@ static void pc_q35_init(MachineState *machine) /* Handle the machine opt max-ram-below-4g. It is basically doing * min(qemu limit, user limit). */ - if (!x86ms->max_ram_below_4g) { - x86ms->max_ram_below_4g = 4 * GiB; + if (!pcms->max_ram_below_4g) { + pcms->max_ram_below_4g = 4 * GiB; } - if (lowmem > x86ms->max_ram_below_4g) { - lowmem = x86ms->max_ram_below_4g; + if (lowmem > pcms->max_ram_below_4g) { + lowmem = pcms->max_ram_below_4g; if (machine->ram_size - lowmem > lowmem && lowmem & (1 * GiB - 1)) { warn_report("There is possibly poor performance as the ram size " " (0x%" PRIx64 ") is more then twice the size of" " max-ram-below-4g (%"PRIu64") and" " max-ram-below-4g is not a multiple of 1G.", - (uint64_t)machine->ram_size, x86ms->max_ram_below_4g); + (uint64_t)machine->ram_size, pcms->max_ram_below_4g); } } diff --git a/hw/i386/x86.c b/hw/i386/x86.c index bb31935f70..34229b45c7 100644 --- a/hw/i386/x86.c +++ b/hw/i386/x86.c @@ -846,45 +846,6 @@ void x86_bios_rom_init(MemoryRegion *rom_memory, bool isapc_ram_fw) bios); } -static void x86_machine_get_max_ram_below_4g(Object *obj, Visitor *v, - const char *name, void *opaque, - Error **errp) -{ - X86MachineState *x86ms = X86_MACHINE(obj); - uint64_t value = x86ms->max_ram_below_4g; - - visit_type_size(v, name, &value, errp); -} - -static void x86_machine_set_max_ram_below_4g(Object *obj, Visitor *v, - const char *name, void *opaque, - Error **errp) -{ - X86MachineState *x86ms = X86_MACHINE(obj); - Error *error = NULL; - uint64_t value; - - visit_type_size(v, name, &value, &error); - if (error) { - error_propagate(errp, error); - return; - } - if (value > 4 * GiB) { - error_setg(&error, - "Machine option 'max-ram-below-4g=%"PRIu64 - "' expects size less than or equal to 4G", value); - error_propagate(errp, error); - return; - } - - if (value < 1 * MiB) { - warn_report("Only %" PRIu64 " bytes of RAM below the 4GiB boundary," - "BIOS may not work with less than 1MiB", value); - } - - x86ms->max_ram_below_4g = value; -} - bool x86_machine_is_smm_enabled(X86MachineState *x86ms) { bool smm_available = false; @@ -958,7 +919,6 @@ static void x86_machine_initfn(Object *obj) x86ms->smm = ON_OFF_AUTO_AUTO; x86ms->acpi = ON_OFF_AUTO_AUTO; - x86ms->max_ram_below_4g = 0; /* use default */ x86ms->smp_dies = 1; x86ms->apicid_from_cpu_idx = x86_apicid_from_cpu_idx; @@ -980,12 +940,6 @@ static void x86_machine_class_init(ObjectClass *oc, void *data) x86mc->save_tsc_khz = true; nc->nmi_monitor_handler = x86_nmi; - object_class_property_add(oc, X86_MACHINE_MAX_RAM_BELOW_4G, "size", - x86_machine_get_max_ram_below_4g, x86_machine_set_max_ram_below_4g, - NULL, NULL); - object_class_property_set_description(oc, X86_MACHINE_MAX_RAM_BELOW_4G, - "Maximum ram below the 4G boundary (32bit boundary)"); - object_class_property_add(oc, X86_MACHINE_SMM, "OnOffAuto", x86_machine_get_smm, x86_machine_set_smm, NULL, NULL); diff --git a/hw/i386/xen/xen-hvm.c b/hw/i386/xen/xen-hvm.c index 628bde5fac..cde981bad6 100644 --- a/hw/i386/xen/xen-hvm.c +++ b/hw/i386/xen/xen-hvm.c @@ -205,7 +205,7 @@ static void xen_ram_init(PCMachineState *pcms, ram_addr_t block_len; uint64_t user_lowmem = object_property_get_uint(qdev_get_machine(), - X86_MACHINE_MAX_RAM_BELOW_4G, + PC_MACHINE_MAX_RAM_BELOW_4G, &error_abort); /* Handle the machine opt max-ram-below-4g. It is basically doing diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h index 8d764f965c..e6135c34d6 100644 --- a/include/hw/i386/pc.h +++ b/include/hw/i386/pc.h @@ -35,6 +35,7 @@ struct PCMachineState { PFlashCFI01 *flash[2]; /* Configuration options: */ + uint64_t max_ram_below_4g; OnOffAuto vmport; bool acpi_build_enabled; @@ -51,6 +52,7 @@ struct PCMachineState { }; #define PC_MACHINE_ACPI_DEVICE_PROP "acpi-device" +#define PC_MACHINE_MAX_RAM_BELOW_4G "max-ram-below-4g" #define PC_MACHINE_DEVMEM_REGION_SIZE "device-memory-region-size" #define PC_MACHINE_VMPORT "vmport" #define PC_MACHINE_SMBUS "smbus" diff --git a/include/hw/i386/x86.h b/include/hw/i386/x86.h index b522854816..b79f24e285 100644 --- a/include/hw/i386/x86.h +++ b/include/hw/i386/x86.h @@ -51,9 +51,6 @@ typedef struct { qemu_irq *gsi; GMappedFile *initrd_mapped_file; - /* Configuration options: */ - uint64_t max_ram_below_4g; - /* RAM information (sizes, addresses, configuration): */ ram_addr_t below_4g_mem_size, above_4g_mem_size; @@ -82,7 +79,6 @@ typedef struct { AddressSpace *ioapic_as; } X86MachineState; -#define X86_MACHINE_MAX_RAM_BELOW_4G "max-ram-below-4g" #define X86_MACHINE_SMM "smm" #define X86_MACHINE_ACPI "acpi" From c8b473594b8fbba169a6ea950493a3015d15a18d Mon Sep 17 00:00:00 2001 From: Gerd Hoffmann Date: Fri, 29 May 2020 09:39:57 +0200 Subject: [PATCH 4/4] microvm: move virtio base to 0xfeb00000 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Place virtio-mmio devices near the other mmio regions, next ioapic is at @ 0xfec00000. Signed-off-by: Gerd Hoffmann Reviewed-by: Michael S. Tsirkin Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Igor Mammedov Reviewed-by: Paul Durrant Acked-by: Paolo Bonzini Message-id: 20200529073957.8018-5-kraxel@redhat.com --- include/hw/i386/microvm.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/hw/i386/microvm.h b/include/hw/i386/microvm.h index ba68d1f22b..fd34b78e0d 100644 --- a/include/hw/i386/microvm.h +++ b/include/hw/i386/microvm.h @@ -26,7 +26,7 @@ #include "hw/i386/x86.h" /* Platform virtio definitions */ -#define VIRTIO_MMIO_BASE 0xc0000000 +#define VIRTIO_MMIO_BASE 0xfeb00000 #define VIRTIO_IRQ_BASE 5 #define VIRTIO_NUM_TRANSPORTS 8 #define VIRTIO_CMDLINE_MAXLEN 64