From: Greg Kroah-Hartman Date: Tue, 25 Sep 2012 20:17:27 +0000 (-0700) Subject: 3.5-stable patches X-Git-Tag: v3.0.44~71 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=ecdf9ab0794714bf9411b62ae967987678f8459e;p=thirdparty%2Fkernel%2Fstable-queue.git 3.5-stable patches added patches: xen-boot-disable-bios-smp-mp-table-search.patch xen-boot-disable-numa-for-pv-guests.patch xen-m2p-do-not-reuse-kmap_op-dev_bus_addr.patch --- diff --git a/queue-3.5/series b/queue-3.5/series index 08fcd313f90..c263aee1b7b 100644 --- a/queue-3.5/series +++ b/queue-3.5/series @@ -103,3 +103,6 @@ misdn-fix-wrong-usage-of-flush_work_sync-while-holding-locks.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-bios-smp-mp-table-search.patch +xen-boot-disable-numa-for-pv-guests.patch diff --git a/queue-3.5/xen-boot-disable-bios-smp-mp-table-search.patch b/queue-3.5/xen-boot-disable-bios-smp-mp-table-search.patch new file mode 100644 index 00000000000..b8a792dcdb2 --- /dev/null +++ b/queue-3.5/xen-boot-disable-bios-smp-mp-table-search.patch @@ -0,0 +1,89 @@ +From bd49940a35ec7d488ae63bd625639893b3385b97 Mon Sep 17 00:00:00 2001 +From: Konrad Rzeszutek Wilk +Date: Wed, 19 Sep 2012 08:30:55 -0400 +Subject: xen/boot: Disable BIOS SMP MP table search. + +From: Konrad Rzeszutek Wilk + +commit bd49940a35ec7d488ae63bd625639893b3385b97 upstream. + +As the initial domain we are able to search/map certain regions +of memory to harvest configuration data. For all low-level we +use ACPI tables - for interrupts we use exclusively ACPI _PRT +(so DSDT) and MADT for INT_SRC_OVR. + +The SMP MP table is not used at all. As a matter of fact we do +not even support machines that only have SMP MP but no ACPI tables. + +Lets follow how Moorestown does it and just disable searching +for BIOS SMP tables. + +This also fixes an issue on HP Proliant BL680c G5 and DL380 G6: + +9f->100 for 1:1 PTE +Freeing 9f-100 pfn range: 97 pages freed +1-1 mapping on 9f->100 +.. snip.. +e820: BIOS-provided physical RAM map: +Xen: [mem 0x0000000000000000-0x000000000009efff] usable +Xen: [mem 0x000000000009f400-0x00000000000fffff] reserved +Xen: [mem 0x0000000000100000-0x00000000cfd1dfff] usable +.. snip.. +Scan for SMP in [mem 0x00000000-0x000003ff] +Scan for SMP in [mem 0x0009fc00-0x0009ffff] +Scan for SMP in [mem 0x000f0000-0x000fffff] +found SMP MP-table at [mem 0x000f4fa0-0x000f4faf] mapped at [ffff8800000f4fa0] +(XEN) mm.c:908:d0 Error getting mfn 100 (pfn 5555555555555555) from L1 entry 0000000000100461 for l1e_owner=0, pg_owner=0 +(XEN) mm.c:4995:d0 ptwr_emulate: could not get_page_from_l1e() +BUG: unable to handle kernel NULL pointer dereference at (null) +IP: [] xen_set_pte_init+0x66/0x71 +. snip.. +Pid: 0, comm: swapper Not tainted 3.6.0-rc6upstream-00188-gb6fb969-dirty #2 HP ProLiant BL680c G5 +.. snip.. +Call Trace: + [] __early_ioremap+0x18a/0x248 + [] ? printk+0x48/0x4a + [] early_ioremap+0x13/0x15 + [] get_mpc_size+0x2f/0x67 + [] smp_scan_config+0x10c/0x136 + [] default_find_smp_config+0x36/0x5a + [] setup_arch+0x5b3/0xb5b + [] ? printk+0x48/0x4a + [] start_kernel+0x90/0x390 + [] x86_64_start_reservations+0x131/0x136 + [] xen_start_kernel+0x65f/0x661 +(XEN) Domain 0 crashed: 'noreboot' set - not rebooting. + +which is that ioremap would end up mapping 0xff using _PAGE_IOMAP +(which is what early_ioremap sticks as a flag) - which meant +we would get MFN 0xFF (pte ff461, which is OK), and then it would +also map 0x100 (b/c ioremap tries to get page aligned request, and +it was trying to map 0xf4fa0 + PAGE_SIZE - so it mapped the next page) +as _PAGE_IOMAP. Since 0x100 is actually a RAM page, and the _PAGE_IOMAP +bypasses the P2M lookup we would happily set the PTE to 1000461. +Xen would deny the request since we do not have access to the +Machine Frame Number (MFN) of 0x100. The P2M[0x100] is for example +0x80140. + +Fixes-Oracle-Bugzilla: https://bugzilla.oracle.com/bugzilla/show_bug.cgi?id=13665 +Acked-by: Jan Beulich +Signed-off-by: Konrad Rzeszutek Wilk +Signed-off-by: Greg Kroah-Hartman + +--- + arch/x86/xen/enlighten.c | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/arch/x86/xen/enlighten.c ++++ b/arch/x86/xen/enlighten.c +@@ -1422,6 +1422,10 @@ asmlinkage void __init xen_start_kernel( + pci_request_acs(); + + xen_acpi_sleep_register(); ++ ++ /* Avoid searching for BIOS MP tables */ ++ x86_init.mpparse.find_smp_config = x86_init_noop; ++ x86_init.mpparse.get_smp_config = x86_init_uint_noop; + } + #ifdef CONFIG_PCI + /* PCI BIOS service won't work from a PV guest. */ diff --git a/queue-3.5/xen-boot-disable-numa-for-pv-guests.patch b/queue-3.5/xen-boot-disable-numa-for-pv-guests.patch new file mode 100644 index 00000000000..a855aecc32f --- /dev/null +++ b/queue-3.5/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 + +@@ -549,4 +550,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.5/xen-m2p-do-not-reuse-kmap_op-dev_bus_addr.patch b/queue-3.5/xen-m2p-do-not-reuse-kmap_op-dev_bus_addr.patch new file mode 100644 index 00000000000..564dc3c780b --- /dev/null +++ b/queue-3.5/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 +@@ -51,7 +51,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 +@@ -828,9 +828,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)]); +@@ -857,7 +854,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; +@@ -887,10 +885,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; +@@ -902,13 +898,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); +@@ -918,8 +914,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, +@@ -930,10 +926,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 +@@ -870,7 +870,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; + bool lazy = false; +@@ -888,7 +889,8 @@ int gnttab_unmap_refs(struct gnttab_unma + } + + 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 +@@ -187,6 +187,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__ */