v9.0.1 release
-----BEGIN PGP SIGNATURE----- iQFDBAABCAAtFiEEe3O61ovnosKJMUsicBtPaxppPlkFAmZky/sPHG1qdEB0bHMu bXNrLnJ1AAoJEHAbT2saaT5ZbfwIALtGu9NMrjfJTlXyzopqXsHqEw4L/ztZ/aFz oGHs8b5Xti51GY6PcDuNgInWQXTJs6RNcrpzpKPnPoDN4Et7PS5enuMEy687MdXr lyYyMp1QQm2oUBKTkRKAXDnWw23IPSVSHincvKK4EqJJODwRPZNrNu9rsVeLSrqo GTCrapuld1hkhuuZmlqb6weBSTItOLhfc1DMdXWB6n8mpoNXVuYAHNxvwjsYYoqT 12pIHBhvVcErqPl5MpOYSFT8o/kRsYMMMC1jzXf185wi757SlJ64l43daDNmutBT 4rwEZznllgpp0sZurfcFh1wHMMR50TbIXfro05eZZbYd/jShXlc= =RJCg -----END PGP SIGNATURE----- gpgsig -----BEGIN PGP SIGNATURE----- iHUEABYKAB0WIQSq9xYmtep25y1RrMYC5KE/dBVGigUCZnH/MgAKCRAC5KE/dBVG in7bAP9sd46ztdJLrwC/Chjz7PxeymuXOtRlqJ3MSlpao1XnlgD/ZF4M920yloc2 xoKgu50RfieeSh00Y9EQWjzRmMFbvgA= =L0Ju -----END PGP SIGNATURE----- Merge tag 'v9.0.1' into update_qemu_9_0_1 v9.0.1 release
This commit is contained in:
commit
2c7a79e826
@ -26,10 +26,10 @@
|
|||||||
then
|
then
|
||||||
pyvenv/bin/meson configure . -Dbackend_max_links="$LD_JOBS" ;
|
pyvenv/bin/meson configure . -Dbackend_max_links="$LD_JOBS" ;
|
||||||
fi || exit 1;
|
fi || exit 1;
|
||||||
- make -j"$JOBS"
|
- $MAKE -j"$JOBS"
|
||||||
- if test -n "$MAKE_CHECK_ARGS";
|
- if test -n "$MAKE_CHECK_ARGS";
|
||||||
then
|
then
|
||||||
make -j"$JOBS" $MAKE_CHECK_ARGS ;
|
$MAKE -j"$JOBS" $MAKE_CHECK_ARGS ;
|
||||||
fi
|
fi
|
||||||
- ccache --show-stats
|
- ccache --show-stats
|
||||||
|
|
||||||
@ -60,7 +60,7 @@
|
|||||||
- cd build
|
- cd build
|
||||||
- find . -type f -exec touch {} +
|
- find . -type f -exec touch {} +
|
||||||
# Avoid recompiling by hiding ninja with NINJA=":"
|
# Avoid recompiling by hiding ninja with NINJA=":"
|
||||||
- make NINJA=":" $MAKE_CHECK_ARGS
|
- $MAKE NINJA=":" $MAKE_CHECK_ARGS
|
||||||
|
|
||||||
.native_test_job_template:
|
.native_test_job_template:
|
||||||
extends: .common_test_job_template
|
extends: .common_test_job_template
|
||||||
|
@ -575,6 +575,9 @@ tsan-build:
|
|||||||
CONFIGURE_ARGS: --enable-tsan --cc=clang --cxx=clang++
|
CONFIGURE_ARGS: --enable-tsan --cc=clang --cxx=clang++
|
||||||
--enable-trace-backends=ust --disable-slirp
|
--enable-trace-backends=ust --disable-slirp
|
||||||
TARGETS: x86_64-softmmu ppc64-softmmu riscv64-softmmu x86_64-linux-user
|
TARGETS: x86_64-softmmu ppc64-softmmu riscv64-softmmu x86_64-linux-user
|
||||||
|
# Remove when we switch to a distro with clang >= 18
|
||||||
|
# https://github.com/google/sanitizers/issues/1716
|
||||||
|
MAKE: setarch -R make
|
||||||
|
|
||||||
# gcov is a GCC features
|
# gcov is a GCC features
|
||||||
gcov:
|
gcov:
|
||||||
|
@ -57,6 +57,7 @@ x64-freebsd-13-build:
|
|||||||
CIRRUS_VM_RAM: 8G
|
CIRRUS_VM_RAM: 8G
|
||||||
UPDATE_COMMAND: pkg update; pkg upgrade -y
|
UPDATE_COMMAND: pkg update; pkg upgrade -y
|
||||||
INSTALL_COMMAND: pkg install -y
|
INSTALL_COMMAND: pkg install -y
|
||||||
|
CONFIGURE_ARGS: --target-list-exclude=arm-softmmu,i386-softmmu,microblaze-softmmu,mips64el-softmmu,mipsel-softmmu,mips-softmmu,ppc-softmmu,sh4eb-softmmu,xtensa-softmmu
|
||||||
TEST_TARGETS: check
|
TEST_TARGETS: check
|
||||||
|
|
||||||
aarch64-macos-13-base-build:
|
aarch64-macos-13-base-build:
|
||||||
@ -72,6 +73,7 @@ aarch64-macos-13-base-build:
|
|||||||
INSTALL_COMMAND: brew install
|
INSTALL_COMMAND: brew install
|
||||||
PATH_EXTRA: /opt/homebrew/ccache/libexec:/opt/homebrew/gettext/bin
|
PATH_EXTRA: /opt/homebrew/ccache/libexec:/opt/homebrew/gettext/bin
|
||||||
PKG_CONFIG_PATH: /opt/homebrew/curl/lib/pkgconfig:/opt/homebrew/ncurses/lib/pkgconfig:/opt/homebrew/readline/lib/pkgconfig
|
PKG_CONFIG_PATH: /opt/homebrew/curl/lib/pkgconfig:/opt/homebrew/ncurses/lib/pkgconfig:/opt/homebrew/readline/lib/pkgconfig
|
||||||
|
CONFIGURE_ARGS: --target-list-exclude=arm-softmmu,i386-softmmu,microblazeel-softmmu,mips64-softmmu,mipsel-softmmu,mips-softmmu,ppc-softmmu,sh4-softmmu,xtensaeb-softmmu
|
||||||
TEST_TARGETS: check-unit check-block check-qapi-schema check-softfloat check-qtest-x86_64
|
TEST_TARGETS: check-unit check-block check-qapi-schema check-softfloat check-qtest-x86_64
|
||||||
|
|
||||||
aarch64-macos-14-base-build:
|
aarch64-macos-14-base-build:
|
||||||
|
@ -1,9 +1,7 @@
|
|||||||
msys2-64bit:
|
msys2-64bit:
|
||||||
extends: .base_job_template
|
extends: .base_job_template
|
||||||
tags:
|
tags:
|
||||||
- shared-windows
|
- saas-windows-medium-amd64
|
||||||
- windows
|
|
||||||
- windows-1809
|
|
||||||
cache:
|
cache:
|
||||||
key: "$CI_JOB_NAME"
|
key: "$CI_JOB_NAME"
|
||||||
paths:
|
paths:
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
|
|
||||||
#include "qemu/osdep.h"
|
#include "qemu/osdep.h"
|
||||||
#include "sysemu/cryptodev.h"
|
#include "sysemu/cryptodev.h"
|
||||||
|
#include "qemu/error-report.h"
|
||||||
#include "qapi/error.h"
|
#include "qapi/error.h"
|
||||||
#include "standard-headers/linux/virtio_crypto.h"
|
#include "standard-headers/linux/virtio_crypto.h"
|
||||||
#include "crypto/cipher.h"
|
#include "crypto/cipher.h"
|
||||||
@ -396,7 +397,7 @@ static int cryptodev_builtin_create_session(
|
|||||||
case VIRTIO_CRYPTO_HASH_CREATE_SESSION:
|
case VIRTIO_CRYPTO_HASH_CREATE_SESSION:
|
||||||
case VIRTIO_CRYPTO_MAC_CREATE_SESSION:
|
case VIRTIO_CRYPTO_MAC_CREATE_SESSION:
|
||||||
default:
|
default:
|
||||||
error_setg(&local_error, "Unsupported opcode :%" PRIu32 "",
|
error_report("Unsupported opcode :%" PRIu32 "",
|
||||||
sess_info->op_code);
|
sess_info->op_code);
|
||||||
return -VIRTIO_CRYPTO_NOTSUPP;
|
return -VIRTIO_CRYPTO_NOTSUPP;
|
||||||
}
|
}
|
||||||
@ -554,7 +555,7 @@ static int cryptodev_builtin_operation(
|
|||||||
|
|
||||||
if (op_info->session_id >= MAX_NUM_SESSIONS ||
|
if (op_info->session_id >= MAX_NUM_SESSIONS ||
|
||||||
builtin->sessions[op_info->session_id] == NULL) {
|
builtin->sessions[op_info->session_id] == NULL) {
|
||||||
error_setg(&local_error, "Cannot find a valid session id: %" PRIu64 "",
|
error_report("Cannot find a valid session id: %" PRIu64 "",
|
||||||
op_info->session_id);
|
op_info->session_id);
|
||||||
return -VIRTIO_CRYPTO_INVSESS;
|
return -VIRTIO_CRYPTO_INVSESS;
|
||||||
}
|
}
|
||||||
|
11
configure
vendored
11
configure
vendored
@ -411,8 +411,10 @@ else
|
|||||||
# Using uname is really broken, but it is just a fallback for architectures
|
# Using uname is really broken, but it is just a fallback for architectures
|
||||||
# that are going to use TCI anyway
|
# that are going to use TCI anyway
|
||||||
cpu=$(uname -m)
|
cpu=$(uname -m)
|
||||||
|
if test "$host_os" != "bogus"; then
|
||||||
echo "WARNING: unrecognized host CPU, proceeding with 'uname -m' output '$cpu'"
|
echo "WARNING: unrecognized host CPU, proceeding with 'uname -m' output '$cpu'"
|
||||||
fi
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
# Normalise host CPU name to the values used by Meson cross files and in source
|
# Normalise host CPU name to the values used by Meson cross files and in source
|
||||||
# directories, and set multilib cflags. The canonicalization isn't really
|
# directories, and set multilib cflags. The canonicalization isn't really
|
||||||
@ -779,7 +781,7 @@ for opt do
|
|||||||
--*) meson_option_parse "$opt" "$optarg"
|
--*) meson_option_parse "$opt" "$optarg"
|
||||||
;;
|
;;
|
||||||
# Pass through -Dxxxx options to meson
|
# Pass through -Dxxxx options to meson
|
||||||
-D*) meson_options="$meson_options $opt"
|
-D*) meson_option_add "$opt"
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
done
|
done
|
||||||
@ -911,6 +913,13 @@ EOF
|
|||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Now that we are sure that the user did not only want to print the --help
|
||||||
|
# information, we should double-check that the C compiler really works:
|
||||||
|
write_c_skeleton
|
||||||
|
if ! compile_object ; then
|
||||||
|
error_exit "C compiler \"$cc\" either does not exist or does not work."
|
||||||
|
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
|
||||||
|
|
||||||
|
@ -2190,7 +2190,22 @@ static const char *csr_name(int csrno)
|
|||||||
case 0x0383: return "mibound";
|
case 0x0383: return "mibound";
|
||||||
case 0x0384: return "mdbase";
|
case 0x0384: return "mdbase";
|
||||||
case 0x0385: return "mdbound";
|
case 0x0385: return "mdbound";
|
||||||
case 0x03a0: return "pmpcfg3";
|
case 0x03a0: return "pmpcfg0";
|
||||||
|
case 0x03a1: return "pmpcfg1";
|
||||||
|
case 0x03a2: return "pmpcfg2";
|
||||||
|
case 0x03a3: return "pmpcfg3";
|
||||||
|
case 0x03a4: return "pmpcfg4";
|
||||||
|
case 0x03a5: return "pmpcfg5";
|
||||||
|
case 0x03a6: return "pmpcfg6";
|
||||||
|
case 0x03a7: return "pmpcfg7";
|
||||||
|
case 0x03a8: return "pmpcfg8";
|
||||||
|
case 0x03a9: return "pmpcfg9";
|
||||||
|
case 0x03aa: return "pmpcfg10";
|
||||||
|
case 0x03ab: return "pmpcfg11";
|
||||||
|
case 0x03ac: return "pmpcfg12";
|
||||||
|
case 0x03ad: return "pmpcfg13";
|
||||||
|
case 0x03ae: return "pmpcfg14";
|
||||||
|
case 0x03af: return "pmpcfg15";
|
||||||
case 0x03b0: return "pmpaddr0";
|
case 0x03b0: return "pmpaddr0";
|
||||||
case 0x03b1: return "pmpaddr1";
|
case 0x03b1: return "pmpaddr1";
|
||||||
case 0x03b2: return "pmpaddr2";
|
case 0x03b2: return "pmpaddr2";
|
||||||
@ -2207,6 +2222,54 @@ static const char *csr_name(int csrno)
|
|||||||
case 0x03bd: return "pmpaddr13";
|
case 0x03bd: return "pmpaddr13";
|
||||||
case 0x03be: return "pmpaddr14";
|
case 0x03be: return "pmpaddr14";
|
||||||
case 0x03bf: return "pmpaddr15";
|
case 0x03bf: return "pmpaddr15";
|
||||||
|
case 0x03c0: return "pmpaddr16";
|
||||||
|
case 0x03c1: return "pmpaddr17";
|
||||||
|
case 0x03c2: return "pmpaddr18";
|
||||||
|
case 0x03c3: return "pmpaddr19";
|
||||||
|
case 0x03c4: return "pmpaddr20";
|
||||||
|
case 0x03c5: return "pmpaddr21";
|
||||||
|
case 0x03c6: return "pmpaddr22";
|
||||||
|
case 0x03c7: return "pmpaddr23";
|
||||||
|
case 0x03c8: return "pmpaddr24";
|
||||||
|
case 0x03c9: return "pmpaddr25";
|
||||||
|
case 0x03ca: return "pmpaddr26";
|
||||||
|
case 0x03cb: return "pmpaddr27";
|
||||||
|
case 0x03cc: return "pmpaddr28";
|
||||||
|
case 0x03cd: return "pmpaddr29";
|
||||||
|
case 0x03ce: return "pmpaddr30";
|
||||||
|
case 0x03cf: return "pmpaddr31";
|
||||||
|
case 0x03d0: return "pmpaddr32";
|
||||||
|
case 0x03d1: return "pmpaddr33";
|
||||||
|
case 0x03d2: return "pmpaddr34";
|
||||||
|
case 0x03d3: return "pmpaddr35";
|
||||||
|
case 0x03d4: return "pmpaddr36";
|
||||||
|
case 0x03d5: return "pmpaddr37";
|
||||||
|
case 0x03d6: return "pmpaddr38";
|
||||||
|
case 0x03d7: return "pmpaddr39";
|
||||||
|
case 0x03d8: return "pmpaddr40";
|
||||||
|
case 0x03d9: return "pmpaddr41";
|
||||||
|
case 0x03da: return "pmpaddr42";
|
||||||
|
case 0x03db: return "pmpaddr43";
|
||||||
|
case 0x03dc: return "pmpaddr44";
|
||||||
|
case 0x03dd: return "pmpaddr45";
|
||||||
|
case 0x03de: return "pmpaddr46";
|
||||||
|
case 0x03df: return "pmpaddr47";
|
||||||
|
case 0x03e0: return "pmpaddr48";
|
||||||
|
case 0x03e1: return "pmpaddr49";
|
||||||
|
case 0x03e2: return "pmpaddr50";
|
||||||
|
case 0x03e3: return "pmpaddr51";
|
||||||
|
case 0x03e4: return "pmpaddr52";
|
||||||
|
case 0x03e5: return "pmpaddr53";
|
||||||
|
case 0x03e6: return "pmpaddr54";
|
||||||
|
case 0x03e7: return "pmpaddr55";
|
||||||
|
case 0x03e8: return "pmpaddr56";
|
||||||
|
case 0x03e9: return "pmpaddr57";
|
||||||
|
case 0x03ea: return "pmpaddr58";
|
||||||
|
case 0x03eb: return "pmpaddr59";
|
||||||
|
case 0x03ec: return "pmpaddr60";
|
||||||
|
case 0x03ed: return "pmpaddr61";
|
||||||
|
case 0x03ee: return "pmpaddr62";
|
||||||
|
case 0x03ef: return "pmpaddr63";
|
||||||
case 0x0780: return "mtohost";
|
case 0x0780: return "mtohost";
|
||||||
case 0x0781: return "mfromhost";
|
case 0x0781: return "mfromhost";
|
||||||
case 0x0782: return "mreset";
|
case 0x0782: return "mreset";
|
||||||
|
@ -36,7 +36,7 @@ The QEMU PC System emulator simulates the following peripherals:
|
|||||||
- PCI UHCI, OHCI, EHCI or XHCI USB controller and a virtual USB-1.1
|
- PCI UHCI, OHCI, EHCI or XHCI USB controller and a virtual USB-1.1
|
||||||
hub.
|
hub.
|
||||||
|
|
||||||
SMP is supported with up to 255 CPUs.
|
SMP is supported with up to 255 CPUs (and 4096 CPUs for PC Q35 machine).
|
||||||
|
|
||||||
QEMU uses the PC BIOS from the Seabios project and the Plex86/Bochs LGPL
|
QEMU uses the PC BIOS from the Seabios project and the Plex86/Bochs LGPL
|
||||||
VGA BIOS.
|
VGA BIOS.
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
#include "hw/qdev-clock.h"
|
#include "hw/qdev-clock.h"
|
||||||
#include "hw/qdev-properties.h"
|
#include "hw/qdev-properties.h"
|
||||||
#include "qapi/error.h"
|
#include "qapi/error.h"
|
||||||
|
#include "qemu/bswap.h"
|
||||||
#include "qemu/units.h"
|
#include "qemu/units.h"
|
||||||
#include "sysemu/sysemu.h"
|
#include "sysemu/sysemu.h"
|
||||||
#include "target/arm/cpu-qom.h"
|
#include "target/arm/cpu-qom.h"
|
||||||
@ -386,7 +387,7 @@ static void npcm7xx_init_fuses(NPCM7xxState *s)
|
|||||||
* The initial mask of disabled modules indicates the chip derivative (e.g.
|
* The initial mask of disabled modules indicates the chip derivative (e.g.
|
||||||
* NPCM750 or NPCM730).
|
* NPCM750 or NPCM730).
|
||||||
*/
|
*/
|
||||||
value = tswap32(nc->disabled_modules);
|
value = cpu_to_le32(nc->disabled_modules);
|
||||||
npcm7xx_otp_array_write(&s->fuse_array, &value, NPCM7XX_FUSE_DERIVATIVE,
|
npcm7xx_otp_array_write(&s->fuse_array, &value, NPCM7XX_FUSE_DERIVATIVE,
|
||||||
sizeof(value));
|
sizeof(value));
|
||||||
}
|
}
|
||||||
|
@ -518,10 +518,6 @@ static void pflash_write(PFlashCFI01 *pfl, hwaddr offset,
|
|||||||
break;
|
break;
|
||||||
case 0xe8: /* Write to buffer */
|
case 0xe8: /* Write to buffer */
|
||||||
trace_pflash_write(pfl->name, "write to buffer");
|
trace_pflash_write(pfl->name, "write to buffer");
|
||||||
/* FIXME should save @offset, @width for case 1+ */
|
|
||||||
qemu_log_mask(LOG_UNIMP,
|
|
||||||
"%s: Write to buffer emulation is flawed\n",
|
|
||||||
__func__);
|
|
||||||
pfl->status |= 0x80; /* Ready! */
|
pfl->status |= 0x80; /* Ready! */
|
||||||
break;
|
break;
|
||||||
case 0xf0: /* Probe for AMD flash */
|
case 0xf0: /* Probe for AMD flash */
|
||||||
@ -574,7 +570,6 @@ static void pflash_write(PFlashCFI01 *pfl, hwaddr offset,
|
|||||||
}
|
}
|
||||||
pfl->counter = value;
|
pfl->counter = value;
|
||||||
pfl->wcycle++;
|
pfl->wcycle++;
|
||||||
pflash_blk_write_start(pfl, offset);
|
|
||||||
break;
|
break;
|
||||||
case 0x60:
|
case 0x60:
|
||||||
if (cmd == 0xd0) {
|
if (cmd == 0xd0) {
|
||||||
@ -605,6 +600,9 @@ static void pflash_write(PFlashCFI01 *pfl, hwaddr offset,
|
|||||||
switch (pfl->cmd) {
|
switch (pfl->cmd) {
|
||||||
case 0xe8: /* Block write */
|
case 0xe8: /* Block write */
|
||||||
/* FIXME check @offset, @width */
|
/* FIXME check @offset, @width */
|
||||||
|
if (pfl->blk_offset == -1 && pfl->counter) {
|
||||||
|
pflash_blk_write_start(pfl, offset);
|
||||||
|
}
|
||||||
if (!pfl->ro && (pfl->blk_offset != -1)) {
|
if (!pfl->ro && (pfl->blk_offset != -1)) {
|
||||||
pflash_data_write(pfl, offset, value, width, be);
|
pflash_data_write(pfl, offset, value, width, be);
|
||||||
} else {
|
} else {
|
||||||
|
@ -37,6 +37,7 @@ GlobalProperty hw_compat_8_2[] = {
|
|||||||
{ "migration", "zero-page-detection", "legacy"},
|
{ "migration", "zero-page-detection", "legacy"},
|
||||||
{ TYPE_VIRTIO_IOMMU_PCI, "granule", "4k" },
|
{ TYPE_VIRTIO_IOMMU_PCI, "granule", "4k" },
|
||||||
{ TYPE_VIRTIO_IOMMU_PCI, "aw-bits", "64" },
|
{ TYPE_VIRTIO_IOMMU_PCI, "aw-bits", "64" },
|
||||||
|
{ "virtio-gpu-device", "x-scanout-vmstate-version", "1" },
|
||||||
};
|
};
|
||||||
const size_t hw_compat_8_2_len = G_N_ELEMENTS(hw_compat_8_2);
|
const size_t hw_compat_8_2_len = G_N_ELEMENTS(hw_compat_8_2);
|
||||||
|
|
||||||
@ -45,15 +46,15 @@ GlobalProperty hw_compat_8_1[] = {
|
|||||||
{ "ramfb", "x-migrate", "off" },
|
{ "ramfb", "x-migrate", "off" },
|
||||||
{ "vfio-pci-nohotplug", "x-ramfb-migrate", "off" },
|
{ "vfio-pci-nohotplug", "x-ramfb-migrate", "off" },
|
||||||
{ "igb", "x-pcie-flr-init", "off" },
|
{ "igb", "x-pcie-flr-init", "off" },
|
||||||
|
{ TYPE_VIRTIO_NET, "host_uso", "off"},
|
||||||
|
{ TYPE_VIRTIO_NET, "guest_uso4", "off"},
|
||||||
|
{ TYPE_VIRTIO_NET, "guest_uso6", "off"},
|
||||||
};
|
};
|
||||||
const size_t hw_compat_8_1_len = G_N_ELEMENTS(hw_compat_8_1);
|
const size_t hw_compat_8_1_len = G_N_ELEMENTS(hw_compat_8_1);
|
||||||
|
|
||||||
GlobalProperty hw_compat_8_0[] = {
|
GlobalProperty hw_compat_8_0[] = {
|
||||||
{ "migration", "multifd-flush-after-each-section", "on"},
|
{ "migration", "multifd-flush-after-each-section", "on"},
|
||||||
{ TYPE_PCI_DEVICE, "x-pcie-ari-nextfn-1", "on" },
|
{ TYPE_PCI_DEVICE, "x-pcie-ari-nextfn-1", "on" },
|
||||||
{ TYPE_VIRTIO_NET, "host_uso", "off"},
|
|
||||||
{ TYPE_VIRTIO_NET, "guest_uso4", "off"},
|
|
||||||
{ TYPE_VIRTIO_NET, "guest_uso6", "off"},
|
|
||||||
};
|
};
|
||||||
const size_t hw_compat_8_0_len = G_N_ELEMENTS(hw_compat_8_0);
|
const size_t hw_compat_8_0_len = G_N_ELEMENTS(hw_compat_8_0);
|
||||||
|
|
||||||
|
@ -1166,10 +1166,17 @@ static void virtio_gpu_cursor_bh(void *opaque)
|
|||||||
virtio_gpu_handle_cursor(&g->parent_obj.parent_obj, g->cursor_vq);
|
virtio_gpu_handle_cursor(&g->parent_obj.parent_obj, g->cursor_vq);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool scanout_vmstate_after_v2(void *opaque, int version)
|
||||||
|
{
|
||||||
|
struct VirtIOGPUBase *base = container_of(opaque, VirtIOGPUBase, scanout);
|
||||||
|
struct VirtIOGPU *gpu = container_of(base, VirtIOGPU, parent_obj);
|
||||||
|
|
||||||
|
return gpu->scanout_vmstate_version >= 2;
|
||||||
|
}
|
||||||
|
|
||||||
static const VMStateDescription vmstate_virtio_gpu_scanout = {
|
static const VMStateDescription vmstate_virtio_gpu_scanout = {
|
||||||
.name = "virtio-gpu-one-scanout",
|
.name = "virtio-gpu-one-scanout",
|
||||||
.version_id = 2,
|
.version_id = 1,
|
||||||
.minimum_version_id = 1,
|
|
||||||
.fields = (const VMStateField[]) {
|
.fields = (const VMStateField[]) {
|
||||||
VMSTATE_UINT32(resource_id, struct virtio_gpu_scanout),
|
VMSTATE_UINT32(resource_id, struct virtio_gpu_scanout),
|
||||||
VMSTATE_UINT32(width, struct virtio_gpu_scanout),
|
VMSTATE_UINT32(width, struct virtio_gpu_scanout),
|
||||||
@ -1181,12 +1188,18 @@ static const VMStateDescription vmstate_virtio_gpu_scanout = {
|
|||||||
VMSTATE_UINT32(cursor.hot_y, struct virtio_gpu_scanout),
|
VMSTATE_UINT32(cursor.hot_y, struct virtio_gpu_scanout),
|
||||||
VMSTATE_UINT32(cursor.pos.x, struct virtio_gpu_scanout),
|
VMSTATE_UINT32(cursor.pos.x, struct virtio_gpu_scanout),
|
||||||
VMSTATE_UINT32(cursor.pos.y, struct virtio_gpu_scanout),
|
VMSTATE_UINT32(cursor.pos.y, struct virtio_gpu_scanout),
|
||||||
VMSTATE_UINT32_V(fb.format, struct virtio_gpu_scanout, 2),
|
VMSTATE_UINT32_TEST(fb.format, struct virtio_gpu_scanout,
|
||||||
VMSTATE_UINT32_V(fb.bytes_pp, struct virtio_gpu_scanout, 2),
|
scanout_vmstate_after_v2),
|
||||||
VMSTATE_UINT32_V(fb.width, struct virtio_gpu_scanout, 2),
|
VMSTATE_UINT32_TEST(fb.bytes_pp, struct virtio_gpu_scanout,
|
||||||
VMSTATE_UINT32_V(fb.height, struct virtio_gpu_scanout, 2),
|
scanout_vmstate_after_v2),
|
||||||
VMSTATE_UINT32_V(fb.stride, struct virtio_gpu_scanout, 2),
|
VMSTATE_UINT32_TEST(fb.width, struct virtio_gpu_scanout,
|
||||||
VMSTATE_UINT32_V(fb.offset, struct virtio_gpu_scanout, 2),
|
scanout_vmstate_after_v2),
|
||||||
|
VMSTATE_UINT32_TEST(fb.height, struct virtio_gpu_scanout,
|
||||||
|
scanout_vmstate_after_v2),
|
||||||
|
VMSTATE_UINT32_TEST(fb.stride, struct virtio_gpu_scanout,
|
||||||
|
scanout_vmstate_after_v2),
|
||||||
|
VMSTATE_UINT32_TEST(fb.offset, struct virtio_gpu_scanout,
|
||||||
|
scanout_vmstate_after_v2),
|
||||||
VMSTATE_END_OF_LIST()
|
VMSTATE_END_OF_LIST()
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
@ -1659,6 +1672,7 @@ static Property virtio_gpu_properties[] = {
|
|||||||
DEFINE_PROP_BIT("blob", VirtIOGPU, parent_obj.conf.flags,
|
DEFINE_PROP_BIT("blob", VirtIOGPU, parent_obj.conf.flags,
|
||||||
VIRTIO_GPU_FLAG_BLOB_ENABLED, false),
|
VIRTIO_GPU_FLAG_BLOB_ENABLED, false),
|
||||||
DEFINE_PROP_SIZE("hostmem", VirtIOGPU, parent_obj.conf.hostmem, 0),
|
DEFINE_PROP_SIZE("hostmem", VirtIOGPU, parent_obj.conf.hostmem, 0),
|
||||||
|
DEFINE_PROP_UINT8("x-scanout-vmstate-version", VirtIOGPU, scanout_vmstate_version, 2),
|
||||||
DEFINE_PROP_END_OF_LIST(),
|
DEFINE_PROP_END_OF_LIST(),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -175,24 +175,24 @@ static uint64_t xlnx_dpdma_desc_get_source_address(DPDMADescriptor *desc,
|
|||||||
|
|
||||||
switch (frag) {
|
switch (frag) {
|
||||||
case 0:
|
case 0:
|
||||||
addr = desc->source_address
|
addr = (uint64_t)desc->source_address
|
||||||
+ (extract32(desc->address_extension, 16, 12) << 20);
|
+ (extract64(desc->address_extension, 16, 16) << 32);
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
addr = desc->source_address2
|
addr = (uint64_t)desc->source_address2
|
||||||
+ (extract32(desc->address_extension_23, 0, 12) << 8);
|
+ (extract64(desc->address_extension_23, 0, 16) << 32);
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
addr = desc->source_address3
|
addr = (uint64_t)desc->source_address3
|
||||||
+ (extract32(desc->address_extension_23, 16, 12) << 20);
|
+ (extract64(desc->address_extension_23, 16, 16) << 32);
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
addr = desc->source_address4
|
addr = (uint64_t)desc->source_address4
|
||||||
+ (extract32(desc->address_extension_45, 0, 12) << 8);
|
+ (extract64(desc->address_extension_45, 0, 16) << 32);
|
||||||
break;
|
break;
|
||||||
case 4:
|
case 4:
|
||||||
addr = desc->source_address5
|
addr = (uint64_t)desc->source_address5
|
||||||
+ (extract32(desc->address_extension_45, 16, 12) << 20);
|
+ (extract64(desc->address_extension_45, 16, 16) << 32);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
addr = 0;
|
addr = 0;
|
||||||
|
@ -1658,7 +1658,7 @@ static MemTxResult gic_cpu_read(GICState *s, int cpu, int offset,
|
|||||||
*data = s->h_apr[gic_get_vcpu_real_id(cpu)];
|
*data = s->h_apr[gic_get_vcpu_real_id(cpu)];
|
||||||
} else if (gic_cpu_ns_access(s, cpu, attrs)) {
|
} else if (gic_cpu_ns_access(s, cpu, attrs)) {
|
||||||
/* NS view of GICC_APR<n> is the top half of GIC_NSAPR<n> */
|
/* NS view of GICC_APR<n> is the top half of GIC_NSAPR<n> */
|
||||||
*data = gic_apr_ns_view(s, regno, cpu);
|
*data = gic_apr_ns_view(s, cpu, regno);
|
||||||
} else {
|
} else {
|
||||||
*data = s->apr[regno][cpu];
|
*data = s->apr[regno][cpu];
|
||||||
}
|
}
|
||||||
@ -1746,7 +1746,7 @@ static MemTxResult gic_cpu_write(GICState *s, int cpu, int offset,
|
|||||||
s->h_apr[gic_get_vcpu_real_id(cpu)] = value;
|
s->h_apr[gic_get_vcpu_real_id(cpu)] = value;
|
||||||
} else if (gic_cpu_ns_access(s, cpu, attrs)) {
|
} else if (gic_cpu_ns_access(s, cpu, attrs)) {
|
||||||
/* NS view of GICC_APR<n> is the top half of GIC_NSAPR<n> */
|
/* NS view of GICC_APR<n> is the top half of GIC_NSAPR<n> */
|
||||||
gic_apr_write_ns_view(s, regno, cpu, value);
|
gic_apr_write_ns_view(s, cpu, regno, value);
|
||||||
} else {
|
} else {
|
||||||
s->apr[regno][cpu] = value;
|
s->apr[regno][cpu] = value;
|
||||||
}
|
}
|
||||||
|
@ -1000,16 +1000,16 @@ DeviceState *riscv_aplic_create(hwaddr addr, hwaddr size,
|
|||||||
qdev_prop_set_bit(dev, "msimode", msimode);
|
qdev_prop_set_bit(dev, "msimode", msimode);
|
||||||
qdev_prop_set_bit(dev, "mmode", mmode);
|
qdev_prop_set_bit(dev, "mmode", mmode);
|
||||||
|
|
||||||
|
if (parent) {
|
||||||
|
riscv_aplic_add_child(parent, dev);
|
||||||
|
}
|
||||||
|
|
||||||
sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
|
sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
|
||||||
|
|
||||||
if (!is_kvm_aia(msimode)) {
|
if (!is_kvm_aia(msimode)) {
|
||||||
sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, addr);
|
sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (parent) {
|
|
||||||
riscv_aplic_add_child(parent, dev);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!msimode) {
|
if (!msimode) {
|
||||||
for (i = 0; i < num_harts; i++) {
|
for (i = 0; i < num_harts; i++) {
|
||||||
CPUState *cpu = cpu_by_arch_id(hartid_base + i);
|
CPUState *cpu = cpu_by_arch_id(hartid_base + i);
|
||||||
|
@ -333,7 +333,8 @@ static void fdt_add_memory_node(MachineState *ms,
|
|||||||
char *nodename = g_strdup_printf("/memory@%" PRIx64, base);
|
char *nodename = g_strdup_printf("/memory@%" PRIx64, base);
|
||||||
|
|
||||||
qemu_fdt_add_subnode(ms->fdt, nodename);
|
qemu_fdt_add_subnode(ms->fdt, nodename);
|
||||||
qemu_fdt_setprop_cells(ms->fdt, nodename, "reg", 2, base, 2, size);
|
qemu_fdt_setprop_cells(ms->fdt, nodename, "reg", base >> 32, base,
|
||||||
|
size >> 32, size);
|
||||||
qemu_fdt_setprop_string(ms->fdt, nodename, "device_type", "memory");
|
qemu_fdt_setprop_string(ms->fdt, nodename, "device_type", "memory");
|
||||||
|
|
||||||
if (ms->numa_state && ms->numa_state->num_nodes) {
|
if (ms->numa_state && ms->numa_state->num_nodes) {
|
||||||
@ -832,7 +833,6 @@ static void loongarch_init(MachineState *machine)
|
|||||||
const CPUArchIdList *possible_cpus;
|
const CPUArchIdList *possible_cpus;
|
||||||
MachineClass *mc = MACHINE_GET_CLASS(machine);
|
MachineClass *mc = MACHINE_GET_CLASS(machine);
|
||||||
CPUState *cpu;
|
CPUState *cpu;
|
||||||
char *ramName = NULL;
|
|
||||||
struct loaderparams loaderparams = { };
|
struct loaderparams loaderparams = { };
|
||||||
|
|
||||||
if (!cpu_model) {
|
if (!cpu_model) {
|
||||||
@ -892,7 +892,7 @@ static void loongarch_init(MachineState *machine)
|
|||||||
|
|
||||||
for (i = 1; i < nb_numa_nodes; i++) {
|
for (i = 1; i < nb_numa_nodes; i++) {
|
||||||
MemoryRegion *nodemem = g_new(MemoryRegion, 1);
|
MemoryRegion *nodemem = g_new(MemoryRegion, 1);
|
||||||
ramName = g_strdup_printf("loongarch.node%d.ram", i);
|
g_autofree char *ramName = g_strdup_printf("loongarch.node%d.ram", i);
|
||||||
memory_region_init_alias(nodemem, NULL, ramName, machine->ram,
|
memory_region_init_alias(nodemem, NULL, ramName, machine->ram,
|
||||||
offset, numa_info[i].node_mem);
|
offset, numa_info[i].node_mem);
|
||||||
memory_region_add_subregion(address_space_mem, phyAddr, nodemem);
|
memory_region_add_subregion(address_space_mem, phyAddr, nodemem);
|
||||||
|
@ -281,7 +281,7 @@ static ssize_t vfu_object_cfg_access(vfu_ctx_t *vfu_ctx, char * const buf,
|
|||||||
while (bytes > 0) {
|
while (bytes > 0) {
|
||||||
len = (bytes > pci_access_width) ? pci_access_width : bytes;
|
len = (bytes > pci_access_width) ? pci_access_width : bytes;
|
||||||
if (is_write) {
|
if (is_write) {
|
||||||
memcpy(&val, ptr, len);
|
val = ldn_le_p(ptr, len);
|
||||||
pci_host_config_write_common(o->pci_dev, offset,
|
pci_host_config_write_common(o->pci_dev, offset,
|
||||||
pci_config_size(o->pci_dev),
|
pci_config_size(o->pci_dev),
|
||||||
val, len);
|
val, len);
|
||||||
@ -289,7 +289,7 @@ static ssize_t vfu_object_cfg_access(vfu_ctx_t *vfu_ctx, char * const buf,
|
|||||||
} else {
|
} else {
|
||||||
val = pci_host_config_read_common(o->pci_dev, offset,
|
val = pci_host_config_read_common(o->pci_dev, offset,
|
||||||
pci_config_size(o->pci_dev), len);
|
pci_config_size(o->pci_dev), len);
|
||||||
memcpy(ptr, &val, len);
|
stn_le_p(ptr, len, val);
|
||||||
trace_vfu_cfg_read(offset, val);
|
trace_vfu_cfg_read(offset, val);
|
||||||
}
|
}
|
||||||
offset += len;
|
offset += len;
|
||||||
|
@ -126,6 +126,10 @@ static MemTxResult ufs_dma_read_req_upiu(UfsRequest *req)
|
|||||||
copy_size = sizeof(UtpUpiuHeader) + UFS_TRANSACTION_SPECIFIC_FIELD_SIZE +
|
copy_size = sizeof(UtpUpiuHeader) + UFS_TRANSACTION_SPECIFIC_FIELD_SIZE +
|
||||||
data_segment_length;
|
data_segment_length;
|
||||||
|
|
||||||
|
if (copy_size > sizeof(req->req_upiu)) {
|
||||||
|
copy_size = sizeof(req->req_upiu);
|
||||||
|
}
|
||||||
|
|
||||||
ret = ufs_addr_read(u, req_upiu_base_addr, &req->req_upiu, copy_size);
|
ret = ufs_addr_read(u, req_upiu_base_addr, &req->req_upiu, copy_size);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
trace_ufs_err_dma_read_req_upiu(req->slot, req_upiu_base_addr);
|
trace_ufs_err_dma_read_req_upiu(req->slot, req_upiu_base_addr);
|
||||||
@ -225,6 +229,10 @@ static MemTxResult ufs_dma_write_rsp_upiu(UfsRequest *req)
|
|||||||
copy_size = rsp_upiu_byte_len;
|
copy_size = rsp_upiu_byte_len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (copy_size > sizeof(req->rsp_upiu)) {
|
||||||
|
copy_size = sizeof(req->rsp_upiu);
|
||||||
|
}
|
||||||
|
|
||||||
ret = ufs_addr_write(u, rsp_upiu_base_addr, &req->rsp_upiu, copy_size);
|
ret = ufs_addr_write(u, rsp_upiu_base_addr, &req->rsp_upiu, copy_size);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
trace_ufs_err_dma_write_rsp_upiu(req->slot, rsp_upiu_base_addr);
|
trace_ufs_err_dma_write_rsp_upiu(req->slot, rsp_upiu_base_addr);
|
||||||
|
@ -177,6 +177,7 @@ typedef struct VGPUDMABuf {
|
|||||||
struct VirtIOGPU {
|
struct VirtIOGPU {
|
||||||
VirtIOGPUBase parent_obj;
|
VirtIOGPUBase parent_obj;
|
||||||
|
|
||||||
|
uint8_t scanout_vmstate_version;
|
||||||
uint64_t conf_max_hostmem;
|
uint64_t conf_max_hostmem;
|
||||||
|
|
||||||
VirtQueue *ctrl_vq;
|
VirtQueue *ctrl_vq;
|
||||||
|
@ -69,37 +69,40 @@ qio_channel_tls_new_server(QIOChannel *master,
|
|||||||
const char *aclname,
|
const char *aclname,
|
||||||
Error **errp)
|
Error **errp)
|
||||||
{
|
{
|
||||||
QIOChannelTLS *ioc;
|
QIOChannelTLS *tioc;
|
||||||
|
QIOChannel *ioc;
|
||||||
|
|
||||||
ioc = QIO_CHANNEL_TLS(object_new(TYPE_QIO_CHANNEL_TLS));
|
tioc = QIO_CHANNEL_TLS(object_new(TYPE_QIO_CHANNEL_TLS));
|
||||||
|
ioc = QIO_CHANNEL(tioc);
|
||||||
|
|
||||||
ioc->master = master;
|
tioc->master = master;
|
||||||
|
ioc->follow_coroutine_ctx = master->follow_coroutine_ctx;
|
||||||
if (qio_channel_has_feature(master, QIO_CHANNEL_FEATURE_SHUTDOWN)) {
|
if (qio_channel_has_feature(master, QIO_CHANNEL_FEATURE_SHUTDOWN)) {
|
||||||
qio_channel_set_feature(QIO_CHANNEL(ioc), QIO_CHANNEL_FEATURE_SHUTDOWN);
|
qio_channel_set_feature(ioc, QIO_CHANNEL_FEATURE_SHUTDOWN);
|
||||||
}
|
}
|
||||||
object_ref(OBJECT(master));
|
object_ref(OBJECT(master));
|
||||||
|
|
||||||
ioc->session = qcrypto_tls_session_new(
|
tioc->session = qcrypto_tls_session_new(
|
||||||
creds,
|
creds,
|
||||||
NULL,
|
NULL,
|
||||||
aclname,
|
aclname,
|
||||||
QCRYPTO_TLS_CREDS_ENDPOINT_SERVER,
|
QCRYPTO_TLS_CREDS_ENDPOINT_SERVER,
|
||||||
errp);
|
errp);
|
||||||
if (!ioc->session) {
|
if (!tioc->session) {
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
qcrypto_tls_session_set_callbacks(
|
qcrypto_tls_session_set_callbacks(
|
||||||
ioc->session,
|
tioc->session,
|
||||||
qio_channel_tls_write_handler,
|
qio_channel_tls_write_handler,
|
||||||
qio_channel_tls_read_handler,
|
qio_channel_tls_read_handler,
|
||||||
ioc);
|
tioc);
|
||||||
|
|
||||||
trace_qio_channel_tls_new_server(ioc, master, creds, aclname);
|
trace_qio_channel_tls_new_server(tioc, master, creds, aclname);
|
||||||
return ioc;
|
return tioc;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
object_unref(OBJECT(ioc));
|
object_unref(OBJECT(tioc));
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -116,6 +119,7 @@ qio_channel_tls_new_client(QIOChannel *master,
|
|||||||
ioc = QIO_CHANNEL(tioc);
|
ioc = QIO_CHANNEL(tioc);
|
||||||
|
|
||||||
tioc->master = master;
|
tioc->master = master;
|
||||||
|
ioc->follow_coroutine_ctx = master->follow_coroutine_ctx;
|
||||||
if (qio_channel_has_feature(master, QIO_CHANNEL_FEATURE_SHUTDOWN)) {
|
if (qio_channel_has_feature(master, QIO_CHANNEL_FEATURE_SHUTDOWN)) {
|
||||||
qio_channel_set_feature(ioc, QIO_CHANNEL_FEATURE_SHUTDOWN);
|
qio_channel_set_feature(ioc, QIO_CHANNEL_FEATURE_SHUTDOWN);
|
||||||
}
|
}
|
||||||
|
@ -883,6 +883,7 @@ qio_channel_websock_new_server(QIOChannel *master)
|
|||||||
ioc = QIO_CHANNEL(wioc);
|
ioc = QIO_CHANNEL(wioc);
|
||||||
|
|
||||||
wioc->master = master;
|
wioc->master = master;
|
||||||
|
ioc->follow_coroutine_ctx = master->follow_coroutine_ctx;
|
||||||
if (qio_channel_has_feature(master, QIO_CHANNEL_FEATURE_SHUTDOWN)) {
|
if (qio_channel_has_feature(master, QIO_CHANNEL_FEATURE_SHUTDOWN)) {
|
||||||
qio_channel_set_feature(ioc, QIO_CHANNEL_FEATURE_SHUTDOWN);
|
qio_channel_set_feature(ioc, QIO_CHANNEL_FEATURE_SHUTDOWN);
|
||||||
}
|
}
|
||||||
|
@ -2294,18 +2294,13 @@ static abi_long do_setsockopt(int sockfd, int level, int optname,
|
|||||||
switch (optname) {
|
switch (optname) {
|
||||||
case ALG_SET_KEY:
|
case ALG_SET_KEY:
|
||||||
{
|
{
|
||||||
char *alg_key = g_malloc(optlen);
|
char *alg_key = lock_user(VERIFY_READ, optval_addr, optlen, 1);
|
||||||
|
|
||||||
if (!alg_key) {
|
if (!alg_key) {
|
||||||
return -TARGET_ENOMEM;
|
|
||||||
}
|
|
||||||
if (copy_from_user(alg_key, optval_addr, optlen)) {
|
|
||||||
g_free(alg_key);
|
|
||||||
return -TARGET_EFAULT;
|
return -TARGET_EFAULT;
|
||||||
}
|
}
|
||||||
ret = get_errno(setsockopt(sockfd, level, optname,
|
ret = get_errno(setsockopt(sockfd, level, optname,
|
||||||
alg_key, optlen));
|
alg_key, optlen));
|
||||||
g_free(alg_key);
|
unlock_user(alg_key, optval_addr, optlen);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ALG_SET_AEAD_AUTHSIZE:
|
case ALG_SET_AEAD_AUTHSIZE:
|
||||||
|
@ -835,6 +835,16 @@ static void *colo_process_incoming_thread(void *opaque)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Make sure all file formats throw away their mutable metadata */
|
||||||
|
bql_lock();
|
||||||
|
bdrv_activate_all(&local_err);
|
||||||
|
if (local_err) {
|
||||||
|
bql_unlock();
|
||||||
|
error_report_err(local_err);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
bql_unlock();
|
||||||
|
|
||||||
failover_init_state();
|
failover_init_state();
|
||||||
|
|
||||||
mis->to_src_file = qemu_file_get_return_path(mis->from_src_file);
|
mis->to_src_file = qemu_file_get_return_path(mis->from_src_file);
|
||||||
@ -922,7 +932,6 @@ out:
|
|||||||
int coroutine_fn colo_incoming_co(void)
|
int coroutine_fn colo_incoming_co(void)
|
||||||
{
|
{
|
||||||
MigrationIncomingState *mis = migration_incoming_get_current();
|
MigrationIncomingState *mis = migration_incoming_get_current();
|
||||||
Error *local_err = NULL;
|
|
||||||
QemuThread th;
|
QemuThread th;
|
||||||
|
|
||||||
assert(bql_locked());
|
assert(bql_locked());
|
||||||
@ -931,13 +940,6 @@ int coroutine_fn colo_incoming_co(void)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Make sure all file formats throw away their mutable metadata */
|
|
||||||
bdrv_activate_all(&local_err);
|
|
||||||
if (local_err) {
|
|
||||||
error_report_err(local_err);
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
qemu_thread_create(&th, "COLO incoming", colo_process_incoming_thread,
|
qemu_thread_create(&th, "COLO incoming", colo_process_incoming_thread,
|
||||||
mis, QEMU_THREAD_JOINABLE);
|
mis, QEMU_THREAD_JOINABLE);
|
||||||
|
|
||||||
|
28
nbd/client.c
28
nbd/client.c
@ -596,13 +596,31 @@ static int nbd_request_simple_option(QIOChannel *ioc, int opt, bool strict,
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Callback to learn when QIO TLS upgrade is complete */
|
||||||
|
struct NBDTLSClientHandshakeData {
|
||||||
|
bool complete;
|
||||||
|
Error *error;
|
||||||
|
GMainLoop *loop;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void nbd_client_tls_handshake(QIOTask *task, void *opaque)
|
||||||
|
{
|
||||||
|
struct NBDTLSClientHandshakeData *data = opaque;
|
||||||
|
|
||||||
|
qio_task_propagate_error(task, &data->error);
|
||||||
|
data->complete = true;
|
||||||
|
if (data->loop) {
|
||||||
|
g_main_loop_quit(data->loop);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static QIOChannel *nbd_receive_starttls(QIOChannel *ioc,
|
static QIOChannel *nbd_receive_starttls(QIOChannel *ioc,
|
||||||
QCryptoTLSCreds *tlscreds,
|
QCryptoTLSCreds *tlscreds,
|
||||||
const char *hostname, Error **errp)
|
const char *hostname, Error **errp)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
QIOChannelTLS *tioc;
|
QIOChannelTLS *tioc;
|
||||||
struct NBDTLSHandshakeData data = { 0 };
|
struct NBDTLSClientHandshakeData data = { 0 };
|
||||||
|
|
||||||
ret = nbd_request_simple_option(ioc, NBD_OPT_STARTTLS, true, errp);
|
ret = nbd_request_simple_option(ioc, NBD_OPT_STARTTLS, true, errp);
|
||||||
if (ret <= 0) {
|
if (ret <= 0) {
|
||||||
@ -619,18 +637,20 @@ static QIOChannel *nbd_receive_starttls(QIOChannel *ioc,
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
qio_channel_set_name(QIO_CHANNEL(tioc), "nbd-client-tls");
|
qio_channel_set_name(QIO_CHANNEL(tioc), "nbd-client-tls");
|
||||||
data.loop = g_main_loop_new(g_main_context_default(), FALSE);
|
|
||||||
trace_nbd_receive_starttls_tls_handshake();
|
trace_nbd_receive_starttls_tls_handshake();
|
||||||
qio_channel_tls_handshake(tioc,
|
qio_channel_tls_handshake(tioc,
|
||||||
nbd_tls_handshake,
|
nbd_client_tls_handshake,
|
||||||
&data,
|
&data,
|
||||||
NULL,
|
NULL,
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
if (!data.complete) {
|
if (!data.complete) {
|
||||||
|
data.loop = g_main_loop_new(g_main_context_default(), FALSE);
|
||||||
g_main_loop_run(data.loop);
|
g_main_loop_run(data.loop);
|
||||||
}
|
assert(data.complete);
|
||||||
g_main_loop_unref(data.loop);
|
g_main_loop_unref(data.loop);
|
||||||
|
}
|
||||||
|
|
||||||
if (data.error) {
|
if (data.error) {
|
||||||
error_propagate(errp, data.error);
|
error_propagate(errp, data.error);
|
||||||
object_unref(OBJECT(tioc));
|
object_unref(OBJECT(tioc));
|
||||||
|
11
nbd/common.c
11
nbd/common.c
@ -47,17 +47,6 @@ int nbd_drop(QIOChannel *ioc, size_t size, Error **errp)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void nbd_tls_handshake(QIOTask *task,
|
|
||||||
void *opaque)
|
|
||||||
{
|
|
||||||
struct NBDTLSHandshakeData *data = opaque;
|
|
||||||
|
|
||||||
qio_task_propagate_error(task, &data->error);
|
|
||||||
data->complete = true;
|
|
||||||
g_main_loop_quit(data->loop);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
const char *nbd_opt_lookup(uint32_t opt)
|
const char *nbd_opt_lookup(uint32_t opt)
|
||||||
{
|
{
|
||||||
switch (opt) {
|
switch (opt) {
|
||||||
|
@ -72,16 +72,6 @@ static inline int nbd_write(QIOChannel *ioc, const void *buffer, size_t size,
|
|||||||
return qio_channel_write_all(ioc, buffer, size, errp) < 0 ? -EIO : 0;
|
return qio_channel_write_all(ioc, buffer, size, errp) < 0 ? -EIO : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct NBDTLSHandshakeData {
|
|
||||||
GMainLoop *loop;
|
|
||||||
bool complete;
|
|
||||||
Error *error;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
void nbd_tls_handshake(QIOTask *task,
|
|
||||||
void *opaque);
|
|
||||||
|
|
||||||
int nbd_drop(QIOChannel *ioc, size_t size, Error **errp);
|
int nbd_drop(QIOChannel *ioc, size_t size, Error **errp);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
112
nbd/server.c
112
nbd/server.c
@ -195,7 +195,8 @@ static inline void set_be_option_rep(NBDOptionReply *rep, uint32_t option,
|
|||||||
|
|
||||||
/* Send a reply header, including length, but no payload.
|
/* Send a reply header, including length, but no payload.
|
||||||
* Return -errno on error, 0 on success. */
|
* Return -errno on error, 0 on success. */
|
||||||
static int nbd_negotiate_send_rep_len(NBDClient *client, uint32_t type,
|
static coroutine_fn int
|
||||||
|
nbd_negotiate_send_rep_len(NBDClient *client, uint32_t type,
|
||||||
uint32_t len, Error **errp)
|
uint32_t len, Error **errp)
|
||||||
{
|
{
|
||||||
NBDOptionReply rep;
|
NBDOptionReply rep;
|
||||||
@ -211,15 +212,15 @@ static int nbd_negotiate_send_rep_len(NBDClient *client, uint32_t type,
|
|||||||
|
|
||||||
/* Send a reply header with default 0 length.
|
/* Send a reply header with default 0 length.
|
||||||
* Return -errno on error, 0 on success. */
|
* Return -errno on error, 0 on success. */
|
||||||
static int nbd_negotiate_send_rep(NBDClient *client, uint32_t type,
|
static coroutine_fn int
|
||||||
Error **errp)
|
nbd_negotiate_send_rep(NBDClient *client, uint32_t type, Error **errp)
|
||||||
{
|
{
|
||||||
return nbd_negotiate_send_rep_len(client, type, 0, errp);
|
return nbd_negotiate_send_rep_len(client, type, 0, errp);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Send an error reply.
|
/* Send an error reply.
|
||||||
* Return -errno on error, 0 on success. */
|
* Return -errno on error, 0 on success. */
|
||||||
static int G_GNUC_PRINTF(4, 0)
|
static coroutine_fn int G_GNUC_PRINTF(4, 0)
|
||||||
nbd_negotiate_send_rep_verr(NBDClient *client, uint32_t type,
|
nbd_negotiate_send_rep_verr(NBDClient *client, uint32_t type,
|
||||||
Error **errp, const char *fmt, va_list va)
|
Error **errp, const char *fmt, va_list va)
|
||||||
{
|
{
|
||||||
@ -259,7 +260,7 @@ nbd_sanitize_name(const char *name)
|
|||||||
|
|
||||||
/* Send an error reply.
|
/* Send an error reply.
|
||||||
* Return -errno on error, 0 on success. */
|
* Return -errno on error, 0 on success. */
|
||||||
static int G_GNUC_PRINTF(4, 5)
|
static coroutine_fn int G_GNUC_PRINTF(4, 5)
|
||||||
nbd_negotiate_send_rep_err(NBDClient *client, uint32_t type,
|
nbd_negotiate_send_rep_err(NBDClient *client, uint32_t type,
|
||||||
Error **errp, const char *fmt, ...)
|
Error **errp, const char *fmt, ...)
|
||||||
{
|
{
|
||||||
@ -275,7 +276,7 @@ nbd_negotiate_send_rep_err(NBDClient *client, uint32_t type,
|
|||||||
/* Drop remainder of the current option, and send a reply with the
|
/* Drop remainder of the current option, and send a reply with the
|
||||||
* given error type and message. Return -errno on read or write
|
* given error type and message. Return -errno on read or write
|
||||||
* failure; or 0 if connection is still live. */
|
* failure; or 0 if connection is still live. */
|
||||||
static int G_GNUC_PRINTF(4, 0)
|
static coroutine_fn int G_GNUC_PRINTF(4, 0)
|
||||||
nbd_opt_vdrop(NBDClient *client, uint32_t type, Error **errp,
|
nbd_opt_vdrop(NBDClient *client, uint32_t type, Error **errp,
|
||||||
const char *fmt, va_list va)
|
const char *fmt, va_list va)
|
||||||
{
|
{
|
||||||
@ -288,7 +289,7 @@ nbd_opt_vdrop(NBDClient *client, uint32_t type, Error **errp,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int G_GNUC_PRINTF(4, 5)
|
static coroutine_fn int G_GNUC_PRINTF(4, 5)
|
||||||
nbd_opt_drop(NBDClient *client, uint32_t type, Error **errp,
|
nbd_opt_drop(NBDClient *client, uint32_t type, Error **errp,
|
||||||
const char *fmt, ...)
|
const char *fmt, ...)
|
||||||
{
|
{
|
||||||
@ -302,7 +303,7 @@ nbd_opt_drop(NBDClient *client, uint32_t type, Error **errp,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int G_GNUC_PRINTF(3, 4)
|
static coroutine_fn int G_GNUC_PRINTF(3, 4)
|
||||||
nbd_opt_invalid(NBDClient *client, Error **errp, const char *fmt, ...)
|
nbd_opt_invalid(NBDClient *client, Error **errp, const char *fmt, ...)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
@ -319,7 +320,8 @@ nbd_opt_invalid(NBDClient *client, Error **errp, const char *fmt, ...)
|
|||||||
* If @check_nul, require that no NUL bytes appear in buffer.
|
* If @check_nul, require that no NUL bytes appear in buffer.
|
||||||
* Return -errno on I/O error, 0 if option was completely handled by
|
* Return -errno on I/O error, 0 if option was completely handled by
|
||||||
* sending a reply about inconsistent lengths, or 1 on success. */
|
* sending a reply about inconsistent lengths, or 1 on success. */
|
||||||
static int nbd_opt_read(NBDClient *client, void *buffer, size_t size,
|
static coroutine_fn int
|
||||||
|
nbd_opt_read(NBDClient *client, void *buffer, size_t size,
|
||||||
bool check_nul, Error **errp)
|
bool check_nul, Error **errp)
|
||||||
{
|
{
|
||||||
if (size > client->optlen) {
|
if (size > client->optlen) {
|
||||||
@ -343,7 +345,8 @@ static int nbd_opt_read(NBDClient *client, void *buffer, size_t size,
|
|||||||
/* Drop size bytes from the unparsed payload of the current option.
|
/* Drop size bytes from the unparsed payload of the current option.
|
||||||
* Return -errno on I/O error, 0 if option was completely handled by
|
* Return -errno on I/O error, 0 if option was completely handled by
|
||||||
* sending a reply about inconsistent lengths, or 1 on success. */
|
* sending a reply about inconsistent lengths, or 1 on success. */
|
||||||
static int nbd_opt_skip(NBDClient *client, size_t size, Error **errp)
|
static coroutine_fn int
|
||||||
|
nbd_opt_skip(NBDClient *client, size_t size, Error **errp)
|
||||||
{
|
{
|
||||||
if (size > client->optlen) {
|
if (size > client->optlen) {
|
||||||
return nbd_opt_invalid(client, errp,
|
return nbd_opt_invalid(client, errp,
|
||||||
@ -366,7 +369,8 @@ static int nbd_opt_skip(NBDClient *client, size_t size, Error **errp)
|
|||||||
* Return -errno on I/O error, 0 if option was completely handled by
|
* Return -errno on I/O error, 0 if option was completely handled by
|
||||||
* sending a reply about inconsistent lengths, or 1 on success.
|
* sending a reply about inconsistent lengths, or 1 on success.
|
||||||
*/
|
*/
|
||||||
static int nbd_opt_read_name(NBDClient *client, char **name, uint32_t *length,
|
static coroutine_fn int
|
||||||
|
nbd_opt_read_name(NBDClient *client, char **name, uint32_t *length,
|
||||||
Error **errp)
|
Error **errp)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
@ -402,8 +406,8 @@ static int nbd_opt_read_name(NBDClient *client, char **name, uint32_t *length,
|
|||||||
|
|
||||||
/* Send a single NBD_REP_SERVER reply to NBD_OPT_LIST, including payload.
|
/* Send a single NBD_REP_SERVER reply to NBD_OPT_LIST, including payload.
|
||||||
* Return -errno on error, 0 on success. */
|
* Return -errno on error, 0 on success. */
|
||||||
static int nbd_negotiate_send_rep_list(NBDClient *client, NBDExport *exp,
|
static coroutine_fn int
|
||||||
Error **errp)
|
nbd_negotiate_send_rep_list(NBDClient *client, NBDExport *exp, Error **errp)
|
||||||
{
|
{
|
||||||
ERRP_GUARD();
|
ERRP_GUARD();
|
||||||
size_t name_len, desc_len;
|
size_t name_len, desc_len;
|
||||||
@ -444,7 +448,8 @@ static int nbd_negotiate_send_rep_list(NBDClient *client, NBDExport *exp,
|
|||||||
|
|
||||||
/* Process the NBD_OPT_LIST command, with a potential series of replies.
|
/* Process the NBD_OPT_LIST command, with a potential series of replies.
|
||||||
* Return -errno on error, 0 on success. */
|
* Return -errno on error, 0 on success. */
|
||||||
static int nbd_negotiate_handle_list(NBDClient *client, Error **errp)
|
static coroutine_fn int
|
||||||
|
nbd_negotiate_handle_list(NBDClient *client, Error **errp)
|
||||||
{
|
{
|
||||||
NBDExport *exp;
|
NBDExport *exp;
|
||||||
assert(client->opt == NBD_OPT_LIST);
|
assert(client->opt == NBD_OPT_LIST);
|
||||||
@ -459,7 +464,8 @@ static int nbd_negotiate_handle_list(NBDClient *client, Error **errp)
|
|||||||
return nbd_negotiate_send_rep(client, NBD_REP_ACK, errp);
|
return nbd_negotiate_send_rep(client, NBD_REP_ACK, errp);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void nbd_check_meta_export(NBDClient *client, NBDExport *exp)
|
static coroutine_fn void
|
||||||
|
nbd_check_meta_export(NBDClient *client, NBDExport *exp)
|
||||||
{
|
{
|
||||||
if (exp != client->contexts.exp) {
|
if (exp != client->contexts.exp) {
|
||||||
client->contexts.count = 0;
|
client->contexts.count = 0;
|
||||||
@ -468,7 +474,8 @@ static void nbd_check_meta_export(NBDClient *client, NBDExport *exp)
|
|||||||
|
|
||||||
/* Send a reply to NBD_OPT_EXPORT_NAME.
|
/* Send a reply to NBD_OPT_EXPORT_NAME.
|
||||||
* Return -errno on error, 0 on success. */
|
* Return -errno on error, 0 on success. */
|
||||||
static int nbd_negotiate_handle_export_name(NBDClient *client, bool no_zeroes,
|
static coroutine_fn int
|
||||||
|
nbd_negotiate_handle_export_name(NBDClient *client, bool no_zeroes,
|
||||||
Error **errp)
|
Error **errp)
|
||||||
{
|
{
|
||||||
ERRP_GUARD();
|
ERRP_GUARD();
|
||||||
@ -536,9 +543,9 @@ static int nbd_negotiate_handle_export_name(NBDClient *client, bool no_zeroes,
|
|||||||
/* Send a single NBD_REP_INFO, with a buffer @buf of @length bytes.
|
/* Send a single NBD_REP_INFO, with a buffer @buf of @length bytes.
|
||||||
* The buffer does NOT include the info type prefix.
|
* The buffer does NOT include the info type prefix.
|
||||||
* Return -errno on error, 0 if ready to send more. */
|
* Return -errno on error, 0 if ready to send more. */
|
||||||
static int nbd_negotiate_send_info(NBDClient *client,
|
static coroutine_fn int
|
||||||
uint16_t info, uint32_t length, void *buf,
|
nbd_negotiate_send_info(NBDClient *client, uint16_t info, uint32_t length,
|
||||||
Error **errp)
|
void *buf, Error **errp)
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
@ -565,7 +572,8 @@ static int nbd_negotiate_send_info(NBDClient *client,
|
|||||||
* -errno transmission error occurred or @fatal was requested, errp is set
|
* -errno transmission error occurred or @fatal was requested, errp is set
|
||||||
* 0 error message successfully sent to client, errp is not set
|
* 0 error message successfully sent to client, errp is not set
|
||||||
*/
|
*/
|
||||||
static int nbd_reject_length(NBDClient *client, bool fatal, Error **errp)
|
static coroutine_fn int
|
||||||
|
nbd_reject_length(NBDClient *client, bool fatal, Error **errp)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
@ -583,7 +591,8 @@ static int nbd_reject_length(NBDClient *client, bool fatal, Error **errp)
|
|||||||
/* Handle NBD_OPT_INFO and NBD_OPT_GO.
|
/* Handle NBD_OPT_INFO and NBD_OPT_GO.
|
||||||
* Return -errno on error, 0 if ready for next option, and 1 to move
|
* Return -errno on error, 0 if ready for next option, and 1 to move
|
||||||
* into transmission phase. */
|
* into transmission phase. */
|
||||||
static int nbd_negotiate_handle_info(NBDClient *client, Error **errp)
|
static coroutine_fn int
|
||||||
|
nbd_negotiate_handle_info(NBDClient *client, Error **errp)
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
g_autofree char *name = NULL;
|
g_autofree char *name = NULL;
|
||||||
@ -748,15 +757,33 @@ static int nbd_negotiate_handle_info(NBDClient *client, Error **errp)
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Callback to learn when QIO TLS upgrade is complete */
|
||||||
|
struct NBDTLSServerHandshakeData {
|
||||||
|
bool complete;
|
||||||
|
Error *error;
|
||||||
|
Coroutine *co;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void
|
||||||
|
nbd_server_tls_handshake(QIOTask *task, void *opaque)
|
||||||
|
{
|
||||||
|
struct NBDTLSServerHandshakeData *data = opaque;
|
||||||
|
|
||||||
|
qio_task_propagate_error(task, &data->error);
|
||||||
|
data->complete = true;
|
||||||
|
if (!qemu_coroutine_entered(data->co)) {
|
||||||
|
aio_co_wake(data->co);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Handle NBD_OPT_STARTTLS. Return NULL to drop connection, or else the
|
/* Handle NBD_OPT_STARTTLS. Return NULL to drop connection, or else the
|
||||||
* new channel for all further (now-encrypted) communication. */
|
* new channel for all further (now-encrypted) communication. */
|
||||||
static QIOChannel *nbd_negotiate_handle_starttls(NBDClient *client,
|
static coroutine_fn QIOChannel *
|
||||||
Error **errp)
|
nbd_negotiate_handle_starttls(NBDClient *client, Error **errp)
|
||||||
{
|
{
|
||||||
QIOChannel *ioc;
|
QIOChannel *ioc;
|
||||||
QIOChannelTLS *tioc;
|
QIOChannelTLS *tioc;
|
||||||
struct NBDTLSHandshakeData data = { 0 };
|
struct NBDTLSServerHandshakeData data = { 0 };
|
||||||
|
|
||||||
assert(client->opt == NBD_OPT_STARTTLS);
|
assert(client->opt == NBD_OPT_STARTTLS);
|
||||||
|
|
||||||
@ -777,17 +804,18 @@ static QIOChannel *nbd_negotiate_handle_starttls(NBDClient *client,
|
|||||||
|
|
||||||
qio_channel_set_name(QIO_CHANNEL(tioc), "nbd-server-tls");
|
qio_channel_set_name(QIO_CHANNEL(tioc), "nbd-server-tls");
|
||||||
trace_nbd_negotiate_handle_starttls_handshake();
|
trace_nbd_negotiate_handle_starttls_handshake();
|
||||||
data.loop = g_main_loop_new(g_main_context_default(), FALSE);
|
data.co = qemu_coroutine_self();
|
||||||
qio_channel_tls_handshake(tioc,
|
qio_channel_tls_handshake(tioc,
|
||||||
nbd_tls_handshake,
|
nbd_server_tls_handshake,
|
||||||
&data,
|
&data,
|
||||||
NULL,
|
NULL,
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
if (!data.complete) {
|
if (!data.complete) {
|
||||||
g_main_loop_run(data.loop);
|
qemu_coroutine_yield();
|
||||||
|
assert(data.complete);
|
||||||
}
|
}
|
||||||
g_main_loop_unref(data.loop);
|
|
||||||
if (data.error) {
|
if (data.error) {
|
||||||
object_unref(OBJECT(tioc));
|
object_unref(OBJECT(tioc));
|
||||||
error_propagate(errp, data.error);
|
error_propagate(errp, data.error);
|
||||||
@ -803,10 +831,9 @@ static QIOChannel *nbd_negotiate_handle_starttls(NBDClient *client,
|
|||||||
*
|
*
|
||||||
* For NBD_OPT_LIST_META_CONTEXT @context_id is ignored, 0 is used instead.
|
* For NBD_OPT_LIST_META_CONTEXT @context_id is ignored, 0 is used instead.
|
||||||
*/
|
*/
|
||||||
static int nbd_negotiate_send_meta_context(NBDClient *client,
|
static coroutine_fn int
|
||||||
const char *context,
|
nbd_negotiate_send_meta_context(NBDClient *client, const char *context,
|
||||||
uint32_t context_id,
|
uint32_t context_id, Error **errp)
|
||||||
Error **errp)
|
|
||||||
{
|
{
|
||||||
NBDOptionReplyMetaContext opt;
|
NBDOptionReplyMetaContext opt;
|
||||||
struct iovec iov[] = {
|
struct iovec iov[] = {
|
||||||
@ -831,7 +858,8 @@ static int nbd_negotiate_send_meta_context(NBDClient *client,
|
|||||||
* Return true if @query matches @pattern, or if @query is empty when
|
* Return true if @query matches @pattern, or if @query is empty when
|
||||||
* the @client is performing _LIST_.
|
* the @client is performing _LIST_.
|
||||||
*/
|
*/
|
||||||
static bool nbd_meta_empty_or_pattern(NBDClient *client, const char *pattern,
|
static coroutine_fn bool
|
||||||
|
nbd_meta_empty_or_pattern(NBDClient *client, const char *pattern,
|
||||||
const char *query)
|
const char *query)
|
||||||
{
|
{
|
||||||
if (!*query) {
|
if (!*query) {
|
||||||
@ -849,7 +877,8 @@ static bool nbd_meta_empty_or_pattern(NBDClient *client, const char *pattern,
|
|||||||
/*
|
/*
|
||||||
* Return true and adjust @str in place if it begins with @prefix.
|
* Return true and adjust @str in place if it begins with @prefix.
|
||||||
*/
|
*/
|
||||||
static bool nbd_strshift(const char **str, const char *prefix)
|
static coroutine_fn bool
|
||||||
|
nbd_strshift(const char **str, const char *prefix)
|
||||||
{
|
{
|
||||||
size_t len = strlen(prefix);
|
size_t len = strlen(prefix);
|
||||||
|
|
||||||
@ -865,7 +894,8 @@ static bool nbd_strshift(const char **str, const char *prefix)
|
|||||||
* Handle queries to 'base' namespace. For now, only the base:allocation
|
* Handle queries to 'base' namespace. For now, only the base:allocation
|
||||||
* context is available. Return true if @query has been handled.
|
* context is available. Return true if @query has been handled.
|
||||||
*/
|
*/
|
||||||
static bool nbd_meta_base_query(NBDClient *client, NBDMetaContexts *meta,
|
static coroutine_fn bool
|
||||||
|
nbd_meta_base_query(NBDClient *client, NBDMetaContexts *meta,
|
||||||
const char *query)
|
const char *query)
|
||||||
{
|
{
|
||||||
if (!nbd_strshift(&query, "base:")) {
|
if (!nbd_strshift(&query, "base:")) {
|
||||||
@ -885,7 +915,8 @@ static bool nbd_meta_base_query(NBDClient *client, NBDMetaContexts *meta,
|
|||||||
* and qemu:allocation-depth contexts are available. Return true if @query
|
* and qemu:allocation-depth contexts are available. Return true if @query
|
||||||
* has been handled.
|
* has been handled.
|
||||||
*/
|
*/
|
||||||
static bool nbd_meta_qemu_query(NBDClient *client, NBDMetaContexts *meta,
|
static coroutine_fn bool
|
||||||
|
nbd_meta_qemu_query(NBDClient *client, NBDMetaContexts *meta,
|
||||||
const char *query)
|
const char *query)
|
||||||
{
|
{
|
||||||
size_t i;
|
size_t i;
|
||||||
@ -950,7 +981,8 @@ static bool nbd_meta_qemu_query(NBDClient *client, NBDMetaContexts *meta,
|
|||||||
*
|
*
|
||||||
* Return -errno on I/O error, 0 if option was completely handled by
|
* Return -errno on I/O error, 0 if option was completely handled by
|
||||||
* sending a reply about inconsistent lengths, or 1 on success. */
|
* sending a reply about inconsistent lengths, or 1 on success. */
|
||||||
static int nbd_negotiate_meta_query(NBDClient *client,
|
static coroutine_fn int
|
||||||
|
nbd_negotiate_meta_query(NBDClient *client,
|
||||||
NBDMetaContexts *meta, Error **errp)
|
NBDMetaContexts *meta, Error **errp)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
@ -990,7 +1022,8 @@ static int nbd_negotiate_meta_query(NBDClient *client,
|
|||||||
* Handle NBD_OPT_LIST_META_CONTEXT and NBD_OPT_SET_META_CONTEXT
|
* Handle NBD_OPT_LIST_META_CONTEXT and NBD_OPT_SET_META_CONTEXT
|
||||||
*
|
*
|
||||||
* Return -errno on I/O error, or 0 if option was completely handled. */
|
* Return -errno on I/O error, or 0 if option was completely handled. */
|
||||||
static int nbd_negotiate_meta_queries(NBDClient *client, Error **errp)
|
static coroutine_fn int
|
||||||
|
nbd_negotiate_meta_queries(NBDClient *client, Error **errp)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
g_autofree char *export_name = NULL;
|
g_autofree char *export_name = NULL;
|
||||||
@ -1118,7 +1151,8 @@ static int nbd_negotiate_meta_queries(NBDClient *client, Error **errp)
|
|||||||
* 1 if client sent NBD_OPT_ABORT, i.e. on valid disconnect,
|
* 1 if client sent NBD_OPT_ABORT, i.e. on valid disconnect,
|
||||||
* errp is not set
|
* errp is not set
|
||||||
*/
|
*/
|
||||||
static int nbd_negotiate_options(NBDClient *client, Error **errp)
|
static coroutine_fn int
|
||||||
|
nbd_negotiate_options(NBDClient *client, Error **errp)
|
||||||
{
|
{
|
||||||
uint32_t flags;
|
uint32_t flags;
|
||||||
bool fixedNewstyle = false;
|
bool fixedNewstyle = false;
|
||||||
|
@ -373,7 +373,7 @@ void qemu_plugin_tb_trans_cb(CPUState *cpu, struct qemu_plugin_tb *tb)
|
|||||||
struct qemu_plugin_cb *cb, *next;
|
struct qemu_plugin_cb *cb, *next;
|
||||||
enum qemu_plugin_event ev = QEMU_PLUGIN_EV_VCPU_TB_TRANS;
|
enum qemu_plugin_event ev = QEMU_PLUGIN_EV_VCPU_TB_TRANS;
|
||||||
|
|
||||||
/* no plugin_mask check here; caller should have checked */
|
/* no plugin_state->event_mask check here; caller should have checked */
|
||||||
|
|
||||||
QLIST_FOREACH_SAFE_RCU(cb, &plugin.cb_lists[ev], entry, next) {
|
QLIST_FOREACH_SAFE_RCU(cb, &plugin.cb_lists[ev], entry, next) {
|
||||||
qemu_plugin_vcpu_tb_trans_cb_t func = cb->f.vcpu_tb_trans;
|
qemu_plugin_vcpu_tb_trans_cb_t func = cb->f.vcpu_tb_trans;
|
||||||
|
@ -109,7 +109,11 @@ void arm_cpu_sve_finalize(ARMCPU *cpu, Error **errp)
|
|||||||
* No explicit bits enabled, and no implicit bits from sve-max-vq.
|
* No explicit bits enabled, and no implicit bits from sve-max-vq.
|
||||||
*/
|
*/
|
||||||
if (!cpu_isar_feature(aa64_sve, cpu)) {
|
if (!cpu_isar_feature(aa64_sve, cpu)) {
|
||||||
/* SVE is disabled and so are all vector lengths. Good. */
|
/*
|
||||||
|
* SVE is disabled and so are all vector lengths. Good.
|
||||||
|
* Disable all SVE extensions as well.
|
||||||
|
*/
|
||||||
|
cpu->isar.id_aa64zfr0 = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -397,85 +397,85 @@ struct hvf_sreg_match {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static struct hvf_sreg_match hvf_sreg_match[] = {
|
static struct hvf_sreg_match hvf_sreg_match[] = {
|
||||||
{ HV_SYS_REG_DBGBVR0_EL1, HVF_SYSREG(0, 0, 14, 0, 4) },
|
{ HV_SYS_REG_DBGBVR0_EL1, HVF_SYSREG(0, 0, 2, 0, 4) },
|
||||||
{ HV_SYS_REG_DBGBCR0_EL1, HVF_SYSREG(0, 0, 14, 0, 5) },
|
{ HV_SYS_REG_DBGBCR0_EL1, HVF_SYSREG(0, 0, 2, 0, 5) },
|
||||||
{ HV_SYS_REG_DBGWVR0_EL1, HVF_SYSREG(0, 0, 14, 0, 6) },
|
{ HV_SYS_REG_DBGWVR0_EL1, HVF_SYSREG(0, 0, 2, 0, 6) },
|
||||||
{ HV_SYS_REG_DBGWCR0_EL1, HVF_SYSREG(0, 0, 14, 0, 7) },
|
{ HV_SYS_REG_DBGWCR0_EL1, HVF_SYSREG(0, 0, 2, 0, 7) },
|
||||||
|
|
||||||
{ HV_SYS_REG_DBGBVR1_EL1, HVF_SYSREG(0, 1, 14, 0, 4) },
|
{ HV_SYS_REG_DBGBVR1_EL1, HVF_SYSREG(0, 1, 2, 0, 4) },
|
||||||
{ HV_SYS_REG_DBGBCR1_EL1, HVF_SYSREG(0, 1, 14, 0, 5) },
|
{ HV_SYS_REG_DBGBCR1_EL1, HVF_SYSREG(0, 1, 2, 0, 5) },
|
||||||
{ HV_SYS_REG_DBGWVR1_EL1, HVF_SYSREG(0, 1, 14, 0, 6) },
|
{ HV_SYS_REG_DBGWVR1_EL1, HVF_SYSREG(0, 1, 2, 0, 6) },
|
||||||
{ HV_SYS_REG_DBGWCR1_EL1, HVF_SYSREG(0, 1, 14, 0, 7) },
|
{ HV_SYS_REG_DBGWCR1_EL1, HVF_SYSREG(0, 1, 2, 0, 7) },
|
||||||
|
|
||||||
{ HV_SYS_REG_DBGBVR2_EL1, HVF_SYSREG(0, 2, 14, 0, 4) },
|
{ HV_SYS_REG_DBGBVR2_EL1, HVF_SYSREG(0, 2, 2, 0, 4) },
|
||||||
{ HV_SYS_REG_DBGBCR2_EL1, HVF_SYSREG(0, 2, 14, 0, 5) },
|
{ HV_SYS_REG_DBGBCR2_EL1, HVF_SYSREG(0, 2, 2, 0, 5) },
|
||||||
{ HV_SYS_REG_DBGWVR2_EL1, HVF_SYSREG(0, 2, 14, 0, 6) },
|
{ HV_SYS_REG_DBGWVR2_EL1, HVF_SYSREG(0, 2, 2, 0, 6) },
|
||||||
{ HV_SYS_REG_DBGWCR2_EL1, HVF_SYSREG(0, 2, 14, 0, 7) },
|
{ HV_SYS_REG_DBGWCR2_EL1, HVF_SYSREG(0, 2, 2, 0, 7) },
|
||||||
|
|
||||||
{ HV_SYS_REG_DBGBVR3_EL1, HVF_SYSREG(0, 3, 14, 0, 4) },
|
{ HV_SYS_REG_DBGBVR3_EL1, HVF_SYSREG(0, 3, 2, 0, 4) },
|
||||||
{ HV_SYS_REG_DBGBCR3_EL1, HVF_SYSREG(0, 3, 14, 0, 5) },
|
{ HV_SYS_REG_DBGBCR3_EL1, HVF_SYSREG(0, 3, 2, 0, 5) },
|
||||||
{ HV_SYS_REG_DBGWVR3_EL1, HVF_SYSREG(0, 3, 14, 0, 6) },
|
{ HV_SYS_REG_DBGWVR3_EL1, HVF_SYSREG(0, 3, 2, 0, 6) },
|
||||||
{ HV_SYS_REG_DBGWCR3_EL1, HVF_SYSREG(0, 3, 14, 0, 7) },
|
{ HV_SYS_REG_DBGWCR3_EL1, HVF_SYSREG(0, 3, 2, 0, 7) },
|
||||||
|
|
||||||
{ HV_SYS_REG_DBGBVR4_EL1, HVF_SYSREG(0, 4, 14, 0, 4) },
|
{ HV_SYS_REG_DBGBVR4_EL1, HVF_SYSREG(0, 4, 2, 0, 4) },
|
||||||
{ HV_SYS_REG_DBGBCR4_EL1, HVF_SYSREG(0, 4, 14, 0, 5) },
|
{ HV_SYS_REG_DBGBCR4_EL1, HVF_SYSREG(0, 4, 2, 0, 5) },
|
||||||
{ HV_SYS_REG_DBGWVR4_EL1, HVF_SYSREG(0, 4, 14, 0, 6) },
|
{ HV_SYS_REG_DBGWVR4_EL1, HVF_SYSREG(0, 4, 2, 0, 6) },
|
||||||
{ HV_SYS_REG_DBGWCR4_EL1, HVF_SYSREG(0, 4, 14, 0, 7) },
|
{ HV_SYS_REG_DBGWCR4_EL1, HVF_SYSREG(0, 4, 2, 0, 7) },
|
||||||
|
|
||||||
{ HV_SYS_REG_DBGBVR5_EL1, HVF_SYSREG(0, 5, 14, 0, 4) },
|
{ HV_SYS_REG_DBGBVR5_EL1, HVF_SYSREG(0, 5, 2, 0, 4) },
|
||||||
{ HV_SYS_REG_DBGBCR5_EL1, HVF_SYSREG(0, 5, 14, 0, 5) },
|
{ HV_SYS_REG_DBGBCR5_EL1, HVF_SYSREG(0, 5, 2, 0, 5) },
|
||||||
{ HV_SYS_REG_DBGWVR5_EL1, HVF_SYSREG(0, 5, 14, 0, 6) },
|
{ HV_SYS_REG_DBGWVR5_EL1, HVF_SYSREG(0, 5, 2, 0, 6) },
|
||||||
{ HV_SYS_REG_DBGWCR5_EL1, HVF_SYSREG(0, 5, 14, 0, 7) },
|
{ HV_SYS_REG_DBGWCR5_EL1, HVF_SYSREG(0, 5, 2, 0, 7) },
|
||||||
|
|
||||||
{ HV_SYS_REG_DBGBVR6_EL1, HVF_SYSREG(0, 6, 14, 0, 4) },
|
{ HV_SYS_REG_DBGBVR6_EL1, HVF_SYSREG(0, 6, 2, 0, 4) },
|
||||||
{ HV_SYS_REG_DBGBCR6_EL1, HVF_SYSREG(0, 6, 14, 0, 5) },
|
{ HV_SYS_REG_DBGBCR6_EL1, HVF_SYSREG(0, 6, 2, 0, 5) },
|
||||||
{ HV_SYS_REG_DBGWVR6_EL1, HVF_SYSREG(0, 6, 14, 0, 6) },
|
{ HV_SYS_REG_DBGWVR6_EL1, HVF_SYSREG(0, 6, 2, 0, 6) },
|
||||||
{ HV_SYS_REG_DBGWCR6_EL1, HVF_SYSREG(0, 6, 14, 0, 7) },
|
{ HV_SYS_REG_DBGWCR6_EL1, HVF_SYSREG(0, 6, 2, 0, 7) },
|
||||||
|
|
||||||
{ HV_SYS_REG_DBGBVR7_EL1, HVF_SYSREG(0, 7, 14, 0, 4) },
|
{ HV_SYS_REG_DBGBVR7_EL1, HVF_SYSREG(0, 7, 2, 0, 4) },
|
||||||
{ HV_SYS_REG_DBGBCR7_EL1, HVF_SYSREG(0, 7, 14, 0, 5) },
|
{ HV_SYS_REG_DBGBCR7_EL1, HVF_SYSREG(0, 7, 2, 0, 5) },
|
||||||
{ HV_SYS_REG_DBGWVR7_EL1, HVF_SYSREG(0, 7, 14, 0, 6) },
|
{ HV_SYS_REG_DBGWVR7_EL1, HVF_SYSREG(0, 7, 2, 0, 6) },
|
||||||
{ HV_SYS_REG_DBGWCR7_EL1, HVF_SYSREG(0, 7, 14, 0, 7) },
|
{ HV_SYS_REG_DBGWCR7_EL1, HVF_SYSREG(0, 7, 2, 0, 7) },
|
||||||
|
|
||||||
{ HV_SYS_REG_DBGBVR8_EL1, HVF_SYSREG(0, 8, 14, 0, 4) },
|
{ HV_SYS_REG_DBGBVR8_EL1, HVF_SYSREG(0, 8, 2, 0, 4) },
|
||||||
{ HV_SYS_REG_DBGBCR8_EL1, HVF_SYSREG(0, 8, 14, 0, 5) },
|
{ HV_SYS_REG_DBGBCR8_EL1, HVF_SYSREG(0, 8, 2, 0, 5) },
|
||||||
{ HV_SYS_REG_DBGWVR8_EL1, HVF_SYSREG(0, 8, 14, 0, 6) },
|
{ HV_SYS_REG_DBGWVR8_EL1, HVF_SYSREG(0, 8, 2, 0, 6) },
|
||||||
{ HV_SYS_REG_DBGWCR8_EL1, HVF_SYSREG(0, 8, 14, 0, 7) },
|
{ HV_SYS_REG_DBGWCR8_EL1, HVF_SYSREG(0, 8, 2, 0, 7) },
|
||||||
|
|
||||||
{ HV_SYS_REG_DBGBVR9_EL1, HVF_SYSREG(0, 9, 14, 0, 4) },
|
{ HV_SYS_REG_DBGBVR9_EL1, HVF_SYSREG(0, 9, 2, 0, 4) },
|
||||||
{ HV_SYS_REG_DBGBCR9_EL1, HVF_SYSREG(0, 9, 14, 0, 5) },
|
{ HV_SYS_REG_DBGBCR9_EL1, HVF_SYSREG(0, 9, 2, 0, 5) },
|
||||||
{ HV_SYS_REG_DBGWVR9_EL1, HVF_SYSREG(0, 9, 14, 0, 6) },
|
{ HV_SYS_REG_DBGWVR9_EL1, HVF_SYSREG(0, 9, 2, 0, 6) },
|
||||||
{ HV_SYS_REG_DBGWCR9_EL1, HVF_SYSREG(0, 9, 14, 0, 7) },
|
{ HV_SYS_REG_DBGWCR9_EL1, HVF_SYSREG(0, 9, 2, 0, 7) },
|
||||||
|
|
||||||
{ HV_SYS_REG_DBGBVR10_EL1, HVF_SYSREG(0, 10, 14, 0, 4) },
|
{ HV_SYS_REG_DBGBVR10_EL1, HVF_SYSREG(0, 10, 2, 0, 4) },
|
||||||
{ HV_SYS_REG_DBGBCR10_EL1, HVF_SYSREG(0, 10, 14, 0, 5) },
|
{ HV_SYS_REG_DBGBCR10_EL1, HVF_SYSREG(0, 10, 2, 0, 5) },
|
||||||
{ HV_SYS_REG_DBGWVR10_EL1, HVF_SYSREG(0, 10, 14, 0, 6) },
|
{ HV_SYS_REG_DBGWVR10_EL1, HVF_SYSREG(0, 10, 2, 0, 6) },
|
||||||
{ HV_SYS_REG_DBGWCR10_EL1, HVF_SYSREG(0, 10, 14, 0, 7) },
|
{ HV_SYS_REG_DBGWCR10_EL1, HVF_SYSREG(0, 10, 2, 0, 7) },
|
||||||
|
|
||||||
{ HV_SYS_REG_DBGBVR11_EL1, HVF_SYSREG(0, 11, 14, 0, 4) },
|
{ HV_SYS_REG_DBGBVR11_EL1, HVF_SYSREG(0, 11, 2, 0, 4) },
|
||||||
{ HV_SYS_REG_DBGBCR11_EL1, HVF_SYSREG(0, 11, 14, 0, 5) },
|
{ HV_SYS_REG_DBGBCR11_EL1, HVF_SYSREG(0, 11, 2, 0, 5) },
|
||||||
{ HV_SYS_REG_DBGWVR11_EL1, HVF_SYSREG(0, 11, 14, 0, 6) },
|
{ HV_SYS_REG_DBGWVR11_EL1, HVF_SYSREG(0, 11, 2, 0, 6) },
|
||||||
{ HV_SYS_REG_DBGWCR11_EL1, HVF_SYSREG(0, 11, 14, 0, 7) },
|
{ HV_SYS_REG_DBGWCR11_EL1, HVF_SYSREG(0, 11, 2, 0, 7) },
|
||||||
|
|
||||||
{ HV_SYS_REG_DBGBVR12_EL1, HVF_SYSREG(0, 12, 14, 0, 4) },
|
{ HV_SYS_REG_DBGBVR12_EL1, HVF_SYSREG(0, 12, 2, 0, 4) },
|
||||||
{ HV_SYS_REG_DBGBCR12_EL1, HVF_SYSREG(0, 12, 14, 0, 5) },
|
{ HV_SYS_REG_DBGBCR12_EL1, HVF_SYSREG(0, 12, 2, 0, 5) },
|
||||||
{ HV_SYS_REG_DBGWVR12_EL1, HVF_SYSREG(0, 12, 14, 0, 6) },
|
{ HV_SYS_REG_DBGWVR12_EL1, HVF_SYSREG(0, 12, 2, 0, 6) },
|
||||||
{ HV_SYS_REG_DBGWCR12_EL1, HVF_SYSREG(0, 12, 14, 0, 7) },
|
{ HV_SYS_REG_DBGWCR12_EL1, HVF_SYSREG(0, 12, 2, 0, 7) },
|
||||||
|
|
||||||
{ HV_SYS_REG_DBGBVR13_EL1, HVF_SYSREG(0, 13, 14, 0, 4) },
|
{ HV_SYS_REG_DBGBVR13_EL1, HVF_SYSREG(0, 13, 2, 0, 4) },
|
||||||
{ HV_SYS_REG_DBGBCR13_EL1, HVF_SYSREG(0, 13, 14, 0, 5) },
|
{ HV_SYS_REG_DBGBCR13_EL1, HVF_SYSREG(0, 13, 2, 0, 5) },
|
||||||
{ HV_SYS_REG_DBGWVR13_EL1, HVF_SYSREG(0, 13, 14, 0, 6) },
|
{ HV_SYS_REG_DBGWVR13_EL1, HVF_SYSREG(0, 13, 2, 0, 6) },
|
||||||
{ HV_SYS_REG_DBGWCR13_EL1, HVF_SYSREG(0, 13, 14, 0, 7) },
|
{ HV_SYS_REG_DBGWCR13_EL1, HVF_SYSREG(0, 13, 2, 0, 7) },
|
||||||
|
|
||||||
{ HV_SYS_REG_DBGBVR14_EL1, HVF_SYSREG(0, 14, 14, 0, 4) },
|
{ HV_SYS_REG_DBGBVR14_EL1, HVF_SYSREG(0, 14, 2, 0, 4) },
|
||||||
{ HV_SYS_REG_DBGBCR14_EL1, HVF_SYSREG(0, 14, 14, 0, 5) },
|
{ HV_SYS_REG_DBGBCR14_EL1, HVF_SYSREG(0, 14, 2, 0, 5) },
|
||||||
{ HV_SYS_REG_DBGWVR14_EL1, HVF_SYSREG(0, 14, 14, 0, 6) },
|
{ HV_SYS_REG_DBGWVR14_EL1, HVF_SYSREG(0, 14, 2, 0, 6) },
|
||||||
{ HV_SYS_REG_DBGWCR14_EL1, HVF_SYSREG(0, 14, 14, 0, 7) },
|
{ HV_SYS_REG_DBGWCR14_EL1, HVF_SYSREG(0, 14, 2, 0, 7) },
|
||||||
|
|
||||||
{ HV_SYS_REG_DBGBVR15_EL1, HVF_SYSREG(0, 15, 14, 0, 4) },
|
{ HV_SYS_REG_DBGBVR15_EL1, HVF_SYSREG(0, 15, 2, 0, 4) },
|
||||||
{ HV_SYS_REG_DBGBCR15_EL1, HVF_SYSREG(0, 15, 14, 0, 5) },
|
{ HV_SYS_REG_DBGBCR15_EL1, HVF_SYSREG(0, 15, 2, 0, 5) },
|
||||||
{ HV_SYS_REG_DBGWVR15_EL1, HVF_SYSREG(0, 15, 14, 0, 6) },
|
{ HV_SYS_REG_DBGWVR15_EL1, HVF_SYSREG(0, 15, 2, 0, 6) },
|
||||||
{ HV_SYS_REG_DBGWCR15_EL1, HVF_SYSREG(0, 15, 14, 0, 7) },
|
{ HV_SYS_REG_DBGWCR15_EL1, HVF_SYSREG(0, 15, 2, 0, 7) },
|
||||||
|
|
||||||
#ifdef SYNC_NO_RAW_REGS
|
#ifdef SYNC_NO_RAW_REGS
|
||||||
/*
|
/*
|
||||||
@ -487,7 +487,7 @@ static struct hvf_sreg_match hvf_sreg_match[] = {
|
|||||||
{ HV_SYS_REG_MPIDR_EL1, HVF_SYSREG(0, 0, 3, 0, 5) },
|
{ HV_SYS_REG_MPIDR_EL1, HVF_SYSREG(0, 0, 3, 0, 5) },
|
||||||
{ HV_SYS_REG_ID_AA64PFR0_EL1, HVF_SYSREG(0, 4, 3, 0, 0) },
|
{ HV_SYS_REG_ID_AA64PFR0_EL1, HVF_SYSREG(0, 4, 3, 0, 0) },
|
||||||
#endif
|
#endif
|
||||||
{ HV_SYS_REG_ID_AA64PFR1_EL1, HVF_SYSREG(0, 4, 3, 0, 2) },
|
{ HV_SYS_REG_ID_AA64PFR1_EL1, HVF_SYSREG(0, 4, 3, 0, 1) },
|
||||||
{ HV_SYS_REG_ID_AA64DFR0_EL1, HVF_SYSREG(0, 5, 3, 0, 0) },
|
{ HV_SYS_REG_ID_AA64DFR0_EL1, HVF_SYSREG(0, 5, 3, 0, 0) },
|
||||||
{ HV_SYS_REG_ID_AA64DFR1_EL1, HVF_SYSREG(0, 5, 3, 0, 1) },
|
{ HV_SYS_REG_ID_AA64DFR1_EL1, HVF_SYSREG(0, 5, 3, 0, 1) },
|
||||||
{ HV_SYS_REG_ID_AA64ISAR0_EL1, HVF_SYSREG(0, 6, 3, 0, 0) },
|
{ HV_SYS_REG_ID_AA64ISAR0_EL1, HVF_SYSREG(0, 6, 3, 0, 0) },
|
||||||
|
@ -38,8 +38,16 @@ static bool aprofile_require_alignment(CPUARMState *env, int el, uint64_t sctlr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If translation is disabled, then the default memory type is
|
* With PMSA, when the MPU is disabled, all memory types in the
|
||||||
* Device(-nGnRnE) instead of Normal, which requires that alignment
|
* default map are Normal, so don't need aligment enforcing.
|
||||||
|
*/
|
||||||
|
if (arm_feature(env, ARM_FEATURE_PMSA)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* With VMSA, if translation is disabled, then the default memory type
|
||||||
|
* is Device(-nGnRnE) instead of Normal, which requires that alignment
|
||||||
* be enforced. Since this affects all ram, it is most efficient
|
* be enforced. Since this affects all ram, it is most efficient
|
||||||
* to handle this during translation.
|
* to handle this during translation.
|
||||||
*/
|
*/
|
||||||
|
@ -1550,8 +1550,8 @@ static FeatureDep feature_dependencies[] = {
|
|||||||
.to = { FEAT_SVM, ~0ull },
|
.to = { FEAT_SVM, ~0ull },
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.from = { FEAT_VMX_SECONDARY_CTLS, VMX_SECONDARY_EXEC_ENABLE_USER_WAIT_PAUSE },
|
.from = { FEAT_7_0_ECX, CPUID_7_0_ECX_WAITPKG },
|
||||||
.to = { FEAT_7_0_ECX, CPUID_7_0_ECX_WAITPKG },
|
.to = { FEAT_VMX_SECONDARY_CTLS, VMX_SECONDARY_EXEC_ENABLE_USER_WAIT_PAUSE },
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -81,7 +81,7 @@ int kvm_hv_handle_exit(X86CPU *cpu, struct kvm_hyperv_exit *exit)
|
|||||||
*/
|
*/
|
||||||
async_safe_run_on_cpu(CPU(cpu), async_synic_update, RUN_ON_CPU_NULL);
|
async_safe_run_on_cpu(CPU(cpu), async_synic_update, RUN_ON_CPU_NULL);
|
||||||
|
|
||||||
return 0;
|
return EXCP_INTERRUPT;
|
||||||
case KVM_EXIT_HYPERV_HCALL: {
|
case KVM_EXIT_HYPERV_HCALL: {
|
||||||
uint16_t code = exit->u.hcall.input & 0xffff;
|
uint16_t code = exit->u.hcall.input & 0xffff;
|
||||||
bool fast = exit->u.hcall.input & HV_HYPERCALL_FAST;
|
bool fast = exit->u.hcall.input & HV_HYPERCALL_FAST;
|
||||||
|
@ -1485,9 +1485,9 @@ static bool has_cpuid_feature(DisasContext *s, X86CPUIDFeature cpuid)
|
|||||||
case X86_FEAT_PCLMULQDQ:
|
case X86_FEAT_PCLMULQDQ:
|
||||||
return (s->cpuid_ext_features & CPUID_EXT_PCLMULQDQ);
|
return (s->cpuid_ext_features & CPUID_EXT_PCLMULQDQ);
|
||||||
case X86_FEAT_SSE:
|
case X86_FEAT_SSE:
|
||||||
return (s->cpuid_ext_features & CPUID_SSE);
|
return (s->cpuid_features & CPUID_SSE);
|
||||||
case X86_FEAT_SSE2:
|
case X86_FEAT_SSE2:
|
||||||
return (s->cpuid_ext_features & CPUID_SSE2);
|
return (s->cpuid_features & CPUID_SSE2);
|
||||||
case X86_FEAT_SSE3:
|
case X86_FEAT_SSE3:
|
||||||
return (s->cpuid_ext_features & CPUID_EXT_SSE3);
|
return (s->cpuid_ext_features & CPUID_EXT_SSE3);
|
||||||
case X86_FEAT_SSSE3:
|
case X86_FEAT_SSSE3:
|
||||||
|
@ -3010,6 +3010,11 @@ void helper_xsetbv(CPUX86State *env, uint32_t ecx, uint64_t mask)
|
|||||||
goto do_gpf;
|
goto do_gpf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* SSE can be disabled, but only if AVX is disabled too. */
|
||||||
|
if ((mask & (XSTATE_SSE_MASK | XSTATE_YMM_MASK)) == XSTATE_YMM_MASK) {
|
||||||
|
goto do_gpf;
|
||||||
|
}
|
||||||
|
|
||||||
/* Disallow enabling unimplemented features. */
|
/* Disallow enabling unimplemented features. */
|
||||||
cpu_x86_cpuid(env, 0x0d, 0, &ena_lo, &dummy, &dummy, &ena_hi);
|
cpu_x86_cpuid(env, 0x0d, 0, &ena_lo, &dummy, &dummy, &ena_hi);
|
||||||
ena = ((uint64_t)ena_hi << 32) | ena_lo;
|
ena = ((uint64_t)ena_hi << 32) | ena_lo;
|
||||||
|
@ -2817,13 +2817,17 @@ static void gen_bnd_jmp(DisasContext *s)
|
|||||||
static void
|
static void
|
||||||
do_gen_eob_worker(DisasContext *s, bool inhibit, bool recheck_tf, bool jr)
|
do_gen_eob_worker(DisasContext *s, bool inhibit, bool recheck_tf, bool jr)
|
||||||
{
|
{
|
||||||
|
bool inhibit_reset;
|
||||||
|
|
||||||
gen_update_cc_op(s);
|
gen_update_cc_op(s);
|
||||||
|
|
||||||
/* If several instructions disable interrupts, only the first does it. */
|
/* If several instructions disable interrupts, only the first does it. */
|
||||||
if (inhibit && !(s->flags & HF_INHIBIT_IRQ_MASK)) {
|
inhibit_reset = false;
|
||||||
gen_set_hflag(s, HF_INHIBIT_IRQ_MASK);
|
if (s->flags & HF_INHIBIT_IRQ_MASK) {
|
||||||
} else {
|
|
||||||
gen_reset_hflag(s, HF_INHIBIT_IRQ_MASK);
|
gen_reset_hflag(s, HF_INHIBIT_IRQ_MASK);
|
||||||
|
inhibit_reset = true;
|
||||||
|
} else if (inhibit) {
|
||||||
|
gen_set_hflag(s, HF_INHIBIT_IRQ_MASK);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (s->base.tb->flags & HF_RF_MASK) {
|
if (s->base.tb->flags & HF_RF_MASK) {
|
||||||
@ -2832,9 +2836,11 @@ do_gen_eob_worker(DisasContext *s, bool inhibit, bool recheck_tf, bool jr)
|
|||||||
if (recheck_tf) {
|
if (recheck_tf) {
|
||||||
gen_helper_rechecking_single_step(tcg_env);
|
gen_helper_rechecking_single_step(tcg_env);
|
||||||
tcg_gen_exit_tb(NULL, 0);
|
tcg_gen_exit_tb(NULL, 0);
|
||||||
} else if (s->flags & HF_TF_MASK) {
|
} else if ((s->flags & HF_TF_MASK) && !inhibit) {
|
||||||
gen_helper_single_step(tcg_env);
|
gen_helper_single_step(tcg_env);
|
||||||
} else if (jr) {
|
} else if (jr &&
|
||||||
|
/* give irqs a chance to happen */
|
||||||
|
!inhibit_reset) {
|
||||||
tcg_gen_lookup_and_goto_ptr();
|
tcg_gen_lookup_and_goto_ptr();
|
||||||
} else {
|
} else {
|
||||||
tcg_gen_exit_tb(NULL, 0);
|
tcg_gen_exit_tb(NULL, 0);
|
||||||
@ -6102,7 +6108,8 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
|
|||||||
gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 1);
|
gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 1);
|
||||||
break;
|
break;
|
||||||
case 0xee: /* rdpkru */
|
case 0xee: /* rdpkru */
|
||||||
if (prefixes & PREFIX_LOCK) {
|
if (s->prefix & (PREFIX_LOCK | PREFIX_DATA
|
||||||
|
| PREFIX_REPZ | PREFIX_REPNZ)) {
|
||||||
goto illegal_op;
|
goto illegal_op;
|
||||||
}
|
}
|
||||||
tcg_gen_trunc_tl_i32(s->tmp2_i32, cpu_regs[R_ECX]);
|
tcg_gen_trunc_tl_i32(s->tmp2_i32, cpu_regs[R_ECX]);
|
||||||
@ -6110,7 +6117,8 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
|
|||||||
tcg_gen_extr_i64_tl(cpu_regs[R_EAX], cpu_regs[R_EDX], s->tmp1_i64);
|
tcg_gen_extr_i64_tl(cpu_regs[R_EAX], cpu_regs[R_EDX], s->tmp1_i64);
|
||||||
break;
|
break;
|
||||||
case 0xef: /* wrpkru */
|
case 0xef: /* wrpkru */
|
||||||
if (prefixes & PREFIX_LOCK) {
|
if (s->prefix & (PREFIX_LOCK | PREFIX_DATA
|
||||||
|
| PREFIX_REPZ | PREFIX_REPNZ)) {
|
||||||
goto illegal_op;
|
goto illegal_op;
|
||||||
}
|
}
|
||||||
tcg_gen_concat_tl_i64(s->tmp1_i64, cpu_regs[R_EAX],
|
tcg_gen_concat_tl_i64(s->tmp1_i64, cpu_regs[R_EAX],
|
||||||
@ -6818,12 +6826,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
|
|||||||
modrm = x86_ldub_code(env, s);
|
modrm = x86_ldub_code(env, s);
|
||||||
reg = ((modrm >> 3) & 7) | REX_R(s);
|
reg = ((modrm >> 3) & 7) | REX_R(s);
|
||||||
|
|
||||||
if (s->prefix & PREFIX_DATA) {
|
ot = dflag;
|
||||||
ot = MO_16;
|
|
||||||
} else {
|
|
||||||
ot = mo_64_32(dflag);
|
|
||||||
}
|
|
||||||
|
|
||||||
gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
|
gen_ldst_modrm(env, s, modrm, ot, OR_TMP0, 0);
|
||||||
gen_extu(ot, s->T0);
|
gen_extu(ot, s->T0);
|
||||||
tcg_gen_mov_tl(cpu_cc_src, s->T0);
|
tcg_gen_mov_tl(cpu_cc_src, s->T0);
|
||||||
@ -6987,7 +6990,7 @@ static void i386_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cpu)
|
|||||||
dc->cpuid_7_1_eax_features = env->features[FEAT_7_1_EAX];
|
dc->cpuid_7_1_eax_features = env->features[FEAT_7_1_EAX];
|
||||||
dc->cpuid_xsave_features = env->features[FEAT_XSAVE];
|
dc->cpuid_xsave_features = env->features[FEAT_XSAVE];
|
||||||
dc->jmp_opt = !((cflags & CF_NO_GOTO_TB) ||
|
dc->jmp_opt = !((cflags & CF_NO_GOTO_TB) ||
|
||||||
(flags & (HF_TF_MASK | HF_INHIBIT_IRQ_MASK)));
|
(flags & (HF_RF_MASK | HF_TF_MASK | HF_INHIBIT_IRQ_MASK)));
|
||||||
/*
|
/*
|
||||||
* If jmp_opt, we want to handle each string instruction individually.
|
* If jmp_opt, we want to handle each string instruction individually.
|
||||||
* For icount also disable repz optimization so that each iteration
|
* For icount also disable repz optimization so that each iteration
|
||||||
|
@ -92,7 +92,7 @@ void G_NORETURN do_raise_exception(CPULoongArchState *env,
|
|||||||
{
|
{
|
||||||
CPUState *cs = env_cpu(env);
|
CPUState *cs = env_cpu(env);
|
||||||
|
|
||||||
qemu_log_mask(CPU_LOG_INT, "%s: expection: %d (%s)\n",
|
qemu_log_mask(CPU_LOG_INT, "%s: exception: %d (%s)\n",
|
||||||
__func__,
|
__func__,
|
||||||
exception,
|
exception,
|
||||||
loongarch_exception_name(exception));
|
loongarch_exception_name(exception));
|
||||||
@ -710,7 +710,7 @@ void loongarch_cpu_dump_state(CPUState *cs, FILE *f, int flags)
|
|||||||
qemu_fprintf(f, "EENTRY=%016" PRIx64 "\n", env->CSR_EENTRY);
|
qemu_fprintf(f, "EENTRY=%016" PRIx64 "\n", env->CSR_EENTRY);
|
||||||
qemu_fprintf(f, "PRCFG1=%016" PRIx64 ", PRCFG2=%016" PRIx64 ","
|
qemu_fprintf(f, "PRCFG1=%016" PRIx64 ", PRCFG2=%016" PRIx64 ","
|
||||||
" PRCFG3=%016" PRIx64 "\n",
|
" PRCFG3=%016" PRIx64 "\n",
|
||||||
env->CSR_PRCFG1, env->CSR_PRCFG3, env->CSR_PRCFG3);
|
env->CSR_PRCFG1, env->CSR_PRCFG2, env->CSR_PRCFG3);
|
||||||
qemu_fprintf(f, "TLBRENTRY=%016" PRIx64 "\n", env->CSR_TLBRENTRY);
|
qemu_fprintf(f, "TLBRENTRY=%016" PRIx64 "\n", env->CSR_TLBRENTRY);
|
||||||
qemu_fprintf(f, "TLBRBADV=%016" PRIx64 "\n", env->CSR_TLBRBADV);
|
qemu_fprintf(f, "TLBRBADV=%016" PRIx64 "\n", env->CSR_TLBRBADV);
|
||||||
qemu_fprintf(f, "TLBRERA=%016" PRIx64 "\n", env->CSR_TLBRERA);
|
qemu_fprintf(f, "TLBRERA=%016" PRIx64 "\n", env->CSR_TLBRERA);
|
||||||
|
@ -436,6 +436,9 @@ static int kvm_loongarch_get_regs_fp(CPUState *cs)
|
|||||||
env->fcsr0 = fpu.fcsr;
|
env->fcsr0 = fpu.fcsr;
|
||||||
for (i = 0; i < 32; i++) {
|
for (i = 0; i < 32; i++) {
|
||||||
env->fpr[i].vreg.UD[0] = fpu.fpr[i].val64[0];
|
env->fpr[i].vreg.UD[0] = fpu.fpr[i].val64[0];
|
||||||
|
env->fpr[i].vreg.UD[1] = fpu.fpr[i].val64[1];
|
||||||
|
env->fpr[i].vreg.UD[2] = fpu.fpr[i].val64[2];
|
||||||
|
env->fpr[i].vreg.UD[3] = fpu.fpr[i].val64[3];
|
||||||
}
|
}
|
||||||
for (i = 0; i < 8; i++) {
|
for (i = 0; i < 8; i++) {
|
||||||
env->cf[i] = fpu.fcc & 0xFF;
|
env->cf[i] = fpu.fcc & 0xFF;
|
||||||
@ -455,6 +458,9 @@ static int kvm_loongarch_put_regs_fp(CPUState *cs)
|
|||||||
fpu.fcc = 0;
|
fpu.fcc = 0;
|
||||||
for (i = 0; i < 32; i++) {
|
for (i = 0; i < 32; i++) {
|
||||||
fpu.fpr[i].val64[0] = env->fpr[i].vreg.UD[0];
|
fpu.fpr[i].val64[0] = env->fpr[i].vreg.UD[0];
|
||||||
|
fpu.fpr[i].val64[1] = env->fpr[i].vreg.UD[1];
|
||||||
|
fpu.fpr[i].val64[2] = env->fpr[i].vreg.UD[2];
|
||||||
|
fpu.fpr[i].val64[3] = env->fpr[i].vreg.UD[3];
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < 8; i++) {
|
for (i = 0; i < 8; i++) {
|
||||||
|
@ -1535,7 +1535,7 @@ const RISCVCPUMultiExtConfig riscv_cpu_extensions[] = {
|
|||||||
/* Vector cryptography extensions */
|
/* Vector cryptography extensions */
|
||||||
MULTI_EXT_CFG_BOOL("zvbb", ext_zvbb, false),
|
MULTI_EXT_CFG_BOOL("zvbb", ext_zvbb, false),
|
||||||
MULTI_EXT_CFG_BOOL("zvbc", ext_zvbc, false),
|
MULTI_EXT_CFG_BOOL("zvbc", ext_zvbc, false),
|
||||||
MULTI_EXT_CFG_BOOL("zvkb", ext_zvkg, false),
|
MULTI_EXT_CFG_BOOL("zvkb", ext_zvkb, false),
|
||||||
MULTI_EXT_CFG_BOOL("zvkg", ext_zvkg, false),
|
MULTI_EXT_CFG_BOOL("zvkg", ext_zvkg, false),
|
||||||
MULTI_EXT_CFG_BOOL("zvkned", ext_zvkned, false),
|
MULTI_EXT_CFG_BOOL("zvkned", ext_zvkned, false),
|
||||||
MULTI_EXT_CFG_BOOL("zvknha", ext_zvknha, false),
|
MULTI_EXT_CFG_BOOL("zvknha", ext_zvknha, false),
|
||||||
|
@ -821,6 +821,9 @@ void riscv_set_csr_ops(int csrno, riscv_csr_operations *ops);
|
|||||||
|
|
||||||
void riscv_cpu_register_gdb_regs_for_features(CPUState *cs);
|
void riscv_cpu_register_gdb_regs_for_features(CPUState *cs);
|
||||||
|
|
||||||
|
target_ulong riscv_new_csr_seed(target_ulong new_value,
|
||||||
|
target_ulong write_mask);
|
||||||
|
|
||||||
uint8_t satp_mode_max_from_map(uint32_t map);
|
uint8_t satp_mode_max_from_map(uint32_t map);
|
||||||
const char *satp_mode_str(uint8_t satp_mode, bool is_32_bit);
|
const char *satp_mode_str(uint8_t satp_mode, bool is_32_bit);
|
||||||
|
|
||||||
|
@ -1176,28 +1176,30 @@ static void raise_mmu_exception(CPURISCVState *env, target_ulong address,
|
|||||||
|
|
||||||
switch (access_type) {
|
switch (access_type) {
|
||||||
case MMU_INST_FETCH:
|
case MMU_INST_FETCH:
|
||||||
if (env->virt_enabled && !first_stage) {
|
if (pmp_violation) {
|
||||||
|
cs->exception_index = RISCV_EXCP_INST_ACCESS_FAULT;
|
||||||
|
} else if (env->virt_enabled && !first_stage) {
|
||||||
cs->exception_index = RISCV_EXCP_INST_GUEST_PAGE_FAULT;
|
cs->exception_index = RISCV_EXCP_INST_GUEST_PAGE_FAULT;
|
||||||
} else {
|
} else {
|
||||||
cs->exception_index = pmp_violation ?
|
cs->exception_index = RISCV_EXCP_INST_PAGE_FAULT;
|
||||||
RISCV_EXCP_INST_ACCESS_FAULT : RISCV_EXCP_INST_PAGE_FAULT;
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case MMU_DATA_LOAD:
|
case MMU_DATA_LOAD:
|
||||||
if (two_stage && !first_stage) {
|
if (pmp_violation) {
|
||||||
|
cs->exception_index = RISCV_EXCP_LOAD_ACCESS_FAULT;
|
||||||
|
} else if (two_stage && !first_stage) {
|
||||||
cs->exception_index = RISCV_EXCP_LOAD_GUEST_ACCESS_FAULT;
|
cs->exception_index = RISCV_EXCP_LOAD_GUEST_ACCESS_FAULT;
|
||||||
} else {
|
} else {
|
||||||
cs->exception_index = pmp_violation ?
|
cs->exception_index = RISCV_EXCP_LOAD_PAGE_FAULT;
|
||||||
RISCV_EXCP_LOAD_ACCESS_FAULT : RISCV_EXCP_LOAD_PAGE_FAULT;
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case MMU_DATA_STORE:
|
case MMU_DATA_STORE:
|
||||||
if (two_stage && !first_stage) {
|
if (pmp_violation) {
|
||||||
|
cs->exception_index = RISCV_EXCP_STORE_AMO_ACCESS_FAULT;
|
||||||
|
} else if (two_stage && !first_stage) {
|
||||||
cs->exception_index = RISCV_EXCP_STORE_GUEST_AMO_ACCESS_FAULT;
|
cs->exception_index = RISCV_EXCP_STORE_GUEST_AMO_ACCESS_FAULT;
|
||||||
} else {
|
} else {
|
||||||
cs->exception_index = pmp_violation ?
|
cs->exception_index = RISCV_EXCP_STORE_PAGE_FAULT;
|
||||||
RISCV_EXCP_STORE_AMO_ACCESS_FAULT :
|
|
||||||
RISCV_EXCP_STORE_PAGE_FAULT;
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -1373,19 +1375,19 @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
|
|||||||
__func__, pa, ret, prot_pmp, tlb_size);
|
__func__, pa, ret, prot_pmp, tlb_size);
|
||||||
|
|
||||||
prot &= prot_pmp;
|
prot &= prot_pmp;
|
||||||
}
|
} else {
|
||||||
|
|
||||||
if (ret != TRANSLATE_SUCCESS) {
|
|
||||||
/*
|
/*
|
||||||
* Guest physical address translation failed, this is a HS
|
* Guest physical address translation failed, this is a HS
|
||||||
* level exception
|
* level exception
|
||||||
*/
|
*/
|
||||||
first_stage_error = false;
|
first_stage_error = false;
|
||||||
|
if (ret != TRANSLATE_PMP_FAIL) {
|
||||||
env->guest_phys_fault_addr = (im_address |
|
env->guest_phys_fault_addr = (im_address |
|
||||||
(address &
|
(address &
|
||||||
(TARGET_PAGE_SIZE - 1))) >> 2;
|
(TARGET_PAGE_SIZE - 1))) >> 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
/* Single stage lookup */
|
/* Single stage lookup */
|
||||||
ret = get_physical_address(env, &pa, &prot, address, NULL,
|
ret = get_physical_address(env, &pa, &prot, address, NULL,
|
||||||
|
@ -4267,9 +4267,7 @@ static RISCVException write_upmbase(CPURISCVState *env, int csrno,
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Crypto Extension */
|
/* Crypto Extension */
|
||||||
static RISCVException rmw_seed(CPURISCVState *env, int csrno,
|
target_ulong riscv_new_csr_seed(target_ulong new_value,
|
||||||
target_ulong *ret_value,
|
|
||||||
target_ulong new_value,
|
|
||||||
target_ulong write_mask)
|
target_ulong write_mask)
|
||||||
{
|
{
|
||||||
uint16_t random_v;
|
uint16_t random_v;
|
||||||
@ -4294,6 +4292,18 @@ static RISCVException rmw_seed(CPURISCVState *env, int csrno,
|
|||||||
rval = random_v | SEED_OPST_ES16;
|
rval = random_v | SEED_OPST_ES16;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return rval;
|
||||||
|
}
|
||||||
|
|
||||||
|
static RISCVException rmw_seed(CPURISCVState *env, int csrno,
|
||||||
|
target_ulong *ret_value,
|
||||||
|
target_ulong new_value,
|
||||||
|
target_ulong write_mask)
|
||||||
|
{
|
||||||
|
target_ulong rval;
|
||||||
|
|
||||||
|
rval = riscv_new_csr_seed(new_value, write_mask);
|
||||||
|
|
||||||
if (ret_value) {
|
if (ret_value) {
|
||||||
*ret_value = rval;
|
*ret_value = rval;
|
||||||
}
|
}
|
||||||
|
@ -288,7 +288,7 @@ static GDBFeature *riscv_gen_dynamic_csr_feature(CPUState *cs, int base_reg)
|
|||||||
static GDBFeature *ricsv_gen_dynamic_vector_feature(CPUState *cs, int base_reg)
|
static GDBFeature *ricsv_gen_dynamic_vector_feature(CPUState *cs, int base_reg)
|
||||||
{
|
{
|
||||||
RISCVCPU *cpu = RISCV_CPU(cs);
|
RISCVCPU *cpu = RISCV_CPU(cs);
|
||||||
int reg_width = cpu->cfg.vlenb;
|
int bitsize = cpu->cfg.vlenb << 3;
|
||||||
GDBFeatureBuilder builder;
|
GDBFeatureBuilder builder;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
@ -298,7 +298,7 @@ static GDBFeature *ricsv_gen_dynamic_vector_feature(CPUState *cs, int base_reg)
|
|||||||
|
|
||||||
/* First define types and totals in a whole VL */
|
/* First define types and totals in a whole VL */
|
||||||
for (i = 0; i < ARRAY_SIZE(vec_lanes); i++) {
|
for (i = 0; i < ARRAY_SIZE(vec_lanes); i++) {
|
||||||
int count = reg_width / vec_lanes[i].size;
|
int count = bitsize / vec_lanes[i].size;
|
||||||
gdb_feature_builder_append_tag(
|
gdb_feature_builder_append_tag(
|
||||||
&builder, "<vector id=\"%s\" type=\"%s\" count=\"%d\"/>",
|
&builder, "<vector id=\"%s\" type=\"%s\" count=\"%d\"/>",
|
||||||
vec_lanes[i].id, vec_lanes[i].gdb_type, count);
|
vec_lanes[i].id, vec_lanes[i].gdb_type, count);
|
||||||
@ -316,7 +316,7 @@ static GDBFeature *ricsv_gen_dynamic_vector_feature(CPUState *cs, int base_reg)
|
|||||||
/* Define vector registers */
|
/* Define vector registers */
|
||||||
for (i = 0; i < 32; i++) {
|
for (i = 0; i < 32; i++) {
|
||||||
gdb_feature_builder_append_reg(&builder, g_strdup_printf("v%d", i),
|
gdb_feature_builder_append_reg(&builder, g_strdup_printf("v%d", i),
|
||||||
reg_width, i, "riscv_vector", "vector");
|
bitsize, i, "riscv_vector", "vector");
|
||||||
}
|
}
|
||||||
|
|
||||||
gdb_feature_builder_end(&builder);
|
gdb_feature_builder_end(&builder);
|
||||||
|
@ -50,6 +50,22 @@ static bool require_rvf(DisasContext *s)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool require_rvfmin(DisasContext *s)
|
||||||
|
{
|
||||||
|
if (s->mstatus_fs == EXT_STATUS_DISABLED) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (s->sew) {
|
||||||
|
case MO_16:
|
||||||
|
return s->cfg_ptr->ext_zvfhmin;
|
||||||
|
case MO_32:
|
||||||
|
return s->cfg_ptr->ext_zve32f;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static bool require_scale_rvf(DisasContext *s)
|
static bool require_scale_rvf(DisasContext *s)
|
||||||
{
|
{
|
||||||
if (s->mstatus_fs == EXT_STATUS_DISABLED) {
|
if (s->mstatus_fs == EXT_STATUS_DISABLED) {
|
||||||
@ -75,8 +91,6 @@ static bool require_scale_rvfmin(DisasContext *s)
|
|||||||
}
|
}
|
||||||
|
|
||||||
switch (s->sew) {
|
switch (s->sew) {
|
||||||
case MO_8:
|
|
||||||
return s->cfg_ptr->ext_zvfhmin;
|
|
||||||
case MO_16:
|
case MO_16:
|
||||||
return s->cfg_ptr->ext_zve32f;
|
return s->cfg_ptr->ext_zve32f;
|
||||||
case MO_32:
|
case MO_32:
|
||||||
@ -2317,8 +2331,8 @@ GEN_OPFVF_TRANS(vfrsub_vf, opfvf_check)
|
|||||||
static bool opfvv_widen_check(DisasContext *s, arg_rmrr *a)
|
static bool opfvv_widen_check(DisasContext *s, arg_rmrr *a)
|
||||||
{
|
{
|
||||||
return require_rvv(s) &&
|
return require_rvv(s) &&
|
||||||
|
require_rvf(s) &&
|
||||||
require_scale_rvf(s) &&
|
require_scale_rvf(s) &&
|
||||||
(s->sew != MO_8) &&
|
|
||||||
vext_check_isa_ill(s) &&
|
vext_check_isa_ill(s) &&
|
||||||
vext_check_dss(s, a->rd, a->rs1, a->rs2, a->vm);
|
vext_check_dss(s, a->rd, a->rs1, a->rs2, a->vm);
|
||||||
}
|
}
|
||||||
@ -2356,8 +2370,8 @@ GEN_OPFVV_WIDEN_TRANS(vfwsub_vv, opfvv_widen_check)
|
|||||||
static bool opfvf_widen_check(DisasContext *s, arg_rmrr *a)
|
static bool opfvf_widen_check(DisasContext *s, arg_rmrr *a)
|
||||||
{
|
{
|
||||||
return require_rvv(s) &&
|
return require_rvv(s) &&
|
||||||
|
require_rvf(s) &&
|
||||||
require_scale_rvf(s) &&
|
require_scale_rvf(s) &&
|
||||||
(s->sew != MO_8) &&
|
|
||||||
vext_check_isa_ill(s) &&
|
vext_check_isa_ill(s) &&
|
||||||
vext_check_ds(s, a->rd, a->rs2, a->vm);
|
vext_check_ds(s, a->rd, a->rs2, a->vm);
|
||||||
}
|
}
|
||||||
@ -2388,8 +2402,8 @@ GEN_OPFVF_WIDEN_TRANS(vfwsub_vf)
|
|||||||
static bool opfwv_widen_check(DisasContext *s, arg_rmrr *a)
|
static bool opfwv_widen_check(DisasContext *s, arg_rmrr *a)
|
||||||
{
|
{
|
||||||
return require_rvv(s) &&
|
return require_rvv(s) &&
|
||||||
|
require_rvf(s) &&
|
||||||
require_scale_rvf(s) &&
|
require_scale_rvf(s) &&
|
||||||
(s->sew != MO_8) &&
|
|
||||||
vext_check_isa_ill(s) &&
|
vext_check_isa_ill(s) &&
|
||||||
vext_check_dds(s, a->rd, a->rs1, a->rs2, a->vm);
|
vext_check_dds(s, a->rd, a->rs1, a->rs2, a->vm);
|
||||||
}
|
}
|
||||||
@ -2427,8 +2441,8 @@ GEN_OPFWV_WIDEN_TRANS(vfwsub_wv)
|
|||||||
static bool opfwf_widen_check(DisasContext *s, arg_rmrr *a)
|
static bool opfwf_widen_check(DisasContext *s, arg_rmrr *a)
|
||||||
{
|
{
|
||||||
return require_rvv(s) &&
|
return require_rvv(s) &&
|
||||||
|
require_rvf(s) &&
|
||||||
require_scale_rvf(s) &&
|
require_scale_rvf(s) &&
|
||||||
(s->sew != MO_8) &&
|
|
||||||
vext_check_isa_ill(s) &&
|
vext_check_isa_ill(s) &&
|
||||||
vext_check_dd(s, a->rd, a->rs2, a->vm);
|
vext_check_dd(s, a->rd, a->rs2, a->vm);
|
||||||
}
|
}
|
||||||
@ -2685,8 +2699,8 @@ static bool opxfv_widen_check(DisasContext *s, arg_rmr *a)
|
|||||||
static bool opffv_widen_check(DisasContext *s, arg_rmr *a)
|
static bool opffv_widen_check(DisasContext *s, arg_rmr *a)
|
||||||
{
|
{
|
||||||
return opfv_widen_check(s, a) &&
|
return opfv_widen_check(s, a) &&
|
||||||
require_scale_rvfmin(s) &&
|
require_rvfmin(s) &&
|
||||||
(s->sew != MO_8);
|
require_scale_rvfmin(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define GEN_OPFV_WIDEN_TRANS(NAME, CHECK, HELPER, FRM) \
|
#define GEN_OPFV_WIDEN_TRANS(NAME, CHECK, HELPER, FRM) \
|
||||||
@ -2790,15 +2804,15 @@ static bool opfxv_narrow_check(DisasContext *s, arg_rmr *a)
|
|||||||
static bool opffv_narrow_check(DisasContext *s, arg_rmr *a)
|
static bool opffv_narrow_check(DisasContext *s, arg_rmr *a)
|
||||||
{
|
{
|
||||||
return opfv_narrow_check(s, a) &&
|
return opfv_narrow_check(s, a) &&
|
||||||
require_scale_rvfmin(s) &&
|
require_rvfmin(s) &&
|
||||||
(s->sew != MO_8);
|
require_scale_rvfmin(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool opffv_rod_narrow_check(DisasContext *s, arg_rmr *a)
|
static bool opffv_rod_narrow_check(DisasContext *s, arg_rmr *a)
|
||||||
{
|
{
|
||||||
return opfv_narrow_check(s, a) &&
|
return opfv_narrow_check(s, a) &&
|
||||||
require_scale_rvf(s) &&
|
require_rvf(s) &&
|
||||||
(s->sew != MO_8);
|
require_scale_rvf(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define GEN_OPFV_NARROW_TRANS(NAME, CHECK, HELPER, FRM) \
|
#define GEN_OPFV_NARROW_TRANS(NAME, CHECK, HELPER, FRM) \
|
||||||
@ -2925,8 +2939,8 @@ GEN_OPFVV_TRANS(vfredmin_vs, freduction_check)
|
|||||||
static bool freduction_widen_check(DisasContext *s, arg_rmrr *a)
|
static bool freduction_widen_check(DisasContext *s, arg_rmrr *a)
|
||||||
{
|
{
|
||||||
return reduction_widen_check(s, a) &&
|
return reduction_widen_check(s, a) &&
|
||||||
require_scale_rvf(s) &&
|
require_rvf(s) &&
|
||||||
(s->sew != MO_8);
|
require_scale_rvf(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
GEN_OPFVV_WIDEN_TRANS(vfwredusum_vs, freduction_widen_check)
|
GEN_OPFVV_WIDEN_TRANS(vfwredusum_vs, freduction_widen_check)
|
||||||
|
@ -31,27 +31,35 @@
|
|||||||
static bool trans_cbo_clean(DisasContext *ctx, arg_cbo_clean *a)
|
static bool trans_cbo_clean(DisasContext *ctx, arg_cbo_clean *a)
|
||||||
{
|
{
|
||||||
REQUIRE_ZICBOM(ctx);
|
REQUIRE_ZICBOM(ctx);
|
||||||
gen_helper_cbo_clean_flush(tcg_env, cpu_gpr[a->rs1]);
|
TCGv src = get_address(ctx, a->rs1, 0);
|
||||||
|
|
||||||
|
gen_helper_cbo_clean_flush(tcg_env, src);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool trans_cbo_flush(DisasContext *ctx, arg_cbo_flush *a)
|
static bool trans_cbo_flush(DisasContext *ctx, arg_cbo_flush *a)
|
||||||
{
|
{
|
||||||
REQUIRE_ZICBOM(ctx);
|
REQUIRE_ZICBOM(ctx);
|
||||||
gen_helper_cbo_clean_flush(tcg_env, cpu_gpr[a->rs1]);
|
TCGv src = get_address(ctx, a->rs1, 0);
|
||||||
|
|
||||||
|
gen_helper_cbo_clean_flush(tcg_env, src);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool trans_cbo_inval(DisasContext *ctx, arg_cbo_inval *a)
|
static bool trans_cbo_inval(DisasContext *ctx, arg_cbo_inval *a)
|
||||||
{
|
{
|
||||||
REQUIRE_ZICBOM(ctx);
|
REQUIRE_ZICBOM(ctx);
|
||||||
gen_helper_cbo_inval(tcg_env, cpu_gpr[a->rs1]);
|
TCGv src = get_address(ctx, a->rs1, 0);
|
||||||
|
|
||||||
|
gen_helper_cbo_inval(tcg_env, src);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool trans_cbo_zero(DisasContext *ctx, arg_cbo_zero *a)
|
static bool trans_cbo_zero(DisasContext *ctx, arg_cbo_zero *a)
|
||||||
{
|
{
|
||||||
REQUIRE_ZICBOZ(ctx);
|
REQUIRE_ZICBOZ(ctx);
|
||||||
gen_helper_cbo_zero(tcg_env, cpu_gpr[a->rs1]);
|
TCGv src = get_address(ctx, a->rs1, 0);
|
||||||
|
|
||||||
|
gen_helper_cbo_zero(tcg_env, src);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -427,13 +427,17 @@ static void kvm_riscv_update_cpu_cfg_isa_ext(RISCVCPU *cpu, CPUState *cs)
|
|||||||
reg = kvm_cpu_cfg_get(cpu, multi_ext_cfg);
|
reg = kvm_cpu_cfg_get(cpu, multi_ext_cfg);
|
||||||
ret = kvm_set_one_reg(cs, id, ®);
|
ret = kvm_set_one_reg(cs, id, ®);
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
error_report("Unable to %s extension %s in KVM, error %d",
|
if (!reg && ret == -EINVAL) {
|
||||||
reg ? "enable" : "disable",
|
warn_report("KVM cannot disable extension %s",
|
||||||
|
multi_ext_cfg->name);
|
||||||
|
} else {
|
||||||
|
error_report("Unable to enable extension %s in KVM, error %d",
|
||||||
multi_ext_cfg->name, ret);
|
multi_ext_cfg->name, ret);
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void cpu_get_cfg_unavailable(Object *obj, Visitor *v,
|
static void cpu_get_cfg_unavailable(Object *obj, Visitor *v,
|
||||||
const char *name,
|
const char *name,
|
||||||
@ -1054,8 +1058,8 @@ static void kvm_riscv_read_vlenb(RISCVCPU *cpu, KVMScratchCPU *kvmcpu,
|
|||||||
|
|
||||||
ret = ioctl(kvmcpu->cpufd, KVM_GET_ONE_REG, ®);
|
ret = ioctl(kvmcpu->cpufd, KVM_GET_ONE_REG, ®);
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
error_report("Unable to read vlenb register, error code: %s",
|
error_report("Unable to read vlenb register, error code: %d",
|
||||||
strerrorname_np(errno));
|
errno);
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1418,6 +1422,28 @@ static int kvm_riscv_handle_sbi(CPUState *cs, struct kvm_run *run)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int kvm_riscv_handle_csr(CPUState *cs, struct kvm_run *run)
|
||||||
|
{
|
||||||
|
target_ulong csr_num = run->riscv_csr.csr_num;
|
||||||
|
target_ulong new_value = run->riscv_csr.new_value;
|
||||||
|
target_ulong write_mask = run->riscv_csr.write_mask;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
switch (csr_num) {
|
||||||
|
case CSR_SEED:
|
||||||
|
run->riscv_csr.ret_value = riscv_new_csr_seed(new_value, write_mask);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
qemu_log_mask(LOG_UNIMP,
|
||||||
|
"%s: un-handled CSR EXIT for CSR %lx\n",
|
||||||
|
__func__, csr_num);
|
||||||
|
ret = -1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run)
|
int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
@ -1425,6 +1451,9 @@ int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run)
|
|||||||
case KVM_EXIT_RISCV_SBI:
|
case KVM_EXIT_RISCV_SBI:
|
||||||
ret = kvm_riscv_handle_sbi(cs, run);
|
ret = kvm_riscv_handle_sbi(cs, run);
|
||||||
break;
|
break;
|
||||||
|
case KVM_EXIT_RISCV_CSR:
|
||||||
|
ret = kvm_riscv_handle_csr(cs, run);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
qemu_log_mask(LOG_UNIMP, "%s: un-handled exit reason %d\n",
|
qemu_log_mask(LOG_UNIMP, "%s: un-handled exit reason %d\n",
|
||||||
__func__, run->exit_reason);
|
__func__, run->exit_reason);
|
||||||
@ -1642,7 +1671,14 @@ void kvm_riscv_aia_create(MachineState *machine, uint64_t group_shift,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (max_hart_per_socket > 1) {
|
||||||
|
max_hart_per_socket--;
|
||||||
hart_bits = find_last_bit(&max_hart_per_socket, BITS_PER_LONG) + 1;
|
hart_bits = find_last_bit(&max_hart_per_socket, BITS_PER_LONG) + 1;
|
||||||
|
} else {
|
||||||
|
hart_bits = 0;
|
||||||
|
}
|
||||||
|
|
||||||
ret = kvm_device_access(aia_fd, KVM_DEV_RISCV_AIA_GRP_CONFIG,
|
ret = kvm_device_access(aia_fd, KVM_DEV_RISCV_AIA_GRP_CONFIG,
|
||||||
KVM_DEV_RISCV_AIA_CONFIG_HART_BITS,
|
KVM_DEV_RISCV_AIA_CONFIG_HART_BITS,
|
||||||
&hart_bits, true, NULL);
|
&hart_bits, true, NULL);
|
||||||
|
@ -30,6 +30,28 @@ void vext_set_elems_1s(void *base, uint32_t is_agnostic, uint32_t cnt,
|
|||||||
if (tot - cnt == 0) {
|
if (tot - cnt == 0) {
|
||||||
return ;
|
return ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (HOST_BIG_ENDIAN) {
|
||||||
|
/*
|
||||||
|
* Deal the situation when the elements are insdie
|
||||||
|
* only one uint64 block including setting the
|
||||||
|
* masked-off element.
|
||||||
|
*/
|
||||||
|
if (((tot - 1) ^ cnt) < 8) {
|
||||||
|
memset(base + H1(tot - 1), -1, tot - cnt);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* Otherwise, at least cross two uint64_t blocks.
|
||||||
|
* Set first unaligned block.
|
||||||
|
*/
|
||||||
|
if (cnt % 8 != 0) {
|
||||||
|
uint32_t j = ROUND_UP(cnt, 8);
|
||||||
|
memset(base + H1(j - 1), -1, j - cnt);
|
||||||
|
cnt = j;
|
||||||
|
}
|
||||||
|
/* Set other 64bit aligend blocks */
|
||||||
|
}
|
||||||
memset(base + cnt, -1, tot - cnt);
|
memset(base + cnt, -1, tot - cnt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -714,7 +714,7 @@ static void _decode_opc(DisasContext * ctx)
|
|||||||
tcg_gen_xor_i32(t2, REG(B7_4), REG(B11_8));
|
tcg_gen_xor_i32(t2, REG(B7_4), REG(B11_8));
|
||||||
tcg_gen_andc_i32(cpu_sr_t, t1, t2);
|
tcg_gen_andc_i32(cpu_sr_t, t1, t2);
|
||||||
tcg_gen_shri_i32(cpu_sr_t, cpu_sr_t, 31);
|
tcg_gen_shri_i32(cpu_sr_t, cpu_sr_t, 31);
|
||||||
tcg_gen_mov_i32(REG(B7_4), t0);
|
tcg_gen_mov_i32(REG(B11_8), t0);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
case 0x2009: /* and Rm,Rn */
|
case 0x2009: /* and Rm,Rn */
|
||||||
@ -933,7 +933,7 @@ static void _decode_opc(DisasContext * ctx)
|
|||||||
t0 = tcg_temp_new();
|
t0 = tcg_temp_new();
|
||||||
tcg_gen_sub_i32(t0, REG(B11_8), REG(B7_4));
|
tcg_gen_sub_i32(t0, REG(B11_8), REG(B7_4));
|
||||||
t1 = tcg_temp_new();
|
t1 = tcg_temp_new();
|
||||||
tcg_gen_xor_i32(t1, t0, REG(B7_4));
|
tcg_gen_xor_i32(t1, t0, REG(B11_8));
|
||||||
t2 = tcg_temp_new();
|
t2 = tcg_temp_new();
|
||||||
tcg_gen_xor_i32(t2, REG(B11_8), REG(B7_4));
|
tcg_gen_xor_i32(t2, REG(B11_8), REG(B7_4));
|
||||||
tcg_gen_and_i32(t1, t1, t2);
|
tcg_gen_and_i32(t1, t1, t2);
|
||||||
@ -2181,6 +2181,7 @@ static void decode_gusa(DisasContext *ctx, CPUSH4State *env)
|
|||||||
*/
|
*/
|
||||||
for (i = 1; i < max_insns; ++i) {
|
for (i = 1; i < max_insns; ++i) {
|
||||||
tcg_gen_insn_start(pc + i * 2, ctx->envflags);
|
tcg_gen_insn_start(pc + i * 2, ctx->envflags);
|
||||||
|
ctx->base.insn_start = tcg_last_op();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -94,15 +94,12 @@ DEF_HELPER_FLAGS_2(fstox, TCG_CALL_NO_WG, s64, env, f32)
|
|||||||
DEF_HELPER_FLAGS_2(fdtox, TCG_CALL_NO_WG, s64, env, f64)
|
DEF_HELPER_FLAGS_2(fdtox, TCG_CALL_NO_WG, s64, env, f64)
|
||||||
DEF_HELPER_FLAGS_2(fqtox, TCG_CALL_NO_WG, s64, env, i128)
|
DEF_HELPER_FLAGS_2(fqtox, TCG_CALL_NO_WG, s64, env, i128)
|
||||||
|
|
||||||
DEF_HELPER_FLAGS_2(fpmerge, TCG_CALL_NO_RWG_SE, i64, i64, i64)
|
DEF_HELPER_FLAGS_2(fpmerge, TCG_CALL_NO_RWG_SE, i64, i32, i32)
|
||||||
DEF_HELPER_FLAGS_2(fmul8x16, TCG_CALL_NO_RWG_SE, i64, i64, i64)
|
DEF_HELPER_FLAGS_2(fmul8x16, TCG_CALL_NO_RWG_SE, i64, i32, i64)
|
||||||
DEF_HELPER_FLAGS_2(fmul8x16al, TCG_CALL_NO_RWG_SE, i64, i64, i64)
|
DEF_HELPER_FLAGS_2(fmul8x16a, TCG_CALL_NO_RWG_SE, i64, i32, s32)
|
||||||
DEF_HELPER_FLAGS_2(fmul8x16au, TCG_CALL_NO_RWG_SE, i64, i64, i64)
|
|
||||||
DEF_HELPER_FLAGS_2(fmul8sux16, TCG_CALL_NO_RWG_SE, i64, i64, i64)
|
DEF_HELPER_FLAGS_2(fmul8sux16, TCG_CALL_NO_RWG_SE, i64, i64, i64)
|
||||||
DEF_HELPER_FLAGS_2(fmul8ulx16, TCG_CALL_NO_RWG_SE, i64, i64, i64)
|
DEF_HELPER_FLAGS_2(fmul8ulx16, TCG_CALL_NO_RWG_SE, i64, i64, i64)
|
||||||
DEF_HELPER_FLAGS_2(fmuld8sux16, TCG_CALL_NO_RWG_SE, i64, i64, i64)
|
DEF_HELPER_FLAGS_1(fexpand, TCG_CALL_NO_RWG_SE, i64, i32)
|
||||||
DEF_HELPER_FLAGS_2(fmuld8ulx16, TCG_CALL_NO_RWG_SE, i64, i64, i64)
|
|
||||||
DEF_HELPER_FLAGS_2(fexpand, TCG_CALL_NO_RWG_SE, i64, i64, i64)
|
|
||||||
DEF_HELPER_FLAGS_3(pdist, TCG_CALL_NO_RWG_SE, i64, i64, i64, i64)
|
DEF_HELPER_FLAGS_3(pdist, TCG_CALL_NO_RWG_SE, i64, i64, i64, i64)
|
||||||
DEF_HELPER_FLAGS_2(fpack16, TCG_CALL_NO_RWG_SE, i32, i64, i64)
|
DEF_HELPER_FLAGS_2(fpack16, TCG_CALL_NO_RWG_SE, i32, i64, i64)
|
||||||
DEF_HELPER_FLAGS_3(fpack32, TCG_CALL_NO_RWG_SE, i64, i64, i64, i64)
|
DEF_HELPER_FLAGS_3(fpack32, TCG_CALL_NO_RWG_SE, i64, i64, i64, i64)
|
||||||
|
@ -352,7 +352,7 @@ FCMPEq 10 000 cc:2 110101 rs1:5 0 0101 0111 rs2:5
|
|||||||
FALIGNDATAg 10 ..... 110110 ..... 0 0100 1000 ..... @r_r_r
|
FALIGNDATAg 10 ..... 110110 ..... 0 0100 1000 ..... @r_r_r
|
||||||
FPMERGE 10 ..... 110110 ..... 0 0100 1011 ..... @r_r_r
|
FPMERGE 10 ..... 110110 ..... 0 0100 1011 ..... @r_r_r
|
||||||
BSHUFFLE 10 ..... 110110 ..... 0 0100 1100 ..... @r_r_r
|
BSHUFFLE 10 ..... 110110 ..... 0 0100 1100 ..... @r_r_r
|
||||||
FEXPAND 10 ..... 110110 ..... 0 0100 1101 ..... @r_r_r
|
FEXPAND 10 ..... 110110 00000 0 0100 1101 ..... @r_r2
|
||||||
|
|
||||||
FSRCd 10 ..... 110110 ..... 0 0111 0100 00000 @r_r1 # FSRC1d
|
FSRCd 10 ..... 110110 ..... 0 0111 0100 00000 @r_r1 # FSRC1d
|
||||||
FSRCs 10 ..... 110110 ..... 0 0111 0101 00000 @r_r1 # FSRC1s
|
FSRCs 10 ..... 110110 ..... 0 0111 0101 00000 @r_r1 # FSRC1s
|
||||||
|
@ -45,6 +45,7 @@
|
|||||||
# define gen_helper_clear_softint(E, S) qemu_build_not_reached()
|
# define gen_helper_clear_softint(E, S) qemu_build_not_reached()
|
||||||
# define gen_helper_done(E) qemu_build_not_reached()
|
# define gen_helper_done(E) qemu_build_not_reached()
|
||||||
# define gen_helper_flushw(E) qemu_build_not_reached()
|
# define gen_helper_flushw(E) qemu_build_not_reached()
|
||||||
|
# define gen_helper_fmul8x16a(D, S1, S2) qemu_build_not_reached()
|
||||||
# define gen_helper_rdccr(D, E) qemu_build_not_reached()
|
# define gen_helper_rdccr(D, E) qemu_build_not_reached()
|
||||||
# define gen_helper_rdcwp(D, E) qemu_build_not_reached()
|
# define gen_helper_rdcwp(D, E) qemu_build_not_reached()
|
||||||
# define gen_helper_restored(E) qemu_build_not_reached()
|
# define gen_helper_restored(E) qemu_build_not_reached()
|
||||||
@ -72,11 +73,7 @@
|
|||||||
# define gen_helper_fexpand ({ qemu_build_not_reached(); NULL; })
|
# define gen_helper_fexpand ({ qemu_build_not_reached(); NULL; })
|
||||||
# define gen_helper_fmul8sux16 ({ qemu_build_not_reached(); NULL; })
|
# define gen_helper_fmul8sux16 ({ qemu_build_not_reached(); NULL; })
|
||||||
# define gen_helper_fmul8ulx16 ({ qemu_build_not_reached(); NULL; })
|
# define gen_helper_fmul8ulx16 ({ qemu_build_not_reached(); NULL; })
|
||||||
# define gen_helper_fmul8x16al ({ qemu_build_not_reached(); NULL; })
|
|
||||||
# define gen_helper_fmul8x16au ({ qemu_build_not_reached(); NULL; })
|
|
||||||
# define gen_helper_fmul8x16 ({ qemu_build_not_reached(); NULL; })
|
# define gen_helper_fmul8x16 ({ qemu_build_not_reached(); NULL; })
|
||||||
# define gen_helper_fmuld8sux16 ({ qemu_build_not_reached(); NULL; })
|
|
||||||
# define gen_helper_fmuld8ulx16 ({ qemu_build_not_reached(); NULL; })
|
|
||||||
# define gen_helper_fpmerge ({ qemu_build_not_reached(); NULL; })
|
# define gen_helper_fpmerge ({ qemu_build_not_reached(); NULL; })
|
||||||
# define gen_helper_fqtox ({ qemu_build_not_reached(); NULL; })
|
# define gen_helper_fqtox ({ qemu_build_not_reached(); NULL; })
|
||||||
# define gen_helper_fstox ({ qemu_build_not_reached(); NULL; })
|
# define gen_helper_fstox ({ qemu_build_not_reached(); NULL; })
|
||||||
@ -719,6 +716,60 @@ static void gen_op_bshuffle(TCGv_i64 dst, TCGv_i64 src1, TCGv_i64 src2)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void gen_op_fmul8x16al(TCGv_i64 dst, TCGv_i32 src1, TCGv_i32 src2)
|
||||||
|
{
|
||||||
|
tcg_gen_ext16s_i32(src2, src2);
|
||||||
|
gen_helper_fmul8x16a(dst, src1, src2);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void gen_op_fmul8x16au(TCGv_i64 dst, TCGv_i32 src1, TCGv_i32 src2)
|
||||||
|
{
|
||||||
|
tcg_gen_sari_i32(src2, src2, 16);
|
||||||
|
gen_helper_fmul8x16a(dst, src1, src2);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void gen_op_fmuld8ulx16(TCGv_i64 dst, TCGv_i32 src1, TCGv_i32 src2)
|
||||||
|
{
|
||||||
|
TCGv_i32 t0 = tcg_temp_new_i32();
|
||||||
|
TCGv_i32 t1 = tcg_temp_new_i32();
|
||||||
|
TCGv_i32 t2 = tcg_temp_new_i32();
|
||||||
|
|
||||||
|
tcg_gen_ext8u_i32(t0, src1);
|
||||||
|
tcg_gen_ext16s_i32(t1, src2);
|
||||||
|
tcg_gen_mul_i32(t0, t0, t1);
|
||||||
|
|
||||||
|
tcg_gen_extract_i32(t1, src1, 16, 8);
|
||||||
|
tcg_gen_sextract_i32(t2, src2, 16, 16);
|
||||||
|
tcg_gen_mul_i32(t1, t1, t2);
|
||||||
|
|
||||||
|
tcg_gen_concat_i32_i64(dst, t0, t1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void gen_op_fmuld8sux16(TCGv_i64 dst, TCGv_i32 src1, TCGv_i32 src2)
|
||||||
|
{
|
||||||
|
TCGv_i32 t0 = tcg_temp_new_i32();
|
||||||
|
TCGv_i32 t1 = tcg_temp_new_i32();
|
||||||
|
TCGv_i32 t2 = tcg_temp_new_i32();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The insn description talks about extracting the upper 8 bits
|
||||||
|
* of the signed 16-bit input rs1, performing the multiply, then
|
||||||
|
* shifting left by 8 bits. Instead, zap the lower 8 bits of
|
||||||
|
* the rs1 input, which avoids the need for two shifts.
|
||||||
|
*/
|
||||||
|
tcg_gen_ext16s_i32(t0, src1);
|
||||||
|
tcg_gen_andi_i32(t0, t0, ~0xff);
|
||||||
|
tcg_gen_ext16s_i32(t1, src2);
|
||||||
|
tcg_gen_mul_i32(t0, t0, t1);
|
||||||
|
|
||||||
|
tcg_gen_sextract_i32(t1, src1, 16, 16);
|
||||||
|
tcg_gen_andi_i32(t1, t1, ~0xff);
|
||||||
|
tcg_gen_sextract_i32(t2, src2, 16, 16);
|
||||||
|
tcg_gen_mul_i32(t1, t1, t2);
|
||||||
|
|
||||||
|
tcg_gen_concat_i32_i64(dst, t0, t1);
|
||||||
|
}
|
||||||
|
|
||||||
static void finishing_insn(DisasContext *dc)
|
static void finishing_insn(DisasContext *dc)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
@ -4358,6 +4409,25 @@ TRANS(FSQRTd, ALL, do_env_dd, a, gen_helper_fsqrtd)
|
|||||||
TRANS(FxTOd, 64, do_env_dd, a, gen_helper_fxtod)
|
TRANS(FxTOd, 64, do_env_dd, a, gen_helper_fxtod)
|
||||||
TRANS(FdTOx, 64, do_env_dd, a, gen_helper_fdtox)
|
TRANS(FdTOx, 64, do_env_dd, a, gen_helper_fdtox)
|
||||||
|
|
||||||
|
static bool do_df(DisasContext *dc, arg_r_r *a,
|
||||||
|
void (*func)(TCGv_i64, TCGv_i32))
|
||||||
|
{
|
||||||
|
TCGv_i64 dst;
|
||||||
|
TCGv_i32 src;
|
||||||
|
|
||||||
|
if (gen_trap_ifnofpu(dc)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
dst = tcg_temp_new_i64();
|
||||||
|
src = gen_load_fpr_F(dc, a->rs);
|
||||||
|
func(dst, src);
|
||||||
|
gen_store_fpr_D(dc, a->rd, dst);
|
||||||
|
return advance_pc(dc);
|
||||||
|
}
|
||||||
|
|
||||||
|
TRANS(FEXPAND, VIS1, do_df, a, gen_helper_fexpand)
|
||||||
|
|
||||||
static bool do_env_df(DisasContext *dc, arg_r_r *a,
|
static bool do_env_df(DisasContext *dc, arg_r_r *a,
|
||||||
void (*func)(TCGv_i64, TCGv_env, TCGv_i32))
|
void (*func)(TCGv_i64, TCGv_env, TCGv_i32))
|
||||||
{
|
{
|
||||||
@ -4564,6 +4634,50 @@ TRANS(FSUBs, ALL, do_env_fff, a, gen_helper_fsubs)
|
|||||||
TRANS(FMULs, ALL, do_env_fff, a, gen_helper_fmuls)
|
TRANS(FMULs, ALL, do_env_fff, a, gen_helper_fmuls)
|
||||||
TRANS(FDIVs, ALL, do_env_fff, a, gen_helper_fdivs)
|
TRANS(FDIVs, ALL, do_env_fff, a, gen_helper_fdivs)
|
||||||
|
|
||||||
|
static bool do_dff(DisasContext *dc, arg_r_r_r *a,
|
||||||
|
void (*func)(TCGv_i64, TCGv_i32, TCGv_i32))
|
||||||
|
{
|
||||||
|
TCGv_i64 dst;
|
||||||
|
TCGv_i32 src1, src2;
|
||||||
|
|
||||||
|
if (gen_trap_ifnofpu(dc)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
dst = gen_dest_fpr_D(dc, a->rd);
|
||||||
|
src1 = gen_load_fpr_F(dc, a->rs1);
|
||||||
|
src2 = gen_load_fpr_F(dc, a->rs2);
|
||||||
|
func(dst, src1, src2);
|
||||||
|
gen_store_fpr_D(dc, a->rd, dst);
|
||||||
|
return advance_pc(dc);
|
||||||
|
}
|
||||||
|
|
||||||
|
TRANS(FMUL8x16AU, VIS1, do_dff, a, gen_op_fmul8x16au)
|
||||||
|
TRANS(FMUL8x16AL, VIS1, do_dff, a, gen_op_fmul8x16al)
|
||||||
|
TRANS(FMULD8SUx16, VIS1, do_dff, a, gen_op_fmuld8sux16)
|
||||||
|
TRANS(FMULD8ULx16, VIS1, do_dff, a, gen_op_fmuld8ulx16)
|
||||||
|
TRANS(FPMERGE, VIS1, do_dff, a, gen_helper_fpmerge)
|
||||||
|
|
||||||
|
static bool do_dfd(DisasContext *dc, arg_r_r_r *a,
|
||||||
|
void (*func)(TCGv_i64, TCGv_i32, TCGv_i64))
|
||||||
|
{
|
||||||
|
TCGv_i64 dst, src2;
|
||||||
|
TCGv_i32 src1;
|
||||||
|
|
||||||
|
if (gen_trap_ifnofpu(dc)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
dst = gen_dest_fpr_D(dc, a->rd);
|
||||||
|
src1 = gen_load_fpr_F(dc, a->rs1);
|
||||||
|
src2 = gen_load_fpr_D(dc, a->rs2);
|
||||||
|
func(dst, src1, src2);
|
||||||
|
gen_store_fpr_D(dc, a->rd, dst);
|
||||||
|
return advance_pc(dc);
|
||||||
|
}
|
||||||
|
|
||||||
|
TRANS(FMUL8x16, VIS1, do_dfd, a, gen_helper_fmul8x16)
|
||||||
|
|
||||||
static bool do_ddd(DisasContext *dc, arg_r_r_r *a,
|
static bool do_ddd(DisasContext *dc, arg_r_r_r *a,
|
||||||
void (*func)(TCGv_i64, TCGv_i64, TCGv_i64))
|
void (*func)(TCGv_i64, TCGv_i64, TCGv_i64))
|
||||||
{
|
{
|
||||||
@ -4581,15 +4695,8 @@ static bool do_ddd(DisasContext *dc, arg_r_r_r *a,
|
|||||||
return advance_pc(dc);
|
return advance_pc(dc);
|
||||||
}
|
}
|
||||||
|
|
||||||
TRANS(FMUL8x16, VIS1, do_ddd, a, gen_helper_fmul8x16)
|
|
||||||
TRANS(FMUL8x16AU, VIS1, do_ddd, a, gen_helper_fmul8x16au)
|
|
||||||
TRANS(FMUL8x16AL, VIS1, do_ddd, a, gen_helper_fmul8x16al)
|
|
||||||
TRANS(FMUL8SUx16, VIS1, do_ddd, a, gen_helper_fmul8sux16)
|
TRANS(FMUL8SUx16, VIS1, do_ddd, a, gen_helper_fmul8sux16)
|
||||||
TRANS(FMUL8ULx16, VIS1, do_ddd, a, gen_helper_fmul8ulx16)
|
TRANS(FMUL8ULx16, VIS1, do_ddd, a, gen_helper_fmul8ulx16)
|
||||||
TRANS(FMULD8SUx16, VIS1, do_ddd, a, gen_helper_fmuld8sux16)
|
|
||||||
TRANS(FMULD8ULx16, VIS1, do_ddd, a, gen_helper_fmuld8ulx16)
|
|
||||||
TRANS(FPMERGE, VIS1, do_ddd, a, gen_helper_fpmerge)
|
|
||||||
TRANS(FEXPAND, VIS1, do_ddd, a, gen_helper_fexpand)
|
|
||||||
|
|
||||||
TRANS(FPADD16, VIS1, do_ddd, a, tcg_gen_vec_add16_i64)
|
TRANS(FPADD16, VIS1, do_ddd, a, tcg_gen_vec_add16_i64)
|
||||||
TRANS(FPADD32, VIS1, do_ddd, a, tcg_gen_vec_add32_i64)
|
TRANS(FPADD32, VIS1, do_ddd, a, tcg_gen_vec_add32_i64)
|
||||||
|
@ -74,36 +74,38 @@ typedef union {
|
|||||||
float32 f;
|
float32 f;
|
||||||
} VIS32;
|
} VIS32;
|
||||||
|
|
||||||
uint64_t helper_fpmerge(uint64_t src1, uint64_t src2)
|
uint64_t helper_fpmerge(uint32_t src1, uint32_t src2)
|
||||||
{
|
{
|
||||||
VIS64 s, d;
|
VIS32 s1, s2;
|
||||||
|
VIS64 d;
|
||||||
|
|
||||||
s.ll = src1;
|
s1.l = src1;
|
||||||
d.ll = src2;
|
s2.l = src2;
|
||||||
|
d.ll = 0;
|
||||||
|
|
||||||
/* Reverse calculation order to handle overlap */
|
d.VIS_B64(7) = s1.VIS_B32(3);
|
||||||
d.VIS_B64(7) = s.VIS_B64(3);
|
d.VIS_B64(6) = s2.VIS_B32(3);
|
||||||
d.VIS_B64(6) = d.VIS_B64(3);
|
d.VIS_B64(5) = s1.VIS_B32(2);
|
||||||
d.VIS_B64(5) = s.VIS_B64(2);
|
d.VIS_B64(4) = s2.VIS_B32(2);
|
||||||
d.VIS_B64(4) = d.VIS_B64(2);
|
d.VIS_B64(3) = s1.VIS_B32(1);
|
||||||
d.VIS_B64(3) = s.VIS_B64(1);
|
d.VIS_B64(2) = s2.VIS_B32(1);
|
||||||
d.VIS_B64(2) = d.VIS_B64(1);
|
d.VIS_B64(1) = s1.VIS_B32(0);
|
||||||
d.VIS_B64(1) = s.VIS_B64(0);
|
d.VIS_B64(0) = s2.VIS_B32(0);
|
||||||
/* d.VIS_B64(0) = d.VIS_B64(0); */
|
|
||||||
|
|
||||||
return d.ll;
|
return d.ll;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t helper_fmul8x16(uint64_t src1, uint64_t src2)
|
uint64_t helper_fmul8x16(uint32_t src1, uint64_t src2)
|
||||||
{
|
{
|
||||||
VIS64 s, d;
|
VIS64 d;
|
||||||
|
VIS32 s;
|
||||||
uint32_t tmp;
|
uint32_t tmp;
|
||||||
|
|
||||||
s.ll = src1;
|
s.l = src1;
|
||||||
d.ll = src2;
|
d.ll = src2;
|
||||||
|
|
||||||
#define PMUL(r) \
|
#define PMUL(r) \
|
||||||
tmp = (int32_t)d.VIS_SW64(r) * (int32_t)s.VIS_B64(r); \
|
tmp = (int32_t)d.VIS_SW64(r) * (int32_t)s.VIS_B32(r); \
|
||||||
if ((tmp & 0xff) > 0x7f) { \
|
if ((tmp & 0xff) > 0x7f) { \
|
||||||
tmp += 0x100; \
|
tmp += 0x100; \
|
||||||
} \
|
} \
|
||||||
@ -118,44 +120,23 @@ uint64_t helper_fmul8x16(uint64_t src1, uint64_t src2)
|
|||||||
return d.ll;
|
return d.ll;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t helper_fmul8x16al(uint64_t src1, uint64_t src2)
|
uint64_t helper_fmul8x16a(uint32_t src1, int32_t src2)
|
||||||
{
|
{
|
||||||
VIS64 s, d;
|
VIS32 s;
|
||||||
|
VIS64 d;
|
||||||
uint32_t tmp;
|
uint32_t tmp;
|
||||||
|
|
||||||
s.ll = src1;
|
s.l = src1;
|
||||||
d.ll = src2;
|
d.ll = 0;
|
||||||
|
|
||||||
#define PMUL(r) \
|
#define PMUL(r) \
|
||||||
tmp = (int32_t)d.VIS_SW64(1) * (int32_t)s.VIS_B64(r); \
|
do { \
|
||||||
|
tmp = src2 * (int32_t)s.VIS_B32(r); \
|
||||||
if ((tmp & 0xff) > 0x7f) { \
|
if ((tmp & 0xff) > 0x7f) { \
|
||||||
tmp += 0x100; \
|
tmp += 0x100; \
|
||||||
} \
|
} \
|
||||||
d.VIS_W64(r) = tmp >> 8;
|
d.VIS_W64(r) = tmp >> 8; \
|
||||||
|
} while (0)
|
||||||
PMUL(0);
|
|
||||||
PMUL(1);
|
|
||||||
PMUL(2);
|
|
||||||
PMUL(3);
|
|
||||||
#undef PMUL
|
|
||||||
|
|
||||||
return d.ll;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint64_t helper_fmul8x16au(uint64_t src1, uint64_t src2)
|
|
||||||
{
|
|
||||||
VIS64 s, d;
|
|
||||||
uint32_t tmp;
|
|
||||||
|
|
||||||
s.ll = src1;
|
|
||||||
d.ll = src2;
|
|
||||||
|
|
||||||
#define PMUL(r) \
|
|
||||||
tmp = (int32_t)d.VIS_SW64(0) * (int32_t)s.VIS_B64(r); \
|
|
||||||
if ((tmp & 0xff) > 0x7f) { \
|
|
||||||
tmp += 0x100; \
|
|
||||||
} \
|
|
||||||
d.VIS_W64(r) = tmp >> 8;
|
|
||||||
|
|
||||||
PMUL(0);
|
PMUL(0);
|
||||||
PMUL(1);
|
PMUL(1);
|
||||||
@ -214,59 +195,13 @@ uint64_t helper_fmul8ulx16(uint64_t src1, uint64_t src2)
|
|||||||
return d.ll;
|
return d.ll;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t helper_fmuld8sux16(uint64_t src1, uint64_t src2)
|
uint64_t helper_fexpand(uint32_t src2)
|
||||||
{
|
|
||||||
VIS64 s, d;
|
|
||||||
uint32_t tmp;
|
|
||||||
|
|
||||||
s.ll = src1;
|
|
||||||
d.ll = src2;
|
|
||||||
|
|
||||||
#define PMUL(r) \
|
|
||||||
tmp = (int32_t)d.VIS_SW64(r) * ((int32_t)s.VIS_SW64(r) >> 8); \
|
|
||||||
if ((tmp & 0xff) > 0x7f) { \
|
|
||||||
tmp += 0x100; \
|
|
||||||
} \
|
|
||||||
d.VIS_L64(r) = tmp;
|
|
||||||
|
|
||||||
/* Reverse calculation order to handle overlap */
|
|
||||||
PMUL(1);
|
|
||||||
PMUL(0);
|
|
||||||
#undef PMUL
|
|
||||||
|
|
||||||
return d.ll;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint64_t helper_fmuld8ulx16(uint64_t src1, uint64_t src2)
|
|
||||||
{
|
|
||||||
VIS64 s, d;
|
|
||||||
uint32_t tmp;
|
|
||||||
|
|
||||||
s.ll = src1;
|
|
||||||
d.ll = src2;
|
|
||||||
|
|
||||||
#define PMUL(r) \
|
|
||||||
tmp = (int32_t)d.VIS_SW64(r) * ((uint32_t)s.VIS_B64(r * 2)); \
|
|
||||||
if ((tmp & 0xff) > 0x7f) { \
|
|
||||||
tmp += 0x100; \
|
|
||||||
} \
|
|
||||||
d.VIS_L64(r) = tmp;
|
|
||||||
|
|
||||||
/* Reverse calculation order to handle overlap */
|
|
||||||
PMUL(1);
|
|
||||||
PMUL(0);
|
|
||||||
#undef PMUL
|
|
||||||
|
|
||||||
return d.ll;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint64_t helper_fexpand(uint64_t src1, uint64_t src2)
|
|
||||||
{
|
{
|
||||||
VIS32 s;
|
VIS32 s;
|
||||||
VIS64 d;
|
VIS64 d;
|
||||||
|
|
||||||
s.l = (uint32_t)src1;
|
s.l = src2;
|
||||||
d.ll = src2;
|
d.ll = 0;
|
||||||
d.VIS_W64(0) = s.VIS_B32(0) << 4;
|
d.VIS_W64(0) = s.VIS_B32(0) << 4;
|
||||||
d.VIS_W64(1) = s.VIS_B32(1) << 4;
|
d.VIS_W64(1) = s.VIS_B32(1) << 4;
|
||||||
d.VIS_W64(2) = s.VIS_B32(2) << 4;
|
d.VIS_W64(2) = s.VIS_B32(2) << 4;
|
||||||
|
@ -808,18 +808,88 @@ static void tcg_out_ldst(TCGContext *s, LoongArchInsn opc, TCGReg data,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void tcg_out_ld(TCGContext *s, TCGType type, TCGReg arg,
|
static void tcg_out_ld(TCGContext *s, TCGType type, TCGReg dest,
|
||||||
TCGReg arg1, intptr_t arg2)
|
TCGReg base, intptr_t offset)
|
||||||
{
|
{
|
||||||
bool is_32bit = type == TCG_TYPE_I32;
|
switch (type) {
|
||||||
tcg_out_ldst(s, is_32bit ? OPC_LD_W : OPC_LD_D, arg, arg1, arg2);
|
case TCG_TYPE_I32:
|
||||||
|
if (dest < TCG_REG_V0) {
|
||||||
|
tcg_out_ldst(s, OPC_LD_W, dest, base, offset);
|
||||||
|
} else {
|
||||||
|
tcg_out_dupm_vec(s, TCG_TYPE_I128, MO_32, dest, base, offset);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case TCG_TYPE_I64:
|
||||||
|
if (dest < TCG_REG_V0) {
|
||||||
|
tcg_out_ldst(s, OPC_LD_D, dest, base, offset);
|
||||||
|
} else {
|
||||||
|
tcg_out_dupm_vec(s, TCG_TYPE_I128, MO_64, dest, base, offset);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case TCG_TYPE_V128:
|
||||||
|
if (-0x800 <= offset && offset <= 0x7ff) {
|
||||||
|
tcg_out_opc_vld(s, dest, base, offset);
|
||||||
|
} else {
|
||||||
|
tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_TMP0, offset);
|
||||||
|
tcg_out_opc_vldx(s, dest, base, TCG_REG_TMP0);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
g_assert_not_reached();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void tcg_out_st(TCGContext *s, TCGType type, TCGReg arg,
|
static void tcg_out_st(TCGContext *s, TCGType type, TCGReg src,
|
||||||
TCGReg arg1, intptr_t arg2)
|
TCGReg base, intptr_t offset)
|
||||||
{
|
{
|
||||||
bool is_32bit = type == TCG_TYPE_I32;
|
switch (type) {
|
||||||
tcg_out_ldst(s, is_32bit ? OPC_ST_W : OPC_ST_D, arg, arg1, arg2);
|
case TCG_TYPE_I32:
|
||||||
|
if (src < TCG_REG_V0) {
|
||||||
|
tcg_out_ldst(s, OPC_ST_W, src, base, offset);
|
||||||
|
} else {
|
||||||
|
/* TODO: Could use fst_s, fstx_s */
|
||||||
|
if (offset < -0x100 || offset > 0xff || (offset & 3)) {
|
||||||
|
if (-0x800 <= offset && offset <= 0x7ff) {
|
||||||
|
tcg_out_opc_addi_d(s, TCG_REG_TMP0, base, offset);
|
||||||
|
} else {
|
||||||
|
tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_TMP0, offset);
|
||||||
|
tcg_out_opc_add_d(s, TCG_REG_TMP0, TCG_REG_TMP0, base);
|
||||||
|
}
|
||||||
|
base = TCG_REG_TMP0;
|
||||||
|
offset = 0;
|
||||||
|
}
|
||||||
|
tcg_out_opc_vstelm_w(s, src, base, offset, 0);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case TCG_TYPE_I64:
|
||||||
|
if (src < TCG_REG_V0) {
|
||||||
|
tcg_out_ldst(s, OPC_ST_D, src, base, offset);
|
||||||
|
} else {
|
||||||
|
/* TODO: Could use fst_d, fstx_d */
|
||||||
|
if (offset < -0x100 || offset > 0xff || (offset & 7)) {
|
||||||
|
if (-0x800 <= offset && offset <= 0x7ff) {
|
||||||
|
tcg_out_opc_addi_d(s, TCG_REG_TMP0, base, offset);
|
||||||
|
} else {
|
||||||
|
tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_TMP0, offset);
|
||||||
|
tcg_out_opc_add_d(s, TCG_REG_TMP0, TCG_REG_TMP0, base);
|
||||||
|
}
|
||||||
|
base = TCG_REG_TMP0;
|
||||||
|
offset = 0;
|
||||||
|
}
|
||||||
|
tcg_out_opc_vstelm_d(s, src, base, offset, 0);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case TCG_TYPE_V128:
|
||||||
|
if (-0x800 <= offset && offset <= 0x7ff) {
|
||||||
|
tcg_out_opc_vst(s, src, base, offset);
|
||||||
|
} else {
|
||||||
|
tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_TMP0, offset);
|
||||||
|
tcg_out_opc_vstx(s, src, base, TCG_REG_TMP0);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
g_assert_not_reached();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool tcg_out_sti(TCGContext *s, TCGType type, TCGArg val,
|
static bool tcg_out_sti(TCGContext *s, TCGType type, TCGArg val,
|
||||||
@ -1740,7 +1810,6 @@ static void tcg_out_vec_op(TCGContext *s, TCGOpcode opc,
|
|||||||
{
|
{
|
||||||
TCGType type = vecl + TCG_TYPE_V64;
|
TCGType type = vecl + TCG_TYPE_V64;
|
||||||
TCGArg a0, a1, a2, a3;
|
TCGArg a0, a1, a2, a3;
|
||||||
TCGReg temp = TCG_REG_TMP0;
|
|
||||||
TCGReg temp_vec = TCG_VEC_TMP0;
|
TCGReg temp_vec = TCG_VEC_TMP0;
|
||||||
|
|
||||||
static const LoongArchInsn cmp_vec_insn[16][4] = {
|
static const LoongArchInsn cmp_vec_insn[16][4] = {
|
||||||
@ -1820,22 +1889,10 @@ static void tcg_out_vec_op(TCGContext *s, TCGOpcode opc,
|
|||||||
|
|
||||||
switch (opc) {
|
switch (opc) {
|
||||||
case INDEX_op_st_vec:
|
case INDEX_op_st_vec:
|
||||||
/* Try to fit vst imm */
|
tcg_out_st(s, type, a0, a1, a2);
|
||||||
if (-0x800 <= a2 && a2 <= 0x7ff) {
|
|
||||||
tcg_out_opc_vst(s, a0, a1, a2);
|
|
||||||
} else {
|
|
||||||
tcg_out_movi(s, TCG_TYPE_I64, temp, a2);
|
|
||||||
tcg_out_opc_vstx(s, a0, a1, temp);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case INDEX_op_ld_vec:
|
case INDEX_op_ld_vec:
|
||||||
/* Try to fit vld imm */
|
tcg_out_ld(s, type, a0, a1, a2);
|
||||||
if (-0x800 <= a2 && a2 <= 0x7ff) {
|
|
||||||
tcg_out_opc_vld(s, a0, a1, a2);
|
|
||||||
} else {
|
|
||||||
tcg_out_movi(s, TCG_TYPE_I64, temp, a2);
|
|
||||||
tcg_out_opc_vldx(s, a0, a1, temp);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case INDEX_op_and_vec:
|
case INDEX_op_and_vec:
|
||||||
tcg_out_opc_vand_v(s, a0, a1, a2);
|
tcg_out_opc_vand_v(s, a0, a1, a2);
|
||||||
|
@ -646,12 +646,12 @@ class BootLinuxConsole(LinuxKernelTest):
|
|||||||
:avocado: tags=accel:tcg
|
:avocado: tags=accel:tcg
|
||||||
"""
|
"""
|
||||||
deb_url = ('https://apt.armbian.com/pool/main/l/'
|
deb_url = ('https://apt.armbian.com/pool/main/l/'
|
||||||
'linux-5.10.16-sunxi/linux-image-current-sunxi_21.02.2_armhf.deb')
|
'linux-6.6.16/linux-image-current-sunxi_24.2.1_armhf__6.6.16-Seb3e-D6b4a-P2359-Ce96bHfe66-HK01ba-V014b-B067e-R448a.deb')
|
||||||
deb_hash = '9fa84beda245cabf0b4fa84cf6eaa7738ead1da0'
|
deb_hash = 'f7c3c8c5432f765445dc6e7eab02f3bbe668256b'
|
||||||
deb_path = self.fetch_asset(deb_url, asset_hash=deb_hash)
|
deb_path = self.fetch_asset(deb_url, asset_hash=deb_hash)
|
||||||
kernel_path = self.extract_from_deb(deb_path,
|
kernel_path = self.extract_from_deb(deb_path,
|
||||||
'/boot/vmlinuz-5.10.16-sunxi')
|
'/boot/vmlinuz-6.6.16-current-sunxi')
|
||||||
dtb_path = '/usr/lib/linux-image-current-sunxi/sun4i-a10-cubieboard.dtb'
|
dtb_path = '/usr/lib/linux-image-6.6.16-current-sunxi/sun4i-a10-cubieboard.dtb'
|
||||||
dtb_path = self.extract_from_deb(deb_path, dtb_path)
|
dtb_path = self.extract_from_deb(deb_path, dtb_path)
|
||||||
initrd_url = ('https://github.com/groeck/linux-build-test/raw/'
|
initrd_url = ('https://github.com/groeck/linux-build-test/raw/'
|
||||||
'2eb0a73b5d5a28df3170c546ddaaa9757e1e0848/rootfs/'
|
'2eb0a73b5d5a28df3170c546ddaaa9757e1e0848/rootfs/'
|
||||||
@ -690,12 +690,12 @@ class BootLinuxConsole(LinuxKernelTest):
|
|||||||
:avocado: tags=accel:tcg
|
:avocado: tags=accel:tcg
|
||||||
"""
|
"""
|
||||||
deb_url = ('https://apt.armbian.com/pool/main/l/'
|
deb_url = ('https://apt.armbian.com/pool/main/l/'
|
||||||
'linux-5.10.16-sunxi/linux-image-current-sunxi_21.02.2_armhf.deb')
|
'linux-6.6.16/linux-image-current-sunxi_24.2.1_armhf__6.6.16-Seb3e-D6b4a-P2359-Ce96bHfe66-HK01ba-V014b-B067e-R448a.deb')
|
||||||
deb_hash = '9fa84beda245cabf0b4fa84cf6eaa7738ead1da0'
|
deb_hash = 'f7c3c8c5432f765445dc6e7eab02f3bbe668256b'
|
||||||
deb_path = self.fetch_asset(deb_url, asset_hash=deb_hash)
|
deb_path = self.fetch_asset(deb_url, asset_hash=deb_hash)
|
||||||
kernel_path = self.extract_from_deb(deb_path,
|
kernel_path = self.extract_from_deb(deb_path,
|
||||||
'/boot/vmlinuz-5.10.16-sunxi')
|
'/boot/vmlinuz-6.6.16-current-sunxi')
|
||||||
dtb_path = '/usr/lib/linux-image-current-sunxi/sun4i-a10-cubieboard.dtb'
|
dtb_path = '/usr/lib/linux-image-6.6.16-current-sunxi/sun4i-a10-cubieboard.dtb'
|
||||||
dtb_path = self.extract_from_deb(deb_path, dtb_path)
|
dtb_path = self.extract_from_deb(deb_path, dtb_path)
|
||||||
rootfs_url = ('https://github.com/groeck/linux-build-test/raw/'
|
rootfs_url = ('https://github.com/groeck/linux-build-test/raw/'
|
||||||
'2eb0a73b5d5a28df3170c546ddaaa9757e1e0848/rootfs/'
|
'2eb0a73b5d5a28df3170c546ddaaa9757e1e0848/rootfs/'
|
||||||
@ -872,13 +872,13 @@ class BootLinuxConsole(LinuxKernelTest):
|
|||||||
:avocado: tags=machine:bpim2u
|
:avocado: tags=machine:bpim2u
|
||||||
:avocado: tags=accel:tcg
|
:avocado: tags=accel:tcg
|
||||||
"""
|
"""
|
||||||
deb_url = ('https://apt.armbian.com/pool/main/l/linux-5.10.16-sunxi/'
|
deb_url = ('https://apt.armbian.com/pool/main/l/'
|
||||||
'linux-image-current-sunxi_21.02.2_armhf.deb')
|
'linux-6.6.16/linux-image-current-sunxi_24.2.1_armhf__6.6.16-Seb3e-D6b4a-P2359-Ce96bHfe66-HK01ba-V014b-B067e-R448a.deb')
|
||||||
deb_hash = '9fa84beda245cabf0b4fa84cf6eaa7738ead1da0'
|
deb_hash = 'f7c3c8c5432f765445dc6e7eab02f3bbe668256b'
|
||||||
deb_path = self.fetch_asset(deb_url, asset_hash=deb_hash)
|
deb_path = self.fetch_asset(deb_url, asset_hash=deb_hash)
|
||||||
kernel_path = self.extract_from_deb(deb_path,
|
kernel_path = self.extract_from_deb(deb_path,
|
||||||
'/boot/vmlinuz-5.10.16-sunxi')
|
'/boot/vmlinuz-6.6.16-current-sunxi')
|
||||||
dtb_path = ('/usr/lib/linux-image-current-sunxi/'
|
dtb_path = ('/usr/lib/linux-image-6.6.16-current-sunxi/'
|
||||||
'sun8i-r40-bananapi-m2-ultra.dtb')
|
'sun8i-r40-bananapi-m2-ultra.dtb')
|
||||||
dtb_path = self.extract_from_deb(deb_path, dtb_path)
|
dtb_path = self.extract_from_deb(deb_path, dtb_path)
|
||||||
|
|
||||||
@ -899,13 +899,13 @@ class BootLinuxConsole(LinuxKernelTest):
|
|||||||
:avocado: tags=accel:tcg
|
:avocado: tags=accel:tcg
|
||||||
:avocado: tags=machine:bpim2u
|
:avocado: tags=machine:bpim2u
|
||||||
"""
|
"""
|
||||||
deb_url = ('https://apt.armbian.com/pool/main/l/linux-5.10.16-sunxi/'
|
deb_url = ('https://apt.armbian.com/pool/main/l/'
|
||||||
'linux-image-current-sunxi_21.02.2_armhf.deb')
|
'linux-6.6.16/linux-image-current-sunxi_24.2.1_armhf__6.6.16-Seb3e-D6b4a-P2359-Ce96bHfe66-HK01ba-V014b-B067e-R448a.deb')
|
||||||
deb_hash = '9fa84beda245cabf0b4fa84cf6eaa7738ead1da0'
|
deb_hash = 'f7c3c8c5432f765445dc6e7eab02f3bbe668256b'
|
||||||
deb_path = self.fetch_asset(deb_url, asset_hash=deb_hash)
|
deb_path = self.fetch_asset(deb_url, asset_hash=deb_hash)
|
||||||
kernel_path = self.extract_from_deb(deb_path,
|
kernel_path = self.extract_from_deb(deb_path,
|
||||||
'/boot/vmlinuz-5.10.16-sunxi')
|
'/boot/vmlinuz-6.6.16-current-sunxi')
|
||||||
dtb_path = ('/usr/lib/linux-image-current-sunxi/'
|
dtb_path = ('/usr/lib/linux-image-6.6.16-current-sunxi/'
|
||||||
'sun8i-r40-bananapi-m2-ultra.dtb')
|
'sun8i-r40-bananapi-m2-ultra.dtb')
|
||||||
dtb_path = self.extract_from_deb(deb_path, dtb_path)
|
dtb_path = self.extract_from_deb(deb_path, dtb_path)
|
||||||
initrd_url = ('https://github.com/groeck/linux-build-test/raw/'
|
initrd_url = ('https://github.com/groeck/linux-build-test/raw/'
|
||||||
@ -946,13 +946,13 @@ class BootLinuxConsole(LinuxKernelTest):
|
|||||||
"""
|
"""
|
||||||
self.require_netdev('user')
|
self.require_netdev('user')
|
||||||
|
|
||||||
deb_url = ('https://apt.armbian.com/pool/main/l/linux-5.10.16-sunxi/'
|
deb_url = ('https://apt.armbian.com/pool/main/l/'
|
||||||
'linux-image-current-sunxi_21.02.2_armhf.deb')
|
'linux-6.6.16/linux-image-current-sunxi_24.2.1_armhf__6.6.16-Seb3e-D6b4a-P2359-Ce96bHfe66-HK01ba-V014b-B067e-R448a.deb')
|
||||||
deb_hash = '9fa84beda245cabf0b4fa84cf6eaa7738ead1da0'
|
deb_hash = 'f7c3c8c5432f765445dc6e7eab02f3bbe668256b'
|
||||||
deb_path = self.fetch_asset(deb_url, asset_hash=deb_hash)
|
deb_path = self.fetch_asset(deb_url, asset_hash=deb_hash)
|
||||||
kernel_path = self.extract_from_deb(deb_path,
|
kernel_path = self.extract_from_deb(deb_path,
|
||||||
'/boot/vmlinuz-5.10.16-sunxi')
|
'/boot/vmlinuz-6.6.16-current-sunxi')
|
||||||
dtb_path = ('/usr/lib/linux-image-current-sunxi/'
|
dtb_path = ('/usr/lib/linux-image-6.6.16-current-sunxi/'
|
||||||
'sun8i-r40-bananapi-m2-ultra.dtb')
|
'sun8i-r40-bananapi-m2-ultra.dtb')
|
||||||
dtb_path = self.extract_from_deb(deb_path, dtb_path)
|
dtb_path = self.extract_from_deb(deb_path, dtb_path)
|
||||||
rootfs_url = ('http://storage.kernelci.org/images/rootfs/buildroot/'
|
rootfs_url = ('http://storage.kernelci.org/images/rootfs/buildroot/'
|
||||||
@ -1049,12 +1049,12 @@ class BootLinuxConsole(LinuxKernelTest):
|
|||||||
:avocado: tags=accel:tcg
|
:avocado: tags=accel:tcg
|
||||||
"""
|
"""
|
||||||
deb_url = ('https://apt.armbian.com/pool/main/l/'
|
deb_url = ('https://apt.armbian.com/pool/main/l/'
|
||||||
'linux-5.10.16-sunxi/linux-image-current-sunxi_21.02.2_armhf.deb')
|
'linux-6.6.16/linux-image-current-sunxi_24.2.1_armhf__6.6.16-Seb3e-D6b4a-P2359-Ce96bHfe66-HK01ba-V014b-B067e-R448a.deb')
|
||||||
deb_hash = '9fa84beda245cabf0b4fa84cf6eaa7738ead1da0'
|
deb_hash = 'f7c3c8c5432f765445dc6e7eab02f3bbe668256b'
|
||||||
deb_path = self.fetch_asset(deb_url, asset_hash=deb_hash)
|
deb_path = self.fetch_asset(deb_url, asset_hash=deb_hash)
|
||||||
kernel_path = self.extract_from_deb(deb_path,
|
kernel_path = self.extract_from_deb(deb_path,
|
||||||
'/boot/vmlinuz-5.10.16-sunxi')
|
'/boot/vmlinuz-6.6.16-current-sunxi')
|
||||||
dtb_path = '/usr/lib/linux-image-current-sunxi/sun8i-h3-orangepi-pc.dtb'
|
dtb_path = '/usr/lib/linux-image-6.6.16-current-sunxi/sun8i-h3-orangepi-pc.dtb'
|
||||||
dtb_path = self.extract_from_deb(deb_path, dtb_path)
|
dtb_path = self.extract_from_deb(deb_path, dtb_path)
|
||||||
|
|
||||||
self.vm.set_console()
|
self.vm.set_console()
|
||||||
@ -1075,12 +1075,12 @@ class BootLinuxConsole(LinuxKernelTest):
|
|||||||
:avocado: tags=machine:orangepi-pc
|
:avocado: tags=machine:orangepi-pc
|
||||||
"""
|
"""
|
||||||
deb_url = ('https://apt.armbian.com/pool/main/l/'
|
deb_url = ('https://apt.armbian.com/pool/main/l/'
|
||||||
'linux-5.10.16-sunxi/linux-image-current-sunxi_21.02.2_armhf.deb')
|
'linux-6.6.16/linux-image-current-sunxi_24.2.1_armhf__6.6.16-Seb3e-D6b4a-P2359-Ce96bHfe66-HK01ba-V014b-B067e-R448a.deb')
|
||||||
deb_hash = '9fa84beda245cabf0b4fa84cf6eaa7738ead1da0'
|
deb_hash = 'f7c3c8c5432f765445dc6e7eab02f3bbe668256b'
|
||||||
deb_path = self.fetch_asset(deb_url, asset_hash=deb_hash)
|
deb_path = self.fetch_asset(deb_url, asset_hash=deb_hash)
|
||||||
kernel_path = self.extract_from_deb(deb_path,
|
kernel_path = self.extract_from_deb(deb_path,
|
||||||
'/boot/vmlinuz-5.10.16-sunxi')
|
'/boot/vmlinuz-6.6.16-current-sunxi')
|
||||||
dtb_path = '/usr/lib/linux-image-current-sunxi/sun8i-h3-orangepi-pc.dtb'
|
dtb_path = '/usr/lib/linux-image-6.6.16-current-sunxi/sun8i-h3-orangepi-pc.dtb'
|
||||||
dtb_path = self.extract_from_deb(deb_path, dtb_path)
|
dtb_path = self.extract_from_deb(deb_path, dtb_path)
|
||||||
initrd_url = ('https://github.com/groeck/linux-build-test/raw/'
|
initrd_url = ('https://github.com/groeck/linux-build-test/raw/'
|
||||||
'2eb0a73b5d5a28df3170c546ddaaa9757e1e0848/rootfs/'
|
'2eb0a73b5d5a28df3170c546ddaaa9757e1e0848/rootfs/'
|
||||||
@ -1121,12 +1121,12 @@ class BootLinuxConsole(LinuxKernelTest):
|
|||||||
self.require_netdev('user')
|
self.require_netdev('user')
|
||||||
|
|
||||||
deb_url = ('https://apt.armbian.com/pool/main/l/'
|
deb_url = ('https://apt.armbian.com/pool/main/l/'
|
||||||
'linux-5.10.16-sunxi/linux-image-current-sunxi_21.02.2_armhf.deb')
|
'linux-6.6.16/linux-image-current-sunxi_24.2.1_armhf__6.6.16-Seb3e-D6b4a-P2359-Ce96bHfe66-HK01ba-V014b-B067e-R448a.deb')
|
||||||
deb_hash = '9fa84beda245cabf0b4fa84cf6eaa7738ead1da0'
|
deb_hash = 'f7c3c8c5432f765445dc6e7eab02f3bbe668256b'
|
||||||
deb_path = self.fetch_asset(deb_url, asset_hash=deb_hash)
|
deb_path = self.fetch_asset(deb_url, asset_hash=deb_hash)
|
||||||
kernel_path = self.extract_from_deb(deb_path,
|
kernel_path = self.extract_from_deb(deb_path,
|
||||||
'/boot/vmlinuz-5.10.16-sunxi')
|
'/boot/vmlinuz-6.6.16-current-sunxi')
|
||||||
dtb_path = '/usr/lib/linux-image-current-sunxi/sun8i-h3-orangepi-pc.dtb'
|
dtb_path = '/usr/lib/linux-image-6.6.16-current-sunxi/sun8i-h3-orangepi-pc.dtb'
|
||||||
dtb_path = self.extract_from_deb(deb_path, dtb_path)
|
dtb_path = self.extract_from_deb(deb_path, dtb_path)
|
||||||
rootfs_url = ('http://storage.kernelci.org/images/rootfs/buildroot/'
|
rootfs_url = ('http://storage.kernelci.org/images/rootfs/buildroot/'
|
||||||
'buildroot-baseline/20221116.0/armel/rootfs.ext2.xz')
|
'buildroot-baseline/20221116.0/armel/rootfs.ext2.xz')
|
||||||
|
@ -203,12 +203,12 @@ class ReplayKernelNormal(ReplayKernelBase):
|
|||||||
:avocado: tags=machine:cubieboard
|
:avocado: tags=machine:cubieboard
|
||||||
"""
|
"""
|
||||||
deb_url = ('https://apt.armbian.com/pool/main/l/'
|
deb_url = ('https://apt.armbian.com/pool/main/l/'
|
||||||
'linux-5.10.16-sunxi/linux-image-current-sunxi_21.02.2_armhf.deb')
|
'linux-6.6.16/linux-image-current-sunxi_24.2.1_armhf__6.6.16-Seb3e-D6b4a-P2359-Ce96bHfe66-HK01ba-V014b-B067e-R448a.deb')
|
||||||
deb_hash = '9fa84beda245cabf0b4fa84cf6eaa7738ead1da0'
|
deb_hash = 'f7c3c8c5432f765445dc6e7eab02f3bbe668256b'
|
||||||
deb_path = self.fetch_asset(deb_url, asset_hash=deb_hash)
|
deb_path = self.fetch_asset(deb_url, asset_hash=deb_hash)
|
||||||
kernel_path = self.extract_from_deb(deb_path,
|
kernel_path = self.extract_from_deb(deb_path,
|
||||||
'/boot/vmlinuz-5.10.16-sunxi')
|
'/boot/vmlinuz-6.6.16-current-sunxi')
|
||||||
dtb_path = '/usr/lib/linux-image-current-sunxi/sun4i-a10-cubieboard.dtb'
|
dtb_path = '/usr/lib/linux-image-6.6.16-current-sunxi/sun4i-a10-cubieboard.dtb'
|
||||||
dtb_path = self.extract_from_deb(deb_path, dtb_path)
|
dtb_path = self.extract_from_deb(deb_path, dtb_path)
|
||||||
initrd_url = ('https://github.com/groeck/linux-build-test/raw/'
|
initrd_url = ('https://github.com/groeck/linux-build-test/raw/'
|
||||||
'2eb0a73b5d5a28df3170c546ddaaa9757e1e0848/rootfs/'
|
'2eb0a73b5d5a28df3170c546ddaaa9757e1e0848/rootfs/'
|
||||||
|
@ -68,6 +68,7 @@ RUN DEBIAN_FRONTEND=noninteractive eatmydata \
|
|||||||
ENV QEMU_CONFIGURE_OPTS --disable-system --disable-docs --disable-tools
|
ENV QEMU_CONFIGURE_OPTS --disable-system --disable-docs --disable-tools
|
||||||
ENV DEF_TARGET_LIST aarch64-linux-user,arm-linux-user,hppa-linux-user,i386-linux-user,m68k-linux-user,mips-linux-user,mips64-linux-user,mips64el-linux-user,mipsel-linux-user,ppc-linux-user,ppc64-linux-user,ppc64le-linux-user,riscv64-linux-user,s390x-linux-user,sparc64-linux-user
|
ENV DEF_TARGET_LIST aarch64-linux-user,arm-linux-user,hppa-linux-user,i386-linux-user,m68k-linux-user,mips-linux-user,mips64-linux-user,mips64el-linux-user,mipsel-linux-user,ppc-linux-user,ppc64-linux-user,ppc64le-linux-user,riscv64-linux-user,s390x-linux-user,sparc64-linux-user
|
||||||
# As a final step configure the user (if env is defined)
|
# As a final step configure the user (if env is defined)
|
||||||
|
ENV MAKE /usr/bin/make
|
||||||
ARG USER
|
ARG USER
|
||||||
ARG UID
|
ARG UID
|
||||||
RUN if [ "${USER}" ]; then \
|
RUN if [ "${USER}" ]; then \
|
||||||
|
@ -45,6 +45,7 @@ ENV CCACHE_WRAPPERSDIR "/usr/libexec/ccache-wrappers"
|
|||||||
|
|
||||||
RUN curl -#SL "$TOOLCHAIN_URL" | tar -xJC "$TOOLCHAIN_INSTALL"
|
RUN curl -#SL "$TOOLCHAIN_URL" | tar -xJC "$TOOLCHAIN_INSTALL"
|
||||||
ENV PATH $PATH:${TOOLCHAIN_INSTALL}/${TOOLCHAIN_BASENAME}/x86_64-linux-gnu/bin
|
ENV PATH $PATH:${TOOLCHAIN_INSTALL}/${TOOLCHAIN_BASENAME}/x86_64-linux-gnu/bin
|
||||||
|
ENV MAKE /usr/bin/make
|
||||||
# As a final step configure the user (if env is defined)
|
# As a final step configure the user (if env is defined)
|
||||||
ARG USER
|
ARG USER
|
||||||
ARG UID
|
ARG UID
|
||||||
|
@ -42,6 +42,7 @@ RUN /usr/bin/pip3 install tomli
|
|||||||
|
|
||||||
ENV QEMU_CONFIGURE_OPTS --disable-system --disable-docs --disable-tools
|
ENV QEMU_CONFIGURE_OPTS --disable-system --disable-docs --disable-tools
|
||||||
ENV DEF_TARGET_LIST alpha-linux-user,sh4-linux-user
|
ENV DEF_TARGET_LIST alpha-linux-user,sh4-linux-user
|
||||||
|
ENV MAKE /usr/bin/make
|
||||||
# As a final step configure the user (if env is defined)
|
# As a final step configure the user (if env is defined)
|
||||||
ARG USER
|
ARG USER
|
||||||
ARG UID
|
ARG UID
|
||||||
|
@ -44,6 +44,7 @@ ENV LD_LIBRARY_PATH /opt/cross-tools/lib:/opt/cross-tools/loongarch64-unknown-li
|
|||||||
|
|
||||||
ENV QEMU_CONFIGURE_OPTS --disable-system --disable-docs --disable-tools
|
ENV QEMU_CONFIGURE_OPTS --disable-system --disable-docs --disable-tools
|
||||||
ENV DEF_TARGET_LIST loongarch64-linux-user,loongarch-softmmu
|
ENV DEF_TARGET_LIST loongarch64-linux-user,loongarch-softmmu
|
||||||
|
ENV MAKE /usr/bin/make
|
||||||
|
|
||||||
# As a final step configure the user (if env is defined)
|
# As a final step configure the user (if env is defined)
|
||||||
ARG USER
|
ARG USER
|
||||||
|
@ -44,6 +44,7 @@ RUN curl -#SL https://github.com/bkoppelmann/package_940/releases/download/trico
|
|||||||
# This image can only build a very minimal QEMU as well as the tests
|
# This image can only build a very minimal QEMU as well as the tests
|
||||||
ENV DEF_TARGET_LIST tricore-softmmu
|
ENV DEF_TARGET_LIST tricore-softmmu
|
||||||
ENV QEMU_CONFIGURE_OPTS --disable-user --disable-tools --disable-fdt
|
ENV QEMU_CONFIGURE_OPTS --disable-user --disable-tools --disable-fdt
|
||||||
|
ENV MAKE /usr/bin/make
|
||||||
# As a final step configure the user (if env is defined)
|
# As a final step configure the user (if env is defined)
|
||||||
ARG USER
|
ARG USER
|
||||||
ARG UID
|
ARG UID
|
||||||
|
@ -27,6 +27,7 @@ RUN for cpu in $CPU_LIST; do \
|
|||||||
done
|
done
|
||||||
|
|
||||||
ENV PATH $PATH:/opt/$TOOLCHAIN_RELEASE/xtensa-dc232b-elf/bin:/opt/$TOOLCHAIN_RELEASE/xtensa-dc233c-elf/bin:/opt/$TOOLCHAIN_RELEASE/xtensa-de233_fpu-elf/bin:/opt/$TOOLCHAIN_RELEASE/xtensa-dsp3400-elf/bin
|
ENV PATH $PATH:/opt/$TOOLCHAIN_RELEASE/xtensa-dc232b-elf/bin:/opt/$TOOLCHAIN_RELEASE/xtensa-dc233c-elf/bin:/opt/$TOOLCHAIN_RELEASE/xtensa-de233_fpu-elf/bin:/opt/$TOOLCHAIN_RELEASE/xtensa-dsp3400-elf/bin
|
||||||
|
ENV MAKE /usr/bin/make
|
||||||
# As a final step configure the user (if env is defined)
|
# As a final step configure the user (if env is defined)
|
||||||
ARG USER
|
ARG USER
|
||||||
ARG UID
|
ARG UID
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
FROM registry.fedoraproject.org/fedora:33
|
FROM registry.fedoraproject.org/fedora:33
|
||||||
ENV PACKAGES gcc-cris-linux-gnu
|
ENV PACKAGES gcc-cris-linux-gnu
|
||||||
|
ENV MAKE /usr/bin/make
|
||||||
RUN dnf install -y $PACKAGES
|
RUN dnf install -y $PACKAGES
|
||||||
RUN rpm -q $PACKAGES | sort > /packages.txt
|
RUN rpm -q $PACKAGES | sort > /packages.txt
|
||||||
# As a final step configure the user (if env is defined)
|
# As a final step configure the user (if env is defined)
|
||||||
|
168
tests/qemu-iotests/tests/nbd-tls-iothread
Executable file
168
tests/qemu-iotests/tests/nbd-tls-iothread
Executable file
@ -0,0 +1,168 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# group: rw quick
|
||||||
|
#
|
||||||
|
# Test of NBD+TLS+iothread
|
||||||
|
#
|
||||||
|
# Copyright (C) 2024 Red Hat, Inc.
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation; either version 2 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
#
|
||||||
|
|
||||||
|
# creator
|
||||||
|
owner=eblake@redhat.com
|
||||||
|
|
||||||
|
seq=`basename $0`
|
||||||
|
echo "QA output created by $seq"
|
||||||
|
|
||||||
|
status=1 # failure is the default!
|
||||||
|
|
||||||
|
_cleanup()
|
||||||
|
{
|
||||||
|
_cleanup_qemu
|
||||||
|
_cleanup_test_img
|
||||||
|
rm -f "$dst_image"
|
||||||
|
tls_x509_cleanup
|
||||||
|
}
|
||||||
|
trap "_cleanup; exit \$status" 0 1 2 3 15
|
||||||
|
|
||||||
|
# get standard environment, filters and checks
|
||||||
|
cd ..
|
||||||
|
. ./common.rc
|
||||||
|
. ./common.filter
|
||||||
|
. ./common.qemu
|
||||||
|
. ./common.tls
|
||||||
|
. ./common.nbd
|
||||||
|
|
||||||
|
_supported_fmt qcow2 # Hardcoded to qcow2 command line and QMP below
|
||||||
|
_supported_proto file
|
||||||
|
|
||||||
|
# pick_unused_port
|
||||||
|
#
|
||||||
|
# Picks and returns an "unused" port, setting the global variable
|
||||||
|
# $port.
|
||||||
|
#
|
||||||
|
# This is inherently racy, but we need it because qemu does not currently
|
||||||
|
# permit NBD+TLS over a Unix domain socket
|
||||||
|
pick_unused_port ()
|
||||||
|
{
|
||||||
|
if ! (ss --version) >/dev/null 2>&1; then
|
||||||
|
_notrun "ss utility required, skipped this test"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Start at a random port to make it less likely that two parallel
|
||||||
|
# tests will conflict.
|
||||||
|
port=$(( 50000 + (RANDOM%15000) ))
|
||||||
|
while ss -ltn | grep -sqE ":$port\b"; do
|
||||||
|
((port++))
|
||||||
|
if [ $port -eq 65000 ]; then port=50000; fi
|
||||||
|
done
|
||||||
|
echo picked unused port
|
||||||
|
}
|
||||||
|
|
||||||
|
tls_x509_init
|
||||||
|
|
||||||
|
size=1G
|
||||||
|
DST_IMG="$TEST_DIR/dst.qcow2"
|
||||||
|
|
||||||
|
echo
|
||||||
|
echo "== preparing TLS creds and spare port =="
|
||||||
|
|
||||||
|
pick_unused_port
|
||||||
|
tls_x509_create_root_ca "ca1"
|
||||||
|
tls_x509_create_server "ca1" "server1"
|
||||||
|
tls_x509_create_client "ca1" "client1"
|
||||||
|
tls_obj_base=tls-creds-x509,id=tls0,verify-peer=true,dir="${tls_dir}"
|
||||||
|
|
||||||
|
echo
|
||||||
|
echo "== preparing image =="
|
||||||
|
|
||||||
|
_make_test_img $size
|
||||||
|
$QEMU_IMG create -f qcow2 "$DST_IMG" $size | _filter_img_create
|
||||||
|
|
||||||
|
echo
|
||||||
|
echo === Starting Src QEMU ===
|
||||||
|
echo
|
||||||
|
|
||||||
|
_launch_qemu -machine q35 \
|
||||||
|
-object iothread,id=iothread0 \
|
||||||
|
-object "${tls_obj_base}"/client1,endpoint=client \
|
||||||
|
-device '{"driver":"pcie-root-port", "id":"root0", "multifunction":true,
|
||||||
|
"bus":"pcie.0"}' \
|
||||||
|
-device '{"driver":"virtio-scsi-pci", "id":"virtio_scsi_pci0",
|
||||||
|
"bus":"root0", "iothread":"iothread0"}' \
|
||||||
|
-device '{"driver":"scsi-hd", "id":"image1", "drive":"drive_image1",
|
||||||
|
"bus":"virtio_scsi_pci0.0"}' \
|
||||||
|
-blockdev '{"driver":"file", "cache":{"direct":true, "no-flush":false},
|
||||||
|
"filename":"'"$TEST_IMG"'", "node-name":"drive_sys1"}' \
|
||||||
|
-blockdev '{"driver":"qcow2", "node-name":"drive_image1",
|
||||||
|
"file":"drive_sys1"}'
|
||||||
|
h1=$QEMU_HANDLE
|
||||||
|
_send_qemu_cmd $h1 '{"execute": "qmp_capabilities"}' 'return'
|
||||||
|
|
||||||
|
echo
|
||||||
|
echo === Starting Dst VM2 ===
|
||||||
|
echo
|
||||||
|
|
||||||
|
_launch_qemu -machine q35 \
|
||||||
|
-object iothread,id=iothread0 \
|
||||||
|
-object "${tls_obj_base}"/server1,endpoint=server \
|
||||||
|
-device '{"driver":"pcie-root-port", "id":"root0", "multifunction":true,
|
||||||
|
"bus":"pcie.0"}' \
|
||||||
|
-device '{"driver":"virtio-scsi-pci", "id":"virtio_scsi_pci0",
|
||||||
|
"bus":"root0", "iothread":"iothread0"}' \
|
||||||
|
-device '{"driver":"scsi-hd", "id":"image1", "drive":"drive_image1",
|
||||||
|
"bus":"virtio_scsi_pci0.0"}' \
|
||||||
|
-blockdev '{"driver":"file", "cache":{"direct":true, "no-flush":false},
|
||||||
|
"filename":"'"$DST_IMG"'", "node-name":"drive_sys1"}' \
|
||||||
|
-blockdev '{"driver":"qcow2", "node-name":"drive_image1",
|
||||||
|
"file":"drive_sys1"}' \
|
||||||
|
-incoming defer
|
||||||
|
h2=$QEMU_HANDLE
|
||||||
|
_send_qemu_cmd $h2 '{"execute": "qmp_capabilities"}' 'return'
|
||||||
|
|
||||||
|
echo
|
||||||
|
echo === Dst VM: Enable NBD server for incoming storage migration ===
|
||||||
|
echo
|
||||||
|
|
||||||
|
_send_qemu_cmd $h2 '{"execute": "nbd-server-start", "arguments":
|
||||||
|
{"addr": {"type": "inet", "data": {"host": "127.0.0.1", "port": "'$port'"}},
|
||||||
|
"tls-creds": "tls0"}}' '{"return": {}}' | sed "s/\"$port\"/PORT/g"
|
||||||
|
_send_qemu_cmd $h2 '{"execute": "block-export-add", "arguments":
|
||||||
|
{"node-name": "drive_image1", "type": "nbd", "writable": true,
|
||||||
|
"id": "drive_image1"}}' '{"return": {}}'
|
||||||
|
|
||||||
|
echo
|
||||||
|
echo === Src VM: Mirror to dst NBD for outgoing storage migration ===
|
||||||
|
echo
|
||||||
|
|
||||||
|
_send_qemu_cmd $h1 '{"execute": "blockdev-add", "arguments":
|
||||||
|
{"node-name": "mirror", "driver": "nbd",
|
||||||
|
"server": {"type": "inet", "host": "127.0.0.1", "port": "'$port'"},
|
||||||
|
"export": "drive_image1", "tls-creds": "tls0",
|
||||||
|
"tls-hostname": "127.0.0.1"}}' '{"return": {}}' | sed "s/\"$port\"/PORT/g"
|
||||||
|
_send_qemu_cmd $h1 '{"execute": "blockdev-mirror", "arguments":
|
||||||
|
{"sync": "full", "device": "drive_image1", "target": "mirror",
|
||||||
|
"job-id": "drive_image1_53"}}' '{"return": {}}'
|
||||||
|
_timed_wait_for $h1 '"ready"'
|
||||||
|
|
||||||
|
echo
|
||||||
|
echo === Cleaning up ===
|
||||||
|
echo
|
||||||
|
|
||||||
|
_send_qemu_cmd $h1 '{"execute":"quit"}' ''
|
||||||
|
_send_qemu_cmd $h2 '{"execute":"quit"}' ''
|
||||||
|
|
||||||
|
echo "*** done"
|
||||||
|
rm -f $seq.full
|
||||||
|
status=0
|
54
tests/qemu-iotests/tests/nbd-tls-iothread.out
Normal file
54
tests/qemu-iotests/tests/nbd-tls-iothread.out
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
QA output created by nbd-tls-iothread
|
||||||
|
|
||||||
|
== preparing TLS creds and spare port ==
|
||||||
|
picked unused port
|
||||||
|
Generating a self signed certificate...
|
||||||
|
Generating a signed certificate...
|
||||||
|
Generating a signed certificate...
|
||||||
|
|
||||||
|
== preparing image ==
|
||||||
|
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||||
|
Formatting 'TEST_DIR/dst.IMGFMT', fmt=IMGFMT size=1073741824
|
||||||
|
|
||||||
|
=== Starting Src QEMU ===
|
||||||
|
|
||||||
|
{"execute": "qmp_capabilities"}
|
||||||
|
{"return": {}}
|
||||||
|
|
||||||
|
=== Starting Dst VM2 ===
|
||||||
|
|
||||||
|
{"execute": "qmp_capabilities"}
|
||||||
|
{"return": {}}
|
||||||
|
|
||||||
|
=== Dst VM: Enable NBD server for incoming storage migration ===
|
||||||
|
|
||||||
|
{"execute": "nbd-server-start", "arguments":
|
||||||
|
{"addr": {"type": "inet", "data": {"host": "127.0.0.1", "port": PORT}},
|
||||||
|
"tls-creds": "tls0"}}
|
||||||
|
{"return": {}}
|
||||||
|
{"execute": "block-export-add", "arguments":
|
||||||
|
{"node-name": "drive_image1", "type": "nbd", "writable": true,
|
||||||
|
"id": "drive_image1"}}
|
||||||
|
{"return": {}}
|
||||||
|
|
||||||
|
=== Src VM: Mirror to dst NBD for outgoing storage migration ===
|
||||||
|
|
||||||
|
{"execute": "blockdev-add", "arguments":
|
||||||
|
{"node-name": "mirror", "driver": "nbd",
|
||||||
|
"server": {"type": "inet", "host": "127.0.0.1", "port": PORT},
|
||||||
|
"export": "drive_image1", "tls-creds": "tls0",
|
||||||
|
"tls-hostname": "127.0.0.1"}}
|
||||||
|
{"return": {}}
|
||||||
|
{"execute": "blockdev-mirror", "arguments":
|
||||||
|
{"sync": "full", "device": "drive_image1", "target": "mirror",
|
||||||
|
"job-id": "drive_image1_53"}}
|
||||||
|
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "drive_image1_53"}}
|
||||||
|
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "drive_image1_53"}}
|
||||||
|
{"return": {}}
|
||||||
|
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "ready", "id": "drive_image1_53"}}
|
||||||
|
|
||||||
|
=== Cleaning up ===
|
||||||
|
|
||||||
|
{"execute":"quit"}
|
||||||
|
{"execute":"quit"}
|
||||||
|
*** done
|
@ -17,3 +17,9 @@ TESTS += test-macl
|
|||||||
|
|
||||||
test-macw: CFLAGS += -O -g
|
test-macw: CFLAGS += -O -g
|
||||||
TESTS += test-macw
|
TESTS += test-macw
|
||||||
|
|
||||||
|
test-addv: CFLAGS += -O -g
|
||||||
|
TESTS += test-addv
|
||||||
|
|
||||||
|
test-subv: CFLAGS += -O -g
|
||||||
|
TESTS += test-subv
|
||||||
|
27
tests/tcg/sh4/test-addv.c
Normal file
27
tests/tcg/sh4/test-addv.c
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||||
|
|
||||||
|
#include <limits.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
static void addv(const int a, const int b, const int res, const int carry)
|
||||||
|
{
|
||||||
|
int o = a, c;
|
||||||
|
|
||||||
|
asm volatile("addv %2,%0\n"
|
||||||
|
"movt %1\n"
|
||||||
|
: "+r"(o), "=r"(c) : "r"(b) : );
|
||||||
|
|
||||||
|
if (c != carry || o != res) {
|
||||||
|
printf("ADDV %d, %d = %d/%d [T = %d/%d]\n", a, b, o, res, c, carry);
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
addv(INT_MAX, 1, INT_MIN, 1);
|
||||||
|
addv(INT_MAX - 1, 1, INT_MAX, 0);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
30
tests/tcg/sh4/test-subv.c
Normal file
30
tests/tcg/sh4/test-subv.c
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||||
|
|
||||||
|
#include <limits.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
static void subv(const int a, const int b, const int res, const int carry)
|
||||||
|
{
|
||||||
|
int o = a, c;
|
||||||
|
|
||||||
|
asm volatile("subv %2,%0\n"
|
||||||
|
"movt %1\n"
|
||||||
|
: "+r"(o), "=r"(c) : "r"(b) : );
|
||||||
|
|
||||||
|
if (c != carry || o != res) {
|
||||||
|
printf("SUBV %d, %d = %d/%d [T = %d/%d]\n", a, b, o, res, c, carry);
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
subv(INT_MIN, 1, INT_MAX, 1);
|
||||||
|
subv(INT_MAX, -1, INT_MIN, 1);
|
||||||
|
subv(INT_MAX, 1, INT_MAX - 1, 0);
|
||||||
|
subv(0, 1, -1, 0);
|
||||||
|
subv(-1, -1, 0, 0);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
@ -99,7 +99,7 @@ void gd_egl_draw(VirtualConsole *vc)
|
|||||||
#ifdef CONFIG_GBM
|
#ifdef CONFIG_GBM
|
||||||
if (dmabuf) {
|
if (dmabuf) {
|
||||||
egl_dmabuf_create_fence(dmabuf);
|
egl_dmabuf_create_fence(dmabuf);
|
||||||
if (dmabuf->fence_fd > 0) {
|
if (dmabuf->fence_fd >= 0) {
|
||||||
qemu_set_fd_handler(dmabuf->fence_fd, gd_hw_gl_flushed, NULL, vc);
|
qemu_set_fd_handler(dmabuf->fence_fd, gd_hw_gl_flushed, NULL, vc);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -86,7 +86,7 @@ void gd_gl_area_draw(VirtualConsole *vc)
|
|||||||
#ifdef CONFIG_GBM
|
#ifdef CONFIG_GBM
|
||||||
if (dmabuf) {
|
if (dmabuf) {
|
||||||
egl_dmabuf_create_fence(dmabuf);
|
egl_dmabuf_create_fence(dmabuf);
|
||||||
if (dmabuf->fence_fd > 0) {
|
if (dmabuf->fence_fd >= 0) {
|
||||||
qemu_set_fd_handler(dmabuf->fence_fd, gd_hw_gl_flushed, NULL, vc);
|
qemu_set_fd_handler(dmabuf->fence_fd, gd_hw_gl_flushed, NULL, vc);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
20
ui/gtk.c
20
ui/gtk.c
@ -597,11 +597,13 @@ void gd_hw_gl_flushed(void *vcon)
|
|||||||
VirtualConsole *vc = vcon;
|
VirtualConsole *vc = vcon;
|
||||||
QemuDmaBuf *dmabuf = vc->gfx.guest_fb.dmabuf;
|
QemuDmaBuf *dmabuf = vc->gfx.guest_fb.dmabuf;
|
||||||
|
|
||||||
|
if (dmabuf->fence_fd >= 0) {
|
||||||
qemu_set_fd_handler(dmabuf->fence_fd, NULL, NULL, NULL);
|
qemu_set_fd_handler(dmabuf->fence_fd, NULL, NULL, NULL);
|
||||||
close(dmabuf->fence_fd);
|
close(dmabuf->fence_fd);
|
||||||
dmabuf->fence_fd = -1;
|
dmabuf->fence_fd = -1;
|
||||||
graphic_hw_gl_block(vc->gfx.dcl.con, false);
|
graphic_hw_gl_block(vc->gfx.dcl.con, false);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/** DisplayState Callbacks (opengl version) **/
|
/** DisplayState Callbacks (opengl version) **/
|
||||||
|
|
||||||
@ -887,7 +889,7 @@ static gboolean gd_motion_event(GtkWidget *widget, GdkEventMotion *motion,
|
|||||||
int x, y;
|
int x, y;
|
||||||
int mx, my;
|
int mx, my;
|
||||||
int fbh, fbw;
|
int fbh, fbw;
|
||||||
int ww, wh, ws;
|
int ww, wh;
|
||||||
|
|
||||||
if (!vc->gfx.ds) {
|
if (!vc->gfx.ds) {
|
||||||
return TRUE;
|
return TRUE;
|
||||||
@ -895,11 +897,15 @@ static gboolean gd_motion_event(GtkWidget *widget, GdkEventMotion *motion,
|
|||||||
|
|
||||||
fbw = surface_width(vc->gfx.ds) * vc->gfx.scale_x;
|
fbw = surface_width(vc->gfx.ds) * vc->gfx.scale_x;
|
||||||
fbh = surface_height(vc->gfx.ds) * vc->gfx.scale_y;
|
fbh = surface_height(vc->gfx.ds) * vc->gfx.scale_y;
|
||||||
|
|
||||||
ww = gtk_widget_get_allocated_width(widget);
|
ww = gtk_widget_get_allocated_width(widget);
|
||||||
wh = gtk_widget_get_allocated_height(widget);
|
wh = gtk_widget_get_allocated_height(widget);
|
||||||
ws = gtk_widget_get_scale_factor(widget);
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* `widget` may not have the same size with the frame buffer.
|
||||||
|
* In such cases, some paddings are needed around the `vc`.
|
||||||
|
* To achieve that, `vc` will be displayed at (mx, my)
|
||||||
|
* so that it is displayed at the center of the widget.
|
||||||
|
*/
|
||||||
mx = my = 0;
|
mx = my = 0;
|
||||||
if (ww > fbw) {
|
if (ww > fbw) {
|
||||||
mx = (ww - fbw) / 2;
|
mx = (ww - fbw) / 2;
|
||||||
@ -908,8 +914,12 @@ static gboolean gd_motion_event(GtkWidget *widget, GdkEventMotion *motion,
|
|||||||
my = (wh - fbh) / 2;
|
my = (wh - fbh) / 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
x = (motion->x - mx) / vc->gfx.scale_x * ws;
|
/*
|
||||||
y = (motion->y - my) / vc->gfx.scale_y * ws;
|
* `motion` is reported in `widget` coordinates
|
||||||
|
* so translating it to the coordinates in `vc`.
|
||||||
|
*/
|
||||||
|
x = (motion->x - mx) / vc->gfx.scale_x;
|
||||||
|
y = (motion->y - my) / vc->gfx.scale_y;
|
||||||
|
|
||||||
if (qemu_input_is_absolute(vc->gfx.dcl.con)) {
|
if (qemu_input_is_absolute(vc->gfx.dcl.con)) {
|
||||||
if (x < 0 || y < 0 ||
|
if (x < 0 || y < 0 ||
|
||||||
|
@ -874,6 +874,7 @@ static void sdl2_display_init(DisplayState *ds, DisplayOptions *o)
|
|||||||
SDL_SetHint(SDL_HINT_ALLOW_ALT_TAB_WHILE_GRABBED, "0");
|
SDL_SetHint(SDL_HINT_ALLOW_ALT_TAB_WHILE_GRABBED, "0");
|
||||||
#endif
|
#endif
|
||||||
SDL_SetHint(SDL_HINT_WINDOWS_NO_CLOSE_ON_ALT_F4, "1");
|
SDL_SetHint(SDL_HINT_WINDOWS_NO_CLOSE_ON_ALT_F4, "1");
|
||||||
|
SDL_EnableScreenSaver();
|
||||||
memset(&info, 0, sizeof(info));
|
memset(&info, 0, sizeof(info));
|
||||||
SDL_VERSION(&info.version);
|
SDL_VERSION(&info.version);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user