*/
#include "qemu/osdep.h"
+#include "qemu/log.h"
#include "qapi/error.h"
#include "cpu.h"
#include "exec/memory.h"
#include "qemu/main-loop.h"
#include "qemu/qemu-print.h"
#include "qom/object.h"
-#include "trace-root.h"
+#include "trace.h"
#include "exec/memory-internal.h"
#include "exec/ram_addr.h"
static bool flatview_ref(FlatView *view)
{
- return atomic_fetch_inc_nonzero(&view->ref) > 0;
+ return qatomic_fetch_inc_nonzero(&view->ref) > 0;
}
void flatview_unref(FlatView *view)
{
- if (atomic_fetch_dec(&view->ref) == 1) {
+ if (qatomic_fetch_dec(&view->ref) == 1) {
trace_flatview_destroy_rcu(view, view->root);
assert(view->root);
call_rcu(view, flatview_destroy, rcu);
}
}
+void flatview_for_each_range(FlatView *fv, flatview_cb cb , void *opaque)
+{
+ FlatRange *fr;
+
+ assert(fv);
+ assert(cb);
+
+ FOR_EACH_FLAT_RANGE(fr, fv) {
+ if (cb(fr->addr.start, fr->addr.size, fr->mr, opaque))
+ break;
+ }
+}
+
static MemoryRegion *memory_region_get_flatview_root(MemoryRegion *mr)
{
while (mr->enabled) {
}
/* Writes are protected by the BQL. */
- atomic_rcu_set(&as->current_map, new_view);
+ qatomic_rcu_set(&as->current_map, new_view);
if (old_view) {
flatview_unref(old_view);
}
mr->ops = &unassigned_mem_ops;
mr->enabled = true;
mr->romd_mode = true;
- mr->global_locking = true;
mr->destructor = memory_region_destructor_none;
QTAILQ_INIT(&mr->subregions);
QTAILQ_INIT(&mr->coalesced);
{
if (mr->ops->valid.accepts
&& !mr->ops->valid.accepts(mr->opaque, addr, size, is_write, attrs)) {
+ qemu_log_mask(LOG_GUEST_ERROR, "Invalid access at addr "
+ "0x%" HWADDR_PRIX ", size %u, "
+ "region '%s', reason: rejected\n",
+ addr, size, memory_region_name(mr));
return false;
}
if (!mr->ops->valid.unaligned && (addr & (size - 1))) {
+ qemu_log_mask(LOG_GUEST_ERROR, "Invalid access at addr "
+ "0x%" HWADDR_PRIX ", size %u, "
+ "region '%s', reason: unaligned\n",
+ addr, size, memory_region_name(mr));
return false;
}
if (size > mr->ops->valid.max_access_size
|| size < mr->ops->valid.min_access_size) {
+ qemu_log_mask(LOG_GUEST_ERROR, "Invalid access at addr "
+ "0x%" HWADDR_PRIX ", size %u, "
+ "region '%s', reason: invalid size "
+ "(min:%u max:%u)\n",
+ addr, size, memory_region_name(mr),
+ mr->ops->valid.min_access_size,
+ mr->ops->valid.max_access_size);
return false;
}
return true;
unsigned size = memop_size(op);
MemTxResult r;
+ fuzz_dma_read_cb(addr, size, mr, false);
if (!memory_region_access_valid(mr, addr, size, false, attrs)) {
*pval = unassigned_mem_read(mr, addr, size);
return MEMTX_DECODE_ERROR;
uint8_t memory_region_get_dirty_log_mask(MemoryRegion *mr)
{
uint8_t mask = mr->dirty_log_mask;
- if (global_dirty_log && mr->ram_block) {
+ if (global_dirty_log && (mr->ram_block || memory_region_is_iommu(mr))) {
mask |= (1 << DIRTY_MEMORY_MIGRATION);
}
return mask;
return ret;
}
+int memory_region_iommu_set_page_size_mask(IOMMUMemoryRegion *iommu_mr,
+ uint64_t page_size_mask,
+ Error **errp)
+{
+ IOMMUMemoryRegionClass *imrc = IOMMU_MEMORY_REGION_GET_CLASS(iommu_mr);
+ int ret = 0;
+
+ if (imrc->iommu_set_page_size_mask) {
+ ret = imrc->iommu_set_page_size_mask(iommu_mr, page_size_mask, errp);
+ }
+ return ret;
+}
+
int memory_region_register_iommu_notifier(MemoryRegion *mr,
IOMMUNotifier *n, Error **errp)
{
}
}
-void memory_region_clear_global_locking(MemoryRegion *mr)
-{
- mr->global_locking = false;
-}
-
static bool userspace_eventfd_warning;
void memory_region_add_eventfd(MemoryRegion *mr,
vmstate_register_ram(mr, owner_dev);
}
+/*
+ * Support softmmu builds with CONFIG_FUZZ using a weak symbol and a stub for
+ * the fuzz_dma_read_cb callback
+ */
+#ifdef CONFIG_FUZZ
+void __attribute__((weak)) fuzz_dma_read_cb(size_t addr,
+ size_t len,
+ MemoryRegion *mr,
+ bool is_write)
+{
+}
+#endif
+
static const TypeInfo memory_region_info = {
.parent = TYPE_OBJECT,
.name = TYPE_MEMORY_REGION,