From patchwork Wed Sep 5 08:31:54 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sasha Levin X-Patchwork-Id: 1406741 Return-Path: X-Original-To: patchwork-kvm@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork2.kernel.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by patchwork2.kernel.org (Postfix) with ESMTP id 41B71DF28C for ; Wed, 5 Sep 2012 08:37:17 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1758230Ab2IEIhK (ORCPT ); Wed, 5 Sep 2012 04:37:10 -0400 Received: from mail-we0-f174.google.com ([74.125.82.174]:40454 "EHLO mail-we0-f174.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1758133Ab2IEIgM (ORCPT ); Wed, 5 Sep 2012 04:36:12 -0400 Received: by mail-we0-f174.google.com with SMTP id x8so223930wey.19 for ; Wed, 05 Sep 2012 01:36:11 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id:x-mailer:in-reply-to:references; bh=/e6GX7n8cfYytr8D23Qt3AIFmbO38eihLaF/N7L9EFc=; b=kBGTUk8thC2Yb+Dgp1AojVFW+0NgCLGJ3TEfmfjTPJnSl+u6ry9bW0PaWvGh3bCYq3 +peB9jTC0Bw6GJm9l4wjVLW3sp8XoIge/0BWBJhAvYzzRE1VkNbSsKpJz5RdoppFknlg wy3R/aNZGkKu8s/oXhwff8iMIzpCIGO5qLegX8pZu+xV9UQ1SglWUQ6NG4RxYpzz7IXu /xx8mAddkqPWhflY0YMMFiWmF8k+eDDUWyu1Sm2okDlxZd6zWNeWHd3dPTFAJqSMizb0 E3Re1QUWjecawaV4suMpMWu/gUt3iqeK5U9936rFX2BcgdcHKJsYRrjqnyawpwxzFbJF 7u6A== Received: by 10.180.98.200 with SMTP id ek8mr36496460wib.0.1346834171541; Wed, 05 Sep 2012 01:36:11 -0700 (PDT) Received: from lappy.capriciverd.com (20.Red-80-59-140.staticIP.rima-tde.net. [80.59.140.20]) by mx.google.com with ESMTPS id q4sm27971068wix.9.2012.09.05.01.36.09 (version=TLSv1/SSLv3 cipher=OTHER); Wed, 05 Sep 2012 01:36:10 -0700 (PDT) From: Sasha Levin To: penberg@kernel.org Cc: asias.hejun@gmail.com, mingo@elte.hu, gorcunov@openvz.org, kvm@vger.kernel.org, Sasha Levin Subject: [PATCH 20/33] kvm tools: pci-shmem init-exit Date: Wed, 5 Sep 2012 10:31:54 +0200 Message-Id: <1346833927-15740-21-git-send-email-levinsasha928@gmail.com> X-Mailer: git-send-email 1.7.12 In-Reply-To: <1346833927-15740-1-git-send-email-levinsasha928@gmail.com> References: <1346833927-15740-1-git-send-email-levinsasha928@gmail.com> Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org 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 --- 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 #include +#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 #include +#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);