diff --git a/configure b/configure
index 3eee3fcf70..ce54cd2bdc 100755
--- a/configure
+++ b/configure
@@ -5745,6 +5745,7 @@ qemu_confdir=$sysconfdir$confsuffix
 qemu_moddir=$libdir$confsuffix
 qemu_datadir=$datadir$confsuffix
 qemu_localedir="$datadir/locale"
+qemu_icondir="$datadir/icons"
 
 # We can only support ivshmem if we have eventfd
 if [ "$eventfd" = "yes" ]; then
@@ -6210,6 +6211,7 @@ if test "$mingw32" = "no" ; then
 fi
 echo "qemu_helperdir=$libexecdir" >> $config_host_mak
 echo "qemu_localedir=$qemu_localedir" >> $config_host_mak
+echo "qemu_icondir=$qemu_icondir" >> $config_host_mak
 echo "libs_softmmu=$libs_softmmu" >> $config_host_mak
 echo "GIT=$git" >> $config_host_mak
 echo "GIT_SUBMODULES=$git_submodules" >> $config_host_mak
diff --git a/Makefile b/Makefile
index dccba1dca2..e4218d1192 100644
--- a/Makefile
+++ b/Makefile
@@ -667,7 +667,6 @@ pxe-pcnet.rom pxe-rtl8139.rom pxe-virtio.rom \
 efi-e1000.rom efi-eepro100.rom efi-ne2k_pci.rom \
 efi-pcnet.rom efi-rtl8139.rom efi-virtio.rom \
 efi-e1000e.rom efi-vmxnet3.rom \
-qemu-icon.bmp qemu_logo_no_text.svg \
 bamboo.dtb canyonlands.dtb petalogix-s3adsp1800.dtb petalogix-ml605.dtb \
 multiboot.bin linuxboot.bin linuxboot_dma.bin kvmvapic.bin \
 s390-ccw.img s390-netboot.img \
@@ -720,6 +719,7 @@ ifneq (,$(findstring qemu-ga,$(TOOLS)))
 endif
 endif
 
+ICON_SIZES=16x16 24x24 32x32 48x48 64x64 128x128 256x256 512x512
 
 install: all $(if $(BUILD_DOCS),install-doc) install-datadir install-localstatedir
 ifneq ($(TOOLS),)
@@ -741,6 +741,17 @@ ifneq ($(BLOBS),)
 		$(INSTALL_DATA) $(SRC_PATH)/pc-bios/$$x "$(DESTDIR)$(qemu_datadir)"; \
 	done
 endif
+	for s in $(ICON_SIZES); do \
+		mkdir -p "$(DESTDIR)/$(qemu_icondir)/hicolor/$${s}/apps"; \
+		$(INSTALL_DATA) $(SRC_PATH)/ui/icons/qemu_$${s}.png \
+			"$(DESTDIR)/$(qemu_icondir)/hicolor/$${s}/apps/qemu.png"; \
+	done; \
+	mkdir -p "$(DESTDIR)/$(qemu_icondir)/hicolor/32x32/apps"; \
+	$(INSTALL_DATA) $(SRC_PATH)/ui/icons/qemu_32x32.bmp \
+		"$(DESTDIR)/$(qemu_icondir)/hicolor/32x32/apps/qemu.bmp"; \
+	mkdir -p "$(DESTDIR)/$(qemu_icondir)/hicolor/scalable/apps"; \
+	$(INSTALL_DATA) $(SRC_PATH)/ui/icons/qemu.svg \
+		"$(DESTDIR)/$(qemu_icondir)/hicolor/scalable/apps/qemu.svg"
 ifdef CONFIG_GTK
 	$(MAKE) -C po $@
 endif
diff --git a/ui/gtk.c b/ui/gtk.c
index 579990b865..ec63befa16 100644
--- a/ui/gtk.c
+++ b/ui/gtk.c
@@ -2214,8 +2214,8 @@ static void gtk_display_init(DisplayState *ds, DisplayOptions *opts)
     VirtualConsole *vc;
 
     GtkDisplayState *s = g_malloc0(sizeof(*s));
-    char *filename;
     GdkDisplay *window_display;
