aboutsummaryrefslogtreecommitdiff
path: root/accel/tcg
diff options
context:
space:
mode:
authorRichard Henderson <richard.henderson@linaro.org>2022-07-11 08:44:20 +0530
committerPeter Maydell <peter.maydell@linaro.org>2022-07-18 13:20:13 +0100
commit7f2cf760fe649972dba0948f8e3fc5618cb1fb37 (patch)
tree544f7f7d215d392eb88d75ff4a9be9d32507b45d /accel/tcg
parent6a775fd6e0423e76d3e3cb751b4b468d68f19ca5 (diff)
linux-user/aarch64: Do not clear PROT_MTE on mprotect
The documentation for PROT_MTE says that it cannot be cleared by mprotect. Further, the implementation of the VM_ARCH_CLEAR bit, contains PROT_BTI confiming that bit should be cleared. Introduce PAGE_TARGET_STICKY to allow target/arch/cpu.h to control which bits may be reset during page_set_flags. This is sort of the opposite of VM_ARCH_CLEAR, but works better with qemu's PAGE_* bits that are separate from PROT_* bits. Reported-by: Vitaly Buka <vitalybuka@google.com> Signed-off-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 20220711031420.17820-1-richard.henderson@linaro.org Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'accel/tcg')
-rw-r--r--accel/tcg/translate-all.c13
1 files changed, 11 insertions, 2 deletions
diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c
index 8fd23a9d05..ef62a199c7 100644
--- a/accel/tcg/translate-all.c
+++ b/accel/tcg/translate-all.c
@@ -2256,6 +2256,15 @@ int page_get_flags(target_ulong address)
return p->flags;
}
+/*
+ * Allow the target to decide if PAGE_TARGET_[12] may be reset.
+ * By default, they are not kept.
+ */
+#ifndef PAGE_TARGET_STICKY
+#define PAGE_TARGET_STICKY 0
+#endif
+#define PAGE_STICKY (PAGE_ANON | PAGE_TARGET_STICKY)
+
/* Modify the flags of a page and invalidate the code if necessary.
The flag PAGE_WRITE_ORG is positioned automatically depending
on PAGE_WRITE. The mmap_lock should already be held. */
@@ -2299,8 +2308,8 @@ void page_set_flags(target_ulong start, target_ulong end, int flags)
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;
+ /* Using mprotect on a page does not change sticky bits. */
+ p->flags = (p->flags & PAGE_STICKY) | flags;
}
}
}