--- /dev/null
+From bd49940a35ec7d488ae63bd625639893b3385b97 Mon Sep 17 00:00:00 2001
+From: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
+Date: Wed, 19 Sep 2012 08:30:55 -0400
+Subject: xen/boot: Disable BIOS SMP MP table search.
+
+From: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
+
+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: [<ffffffff81ac07e2>] 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:
+ [<ffffffff81ad31c6>] __early_ioremap+0x18a/0x248
+ [<ffffffff81624731>] ? printk+0x48/0x4a
+ [<ffffffff81ad32ac>] early_ioremap+0x13/0x15
+ [<ffffffff81acc140>] get_mpc_size+0x2f/0x67
+ [<ffffffff81acc284>] smp_scan_config+0x10c/0x136
+ [<ffffffff81acc2e4>] default_find_smp_config+0x36/0x5a
+ [<ffffffff81ac3085>] setup_arch+0x5b3/0xb5b
+ [<ffffffff81624731>] ? printk+0x48/0x4a
+ [<ffffffff81abca7f>] start_kernel+0x90/0x390
+ [<ffffffff81abc356>] x86_64_start_reservations+0x131/0x136
+ [<ffffffff81abfa83>] 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 <jbeulich@suse.com>
+Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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. */
--- /dev/null
+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>
+
+@@ -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
+ }
--- /dev/null
+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
+@@ -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__ */