All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Alex Bennée" <alex.bennee@linaro.org>
To: Yeqi Fu <fufuyqqqqqq@gmail.com>
Cc: richard.henderson@linaro.org, qemu-devel@nongnu.org,
	Paolo Bonzini <pbonzini@redhat.com>,
	Thomas Huth <thuth@redhat.com>, Riku Voipio <riku.voipio@iki.fi>
Subject: Re: [RFC v3 03/10] build: Implement libnative library and configure options
Date: Mon, 03 Jul 2023 16:30:22 +0100	[thread overview]
Message-ID: <87mt0dgdcj.fsf@linaro.org> (raw)
In-Reply-To: <20230625212707.1078951-4-fufuyqqqqqq@gmail.com>


Yeqi Fu <fufuyqqqqqq@gmail.com> writes:

> This commit implements a shared library, where native functions are
> rewritten as specialized instructions. At runtime, user programs load
> the shared library, and specialized instructions are executed when
> native functions are called.

This commit breaks the build:

  make -j9 all
  config-host.mak is out-of-date, running configure
  python determined to be '/usr/bin/python3'
  python version: Python 3.11.2
  mkvenv: Creating non-isolated virtual environment at 'pyvenv'
  mkvenv: checking for meson>=0.63.0
  The Meson build system
  Version: 1.0.1
  Source dir: /home/alex/lsrc/qemu.git
  Build dir: /home/alex/lsrc/qemu.git/builds/user
  Build type: native build
  Project name: qemu
  Project version: 8.0.50
  C compiler for the host machine: cc -m64 -mcx16 (gcc 12.2.0 "cc (Debian 12.2.0-14) 12.2.0")
  C linker for the host machine: cc -m64 -mcx16 ld.bfd 2.40
  Host machine cpu family: x86_64
  Host machine cpu: x86_64
  Program scripts/symlink-install-tree.py found: YES (/home/alex/lsrc/qemu.git/builds/user/pyvenv/bin/python3 /home/alex/lsrc/qemu.git/scripts/symlink-install-tree.py)
  Program sh found: YES (/usr/bin/sh)
  C++ compiler for the host machine: c++ -m64 -mcx16 (gcc 12.2.0 "c++ (Debian 12.2.0-14) 12.2.0")
  C++ linker for the host machine: c++ -m64 -mcx16 ld.bfd 2.40

  ../../meson.build:68:0: ERROR: Key TARGET_DIRS is not in the dictionary.

  A full log can be found at /home/alex/lsrc/qemu.git/builds/user/meson-logs/meson-log.txt

  ERROR: meson setup failed

  make: *** [Makefile:83: config-host.mak] Error 1

  Compilation exited abnormally with code 2 at Mon Jul  3 16:29:43

I would split this into a number of separate commits.

  - configure logic to move around and share the config.mk
  - add the build machinery for libnative with a default WRAP_NATIVE
    which asserts()
  - merge the per-arch macros with arch enabling patch

>
> Signed-off-by: Yeqi Fu <fufuyqqqqqq@gmail.com>
> ---
>  Makefile                            |   2 +
>  common-user/native/Makefile.include |   9 +++
>  common-user/native/Makefile.target  |  26 +++++++
>  common-user/native/libnative.c      | 112 ++++++++++++++++++++++++++++
>  configure                           |  84 ++++++++++++++++-----
>  include/native/libnative.h          |  12 +++
>  include/native/native-defs.h        |  65 ++++++++++++++++
>  7 files changed, 293 insertions(+), 17 deletions(-)
>  create mode 100644 common-user/native/Makefile.include
>  create mode 100644 common-user/native/Makefile.target
>  create mode 100644 common-user/native/libnative.c
>  create mode 100644 include/native/libnative.h
>  create mode 100644 include/native/native-defs.h
>
> diff --git a/Makefile b/Makefile
> index 3c7d67142f..787b8954a6 100644
> --- a/Makefile
> +++ b/Makefile
> @@ -185,6 +185,8 @@ SUBDIR_MAKEFLAGS=$(if $(V),,--no-print-directory --quiet)
>  
>  include $(SRC_PATH)/tests/Makefile.include
>  
> +include $(SRC_PATH)/common-user/native/Makefile.include
> +
>  all: recurse-all
>  
>  ROMS_RULES=$(foreach t, all clean distclean, $(addsuffix /$(t), $(ROMS)))
> diff --git a/common-user/native/Makefile.include b/common-user/native/Makefile.include
> new file mode 100644
> index 0000000000..40d20bcd4c
> --- /dev/null
> +++ b/common-user/native/Makefile.include
> @@ -0,0 +1,9 @@
> +.PHONY: build-native
> +build-native: $(NATIVE_TARGETS:%=build-native-library-%)
> +$(NATIVE_TARGETS:%=build-native-library-%): build-native-library-%:
> +	$(call quiet-command, \
> +	    $(MAKE) -C common-user/native/$* $(SUBDIR_MAKEFLAGS), \
> +	"BUILD","$* native library")
> +# endif
> +
> +all: build-native
> diff --git a/common-user/native/Makefile.target b/common-user/native/Makefile.target
> new file mode 100644
> index 0000000000..1bb468a2ec
> --- /dev/null
> +++ b/common-user/native/Makefile.target
> @@ -0,0 +1,26 @@
> +# -*- Mode: makefile -*-
> +#
> +# Library for native calls 
> +#
> +
> +all:
> +-include ../config-host.mak
> +-include config-target.mak
> +
> +CFLAGS+=-O1 -fPIC -shared -fno-stack-protector -I$(SRC_PATH)/include -D$(TARGET_NAME) 
> +LDFLAGS+=
> +
> +ifeq ($(TARGET_NAME),arm)
> +EXTRA_CFLAGS+=-marm
> +endif

