1#include "virtgpu-shm.h"
2
3#include "virtgpu.h"
4
5#include <assert.h>
6
7static uint32_t virtgpu_ioctl_resource_create_blob(virtgpu * gpu,
8 uint32_t blob_mem,
9 uint32_t blob_flags,
10 size_t blob_size,
11 uint64_t blob_id,
12 uint32_t * res_id) {
13#ifdef SIMULATE_BO_SIZE_FIX
14 blob_size = align64(blob_size, 4096);
15#endif
16
17 drm_virtgpu_resource_create_blob args = {
18 .blob_mem = blob_mem,
19 .blob_flags = blob_flags,
20 .bo_handle = 0,
21 .res_handle = 0,
22 .size = blob_size,
23 .pad = 0,
24 .cmd_size = 0,
25 .cmd = 0,
26 .blob_id = blob_id,
27 };
28
29 if (virtgpu_ioctl(gpu, DRM_IOCTL_VIRTGPU_RESOURCE_CREATE_BLOB, &args)) {
30 return 0;
31 }
32
33 *res_id = args.res_handle;
34 return args.bo_handle;
35}
36
37static void virtgpu_ioctl_gem_close(virtgpu * gpu, uint32_t gem_handle) {
38 drm_gem_close args = {
39 .handle = gem_handle,
40 .pad = 0,
41 };
42
43 const int ret = virtgpu_ioctl(gpu, DRM_IOCTL_GEM_CLOSE, &args);
44 assert(!ret);
45#ifdef NDEBUG
46 UNUSED(ret);
47#endif
48}
49
50static void * virtgpu_ioctl_map(virtgpu * gpu, uint32_t gem_handle, size_t size) {
51 drm_virtgpu_map args = {
52 .offset = 0,
53 .handle = gem_handle,
54 .pad = 0,
55 };
56
57 if (virtgpu_ioctl(gpu, DRM_IOCTL_VIRTGPU_MAP, &args)) {
58 return NULL;
59 }
60
61 void * ptr = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, gpu->fd, args.offset);
62 if (ptr == MAP_FAILED) {
63 return NULL;
64 }
65
66 return ptr;
67}
68
69void virtgpu_shmem_destroy(virtgpu * gpu, virtgpu_shmem * shmem) {
70 munmap(shmem->mmap_ptr, shmem->mmap_size);
71 virtgpu_ioctl_gem_close(gpu, shmem->gem_handle);
72}
73
74int virtgpu_shmem_create(virtgpu * gpu, size_t size, virtgpu_shmem * shmem) {
75 size = align64(size, 16384);
76
77 uint32_t res_id;
78 uint32_t gem_handle = virtgpu_ioctl_resource_create_blob(gpu, VIRTGPU_BLOB_MEM_HOST3D,
79 VIRTGPU_BLOB_FLAG_USE_MAPPABLE, size, 0, &res_id);
80
81 if (!gem_handle) {
82 return 1;
83 }
84
85 void * ptr = virtgpu_ioctl_map(gpu, gem_handle, size);
86 if (!ptr) {
87 virtgpu_ioctl_gem_close(gpu, gem_handle);
88 GGML_LOG_ERROR(GGML_VIRTGPU "%s: virtgpu_ioctl_map failed\n", __func__);
89 return 1;
90 }
91
92 shmem->res_id = res_id;
93 shmem->mmap_size = size;
94 shmem->mmap_ptr = ptr;
95 shmem->gem_handle = gem_handle;
96
97 return 0;
98}