From mboxrd@z Thu Jan 1 00:00:00 1970 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 From: Alexander Graf Date: Mon, 1 Nov 2010 16:01:43 +0100 Message-Id: <1288623713-28062-31-git-send-email-agraf@suse.de> In-Reply-To: <1288623713-28062-1-git-send-email-agraf@suse.de> References: <1288623713-28062-1-git-send-email-agraf@suse.de> Subject: [Qemu-devel] [PATCH 30/40] xenner: libxc emu: memory mapping List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel Developers Cc: Gerd Hoffmann 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, +}; -- 1.6.0.2