aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sparc/mm
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2012-09-06 23:35:36 -0400
committerDavid S. Miller <davem@davemloft.net>2012-09-06 23:35:36 -0400
commitc69ad0a3f7d871aa61fb669fb41c951df6660a61 (patch)
tree4dee9eab4894c9103f617be916359724172c240c /arch/sparc/mm
parentce33fdc52ad50043eef07d11473bc51e225565bd (diff)
sparc64: Use cpu_pgsz_mask for linear kernel mapping config.
This required a little bit of reordering of how we set up the memory management early on. We now only know the final values of kern_linear_pte_xor[] after we take over the trap table and start processing TLB misses ourselves. So once we fill those values in we re-clear the kernel's 4M TSB and flush the TLBs. That way if we find we support larger than 4M pages we won't have any stale smaller page size entries in the TSB. SUN4U Panther support for larger page sizes should now be extremely trivial but I have no hardware on which to test it and I believe that some of the sun4u TLB miss assembler needs to be audited first to make sure it really can handle larger than 4M PTEs properly. Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'arch/sparc/mm')
-rw-r--r--arch/sparc/mm/init_64.c104
1 files changed, 65 insertions, 39 deletions
diff --git a/arch/sparc/mm/init_64.c b/arch/sparc/mm/init_64.c
index 445369132e03..696bb095e0fc 100644
--- a/arch/sparc/mm/init_64.c
+++ b/arch/sparc/mm/init_64.c
@@ -1660,10 +1660,11 @@ static void __init sun4v_ktsb_init(void)
1660 ((unsigned long)&swapper_4m_tsb[0] - KERNBASE)); 1660 ((unsigned long)&swapper_4m_tsb[0] - KERNBASE));
1661 1661
1662 ktsb_descr[1].pgsz_idx = HV_PGSZ_IDX_4MB; 1662 ktsb_descr[1].pgsz_idx = HV_PGSZ_IDX_4MB;
1663 ktsb_descr[1].pgsz_mask = (HV_PGSZ_MASK_4MB | 1663 ktsb_descr[1].pgsz_mask = ((HV_PGSZ_MASK_4MB |
1664 HV_PGSZ_MASK_256MB); 1664 HV_PGSZ_MASK_256MB |
1665 if (sun4v_chip_type == SUN4V_CHIP_NIAGARA4) 1665 HV_PGSZ_MASK_2GB |
1666 ktsb_descr[1].pgsz_mask |= HV_PGSZ_MASK_2GB; 1666 HV_PGSZ_MASK_16GB) &
1667 cpu_pgsz_mask);
1667 ktsb_descr[1].assoc = 1; 1668 ktsb_descr[1].assoc = 1;
1668 ktsb_descr[1].num_ttes = KERNEL_TSB4M_NENTRIES; 1669 ktsb_descr[1].num_ttes = KERNEL_TSB4M_NENTRIES;
1669 ktsb_descr[1].ctx_idx = 0; 1670 ktsb_descr[1].ctx_idx = 0;
@@ -1686,6 +1687,47 @@ void __cpuinit sun4v_ktsb_register(void)
1686 } 1687 }
1687} 1688}
1688 1689
1690static void __init sun4u_linear_pte_xor_finalize(void)
1691{
1692#ifndef CONFIG_DEBUG_PAGEALLOC
1693 /* This is where we would add Panther support for
1694 * 32MB and 256MB pages.
1695 */
1696#endif
1697}
1698
1699static void __init sun4v_linear_pte_xor_finalize(void)
1700{
1701#ifndef CONFIG_DEBUG_PAGEALLOC
1702 if (cpu_pgsz_mask & HV_PGSZ_MASK_256MB) {
1703 kern_linear_pte_xor[1] = (_PAGE_VALID | _PAGE_SZ256MB_4V) ^
1704 0xfffff80000000000UL;
1705 kern_linear_pte_xor[1] |= (_PAGE_CP_4V | _PAGE_CV_4V |
1706 _PAGE_P_4V | _PAGE_W_4V);
1707 } else {
1708 kern_linear_pte_xor[1] = kern_linear_pte_xor[0];
1709 }
1710
1711 if (cpu_pgsz_mask & HV_PGSZ_MASK_2GB) {
1712 kern_linear_pte_xor[2] = (_PAGE_VALID | _PAGE_SZ2GB_4V) ^
1713 0xfffff80000000000UL;
1714 kern_linear_pte_xor[2] |= (_PAGE_CP_4V | _PAGE_CV_4V |
1715 _PAGE_P_4V | _PAGE_W_4V);
1716 } else {
1717 kern_linear_pte_xor[2] = kern_linear_pte_xor[1];
1718 }
1719
1720 if (cpu_pgsz_mask & HV_PGSZ_MASK_16GB) {
1721 kern_linear_pte_xor[3] = (_PAGE_VALID | _PAGE_SZ16GB_4V) ^
1722 0xfffff80000000000UL;
1723 kern_linear_pte_xor[3] |= (_PAGE_CP_4V | _PAGE_CV_4V |
1724 _PAGE_P_4V | _PAGE_W_4V);
1725 } else {
1726 kern_linear_pte_xor[3] = kern_linear_pte_xor[2];
1727 }
1728#endif
1729}
1730
1689/* paging_init() sets up the page tables */ 1731/* paging_init() sets up the page tables */
1690 1732
1691static unsigned long last_valid_pfn; 1733static unsigned long last_valid_pfn;
@@ -1745,10 +1787,8 @@ void __init paging_init(void)
1745 ktsb_phys_patch(); 1787 ktsb_phys_patch();
1746 } 1788 }
1747 1789
1748 if (tlb_type == hypervisor) { 1790 if (tlb_type == hypervisor)
1749 sun4v_patch_tlb_handlers(); 1791 sun4v_patch_tlb_handlers();
1750 sun4v_ktsb_init();
1751 }
1752 1792
1753 /* Find available physical memory... 1793 /* Find available physical memory...
1754 * 1794 *
@@ -1807,9 +1847,6 @@ void __init paging_init(void)
1807 1847
1808 __flush_tlb_all(); 1848 __flush_tlb_all();
1809 1849
1810 if (tlb_type == hypervisor)
1811 sun4v_ktsb_register();
1812
1813 prom_build_devicetree(); 1850 prom_build_devicetree();
1814 of_populate_present_mask(); 1851 of_populate_present_mask();
1815#ifndef CONFIG_SMP 1852#ifndef CONFIG_SMP
@@ -1823,6 +1860,11 @@ void __init paging_init(void)
1823 mdesc_fill_in_cpu_data(cpu_all_mask); 1860 mdesc_fill_in_cpu_data(cpu_all_mask);
1824#endif 1861#endif
1825 mdesc_get_page_sizes(cpu_all_mask, &cpu_pgsz_mask); 1862 mdesc_get_page_sizes(cpu_all_mask, &cpu_pgsz_mask);
1863
1864 sun4v_linear_pte_xor_finalize();
1865
1866 sun4v_ktsb_init();
1867 sun4v_ktsb_register();
1826 } else { 1868 } else {
1827 unsigned long impl, ver; 1869 unsigned long impl, ver;
1828 1870
@@ -1834,8 +1876,19 @@ void __init paging_init(void)
1834 if (impl == PANTHER_IMPL) 1876 if (impl == PANTHER_IMPL)
1835 cpu_pgsz_mask |= (HV_PGSZ_MASK_32MB | 1877 cpu_pgsz_mask |= (HV_PGSZ_MASK_32MB |
1836 HV_PGSZ_MASK_256MB); 1878 HV_PGSZ_MASK_256MB);
1879
1880 sun4u_linear_pte_xor_finalize();
1837 } 1881 }
1838 1882
1883 /* Flush the TLBs and the 4M TSB so that the updated linear
1884 * pte XOR settings are realized for all mappings.
1885 */
1886 __flush_tlb_all();
1887#ifndef CONFIG_DEBUG_PAGEALLOC
1888 memset(swapper_4m_tsb, 0x40, sizeof(swapper_4m_tsb));
1889#endif
1890 __flush_tlb_all();
1891
1839 /* Setup bootmem... */ 1892 /* Setup bootmem... */
1840 last_valid_pfn = end_pfn = bootmem_init(phys_base); 1893 last_valid_pfn = end_pfn = bootmem_init(phys_base);
1841 1894
@@ -2230,7 +2283,6 @@ static void __init sun4u_pgprot_init(void)
2230 kern_linear_pte_xor[0] |= (_PAGE_CP_4U | _PAGE_CV_4U | 2283 kern_linear_pte_xor[0] |= (_PAGE_CP_4U | _PAGE_CV_4U |
2231 _PAGE_P_4U | _PAGE_W_4U); 2284 _PAGE_P_4U | _PAGE_W_4U);
2232 2285
2233 /* XXX Should use 256MB on Panther. XXX */
2234 for (i = 1; i < 4; i++) 2286 for (i = 1; i < 4; i++)
2235 kern_linear_pte_xor[i] = kern_linear_pte_xor[0]; 2287 kern_linear_pte_xor[i] = kern_linear_pte_xor[0];
2236 2288
@@ -2280,34 +2332,8 @@ static void __init sun4v_pgprot_init(void)
2280 kern_linear_pte_xor[0] |= (_PAGE_CP_4V | _PAGE_CV_4V | 2332 kern_linear_pte_xor[0] |= (_PAGE_CP_4V | _PAGE_CV_4V |
2281 _PAGE_P_4V | _PAGE_W_4V); 2333 _PAGE_P_4V | _PAGE_W_4V);
2282 2334
2283#ifdef CONFIG_DEBUG_PAGEALLOC 2335 for (i = 1; i < 4; i++)
2284 kern_linear_pte_xor[1] = (_PAGE_VALID | _PAGE_SZBITS_4V) ^ 2336 kern_linear_pte_xor[i] = kern_linear_pte_xor[0];
2285 0xfffff80000000000UL;
2286#else
2287 kern_linear_pte_xor[1] = (_PAGE_VALID | _PAGE_SZ256MB_4V) ^
2288 0xfffff80000000000UL;
2289#endif
2290 kern_linear_pte_xor[1] |= (_PAGE_CP_4V | _PAGE_CV_4V |
2291 _PAGE_P_4V | _PAGE_W_4V);
2292
2293 i = 2;
2294
2295 if (sun4v_chip_type == SUN4V_CHIP_NIAGARA4) {
2296#ifdef CONFIG_DEBUG_PAGEALLOC
2297 kern_linear_pte_xor[2] = (_PAGE_VALID | _PAGE_SZBITS_4V) ^
2298 0xfffff80000000000UL;
2299#else
2300 kern_linear_pte_xor[2] = (_PAGE_VALID | _PAGE_SZ2GB_4V) ^
2301 0xfffff80000000000UL;
2302#endif
2303 kern_linear_pte_xor[2] |= (_PAGE_CP_4V | _PAGE_CV_4V |
2304 _PAGE_P_4V | _PAGE_W_4V);
2305
2306 i = 3;
2307 }
2308
2309 for (; i < 4; i++)
2310 kern_linear_pte_xor[i] = kern_linear_pte_xor[i - 1];
2311 2337
2312 pg_iobits = (_PAGE_VALID | _PAGE_PRESENT_4V | __DIRTY_BITS_4V | 2338 pg_iobits = (_PAGE_VALID | _PAGE_PRESENT_4V | __DIRTY_BITS_4V |
2313 __ACCESS_BITS_4V | _PAGE_E_4V); 2339 __ACCESS_BITS_4V | _PAGE_E_4V);