qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: "Michael S. Tsirkin" <mst@redhat.com>
To: qemu-devel@nongnu.org
Cc: Peter Maydell <peter.maydell@linaro.org>,
	Don Slutz <dslutz@verizon.com>,
	Anthony Liguori <aliguori@amazon.com>
Subject: [Qemu-devel] [PULL 22/23] pc & q35: Add new machine opt max-ram-below-4g
Date: Mon, 23 Jun 2014 18:54:22 +0300	[thread overview]
Message-ID: <1403538745-18622-23-git-send-email-mst@redhat.com> (raw)
In-Reply-To: <1403538745-18622-1-git-send-email-mst@redhat.com>

From: Don Slutz <dslutz@verizon.com>

This is a pc & q35 only machine opt.

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.

Note: this machine option cannot be used to increase the amount
of ram below 4G.

Signed-off-by: Don Slutz <dslutz@verizon.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>

MST: fix 32 bit
---
 include/hw/i386/pc.h |  3 +++
 hw/i386/pc.c         | 47 +++++++++++++++++++++++++++++++++++++++++++++++
 hw/i386/pc_piix.c    | 22 +++++++++++++++++++++-
 hw/i386/pc_q35.c     | 22 +++++++++++++++++++++-
 vl.c                 |  4 ++++
 5 files changed, 96 insertions(+), 2 deletions(-)

diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
index 651971d..486e98f 100644
--- a/include/hw/i386/pc.h
+++ b/include/hw/i386/pc.h
@@ -33,10 +33,13 @@ struct PCMachineState {
     MemoryRegion hotplug_memory;
 
     HotplugHandler *acpi_dev;
+
+    uint64_t max_ram_below_4g;
 };
 
 #define PC_MACHINE_ACPI_DEVICE_PROP "acpi-device"
 #define PC_MACHINE_MEMHP_REGION_SIZE "hotplug-memory-region-size"
+#define PC_MACHINE_MAX_RAM_BELOW_4G "max-ram-below-4g"
 
 /**
  * PCMachineClass:
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 67eb450..2cf22b1 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -1643,11 +1643,58 @@ pc_machine_get_hotplug_memory_region_size(Object *obj, Visitor *v, void *opaque,
     visit_type_int(v, &value, name, errp);
 }
 
+static void pc_machine_get_max_ram_below_4g(Object *obj, Visitor *v,
+                                         void *opaque, const char *name,
+                                         Error **errp)
+{
+    PCMachineState *pcms = PC_MACHINE(obj);
+    uint64_t value = pcms->max_ram_below_4g;
+
+    visit_type_size(v, &value, name, errp);
+}
+
+static void pc_machine_set_max_ram_below_4g(Object *obj, Visitor *v,
+                                         void *opaque, const char *name,
+                                         Error **errp)
+{
+    PCMachineState *pcms = PC_MACHINE(obj);
+    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 than or equal to 4G", value);
+        error_propagate(errp, error);
+        return;
+    }
+
+    if (value < (1ULL << 20)) {
+        error_report("Warning: small max_ram_below_4g(%"PRIu64
+                     ") less than 1M.  BIOS may not work..",
+                     value);
+    }
+
+    pcms->max_ram_below_4g = value;
+}
+
 static void pc_machine_initfn(Object *obj)
 {
+    PCMachineState *pcms = PC_MACHINE(obj);
+
     object_property_add(obj, PC_MACHINE_MEMHP_REGION_SIZE, "int",
                         pc_machine_get_hotplug_memory_region_size,
                         NULL, NULL, NULL, NULL);
+    pcms->max_ram_below_4g = 1ULL << 32; /* 4G */
+    object_property_add(obj, PC_MACHINE_MAX_RAM_BELOW_4G, "size",
+                        pc_machine_get_max_ram_below_4g,
+                        pc_machine_set_max_ram_below_4g,
+                        NULL, NULL, NULL);
 }
 
 static void pc_machine_class_init(ObjectClass *oc, void *data)
diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index 60057f9..47546b7 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -48,6 +48,7 @@
 #include "exec/address-spaces.h"
 #include "hw/acpi/acpi.h"
 #include "cpu.h"
