/*
 * Copyright 2011 Paul Mackerras, IBM Corp. <paulus@au1.ibm.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License, version 2, as
 * published by the Free Software Foundation.
 */

#include <linux/kvm_host.h>
#include <linux/preempt.h>
#include <linux/export.h>
#include <linux/sched.h>
#include <linux/spinlock.h>
#include <linux/bootmem.h>
#include <linux/init.h>

#include <asm/cputable.h>
#include <asm/kvm_ppc.h>
#include <asm/kvm_book3s.h>

/*
 * This maintains a list of RMAs (real mode areas) for KVM guests to use.
 * Each RMA has to be physically contiguous and of a size that the
 * hardware supports.  PPC970 and POWER7 support 64MB, 128MB and 256MB,
 * and other larger sizes.  Since we are unlikely to be allocate that
 * much physically contiguous memory after the system is up and running,
 * we preallocate a set of RMAs in early boot for KVM to use.
 */
static unsigned long kvm_rma_size = 64 << 20;	/* 64MB */
static unsigned long kvm_rma_count;

static int __init early_parse_rma_size(char *p)
{
	if (!p)
		return 1;

	kvm_rma_size = memparse(p, &p);

	return 0;
}
early_param("kvm_rma_size", early_parse_rma_size);

static int __init early_parse_rma_count(char *p)
{
	if (!p)
		return 1;

	kvm_rma_count = simple_strtoul(p, NULL, 0);

	return 0;
}
early_param("kvm_rma_count", early_parse_rma_count);

static struct kvmppc_rma_info *rma_info;
static LIST_HEAD(free_rmas);
static DEFINE_SPINLOCK(rma_lock);

/* Work out RMLS (real mode limit selector) field value for a given RMA size.
   Assumes POWER7 or PPC970. */
static inline int lpcr_rmls(unsigned long rma_size)
{
	switch (rma_size) {
	case 32ul << 20:	/* 32 MB */
		if (cpu_has_feature(CPU_FTR_ARCH_206))
			return 8;	/* only supported on POWER7 */
		return -1;
	case 64ul << 20:	/* 64 MB */
		return 3;
	case 128ul << 20:	/* 128 MB */
		return 7;
	case 256ul << 20:	/* 256 MB */
		return 4;
	case 1ul << 30:		/* 1 GB */
		return 2;
	case 16ul << 30:	/* 16 GB */
		return 1;
	case 256ul << 30:	/* 256 GB */
		return 0;
	default:
		return -1;
	}
}

/*
 * Called at boot time while the bootmem allocator is active,
 * to allocate contiguous physical memory for the real memory
 * areas for guests.
 */
void __init kvm_rma_init(void)
{
	unsigned long i;
	unsigned long j, npages;
	void *rma;
	struct page *pg;

	/* Only do this on PPC970 in HV mode */
	if (!cpu_has_feature(CPU_FTR_HVMODE) ||
	    !cpu_has_feature(CPU_FTR_ARCH_201))
		return;

	if (!kvm_rma_size || !kvm_rma_count)
		return;

	/* Check that the requested size is one supported in hardware */
	if (lpcr_rmls(kvm_rma_size) < 0) {
		pr_err("RMA size of 0x%lx not supported\n", kvm_rma_size);
		return;
	}

	npages = kvm_rma_size >> PAGE_SHIFT;
	rma_info = alloc_bootmem(kvm_rma_count * sizeof(struct kvmppc_rma_info));
	for (i = 0; i < kvm_rma_count; ++i) {
		rma = alloc_bootmem_align(kvm_rma_size, kvm_rma_size);
		pr_info("Allocated KVM RMA at %p (%ld MB)\n", rma,
			kvm_rma_size >> 20);
		rma_info[i].base_virt = rma;
		rma_info[i].base_pfn = __pa(rma) >> PAGE_SHIFT;
		rma_info[i].npages = npages;
		list_add_tail(&rma_info[i].list, &free_rmas);
		atomic_set(&rma_info[i].use_count, 0);

		pg = pfn_to_page(rma_info[i].base_pfn);
		for (j = 0; j < npages; ++j) {
			atomic_inc(&pg->_count);
			++pg;
		}
	}
}

struct kvmppc_rma_info *kvm_alloc_rma(void)
{
	struct kvmppc_rma_info *ri;

	ri = NULL;
	spin_lock(&rma_lock);
	if (!list_empty(&free_rmas)) {
		ri = list_first_entry(&free_rmas, struct kvmppc_rma_info, list);
		list_del(&ri->list);
		atomic_inc(&ri->use_count);
	}
	spin_unlock(&rma_lock);
	return ri;
}
EXPORT_SYMBOL_GPL(kvm_alloc_rma);

void kvm_release_rma(struct kvmppc_rma_info *ri)
{
	if (atomic_dec_and_test(&ri->use_count)) {
		spin_lock(&rma_lock);
		list_add_tail(&ri->list, &free_rmas);
		spin_unlock(&rma_lock);

	}
}
EXPORT_SYMBOL_GPL(kvm_release_rma);

