// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright 2011 Paul Mackerras, IBM Corp. <paulus@au1.ibm.com>
 */

#include <linux/cpu.h>
#include <linux/kvm_host.h>
#include <linux/preempt.h>
#include <linux/export.h>
#include <linux/sched.h>
#include <linux/spinlock.h>
#include <linux/init.h>
#include <linux/memblock.h>
#include <linux/sizes.h>
#include <linux/cma.h>
#include <linux/bitops.h>

#include <asm/asm-prototypes.h>
#include <asm/cputable.h>
#include <asm/kvm_ppc.h>
#include <asm/kvm_book3s.h>
#include <asm/archrandom.h>
#include <asm/xics.h>
#include <asm/xive.h>
#include <asm/dbell.h>
#include <asm/cputhreads.h>
#include <asm/io.h>
#include <asm/opal.h>
#include <asm/smp.h>

#define KVM_CMA_CHUNK_ORDER	18

#include "book3s_xics.h"
#include "book3s_xive.h"

/*
 * The XIVE module will populate these when it loads
 */
unsigned long (*__xive_vm_h_xirr)(struct kvm_vcpu *vcpu);
unsigned long (*__xive_vm_h_ipoll)(struct kvm_vcpu *vcpu, unsigned long server);
int (*__xive_vm_h_ipi)(struct kvm_vcpu *vcpu, unsigned long server,
		       unsigned long mfrr);
int (*__xive_vm_h_cppr)(struct kvm_vcpu *vcpu, unsigned long cppr);
int (*__xive_vm_h_eoi)(struct kvm_vcpu *vcpu, unsigned long xirr);
EXPORT_SYMBOL_GPL(__xive_vm_h_xirr);
EXPORT_SYMBOL_GPL(__xive_vm_h_ipoll);
EXPORT_SYMBOL_GPL(__xive_vm_h_ipi);
EXPORT_SYMBOL_GPL(__xive_vm_h_cppr);
EXPORT_SYMBOL_GPL(__xive_vm_h_eoi);

/*
 * Hash page table alignment on newer cpus(CPU_FTR_ARCH_206)
 * should be power of 2.
 */
#define HPT_ALIGN_PAGES		((1 << 18) >> PAGE_SHIFT) /* 256k */
/*
 * By default we reserve 5% of memory for hash pagetable allocation.
 */
static unsigned long kvm_cma_resv_ratio = 5;

static struct cma *kvm_cma;

static int __init early_parse_kvm_cma_resv(char *p)
{
	pr_debug("%s(%s)\n", __func__, p);
	if (!p)
		return -EINVAL;
	return kstrtoul(p, 0, &kvm_cma_resv_ratio);
}
early_param("kvm_cma_resv_ratio", early_parse_kvm_cma_resv);

struct page *kvm_alloc_hpt_cma(unsigned long nr_pages)
{
	VM_BUG_ON(order_base_2(nr_pages) < KVM_CMA_CHUNK_ORDER - PAGE_SHIFT);

	return cma_alloc(kvm_cma, nr_pages, order_base_2(HPT_ALIGN_PAGES),
			 false);
}
EXPORT_SYMBOL_GPL(kvm_alloc_hpt_cma);

void kvm_free_hpt_cma(struct page *page, unsigned long nr_pages)
{
	cma_release(kvm_cma, page, nr_pages);
}
EXPORT_SYMBOL_GPL(kvm_free_hpt_cma);

/**
 * kvm_cma_reserve() - reserve area for kvm hash pagetable
 *
 * This function reserves memory from early allocator. It should be
 * called by arch specific code once the memblock allocator
 * has been activated and all other subsystems have already allocated/reserved
 * memory.
 */
void __init kvm_cma_reserve(void)
{
	unsigned long align_size;
	phys_addr_t selected_size;

	/*
	 * We need CMA reservation only when we are in HV mode
	 */
	if (!cpu_has_feature(CPU_FTR_HVMODE))
		return;

	selected_size = PAGE_ALIGN(memblock_phys_mem_size() * kvm_cma_resv_ratio / 100);
	if (selected_size) {
		pr_info("%s: reserving %ld MiB for global area\n", __func__,
			 (unsigned long)selected_size / SZ_1M);
		align_size = HPT_ALIGN_PAGES << PAGE_SHIFT;
		cma_declare_contiguous(0, selected_size, 0, align_size,
			KVM_CMA_CHUNK_ORDER - PAGE_SHIFT, false, "kvm_cma",
			&kvm_cma);
	}
}

