accel/tcg: Preserve PAGE_ANON when changing page permissions

Using mprotect() to change PROT_* does not change the MAP_ANON
previously set with mmap().  Our linux-user version of MTE only
works with MAP_ANON pages, so losing PAGE_ANON caused MTE to
stop working.

Reported-by: Stephen Long <steplong@quicinc.com>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Tested-by: Alex Bennée <alex.bennee@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Richard Henderson 2021-04-06 10:40:20 -07:00 committed by Peter Maydell
parent 017a913af4
commit eb42297a59
4 changed files with 53 additions and 4 deletions

View file

@ -2714,6 +2714,8 @@ void page_set_flags(target_ulong start, target_ulong end, int flags)
a missing call to h2g_valid. */
assert(end - 1 <= GUEST_ADDR_MAX);
assert(start < end);
/* Only set PAGE_ANON with new mappings. */
assert(!(flags & PAGE_ANON) || (flags & PAGE_RESET));
assert_memory_lock();
start = start & TARGET_PAGE_MASK;
@ -2737,11 +2739,14 @@ void page_set_flags(target_ulong start, target_ulong end, int flags)
p->first_tb) {
tb_invalidate_phys_page(addr, 0);
}
if (reset_target_data && p->target_data) {
if (reset_target_data) {
g_free(p->target_data);
p->target_data = NULL;
p->flags = flags;
} else {
/* Using mprotect on a page does not change MAP_ANON. */
p->flags = (p->flags & PAGE_ANON) | flags;
}
p->flags = flags;
}
}