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 <levinsasha...@gmail.com>
---
 tools/kvm/builtin-run.c           | 134 +++--------------------------------
 tools/kvm/hw/pci-shmem.c          | 143 ++++++++++++++++++++++++++++++++++++--
 tools/kvm/include/kvm/pci-shmem.h |   6 +-
 3 files changed, 153 insertions(+), 130 deletions(-)

diff --git a/tools/kvm/builtin-run.c b/tools/kvm/builtin-run.c
index ec61696..9a09376 100644
--- a/tools/kvm/builtin-run.c
+++ b/tools/kvm/builtin-run.c
@@ -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);
diff --git a/tools/kvm/hw/pci-shmem.c b/tools/kvm/hw/pci-shmem.c
index ac2d264..47bb337 100644
--- a/tools/kvm/hw/pci-shmem.c
+++ b/tools/kvm/hw/pci-shmem.c
@@ -13,6 +13,10 @@
 #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;
 }
diff --git a/tools/kvm/include/kvm/pci-shmem.h 
b/tools/kvm/include/kvm/pci-shmem.h
index 599ab37..6cff2b8 100644
--- a/tools/kvm/include/kvm/pci-shmem.h
+++ b/tools/kvm/include/kvm/pci-shmem.h
@@ -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);
-- 
1.7.12

--
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