All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v4 0/7] iOS and Apple Silicon host support
@ 2020-11-08  5:25 Joelle van Dyne
  2020-11-08  5:25 ` [PATCH v4 1/7] configure: option to disable host block devices Joelle van Dyne
                   ` (6 more replies)
  0 siblings, 7 replies; 11+ messages in thread
From: Joelle van Dyne @ 2020-11-08  5:25 UTC (permalink / raw)
  To: qemu-devel; +Cc: Joelle van Dyne

Based-on: 20201106032921.600200-1-richard.henderson@linaro.org
([PATCH v3 00/41] Mirror map JIT memory for TCG)

These set of changes brings QEMU TCG to iOS devices and future Apple Silicon
devices. They were originally developed last year and have been working in the
UTM app. Recently, we ported the changes to master, re-wrote a lot of the build
script changes for meson, and broke up the patches into more distinct units.

A summary of the changes:

* `CONFIG_IOS` defined when building for iOS and iOS specific changes (as well
  as unsupported code) are gated behind it.
* A new dependency, libucontext is added since iOS does not have native ucontext
  and broken support for sigaltstack. libucontext is available as a new option
  for coroutine backend.
* For (recent) jailbroken iOS devices as well as upcoming Apple Silicon devices,
  there are new rules for applications supporting JIT (with the proper
  entitlement). These rules are implemented as well.

Since v4:

* Updated QAPI schema for CONFIG_HOST_BLOCK_DEVICE
* Updated maintainers file for iOS host support
* Moved system() changes to osdep.h
* Fixed typo in libucontext meson.build change

Since v3:

* Moved mirror JIT support to a different patch set.
* Removed dependency on `pthread_jit_write_protect_np` because it was redundent
  and also crashes if called on a non-jailbroken iOS device.
* Removed `--enable-cross-compile` option
* Fixed checkpatch errors
* Fixed iOS build on master due to new test recently added which calls system()

Since v2:

* Changed getting mirror pointer from a macro to inline functions
* Split constification of TCG code pointers to separate patch
* Removed slirp updates (will send future patch once slirp changes are in)
* Removed shared library patch (will send future patch)

-j

Joelle van Dyne (7):
  configure: option to disable host block devices
  configure: cross-compiling with empty cross_prefix
  qemu: add support for iOS host
  coroutine: add libucontext as external library
  slirp: update build flags for iOS resolv fix
  tcg: implement JIT for iOS and Apple Silicon
  block: check availablity for preadv/pwritev on mac

 docs/devel/index.rst        |  1 +
 docs/devel/ios.rst          | 28 ++++++++++++
 configure                   | 76 +++++++++++++++++++++++++++++---
 meson.build                 | 33 +++++++++++++-
 qapi/block-core.json        |  4 +-
 include/exec/exec-all.h     |  2 +
 include/qemu/osdep.h        | 11 +++++
 include/tcg/tcg-apple-jit.h | 86 +++++++++++++++++++++++++++++++++++++
 include/tcg/tcg.h           |  3 ++
 accel/tcg/cpu-exec-common.c |  2 +
 accel/tcg/cpu-exec.c        |  2 +
 accel/tcg/translate-all.c   | 46 ++++++++++++++++++++
 block.c                     |  2 +-
 block/file-posix.c          | 51 ++++++++++++++++------
 net/slirp.c                 | 16 +++----
 qga/commands-posix.c        |  6 +++
 tcg/tcg.c                   |  4 ++
 util/coroutine-ucontext.c   |  9 ++++
 .gitmodules                 |  3 ++
 MAINTAINERS                 |  7 +++
 libucontext                 |  1 +
 meson_options.txt           |  2 +
 tests/qtest/meson.build     |  7 ++-
 23 files changed, 367 insertions(+), 35 deletions(-)
 create mode 100644 docs/devel/ios.rst
 create mode 100644 include/tcg/tcg-apple-jit.h
 create mode 160000 libucontext

-- 
2.28.0



^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH v4 1/7] configure: option to disable host block devices
  2020-11-08  5:25 [PATCH v4 0/7] iOS and Apple Silicon host support Joelle van Dyne
@ 2020-11-08  5:25 ` Joelle van Dyne
  2020-11-08  5:26 ` [PATCH v4 2/7] configure: cross-compiling with empty cross_prefix Joelle van Dyne
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 11+ messages in thread
From: Joelle van Dyne @ 2020-11-08  5:25 UTC (permalink / raw)
  To: qemu-devel
  Cc: Kevin Wolf, open list:raw, Markus Armbruster, Max Reitz, Joelle van Dyne

Some hosts (iOS) have a sandboxed filesystem and do not provide low-level
APIs for interfacing with host block devices.

Signed-off-by: Joelle van Dyne <j@getutm.app>
---
 configure            | 4 ++++
 meson.build          | 1 +
 qapi/block-core.json | 4 +++-
 block/file-posix.c   | 8 +++++++-
 4 files changed, 15 insertions(+), 2 deletions(-)

diff --git a/configure b/configure
index 2c3c69f118..97a879808d 100755
--- a/configure
+++ b/configure
@@ -448,6 +448,7 @@ meson=""
 ninja=""
 skip_meson=no
 gettext=""
+host_block_device_support="yes"
 
 bogus_os="no"
 malloc_trim="auto"
@@ -5907,6 +5908,9 @@ if test "$default_devices" = "yes" ; then
 else
   echo "CONFIG_MINIKCONF_MODE=--allnoconfig" >> $config_host_mak
 fi
+if test "$host_block_device_support" = "yes" ; then
+  echo "CONFIG_HOST_BLOCK_DEVICE=y" >> $config_host_mak
+fi
 if test "$debug_tcg" = "yes" ; then
   echo "CONFIG_DEBUG_TCG=y" >> $config_host_mak
 fi
diff --git a/meson.build b/meson.build
index 39ac5cf6d8..fd822346e7 100644
--- a/meson.build
+++ b/meson.build
@@ -2166,6 +2166,7 @@ summary_info += {'vvfat support':     config_host.has_key('CONFIG_VVFAT')}
 summary_info += {'qed support':       config_host.has_key('CONFIG_QED')}
 summary_info += {'parallels support': config_host.has_key('CONFIG_PARALLELS')}
 summary_info += {'sheepdog support':  config_host.has_key('CONFIG_SHEEPDOG')}
+summary_info += {'host block dev support': config_host.has_key('CONFIG_HOST_BLOCK_DEVICE')}
 summary_info += {'capstone':          capstone_opt == 'disabled' ? false : capstone_opt}
 summary_info += {'libpmem support':   config_host.has_key('CONFIG_LIBPMEM')}
 summary_info += {'libdaxctl support': config_host.has_key('CONFIG_LIBDAXCTL')}
