summary refs log tree commit diff stats
path: root/hw
diff options
context:
space:
mode:
authorRichard Henderson <richard.henderson@linaro.org>2022-04-27 10:49:27 -0700
committerRichard Henderson <richard.henderson@linaro.org>2022-04-27 10:49:28 -0700
commitcf6f26d6f9b2015ee12b4604b79359e76784163a (patch)
tree43dde683a31d7224e3ea29632281cdc5aaa99aff /hw
parent34723f59371f3fd02ea59b94674314b875504426 (diff)
parenta8152c4e4613c70c2f0573a82babbc8acc00cf90 (diff)
downloadfocaccia-qemu-cf6f26d6f9b2015ee12b4604b79359e76784163a.tar.gz
focaccia-qemu-cf6f26d6f9b2015ee12b4604b79359e76784163a.zip
Merge tag 'kraxel-20220427-pull-request' of git://git.kraxel.org/qemu 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/7k6F6eZAf59TLbY7tPocTgFAmJpfYUACgkQTLbY7tPo
# cTg6ChAAn5EWtNwmVbfbVzRTu0kqdx7QXyK6FFgTgXrsrmBCWzJhHDraYa9cMOZU
# wBlU/Rutuv9ETvtRTRic3t0qcdRmvZjpHuA/3agBMJY7xpEQbQ8NwVdSRZTOZo0i
# hXzWEAnxviEv8F/W1TXwB5d2Q9sWlJ2yO8SvcxTfAEK7hOSFrWypp3XRKr5WBHjO
# DFTtwqTk9MRNsgsfnpEHNGDb30JPTqKZKRbDal15NDR9fQz+iCq3FIv/FpBaUfys
# v9GA2zNT324MvhR64xNblaujCn2XFOsFvDY4nGDrfbKGJch8ltAg5t4G1CCZqOn7
# NIiwodC0508sAv9xUm+qvh+oHyf11EFdcAMWYimrExY2I51XOEDnJip/SAdogo5u
# h7LyLkZTEG5tyc+a4PGIcC216ecDDNytMnJM9nh9YK3p5UiBOgcHV2wWDdzJbsdS
# GRoP0fzF/MBQd985HBCF2vtQVk4AbQA7atZ8FKp1ZsHr3sFfs+vd0xyItsDMinBP
# k/eKOOKbHRgXcdIocw4PK16yURrMo5IUGCGGiG9waqYz+VDyHhtikBAzQvYYdnqN
# NaZttCcEieIk4XNd+wCfI0GQLtOY/AP1k8TV0rCaDTnO6nOxJ/uP64IaCzxzCT10
# b8VRdCfYDGjd2C14XYKmTzBRPM4hVrf9bo7FtXVtmSksTG+eIao=
# =yaxh
# -----END PGP SIGNATURE-----
# gpg: Signature made Wed 27 Apr 2022 10:29:41 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-20220427-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>
Diffstat (limited to 'hw')
-rw-r--r--hw/display/trace-events1
-rw-r--r--hw/display/vmware_vga.c41
-rw-r--r--hw/i386/pc_sysfw.c36
-rw-r--r--hw/i386/x86.c32
4 files changed, 70 insertions, 40 deletions
diff --git a/hw/display/trace-events b/hw/display/trace-events
index 91efc88f04..0c0ffcbe42 100644
--- a/hw/display/trace-events
+++ b/hw/display/trace-events
@@ -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"
diff --git a/hw/display/vmware_vga.c b/hw/display/vmware_vga.c
index 45d06cbe25..cedbbde522 100644
--- a/hw/display/vmware_vga.c
+++ b/hw/display/vmware_vga.c
@@ -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"
@@ -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
@@ -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;
 
diff --git a/hw/i386/pc_sysfw.c b/hw/i386/pc_sysfw.c
index 0540047bad..c8d9e71b88 100644
--- a/hw/i386/pc_sysfw.c
+++ b/hw/i386/pc_sysfw.c
@@ -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);
 
@@ -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);
             }
         }
     }
@@ -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);
+    }
+}
diff --git a/hw/i386/x86.c b/hw/i386/x86.c
index bb67272790..79ebdface6 100644
--- a/hw/i386/x86.c
+++ b/hw/i386/x86.c
@@ -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);
 
@@ -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)