* [Qemu-devel] [PATCH v4 0/3] Add max-ram-below-4g (was Add pci_hole_min_size machine option) @ 2014-06-05 16:11 Don Slutz 2014-06-05 16:11 ` [Qemu-devel] [PATCH v4 1/3] xen-hvm: Fix xen_hvm_init() to adjust pc memory layout Don Slutz ` (2 more replies) 0 siblings, 3 replies; 7+ messages in thread From: Don Slutz @ 2014-06-05 16:11 UTC (permalink / raw) To: xen-devel, qemu-devel, Stefano Stabellini Cc: Don Slutz, Anthony Liguori, Michael S. Tsirkin Changes v3 to v4: Split out #2 "GlobalProperty: Display warning about unused -global" rebase on e00fcfe (origin/master) rename xen-all to xen-hvm Adjust #1 "xen-hvm: Fix xen_hvm_init() to adjust pc memory layout" Switch Acked-by & Signed-off-by rebase on master Rework #3 "xen-hvm: Pass is_default to xen_hvm_init": To pass is_default instead of max_ram_below_4g. Also did not add "Acked-by: Stefano Stabellini" since code changed a lot. Andreas Färber: all: Remove dot at end of subject #3 "xen-hvm: Pass is_default to xen_hvm_init" Adjust comment formatting. Andreas Färber, Paolo Bonzini, Marcel Apfelbaum: rework to use "opts per machine" Drop old #3, new #2. Changes v2 to v3: Stefano Stabellini: Acked-by #1 "xen-all: Fix xen_hvm_init() to adjust pc memory" Adjust for code readability #4 "xen-all: Pass max_ram_below_4g to xen_hvm_init." Set max_ram_below_4g always and use it to calculate above_4g_mem_size, below_4g_mem_size. Changes v1 to v2: Michael S. Tsirkin: Rename option. Only add it to machine types that support it. Split into 4 parts. 1/4 -- xen-all: Fix xen_hvm_init() to adjust pc memory layout This looks to be a possible bug that has yet to be found. below_4g_mem_size and above_4g_mem_size are stored in PcGuestInfo (pc_guest_info_init) which are currently not "correct". This and 4/4 change the same lines. 2/4 -- GlobalProperty: Display warning about unused -global My testing showed that setting a global property on an object that is not used is not reported at all. This is added to help when the new global is set but not used. The negative not_used was picked so that all static objects are assumed to be used even when they are not. 3/4 -- pc & q35: Add new object pc-memory-layout The objects that it might make sense to add this property to all get created too late. So add a new object just to hold this property. Name it so that it is expected that only pc (and q35) machine types support it. 4/4 -- xen-all: Pass max_ram_below_4g to xen_hvm_init Seprate the xen only part of the change. Currectly based on patch 1/4 Don Slutz (3): xen-hvm: Fix xen_hvm_init() to adjust pc memory layout pc & q35: Add new machine opt max-ram-below-4g xen-hvm: Pass is_default to xen_hvm_init hw/core/machine.c | 44 +++++++++++++++ hw/i386/pc.c | 22 ++++++++ hw/i386/pc_piix.c | 115 +++++++++++++++++++++++++++++++++----- hw/i386/pc_q35.c | 65 ++++++++++++++++----- include/hw/boards.h | 1 + include/hw/i386/pc-machine-opts.h | 46 +++++++++++++++ include/hw/xen/xen.h | 3 +- vl.c | 5 ++ xen-hvm-stub.c | 3 +- xen-hvm.c | 46 ++++++++------- 10 files changed, 300 insertions(+), 50 deletions(-) create mode 100644 include/hw/i386/pc-machine-opts.h -- 1.8.4 ^ permalink raw reply [flat|nested] 7+ messages in thread
* [Qemu-devel] [PATCH v4 1/3] xen-hvm: Fix xen_hvm_init() to adjust pc memory layout 2014-06-05 16:11 [Qemu-devel] [PATCH v4 0/3] Add max-ram-below-4g (was Add pci_hole_min_size machine option) Don Slutz @ 2014-06-05 16:11 ` Don Slutz 2014-06-05 16:11 ` [Qemu-devel] [PATCH v4 2/3] pc & q35: Add new machine opt max-ram-below-4g Don Slutz 2014-06-05 16:11 ` [Qemu-devel] [PATCH v4 3/3] xen-hvm: Pass is_default to xen_hvm_init Don Slutz 2 siblings, 0 replies; 7+ messages in thread From: Don Slutz @ 2014-06-05 16:11 UTC (permalink / raw) To: xen-devel, qemu-devel, Stefano Stabellini Cc: Don Slutz, Anthony Liguori, Michael S. Tsirkin This is just below_4g_mem_size and above_4g_mem_size which is used later in QEMU. Acked-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com> Signed-off-by: Don Slutz <dslutz@verizon.com> --- v4: Switch Acked-by & Signed-off-by rebase on master hw/i386/pc_piix.c | 31 ++++++++++++++++--------------- hw/i386/pc_q35.c | 29 +++++++++++++++-------------- include/hw/xen/xen.h | 3 ++- xen-hvm-stub.c | 3 ++- xen-hvm.c | 24 ++++++++++++++---------- 5 files changed, 49 insertions(+), 41 deletions(-) diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c index a48e263..e619356 100644 --- a/hw/i386/pc_piix.c +++ b/hw/i386/pc_piix.c @@ -97,21 +97,6 @@ static void pc_init1(MachineState *machine, FWCfgState *fw_cfg = NULL; PcGuestInfo *guest_info; - if (xen_enabled() && xen_hvm_init(&ram_memory) != 0) { - fprintf(stderr, "xen hardware virtual machine initialisation failed\n"); - exit(1); - } - - icc_bridge = qdev_create(NULL, TYPE_ICC_BRIDGE); - object_property_add_child(qdev_get_machine(), "icc-bridge", - OBJECT(icc_bridge), NULL); - - pc_cpus_init(machine->cpu_model, icc_bridge); - - if (kvm_enabled() && kvmclock_enabled) { - kvmclock_create(); - } - /* Check whether RAM fits below 4G (leaving 1/2 GByte for IO memory). * 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 @@ -128,6 +113,22 @@ static void pc_init1(MachineState *machine, below_4g_mem_size = machine->ram_size; } + if (xen_enabled() && xen_hvm_init(&below_4g_mem_size, &above_4g_mem_size, + &ram_memory) != 0) { + fprintf(stderr, "xen hardware virtual machine initialisation failed\n"); + exit(1); + } + + icc_bridge = qdev_create(NULL, TYPE_ICC_BRIDGE); + object_property_add_child(qdev_get_machine(), "icc-bridge", + OBJECT(icc_bridge), NULL); + + pc_cpus_init(machine->cpu_model, icc_bridge); + + if (kvm_enabled() && kvmclock_enabled) { + kvmclock_create(); + } + if (pci_enabled) { pci_memory = g_new(MemoryRegion, 1); memory_region_init(pci_memory, NULL, "pci", UINT64_MAX); diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c index b3c02c1..30a8911 100644 --- a/hw/i386/pc_q35.c +++ b/hw/i386/pc_q35.c @@ -84,20 +84,6 @@ static void pc_q35_init(MachineState *machine) DeviceState *icc_bridge; PcGuestInfo *guest_info; - if (xen_enabled() && xen_hvm_init(&ram_memory) != 0) { - fprintf(stderr, "xen hardware virtual machine initialisation failed\n"); - exit(1); - } - - icc_bridge = qdev_create(NULL, TYPE_ICC_BRIDGE); - object_property_add_child(qdev_get_machine(), "icc-bridge", - OBJECT(icc_bridge), NULL); - - pc_cpus_init(machine->cpu_model, icc_bridge); - pc_acpi_init("q35-acpi-dsdt.aml"); - - kvmclock_create(); - /* 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). @@ -116,6 +102,21 @@ static void pc_q35_init(MachineState *machine) below_4g_mem_size = machine->ram_size; } + if (xen_enabled() && xen_hvm_init(&below_4g_mem_size, &above_4g_mem_size, + &ram_memory) != 0) { + fprintf(stderr, "xen hardware virtual machine initialisation failed\n"); + exit(1); + } + + icc_bridge = qdev_create(NULL, TYPE_ICC_BRIDGE); + object_property_add_child(qdev_get_machine(), "icc-bridge", + OBJECT(icc_bridge), NULL); + + pc_cpus_init(machine->cpu_model, icc_bridge); + pc_acpi_init("q35-acpi-dsdt.aml"); + + kvmclock_create(); + /* pci enabled */ if (pci_enabled) { pci_memory = g_new(MemoryRegion, 1); diff --git a/include/hw/xen/xen.h b/include/hw/xen/xen.h index 85fda3d..f71f2d8 100644 --- a/include/hw/xen/xen.h +++ b/include/hw/xen/xen.h @@ -37,10 +37,11 @@ void xen_cmos_set_s3_resume(void *opaque, int irq, int level); qemu_irq *xen_interrupt_controller_init(void); int xen_init(MachineClass *mc); -int xen_hvm_init(MemoryRegion **ram_memory); void xenstore_store_pv_console_info(int i, struct CharDriverState *chr); #if defined(NEED_CPU_H) && !defined(CONFIG_USER_ONLY) +int xen_hvm_init(ram_addr_t *below_4g_mem_size, ram_addr_t *above_4g_mem_size, + MemoryRegion **ram_memory); void xen_ram_alloc(ram_addr_t ram_addr, ram_addr_t size, struct MemoryRegion *mr); void xen_modified_memory(ram_addr_t start, ram_addr_t length); diff --git a/xen-hvm-stub.c b/xen-hvm-stub.c index 4eb27b5..2d98696 100644 --- a/xen-hvm-stub.c +++ b/xen-hvm-stub.c @@ -51,7 +51,8 @@ void xen_modified_memory(ram_addr_t start, ram_addr_t length) { } -int xen_hvm_init(MemoryRegion **ram_memory) +int xen_hvm_init(ram_addr_t *below_4g_mem_size, ram_addr_t *above_4g_mem_size, + MemoryRegion **ram_memory) { return 0; } diff --git a/xen-hvm.c b/xen-hvm.c index a64486c..a0b6b5d 100644 --- a/xen-hvm.c +++ b/xen-hvm.c @@ -155,10 +155,11 @@ qemu_irq *xen_interrupt_controller_init(void) /* Memory Ops */ -static void xen_ram_init(ram_addr_t ram_size, MemoryRegion **ram_memory_p) +static void xen_ram_init(ram_addr_t *below_4g_mem_size, + ram_addr_t *above_4g_mem_size, + ram_addr_t ram_size, MemoryRegion **ram_memory_p) { MemoryRegion *sysmem = get_system_memory(); - ram_addr_t below_4g_mem_size, above_4g_mem_size = 0; ram_addr_t block_len; block_len = ram_size; @@ -173,10 +174,11 @@ static void xen_ram_init(ram_addr_t ram_size, MemoryRegion **ram_memory_p) vmstate_register_ram_global(&ram_memory); if (ram_size >= HVM_BELOW_4G_RAM_END) { - above_4g_mem_size = ram_size - HVM_BELOW_4G_RAM_END; - below_4g_mem_size = HVM_BELOW_4G_RAM_END; + *above_4g_mem_size = ram_size - HVM_BELOW_4G_RAM_END; + *below_4g_mem_size = HVM_BELOW_4G_RAM_END; } else { - below_4g_mem_size = ram_size; + *above_4g_mem_size = 0; + *below_4g_mem_size = ram_size; } memory_region_init_alias(&ram_640k, NULL, "xen.ram.640k", @@ -189,12 +191,13 @@ static void xen_ram_init(ram_addr_t ram_size, MemoryRegion **ram_memory_p) * the Options ROM, so it is registered here as RAM. */ memory_region_init_alias(&ram_lo, NULL, "xen.ram.lo", - &ram_memory, 0xc0000, below_4g_mem_size - 0xc0000); + &ram_memory, 0xc0000, + *below_4g_mem_size - 0xc0000); memory_region_add_subregion(sysmem, 0xc0000, &ram_lo); - if (above_4g_mem_size > 0) { + if (*above_4g_mem_size > 0) { memory_region_init_alias(&ram_hi, NULL, "xen.ram.hi", &ram_memory, 0x100000000ULL, - above_4g_mem_size); + *above_4g_mem_size); memory_region_add_subregion(sysmem, 0x100000000ULL, &ram_hi); } } @@ -958,7 +961,8 @@ static void xen_wakeup_notifier(Notifier *notifier, void *data) xc_set_hvm_param(xen_xc, xen_domid, HVM_PARAM_ACPI_S_STATE, 0); } -int xen_hvm_init(MemoryRegion **ram_memory) +int xen_hvm_init(ram_addr_t *below_4g_mem_size, ram_addr_t *above_4g_mem_size, + MemoryRegion **ram_memory) { int i, rc; unsigned long ioreq_pfn; @@ -1036,7 +1040,7 @@ int xen_hvm_init(MemoryRegion **ram_memory) /* Init RAM management */ xen_map_cache_init(xen_phys_offset_to_gaddr, state); - xen_ram_init(ram_size, ram_memory); + xen_ram_init(below_4g_mem_size, above_4g_mem_size, ram_size, ram_memory); qemu_add_vm_change_state_handler(xen_hvm_change_state_handler, state); -- 1.8.4 ^ permalink raw reply related [flat|nested] 7+ messages in thread
* [Qemu-devel] [PATCH v4 2/3] pc & q35: Add new machine opt max-ram-below-4g 2014-06-05 16:11 [Qemu-devel] [PATCH v4 0/3] Add max-ram-below-4g (was Add pci_hole_min_size machine option) Don Slutz 2014-06-05 16:11 ` [Qemu-devel] [PATCH v4 1/3] xen-hvm: Fix xen_hvm_init() to adjust pc memory layout Don Slutz @ 2014-06-05 16:11 ` Don Slutz 2014-06-05 16:27 ` Igor Mammedov 2014-06-05 16:11 ` [Qemu-devel] [PATCH v4 3/3] xen-hvm: Pass is_default to xen_hvm_init Don Slutz 2 siblings, 1 reply; 7+ messages in thread From: Don Slutz @ 2014-06-05 16:11 UTC (permalink / raw) To: xen-devel, qemu-devel, Stefano Stabellini Cc: Don Slutz, Anthony Liguori, Michael S. Tsirkin This is a pc & q35 only machine opt. One use is to allow for more ram in a 32bit guest for example: -machine pc,max-ram-below-4g=3.75G If you add enough PCI devices then all mmio for them will not fit below 4G which may not be the layout the user wanted. This allows you to increase the below 4G address space that PCI devices can use (aka decrease ram below 4G) and therefore in more cases not have any mmio that is above 4G. For example using "-machine pc,max-ram-below-4g=2G" on the command line will limit the amount of ram that is below 4G to 2G. Signed-off-by: Don Slutz <dslutz@verizon.com> --- hw/core/machine.c | 44 +++++++++++++++++++ hw/i386/pc.c | 22 ++++++++++ hw/i386/pc_piix.c | 89 +++++++++++++++++++++++++++++++++++++-- hw/i386/pc_q35.c | 39 ++++++++++++++++- include/hw/boards.h | 1 + include/hw/i386/pc-machine-opts.h | 46 ++++++++++++++++++++ vl.c | 5 +++ 7 files changed, 241 insertions(+), 5 deletions(-) create mode 100644 include/hw/i386/pc-machine-opts.h diff --git a/hw/core/machine.c b/hw/core/machine.c index cbba679..82c0ce6 100644 --- a/hw/core/machine.c +++ b/hw/core/machine.c @@ -12,6 +12,7 @@ #include "hw/boards.h" #include "qapi/visitor.h" +#include "hw/i386/pc-machine-opts.h" static char *machine_get_accel(Object *obj, Error **errp) { @@ -235,8 +236,45 @@ static void machine_set_firmware(Object *obj, const char *value, Error **errp) ms->firmware = g_strdup(value); } +static void machine_get_max_ram_below_4g(Object *obj, Visitor *v, + void *opaque, const char *name, + Error **errp) +{ + PCMachineOptsClass *pmc = opaque; + uint64_t value = pmc->max_ram_below_4g; + + visit_type_size(v, &value, name, errp); +} + +static void machine_set_max_ram_below_4g(Object *obj, Visitor *v, + void *opaque, const char *name, + Error **errp) +{ + PCMachineOptsClass *pmc = opaque; + Error *error = NULL; + uint64_t value; + + visit_type_size(v, &value, name, &error); + if (error) { + error_propagate(errp, error); + return; + } + if (value > (1ULL << 32)) { + error_set(&error, ERROR_CLASS_GENERIC_ERROR, + "Machine option 'max-ram-below-4g=%"PRIu64 + "' expects size less then or equal to 4G", value); + error_propagate(errp, error); + return; + } + + pmc->max_ram_below_4g = value; +} + static void machine_initfn(Object *obj) { + PCMachineOptsClass *pmc = (PCMachineOptsClass *) + object_dynamic_cast(obj, TYPE_PC_MACHINE_OPTS); + object_property_add_str(obj, "accel", machine_get_accel, machine_set_accel, NULL); object_property_add_bool(obj, "kernel_irqchip", @@ -274,6 +312,12 @@ static void machine_initfn(Object *obj) object_property_add_bool(obj, "usb", machine_get_usb, machine_set_usb, NULL); object_property_add_str(obj, "firmware", machine_get_firmware, machine_set_firmware, NULL); + if (pmc) { + object_property_add(obj, "max-ram-below-4g", "size", + machine_get_max_ram_below_4g, + machine_set_max_ram_below_4g, + NULL, pmc, NULL); + } } static void machine_finalize(Object *obj) diff --git a/hw/i386/pc.c b/hw/i386/pc.c index e6369d5..b1f3a1c 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -23,6 +23,7 @@ */ #include "hw/hw.h" #include "hw/i386/pc.h" +#include "hw/i386/pc-machine-opts.h" #include "hw/char/serial.h" #include "hw/i386/apic.h" #include "hw/block/fdc.h" @@ -1459,3 +1460,24 @@ void ioapic_init_gsi(GSIState *gsi_state, const char *parent_name) gsi_state->ioapic_irq[i] = qdev_get_gpio_in(dev, i); } } + +static void pc_machine_opts_class_init(ObjectClass *klass, void *data) +{ + PCMachineOptsClass *pmc = PC_MACHINE_OPTS_CLASS(klass); + + pmc->max_ram_below_4g = 0; +} + +static const TypeInfo pc_machine_opts_info = { + .name = TYPE_PC_MACHINE_OPTS, + .parent = TYPE_INTERFACE, + .class_size = sizeof(PCMachineOptsClass), + .class_init = pc_machine_opts_class_init, +}; + +static void pc_machine_opts_register_types(void) +{ + type_register_static(&pc_machine_opts_info); +} + +type_init(pc_machine_opts_register_types) diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c index e619356..f631c5c 100644 --- a/hw/i386/pc_piix.c +++ b/hw/i386/pc_piix.c @@ -27,6 +27,7 @@ #include "hw/hw.h" #include "hw/loader.h" #include "hw/i386/pc.h" +#include "hw/i386/pc-machine-opts.h" #include "hw/i386/apic.h" #include "hw/i386/smbios.h" #include "hw/pci/pci.h" @@ -96,6 +97,14 @@ static void pc_init1(MachineState *machine, DeviceState *icc_bridge; FWCfgState *fw_cfg = NULL; PcGuestInfo *guest_info; + Object *mo = qdev_get_machine(); + PCMachineOptsClass *pmc = (PCMachineOptsClass *) + object_dynamic_cast(mo, TYPE_PC_MACHINE_OPTS); + ram_addr_t lowmem = 0xe0000000; + + if (pmc && pmc->max_ram_below_4g) { + lowmem = pmc->max_ram_below_4g; + } /* Check whether RAM fits below 4G (leaving 1/2 GByte for IO memory). * If it doesn't, we need to split it in chunks below and above 4G. @@ -104,8 +113,10 @@ static void pc_init1(MachineState *machine, * For old machine types, use whatever split we used historically to avoid * breaking migration. */ - if (machine->ram_size >= 0xe0000000) { - ram_addr_t lowmem = gigabyte_align ? 0xc0000000 : 0xe0000000; + if (machine->ram_size >= lowmem) { + if (!(pmc && pmc->max_ram_below_4g) && gigabyte_align) { + lowmem = 0xc0000000; + } above_4g_mem_size = machine->ram_size - lowmem; below_4g_mem_size = lowmem; } else { @@ -120,7 +131,7 @@ static void pc_init1(MachineState *machine, } icc_bridge = qdev_create(NULL, TYPE_ICC_BRIDGE); - object_property_add_child(qdev_get_machine(), "icc-bridge", + object_property_add_child(mo, "icc-bridge", OBJECT(icc_bridge), NULL); pc_cpus_init(machine->cpu_model, icc_bridge); @@ -408,6 +419,10 @@ static QEMUMachine pc_i440fx_machine_v2_1 = { .alias = "pc", .init = pc_init_pci, .is_default = 1, + .interfaces = (InterfaceInfo[]) { + { TYPE_PC_MACHINE_OPTS }, + { } + } }; #define PC_I440FX_2_0_MACHINE_OPTIONS PC_I440FX_2_1_MACHINE_OPTIONS @@ -420,6 +435,10 @@ static QEMUMachine pc_i440fx_machine_v2_0 = { PC_COMPAT_2_0, { /* end of list */ } }, + .interfaces = (InterfaceInfo[]) { + { TYPE_PC_MACHINE_OPTS }, + { } + } }; #define PC_I440FX_1_7_MACHINE_OPTIONS PC_I440FX_MACHINE_OPTIONS @@ -432,6 +451,10 @@ static QEMUMachine pc_i440fx_machine_v1_7 = { PC_COMPAT_1_7, { /* end of list */ } }, + .interfaces = (InterfaceInfo[]) { + { TYPE_PC_MACHINE_OPTS }, + { } + } }; #define PC_I440FX_1_6_MACHINE_OPTIONS PC_I440FX_MACHINE_OPTIONS @@ -444,6 +467,10 @@ static QEMUMachine pc_i440fx_machine_v1_6 = { PC_COMPAT_1_6, { /* end of list */ } }, + .interfaces = (InterfaceInfo[]) { + { TYPE_PC_MACHINE_OPTS }, + { } + } }; static QEMUMachine pc_i440fx_machine_v1_5 = { @@ -454,6 +481,10 @@ static QEMUMachine pc_i440fx_machine_v1_5 = { PC_COMPAT_1_5, { /* end of list */ } }, + .interfaces = (InterfaceInfo[]) { + { TYPE_PC_MACHINE_OPTS }, + { } + } }; #define PC_I440FX_1_4_MACHINE_OPTIONS \ @@ -468,6 +499,10 @@ static QEMUMachine pc_i440fx_machine_v1_4 = { PC_COMPAT_1_4, { /* end of list */ } }, + .interfaces = (InterfaceInfo[]) { + { TYPE_PC_MACHINE_OPTS }, + { } + } }; #define PC_COMPAT_1_3 \ @@ -498,6 +533,10 @@ static QEMUMachine pc_machine_v1_3 = { PC_COMPAT_1_3, { /* end of list */ } }, + .interfaces = (InterfaceInfo[]) { + { TYPE_PC_MACHINE_OPTS }, + { } + } }; #define PC_COMPAT_1_2 \ @@ -539,6 +578,10 @@ static QEMUMachine pc_machine_v1_2 = { PC_COMPAT_1_2, { /* end of list */ } }, + .interfaces = (InterfaceInfo[]) { + { TYPE_PC_MACHINE_OPTS }, + { } + } }; #define PC_COMPAT_1_1 \ @@ -580,6 +623,10 @@ static QEMUMachine pc_machine_v1_1 = { PC_COMPAT_1_1, { /* end of list */ } }, + .interfaces = (InterfaceInfo[]) { + { TYPE_PC_MACHINE_OPTS }, + { } + } }; #define PC_COMPAT_1_0 \ @@ -610,6 +657,10 @@ static QEMUMachine pc_machine_v1_0 = { { /* end of list */ } }, .hw_version = "1.0", + .interfaces = (InterfaceInfo[]) { + { TYPE_PC_MACHINE_OPTS }, + { } + } }; #define PC_COMPAT_0_15 \ @@ -623,6 +674,10 @@ static QEMUMachine pc_machine_v0_15 = { { /* end of list */ } }, .hw_version = "0.15", + .interfaces = (InterfaceInfo[]) { + { TYPE_PC_MACHINE_OPTS }, + { } + } }; #define PC_COMPAT_0_14 \ @@ -662,6 +717,10 @@ static QEMUMachine pc_machine_v0_14 = { { /* end of list */ } }, .hw_version = "0.14", + .interfaces = (InterfaceInfo[]) { + { TYPE_PC_MACHINE_OPTS }, + { } + } }; #define PC_COMPAT_0_13 \ @@ -701,6 +760,10 @@ static QEMUMachine pc_machine_v0_13 = { { /* end of list */ } }, .hw_version = "0.13", + .interfaces = (InterfaceInfo[]) { + { TYPE_PC_MACHINE_OPTS }, + { } + } }; #define PC_COMPAT_0_12 \ @@ -744,6 +807,10 @@ static QEMUMachine pc_machine_v0_12 = { { /* end of list */ } }, .hw_version = "0.12", + .interfaces = (InterfaceInfo[]) { + { TYPE_PC_MACHINE_OPTS }, + { } + } }; #define PC_COMPAT_0_11 \ @@ -775,6 +842,10 @@ static QEMUMachine pc_machine_v0_11 = { { /* end of list */ } }, .hw_version = "0.11", + .interfaces = (InterfaceInfo[]) { + { TYPE_PC_MACHINE_OPTS }, + { } + } }; static QEMUMachine pc_machine_v0_10 = { @@ -806,6 +877,10 @@ static QEMUMachine pc_machine_v0_10 = { { /* end of list */ } }, .hw_version = "0.10", + .interfaces = (InterfaceInfo[]) { + { TYPE_PC_MACHINE_OPTS }, + { } + } }; static QEMUMachine isapc_machine = { @@ -817,6 +892,10 @@ static QEMUMachine isapc_machine = { .compat_props = (GlobalProperty[]) { { /* end of list */ } }, + .interfaces = (InterfaceInfo[]) { + { TYPE_PC_MACHINE_OPTS }, + { } + } }; #ifdef CONFIG_XEN @@ -839,6 +918,10 @@ static QEMUMachine xenfv_machine = { }, { /* end of list */ } }, + .interfaces = (InterfaceInfo[]) { + { TYPE_PC_MACHINE_OPTS }, + { } + } }; #endif diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c index 30a8911..ba4ada2 100644 --- a/hw/i386/pc_q35.c +++ b/hw/i386/pc_q35.c @@ -39,6 +39,7 @@ #include "hw/pci-host/q35.h" #include "exec/address-spaces.h" #include "hw/i386/ich9.h" +#include "hw/i386/pc-machine-opts.h" #include "hw/i386/smbios.h" #include "hw/ide/pci.h" #include "hw/ide/ahci.h" @@ -83,6 +84,14 @@ static void pc_q35_init(MachineState *machine) PCIDevice *ahci; DeviceState *icc_bridge; PcGuestInfo *guest_info; + Object *mo = qdev_get_machine(); + PCMachineOptsClass *pmc = (PCMachineOptsClass *) + object_dynamic_cast(mo, TYPE_PC_MACHINE_OPTS); + ram_addr_t lowmem = 0xb0000000; + + if (pmc && pmc->max_ram_below_4g) { + lowmem = pmc->max_ram_below_4g; + } /* Check whether RAM fits below 4G (leaving 1/2 GByte for IO memory * and 256 Mbytes for PCI Express Enhanced Configuration Access Mapping @@ -93,8 +102,10 @@ static void pc_q35_init(MachineState *machine) * For old machine types, use whatever split we used historically to avoid * breaking migration. */ - if (machine->ram_size >= 0xb0000000) { - ram_addr_t lowmem = gigabyte_align ? 0x80000000 : 0xb0000000; + if (machine->ram_size >= lowmem) { + if (!(pmc && pmc->max_ram_below_4g) && gigabyte_align) { + lowmem = 0x800000000; + } above_4g_mem_size = machine->ram_size - lowmem; below_4g_mem_size = lowmem; } else { @@ -321,6 +332,10 @@ static QEMUMachine pc_q35_machine_v2_1 = { .name = "pc-q35-2.1", .alias = "q35", .init = pc_q35_init, + .interfaces = (InterfaceInfo[]) { + { TYPE_PC_MACHINE_OPTS }, + { } + } }; #define PC_Q35_2_0_MACHINE_OPTIONS PC_Q35_2_1_MACHINE_OPTIONS @@ -333,6 +348,10 @@ static QEMUMachine pc_q35_machine_v2_0 = { PC_Q35_COMPAT_2_0, { /* end of list */ } }, + .interfaces = (InterfaceInfo[]) { + { TYPE_PC_MACHINE_OPTS }, + { } + } }; #define PC_Q35_1_7_MACHINE_OPTIONS PC_Q35_MACHINE_OPTIONS @@ -345,6 +364,10 @@ static QEMUMachine pc_q35_machine_v1_7 = { PC_Q35_COMPAT_1_7, { /* end of list */ } }, + .interfaces = (InterfaceInfo[]) { + { TYPE_PC_MACHINE_OPTS }, + { } + } }; #define PC_Q35_1_6_MACHINE_OPTIONS PC_Q35_MACHINE_OPTIONS @@ -357,6 +380,10 @@ static QEMUMachine pc_q35_machine_v1_6 = { PC_Q35_COMPAT_1_6, { /* end of list */ } }, + .interfaces = (InterfaceInfo[]) { + { TYPE_PC_MACHINE_OPTS }, + { } + } }; static QEMUMachine pc_q35_machine_v1_5 = { @@ -367,6 +394,10 @@ static QEMUMachine pc_q35_machine_v1_5 = { PC_Q35_COMPAT_1_5, { /* end of list */ } }, + .interfaces = (InterfaceInfo[]) { + { TYPE_PC_MACHINE_OPTS }, + { } + } }; #define PC_Q35_1_4_MACHINE_OPTIONS \ @@ -381,6 +412,10 @@ static QEMUMachine pc_q35_machine_v1_4 = { PC_COMPAT_1_4, { /* end of list */ } }, + .interfaces = (InterfaceInfo[]) { + { TYPE_PC_MACHINE_OPTS }, + { } + } }; static void pc_q35_machine_init(void) diff --git a/include/hw/boards.h b/include/hw/boards.h index 2d2e2be..87b45cf 100644 --- a/include/hw/boards.h +++ b/include/hw/boards.h @@ -41,6 +41,7 @@ struct QEMUMachine { const char *default_boot_order; GlobalProperty *compat_props; const char *hw_version; + InterfaceInfo *interfaces; }; #define TYPE_MACHINE_SUFFIX "-machine" diff --git a/include/hw/i386/pc-machine-opts.h b/include/hw/i386/pc-machine-opts.h new file mode 100644 index 0000000..b90e42b --- /dev/null +++ b/include/hw/i386/pc-machine-opts.h @@ -0,0 +1,46 @@ +/* + * PC Machine private opts + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, + * or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef PC_MACHINE_OPTS_H +#define PC_MACHINE_OPTS_H 1 + +#include "qemu-common.h" +#include "qom/object.h" + +#define TYPE_PC_MACHINE_OPTS "pc-machine-opts" + +#define PC_MACHINE_OPTS_CLASS(klass) \ + OBJECT_CLASS_CHECK(PCMachineOptsClass, (klass), TYPE_PC_MACHINE_OPTS) +#define PC_MACHINE_OPTS_GET_CLASS(obj) \ + OBJECT_GET_CLASS(PCMachineOptsClass, (obj), TYPE_PC_MACHINE_OPTS) +#define PC_MACHINE_OPTS(obj) \ + INTERFACE_CHECK(PCMachineOpts, (obj), TYPE_PC_MACHINE_OPTS) + +typedef struct PCMachineOpts { + /*< private >*/ + Object parent_obj; + /*< public >*/ +} PCMachineOpts; + +typedef struct PCMachineOptsClass { + /*< private >*/ + InterfaceClass parent_class; + /*< public >*/ + uint64_t max_ram_below_4g; +} PCMachineOptsClass; + +#endif /* PC_MACHINE_OPTS_H */ diff --git a/vl.c b/vl.c index 0c15608..c67ea5c 100644 --- a/vl.c +++ b/vl.c @@ -382,6 +382,10 @@ static QemuOptsList qemu_machine_opts = { .name = "kvm-type", .type = QEMU_OPT_STRING, .help = "Specifies the KVM virtualization mode (HV, PR)", + },{ + .name = "max-ram-below-4g", + .type = QEMU_OPT_SIZE, + .help = "maximum ram below the 4G boundary (32bit boundary)", }, { /* End of list */ } }, @@ -1623,6 +1627,7 @@ int qemu_register_machine(QEMUMachine *m) .parent = TYPE_MACHINE, .class_init = machine_class_init, .class_data = (void *)m, + .interfaces = m->interfaces, }; type_register(&ti); -- 1.8.4 ^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [Qemu-devel] [PATCH v4 2/3] pc & q35: Add new machine opt max-ram-below-4g 2014-06-05 16:11 ` [Qemu-devel] [PATCH v4 2/3] pc & q35: Add new machine opt max-ram-below-4g Don Slutz @ 2014-06-05 16:27 ` Igor Mammedov 2014-06-05 16:49 ` Don Slutz 0 siblings, 1 reply; 7+ messages in thread From: Igor Mammedov @ 2014-06-05 16:27 UTC (permalink / raw) To: Don Slutz Cc: xen-devel, Michael S. Tsirkin, qemu-devel, Anthony Liguori, Stefano Stabellini On Thu, 5 Jun 2014 12:11:55 -0400 Don Slutz <dslutz@verizon.com> wrote: > This is a pc & q35 only machine opt. One use is to allow for more > ram in a 32bit guest for example: > > -machine pc,max-ram-below-4g=3.75G > > If you add enough PCI devices then all mmio for them will not fit > below 4G which may not be the layout the user wanted. This allows > you to increase the below 4G address space that PCI devices can use > (aka decrease ram below 4G) and therefore in more cases not have any > mmio that is above 4G. > > For example using "-machine pc,max-ram-below-4g=2G" on the command > line will limit the amount of ram that is below 4G to 2G. > > Signed-off-by: Don Slutz <dslutz@verizon.com> this patch would look better if rebased on top of http://lists.gnu.org/archive/html/qemu-devel/2014-06/msg00133.html and would use PCMachine type to add PC specific "max-ram-below-4g" property. > --- > hw/core/machine.c | 44 +++++++++++++++++++ > hw/i386/pc.c | 22 ++++++++++ > hw/i386/pc_piix.c | 89 +++++++++++++++++++++++++++++++++++++-- > hw/i386/pc_q35.c | 39 ++++++++++++++++- > include/hw/boards.h | 1 + > include/hw/i386/pc-machine-opts.h | 46 ++++++++++++++++++++ > vl.c | 5 +++ > 7 files changed, 241 insertions(+), 5 deletions(-) > create mode 100644 include/hw/i386/pc-machine-opts.h > > diff --git a/hw/core/machine.c b/hw/core/machine.c > index cbba679..82c0ce6 100644 > --- a/hw/core/machine.c > +++ b/hw/core/machine.c > @@ -12,6 +12,7 @@ > > #include "hw/boards.h" > #include "qapi/visitor.h" > +#include "hw/i386/pc-machine-opts.h" > > static char *machine_get_accel(Object *obj, Error **errp) > { > @@ -235,8 +236,45 @@ static void machine_set_firmware(Object *obj, const char *value, Error **errp) > ms->firmware = g_strdup(value); > } > > +static void machine_get_max_ram_below_4g(Object *obj, Visitor *v, > + void *opaque, const char *name, > + Error **errp) > +{ > + PCMachineOptsClass *pmc = opaque; > + uint64_t value = pmc->max_ram_below_4g; > + > + visit_type_size(v, &value, name, errp); > +} > + > +static void machine_set_max_ram_below_4g(Object *obj, Visitor *v, > + void *opaque, const char *name, > + Error **errp) > +{ > + PCMachineOptsClass *pmc = opaque; > + Error *error = NULL; > + uint64_t value; > + > + visit_type_size(v, &value, name, &error); > + if (error) { > + error_propagate(errp, error); > + return; > + } > + if (value > (1ULL << 32)) { > + error_set(&error, ERROR_CLASS_GENERIC_ERROR, > + "Machine option 'max-ram-below-4g=%"PRIu64 > + "' expects size less then or equal to 4G", value); > + error_propagate(errp, error); > + return; > + } > + > + pmc->max_ram_below_4g = value; > +} > + > static void machine_initfn(Object *obj) > { > + PCMachineOptsClass *pmc = (PCMachineOptsClass *) > + object_dynamic_cast(obj, TYPE_PC_MACHINE_OPTS); > + > object_property_add_str(obj, "accel", > machine_get_accel, machine_set_accel, NULL); > object_property_add_bool(obj, "kernel_irqchip", > @@ -274,6 +312,12 @@ static void machine_initfn(Object *obj) > object_property_add_bool(obj, "usb", machine_get_usb, machine_set_usb, NULL); > object_property_add_str(obj, "firmware", > machine_get_firmware, machine_set_firmware, NULL); > + if (pmc) { > + object_property_add(obj, "max-ram-below-4g", "size", > + machine_get_max_ram_below_4g, > + machine_set_max_ram_below_4g, > + NULL, pmc, NULL); > + } > } > > static void machine_finalize(Object *obj) > diff --git a/hw/i386/pc.c b/hw/i386/pc.c > index e6369d5..b1f3a1c 100644 > --- a/hw/i386/pc.c > +++ b/hw/i386/pc.c > @@ -23,6 +23,7 @@ > */ > #include "hw/hw.h" > #include "hw/i386/pc.h" > +#include "hw/i386/pc-machine-opts.h" > #include "hw/char/serial.h" > #include "hw/i386/apic.h" > #include "hw/block/fdc.h" > @@ -1459,3 +1460,24 @@ void ioapic_init_gsi(GSIState *gsi_state, const char *parent_name) > gsi_state->ioapic_irq[i] = qdev_get_gpio_in(dev, i); > } > } > + > +static void pc_machine_opts_class_init(ObjectClass *klass, void *data) > +{ > + PCMachineOptsClass *pmc = PC_MACHINE_OPTS_CLASS(klass); > + > + pmc->max_ram_below_4g = 0; > +} > + > +static const TypeInfo pc_machine_opts_info = { > + .name = TYPE_PC_MACHINE_OPTS, > + .parent = TYPE_INTERFACE, > + .class_size = sizeof(PCMachineOptsClass), > + .class_init = pc_machine_opts_class_init, > +}; > + > +static void pc_machine_opts_register_types(void) > +{ > + type_register_static(&pc_machine_opts_info); > +} > + > +type_init(pc_machine_opts_register_types) > diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c > index e619356..f631c5c 100644 > --- a/hw/i386/pc_piix.c > +++ b/hw/i386/pc_piix.c > @@ -27,6 +27,7 @@ > #include "hw/hw.h" > #include "hw/loader.h" > #include "hw/i386/pc.h" > +#include "hw/i386/pc-machine-opts.h" > #include "hw/i386/apic.h" > #include "hw/i386/smbios.h" > #include "hw/pci/pci.h" > @@ -96,6 +97,14 @@ static void pc_init1(MachineState *machine, > DeviceState *icc_bridge; > FWCfgState *fw_cfg = NULL; > PcGuestInfo *guest_info; > + Object *mo = qdev_get_machine(); > + PCMachineOptsClass *pmc = (PCMachineOptsClass *) > + object_dynamic_cast(mo, TYPE_PC_MACHINE_OPTS); > + ram_addr_t lowmem = 0xe0000000; > + > + if (pmc && pmc->max_ram_below_4g) { > + lowmem = pmc->max_ram_below_4g; > + } > > /* Check whether RAM fits below 4G (leaving 1/2 GByte for IO memory). > * If it doesn't, we need to split it in chunks below and above 4G. > @@ -104,8 +113,10 @@ static void pc_init1(MachineState *machine, > * For old machine types, use whatever split we used historically to avoid > * breaking migration. > */ > - if (machine->ram_size >= 0xe0000000) { > - ram_addr_t lowmem = gigabyte_align ? 0xc0000000 : 0xe0000000; > + if (machine->ram_size >= lowmem) { > + if (!(pmc && pmc->max_ram_below_4g) && gigabyte_align) { > + lowmem = 0xc0000000; > + } > above_4g_mem_size = machine->ram_size - lowmem; > below_4g_mem_size = lowmem; > } else { > @@ -120,7 +131,7 @@ static void pc_init1(MachineState *machine, > } > > icc_bridge = qdev_create(NULL, TYPE_ICC_BRIDGE); > - object_property_add_child(qdev_get_machine(), "icc-bridge", > + object_property_add_child(mo, "icc-bridge", > OBJECT(icc_bridge), NULL); > > pc_cpus_init(machine->cpu_model, icc_bridge); > @@ -408,6 +419,10 @@ static QEMUMachine pc_i440fx_machine_v2_1 = { > .alias = "pc", > .init = pc_init_pci, > .is_default = 1, > + .interfaces = (InterfaceInfo[]) { > + { TYPE_PC_MACHINE_OPTS }, > + { } > + } > }; > > #define PC_I440FX_2_0_MACHINE_OPTIONS PC_I440FX_2_1_MACHINE_OPTIONS > @@ -420,6 +435,10 @@ static QEMUMachine pc_i440fx_machine_v2_0 = { > PC_COMPAT_2_0, > { /* end of list */ } > }, > + .interfaces = (InterfaceInfo[]) { > + { TYPE_PC_MACHINE_OPTS }, > + { } > + } > }; > > #define PC_I440FX_1_7_MACHINE_OPTIONS PC_I440FX_MACHINE_OPTIONS > @@ -432,6 +451,10 @@ static QEMUMachine pc_i440fx_machine_v1_7 = { > PC_COMPAT_1_7, > { /* end of list */ } > }, > + .interfaces = (InterfaceInfo[]) { > + { TYPE_PC_MACHINE_OPTS }, > + { } > + } > }; > > #define PC_I440FX_1_6_MACHINE_OPTIONS PC_I440FX_MACHINE_OPTIONS > @@ -444,6 +467,10 @@ static QEMUMachine pc_i440fx_machine_v1_6 = { > PC_COMPAT_1_6, > { /* end of list */ } > }, > + .interfaces = (InterfaceInfo[]) { > + { TYPE_PC_MACHINE_OPTS }, > + { } > + } > }; > > static QEMUMachine pc_i440fx_machine_v1_5 = { > @@ -454,6 +481,10 @@ static QEMUMachine pc_i440fx_machine_v1_5 = { > PC_COMPAT_1_5, > { /* end of list */ } > }, > + .interfaces = (InterfaceInfo[]) { > + { TYPE_PC_MACHINE_OPTS }, > + { } > + } > }; > > #define PC_I440FX_1_4_MACHINE_OPTIONS \ > @@ -468,6 +499,10 @@ static QEMUMachine pc_i440fx_machine_v1_4 = { > PC_COMPAT_1_4, > { /* end of list */ } > }, > + .interfaces = (InterfaceInfo[]) { > + { TYPE_PC_MACHINE_OPTS }, > + { } > + } > }; > > #define PC_COMPAT_1_3 \ > @@ -498,6 +533,10 @@ static QEMUMachine pc_machine_v1_3 = { > PC_COMPAT_1_3, > { /* end of list */ } > }, > + .interfaces = (InterfaceInfo[]) { > + { TYPE_PC_MACHINE_OPTS }, > + { } > + } > }; > > #define PC_COMPAT_1_2 \ > @@ -539,6 +578,10 @@ static QEMUMachine pc_machine_v1_2 = { > PC_COMPAT_1_2, > { /* end of list */ } > }, > + .interfaces = (InterfaceInfo[]) { > + { TYPE_PC_MACHINE_OPTS }, > + { } > + } > }; > > #define PC_COMPAT_1_1 \ > @@ -580,6 +623,10 @@ static QEMUMachine pc_machine_v1_1 = { > PC_COMPAT_1_1, > { /* end of list */ } > }, > + .interfaces = (InterfaceInfo[]) { > + { TYPE_PC_MACHINE_OPTS }, > + { } > + } > }; > > #define PC_COMPAT_1_0 \ > @@ -610,6 +657,10 @@ static QEMUMachine pc_machine_v1_0 = { > { /* end of list */ } > }, > .hw_version = "1.0", > + .interfaces = (InterfaceInfo[]) { > + { TYPE_PC_MACHINE_OPTS }, > + { } > + } > }; > > #define PC_COMPAT_0_15 \ > @@ -623,6 +674,10 @@ static QEMUMachine pc_machine_v0_15 = { > { /* end of list */ } > }, > .hw_version = "0.15", > + .interfaces = (InterfaceInfo[]) { > + { TYPE_PC_MACHINE_OPTS }, > + { } > + } > }; > > #define PC_COMPAT_0_14 \ > @@ -662,6 +717,10 @@ static QEMUMachine pc_machine_v0_14 = { > { /* end of list */ } > }, > .hw_version = "0.14", > + .interfaces = (InterfaceInfo[]) { > + { TYPE_PC_MACHINE_OPTS }, > + { } > + } > }; > > #define PC_COMPAT_0_13 \ > @@ -701,6 +760,10 @@ static QEMUMachine pc_machine_v0_13 = { > { /* end of list */ } > }, > .hw_version = "0.13", > + .interfaces = (InterfaceInfo[]) { > + { TYPE_PC_MACHINE_OPTS }, > + { } > + } > }; > > #define PC_COMPAT_0_12 \ > @@ -744,6 +807,10 @@ static QEMUMachine pc_machine_v0_12 = { > { /* end of list */ } > }, > .hw_version = "0.12", > + .interfaces = (InterfaceInfo[]) { > + { TYPE_PC_MACHINE_OPTS }, > + { } > + } > }; > > #define PC_COMPAT_0_11 \ > @@ -775,6 +842,10 @@ static QEMUMachine pc_machine_v0_11 = { > { /* end of list */ } > }, > .hw_version = "0.11", > + .interfaces = (InterfaceInfo[]) { > + { TYPE_PC_MACHINE_OPTS }, > + { } > + } > }; > > static QEMUMachine pc_machine_v0_10 = { > @@ -806,6 +877,10 @@ static QEMUMachine pc_machine_v0_10 = { > { /* end of list */ } > }, > .hw_version = "0.10", > + .interfaces = (InterfaceInfo[]) { > + { TYPE_PC_MACHINE_OPTS }, > + { } > + } > }; > > static QEMUMachine isapc_machine = { > @@ -817,6 +892,10 @@ static QEMUMachine isapc_machine = { > .compat_props = (GlobalProperty[]) { > { /* end of list */ } > }, > + .interfaces = (InterfaceInfo[]) { > + { TYPE_PC_MACHINE_OPTS }, > + { } > + } > }; > > #ifdef CONFIG_XEN > @@ -839,6 +918,10 @@ static QEMUMachine xenfv_machine = { > }, > { /* end of list */ } > }, > + .interfaces = (InterfaceInfo[]) { > + { TYPE_PC_MACHINE_OPTS }, > + { } > + } > }; > #endif > > diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c > index 30a8911..ba4ada2 100644 > --- a/hw/i386/pc_q35.c > +++ b/hw/i386/pc_q35.c > @@ -39,6 +39,7 @@ > #include "hw/pci-host/q35.h" > #include "exec/address-spaces.h" > #include "hw/i386/ich9.h" > +#include "hw/i386/pc-machine-opts.h" > #include "hw/i386/smbios.h" > #include "hw/ide/pci.h" > #include "hw/ide/ahci.h" > @@ -83,6 +84,14 @@ static void pc_q35_init(MachineState *machine) > PCIDevice *ahci; > DeviceState *icc_bridge; > PcGuestInfo *guest_info; > + Object *mo = qdev_get_machine(); > + PCMachineOptsClass *pmc = (PCMachineOptsClass *) > + object_dynamic_cast(mo, TYPE_PC_MACHINE_OPTS); > + ram_addr_t lowmem = 0xb0000000; > + > + if (pmc && pmc->max_ram_below_4g) { > + lowmem = pmc->max_ram_below_4g; > + } > > /* Check whether RAM fits below 4G (leaving 1/2 GByte for IO memory > * and 256 Mbytes for PCI Express Enhanced Configuration Access Mapping > @@ -93,8 +102,10 @@ static void pc_q35_init(MachineState *machine) > * For old machine types, use whatever split we used historically to avoid > * breaking migration. > */ > - if (machine->ram_size >= 0xb0000000) { > - ram_addr_t lowmem = gigabyte_align ? 0x80000000 : 0xb0000000; > + if (machine->ram_size >= lowmem) { > + if (!(pmc && pmc->max_ram_below_4g) && gigabyte_align) { > + lowmem = 0x800000000; > + } > above_4g_mem_size = machine->ram_size - lowmem; > below_4g_mem_size = lowmem; > } else { > @@ -321,6 +332,10 @@ static QEMUMachine pc_q35_machine_v2_1 = { > .name = "pc-q35-2.1", > .alias = "q35", > .init = pc_q35_init, > + .interfaces = (InterfaceInfo[]) { > + { TYPE_PC_MACHINE_OPTS }, > + { } > + } > }; > > #define PC_Q35_2_0_MACHINE_OPTIONS PC_Q35_2_1_MACHINE_OPTIONS > @@ -333,6 +348,10 @@ static QEMUMachine pc_q35_machine_v2_0 = { > PC_Q35_COMPAT_2_0, > { /* end of list */ } > }, > + .interfaces = (InterfaceInfo[]) { > + { TYPE_PC_MACHINE_OPTS }, > + { } > + } > }; > > #define PC_Q35_1_7_MACHINE_OPTIONS PC_Q35_MACHINE_OPTIONS > @@ -345,6 +364,10 @@ static QEMUMachine pc_q35_machine_v1_7 = { > PC_Q35_COMPAT_1_7, > { /* end of list */ } > }, > + .interfaces = (InterfaceInfo[]) { > + { TYPE_PC_MACHINE_OPTS }, > + { } > + } > }; > > #define PC_Q35_1_6_MACHINE_OPTIONS PC_Q35_MACHINE_OPTIONS > @@ -357,6 +380,10 @@ static QEMUMachine pc_q35_machine_v1_6 = { > PC_Q35_COMPAT_1_6, > { /* end of list */ } > }, > + .interfaces = (InterfaceInfo[]) { > + { TYPE_PC_MACHINE_OPTS }, > + { } > + } > }; > > static QEMUMachine pc_q35_machine_v1_5 = { > @@ -367,6 +394,10 @@ static QEMUMachine pc_q35_machine_v1_5 = { > PC_Q35_COMPAT_1_5, > { /* end of list */ } > }, > + .interfaces = (InterfaceInfo[]) { > + { TYPE_PC_MACHINE_OPTS }, > + { } > + } > }; > > #define PC_Q35_1_4_MACHINE_OPTIONS \ > @@ -381,6 +412,10 @@ static QEMUMachine pc_q35_machine_v1_4 = { > PC_COMPAT_1_4, > { /* end of list */ } > }, > + .interfaces = (InterfaceInfo[]) { > + { TYPE_PC_MACHINE_OPTS }, > + { } > + } > }; > > static void pc_q35_machine_init(void) > diff --git a/include/hw/boards.h b/include/hw/boards.h > index 2d2e2be..87b45cf 100644 > --- a/include/hw/boards.h > +++ b/include/hw/boards.h > @@ -41,6 +41,7 @@ struct QEMUMachine { > const char *default_boot_order; > GlobalProperty *compat_props; > const char *hw_version; > + InterfaceInfo *interfaces; > }; > > #define TYPE_MACHINE_SUFFIX "-machine" > diff --git a/include/hw/i386/pc-machine-opts.h b/include/hw/i386/pc-machine-opts.h > new file mode 100644 > index 0000000..b90e42b > --- /dev/null > +++ b/include/hw/i386/pc-machine-opts.h > @@ -0,0 +1,46 @@ > +/* > + * PC Machine private opts > + * > + * This program is free software; you can redistribute it and/or modify > + * it under the terms of the GNU General Public License as published by > + * the Free Software Foundation; either version 2 of the License, > + * or (at your option) any later version. > + * > + * This program is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > + * GNU General Public License for more details. > + * > + * You should have received a copy of the GNU General Public License > + * along with this program; if not, see <http://www.gnu.org/licenses/>. > + */ > + > +#ifndef PC_MACHINE_OPTS_H > +#define PC_MACHINE_OPTS_H 1 > + > +#include "qemu-common.h" > +#include "qom/object.h" > + > +#define TYPE_PC_MACHINE_OPTS "pc-machine-opts" > + > +#define PC_MACHINE_OPTS_CLASS(klass) \ > + OBJECT_CLASS_CHECK(PCMachineOptsClass, (klass), TYPE_PC_MACHINE_OPTS) > +#define PC_MACHINE_OPTS_GET_CLASS(obj) \ > + OBJECT_GET_CLASS(PCMachineOptsClass, (obj), TYPE_PC_MACHINE_OPTS) > +#define PC_MACHINE_OPTS(obj) \ > + INTERFACE_CHECK(PCMachineOpts, (obj), TYPE_PC_MACHINE_OPTS) > + > +typedef struct PCMachineOpts { > + /*< private >*/ > + Object parent_obj; > + /*< public >*/ > +} PCMachineOpts; > + > +typedef struct PCMachineOptsClass { > + /*< private >*/ > + InterfaceClass parent_class; > + /*< public >*/ > + uint64_t max_ram_below_4g; > +} PCMachineOptsClass; > + > +#endif /* PC_MACHINE_OPTS_H */ > diff --git a/vl.c b/vl.c > index 0c15608..c67ea5c 100644 > --- a/vl.c > +++ b/vl.c > @@ -382,6 +382,10 @@ static QemuOptsList qemu_machine_opts = { > .name = "kvm-type", > .type = QEMU_OPT_STRING, > .help = "Specifies the KVM virtualization mode (HV, PR)", > + },{ > + .name = "max-ram-below-4g", > + .type = QEMU_OPT_SIZE, > + .help = "maximum ram below the 4G boundary (32bit boundary)", > }, > { /* End of list */ } > }, > @@ -1623,6 +1627,7 @@ int qemu_register_machine(QEMUMachine *m) > .parent = TYPE_MACHINE, > .class_init = machine_class_init, > .class_data = (void *)m, > + .interfaces = m->interfaces, > }; > > type_register(&ti); ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [Qemu-devel] [PATCH v4 2/3] pc & q35: Add new machine opt max-ram-below-4g 2014-06-05 16:27 ` Igor Mammedov @ 2014-06-05 16:49 ` Don Slutz 0 siblings, 0 replies; 7+ messages in thread From: Don Slutz @ 2014-06-05 16:49 UTC (permalink / raw) To: Igor Mammedov, Don Slutz Cc: xen-devel, Michael S. Tsirkin, qemu-devel, Anthony Liguori, Stefano Stabellini On 06/05/14 12:27, Igor Mammedov wrote: > On Thu, 5 Jun 2014 12:11:55 -0400 > Don Slutz <dslutz@verizon.com> wrote: > >> This is a pc & q35 only machine opt. One use is to allow for more >> ram in a 32bit guest for example: >> >> -machine pc,max-ram-below-4g=3.75G >> >> If you add enough PCI devices then all mmio for them will not fit >> below 4G which may not be the layout the user wanted. This allows >> you to increase the below 4G address space that PCI devices can use >> (aka decrease ram below 4G) and therefore in more cases not have any >> mmio that is above 4G. >> >> For example using "-machine pc,max-ram-below-4g=2G" on the command >> line will limit the amount of ram that is below 4G to 2G. >> >> Signed-off-by: Don Slutz <dslutz@verizon.com> > this patch would look better if rebased on top of > http://lists.gnu.org/archive/html/qemu-devel/2014-06/msg00133.html > and would use PCMachine type to add PC specific "max-ram-below-4g" property. I somehow missed this patch series. Will work on a rebase on top of this. -Don Slutz > ^ permalink raw reply [flat|nested] 7+ messages in thread
* [Qemu-devel] [PATCH v4 3/3] xen-hvm: Pass is_default to xen_hvm_init 2014-06-05 16:11 [Qemu-devel] [PATCH v4 0/3] Add max-ram-below-4g (was Add pci_hole_min_size machine option) Don Slutz 2014-06-05 16:11 ` [Qemu-devel] [PATCH v4 1/3] xen-hvm: Fix xen_hvm_init() to adjust pc memory layout Don Slutz 2014-06-05 16:11 ` [Qemu-devel] [PATCH v4 2/3] pc & q35: Add new machine opt max-ram-below-4g Don Slutz @ 2014-06-05 16:11 ` Don Slutz 2014-06-06 11:45 ` Stefano Stabellini 2 siblings, 1 reply; 7+ messages in thread From: Don Slutz @ 2014-06-05 16:11 UTC (permalink / raw) To: xen-devel, qemu-devel, Stefano Stabellini Cc: Don Slutz, Anthony Liguori, Michael S. Tsirkin This is the xen part of "pc & q35: Add new machine opt max-ram-below-4g" Signed-off-by: Don Slutz <dslutz@verizon.com> --- v4: Pass is_default instead of max_ram_below_4g. Also did not add "Acked-by: Stefano Stabellini" since code changed a lot. hw/i386/pc_piix.c | 1 + hw/i386/pc_q35.c | 1 + include/hw/xen/xen.h | 2 +- xen-hvm-stub.c | 2 +- xen-hvm.c | 36 ++++++++++++++++++++---------------- 5 files changed, 24 insertions(+), 18 deletions(-) diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c index f631c5c..d0de12a 100644 --- a/hw/i386/pc_piix.c +++ b/hw/i386/pc_piix.c @@ -125,6 +125,7 @@ static void pc_init1(MachineState *machine, } if (xen_enabled() && xen_hvm_init(&below_4g_mem_size, &above_4g_mem_size, + !(pmc && pmc->max_ram_below_4g), &ram_memory) != 0) { fprintf(stderr, "xen hardware virtual machine initialisation failed\n"); exit(1); diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c index ba4ada2..6ae5b1a 100644 --- a/hw/i386/pc_q35.c +++ b/hw/i386/pc_q35.c @@ -114,6 +114,7 @@ static void pc_q35_init(MachineState *machine) } if (xen_enabled() && xen_hvm_init(&below_4g_mem_size, &above_4g_mem_size, + !(pmc && pmc->max_ram_below_4g), &ram_memory) != 0) { fprintf(stderr, "xen hardware virtual machine initialisation failed\n"); exit(1); diff --git a/include/hw/xen/xen.h b/include/hw/xen/xen.h index f71f2d8..6b94c14 100644 --- a/include/hw/xen/xen.h +++ b/include/hw/xen/xen.h @@ -41,7 +41,7 @@ void xenstore_store_pv_console_info(int i, struct CharDriverState *chr); #if defined(NEED_CPU_H) && !defined(CONFIG_USER_ONLY) int xen_hvm_init(ram_addr_t *below_4g_mem_size, ram_addr_t *above_4g_mem_size, - MemoryRegion **ram_memory); + bool is_default, MemoryRegion **ram_memory); void xen_ram_alloc(ram_addr_t ram_addr, ram_addr_t size, struct MemoryRegion *mr); void xen_modified_memory(ram_addr_t start, ram_addr_t length); diff --git a/xen-hvm-stub.c b/xen-hvm-stub.c index 2d98696..d1bdb76 100644 --- a/xen-hvm-stub.c +++ b/xen-hvm-stub.c @@ -52,7 +52,7 @@ void xen_modified_memory(ram_addr_t start, ram_addr_t length) } int xen_hvm_init(ram_addr_t *below_4g_mem_size, ram_addr_t *above_4g_mem_size, - MemoryRegion **ram_memory) + bool is_default, MemoryRegion **ram_memory) { return 0; } diff --git a/xen-hvm.c b/xen-hvm.c index a0b6b5d..8d27ee6 100644 --- a/xen-hvm.c +++ b/xen-hvm.c @@ -156,31 +156,34 @@ qemu_irq *xen_interrupt_controller_init(void) /* Memory Ops */ static void xen_ram_init(ram_addr_t *below_4g_mem_size, - ram_addr_t *above_4g_mem_size, + ram_addr_t *above_4g_mem_size, bool is_default, ram_addr_t ram_size, MemoryRegion **ram_memory_p) { MemoryRegion *sysmem = get_system_memory(); ram_addr_t block_len; - block_len = ram_size; - if (ram_size >= HVM_BELOW_4G_RAM_END) { - /* Xen does not allocate the memory continuously, and keep a hole at - * HVM_BELOW_4G_MMIO_START of HVM_BELOW_4G_MMIO_LENGTH + if (is_default) { + if (ram_size >= HVM_BELOW_4G_RAM_END) { + *above_4g_mem_size = ram_size - HVM_BELOW_4G_RAM_END; + *below_4g_mem_size = HVM_BELOW_4G_RAM_END; + } else { + *above_4g_mem_size = 0; + *below_4g_mem_size = ram_size; + } + } + if (!*above_4g_mem_size) { + block_len = ram_size; + } else { + /* + * Xen does not allocate the memory continuously, and keep a hole of + * of the size computed above or passed in. */ - block_len += HVM_BELOW_4G_MMIO_LENGTH; + block_len = (1ULL << 32) + *above_4g_mem_size; } memory_region_init_ram(&ram_memory, NULL, "xen.ram", block_len); *ram_memory_p = &ram_memory; vmstate_register_ram_global(&ram_memory); - if (ram_size >= HVM_BELOW_4G_RAM_END) { - *above_4g_mem_size = ram_size - HVM_BELOW_4G_RAM_END; - *below_4g_mem_size = HVM_BELOW_4G_RAM_END; - } else { - *above_4g_mem_size = 0; - *below_4g_mem_size = ram_size; - } - memory_region_init_alias(&ram_640k, NULL, "xen.ram.640k", &ram_memory, 0, 0xa0000); memory_region_add_subregion(sysmem, 0, &ram_640k); @@ -962,7 +965,7 @@ static void xen_wakeup_notifier(Notifier *notifier, void *data) } int xen_hvm_init(ram_addr_t *below_4g_mem_size, ram_addr_t *above_4g_mem_size, - MemoryRegion **ram_memory) + bool is_default, MemoryRegion **ram_memory) { int i, rc; unsigned long ioreq_pfn; @@ -1040,7 +1043,8 @@ int xen_hvm_init(ram_addr_t *below_4g_mem_size, ram_addr_t *above_4g_mem_size, /* Init RAM management */ xen_map_cache_init(xen_phys_offset_to_gaddr, state); - xen_ram_init(below_4g_mem_size, above_4g_mem_size, ram_size, ram_memory); + xen_ram_init(below_4g_mem_size, above_4g_mem_size, is_default, ram_size, + ram_memory); qemu_add_vm_change_state_handler(xen_hvm_change_state_handler, state); -- 1.8.4 ^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [Qemu-devel] [PATCH v4 3/3] xen-hvm: Pass is_default to xen_hvm_init 2014-06-05 16:11 ` [Qemu-devel] [PATCH v4 3/3] xen-hvm: Pass is_default to xen_hvm_init Don Slutz @ 2014-06-06 11:45 ` Stefano Stabellini 0 siblings, 0 replies; 7+ messages in thread From: Stefano Stabellini @ 2014-06-06 11:45 UTC (permalink / raw) To: Don Slutz Cc: xen-devel, Michael S. Tsirkin, qemu-devel, Anthony Liguori, Stefano Stabellini On Thu, 5 Jun 2014, Don Slutz wrote: > This is the xen part of "pc & q35: Add new machine opt max-ram-below-4g" > > Signed-off-by: Don Slutz <dslutz@verizon.com> Acked-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com> > v4: > Pass is_default instead of max_ram_below_4g. > Also did not add "Acked-by: Stefano Stabellini" since code changed a lot. > > hw/i386/pc_piix.c | 1 + > hw/i386/pc_q35.c | 1 + > include/hw/xen/xen.h | 2 +- > xen-hvm-stub.c | 2 +- > xen-hvm.c | 36 ++++++++++++++++++++---------------- > 5 files changed, 24 insertions(+), 18 deletions(-) > > diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c > index f631c5c..d0de12a 100644 > --- a/hw/i386/pc_piix.c > +++ b/hw/i386/pc_piix.c > @@ -125,6 +125,7 @@ static void pc_init1(MachineState *machine, > } > > if (xen_enabled() && xen_hvm_init(&below_4g_mem_size, &above_4g_mem_size, > + !(pmc && pmc->max_ram_below_4g), > &ram_memory) != 0) { > fprintf(stderr, "xen hardware virtual machine initialisation failed\n"); > exit(1); > diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c > index ba4ada2..6ae5b1a 100644 > --- a/hw/i386/pc_q35.c > +++ b/hw/i386/pc_q35.c > @@ -114,6 +114,7 @@ static void pc_q35_init(MachineState *machine) > } > > if (xen_enabled() && xen_hvm_init(&below_4g_mem_size, &above_4g_mem_size, > + !(pmc && pmc->max_ram_below_4g), > &ram_memory) != 0) { > fprintf(stderr, "xen hardware virtual machine initialisation failed\n"); > exit(1); > diff --git a/include/hw/xen/xen.h b/include/hw/xen/xen.h > index f71f2d8..6b94c14 100644 > --- a/include/hw/xen/xen.h > +++ b/include/hw/xen/xen.h > @@ -41,7 +41,7 @@ void xenstore_store_pv_console_info(int i, struct CharDriverState *chr); > > #if defined(NEED_CPU_H) && !defined(CONFIG_USER_ONLY) > int xen_hvm_init(ram_addr_t *below_4g_mem_size, ram_addr_t *above_4g_mem_size, > - MemoryRegion **ram_memory); > + bool is_default, MemoryRegion **ram_memory); > void xen_ram_alloc(ram_addr_t ram_addr, ram_addr_t size, > struct MemoryRegion *mr); > void xen_modified_memory(ram_addr_t start, ram_addr_t length); > diff --git a/xen-hvm-stub.c b/xen-hvm-stub.c > index 2d98696..d1bdb76 100644 > --- a/xen-hvm-stub.c > +++ b/xen-hvm-stub.c > @@ -52,7 +52,7 @@ void xen_modified_memory(ram_addr_t start, ram_addr_t length) > } > > int xen_hvm_init(ram_addr_t *below_4g_mem_size, ram_addr_t *above_4g_mem_size, > - MemoryRegion **ram_memory) > + bool is_default, MemoryRegion **ram_memory) > { > return 0; > } > diff --git a/xen-hvm.c b/xen-hvm.c > index a0b6b5d..8d27ee6 100644 > --- a/xen-hvm.c > +++ b/xen-hvm.c > @@ -156,31 +156,34 @@ qemu_irq *xen_interrupt_controller_init(void) > /* Memory Ops */ > > static void xen_ram_init(ram_addr_t *below_4g_mem_size, > - ram_addr_t *above_4g_mem_size, > + ram_addr_t *above_4g_mem_size, bool is_default, > ram_addr_t ram_size, MemoryRegion **ram_memory_p) > { > MemoryRegion *sysmem = get_system_memory(); > ram_addr_t block_len; > > - block_len = ram_size; > - if (ram_size >= HVM_BELOW_4G_RAM_END) { > - /* Xen does not allocate the memory continuously, and keep a hole at > - * HVM_BELOW_4G_MMIO_START of HVM_BELOW_4G_MMIO_LENGTH > + if (is_default) { > + if (ram_size >= HVM_BELOW_4G_RAM_END) { > + *above_4g_mem_size = ram_size - HVM_BELOW_4G_RAM_END; > + *below_4g_mem_size = HVM_BELOW_4G_RAM_END; > + } else { > + *above_4g_mem_size = 0; > + *below_4g_mem_size = ram_size; > + } > + } > + if (!*above_4g_mem_size) { > + block_len = ram_size; > + } else { > + /* > + * Xen does not allocate the memory continuously, and keep a hole of > + * of the size computed above or passed in. > */ > - block_len += HVM_BELOW_4G_MMIO_LENGTH; > + block_len = (1ULL << 32) + *above_4g_mem_size; > } > memory_region_init_ram(&ram_memory, NULL, "xen.ram", block_len); > *ram_memory_p = &ram_memory; > vmstate_register_ram_global(&ram_memory); > > - if (ram_size >= HVM_BELOW_4G_RAM_END) { > - *above_4g_mem_size = ram_size - HVM_BELOW_4G_RAM_END; > - *below_4g_mem_size = HVM_BELOW_4G_RAM_END; > - } else { > - *above_4g_mem_size = 0; > - *below_4g_mem_size = ram_size; > - } > - > memory_region_init_alias(&ram_640k, NULL, "xen.ram.640k", > &ram_memory, 0, 0xa0000); > memory_region_add_subregion(sysmem, 0, &ram_640k); > @@ -962,7 +965,7 @@ static void xen_wakeup_notifier(Notifier *notifier, void *data) > } > > int xen_hvm_init(ram_addr_t *below_4g_mem_size, ram_addr_t *above_4g_mem_size, > - MemoryRegion **ram_memory) > + bool is_default, MemoryRegion **ram_memory) > { > int i, rc; > unsigned long ioreq_pfn; > @@ -1040,7 +1043,8 @@ int xen_hvm_init(ram_addr_t *below_4g_mem_size, ram_addr_t *above_4g_mem_size, > > /* Init RAM management */ > xen_map_cache_init(xen_phys_offset_to_gaddr, state); > - xen_ram_init(below_4g_mem_size, above_4g_mem_size, ram_size, ram_memory); > + xen_ram_init(below_4g_mem_size, above_4g_mem_size, is_default, ram_size, > + ram_memory); > > qemu_add_vm_change_state_handler(xen_hvm_change_state_handler, state); > > -- > 1.8.4 > ^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2014-06-06 11:46 UTC | newest] Thread overview: 7+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2014-06-05 16:11 [Qemu-devel] [PATCH v4 0/3] Add max-ram-below-4g (was Add pci_hole_min_size machine option) Don Slutz 2014-06-05 16:11 ` [Qemu-devel] [PATCH v4 1/3] xen-hvm: Fix xen_hvm_init() to adjust pc memory layout Don Slutz 2014-06-05 16:11 ` [Qemu-devel] [PATCH v4 2/3] pc & q35: Add new machine opt max-ram-below-4g Don Slutz 2014-06-05 16:27 ` Igor Mammedov 2014-06-05 16:49 ` Don Slutz 2014-06-05 16:11 ` [Qemu-devel] [PATCH v4 3/3] xen-hvm: Pass is_default to xen_hvm_init Don Slutz 2014-06-06 11:45 ` Stefano Stabellini
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).