qemu-block
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH v6 3/7] qemu: add support for iOS host


From: Peter Maydell
Subject: Re: [PATCH v6 3/7] qemu: add support for iOS host
Date: Tue, 12 Jan 2021 15:03:11 +0000

On Tue, 5 Jan 2021 at 02:25, Joelle van Dyne <j@getutm.app> wrote:
>
> 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 f10ed77e4c..2cc8a13ebe 100644
> --- a/docs/devel/index.rst
> +++ b/docs/devel/index.rst
> @@ -35,3 +35,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

QEMU is upper-cased.

> +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

"calls"

> +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

"requires"

> +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 744d1990be..c1a08f0171 100755
> --- a/configure
> +++ b/configure
> @@ -560,6 +560,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>
> @@ -602,7 +615,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

So here targetos=iOS and targetos=Darwin are separate things...

> @@ -6974,6 +7012,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

...so why is this needed if we're not "darwin", but "iOS"...

>      case "$ARCH" in
>          i386|x86_64)
>              echo "cpu_family = 'x86'" >> $cross
> diff --git a/meson.build b/meson.build
> index 9a640d3407..ee333b7a94 100644
> --- a/meson.build
> +++ b/meson.build
> @@ -181,7 +181,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'),

...and here ios seems to be a subtype of darwin, not a different
kind of targetos. That's a bit confusing. Maybe this is Meson's fault ?

> 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 8f177504d4..984a73a82c 100644
> --- a/block.c
> +++ b/block.c
> @@ -54,7 +54,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

Instead of extending this ifdef of OSes, can we add a meson.build
test for "does sys/disk.h exist" and then use #ifdef HAVE_SYS_DISK_H ?
(HAVE_PTY_H is probably a good example to crib from.)

This is part of a general preference we have for not testing
"are we building for host OS Foo" if we can test the specific
property we care about instead.

>  #endif
> diff --git a/block/file-posix.c b/block/file-posix.c
> index c34bb9fac1..9f556322e6 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.
> @@ -2307,7 +2324,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;
> @@ -3543,16 +3560,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;

This sort of ifdeffery should probably also be changed to test
what it really cares about rather than just adding another host OS
type to the list.

> diff --git a/qga/commands-posix.c b/qga/commands-posix.c
> index c089e38120..81e40ac14a 100644
> --- a/qga/commands-posix.c
> +++ b/qga/commands-posix.c

Does it even make sense to build the guest agent for iOS ?
It's not like you can run iOS inside QEMU...

> diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build
> index 6a67c538be..42b46a7ca4 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)

So, why is bios-tables-test not something to run if we're building for iOS?
If there's a good reason for the exclusion the comment should say what it is.

>  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

thanks
-- PMM



reply via email to

[Prev in Thread] Current Thread [Next in Thread]