Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Pass tag set/invalidate size to probe_write and on to notdirty_write
Our store_cap_to_memory_mmu_index implementation uses the host pointer it gets back, if it gets one, to write the capability to host memory directly, and so this size needs to be accurate when probing. Otherwise there are two issues: the first is that watchpoints are done based on the size, so a sub-capability watchpoint at a non-zero offset would not be triggered by a capability write to a non-MMIO region, and the second is that the TB caching uses that size to know which TBs to invalidate on write (even on an architecture like AArch64 where D$ and I$ are not architecturally coherent, QEMU ignores IC IVAU in place of just always making the two coherent regardless of architecture), so if we don't give the right size then we won't invalidate all the TBs that overlap the stored-to capability. In particular, a CHERI-aware memcpy used to copy code, as done by the C18N run-time linker in CheriBSD, uses capability loads and stores when suitably aligned, and so can run into stale cached TBs. However, probe_access_inlined also didn't forward the right size on to notdirty_write upstream. This is a bug that affects even the DC ZVA implementation upstream, and this fix (extended to the additional functions added upstream in newer versions) has been sent upstream, but is required for the size we give to probe_write to be correctly honoured, otherwise it would only fix watchpoints but not the TB caching. Also pass on a full capability as the size for cheri_tag_get's probe_read, since that's the only context when it makes sense to get the size. In reality that doesn't matter, because the only caller has already probed for a full capability, and even without that it would only affect watchpoints, which are a bit of a strange thing when it comes to tags.
- Loading branch information