From patchwork Thu Jan 28 10:21:45 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Wang, Zhi A" X-Patchwork-Id: 8148641 Return-Path: X-Original-To: patchwork-intel-gfx@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 2AAC7BEEE5 for ; Thu, 28 Jan 2016 10:25:12 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 900422034C for ; Thu, 28 Jan 2016 10:25:09 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by mail.kernel.org (Postfix) with ESMTP id A53822034F for ; Thu, 28 Jan 2016 10:25:04 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id ABBE3720C5; Thu, 28 Jan 2016 02:25:03 -0800 (PST) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from mga01.intel.com (mga01.intel.com [192.55.52.88]) by gabe.freedesktop.org (Postfix) with ESMTP id 8AA0F6E7F8 for ; Thu, 28 Jan 2016 02:24:59 -0800 (PST) Received: from orsmga001.jf.intel.com ([10.7.209.18]) by fmsmga101.fm.intel.com with ESMTP; 28 Jan 2016 02:24:49 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.22,358,1449561600"; d="scan'208";a="870588670" Received: from dev-inno.bj.intel.com ([10.238.135.69]) by orsmga001.jf.intel.com with ESMTP; 28 Jan 2016 02:24:44 -0800 From: Zhi Wang To: intel-gfx@lists.freedesktop.org, igvt-g@lists.01.org Date: Thu, 28 Jan 2016 18:21:45 +0800 Message-Id: <1453976511-27322-24-git-send-email-zhi.a.wang@intel.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1453976511-27322-1-git-send-email-zhi.a.wang@intel.com> References: <1453976511-27322-1-git-send-email-zhi.a.wang@intel.com> Cc: daniel.vetter@ffwll.ch, david.j.cowperthwaite@intel.com Subject: [Intel-gfx] [RFC 23/29] drm/i915: gvt: Introduce GVT control interface X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" X-Spam-Status: No, score=-4.2 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Yi Sun This patch introduces the control interface for creating/destroying vGPUs. Signed-off-by: Yi Sun Signed-off-by: Zhi Wang --- 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