[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


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.