Преглед изворни кода

Merge tag 'pull-target-arm-20220922' of https://git.linaro.org/people/pmaydell/qemu-arm into staging

target-arm queue:
 * hw/net/can: fix Xilinx ZynqMP CAN RX FIFO logic
 * Fix alignment for Neon VLD4.32
 * Refactoring of page-table-walk code
 * hw/acpi: Add ospm_status hook implementation for acpi-ged
 * hw/net/lan9118: Signal TSFL_INT flag when TX FIFO reaches specified level
 * chardev/baum: avoid variable-length arrays
 * io/channel-websock: avoid variable-length arrays
 * hw/net/e1000e_core: Use definition to avoid dynamic stack allocation
 * hw/ppc/pnv: Avoid dynamic stack allocation
 * hw/intc/xics: Avoid dynamic stack allocation
 * hw/i386/multiboot: Avoid dynamic stack allocation
 * hw/usb/hcd-ohci: Use definition to avoid dynamic stack allocation
 * ui/curses: Avoid dynamic stack allocation
 * tests/unit/test-vmstate: Avoid dynamic stack allocation
 * configure: fix various shellcheck-spotted issues and nits

# -----BEGIN PGP SIGNATURE-----
#
# iQJNBAABCAA3FiEE4aXFk81BneKOgxXPPCUl7RQ2DN4FAmMsjocZHHBldGVyLm1h
# eWRlbGxAbGluYXJvLm9yZwAKCRA8JSXtFDYM3s0vEACuUs7nGGX5vd96EPN+sO5s
# HstP16G6/Xnlw2z0BaXi0MMWapQRhSQJ+MIeDJmqIyZKQ3geJGP7pbFTxI3zreYM
# UTKjdI/wWRYMKPYfxlIBZ8TPugj4a4paFJlyqmpHXtkwiWRv6rF70HQ9Yku5id93
# FN9js/dyF74S2AaDppBuTWp31cM1k6kBTg/v5tXSxE8kDUKkO+HZ1VujOqIG/4nJ
# 6urNJ7jlHSiFdXya2QiR+CAkyXyy551rLETeO8VJg9tOO7Ys7Olj7lqv6kHJY/X1
# 01RbN5A5WXhqCvTLM3UYTvFHmbZtS/C5iUhHRtlZkOoeSv2jS6IRDB8BrBtIbOwF
# XKpaYf1jyFLFwX++hpvySD9Vbcu8KgKId8iKTuDcxjQlEjL3fTbt1ulKo4y+rJ8O
# 6G1k4yZc8/nAvttNoKCn7/Jr1dC+HsANa+1s1L+6w+f1gARV0VXs4gqsveNnbe1+
# WzzaHvHt+hCaiWkSZlyisyw3fbEXMrEyKewi+SZu3c8PvJ6DHa+rYjkhem7muBVF
# iR48FRTjFiS+o402KMwXfMdiGjXyZFi09yn5diowlVjkNAaZVZfgu/wUMD5QBhbh
# fNDSw7LpXGUHML/O98MiXznkgGvTEQNxZdp2qIQrTiinUgmV4ZRLR23ZpEibdJPX
# kiOkr46SbWvksCXnRlTf8w==
# =hec8
# -----END PGP SIGNATURE-----
# gpg: Signature made Thu 22 Sep 2022 12:34:15 EDT
# gpg:                using RSA key E1A5C593CD419DE28E8315CF3C2525ED14360CDE
# gpg:                issuer "peter.maydell@linaro.org"
# gpg: Good signature from "Peter Maydell <peter.maydell@linaro.org>" [full]
# gpg:                 aka "Peter Maydell <pmaydell@gmail.com>" [full]
# gpg:                 aka "Peter Maydell <pmaydell@chiark.greenend.org.uk>" [full]
# gpg:                 aka "Peter Maydell <peter@archaic.org.uk>" [unknown]
# Primary key fingerprint: E1A5 C593 CD41 9DE2 8E83  15CF 3C25 25ED 1436 0CDE

* tag 'pull-target-arm-20220922' of https://git.linaro.org/people/pmaydell/qemu-arm: (39 commits)
  configure: Avoid use of 'local' as it is non-POSIX
  configure: Check mkdir result directly, not via $?
  configure: Remove use of backtick `...` syntax
  configure: Add './' on front of glob of */config-devices.mak.d
  configure: Add missing quoting for some easy cases
  configure: Remove unused meson_args variable
  configure: Remove unused python_version variable
  tests/unit/test-vmstate: Avoid dynamic stack allocation
  ui/curses: Avoid dynamic stack allocation
  hw/usb/hcd-ohci: Use definition to avoid dynamic stack allocation
  hw/i386/multiboot: Avoid dynamic stack allocation
  hw/intc/xics: Avoid dynamic stack allocation
  hw/ppc/pnv: Avoid dynamic stack allocation
  hw/net/e1000e_core: Use definition to avoid dynamic stack allocation
  io/channel-websock: Replace strlen(const_str) by sizeof(const_str) - 1
  chardev/baum: Avoid dynamic stack allocation
  chardev/baum: Use definitions to avoid dynamic stack allocation
  chardev/baum: Replace magic values by X_MAX / Y_MAX definitions
  hw/net/lan9118: Signal TSFL_INT flag when TX FIFO reaches specified level
  hw/acpi: Add ospm_status hook implementation for acpi-ged
  ...

Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Stefan Hajnoczi пре 2 година
родитељ
комит
99d6b11b5b

+ 13 - 9
chardev/baum.c

@@ -87,6 +87,9 @@
 
 
 #define BUF_SIZE 256
 #define BUF_SIZE 256
 
 
+#define X_MAX   84
+#define Y_MAX   1
+
 struct BaumChardev {
 struct BaumChardev {
     Chardev parent;
     Chardev parent;
 
 
@@ -244,11 +247,11 @@ static int baum_deferred_init(BaumChardev *baum)
         brlapi_perror("baum: brlapi__getDisplaySize");
         brlapi_perror("baum: brlapi__getDisplaySize");
         return 0;
         return 0;
     }
     }
-    if (baum->y > 1) {
-        baum->y = 1;
+    if (baum->y > Y_MAX) {
+        baum->y = Y_MAX;
     }
     }
-    if (baum->x > 84) {
-        baum->x = 84;
+    if (baum->x > X_MAX) {
+        baum->x = X_MAX;
     }
     }
 
 
     con = qemu_console_lookup_by_index(0);
     con = qemu_console_lookup_by_index(0);
