[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 21/22] memory: propagate errors on I/O dispatch
From: |
Paolo Bonzini |
Subject: |
[Qemu-devel] [PATCH 21/22] memory: propagate errors on I/O dispatch |
Date: |
Fri, 24 May 2013 19:05:56 +0200 |
Signed-off-by: Paolo Bonzini <address@hidden>
---
exec.c | 21 ++++++++++++---------
include/exec/exec-all.h | 6 +++---
include/exec/softmmu_template.h | 4 +++-
memory.c | 35 ++++++++++++++++++-----------------
4 files changed, 36 insertions(+), 30 deletions(-)
diff --git a/exec.c b/exec.c
index 3068077..28dcee9 100644
--- a/exec.c
+++ b/exec.c
@@ -1523,6 +1523,8 @@ static uint64_t subpage_read(void *opaque, hwaddr addr,
{
subpage_t *mmio = opaque;
unsigned int idx = SUBPAGE_IDX(addr);
+ uint64_t val;
+
MemoryRegionSection *section;
#if defined(DEBUG_SUBPAGE)
printf("%s: subpage %p len %d addr " TARGET_FMT_plx " idx %d\n", __func__,
@@ -1533,7 +1535,8 @@ static uint64_t subpage_read(void *opaque, hwaddr addr,
addr += mmio->base;
addr -= section->offset_within_address_space;
addr += section->offset_within_region;
- return io_mem_read(section->mr, addr, len);
+ io_mem_read(section->mr, addr, &val, len);
+ return val;
}
static void subpage_write(void *opaque, hwaddr addr,
@@ -1901,7 +1904,7 @@ void address_space_rw(AddressSpace *as, hwaddr addr,
uint8_t *buf,
{
hwaddr l;
uint8_t *ptr;
- uint32_t val;
+ uint64_t val;
hwaddr addr1;
MemoryRegionSection *section;
@@ -1940,15 +1943,15 @@ void address_space_rw(AddressSpace *as, hwaddr addr,
uint8_t *buf,
l = memory_access_size(l, addr1);
if (l == 4) {
/* 32 bit read access */
- val = io_mem_read(section->mr, addr1, 4);
+ io_mem_read(section->mr, addr1, &val, 4);
stl_p(buf, val);
} else if (l == 2) {
/* 16 bit read access */
- val = io_mem_read(section->mr, addr1, 2);
+ io_mem_read(section->mr, addr1, &val, 2);
stw_p(buf, val);
} else {
/* 8 bit read access */
- val = io_mem_read(section->mr, addr1, 1);
+ io_mem_read(section->mr, addr1, &val, 1);
stb_p(buf, val);
}
} else {
@@ -2192,7 +2195,7 @@ static inline uint32_t ldl_phys_internal(hwaddr addr,
enum device_endian endian)
{
uint8_t *ptr;
- uint32_t val;
+ uint64_t val;
MemoryRegionSection *section;
hwaddr l = 4;
hwaddr addr1;
@@ -2201,7 +2204,7 @@ static inline uint32_t ldl_phys_internal(hwaddr addr,
false);
if (l < 4 || !memory_access_is_direct(section->mr, false)) {
/* I/O case */
- val = io_mem_read(section->mr, addr1, 4);
+ io_mem_read(section->mr, addr1, &val, 4);
#if defined(TARGET_WORDS_BIGENDIAN)
if (endian == DEVICE_LITTLE_ENDIAN) {
val = bswap32(val);
@@ -2260,7 +2263,7 @@ static inline uint64_t ldq_phys_internal(hwaddr addr,
false);
if (l < 8 || !memory_access_is_direct(section->mr, false)) {
/* I/O case */
- val = io_mem_read(section->mr, addr1, 8);
+ io_mem_read(section->mr, addr1, &val, 8);
#if defined(TARGET_WORDS_BIGENDIAN)
if (endian == DEVICE_LITTLE_ENDIAN) {
val = bswap64(val);
@@ -2327,7 +2330,7 @@ static inline uint32_t lduw_phys_internal(hwaddr addr,
false);
if (l < 2 || !memory_access_is_direct(section->mr, false)) {
/* I/O case */
- val = io_mem_read(section->mr, addr1, 2);
+ io_mem_read(section->mr, addr1, &val, 2);
#if defined(TARGET_WORDS_BIGENDIAN)
if (endian == DEVICE_LITTLE_ENDIAN) {
val = bswap16(val);
diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h
index 6362074..17fde25 100644
--- a/include/exec/exec-all.h
+++ b/include/exec/exec-all.h
@@ -367,9 +367,9 @@ bool is_tcg_gen_code(uintptr_t pc_ptr);
#if !defined(CONFIG_USER_ONLY)
struct MemoryRegion *iotlb_to_region(hwaddr index);
-uint64_t io_mem_read(struct MemoryRegion *mr, hwaddr addr,
- unsigned size);
-void io_mem_write(struct MemoryRegion *mr, hwaddr addr,
+bool io_mem_read(struct MemoryRegion *mr, hwaddr addr,
+ uint64_t *pvalue, unsigned size);
+bool io_mem_write(struct MemoryRegion *mr, hwaddr addr,
uint64_t value, unsigned size);
void tlb_fill(CPUArchState *env1, target_ulong addr, int is_write, int mmu_idx,
diff --git a/include/exec/softmmu_template.h b/include/exec/softmmu_template.h
index 292ca02..8584902 100644
--- a/include/exec/softmmu_template.h
+++ b/include/exec/softmmu_template.h
@@ -63,6 +63,7 @@ static inline DATA_TYPE glue(io_read, SUFFIX)(CPUArchState
*env,
target_ulong addr,
uintptr_t retaddr)
{
+ uint64_t val;
MemoryRegion *mr = iotlb_to_region(physaddr);
physaddr = (physaddr & TARGET_PAGE_MASK) + addr;
@@ -72,7 +73,8 @@ static inline DATA_TYPE glue(io_read, SUFFIX)(CPUArchState
*env,
}
env->mem_io_vaddr = addr;
- return io_mem_read(mr, physaddr, 1 << SHIFT);
+ io_mem_read(mr, physaddr, &val, 1 << SHIFT);
+ return val;
}
/* handle all cases except unaligned access which span two pages */
diff --git a/memory.c b/memory.c
index c9833a3..5d3b7c3 100644
--- a/memory.c
+++ b/memory.c
@@ -928,10 +928,6 @@ static uint64_t memory_region_dispatch_read1(MemoryRegion
*mr,
{
uint64_t data = 0;
- if (!memory_region_access_valid(mr, addr, size, false)) {
- return unassigned_mem_read(mr, addr, size);
- }
-
if (mr->ops->read) {
access_with_adjusted_size(addr, &data, size,
mr->ops->impl.min_access_size,
@@ -966,25 +962,29 @@ static void adjust_endianness(MemoryRegion *mr, uint64_t
*data, unsigned size)
}
}
-static uint64_t memory_region_dispatch_read(MemoryRegion *mr,
- hwaddr addr,
- unsigned size)
+static bool memory_region_dispatch_read(MemoryRegion *mr,
+ hwaddr addr,
+ uint64_t *pval,
+ unsigned size)
{
- uint64_t ret;
+ if (!memory_region_access_valid(mr, addr, size, false)) {
+ *pval = unassigned_mem_read(mr, addr, size);
+ return true;
+ }
- ret = memory_region_dispatch_read1(mr, addr, size);
- adjust_endianness(mr, &ret, size);
- return ret;
+ *pval = memory_region_dispatch_read1(mr, addr, size);
+ adjust_endianness(mr, pval, size);
+ return false;
}
-static void memory_region_dispatch_write(MemoryRegion *mr,
+static bool memory_region_dispatch_write(MemoryRegion *mr,
hwaddr addr,
uint64_t data,
unsigned size)
{
if (!memory_region_access_valid(mr, addr, size, true)) {
unassigned_mem_write(mr, addr, data, size);
- return;
+ return true;
}
adjust_endianness(mr, &data, size);
@@ -998,6 +998,7 @@ static void memory_region_dispatch_write(MemoryRegion *mr,
access_with_adjusted_size(addr, &data, size, 1, 4,
memory_region_oldmmio_write_accessor, mr);
}
+ return false;
}
void memory_region_init_io(MemoryRegion *mr,
@@ -1650,15 +1651,15 @@ void address_space_destroy(AddressSpace *as)
g_free(as->ioeventfds);
}
-uint64_t io_mem_read(MemoryRegion *mr, hwaddr addr, unsigned size)
+bool io_mem_read(MemoryRegion *mr, hwaddr addr, uint64_t *pval, unsigned size)
{
- return memory_region_dispatch_read(mr, addr, size);
+ return memory_region_dispatch_read(mr, addr, pval, size);
}
-void io_mem_write(MemoryRegion *mr, hwaddr addr,
+bool io_mem_write(MemoryRegion *mr, hwaddr addr,
uint64_t val, unsigned size)
{
- memory_region_dispatch_write(mr, addr, val, size);
+ return memory_region_dispatch_write(mr, addr, val, size);
}
typedef struct MemoryRegionList MemoryRegionList;
--
1.8.1.4
- [Qemu-devel] [PATCH 06/22] memory: dispatch unassigned accesses based on .valid.accepts, (continued)
- [Qemu-devel] [PATCH 06/22] memory: dispatch unassigned accesses based on .valid.accepts, Paolo Bonzini, 2013/05/24
- [Qemu-devel] [PATCH 08/22] memory: move unassigned_mem_ops to memory.c, Paolo Bonzini, 2013/05/24
- [Qemu-devel] [PATCH 07/22] memory: add address_space_translate, Paolo Bonzini, 2013/05/24
- [Qemu-devel] [PATCH 09/22] memory: assign MemoryRegionOps to all regions, Paolo Bonzini, 2013/05/24
- [Qemu-devel] [PATCH 11/22] exec: introduce memory_access_is_direct, Paolo Bonzini, 2013/05/24
- [Qemu-devel] [PATCH 12/22] exec: introduce memory_access_size, Paolo Bonzini, 2013/05/24
- [Qemu-devel] [PATCH 10/22] exec: expect mr->ops to be initialized for ROM, Paolo Bonzini, 2013/05/24
- [Qemu-devel] [PATCH 13/22] memory: export memory_region_access_valid to exec.c, Paolo Bonzini, 2013/05/24
- [Qemu-devel] [PATCH 14/22] exec: implement .valid.accepts for subpages, Paolo Bonzini, 2013/05/24
- [Qemu-devel] [PATCH 20/22] exec: just use io_mem_read/io_mem_write for 8-byte I/O accesses, Paolo Bonzini, 2013/05/24
- [Qemu-devel] [PATCH 21/22] memory: propagate errors on I/O dispatch,
Paolo Bonzini <=
- [Qemu-devel] [PATCH 22/22] memory: add return value to address_space_rw/read/write, Paolo Bonzini, 2013/05/24
- [Qemu-devel] [PATCH 18/22] memory: split accesses even when the old MMIO callbacks are used, Paolo Bonzini, 2013/05/24
- [Qemu-devel] [PATCH 19/22] memory: correctly handle endian-swapped 64-bit accesses, Paolo Bonzini, 2013/05/24
- [Qemu-devel] [PATCH 15/22] memory: add address_space_access_valid, Paolo Bonzini, 2013/05/24
- [Qemu-devel] [PATCH 17/22] memory: add big endian support to access_with_adjusted_size, Paolo Bonzini, 2013/05/24
- [Qemu-devel] [PATCH 16/22] memory: accept mismatching sizes in memory_region_access_valid, Paolo Bonzini, 2013/05/24
- Re: [Qemu-devel] [PATCH 00/22] Memory/IOMMU patches, part 2: unassigned access detection, Richard Henderson, 2013/05/24