I was wondering about what the best way is to implement emulation in TCG of the AArch64 tagged-addresses feature. (cc'd Tom Hanson who's looking at actually writing code for this, and RTH for review of the design sketch below.)
Quick summary of the feature (which is described in the v8 ARM ARM section D4.1.1 "Address tagging in AArch64 state"): If the 'tagged addresses' bit in TCR_EL1 is set then: * the top 8 bits of virtual addresses are ignored for doing va-to-pa translation (addresses are sign extended from bit 55) * the top 8 bits are ignored for purposes of TLB-invalidate-by-address * various operations that set the PC (branches, exception returns, etc) sign-extend the new PC value from bit 55 * for a data abort or watchpoint hit, the virtual address reported in the FAR (fault address register) includes the tag bits (Complication, for EL0/EL1 there are two 'enable tags' bits in TCR_EL1, and which one you use depends on bit 55 of the VA, so you can (say) enable tags for the "lower" half of the virtual address space, and disable them for the "higher" half.) I thought of two possible ways to approach implementing this. Option (1) would be to change the codegen in translate-a64.c so that we mask out high bits before doing the QEMU load/store TCG op. Option (2) leaves the VA that we pass to the TCG load/store alone (ie with tag bits intact) and tries to handle this all in the va-to-pa code. I think option (1) is a non-starter because of that requirement to report the full address with tags in the FAR (as well as being slower due to all the extra masking on memory operations). So that leaves option (2), possibly with some help from common code to make things a bit less awkward. In particular I think if you just do the relevant handling of the tag bits in target-arm's get_phys_addr() and its subroutines then this should work ok, with the exceptions that: * the QEMU TLB code will think that [tag A + address X] and [tag B + address X] are different virtual addresses and they will miss each other in the TLB * tlb invalidate by address becomes nasty because we need to invalidate [every tag + address X] Can we fix those just by having arm_tlb_fill() call tlb_set_page_with_attrs() with the vaddr with the tag masked out? Have I missed some complication that would make this not work? [NB: this is all assuming softmmu; getting tagged addresses to work in linux-user mode would require doing the masking in translate.c, but I definitely don't want two implementations so I guess we just ignore linux-user here.] thanks -- PMM