[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 1/1] Support 2**64 bytes memory regions.
From: |
Alexander Barabash |
Subject: |
[Qemu-devel] [PATCH 1/1] Support 2**64 bytes memory regions. |
Date: |
Mon, 7 Jan 2013 14:08:07 +0200 |
Memory regions created with size UINT64_MAX
are currently treated as regions of size 2**64 bytes.
This patch adds full support for such regions.
Signed-off-by: Alexander Barabash <address@hidden>
---
exec.c | 4 ++++
memory.c | 72 ++++++++++++++++++++++++++++++++++++++++++++------------------
2 files changed, 55 insertions(+), 21 deletions(-)
diff --git a/exec.c b/exec.c
index 140eb56..8ce8ab4 100644
--- a/exec.c
+++ b/exec.c
@@ -789,6 +789,10 @@ static void mem_add(MemoryListener *listener,
MemoryRegionSection *section)
remain.size -= now.size;
remain.offset_within_address_space += now.size;
remain.offset_within_region += now.size;
+ if ((remain.size == TARGET_PAGE_SIZE - 1) &&
+ (section->size == UINT64_MAX)) {
+ remain.size = TARGET_PAGE_SIZE;
+ }
}
now = remain;
if (now.size) {
diff --git a/memory.c b/memory.c
index 1652c10..b30edc8 100644
--- a/memory.c
+++ b/memory.c
@@ -84,6 +84,19 @@ static AddrRange addrrange_intersection(AddrRange r1,
AddrRange r2)
return addrrange_make(start, int128_sub(end, start));
}
+static uint64_t mr_size_get64(Int128 size)
+{
+ if (int128_eq(size, int128_2_64())) {
+ return UINT64_MAX;
+ }
+ return int128_get64(size);
+}
+
+static uint64_t addrrange_size_get64(const AddrRange *r)
+{
+ return mr_size_get64(r->size);
+}
+
enum ListenerDirection { Forward, Reverse };
static bool memory_listener_match(MemoryListener *listener,
@@ -93,6 +106,18 @@ static bool memory_listener_match(MemoryListener *listener,
|| listener->address_space_filter == section->address_space;
}
+static hwaddr memory_region_get_last_addr(const MemoryRegion *mr, hwaddr base)
+{
+ return int128_get64(int128_sub(int128_add(int128_make64(base + mr->addr),
+ mr->size), int128_one()));
+}
+
+static hwaddr memory_region_get_last_offset(const MemoryRegion *mr)
+{
+ return int128_get64(int128_sub(int128_add(int128_make64(mr->alias_offset),
+ mr->size), int128_one()));
+}
+
#define MEMORY_LISTENER_CALL_GLOBAL(_callback, _direction, _args...) \
do { \
MemoryListener *_listener; \
@@ -150,7 +175,7 @@ static bool memory_listener_match(MemoryListener *listener,
.mr = (fr)->mr, \
.address_space = (as), \
.offset_within_region = (fr)->offset_in_region, \
- .size = int128_get64((fr)->addr.size), \
+ .size = flatrange_size_get64(fr), \
.offset_within_address_space = int128_get64((fr)->addr.start), \
.readonly = (fr)->readonly, \
}))
@@ -204,6 +229,12 @@ static bool
memory_region_ioeventfd_equal(MemoryRegionIoeventfd a,
&& !memory_region_ioeventfd_before(b, a);
}
+static
+uint64_t memory_region_ioeventfd_size_get64(const MemoryRegionIoeventfd *fd)
+{
+ return addrrange_size_get64(&fd->addr);
+}
+
typedef struct FlatRange FlatRange;
typedef struct FlatView FlatView;
@@ -240,6 +271,11 @@ static bool flatrange_equal(FlatRange *a, FlatRange *b)
&& a->readonly == b->readonly;
}
+static uint64_t flatrange_size_get64(const FlatRange *fr)
+{
+ return addrrange_size_get64(&fr->addr);
+}
+
static void flatview_init(FlatView *view)
{
view->ranges = NULL;
@@ -598,7 +634,7 @@ static void address_space_add_del_ioeventfds(AddressSpace
*as,
section = (MemoryRegionSection) {
.address_space = as,
.offset_within_address_space = int128_get64(fd->addr.start),
- .size = int128_get64(fd->addr.size),
+ .size = memory_region_ioeventfd_size_get64(fd),
};
MEMORY_LISTENER_CALL(eventfd_del, Forward, §ion,
fd->match_data, fd->data, fd->e);
@@ -611,7 +647,7 @@ static void address_space_add_del_ioeventfds(AddressSpace
*as,
section = (MemoryRegionSection) {
.address_space = as,
.offset_within_address_space = int128_get64(fd->addr.start),
- .size = int128_get64(fd->addr.size),
+ .size = memory_region_ioeventfd_size_get64(fd),
};
MEMORY_LISTENER_CALL(eventfd_add, Reverse, §ion,
fd->match_data, fd->data, fd->e);
@@ -1030,10 +1066,7 @@ void memory_region_destroy(MemoryRegion *mr)
uint64_t memory_region_size(MemoryRegion *mr)
{
- if (int128_eq(mr->size, int128_2_64())) {
- return UINT64_MAX;
- }
- return int128_get64(mr->size);
+ return mr_size_get64(mr->size);
}
const char *memory_region_name(MemoryRegion *mr)
@@ -1163,12 +1196,12 @@ static void
memory_region_update_coalesced_range_as(MemoryRegion *mr, AddressSpa
section = (MemoryRegionSection) {
.address_space = as,
.offset_within_address_space = int128_get64(fr->addr.start),
- .size = int128_get64(fr->addr.size),
+ .size = flatrange_size_get64(fr),
};
MEMORY_LISTENER_CALL(coalesced_mmio_del, Reverse, §ion,
int128_get64(fr->addr.start),
- int128_get64(fr->addr.size));
+ flatrange_size_get64(fr));
QTAILQ_FOREACH(cmr, &mr->coalesced, link) {
tmp = addrrange_shift(cmr->addr,
int128_sub(fr->addr.start,
@@ -1179,7 +1212,7 @@ static void
memory_region_update_coalesced_range_as(MemoryRegion *mr, AddressSpa
tmp = addrrange_intersection(tmp, fr->addr);
MEMORY_LISTENER_CALL(coalesced_mmio_add, Forward, §ion,
int128_get64(tmp.start),
- int128_get64(tmp.size));
+ addrrange_size_get64(&tmp));
}
}
}
@@ -1197,7 +1230,7 @@ static void
memory_region_update_coalesced_range(MemoryRegion *mr)
void memory_region_set_coalescing(MemoryRegion *mr)
{
memory_region_clear_coalescing(mr);
- memory_region_add_coalescing(mr, 0, int128_get64(mr->size));
+ memory_region_add_coalescing(mr, 0, memory_region_size(mr));
}
void memory_region_add_coalescing(MemoryRegion *mr,
@@ -1331,10 +1364,10 @@ static void
memory_region_add_subregion_common(MemoryRegion *mr,
printf("warning: subregion collision %llx/%llx (%s) "
"vs %llx/%llx (%s)\n",
(unsigned long long)offset,
- (unsigned long long)int128_get64(subregion->size),
+ (unsigned long long)memory_region_size(subregion),
subregion->name,
(unsigned long long)other->addr,
- (unsigned long long)int128_get64(other->size),
+ (unsigned long long)memory_region_size(other),
other->name);
#endif
}
@@ -1474,7 +1507,7 @@ MemoryRegionSection memory_region_find(MemoryRegion
*address_space,
ret.offset_within_region = fr->offset_in_region;
ret.offset_within_region += int128_get64(int128_sub(range.start,
fr->addr.start));
- ret.size = int128_get64(range.size);
+ ret.size = addrrange_size_get64(&range);
ret.offset_within_address_space = int128_get64(range.start);
ret.readonly = fr->readonly;
return ret;
@@ -1523,7 +1556,7 @@ static void listener_add_address_space(MemoryListener
*listener,
.mr = fr->mr,
.address_space = as,
.offset_within_region = fr->offset_in_region,
- .size = int128_get64(fr->addr.size),
+ .size = flatrange_size_get64(fr),
.offset_within_address_space = int128_get64(fr->addr.start),
.readonly = fr->readonly,
};
@@ -1652,8 +1685,7 @@ static void mtree_print_mr(fprintf_function mon_printf,
void *f,
" (prio %d, %c%c): alias %s @%s " TARGET_FMT_plx
"-" TARGET_FMT_plx "\n",
base + mr->addr,
- base + mr->addr
- + (hwaddr)int128_get64(mr->size) - 1,
+ memory_region_get_last_addr(mr, base),
mr->priority,
mr->readable ? 'R' : '-',
!mr->readonly && !(mr->rom_device && mr->readable) ? 'W'
@@ -1661,14 +1693,12 @@ static void mtree_print_mr(fprintf_function mon_printf,
void *f,
mr->name,
mr->alias->name,
mr->alias_offset,
- mr->alias_offset
- + (hwaddr)int128_get64(mr->size) - 1);
+ memory_region_get_last_offset(mr));
} else {
mon_printf(f,
TARGET_FMT_plx "-" TARGET_FMT_plx " (prio %d, %c%c): %s\n",
base + mr->addr,
- base + mr->addr
- + (hwaddr)int128_get64(mr->size) - 1,
+ memory_region_get_last_addr(mr, base),
mr->priority,
mr->readable ? 'R' : '-',
!mr->readonly && !(mr->rom_device && mr->readable) ? 'W'
--
1.7.9.5
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Qemu-devel] [PATCH 1/1] Support 2**64 bytes memory regions.,
Alexander Barabash <=