All of lore.kernel.org
 help / color / mirror / Atom feed
From: Wen Congyang <wency@cn.fujitsu.com>
To: Jan Kiszka <jan.kiszka@siemens.com>
Cc: HATAYAMA Daisuke <d.hatayama@jp.fujitsu.com>,
	Dave Anderson <anderson@redhat.com>,
	qemu-devel <qemu-devel@nongnu.org>
Subject: Re: [Qemu-devel] [RFC][PATCH 1/5 v2] Add API to create memory mapping list
Date: Wed, 14 Dec 2011 16:10:21 +0800	[thread overview]
Message-ID: <4EE859ED.5020107@cn.fujitsu.com> (raw)
In-Reply-To: <4EE74D33.6070105@siemens.com>

At 12/13/2011 09:03 PM, Jan Kiszka Write:
> On 2011-12-09 09:06, Wen Congyang wrote:
>> The memory mapping list stores virtual address and physical address mapping.
>> The folloing patch will use this information to create PT_LOAD in the vmcore.
>>
>> Signed-off-by: Wen Congyang <wency@cn.fujitsu.com>
>> ---
>>  Makefile.target  |    1 +
>>  memory_mapping.c |  130 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
>>  memory_mapping.h |   29 ++++++++++++
>>  3 files changed, 160 insertions(+), 0 deletions(-)
>>  create mode 100644 memory_mapping.c
>>  create mode 100644 memory_mapping.h
>>
>> diff --git a/Makefile.target b/Makefile.target
>> index a111521..778f514 100644
>> --- a/Makefile.target
>> +++ b/Makefile.target
>> @@ -205,6 +205,7 @@ obj-$(CONFIG_REALLY_VIRTFS) += 9pfs/virtio-9p-device.o
>>  obj-$(CONFIG_KVM) += kvm.o kvm-all.o
>>  obj-$(CONFIG_NO_KVM) += kvm-stub.o
>>  obj-y += memory.o
>> +obj-y += memory_mapping.o
>>  LIBS+=-lz
>>  
>>  QEMU_CFLAGS += $(VNC_TLS_CFLAGS)
>> diff --git a/memory_mapping.c b/memory_mapping.c
>> new file mode 100644
>> index 0000000..d83b7d7
>> --- /dev/null
>> +++ b/memory_mapping.c
>> @@ -0,0 +1,130 @@
>> +/*
>> + * QEMU memory mapping
>> + *
>> + * Copyright Fujitsu, Corp. 2011
>> + *
>> + * Authors:
>> + *     Wen Congyang <wency@cn.fujitsu.com>
>> + *
>> + * This work is licensed under the terms of the GNU GPL, version 2.  See
>> + * the COPYING file in the top-level directory.
>> + *
>> + */
>> +
>> +#include "cpu.h"
>> +#include "cpu-all.h"
>> +#include "memory_mapping.h"
>> +
>> +static MemoryMapping *last_mapping;
>> +
>> +static void create_new_memory_mapping(MemoryMappingList *list,
>> +                                      target_phys_addr_t phys_addr,
>> +                                      target_phys_addr_t virt_addr,
>> +                                      ram_addr_t length)
>> +{
>> +    MemoryMapping *memory_mapping, *p;
>> +
>> +    memory_mapping = g_malloc(sizeof(MemoryMapping));
>> +    memory_mapping->phys_addr = phys_addr;
>> +    memory_mapping->virt_addr = virt_addr;
>> +    memory_mapping->length = length;
>> +    last_mapping = memory_mapping;
>> +    list->num++;
>> +    QTAILQ_FOREACH(p, &list->head, next) {
>> +        if (p->phys_addr >= memory_mapping->phys_addr) {
>> +            QTAILQ_INSERT_BEFORE(p, memory_mapping, next);
>> +            return;
>> +        }
>> +    }
>> +    QTAILQ_INSERT_TAIL(&list->head, memory_mapping, next);
>> +    return;
>> +}
>> +
>> +void create_new_memory_mapping_head(MemoryMappingList *list,
>> +                                    target_phys_addr_t phys_addr,
>> +                                    target_phys_addr_t virt_addr,
>> +                                    ram_addr_t length)
>> +{
>> +    MemoryMapping *memory_mapping;
>> +
>> +    memory_mapping = g_malloc(sizeof(MemoryMapping));
>> +    memory_mapping->phys_addr = phys_addr;
>> +    memory_mapping->virt_addr = virt_addr;
>> +    memory_mapping->length = length;
>> +    last_mapping = memory_mapping;
>> +    list->num++;
>> +    QTAILQ_INSERT_HEAD(&list->head, memory_mapping, next);
>> +    return;
>> +}
> 
> Isn't create_new_memory_mapping_head just a special case of
> create_new_memory_mapping? And can't add_to_memory_mapping be used or
> extended so that create_new_memory_mapping_head becomes obsolete?
> Documenting the API would help at least me understanding the different
> semantics.

