Skip to content

Commit

Permalink
Merge tag 'kraxel-20220426-pull-request' of git://git.kraxel.org/qemu…
Browse files Browse the repository at this point in the history
… into staging

vnc: add display-update monitor command.
screendump: add png support.
vmsvga: screen update fix.
i386: sev setup for -bios loaded firmware

# -----BEGIN PGP SIGNATURE-----
#
# iQIzBAABCgAdFiEEoDKM/7k6F6eZAf59TLbY7tPocTgFAmJn0Y8ACgkQTLbY7tPo
# cThxchAAtaz1nUhp4zYPkRaYMYiSI25SIotjzTVozCrtDwgV0SKgGmqBgnY3FFeo
# 1N1xduiDIgfZxam4ptQzZOyQlGq2o7jZGaD07J8wYonqZgQnWjNjZsZGRvAQbuSZ
# e6QCKP29s0ICnp+Y1ync0rFXXKhBCsd6ezl/9irkvtKJ6wkM+Q4hDZft/L9s1eH+
# J+U2TPwAwha91eOKd1UCRnS5mjauIQSY84GOq2ldhHCEqAdkMtwgvsrTYdp8Pp4d
# Ebogwf6xp5fWbhff7Wv9vMUOwa6gYCtSXeLQsgLLcWVmyDBpXxp0FMhT5A35+Mtc
# lrtON+y7/XpZ6lDsG1/WsuJKKjL7l4T2nYcec9z653lWdXMaiZNS9md9eK7+azlc
# JRPk2Mo522OB4xd8uMztBMltIKPWI9mmd48JBq3UbZfv1UG4ZoEw5vwrxrb4iuzk
# GScuW+J3jDdhgKyE8WZIBcIg1C2lRAlp9GmR8J9ZwvecJeFA2dlBrpBSNt26AC21
# ioWFtRrF72C0chJPuijm3P302QaxgFj/vCQ/HX+0BrJbcJQccjCrBzC4OX8tHVcd
# adz1RlOnJoecHXGmMfadeU5triiPWKgEu6E8M4mNzR7BPmwhbnD0SeXh3Dx1nUmf
# le4Mem+94xbzlIwcsgE30wEf91dGiidvkDMTNjhJ3TtVzF3CgqU=
# =TCjo
# -----END PGP SIGNATURE-----
# gpg: Signature made Tue 26 Apr 2022 04:03:43 AM PDT
# gpg:                using RSA key A0328CFFB93A17A79901FE7D4CB6D8EED3E87138
# gpg: Good signature from "Gerd Hoffmann (work) <kraxel@redhat.com>" [undefined]
# gpg:                 aka "Gerd Hoffmann <gerd@kraxel.org>" [undefined]
# gpg:                 aka "Gerd Hoffmann (private) <kraxel@gmail.com>" [undefined]
# 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: A032 8CFF B93A 17A7 9901  FE7D 4CB6 D8EE D3E8 7138

* tag 'kraxel-20220426-pull-request' of git://git.kraxel.org/qemu:
  i386: firmware parsing and sev setup for -bios loaded firmware
  i386: factor out x86_firmware_configure()
  i386: move bios load error message
  avocado/vnc: add test_change_listen
  qapi/ui: add 'display-update' command for changing listen address
  ui/vnc: refactor arrays of addresses to SocketAddressList
  Added parameter to take screenshot with screendump as PNG
  Replacing CONFIG_VNC_PNG with CONFIG_PNG
  hw/display/vmware_vga: do not discard screen updates

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
  • Loading branch information
rth7680 committed Apr 26, 2022
2 parents 80a172d + f7683b6 commit 9aac40c
Show file tree
Hide file tree
Showing 20 changed files with 454 additions and 154 deletions.
3 changes: 2 additions & 1 deletion docs/about/removed-features.rst
Expand Up @@ -355,7 +355,8 @@ documentation of ``query-hotpluggable-cpus`` for additional details.
``change`` (removed in 6.0)
'''''''''''''''''''''''''''

Use ``blockdev-change-medium`` or ``change-vnc-password`` instead.
Use ``blockdev-change-medium`` or ``change-vnc-password`` or
``display-update`` instead.

``query-events`` (removed in 6.0)
'''''''''''''''''''''''''''''''''
Expand Down
11 changes: 6 additions & 5 deletions hmp-commands.hx
Expand Up @@ -247,11 +247,12 @@ ERST