/*
 * Real-mode H_CONFER implementation.
 * We check if we are the only vcpu out of this virtual core
 * still running in the guest and not ceded.  If so, we pop up
 * to the virtual-mode implementation; if not, just return to
 * the guest.
 */
long int kvmppc_rm_h_confer(struct kvm_vcpu *vcpu, int target,
			    unsigned int yield_count)
{
	struct kvmppc_vcore *vc = local_paca->kvm_hstate.kvm_vcore;
	int ptid = local_paca->kvm_hstate.ptid;
	int threads_running;
	int threads_ceded;
	int threads_conferring;
	u64 stop = get_tb() + 10 * tb_ticks_per_usec;
	int rv = H_SUCCESS; /* => don't yield */

	set_bit(ptid, &vc->conferring_threads);
	while ((get_tb() < stop) && !VCORE_IS_EXITING(vc)) {
		threads_running = VCORE_ENTRY_MAP(vc);
		threads_ceded = vc->napping_threads;
		threads_conferring = vc->conferring_threads;
		if ((threads_ceded | threads_conferring) == threads_running) {
			rv = H_TOO_HARD; /* => do yield */
			break;
		}
	}
	clear_bit(ptid, &vc->conferring_threads);
	return rv;
}

/*
 * When running HV mode KVM we need to block certain operations while KVM VMs
 * exist in the system. We use a counter of VMs to track this.
 *
 * One of the operations we need to block is onlining of secondaries, so we
 * protect hv_vm_count with get/put_online_cpus().
 */
static atomic_t hv_vm_count;

void kvm_hv_vm_activated(void)
{
	get_online_cpus();
	atomic_inc(&hv_vm_count);
	put_online_cpus();
}
EXPORT_SYMBOL_GPL(kvm_hv_vm_activated);

void kvm_hv_vm_deactivated(void)
{
	get_online_cpus();
	atomic_dec(&hv_vm_count);
	put_online_cpus();
}
EXPORT_SYMBOL_GPL(kvm_hv_vm_deactivated);

bool kvm_hv_mode_active(void)
{
	return atomic_read(&hv_vm_count) != 0;
}

extern int hcall_real_table[], hcall_real_table_end[];

int kvmppc_hcall_impl_hv_realmode(unsigned long cmd)
{
	cmd /= 4;
	if (cmd < hcall_real_table_end - hcall_real_table &&
	    hcall_real_table[cmd])
		return 1;

	return 0;
}
EXPORT_SYMBOL_GPL(kvmppc_hcall_impl_hv_realmode);

int kvmppc_hwrng_present(void)
{
	return powernv_hwrng_present();
}
EXPORT_SYMBOL_GPL(kvmppc_hwrng_present);

long kvmppc_h_random(struct kvm_vcpu *vcpu)
{
	int r;

	/* Only need to do the expensive mfmsr() on radix */
	if (kvm_is_radix(vcpu->kvm) && (mfmsr() & MSR_IR))
		r = powernv_get_random_long(&vcpu->arch.regs.gpr[4]);
	else
		r = powernv_get_random_real_mode(&vcpu->arch.regs.gpr[4]);
	if (r)
		return H_SUCCESS;

	return H_HARDWARE;
}

/*
 * Send an interrupt or message to another CPU.
 * The caller needs to include any barrier needed to order writes
 * to memory vs. the IPI/message.
 */
