diff mbox series

[06/10] coroutine: add libucontext as external library

Message ID 20201012232939.48481-7-j@getutm.app (mailing list archive)
State New, archived
Headers show
Series iOS and Apple Silicon host support | expand

Commit Message

Joelle van Dyne Oct. 12, 2020, 11:29 p.m. UTC
From: osy <osy86@users.noreply.github.com>

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>
---
 .gitmodules               |  3 +++
 configure                 | 23 ++++++++++++++++++++---
 libucontext               |  1 +
 meson.build               | 29 ++++++++++++++++++++++++++++-
 meson_options.txt         |  2 ++
 util/coroutine-ucontext.c |  9 +++++++++
 6 files changed, 63 insertions(+), 4 deletions(-)
 create mode 160000 libucontext

Comments

Stefan Hajnoczi Oct. 13, 2020, 1:31 p.m. UTC | #1
On Mon, Oct 12, 2020 at 04:29:35PM -0700, Joelle van Dyne wrote:
> From: osy <osy86@users.noreply.github.com>
> 
> 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>

Hi,
Thanks for sending posting this!

Please indicate what license libucontext is under, that it is compatible
with QEMU's overall GPL v2 license, and update QEMU license
documentation (LICENSE, etc), if necessary.

Please update .gitlab-ci.yml with build tests. Is there a way to test
building QEMU for iOS? If not, then it's difficult for the upstream QEMU
project to carry iOS-specific features since we cannot test them.

Thanks,
Stefan
BALATON Zoltan Oct. 13, 2020, 2:49 p.m. UTC | #2
On Tue, 13 Oct 2020, Stefan Hajnoczi wrote:
> On Mon, Oct 12, 2020 at 04:29:35PM -0700, Joelle van Dyne wrote:
>> From: osy <osy86@users.noreply.github.com>
>>
>> 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>
>
> Hi,
> Thanks for sending posting this!
>
> Please indicate what license libucontext is under, that it is compatible
> with QEMU's overall GPL v2 license, and update QEMU license

https://github.com/utmapp/libucontext/blob/master/LICENSE

Maybe the submodule repo should be mirrored in qemu.git eventually.

> documentation (LICENSE, etc), if necessary.
>
> Please update .gitlab-ci.yml with build tests. Is there a way to test
> building QEMU for iOS? If not, then it's difficult for the upstream QEMU
> project to carry iOS-specific features since we cannot test them.

Build testing should be possible on OS X host that I think we already have 
provided it has the right XCode version installed. (Running it is 
difficult due to app deployment requirements of iOS devices.) But I don't 
know much about these, just trying to point at some possible directions to 
solve this.

Regards,
BALATON Zoltan
Joelle van Dyne Oct. 13, 2020, 3:25 p.m. UTC | #3
Thanks for providing the link.

I'm not sure what license that is/if it is compatible with GPLv2. Can
someone provide guidance on what to update in QEMU's license? I am not
too familiar with all this license stuff.

Regarding building for iOS, as Balaton said it is possible with an OSX
host. However, it does require some work to set up all the right
environment variables (Apple does not follow standard conventions for
cross compiling). You can see the build script we use for UTM:
https://github.com/utmapp/UTM/blob/master/scripts/build_dependencies.sh

However, a lot of the changes does work on other platforms
(libucontext and bulletproof (mirror mapped) JIT are two major ones).
We used iOS build to guard these features because they are only useful
for iOS, but we can make it a configure option if that's desired?

-j

