diff options
Diffstat (limited to 'arch/sparc/mm/init_64.c')
-rw-r--r-- | arch/sparc/mm/init_64.c | 47 |
1 files changed, 46 insertions, 1 deletions
diff --git a/arch/sparc/mm/init_64.c b/arch/sparc/mm/init_64.c index 8415f614ce0c..8584a25a9f0d 100644 --- a/arch/sparc/mm/init_64.c +++ b/arch/sparc/mm/init_64.c | |||
@@ -511,6 +511,11 @@ static void __init read_obp_translations(void) | |||
511 | for (i = 0; i < prom_trans_ents; i++) | 511 | for (i = 0; i < prom_trans_ents; i++) |
512 | prom_trans[i].data &= ~0x0003fe0000000000UL; | 512 | prom_trans[i].data &= ~0x0003fe0000000000UL; |
513 | } | 513 | } |
514 | |||
515 | /* Force execute bit on. */ | ||
516 | for (i = 0; i < prom_trans_ents; i++) | ||
517 | prom_trans[i].data |= (tlb_type == hypervisor ? | ||
518 | _PAGE_EXEC_4V : _PAGE_EXEC_4U); | ||
514 | } | 519 | } |
515 | 520 | ||
516 | static void __init hypervisor_tlb_lock(unsigned long vaddr, | 521 | static void __init hypervisor_tlb_lock(unsigned long vaddr, |
@@ -1597,6 +1602,44 @@ static void __init tsb_phys_patch(void) | |||
1597 | static struct hv_tsb_descr ktsb_descr[NUM_KTSB_DESCR]; | 1602 | static struct hv_tsb_descr ktsb_descr[NUM_KTSB_DESCR]; |
1598 | extern struct tsb swapper_tsb[KERNEL_TSB_NENTRIES]; | 1603 | extern struct tsb swapper_tsb[KERNEL_TSB_NENTRIES]; |
1599 | 1604 | ||
1605 | static void patch_one_ktsb_phys(unsigned int *start, unsigned int *end, unsigned long pa) | ||
1606 | { | ||
1607 | pa >>= KTSB_PHYS_SHIFT; | ||
1608 | |||
1609 | while (start < end) { | ||
1610 | unsigned int *ia = (unsigned int *)(unsigned long)*start; | ||
1611 | |||
1612 | ia[0] = (ia[0] & ~0x3fffff) | (pa >> 10); | ||
1613 | __asm__ __volatile__("flush %0" : : "r" (ia)); | ||
1614 | |||
1615 | ia[1] = (ia[1] & ~0x3ff) | (pa & 0x3ff); | ||
1616 | __asm__ __volatile__("flush %0" : : "r" (ia + 1)); | ||
1617 | |||
1618 | start++; | ||
1619 | } | ||
1620 | } | ||
1621 | |||
1622 | static void ktsb_phys_patch(void) | ||
1623 | { | ||
1624 | extern unsigned int __swapper_tsb_phys_patch; | ||
1625 | extern unsigned int __swapper_tsb_phys_patch_end; | ||
1626 | unsigned long ktsb_pa; | ||
1627 | |||
1628 | ktsb_pa = kern_base + ((unsigned long)&swapper_tsb[0] - KERNBASE); | ||
1629 | patch_one_ktsb_phys(&__swapper_tsb_phys_patch, | ||
1630 | &__swapper_tsb_phys_patch_end, ktsb_pa); | ||
1631 | #ifndef CONFIG_DEBUG_PAGEALLOC | ||
1632 | { | ||
1633 | extern unsigned int __swapper_4m_tsb_phys_patch; | ||
1634 | extern unsigned int __swapper_4m_tsb_phys_patch_end; | ||
1635 | ktsb_pa = (kern_base + | ||
1636 | ((unsigned long)&swapper_4m_tsb[0] - KERNBASE)); | ||
1637 | patch_one_ktsb_phys(&__swapper_4m_tsb_phys_patch, | ||
1638 | &__swapper_4m_tsb_phys_patch_end, ktsb_pa); | ||
1639 | } | ||
1640 | #endif | ||
1641 | } | ||
1642 | |||
1600 | static void __init sun4v_ktsb_init(void) | 1643 | static void __init sun4v_ktsb_init(void) |
1601 | { | 1644 | { |
1602 | unsigned long ktsb_pa; | 1645 | unsigned long ktsb_pa; |
@@ -1716,8 +1759,10 @@ void __init paging_init(void) | |||
1716 | sun4u_pgprot_init(); | 1759 | sun4u_pgprot_init(); |
1717 | 1760 | ||
1718 | if (tlb_type == cheetah_plus || | 1761 | if (tlb_type == cheetah_plus || |
1719 | tlb_type == hypervisor) | 1762 | tlb_type == hypervisor) { |
1720 | tsb_phys_patch(); | 1763 | tsb_phys_patch(); |
1764 | ktsb_phys_patch(); | ||
1765 | } | ||
1721 | 1766 | ||
1722 | if (tlb_type == hypervisor) { | 1767 | if (tlb_type == hypervisor) { |
1723 | sun4v_patch_tlb_handlers(); | 1768 | sun4v_patch_tlb_handlers(); |