[RFC 04/12] kvm tools: Fixes for UI modules

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Fixes include:
 - Error handling
 - Cleanup
 - Standard init/uninit

Signed-off-by: Sasha Levin <levinsasha928@xxxxxxxxx>
---
 tools/kvm/builtin-run.c             |   35 ++++++++++++++++++++++++++---------
 tools/kvm/framebuffer.c             |    9 ++++++++-
 tools/kvm/hw/vesa.c                 |   11 +++++++----
 tools/kvm/include/kvm/framebuffer.h |    1 +
 tools/kvm/include/kvm/sdl.h         |    7 ++++++-
 tools/kvm/include/kvm/vnc.h         |   10 ++++++++--
 tools/kvm/ui/sdl.c                  |   31 +++++++++++++++++++++++++++----
 tools/kvm/ui/vnc.c                  |   22 +++++++++++++++++-----
 8 files changed, 100 insertions(+), 26 deletions(-)

diff --git a/tools/kvm/builtin-run.c b/tools/kvm/builtin-run.c
index e40d90b..37bc3f2 100644
--- a/tools/kvm/builtin-run.c
+++ b/tools/kvm/builtin-run.c
@@ -35,6 +35,7 @@
 #include "kvm/builtin-debug.h"
 
 #include <linux/types.h>
+#include <linux/err.h>
 
 #include <sys/utsname.h>
 #include <sys/types.h>
@@ -992,8 +993,9 @@ static int kvm_cmd_run_init(int argc, const char **argv)
 	if (vnc || sdl) {
 		if (vidmode == -1)
 			vidmode = 0x312;
-	} else
+	} else {
 		vidmode = 0;
+	}
 
 	memset(real_cmdline, 0, sizeof(real_cmdline));
 	kvm__arch_set_cmdline(real_cmdline, vnc || sdl);
@@ -1105,20 +1107,35 @@ static int kvm_cmd_run_init(int argc, const char **argv)
 
 	pci_shmem__init(kvm);
 
-	if (vnc || sdl)
+	if (vnc || sdl) {
 		fb = vesa__init(kvm);
+		if (IS_ERR(fb)) {
+			pr_error("vesa__init() failed with error %ld\n", PTR_ERR(fb));
+			goto fail;
+		}
+	}
 
