aboutsummaryrefslogtreecommitdiff
path: root/accel/tcg/cpu-exec.c
diff options
context:
space:
mode:
authorRichard Henderson <richard.henderson@linaro.org>2022-08-22 18:50:46 -0700
committerRichard Henderson <richard.henderson@linaro.org>2022-09-06 08:04:26 +0100
commit9867b30287ec98728e52ed49d03c666e86c90a04 (patch)
tree1ea34b38d5acc4e52d1d4e4c42714566cb97efd3 /accel/tcg/cpu-exec.c
parent7e0d9973ea665bf459b2dbd173d0e51bc6ca5216 (diff)
accel/tcg: Document the faulting lookup in tb_lookup_cmp
It was non-obvious to me why we can raise an exception in the middle of a comparison function, but it works. While nearby, use TARGET_PAGE_ALIGN instead of open-coding. Acked-by: Ilya Leoshkevich <iii@linux.ibm.com> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Diffstat (limited to 'accel/tcg/cpu-exec.c')
-rw-r--r--accel/tcg/cpu-exec.c11
1 files changed, 10 insertions, 1 deletions
diff --git a/accel/tcg/cpu-exec.c b/accel/tcg/cpu-exec.c
index 7887af6f45..5f43b9769a 100644
--- a/accel/tcg/cpu-exec.c
+++ b/accel/tcg/cpu-exec.c
@@ -198,7 +198,16 @@ static bool tb_lookup_cmp(const void *p, const void *d)
tb_page_addr_t phys_page2;
target_ulong virt_page2;
- virt_page2 = (desc->pc & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
+ /*
+ * We know that the first page matched, and an otherwise valid TB
+ * encountered an incomplete instruction at the end of that page,
+ * therefore we know that generating a new TB from the current PC
+ * must also require reading from the next page -- even if the
+ * second pages do not match, and therefore the resulting insn
+ * is different for the new TB. Therefore any exception raised
+ * here by the faulting lookup is not premature.
+ */
+ virt_page2 = TARGET_PAGE_ALIGN(desc->pc);
phys_page2 = get_page_addr_code(desc->env, virt_page2);
if (tb->page_addr[1] == phys_page2) {
return true;