Transform the prot bit to a qemu internal page bit, and save it in the page tables.
Signed-off-by: Richard Henderson <richard.hender...@linaro.org> --- include/exec/cpu-all.h | 2 ++ linux-user/syscall_defs.h | 4 ++++ linux-user/mmap.c | 16 ++++++++++++++++ target/arm/translate-a64.c | 6 +++--- 4 files changed, 25 insertions(+), 3 deletions(-) diff --git a/include/exec/cpu-all.h b/include/exec/cpu-all.h index 40b140cbba..27470b73f7 100644 --- a/include/exec/cpu-all.h +++ b/include/exec/cpu-all.h @@ -248,6 +248,8 @@ extern intptr_t qemu_host_page_mask; /* FIXME: Code that sets/uses this is broken and needs to go away. */ #define PAGE_RESERVED 0x0020 #endif +/* Target-specific bits that will be used via page_get_flags(). */ +#define PAGE_TARGET_1 0x0080 #if defined(CONFIG_USER_ONLY) void page_dump(FILE *f); diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h index 0662270300..a59a81e4b6 100644 --- a/linux-user/syscall_defs.h +++ b/linux-user/syscall_defs.h @@ -1124,6 +1124,10 @@ struct target_winsize { #define TARGET_PROT_SEM 0x08 #endif +#ifdef TARGET_AARCH64 +#define TARGET_PROT_BTI 0x10 +#endif + /* Common */ #define TARGET_MAP_SHARED 0x01 /* Share changes */ #define TARGET_MAP_PRIVATE 0x02 /* Changes are private */ diff --git a/linux-user/mmap.c b/linux-user/mmap.c index c1a188ec0b..c1bed290f6 100644 --- a/linux-user/mmap.c +++ b/linux-user/mmap.c @@ -83,6 +83,22 @@ static int validate_prot_to_pageflags(int *host_prot, int prot) */ *host_prot = prot & (PROT_READ | PROT_WRITE | PROT_EXEC); +#ifdef TARGET_AARCH64 + /* + * The PROT_BTI bit is only accepted if the cpu supports the feature. + * Since this is the unusual case, don't bother checking unless + * the bit has been requested. If set and valid, record the bit + * within QEMU's page_flags as PAGE_TARGET_1. + */ + if (prot & TARGET_PROT_BTI) { + ARMCPU *cpu = ARM_CPU(thread_cpu); + if (cpu_isar_feature(aa64_bti, cpu)) { + valid |= TARGET_PROT_BTI; + page_flags |= PAGE_TARGET_1; + } + } +#endif + return prot & ~valid ? 0 : page_flags; } diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c index 06ff3a7f2e..395e498acf 100644 --- a/target/arm/translate-a64.c +++ b/target/arm/translate-a64.c @@ -13963,10 +13963,10 @@ static void disas_data_proc_simd_fp(DisasContext *s, uint32_t insn) */ static bool is_guarded_page(CPUARMState *env, DisasContext *s) { -#ifdef CONFIG_USER_ONLY - return false; /* FIXME */ -#else uint64_t addr = s->base.pc_first; +#ifdef CONFIG_USER_ONLY + return page_get_flags(addr) & PAGE_TARGET_1; +#else int mmu_idx = arm_to_core_mmu_idx(s->mmu_idx); unsigned int index = tlb_index(env, mmu_idx, addr); CPUTLBEntry *entry = tlb_entry(env, mmu_idx, addr); -- 2.17.1