diff mbox series

[v4,2/4] linux-user: Set PAGE_TARGET_1 for TARGET_PROT_BTI

Message ID 20190330005900.17282-3-richard.henderson@linaro.org
State New
Headers show
Series target/arm: Implement ARMv8.5-BTI for linux-user | expand

Commit Message

Richard Henderson March 30, 2019, 12:58 a.m. UTC
There is agreement that there will be a mmap/mprotect bit,
although no word yet on the value or the name.   Invent a
name to make forward progress.

The PAGE_TARGET_1 bit, is qemu internal, and allows the
target something to query from the guest page tables.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>

---
 include/exec/cpu-all.h     | 12 +++++++++---
 linux-user/syscall_defs.h  |  5 +++++
 linux-user/mmap.c          | 13 ++++++++++++-
 target/arm/translate-a64.c |  6 +++---
 4 files changed, 29 insertions(+), 7 deletions(-)

-- 
2.17.1

Comments

Peter Maydell April 29, 2019, 4:21 p.m. UTC | #1
On Sat, 30 Mar 2019 at 00:59, Richard Henderson
<richard.henderson@linaro.org> wrote:
>

> There is agreement that there will be a mmap/mprotect bit,

> although no word yet on the value or the name.   Invent a

> name to make forward progress.

>

> The PAGE_TARGET_1 bit, is qemu internal, and allows the

> target something to query from the guest page tables.

>

> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>


This looks ok code-wise, but we'd need to hide it behind
a defaults-to-off x-something property if we wanted to
commit it before the kernel ABI is fixed.

Do we also need to handle this in mprotect() ?

thanks
-- PMM
Richard Henderson April 29, 2019, 8:12 p.m. UTC | #2
On 4/29/19 9:21 AM, Peter Maydell wrote:
> This looks ok code-wise, but we'd need to hide it behind

> a defaults-to-off x-something property if we wanted to

> commit it before the kernel ABI is fixed.


I'm not intending to change the user-level abi, only the
internal abi within qemu, for handling of the elf notes.

You think this should be done differently, so that there's
zero possibility of a user-level setting the relevant bit?

> Do we also need to handle this in mprotect() ?


Not until there's a kernel abi.


r~
Peter Maydell April 30, 2019, 10:40 a.m. UTC | #3
On Mon, 29 Apr 2019 at 21:13, Richard Henderson
<richard.henderson@linaro.org> wrote:
>

> On 4/29/19 9:21 AM, Peter Maydell wrote:

> > This looks ok code-wise, but we'd need to hide it behind

> > a defaults-to-off x-something property if we wanted to

> > commit it before the kernel ABI is fixed.

>

> I'm not intending to change the user-level abi, only the

> internal abi within qemu, for handling of the elf notes.


You're changing target_mmap(), which is used by the
guest mmap syscall, though, right?

> You think this should be done differently, so that there's

> zero possibility of a user-level setting the relevant bit?


I think that we shouldn't allow guest binaries written
to the ad-hoc TARGET_PROT_BTI ABI to work without an
explicit x-something command line argument to QEMU, to
indicate that the user knows they're doing something
odd and that these binaries won't always continue to work
in future QEMU versions.

thanks
-- PMM
Richard Henderson April 30, 2019, 3:25 p.m. UTC | #4
On 4/30/19 3:40 AM, Peter Maydell wrote:
> On Mon, 29 Apr 2019 at 21:13, Richard Henderson

> <richard.henderson@linaro.org> wrote:

>>

>> On 4/29/19 9:21 AM, Peter Maydell wrote:

>>> This looks ok code-wise, but we'd need to hide it behind

>>> a defaults-to-off x-something property if we wanted to

>>> commit it before the kernel ABI is fixed.

>>

>> I'm not intending to change the user-level abi, only the

>> internal abi within qemu, for handling of the elf notes.

> 

> You're changing target_mmap(), which is used by the

> guest mmap syscall, though, right?


Yes, but it's also used by elfload.c to map the executable.

> I think that we shouldn't allow guest binaries written

> to the ad-hoc TARGET_PROT_BTI ABI to work without an

> explicit x-something command line argument to QEMU...


The guest binary is not written to an ad-hoc abi.

It is written to the finalized ELF note abi, which
I am trying to implement with a *private* QEMU abi.


r~
diff mbox series

Patch

diff --git a/include/exec/cpu-all.h b/include/exec/cpu-all.h
index b16c9ec513..fb38467ed1 100644
--- a/include/exec/cpu-all.h
+++ b/include/exec/cpu-all.h
@@ -242,13 +242,19 @@  extern intptr_t qemu_host_page_mask;
 /* original state of the write flag (used when tracking self-modifying
    code */
 #define PAGE_WRITE_ORG 0x0010
-/* Invalidate the TLB entry immediately, helpful for s390x
- * Low-Address-Protection. Used with PAGE_WRITE in tlb_set_page_with_attrs() */
-#define PAGE_WRITE_INV 0x0040
 #if defined(CONFIG_BSD) && defined(CONFIG_USER_ONLY)
 /* FIXME: Code that sets/uses this is broken and needs to go away.  */
 #define PAGE_RESERVED  0x0020
 #endif
+/*
+ * Invalidate the TLB entry immediately, helpful for s390x
+ * Low-Address-Protection. Used with PAGE_WRITE in tlb_set_page_with_attrs()
+ */
+#define PAGE_WRITE_INV 0x0040
+/*
+ * Some 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 12c8407144..563f752081 100644
--- a/linux-user/syscall_defs.h
+++ b/linux-user/syscall_defs.h
@@ -1090,6 +1090,11 @@  struct target_winsize {
 #define TARGET_PROT_SEM         0x08
 #endif
 
+#ifdef TARGET_AARCH64
+/* FIXME: Placeholder while waiting on the official ABI.  */
+#define TARGET_PROT_BTI         0x1000
+#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 e0249efe4f..48b4d9ea02 100644
--- a/linux-user/mmap.c
+++ b/linux-user/mmap.c
@@ -362,6 +362,7 @@  abi_long target_mmap(abi_ulong start, abi_ulong len, int prot,
                      int flags, int fd, abi_ulong offset)
 {
     abi_ulong ret, end, real_start, real_end, retaddr, host_offset, host_len;
+    int page_flags;
 
     mmap_lock();
 #ifdef DEBUG_MMAP
@@ -451,6 +452,16 @@  abi_long target_mmap(abi_ulong start, abi_ulong len, int prot,
        }
     }
 
+    page_flags = (prot & PAGE_BITS) | PAGE_VALID;
+
+#ifdef TARGET_AARCH64
+    /* Remember the BTI bit for page_get_flags, but don't pass to host.  */
+    if (prot & TARGET_PROT_BTI) {
+        page_flags |= PAGE_TARGET_1;
+        prot &= ~TARGET_PROT_BTI;
+    }
+#endif
+
     if (!(flags & MAP_FIXED)) {
         unsigned long host_start;
         void *p;
@@ -562,7 +573,7 @@  abi_long target_mmap(abi_ulong start, abi_ulong len, int prot,
         }
     }
  the_end1:
-    page_set_flags(start, start + len, prot | PAGE_VALID);
+    page_set_flags(start, start + len, page_flags);
  the_end:
 #ifdef DEBUG_MMAP
     printf("ret=0x" TARGET_ABI_FMT_lx "\n", start);
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
index dcdeb80176..5b7bdc3926 100644
--- a/target/arm/translate-a64.c
+++ b/target/arm/translate-a64.c
@@ -14144,10 +14144,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);