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