+    GtkIconTheme *theme;
 
     if (!gtkinit) {
         fprintf(stderr, "gtk initialization failed\n");
@@ -2224,6 +2224,9 @@ static void gtk_display_init(DisplayState *ds, DisplayOptions *opts)
     assert(opts->type == DISPLAY_TYPE_GTK);
     s->opts = opts;
 
+    theme = gtk_icon_theme_get_default();
+    gtk_icon_theme_prepend_search_path(theme, CONFIG_QEMU_ICONDIR);
+
     s->window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
     s->vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
     s->notebook = gtk_notebook_new();
@@ -2248,17 +2251,7 @@ static void gtk_display_init(DisplayState *ds, DisplayOptions *opts)
     qemu_add_mouse_mode_change_notifier(&s->mouse_mode_notifier);
     qemu_add_vm_change_state_handler(gd_change_runstate, s);
 
-    filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, "qemu_logo_no_text.svg");
-    if (filename) {
-        GError *error = NULL;
-        GdkPixbuf *pixbuf = gdk_pixbuf_new_from_file(filename, &error);
-        if (pixbuf) {
-            gtk_window_set_icon(GTK_WINDOW(s->window), pixbuf);
-        } else {
-            g_error_free(error);
-        }
-        g_free(filename);
-    }
+    gtk_window_set_icon_name(GTK_WINDOW(s->window), "qemu");
 
     gd_create_menus(s);
 
diff --git a/ui/sdl2.c b/ui/sdl2.c
index a10b6e3a08..4c0d5db473 100644
--- a/ui/sdl2.c
+++ b/ui/sdl2.c
@@ -762,7 +762,6 @@ static void sdl2_display_early_init(DisplayOptions *o)
 static void sdl2_display_init(DisplayState *ds, DisplayOptions *o)
 {
     uint8_t data = 0;
-    char *filename;
     int i;
     SDL_SysWMinfo info;
 
@@ -837,15 +836,12 @@ static void sdl2_display_init(DisplayState *ds, DisplayOptions *o)
     }
 
     /* Load a 32x32x4 image. White pixels are transparent. */
-    filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, "qemu-icon.bmp");
-    if (filename) {
-        SDL_Surface *image = SDL_LoadBMP(filename);
-        if (image) {
-            uint32_t colorkey = SDL_MapRGB(image->format, 255, 255, 255);
-            SDL_SetColorKey(image, SDL_TRUE, colorkey);
-            SDL_SetWindowIcon(sdl2_console[0].real_window, image);
-        }
-        g_free(filename);
+    SDL_Surface *image = SDL_LoadBMP(CONFIG_QEMU_ICONDIR
+                                     "/hicolor/32x32/apps/qemu.bmp");
+    if (image) {
+        uint32_t colorkey = SDL_MapRGB(image->format, 255, 255, 255);
+        SDL_SetColorKey(image, SDL_TRUE, colorkey);
+        SDL_SetWindowIcon(sdl2_console[0].real_window, image);
     }
 
     gui_grab = 0;
diff --git a/pc-bios/qemu-icon.bmp b/pc-bios/qemu-icon.bmp
deleted file mode 100644
index 72d9a2f561ecbb61e49e75540debf189ee67cdb5..0000000000000000000000000000000000000000
GIT binary patch
diff --git a/ui/icons/Makefile b/ui/icons/Makefile
new file mode 100644
index 0000000000..20bd64ccce
--- /dev/null
+++ b/ui/icons/Makefile
@@ -0,0 +1,13 @@
+
+# Regenerate bitmaps from the SVG using inkscape CLI export
+# and ImageMagick. Don't use ImageMagick for the initial
+# SVG conversion, since it merely calls inkscape, but uses
+# 96 DPI res resulting in poor quality output.
+
+regenerate:
+	for s in 16 24 32 48 64 128 256 512; \
+	do \
+	    inkscape --without-gui --export-png=qemu_$${s}x$${s}.png \
+		--export-width=$$s --export-height=$$s qemu.svg ; \
+	done
+	convert qemu_32x32.png qemu_32x32.bmp
diff --git a/pc-bios/qemu_logo_no_text.svg b/ui/icons/qemu.svg
similarity index 100%
rename from pc-bios/qemu_logo_no_text.svg
rename to ui/icons/qemu.svg