void kvmhv_rm_send_ipi(int cpu)
{
	void __iomem *xics_phys;
	unsigned long msg = PPC_DBELL_TYPE(PPC_DBELL_SERVER);

	/* For a nested hypervisor, use the XICS via hcall */
	if (kvmhv_on_pseries()) {
		unsigned long retbuf[PLPAR_HCALL_BUFSIZE];

		plpar_hcall_raw(H_IPI, retbuf, get_hard_smp_processor_id(cpu),
				IPI_PRIORITY);
		return;
	}

	/* On POWER9 we can use msgsnd for any destination cpu. */
	if (cpu_has_feature(CPU_FTR_ARCH_300)) {
		msg |= get_hard_smp_processor_id(cpu);
		__asm__ __volatile__ (PPC_MSGSND(%0) : : "r" (msg));
		return;
	}

	/* On POWER8 for IPIs to threads in the same core, use msgsnd. */
	if (cpu_has_feature(CPU_FTR_ARCH_207S) &&
	    cpu_first_thread_sibling(cpu) ==
	    cpu_first_thread_sibling(raw_smp_processor_id())) {
		msg |= cpu_thread_in_core(cpu);
		__asm__ __volatile__ (PPC_MSGSND(%0) : : "r" (msg));
		return;
	}

	/* We should never reach this */
	if (WARN_ON_ONCE(xics_on_xive()))
	    return;

	/* Else poke the target with an IPI */
	xics_phys = paca_ptrs[cpu]->kvm_hstate.xics_phys;
	if (xics_phys)
		__raw_rm_writeb(IPI_PRIORITY, xics_phys + XICS_MFRR);
	else
		opal_int_set_mfrr(get_hard_smp_processor_id(cpu), IPI_PRIORITY);
}

/*
 * The following functions are called from the assembly code
 * in book3s_hv_rmhandlers.S.
 */
static void kvmhv_interrupt_vcore(struct kvmppc_vcore *vc, int active)
{
	int cpu = vc->pcpu;

	/* Order setting of exit map vs. msgsnd/IPI */
	smp_mb();
	for (; active; active >>= 1, ++cpu)
		if (active & 1)
			kvmhv_rm_send_ipi(cpu);
}

void kvmhv_commence_exit(int trap)
{
	struct kvmppc_vcore *vc = local_paca->kvm_hstate.kvm_vcore;
	int ptid = local_paca->kvm_hstate.ptid;
	struct kvm_split_mode *sip = local_paca->kvm_hstate.kvm_split_mode;
	int me, ee, i, t;
	int cpu0;

	/* Set our bit in the threads-exiting-guest map in the 0xff00
	   bits of vcore->entry_exit_map */
	me = 0x100 << ptid;
	do {
		ee = vc->entry_exit_map;
	} while (cmpxchg(&vc->entry_exit_map, ee, ee | me) != ee);

	/* Are we the first here? */
	if ((ee >> 8) != 0)
		return;

	/*
	 * Trigger the other threads in this vcore to exit the guest.
	 * If this is a hypervisor decrementer interrupt then they
	 * will be already on their way out of the guest.
	 */
	if (trap != BOOK3S_INTERRUPT_HV_DECREMENTER)
		kvmhv_interrupt_vcore(vc, ee & ~(1 << ptid));

	/*
	 * If we are doing dynamic micro-threading, interrupt the other
	 * subcores to pull them out of their guests too.
	 */
	if (!sip)
		return;

	for (i = 0; i < MAX_SUBCORES; ++i) {
		vc = sip->vc[i];
		if (!vc)
			break;
		do {
			ee = vc->entry_exit_map;
			/* Already asked to exit? */
			if ((ee >> 8) != 0)
				break;
		} while (cmpxchg(&vc->entry_exit_map, ee,
				 ee | VCORE_EXIT_REQ) != ee);
		if ((ee >> 8) == 0)
			kvmhv_interrupt_vcore(vc, ee);
	}

	/*
	 * On POWER9 when running a HPT guest on a radix host (sip != NULL),
	 * we have to interrupt inactive CPU threads to get them to
	 * restore the host LPCR value.
	 */
	if (sip->lpcr_req) {
		if (cmpxchg(&sip->do_restore, 0, 1) == 0) {
			vc = local_paca->kvm_hstate.kvm_vcore;
			cpu0 = vc->pcpu + ptid - local_paca->kvm_hstate.tid;
			for (t = 1; t < threads_per_core; ++t) {
				if (sip->napped[t])
					kvmhv_rm_send_ipi(cpu0 + t);
			}
		}
	}
}

struct kvmppc_host_rm_ops *kvmppc_host_rm_ops_hv;
EXPORT_SYMBOL_GPL(kvmppc_host_rm_ops_hv);

