/*
 * Handle caching attributes in page tables (PAT)
 *
 * Authors: Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>
 *          Suresh B Siddha <suresh.b.siddha@intel.com>
 *
 * Loosely based on earlier PAT patchset from Eric Biederman and Andi Kleen.
 */

#include <linux/mm.h>
#include <linux/kernel.h>
#include <linux/gfp.h>
#include <linux/fs.h>
#include <linux/bootmem.h>

#include <asm/msr.h>
#include <asm/tlbflush.h>
#include <asm/processor.h>
#include <asm/page.h>
#include <asm/pgtable.h>
#include <asm/pat.h>
#include <asm/e820.h>
#include <asm/cacheflush.h>
#include <asm/fcntl.h>
#include <asm/mtrr.h>
#include <asm/io.h>

#ifdef CONFIG_X86_PAT
int __read_mostly pat_wc_enabled = 1;

void __cpuinit pat_disable(char *reason)
{
	pat_wc_enabled = 0;
	printk(KERN_INFO "%s\n", reason);
}

static int nopat(char *str)
{
	pat_disable("PAT support disabled.");
	return 0;
}
early_param("nopat", nopat);
#endif

static u64 __read_mostly boot_pat_state;

enum {
	PAT_UC = 0,		/* uncached */
	PAT_WC = 1,		/* Write combining */
	PAT_WT = 4,		/* Write Through */
	PAT_WP = 5,		/* Write Protected */
	PAT_WB = 6,		/* Write Back (default) */
	PAT_UC_MINUS = 7,	/* UC, but can be overriden by MTRR */
};

#define PAT(x,y)	((u64)PAT_ ## y << ((x)*8))

void pat_init(void)
{
	u64 pat;

	if (!pat_wc_enabled)
		return;

	/* Paranoia check. */
	if (!cpu_has_pat) {
		printk(KERN_ERR "PAT enabled, but CPU feature cleared\n");
		/*
		 * Panic if this happens on the secondary CPU, and we
		 * switched to PAT on the boot CPU. We have no way to
		 * undo PAT.
		*/
		BUG_ON(boot_pat_state);
	}

	/* Set PWT to Write-Combining. All other bits stay the same */
	/*
	 * PTE encoding used in Linux:
	 *      PAT
	 *      |PCD
	 *      ||PWT
	 *      |||
	 *      000 WB		_PAGE_CACHE_WB
	 *      001 WC		_PAGE_CACHE_WC
	 *      010 UC-		_PAGE_CACHE_UC_MINUS
	 *      011 UC		_PAGE_CACHE_UC
	 * PAT bit unused
	 */
	pat = PAT(0,WB) | PAT(1,WC) | PAT(2,UC_MINUS) | PAT(3,UC) |
	      PAT(4,WB) | PAT(5,WC) | PAT(6,UC_MINUS) | PAT(7,UC);

	/* Boot CPU check */
	if (!boot_pat_state)
		rdmsrl(MSR_IA32_CR_PAT, boot_pat_state);

	wrmsrl(MSR_IA32_CR_PAT, pat);
	printk(KERN_INFO "x86 PAT enabled: cpu %d, old 0x%Lx, new 0x%Lx\n",
	       smp_processor_id(), boot_pat_state, pat);
}

#undef PAT

static char *cattr_name(unsigned long flags)
{
	switch (flags & _PAGE_CACHE_MASK) {
		case _PAGE_CACHE_UC:		return "uncached";
		case _PAGE_CACHE_UC_MINUS:	return "uncached-minus";
		case _PAGE_CACHE_WB:		return "write-back";
		case _PAGE_CACHE_WC:		return "write-combining";
		default:			return "broken";
	}
}

/*
 * The global memtype list keeps track of memory type for specific
 * physical memory areas. Conflicting memory types in different
 * mappings can cause CPU cache corruption. To avoid this we keep track.
 *
 * The list is sorted based on starting address and can contain multiple
 * entries for each address (this allows reference counting for overlapping
 * areas). All the aliases have the same cache attributes of course.
 * Zero attributes are represented as holes.
 *
 * Currently the data structure is a list because the number of mappings
 * are expected to be relatively small. If this should be a problem
 * it could be changed to a rbtree or similar.
 *
 * memtype_lock protects the whole list.
 */

struct memtype {
	u64 start;
	u64 end;
	unsigned long type;
	struct list_head nd;
};

static LIST_HEAD(memtype_list);
static DEFINE_SPINLOCK(memtype_lock); 	/* protects memtype list */

/*
 * Does intersection of PAT memory type and MTRR memory type and returns
 * the resulting memory type as PAT understands it.
 * (Type in pat and mtrr will not have same value)
 * The intersection is based on "Effective Memory Type" tables in IA-32
 * SDM vol 3a
 */
