Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'stable/for-linus-3.6-rc6-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/konrad/xen

Pull Xen bug-fixes from Konrad Rzeszutek Wilk:
- Fix M2P batching re-using the incorrect structure field.

In v3.5 we added batching for M2P override (Machine Frame Number ->
Physical Frame Number), but the original MFN was saved in an
incorrect structure - and we would oops/restore when restoring with
the old MFN.

- Disable BIOS SMP MP table search.

A bootup issue that we had ignored until we found that on DL380 G6 it
was needed.

* tag 'stable/for-linus-3.6-rc6-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/konrad/xen:
xen/boot: Disable BIOS SMP MP table search.
xen/m2p: do not reuse kmap_op->dev_bus_addr

+27 -23
+2 -1
arch/x86/include/asm/xen/page.h
··· 51 51 52 52 extern int m2p_add_override(unsigned long mfn, struct page *page, 53 53 struct gnttab_map_grant_ref *kmap_op); 54 - extern int m2p_remove_override(struct page *page, bool clear_pte); 54 + extern int m2p_remove_override(struct page *page, 55 + struct gnttab_map_grant_ref *kmap_op); 55 56 extern struct page *m2p_find_override(unsigned long mfn); 56 57 extern unsigned long m2p_find_override_pfn(unsigned long mfn, unsigned long pfn); 57 58
+4
arch/x86/xen/enlighten.c
··· 1452 1452 pci_request_acs(); 1453 1453 1454 1454 xen_acpi_sleep_register(); 1455 + 1456 + /* Avoid searching for BIOS MP tables */ 1457 + x86_init.mpparse.find_smp_config = x86_init_noop; 1458 + x86_init.mpparse.get_smp_config = x86_init_uint_noop; 1455 1459 } 1456 1460 #ifdef CONFIG_PCI 1457 1461 /* PCI BIOS service won't work from a PV guest. */
+11 -16
arch/x86/xen/p2m.c
··· 828 828 829 829 xen_mc_issue(PARAVIRT_LAZY_MMU); 830 830 } 831 - /* let's use dev_bus_addr to record the old mfn instead */ 832 - kmap_op->dev_bus_addr = page->index; 833 - page->index = (unsigned long) kmap_op; 834 831 } 835 832 spin_lock_irqsave(&m2p_override_lock, flags); 836 833 list_add(&page->lru, &m2p_overrides[mfn_hash(mfn)]); ··· 854 857 return 0; 855 858 } 856 859 EXPORT_SYMBOL_GPL(m2p_add_override); 857 - int m2p_remove_override(struct page *page, bool clear_pte) 860 + int m2p_remove_override(struct page *page, 861 + struct gnttab_map_grant_ref *kmap_op) 858 862 { 859 863 unsigned long flags; 860 864 unsigned long mfn; ··· 885 887 WARN_ON(!PagePrivate(page)); 886 888 ClearPagePrivate(page); 887 889 888 - if (clear_pte) { 889 - struct gnttab_map_grant_ref *map_op = 890 - (struct gnttab_map_grant_ref *) page->index; 891 - set_phys_to_machine(pfn, map_op->dev_bus_addr); 890 + set_phys_to_machine(pfn, page->index); 891 + if (kmap_op != NULL) { 892 892 if (!PageHighMem(page)) { 893 893 struct multicall_space mcs; 894 894 struct gnttab_unmap_grant_ref *unmap_op; ··· 898 902 * issued. In this case handle is going to -1 because 899 903 * it hasn't been modified yet. 900 904 */ 901 - if (map_op->handle == -1) 905 + if (kmap_op->handle == -1) 902 906 xen_mc_flush(); 903 907 /* 904 - * Now if map_op->handle is negative it means that the 908 + * Now if kmap_op->handle is negative it means that the 905 909 * hypercall actually returned an error. 906 910 */ 907 - if (map_op->handle == GNTST_general_error) { 911 + if (kmap_op->handle == GNTST_general_error) { 908 912 printk(KERN_WARNING "m2p_remove_override: " 909 913 "pfn %lx mfn %lx, failed to modify kernel mappings", 910 914 pfn, mfn); ··· 914 918 mcs = xen_mc_entry( 915 919 sizeof(struct gnttab_unmap_grant_ref)); 916 920 unmap_op = mcs.args; 917 - unmap_op->host_addr = map_op->host_addr; 918 - unmap_op->handle = map_op->handle; 921 + unmap_op->host_addr = kmap_op->host_addr; 922 + unmap_op->handle = kmap_op->handle; 919 923 unmap_op->dev_bus_addr = 0; 920 924 921 925 MULTI_grant_table_op(mcs.mc, ··· 926 930 set_pte_at(&init_mm, address, ptep, 927 931 pfn_pte(pfn, PAGE_KERNEL)); 928 932 __flush_tlb_single(address); 929 - map_op->host_addr = 0; 933 + kmap_op->host_addr = 0; 930 934 } 931 - } else 932 - set_phys_to_machine(pfn, page->index); 935 + } 933 936 934 937 /* p2m(m2p(mfn)) == FOREIGN_FRAME(mfn): the mfn is already present 935 938 * somewhere in this domain, even before being added to the
+1 -1
drivers/block/xen-blkback/blkback.c
··· 337 337 invcount++; 338 338 } 339 339 340 - ret = gnttab_unmap_refs(unmap, pages, invcount, false); 340 + ret = gnttab_unmap_refs(unmap, NULL, pages, invcount); 341 341 BUG_ON(ret); 342 342 } 343 343
+3 -2
drivers/xen/gntdev.c
··· 314 314 } 315 315 } 316 316 317 - err = gnttab_unmap_refs(map->unmap_ops + offset, map->pages + offset, 318 - pages, true); 317 + err = gnttab_unmap_refs(map->unmap_ops + offset, 318 + use_ptemod ? map->kmap_ops + offset : NULL, map->pages + offset, 319 + pages); 319 320 if (err) 320 321 return err; 321 322
+4 -2
drivers/xen/grant-table.c
··· 870 870 EXPORT_SYMBOL_GPL(gnttab_map_refs); 871 871 872 872 int gnttab_unmap_refs(struct gnttab_unmap_grant_ref *unmap_ops, 873 - struct page **pages, unsigned int count, bool clear_pte) 873 + struct gnttab_map_grant_ref *kmap_ops, 874 + struct page **pages, unsigned int count) 874 875 { 875 876 int i, ret; 876 877 bool lazy = false; ··· 889 888 } 890 889 891 890 for (i = 0; i < count; i++) { 892 - ret = m2p_remove_override(pages[i], clear_pte); 891 + ret = m2p_remove_override(pages[i], kmap_ops ? 892 + &kmap_ops[i] : NULL); 893 893 if (ret) 894 894 return ret; 895 895 }
+2 -1
include/xen/grant_table.h
··· 187 187 struct gnttab_map_grant_ref *kmap_ops, 188 188 struct page **pages, unsigned int count); 189 189 int gnttab_unmap_refs(struct gnttab_unmap_grant_ref *unmap_ops, 190 - struct page **pages, unsigned int count, bool clear_pte); 190 + struct gnttab_map_grant_ref *kunmap_ops, 191 + struct page **pages, unsigned int count); 191 192 192 193 #endif /* __ASM_GNTTAB_H__ */