Skip to content

Commit

Permalink
Move the DMA CHERI tag invalidation to invalidate_and_set_dirty().
Browse files Browse the repository at this point in the history
This change moves the CHERI tag invalidation for I/O to the same
place that RAM is invalidated and marked dirty on writes or
invalidate_and_set_dirty().  Not all I/O that writes to memory uses
the previous place (dma_memory_rw) and this is more general.
  • Loading branch information
staceyson committed Jul 13, 2016
1 parent 7ab6047 commit ab5220b
Show file tree
Hide file tree
Showing 4 changed files with 19 additions and 24 deletions.
6 changes: 6 additions & 0 deletions exec.c
Original file line number Diff line number Diff line change
Expand Up @@ -2344,6 +2344,9 @@ int cpu_memory_rw_debug(CPUState *cpu, target_ulong addr,

#else

/* XXX CHERI tag memory emulation needs to be moved to memory.c */
void cheri_tag_phys_invalidate(hwaddr paddr, hwaddr len);

static void invalidate_and_set_dirty(MemoryRegion *mr, hwaddr addr,
hwaddr length)
{
Expand All @@ -2361,6 +2364,9 @@ static void invalidate_and_set_dirty(MemoryRegion *mr, hwaddr addr,
dirty_log_mask &= ~(1 << DIRTY_MEMORY_CODE);
}
cpu_physical_memory_set_dirty_range(addr, length, dirty_log_mask);

/* Invalidate the CHERI memory tags. */
cheri_tag_phys_invalidate(addr, length);
}

static int memory_access_size(MemoryRegion *mr, unsigned l, hwaddr addr)
Expand Down
18 changes: 2 additions & 16 deletions include/sysemu/dma.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,26 +84,12 @@ static inline bool dma_memory_valid(AddressSpace *as,
dir == DMA_DIRECTION_FROM_DEVICE);
}

/* XXX CHERI tag memory emulation needs to be moved to memory.c */
void cheri_tag_dma_invalidate(uint64_t paddr, uint64_t len);

static inline int dma_memory_rw_relaxed(AddressSpace *as, dma_addr_t addr,
void *buf, dma_addr_t len,
DMADirection dir)
{
MemTxResult ret;

ret = address_space_rw(as, addr, MEMTXATTRS_UNSPECIFIED,
buf, len, dir == DMA_DIRECTION_FROM_DEVICE);

/*
* If successful and was a write to memory then invalidate
* the CHERI memory tag(s).
*/
if (ret == MEMTX_OK && dir == DMA_DIRECTION_FROM_DEVICE)
cheri_tag_dma_invalidate(addr, len);

return (bool)ret;
return (bool)address_space_rw(as, addr, MEMTXATTRS_UNSPECIFIED,
buf, len, dir == DMA_DIRECTION_FROM_DEVICE);
}

static inline int dma_memory_read_relaxed(AddressSpace *as, dma_addr_t addr,
Expand Down
2 changes: 1 addition & 1 deletion target-mips/cpu.h
Original file line number Diff line number Diff line change
Expand Up @@ -1272,7 +1272,7 @@ static inline void cpu_mips_store_cause(CPUMIPSState *env, target_ulong val)

void cheri_tag_init(uint64_t memory_size);
void cheri_tag_invalidate(CPUMIPSState *env, target_ulong vaddr, int32_t size);
void cheri_tag_dma_invalidate(uint64_t paddr, uint64_t len);
void cheri_tag_phys_invalidate(hwaddr paddr, hwaddr len);
int cheri_tag_get(CPUMIPSState *env, target_ulong vaddr, int reg,
hwaddr *ret_paddr);
void cheri_tag_set(CPUMIPSState *env, target_ulong vaddr, int reg);
Expand Down
17 changes: 10 additions & 7 deletions target-mips/helper.c
Original file line number Diff line number Diff line change
Expand Up @@ -995,7 +995,7 @@ void r4k_invalidate_tlb (CPUMIPSState *env, int idx, int use_extra)
#endif /* ! CHERI_MAGIC128 */

uint8_t **cheri_tagmem = NULL;
uint64_t cheri_ntagblks = 0;
uint64_t cheri_ntagblks = 0ul;

void cheri_tag_init(uint64_t memory_size)
{
Expand Down Expand Up @@ -1060,16 +1060,19 @@ void cheri_tag_invalidate(CPUMIPSState *env, target_ulong vaddr, int32_t size)
return;
}

void cheri_tag_dma_invalidate(uint64_t paddr, uint64_t len)
void cheri_tag_phys_invalidate(hwaddr paddr, hwaddr len)
{
uint64_t tag, addr, endaddr;
uint64_t tag, addr, endaddr, tagmem_idx;
uint8_t *tagblk;

endaddr = paddr + len;
endaddr = (uint64_t)(paddr + len);

for(addr = paddr; addr < endaddr; addr += CAP_SIZE) {
for(addr = (uint64_t)paddr; addr < endaddr; addr += CAP_SIZE) {
tag = addr >> CAP_TAG_SHFT;
tagblk = cheri_tagmem[tag >> CAP_TAGBLK_SHFT];
tagmem_idx = tag >> CAP_TAGBLK_SHFT;
if (tagmem_idx > cheri_ntagblks)
return;
tagblk = cheri_tagmem[tagmem_idx];

if (tagblk != NULL)
tagblk[CAP_TAGBLK_IDX(tag)] = 0;
Expand Down Expand Up @@ -1198,6 +1201,6 @@ int cheri_tag_get_m128(CPUMIPSState *env, target_ulong vaddr, int reg,

#else /* ! TARGET_CHERI */

void cheri_tag_dma_invalidate(uint64_t paddr, uint64_t len) { }
void cheri_tag_phys_invalidate(hwaddr paddr, hwaddr len) { }

#endif /* ! TARGET_CHERI */

0 comments on commit ab5220b

Please sign in to comment.