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

Commit c8fe6a68 authored by Zhi Wang's avatar Zhi Wang Committed by Zhenyu Wang
Browse files

drm/i915/gvt: vGPU interrupt virtualization.



This patch introduces vGPU interrupt emulation framework.

The vGPU intrerrupt emulation framework is an event-based interrupt
emulation framework. It's responsible for emulating GEN hardware interrupts
during emulating other HW behaviour.

It consists several components:

- Descriptions of interrupt register bit
- Upper level <-> lower level interrupt mapping
- GEN HW IER/IMR/IIR register emulation routines
- Event-based interrupt propagation interface

When a GVT-g component wants to inject an interrupt to a VM during a
emulation, first it should specify the event needs to be emulated and the
framework will deal with the rest of emulation:

- Generating related virtual IIR bit according to virtual IER and IMRs,
- Generate related virtual upper level virtual IIR bit accodring to the
per-platform interrupt mapping
- Injecting a MSI to VM

Signed-off-by: default avatarZhi Wang <zhi.a.wang@intel.com>
Signed-off-by: default avatarZhenyu Wang <zhenyuw@linux.intel.com>
parent 3f728236
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
GVT_DIR := gvt
GVT_SOURCE := gvt.o aperture_gm.o handlers.o vgpu.o trace_points.o firmware.o
GVT_SOURCE := gvt.o aperture_gm.o handlers.o vgpu.o trace_points.o firmware.o \
	interrupt.o

ccflags-y                      += -I$(src) -I$(src)/$(GVT_DIR) -Wall
i915-y			       += $(addprefix $(GVT_DIR)/, $(GVT_SOURCE))
+2 −3
Original line number Diff line number Diff line
@@ -30,8 +30,7 @@
#define gvt_dbg_core(fmt, args...) \
	DRM_DEBUG_DRIVER("gvt: core: "fmt, ##args)

/*
 * Other GVT debug stuff will be introduced in the GVT device model patches.
 */
#define gvt_dbg_irq(fmt, args...) \
	DRM_DEBUG_DRIVER("gvt: irq: "fmt, ##args)

#endif
+9 −1
Original line number Diff line number Diff line
@@ -97,9 +97,10 @@ static void init_device_info(struct intel_gvt *gvt)

	if (IS_BROADWELL(gvt->dev_priv) || IS_SKYLAKE(gvt->dev_priv)) {
		info->max_support_vgpus = 8;
		info->mmio_size = 2 * 1024 * 1024;
		info->cfg_space_size = 256;
		info->mmio_size = 2 * 1024 * 1024;
		info->mmio_bar = 0;
		info->msi_cap_offset = IS_SKYLAKE(gvt->dev_priv) ? 0xac : 0x90;
	}
}

@@ -118,6 +119,7 @@ void intel_gvt_clean_device(struct drm_i915_private *dev_priv)
	if (WARN_ON(!gvt->initialized))
		return;

	intel_gvt_clean_irq(gvt);
	intel_gvt_clean_mmio_info(gvt);
	intel_gvt_free_firmware(gvt);

@@ -165,10 +167,16 @@ int intel_gvt_init_device(struct drm_i915_private *dev_priv)
	if (ret)
		goto out_clean_mmio_info;

	ret = intel_gvt_init_irq(gvt);
	if (ret)
		goto out_free_firmware;

	gvt_dbg_core("gvt device creation is done\n");
	gvt->initialized = true;
	return 0;

out_free_firmware:
	intel_gvt_free_firmware(gvt);
out_clean_mmio_info:
	intel_gvt_clean_mmio_info(gvt);
	return ret;
+9 −1
Original line number Diff line number Diff line
@@ -37,6 +37,7 @@
#include "hypercall.h"
#include "mmio.h"
#include "reg.h"
#include "interrupt.h"

#define GVT_MAX_VGPU 8

@@ -56,9 +57,10 @@ extern struct intel_gvt_host intel_gvt_host;
/* Describe per-platform limitations. */
struct intel_gvt_device_info {
	u32 max_support_vgpus;
	u32 mmio_size;
	u32 cfg_space_size;
	u32 mmio_size;
	u32 mmio_bar;
	unsigned long msi_cap_offset;
};

/* GM resources owned by a vGPU */
@@ -98,6 +100,10 @@ struct intel_vgpu_cfg_space {

#define vgpu_cfg_space(vgpu) ((vgpu)->cfg_space.virtual_cfg_space)

struct intel_vgpu_irq {
	bool irq_warn_once[INTEL_GVT_EVENT_MAX];
};

struct intel_vgpu {
	struct intel_gvt *gvt;
	int id;
@@ -109,6 +115,7 @@ struct intel_vgpu {
	struct intel_vgpu_gm gm;
	struct intel_vgpu_cfg_space cfg_space;
	struct intel_vgpu_mmio mmio;
	struct intel_vgpu_irq irq;
};

struct intel_gvt_gm {
@@ -145,6 +152,7 @@ struct intel_gvt {
	struct intel_gvt_fence fence;
	struct intel_gvt_mmio mmio;
	struct intel_gvt_firmware firmware;
	struct intel_gvt_irq irq;
};

void intel_gvt_free_firmware(struct intel_gvt *gvt);
+1 −0
Original line number Diff line number Diff line
@@ -41,6 +41,7 @@ struct intel_gvt_mpt {
	int (*detect_host)(void);
	int (*attach_vgpu)(void *vgpu, unsigned long *handle);
	void (*detach_vgpu)(unsigned long handle);
	int (*inject_msi)(unsigned long handle, u32 addr, u16 data);
};

extern struct intel_gvt_mpt xengt_mpt;
Loading