arch/tile: Allow tilegx to build with either 16K or 64K page size
This change introduces new flags for the hv_install_context() API that passes a page table pointer to the hypervisor. Clients can explicitly request 4K, 16K, or 64K small pages when they install a new context. In practice, the page size is fixed at kernel compile time and the same size is always requested every time a new page table is installed. The <hv/hypervisor.h> header changes so that it provides more abstract macros for managing "page" things like PFNs and page tables. For example there is now a HV_DEFAULT_PAGE_SIZE_SMALL instead of the old HV_PAGE_SIZE_SMALL. The various PFN routines have been eliminated and only PA- or PTFN-based ones remain (since PTFNs are always expressed in fixed 2KB "page" size). The page-table management macros are renamed with a leading underscore and take page-size arguments with the presumption that clients will use those macros in some single place to provide the "real" macros they will use themselves. I happened to notice the old hv_set_caching() API was totally broken (it assumed 4KB pages) so I changed it so it would nominally work correctly with other page sizes. Tag modules with the page size so you can't load a module built with a conflicting page size. (And add a test for SMP while we're at it.) Signed-off-by: Chris Metcalf <cmetcalf@tilera.com>
This commit is contained in:
@@ -69,7 +69,7 @@ ENTRY(_start)
|
||||
}
|
||||
{
|
||||
moveli lr, lo16(1f)
|
||||
move r5, zero
|
||||
moveli r5, CTX_PAGE_FLAG
|
||||
}
|
||||
{
|
||||
auli lr, lr, ha16(1f)
|
||||
@@ -141,11 +141,11 @@ ENTRY(empty_zero_page)
|
||||
|
||||
.macro PTE va, cpa, bits1, no_org=0
|
||||
.ifeq \no_org
|
||||
.org swapper_pg_dir + HV_L1_INDEX(\va) * HV_PTE_SIZE
|
||||
.org swapper_pg_dir + PGD_INDEX(\va) * HV_PTE_SIZE
|
||||
.endif
|
||||
.word HV_PTE_PAGE | HV_PTE_DIRTY | HV_PTE_PRESENT | HV_PTE_ACCESSED | \
|
||||
(HV_PTE_MODE_CACHE_NO_L3 << HV_PTE_INDEX_MODE)
|
||||
.word (\bits1) | (HV_CPA_TO_PFN(\cpa) << (HV_PTE_INDEX_PFN - 32))
|
||||
.word (\bits1) | (HV_CPA_TO_PTFN(\cpa) << (HV_PTE_INDEX_PTFN - 32))
|
||||
.endm
|
||||
|
||||
__PAGE_ALIGNED_DATA
|
||||
@@ -166,7 +166,7 @@ ENTRY(swapper_pg_dir)
|
||||
/* The true text VAs are mapped as VA = PA + MEM_SV_INTRPT */
|
||||
PTE MEM_SV_INTRPT, 0, (1 << (HV_PTE_INDEX_READABLE - 32)) | \
|
||||
(1 << (HV_PTE_INDEX_EXECUTABLE - 32))
|
||||
.org swapper_pg_dir + HV_L1_SIZE
|
||||
.org swapper_pg_dir + PGDIR_SIZE
|
||||
END(swapper_pg_dir)
|
||||
|
||||
/*
|
||||
|
@@ -114,7 +114,7 @@ ENTRY(_start)
|
||||
shl16insli r0, r0, hw0(swapper_pg_dir - PAGE_OFFSET)
|
||||
}
|
||||
{
|
||||
move r3, zero
|
||||
moveli r3, CTX_PAGE_FLAG
|
||||
j hv_install_context
|
||||
}
|
||||
1:
|
||||
@@ -210,19 +210,19 @@ ENTRY(empty_zero_page)
|
||||
.macro PTE cpa, bits1
|
||||
.quad HV_PTE_PAGE | HV_PTE_DIRTY | HV_PTE_PRESENT | HV_PTE_ACCESSED |\
|
||||
HV_PTE_GLOBAL | (HV_PTE_MODE_CACHE_NO_L3 << HV_PTE_INDEX_MODE) |\
|
||||
(\bits1) | (HV_CPA_TO_PFN(\cpa) << HV_PTE_INDEX_PFN)
|
||||
(\bits1) | (HV_CPA_TO_PTFN(\cpa) << HV_PTE_INDEX_PTFN)
|
||||
.endm
|
||||
|
||||
__PAGE_ALIGNED_DATA
|
||||
.align PAGE_SIZE
|
||||
ENTRY(swapper_pg_dir)
|
||||
.org swapper_pg_dir + HV_L0_INDEX(PAGE_OFFSET) * HV_PTE_SIZE
|
||||
.org swapper_pg_dir + PGD_INDEX(PAGE_OFFSET) * HV_PTE_SIZE
|
||||
.Lsv_data_pmd:
|
||||
.quad 0 /* PTE temp_data_pmd - PAGE_OFFSET, 0 */
|
||||
.org swapper_pg_dir + HV_L0_INDEX(MEM_SV_START) * HV_PTE_SIZE
|
||||
.org swapper_pg_dir + PGD_INDEX(MEM_SV_START) * HV_PTE_SIZE
|
||||
.Lsv_code_pmd:
|
||||
.quad 0 /* PTE temp_code_pmd - PAGE_OFFSET, 0 */
|
||||
.org swapper_pg_dir + HV_L0_SIZE
|
||||
.org swapper_pg_dir + SIZEOF_PGD
|
||||
END(swapper_pg_dir)
|
||||
|
||||
.align HV_PAGE_TABLE_ALIGN
|
||||
@@ -233,11 +233,11 @@ ENTRY(temp_data_pmd)
|
||||
* permissions later.
|
||||
*/
|
||||
.set addr, 0
|
||||
.rept HV_L1_ENTRIES
|
||||
.rept PTRS_PER_PMD
|
||||
PTE addr, HV_PTE_READABLE | HV_PTE_WRITABLE
|
||||
.set addr, addr + HV_PAGE_SIZE_LARGE
|
||||
.set addr, addr + HPAGE_SIZE
|
||||
.endr
|
||||
.org temp_data_pmd + HV_L1_SIZE
|
||||
.org temp_data_pmd + SIZEOF_PMD
|
||||
END(temp_data_pmd)
|
||||
|
||||
.align HV_PAGE_TABLE_ALIGN
|
||||
@@ -248,11 +248,11 @@ ENTRY(temp_code_pmd)
|
||||
* permissions later.
|
||||
*/
|
||||
.set addr, 0
|
||||
.rept HV_L1_ENTRIES
|
||||
.rept PTRS_PER_PMD
|
||||
PTE addr, HV_PTE_READABLE | HV_PTE_EXECUTABLE
|
||||
.set addr, addr + HV_PAGE_SIZE_LARGE
|
||||
.set addr, addr + HPAGE_SIZE
|
||||
.endr
|
||||
.org temp_code_pmd + HV_L1_SIZE
|
||||
.org temp_code_pmd + SIZEOF_PMD
|
||||
END(temp_code_pmd)
|
||||
|
||||
/*
|
||||
|
@@ -251,6 +251,7 @@ static void setup_quasi_va_is_pa(void)
|
||||
void machine_kexec(struct kimage *image)
|
||||
{
|
||||
void *reboot_code_buffer;
|
||||
pte_t *ptep;
|
||||
void (*rnk)(unsigned long, void *, unsigned long)
|
||||
__noreturn;
|
||||
|
||||
@@ -266,8 +267,10 @@ void machine_kexec(struct kimage *image)
|
||||
*/
|
||||
homecache_change_page_home(image->control_code_page, 0,
|
||||
smp_processor_id());
|
||||
reboot_code_buffer = vmap(&image->control_code_page, 1, 0,
|
||||
__pgprot(_PAGE_KERNEL | _PAGE_EXECUTABLE));
|
||||
reboot_code_buffer = page_address(image->control_code_page);
|
||||
BUG_ON(reboot_code_buffer == NULL);
|
||||
ptep = virt_to_pte(NULL, (unsigned long)reboot_code_buffer);
|
||||
__set_pte(ptep, pte_mkexec(*ptep));
|
||||
memcpy(reboot_code_buffer, relocate_new_kernel,
|
||||
relocate_new_kernel_size);
|
||||
__flush_icache_range(
|
||||
|
@@ -1396,13 +1396,13 @@ void __init setup_per_cpu_areas(void)
|
||||
for (i = 0; i < size; i += PAGE_SIZE, ++pfn, ++pg) {
|
||||
|
||||
/* Update the vmalloc mapping and page home. */
|
||||
pte_t *ptep =
|
||||
virt_to_pte(NULL, (unsigned long)ptr + i);
|
||||
unsigned long addr = (unsigned long)ptr + i;
|
||||
pte_t *ptep = virt_to_pte(NULL, addr);
|
||||
pte_t pte = *ptep;
|
||||
BUG_ON(pfn != pte_pfn(pte));
|
||||
pte = hv_pte_set_mode(pte, HV_PTE_MODE_CACHE_TILE_L3);
|
||||
pte = set_remote_cache_cpu(pte, cpu);
|
||||
set_pte(ptep, pte);
|
||||
set_pte_at(&init_mm, addr, ptep, pte);
|
||||
|
||||
/* Update the lowmem mapping for consistency. */
|
||||
lowmem_va = (unsigned long)pfn_to_kaddr(pfn);
|
||||
@@ -1415,7 +1415,7 @@ void __init setup_per_cpu_areas(void)
|
||||
BUG_ON(pte_huge(*ptep));
|
||||
}
|
||||
BUG_ON(pfn != pte_pfn(*ptep));
|
||||
set_pte(ptep, pte);
|
||||
set_pte_at(&init_mm, lowmem_va, ptep, pte);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -203,7 +203,7 @@ void __init ipi_init(void)
|
||||
if (hv_get_ipi_pte(tile, KERNEL_PL, &pte) != 0)
|
||||
panic("Failed to initialize IPI for cpu %d\n", cpu);
|
||||
|
||||
offset = hv_pte_get_pfn(pte) << PAGE_SHIFT;
|
||||
offset = PFN_PHYS(pte_pfn(pte));
|
||||
ipi_mappings[cpu] = ioremap_prot(offset, PAGE_SIZE, pte);
|
||||
}
|
||||
#endif
|
||||
|
Fai riferimento in un nuovo problema
Block a user