#ifdef CONFIG_KVM_XICS
static struct kvmppc_irq_map *get_irqmap(struct kvmppc_passthru_irqmap *pimap,
					 u32 xisr)
{
	int i;

	/*
	 * We access the mapped array here without a lock.  That
	 * is safe because we never reduce the number of entries
	 * in the array and we never change the v_hwirq field of
	 * an entry once it is set.
	 *
	 * We have also carefully ordered the stores in the writer
	 * and the loads here in the reader, so that if we find a matching
	 * hwirq here, the associated GSI and irq_desc fields are valid.
	 */
	for (i = 0; i < pimap->n_mapped; i++)  {
		if (xisr == pimap->mapped[i].r_hwirq) {
			/*
			 * Order subsequent reads in the caller to serialize
			 * with the writer.
			 */
			smp_rmb();
			return &pimap->mapped[i];
		}
	}
	return NULL;
}

/*
 * If we have an interrupt that's not an IPI, check if we have a
 * passthrough adapter and if so, check if this external interrupt
 * is for the adapter.
 * We will attempt to deliver the IRQ directly to the target VCPU's
 * ICP, the virtual ICP (based on affinity - the xive value in ICS).
 *
 * If the delivery fails or if this is not for a passthrough adapter,
 * return to the host to handle this interrupt. We earlier
 * saved a copy of the XIRR in the PACA, it will be picked up by
 * the host ICP driver.
 */
static int kvmppc_check_passthru(u32 xisr, __be32 xirr, bool *again)
{
	struct kvmppc_passthru_irqmap *pimap;
	struct kvmppc_irq_map *irq_map;
	struct kvm_vcpu *vcpu;

	vcpu = local_paca->kvm_hstate.kvm_vcpu;
	if (!vcpu)
		return 1;
	pimap = kvmppc_get_passthru_irqmap(vcpu->kvm);
	if (!pimap)
		return 1;
	irq_map = get_irqmap(pimap, xisr);
	if (!irq_map)
		return 1;

	/* We're handling this interrupt, generic code doesn't need to */
	local_paca->kvm_hstate.saved_xirr = 0;

	return kvmppc_deliver_irq_passthru(vcpu, xirr, irq_map, pimap, again);
}

#else
static inline int kvmppc_check_passthru(u32 xisr, __be32 xirr, bool *again)
{
	return 1;
}
#endif

/*
 * Determine what sort of external interrupt is pending (if any).
 * Returns:
 *	0 if no interrupt is pending
 *	1 if an interrupt is pending that needs to be handled by the host
 *	2 Passthrough that needs completion in the host
 *	-1 if there was a guest wakeup IPI (which has now been cleared)
 *	-2 if there is PCI passthrough external interrupt that was handled
 */
static long kvmppc_read_one_intr(bool *again);

long kvmppc_read_intr(void)
{
	long ret = 0;
	long rc;
	bool again;

	if (xive_enabled())
		return 1;

	do {
		again = false;
		rc = kvmppc_read_one_intr(&again);
		if (rc && (ret == 0 || rc > ret))
			ret = rc;
	} while (again);
	return ret;
}

