/*
 * Copyright 2002 Andi Kleen, SuSE Labs.
 * Thanks to Ben LaHaise for precious feedback.
 */

#include <linux/highmem.h>
#include <linux/module.h>
#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/mm.h>

void clflush_cache_range(void *addr, int size)
{
	int i;

	for (i = 0; i < size; i += boot_cpu_data.x86_clflush_size)
		clflush(addr+i);
}

#include <asm/processor.h>
#include <asm/tlbflush.h>
#include <asm/sections.h>
#include <asm/uaccess.h>
#include <asm/pgalloc.h>

pte_t *lookup_address(unsigned long address, int *level)
{
	pgd_t *pgd = pgd_offset_k(address);
	pud_t *pud;
	pmd_t *pmd;

	if (pgd_none(*pgd))
		return NULL;
	pud = pud_offset(pgd, address);
	if (pud_none(*pud))
		return NULL;
	pmd = pmd_offset(pud, address);
	if (pmd_none(*pmd))
		return NULL;
	*level = 3;
	if (pmd_large(*pmd))
		return (pte_t *)pmd;
	*level = 4;

	return pte_offset_kernel(pmd, address);
}

static struct page *
split_large_page(unsigned long address, pgprot_t ref_prot)
{
	unsigned long addr;
	struct page *base;
	pte_t *pbase;
	int i;

	base = alloc_pages(GFP_KERNEL, 0);
	if (!base)
		return NULL;

	address = __pa(address);
	addr = address & LARGE_PAGE_MASK;
	pbase = (pte_t *)page_address(base);
	for (i = 0; i < PTRS_PER_PTE; i++, addr += PAGE_SIZE)
		pbase[i] = pfn_pte(addr >> PAGE_SHIFT, ref_prot);

	return base;
}

static int
__change_page_attr(unsigned long address, unsigned long pfn, pgprot_t prot,
		   pgprot_t ref_prot)
{
	struct page *kpte_page;
	pte_t *kpte;
	pgprot_t ref_prot2, oldprot;
	int level;

repeat:
	kpte = lookup_address(address, &level);
	if (!kpte)
		return 0;

	kpte_page = virt_to_page(kpte);
	oldprot = pte_pgprot(*kpte);
	BUG_ON(PageLRU(kpte_page));
	BUG_ON(PageCompound(kpte_page));
	ref_prot = canon_pgprot(ref_prot);
	prot = canon_pgprot(prot);

	if (pgprot_val(prot) != pgprot_val(ref_prot)) {
		if (level == 4) {
			set_pte(kpte, pfn_pte(pfn, prot));
		} else {
			/*
			 * split_large_page will take the reference for this
			 * change_page_attr on the split page.
			 */
			struct page *split;

			ref_prot2 = pte_pgprot(pte_clrhuge(*kpte));
			split = split_large_page(address, ref_prot2);
			if (!split)
				return -ENOMEM;
			pgprot_val(ref_prot2) &= ~_PAGE_NX;
			set_pte(kpte, mk_pte(split, ref_prot2));
			goto repeat;
		}
	} else {
		if (level == 4) {
			set_pte(kpte, pfn_pte(pfn, ref_prot));
		} else
			BUG();
	}

	return 0;
}

/**
 * change_page_attr_addr - Change page table attributes in linear mapping
 * @address: Virtual address in linear mapping.
 * @numpages: Number of pages to change
 * @prot:    New page table attribute (PAGE_*)
 *
 * Change page attributes of a page in the direct mapping. This is a variant
 * of change_page_attr() that also works on memory holes that do not have
 * mem_map entry (pfn_valid() is false).
 *
 * See change_page_attr() documentation for more details.
 */

int change_page_attr_addr(unsigned long address, int numpages, pgprot_t prot)
{
	int err = 0, kernel_map = 0, i;

	if (address >= __START_KERNEL_map &&
			address < __START_KERNEL_map + KERNEL_TEXT_SIZE) {

		address = (unsigned long)__va(__pa(address));
		kernel_map = 1;
	}

	down_write(&init_mm.mmap_sem);
	for (i = 0; i < numpages; i++, address += PAGE_SIZE) {
		unsigned long pfn = __pa(address) >> PAGE_SHIFT;

		if (!kernel_map || pte_present(pfn_pte(0, prot))) {
			err = __change_page_attr(address, pfn, prot,
						PAGE_KERNEL);
			if (err)
				break;
		}
		/* Handle kernel mapping too which aliases part of the
		 * lowmem */
		if (__pa(address) < KERNEL_TEXT_SIZE) {
			unsigned long addr2;
			pgprot_t prot2;

			addr2 = __START_KERNEL_map + __pa(address);
			/* Make sure the kernel mappings stay executable */
			prot2 = pte_pgprot(pte_mkexec(pfn_pte(0, prot)));
			err = __change_page_attr(addr2, pfn, prot2,
						 PAGE_KERNEL_EXEC);
		}
	}
	up_write(&init_mm.mmap_sem);

	return err;
}

/**
 * change_page_attr - Change page table attributes in the linear mapping.
 * @page: First page to change
 * @numpages: Number of pages to change
 * @prot: New protection/caching type (PAGE_*)
 *
 * Returns 0 on success, otherwise a negated errno.
 *
 * This should be used when a page is mapped with a different caching policy
 * than write-back somewhere - some CPUs do not like it when mappings with
 * different caching policies exist. This changes the page attributes of the
 * in kernel linear mapping too.
 *
 * Caller must call global_flush_tlb() later to make the changes active.
 *
 * The caller needs to ensure that there are no conflicting mappings elsewhere
 * (e.g. in user space) * This function only deals with the kernel linear map.
 *
 * For MMIO areas without mem_map use change_page_attr_addr() instead.
 */
int change_page_attr(struct page *page, int numpages, pgprot_t prot)
{
	unsigned long addr = (unsigned long)page_address(page);

	return change_page_attr_addr(addr, numpages, prot);
}
EXPORT_SYMBOL(change_page_attr);

static void flush_kernel_map(void *arg)
{
	/*
	 * Flush all to work around Errata in early athlons regarding
	 * large page flushing.
	 */
	__flush_tlb_all();

	if (boot_cpu_data.x86_model >= 4)
		wbinvd();
}

void global_flush_tlb(void)
{
	BUG_ON(irqs_disabled());

	on_each_cpu(flush_kernel_map, NULL, 1, 1);
}
EXPORT_SYMBOL(global_flush_tlb);
