Commit 4996c342 authored by Dave Airlie's avatar Dave Airlie

Merge tag 'drm-intel-fixes-2021-05-20' of...

Merge tag 'drm-intel-fixes-2021-05-20' of git://anongit.freedesktop.org/drm/drm-intel into drm-fixes

drm/i915 fixes for v5.13-rc3:
- Pin the L-shape quirked object as unshrinkable to fix crashes
- Disable HiZ Raw Stall Optimization on broken gen7 to fix glitches, gfx corruption
- GVT: Move mdev attribute groups into kvmgt module to fix kconfig deps issue
Signed-off-by: default avatarDave Airlie <airlied@redhat.com>
From: Jani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/87a6opehx6.fsf@intel.com
parents af8d80bf eddd1b8f
...@@ -102,7 +102,6 @@ config DRM_I915_GVT ...@@ -102,7 +102,6 @@ config DRM_I915_GVT
bool "Enable Intel GVT-g graphics virtualization host support" bool "Enable Intel GVT-g graphics virtualization host support"
depends on DRM_I915 depends on DRM_I915
depends on 64BIT depends on 64BIT
depends on VFIO_MDEV=y || VFIO_MDEV=DRM_I915
default n default n
help help
Choose this option if you want to enable Intel GVT-g graphics Choose this option if you want to enable Intel GVT-g graphics
......
...@@ -63,6 +63,8 @@ void __i915_gem_object_set_pages(struct drm_i915_gem_object *obj, ...@@ -63,6 +63,8 @@ void __i915_gem_object_set_pages(struct drm_i915_gem_object *obj,
i915->quirks & QUIRK_PIN_SWIZZLED_PAGES) { i915->quirks & QUIRK_PIN_SWIZZLED_PAGES) {
GEM_BUG_ON(i915_gem_object_has_tiling_quirk(obj)); GEM_BUG_ON(i915_gem_object_has_tiling_quirk(obj));
i915_gem_object_set_tiling_quirk(obj); i915_gem_object_set_tiling_quirk(obj);
GEM_BUG_ON(!list_empty(&obj->mm.link));
atomic_inc(&obj->mm.shrink_pin);
shrinkable = false; shrinkable = false;
} }
......
...@@ -397,7 +397,10 @@ static void emit_batch(struct i915_vma * const vma, ...@@ -397,7 +397,10 @@ static void emit_batch(struct i915_vma * const vma,
gen7_emit_pipeline_invalidate(&cmds); gen7_emit_pipeline_invalidate(&cmds);
batch_add(&cmds, MI_LOAD_REGISTER_IMM(2)); batch_add(&cmds, MI_LOAD_REGISTER_IMM(2));
batch_add(&cmds, i915_mmio_reg_offset(CACHE_MODE_0_GEN7)); batch_add(&cmds, i915_mmio_reg_offset(CACHE_MODE_0_GEN7));
batch_add(&cmds, 0xffff0000); batch_add(&cmds, 0xffff0000 |
((IS_IVB_GT1(i915) || IS_VALLEYVIEW(i915)) ?
HIZ_RAW_STALL_OPT_DISABLE :
0));
batch_add(&cmds, i915_mmio_reg_offset(CACHE_MODE_1)); batch_add(&cmds, i915_mmio_reg_offset(CACHE_MODE_1));
batch_add(&cmds, 0xffff0000 | PIXEL_SUBSPAN_COLLECT_OPT_DISABLE); batch_add(&cmds, 0xffff0000 | PIXEL_SUBSPAN_COLLECT_OPT_DISABLE);
gen7_emit_pipeline_invalidate(&cmds); gen7_emit_pipeline_invalidate(&cmds);
......
...@@ -46,118 +46,6 @@ static const char * const supported_hypervisors[] = { ...@@ -46,118 +46,6 @@ static const char * const supported_hypervisors[] = {
[INTEL_GVT_HYPERVISOR_KVM] = "KVM", [INTEL_GVT_HYPERVISOR_KVM] = "KVM",
}; };
static struct intel_vgpu_type *
intel_gvt_find_vgpu_type(struct intel_gvt *gvt, unsigned int type_group_id)
{
if (WARN_ON(type_group_id >= gvt->num_types))
return NULL;
return &gvt->types[type_group_id];
}
static ssize_t available_instances_show(struct mdev_type *mtype,
struct mdev_type_attribute *attr,
char *buf)
{
struct intel_vgpu_type *type;
unsigned int num = 0;
void *gvt = kdev_to_i915(mtype_get_parent_dev(mtype))->gvt;
type = intel_gvt_find_vgpu_type(gvt, mtype_get_type_group_id(mtype));
if (!type)
num = 0;
else
num = type->avail_instance;
return sprintf(buf, "%u\n", num);
}
static ssize_t device_api_show(struct mdev_type *mtype,
struct mdev_type_attribute *attr, char *buf)
{
return sprintf(buf, "%s\n", VFIO_DEVICE_API_PCI_STRING);
}
static ssize_t description_show(struct mdev_type *mtype,
struct mdev_type_attribute *attr, char *buf)
{
struct intel_vgpu_type *type;
void *gvt = kdev_to_i915(mtype_get_parent_dev(mtype))->gvt;
type = intel_gvt_find_vgpu_type(gvt, mtype_get_type_group_id(mtype));
if (!type)
return 0;
return sprintf(buf, "low_gm_size: %dMB\nhigh_gm_size: %dMB\n"
"fence: %d\nresolution: %s\n"
"weight: %d\n",
BYTES_TO_MB(type->low_gm_size),
BYTES_TO_MB(type->high_gm_size),
type->fence, vgpu_edid_str(type->resolution),
type->weight);
}
static MDEV_TYPE_ATTR_RO(available_instances);
static MDEV_TYPE_ATTR_RO(device_api);
static MDEV_TYPE_ATTR_RO(description);
static struct attribute *gvt_type_attrs[] = {
&mdev_type_attr_available_instances.attr,
&mdev_type_attr_device_api.attr,
&mdev_type_attr_description.attr,
NULL,
};
static struct attribute_group *gvt_vgpu_type_groups[] = {
[0 ... NR_MAX_INTEL_VGPU_TYPES - 1] = NULL,
};
static bool intel_get_gvt_attrs(struct attribute_group ***intel_vgpu_type_groups)
{
*intel_vgpu_type_groups = gvt_vgpu_type_groups;
return true;
}
static int intel_gvt_init_vgpu_type_groups(struct intel_gvt *gvt)
{
int i, j;
struct intel_vgpu_type *type;
struct attribute_group *group;
for (i = 0; i < gvt->num_types; i++) {
type = &gvt->types[i];
group = kzalloc(sizeof(struct attribute_group), GFP_KERNEL);
if (WARN_ON(!group))
goto unwind;
group->name = type->name;
group->attrs = gvt_type_attrs;
gvt_vgpu_type_groups[i] = group;
}
return 0;
unwind:
for (j = 0; j < i; j++) {
group = gvt_vgpu_type_groups[j];
kfree(group);
}
return -ENOMEM;
}
static void intel_gvt_cleanup_vgpu_type_groups(struct intel_gvt *gvt)
{
int i;
struct attribute_group *group;
for (i = 0; i < gvt->num_types; i++) {
group = gvt_vgpu_type_groups[i];
gvt_vgpu_type_groups[i] = NULL;
kfree(group);
}
}
static const struct intel_gvt_ops intel_gvt_ops = { static const struct intel_gvt_ops intel_gvt_ops = {
.emulate_cfg_read = intel_vgpu_emulate_cfg_read, .emulate_cfg_read = intel_vgpu_emulate_cfg_read,
.emulate_cfg_write = intel_vgpu_emulate_cfg_write, .emulate_cfg_write = intel_vgpu_emulate_cfg_write,
...@@ -169,8 +57,6 @@ static const struct intel_gvt_ops intel_gvt_ops = { ...@@ -169,8 +57,6 @@ static const struct intel_gvt_ops intel_gvt_ops = {
.vgpu_reset = intel_gvt_reset_vgpu, .vgpu_reset = intel_gvt_reset_vgpu,
.vgpu_activate = intel_gvt_activate_vgpu, .vgpu_activate = intel_gvt_activate_vgpu,
.vgpu_deactivate = intel_gvt_deactivate_vgpu, .vgpu_deactivate = intel_gvt_deactivate_vgpu,
.gvt_find_vgpu_type = intel_gvt_find_vgpu_type,
.get_gvt_attrs = intel_get_gvt_attrs,
.vgpu_query_plane = intel_vgpu_query_plane, .vgpu_query_plane = intel_vgpu_query_plane,
.vgpu_get_dmabuf = intel_vgpu_get_dmabuf, .vgpu_get_dmabuf = intel_vgpu_get_dmabuf,
.write_protect_handler = intel_vgpu_page_track_handler, .write_protect_handler = intel_vgpu_page_track_handler,
...@@ -274,7 +160,6 @@ void intel_gvt_clean_device(struct drm_i915_private *i915) ...@@ -274,7 +160,6 @@ void intel_gvt_clean_device(struct drm_i915_private *i915)
return; return;
intel_gvt_destroy_idle_vgpu(gvt->idle_vgpu); intel_gvt_destroy_idle_vgpu(gvt->idle_vgpu);
intel_gvt_cleanup_vgpu_type_groups(gvt);
intel_gvt_clean_vgpu_types(gvt); intel_gvt_clean_vgpu_types(gvt);
intel_gvt_debugfs_clean(gvt); intel_gvt_debugfs_clean(gvt);
...@@ -363,12 +248,6 @@ int intel_gvt_init_device(struct drm_i915_private *i915) ...@@ -363,12 +248,6 @@ int intel_gvt_init_device(struct drm_i915_private *i915)
if (ret) if (ret)
goto out_clean_thread; goto out_clean_thread;
ret = intel_gvt_init_vgpu_type_groups(gvt);
if (ret) {
gvt_err("failed to init vgpu type groups: %d\n", ret);
goto out_clean_types;
}
vgpu = intel_gvt_create_idle_vgpu(gvt); vgpu = intel_gvt_create_idle_vgpu(gvt);
if (IS_ERR(vgpu)) { if (IS_ERR(vgpu)) {
ret = PTR_ERR(vgpu); ret = PTR_ERR(vgpu);
...@@ -454,7 +333,8 @@ EXPORT_SYMBOL_GPL(intel_gvt_register_hypervisor); ...@@ -454,7 +333,8 @@ EXPORT_SYMBOL_GPL(intel_gvt_register_hypervisor);
void void
intel_gvt_unregister_hypervisor(void) intel_gvt_unregister_hypervisor(void)
{ {
intel_gvt_hypervisor_host_exit(intel_gvt_host.dev); 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); module_put(THIS_MODULE);
} }
EXPORT_SYMBOL_GPL(intel_gvt_unregister_hypervisor); EXPORT_SYMBOL_GPL(intel_gvt_unregister_hypervisor);
...@@ -574,9 +574,6 @@ struct intel_gvt_ops { ...@@ -574,9 +574,6 @@ struct intel_gvt_ops {
void (*vgpu_reset)(struct intel_vgpu *); void (*vgpu_reset)(struct intel_vgpu *);
void (*vgpu_activate)(struct intel_vgpu *); void (*vgpu_activate)(struct intel_vgpu *);
void (*vgpu_deactivate)(struct intel_vgpu *); void (*vgpu_deactivate)(struct intel_vgpu *);
struct intel_vgpu_type *(*gvt_find_vgpu_type)(
struct intel_gvt *gvt, unsigned int type_group_id);
bool (*get_gvt_attrs)(struct attribute_group ***intel_vgpu_type_groups);
int (*vgpu_query_plane)(struct intel_vgpu *vgpu, void *); int (*vgpu_query_plane)(struct intel_vgpu *vgpu, void *);
int (*vgpu_get_dmabuf)(struct intel_vgpu *vgpu, unsigned int); int (*vgpu_get_dmabuf)(struct intel_vgpu *vgpu, unsigned int);
int (*write_protect_handler)(struct intel_vgpu *, u64, void *, int (*write_protect_handler)(struct intel_vgpu *, u64, void *,
......
...@@ -49,7 +49,7 @@ enum hypervisor_type { ...@@ -49,7 +49,7 @@ enum hypervisor_type {
struct intel_gvt_mpt { struct intel_gvt_mpt {
enum hypervisor_type type; enum hypervisor_type type;
int (*host_init)(struct device *dev, void *gvt, const void *ops); int (*host_init)(struct device *dev, void *gvt, const void *ops);
void (*host_exit)(struct device *dev); void (*host_exit)(struct device *dev, void *gvt);
int (*attach_vgpu)(void *vgpu, unsigned long *handle); int (*attach_vgpu)(void *vgpu, unsigned long *handle);
void (*detach_vgpu)(void *vgpu); void (*detach_vgpu)(void *vgpu);
int (*inject_msi)(unsigned long handle, u32 addr, u16 data); int (*inject_msi)(unsigned long handle, u32 addr, u16 data);
......
...@@ -144,6 +144,104 @@ static inline bool handle_valid(unsigned long handle) ...@@ -144,6 +144,104 @@ static inline bool handle_valid(unsigned long handle)
return !!(handle & ~0xff); return !!(handle & ~0xff);
} }
static ssize_t available_instances_show(struct mdev_type *mtype,
struct mdev_type_attribute *attr,
char *buf)
{
struct intel_vgpu_type *type;
unsigned int num = 0;
struct intel_gvt *gvt = kdev_to_i915(mtype_get_parent_dev(mtype))->gvt;
type = &gvt->types[mtype_get_type_group_id(mtype)];
if (!type)
num = 0;
else
num = type->avail_instance;
return sprintf(buf, "%u\n", num);
}
static ssize_t device_api_show(struct mdev_type *mtype,
struct mdev_type_attribute *attr, char *buf)
{
return sprintf(buf, "%s\n", VFIO_DEVICE_API_PCI_STRING);
}
static ssize_t description_show(struct mdev_type *mtype,
struct mdev_type_attribute *attr, char *buf)
{
struct intel_vgpu_type *type;
struct intel_gvt *gvt = kdev_to_i915(mtype_get_parent_dev(mtype))->gvt;
type = &gvt->types[mtype_get_type_group_id(mtype)];
if (!type)
return 0;
return sprintf(buf, "low_gm_size: %dMB\nhigh_gm_size: %dMB\n"
"fence: %d\nresolution: %s\n"
"weight: %d\n",
BYTES_TO_MB(type->low_gm_size),
BYTES_TO_MB(type->high_gm_size),
type->fence, vgpu_edid_str(type->resolution),
type->weight);
}
static MDEV_TYPE_ATTR_RO(available_instances);
static MDEV_TYPE_ATTR_RO(device_api);
static MDEV_TYPE_ATTR_RO(description);
static struct attribute *gvt_type_attrs[] = {
&mdev_type_attr_available_instances.attr,
&mdev_type_attr_device_api.attr,
&mdev_type_attr_description.attr,
NULL,
};
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 i, j;
struct intel_vgpu_type *type;
struct attribute_group *group;
for (i = 0; i < gvt->num_types; i++) {
type = &gvt->types[i];
group = kzalloc(sizeof(struct attribute_group), GFP_KERNEL);
if (!group)
goto unwind;
group->name = type->name;
group->attrs = gvt_type_attrs;
gvt_vgpu_type_groups[i] = group;
}
return 0;
unwind:
for (j = 0; j < i; j++) {
group = gvt_vgpu_type_groups[j];
kfree(group);
}
return -ENOMEM;
}
static void intel_gvt_cleanup_vgpu_type_groups(struct intel_gvt *gvt)
{
int i;
struct attribute_group *group;
for (i = 0; i < gvt->num_types; i++) {
group = gvt_vgpu_type_groups[i];
gvt_vgpu_type_groups[i] = NULL;
kfree(group);
}
}
static int kvmgt_guest_init(struct mdev_device *mdev); static int kvmgt_guest_init(struct mdev_device *mdev);
static void intel_vgpu_release_work(struct work_struct *work); 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 kvmgt_guest_info *info);
...@@ -694,14 +792,13 @@ static int intel_vgpu_create(struct mdev_device *mdev) ...@@ -694,14 +792,13 @@ static int intel_vgpu_create(struct mdev_device *mdev)
struct intel_vgpu *vgpu = NULL; struct intel_vgpu *vgpu = NULL;
struct intel_vgpu_type *type; struct intel_vgpu_type *type;
struct device *pdev; struct device *pdev;
void *gvt; struct intel_gvt *gvt;
int ret; int ret;
pdev = mdev_parent_dev(mdev); pdev = mdev_parent_dev(mdev);
gvt = kdev_to_i915(pdev)->gvt; gvt = kdev_to_i915(pdev)->gvt;
type = intel_gvt_ops->gvt_find_vgpu_type(gvt, type = &gvt->types[mdev_get_type_group_id(mdev)];
mdev_get_type_group_id(mdev));
if (!type) { if (!type) {
ret = -EINVAL; ret = -EINVAL;
goto out; goto out;
...@@ -1667,19 +1764,26 @@ static struct mdev_parent_ops intel_vgpu_ops = { ...@@ -1667,19 +1764,26 @@ static struct mdev_parent_ops intel_vgpu_ops = {
static int kvmgt_host_init(struct device *dev, void *gvt, const void *ops) static int kvmgt_host_init(struct device *dev, void *gvt, const void *ops)
{ {
struct attribute_group **kvm_vgpu_type_groups; int ret;
ret = intel_gvt_init_vgpu_type_groups((struct intel_gvt *)gvt);
if (ret)
return ret;
intel_gvt_ops = ops; intel_gvt_ops = ops;
if (!intel_gvt_ops->get_gvt_attrs(&kvm_vgpu_type_groups)) intel_vgpu_ops.supported_type_groups = gvt_vgpu_type_groups;
return -EFAULT;
intel_vgpu_ops.supported_type_groups = kvm_vgpu_type_groups;
return mdev_register_device(dev, &intel_vgpu_ops); ret = mdev_register_device(dev, &intel_vgpu_ops);
if (ret)
intel_gvt_cleanup_vgpu_type_groups((struct intel_gvt *)gvt);
return ret;
} }
static void kvmgt_host_exit(struct device *dev) static void kvmgt_host_exit(struct device *dev, void *gvt)
{ {
mdev_unregister_device(dev); mdev_unregister_device(dev);
intel_gvt_cleanup_vgpu_type_groups((struct intel_gvt *)gvt);
} }
static int kvmgt_page_track_add(unsigned long handle, u64 gfn) static int kvmgt_page_track_add(unsigned long handle, u64 gfn)
......
...@@ -63,13 +63,13 @@ static inline int intel_gvt_hypervisor_host_init(struct device *dev, ...@@ -63,13 +63,13 @@ static inline int intel_gvt_hypervisor_host_init(struct device *dev,
/** /**
* intel_gvt_hypervisor_host_exit - exit GVT-g host side * intel_gvt_hypervisor_host_exit - exit GVT-g host side
*/ */
static inline void intel_gvt_hypervisor_host_exit(struct device *dev) static inline void intel_gvt_hypervisor_host_exit(struct device *dev, void *gvt)
{ {
/* optional to provide */ /* optional to provide */
if (!intel_gvt_host.mpt->host_exit) if (!intel_gvt_host.mpt->host_exit)
return; return;
intel_gvt_host.mpt->host_exit(dev); intel_gvt_host.mpt->host_exit(dev, gvt);
} }
/** /**
......
...@@ -999,12 +999,11 @@ i915_gem_madvise_ioctl(struct drm_device *dev, void *data, ...@@ -999,12 +999,11 @@ i915_gem_madvise_ioctl(struct drm_device *dev, void *data,
obj->mm.madv = args->madv; obj->mm.madv = args->madv;
if (i915_gem_object_has_pages(obj)) { if (i915_gem_object_has_pages(obj)) {
struct list_head *list;
if (i915_gem_object_is_shrinkable(obj)) {
unsigned long flags; unsigned long flags;
spin_lock_irqsave(&i915->mm.obj_lock, flags); spin_lock_irqsave(&i915->mm.obj_lock, flags);
if (!list_empty(&obj->mm.link)) {
struct list_head *list;
if (obj->mm.madv != I915_MADV_WILLNEED) if (obj->mm.madv != I915_MADV_WILLNEED)
list = &i915->mm.purge_list; list = &i915->mm.purge_list;
...@@ -1012,8 +1011,8 @@ i915_gem_madvise_ioctl(struct drm_device *dev, void *data, ...@@ -1012,8 +1011,8 @@ i915_gem_madvise_ioctl(struct drm_device *dev, void *data,
list = &i915->mm.shrink_list; list = &i915->mm.shrink_list;
list_move_tail(&obj->mm.link, list); list_move_tail(&obj->mm.link, list);
spin_unlock_irqrestore(&i915->mm.obj_lock, flags);
} }
spin_unlock_irqrestore(&i915->mm.obj_lock, flags);
} }
/* if the object is no longer attached, discard its backing storage */ /* if the object is no longer attached, discard its backing storage */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment