drivers/gpu/drm/i915/gvt/aperture_gm.c

Source file repositories/reference/linux-study-clean/drivers/gpu/drm/i915/gvt/aperture_gm.c

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/i915/gvt/aperture_gm.c
Extension
.c
Size
9787 bytes
Lines
371
Domain
Driver Families
Bucket
drivers/gpu
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

#include <drm/drm_print.h>

#include "gt/intel_ggtt_fencing.h"

#include "gvt.h"
#include "i915_drv.h"
#include "i915_reg.h"

static int alloc_gm(struct intel_vgpu *vgpu, bool high_gm)
{
	struct intel_gvt *gvt = vgpu->gvt;
	struct intel_gt *gt = gvt->gt;
	unsigned int flags;
	u64 start, end, size;
	struct drm_mm_node *node;
	intel_wakeref_t wakeref;
	int ret;

	if (high_gm) {
		node = &vgpu->gm.high_gm_node;
		size = vgpu_hidden_sz(vgpu);
		start = ALIGN(gvt_hidden_gmadr_base(gvt), I915_GTT_PAGE_SIZE);
		end = ALIGN(gvt_hidden_gmadr_end(gvt), I915_GTT_PAGE_SIZE);
		flags = PIN_HIGH;
	} else {
		node = &vgpu->gm.low_gm_node;
		size = vgpu_aperture_sz(vgpu);
		start = ALIGN(gvt_aperture_gmadr_base(gvt), I915_GTT_PAGE_SIZE);
		end = ALIGN(gvt_aperture_gmadr_end(gvt), I915_GTT_PAGE_SIZE);
		flags = PIN_MAPPABLE;
	}

	mutex_lock(&gt->ggtt->vm.mutex);
	wakeref = mmio_hw_access_pre(gt);
	ret = i915_gem_gtt_insert(&gt->ggtt->vm, NULL, node,
				  size, I915_GTT_PAGE_SIZE,
				  I915_COLOR_UNEVICTABLE,
				  start, end, flags);
	mmio_hw_access_post(gt, wakeref);
	mutex_unlock(&gt->ggtt->vm.mutex);
	if (ret)
		gvt_err("fail to alloc %s gm space from host\n",
			high_gm ? "high" : "low");

	return ret;
}

static int alloc_vgpu_gm(struct intel_vgpu *vgpu)
{
	struct intel_gvt *gvt = vgpu->gvt;
	struct intel_gt *gt = gvt->gt;
	int ret;

	ret = alloc_gm(vgpu, false);
	if (ret)
		return ret;

	ret = alloc_gm(vgpu, true);
	if (ret)
		goto out_free_aperture;

	gvt_dbg_core("vgpu%d: alloc low GM start %llx size %llx\n", vgpu->id,
		     vgpu_aperture_offset(vgpu), vgpu_aperture_sz(vgpu));

	gvt_dbg_core("vgpu%d: alloc high GM start %llx size %llx\n", vgpu->id,
		     vgpu_hidden_offset(vgpu), vgpu_hidden_sz(vgpu));

	return 0;
out_free_aperture:
	mutex_lock(&gt->ggtt->vm.mutex);
	drm_mm_remove_node(&vgpu->gm.low_gm_node);
	mutex_unlock(&gt->ggtt->vm.mutex);
	return ret;
}

static void free_vgpu_gm(struct intel_vgpu *vgpu)
{
	struct intel_gvt *gvt = vgpu->gvt;
	struct intel_gt *gt = gvt->gt;

	mutex_lock(&gt->ggtt->vm.mutex);
	drm_mm_remove_node(&vgpu->gm.low_gm_node);
	drm_mm_remove_node(&vgpu->gm.high_gm_node);
	mutex_unlock(&gt->ggtt->vm.mutex);
}

/**
 * intel_vgpu_write_fence - write fence registers owned by a vGPU
 * @vgpu: vGPU instance
 * @fence: vGPU fence register number

Annotation

Implementation Notes