static long kvmppc_read_one_intr(bool *again)
{
	void __iomem *xics_phys;
	u32 h_xirr;
	__be32 xirr;
	u32 xisr;
	u8 host_ipi;
	int64_t rc;

	if (xive_enabled())
		return 1;

	/* see if a host IPI is pending */
	host_ipi = local_paca->kvm_hstate.host_ipi;
	if (host_ipi)
		return 1;

	/* Now read the interrupt from the ICP */
	if (kvmhv_on_pseries()) {
		unsigned long retbuf[PLPAR_HCALL_BUFSIZE];

		rc = plpar_hcall_raw(H_XIRR, retbuf, 0xFF);
		xirr = cpu_to_be32(retbuf[0]);
	} else {
		xics_phys = local_paca->kvm_hstate.xics_phys;
		rc = 0;
		if (!xics_phys)
			rc = opal_int_get_xirr(&xirr, false);
		else
			xirr = __raw_rm_readl(xics_phys + XICS_XIRR);
	}
	if (rc < 0)
		return 1;

	/*
	 * Save XIRR for later. Since we get control in reverse endian
	 * on LE systems, save it byte reversed and fetch it back in
	 * host endian. Note that xirr is the value read from the
	 * XIRR register, while h_xirr is the host endian version.
	 */
	h_xirr = be32_to_cpu(xirr);
	local_paca->kvm_hstate.saved_xirr = h_xirr;
	xisr = h_xirr & 0xffffff;
	/*
	 * Ensure that the store/load complete to guarantee all side
	 * effects of loading from XIRR has completed
	 */
	smp_mb();

	/* if nothing pending in the ICP */
	if (!xisr)
		return 0;

	/* We found something in the ICP...
	 *
	 * If it is an IPI, clear the MFRR and EOI it.
	 */
	if (xisr == XICS_IPI) {
		rc = 0;
		if (kvmhv_on_pseries()) {
			unsigned long retbuf[PLPAR_HCALL_BUFSIZE];

			plpar_hcall_raw(H_IPI, retbuf,
					hard_smp_processor_id(), 0xff);
			plpar_hcall_raw(H_EOI, retbuf, h_xirr);
		} else if (xics_phys) {
			__raw_rm_writeb(0xff, xics_phys + XICS_MFRR);
			__raw_rm_writel(xirr, xics_phys + XICS_XIRR);
		} else {
			opal_int_set_mfrr(hard_smp_processor_id(), 0xff);
			rc = opal_int_eoi(h_xirr);
		}
		/* If rc > 0, there is another interrupt pending */
		*again = rc > 0;

		/*
		 * Need to ensure side effects of above stores
		 * complete before proceeding.
		 */
		smp_mb();

		/*
		 * We need to re-check host IPI now in case it got set in the
		 * meantime. If it's clear, we bounce the interrupt to the
		 * guest
		 */
		host_ipi = local_paca->kvm_hstate.host_ipi;
		if (unlikely(host_ipi != 0)) {
			/* We raced with the host,
			 * we need to resend that IPI, bummer
			 */
			if (kvmhv_on_pseries()) {
				unsigned long retbuf[PLPAR_HCALL_BUFSIZE];

				plpar_hcall_raw(H_IPI, retbuf,
						hard_smp_processor_id(),
						IPI_PRIORITY);
			} else if (xics_phys)
				__raw_rm_writeb(IPI_PRIORITY,
						xics_phys + XICS_MFRR);
			else
				opal_int_set_mfrr(hard_smp_processor_id(),
						  IPI_PRIORITY);
			/* Let side effects complete */
			smp_mb();
			return 1;
		}

		/* OK, it's an IPI for us */
		local_paca->kvm_hstate.saved_xirr = 0;
		return -1;
	}

	return kvmppc_check_passthru(xisr, xirr, again);
}

#ifdef CONFIG_KVM_XICS
static inline bool is_rm(void)
{
	return !(mfmsr() & MSR_DR);
}

unsigned long kvmppc_rm_h_xirr(struct kvm_vcpu *vcpu)
{
	if (!kvmppc_xics_enabled(vcpu))
		return H_TOO_HARD;
	if (xics_on_xive()) {
		if (is_rm())
			return xive_rm_h_xirr(vcpu);
		if (unlikely(!__xive_vm_h_xirr))
			return H_NOT_AVAILABLE;
		return __xive_vm_h_xirr(vcpu);
	} else
		return xics_rm_h_xirr(vcpu);
}

unsigned long kvmppc_rm_h_xirr_x(struct kvm_vcpu *vcpu)
{
	if (!kvmppc_xics_enabled(vcpu))
		return H_TOO_HARD;
	vcpu->arch.regs.gpr[5] = get_tb();
	if (xics_on_xive()) {
		if (is_rm())
			return xive_rm_h_xirr(vcpu);
		if (unlikely(!__xive_vm_h_xirr))
			return H_NOT_AVAILABLE;
		return __xive_vm_h_xirr(vcpu);
	} else
		return xics_rm_h_xirr(vcpu);
}

unsigned long kvmppc_rm_h_ipoll(struct kvm_vcpu *vcpu, unsigned long server)
{
	if (!kvmppc_xics_enabled(vcpu))
		return H_TOO_HARD;
	if (xics_on_xive()) {
		if (is_rm())
			return xive_rm_h_ipoll(vcpu, server);
		if (unlikely(!__xive_vm_h_ipoll))
			return H_NOT_AVAILABLE;
		return __xive_vm_h_ipoll(vcpu, server);
	} else
		return H_TOO_HARD;
}

