/*
 * kvm guest debug support
 *
 * Copyright IBM Corp. 2014
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License (version 2 only)
 * as published by the Free Software Foundation.
 *
 *    Author(s): David Hildenbrand <dahi@linux.vnet.ibm.com>
 */
#include <linux/kvm_host.h>
#include <linux/errno.h>
#include "kvm-s390.h"
#include "gaccess.h"

/*
 * Extends the address range given by *start and *stop to include the address
 * range starting with estart and the length len. Takes care of overflowing
 * intervals and tries to minimize the overall intervall size.
 */
static void extend_address_range(u64 *start, u64 *stop, u64 estart, int len)
{
	u64 estop;

	if (len > 0)
		len--;
	else
		len = 0;

	estop = estart + len;

	/* 0-0 range represents "not set" */
	if ((*start == 0) && (*stop == 0)) {
		*start = estart;
		*stop = estop;
	} else if (*start <= *stop) {
		/* increase the existing range */
		if (estart < *start)
			*start = estart;
		if (estop > *stop)
			*stop = estop;
	} else {
		/* "overflowing" interval, whereby *stop > *start */
		if (estart <= *stop) {
			if (estop > *stop)
				*stop = estop;
		} else if (estop > *start) {
			if (estart < *start)
				*start = estart;
		}
		/* minimize the range */
		else if ((estop - *stop) < (*start - estart))
			*stop = estop;
		else
			*start = estart;
	}
}

#define MAX_INST_SIZE 6

static void enable_all_hw_bp(struct kvm_vcpu *vcpu)
{
	unsigned long start, len;
	u64 *cr9 = &vcpu->arch.sie_block->gcr[9];
	u64 *cr10 = &vcpu->arch.sie_block->gcr[10];
	u64 *cr11 = &vcpu->arch.sie_block->gcr[11];
	int i;

	if (vcpu->arch.guestdbg.nr_hw_bp <= 0 ||
	    vcpu->arch.guestdbg.hw_bp_info == NULL)
		return;

	/*
	 * If the guest is not interrested in branching events, we can savely
	 * limit them to the PER address range.
	 */
	if (!(*cr9 & PER_EVENT_BRANCH))
		*cr9 |= PER_CONTROL_BRANCH_ADDRESS;
	*cr9 |= PER_EVENT_IFETCH | PER_EVENT_BRANCH;

	for (i = 0; i < vcpu->arch.guestdbg.nr_hw_bp; i++) {
		start = vcpu->arch.guestdbg.hw_bp_info[i].addr;
		len = vcpu->arch.guestdbg.hw_bp_info[i].len;

		/*
		 * The instruction in front of the desired bp has to
		 * report instruction-fetching events
		 */
		if (start < MAX_INST_SIZE) {
			len += start;
			start = 0;
		} else {
			start -= MAX_INST_SIZE;
			len += MAX_INST_SIZE;
		}

		extend_address_range(cr10, cr11, start, len);
	}
}

static void enable_all_hw_wp(struct kvm_vcpu *vcpu)
{
	unsigned long start, len;
	u64 *cr9 = &vcpu->arch.sie_block->gcr[9];
	u64 *cr10 = &vcpu->arch.sie_block->gcr[10];
	u64 *cr11 = &vcpu->arch.sie_block->gcr[11];
	int i;

	if (vcpu->arch.guestdbg.nr_hw_wp <= 0 ||
	    vcpu->arch.guestdbg.hw_wp_info == NULL)
		return;

	/* if host uses storage alternation for special address
	 * spaces, enable all events and give all to the guest */
	if (*cr9 & PER_EVENT_STORE && *cr9 & PER_CONTROL_ALTERATION) {
		*cr9 &= ~PER_CONTROL_ALTERATION;
		*cr10 = 0;
		*cr11 = PSW_ADDR_INSN;
	} else {
		*cr9 &= ~PER_CONTROL_ALTERATION;
		*cr9 |= PER_EVENT_STORE;

		for (i = 0; i < vcpu->arch.guestdbg.nr_hw_wp; i++) {
			start = vcpu->arch.guestdbg.hw_wp_info[i].addr;
			len = vcpu->arch.guestdbg.hw_wp_info[i].len;

			extend_address_range(cr10, cr11, start, len);
		}
	}
}

