Пример #1
0
/*
 * devmem_is_allowed() checks to see if /dev/mem access to a certain address
 * is valid. The argument is a physical page number.
 *
 * On Tile, the only valid things for which we can just hand out unchecked
 * PTEs are the kernel code and data.  Anything else might change its
 * homing with time, and we wouldn't know to adjust the /dev/mem PTEs.
 * Note that init_thread_union is released to heap soon after boot,
 * so we include it in the init data.
 *
 * For TILE-Gx, we might want to consider allowing access to PA
 * regions corresponding to PCI space, etc.
 */
int devmem_is_allowed(unsigned long pagenr)
{
	return pagenr < kaddr_to_pfn(_end) &&
		!(pagenr >= kaddr_to_pfn(&init_thread_union) ||
		  pagenr < kaddr_to_pfn(_einitdata)) &&
		!(pagenr >= kaddr_to_pfn(_sinittext) ||
		  pagenr <= kaddr_to_pfn(_einittext-1));
}
Пример #2
0
/*
 * The __w1data area holds data that is only written during initialization,
 * and is read-only and thus freely cacheable thereafter.  Fix the page
 * table entries that cover that region accordingly.
 */
static void mark_w1data_ro(void)
{
	/* Loop over page table entries */
	unsigned long addr = (unsigned long)__w1data_begin;
	BUG_ON((addr & (PAGE_SIZE-1)) != 0);
	for (; addr <= (unsigned long)__w1data_end - 1; addr += PAGE_SIZE) {
		unsigned long pfn = kaddr_to_pfn((void *)addr);
		pte_t *ptep = virt_to_pte(NULL, addr);
		BUG_ON(pte_huge(*ptep));   /* not relevant for kdata_huge */
		set_pte_at(&init_mm, addr, ptep, pfn_pte(pfn, PAGE_KERNEL_RO));
	}
}
Пример #3
0
static void free_init_pages(char *what, unsigned long begin, unsigned long end)
{
#ifdef CONFIG_HOMECACHE
    int home = initial_heap_home();
#endif
    unsigned long addr = (unsigned long) begin;

    if (kdata_huge && !initfree) {
        pr_warning("Warning: ignoring initfree=0:"
                   " incompatible with kdata=huge\n");
        initfree = 1;
    }
    end = (end + PAGE_SIZE - 1) & PAGE_MASK;
    local_flush_tlb_pages(NULL, begin, PAGE_SIZE, end - begin);
    for (addr = begin; addr < end; addr += PAGE_SIZE) {
        /*
         * Note we just reset the home here directly in the
         * page table.  We know this is safe because our caller
         * just flushed the caches on all the other cpus,
         * and they won't be touching any of these pages.
         */
        int pfn = kaddr_to_pfn((void *)addr);
        struct page *page = pfn_to_page(pfn);
        pte_t *ptep = virt_to_pte(NULL, addr);
        if (!initfree) {
            /*
             * If debugging page accesses then do not free
             * this memory but mark them not present - any
             * buggy init-section access will create a
             * kernel page fault:
             */
            pte_clear(&init_mm, addr, ptep);
            continue;
        }
#ifdef CONFIG_HOMECACHE
        set_page_home(page, home);
        __clear_bit(PG_homecache_nomigrate, &page->flags);
#endif
        __ClearPageReserved(page);
        init_page_count(page);
        if (pte_huge(*ptep))
            BUG_ON(!kdata_huge);
        else
            set_pte_at(&init_mm, addr, ptep,
                       pfn_pte(pfn, PAGE_KERNEL));
        memset((void *)addr, POISON_FREE_INITMEM, PAGE_SIZE);
        free_page(addr);
        totalram_pages++;
    }
    pr_info("Freeing %s: %ldk freed\n", what, (end - begin) >> 10);
}