I think I mentioned before that this is something that the configure
script should add to config-target.mak.

> +
> +SRC = $(SRC_PATH)/common-user/native/libnative.c
> +LIBNATIVE = libnative.so
> +
> +all: $(LIBNATIVE)
> +
> +$(LIBNATIVE): $(SRC)
> +	$(CC) $(CFLAGS) $(EXTRA_CFLAGS) $< -o $@ $(LDFLAGS)
> +
> +clean:
> +	rm -f $(LIBNATIVE)
> diff --git a/common-user/native/libnative.c b/common-user/native/libnative.c
> new file mode 100644
> index 0000000000..26a004e3b4
> --- /dev/null
> +++ b/common-user/native/libnative.c
> @@ -0,0 +1,112 @@
> +#include <stdint.h>
> +#include <stdio.h>
> +#include <stdlib.h>
> +
> +#include "native/libnative.h"
> +#include "native/native-defs.h"
> +
> +#if defined(i386) || defined(x86_64)
> +/* unused opcode */
> +#define WRAP_NATIVE_CALL(func_id, abi_map)                          \
> +    do {                                                            \
> +        __asm__ volatile(".byte 0x0f,0xff\n\t"                      \
> +                         ".word %c[imm1],%c[imm2]\n\t"              \
> +                         : /* no outputs */                         \
> +                         : [imm1] "i"(func_id), [imm2] "i"(abi_map) \
> +                         :);                                        \
> +    } while (0)
> +
> +#endif
> +
> +#if defined(arm) || defined(aarch64)
> +/*
> + * HLT is an invalid instruction for userspace and usefully has 16
> + * bits of spare immeadiate data which we can stuff data in.
> + */
> +#define WRAP_NATIVE_CALL(func_id, abi_map)            \
> +    do {                                              \
> +        __asm__ volatile("hlt  %c0\n\t"               \
> +                         "hlt  %c1\n\t"               \
> +                         : /* no outputs */           \
> +                         : "i"(func_id), "i"(abi_map) \
> +                         : "memory");                 \
> +    } while (0)
> +
> +#endif
> +
> +#if defined(mips) || defined(mips64)
> +/*
> + * There are some unused bytes in the syscall instruction
> + */
> +#define WRAP_NATIVE_CALL(func_id, abi_map)            \
> +    do {                                              \
> +        __asm__ volatile("syscall  %c0\n\t"           \
> +                         "syscall  %c1\n\t"           \
> +                         : /* no outputs */           \
> +                         : "i"(func_id), "i"(abi_map) \
> +                         : "memory");                 \
> +    } while (0)
> +
> +#endif
> +
> +static inline const uint32_t encode_1out_3in(int rtype, int arg1, int arg2,
> +                                             int arg3)
> +{
> +    return (rtype & 0xf) | ((arg1 & 0xf) << 4) | ((arg2 & 0xf) << 8) |
> +           ((arg3 & 0xf) << 12);
> +}
> +
> +static inline const uint32_t encode_0out_3in(int arg1, int arg2, int arg3)
> +{
> +    return encode_1out_3in(TYPE_NO_ARG, arg1, arg2, arg3);
> +}
> +
> +static inline const uint32_t encode_1out_2in(int rtype, int arg1, int arg2)
> +{
> +    return encode_1out_3in(rtype, arg1, arg2, TYPE_NO_ARG);
> +}
> +
> +void *memcpy(void *dest, const void *src, size_t n)
> +{
> +    const uint32_t args = encode_1out_3in(TYPE_PTR_ARG, TYPE_PTR_ARG_W,
> +                                          TYPE_PTR_ARG_R, TYPE_IPTR_ARG);
> +    WRAP_NATIVE_CALL(NATIVE_MEMCPY, args);
> +}
> +
> +int memcmp(const void *s1, const void *s2, size_t n)
> +{
> +    const uint32_t args = encode_1out_3in(TYPE_INT_ARG, TYPE_PTR_ARG_R,
> +                                          TYPE_PTR_ARG_R, TYPE_IPTR_ARG);
> +    WRAP_NATIVE_CALL(NATIVE_MEMCMP, args);
> +}
> +
> +void *memset(void *s, int c, size_t n)
> +{
> +    const uint32_t args = encode_1out_3in(TYPE_PTR_ARG, TYPE_PTR_ARG_W,
> +                                          TYPE_INT_ARG, TYPE_IPTR_ARG);
> +    WRAP_NATIVE_CALL(NATIVE_MEMSET, args);
> +}
> +char *strncpy(char *dest, const char *src, size_t n)
> +{
> +    const uint32_t args = encode_1out_3in(TYPE_PTR_ARG, TYPE_PTR_ARG_W,
> +                                          TYPE_PTR_ARG_R, TYPE_IPTR_ARG);
> +    WRAP_NATIVE_CALL(NATIVE_STRNCPY, args);
> +}
> +int strncmp(const char *s1, const char *s2, size_t n)
> +{
> +    const uint32_t args = encode_1out_3in(TYPE_INT_ARG, TYPE_PTR_ARG_R,
> +                                          TYPE_PTR_ARG_R, TYPE_IPTR_ARG);
> +    WRAP_NATIVE_CALL(NATIVE_STRNCMP, args);
> +}
> +char *strcpy(char *dest, const char *src)
> +{
> +    const uint32_t args =
> +        encode_1out_2in(TYPE_PTR_ARG, TYPE_PTR_ARG_W, TYPE_PTR_ARG_R);
> +    WRAP_NATIVE_CALL(NATIVE_STRCPY, args);
> +}
> +int strcmp(const char *s1, const char *s2)
> +{
> +    const uint32_t args =
> +        encode_1out_2in(TYPE_INT_ARG, TYPE_PTR_ARG_R, TYPE_PTR_ARG_R);
> +    WRAP_NATIVE_CALL(NATIVE_STRCMP, args);
> +}
> diff --git a/configure b/configure
> index 2a556d14c9..64edbda892 100755
> --- a/configure
> +++ b/configure
> @@ -1838,48 +1838,42 @@ if test "$ccache_cpp2" = "yes"; then
>    echo "export CCACHE_CPP2=y" >> $config_host_mak
>  fi
>  
> -# tests/tcg configuration
> -(config_host_mak=tests/tcg/config-host.mak
> -mkdir -p tests/tcg
> -echo "# Automatically generated by configure - do not modify" > $config_host_mak
> -echo "SRC_PATH=$source_path" >> $config_host_mak
> -echo "HOST_CC=$host_cc" >> $config_host_mak
> +# prepare config files for cross build

I think we could expand this comment a little. Something like:

# Prepare the config files for cross building. There are two parts:
#  - cross-build/config-host.mak (common host definitions)
#  - cross-build/<target>/config-target.mak
#
# These files are then symlinked to the directories that need them which
# including the TCG tests (tests/tcg/<target>) and the libnative library
# for linux-user (common/native/<target>/).

> +config_corss_build_host_mak=cross-build/config-host.mak

I'm not sure renaming the config_host_mak variable helps here. Although
now I see the problem because there are two config-host's here:

✗  diff -y config-host.mak ./tests/tcg/config-host.mak
# Automatically generated by configure - do not modify          # Automatically generated by configure - do not modify
                                                              <
all:                                                          <
CONFIG_POSIX=y                                                <
CONFIG_LINUX=y                                                <
SRC_PATH=/home/alex/lsrc/qemu.git                               SRC_PATH=/home/alex/lsrc/qemu.git
TARGET_DIRS=aarch64-linux-user aarch64_be-linux-user alpha-li | HOST_CC=cc
CONFIG_PLUGIN=y                                               <
HAVE_GDB_BIN=/usr/bin/gdb-multiarch                             HAVE_GDB_BIN=/usr/bin/gdb-multiarch
ENGINE=docker                                                 | CONFIG_PLUGIN=y
RUNC=docker                                                   <
ROMS=                                                         <
PYTHON=/home/alex/lsrc/qemu.git/builds/user/pyvenv/bin/python <
GENISOIMAGE=/usr/bin/genisoimage                              <
MESON=/home/alex/lsrc/qemu.git/builds/user/pyvenv/bin/meson   <
NINJA=/usr/bin/ninja                                          <
PKG_CONFIG=pkg-config                                         <
CC=cc                                                         <
EXESUF=                                                       <
CONFIG_DEFAULT_TARGETS=y                                      <
TCG_TESTS_TARGETS= aarch64-linux-user alpha-linux-user arm-li <

and the result of this patch squashes two together and looses the extra
information the top config-host.mak needs.

> +mkdir -p cross-build
> +echo "# Automatically generated by configure - do not modify" > $config_corss_build_host_mak
> +echo "SRC_PATH=$source_path" >> $config_corss_build_host_mak
> +echo "HOST_CC=$host_cc" >> $config_corss_build_host_mak

Phillipe has already mentioned the s/corss/cross/

>  
>  # versioned checked in the main config_host.mak above
>  if test -n "$gdb_bin"; then
> -    echo "HAVE_GDB_BIN=$gdb_bin" >> $config_host_mak
> +    echo "HAVE_GDB_BIN=$gdb_bin" >> $config_corss_build_host_mak
>  fi
>  if test "$plugins" = "yes" ; then
> -    echo "CONFIG_PLUGIN=y" >> $config_host_mak
> +    echo "CONFIG_PLUGIN=y" >> $config_corss_build_host_mak
>  fi
>  
> -tcg_tests_targets=
>  for target in $target_list; do
>    arch=${target%%-*}
> -
>    case $target in
>      xtensa*-linux-user)
> -      # the toolchain is not complete with headers, only build softmmu tests
>        continue
>        ;;
>      *-softmmu)
> -      test -f "$source_path/tests/tcg/$arch/Makefile.softmmu-target" || continue
>        qemu="qemu-system-$arch"
>        ;;
>      *-linux-user|*-bsd-user)
>        qemu="qemu-$arch"
>        ;;
>    esac
> -
>    if probe_target_compiler $target || test -n "$container_image"; then
>        test -n "$container_image" && build_static=y
> -      mkdir -p "tests/tcg/$target"
> -      config_target_mak=tests/tcg/$target/config-target.mak
> -      ln -sf "$source_path/tests/tcg/Makefile.target" "tests/tcg/$target/Makefile"
> +      mkdir -p "cross-build/$target"
> +      config_target_mak=cross-build/$target/config-target.mak
>        echo "# Automatically generated by configure - do not modify" > "$config_target_mak"
>        echo "TARGET_NAME=$arch" >> "$config_target_mak"
>        echo "TARGET=$target" >> "$config_target_mak"
> -      write_target_makefile "build-tcg-tests-$target" >> "$config_target_mak"
> +      write_target_makefile "$target" >> "$config_target_mak"
>        echo "BUILD_STATIC=$build_static" >> "$config_target_mak"
>        echo "QEMU=$PWD/$qemu" >> "$config_target_mak"
>  
> @@ -1887,7 +1881,34 @@ for target in $target_list; do
>        if test "${gdb_arches#*$arch}" != "$gdb_arches"; then
>            echo "HOST_GDB_SUPPORTS_ARCH=y" >> "$config_target_mak"
>        fi
> +  fi
> +done
> +
> +
> +# tests/tcg configuration
> +(mkdir -p tests/tcg
> +ln -srf $config_corss_build_host_mak tests/tcg/config-host.mak
> +
> +tcg_tests_targets=
> +for target in $target_list; do
> +  arch=${target%%-*}
> +
> +  case $target in
> +    xtensa*-linux-user)
> +      # the toolchain is not complete with headers, only build softmmu tests
> +      continue
> +      ;;
> +    *-softmmu)
> +      test -f "$source_path/tests/tcg/$arch/Makefile.softmmu-target" || continue
> +      ;;
> +    *-linux-user|*-bsd-user)
> +      ;;
> +  esac
>  
> +  if probe_target_compiler $target || test -n "$container_image"; then
> +      mkdir -p "tests/tcg/$target"
> +      ln -srf cross-build/$target/config-target.mak tests/tcg/$target/config-target.mak
> +      ln -sf $source_path/tests/tcg/Makefile.target tests/tcg/$target/Makefile
>        echo "run-tcg-tests-$target: $qemu\$(EXESUF)" >> Makefile.prereqs
>        tcg_tests_targets="$tcg_tests_targets $target"
>    fi
> @@ -1898,6 +1919,35 @@ if test "$tcg" = "enabled"; then
>  fi
>  )
>  
> +# common-user/native configuration
> +(mkdir -p common-user/native
> +# reuse the same config-host.mak as tests/tcg
> +ln -srf $config_corss_build_host_mak common-user/native/config-host.mak
> +
> +native_targets=
> +for target in $target_list; do
> +  arch=${target%%-*}
> +  # Skip targets that are not supported
> +  case "$arch" in
> +    i386|x86_64|arm|aarch64|mips|mips64)
> +      case $target in
> +        *-linux-user|*-bsd-user)
> +          if probe_target_compiler $target || test -n
> "$container_image"; then

We are repeating the compiler probe here. We should only need to do it
once for all targets and then if there is a valid cross-build config
detect that when symlinking the tests/tcg and common-user versions.

> +            mkdir -p "common-user/native/$target"
> +            # reuse the same config-target.mak as tests/tcg
> +            ln -srf cross-build/$target/config-target.mak common-user/native/$target/config-target.mak
> +            ln -sf $source_path/common-user/native/Makefile.target common-user/native/$target/Makefile
> +            native_targets="$native_targets $target"
> +          fi
> +        ;;
> +      esac
> +    ;;
> +  esac
> +done
> +
> +echo "NATIVE_TARGETS=$native_targets" >> config-host.mak
> +)
> +
>  if test "$skip_meson" = no; then
>    cross="config-meson.cross.new"
>    meson_quote() {
> diff --git a/include/native/libnative.h b/include/native/libnative.h
> new file mode 100644
> index 0000000000..25a59833db
> --- /dev/null
> +++ b/include/native/libnative.h
> @@ -0,0 +1,12 @@
> +#ifndef __LIBNATIVE_H__
> +#define __LIBNATIVE_H__
> +
> +void *memcpy(void *dest, const void *src, size_t n);
> +int memcmp(const void *s1, const void *s2, size_t n);
> +void *memset(void *s, int c, size_t n);
> +char *strncpy(char *dest, const char *src, size_t n);
> +int strncmp(const char *s1, const char *s2, size_t n);
> +char *strcpy(char *dest, const char *src);
> +int strcmp(const char *s1, const char *s2);
> +
> +#endif /* __LIBNATIVE_H__ */
> diff --git a/include/native/native-defs.h b/include/native/native-defs.h
> new file mode 100644
> index 0000000000..37ed479408
> --- /dev/null
> +++ b/include/native/native-defs.h
> @@ -0,0 +1,65 @@
> +#ifndef __NATIVE_FUNC_H__
> +#define __NATIVE_FUNC_H__
> +
> +/*
> + * Native function IDs. These are used to identify the native function
> + */
> +#define NATIVE_MEMCPY 0x1001
> +#define NATIVE_MEMCMP 0x1002
> +#define NATIVE_MEMSET 0x1003
> +#define NATIVE_STRNCPY 0x1004
> +#define NATIVE_STRNCMP 0x1005
> +#define NATIVE_STRCPY 0x2001
> +#define NATIVE_STRCMP 0x2002
> +
> +/*
> + * Argument encoding. We only really care about 3 types. The two base
> + * register sizes (32 and 64) and if the value is a pointer (in which
> + * case we need to adjust it g2h before passing to the native
> + * function).
> + */
> +#define TYPE_NO_ARG 0x0
> +#define TYPE_I32_ARG 0x1 /* uint32_t */
> +#define TYPE_I64_ARG 0x2 /* uint64_t */
> +#define TYPE_INT_ARG 0x3 /* int */
> +#define TYPE_PTR_ARG 0x4 /* void* */
> +#define TYPE_PTR_ARG_R 0x5
> +#define TYPE_PTR_ARG_W 0x6
> +
> +/*
> + * Add an alias for the natural register size, it might be easier to
> + * pass this in.
> + */
> +#if UINTPTR_MAX == 0xFFFFFFFF
> +#define TYPE_IPTR_ARG TYPE_I32_ARG
> +#elif UINTPTR_MAX == 0xFFFFFFFFFFFFFFFFu
> +#define TYPE_IPTR_ARG TYPE_I64_ARG
> +#else
> +#error TBD pointer size
> +#endif
> +
> +#define GET_RVALUE(types) ((types)&0xf)
> +#define GET_ARG1(types) (((types) >> 4) & 0xf)
> +#define GET_ARG2(types) (((types) >> 8) & 0xf)
> +#define GET_ARG3(types) (((types) >> 12) & 0xf)
> +
> +#define IS_PTR_RVALUE(types) (GET_RVALUE(types) >= TYPE_PTR_ARG)
> +#define IS_PTR_ARG1(types) (GET_ARG1(types) >= TYPE_PTR_ARG)
> +#define IS_PTR_ARG2(types) (GET_ARG2(types) >= TYPE_PTR_ARG)
> +#define IS_PTR_ARG3(types) (GET_ARG3(types) >= TYPE_PTR_ARG)
> +
> +#define IS_ARG_PTR(type) (type >= TYPE_PTR_ARG)
> +#define IS_ARG_READ(type) (type == TYPE_PTR_ARG_R)
> +#define IS_ARG_WRITE(type) (type == TYPE_PTR_ARG_W)
> +
> +/*
> + * Check if the native bypass feature is enabled.
> + */
> +#if defined(CONFIG_USER_ONLY) && defined(CONFIG_NATIVE_CALL)
> +extern bool native_bypass_enabled;
> +#define native_call_enabled() (native_bypass_enabled)
> +#else
> +#define native_call_enabled() 0
> +#endif
> +
> +#endif /* __NATIVE_FUNC_H__ */


-- 
Alex Bennée
Virtualisation Tech Lead @ Linaro


  parent reply	other threads:[~2023-07-03 16:38 UTC|newest]

Thread overview: 20+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-06-25 21:26 [RFC v3 00/10] Native Library Calls Yeqi Fu
2023-06-25 21:26 ` [RFC v3 01/10] docs: Add specification for native library calls Yeqi Fu
2023-07-03 15:04   ` Alex Bennée
2023-06-25 21:26 ` [RFC v3 02/10] build: Add configure options for native calls Yeqi Fu
2023-07-03 15:22   ` Alex Bennée
2023-06-25 21:27 ` [RFC v3 03/10] build: Implement libnative library and configure options Yeqi Fu
2023-06-25 21:47   ` Philippe Mathieu-Daudé
2023-07-03 15:30   ` Alex Bennée [this message]
2023-06-25 21:27 ` [RFC v3 04/10] linux-user: Implement envlist_appendenv Yeqi Fu
2023-07-03 16:38   ` Alex Bennée
2023-07-03 16:55     ` Warner Losh
2023-06-25 21:27 ` [RFC v3 05/10] linux-user: Implement native-bypass option support Yeqi Fu
2023-07-03 18:21   ` Alex Bennée
2023-06-25 21:27 ` [RFC v3 06/10] accel/tcg: Add support for native library calls Yeqi Fu
2023-06-25 21:27 ` [RFC v3 07/10] target/i386: " Yeqi Fu
2023-06-25 21:27 ` [RFC v3 08/10] target/mips: " Yeqi Fu
2023-06-25 21:53   ` Philippe Mathieu-Daudé
2023-06-25 21:27 ` [RFC v3 09/10] target/arm: " Yeqi Fu
2023-07-03 12:13   ` Alex Bennée
2023-06-25 21:27 ` [RFC v3 10/10] tests/tcg/multiarch: Add nativecalls.c test Yeqi Fu

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87mt0dgdcj.fsf@linaro.org \
    --to=alex.bennee@linaro.org \
    --cc=fufuyqqqqqq@gmail.com \
    --cc=pbonzini@redhat.com \
    --cc=qemu-devel@nongnu.org \
    --cc=richard.henderson@linaro.org \
    --cc=riku.voipio@iki.fi \
    --cc=thuth@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.