{
.name = "screendump",
.args_type = "filename:F,device:s?,head:i?",
.params = "filename [device [head]]",
.help = "save screen from head 'head' of display device 'device' "
"into PPM image 'filename'",
.cmd = hmp_screendump,
.args_type = "filename:F,format:-fs,device:s?,head:i?",
.params = "filename [-f format] [device [head]]",
.help = "save screen from head 'head' of display device 'device'"
"in specified format 'format' as image 'filename'."
"Currently only 'png' and 'ppm' formats are supported.",
.cmd = hmp_screendump,
.coroutine = true,
},

Expand Down
1 change: 1 addition & 0 deletions hw/display/trace-events
Expand Up @@ -24,6 +24,7 @@ vmware_setmode(uint32_t w, uint32_t h, uint32_t bpp) "%dx%d @ %d bpp"
vmware_verify_rect_less_than_zero(const char *name, const char *param, int x) "%s: %s was < 0 (%d)"
vmware_verify_rect_greater_than_bound(const char *name, const char *param, int bound, int x) "%s: %s was > %d (%d)"
vmware_verify_rect_surface_bound_exceeded(const char *name, const char *component, int bound, const char *param1, int value1, const char *param2, int value2) "%s: %s > %d (%s: %d, %s: %d)"
vmware_update_rect_delayed_flush(void) "display update FIFO full - forcing flush"

# virtio-gpu-base.c
virtio_gpu_features(bool virgl) "virgl %d"
Expand Down
41 changes: 23 additions & 18 deletions hw/display/vmware_vga.c
Expand Up @@ -80,7 +80,7 @@ struct vmsvga_state_s {
struct vmsvga_rect_s {
int x, y, w, h;
} redraw_fifo[REDRAW_FIFO_LEN];
int redraw_fifo_first, redraw_fifo_last;
int redraw_fifo_last;
};

#define TYPE_VMWARE_SVGA "vmware-svga"
Expand Down Expand Up @@ -380,33 +380,39 @@ static inline void vmsvga_update_rect(struct vmsvga_state_s *s,
dpy_gfx_update(s->vga.con, x, y, w, h);
}

static inline void vmsvga_update_rect_delayed(struct vmsvga_state_s *s,
int x, int y, int w, int h)
{
struct vmsvga_rect_s *rect = &s->redraw_fifo[s->redraw_fifo_last++];

s->redraw_fifo_last &= REDRAW_FIFO_LEN - 1;
rect->x = x;
rect->y = y;
rect->w = w;
rect->h = h;
}