@@ -296,7 +299,8 @@ static void baum_chr_accept_input(struct Chardev *chr)
 static void baum_write_packet(BaumChardev *baum, const uint8_t *buf, int len)
 static void baum_write_packet(BaumChardev *baum, const uint8_t *buf, int len)
 {
 {
     Chardev *chr = CHARDEV(baum);
     Chardev *chr = CHARDEV(baum);
-    uint8_t io_buf[1 + 2 * len], *cur = io_buf;
+    g_autofree uint8_t *io_buf = g_malloc(1 + 2 * len);
+    uint8_t *cur = io_buf;
     int room;
     int room;
     *cur++ = ESC;
     *cur++ = ESC;
     while (len--)
     while (len--)
@@ -380,9 +384,9 @@ static int baum_eat_packet(BaumChardev *baum, const uint8_t *buf, int len)
     switch (req) {
     switch (req) {
     case BAUM_REQ_DisplayData:
     case BAUM_REQ_DisplayData:
     {
     {
-        uint8_t cells[baum->x * baum->y], c;
-        uint8_t text[baum->x * baum->y];
-        uint8_t zero[baum->x * baum->y];
+        uint8_t cells[X_MAX * Y_MAX], c;
+        uint8_t text[X_MAX * Y_MAX];
+        uint8_t zero[X_MAX * Y_MAX];
         int cursor = BRLAPI_CURSOR_OFF;
         int cursor = BRLAPI_CURSOR_OFF;
         int i;
         int i;
 
 
@@ -405,7 +409,7 @@ static int baum_eat_packet(BaumChardev *baum, const uint8_t *buf, int len)
         }
         }
         timer_del(baum->cellCount_timer);
         timer_del(baum->cellCount_timer);
 
 
-        memset(zero, 0, sizeof(zero));
+        memset(zero, 0, baum->x * baum->y);
 
 
         brlapi_writeArguments_t wa = {
         brlapi_writeArguments_t wa = {
             .displayNumber = BRLAPI_DISPLAY_DEFAULT,
             .displayNumber = BRLAPI_DISPLAY_DEFAULT,

+ 38 - 44
configure

@@ -57,7 +57,7 @@ GNUmakefile: ;
 
 
 EOF
 EOF
     cd build
     cd build
-    exec $source_path/configure "$@"
+    exec "$source_path/configure" "$@"
 fi
 fi
 
 
 # Temporary directory used for files created while
 # Temporary directory used for files created while
@@ -67,8 +67,7 @@ fi
 # it when configure exits.)
 # it when configure exits.)
 TMPDIR1="config-temp"
 TMPDIR1="config-temp"
 rm -rf "${TMPDIR1}"
 rm -rf "${TMPDIR1}"
-mkdir -p "${TMPDIR1}"
-if [ $? -ne 0 ]; then
+if ! mkdir -p "${TMPDIR1}"; then
     echo "ERROR: failed to create temporary directory"
     echo "ERROR: failed to create temporary directory"
     exit 1
     exit 1
 fi
 fi
@@ -111,7 +110,7 @@ error_exit() {
 do_compiler() {
 do_compiler() {
   # Run the compiler, capturing its output to the log. First argument
   # Run the compiler, capturing its output to the log. First argument
   # is compiler binary to execute.
   # is compiler binary to execute.
-  local compiler="$1"
+  compiler="$1"
   shift
   shift
   if test -n "$BASH_VERSION"; then eval '
   if test -n "$BASH_VERSION"; then eval '
       echo >>config.log "
       echo >>config.log "
@@ -311,7 +310,6 @@ pie=""
 coroutine=""
 coroutine=""
 plugins="$default_feature"
 plugins="$default_feature"
 meson=""
 meson=""
-meson_args=""
 ninja=""
 ninja=""
 bindir="bin"
 bindir="bin"
 skip_meson=no
 skip_meson=no
@@ -692,7 +690,7 @@ meson_option_build_array() {
   printf ']\n'
   printf ']\n'
 }
 }
 
 
-. $source_path/scripts/meson-buildoptions.sh
+. "$source_path/scripts/meson-buildoptions.sh"
 
 
 meson_options=
 meson_options=
 meson_option_add() {
 meson_option_add() {
@@ -712,7 +710,7 @@ for opt do
   case "$opt" in
   case "$opt" in
   --help|-h) show_help=yes
   --help|-h) show_help=yes
   ;;
   ;;
-  --version|-V) exec cat $source_path/VERSION
+  --version|-V) exec cat "$source_path/VERSION"
   ;;
   ;;
   --prefix=*) prefix="$optarg"
   --prefix=*) prefix="$optarg"
   ;;
   ;;
@@ -986,7 +984,7 @@ default_target_list=""
 mak_wilds=""
 mak_wilds=""
 
 
 if [ "$linux_user" != no ]; then
 if [ "$linux_user" != no ]; then
-    if [ "$targetos" = linux ] && [ -d $source_path/linux-user/include/host/$cpu ]; then
+    if [ "$targetos" = linux ] && [ -d "$source_path/linux-user/include/host/$cpu" ]; then
         linux_user=yes
         linux_user=yes
     elif [ "$linux_user" = yes ]; then
     elif [ "$linux_user" = yes ]; then
         error_exit "linux-user not supported on this architecture"
         error_exit "linux-user not supported on this architecture"
@@ -996,7 +994,7 @@ if [ "$bsd_user" != no ]; then
     if [ "$bsd_user" = "" ]; then
     if [ "$bsd_user" = "" ]; then
         test $targetos = freebsd && bsd_user=yes
         test $targetos = freebsd && bsd_user=yes
     fi
     fi
-    if [ "$bsd_user" = yes ] && ! [ -d $source_path/bsd-user/$targetos ]; then
+    if [ "$bsd_user" = yes ] && ! [ -d "$source_path/bsd-user/$targetos" ]; then
         error_exit "bsd-user not supported on this host OS"
         error_exit "bsd-user not supported on this host OS"
     fi
     fi
 fi
 fi
@@ -1094,7 +1092,7 @@ exit 0
 fi
 fi
 
 
 # Remove old dependency files to make sure that they get properly regenerated
 # Remove old dependency files to make sure that they get properly regenerated
-rm -f */config-devices.mak.d
+rm -f ./*/config-devices.mak.d
 
 
 if test -z "$python"
 if test -z "$python"
 then
 then
@@ -1112,16 +1110,13 @@ if ! $python -c 'import sys; sys.exit(sys.version_info < (3,6))'; then
       "Use --python=/path/to/python to specify a supported Python."
       "Use --python=/path/to/python to specify a supported Python."
 fi
 fi
 
 
-# Preserve python version since some functionality is dependent on it
-python_version=$($python -c 'import sys; print("%d.%d.%d" % (sys.version_info[0], sys.version_info[1], sys.version_info[2]))' 2>/dev/null)
-
 # Suppress writing compiled files
 # Suppress writing compiled files
 python="$python -B"
 python="$python -B"
 
 
 if test -z "$meson"; then
 if test -z "$meson"; then
     if test "$explicit_python" = no && has meson && version_ge "$(meson --version)" 0.59.3; then
     if test "$explicit_python" = no && has meson && version_ge "$(meson --version)" 0.59.3; then
         meson=meson
         meson=meson
-    elif test $git_submodules_action != 'ignore' ; then
+    elif test "$git_submodules_action" != 'ignore' ; then
         meson=git
         meson=git
     elif test -e "${source_path}/meson/meson.py" ; then
     elif test -e "${source_path}/meson/meson.py" ; then
         meson=internal
         meson=internal
@@ -1838,7 +1833,7 @@ esac
 container="no"
 container="no"
 if test $use_containers = "yes"; then
 if test $use_containers = "yes"; then
     if has "docker" || has "podman"; then
     if has "docker" || has "podman"; then
-        container=$($python $source_path/tests/docker/docker.py probe)
+        container=$($python "$source_path"/tests/docker/docker.py probe)
     fi
     fi
 fi
 fi
 
 
@@ -2070,7 +2065,6 @@ probe_target_compiler() {
     : ${container_cross_strip:=${container_cross_prefix}strip}
     : ${container_cross_strip:=${container_cross_prefix}strip}
   done
   done
 
 
-  local t try
   try=cross
   try=cross
   case "$target_arch:$cpu" in
   case "$target_arch:$cpu" in
     aarch64_be:aarch64 | \
     aarch64_be:aarch64 | \
@@ -2083,8 +2077,8 @@ probe_target_compiler() {
       try='native cross' ;;
       try='native cross' ;;
   esac
   esac
   eval "target_cflags=\${cross_cc_cflags_$target_arch}"
   eval "target_cflags=\${cross_cc_cflags_$target_arch}"
-  for t in $try; do
-    case $t in
+  for thistry in $try; do
+    case $thistry in
     native)
     native)
       target_cc=$cc
       target_cc=$cc
       target_ccas=$ccas
       target_ccas=$ccas
@@ -2288,7 +2282,7 @@ if test "$QEMU_GA_DISTRO" = ""; then
   QEMU_GA_DISTRO=Linux
   QEMU_GA_DISTRO=Linux
 fi
 fi
 if test "$QEMU_GA_VERSION" = ""; then
 if test "$QEMU_GA_VERSION" = ""; then
-    QEMU_GA_VERSION=$(cat $source_path/VERSION)
+    QEMU_GA_VERSION=$(cat "$source_path"/VERSION)
 fi
 fi
 
 
 
 
@@ -2315,7 +2309,7 @@ LINKS="$LINKS python"
 LINKS="$LINKS contrib/plugins/Makefile "
 LINKS="$LINKS contrib/plugins/Makefile "
 for f in $LINKS ; do
 for f in $LINKS ; do
     if [ -e "$source_path/$f" ]; then
     if [ -e "$source_path/$f" ]; then
-        mkdir -p `dirname ./$f`
+        mkdir -p "$(dirname ./"$f")"
         symlink "$source_path/$f" "$f"
         symlink "$source_path/$f" "$f"
     fi
     fi
 done
 done
@@ -2537,7 +2531,7 @@ fi
 for target in $target_list; do
 for target in $target_list; do
     target_dir="$target"
     target_dir="$target"
     target_name=$(echo $target | cut -d '-' -f 1)$EXESUF
     target_name=$(echo $target | cut -d '-' -f 1)$EXESUF
-    mkdir -p $target_dir
+    mkdir -p "$target_dir"
     case $target in
     case $target in
         *-user) symlink "../qemu-$target_name" "$target_dir/qemu-$target_name" ;;
         *-user) symlink "../qemu-$target_name" "$target_dir/qemu-$target_name" ;;
         *) symlink "../qemu-system-$target_name" "$target_dir/qemu-system-$target_name" ;;
         *) symlink "../qemu-system-$target_name" "$target_dir/qemu-system-$target_name" ;;
@@ -2572,14 +2566,14 @@ for target in $target_list; do
   config_target_mak=tests/tcg/config-$target.mak
   config_target_mak=tests/tcg/config-$target.mak
 
 
   echo "# Automatically generated by configure - do not modify" > $config_target_mak
   echo "# Automatically generated by configure - do not modify" > $config_target_mak
-  echo "TARGET_NAME=$arch" >> $config_target_mak
+  echo "TARGET_NAME=$arch" >> "$config_target_mak"
   case $target in
   case $target in
     xtensa*-linux-user)
     xtensa*-linux-user)
       # the toolchain is not complete with headers, only build softmmu tests
       # the toolchain is not complete with headers, only build softmmu tests
       continue
       continue
       ;;
       ;;
     *-softmmu)
     *-softmmu)
-      test -f $source_path/tests/tcg/$arch/Makefile.softmmu-target || continue
+      test -f "$source_path/tests/tcg/$arch/Makefile.softmmu-target" || continue
       qemu="qemu-system-$arch"
       qemu="qemu-system-$arch"
       ;;
       ;;
     *-linux-user|*-bsd-user)
     *-linux-user|*-bsd-user)
@@ -2594,73 +2588,73 @@ for target in $target_list; do
       # compilers is a requirememt for adding a new test that needs a
       # compilers is a requirememt for adding a new test that needs a
       # compiler feature.
       # compiler feature.
 
 
-      echo "BUILD_STATIC=$build_static" >> $config_target_mak
-      write_target_makefile >> $config_target_mak
+      echo "BUILD_STATIC=$build_static" >> "$config_target_mak"
+      write_target_makefile >> "$config_target_mak"
       case $target in
       case $target in
           aarch64-*)
           aarch64-*)
               if do_compiler "$target_cc" $target_cflags \
               if do_compiler "$target_cc" $target_cflags \
                              -march=armv8.1-a+sve -o $TMPE $TMPC; then
                              -march=armv8.1-a+sve -o $TMPE $TMPC; then
-                  echo "CROSS_CC_HAS_SVE=y" >> $config_target_mak
+                  echo "CROSS_CC_HAS_SVE=y" >> "$config_target_mak"
               fi
               fi
               if do_compiler "$target_cc" $target_cflags \
               if do_compiler "$target_cc" $target_cflags \
                              -march=armv8.1-a+sve2 -o $TMPE $TMPC; then
                              -march=armv8.1-a+sve2 -o $TMPE $TMPC; then
-                  echo "CROSS_CC_HAS_SVE2=y" >> $config_target_mak
+                  echo "CROSS_CC_HAS_SVE2=y" >> "$config_target_mak"
               fi
               fi
               if do_compiler "$target_cc" $target_cflags \
               if do_compiler "$target_cc" $target_cflags \
                              -march=armv8.3-a -o $TMPE $TMPC; then
                              -march=armv8.3-a -o $TMPE $TMPC; then
-                  echo "CROSS_CC_HAS_ARMV8_3=y" >> $config_target_mak
+                  echo "CROSS_CC_HAS_ARMV8_3=y" >> "$config_target_mak"
               fi
               fi
               if do_compiler "$target_cc" $target_cflags \
               if do_compiler "$target_cc" $target_cflags \
                              -mbranch-protection=standard -o $TMPE $TMPC; then
                              -mbranch-protection=standard -o $TMPE $TMPC; then
-                  echo "CROSS_CC_HAS_ARMV8_BTI=y" >> $config_target_mak
+                  echo "CROSS_CC_HAS_ARMV8_BTI=y" >> "$config_target_mak"
               fi
               fi
               if do_compiler "$target_cc" $target_cflags \
               if do_compiler "$target_cc" $target_cflags \
                              -march=armv8.5-a+memtag -o $TMPE $TMPC; then
                              -march=armv8.5-a+memtag -o $TMPE $TMPC; then
-                  echo "CROSS_CC_HAS_ARMV8_MTE=y" >> $config_target_mak
+                  echo "CROSS_CC_HAS_ARMV8_MTE=y" >> "$config_target_mak"
               fi
               fi
               ;;
               ;;
           ppc*)
           ppc*)
               if do_compiler "$target_cc" $target_cflags \
               if do_compiler "$target_cc" $target_cflags \
                              -mpower8-vector -o $TMPE $TMPC; then
                              -mpower8-vector -o $TMPE $TMPC; then
-                  echo "CROSS_CC_HAS_POWER8_VECTOR=y" >> $config_target_mak
+                  echo "CROSS_CC_HAS_POWER8_VECTOR=y" >> "$config_target_mak"
               fi
               fi
               if do_compiler "$target_cc" $target_cflags \
               if do_compiler "$target_cc" $target_cflags \
                              -mpower10 -o $TMPE $TMPC; then
                              -mpower10 -o $TMPE $TMPC; then
-                  echo "CROSS_CC_HAS_POWER10=y" >> $config_target_mak
+                  echo "CROSS_CC_HAS_POWER10=y" >> "$config_target_mak"
               fi
               fi
               ;;
               ;;
           i386-linux-user)
           i386-linux-user)
               if do_compiler "$target_cc" $target_cflags \
               if do_compiler "$target_cc" $target_cflags \
                              -Werror -fno-pie -o $TMPE $TMPC; then
                              -Werror -fno-pie -o $TMPE $TMPC; then
-                  echo "CROSS_CC_HAS_I386_NOPIE=y" >> $config_target_mak
+                  echo "CROSS_CC_HAS_I386_NOPIE=y" >> "$config_target_mak"
               fi
               fi
               ;;
               ;;
       esac
       esac
   elif test -n "$container_image"; then
   elif test -n "$container_image"; then
       echo "build-tcg-tests-$target: docker-image-$container_image" >> $makefile
       echo "build-tcg-tests-$target: docker-image-$container_image" >> $makefile
-      echo "BUILD_STATIC=y" >> $config_target_mak
-      write_container_target_makefile >> $config_target_mak
+      echo "BUILD_STATIC=y" >> "$config_target_mak"
+      write_container_target_makefile >> "$config_target_mak"
       case $target in
       case $target in
           aarch64-*)
           aarch64-*)
-              echo "CROSS_CC_HAS_SVE=y" >> $config_target_mak
-              echo "CROSS_CC_HAS_SVE2=y" >> $config_target_mak
-              echo "CROSS_CC_HAS_ARMV8_3=y" >> $config_target_mak
-              echo "CROSS_CC_HAS_ARMV8_BTI=y" >> $config_target_mak
-              echo "CROSS_CC_HAS_ARMV8_MTE=y" >> $config_target_mak
+              echo "CROSS_CC_HAS_SVE=y" >> "$config_target_mak"
+              echo "CROSS_CC_HAS_SVE2=y" >> "$config_target_mak"
+              echo "CROSS_CC_HAS_ARMV8_3=y" >> "$config_target_mak"
+              echo "CROSS_CC_HAS_ARMV8_BTI=y" >> "$config_target_mak"
+              echo "CROSS_CC_HAS_ARMV8_MTE=y" >> "$config_target_mak"
               ;;
               ;;
           ppc*)
           ppc*)
-              echo "CROSS_CC_HAS_POWER8_VECTOR=y" >> $config_target_mak
-              echo "CROSS_CC_HAS_POWER10=y" >> $config_target_mak
+              echo "CROSS_CC_HAS_POWER8_VECTOR=y" >> "$config_target_mak"
+              echo "CROSS_CC_HAS_POWER10=y" >> "$config_target_mak"
               ;;
               ;;
           i386-linux-user)
           i386-linux-user)
-              echo "CROSS_CC_HAS_I386_NOPIE=y" >> $config_target_mak
+              echo "CROSS_CC_HAS_I386_NOPIE=y" >> "$config_target_mak"
               ;;
               ;;
       esac
       esac
       got_cross_cc=yes
       got_cross_cc=yes
   fi
   fi
   if test $got_cross_cc = yes; then
   if test $got_cross_cc = yes; then
       mkdir -p tests/tcg/$target
       mkdir -p tests/tcg/$target
-      echo "QEMU=$PWD/$qemu" >> $config_target_mak
+      echo "QEMU=$PWD/$qemu" >> "$config_target_mak"
       echo "run-tcg-tests-$target: $qemu\$(EXESUF)" >> $makefile
       echo "run-tcg-tests-$target: $qemu\$(EXESUF)" >> $makefile
       tcg_tests_targets="$tcg_tests_targets $target"
       tcg_tests_targets="$tcg_tests_targets $target"
   fi
   fi

+ 8 - 0
hw/acpi/generic_event_device.c

@@ -267,6 +267,13 @@ static void acpi_ged_unplug_cb(HotplugHandler *hotplug_dev,
     }
     }
 }
 }
 
 
+static void acpi_ged_ospm_status(AcpiDeviceIf *adev, ACPIOSTInfoList ***list)
+{
+    AcpiGedState *s = ACPI_GED(adev);
+
+    acpi_memory_ospm_status(&s->memhp_state, list);
+}
+
 static void acpi_ged_send_event(AcpiDeviceIf *adev, AcpiEventStatusBits ev)
 static void acpi_ged_send_event(AcpiDeviceIf *adev, AcpiEventStatusBits ev)
 {
 {
     AcpiGedState *s = ACPI_GED(adev);
     AcpiGedState *s = ACPI_GED(adev);
@@ -409,6 +416,7 @@ static void acpi_ged_class_init(ObjectClass *class, void *data)
     hc->unplug_request = acpi_ged_unplug_request_cb;
     hc->unplug_request = acpi_ged_unplug_request_cb;
     hc->unplug = acpi_ged_unplug_cb;
     hc->unplug = acpi_ged_unplug_cb;
 
 
+    adevc->ospm_status = acpi_ged_ospm_status;
     adevc->send_event = acpi_ged_send_event;
     adevc->send_event = acpi_ged_send_event;
 }
 }
 
 

+ 2 - 3
hw/i386/multiboot.c

@@ -163,6 +163,7 @@ int load_multiboot(X86MachineState *x86ms,
     uint8_t *mb_bootinfo_data;
     uint8_t *mb_bootinfo_data;
     uint32_t cmdline_len;
     uint32_t cmdline_len;
     GList *mods = NULL;
     GList *mods = NULL;
+    g_autofree char *kcmdline = NULL;
 
 
     /* Ok, let's see if it is a multiboot image.
     /* Ok, let's see if it is a multiboot image.
        The header is 12x32bit long, so the latest entry may be 8192 - 48. */
        The header is 12x32bit long, so the latest entry may be 8192 - 48. */
@@ -362,9 +363,7 @@ int load_multiboot(X86MachineState *x86ms,
     }
     }
 
 
     /* Commandline support */
     /* Commandline support */
-    char kcmdline[strlen(kernel_filename) + strlen(kernel_cmdline) + 2];
-    snprintf(kcmdline, sizeof(kcmdline), "%s %s",
-             kernel_filename, kernel_cmdline);
+    kcmdline = g_strdup_printf("%s %s", kernel_filename, kernel_cmdline);
     stl_p(bootinfo + MBI_CMDLINE, mb_add_cmdline(&mbs, kcmdline));
     stl_p(bootinfo + MBI_CMDLINE, mb_add_cmdline(&mbs, kcmdline));
 
 
     stl_p(bootinfo + MBI_BOOTLOADER, mb_add_bootloader(&mbs, bootloader_name));
     stl_p(bootinfo + MBI_BOOTLOADER, mb_add_bootloader(&mbs, bootloader_name));

+ 1 - 1
hw/intc/xics.c

@@ -567,8 +567,8 @@ static void ics_reset_irq(ICSIRQState *irq)
 static void ics_reset(DeviceState *dev)
 static void ics_reset(DeviceState *dev)
 {
 {
     ICSState *ics = ICS(dev);
     ICSState *ics = ICS(dev);
+    g_autofree uint8_t *flags = g_malloc(ics->nr_irqs);
     int i;
     int i;
-    uint8_t flags[ics->nr_irqs];
 
 
     for (i = 0; i < ics->nr_irqs; i++) {
     for (i = 0; i < ics->nr_irqs; i++) {
         flags[i] = ics->irqs[i].flags;
         flags[i] = ics->irqs[i].flags;

+ 16 - 16
hw/net/can/xlnx-zynqmp-can.c

@@ -696,30 +696,30 @@ static void update_rx_fifo(XlnxZynqMPCANState *s, const qemu_can_frame *frame)
                                                timestamp));
                                                timestamp));
 
 
             /* First 32 bit of the data. */
             /* First 32 bit of the data. */
-            fifo32_push(&s->rx_fifo, deposit32(0, R_TXFIFO_DATA1_DB3_SHIFT,
-                                               R_TXFIFO_DATA1_DB3_LENGTH,
+            fifo32_push(&s->rx_fifo, deposit32(0, R_RXFIFO_DATA1_DB3_SHIFT,
+                                               R_RXFIFO_DATA1_DB3_LENGTH,
                                                frame->data[0]) |
                                                frame->data[0]) |
-                                     deposit32(0, R_TXFIFO_DATA1_DB2_SHIFT,
-                                               R_TXFIFO_DATA1_DB2_LENGTH,
+                                     deposit32(0, R_RXFIFO_DATA1_DB2_SHIFT,
+                                               R_RXFIFO_DATA1_DB2_LENGTH,
                                                frame->data[1]) |
                                                frame->data[1]) |
-                                     deposit32(0, R_TXFIFO_DATA1_DB1_SHIFT,
-                                               R_TXFIFO_DATA1_DB1_LENGTH,
+                                     deposit32(0, R_RXFIFO_DATA1_DB1_SHIFT,
+                                               R_RXFIFO_DATA1_DB1_LENGTH,
                                                frame->data[2]) |
                                                frame->data[2]) |
-                                     deposit32(0, R_TXFIFO_DATA1_DB0_SHIFT,
-                                               R_TXFIFO_DATA1_DB0_LENGTH,
+                                     deposit32(0, R_RXFIFO_DATA1_DB0_SHIFT,
+                                               R_RXFIFO_DATA1_DB0_LENGTH,
                                                frame->data[3]));
                                                frame->data[3]));
             /* Last 32 bit of the data. */
             /* Last 32 bit of the data. */
-            fifo32_push(&s->rx_fifo, deposit32(0, R_TXFIFO_DATA2_DB7_SHIFT,
-                                               R_TXFIFO_DATA2_DB7_LENGTH,
+            fifo32_push(&s->rx_fifo, deposit32(0, R_RXFIFO_DATA2_DB7_SHIFT,
+                                               R_RXFIFO_DATA2_DB7_LENGTH,
                                                frame->data[4]) |
                                                frame->data[4]) |
-                                     deposit32(0, R_TXFIFO_DATA2_DB6_SHIFT,
-                                               R_TXFIFO_DATA2_DB6_LENGTH,
+                                     deposit32(0, R_RXFIFO_DATA2_DB6_SHIFT,
+                                               R_RXFIFO_DATA2_DB6_LENGTH,
                                                frame->data[5]) |
                                                frame->data[5]) |
-                                     deposit32(0, R_TXFIFO_DATA2_DB5_SHIFT,
-                                               R_TXFIFO_DATA2_DB5_LENGTH,
+                                     deposit32(0, R_RXFIFO_DATA2_DB5_SHIFT,
+                                               R_RXFIFO_DATA2_DB5_LENGTH,
                                                frame->data[6]) |
                                                frame->data[6]) |
-                                     deposit32(0, R_TXFIFO_DATA2_DB4_SHIFT,
-                                               R_TXFIFO_DATA2_DB4_LENGTH,
+                                     deposit32(0, R_RXFIFO_DATA2_DB4_SHIFT,
+                                               R_RXFIFO_DATA2_DB4_LENGTH,
                                                frame->data[7]));
                                                frame->data[7]));
 
 
             ARRAY_FIELD_DP32(s->regs, INTERRUPT_STATUS_REGISTER, RXOK, 1);
             ARRAY_FIELD_DP32(s->regs, INTERRUPT_STATUS_REGISTER, RXOK, 1);

+ 4 - 3
hw/net/e1000e_core.c

@@ -1622,15 +1622,16 @@ e1000e_rx_fix_l4_csum(E1000ECore *core, struct NetRxPkt *pkt)
     }
     }
 }
 }
 
 
