2022-04-12 13:04:35

by Christoph Hellwig

[permalink] [raw]
Subject: refactor the i915 GVT support and move to the modern mdev API v3

Hi all,

the GVT code in the i915 is a bit of a mess right now due to strange
abstractions and lots of indirect calls. This series refactors various
bits to clean that up. The main user visible change is that almost all
of the GVT code moves out of the main i915 driver and into the kvmgt
module.

Tested on my Thinkpad with a Kaby Lake CPU and integrated graphics.

Git tree:

git://git.infradead.org/users/hch/misc.git i915-gvt

Gitweb:

http://git.infradead.org/users/hch/misc.git/shortlog/refs/heads/i915-gvt

Changes since v2:
- rebased on top of Linx 5.18-rc +
"Refactor GVT-g MMIO tracking table and handlers"
- don't fold the gvt Makefile into the main Makefile
- add the mdev patches to remove the legacy interface that is now
unused to the end of the series

Changes since v1:
- rebased on Linux 5.15
- allow the kvmgvt module to be loaded at any time and thus solve
the deadlock when both i915 amd kvmgvt are modular
- include the conversion to the modern mdev API

Note that I do expect to rebased this again against 5.16-rc1 once
released, but I'd like to get this out for review ASAP.

Diffstat:
b/drivers/gpu/drm/i915/Kconfig | 33
b/drivers/gpu/drm/i915/Makefile | 31
b/drivers/gpu/drm/i915/gvt/cfg_space.c | 89 --
b/drivers/gpu/drm/i915/gvt/cmd_parser.c | 4
b/drivers/gpu/drm/i915/gvt/dmabuf.c | 36 -
b/drivers/gpu/drm/i915/gvt/execlist.c | 12
b/drivers/gpu/drm/i915/gvt/gtt.c | 55 +
b/drivers/gpu/drm/i915/gvt/gvt.h | 125 ++-
b/drivers/gpu/drm/i915/gvt/interrupt.c | 38 +
b/drivers/gpu/drm/i915/gvt/kvmgt.c | 1099 +++++++++++++++-----------------
b/drivers/gpu/drm/i915/gvt/mmio.c | 4
b/drivers/gpu/drm/i915/gvt/opregion.c | 148 ----
b/drivers/gpu/drm/i915/gvt/page_track.c | 8
b/drivers/gpu/drm/i915/gvt/scheduler.c | 37 -
b/drivers/gpu/drm/i915/gvt/trace.h | 2
b/drivers/gpu/drm/i915/gvt/vgpu.c | 22
b/drivers/gpu/drm/i915/i915_drv.c | 7
b/drivers/gpu/drm/i915/i915_drv.h | 1
b/drivers/gpu/drm/i915/i915_trace.h | 1
b/drivers/gpu/drm/i915/intel_gvt.c | 162 +++-
b/drivers/gpu/drm/i915/intel_gvt.h | 17
drivers/gpu/drm/i915/gvt/Makefile | 9
drivers/gpu/drm/i915/gvt/gvt.c | 340 ---------
drivers/gpu/drm/i915/gvt/hypercall.h | 82 --
drivers/gpu/drm/i915/gvt/mpt.h | 400 -----------
25 files changed, 929 insertions(+), 1833 deletions(-)


2022-04-12 14:12:04

by Christoph Hellwig

[permalink] [raw]
Subject: [PATCH 22/34] drm/i915/gvt: devirtualize dma_pin_guest_page

Just call the function directly and remove a pointless wrapper.

Signed-off-by: Christoph Hellwig <[email protected]>
---
drivers/gpu/drm/i915/gvt/dmabuf.c | 14 +-------------
drivers/gpu/drm/i915/gvt/gvt.h | 1 +
drivers/gpu/drm/i915/gvt/hypercall.h | 2 --
drivers/gpu/drm/i915/gvt/kvmgt.c | 4 +---
drivers/gpu/drm/i915/gvt/mpt.h | 15 ---------------
5 files changed, 3 insertions(+), 33 deletions(-)

diff --git a/drivers/gpu/drm/i915/gvt/dmabuf.c b/drivers/gpu/drm/i915/gvt/dmabuf.c
index db93b63543276..90443306a9ad4 100644
--- a/drivers/gpu/drm/i915/gvt/dmabuf.c
+++ b/drivers/gpu/drm/i915/gvt/dmabuf.c
@@ -42,18 +42,6 @@

#define GEN8_DECODE_PTE(pte) (pte & GENMASK_ULL(63, 12))

