@@ -35,6 +35,8 @@ typedef struct MemTxAttrs {
unsigned int secure:1;
/* Memory access is usermode (unprivileged) */
unsigned int user:1;
+ /* Bus master restricted to ROM/RAM slaves */
+ unsigned int direct_access:1;
/* Requester ID (for MSI for example) */
unsigned int requester_id:16;
/* Invert endianness for this page */
@@ -66,6 +68,7 @@ typedef struct MemTxAttrs {
#define MEMTX_OK 0
#define MEMTX_ERROR (1U << 0) /* device returned an error */
#define MEMTX_DECODE_ERROR (1U << 1) /* nothing at that address */
+#define MEMTX_BUS_ERROR (1U << 2) /* bus returned an error */
typedef uint32_t MemTxResult;
#endif
@@ -3213,6 +3213,10 @@ static MemTxResult flatview_write(FlatView *fv, hwaddr addr, MemTxAttrs attrs,
l = len;
mr = flatview_translate(fv, addr, &addr1, &l, true, attrs);
+ if (attrs.direct_access && !memory_access_is_direct(mr, true)) {
+ trace_memory_access_illegal(true, addr, len, mr->name);
+ return MEMTX_BUS_ERROR;
+ }
result = flatview_write_continue(fv, addr, attrs, buf, len,
addr1, l, mr);
@@ -3275,6 +3279,10 @@ static MemTxResult flatview_read(FlatView *fv, hwaddr addr,
l = len;
mr = flatview_translate(fv, addr, &addr1, &l, false, attrs);
+ if (attrs.direct_access && !memory_access_is_direct(mr, false)) {
+ trace_memory_access_illegal(false, addr, len, mr->name);
+ return MEMTX_BUS_ERROR;
+ }
return flatview_read_continue(fv, addr, attrs, buf, len,
addr1, l, mr);
}
@@ -54,6 +54,7 @@ find_ram_offset_loop(uint64_t size, uint64_t candidate, uint64_t offset, uint64_
ram_block_discard_range(const char *rbname, void *hva, size_t length, bool need_madvise, bool need_fallocate, int ret) "%s@%p + 0x%zx: madvise: %d fallocate: %d ret: %d"
memory_notdirty_write_access(uint64_t vaddr, uint64_t ram_addr, unsigned size) "0x%" PRIx64 " ram_addr 0x%" PRIx64 " size %u"
memory_notdirty_set_dirty(uint64_t vaddr) "0x%" PRIx64
+memory_access_illegal(bool is_write, uint64_t addr, uint64_t len, const char *mr_name) "is_write:%u addr:0x%08" PRIx64 " size:0x%04" PRIx64 " region:'%s'"
# memory.c
memory_region_ops_read(int cpu_index, void *mr, uint64_t addr, uint64_t value, unsigned size) "cpu %d mr %p addr 0x%"PRIx64" value 0x%"PRIx64" size %u"
Add the 'direct_access' bit to the memory attributes to restrict bus master access to ROM/RAM. Have read/write accessors return MEMTX_BUS_ERROR if an access is restricted and the region is not ROM/RAM ('direct'). Add corresponding trace events. Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com> --- include/exec/memattrs.h | 3 +++ exec.c | 8 ++++++++ trace-events | 1 + 3 files changed, 12 insertions(+)