+/* Min. octets in an ethernet frame sans FCS */
+#define MIN_BUF_SIZE 60
+
 ssize_t
 ssize_t
 e1000e_receive_iov(E1000ECore *core, const struct iovec *iov, int iovcnt)
 e1000e_receive_iov(E1000ECore *core, const struct iovec *iov, int iovcnt)
 {
 {
     static const int maximum_ethernet_hdr_len = (14 + 4);
     static const int maximum_ethernet_hdr_len = (14 + 4);
-    /* Min. octets in an ethernet frame sans FCS */
-    static const int min_buf_size = 60;
 
 
     uint32_t n = 0;
     uint32_t n = 0;
-    uint8_t min_buf[min_buf_size];
+    uint8_t min_buf[MIN_BUF_SIZE];
     struct iovec min_iov;
     struct iovec min_iov;
     uint8_t *filter_buf;
     uint8_t *filter_buf;
     size_t size, orig_size;
     size_t size, orig_size;

+ 8 - 0
hw/net/lan9118.c

@@ -696,6 +696,14 @@ static void do_tx_packet(lan9118_state *s)
     n = (s->tx_status_fifo_head + s->tx_status_fifo_used) & 511;
     n = (s->tx_status_fifo_head + s->tx_status_fifo_used) & 511;
     s->tx_status_fifo[n] = status;
     s->tx_status_fifo[n] = status;
     s->tx_status_fifo_used++;
     s->tx_status_fifo_used++;
+
+    /*
+     * Generate TSFL interrupt if TX FIFO level exceeds the level
+     * specified in the FIFO_INT TX Status Level field.
+     */
+    if (s->tx_status_fifo_used > ((s->fifo_int >> 16) & 0xff)) {
+        s->int_sts |= TSFL_INT;
+    }
     if (s->tx_status_fifo_used == 512) {
     if (s->tx_status_fifo_used == 512) {
         s->int_sts |= TSFF_INT;
         s->int_sts |= TSFF_INT;
         /* TODO: Stop transmission.  */
         /* TODO: Stop transmission.  */

+ 2 - 2
hw/ppc/pnv.c

@@ -138,7 +138,7 @@ static void pnv_dt_core(PnvChip *chip, PnvCore *pc, void *fdt)
     int smt_threads = CPU_CORE(pc)->nr_threads;
     int smt_threads = CPU_CORE(pc)->nr_threads;
     CPUPPCState *env = &cpu->env;
     CPUPPCState *env = &cpu->env;
     PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cs);
     PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cs);
-    uint32_t servers_prop[smt_threads];
+    g_autofree uint32_t *servers_prop = g_new(uint32_t, smt_threads);
     int i;
     int i;
     uint32_t segs[] = {cpu_to_be32(28), cpu_to_be32(40),
     uint32_t segs[] = {cpu_to_be32(28), cpu_to_be32(40),
                        0xffffffff, 0xffffffff};
                        0xffffffff, 0xffffffff};
@@ -241,7 +241,7 @@ static void pnv_dt_core(PnvChip *chip, PnvCore *pc, void *fdt)
         servers_prop[i] = cpu_to_be32(pc->pir + i);
         servers_prop[i] = cpu_to_be32(pc->pir + i);
     }
     }
     _FDT((fdt_setprop(fdt, offset, "ibm,ppc-interrupt-server#s",
     _FDT((fdt_setprop(fdt, offset, "ibm,ppc-interrupt-server#s",
-                       servers_prop, sizeof(servers_prop))));
+                       servers_prop, sizeof(*servers_prop) * smt_threads)));
 }
 }
 
 
 static void pnv_dt_icp(PnvChip *chip, void *fdt, uint32_t pir,
 static void pnv_dt_icp(PnvChip *chip, void *fdt, uint32_t pir,

+ 4 - 4
hw/ppc/spapr.c

@@ -177,8 +177,8 @@ static int spapr_fixup_cpu_smt_dt(void *fdt, int offset, PowerPCCPU *cpu,
                                   int smt_threads)
                                   int smt_threads)
 {
 {
     int i, ret = 0;
     int i, ret = 0;
-    uint32_t servers_prop[smt_threads];
-    uint32_t gservers_prop[smt_threads * 2];
+    g_autofree uint32_t *servers_prop = g_new(uint32_t, smt_threads);
+    g_autofree uint32_t *gservers_prop = g_new(uint32_t, smt_threads * 2);
     int index = spapr_get_vcpu_id(cpu);
     int index = spapr_get_vcpu_id(cpu);
 
 
     if (cpu->compat_pvr) {
     if (cpu->compat_pvr) {
@@ -196,12 +196,12 @@ static int spapr_fixup_cpu_smt_dt(void *fdt, int offset, PowerPCCPU *cpu,
         gservers_prop[i*2 + 1] = 0;
         gservers_prop[i*2 + 1] = 0;
     }
     }
     ret = fdt_setprop(fdt, offset, "ibm,ppc-interrupt-server#s",
     ret = fdt_setprop(fdt, offset, "ibm,ppc-interrupt-server#s",
-                      servers_prop, sizeof(servers_prop));
+                      servers_prop, sizeof(*servers_prop) * smt_threads);
     if (ret < 0) {
     if (ret < 0) {
         return ret;
         return ret;
     }
     }
     ret = fdt_setprop(fdt, offset, "ibm,ppc-interrupt-gserver#s",
     ret = fdt_setprop(fdt, offset, "ibm,ppc-interrupt-gserver#s",
-                      gservers_prop, sizeof(gservers_prop));
+                      gservers_prop, sizeof(*gservers_prop) * smt_threads * 2);
 
 
     return ret;
     return ret;
 }
 }

+ 1 - 1
hw/ppc/spapr_pci_nvlink2.c

@@ -397,7 +397,7 @@ void spapr_phb_nvgpu_populate_pcidev_dt(PCIDevice *dev, void *fdt, int offset,
             continue;
             continue;
         }
         }
         if (dev == nvslot->gpdev) {
         if (dev == nvslot->gpdev) {
-            uint32_t npus[nvslot->linknum];
+            g_autofree uint32_t *npus = g_new(uint32_t, nvslot->linknum);
 
 
             for (j = 0; j < nvslot->linknum; ++j) {
             for (j = 0; j < nvslot->linknum; ++j) {
                 PCIDevice *npdev = nvslot->links[j].npdev;
                 PCIDevice *npdev = nvslot->links[j].npdev;

+ 4 - 3
hw/usb/hcd-ohci.c

@@ -805,13 +805,14 @@ static int ohci_service_iso_td(OHCIState *ohci, struct ohci_ed *ed)
     return 1;
     return 1;
 }
 }
 
 
+#define HEX_CHAR_PER_LINE 16
+
 static void ohci_td_pkt(const char *msg, const uint8_t *buf, size_t len)
 static void ohci_td_pkt(const char *msg, const uint8_t *buf, size_t len)
 {
 {
     bool print16;
     bool print16;
     bool printall;
     bool printall;
-    const int width = 16;
     int i;
     int i;
-    char tmp[3 * width + 1];
+    char tmp[3 * HEX_CHAR_PER_LINE + 1];
     char *p = tmp;
     char *p = tmp;
 
 
     print16 = !!trace_event_get_state_backends(TRACE_USB_OHCI_TD_PKT_SHORT);
     print16 = !!trace_event_get_state_backends(TRACE_USB_OHCI_TD_PKT_SHORT);
@@ -822,7 +823,7 @@ static void ohci_td_pkt(const char *msg, const uint8_t *buf, size_t len)
     }
     }
 
 
     for (i = 0; ; i++) {
     for (i = 0; ; i++) {
-        if (i && (!(i % width) || (i == len))) {
+        if (i && (!(i % HEX_CHAR_PER_LINE) || (i == len))) {
             if (!printall) {
             if (!printall) {
                 trace_usb_ohci_td_pkt_short(msg, tmp);
                 trace_usb_ohci_td_pkt_short(msg, tmp);
                 break;
                 break;

+ 1 - 1
io/channel-websock.c

@@ -32,7 +32,7 @@
 
 
 #define QIO_CHANNEL_WEBSOCK_CLIENT_KEY_LEN 24
 #define QIO_CHANNEL_WEBSOCK_CLIENT_KEY_LEN 24
 #define QIO_CHANNEL_WEBSOCK_GUID "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"
 #define QIO_CHANNEL_WEBSOCK_GUID "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"
-#define QIO_CHANNEL_WEBSOCK_GUID_LEN strlen(QIO_CHANNEL_WEBSOCK_GUID)
+#define QIO_CHANNEL_WEBSOCK_GUID_LEN (sizeof(QIO_CHANNEL_WEBSOCK_GUID) - 1)
 
 
 #define QIO_CHANNEL_WEBSOCK_HEADER_PROTOCOL "sec-websocket-protocol"
 #define QIO_CHANNEL_WEBSOCK_HEADER_PROTOCOL "sec-websocket-protocol"
 #define QIO_CHANNEL_WEBSOCK_HEADER_VERSION "sec-websocket-version"
 #define QIO_CHANNEL_WEBSOCK_HEADER_VERSION "sec-websocket-version"

+ 11 - 16
target/arm/helper.c

@@ -3190,24 +3190,19 @@ static CPAccessResult ats_access(CPUARMState *env, const ARMCPRegInfo *ri,
 static uint64_t do_ats_write(CPUARMState *env, uint64_t value,
 static uint64_t do_ats_write(CPUARMState *env, uint64_t value,
                              MMUAccessType access_type, ARMMMUIdx mmu_idx)
                              MMUAccessType access_type, ARMMMUIdx mmu_idx)
 {
 {
-    hwaddr phys_addr;
-    target_ulong page_size;
-    int prot;
     bool ret;
     bool ret;
     uint64_t par64;
     uint64_t par64;
     bool format64 = false;
     bool format64 = false;
-    MemTxAttrs attrs = {};
     ARMMMUFaultInfo fi = {};
     ARMMMUFaultInfo fi = {};
-    ARMCacheAttrs cacheattrs = {};
+    GetPhysAddrResult res = {};
 
 
-    ret = get_phys_addr(env, value, access_type, mmu_idx, &phys_addr, &attrs,
-                        &prot, &page_size, &fi, &cacheattrs);
+    ret = get_phys_addr(env, value, access_type, mmu_idx, &res, &fi);
 
 
     /*
     /*
      * ATS operations only do S1 or S1+S2 translations, so we never
      * ATS operations only do S1 or S1+S2 translations, so we never
      * have to deal with the ARMCacheAttrs format for S2 only.
      * have to deal with the ARMCacheAttrs format for S2 only.
      */
      */
-    assert(!cacheattrs.is_s2_format);
+    assert(!res.cacheattrs.is_s2_format);
 
 
     if (ret) {
     if (ret) {
         /*
         /*
@@ -3313,12 +3308,12 @@ static uint64_t do_ats_write(CPUARMState *env, uint64_t value,
         /* Create a 64-bit PAR */
         /* Create a 64-bit PAR */
         par64 = (1 << 11); /* LPAE bit always set */
         par64 = (1 << 11); /* LPAE bit always set */
         if (!ret) {
         if (!ret) {
-            par64 |= phys_addr & ~0xfffULL;
-            if (!attrs.secure) {
+            par64 |= res.phys & ~0xfffULL;
+            if (!res.attrs.secure) {
                 par64 |= (1 << 9); /* NS */
                 par64 |= (1 << 9); /* NS */
             }
             }
-            par64 |= (uint64_t)cacheattrs.attrs << 56; /* ATTR */
-            par64 |= cacheattrs.shareability << 7; /* SH */
+            par64 |= (uint64_t)res.cacheattrs.attrs << 56; /* ATTR */
+            par64 |= res.cacheattrs.shareability << 7; /* SH */
         } else {
         } else {
             uint32_t fsr = arm_fi_to_lfsc(&fi);
             uint32_t fsr = arm_fi_to_lfsc(&fi);
 
 
@@ -3338,13 +3333,13 @@ static uint64_t do_ats_write(CPUARMState *env, uint64_t value,
          */
          */
         if (!ret) {
         if (!ret) {
             /* We do not set any attribute bits in the PAR */
             /* We do not set any attribute bits in the PAR */
-            if (page_size == (1 << 24)
+            if (res.page_size == (1 << 24)
                 && arm_feature(env, ARM_FEATURE_V7)) {
                 && arm_feature(env, ARM_FEATURE_V7)) {
-                par64 = (phys_addr & 0xff000000) | (1 << 1);
+                par64 = (res.phys & 0xff000000) | (1 << 1);
             } else {
             } else {
-                par64 = phys_addr & 0xfffff000;
+                par64 = res.phys & 0xfffff000;
             }
             }
-            if (!attrs.secure) {
+            if (!res.attrs.secure) {
                 par64 |= (1 << 9); /* NS */
                 par64 |= (1 << 9); /* NS */
             }
             }
         } else {
         } else {

+ 16 - 10
target/arm/internals.h

@@ -1123,13 +1123,7 @@ typedef struct V8M_SAttributes {
 
 
 void v8m_security_lookup(CPUARMState *env, uint32_t address,
 void v8m_security_lookup(CPUARMState *env, uint32_t address,
                          MMUAccessType access_type, ARMMMUIdx mmu_idx,
                          MMUAccessType access_type, ARMMMUIdx mmu_idx,
-                         V8M_SAttributes *sattrs);
-
-bool pmsav8_mpu_lookup(CPUARMState *env, uint32_t address,
-                       MMUAccessType access_type, ARMMMUIdx mmu_idx,
-                       hwaddr *phys_ptr, MemTxAttrs *txattrs,
-                       int *prot, bool *is_subpage,
-                       ARMMMUFaultInfo *fi, uint32_t *mregion);
+                         bool secure, V8M_SAttributes *sattrs);
 
 
 /* Cacheability and shareability attributes for a memory access */
 /* Cacheability and shareability attributes for a memory access */
 typedef struct ARMCacheAttrs {
 typedef struct ARMCacheAttrs {
@@ -1142,13 +1136,25 @@ typedef struct ARMCacheAttrs {
     bool is_s2_format:1;
     bool is_s2_format:1;
 } ARMCacheAttrs;
 } ARMCacheAttrs;
 
 
+/* Fields that are valid upon success. */
+typedef struct GetPhysAddrResult {
+    hwaddr phys;
+    target_ulong page_size;
+    int prot;
+    MemTxAttrs attrs;
+    ARMCacheAttrs cacheattrs;
+} GetPhysAddrResult;
+
 bool get_phys_addr(CPUARMState *env, target_ulong address,
 bool get_phys_addr(CPUARMState *env, target_ulong address,
                    MMUAccessType access_type, ARMMMUIdx mmu_idx,
                    MMUAccessType access_type, ARMMMUIdx mmu_idx,
-                   hwaddr *phys_ptr, MemTxAttrs *attrs, int *prot,
-                   target_ulong *page_size,
-                   ARMMMUFaultInfo *fi, ARMCacheAttrs *cacheattrs)
+                   GetPhysAddrResult *result, ARMMMUFaultInfo *fi)
     __attribute__((nonnull));
     __attribute__((nonnull));
 
 
+bool pmsav8_mpu_lookup(CPUARMState *env, uint32_t address,
+                       MMUAccessType access_type, ARMMMUIdx mmu_idx,
+                       bool is_secure, GetPhysAddrResult *result,
+                       ARMMMUFaultInfo *fi, uint32_t *mregion);
+
 void arm_log_exception(CPUState *cs);
 void arm_log_exception(CPUState *cs);
 
 
 #endif /* !CONFIG_USER_ONLY */
 #endif /* !CONFIG_USER_ONLY */

+ 29 - 49
target/arm/m_helper.c

@@ -183,19 +183,14 @@ static bool v7m_stack_write(ARMCPU *cpu, uint32_t addr, uint32_t value,
 {
 {
     CPUState *cs = CPU(cpu);
     CPUState *cs = CPU(cpu);
     CPUARMState *env = &cpu->env;
     CPUARMState *env = &cpu->env;
-    MemTxAttrs attrs = {};
     MemTxResult txres;
     MemTxResult txres;
-    target_ulong page_size;
-    hwaddr physaddr;
-    int prot;
+    GetPhysAddrResult res = {};
     ARMMMUFaultInfo fi = {};
     ARMMMUFaultInfo fi = {};
-    ARMCacheAttrs cacheattrs = {};
     bool secure = mmu_idx & ARM_MMU_IDX_M_S;
     bool secure = mmu_idx & ARM_MMU_IDX_M_S;
     int exc;
     int exc;
     bool exc_secure;
     bool exc_secure;
 
 
-    if (get_phys_addr(env, addr, MMU_DATA_STORE, mmu_idx, &physaddr,
-                      &attrs, &prot, &page_size, &fi, &cacheattrs)) {
+    if (get_phys_addr(env, addr, MMU_DATA_STORE, mmu_idx, &res, &fi)) {
         /* MPU/SAU lookup failed */
         /* MPU/SAU lookup failed */
         if (fi.type == ARMFault_QEMU_SFault) {
         if (fi.type == ARMFault_QEMU_SFault) {
             if (mode == STACK_LAZYFP) {
             if (mode == STACK_LAZYFP) {
@@ -228,8 +223,8 @@ static bool v7m_stack_write(ARMCPU *cpu, uint32_t addr, uint32_t value,
         }
         }
         goto pend_fault;
         goto pend_fault;
     }
     }
-    address_space_stl_le(arm_addressspace(cs, attrs), physaddr, value,
-                         attrs, &txres);
+    address_space_stl_le(arm_addressspace(cs, res.attrs), res.phys, value,
+                         res.attrs, &txres);
     if (txres != MEMTX_OK) {
     if (txres != MEMTX_OK) {
         /* BusFault trying to write the data */
         /* BusFault trying to write the data */
         if (mode == STACK_LAZYFP) {
         if (mode == STACK_LAZYFP) {
@@ -276,20 +271,15 @@ static bool v7m_stack_read(ARMCPU *cpu, uint32_t *dest, uint32_t addr,
 {
 {
     CPUState *cs = CPU(cpu);
     CPUState *cs = CPU(cpu);
     CPUARMState *env = &cpu->env;
     CPUARMState *env = &cpu->env;
-    MemTxAttrs attrs = {};
     MemTxResult txres;
     MemTxResult txres;
-    target_ulong page_size;
-    hwaddr physaddr;
-    int prot;
+    GetPhysAddrResult res = {};
     ARMMMUFaultInfo fi = {};
     ARMMMUFaultInfo fi = {};
-    ARMCacheAttrs cacheattrs = {};
     bool secure = mmu_idx & ARM_MMU_IDX_M_S;
     bool secure = mmu_idx & ARM_MMU_IDX_M_S;
     int exc;
     int exc;
     bool exc_secure;
     bool exc_secure;
     uint32_t value;
     uint32_t value;
 
 
-    if (get_phys_addr(env, addr, MMU_DATA_LOAD, mmu_idx, &physaddr,
-                      &attrs, &prot, &page_size, &fi, &cacheattrs)) {
+    if (get_phys_addr(env, addr, MMU_DATA_LOAD, mmu_idx, &res, &fi)) {
         /* MPU/SAU lookup failed */
         /* MPU/SAU lookup failed */
         if (fi.type == ARMFault_QEMU_SFault) {
         if (fi.type == ARMFault_QEMU_SFault) {
             qemu_log_mask(CPU_LOG_INT,
             qemu_log_mask(CPU_LOG_INT,
@@ -308,8 +298,8 @@ static bool v7m_stack_read(ARMCPU *cpu, uint32_t *dest, uint32_t addr,
         goto pend_fault;
         goto pend_fault;
     }
     }
 
 
-    value = address_space_ldl(arm_addressspace(cs, attrs), physaddr,
-                              attrs, &txres);
+    value = address_space_ldl(arm_addressspace(cs, res.attrs), res.phys,
+                              res.attrs, &txres);
     if (txres != MEMTX_OK) {
     if (txres != MEMTX_OK) {
         /* BusFault trying to read the data */
         /* BusFault trying to read the data */
         qemu_log_mask(CPU_LOG_INT, "...BusFault with BFSR.UNSTKERR\n");
         qemu_log_mask(CPU_LOG_INT, "...BusFault with BFSR.UNSTKERR\n");
@@ -699,7 +689,8 @@ static bool arm_v7m_load_vector(ARMCPU *cpu, int exc, bool targets_secure,
     if (arm_feature(env, ARM_FEATURE_M_SECURITY)) {
     if (arm_feature(env, ARM_FEATURE_M_SECURITY)) {
         V8M_SAttributes sattrs = {};
         V8M_SAttributes sattrs = {};
 
 
-        v8m_security_lookup(env, addr, MMU_DATA_LOAD, mmu_idx, &sattrs);
+        v8m_security_lookup(env, addr, MMU_DATA_LOAD, mmu_idx,
+                            targets_secure, &sattrs);
         if (sattrs.ns) {
         if (sattrs.ns) {
             attrs.secure = false;
             attrs.secure = false;
         } else if (!targets_secure) {
         } else if (!targets_secure) {
@@ -2008,15 +1999,12 @@ static bool v7m_read_half_insn(ARMCPU *cpu, ARMMMUIdx mmu_idx,
     CPUState *cs = CPU(cpu);
     CPUState *cs = CPU(cpu);
     CPUARMState *env = &cpu->env;
     CPUARMState *env = &cpu->env;
     V8M_SAttributes sattrs = {};
     V8M_SAttributes sattrs = {};
-    MemTxAttrs attrs = {};
+    GetPhysAddrResult res = {};
     ARMMMUFaultInfo fi = {};
     ARMMMUFaultInfo fi = {};
-    ARMCacheAttrs cacheattrs = {};
     MemTxResult txres;
     MemTxResult txres;
-    target_ulong page_size;
-    hwaddr physaddr;
-    int prot;
 
 
-    v8m_security_lookup(env, addr, MMU_INST_FETCH, mmu_idx, &sattrs);
+    v8m_security_lookup(env, addr, MMU_INST_FETCH, mmu_idx,
+                        regime_is_secure(env, mmu_idx), &sattrs);
     if (!sattrs.nsc || sattrs.ns) {
     if (!sattrs.nsc || sattrs.ns) {
         /*
         /*
          * This must be the second half of the insn, and it straddles a
          * This must be the second half of the insn, and it straddles a
@@ -2028,16 +2016,15 @@ static bool v7m_read_half_insn(ARMCPU *cpu, ARMMMUIdx mmu_idx,
                       "...really SecureFault with SFSR.INVEP\n");
                       "...really SecureFault with SFSR.INVEP\n");
         return false;
         return false;
     }
     }
-    if (get_phys_addr(env, addr, MMU_INST_FETCH, mmu_idx, &physaddr,
-                      &attrs, &prot, &page_size, &fi, &cacheattrs)) {
+    if (get_phys_addr(env, addr, MMU_INST_FETCH, mmu_idx, &res, &fi)) {
         /* the MPU lookup failed */
         /* the MPU lookup failed */
         env->v7m.cfsr[env->v7m.secure] |= R_V7M_CFSR_IACCVIOL_MASK;
         env->v7m.cfsr[env->v7m.secure] |= R_V7M_CFSR_IACCVIOL_MASK;
         armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_MEM, env->v7m.secure);
         armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_MEM, env->v7m.secure);
         qemu_log_mask(CPU_LOG_INT, "...really MemManage with CFSR.IACCVIOL\n");
         qemu_log_mask(CPU_LOG_INT, "...really MemManage with CFSR.IACCVIOL\n");
         return false;
         return false;
     }
     }
-    *insn = address_space_lduw_le(arm_addressspace(cs, attrs), physaddr,
-                                 attrs, &txres);
+    *insn = address_space_lduw_le(arm_addressspace(cs, res.attrs), res.phys,
+                                  res.attrs, &txres);
     if (txres != MEMTX_OK) {
     if (txres != MEMTX_OK) {
         env->v7m.cfsr[M_REG_NS] |= R_V7M_CFSR_IBUSERR_MASK;
         env->v7m.cfsr[M_REG_NS] |= R_V7M_CFSR_IBUSERR_MASK;
         armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_BUS, false);
         armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_BUS, false);
@@ -2060,17 +2047,12 @@ static bool v7m_read_sg_stack_word(ARMCPU *cpu, ARMMMUIdx mmu_idx,
      */
      */
     CPUState *cs = CPU(cpu);
     CPUState *cs = CPU(cpu);
     CPUARMState *env = &cpu->env;
     CPUARMState *env = &cpu->env;
-    MemTxAttrs attrs = {};
     MemTxResult txres;
     MemTxResult txres;
-    target_ulong page_size;
-    hwaddr physaddr;
-    int prot;
+    GetPhysAddrResult res = {};
     ARMMMUFaultInfo fi = {};
     ARMMMUFaultInfo fi = {};
-    ARMCacheAttrs cacheattrs = {};
     uint32_t value;
     uint32_t value;
 
 
-    if (get_phys_addr(env, addr, MMU_DATA_LOAD, mmu_idx, &physaddr,
-                      &attrs, &prot, &page_size, &fi, &cacheattrs)) {
+    if (get_phys_addr(env, addr, MMU_DATA_LOAD, mmu_idx, &res, &fi)) {
         /* MPU/SAU lookup failed */
         /* MPU/SAU lookup failed */
         if (fi.type == ARMFault_QEMU_SFault) {
         if (fi.type == ARMFault_QEMU_SFault) {
             qemu_log_mask(CPU_LOG_INT,
             qemu_log_mask(CPU_LOG_INT,
@@ -2088,8 +2070,8 @@ static bool v7m_read_sg_stack_word(ARMCPU *cpu, ARMMMUIdx mmu_idx,
         }
         }
         return false;
         return false;
     }
     }
-    value = address_space_ldl(arm_addressspace(cs, attrs), physaddr,
-                              attrs, &txres);
+    value = address_space_ldl(arm_addressspace(cs, res.attrs), res.phys,
+                              res.attrs, &txres);
     if (txres != MEMTX_OK) {
     if (txres != MEMTX_OK) {
         /* BusFault trying to read the data */
         /* BusFault trying to read the data */
         qemu_log_mask(CPU_LOG_INT,
         qemu_log_mask(CPU_LOG_INT,
@@ -2790,15 +2772,10 @@ uint32_t HELPER(v7m_tt)(CPUARMState *env, uint32_t addr, uint32_t op)
     V8M_SAttributes sattrs = {};
     V8M_SAttributes sattrs = {};
     uint32_t tt_resp;
     uint32_t tt_resp;
     bool r, rw, nsr, nsrw, mrvalid;
     bool r, rw, nsr, nsrw, mrvalid;
-    int prot;
-    ARMMMUFaultInfo fi = {};
-    MemTxAttrs attrs = {};
-    hwaddr phys_addr;
     ARMMMUIdx mmu_idx;
     ARMMMUIdx mmu_idx;
     uint32_t mregion;
     uint32_t mregion;
     bool targetpriv;
     bool targetpriv;
     bool targetsec = env->v7m.secure;
     bool targetsec = env->v7m.secure;
-    bool is_subpage;
 
 
     /*
     /*
      * Work out what the security state and privilege level we're
      * Work out what the security state and privilege level we're
@@ -2829,18 +2806,20 @@ uint32_t HELPER(v7m_tt)(CPUARMState *env, uint32_t addr, uint32_t op)
      * inspecting the other MPU state.
      * inspecting the other MPU state.
      */
      */
     if (arm_current_el(env) != 0 || alt) {
     if (arm_current_el(env) != 0 || alt) {
+        GetPhysAddrResult res = {};
+        ARMMMUFaultInfo fi = {};
+
         /* We can ignore the return value as prot is always set */
         /* We can ignore the return value as prot is always set */
-        pmsav8_mpu_lookup(env, addr, MMU_DATA_LOAD, mmu_idx,
-                          &phys_addr, &attrs, &prot, &is_subpage,
-                          &fi, &mregion);
+        pmsav8_mpu_lookup(env, addr, MMU_DATA_LOAD, mmu_idx, targetsec,
+                          &res, &fi, &mregion);
         if (mregion == -1) {
         if (mregion == -1) {
             mrvalid = false;
             mrvalid = false;
             mregion = 0;
             mregion = 0;
         } else {
         } else {
             mrvalid = true;
             mrvalid = true;
         }
         }
-        r = prot & PAGE_READ;
-        rw = prot & PAGE_WRITE;
+        r = res.prot & PAGE_READ;
+        rw = res.prot & PAGE_WRITE;
     } else {
     } else {
         r = false;
         r = false;
         rw = false;
         rw = false;
@@ -2849,7 +2828,8 @@ uint32_t HELPER(v7m_tt)(CPUARMState *env, uint32_t addr, uint32_t op)
     }
     }
 
 
     if (env->v7m.secure) {
     if (env->v7m.secure) {
-        v8m_security_lookup(env, addr, MMU_DATA_LOAD, mmu_idx, &sattrs);
+        v8m_security_lookup(env, addr, MMU_DATA_LOAD, mmu_idx,
+                            targetsec, &sattrs);
         nsr = sattrs.ns && r;
         nsr = sattrs.ns && r;
         nsrw = sattrs.ns && rw;
         nsrw = sattrs.ns && rw;
     } else {
     } else {

+ 171 - 193
target/arm/ptw.c

@@ -16,10 +16,8 @@
 
 
 static bool get_phys_addr_lpae(CPUARMState *env, uint64_t address,
 static bool get_phys_addr_lpae(CPUARMState *env, uint64_t address,
                                MMUAccessType access_type, ARMMMUIdx mmu_idx,
                                MMUAccessType access_type, ARMMMUIdx mmu_idx,
-                               bool s1_is_el0, hwaddr *phys_ptr,
-                               MemTxAttrs *txattrs, int *prot,
-                               target_ulong *page_size_ptr,
-                               ARMMMUFaultInfo *fi, ARMCacheAttrs *cacheattrs)
+                               bool s1_is_el0, GetPhysAddrResult *result,
+                               ARMMMUFaultInfo *fi)
     __attribute__((nonnull));
     __attribute__((nonnull));
 
 
 /* This mapping is common between ID_AA64MMFR0.PARANGE and TCR_ELx.{I}PS. */
 /* This mapping is common between ID_AA64MMFR0.PARANGE and TCR_ELx.{I}PS. */
@@ -204,18 +202,13 @@ static hwaddr S1_ptw_translate(CPUARMState *env, ARMMMUIdx mmu_idx,
 {
 {
     if (arm_mmu_idx_is_stage1_of_2(mmu_idx) &&
     if (arm_mmu_idx_is_stage1_of_2(mmu_idx) &&
         !regime_translation_disabled(env, ARMMMUIdx_Stage2)) {
         !regime_translation_disabled(env, ARMMMUIdx_Stage2)) {
-        target_ulong s2size;
-        hwaddr s2pa;
-        int s2prot;
-        int ret;
         ARMMMUIdx s2_mmu_idx = *is_secure ? ARMMMUIdx_Stage2_S
         ARMMMUIdx s2_mmu_idx = *is_secure ? ARMMMUIdx_Stage2_S
                                           : ARMMMUIdx_Stage2;
                                           : ARMMMUIdx_Stage2;
-        ARMCacheAttrs cacheattrs = {};
-        MemTxAttrs txattrs = {};
+        GetPhysAddrResult s2 = {};
+        int ret;
 
 
         ret = get_phys_addr_lpae(env, addr, MMU_DATA_LOAD, s2_mmu_idx, false,
         ret = get_phys_addr_lpae(env, addr, MMU_DATA_LOAD, s2_mmu_idx, false,
-                                 &s2pa, &txattrs, &s2prot, &s2size, fi,
-                                 &cacheattrs);
+                                 &s2, fi);
         if (ret) {
         if (ret) {
             assert(fi->type != ARMFault_None);
             assert(fi->type != ARMFault_None);
             fi->s2addr = addr;
             fi->s2addr = addr;
@@ -225,7 +218,7 @@ static hwaddr S1_ptw_translate(CPUARMState *env, ARMMMUIdx mmu_idx,
             return ~0;
             return ~0;
         }
         }
         if ((arm_hcr_el2_eff(env) & HCR_PTW) &&
         if ((arm_hcr_el2_eff(env) & HCR_PTW) &&
-            ptw_attrs_are_device(env, cacheattrs)) {
+            ptw_attrs_are_device(env, s2.cacheattrs)) {
             /*
             /*
              * PTW set and S1 walk touched S2 Device memory:
              * PTW set and S1 walk touched S2 Device memory:
              * generate Permission fault.
              * generate Permission fault.
@@ -249,7 +242,7 @@ static hwaddr S1_ptw_translate(CPUARMState *env, ARMMMUIdx mmu_idx,
             assert(!*is_secure);
             assert(!*is_secure);
         }
         }
 
 
-        addr = s2pa;
+        addr = s2.phys;
     }
     }
     return addr;
     return addr;
 }
 }
@@ -421,8 +414,7 @@ static int simple_ap_to_rw_prot(CPUARMState *env, ARMMMUIdx mmu_idx, int ap)
 
 
 static bool get_phys_addr_v5(CPUARMState *env, uint32_t address,
 static bool get_phys_addr_v5(CPUARMState *env, uint32_t address,
                              MMUAccessType access_type, ARMMMUIdx mmu_idx,
                              MMUAccessType access_type, ARMMMUIdx mmu_idx,
-                             hwaddr *phys_ptr, int *prot,
-                             target_ulong *page_size,
+                             bool is_secure, GetPhysAddrResult *result,
                              ARMMMUFaultInfo *fi)
                              ARMMMUFaultInfo *fi)
 {
 {
     int level = 1;
     int level = 1;
@@ -442,8 +434,7 @@ static bool get_phys_addr_v5(CPUARMState *env, uint32_t address,
         fi->type = ARMFault_Translation;
         fi->type = ARMFault_Translation;
         goto do_fault;
         goto do_fault;
     }
     }
-    desc = arm_ldl_ptw(env, table, regime_is_secure(env, mmu_idx),
-                       mmu_idx, fi);
+    desc = arm_ldl_ptw(env, table, is_secure, mmu_idx, fi);
     if (fi->type != ARMFault_None) {
     if (fi->type != ARMFault_None) {
         goto do_fault;
         goto do_fault;
     }
     }
@@ -471,7 +462,7 @@ static bool get_phys_addr_v5(CPUARMState *env, uint32_t address,
         /* 1Mb section.  */
         /* 1Mb section.  */
         phys_addr = (desc & 0xfff00000) | (address & 0x000fffff);
         phys_addr = (desc & 0xfff00000) | (address & 0x000fffff);
         ap = (desc >> 10) & 3;
         ap = (desc >> 10) & 3;
-        *page_size = 1024 * 1024;
+        result->page_size = 1024 * 1024;
     } else {
     } else {
         /* Lookup l2 entry.  */
         /* Lookup l2 entry.  */
         if (type == 1) {
         if (type == 1) {
@@ -481,8 +472,7 @@ static bool get_phys_addr_v5(CPUARMState *env, uint32_t address,
             /* Fine pagetable.  */
             /* Fine pagetable.  */
             table = (desc & 0xfffff000) | ((address >> 8) & 0xffc);
             table = (desc & 0xfffff000) | ((address >> 8) & 0xffc);
         }
         }
-        desc = arm_ldl_ptw(env, table, regime_is_secure(env, mmu_idx),
-                           mmu_idx, fi);
+        desc = arm_ldl_ptw(env, table, is_secure, mmu_idx, fi);
         if (fi->type != ARMFault_None) {
         if (fi->type != ARMFault_None) {
             goto do_fault;
             goto do_fault;
         }
         }
@@ -493,12 +483,12 @@ static bool get_phys_addr_v5(CPUARMState *env, uint32_t address,
         case 1: /* 64k page.  */
         case 1: /* 64k page.  */
             phys_addr = (desc & 0xffff0000) | (address & 0xffff);
             phys_addr = (desc & 0xffff0000) | (address & 0xffff);
             ap = (desc >> (4 + ((address >> 13) & 6))) & 3;
             ap = (desc >> (4 + ((address >> 13) & 6))) & 3;
-            *page_size = 0x10000;
+            result->page_size = 0x10000;
             break;
             break;
         case 2: /* 4k page.  */
         case 2: /* 4k page.  */
             phys_addr = (desc & 0xfffff000) | (address & 0xfff);
             phys_addr = (desc & 0xfffff000) | (address & 0xfff);
             ap = (desc >> (4 + ((address >> 9) & 6))) & 3;
             ap = (desc >> (4 + ((address >> 9) & 6))) & 3;
-            *page_size = 0x1000;
+            result->page_size = 0x1000;
             break;
             break;
         case 3: /* 1k page, or ARMv6/XScale "extended small (4k) page" */
         case 3: /* 1k page, or ARMv6/XScale "extended small (4k) page" */
             if (type == 1) {
             if (type == 1) {
@@ -506,7 +496,7 @@ static bool get_phys_addr_v5(CPUARMState *env, uint32_t address,
                 if (arm_feature(env, ARM_FEATURE_XSCALE)
                 if (arm_feature(env, ARM_FEATURE_XSCALE)
                     || arm_feature(env, ARM_FEATURE_V6)) {
                     || arm_feature(env, ARM_FEATURE_V6)) {
                     phys_addr = (desc & 0xfffff000) | (address & 0xfff);
                     phys_addr = (desc & 0xfffff000) | (address & 0xfff);
-                    *page_size = 0x1000;
+                    result->page_size = 0x1000;
                 } else {
                 } else {
                     /*
                     /*
                      * UNPREDICTABLE in ARMv5; we choose to take a
                      * UNPREDICTABLE in ARMv5; we choose to take a
@@ -517,7 +507,7 @@ static bool get_phys_addr_v5(CPUARMState *env, uint32_t address,
                 }
                 }
             } else {
             } else {
                 phys_addr = (desc & 0xfffffc00) | (address & 0x3ff);
                 phys_addr = (desc & 0xfffffc00) | (address & 0x3ff);
-                *page_size = 0x400;
+                result->page_size = 0x400;
             }
             }
             ap = (desc >> 4) & 3;
             ap = (desc >> 4) & 3;
             break;
             break;
@@ -526,14 +516,14 @@ static bool get_phys_addr_v5(CPUARMState *env, uint32_t address,
             g_assert_not_reached();
             g_assert_not_reached();
         }
         }
     }
     }
-    *prot = ap_to_rw_prot(env, mmu_idx, ap, domain_prot);
-    *prot |= *prot ? PAGE_EXEC : 0;
-    if (!(*prot & (1 << access_type))) {
+    result->prot = ap_to_rw_prot(env, mmu_idx, ap, domain_prot);
+    result->prot |= result->prot ? PAGE_EXEC : 0;
+    if (!(result->prot & (1 << access_type))) {
         /* Access permission fault.  */
         /* Access permission fault.  */
         fi->type = ARMFault_Permission;
         fi->type = ARMFault_Permission;
         goto do_fault;
         goto do_fault;
     }
     }
-    *phys_ptr = phys_addr;
+    result->phys = phys_addr;
     return false;
     return false;
 do_fault:
 do_fault:
     fi->domain = domain;
     fi->domain = domain;
@@ -543,8 +533,8 @@ do_fault:
 
 
 static bool get_phys_addr_v6(CPUARMState *env, uint32_t address,
 static bool get_phys_addr_v6(CPUARMState *env, uint32_t address,
                              MMUAccessType access_type, ARMMMUIdx mmu_idx,
                              MMUAccessType access_type, ARMMMUIdx mmu_idx,
-                             hwaddr *phys_ptr, MemTxAttrs *attrs, int *prot,
-                             target_ulong *page_size, ARMMMUFaultInfo *fi)
+                             bool is_secure, GetPhysAddrResult *result,
+                             ARMMMUFaultInfo *fi)
 {
 {
     ARMCPU *cpu = env_archcpu(env);
     ARMCPU *cpu = env_archcpu(env);
     int level = 1;
     int level = 1;
@@ -567,8 +557,7 @@ static bool get_phys_addr_v6(CPUARMState *env, uint32_t address,
         fi->type = ARMFault_Translation;
         fi->type = ARMFault_Translation;
         goto do_fault;
         goto do_fault;
     }
     }
-    desc = arm_ldl_ptw(env, table, regime_is_secure(env, mmu_idx),
-                       mmu_idx, fi);
+    desc = arm_ldl_ptw(env, table, is_secure, mmu_idx, fi);
     if (fi->type != ARMFault_None) {
     if (fi->type != ARMFault_None) {
         goto do_fault;
         goto do_fault;
     }
     }
@@ -604,11 +593,11 @@ static bool get_phys_addr_v6(CPUARMState *env, uint32_t address,
             phys_addr = (desc & 0xff000000) | (address & 0x00ffffff);
             phys_addr = (desc & 0xff000000) | (address & 0x00ffffff);
             phys_addr |= (uint64_t)extract32(desc, 20, 4) << 32;
             phys_addr |= (uint64_t)extract32(desc, 20, 4) << 32;
             phys_addr |= (uint64_t)extract32(desc, 5, 4) << 36;
             phys_addr |= (uint64_t)extract32(desc, 5, 4) << 36;
-            *page_size = 0x1000000;
+            result->page_size = 0x1000000;
         } else {
         } else {
             /* Section.  */
             /* Section.  */
             phys_addr = (desc & 0xfff00000) | (address & 0x000fffff);
             phys_addr = (desc & 0xfff00000) | (address & 0x000fffff);
-            *page_size = 0x100000;
+            result->page_size = 0x100000;
         }
         }
         ap = ((desc >> 10) & 3) | ((desc >> 13) & 4);
         ap = ((desc >> 10) & 3) | ((desc >> 13) & 4);
         xn = desc & (1 << 4);
         xn = desc & (1 << 4);
@@ -621,8 +610,7 @@ static bool get_phys_addr_v6(CPUARMState *env, uint32_t address,
         ns = extract32(desc, 3, 1);
         ns = extract32(desc, 3, 1);
         /* Lookup l2 entry.  */
         /* Lookup l2 entry.  */
         table = (desc & 0xfffffc00) | ((address >> 10) & 0x3fc);
         table = (desc & 0xfffffc00) | ((address >> 10) & 0x3fc);
-        desc = arm_ldl_ptw(env, table, regime_is_secure(env, mmu_idx),
-                           mmu_idx, fi);
+        desc = arm_ldl_ptw(env, table, is_secure, mmu_idx, fi);
         if (fi->type != ARMFault_None) {
         if (fi->type != ARMFault_None) {
             goto do_fault;
             goto do_fault;
         }
         }
@@ -634,12 +622,12 @@ static bool get_phys_addr_v6(CPUARMState *env, uint32_t address,
         case 1: /* 64k page.  */
         case 1: /* 64k page.  */
             phys_addr = (desc & 0xffff0000) | (address & 0xffff);
             phys_addr = (desc & 0xffff0000) | (address & 0xffff);
             xn = desc & (1 << 15);
             xn = desc & (1 << 15);
-            *page_size = 0x10000;
+            result->page_size = 0x10000;
             break;
             break;
         case 2: case 3: /* 4k page.  */
         case 2: case 3: /* 4k page.  */
             phys_addr = (desc & 0xfffff000) | (address & 0xfff);
             phys_addr = (desc & 0xfffff000) | (address & 0xfff);
             xn = desc & 1;
             xn = desc & 1;
-            *page_size = 0x1000;
+            result->page_size = 0x1000;
             break;
             break;
         default:
         default:
             /* Never happens, but compiler isn't smart enough to tell.  */
             /* Never happens, but compiler isn't smart enough to tell.  */
@@ -647,7 +635,7 @@ static bool get_phys_addr_v6(CPUARMState *env, uint32_t address,
         }
         }
     }
     }
     if (domain_prot == 3) {
     if (domain_prot == 3) {
-        *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
+        result->prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
     } else {
     } else {
         if (pxn && !regime_is_user(env, mmu_idx)) {
         if (pxn && !regime_is_user(env, mmu_idx)) {
             xn = 1;
             xn = 1;
@@ -665,14 +653,14 @@ static bool get_phys_addr_v6(CPUARMState *env, uint32_t address,
                 fi->type = ARMFault_AccessFlag;
                 fi->type = ARMFault_AccessFlag;
                 goto do_fault;
                 goto do_fault;
             }
             }
-            *prot = simple_ap_to_rw_prot(env, mmu_idx, ap >> 1);
+            result->prot = simple_ap_to_rw_prot(env, mmu_idx, ap >> 1);
         } else {
         } else {
-            *prot = ap_to_rw_prot(env, mmu_idx, ap, domain_prot);
+            result->prot = ap_to_rw_prot(env, mmu_idx, ap, domain_prot);
         }
         }
-        if (*prot && !xn) {
-            *prot |= PAGE_EXEC;
+        if (result->prot && !xn) {
+            result->prot |= PAGE_EXEC;
         }
         }
-        if (!(*prot & (1 << access_type))) {
+        if (!(result->prot & (1 << access_type))) {
             /* Access permission fault.  */
             /* Access permission fault.  */
             fi->type = ARMFault_Permission;
             fi->type = ARMFault_Permission;
             goto do_fault;
             goto do_fault;
@@ -683,9 +671,9 @@ static bool get_phys_addr_v6(CPUARMState *env, uint32_t address,
          * the CPU doesn't support TZ or this is a non-secure translation
          * the CPU doesn't support TZ or this is a non-secure translation
          * regime, because the attribute will already be non-secure.
          * regime, because the attribute will already be non-secure.
          */
          */
-        attrs->secure = false;
+        result->attrs.secure = false;
     }
     }
-    *phys_ptr = phys_addr;
+    result->phys = phys_addr;
     return false;
     return false;
 do_fault:
 do_fault:
     fi->domain = domain;
     fi->domain = domain;
@@ -972,19 +960,13 @@ static bool check_s2_mmu_setup(ARMCPU *cpu, bool is_aa64, int level,
  *             table walk), must be true if this is stage 2 of a stage 1+2
  *             table walk), must be true if this is stage 2 of a stage 1+2
  *             walk for an EL0 access. If @mmu_idx is anything else,
  *             walk for an EL0 access. If @mmu_idx is anything else,
  *             @s1_is_el0 is ignored.
  *             @s1_is_el0 is ignored.
- * @phys_ptr: set to the physical address corresponding to the virtual address
- * @attrs: set to the memory transaction attributes to use
- * @prot: set to the permissions for the page containing phys_ptr
- * @page_size_ptr: set to the size of the page containing phys_ptr
+ * @result: set on translation success,
  * @fi: set to fault info if the translation fails
  * @fi: set to fault info if the translation fails
- * @cacheattrs: (if non-NULL) set to the cacheability/shareability attributes
  */
  */
 static bool get_phys_addr_lpae(CPUARMState *env, uint64_t address,
 static bool get_phys_addr_lpae(CPUARMState *env, uint64_t address,
                                MMUAccessType access_type, ARMMMUIdx mmu_idx,
                                MMUAccessType access_type, ARMMMUIdx mmu_idx,
-                               bool s1_is_el0, hwaddr *phys_ptr,
-                               MemTxAttrs *txattrs, int *prot,
-                               target_ulong *page_size_ptr,
-                               ARMMMUFaultInfo *fi, ARMCacheAttrs *cacheattrs)
+                               bool s1_is_el0, GetPhysAddrResult *result,
+                               ARMMMUFaultInfo *fi)
 {
 {
     ARMCPU *cpu = env_archcpu(env);
     ARMCPU *cpu = env_archcpu(env);
     /* Read an LPAE long-descriptor translation table. */
     /* Read an LPAE long-descriptor translation table. */
@@ -1302,16 +1284,16 @@ static bool get_phys_addr_lpae(CPUARMState *env, uint64_t address,
     if (mmu_idx == ARMMMUIdx_Stage2 || mmu_idx == ARMMMUIdx_Stage2_S) {
     if (mmu_idx == ARMMMUIdx_Stage2 || mmu_idx == ARMMMUIdx_Stage2_S) {
         ns = mmu_idx == ARMMMUIdx_Stage2;
         ns = mmu_idx == ARMMMUIdx_Stage2;
         xn = extract32(attrs, 11, 2);
         xn = extract32(attrs, 11, 2);
-        *prot = get_S2prot(env, ap, xn, s1_is_el0);
+        result->prot = get_S2prot(env, ap, xn, s1_is_el0);
     } else {
     } else {
         ns = extract32(attrs, 3, 1);
         ns = extract32(attrs, 3, 1);
         xn = extract32(attrs, 12, 1);
         xn = extract32(attrs, 12, 1);
         pxn = extract32(attrs, 11, 1);
         pxn = extract32(attrs, 11, 1);
-        *prot = get_S1prot(env, mmu_idx, aarch64, ap, ns, xn, pxn);
+        result->prot = get_S1prot(env, mmu_idx, aarch64, ap, ns, xn, pxn);
     }
     }
 
 
     fault_type = ARMFault_Permission;
     fault_type = ARMFault_Permission;
-    if (!(*prot & (1 << access_type))) {
+    if (!(result->prot & (1 << access_type))) {
         goto do_fault;
         goto do_fault;
     }
     }
 
 
@@ -1321,23 +1303,23 @@ static bool get_phys_addr_lpae(CPUARMState *env, uint64_t address,
          * the CPU doesn't support TZ or this is a non-secure translation
          * the CPU doesn't support TZ or this is a non-secure translation
          * regime, because the attribute will already be non-secure.
          * regime, because the attribute will already be non-secure.
          */
          */
-        txattrs->secure = false;
+        result->attrs.secure = false;
     }
     }
     /* When in aarch64 mode, and BTI is enabled, remember GP in the IOTLB.  */
     /* When in aarch64 mode, and BTI is enabled, remember GP in the IOTLB.  */
     if (aarch64 && guarded && cpu_isar_feature(aa64_bti, cpu)) {
     if (aarch64 && guarded && cpu_isar_feature(aa64_bti, cpu)) {
-        arm_tlb_bti_gp(txattrs) = true;
+        arm_tlb_bti_gp(&result->attrs) = true;
     }
     }
 
 
     if (mmu_idx == ARMMMUIdx_Stage2 || mmu_idx == ARMMMUIdx_Stage2_S) {
     if (mmu_idx == ARMMMUIdx_Stage2 || mmu_idx == ARMMMUIdx_Stage2_S) {
-        cacheattrs->is_s2_format = true;
-        cacheattrs->attrs = extract32(attrs, 0, 4);
+        result->cacheattrs.is_s2_format = true;
+        result->cacheattrs.attrs = extract32(attrs, 0, 4);
     } else {
     } else {
         /* Index into MAIR registers for cache attributes */
         /* Index into MAIR registers for cache attributes */
         uint8_t attrindx = extract32(attrs, 0, 3);
         uint8_t attrindx = extract32(attrs, 0, 3);
         uint64_t mair = env->cp15.mair_el[regime_el(env, mmu_idx)];
         uint64_t mair = env->cp15.mair_el[regime_el(env, mmu_idx)];
         assert(attrindx <= 7);
         assert(attrindx <= 7);
-        cacheattrs->is_s2_format = false;
-        cacheattrs->attrs = extract64(mair, attrindx * 8, 8);
+        result->cacheattrs.is_s2_format = false;
+        result->cacheattrs.attrs = extract64(mair, attrindx * 8, 8);
     }
     }
 
 
     /*
     /*
@@ -1346,13 +1328,13 @@ static bool get_phys_addr_lpae(CPUARMState *env, uint64_t address,
      * that case comes from TCR_ELx, which we extracted earlier.
      * that case comes from TCR_ELx, which we extracted earlier.
      */
      */
     if (param.ds) {
     if (param.ds) {
-        cacheattrs->shareability = param.sh;
+        result->cacheattrs.shareability = param.sh;
     } else {
     } else {
-        cacheattrs->shareability = extract32(attrs, 6, 2);
+        result->cacheattrs.shareability = extract32(attrs, 6, 2);
     }
     }
 
 
-    *phys_ptr = descaddr;
-    *page_size_ptr = page_size;
+    result->phys = descaddr;
+    result->page_size = page_size;
     return false;
     return false;
 
 
 do_fault:
 do_fault:
@@ -1367,7 +1349,7 @@ do_fault:
 
 
 static bool get_phys_addr_pmsav5(CPUARMState *env, uint32_t address,
 static bool get_phys_addr_pmsav5(CPUARMState *env, uint32_t address,
                                  MMUAccessType access_type, ARMMMUIdx mmu_idx,
                                  MMUAccessType access_type, ARMMMUIdx mmu_idx,
-                                 hwaddr *phys_ptr, int *prot,
+                                 bool is_secure, GetPhysAddrResult *result,
                                  ARMMMUFaultInfo *fi)
                                  ARMMMUFaultInfo *fi)
 {
 {
     int n;
     int n;
@@ -1377,12 +1359,12 @@ static bool get_phys_addr_pmsav5(CPUARMState *env, uint32_t address,
 
 
     if (regime_translation_disabled(env, mmu_idx)) {
     if (regime_translation_disabled(env, mmu_idx)) {
         /* MPU disabled.  */
         /* MPU disabled.  */
-        *phys_ptr = address;
-        *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
+        result->phys = address;
+        result->prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
         return false;
         return false;
     }
     }
 
 
-    *phys_ptr = address;
+    result->phys = address;
     for (n = 7; n >= 0; n--) {
     for (n = 7; n >= 0; n--) {
         base = env->cp15.c6_region[n];
         base = env->cp15.c6_region[n];
         if ((base & 1) == 0) {
         if ((base & 1) == 0) {
@@ -1418,16 +1400,16 @@ static bool get_phys_addr_pmsav5(CPUARMState *env, uint32_t address,
             fi->level = 1;
             fi->level = 1;
             return true;
             return true;
         }
         }
-        *prot = PAGE_READ | PAGE_WRITE;
+        result->prot = PAGE_READ | PAGE_WRITE;
         break;
         break;
     case 2:
     case 2:
-        *prot = PAGE_READ;
+        result->prot = PAGE_READ;
         if (!is_user) {
         if (!is_user) {
-            *prot |= PAGE_WRITE;
+            result->prot |= PAGE_WRITE;
         }
         }
         break;
         break;
     case 3:
     case 3:
-        *prot = PAGE_READ | PAGE_WRITE;
+        result->prot = PAGE_READ | PAGE_WRITE;
         break;
         break;
     case 5:
     case 5:
         if (is_user) {
         if (is_user) {
@@ -1435,10 +1417,10 @@ static bool get_phys_addr_pmsav5(CPUARMState *env, uint32_t address,
             fi->level = 1;
             fi->level = 1;
             return true;
             return true;
         }
         }
-        *prot = PAGE_READ;
+        result->prot = PAGE_READ;
         break;
         break;
     case 6:
     case 6:
-        *prot = PAGE_READ;
+        result->prot = PAGE_READ;
         break;
         break;
     default:
     default:
         /* Bad permission.  */
         /* Bad permission.  */
@@ -1446,7 +1428,7 @@ static bool get_phys_addr_pmsav5(CPUARMState *env, uint32_t address,
         fi->level = 1;
         fi->level = 1;
         return true;
         return true;
     }
     }
-    *prot |= PAGE_EXEC;
+    result->prot |= PAGE_EXEC;
     return false;
     return false;
 }
 }
 
 
@@ -1507,7 +1489,7 @@ static bool m_is_system_region(CPUARMState *env, uint32_t address)
 }
 }
 
 
 static bool pmsav7_use_background_region(ARMCPU *cpu, ARMMMUIdx mmu_idx,
 static bool pmsav7_use_background_region(ARMCPU *cpu, ARMMMUIdx mmu_idx,
-                                         bool is_user)
+                                         bool is_secure, bool is_user)
 {
 {
     /*
     /*
      * Return true if we should use the default memory map as a
      * Return true if we should use the default memory map as a
@@ -1520,8 +1502,7 @@ static bool pmsav7_use_background_region(ARMCPU *cpu, ARMMMUIdx mmu_idx,
     }
     }
 
 
     if (arm_feature(env, ARM_FEATURE_M)) {
     if (arm_feature(env, ARM_FEATURE_M)) {
-        return env->v7m.mpu_ctrl[regime_is_secure(env, mmu_idx)]
-            & R_V7M_MPU_CTRL_PRIVDEFENA_MASK;
+        return env->v7m.mpu_ctrl[is_secure] & R_V7M_MPU_CTRL_PRIVDEFENA_MASK;
     } else {
     } else {
         return regime_sctlr(env, mmu_idx) & SCTLR_BR;
         return regime_sctlr(env, mmu_idx) & SCTLR_BR;
     }
     }
@@ -1529,17 +1510,16 @@ static bool pmsav7_use_background_region(ARMCPU *cpu, ARMMMUIdx mmu_idx,
 
 
 static bool get_phys_addr_pmsav7(CPUARMState *env, uint32_t address,
 static bool get_phys_addr_pmsav7(CPUARMState *env, uint32_t address,
                                  MMUAccessType access_type, ARMMMUIdx mmu_idx,
                                  MMUAccessType access_type, ARMMMUIdx mmu_idx,
-                                 hwaddr *phys_ptr, int *prot,
-                                 target_ulong *page_size,
+                                 bool secure, GetPhysAddrResult *result,
                                  ARMMMUFaultInfo *fi)
                                  ARMMMUFaultInfo *fi)
 {
 {
     ARMCPU *cpu = env_archcpu(env);
     ARMCPU *cpu = env_archcpu(env);
     int n;
     int n;
     bool is_user = regime_is_user(env, mmu_idx);
     bool is_user = regime_is_user(env, mmu_idx);
 
 
-    *phys_ptr = address;
-    *page_size = TARGET_PAGE_SIZE;
-    *prot = 0;
+    result->phys = address;
+    result->page_size = TARGET_PAGE_SIZE;
+    result->prot = 0;
 
 
     if (regime_translation_disabled(env, mmu_idx) ||
     if (regime_translation_disabled(env, mmu_idx) ||
         m_is_ppb_region(env, address)) {
         m_is_ppb_region(env, address)) {
@@ -1551,7 +1531,7 @@ static bool get_phys_addr_pmsav7(CPUARMState *env, uint32_t address,
          * which always does a direct read using address_space_ldl(), rather
          * which always does a direct read using address_space_ldl(), rather
          * than going via this function, so we don't need to check that here.
          * than going via this function, so we don't need to check that here.
          */
          */
-        get_phys_addr_pmsav7_default(env, mmu_idx, address, prot);
+        get_phys_addr_pmsav7_default(env, mmu_idx, address, &result->prot);
     } else { /* MPU enabled */
     } else { /* MPU enabled */
         for (n = (int)cpu->pmsav7_dregion - 1; n >= 0; n--) {
         for (n = (int)cpu->pmsav7_dregion - 1; n >= 0; n--) {
             /* region search */
             /* region search */
@@ -1593,7 +1573,7 @@ static bool get_phys_addr_pmsav7(CPUARMState *env, uint32_t address,
                 if (ranges_overlap(base, rmask,
                 if (ranges_overlap(base, rmask,
                                    address & TARGET_PAGE_MASK,
                                    address & TARGET_PAGE_MASK,
                                    TARGET_PAGE_SIZE)) {
                                    TARGET_PAGE_SIZE)) {
-                    *page_size = 1;
+                    result->page_size = 1;
                 }
                 }
                 continue;
                 continue;
             }
             }
@@ -1631,18 +1611,18 @@ static bool get_phys_addr_pmsav7(CPUARMState *env, uint32_t address,
                 continue;
                 continue;
             }
             }
             if (rsize < TARGET_PAGE_BITS) {
             if (rsize < TARGET_PAGE_BITS) {
-                *page_size = 1 << rsize;
+                result->page_size = 1 << rsize;
             }
             }
             break;
             break;
         }
         }
 
 
         if (n == -1) { /* no hits */
         if (n == -1) { /* no hits */
-            if (!pmsav7_use_background_region(cpu, mmu_idx, is_user)) {
+            if (!pmsav7_use_background_region(cpu, mmu_idx, secure, is_user)) {
                 /* background fault */
                 /* background fault */
                 fi->type = ARMFault_Background;
                 fi->type = ARMFault_Background;
                 return true;
                 return true;
             }
             }
-            get_phys_addr_pmsav7_default(env, mmu_idx, address, prot);
+            get_phys_addr_pmsav7_default(env, mmu_idx, address, &result->prot);
         } else { /* a MPU hit! */
         } else { /* a MPU hit! */
             uint32_t ap = extract32(env->pmsav7.dracr[n], 8, 3);
             uint32_t ap = extract32(env->pmsav7.dracr[n], 8, 3);
             uint32_t xn = extract32(env->pmsav7.dracr[n], 12, 1);
             uint32_t xn = extract32(env->pmsav7.dracr[n], 12, 1);
@@ -1659,16 +1639,16 @@ static bool get_phys_addr_pmsav7(CPUARMState *env, uint32_t address,
                 case 5:
                 case 5:
                     break; /* no access */
                     break; /* no access */
                 case 3:
                 case 3:
-                    *prot |= PAGE_WRITE;
+                    result->prot |= PAGE_WRITE;
                     /* fall through */
                     /* fall through */
                 case 2:
                 case 2:
                 case 6:
                 case 6:
-                    *prot |= PAGE_READ | PAGE_EXEC;
+                    result->prot |= PAGE_READ | PAGE_EXEC;
                     break;
                     break;
                 case 7:
                 case 7:
                     /* for v7M, same as 6; for R profile a reserved value */
                     /* for v7M, same as 6; for R profile a reserved value */
                     if (arm_feature(env, ARM_FEATURE_M)) {
                     if (arm_feature(env, ARM_FEATURE_M)) {
-                        *prot |= PAGE_READ | PAGE_EXEC;
+                        result->prot |= PAGE_READ | PAGE_EXEC;
                         break;
                         break;
                     }
                     }
                     /* fall through */
                     /* fall through */
@@ -1684,16 +1664,16 @@ static bool get_phys_addr_pmsav7(CPUARMState *env, uint32_t address,
                 case 1:
                 case 1:
                 case 2:
                 case 2:
                 case 3:
                 case 3:
-                    *prot |= PAGE_WRITE;
+                    result->prot |= PAGE_WRITE;
                     /* fall through */
                     /* fall through */
                 case 5:
                 case 5:
                 case 6:
                 case 6:
-                    *prot |= PAGE_READ | PAGE_EXEC;
+                    result->prot |= PAGE_READ | PAGE_EXEC;
                     break;
                     break;
                 case 7:
                 case 7:
                     /* for v7M, same as 6; for R profile a reserved value */
                     /* for v7M, same as 6; for R profile a reserved value */
                     if (arm_feature(env, ARM_FEATURE_M)) {
                     if (arm_feature(env, ARM_FEATURE_M)) {
-                        *prot |= PAGE_READ | PAGE_EXEC;
+                        result->prot |= PAGE_READ | PAGE_EXEC;
                         break;
                         break;
                     }
                     }
                     /* fall through */
                     /* fall through */
@@ -1706,20 +1686,19 @@ static bool get_phys_addr_pmsav7(CPUARMState *env, uint32_t address,
 
 
             /* execute never */
             /* execute never */
             if (xn) {
             if (xn) {
-                *prot &= ~PAGE_EXEC;
+                result->prot &= ~PAGE_EXEC;
             }
             }
         }
         }
     }
     }
 
 
     fi->type = ARMFault_Permission;
     fi->type = ARMFault_Permission;
     fi->level = 1;
     fi->level = 1;
-    return !(*prot & (1 << access_type));
+    return !(result->prot & (1 << access_type));
 }
 }
 
 
 bool pmsav8_mpu_lookup(CPUARMState *env, uint32_t address,
 bool pmsav8_mpu_lookup(CPUARMState *env, uint32_t address,
                        MMUAccessType access_type, ARMMMUIdx mmu_idx,
                        MMUAccessType access_type, ARMMMUIdx mmu_idx,
-                       hwaddr *phys_ptr, MemTxAttrs *txattrs,
-                       int *prot, bool *is_subpage,
+                       bool secure, GetPhysAddrResult *result,
                        ARMMMUFaultInfo *fi, uint32_t *mregion)
                        ARMMMUFaultInfo *fi, uint32_t *mregion)
 {
 {
     /*
     /*
@@ -1728,21 +1707,21 @@ bool pmsav8_mpu_lookup(CPUARMState *env, uint32_t address,
      * mregion is (if not NULL) set to the region number which matched,
      * mregion is (if not NULL) set to the region number which matched,
      * or -1 if no region number is returned (MPU off, address did not
      * or -1 if no region number is returned (MPU off, address did not
      * hit a region, address hit in multiple regions).
      * hit a region, address hit in multiple regions).
-     * We set is_subpage to true if the region hit doesn't cover the
-     * entire TARGET_PAGE the address is within.
+     * If the region hit doesn't cover the entire TARGET_PAGE the address
+     * is within, then we set the result page_size to 1 to force the
+     * memory system to use a subpage.
      */
      */
     ARMCPU *cpu = env_archcpu(env);
     ARMCPU *cpu = env_archcpu(env);
     bool is_user = regime_is_user(env, mmu_idx);
     bool is_user = regime_is_user(env, mmu_idx);
-    uint32_t secure = regime_is_secure(env, mmu_idx);
     int n;
     int n;
     int matchregion = -1;
     int matchregion = -1;
     bool hit = false;
     bool hit = false;
     uint32_t addr_page_base = address & TARGET_PAGE_MASK;
     uint32_t addr_page_base = address & TARGET_PAGE_MASK;
     uint32_t addr_page_limit = addr_page_base + (TARGET_PAGE_SIZE - 1);
     uint32_t addr_page_limit = addr_page_base + (TARGET_PAGE_SIZE - 1);
 
 
-    *is_subpage = false;
-    *phys_ptr = address;
-    *prot = 0;
+    result->page_size = TARGET_PAGE_SIZE;
+    result->phys = address;
+    result->prot = 0;
     if (mregion) {
     if (mregion) {
         *mregion = -1;
         *mregion = -1;
     }
     }
@@ -1759,7 +1738,7 @@ bool pmsav8_mpu_lookup(CPUARMState *env, uint32_t address,
     } else if (m_is_ppb_region(env, address)) {
     } else if (m_is_ppb_region(env, address)) {
         hit = true;
         hit = true;
     } else {
     } else {
-        if (pmsav7_use_background_region(cpu, mmu_idx, is_user)) {
+        if (pmsav7_use_background_region(cpu, mmu_idx, secure, is_user)) {
             hit = true;
             hit = true;
         }
         }
 
 
@@ -1792,13 +1771,13 @@ bool pmsav8_mpu_lookup(CPUARMState *env, uint32_t address,
                     ranges_overlap(base, limit - base + 1,
                     ranges_overlap(base, limit - base + 1,
                                    addr_page_base,
                                    addr_page_base,
                                    TARGET_PAGE_SIZE)) {
                                    TARGET_PAGE_SIZE)) {
-                    *is_subpage = true;
+                    result->page_size = 1;
                 }
                 }
                 continue;
                 continue;
             }
             }
 
 
             if (base > addr_page_base || limit < addr_page_limit) {
             if (base > addr_page_base || limit < addr_page_limit) {
-                *is_subpage = true;
+                result->page_size = 1;
             }
             }
 
 
             if (matchregion != -1) {
             if (matchregion != -1) {
@@ -1824,7 +1803,7 @@ bool pmsav8_mpu_lookup(CPUARMState *env, uint32_t address,
 
 
     if (matchregion == -1) {
     if (matchregion == -1) {
         /* hit using the background region */
         /* hit using the background region */
-        get_phys_addr_pmsav7_default(env, mmu_idx, address, prot);
+        get_phys_addr_pmsav7_default(env, mmu_idx, address, &result->prot);
     } else {
     } else {
         uint32_t ap = extract32(env->pmsav8.rbar[secure][matchregion], 1, 2);
         uint32_t ap = extract32(env->pmsav8.rbar[secure][matchregion], 1, 2);
         uint32_t xn = extract32(env->pmsav8.rbar[secure][matchregion], 0, 1);
         uint32_t xn = extract32(env->pmsav8.rbar[secure][matchregion], 0, 1);
@@ -1839,9 +1818,9 @@ bool pmsav8_mpu_lookup(CPUARMState *env, uint32_t address,
             xn = 1;
             xn = 1;
         }
         }
 
 
-        *prot = simple_ap_to_rw_prot(env, mmu_idx, ap);
-        if (*prot && !xn && !(pxn && !is_user)) {
-            *prot |= PAGE_EXEC;
+        result->prot = simple_ap_to_rw_prot(env, mmu_idx, ap);
+        if (result->prot && !xn && !(pxn && !is_user)) {
+            result->prot |= PAGE_EXEC;
         }
         }
         /*
         /*
          * We don't need to look the attribute up in the MAIR0/MAIR1
          * We don't need to look the attribute up in the MAIR0/MAIR1
@@ -1854,7 +1833,7 @@ bool pmsav8_mpu_lookup(CPUARMState *env, uint32_t address,
 
 
     fi->type = ARMFault_Permission;
     fi->type = ARMFault_Permission;
     fi->level = 1;
     fi->level = 1;
-    return !(*prot & (1 << access_type));
+    return !(result->prot & (1 << access_type));
 }
 }
 
 
 static bool v8m_is_sau_exempt(CPUARMState *env,
 static bool v8m_is_sau_exempt(CPUARMState *env,
@@ -1874,8 +1853,8 @@ static bool v8m_is_sau_exempt(CPUARMState *env,
 }
 }
 
 
 void v8m_security_lookup(CPUARMState *env, uint32_t address,
 void v8m_security_lookup(CPUARMState *env, uint32_t address,
-                                MMUAccessType access_type, ARMMMUIdx mmu_idx,
-                                V8M_SAttributes *sattrs)
+                         MMUAccessType access_type, ARMMMUIdx mmu_idx,
+                         bool is_secure, V8M_SAttributes *sattrs)
 {
 {
     /*
     /*
      * Look up the security attributes for this address. Compare the
      * Look up the security attributes for this address. Compare the
@@ -1903,7 +1882,7 @@ void v8m_security_lookup(CPUARMState *env, uint32_t address,
     }
     }
 
 
     if (idau_exempt || v8m_is_sau_exempt(env, address, access_type)) {
     if (idau_exempt || v8m_is_sau_exempt(env, address, access_type)) {
-        sattrs->ns = !regime_is_secure(env, mmu_idx);
+        sattrs->ns = !is_secure;
         return;
         return;
     }
     }
 
 
@@ -1984,17 +1963,15 @@ void v8m_security_lookup(CPUARMState *env, uint32_t address,
 
 
 static bool get_phys_addr_pmsav8(CPUARMState *env, uint32_t address,
 static bool get_phys_addr_pmsav8(CPUARMState *env, uint32_t address,
                                  MMUAccessType access_type, ARMMMUIdx mmu_idx,
                                  MMUAccessType access_type, ARMMMUIdx mmu_idx,
-                                 hwaddr *phys_ptr, MemTxAttrs *txattrs,
-                                 int *prot, target_ulong *page_size,
+                                 bool secure, GetPhysAddrResult *result,
                                  ARMMMUFaultInfo *fi)
                                  ARMMMUFaultInfo *fi)
 {
 {
-    uint32_t secure = regime_is_secure(env, mmu_idx);
     V8M_SAttributes sattrs = {};
     V8M_SAttributes sattrs = {};
     bool ret;
     bool ret;
-    bool mpu_is_subpage;
 
 
     if (arm_feature(env, ARM_FEATURE_M_SECURITY)) {
     if (arm_feature(env, ARM_FEATURE_M_SECURITY)) {
-        v8m_security_lookup(env, address, access_type, mmu_idx, &sattrs);
+        v8m_security_lookup(env, address, access_type, mmu_idx,
+                            secure, &sattrs);
         if (access_type == MMU_INST_FETCH) {
         if (access_type == MMU_INST_FETCH) {
             /*
             /*
              * Instruction fetches always use the MMU bank and the
              * Instruction fetches always use the MMU bank and the
@@ -2020,9 +1997,9 @@ static bool get_phys_addr_pmsav8(CPUARMState *env, uint32_t address,
                 } else {
                 } else {
                     fi->type = ARMFault_QEMU_SFault;
                     fi->type = ARMFault_QEMU_SFault;
                 }
                 }
-                *page_size = sattrs.subpage ? 1 : TARGET_PAGE_SIZE;
-                *phys_ptr = address;
-                *prot = 0;
+                result->page_size = sattrs.subpage ? 1 : TARGET_PAGE_SIZE;
+                result->phys = address;
+                result->prot = 0;
                 return true;
                 return true;
             }
             }
         } else {
         } else {
@@ -2032,7 +2009,7 @@ static bool get_phys_addr_pmsav8(CPUARMState *env, uint32_t address,
              * might downgrade a secure access to nonsecure.
              * might downgrade a secure access to nonsecure.
              */
              */
             if (sattrs.ns) {
             if (sattrs.ns) {
-                txattrs->secure = false;
+                result->attrs.secure = false;
             } else if (!secure) {
             } else if (!secure) {
                 /*
                 /*
                  * NS access to S memory must fault.
                  * NS access to S memory must fault.
@@ -2045,17 +2022,19 @@ static bool get_phys_addr_pmsav8(CPUARMState *env, uint32_t address,
                  * for M_FAKE_FSR_SFAULT in arm_v7m_cpu_do_interrupt().
                  * for M_FAKE_FSR_SFAULT in arm_v7m_cpu_do_interrupt().
                  */
                  */
                 fi->type = ARMFault_QEMU_SFault;
                 fi->type = ARMFault_QEMU_SFault;
-                *page_size = sattrs.subpage ? 1 : TARGET_PAGE_SIZE;
-                *phys_ptr = address;
-                *prot = 0;
+                result->page_size = sattrs.subpage ? 1 : TARGET_PAGE_SIZE;
+                result->phys = address;
+                result->prot = 0;
                 return true;
                 return true;
             }
             }
         }
         }
     }
     }
 
 
-    ret = pmsav8_mpu_lookup(env, address, access_type, mmu_idx, phys_ptr,
-                            txattrs, prot, &mpu_is_subpage, fi, NULL);
-    *page_size = sattrs.subpage || mpu_is_subpage ? 1 : TARGET_PAGE_SIZE;
+    ret = pmsav8_mpu_lookup(env, address, access_type, mmu_idx, secure,
+                            result, fi, NULL);
+    if (sattrs.subpage) {
+        result->page_size = 1;
+    }
     return ret;
     return ret;
 }
 }
 
 
@@ -2300,20 +2279,15 @@ static ARMCacheAttrs combine_cacheattrs(CPUARMState *env,
  * @address: virtual address to get physical address for
  * @address: virtual address to get physical address for
  * @access_type: 0 for read, 1 for write, 2 for execute
  * @access_type: 0 for read, 1 for write, 2 for execute
  * @mmu_idx: MMU index indicating required translation regime
  * @mmu_idx: MMU index indicating required translation regime
- * @phys_ptr: set to the physical address corresponding to the virtual address
- * @attrs: set to the memory transaction attributes to use
- * @prot: set to the permissions for the page containing phys_ptr
- * @page_size: set to the size of the page containing phys_ptr
+ * @result: set on translation success.
  * @fi: set to fault info if the translation fails
  * @fi: set to fault info if the translation fails
- * @cacheattrs: (if non-NULL) set to the cacheability/shareability attributes
  */
  */
 bool get_phys_addr(CPUARMState *env, target_ulong address,
 bool get_phys_addr(CPUARMState *env, target_ulong address,
                    MMUAccessType access_type, ARMMMUIdx mmu_idx,
                    MMUAccessType access_type, ARMMMUIdx mmu_idx,
-                   hwaddr *phys_ptr, MemTxAttrs *attrs, int *prot,
-                   target_ulong *page_size,
-                   ARMMMUFaultInfo *fi, ARMCacheAttrs *cacheattrs)
+                   GetPhysAddrResult *result, ARMMMUFaultInfo *fi)
 {
 {
     ARMMMUIdx s1_mmu_idx = stage_1_mmu_idx(mmu_idx);
     ARMMMUIdx s1_mmu_idx = stage_1_mmu_idx(mmu_idx);
+    bool is_secure = regime_is_secure(env, mmu_idx);
 
 
     if (mmu_idx != s1_mmu_idx) {
     if (mmu_idx != s1_mmu_idx) {
         /*
         /*
@@ -2322,43 +2296,52 @@ bool get_phys_addr(CPUARMState *env, target_ulong address,
          */
          */
         if (arm_feature(env, ARM_FEATURE_EL2)) {
         if (arm_feature(env, ARM_FEATURE_EL2)) {
             hwaddr ipa;
             hwaddr ipa;
-            int s2_prot;
+            int s1_prot;
             int ret;
             int ret;
             bool ipa_secure;
             bool ipa_secure;
-            ARMCacheAttrs cacheattrs2 = {};
+            ARMCacheAttrs cacheattrs1;
             ARMMMUIdx s2_mmu_idx;
             ARMMMUIdx s2_mmu_idx;
             bool is_el0;
             bool is_el0;
 
 
-            ret = get_phys_addr(env, address, access_type, s1_mmu_idx, &ipa,
-                                attrs, prot, page_size, fi, cacheattrs);
+            ret = get_phys_addr(env, address, access_type, s1_mmu_idx,
+                                result, fi);
 
 
             /* If S1 fails or S2 is disabled, return early.  */
             /* If S1 fails or S2 is disabled, return early.  */
             if (ret || regime_translation_disabled(env, ARMMMUIdx_Stage2)) {
             if (ret || regime_translation_disabled(env, ARMMMUIdx_Stage2)) {
-                *phys_ptr = ipa;
                 return ret;
                 return ret;
             }
             }
 
 
-            ipa_secure = attrs->secure;
+            ipa = result->phys;
+            ipa_secure = result->attrs.secure;
             if (arm_is_secure_below_el3(env)) {
             if (arm_is_secure_below_el3(env)) {
                 if (ipa_secure) {
                 if (ipa_secure) {
-                    attrs->secure = !(env->cp15.vstcr_el2 & VSTCR_SW);
+                    result->attrs.secure = !(env->cp15.vstcr_el2 & VSTCR_SW);
                 } else {
                 } else {
-                    attrs->secure = !(env->cp15.vtcr_el2 & VTCR_NSW);
+                    result->attrs.secure = !(env->cp15.vtcr_el2 & VTCR_NSW);
                 }
                 }
             } else {
             } else {
                 assert(!ipa_secure);
                 assert(!ipa_secure);
             }
             }
 
 
-            s2_mmu_idx = attrs->secure ? ARMMMUIdx_Stage2_S : ARMMMUIdx_Stage2;
+            s2_mmu_idx = (result->attrs.secure
+                          ? ARMMMUIdx_Stage2_S : ARMMMUIdx_Stage2);
             is_el0 = mmu_idx == ARMMMUIdx_E10_0 || mmu_idx == ARMMMUIdx_SE10_0;
             is_el0 = mmu_idx == ARMMMUIdx_E10_0 || mmu_idx == ARMMMUIdx_SE10_0;
 
 
-            /* S1 is done. Now do S2 translation.  */
-            ret = get_phys_addr_lpae(env, ipa, access_type, s2_mmu_idx, is_el0,
-                                     phys_ptr, attrs, &s2_prot,
-                                     page_size, fi, &cacheattrs2);
+            /*
+             * S1 is done, now do S2 translation.
+             * Save the stage1 results so that we may merge
+             * prot and cacheattrs later.
+             */
+            s1_prot = result->prot;
+            cacheattrs1 = result->cacheattrs;
+            memset(result, 0, sizeof(*result));
+
+            ret = get_phys_addr_lpae(env, ipa, access_type, s2_mmu_idx,
+                                     is_el0, result, fi);
             fi->s2addr = ipa;
             fi->s2addr = ipa;
+
             /* Combine the S1 and S2 perms.  */
             /* Combine the S1 and S2 perms.  */
-            *prot &= s2_prot;
+            result->prot &= s1_prot;
 
 
             /* If S2 fails, return early.  */
             /* If S2 fails, return early.  */
             if (ret) {
             if (ret) {
@@ -2374,20 +2357,21 @@ bool get_phys_addr(CPUARMState *env, target_ulong address,
                  *  Outer Write-Back Read-Allocate Write-Allocate.
                  *  Outer Write-Back Read-Allocate Write-Allocate.
                  * Do not overwrite Tagged within attrs.
                  * Do not overwrite Tagged within attrs.
                  */
                  */
-                if (cacheattrs->attrs != 0xf0) {
-                    cacheattrs->attrs = 0xff;
+                if (cacheattrs1.attrs != 0xf0) {
+                    cacheattrs1.attrs = 0xff;
                 }
                 }
-                cacheattrs->shareability = 0;
+                cacheattrs1.shareability = 0;
             }
             }
-            *cacheattrs = combine_cacheattrs(env, *cacheattrs, cacheattrs2);
+            result->cacheattrs = combine_cacheattrs(env, cacheattrs1,
+                                                    result->cacheattrs);
 
 
             /* Check if IPA translates to secure or non-secure PA space. */
             /* Check if IPA translates to secure or non-secure PA space. */
             if (arm_is_secure_below_el3(env)) {
             if (arm_is_secure_below_el3(env)) {
                 if (ipa_secure) {
                 if (ipa_secure) {
-                    attrs->secure =
+                    result->attrs.secure =
                         !(env->cp15.vstcr_el2 & (VSTCR_SA | VSTCR_SW));
                         !(env->cp15.vstcr_el2 & (VSTCR_SA | VSTCR_SW));
                 } else {
                 } else {
-                    attrs->secure =
+                    result->attrs.secure =
                         !((env->cp15.vtcr_el2 & (VTCR_NSA | VTCR_NSW))
                         !((env->cp15.vtcr_el2 & (VTCR_NSA | VTCR_NSW))
                         || (env->cp15.vstcr_el2 & (VSTCR_SA | VSTCR_SW)));
                         || (env->cp15.vstcr_el2 & (VSTCR_SA | VSTCR_SW)));
                 }
                 }
@@ -2406,8 +2390,8 @@ bool get_phys_addr(CPUARMState *env, target_ulong address,
      * cannot upgrade an non-secure translation regime's attributes
      * cannot upgrade an non-secure translation regime's attributes
      * to secure.
      * to secure.
      */
      */
-    attrs->secure = regime_is_secure(env, mmu_idx);
-    attrs->user = regime_is_user(env, mmu_idx);
+    result->attrs.secure = is_secure;
+    result->attrs.user = regime_is_user(env, mmu_idx);
 
 
     /*
     /*
      * Fast Context Switch Extension. This doesn't exist at all in v8.
      * Fast Context Switch Extension. This doesn't exist at all in v8.
@@ -2424,20 +2408,20 @@ bool get_phys_addr(CPUARMState *env, target_ulong address,
 
 
     if (arm_feature(env, ARM_FEATURE_PMSA)) {
     if (arm_feature(env, ARM_FEATURE_PMSA)) {
         bool ret;
         bool ret;
-        *page_size = TARGET_PAGE_SIZE;
+        result->page_size = TARGET_PAGE_SIZE;
 
 
         if (arm_feature(env, ARM_FEATURE_V8)) {
         if (arm_feature(env, ARM_FEATURE_V8)) {
             /* PMSAv8 */
             /* PMSAv8 */
             ret = get_phys_addr_pmsav8(env, address, access_type, mmu_idx,
             ret = get_phys_addr_pmsav8(env, address, access_type, mmu_idx,
-                                       phys_ptr, attrs, prot, page_size, fi);
+                                       is_secure, result, fi);
         } else if (arm_feature(env, ARM_FEATURE_V7)) {
         } else if (arm_feature(env, ARM_FEATURE_V7)) {
             /* PMSAv7 */
             /* PMSAv7 */
             ret = get_phys_addr_pmsav7(env, address, access_type, mmu_idx,
             ret = get_phys_addr_pmsav7(env, address, access_type, mmu_idx,
-                                       phys_ptr, prot, page_size, fi);
+                                       is_secure, result, fi);
         } else {
         } else {
             /* Pre-v7 MPU */
             /* Pre-v7 MPU */
             ret = get_phys_addr_pmsav5(env, address, access_type, mmu_idx,
             ret = get_phys_addr_pmsav5(env, address, access_type, mmu_idx,
-                                       phys_ptr, prot, fi);
+                                       is_secure, result, fi);
         }
         }
         qemu_log_mask(CPU_LOG_MMU, "PMSA MPU lookup for %s at 0x%08" PRIx32
         qemu_log_mask(CPU_LOG_MMU, "PMSA MPU lookup for %s at 0x%08" PRIx32
                       " mmu_idx %u -> %s (prot %c%c%c)\n",
                       " mmu_idx %u -> %s (prot %c%c%c)\n",
@@ -2445,9 +2429,9 @@ bool get_phys_addr(CPUARMState *env, target_ulong address,
                       (access_type == MMU_DATA_STORE ? "writing" : "execute"),
                       (access_type == MMU_DATA_STORE ? "writing" : "execute"),
                       (uint32_t)address, mmu_idx,
                       (uint32_t)address, mmu_idx,
                       ret ? "Miss" : "Hit",
                       ret ? "Miss" : "Hit",
-                      *prot & PAGE_READ ? 'r' : '-',
-                      *prot & PAGE_WRITE ? 'w' : '-',
-                      *prot & PAGE_EXEC ? 'x' : '-');
+                      result->prot & PAGE_READ ? 'r' : '-',
+                      result->prot & PAGE_WRITE ? 'w' : '-',
+                      result->prot & PAGE_EXEC ? 'x' : '-');
 
 
         return ret;
         return ret;
     }
     }
@@ -2492,14 +2476,14 @@ bool get_phys_addr(CPUARMState *env, target_ulong address,
                 address = extract64(address, 0, 52);
                 address = extract64(address, 0, 52);
             }
             }
         }
         }
-        *phys_ptr = address;
-        *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
-        *page_size = TARGET_PAGE_SIZE;
+        result->phys = address;
+        result->prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
+        result->page_size = TARGET_PAGE_SIZE;
 
 
         /* Fill in cacheattr a-la AArch64.TranslateAddressS1Off. */
         /* Fill in cacheattr a-la AArch64.TranslateAddressS1Off. */
         hcr = arm_hcr_el2_eff(env);
         hcr = arm_hcr_el2_eff(env);
-        cacheattrs->shareability = 0;
-        cacheattrs->is_s2_format = false;
+        result->cacheattrs.shareability = 0;
+        result->cacheattrs.is_s2_format = false;
         if (hcr & HCR_DC) {
         if (hcr & HCR_DC) {
             if (hcr & HCR_DCT) {
             if (hcr & HCR_DCT) {
                 memattr = 0xf0;  /* Tagged, Normal, WB, RWA */
                 memattr = 0xf0;  /* Tagged, Normal, WB, RWA */
@@ -2512,24 +2496,23 @@ bool get_phys_addr(CPUARMState *env, target_ulong address,
             } else {
             } else {
                 memattr = 0x44;  /* Normal, NC, No */
                 memattr = 0x44;  /* Normal, NC, No */
             }
             }
-            cacheattrs->shareability = 2; /* outer sharable */
+            result->cacheattrs.shareability = 2; /* outer sharable */
         } else {
         } else {
             memattr = 0x00;      /* Device, nGnRnE */
             memattr = 0x00;      /* Device, nGnRnE */
         }
         }
-        cacheattrs->attrs = memattr;
+        result->cacheattrs.attrs = memattr;
         return 0;
         return 0;
     }
     }
 
 
     if (regime_using_lpae_format(env, mmu_idx)) {
     if (regime_using_lpae_format(env, mmu_idx)) {
         return get_phys_addr_lpae(env, address, access_type, mmu_idx, false,
         return get_phys_addr_lpae(env, address, access_type, mmu_idx, false,
-                                  phys_ptr, attrs, prot, page_size,
-                                  fi, cacheattrs);
+                                  result, fi);
     } else if (regime_sctlr(env, mmu_idx) & SCTLR_XP) {
     } else if (regime_sctlr(env, mmu_idx) & SCTLR_XP) {
         return get_phys_addr_v6(env, address, access_type, mmu_idx,
         return get_phys_addr_v6(env, address, access_type, mmu_idx,
-                                phys_ptr, attrs, prot, page_size, fi);
+                                is_secure, result, fi);
     } else {
     } else {
         return get_phys_addr_v5(env, address, access_type, mmu_idx,
         return get_phys_addr_v5(env, address, access_type, mmu_idx,
-                                    phys_ptr, prot, page_size, fi);
+                                is_secure, result, fi);
     }
     }
 }
 }
 
 
@@ -2538,21 +2521,16 @@ hwaddr arm_cpu_get_phys_page_attrs_debug(CPUState *cs, vaddr addr,
 {
 {
     ARMCPU *cpu = ARM_CPU(cs);
     ARMCPU *cpu = ARM_CPU(cs);
     CPUARMState *env = &cpu->env;
     CPUARMState *env = &cpu->env;
-    hwaddr phys_addr;
-    target_ulong page_size;
-    int prot;
-    bool ret;
+    GetPhysAddrResult res = {};
     ARMMMUFaultInfo fi = {};
     ARMMMUFaultInfo fi = {};
     ARMMMUIdx mmu_idx = arm_mmu_idx(env);
     ARMMMUIdx mmu_idx = arm_mmu_idx(env);
-    ARMCacheAttrs cacheattrs = {};
-
-    *attrs = (MemTxAttrs) {};
+    bool ret;
 
 
-    ret = get_phys_addr(env, addr, MMU_DATA_LOAD, mmu_idx, &phys_addr,
-                        attrs, &prot, &page_size, &fi, &cacheattrs);
+    ret = get_phys_addr(env, addr, MMU_DATA_LOAD, mmu_idx, &res, &fi);
+    *attrs = res.attrs;
 
 
     if (ret) {
     if (ret) {
         return -1;
         return -1;
     }
     }
-    return phys_addr;
+    return res.phys;
 }
 }

+ 9 - 13
target/arm/tlb_helper.c

@@ -209,11 +209,8 @@ bool arm_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
 {
 {
     ARMCPU *cpu = ARM_CPU(cs);
     ARMCPU *cpu = ARM_CPU(cs);
     ARMMMUFaultInfo fi = {};
     ARMMMUFaultInfo fi = {};
-    hwaddr phys_addr;
-    target_ulong page_size;
-    int prot, ret;
-    MemTxAttrs attrs = {};
-    ARMCacheAttrs cacheattrs = {};
+    GetPhysAddrResult res = {};
+    int ret;
 
 
     /*
     /*
      * Walk the page table and (if the mapping exists) add the page
      * Walk the page table and (if the mapping exists) add the page
@@ -223,25 +220,24 @@ bool arm_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
      */
      */
     ret = get_phys_addr(&cpu->env, address, access_type,
     ret = get_phys_addr(&cpu->env, address, access_type,
                         core_to_arm_mmu_idx(&cpu->env, mmu_idx),
                         core_to_arm_mmu_idx(&cpu->env, mmu_idx),
-                        &phys_addr, &attrs, &prot, &page_size,
-                        &fi, &cacheattrs);
+                        &res, &fi);
     if (likely(!ret)) {
     if (likely(!ret)) {
         /*
         /*
          * Map a single [sub]page. Regions smaller than our declared
          * Map a single [sub]page. Regions smaller than our declared
          * target page size are handled specially, so for those we
          * target page size are handled specially, so for those we
          * pass in the exact addresses.
          * pass in the exact addresses.
          */
          */
-        if (page_size >= TARGET_PAGE_SIZE) {
-            phys_addr &= TARGET_PAGE_MASK;
+        if (res.page_size >= TARGET_PAGE_SIZE) {
+            res.phys &= TARGET_PAGE_MASK;
             address &= TARGET_PAGE_MASK;
             address &= TARGET_PAGE_MASK;
         }
         }
         /* Notice and record tagged memory. */
         /* Notice and record tagged memory. */
-        if (cpu_isar_feature(aa64_mte, cpu) && cacheattrs.attrs == 0xf0) {
-            arm_tlb_mte_tagged(&attrs) = true;
+        if (cpu_isar_feature(aa64_mte, cpu) && res.cacheattrs.attrs == 0xf0) {
+            arm_tlb_mte_tagged(&res.attrs) = true;
         }
         }
 
 
-        tlb_set_page_with_attrs(cs, address, phys_addr, attrs,
-                                prot, mmu_idx, page_size);
+        tlb_set_page_with_attrs(cs, address, res.phys, res.attrs,
+                                res.prot, mmu_idx, res.page_size);
         return true;
         return true;
     } else if (probe) {
     } else if (probe) {
         return false;
         return false;

+ 5 - 1
target/arm/translate-neon.c

@@ -584,7 +584,11 @@ static bool trans_VLD_all_lanes(DisasContext *s, arg_VLD_all_lanes *a)
         case 3:
         case 3:
             return false;
             return false;
         case 4:
         case 4:
-            align = pow2_align(size + 2);
+            if (size == 2) {
+                align = pow2_align(3);
+            } else {
+                align = pow2_align(size + 2);
+            }
             break;
             break;
         default:
         default:
             g_assert_not_reached();
             g_assert_not_reached();

+ 3 - 4
tests/unit/test-vmstate.c

@@ -87,17 +87,16 @@ static void save_buffer(const uint8_t *buf, size_t buf_size)
 static void compare_vmstate(const uint8_t *wire, size_t size)
 static void compare_vmstate(const uint8_t *wire, size_t size)
 {
 {
     QEMUFile *f = open_test_file(false);
     QEMUFile *f = open_test_file(false);
-    uint8_t result[size];
+    g_autofree uint8_t *result = g_malloc(size);
 
 
     /* read back as binary */
     /* read back as binary */
 
 
-    g_assert_cmpint(qemu_get_buffer(f, result, sizeof(result)), ==,
-                    sizeof(result));
+    g_assert_cmpint(qemu_get_buffer(f, result, size), ==, size);
     g_assert(!qemu_file_get_error(f));
     g_assert(!qemu_file_get_error(f));
 
 
     /* Compare that what is on the file is the same that what we
     /* Compare that what is on the file is the same that what we
        expected to be there */
        expected to be there */
-    SUCCESS(memcmp(result, wire, sizeof(result)));
+    SUCCESS(memcmp(result, wire, size));
 
 
     /* Must reach EOF */
     /* Must reach EOF */
     qemu_get_byte(f);
     qemu_get_byte(f);

+ 1 - 1
ui/curses.c

@@ -69,7 +69,7 @@ static void curses_update(DisplayChangeListener *dcl,
                           int x, int y, int w, int h)
                           int x, int y, int w, int h)
 {
 {
     console_ch_t *line;
     console_ch_t *line;
-    cchar_t curses_line[width];
+    g_autofree cchar_t *curses_line = g_new(cchar_t, width);
     wchar_t wch[CCHARW_MAX];
     wchar_t wch[CCHARW_MAX];
     attr_t attrs;
     attr_t attrs;
     short colors;
     short colors;