int kvmppc_rm_h_ipi(struct kvm_vcpu *vcpu, unsigned long server,
		    unsigned long mfrr)
{
	if (!kvmppc_xics_enabled(vcpu))
		return H_TOO_HARD;
	if (xics_on_xive()) {
		if (is_rm())
			return xive_rm_h_ipi(vcpu, server, mfrr);
		if (unlikely(!__xive_vm_h_ipi))
			return H_NOT_AVAILABLE;
		return __xive_vm_h_ipi(vcpu, server, mfrr);
	} else
		return xics_rm_h_ipi(vcpu, server, mfrr);
}

int kvmppc_rm_h_cppr(struct kvm_vcpu *vcpu, unsigned long cppr)
{
	if (!kvmppc_xics_enabled(vcpu))
		return H_TOO_HARD;
	if (xics_on_xive()) {
		if (is_rm())
			return xive_rm_h_cppr(vcpu, cppr);
		if (unlikely(!__xive_vm_h_cppr))
			return H_NOT_AVAILABLE;
		return __xive_vm_h_cppr(vcpu, cppr);
	} else
		return xics_rm_h_cppr(vcpu, cppr);
}

int kvmppc_rm_h_eoi(struct kvm_vcpu *vcpu, unsigned long xirr)
{
	if (!kvmppc_xics_enabled(vcpu))
		return H_TOO_HARD;
	if (xics_on_xive()) {
		if (is_rm())
			return xive_rm_h_eoi(vcpu, xirr);
		if (unlikely(!__xive_vm_h_eoi))
			return H_NOT_AVAILABLE;
		return __xive_vm_h_eoi(vcpu, xirr);
	} else
		return xics_rm_h_eoi(vcpu, xirr);
}
#endif /* CONFIG_KVM_XICS */

void kvmppc_bad_interrupt(struct pt_regs *regs)
{
	/*
	 * 100 could happen at any time, 200 can happen due to invalid real
	 * address access for example (or any time due to a hardware problem).
	 */
	if (TRAP(regs) == 0x100) {
		get_paca()->in_nmi++;
		system_reset_exception(regs);
		get_paca()->in_nmi--;
	} else if (TRAP(regs) == 0x200) {
		machine_check_exception(regs);
	} else {
		die("Bad interrupt in KVM entry/exit code", regs, SIGABRT);
	}
	panic("Bad KVM trap");
}

/*
 * Functions used to switch LPCR HR and UPRT bits on all threads
 * when entering and exiting HPT guests on a radix host.
 */

#define PHASE_REALMODE		1	/* in real mode */
#define PHASE_SET_LPCR		2	/* have set LPCR */
#define PHASE_OUT_OF_GUEST	4	/* have finished executing in guest */
#define PHASE_RESET_LPCR	8	/* have reset LPCR to host value */

#define ALL(p)		(((p) << 24) | ((p) << 16) | ((p) << 8) | (p))

static void wait_for_sync(struct kvm_split_mode *sip, int phase)
{
	int thr = local_paca->kvm_hstate.tid;

	sip->lpcr_sync.phase[thr] |= phase;
	phase = ALL(phase);
	while ((sip->lpcr_sync.allphases & phase) != phase) {
		HMT_low();
		barrier();
	}
	HMT_medium();
}