void kvm_s390_backup_guest_per_regs(struct kvm_vcpu *vcpu)
{
	vcpu->arch.guestdbg.cr0 = vcpu->arch.sie_block->gcr[0];
	vcpu->arch.guestdbg.cr9 = vcpu->arch.sie_block->gcr[9];
	vcpu->arch.guestdbg.cr10 = vcpu->arch.sie_block->gcr[10];
	vcpu->arch.guestdbg.cr11 = vcpu->arch.sie_block->gcr[11];
}

void kvm_s390_restore_guest_per_regs(struct kvm_vcpu *vcpu)
{
	vcpu->arch.sie_block->gcr[0] = vcpu->arch.guestdbg.cr0;
	vcpu->arch.sie_block->gcr[9] = vcpu->arch.guestdbg.cr9;
	vcpu->arch.sie_block->gcr[10] = vcpu->arch.guestdbg.cr10;
	vcpu->arch.sie_block->gcr[11] = vcpu->arch.guestdbg.cr11;
}

void kvm_s390_patch_guest_per_regs(struct kvm_vcpu *vcpu)
{
	/*
	 * TODO: if guest psw has per enabled, otherwise 0s!
	 * This reduces the amount of reported events.
	 * Need to intercept all psw changes!
	 */

	if (guestdbg_sstep_enabled(vcpu)) {
		/* disable timer (clock-comparator) interrupts */
		vcpu->arch.sie_block->gcr[0] &= ~0x800ul;
		vcpu->arch.sie_block->gcr[9] |= PER_EVENT_IFETCH;
		vcpu->arch.sie_block->gcr[10] = 0;
		vcpu->arch.sie_block->gcr[11] = PSW_ADDR_INSN;
	}

	if (guestdbg_hw_bp_enabled(vcpu)) {
		enable_all_hw_bp(vcpu);
		enable_all_hw_wp(vcpu);
	}

	/* TODO: Instruction-fetching-nullification not allowed for now */
	if (vcpu->arch.sie_block->gcr[9] & PER_EVENT_NULLIFICATION)
		vcpu->arch.sie_block->gcr[9] &= ~PER_EVENT_NULLIFICATION;
}

#define MAX_WP_SIZE 100

static int __import_wp_info(struct kvm_vcpu *vcpu,
			    struct kvm_hw_breakpoint *bp_data,
			    struct kvm_hw_wp_info_arch *wp_info)
{
	int ret = 0;
	wp_info->len = bp_data->len;
	wp_info->addr = bp_data->addr;
	wp_info->phys_addr = bp_data->phys_addr;
	wp_info->old_data = NULL;

	if (wp_info->len < 0 || wp_info->len > MAX_WP_SIZE)
		return -EINVAL;

	wp_info->old_data = kmalloc(bp_data->len, GFP_KERNEL);
	if (!wp_info->old_data)
		return -ENOMEM;
	/* try to backup the original value */
	ret = read_guest_abs(vcpu, wp_info->phys_addr, wp_info->old_data,
			     wp_info->len);
	if (ret) {
		kfree(wp_info->old_data);
		wp_info->old_data = NULL;
	}

	return ret;
}

#define MAX_BP_COUNT 50

int kvm_s390_import_bp_data(struct kvm_vcpu *vcpu,
			    struct kvm_guest_debug *dbg)
{
	int ret = 0, nr_wp = 0, nr_bp = 0, i, size;
	struct kvm_hw_breakpoint *bp_data = NULL;
	struct kvm_hw_wp_info_arch *wp_info = NULL;
	struct kvm_hw_bp_info_arch *bp_info = NULL;

	if (dbg->arch.nr_hw_bp <= 0 || !dbg->arch.hw_bp)
		return 0;
	else if (dbg->arch.nr_hw_bp > MAX_BP_COUNT)
		return -EINVAL;

	size = dbg->arch.nr_hw_bp * sizeof(struct kvm_hw_breakpoint);
	bp_data = kmalloc(size, GFP_KERNEL);
	if (!bp_data) {
		ret = -ENOMEM;
		goto error;
	}

	if (copy_from_user(bp_data, dbg->arch.hw_bp, size)) {
		ret = -EFAULT;
		goto error;
	}

	for (i = 0; i < dbg->arch.nr_hw_bp; i++) {
		switch (bp_data[i].type) {
		case KVM_HW_WP_WRITE:
			nr_wp++;
			break;
		case KVM_HW_BP:
			nr_bp++;
			break;
		default:
			break;
		}
	}

	size = nr_wp * sizeof(struct kvm_hw_wp_info_arch);
	if (size > 0) {
		wp_info = kmalloc(size, GFP_KERNEL);
		if (!wp_info) {
			ret = -ENOMEM;
			goto error;
		}
	}
	size = nr_bp * sizeof(struct kvm_hw_bp_info_arch);
	if (size > 0) {
		bp_info = kmalloc(size, GFP_KERNEL);
		if (!bp_info) {
			ret = -ENOMEM;
			goto error;
		}
	}

	for (nr_wp = 0, nr_bp = 0, i = 0; i < dbg->arch.nr_hw_bp; i++) {
		switch (bp_data[i].type) {
		case KVM_HW_WP_WRITE:
			ret = __import_wp_info(vcpu, &bp_data[i],
					       &wp_info[nr_wp]);
			if (ret)
				goto error;
			nr_wp++;
			break;
		case KVM_HW_BP:
			bp_info[nr_bp].len = bp_data[i].len;
			bp_info[nr_bp].addr = bp_data[i].addr;
			nr_bp++;
			break;
		}
	}

	vcpu->arch.guestdbg.nr_hw_bp = nr_bp;
	vcpu->arch.guestdbg.hw_bp_info = bp_info;
	vcpu->arch.guestdbg.nr_hw_wp = nr_wp;
	vcpu->arch.guestdbg.hw_wp_info = wp_info;
	return 0;
error:
	kfree(bp_data);
	kfree(wp_info);
	kfree(bp_info);
	return ret;
}

void kvm_s390_clear_bp_data(struct kvm_vcpu *vcpu)
{
	int i;
	struct kvm_hw_wp_info_arch *hw_wp_info = NULL;

	for (i = 0; i < vcpu->arch.guestdbg.nr_hw_wp; i++) {
		hw_wp_info = &vcpu->arch.guestdbg.hw_wp_info[i];
		kfree(hw_wp_info->old_data);
		hw_wp_info->old_data = NULL;
	}
	kfree(vcpu->arch.guestdbg.hw_wp_info);
	vcpu->arch.guestdbg.hw_wp_info = NULL;

	kfree(vcpu->arch.guestdbg.hw_bp_info);
	vcpu->arch.guestdbg.hw_bp_info = NULL;

	vcpu->arch.guestdbg.nr_hw_wp = 0;
	vcpu->arch.guestdbg.nr_hw_bp = 0;
}

static inline int in_addr_range(u64 addr, u64 a, u64 b)
{
	if (a <= b)
		return (addr >= a) && (addr <= b);
	else
		/* "overflowing" interval */
		return (addr <= a) && (addr >= b);
}

#define end_of_range(bp_info) (bp_info->addr + bp_info->len - 1)

static struct kvm_hw_bp_info_arch *find_hw_bp(struct kvm_vcpu *vcpu,
					      unsigned long addr)
{
	struct kvm_hw_bp_info_arch *bp_info = vcpu->arch.guestdbg.hw_bp_info;
	int i;

	if (vcpu->arch.guestdbg.nr_hw_bp == 0)
		return NULL;

	for (i = 0; i < vcpu->arch.guestdbg.nr_hw_bp; i++) {
		/* addr is directly the start or in the range of a bp */
		if (addr == bp_info->addr)
			goto found;
		if (bp_info->len > 0 &&
		    in_addr_range(addr, bp_info->addr, end_of_range(bp_info)))
			goto found;

		bp_info++;
	}

	return NULL;
found:
	return bp_info;
}

static struct kvm_hw_wp_info_arch *any_wp_changed(struct kvm_vcpu *vcpu)
{
	int i;
	struct kvm_hw_wp_info_arch *wp_info = NULL;
	void *temp = NULL;

	if (vcpu->arch.guestdbg.nr_hw_wp == 0)
		return NULL;

	for (i = 0; i < vcpu->arch.guestdbg.nr_hw_wp; i++) {
		wp_info = &vcpu->arch.guestdbg.hw_wp_info[i];
		if (!wp_info || !wp_info->old_data || wp_info->len <= 0)
			continue;

		temp = kmalloc(wp_info->len, GFP_KERNEL);
		if (!temp)
			continue;

		/* refetch the wp data and compare it to the old value */
		if (!read_guest_abs(vcpu, wp_info->phys_addr, temp,
				    wp_info->len)) {
			if (memcmp(temp, wp_info->old_data, wp_info->len)) {
				kfree(temp);
				return wp_info;
			}
		}
		kfree(temp);
		temp = NULL;
	}