static int pat_x_mtrr_type(u64 start, u64 end, unsigned long prot,
				unsigned long *ret_prot)
{
	unsigned long pat_type;
	u8 mtrr_type;

	mtrr_type = mtrr_type_lookup(start, end);
	if (mtrr_type == 0xFF) {		/* MTRR not enabled */
		*ret_prot = prot;
		return 0;
	}
	if (mtrr_type == 0xFE) {		/* MTRR match error */
		*ret_prot = _PAGE_CACHE_UC;
		return -1;
	}
	if (mtrr_type != MTRR_TYPE_UNCACHABLE &&
	    mtrr_type != MTRR_TYPE_WRBACK &&
	    mtrr_type != MTRR_TYPE_WRCOMB) {	/* MTRR type unhandled */
		*ret_prot = _PAGE_CACHE_UC;
		return -1;
	}

	pat_type = prot & _PAGE_CACHE_MASK;
	prot &= (~_PAGE_CACHE_MASK);

	/* Currently doing intersection by hand. Optimize it later. */
	if (pat_type == _PAGE_CACHE_WC) {
		*ret_prot = prot | _PAGE_CACHE_WC;
	} else if (pat_type == _PAGE_CACHE_UC_MINUS) {
		*ret_prot = prot | _PAGE_CACHE_UC_MINUS;
	} else if (pat_type == _PAGE_CACHE_UC ||
	           mtrr_type == MTRR_TYPE_UNCACHABLE) {
		*ret_prot = prot | _PAGE_CACHE_UC;
	} else if (mtrr_type == MTRR_TYPE_WRCOMB) {
		*ret_prot = prot | _PAGE_CACHE_WC;
	} else {
		*ret_prot = prot | _PAGE_CACHE_WB;
	}

	return 0;
}

/*
 * req_type typically has one of the:
 * - _PAGE_CACHE_WB
 * - _PAGE_CACHE_WC
 * - _PAGE_CACHE_UC_MINUS
 * - _PAGE_CACHE_UC
 *
 * req_type will have a special case value '-1', when requester want to inherit
 * the memory type from mtrr (if WB), existing PAT, defaulting to UC_MINUS.
 *
 * If ret_type is NULL, function will return an error if it cannot reserve the
 * region with req_type. If ret_type is non-null, function will return
 * available type in ret_type in case of no error. In case of any error
 * it will return a negative return value.
 */
