Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8be8f4a9 authored by Daniel Vetter's avatar Daniel Vetter
Browse files

Merge tag 'gvt-next-kvmgt-framework' of https://github.com/01org/gvt-linux...

Merge tag 'gvt-next-kvmgt-framework' of https://github.com/01org/gvt-linux

 into drm-intel-next-queued

Zhenyu Wang writes:

gvt-next-kvmgt-framework

This adds initial KVMGT framework based on GVT-g MPT(Mediated Passthrough) interface.

Signed-off-by: default avatarDaniel Vetter <daniel.vetter@intel.com>
parents 0c40ce13 f30437c5
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -107,6 +107,15 @@ config DRM_I915_GVT

	  If in doubt, say "N".

config DRM_I915_GVT_KVMGT
	tristate "Enable KVM/VFIO support for Intel GVT-g"
	depends on DRM_I915_GVT
	depends on KVM
	default n
	help
	  Choose this option if you want to enable KVMGT support for
	  Intel GVT-g.

menu "drm/i915 Debugging"
depends on DRM_I915
depends on EXPERT
+5 −2
Original line number Diff line number Diff line
@@ -5,3 +5,6 @@ GVT_SOURCE := gvt.o aperture_gm.o handlers.o vgpu.o trace_points.o firmware.o \

ccflags-y				+= -I$(src) -I$(src)/$(GVT_DIR) -Wall
i915-y					+= $(addprefix $(GVT_DIR)/, $(GVT_SOURCE))