-static int vgpu_pin_dma_address(struct intel_vgpu *vgpu,
- unsigned long size,
- dma_addr_t dma_addr)
-{
- int ret = 0;
-
- if (intel_gvt_hypervisor_dma_pin_guest_page(vgpu, dma_addr))
- ret = -EINVAL;
-
- return ret;
-}
-
static int vgpu_gem_get_pages(
struct drm_i915_gem_object *obj)
{
@@ -89,7 +77,7 @@ static int vgpu_gem_get_pages(
for_each_sg(st->sgl, sg, page_num, i) {
dma_addr_t dma_addr =
GEN8_DECODE_PTE(readq(&gtt_entries[i]));
- if (vgpu_pin_dma_address(vgpu, PAGE_SIZE, dma_addr)) {
+ if (intel_gvt_dma_pin_guest_page(vgpu, dma_addr)) {
ret = -EINVAL;
goto out;
}
diff --git a/drivers/gpu/drm/i915/gvt/gvt.h b/drivers/gpu/drm/i915/gvt/gvt.h
index 4e42e6ac40772..938f572717377 100644
--- a/drivers/gpu/drm/i915/gvt/gvt.h
+++ b/drivers/gpu/drm/i915/gvt/gvt.h
@@ -767,6 +767,7 @@ void intel_gvt_debugfs_clean(struct intel_gvt *gvt);

int intel_gvt_page_track_add(struct intel_vgpu *info, u64 gfn);
int intel_gvt_page_track_remove(struct intel_vgpu *info, u64 gfn);
+int intel_gvt_dma_pin_guest_page(struct intel_vgpu *vgpu, dma_addr_t dma_addr);
int intel_gvt_dma_map_guest_page(struct intel_vgpu *vgpu, unsigned long gfn,
unsigned long size, dma_addr_t *dma_addr);
void intel_gvt_dma_unmap_guest_page(struct intel_vgpu *vgpu,
diff --git a/drivers/gpu/drm/i915/gvt/hypercall.h b/drivers/gpu/drm/i915/gvt/hypercall.h
index ba03b3368a955..d49437aeabac8 100644
--- a/drivers/gpu/drm/i915/gvt/hypercall.h
+++ b/drivers/gpu/drm/i915/gvt/hypercall.h
@@ -45,8 +45,6 @@ struct intel_vgpu;
struct intel_gvt_mpt {
int (*host_init)(struct device *dev, void *gvt);
void (*host_exit)(struct device *dev, void *gvt);
-
- int (*dma_pin_guest_page)(struct intel_vgpu *vgpu, dma_addr_t dma_addr);
};

#endif /* _GVT_HYPERCALL_H_ */
diff --git a/drivers/gpu/drm/i915/gvt/kvmgt.c b/drivers/gpu/drm/i915/gvt/kvmgt.c
index a02274036487f..606b2cb923d8e 100644
--- a/drivers/gpu/drm/i915/gvt/kvmgt.c
+++ b/drivers/gpu/drm/i915/gvt/kvmgt.c
@@ -1921,8 +1921,7 @@ int intel_gvt_dma_map_guest_page(struct intel_vgpu *vgpu, unsigned long gfn,
return ret;
}

-static int kvmgt_dma_pin_guest_page(struct intel_vgpu *vgpu,
- dma_addr_t dma_addr)
+int intel_gvt_dma_pin_guest_page(struct intel_vgpu *vgpu, dma_addr_t dma_addr)
{
struct gvt_dma *entry;
int ret = 0;
@@ -1968,7 +1967,6 @@ void intel_gvt_dma_unmap_guest_page(struct intel_vgpu *vgpu,
static const struct intel_gvt_mpt kvmgt_mpt = {
.host_init = kvmgt_host_init,
.host_exit = kvmgt_host_exit,
- .dma_pin_guest_page = kvmgt_dma_pin_guest_page,
};

struct intel_gvt_host intel_gvt_host = {
diff --git a/drivers/gpu/drm/i915/gvt/mpt.h b/drivers/gpu/drm/i915/gvt/mpt.h
index 26c1ee690f7e9..3be602a3f764a 100644
--- a/drivers/gpu/drm/i915/gvt/mpt.h
+++ b/drivers/gpu/drm/i915/gvt/mpt.h
@@ -71,19 +71,4 @@ static inline void intel_gvt_hypervisor_host_exit(struct device *dev, void *gvt)
intel_gvt_host.mpt->host_exit(dev, gvt);
}

-/**
- * intel_gvt_hypervisor_dma_pin_guest_page - pin guest dma buf
- * @vgpu: a vGPU
- * @dma_addr: guest dma addr
- *
- * Returns:
- * 0 on success, negative error code if failed.
- */
-static inline int
-intel_gvt_hypervisor_dma_pin_guest_page(struct intel_vgpu *vgpu,
- dma_addr_t dma_addr)
-{
- return intel_gvt_host.mpt->dma_pin_guest_page(vgpu, dma_addr);
-}
-
#endif /* _GVT_MPT_H_ */
--
2.30.2

2022-04-12 19:32:41

by Christoph Hellwig

[permalink] [raw]
Subject: [PATCH 11/34] drm/i915/gvt: merge struct kvmgt_guest_info into strut intel_vgpu

Consolidate the per-VGPU structures into a single one.

Signed-off-by: Christoph Hellwig <[email protected]>
---
drivers/gpu/drm/i915/gvt/gvt.h | 8 +++
drivers/gpu/drm/i915/gvt/kvmgt.c | 117 ++++++++++++-------------------
2 files changed, 52 insertions(+), 73 deletions(-)

diff --git a/drivers/gpu/drm/i915/gvt/gvt.h b/drivers/gpu/drm/i915/gvt/gvt.h
index 628dd686c03d5..16daa615f9c0d 100644
--- a/drivers/gpu/drm/i915/gvt/gvt.h
+++ b/drivers/gpu/drm/i915/gvt/gvt.h
@@ -34,6 +34,7 @@
#define _GVT_H_

#include <uapi/linux/pci_regs.h>
+#include <linux/kvm_host.h>

#include "i915_drv.h"
#include "intel_gvt.h"
@@ -174,6 +175,8 @@ struct intel_vgpu_submission {
} last_ctx[I915_NUM_ENGINES];
};

+#define KVMGT_DEBUGFS_FILENAME "kvmgt_nr_cache_entries"
+
struct intel_vgpu {
struct intel_gvt *gvt;
struct mutex vgpu_lock;
@@ -236,6 +239,11 @@ struct intel_vgpu {
atomic_t released;
struct vfio_device *vfio_device;
struct vfio_group *vfio_group;
+
+ struct kvm_page_track_notifier_node track_node;
+#define NR_BKT (1 << 18)
+ struct hlist_head ptable[NR_BKT];
+#undef NR_BKT
};

/* validating GM healthy status*/
diff --git a/drivers/gpu/drm/i915/gvt/kvmgt.c b/drivers/gpu/drm/i915/gvt/kvmgt.c
index 1c2b949d8e01f..37cdf092a7140 100644
--- a/drivers/gpu/drm/i915/gvt/kvmgt.c
+++ b/drivers/gpu/drm/i915/gvt/kvmgt.c
@@ -39,7 +39,6 @@
#include <linux/spinlock.h>
#include <linux/eventfd.h>
#include <linux/uuid.h>
-#include <linux/kvm_host.h>
#include <linux/vfio.h>
#include <linux/mdev.h>
#include <linux/debugfs.h>
@@ -92,16 +91,6 @@ struct kvmgt_pgfn {
struct hlist_node hnode;
};

-#define KVMGT_DEBUGFS_FILENAME "kvmgt_nr_cache_entries"
-struct kvmgt_guest_info {
- struct kvm *kvm;
- struct intel_vgpu *vgpu;
- struct kvm_page_track_notifier_node track_node;
-#define NR_BKT (1 << 18)
- struct hlist_head ptable[NR_BKT];
-#undef NR_BKT
-};
-
struct gvt_dma {
struct intel_vgpu *vgpu;
struct rb_node gfn_node;
@@ -232,7 +221,7 @@ static void intel_gvt_cleanup_vgpu_type_groups(struct intel_gvt *gvt)

static int kvmgt_guest_init(struct mdev_device *mdev);
static void intel_vgpu_release_work(struct work_struct *work);
-static bool kvmgt_guest_exit(struct kvmgt_guest_info *info);
+static bool kvmgt_guest_exit(struct intel_vgpu *info);

static void gvt_unpin_guest_page(struct intel_vgpu *vgpu, unsigned long gfn,
unsigned long size)
@@ -456,12 +445,12 @@ static void gvt_cache_init(struct intel_vgpu *vgpu)
mutex_init(&vgpu->cache_lock);
}

-static void kvmgt_protect_table_init(struct kvmgt_guest_info *info)
+static void kvmgt_protect_table_init(struct intel_vgpu *info)
{
hash_init(info->ptable);
}

-static void kvmgt_protect_table_destroy(struct kvmgt_guest_info *info)
+static void kvmgt_protect_table_destroy(struct intel_vgpu *info)
{
struct kvmgt_pgfn *p;
struct hlist_node *tmp;
@@ -474,7 +463,7 @@ static void kvmgt_protect_table_destroy(struct kvmgt_guest_info *info)
}

static struct kvmgt_pgfn *
-__kvmgt_protect_table_find(struct kvmgt_guest_info *info, gfn_t gfn)
+__kvmgt_protect_table_find(struct intel_vgpu *info, gfn_t gfn)
{
struct kvmgt_pgfn *p, *res = NULL;

@@ -488,8 +477,7 @@ __kvmgt_protect_table_find(struct kvmgt_guest_info *info, gfn_t gfn)
return res;
}

-static bool kvmgt_gfn_is_write_protected(struct kvmgt_guest_info *info,
- gfn_t gfn)
+static bool kvmgt_gfn_is_write_protected(struct intel_vgpu *info, gfn_t gfn)
{
struct kvmgt_pgfn *p;

@@ -497,7 +485,7 @@ static bool kvmgt_gfn_is_write_protected(struct kvmgt_guest_info *info,
return !!p;
}

-static void kvmgt_protect_table_add(struct kvmgt_guest_info *info, gfn_t gfn)
+static void kvmgt_protect_table_add(struct intel_vgpu *info, gfn_t gfn)
{
struct kvmgt_pgfn *p;

@@ -512,8 +500,7 @@ static void kvmgt_protect_table_add(struct kvmgt_guest_info *info, gfn_t gfn)
hash_add(info->ptable, &p->hnode, gfn);
}

-static void kvmgt_protect_table_del(struct kvmgt_guest_info *info,
- gfn_t gfn)
+static void kvmgt_protect_table_del(struct intel_vgpu *info, gfn_t gfn)
{
struct kvmgt_pgfn *p;

@@ -940,7 +927,6 @@ static void intel_vgpu_release_msi_eventfd_ctx(struct intel_vgpu *vgpu)
static void __intel_vgpu_release(struct intel_vgpu *vgpu)
{
struct drm_i915_private *i915 = vgpu->gvt->gt->i915;
- struct kvmgt_guest_info *info;
int ret;

if (!handle_valid(vgpu->handle))
@@ -964,8 +950,7 @@ static void __intel_vgpu_release(struct intel_vgpu *vgpu)
/* dereference module reference taken at open */
module_put(THIS_MODULE);

- info = (struct kvmgt_guest_info *)vgpu->handle;
- kvmgt_guest_exit(info);
+ kvmgt_guest_exit(vgpu);

intel_vgpu_release_msi_eventfd_ctx(vgpu);
vfio_group_put_external_user(vgpu->vfio_group);
@@ -1751,7 +1736,7 @@ static void kvmgt_host_exit(struct device *dev, void *gvt)

static int kvmgt_page_track_add(unsigned long handle, u64 gfn)
{
- struct kvmgt_guest_info *info;
+ struct intel_vgpu *info;
struct kvm *kvm;
struct kvm_memory_slot *slot;
int idx;
@@ -1759,7 +1744,7 @@ static int kvmgt_page_track_add(unsigned long handle, u64 gfn)
if (!handle_valid(handle))
return -ESRCH;

- info = (struct kvmgt_guest_info *)handle;
+ info = (struct intel_vgpu *)handle;
kvm = info->kvm;

idx = srcu_read_lock(&kvm->srcu);
@@ -1785,7 +1770,7 @@ static int kvmgt_page_track_add(unsigned long handle, u64 gfn)

static int kvmgt_page_track_remove(unsigned long handle, u64 gfn)
{
- struct kvmgt_guest_info *info;
+ struct intel_vgpu *info;
struct kvm *kvm;
struct kvm_memory_slot *slot;
int idx;
@@ -1793,7 +1778,7 @@ static int kvmgt_page_track_remove(unsigned long handle, u64 gfn)
if (!handle_valid(handle))
return 0;

- info = (struct kvmgt_guest_info *)handle;
+ info = (struct intel_vgpu *)handle;
kvm = info->kvm;

idx = srcu_read_lock(&kvm->srcu);
@@ -1821,11 +1806,11 @@ static void kvmgt_page_track_write(struct kvm_vcpu *vcpu, gpa_t gpa,
const u8 *val, int len,
struct kvm_page_track_notifier_node *node)
{
- struct kvmgt_guest_info *info = container_of(node,
- struct kvmgt_guest_info, track_node);
+ struct intel_vgpu *info =
+ container_of(node, struct intel_vgpu, track_node);

if (kvmgt_gfn_is_write_protected(info, gpa_to_gfn(gpa)))
- intel_vgpu_page_track_handler(info->vgpu, gpa,
+ intel_vgpu_page_track_handler(info, gpa,
(void *)val, len);
}

@@ -1835,8 +1820,8 @@ static void kvmgt_page_track_flush_slot(struct kvm *kvm,
{
int i;
gfn_t gfn;
- struct kvmgt_guest_info *info = container_of(node,
- struct kvmgt_guest_info, track_node);
+ struct intel_vgpu *info =
+ container_of(node, struct intel_vgpu, track_node);

write_lock(&kvm->mmu_lock);
for (i = 0; i < slot->npages; i++) {
@@ -1853,7 +1838,6 @@ static void kvmgt_page_track_flush_slot(struct kvm *kvm,
static bool __kvmgt_vgpu_exist(struct intel_vgpu *vgpu, struct kvm *kvm)
{
struct intel_vgpu *itr;
- struct kvmgt_guest_info *info;
int id;
bool ret = false;

@@ -1862,8 +1846,7 @@ static bool __kvmgt_vgpu_exist(struct intel_vgpu *vgpu, struct kvm *kvm)
if (!handle_valid(itr->handle))
continue;

- info = (struct kvmgt_guest_info *)itr->handle;
- if (kvm && kvm == info->kvm) {
+ if (kvm && kvm == itr->kvm) {
ret = true;
goto out;
}
@@ -1875,7 +1858,6 @@ static bool __kvmgt_vgpu_exist(struct intel_vgpu *vgpu, struct kvm *kvm)

static int kvmgt_guest_init(struct mdev_device *mdev)
{
- struct kvmgt_guest_info *info;
struct intel_vgpu *vgpu;
struct kvm *kvm;

@@ -1892,38 +1874,29 @@ static int kvmgt_guest_init(struct mdev_device *mdev)
if (__kvmgt_vgpu_exist(vgpu, kvm))
return -EEXIST;

- info = vzalloc(sizeof(struct kvmgt_guest_info));
- if (!info)
- return -ENOMEM;
-
- vgpu->handle = (unsigned long)info;
- info->vgpu = vgpu;
- info->kvm = kvm;
- kvm_get_kvm(info->kvm);
+ vgpu->handle = (unsigned long)vgpu;
+ kvm_get_kvm(vgpu->kvm);

- kvmgt_protect_table_init(info);
+ kvmgt_protect_table_init(vgpu);
gvt_cache_init(vgpu);

- info->track_node.track_write = kvmgt_page_track_write;
- info->track_node.track_flush_slot = kvmgt_page_track_flush_slot;
- kvm_page_track_register_notifier(kvm, &info->track_node);
+ vgpu->track_node.track_write = kvmgt_page_track_write;
+ vgpu->track_node.track_flush_slot = kvmgt_page_track_flush_slot;
+ kvm_page_track_register_notifier(kvm, &vgpu->track_node);

debugfs_create_ulong(KVMGT_DEBUGFS_FILENAME, 0444, vgpu->debugfs,
&vgpu->nr_cache_entries);
return 0;
}

-static bool kvmgt_guest_exit(struct kvmgt_guest_info *info)
+static bool kvmgt_guest_exit(struct intel_vgpu *info)
{
- debugfs_remove(debugfs_lookup(KVMGT_DEBUGFS_FILENAME,
- info->vgpu->debugfs));
+ debugfs_remove(debugfs_lookup(KVMGT_DEBUGFS_FILENAME, info->debugfs));

kvm_page_track_unregister_notifier(info->kvm, &info->track_node);
kvm_put_kvm(info->kvm);
kvmgt_protect_table_destroy(info);
- gvt_cache_destroy(info->vgpu);
- vfree(info);
-
+ gvt_cache_destroy(info);
return true;
}

@@ -1946,14 +1919,12 @@ static void kvmgt_detach_vgpu(void *p_vgpu)

static int kvmgt_inject_msi(unsigned long handle, u32 addr, u16 data)
{
- struct kvmgt_guest_info *info;
struct intel_vgpu *vgpu;

if (!handle_valid(handle))
return -ESRCH;

- info = (struct kvmgt_guest_info *)handle;
- vgpu = info->vgpu;
+ vgpu = (struct intel_vgpu *)handle;

/*
* When guest is poweroff, msi_trigger is set to NULL, but vgpu's
@@ -1975,15 +1946,15 @@ static int kvmgt_inject_msi(unsigned long handle, u32 addr, u16 data)

static unsigned long kvmgt_gfn_to_pfn(unsigned long handle, unsigned long gfn)
{
- struct kvmgt_guest_info *info;
+ struct intel_vgpu *vgpu;
kvm_pfn_t pfn;

if (!handle_valid(handle))
return INTEL_GVT_INVALID_ADDR;

- info = (struct kvmgt_guest_info *)handle;
+ vgpu = (struct intel_vgpu *)handle;

- pfn = gfn_to_pfn(info->kvm, gfn);
+ pfn = gfn_to_pfn(vgpu->kvm, gfn);
if (is_error_noslot_pfn(pfn))
return INTEL_GVT_INVALID_ADDR;

@@ -2000,7 +1971,7 @@ static int kvmgt_dma_map_guest_page(unsigned long handle, unsigned long gfn,
if (!handle_valid(handle))
return -EINVAL;

- vgpu = ((struct kvmgt_guest_info *)handle)->vgpu;
+ vgpu = (struct intel_vgpu *)handle;

mutex_lock(&vgpu->cache_lock);

@@ -2042,22 +2013,22 @@ static int kvmgt_dma_map_guest_page(unsigned long handle, unsigned long gfn,

static int kvmgt_dma_pin_guest_page(unsigned long handle, dma_addr_t dma_addr)
{
- struct kvmgt_guest_info *info;
+ struct intel_vgpu *vgpu;
struct gvt_dma *entry;
int ret = 0;

if (!handle_valid(handle))
return -ENODEV;

- info = (struct kvmgt_guest_info *)handle;
+ vgpu = (struct intel_vgpu *)handle;

- mutex_lock(&info->vgpu->cache_lock);
- entry = __gvt_cache_find_dma_addr(info->vgpu, dma_addr);
+ mutex_lock(&vgpu->cache_lock);
+ entry = __gvt_cache_find_dma_addr(vgpu, dma_addr);
if (entry)
kref_get(&entry->ref);
else
ret = -ENOMEM;
- mutex_unlock(&info->vgpu->cache_lock);
+ mutex_unlock(&vgpu->cache_lock);

return ret;
}
@@ -2079,7 +2050,7 @@ static void kvmgt_dma_unmap_guest_page(unsigned long handle, dma_addr_t dma_addr
if (!handle_valid(handle))
return;

- vgpu = ((struct kvmgt_guest_info *)handle)->vgpu;
+ vgpu = (struct intel_vgpu *)handle;

mutex_lock(&vgpu->cache_lock);
entry = __gvt_cache_find_dma_addr(vgpu, dma_addr);
@@ -2091,14 +2062,14 @@ static void kvmgt_dma_unmap_guest_page(unsigned long handle, dma_addr_t dma_addr
static int kvmgt_rw_gpa(unsigned long handle, unsigned long gpa,
void *buf, unsigned long len, bool write)
{
- struct kvmgt_guest_info *info;
+ struct intel_vgpu *vgpu;

if (!handle_valid(handle))
return -ESRCH;

- info = (struct kvmgt_guest_info *)handle;
+ vgpu = (struct intel_vgpu *)handle;

- return vfio_dma_rw(info->vgpu->vfio_group, gpa, buf, len, write);
+ return vfio_dma_rw(vgpu->vfio_group, gpa, buf, len, write);
}

static int kvmgt_read_gpa(unsigned long handle, unsigned long gpa,
@@ -2115,7 +2086,7 @@ static int kvmgt_write_gpa(unsigned long handle, unsigned long gpa,

static bool kvmgt_is_valid_gfn(unsigned long handle, unsigned long gfn)
{
- struct kvmgt_guest_info *info;
+ struct intel_vgpu *vgpu;
struct kvm *kvm;
int idx;
bool ret;
@@ -2123,8 +2094,8 @@ static bool kvmgt_is_valid_gfn(unsigned long handle, unsigned long gfn)
if (!handle_valid(handle))
return false;

- info = (struct kvmgt_guest_info *)handle;
- kvm = info->kvm;
+ vgpu = (struct intel_vgpu *)handle;
+ kvm = vgpu->kvm;

idx = srcu_read_lock(&kvm->srcu);
ret = kvm_is_visible_gfn(kvm, gfn);
--
2.30.2

2022-04-12 20:01:08

by Christoph Hellwig

[permalink] [raw]
Subject: [PATCH 21/34] drm/i915/gvt: devirtualize ->dma_{,un}map_guest_page

Just call the functions directly. Also remove a pointless wrapper.

Signed-off-by: Christoph Hellwig <[email protected]>
---
drivers/gpu/drm/i915/gvt/dmabuf.c | 10 ++--------
drivers/gpu/drm/i915/gvt/gtt.c | 20 +++++++++----------
drivers/gpu/drm/i915/gvt/gvt.h | 4 ++++
drivers/gpu/drm/i915/gvt/hypercall.h | 5 -----
drivers/gpu/drm/i915/gvt/kvmgt.c | 6 ++----
drivers/gpu/drm/i915/gvt/mpt.h | 29 ----------------------------
6 files changed, 17 insertions(+), 57 deletions(-)

diff --git a/drivers/gpu/drm/i915/gvt/dmabuf.c b/drivers/gpu/drm/i915/gvt/dmabuf.c
index cc1a9ac0d2720..db93b63543276 100644
--- a/drivers/gpu/drm/i915/gvt/dmabuf.c
+++ b/drivers/gpu/drm/i915/gvt/dmabuf.c
@@ -54,12 +54,6 @@ static int vgpu_pin_dma_address(struct intel_vgpu *vgpu,
return ret;
}

-static void vgpu_unpin_dma_address(struct intel_vgpu *vgpu,
- dma_addr_t dma_addr)
-{
- intel_gvt_hypervisor_dma_unmap_guest_page(vgpu, dma_addr);
-}
-
static int vgpu_gem_get_pages(
struct drm_i915_gem_object *obj)
{
@@ -114,7 +108,7 @@ static int vgpu_gem_get_pages(
for_each_sg(st->sgl, sg, i, j) {
dma_addr = sg_dma_address(sg);
if (dma_addr)
- vgpu_unpin_dma_address(vgpu, dma_addr);
+ intel_gvt_dma_unmap_guest_page(vgpu, dma_addr);
}
sg_free_table(st);
kfree(st);
@@ -136,7 +130,7 @@ static void vgpu_gem_put_pages(struct drm_i915_gem_object *obj,
int i;

for_each_sg(pages->sgl, sg, fb_info->size, i)
- vgpu_unpin_dma_address(vgpu,
+ intel_gvt_dma_unmap_guest_page(vgpu,
sg_dma_address(sg));
}

diff --git a/drivers/gpu/drm/i915/gvt/gtt.c b/drivers/gpu/drm/i915/gvt/gtt.c
index f6f3b22a70d26..9c5cc28009758 100644
--- a/drivers/gpu/drm/i915/gvt/gtt.c
+++ b/drivers/gpu/drm/i915/gvt/gtt.c
@@ -1013,7 +1013,7 @@ static inline void ppgtt_invalidate_pte(struct intel_vgpu_ppgtt_spt *spt,
if (!pfn || pfn == vgpu->gtt.scratch_pt[type].page_mfn)
return;

- intel_gvt_hypervisor_dma_unmap_guest_page(vgpu, pfn << PAGE_SHIFT);
+ intel_gvt_dma_unmap_guest_page(vgpu, pfn << PAGE_SHIFT);
}

static int ppgtt_invalidate_spt(struct intel_vgpu_ppgtt_spt *spt)
@@ -1212,8 +1212,8 @@ static int split_2MB_gtt_entry(struct intel_vgpu *vgpu,
return PTR_ERR(sub_spt);

for_each_shadow_entry(sub_spt, &sub_se, sub_index) {
- ret = intel_gvt_hypervisor_dma_map_guest_page(vgpu,
- start_gfn + sub_index, PAGE_SIZE, &dma_addr);
+ ret = intel_gvt_dma_map_guest_page(vgpu, start_gfn + sub_index,
+ PAGE_SIZE, &dma_addr);
if (ret) {
ppgtt_invalidate_spt(spt);
return ret;
@@ -1258,8 +1258,8 @@ static int split_64KB_gtt_entry(struct intel_vgpu *vgpu,
ops->set_64k_splited(&entry);

for (i = 0; i < GTT_64K_PTE_STRIDE; i++) {
- ret = intel_gvt_hypervisor_dma_map_guest_page(vgpu,
- start_gfn + i, PAGE_SIZE, &dma_addr);
+ ret = intel_gvt_dma_map_guest_page(vgpu, start_gfn + i,
+ PAGE_SIZE, &dma_addr);
if (ret)
return ret;

@@ -1313,8 +1313,7 @@ static int ppgtt_populate_shadow_entry(struct intel_vgpu *vgpu,
}

/* direct shadow */
- ret = intel_gvt_hypervisor_dma_map_guest_page(vgpu, gfn, page_size,
- &dma_addr);
+ ret = intel_gvt_dma_map_guest_page(vgpu, gfn, page_size, &dma_addr);
if (ret)
return -ENXIO;

@@ -2245,8 +2244,7 @@ static void ggtt_invalidate_pte(struct intel_vgpu *vgpu,

pfn = pte_ops->get_pfn(entry);
if (pfn != vgpu->gvt->gtt.scratch_mfn)
- intel_gvt_hypervisor_dma_unmap_guest_page(vgpu,
- pfn << PAGE_SHIFT);
+ intel_gvt_dma_unmap_guest_page(vgpu, pfn << PAGE_SHIFT);
}

static int emulate_ggtt_mmio_write(struct intel_vgpu *vgpu, unsigned int off,
@@ -2337,8 +2335,8 @@ static int emulate_ggtt_mmio_write(struct intel_vgpu *vgpu, unsigned int off,
goto out;
}

- ret = intel_gvt_hypervisor_dma_map_guest_page(vgpu, gfn,
- PAGE_SIZE, &dma_addr);
+ ret = intel_gvt_dma_map_guest_page(vgpu, gfn, PAGE_SIZE,
+ &dma_addr);
if (ret) {
gvt_vgpu_err("fail to populate guest ggtt entry\n");
/* guest driver may read/write the entry when partial
diff --git a/drivers/gpu/drm/i915/gvt/gvt.h b/drivers/gpu/drm/i915/gvt/gvt.h
index a8a8728cd54a8..4e42e6ac40772 100644
--- a/drivers/gpu/drm/i915/gvt/gvt.h
+++ b/drivers/gpu/drm/i915/gvt/gvt.h
@@ -767,6 +767,10 @@ void intel_gvt_debugfs_clean(struct intel_gvt *gvt);

int intel_gvt_page_track_add(struct intel_vgpu *info, u64 gfn);
int intel_gvt_page_track_remove(struct intel_vgpu *info, u64 gfn);
+int intel_gvt_dma_map_guest_page(struct intel_vgpu *vgpu, unsigned long gfn,
+ unsigned long size, dma_addr_t *dma_addr);
+void intel_gvt_dma_unmap_guest_page(struct intel_vgpu *vgpu,
+ dma_addr_t dma_addr);

#include "trace.h"
#include "mpt.h"
diff --git a/drivers/gpu/drm/i915/gvt/hypercall.h b/drivers/gpu/drm/i915/gvt/hypercall.h
index ded13a63ab663..ba03b3368a955 100644
--- a/drivers/gpu/drm/i915/gvt/hypercall.h
+++ b/drivers/gpu/drm/i915/gvt/hypercall.h
@@ -46,11 +46,6 @@ struct intel_gvt_mpt {
int (*host_init)(struct device *dev, void *gvt);
void (*host_exit)(struct device *dev, void *gvt);

- int (*dma_map_guest_page)(struct intel_vgpu *vgpu, unsigned long gfn,
- unsigned long size, dma_addr_t *dma_addr);
- void (*dma_unmap_guest_page)(struct intel_vgpu *vgpu,
- dma_addr_t dma_addr);
-
int (*dma_pin_guest_page)(struct intel_vgpu *vgpu, dma_addr_t dma_addr);
};

diff --git a/drivers/gpu/drm/i915/gvt/kvmgt.c b/drivers/gpu/drm/i915/gvt/kvmgt.c
index fbef3d3dfb1f5..a02274036487f 100644
--- a/drivers/gpu/drm/i915/gvt/kvmgt.c
+++ b/drivers/gpu/drm/i915/gvt/kvmgt.c
@@ -1874,7 +1874,7 @@ void intel_vgpu_detach_regions(struct intel_vgpu *vgpu)
vgpu->region = NULL;
}

-static int kvmgt_dma_map_guest_page(struct intel_vgpu *vgpu, unsigned long gfn,
+int intel_gvt_dma_map_guest_page(struct intel_vgpu *vgpu, unsigned long gfn,
unsigned long size, dma_addr_t *dma_addr)
{
struct gvt_dma *entry;
@@ -1950,7 +1950,7 @@ static void __gvt_dma_release(struct kref *ref)
__gvt_cache_remove_entry(entry->vgpu, entry);
}

-static void kvmgt_dma_unmap_guest_page(struct intel_vgpu *vgpu,
+void intel_gvt_dma_unmap_guest_page(struct intel_vgpu *vgpu,
dma_addr_t dma_addr)
{
struct gvt_dma *entry;
@@ -1968,8 +1968,6 @@ static void kvmgt_dma_unmap_guest_page(struct intel_vgpu *vgpu,
static const struct intel_gvt_mpt kvmgt_mpt = {
.host_init = kvmgt_host_init,
.host_exit = kvmgt_host_exit,
- .dma_map_guest_page = kvmgt_dma_map_guest_page,
- .dma_unmap_guest_page = kvmgt_dma_unmap_guest_page,
.dma_pin_guest_page = kvmgt_dma_pin_guest_page,
};

diff --git a/drivers/gpu/drm/i915/gvt/mpt.h b/drivers/gpu/drm/i915/gvt/mpt.h
index d2723ac8bb044..26c1ee690f7e9 100644
--- a/drivers/gpu/drm/i915/gvt/mpt.h
+++ b/drivers/gpu/drm/i915/gvt/mpt.h
@@ -71,35 +71,6 @@ static inline void intel_gvt_hypervisor_host_exit(struct device *dev, void *gvt)
intel_gvt_host.mpt->host_exit(dev, gvt);
}

-/**
- * intel_gvt_hypervisor_dma_map_guest_page - setup dma map for guest page
- * @vgpu: a vGPU
- * @gfn: guest pfn
- * @size: page size
- * @dma_addr: retrieve allocated dma addr
- *
- * Returns:
- * 0 on success, negative error code if failed.
- */
-static inline int intel_gvt_hypervisor_dma_map_guest_page(
- struct intel_vgpu *vgpu, unsigned long gfn, unsigned long size,
- dma_addr_t *dma_addr)
-{
- return intel_gvt_host.mpt->dma_map_guest_page(vgpu, gfn, size,
- dma_addr);
-}
-
-/**
- * intel_gvt_hypervisor_dma_unmap_guest_page - cancel dma map for guest page
- * @vgpu: a vGPU
- * @dma_addr: the mapped dma addr
- */
-static inline void intel_gvt_hypervisor_dma_unmap_guest_page(
- struct intel_vgpu *vgpu, dma_addr_t dma_addr)
-{
- intel_gvt_host.mpt->dma_unmap_guest_page(vgpu, dma_addr);
-}
-
/**
* intel_gvt_hypervisor_dma_pin_guest_page - pin guest dma buf
* @vgpu: a vGPU
--
2.30.2

2022-04-12 20:07:11

by Christoph Hellwig

[permalink] [raw]
Subject: [PATCH 34/34] vfio/mdev: Remove mdev drvdata

From: Jason Gunthorpe <[email protected]>

This is no longer used, remove it.

All usages were moved over to either use container_of() from a vfio_device
or to use dev_drvdata() directly on the mdev.

Signed-off-by: Jason Gunthorpe <[email protected]>
Signed-off-by: Christoph Hellwig <[email protected]>
---
include/linux/mdev.h | 9 ---------
1 file changed, 9 deletions(-)

diff --git a/include/linux/mdev.h b/include/linux/mdev.h
index 1f6f57a3c3168..bb539794f54a8 100644
--- a/include/linux/mdev.h
+++ b/include/linux/mdev.h
@@ -15,7 +15,6 @@ struct mdev_type;
struct mdev_device {
struct device dev;
guid_t uuid;
- void *driver_data;
struct list_head next;
struct mdev_type *type;
bool active;
@@ -66,14 +65,6 @@ struct mdev_driver {
struct device_driver driver;
};

-static inline void *mdev_get_drvdata(struct mdev_device *mdev)
-{
- return mdev->driver_data;
-}
-static inline void mdev_set_drvdata(struct mdev_device *mdev, void *data)
-{
- mdev->driver_data = data;
-}
static inline const guid_t *mdev_uuid(struct mdev_device *mdev)
{
return &mdev->uuid;
--
2.30.2

2022-04-12 20:36:43

by Christoph Hellwig

[permalink] [raw]
Subject: [PATCH 19/34] drm/i915/gvt: devirtualize ->gfn_to_mfn

Just open code it in the only caller.

Signed-off-by: Christoph Hellwig <[email protected]>
---
drivers/gpu/drm/i915/gvt/gtt.c | 9 +++++----
drivers/gpu/drm/i915/gvt/hypercall.h | 1 -
drivers/gpu/drm/i915/gvt/kvmgt.c | 16 ----------------
drivers/gpu/drm/i915/gvt/mpt.h | 14 --------------
4 files changed, 5 insertions(+), 35 deletions(-)

diff --git a/drivers/gpu/drm/i915/gvt/gtt.c b/drivers/gpu/drm/i915/gvt/gtt.c
index 1360412f8ef8a..f6f3b22a70d26 100644
--- a/drivers/gpu/drm/i915/gvt/gtt.c
+++ b/drivers/gpu/drm/i915/gvt/gtt.c
@@ -1178,15 +1178,16 @@ static int is_2MB_gtt_possible(struct intel_vgpu *vgpu,
struct intel_gvt_gtt_entry *entry)
{
const struct intel_gvt_gtt_pte_ops *ops = vgpu->gvt->gtt.pte_ops;
- unsigned long pfn;
+ kvm_pfn_t pfn;

if (!HAS_PAGE_SIZES(vgpu->gvt->gt->i915, I915_GTT_PAGE_SIZE_2M))
return 0;

- pfn = intel_gvt_hypervisor_gfn_to_mfn(vgpu, ops->get_pfn(entry));
- if (pfn == INTEL_GVT_INVALID_ADDR)
+ if (!vgpu->attached)
+ return -EINVAL;
+ pfn = gfn_to_pfn(vgpu->kvm, ops->get_pfn(entry));
+ if (is_error_noslot_pfn(pfn))
return -EINVAL;
-
return PageTransHuge(pfn_to_page(pfn));
}

diff --git a/drivers/gpu/drm/i915/gvt/hypercall.h b/drivers/gpu/drm/i915/gvt/hypercall.h
index c1a9eeed04607..dbde492cafc84 100644
--- a/drivers/gpu/drm/i915/gvt/hypercall.h
+++ b/drivers/gpu/drm/i915/gvt/hypercall.h
@@ -47,7 +47,6 @@ struct intel_gvt_mpt {
void (*host_exit)(struct device *dev, void *gvt);
int (*enable_page_track)(struct intel_vgpu *vgpu, u64 gfn);
int (*disable_page_track)(struct intel_vgpu *vgpu, u64 gfn);
- unsigned long (*gfn_to_mfn)(struct intel_vgpu *vgpu, unsigned long gfn);

int (*dma_map_guest_page)(struct intel_vgpu *vgpu, unsigned long gfn,
unsigned long size, dma_addr_t *dma_addr);
diff --git a/drivers/gpu/drm/i915/gvt/kvmgt.c b/drivers/gpu/drm/i915/gvt/kvmgt.c
index 93fd7f997c8a1..6d4c67270172a 100644
--- a/drivers/gpu/drm/i915/gvt/kvmgt.c
+++ b/drivers/gpu/drm/i915/gvt/kvmgt.c
@@ -1874,21 +1874,6 @@ void intel_vgpu_detach_regions(struct intel_vgpu *vgpu)
vgpu->region = NULL;
}

-static unsigned long kvmgt_gfn_to_pfn(struct intel_vgpu *vgpu,
- unsigned long gfn)
-{
- kvm_pfn_t pfn;
-
- if (!vgpu->attached)
- return INTEL_GVT_INVALID_ADDR;
-
- pfn = gfn_to_pfn(vgpu->kvm, gfn);
- if (is_error_noslot_pfn(pfn))
- return INTEL_GVT_INVALID_ADDR;
-
- return pfn;
-}
-
static int kvmgt_dma_map_guest_page(struct intel_vgpu *vgpu, unsigned long gfn,
unsigned long size, dma_addr_t *dma_addr)
{
@@ -1985,7 +1970,6 @@ static const struct intel_gvt_mpt kvmgt_mpt = {
.host_exit = kvmgt_host_exit,
.enable_page_track = kvmgt_page_track_add,
.disable_page_track = kvmgt_page_track_remove,
- .gfn_to_mfn = kvmgt_gfn_to_pfn,
.dma_map_guest_page = kvmgt_dma_map_guest_page,
.dma_unmap_guest_page = kvmgt_dma_unmap_guest_page,
.dma_pin_guest_page = kvmgt_dma_pin_guest_page,
diff --git a/drivers/gpu/drm/i915/gvt/mpt.h b/drivers/gpu/drm/i915/gvt/mpt.h
index 1a796f2181ba8..2d4bb6eaa08e3 100644
--- a/drivers/gpu/drm/i915/gvt/mpt.h
+++ b/drivers/gpu/drm/i915/gvt/mpt.h
@@ -99,20 +99,6 @@ static inline int intel_gvt_hypervisor_disable_page_track(
return intel_gvt_host.mpt->disable_page_track(vgpu, gfn);
}

-/**
- * intel_gvt_hypervisor_gfn_to_mfn - translate a GFN to MFN
- * @vgpu: a vGPU
- * @gpfn: guest pfn
- *
- * Returns:
- * MFN on success, INTEL_GVT_INVALID_ADDR if failed.
- */
-static inline unsigned long intel_gvt_hypervisor_gfn_to_mfn(
- struct intel_vgpu *vgpu, unsigned long gfn)
-{
- return intel_gvt_host.mpt->gfn_to_mfn(vgpu, gfn);
-}
-
/**
* intel_gvt_hypervisor_dma_map_guest_page - setup dma map for guest page
* @vgpu: a vGPU
--
2.30.2

2022-04-12 20:48:52

by Christoph Hellwig

[permalink] [raw]
Subject: [PATCH 14/34] drm/i915/gvt: devirtualize ->{get,put}_vfio_device

Just open code the calls to the VFIO APIs.

Signed-off-by: Christoph Hellwig <[email protected]>
---
drivers/gpu/drm/i915/gvt/dmabuf.c | 12 ++++++-----
drivers/gpu/drm/i915/gvt/hypercall.h | 2 --
drivers/gpu/drm/i915/gvt/kvmgt.c | 22 --------------------
drivers/gpu/drm/i915/gvt/mpt.h | 30 ----------------------------
4 files changed, 7 insertions(+), 59 deletions(-)

diff --git a/drivers/gpu/drm/i915/gvt/dmabuf.c b/drivers/gpu/drm/i915/gvt/dmabuf.c
index c95c25d2addbc..cc1a9ac0d2720 100644
--- a/drivers/gpu/drm/i915/gvt/dmabuf.c
+++ b/drivers/gpu/drm/i915/gvt/dmabuf.c
@@ -29,7 +29,7 @@
*/

#include <linux/dma-buf.h>
-#include <linux/vfio.h>
+#include <linux/mdev.h>

#include <drm/drm_fourcc.h>
#include <drm/drm_plane.h>
@@ -157,7 +157,7 @@ static void dmabuf_gem_object_free(struct kref *kref)
dmabuf_obj = list_entry(pos, struct intel_vgpu_dmabuf_obj, list);
if (dmabuf_obj == obj) {
list_del(pos);
- intel_gvt_hypervisor_put_vfio_device(vgpu);
+ vfio_device_put(vgpu->vfio_device);
idr_remove(&vgpu->object_idr,
dmabuf_obj->dmabuf_id);
kfree(dmabuf_obj->info);
@@ -492,9 +492,11 @@ int intel_vgpu_query_plane(struct intel_vgpu *vgpu, void *args)
kref_init(&dmabuf_obj->kref);

mutex_lock(&vgpu->dmabuf_lock);
- if (intel_gvt_hypervisor_get_vfio_device(vgpu)) {
- gvt_vgpu_err("get vfio device failed\n");
+ vgpu->vfio_device = vfio_device_get_from_dev(mdev_dev(vgpu->mdev));
+ if (!vgpu->vfio_device) {
+ gvt_vgpu_err("failed to get vfio device\n");
mutex_unlock(&vgpu->dmabuf_lock);
+ ret = -ENODEV;
goto out_free_info;
}
mutex_unlock(&vgpu->dmabuf_lock);
@@ -603,7 +605,7 @@ void intel_vgpu_dmabuf_cleanup(struct intel_vgpu *vgpu)
dmabuf_obj->vgpu = NULL;

idr_remove(&vgpu->object_idr, dmabuf_obj->dmabuf_id);
- intel_gvt_hypervisor_put_vfio_device(vgpu);
+ vfio_device_put(vgpu->vfio_device);
list_del(pos);

/* dmabuf_obj might be freed in dmabuf_obj_put */
diff --git a/drivers/gpu/drm/i915/gvt/hypercall.h b/drivers/gpu/drm/i915/gvt/hypercall.h
index 61e493e2de852..fd903d52f4314 100644
--- a/drivers/gpu/drm/i915/gvt/hypercall.h
+++ b/drivers/gpu/drm/i915/gvt/hypercall.h
@@ -60,8 +60,6 @@ struct intel_gvt_mpt {

int (*set_opregion)(struct intel_vgpu *vgpu);
int (*set_edid)(struct intel_vgpu *vgpu, int port_num);
- int (*get_vfio_device)(struct intel_vgpu *vgpu);
- void (*put_vfio_device)(struct intel_vgpu *vgpu);
bool (*is_valid_gfn)(struct intel_vgpu *vgpu, unsigned long gfn);
};

diff --git a/drivers/gpu/drm/i915/gvt/kvmgt.c b/drivers/gpu/drm/i915/gvt/kvmgt.c
index e4e3d0cc66fc8..1f70cbd51a3fa 100644
--- a/drivers/gpu/drm/i915/gvt/kvmgt.c
+++ b/drivers/gpu/drm/i915/gvt/kvmgt.c
@@ -662,18 +662,6 @@ static int intel_vgpu_register_reg(struct intel_vgpu *vgpu,
return 0;
}

-static int kvmgt_get_vfio_device(struct intel_vgpu *vgpu)
-{
- vgpu->vfio_device = vfio_device_get_from_dev(
- mdev_dev(vgpu->mdev));
- if (!vgpu->vfio_device) {
- gvt_vgpu_err("failed to get vfio device\n");
- return -ENODEV;
- }
- return 0;
-}
-
-
static int kvmgt_set_opregion(struct intel_vgpu *vgpu)
{
void *base;
@@ -730,14 +718,6 @@ static int kvmgt_set_edid(struct intel_vgpu *vgpu, int port_num)
return ret;
}

-static void kvmgt_put_vfio_device(struct intel_vgpu *vgpu)
-{
- if (WARN_ON(!vgpu->vfio_device))
- return;
-
- vfio_device_put(vgpu->vfio_device);
-}
-
static int intel_vgpu_create(struct mdev_device *mdev)
{
struct intel_vgpu *vgpu = NULL;
@@ -2052,8 +2032,6 @@ static const struct intel_gvt_mpt kvmgt_mpt = {
.dma_pin_guest_page = kvmgt_dma_pin_guest_page,
.set_opregion = kvmgt_set_opregion,
.set_edid = kvmgt_set_edid,
- .get_vfio_device = kvmgt_get_vfio_device,
- .put_vfio_device = kvmgt_put_vfio_device,
.is_valid_gfn = kvmgt_is_valid_gfn,
};

diff --git a/drivers/gpu/drm/i915/gvt/mpt.h b/drivers/gpu/drm/i915/gvt/mpt.h
index 72388ceec5966..2196187203af1 100644
--- a/drivers/gpu/drm/i915/gvt/mpt.h
+++ b/drivers/gpu/drm/i915/gvt/mpt.h
@@ -242,36 +242,6 @@ static inline int intel_gvt_hypervisor_set_edid(struct intel_vgpu *vgpu,
return intel_gvt_host.mpt->set_edid(vgpu, port_num);
}

-/**
- * intel_gvt_hypervisor_get_vfio_device - increase vfio device ref count
- * @vgpu: a vGPU
- *
- * Returns:
- * Zero on success, negative error code if failed.
- */
-static inline int intel_gvt_hypervisor_get_vfio_device(struct intel_vgpu *vgpu)
-{
- if (!intel_gvt_host.mpt->get_vfio_device)
- return 0;
-
- return intel_gvt_host.mpt->get_vfio_device(vgpu);
-}
-
-/**
- * intel_gvt_hypervisor_put_vfio_device - decrease vfio device ref count
- * @vgpu: a vGPU
- *
- * Returns:
- * Zero on success, negative error code if failed.
- */
-static inline void intel_gvt_hypervisor_put_vfio_device(struct intel_vgpu *vgpu)
-{
- if (!intel_gvt_host.mpt->put_vfio_device)
- return;
-
- intel_gvt_host.mpt->put_vfio_device(vgpu);
-}
-
/**
* intel_gvt_hypervisor_is_valid_gfn - check if a visible gfn
* @vgpu: a vGPU
--
2.30.2

2022-04-12 20:52:40

by Christoph Hellwig

[permalink] [raw]
Subject: [PATCH 01/34] drm/i915/gvt: remove module refcounting in intel_gvt_{,un}register_hypervisor

THIS_MODULE always is reference when a symbol called by it is used, so
don't bother with the additional reference.

Signed-off-by: Christoph Hellwig <[email protected]>
---
drivers/gpu/drm/i915/gvt/gvt.c | 6 ------
1 file changed, 6 deletions(-)

diff --git a/drivers/gpu/drm/i915/gvt/gvt.c b/drivers/gpu/drm/i915/gvt/gvt.c
index f0b69e4dcb525..623424766c359 100644
--- a/drivers/gpu/drm/i915/gvt/gvt.c
+++ b/drivers/gpu/drm/i915/gvt/gvt.c
@@ -308,10 +308,6 @@ intel_gvt_register_hypervisor(const struct intel_gvt_mpt *m)
m->type != INTEL_GVT_HYPERVISOR_XEN)
return -EINVAL;

- /* Get a reference for device model module */
- if (!try_module_get(THIS_MODULE))
- return -ENODEV;
-
intel_gvt_host.mpt = m;
intel_gvt_host.hypervisor_type = m->type;
gvt = (void *)kdev_to_i915(intel_gvt_host.dev)->gvt;
@@ -321,7 +317,6 @@ intel_gvt_register_hypervisor(const struct intel_gvt_mpt *m)
if (ret < 0) {
gvt_err("Failed to init %s hypervisor module\n",
supported_hypervisors[intel_gvt_host.hypervisor_type]);
- module_put(THIS_MODULE);
return -ENODEV;
}
gvt_dbg_core("Running with hypervisor %s in host mode\n",
@@ -335,6 +330,5 @@ intel_gvt_unregister_hypervisor(void)
{
void *gvt = (void *)kdev_to_i915(intel_gvt_host.dev)->gvt;
intel_gvt_hypervisor_host_exit(intel_gvt_host.dev, gvt);
- module_put(THIS_MODULE);
}
EXPORT_SYMBOL_GPL(intel_gvt_unregister_hypervisor);
--
2.30.2

2022-04-12 21:18:32

by Christoph Hellwig

[permalink] [raw]
Subject: [PATCH 30/34] vfio/mdev: Remove vfio_mdev.c

From: Jason Gunthorpe <[email protected]>

Now that all mdev drivers directly create their own mdev_device driver and
directly register with the vfio core's vfio_device_ops this is all dead
code.

Delete vfio_mdev.c and the mdev_parent_ops members that are connected to
it.

Signed-off-by: Jason Gunthorpe <[email protected]>
Signed-off-by: Christoph Hellwig <[email protected]>
---
.../driver-api/vfio-mediated-device.rst | 3 -
drivers/vfio/mdev/Makefile | 2 +-
drivers/vfio/mdev/mdev_core.c | 40 +----
drivers/vfio/mdev/mdev_driver.c | 10 --
drivers/vfio/mdev/mdev_private.h | 2 -
drivers/vfio/mdev/vfio_mdev.c | 152 ------------------
include/linux/mdev.h | 48 +-----
7 files changed, 6 insertions(+), 251 deletions(-)
delete mode 100644 drivers/vfio/mdev/vfio_mdev.c

diff --git a/Documentation/driver-api/vfio-mediated-device.rst b/Documentation/driver-api/vfio-mediated-device.rst
index 9f26079cacae3..5a6e18a651a18 100644
--- a/Documentation/driver-api/vfio-mediated-device.rst
+++ b/Documentation/driver-api/vfio-mediated-device.rst
@@ -138,9 +138,6 @@ The structures in the mdev_parent_ops structure are as follows:
* supported_config: attributes to define supported configurations
* device_driver: device driver to bind for mediated device instances

-The mdev_parent_ops also still has various functions pointers. Theses exist
-for historical reasons only and shall not be used for new drivers.
-
When a driver wants to add the GUID creation sysfs to an existing device it has
probe'd to then it should call::

diff --git a/drivers/vfio/mdev/Makefile b/drivers/vfio/mdev/Makefile
index ff9ecd8021250..7c236ba1b90eb 100644
--- a/drivers/vfio/mdev/Makefile
+++ b/drivers/vfio/mdev/Makefile
@@ -1,5 +1,5 @@
# SPDX-License-Identifier: GPL-2.0-only

-mdev-y := mdev_core.o mdev_sysfs.o mdev_driver.o vfio_mdev.o
+mdev-y := mdev_core.o mdev_sysfs.o mdev_driver.o

obj-$(CONFIG_VFIO_MDEV) += mdev.o
diff --git a/drivers/vfio/mdev/mdev_core.c b/drivers/vfio/mdev/mdev_core.c
index b314101237fe2..8b1e86b9e8bc0 100644
--- a/drivers/vfio/mdev/mdev_core.c
+++ b/drivers/vfio/mdev/mdev_core.c
@@ -89,17 +89,10 @@ void mdev_release_parent(struct kref *kref)
static void mdev_device_remove_common(struct mdev_device *mdev)
{
struct mdev_parent *parent = mdev->type->parent;
- int ret;

mdev_remove_sysfs_files(mdev);
device_del(&mdev->dev);
lockdep_assert_held(&parent->unreg_sem);
- if (parent->ops->remove) {
- ret = parent->ops->remove(mdev);
- if (ret)
- dev_err(&mdev->dev, "Remove failed: err=%d\n", ret);
- }
-
/* Balances with device_initialize() */
put_device(&mdev->dev);
}
@@ -131,7 +124,7 @@ int mdev_register_device(struct device *dev, const struct mdev_parent_ops *ops)
/* check for mandatory ops */
if (!ops || !ops->supported_type_groups)
return -EINVAL;
- if (!ops->device_driver && (!ops->create || !ops->remove))
+ if (!ops->device_driver)
return -EINVAL;

dev = get_device(dev);
@@ -297,18 +290,10 @@ int mdev_device_create(struct mdev_type *type, const guid_t *uuid)
goto out_put_device;
}

- if (parent->ops->create) {
- ret = parent->ops->create(mdev);
- if (ret)
- goto out_unlock;
- }
-
ret = device_add(&mdev->dev);
if (ret)
- goto out_remove;
+ goto out_unlock;

- if (!drv)
- drv = &vfio_mdev_driver;
ret = device_driver_attach(&drv->driver, &mdev->dev);
if (ret)
goto out_del;
@@ -325,9 +310,6 @@ int mdev_device_create(struct mdev_type *type, const guid_t *uuid)

out_del:
device_del(&mdev->dev);
-out_remove:
- if (parent->ops->remove)
- parent->ops->remove(mdev);
out_unlock:
up_read(&parent->unreg_sem);
out_put_device:
@@ -370,28 +352,14 @@ int mdev_device_remove(struct mdev_device *mdev)

static int __init mdev_init(void)
{
- int rc;
-
- rc = mdev_bus_register();
- if (rc)
- return rc;
- rc = mdev_register_driver(&vfio_mdev_driver);
- if (rc)
- goto err_bus;
- return 0;
-err_bus:
- mdev_bus_unregister();
- return rc;
+ return bus_register(&mdev_bus_type);
}

static void __exit mdev_exit(void)
{
- mdev_unregister_driver(&vfio_mdev_driver);
-
if (mdev_bus_compat_class)
class_compat_unregister(mdev_bus_compat_class);
-
- mdev_bus_unregister();
+ bus_unregister(&mdev_bus_type);
}

subsys_initcall(mdev_init)
diff --git a/drivers/vfio/mdev/mdev_driver.c b/drivers/vfio/mdev/mdev_driver.c
index 7927ed4f1711f..9c2af59809e2e 100644
--- a/drivers/vfio/mdev/mdev_driver.c
+++ b/drivers/vfio/mdev/mdev_driver.c
@@ -74,13 +74,3 @@ void mdev_unregister_driver(struct mdev_driver *drv)
driver_unregister(&drv->driver);
}
EXPORT_SYMBOL(mdev_unregister_driver);
-
-int mdev_bus_register(void)
-{
- return bus_register(&mdev_bus_type);
-}
-
-void mdev_bus_unregister(void)
-{
- bus_unregister(&mdev_bus_type);
-}
diff --git a/drivers/vfio/mdev/mdev_private.h b/drivers/vfio/mdev/mdev_private.h
index afbad7b0a14a1..6999c89db7b16 100644
--- a/drivers/vfio/mdev/mdev_private.h
+++ b/drivers/vfio/mdev/mdev_private.h
@@ -37,8 +37,6 @@ struct mdev_type {
#define to_mdev_type(_kobj) \
container_of(_kobj, struct mdev_type, kobj)

-extern struct mdev_driver vfio_mdev_driver;
-
int parent_create_sysfs_files(struct mdev_parent *parent);
void parent_remove_sysfs_files(struct mdev_parent *parent);

diff --git a/drivers/vfio/mdev/vfio_mdev.c b/drivers/vfio/mdev/vfio_mdev.c
deleted file mode 100644
index a90e24b0c851d..0000000000000
--- a/drivers/vfio/mdev/vfio_mdev.c
+++ /dev/null
@@ -1,152 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * VFIO based driver for Mediated device
- *
- * Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved.
- * Author: Neo Jia <[email protected]>
- * Kirti Wankhede <[email protected]>
- */
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/device.h>
-#include <linux/kernel.h>
-#include <linux/slab.h>
-#include <linux/vfio.h>
-#include <linux/mdev.h>
-
-#include "mdev_private.h"
-
-static int vfio_mdev_open_device(struct vfio_device *core_vdev)
-{
- struct mdev_device *mdev = to_mdev_device(core_vdev->dev);
- struct mdev_parent *parent = mdev->type->parent;
-
- if (unlikely(!parent->ops->open_device))
- return 0;
-
- return parent->ops->open_device(mdev);
-}
-
-static void vfio_mdev_close_device(struct vfio_device *core_vdev)
-{
- struct mdev_device *mdev = to_mdev_device(core_vdev->dev);
- struct mdev_parent *parent = mdev->type->parent;
-
- if (likely(parent->ops->close_device))
- parent->ops->close_device(mdev);
-}
-
-static long vfio_mdev_unlocked_ioctl(struct vfio_device *core_vdev,
- unsigned int cmd, unsigned long arg)
-{
- struct mdev_device *mdev = to_mdev_device(core_vdev->dev);
- struct mdev_parent *parent = mdev->type->parent;
-
- if (unlikely(!parent->ops->ioctl))
- return 0;
-
- return parent->ops->ioctl(mdev, cmd, arg);
-}
-
-static ssize_t vfio_mdev_read(struct vfio_device *core_vdev, char __user *buf,
- size_t count, loff_t *ppos)
-{
- struct mdev_device *mdev = to_mdev_device(core_vdev->dev);
- struct mdev_parent *parent = mdev->type->parent;
-
- if (unlikely(!parent->ops->read))
- return -EINVAL;
-
- return parent->ops->read(mdev, buf, count, ppos);
-}
-
-static ssize_t vfio_mdev_write(struct vfio_device *core_vdev,
- const char __user *buf, size_t count,
- loff_t *ppos)
-{
- struct mdev_device *mdev = to_mdev_device(core_vdev->dev);
- struct mdev_parent *parent = mdev->type->parent;
-
- if (unlikely(!parent->ops->write))
- return -EINVAL;
-
- return parent->ops->write(mdev, buf, count, ppos);
-}
-
-static int vfio_mdev_mmap(struct vfio_device *core_vdev,
- struct vm_area_struct *vma)
-{
- struct mdev_device *mdev = to_mdev_device(core_vdev->dev);
- struct mdev_parent *parent = mdev->type->parent;
-
- if (unlikely(!parent->ops->mmap))
- return -EINVAL;
-
- return parent->ops->mmap(mdev, vma);
-}
-
-static void vfio_mdev_request(struct vfio_device *core_vdev, unsigned int count)
-{
- struct mdev_device *mdev = to_mdev_device(core_vdev->dev);
- struct mdev_parent *parent = mdev->type->parent;
-
- if (parent->ops->request)
- parent->ops->request(mdev, count);
- else if (count == 0)
- dev_notice(mdev_dev(mdev),
- "No mdev vendor driver request callback support, blocked until released by user\n");
-}
-
-static const struct vfio_device_ops vfio_mdev_dev_ops = {
- .name = "vfio-mdev",
- .open_device = vfio_mdev_open_device,
- .close_device = vfio_mdev_close_device,
- .ioctl = vfio_mdev_unlocked_ioctl,
- .read = vfio_mdev_read,
- .write = vfio_mdev_write,
- .mmap = vfio_mdev_mmap,
- .request = vfio_mdev_request,
-};
-
-static int vfio_mdev_probe(struct mdev_device *mdev)
-{
- struct vfio_device *vdev;
- int ret;
-
- vdev = kzalloc(sizeof(*vdev), GFP_KERNEL);
- if (!vdev)
- return -ENOMEM;
-
- vfio_init_group_dev(vdev, &mdev->dev, &vfio_mdev_dev_ops);
- ret = vfio_register_emulated_iommu_dev(vdev);
- if (ret)
- goto out_uninit;
-
- dev_set_drvdata(&mdev->dev, vdev);
- return 0;
-
-out_uninit:
- vfio_uninit_group_dev(vdev);
- kfree(vdev);
- return ret;
-}
-
-static void vfio_mdev_remove(struct mdev_device *mdev)
-{
- struct vfio_device *vdev = dev_get_drvdata(&mdev->dev);
-
- vfio_unregister_group_dev(vdev);
- vfio_uninit_group_dev(vdev);
- kfree(vdev);
-}
-
-struct mdev_driver vfio_mdev_driver = {
- .driver = {
- .name = "vfio_mdev",
- .owner = THIS_MODULE,
- .mod_name = KBUILD_MODNAME,
- },
- .probe = vfio_mdev_probe,
- .remove = vfio_mdev_remove,
-};
diff --git a/include/linux/mdev.h b/include/linux/mdev.h
index 15d03f6532d07..192aed656116f 100644
--- a/include/linux/mdev.h
+++ b/include/linux/mdev.h
@@ -40,40 +40,7 @@ struct device *mtype_get_parent_dev(struct mdev_type *mtype);
* @mdev_attr_groups: Attributes of the mediated device.
* @supported_type_groups: Attributes to define supported types. It is mandatory
* to provide supported types.
- * @create: Called to allocate basic resources in parent device's
- * driver for a particular mediated device. It is
- * mandatory to provide create ops.
- * @mdev: mdev_device structure on of mediated device
- * that is being created
- * Returns integer: success (0) or error (< 0)
- * @remove: Called to free resources in parent device's driver for
- * a mediated device. It is mandatory to provide 'remove'
- * ops.
- * @mdev: mdev_device device structure which is being
- * destroyed
- * Returns integer: success (0) or error (< 0)
- * @read: Read emulation callback
- * @mdev: mediated device structure
- * @buf: read buffer
- * @count: number of bytes to read
- * @ppos: address.
- * Retuns number on bytes read on success or error.
- * @write: Write emulation callback
- * @mdev: mediated device structure
- * @buf: write buffer
- * @count: number of bytes to be written
- * @ppos: address.
- * Retuns number on bytes written on success or error.
- * @ioctl: IOCTL callback
- * @mdev: mediated device structure
- * @cmd: ioctl command
- * @arg: arguments to ioctl
- * @mmap: mmap callback
- * @mdev: mediated device structure
- * @vma: vma structure
- * @request: request callback to release device
- * @mdev: mediated device structure
- * @count: request sequence number
+ *
* Parent device that support mediated device should be registered with mdev
* module with mdev_parent_ops structure.
**/
@@ -83,19 +50,6 @@ struct mdev_parent_ops {
const struct attribute_group **dev_attr_groups;
const struct attribute_group **mdev_attr_groups;
struct attribute_group **supported_type_groups;
-
- int (*create)(struct mdev_device *mdev);
- int (*remove)(struct mdev_device *mdev);
- int (*open_device)(struct mdev_device *mdev);
- void (*close_device)(struct mdev_device *mdev);
- ssize_t (*read)(struct mdev_device *mdev, char __user *buf,
- size_t count, loff_t *ppos);
- ssize_t (*write)(struct mdev_device *mdev, const char __user *buf,
- size_t count, loff_t *ppos);
- long (*ioctl)(struct mdev_device *mdev, unsigned int cmd,
- unsigned long arg);
- int (*mmap)(struct mdev_device *mdev, struct vm_area_struct *vma);
- void (*request)(struct mdev_device *mdev, unsigned int count);
};

/* interface for exporting mdev supported type attributes */
--
2.30.2

2022-04-12 21:44:30

by Christoph Hellwig

[permalink] [raw]
Subject: [PATCH 03/34] drm/i915/gvt: rename intel_vgpu_ops to intel_vgpu_mdev_ops

Free the intel_vgpu_ops symbol name for something that fits better.

Signed-off-by: Christoph Hellwig <[email protected]>
---
drivers/gpu/drm/i915/gvt/kvmgt.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/gvt/kvmgt.c b/drivers/gpu/drm/i915/gvt/kvmgt.c
index 5231ce8084b36..e3f0c555ed5f6 100644
--- a/drivers/gpu/drm/i915/gvt/kvmgt.c
+++ b/drivers/gpu/drm/i915/gvt/kvmgt.c
@@ -1765,7 +1765,7 @@ static const struct attribute_group *intel_vgpu_groups[] = {
NULL,
};

-static struct mdev_parent_ops intel_vgpu_ops = {
+static struct mdev_parent_ops intel_vgpu_mdev_ops = {
.mdev_attr_groups = intel_vgpu_groups,
.create = intel_vgpu_create,
.remove = intel_vgpu_remove,
@@ -1788,9 +1788,9 @@ static int kvmgt_host_init(struct device *dev, void *gvt, const void *ops)
return ret;

intel_gvt_ops = ops;
- intel_vgpu_ops.supported_type_groups = gvt_vgpu_type_groups;
+ intel_vgpu_mdev_ops.supported_type_groups = gvt_vgpu_type_groups;

- ret = mdev_register_device(dev, &intel_vgpu_ops);
+ ret = mdev_register_device(dev, &intel_vgpu_mdev_ops);
if (ret)
intel_gvt_cleanup_vgpu_type_groups((struct intel_gvt *)gvt);

--
2.30.2

2022-04-12 21:45:42

by Jason Gunthorpe

[permalink] [raw]
Subject: Re: [PATCH 22/34] drm/i915/gvt: devirtualize dma_pin_guest_page

On Mon, Apr 11, 2022 at 04:13:51PM +0200, Christoph Hellwig wrote:
> Just call the function directly and remove a pointless wrapper.
>
> Signed-off-by: Christoph Hellwig <[email protected]>
> ---
> drivers/gpu/drm/i915/gvt/dmabuf.c | 14 +-------------
> drivers/gpu/drm/i915/gvt/gvt.h | 1 +
> drivers/gpu/drm/i915/gvt/hypercall.h | 2 --
> drivers/gpu/drm/i915/gvt/kvmgt.c | 4 +---
> drivers/gpu/drm/i915/gvt/mpt.h | 15 ---------------
> 5 files changed, 3 insertions(+), 33 deletions(-)

Reviewed-by: Jason Gunthorpe <[email protected]>

Jason

2022-04-12 21:49:00

by Christoph Hellwig

[permalink] [raw]
Subject: [PATCH 28/34] drm/i915/gvt: convert to use vfio_register_emulated_iommu_dev

This is straightforward conversion, the intel_vgpu already has a pointer
to the vfio_dev, which can be replaced with the embedded structure and
we can replace all the mdev_get_drvdata() with a simple container_of().

Based on an patch from Jason Gunthorpe.

Signed-off-by: Christoph Hellwig <[email protected]>
---
drivers/gpu/drm/i915/gvt/gvt.h | 2 +-
drivers/gpu/drm/i915/gvt/kvmgt.c | 190 ++++++++++++++++---------------
2 files changed, 102 insertions(+), 90 deletions(-)

diff --git a/drivers/gpu/drm/i915/gvt/gvt.h b/drivers/gpu/drm/i915/gvt/gvt.h
index 8565189e0c0dd..c32e8eb199f10 100644
--- a/drivers/gpu/drm/i915/gvt/gvt.h
+++ b/drivers/gpu/drm/i915/gvt/gvt.h
@@ -211,7 +211,7 @@ struct intel_vgpu {

u32 scan_nonprivbb;

- struct mdev_device *mdev;
+ struct vfio_device vfio_device;
struct vfio_region *region;
int num_regions;
struct eventfd_ctx *intx_trigger;
diff --git a/drivers/gpu/drm/i915/gvt/kvmgt.c b/drivers/gpu/drm/i915/gvt/kvmgt.c
index 38629ab4c9bf2..4113f850bf92d 100644
--- a/drivers/gpu/drm/i915/gvt/kvmgt.c
+++ b/drivers/gpu/drm/i915/gvt/kvmgt.c
@@ -100,6 +100,9 @@ struct gvt_dma {
struct kref ref;
};

+#define vfio_dev_to_vgpu(vfio_dev) \
+ container_of((vfio_dev), struct intel_vgpu, vfio_device)
+
static void kvmgt_page_track_write(struct kvm_vcpu *vcpu, gpa_t gpa,
const u8 *val, int len,
struct kvm_page_track_notifier_node *node);
@@ -723,44 +726,6 @@ int intel_gvt_set_edid(struct intel_vgpu *vgpu, int port_num)
return ret;
}

-static int intel_vgpu_create(struct mdev_device *mdev)
-{
- struct device *pdev = mdev_parent_dev(mdev);
- struct intel_gvt *gvt = kdev_to_i915(pdev)->gvt;
- struct intel_vgpu_type *type;
- struct intel_vgpu *vgpu;
-
- type = &gvt->types[mdev_get_type_group_id(mdev)];
- if (!type)
- return -EINVAL;
-
- vgpu = intel_gvt_create_vgpu(gvt, type);
- if (IS_ERR(vgpu)) {
- gvt_err("failed to create intel vgpu: %ld\n", PTR_ERR(vgpu));
- return PTR_ERR(vgpu);
- }
-
- INIT_WORK(&vgpu->release_work, intel_vgpu_release_work);
-
- vgpu->mdev = mdev;
- mdev_set_drvdata(mdev, vgpu);
-
- gvt_dbg_core("intel_vgpu_create succeeded for mdev: %s\n",
- dev_name(mdev_dev(mdev)));
- return 0;
-}
-
-static int intel_vgpu_remove(struct mdev_device *mdev)
-{
- struct intel_vgpu *vgpu = mdev_get_drvdata(mdev);
-
- if (vgpu->attached)
- return -EBUSY;
-
- intel_gvt_destroy_vgpu(vgpu);
- return 0;
-}
-
static int intel_vgpu_iommu_notifier(struct notifier_block *nb,
unsigned long action, void *data)
{
@@ -829,9 +794,9 @@ static bool __kvmgt_vgpu_exist(struct intel_vgpu *vgpu)
return ret;
}

-static int intel_vgpu_open_device(struct mdev_device *mdev)
+static int intel_vgpu_open_device(struct vfio_device *vfio_dev)
{
- struct intel_vgpu *vgpu = mdev_get_drvdata(mdev);
+ struct intel_vgpu *vgpu = vfio_dev_to_vgpu(vfio_dev);
unsigned long events;
int ret;
struct vfio_group *vfio_group;
@@ -840,7 +805,7 @@ static int intel_vgpu_open_device(struct mdev_device *mdev)
vgpu->group_notifier.notifier_call = intel_vgpu_group_notifier;

events = VFIO_IOMMU_NOTIFY_DMA_UNMAP;
- ret = vfio_register_notifier(mdev_dev(mdev), VFIO_IOMMU_NOTIFY, &events,
+ ret = vfio_register_notifier(vfio_dev->dev, VFIO_IOMMU_NOTIFY, &events,
&vgpu->iommu_notifier);
if (ret != 0) {
gvt_vgpu_err("vfio_register_notifier for iommu failed: %d\n",
@@ -849,7 +814,7 @@ static int intel_vgpu_open_device(struct mdev_device *mdev)
}

events = VFIO_GROUP_NOTIFY_SET_KVM;
- ret = vfio_register_notifier(mdev_dev(mdev), VFIO_GROUP_NOTIFY, &events,
+ ret = vfio_register_notifier(vfio_dev->dev, VFIO_GROUP_NOTIFY, &events,
&vgpu->group_notifier);
if (ret != 0) {
gvt_vgpu_err("vfio_register_notifier for group failed: %d\n",
@@ -857,7 +822,8 @@ static int intel_vgpu_open_device(struct mdev_device *mdev)
goto undo_iommu;
}

- vfio_group = vfio_group_get_external_user_from_dev(mdev_dev(mdev));
+ vfio_group =
+ vfio_group_get_external_user_from_dev(vgpu->vfio_device.dev);
if (IS_ERR_OR_NULL(vfio_group)) {
ret = !vfio_group ? -EFAULT : PTR_ERR(vfio_group);
gvt_vgpu_err("vfio_group_get_external_user_from_dev failed\n");
@@ -865,14 +831,6 @@ static int intel_vgpu_open_device(struct mdev_device *mdev)
}
vgpu->vfio_group = vfio_group;

- /* Take a module reference as mdev core doesn't take
- * a reference for vendor driver.
- */
- if (!try_module_get(THIS_MODULE)) {
- ret = -ENODEV;
- goto undo_group;
- }
-
ret = -EEXIST;
if (vgpu->attached)
goto undo_group;
@@ -910,11 +868,11 @@ static int intel_vgpu_open_device(struct mdev_device *mdev)
vgpu->vfio_group = NULL;

undo_register:
- vfio_unregister_notifier(mdev_dev(mdev), VFIO_GROUP_NOTIFY,
+ vfio_unregister_notifier(vfio_dev->dev, VFIO_GROUP_NOTIFY,
&vgpu->group_notifier);

undo_iommu:
- vfio_unregister_notifier(mdev_dev(mdev), VFIO_IOMMU_NOTIFY,
+ vfio_unregister_notifier(vfio_dev->dev, VFIO_IOMMU_NOTIFY,
&vgpu->iommu_notifier);
out:
return ret;
@@ -944,19 +902,16 @@ static void __intel_vgpu_release(struct intel_vgpu *vgpu)

intel_gvt_release_vgpu(vgpu);

- ret = vfio_unregister_notifier(mdev_dev(vgpu->mdev), VFIO_IOMMU_NOTIFY,
+ ret = vfio_unregister_notifier(vgpu->vfio_device.dev, VFIO_IOMMU_NOTIFY,
&vgpu->iommu_notifier);
drm_WARN(&i915->drm, ret,
"vfio_unregister_notifier for iommu failed: %d\n", ret);

- ret = vfio_unregister_notifier(mdev_dev(vgpu->mdev), VFIO_GROUP_NOTIFY,
+ ret = vfio_unregister_notifier(vgpu->vfio_device.dev, VFIO_GROUP_NOTIFY,
&vgpu->group_notifier);
drm_WARN(&i915->drm, ret,
"vfio_unregister_notifier for group failed: %d\n", ret);

- /* dereference module reference taken at open */
- module_put(THIS_MODULE);
-
debugfs_remove(debugfs_lookup(KVMGT_DEBUGFS_FILENAME, vgpu->debugfs));

kvm_page_track_unregister_notifier(vgpu->kvm, &vgpu->track_node);
@@ -971,11 +926,9 @@ static void __intel_vgpu_release(struct intel_vgpu *vgpu)
vgpu->attached = false;
}

-static void intel_vgpu_close_device(struct mdev_device *mdev)
+static void intel_vgpu_close_device(struct vfio_device *vfio_dev)
{
- struct intel_vgpu *vgpu = mdev_get_drvdata(mdev);
-
- __intel_vgpu_release(vgpu);
+ __intel_vgpu_release(vfio_dev_to_vgpu(vfio_dev));
}

static void intel_vgpu_release_work(struct work_struct *work)
@@ -1127,10 +1080,10 @@ static bool gtt_entry(struct intel_vgpu *vgpu, loff_t *ppos)
true : false;
}

-static ssize_t intel_vgpu_read(struct mdev_device *mdev, char __user *buf,
+static ssize_t intel_vgpu_read(struct vfio_device *vfio_dev, char __user *buf,
size_t count, loff_t *ppos)
{
- struct intel_vgpu *vgpu = mdev_get_drvdata(mdev);
+ struct intel_vgpu *vgpu = vfio_dev_to_vgpu(vfio_dev);
unsigned int done = 0;
int ret;

@@ -1201,11 +1154,11 @@ static ssize_t intel_vgpu_read(struct mdev_device *mdev, char __user *buf,
return -EFAULT;
}

-static ssize_t intel_vgpu_write(struct mdev_device *mdev,
+static ssize_t intel_vgpu_write(struct vfio_device *vfio_dev,
const char __user *buf,
size_t count, loff_t *ppos)
{
- struct intel_vgpu *vgpu = mdev_get_drvdata(mdev);
+ struct intel_vgpu *vgpu = vfio_dev_to_vgpu(vfio_dev);
unsigned int done = 0;
int ret;

@@ -1275,13 +1228,14 @@ static ssize_t intel_vgpu_write(struct mdev_device *mdev,
return -EFAULT;
}

-static int intel_vgpu_mmap(struct mdev_device *mdev, struct vm_area_struct *vma)
+static int intel_vgpu_mmap(struct vfio_device *vfio_dev,
+ struct vm_area_struct *vma)
{
+ struct intel_vgpu *vgpu = vfio_dev_to_vgpu(vfio_dev);
unsigned int index;
u64 virtaddr;
unsigned long req_size, pgoff, req_start;
pgprot_t pg_prot;
- struct intel_vgpu *vgpu = mdev_get_drvdata(mdev);

index = vma->vm_pgoff >> (VFIO_PCI_OFFSET_SHIFT - PAGE_SHIFT);
if (index >= VFIO_PCI_ROM_REGION_INDEX)
@@ -1404,10 +1358,10 @@ static int intel_vgpu_set_irqs(struct intel_vgpu *vgpu, u32 flags,
return func(vgpu, index, start, count, flags, data);
}

-static long intel_vgpu_ioctl(struct mdev_device *mdev, unsigned int cmd,
+static long intel_vgpu_ioctl(struct vfio_device *vfio_dev, unsigned int cmd,
unsigned long arg)
{
- struct intel_vgpu *vgpu = mdev_get_drvdata(mdev);
+ struct intel_vgpu *vgpu = vfio_dev_to_vgpu(vfio_dev);
unsigned long minsz;

gvt_dbg_core("vgpu%d ioctl, cmd: %d\n", vgpu->id, cmd);
@@ -1682,14 +1636,9 @@ static ssize_t
vgpu_id_show(struct device *dev, struct device_attribute *attr,
char *buf)
{
- struct mdev_device *mdev = mdev_from_dev(dev);
+ struct intel_vgpu *vgpu = dev_get_drvdata(dev);

- if (mdev) {
- struct intel_vgpu *vgpu = (struct intel_vgpu *)
- mdev_get_drvdata(mdev);
- return sprintf(buf, "%d\n", vgpu->id);
- }
- return sprintf(buf, "\n");
+ return sprintf(buf, "%d\n", vgpu->id);
}

static DEVICE_ATTR_RO(vgpu_id);
@@ -1709,19 +1658,72 @@ static const struct attribute_group *intel_vgpu_groups[] = {
NULL,
};

-const struct mdev_parent_ops intel_vgpu_mdev_ops = {
- .mdev_attr_groups = intel_vgpu_groups,
- .supported_type_groups = gvt_vgpu_type_groups,
- .create = intel_vgpu_create,
- .remove = intel_vgpu_remove,
+static const struct vfio_device_ops intel_vgpu_dev_ops = {
+ .open_device = intel_vgpu_open_device,
+ .close_device = intel_vgpu_close_device,
+ .read = intel_vgpu_read,
+ .write = intel_vgpu_write,
+ .mmap = intel_vgpu_mmap,
+ .ioctl = intel_vgpu_ioctl,
+};

- .open_device = intel_vgpu_open_device,
- .close_device = intel_vgpu_close_device,
+static int intel_vgpu_probe(struct mdev_device *mdev)
+{
+ struct device *pdev = mdev_parent_dev(mdev);
+ struct intel_gvt *gvt = kdev_to_i915(pdev)->gvt;
+ struct intel_vgpu_type *type;
+ struct intel_vgpu *vgpu;
+ int ret;
+
+ type = &gvt->types[mdev_get_type_group_id(mdev)];
+ if (!type)
+ return -EINVAL;
+
+ vgpu = intel_gvt_create_vgpu(gvt, type);
+ if (IS_ERR(vgpu)) {
+ gvt_err("failed to create intel vgpu: %ld\n", PTR_ERR(vgpu));
+ return PTR_ERR(vgpu);
+ }

- .read = intel_vgpu_read,
- .write = intel_vgpu_write,
- .mmap = intel_vgpu_mmap,
- .ioctl = intel_vgpu_ioctl,
+ INIT_WORK(&vgpu->release_work, intel_vgpu_release_work);
+ vfio_init_group_dev(&vgpu->vfio_device, &mdev->dev,
+ &intel_vgpu_dev_ops);
+
+ dev_set_drvdata(&mdev->dev, vgpu);
+ ret = vfio_register_emulated_iommu_dev(&vgpu->vfio_device);
+ if (ret) {
+ intel_gvt_destroy_vgpu(vgpu);
+ return ret;
+ }
+
+ gvt_dbg_core("intel_vgpu_create succeeded for mdev: %s\n",
+ dev_name(mdev_dev(mdev)));
+ return 0;
+}
+
+static void intel_vgpu_remove(struct mdev_device *mdev)
+{
+ struct intel_vgpu *vgpu = dev_get_drvdata(&mdev->dev);
+
+ if (WARN_ON_ONCE(vgpu->attached))
+ return;
+ intel_gvt_destroy_vgpu(vgpu);
+}
+
+static struct mdev_driver intel_vgpu_mdev_driver = {
+ .driver = {
+ .name = "intel_vgpu_mdev",
+ .owner = THIS_MODULE,
+ .dev_groups = intel_vgpu_groups,
+ },
+ .probe = intel_vgpu_probe,
+ .remove = intel_vgpu_remove,
+};
+
+const struct mdev_parent_ops intel_vgpu_mdev_ops = {
+ .owner = THIS_MODULE,
+ .supported_type_groups = gvt_vgpu_type_groups,
+ .device_driver = &intel_vgpu_mdev_driver,
};

int intel_gvt_page_track_add(struct intel_vgpu *info, u64 gfn)
@@ -1925,11 +1927,21 @@ void intel_gvt_dma_unmap_guest_page(struct intel_vgpu *vgpu,

static int __init kvmgt_init(void)
{
- return intel_gvt_set_ops(&intel_gvt_vgpu_ops);
+ int ret;
+
+ ret = intel_gvt_set_ops(&intel_gvt_vgpu_ops);
+ if (ret)
+ return ret;
+
+ ret = mdev_register_driver(&intel_vgpu_mdev_driver);
+ if (ret)
+ intel_gvt_clear_ops(&intel_gvt_vgpu_ops);
+ return ret;
}

static void __exit kvmgt_exit(void)
{
+ mdev_unregister_driver(&intel_vgpu_mdev_driver);
intel_gvt_clear_ops(&intel_gvt_vgpu_ops);
}

--
2.30.2

2022-04-12 22:03:13

by Christoph Hellwig

[permalink] [raw]
Subject: [PATCH 29/34] drm/i915/gvt: merge gvt.c into kvmgvt.c

The code in both files is deeply interconnected, so merge it and
keep a bunch of structures and functions static.

Signed-off-by: Christoph Hellwig <[email protected]>
---
drivers/gpu/drm/i915/gvt/Makefile | 1 -
drivers/gpu/drm/i915/gvt/gvt.c | 291 ------------------------------
drivers/gpu/drm/i915/gvt/gvt.h | 6 -
drivers/gpu/drm/i915/gvt/kvmgt.c | 264 ++++++++++++++++++++++++++-
4 files changed, 260 insertions(+), 302 deletions(-)
delete mode 100644 drivers/gpu/drm/i915/gvt/gvt.c

diff --git a/drivers/gpu/drm/i915/gvt/Makefile b/drivers/gpu/drm/i915/gvt/Makefile
index cecedd9830f7c..2b08192930c18 100644
--- a/drivers/gpu/drm/i915/gvt/Makefile
+++ b/drivers/gpu/drm/i915/gvt/Makefile
@@ -1,7 +1,6 @@
# SPDX-License-Identifier: GPL-2.0

kvmgt-y += \
- gvt/gvt.o \
gvt/aperture_gm.o \
gvt/handlers.o \
gvt/vgpu.o \
diff --git a/drivers/gpu/drm/i915/gvt/gvt.c b/drivers/gpu/drm/i915/gvt/gvt.c
deleted file mode 100644
index 047fb6c41788b..0000000000000
--- a/drivers/gpu/drm/i915/gvt/gvt.c
+++ /dev/null
@@ -1,291 +0,0 @@
-/*
- * Copyright(c) 2011-2016 Intel Corporation. All rights reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Authors:
- * Kevin Tian <[email protected]>
- * Eddie Dong <[email protected]>
- *
- * Contributors:
- * Niu Bing <[email protected]>
- * Zhi Wang <[email protected]>
- *
- */
-
-#include <linux/types.h>
-#include <linux/kthread.h>
-
-#include "i915_drv.h"
-#include "intel_gvt.h"
-#include "gvt.h"
-#include <linux/vfio.h>
-#include <linux/mdev.h>
-
-static void init_device_info(struct intel_gvt *gvt)
-{
- struct intel_gvt_device_info *info = &gvt->device_info;
- struct pci_dev *pdev = to_pci_dev(gvt->gt->i915->drm.dev);
-
- info->max_support_vgpus = 8;
- info->cfg_space_size = PCI_CFG_SPACE_EXP_SIZE;
- info->mmio_size = 2 * 1024 * 1024;
- info->mmio_bar = 0;
- info->gtt_start_offset = 8 * 1024 * 1024;
- info->gtt_entry_size = 8;
- info->gtt_entry_size_shift = 3;
- info->gmadr_bytes_in_cmd = 8;
- info->max_surface_size = 36 * 1024 * 1024;
- info->msi_cap_offset = pdev->msi_cap;
-}
-
-static void intel_gvt_test_and_emulate_vblank(struct intel_gvt *gvt)
-{
- struct intel_vgpu *vgpu;
- int id;
-
- mutex_lock(&gvt->lock);
- idr_for_each_entry((&(gvt)->vgpu_idr), (vgpu), (id)) {
- if (test_and_clear_bit(INTEL_GVT_REQUEST_EMULATE_VBLANK + id,
- (void *)&gvt->service_request)) {
- if (vgpu->active)
- intel_vgpu_emulate_vblank(vgpu);
- }
- }
- mutex_unlock(&gvt->lock);
-}
-
-static int gvt_service_thread(void *data)
-{
- struct intel_gvt *gvt = (struct intel_gvt *)data;
- int ret;
-
- gvt_dbg_core("service thread start\n");
-
- while (!kthread_should_stop()) {
- ret = wait_event_interruptible(gvt->service_thread_wq,
- kthread_should_stop() || gvt->service_request);
-
- if (kthread_should_stop())
- break;
-
- if (WARN_ONCE(ret, "service thread is waken up by signal.\n"))
- continue;
-
- intel_gvt_test_and_emulate_vblank(gvt);
-
- if (test_bit(INTEL_GVT_REQUEST_SCHED,
- (void *)&gvt->service_request) ||
- test_bit(INTEL_GVT_REQUEST_EVENT_SCHED,
- (void *)&gvt->service_request)) {
- intel_gvt_schedule(gvt);
- }
- }
-
- return 0;
-}
-
-static void clean_service_thread(struct intel_gvt *gvt)
-{
- kthread_stop(gvt->service_thread);
-}
-
-static int init_service_thread(struct intel_gvt *gvt)
-{
- init_waitqueue_head(&gvt->service_thread_wq);
-
- gvt->service_thread = kthread_run(gvt_service_thread,
- gvt, "gvt_service_thread");
- if (IS_ERR(gvt->service_thread)) {
- gvt_err("fail to start service thread.\n");
- return PTR_ERR(gvt->service_thread);
- }
- return 0;
-}
-
-/**
- * intel_gvt_clean_device - clean a GVT device
- * @i915: i915 private
- *
- * This function is called at the driver unloading stage, to free the
- * resources owned by a GVT device.
- *
- */
-static void intel_gvt_clean_device(struct drm_i915_private *i915)
-{
- struct intel_gvt *gvt = fetch_and_zero(&i915->gvt);
-
- if (drm_WARN_ON(&i915->drm, !gvt))
- return;
-
- mdev_unregister_device(i915->drm.dev);
- intel_gvt_cleanup_vgpu_type_groups(gvt);
- intel_gvt_destroy_idle_vgpu(gvt->idle_vgpu);
- intel_gvt_clean_vgpu_types(gvt);
-
- intel_gvt_debugfs_clean(gvt);
- clean_service_thread(gvt);
- intel_gvt_clean_cmd_parser(gvt);
- intel_gvt_clean_sched_policy(gvt);
- intel_gvt_clean_workload_scheduler(gvt);
- intel_gvt_clean_gtt(gvt);
- intel_gvt_free_firmware(gvt);
- intel_gvt_clean_mmio_info(gvt);
- idr_destroy(&gvt->vgpu_idr);
-
- kfree(i915->gvt);
-}
-
-/**
- * intel_gvt_init_device - initialize a GVT device
- * @i915: drm i915 private data
- *
- * This function is called at the initialization stage, to initialize
- * necessary GVT components.
- *
- * Returns:
- * Zero on success, negative error code if failed.
- *
- */
-static int intel_gvt_init_device(struct drm_i915_private *i915)
-{
- struct intel_gvt *gvt;
- struct intel_vgpu *vgpu;
- int ret;
-
- if (drm_WARN_ON(&i915->drm, i915->gvt))
- return -EEXIST;
-
- gvt = kzalloc(sizeof(struct intel_gvt), GFP_KERNEL);
- if (!gvt)
- return -ENOMEM;
-
- gvt_dbg_core("init gvt device\n");
-
- idr_init_base(&gvt->vgpu_idr, 1);
- spin_lock_init(&gvt->scheduler.mmio_context_lock);
- mutex_init(&gvt->lock);
- mutex_init(&gvt->sched_lock);
- gvt->gt = to_gt(i915);
- i915->gvt = gvt;
-
- init_device_info(gvt);
-
- ret = intel_gvt_setup_mmio_info(gvt);
- if (ret)
- goto out_clean_idr;
-
- intel_gvt_init_engine_mmio_context(gvt);
-
- ret = intel_gvt_load_firmware(gvt);
- if (ret)
- goto out_clean_mmio_info;
-
- ret = intel_gvt_init_irq(gvt);
- if (ret)
- goto out_free_firmware;
-
- ret = intel_gvt_init_gtt(gvt);
- if (ret)
- goto out_free_firmware;
-
- ret = intel_gvt_init_workload_scheduler(gvt);
- if (ret)
- goto out_clean_gtt;
-
- ret = intel_gvt_init_sched_policy(gvt);
- if (ret)
- goto out_clean_workload_scheduler;
-
- ret = intel_gvt_init_cmd_parser(gvt);
- if (ret)
- goto out_clean_sched_policy;
-
- ret = init_service_thread(gvt);
- if (ret)
- goto out_clean_cmd_parser;
-
- ret = intel_gvt_init_vgpu_types(gvt);
- if (ret)
- goto out_clean_thread;
-
- vgpu = intel_gvt_create_idle_vgpu(gvt);
- if (IS_ERR(vgpu)) {
- ret = PTR_ERR(vgpu);
- gvt_err("failed to create idle vgpu\n");
- goto out_clean_types;
- }
- gvt->idle_vgpu = vgpu;
-
- intel_gvt_debugfs_init(gvt);
-
- ret = intel_gvt_init_vgpu_type_groups(gvt);
- if (ret)
- goto out_destroy_idle_vgpu;
-
- ret = mdev_register_device(i915->drm.dev, &intel_vgpu_mdev_ops);
- if (ret)
- goto out_cleanup_vgpu_type_groups;
-
- gvt_dbg_core("gvt device initialization is done\n");
- return 0;
-
-out_cleanup_vgpu_type_groups:
- intel_gvt_cleanup_vgpu_type_groups(gvt);
-out_destroy_idle_vgpu:
- intel_gvt_destroy_idle_vgpu(gvt->idle_vgpu);
- intel_gvt_debugfs_clean(gvt);
-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:
- intel_gvt_clean_sched_policy(gvt);
-out_clean_workload_scheduler:
- intel_gvt_clean_workload_scheduler(gvt);
-out_clean_gtt:
- intel_gvt_clean_gtt(gvt);
-out_free_firmware:
- intel_gvt_free_firmware(gvt);
-out_clean_mmio_info:
- intel_gvt_clean_mmio_info(gvt);
-out_clean_idr:
- idr_destroy(&gvt->vgpu_idr);
- kfree(gvt);
- i915->gvt = NULL;
- return ret;
-}
-
-static void intel_gvt_pm_resume(struct drm_i915_private *i915)
-{
- struct intel_gvt *gvt = i915->gvt;
-
- intel_gvt_restore_fence(gvt);
- intel_gvt_restore_mmio(gvt);
- intel_gvt_restore_ggtt(gvt);
-}
-
-const struct intel_vgpu_ops intel_gvt_vgpu_ops = {
- .init_device = intel_gvt_init_device,
- .clean_device = intel_gvt_clean_device,
- .pm_resume = intel_gvt_pm_resume,
-};
diff --git a/drivers/gpu/drm/i915/gvt/gvt.h b/drivers/gpu/drm/i915/gvt/gvt.h
index c32e8eb199f10..03ecffc2ba56a 100644
--- a/drivers/gpu/drm/i915/gvt/gvt.h
+++ b/drivers/gpu/drm/i915/gvt/gvt.h
@@ -765,12 +765,6 @@ int intel_gvt_dma_map_guest_page(struct intel_vgpu *vgpu, unsigned long gfn,
void intel_gvt_dma_unmap_guest_page(struct intel_vgpu *vgpu,
dma_addr_t dma_addr);

-int intel_gvt_init_vgpu_type_groups(struct intel_gvt *gvt);
-void intel_gvt_cleanup_vgpu_type_groups(struct intel_gvt *gvt);
-
#include "trace.h"

-extern const struct intel_vgpu_ops intel_gvt_vgpu_ops;
-extern const struct mdev_parent_ops intel_vgpu_mdev_ops;
-
#endif
diff --git a/drivers/gpu/drm/i915/gvt/kvmgt.c b/drivers/gpu/drm/i915/gvt/kvmgt.c
index 4113f850bf92d..f033031c676da 100644
--- a/drivers/gpu/drm/i915/gvt/kvmgt.c
+++ b/drivers/gpu/drm/i915/gvt/kvmgt.c
@@ -1,7 +1,7 @@
/*
* KVMGT - the implementation of Intel mediated pass-through framework for KVM
*
- * Copyright(c) 2014-2016 Intel Corporation. All rights reserved.
+ * Copyright(c) 2011-2016 Intel Corporation. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@@ -26,6 +26,11 @@
* Kevin Tian <[email protected]>
* Jike Song <[email protected]>
* Xiaoguang Chen <[email protected]>
+ * Eddie Dong <[email protected]>
+ *
+ * Contributors:
+ * Niu Bing <[email protected]>
+ * Zhi Wang <[email protected]>
*/

#include <linux/init.h>
@@ -182,7 +187,7 @@ static struct attribute_group *gvt_vgpu_type_groups[] = {
[0 ... NR_MAX_INTEL_VGPU_TYPES - 1] = NULL,
};

-int intel_gvt_init_vgpu_type_groups(struct intel_gvt *gvt)
+static int intel_gvt_init_vgpu_type_groups(struct intel_gvt *gvt)
{
int i, j;
struct intel_vgpu_type *type;
@@ -211,7 +216,7 @@ int intel_gvt_init_vgpu_type_groups(struct intel_gvt *gvt)
return -ENOMEM;
}

-void intel_gvt_cleanup_vgpu_type_groups(struct intel_gvt *gvt)
+static void intel_gvt_cleanup_vgpu_type_groups(struct intel_gvt *gvt)
{
int i;
struct attribute_group *group;
@@ -1720,7 +1725,7 @@ static struct mdev_driver intel_vgpu_mdev_driver = {
.remove = intel_vgpu_remove,
};

-const struct mdev_parent_ops intel_vgpu_mdev_ops = {
+static const struct mdev_parent_ops intel_vgpu_mdev_ops = {
.owner = THIS_MODULE,
.supported_type_groups = gvt_vgpu_type_groups,
.device_driver = &intel_vgpu_mdev_driver,
@@ -1925,6 +1930,257 @@ void intel_gvt_dma_unmap_guest_page(struct intel_vgpu *vgpu,
mutex_unlock(&vgpu->cache_lock);
}

+static void init_device_info(struct intel_gvt *gvt)
+{
+ struct intel_gvt_device_info *info = &gvt->device_info;
+ struct pci_dev *pdev = to_pci_dev(gvt->gt->i915->drm.dev);
+
+ info->max_support_vgpus = 8;
+ info->cfg_space_size = PCI_CFG_SPACE_EXP_SIZE;
+ info->mmio_size = 2 * 1024 * 1024;
+ info->mmio_bar = 0;
+ info->gtt_start_offset = 8 * 1024 * 1024;
+ info->gtt_entry_size = 8;
+ info->gtt_entry_size_shift = 3;
+ info->gmadr_bytes_in_cmd = 8;
+ info->max_surface_size = 36 * 1024 * 1024;
+ info->msi_cap_offset = pdev->msi_cap;
+}
+
+static void intel_gvt_test_and_emulate_vblank(struct intel_gvt *gvt)
+{
+ struct intel_vgpu *vgpu;
+ int id;
+
+ mutex_lock(&gvt->lock);
+ idr_for_each_entry((&(gvt)->vgpu_idr), (vgpu), (id)) {
+ if (test_and_clear_bit(INTEL_GVT_REQUEST_EMULATE_VBLANK + id,
+ (void *)&gvt->service_request)) {
+ if (vgpu->active)
+ intel_vgpu_emulate_vblank(vgpu);
+ }
+ }
+ mutex_unlock(&gvt->lock);
+}
+
+static int gvt_service_thread(void *data)
+{
+ struct intel_gvt *gvt = (struct intel_gvt *)data;
+ int ret;
+
+ gvt_dbg_core("service thread start\n");
+
+ while (!kthread_should_stop()) {
+ ret = wait_event_interruptible(gvt->service_thread_wq,
+ kthread_should_stop() || gvt->service_request);
+
+ if (kthread_should_stop())
+ break;
+
+ if (WARN_ONCE(ret, "service thread is waken up by signal.\n"))
+ continue;
+
+ intel_gvt_test_and_emulate_vblank(gvt);
+
+ if (test_bit(INTEL_GVT_REQUEST_SCHED,
+ (void *)&gvt->service_request) ||
+ test_bit(INTEL_GVT_REQUEST_EVENT_SCHED,
+ (void *)&gvt->service_request)) {
+ intel_gvt_schedule(gvt);
+ }
+ }
+
+ return 0;
+}
+
+static void clean_service_thread(struct intel_gvt *gvt)
+{
+ kthread_stop(gvt->service_thread);
+}
+
+static int init_service_thread(struct intel_gvt *gvt)
+{
+ init_waitqueue_head(&gvt->service_thread_wq);
+
+ gvt->service_thread = kthread_run(gvt_service_thread,
+ gvt, "gvt_service_thread");
+ if (IS_ERR(gvt->service_thread)) {
+ gvt_err("fail to start service thread.\n");
+ return PTR_ERR(gvt->service_thread);
+ }
+ return 0;
+}
+
+/**
+ * intel_gvt_clean_device - clean a GVT device
+ * @i915: i915 private
+ *
+ * This function is called at the driver unloading stage, to free the
+ * resources owned by a GVT device.
+ *
+ */
+static void intel_gvt_clean_device(struct drm_i915_private *i915)
+{
+ struct intel_gvt *gvt = fetch_and_zero(&i915->gvt);
+
+ if (drm_WARN_ON(&i915->drm, !gvt))
+ return;
+
+ mdev_unregister_device(i915->drm.dev);
+ intel_gvt_cleanup_vgpu_type_groups(gvt);
+ intel_gvt_destroy_idle_vgpu(gvt->idle_vgpu);
+ intel_gvt_clean_vgpu_types(gvt);
+
+ intel_gvt_debugfs_clean(gvt);
+ clean_service_thread(gvt);
+ intel_gvt_clean_cmd_parser(gvt);
+ intel_gvt_clean_sched_policy(gvt);
+ intel_gvt_clean_workload_scheduler(gvt);
+ intel_gvt_clean_gtt(gvt);
+ intel_gvt_free_firmware(gvt);
+ intel_gvt_clean_mmio_info(gvt);
+ idr_destroy(&gvt->vgpu_idr);
+
+ kfree(i915->gvt);
+}
+
+/**
+ * intel_gvt_init_device - initialize a GVT device
+ * @i915: drm i915 private data
+ *
+ * This function is called at the initialization stage, to initialize
+ * necessary GVT components.
+ *
+ * Returns:
+ * Zero on success, negative error code if failed.
+ *
+ */
+static int intel_gvt_init_device(struct drm_i915_private *i915)
+{
+ struct intel_gvt *gvt;
+ struct intel_vgpu *vgpu;
+ int ret;
+
+ if (drm_WARN_ON(&i915->drm, i915->gvt))
+ return -EEXIST;
+
+ gvt = kzalloc(sizeof(struct intel_gvt), GFP_KERNEL);
+ if (!gvt)
+ return -ENOMEM;
+
+ gvt_dbg_core("init gvt device\n");
+
+ idr_init_base(&gvt->vgpu_idr, 1);
+ spin_lock_init(&gvt->scheduler.mmio_context_lock);
+ mutex_init(&gvt->lock);
+ mutex_init(&gvt->sched_lock);
+ gvt->gt = to_gt(i915);
+ i915->gvt = gvt;
+
+ init_device_info(gvt);
+
+ ret = intel_gvt_setup_mmio_info(gvt);
+ if (ret)
+ goto out_clean_idr;
+
+ intel_gvt_init_engine_mmio_context(gvt);
+
+ ret = intel_gvt_load_firmware(gvt);
+ if (ret)
+ goto out_clean_mmio_info;
+
+ ret = intel_gvt_init_irq(gvt);
+ if (ret)
+ goto out_free_firmware;
+
+ ret = intel_gvt_init_gtt(gvt);
+ if (ret)
+ goto out_free_firmware;
+
+ ret = intel_gvt_init_workload_scheduler(gvt);
+ if (ret)
+ goto out_clean_gtt;
+
+ ret = intel_gvt_init_sched_policy(gvt);
+ if (ret)
+ goto out_clean_workload_scheduler;
+
+ ret = intel_gvt_init_cmd_parser(gvt);
+ if (ret)
+ goto out_clean_sched_policy;
+
+ ret = init_service_thread(gvt);
+ if (ret)
+ goto out_clean_cmd_parser;
+
+ ret = intel_gvt_init_vgpu_types(gvt);
+ if (ret)
+ goto out_clean_thread;
+
+ vgpu = intel_gvt_create_idle_vgpu(gvt);
+ if (IS_ERR(vgpu)) {
+ ret = PTR_ERR(vgpu);
+ gvt_err("failed to create idle vgpu\n");
+ goto out_clean_types;
+ }
+ gvt->idle_vgpu = vgpu;
+
+ intel_gvt_debugfs_init(gvt);
+
+ ret = intel_gvt_init_vgpu_type_groups(gvt);
+ if (ret)
+ goto out_destroy_idle_vgpu;
+
+ ret = mdev_register_device(i915->drm.dev, &intel_vgpu_mdev_ops);
+ if (ret)
+ goto out_cleanup_vgpu_type_groups;
+
+ gvt_dbg_core("gvt device initialization is done\n");
+ return 0;
+
+out_cleanup_vgpu_type_groups:
+ intel_gvt_cleanup_vgpu_type_groups(gvt);
+out_destroy_idle_vgpu:
+ intel_gvt_destroy_idle_vgpu(gvt->idle_vgpu);
+ intel_gvt_debugfs_clean(gvt);
+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:
+ intel_gvt_clean_sched_policy(gvt);
+out_clean_workload_scheduler:
+ intel_gvt_clean_workload_scheduler(gvt);
+out_clean_gtt:
+ intel_gvt_clean_gtt(gvt);
+out_free_firmware:
+ intel_gvt_free_firmware(gvt);
+out_clean_mmio_info:
+ intel_gvt_clean_mmio_info(gvt);
+out_clean_idr:
+ idr_destroy(&gvt->vgpu_idr);
+ kfree(gvt);
+ i915->gvt = NULL;
+ return ret;
+}
+
+static void intel_gvt_pm_resume(struct drm_i915_private *i915)
+{
+ struct intel_gvt *gvt = i915->gvt;
+
+ intel_gvt_restore_fence(gvt);
+ intel_gvt_restore_mmio(gvt);
+ intel_gvt_restore_ggtt(gvt);
+}
+
+static const struct intel_vgpu_ops intel_gvt_vgpu_ops = {
+ .init_device = intel_gvt_init_device,
+ .clean_device = intel_gvt_clean_device,
+ .pm_resume = intel_gvt_pm_resume,
+};
+
static int __init kvmgt_init(void)
{
int ret;
--
2.30.2

2022-04-12 22:22:27

by Christoph Hellwig

[permalink] [raw]
Subject: [PATCH 18/34] drm/i915/gvt: devirtualize ->is_valid_gfn

Just call the code directly and move towards the callers.

Signed-off-by: Christoph Hellwig <[email protected]>
---
drivers/gpu/drm/i915/gvt/gtt.c | 20 ++++++++++++++++++--
drivers/gpu/drm/i915/gvt/hypercall.h | 1 -
drivers/gpu/drm/i915/gvt/kvmgt.c | 17 -----------------
drivers/gpu/drm/i915/gvt/mpt.h | 17 -----------------
4 files changed, 18 insertions(+), 37 deletions(-)

diff --git a/drivers/gpu/drm/i915/gvt/gtt.c b/drivers/gpu/drm/i915/gvt/gtt.c
index 9b696e5705eb7..1360412f8ef8a 100644
--- a/drivers/gpu/drm/i915/gvt/gtt.c
+++ b/drivers/gpu/drm/i915/gvt/gtt.c
@@ -49,6 +49,22 @@
static bool enable_out_of_sync = false;
static int preallocated_oos_pages = 8192;

+static bool intel_gvt_is_valid_gfn(struct intel_vgpu *vgpu, unsigned long gfn)
+{
+ struct kvm *kvm = vgpu->kvm;
+ int idx;
+ bool ret;
+
+ if (!vgpu->attached)
+ return false;
+
+ idx = srcu_read_lock(&kvm->srcu);
+ ret = kvm_is_visible_gfn(kvm, gfn);
+ srcu_read_unlock(&kvm->srcu, idx);
+
+ return ret;
+}
+
/*
* validate a gm address and related range size,
* translate it to host gm address
@@ -1331,7 +1347,7 @@ static int ppgtt_populate_spt(struct intel_vgpu_ppgtt_spt *spt)
ppgtt_set_shadow_entry(spt, &se, i);
} else {
gfn = ops->get_pfn(&ge);
- if (!intel_gvt_hypervisor_is_valid_gfn(vgpu, gfn)) {
+ if (!intel_gvt_is_valid_gfn(vgpu, gfn)) {
ops->set_pfn(&se, gvt->gtt.scratch_mfn);
ppgtt_set_shadow_entry(spt, &se, i);
continue;
@@ -2315,7 +2331,7 @@ static int emulate_ggtt_mmio_write(struct intel_vgpu *vgpu, unsigned int off,
/* one PTE update may be issued in multiple writes and the
* first write may not construct a valid gfn
*/
- if (!intel_gvt_hypervisor_is_valid_gfn(vgpu, gfn)) {
+ if (!intel_gvt_is_valid_gfn(vgpu, gfn)) {
ops->set_pfn(&m, gvt->gtt.scratch_mfn);
goto out;
}
diff --git a/drivers/gpu/drm/i915/gvt/hypercall.h b/drivers/gpu/drm/i915/gvt/hypercall.h
index de63bd8dd05ba..c1a9eeed04607 100644
--- a/drivers/gpu/drm/i915/gvt/hypercall.h
+++ b/drivers/gpu/drm/i915/gvt/hypercall.h
@@ -55,7 +55,6 @@ struct intel_gvt_mpt {
dma_addr_t dma_addr);

int (*dma_pin_guest_page)(struct intel_vgpu *vgpu, dma_addr_t dma_addr);
- bool (*is_valid_gfn)(struct intel_vgpu *vgpu, unsigned long gfn);
};

#endif /* _GVT_HYPERCALL_H_ */
diff --git a/drivers/gpu/drm/i915/gvt/kvmgt.c b/drivers/gpu/drm/i915/gvt/kvmgt.c
index 1d1c026fd8258..93fd7f997c8a1 100644
--- a/drivers/gpu/drm/i915/gvt/kvmgt.c
+++ b/drivers/gpu/drm/i915/gvt/kvmgt.c
@@ -1980,22 +1980,6 @@ static void kvmgt_dma_unmap_guest_page(struct intel_vgpu *vgpu,
mutex_unlock(&vgpu->cache_lock);
}

-static bool kvmgt_is_valid_gfn(struct intel_vgpu *vgpu, unsigned long gfn)
-{
- struct kvm *kvm = vgpu->kvm;
- int idx;
- bool ret;
-
- if (!vgpu->attached)
- return false;
-
- idx = srcu_read_lock(&kvm->srcu);
- ret = kvm_is_visible_gfn(kvm, gfn);
- srcu_read_unlock(&kvm->srcu, idx);
-
- return ret;
-}
-
static const struct intel_gvt_mpt kvmgt_mpt = {
.host_init = kvmgt_host_init,
.host_exit = kvmgt_host_exit,
@@ -2005,7 +1989,6 @@ static const struct intel_gvt_mpt kvmgt_mpt = {
.dma_map_guest_page = kvmgt_dma_map_guest_page,
.dma_unmap_guest_page = kvmgt_dma_unmap_guest_page,
.dma_pin_guest_page = kvmgt_dma_pin_guest_page,
- .is_valid_gfn = kvmgt_is_valid_gfn,
};

struct intel_gvt_host intel_gvt_host = {
diff --git a/drivers/gpu/drm/i915/gvt/mpt.h b/drivers/gpu/drm/i915/gvt/mpt.h
index 59369e8b3b692..1a796f2181ba8 100644
--- a/drivers/gpu/drm/i915/gvt/mpt.h
+++ b/drivers/gpu/drm/i915/gvt/mpt.h
@@ -157,21 +157,4 @@ intel_gvt_hypervisor_dma_pin_guest_page(struct intel_vgpu *vgpu,
return intel_gvt_host.mpt->dma_pin_guest_page(vgpu, dma_addr);
}

-/**
- * intel_gvt_hypervisor_is_valid_gfn - check if a visible gfn
- * @vgpu: a vGPU
- * @gfn: guest PFN
- *
- * Returns:
- * true on valid gfn, false on not.
- */
-static inline bool intel_gvt_hypervisor_is_valid_gfn(
- struct intel_vgpu *vgpu, unsigned long gfn)
-{
- if (!intel_gvt_host.mpt->is_valid_gfn)
- return true;
-
- return intel_gvt_host.mpt->is_valid_gfn(vgpu, gfn);
-}
-
#endif /* _GVT_MPT_H_ */
--
2.30.2

2022-04-12 22:24:34

by Christoph Hellwig

[permalink] [raw]
Subject: [PATCH 02/34] drm/i915/gvt: remove enum hypervisor_type

The only supported hypervisor is KVM, so don't bother with dead code
enumerating hypervisors.

Signed-off-by: Christoph Hellwig <[email protected]>
---
drivers/gpu/drm/i915/gvt/gvt.c | 17 +--
drivers/gpu/drm/i915/gvt/gvt.h | 1 -
drivers/gpu/drm/i915/gvt/hypercall.h | 6 --
drivers/gpu/drm/i915/gvt/kvmgt.c | 1 -
drivers/gpu/drm/i915/gvt/opregion.c | 150 ++++++---------------------
5 files changed, 34 insertions(+), 141 deletions(-)

diff --git a/drivers/gpu/drm/i915/gvt/gvt.c b/drivers/gpu/drm/i915/gvt/gvt.c
index 623424766c359..b4b13e4a94e34 100644
--- a/drivers/gpu/drm/i915/gvt/gvt.c
+++ b/drivers/gpu/drm/i915/gvt/gvt.c
@@ -41,11 +41,6 @@

struct intel_gvt_host intel_gvt_host;

-static const char * const supported_hypervisors[] = {
- [INTEL_GVT_HYPERVISOR_XEN] = "XEN",
- [INTEL_GVT_HYPERVISOR_KVM] = "KVM",
-};
-
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,
@@ -304,23 +299,13 @@ intel_gvt_register_hypervisor(const struct intel_gvt_mpt *m)
if (!intel_gvt_host.initialized)
return -ENODEV;

- if (m->type != INTEL_GVT_HYPERVISOR_KVM &&
- m->type != INTEL_GVT_HYPERVISOR_XEN)
- return -EINVAL;
-
intel_gvt_host.mpt = m;
- intel_gvt_host.hypervisor_type = m->type;
gvt = (void *)kdev_to_i915(intel_gvt_host.dev)->gvt;

ret = intel_gvt_hypervisor_host_init(intel_gvt_host.dev, gvt,
&intel_gvt_ops);
- if (ret < 0) {
- gvt_err("Failed to init %s hypervisor module\n",
- supported_hypervisors[intel_gvt_host.hypervisor_type]);
+ if (ret < 0)
return -ENODEV;
- }
- gvt_dbg_core("Running with hypervisor %s in host mode\n",
- supported_hypervisors[intel_gvt_host.hypervisor_type]);
return 0;
}
EXPORT_SYMBOL_GPL(intel_gvt_register_hypervisor);
diff --git a/drivers/gpu/drm/i915/gvt/gvt.h b/drivers/gpu/drm/i915/gvt/gvt.h
index bfe07c69cfd26..554baf26cab35 100644
--- a/drivers/gpu/drm/i915/gvt/gvt.h
+++ b/drivers/gpu/drm/i915/gvt/gvt.h
@@ -60,7 +60,6 @@
struct intel_gvt_host {
struct device *dev;
bool initialized;
- int hypervisor_type;
const struct intel_gvt_mpt *mpt;
};

diff --git a/drivers/gpu/drm/i915/gvt/hypercall.h b/drivers/gpu/drm/i915/gvt/hypercall.h
index f33e3cbd0439d..3179831536458 100644
--- a/drivers/gpu/drm/i915/gvt/hypercall.h
+++ b/drivers/gpu/drm/i915/gvt/hypercall.h
@@ -37,17 +37,11 @@

struct device;

-enum hypervisor_type {
- INTEL_GVT_HYPERVISOR_XEN = 0,
- INTEL_GVT_HYPERVISOR_KVM,
-};
-
/*
* Specific GVT-g MPT modules function collections. Currently GVT-g supports
* both Xen and KVM by providing dedicated hypervisor-related MPT modules.
*/
struct intel_gvt_mpt {
- enum hypervisor_type type;
int (*host_init)(struct device *dev, void *gvt, const void *ops);
void (*host_exit)(struct device *dev, void *gvt);
int (*attach_vgpu)(void *vgpu, unsigned long *handle);
diff --git a/drivers/gpu/drm/i915/gvt/kvmgt.c b/drivers/gpu/drm/i915/gvt/kvmgt.c
index 057ec44901045..5231ce8084b36 100644
--- a/drivers/gpu/drm/i915/gvt/kvmgt.c
+++ b/drivers/gpu/drm/i915/gvt/kvmgt.c
@@ -2221,7 +2221,6 @@ static bool kvmgt_is_valid_gfn(unsigned long handle, unsigned long gfn)
}

static const struct intel_gvt_mpt kvmgt_mpt = {
- .type = INTEL_GVT_HYPERVISOR_KVM,
.host_init = kvmgt_host_init,
.host_exit = kvmgt_host_exit,
.attach_vgpu = kvmgt_attach_vgpu,
diff --git a/drivers/gpu/drm/i915/gvt/opregion.c b/drivers/gpu/drm/i915/gvt/opregion.c
index 33569b910ed5b..286ac6d7c6ced 100644
--- a/drivers/gpu/drm/i915/gvt/opregion.c
+++ b/drivers/gpu/drm/i915/gvt/opregion.c
@@ -255,33 +255,6 @@ int intel_vgpu_init_opregion(struct intel_vgpu *vgpu)
return 0;
}

-static int map_vgpu_opregion(struct intel_vgpu *vgpu, bool map)
-{
- u64 mfn;
- int i, ret;
-
- for (i = 0; i < INTEL_GVT_OPREGION_PAGES; i++) {
- mfn = intel_gvt_hypervisor_virt_to_mfn(vgpu_opregion(vgpu)->va
- + i * PAGE_SIZE);
- if (mfn == INTEL_GVT_INVALID_ADDR) {
- gvt_vgpu_err("fail to get MFN from VA\n");
- return -EINVAL;
- }
- ret = intel_gvt_hypervisor_map_gfn_to_mfn(vgpu,
- vgpu_opregion(vgpu)->gfn[i],
- mfn, 1, map);
- if (ret) {
- gvt_vgpu_err("fail to map GFN to MFN, errno: %d\n",
- ret);
- return ret;
- }
- }
-
- vgpu_opregion(vgpu)->mapped = map;
-
- return 0;
-}
-
/**
* intel_vgpu_opregion_base_write_handler - Opregion base register write handler
*
@@ -294,34 +267,13 @@ static int map_vgpu_opregion(struct intel_vgpu *vgpu, bool map)
int intel_vgpu_opregion_base_write_handler(struct intel_vgpu *vgpu, u32 gpa)
{

- int i, ret = 0;
+ int i;

gvt_dbg_core("emulate opregion from kernel\n");

- switch (intel_gvt_host.hypervisor_type) {
- case INTEL_GVT_HYPERVISOR_KVM:
- for (i = 0; i < INTEL_GVT_OPREGION_PAGES; i++)
- vgpu_opregion(vgpu)->gfn[i] = (gpa >> PAGE_SHIFT) + i;
- break;
- case INTEL_GVT_HYPERVISOR_XEN:
- /**
- * Wins guest on Xengt will write this register twice: xen
- * hvmloader and windows graphic driver.
- */
- if (vgpu_opregion(vgpu)->mapped)
- map_vgpu_opregion(vgpu, false);
-
- for (i = 0; i < INTEL_GVT_OPREGION_PAGES; i++)
- vgpu_opregion(vgpu)->gfn[i] = (gpa >> PAGE_SHIFT) + i;
-
- ret = map_vgpu_opregion(vgpu, true);
- break;
- default:
- ret = -EINVAL;
- gvt_vgpu_err("not supported hypervisor\n");
- }
-
- return ret;
+ for (i = 0; i < INTEL_GVT_OPREGION_PAGES; i++)
+ vgpu_opregion(vgpu)->gfn[i] = (gpa >> PAGE_SHIFT) + i;
+ return 0;
}

/**
@@ -336,12 +288,7 @@ void intel_vgpu_clean_opregion(struct intel_vgpu *vgpu)
if (!vgpu_opregion(vgpu)->va)
return;

- if (intel_gvt_host.hypervisor_type == INTEL_GVT_HYPERVISOR_XEN) {
- if (vgpu_opregion(vgpu)->mapped)
- map_vgpu_opregion(vgpu, false);
- } else if (intel_gvt_host.hypervisor_type == INTEL_GVT_HYPERVISOR_KVM) {
- /* Guest opregion is released by VFIO */
- }
+ /* Guest opregion is released by VFIO */
free_pages((unsigned long)vgpu_opregion(vgpu)->va,
get_order(INTEL_GVT_OPREGION_SIZE));

@@ -470,39 +417,22 @@ int intel_vgpu_emulate_opregion_request(struct intel_vgpu *vgpu, u32 swsci)
u64 scic_pa = 0, parm_pa = 0;
int ret;

- switch (intel_gvt_host.hypervisor_type) {
- case INTEL_GVT_HYPERVISOR_XEN:
- scic = *((u32 *)vgpu_opregion(vgpu)->va +
- INTEL_GVT_OPREGION_SCIC);
- parm = *((u32 *)vgpu_opregion(vgpu)->va +
- INTEL_GVT_OPREGION_PARM);
- break;
- case INTEL_GVT_HYPERVISOR_KVM:
- scic_pa = (vgpu_opregion(vgpu)->gfn[0] << PAGE_SHIFT) +
- INTEL_GVT_OPREGION_SCIC;
- parm_pa = (vgpu_opregion(vgpu)->gfn[0] << PAGE_SHIFT) +
- INTEL_GVT_OPREGION_PARM;
-
- ret = intel_gvt_hypervisor_read_gpa(vgpu, scic_pa,
- &scic, sizeof(scic));
- if (ret) {
- gvt_vgpu_err("guest opregion read error %d, gpa 0x%llx, len %lu\n",
- ret, scic_pa, sizeof(scic));
- return ret;
- }
-
- ret = intel_gvt_hypervisor_read_gpa(vgpu, parm_pa,
- &parm, sizeof(parm));
- if (ret) {
- gvt_vgpu_err("guest opregion read error %d, gpa 0x%llx, len %lu\n",
- ret, scic_pa, sizeof(scic));
- return ret;
- }
+ scic_pa = (vgpu_opregion(vgpu)->gfn[0] << PAGE_SHIFT) +
+ INTEL_GVT_OPREGION_SCIC;
+ parm_pa = (vgpu_opregion(vgpu)->gfn[0] << PAGE_SHIFT) +
+ INTEL_GVT_OPREGION_PARM;
+ ret = intel_gvt_hypervisor_read_gpa(vgpu, scic_pa, &scic, sizeof(scic));
+ if (ret) {
+ gvt_vgpu_err("guest opregion read error %d, gpa 0x%llx, len %lu\n",
+ ret, scic_pa, sizeof(scic));
+ return ret;
+ }

- break;
- default:
- gvt_vgpu_err("not supported hypervisor\n");
- return -EINVAL;
+ ret = intel_gvt_hypervisor_read_gpa(vgpu, parm_pa, &parm, sizeof(parm));
+ if (ret) {
+ gvt_vgpu_err("guest opregion read error %d, gpa 0x%llx, len %lu\n",
+ ret, scic_pa, sizeof(scic));
+ return ret;
}

if (!(swsci & SWSCI_SCI_SELECT)) {
@@ -535,34 +465,20 @@ int intel_vgpu_emulate_opregion_request(struct intel_vgpu *vgpu, u32 swsci)
parm = 0;

out:
- switch (intel_gvt_host.hypervisor_type) {
- case INTEL_GVT_HYPERVISOR_XEN:
- *((u32 *)vgpu_opregion(vgpu)->va +
- INTEL_GVT_OPREGION_SCIC) = scic;
- *((u32 *)vgpu_opregion(vgpu)->va +
- INTEL_GVT_OPREGION_PARM) = parm;
- break;
- case INTEL_GVT_HYPERVISOR_KVM:
- ret = intel_gvt_hypervisor_write_gpa(vgpu, scic_pa,
- &scic, sizeof(scic));
- if (ret) {
- gvt_vgpu_err("guest opregion write error %d, gpa 0x%llx, len %lu\n",
- ret, scic_pa, sizeof(scic));
- return ret;
- }
-
- ret = intel_gvt_hypervisor_write_gpa(vgpu, parm_pa,
- &parm, sizeof(parm));
- if (ret) {
- gvt_vgpu_err("guest opregion write error %d, gpa 0x%llx, len %lu\n",
- ret, scic_pa, sizeof(scic));
- return ret;
- }
+ ret = intel_gvt_hypervisor_write_gpa(vgpu, scic_pa, &scic,
+ sizeof(scic));
+ if (ret) {
+ gvt_vgpu_err("guest opregion write error %d, gpa 0x%llx, len %lu\n",
+ ret, scic_pa, sizeof(scic));
+ return ret;
+ }

- break;
- default:
- gvt_vgpu_err("not supported hypervisor\n");
- return -EINVAL;
+ ret = intel_gvt_hypervisor_write_gpa(vgpu, parm_pa, &parm,
+ sizeof(parm));
+ if (ret) {
+ gvt_vgpu_err("guest opregion write error %d, gpa 0x%llx, len %lu\n",
+ ret, scic_pa, sizeof(scic));
+ return ret;
}

return 0;
--
2.30.2

2022-04-12 22:25:34

by Christoph Hellwig

[permalink] [raw]
Subject: [PATCH 04/34] drm/i915/gvt: don't override the include path

drivers/gpu/drm/i915/gvt/Makefile is included
from drivers/gpu/drm/i915/Makefile and thus inherits the normal include
path relative to drivers/gpu/drm/i915/. Fix up the gvt-specific trace
header and just do away with the include path manipulation.

Signed-off-by: Christoph Hellwig <[email protected]>
---
drivers/gpu/drm/i915/gvt/Makefile | 1 -
drivers/gpu/drm/i915/gvt/trace.h | 2 +-
2 files changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/gvt/Makefile b/drivers/gpu/drm/i915/gvt/Makefile
index ea8324abc784a..4d70f4689479c 100644
--- a/drivers/gpu/drm/i915/gvt/Makefile
+++ b/drivers/gpu/drm/i915/gvt/Makefile
@@ -5,5 +5,4 @@ GVT_SOURCE := gvt.o aperture_gm.o handlers.o vgpu.o trace_points.o firmware.o \
execlist.o scheduler.o sched_policy.o mmio_context.o cmd_parser.o debugfs.o \
fb_decoder.o dmabuf.o page_track.o

-ccflags-y += -I $(srctree)/$(src) -I $(srctree)/$(src)/$(GVT_DIR)/
i915-y += $(addprefix $(GVT_DIR)/, $(GVT_SOURCE))
diff --git a/drivers/gpu/drm/i915/gvt/trace.h b/drivers/gpu/drm/i915/gvt/trace.h
index 6d787750d279f..348f57f8301db 100644
--- a/drivers/gpu/drm/i915/gvt/trace.h
+++ b/drivers/gpu/drm/i915/gvt/trace.h
@@ -379,5 +379,5 @@ TRACE_EVENT(render_mmio,
#undef TRACE_INCLUDE_PATH
#define TRACE_INCLUDE_PATH .
#undef TRACE_INCLUDE_FILE
-#define TRACE_INCLUDE_FILE trace
+#define TRACE_INCLUDE_FILE gvt/trace
#include <trace/define_trace.h>
--
2.30.2

2022-04-12 22:30:47

by Christoph Hellwig

[permalink] [raw]
Subject: [PATCH 27/34] drm/i915/gvt: remove kvmgt_guest_{init,exit}

Merge these into their only callers.

Signed-off-by: Christoph Hellwig <[email protected]>
---
drivers/gpu/drm/i915/gvt/kvmgt.c | 129 ++++++++++++++-----------------
1 file changed, 60 insertions(+), 69 deletions(-)

diff --git a/drivers/gpu/drm/i915/gvt/kvmgt.c b/drivers/gpu/drm/i915/gvt/kvmgt.c
index 5db74b6fe5137..38629ab4c9bf2 100644
--- a/drivers/gpu/drm/i915/gvt/kvmgt.c
+++ b/drivers/gpu/drm/i915/gvt/kvmgt.c
@@ -100,6 +100,13 @@ struct gvt_dma {
struct kref ref;
};

+static void kvmgt_page_track_write(struct kvm_vcpu *vcpu, gpa_t gpa,
+ const u8 *val, int len,
+ struct kvm_page_track_notifier_node *node);
+static void kvmgt_page_track_flush_slot(struct kvm *kvm,
+ struct kvm_memory_slot *slot,
+ struct kvm_page_track_notifier_node *node);
+
static ssize_t available_instances_show(struct mdev_type *mtype,
struct mdev_type_attribute *attr,
char *buf)
@@ -213,9 +220,7 @@ void intel_gvt_cleanup_vgpu_type_groups(struct intel_gvt *gvt)
}
}

-static int kvmgt_guest_init(struct mdev_device *mdev);
static void intel_vgpu_release_work(struct work_struct *work);
-static bool kvmgt_guest_exit(struct intel_vgpu *info);

static void gvt_unpin_guest_page(struct intel_vgpu *vgpu, unsigned long gfn,
unsigned long size)
@@ -803,6 +808,27 @@ static int intel_vgpu_group_notifier(struct notifier_block *nb,
return NOTIFY_OK;
}

+static bool __kvmgt_vgpu_exist(struct intel_vgpu *vgpu)
+{
+ struct intel_vgpu *itr;
+ int id;
+ bool ret = false;
+
+ mutex_lock(&vgpu->gvt->lock);
+ for_each_active_vgpu(vgpu->gvt, itr, id) {
+ if (!itr->attached)
+ continue;
+
+ if (vgpu->kvm == itr->kvm) {
+ ret = true;
+ goto out;
+ }
+ }
+out:
+ mutex_unlock(&vgpu->gvt->lock);
+ return ret;
+}
+
static int intel_vgpu_open_device(struct mdev_device *mdev)
{
struct intel_vgpu *vgpu = mdev_get_drvdata(mdev);
@@ -847,14 +873,37 @@ static int intel_vgpu_open_device(struct mdev_device *mdev)
goto undo_group;
}

- ret = kvmgt_guest_init(mdev);
- if (ret)
+ ret = -EEXIST;
+ if (vgpu->attached)
+ goto undo_group;
+
+ ret = -ESRCH;
+ if (!vgpu->kvm || vgpu->kvm->mm != current->mm) {
+ gvt_vgpu_err("KVM is required to use Intel vGPU\n");
+ goto undo_group;
+ }
+
+ ret = -EEXIST;
+ if (__kvmgt_vgpu_exist(vgpu))
goto undo_group;

+ vgpu->attached = true;
+ kvm_get_kvm(vgpu->kvm);
+
+ kvmgt_protect_table_init(vgpu);
+ gvt_cache_init(vgpu);
+
+ vgpu->track_node.track_write = kvmgt_page_track_write;
+ vgpu->track_node.track_flush_slot = kvmgt_page_track_flush_slot;
+ kvm_page_track_register_notifier(vgpu->kvm, &vgpu->track_node);
+
+ debugfs_create_ulong(KVMGT_DEBUGFS_FILENAME, 0444, vgpu->debugfs,
+ &vgpu->nr_cache_entries);
+
intel_gvt_activate_vgpu(vgpu);

atomic_set(&vgpu->released, 0);
- return ret;
+ return 0;

undo_group:
vfio_group_put_external_user(vgpu->vfio_group);
@@ -908,7 +957,12 @@ static void __intel_vgpu_release(struct intel_vgpu *vgpu)
/* dereference module reference taken at open */
module_put(THIS_MODULE);

- kvmgt_guest_exit(vgpu);
+ debugfs_remove(debugfs_lookup(KVMGT_DEBUGFS_FILENAME, vgpu->debugfs));
+
+ kvm_page_track_unregister_notifier(vgpu->kvm, &vgpu->track_node);
+ kvm_put_kvm(vgpu->kvm);
+ kvmgt_protect_table_destroy(vgpu);
+ gvt_cache_destroy(vgpu);

intel_vgpu_release_msi_eventfd_ctx(vgpu);
vfio_group_put_external_user(vgpu->vfio_group);
@@ -1763,69 +1817,6 @@ static void kvmgt_page_track_flush_slot(struct kvm *kvm,
write_unlock(&kvm->mmu_lock);
}

-static bool __kvmgt_vgpu_exist(struct intel_vgpu *vgpu, struct kvm *kvm)
-{
- struct intel_vgpu *itr;
- int id;
- bool ret = false;
-
- mutex_lock(&vgpu->gvt->lock);
- for_each_active_vgpu(vgpu->gvt, itr, id) {
- if (!itr->attached)
- continue;
-
- if (kvm && kvm == itr->kvm) {
- ret = true;
- goto out;
- }
- }
-out:
- mutex_unlock(&vgpu->gvt->lock);
- return ret;
-}
-
-static int kvmgt_guest_init(struct mdev_device *mdev)
-{
- struct intel_vgpu *vgpu = mdev_get_drvdata(mdev);
- struct kvm *kvm = vgpu->kvm;
-
- if (vgpu->attached)
- return -EEXIST;
-
- if (!kvm || kvm->mm != current->mm) {
- gvt_vgpu_err("KVM is required to use Intel vGPU\n");
- return -ESRCH;
- }
-
- if (__kvmgt_vgpu_exist(vgpu, kvm))
- return -EEXIST;
-
- vgpu->attached = true;
- kvm_get_kvm(vgpu->kvm);
-
- kvmgt_protect_table_init(vgpu);
- gvt_cache_init(vgpu);
-
- vgpu->track_node.track_write = kvmgt_page_track_write;
- vgpu->track_node.track_flush_slot = kvmgt_page_track_flush_slot;
- kvm_page_track_register_notifier(kvm, &vgpu->track_node);
-
- debugfs_create_ulong(KVMGT_DEBUGFS_FILENAME, 0444, vgpu->debugfs,
- &vgpu->nr_cache_entries);
- return 0;
-}
-
-static bool kvmgt_guest_exit(struct intel_vgpu *info)
-{
- debugfs_remove(debugfs_lookup(KVMGT_DEBUGFS_FILENAME, info->debugfs));
-
- kvm_page_track_unregister_notifier(info->kvm, &info->track_node);
- kvm_put_kvm(info->kvm);
- kvmgt_protect_table_destroy(info);
- gvt_cache_destroy(info);
- return true;
-}
-
void intel_vgpu_detach_regions(struct intel_vgpu *vgpu)
{
int i;
--
2.30.2

2022-04-12 22:32:55

by Christoph Hellwig

[permalink] [raw]
Subject: [PATCH 32/34] vfio/mdev: Remove mdev_parent_ops

From: Jason Gunthorpe <[email protected]>

The last useful member in this struct is the supported_type_groups, move
it to the mdev_driver and delete mdev_parent_ops.

Replace it with mdev_driver as an argument to mdev_register_device()

Signed-off-by: Jason Gunthorpe <[email protected]>
Signed-off-by: Christoph Hellwig <[email protected]>
---
.../driver-api/vfio-mediated-device.rst | 24 ++++--------------
drivers/gpu/drm/i915/gvt/kvmgt.c | 7 +-----
drivers/s390/cio/vfio_ccw_ops.c | 7 +-----
drivers/s390/crypto/vfio_ap_ops.c | 9 ++-----
drivers/vfio/mdev/mdev_core.c | 13 ++++------
drivers/vfio/mdev/mdev_private.h | 2 +-
drivers/vfio/mdev/mdev_sysfs.c | 6 ++---
include/linux/mdev.h | 25 +++----------------
samples/vfio-mdev/mbochs.c | 9 ++-----
samples/vfio-mdev/mdpy.c | 9 ++-----
samples/vfio-mdev/mtty.c | 9 ++-----
11 files changed, 28 insertions(+), 92 deletions(-)

diff --git a/Documentation/driver-api/vfio-mediated-device.rst b/Documentation/driver-api/vfio-mediated-device.rst
index 5a6e18a651a18..784bbeb22adcf 100644
--- a/Documentation/driver-api/vfio-mediated-device.rst
+++ b/Documentation/driver-api/vfio-mediated-device.rst
@@ -105,6 +105,7 @@ structure to represent a mediated device's driver::
struct mdev_driver {
int (*probe) (struct mdev_device *dev);
void (*remove) (struct mdev_device *dev);
+ struct attribute_group **supported_type_groups;
struct device_driver driver;
};

@@ -119,30 +120,15 @@ to register and unregister itself with the core driver:

extern void mdev_unregister_driver(struct mdev_driver *drv);

-The mediated bus driver is responsible for adding mediated devices to the VFIO
-group when devices are bound to the driver and removing mediated devices from
-the VFIO when devices are unbound from the driver.
-
-
-Physical Device Driver Interface
---------------------------------
-
-The physical device driver interface provides the mdev_parent_ops[3] structure
-to define the APIs to manage work in the mediated core driver that is related
-to the physical device.
-
-The structures in the mdev_parent_ops structure are as follows:
-
-* dev_attr_groups: attributes of the parent device
-* mdev_attr_groups: attributes of the mediated device
-* supported_config: attributes to define supported configurations
-* device_driver: device driver to bind for mediated device instances
+The mediated bus driver's probe function should create a vfio_device on top of
+the mdev_device and connect it to an appropriate implementation of
+vfio_device_ops.

When a driver wants to add the GUID creation sysfs to an existing device it has
probe'd to then it should call::

extern int mdev_register_device(struct device *dev,
- const struct mdev_parent_ops *ops);
+ struct mdev_driver *mdev_driver);

This will provide the 'mdev_supported_types/XX/create' files which can then be
used to trigger the creation of a mdev_device. The created mdev_device will be
diff --git a/drivers/gpu/drm/i915/gvt/kvmgt.c b/drivers/gpu/drm/i915/gvt/kvmgt.c
index f033031c676da..0787ba5c301f5 100644
--- a/drivers/gpu/drm/i915/gvt/kvmgt.c
+++ b/drivers/gpu/drm/i915/gvt/kvmgt.c
@@ -1723,12 +1723,7 @@ static struct mdev_driver intel_vgpu_mdev_driver = {
},
.probe = intel_vgpu_probe,
.remove = intel_vgpu_remove,
-};
-
-static const struct mdev_parent_ops intel_vgpu_mdev_ops = {
- .owner = THIS_MODULE,
.supported_type_groups = gvt_vgpu_type_groups,
- .device_driver = &intel_vgpu_mdev_driver,
};

int intel_gvt_page_track_add(struct intel_vgpu *info, u64 gfn)
@@ -2131,7 +2126,7 @@ static int intel_gvt_init_device(struct drm_i915_private *i915)
if (ret)
goto out_destroy_idle_vgpu;

- ret = mdev_register_device(i915->drm.dev, &intel_vgpu_mdev_ops);
+ ret = mdev_register_device(i915->drm.dev, &intel_vgpu_mdev_driver);
if (ret)
goto out_cleanup_vgpu_type_groups;

diff --git a/drivers/s390/cio/vfio_ccw_ops.c b/drivers/s390/cio/vfio_ccw_ops.c
index d8589afac272f..c4d60cdbf247b 100644
--- a/drivers/s390/cio/vfio_ccw_ops.c
+++ b/drivers/s390/cio/vfio_ccw_ops.c
@@ -656,17 +656,12 @@ struct mdev_driver vfio_ccw_mdev_driver = {
},
.probe = vfio_ccw_mdev_probe,
.remove = vfio_ccw_mdev_remove,
-};
-
-static const struct mdev_parent_ops vfio_ccw_mdev_ops = {
- .owner = THIS_MODULE,
- .device_driver = &vfio_ccw_mdev_driver,
.supported_type_groups = mdev_type_groups,
};

int vfio_ccw_mdev_reg(struct subchannel *sch)
{
- return mdev_register_device(&sch->dev, &vfio_ccw_mdev_ops);
+ return mdev_register_device(&sch->dev, &vfio_ccw_mdev_driver);
}

void vfio_ccw_mdev_unreg(struct subchannel *sch)
diff --git a/drivers/s390/crypto/vfio_ap_ops.c b/drivers/s390/crypto/vfio_ap_ops.c
index 6e08d04b605d6..ee0a3bf8f476c 100644
--- a/drivers/s390/crypto/vfio_ap_ops.c
+++ b/drivers/s390/crypto/vfio_ap_ops.c
@@ -1496,12 +1496,7 @@ static struct mdev_driver vfio_ap_matrix_driver = {
},
.probe = vfio_ap_mdev_probe,
.remove = vfio_ap_mdev_remove,
-};
-
-static const struct mdev_parent_ops vfio_ap_matrix_ops = {
- .owner = THIS_MODULE,
- .device_driver = &vfio_ap_matrix_driver,
- .supported_type_groups = vfio_ap_mdev_type_groups,
+ .supported_type_groups = vfio_ap_mdev_type_groups,
};

int vfio_ap_mdev_register(void)
@@ -1514,7 +1509,7 @@ int vfio_ap_mdev_register(void)
if (ret)
return ret;

- ret = mdev_register_device(&matrix_dev->device, &vfio_ap_matrix_ops);
+ ret = mdev_register_device(&matrix_dev->device, &vfio_ap_matrix_driver);
if (ret)
goto err_driver;
return 0;
diff --git a/drivers/vfio/mdev/mdev_core.c b/drivers/vfio/mdev/mdev_core.c
index 8b1e86b9e8bc0..19a20ff420b7f 100644
--- a/drivers/vfio/mdev/mdev_core.c
+++ b/drivers/vfio/mdev/mdev_core.c
@@ -109,12 +109,12 @@ static int mdev_device_remove_cb(struct device *dev, void *data)
/*
* mdev_register_device : Register a device
* @dev: device structure representing parent device.
- * @ops: Parent device operation structure to be registered.
+ * @mdev_driver: Device driver to bind to the newly created mdev
*
* Add device to list of registered parent devices.
* Returns a negative value on error, otherwise 0.
*/
-int mdev_register_device(struct device *dev, const struct mdev_parent_ops *ops)
+int mdev_register_device(struct device *dev, struct mdev_driver *mdev_driver)
{
int ret;
struct mdev_parent *parent;
@@ -122,9 +122,7 @@ int mdev_register_device(struct device *dev, const struct mdev_parent_ops *ops)
char *envp[] = { env_string, NULL };

/* check for mandatory ops */
- if (!ops || !ops->supported_type_groups)
- return -EINVAL;
- if (!ops->device_driver)
+ if (!mdev_driver->supported_type_groups)
return -EINVAL;

dev = get_device(dev);
@@ -151,7 +149,7 @@ int mdev_register_device(struct device *dev, const struct mdev_parent_ops *ops)
init_rwsem(&parent->unreg_sem);

parent->dev = dev;
- parent->ops = ops;
+ parent->mdev_driver = mdev_driver;

if (!mdev_bus_compat_class) {
mdev_bus_compat_class = class_compat_register("mdev_bus");
@@ -249,7 +247,7 @@ int mdev_device_create(struct mdev_type *type, const guid_t *uuid)
int ret;
struct mdev_device *mdev, *tmp;
struct mdev_parent *parent = type->parent;
- struct mdev_driver *drv = parent->ops->device_driver;
+ struct mdev_driver *drv = parent->mdev_driver;

mutex_lock(&mdev_list_lock);

@@ -271,7 +269,6 @@ int mdev_device_create(struct mdev_type *type, const guid_t *uuid)
mdev->dev.parent = parent->dev;
mdev->dev.bus = &mdev_bus_type;
mdev->dev.release = mdev_device_release;
- mdev->dev.groups = parent->ops->mdev_attr_groups;
mdev->type = type;
/* Pairs with the put in mdev_device_release() */
kobject_get(&type->kobj);
diff --git a/drivers/vfio/mdev/mdev_private.h b/drivers/vfio/mdev/mdev_private.h
index 6999c89db7b16..5a7ffd4e770fd 100644
--- a/drivers/vfio/mdev/mdev_private.h
+++ b/drivers/vfio/mdev/mdev_private.h
@@ -15,7 +15,7 @@ void mdev_bus_unregister(void);

struct mdev_parent {
struct device *dev;
- const struct mdev_parent_ops *ops;
+ struct mdev_driver *mdev_driver;
struct kref ref;
struct list_head next;
struct kset *mdev_types_kset;
diff --git a/drivers/vfio/mdev/mdev_sysfs.c b/drivers/vfio/mdev/mdev_sysfs.c
index 66eef08833a4e..5a3873d1a275a 100644
--- a/drivers/vfio/mdev/mdev_sysfs.c
+++ b/drivers/vfio/mdev/mdev_sysfs.c
@@ -97,7 +97,7 @@ static struct mdev_type *add_mdev_supported_type(struct mdev_parent *parent,
{
struct mdev_type *type;
struct attribute_group *group =
- parent->ops->supported_type_groups[type_group_id];
+ parent->mdev_driver->supported_type_groups[type_group_id];
int ret;

if (!group->name) {
@@ -154,7 +154,7 @@ static struct mdev_type *add_mdev_supported_type(struct mdev_parent *parent,
static void remove_mdev_supported_type(struct mdev_type *type)
{
struct attribute_group *group =
- type->parent->ops->supported_type_groups[type->type_group_id];
+ type->parent->mdev_driver->supported_type_groups[type->type_group_id];

sysfs_remove_files(&type->kobj,
(const struct attribute **)group->attrs);
@@ -168,7 +168,7 @@ static int add_mdev_supported_type_groups(struct mdev_parent *parent)
{
int i;

- for (i = 0; parent->ops->supported_type_groups[i]; i++) {
+ for (i = 0; parent->mdev_driver->supported_type_groups[i]; i++) {
struct mdev_type *type;

type = add_mdev_supported_type(parent, i);
diff --git a/include/linux/mdev.h b/include/linux/mdev.h
index 69df1fa2cb6f9..1f6f57a3c3168 100644
--- a/include/linux/mdev.h
+++ b/include/linux/mdev.h
@@ -30,26 +30,6 @@ unsigned int mdev_get_type_group_id(struct mdev_device *mdev);
unsigned int mtype_get_type_group_id(struct mdev_type *mtype);
struct device *mtype_get_parent_dev(struct mdev_type *mtype);

-/**
- * struct mdev_parent_ops - Structure to be registered for each parent device to
- * register the device to mdev module.
- *
- * @owner: The module owner.
- * @device_driver: Which device driver to probe() on newly created devices
- * @mdev_attr_groups: Attributes of the mediated device.
- * @supported_type_groups: Attributes to define supported types. It is mandatory
- * to provide supported types.
- *
- * Parent device that support mediated device should be registered with mdev
- * module with mdev_parent_ops structure.
- **/
-struct mdev_parent_ops {
- struct module *owner;
- struct mdev_driver *device_driver;
- const struct attribute_group **mdev_attr_groups;
- struct attribute_group **supported_type_groups;
-};
-
/* interface for exporting mdev supported type attributes */
struct mdev_type_attribute {
struct attribute attr;
@@ -74,12 +54,15 @@ struct mdev_type_attribute mdev_type_attr_##_name = \
* struct mdev_driver - Mediated device driver
* @probe: called when new device created
* @remove: called when device removed
+ * @supported_type_groups: Attributes to define supported types. It is mandatory
+ * to provide supported types.
* @driver: device driver structure
*
**/
struct mdev_driver {
int (*probe)(struct mdev_device *dev);
void (*remove)(struct mdev_device *dev);
+ struct attribute_group **supported_type_groups;
struct device_driver driver;
};

@@ -98,7 +81,7 @@ static inline const guid_t *mdev_uuid(struct mdev_device *mdev)

extern struct bus_type mdev_bus_type;

-int mdev_register_device(struct device *dev, const struct mdev_parent_ops *ops);
+int mdev_register_device(struct device *dev, struct mdev_driver *mdev_driver);
void mdev_unregister_device(struct device *dev);

int mdev_register_driver(struct mdev_driver *drv);
diff --git a/samples/vfio-mdev/mbochs.c b/samples/vfio-mdev/mbochs.c
index e90c8552cc312..344c2901a82bf 100644
--- a/samples/vfio-mdev/mbochs.c
+++ b/samples/vfio-mdev/mbochs.c
@@ -1412,12 +1412,7 @@ static struct mdev_driver mbochs_driver = {
},
.probe = mbochs_probe,
.remove = mbochs_remove,
-};
-
-static const struct mdev_parent_ops mdev_fops = {
- .owner = THIS_MODULE,
- .device_driver = &mbochs_driver,
- .supported_type_groups = mdev_type_groups,
+ .supported_type_groups = mdev_type_groups,
};

static const struct file_operations vd_fops = {
@@ -1462,7 +1457,7 @@ static int __init mbochs_dev_init(void)
if (ret)
goto err_class;

- ret = mdev_register_device(&mbochs_dev, &mdev_fops);
+ ret = mdev_register_device(&mbochs_dev, &mbochs_driver);
if (ret)
goto err_device;

diff --git a/samples/vfio-mdev/mdpy.c b/samples/vfio-mdev/mdpy.c
index fe5d43e797b6d..e8c46eb2e2468 100644
--- a/samples/vfio-mdev/mdpy.c
+++ b/samples/vfio-mdev/mdpy.c
@@ -723,12 +723,7 @@ static struct mdev_driver mdpy_driver = {
},
.probe = mdpy_probe,
.remove = mdpy_remove,
-};
-
-static const struct mdev_parent_ops mdev_fops = {
- .owner = THIS_MODULE,
- .device_driver = &mdpy_driver,
- .supported_type_groups = mdev_type_groups,
+ .supported_type_groups = mdev_type_groups,
};

static const struct file_operations vd_fops = {
@@ -771,7 +766,7 @@ static int __init mdpy_dev_init(void)
if (ret)
goto err_class;

- ret = mdev_register_device(&mdpy_dev, &mdev_fops);
+ ret = mdev_register_device(&mdpy_dev, &mdpy_driver);
if (ret)
goto err_device;

diff --git a/samples/vfio-mdev/mtty.c b/samples/vfio-mdev/mtty.c
index 4f227dc267859..f42a59ed2e3fe 100644
--- a/samples/vfio-mdev/mtty.c
+++ b/samples/vfio-mdev/mtty.c
@@ -1301,12 +1301,7 @@ static struct mdev_driver mtty_driver = {
},
.probe = mtty_probe,
.remove = mtty_remove,
-};
-
-static const struct mdev_parent_ops mdev_fops = {
- .owner = THIS_MODULE,
- .device_driver = &mtty_driver,
- .supported_type_groups = mdev_type_groups,
+ .supported_type_groups = mdev_type_groups,
};

static void mtty_device_release(struct device *dev)
@@ -1357,7 +1352,7 @@ static int __init mtty_dev_init(void)
if (ret)
goto err_class;

- ret = mdev_register_device(&mtty_dev.dev, &mdev_fops);
+ ret = mdev_register_device(&mtty_dev.dev, &mtty_driver);
if (ret)
goto err_device;
return 0;
--
2.30.2

2022-04-12 22:34:02

by Christoph Hellwig

[permalink] [raw]
Subject: [PATCH 13/34] drm/i915/gvt: devirtualize ->{read,write}_gpa

Just call the VFIO functions directly instead of through the method
table.

Signed-off-by: Christoph Hellwig <[email protected]>
---
drivers/gpu/drm/i915/gvt/cmd_parser.c | 4 +--
drivers/gpu/drm/i915/gvt/execlist.c | 12 ++++-----
drivers/gpu/drm/i915/gvt/gtt.c | 6 ++---
drivers/gpu/drm/i915/gvt/gvt.h | 37 +++++++++++++++++++++++++++
drivers/gpu/drm/i915/gvt/hypercall.h | 4 ---
drivers/gpu/drm/i915/gvt/kvmgt.c | 23 -----------------
drivers/gpu/drm/i915/gvt/mmio.c | 4 +--
drivers/gpu/drm/i915/gvt/mpt.h | 32 -----------------------
drivers/gpu/drm/i915/gvt/opregion.c | 10 +++-----
drivers/gpu/drm/i915/gvt/scheduler.c | 37 +++++++++++++--------------
10 files changed, 72 insertions(+), 97 deletions(-)

diff --git a/drivers/gpu/drm/i915/gvt/cmd_parser.c b/drivers/gpu/drm/i915/gvt/cmd_parser.c
index 2459213b6c87f..b9eb75a2b4002 100644
--- a/drivers/gpu/drm/i915/gvt/cmd_parser.c
+++ b/drivers/gpu/drm/i915/gvt/cmd_parser.c
@@ -1011,7 +1011,7 @@ static int cmd_reg_handler(struct parser_exec_state *s,
if (GRAPHICS_VER(s->engine->i915) == 9 &&
intel_gvt_mmio_is_sr_in_ctx(gvt, offset) &&
!strncmp(cmd, "lri", 3)) {
- intel_gvt_hypervisor_read_gpa(s->vgpu,
+ intel_gvt_read_gpa(s->vgpu,
s->workload->ring_context_gpa + 12, &ctx_sr_ctl, 4);
/* check inhibit context */
if (ctx_sr_ctl & 1) {
@@ -1775,7 +1775,7 @@ static int copy_gma_to_hva(struct intel_vgpu *vgpu, struct intel_vgpu_mm *mm,
copy_len = (end_gma - gma) >= (I915_GTT_PAGE_SIZE - offset) ?
I915_GTT_PAGE_SIZE - offset : end_gma - gma;

- intel_gvt_hypervisor_read_gpa(vgpu, gpa, va + len, copy_len);
+ intel_gvt_read_gpa(vgpu, gpa, va + len, copy_len);

len += copy_len;
gma += copy_len;
diff --git a/drivers/gpu/drm/i915/gvt/execlist.c b/drivers/gpu/drm/i915/gvt/execlist.c
index 66d354c4195b4..274c6ef42400b 100644
--- a/drivers/gpu/drm/i915/gvt/execlist.c
+++ b/drivers/gpu/drm/i915/gvt/execlist.c
@@ -159,12 +159,12 @@ static void emulate_csb_update(struct intel_vgpu_execlist *execlist,
hwsp_gpa = intel_vgpu_gma_to_gpa(vgpu->gtt.ggtt_mm,
vgpu->hws_pga[execlist->engine->id]);
if (hwsp_gpa != INTEL_GVT_INVALID_ADDR) {
- intel_gvt_hypervisor_write_gpa(vgpu,
- hwsp_gpa + I915_HWS_CSB_BUF0_INDEX * 4 + write_pointer * 8,
- status, 8);
- intel_gvt_hypervisor_write_gpa(vgpu,
- hwsp_gpa + INTEL_HWS_CSB_WRITE_INDEX(execlist->engine->i915) * 4,
- &write_pointer, 4);
+ intel_gvt_write_gpa(vgpu,
+ hwsp_gpa + I915_HWS_CSB_BUF0_INDEX * 4 + write_pointer * 8,
+ status, 8);
+ intel_gvt_write_gpa(vgpu,
+ hwsp_gpa + INTEL_HWS_CSB_WRITE_INDEX(execlist->engine->i915) * 4,
+ &write_pointer, 4);
}

gvt_dbg_el("vgpu%d: w pointer %u reg %x csb l %x csb h %x\n",
diff --git a/drivers/gpu/drm/i915/gvt/gtt.c b/drivers/gpu/drm/i915/gvt/gtt.c
index d4082f4b9be19..9b696e5705eb7 100644
--- a/drivers/gpu/drm/i915/gvt/gtt.c
+++ b/drivers/gpu/drm/i915/gvt/gtt.c
@@ -314,7 +314,7 @@ static inline int gtt_get_entry64(void *pt,
return -EINVAL;

if (hypervisor_access) {
- ret = intel_gvt_hypervisor_read_gpa(vgpu, gpa +
+ ret = intel_gvt_read_gpa(vgpu, gpa +
(index << info->gtt_entry_size_shift),
&e->val64, 8);
if (WARN_ON(ret))
@@ -339,7 +339,7 @@ static inline int gtt_set_entry64(void *pt,
return -EINVAL;

if (hypervisor_access) {
- ret = intel_gvt_hypervisor_write_gpa(vgpu, gpa +
+ ret = intel_gvt_write_gpa(vgpu, gpa +
(index << info->gtt_entry_size_shift),
&e->val64, 8);
if (WARN_ON(ret))
@@ -1497,7 +1497,7 @@ static int attach_oos_page(struct intel_vgpu_oos_page *oos_page,
struct intel_gvt *gvt = spt->vgpu->gvt;
int ret;

- ret = intel_gvt_hypervisor_read_gpa(spt->vgpu,
+ ret = intel_gvt_read_gpa(spt->vgpu,
spt->guest_page.gfn << I915_GTT_PAGE_SHIFT,
oos_page->mem, I915_GTT_PAGE_SIZE);
if (ret)
diff --git a/drivers/gpu/drm/i915/gvt/gvt.h b/drivers/gpu/drm/i915/gvt/gvt.h
index cda70ea3d1747..ea07f45138056 100644
--- a/drivers/gpu/drm/i915/gvt/gvt.h
+++ b/drivers/gpu/drm/i915/gvt/gvt.h
@@ -35,6 +35,7 @@

#include <uapi/linux/pci_regs.h>
#include <linux/kvm_host.h>
+#include <linux/vfio.h>

#include "i915_drv.h"
#include "intel_gvt.h"
@@ -720,6 +721,42 @@ static inline bool intel_gvt_mmio_is_cmd_write_patch(
return gvt->mmio.mmio_attribute[offset >> 2] & F_CMD_WRITE_PATCH;
}

+/**
+ * intel_gvt_read_gpa - copy data from GPA to host data buffer
+ * @vgpu: a vGPU
+ * @gpa: guest physical address
+ * @buf: host data buffer
+ * @len: data length
+ *
+ * Returns:
+ * Zero on success, negative error code if failed.
+ */
+static inline int intel_gvt_read_gpa(struct intel_vgpu *vgpu, unsigned long gpa,
+ void *buf, unsigned long len)
+{
+ if (!vgpu->attached)
+ return -ESRCH;
+ return vfio_dma_rw(vgpu->vfio_group, gpa, buf, len, false);
+}
+
+/**
+ * intel_gvt_write_gpa - copy data from host data buffer to GPA
+ * @vgpu: a vGPU
+ * @gpa: guest physical address
+ * @buf: host data buffer
+ * @len: data length
+ *
+ * Returns:
+ * Zero on success, negative error code if failed.
+ */
+static inline int intel_gvt_write_gpa(struct intel_vgpu *vgpu,
+ unsigned long gpa, void *buf, unsigned long len)
+{
+ if (!vgpu->attached)
+ return -ESRCH;
+ return vfio_dma_rw(vgpu->vfio_group, gpa, buf, len, true);
+}
+
void intel_gvt_debugfs_remove_vgpu(struct intel_vgpu *vgpu);
void intel_gvt_debugfs_init(struct intel_gvt *gvt);
void intel_gvt_debugfs_clean(struct intel_gvt *gvt);
diff --git a/drivers/gpu/drm/i915/gvt/hypercall.h b/drivers/gpu/drm/i915/gvt/hypercall.h
index 9f04757598251..61e493e2de852 100644
--- a/drivers/gpu/drm/i915/gvt/hypercall.h
+++ b/drivers/gpu/drm/i915/gvt/hypercall.h
@@ -49,10 +49,6 @@ struct intel_gvt_mpt {
int (*inject_msi)(struct intel_vgpu *vgpu, u32 addr, u16 data);
int (*enable_page_track)(struct intel_vgpu *vgpu, u64 gfn);
int (*disable_page_track)(struct intel_vgpu *vgpu, u64 gfn);
- int (*read_gpa)(struct intel_vgpu *vgpu, unsigned long gpa, void *buf,
- unsigned long len);
- int (*write_gpa)(struct intel_vgpu *vgpu, unsigned long gpa, void *buf,
- unsigned long len);
unsigned long (*gfn_to_mfn)(struct intel_vgpu *vgpu, unsigned long gfn);

int (*dma_map_guest_page)(struct intel_vgpu *vgpu, unsigned long gfn,
diff --git a/drivers/gpu/drm/i915/gvt/kvmgt.c b/drivers/gpu/drm/i915/gvt/kvmgt.c
index ed010ab13310b..e4e3d0cc66fc8 100644
--- a/drivers/gpu/drm/i915/gvt/kvmgt.c
+++ b/drivers/gpu/drm/i915/gvt/kvmgt.c
@@ -39,7 +39,6 @@
#include <linux/spinlock.h>
#include <linux/eventfd.h>
#include <linux/uuid.h>
-#include <linux/vfio.h>
#include <linux/mdev.h>
#include <linux/debugfs.h>

@@ -2024,26 +2023,6 @@ static void kvmgt_dma_unmap_guest_page(struct intel_vgpu *vgpu,
mutex_unlock(&vgpu->cache_lock);
}

-static int kvmgt_rw_gpa(struct intel_vgpu *vgpu, unsigned long gpa,
- void *buf, unsigned long len, bool write)
-{
- if (!vgpu->attached)
- return -ESRCH;
- return vfio_dma_rw(vgpu->vfio_group, gpa, buf, len, write);
-}
-
-static int kvmgt_read_gpa(struct intel_vgpu *vgpu, unsigned long gpa,
- void *buf, unsigned long len)
-{
- return kvmgt_rw_gpa(vgpu, gpa, buf, len, false);
-}
-
-static int kvmgt_write_gpa(struct intel_vgpu *vgpu, unsigned long gpa,
- void *buf, unsigned long len)
-{
- return kvmgt_rw_gpa(vgpu, gpa, buf, len, true);
-}
-
static bool kvmgt_is_valid_gfn(struct intel_vgpu *vgpu, unsigned long gfn)
{
struct kvm *kvm = vgpu->kvm;
@@ -2067,8 +2046,6 @@ static const struct intel_gvt_mpt kvmgt_mpt = {
.inject_msi = kvmgt_inject_msi,
.enable_page_track = kvmgt_page_track_add,
.disable_page_track = kvmgt_page_track_remove,
- .read_gpa = kvmgt_read_gpa,
- .write_gpa = kvmgt_write_gpa,
.gfn_to_mfn = kvmgt_gfn_to_pfn,
.dma_map_guest_page = kvmgt_dma_map_guest_page,
.dma_unmap_guest_page = kvmgt_dma_unmap_guest_page,
diff --git a/drivers/gpu/drm/i915/gvt/mmio.c b/drivers/gpu/drm/i915/gvt/mmio.c
index 5db0ef83d5227..9acc00505fde1 100644
--- a/drivers/gpu/drm/i915/gvt/mmio.c
+++ b/drivers/gpu/drm/i915/gvt/mmio.c
@@ -139,7 +139,7 @@ int intel_vgpu_emulate_mmio_read(struct intel_vgpu *vgpu, u64 pa,
}

if (drm_WARN_ON_ONCE(&i915->drm, !reg_is_mmio(gvt, offset))) {
- ret = intel_gvt_hypervisor_read_gpa(vgpu, pa, p_data, bytes);
+ ret = intel_gvt_read_gpa(vgpu, pa, p_data, bytes);
goto out;
}

@@ -215,7 +215,7 @@ int intel_vgpu_emulate_mmio_write(struct intel_vgpu *vgpu, u64 pa,
}

if (drm_WARN_ON_ONCE(&i915->drm, !reg_is_mmio(gvt, offset))) {
- ret = intel_gvt_hypervisor_write_gpa(vgpu, pa, p_data, bytes);
+ ret = intel_gvt_write_gpa(vgpu, pa, p_data, bytes);
goto out;
}

diff --git a/drivers/gpu/drm/i915/gvt/mpt.h b/drivers/gpu/drm/i915/gvt/mpt.h
index ba0c31c4a705c..72388ceec5966 100644
--- a/drivers/gpu/drm/i915/gvt/mpt.h
+++ b/drivers/gpu/drm/i915/gvt/mpt.h
@@ -152,38 +152,6 @@ static inline int intel_gvt_hypervisor_disable_page_track(
return intel_gvt_host.mpt->disable_page_track(vgpu, gfn);
}

-/**
- * intel_gvt_hypervisor_read_gpa - copy data from GPA to host data buffer
- * @vgpu: a vGPU
- * @gpa: guest physical address
- * @buf: host data buffer
- * @len: data length
- *
- * Returns:
- * Zero on success, negative error code if failed.
- */
-static inline int intel_gvt_hypervisor_read_gpa(struct intel_vgpu *vgpu,
- unsigned long gpa, void *buf, unsigned long len)
-{
- return intel_gvt_host.mpt->read_gpa(vgpu, gpa, buf, len);
-}
-
-/**
- * intel_gvt_hypervisor_write_gpa - copy data from host data buffer to GPA
- * @vgpu: a vGPU
- * @gpa: guest physical address
- * @buf: host data buffer
- * @len: data length
- *
- * Returns:
- * Zero on success, negative error code if failed.
- */
-static inline int intel_gvt_hypervisor_write_gpa(struct intel_vgpu *vgpu,
- unsigned long gpa, void *buf, unsigned long len)
-{
- return intel_gvt_host.mpt->write_gpa(vgpu, gpa, buf, len);
-}
-
/**
* intel_gvt_hypervisor_gfn_to_mfn - translate a GFN to MFN
* @vgpu: a vGPU
diff --git a/drivers/gpu/drm/i915/gvt/opregion.c b/drivers/gpu/drm/i915/gvt/opregion.c
index 286ac6d7c6ced..d2bed466540ab 100644
--- a/drivers/gpu/drm/i915/gvt/opregion.c
+++ b/drivers/gpu/drm/i915/gvt/opregion.c
@@ -421,14 +421,14 @@ int intel_vgpu_emulate_opregion_request(struct intel_vgpu *vgpu, u32 swsci)
INTEL_GVT_OPREGION_SCIC;
parm_pa = (vgpu_opregion(vgpu)->gfn[0] << PAGE_SHIFT) +
INTEL_GVT_OPREGION_PARM;
- ret = intel_gvt_hypervisor_read_gpa(vgpu, scic_pa, &scic, sizeof(scic));
+ ret = intel_gvt_read_gpa(vgpu, scic_pa, &scic, sizeof(scic));
if (ret) {
gvt_vgpu_err("guest opregion read error %d, gpa 0x%llx, len %lu\n",
ret, scic_pa, sizeof(scic));
return ret;
}

- ret = intel_gvt_hypervisor_read_gpa(vgpu, parm_pa, &parm, sizeof(parm));
+ ret = intel_gvt_read_gpa(vgpu, parm_pa, &parm, sizeof(parm));
if (ret) {
gvt_vgpu_err("guest opregion read error %d, gpa 0x%llx, len %lu\n",
ret, scic_pa, sizeof(scic));
@@ -465,16 +465,14 @@ int intel_vgpu_emulate_opregion_request(struct intel_vgpu *vgpu, u32 swsci)
parm = 0;

out:
- ret = intel_gvt_hypervisor_write_gpa(vgpu, scic_pa, &scic,
- sizeof(scic));
+ ret = intel_gvt_write_gpa(vgpu, scic_pa, &scic, sizeof(scic));
if (ret) {
gvt_vgpu_err("guest opregion write error %d, gpa 0x%llx, len %lu\n",
ret, scic_pa, sizeof(scic));
return ret;
}

- ret = intel_gvt_hypervisor_write_gpa(vgpu, parm_pa, &parm,
- sizeof(parm));
+ ret = intel_gvt_write_gpa(vgpu, parm_pa, &parm, sizeof(parm));
if (ret) {
gvt_vgpu_err("guest opregion write error %d, gpa 0x%llx, len %lu\n",
ret, scic_pa, sizeof(scic));
diff --git a/drivers/gpu/drm/i915/gvt/scheduler.c b/drivers/gpu/drm/i915/gvt/scheduler.c
index 679476da06401..d6fe94cd0fdb6 100644
--- a/drivers/gpu/drm/i915/gvt/scheduler.c
+++ b/drivers/gpu/drm/i915/gvt/scheduler.c
@@ -150,10 +150,10 @@ static int populate_shadow_context(struct intel_vgpu_workload *workload)

sr_oa_regs(workload, (u32 *)shadow_ring_context, true);
#define COPY_REG(name) \
- intel_gvt_hypervisor_read_gpa(vgpu, workload->ring_context_gpa \
+ intel_gvt_read_gpa(vgpu, workload->ring_context_gpa \
+ RING_CTX_OFF(name.val), &shadow_ring_context->name.val, 4)
#define COPY_REG_MASKED(name) {\
- intel_gvt_hypervisor_read_gpa(vgpu, workload->ring_context_gpa \
+ intel_gvt_read_gpa(vgpu, workload->ring_context_gpa \
+ RING_CTX_OFF(name.val),\
&shadow_ring_context->name.val, 4);\
shadow_ring_context->name.val |= 0xffff << 16;\
@@ -167,7 +167,7 @@ static int populate_shadow_context(struct intel_vgpu_workload *workload)
COPY_REG(rcs_indirect_ctx);
COPY_REG(rcs_indirect_ctx_offset);
} else if (workload->engine->id == BCS0)
- intel_gvt_hypervisor_read_gpa(vgpu,
+ intel_gvt_read_gpa(vgpu,
workload->ring_context_gpa +
BCS_TILE_REGISTER_VAL_OFFSET,
(void *)shadow_ring_context +
@@ -178,7 +178,7 @@ static int populate_shadow_context(struct intel_vgpu_workload *workload)
/* don't copy Ring Context (the first 0x50 dwords),
* only copy the Engine Context part from guest
*/
- intel_gvt_hypervisor_read_gpa(vgpu,
+ intel_gvt_read_gpa(vgpu,
workload->ring_context_gpa +
RING_CTX_SIZE,
(void *)shadow_ring_context +
@@ -245,7 +245,7 @@ static int populate_shadow_context(struct intel_vgpu_workload *workload)
continue;

read:
- intel_gvt_hypervisor_read_gpa(vgpu, gpa_base, dst, gpa_size);
+ intel_gvt_read_gpa(vgpu, gpa_base, dst, gpa_size);
gpa_base = context_gpa;
gpa_size = I915_GTT_PAGE_SIZE;
dst = context_base + (i << I915_GTT_PAGE_SHIFT);
@@ -911,8 +911,7 @@ static void update_guest_pdps(struct intel_vgpu *vgpu,
gpa = ring_context_gpa + RING_CTX_OFF(pdps[0].val);

for (i = 0; i < 8; i++)
- intel_gvt_hypervisor_write_gpa(vgpu,
- gpa + i * 8, &pdp[7 - i], 4);
+ intel_gvt_write_gpa(vgpu, gpa + i * 8, &pdp[7 - i], 4);
}

static __maybe_unused bool
@@ -1007,13 +1006,13 @@ static void update_guest_context(struct intel_vgpu_workload *workload)
continue;

write:
- intel_gvt_hypervisor_write_gpa(vgpu, gpa_base, src, gpa_size);
+ intel_gvt_write_gpa(vgpu, gpa_base, src, gpa_size);
gpa_base = context_gpa;
gpa_size = I915_GTT_PAGE_SIZE;
src = context_base + (i << I915_GTT_PAGE_SHIFT);
}

- intel_gvt_hypervisor_write_gpa(vgpu, workload->ring_context_gpa +
+ intel_gvt_write_gpa(vgpu, workload->ring_context_gpa +
RING_CTX_OFF(ring_header.val), &workload->rb_tail, 4);

shadow_ring_context = (void *) ctx->lrc_reg_state;
@@ -1028,7 +1027,7 @@ static void update_guest_context(struct intel_vgpu_workload *workload)
}

#define COPY_REG(name) \
- intel_gvt_hypervisor_write_gpa(vgpu, workload->ring_context_gpa + \
+ intel_gvt_write_gpa(vgpu, workload->ring_context_gpa + \
RING_CTX_OFF(name.val), &shadow_ring_context->name.val, 4)

COPY_REG(ctx_ctrl);
@@ -1036,7 +1035,7 @@ static void update_guest_context(struct intel_vgpu_workload *workload)

#undef COPY_REG

- intel_gvt_hypervisor_write_gpa(vgpu,
+ intel_gvt_write_gpa(vgpu,
workload->ring_context_gpa +
sizeof(*shadow_ring_context),
(void *)shadow_ring_context +
@@ -1573,7 +1572,7 @@ static void read_guest_pdps(struct intel_vgpu *vgpu,
gpa = ring_context_gpa + RING_CTX_OFF(pdps[0].val);

for (i = 0; i < 8; i++)
- intel_gvt_hypervisor_read_gpa(vgpu,
+ intel_gvt_read_gpa(vgpu,
gpa + i * 8, &pdp[7 - i], 4);
}

@@ -1644,10 +1643,10 @@ intel_vgpu_create_workload(struct intel_vgpu *vgpu,
return ERR_PTR(-EINVAL);
}

- intel_gvt_hypervisor_read_gpa(vgpu, ring_context_gpa +
+ intel_gvt_read_gpa(vgpu, ring_context_gpa +
RING_CTX_OFF(ring_header.val), &head, 4);

- intel_gvt_hypervisor_read_gpa(vgpu, ring_context_gpa +
+ intel_gvt_read_gpa(vgpu, ring_context_gpa +
RING_CTX_OFF(ring_tail.val), &tail, 4);

guest_head = head;
@@ -1674,11 +1673,11 @@ intel_vgpu_create_workload(struct intel_vgpu *vgpu,
gvt_dbg_el("ring %s begin a new workload\n", engine->name);

/* record some ring buffer register values for scan and shadow */
- intel_gvt_hypervisor_read_gpa(vgpu, ring_context_gpa +
+ intel_gvt_read_gpa(vgpu, ring_context_gpa +
RING_CTX_OFF(rb_start.val), &start, 4);
- intel_gvt_hypervisor_read_gpa(vgpu, ring_context_gpa +
+ intel_gvt_read_gpa(vgpu, ring_context_gpa +
RING_CTX_OFF(rb_ctrl.val), &ctl, 4);
- intel_gvt_hypervisor_read_gpa(vgpu, ring_context_gpa +
+ intel_gvt_read_gpa(vgpu, ring_context_gpa +
RING_CTX_OFF(ctx_ctrl.val), &ctx_ctl, 4);

if (!intel_gvt_ggtt_validate_range(vgpu, start,
@@ -1701,9 +1700,9 @@ intel_vgpu_create_workload(struct intel_vgpu *vgpu,
workload->rb_ctl = ctl;

if (engine->id == RCS0) {
- intel_gvt_hypervisor_read_gpa(vgpu, ring_context_gpa +
+ intel_gvt_read_gpa(vgpu, ring_context_gpa +
RING_CTX_OFF(bb_per_ctx_ptr.val), &per_ctx, 4);
- intel_gvt_hypervisor_read_gpa(vgpu, ring_context_gpa +
+ intel_gvt_read_gpa(vgpu, ring_context_gpa +
RING_CTX_OFF(rcs_indirect_ctx.val), &indirect_ctx, 4);

workload->wa_ctx.indirect_ctx.guest_gma =
--
2.30.2

2022-04-12 23:12:52

by Jason Gunthorpe

[permalink] [raw]
Subject: Re: [PATCH 03/34] drm/i915/gvt: rename intel_vgpu_ops to intel_vgpu_mdev_ops

On Mon, Apr 11, 2022 at 04:13:32PM +0200, Christoph Hellwig wrote:
> Free the intel_vgpu_ops symbol name for something that fits better.
>
> Signed-off-by: Christoph Hellwig <[email protected]>
> ---
> drivers/gpu/drm/i915/gvt/kvmgt.c | 6 +++---
> 1 file changed, 3 insertions(+), 3 deletions(-)

Reviewed-by: Jason Gunthorpe <[email protected]>

Jason

2022-04-12 23:13:04

by Christoph Hellwig

[permalink] [raw]
Subject: [PATCH 07/34] drm/i915/gvt: remove intel_gvt_ops

Remove these pointless indirect alls by just calling the only instance
of each method directly.

Signed-off-by: Christoph Hellwig <[email protected]>
---
drivers/gpu/drm/i915/gvt/gvt.c | 20 +--------------
drivers/gpu/drm/i915/gvt/gvt.h | 24 ------------------
drivers/gpu/drm/i915/gvt/hypercall.h | 2 +-
drivers/gpu/drm/i915/gvt/kvmgt.c | 37 +++++++++++-----------------
drivers/gpu/drm/i915/gvt/mpt.h | 5 ++--
5 files changed, 19 insertions(+), 69 deletions(-)

diff --git a/drivers/gpu/drm/i915/gvt/gvt.c b/drivers/gpu/drm/i915/gvt/gvt.c
index c3308058f4616..9259f2a17398d 100644
--- a/drivers/gpu/drm/i915/gvt/gvt.c
+++ b/drivers/gpu/drm/i915/gvt/gvt.c
@@ -39,23 +39,6 @@
#include <linux/vfio.h>
#include <linux/mdev.h>

-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_release = intel_gvt_release_vgpu,
- .vgpu_reset = intel_gvt_reset_vgpu,
- .vgpu_activate = intel_gvt_activate_vgpu,
- .vgpu_deactivate = intel_gvt_deactivate_vgpu,
- .vgpu_query_plane = intel_vgpu_query_plane,
- .vgpu_get_dmabuf = intel_vgpu_get_dmabuf,
- .write_protect_handler = intel_vgpu_page_track_handler,
- .emulate_hotplug = intel_vgpu_emulate_hotplug,
-};
-
static void init_device_info(struct intel_gvt *gvt)
{
struct intel_gvt_device_info *info = &gvt->device_info;
@@ -252,8 +235,7 @@ static int intel_gvt_init_device(struct drm_i915_private *i915)

intel_gvt_debugfs_init(gvt);

- ret = intel_gvt_hypervisor_host_init(i915->drm.dev, gvt,
- &intel_gvt_ops);
+ ret = intel_gvt_hypervisor_host_init(i915->drm.dev, gvt);
if (ret)
goto out_destroy_idle_vgpu;

diff --git a/drivers/gpu/drm/i915/gvt/gvt.h b/drivers/gpu/drm/i915/gvt/gvt.h
index dc36a791467b9..97150a1297ebb 100644
--- a/drivers/gpu/drm/i915/gvt/gvt.h
+++ b/drivers/gpu/drm/i915/gvt/gvt.h
@@ -556,30 +556,6 @@ void populate_pvinfo_page(struct intel_vgpu *vgpu);
int intel_gvt_scan_and_shadow_workload(struct intel_vgpu_workload *workload);
void enter_failsafe_mode(struct intel_vgpu *vgpu, int reason);

-struct intel_gvt_ops {
- int (*emulate_cfg_read)(struct intel_vgpu *, unsigned int, void *,
- unsigned int);
- int (*emulate_cfg_write)(struct intel_vgpu *, unsigned int, void *,
- unsigned int);
- int (*emulate_mmio_read)(struct intel_vgpu *, u64, void *,
- unsigned int);
- int (*emulate_mmio_write)(struct intel_vgpu *, u64, void *,
- unsigned int);
- struct intel_vgpu *(*vgpu_create)(struct intel_gvt *,
- struct intel_vgpu_type *);
- void (*vgpu_destroy)(struct intel_vgpu *vgpu);
- void (*vgpu_release)(struct intel_vgpu *vgpu);
- void (*vgpu_reset)(struct intel_vgpu *);
- void (*vgpu_activate)(struct intel_vgpu *);
- void (*vgpu_deactivate)(struct intel_vgpu *);
- int (*vgpu_query_plane)(struct intel_vgpu *vgpu, void *);
- int (*vgpu_get_dmabuf)(struct intel_vgpu *vgpu, unsigned int);
- int (*write_protect_handler)(struct intel_vgpu *, u64, void *,
- unsigned int);
- void (*emulate_hotplug)(struct intel_vgpu *vgpu, bool connected);
-};
-
-
enum {
GVT_FAILSAFE_UNSUPPORTED_GUEST,
GVT_FAILSAFE_INSUFFICIENT_RESOURCE,
diff --git a/drivers/gpu/drm/i915/gvt/hypercall.h b/drivers/gpu/drm/i915/gvt/hypercall.h
index 3179831536458..395bce9633faa 100644
--- a/drivers/gpu/drm/i915/gvt/hypercall.h
+++ b/drivers/gpu/drm/i915/gvt/hypercall.h
@@ -42,7 +42,7 @@ struct device;
* both Xen and KVM by providing dedicated hypervisor-related MPT modules.
*/
struct intel_gvt_mpt {
- int (*host_init)(struct device *dev, void *gvt, const void *ops);
+ int (*host_init)(struct device *dev, void *gvt);
void (*host_exit)(struct device *dev, void *gvt);
int (*attach_vgpu)(void *vgpu, unsigned long *handle);
void (*detach_vgpu)(void *vgpu);
diff --git a/drivers/gpu/drm/i915/gvt/kvmgt.c b/drivers/gpu/drm/i915/gvt/kvmgt.c
index fa8b326eb2197..9ed13c86d4765 100644
--- a/drivers/gpu/drm/i915/gvt/kvmgt.c
+++ b/drivers/gpu/drm/i915/gvt/kvmgt.c
@@ -55,8 +55,6 @@
MODULE_IMPORT_NS(DMA_BUF);
MODULE_IMPORT_NS(I915_GVT);

-static const struct intel_gvt_ops *intel_gvt_ops;
-
/* helper macros copied from vfio-pci */
#define VFIO_PCI_OFFSET_SHIFT 40
#define VFIO_PCI_OFFSET_TO_INDEX(off) (off >> VFIO_PCI_OFFSET_SHIFT)
@@ -621,9 +619,9 @@ static int handle_edid_regs(struct intel_vgpu *vgpu,
gvt_vgpu_err("invalid EDID blob\n");
return -EINVAL;
}
- intel_gvt_ops->emulate_hotplug(vgpu, true);
+ intel_vgpu_emulate_hotplug(vgpu, true);
} else if (data == VFIO_DEVICE_GFX_LINK_STATE_DOWN)
- intel_gvt_ops->emulate_hotplug(vgpu, false);
+ intel_vgpu_emulate_hotplug(vgpu, false);
else {
gvt_vgpu_err("invalid EDID link state %d\n",
regs->link_state);
@@ -825,7 +823,7 @@ static int intel_vgpu_create(struct mdev_device *mdev)
goto out;
}

- vgpu = intel_gvt_ops->vgpu_create(gvt, type);
+ vgpu = intel_gvt_create_vgpu(gvt, type);
if (IS_ERR_OR_NULL(vgpu)) {
ret = vgpu == NULL ? -EFAULT : PTR_ERR(vgpu);
gvt_err("failed to create intel vgpu: %d\n", ret);
@@ -852,7 +850,7 @@ static int intel_vgpu_remove(struct mdev_device *mdev)
if (handle_valid(vgpu->handle))
return -EBUSY;

- intel_gvt_ops->vgpu_destroy(vgpu);
+ intel_gvt_destroy_vgpu(vgpu);
return 0;
}

@@ -955,7 +953,7 @@ static int intel_vgpu_open_device(struct mdev_device *mdev)
if (ret)
goto undo_group;

- intel_gvt_ops->vgpu_activate(vgpu);
+ intel_gvt_activate_vgpu(vgpu);

atomic_set(&vdev->released, 0);
return ret;
@@ -1000,7 +998,7 @@ static void __intel_vgpu_release(struct intel_vgpu *vgpu)
if (atomic_cmpxchg(&vdev->released, 0, 1))
return;

- intel_gvt_ops->vgpu_release(vgpu);
+ intel_gvt_release_vgpu(vgpu);

ret = vfio_unregister_notifier(mdev_dev(vdev->mdev), VFIO_IOMMU_NOTIFY,
&vdev->iommu_notifier);
@@ -1074,10 +1072,10 @@ static int intel_vgpu_bar_rw(struct intel_vgpu *vgpu, int bar, u64 off,
int ret;

if (is_write)
- ret = intel_gvt_ops->emulate_mmio_write(vgpu,
+ ret = intel_vgpu_emulate_mmio_write(vgpu,
bar_start + off, buf, count);
else
- ret = intel_gvt_ops->emulate_mmio_read(vgpu,
+ ret = intel_vgpu_emulate_mmio_read(vgpu,
bar_start + off, buf, count);
return ret;
}
@@ -1133,10 +1131,10 @@ static ssize_t intel_vgpu_rw(struct mdev_device *mdev, char *buf,
switch (index) {
case VFIO_PCI_CONFIG_REGION_INDEX:
if (is_write)
- ret = intel_gvt_ops->emulate_cfg_write(vgpu, pos,
+ ret = intel_vgpu_emulate_cfg_write(vgpu, pos,
buf, count);
else
- ret = intel_gvt_ops->emulate_cfg_read(vgpu, pos,
+ ret = intel_vgpu_emulate_cfg_read(vgpu, pos,
buf, count);
break;
case VFIO_PCI_BAR0_REGION_INDEX:
@@ -1704,7 +1702,7 @@ static long intel_vgpu_ioctl(struct mdev_device *mdev, unsigned int cmd,

return ret;
} else if (cmd == VFIO_DEVICE_RESET) {
- intel_gvt_ops->vgpu_reset(vgpu);
+ intel_gvt_reset_vgpu(vgpu);
return 0;
} else if (cmd == VFIO_DEVICE_QUERY_GFX_PLANE) {
struct vfio_device_gfx_plane_info dmabuf;
@@ -1717,7 +1715,7 @@ static long intel_vgpu_ioctl(struct mdev_device *mdev, unsigned int cmd,
if (dmabuf.argsz < minsz)
return -EINVAL;

- ret = intel_gvt_ops->vgpu_query_plane(vgpu, &dmabuf);
+ ret = intel_vgpu_query_plane(vgpu, &dmabuf);
if (ret != 0)
return ret;

@@ -1725,14 +1723,10 @@ static long intel_vgpu_ioctl(struct mdev_device *mdev, unsigned int cmd,
-EFAULT : 0;
} else if (cmd == VFIO_DEVICE_GET_GFX_DMABUF) {
__u32 dmabuf_id;
- __s32 dmabuf_fd;

if (get_user(dmabuf_id, (__u32 __user *)arg))
return -EFAULT;
-
- dmabuf_fd = intel_gvt_ops->vgpu_get_dmabuf(vgpu, dmabuf_id);
- return dmabuf_fd;
-
+ return intel_vgpu_get_dmabuf(vgpu, dmabuf_id);
}

return -ENOTTY;
@@ -1783,7 +1777,7 @@ static struct mdev_parent_ops intel_vgpu_mdev_ops = {
.ioctl = intel_vgpu_ioctl,
};

-static int kvmgt_host_init(struct device *dev, void *gvt, const void *ops)
+static int kvmgt_host_init(struct device *dev, void *gvt)
{
int ret;

@@ -1791,7 +1785,6 @@ static int kvmgt_host_init(struct device *dev, void *gvt, const void *ops)
if (ret)
return ret;

- intel_gvt_ops = ops;
intel_vgpu_mdev_ops.supported_type_groups = gvt_vgpu_type_groups;

ret = mdev_register_device(dev, &intel_vgpu_mdev_ops);
@@ -1883,7 +1876,7 @@ static void kvmgt_page_track_write(struct kvm_vcpu *vcpu, gpa_t gpa,
struct kvmgt_guest_info, track_node);

if (kvmgt_gfn_is_write_protected(info, gpa_to_gfn(gpa)))
- intel_gvt_ops->write_protect_handler(info->vgpu, gpa,
+ intel_vgpu_page_track_handler(info->vgpu, gpa,
(void *)val, len);
}

diff --git a/drivers/gpu/drm/i915/gvt/mpt.h b/drivers/gpu/drm/i915/gvt/mpt.h
index 1b5617bb27450..0e3966e1fec8b 100644
--- a/drivers/gpu/drm/i915/gvt/mpt.h
+++ b/drivers/gpu/drm/i915/gvt/mpt.h
@@ -51,13 +51,12 @@
* Returns:
* Zero on success, negative error code if failed
*/
-static inline int intel_gvt_hypervisor_host_init(struct device *dev,
- void *gvt, const void *ops)
+static inline int intel_gvt_hypervisor_host_init(struct device *dev, void *gvt)
{
if (!intel_gvt_host.mpt->host_init)
return -ENODEV;

- return intel_gvt_host.mpt->host_init(dev, gvt, ops);
+ return intel_gvt_host.mpt->host_init(dev, gvt);
}

/**
--
2.30.2

2022-04-12 23:19:00

by Kirti Wankhede

[permalink] [raw]
Subject: Re: [PATCH 32/34] vfio/mdev: Remove mdev_parent_ops



On 4/11/2022 7:44 PM, Christoph Hellwig wrote:
> From: Jason Gunthorpe <[email protected]>
>
> The last useful member in this struct is the supported_type_groups, move
> it to the mdev_driver and delete mdev_parent_ops.
>
> Replace it with mdev_driver as an argument to mdev_register_device()
>
> Signed-off-by: Jason Gunthorpe <[email protected]>
> Signed-off-by: Christoph Hellwig <[email protected]>
> ---
> .../driver-api/vfio-mediated-device.rst | 24 ++++--------------
> drivers/gpu/drm/i915/gvt/kvmgt.c | 7 +-----
> drivers/s390/cio/vfio_ccw_ops.c | 7 +-----
> drivers/s390/crypto/vfio_ap_ops.c | 9 ++-----
> drivers/vfio/mdev/mdev_core.c | 13 ++++------
> drivers/vfio/mdev/mdev_private.h | 2 +-
> drivers/vfio/mdev/mdev_sysfs.c | 6 ++---
> include/linux/mdev.h | 25 +++----------------
> samples/vfio-mdev/mbochs.c | 9 ++-----
> samples/vfio-mdev/mdpy.c | 9 ++-----
> samples/vfio-mdev/mtty.c | 9 ++-----
> 11 files changed, 28 insertions(+), 92 deletions(-)
>

Reviewed-by: Kirti Wankhede <[email protected]>

2022-04-12 23:26:56

by Christoph Hellwig

[permalink] [raw]
Subject: [PATCH 10/34] drm/i915/gvt: merge struct kvmgt_vdev into struct intel_vgpu

Move towards having only a single structure for the per-VGPU state.

Signed-off-by: Christoph Hellwig <[email protected]>
---
drivers/gpu/drm/i915/gvt/gvt.h | 31 ++-
drivers/gpu/drm/i915/gvt/hypercall.h | 1 -
drivers/gpu/drm/i915/gvt/kvmgt.c | 288 ++++++++++-----------------
drivers/gpu/drm/i915/gvt/mpt.h | 16 --
drivers/gpu/drm/i915/gvt/vgpu.c | 8 +-
5 files changed, 128 insertions(+), 216 deletions(-)

diff --git a/drivers/gpu/drm/i915/gvt/gvt.h b/drivers/gpu/drm/i915/gvt/gvt.h
index 97150a1297ebb..628dd686c03d5 100644
--- a/drivers/gpu/drm/i915/gvt/gvt.h
+++ b/drivers/gpu/drm/i915/gvt/gvt.h
@@ -207,21 +207,36 @@ struct intel_vgpu {

struct dentry *debugfs;

- /* Hypervisor-specific device state. */
- void *vdev;
-
struct list_head dmabuf_obj_list_head;
struct mutex dmabuf_lock;
struct idr object_idr;
struct intel_vgpu_vblank_timer vblank_timer;

u32 scan_nonprivbb;
-};

-static inline void *intel_vgpu_vdev(struct intel_vgpu *vgpu)
-{
- return vgpu->vdev;
-}
+ struct mdev_device *mdev;
+ struct vfio_region *region;
+ int num_regions;
+ struct eventfd_ctx *intx_trigger;
+ struct eventfd_ctx *msi_trigger;
+
+ /*
+ * Two caches are used to avoid mapping duplicated pages (eg.
+ * scratch pages). This help to reduce dma setup overhead.
+ */
+ struct rb_root gfn_cache;
+ struct rb_root dma_addr_cache;
+ unsigned long nr_cache_entries;
+ struct mutex cache_lock;
+
+ struct notifier_block iommu_notifier;
+ struct notifier_block group_notifier;
+ struct kvm *kvm;
+ struct work_struct release_work;
+ atomic_t released;
+ struct vfio_device *vfio_device;
+ struct vfio_group *vfio_group;
+};

/* validating GM healthy status*/
#define vgpu_is_vm_unhealthy(ret_val) \
diff --git a/drivers/gpu/drm/i915/gvt/hypercall.h b/drivers/gpu/drm/i915/gvt/hypercall.h
index 27890a5e2d828..eacee6f41f9c7 100644
--- a/drivers/gpu/drm/i915/gvt/hypercall.h
+++ b/drivers/gpu/drm/i915/gvt/hypercall.h
@@ -44,7 +44,6 @@ struct device;
struct intel_gvt_mpt {
int (*host_init)(struct device *dev, void *gvt);
void (*host_exit)(struct device *dev, void *gvt);
- int (*attach_vgpu)(void *vgpu, unsigned long *handle);
void (*detach_vgpu)(void *vgpu);
int (*inject_msi)(unsigned long handle, u32 addr, u16 data);
int (*enable_page_track)(unsigned long handle, u64 gfn);
diff --git a/drivers/gpu/drm/i915/gvt/kvmgt.c b/drivers/gpu/drm/i915/gvt/kvmgt.c
index f7b8ce87bc330..1c2b949d8e01f 100644
--- a/drivers/gpu/drm/i915/gvt/kvmgt.c
+++ b/drivers/gpu/drm/i915/gvt/kvmgt.c
@@ -112,37 +112,6 @@ struct gvt_dma {
struct kref ref;
};

-struct kvmgt_vdev {
- struct intel_vgpu *vgpu;
- struct mdev_device *mdev;
- struct vfio_region *region;
- int num_regions;
- struct eventfd_ctx *intx_trigger;
- struct eventfd_ctx *msi_trigger;
-
- /*
- * Two caches are used to avoid mapping duplicated pages (eg.
- * scratch pages). This help to reduce dma setup overhead.
- */
- struct rb_root gfn_cache;
- struct rb_root dma_addr_cache;
- unsigned long nr_cache_entries;
- struct mutex cache_lock;
-
- struct notifier_block iommu_notifier;
- struct notifier_block group_notifier;
- struct kvm *kvm;
- struct work_struct release_work;
- atomic_t released;
- struct vfio_device *vfio_device;
- struct vfio_group *vfio_group;
-};
-
-static inline struct kvmgt_vdev *kvmgt_vdev(struct intel_vgpu *vgpu)
-{
- return intel_vgpu_vdev(vgpu);
-}
-
static inline bool handle_valid(unsigned long handle)
{
return !!(handle & ~0xff);
@@ -269,7 +238,6 @@ static void gvt_unpin_guest_page(struct intel_vgpu *vgpu, unsigned long gfn,
unsigned long size)
{
struct drm_i915_private *i915 = vgpu->gvt->gt->i915;
- struct kvmgt_vdev *vdev = kvmgt_vdev(vgpu);
int total_pages;
int npage;
int ret;
@@ -279,7 +247,7 @@ static void gvt_unpin_guest_page(struct intel_vgpu *vgpu, unsigned long gfn,
for (npage = 0; npage < total_pages; npage++) {
unsigned long cur_gfn = gfn + npage;

- ret = vfio_group_unpin_pages(vdev->vfio_group, &cur_gfn, 1);
+ ret = vfio_group_unpin_pages(vgpu->vfio_group, &cur_gfn, 1);
drm_WARN_ON(&i915->drm, ret != 1);
}
}
@@ -288,7 +256,6 @@ static void gvt_unpin_guest_page(struct intel_vgpu *vgpu, unsigned long gfn,
static int gvt_pin_guest_page(struct intel_vgpu *vgpu, unsigned long gfn,
unsigned long size, struct page **page)
{
- struct kvmgt_vdev *vdev = kvmgt_vdev(vgpu);
unsigned long base_pfn = 0;
int total_pages;
int npage;
@@ -303,7 +270,7 @@ static int gvt_pin_guest_page(struct intel_vgpu *vgpu, unsigned long gfn,
unsigned long cur_gfn = gfn + npage;
unsigned long pfn;

- ret = vfio_group_pin_pages(vdev->vfio_group, &cur_gfn, 1,
+ ret = vfio_group_pin_pages(vgpu->vfio_group, &cur_gfn, 1,
IOMMU_READ | IOMMU_WRITE, &pfn);
if (ret != 1) {
gvt_vgpu_err("vfio_pin_pages failed for gfn 0x%lx, ret %d\n",
@@ -370,7 +337,7 @@ static void gvt_dma_unmap_page(struct intel_vgpu *vgpu, unsigned long gfn,
static struct gvt_dma *__gvt_cache_find_dma_addr(struct intel_vgpu *vgpu,
dma_addr_t dma_addr)
{
- struct rb_node *node = kvmgt_vdev(vgpu)->dma_addr_cache.rb_node;
+ struct rb_node *node = vgpu->dma_addr_cache.rb_node;
struct gvt_dma *itr;

while (node) {
@@ -388,7 +355,7 @@ static struct gvt_dma *__gvt_cache_find_dma_addr(struct intel_vgpu *vgpu,

static struct gvt_dma *__gvt_cache_find_gfn(struct intel_vgpu *vgpu, gfn_t gfn)
{
- struct rb_node *node = kvmgt_vdev(vgpu)->gfn_cache.rb_node;
+ struct rb_node *node = vgpu->gfn_cache.rb_node;
struct gvt_dma *itr;

while (node) {
@@ -409,7 +376,6 @@ static int __gvt_cache_add(struct intel_vgpu *vgpu, gfn_t gfn,
{
struct gvt_dma *new, *itr;
struct rb_node **link, *parent = NULL;
- struct kvmgt_vdev *vdev = kvmgt_vdev(vgpu);

new = kzalloc(sizeof(struct gvt_dma), GFP_KERNEL);
if (!new)
@@ -422,7 +388,7 @@ static int __gvt_cache_add(struct intel_vgpu *vgpu, gfn_t gfn,
kref_init(&new->ref);

/* gfn_cache maps gfn to struct gvt_dma. */
- link = &vdev->gfn_cache.rb_node;
+ link = &vgpu->gfn_cache.rb_node;
while (*link) {
parent = *link;
itr = rb_entry(parent, struct gvt_dma, gfn_node);
@@ -433,11 +399,11 @@ static int __gvt_cache_add(struct intel_vgpu *vgpu, gfn_t gfn,
link = &parent->rb_right;
}
rb_link_node(&new->gfn_node, parent, link);
- rb_insert_color(&new->gfn_node, &vdev->gfn_cache);
+ rb_insert_color(&new->gfn_node, &vgpu->gfn_cache);

/* dma_addr_cache maps dma addr to struct gvt_dma. */
parent = NULL;
- link = &vdev->dma_addr_cache.rb_node;
+ link = &vgpu->dma_addr_cache.rb_node;
while (*link) {
parent = *link;
itr = rb_entry(parent, struct gvt_dma, dma_addr_node);
@@ -448,51 +414,46 @@ static int __gvt_cache_add(struct intel_vgpu *vgpu, gfn_t gfn,
link = &parent->rb_right;
}
rb_link_node(&new->dma_addr_node, parent, link);
- rb_insert_color(&new->dma_addr_node, &vdev->dma_addr_cache);
+ rb_insert_color(&new->dma_addr_node, &vgpu->dma_addr_cache);

- vdev->nr_cache_entries++;
+ vgpu->nr_cache_entries++;
return 0;
}

static void __gvt_cache_remove_entry(struct intel_vgpu *vgpu,
struct gvt_dma *entry)
{
- struct kvmgt_vdev *vdev = kvmgt_vdev(vgpu);
-
- rb_erase(&entry->gfn_node, &vdev->gfn_cache);
- rb_erase(&entry->dma_addr_node, &vdev->dma_addr_cache);
+ rb_erase(&entry->gfn_node, &vgpu->gfn_cache);
+ rb_erase(&entry->dma_addr_node, &vgpu->dma_addr_cache);
kfree(entry);
- vdev->nr_cache_entries--;
+ vgpu->nr_cache_entries--;
}

static void gvt_cache_destroy(struct intel_vgpu *vgpu)
{
struct gvt_dma *dma;
struct rb_node *node = NULL;
- struct kvmgt_vdev *vdev = kvmgt_vdev(vgpu);

for (;;) {
- mutex_lock(&vdev->cache_lock);
- node = rb_first(&vdev->gfn_cache);
+ mutex_lock(&vgpu->cache_lock);
+ node = rb_first(&vgpu->gfn_cache);
if (!node) {
- mutex_unlock(&vdev->cache_lock);
+ mutex_unlock(&vgpu->cache_lock);
break;
}
dma = rb_entry(node, struct gvt_dma, gfn_node);
gvt_dma_unmap_page(vgpu, dma->gfn, dma->dma_addr, dma->size);
__gvt_cache_remove_entry(vgpu, dma);
- mutex_unlock(&vdev->cache_lock);
+ mutex_unlock(&vgpu->cache_lock);
}
}

static void gvt_cache_init(struct intel_vgpu *vgpu)
{
- struct kvmgt_vdev *vdev = kvmgt_vdev(vgpu);
-
- vdev->gfn_cache = RB_ROOT;
- vdev->dma_addr_cache = RB_ROOT;
- vdev->nr_cache_entries = 0;
- mutex_init(&vdev->cache_lock);
+ vgpu->gfn_cache = RB_ROOT;
+ vgpu->dma_addr_cache = RB_ROOT;
+ vgpu->nr_cache_entries = 0;
+ mutex_init(&vgpu->cache_lock);
}

static void kvmgt_protect_table_init(struct kvmgt_guest_info *info)
@@ -566,18 +527,17 @@ static void kvmgt_protect_table_del(struct kvmgt_guest_info *info,
static size_t intel_vgpu_reg_rw_opregion(struct intel_vgpu *vgpu, char *buf,
size_t count, loff_t *ppos, bool iswrite)
{
- struct kvmgt_vdev *vdev = kvmgt_vdev(vgpu);
unsigned int i = VFIO_PCI_OFFSET_TO_INDEX(*ppos) -
VFIO_PCI_NUM_REGIONS;
- void *base = vdev->region[i].data;
+ void *base = vgpu->region[i].data;
loff_t pos = *ppos & VFIO_PCI_OFFSET_MASK;


- if (pos >= vdev->region[i].size || iswrite) {
+ if (pos >= vgpu->region[i].size || iswrite) {
gvt_vgpu_err("invalid op or offset for Intel vgpu OpRegion\n");
return -EINVAL;
}
- count = min(count, (size_t)(vdev->region[i].size - pos));
+ count = min(count, (size_t)(vgpu->region[i].size - pos));
memcpy(buf, base + pos, count);

return count;
@@ -670,8 +630,7 @@ static size_t intel_vgpu_reg_rw_edid(struct intel_vgpu *vgpu, char *buf,
int ret;
unsigned int i = VFIO_PCI_OFFSET_TO_INDEX(*ppos) -
VFIO_PCI_NUM_REGIONS;
- struct vfio_edid_region *region =
- (struct vfio_edid_region *)kvmgt_vdev(vgpu)->region[i].data;
+ struct vfio_edid_region *region = vgpu->region[i].data;
loff_t pos = *ppos & VFIO_PCI_OFFSET_MASK;

if (pos < region->vfio_edid_regs.edid_offset) {
@@ -703,34 +662,32 @@ static int intel_vgpu_register_reg(struct intel_vgpu *vgpu,
const struct intel_vgpu_regops *ops,
size_t size, u32 flags, void *data)
{
- struct kvmgt_vdev *vdev = kvmgt_vdev(vgpu);
struct vfio_region *region;

- region = krealloc(vdev->region,
- (vdev->num_regions + 1) * sizeof(*region),
+ region = krealloc(vgpu->region,
+ (vgpu->num_regions + 1) * sizeof(*region),
GFP_KERNEL);
if (!region)
return -ENOMEM;

- vdev->region = region;
- vdev->region[vdev->num_regions].type = type;
- vdev->region[vdev->num_regions].subtype = subtype;
- vdev->region[vdev->num_regions].ops = ops;
- vdev->region[vdev->num_regions].size = size;
- vdev->region[vdev->num_regions].flags = flags;
- vdev->region[vdev->num_regions].data = data;
- vdev->num_regions++;
+ vgpu->region = region;
+ vgpu->region[vgpu->num_regions].type = type;
+ vgpu->region[vgpu->num_regions].subtype = subtype;
+ vgpu->region[vgpu->num_regions].ops = ops;
+ vgpu->region[vgpu->num_regions].size = size;
+ vgpu->region[vgpu->num_regions].flags = flags;
+ vgpu->region[vgpu->num_regions].data = data;
+ vgpu->num_regions++;
return 0;
}

static int kvmgt_get_vfio_device(void *p_vgpu)
{
struct intel_vgpu *vgpu = (struct intel_vgpu *)p_vgpu;
- struct kvmgt_vdev *vdev = kvmgt_vdev(vgpu);

- vdev->vfio_device = vfio_device_get_from_dev(
- mdev_dev(vdev->mdev));
- if (!vdev->vfio_device) {
+ vgpu->vfio_device = vfio_device_get_from_dev(
+ mdev_dev(vgpu->mdev));
+ if (!vgpu->vfio_device) {
gvt_vgpu_err("failed to get vfio device\n");
return -ENODEV;
}
@@ -796,14 +753,14 @@ static int kvmgt_set_edid(void *p_vgpu, int port_num)
return ret;
}

-static void kvmgt_put_vfio_device(void *vgpu)
+static void kvmgt_put_vfio_device(void *data)
{
- struct kvmgt_vdev *vdev = kvmgt_vdev((struct intel_vgpu *)vgpu);
+ struct intel_vgpu *vgpu = data;

- if (WARN_ON(!vdev->vfio_device))
+ if (WARN_ON(!vgpu->vfio_device))
return;

- vfio_device_put(vdev->vfio_device);
+ vfio_device_put(vgpu->vfio_device);
}

static int intel_vgpu_create(struct mdev_device *mdev)
@@ -830,9 +787,9 @@ static int intel_vgpu_create(struct mdev_device *mdev)
goto out;
}

- INIT_WORK(&kvmgt_vdev(vgpu)->release_work, intel_vgpu_release_work);
+ INIT_WORK(&vgpu->release_work, intel_vgpu_release_work);

- kvmgt_vdev(vgpu)->mdev = mdev;
+ vgpu->mdev = mdev;
mdev_set_drvdata(mdev, vgpu);

gvt_dbg_core("intel_vgpu_create succeeded for mdev: %s\n",
@@ -857,10 +814,8 @@ static int intel_vgpu_remove(struct mdev_device *mdev)
static int intel_vgpu_iommu_notifier(struct notifier_block *nb,
unsigned long action, void *data)
{
- struct kvmgt_vdev *vdev = container_of(nb,
- struct kvmgt_vdev,
- iommu_notifier);
- struct intel_vgpu *vgpu = vdev->vgpu;
+ struct intel_vgpu *vgpu =
+ container_of(nb, struct intel_vgpu, iommu_notifier);

if (action == VFIO_IOMMU_NOTIFY_DMA_UNMAP) {
struct vfio_iommu_type1_dma_unmap *unmap = data;
@@ -870,7 +825,7 @@ static int intel_vgpu_iommu_notifier(struct notifier_block *nb,
iov_pfn = unmap->iova >> PAGE_SHIFT;
end_iov_pfn = iov_pfn + unmap->size / PAGE_SIZE;

- mutex_lock(&vdev->cache_lock);
+ mutex_lock(&vgpu->cache_lock);
for (; iov_pfn < end_iov_pfn; iov_pfn++) {
entry = __gvt_cache_find_gfn(vgpu, iov_pfn);
if (!entry)
@@ -880,7 +835,7 @@ static int intel_vgpu_iommu_notifier(struct notifier_block *nb,
entry->size);
__gvt_cache_remove_entry(vgpu, entry);
}
- mutex_unlock(&vdev->cache_lock);
+ mutex_unlock(&vgpu->cache_lock);
}

return NOTIFY_OK;
@@ -889,16 +844,15 @@ static int intel_vgpu_iommu_notifier(struct notifier_block *nb,
static int intel_vgpu_group_notifier(struct notifier_block *nb,
unsigned long action, void *data)
{
- struct kvmgt_vdev *vdev = container_of(nb,
- struct kvmgt_vdev,
- group_notifier);
+ struct intel_vgpu *vgpu =
+ container_of(nb, struct intel_vgpu, group_notifier);

/* the only action we care about */
if (action == VFIO_GROUP_NOTIFY_SET_KVM) {
- vdev->kvm = data;
+ vgpu->kvm = data;

if (!data)
- schedule_work(&vdev->release_work);
+ schedule_work(&vgpu->release_work);
}

return NOTIFY_OK;
@@ -907,17 +861,16 @@ static int intel_vgpu_group_notifier(struct notifier_block *nb,
static int intel_vgpu_open_device(struct mdev_device *mdev)
{
struct intel_vgpu *vgpu = mdev_get_drvdata(mdev);
- struct kvmgt_vdev *vdev = kvmgt_vdev(vgpu);
unsigned long events;
int ret;
struct vfio_group *vfio_group;

- vdev->iommu_notifier.notifier_call = intel_vgpu_iommu_notifier;
- vdev->group_notifier.notifier_call = intel_vgpu_group_notifier;
+ vgpu->iommu_notifier.notifier_call = intel_vgpu_iommu_notifier;
+ vgpu->group_notifier.notifier_call = intel_vgpu_group_notifier;

events = VFIO_IOMMU_NOTIFY_DMA_UNMAP;
ret = vfio_register_notifier(mdev_dev(mdev), VFIO_IOMMU_NOTIFY, &events,
- &vdev->iommu_notifier);
+ &vgpu->iommu_notifier);
if (ret != 0) {
gvt_vgpu_err("vfio_register_notifier for iommu failed: %d\n",
ret);
@@ -926,7 +879,7 @@ static int intel_vgpu_open_device(struct mdev_device *mdev)

events = VFIO_GROUP_NOTIFY_SET_KVM;
ret = vfio_register_notifier(mdev_dev(mdev), VFIO_GROUP_NOTIFY, &events,
- &vdev->group_notifier);
+ &vgpu->group_notifier);
if (ret != 0) {
gvt_vgpu_err("vfio_register_notifier for group failed: %d\n",
ret);
@@ -939,7 +892,7 @@ static int intel_vgpu_open_device(struct mdev_device *mdev)
gvt_vgpu_err("vfio_group_get_external_user_from_dev failed\n");
goto undo_register;
}
- vdev->vfio_group = vfio_group;
+ vgpu->vfio_group = vfio_group;

/* Take a module reference as mdev core doesn't take
* a reference for vendor driver.
@@ -955,39 +908,37 @@ static int intel_vgpu_open_device(struct mdev_device *mdev)

intel_gvt_activate_vgpu(vgpu);

- atomic_set(&vdev->released, 0);
+ atomic_set(&vgpu->released, 0);
return ret;

undo_group:
- vfio_group_put_external_user(vdev->vfio_group);
- vdev->vfio_group = NULL;
+ vfio_group_put_external_user(vgpu->vfio_group);
+ vgpu->vfio_group = NULL;

undo_register:
vfio_unregister_notifier(mdev_dev(mdev), VFIO_GROUP_NOTIFY,
- &vdev->group_notifier);
+ &vgpu->group_notifier);

undo_iommu:
vfio_unregister_notifier(mdev_dev(mdev), VFIO_IOMMU_NOTIFY,
- &vdev->iommu_notifier);
+ &vgpu->iommu_notifier);
out:
return ret;
}

static void intel_vgpu_release_msi_eventfd_ctx(struct intel_vgpu *vgpu)
{
- struct kvmgt_vdev *vdev = kvmgt_vdev(vgpu);
struct eventfd_ctx *trigger;

- trigger = vdev->msi_trigger;
+ trigger = vgpu->msi_trigger;
if (trigger) {
eventfd_ctx_put(trigger);
- vdev->msi_trigger = NULL;
+ vgpu->msi_trigger = NULL;
}
}

static void __intel_vgpu_release(struct intel_vgpu *vgpu)
{
- struct kvmgt_vdev *vdev = kvmgt_vdev(vgpu);
struct drm_i915_private *i915 = vgpu->gvt->gt->i915;
struct kvmgt_guest_info *info;
int ret;
@@ -995,18 +946,18 @@ static void __intel_vgpu_release(struct intel_vgpu *vgpu)
if (!handle_valid(vgpu->handle))
return;

- if (atomic_cmpxchg(&vdev->released, 0, 1))
+ if (atomic_cmpxchg(&vgpu->released, 0, 1))
return;

intel_gvt_release_vgpu(vgpu);

- ret = vfio_unregister_notifier(mdev_dev(vdev->mdev), VFIO_IOMMU_NOTIFY,
- &vdev->iommu_notifier);
+ ret = vfio_unregister_notifier(mdev_dev(vgpu->mdev), VFIO_IOMMU_NOTIFY,
+ &vgpu->iommu_notifier);
drm_WARN(&i915->drm, ret,
"vfio_unregister_notifier for iommu failed: %d\n", ret);

- ret = vfio_unregister_notifier(mdev_dev(vdev->mdev), VFIO_GROUP_NOTIFY,
- &vdev->group_notifier);
+ ret = vfio_unregister_notifier(mdev_dev(vgpu->mdev), VFIO_GROUP_NOTIFY,
+ &vgpu->group_notifier);
drm_WARN(&i915->drm, ret,
"vfio_unregister_notifier for group failed: %d\n", ret);

@@ -1017,9 +968,9 @@ static void __intel_vgpu_release(struct intel_vgpu *vgpu)
kvmgt_guest_exit(info);

intel_vgpu_release_msi_eventfd_ctx(vgpu);
- vfio_group_put_external_user(vdev->vfio_group);
+ vfio_group_put_external_user(vgpu->vfio_group);

- vdev->kvm = NULL;
+ vgpu->kvm = NULL;
vgpu->handle = 0;
}

@@ -1032,10 +983,10 @@ static void intel_vgpu_close_device(struct mdev_device *mdev)

static void intel_vgpu_release_work(struct work_struct *work)
{
- struct kvmgt_vdev *vdev = container_of(work, struct kvmgt_vdev,
- release_work);
+ struct intel_vgpu *vgpu =
+ container_of(work, struct intel_vgpu, release_work);

- __intel_vgpu_release(vdev->vgpu);
+ __intel_vgpu_release(vgpu);
}

static u64 intel_vgpu_get_bar_addr(struct intel_vgpu *vgpu, int bar)
@@ -1117,13 +1068,12 @@ static ssize_t intel_vgpu_rw(struct mdev_device *mdev, char *buf,
size_t count, loff_t *ppos, bool is_write)
{
struct intel_vgpu *vgpu = mdev_get_drvdata(mdev);
- struct kvmgt_vdev *vdev = kvmgt_vdev(vgpu);
unsigned int index = VFIO_PCI_OFFSET_TO_INDEX(*ppos);
u64 pos = *ppos & VFIO_PCI_OFFSET_MASK;
int ret = -EINVAL;


- if (index >= VFIO_PCI_NUM_REGIONS + vdev->num_regions) {
+ if (index >= VFIO_PCI_NUM_REGIONS + vgpu->num_regions) {
gvt_vgpu_err("invalid index: %u\n", index);
return -EINVAL;
}
@@ -1152,11 +1102,11 @@ static ssize_t intel_vgpu_rw(struct mdev_device *mdev, char *buf,
case VFIO_PCI_ROM_REGION_INDEX:
break;
default:
- if (index >= VFIO_PCI_NUM_REGIONS + vdev->num_regions)
+ if (index >= VFIO_PCI_NUM_REGIONS + vgpu->num_regions)
return -EINVAL;

index -= VFIO_PCI_NUM_REGIONS;
- return vdev->region[index].ops->rw(vgpu, buf, count,
+ return vgpu->region[index].ops->rw(vgpu, buf, count,
ppos, is_write);
}

@@ -1409,7 +1359,7 @@ static int intel_vgpu_set_msi_trigger(struct intel_vgpu *vgpu,
gvt_vgpu_err("eventfd_ctx_fdget failed\n");
return PTR_ERR(trigger);
}
- kvmgt_vdev(vgpu)->msi_trigger = trigger;
+ vgpu->msi_trigger = trigger;
} else if ((flags & VFIO_IRQ_SET_DATA_NONE) && !count)
intel_vgpu_release_msi_eventfd_ctx(vgpu);

@@ -1461,7 +1411,6 @@ static long intel_vgpu_ioctl(struct mdev_device *mdev, unsigned int cmd,
unsigned long arg)
{
struct intel_vgpu *vgpu = mdev_get_drvdata(mdev);
- struct kvmgt_vdev *vdev = kvmgt_vdev(vgpu);
unsigned long minsz;

gvt_dbg_core("vgpu%d ioctl, cmd: %d\n", vgpu->id, cmd);
@@ -1480,7 +1429,7 @@ static long intel_vgpu_ioctl(struct mdev_device *mdev, unsigned int cmd,
info.flags = VFIO_DEVICE_FLAGS_PCI;
info.flags |= VFIO_DEVICE_FLAGS_RESET;
info.num_regions = VFIO_PCI_NUM_REGIONS +
- vdev->num_regions;
+ vgpu->num_regions;
info.num_irqs = VFIO_PCI_NUM_IRQS;

return copy_to_user((void __user *)arg, &info, minsz) ?
@@ -1571,22 +1520,22 @@ static long intel_vgpu_ioctl(struct mdev_device *mdev, unsigned int cmd,
.header.version = 1 };

if (info.index >= VFIO_PCI_NUM_REGIONS +
- vdev->num_regions)
+ vgpu->num_regions)
return -EINVAL;
info.index =
array_index_nospec(info.index,
VFIO_PCI_NUM_REGIONS +
- vdev->num_regions);
+ vgpu->num_regions);

i = info.index - VFIO_PCI_NUM_REGIONS;

info.offset =
VFIO_PCI_INDEX_TO_OFFSET(info.index);
- info.size = vdev->region[i].size;
- info.flags = vdev->region[i].flags;
+ info.size = vgpu->region[i].size;
+ info.flags = vgpu->region[i].flags;

- cap_type.type = vdev->region[i].type;
- cap_type.subtype = vdev->region[i].subtype;
+ cap_type.type = vgpu->region[i].type;
+ cap_type.subtype = vgpu->region[i].subtype;

ret = vfio_info_add_capability(&caps,
&cap_type.header,
@@ -1928,15 +1877,13 @@ static int kvmgt_guest_init(struct mdev_device *mdev)
{
struct kvmgt_guest_info *info;
struct intel_vgpu *vgpu;
- struct kvmgt_vdev *vdev;
struct kvm *kvm;

vgpu = mdev_get_drvdata(mdev);
if (handle_valid(vgpu->handle))
return -EEXIST;

- vdev = kvmgt_vdev(vgpu);
- kvm = vdev->kvm;
+ kvm = vgpu->kvm;
if (!kvm || kvm->mm != current->mm) {
gvt_vgpu_err("KVM is required to use Intel vGPU\n");
return -ESRCH;
@@ -1962,7 +1909,7 @@ static int kvmgt_guest_init(struct mdev_device *mdev)
kvm_page_track_register_notifier(kvm, &info->track_node);

debugfs_create_ulong(KVMGT_DEBUGFS_FILENAME, 0444, vgpu->debugfs,
- &vdev->nr_cache_entries);
+ &vgpu->nr_cache_entries);
return 0;
}

@@ -1980,52 +1927,33 @@ static bool kvmgt_guest_exit(struct kvmgt_guest_info *info)
return true;
}

-static int kvmgt_attach_vgpu(void *p_vgpu, unsigned long *handle)
-{
- struct intel_vgpu *vgpu = (struct intel_vgpu *)p_vgpu;
-
- vgpu->vdev = kzalloc(sizeof(struct kvmgt_vdev), GFP_KERNEL);
-
- if (!vgpu->vdev)
- return -ENOMEM;
-
- kvmgt_vdev(vgpu)->vgpu = vgpu;
-
- return 0;
-}
-
static void kvmgt_detach_vgpu(void *p_vgpu)
{
int i;
struct intel_vgpu *vgpu = (struct intel_vgpu *)p_vgpu;
- struct kvmgt_vdev *vdev = kvmgt_vdev(vgpu);

- if (!vdev->region)
+ if (!vgpu->region)
return;

- for (i = 0; i < vdev->num_regions; i++)
- if (vdev->region[i].ops->release)
- vdev->region[i].ops->release(vgpu,
- &vdev->region[i]);
- vdev->num_regions = 0;
- kfree(vdev->region);
- vdev->region = NULL;
-
- kfree(vdev);
+ for (i = 0; i < vgpu->num_regions; i++)
+ if (vgpu->region[i].ops->release)
+ vgpu->region[i].ops->release(vgpu,
+ &vgpu->region[i]);
+ vgpu->num_regions = 0;
+ kfree(vgpu->region);
+ vgpu->region = NULL;
}

static int kvmgt_inject_msi(unsigned long handle, u32 addr, u16 data)
{
struct kvmgt_guest_info *info;
struct intel_vgpu *vgpu;
- struct kvmgt_vdev *vdev;

if (!handle_valid(handle))
return -ESRCH;

info = (struct kvmgt_guest_info *)handle;
vgpu = info->vgpu;
- vdev = kvmgt_vdev(vgpu);

/*
* When guest is poweroff, msi_trigger is set to NULL, but vgpu's
@@ -2036,10 +1964,10 @@ static int kvmgt_inject_msi(unsigned long handle, u32 addr, u16 data)
* enabled by guest. so if msi_trigger is null, success is still
* returned and don't inject interrupt into guest.
*/
- if (vdev->msi_trigger == NULL)
+ if (vgpu->msi_trigger == NULL)
return 0;

- if (eventfd_signal(vdev->msi_trigger, 1) == 1)
+ if (eventfd_signal(vgpu->msi_trigger, 1) == 1)
return 0;

return -EFAULT;
@@ -2066,7 +1994,6 @@ static int kvmgt_dma_map_guest_page(unsigned long handle, unsigned long gfn,
unsigned long size, dma_addr_t *dma_addr)
{
struct intel_vgpu *vgpu;
- struct kvmgt_vdev *vdev;
struct gvt_dma *entry;
int ret;

@@ -2074,9 +2001,8 @@ static int kvmgt_dma_map_guest_page(unsigned long handle, unsigned long gfn,
return -EINVAL;

vgpu = ((struct kvmgt_guest_info *)handle)->vgpu;
- vdev = kvmgt_vdev(vgpu);

- mutex_lock(&vdev->cache_lock);
+ mutex_lock(&vgpu->cache_lock);

entry = __gvt_cache_find_gfn(vgpu, gfn);
if (!entry) {
@@ -2104,20 +2030,19 @@ static int kvmgt_dma_map_guest_page(unsigned long handle, unsigned long gfn,
*dma_addr = entry->dma_addr;
}

- mutex_unlock(&vdev->cache_lock);
+ mutex_unlock(&vgpu->cache_lock);
return 0;

err_unmap:
gvt_dma_unmap_page(vgpu, gfn, *dma_addr, size);
err_unlock:
- mutex_unlock(&vdev->cache_lock);
+ mutex_unlock(&vgpu->cache_lock);
return ret;
}

static int kvmgt_dma_pin_guest_page(unsigned long handle, dma_addr_t dma_addr)
{
struct kvmgt_guest_info *info;
- struct kvmgt_vdev *vdev;
struct gvt_dma *entry;
int ret = 0;

@@ -2125,15 +2050,14 @@ static int kvmgt_dma_pin_guest_page(unsigned long handle, dma_addr_t dma_addr)
return -ENODEV;

info = (struct kvmgt_guest_info *)handle;
- vdev = kvmgt_vdev(info->vgpu);

- mutex_lock(&vdev->cache_lock);
+ mutex_lock(&info->vgpu->cache_lock);
entry = __gvt_cache_find_dma_addr(info->vgpu, dma_addr);
if (entry)
kref_get(&entry->ref);
else
ret = -ENOMEM;
- mutex_unlock(&vdev->cache_lock);
+ mutex_unlock(&info->vgpu->cache_lock);

return ret;
}
@@ -2150,20 +2074,18 @@ static void __gvt_dma_release(struct kref *ref)
static void kvmgt_dma_unmap_guest_page(unsigned long handle, dma_addr_t dma_addr)
{
struct intel_vgpu *vgpu;
- struct kvmgt_vdev *vdev;
struct gvt_dma *entry;

if (!handle_valid(handle))
return;

vgpu = ((struct kvmgt_guest_info *)handle)->vgpu;
- vdev = kvmgt_vdev(vgpu);

- mutex_lock(&vdev->cache_lock);
+ mutex_lock(&vgpu->cache_lock);
entry = __gvt_cache_find_dma_addr(vgpu, dma_addr);
if (entry)
kref_put(&entry->ref, __gvt_dma_release);
- mutex_unlock(&vdev->cache_lock);
+ mutex_unlock(&vgpu->cache_lock);
}

static int kvmgt_rw_gpa(unsigned long handle, unsigned long gpa,
@@ -2176,8 +2098,7 @@ static int kvmgt_rw_gpa(unsigned long handle, unsigned long gpa,

info = (struct kvmgt_guest_info *)handle;

- return vfio_dma_rw(kvmgt_vdev(info->vgpu)->vfio_group,
- gpa, buf, len, write);
+ return vfio_dma_rw(info->vgpu->vfio_group, gpa, buf, len, write);
}

static int kvmgt_read_gpa(unsigned long handle, unsigned long gpa,
@@ -2215,7 +2136,6 @@ static bool kvmgt_is_valid_gfn(unsigned long handle, unsigned long gfn)
static const struct intel_gvt_mpt kvmgt_mpt = {
.host_init = kvmgt_host_init,
.host_exit = kvmgt_host_exit,
- .attach_vgpu = kvmgt_attach_vgpu,
.detach_vgpu = kvmgt_detach_vgpu,
.inject_msi = kvmgt_inject_msi,
.enable_page_track = kvmgt_page_track_add,
diff --git a/drivers/gpu/drm/i915/gvt/mpt.h b/drivers/gpu/drm/i915/gvt/mpt.h
index 6d062cf71de92..8a659301d78b9 100644
--- a/drivers/gpu/drm/i915/gvt/mpt.h
+++ b/drivers/gpu/drm/i915/gvt/mpt.h
@@ -71,22 +71,6 @@ static inline void intel_gvt_hypervisor_host_exit(struct device *dev, void *gvt)
intel_gvt_host.mpt->host_exit(dev, gvt);
}

-/**
- * intel_gvt_hypervisor_attach_vgpu - call hypervisor to initialize vGPU
- * related stuffs inside hypervisor.
- *
- * Returns:
- * Zero on success, negative error code if failed.
- */
-static inline int intel_gvt_hypervisor_attach_vgpu(struct intel_vgpu *vgpu)
-{
- /* optional to provide */
- if (!intel_gvt_host.mpt->attach_vgpu)
- return 0;
-
- return intel_gvt_host.mpt->attach_vgpu(vgpu, &vgpu->handle);
-}
-
/**
* intel_gvt_hypervisor_detach_vgpu - call hypervisor to release vGPU
* related stuffs inside hypervisor.
diff --git a/drivers/gpu/drm/i915/gvt/vgpu.c b/drivers/gpu/drm/i915/gvt/vgpu.c
index 8dddd0a940a1b..fd335a7bcb849 100644
--- a/drivers/gpu/drm/i915/gvt/vgpu.c
+++ b/drivers/gpu/drm/i915/gvt/vgpu.c
@@ -405,13 +405,9 @@ static struct intel_vgpu *__intel_gvt_create_vgpu(struct intel_gvt *gvt,

populate_pvinfo_page(vgpu);

- ret = intel_gvt_hypervisor_attach_vgpu(vgpu);
- if (ret)
- goto out_clean_vgpu_resource;
-
ret = intel_vgpu_init_gtt(vgpu);
if (ret)
- goto out_detach_hypervisor_vgpu;
+ goto out_clean_vgpu_resource;

ret = intel_vgpu_init_opregion(vgpu);
if (ret)
@@ -454,8 +450,6 @@ static struct intel_vgpu *__intel_gvt_create_vgpu(struct intel_gvt *gvt,
intel_vgpu_clean_opregion(vgpu);
out_clean_gtt:
intel_vgpu_clean_gtt(vgpu);
-out_detach_hypervisor_vgpu:
- intel_gvt_hypervisor_detach_vgpu(vgpu);
out_clean_vgpu_resource:
intel_vgpu_free_resource(vgpu);
out_clean_vgpu_mmio:
--
2.30.2

2022-04-12 23:33:50

by Jason Gunthorpe

[permalink] [raw]
Subject: Re: [PATCH 02/34] drm/i915/gvt: remove enum hypervisor_type

On Mon, Apr 11, 2022 at 04:13:31PM +0200, Christoph Hellwig wrote:
> The only supported hypervisor is KVM, so don't bother with dead code
> enumerating hypervisors.
>
> Signed-off-by: Christoph Hellwig <[email protected]>
> ---
> drivers/gpu/drm/i915/gvt/gvt.c | 17 +--
> drivers/gpu/drm/i915/gvt/gvt.h | 1 -
> drivers/gpu/drm/i915/gvt/hypercall.h | 6 --
> drivers/gpu/drm/i915/gvt/kvmgt.c | 1 -
> drivers/gpu/drm/i915/gvt/opregion.c | 150 ++++++---------------------
> 5 files changed, 34 insertions(+), 141 deletions(-)

Reviewed-by: Jason Gunthorpe <[email protected]>

Jason

2022-04-12 23:36:47

by Christoph Hellwig

[permalink] [raw]
Subject: [PATCH 23/34] drm/i915/gvt: remove struct intel_gvt_mpt

Just call the initializion and exit functions directly and remove
this abstraction entirely.

Signed-off-by: Christoph Hellwig <[email protected]>
---
drivers/gpu/drm/i915/gvt/gvt.c | 11 ++++-
drivers/gpu/drm/i915/gvt/gvt.h | 12 ++---
drivers/gpu/drm/i915/gvt/hypercall.h | 50 -------------------
drivers/gpu/drm/i915/gvt/kvmgt.c | 39 ++-------------
drivers/gpu/drm/i915/gvt/mpt.h | 74 ----------------------------
5 files changed, 17 insertions(+), 169 deletions(-)
delete mode 100644 drivers/gpu/drm/i915/gvt/hypercall.h
delete mode 100644 drivers/gpu/drm/i915/gvt/mpt.h

diff --git a/drivers/gpu/drm/i915/gvt/gvt.c b/drivers/gpu/drm/i915/gvt/gvt.c
index 9259f2a17398d..047fb6c41788b 100644
--- a/drivers/gpu/drm/i915/gvt/gvt.c
+++ b/drivers/gpu/drm/i915/gvt/gvt.c
@@ -135,7 +135,8 @@ static void intel_gvt_clean_device(struct drm_i915_private *i915)
if (drm_WARN_ON(&i915->drm, !gvt))
return;

- intel_gvt_hypervisor_host_exit(i915->drm.dev, gvt);
+ mdev_unregister_device(i915->drm.dev);
+ intel_gvt_cleanup_vgpu_type_groups(gvt);
intel_gvt_destroy_idle_vgpu(gvt->idle_vgpu);
intel_gvt_clean_vgpu_types(gvt);

@@ -235,13 +236,19 @@ static int intel_gvt_init_device(struct drm_i915_private *i915)

intel_gvt_debugfs_init(gvt);

- ret = intel_gvt_hypervisor_host_init(i915->drm.dev, gvt);
+ ret = intel_gvt_init_vgpu_type_groups(gvt);
if (ret)
goto out_destroy_idle_vgpu;

+ ret = mdev_register_device(i915->drm.dev, &intel_vgpu_mdev_ops);
+ if (ret)
+ goto out_cleanup_vgpu_type_groups;
+
gvt_dbg_core("gvt device initialization is done\n");
return 0;

+out_cleanup_vgpu_type_groups:
+ intel_gvt_cleanup_vgpu_type_groups(gvt);
out_destroy_idle_vgpu:
intel_gvt_destroy_idle_vgpu(gvt->idle_vgpu);
intel_gvt_debugfs_clean(gvt);
diff --git a/drivers/gpu/drm/i915/gvt/gvt.h b/drivers/gpu/drm/i915/gvt/gvt.h
index 938f572717377..865997c5005d5 100644
--- a/drivers/gpu/drm/i915/gvt/gvt.h
+++ b/drivers/gpu/drm/i915/gvt/gvt.h
@@ -41,7 +41,6 @@
#include "intel_gvt.h"

#include "debug.h"
-#include "hypercall.h"
#include "mmio.h"
#include "reg.h"
#include "interrupt.h"
@@ -59,12 +58,6 @@

#define GVT_MAX_VGPU 8

-struct intel_gvt_host {
- const struct intel_gvt_mpt *mpt;
-};
-
-extern struct intel_gvt_host intel_gvt_host;
-
/* Describe per-platform limitations. */
struct intel_gvt_device_info {
u32 max_support_vgpus;
@@ -773,9 +766,12 @@ int intel_gvt_dma_map_guest_page(struct intel_vgpu *vgpu, unsigned long gfn,
void intel_gvt_dma_unmap_guest_page(struct intel_vgpu *vgpu,
dma_addr_t dma_addr);

+int intel_gvt_init_vgpu_type_groups(struct intel_gvt *gvt);
+void intel_gvt_cleanup_vgpu_type_groups(struct intel_gvt *gvt);
+
#include "trace.h"
-#include "mpt.h"

extern const struct intel_vgpu_ops intel_gvt_vgpu_ops;
+extern const struct mdev_parent_ops intel_vgpu_mdev_ops;

#endif
diff --git a/drivers/gpu/drm/i915/gvt/hypercall.h b/drivers/gpu/drm/i915/gvt/hypercall.h
deleted file mode 100644
index d49437aeabac8..0000000000000
--- a/drivers/gpu/drm/i915/gvt/hypercall.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright(c) 2011-2016 Intel Corporation. All rights reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Authors:
- * Eddie Dong <[email protected]>
- * Dexuan Cui
- * Jike Song <[email protected]>
- *
- * Contributors:
- * Zhi Wang <[email protected]>
- *
- */
-
-#ifndef _GVT_HYPERCALL_H_
-#define _GVT_HYPERCALL_H_
-
-#include <linux/types.h>
-
-struct device;
-struct intel_vgpu;
-
-/*
- * Specific GVT-g MPT modules function collections. Currently GVT-g supports
- * both Xen and KVM by providing dedicated hypervisor-related MPT modules.
- */
-struct intel_gvt_mpt {
- int (*host_init)(struct device *dev, void *gvt);
- void (*host_exit)(struct device *dev, void *gvt);
-};
-
-#endif /* _GVT_HYPERCALL_H_ */
diff --git a/drivers/gpu/drm/i915/gvt/kvmgt.c b/drivers/gpu/drm/i915/gvt/kvmgt.c
index 606b2cb923d8e..f908867223aec 100644
--- a/drivers/gpu/drm/i915/gvt/kvmgt.c
+++ b/drivers/gpu/drm/i915/gvt/kvmgt.c
@@ -172,7 +172,7 @@ static struct attribute_group *gvt_vgpu_type_groups[] = {
[0 ... NR_MAX_INTEL_VGPU_TYPES - 1] = NULL,
};

-static int intel_gvt_init_vgpu_type_groups(struct intel_gvt *gvt)
+int intel_gvt_init_vgpu_type_groups(struct intel_gvt *gvt)
{
int i, j;
struct intel_vgpu_type *type;
@@ -201,7 +201,7 @@ static int intel_gvt_init_vgpu_type_groups(struct intel_gvt *gvt)
return -ENOMEM;
}

-static void intel_gvt_cleanup_vgpu_type_groups(struct intel_gvt *gvt)
+void intel_gvt_cleanup_vgpu_type_groups(struct intel_gvt *gvt)
{
int i;
struct attribute_group *group;
@@ -1665,8 +1665,9 @@ static const struct attribute_group *intel_vgpu_groups[] = {
NULL,
};

-static struct mdev_parent_ops intel_vgpu_mdev_ops = {
+const struct mdev_parent_ops intel_vgpu_mdev_ops = {
.mdev_attr_groups = intel_vgpu_groups,
+ .supported_type_groups = gvt_vgpu_type_groups,
.create = intel_vgpu_create,
.remove = intel_vgpu_remove,

@@ -1679,29 +1680,6 @@ static struct mdev_parent_ops intel_vgpu_mdev_ops = {
.ioctl = intel_vgpu_ioctl,
};

-static int kvmgt_host_init(struct device *dev, void *gvt)
-{
- int ret;
-
- ret = intel_gvt_init_vgpu_type_groups((struct intel_gvt *)gvt);
- if (ret)
- return ret;
-
- intel_vgpu_mdev_ops.supported_type_groups = gvt_vgpu_type_groups;
-
- ret = mdev_register_device(dev, &intel_vgpu_mdev_ops);
- if (ret)
- intel_gvt_cleanup_vgpu_type_groups((struct intel_gvt *)gvt);
-
- return ret;
-}
-
-static void kvmgt_host_exit(struct device *dev, void *gvt)
-{
- mdev_unregister_device(dev);
- intel_gvt_cleanup_vgpu_type_groups((struct intel_gvt *)gvt);
-}
-
int intel_gvt_page_track_add(struct intel_vgpu *info, u64 gfn)
{
struct kvm *kvm = info->kvm;
@@ -1964,15 +1942,6 @@ void intel_gvt_dma_unmap_guest_page(struct intel_vgpu *vgpu,
mutex_unlock(&vgpu->cache_lock);
}

-static const struct intel_gvt_mpt kvmgt_mpt = {
- .host_init = kvmgt_host_init,
- .host_exit = kvmgt_host_exit,
-};
-
-struct intel_gvt_host intel_gvt_host = {
- .mpt = &kvmgt_mpt,
-};
-
static int __init kvmgt_init(void)
{
return intel_gvt_set_ops(&intel_gvt_vgpu_ops);
diff --git a/drivers/gpu/drm/i915/gvt/mpt.h b/drivers/gpu/drm/i915/gvt/mpt.h
deleted file mode 100644
index 3be602a3f764a..0000000000000
--- a/drivers/gpu/drm/i915/gvt/mpt.h
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright(c) 2011-2016 Intel Corporation. All rights reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Authors:
- * Eddie Dong <[email protected]>
- * Dexuan Cui
- * Jike Song <[email protected]>
- *
- * Contributors:
- * Zhi Wang <[email protected]>
- *
- */
-
-#ifndef _GVT_MPT_H_
-#define _GVT_MPT_H_
-
-#include "gvt.h"
-
-/**
- * DOC: Hypervisor Service APIs for GVT-g Core Logic
- *
- * This is the glue layer between specific hypervisor MPT modules and GVT-g core
- * logic. Each kind of hypervisor MPT module provides a collection of function
- * callbacks and will be attached to GVT host when the driver is loading.
- * GVT-g core logic will call these APIs to request specific services from
- * hypervisor.
- */
-
-/**
- * intel_gvt_hypervisor_host_init - init GVT-g host side
- *
- * Returns:
- * Zero on success, negative error code if failed
- */
-static inline int intel_gvt_hypervisor_host_init(struct device *dev, void *gvt)
-{
- if (!intel_gvt_host.mpt->host_init)
- return -ENODEV;
-
- return intel_gvt_host.mpt->host_init(dev, gvt);
-}
-
-/**
- * intel_gvt_hypervisor_host_exit - exit GVT-g host side
- */
-static inline void intel_gvt_hypervisor_host_exit(struct device *dev, void *gvt)
-{
- /* optional to provide */
- if (!intel_gvt_host.mpt->host_exit)
- return;
-
- intel_gvt_host.mpt->host_exit(dev, gvt);
-}
-
-#endif /* _GVT_MPT_H_ */
--
2.30.2

2022-04-12 23:46:13

by Christoph Hellwig

[permalink] [raw]
Subject: [PATCH 26/34] drm/i915/gvt: pass a struct intel_vgpu to the vfio read/write helpers

Pass the structure we actually care about instead of deriving it from
the mdev_device in the lower level code.

Signed-off-by: Christoph Hellwig <[email protected]>
---
drivers/gpu/drm/i915/gvt/kvmgt.c | 28 ++++++++++++++--------------
1 file changed, 14 insertions(+), 14 deletions(-)

diff --git a/drivers/gpu/drm/i915/gvt/kvmgt.c b/drivers/gpu/drm/i915/gvt/kvmgt.c
index 11bce3a91a225..5db74b6fe5137 100644
--- a/drivers/gpu/drm/i915/gvt/kvmgt.c
+++ b/drivers/gpu/drm/i915/gvt/kvmgt.c
@@ -1007,10 +1007,9 @@ static int intel_vgpu_aperture_rw(struct intel_vgpu *vgpu, u64 off,
return 0;
}

-static ssize_t intel_vgpu_rw(struct mdev_device *mdev, char *buf,
+static ssize_t intel_vgpu_rw(struct intel_vgpu *vgpu, char *buf,
size_t count, loff_t *ppos, bool is_write)
{
- struct intel_vgpu *vgpu = mdev_get_drvdata(mdev);
unsigned int index = VFIO_PCI_OFFSET_TO_INDEX(*ppos);
u64 pos = *ppos & VFIO_PCI_OFFSET_MASK;
int ret = -EINVAL;
@@ -1056,9 +1055,8 @@ static ssize_t intel_vgpu_rw(struct mdev_device *mdev, char *buf,
return ret == 0 ? count : ret;
}

-static bool gtt_entry(struct mdev_device *mdev, loff_t *ppos)
+static bool gtt_entry(struct intel_vgpu *vgpu, loff_t *ppos)
{
- struct intel_vgpu *vgpu = mdev_get_drvdata(mdev);
unsigned int index = VFIO_PCI_OFFSET_TO_INDEX(*ppos);
struct intel_gvt *gvt = vgpu->gvt;
int offset;
@@ -1078,6 +1076,7 @@ static bool gtt_entry(struct mdev_device *mdev, loff_t *ppos)
static ssize_t intel_vgpu_read(struct mdev_device *mdev, char __user *buf,
size_t count, loff_t *ppos)
{
+ struct intel_vgpu *vgpu = mdev_get_drvdata(mdev);
unsigned int done = 0;
int ret;

@@ -1086,10 +1085,10 @@ static ssize_t intel_vgpu_read(struct mdev_device *mdev, char __user *buf,

/* Only support GGTT entry 8 bytes read */
if (count >= 8 && !(*ppos % 8) &&
- gtt_entry(mdev, ppos)) {
+ gtt_entry(vgpu, ppos)) {
u64 val;

- ret = intel_vgpu_rw(mdev, (char *)&val, sizeof(val),
+ ret = intel_vgpu_rw(vgpu, (char *)&val, sizeof(val),
ppos, false);
if (ret <= 0)
goto read_err;
@@ -1101,7 +1100,7 @@ static ssize_t intel_vgpu_read(struct mdev_device *mdev, char __user *buf,
} else if (count >= 4 && !(*ppos % 4)) {
u32 val;

- ret = intel_vgpu_rw(mdev, (char *)&val, sizeof(val),
+ ret = intel_vgpu_rw(vgpu, (char *)&val, sizeof(val),
ppos, false);
if (ret <= 0)
goto read_err;
@@ -1113,7 +1112,7 @@ static ssize_t intel_vgpu_read(struct mdev_device *mdev, char __user *buf,
} else if (count >= 2 && !(*ppos % 2)) {
u16 val;

- ret = intel_vgpu_rw(mdev, (char *)&val, sizeof(val),
+ ret = intel_vgpu_rw(vgpu, (char *)&val, sizeof(val),
ppos, false);
if (ret <= 0)
goto read_err;
@@ -1125,7 +1124,7 @@ static ssize_t intel_vgpu_read(struct mdev_device *mdev, char __user *buf,
} else {
u8 val;

- ret = intel_vgpu_rw(mdev, &val, sizeof(val), ppos,
+ ret = intel_vgpu_rw(vgpu, &val, sizeof(val), ppos,
false);
if (ret <= 0)
goto read_err;
@@ -1152,6 +1151,7 @@ static ssize_t intel_vgpu_write(struct mdev_device *mdev,
const char __user *buf,
size_t count, loff_t *ppos)
{
+ struct intel_vgpu *vgpu = mdev_get_drvdata(mdev);
unsigned int done = 0;
int ret;

@@ -1160,13 +1160,13 @@ static ssize_t intel_vgpu_write(struct mdev_device *mdev,

/* Only support GGTT entry 8 bytes write */
if (count >= 8 && !(*ppos % 8) &&
- gtt_entry(mdev, ppos)) {
+ gtt_entry(vgpu, ppos)) {
u64 val;

if (copy_from_user(&val, buf, sizeof(val)))
goto write_err;

- ret = intel_vgpu_rw(mdev, (char *)&val, sizeof(val),
+ ret = intel_vgpu_rw(vgpu, (char *)&val, sizeof(val),
ppos, true);
if (ret <= 0)
goto write_err;
@@ -1178,7 +1178,7 @@ static ssize_t intel_vgpu_write(struct mdev_device *mdev,
if (copy_from_user(&val, buf, sizeof(val)))
goto write_err;

- ret = intel_vgpu_rw(mdev, (char *)&val, sizeof(val),
+ ret = intel_vgpu_rw(vgpu, (char *)&val, sizeof(val),
ppos, true);
if (ret <= 0)
goto write_err;
@@ -1190,7 +1190,7 @@ static ssize_t intel_vgpu_write(struct mdev_device *mdev,
if (copy_from_user(&val, buf, sizeof(val)))
goto write_err;

- ret = intel_vgpu_rw(mdev, (char *)&val,
+ ret = intel_vgpu_rw(vgpu, (char *)&val,
sizeof(val), ppos, true);
if (ret <= 0)
goto write_err;
@@ -1202,7 +1202,7 @@ static ssize_t intel_vgpu_write(struct mdev_device *mdev,
if (copy_from_user(&val, buf, sizeof(val)))
goto write_err;

- ret = intel_vgpu_rw(mdev, &val, sizeof(val),
+ ret = intel_vgpu_rw(vgpu, &val, sizeof(val),
ppos, true);
if (ret <= 0)
goto write_err;
--
2.30.2

2022-04-13 00:01:13

by Christoph Hellwig

[permalink] [raw]
Subject: [PATCH 20/34] drm/i915/gvt: devirtualize ->{enable,disable}_page_track

Just call the kvmgt functions directly.

Signed-off-by: Christoph Hellwig <[email protected]>
---
drivers/gpu/drm/i915/gvt/gvt.h | 3 +++
drivers/gpu/drm/i915/gvt/hypercall.h | 2 --
drivers/gpu/drm/i915/gvt/kvmgt.c | 6 ++----
drivers/gpu/drm/i915/gvt/mpt.h | 28 ---------------------------
drivers/gpu/drm/i915/gvt/page_track.c | 8 ++++----
5 files changed, 9 insertions(+), 38 deletions(-)

diff --git a/drivers/gpu/drm/i915/gvt/gvt.h b/drivers/gpu/drm/i915/gvt/gvt.h
index 52ef88d2bf21a..a8a8728cd54a8 100644
--- a/drivers/gpu/drm/i915/gvt/gvt.h
+++ b/drivers/gpu/drm/i915/gvt/gvt.h
@@ -765,6 +765,9 @@ void intel_gvt_debugfs_remove_vgpu(struct intel_vgpu *vgpu);
void intel_gvt_debugfs_init(struct intel_gvt *gvt);
void intel_gvt_debugfs_clean(struct intel_gvt *gvt);

+int intel_gvt_page_track_add(struct intel_vgpu *info, u64 gfn);
+int intel_gvt_page_track_remove(struct intel_vgpu *info, u64 gfn);
+
#include "trace.h"
#include "mpt.h"

diff --git a/drivers/gpu/drm/i915/gvt/hypercall.h b/drivers/gpu/drm/i915/gvt/hypercall.h
index dbde492cafc84..ded13a63ab663 100644
--- a/drivers/gpu/drm/i915/gvt/hypercall.h
+++ b/drivers/gpu/drm/i915/gvt/hypercall.h
@@ -45,8 +45,6 @@ struct intel_vgpu;
struct intel_gvt_mpt {
int (*host_init)(struct device *dev, void *gvt);
void (*host_exit)(struct device *dev, void *gvt);
- int (*enable_page_track)(struct intel_vgpu *vgpu, u64 gfn);
- int (*disable_page_track)(struct intel_vgpu *vgpu, u64 gfn);

int (*dma_map_guest_page)(struct intel_vgpu *vgpu, unsigned long gfn,
unsigned long size, dma_addr_t *dma_addr);
diff --git a/drivers/gpu/drm/i915/gvt/kvmgt.c b/drivers/gpu/drm/i915/gvt/kvmgt.c
index 6d4c67270172a..fbef3d3dfb1f5 100644
--- a/drivers/gpu/drm/i915/gvt/kvmgt.c
+++ b/drivers/gpu/drm/i915/gvt/kvmgt.c
@@ -1702,7 +1702,7 @@ static void kvmgt_host_exit(struct device *dev, void *gvt)
intel_gvt_cleanup_vgpu_type_groups((struct intel_gvt *)gvt);
}

-static int kvmgt_page_track_add(struct intel_vgpu *info, u64 gfn)
+int intel_gvt_page_track_add(struct intel_vgpu *info, u64 gfn)
{
struct kvm *kvm = info->kvm;
struct kvm_memory_slot *slot;
@@ -1732,7 +1732,7 @@ static int kvmgt_page_track_add(struct intel_vgpu *info, u64 gfn)
return 0;
}

-static int kvmgt_page_track_remove(struct intel_vgpu *info, u64 gfn)
+int intel_gvt_page_track_remove(struct intel_vgpu *info, u64 gfn)
{
struct kvm *kvm = info->kvm;
struct kvm_memory_slot *slot;
@@ -1968,8 +1968,6 @@ static void kvmgt_dma_unmap_guest_page(struct intel_vgpu *vgpu,
static const struct intel_gvt_mpt kvmgt_mpt = {
.host_init = kvmgt_host_init,
.host_exit = kvmgt_host_exit,
- .enable_page_track = kvmgt_page_track_add,
- .disable_page_track = kvmgt_page_track_remove,
.dma_map_guest_page = kvmgt_dma_map_guest_page,
.dma_unmap_guest_page = kvmgt_dma_unmap_guest_page,
.dma_pin_guest_page = kvmgt_dma_pin_guest_page,
diff --git a/drivers/gpu/drm/i915/gvt/mpt.h b/drivers/gpu/drm/i915/gvt/mpt.h
index 2d4bb6eaa08e3..d2723ac8bb044 100644
--- a/drivers/gpu/drm/i915/gvt/mpt.h
+++ b/drivers/gpu/drm/i915/gvt/mpt.h
@@ -71,34 +71,6 @@ static inline void intel_gvt_hypervisor_host_exit(struct device *dev, void *gvt)
intel_gvt_host.mpt->host_exit(dev, gvt);
}

-/**
- * intel_gvt_hypervisor_enable_page_track - track a guest page
- * @vgpu: a vGPU
- * @gfn: the gfn of guest
- *
- * Returns:
- * Zero on success, negative error code if failed.
- */
-static inline int intel_gvt_hypervisor_enable_page_track(
- struct intel_vgpu *vgpu, unsigned long gfn)
-{
- return intel_gvt_host.mpt->enable_page_track(vgpu, gfn);
-}
-
-/**
- * intel_gvt_hypervisor_disable_page_track - untrack a guest page
- * @vgpu: a vGPU
- * @gfn: the gfn of guest
- *
- * Returns:
- * Zero on success, negative error code if failed.
- */
-static inline int intel_gvt_hypervisor_disable_page_track(
- struct intel_vgpu *vgpu, unsigned long gfn)
-{
- return intel_gvt_host.mpt->disable_page_track(vgpu, gfn);
-}
-
/**
* intel_gvt_hypervisor_dma_map_guest_page - setup dma map for guest page
* @vgpu: a vGPU
diff --git a/drivers/gpu/drm/i915/gvt/page_track.c b/drivers/gpu/drm/i915/gvt/page_track.c
index 84856022528ee..3375b51c75f1e 100644
--- a/drivers/gpu/drm/i915/gvt/page_track.c
+++ b/drivers/gpu/drm/i915/gvt/page_track.c
@@ -87,7 +87,7 @@ void intel_vgpu_unregister_page_track(struct intel_vgpu *vgpu,
track = radix_tree_delete(&vgpu->page_track_tree, gfn);
if (track) {
if (track->tracked)
- intel_gvt_hypervisor_disable_page_track(vgpu, gfn);
+ intel_gvt_page_track_remove(vgpu, gfn);
kfree(track);
}
}
@@ -112,7 +112,7 @@ int intel_vgpu_enable_page_track(struct intel_vgpu *vgpu, unsigned long gfn)
if (track->tracked)
return 0;

- ret = intel_gvt_hypervisor_enable_page_track(vgpu, gfn);
+ ret = intel_gvt_page_track_add(vgpu, gfn);
if (ret)
return ret;
track->tracked = true;
@@ -139,7 +139,7 @@ int intel_vgpu_disable_page_track(struct intel_vgpu *vgpu, unsigned long gfn)
if (!track->tracked)
return 0;

- ret = intel_gvt_hypervisor_disable_page_track(vgpu, gfn);
+ ret = intel_gvt_page_track_remove(vgpu, gfn);
if (ret)
return ret;
track->tracked = false;
@@ -172,7 +172,7 @@ int intel_vgpu_page_track_handler(struct intel_vgpu *vgpu, u64 gpa,

if (unlikely(vgpu->failsafe)) {
/* Remove write protection to prevent furture traps. */
- intel_vgpu_disable_page_track(vgpu, gpa >> PAGE_SHIFT);
+ intel_gvt_page_track_remove(vgpu, gpa >> PAGE_SHIFT);
} else {
ret = page_track->handler(page_track, gpa, data, bytes);
if (ret)
--
2.30.2

2022-04-13 00:01:53

by Jason Gunthorpe

[permalink] [raw]
Subject: Re: [PATCH 07/34] drm/i915/gvt: remove intel_gvt_ops

On Mon, Apr 11, 2022 at 04:13:36PM +0200, Christoph Hellwig wrote:
> Remove these pointless indirect alls by just calling the only instance

'alls' -> 'calls'

Reviewed-by: Jason Gunthorpe <[email protected]>

Jason

2022-04-13 00:06:44

by Kirti Wankhede

[permalink] [raw]
Subject: Re: [PATCH 34/34] vfio/mdev: Remove mdev drvdata



On 4/11/2022 7:44 PM, Christoph Hellwig wrote:
> From: Jason Gunthorpe <[email protected]>
>
> This is no longer used, remove it.
>
> All usages were moved over to either use container_of() from a vfio_device
> or to use dev_drvdata() directly on the mdev.
>
> Signed-off-by: Jason Gunthorpe <[email protected]>
> Signed-off-by: Christoph Hellwig <[email protected]>
> ---
> include/linux/mdev.h | 9 ---------
> 1 file changed, 9 deletions(-)
>

Reviewed-by: Kirti Wankhede <[email protected]>

2022-04-13 00:07:33

by Kirti Wankhede

[permalink] [raw]
Subject: Re: [PATCH 30/34] vfio/mdev: Remove vfio_mdev.c



On 4/11/2022 7:43 PM, Christoph Hellwig wrote:
> From: Jason Gunthorpe <[email protected]>
>
> Now that all mdev drivers directly create their own mdev_device driver and
> directly register with the vfio core's vfio_device_ops this is all dead
> code.
>
> Delete vfio_mdev.c and the mdev_parent_ops members that are connected to
> it.
>
> Signed-off-by: Jason Gunthorpe <[email protected]>
> Signed-off-by: Christoph Hellwig <[email protected]>

Reviewed-by: Kirti Wankhede <[email protected]>

2022-04-13 00:10:46

by Jason Gunthorpe

[permalink] [raw]
Subject: Re: [PATCH 28/34] drm/i915/gvt: convert to use vfio_register_emulated_iommu_dev

On Mon, Apr 11, 2022 at 04:13:57PM +0200, Christoph Hellwig wrote:

> -static int intel_vgpu_create(struct mdev_device *mdev)
> -{
> - struct device *pdev = mdev_parent_dev(mdev);
> - struct intel_gvt *gvt = kdev_to_i915(pdev)->gvt;
> - struct intel_vgpu_type *type;
> - struct intel_vgpu *vgpu;
> -
> - type = &gvt->types[mdev_get_type_group_id(mdev)];
> - if (!type)
> - return -EINVAL;
> -
> - vgpu = intel_gvt_create_vgpu(gvt, type);
> - if (IS_ERR(vgpu)) {
> - gvt_err("failed to create intel vgpu: %ld\n", PTR_ERR(vgpu));
> - return PTR_ERR(vgpu);
> - }
> -
> - INIT_WORK(&vgpu->release_work, intel_vgpu_release_work);
> -
> - vgpu->mdev = mdev;
> - mdev_set_drvdata(mdev, vgpu);
> -
> - gvt_dbg_core("intel_vgpu_create succeeded for mdev: %s\n",
> - dev_name(mdev_dev(mdev)));

nit: the debug print has the wrong function name now

Rest looks OK

Reviewed-by: Jason Gunthorpe <[email protected]>

Jason

2022-04-13 18:37:00

by Wang, Zhi A

[permalink] [raw]
Subject: Re: refactor the i915 GVT support and move to the modern mdev API v3

On 4/11/22 2:13 PM, Christoph Hellwig wrote:
> Hi all,
>
> the GVT code in the i915 is a bit of a mess right now due to strange
> abstractions and lots of indirect calls. This series refactors various
> bits to clean that up. The main user visible change is that almost all
> of the GVT code moves out of the main i915 driver and into the kvmgt
> module.

Hi Christoph:

Do you want me to merge the GVT-g patches in this series? Or you want them to get merged from your side?

Thanks,
Zhi.

>
> Tested on my Thinkpad with a Kaby Lake CPU and integrated graphics.
>
> Git tree:
>
> git://git.infradead.org/users/hch/misc.git i915-gvt
>
> Gitweb:
>
> http://git.infradead.org/users/hch/misc.git/shortlog/refs/heads/i915-gvt
>
> Changes since v2:
> - rebased on top of Linx 5.18-rc +
> "Refactor GVT-g MMIO tracking table and handlers"
> - don't fold the gvt Makefile into the main Makefile
> - add the mdev patches to remove the legacy interface that is now
> unused to the end of the series
>
> Changes since v1:
> - rebased on Linux 5.15
> - allow the kvmgvt module to be loaded at any time and thus solve
> the deadlock when both i915 amd kvmgvt are modular
> - include the conversion to the modern mdev API
>
> Note that I do expect to rebased this again against 5.16-rc1 once
> released, but I'd like to get this out for review ASAP.
>
> Diffstat:
> b/drivers/gpu/drm/i915/Kconfig | 33
> b/drivers/gpu/drm/i915/Makefile | 31
> b/drivers/gpu/drm/i915/gvt/cfg_space.c | 89 --
> b/drivers/gpu/drm/i915/gvt/cmd_parser.c | 4
> b/drivers/gpu/drm/i915/gvt/dmabuf.c | 36 -
> b/drivers/gpu/drm/i915/gvt/execlist.c | 12
> b/drivers/gpu/drm/i915/gvt/gtt.c | 55 +
> b/drivers/gpu/drm/i915/gvt/gvt.h | 125 ++-
> b/drivers/gpu/drm/i915/gvt/interrupt.c | 38 +
> b/drivers/gpu/drm/i915/gvt/kvmgt.c | 1099 +++++++++++++++-----------------
> b/drivers/gpu/drm/i915/gvt/mmio.c | 4
> b/drivers/gpu/drm/i915/gvt/opregion.c | 148 ----
> b/drivers/gpu/drm/i915/gvt/page_track.c | 8
> b/drivers/gpu/drm/i915/gvt/scheduler.c | 37 -
> b/drivers/gpu/drm/i915/gvt/trace.h | 2
> b/drivers/gpu/drm/i915/gvt/vgpu.c | 22
> b/drivers/gpu/drm/i915/i915_drv.c | 7
> b/drivers/gpu/drm/i915/i915_drv.h | 1
> b/drivers/gpu/drm/i915/i915_trace.h | 1
> b/drivers/gpu/drm/i915/intel_gvt.c | 162 +++-
> b/drivers/gpu/drm/i915/intel_gvt.h | 17
> drivers/gpu/drm/i915/gvt/Makefile | 9
> drivers/gpu/drm/i915/gvt/gvt.c | 340 ---------
> drivers/gpu/drm/i915/gvt/hypercall.h | 82 --
> drivers/gpu/drm/i915/gvt/mpt.h | 400 -----------
> 25 files changed, 929 insertions(+), 1833 deletions(-)
>

2022-04-13 19:04:50

by Christoph Hellwig

[permalink] [raw]
Subject: Re: refactor the i915 GVT support and move to the modern mdev API v3

On Wed, Apr 13, 2022 at 06:58:47PM +0300, Jani Nikula wrote:
> Acked-by: Jani Nikula <[email protected]>

I've only added this to the i915 patches for now, let me know if you
also want me to add it to the vfio/mdev ones.

2022-04-13 19:28:41

by Jani Nikula

[permalink] [raw]
Subject: Re: refactor the i915 GVT support and move to the modern mdev API v3

On Wed, 13 Apr 2022, Christoph Hellwig <[email protected]> wrote:
> On Wed, Apr 13, 2022 at 01:47:05PM +0000, Wang, Zhi A wrote:
>> > the GVT code in the i915 is a bit of a mess right now due to strange
>> > abstractions and lots of indirect calls. This series refactors various
>> > bits to clean that up. The main user visible change is that almost all
>> > of the GVT code moves out of the main i915 driver and into the kvmgt
>> > module.
>>
>> Hi Christoph:
>>
>> Do you want me to merge the GVT-g patches in this series? Or you want them to get merged from your side?
>
> The two option here are drm tree via gvt and i915 trees or the vfio
> tree, neither of which really is my tree.
>
> We already have a fair bit of vfio changes at the tail end of the series,
> and Jason has some more that should sit on top of it, and I have some
> more that I haven't sent yet.
>
> So if we could get the MMIO table and Makefile cleanups into a topic
> branch that we could pull into the vfio tree and merge it through that
> that would seem easiest to me, assuming that is ok with the i915, drm
> and vfio maintainers.

AFAICS the changes are mostly to gvt/, and at least I'm fine with the
minor changes to i915 (in this series and in my two patches) being
merged via whichever tree you all see fit.

Acked-by: Jani Nikula <[email protected]>

Joonas, Tvrtko, Rodrigo, chime in now if you have any issues with that.


BR,
Jani.


--
Jani Nikula, Intel Open Source Graphics Center

2022-04-14 13:43:54

by Wang, Zhi A

[permalink] [raw]
Subject: Re: refactor the i915 GVT support and move to the modern mdev API v3

Hi folks:

Thanks so much for the efforts. I prepared a branch which contains all our patches.The aim of the branch is for the VFIO maintainers to pull the whole bunch easily after the drm-intel-next got merged through drm (as one of the MMIO patches depends on a patch in drm-intel-next).

I dropped patch 4 and patch 5 as they have been covered by Jani's patches. Some conflicts was solved.
QA is going to test it today.

You can find it here:

git clone https://github.com/intel/gvt-linux -b for-christoph

Thanks,
Zhi.

On 4/13/22 3:58 PM, Jani Nikula wrote:
> On Wed, 13 Apr 2022, Christoph Hellwig <[email protected]> wrote:
>> On Wed, Apr 13, 2022 at 01:47:05PM +0000, Wang, Zhi A wrote:
>>>> the GVT code in the i915 is a bit of a mess right now due to strange
>>>> abstractions and lots of indirect calls. This series refactors various
>>>> bits to clean that up. The main user visible change is that almost all
>>>> of the GVT code moves out of the main i915 driver and into the kvmgt
>>>> module.
>>>
>>> Hi Christoph:
>>>
>>> Do you want me to merge the GVT-g patches in this series? Or you want them to get merged from your side?
>>
>> The two option here are drm tree via gvt and i915 trees or the vfio
>> tree, neither of which really is my tree.
>>
>> We already have a fair bit of vfio changes at the tail end of the series,
>> and Jason has some more that should sit on top of it, and I have some
>> more that I haven't sent yet.
>>
>> So if we could get the MMIO table and Makefile cleanups into a topic
>> branch that we could pull into the vfio tree and merge it through that
>> that would seem easiest to me, assuming that is ok with the i915, drm
>> and vfio maintainers.
>
> AFAICS the changes are mostly to gvt/, and at least I'm fine with the
> minor changes to i915 (in this series and in my two patches) being
> merged via whichever tree you all see fit.
>
> Acked-by: Jani Nikula <[email protected]>
>
> Joonas, Tvrtko, Rodrigo, chime in now if you have any issues with that.
>
>
> BR,
> Jani.
>
>

2022-04-14 14:24:33

by Jason Gunthorpe

[permalink] [raw]
Subject: Re: refactor the i915 GVT support and move to the modern mdev API v3

On Wed, Apr 13, 2022 at 11:13:06PM +0000, Wang, Zhi A wrote:
> Hi folks:
>
> Thanks so much for the efforts. I prepared a branch which contains all our patches.The aim of the branch is for the VFIO maintainers to pull the whole bunch easily after the drm-intel-next got merged through drm (as one of the MMIO patches depends on a patch in drm-intel-next).
>
> I dropped patch 4 and patch 5 as they have been covered by Jani's patches. Some conflicts was solved.
> QA is going to test it today.
>
> You can find it here:
>
> git clone https://github.com/intel/gvt-linux -b for-christoph

There are alot of extra commits on there - is it possible to base this
straight on rc1 not on some kind of existing DRM tree?

Why did you choose drm/i915/fbc: Call intel_fbc_activate() directly
from frontbuffer flush as a base?

Jason

2022-04-14 20:04:49

by Christoph Hellwig

[permalink] [raw]
Subject: Re: refactor the i915 GVT support and move to the modern mdev API v3

On Wed, Apr 13, 2022 at 01:47:05PM +0000, Wang, Zhi A wrote:
> > the GVT code in the i915 is a bit of a mess right now due to strange
> > abstractions and lots of indirect calls. This series refactors various
> > bits to clean that up. The main user visible change is that almost all
> > of the GVT code moves out of the main i915 driver and into the kvmgt
> > module.
>
> Hi Christoph:
>
> Do you want me to merge the GVT-g patches in this series? Or you want them to get merged from your side?

The two option here are drm tree via gvt and i915 trees or the vfio
tree, neither of which really is my tree.

We already have a fair bit of vfio changes at the tail end of the series,
and Jason has some more that should sit on top of it, and I have some
more that I haven't sent yet.

So if we could get the MMIO table and Makefile cleanups into a topic
branch that we could pull into the vfio tree and merge it through that
that would seem easiest to me, assuming that is ok with the i915, drm
and vfio maintainers.

2022-04-14 21:32:40

by Wang, Zhi A

[permalink] [raw]
Subject: Re: refactor the i915 GVT support and move to the modern mdev API v3

On 4/13/22 11:20 PM, Jason Gunthorpe wrote:
> On Wed, Apr 13, 2022 at 11:13:06PM +0000, Wang, Zhi A wrote:
>> Hi folks:
>>
>> Thanks so much for the efforts. I prepared a branch which contains all our patches.The aim of the branch is for the VFIO maintainers to pull the whole bunch easily after the drm-intel-next got merged through drm (as one of the MMIO patches depends on a patch in drm-intel-next).
>>
>> I dropped patch 4 and patch 5 as they have been covered by Jani's patches. Some conflicts was solved.
>> QA is going to test it today.
>>
>> You can find it here:
>>
>> git clone https://github.com/intel/gvt-linux -b for-christoph
>
> There are alot of extra commits on there - is it possible to base this
> straight on rc1 not on some kind of existing DRM tree?
>
> Why did you choose drm/i915/fbc: Call intel_fbc_activate() directly
> from frontbuffer flush as a base?
>
> Jason
>

Hi Jason:

I updated the branch. You can check if those are what you are expecting. :)

Thanks,
Zhi.

2022-04-15 08:41:37

by Jason Gunthorpe

[permalink] [raw]
Subject: Re: refactor the i915 GVT support and move to the modern mdev API v3

On Thu, Apr 14, 2022 at 01:39:11PM +0000, Wang, Zhi A wrote:
> On 4/14/22 1:34 PM, Jason Gunthorpe wrote:
> > On Thu, Apr 14, 2022 at 12:20:42PM +0000, Wang, Zhi A wrote:
> >> On 4/13/22 11:20 PM, Jason Gunthorpe wrote:
> >>> On Wed, Apr 13, 2022 at 11:13:06PM +0000, Wang, Zhi A wrote:
> >>>> Hi folks:
> >>>>
> >>>> Thanks so much for the efforts. I prepared a branch which contains all our patches.The aim of the branch is for the VFIO maintainers to pull the whole bunch easily after the drm-intel-next got merged through drm (as one of the MMIO patches depends on a patch in drm-intel-next).
> >>>>
> >>>> I dropped patch 4 and patch 5 as they have been covered by Jani's patches. Some conflicts was solved.
> >>>> QA is going to test it today.
> >>>>
> >>>> You can find it here:
> >>>>
> >>>> git clone https://github.com/intel/gvt-linux -b for-christoph
> >>>
> >>> There are alot of extra commits on there - is it possible to base this
> >>> straight on rc1 not on some kind of existing DRM tree?
> >>>
> >>> Why did you choose drm/i915/fbc: Call intel_fbc_activate() directly
> >>> from frontbuffer flush as a base?
> >>>
> >>> Jason
> >>>
> >>
> >> Hi Jason:
> >>
> This one belongs to i915, which has already been queued in drm-intel-next, but
> not yet reached to the top. When it is landed in -rc, I will rebase this branch
> on it, then we can drop this patch in this branch.

A commit called 'split out dmc registers' with no Fixes: will be sent
to a rc?

Jason

2022-04-15 09:25:15

by Jason Gunthorpe

[permalink] [raw]
Subject: Re: refactor the i915 GVT support and move to the modern mdev API v3

On Thu, Apr 14, 2022 at 02:25:36PM +0000, Wang, Zhi A wrote:

> > So drop the '[DONT PULL]' commit and send a PR to the next DRM tree -
> > when that is confirmed send the same PR to vfio,
>
> I updated the branch again, but I am confused. What is the purpose of sending
> the PR to next DRM tree? I suppose all the patches will go through VFIO? If
> I understand correctly?

pull requests can flow through more than one tree concurrently. The
purpose of the topic branch is to allow all the commits to be in all
the trees they need to be in at once.

So you should send this branch as a PR to the next logical upstream
tree gvt patches normally go through, in the usual way that you send
PRs. Especially in this case where there is a small merge conflict
internal to DRM to resolve. I'm assuming this is the drm-intel-next
tree?

Once DRM is internally happy then VFIO can merge it as well. You can
view VFIO as the secondary path to Linus, DRM as primary. Alex will
mention in his pull request that VFIO has a 'shared branch with DRM
for gvt'.

Jason

2022-04-15 14:23:04

by Jason Gunthorpe

[permalink] [raw]
Subject: Re: refactor the i915 GVT support and move to the modern mdev API v3

On Thu, Apr 14, 2022 at 04:40:11PM +0300, Jani Nikula wrote:

> >> >> git clone https://github.com/intel/gvt-linux -b for-christoph
> >> >
> >> > There are alot of extra commits on there - is it possible to base this
> >> > straight on rc1 not on some kind of existing DRM tree?
> >> >
> >> > Why did you choose drm/i915/fbc: Call intel_fbc_activate() directly
> >> > from frontbuffer flush as a base?
> >> >
> >> > Jason
> >> >
> >>
> >> Hi Jason:
> >>
> >> I updated the branch. You can check if those are what you are expecting. :)
> >
> > This is better, except for the first commit:
> >
> > [DON'T PULL] drm/i915/dmc: split out dmc registers to a separate file
> > THIS PATCH WILL GO THROUGH DRM-INTEL-NEXT TO UPSTREAM
> >
> > Clean up the massive i915_reg.h a bit with this isolated set of
> > registers.
> >
> > v2: Remove stale comment (Lucas)
> >
> > Clean the commit message and send that as a proper PR to
> > drm-intel-next, then everything else is OK.
>
> It's already in drm-intel-next, I guess the problem is basing the branch
> on something that doesn't have it. I'd probably just base everything
> cleanly on -rc1, and whoever does the merge between the two will need to
> account for the missing include in the result. It's just adding one line
> in the right place.

That makes sense to me, especially if you can do the merge fixup
internally in DRM.

So drop the '[DONT PULL]' commit and send a PR to the next DRM tree -
when that is confirmed send the same PR to vfio,

Thanks,
Jason

2022-04-16 00:35:57

by Jani Nikula

[permalink] [raw]
Subject: Re: refactor the i915 GVT support and move to the modern mdev API v3

On Thu, 14 Apr 2022, Jason Gunthorpe <[email protected]> wrote:
> On Thu, Apr 14, 2022 at 12:20:42PM +0000, Wang, Zhi A wrote:
>> On 4/13/22 11:20 PM, Jason Gunthorpe wrote:
>> > On Wed, Apr 13, 2022 at 11:13:06PM +0000, Wang, Zhi A wrote:
>> >> Hi folks:
>> >>
>> >> Thanks so much for the efforts. I prepared a branch which contains all our patches.The aim of the branch is for the VFIO maintainers to pull the whole bunch easily after the drm-intel-next got merged through drm (as one of the MMIO patches depends on a patch in drm-intel-next).
>> >>
>> >> I dropped patch 4 and patch 5 as they have been covered by Jani's patches. Some conflicts was solved.
>> >> QA is going to test it today.
>> >>
>> >> You can find it here:
>> >>
>> >> git clone https://github.com/intel/gvt-linux -b for-christoph
>> >
>> > There are alot of extra commits on there - is it possible to base this
>> > straight on rc1 not on some kind of existing DRM tree?
>> >
>> > Why did you choose drm/i915/fbc: Call intel_fbc_activate() directly
>> > from frontbuffer flush as a base?
>> >
>> > Jason
>> >
>>
>> Hi Jason:
>>
>> I updated the branch. You can check if those are what you are expecting. :)
>
> This is better, except for the first commit:
>
> [DON'T PULL] drm/i915/dmc: split out dmc registers to a separate file
> THIS PATCH WILL GO THROUGH DRM-INTEL-NEXT TO UPSTREAM
>
> Clean up the massive i915_reg.h a bit with this isolated set of
> registers.
>
> v2: Remove stale comment (Lucas)
>
> Clean the commit message and send that as a proper PR to
> drm-intel-next, then everything else is OK.

It's already in drm-intel-next, I guess the problem is basing the branch
on something that doesn't have it. I'd probably just base everything
cleanly on -rc1, and whoever does the merge between the two will need to
account for the missing include in the result. It's just adding one line
in the right place.

BR,
Jani.


--
Jani Nikula, Intel Open Source Graphics Center

2022-04-16 01:47:45

by Jason Gunthorpe

[permalink] [raw]
Subject: Re: refactor the i915 GVT support and move to the modern mdev API v3

On Thu, Apr 14, 2022 at 12:20:42PM +0000, Wang, Zhi A wrote:
> On 4/13/22 11:20 PM, Jason Gunthorpe wrote:
> > On Wed, Apr 13, 2022 at 11:13:06PM +0000, Wang, Zhi A wrote:
> >> Hi folks:
> >>
> >> Thanks so much for the efforts. I prepared a branch which contains all our patches.The aim of the branch is for the VFIO maintainers to pull the whole bunch easily after the drm-intel-next got merged through drm (as one of the MMIO patches depends on a patch in drm-intel-next).
> >>
> >> I dropped patch 4 and patch 5 as they have been covered by Jani's patches. Some conflicts was solved.
> >> QA is going to test it today.
> >>
> >> You can find it here:
> >>
> >> git clone https://github.com/intel/gvt-linux -b for-christoph
> >
> > There are alot of extra commits on there - is it possible to base this
> > straight on rc1 not on some kind of existing DRM tree?
> >
> > Why did you choose drm/i915/fbc: Call intel_fbc_activate() directly
> > from frontbuffer flush as a base?
> >
> > Jason
> >
>
> Hi Jason:
>
> I updated the branch. You can check if those are what you are expecting. :)

This is better, except for the first commit:

[DON'T PULL] drm/i915/dmc: split out dmc registers to a separate file
THIS PATCH WILL GO THROUGH DRM-INTEL-NEXT TO UPSTREAM

Clean up the massive i915_reg.h a bit with this isolated set of
registers.

v2: Remove stale comment (Lucas)

Clean the commit message and send that as a proper PR to
drm-intel-next, then everything else is OK.

Jason

2022-04-16 01:50:23

by Jani Nikula

[permalink] [raw]
Subject: Re: refactor the i915 GVT support and move to the modern mdev API v3

On Thu, 14 Apr 2022, Jason Gunthorpe <[email protected]> wrote:
> On Thu, Apr 14, 2022 at 01:39:11PM +0000, Wang, Zhi A wrote:
>> This one belongs to i915, which has already been queued in drm-intel-next, but
>> not yet reached to the top. When it is landed in -rc, I will rebase this branch
>> on it, then we can drop this patch in this branch.
>
> A commit called 'split out dmc registers' with no Fixes: will be sent
> to a rc?

Won't. It's in drm-intel-next (and drm-next), headed to v5.19.

BR,
Jani.

--
Jani Nikula, Intel Open Source Graphics Center

2022-04-16 02:11:06

by Wang, Zhi A

[permalink] [raw]
Subject: Re: refactor the i915 GVT support and move to the modern mdev API v3

On 4/14/22 1:34 PM, Jason Gunthorpe wrote:
> On Thu, Apr 14, 2022 at 12:20:42PM +0000, Wang, Zhi A wrote:
>> On 4/13/22 11:20 PM, Jason Gunthorpe wrote:
>>> On Wed, Apr 13, 2022 at 11:13:06PM +0000, Wang, Zhi A wrote:
>>>> Hi folks:
>>>>
>>>> Thanks so much for the efforts. I prepared a branch which contains all our patches.The aim of the branch is for the VFIO maintainers to pull the whole bunch easily after the drm-intel-next got merged through drm (as one of the MMIO patches depends on a patch in drm-intel-next).
>>>>
>>>> I dropped patch 4 and patch 5 as they have been covered by Jani's patches. Some conflicts was solved.
>>>> QA is going to test it today.
>>>>
>>>> You can find it here:
>>>>
>>>> git clone https://github.com/intel/gvt-linux -b for-christoph
>>>
>>> There are alot of extra commits on there - is it possible to base this
>>> straight on rc1 not on some kind of existing DRM tree?
>>>
>>> Why did you choose drm/i915/fbc: Call intel_fbc_activate() directly
>>> from frontbuffer flush as a base?
>>>
>>> Jason
>>>
>>
>> Hi Jason:
>>
This one belongs to i915, which has already been queued in drm-intel-next, but
not yet reached to the top. When it is landed in -rc, I will rebase this branch
on it, then we can drop this patch in this branch.

>> I updated the branch. You can check if those are what you are expecting. :)
>
> This is better, except for the first commit:
>
> [DON'T PULL] drm/i915/dmc: split out dmc registers to a separate file
> THIS PATCH WILL GO THROUGH DRM-INTEL-NEXT TO UPSTREAM
>
> Clean up the massive i915_reg.h a bit with this isolated set of
> registers.
>
> v2: Remove stale comment (Lucas)
>
> Clean the commit message and send that as a proper PR to
> drm-intel-next, then everything else is OK.
>
> Jason
>

2022-04-16 02:21:59

by Wang, Zhi A

[permalink] [raw]
Subject: Re: refactor the i915 GVT support and move to the modern mdev API v3

On 4/14/22 1:43 PM, Jason Gunthorpe wrote:
> On Thu, Apr 14, 2022 at 04:40:11PM +0300, Jani Nikula wrote:
>
>>>>>> git clone https://github.com/intel/gvt-linux -b for-christoph
>>>>>
>>>>> There are alot of extra commits on there - is it possible to base this
>>>>> straight on rc1 not on some kind of existing DRM tree?
>>>>>
>>>>> Why did you choose drm/i915/fbc: Call intel_fbc_activate() directly
>>>>> from frontbuffer flush as a base?
>>>>>
>>>>> Jason
>>>>>
>>>>
>>>> Hi Jason:
>>>>
>>>> I updated the branch. You can check if those are what you are expecting. :)
>>>
>>> This is better, except for the first commit:
>>>
>>> [DON'T PULL] drm/i915/dmc: split out dmc registers to a separate file
>>> THIS PATCH WILL GO THROUGH DRM-INTEL-NEXT TO UPSTREAM
>>>
>>> Clean up the massive i915_reg.h a bit with this isolated set of
>>> registers.
>>>
>>> v2: Remove stale comment (Lucas)
>>>
>>> Clean the commit message and send that as a proper PR to
>>> drm-intel-next, then everything else is OK.
>>
>> It's already in drm-intel-next, I guess the problem is basing the branch
>> on something that doesn't have it. I'd probably just base everything
>> cleanly on -rc1, and whoever does the merge between the two will need to
>> account for the missing include in the result. It's just adding one line
>> in the right place.
>
> That makes sense to me, especially if you can do the merge fixup
> internally in DRM.
>
> So drop the '[DONT PULL]' commit and send a PR to the next DRM tree -
> when that is confirmed send the same PR to vfio,

I updated the branch again, but I am confused. What is the purpose of sending
the PR to next DRM tree? I suppose all the patches will go through VFIO? If
I understand correctly?
>
> Thanks,
> Jason
>

2022-04-22 15:15:01

by Christoph Hellwig

[permalink] [raw]
Subject: Re: refactor the i915 GVT support and move to the modern mdev API v3

On Thu, Apr 14, 2022 at 11:38:59AM -0300, Jason Gunthorpe wrote:
> pull requests can flow through more than one tree concurrently. The
> purpose of the topic branch is to allow all the commits to be in all
> the trees they need to be in at once.
>
> So you should send this branch as a PR to the next logical upstream
> tree gvt patches normally go through, in the usual way that you send
> PRs. Especially in this case where there is a small merge conflict
> internal to DRM to resolve. I'm assuming this is the drm-intel-next
> tree?
>
> Once DRM is internally happy then VFIO can merge it as well. You can
> view VFIO as the secondary path to Linus, DRM as primary. Alex will
> mention in his pull request that VFIO has a 'shared branch with DRM
> for gvt'.

Where do we stand here? The (somewhat misnamed) topic/for-christoph
branch looks fine to me now except for the mіssing "static inline" on
the intel_gvt_iterate_mmio_table stub.

When can we expect it in the i915 tree and linux-next?

2022-04-22 21:25:51

by Wang, Zhi A

[permalink] [raw]
Subject: Re: refactor the i915 GVT support and move to the modern mdev API v3

On 4/20/22 7:08 AM, Christoph Hellwig wrote:
> On Thu, Apr 14, 2022 at 11:38:59AM -0300, Jason Gunthorpe wrote:
>> pull requests can flow through more than one tree concurrently. The
>> purpose of the topic branch is to allow all the commits to be in all
>> the trees they need to be in at once.
>>
>> So you should send this branch as a PR to the next logical upstream
>> tree gvt patches normally go through, in the usual way that you send
>> PRs. Especially in this case where there is a small merge conflict
>> internal to DRM to resolve. I'm assuming this is the drm-intel-next
>> tree?
>>
>> Once DRM is internally happy then VFIO can merge it as well. You can
>> view VFIO as the secondary path to Linus, DRM as primary. Alex will
>> mention in his pull request that VFIO has a 'shared branch with DRM
>> for gvt'.
>
> Where do we stand here? The (somewhat misnamed) topic/for-christoph
> branch looks fine to me now except for the mіssing "static inline" on
> the intel_gvt_iterate_mmio_table stub.
>
> When can we expect it in the i915 tree and linux-next?
>
Qur QA finished the test yesterday and I just made a tag. The pull
request is going to be sent today. Yes, I will fix that.

Thanks,
Zhi.