-	if (vnc) {
-		if (fb)
-			vnc__init(fb);
+	if (vnc && fb) {
+		r = vnc__init(fb);
+		if (r < 0) {
+			pr_error("vnc__init() failed with error %d\n", r);
+			goto fail;
+		}
 	}
 
-	if (sdl) {
-		if (fb)
-			sdl__init(fb);
+	if (sdl && fb) {
+		sdl__init(fb);
+		if (r < 0) {
+			pr_error("sdl__init() failed with error %d\n", r);
+			goto fail;
+		}
 	}
 
-	fb__start();
+	r = fb__start();
+	if (r < 0) {
+		pr_error("fb__init() failed with error %d\n", r);
+		goto fail;
+	}
 
 	/* Device init all done; firmware init must
 	 * come after this (it may set up device trees etc.)
diff --git a/tools/kvm/framebuffer.c b/tools/kvm/framebuffer.c
index b6eb1ac..e15b717 100644
--- a/tools/kvm/framebuffer.c
+++ b/tools/kvm/framebuffer.c
@@ -4,6 +4,7 @@
 #include <linux/list.h>
 #include <stdlib.h>
 #include <sys/mman.h>
+#include <errno.h>
 
 static LIST_HEAD(framebuffers);
 
@@ -18,7 +19,7 @@ struct framebuffer *fb__register(struct framebuffer *fb)
 int fb__attach(struct framebuffer *fb, struct fb_target_operations *ops)
 {
 	if (fb->nr_targets >= FB_MAX_TARGETS)
-		return -1;
+		return -ENOSPC;
 
 	fb->targets[fb->nr_targets++] = ops;
 
@@ -63,6 +64,12 @@ void fb__stop(void)
 	struct framebuffer *fb;
 
 	list_for_each_entry(fb, &framebuffers, node) {
+		u32 i;
+
+		for (i = 0; i < fb->nr_targets; i++)
+			if (fb->targets[i]->stop)
+				fb->targets[i]->stop(fb);
+
 		munmap(fb->mem, fb->mem_size);
 	}
 }
diff --git a/tools/kvm/hw/vesa.c b/tools/kvm/hw/vesa.c
index 63f1082..2c0101f 100644
--- a/tools/kvm/hw/vesa.c
+++ b/tools/kvm/hw/vesa.c
@@ -8,9 +8,10 @@
 #include "kvm/irq.h"
 #include "kvm/kvm.h"
 #include "kvm/pci.h"
+
 #include <linux/byteorder.h>
 #include <sys/mman.h>
-
+#include <linux/err.h>
 #include <sys/types.h>
 #include <sys/ioctl.h>
 #include <inttypes.h>
@@ -50,9 +51,11 @@ struct framebuffer *vesa__init(struct kvm *kvm)
 	u16 vesa_base_addr;
 	u8 dev, line, pin;
 	char *mem;
+	int r;
 
-	if (irq__register_device(PCI_DEVICE_ID_VESA, &dev, &pin, &line) < 0)
-		return NULL;
+	r = irq__register_device(PCI_DEVICE_ID_VESA, &dev, &pin, &line);
+	if (r < 0)
+		return ERR_PTR(r);
 
 	vesa_pci_device.irq_pin		= pin;
 	vesa_pci_device.irq_line	= line;
@@ -62,7 +65,7 @@ struct framebuffer *vesa__init(struct kvm *kvm)
 
 	mem = mmap(NULL, VESA_MEM_SIZE, PROT_RW, MAP_ANON_NORESERVE, -1, 0);
 	if (mem == MAP_FAILED)
-		return NULL;
+		ERR_PTR(-errno);
 
 	kvm__register_mem(kvm, VESA_MEM_ADDR, VESA_MEM_SIZE, mem);
 
diff --git a/tools/kvm/include/kvm/framebuffer.h b/tools/kvm/include/kvm/framebuffer.h
index b66d0ba..dc5022c 100644
--- a/tools/kvm/include/kvm/framebuffer.h
+++ b/tools/kvm/include/kvm/framebuffer.h
@@ -8,6 +8,7 @@ struct framebuffer;
 
 struct fb_target_operations {
 	int (*start)(struct framebuffer *fb);
+	int (*stop)(struct framebuffer *fb);
 };
 
 #define FB_MAX_TARGETS			2
diff --git a/tools/kvm/include/kvm/sdl.h b/tools/kvm/include/kvm/sdl.h
index a5aa411..d0f83e0 100644
--- a/tools/kvm/include/kvm/sdl.h
+++ b/tools/kvm/include/kvm/sdl.h
@@ -6,12 +6,17 @@
 struct framebuffer;
 
 #ifdef CONFIG_HAS_SDL
-void sdl__init(struct framebuffer *fb);
+int sdl__init(struct framebuffer *fb);
+int sdl__uninit(struct framebuffer *fb);
 #else
 static inline void sdl__init(struct framebuffer *fb)
 {
 	die("SDL support not compiled in. (install the SDL-dev[el] package)");
 }
+static inline void sdl__uninit(struct framebuffer *fb)
+{
+	die("SDL support not compiled in. (install the SDL-dev[el] package)");
+}
 #endif
 
 #endif /* KVM__SDL_H */
diff --git a/tools/kvm/include/kvm/vnc.h b/tools/kvm/include/kvm/vnc.h
index da2f635..7f1df5d 100644
--- a/tools/kvm/include/kvm/vnc.h
+++ b/tools/kvm/include/kvm/vnc.h
@@ -4,10 +4,16 @@
 struct framebuffer;
 
 #ifdef CONFIG_HAS_VNCSERVER
-void vnc__init(struct framebuffer *fb);
+int vnc__init(struct framebuffer *fb);
+int vnc__uninit(struct framebuffer *fb);
 #else
-static inline void vnc__init(struct framebuffer *fb)
+static inline int vnc__init(struct framebuffer *fb)
 {
+	return 0;
+}
+static inline int vnc__uninit(struct framebuffer *fb)
+{
+	return 0;
 }
 #endif
 
diff --git a/tools/kvm/ui/sdl.c b/tools/kvm/ui/sdl.c
index 5bf11fa..36e46fa 100644
--- a/tools/kvm/ui/sdl.c
+++ b/tools/kvm/ui/sdl.c
@@ -137,6 +137,7 @@ static const struct set2_scancode const keymap[255] = {
 	[118]	= DEFINE_ESC(0x70),	/* <ins> */
 	[119]	= DEFINE_ESC(0x71),	/* <delete> */
 };
+static bool running, done;
 
 static const struct set2_scancode *to_code(u8 scancode)
 {
@@ -225,7 +226,7 @@ static void *sdl__thread(void *p)
 
 	SDL_EnableKeyRepeat(200, 50);
 
-	for (;;) {
+	while (running) {
 		SDL_BlitSurface(guest_screen, NULL, screen, NULL);
 		SDL_Flip(screen);
 
@@ -254,6 +255,11 @@ static void *sdl__thread(void *p)
 
 		SDL_Delay(1000 / FRAME_RATE);
 	}
+
+	if (running == false && done == false) {
+		done = true;
+		return NULL;
+	}
 exit:
 	kvm_cpu__reboot();
 
@@ -264,17 +270,34 @@ static int sdl__start(struct framebuffer *fb)
 {
 	pthread_t thread;
 
+	running = true;
+
 	if (pthread_create(&thread, NULL, sdl__thread, fb) != 0)
 		return -1;
 
 	return 0;
 }
 
+static int sdl__stop(struct framebuffer *fb)
+{
+	running = false;
+	while (done == false)
+		sleep(0);
+
+	return 0;
+}
+
 static struct fb_target_operations sdl_ops = {
-	.start			= sdl__start,
+	.start	= sdl__start,
+	.start	= sdl__stop,
 };
 
-void sdl__init(struct framebuffer *fb)
+int sdl__init(struct framebuffer *fb)
+{
+	return fb__attach(fb, &sdl_ops);
+}
+
+int sdl__uninit(struct framebuffer *fb)
 {
-	fb__attach(fb, &sdl_ops);
+	return sdl__stop(fb);
 }
diff --git a/tools/kvm/ui/vnc.c b/tools/kvm/ui/vnc.c
index d760492..344e6b7 100644
--- a/tools/kvm/ui/vnc.c
+++ b/tools/kvm/ui/vnc.c
@@ -30,6 +30,7 @@ static char letters[26] = {
 	0x1a,
 };
 
+static rfbScreenInfoPtr server;
 static char num[10] = {
 	0x45, 0x16, 0x1e, 0x26, 0x2e, 0x23, 0x36, 0x3d, 0x3e, 0x46,
 };
@@ -182,8 +183,6 @@ static void *vnc__thread(void *p)
 	char argv[1][1] = {{0}};
 	int argc = 1;
 
-	rfbScreenInfoPtr server;
-
 	server = rfbGetScreen(&argc, (char **) argv, fb->width, fb->height, 8, 3, 4);
 	server->frameBuffer		= fb->mem;
 	server->alwaysShared		= TRUE;
@@ -208,11 +207,24 @@ static int vnc__start(struct framebuffer *fb)
 	return 0;
 }
 
+static int vnc__stop(struct framebuffer *fb)
+{
+	rfbShutdownServer(server, TRUE);
+
+	return 0;
+}
+
 static struct fb_target_operations vnc_ops = {
-	.start			= vnc__start,
+	.start	= vnc__start,
+	.stop	= vnc__stop,
 };
 
-void vnc__init(struct framebuffer *fb)
+int vnc__init(struct framebuffer *fb)
 {
-	fb__attach(fb, &vnc_ops);
+	return fb__attach(fb, &vnc_ops);
 }
+
+int vnc__uninit(struct framebuffer *fb)
+{
+	return vnc__stop(fb);
+}
\ No newline at end of file
-- 
1.7.8

--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [KVM ARM]     [KVM ia64]     [KVM ppc]     [Virtualization Tools]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite Questions]     [Linux Kernel]     [Linux SCSI]     [XFree86]
  Powered by Linux