From a014ed07bd5a93950fe12c88ed5faf188a22ee01 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Fri, 24 May 2013 17:48:52 +0200 Subject: memory: accept mismatching sizes in memory_region_access_valid The memory API is able to use smaller/wider accesses than requested, match that in memory_region_access_valid. Of course, the accepts callback is still free to reject those accesses. Reviewed-by: Richard Henderson Signed-off-by: Paolo Bonzini --- memory.c | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) (limited to 'memory.c') diff --git a/memory.c b/memory.c index 9e1c1a3aba..c72f56d472 100644 --- a/memory.c +++ b/memory.c @@ -856,24 +856,35 @@ bool memory_region_access_valid(MemoryRegion *mr, unsigned size, bool is_write) { - if (mr->ops->valid.accepts - && !mr->ops->valid.accepts(mr->opaque, addr, size, is_write)) { - return false; - } + int access_size_min, access_size_max; + int access_size, i; if (!mr->ops->valid.unaligned && (addr & (size - 1))) { return false; } - /* Treat zero as compatibility all valid */ - if (!mr->ops->valid.max_access_size) { + if (!mr->ops->valid.accepts) { return true; } - if (size > mr->ops->valid.max_access_size - || size < mr->ops->valid.min_access_size) { - return false; + access_size_min = mr->ops->valid.min_access_size; + if (!mr->ops->valid.min_access_size) { + access_size_min = 1; + } + + access_size_max = mr->ops->valid.max_access_size; + if (!mr->ops->valid.max_access_size) { + access_size_max = 4; + } + + access_size = MAX(MIN(size, access_size_max), access_size_min); + for (i = 0; i < size; i += access_size) { + if (!mr->ops->valid.accepts(mr->opaque, addr + i, access_size, + is_write)) { + return false; + } } + return true; } -- cgit v1.2.1