]> git.proxmox.com Git - qemu.git/commitdiff
memory: accept mismatching sizes in memory_region_access_valid
authorPaolo Bonzini <pbonzini@redhat.com>
Fri, 24 May 2013 15:48:52 +0000 (17:48 +0200)
committerPaolo Bonzini <pbonzini@redhat.com>
Wed, 29 May 2013 14:27:19 +0000 (16:27 +0200)
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 <rth@twiddle.net>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
memory.c

index 9e1c1a3abacb3d0de7251a48729bb311e3f8d967..c72f56d472b6ceaad593fb7046956a0a43378120 100644 (file)
--- 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;
 }