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 <rth@twiddle.net> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
parent
51644ab70b
commit
a014ed07bd
29
memory.c
29
memory.c
@ -856,24 +856,35 @@ bool memory_region_access_valid(MemoryRegion *mr,
|
|||||||
unsigned size,
|
unsigned size,
|
||||||
bool is_write)
|
bool is_write)
|
||||||
{
|
{
|
||||||
if (mr->ops->valid.accepts
|
int access_size_min, access_size_max;
|
||||||
&& !mr->ops->valid.accepts(mr->opaque, addr, size, is_write)) {
|
int access_size, i;
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!mr->ops->valid.unaligned && (addr & (size - 1))) {
|
if (!mr->ops->valid.unaligned && (addr & (size - 1))) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Treat zero as compatibility all valid */
|
if (!mr->ops->valid.accepts) {
|
||||||
if (!mr->ops->valid.max_access_size) {
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (size > mr->ops->valid.max_access_size
|
access_size_min = mr->ops->valid.min_access_size;
|
||||||
|| size < mr->ops->valid.min_access_size) {
|
if (!mr->ops->valid.min_access_size) {
|
||||||
return false;
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user