static inline void vmsvga_update_rect_flush(struct vmsvga_state_s *s)
{
struct vmsvga_rect_s *rect;

if (s->invalidated) {
s->redraw_fifo_first = s->redraw_fifo_last;
s->redraw_fifo_last = 0;
return;
}
/* Overlapping region updates can be optimised out here - if someone
* knows a smart algorithm to do that, please share. */
while (s->redraw_fifo_first != s->redraw_fifo_last) {
rect = &s->redraw_fifo[s->redraw_fifo_first++];
s->redraw_fifo_first &= REDRAW_FIFO_LEN - 1;
for (int i = 0; i < s->redraw_fifo_last; i++) {
rect = &s->redraw_fifo[i];
vmsvga_update_rect(s, rect->x, rect->y, rect->w, rect->h);
}

s->redraw_fifo_last = 0;
}

static inline void vmsvga_update_rect_delayed(struct vmsvga_state_s *s,
int x, int y, int w, int h)
{

if (s->redraw_fifo_last >= REDRAW_FIFO_LEN) {
trace_vmware_update_rect_delayed_flush();
vmsvga_update_rect_flush(s);
}

struct vmsvga_rect_s *rect = &s->redraw_fifo[s->redraw_fifo_last++];

rect->x = x;
rect->y = y;
rect->w = w;
rect->h = h;
}

#ifdef HW_RECT_ACCEL
Expand Down Expand Up @@ -1161,7 +1167,6 @@ static void vmsvga_reset(DeviceState *dev)
s->config = 0;
s->svgaid = SVGA_ID;
s->cursor.on = 0;
s->redraw_fifo_first = 0;
s->redraw_fifo_last = 0;
s->syncing = 0;

Expand Down
36 changes: 22 additions & 14 deletions hw/i386/pc_sysfw.c
Expand Up @@ -147,7 +147,6 @@ static void pc_system_flash_map(PCMachineState *pcms,
MemoryRegion *flash_mem;
void *flash_ptr;
int flash_size;
int ret;

assert(PC_MACHINE_GET_CLASS(pcms)->pci_enabled);

Expand Down Expand Up @@ -195,19 +194,7 @@ static void pc_system_flash_map(PCMachineState *pcms,
if (sev_enabled()) {
flash_ptr = memory_region_get_ram_ptr(flash_mem);
flash_size = memory_region_size(flash_mem);
/*
* OVMF places a GUIDed structures in the flash, so
* search for them
*/
pc_system_parse_ovmf_flash(flash_ptr, flash_size);

ret = sev_es_save_reset_vector(flash_ptr, flash_size);
if (ret) {
error_report("failed to locate and/or save reset vector");
exit(1);
}

sev_encrypt_flash(flash_ptr, flash_size, &error_fatal);
x86_firmware_configure(flash_ptr, flash_size);
}
}
}
Expand Down Expand Up @@ -259,3 +246,24 @@ void pc_system_firmware_init(PCMachineState *pcms,

pc_system_flash_cleanup_unused(pcms);
}

void x86_firmware_configure(void *ptr, int size)
{
int ret;

/*
* OVMF places a GUIDed structures in the flash, so
* search for them
*/
pc_system_parse_ovmf_flash(ptr, size);

if (sev_enabled()) {
ret = sev_es_save_reset_vector(ptr, size);
if (ret) {
error_report("failed to locate and/or save reset vector");
exit(1);
}

sev_encrypt_flash(ptr, size, &error_fatal);
}
}
32 changes: 24 additions & 8 deletions hw/i386/x86.c
Expand Up @@ -1115,14 +1115,25 @@ void x86_bios_rom_init(MachineState *ms, const char *default_firmware,
}
bios = g_malloc(sizeof(*bios));
memory_region_init_ram(bios, NULL, "pc.bios", bios_size, &error_fatal);
if (!isapc_ram_fw) {
memory_region_set_readonly(bios, true);
}
ret = rom_add_file_fixed(bios_name, (uint32_t)(-bios_size), -1);
if (ret != 0) {
bios_error:
fprintf(stderr, "qemu: could not load PC BIOS '%s'\n", bios_name);
exit(1);
if (sev_enabled()) {
/*
* The concept of a "reset" simply doesn't exist for
* confidential computing guests, we have to destroy and
* re-launch them instead. So there is no need to register
* the firmware as rom to properly re-initialize on reset.
* Just go for a straight file load instead.
*/
void *ptr = memory_region_get_ram_ptr(bios);
load_image_size(filename, ptr, bios_size);
x86_firmware_configure(ptr, bios_size);
} else {
if (!isapc_ram_fw) {
memory_region_set_readonly(bios, true);
}
ret = rom_add_file_fixed(bios_name, (uint32_t)(-bios_size), -1);
if (ret != 0) {
goto bios_error;
}
}
g_free(filename);

Expand All @@ -1143,6 +1154,11 @@ void x86_bios_rom_init(MachineState *ms, const char *default_firmware,
memory_region_add_subregion(rom_memory,
(uint32_t)(-bios_size),
bios);
return;

bios_error:
fprintf(stderr, "qemu: could not load PC BIOS '%s'\n", bios_name);
exit(1);
}

bool x86_machine_is_smm_enabled(const X86MachineState *x86ms)
Expand Down
3 changes: 3 additions & 0 deletions include/hw/i386/x86.h
Expand Up @@ -140,4 +140,7 @@ void gsi_handler(void *opaque, int n, int level);
void ioapic_init_gsi(GSIState *gsi_state, const char *parent_name);
DeviceState *ioapic_init_secondary(GSIState *gsi_state);

/* pc_sysfw.c */
void x86_firmware_configure(void *ptr, int size);

#endif
1 change: 1 addition & 0 deletions include/ui/console.h
Expand Up @@ -518,6 +518,7 @@ int vnc_display_pw_expire(const char *id, time_t expires);
void vnc_parse(const char *str);
int vnc_init_func(void *opaque, QemuOpts *opts, Error **errp);
bool vnc_display_reload_certs(const char *id, Error **errp);
bool vnc_display_update(DisplayUpdateOptionsVNC *arg, Error **errp);

/* input.c */
int index_from_key(const char *key, size_t key_length);
Expand Down
12 changes: 7 additions & 5 deletions meson.build
Expand Up @@ -1115,14 +1115,16 @@ if gtkx11.found()
x11 = dependency('x11', method: 'pkg-config', required: gtkx11.found(),
kwargs: static_kwargs)
endif
vnc = not_found
png = not_found
if get_option('png').allowed() and have_system
png = dependency('libpng', required: get_option('png'),
method: 'pkg-config', kwargs: static_kwargs)
endif
vnc = not_found
jpeg = not_found
sasl = not_found
if get_option('vnc').allowed() and have_system
vnc = declare_dependency() # dummy dependency
png = dependency('libpng', required: get_option('vnc_png'),
method: 'pkg-config', kwargs: static_kwargs)
jpeg = dependency('libjpeg', required: get_option('vnc_jpeg'),
method: 'pkg-config', kwargs: static_kwargs)
sasl = cc.find_library('sasl2', has_headers: ['sasl/sasl.h'],
Expand Down Expand Up @@ -1554,9 +1556,9 @@ config_host_data.set('CONFIG_TPM', have_tpm)
config_host_data.set('CONFIG_USB_LIBUSB', libusb.found())
config_host_data.set('CONFIG_VDE', vde.found())
config_host_data.set('CONFIG_VHOST_USER_BLK_SERVER', have_vhost_user_blk_server)
config_host_data.set('CONFIG_PNG', png.found())
config_host_data.set('CONFIG_VNC', vnc.found())
config_host_data.set('CONFIG_VNC_JPEG', jpeg.found())
config_host_data.set('CONFIG_VNC_PNG', png.found())
config_host_data.set('CONFIG_VNC_SASL', sasl.found())
config_host_data.set('CONFIG_VIRTFS', have_virtfs)
config_host_data.set('CONFIG_VTE', vte.found())
Expand Down Expand Up @@ -3667,11 +3669,11 @@ summary_info += {'curses support': curses}
summary_info += {'virgl support': virgl}
summary_info += {'curl support': curl}
summary_info += {'Multipath support': mpathpersist}
summary_info += {'PNG support': png}
summary_info += {'VNC support': vnc}
if vnc.found()
summary_info += {'VNC SASL support': sasl}
summary_info += {'VNC JPEG support': jpeg}
summary_info += {'VNC PNG support': png}
endif
if targetos not in ['darwin', 'haiku', 'windows']
summary_info += {'OSS support': oss}
Expand Down
4 changes: 2 additions & 2 deletions meson_options.txt
Expand Up @@ -177,12 +177,12 @@ option('vde', type : 'feature', value : 'auto',
description: 'vde network backend support')
option('virglrenderer', type : 'feature', value : 'auto',
description: 'virgl rendering support')
option('png', type : 'feature', value : 'auto',
description: 'PNG support with libpng')
option('vnc', type : 'feature', value : 'auto',
description: 'VNC server')
option('vnc_jpeg', type : 'feature', value : 'auto',
description: 'JPEG lossy compression for VNC server')
option('vnc_png', type : 'feature', value : 'auto',
description: 'PNG compression for VNC server')
option('vnc_sasl', type : 'feature', value : 'auto',
description: 'SASL authentication for VNC server')
option('vte', type : 'feature', value : 'auto',
Expand Down
12 changes: 11 additions & 1 deletion monitor/hmp-cmds.c
Expand Up @@ -1722,9 +1722,19 @@ hmp_screendump(Monitor *mon, const QDict *qdict)
const char *filename = qdict_get_str(qdict, "filename");
const char *id = qdict_get_try_str(qdict, "device");
int64_t head = qdict_get_try_int(qdict, "head", 0);
const char *input_format = qdict_get_try_str(qdict, "format");
Error *err = NULL;
ImageFormat format;

qmp_screendump(filename, id != NULL, id, id != NULL, head, &err);
format = qapi_enum_parse(&ImageFormat_lookup, input_format,
IMAGE_FORMAT_PPM, &err);
if (err) {
goto end;
}

qmp_screendump(filename, id != NULL, id, id != NULL, head,
input_format != NULL, format, &err);
end:
hmp_handle_error(mon, err);
}

Expand Down
15 changes: 15 additions & 0 deletions monitor/qmp-cmds.c
Expand Up @@ -346,6 +346,21 @@ void qmp_display_reload(DisplayReloadOptions *arg, Error **errp)
}
}

void qmp_display_update(DisplayUpdateOptions *arg, Error **errp)
{
switch (arg->type) {
case DISPLAY_UPDATE_TYPE_VNC:
#ifdef CONFIG_VNC
vnc_display_update(&arg->u.vnc, errp);
#else
error_setg(errp, "vnc is invalid, missing 'CONFIG_VNC'");
#endif
break;
default:
abort();
}
}

static int qmp_x_query_rdma_foreach(Object *obj, void *opaque)
{
RdmaProvider *rdma;
Expand Down

0 comments on commit 9aac40c

Please sign in to comment.