diff --git a/qapi/block-core.json b/qapi/block-core.json
index 1b8b4156b4..ddcb61b8e8 100644
--- a/qapi/block-core.json
+++ b/qapi/block-core.json
@@ -2848,7 +2848,9 @@
 { 'enum': 'BlockdevDriver',
   'data': [ 'blkdebug', 'blklogwrites', 'blkreplay', 'blkverify', 'bochs',
             'cloop', 'compress', 'copy-on-read', 'dmg', 'file', 'ftp', 'ftps',
-            'gluster', 'host_cdrom', 'host_device', 'http', 'https', 'iscsi',
+            'gluster', 'host_cdrom',
+            {'name': 'host_device', 'if': 'defined(CONFIG_HOST_BLOCK_DEVICE)' },
+            'http', 'https', 'iscsi',
             'luks', 'nbd', 'nfs', 'null-aio', 'null-co', 'nvme', 'parallels',
             'qcow', 'qcow2', 'qed', 'quorum', 'raw', 'rbd',
             { 'name': 'replication', 'if': 'defined(CONFIG_REPLICATION)' },
diff --git a/block/file-posix.c b/block/file-posix.c
index c63926d592..52f7c20525 100644
--- a/block/file-posix.c
+++ b/block/file-posix.c
@@ -41,7 +41,7 @@
 #include "scsi/pr-manager.h"
 #include "scsi/constants.h"
 
-#if defined(__APPLE__) && (__MACH__)
+#if defined(CONFIG_HOST_BLOCK_DEVICE) && defined(__APPLE__) && (__MACH__)
 #include <paths.h>
 #include <sys/param.h>
 #include <IOKit/IOKitLib.h>
@@ -3247,6 +3247,8 @@ BlockDriver bdrv_file = {
 /***********************************************/
 /* host device */
 
+#if defined(CONFIG_HOST_BLOCK_DEVICE)
+
 #if defined(__APPLE__) && defined(__MACH__)
 static kern_return_t GetBSDPath(io_iterator_t mediaIterator, char *bsdPath,
                                 CFIndex maxPathSize, int flags);
@@ -3872,6 +3874,8 @@ static BlockDriver bdrv_host_cdrom = {
 };
 #endif /* __FreeBSD__ */
 
+#endif /* CONFIG_HOST_BLOCK_DEVICE */
+
 static void bdrv_file_init(void)
 {
     /*
@@ -3879,6 +3883,7 @@ static void bdrv_file_init(void)
      * registered last will get probed first.
      */
     bdrv_register(&bdrv_file);
+#if defined(CONFIG_HOST_BLOCK_DEVICE)
     bdrv_register(&bdrv_host_device);
 #ifdef __linux__
     bdrv_register(&bdrv_host_cdrom);
@@ -3886,6 +3891,7 @@ static void bdrv_file_init(void)
 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
     bdrv_register(&bdrv_host_cdrom);
 #endif
+#endif /* CONFIG_HOST_BLOCK_DEVICE */
 }
 
 block_init(bdrv_file_init);
-- 
2.28.0



^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH v4 2/7] configure: cross-compiling with empty cross_prefix
  2020-11-08  5:25 [PATCH v4 0/7] iOS and Apple Silicon host support Joelle van Dyne
  2020-11-08  5:25 ` [PATCH v4 1/7] configure: option to disable host block devices Joelle van Dyne
@ 2020-11-08  5:26 ` Joelle van Dyne
  2020-11-09 18:52   ` Thomas Huth
  2020-11-08  5:26 ` [PATCH v4 3/7] qemu: add support for iOS host Joelle van Dyne
                   ` (4 subsequent siblings)
  6 siblings, 1 reply; 11+ messages in thread
From: Joelle van Dyne @ 2020-11-08  5:26 UTC (permalink / raw)
  To: qemu-devel; +Cc: Joelle van Dyne

The iOS toolchain does not use the host prefix naming convention. So we need
to enable cross-compile options while allowing the PREFIX to be blank.

Signed-off-by: Joelle van Dyne <j@getutm.app>
---
 configure | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/configure b/configure
index 97a879808d..fda7a875f7 100755
--- a/configure
+++ b/configure
@@ -234,6 +234,7 @@ cpu=""
 iasl="iasl"
 interp_prefix="/usr/gnemul/qemu-%M"
 static="no"
+cross_compile="no"
 cross_prefix=""
 audio_drv_list=""
 block_drv_rw_whitelist=""
@@ -458,6 +459,7 @@ for opt do
   optarg=$(expr "x$opt" : 'x[^=]*=\(.*\)')
   case "$opt" in
   --cross-prefix=*) cross_prefix="$optarg"
+                    cross_compile="yes"
   ;;
   --cc=*) CC="$optarg"
   ;;
@@ -1657,7 +1659,7 @@ $(echo Available targets: $default_target_list | \
   --target-list-exclude=LIST exclude a set of targets from the default target-list
 
 Advanced options (experts only):
-  --cross-prefix=PREFIX    use PREFIX for compile tools [$cross_prefix]
+  --cross-prefix=PREFIX    use PREFIX for compile tools, PREFIX can be blank [$cross_prefix]
   --cc=CC                  use C compiler CC [$cc]
   --iasl=IASL              use ACPI compiler IASL [$iasl]
   --host-cc=CC             use C compiler CC [$host_cc] for code run at
@@ -6933,7 +6935,7 @@ if has $sdl2_config; then
 fi
 echo "strip = [$(meson_quote $strip)]" >> $cross
 echo "windres = [$(meson_quote $windres)]" >> $cross
-if test -n "$cross_prefix"; then
+if test "$cross_compile" = "yes"; then
     cross_arg="--cross-file config-meson.cross"
     echo "[host_machine]" >> $cross
     if test "$mingw32" = "yes" ; then
-- 
2.28.0



^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH v4 3/7] qemu: add support for iOS host
  2020-11-08  5:25 [PATCH v4 0/7] iOS and Apple Silicon host support Joelle van Dyne
  2020-11-08  5:25 ` [PATCH v4 1/7] configure: option to disable host block devices Joelle van Dyne
  2020-11-08  5:26 ` [PATCH v4 2/7] configure: cross-compiling with empty cross_prefix Joelle van Dyne
@ 2020-11-08  5:26 ` Joelle van Dyne
  2020-11-08  5:26 ` [PATCH v4 4/7] coroutine: add libucontext as external library Joelle van Dyne
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 11+ messages in thread
From: Joelle van Dyne @ 2020-11-08  5:26 UTC (permalink / raw)
  To: qemu-devel
  Cc: Kevin Wolf, Laurent Vivier, Thomas Huth,
	open list:Block layer core, Jason Wang, Michael Roth, Max Reitz,
	Joelle van Dyne, Paolo Bonzini, Samuel Thibault

This introduces support for building for iOS hosts. When the correct Xcode
toolchain is used, iOS host will be detected automatically.

* block: disable features not supported by iOS sandbox
* slirp: disable SMB features for iOS
* osdep: disable system() calls for iOS

Signed-off-by: Joelle van Dyne <j@getutm.app>
---
 docs/devel/index.rst    |  1 +
 docs/devel/ios.rst      | 28 +++++++++++++++++++++++++++
 configure               | 43 ++++++++++++++++++++++++++++++++++++++++-
 meson.build             |  2 +-
 include/qemu/osdep.h    | 11 +++++++++++
 block.c                 |  2 +-
 block/file-posix.c      | 31 +++++++++++++++++------------
 net/slirp.c             | 16 +++++++--------
 qga/commands-posix.c    |  6 ++++++
 MAINTAINERS             |  7 +++++++
 tests/qtest/meson.build |  7 +++----
 11 files changed, 127 insertions(+), 27 deletions(-)
 create mode 100644 docs/devel/ios.rst

diff --git a/docs/devel/index.rst b/docs/devel/index.rst
index 77baae5c77..a46740929f 100644
--- a/docs/devel/index.rst
+++ b/docs/devel/index.rst
@@ -34,3 +34,4 @@ Contents:
    clocks
    qom
    block-coroutine-wrapper
+   ios
diff --git a/docs/devel/ios.rst b/docs/devel/ios.rst
new file mode 100644
index 0000000000..b4ab11bec1
--- /dev/null
+++ b/docs/devel/ios.rst
@@ -0,0 +1,28 @@
+===========
+iOS Support
+===========
+
+To run qemu on the iOS platform, some modifications were required. Most of the
+modifications are conditioned on the ``CONFIG_IOS`` and configuration variable.
+
+Build support
+-------------
+
+For the code to compile, certain changes in the block driver and the slirp
+driver had to be made. There is no ``system()`` call, so it has been replaced
+with an assertion error. There should be no code path that call system() from
+iOS.
+
+``ucontext`` support is broken on iOS. The implementation from ``libucontext``
+is used instead.
+
+JIT support
+-----------
+
+On iOS, allocating RWX pages require special entitlements not usually granted to
+apps. However, it is possible to use `bulletproof JIT`_ with a development
+certificate. This means that we need to allocate one chunk of memory with RX
+permissions and then mirror map the same memory with RW permissions. We generate
+code to the mirror mapping and execute the original mapping.
+
+.. _bulletproof JIT: https://www.blackhat.com/docs/us-16/materials/us-16-Krstic.pdf
diff --git a/configure b/configure
index fda7a875f7..2a6db88a46 100755
--- a/configure
+++ b/configure
@@ -557,6 +557,19 @@ EOF
   compile_object
 }
 
+check_ios() {
+  cat > $TMPC <<EOF
+#ifdef __APPLE__
+#import "TargetConditionals.h"
+#if !TARGET_OS_IPHONE
+#error TARGET_OS_IPHONE not true
+#endif
+#endif
+int main(void) { return 0; }
+EOF
+  compile_object
+}
+
 check_include() {
 cat > $TMPC <<EOF
 #include <$1>
@@ -599,7 +612,11 @@ elif check_define __DragonFly__ ; then
 elif check_define __NetBSD__; then
   targetos='NetBSD'
 elif check_define __APPLE__; then
-  targetos='Darwin'
+  if check_ios ; then
+    targetos='iOS'
+  else
+    targetos='Darwin'
+  fi
 else
   # This is a fatal error, but don't report it yet, because we
   # might be going to just print the --help text, or it might
@@ -777,6 +794,22 @@ Darwin)
   # won't work when we're compiling with gcc as a C compiler.
   QEMU_CFLAGS="-DOS_OBJECT_USE_OBJC=0 $QEMU_CFLAGS"
 ;;
+iOS)
+  bsd="yes"
+  darwin="yes"
+  ios="yes"
+  if [ "$cpu" = "x86_64" ] ; then
+    QEMU_CFLAGS="-arch x86_64 $QEMU_CFLAGS"
+    QEMU_LDFLAGS="-arch x86_64 $QEMU_LDFLAGS"
+  fi
+  host_block_device_support="no"
+  audio_drv_list=""
+  audio_possible_drivers=""
+  QEMU_LDFLAGS="-framework CoreFoundation $QEMU_LDFLAGS"
+  # Disable attempts to use ObjectiveC features in os/object.h since they
+  # won't work when we're compiling with gcc as a C compiler.
+  QEMU_CFLAGS="-DOS_OBJECT_USE_OBJC=0 $QEMU_CFLAGS"
+;;
 SunOS)
   solaris="yes"
   make="${MAKE-gmake}"
@@ -5962,6 +5995,10 @@ if test "$darwin" = "yes" ; then
   echo "CONFIG_DARWIN=y" >> $config_host_mak
 fi
 
+if test "$ios" = "yes" ; then
+  echo "CONFIG_IOS=y" >> $config_host_mak
+fi
+
 if test "$solaris" = "yes" ; then
   echo "CONFIG_SOLARIS=y" >> $config_host_mak
 fi
@@ -6926,6 +6963,7 @@ echo "cpp_link_args = [${LDFLAGS:+$(meson_quote $LDFLAGS)}]" >> $cross
 echo "[binaries]" >> $cross
 echo "c = [$(meson_quote $cc)]" >> $cross
 test -n "$cxx" && echo "cpp = [$(meson_quote $cxx)]" >> $cross
+test -n "$objcc" && echo "objc = [$(meson_quote $objcc)]" >> $cross
 echo "ar = [$(meson_quote $ar)]" >> $cross
 echo "nm = [$(meson_quote $nm)]" >> $cross
 echo "pkgconfig = [$(meson_quote $pkg_config_exe)]" >> $cross
@@ -6944,6 +6982,9 @@ if test "$cross_compile" = "yes"; then
     if test "$linux" = "yes" ; then
         echo "system = 'linux'" >> $cross
     fi
+    if test "$darwin" = "yes" ; then
+        echo "system = 'darwin'" >> $cross
+    fi
     case "$ARCH" in
         i386|x86_64)
             echo "cpu_family = 'x86'" >> $cross
diff --git a/meson.build b/meson.build
index fd822346e7..8894171bd1 100644
--- a/meson.build
+++ b/meson.build
@@ -176,7 +176,7 @@ if targetos == 'windows'
                                       include_directories: include_directories('.'))
 elif targetos == 'darwin'
   coref = dependency('appleframeworks', modules: 'CoreFoundation')
-  iokit = dependency('appleframeworks', modules: 'IOKit')
+  iokit = dependency('appleframeworks', modules: 'IOKit', required: 'CONFIG_IOS' not in config_host)
   cocoa = dependency('appleframeworks', modules: 'Cocoa', required: get_option('cocoa'))
 elif targetos == 'sunos'
   socket = [cc.find_library('socket'),
diff --git a/include/qemu/osdep.h b/include/qemu/osdep.h
index f9ec8c84e9..eb8d06cbf5 100644
--- a/include/qemu/osdep.h
+++ b/include/qemu/osdep.h
@@ -686,4 +686,15 @@ char *qemu_get_host_name(Error **errp);
  */
 size_t qemu_get_host_physmem(void);
 
+/**
+ * iOS does not support system() so we replace it with an assertion failure.
+ */
+#ifdef CONFIG_IOS
+#define system ios_does_not_support_system
+static inline int ios_does_not_support_system(const char *command)
+{
+    assert(0);
+}
+#endif /* CONFIG_IOS */
+
 #endif
diff --git a/block.c b/block.c
index 56bacc9e9f..e99cbf25ee 100644
--- a/block.c
+++ b/block.c
@@ -53,7 +53,7 @@
 #ifdef CONFIG_BSD
 #include <sys/ioctl.h>
 #include <sys/queue.h>
-#ifndef __DragonFly__
+#if !defined(__DragonFly__) && !defined(CONFIG_IOS)
 #include <sys/disk.h>
 #endif
 #endif
diff --git a/block/file-posix.c b/block/file-posix.c
index 52f7c20525..5560fd20ac 100644
--- a/block/file-posix.c
+++ b/block/file-posix.c
@@ -181,7 +181,17 @@ typedef struct BDRVRawReopenState {
     bool check_cache_dropped;
 } BDRVRawReopenState;
 
-static int fd_open(BlockDriverState *bs);
+static int fd_open(BlockDriverState *bs)
+{
+    BDRVRawState *s = bs->opaque;
+
+    /* this is just to ensure s->fd is sane (its called by io ops) */
+    if (s->fd >= 0) {
+        return 0;
+    }
+    return -EIO;
+}
+
 static int64_t raw_getlength(BlockDriverState *bs);
 
 typedef struct RawPosixAIOData {
@@ -252,6 +262,12 @@ static int raw_normalize_devicepath(const char **filename, Error **errp)
 }
 #endif
 
+#if defined(CONFIG_IOS)
+static int probe_logical_blocksize(int fd, unsigned int *sector_size_p)
+{
+    return -ENOTSUP; /* not supported on iOS */
+}
+#else /* CONFIG_IOS */
 /*
  * Get logical block size via ioctl. On success store it in @sector_size_p.
  */
@@ -284,6 +300,7 @@ static int probe_logical_blocksize(int fd, unsigned int *sector_size_p)
 
     return success ? 0 : -errno;
 }
+#endif /* !CONFIG_IOS */
 
 /**
  * Get physical block size of @fd.
@@ -2306,7 +2323,7 @@ again:
         }
         if (size == 0)
 #endif
-#if defined(__APPLE__) && defined(__MACH__)
+#if !defined(CONFIG_IOS) && defined(__APPLE__) && defined(__MACH__)
         {
             uint64_t sectors = 0;
             uint32_t sector_size = 0;
@@ -3541,16 +3558,6 @@ hdev_co_ioctl(BlockDriverState *bs, unsigned long int req, void *buf)
 }
 #endif /* linux */
 
-static int fd_open(BlockDriverState *bs)
-{
-    BDRVRawState *s = bs->opaque;
-
-    /* this is just to ensure s->fd is sane (its called by io ops) */
-    if (s->fd >= 0)
-        return 0;
-    return -EIO;
-}
-
 static coroutine_fn int
 hdev_co_pdiscard(BlockDriverState *bs, int64_t offset, int bytes)
 {
diff --git a/net/slirp.c b/net/slirp.c
index 77042e6df7..8413042c09 100644
--- a/net/slirp.c
+++ b/net/slirp.c
@@ -27,7 +27,7 @@
 #include "net/slirp.h"
 
 
-#ifndef _WIN32
+#if !defined(_WIN32) && !defined(CONFIG_IOS)
 #include <pwd.h>
 #include <sys/wait.h>
 #endif
@@ -90,7 +90,7 @@ typedef struct SlirpState {
     Slirp *slirp;
     Notifier poll_notifier;
     Notifier exit_notifier;
-#ifndef _WIN32
+#if !defined(_WIN32) && !defined(CONFIG_IOS)
     gchar *smb_dir;
 #endif
     GSList *fwd;
@@ -103,7 +103,7 @@ static QTAILQ_HEAD(, SlirpState) slirp_stacks =
 static int slirp_hostfwd(SlirpState *s, const char *redir_str, Error **errp);
 static int slirp_guestfwd(SlirpState *s, const char *config_str, Error **errp);
 
-#ifndef _WIN32
+#if !defined(_WIN32) && !defined(CONFIG_IOS)
 static int slirp_smb(SlirpState *s, const char *exported_dir,
                      struct in_addr vserver_addr, Error **errp);
 static void slirp_smb_cleanup(SlirpState *s);
@@ -368,7 +368,7 @@ static int net_slirp_init(NetClientState *peer, const char *model,
     struct in6_addr ip6_prefix;
     struct in6_addr ip6_host;
     struct in6_addr ip6_dns;
-#ifndef _WIN32
+#if !defined(_WIN32) && !defined(CONFIG_IOS)
     struct in_addr smbsrv = { .s_addr = 0 };
 #endif
     NetClientState *nc;
@@ -478,7 +478,7 @@ static int net_slirp_init(NetClientState *peer, const char *model,
         return -1;
     }
 
-#ifndef _WIN32
+#if !defined(_WIN32) && !defined(CONFIG_IOS)
     if (vsmbserver && !inet_aton(vsmbserver, &smbsrv)) {
         error_setg(errp, "Failed to parse SMB address");
         return -1;
@@ -593,7 +593,7 @@ static int net_slirp_init(NetClientState *peer, const char *model,
             }
         }
     }
-#ifndef _WIN32
+#if !defined(_WIN32) && !defined(CONFIG_IOS)
     if (smb_export) {
         if (slirp_smb(s, smb_export, smbsrv, errp) < 0) {
             goto error;
@@ -785,7 +785,7 @@ void hmp_hostfwd_add(Monitor *mon, const QDict *qdict)
 
 }
 
-#ifndef _WIN32
+#if !defined(_WIN32) && !defined(CONFIG_IOS)
 
 /* automatic user mode samba server configuration */
 static void slirp_smb_cleanup(SlirpState *s)
@@ -900,7 +900,7 @@ static int slirp_smb(SlirpState* s, const char *exported_dir,
     return 0;
 }
 
-#endif /* !defined(_WIN32) */
+#endif /* !defined(_WIN32) && !defined(CONFIG_IOS) */
 
 static int guestfwd_can_read(void *opaque)
 {
diff --git a/qga/commands-posix.c b/qga/commands-posix.c
index 3711080d07..66a2f2ac9e 100644
--- a/qga/commands-posix.c
+++ b/qga/commands-posix.c
@@ -34,6 +34,12 @@
 
 #ifndef CONFIG_HAS_ENVIRON
 #ifdef __APPLE__
+#include "TargetConditionals.h"
+#if !TARGET_OS_IPHONE && !TARGET_IPHONE_SIMULATOR
+#define APPLE_USE_CRT_EXTERNS
+#endif
+#endif
+#ifdef APPLE_USE_CRT_EXTERNS
 #include <crt_externs.h>
 #define environ (*_NSGetEnviron())
 #else
diff --git a/MAINTAINERS b/MAINTAINERS
index 63223e1183..1ec4c67a62 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -528,6 +528,13 @@ F: include/*/*win32*
 X: qga/*win32*
 F: qemu.nsi
 
+IOS
+M: Joelle van Dyne <j@getutm.app>
+S: Maintained
+K: ^Subject:.*(?i)iOS
+F: docs/devel/ios.rst
+F: include/tcg/tcg-apple-jit.h
+
 Alpha Machines
 --------------
 M: Richard Henderson <rth@twiddle.net>
diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build
index c19f1c8503..8a151ee2da 100644
--- a/tests/qtest/meson.build
+++ b/tests/qtest/meson.build
@@ -46,12 +46,11 @@ qtests_i386 = \
   (config_all_devices.has_key('CONFIG_TPM_TIS_ISA') ? ['tpm-tis-test'] : []) +              \
   (config_all_devices.has_key('CONFIG_TPM_TIS_ISA') ? ['tpm-tis-swtpm-test'] : []) +        \
   (config_all_devices.has_key('CONFIG_RTL8139_PCI') ? ['rtl8139-test'] : []) +              \
+  (not config_host.has_key('CONFIG_IOS') ? ['bios-tables-test', 'hd-geo-test'] : []) +      \
   qtests_pci +                                                                              \
   ['fdc-test',
    'ide-test',
-   'hd-geo-test',
    'boot-order-test',
-   'bios-tables-test',
    'rtc-test',
    'i440fx-test',
    'fuzz-test',
@@ -148,9 +147,9 @@ qtests_arm = \
    'boot-serial-test',
    'hexloader-test']
 
-# TODO: once aarch64 TCG is fixed on ARM 32 bit host, make bios-tables-test unconditional
+# TODO: once aarch64 TCG is fixed on ARM 32 bit host, make bios-tables-test unconditional (except on iOS)
 qtests_aarch64 = \
-  (cpu != 'arm' ? ['bios-tables-test'] : []) +                                                  \
+  (cpu != 'arm' and not config_host.has_key('CONFIG_IOS') ? ['bios-tables-test'] : []) +        \
   (config_all_devices.has_key('CONFIG_TPM_TIS_SYSBUS') ? ['tpm-tis-device-test'] : []) +        \
   (config_all_devices.has_key('CONFIG_TPM_TIS_SYSBUS') ? ['tpm-tis-device-swtpm-test'] : []) +  \
   ['arm-cpu-features',
-- 
2.28.0



^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH v4 4/7] coroutine: add libucontext as external library
  2020-11-08  5:25 [PATCH v4 0/7] iOS and Apple Silicon host support Joelle van Dyne
                   ` (2 preceding siblings ...)
  2020-11-08  5:26 ` [PATCH v4 3/7] qemu: add support for iOS host Joelle van Dyne
@ 2020-11-08  5:26 ` Joelle van Dyne
  2020-11-08 15:46   ` Philippe Mathieu-Daudé
  2020-11-08  5:26 ` [PATCH v4 5/7] slirp: update build flags for iOS resolv fix Joelle van Dyne
                   ` (2 subsequent siblings)
  6 siblings, 1 reply; 11+ messages in thread
From: Joelle van Dyne @ 2020-11-08  5:26 UTC (permalink / raw)
  To: qemu-devel; +Cc: Kevin Wolf, Joelle van Dyne, Stefan Hajnoczi

iOS does not support ucontext natively for aarch64 and the sigaltstack is
also unsupported (even worse, it fails silently, see:
https://openradar.appspot.com/13002712 )

As a workaround we include a library implementation of ucontext and add it
as a build option.

Signed-off-by: Joelle van Dyne <j@getutm.app>
---
 configure                 | 23 ++++++++++++++++++++---
 meson.build               | 28 +++++++++++++++++++++++++++-
 util/coroutine-ucontext.c |  9 +++++++++
 .gitmodules               |  3 +++
 libucontext               |  1 +
 meson_options.txt         |  2 ++
 6 files changed, 62 insertions(+), 4 deletions(-)
 create mode 160000 libucontext

diff --git a/configure b/configure
index 2a6db88a46..d1c6aa9750 100755
--- a/configure
+++ b/configure
@@ -1750,7 +1750,7 @@ Advanced options (experts only):
   --oss-lib                path to OSS library
   --cpu=CPU                Build for host CPU [$cpu]
   --with-coroutine=BACKEND coroutine backend. Supported options:
-                           ucontext, sigaltstack, windows
+                           ucontext, libucontext, sigaltstack, windows
   --enable-gcov            enable test coverage analysis with gcov
   --disable-blobs          disable installing provided firmware blobs
   --with-vss-sdk=SDK-path  enable Windows VSS support in QEMU Guest Agent
@@ -4883,6 +4883,8 @@ if test "$coroutine" = ""; then
     coroutine=win32
   elif test "$ucontext_works" = "yes"; then
     coroutine=ucontext
+  elif test "$ios" = "yes"; then
+    coroutine=libucontext
   else
     coroutine=sigaltstack
   fi
@@ -4906,12 +4908,27 @@ else
       error_exit "only the 'windows' coroutine backend is valid for Windows"
     fi
     ;;
+  libucontext)
+  ;;
   *)
     error_exit "unknown coroutine backend $coroutine"
     ;;
   esac
 fi
 
+case $coroutine in
+libucontext)
+  git_submodules="${git_submodules} libucontext"
+  mkdir -p libucontext
+  coroutine_impl=ucontext
+  libucontext="enabled"
+  ;;
+*)
+  coroutine_impl=$coroutine
+  libucontext="disabled"
+  ;;
+esac
+
 if test "$coroutine_pool" = ""; then
   coroutine_pool=yes
 fi
@@ -6457,7 +6474,7 @@ if test "$rbd" = "yes" ; then
   echo "RBD_LIBS=$rbd_libs" >> $config_host_mak
 fi
 
-echo "CONFIG_COROUTINE_BACKEND=$coroutine" >> $config_host_mak
+echo "CONFIG_COROUTINE_BACKEND=$coroutine_impl" >> $config_host_mak
 if test "$coroutine_pool" = "yes" ; then
   echo "CONFIG_COROUTINE_POOL=1" >> $config_host_mak
 else
@@ -7035,7 +7052,7 @@ NINJA=$ninja $meson setup \
         -Dcocoa=$cocoa -Dmpath=$mpath -Dsdl=$sdl -Dsdl_image=$sdl_image \
         -Dvnc=$vnc -Dvnc_sasl=$vnc_sasl -Dvnc_jpeg=$vnc_jpeg -Dvnc_png=$vnc_png \
         -Dgettext=$gettext -Dxkbcommon=$xkbcommon -Du2f=$u2f -Dvirtiofsd=$virtiofsd \
-        -Dcapstone=$capstone -Dslirp=$slirp -Dfdt=$fdt \
+        -Dcapstone=$capstone -Dslirp=$slirp -Dfdt=$fdt -Ducontext=$libucontext \
         -Diconv=$iconv -Dcurses=$curses -Dlibudev=$libudev\
         -Ddocs=$docs -Dsphinx_build=$sphinx_build -Dinstall_blobs=$blobs \
         $cross_arg \
diff --git a/meson.build b/meson.build
index 8894171bd1..e62324d5ac 100644
--- a/meson.build
+++ b/meson.build
@@ -1259,9 +1259,34 @@ if not fdt.found() and fdt_required.length() > 0
   error('fdt not available but required by targets ' + ', '.join(fdt_required))
 endif
 
+ucontext = not_found
+if get_option('ucontext').enabled()
+  if not fs.is_dir(meson.current_source_dir() / 'libucontext/arch' / cpu)
+    error('libucontext is wanted but not implemented for host ' + cpu)
+  endif
+  arch = host_machine.cpu()
+  ucontext_cargs = ['-DG_LOG_DOMAIN="ucontext"', '-DCUSTOM_IMPL']
+  ucontext_files = [
+    'libucontext/arch' / arch / 'getcontext.S',
+    'libucontext/arch' / arch / 'setcontext.S',
+    'libucontext/arch' / arch / 'makecontext.c',
+    'libucontext/arch' / arch / 'startcontext.S',
+    'libucontext/arch' / arch / 'swapcontext.S',
+  ]
+
+  ucontext_inc = include_directories('libucontext/include')
+  libucontext = static_library('ucontext',
+                               sources: ucontext_files,
+                               c_args: ucontext_cargs,
+                               include_directories: ucontext_inc)
+  ucontext = declare_dependency(link_with: libucontext,
+                                include_directories: ucontext_inc)
+endif
+
 config_host_data.set('CONFIG_CAPSTONE', capstone.found())
 config_host_data.set('CONFIG_FDT', fdt.found())
 config_host_data.set('CONFIG_SLIRP', slirp.found())
+config_host_data.set('CONFIG_LIBUCONTEXT', ucontext.found())
 
 #####################
 # Generated sources #
@@ -1477,7 +1502,7 @@ util_ss.add_all(trace_ss)
 util_ss = util_ss.apply(config_all, strict: false)
 libqemuutil = static_library('qemuutil',
                              sources: util_ss.sources() + stub_ss.sources() + genh,
-                             dependencies: [util_ss.dependencies(), m, glib, socket, malloc])
+                             dependencies: [util_ss.dependencies(), m, glib, socket, malloc, ucontext])
 qemuutil = declare_dependency(link_with: libqemuutil,
                               sources: genh + version_res)
 
@@ -2135,6 +2160,7 @@ if targetos == 'windows'
   summary_info += {'QGA MSI support':   config_host.has_key('CONFIG_QGA_MSI')}
 endif
 summary_info += {'seccomp support':   config_host.has_key('CONFIG_SECCOMP')}
+summary_info += {'libucontext support': ucontext.found()}
 summary_info += {'coroutine backend': config_host['CONFIG_COROUTINE_BACKEND']}
 summary_info += {'coroutine pool':    config_host['CONFIG_COROUTINE_POOL'] == '1'}
 summary_info += {'debug stack usage': config_host.has_key('CONFIG_DEBUG_STACK_USAGE')}
diff --git a/util/coroutine-ucontext.c b/util/coroutine-ucontext.c
index 904b375192..1e1dd43512 100644
--- a/util/coroutine-ucontext.c
+++ b/util/coroutine-ucontext.c
@@ -23,7 +23,16 @@
 #undef _FORTIFY_SOURCE
 #endif
 #include "qemu/osdep.h"
+#if defined(CONFIG_LIBUCONTEXT)
+#include <libucontext.h>
+#define ucontext_t libucontext_ucontext_t
+#define getcontext libucontext_getcontext
+#define setcontext libucontext_setcontext
+#define swapcontext libucontext_swapcontext
+#define makecontext libucontext_makecontext
+#else
 #include <ucontext.h>
+#endif
 #include "qemu/coroutine_int.h"
 
 #ifdef CONFIG_VALGRIND_H
diff --git a/.gitmodules b/.gitmodules
index 2bdeeacef8..065b52867f 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -64,3 +64,6 @@
 [submodule "roms/vbootrom"]
 	path = roms/vbootrom
 	url = https://git.qemu.org/git/vbootrom.git
+[submodule "libucontext"]
+	path = libucontext
+	url = https://github.com/utmapp/libucontext.git
diff --git a/libucontext b/libucontext
new file mode 160000
index 0000000000..7094e4c427
--- /dev/null
+++ b/libucontext
@@ -0,0 +1 @@
+Subproject commit 7094e4c42723b6178a4e2b60d4631d8a88f40719
diff --git a/meson_options.txt b/meson_options.txt
index b4f1801875..da24102898 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -64,6 +64,8 @@ option('xkbcommon', type : 'feature', value : 'auto',
        description: 'xkbcommon support')
 option('virtiofsd', type: 'feature', value: 'auto',
        description: 'build virtiofs daemon (virtiofsd)')
+option('ucontext', type : 'feature', value : 'disabled',
+       description: 'libucontext support')
 
 option('capstone', type: 'combo', value: 'auto',
        choices: ['disabled', 'enabled', 'auto', 'system', 'internal'],
-- 
2.28.0



^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH v4 5/7] slirp: update build flags for iOS resolv fix
  2020-11-08  5:25 [PATCH v4 0/7] iOS and Apple Silicon host support Joelle van Dyne
                   ` (3 preceding siblings ...)
  2020-11-08  5:26 ` [PATCH v4 4/7] coroutine: add libucontext as external library Joelle van Dyne
@ 2020-11-08  5:26 ` Joelle van Dyne
  2020-11-08  5:26 ` [PATCH v4 6/7] tcg: implement JIT for iOS and Apple Silicon Joelle van Dyne
  2020-11-08  5:26 ` [PATCH v4 7/7] block: check availablity for preadv/pwritev on mac Joelle van Dyne
  6 siblings, 0 replies; 11+ messages in thread
From: Joelle van Dyne @ 2020-11-08  5:26 UTC (permalink / raw)
  To: qemu-devel; +Cc: Joelle van Dyne, Stefan Hajnoczi

A future libslirp update will use libresolv on Darwin systems, so we add the
flags in QEMU build now.

Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Joelle van Dyne <j@getutm.app>
---
 meson.build | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/meson.build b/meson.build
index e62324d5ac..664d9f93a5 100644
--- a/meson.build
+++ b/meson.build
@@ -1156,6 +1156,8 @@ if have_system
     slirp_deps = []
     if targetos == 'windows'
       slirp_deps = cc.find_library('iphlpapi')
+    elif targetos == 'darwin'
+      slirp_deps = cc.find_library('resolv')
     endif
     slirp_conf = configuration_data()
     slirp_conf.set('SLIRP_MAJOR_VERSION', meson.project_version().split('.')[0])
-- 
2.28.0



^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH v4 6/7] tcg: implement JIT for iOS and Apple Silicon
  2020-11-08  5:25 [PATCH v4 0/7] iOS and Apple Silicon host support Joelle van Dyne
                   ` (4 preceding siblings ...)
  2020-11-08  5:26 ` [PATCH v4 5/7] slirp: update build flags for iOS resolv fix Joelle van Dyne
@ 2020-11-08  5:26 ` Joelle van Dyne
  2020-11-08  5:26 ` [PATCH v4 7/7] block: check availablity for preadv/pwritev on mac Joelle van Dyne
  6 siblings, 0 replies; 11+ messages in thread
From: Joelle van Dyne @ 2020-11-08  5:26 UTC (permalink / raw)
  To: qemu-devel; +Cc: Paolo Bonzini, Joelle van Dyne, Richard Henderson

When entitlements are available (macOS or jailbroken iOS), a hardware
feature called APRR exists on newer Apple Silicon that can cheaply mark JIT
pages as either RX or RW. Reverse engineered functions from
libsystem_pthread.dylib are implemented to handle this.

The following rules apply for JIT write protect:
  * JIT write-protect is enabled before tcg_qemu_tb_exec()
  * JIT write-protect is disabled after tcg_qemu_tb_exec() returns
  * JIT write-protect is disabled inside do_tb_phys_invalidate() but if it
    is called inside of tcg_qemu_tb_exec() then write-protect will be
    enabled again before returning.
  * JIT write-protect is disabled by cpu_loop_exit() for interrupt handling.
  * JIT write-protect is disabled everywhere else.

See https://developer.apple.com/documentation/apple_silicon/porting_just-in-time_compilers_to_apple_silicon

Signed-off-by: Joelle van Dyne <j@getutm.app>
---
 include/exec/exec-all.h     |  2 +
 include/tcg/tcg-apple-jit.h | 86 +++++++++++++++++++++++++++++++++++++
 include/tcg/tcg.h           |  3 ++
 accel/tcg/cpu-exec-common.c |  2 +
 accel/tcg/cpu-exec.c        |  2 +
 accel/tcg/translate-all.c   | 46 ++++++++++++++++++++
 tcg/tcg.c                   |  4 ++
 7 files changed, 145 insertions(+)
 create mode 100644 include/tcg/tcg-apple-jit.h

diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h
index aa65103702..3829f3d470 100644
--- a/include/exec/exec-all.h
+++ b/include/exec/exec-all.h
@@ -549,6 +549,8 @@ TranslationBlock *tb_htable_lookup(CPUState *cpu, target_ulong pc,
                                    target_ulong cs_base, uint32_t flags,
                                    uint32_t cf_mask);
 void tb_set_jmp_target(TranslationBlock *tb, int n, uintptr_t addr);
+void tb_exec_lock(void);
+void tb_exec_unlock(void);
 
 /* GETPC is the true target of the return instruction that we'll execute.  */
 #if defined(CONFIG_TCG_INTERPRETER)
diff --git a/include/tcg/tcg-apple-jit.h b/include/tcg/tcg-apple-jit.h
new file mode 100644
index 0000000000..9efdb2000d
--- /dev/null
+++ b/include/tcg/tcg-apple-jit.h
@@ -0,0 +1,86 @@
+/*
+ * Apple Silicon functions for JIT handling
+ *
+ * Copyright (c) 2020 osy
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef TCG_APPLE_JIT_H
+#define TCG_APPLE_JIT_H
+
+/*
+ * APRR handling
+ * Credits to: https://siguza.github.io/APRR/
+ * Reversed from /usr/lib/system/libsystem_pthread.dylib
+ */
+
+#if defined(__aarch64__) && defined(CONFIG_DARWIN)
+
+#define _COMM_PAGE_START_ADDRESS        (0x0000000FFFFFC000ULL) /* In TTBR0 */
+#define _COMM_PAGE_APRR_SUPPORT         (_COMM_PAGE_START_ADDRESS + 0x10C)
+#define _COMM_PAGE_APPR_WRITE_ENABLE    (_COMM_PAGE_START_ADDRESS + 0x110)
+#define _COMM_PAGE_APRR_WRITE_DISABLE   (_COMM_PAGE_START_ADDRESS + 0x118)
+
+static __attribute__((__always_inline__)) bool jit_write_protect_supported(void)
+{
+    /* Access shared kernel page at fixed memory location. */
+    uint8_t aprr_support = *(volatile uint8_t *)_COMM_PAGE_APRR_SUPPORT;
+    return aprr_support > 0;
+}
+
+/* write protect enable = write disable */
+static __attribute__((__always_inline__)) void jit_write_protect(int enabled)
+{
+    /* Access shared kernel page at fixed memory location. */
+    uint8_t aprr_support = *(volatile uint8_t *)_COMM_PAGE_APRR_SUPPORT;
+    if (aprr_support == 0 || aprr_support > 3) {
+        return;
+    } else if (aprr_support == 1) {
+        __asm__ __volatile__ (
+            "mov x0, %0\n"
+            "ldr x0, [x0]\n"
+            "msr S3_4_c15_c2_7, x0\n"
+            "isb sy\n"
+            :: "r" (enabled ? _COMM_PAGE_APRR_WRITE_DISABLE
+                            : _COMM_PAGE_APPR_WRITE_ENABLE)
+            : "memory", "x0"
+        );
+    } else {
+        __asm__ __volatile__ (
+            "mov x0, %0\n"
+            "ldr x0, [x0]\n"
+            "msr S3_6_c15_c1_5, x0\n"
+            "isb sy\n"
+            :: "r" (enabled ? _COMM_PAGE_APRR_WRITE_DISABLE
+                            : _COMM_PAGE_APPR_WRITE_ENABLE)
+            : "memory", "x0"
+        );
+    }
+}
+
+#else /* defined(__aarch64__) && defined(CONFIG_DARWIN) */
+
+static __attribute__((__always_inline__)) bool jit_write_protect_supported(void)
+{
+    return false;
+}
+
+static __attribute__((__always_inline__)) void jit_write_protect(int enabled)
+{
+}
+
+#endif
+
+#endif /* define TCG_APPLE_JIT_H */
diff --git a/include/tcg/tcg.h b/include/tcg/tcg.h
index 477919aeb6..b16b687d0b 100644
--- a/include/tcg/tcg.h
+++ b/include/tcg/tcg.h
@@ -625,6 +625,9 @@ struct TCGContext {
     size_t code_gen_buffer_size;
     void *code_gen_ptr;
     void *data_gen_ptr;
+#if defined(CONFIG_DARWIN) && !defined(CONFIG_TCG_INTERPRETER)
+    bool code_gen_locked; /* on Darwin each thread tracks W^X flags */
+#endif
 
     /* Threshold to flush the translated code buffer.  */
     void *code_gen_highwater;
diff --git a/accel/tcg/cpu-exec-common.c b/accel/tcg/cpu-exec-common.c
index 12c1e3e974..f1eb767b02 100644
--- a/accel/tcg/cpu-exec-common.c
+++ b/accel/tcg/cpu-exec-common.c
@@ -64,6 +64,8 @@ void cpu_reloading_memory_map(void)
 
 void cpu_loop_exit(CPUState *cpu)
 {
+    /* Unlock JIT write protect if applicable. */
+    tb_exec_unlock();
     /* Undo the setting in cpu_tb_exec.  */
     cpu->can_do_io = 1;
     siglongjmp(cpu->jmp_env, 1);
diff --git a/accel/tcg/cpu-exec.c b/accel/tcg/cpu-exec.c
index 8df0a1782e..960e0c1f36 100644
--- a/accel/tcg/cpu-exec.c
+++ b/accel/tcg/cpu-exec.c
@@ -176,7 +176,9 @@ static inline TranslationBlock *cpu_tb_exec(CPUState *cpu,
     }
 #endif /* DEBUG_DISAS */
 
+    tb_exec_lock();
     ret = tcg_qemu_tb_exec(env, tb_ptr);
+    tb_exec_unlock();
     cpu->can_do_io = 1;
     /*
      * TODO: Delay swapping back to the read-write region of the TB
diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c
index 06102871e7..5773c561cb 100644
--- a/accel/tcg/translate-all.c
+++ b/accel/tcg/translate-all.c
@@ -27,6 +27,9 @@
 #include "disas/disas.h"
 #include "exec/exec-all.h"
 #include "tcg/tcg.h"
+#if defined(CONFIG_DARWIN)
+#include "tcg/tcg-apple-jit.h"
+#endif
 #if defined(CONFIG_USER_ONLY)
 #include "qemu.h"
 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
@@ -61,6 +64,9 @@
 #include "sysemu/tcg.h"
 #include "qapi/error.h"
 
+static bool tb_exec_is_locked(void);
+static void tb_exec_change(bool locked);
+
 /* #define DEBUG_TB_INVALIDATE */
 /* #define DEBUG_TB_FLUSH */
 /* make various TB consistency checks */
@@ -1339,6 +1345,7 @@ void tcg_exec_init(unsigned long tb_size, int splitwx)
                                splitwx, &error_fatal);
     assert(ok);
 
+    tb_exec_unlock();
 #if defined(CONFIG_SOFTMMU)
     /* There's no guest base to take into account, so go ahead and
        initialize the prologue now.  */
@@ -1615,8 +1622,11 @@ static void do_tb_phys_invalidate(TranslationBlock *tb, bool rm_from_page_list)
     PageDesc *p;
     uint32_t h;
     tb_page_addr_t phys_pc;
+    bool code_gen_locked;
 
     assert_memory_lock();
+    code_gen_locked = tb_exec_is_locked();
+    tb_exec_unlock();
 
     /* make sure no further incoming jumps will be chained to this TB */
     qemu_spin_lock(&tb->jmp_lock);
@@ -1629,6 +1639,7 @@ static void do_tb_phys_invalidate(TranslationBlock *tb, bool rm_from_page_list)
                      tb->trace_vcpu_dstate);
     if (!(tb->cflags & CF_NOCACHE) &&
         !qht_remove(&tb_ctx.htable, tb, h)) {
+        tb_exec_change(code_gen_locked);
         return;
     }
 
@@ -1661,6 +1672,8 @@ static void do_tb_phys_invalidate(TranslationBlock *tb, bool rm_from_page_list)
 
     qatomic_set(&tcg_ctx->tb_phys_invalidate_count,
                tcg_ctx->tb_phys_invalidate_count + 1);
+
+    tb_exec_change(code_gen_locked);
 }
 
 static void tb_phys_invalidate__locked(TranslationBlock *tb)
@@ -2899,3 +2912,36 @@ void tcg_flush_softmmu_tlb(CPUState *cs)
     tlb_flush(cs);
 #endif
 }
+
+#if defined(CONFIG_DARWIN) && !defined(CONFIG_TCG_INTERPRETER)
+static bool tb_exec_is_locked(void)
+{
+    return tcg_ctx->code_gen_locked;
+}
+
+static void tb_exec_change(bool locked)
+{
+    if (jit_write_protect_supported()) {
+        jit_write_protect(locked);
+    }
+    tcg_ctx->code_gen_locked = locked;
+}
+#else /* not needed on non-Darwin platforms */
+static bool tb_exec_is_locked(void)
+{
+    return false;
+}
+
+static void tb_exec_change(bool locked) {}
+#endif
+
+void tb_exec_lock(void)
+{
+    /* assumes sys_icache_invalidate already called */
+    tb_exec_change(true);
+}
+
+void tb_exec_unlock(void)
+{
+    tb_exec_change(false);
+}
diff --git a/tcg/tcg.c b/tcg/tcg.c
index d3052031cb..5ed79d2724 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -809,6 +809,8 @@ static void alloc_tcg_plugin_context(TCGContext *s)
 void tcg_register_thread(void)
 {
     tcg_ctx = &tcg_init_ctx;
+
+    tb_exec_unlock();
 }
 #else
 void tcg_register_thread(void)