On Tue, Oct 13, 2020 at 7:49 AM BALATON Zoltan <balaton@eik.bme.hu> wrote:
>
> On Tue, 13 Oct 2020, Stefan Hajnoczi wrote:
> > On Mon, Oct 12, 2020 at 04:29:35PM -0700, Joelle van Dyne wrote:
> >> From: osy <osy86@users.noreply.github.com>
> >>
> >> 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>
> >
> > Hi,
> > Thanks for sending posting this!
> >
> > Please indicate what license libucontext is under, that it is compatible
> > with QEMU's overall GPL v2 license, and update QEMU license
>
> https://github.com/utmapp/libucontext/blob/master/LICENSE
>
> Maybe the submodule repo should be mirrored in qemu.git eventually.
>
> > documentation (LICENSE, etc), if necessary.
> >
> > Please update .gitlab-ci.yml with build tests. Is there a way to test
> > building QEMU for iOS? If not, then it's difficult for the upstream QEMU
> > project to carry iOS-specific features since we cannot test them.
>
> Build testing should be possible on OS X host that I think we already have
> provided it has the right XCode version installed. (Running it is
> difficult due to app deployment requirements of iOS devices.) But I don't
> know much about these, just trying to point at some possible directions to
> solve this.
>
> Regards,
> BALATON Zoltan
Daniel P. Berrangé Oct. 13, 2020, 4:18 p.m. UTC | #4
On Tue, Oct 13, 2020 at 04:49:26PM +0200, BALATON Zoltan via wrote:
> On Tue, 13 Oct 2020, Stefan Hajnoczi wrote:
> > On Mon, Oct 12, 2020 at 04:29:35PM -0700, Joelle van Dyne wrote:
> > > From: osy <osy86@users.noreply.github.com>
> > > 
> > > 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>
> > 
> > Hi,
> > Thanks for sending posting this!
> > 
> > Please indicate what license libucontext is under, that it is compatible
> > with QEMU's overall GPL v2 license, and update QEMU license
> 
> https://github.com/utmapp/libucontext/blob/master/LICENSE

I don't recognise that license text as being an exact match for any
common open source license.

As best I can tell, it is closest to being yet another variant of the
MIT license, of which there are ridiculously many

  https://fedoraproject.org/wiki/Licensing:MIT


Regards,
Daniel
diff mbox series

Patch

diff --git a/.gitmodules b/.gitmodules
index f23e859210..f5a1dc3c5a 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/configure b/configure
index 37b27d9e35..16c66b437c 100755
--- a/configure
+++ b/configure
@@ -1761,7 +1761,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
@@ -5064,6 +5064,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
@@ -5087,12 +5089,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
@@ -6682,7 +6699,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
@@ -7282,7 +7299,7 @@  NINJA=${ninja:-$PWD/ninjatool} $meson setup \
 	-Dxen=$xen -Dxen_pci_passthrough=$xen_pci_passthrough -Dtcg=$tcg \
 	-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 \
+	-Dgettext=$gettext -Dxkbcommon=$xkbcommon -Du2f=$u2f -Ducontext=$libucontext \
 	-Dcapstone=$capstone -Dslirp=$slirp -Dfdt=$fdt -Dshared-lib=$shared_lib \
         $cross_arg \
         "$PWD" "$source_path"
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.build b/meson.build
index da96e296e0..118276edb7 100644
--- a/meson.build
+++ b/meson.build
@@ -1101,9 +1101,35 @@  if not fdt.found() and fdt_required.length() > 0
   error('fdt not available but required by targets ' + ', '.join(fdt_required))
 endif
 
+ucontext = not_found
+slirp_opt = 'disabled'
+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())
 
 genh += configure_file(output: 'config-host.h', configuration: config_host_data)
 
@@ -1323,7 +1349,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)
 
@@ -1946,6 +1972,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/meson_options.txt b/meson_options.txt
index bcecbd5e12..acd989dfa2 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -50,6 +50,8 @@  option('vnc_sasl', type : 'feature', value : 'auto',
        description: 'SASL authentication for VNC server')
 option('xkbcommon', type : 'feature', value : 'auto',
        description: 'xkbcommon support')
+option('ucontext', type : 'feature', value : 'disabled',
+       description: 'libucontext support')
 
 option('capstone', type: 'combo', value: 'auto',
        choices: ['disabled', 'enabled', 'auto', 'system', 'internal'],
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