]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.4-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 25 Sep 2012 20:17:21 +0000 (13:17 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 25 Sep 2012 20:17:21 +0000 (13:17 -0700)
added patches:
xen-boot-disable-numa-for-pv-guests.patch
xen-m2p-do-not-reuse-kmap_op-dev_bus_addr.patch

queue-3.4/series
queue-3.4/xen-boot-disable-numa-for-pv-guests.patch [new file with mode: 0644]
queue-3.4/xen-m2p-do-not-reuse-kmap_op-dev_bus_addr.patch [new file with mode: 0644]

index 8d247d38c6c09557bf104600e7cbb6f9d0df7974..95857ef07c488ba5abba19bef19c2ddd9a16f17e 100644 (file)
@@ -80,3 +80,5 @@ sched-add-missing-call-to-calc_load_exit_idle.patch
 can-mcp251x-avoid-repeated-frame-bug.patch
 mm-ia64-fix-a-memory-block-size-bug.patch
 memory-hotplug-fix-section-info-double-registration-bug.patch
+xen-m2p-do-not-reuse-kmap_op-dev_bus_addr.patch
+xen-boot-disable-numa-for-pv-guests.patch
diff --git a/queue-3.4/xen-boot-disable-numa-for-pv-guests.patch b/queue-3.4/xen-boot-disable-numa-for-pv-guests.patch
new file mode 100644 (file)
index 0000000..3351522
--- /dev/null
@@ -0,0 +1,91 @@
+From 8d54db795dfb1049d45dc34f0dddbc5347ec5642 Mon Sep 17 00:00:00 2001
+From: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
+Date: Fri, 17 Aug 2012 10:22:37 -0400
+Subject: xen/boot: Disable NUMA for PV guests.
+
+From: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
+
+commit 8d54db795dfb1049d45dc34f0dddbc5347ec5642 upstream.
+
+The hypervisor is in charge of allocating the proper "NUMA" memory
+and dealing with the CPU scheduler to keep them bound to the proper
+NUMA node. The PV guests (and PVHVM) have no inkling of where they
+run and do not need to know that right now. In the future we will
+need to inject NUMA configuration data (if a guest spans two or more
+NUMA nodes) so that the kernel can make the right choices. But those
+patches are not yet present.
+
+In the meantime, disable the NUMA capability in the PV guest, which
+also fixes a bootup issue. Andre says:
+
+"we see Dom0 crashes due to the kernel detecting the NUMA topology not
+by ACPI, but directly from the northbridge (CONFIG_AMD_NUMA).
+
+This will detect the actual NUMA config of the physical machine, but
+will crash about the mismatch with Dom0's virtual memory. Variation of
+the theme: Dom0 sees what it's not supposed to see.
+
+This happens with the said config option enabled and on a machine where
+this scanning is still enabled (K8 and Fam10h, not Bulldozer class)
+
+We have this dump then:
+NUMA: Warning: node ids are out of bound, from=-1 to=-1 distance=10
+Scanning NUMA topology in Northbridge 24
+Number of physical nodes 4
+Node 0 MemBase 0000000000000000 Limit 0000000040000000
+Node 1 MemBase 0000000040000000 Limit 0000000138000000
+Node 2 MemBase 0000000138000000 Limit 00000001f8000000
+Node 3 MemBase 00000001f8000000 Limit 0000000238000000
+Initmem setup node 0 0000000000000000-0000000040000000
+  NODE_DATA [000000003ffd9000 - 000000003fffffff]
+Initmem setup node 1 0000000040000000-0000000138000000
+  NODE_DATA [0000000137fd9000 - 0000000137ffffff]
+Initmem setup node 2 0000000138000000-00000001f8000000
+  NODE_DATA [00000001f095e000 - 00000001f0984fff]
+Initmem setup node 3 00000001f8000000-0000000238000000
+Cannot find 159744 bytes in node 3
+BUG: unable to handle kernel NULL pointer dereference at (null)
+IP: [<ffffffff81d220e6>] __alloc_bootmem_node+0x43/0x96
+Pid: 0, comm: swapper Not tainted 3.3.6 #1 AMD Dinar/Dinar
+RIP: e030:[<ffffffff81d220e6>]  [<ffffffff81d220e6>] __alloc_bootmem_node+0x43/0x96
+.. snip..
+  [<ffffffff81d23024>] sparse_early_usemaps_alloc_node+0x64/0x178
+  [<ffffffff81d23348>] sparse_init+0xe4/0x25a
+  [<ffffffff81d16840>] paging_init+0x13/0x22
+  [<ffffffff81d07fbb>] setup_arch+0x9c6/0xa9b
+  [<ffffffff81683954>] ? printk+0x3c/0x3e
+  [<ffffffff81d01a38>] start_kernel+0xe5/0x468
+  [<ffffffff81d012cf>] x86_64_start_reservations+0xba/0xc1
+  [<ffffffff81007153>] ? xen_setup_runstate_info+0x2c/0x36
+  [<ffffffff81d050ee>] xen_start_kernel+0x565/0x56c
+"
+
+so we just disable NUMA scanning by setting numa_off=1.
+
+Reported-and-Tested-by: Andre Przywara <andre.przywara@amd.com>
+Acked-by: Andre Przywara <andre.przywara@amd.com>
+Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/x86/xen/setup.c |    4 ++++
+ 1 file changed, 4 insertions(+)
+
+--- a/arch/x86/xen/setup.c
++++ b/arch/x86/xen/setup.c
+@@ -17,6 +17,7 @@
+ #include <asm/e820.h>
+ #include <asm/setup.h>
+ #include <asm/acpi.h>
++#include <asm/numa.h>
+ #include <asm/xen/hypervisor.h>
+ #include <asm/xen/hypercall.h>
+@@ -431,4 +432,7 @@ void __init xen_arch_setup(void)
+       disable_cpufreq();
+       WARN_ON(set_pm_idle_to_default());
+       fiddle_vdso();
++#ifdef CONFIG_NUMA
++      numa_off = 1;
++#endif
+ }
diff --git a/queue-3.4/xen-m2p-do-not-reuse-kmap_op-dev_bus_addr.patch b/queue-3.4/xen-m2p-do-not-reuse-kmap_op-dev_bus_addr.patch
new file mode 100644 (file)
index 0000000..d7e864d
--- /dev/null
@@ -0,0 +1,183 @@
+From 2fc136eecd0c647a6b13fcd00d0c41a1a28f35a5 Mon Sep 17 00:00:00 2001
+From: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
+Date: Wed, 12 Sep 2012 12:44:30 +0100
+Subject: xen/m2p: do not reuse kmap_op->dev_bus_addr
+
+From: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
+
+commit 2fc136eecd0c647a6b13fcd00d0c41a1a28f35a5 upstream.
+
+If the caller passes a valid kmap_op to m2p_add_override, we use
+kmap_op->dev_bus_addr to store the original mfn, but dev_bus_addr is
+part of the interface with Xen and if we are batching the hypercalls it
+might not have been written by the hypervisor yet. That means that later
+on Xen will write to it and we'll think that the original mfn is
+actually what Xen has written to it.
+
+Rather than "stealing" struct members from kmap_op, keep using
+page->index to store the original mfn and add another parameter to
+m2p_remove_override to get the corresponding kmap_op instead.
+It is now responsibility of the caller to keep track of which kmap_op
+corresponds to a particular page in the m2p_override (gntdev, the only
+user of this interface that passes a valid kmap_op, is already doing that).
+
+Reported-and-Tested-By: Sander Eikelenboom <linux@eikelenboom.it>
+Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
+Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/x86/include/asm/xen/page.h     |    3 ++-
+ arch/x86/xen/p2m.c                  |   27 +++++++++++----------------
+ drivers/block/xen-blkback/blkback.c |    2 +-
+ drivers/xen/gntdev.c                |    5 +++--
+ drivers/xen/grant-table.c           |    6 ++++--
+ include/xen/grant_table.h           |    3 ++-
+ 6 files changed, 23 insertions(+), 23 deletions(-)
+
+--- a/arch/x86/include/asm/xen/page.h
++++ b/arch/x86/include/asm/xen/page.h
+@@ -50,7 +50,8 @@ extern unsigned long set_phys_range_iden
+ extern int m2p_add_override(unsigned long mfn, struct page *page,
+                           struct gnttab_map_grant_ref *kmap_op);
+-extern int m2p_remove_override(struct page *page, bool clear_pte);
++extern int m2p_remove_override(struct page *page,
++                              struct gnttab_map_grant_ref *kmap_op);
+ extern struct page *m2p_find_override(unsigned long mfn);
+ extern unsigned long m2p_find_override_pfn(unsigned long mfn, unsigned long pfn);
+--- a/arch/x86/xen/p2m.c
++++ b/arch/x86/xen/p2m.c
+@@ -714,9 +714,6 @@ int m2p_add_override(unsigned long mfn,
+                       xen_mc_issue(PARAVIRT_LAZY_MMU);
+               }
+-              /* let's use dev_bus_addr to record the old mfn instead */
+-              kmap_op->dev_bus_addr = page->index;
+-              page->index = (unsigned long) kmap_op;
+       }
+       spin_lock_irqsave(&m2p_override_lock, flags);
+       list_add(&page->lru,  &m2p_overrides[mfn_hash(mfn)]);
+@@ -743,7 +740,8 @@ int m2p_add_override(unsigned long mfn,
+       return 0;
+ }
+ EXPORT_SYMBOL_GPL(m2p_add_override);
+-int m2p_remove_override(struct page *page, bool clear_pte)
++int m2p_remove_override(struct page *page,
++              struct gnttab_map_grant_ref *kmap_op)
+ {
+       unsigned long flags;
+       unsigned long mfn;
+@@ -773,10 +771,8 @@ int m2p_remove_override(struct page *pag
+       WARN_ON(!PagePrivate(page));
+       ClearPagePrivate(page);
+-      if (clear_pte) {
+-              struct gnttab_map_grant_ref *map_op =
+-                      (struct gnttab_map_grant_ref *) page->index;
+-              set_phys_to_machine(pfn, map_op->dev_bus_addr);
++      set_phys_to_machine(pfn, page->index);
++      if (kmap_op != NULL) {
+               if (!PageHighMem(page)) {
+                       struct multicall_space mcs;
+                       struct gnttab_unmap_grant_ref *unmap_op;
+@@ -788,13 +784,13 @@ int m2p_remove_override(struct page *pag
+                        * issued. In this case handle is going to -1 because
+                        * it hasn't been modified yet.
+                        */
+-                      if (map_op->handle == -1)
++                      if (kmap_op->handle == -1)
+                               xen_mc_flush();
+                       /*
+-                       * Now if map_op->handle is negative it means that the
++                       * Now if kmap_op->handle is negative it means that the
+                        * hypercall actually returned an error.
+                        */
+-                      if (map_op->handle == GNTST_general_error) {
++                      if (kmap_op->handle == GNTST_general_error) {
+                               printk(KERN_WARNING "m2p_remove_override: "
+                                               "pfn %lx mfn %lx, failed to modify kernel mappings",
+                                               pfn, mfn);
+@@ -804,8 +800,8 @@ int m2p_remove_override(struct page *pag
+                       mcs = xen_mc_entry(
+                                       sizeof(struct gnttab_unmap_grant_ref));
+                       unmap_op = mcs.args;
+-                      unmap_op->host_addr = map_op->host_addr;
+-                      unmap_op->handle = map_op->handle;
++                      unmap_op->host_addr = kmap_op->host_addr;
++                      unmap_op->handle = kmap_op->handle;
+                       unmap_op->dev_bus_addr = 0;
+                       MULTI_grant_table_op(mcs.mc,
+@@ -816,10 +812,9 @@ int m2p_remove_override(struct page *pag
+                       set_pte_at(&init_mm, address, ptep,
+                                       pfn_pte(pfn, PAGE_KERNEL));
+                       __flush_tlb_single(address);
+-                      map_op->host_addr = 0;
++                      kmap_op->host_addr = 0;
+               }
+-      } else
+-              set_phys_to_machine(pfn, page->index);
++      }
+       /* p2m(m2p(mfn)) == FOREIGN_FRAME(mfn): the mfn is already present
+        * somewhere in this domain, even before being added to the
+--- a/drivers/block/xen-blkback/blkback.c
++++ b/drivers/block/xen-blkback/blkback.c
+@@ -337,7 +337,7 @@ static void xen_blkbk_unmap(struct pendi
+               invcount++;
+       }
+-      ret = gnttab_unmap_refs(unmap, pages, invcount, false);
++      ret = gnttab_unmap_refs(unmap, NULL, pages, invcount);
+       BUG_ON(ret);
+ }
+--- a/drivers/xen/gntdev.c
++++ b/drivers/xen/gntdev.c
+@@ -314,8 +314,9 @@ static int __unmap_grant_pages(struct gr
+               }
+       }
+-      err = gnttab_unmap_refs(map->unmap_ops + offset, map->pages + offset,
+-                              pages, true);
++      err = gnttab_unmap_refs(map->unmap_ops + offset,
++                      use_ptemod ? map->kmap_ops + offset : NULL, map->pages + offset,
++                      pages);
+       if (err)
+               return err;
+--- a/drivers/xen/grant-table.c
++++ b/drivers/xen/grant-table.c
+@@ -774,7 +774,8 @@ int gnttab_map_refs(struct gnttab_map_gr
+ EXPORT_SYMBOL_GPL(gnttab_map_refs);
+ int gnttab_unmap_refs(struct gnttab_unmap_grant_ref *unmap_ops,
+-                    struct page **pages, unsigned int count, bool clear_pte)
++                    struct gnttab_map_grant_ref *kmap_ops,
++                    struct page **pages, unsigned int count)
+ {
+       int i, ret;
+@@ -786,7 +787,8 @@ int gnttab_unmap_refs(struct gnttab_unma
+               return ret;
+       for (i = 0; i < count; i++) {
+-              ret = m2p_remove_override(pages[i], clear_pte);
++              ret = m2p_remove_override(pages[i], kmap_ops ?
++                                     &kmap_ops[i] : NULL);
+               if (ret)
+                       return ret;
+       }
+--- a/include/xen/grant_table.h
++++ b/include/xen/grant_table.h
+@@ -185,6 +185,7 @@ int gnttab_map_refs(struct gnttab_map_gr
+                   struct gnttab_map_grant_ref *kmap_ops,
+                   struct page **pages, unsigned int count);
+ int gnttab_unmap_refs(struct gnttab_unmap_grant_ref *unmap_ops,
+-                    struct page **pages, unsigned int count, bool clear_pte);
++                    struct gnttab_map_grant_ref *kunmap_ops,
++                    struct page **pages, unsigned int count);
+ #endif /* __ASM_GNTTAB_H__ */