void kvmhv_p9_set_lpcr(struct kvm_split_mode *sip)
{
	int num_sets;
	unsigned long rb, set;

	/* wait for every other thread to get to real mode */
	wait_for_sync(sip, PHASE_REALMODE);

	/* Set LPCR and LPIDR */
	mtspr(SPRN_LPCR, sip->lpcr_req);
	mtspr(SPRN_LPID, sip->lpidr_req);
	isync();

	/*
	 * P10 will flush all the congruence class with a single tlbiel
	 */
	if (cpu_has_feature(CPU_FTR_ARCH_31))
		num_sets =  1;
	else
		num_sets = POWER9_TLB_SETS_RADIX;

	/* Invalidate the TLB on thread 0 */
	if (local_paca->kvm_hstate.tid == 0) {
		sip->do_set = 0;
		asm volatile("ptesync" : : : "memory");
		for (set = 0; set < num_sets; ++set) {
			rb = TLBIEL_INVAL_SET_LPID +
				(set << TLBIEL_INVAL_SET_SHIFT);
			asm volatile(PPC_TLBIEL(%0, %1, 0, 0, 0) : :
				     "r" (rb), "r" (0));
		}
		asm volatile("ptesync" : : : "memory");
	}

	/* indicate that we have done so and wait for others */
	wait_for_sync(sip, PHASE_SET_LPCR);
	/* order read of sip->lpcr_sync.allphases vs. sip->do_set */
	smp_rmb();
}

/*
 * Called when a thread that has been in the guest needs
 * to reload the host LPCR value - but only on POWER9 when
 * running a HPT guest on a radix host.
 */
void kvmhv_p9_restore_lpcr(struct kvm_split_mode *sip)
{
	/* we're out of the guest... */
	wait_for_sync(sip, PHASE_OUT_OF_GUEST);

	mtspr(SPRN_LPID, 0);
	mtspr(SPRN_LPCR, sip->host_lpcr);
	isync();

	if (local_paca->kvm_hstate.tid == 0) {
		sip->do_restore = 0;
		smp_wmb();	/* order store of do_restore vs. phase */
	}

	wait_for_sync(sip, PHASE_RESET_LPCR);
	smp_mb();
	local_paca->kvm_hstate.kvm_split_mode = NULL;
}

static void kvmppc_end_cede(struct kvm_vcpu *vcpu)
{
	vcpu->arch.ceded = 0;
	if (vcpu->arch.timer_running) {
		hrtimer_try_to_cancel(&vcpu->arch.dec_timer);
		vcpu->arch.timer_running = 0;
	}
}

void kvmppc_set_msr_hv(struct kvm_vcpu *vcpu, u64 msr)
{
	/*
	 * Check for illegal transactional state bit combination
	 * and if we find it, force the TS field to a safe state.
	 */
	if ((msr & MSR_TS_MASK) == MSR_TS_MASK)
		msr &= ~MSR_TS_MASK;
	vcpu->arch.shregs.msr = msr;
	kvmppc_end_cede(vcpu);
}
EXPORT_SYMBOL_GPL(kvmppc_set_msr_hv);

static void inject_interrupt(struct kvm_vcpu *vcpu, int vec, u64 srr1_flags)
{
	unsigned long msr, pc, new_msr, new_pc;

	msr = kvmppc_get_msr(vcpu);
	pc = kvmppc_get_pc(vcpu);
	new_msr = vcpu->arch.intr_msr;
	new_pc = vec;

	/* If transactional, change to suspend mode on IRQ delivery */
	if (MSR_TM_TRANSACTIONAL(msr))
		new_msr |= MSR_TS_S;
	else
		new_msr |= msr & MSR_TS_MASK;

	/*
	 * Perform MSR and PC adjustment for LPCR[AIL]=3 if it is set and
	 * applicable. AIL=2 is not supported.
	 *
	 * AIL does not apply to SRESET, MCE, or HMI (which is never
	 * delivered to the guest), and does not apply if IR=0 or DR=0.
	 */
	if (vec != BOOK3S_INTERRUPT_SYSTEM_RESET &&
	    vec != BOOK3S_INTERRUPT_MACHINE_CHECK &&
	    (vcpu->arch.vcore->lpcr & LPCR_AIL) == LPCR_AIL_3 &&
	    (msr & (MSR_IR|MSR_DR)) == (MSR_IR|MSR_DR) ) {
		new_msr |= MSR_IR | MSR_DR;
		new_pc += 0xC000000000004000ULL;
	}

	kvmppc_set_srr0(vcpu, pc);
	kvmppc_set_srr1(vcpu, (msr & SRR1_MSR_BITS) | srr1_flags);
	kvmppc_set_pc(vcpu, new_pc);
	vcpu->arch.shregs.msr = new_msr;
}

