18c2ecf20Sopenharmony_ci/*
28c2ecf20Sopenharmony_ci * Copyright 2017 Intel Corporation. All rights reserved.
38c2ecf20Sopenharmony_ci *
48c2ecf20Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a
58c2ecf20Sopenharmony_ci * copy of this software and associated documentation files (the "Software"),
68c2ecf20Sopenharmony_ci * to deal in the Software without restriction, including without limitation
78c2ecf20Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense,
88c2ecf20Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the
98c2ecf20Sopenharmony_ci * Software is furnished to do so, subject to the following conditions:
108c2ecf20Sopenharmony_ci *
118c2ecf20Sopenharmony_ci * The above copyright notice and this permission notice (including the next
128c2ecf20Sopenharmony_ci * paragraph) shall be included in all copies or substantial portions of the
138c2ecf20Sopenharmony_ci * Software.
148c2ecf20Sopenharmony_ci *
158c2ecf20Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
168c2ecf20Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
178c2ecf20Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
188c2ecf20Sopenharmony_ci * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
198c2ecf20Sopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
208c2ecf20Sopenharmony_ci * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
218c2ecf20Sopenharmony_ci * DEALINGS IN THE SOFTWARE.
228c2ecf20Sopenharmony_ci *
238c2ecf20Sopenharmony_ci * Authors:
248c2ecf20Sopenharmony_ci *    Zhiyuan Lv <zhiyuan.lv@intel.com>
258c2ecf20Sopenharmony_ci *
268c2ecf20Sopenharmony_ci * Contributors:
278c2ecf20Sopenharmony_ci *    Xiaoguang Chen
288c2ecf20Sopenharmony_ci *    Tina Zhang <tina.zhang@intel.com>
298c2ecf20Sopenharmony_ci */
308c2ecf20Sopenharmony_ci
318c2ecf20Sopenharmony_ci#include <linux/dma-buf.h>
328c2ecf20Sopenharmony_ci#include <linux/vfio.h>
338c2ecf20Sopenharmony_ci
348c2ecf20Sopenharmony_ci#include "i915_drv.h"
358c2ecf20Sopenharmony_ci#include "gvt.h"
368c2ecf20Sopenharmony_ci
378c2ecf20Sopenharmony_ci#define GEN8_DECODE_PTE(pte) (pte & GENMASK_ULL(63, 12))
388c2ecf20Sopenharmony_ci
398c2ecf20Sopenharmony_cistatic int vgpu_pin_dma_address(struct intel_vgpu *vgpu,
408c2ecf20Sopenharmony_ci				unsigned long size,
418c2ecf20Sopenharmony_ci				dma_addr_t dma_addr)
428c2ecf20Sopenharmony_ci{
438c2ecf20Sopenharmony_ci	int ret = 0;
448c2ecf20Sopenharmony_ci
458c2ecf20Sopenharmony_ci	if (intel_gvt_hypervisor_dma_pin_guest_page(vgpu, dma_addr))
468c2ecf20Sopenharmony_ci		ret = -EINVAL;
478c2ecf20Sopenharmony_ci
488c2ecf20Sopenharmony_ci	return ret;
498c2ecf20Sopenharmony_ci}
508c2ecf20Sopenharmony_ci
518c2ecf20Sopenharmony_cistatic void vgpu_unpin_dma_address(struct intel_vgpu *vgpu,
528c2ecf20Sopenharmony_ci				   dma_addr_t dma_addr)
538c2ecf20Sopenharmony_ci{
548c2ecf20Sopenharmony_ci	intel_gvt_hypervisor_dma_unmap_guest_page(vgpu, dma_addr);
558c2ecf20Sopenharmony_ci}
568c2ecf20Sopenharmony_ci
578c2ecf20Sopenharmony_cistatic int vgpu_gem_get_pages(
588c2ecf20Sopenharmony_ci		struct drm_i915_gem_object *obj)
598c2ecf20Sopenharmony_ci{
608c2ecf20Sopenharmony_ci	struct drm_i915_private *dev_priv = to_i915(obj->base.dev);
618c2ecf20Sopenharmony_ci	struct intel_vgpu *vgpu;
628c2ecf20Sopenharmony_ci	struct sg_table *st;
638c2ecf20Sopenharmony_ci	struct scatterlist *sg;
648c2ecf20Sopenharmony_ci	int i, j, ret;
658c2ecf20Sopenharmony_ci	gen8_pte_t __iomem *gtt_entries;
668c2ecf20Sopenharmony_ci	struct intel_vgpu_fb_info *fb_info;
678c2ecf20Sopenharmony_ci	u32 page_num;
688c2ecf20Sopenharmony_ci
698c2ecf20Sopenharmony_ci	fb_info = (struct intel_vgpu_fb_info *)obj->gvt_info;
708c2ecf20Sopenharmony_ci	if (drm_WARN_ON(&dev_priv->drm, !fb_info))
718c2ecf20Sopenharmony_ci		return -ENODEV;
728c2ecf20Sopenharmony_ci
738c2ecf20Sopenharmony_ci	vgpu = fb_info->obj->vgpu;
748c2ecf20Sopenharmony_ci	if (drm_WARN_ON(&dev_priv->drm, !vgpu))
758c2ecf20Sopenharmony_ci		return -ENODEV;
768c2ecf20Sopenharmony_ci
778c2ecf20Sopenharmony_ci	st = kmalloc(sizeof(*st), GFP_KERNEL);
788c2ecf20Sopenharmony_ci	if (unlikely(!st))
798c2ecf20Sopenharmony_ci		return -ENOMEM;
808c2ecf20Sopenharmony_ci
818c2ecf20Sopenharmony_ci	page_num = obj->base.size >> PAGE_SHIFT;
828c2ecf20Sopenharmony_ci	ret = sg_alloc_table(st, page_num, GFP_KERNEL);
838c2ecf20Sopenharmony_ci	if (ret) {
848c2ecf20Sopenharmony_ci		kfree(st);
858c2ecf20Sopenharmony_ci		return ret;
868c2ecf20Sopenharmony_ci	}
878c2ecf20Sopenharmony_ci	gtt_entries = (gen8_pte_t __iomem *)dev_priv->ggtt.gsm +
888c2ecf20Sopenharmony_ci		(fb_info->start >> PAGE_SHIFT);
898c2ecf20Sopenharmony_ci	for_each_sg(st->sgl, sg, page_num, i) {
908c2ecf20Sopenharmony_ci		dma_addr_t dma_addr =
918c2ecf20Sopenharmony_ci			GEN8_DECODE_PTE(readq(&gtt_entries[i]));
928c2ecf20Sopenharmony_ci		if (vgpu_pin_dma_address(vgpu, PAGE_SIZE, dma_addr)) {
938c2ecf20Sopenharmony_ci			ret = -EINVAL;
948c2ecf20Sopenharmony_ci			goto out;
958c2ecf20Sopenharmony_ci		}
968c2ecf20Sopenharmony_ci
978c2ecf20Sopenharmony_ci		sg->offset = 0;
988c2ecf20Sopenharmony_ci		sg->length = PAGE_SIZE;
998c2ecf20Sopenharmony_ci		sg_dma_len(sg) = PAGE_SIZE;
1008c2ecf20Sopenharmony_ci		sg_dma_address(sg) = dma_addr;
1018c2ecf20Sopenharmony_ci	}
1028c2ecf20Sopenharmony_ci
1038c2ecf20Sopenharmony_ci	__i915_gem_object_set_pages(obj, st, PAGE_SIZE);
1048c2ecf20Sopenharmony_ciout:
1058c2ecf20Sopenharmony_ci	if (ret) {
1068c2ecf20Sopenharmony_ci		dma_addr_t dma_addr;
1078c2ecf20Sopenharmony_ci
1088c2ecf20Sopenharmony_ci		for_each_sg(st->sgl, sg, i, j) {
1098c2ecf20Sopenharmony_ci			dma_addr = sg_dma_address(sg);
1108c2ecf20Sopenharmony_ci			if (dma_addr)
1118c2ecf20Sopenharmony_ci				vgpu_unpin_dma_address(vgpu, dma_addr);
1128c2ecf20Sopenharmony_ci		}
1138c2ecf20Sopenharmony_ci		sg_free_table(st);
1148c2ecf20Sopenharmony_ci		kfree(st);
1158c2ecf20Sopenharmony_ci	}
1168c2ecf20Sopenharmony_ci
1178c2ecf20Sopenharmony_ci	return ret;
1188c2ecf20Sopenharmony_ci
1198c2ecf20Sopenharmony_ci}
1208c2ecf20Sopenharmony_ci
1218c2ecf20Sopenharmony_cistatic void vgpu_gem_put_pages(struct drm_i915_gem_object *obj,
1228c2ecf20Sopenharmony_ci		struct sg_table *pages)
1238c2ecf20Sopenharmony_ci{
1248c2ecf20Sopenharmony_ci	struct scatterlist *sg;
1258c2ecf20Sopenharmony_ci
1268c2ecf20Sopenharmony_ci	if (obj->base.dma_buf) {
1278c2ecf20Sopenharmony_ci		struct intel_vgpu_fb_info *fb_info = obj->gvt_info;
1288c2ecf20Sopenharmony_ci		struct intel_vgpu_dmabuf_obj *obj = fb_info->obj;
1298c2ecf20Sopenharmony_ci		struct intel_vgpu *vgpu = obj->vgpu;
1308c2ecf20Sopenharmony_ci		int i;
1318c2ecf20Sopenharmony_ci
1328c2ecf20Sopenharmony_ci		for_each_sg(pages->sgl, sg, fb_info->size, i)
1338c2ecf20Sopenharmony_ci			vgpu_unpin_dma_address(vgpu,
1348c2ecf20Sopenharmony_ci					       sg_dma_address(sg));
1358c2ecf20Sopenharmony_ci	}
1368c2ecf20Sopenharmony_ci
1378c2ecf20Sopenharmony_ci	sg_free_table(pages);
1388c2ecf20Sopenharmony_ci	kfree(pages);
1398c2ecf20Sopenharmony_ci}
1408c2ecf20Sopenharmony_ci
1418c2ecf20Sopenharmony_cistatic void dmabuf_gem_object_free(struct kref *kref)
1428c2ecf20Sopenharmony_ci{
1438c2ecf20Sopenharmony_ci	struct intel_vgpu_dmabuf_obj *obj =
1448c2ecf20Sopenharmony_ci		container_of(kref, struct intel_vgpu_dmabuf_obj, kref);
1458c2ecf20Sopenharmony_ci	struct intel_vgpu *vgpu = obj->vgpu;
1468c2ecf20Sopenharmony_ci	struct list_head *pos;
1478c2ecf20Sopenharmony_ci	struct intel_vgpu_dmabuf_obj *dmabuf_obj;
1488c2ecf20Sopenharmony_ci
1498c2ecf20Sopenharmony_ci	if (vgpu && vgpu->active && !list_empty(&vgpu->dmabuf_obj_list_head)) {
1508c2ecf20Sopenharmony_ci		list_for_each(pos, &vgpu->dmabuf_obj_list_head) {
1518c2ecf20Sopenharmony_ci			dmabuf_obj = container_of(pos,
1528c2ecf20Sopenharmony_ci					struct intel_vgpu_dmabuf_obj, list);
1538c2ecf20Sopenharmony_ci			if (dmabuf_obj == obj) {
1548c2ecf20Sopenharmony_ci				list_del(pos);
1558c2ecf20Sopenharmony_ci				intel_gvt_hypervisor_put_vfio_device(vgpu);
1568c2ecf20Sopenharmony_ci				idr_remove(&vgpu->object_idr,
1578c2ecf20Sopenharmony_ci					   dmabuf_obj->dmabuf_id);
1588c2ecf20Sopenharmony_ci				kfree(dmabuf_obj->info);
1598c2ecf20Sopenharmony_ci				kfree(dmabuf_obj);
1608c2ecf20Sopenharmony_ci				break;
1618c2ecf20Sopenharmony_ci			}
1628c2ecf20Sopenharmony_ci		}
1638c2ecf20Sopenharmony_ci	} else {
1648c2ecf20Sopenharmony_ci		/* Free the orphan dmabuf_objs here */
1658c2ecf20Sopenharmony_ci		kfree(obj->info);
1668c2ecf20Sopenharmony_ci		kfree(obj);
1678c2ecf20Sopenharmony_ci	}
1688c2ecf20Sopenharmony_ci}
1698c2ecf20Sopenharmony_ci
1708c2ecf20Sopenharmony_ci
1718c2ecf20Sopenharmony_cistatic inline void dmabuf_obj_get(struct intel_vgpu_dmabuf_obj *obj)
1728c2ecf20Sopenharmony_ci{
1738c2ecf20Sopenharmony_ci	kref_get(&obj->kref);
1748c2ecf20Sopenharmony_ci}
1758c2ecf20Sopenharmony_ci
1768c2ecf20Sopenharmony_cistatic inline void dmabuf_obj_put(struct intel_vgpu_dmabuf_obj *obj)
1778c2ecf20Sopenharmony_ci{
1788c2ecf20Sopenharmony_ci	kref_put(&obj->kref, dmabuf_gem_object_free);
1798c2ecf20Sopenharmony_ci}
1808c2ecf20Sopenharmony_ci
1818c2ecf20Sopenharmony_cistatic void vgpu_gem_release(struct drm_i915_gem_object *gem_obj)
1828c2ecf20Sopenharmony_ci{
1838c2ecf20Sopenharmony_ci
1848c2ecf20Sopenharmony_ci	struct intel_vgpu_fb_info *fb_info = gem_obj->gvt_info;
1858c2ecf20Sopenharmony_ci	struct intel_vgpu_dmabuf_obj *obj = fb_info->obj;
1868c2ecf20Sopenharmony_ci	struct intel_vgpu *vgpu = obj->vgpu;
1878c2ecf20Sopenharmony_ci
1888c2ecf20Sopenharmony_ci	if (vgpu) {
1898c2ecf20Sopenharmony_ci		mutex_lock(&vgpu->dmabuf_lock);
1908c2ecf20Sopenharmony_ci		gem_obj->base.dma_buf = NULL;
1918c2ecf20Sopenharmony_ci		dmabuf_obj_put(obj);
1928c2ecf20Sopenharmony_ci		mutex_unlock(&vgpu->dmabuf_lock);
1938c2ecf20Sopenharmony_ci	} else {
1948c2ecf20Sopenharmony_ci		/* vgpu is NULL, as it has been removed already */
1958c2ecf20Sopenharmony_ci		gem_obj->base.dma_buf = NULL;
1968c2ecf20Sopenharmony_ci		dmabuf_obj_put(obj);
1978c2ecf20Sopenharmony_ci	}
1988c2ecf20Sopenharmony_ci}
1998c2ecf20Sopenharmony_ci
2008c2ecf20Sopenharmony_cistatic const struct drm_i915_gem_object_ops intel_vgpu_gem_ops = {
2018c2ecf20Sopenharmony_ci	.name = "i915_gem_object_vgpu",
2028c2ecf20Sopenharmony_ci	.flags = I915_GEM_OBJECT_IS_PROXY,
2038c2ecf20Sopenharmony_ci	.get_pages = vgpu_gem_get_pages,
2048c2ecf20Sopenharmony_ci	.put_pages = vgpu_gem_put_pages,
2058c2ecf20Sopenharmony_ci	.release = vgpu_gem_release,
2068c2ecf20Sopenharmony_ci};
2078c2ecf20Sopenharmony_ci
2088c2ecf20Sopenharmony_cistatic struct drm_i915_gem_object *vgpu_create_gem(struct drm_device *dev,
2098c2ecf20Sopenharmony_ci		struct intel_vgpu_fb_info *info)
2108c2ecf20Sopenharmony_ci{
2118c2ecf20Sopenharmony_ci	static struct lock_class_key lock_class;
2128c2ecf20Sopenharmony_ci	struct drm_i915_private *dev_priv = to_i915(dev);
2138c2ecf20Sopenharmony_ci	struct drm_i915_gem_object *obj;
2148c2ecf20Sopenharmony_ci
2158c2ecf20Sopenharmony_ci	obj = i915_gem_object_alloc();
2168c2ecf20Sopenharmony_ci	if (obj == NULL)
2178c2ecf20Sopenharmony_ci		return NULL;
2188c2ecf20Sopenharmony_ci
2198c2ecf20Sopenharmony_ci	drm_gem_private_object_init(dev, &obj->base,
2208c2ecf20Sopenharmony_ci		roundup(info->size, PAGE_SIZE));
2218c2ecf20Sopenharmony_ci	i915_gem_object_init(obj, &intel_vgpu_gem_ops, &lock_class);
2228c2ecf20Sopenharmony_ci	i915_gem_object_set_readonly(obj);
2238c2ecf20Sopenharmony_ci
2248c2ecf20Sopenharmony_ci	obj->read_domains = I915_GEM_DOMAIN_GTT;
2258c2ecf20Sopenharmony_ci	obj->write_domain = 0;
2268c2ecf20Sopenharmony_ci	if (INTEL_GEN(dev_priv) >= 9) {
2278c2ecf20Sopenharmony_ci		unsigned int tiling_mode = 0;
2288c2ecf20Sopenharmony_ci		unsigned int stride = 0;
2298c2ecf20Sopenharmony_ci
2308c2ecf20Sopenharmony_ci		switch (info->drm_format_mod) {
2318c2ecf20Sopenharmony_ci		case DRM_FORMAT_MOD_LINEAR:
2328c2ecf20Sopenharmony_ci			tiling_mode = I915_TILING_NONE;
2338c2ecf20Sopenharmony_ci			break;
2348c2ecf20Sopenharmony_ci		case I915_FORMAT_MOD_X_TILED:
2358c2ecf20Sopenharmony_ci			tiling_mode = I915_TILING_X;
2368c2ecf20Sopenharmony_ci			stride = info->stride;
2378c2ecf20Sopenharmony_ci			break;
2388c2ecf20Sopenharmony_ci		case I915_FORMAT_MOD_Y_TILED:
2398c2ecf20Sopenharmony_ci		case I915_FORMAT_MOD_Yf_TILED:
2408c2ecf20Sopenharmony_ci			tiling_mode = I915_TILING_Y;
2418c2ecf20Sopenharmony_ci			stride = info->stride;
2428c2ecf20Sopenharmony_ci			break;
2438c2ecf20Sopenharmony_ci		default:
2448c2ecf20Sopenharmony_ci			gvt_dbg_core("invalid drm_format_mod %llx for tiling\n",
2458c2ecf20Sopenharmony_ci				     info->drm_format_mod);
2468c2ecf20Sopenharmony_ci		}
2478c2ecf20Sopenharmony_ci		obj->tiling_and_stride = tiling_mode | stride;
2488c2ecf20Sopenharmony_ci	} else {
2498c2ecf20Sopenharmony_ci		obj->tiling_and_stride = info->drm_format_mod ?
2508c2ecf20Sopenharmony_ci					I915_TILING_X : 0;
2518c2ecf20Sopenharmony_ci	}
2528c2ecf20Sopenharmony_ci
2538c2ecf20Sopenharmony_ci	return obj;
2548c2ecf20Sopenharmony_ci}
2558c2ecf20Sopenharmony_ci
2568c2ecf20Sopenharmony_cistatic bool validate_hotspot(struct intel_vgpu_cursor_plane_format *c)
2578c2ecf20Sopenharmony_ci{
2588c2ecf20Sopenharmony_ci	if (c && c->x_hot <= c->width && c->y_hot <= c->height)
2598c2ecf20Sopenharmony_ci		return true;
2608c2ecf20Sopenharmony_ci	else
2618c2ecf20Sopenharmony_ci		return false;
2628c2ecf20Sopenharmony_ci}
2638c2ecf20Sopenharmony_ci
2648c2ecf20Sopenharmony_cistatic int vgpu_get_plane_info(struct drm_device *dev,
2658c2ecf20Sopenharmony_ci		struct intel_vgpu *vgpu,
2668c2ecf20Sopenharmony_ci		struct intel_vgpu_fb_info *info,
2678c2ecf20Sopenharmony_ci		int plane_id)
2688c2ecf20Sopenharmony_ci{
2698c2ecf20Sopenharmony_ci	struct intel_vgpu_primary_plane_format p;
2708c2ecf20Sopenharmony_ci	struct intel_vgpu_cursor_plane_format c;
2718c2ecf20Sopenharmony_ci	int ret, tile_height = 1;
2728c2ecf20Sopenharmony_ci
2738c2ecf20Sopenharmony_ci	memset(info, 0, sizeof(*info));
2748c2ecf20Sopenharmony_ci
2758c2ecf20Sopenharmony_ci	if (plane_id == DRM_PLANE_TYPE_PRIMARY) {
2768c2ecf20Sopenharmony_ci		ret = intel_vgpu_decode_primary_plane(vgpu, &p);
2778c2ecf20Sopenharmony_ci		if (ret)
2788c2ecf20Sopenharmony_ci			return ret;
2798c2ecf20Sopenharmony_ci		info->start = p.base;
2808c2ecf20Sopenharmony_ci		info->start_gpa = p.base_gpa;
2818c2ecf20Sopenharmony_ci		info->width = p.width;
2828c2ecf20Sopenharmony_ci		info->height = p.height;
2838c2ecf20Sopenharmony_ci		info->stride = p.stride;
2848c2ecf20Sopenharmony_ci		info->drm_format = p.drm_format;
2858c2ecf20Sopenharmony_ci
2868c2ecf20Sopenharmony_ci		switch (p.tiled) {
2878c2ecf20Sopenharmony_ci		case PLANE_CTL_TILED_LINEAR:
2888c2ecf20Sopenharmony_ci			info->drm_format_mod = DRM_FORMAT_MOD_LINEAR;
2898c2ecf20Sopenharmony_ci			break;
2908c2ecf20Sopenharmony_ci		case PLANE_CTL_TILED_X:
2918c2ecf20Sopenharmony_ci			info->drm_format_mod = I915_FORMAT_MOD_X_TILED;
2928c2ecf20Sopenharmony_ci			tile_height = 8;
2938c2ecf20Sopenharmony_ci			break;
2948c2ecf20Sopenharmony_ci		case PLANE_CTL_TILED_Y:
2958c2ecf20Sopenharmony_ci			info->drm_format_mod = I915_FORMAT_MOD_Y_TILED;
2968c2ecf20Sopenharmony_ci			tile_height = 32;
2978c2ecf20Sopenharmony_ci			break;
2988c2ecf20Sopenharmony_ci		case PLANE_CTL_TILED_YF:
2998c2ecf20Sopenharmony_ci			info->drm_format_mod = I915_FORMAT_MOD_Yf_TILED;
3008c2ecf20Sopenharmony_ci			tile_height = 32;
3018c2ecf20Sopenharmony_ci			break;
3028c2ecf20Sopenharmony_ci		default:
3038c2ecf20Sopenharmony_ci			gvt_vgpu_err("invalid tiling mode: %x\n", p.tiled);
3048c2ecf20Sopenharmony_ci		}
3058c2ecf20Sopenharmony_ci	} else if (plane_id == DRM_PLANE_TYPE_CURSOR) {
3068c2ecf20Sopenharmony_ci		ret = intel_vgpu_decode_cursor_plane(vgpu, &c);
3078c2ecf20Sopenharmony_ci		if (ret)
3088c2ecf20Sopenharmony_ci			return ret;
3098c2ecf20Sopenharmony_ci		info->start = c.base;
3108c2ecf20Sopenharmony_ci		info->start_gpa = c.base_gpa;
3118c2ecf20Sopenharmony_ci		info->width = c.width;
3128c2ecf20Sopenharmony_ci		info->height = c.height;
3138c2ecf20Sopenharmony_ci		info->stride = c.width * (c.bpp / 8);
3148c2ecf20Sopenharmony_ci		info->drm_format = c.drm_format;
3158c2ecf20Sopenharmony_ci		info->drm_format_mod = 0;
3168c2ecf20Sopenharmony_ci		info->x_pos = c.x_pos;
3178c2ecf20Sopenharmony_ci		info->y_pos = c.y_pos;
3188c2ecf20Sopenharmony_ci
3198c2ecf20Sopenharmony_ci		if (validate_hotspot(&c)) {
3208c2ecf20Sopenharmony_ci			info->x_hot = c.x_hot;
3218c2ecf20Sopenharmony_ci			info->y_hot = c.y_hot;
3228c2ecf20Sopenharmony_ci		} else {
3238c2ecf20Sopenharmony_ci			info->x_hot = UINT_MAX;
3248c2ecf20Sopenharmony_ci			info->y_hot = UINT_MAX;
3258c2ecf20Sopenharmony_ci		}
3268c2ecf20Sopenharmony_ci	} else {
3278c2ecf20Sopenharmony_ci		gvt_vgpu_err("invalid plane id:%d\n", plane_id);
3288c2ecf20Sopenharmony_ci		return -EINVAL;
3298c2ecf20Sopenharmony_ci	}
3308c2ecf20Sopenharmony_ci
3318c2ecf20Sopenharmony_ci	info->size = info->stride * roundup(info->height, tile_height);
3328c2ecf20Sopenharmony_ci	if (info->size == 0) {
3338c2ecf20Sopenharmony_ci		gvt_vgpu_err("fb size is zero\n");
3348c2ecf20Sopenharmony_ci		return -EINVAL;
3358c2ecf20Sopenharmony_ci	}
3368c2ecf20Sopenharmony_ci
3378c2ecf20Sopenharmony_ci	if (info->start & (PAGE_SIZE - 1)) {
3388c2ecf20Sopenharmony_ci		gvt_vgpu_err("Not aligned fb address:0x%llx\n", info->start);
3398c2ecf20Sopenharmony_ci		return -EFAULT;
3408c2ecf20Sopenharmony_ci	}
3418c2ecf20Sopenharmony_ci
3428c2ecf20Sopenharmony_ci	if (!intel_gvt_ggtt_validate_range(vgpu, info->start, info->size)) {
3438c2ecf20Sopenharmony_ci		gvt_vgpu_err("invalid gma addr\n");
3448c2ecf20Sopenharmony_ci		return -EFAULT;
3458c2ecf20Sopenharmony_ci	}
3468c2ecf20Sopenharmony_ci
3478c2ecf20Sopenharmony_ci	return 0;
3488c2ecf20Sopenharmony_ci}
3498c2ecf20Sopenharmony_ci
3508c2ecf20Sopenharmony_cistatic struct intel_vgpu_dmabuf_obj *
3518c2ecf20Sopenharmony_cipick_dmabuf_by_info(struct intel_vgpu *vgpu,
3528c2ecf20Sopenharmony_ci		    struct intel_vgpu_fb_info *latest_info)
3538c2ecf20Sopenharmony_ci{
3548c2ecf20Sopenharmony_ci	struct list_head *pos;
3558c2ecf20Sopenharmony_ci	struct intel_vgpu_fb_info *fb_info;
3568c2ecf20Sopenharmony_ci	struct intel_vgpu_dmabuf_obj *dmabuf_obj = NULL;
3578c2ecf20Sopenharmony_ci	struct intel_vgpu_dmabuf_obj *ret = NULL;
3588c2ecf20Sopenharmony_ci
3598c2ecf20Sopenharmony_ci	list_for_each(pos, &vgpu->dmabuf_obj_list_head) {
3608c2ecf20Sopenharmony_ci		dmabuf_obj = container_of(pos, struct intel_vgpu_dmabuf_obj,
3618c2ecf20Sopenharmony_ci						list);
3628c2ecf20Sopenharmony_ci		if ((dmabuf_obj == NULL) ||
3638c2ecf20Sopenharmony_ci		    (dmabuf_obj->info == NULL))
3648c2ecf20Sopenharmony_ci			continue;
3658c2ecf20Sopenharmony_ci
3668c2ecf20Sopenharmony_ci		fb_info = (struct intel_vgpu_fb_info *)dmabuf_obj->info;
3678c2ecf20Sopenharmony_ci		if ((fb_info->start == latest_info->start) &&
3688c2ecf20Sopenharmony_ci		    (fb_info->start_gpa == latest_info->start_gpa) &&
3698c2ecf20Sopenharmony_ci		    (fb_info->size == latest_info->size) &&
3708c2ecf20Sopenharmony_ci		    (fb_info->drm_format_mod == latest_info->drm_format_mod) &&
3718c2ecf20Sopenharmony_ci		    (fb_info->drm_format == latest_info->drm_format) &&
3728c2ecf20Sopenharmony_ci		    (fb_info->width == latest_info->width) &&
3738c2ecf20Sopenharmony_ci		    (fb_info->height == latest_info->height)) {
3748c2ecf20Sopenharmony_ci			ret = dmabuf_obj;
3758c2ecf20Sopenharmony_ci			break;
3768c2ecf20Sopenharmony_ci		}
3778c2ecf20Sopenharmony_ci	}
3788c2ecf20Sopenharmony_ci
3798c2ecf20Sopenharmony_ci	return ret;
3808c2ecf20Sopenharmony_ci}
3818c2ecf20Sopenharmony_ci
3828c2ecf20Sopenharmony_cistatic struct intel_vgpu_dmabuf_obj *
3838c2ecf20Sopenharmony_cipick_dmabuf_by_num(struct intel_vgpu *vgpu, u32 id)
3848c2ecf20Sopenharmony_ci{
3858c2ecf20Sopenharmony_ci	struct list_head *pos;
3868c2ecf20Sopenharmony_ci	struct intel_vgpu_dmabuf_obj *dmabuf_obj = NULL;
3878c2ecf20Sopenharmony_ci	struct intel_vgpu_dmabuf_obj *ret = NULL;
3888c2ecf20Sopenharmony_ci
3898c2ecf20Sopenharmony_ci	list_for_each(pos, &vgpu->dmabuf_obj_list_head) {
3908c2ecf20Sopenharmony_ci		dmabuf_obj = container_of(pos, struct intel_vgpu_dmabuf_obj,
3918c2ecf20Sopenharmony_ci						list);
3928c2ecf20Sopenharmony_ci		if (!dmabuf_obj)
3938c2ecf20Sopenharmony_ci			continue;
3948c2ecf20Sopenharmony_ci
3958c2ecf20Sopenharmony_ci		if (dmabuf_obj->dmabuf_id == id) {
3968c2ecf20Sopenharmony_ci			ret = dmabuf_obj;
3978c2ecf20Sopenharmony_ci			break;
3988c2ecf20Sopenharmony_ci		}
3998c2ecf20Sopenharmony_ci	}
4008c2ecf20Sopenharmony_ci
4018c2ecf20Sopenharmony_ci	return ret;
4028c2ecf20Sopenharmony_ci}
4038c2ecf20Sopenharmony_ci
4048c2ecf20Sopenharmony_cistatic void update_fb_info(struct vfio_device_gfx_plane_info *gvt_dmabuf,
4058c2ecf20Sopenharmony_ci		      struct intel_vgpu_fb_info *fb_info)
4068c2ecf20Sopenharmony_ci{
4078c2ecf20Sopenharmony_ci	gvt_dmabuf->drm_format = fb_info->drm_format;
4088c2ecf20Sopenharmony_ci	gvt_dmabuf->drm_format_mod = fb_info->drm_format_mod;
4098c2ecf20Sopenharmony_ci	gvt_dmabuf->width = fb_info->width;
4108c2ecf20Sopenharmony_ci	gvt_dmabuf->height = fb_info->height;
4118c2ecf20Sopenharmony_ci	gvt_dmabuf->stride = fb_info->stride;
4128c2ecf20Sopenharmony_ci	gvt_dmabuf->size = fb_info->size;
4138c2ecf20Sopenharmony_ci	gvt_dmabuf->x_pos = fb_info->x_pos;
4148c2ecf20Sopenharmony_ci	gvt_dmabuf->y_pos = fb_info->y_pos;
4158c2ecf20Sopenharmony_ci	gvt_dmabuf->x_hot = fb_info->x_hot;
4168c2ecf20Sopenharmony_ci	gvt_dmabuf->y_hot = fb_info->y_hot;
4178c2ecf20Sopenharmony_ci}
4188c2ecf20Sopenharmony_ci
4198c2ecf20Sopenharmony_ciint intel_vgpu_query_plane(struct intel_vgpu *vgpu, void *args)
4208c2ecf20Sopenharmony_ci{
4218c2ecf20Sopenharmony_ci	struct drm_device *dev = &vgpu->gvt->gt->i915->drm;
4228c2ecf20Sopenharmony_ci	struct vfio_device_gfx_plane_info *gfx_plane_info = args;
4238c2ecf20Sopenharmony_ci	struct intel_vgpu_dmabuf_obj *dmabuf_obj;
4248c2ecf20Sopenharmony_ci	struct intel_vgpu_fb_info fb_info;
4258c2ecf20Sopenharmony_ci	int ret = 0;
4268c2ecf20Sopenharmony_ci
4278c2ecf20Sopenharmony_ci	if (gfx_plane_info->flags == (VFIO_GFX_PLANE_TYPE_DMABUF |
4288c2ecf20Sopenharmony_ci				       VFIO_GFX_PLANE_TYPE_PROBE))
4298c2ecf20Sopenharmony_ci		return ret;
4308c2ecf20Sopenharmony_ci	else if ((gfx_plane_info->flags & ~VFIO_GFX_PLANE_TYPE_DMABUF) ||
4318c2ecf20Sopenharmony_ci			(!gfx_plane_info->flags))
4328c2ecf20Sopenharmony_ci		return -EINVAL;
4338c2ecf20Sopenharmony_ci
4348c2ecf20Sopenharmony_ci	ret = vgpu_get_plane_info(dev, vgpu, &fb_info,
4358c2ecf20Sopenharmony_ci					gfx_plane_info->drm_plane_type);
4368c2ecf20Sopenharmony_ci	if (ret != 0)
4378c2ecf20Sopenharmony_ci		goto out;
4388c2ecf20Sopenharmony_ci
4398c2ecf20Sopenharmony_ci	mutex_lock(&vgpu->dmabuf_lock);
4408c2ecf20Sopenharmony_ci	/* If exists, pick up the exposed dmabuf_obj */
4418c2ecf20Sopenharmony_ci	dmabuf_obj = pick_dmabuf_by_info(vgpu, &fb_info);
4428c2ecf20Sopenharmony_ci	if (dmabuf_obj) {
4438c2ecf20Sopenharmony_ci		update_fb_info(gfx_plane_info, &fb_info);
4448c2ecf20Sopenharmony_ci		gfx_plane_info->dmabuf_id = dmabuf_obj->dmabuf_id;
4458c2ecf20Sopenharmony_ci
4468c2ecf20Sopenharmony_ci		/* This buffer may be released between query_plane ioctl and
4478c2ecf20Sopenharmony_ci		 * get_dmabuf ioctl. Add the refcount to make sure it won't
4488c2ecf20Sopenharmony_ci		 * be released between the two ioctls.
4498c2ecf20Sopenharmony_ci		 */
4508c2ecf20Sopenharmony_ci		if (!dmabuf_obj->initref) {
4518c2ecf20Sopenharmony_ci			dmabuf_obj->initref = true;
4528c2ecf20Sopenharmony_ci			dmabuf_obj_get(dmabuf_obj);
4538c2ecf20Sopenharmony_ci		}
4548c2ecf20Sopenharmony_ci		ret = 0;
4558c2ecf20Sopenharmony_ci		gvt_dbg_dpy("vgpu%d: re-use dmabuf_obj ref %d, id %d\n",
4568c2ecf20Sopenharmony_ci			    vgpu->id, kref_read(&dmabuf_obj->kref),
4578c2ecf20Sopenharmony_ci			    gfx_plane_info->dmabuf_id);
4588c2ecf20Sopenharmony_ci		mutex_unlock(&vgpu->dmabuf_lock);
4598c2ecf20Sopenharmony_ci		goto out;
4608c2ecf20Sopenharmony_ci	}
4618c2ecf20Sopenharmony_ci
4628c2ecf20Sopenharmony_ci	mutex_unlock(&vgpu->dmabuf_lock);
4638c2ecf20Sopenharmony_ci
4648c2ecf20Sopenharmony_ci	/* Need to allocate a new one*/
4658c2ecf20Sopenharmony_ci	dmabuf_obj = kmalloc(sizeof(struct intel_vgpu_dmabuf_obj), GFP_KERNEL);
4668c2ecf20Sopenharmony_ci	if (unlikely(!dmabuf_obj)) {
4678c2ecf20Sopenharmony_ci		gvt_vgpu_err("alloc dmabuf_obj failed\n");
4688c2ecf20Sopenharmony_ci		ret = -ENOMEM;
4698c2ecf20Sopenharmony_ci		goto out;
4708c2ecf20Sopenharmony_ci	}
4718c2ecf20Sopenharmony_ci
4728c2ecf20Sopenharmony_ci	dmabuf_obj->info = kmalloc(sizeof(struct intel_vgpu_fb_info),
4738c2ecf20Sopenharmony_ci				   GFP_KERNEL);
4748c2ecf20Sopenharmony_ci	if (unlikely(!dmabuf_obj->info)) {
4758c2ecf20Sopenharmony_ci		gvt_vgpu_err("allocate intel vgpu fb info failed\n");
4768c2ecf20Sopenharmony_ci		ret = -ENOMEM;
4778c2ecf20Sopenharmony_ci		goto out_free_dmabuf;
4788c2ecf20Sopenharmony_ci	}
4798c2ecf20Sopenharmony_ci	memcpy(dmabuf_obj->info, &fb_info, sizeof(struct intel_vgpu_fb_info));
4808c2ecf20Sopenharmony_ci
4818c2ecf20Sopenharmony_ci	((struct intel_vgpu_fb_info *)dmabuf_obj->info)->obj = dmabuf_obj;
4828c2ecf20Sopenharmony_ci
4838c2ecf20Sopenharmony_ci	dmabuf_obj->vgpu = vgpu;
4848c2ecf20Sopenharmony_ci
4858c2ecf20Sopenharmony_ci	ret = idr_alloc(&vgpu->object_idr, dmabuf_obj, 1, 0, GFP_NOWAIT);
4868c2ecf20Sopenharmony_ci	if (ret < 0)
4878c2ecf20Sopenharmony_ci		goto out_free_info;
4888c2ecf20Sopenharmony_ci	gfx_plane_info->dmabuf_id = ret;
4898c2ecf20Sopenharmony_ci	dmabuf_obj->dmabuf_id = ret;
4908c2ecf20Sopenharmony_ci
4918c2ecf20Sopenharmony_ci	dmabuf_obj->initref = true;
4928c2ecf20Sopenharmony_ci
4938c2ecf20Sopenharmony_ci	kref_init(&dmabuf_obj->kref);
4948c2ecf20Sopenharmony_ci
4958c2ecf20Sopenharmony_ci	mutex_lock(&vgpu->dmabuf_lock);
4968c2ecf20Sopenharmony_ci	if (intel_gvt_hypervisor_get_vfio_device(vgpu)) {
4978c2ecf20Sopenharmony_ci		gvt_vgpu_err("get vfio device failed\n");
4988c2ecf20Sopenharmony_ci		mutex_unlock(&vgpu->dmabuf_lock);
4998c2ecf20Sopenharmony_ci		goto out_free_info;
5008c2ecf20Sopenharmony_ci	}
5018c2ecf20Sopenharmony_ci	mutex_unlock(&vgpu->dmabuf_lock);
5028c2ecf20Sopenharmony_ci
5038c2ecf20Sopenharmony_ci	update_fb_info(gfx_plane_info, &fb_info);
5048c2ecf20Sopenharmony_ci
5058c2ecf20Sopenharmony_ci	INIT_LIST_HEAD(&dmabuf_obj->list);
5068c2ecf20Sopenharmony_ci	mutex_lock(&vgpu->dmabuf_lock);
5078c2ecf20Sopenharmony_ci	list_add_tail(&dmabuf_obj->list, &vgpu->dmabuf_obj_list_head);
5088c2ecf20Sopenharmony_ci	mutex_unlock(&vgpu->dmabuf_lock);
5098c2ecf20Sopenharmony_ci
5108c2ecf20Sopenharmony_ci	gvt_dbg_dpy("vgpu%d: %s new dmabuf_obj ref %d, id %d\n", vgpu->id,
5118c2ecf20Sopenharmony_ci		    __func__, kref_read(&dmabuf_obj->kref), ret);
5128c2ecf20Sopenharmony_ci
5138c2ecf20Sopenharmony_ci	return 0;
5148c2ecf20Sopenharmony_ci
5158c2ecf20Sopenharmony_ciout_free_info:
5168c2ecf20Sopenharmony_ci	kfree(dmabuf_obj->info);
5178c2ecf20Sopenharmony_ciout_free_dmabuf:
5188c2ecf20Sopenharmony_ci	kfree(dmabuf_obj);
5198c2ecf20Sopenharmony_ciout:
5208c2ecf20Sopenharmony_ci	/* ENODEV means plane isn't ready, which might be a normal case. */
5218c2ecf20Sopenharmony_ci	return (ret == -ENODEV) ? 0 : ret;
5228c2ecf20Sopenharmony_ci}
5238c2ecf20Sopenharmony_ci
5248c2ecf20Sopenharmony_ci/* To associate an exposed dmabuf with the dmabuf_obj */
5258c2ecf20Sopenharmony_ciint intel_vgpu_get_dmabuf(struct intel_vgpu *vgpu, unsigned int dmabuf_id)
5268c2ecf20Sopenharmony_ci{
5278c2ecf20Sopenharmony_ci	struct drm_device *dev = &vgpu->gvt->gt->i915->drm;
5288c2ecf20Sopenharmony_ci	struct intel_vgpu_dmabuf_obj *dmabuf_obj;
5298c2ecf20Sopenharmony_ci	struct drm_i915_gem_object *obj;
5308c2ecf20Sopenharmony_ci	struct dma_buf *dmabuf;
5318c2ecf20Sopenharmony_ci	int dmabuf_fd;
5328c2ecf20Sopenharmony_ci	int ret = 0;
5338c2ecf20Sopenharmony_ci
5348c2ecf20Sopenharmony_ci	mutex_lock(&vgpu->dmabuf_lock);
5358c2ecf20Sopenharmony_ci
5368c2ecf20Sopenharmony_ci	dmabuf_obj = pick_dmabuf_by_num(vgpu, dmabuf_id);
5378c2ecf20Sopenharmony_ci	if (dmabuf_obj == NULL) {
5388c2ecf20Sopenharmony_ci		gvt_vgpu_err("invalid dmabuf id:%d\n", dmabuf_id);
5398c2ecf20Sopenharmony_ci		ret = -EINVAL;
5408c2ecf20Sopenharmony_ci		goto out;
5418c2ecf20Sopenharmony_ci	}
5428c2ecf20Sopenharmony_ci
5438c2ecf20Sopenharmony_ci	obj = vgpu_create_gem(dev, dmabuf_obj->info);
5448c2ecf20Sopenharmony_ci	if (obj == NULL) {
5458c2ecf20Sopenharmony_ci		gvt_vgpu_err("create gvt gem obj failed\n");
5468c2ecf20Sopenharmony_ci		ret = -ENOMEM;
5478c2ecf20Sopenharmony_ci		goto out;
5488c2ecf20Sopenharmony_ci	}
5498c2ecf20Sopenharmony_ci
5508c2ecf20Sopenharmony_ci	obj->gvt_info = dmabuf_obj->info;
5518c2ecf20Sopenharmony_ci
5528c2ecf20Sopenharmony_ci	dmabuf = i915_gem_prime_export(&obj->base, DRM_CLOEXEC | DRM_RDWR);
5538c2ecf20Sopenharmony_ci	if (IS_ERR(dmabuf)) {
5548c2ecf20Sopenharmony_ci		gvt_vgpu_err("export dma-buf failed\n");
5558c2ecf20Sopenharmony_ci		ret = PTR_ERR(dmabuf);
5568c2ecf20Sopenharmony_ci		goto out_free_gem;
5578c2ecf20Sopenharmony_ci	}
5588c2ecf20Sopenharmony_ci
5598c2ecf20Sopenharmony_ci	ret = dma_buf_fd(dmabuf, DRM_CLOEXEC | DRM_RDWR);
5608c2ecf20Sopenharmony_ci	if (ret < 0) {
5618c2ecf20Sopenharmony_ci		gvt_vgpu_err("create dma-buf fd failed ret:%d\n", ret);
5628c2ecf20Sopenharmony_ci		goto out_free_dmabuf;
5638c2ecf20Sopenharmony_ci	}
5648c2ecf20Sopenharmony_ci	dmabuf_fd = ret;
5658c2ecf20Sopenharmony_ci
5668c2ecf20Sopenharmony_ci	dmabuf_obj_get(dmabuf_obj);
5678c2ecf20Sopenharmony_ci
5688c2ecf20Sopenharmony_ci	if (dmabuf_obj->initref) {
5698c2ecf20Sopenharmony_ci		dmabuf_obj->initref = false;
5708c2ecf20Sopenharmony_ci		dmabuf_obj_put(dmabuf_obj);
5718c2ecf20Sopenharmony_ci	}
5728c2ecf20Sopenharmony_ci
5738c2ecf20Sopenharmony_ci	mutex_unlock(&vgpu->dmabuf_lock);
5748c2ecf20Sopenharmony_ci
5758c2ecf20Sopenharmony_ci	gvt_dbg_dpy("vgpu%d: dmabuf:%d, dmabuf ref %d, fd:%d\n"
5768c2ecf20Sopenharmony_ci		    "        file count: %ld, GEM ref: %d\n",
5778c2ecf20Sopenharmony_ci		    vgpu->id, dmabuf_obj->dmabuf_id,
5788c2ecf20Sopenharmony_ci		    kref_read(&dmabuf_obj->kref),
5798c2ecf20Sopenharmony_ci		    dmabuf_fd,
5808c2ecf20Sopenharmony_ci		    file_count(dmabuf->file),
5818c2ecf20Sopenharmony_ci		    kref_read(&obj->base.refcount));
5828c2ecf20Sopenharmony_ci
5838c2ecf20Sopenharmony_ci	i915_gem_object_put(obj);
5848c2ecf20Sopenharmony_ci
5858c2ecf20Sopenharmony_ci	return dmabuf_fd;
5868c2ecf20Sopenharmony_ci
5878c2ecf20Sopenharmony_ciout_free_dmabuf:
5888c2ecf20Sopenharmony_ci	dma_buf_put(dmabuf);
5898c2ecf20Sopenharmony_ciout_free_gem:
5908c2ecf20Sopenharmony_ci	i915_gem_object_put(obj);
5918c2ecf20Sopenharmony_ciout:
5928c2ecf20Sopenharmony_ci	mutex_unlock(&vgpu->dmabuf_lock);
5938c2ecf20Sopenharmony_ci	return ret;
5948c2ecf20Sopenharmony_ci}
5958c2ecf20Sopenharmony_ci
5968c2ecf20Sopenharmony_civoid intel_vgpu_dmabuf_cleanup(struct intel_vgpu *vgpu)
5978c2ecf20Sopenharmony_ci{
5988c2ecf20Sopenharmony_ci	struct list_head *pos, *n;
5998c2ecf20Sopenharmony_ci	struct intel_vgpu_dmabuf_obj *dmabuf_obj;
6008c2ecf20Sopenharmony_ci
6018c2ecf20Sopenharmony_ci	mutex_lock(&vgpu->dmabuf_lock);
6028c2ecf20Sopenharmony_ci	list_for_each_safe(pos, n, &vgpu->dmabuf_obj_list_head) {
6038c2ecf20Sopenharmony_ci		dmabuf_obj = container_of(pos, struct intel_vgpu_dmabuf_obj,
6048c2ecf20Sopenharmony_ci						list);
6058c2ecf20Sopenharmony_ci		dmabuf_obj->vgpu = NULL;
6068c2ecf20Sopenharmony_ci
6078c2ecf20Sopenharmony_ci		idr_remove(&vgpu->object_idr, dmabuf_obj->dmabuf_id);
6088c2ecf20Sopenharmony_ci		intel_gvt_hypervisor_put_vfio_device(vgpu);
6098c2ecf20Sopenharmony_ci		list_del(pos);
6108c2ecf20Sopenharmony_ci
6118c2ecf20Sopenharmony_ci		/* dmabuf_obj might be freed in dmabuf_obj_put */
6128c2ecf20Sopenharmony_ci		if (dmabuf_obj->initref) {
6138c2ecf20Sopenharmony_ci			dmabuf_obj->initref = false;
6148c2ecf20Sopenharmony_ci			dmabuf_obj_put(dmabuf_obj);
6158c2ecf20Sopenharmony_ci		}
6168c2ecf20Sopenharmony_ci
6178c2ecf20Sopenharmony_ci	}
6188c2ecf20Sopenharmony_ci	mutex_unlock(&vgpu->dmabuf_lock);
6198c2ecf20Sopenharmony_ci}
620