Commit 87809d31 authored by Rodrigo Vivi's avatar Rodrigo Vivi
Browse files

Merge tag 'gvt-fixes-2023-01-05' of https://github.com/intel/gvt-linux into drm-intel-fixes



gvt-fixes-2023-01-05

- Fix one missed unpin in error of intel_vgpu_shadow_mm_pin()
- Fix two debugfs destroy oops issues for vgpu and gvt entries
- Fix one potential double free issue in gtt shadow pt code
- Fix to use atomic bit flag for vgpu status

Signed-off-by: default avatarRodrigo Vivi <rodrigo.vivi@intel.com>
From: Zhenyu Wang <zhenyuw@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/Y7YWoFpz4plnSLCd@zhen-hp.sh.intel.com
parents 88603b6d 4a61648a
Loading
Loading
Loading
Loading
+31 −5
Original line number Original line Diff line number Diff line
@@ -151,6 +151,22 @@ DEFINE_SIMPLE_ATTRIBUTE(vgpu_scan_nonprivbb_fops,
			vgpu_scan_nonprivbb_get, vgpu_scan_nonprivbb_set,
			vgpu_scan_nonprivbb_get, vgpu_scan_nonprivbb_set,
			"0x%llx\n");
			"0x%llx\n");


static int vgpu_status_get(void *data, u64 *val)
{
	struct intel_vgpu *vgpu = (struct intel_vgpu *)data;

	*val = 0;

	if (test_bit(INTEL_VGPU_STATUS_ATTACHED, vgpu->status))
		*val |= (1 << INTEL_VGPU_STATUS_ATTACHED);
	if (test_bit(INTEL_VGPU_STATUS_ACTIVE, vgpu->status))
		*val |= (1 << INTEL_VGPU_STATUS_ACTIVE);

	return 0;
}

DEFINE_SIMPLE_ATTRIBUTE(vgpu_status_fops, vgpu_status_get, NULL, "0x%llx\n");

/**
/**
 * intel_gvt_debugfs_add_vgpu - register debugfs entries for a vGPU
 * intel_gvt_debugfs_add_vgpu - register debugfs entries for a vGPU
 * @vgpu: a vGPU
 * @vgpu: a vGPU
@@ -162,11 +178,12 @@ void intel_gvt_debugfs_add_vgpu(struct intel_vgpu *vgpu)
	snprintf(name, 16, "vgpu%d", vgpu->id);
	snprintf(name, 16, "vgpu%d", vgpu->id);
	vgpu->debugfs = debugfs_create_dir(name, vgpu->gvt->debugfs_root);
	vgpu->debugfs = debugfs_create_dir(name, vgpu->gvt->debugfs_root);


	debugfs_create_bool("active", 0444, vgpu->debugfs, &vgpu->active);
	debugfs_create_file("mmio_diff", 0444, vgpu->debugfs, vgpu,
	debugfs_create_file("mmio_diff", 0444, vgpu->debugfs, vgpu,
			    &vgpu_mmio_diff_fops);
			    &vgpu_mmio_diff_fops);
	debugfs_create_file("scan_nonprivbb", 0644, vgpu->debugfs, vgpu,
	debugfs_create_file("scan_nonprivbb", 0644, vgpu->debugfs, vgpu,
			    &vgpu_scan_nonprivbb_fops);
			    &vgpu_scan_nonprivbb_fops);
	debugfs_create_file("status", 0644, vgpu->debugfs, vgpu,
			    &vgpu_status_fops);
}
}


/**
/**
@@ -175,9 +192,14 @@ void intel_gvt_debugfs_add_vgpu(struct intel_vgpu *vgpu)
 */
 */
void intel_gvt_debugfs_remove_vgpu(struct intel_vgpu *vgpu)
void intel_gvt_debugfs_remove_vgpu(struct intel_vgpu *vgpu)
{
{
	struct intel_gvt *gvt = vgpu->gvt;
	struct drm_minor *minor = gvt->gt->i915->drm.primary;

	if (minor->debugfs_root && gvt->debugfs_root) {
		debugfs_remove_recursive(vgpu->debugfs);
		debugfs_remove_recursive(vgpu->debugfs);
		vgpu->debugfs = NULL;
		vgpu->debugfs = NULL;
	}
	}
}


/**
/**
 * intel_gvt_debugfs_init - register gvt debugfs root entry
 * intel_gvt_debugfs_init - register gvt debugfs root entry
@@ -199,6 +221,10 @@ void intel_gvt_debugfs_init(struct intel_gvt *gvt)
 */
 */
