[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [Qemu-devel] [PATCH v4 2/3] pc & q35: Add new machine opt max-ram-below-4g
On Thu, 5 Jun 2014 12:11:55 -0400 Don Slutz <dslutz@xxxxxxxxxxx> 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@xxxxxxxxxxx> 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); _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |