/*
 * Copyright(c) 2011-2017 Intel Corporation. All rights reserved.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice (including the next
 * paragraph) shall be included in all copies or substantial portions of the
 * Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */
#include "i915_drv.h"
#include "gvt.h"

/**
 * intel_vgpu_find_page_track - find page track rcord of guest page
 * @vgpu: a vGPU
 * @gfn: the gfn of guest page
 *
 * Returns:
 * A pointer to struct intel_vgpu_page_track if found, else NULL returned.
 */
struct intel_vgpu_page_track *intel_vgpu_find_page_track(
		struct intel_vgpu *vgpu, unsigned long gfn)
{
	return radix_tree_lookup(&vgpu->page_track_tree, gfn);
}

/**
 * intel_vgpu_register_page_track - register a guest page to be tacked
 * @vgpu: a vGPU
 * @gfn: the gfn of guest page
 * @handler: page track handler
 * @priv: tracker private
 *
 * Returns:
 * zero on success, negative error code if failed.
 */
int intel_vgpu_register_page_track(struct intel_vgpu *vgpu, unsigned long gfn,
		gvt_page_track_handler_t handler, void *priv)
{
	struct intel_vgpu_page_track *track;
	int ret;

	track = intel_vgpu_find_page_track(vgpu, gfn);
	if (track)
		return -EEXIST;

	track = kzalloc(sizeof(*track), GFP_KERNEL);
	if (!track)
		return -ENOMEM;

	track->handler = handler;
	track->priv_data = priv;

	ret = radix_tree_insert(&vgpu->page_track_tree, gfn, track);
	if (ret) {
		kfree(track);
		return ret;
	}

	return 0;
}

/**
 * intel_vgpu_unregister_page_track - unregister the tracked guest page
 * @vgpu: a vGPU
 * @gfn: the gfn of guest page
 *
 */
void intel_vgpu_unregister_page_track(struct intel_vgpu *vgpu,
		unsigned long gfn)
{
	struct intel_vgpu_page_track *track;

	track = radix_tree_delete(&vgpu->page_track_tree, gfn);
	if (track) {
		if (track->tracked)
			intel_gvt_hypervisor_disable_page_track(vgpu, gfn);
		kfree(track);
	}
}

/**
 * intel_vgpu_enable_page_track - set write-protection on guest page
 * @vgpu: a vGPU
 * @gfn: the gfn of guest page
 *
 * Returns:
 * zero on success, negative error code if failed.
 */
int intel_vgpu_enable_page_track(struct intel_vgpu *vgpu, unsigned long gfn)
{
	struct intel_vgpu_page_track *track;
	int ret;

	track = intel_vgpu_find_page_track(vgpu, gfn);
	if (!track)
		return -ENXIO;

	if (track->tracked)
		return 0;

	ret = intel_gvt_hypervisor_enable_page_track(vgpu, gfn);
	if (ret)
		return ret;
	track->tracked = true;
	return 0;
}

/**
 * intel_vgpu_enable_page_track - cancel write-protection on guest page
 * @vgpu: a vGPU
 * @gfn: the gfn of guest page
 *
 * Returns:
 * zero on success, negative error code if failed.
 */
int intel_vgpu_disable_page_track(struct intel_vgpu *vgpu, unsigned long gfn)
{
	struct intel_vgpu_page_track *track;
	int ret;

	track = intel_vgpu_find_page_track(vgpu, gfn);
	if (!track)
		return -ENXIO;

	if (!track->tracked)
		return 0;

	ret = intel_gvt_hypervisor_disable_page_track(vgpu, gfn);
	if (ret)
		return ret;
	track->tracked = false;
	return 0;
}

/**
 * intel_vgpu_page_track_handler - called when write to write-protected page
 * @vgpu: a vGPU
 * @gpa: the gpa of this write
 * @data: the writed data
 * @bytes: the length of this write
 *
 * Returns:
 * zero on success, negative error code if failed.
 */
int intel_vgpu_page_track_handler(struct intel_vgpu *vgpu, u64 gpa,
		void *data, unsigned int bytes)
{
	struct intel_vgpu_page_track *page_track;
	int ret = 0;

	mutex_lock(&vgpu->vgpu_lock);

	page_track = intel_vgpu_find_page_track(vgpu, gpa >> PAGE_SHIFT);
	if (!page_track) {
		ret = -ENXIO;
		goto out;
	}

	if (unlikely(vgpu->failsafe)) {
		/* Remove write protection to prevent furture traps. */
		intel_vgpu_disable_page_track(vgpu, gpa >> PAGE_SHIFT);
	} else {
		ret = page_track->handler(page_track, gpa, data, bytes);
		if (ret)
			gvt_err("guest page write error, gpa %llx\n", gpa);
	}

out:
	mutex_unlock(&vgpu->vgpu_lock);
	return ret;
}