+#include "qemu/error-report.h"
 #ifdef CONFIG_XEN
 #  include <xen/hvm/hvm_info_table.h>
 #endif
@@ -98,6 +99,7 @@ static void pc_init1(MachineState *machine,
     DeviceState *icc_bridge;
     FWCfgState *fw_cfg = NULL;
     PcGuestInfo *guest_info;
+    ram_addr_t lowmem;
 
     /* 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.
@@ -107,7 +109,25 @@ static void pc_init1(MachineState *machine,
      * breaking migration.
      */
     if (machine->ram_size >= 0xe0000000) {
-        ram_addr_t lowmem = gigabyte_align ? 0xc0000000 : 0xe0000000;
+        lowmem = gigabyte_align ? 0xc0000000 : 0xe0000000;
+    } else {
+        lowmem = 0xe0000000;
+    }
+
+    /* Handle the machine opt max-ram-below-4g.  It is basicly doing
+     * min(qemu limit, user limit).
+     */
+    if (lowmem > pc_machine->max_ram_below_4g) {
+        lowmem = pc_machine->max_ram_below_4g;
+        if (machine->ram_size - lowmem > lowmem &&
+            lowmem & ((1ULL << 30) - 1)) {
+            error_report("Warning: Large machine and max_ram_below_4g(%"PRIu64
+                         ") not a multiple of 1G; possible bad performance.",
+                         pc_machine->max_ram_below_4g);
+        }
+    }
+
+    if (machine->ram_size >= lowmem) {
         above_4g_mem_size = machine->ram_size - lowmem;
         below_4g_mem_size = lowmem;
     } else {
diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c
index da5fd53..155db99 100644
--- a/hw/i386/pc_q35.c
+++ b/hw/i386/pc_q35.c
@@ -44,6 +44,7 @@
 #include "hw/ide/ahci.h"
 #include "hw/usb.h"
 #include "hw/cpu/icc_bus.h"
+#include "qemu/error-report.h"
 
 /* ICH9 AHCI has 6 ports */
 #define MAX_SATA_PORTS     6
@@ -85,6 +86,7 @@ static void pc_q35_init(MachineState *machine)
     PCIDevice *ahci;
     DeviceState *icc_bridge;
     PcGuestInfo *guest_info;
+    ram_addr_t lowmem;
 
     /* Check whether RAM fits below 4G (leaving 1/2 GByte for IO memory
      * and 256 Mbytes for PCI Express Enhanced Configuration Access Mapping
@@ -96,7 +98,25 @@ static void pc_q35_init(MachineState *machine)
      * breaking migration.
      */
     if (machine->ram_size >= 0xb0000000) {
-        ram_addr_t lowmem = gigabyte_align ? 0x80000000 : 0xb0000000;
+        lowmem = gigabyte_align ? 0x80000000 : 0xb0000000;
+    } else {
+        lowmem = 0xb0000000;
+    }
+
+    /* Handle the machine opt max-ram-below-4g.  It is basicly doing
+     * min(qemu limit, user limit).
+     */
+    if (lowmem > pc_machine->max_ram_below_4g) {
+        lowmem = pc_machine->max_ram_below_4g;
+        if (machine->ram_size - lowmem > lowmem &&
+            lowmem & ((1ULL << 30) - 1)) {
+            error_report("Warning: Large machine and max_ram_below_4g(%"PRIu64
+                         ") not a multiple of 1G; possible bad performance.",
+                         pc_machine->max_ram_below_4g);
+        }
+    }
+
+    if (machine->ram_size >= lowmem) {
         above_4g_mem_size = machine->ram_size - lowmem;
         below_4g_mem_size = lowmem;
     } else {
diff --git a/vl.c b/vl.c
index ab8f152..194c6f7 100644
--- a/vl.c
+++ b/vl.c
@@ -381,6 +381,10 @@ static QemuOptsList qemu_machine_opts = {
             .name = "kvm-type",
             .type = QEMU_OPT_STRING,
             .help = "Specifies the KVM virtualization mode (HV, PR)",
+        },{
+            .name = PC_MACHINE_MAX_RAM_BELOW_4G,
+            .type = QEMU_OPT_SIZE,
+            .help = "maximum ram below the 4G boundary (32bit boundary)",
         },
         { /* End of list */ }
     },
-- 
MST

  parent reply	other threads:[~2014-06-23 15:54 UTC|newest]

Thread overview: 25+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-06-23 15:53 [Qemu-devel] [PULL 00/23] pc,pci,vhost,net fixes, enhancements Michael S. Tsirkin
2014-06-23 15:53 ` [Qemu-devel] [PULL 01/23] vhost: block migration if backend does not log memory Michael S. Tsirkin
2014-06-23 15:53 ` [Qemu-devel] [PULL 02/23] vhost: fix resource leak in error handling Michael S. Tsirkin
2014-06-23 15:53 ` [Qemu-devel] [PULL 03/23] qapi/hmp: use 'backend' instead of 'device' with memory backend Michael S. Tsirkin
2014-06-23 15:53 ` [Qemu-devel] [PULL 04/23] libqemustub: add more stubs for qemu-char Michael S. Tsirkin
2014-06-23 15:53 ` [Qemu-devel] [PULL 05/23] qtest: fix qtest for vhost-user Michael S. Tsirkin
2014-06-23 15:53 ` [Qemu-devel] [PULL 06/23] qtest: fix vhost-user-test unbalanced mutex locks Michael S. Tsirkin
2014-06-23 15:53 ` [Qemu-devel] [PULL 07/23] e1000: emulate auto-negotiation during external link status change Michael S. Tsirkin
2014-06-23 15:53 ` [Qemu-devel] [PULL 08/23] e1000: improve auto-negotiation reporting via mii-tool Michael S. Tsirkin
2014-06-23 15:53 ` [Qemu-devel] [PULL 09/23] e1000: signal guest on successful link auto-negotiation Michael S. Tsirkin
2014-06-23 15:53 ` [Qemu-devel] [PULL 10/23] e1000: move e1000_autoneg_timer() to after set_ics() Michael S. Tsirkin
2014-06-23 15:53 ` [Qemu-devel] [PULL 11/23] e1000: factor out checking for auto-negotiation availability Michael S. Tsirkin
2014-06-23 15:53 ` [Qemu-devel] [PULL 12/23] qapi/string-output-visitor: fix human output Michael S. Tsirkin
2014-06-23 15:53 ` [Qemu-devel] [PULL 13/23] qemu-char: fix qemu_chr_fe_get_msgfd() Michael S. Tsirkin
2014-06-23 15:53 ` [Qemu-devel] [PULL 14/23] qemu-char: avoid leaking unused fds in tcp_get_msgfds() Michael S. Tsirkin
2014-06-23 15:53 ` [Qemu-devel] [PULL 15/23] virtio-pci: Report an error when msix vectors init fails Michael S. Tsirkin
2014-06-23 15:54 ` [Qemu-devel] [PULL 16/23] q35: Use PC_Q35_COMPAT_1_4 on pc-q35-1.4 compat_props Michael S. Tsirkin
2014-06-23 15:54 ` [Qemu-devel] [PULL 17/23] hw/pcie: correct debug message Michael S. Tsirkin
2014-06-23 15:54 ` [Qemu-devel] [PULL 18/23] hw/pcie: implement power controller functionality Michael S. Tsirkin
2014-06-23 15:54 ` [Qemu-devel] [PULL 19/23] hw/pcie: better hotplug/hotunplug support Michael S. Tsirkin
2014-06-23 15:54 ` [Qemu-devel] [PULL 20/23] pcie: coding style tweak Michael S. Tsirkin
2014-06-23 15:54 ` [Qemu-devel] [PULL 21/23] xen-hvm: Fix xen_hvm_init() to adjust pc memory layout Michael S. Tsirkin
2014-06-23 15:54 ` Michael S. Tsirkin [this message]
2014-06-23 15:54 ` [Qemu-devel] [PULL 23/23] xen-hvm: Handle machine opt max-ram-below-4g Michael S. Tsirkin
2014-06-24 11:21 ` [Qemu-devel] [PULL 00/23] pc,pci,vhost,net fixes, enhancements Peter Maydell

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1403538745-18622-23-git-send-email-mst@redhat.com \
    --to=mst@redhat.com \
    --cc=aliguori@amazon.com \
    --cc=dslutz@verizon.com \
    --cc=peter.maydell@linaro.org \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).