[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-devel] [RFC][PATCH 02/16 v6] Add API to create memory mapping
From: |
Wen Congyang |
Subject: |
Re: [Qemu-devel] [RFC][PATCH 02/16 v6] Add API to create memory mapping list |
Date: |
Wed, 15 Feb 2012 11:00:30 +0800 |
User-agent: |
Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.1.9) Gecko/20100413 Fedora/3.0.4-2.fc13 Thunderbird/3.0.4 |
At 02/15/2012 12:39 AM, Jan Kiszka Wrote:
> On 2012-02-09 04:20, 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 <address@hidden>
>> ---
>> Makefile.target | 1 +
>> memory_mapping.c | 130
>> ++++++++++++++++++++++++++++++++++++++++++++++++++++++
>> memory_mapping.h | 38 ++++++++++++++++
>> 3 files changed, 169 insertions(+), 0 deletions(-)
>> create mode 100644 memory_mapping.c
>> create mode 100644 memory_mapping.h
>>
>> diff --git a/Makefile.target b/Makefile.target
>> index 68481a3..e35e464 100644
>> --- a/Makefile.target
>> +++ b/Makefile.target
>> @@ -200,6 +200,7 @@ obj-$(CONFIG_KVM) += kvm.o kvm-all.o
>> obj-$(CONFIG_NO_KVM) += kvm-stub.o
>> obj-$(CONFIG_VGA) += vga.o
>> obj-y += memory.o savevm.o
>> +obj-y += memory_mapping.o
>> LIBS+=-lz
>>
>> obj-i386-$(CONFIG_KVM) += hyperv.o
>> 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 <address@hidden>
>> + *
>> + * 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;
>> +}
>> +
>> +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);
>> + }
>> +
>> + list->num = 0;
>> +}
>> diff --git a/memory_mapping.h b/memory_mapping.h
>> new file mode 100644
>> index 0000000..a4b1532
>> --- /dev/null
>> +++ b/memory_mapping.h
>> @@ -0,0 +1,38 @@
>> +#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;
>
> This field looks unused by this series. Unless I miss something, you
> probably want to drop it.
It is used in patch 09/16. I need it to calculate the PT_LOAD's num.
>
>> + QTAILQ_HEAD(, MemoryMapping) head;
>> +} MemoryMappingList;
>> +
>> +/*
>> + * crash needs some memory mapping should be at the head of the list. It
>> will
>> + * cause the list is not sorted. So the caller must add the special memory
>> + * mapping after adding all the normal memory mapping into list.
>> + */
>> +void create_new_memory_mapping_head(MemoryMappingList *list,
>> + target_phys_addr_t phys_addr,
>> + target_phys_addr_t virt_addr,
>> + ram_addr_t length);
>> +/*
>> + * add or merge the memory region into the memory mapping's list. The list
>> is
>> + * sorted by phys_addr.
>> + */
>> +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
>
> A bit hard to understand and use the API. I would suggest:
Sorry for confusing you. I will change the API's name.
>
> memory_mapping_list_add_sorted(MemoryMappingList *list, ...);
> memory_mapping_list_add_head(MemoryMappingList *list, ...);
> memory_mapping_list_free(MemoryMappingList *list);
>
> memory_mapping_list_add_head should set a flag in the MemoryMapping
> appended to the list or let the MemoryMappingList point to the firs
> sorted entry. That way, the adding order becomes irrelevant.
Agree with it.
>
> Moreover, you are lacking some
> memory_mapping_list_init(MemoryMappingList *list). Cleaner than
> open-coding this.
A useful API, and I will add it.
Thanks
Wen Congyang
>
> Jan
>
- [Qemu-devel] [RFC][PATCH 00/16 v6] introducing a new, dedicated memory dump mechanism, Wen Congyang, 2012/02/08
- [Qemu-devel] [RFC][PATCH 02/16 v6] Add API to create memory mapping list, Wen Congyang, 2012/02/08
- [Qemu-devel] [RFC][PATCH 03/16 v6] Add API to check whether a physical address is I/O address, Wen Congyang, 2012/02/08
- [Qemu-devel] [RFC][PATCH 04/16 v6] target-i386: implement cpu_get_memory_mapping(), Wen Congyang, 2012/02/08
- [Qemu-devel] [RFC][PATCH 05/16 v6] Add API to get memory mapping, Wen Congyang, 2012/02/08