#endif
}
-static bool memory_region_wrong_endianness(MemoryRegion *mr)
+static void adjust_endianness(MemoryRegion *mr, uint64_t *data, MemOp op)
{
-#ifdef TARGET_WORDS_BIGENDIAN
- return mr->ops->endianness == DEVICE_LITTLE_ENDIAN;
-#else
- return mr->ops->endianness == DEVICE_BIG_ENDIAN;
-#endif
-}
-
-static void adjust_endianness(MemoryRegion *mr, uint64_t *data, unsigned size)
-{
- if (memory_region_wrong_endianness(mr)) {
- switch (size) {
- case 1:
+ if ((op & MO_BSWAP) != devend_memop(mr->ops->endianness)) {
+ switch (op & MO_SIZE) {
+ case MO_8:
break;
- case 2:
+ case MO_16:
*data = bswap16(*data);
break;
- case 4:
+ case MO_32:
*data = bswap32(*data);
break;
- case 8:
+ case MO_64:
*data = bswap64(*data);
break;
default:
- abort();
+ g_assert_not_reached();
}
}
}
tmp = mr->ops->read(mr->opaque, addr, size);
if (mr->subpage) {
trace_memory_region_subpage_read(get_cpu_index(), mr, addr, tmp, size);
- } else if (mr == &io_mem_notdirty) {
- /* Accesses to code which has previously been translated into a TB show
- * up in the MMIO path, as accesses to the io_mem_notdirty
- * MemoryRegion. */
- trace_memory_region_tb_read(get_cpu_index(), addr, tmp, size);
} else if (TRACE_MEMORY_REGION_OPS_READ_ENABLED) {
hwaddr abs_addr = memory_region_to_absolute_addr(mr, addr);
trace_memory_region_ops_read(get_cpu_index(), mr, abs_addr, tmp, size);
r = mr->ops->read_with_attrs(mr->opaque, addr, &tmp, size, attrs);
if (mr->subpage) {
trace_memory_region_subpage_read(get_cpu_index(), mr, addr, tmp, size);
- } else if (mr == &io_mem_notdirty) {
- /* Accesses to code which has previously been translated into a TB show
- * up in the MMIO path, as accesses to the io_mem_notdirty
- * MemoryRegion. */
- trace_memory_region_tb_read(get_cpu_index(), addr, tmp, size);
} else if (TRACE_MEMORY_REGION_OPS_READ_ENABLED) {
hwaddr abs_addr = memory_region_to_absolute_addr(mr, addr);
trace_memory_region_ops_read(get_cpu_index(), mr, abs_addr, tmp, size);
if (mr->subpage) {
trace_memory_region_subpage_write(get_cpu_index(), mr, addr, tmp, size);
- } else if (mr == &io_mem_notdirty) {
- /* Accesses to code which has previously been translated into a TB show
- * up in the MMIO path, as accesses to the io_mem_notdirty
- * MemoryRegion. */
- trace_memory_region_tb_write(get_cpu_index(), addr, tmp, size);
} else if (TRACE_MEMORY_REGION_OPS_WRITE_ENABLED) {
hwaddr abs_addr = memory_region_to_absolute_addr(mr, addr);
trace_memory_region_ops_write(get_cpu_index(), mr, abs_addr, tmp, size);
if (mr->subpage) {
trace_memory_region_subpage_write(get_cpu_index(), mr, addr, tmp, size);
- } else if (mr == &io_mem_notdirty) {
- /* Accesses to code which has previously been translated into a TB show
- * up in the MMIO path, as accesses to the io_mem_notdirty
- * MemoryRegion. */
- trace_memory_region_tb_write(get_cpu_index(), addr, tmp, size);
} else if (TRACE_MEMORY_REGION_OPS_WRITE_ENABLED) {
hwaddr abs_addr = memory_region_to_absolute_addr(mr, addr);
trace_memory_region_ops_write(get_cpu_index(), mr, abs_addr, tmp, size);
{
FlatView *view;
- rcu_read_lock();
+ RCU_READ_LOCK_GUARD();
do {
view = address_space_to_flatview(as);
/* If somebody has replaced as->current_map concurrently,
* flatview_ref returns false.
*/
} while (!flatview_ref(view));
- rcu_read_unlock();
return view;
}
#ifdef DEBUG_UNASSIGNED
printf("Unassigned mem read " TARGET_FMT_plx "\n", addr);
#endif
- if (current_cpu != NULL) {
- bool is_exec = current_cpu->mem_io_access_type == MMU_INST_FETCH;
- cpu_unassigned_access(current_cpu, addr, false, is_exec, 0, size);
- }
return 0;
}
#ifdef DEBUG_UNASSIGNED
printf("Unassigned mem write " TARGET_FMT_plx " = 0x%"PRIx64"\n", addr, val);
#endif
- if (current_cpu != NULL) {
- cpu_unassigned_access(current_cpu, addr, true, false, 0, size);
- }
}
static bool unassigned_mem_accepts(void *opaque, hwaddr addr,
MemTxResult memory_region_dispatch_read(MemoryRegion *mr,
hwaddr addr,
uint64_t *pval,
- unsigned size,
+ MemOp op,
MemTxAttrs attrs)
{
+ unsigned size = memop_size(op);
MemTxResult r;
if (!memory_region_access_valid(mr, addr, size, false, attrs)) {
}
r = memory_region_dispatch_read1(mr, addr, pval, size, attrs);
- adjust_endianness(mr, pval, size);
+ adjust_endianness(mr, pval, op);
return r;
}
MemTxResult memory_region_dispatch_write(MemoryRegion *mr,
hwaddr addr,
uint64_t data,
- unsigned size,
+ MemOp op,
MemTxAttrs attrs)
{
+ unsigned size = memop_size(op);
+
if (!memory_region_access_valid(mr, addr, size, true, attrs)) {
unassigned_mem_write(mr, addr, data, size);
return MEMTX_DECODE_ERROR;
}
- adjust_endianness(mr, &data, size);
+ adjust_endianness(mr, &data, op);
if ((!kvm_eventfds_enabled()) &&
memory_region_dispatch_write_eventfds(mr, addr, data, size, attrs)) {
return memory_region_get_dirty_log_mask(mr) & (1 << client);
}
-static void memory_region_update_iommu_notify_flags(IOMMUMemoryRegion *iommu_mr)
+static int memory_region_update_iommu_notify_flags(IOMMUMemoryRegion *iommu_mr,
+ Error **errp)
{
IOMMUNotifierFlag flags = IOMMU_NOTIFIER_NONE;
IOMMUNotifier *iommu_notifier;
IOMMUMemoryRegionClass *imrc = IOMMU_MEMORY_REGION_GET_CLASS(iommu_mr);
+ int ret = 0;
IOMMU_NOTIFIER_FOREACH(iommu_notifier, iommu_mr) {
flags |= iommu_notifier->notifier_flags;
}
if (flags != iommu_mr->iommu_notify_flags && imrc->notify_flag_changed) {
- imrc->notify_flag_changed(iommu_mr,
- iommu_mr->iommu_notify_flags,
- flags);
+ ret = imrc->notify_flag_changed(iommu_mr,
+ iommu_mr->iommu_notify_flags,
+ flags, errp);
}
- iommu_mr->iommu_notify_flags = flags;
+ if (!ret) {
+ iommu_mr->iommu_notify_flags = flags;
+ }
+ return ret;
}
-void memory_region_register_iommu_notifier(MemoryRegion *mr,
- IOMMUNotifier *n)
+int memory_region_register_iommu_notifier(MemoryRegion *mr,
+ IOMMUNotifier *n, Error **errp)
{
IOMMUMemoryRegion *iommu_mr;
+ int ret;
if (mr->alias) {
- memory_region_register_iommu_notifier(mr->alias, n);
- return;
+ return memory_region_register_iommu_notifier(mr->alias, n, errp);
}
/* We need to register for at least one bitfield */
n->iommu_idx < memory_region_iommu_num_indexes(iommu_mr));
QLIST_INSERT_HEAD(&iommu_mr->iommu_notify, n, node);
- memory_region_update_iommu_notify_flags(iommu_mr);
+ ret = memory_region_update_iommu_notify_flags(iommu_mr, errp);
+ if (ret) {
+ QLIST_REMOVE(n, node);
+ }
+ return ret;
}
uint64_t memory_region_iommu_get_min_page_size(IOMMUMemoryRegion *iommu_mr)
}
QLIST_REMOVE(n, node);
iommu_mr = IOMMU_MEMORY_REGION(mr);
- memory_region_update_iommu_notify_flags(iommu_mr);
+ memory_region_update_iommu_notify_flags(iommu_mr, NULL);
}
void memory_region_notify_one(IOMMUNotifier *notifier,
{
int fd;
- rcu_read_lock();
+ RCU_READ_LOCK_GUARD();
while (mr->alias) {
mr = mr->alias;
}
fd = mr->ram_block->fd;
- rcu_read_unlock();
return fd;
}
void *ptr;
uint64_t offset = 0;
- rcu_read_lock();
+ RCU_READ_LOCK_GUARD();
while (mr->alias) {
offset += mr->alias_offset;
mr = mr->alias;
}
assert(mr->ram_block);
ptr = qemu_map_ram_ptr(mr->ram_block, offset);
- rcu_read_unlock();
return ptr;
}
qemu_ram_resize(mr->ram_block, newsize, errp);
}
+
+void memory_region_do_writeback(MemoryRegion *mr, hwaddr addr, hwaddr size)
+{
+ /*
+ * Might be extended case needed to cover
+ * different types of memory regions
+ */
+ if (mr->ram_block && mr->dirty_log_mask) {
+ qemu_ram_writeback(mr->ram_block, addr, size);
+ }
+}
+
/*
* Call proper memory listeners about the change on the newly
* added/removed CoalescedMemoryRange.
}
if (size) {
- adjust_endianness(mr, &mrfd.data, size);
+ adjust_endianness(mr, &mrfd.data, size_memop(size) | MO_TE);
}
memory_region_transaction_begin();
for (i = 0; i < mr->ioeventfd_nb; ++i) {
unsigned i;
if (size) {
- adjust_endianness(mr, &mrfd.data, size);
+ adjust_endianness(mr, &mrfd.data, size_memop(size) | MO_TE);
}
memory_region_transaction_begin();
for (i = 0; i < mr->ioeventfd_nb; ++i) {
hwaddr addr, uint64_t size)
{
MemoryRegionSection ret;
- rcu_read_lock();
+ RCU_READ_LOCK_GUARD();
ret = memory_region_find_rcu(mr, addr, size);
if (ret.mr) {
memory_region_ref(ret.mr);
}
- rcu_read_unlock();
return ret;
}
{
MemoryRegion *mr;
- rcu_read_lock();
+ RCU_READ_LOCK_GUARD();
mr = memory_region_find_rcu(container, addr, 1).mr;
- rcu_read_unlock();
return mr && mr != container;
}
bool dispatch_tree;
bool owner;
AccelClass *ac;
- const char *ac_name;
};
static void mtree_print_flatview(gpointer key, gpointer value,
if (fvi->ac->has_memory(current_machine, as,
int128_get64(range->addr.start),
MR_SIZE(range->addr.size) + 1)) {
- qemu_printf(" %s", fvi->ac_name);
+ qemu_printf(" %s", fvi->ac->name);
}
}
}
if (ac->has_memory) {
fvi.ac = ac;
- fvi.ac_name = current_machine->accel ? current_machine->accel :
- object_class_get_name(OBJECT_CLASS(ac));
}
/* Gather all FVs in one table */