void kvmppc_inject_interrupt_hv(struct kvm_vcpu *vcpu, int vec, u64 srr1_flags)
{
	inject_interrupt(vcpu, vec, srr1_flags);
	kvmppc_end_cede(vcpu);
}
EXPORT_SYMBOL_GPL(kvmppc_inject_interrupt_hv);

/*
 * Is there a PRIV_DOORBELL pending for the guest (on POWER9)?
 * Can we inject a Decrementer or a External interrupt?
 */
void kvmppc_guest_entry_inject_int(struct kvm_vcpu *vcpu)
{
	int ext;
	unsigned long lpcr;

	/* Insert EXTERNAL bit into LPCR at the MER bit position */
	ext = (vcpu->arch.pending_exceptions >> BOOK3S_IRQPRIO_EXTERNAL) & 1;
	lpcr = mfspr(SPRN_LPCR);
	lpcr |= ext << LPCR_MER_SH;
	mtspr(SPRN_LPCR, lpcr);
	isync();

	if (vcpu->arch.shregs.msr & MSR_EE) {
		if (ext) {
			inject_interrupt(vcpu, BOOK3S_INTERRUPT_EXTERNAL, 0);
		} else {
			long int dec = mfspr(SPRN_DEC);
			if (!(lpcr & LPCR_LD))
				dec = (int) dec;
			if (dec < 0)
				inject_interrupt(vcpu,
					BOOK3S_INTERRUPT_DECREMENTER, 0);
		}
	}

	if (vcpu->arch.doorbell_request) {
		mtspr(SPRN_DPDES, 1);
		vcpu->arch.vcore->dpdes = 1;
		smp_wmb();
		vcpu->arch.doorbell_request = 0;
	}
}

static void flush_guest_tlb(struct kvm *kvm)
{
	unsigned long rb, set;

	rb = PPC_BIT(52);	/* IS = 2 */
	if (kvm_is_radix(kvm)) {
		/* R=1 PRS=1 RIC=2 */
		asm volatile(PPC_TLBIEL(%0, %4, %3, %2, %1)
			     : : "r" (rb), "i" (1), "i" (1), "i" (2),
			       "r" (0) : "memory");
		for (set = 1; set < kvm->arch.tlb_sets; ++set) {
			rb += PPC_BIT(51);	/* increment set number */
			/* R=1 PRS=1 RIC=0 */
			asm volatile(PPC_TLBIEL(%0, %4, %3, %2, %1)
				     : : "r" (rb), "i" (1), "i" (1), "i" (0),
				       "r" (0) : "memory");
		}
		asm volatile("ptesync": : :"memory");
		asm volatile(PPC_RADIX_INVALIDATE_ERAT_GUEST : : :"memory");
	} else {
		for (set = 0; set < kvm->arch.tlb_sets; ++set) {
			/* R=0 PRS=0 RIC=0 */
			asm volatile(PPC_TLBIEL(%0, %4, %3, %2, %1)
				     : : "r" (rb), "i" (0), "i" (0), "i" (0),
				       "r" (0) : "memory");
			rb += PPC_BIT(51);	/* increment set number */
		}
		asm volatile("ptesync": : :"memory");
		asm volatile(PPC_ISA_3_0_INVALIDATE_ERAT : : :"memory");
	}
}

void kvmppc_check_need_tlb_flush(struct kvm *kvm, int pcpu,
				 struct kvm_nested_guest *nested)
{
	cpumask_t *need_tlb_flush;

	/*
	 * On POWER9, individual threads can come in here, but the
	 * TLB is shared between the 4 threads in a core, hence
	 * invalidating on one thread invalidates for all.
	 * Thus we make all 4 threads use the same bit.
	 */
	if (cpu_has_feature(CPU_FTR_ARCH_300))
		pcpu = cpu_first_thread_sibling(pcpu);

	if (nested)
		need_tlb_flush = &nested->need_tlb_flush;
	else
		need_tlb_flush = &kvm->arch.need_tlb_flush;

	if (cpumask_test_cpu(pcpu, need_tlb_flush)) {
		flush_guest_tlb(kvm);

		/* Clear the bit after the TLB flush */
		cpumask_clear_cpu(pcpu, need_tlb_flush);
	}
}
EXPORT_SYMBOL_GPL(kvmppc_check_need_tlb_flush);