CFLAGS_kvmgt.o				:= -Wno-unused-function
obj-$(CONFIG_DRM_I915_GVT_KVMGT)	+= $(GVT_DIR)/kvmgt.o
+4 −8
Original line number Diff line number Diff line
@@ -47,11 +47,9 @@ enum {
 * Returns:
 * Zero on success, negative error code if failed.
 */
int intel_vgpu_emulate_cfg_read(void *__vgpu, unsigned int offset,
int intel_vgpu_emulate_cfg_read(struct intel_vgpu *vgpu, unsigned int offset,
	void *p_data, unsigned int bytes)
{
	struct intel_vgpu *vgpu = __vgpu;

	if (WARN_ON(bytes > 4))
		return -EINVAL;

@@ -82,9 +80,8 @@ static int map_aperture(struct intel_vgpu *vgpu, bool map)

	ret = intel_gvt_hypervisor_map_gfn_to_mfn(vgpu, first_gfn,
						  first_mfn,
						  vgpu_aperture_sz(vgpu)
						  >> PAGE_SHIFT, map,
						  GVT_MAP_APERTURE);
						  vgpu_aperture_sz(vgpu) >>
						  PAGE_SHIFT, map);
	if (ret)
		return ret;

@@ -235,10 +232,9 @@ static int emulate_pci_bar_write(struct intel_vgpu *vgpu, unsigned int offset,
 * Returns:
 * Zero on success, negative error code if failed.
 */
int intel_vgpu_emulate_cfg_write(void *__vgpu, unsigned int offset,
int intel_vgpu_emulate_cfg_write(struct intel_vgpu *vgpu, unsigned int offset,
	void *p_data, unsigned int bytes)
{
	struct intel_vgpu *vgpu = __vgpu;
	int ret;

	if (WARN_ON(bytes > 4))
+17 −34
Original line number Diff line number Diff line
@@ -974,7 +974,7 @@ static int ppgtt_populate_shadow_page(struct intel_vgpu_ppgtt_spt *spt)
}

static int ppgtt_handle_guest_entry_removal(struct intel_vgpu_guest_page *gpt,
		struct intel_gvt_gtt_entry *we, unsigned long index)
		unsigned long index)
{
	struct intel_vgpu_ppgtt_spt *spt = guest_page_to_ppgtt_spt(gpt);
	struct intel_vgpu_shadow_page *sp = &spt->shadow_page;
@@ -983,25 +983,26 @@ static int ppgtt_handle_guest_entry_removal(struct intel_vgpu_guest_page *gpt,
	struct intel_gvt_gtt_entry e;
	int ret;

	trace_gpt_change(spt->vgpu->id, "remove", spt, sp->type,
		we->val64, index);

	ppgtt_get_shadow_entry(spt, &e, index);

	trace_gpt_change(spt->vgpu->id, "remove", spt, sp->type, e.val64,
			 index);

	if (!ops->test_present(&e))
		return 0;

	if (ops->get_pfn(&e) == vgpu->gtt.scratch_pt[sp->type].page_mfn)
		return 0;

	if (gtt_type_is_pt(get_next_pt_type(we->type))) {
		struct intel_vgpu_guest_page *g =
			intel_vgpu_find_guest_page(vgpu, ops->get_pfn(we));
		if (!g) {
	if (gtt_type_is_pt(get_next_pt_type(e.type))) {
		struct intel_vgpu_ppgtt_spt *s =
			ppgtt_find_shadow_page(vgpu, ops->get_pfn(&e));
		if (!s) {
			gvt_err("fail to find guest page\n");
			ret = -ENXIO;
			goto fail;
		}
		ret = ppgtt_invalidate_shadow_page(guest_page_to_ppgtt_spt(g));
		ret = ppgtt_invalidate_shadow_page(s);
		if (ret)
			goto fail;
	}
@@ -1010,7 +1011,7 @@ static int ppgtt_handle_guest_entry_removal(struct intel_vgpu_guest_page *gpt,
	return 0;
fail:
	gvt_err("vgpu%d: fail: shadow page %p guest entry 0x%llx type %d\n",
			vgpu->id, spt, we->val64, we->type);
			vgpu->id, spt, e.val64, e.type);
	return ret;
}

@@ -1231,23 +1232,16 @@ static int ppgtt_handle_guest_write_page_table(
	struct intel_vgpu_ppgtt_spt *spt = guest_page_to_ppgtt_spt(gpt);
	struct intel_vgpu *vgpu = spt->vgpu;
	struct intel_gvt_gtt_pte_ops *ops = vgpu->gvt->gtt.pte_ops;
	struct intel_gvt_gtt_entry ge;

	int old_present, new_present;
	int ret;
	int new_present;

	ppgtt_get_guest_entry(spt, &ge, index);

	old_present = ops->test_present(&ge);
	new_present = ops->test_present(we);

	ppgtt_set_guest_entry(spt, we, index);

	if (old_present) {
		ret = ppgtt_handle_guest_entry_removal(gpt, &ge, index);
	ret = ppgtt_handle_guest_entry_removal(gpt, index);
	if (ret)
		goto fail;
	}

	if (new_present) {
		ret = ppgtt_handle_guest_entry_add(gpt, we, index);
		if (ret)
@@ -1293,7 +1287,7 @@ int intel_vgpu_flush_post_shadow(struct intel_vgpu *vgpu)
{
	struct list_head *pos, *n;
	struct intel_vgpu_ppgtt_spt *spt;
	struct intel_gvt_gtt_entry ge, e;
	struct intel_gvt_gtt_entry ge;
	unsigned long index;
	int ret;

@@ -1304,9 +1298,6 @@ int intel_vgpu_flush_post_shadow(struct intel_vgpu *vgpu)
		for_each_set_bit(index, spt->post_shadow_bitmap,
				GTT_ENTRY_NUM_IN_ONE_PAGE) {
			ppgtt_get_guest_entry(spt, &ge, index);
			e = ge;
			e.val64 = 0;
			ppgtt_set_guest_entry(spt, &e, index);

			ret = ppgtt_handle_guest_write_page_table(
					&spt->guest_page, &ge, index);
@@ -1334,8 +1325,6 @@ static int ppgtt_handle_guest_write_page_table_bytes(void *gp,
	index = (pa & (PAGE_SIZE - 1)) >> info->gtt_entry_size_shift;

	ppgtt_get_guest_entry(spt, &we, index);
	memcpy((void *)&we.val64 + (pa & (info->gtt_entry_size - 1)),
			p_data, bytes);

	ops->test_pse(&we);

@@ -1344,19 +1333,13 @@ static int ppgtt_handle_guest_write_page_table_bytes(void *gp,
		if (ret)
			return ret;
	} else {
		struct intel_gvt_gtt_entry ge;

		ppgtt_get_guest_entry(spt, &ge, index);

		if (!test_bit(index, spt->post_shadow_bitmap)) {
			ret = ppgtt_handle_guest_entry_removal(gpt,
					&ge, index);
			ret = ppgtt_handle_guest_entry_removal(gpt, index);
			if (ret)
				return ret;
		}

		ppgtt_set_post_shadow(spt, index);
		ppgtt_set_guest_entry(spt, &we, index);
	}

	if (!enable_out_of_sync)
+26 −3
Original line number Diff line number Diff line
@@ -44,11 +44,14 @@ static const char * const supported_hypervisors[] = {
	[INTEL_GVT_HYPERVISOR_KVM] = "KVM",
};

struct intel_gvt_io_emulation_ops intel_gvt_io_emulation_ops = {
static const struct intel_gvt_ops intel_gvt_ops = {
	.emulate_cfg_read = intel_vgpu_emulate_cfg_read,
	.emulate_cfg_write = intel_vgpu_emulate_cfg_write,
	.emulate_mmio_read = intel_vgpu_emulate_mmio_read,
	.emulate_mmio_write = intel_vgpu_emulate_mmio_write,
	.vgpu_create = intel_gvt_create_vgpu,
	.vgpu_destroy = intel_gvt_destroy_vgpu,
	.vgpu_reset = intel_gvt_reset_vgpu,
};

/**
@@ -81,10 +84,12 @@ int intel_gvt_init_host(void)
				symbol_get(xengt_mpt), "xengt");
		intel_gvt_host.hypervisor_type = INTEL_GVT_HYPERVISOR_XEN;
	} else {
#if IS_ENABLED(CONFIG_DRM_I915_GVT_KVMGT)
		/* not in Xen. Try KVMGT */
		intel_gvt_host.mpt = try_then_request_module(
				symbol_get(kvmgt_mpt), "kvm");
				symbol_get(kvmgt_mpt), "kvmgt");
		intel_gvt_host.hypervisor_type = INTEL_GVT_HYPERVISOR_KVM;
#endif
	}

	/* Fail to load MPT modules - bail out */
@@ -193,6 +198,9 @@ void intel_gvt_clean_device(struct drm_i915_private *dev_priv)
	intel_gvt_clean_mmio_info(gvt);
	intel_gvt_free_firmware(gvt);

	intel_gvt_hypervisor_host_exit(&dev_priv->drm.pdev->dev, gvt);
	intel_gvt_clean_vgpu_types(gvt);

	kfree(dev_priv->gvt);
	dev_priv->gvt = NULL;
}
@@ -270,10 +278,25 @@ int intel_gvt_init_device(struct drm_i915_private *dev_priv)
	if (ret)
		goto out_clean_cmd_parser;

	gvt_dbg_core("gvt device creation is done\n");
	ret = intel_gvt_init_vgpu_types(gvt);
	if (ret)
		goto out_clean_thread;

	ret = intel_gvt_hypervisor_host_init(&dev_priv->drm.pdev->dev, gvt,
				&intel_gvt_ops);
	if (ret) {
		gvt_err("failed to register gvt-g host device: %d\n", ret);
		goto out_clean_types;
	}

	gvt_dbg_core("gvt device initialization is done\n");
	dev_priv->gvt = gvt;
	return 0;

out_clean_types:
	intel_gvt_clean_vgpu_types(gvt);
out_clean_thread:
	clean_service_thread(gvt);
out_clean_cmd_parser:
	intel_gvt_clean_cmd_parser(gvt);
out_clean_sched_policy:
Loading