ACRN:DM: Export BLOB feature to guest

The DMABuf sharing is based on the BLOB feature. This will
check the attribute of system memory for guest_vm and udmabuf.list_limit
parameter. If it meets with the requirement, export the BLOB feature
so that the FE driver in guest_vm can send the blob cmd.
VIRTIO_GPU_CMD_CREATE_BLOB:
VIRTIO_GPU_CMD_SET_SCANOUT_BLOB:
VIRTIO_GPU_CMD_SET_FLUSH(BLOB)

Tracked-On: #7210

Acked-by: Wang Yu <yu1.wang@intel.com>
Signed-off-by: Zhao Yakui <yakui.zhao@intel.com>
This commit is contained in:
Zhao Yakui 2022-04-01 10:56:47 +08:00 committed by acrnsi-robot
parent c19b2bed18
commit 34bfaa71f6
3 changed files with 69 additions and 0 deletions

View File

@ -881,3 +881,35 @@ vm_find_memfd_region(struct vmctx *ctx, vm_paddr_t gpa,
return ret;
}
bool vm_allow_dmabuf(struct vmctx *ctx)
{
uint32_t mem_flags;
mem_flags = 0;
if (ctx->highmem) {
/* Check the highmem is used by HUGETLB_LV1/HUGETLB_LV2 */
if ((hugetlb_priv[HUGETLB_LV1].fd > 0) &&
(hugetlb_priv[HUGETLB_LV1].highmem))
mem_flags |= 1;
if ((hugetlb_priv[HUGETLB_LV2].fd > 0) &&
(hugetlb_priv[HUGETLB_LV2].highmem))
mem_flags |= 0x02;
if (mem_flags == 0x03)
return false;
}
if (ctx->lowmem) {
/* Check the lowhmem is used by HUGETLB_LV1/HUGETLB_LV2 */
mem_flags = 0;
if ((hugetlb_priv[HUGETLB_LV1].fd > 0) &&
(hugetlb_priv[HUGETLB_LV1].lowmem))
mem_flags |= 1;
if ((hugetlb_priv[HUGETLB_LV2].fd > 0) &&
(hugetlb_priv[HUGETLB_LV2].lowmem))
mem_flags |= 0x02;
if (mem_flags == 0x03)
return false;
}
return true;
}

View File

@ -17,6 +17,8 @@
#include <vmmapi.h>
#include <drm/drm_fourcc.h>
#include <linux/udmabuf.h>
#include <sys/stat.h>
#include <stdio.h>
#include "dm.h"
#include "pci_core.h"
@ -1468,6 +1470,40 @@ virtio_gpu_init(struct vmctx *ctx, struct pci_vdev *dev, char *opts)
gpu->base.mtx = &gpu->mtx;
gpu->base.device_caps = VIRTIO_GPU_S_HOSTCAPS;
if (vm_allow_dmabuf(gpu->base.dev->vmctx)) {
FILE *fp;
char buf[16];
int list_limit;
gpu->is_blob_supported = true;
/* Now the memfd is used by default and it
* is based on Huge_tlb.
* But if both 2M and 1G are used for memory,
* it can't support dmabuf as it is difficult to
* determine whether one memory region is based on 2M or 1G.
*/
fp = fopen("/sys/module/udmabuf/parameters/list_limit", "r");
if (fp) {
memset(buf, 0, sizeof(buf));
rc = fread(buf, sizeof(buf), 1, fp);
fclose(fp);
list_limit = atoi(buf);
if (list_limit < 4096) {
pr_info("udmabuf.list_limit=%d in kernel is too small. "
"Please add udmabuf.list_limit=4096 in kernel "
"boot option to use GPU zero-copy.\n",
list_limit);
gpu->is_blob_supported = false;
}
} else {
pr_info("Zero-copy is disabled. Please check that "
"CONFIG_UDMABUF is enabled in the kernel config.\n");
gpu->is_blob_supported = false;
}
if (gpu->is_blob_supported)
gpu->base.device_caps |= (1UL << VIRTIO_GPU_F_RESOURCE_BLOB);
}
/* set queue size */
gpu->vq[VIRTIO_GPU_CONTROLQ].qsize = VIRTIO_GPU_RINGSZ;
gpu->vq[VIRTIO_GPU_CONTROLQ].notify = virtio_gpu_notify_controlq;

View File

@ -95,6 +95,7 @@ struct vm_mem_region {
};
bool vm_find_memfd_region(struct vmctx *ctx, vm_paddr_t gpa,
struct vm_mem_region *ret_region);
bool vm_allow_dmabuf(struct vmctx *ctx);
/*
* Create a device memory segment identified by 'segid'.
*