@@ -341,7 +341,7 @@ address_space_translate_internal(AddressSpaceDispatch *d, hwaddr addr, hwaddr *x
static inline bool memory_access_is_direct(MemoryRegion *mr, bool is_write)
{
- if (memory_region_is_ram(mr)) {
+ if (memory_region_is_ram(mr) || mr->alloc_from_ptr) {
return !(is_write && mr->readonly);
}
if (memory_region_is_romd(mr)) {
@@ -149,6 +149,7 @@ struct MemoryRegion {
bool rom_device;
bool warning_printed; /* For reservations */
bool flush_coalesced_mmio;
+ bool alloc_from_ptr;
MemoryRegion *alias;
hwaddr alias_offset;
int priority;
@@ -327,6 +328,21 @@ void memory_region_init_ram_ptr(MemoryRegion *mr,
const char *name,
uint64_t size,
void *ptr);
+/**
+ * memory_region_init_ram_ptr: As before, but for non-RAM memory.
+ *
+ * @mr: the #MemoryRegion to be initialized.
+ * @owner: the object that tracks the region's reference count
+ * @name: the name of the region.
+ * @size: size of the region.
+ * @ptr: memory to be mapped; must contain at least @size bytes.
+ */
+void memory_region_init_ptr(MemoryRegion *mr,
+ struct Object *owner,
+ const char *name,
+ uint64_t size,
+ void *ptr);
+
/**
* memory_region_init_alias: Initialize a memory region that aliases all or a
@@ -1030,6 +1030,20 @@ void memory_region_init_ram_ptr(MemoryRegion *mr,
mr->terminates = true;
mr->destructor = memory_region_destructor_ram_from_ptr;
mr->ram_addr = qemu_ram_alloc_from_ptr(size, ptr, mr);
+ mr->alloc_from_ptr = true;
+}
+
+void memory_region_init_ptr(MemoryRegion *mr,
+ Object *owner,
+ const char *name,
+ uint64_t size,
+ void *ptr)
+{
+ memory_region_init(mr, owner, name, size);
+ mr->terminates = true;
+ mr->destructor = memory_region_destructor_ram_from_ptr;
+ mr->ram_addr = qemu_ram_alloc_from_ptr(size, ptr, mr);
+ mr->alloc_from_ptr = true;
}
void memory_region_init_alias(MemoryRegion *mr,
@@ -203,7 +203,7 @@ static void guest_phys_blocks_region_add(MemoryListener *listener,
GuestPhysBlock *predecessor;
/* we only care about RAM */
- if (!memory_region_is_ram(section->mr)) {
+ if (!memory_region_is_ram(section->mr) && !section->mr->alloc_from_ptr) {
return;
}
The method memory_region_init_ptr() allows the allocation of non-RAM memory from a user-provided pointer. The function is useful in VFIO, where a pointer to the memory regions of the device is provided by the user. A new flag inside MemoryRegion tells if the memory has been allocated through a user pointer, allowing to not call the IOMMU callbacks for these regions, but rather to access the memory directly. Signed-off-by: Alvise Rigo <a.rigo@virtualopensystems.com> --- exec.c | 2 +- include/exec/memory.h | 16 ++++++++++++++++ memory.c | 14 ++++++++++++++ memory_mapping.c | 2 +- 4 files changed, 32 insertions(+), 2 deletions(-)