@@ -843,6 +845,8 @@ void tcg_register_thread(void)
     err = tcg_region_initial_alloc__locked(tcg_ctx);
     g_assert(!err);
     qemu_mutex_unlock(&region.lock);
+
+    tb_exec_unlock();
 }
 #endif /* !CONFIG_USER_ONLY */
 
-- 
2.28.0



^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH v4 7/7] block: check availablity for preadv/pwritev on mac
  2020-11-08  5:25 [PATCH v4 0/7] iOS and Apple Silicon host support Joelle van Dyne
                   ` (5 preceding siblings ...)
  2020-11-08  5:26 ` [PATCH v4 6/7] tcg: implement JIT for iOS and Apple Silicon Joelle van Dyne
@ 2020-11-08  5:26 ` Joelle van Dyne
  6 siblings, 0 replies; 11+ messages in thread
From: Joelle van Dyne @ 2020-11-08  5:26 UTC (permalink / raw)
  To: qemu-devel; +Cc: Kevin Wolf, Joelle van Dyne, open list:raw, Max Reitz

macOS 11/iOS 14 added preadv/pwritev APIs. Due to weak linking, configure
will succeed with CONFIG_PREADV even when targeting a lower OS version. We
therefore need to check at run time if we can actually use these APIs.

Signed-off-by: Joelle van Dyne <j@getutm.app>
---
 block/file-posix.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/block/file-posix.c b/block/file-posix.c
index 5560fd20ac..b5a7ce483d 100644
--- a/block/file-posix.c
+++ b/block/file-posix.c
@@ -1394,12 +1394,24 @@ static bool preadv_present = true;
 static ssize_t
 qemu_preadv(int fd, const struct iovec *iov, int nr_iov, off_t offset)
 {
+#ifdef CONFIG_DARWIN /* preadv introduced in macOS 11 */
+    if (!__builtin_available(macOS 11, iOS 14, watchOS 7, tvOS 14, *)) {
+        preadv_present = false;
+        return -ENOSYS;
+    } else
+#endif
     return preadv(fd, iov, nr_iov, offset);
 }
 
 static ssize_t
 qemu_pwritev(int fd, const struct iovec *iov, int nr_iov, off_t offset)
 {
+#ifdef CONFIG_DARWIN /* pwritev introduced in macOS 11 */
+    if (!__builtin_available(macOS 11, iOS 14, watchOS 7, tvOS 14, *)) {
+        preadv_present = false;
+        return -ENOSYS;
+    } else
+#endif
     return pwritev(fd, iov, nr_iov, offset);
 }
 
-- 
2.28.0



^ permalink raw reply related	[flat|nested] 11+ messages in thread

* Re: [PATCH v4 4/7] coroutine: add libucontext as external library
  2020-11-08  5:26 ` [PATCH v4 4/7] coroutine: add libucontext as external library Joelle van Dyne
