Add tests for TLB overlap cases#36
Conversation
| } | ||
|
|
||
| /// Build a TLB hi word for a 4MB page with correct V/G encoding. | ||
| fn make_tlb_hi_vg_4m(vpn_1m: u32, asid: u32, global: bool) -> u32 { |
There was a problem hiding this comment.
I don't know rust, but is there a reason to define this function instead of using make_tlb_hi_vg directly?
There was a problem hiding this comment.
I came to the same conclusion. make_tlb_hi_vg_4m isn't used anywhere and even if it was, it's a wrapper without any additional functionality.
| hi = in(reg) hi, | ||
| lo = in(reg) lo, | ||
| idx = in(reg) idx, | ||
| res = out(reg) result, |
There was a problem hiding this comment.
Maybe match the result variable names? Either res or result for both. Not important, but got me confused for a second.
There was a problem hiding this comment.
For consistency I applied this more generally hexagon-arch-tests: match inline asm operand names to their bindings.
| /// entry. Returns overlapping index, 0x8000_0000 (none), or 0xFFFF_FFFF | ||
| /// (multiple overlaps). Does NOT write. | ||
| #[inline(always)] | ||
| fn tlboc(hi: u32, lo: u32) -> u32 { |
There was a problem hiding this comment.
Are there intrinsics for those helpers?
There was a problem hiding this comment.
No intrinsics for tlboc or ctlbw -- yet.
I lobbied for some new intrinsics recently and the architecture team was on board. So if we want these we could push for 'em.
5ccf7a3 to
f826e7b
Compare
Rename the named asm! template operands (`res`) to match their Rust variable names (`result`, `val`) in iassignr, tlb_probe, and memw_phys_read. This follows the idiom used elsewhere in the Rust ecosystem (e.g. compiler-builtins' arm_linux atomics) where the operand name and the bound variable share a name, avoiding a gratuitous res/result split. Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
Add 11 new tests to test_tlb_mmu.rs covering overlapping TLB entry detection via ctlbw and tlboc instructions: no-overlap, single overlap, multiple overlaps, global-entry semantics, ASID isolation, page-size-aware range checking, invalid-entry exclusion, and incoming G-bit behavior. Introduces make_tlb_hi_vg() helper with correct V/G bit placement in the TLB register pair hi word (existing make_tlb_hi always sets G=1). All 20 tests pass on hexagon-sim, SDK QEMU, and local QEMU build. Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
Add 4 tests that assert multi-TLB-match raises NMI with cause 0x44 (IMPRECISE_CAUSE_MULTI_TLB_MATCH). These pass on hexagon-sim and fail on QEMU, which silently resolves overlaps without raising the imprecise exception. The NMI handler in crt0.S now records cause/count and returns via rte instead of jumping to coredump. Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
The page size of a TLB entry is the position of the lowest set bit of the PPD field, lo[23:0]. tlboc forces the valid bit on for the value it is handed, so probing with an empty PPD reaches the decoder directly. An empty PPD field is not a size architecture defines a result for, so this test pins expected/ desired behavior for an undefined case: treat such an entry as covering one small page at its own VPN rather than the whole address space. The test installs an unrelated mapping elsewhere and requires the probe not to collide with it. A wrongly-inflated page overlaps everything and tlboc reports a multi-hit. The existing invalid-entry coverage does not reach this. tlb_invalidate() writes all zeroes, which is easy to special-case; a kernel parking a bookkeeping word in a spare slot is not. Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
…read test_ctlbw_ignores_invalid_entries clears the slot with tlb_invalidate(), which writes all zeroes -- a shape an implementation can skip with a single check for a zero entry, without ever consulting the valid bit. A kernel that parks a bookkeeping word in a spare TLB slot leaves something quite different behind: non-zero in both words, V=0. Park such a value and require an unrelated ctlbw to succeed. The PPD field is set to encode the largest page size, a perfectly legal encoding, so an implementation that reads the slot's span before testing its validity sees an entry covering the whole address space and rejects the write. That makes the check independent of how out-of-range sizes are handled. Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
Bit 27 of the lo word is HSV39, a flag distinct from the cache-attribute field (CCC). It only takes effect for HSV39 entries, which occupy a separate range of TLB indices starting at 512; entries below that index are always legacy 38-bit entries and must be interpreted as such regardless of what value HSV39 carries. Every existing entry in this suite is built by make_tlb_lo(), which never sets bit 27, so nothing covered the case. Write an entry, at a legacy-range index, that is identical to the ones the other tests use apart from that bit, and require a probe for its address to find it. An implementation that treats bit 27 as an addressing-mode selector for this entry places it at VPN << 20 instead and the probe misses. Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
0fccb5b to
9461b50
Compare
|
Addressed the comments and added more TLB cases. |
No description provided.