From: Yi Sun <yi.sun@xxxxxxxxx> This patch introduces the control interface for creating/destroying vGPUs. Signed-off-by: Yi Sun <yi.sun@xxxxxxxxx> Signed-off-by: Zhi Wang <zhi.a.wang@xxxxxxxxx> --- drivers/gpu/drm/i915/gvt/Makefile | 2 +- drivers/gpu/drm/i915/gvt/control.c | 181 +++++++++++++++++++++++++++++++++++++ drivers/gpu/drm/i915/gvt/gvt.c | 4 + drivers/gpu/drm/i915/gvt/gvt.h | 8 ++ 4 files changed, 194 insertions(+), 1 deletion(-) create mode 100644 drivers/gpu/drm/i915/gvt/control.c diff --git a/drivers/gpu/drm/i915/gvt/Makefile b/drivers/gpu/drm/i915/gvt/Makefile index c146c57..8874fe0 100644 --- a/drivers/gpu/drm/i915/gvt/Makefile +++ b/drivers/gpu/drm/i915/gvt/Makefile @@ -1,6 +1,6 @@ GVT_SOURCE := gvt.o params.o aperture_gm.o mmio.o handlers.o instance.o \ trace_points.o interrupt.o gtt.o cfg_space.o opregion.o utility.o \ - fb_decoder.o display.o edid.o + fb_decoder.o display.o edid.o control.o ccflags-y += -I$(src) -I$(src)/.. -Wall -Werror -Wno-unused-function i915_gvt-y := $(GVT_SOURCE) diff --git a/drivers/gpu/drm/i915/gvt/control.c b/drivers/gpu/drm/i915/gvt/control.c new file mode 100644 index 0000000..625d213 --- /dev/null +++ b/drivers/gpu/drm/i915/gvt/control.c @@ -0,0 +1,181 @@ +/* + * 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. + */ + +#include "gvt.h" + +#define GVT_TYPE (';') +#define GVT_BASE 0xA0 + +#define GVT_CREATE_INSTANCE _IOW(GVT_TYPE, GVT_BASE + 0, struct gvt_instance_info) +#define GVT_DESTROY_INSTANCE _IOW(GVT_TYPE, GVT_BASE + 1, s32) + +struct misc_device_client_info { + struct pgt_device *pdev; + struct vgt_device *vgt; + struct mutex lock; +}; + +static int misc_device_open(struct inode *inode, struct file *filp) +{ + struct miscdevice *dev = filp->private_data; + struct pgt_device *pdev = container_of(dev, struct pgt_device, control.misc_device); + struct misc_device_client_info *info = NULL; + + info = kzalloc(sizeof(*info), GFP_KERNEL); + if (!info) { + gvt_err("fail to allocate memory"); + return -ENOMEM; + } + + info->pdev = pdev; + mutex_init(&info->lock); + + filp->private_data = info; + + return 0; +} + +static int misc_device_close(struct inode *inode, struct file *filp) +{ + struct misc_device_client_info *info = filp->private_data; + + if (info->vgt) + gvt_destroy_instance(info->vgt); + + kfree(info); + filp->private_data = NULL; + return 0; +} + +static long misc_device_ioctl(struct file *filp, + unsigned int cmd, unsigned long arg) +{ + struct misc_device_client_info *info = filp->private_data; + struct gvt_instance_info param; + int r = 0; + + if (copy_from_user(¶m, (void *)arg, sizeof(param))) + return -EFAULT; + + mutex_lock(&info->lock); + switch(cmd) { + case GVT_CREATE_INSTANCE: + if (info->vgt) { + gvt_err("instance has already been created"); + r = -EEXIST; + goto out; + } + + info->vgt = gvt_create_instance(info->pdev, ¶m); + + if (!info->vgt) { + gvt_err("fail to create instance"); + r = -ENOMEM; + goto out; + } + break; + case GVT_DESTROY_INSTANCE: + if (!info->vgt) { + r = -ENODEV; + goto out; + } + gvt_destroy_instance(info->vgt); + info->vgt = NULL; + break; + default: + r = -EINVAL; + goto out; + } +out: + mutex_unlock(&info->lock); + return r; +} + +static struct file_operations misc_device_fops = +{ + .open = misc_device_open, + .release = misc_device_close, + .unlocked_ioctl = misc_device_ioctl, + .compat_ioctl = misc_device_ioctl, +}; + +void clean_misc_device(struct pgt_device *pdev) +{ + struct miscdevice *dev = &pdev->control.misc_device; + + if (!list_empty(&dev->list)) + misc_deregister(dev); + + if (dev->name) { + kfree(dev->name); + dev->name = NULL; + } +} + +bool setup_misc_device(struct pgt_device *pdev) +{ + struct miscdevice *dev = &pdev->control.misc_device; + unsigned long len; + char name[32]; + + len = snprintf(name, 32, "dri/gvt%d", pdev->id); + dev->name = kzalloc(len + 1, GFP_KERNEL); + if (!dev->name) { + gvt_err("fail to allocate memory"); + return false; + } + + dev->name = name; + dev->minor = MISC_DYNAMIC_MINOR; + dev->fops = &misc_device_fops; + + INIT_LIST_HEAD(&dev->list); + + if (misc_register(dev) < 0) { + gvt_err("fail to register miscdevice"); + goto err; + } + + return true; +err: + clean_misc_device(pdev); + return false; +} + +bool gvt_setup_control_interface(struct pgt_device *pdev) +{ + bool r; + + r = setup_misc_device(pdev); + if (!r) { + gvt_err("fail to setup misc device node\n"); + return false; + } + + return true; +} + +void gvt_clean_control_interface(struct pgt_device *pdev) +{ + clean_misc_device(pdev); +} diff --git a/drivers/gpu/drm/i915/gvt/gvt.c b/drivers/gpu/drm/i915/gvt/gvt.c index ea871cd..77fe5d39 100644 --- a/drivers/gpu/drm/i915/gvt/gvt.c +++ b/drivers/gpu/drm/i915/gvt/gvt.c @@ -283,6 +283,7 @@ static bool init_service_thread(struct pgt_device *pdev) static void clean_pgt_device(struct pgt_device *pdev) { clean_service_thread(pdev); + gvt_clean_control_interface(pdev); gvt_clean_gtt(pdev); gvt_irq_exit(pdev); gvt_clean_mmio_emulation_state(pdev); @@ -315,6 +316,9 @@ static bool init_pgt_device(struct pgt_device *pdev, struct drm_i915_private *de if (!gvt_init_gtt(pdev)) goto err; + if (!gvt_setup_control_interface(pdev)) + goto err; + if (!init_service_thread(pdev)) goto err; diff --git a/drivers/gpu/drm/i915/gvt/gvt.h b/drivers/gpu/drm/i915/gvt/gvt.h index b44b5b5..1d5c15c 100644 --- a/drivers/gpu/drm/i915/gvt/gvt.h +++ b/drivers/gpu/drm/i915/gvt/gvt.h @@ -163,6 +163,10 @@ struct gvt_gm_allocator { struct drm_mm high_gm; }; +struct gvt_device_control { + struct miscdevice misc_device; +}; + struct pgt_device { struct mutex lock; int id; @@ -214,6 +218,7 @@ struct pgt_device { struct pgt_statistics stat; struct gvt_gtt_info gtt; + struct gvt_device_control control; }; /* request types to wake up main thread */ @@ -688,6 +693,9 @@ bool register_mmio_handler(struct pgt_device *pdev, unsigned int start, int byte bool gvt_update_display_events_emulation(struct pgt_device *pdev); void gvt_emulate_display_events(struct pgt_device *pdev); +bool gvt_setup_control_interface(struct pgt_device *pdev); +void gvt_clean_control_interface(struct pgt_device *pdev); + #include "mpt.h" #endif -- 1.9.1 _______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/intel-gfx