@ 2020-11-08 15:46   ` Philippe Mathieu-Daudé
  2020-11-08 22:51     ` Joelle van Dyne
  0 siblings, 1 reply; 11+ messages in thread
From: Philippe Mathieu-Daudé @ 2020-11-08 15:46 UTC (permalink / raw)
  To: Joelle van Dyne, qemu-devel; +Cc: Kevin Wolf, Stefan Hajnoczi

Hi Joelle,

On 11/8/20 6:26 AM, Joelle van Dyne wrote:
> iOS does not support ucontext natively for aarch64 and the sigaltstack is
> also unsupported (even worse, it fails silently, see:
> https://openradar.appspot.com/13002712 )
> 
> As a workaround we include a library implementation of ucontext and add it
> as a build option.
> 
> Signed-off-by: Joelle van Dyne <j@getutm.app>
> ---
>  configure                 | 23 ++++++++++++++++++++---
>  meson.build               | 28 +++++++++++++++++++++++++++-
>  util/coroutine-ucontext.c |  9 +++++++++
>  .gitmodules               |  3 +++
>  libucontext               |  1 +
>  meson_options.txt         |  2 ++
>  6 files changed, 62 insertions(+), 4 deletions(-)
>  create mode 160000 libucontext
...

> diff --git a/meson.build b/meson.build
> index 8894171bd1..e62324d5ac 100644
> --- a/meson.build
> +++ b/meson.build
> @@ -1259,9 +1259,34 @@ if not fdt.found() and fdt_required.length() > 0
>    error('fdt not available but required by targets ' + ', '.join(fdt_required))
>  endif
>  
> +ucontext = not_found
> +if get_option('ucontext').enabled()
> +  if not fs.is_dir(meson.current_source_dir() / 'libucontext/arch' / cpu)
> +    error('libucontext is wanted but not implemented for host ' + cpu)
> +  endif
> +  arch = host_machine.cpu()
> +  ucontext_cargs = ['-DG_LOG_DOMAIN="ucontext"', '-DCUSTOM_IMPL']
> +  ucontext_files = [
> +    'libucontext/arch' / arch / 'getcontext.S',
> +    'libucontext/arch' / arch / 'setcontext.S',
> +    'libucontext/arch' / arch / 'makecontext.c',
> +    'libucontext/arch' / arch / 'startcontext.S',
> +    'libucontext/arch' / arch / 'swapcontext.S',
> +  ]
> +
> +  ucontext_inc = include_directories('libucontext/include')
> +  libucontext = static_library('ucontext',
> +                               sources: ucontext_files,
> +                               c_args: ucontext_cargs,
> +                               include_directories: ucontext_inc)
> +  ucontext = declare_dependency(link_with: libucontext,
> +                                include_directories: ucontext_inc)
> +endif
> +
>  config_host_data.set('CONFIG_CAPSTONE', capstone.found())
>  config_host_data.set('CONFIG_FDT', fdt.found())
>  config_host_data.set('CONFIG_SLIRP', slirp.found())
> +config_host_data.set('CONFIG_LIBUCONTEXT', ucontext.found())
>  
>  #####################
>  # Generated sources #
> @@ -1477,7 +1502,7 @@ util_ss.add_all(trace_ss)
>  util_ss = util_ss.apply(config_all, strict: false)
>  libqemuutil = static_library('qemuutil',
>                               sources: util_ss.sources() + stub_ss.sources() + genh,
> -                             dependencies: [util_ss.dependencies(), m, glib, socket, malloc])
> +                             dependencies: [util_ss.dependencies(), m, glib, socket, malloc, ucontext])
>  qemuutil = declare_dependency(link_with: libqemuutil,
>                                sources: genh + version_res)
>  
> @@ -2135,6 +2160,7 @@ if targetos == 'windows'
>    summary_info += {'QGA MSI support':   config_host.has_key('CONFIG_QGA_MSI')}
>  endif
>  summary_info += {'seccomp support':   config_host.has_key('CONFIG_SECCOMP')}
> +summary_info += {'libucontext support': ucontext.found()}
>  summary_info += {'coroutine backend': config_host['CONFIG_COROUTINE_BACKEND']}
>  summary_info += {'coroutine pool':    config_host['CONFIG_COROUTINE_POOL'] == '1'}
>  summary_info += {'debug stack usage': config_host.has_key('CONFIG_DEBUG_STACK_USAGE')}
> diff --git a/util/coroutine-ucontext.c b/util/coroutine-ucontext.c
> index 904b375192..1e1dd43512 100644
> --- a/util/coroutine-ucontext.c
> +++ b/util/coroutine-ucontext.c
> @@ -23,7 +23,16 @@
>  #undef _FORTIFY_SOURCE
>  #endif
>  #include "qemu/osdep.h"
> +#if defined(CONFIG_LIBUCONTEXT)
> +#include <libucontext.h>
> +#define ucontext_t libucontext_ucontext_t
> +#define getcontext libucontext_getcontext
> +#define setcontext libucontext_setcontext
> +#define swapcontext libucontext_swapcontext
> +#define makecontext libucontext_makecontext
> +#else
>  #include <ucontext.h>
> +#endif
>  #include "qemu/coroutine_int.h"

