diff options
author | Richard Henderson | 2022-07-11 05:14:20 +0200 |
---|---|---|
committer | Peter Maydell | 2022-07-18 14:20:13 +0200 |
commit | 7f2cf760fe649972dba0948f8e3fc5618cb1fb37 (patch) | |
tree | 544f7f7d215d392eb88d75ff4a9be9d32507b45d | |
parent | target/arm: Fix aarch64_sve_change_el for SME (diff) | |
download | qemu-7f2cf760fe649972dba0948f8e3fc5618cb1fb37.tar.gz qemu-7f2cf760fe649972dba0948f8e3fc5618cb1fb37.tar.xz qemu-7f2cf760fe649972dba0948f8e3fc5618cb1fb37.zip |
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>
-rw-r--r-- | accel/tcg/translate-all.c | 13 | ||||
-rw-r--r-- | target/arm/cpu.h | 7 |
2 files changed, 16 insertions, 4 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; } } } diff --git a/target/arm/cpu.h b/target/arm/cpu.h index 1e36a839ee..6afcc882f2 100644 --- a/target/arm/cpu.h +++ b/target/arm/cpu.h @@ -3392,9 +3392,12 @@ static inline MemTxAttrs *typecheck_memtxattrs(MemTxAttrs *x) /* * AArch64 usage of the PAGE_TARGET_* bits for linux-user. + * Note that with the Linux kernel, PROT_MTE may not be cleared by mprotect + * mprotect but PROT_BTI may be cleared. C.f. the kernel's VM_ARCH_CLEAR. */ -#define PAGE_BTI PAGE_TARGET_1 -#define PAGE_MTE PAGE_TARGET_2 +#define PAGE_BTI PAGE_TARGET_1 +#define PAGE_MTE PAGE_TARGET_2 +#define PAGE_TARGET_STICKY PAGE_MTE #ifdef TARGET_TAGGED_ADDRESSES /** |