mirror of
https://github.com/torvalds/linux.git
synced 2024-12-11 13:41:55 +00:00
drm/i915/gvt: devirtualize ->inject_msi
Just open code the MSI injection in a single place instead of going through the method table. Signed-off-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Zhi Wang <zhi.a.wang@intel.com> Link: http://patchwork.freedesktop.org/patch/msgid/20220411141403.86980-18-hch@lst.de Reviewed-by: Jason Gunthorpe <jgg@nvidia.com> Reviewed-by: Zhi Wang <zhi.a.wang@intel.com>
This commit is contained in:
parent
4c705ad0d7
commit
b3bece3495
@ -45,7 +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 (*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);
|
||||
unsigned long (*gfn_to_mfn)(struct intel_vgpu *vgpu, unsigned long gfn);
|
||||
|
@ -29,6 +29,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/eventfd.h>
|
||||
|
||||
#include "i915_drv.h"
|
||||
#include "i915_reg.h"
|
||||
#include "gvt.h"
|
||||
@ -397,9 +399,45 @@ static void init_irq_map(struct intel_gvt_irq *irq)
|
||||
}
|
||||
|
||||
/* =======================vEvent injection===================== */
|
||||
|
||||
#define MSI_CAP_CONTROL(offset) (offset + 2)
|
||||
#define MSI_CAP_ADDRESS(offset) (offset + 4)
|
||||
#define MSI_CAP_DATA(offset) (offset + 8)
|
||||
#define MSI_CAP_EN 0x1
|
||||
|
||||
static int inject_virtual_interrupt(struct intel_vgpu *vgpu)
|
||||
{
|
||||
return intel_gvt_hypervisor_inject_msi(vgpu);
|
||||
unsigned long offset = vgpu->gvt->device_info.msi_cap_offset;
|
||||
u16 control, data;
|
||||
u32 addr;
|
||||
|
||||
control = *(u16 *)(vgpu_cfg_space(vgpu) + MSI_CAP_CONTROL(offset));
|
||||
addr = *(u32 *)(vgpu_cfg_space(vgpu) + MSI_CAP_ADDRESS(offset));
|
||||
data = *(u16 *)(vgpu_cfg_space(vgpu) + MSI_CAP_DATA(offset));
|
||||
|
||||
/* Do not generate MSI if MSIEN is disabled */
|
||||
if (!(control & MSI_CAP_EN))
|
||||
return 0;
|
||||
|
||||
if (WARN(control & GENMASK(15, 1), "only support one MSI format\n"))
|
||||
return -EINVAL;
|
||||
|
||||
trace_inject_msi(vgpu->id, addr, data);
|
||||
|
||||
/*
|
||||
* When guest is powered off, msi_trigger is set to NULL, but vgpu's
|
||||
* config and mmio register isn't restored to default during guest
|
||||
* poweroff. If this vgpu is still used in next vm, this vgpu's pipe
|
||||
* may be enabled, then once this vgpu is active, it will get inject
|
||||
* vblank interrupt request. But msi_trigger is null until msi is
|
||||
* enabled by guest. so if msi_trigger is null, success is still
|
||||
* returned and don't inject interrupt into guest.
|
||||
*/
|
||||
if (!vgpu->attached)
|
||||
return -ESRCH;
|
||||
if (vgpu->msi_trigger && eventfd_signal(vgpu->msi_trigger, 1) != 1)
|
||||
return -EFAULT;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void propagate_event(struct intel_gvt_irq *irq,
|
||||
|
@ -1874,29 +1874,6 @@ void intel_vgpu_detach_regions(struct intel_vgpu *vgpu)
|
||||
vgpu->region = NULL;
|
||||
}
|
||||
|
||||
static int kvmgt_inject_msi(struct intel_vgpu *vgpu, u32 addr, u16 data)
|
||||
{
|
||||
if (!vgpu->attached)
|
||||
return -ESRCH;
|
||||
|
||||
/*
|
||||
* When guest is poweroff, msi_trigger is set to NULL, but vgpu's
|
||||
* config and mmio register isn't restored to default during guest
|
||||
* poweroff. If this vgpu is still used in next vm, this vgpu's pipe
|
||||
* may be enabled, then once this vgpu is active, it will get inject
|
||||
* vblank interrupt request. But msi_trigger is null until msi is
|
||||
* enabled by guest. so if msi_trigger is null, success is still
|
||||
* returned and don't inject interrupt into guest.
|
||||
*/
|
||||
if (vgpu->msi_trigger == NULL)
|
||||
return 0;
|
||||
|
||||
if (eventfd_signal(vgpu->msi_trigger, 1) == 1)
|
||||
return 0;
|
||||
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
static unsigned long kvmgt_gfn_to_pfn(struct intel_vgpu *vgpu,
|
||||
unsigned long gfn)
|
||||
{
|
||||
@ -2022,7 +1999,6 @@ static bool kvmgt_is_valid_gfn(struct intel_vgpu *vgpu, unsigned long gfn)
|
||||
static const struct intel_gvt_mpt kvmgt_mpt = {
|
||||
.host_init = kvmgt_host_init,
|
||||
.host_exit = kvmgt_host_exit,
|
||||
.inject_msi = kvmgt_inject_msi,
|
||||
.enable_page_track = kvmgt_page_track_add,
|
||||
.disable_page_track = kvmgt_page_track_remove,
|
||||
.gfn_to_mfn = kvmgt_gfn_to_pfn,
|
||||
|
@ -71,43 +71,6 @@ static inline void intel_gvt_hypervisor_host_exit(struct device *dev, void *gvt)
|
||||
intel_gvt_host.mpt->host_exit(dev, gvt);
|
||||
}
|
||||
|
||||
#define MSI_CAP_CONTROL(offset) (offset + 2)
|
||||
#define MSI_CAP_ADDRESS(offset) (offset + 4)
|
||||
#define MSI_CAP_DATA(offset) (offset + 8)
|
||||
#define MSI_CAP_EN 0x1
|
||||
|
||||
/**
|
||||
* intel_gvt_hypervisor_inject_msi - inject a MSI interrupt into vGPU
|
||||
*
|
||||
* Returns:
|
||||
* Zero on success, negative error code if failed.
|
||||
*/
|
||||
static inline int intel_gvt_hypervisor_inject_msi(struct intel_vgpu *vgpu)
|
||||
{
|
||||
unsigned long offset = vgpu->gvt->device_info.msi_cap_offset;
|
||||
u16 control, data;
|
||||
u32 addr;
|
||||
int ret;
|
||||
|
||||
control = *(u16 *)(vgpu_cfg_space(vgpu) + MSI_CAP_CONTROL(offset));
|
||||
addr = *(u32 *)(vgpu_cfg_space(vgpu) + MSI_CAP_ADDRESS(offset));
|
||||
data = *(u16 *)(vgpu_cfg_space(vgpu) + MSI_CAP_DATA(offset));
|
||||
|
||||
/* Do not generate MSI if MSIEN is disable */
|
||||
if (!(control & MSI_CAP_EN))
|
||||
return 0;
|
||||
|
||||
if (WARN(control & GENMASK(15, 1), "only support one MSI format\n"))
|
||||
return -EINVAL;
|
||||
|
||||
trace_inject_msi(vgpu->id, addr, data);
|
||||
|
||||
ret = intel_gvt_host.mpt->inject_msi(vgpu, addr, data);
|
||||
if (ret)
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* intel_gvt_hypervisor_enable_page_track - track a guest page
|
||||
* @vgpu: a vGPU
|
||||
|
Loading…
Reference in New Issue
Block a user