Blame 0008-pc-fix-regression-for-64-bit-PCI-memory.patch

298366
From a73c74f63aa8f977ece88c97280a03ea9b1ca395 Mon Sep 17 00:00:00 2001
298366
From: "Michael S. Tsirkin" <mst@redhat.com>
298366
Date: Tue, 27 Aug 2013 08:37:26 +0300
298366
Subject: [PATCH] pc: fix regression for 64 bit PCI memory
298366
298366
commit 398489018183d613306ab022653552247d93919f
298366
    pc: limit 64 bit hole to 2G by default
298366
introduced a way for management to control
298366
the window allocated to the 64 bit PCI hole.
298366
298366
This is useful, but existing management tools do not know how to set
298366
this property.  As a result, e.g. specifying a large ivshmem device with
298366
size > 4G is broken by default.  For example this configuration no
298366
longer works:
298366
298366
-device ivshmem,size=4294967296,chardev=cfoo
298366
-chardev socket,path=/tmp/sock,id=cfoo,server,nowait
298366
298366
Fix this by detecting that hole size was not specified
298366
and defaulting to the backwards-compatible value of 1 << 62.
298366
298366
Cc: qemu-stable@nongnu.org
298366
Cc: Igor Mammedov <imammedo@redhat.com>
298366
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
298366
(cherry picked from commit 1466cef32dd5e7ef3c6477e96d85d92302ad02e3)
298366
298366
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
298366
---
298366
 hw/pci-host/piix.c   |  9 ++++++---
298366
 hw/pci-host/q35.c    |  8 +++++---
298366
 include/hw/i386/pc.h | 11 ++++++++++-
298366
 3 files changed, 21 insertions(+), 7 deletions(-)
298366
298366
diff --git a/hw/pci-host/piix.c b/hw/pci-host/piix.c
298366
index dc1718f..221d82b 100644
298366
--- a/hw/pci-host/piix.c
298366
+++ b/hw/pci-host/piix.c
298366
@@ -320,6 +320,7 @@ PCIBus *i440fx_init(PCII440FXState **pi440fx_state,
298366
     PCII440FXState *f;
298366
     unsigned i;
298366
     I440FXState *i440fx;
298366
+    uint64_t pci_hole64_size;
298366
 
298366
     dev = qdev_create(NULL, TYPE_I440FX_PCI_HOST_BRIDGE);
298366
     s = PCI_HOST_BRIDGE(dev);
298366
@@ -351,13 +352,15 @@ PCIBus *i440fx_init(PCII440FXState **pi440fx_state,
298366
                              pci_hole_start, pci_hole_size);
298366
     memory_region_add_subregion(f->system_memory, pci_hole_start, &f->pci_hole);
298366
 
298366
+    pci_hole64_size = pci_host_get_hole64_size(i440fx->pci_hole64_size);
298366
+
298366
     pc_init_pci64_hole(&i440fx->pci_info, 0x100000000ULL + above_4g_mem_size,
298366
-                       i440fx->pci_hole64_size);
298366
+                       pci_hole64_size);
298366
     memory_region_init_alias(&f->pci_hole_64bit, OBJECT(d), "pci-hole64",
298366
                              f->pci_address_space,
298366
                              i440fx->pci_info.w64.begin,
298366
-                             i440fx->pci_hole64_size);
298366
-    if (i440fx->pci_hole64_size) {
298366
+                             pci_hole64_size);
298366
+    if (pci_hole64_size) {
298366
         memory_region_add_subregion(f->system_memory,
298366
                                     i440fx->pci_info.w64.begin,
298366
                                     &f->pci_hole_64bit);
298366
diff --git a/hw/pci-host/q35.c b/hw/pci-host/q35.c
298366
index 12314d8..4febd24 100644
298366
--- a/hw/pci-host/q35.c
298366
+++ b/hw/pci-host/q35.c
298366
@@ -320,6 +320,7 @@ static int mch_init(PCIDevice *d)
298366
 {
298366
     int i;
298366
     MCHPCIState *mch = MCH_PCI_DEVICE(d);
298366
+    uint64_t pci_hole64_size;
298366
 
298366
     /* setup pci memory regions */
298366
     memory_region_init_alias(&mch->pci_hole, OBJECT(mch), "pci-hole",
298366
@@ -329,13 +330,14 @@ static int mch_init(PCIDevice *d)
298366
     memory_region_add_subregion(mch->system_memory, mch->below_4g_mem_size,
298366
                                 &mch->pci_hole);
298366
 
298366
+    pci_hole64_size = pci_host_get_hole64_size(mch->pci_hole64_size);
298366
     pc_init_pci64_hole(&mch->pci_info, 0x100000000ULL + mch->above_4g_mem_size,
298366
-                       mch->pci_hole64_size);
298366
+                       pci_hole64_size);
298366
     memory_region_init_alias(&mch->pci_hole_64bit, OBJECT(mch), "pci-hole64",
298366
                              mch->pci_address_space,
298366
                              mch->pci_info.w64.begin,
298366
-                             mch->pci_hole64_size);
298366
-    if (mch->pci_hole64_size) {
298366
+                             pci_hole64_size);
298366
+    if (pci_hole64_size) {
298366
         memory_region_add_subregion(mch->system_memory,
298366
                                     mch->pci_info.w64.begin,
298366
                                     &mch->pci_hole_64bit);
298366
diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
298366
index f79d478..475ba9e 100644
298366
--- a/include/hw/i386/pc.h
298366
+++ b/include/hw/i386/pc.h
298366
@@ -106,7 +106,16 @@ PcGuestInfo *pc_guest_info_init(ram_addr_t below_4g_mem_size,
298366
 #define PCI_HOST_PROP_PCI_HOLE64_START "pci-hole64-start"
298366
 #define PCI_HOST_PROP_PCI_HOLE64_END   "pci-hole64-end"
298366
 #define PCI_HOST_PROP_PCI_HOLE64_SIZE  "pci-hole64-size"
298366
-#define DEFAULT_PCI_HOLE64_SIZE (1ULL << 31)
298366
+#define DEFAULT_PCI_HOLE64_SIZE (~0x0ULL)
298366
+
298366
+static inline uint64_t pci_host_get_hole64_size(uint64_t pci_hole64_size)
298366
+{
298366
+    if (pci_hole64_size == DEFAULT_PCI_HOLE64_SIZE) {
298366
+        return 1ULL << 62;
298366
+    } else {
298366
+        return pci_hole64_size;
298366
+    }
298366
+}
298366
 
298366
 void pc_init_pci64_hole(PcPciInfo *pci_info, uint64_t pci_hole64_start,
298366
                         uint64_t pci_hole64_size);