int reserve_memtype(u64 start, u64 end, unsigned long req_type,
			unsigned long *ret_type)
{
	struct memtype *new_entry = NULL;
	struct memtype *parse;
	unsigned long actual_type;
	int err = 0;

	/* Only track when pat_wc_enabled */
	if (!pat_wc_enabled) {
		/* This is identical to page table setting without PAT */
		if (ret_type) {
			if (req_type == -1) {
				*ret_type = _PAGE_CACHE_WB;
			} else {
				*ret_type = req_type;
			}
		}
		return 0;
	}

	/* Low ISA region is always mapped WB in page table. No need to track */
	if (start >= ISA_START_ADDRESS && (end - 1) <= ISA_END_ADDRESS) {
		if (ret_type)
			*ret_type = _PAGE_CACHE_WB;

		return 0;
	}

	if (req_type == -1) {
		/*
		 * Special case where caller wants to inherit from mtrr or
		 * existing pat mapping, defaulting to UC_MINUS in case of
		 * no match.
		 */
		u8 mtrr_type = mtrr_type_lookup(start, end);
		if (mtrr_type == 0xFE) { /* MTRR match error */
			err = -1;
		}

		if (mtrr_type == MTRR_TYPE_WRBACK) {
			req_type = _PAGE_CACHE_WB;
			actual_type = _PAGE_CACHE_WB;
		} else {
			req_type = _PAGE_CACHE_UC_MINUS;
			actual_type = _PAGE_CACHE_UC_MINUS;
		}
	} else {
		req_type &= _PAGE_CACHE_MASK;
		err = pat_x_mtrr_type(start, end, req_type, &actual_type);
	}

	if (err) {
		if (ret_type)
			*ret_type = actual_type;

		return -EINVAL;
	}

	new_entry  = kmalloc(sizeof(struct memtype), GFP_KERNEL);
	if (!new_entry)
		return -ENOMEM;

	new_entry->start = start;
	new_entry->end = end;
	new_entry->type = actual_type;

	if (ret_type)
		*ret_type = actual_type;

	spin_lock(&memtype_lock);

	/* Search for existing mapping that overlaps the current range */
	list_for_each_entry(parse, &memtype_list, nd) {
		struct memtype *saved_ptr;

		if (parse->start >= end) {
			pr_debug("New Entry\n");
			list_add(&new_entry->nd, parse->nd.prev);
			new_entry = NULL;
			break;
		}

		if (start <= parse->start && end >= parse->start) {
			if (actual_type != parse->type && ret_type) {
				actual_type = parse->type;
				*ret_type = actual_type;
				new_entry->type = actual_type;
			}

			if (actual_type != parse->type) {
				printk(
		KERN_INFO "%s:%d conflicting memory types %Lx-%Lx %s<->%s\n",
					current->comm, current->pid,
					start, end,
					cattr_name(actual_type),
					cattr_name(parse->type));
				err = -EBUSY;
				break;
			}

			saved_ptr = parse;
			/*
			 * Check to see whether the request overlaps more
			 * than one entry in the list
			 */
			list_for_each_entry_continue(parse, &memtype_list, nd) {
				if (end <= parse->start) {
					break;
				}

				if (actual_type != parse->type) {
					printk(
		KERN_INFO "%s:%d conflicting memory types %Lx-%Lx %s<->%s\n",
						current->comm, current->pid,
						start, end,
						cattr_name(actual_type),
						cattr_name(parse->type));
					err = -EBUSY;
					break;
				}
			}

			if (err) {
				break;
			}

			pr_debug("Overlap at 0x%Lx-0x%Lx\n",
			       saved_ptr->start, saved_ptr->end);
			/* No conflict. Go ahead and add this new entry */
			list_add(&new_entry->nd, saved_ptr->nd.prev);
			new_entry = NULL;
			break;
		}

		if (start < parse->end) {
			if (actual_type != parse->type && ret_type) {
				actual_type = parse->type;
				*ret_type = actual_type;
				new_entry->type = actual_type;
			}

			if (actual_type != parse->type) {
				printk(
		KERN_INFO "%s:%d conflicting memory types %Lx-%Lx %s<->%s\n",
					current->comm, current->pid,
					start, end,
					cattr_name(actual_type),
					cattr_name(parse->type));
				err = -EBUSY;
				break;
			}

			saved_ptr = parse;
			/*
			 * Check to see whether the request overlaps more
			 * than one entry in the list
			 */
			list_for_each_entry_continue(parse, &memtype_list, nd) {
				if (end <= parse->start) {
					break;
				}

				if (actual_type != parse->type) {
					printk(
		KERN_INFO "%s:%d conflicting memory types %Lx-%Lx %s<->%s\n",
						current->comm, current->pid,
						start, end,
						cattr_name(actual_type),
						cattr_name(parse->type));
					err = -EBUSY;
					break;
				}
			}

			if (err) {
				break;
			}

			pr_debug(KERN_INFO "Overlap at 0x%Lx-0x%Lx\n",
				 saved_ptr->start, saved_ptr->end);
			/* No conflict. Go ahead and add this new entry */
			list_add(&new_entry->nd, &saved_ptr->nd);
			new_entry = NULL;
			break;
		}
	}

	if (err) {
		printk(KERN_INFO
	"reserve_memtype failed 0x%Lx-0x%Lx, track %s, req %s\n",
			start, end, cattr_name(new_entry->type),
			cattr_name(req_type));
		kfree(new_entry);
		spin_unlock(&memtype_lock);
		return err;
	}

	if (new_entry) {
		/* No conflict. Not yet added to the list. Add to the tail */
		list_add_tail(&new_entry->nd, &memtype_list);
		pr_debug("New Entry\n");
	}

	if (ret_type) {
		pr_debug(
	"reserve_memtype added 0x%Lx-0x%Lx, track %s, req %s, ret %s\n",
			start, end, cattr_name(actual_type),
			cattr_name(req_type), cattr_name(*ret_type));
	} else {
		pr_debug(
	"reserve_memtype added 0x%Lx-0x%Lx, track %s, req %s\n",
			start, end, cattr_name(actual_type),
			cattr_name(req_type));
	}

	spin_unlock(&memtype_lock);
	return err;
}

int free_memtype(u64 start, u64 end)
{
	struct memtype *ml;
	int err = -EINVAL;

	/* Only track when pat_wc_enabled */
	if (!pat_wc_enabled) {
		return 0;
	}

	/* Low ISA region is always mapped WB. No need to track */
	if (start >= ISA_START_ADDRESS && end <= ISA_END_ADDRESS) {
		return 0;
	}

	spin_lock(&memtype_lock);
	list_for_each_entry(ml, &memtype_list, nd) {
		if (ml->start == start && ml->end == end) {
			list_del(&ml->nd);
			kfree(ml);
			err = 0;
			break;
		}
	}
	spin_unlock(&memtype_lock);

	if (err) {
		printk(KERN_INFO "%s:%d freeing invalid memtype %Lx-%Lx\n",
			current->comm, current->pid, start, end);
	}

	pr_debug("free_memtype request 0x%Lx-0x%Lx\n", start, end);
	return err;
}


