]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
kvm tools: pci-shmem init-exit
authorSasha Levin <levinsasha928@gmail.com>
Wed, 5 Sep 2012 08:31:54 +0000 (10:31 +0200)
committerPekka Enberg <penberg@kernel.org>
Wed, 5 Sep 2012 13:22:37 +0000 (16:22 +0300)
Make the init/exit of pci-shmem self-contained, so the global init code
won't need to check if it was selected or not.

Also move the parser out of builtin-run into the pci-shmem code.

Signed-off-by: Sasha Levin <levinsasha928@gmail.com>
Signed-off-by: Pekka Enberg <penberg@kernel.org>
tools/kvm/builtin-run.c
tools/kvm/hw/pci-shmem.c
tools/kvm/include/kvm/pci-shmem.h

index 236078aeda32499b05d1eb1a0b3c0117d1d83e45..d1e7d631f0109b392f45e329956be808fabef97f 100644 (file)
@@ -237,130 +237,6 @@ done:
        return 0;
 }
 
-static int shmem_parser(const struct option *opt, const char *arg, int unset)
-{
-       const u64 default_size = SHMEM_DEFAULT_SIZE;
-       const u64 default_phys_addr = SHMEM_DEFAULT_ADDR;
-       const char *default_handle = SHMEM_DEFAULT_HANDLE;
-       struct shmem_info *si = malloc(sizeof(struct shmem_info));
-       u64 phys_addr;
-       u64 size;
-       char *handle = NULL;
-       int create = 0;
-       const char *p = arg;
-       char *next;
-       int base = 10;
-       int verbose = 0;
-
-       const int skip_pci = strlen("pci:");
-       if (verbose)
-               pr_info("shmem_parser(%p,%s,%d)", opt, arg, unset);
-       /* parse out optional addr family */
-       if (strcasestr(p, "pci:")) {
-               p += skip_pci;
-       } else if (strcasestr(p, "mem:")) {
-               die("I can't add to E820 map yet.\n");
-       }
-       /* parse out physical addr */
-       base = 10;
-       if (strcasestr(p, "0x"))
-               base = 16;
-       phys_addr = strtoll(p, &next, base);
-       if (next == p && phys_addr == 0) {
-               pr_info("shmem: no physical addr specified, using default.");
-               phys_addr = default_phys_addr;
-       }
-       if (*next != ':' && *next != '\0')
-               die("shmem: unexpected chars after phys addr.\n");
-       if (*next == '\0')
-               p = next;
-       else
-               p = next + 1;
-       /* parse out size */
-       base = 10;
-       if (strcasestr(p, "0x"))
-               base = 16;
-       size = strtoll(p, &next, base);
-       if (next == p && size == 0) {
-               pr_info("shmem: no size specified, using default.");
-               size = default_size;
-       }
-       /* look for [KMGkmg][Bb]*  uses base 2. */
-       int skip_B = 0;
-       if (strspn(next, "KMGkmg")) {   /* might have a prefix */
-               if (*(next + 1) == 'B' || *(next + 1) == 'b')
-                       skip_B = 1;
-               switch (*next) {
-               case 'K':
-               case 'k':
-                       size = size << KB_SHIFT;
-                       break;
-               case 'M':
-               case 'm':
-                       size = size << MB_SHIFT;
-                       break;
-               case 'G':
-               case 'g':
-                       size = size << GB_SHIFT;
-                       break;
-               default:
-                       die("shmem: bug in detecting size prefix.");
-                       break;
-               }
-               next += 1 + skip_B;
-       }
-       if (*next != ':' && *next != '\0') {
-               die("shmem: unexpected chars after phys size. <%c><%c>\n",
-                   *next, *p);
-       }
-       if (*next == '\0')
-               p = next;
-       else
-               p = next + 1;
-       /* parse out optional shmem handle */
-       const int skip_handle = strlen("handle=");
-       next = strcasestr(p, "handle=");
-       if (*p && next) {
-               if (p != next)
-                       die("unexpected chars before handle\n");
-               p += skip_handle;
-               next = strchrnul(p, ':');
-               if (next - p) {
-                       handle = malloc(next - p + 1);
-                       strncpy(handle, p, next - p);
-                       handle[next - p] = '\0';        /* just in case. */
-               }
-               if (*next == '\0')
-                       p = next;
-               else
-                       p = next + 1;
-       }
-       /* parse optional create flag to see if we should create shm seg. */
-       if (*p && strcasestr(p, "create")) {
-               create = 1;
-               p += strlen("create");
-       }
-       if (*p != '\0')
-               die("shmem: unexpected trailing chars\n");
-       if (handle == NULL) {
-               handle = malloc(strlen(default_handle) + 1);
-               strcpy(handle, default_handle);
-       }
-       if (verbose) {
-               pr_info("shmem: phys_addr = %llx", phys_addr);
-               pr_info("shmem: size      = %llx", size);
-               pr_info("shmem: handle    = %s", handle);
-               pr_info("shmem: create    = %d", create);
-       }
-
-       si->phys_addr = phys_addr;
-       si->size = size;
-       si->handle = handle;
-       si->create = create;
-       pci_shmem__register_mem(si);    /* ownership of si, etc. passed on. */
-       return 0;
-}
-
 #define BUILD_OPTIONS(name, cfg, kvm)                                  \
        struct option name[] = {                                        \
        OPT_GROUP("Basic options:"),                                    \
@@ -1174,7 +1050,11 @@ static int kvm_cmd_run_init(int argc, const char **argv)
        kbd__init(kvm);
 #endif
 
-       pci_shmem__init(kvm);
+       r = pci_shmem__init(kvm);
+       if (r < 0) {
+               pr_err("pci_shmem__init() failed with error %d\n", r);
+               goto fail;
+       }
 
        if (kvm->cfg.vnc || kvm->cfg.sdl) {
                fb = vesa__init(kvm);
@@ -1298,6 +1178,10 @@ static void kvm_cmd_run_exit(int guest_ret)
        if (r < 0)
                pr_warning("virtio_console__exit() failed with error %d\n", r);
 
+       r = pci_shmem__exit(kvm);
+       if (r < 0)
+               pr_warning("pci_shmem__exit() failed with error %d\n", r);
+
        r = disk_image__exit(kvm);
        if (r < 0)
                pr_warning("disk_image__exit() failed with error %d\n", r);
index ac2d264cf733a690bf3d3c3ec1e49fefe91d8b80..47bb337f4476a78f63c7ee855e77dc25906a2851 100644 (file)
 #include <fcntl.h>
 #include <sys/mman.h>
 
+#define MB_SHIFT (20)
+#define KB_SHIFT (10)
+#define GB_SHIFT (30)
+
 static struct pci_device_header pci_shmem_pci_device = {
        .vendor_id      = cpu_to_le16(PCI_VENDOR_ID_REDHAT_QUMRANET),
        .device_id      = cpu_to_le16(0x1110),
@@ -216,6 +220,130 @@ static void *setup_shmem(const char *key, size_t len, int creating)
        return mem;
 }
 
+int shmem_parser(const struct option *opt, const char *arg, int unset)
+{
+       const u64 default_size = SHMEM_DEFAULT_SIZE;
+       const u64 default_phys_addr = SHMEM_DEFAULT_ADDR;
+       const char *default_handle = SHMEM_DEFAULT_HANDLE;
+       struct shmem_info *si = malloc(sizeof(struct shmem_info));
+       u64 phys_addr;
+       u64 size;
+       char *handle = NULL;
+       int create = 0;
+       const char *p = arg;
+       char *next;
+       int base = 10;
+       int verbose = 0;
+
+       const int skip_pci = strlen("pci:");
+       if (verbose)
+               pr_info("shmem_parser(%p,%s,%d)", opt, arg, unset);
+       /* parse out optional addr family */
+       if (strcasestr(p, "pci:")) {
+               p += skip_pci;
+       } else if (strcasestr(p, "mem:")) {
+               die("I can't add to E820 map yet.\n");
+       }
+       /* parse out physical addr */
+       base = 10;
+       if (strcasestr(p, "0x"))
+               base = 16;
+       phys_addr = strtoll(p, &next, base);
+       if (next == p && phys_addr == 0) {
+               pr_info("shmem: no physical addr specified, using default.");
+               phys_addr = default_phys_addr;
+       }
+       if (*next != ':' && *next != '\0')
+               die("shmem: unexpected chars after phys addr.\n");
+       if (*next == '\0')
+               p = next;
+       else
+               p = next + 1;
+       /* parse out size */
+       base = 10;
+       if (strcasestr(p, "0x"))
+               base = 16;
+       size = strtoll(p, &next, base);
+       if (next == p && size == 0) {
+               pr_info("shmem: no size specified, using default.");
+               size = default_size;
+       }
+       /* look for [KMGkmg][Bb]*  uses base 2. */
+       int skip_B = 0;
+       if (strspn(next, "KMGkmg")) {   /* might have a prefix */
+               if (*(next + 1) == 'B' || *(next + 1) == 'b')
+                       skip_B = 1;
+               switch (*next) {
+               case 'K':
+               case 'k':
+                       size = size << KB_SHIFT;
+                       break;
+               case 'M':
+               case 'm':
+                       size = size << MB_SHIFT;
+                       break;
+               case 'G':
+               case 'g':
+                       size = size << GB_SHIFT;
+                       break;
+               default:
+                       die("shmem: bug in detecting size prefix.");
+                       break;
+               }
+               next += 1 + skip_B;
+       }
+       if (*next != ':' && *next != '\0') {
+               die("shmem: unexpected chars after phys size. <%c><%c>\n",
+                   *next, *p);
+       }
+       if (*next == '\0')
+               p = next;
+       else
+               p = next + 1;
+       /* parse out optional shmem handle */
+       const int skip_handle = strlen("handle=");
+       next = strcasestr(p, "handle=");
+       if (*p && next) {
+               if (p != next)
+                       die("unexpected chars before handle\n");
+               p += skip_handle;
+               next = strchrnul(p, ':');
+               if (next - p) {
+                       handle = malloc(next - p + 1);
+                       strncpy(handle, p, next - p);
+                       handle[next - p] = '\0';        /* just in case. */
+               }
+               if (*next == '\0')
+                       p = next;
+               else
+                       p = next + 1;
+       }
+       /* parse optional create flag to see if we should create shm seg. */
+       if (*p && strcasestr(p, "create")) {
+               create = 1;
+               p += strlen("create");
+       }
+       if (*p != '\0')
+               die("shmem: unexpected trailing chars\n");
+       if (handle == NULL) {
+               handle = malloc(strlen(default_handle) + 1);
+               strcpy(handle, default_handle);
+       }
+       if (verbose) {
+               pr_info("shmem: phys_addr = %llx", phys_addr);
+               pr_info("shmem: size      = %llx", size);
+               pr_info("shmem: handle    = %s", handle);
+               pr_info("shmem: create    = %d", create);
+       }
+
+       si->phys_addr = phys_addr;
+       si->size = size;
+       si->handle = handle;
+       si->create = create;
+       pci_shmem__register_mem(si);    /* ownership of si, etc. passed on. */
+       return 0;
+}
+
 int pci_shmem__init(struct kvm *kvm)
 {
        u8 dev, line, pin;
@@ -226,8 +354,9 @@ int pci_shmem__init(struct kvm *kvm)
                return 0;
 
        /* Register good old INTx */
-       if (irq__register_device(PCI_DEVICE_ID_PCI_SHMEM, &dev, &pin, &line) < 0)
-               return 0;
+       r = irq__register_device(PCI_DEVICE_ID_PCI_SHMEM, &dev, &pin, &line);
+       if (r < 0)
+               return r;
 
        pci_shmem_pci_device.irq_pin = pin;
        pci_shmem_pci_device.irq_line = line;
@@ -261,8 +390,14 @@ int pci_shmem__init(struct kvm *kvm)
        mem = setup_shmem(shmem_region->handle, shmem_region->size,
                                shmem_region->create);
        if (mem == NULL)
-               return 0;
+               return -EINVAL;
+
        kvm__register_mem(kvm, shmem_region->phys_addr, shmem_region->size,
                          mem);
-       return 1;
+       return 0;
+}
+
+int pci_shmem__exit(struct kvm *kvm)
+{
+       return 0;
 }
index 599ab377a72d935195787fffd4019e3e9691f163..6cff2b85bfd3091eca7858564410f209c7d9daa5 100644 (file)
@@ -4,6 +4,8 @@
 #include <linux/types.h>
 #include <linux/list.h>
 
+#include "kvm/parse-options.h"
+
 #define SHMEM_DEFAULT_SIZE (16 << MB_SHIFT)
 #define SHMEM_DEFAULT_ADDR (0xc8000000)
 #define SHMEM_DEFAULT_HANDLE "/kvm_shmem"
@@ -18,8 +20,10 @@ struct shmem_info {
        int create;
 };
 
-int pci_shmem__init(struct kvm *self);
+int pci_shmem__init(struct kvm *kvm);
+int pci_shmem__exit(struct kvm *kvm);
 int pci_shmem__register_mem(struct shmem_info *si);
+int shmem_parser(const struct option *opt, const char *arg, int unset);
 
 int pci_shmem__get_local_irqfd(struct kvm *kvm);
 int pci_shmem__add_client(struct kvm *kvm, u32 id, int fd);