Trying on Ubuntu 20.04 I'm getting:

/usr/bin/ld: libqemuutil.a(util_coroutine-ucontext.c.o): in function
`qemu_coroutine_new':
util/coroutine-ucontext.c:203: undefined reference to
`libucontext_getcontext'
/usr/bin/ld: util/coroutine-ucontext.c:254: undefined reference to
`libucontext_swapcontext'
/usr/bin/ld: libucontext.a(libucontext_arch_x86_64_makecontext.c.o): in
function `libucontext_makecontext':
libucontext/arch/x86_64/makecontext.c:54: undefined reference to
`_start_context'
collect2: error: ld returned 1 exit status

Regards,

Phil.


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH v4 4/7] coroutine: add libucontext as external library
  2020-11-08 15:46   ` Philippe Mathieu-Daudé
@ 2020-11-08 22:51     ` Joelle van Dyne
  0 siblings, 0 replies; 11+ messages in thread
From: Joelle van Dyne @ 2020-11-08 22:51 UTC (permalink / raw)
  To: Philippe Mathieu-Daudé; +Cc: QEMU Developers

Thanks, it built on my 18.04 machine but it seems that newer versions
of GCC had different behavior on the underscore assembly functions. I
will fix it and test on 20.04.

-j

On Sun, Nov 8, 2020 at 7:46 AM Philippe Mathieu-Daudé <f4bug@amsat.org> wrote:
>
> Hi Joelle,
>
> On 11/8/20 6:26 AM, Joelle van Dyne wrote:
> > iOS does not support ucontext natively for aarch64 and the sigaltstack is
> > also unsupported (even worse, it fails silently, see:
> > https://openradar.appspot.com/13002712 )
> >
> > As a workaround we include a library implementation of ucontext and add it
> > as a build option.
> >
> > Signed-off-by: Joelle van Dyne <j@getutm.app>
> > ---
> >  configure                 | 23 ++++++++++++++++++++---
> >  meson.build               | 28 +++++++++++++++++++++++++++-
> >  util/coroutine-ucontext.c |  9 +++++++++
> >  .gitmodules               |  3 +++
> >  libucontext               |  1 +
> >  meson_options.txt         |  2 ++
> >  6 files changed, 62 insertions(+), 4 deletions(-)
> >  create mode 160000 libucontext
> ...
>
> > diff --git a/meson.build b/meson.build
> > index 8894171bd1..e62324d5ac 100644
> > --- a/meson.build
> > +++ b/meson.build
> > @@ -1259,9 +1259,34 @@ if not fdt.found() and fdt_required.length() > 0
> >    error('fdt not available but required by targets ' + ', '.join(fdt_required))
> >  endif
> >
> > +ucontext = not_found
> > +if get_option('ucontext').enabled()
> > +  if not fs.is_dir(meson.current_source_dir() / 'libucontext/arch' / cpu)
> > +    error('libucontext is wanted but not implemented for host ' + cpu)
> > +  endif
> > +  arch = host_machine.cpu()
> > +  ucontext_cargs = ['-DG_LOG_DOMAIN="ucontext"', '-DCUSTOM_IMPL']
> > +  ucontext_files = [
> > +    'libucontext/arch' / arch / 'getcontext.S',
> > +    'libucontext/arch' / arch / 'setcontext.S',
> > +    'libucontext/arch' / arch / 'makecontext.c',
> > +    'libucontext/arch' / arch / 'startcontext.S',
> > +    'libucontext/arch' / arch / 'swapcontext.S',
> > +  ]
> > +
> > +  ucontext_inc = include_directories('libucontext/include')
> > +  libucontext = static_library('ucontext',
> > +                               sources: ucontext_files,
> > +                               c_args: ucontext_cargs,
> > +                               include_directories: ucontext_inc)
> > +  ucontext = declare_dependency(link_with: libucontext,
> > +                                include_directories: ucontext_inc)
> > +endif
> > +
> >  config_host_data.set('CONFIG_CAPSTONE', capstone.found())
> >  config_host_data.set('CONFIG_FDT', fdt.found())
> >  config_host_data.set('CONFIG_SLIRP', slirp.found())
> > +config_host_data.set('CONFIG_LIBUCONTEXT', ucontext.found())
> >
> >  #####################
> >  # Generated sources #
> > @@ -1477,7 +1502,7 @@ util_ss.add_all(trace_ss)
> >  util_ss = util_ss.apply(config_all, strict: false)
> >  libqemuutil = static_library('qemuutil',
> >                               sources: util_ss.sources() + stub_ss.sources() + genh,
> > -                             dependencies: [util_ss.dependencies(), m, glib, socket, malloc])
> > +                             dependencies: [util_ss.dependencies(), m, glib, socket, malloc, ucontext])
> >  qemuutil = declare_dependency(link_with: libqemuutil,
> >                                sources: genh + version_res)
> >
> > @@ -2135,6 +2160,7 @@ if targetos == 'windows'
> >    summary_info += {'QGA MSI support':   config_host.has_key('CONFIG_QGA_MSI')}
> >  endif
> >  summary_info += {'seccomp support':   config_host.has_key('CONFIG_SECCOMP')}
> > +summary_info += {'libucontext support': ucontext.found()}
> >  summary_info += {'coroutine backend': config_host['CONFIG_COROUTINE_BACKEND']}
> >  summary_info += {'coroutine pool':    config_host['CONFIG_COROUTINE_POOL'] == '1'}
> >  summary_info += {'debug stack usage': config_host.has_key('CONFIG_DEBUG_STACK_USAGE')}
> > diff --git a/util/coroutine-ucontext.c b/util/coroutine-ucontext.c
> > index 904b375192..1e1dd43512 100644
> > --- a/util/coroutine-ucontext.c
> > +++ b/util/coroutine-ucontext.c
> > @@ -23,7 +23,16 @@
> >  #undef _FORTIFY_SOURCE
> >  #endif
> >  #include "qemu/osdep.h"
> > +#if defined(CONFIG_LIBUCONTEXT)
> > +#include <libucontext.h>
> > +#define ucontext_t libucontext_ucontext_t
> > +#define getcontext libucontext_getcontext
> > +#define setcontext libucontext_setcontext
> > +#define swapcontext libucontext_swapcontext
> > +#define makecontext libucontext_makecontext
> > +#else
> >  #include <ucontext.h>
> > +#endif
> >  #include "qemu/coroutine_int.h"
>
> Trying on Ubuntu 20.04 I'm getting:
>
> /usr/bin/ld: libqemuutil.a(util_coroutine-ucontext.c.o): in function
> `qemu_coroutine_new':
> util/coroutine-ucontext.c:203: undefined reference to
> `libucontext_getcontext'
> /usr/bin/ld: util/coroutine-ucontext.c:254: undefined reference to
> `libucontext_swapcontext'
> /usr/bin/ld: libucontext.a(libucontext_arch_x86_64_makecontext.c.o): in
> function `libucontext_makecontext':
> libucontext/arch/x86_64/makecontext.c:54: undefined reference to
> `_start_context'
> collect2: error: ld returned 1 exit status
>
> Regards,
>
> Phil.


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH v4 2/7] configure: cross-compiling with empty cross_prefix
  2020-11-08  5:26 ` [PATCH v4 2/7] configure: cross-compiling with empty cross_prefix Joelle van Dyne
@ 2020-11-09 18:52   ` Thomas Huth
  0 siblings, 0 replies; 11+ messages in thread
