From b4a932d175c6aa975c456e9b05339aa069c961cb Mon Sep 17 00:00:00 2001 From: Sasha Levin Date: Sat, 17 Dec 2011 20:10:34 +0200 Subject: [PATCH] kvm tools: Fixes for UI modules Fixes include: - Error handling - Cleanup - Standard init/uninit Signed-off-by: Sasha Levin --- 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 155d06845079..cd881e7849e2 100644 --- a/tools/kvm/builtin-run.c +++ b/tools/kvm/builtin-run.c @@ -35,6 +35,7 @@ #include "kvm/builtin-debug.h" #include +#include #include #include @@ -1034,8 +1035,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); @@ -1148,20 +1150,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_err("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_err("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_err("sdl__init() failed with error %d\n", r); + goto fail; + } } - fb__start(); + r = fb__start(); + if (r < 0) { + pr_err("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 b6eb1acee962..e15b7171f9c9 100644 --- a/tools/kvm/framebuffer.c +++ b/tools/kvm/framebuffer.c @@ -4,6 +4,7 @@ #include #include #include +#include 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 63f1082608ce..2c0101f2bb83 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 #include - +#include #include #include #include @@ -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 b66d0ba9982e..dc5022c3e291 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 a5aa411a2c58..36e5986d9cee 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__exit(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__exit(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 da2f6352f5fd..3278c078b828 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__exit(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__exit(struct framebuffer *fb) +{ + return 0; } #endif diff --git a/tools/kvm/ui/sdl.c b/tools/kvm/ui/sdl.c index ac7f01316204..fa5d9c89fbaf 100644 --- a/tools/kvm/ui/sdl.c +++ b/tools/kvm/ui/sdl.c @@ -137,6 +137,7 @@ static const struct set2_scancode const keymap[256] = { [118] = DEFINE_ESC(0x70), /* */ [119] = DEFINE_ESC(0x71), /* */ }; +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__exit(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 d7604921257b..91254c561d94 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__exit(struct framebuffer *fb) +{ + return vnc__stop(fb); +} \ No newline at end of file -- 2.39.5