/*
 * /dev/mem mmap interface. The memtype used for mapping varies:
 * - Use UC for mappings with O_SYNC flag
 * - Without O_SYNC flag, if there is any conflict in reserve_memtype,
 *   inherit the memtype from existing mapping.
 * - Else use UC_MINUS memtype (for backward compatibility with existing
 *   X drivers.
 */
pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn,
				unsigned long size, pgprot_t vma_prot)
{
	return vma_prot;
}

#ifdef CONFIG_NONPROMISC_DEVMEM
/* This check is done in drivers/char/mem.c in case of NONPROMISC_DEVMEM*/
static inline int range_is_allowed(unsigned long pfn, unsigned long size)
{
	return 1;
}
#else
static inline int range_is_allowed(unsigned long pfn, unsigned long size)
{
	u64 from = ((u64)pfn) << PAGE_SHIFT;
	u64 to = from + size;
	u64 cursor = from;

	while (cursor < to) {
		if (!devmem_is_allowed(pfn)) {
			printk(KERN_INFO
		"Program %s tried to access /dev/mem between %Lx->%Lx.\n",
				current->comm, from, to);
			return 0;
		}
		cursor += PAGE_SIZE;
		pfn++;
	}
	return 1;
}
#endif /* CONFIG_NONPROMISC_DEVMEM */

int phys_mem_access_prot_allowed(struct file *file, unsigned long pfn,
				unsigned long size, pgprot_t *vma_prot)
{
	u64 offset = ((u64) pfn) << PAGE_SHIFT;
	unsigned long flags = _PAGE_CACHE_UC_MINUS;
	int retval;

	if (!range_is_allowed(pfn, size))
		return 0;

	if (file->f_flags & O_SYNC) {
		flags = _PAGE_CACHE_UC;
	}

#ifdef CONFIG_X86_32
	/*
	 * On the PPro and successors, the MTRRs are used to set
	 * memory types for physical addresses outside main memory,
	 * so blindly setting UC or PWT on those pages is wrong.
	 * For Pentiums and earlier, the surround logic should disable
	 * caching for the high addresses through the KEN pin, but
	 * we maintain the tradition of paranoia in this code.
	 */
	if (!pat_wc_enabled &&
	    ! ( test_bit(X86_FEATURE_MTRR, boot_cpu_data.x86_capability) ||
		test_bit(X86_FEATURE_K6_MTRR, boot_cpu_data.x86_capability) ||
		test_bit(X86_FEATURE_CYRIX_ARR, boot_cpu_data.x86_capability) ||
		test_bit(X86_FEATURE_CENTAUR_MCR, boot_cpu_data.x86_capability)) &&
	   (pfn << PAGE_SHIFT) >= __pa(high_memory)) {
		flags = _PAGE_CACHE_UC;
	}
#endif

	/*
	 * With O_SYNC, we can only take UC mapping. Fail if we cannot.
	 * Without O_SYNC, we want to get
	 * - WB for WB-able memory and no other conflicting mappings
	 * - UC_MINUS for non-WB-able memory with no other conflicting mappings
	 * - Inherit from confliting mappings otherwise
	 */
	if (flags != _PAGE_CACHE_UC_MINUS) {
		retval = reserve_memtype(offset, offset + size, flags, NULL);
	} else {
		retval = reserve_memtype(offset, offset + size, -1, &flags);
	}

	if (retval < 0)
		return 0;

	if (pfn <= max_pfn_mapped &&
            ioremap_change_attr((unsigned long)__va(offset), size, flags) < 0) {
		free_memtype(offset, offset + size);
		printk(KERN_INFO
		"%s:%d /dev/mem ioremap_change_attr failed %s for %Lx-%Lx\n",
			current->comm, current->pid,
			cattr_name(flags),
			offset, (unsigned long long)(offset + size));
		return 0;
	}

	*vma_prot = __pgprot((pgprot_val(*vma_prot) & ~_PAGE_CACHE_MASK) |
			     flags);
	return 1;
}

void map_devmem(unsigned long pfn, unsigned long size, pgprot_t vma_prot)
{
	u64 addr = (u64)pfn << PAGE_SHIFT;
	unsigned long flags;
	unsigned long want_flags = (pgprot_val(vma_prot) & _PAGE_CACHE_MASK);

	reserve_memtype(addr, addr + size, want_flags, &flags);
	if (flags != want_flags) {
		printk(KERN_INFO
		"%s:%d /dev/mem expected mapping type %s for %Lx-%Lx, got %s\n",
			current->comm, current->pid,
			cattr_name(want_flags),
			addr, (unsigned long long)(addr + size),
			cattr_name(flags));
	}
}

void unmap_devmem(unsigned long pfn, unsigned long size, pgprot_t vma_prot)
{
	u64 addr = (u64)pfn << PAGE_SHIFT;

	free_memtype(addr, addr + size);
}

