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

Signed-off-by: Sasha Levin <levinsasha...@gmail.com>
---
 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 majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to