mirror of
https://gitlab.com/qemu-project/qemu.git
synced 2026-08-26 22:23:12 -04:00
Various fixes
Collect various graphics & chardev fixes, and some others. Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com> -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEEh6m9kz+HxgbSdvYt2ujhCXWWnOUFAmqNeowACgkQ2ujhCXWW nOWcsg//VwpHLApYC+ovKfZJm+4m0NUydmsxsYnQXSNhkPEueXMFPu91qu6sLW+c T8eRDwCZaItM4te6nKQ46RiD7GOw5M7AB+D7F6H7za5L8+I7j2QGzTz4N1FQnFLL 0t3FTjzgNri99/UFd1Tpvkh3r4tmLRN1gvGIslvfVtpXLPq0GlVmseDY+Tih4Vz9 TZn0jAg1WoR4v4YrtkfWvk/Dl5nzM3CRTiqLYz1/jfUB4kUpo/VxU1pk1Ky3LglK osrn6pcWxsFD2VLNZwoIMVzrdLjA9w7cIPwLI3JkNop3MD0GtSkAIoT4nSGji8uI Ck3CeuQKwZzHeBb4RJBAjEnVXJSpIhgLD5uQ3B4oIGMvfH0FxUphXZ6I77kehs8V awJwlE5c1tsuHcdcj67rrrcW3rzMVdDVCyin+xLJw7TkfofV9P/WH88pGO19EdOY eyNuwZLHDmrw08KzGEHlzoPRwh01+ihnTB+/eTPJjDDsOgIIQLjjeD06a878XUkm bLFnQktMr0DKFwx1wqkKXAqKLAvoWDTcDhlN9a67Y2G1MsGvROmLOsl4EPFqyfK5 +phEDzZvRD4dWm1vZhI1ZUfORfTXd67naBLAyvSvFZHEbiDtji6RplmSaP8MgA21 dRWRkUxlfQp0cIgzq/5DgnA3I0buVwfGxz8oeoQDwe2yXPdJBEs= =2qCQ -----END PGP SIGNATURE----- Merge tag 'fixes-pr-v1' of https://gitlab.com/marcandre.lureau/qemu into staging Various fixes Collect various graphics & chardev fixes, and some others. Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com> # -----BEGIN PGP SIGNATURE----- # # iQIzBAABCgAdFiEEh6m9kz+HxgbSdvYt2ujhCXWWnOUFAmqNeowACgkQ2ujhCXWW # nOWcsg//VwpHLApYC+ovKfZJm+4m0NUydmsxsYnQXSNhkPEueXMFPu91qu6sLW+c # T8eRDwCZaItM4te6nKQ46RiD7GOw5M7AB+D7F6H7za5L8+I7j2QGzTz4N1FQnFLL # 0t3FTjzgNri99/UFd1Tpvkh3r4tmLRN1gvGIslvfVtpXLPq0GlVmseDY+Tih4Vz9 # TZn0jAg1WoR4v4YrtkfWvk/Dl5nzM3CRTiqLYz1/jfUB4kUpo/VxU1pk1Ky3LglK # osrn6pcWxsFD2VLNZwoIMVzrdLjA9w7cIPwLI3JkNop3MD0GtSkAIoT4nSGji8uI # Ck3CeuQKwZzHeBb4RJBAjEnVXJSpIhgLD5uQ3B4oIGMvfH0FxUphXZ6I77kehs8V # awJwlE5c1tsuHcdcj67rrrcW3rzMVdDVCyin+xLJw7TkfofV9P/WH88pGO19EdOY # eyNuwZLHDmrw08KzGEHlzoPRwh01+ihnTB+/eTPJjDDsOgIIQLjjeD06a878XUkm # bLFnQktMr0DKFwx1wqkKXAqKLAvoWDTcDhlN9a67Y2G1MsGvROmLOsl4EPFqyfK5 # +phEDzZvRD4dWm1vZhI1ZUfORfTXd67naBLAyvSvFZHEbiDtji6RplmSaP8MgA21 # dRWRkUxlfQp0cIgzq/5DgnA3I0buVwfGxz8oeoQDwe2yXPdJBEs= # =2qCQ # -----END PGP SIGNATURE----- # gpg: Signature made Tue 25 Aug 2026 04:20:44 AM PDT # gpg: using RSA key 87A9BD933F87C606D276F62DDAE8E10975969CE5 # gpg: Good signature from "Marc-André Lureau <marcandre.lureau@redhat.com>" [unknown] # gpg: aka "Marc-André Lureau <marcandre.lureau@gmail.com>" [unknown] # gpg: WARNING: This key is not certified with a trusted signature! # gpg: There is no indication that the signature belongs to the owner. # Primary key fingerprint: 87A9 BD93 3F87 C606 D276 F62D DAE8 E109 7596 9CE5 * tag 'fixes-pr-v1' of https://gitlab.com/marcandre.lureau/qemu: hw/input/ps2: say why unknown keyboard commands draw a resend hw/input/ps2: answer unknown mouse commands with a resend hw/display/virtio-gpu: Validate resource per command hw/display/virtio-gpu: Check cursor data presence hw/display/virtio-gpu: Propagate udmabuf errors hw/display/virtio-gpu: Avoid mmap() for empty blob hw/display/virtio-gpu: Avoid creating empty udmabuf hw/display/vga: fix text-mode OOB write after a graphics surface switch chardev: Don't unregister yank upon async path connection failure tests/functional: fix pylint false positives for cv2 module ui/egl: fix qemu_egl_display type ui/egl: fix render node cleanup order tests: tag slow tests with 'slow' suite for easy filtering crypto: fix build against nettle >= 4 virtio-gpu: use g_try_malloc to avoid guest-triggered abort hw/display/qxl: validate primary surface stride against width hw/core/machine: fix fdt memory leak migration/multifd: fix Error leak in multifd_recv_terminate_threads() hw/misc: fix trace-events Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
commit
fe11f459f6
25 changed files with 372 additions and 164 deletions
|
|
@ -1128,11 +1128,6 @@ static void qemu_chr_socket_connected(QIOTask *task, void *opaque)
|
|||
|
||||
if (qio_task_propagate_error(task, &err)) {
|
||||
tcp_chr_change_state(s, TCP_CHARDEV_STATE_DISCONNECTED);
|
||||
if (s->registered_yank) {
|
||||
yank_unregister_function(CHARDEV_YANK_INSTANCE(chr->label),
|
||||
char_socket_yank_iochannel,
|
||||
QIO_CHANNEL(sioc));
|
||||
}
|
||||
check_report_connect_error(chr, err);
|
||||
goto cleanup;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -487,7 +487,7 @@ vg_create_mapping_iov(VuGpu *g,
|
|||
struct virtio_gpu_ctrl_command *cmd,
|
||||
struct iovec **iov)
|
||||
{
|
||||
struct virtio_gpu_mem_entry *ents;
|
||||
g_autofree struct virtio_gpu_mem_entry *ents = NULL;
|
||||
size_t esize, s;
|
||||
int i;
|
||||
|
||||
|
|
@ -498,17 +498,22 @@ vg_create_mapping_iov(VuGpu *g,
|
|||
}
|
||||
|
||||
esize = sizeof(*ents) * ab->nr_entries;
|
||||
ents = g_malloc(esize);
|
||||
ents = g_try_malloc(esize);
|
||||
if (!ents && esize) {
|
||||
return -1;
|
||||
}
|
||||
s = iov_to_buf(cmd->elem.out_sg, cmd->elem.out_num,
|
||||
sizeof(*ab), ents, esize);
|
||||
if (s != esize) {
|
||||
g_critical("%s: command data size incorrect %zu vs %zu",
|
||||
__func__, s, esize);
|
||||
g_free(ents);
|
||||
return -1;
|
||||
}
|
||||
|
||||
*iov = g_new0(struct iovec, ab->nr_entries);
|
||||
*iov = g_try_new0(struct iovec, ab->nr_entries);
|
||||
if (!*iov && ab->nr_entries) {
|
||||
return -1;
|
||||
}
|
||||
for (i = 0; i < ab->nr_entries; i++) {
|
||||
uint64_t len = ents[i].length;
|
||||
(*iov)[i].iov_len = ents[i].length;
|
||||
|
|
@ -517,12 +522,10 @@ vg_create_mapping_iov(VuGpu *g,
|
|||
g_critical("%s: resource %d element %d",
|
||||
__func__, ab->resource_id, i);
|
||||
g_free(*iov);
|
||||
g_free(ents);
|
||||
*iov = NULL;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
g_free(ents);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -828,8 +831,14 @@ vg_resource_flush(VuGpu *g,
|
|||
PIXMAN_FORMAT_BPP(pixman_image_get_format(res->image)) / 8;
|
||||
size_t size = width * height * bpp;
|
||||
|
||||
void *p = g_malloc(VHOST_USER_GPU_HDR_SIZE +
|
||||
sizeof(VhostUserGpuUpdate) + size);
|
||||
void *p = g_try_malloc(VHOST_USER_GPU_HDR_SIZE +
|
||||
sizeof(VhostUserGpuUpdate) + size);
|
||||
if (!p) {
|
||||
pixman_region_fini(®ion);
|
||||
pixman_region_fini(&finalregion);
|
||||
cmd->error = VIRTIO_GPU_RESP_ERR_OUT_OF_MEMORY;
|
||||
break;
|
||||
}
|
||||
VhostUserGpuMsg *msg = p;
|
||||
msg->request = VHOST_USER_GPU_UPDATE;
|
||||
msg->size = sizeof(VhostUserGpuUpdate) + size;
|
||||
|
|
|
|||
|
|
@ -209,7 +209,11 @@ virgl_cmd_submit_3d(VuGpu *g,
|
|||
return;
|
||||
}
|
||||
|
||||
buf = g_malloc(cs.size);
|
||||
buf = g_try_malloc(cs.size);
|
||||
if (!buf && cs.size) {
|
||||
cmd->error = VIRTIO_GPU_RESP_ERR_OUT_OF_MEMORY;
|
||||
return;
|
||||
}
|
||||
s = iov_to_buf(cmd->elem.out_sg, cmd->elem.out_num,
|
||||
sizeof(cs), buf, cs.size);
|
||||
if (s != cs.size) {
|
||||
|
|
|
|||
|
|
@ -13,7 +13,10 @@
|
|||
static bool
|
||||
mem_alloc_bo(struct vugbm_buffer *buf)
|
||||
{
|
||||
buf->mmap = g_malloc((uint64_t)buf->width * buf->height * 4);
|
||||
buf->mmap = g_try_malloc((uint64_t)buf->width * buf->height * 4);
|
||||
if (!buf->mmap && buf->width && buf->height) {
|
||||
return false;
|
||||
}
|
||||
buf->stride = buf->width * 4;
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,7 +24,8 @@
|
|||
#include "crypto/hash.h"
|
||||
#include "hashpriv.h"
|
||||
#include <nettle/md5.h>
|
||||
#include <nettle/sha.h>
|
||||
#include <nettle/sha1.h>
|
||||
#include <nettle/sha2.h>
|
||||
#include <nettle/ripemd160.h>
|
||||
#ifdef CONFIG_CRYPTO_SM3
|
||||
#include <nettle/sm3.h>
|
||||
|
|
|
|||
|
|
@ -1314,6 +1314,7 @@ static void machine_finalize(Object *obj)
|
|||
g_free(ms->nvdimms_state);
|
||||
g_free(ms->numa_state);
|
||||
g_free(ms->audiodev);
|
||||
g_free(ms->fdt);
|
||||
}
|
||||
|
||||
bool machine_usb(MachineState *machine)
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@
|
|||
static void qxl_blit(PCIQXLDevice *qxl, QXLRect *rect)
|
||||
{
|
||||
DisplaySurface *surface = qemu_console_surface(qxl->vga.con);
|
||||
int dst_stride = surface_stride(surface);
|
||||
uint8_t *dst = surface_data(surface);
|
||||
uint8_t *src;
|
||||
int len, i;
|
||||
|
|
@ -45,14 +46,14 @@ static void qxl_blit(PCIQXLDevice *qxl, QXLRect *rect)
|
|||
} else {
|
||||
src += rect->top * qxl->guest_primary.abs_stride;
|
||||
}
|
||||
dst += rect->top * qxl->guest_primary.abs_stride;
|
||||
dst += rect->top * dst_stride;
|
||||
src += rect->left * qxl->guest_primary.bytes_pp;
|
||||
dst += rect->left * qxl->guest_primary.bytes_pp;
|
||||
len = (rect->right - rect->left) * qxl->guest_primary.bytes_pp;
|
||||
|
||||
for (i = rect->top; i < rect->bottom; i++) {
|
||||
memcpy(dst, src, len);
|
||||
dst += qxl->guest_primary.abs_stride;
|
||||
dst += dst_stride;
|
||||
src += qxl->guest_primary.qxl_stride;
|
||||
}
|
||||
}
|
||||
|
|
@ -61,30 +62,13 @@ void qxl_render_resize(PCIQXLDevice *qxl)
|
|||
{
|
||||
QXLSurfaceCreate *sc = &qxl->guest_primary.surface;
|
||||
|
||||
qxl->guest_primary.qxl_stride = sc->stride;
|
||||
qxl->guest_primary.abs_stride = abs(sc->stride);
|
||||
qxl->guest_primary.qxl_stride = le32_to_cpu(sc->stride);
|
||||
qxl->guest_primary.abs_stride = abs(qxl->guest_primary.qxl_stride);
|
||||
qxl->guest_primary.resized++;
|
||||
switch (sc->format) {
|
||||
case SPICE_SURFACE_FMT_16_555:
|
||||
qxl->guest_primary.bytes_pp = 2;
|
||||
qxl->guest_primary.bits_pp = 15;
|
||||
break;
|
||||
case SPICE_SURFACE_FMT_16_565:
|
||||
qxl->guest_primary.bytes_pp = 2;
|
||||
qxl->guest_primary.bits_pp = 16;
|
||||
break;
|
||||
case SPICE_SURFACE_FMT_32_xRGB:
|
||||
case SPICE_SURFACE_FMT_32_ARGB:
|
||||
qxl->guest_primary.bytes_pp = 4;
|
||||
qxl->guest_primary.bits_pp = 32;
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "%s: unhandled format: %x\n", __func__,
|
||||
qxl->guest_primary.surface.format);
|
||||
qxl->guest_primary.bytes_pp = 4;
|
||||
qxl->guest_primary.bits_pp = 32;
|
||||
break;
|
||||
}
|
||||
/* fallback to default bpp if format is unknown */
|
||||
qxl_format_bpp(qxl, le32_to_cpu(sc->format),
|
||||
&qxl->guest_primary.bytes_pp,
|
||||
&qxl->guest_primary.bits_pp);
|
||||
}
|
||||
|
||||
static void qxl_set_rect_to_surface(PCIQXLDevice *qxl, QXLRect *area)
|
||||
|
|
@ -101,15 +85,45 @@ static void qxl_render_update_area_unlocked(PCIQXLDevice *qxl)
|
|||
DisplaySurface *surface;
|
||||
int width = qxl->guest_head0_width ?: qxl->guest_primary.surface.width;
|
||||
int height = qxl->guest_head0_height ?: qxl->guest_primary.surface.height;
|
||||
uint64_t map_height;
|
||||
int i;
|
||||
|
||||
if (width <= 0 || height <= 0) {
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (qxl->guest_primary.bytes_pp > 0) {
|
||||
int max_width = qxl->guest_primary.abs_stride
|
||||
/ qxl->guest_primary.bytes_pp;
|
||||
width = MIN(width, max_width);
|
||||
}
|
||||
|
||||
if (qxl->guest_primary.qxl_stride < 0) {
|
||||
/* qxl_blit() uses the primary height to find the first scanline. */
|
||||
height = MIN(height, (int)qxl->guest_primary.surface.height);
|
||||
}
|
||||
|
||||
if (qxl->guest_primary.abs_stride > 0) {
|
||||
int max_height = qxl->vgamem_size / qxl->guest_primary.abs_stride;
|
||||
height = MIN(height, max_height);
|
||||
}
|
||||
|
||||
/*
|
||||
* height limits the visible update, while map_height is the guest memory
|
||||
* span validated by qxl_phys2virt(). With a negative stride qxl_blit()
|
||||
* addresses scanlines from the declared primary height, so a shorter
|
||||
* monitor still requires validating the full primary surface.
|
||||
*/
|
||||
map_height = qxl->guest_primary.qxl_stride < 0 ?
|
||||
qxl->guest_primary.surface.height : height;
|
||||
|
||||
if (qxl->guest_primary.resized) {
|
||||
qxl->guest_primary.resized = 0;
|
||||
qxl->guest_primary.data = qxl_phys2virt(qxl,
|
||||
qxl->guest_primary.surface.mem,
|
||||
MEMSLOT_GROUP_GUEST,
|
||||
qxl->guest_primary.abs_stride
|
||||
* height);
|
||||
* map_height);
|
||||
if (!qxl->guest_primary.data) {
|
||||
goto end;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1489,6 +1489,47 @@ static void qxl_create_guest_primary_complete(PCIQXLDevice *qxl)
|
|||
qxl_render_resize(qxl);
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert a SpiceSurfaceFormat to bytes per pixel and bits per pixel.
|
||||
*
|
||||
* Only valid for surface suitable for rendering.
|
||||
*/
|
||||
bool qxl_format_bpp(PCIQXLDevice *qxl, SpiceSurfaceFmt format,
|
||||
uint32_t *bytes_pp, uint32_t *bits_pp)
|
||||
{
|
||||
uint32_t bypp = 4;
|
||||
uint32_t bipp = 32;
|
||||
bool ret = true;
|
||||
|
||||
switch (format) {
|
||||
case SPICE_SURFACE_FMT_16_555:
|
||||
bypp = 2;
|
||||
bipp = 15;
|
||||
break;
|
||||
case SPICE_SURFACE_FMT_16_565:
|
||||
bypp = 2;
|
||||
bipp = 16;
|
||||
break;
|
||||
case SPICE_SURFACE_FMT_32_xRGB:
|
||||
case SPICE_SURFACE_FMT_32_ARGB:
|
||||
bypp = 4;
|
||||
bipp = 32;
|
||||
break;
|
||||
default:
|
||||
ret = false;
|
||||
qxl_set_guest_bug(qxl, "%s: unhandled format: %x", __func__, format);
|
||||
}
|
||||
|
||||
if (bytes_pp != NULL) {
|
||||
*bytes_pp = bypp;
|
||||
}
|
||||
if (bits_pp != NULL) {
|
||||
*bits_pp = bipp;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void qxl_create_guest_primary(PCIQXLDevice *qxl, int loadvm,
|
||||
qxl_async_io async)
|
||||
{
|
||||
|
|
@ -1496,6 +1537,7 @@ static void qxl_create_guest_primary(PCIQXLDevice *qxl, int loadvm,
|
|||
QXLSurfaceCreate *sc = &qxl->guest_primary.surface;
|
||||
uint32_t requested_height = le32_to_cpu(sc->height);
|
||||
int requested_stride = le32_to_cpu(sc->stride);
|
||||
uint32_t bytes_pp;
|
||||
|
||||
if (requested_stride == INT32_MIN ||
|
||||
abs(requested_stride) * (uint64_t)requested_height
|
||||
|
|
@ -1532,6 +1574,23 @@ static void qxl_create_guest_primary(PCIQXLDevice *qxl, int loadvm,
|
|||
return;
|
||||
}
|
||||
|
||||
if (!qxl_format_bpp(qxl, surface.format, &bytes_pp, NULL)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (surface.width == 0 || surface.height == 0) {
|
||||
qxl_set_guest_bug(qxl, "%s: zero dimension %ux%u",
|
||||
__func__, surface.width, surface.height);
|
||||
return;
|
||||
}
|
||||
|
||||
if ((uint64_t)surface.width * bytes_pp > abs(surface.stride)) {
|
||||
qxl_set_guest_bug(qxl, "%s: stride too small for width:"
|
||||
" stride %d width %u bpp %u",
|
||||
__func__, surface.stride, surface.width, bytes_pp);
|
||||
return;
|
||||
}
|
||||
|
||||
surface.mouse_mode = true;
|
||||
surface.group_id = MEMSLOT_GROUP_GUEST;
|
||||
if (loadvm) {
|
||||
|
|
|
|||
|
|
@ -181,6 +181,8 @@ void qxl_spice_oom(PCIQXLDevice *qxl);
|
|||
void qxl_spice_reset_memslots(PCIQXLDevice *qxl);
|
||||
void qxl_spice_reset_image_cache(PCIQXLDevice *qxl);
|
||||
void qxl_spice_reset_cursor(PCIQXLDevice *qxl);
|
||||
bool qxl_format_bpp(PCIQXLDevice *qxl, SpiceSurfaceFmt format,
|
||||
uint32_t *bytes_pp, uint32_t *bits_pp);
|
||||
|
||||
/* qxl-logger.c */
|
||||
int qxl_log_cmd_cursor(PCIQXLDevice *qxl, QXLCursorCmd *cmd, int group_id);
|
||||
|
|
|
|||
|
|
@ -1241,7 +1241,10 @@ static void vga_draw_text(VGACommonState *s, int full_update)
|
|||
return;
|
||||
}
|
||||
|
||||
if (width != s->last_width || height != s->last_height ||
|
||||
if (surface == NULL ||
|
||||
surface_width(surface) != width * cw ||
|
||||
surface_height(surface) != height * cheight ||
|
||||
width != s->last_text_width || height != s->last_text_height ||
|
||||
cw != s->last_cw || cheight != s->last_ch || s->last_depth) {
|
||||
s->last_scr_width = width * cw;
|
||||
s->last_scr_height = height * cheight;
|
||||
|
|
@ -1249,8 +1252,8 @@ static void vga_draw_text(VGACommonState *s, int full_update)
|
|||
surface = qemu_console_surface(s->con);
|
||||
qemu_console_text_resize(s->con, width, height);
|
||||
s->last_depth = 0;
|
||||
s->last_width = width;
|
||||
s->last_height = height;
|
||||
s->last_text_width = width;
|
||||
s->last_text_height = height;
|
||||
s->last_ch = cheight;
|
||||
s->last_cw = cw;
|
||||
full_update = 1;
|
||||
|
|
@ -1845,6 +1848,8 @@ static void vga_invalidate_display(void *opaque)
|
|||
|
||||
s->last_width = -1;
|
||||
s->last_height = -1;
|
||||
s->last_text_width = -1;
|
||||
s->last_text_height = -1;
|
||||
}
|
||||
|
||||
void vga_common_reset(VGACommonState *s)
|
||||
|
|
@ -1887,6 +1892,8 @@ void vga_common_reset(VGACommonState *s)
|
|||
s->last_ch = 0;
|
||||
s->last_width = 0;
|
||||
s->last_height = 0;
|
||||
s->last_text_width = 0;
|
||||
s->last_text_height = 0;
|
||||
s->last_scr_width = 0;
|
||||
s->last_scr_height = 0;
|
||||
s->cursor_start = 0;
|
||||
|
|
@ -1938,8 +1945,8 @@ static void vga_update_text(void *opaque, uint32_t *chardata)
|
|||
s->graphic_mode = graphic_mode;
|
||||
full_update = 1;
|
||||
}
|
||||
if (s->last_width == -1) {
|
||||
s->last_width = 0;
|
||||
if (s->last_text_width == -1) {
|
||||
s->last_text_width = 0;
|
||||
full_update = 1;
|
||||
}
|
||||
|
||||
|
|
@ -1978,15 +1985,15 @@ static void vga_update_text(void *opaque, uint32_t *chardata)
|
|||
break;
|
||||
}
|
||||
|
||||
if (width != s->last_width || height != s->last_height ||
|
||||
if (width != s->last_text_width || height != s->last_text_height ||
|
||||
cw != s->last_cw || cheight != s->last_ch) {
|
||||
s->last_scr_width = width * cw;
|
||||
s->last_scr_height = height * cheight;
|
||||
qemu_console_resize(s->con, s->last_scr_width, s->last_scr_height);
|
||||
qemu_console_text_resize(s->con, width, height);
|
||||
s->last_depth = 0;
|
||||
s->last_width = width;
|
||||
s->last_height = height;
|
||||
s->last_text_width = width;
|
||||
s->last_text_height = height;
|
||||
s->last_ch = cheight;
|
||||
s->last_cw = cw;
|
||||
full_update = 1;
|
||||
|
|
@ -2071,22 +2078,22 @@ static void vga_update_text(void *opaque, uint32_t *chardata)
|
|||
}
|
||||
|
||||
/* Display a message */
|
||||
s->last_width = 60;
|
||||
s->last_height = height = 3;
|
||||
s->last_text_width = 60;
|
||||
s->last_text_height = height = 3;
|
||||
qemu_console_text_set_cursor(s->con, -1, -1);
|
||||
qemu_console_text_resize(s->con, s->last_width, height);
|
||||
qemu_console_text_resize(s->con, s->last_text_width, height);
|
||||
|
||||
for (dst = chardata, i = 0; i < s->last_width * height; i ++)
|
||||
for (dst = chardata, i = 0; i < s->last_text_width * height; i ++)
|
||||
*dst++ = ' ';
|
||||
|
||||
size = strlen(msg_buffer);
|
||||
width = (s->last_width - size) / 2;
|
||||
dst = chardata + s->last_width + width;
|
||||
width = (s->last_text_width - size) / 2;
|
||||
dst = chardata + s->last_text_width + width;
|
||||
for (i = 0; i < size; i ++)
|
||||
*dst++ = ATTR2CHTYPE(msg_buffer[i], QEMU_COLOR_BLUE,
|
||||
QEMU_COLOR_BLACK, 1);
|
||||
|
||||
qemu_console_text_update(s->con, 0, 0, s->last_width, height);
|
||||
qemu_console_text_update(s->con, 0, 0, s->last_text_width, height);
|
||||
}
|
||||
|
||||
static uint64_t vga_mem_read(void *opaque, hwaddr addr,
|
||||
|
|
|
|||
|
|
@ -122,7 +122,8 @@ typedef struct VGACommonState {
|
|||
uint32_t plane_updated;
|
||||
uint32_t last_line_offset;
|
||||
uint8_t last_cw, last_ch;
|
||||
uint32_t last_width, last_height; /* in chars or pixels */
|
||||
uint32_t last_width, last_height; /* in pixels (graphics renderer) */
|
||||
uint32_t last_text_width, last_text_height; /* in chars (text renderer) */
|
||||
uint32_t last_scr_width, last_scr_height; /* in pixels */
|
||||
uint32_t last_depth; /* in bits */
|
||||
bool last_byteswap;
|
||||
|
|
|
|||
|
|
@ -366,10 +366,20 @@ rutabaga_cmd_submit_3d(VirtIOGPU *g,
|
|||
return;
|
||||
}
|
||||
|
||||
buf = g_new0(uint8_t, cs.size);
|
||||
buf = g_try_new0(uint8_t, cs.size);
|
||||
if (!buf && cs.size) {
|
||||
cmd->error = VIRTIO_GPU_RESP_ERR_OUT_OF_MEMORY;
|
||||
return;
|
||||
}
|
||||
s = iov_to_buf(cmd->elem.out_sg, cmd->elem.out_num,
|
||||
sizeof(cs), buf, cs.size);
|
||||
CHECK(s == cs.size, cmd);
|
||||
if (s != cs.size) {
|
||||
qemu_log_mask(LOG_GUEST_ERROR,
|
||||
"%s: size mismatch (%zu/%u)\n",
|
||||
__func__, s, cs.size);
|
||||
cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_PARAMETER;
|
||||
return;
|
||||
}
|
||||
|
||||
rutabaga_cmd.ctx_id = cs.hdr.ctx_id;
|
||||
rutabaga_cmd.cmd = buf;
|
||||
|
|
|
|||
|
|
@ -7,9 +7,10 @@ bool virtio_gpu_have_udmabuf(void)
|
|||
return false;
|
||||
}
|
||||
|
||||
void virtio_gpu_init_udmabuf(struct virtio_gpu_simple_resource *res)
|
||||
bool virtio_gpu_init_udmabuf(struct virtio_gpu_simple_resource *res)
|
||||
{
|
||||
/* nothing (stub) */
|
||||
return false;
|
||||
}
|
||||
|
||||
void virtio_gpu_fini_udmabuf(VirtIOGPU *g, struct virtio_gpu_simple_resource *res)
|
||||
|
|
|
|||
|
|
@ -39,8 +39,11 @@ static void virtio_gpu_create_udmabuf(struct virtio_gpu_simple_resource *res)
|
|||
return;
|
||||
}
|
||||
|
||||
list = g_malloc0(sizeof(struct udmabuf_create_list) +
|
||||
sizeof(struct udmabuf_create_item) * res->iov_cnt);
|
||||
list = g_try_malloc0(sizeof(struct udmabuf_create_list) +
|
||||
sizeof(struct udmabuf_create_item) * res->iov_cnt);
|
||||
if (!list) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < res->iov_cnt; i++) {
|
||||
rcu_read_lock();
|
||||
|
|
@ -128,7 +131,7 @@ bool virtio_gpu_have_udmabuf(void)
|
|||
return memfd_backend;
|
||||
}
|
||||
|
||||
void virtio_gpu_init_udmabuf(struct virtio_gpu_simple_resource *res)
|
||||
bool virtio_gpu_init_udmabuf(struct virtio_gpu_simple_resource *res)
|
||||
{
|
||||
void *pdata = NULL;
|
||||
|
||||
|
|
@ -136,20 +139,22 @@ void virtio_gpu_init_udmabuf(struct virtio_gpu_simple_resource *res)
|
|||
if (res->iov_cnt == 1 &&
|
||||
res->iov[0].iov_len < 4096) {
|
||||
pdata = res->iov[0].iov_base;
|
||||
} else {
|
||||
} else if (res->blob_size) {
|
||||
virtio_gpu_create_udmabuf(res);
|
||||
if (res->dmabuf_fd < 0) {
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
virtio_gpu_remap_udmabuf(res);
|
||||
if (!res->remapped) {
|
||||
virtio_gpu_destroy_udmabuf(res);
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
pdata = res->remapped;
|
||||
}
|
||||
|
||||
res->blob = pdata;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void virtio_gpu_free_dmabuf(VirtIOGPU *g, VGPUDMABuf *dmabuf)
|
||||
|
|
|
|||
|
|
@ -620,7 +620,11 @@ static void virgl_cmd_submit_3d(VirtIOGPU *g,
|
|||
return;
|
||||
}
|
||||
|
||||
buf = g_malloc(cs.size);
|
||||
buf = g_try_malloc(cs.size);
|
||||
if (!buf && cs.size) {
|
||||
cmd->error = VIRTIO_GPU_RESP_ERR_OUT_OF_MEMORY;
|
||||
return;
|
||||
}
|
||||
s = iov_to_buf(cmd->elem.out_sg, cmd->elem.out_num,
|
||||
sizeof(cs), buf, cs.size);
|
||||
if (s != cs.size) {
|
||||
|
|
|
|||
|
|
@ -37,7 +37,6 @@
|
|||
|
||||
static struct virtio_gpu_simple_resource *
|
||||
virtio_gpu_find_check_resource(VirtIOGPU *g, uint32_t resource_id,
|
||||
bool require_backing,
|
||||
const char *caller, uint32_t *error);
|
||||
|
||||
static void virtio_gpu_reset_bh(void *opaque);
|
||||
|
|
@ -50,8 +49,7 @@ void virtio_gpu_update_cursor_data(VirtIOGPU *g,
|
|||
uint32_t pixels;
|
||||
void *data;
|
||||
|
||||
res = virtio_gpu_find_check_resource(g, resource_id, false,
|
||||
__func__, NULL);
|
||||
res = virtio_gpu_find_check_resource(g, resource_id, __func__, NULL);
|
||||
if (!res) {
|
||||
return;
|
||||
}
|
||||
|
|
@ -63,8 +61,8 @@ void virtio_gpu_update_cursor_data(VirtIOGPU *g,
|
|||
}
|
||||
data = pixman_image_get_data(res->image);
|
||||
} else {
|
||||
if (res->blob_size < (s->current_cursor->width *
|
||||
s->current_cursor->height * 4)) {
|
||||
if (!res->iov || res->blob_size < (s->current_cursor->width *
|
||||
s->current_cursor->height * 4)) {
|
||||
return;
|
||||
}
|
||||
data = res->blob;
|
||||
|
|
@ -128,7 +126,6 @@ virtio_gpu_find_resource(VirtIOGPU *g, uint32_t resource_id)
|
|||
|
||||
static struct virtio_gpu_simple_resource *
|
||||
virtio_gpu_find_check_resource(VirtIOGPU *g, uint32_t resource_id,
|
||||
bool require_backing,
|
||||
const char *caller, uint32_t *error)
|
||||
{
|
||||
struct virtio_gpu_simple_resource *res;
|
||||
|
|
@ -143,17 +140,6 @@ virtio_gpu_find_check_resource(VirtIOGPU *g, uint32_t resource_id,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
if (require_backing) {
|
||||
if (!res->iov || (!res->image && !res->blob)) {
|
||||
qemu_log_mask(LOG_GUEST_ERROR, "%s: no backing storage %d\n",
|
||||
caller, resource_id);
|
||||
if (error) {
|
||||
*error = VIRTIO_GPU_RESP_ERR_UNSPEC;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
|
@ -363,27 +349,34 @@ static void virtio_gpu_resource_create_blob(VirtIOGPU *g,
|
|||
res->resource_id = cblob.resource_id;
|
||||
res->blob_size = cblob.size;
|
||||
|
||||
ret = virtio_gpu_create_mapping_iov(g, cblob.nr_entries, sizeof(cblob),
|
||||
cmd, &res->addrs, &res->iov,
|
||||
&res->iov_cnt);
|
||||
if (ret < 0) {
|
||||
cmd->error = VIRTIO_GPU_RESP_ERR_UNSPEC;
|
||||
g_free(res);
|
||||
return;
|
||||
if (cblob.nr_entries) {
|
||||
ret = virtio_gpu_create_mapping_iov(g, cblob.nr_entries, sizeof(cblob),
|
||||
cmd, &res->addrs, &res->iov,
|
||||
&res->iov_cnt);
|
||||
if (ret < 0) {
|
||||
cmd->error = VIRTIO_GPU_RESP_ERR_UNSPEC;
|
||||
g_free(res);
|
||||
return;
|
||||
}
|
||||
|
||||
if (iov_size(res->iov, res->iov_cnt) < res->blob_size) {
|
||||
qemu_log_mask(LOG_GUEST_ERROR,
|
||||
"%s: backing storage smaller than blob size\n",
|
||||
__func__);
|
||||
cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_PARAMETER;
|
||||
virtio_gpu_cleanup_mapping(g, res);
|
||||
g_free(res);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!virtio_gpu_init_udmabuf(res)) {
|
||||
cmd->error = VIRTIO_GPU_RESP_ERR_UNSPEC;
|
||||
virtio_gpu_cleanup_mapping(g, res);
|
||||
g_free(res);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (res->iov_cnt > 0 &&
|
||||
iov_size(res->iov, res->iov_cnt) < res->blob_size) {
|
||||
qemu_log_mask(LOG_GUEST_ERROR,
|
||||
"%s: backing storage smaller than blob size\n",
|
||||
__func__);
|
||||
cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_PARAMETER;
|
||||
virtio_gpu_cleanup_mapping(g, res);
|
||||
g_free(res);
|
||||
return;
|
||||
}
|
||||
|
||||
virtio_gpu_init_udmabuf(res);
|
||||
QTAILQ_INSERT_HEAD(&g->reslist, res, next);
|
||||
}
|
||||
|
||||
|
|
@ -467,9 +460,24 @@ static void virtio_gpu_transfer_to_host_2d(VirtIOGPU *g,
|
|||
virtio_gpu_t2d_bswap(&t2d);
|
||||
trace_virtio_gpu_cmd_res_xfer_toh_2d(t2d.resource_id);
|
||||
|
||||
res = virtio_gpu_find_check_resource(g, t2d.resource_id, true,
|
||||
res = virtio_gpu_find_check_resource(g, t2d.resource_id,
|
||||
__func__, &cmd->error);
|
||||
if (!res || res->blob) {
|
||||
if (!res) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!res->image) {
|
||||
qemu_log_mask(LOG_GUEST_ERROR, "%s: resource %d is a blob\n",
|
||||
__func__, t2d.resource_id);
|
||||
cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_RESOURCE_ID;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!res->iov) {
|
||||
qemu_log_mask(LOG_GUEST_ERROR,
|
||||
"%s: resource %d has no backing storage\n",
|
||||
__func__, t2d.resource_id);
|
||||
cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_RESOURCE_ID;
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -526,7 +534,7 @@ static void virtio_gpu_resource_flush(VirtIOGPU *g,
|
|||
trace_virtio_gpu_cmd_res_flush(rf.resource_id,
|
||||
rf.r.width, rf.r.height, rf.r.x, rf.r.y);
|
||||
|
||||
res = virtio_gpu_find_check_resource(g, rf.resource_id, false,
|
||||
res = virtio_gpu_find_check_resource(g, rf.resource_id,
|
||||
__func__, &cmd->error);
|
||||
if (!res) {
|
||||
return;
|
||||
|
|
@ -764,12 +772,19 @@ static void virtio_gpu_set_scanout(VirtIOGPU *g,
|
|||
return;
|
||||
}
|
||||
|
||||
res = virtio_gpu_find_check_resource(g, ss.resource_id, true,
|
||||
res = virtio_gpu_find_check_resource(g, ss.resource_id,
|
||||
__func__, &cmd->error);
|
||||
if (!res) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!res->image) {
|
||||
qemu_log_mask(LOG_GUEST_ERROR, "%s: resource %d is a blob\n",
|
||||
__func__, ss.resource_id);
|
||||
cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_RESOURCE_ID;
|
||||
return;
|
||||
}
|
||||
|
||||
fb.format = pixman_image_get_format(res->image);
|
||||
bytes_pp = virtio_gpu_format_bytes_pp(fb.format);
|
||||
fb.width = pixman_image_get_width(res->image);
|
||||
|
|
@ -859,12 +874,28 @@ static void virtio_gpu_set_scanout_blob(VirtIOGPU *g,
|
|||
return;
|
||||
}
|
||||
|
||||
res = virtio_gpu_find_check_resource(g, ss.resource_id, true,
|
||||
res = virtio_gpu_find_check_resource(g, ss.resource_id,
|
||||
__func__, &cmd->error);
|
||||
if (!res) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (res->image) {
|
||||
qemu_log_mask(LOG_GUEST_ERROR,
|
||||
"%s: resource %d is not a blob\n",
|
||||
__func__, ss.resource_id);
|
||||
cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_RESOURCE_ID;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!res->iov) {
|
||||
qemu_log_mask(LOG_GUEST_ERROR,
|
||||
"%s: resource %d has no backing storage\n",
|
||||
__func__, ss.resource_id);
|
||||
cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_RESOURCE_ID;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!virtio_gpu_scanout_blob_to_fb(&fb, &ss, res->blob_size)) {
|
||||
cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_PARAMETER;
|
||||
return;
|
||||
|
|
@ -892,7 +923,10 @@ int virtio_gpu_create_mapping_iov(VirtIOGPU *g,
|
|||
}
|
||||
|
||||
esize = sizeof(*ents) * nr_entries;
|
||||
ents = g_malloc(esize);
|
||||
ents = g_try_malloc(esize);
|
||||
if (!ents && esize) {
|
||||
return -1;
|
||||
}
|
||||
s = iov_to_buf(cmd->elem.out_sg, cmd->elem.out_num,
|
||||
offset, ents, esize);
|
||||
if (s != esize) {
|
||||
|
|
@ -913,6 +947,7 @@ int virtio_gpu_create_mapping_iov(VirtIOGPU *g,
|
|||
hwaddr len;
|
||||
void *map;
|
||||
|
||||
/* TODO: a common DMA map SG helper */
|
||||
do {
|
||||
len = l;
|
||||
map = dma_memory_map(VIRTIO_DEVICE(g)->dma_as, a, &len,
|
||||
|
|
@ -921,20 +956,27 @@ int virtio_gpu_create_mapping_iov(VirtIOGPU *g,
|
|||
if (!map) {
|
||||
qemu_log_mask(LOG_GUEST_ERROR, "%s: failed to map MMIO memory for"
|
||||
" element %d\n", __func__, e);
|
||||
virtio_gpu_cleanup_mapping_iov(g, *iov, v);
|
||||
g_free(ents);
|
||||
*iov = NULL;
|
||||
if (addr) {
|
||||
g_free(*addr);
|
||||
*addr = NULL;
|
||||
}
|
||||
return -1;
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (!(v % 16)) {
|
||||
*iov = g_renew(struct iovec, *iov, v + 16);
|
||||
struct iovec *new_iov;
|
||||
new_iov = g_try_renew(struct iovec, *iov, v + 16);
|
||||
if (!new_iov) {
|
||||
dma_memory_unmap(VIRTIO_DEVICE(g)->dma_as, map, len,
|
||||
DMA_DIRECTION_TO_DEVICE, len);
|
||||
goto err;
|
||||
}
|
||||
*iov = new_iov;
|
||||
if (addr) {
|
||||
*addr = g_renew(uint64_t, *addr, v + 16);
|
||||
uint64_t *new_addr;
|
||||
new_addr = g_try_renew(uint64_t, *addr, v + 16);
|
||||
if (!new_addr) {
|
||||
dma_memory_unmap(VIRTIO_DEVICE(g)->dma_as, map, len,
|
||||
DMA_DIRECTION_TO_DEVICE, len);
|
||||
goto err;
|
||||
}
|
||||
*addr = new_addr;
|
||||
}
|
||||
}
|
||||
(*iov)[v].iov_base = map;
|
||||
|
|
@ -952,6 +994,15 @@ int virtio_gpu_create_mapping_iov(VirtIOGPU *g,
|
|||
|
||||
g_free(ents);
|
||||
return 0;
|
||||
|
||||
err:
|
||||
virtio_gpu_cleanup_mapping_iov(g, *iov, v);
|
||||
*iov = NULL;
|
||||
if (addr) {
|
||||
g_clear_pointer(addr, g_free);
|
||||
}
|
||||
g_free(ents);
|
||||
return -1;
|
||||
}
|
||||
|
||||
void virtio_gpu_cleanup_mapping_iov(VirtIOGPU *g,
|
||||
|
|
@ -1023,8 +1074,9 @@ virtio_gpu_resource_attach_backing(VirtIOGPU *g,
|
|||
return;
|
||||
}
|
||||
|
||||
if (!res->image) {
|
||||
virtio_gpu_init_udmabuf(res);
|
||||
if (!res->image && !virtio_gpu_init_udmabuf(res)) {
|
||||
cmd->error = VIRTIO_GPU_RESP_ERR_UNSPEC;
|
||||
virtio_gpu_cleanup_mapping(g, res);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1039,7 +1091,7 @@ virtio_gpu_resource_detach_backing(VirtIOGPU *g,
|
|||
virtio_gpu_bswap_32(&detach, sizeof(detach));
|
||||
trace_virtio_gpu_cmd_res_back_detach(detach.resource_id);
|
||||
|
||||
res = virtio_gpu_find_check_resource(g, detach.resource_id, true,
|
||||
res = virtio_gpu_find_check_resource(g, detach.resource_id,
|
||||
__func__, &cmd->error);
|
||||
if (!res) {
|
||||
return;
|
||||
|
|
@ -1369,8 +1421,6 @@ static bool virtio_gpu_load_restore_mapping(VirtIOGPU *g,
|
|||
}
|
||||
}
|
||||
|
||||
QTAILQ_INSERT_HEAD(&g->reslist, res, next);
|
||||
g->hostmem += res->hostmem;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -1449,6 +1499,8 @@ static int virtio_gpu_load(QEMUFile *f, void *opaque, size_t size,
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
QTAILQ_INSERT_HEAD(&g->reslist, res, next);
|
||||
g->hostmem += hostmem;
|
||||
resource_id = qemu_get_be32(f);
|
||||
}
|
||||
|
||||
|
|
@ -1508,36 +1560,42 @@ static int virtio_gpu_blob_load(QEMUFile *f, void *opaque, size_t size,
|
|||
res->blob_size = qemu_get_be32(f);
|
||||
res->iov_cnt = qemu_get_be32(f);
|
||||
|
||||
res->addrs = g_try_new(uint64_t, res->iov_cnt);
|
||||
res->iov = g_try_new(struct iovec, res->iov_cnt);
|
||||
if (res->iov_cnt && (!res->addrs || !res->iov)) {
|
||||
g_free(res->addrs);
|
||||
g_free(res->iov);
|
||||
g_free(res);
|
||||
return -EINVAL;
|
||||
if (res->iov_cnt) {
|
||||
res->addrs = g_try_new(uint64_t, res->iov_cnt);
|
||||
res->iov = g_try_new(struct iovec, res->iov_cnt);
|
||||
if (!res->addrs || !res->iov) {
|
||||
g_free(res->addrs);
|
||||
g_free(res->iov);
|
||||
g_free(res);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* read data */
|
||||
for (i = 0; i < res->iov_cnt; i++) {
|
||||
res->addrs[i] = qemu_get_be64(f);
|
||||
res->iov[i].iov_len = qemu_get_be32(f);
|
||||
}
|
||||
|
||||
if (iov_size(res->iov, res->iov_cnt) < res->blob_size) {
|
||||
g_free(res->addrs);
|
||||
g_free(res->iov);
|
||||
g_free(res);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!virtio_gpu_load_restore_mapping(g, res)) {
|
||||
g_free(res);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!virtio_gpu_init_udmabuf(res)) {
|
||||
virtio_gpu_cleanup_mapping(g, res);
|
||||
g_free(res);
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
/* read data */
|
||||
for (i = 0; i < res->iov_cnt; i++) {
|
||||
res->addrs[i] = qemu_get_be64(f);
|
||||
res->iov[i].iov_len = qemu_get_be32(f);
|
||||
}
|
||||
|
||||
if (res->iov_cnt > 0 &&
|
||||
iov_size(res->iov, res->iov_cnt) < res->blob_size) {
|
||||
g_free(res->addrs);
|
||||
g_free(res->iov);
|
||||
g_free(res);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!virtio_gpu_load_restore_mapping(g, res)) {
|
||||
g_free(res);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
virtio_gpu_init_udmabuf(res);
|
||||
|
||||
QTAILQ_INSERT_HEAD(&g->reslist, res, next);
|
||||
resource_id = qemu_get_be32(f);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -73,6 +73,7 @@
|
|||
#define AUX_SET_DEFAULT 0xF6
|
||||
#define AUX_RESET 0xFF /* Reset aux device */
|
||||
#define AUX_ACK 0xFA /* Command byte ACK. */
|
||||
#define AUX_RESEND 0xFE /* Command NACK, send the cmd again */
|
||||
|
||||
#define MOUSE_STATUS_REMOTE 0x40
|
||||
#define MOUSE_STATUS_ENABLED 0x20
|
||||
|
|
@ -646,6 +647,10 @@ void ps2_write_keyboard(PS2KbdState *s, int val)
|
|||
ps2_cqueue_1(ps2, KBD_REPLY_ACK);
|
||||
break;
|
||||
default:
|
||||
/*
|
||||
* A PS/2 device answers every command it is given; an unknown
|
||||
* one draws a resend.
|
||||
*/
|
||||
ps2_cqueue_1(ps2, KBD_REPLY_RESEND);
|
||||
break;
|
||||
}
|
||||
|
|
@ -955,6 +960,11 @@ void ps2_write_mouse(PS2MouseState *s, int val)
|
|||
s->mouse_type);
|
||||
break;
|
||||
default:
|
||||
/*
|
||||
* A PS/2 device answers every command it is given; an unknown
|
||||
* one draws a resend.
|
||||
*/
|
||||
ps2_queue(ps2, AUX_RESEND);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -446,3 +446,9 @@ iommu_testdev_dma_armed(bool armed) "armed=%d"
|
|||
# k230_decomp_gzip.c
|
||||
k230_decomp_gzip_read(uint64_t offset, unsigned int size, uint64_t value) "K230 DECOMP GZIP read: [0x%"PRIx64"] size %u -> 0x%"PRIx64
|
||||
k230_decomp_gzip_write(uint64_t offset, unsigned int size, uint64_t value) "K230 DECOMP GZIP write: [0x%"PRIx64"] size %u <- 0x%"PRIx64
|
||||
|
||||
# vmlaunchupdate.c
|
||||
launch_update_write(void) ""
|
||||
vmlaunch_reset_enter(void) ""
|
||||
vm_launchupdate_finalize(void) ""
|
||||
restore_host_x86_igvm(void) ""
|
||||
|
|
|
|||
|
|
@ -388,7 +388,7 @@ bool virtio_gpu_scanout_blob_to_fb(struct virtio_gpu_framebuffer *fb,
|
|||
|
||||
/* virtio-gpu-udmabuf.c */
|
||||
bool virtio_gpu_have_udmabuf(void);
|
||||
void virtio_gpu_init_udmabuf(struct virtio_gpu_simple_resource *res);
|
||||
bool virtio_gpu_init_udmabuf(struct virtio_gpu_simple_resource *res);
|
||||
void virtio_gpu_fini_udmabuf(VirtIOGPU *g,
|
||||
struct virtio_gpu_simple_resource *res);
|
||||
int virtio_gpu_update_dmabuf(VirtIOGPU *g,
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@
|
|||
#include "ui/console.h"
|
||||
#include "ui/shader.h"
|
||||
|
||||
extern EGLDisplay *qemu_egl_display;
|
||||
extern EGLDisplay qemu_egl_display;
|
||||
extern EGLConfig qemu_egl_config;
|
||||
extern DisplayGLMode qemu_egl_mode;
|
||||
extern bool qemu_egl_angle_d3d;
|
||||
|
|
|
|||
|
|
@ -1056,6 +1056,7 @@ static void multifd_recv_terminate_threads(Error *err)
|
|||
trace_multifd_recv_terminate_threads(err != NULL);
|
||||
|
||||
if (qatomic_xchg(&multifd_recv_state->exiting, 1)) {
|
||||
error_free(err);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -79,6 +79,12 @@ disable=bad-inline-option,
|
|||
useless-suppression,
|
||||
|
||||
|
||||
[TYPECHECK]
|
||||
|
||||
# cv2 is a C extension module whose members are not visible to pylint
|
||||
generated-members=cv2.*
|
||||
|
||||
|
||||
[SIMILARITIES]
|
||||
|
||||
# Minimum lines number of a similarity.
|
||||
|
|
|
|||
|
|
@ -510,6 +510,7 @@ foreach dir : target_dirs
|
|||
protocol: 'tap',
|
||||
timeout: slow_qtests.get(test, 60),
|
||||
priority: slow_qtests.get(test, 60),
|
||||
suite: ['qtest', 'qtest-' + target_base])
|
||||
suite: ['qtest', 'qtest-' + target_base] +
|
||||
(slow_qtests.has_key(test) ? ['slow'] : []))
|
||||
endforeach
|
||||
endforeach
|
||||
|
|
|
|||
|
|
@ -184,6 +184,12 @@ slow_tests = {
|
|||
'test-crypto-tlscredsx509': 90,
|
||||
'test-crypto-tlssession': 90,
|
||||
'test-replication': 60,
|
||||
'rcutorture': 30,
|
||||
'test-rcu-list': 30,
|
||||
'test-rcu-simpleq': 30,
|
||||
'test-rcu-tailq': 30,
|
||||
'test-rcu-slist': 30,
|
||||
'test-thread-pool': 30,
|
||||
}
|
||||
|
||||
foreach test_name, extra: tests
|
||||
|
|
@ -205,5 +211,6 @@ foreach test_name, extra: tests
|
|||
protocol: 'tap',
|
||||
timeout: slow_tests.get(test_name, 30),
|
||||
priority: slow_tests.get(test_name, 30),
|
||||
suite: ['unit'])
|
||||
suite: ['unit'] +
|
||||
(slow_tests.has_key(test_name) ? ['slow'] : []))
|
||||
endforeach
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@
|
|||
#include "trace.h"
|
||||
#include "standard-headers/drm/drm_fourcc.h"
|
||||
|
||||
EGLDisplay *qemu_egl_display;
|
||||
EGLDisplay qemu_egl_display;
|
||||
EGLConfig qemu_egl_config;
|
||||
DisplayGLMode qemu_egl_mode;
|
||||
bool qemu_egl_angle_d3d;
|
||||
|
|
@ -736,19 +736,22 @@ bool egl_init(const char *rendernode, DisplayGLMode mode, Error **errp)
|
|||
|
||||
void egl_cleanup(void)
|
||||
{
|
||||
if (qemu_egl_display) {
|
||||
eglReleaseThread();
|
||||
}
|
||||
|
||||
if (qemu_egl_rn_ctx) {
|
||||
eglDestroyContext(qemu_egl_display, qemu_egl_rn_ctx);
|
||||
qemu_egl_rn_ctx = NULL;
|
||||
}
|
||||
|
||||
if (qemu_egl_display) {
|
||||
eglTerminate(qemu_egl_display);
|
||||
qemu_egl_display = NULL;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_GBM
|
||||
g_clear_pointer(&qemu_egl_rn_gbm_dev, gbm_device_destroy);
|
||||
g_clear_fd(&qemu_egl_rn_fd, NULL);
|
||||
#endif
|
||||
|
||||
if (qemu_egl_display) {
|
||||
eglReleaseThread();
|
||||
eglTerminate(qemu_egl_display);
|
||||
qemu_egl_display = NULL;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue