From patchwork Sun Jul 11 18:09:17 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alex Williamson X-Patchwork-Id: 58531 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [199.232.76.165]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 494E0B6EFE for ; Mon, 12 Jul 2010 04:12:21 +1000 (EST) Received: from localhost ([127.0.0.1]:52241 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1OY10k-000541-1w for incoming@patchwork.ozlabs.org; Sun, 11 Jul 2010 14:12:18 -0400 Received: from [140.186.70.92] (port=45728 helo=eggs.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1OY0xw-0003lf-JI for qemu-devel@nongnu.org; Sun, 11 Jul 2010 14:09:25 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.69) (envelope-from ) id 1OY0xv-0006K0-Cf for qemu-devel@nongnu.org; Sun, 11 Jul 2010 14:09:24 -0400 Received: from mx1.redhat.com ([209.132.183.28]:27179) by eggs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1OY0xv-0006Ji-5h for qemu-devel@nongnu.org; Sun, 11 Jul 2010 14:09:23 -0400 Received: from int-mx01.intmail.prod.int.phx2.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) by mx1.redhat.com (8.13.8/8.13.8) with ESMTP id o6BI9Irb018391 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Sun, 11 Jul 2010 14:09:18 -0400 Received: from localhost6.localdomain6 (ovpn01.gateway.prod.ext.phx2.redhat.com [10.5.9.1]) by int-mx01.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id o6BI9HjN019460; Sun, 11 Jul 2010 14:09:17 -0400 From: Alex Williamson To: kvm@vger.kernel.org, qemu-devel@nongnu.org Date: Sun, 11 Jul 2010 12:09:17 -0600 Message-ID: <20100711180917.20121.51464.stgit@localhost6.localdomain6> In-Reply-To: <20100711180910.20121.93313.stgit@localhost6.localdomain6> References: <20100711180910.20121.93313.stgit@localhost6.localdomain6> User-Agent: StGIT/0.14.3 MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.67 on 10.5.11.11 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. Cc: chrisw@redhat.com, alex.williamson@redhat.com, pugs@cisco.com, mst@redhat.com Subject: [Qemu-devel] [RFC PATCH 1/5] qemu_ram_map/unmap: Allow pre-allocated space to be mapped X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org For assigned devices, we want to map the PCI BARs into the VM address space. This is just like mapping an option ROM except the host backing is an mmap area instead of a chunk of vmalloc memory. This allow registration and removal of such areas. Signed-off-by: Alex Williamson --- cpu-common.h | 3 +++ exec.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+), 0 deletions(-) diff --git a/cpu-common.h b/cpu-common.h index 71e7933..8d03f4e 100644 --- a/cpu-common.h +++ b/cpu-common.h @@ -40,7 +40,10 @@ static inline void cpu_register_physical_memory(target_phys_addr_t start_addr, } ram_addr_t cpu_get_physical_page_desc(target_phys_addr_t addr); +ram_addr_t qemu_ram_map(DeviceState *dev, const char *name, + ram_addr_t size, void *host); ram_addr_t qemu_ram_alloc(DeviceState *dev, const char *name, ram_addr_t size); +void qemu_ram_unmap(ram_addr_t addr); void qemu_ram_free(ram_addr_t addr); /* This should only be used for ram local to a device. */ void *qemu_get_ram_ptr(ram_addr_t addr); diff --git a/exec.c b/exec.c index 5420f56..a98b4e9 100644 --- a/exec.c +++ b/exec.c @@ -2808,6 +2808,49 @@ static ram_addr_t last_ram_offset(void) return last; } +ram_addr_t qemu_ram_map(DeviceState *dev, const char *name, + ram_addr_t size, void *host) +{ + RAMBlock *new_block, *block; + + size = TARGET_PAGE_ALIGN(size); + new_block = qemu_mallocz(sizeof(*new_block)); + + if (dev && dev->parent_bus && dev->parent_bus->info->get_dev_path) { + char *id = dev->parent_bus->info->get_dev_path(dev); + if (id) { + snprintf(new_block->idstr, sizeof(new_block->idstr), "%s/", id); + qemu_free(id); + } + } + pstrcat(new_block->idstr, sizeof(new_block->idstr), name); + + QLIST_FOREACH(block, &ram_list.blocks, next) { + if (!strcmp(block->idstr, new_block->idstr)) { + fprintf(stderr, "RAMBlock \"%s\" already registered, abort!\n", + new_block->idstr); + abort(); + } + } + + new_block->host = host; + + new_block->offset = find_ram_offset(size); + new_block->length = size; + + QLIST_INSERT_HEAD(&ram_list.blocks, new_block, next); + + ram_list.phys_dirty = qemu_realloc(ram_list.phys_dirty, + last_ram_offset() >> TARGET_PAGE_BITS); + memset(ram_list.phys_dirty + (new_block->offset >> TARGET_PAGE_BITS), + 0xff, size >> TARGET_PAGE_BITS); + + if (kvm_enabled()) + kvm_setup_guest_memory(new_block->host, size); + + return new_block->offset; +} + ram_addr_t qemu_ram_alloc(DeviceState *dev, const char *name, ram_addr_t size) { RAMBlock *new_block, *block; @@ -2874,6 +2917,19 @@ ram_addr_t qemu_ram_alloc(DeviceState *dev, const char *name, ram_addr_t size) return new_block->offset; } +void qemu_ram_unmap(ram_addr_t addr) +{ + RAMBlock *block; + + QLIST_FOREACH(block, &ram_list.blocks, next) { + if (addr == block->offset) { + QLIST_REMOVE(block, next); + qemu_free(block); + return; + } + } +} + void qemu_ram_free(ram_addr_t addr) { RAMBlock *block;