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é <[email protected]> --- include/exec/memattrs.h | 3 +++ exec.c | 8 ++++++++ trace-events | 1 + 3 files changed, 12 insertions(+) diff --git a/include/exec/memattrs.h b/include/exec/memattrs.h index 95f2d20d55b..c27cf639a96 100644 --- a/include/exec/memattrs.h +++ b/include/exec/memattrs.h @@ -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 diff --git a/exec.c b/exec.c index 7683afb6a8e..e6185eb04de 100644 --- a/exec.c +++ b/exec.c @@ -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); } diff --git a/trace-events b/trace-events index 42107ebc697..931896735b1 100644 --- a/trace-events +++ b/trace-events @@ -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" -- 2.26.2