void intel_gvt_debugfs_clean(struct intel_gvt *gvt)
void intel_gvt_debugfs_clean(struct intel_gvt *gvt)
{
{
	struct drm_minor *minor = gvt->gt->i915->drm.primary;

	if (minor->debugfs_root) {
		debugfs_remove_recursive(gvt->debugfs_root);
		debugfs_remove_recursive(gvt->debugfs_root);
		gvt->debugfs_root = NULL;
		gvt->debugfs_root = NULL;
	}
	}
}
+2 −1
Original line number Original line Diff line number Diff line
@@ -134,7 +134,8 @@ static void dmabuf_gem_object_free(struct kref *kref)
	struct list_head *pos;
	struct list_head *pos;
	struct intel_vgpu_dmabuf_obj *dmabuf_obj;
	struct intel_vgpu_dmabuf_obj *dmabuf_obj;


	if (vgpu && vgpu->active && !list_empty(&vgpu->dmabuf_obj_list_head)) {
	if (vgpu && test_bit(INTEL_VGPU_STATUS_ACTIVE, vgpu->status) &&
	    !list_empty(&vgpu->dmabuf_obj_list_head)) {
		list_for_each(pos, &vgpu->dmabuf_obj_list_head) {
		list_for_each(pos, &vgpu->dmabuf_obj_list_head) {
			dmabuf_obj = list_entry(pos, struct intel_vgpu_dmabuf_obj, list);
			dmabuf_obj = list_entry(pos, struct intel_vgpu_dmabuf_obj, list);
			if (dmabuf_obj == obj) {
			if (dmabuf_obj == obj) {
+15 −6
Original line number Original line Diff line number Diff line
@@ -55,7 +55,7 @@ static bool intel_gvt_is_valid_gfn(struct intel_vgpu *vgpu, unsigned long gfn)
	int idx;
	int idx;
	bool ret;
	bool ret;


	if (!vgpu->attached)
	if (!test_bit(INTEL_VGPU_STATUS_ATTACHED, vgpu->status))
		return false;
		return false;


	idx = srcu_read_lock(&kvm->srcu);
	idx = srcu_read_lock(&kvm->srcu);
@@ -1178,7 +1178,7 @@ static int is_2MB_gtt_possible(struct intel_vgpu *vgpu,
	if (!HAS_PAGE_SIZES(vgpu->gvt->gt->i915, I915_GTT_PAGE_SIZE_2M))
	if (!HAS_PAGE_SIZES(vgpu->gvt->gt->i915, I915_GTT_PAGE_SIZE_2M))
		return 0;
		return 0;


	if (!vgpu->attached)
	if (!test_bit(INTEL_VGPU_STATUS_ATTACHED, vgpu->status))
		return -EINVAL;
		return -EINVAL;
	pfn = gfn_to_pfn(vgpu->vfio_device.kvm, ops->get_pfn(entry));
	pfn = gfn_to_pfn(vgpu->vfio_device.kvm, ops->get_pfn(entry));
	if (is_error_noslot_pfn(pfn))
	if (is_error_noslot_pfn(pfn))
@@ -1209,10 +1209,8 @@ static int split_2MB_gtt_entry(struct intel_vgpu *vgpu,
	for_each_shadow_entry(sub_spt, &sub_se, sub_index) {
	for_each_shadow_entry(sub_spt, &sub_se, sub_index) {
		ret = intel_gvt_dma_map_guest_page(vgpu, start_gfn + sub_index,
		ret = intel_gvt_dma_map_guest_page(vgpu, start_gfn + sub_index,
						   PAGE_SIZE, &dma_addr);
						   PAGE_SIZE, &dma_addr);
		if (ret) {
		if (ret)
			ppgtt_invalidate_spt(spt);
			goto err;
			return ret;
		}
		sub_se.val64 = se->val64;
		sub_se.val64 = se->val64;


		/* Copy the PAT field from PDE. */
		/* Copy the PAT field from PDE. */
@@ -1231,6 +1229,17 @@ static int split_2MB_gtt_entry(struct intel_vgpu *vgpu,
	ops->set_pfn(se, sub_spt->shadow_page.mfn);
	ops->set_pfn(se, sub_spt->shadow_page.mfn);
	ppgtt_set_shadow_entry(spt, se, index);
	ppgtt_set_shadow_entry(spt, se, index);
	return 0;
	return 0;
err:
	/* Cancel the existing addess mappings of DMA addr. */
	for_each_present_shadow_entry(sub_spt, &sub_se, sub_index) {
		gvt_vdbg_mm("invalidate 4K entry\n");
		ppgtt_invalidate_pte(sub_spt, &sub_se);
	}
	/* Release the new allocated spt. */
	trace_spt_change(sub_spt->vgpu->id, "release", sub_spt,
		sub_spt->guest_page.gfn, sub_spt->shadow_page.type);
	ppgtt_free_spt(sub_spt);
	return ret;
}
}


static int split_64KB_gtt_entry(struct intel_vgpu *vgpu,
static int split_64KB_gtt_entry(struct intel_vgpu *vgpu,
+10 −5
Original line number Original line Diff line number Diff line
@@ -172,13 +172,18 @@ struct intel_vgpu_submission {


#define KVMGT_DEBUGFS_FILENAME		"kvmgt_nr_cache_entries"
#define KVMGT_DEBUGFS_FILENAME		"kvmgt_nr_cache_entries"


enum {
	INTEL_VGPU_STATUS_ATTACHED = 0,
	INTEL_VGPU_STATUS_ACTIVE,
	INTEL_VGPU_STATUS_NR_BITS,
};

struct intel_vgpu {
struct intel_vgpu {
	struct vfio_device vfio_device;
	struct vfio_device vfio_device;
	struct intel_gvt *gvt;
	struct intel_gvt *gvt;
	struct mutex vgpu_lock;
	struct mutex vgpu_lock;
	int id;
	int id;
	bool active;
	DECLARE_BITMAP(status, INTEL_VGPU_STATUS_NR_BITS);
	bool attached;
	bool pv_notified;
	bool pv_notified;
	bool failsafe;
	bool failsafe;
	unsigned int resetting_eng;
	unsigned int resetting_eng;
@@ -467,7 +472,7 @@ void intel_vgpu_write_fence(struct intel_vgpu *vgpu,


#define for_each_active_vgpu(gvt, vgpu, id) \
#define for_each_active_vgpu(gvt, vgpu, id) \
	idr_for_each_entry((&(gvt)->vgpu_idr), (vgpu), (id)) \
	idr_for_each_entry((&(gvt)->vgpu_idr), (vgpu), (id)) \
		for_each_if(vgpu->active)
		for_each_if(test_bit(INTEL_VGPU_STATUS_ACTIVE, vgpu->status))


static inline void intel_vgpu_write_pci_bar(struct intel_vgpu *vgpu,
static inline void intel_vgpu_write_pci_bar(struct intel_vgpu *vgpu,
					    u32 offset, u32 val, bool low)
					    u32 offset, u32 val, bool low)
@@ -725,7 +730,7 @@ static inline bool intel_gvt_mmio_is_cmd_write_patch(
static inline int intel_gvt_read_gpa(struct intel_vgpu *vgpu, unsigned long gpa,
static inline int intel_gvt_read_gpa(struct intel_vgpu *vgpu, unsigned long gpa,
		void *buf, unsigned long len)
		void *buf, unsigned long len)
{
{
	if (!vgpu->attached)
	if (!test_bit(INTEL_VGPU_STATUS_ATTACHED, vgpu->status))
		return -ESRCH;
		return -ESRCH;
	return vfio_dma_rw(&vgpu->vfio_device, gpa, buf, len, false);
	return vfio_dma_rw(&vgpu->vfio_device, gpa, buf, len, false);
}
}
@@ -743,7 +748,7 @@ static inline int intel_gvt_read_gpa(struct intel_vgpu *vgpu, unsigned long gpa,
static inline int intel_gvt_write_gpa(struct intel_vgpu *vgpu,
static inline int intel_gvt_write_gpa(struct intel_vgpu *vgpu,
		unsigned long gpa, void *buf, unsigned long len)
		unsigned long gpa, void *buf, unsigned long len)
{
{
	if (!vgpu->attached)
	if (!test_bit(INTEL_VGPU_STATUS_ATTACHED, vgpu->status))
		return -ESRCH;
		return -ESRCH;
	return vfio_dma_rw(&vgpu->vfio_device, gpa, buf, len, true);
	return vfio_dma_rw(&vgpu->vfio_device, gpa, buf, len, true);
}
}
+1 −1
Original line number Original line Diff line number Diff line
@@ -433,7 +433,7 @@ static int inject_virtual_interrupt(struct intel_vgpu *vgpu)
	 * enabled by guest. so if msi_trigger is null, success is still
	 * enabled by guest. so if msi_trigger is null, success is still
	 * returned and don't inject interrupt into guest.
	 * returned and don't inject interrupt into guest.
	 */
	 */
	if (!vgpu->attached)
	if (!test_bit(INTEL_VGPU_STATUS_ATTACHED, vgpu->status))
		return -ESRCH;
		return -ESRCH;
	if (vgpu->msi_trigger && eventfd_signal(vgpu->msi_trigger, 1) != 1)
	if (vgpu->msi_trigger && eventfd_signal(vgpu->msi_trigger, 1) != 1)
		return -EFAULT;
		return -EFAULT;
Loading