From: Greg Kroah-Hartman Date: Tue, 25 Sep 2012 20:17:21 +0000 (-0700) Subject: 3.4-stable patches X-Git-Tag: v3.0.44~72 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=2bf30675ca1905d3e60402d7c6e829bf6717fed0;p=thirdparty%2Fkernel%2Fstable-queue.git 3.4-stable patches added patches: xen-boot-disable-numa-for-pv-guests.patch xen-m2p-do-not-reuse-kmap_op-dev_bus_addr.patch --- diff --git a/queue-3.4/series b/queue-3.4/series index 8d247d38c6c..95857ef07c4 100644 --- a/queue-3.4/series +++ b/queue-3.4/series @@ -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 index 00000000000..335152205f7 --- /dev/null +++ b/queue-3.4/xen-boot-disable-numa-for-pv-guests.patch @@ -0,0 +1,91 @@ +From 8d54db795dfb1049d45dc34f0dddbc5347ec5642 Mon Sep 17 00:00:00 2001 +From: Konrad Rzeszutek Wilk +Date: Fri, 17 Aug 2012 10:22:37 -0400 +Subject: xen/boot: Disable NUMA for PV guests. + +From: Konrad Rzeszutek Wilk + +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: [] __alloc_bootmem_node+0x43/0x96 +Pid: 0, comm: swapper Not tainted 3.3.6 #1 AMD Dinar/Dinar +RIP: e030:[] [] __alloc_bootmem_node+0x43/0x96 +.. snip.. + [] sparse_early_usemaps_alloc_node+0x64/0x178 + [] sparse_init+0xe4/0x25a + [] paging_init+0x13/0x22 + [] setup_arch+0x9c6/0xa9b + [] ? printk+0x3c/0x3e + [] start_kernel+0xe5/0x468 + [] x86_64_start_reservations+0xba/0xc1 + [] ? xen_setup_runstate_info+0x2c/0x36 + [] xen_start_kernel+0x565/0x56c +" + +so we just disable NUMA scanning by setting numa_off=1. + +Reported-and-Tested-by: Andre Przywara +Acked-by: Andre Przywara +Signed-off-by: Konrad Rzeszutek Wilk +Signed-off-by: Greg Kroah-Hartman + +--- + 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 + #include + #include ++#include + #include + #include + +@@ -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 index 00000000000..d7e864d0c65 --- /dev/null +++ b/queue-3.4/xen-m2p-do-not-reuse-kmap_op-dev_bus_addr.patch @@ -0,0 +1,183 @@ +From 2fc136eecd0c647a6b13fcd00d0c41a1a28f35a5 Mon Sep 17 00:00:00 2001 +From: Stefano Stabellini +Date: Wed, 12 Sep 2012 12:44:30 +0100 +Subject: xen/m2p: do not reuse kmap_op->dev_bus_addr + +From: Stefano Stabellini + +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 +Signed-off-by: Stefano Stabellini +Signed-off-by: Konrad Rzeszutek Wilk +Signed-off-by: Greg Kroah-Hartman + +--- + 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__ */