diff mbox series

[v3,16/41] accel/tcg: Support split-wx for darwin/iOS with vm_remap

Message ID 20201106032921.600200-17-richard.henderson@linaro.org
State Superseded
Headers show
Series Mirror map JIT memory for TCG | expand

Commit Message

Richard Henderson Nov. 6, 2020, 3:28 a.m. UTC
Cribbed from code posted by Joelle van Dyne <j@getutm.app>,
and rearranged to a cleaner structure.  Completely untested.

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

---
 accel/tcg/translate-all.c | 65 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 65 insertions(+)

-- 
2.25.1

Comments

Joelle van Dyne Nov. 8, 2020, 3:37 a.m. UTC | #1
On Thu, Nov 5, 2020 at 7:29 PM Richard Henderson
<richard.henderson@linaro.org> wrote:
>

> Cribbed from code posted by Joelle van Dyne <j@getutm.app>,

> and rearranged to a cleaner structure.  Completely untested.

>

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


Reviewed-by: Joelle van Dyne <j@getutm.app>
Alex Bennée Nov. 10, 2020, 5:37 p.m. UTC | #2
Richard Henderson <richard.henderson@linaro.org> writes:

> Cribbed from code posted by Joelle van Dyne <j@getutm.app>,

> and rearranged to a cleaner structure.  Completely untested.

>

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

> ---

>  accel/tcg/translate-all.c | 65 +++++++++++++++++++++++++++++++++++++++

>  1 file changed, 65 insertions(+)

>

> diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c

> index 1931e65365..17df6c94fa 100644

> --- a/accel/tcg/translate-all.c

> +++ b/accel/tcg/translate-all.c

> @@ -1166,9 +1166,71 @@ static bool alloc_code_gen_buffer_splitwx_memfd(size_t size, Error **errp)

>  }

>  #endif /* CONFIG_POSIX */

>  

> +#ifdef CONFIG_DARWIN

> +#include <mach/mach.h>

> +

> +extern kern_return_t mach_vm_remap(vm_map_t target_task,

> +                                   mach_vm_address_t *target_address,

> +                                   mach_vm_size_t size,

> +                                   mach_vm_offset_t mask,

> +                                   int flags,

> +                                   vm_map_t src_task,

> +                                   mach_vm_address_t src_address,

> +                                   boolean_t copy,

> +                                   vm_prot_t *cur_protection,

> +                                   vm_prot_t *max_protection,

> +                                   vm_inherit_t inheritance);


Our checkpatch really doesn't like the extern being dropped in here but
having grepped the xnu source I'm not sure we have a choice. I'm curious
how stable the function might be given it's not in a published header.

-- 
Alex Bennée
Joelle van Dyne Nov. 10, 2020, 5:57 p.m. UTC | #3
FWIW, it's a syscall that's been around for as long as I can remember.
In macOS 11 they added a new mach_vm_remap but kept the old one for
compatibility so I don't think it's going away any time soon.

-j

On Tue, Nov 10, 2020 at 9:37 AM Alex Bennée <alex.bennee@linaro.org> wrote:
>

>

> Richard Henderson <richard.henderson@linaro.org> writes:

>

> > Cribbed from code posted by Joelle van Dyne <j@getutm.app>,

> > and rearranged to a cleaner structure.  Completely untested.

> >

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

> > ---

> >  accel/tcg/translate-all.c | 65 +++++++++++++++++++++++++++++++++++++++

> >  1 file changed, 65 insertions(+)

> >

> > diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c

> > index 1931e65365..17df6c94fa 100644

> > --- a/accel/tcg/translate-all.c

> > +++ b/accel/tcg/translate-all.c

> > @@ -1166,9 +1166,71 @@ static bool alloc_code_gen_buffer_splitwx_memfd(size_t size, Error **errp)

> >  }

> >  #endif /* CONFIG_POSIX */

> >

> > +#ifdef CONFIG_DARWIN

> > +#include <mach/mach.h>

> > +