	return NULL;
}

void kvm_s390_prepare_debug_exit(struct kvm_vcpu *vcpu)
{
	vcpu->run->exit_reason = KVM_EXIT_DEBUG;
	vcpu->guest_debug &= ~KVM_GUESTDBG_EXIT_PENDING;
}

#define per_bp_event(code) \
			(code & (PER_EVENT_IFETCH | PER_EVENT_BRANCH))
#define per_write_wp_event(code) \
			(code & (PER_EVENT_STORE | PER_EVENT_STORE_REAL))

static int debug_exit_required(struct kvm_vcpu *vcpu)
{
	u32 perc = (vcpu->arch.sie_block->perc << 24);
	struct kvm_debug_exit_arch *debug_exit = &vcpu->run->debug.arch;
	struct kvm_hw_wp_info_arch *wp_info = NULL;
	struct kvm_hw_bp_info_arch *bp_info = NULL;
	unsigned long addr = vcpu->arch.sie_block->gpsw.addr;
	unsigned long peraddr = vcpu->arch.sie_block->peraddr;

	if (guestdbg_hw_bp_enabled(vcpu)) {
		if (per_write_wp_event(perc) &&
		    vcpu->arch.guestdbg.nr_hw_wp > 0) {
			wp_info = any_wp_changed(vcpu);
			if (wp_info) {
				debug_exit->addr = wp_info->addr;
				debug_exit->type = KVM_HW_WP_WRITE;
				goto exit_required;
			}
		}
		if (per_bp_event(perc) &&
			 vcpu->arch.guestdbg.nr_hw_bp > 0) {
			bp_info = find_hw_bp(vcpu, addr);
			/* remove duplicate events if PC==PER address */
			if (bp_info && (addr != peraddr)) {
				debug_exit->addr = addr;
				debug_exit->type = KVM_HW_BP;
				vcpu->arch.guestdbg.last_bp = addr;
				goto exit_required;
			}
			/* breakpoint missed */
			bp_info = find_hw_bp(vcpu, peraddr);
			if (bp_info && vcpu->arch.guestdbg.last_bp != peraddr) {
				debug_exit->addr = peraddr;
				debug_exit->type = KVM_HW_BP;
				goto exit_required;
			}
		}
	}
	if (guestdbg_sstep_enabled(vcpu) && per_bp_event(perc)) {
		debug_exit->addr = addr;
		debug_exit->type = KVM_SINGLESTEP;
		goto exit_required;
	}

	return 0;
exit_required:
	return 1;
}

#define guest_per_enabled(vcpu) \
			     (vcpu->arch.sie_block->gpsw.mask & PSW_MASK_PER)

static void filter_guest_per_event(struct kvm_vcpu *vcpu)
{
	u32 perc = vcpu->arch.sie_block->perc << 24;
	u64 peraddr = vcpu->arch.sie_block->peraddr;
	u64 addr = vcpu->arch.sie_block->gpsw.addr;
	u64 cr9 = vcpu->arch.sie_block->gcr[9];
	u64 cr10 = vcpu->arch.sie_block->gcr[10];
	u64 cr11 = vcpu->arch.sie_block->gcr[11];
	/* filter all events, demanded by the guest */
	u32 guest_perc = perc & cr9 & PER_EVENT_MASK;

	if (!guest_per_enabled(vcpu))
		guest_perc = 0;

	/* filter "successful-branching" events */
	if (guest_perc & PER_EVENT_BRANCH &&
	    cr9 & PER_CONTROL_BRANCH_ADDRESS &&
	    !in_addr_range(addr, cr10, cr11))
		guest_perc &= ~PER_EVENT_BRANCH;

	/* filter "instruction-fetching" events */
	if (guest_perc & PER_EVENT_IFETCH &&
	    !in_addr_range(peraddr, cr10, cr11))
		guest_perc &= ~PER_EVENT_IFETCH;

	/* All other PER events will be given to the guest */
	/* TODO: Check alterated address/address space */

	vcpu->arch.sie_block->perc = guest_perc >> 24;

	if (!guest_perc)
		vcpu->arch.sie_block->iprcc &= ~PGM_PER;
}

void kvm_s390_handle_per_event(struct kvm_vcpu *vcpu)
{
	if (debug_exit_required(vcpu))
		vcpu->guest_debug |= KVM_GUESTDBG_EXIT_PENDING;

	filter_guest_per_event(vcpu);
}
