char-fork/llama.cpp

git clone https://git.t4t.associates/char-fork/llama.cpp

Kevin Pougetggml-virtgpu: improve the reliability of the code (#19846)ffaafde16

char/aliceai-t5-moe
5.0 KiB179 linesraw
1#include "backend-dispatched.h"
2#include "backend-virgl-apir.h"
3#include "ggml-backend-impl.h"
4#include "ggml-backend.h"
5#include "ggml-impl.h"
6
7#include <cstdint>
8
9static uint32_t validate_buffer_operation(size_t offset, size_t size, const char * operation) {
10    // Only check for critical integer overflow - no arbitrary size limits
11    if (offset > SIZE_MAX - size) {
12        GGML_LOG_ERROR(GGML_VIRTGPU_BCK "%s: Integer overflow in offset+size: %zu + %zu\n", operation, offset, size);
13        return 1;
14    }
15
16    return 0;  // Valid
17}
18
19uint32_t backend_buffer_get_base(apir_encoder * enc, apir_decoder * dec, virgl_apir_context * ctx) {
20    GGML_UNUSED(ctx);
21    ggml_backend_buffer_t buffer;
22    buffer = apir_decode_ggml_buffer(dec);
23
24    if (!buffer || apir_decoder_get_fatal(dec)) {
25        GGML_LOG_ERROR(GGML_VIRTGPU_BCK "%s: Invalid buffer handle from guest\n", __func__);
26        return 1;
27    }
28
29    uintptr_t base = (uintptr_t) buffer->iface.get_base(buffer);
30    apir_encode_uintptr_t(enc, &base);
31
32    return 0;
33}
34
35uint32_t backend_buffer_set_tensor(apir_encoder * enc, apir_decoder * dec, virgl_apir_context * ctx) {
36    GGML_UNUSED(ctx);
37    GGML_UNUSED(enc);
38
39    ggml_backend_buffer_t buffer;
40    buffer = apir_decode_ggml_buffer(dec);
41
42    if (!buffer || apir_decoder_get_fatal(dec)) {
43        GGML_LOG_ERROR(GGML_VIRTGPU_BCK "%s: Invalid buffer handle from guest\n", __func__);
44        return 1;
45    }
46
47    ggml_tensor * tensor;
48    // safe to remove the const qualifier here
49    tensor = (ggml_tensor *) (uintptr_t) apir_decode_ggml_tensor(dec);
50
51    uint32_t shmem_res_id;
52    apir_decode_virtgpu_shmem_res_id(dec, &shmem_res_id);
53
54    size_t offset;
55    apir_decode_size_t(dec, &offset);
56
57    size_t size;
58    apir_decode_size_t(dec, &size);
59
60    if (validate_buffer_operation(offset, size, __func__) != 0) {
61        return 1;
62    }
63
64    void * shmem_data = ctx->iface->get_shmem_ptr(ctx->ctx_id, shmem_res_id);
65
66    if (!shmem_data) {
67        GGML_LOG_ERROR(GGML_VIRTGPU_BCK "%s: Couldn't get the shmem addr from virgl\n", __func__);
68        return 1;
69    }
70
71    buffer->iface.set_tensor(buffer, tensor, shmem_data, offset, size);
72
73    return 0;
74}
75
76uint32_t backend_buffer_get_tensor(apir_encoder * enc, apir_decoder * dec, virgl_apir_context * ctx) {
77    GGML_UNUSED(ctx);
78    GGML_UNUSED(enc);
79
80    ggml_backend_buffer_t buffer;
81    buffer = apir_decode_ggml_buffer(dec);
82
83    if (!buffer || apir_decoder_get_fatal(dec)) {
84        GGML_LOG_ERROR(GGML_VIRTGPU_BCK "%s: Invalid buffer handle from guest\n", __func__);
85        return 1;
86    }
87
88    const ggml_tensor * tensor;
89    // safe to remove the const qualifier here
90    tensor = apir_decode_ggml_tensor(dec);
91
92    uint32_t shmem_res_id;
93    apir_decode_virtgpu_shmem_res_id(dec, &shmem_res_id);
94
95    size_t offset;
96    apir_decode_size_t(dec, &offset);
97
98    size_t size;
99    apir_decode_size_t(dec, &size);
100
101    if (validate_buffer_operation(offset, size, __func__) != 0) {
102        return 1;
103    }
104
105    void * shmem_data = ctx->iface->get_shmem_ptr(ctx->ctx_id, shmem_res_id);
106    if (!shmem_data) {
107        GGML_LOG_ERROR(GGML_VIRTGPU_BCK "%s: Couldn't get the shmem addr from virgl\n", __func__);
108        return 1;
109    }
110
111    buffer->iface.get_tensor(buffer, tensor, shmem_data, offset, size);
112
113    return 0;
114}
115
116uint32_t backend_buffer_cpy_tensor(apir_encoder * enc, apir_decoder * dec, virgl_apir_context * ctx) {
117    GGML_UNUSED(ctx);
118
119    ggml_backend_buffer_t buffer;
120    buffer = apir_decode_ggml_buffer(dec);
121
122    if (!buffer || apir_decoder_get_fatal(dec)) {
123        GGML_LOG_ERROR(GGML_VIRTGPU_BCK "%s: Invalid buffer handle from guest\n", __func__);
124        return 1;
125    }
126
127    const ggml_tensor * src;
128    // safe to remove the const qualifier here
129    src               = apir_decode_ggml_tensor(dec);
130    ggml_tensor * dst = (ggml_tensor *) (uintptr_t) apir_decode_ggml_tensor(dec);
131
132    bool ret = buffer->iface.cpy_tensor(buffer, src, (ggml_tensor *) dst);
133
134    apir_encode_bool_t(enc, &ret);
135
136    return 0;
137}
138
139uint32_t backend_buffer_clear(apir_encoder * enc, apir_decoder * dec, virgl_apir_context * ctx) {
140    GGML_UNUSED(ctx);
141    GGML_UNUSED(enc);
142
143    ggml_backend_buffer_t buffer;
144    buffer = apir_decode_ggml_buffer(dec);
145
146    if (!buffer || apir_decoder_get_fatal(dec)) {
147        GGML_LOG_ERROR(GGML_VIRTGPU_BCK "%s: Invalid buffer handle from guest\n", __func__);
148        return 1;
149    }
150
151    uint8_t value;
152    apir_decode_uint8_t(dec, &value);
153
154    buffer->iface.clear(buffer, value);
155
156    return 0;
157}
158
159uint32_t backend_buffer_free_buffer(apir_encoder * enc, apir_decoder * dec, virgl_apir_context * ctx) {
160    GGML_UNUSED(ctx);
161    GGML_UNUSED(enc);
162
163    ggml_backend_buffer_t buffer;
164    buffer = apir_decode_ggml_buffer(dec);
165
166    if (!buffer || apir_decoder_get_fatal(dec)) {
167        GGML_LOG_ERROR(GGML_VIRTGPU_BCK "%s: Invalid buffer handle from guest\n", __func__);
168        return 1;
169    }
170
171    if (!apir_untrack_backend_buffer(buffer)) {
172        GGML_LOG_WARN(GGML_VIRTGPU_BCK "%s: unknown buffer %p\n", __func__, (void *) buffer);
173        return 1;
174    }
175
176    buffer->iface.free_buffer(buffer);
177
178    return 0;
179}