qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] [PATCH 30/40] xenner: libxc emu: memory mapping


From: malc
Subject: Re: [Qemu-devel] [PATCH 30/40] xenner: libxc emu: memory mapping
Date: Mon, 1 Nov 2010 18:12:00 +0300 (MSK)
User-agent: Alpine 2.00 (LNX 1167 2008-08-23)

On Mon, 1 Nov 2010, Alexander Graf wrote:

> 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 <address@hidden>
> ---
>  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 <address@hidden>
> + *             Alexander Graf <address@hidden>
> + *
> + *  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 <http://www.gnu.org/licenses/>.
> + */
> +
> +#include <sys/mman.h>
> +#include <xenctrl.h>
> +
> +#include "hw.h"
> +#include "xen_interfaces.h"
> +#include "xenner.h"
> +
> +/* ------------------------------------------------------------- */
> +
> +static int _qemu_open(void)
> +{
> +    return 42;
> +}

Identifiers with leading underscore are reserved in this context.

> +
> +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);

mmap can fail.

> +
> +    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) {

And what happens to ptr if it didn't fail and this mmap did?

> +            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,
> +};
> 

-- 
mailto:address@hidden



reply via email to

[Prev in Thread] Current Thread [Next in Thread]