summaryrefslogtreecommitdiffstats
path: root/include/exec
diff options
context:
space:
mode:
authorPeter Maydell2015-12-17 19:07:09 +0100
committerPeter Maydell2015-12-17 19:07:09 +0100
commit6a6533213d78dea4407fe6933ad489796b582599 (patch)
tree1e37b82b21a52c000d5d6de0494c168bd69d4307 /include/exec
parentMerge remote-tracking branch 'remotes/pmaydell/tags/pull-target-arm-20151217-... (diff)
parentcoverity: Model g_memdup() (diff)
downloadqemu-6a6533213d78dea4407fe6933ad489796b582599.tar.gz
qemu-6a6533213d78dea4407fe6933ad489796b582599.tar.xz
qemu-6a6533213d78dea4407fe6933ad489796b582599.zip
Merge remote-tracking branch 'remotes/bonzini/tags/for-upstream' into staging
* KVM: synic support, split irqchip support * memory: cleanups, optimizations, ioeventfd emulation * SCSI: small fixes, vmw_pvscsi compatibility improvements * qemu_log cleanups * Coverity model improvements # gpg: Signature made Thu 17 Dec 2015 16:35:21 GMT using RSA key ID 78C7AE83 # gpg: Good signature from "Paolo Bonzini <bonzini@gnu.org>" # gpg: aka "Paolo Bonzini <pbonzini@redhat.com>" * remotes/bonzini/tags/for-upstream: (45 commits) coverity: Model g_memdup() coverity: Model g_poll() scsi: always call notifier on async cancellation scsi: use scsi_req_cancel_async when purging requests target-i386: kvm: clear unusable segments' flags in migration rcu: optimize rcu_read_lock memory: try to inline constant-length reads memory: inline a few small accessors memory: extract first iteration of address_space_read and address_space_write memory: split address_space_read and address_space_write memory: avoid unnecessary object_ref/unref memory: reorder MemoryRegion fields exec: make qemu_ram_ptr_length more similar to qemu_get_ram_ptr exec: always call qemu_get_ram_ptr within rcu_read_lock linux-user: convert DEBUG_SIGNAL logging to tracepoints linux-user: avoid "naked" qemu_log user: introduce "-d page" xtensa: avoid "naked" qemu_log tricore: avoid "naked" qemu_log ppc: cleanup logging ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'include/exec')
-rw-r--r--include/exec/memory.h136
-rw-r--r--include/exec/ram_addr.h2
2 files changed, 103 insertions, 35 deletions
diff --git a/include/exec/memory.h b/include/exec/memory.h
index 0f07159bb4..01f10049c1 100644
--- a/include/exec/memory.h
+++ b/include/exec/memory.h
@@ -159,27 +159,33 @@ typedef struct MemoryRegionIoeventfd MemoryRegionIoeventfd;
struct MemoryRegion {
Object parent_obj;
+
/* All fields are private - violators will be prosecuted */
- const MemoryRegionOps *ops;
+
+ /* The following fields should fit in a cache line */
+ bool romd_mode;
+ bool ram;
+ bool subpage;
+ bool readonly; /* For RAM regions */
+ bool rom_device;
+ bool flush_coalesced_mmio;
+ bool global_locking;
+ uint8_t dirty_log_mask;
+ ram_addr_t ram_addr;
+ Object *owner;
const MemoryRegionIOMMUOps *iommu_ops;
+
+ const MemoryRegionOps *ops;
void *opaque;
MemoryRegion *container;
Int128 size;
hwaddr addr;
void (*destructor)(MemoryRegion *mr);
- ram_addr_t ram_addr;
uint64_t align;
- bool subpage;
bool terminates;
- bool romd_mode;
- bool ram;
bool skip_dump;
- bool readonly; /* For RAM regions */
bool enabled;
- bool rom_device;
bool warning_printed; /* For reservations */
- bool flush_coalesced_mmio;
- bool global_locking;
uint8_t vga_logging_count;
MemoryRegion *alias;
hwaddr alias_offset;
@@ -189,7 +195,6 @@ struct MemoryRegion {
QTAILQ_ENTRY(MemoryRegion) subregions_link;
QTAILQ_HEAD(coalesced_ranges, CoalescedMemoryRange) coalesced;
const char *name;
- uint8_t dirty_log_mask;
unsigned ioeventfd_nb;
MemoryRegionIoeventfd *ioeventfds;
NotifierList iommu_notify;
@@ -518,7 +523,10 @@ uint64_t memory_region_size(MemoryRegion *mr);
*
* @mr: the memory region being queried
*/
-bool memory_region_is_ram(MemoryRegion *mr);
+static inline bool memory_region_is_ram(MemoryRegion *mr)
+{
+ return mr->ram;
+}
/**
* memory_region_is_skip_dump: check whether a memory region should not be
@@ -558,7 +566,11 @@ static inline bool memory_region_is_romd(MemoryRegion *mr)
*
* @mr: the memory region being queried
*/
-bool memory_region_is_iommu(MemoryRegion *mr);
+static inline bool memory_region_is_iommu(MemoryRegion *mr)
+{
+ return mr->iommu_ops;
+}
+
/**
* memory_region_notify_iommu: notify a change in an IOMMU translation entry.
@@ -640,7 +652,11 @@ uint8_t memory_region_get_dirty_log_mask(MemoryRegion *mr);
*
* @mr: the memory region being queried
*/
-bool memory_region_is_rom(MemoryRegion *mr);
+static inline bool memory_region_is_rom(MemoryRegion *mr)
+{
+ return mr->ram && mr->readonly;
+}
+
/**
* memory_region_get_fd: Get a file descriptor backing a RAM memory region.
@@ -656,8 +672,13 @@ int memory_region_get_fd(MemoryRegion *mr);
* memory_region_get_ram_ptr: Get a pointer into a RAM memory region.
*
* Returns a host pointer to a RAM memory region (created with
- * memory_region_init_ram() or memory_region_init_ram_ptr()). Use with
- * care.
+ * memory_region_init_ram() or memory_region_init_ram_ptr()).
+ *
+ * Use with care; by the time this function returns, the returned pointer is
+ * not protected by RCU anymore. If the caller is not within an RCU critical
+ * section and does not hold the iothread lock, it must have other means of
+ * protecting the pointer, such as a reference to the region that includes
+ * the incoming ram_addr_t.
*
* @mr: the memory region being queried.
*/
@@ -960,7 +981,10 @@ void memory_region_add_subregion_overlap(MemoryRegion *mr,
* DO NOT USE THIS FUNCTION. This is a temporary workaround while the Xen
* code is being reworked.
*/
-ram_addr_t memory_region_get_ram_addr(MemoryRegion *mr);
+static inline ram_addr_t memory_region_get_ram_addr(MemoryRegion *mr)
+{
+ return mr->ram_addr;
+}
uint64_t memory_region_get_alignment(const MemoryRegion *mr);
/**
@@ -1210,23 +1234,7 @@ MemTxResult address_space_write(AddressSpace *as, hwaddr addr,
MemTxAttrs attrs,
const uint8_t *buf, int len);
-/**
- * address_space_read: read from an address space.
- *
- * Return a MemTxResult indicating whether the operation succeeded
- * or failed (eg unassigned memory, device rejected the transaction,
- * IOMMU fault).
- *
- * @as: #AddressSpace to be accessed
- * @addr: address within that address space
- * @attrs: memory transaction attributes
- * @buf: buffer with the data transferred
- */
-MemTxResult address_space_read(AddressSpace *as, hwaddr addr, MemTxAttrs attrs,
- uint8_t *buf, int len);
-
-/**
- * address_space_ld*: load from an address space
+/* address_space_ld*: load from an address space
* address_space_st*: store to an address space
*
* These functions perform a load or store of the byte, word,
@@ -1356,6 +1364,68 @@ void address_space_unmap(AddressSpace *as, void *buffer, hwaddr len,
int is_write, hwaddr access_len);
+/* Internal functions, part of the implementation of address_space_read. */
+MemTxResult address_space_read_continue(AddressSpace *as, hwaddr addr,
+ MemTxAttrs attrs, uint8_t *buf,
+ int len, hwaddr addr1, hwaddr l,
+ MemoryRegion *mr);
+MemTxResult address_space_read_full(AddressSpace *as, hwaddr addr,
+ MemTxAttrs attrs, uint8_t *buf, int len);
+void *qemu_get_ram_ptr(ram_addr_t addr);
+
+static inline bool memory_access_is_direct(MemoryRegion *mr, bool is_write)
+{
+ if (is_write) {
+ return memory_region_is_ram(mr) && !mr->readonly;
+ } else {
+ return memory_region_is_ram(mr) || memory_region_is_romd(mr);
+ }
+
+ return false;
+}
+
+/**
+ * address_space_read: read from an address space.
+ *
+ * Return a MemTxResult indicating whether the operation succeeded
+ * or failed (eg unassigned memory, device rejected the transaction,
+ * IOMMU fault).
+ *
+ * @as: #AddressSpace to be accessed
+ * @addr: address within that address space
+ * @attrs: memory transaction attributes
+ * @buf: buffer with the data transferred
+ */
+static inline __attribute__((__always_inline__))
+MemTxResult address_space_read(AddressSpace *as, hwaddr addr, MemTxAttrs attrs,
+ uint8_t *buf, int len)
+{
+ MemTxResult result = MEMTX_OK;
+ hwaddr l, addr1;
+ void *ptr;
+ MemoryRegion *mr;
+
+ if (__builtin_constant_p(len)) {
+ if (len) {
+ rcu_read_lock();
+ l = len;
+ mr = address_space_translate(as, addr, &addr1, &l, false);
+ if (len == l && memory_access_is_direct(mr, false)) {
+ addr1 += memory_region_get_ram_addr(mr);
+ ptr = qemu_get_ram_ptr(addr1);
+ memcpy(buf, ptr, len);
+ } else {
+ result = address_space_read_continue(as, addr, attrs, buf, len,
+ addr1, l, mr);
+ }
+ rcu_read_unlock();
+ }
+ } else {
+ result = address_space_read_full(as, addr, attrs, buf, len);
+ }
+ return result;
+}
+
#endif
#endif
diff --git a/include/exec/ram_addr.h b/include/exec/ram_addr.h
index 7115154bc1..ba4c04d202 100644
--- a/include/exec/ram_addr.h
+++ b/include/exec/ram_addr.h
@@ -73,9 +73,7 @@ ram_addr_t qemu_ram_alloc_resizeable(ram_addr_t size, ram_addr_t max_size,
MemoryRegion *mr, Error **errp);
int qemu_get_ram_fd(ram_addr_t addr);
void *qemu_get_ram_block_host_ptr(ram_addr_t addr);
-void *qemu_get_ram_ptr(ram_addr_t addr);
void qemu_ram_free(ram_addr_t addr);
-void qemu_ram_free_from_ptr(ram_addr_t addr);
int qemu_ram_resize(ram_addr_t base, ram_addr_t newsize, Error **errp);