The memory mapping list is sorted by physical address. If the memory mapping's
num is greater than 2^16-2(the length of the value that contains program header
table entry count is 16 bit), we must drop some mappings...

I drop the memory mappings according to physical address, so I sort it.

But crash will use the first PT_LOAD to calculate phys_offset, so I add
the API create_new_memory_mapping_head() to add a specified memory mapping at
the head of the list.

Do you have any better idea?

> 
>> +
>> +void add_to_memory_mapping(MemoryMappingList *list,
>> +                           target_phys_addr_t phys_addr,
>> +                           target_phys_addr_t virt_addr,
>> +                           ram_addr_t length)
>> +{
>> +    MemoryMapping *memory_mapping;
>> +
>> +    if (QTAILQ_EMPTY(&list->head)) {
>> +        create_new_memory_mapping(list, phys_addr, virt_addr, length);
>> +        return;
>> +    }
>> +
>> +    if (last_mapping) {
>> +        if ((phys_addr == (last_mapping->phys_addr + last_mapping->length)) &&
>> +            (virt_addr == (last_mapping->virt_addr + last_mapping->length))) {
>> +            last_mapping->length += length;
>> +            return;
>> +        }
>> +    }
>> +
>> +    QTAILQ_FOREACH(memory_mapping, &list->head, next) {
>> +        last_mapping = memory_mapping;
>> +        if ((phys_addr == (last_mapping->phys_addr + last_mapping->length)) &&
>> +            (virt_addr == (last_mapping->virt_addr + last_mapping->length))) {
>> +            last_mapping->length += length;
>> +            return;
>> +        }
>> +
>> +        if (!(phys_addr >= (last_mapping->phys_addr)) ||
>> +            !(phys_addr < (last_mapping->phys_addr + last_mapping->length))) {
>> +            /* last_mapping does not contain this region */
>> +            continue;
>> +        }
>> +        if (!(virt_addr >= (last_mapping->virt_addr)) ||
>> +            !(virt_addr < (last_mapping->virt_addr + last_mapping->length))) {
>> +            /* last_mapping does not contain this region */
>> +            continue;
>> +        }
>> +        if ((virt_addr - last_mapping->virt_addr) !=
>> +            (phys_addr - last_mapping->phys_addr)) {
>> +            /*
>> +             * last_mapping contains this region, but we should create another
>> +             * mapping region.
>> +             */
>> +            break;
>> +        }
>> +
>> +        /* merge this region into last_mapping */
>> +        if ((virt_addr + length) >
>> +            (last_mapping->virt_addr + last_mapping->length)) {
>> +            last_mapping->length = virt_addr + length - last_mapping->virt_addr;
>> +        }
>> +        return;
>> +    }
>> +
>> +    /* this region can not be merged into any existed memory mapping. */
>> +    create_new_memory_mapping(list, phys_addr, virt_addr, length);
>> +    return;
>> +}
>> +
>> +void free_memory_mapping_list(MemoryMappingList *list)
>> +{
>> +    MemoryMapping *p, *q;
>> +
>> +    QTAILQ_FOREACH_SAFE(p, &list->head, next, q) {
>> +        QTAILQ_REMOVE(&list->head, p, next);
>> +        g_free(p);
> 
> Can't last_mapping still point to this object?

Yes, will fix it(set last_mapping to NULL in get memory mapping())

Thanks for your comment
Wen Congyang

> 
>> +    }
>> +
>> +    list->num = 0;
>> +}
>> diff --git a/memory_mapping.h b/memory_mapping.h
>> new file mode 100644
>> index 0000000..871591d
>> --- /dev/null
>> +++ b/memory_mapping.h
>> @@ -0,0 +1,29 @@
>> +#ifndef MEMORY_MAPPING_H
>> +#define MEMORY_MAPPING_H
>> +
>> +#include "qemu-queue.h"
>> +
>> +typedef struct MemoryMapping {
>> +    target_phys_addr_t phys_addr;
>> +    target_ulong virt_addr;
>> +    ram_addr_t length;
>> +    QTAILQ_ENTRY(MemoryMapping) next;
>> +} MemoryMapping;
>> +
>> +typedef struct MemoryMappingList {
>> +    unsigned int num;
>> +    QTAILQ_HEAD(, MemoryMapping) head;
>> +} MemoryMappingList;
>> +
>> +void create_new_memory_mapping_head(MemoryMappingList *list,
>> +                                    target_phys_addr_t phys_addr,
>> +                                    target_phys_addr_t virt_addr,
>> +                                    ram_addr_t length);
>> +void add_to_memory_mapping(MemoryMappingList *list,
>> +                           target_phys_addr_t phys_addr,
>> +                           target_phys_addr_t virt_addr,
>> +                           ram_addr_t length);
>> +
>> +void free_memory_mapping_list(MemoryMappingList *list);
>> +
>> +#endif
> 
> Jan
> 

  reply	other threads:[~2011-12-14  8:08 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-12-09  7:57 [Qemu-devel] [RFC][PATCT 0/5 v2] dump memory when host pci device is used by guest Wen Congyang
2011-12-09  8:06 ` [Qemu-devel] [RFC][PATCH 1/5 v2] Add API to create memory mapping list Wen Congyang
2011-12-13 13:03   ` Jan Kiszka
2011-12-14  8:10     ` Wen Congyang [this message]
2011-12-09  8:07 ` [Qemu-devel] [RFC][PATCH 2/5 v2] Add API to check whether a physical address is I/O address Wen Congyang
2011-12-09  8:08 ` [Qemu-devel] [RFC][PATCH 3/5 v2] target-i386: implement cpu_get_memory_mapping() Wen Congyang
2011-12-09  8:09 ` [Qemu-devel] [RFC][PATCH 4/5 v2] Add API to get memory mapping Wen Congyang
2011-12-09  8:09 ` [Qemu-devel] [RFC][PATCH 5/5v2] introduce a new monitor command 'dump' to dump guest's memory Wen Congyang
2011-12-13  3:12 ` [Qemu-devel] [RFC][PATCT 0/5 v2] dump memory when host pci device is used by guest HATAYAMA Daisuke
2011-12-13  3:35   ` Wen Congyang
2011-12-13  6:01     ` HATAYAMA Daisuke
2011-12-13  9:20       ` Wen Congyang
2011-12-15  1:30         ` HATAYAMA Daisuke
2011-12-15  8:57           ` Wen Congyang
2011-12-13 12:55 ` Jan Kiszka
2011-12-14  2:43   ` Wen Congyang

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4EE859ED.5020107@cn.fujitsu.com \
    --to=wency@cn.fujitsu.com \
    --cc=anderson@redhat.com \
    --cc=d.hatayama@jp.fujitsu.com \
    --cc=jan.kiszka@siemens.com \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.