diff options
Diffstat (limited to 'arch/x86/xen')
-rw-r--r-- | arch/x86/xen/enlighten.c | 20 | ||||
-rw-r--r-- | arch/x86/xen/irq.c | 2 | ||||
-rw-r--r-- | arch/x86/xen/mmu.c | 64 | ||||
-rw-r--r-- | arch/x86/xen/p2m.c | 43 | ||||
-rw-r--r-- | arch/x86/xen/setup.c | 10 | ||||
-rw-r--r-- | arch/x86/xen/smp.c | 13 | ||||
-rw-r--r-- | arch/x86/xen/time.c | 14 | ||||
-rw-r--r-- | arch/x86/xen/xen-ops.h | 2 |
8 files changed, 106 insertions, 62 deletions
diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c index e3c6a06cf725..dd7b88f2ec7a 100644 --- a/arch/x86/xen/enlighten.c +++ b/arch/x86/xen/enlighten.c | |||
@@ -235,7 +235,7 @@ static void xen_cpuid(unsigned int *ax, unsigned int *bx, | |||
235 | *dx &= maskedx; | 235 | *dx &= maskedx; |
236 | } | 236 | } |
237 | 237 | ||
238 | static __init void xen_init_cpuid_mask(void) | 238 | static void __init xen_init_cpuid_mask(void) |
239 | { | 239 | { |
240 | unsigned int ax, bx, cx, dx; | 240 | unsigned int ax, bx, cx, dx; |
241 | unsigned int xsave_mask; | 241 | unsigned int xsave_mask; |
@@ -400,7 +400,7 @@ static void xen_load_gdt(const struct desc_ptr *dtr) | |||
400 | /* | 400 | /* |
401 | * load_gdt for early boot, when the gdt is only mapped once | 401 | * load_gdt for early boot, when the gdt is only mapped once |
402 | */ | 402 | */ |
403 | static __init void xen_load_gdt_boot(const struct desc_ptr *dtr) | 403 | static void __init xen_load_gdt_boot(const struct desc_ptr *dtr) |
404 | { | 404 | { |
405 | unsigned long va = dtr->address; | 405 | unsigned long va = dtr->address; |
406 | unsigned int size = dtr->size + 1; | 406 | unsigned int size = dtr->size + 1; |
@@ -662,7 +662,7 @@ static void xen_write_gdt_entry(struct desc_struct *dt, int entry, | |||
662 | * Version of write_gdt_entry for use at early boot-time needed to | 662 | * Version of write_gdt_entry for use at early boot-time needed to |
663 | * update an entry as simply as possible. | 663 | * update an entry as simply as possible. |
664 | */ | 664 | */ |
665 | static __init void xen_write_gdt_entry_boot(struct desc_struct *dt, int entry, | 665 | static void __init xen_write_gdt_entry_boot(struct desc_struct *dt, int entry, |
666 | const void *desc, int type) | 666 | const void *desc, int type) |
667 | { | 667 | { |
668 | switch (type) { | 668 | switch (type) { |
@@ -933,18 +933,18 @@ static unsigned xen_patch(u8 type, u16 clobbers, void *insnbuf, | |||
933 | return ret; | 933 | return ret; |
934 | } | 934 | } |
935 | 935 | ||
936 | static const struct pv_info xen_info __initdata = { | 936 | static const struct pv_info xen_info __initconst = { |
937 | .paravirt_enabled = 1, | 937 | .paravirt_enabled = 1, |
938 | .shared_kernel_pmd = 0, | 938 | .shared_kernel_pmd = 0, |
939 | 939 | ||
940 | .name = "Xen", | 940 | .name = "Xen", |
941 | }; | 941 | }; |
942 | 942 | ||
943 | static const struct pv_init_ops xen_init_ops __initdata = { | 943 | static const struct pv_init_ops xen_init_ops __initconst = { |
944 | .patch = xen_patch, | 944 | .patch = xen_patch, |
945 | }; | 945 | }; |
946 | 946 | ||
947 | static const struct pv_cpu_ops xen_cpu_ops __initdata = { | 947 | static const struct pv_cpu_ops xen_cpu_ops __initconst = { |
948 | .cpuid = xen_cpuid, | 948 | .cpuid = xen_cpuid, |
949 | 949 | ||
950 | .set_debugreg = xen_set_debugreg, | 950 | .set_debugreg = xen_set_debugreg, |
@@ -1004,7 +1004,7 @@ static const struct pv_cpu_ops xen_cpu_ops __initdata = { | |||
1004 | .end_context_switch = xen_end_context_switch, | 1004 | .end_context_switch = xen_end_context_switch, |
1005 | }; | 1005 | }; |
1006 | 1006 | ||
1007 | static const struct pv_apic_ops xen_apic_ops __initdata = { | 1007 | static const struct pv_apic_ops xen_apic_ops __initconst = { |
1008 | #ifdef CONFIG_X86_LOCAL_APIC | 1008 | #ifdef CONFIG_X86_LOCAL_APIC |
1009 | .startup_ipi_hook = paravirt_nop, | 1009 | .startup_ipi_hook = paravirt_nop, |
1010 | #endif | 1010 | #endif |
@@ -1055,7 +1055,7 @@ int xen_panic_handler_init(void) | |||
1055 | return 0; | 1055 | return 0; |
1056 | } | 1056 | } |
1057 | 1057 | ||
1058 | static const struct machine_ops __initdata xen_machine_ops = { | 1058 | static const struct machine_ops xen_machine_ops __initconst = { |
1059 | .restart = xen_restart, | 1059 | .restart = xen_restart, |
1060 | .halt = xen_machine_halt, | 1060 | .halt = xen_machine_halt, |
1061 | .power_off = xen_machine_halt, | 1061 | .power_off = xen_machine_halt, |
@@ -1332,7 +1332,7 @@ static int __cpuinit xen_hvm_cpu_notify(struct notifier_block *self, | |||
1332 | return NOTIFY_OK; | 1332 | return NOTIFY_OK; |
1333 | } | 1333 | } |
1334 | 1334 | ||
1335 | static struct notifier_block __cpuinitdata xen_hvm_cpu_notifier = { | 1335 | static struct notifier_block xen_hvm_cpu_notifier __cpuinitdata = { |
1336 | .notifier_call = xen_hvm_cpu_notify, | 1336 | .notifier_call = xen_hvm_cpu_notify, |
1337 | }; | 1337 | }; |
1338 | 1338 | ||
@@ -1381,7 +1381,7 @@ bool xen_hvm_need_lapic(void) | |||
1381 | } | 1381 | } |
1382 | EXPORT_SYMBOL_GPL(xen_hvm_need_lapic); | 1382 | EXPORT_SYMBOL_GPL(xen_hvm_need_lapic); |
1383 | 1383 | ||
1384 | const __refconst struct hypervisor_x86 x86_hyper_xen_hvm = { | 1384 | const struct hypervisor_x86 x86_hyper_xen_hvm __refconst = { |
1385 | .name = "Xen HVM", | 1385 | .name = "Xen HVM", |
1386 | .detect = xen_hvm_platform, | 1386 | .detect = xen_hvm_platform, |
1387 | .init_platform = xen_hvm_guest_init, | 1387 | .init_platform = xen_hvm_guest_init, |
diff --git a/arch/x86/xen/irq.c b/arch/x86/xen/irq.c index 6a6fe8939645..8bbb465b6f0a 100644 --- a/arch/x86/xen/irq.c +++ b/arch/x86/xen/irq.c | |||
@@ -113,7 +113,7 @@ static void xen_halt(void) | |||
113 | xen_safe_halt(); | 113 | xen_safe_halt(); |
114 | } | 114 | } |
115 | 115 | ||
116 | static const struct pv_irq_ops xen_irq_ops __initdata = { | 116 | static const struct pv_irq_ops xen_irq_ops __initconst = { |
117 | .save_fl = PV_CALLEE_SAVE(xen_save_fl), | 117 | .save_fl = PV_CALLEE_SAVE(xen_save_fl), |
118 | .restore_fl = PV_CALLEE_SAVE(xen_restore_fl), | 118 | .restore_fl = PV_CALLEE_SAVE(xen_restore_fl), |
119 | .irq_disable = PV_CALLEE_SAVE(xen_irq_disable), | 119 | .irq_disable = PV_CALLEE_SAVE(xen_irq_disable), |
diff --git a/arch/x86/xen/mmu.c b/arch/x86/xen/mmu.c index a991b57f91fe..02d752460371 100644 --- a/arch/x86/xen/mmu.c +++ b/arch/x86/xen/mmu.c | |||
@@ -1054,7 +1054,7 @@ void xen_mm_pin_all(void) | |||
1054 | * that's before we have page structures to store the bits. So do all | 1054 | * that's before we have page structures to store the bits. So do all |
1055 | * the book-keeping now. | 1055 | * the book-keeping now. |
1056 | */ | 1056 | */ |
1057 | static __init int xen_mark_pinned(struct mm_struct *mm, struct page *page, | 1057 | static int __init xen_mark_pinned(struct mm_struct *mm, struct page *page, |
1058 | enum pt_level level) | 1058 | enum pt_level level) |
1059 | { | 1059 | { |
1060 | SetPagePinned(page); | 1060 | SetPagePinned(page); |
@@ -1187,7 +1187,7 @@ static void drop_other_mm_ref(void *info) | |||
1187 | 1187 | ||
1188 | active_mm = percpu_read(cpu_tlbstate.active_mm); | 1188 | active_mm = percpu_read(cpu_tlbstate.active_mm); |
1189 | 1189 | ||
1190 | if (active_mm == mm) | 1190 | if (active_mm == mm && percpu_read(cpu_tlbstate.state) != TLBSTATE_OK) |
1191 | leave_mm(smp_processor_id()); | 1191 | leave_mm(smp_processor_id()); |
1192 | 1192 | ||
1193 | /* If this cpu still has a stale cr3 reference, then make sure | 1193 | /* If this cpu still has a stale cr3 reference, then make sure |
@@ -1271,13 +1271,27 @@ void xen_exit_mmap(struct mm_struct *mm) | |||
1271 | spin_unlock(&mm->page_table_lock); | 1271 | spin_unlock(&mm->page_table_lock); |
1272 | } | 1272 | } |
1273 | 1273 | ||
1274 | static __init void xen_pagetable_setup_start(pgd_t *base) | 1274 | static void __init xen_pagetable_setup_start(pgd_t *base) |
1275 | { | 1275 | { |
1276 | } | 1276 | } |
1277 | 1277 | ||
1278 | static __init void xen_mapping_pagetable_reserve(u64 start, u64 end) | ||
1279 | { | ||
1280 | /* reserve the range used */ | ||
1281 | native_pagetable_reserve(start, end); | ||
1282 | |||
1283 | /* set as RW the rest */ | ||
1284 | printk(KERN_DEBUG "xen: setting RW the range %llx - %llx\n", end, | ||
1285 | PFN_PHYS(pgt_buf_top)); | ||
1286 | while (end < PFN_PHYS(pgt_buf_top)) { | ||
1287 | make_lowmem_page_readwrite(__va(end)); | ||
1288 | end += PAGE_SIZE; | ||
1289 | } | ||
1290 | } | ||
1291 | |||
1278 | static void xen_post_allocator_init(void); | 1292 | static void xen_post_allocator_init(void); |
1279 | 1293 | ||
1280 | static __init void xen_pagetable_setup_done(pgd_t *base) | 1294 | static void __init xen_pagetable_setup_done(pgd_t *base) |
1281 | { | 1295 | { |
1282 | xen_setup_shared_info(); | 1296 | xen_setup_shared_info(); |
1283 | xen_post_allocator_init(); | 1297 | xen_post_allocator_init(); |
@@ -1473,16 +1487,20 @@ static void xen_pgd_free(struct mm_struct *mm, pgd_t *pgd) | |||
1473 | #endif | 1487 | #endif |
1474 | } | 1488 | } |
1475 | 1489 | ||
1476 | static __init pte_t mask_rw_pte(pte_t *ptep, pte_t pte) | ||
1477 | { | ||
1478 | unsigned long pfn = pte_pfn(pte); | ||
1479 | |||
1480 | #ifdef CONFIG_X86_32 | 1490 | #ifdef CONFIG_X86_32 |
1491 | static pte_t __init mask_rw_pte(pte_t *ptep, pte_t pte) | ||
1492 | { | ||
1481 | /* If there's an existing pte, then don't allow _PAGE_RW to be set */ | 1493 | /* If there's an existing pte, then don't allow _PAGE_RW to be set */ |
1482 | if (pte_val_ma(*ptep) & _PAGE_PRESENT) | 1494 | if (pte_val_ma(*ptep) & _PAGE_PRESENT) |
1483 | pte = __pte_ma(((pte_val_ma(*ptep) & _PAGE_RW) | ~_PAGE_RW) & | 1495 | pte = __pte_ma(((pte_val_ma(*ptep) & _PAGE_RW) | ~_PAGE_RW) & |
1484 | pte_val_ma(pte)); | 1496 | pte_val_ma(pte)); |
1485 | #endif | 1497 | |
1498 | return pte; | ||
1499 | } | ||
1500 | #else /* CONFIG_X86_64 */ | ||
1501 | static pte_t __init mask_rw_pte(pte_t *ptep, pte_t pte) | ||
1502 | { | ||
1503 | unsigned long pfn = pte_pfn(pte); | ||
1486 | 1504 | ||
1487 | /* | 1505 | /* |
1488 | * If the new pfn is within the range of the newly allocated | 1506 | * If the new pfn is within the range of the newly allocated |
@@ -1491,16 +1509,17 @@ static __init pte_t mask_rw_pte(pte_t *ptep, pte_t pte) | |||
1491 | * it is RO. | 1509 | * it is RO. |
1492 | */ | 1510 | */ |
1493 | if (((!is_early_ioremap_ptep(ptep) && | 1511 | if (((!is_early_ioremap_ptep(ptep) && |
1494 | pfn >= pgt_buf_start && pfn < pgt_buf_end)) || | 1512 | pfn >= pgt_buf_start && pfn < pgt_buf_top)) || |
1495 | (is_early_ioremap_ptep(ptep) && pfn != (pgt_buf_end - 1))) | 1513 | (is_early_ioremap_ptep(ptep) && pfn != (pgt_buf_end - 1))) |
1496 | pte = pte_wrprotect(pte); | 1514 | pte = pte_wrprotect(pte); |
1497 | 1515 | ||
1498 | return pte; | 1516 | return pte; |
1499 | } | 1517 | } |
1518 | #endif /* CONFIG_X86_64 */ | ||
1500 | 1519 | ||
1501 | /* Init-time set_pte while constructing initial pagetables, which | 1520 | /* Init-time set_pte while constructing initial pagetables, which |
1502 | doesn't allow RO pagetable pages to be remapped RW */ | 1521 | doesn't allow RO pagetable pages to be remapped RW */ |
1503 | static __init void xen_set_pte_init(pte_t *ptep, pte_t pte) | 1522 | static void __init xen_set_pte_init(pte_t *ptep, pte_t pte) |
1504 | { | 1523 | { |
1505 | pte = mask_rw_pte(ptep, pte); | 1524 | pte = mask_rw_pte(ptep, pte); |
1506 | 1525 | ||
@@ -1518,7 +1537,7 @@ static void pin_pagetable_pfn(unsigned cmd, unsigned long pfn) | |||
1518 | 1537 | ||
1519 | /* Early in boot, while setting up the initial pagetable, assume | 1538 | /* Early in boot, while setting up the initial pagetable, assume |
1520 | everything is pinned. */ | 1539 | everything is pinned. */ |
1521 | static __init void xen_alloc_pte_init(struct mm_struct *mm, unsigned long pfn) | 1540 | static void __init xen_alloc_pte_init(struct mm_struct *mm, unsigned long pfn) |
1522 | { | 1541 | { |
1523 | #ifdef CONFIG_FLATMEM | 1542 | #ifdef CONFIG_FLATMEM |
1524 | BUG_ON(mem_map); /* should only be used early */ | 1543 | BUG_ON(mem_map); /* should only be used early */ |
@@ -1528,7 +1547,7 @@ static __init void xen_alloc_pte_init(struct mm_struct *mm, unsigned long pfn) | |||
1528 | } | 1547 | } |
1529 | 1548 | ||
1530 | /* Used for pmd and pud */ | 1549 | /* Used for pmd and pud */ |
1531 | static __init void xen_alloc_pmd_init(struct mm_struct *mm, unsigned long pfn) | 1550 | static void __init xen_alloc_pmd_init(struct mm_struct *mm, unsigned long pfn) |
1532 | { | 1551 | { |
1533 | #ifdef CONFIG_FLATMEM | 1552 | #ifdef CONFIG_FLATMEM |
1534 | BUG_ON(mem_map); /* should only be used early */ | 1553 | BUG_ON(mem_map); /* should only be used early */ |
@@ -1538,13 +1557,13 @@ static __init void xen_alloc_pmd_init(struct mm_struct *mm, unsigned long pfn) | |||
1538 | 1557 | ||
1539 | /* Early release_pte assumes that all pts are pinned, since there's | 1558 | /* Early release_pte assumes that all pts are pinned, since there's |
1540 | only init_mm and anything attached to that is pinned. */ | 1559 | only init_mm and anything attached to that is pinned. */ |
1541 | static __init void xen_release_pte_init(unsigned long pfn) | 1560 | static void __init xen_release_pte_init(unsigned long pfn) |
1542 | { | 1561 | { |
1543 | pin_pagetable_pfn(MMUEXT_UNPIN_TABLE, pfn); | 1562 | pin_pagetable_pfn(MMUEXT_UNPIN_TABLE, pfn); |
1544 | make_lowmem_page_readwrite(__va(PFN_PHYS(pfn))); | 1563 | make_lowmem_page_readwrite(__va(PFN_PHYS(pfn))); |
1545 | } | 1564 | } |
1546 | 1565 | ||
1547 | static __init void xen_release_pmd_init(unsigned long pfn) | 1566 | static void __init xen_release_pmd_init(unsigned long pfn) |
1548 | { | 1567 | { |
1549 | make_lowmem_page_readwrite(__va(PFN_PHYS(pfn))); | 1568 | make_lowmem_page_readwrite(__va(PFN_PHYS(pfn))); |
1550 | } | 1569 | } |
@@ -1670,7 +1689,7 @@ static void set_page_prot(void *addr, pgprot_t prot) | |||
1670 | BUG(); | 1689 | BUG(); |
1671 | } | 1690 | } |
1672 | 1691 | ||
1673 | static __init void xen_map_identity_early(pmd_t *pmd, unsigned long max_pfn) | 1692 | static void __init xen_map_identity_early(pmd_t *pmd, unsigned long max_pfn) |
1674 | { | 1693 | { |
1675 | unsigned pmdidx, pteidx; | 1694 | unsigned pmdidx, pteidx; |
1676 | unsigned ident_pte; | 1695 | unsigned ident_pte; |
@@ -1753,7 +1772,7 @@ static void convert_pfn_mfn(void *v) | |||
1753 | * of the physical mapping once some sort of allocator has been set | 1772 | * of the physical mapping once some sort of allocator has been set |
1754 | * up. | 1773 | * up. |
1755 | */ | 1774 | */ |
1756 | __init pgd_t *xen_setup_kernel_pagetable(pgd_t *pgd, | 1775 | pgd_t * __init xen_setup_kernel_pagetable(pgd_t *pgd, |
1757 | unsigned long max_pfn) | 1776 | unsigned long max_pfn) |
1758 | { | 1777 | { |
1759 | pud_t *l3; | 1778 | pud_t *l3; |
@@ -1824,7 +1843,7 @@ __init pgd_t *xen_setup_kernel_pagetable(pgd_t *pgd, | |||
1824 | static RESERVE_BRK_ARRAY(pmd_t, initial_kernel_pmd, PTRS_PER_PMD); | 1843 | static RESERVE_BRK_ARRAY(pmd_t, initial_kernel_pmd, PTRS_PER_PMD); |
1825 | static RESERVE_BRK_ARRAY(pmd_t, swapper_kernel_pmd, PTRS_PER_PMD); | 1844 | static RESERVE_BRK_ARRAY(pmd_t, swapper_kernel_pmd, PTRS_PER_PMD); |
1826 | 1845 | ||
1827 | static __init void xen_write_cr3_init(unsigned long cr3) | 1846 | static void __init xen_write_cr3_init(unsigned long cr3) |
1828 | { | 1847 | { |
1829 | unsigned long pfn = PFN_DOWN(__pa(swapper_pg_dir)); | 1848 | unsigned long pfn = PFN_DOWN(__pa(swapper_pg_dir)); |
1830 | 1849 | ||
@@ -1861,7 +1880,7 @@ static __init void xen_write_cr3_init(unsigned long cr3) | |||
1861 | pv_mmu_ops.write_cr3 = &xen_write_cr3; | 1880 | pv_mmu_ops.write_cr3 = &xen_write_cr3; |
1862 | } | 1881 | } |
1863 | 1882 | ||
1864 | __init pgd_t *xen_setup_kernel_pagetable(pgd_t *pgd, | 1883 | pgd_t * __init xen_setup_kernel_pagetable(pgd_t *pgd, |
1865 | unsigned long max_pfn) | 1884 | unsigned long max_pfn) |
1866 | { | 1885 | { |
1867 | pmd_t *kernel_pmd; | 1886 | pmd_t *kernel_pmd; |
@@ -1967,7 +1986,7 @@ static void xen_set_fixmap(unsigned idx, phys_addr_t phys, pgprot_t prot) | |||
1967 | #endif | 1986 | #endif |
1968 | } | 1987 | } |
1969 | 1988 | ||
1970 | __init void xen_ident_map_ISA(void) | 1989 | void __init xen_ident_map_ISA(void) |
1971 | { | 1990 | { |
1972 | unsigned long pa; | 1991 | unsigned long pa; |
1973 | 1992 | ||
@@ -1990,7 +2009,7 @@ __init void xen_ident_map_ISA(void) | |||
1990 | xen_flush_tlb(); | 2009 | xen_flush_tlb(); |
1991 | } | 2010 | } |
1992 | 2011 | ||
1993 | static __init void xen_post_allocator_init(void) | 2012 | static void __init xen_post_allocator_init(void) |
1994 | { | 2013 | { |
1995 | #ifdef CONFIG_XEN_DEBUG | 2014 | #ifdef CONFIG_XEN_DEBUG |
1996 | pv_mmu_ops.make_pte = PV_CALLEE_SAVE(xen_make_pte_debug); | 2015 | pv_mmu_ops.make_pte = PV_CALLEE_SAVE(xen_make_pte_debug); |
@@ -2027,7 +2046,7 @@ static void xen_leave_lazy_mmu(void) | |||
2027 | preempt_enable(); | 2046 | preempt_enable(); |
2028 | } | 2047 | } |
2029 | 2048 | ||
2030 | static const struct pv_mmu_ops xen_mmu_ops __initdata = { | 2049 | static const struct pv_mmu_ops xen_mmu_ops __initconst = { |
2031 | .read_cr2 = xen_read_cr2, | 2050 | .read_cr2 = xen_read_cr2, |
2032 | .write_cr2 = xen_write_cr2, | 2051 | .write_cr2 = xen_write_cr2, |
2033 | 2052 | ||
@@ -2100,6 +2119,7 @@ static const struct pv_mmu_ops xen_mmu_ops __initdata = { | |||
2100 | 2119 | ||
2101 | void __init xen_init_mmu_ops(void) | 2120 | void __init xen_init_mmu_ops(void) |
2102 | { | 2121 | { |
2122 | x86_init.mapping.pagetable_reserve = xen_mapping_pagetable_reserve; | ||
2103 | x86_init.paging.pagetable_setup_start = xen_pagetable_setup_start; | 2123 | x86_init.paging.pagetable_setup_start = xen_pagetable_setup_start; |
2104 | x86_init.paging.pagetable_setup_done = xen_pagetable_setup_done; | 2124 | x86_init.paging.pagetable_setup_done = xen_pagetable_setup_done; |
2105 | pv_mmu_ops = xen_mmu_ops; | 2125 | pv_mmu_ops = xen_mmu_ops; |
diff --git a/arch/x86/xen/p2m.c b/arch/x86/xen/p2m.c index 141eb0de8b06..58efeb9d5440 100644 --- a/arch/x86/xen/p2m.c +++ b/arch/x86/xen/p2m.c | |||
@@ -522,11 +522,20 @@ static bool __init __early_alloc_p2m(unsigned long pfn) | |||
522 | /* Boundary cross-over for the edges: */ | 522 | /* Boundary cross-over for the edges: */ |
523 | if (idx) { | 523 | if (idx) { |
524 | unsigned long *p2m = extend_brk(PAGE_SIZE, PAGE_SIZE); | 524 | unsigned long *p2m = extend_brk(PAGE_SIZE, PAGE_SIZE); |
525 | unsigned long *mid_mfn_p; | ||
525 | 526 | ||
526 | p2m_init(p2m); | 527 | p2m_init(p2m); |
527 | 528 | ||
528 | p2m_top[topidx][mididx] = p2m; | 529 | p2m_top[topidx][mididx] = p2m; |
529 | 530 | ||
531 | /* For save/restore we need to MFN of the P2M saved */ | ||
532 | |||
533 | mid_mfn_p = p2m_top_mfn_p[topidx]; | ||
534 | WARN(mid_mfn_p[mididx] != virt_to_mfn(p2m_missing), | ||
535 | "P2M_TOP_P[%d][%d] != MFN of p2m_missing!\n", | ||
536 | topidx, mididx); | ||
537 | mid_mfn_p[mididx] = virt_to_mfn(p2m); | ||
538 | |||
530 | } | 539 | } |
531 | return idx != 0; | 540 | return idx != 0; |
532 | } | 541 | } |
@@ -549,12 +558,29 @@ unsigned long __init set_phys_range_identity(unsigned long pfn_s, | |||
549 | pfn += P2M_MID_PER_PAGE * P2M_PER_PAGE) | 558 | pfn += P2M_MID_PER_PAGE * P2M_PER_PAGE) |
550 | { | 559 | { |
551 | unsigned topidx = p2m_top_index(pfn); | 560 | unsigned topidx = p2m_top_index(pfn); |
552 | if (p2m_top[topidx] == p2m_mid_missing) { | 561 | unsigned long *mid_mfn_p; |
553 | unsigned long **mid = extend_brk(PAGE_SIZE, PAGE_SIZE); | 562 | unsigned long **mid; |
563 | |||
564 | mid = p2m_top[topidx]; | ||
565 | mid_mfn_p = p2m_top_mfn_p[topidx]; | ||
566 | if (mid == p2m_mid_missing) { | ||
567 | mid = extend_brk(PAGE_SIZE, PAGE_SIZE); | ||
554 | 568 | ||
555 | p2m_mid_init(mid); | 569 | p2m_mid_init(mid); |
556 | 570 | ||
557 | p2m_top[topidx] = mid; | 571 | p2m_top[topidx] = mid; |
572 | |||
573 | BUG_ON(mid_mfn_p != p2m_mid_missing_mfn); | ||
574 | } | ||
575 | /* And the save/restore P2M tables.. */ | ||
576 | if (mid_mfn_p == p2m_mid_missing_mfn) { | ||
577 | mid_mfn_p = extend_brk(PAGE_SIZE, PAGE_SIZE); | ||
578 | p2m_mid_mfn_init(mid_mfn_p); | ||
579 | |||
580 | p2m_top_mfn_p[topidx] = mid_mfn_p; | ||
581 | p2m_top_mfn[topidx] = virt_to_mfn(mid_mfn_p); | ||
582 | /* Note: we don't set mid_mfn_p[midix] here, | ||
583 | * look in __early_alloc_p2m */ | ||
558 | } | 584 | } |
559 | } | 585 | } |
560 | 586 | ||
@@ -650,7 +676,7 @@ static unsigned long mfn_hash(unsigned long mfn) | |||
650 | } | 676 | } |
651 | 677 | ||
652 | /* Add an MFN override for a particular page */ | 678 | /* Add an MFN override for a particular page */ |
653 | int m2p_add_override(unsigned long mfn, struct page *page) | 679 | int m2p_add_override(unsigned long mfn, struct page *page, bool clear_pte) |
654 | { | 680 | { |
655 | unsigned long flags; | 681 | unsigned long flags; |
656 | unsigned long pfn; | 682 | unsigned long pfn; |
@@ -662,7 +688,6 @@ int m2p_add_override(unsigned long mfn, struct page *page) | |||
662 | if (!PageHighMem(page)) { | 688 | if (!PageHighMem(page)) { |
663 | address = (unsigned long)__va(pfn << PAGE_SHIFT); | 689 | address = (unsigned long)__va(pfn << PAGE_SHIFT); |
664 | ptep = lookup_address(address, &level); | 690 | ptep = lookup_address(address, &level); |
665 | |||
666 | if (WARN(ptep == NULL || level != PG_LEVEL_4K, | 691 | if (WARN(ptep == NULL || level != PG_LEVEL_4K, |
667 | "m2p_add_override: pfn %lx not mapped", pfn)) | 692 | "m2p_add_override: pfn %lx not mapped", pfn)) |
668 | return -EINVAL; | 693 | return -EINVAL; |
@@ -674,18 +699,17 @@ int m2p_add_override(unsigned long mfn, struct page *page) | |||
674 | if (unlikely(!set_phys_to_machine(pfn, FOREIGN_FRAME(mfn)))) | 699 | if (unlikely(!set_phys_to_machine(pfn, FOREIGN_FRAME(mfn)))) |
675 | return -ENOMEM; | 700 | return -ENOMEM; |
676 | 701 | ||
677 | if (!PageHighMem(page)) | 702 | if (clear_pte && !PageHighMem(page)) |
678 | /* Just zap old mapping for now */ | 703 | /* Just zap old mapping for now */ |
679 | pte_clear(&init_mm, address, ptep); | 704 | pte_clear(&init_mm, address, ptep); |
680 | |||
681 | spin_lock_irqsave(&m2p_override_lock, flags); | 705 | spin_lock_irqsave(&m2p_override_lock, flags); |
682 | list_add(&page->lru, &m2p_overrides[mfn_hash(mfn)]); | 706 | list_add(&page->lru, &m2p_overrides[mfn_hash(mfn)]); |
683 | spin_unlock_irqrestore(&m2p_override_lock, flags); | 707 | spin_unlock_irqrestore(&m2p_override_lock, flags); |
684 | 708 | ||
685 | return 0; | 709 | return 0; |
686 | } | 710 | } |
687 | 711 | EXPORT_SYMBOL_GPL(m2p_add_override); | |
688 | int m2p_remove_override(struct page *page) | 712 | int m2p_remove_override(struct page *page, bool clear_pte) |
689 | { | 713 | { |
690 | unsigned long flags; | 714 | unsigned long flags; |
691 | unsigned long mfn; | 715 | unsigned long mfn; |
@@ -713,7 +737,7 @@ int m2p_remove_override(struct page *page) | |||
713 | spin_unlock_irqrestore(&m2p_override_lock, flags); | 737 | spin_unlock_irqrestore(&m2p_override_lock, flags); |
714 | set_phys_to_machine(pfn, page->index); | 738 | set_phys_to_machine(pfn, page->index); |
715 | 739 | ||
716 | if (!PageHighMem(page)) | 740 | if (clear_pte && !PageHighMem(page)) |
717 | set_pte_at(&init_mm, address, ptep, | 741 | set_pte_at(&init_mm, address, ptep, |
718 | pfn_pte(pfn, PAGE_KERNEL)); | 742 | pfn_pte(pfn, PAGE_KERNEL)); |
719 | /* No tlb flush necessary because the caller already | 743 | /* No tlb flush necessary because the caller already |
@@ -721,6 +745,7 @@ int m2p_remove_override(struct page *page) | |||
721 | 745 | ||
722 | return 0; | 746 | return 0; |
723 | } | 747 | } |
748 | EXPORT_SYMBOL_GPL(m2p_remove_override); | ||
724 | 749 | ||
725 | struct page *m2p_find_override(unsigned long mfn) | 750 | struct page *m2p_find_override(unsigned long mfn) |
726 | { | 751 | { |
diff --git a/arch/x86/xen/setup.c b/arch/x86/xen/setup.c index fa0269a99377..be1a464f6d66 100644 --- a/arch/x86/xen/setup.c +++ b/arch/x86/xen/setup.c | |||
@@ -50,7 +50,7 @@ phys_addr_t xen_extra_mem_start, xen_extra_mem_size; | |||
50 | */ | 50 | */ |
51 | #define EXTRA_MEM_RATIO (10) | 51 | #define EXTRA_MEM_RATIO (10) |
52 | 52 | ||
53 | static __init void xen_add_extra_mem(unsigned long pages) | 53 | static void __init xen_add_extra_mem(unsigned long pages) |
54 | { | 54 | { |
55 | unsigned long pfn; | 55 | unsigned long pfn; |
56 | 56 | ||
@@ -166,7 +166,7 @@ static unsigned long __init xen_set_identity(const struct e820entry *list, | |||
166 | if (last > end) | 166 | if (last > end) |
167 | continue; | 167 | continue; |
168 | 168 | ||
169 | if (entry->type == E820_RAM) { | 169 | if ((entry->type == E820_RAM) || (entry->type == E820_UNUSABLE)) { |
170 | if (start > start_pci) | 170 | if (start > start_pci) |
171 | identity += set_phys_range_identity( | 171 | identity += set_phys_range_identity( |
172 | PFN_UP(start_pci), PFN_DOWN(start)); | 172 | PFN_UP(start_pci), PFN_DOWN(start)); |
@@ -227,7 +227,11 @@ char * __init xen_memory_setup(void) | |||
227 | 227 | ||
228 | memcpy(map_raw, map, sizeof(map)); | 228 | memcpy(map_raw, map, sizeof(map)); |
229 | e820.nr_map = 0; | 229 | e820.nr_map = 0; |
230 | #ifdef CONFIG_X86_32 | ||
230 | xen_extra_mem_start = mem_end; | 231 | xen_extra_mem_start = mem_end; |
232 | #else | ||
233 | xen_extra_mem_start = max((1ULL << 32), mem_end); | ||
234 | #endif | ||
231 | for (i = 0; i < memmap.nr_entries; i++) { | 235 | for (i = 0; i < memmap.nr_entries; i++) { |
232 | unsigned long long end; | 236 | unsigned long long end; |
233 | 237 | ||
@@ -336,7 +340,7 @@ static void __init fiddle_vdso(void) | |||
336 | #endif | 340 | #endif |
337 | } | 341 | } |
338 | 342 | ||
339 | static __cpuinit int register_callback(unsigned type, const void *func) | 343 | static int __cpuinit register_callback(unsigned type, const void *func) |
340 | { | 344 | { |
341 | struct callback_register callback = { | 345 | struct callback_register callback = { |
342 | .type = type, | 346 | .type = type, |
diff --git a/arch/x86/xen/smp.c b/arch/x86/xen/smp.c index 30612441ed99..41038c01de40 100644 --- a/arch/x86/xen/smp.c +++ b/arch/x86/xen/smp.c | |||
@@ -46,18 +46,17 @@ static irqreturn_t xen_call_function_interrupt(int irq, void *dev_id); | |||
46 | static irqreturn_t xen_call_function_single_interrupt(int irq, void *dev_id); | 46 | static irqreturn_t xen_call_function_single_interrupt(int irq, void *dev_id); |
47 | 47 | ||
48 | /* | 48 | /* |
49 | * Reschedule call back. Nothing to do, | 49 | * Reschedule call back. |
50 | * all the work is done automatically when | ||
51 | * we return from the interrupt. | ||
52 | */ | 50 | */ |
53 | static irqreturn_t xen_reschedule_interrupt(int irq, void *dev_id) | 51 | static irqreturn_t xen_reschedule_interrupt(int irq, void *dev_id) |
54 | { | 52 | { |
55 | inc_irq_stat(irq_resched_count); | 53 | inc_irq_stat(irq_resched_count); |
54 | scheduler_ipi(); | ||
56 | 55 | ||
57 | return IRQ_HANDLED; | 56 | return IRQ_HANDLED; |
58 | } | 57 | } |
59 | 58 | ||
60 | static __cpuinit void cpu_bringup(void) | 59 | static void __cpuinit cpu_bringup(void) |
61 | { | 60 | { |
62 | int cpu = smp_processor_id(); | 61 | int cpu = smp_processor_id(); |
63 | 62 | ||
@@ -85,7 +84,7 @@ static __cpuinit void cpu_bringup(void) | |||
85 | wmb(); /* make sure everything is out */ | 84 | wmb(); /* make sure everything is out */ |
86 | } | 85 | } |
87 | 86 | ||
88 | static __cpuinit void cpu_bringup_and_idle(void) | 87 | static void __cpuinit cpu_bringup_and_idle(void) |
89 | { | 88 | { |
90 | cpu_bringup(); | 89 | cpu_bringup(); |
91 | cpu_idle(); | 90 | cpu_idle(); |
@@ -242,7 +241,7 @@ static void __init xen_smp_prepare_cpus(unsigned int max_cpus) | |||
242 | } | 241 | } |
243 | } | 242 | } |
244 | 243 | ||
245 | static __cpuinit int | 244 | static int __cpuinit |
246 | cpu_initialize_context(unsigned int cpu, struct task_struct *idle) | 245 | cpu_initialize_context(unsigned int cpu, struct task_struct *idle) |
247 | { | 246 | { |
248 | struct vcpu_guest_context *ctxt; | 247 | struct vcpu_guest_context *ctxt; |
@@ -486,7 +485,7 @@ static irqreturn_t xen_call_function_single_interrupt(int irq, void *dev_id) | |||
486 | return IRQ_HANDLED; | 485 | return IRQ_HANDLED; |
487 | } | 486 | } |
488 | 487 | ||
489 | static const struct smp_ops xen_smp_ops __initdata = { | 488 | static const struct smp_ops xen_smp_ops __initconst = { |
490 | .smp_prepare_boot_cpu = xen_smp_prepare_boot_cpu, | 489 | .smp_prepare_boot_cpu = xen_smp_prepare_boot_cpu, |
491 | .smp_prepare_cpus = xen_smp_prepare_cpus, | 490 | .smp_prepare_cpus = xen_smp_prepare_cpus, |
492 | .smp_cpus_done = xen_smp_cpus_done, | 491 | .smp_cpus_done = xen_smp_cpus_done, |
diff --git a/arch/x86/xen/time.c b/arch/x86/xen/time.c index 2e2d370a47b1..5158c505bef9 100644 --- a/arch/x86/xen/time.c +++ b/arch/x86/xen/time.c | |||
@@ -26,8 +26,6 @@ | |||
26 | 26 | ||
27 | #include "xen-ops.h" | 27 | #include "xen-ops.h" |
28 | 28 | ||
29 | #define XEN_SHIFT 22 | ||
30 | |||
31 | /* Xen may fire a timer up to this many ns early */ | 29 | /* Xen may fire a timer up to this many ns early */ |
32 | #define TIMER_SLOP 100000 | 30 | #define TIMER_SLOP 100000 |
33 | #define NS_PER_TICK (1000000000LL / HZ) | 31 | #define NS_PER_TICK (1000000000LL / HZ) |
@@ -211,8 +209,6 @@ static struct clocksource xen_clocksource __read_mostly = { | |||
211 | .rating = 400, | 209 | .rating = 400, |
212 | .read = xen_clocksource_get_cycles, | 210 | .read = xen_clocksource_get_cycles, |
213 | .mask = ~0, | 211 | .mask = ~0, |
214 | .mult = 1<<XEN_SHIFT, /* time directly in nanoseconds */ | ||
215 | .shift = XEN_SHIFT, | ||
216 | .flags = CLOCK_SOURCE_IS_CONTINUOUS, | 212 | .flags = CLOCK_SOURCE_IS_CONTINUOUS, |
217 | }; | 213 | }; |
218 | 214 | ||
@@ -439,16 +435,16 @@ void xen_timer_resume(void) | |||
439 | } | 435 | } |
440 | } | 436 | } |
441 | 437 | ||
442 | static const struct pv_time_ops xen_time_ops __initdata = { | 438 | static const struct pv_time_ops xen_time_ops __initconst = { |
443 | .sched_clock = xen_clocksource_read, | 439 | .sched_clock = xen_clocksource_read, |
444 | }; | 440 | }; |
445 | 441 | ||
446 | static __init void xen_time_init(void) | 442 | static void __init xen_time_init(void) |
447 | { | 443 | { |
448 | int cpu = smp_processor_id(); | 444 | int cpu = smp_processor_id(); |
449 | struct timespec tp; | 445 | struct timespec tp; |
450 | 446 | ||
451 | clocksource_register(&xen_clocksource); | 447 | clocksource_register_hz(&xen_clocksource, NSEC_PER_SEC); |
452 | 448 | ||
453 | if (HYPERVISOR_vcpu_op(VCPUOP_stop_periodic_timer, cpu, NULL) == 0) { | 449 | if (HYPERVISOR_vcpu_op(VCPUOP_stop_periodic_timer, cpu, NULL) == 0) { |
454 | /* Successfully turned off 100Hz tick, so we have the | 450 | /* Successfully turned off 100Hz tick, so we have the |
@@ -468,7 +464,7 @@ static __init void xen_time_init(void) | |||
468 | xen_setup_cpu_clockevents(); | 464 | xen_setup_cpu_clockevents(); |
469 | } | 465 | } |
470 | 466 | ||
471 | __init void xen_init_time_ops(void) | 467 | void __init xen_init_time_ops(void) |
472 | { | 468 | { |
473 | pv_time_ops = xen_time_ops; | 469 | pv_time_ops = xen_time_ops; |
474 | 470 | ||
@@ -490,7 +486,7 @@ static void xen_hvm_setup_cpu_clockevents(void) | |||
490 | xen_setup_cpu_clockevents(); | 486 | xen_setup_cpu_clockevents(); |
491 | } | 487 | } |
492 | 488 | ||
493 | __init void xen_hvm_init_time_ops(void) | 489 | void __init xen_hvm_init_time_ops(void) |
494 | { | 490 | { |
495 | /* vector callback is needed otherwise we cannot receive interrupts | 491 | /* vector callback is needed otherwise we cannot receive interrupts |
496 | * on cpu > 0 and at this point we don't know how many cpus are | 492 | * on cpu > 0 and at this point we don't know how many cpus are |
diff --git a/arch/x86/xen/xen-ops.h b/arch/x86/xen/xen-ops.h index 3112f55638c4..97dfdc8757b3 100644 --- a/arch/x86/xen/xen-ops.h +++ b/arch/x86/xen/xen-ops.h | |||
@@ -74,7 +74,7 @@ static inline void xen_hvm_smp_init(void) {} | |||
74 | 74 | ||
75 | #ifdef CONFIG_PARAVIRT_SPINLOCKS | 75 | #ifdef CONFIG_PARAVIRT_SPINLOCKS |
76 | void __init xen_init_spinlocks(void); | 76 | void __init xen_init_spinlocks(void); |
77 | __cpuinit void xen_init_lock_cpu(int cpu); | 77 | void __cpuinit xen_init_lock_cpu(int cpu); |
78 | void xen_uninit_lock_cpu(int cpu); | 78 | void xen_uninit_lock_cpu(int cpu); |
79 | #else | 79 | #else |
80 | static inline void xen_init_spinlocks(void) | 80 | static inline void xen_init_spinlocks(void) |