> > +extern kern_return_t mach_vm_remap(vm_map_t target_task,

> > +                                   mach_vm_address_t *target_address,

> > +                                   mach_vm_size_t size,

> > +                                   mach_vm_offset_t mask,

> > +                                   int flags,

> > +                                   vm_map_t src_task,

> > +                                   mach_vm_address_t src_address,

> > +                                   boolean_t copy,

> > +                                   vm_prot_t *cur_protection,

> > +                                   vm_prot_t *max_protection,

> > +                                   vm_inherit_t inheritance);

>

> Our checkpatch really doesn't like the extern being dropped in here but

> having grepped the xnu source I'm not sure we have a choice. I'm curious

> how stable the function might be given it's not in a published header.

>

> --

> Alex Bennée
diff mbox series

Patch

diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c
index 1931e65365..17df6c94fa 100644
--- a/accel/tcg/translate-all.c
+++ b/accel/tcg/translate-all.c
@@ -1166,9 +1166,71 @@  static bool alloc_code_gen_buffer_splitwx_memfd(size_t size, Error **errp)
 }
 #endif /* CONFIG_POSIX */
 
+#ifdef CONFIG_DARWIN
+#include <mach/mach.h>
+
+extern kern_return_t mach_vm_remap(vm_map_t target_task,
+                                   mach_vm_address_t *target_address,
+                                   mach_vm_size_t size,
+                                   mach_vm_offset_t mask,
+                                   int flags,
+                                   vm_map_t src_task,
+                                   mach_vm_address_t src_address,
+                                   boolean_t copy,
+                                   vm_prot_t *cur_protection,
+                                   vm_prot_t *max_protection,
+                                   vm_inherit_t inheritance);
+
+static bool alloc_code_gen_buffer_splitwx_vmremap(size_t size, Error **errp)
+{
+    kern_return_t ret;
+    mach_vm_address_t buf_rw, buf_rx;
+    vm_prot_t cur_prot, max_prot;
+
+    /* Map the read-write portion via normal anon memory. */
+    if (!alloc_code_gen_buffer_anon(size, PROT_READ | PROT_WRITE,
+                                    MAP_PRIVATE | MAP_ANONYMOUS, errp)) {
+        return false;
+    }
+
+    buf_rw = (mach_vm_address_t)tcg_ctx->code_gen_buffer;
+    buf_rx = 0;
+    ret = mach_vm_remap(mach_task_self(),
+                        &buf_rx,
+                        size,
+                        0,
+                        VM_FLAGS_ANYWHERE,
+                        mach_task_self(),
+                        buf_rw,
+                        false,
+                        &cur_prot,
+                        &max_prot,
+                        VM_INHERIT_NONE);
+    if (ret != KERN_SUCCESS) {
+        /* TODO: Convert "ret" to a human readable error message. */
+        error_setg(errp, "vm_remap for jit splitwx failed");
+        munmap((void *)buf_rw, size);
+        return false;
+    }
+
+    if (mprotect((void *)buf_rx, size, PROT_READ | PROT_EXEC) != 0) {
+        error_setg_errno(errp, errno, "mprotect for jit splitwx");
+        munmap((void *)buf_rx, size);
+        munmap((void *)buf_rw, size);
+        return false;
+    }
+
+    tcg_splitwx_diff = buf_rx - buf_rw;
+    return true;
+}
+#endif /* CONFIG_DARWIN */
+
 static bool alloc_code_gen_buffer_splitwx(size_t size, Error **errp)
 {
     if (TCG_TARGET_SUPPORT_MIRROR) {
+#ifdef CONFIG_DARWIN
+        return alloc_code_gen_buffer_splitwx_vmremap(size, errp);
+#endif
 #ifdef CONFIG_POSIX
         return alloc_code_gen_buffer_splitwx_memfd(size, errp);
 #endif
@@ -1201,6 +1263,9 @@  static bool alloc_code_gen_buffer(size_t size, int splitwx, Error **errp)
 #ifdef CONFIG_TCG_INTERPRETER
     /* The tcg interpreter does not need execute permission. */
     prot = PROT_READ | PROT_WRITE;
+#elif defined(CONFIG_DARWIN)
+    /* Applicable to both iOS and macOS (Apple Silicon). */
+    flags |= MAP_JIT;
 #endif
 
     return alloc_code_gen_buffer_anon(size, prot, flags, errp);