From: Thomas Huth @ 2020-11-09 18:52 UTC (permalink / raw)
  To: Joelle van Dyne, qemu-devel

On 08/11/2020 06.26, Joelle van Dyne wrote:
> The iOS toolchain does not use the host prefix naming convention. So we need
> to enable cross-compile options while allowing the PREFIX to be blank.
> 
> Signed-off-by: Joelle van Dyne <j@getutm.app>
> ---
>  configure | 6 ++++--
>  1 file changed, 4 insertions(+), 2 deletions(-)
> 
> diff --git a/configure b/configure
> index 97a879808d..fda7a875f7 100755
> --- a/configure
> +++ b/configure
> @@ -234,6 +234,7 @@ cpu=""
>  iasl="iasl"
>  interp_prefix="/usr/gnemul/qemu-%M"
>  static="no"
> +cross_compile="no"
>  cross_prefix=""
>  audio_drv_list=""
>  block_drv_rw_whitelist=""
> @@ -458,6 +459,7 @@ for opt do
>    optarg=$(expr "x$opt" : 'x[^=]*=\(.*\)')
>    case "$opt" in
>    --cross-prefix=*) cross_prefix="$optarg"
> +                    cross_compile="yes"
>    ;;
>    --cc=*) CC="$optarg"
>    ;;
> @@ -1657,7 +1659,7 @@ $(echo Available targets: $default_target_list | \
>    --target-list-exclude=LIST exclude a set of targets from the default target-list
>  
>  Advanced options (experts only):
> -  --cross-prefix=PREFIX    use PREFIX for compile tools [$cross_prefix]
> +  --cross-prefix=PREFIX    use PREFIX for compile tools, PREFIX can be blank [$cross_prefix]
>    --cc=CC                  use C compiler CC [$cc]
>    --iasl=IASL              use ACPI compiler IASL [$iasl]
>    --host-cc=CC             use C compiler CC [$host_cc] for code run at
> @@ -6933,7 +6935,7 @@ if has $sdl2_config; then
>  fi
>  echo "strip = [$(meson_quote $strip)]" >> $cross
>  echo "windres = [$(meson_quote $windres)]" >> $cross
> -if test -n "$cross_prefix"; then
> +if test "$cross_compile" = "yes"; then
>      cross_arg="--cross-file config-meson.cross"
>      echo "[host_machine]" >> $cross
>      if test "$mingw32" = "yes" ; then
> 

Reviewed-by: Thomas Huth <thuth@redhat.com>



^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2020-11-09 18:53 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-11-08  5:25 [PATCH v4 0/7] iOS and Apple Silicon host support Joelle van Dyne
2020-11-08  5:25 ` [PATCH v4 1/7] configure: option to disable host block devices Joelle van Dyne
2020-11-08  5:26 ` [PATCH v4 2/7] configure: cross-compiling with empty cross_prefix Joelle van Dyne
2020-11-09 18:52   ` Thomas Huth
2020-11-08  5:26 ` [PATCH v4 3/7] qemu: add support for iOS host Joelle van Dyne
2020-11-08  5:26 ` [PATCH v4 4/7] coroutine: add libucontext as external library Joelle van Dyne
2020-11-08 15:46   ` Philippe Mathieu-Daudé
2020-11-08 22:51     ` Joelle van Dyne
2020-11-08  5:26 ` [PATCH v4 5/7] slirp: update build flags for iOS resolv fix Joelle van Dyne
2020-11-08  5:26 ` [PATCH v4 6/7] tcg: implement JIT for iOS and Apple Silicon Joelle van Dyne
2020-11-08  5:26 ` [PATCH v4 7/7] block: check availablity for preadv/pwritev on mac Joelle van Dyne

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.