From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1750993AbdEaEws (ORCPT ); Wed, 31 May 2017 00:52:48 -0400 Received: from mga14.intel.com ([192.55.52.115]:59553 "EHLO mga14.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750778AbdEaEwr (ORCPT ); Wed, 31 May 2017 00:52:47 -0400 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.38,422,1491289200"; d="asc'?scan'208";a="1136421363" Date: Wed, 31 May 2017 12:47:21 +0800 From: Zhenyu Wang To: Xiaoguang Chen Cc: alex.williamson@redhat.com, kraxel@redhat.com, chris@chris-wilson.co.uk, intel-gfx@lists.freedesktop.org, linux-kernel@vger.kernel.org, zhenyuw@linux.intel.com, zhiyuan.lv@intel.com, intel-gvt-dev@lists.freedesktop.org, zhi.a.wang@intel.com, kevin.tian@intel.com, Bing Niu Subject: Re: [PATCH v6 2/6] drm/i915/gvt: OpRegion support for GVT-g Message-ID: <20170531044721.wpazhx267txbmvwb@zhen-hp.sh.intel.com> Reply-To: Zhenyu Wang References: <1495874332-2851-1-git-send-email-xiaoguang.chen@intel.com> <1495874332-2851-3-git-send-email-xiaoguang.chen@intel.com> MIME-Version: 1.0 Content-Type: multipart/signed; micalg=pgp-sha1; protocol="application/pgp-signature"; boundary="7fyju4krzsdyplsr" Content-Disposition: inline In-Reply-To: <1495874332-2851-3-git-send-email-xiaoguang.chen@intel.com> User-Agent: NeoMutt/20170306 (1.8.0) Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org --7fyju4krzsdyplsr Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-Transfer-Encoding: quoted-printable On 2017.05.27 16:38:48 +0800, Xiaoguang Chen wrote: > OpRegion is needed to support display related operation for > intel vgpu. >=20 > A vfio device region is added to intel vgpu to deliver the > host OpRegion information to user space so user space can > construct the OpRegion for vgpu. >=20 > Signed-off-by: Bing Niu > Signed-off-by: Xiaoguang Chen > --- > drivers/gpu/drm/i915/gvt/kvmgt.c | 97 +++++++++++++++++++++++++++++++= ++++++ > drivers/gpu/drm/i915/gvt/opregion.c | 8 ++- > 2 files changed, 104 insertions(+), 1 deletion(-) >=20 > diff --git a/drivers/gpu/drm/i915/gvt/kvmgt.c b/drivers/gpu/drm/i915/gvt/= kvmgt.c > index 3c6a02b..389f072 100644 > --- a/drivers/gpu/drm/i915/gvt/kvmgt.c > +++ b/drivers/gpu/drm/i915/gvt/kvmgt.c > @@ -53,6 +53,8 @@ static const struct intel_gvt_ops *intel_gvt_ops; > #define VFIO_PCI_INDEX_TO_OFFSET(index) ((u64)(index) << VFIO_PCI_OFFSET= _SHIFT) > #define VFIO_PCI_OFFSET_MASK (((u64)(1) << VFIO_PCI_OFFSET_SHIFT) - 1) > =20 > +#define OPREGION_SIGNATURE "IntelGraphicsMem" > + > struct vfio_region; > struct intel_vgpu_regops { > size_t (*rw)(struct intel_vgpu *vgpu, char *buf, > @@ -436,6 +438,92 @@ static void kvmgt_protect_table_del(struct kvmgt_gue= st_info *info, > } > } > =20 > +static size_t intel_vgpu_reg_rw_opregion(struct intel_vgpu *vgpu, char *= buf, > + size_t count, loff_t *ppos, bool iswrite) > +{ > + unsigned int i =3D VFIO_PCI_OFFSET_TO_INDEX(*ppos) - > + VFIO_PCI_NUM_REGIONS; > + void *base =3D vgpu->vdev.region[i].data; > + loff_t pos =3D *ppos & VFIO_PCI_OFFSET_MASK; > + > + if (pos >=3D vgpu->vdev.region[i].size || iswrite) { > + gvt_vgpu_err("invalid op or offset for Intel vgpu OpRegion\n"); > + return -EINVAL; > + } > + count =3D min(count, (size_t)(vgpu->vdev.region[i].size - pos)); > + memcpy(buf, base + pos, count); > + > + return count; > +} > + > +static void intel_vgpu_reg_release_opregion(struct intel_vgpu *vgpu, > + struct vfio_region *region) > +{ > + memunmap(region->data); > +} > + > +static const struct intel_vgpu_regops intel_vgpu_regops_opregion =3D { > + .rw =3D intel_vgpu_reg_rw_opregion, > + .release =3D intel_vgpu_reg_release_opregion, > +}; > + > +static int intel_vgpu_register_reg(struct intel_vgpu *vgpu, > + unsigned int type, unsigned int subtype, > + const struct intel_vgpu_regops *ops, > + size_t size, u32 flags, void *data) > +{ > + struct vfio_region *region; > + > + region =3D krealloc(vgpu->vdev.region, > + (vgpu->vdev.num_regions + 1) * sizeof(*region), > + GFP_KERNEL); > + if (!region) > + return -ENOMEM; > + > + vgpu->vdev.region =3D region; > + vgpu->vdev.region[vgpu->vdev.num_regions].type =3D type; > + vgpu->vdev.region[vgpu->vdev.num_regions].subtype =3D subtype; > + vgpu->vdev.region[vgpu->vdev.num_regions].ops =3D ops; > + vgpu->vdev.region[vgpu->vdev.num_regions].size =3D size; > + vgpu->vdev.region[vgpu->vdev.num_regions].flags =3D flags; > + vgpu->vdev.region[vgpu->vdev.num_regions].data =3D data; > + vgpu->vdev.num_regions++; > + > + return 0; > +} > + > +static int intel_vgpu_reg_init_opregion(struct intel_vgpu *vgpu) > +{ > + unsigned int addr; > + void *base; > + int ret; > + > + addr =3D vgpu->gvt->opregion.opregion_pa; > + if (!addr || !(~addr)) > + return -ENODEV; > + > + base =3D memremap(addr, OPREGION_SIZE, MEMREMAP_WB); > + if (!base) > + return -ENOMEM; > + > + if (memcmp(base, OPREGION_SIGNATURE, 16)) { > + memunmap(base); > + return -EINVAL; > + } > + > + ret =3D intel_vgpu_register_reg(vgpu, > + PCI_VENDOR_ID_INTEL | VFIO_REGION_TYPE_PCI_VENDOR_TYPE, > + VFIO_REGION_SUBTYPE_INTEL_IGD_OPREGION, > + &intel_vgpu_regops_opregion, OPREGION_SIZE, > + VFIO_REGION_INFO_FLAG_READ, base); > + if (ret) { > + memunmap(base); > + return ret; > + } > + > + return ret; > +} > + > static int intel_vgpu_create(struct kobject *kobj, struct mdev_device *m= dev) > { > struct intel_vgpu *vgpu =3D NULL; > @@ -467,6 +555,15 @@ static int intel_vgpu_create(struct kobject *kobj, s= truct mdev_device *mdev) > vgpu->vdev.mdev =3D mdev; > mdev_set_drvdata(mdev, vgpu); > =20 > + ret =3D intel_vgpu_reg_init_opregion(vgpu); > + if (ret) { > + gvt_vgpu_err("create OpRegion failed\n"); > + goto out; > + } Still need to handle error path for created vgpu. > + > + gvt_dbg_core("create OpRegion succeeded for mdev:%s\n", > + dev_name(mdev_dev(mdev))); > + > gvt_dbg_core("intel_vgpu_create succeeded for mdev: %s\n", > dev_name(mdev_dev(mdev))); > ret =3D 0; > diff --git a/drivers/gpu/drm/i915/gvt/opregion.c b/drivers/gpu/drm/i915/g= vt/opregion.c > index 3117991..5c7496d 100644 > --- a/drivers/gpu/drm/i915/gvt/opregion.c > +++ b/drivers/gpu/drm/i915/gvt/opregion.c > @@ -114,6 +114,7 @@ void intel_vgpu_clean_opregion(struct intel_vgpu *vgp= u) > int intel_vgpu_init_opregion(struct intel_vgpu *vgpu, u32 gpa) > { > int ret; > + unsigned long pfn; > =20 > gvt_dbg_core("vgpu%d: init vgpu opregion\n", vgpu->id); > =20 > @@ -127,7 +128,12 @@ int intel_vgpu_init_opregion(struct intel_vgpu *vgpu= , u32 gpa) > ret =3D map_vgpu_opregion(vgpu, true); > if (ret) > return ret; > - } > + } else { > + pfn =3D intel_gvt_hypervisor_gfn_to_mfn(vgpu, gpa >> PAGE_SHIFT); > + vgpu_opregion(vgpu)->va =3D memremap(pfn << PAGE_SHIFT, > + INTEL_GVT_OPREGION_SIZE, > + MEMREMAP_WB); > + } better to use switch for explicit KVM case, and no return check? > =20 > return 0; > } > --=20 > 2.7.4 >=20 --=20 Open Source Technology Center, Intel ltd. $gpg --keyserver wwwkeys.pgp.net --recv-keys 4D781827 --7fyju4krzsdyplsr Content-Type: application/pgp-signature; name="signature.asc" -----BEGIN PGP SIGNATURE----- iF0EARECAB0WIQTXuabgHDW6LPt9CICxBBozTXgYJwUCWS5K2AAKCRCxBBozTXgY JzqUAKCFiev/NyMvPlVNzbVE9TC2J66r6wCeO+COjWx30/JFTIlG/vRwfQ92bco= =TDkA -----END PGP SIGNATURE----- --7fyju4krzsdyplsr--