diff options
author | Stefan Hajnoczi <stefanha@redhat.com> | 2022-09-26 13:38:26 -0400 |
---|---|---|
committer | Stefan Hajnoczi <stefanha@redhat.com> | 2022-09-26 13:38:26 -0400 |
commit | 99d6b11b5b44d7dd64f4cb1973184e40a4a174f8 (patch) | |
tree | f2b7b202b93d603d0b9f5e2e4b61d494a789cfc2 | |
parent | 6160d8ff81fb9fba70f5dad88d43ffd0fa44984c (diff) | |
parent | b3b5472db0ab7a53499441c1fe1dedec05b1e285 (diff) |
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>
-rw-r--r-- | chardev/baum.c | 22 | ||||
-rwxr-xr-x | configure | 82 | ||||
-rw-r--r-- | hw/acpi/generic_event_device.c | 8 | ||||
-rw-r--r-- | hw/i386/multiboot.c | 5 | ||||
-rw-r--r-- | hw/intc/xics.c | 2 | ||||
-rw-r--r-- | hw/net/can/xlnx-zynqmp-can.c | 32 | ||||
-rw-r--r-- | hw/net/e1000e_core.c | 7 | ||||
-rw-r--r-- | hw/net/lan9118.c | 8 | ||||
-rw-r--r-- | hw/ppc/pnv.c | 4 | ||||
-rw-r--r-- | hw/ppc/spapr.c | 8 | ||||
-rw-r--r-- | hw/ppc/spapr_pci_nvlink2.c | 2 | ||||
-rw-r--r-- | hw/usb/hcd-ohci.c | 7 | ||||
-rw-r--r-- | io/channel-websock.c | 2 | ||||
-rw-r--r-- | target/arm/helper.c | 27 | ||||
-rw-r--r-- | target/arm/internals.h | 26 | ||||
-rw-r--r-- | target/arm/m_helper.c | 78 | ||||
-rw-r--r-- | target/arm/ptw.c | 364 | ||||
-rw-r--r-- | target/arm/tlb_helper.c | 22 | ||||
-rw-r--r-- | target/arm/translate-neon.c | 6 | ||||
-rw-r--r-- | tests/unit/test-vmstate.c | 7 | ||||
-rw-r--r-- | ui/curses.c | 2 |
21 files changed, 347 insertions, 374 deletions
diff --git a/chardev/baum.c b/chardev/baum.c index 79d618e350..0a0d12661a 100644 --- a/chardev/baum.c +++ b/chardev/baum.c @@ -87,6 +87,9 @@ #define BUF_SIZE 256 +#define X_MAX 84 +#define Y_MAX 1 + struct BaumChardev { Chardev parent; @@ -244,11 +247,11 @@ static int baum_deferred_init(BaumChardev *baum) brlapi_perror("baum: brlapi__getDisplaySize"); 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); @@ -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) { 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; *cur++ = ESC; while (len--) @@ -380,9 +384,9 @@ static int baum_eat_packet(BaumChardev *baum, const uint8_t *buf, int len) switch (req) { 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 i; @@ -405,7 +409,7 @@ static int baum_eat_packet(BaumChardev *baum, const uint8_t *buf, int len) } timer_del(baum->cellCount_timer); - memset(zero, 0, sizeof(zero)); + memset(zero, 0, baum->x * baum->y); brlapi_writeArguments_t wa = { .displayNumber = BRLAPI_DISPLAY_DEFAULT, @@ -57,7 +57,7 @@ GNUmakefile: ; EOF cd build - exec $source_path/configure "$@" + exec "$source_path/configure" "$@" fi # Temporary directory used for files created while @@ -67,8 +67,7 @@ fi # it when configure exits.) TMPDIR1="config-temp" rm -rf "${TMPDIR1}" -mkdir -p "${TMPDIR1}" -if [ $? -ne 0 ]; then +if ! mkdir -p "${TMPDIR1}"; then echo "ERROR: failed to create temporary directory" exit 1 fi @@ -111,7 +110,7 @@ error_exit() { do_compiler() { # Run the compiler, capturing its output to the log. First argument # is compiler binary to execute. - local compiler="$1" + compiler="$1" shift if test -n "$BASH_VERSION"; then eval ' echo >>config.log " @@ -311,7 +310,6 @@ pie="" coroutine="" plugins="$default_feature" meson="" -meson_args="" ninja="" bindir="bin" skip_meson=no @@ -692,7 +690,7 @@ meson_option_build_array() { printf ']\n' } -. $source_path/scripts/meson-buildoptions.sh +. "$source_path/scripts/meson-buildoptions.sh" meson_options= meson_option_add() { @@ -712,7 +710,7 @@ for opt do case "$opt" in --help|-h) show_help=yes ;; - --version|-V) exec cat $source_path/VERSION + --version|-V) exec cat "$source_path/VERSION" ;; --prefix=*) prefix="$optarg" ;; @@ -986,7 +984,7 @@ default_target_list="" mak_wilds="" 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 elif [ "$linux_user" = yes ]; then error_exit "linux-user not supported on this architecture" @@ -996,7 +994,7 @@ if [ "$bsd_user" != no ]; then if [ "$bsd_user" = "" ]; then test $targetos = freebsd && bsd_user=yes 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" fi fi @@ -1094,7 +1092,7 @@ exit 0 fi # 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" 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." 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 python="$python -B" if test -z "$meson"; then if test "$explicit_python" = no && has meson && version_ge "$(meson --version)" 0.59.3; then meson=meson - elif test $git_submodules_action != 'ignore' ; then + elif test "$git_submodules_action" != 'ignore' ; then meson=git elif test -e "${source_path}/meson/meson.py" ; then meson=internal @@ -1838,7 +1833,7 @@ esac container="no" if test $use_containers = "yes"; 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 @@ -2070,7 +2065,6 @@ probe_target_compiler() { : ${container_cross_strip:=${container_cross_prefix}strip} done - local t try try=cross case "$target_arch:$cpu" in aarch64_be:aarch64 | \ @@ -2083,8 +2077,8 @@ probe_target_compiler() { try='native cross' ;; esac 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) target_cc=$cc target_ccas=$ccas @@ -2288,7 +2282,7 @@ if test "$QEMU_GA_DISTRO" = ""; then QEMU_GA_DISTRO=Linux fi if test "$QEMU_GA_VERSION" = ""; then - QEMU_GA_VERSION=$(cat $source_path/VERSION) + QEMU_GA_VERSION=$(cat "$source_path"/VERSION) fi @@ -2315,7 +2309,7 @@ LINKS="$LINKS python" LINKS="$LINKS contrib/plugins/Makefile " for f in $LINKS ; do if [ -e "$source_path/$f" ]; then - mkdir -p `dirname ./$f` + mkdir -p "$(dirname ./"$f")" symlink "$source_path/$f" "$f" fi done @@ -2537,7 +2531,7 @@ fi for target in $target_list; do target_dir="$target" target_name=$(echo $target | cut -d '-' -f 1)$EXESUF - mkdir -p $target_dir + mkdir -p "$target_dir" case $target in *-user) symlink "../qemu-$target_name" "$target_dir/qemu-$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 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 xtensa*-linux-user) # the toolchain is not complete with headers, only build softmmu tests continue ;; *-softmmu) - test -f $source_path/tests/tcg/$arch/Makefile.softmmu-target || continue + test -f "$source_path/tests/tcg/$arch/Makefile.softmmu-target" || continue qemu="qemu-system-$arch" ;; *-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 # 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 aarch64-*) if do_compiler "$target_cc" $target_cflags \ -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 if do_compiler "$target_cc" $target_cflags \ -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 if do_compiler "$target_cc" $target_cflags \ -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 if do_compiler "$target_cc" $target_cflags \ -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 if do_compiler "$target_cc" $target_cflags \ -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 ;; ppc*) if do_compiler "$target_cc" $target_cflags \ -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 if do_compiler "$target_cc" $target_cflags \ -mpower10 -o $TMPE $TMPC; then - echo "CROSS_CC_HAS_POWER10=y" >> $config_target_mak + echo "CROSS_CC_HAS_POWER10=y" >> "$config_target_mak" fi ;; i386-linux-user) if do_compiler "$target_cc" $target_cflags \ -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 ;; esac elif test -n "$container_image"; then 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 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*) - 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) - echo "CROSS_CC_HAS_I386_NOPIE=y" >> $config_target_mak + echo "CROSS_CC_HAS_I386_NOPIE=y" >> "$config_target_mak" ;; esac got_cross_cc=yes fi if test $got_cross_cc = yes; then 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 tcg_tests_targets="$tcg_tests_targets $target" fi diff --git a/hw/acpi/generic_event_device.c b/hw/acpi/generic_event_device.c index e28457a7d1..a3d31631fe 100644 --- a/hw/acpi/generic_event_device.c +++ b/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) { 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 = acpi_ged_unplug_cb; + adevc->ospm_status = acpi_ged_ospm_status; adevc->send_event = acpi_ged_send_event; } diff --git a/hw/i386/multiboot.c b/hw/i386/multiboot.c index 0a10089f14..963e29362e 100644 --- a/hw/i386/multiboot.c +++ b/hw/i386/multiboot.c @@ -163,6 +163,7 @@ int load_multiboot(X86MachineState *x86ms, uint8_t *mb_bootinfo_data; uint32_t cmdline_len; GList *mods = NULL; + g_autofree char *kcmdline = NULL; /* Ok, let's see if it is a multiboot image. The header is 12x32bit long, so the latest entry may be 8192 - 48. */ @@ -362,9 +363,7 @@ int load_multiboot(X86MachineState *x86ms, } /* 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_BOOTLOADER, mb_add_bootloader(&mbs, bootloader_name)); diff --git a/hw/intc/xics.c b/hw/intc/xics.c index 5b0b4d9624..dcd021af66 100644 --- a/hw/intc/xics.c +++ b/hw/intc/xics.c @@ -567,8 +567,8 @@ static void ics_reset_irq(ICSIRQState *irq) static void ics_reset(DeviceState *dev) { ICSState *ics = ICS(dev); + g_autofree uint8_t *flags = g_malloc(ics->nr_irqs); int i; - uint8_t flags[ics->nr_irqs]; for (i = 0; i < ics->nr_irqs; i++) { flags[i] = ics->irqs[i].flags; diff --git a/hw/net/can/xlnx-zynqmp-can.c b/hw/net/can/xlnx-zynqmp-can.c index 82ac48cee2..e93e6c5e19 100644 --- a/hw/net/can/xlnx-zynqmp-can.c +++ b/hw/net/can/xlnx-zynqmp-can.c @@ -696,30 +696,30 @@ static void update_rx_fifo(XlnxZynqMPCANState *s, const qemu_can_frame *frame) timestamp)); /* 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]) | - 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]) | - 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]) | - 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])); /* 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]) | - 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]) | - 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]) | - 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])); ARRAY_FIELD_DP32(s->regs, INTERRUPT_STATUS_REGISTER, RXOK, 1); diff --git a/hw/net/e1000e_core.c b/hw/net/e1000e_core.c index 208e3e0d79..82aa61fedc 100644 --- a/hw/net/e1000e_core.c +++ b/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 e1000e_receive_iov(E1000ECore *core, const struct iovec *iov, int iovcnt) { 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; - uint8_t min_buf[min_buf_size]; + uint8_t min_buf[MIN_BUF_SIZE]; struct iovec min_iov; uint8_t *filter_buf; size_t size, orig_size; diff --git a/hw/net/lan9118.c b/hw/net/lan9118.c index 456ae38107..f1cba55967 100644 --- a/hw/net/lan9118.c +++ b/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; s->tx_status_fifo[n] = status; 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) { s->int_sts |= TSFF_INT; /* TODO: Stop transmission. */ diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c index 354aa289d1..78e00afb9b 100644 --- a/hw/ppc/pnv.c +++ b/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; CPUPPCState *env = &cpu->env; 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; uint32_t segs[] = {cpu_to_be32(28), cpu_to_be32(40), 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); } _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, diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index cc1adc23fa..8bbaf4f8a4 100644 --- a/hw/ppc/spapr.c +++ b/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 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); 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; } 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) { return ret; } 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; } diff --git a/hw/ppc/spapr_pci_nvlink2.c b/hw/ppc/spapr_pci_nvlink2.c index 63b476c8f7..2a8a11be1d 100644 --- a/hw/ppc/spapr_pci_nvlink2.c +++ b/hw/ppc/spapr_pci_nvlink2.c @@ -397,7 +397,7 @@ void spapr_phb_nvgpu_populate_pcidev_dt(PCIDevice *dev, void *fdt, int offset, continue; } 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) { PCIDevice *npdev = nvslot->links[j].npdev; diff --git a/hw/usb/hcd-ohci.c b/hw/usb/hcd-ohci.c index 895b29fb86..5585fd32cc 100644 --- a/hw/usb/hcd-ohci.c +++ b/hw/usb/hcd-ohci.c @@ -805,13 +805,14 @@ static int ohci_service_iso_td(OHCIState *ohci, struct ohci_ed *ed) return 1; } +#define HEX_CHAR_PER_LINE 16 + static void ohci_td_pkt(const char *msg, const uint8_t *buf, size_t len) { bool print16; bool printall; - const int width = 16; int i; - char tmp[3 * width + 1]; + char tmp[3 * HEX_CHAR_PER_LINE + 1]; char *p = tmp; 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++) { - if (i && (!(i % width) || (i == len))) { + if (i && (!(i % HEX_CHAR_PER_LINE) || (i == len))) { if (!printall) { trace_usb_ohci_td_pkt_short(msg, tmp); break; diff --git a/io/channel-websock.c b/io/channel-websock.c index 9619906ac3..fb4932ade7 100644 --- a/io/channel-websock.c +++ b/io/channel-websock.c @@ -32,7 +32,7 @@ #define QIO_CHANNEL_WEBSOCK_CLIENT_KEY_LEN 24 #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_VERSION "sec-websocket-version" diff --git a/target/arm/helper.c b/target/arm/helper.c index 1a57d2e1d6..b5dac651e7 100644 --- a/target/arm/helper.c +++ b/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, MMUAccessType access_type, ARMMMUIdx mmu_idx) { - hwaddr phys_addr; - target_ulong page_size; - int prot; bool ret; uint64_t par64; bool format64 = false; - MemTxAttrs attrs = {}; 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 * have to deal with the ARMCacheAttrs format for S2 only. */ - assert(!cacheattrs.is_s2_format); + assert(!res.cacheattrs.is_s2_format); if (ret) { /* @@ -3313,12 +3308,12 @@ static uint64_t do_ats_write(CPUARMState *env, uint64_t value, /* Create a 64-bit PAR */ par64 = (1 << 11); /* LPAE bit always set */ if (!ret) { - par64 |= phys_addr & ~0xfffULL; - if (!attrs.secure) { + par64 |= res.phys & ~0xfffULL; + if (!res.attrs.secure) { 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 { 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) { /* 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)) { - par64 = (phys_addr & 0xff000000) | (1 << 1); + par64 = (res.phys & 0xff000000) | (1 << 1); } else { - par64 = phys_addr & 0xfffff000; + par64 = res.phys & 0xfffff000; } - if (!attrs.secure) { + if (!res.attrs.secure) { par64 |= (1 << 9); /* NS */ } } else { diff --git a/target/arm/internals.h b/target/arm/internals.h index bf60cd5f84..307a596505 100644 --- a/target/arm/internals.h +++ b/target/arm/internals.h @@ -1123,13 +1123,7 @@ typedef struct V8M_SAttributes { void v8m_security_lookup(CPUARMState *env, uint32_t address, 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 */ typedef struct ARMCacheAttrs { @@ -1142,13 +1136,25 @@ typedef struct ARMCacheAttrs { bool is_s2_format:1; } 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, 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)); +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); #endif /* !CONFIG_USER_ONLY */ diff --git a/target/arm/m_helper.c b/target/arm/m_helper.c index 308610f6b4..5ee4ee15b3 100644 --- a/target/arm/m_helper.c +++ b/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); CPUARMState *env = &cpu->env; - MemTxAttrs attrs = {}; MemTxResult txres; - target_ulong page_size; - hwaddr physaddr; - int prot; + GetPhysAddrResult res = {}; ARMMMUFaultInfo fi = {}; - ARMCacheAttrs cacheattrs = {}; bool secure = mmu_idx & ARM_MMU_IDX_M_S; int exc; 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 */ if (fi.type == ARMFault_QEMU_SFault) { if (mode == STACK_LAZYFP) { @@ -228,8 +223,8 @@ static bool v7m_stack_write(ARMCPU *cpu, uint32_t addr, uint32_t value, } 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) { /* BusFault trying to write the data */ 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); CPUARMState *env = &cpu->env; - MemTxAttrs attrs = {}; MemTxResult txres; - target_ulong page_size; - hwaddr physaddr; - int prot; + GetPhysAddrResult res = {}; ARMMMUFaultInfo fi = {}; - ARMCacheAttrs cacheattrs = {}; bool secure = mmu_idx & ARM_MMU_IDX_M_S; int exc; bool exc_secure; 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 */ if (fi.type == ARMFault_QEMU_SFault) { 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; } - 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) { /* BusFault trying to read the data */ 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)) { 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) { attrs.secure = false; } else if (!targets_secure) { @@ -2008,15 +1999,12 @@ static bool v7m_read_half_insn(ARMCPU *cpu, ARMMMUIdx mmu_idx, CPUState *cs = CPU(cpu); CPUARMState *env = &cpu->env; V8M_SAttributes sattrs = {}; - MemTxAttrs attrs = {}; + GetPhysAddrResult res = {}; ARMMMUFaultInfo fi = {}; - ARMCacheAttrs cacheattrs = {}; 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) { /* * 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"); 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 */ env->v7m.cfsr[env->v7m.secure] |= R_V7M_CFSR_IACCVIOL_MASK; armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_MEM, env->v7m.secure); qemu_log_mask(CPU_LOG_INT, "...really MemManage with CFSR.IACCVIOL\n"); 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) { env->v7m.cfsr[M_REG_NS] |= R_V7M_CFSR_IBUSERR_MASK; 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); CPUARMState *env = &cpu->env; - MemTxAttrs attrs = {}; MemTxResult txres; - target_ulong page_size; - hwaddr physaddr; - int prot; + GetPhysAddrResult res = {}; ARMMMUFaultInfo fi = {}; - ARMCacheAttrs cacheattrs = {}; 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 */ if (fi.type == ARMFault_QEMU_SFault) { qemu_log_mask(CPU_LOG_INT, @@ -2088,8 +2070,8 @@ static bool v7m_read_sg_stack_word(ARMCPU *cpu, ARMMMUIdx mmu_idx, } 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) { /* BusFault trying to read the data */ 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 = {}; uint32_t tt_resp; bool r, rw, nsr, nsrw, mrvalid; - int prot; - ARMMMUFaultInfo fi = {}; - MemTxAttrs attrs = {}; - hwaddr phys_addr; ARMMMUIdx mmu_idx; uint32_t mregion; bool targetpriv; bool targetsec = env->v7m.secure; - bool is_subpage; /* * 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. */ if (arm_current_el(env) != 0 || alt) { + GetPhysAddrResult res = {}; + ARMMMUFaultInfo fi = {}; + /* 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) { mrvalid = false; mregion = 0; } else { mrvalid = true; } - r = prot & PAGE_READ; - rw = prot & PAGE_WRITE; + r = res.prot & PAGE_READ; + rw = res.prot & PAGE_WRITE; } else { r = false; rw = false; @@ -2849,7 +2828,8 @@ uint32_t HELPER(v7m_tt)(CPUARMState *env, uint32_t addr, uint32_t op) } 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; nsrw = sattrs.ns && rw; } else { diff --git a/target/arm/ptw.c b/target/arm/ptw.c index 3261039d93..2ddfc028ab 100644 --- a/target/arm/ptw.c +++ b/target/arm/ptw.c @@ -16,10 +16,8 @@ static bool get_phys_addr_lpae(CPUARMState *env, uint64_t address, 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)); /* 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) && !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_Stage2; - ARMCacheAttrs cacheattrs = {}; - MemTxAttrs txattrs = {}; + GetPhysAddrResult s2 = {}; + int ret; ret = get_phys_addr_lpae(env, addr, MMU_DATA_LOAD, s2_mmu_idx, false, - &s2pa, &txattrs, &s2prot, &s2size, fi, - &cacheattrs); + &s2, fi); if (ret) { assert(fi->type != ARMFault_None); fi->s2addr = addr; @@ -225,7 +218,7 @@ static hwaddr S1_ptw_translate(CPUARMState *env, ARMMMUIdx mmu_idx, return ~0; } 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: * generate Permission fault. @@ -249,7 +242,7 @@ static hwaddr S1_ptw_translate(CPUARMState *env, ARMMMUIdx mmu_idx, assert(!*is_secure); } - addr = s2pa; + addr = s2.phys; } 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, MMUAccessType access_type, ARMMMUIdx mmu_idx, - hwaddr *phys_ptr, int *prot, - target_ulong *page_size, + bool is_secure, GetPhysAddrResult *result, ARMMMUFaultInfo *fi) { int level = 1; @@ -442,8 +434,7 @@ static bool get_phys_addr_v5(CPUARMState *env, uint32_t address, fi->type = ARMFault_Translation; 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) { goto do_fault; } @@ -471,7 +462,7 @@ static bool get_phys_addr_v5(CPUARMState *env, uint32_t address, /* 1Mb section. */ phys_addr = (desc & 0xfff00000) | (address & 0x000fffff); ap = (desc >> 10) & 3; - *page_size = 1024 * 1024; + result->page_size = 1024 * 1024; } else { /* Lookup l2 entry. */ if (type == 1) { @@ -481,8 +472,7 @@ static bool get_phys_addr_v5(CPUARMState *env, uint32_t address, /* Fine pagetable. */ 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) { goto do_fault; } @@ -493,12 +483,12 @@ static bool get_phys_addr_v5(CPUARMState *env, uint32_t address, case 1: /* 64k page. */ phys_addr = (desc & 0xffff0000) | (address & 0xffff); ap = (desc >> (4 + ((address >> 13) & 6))) & 3; - *page_size = 0x10000; + result->page_size = 0x10000; break; case 2: /* 4k page. */ phys_addr = (desc & 0xfffff000) | (address & 0xfff); ap = (desc >> (4 + ((address >> 9) & 6))) & 3; - *page_size = 0x1000; + result->page_size = 0x1000; break; case 3: /* 1k page, or ARMv6/XScale "extended small (4k) page" */ 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) || arm_feature(env, ARM_FEATURE_V6)) { phys_addr = (desc & 0xfffff000) | (address & 0xfff); - *page_size = 0x1000; + result->page_size = 0x1000; } else { /* * UNPREDICTABLE in ARMv5; we choose to take a @@ -517,7 +507,7 @@ static bool get_phys_addr_v5(CPUARMState *env, uint32_t address, } } else { phys_addr = (desc & 0xfffffc00) | (address & 0x3ff); - *page_size = 0x400; + result->page_size = 0x400; } ap = (desc >> 4) & 3; break; @@ -526,14 +516,14 @@ static bool get_phys_addr_v5(CPUARMState *env, uint32_t address, 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. */ fi->type = ARMFault_Permission; goto do_fault; } - *phys_ptr = phys_addr; + result->phys = phys_addr; return false; do_fault: fi->domain = domain; @@ -543,8 +533,8 @@ do_fault: static bool get_phys_addr_v6(CPUARMState *env, uint32_t address, 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); int level = 1; @@ -567,8 +557,7 @@ static bool get_phys_addr_v6(CPUARMState *env, uint32_t address, fi->type = ARMFault_Translation; 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) { 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 |= (uint64_t)extract32(desc, 20, 4) << 32; phys_addr |= (uint64_t)extract32(desc, 5, 4) << 36; - *page_size = 0x1000000; + result->page_size = 0x1000000; } else { /* Section. */ phys_addr = (desc & 0xfff00000) | (address & 0x000fffff); - *page_size = 0x100000; + result->page_size = 0x100000; } ap = ((desc >> 10) & 3) | ((desc >> 13) & 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); /* Lookup l2 entry. */ 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) { goto do_fault; } @@ -634,12 +622,12 @@ static bool get_phys_addr_v6(CPUARMState *env, uint32_t address, case 1: /* 64k page. */ phys_addr = (desc & 0xffff0000) | (address & 0xffff); xn = desc & (1 << 15); - *page_size = 0x10000; + result->page_size = 0x10000; break; case 2: case 3: /* 4k page. */ phys_addr = (desc & 0xfffff000) | (address & 0xfff); xn = desc & 1; - *page_size = 0x1000; + result->page_size = 0x1000; break; default: /* 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) { - *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC; + result->prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC; } else { if (pxn && !regime_is_user(env, mmu_idx)) { xn = 1; @@ -665,14 +653,14 @@ static bool get_phys_addr_v6(CPUARMState *env, uint32_t address, fi->type = ARMFault_AccessFlag; 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 { - *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. */ fi->type = ARMFault_Permission; 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 * 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; do_fault: 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 * walk for an EL0 access. If @mmu_idx is anything else, * @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 - * @cacheattrs: (if non-NULL) set to the cacheability/shareability attributes */ static bool get_phys_addr_lpae(CPUARMState *env, uint64_t address, 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); /* 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) { ns = mmu_idx == ARMMMUIdx_Stage2; 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 { ns = extract32(attrs, 3, 1); xn = extract32(attrs, 12, 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; - if (!(*prot & (1 << access_type))) { + if (!(result->prot & (1 << access_type))) { 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 * 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. */ 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) { - 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 { /* Index into MAIR registers for cache attributes */ uint8_t attrindx = extract32(attrs, 0, 3); uint64_t mair = env->cp15.mair_el[regime_el(env, mmu_idx)]; 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. */ if (param.ds) { - cacheattrs->shareability = param.sh; + result->cacheattrs.shareability = param.sh; } 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; do_fault: @@ -1367,7 +1349,7 @@ do_fault: static bool get_phys_addr_pmsav5(CPUARMState *env, uint32_t address, MMUAccessType access_type, ARMMMUIdx mmu_idx, - hwaddr *phys_ptr, int *prot, + bool is_secure, GetPhysAddrResult *result, ARMMMUFaultInfo *fi) { int n; @@ -1377,12 +1359,12 @@ static bool get_phys_addr_pmsav5(CPUARMState *env, uint32_t address, if (regime_translation_disabled(env, mmu_idx)) { /* 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; } - *phys_ptr = address; + result->phys = address; for (n = 7; n >= 0; n--) { base = env->cp15.c6_region[n]; if ((base & 1) == 0) { @@ -1418,16 +1400,16 @@ static bool get_phys_addr_pmsav5(CPUARMState *env, uint32_t address, fi->level = 1; return true; } - *prot = PAGE_READ | PAGE_WRITE; + result->prot = PAGE_READ | PAGE_WRITE; break; case 2: - *prot = PAGE_READ; + result->prot = PAGE_READ; if (!is_user) { - *prot |= PAGE_WRITE; + result->prot |= PAGE_WRITE; } break; case 3: - *prot = PAGE_READ | PAGE_WRITE; + result->prot = PAGE_READ | PAGE_WRITE; break; case 5: if (is_user) { @@ -1435,10 +1417,10 @@ static bool get_phys_addr_pmsav5(CPUARMState *env, uint32_t address, fi->level = 1; return true; } - *prot = PAGE_READ; + result->prot = PAGE_READ; break; case 6: - *prot = PAGE_READ; + result->prot = PAGE_READ; break; default: /* Bad permission. */ @@ -1446,7 +1428,7 @@ static bool get_phys_addr_pmsav5(CPUARMState *env, uint32_t address, fi->level = 1; return true; } - *prot |= PAGE_EXEC; + result->prot |= PAGE_EXEC; 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, - bool is_user) + bool is_secure, bool is_user) { /* * 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)) { - 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 { 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, MMUAccessType access_type, ARMMMUIdx mmu_idx, - hwaddr *phys_ptr, int *prot, - target_ulong *page_size, + bool secure, GetPhysAddrResult *result, ARMMMUFaultInfo *fi) { ARMCPU *cpu = env_archcpu(env); int n; 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) || 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 * 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 */ for (n = (int)cpu->pmsav7_dregion - 1; n >= 0; n--) { /* region search */ @@ -1593,7 +1573,7 @@ static bool get_phys_addr_pmsav7(CPUARMState *env, uint32_t address, if (ranges_overlap(base, rmask, address & TARGET_PAGE_MASK, TARGET_PAGE_SIZE)) { - *page_size = 1; + result->page_size = 1; } continue; } @@ -1631,18 +1611,18 @@ static bool get_phys_addr_pmsav7(CPUARMState *env, uint32_t address, continue; } if (rsize < TARGET_PAGE_BITS) { - *page_size = 1 << rsize; + result->page_size = 1 << rsize; } break; } 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 */ fi->type = ARMFault_Background; 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! */ uint32_t ap = extract32(env->pmsav7.dracr[n], 8, 3); 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: break; /* no access */ case 3: - *prot |= PAGE_WRITE; + result->prot |= PAGE_WRITE; /* fall through */ case 2: case 6: - *prot |= PAGE_READ | PAGE_EXEC; + result->prot |= PAGE_READ | PAGE_EXEC; break; case 7: /* for v7M, same as 6; for R profile a reserved value */ if (arm_feature(env, ARM_FEATURE_M)) { - *prot |= PAGE_READ | PAGE_EXEC; + result->prot |= PAGE_READ | PAGE_EXEC; break; } /* fall through */ @@ -1684,16 +1664,16 @@ static bool get_phys_addr_pmsav7(CPUARMState *env, uint32_t address, case 1: case 2: case 3: - *prot |= PAGE_WRITE; + result->prot |= PAGE_WRITE; /* fall through */ case 5: case 6: - *prot |= PAGE_READ | PAGE_EXEC; + result->prot |= PAGE_READ | PAGE_EXEC; break; case 7: /* for v7M, same as 6; for R profile a reserved value */ if (arm_feature(env, ARM_FEATURE_M)) { - *prot |= PAGE_READ | PAGE_EXEC; + result->prot |= PAGE_READ | PAGE_EXEC; break; } /* fall through */ @@ -1706,20 +1686,19 @@ static bool get_phys_addr_pmsav7(CPUARMState *env, uint32_t address, /* execute never */ if (xn) { - *prot &= ~PAGE_EXEC; + result->prot &= ~PAGE_EXEC; } } } fi->type = ARMFault_Permission; fi->level = 1; - return !(*prot & (1 << access_type)); + return !(result->prot & (1 << access_type)); } 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, + bool secure, GetPhysAddrResult *result, 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, * or -1 if no region number is returned (MPU off, address did not * 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); bool is_user = regime_is_user(env, mmu_idx); - uint32_t secure = regime_is_secure(env, mmu_idx); int n; int matchregion = -1; bool hit = false; uint32_t addr_page_base = address & TARGET_PAGE_MASK; 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) { *mregion = -1; } @@ -1759,7 +1738,7 @@ bool pmsav8_mpu_lookup(CPUARMState *env, uint32_t address, } else if (m_is_ppb_region(env, address)) { hit = true; } else { - if (pmsav7_use_background_region(cpu, mmu_idx, is_user)) { + if (pmsav7_use_background_region(cpu, mmu_idx, secure, is_user)) { hit = true; } @@ -1792,13 +1771,13 @@ bool pmsav8_mpu_lookup(CPUARMState *env, uint32_t address, ranges_overlap(base, limit - base + 1, addr_page_base, TARGET_PAGE_SIZE)) { - *is_subpage = true; + result->page_size = 1; } continue; } if (base > addr_page_base || limit < addr_page_limit) { - *is_subpage = true; + result->page_size = 1; } if (matchregion != -1) { @@ -1824,7 +1803,7 @@ bool pmsav8_mpu_lookup(CPUARMState *env, uint32_t address, if (matchregion == -1) { /* 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 { uint32_t ap = extract32(env->pmsav8.rbar[secure][matchregion], 1, 2); 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; } - *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 @@ -1854,7 +1833,7 @@ bool pmsav8_mpu_lookup(CPUARMState *env, uint32_t address, fi->type = ARMFault_Permission; fi->level = 1; - return !(*prot & (1 << access_type)); + return !(result->prot & (1 << access_type)); } 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, - 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 @@ -1903,7 +1882,7 @@ void v8m_security_lookup(CPUARMState *env, uint32_t address, } if (idau_exempt || v8m_is_sau_exempt(env, address, access_type)) { - sattrs->ns = !regime_is_secure(env, mmu_idx); + sattrs->ns = !is_secure; 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, MMUAccessType access_type, ARMMMUIdx mmu_idx, - hwaddr *phys_ptr, MemTxAttrs *txattrs, - int *prot, target_ulong *page_size, + bool secure, GetPhysAddrResult *result, ARMMMUFaultInfo *fi) { - uint32_t secure = regime_is_secure(env, mmu_idx); V8M_SAttributes sattrs = {}; bool ret; - bool mpu_is_subpage; 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) { /* * 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 { 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; } } else { @@ -2032,7 +2009,7 @@ static bool get_phys_addr_pmsav8(CPUARMState *env, uint32_t address, * might downgrade a secure access to nonsecure. */ if (sattrs.ns) { - txattrs->secure = false; + result->attrs.secure = false; } else if (!secure) { /* * 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(). */ 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; } } } - 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; } @@ -2300,20 +2279,15 @@ static ARMCacheAttrs combine_cacheattrs(CPUARMState *env, * @address: virtual address to get physical address for * @access_type: 0 for read, 1 for write, 2 for execute * @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 - * @cacheattrs: (if non-NULL) set to the cacheability/shareability attributes */ bool get_phys_addr(CPUARMState *env, target_ulong address, 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); + bool is_secure = regime_is_secure(env, 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)) { hwaddr ipa; - int s2_prot; + int s1_prot; int ret; bool ipa_secure; - ARMCacheAttrs cacheattrs2 = {}; + ARMCacheAttrs cacheattrs1; ARMMMUIdx s2_mmu_idx; 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 (ret || regime_translation_disabled(env, ARMMMUIdx_Stage2)) { - *phys_ptr = ipa; return ret; } - ipa_secure = attrs->secure; + ipa = result->phys; + ipa_secure = result->attrs.secure; if (arm_is_secure_below_el3(env)) { if (ipa_secure) { - attrs->secure = !(env->cp15.vstcr_el2 & VSTCR_SW); + result->attrs.secure = !(env->cp15.vstcr_el2 & VSTCR_SW); } else { - attrs->secure = !(env->cp15.vtcr_el2 & VTCR_NSW); + result->attrs.secure = !(env->cp15.vtcr_el2 & VTCR_NSW); } } else { 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; - /* 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; + /* Combine the S1 and S2 perms. */ - *prot &= s2_prot; + result->prot &= s1_prot; /* If S2 fails, return early. */ if (ret) { @@ -2374,20 +2357,21 @@ bool get_phys_addr(CPUARMState *env, target_ulong address, * Outer Write-Back Read-Allocate Write-Allocate. * 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. */ if (arm_is_secure_below_el3(env)) { if (ipa_secure) { - attrs->secure = + result->attrs.secure = !(env->cp15.vstcr_el2 & (VSTCR_SA | VSTCR_SW)); } else { - attrs->secure = + result->attrs.secure = !((env->cp15.vtcr_el2 & (VTCR_NSA | VTCR_NSW)) || (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 * 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. @@ -2424,20 +2408,20 @@ bool get_phys_addr(CPUARMState *env, target_ulong address, if (arm_feature(env, ARM_FEATURE_PMSA)) { bool ret; - *page_size = TARGET_PAGE_SIZE; + result->page_size = TARGET_PAGE_SIZE; if (arm_feature(env, ARM_FEATURE_V8)) { /* PMSAv8 */ 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)) { /* PMSAv7 */ ret = get_phys_addr_pmsav7(env, address, access_type, mmu_idx, - phys_ptr, prot, page_size, fi); + is_secure, result, fi); } else { /* Pre-v7 MPU */ 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 " 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"), (uint32_t)address, mmu_idx, 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; } @@ -2492,14 +2476,14 @@ bool get_phys_addr(CPUARMState *env, target_ulong address, 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. */ 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_DCT) { memattr = 0xf0; /* Tagged, Normal, WB, RWA */ @@ -2512,24 +2496,23 @@ bool get_phys_addr(CPUARMState *env, target_ulong address, } else { memattr = 0x44; /* Normal, NC, No */ } - cacheattrs->shareability = 2; /* outer sharable */ + result->cacheattrs.shareability = 2; /* outer sharable */ } else { memattr = 0x00; /* Device, nGnRnE */ } - cacheattrs->attrs = memattr; + result->cacheattrs.attrs = memattr; return 0; } if (regime_using_lpae_format(env, mmu_idx)) { 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) { return get_phys_addr_v6(env, address, access_type, mmu_idx, - phys_ptr, attrs, prot, page_size, fi); + is_secure, result, fi); } else { 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); CPUARMState *env = &cpu->env; - hwaddr phys_addr; - target_ulong page_size; - int prot; - bool ret; + GetPhysAddrResult res = {}; ARMMMUFaultInfo fi = {}; 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) { return -1; } - return phys_addr; + return res.phys; } diff --git a/target/arm/tlb_helper.c b/target/arm/tlb_helper.c index 5a709eab56..ad225b1cb2 100644 --- a/target/arm/tlb_helper.c +++ b/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); 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 @@ -223,25 +220,24 @@ bool arm_cpu_tlb_fill(CPUState *cs, vaddr address, int size, */ ret = get_phys_addr(&cpu->env, address, access_type, core_to_arm_mmu_idx(&cpu->env, mmu_idx), - &phys_addr, &attrs, &prot, &page_size, - &fi, &cacheattrs); + &res, &fi); if (likely(!ret)) { /* * Map a single [sub]page. Regions smaller than our declared * target page size are handled specially, so for those we * 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; } /* 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; } else if (probe) { return false; diff --git a/target/arm/translate-neon.c b/target/arm/translate-neon.c index 321c17e2c7..4016339d46 100644 --- a/target/arm/translate-neon.c +++ b/target/arm/translate-neon.c @@ -584,7 +584,11 @@ static bool trans_VLD_all_lanes(DisasContext *s, arg_VLD_all_lanes *a) case 3: return false; case 4: - align = pow2_align(size + 2); + if (size == 2) { + align = pow2_align(3); + } else { + align = pow2_align(size + 2); + } break; default: g_assert_not_reached(); diff --git a/tests/unit/test-vmstate.c b/tests/unit/test-vmstate.c index 72077b5780..541bb4f63e 100644 --- a/tests/unit/test-vmstate.c +++ b/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) { QEMUFile *f = open_test_file(false); - uint8_t result[size]; + g_autofree uint8_t *result = g_malloc(size); /* 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)); /* Compare that what is on the file is the same that what we expected to be there */ - SUCCESS(memcmp(result, wire, sizeof(result))); + SUCCESS(memcmp(result, wire, size)); /* Must reach EOF */ qemu_get_byte(f); diff --git a/ui/curses.c b/ui/curses.c index 861d63244c..de962faa7c 100644 --- a/ui/curses.c +++ b/ui/curses.c @@ -69,7 +69,7 @@ static void curses_update(DisplayChangeListener *dcl, int x, int y, int w, int h) { 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]; attr_t attrs; short colors; |