brintos

brintos / linux-shallow public Read only

0
0
Text · 4.6 KiB · 60a6543 Raw
180 lines · c
1/*2 * Copyright(c) 2011-2017 Intel Corporation. All rights reserved.3 *4 * Permission is hereby granted, free of charge, to any person obtaining a5 * copy of this software and associated documentation files (the "Software"),6 * to deal in the Software without restriction, including without limitation7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,8 * and/or sell copies of the Software, and to permit persons to whom the9 * Software is furnished to do so, subject to the following conditions:10 *11 * The above copyright notice and this permission notice (including the next12 * paragraph) shall be included in all copies or substantial portions of the13 * Software.14 *15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE21 * SOFTWARE.22 */23#include "i915_drv.h"24#include "gvt.h"25 26/**27 * intel_vgpu_find_page_track - find page track rcord of guest page28 * @vgpu: a vGPU29 * @gfn: the gfn of guest page30 *31 * Returns:32 * A pointer to struct intel_vgpu_page_track if found, else NULL returned.33 */34struct intel_vgpu_page_track *intel_vgpu_find_page_track(35		struct intel_vgpu *vgpu, unsigned long gfn)36{37	return radix_tree_lookup(&vgpu->page_track_tree, gfn);38}39 40/**41 * intel_vgpu_register_page_track - register a guest page to be tacked42 * @vgpu: a vGPU43 * @gfn: the gfn of guest page44 * @handler: page track handler45 * @priv: tracker private46 *47 * Returns:48 * zero on success, negative error code if failed.49 */50int intel_vgpu_register_page_track(struct intel_vgpu *vgpu, unsigned long gfn,51		gvt_page_track_handler_t handler, void *priv)52{53	struct intel_vgpu_page_track *track;54	int ret;55 56	track = intel_vgpu_find_page_track(vgpu, gfn);57	if (track)58		return -EEXIST;59 60	track = kzalloc(sizeof(*track), GFP_KERNEL);61	if (!track)62		return -ENOMEM;63 64	track->handler = handler;65	track->priv_data = priv;66 67	ret = radix_tree_insert(&vgpu->page_track_tree, gfn, track);68	if (ret) {69		kfree(track);70		return ret;71	}72 73	return 0;74}75 76/**77 * intel_vgpu_unregister_page_track - unregister the tracked guest page78 * @vgpu: a vGPU79 * @gfn: the gfn of guest page80 *81 */82void intel_vgpu_unregister_page_track(struct intel_vgpu *vgpu,83		unsigned long gfn)84{85	struct intel_vgpu_page_track *track;86 87	track = radix_tree_delete(&vgpu->page_track_tree, gfn);88	if (track) {89		if (track->tracked)90			intel_gvt_page_track_remove(vgpu, gfn);91		kfree(track);92	}93}94 95/**96 * intel_vgpu_enable_page_track - set write-protection on guest page97 * @vgpu: a vGPU98 * @gfn: the gfn of guest page99 *100 * Returns:101 * zero on success, negative error code if failed.102 */103int intel_vgpu_enable_page_track(struct intel_vgpu *vgpu, unsigned long gfn)104{105	struct intel_vgpu_page_track *track;106	int ret;107 108	track = intel_vgpu_find_page_track(vgpu, gfn);109	if (!track)110		return -ENXIO;111 112	if (track->tracked)113		return 0;114 115	ret = intel_gvt_page_track_add(vgpu, gfn);116	if (ret)117		return ret;118	track->tracked = true;119	return 0;120}121 122/**123 * intel_vgpu_disable_page_track - cancel write-protection on guest page124 * @vgpu: a vGPU125 * @gfn: the gfn of guest page126 *127 * Returns:128 * zero on success, negative error code if failed.129 */130int intel_vgpu_disable_page_track(struct intel_vgpu *vgpu, unsigned long gfn)131{132	struct intel_vgpu_page_track *track;133	int ret;134 135	track = intel_vgpu_find_page_track(vgpu, gfn);136	if (!track)137		return -ENXIO;138 139	if (!track->tracked)140		return 0;141 142	ret = intel_gvt_page_track_remove(vgpu, gfn);143	if (ret)144		return ret;145	track->tracked = false;146	return 0;147}148 149/**150 * intel_vgpu_page_track_handler - called when write to write-protected page151 * @vgpu: a vGPU152 * @gpa: the gpa of this write153 * @data: the writed data154 * @bytes: the length of this write155 *156 * Returns:157 * zero on success, negative error code if failed.158 */159int intel_vgpu_page_track_handler(struct intel_vgpu *vgpu, u64 gpa,160		void *data, unsigned int bytes)161{162	struct intel_vgpu_page_track *page_track;163	int ret = 0;164 165	page_track = intel_vgpu_find_page_track(vgpu, gpa >> PAGE_SHIFT);166	if (!page_track)167		return -ENXIO;168 169	if (unlikely(vgpu->failsafe)) {170		/* Remove write protection to prevent furture traps. */171		intel_gvt_page_track_remove(vgpu, gpa >> PAGE_SHIFT);172	} else {173		ret = page_track->handler(page_track, gpa, data, bytes);174		if (ret)175			gvt_err("guest page write error, gpa %llx\n", gpa);176	}177 178	return ret;179}180