From patchwork Mon Nov 1 15:01:43 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexander Graf X-Patchwork-Id: 69773 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 869241007D2 for ; Tue, 2 Nov 2010 02:05:33 +1100 (EST) Received: from localhost ([127.0.0.1]:55958 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1PCvv5-0003us-D8 for incoming@patchwork.ozlabs.org; Mon, 01 Nov 2010 11:03:35 -0400 Received: from [140.186.70.92] (port=52943 helo=eggs.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1PCvtu-0003mY-22 for qemu-devel@nongnu.org; Mon, 01 Nov 2010 11:02:24 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1PCvtX-0000hM-6a for qemu-devel@nongnu.org; Mon, 01 Nov 2010 11:02:07 -0400 Received: from cantor2.suse.de ([195.135.220.15]:39342 helo=mx2.suse.de) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1PCvtW-0000gI-S8 for qemu-devel@nongnu.org; Mon, 01 Nov 2010 11:01:59 -0400 Received: from relay2.suse.de (charybdis-ext.suse.de [195.135.221.2]) by mx2.suse.de (Postfix) with ESMTP id 9F1F28A95F; Mon, 1 Nov 2010 16:01:54 +0100 (CET) From: Alexander Graf To: qemu-devel Developers Date: Mon, 1 Nov 2010 16:01:43 +0100 Message-Id: <1288623713-28062-31-git-send-email-agraf@suse.de> X-Mailer: git-send-email 1.6.0.2 In-Reply-To: <1288623713-28062-1-git-send-email-agraf@suse.de> References: <1288623713-28062-1-git-send-email-agraf@suse.de> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.4-2.6 Cc: Gerd Hoffmann Subject: [Qemu-devel] [PATCH 30/40] xenner: libxc emu: memory mapping 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 Xenner emulates parts of libxc, so we can not use the real xen infrastructure when running xen pv guests without xen. This patch adds support for guest memory mapping. Signed-off-by: Alexander Graf --- hw/xenner_libxc_if.c | 124 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 124 insertions(+), 0 deletions(-) create mode 100644 hw/xenner_libxc_if.c diff --git a/hw/xenner_libxc_if.c b/hw/xenner_libxc_if.c new file mode 100644 index 0000000..7ccd3c0 --- /dev/null +++ b/hw/xenner_libxc_if.c @@ -0,0 +1,124 @@ +/* + * Copyright (C) Red Hat 2007 + * Copyright (C) Novell Inc. 2010 + * + * Author(s): Gerd Hoffmann + * Alexander Graf + * + * Xenner Emulation -- memory management + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; under version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, see . + */ + +#include +#include + +#include "hw.h" +#include "xen_interfaces.h" +#include "xenner.h" + +/* ------------------------------------------------------------- */ + +static int _qemu_open(void) +{ + return 42; +} + +static int qemu_close(int xc_handle) +{ + return 0; +} + +static void *qemu_map_foreign_range(int xc_handle, uint32_t dom, + int size, int prot, unsigned long mfn) +{ + target_phys_addr_t addr, len; + void *ptr; + + addr = (target_phys_addr_t)mfn << PAGE_SHIFT; + len = size; + ptr = cpu_physical_memory_map(addr, &len, 1); + + if (len != size) { + fprintf(stderr, "%s: couldn't allocate %d bytes\n", __FUNCTION__, size); + return NULL; + } + + return ptr; +} + +static void *qemu_map_foreign_batch(int xc_handle, uint32_t dom, int prot, + xen_pfn_t *arr, int num) +{ + ram_addr_t offset; + void *ptr; + int i; + target_phys_addr_t len = num * TARGET_PAGE_SIZE; + + char filename[] = "/dev/shm/qemu-vmcore.XXXXXX"; + int rc, fd; + + fd = mkstemp(filename); + if (fd == -1) { + fprintf(stderr, "mkstemp(%s): %s\n", filename, strerror(errno)); + return NULL; + }; + unlink(filename); + + rc = ftruncate(fd, len); + if (rc != 0) { + fprintf(stderr, "ftruncate(0x%" PRIx64 "): %s\n", + (uint64_t)len, strerror(errno)); + return NULL; + } + + ptr = mmap(NULL, len, PROT_WRITE | PROT_READ, MAP_SHARED | MAP_POPULATE, + fd, 0); + + for (i = 0; i < num; i++) { + void *map; + target_phys_addr_t pagelen = TARGET_PAGE_SIZE; + + printf("arr[%d] = %#lx\n", i, cpu_get_physical_page_desc(arr[i] << PAGE_SHIFT)); + + /* fetch the pointer in qemu's own virtual memory */ + offset = cpu_get_physical_page_desc(arr[i] << PAGE_SHIFT); + map = cpu_physical_memory_map(offset, &pagelen, 1); + + /* copy current mem to new map */ + memcpy(ptr + (i * TARGET_PAGE_SIZE), map, TARGET_PAGE_SIZE); + + if (mmap(map, TARGET_PAGE_SIZE, prot, MAP_SHARED | MAP_FIXED, + fd, i * TARGET_PAGE_SIZE) == (void*)-1) { + fprintf(stderr, "%s: mmap(#%d, mfn 0x%lx): %s\n", + __FUNCTION__, i, arr[i], strerror(errno)); + return NULL; + } + } + + return ptr; +} + +static void *qemu_map_foreign_pages(int xc_handle, uint32_t dom, int prot, + const xen_pfn_t *arr, int num) +{ + return qemu_map_foreign_batch(xc_handle, dom, prot, (void*)arr, num); +} + +struct XenIfOps xc_xenner = { + .interface_open = _qemu_open, + .interface_close = qemu_close, + .map_foreign_range = qemu_map_foreign_range, + .map_foreign_batch = qemu_map_foreign_batch, + .map_foreign_pages = qemu_map_foreign_pages, +};