[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PULL 74/79] memory: Fix access_with_adjusted_size(small si
From: |
Paolo Bonzini |
Subject: |
[Qemu-devel] [PULL 74/79] memory: Fix access_with_adjusted_size(small size) on big-endian memory regions |
Date: |
Sun, 30 Sep 2018 10:13:12 +0200 |
From: Philippe Mathieu-Daudé <address@hidden>
Memory regions configured as DEVICE_BIG_ENDIAN (or DEVICE_NATIVE_ENDIAN on
big-endian guest) behave incorrectly when the memory access 'size' is smaller
than the implementation 'access_size'.
In the following code segment from access_with_adjusted_size():
if (memory_region_big_endian(mr)) {
for (i = 0; i < size; i += access_size) {
r |= access_fn(mr, addr + i, value, access_size,
(size - access_size - i) * 8, access_mask, attrs);
}
(size - access_size - i) * 8 is the number of bits that will arithmetic
shift the current value.
Currently we can only 'left' shift a read() access, and 'right' shift a write().
When the access 'size' is smaller than the implementation, we get a negative
number of bits to shift.
For the read() case, a negative 'left' shift is a 'right' shift :)
However since the 'shift' type is unsigned, there is currently no way to
right shift.
Fix this by changing the access_fn() prototype to handle signed shift values,
and modify the memory_region_shift_read|write_access() helpers to correctly
arithmetic shift the opposite direction when the 'shift' value is negative.
Signed-off-by: Philippe Mathieu-Daudé <address@hidden>
Message-Id: <address@hidden>
Signed-off-by: Paolo Bonzini <address@hidden>
Signed-off-by: Philippe Mathieu-Daudé <address@hidden>
---
memory.c | 34 +++++++++++++++++++++++-----------
1 file changed, 23 insertions(+), 11 deletions(-)
diff --git a/memory.c b/memory.c
index a4d3fa7..b96aec7 100644
--- a/memory.c
+++ b/memory.c
@@ -375,18 +375,30 @@ static void adjust_endianness(MemoryRegion *mr, uint64_t
*data, unsigned size)
}
static inline void memory_region_shift_read_access(uint64_t *value,
- unsigned shift,
+ signed shift,
uint64_t mask,
uint64_t tmp)
{
- *value |= (tmp & mask) << shift;
+ if (shift >= 0) {
+ *value |= (tmp & mask) << shift;
+ } else {
+ *value |= (tmp & mask) >> -shift;
+ }
}
static inline uint64_t memory_region_shift_write_access(uint64_t *value,
- unsigned shift,
+ signed shift,
uint64_t mask)
{
- return (*value >> shift) & mask;
+ uint64_t tmp;
+
+ if (shift >= 0) {
+ tmp = (*value >> shift) & mask;
+ } else {
+ tmp = (*value << -shift) & mask;
+ }
+
+ return tmp;
}
static hwaddr memory_region_to_absolute_addr(MemoryRegion *mr, hwaddr offset)
@@ -415,7 +427,7 @@ static MemTxResult
memory_region_oldmmio_read_accessor(MemoryRegion *mr,
hwaddr addr,
uint64_t *value,
unsigned size,
- unsigned shift,
+ signed shift,
uint64_t mask,
MemTxAttrs attrs)
{
@@ -441,7 +453,7 @@ static MemTxResult
memory_region_read_accessor(MemoryRegion *mr,
hwaddr addr,
uint64_t *value,
unsigned size,
- unsigned shift,
+ signed shift,
uint64_t mask,
MemTxAttrs attrs)
{
@@ -467,7 +479,7 @@ static MemTxResult
memory_region_read_with_attrs_accessor(MemoryRegion *mr,
hwaddr addr,
uint64_t *value,
unsigned size,
- unsigned shift,
+ signed shift,
uint64_t mask,
MemTxAttrs attrs)
{
@@ -494,7 +506,7 @@ static MemTxResult
memory_region_oldmmio_write_accessor(MemoryRegion *mr,
hwaddr addr,
uint64_t *value,
unsigned size,
- unsigned shift,
+ signed shift,
uint64_t mask,
MemTxAttrs attrs)
{
@@ -519,7 +531,7 @@ static MemTxResult
memory_region_write_accessor(MemoryRegion *mr,
hwaddr addr,
uint64_t *value,
unsigned size,
- unsigned shift,
+ signed shift,
uint64_t mask,
MemTxAttrs attrs)
{
@@ -544,7 +556,7 @@ static MemTxResult
memory_region_write_with_attrs_accessor(MemoryRegion *mr,
hwaddr addr,
uint64_t *value,
unsigned size,
- unsigned shift,
+ signed shift,
uint64_t mask,
MemTxAttrs attrs)
{
@@ -574,7 +586,7 @@ static MemTxResult access_with_adjusted_size(hwaddr addr,
hwaddr addr,
uint64_t *value,
unsigned size,
- unsigned shift,
+ signed shift,
uint64_t mask,
MemTxAttrs attrs),
MemoryRegion *mr,
--
1.8.3.1
- [Qemu-devel] [PULL 61/79] MAINTAINERS: add myself as elf2dmp maintainer, (continued)
- [Qemu-devel] [PULL 61/79] MAINTAINERS: add myself as elf2dmp maintainer, Paolo Bonzini, 2018/09/30
- [Qemu-devel] [PULL 58/79] hw: edu: replace device name with macro, Paolo Bonzini, 2018/09/30
- [Qemu-devel] [PULL 62/79] kvmclock: run KVM_KVMCLOCK_CTRL ioctl in vcpu thread, Paolo Bonzini, 2018/09/30
- [Qemu-devel] [PULL 70/79] replay: replay BH for IDE trim operation, Paolo Bonzini, 2018/09/30
- [Qemu-devel] [PULL 57/79] i386: Compile CPUX86State xsave_buf only when support KVM or HVF, Paolo Bonzini, 2018/09/30
- [Qemu-devel] [PULL 67/79] hvf: drop unused variable, Paolo Bonzini, 2018/09/30
- [Qemu-devel] [PULL 69/79] hostmem-file: make available memory-backend-file on POSIX-based hosts, Paolo Bonzini, 2018/09/30
- [Qemu-devel] [PULL 63/79] scsi-block: Deprecate rotation_rate, Paolo Bonzini, 2018/09/30
- [Qemu-devel] [PULL 72/79] memory: Use MAKE_64BIT_MASK(), Paolo Bonzini, 2018/09/30
- [Qemu-devel] [PULL 50/79] Revert "chardev: tcp: postpone TLS work until machine done", Paolo Bonzini, 2018/09/30
- [Qemu-devel] [PULL 74/79] memory: Fix access_with_adjusted_size(small size) on big-endian memory regions,
Paolo Bonzini <=
- [Qemu-devel] [PULL 76/79] hw/nvram/fw_cfg: Use memberwise copy of MemoryRegionOps struct, Paolo Bonzini, 2018/09/30
- [Qemu-devel] [PULL 78/79] cpus: fix TCG kick timer leak, Paolo Bonzini, 2018/09/30
- [Qemu-devel] [PULL 71/79] virtio: do not take address of packed members, Paolo Bonzini, 2018/09/30
- [Qemu-devel] [PULL 66/79] qom/object: add some interface asserts, Paolo Bonzini, 2018/09/30
- [Qemu-devel] [PULL 73/79] memory: Refactor common shifting code from accessors, Paolo Bonzini, 2018/09/30
- [Qemu-devel] [PULL 77/79] docs/devel/memory.txt: Document _with_attrs accessors, Paolo Bonzini, 2018/09/30
- [Qemu-devel] [PULL 68/79] target/i386: fix translation for icount mode, Paolo Bonzini, 2018/09/30
- [Qemu-devel] [PULL 56/79] target/i386: rename HF_SVMI_MASK to HF_GUEST_MASK, Paolo Bonzini, 2018/09/30
- [Qemu-devel] [PULL 64/79] lsi53c895a: convert to trace-events, Paolo Bonzini, 2018/09/30
- [Qemu-devel] [PULL 79/79] hw/scsi/mptendian: Avoid taking address of fields in packed structs, Paolo Bonzini, 2018/09/30