diff options
64 files changed, 760 insertions, 1173 deletions
diff --git a/Makefile.target b/Makefile.target index 4d56298bbf..44ec4b630c 100644 --- a/Makefile.target +++ b/Makefile.target @@ -158,9 +158,6 @@ GENERATED_FILES += hmp-commands.h hmp-commands-info.h endif # CONFIG_SOFTMMU -# Workaround for http://gcc.gnu.org/PR55489, see configure. -%/translate.o: QEMU_CFLAGS += $(TRANSLATE_OPT_CFLAGS) - dummy := $(call unnest-vars,,obj-y) all-obj-y := $(obj-y) diff --git a/audio/alsaaudio.c b/audio/alsaaudio.c index 362a2276fd..635be73bf4 100644 --- a/audio/alsaaudio.c +++ b/audio/alsaaudio.c @@ -28,9 +28,7 @@ #include "audio.h" #include "trace.h" -#if QEMU_GNUC_PREREQ(4, 3) #pragma GCC diagnostic ignored "-Waddress" -#endif #define AUDIO_CAP "alsa" #include "audio_int.h" diff --git a/block/crypto.c b/block/crypto.c index 33ee01bebd..f0a5f6b987 100644 --- a/block/crypto.c +++ b/block/crypto.c @@ -229,6 +229,7 @@ static int block_crypto_open_generic(QCryptoBlockFormat format, block_crypto_read_func, bs, cflags, + 1, errp); if (!crypto->block) { diff --git a/block/qcow.c b/block/qcow.c index 4518cb4c35..0a235bf393 100644 --- a/block/qcow.c +++ b/block/qcow.c @@ -213,7 +213,7 @@ static int qcow_open(BlockDriverState *bs, QDict *options, int flags, cflags |= QCRYPTO_BLOCK_OPEN_NO_IO; } s->crypto = qcrypto_block_open(crypto_opts, "encrypt.", - NULL, NULL, cflags, errp); + NULL, NULL, cflags, 1, errp); if (!s->crypto) { ret = -EINVAL; goto fail; diff --git a/block/qcow2.c b/block/qcow2.c index 991d6ac91b..bc8868c36a 100644 --- a/block/qcow2.c +++ b/block/qcow2.c @@ -294,7 +294,7 @@ static int qcow2_read_extensions(BlockDriverState *bs, uint64_t start_offset, } s->crypto = qcrypto_block_open(s->crypto_opts, "encrypt.", qcow2_crypto_hdr_read_func, - bs, cflags, errp); + bs, cflags, 1, errp); if (!s->crypto) { return -EINVAL; } @@ -1445,7 +1445,7 @@ static int coroutine_fn qcow2_do_open(BlockDriverState *bs, QDict *options, cflags |= QCRYPTO_BLOCK_OPEN_NO_IO; } s->crypto = qcrypto_block_open(s->crypto_opts, "encrypt.", - NULL, NULL, cflags, errp); + NULL, NULL, cflags, 1, errp); if (!s->crypto) { ret = -EINVAL; goto fail; @@ -1840,6 +1840,31 @@ if test "$bogus_os" = "yes"; then error_exit "Unrecognized host OS (uname -s reports '$(uname -s)')" fi +# Check whether the compiler matches our minimum requirements: +cat > $TMPC << EOF +#if defined(__clang_major__) && defined(__clang_minor__) +# ifdef __apple_build_version__ +# if __clang_major__ < 5 || (__clang_major__ == 5 && __clang_minor__ < 1) +# error You need at least XCode Clang v5.1 to compile QEMU +# endif +# else +# if __clang_major__ < 3 || (__clang_major__ == 3 && __clang_minor__ < 4) +# error You need at least Clang v3.4 to compile QEMU +# endif +# endif +#elif defined(__GNUC__) && defined(__GNUC_MINOR__) +# if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 8) +# error You need at least GCC v4.8 to compile QEMU +# endif +#else +# error You either need GCC or Clang to compiler QEMU +#endif +int main (void) { return 0; } +EOF +if ! compile_prog "" "" ; then + error_exit "You need at least GCC v4.8 or Clang v3.4 (or XCode Clang v5.1)" +fi + gcc_flags="-Wold-style-declaration -Wold-style-definition -Wtype-limits" gcc_flags="-Wformat-security -Wformat-y2k -Winit-self -Wignored-qualifiers $gcc_flags" gcc_flags="-Wno-missing-include-dirs -Wempty-body -Wnested-externs $gcc_flags" @@ -1911,21 +1936,7 @@ else QEMU_CFLAGS="$QEMU_CFLAGS -Wno-missing-braces" fi -# Workaround for http://gcc.gnu.org/PR55489. Happens with -fPIE/-fPIC and -# large functions that use global variables. The bug is in all releases of -# GCC, but it became particularly acute in 4.6.x and 4.7.x. It is fixed in -# 4.7.3 and 4.8.0. We should be able to delete this at the end of 2013. -cat > $TMPC << EOF -#if __GNUC__ == 4 && (__GNUC_MINOR__ == 6 || (__GNUC_MINOR__ == 7 && __GNUC_PATCHLEVEL__ <= 2)) -int main(void) { return 0; } -#else -#error No bug in this compiler. -#endif -EOF -if compile_prog "-Werror -fno-gcse" "" ; then - TRANSLATE_OPT_CFLAGS=-fno-gcse -fi - +# Static linking is not possible with modules or PIE if test "$static" = "yes" ; then if test "$modules" = "yes" ; then error_exit "static and modules are mutually incompatible" @@ -5123,11 +5134,6 @@ fi int128=no cat > $TMPC << EOF -#if defined(__clang_major__) && defined(__clang_minor__) -# if ((__clang_major__ < 3) || (__clang_major__ == 3) && (__clang_minor__ < 2)) -# error __int128_t does not work in CLANG before 3.2 -# endif -#endif __int128_t a; __uint128_t b; int main (void) { @@ -6963,7 +6969,6 @@ echo "LIBS_QGA+=$libs_qga" >> $config_host_mak echo "TASN1_LIBS=$tasn1_libs" >> $config_host_mak echo "TASN1_CFLAGS=$tasn1_cflags" >> $config_host_mak echo "POD2MAN=$POD2MAN" >> $config_host_mak -echo "TRANSLATE_OPT_CFLAGS=$TRANSLATE_OPT_CFLAGS" >> $config_host_mak if test "$gcov" = "yes" ; then echo "CONFIG_GCOV=y" >> $config_host_mak echo "GCOV=$gcov_tool" >> $config_host_mak diff --git a/crypto/block-luks.c b/crypto/block-luks.c index 5738124773..6bac79c3ab 100644 --- a/crypto/block-luks.c +++ b/crypto/block-luks.c @@ -504,14 +504,14 @@ qcrypto_block_luks_load_key(QCryptoBlock *block, * to reset the encryption cipher every time the master * key crosses a sector boundary. */ - if (qcrypto_block_decrypt_helper(cipher, - niv, - ivgen, - QCRYPTO_BLOCK_LUKS_SECTOR_SIZE, - 0, - splitkey, - splitkeylen, - errp) < 0) { + if (qcrypto_block_cipher_decrypt_helper(cipher, + niv, + ivgen, + QCRYPTO_BLOCK_LUKS_SECTOR_SIZE, + 0, + splitkey, + splitkeylen, + errp) < 0) { goto cleanup; } @@ -636,6 +636,7 @@ qcrypto_block_luks_open(QCryptoBlock *block, QCryptoBlockReadFunc readfunc, void *opaque, unsigned int flags, + size_t n_threads, Error **errp) { QCryptoBlockLUKS *luks; @@ -836,11 +837,10 @@ qcrypto_block_luks_open(QCryptoBlock *block, goto fail; } - block->cipher = qcrypto_cipher_new(cipheralg, - ciphermode, - masterkey, masterkeylen, - errp); - if (!block->cipher) { + ret = qcrypto_block_init_cipher(block, cipheralg, ciphermode, + masterkey, masterkeylen, n_threads, + errp); + if (ret < 0) { ret = -ENOTSUP; goto fail; } @@ -863,7 +863,7 @@ qcrypto_block_luks_open(QCryptoBlock *block, fail: g_free(masterkey); - qcrypto_cipher_free(block->cipher); + qcrypto_block_free_cipher(block); qcrypto_ivgen_free(block->ivgen); g_free(luks); g_free(password); @@ -1030,11 +1030,9 @@ qcrypto_block_luks_create(QCryptoBlock *block, /* Setup the block device payload encryption objects */ - block->cipher = qcrypto_cipher_new(luks_opts.cipher_alg, - luks_opts.cipher_mode, - masterkey, luks->header.key_bytes, - errp); - if (!block->cipher) { + if (qcrypto_block_init_cipher(block, luks_opts.cipher_alg, + luks_opts.cipher_mode, masterkey, + luks->header.key_bytes, 1, errp) < 0) { goto error; } @@ -1219,12 +1217,12 @@ qcrypto_block_luks_create(QCryptoBlock *block, /* Now we encrypt the split master key with the key generated * from the user's password, before storing it */ - if (qcrypto_block_encrypt_helper(cipher, block->niv, ivgen, - QCRYPTO_BLOCK_LUKS_SECTOR_SIZE, - 0, - splitkey, - splitkeylen, - errp) < 0) { + if (qcrypto_block_cipher_encrypt_helper(cipher, block->niv, ivgen, + QCRYPTO_BLOCK_LUKS_SECTOR_SIZE, + 0, + splitkey, + splitkeylen, + errp) < 0) { goto error; } @@ -1341,6 +1339,9 @@ qcrypto_block_luks_create(QCryptoBlock *block, qcrypto_ivgen_free(ivgen); qcrypto_cipher_free(cipher); + qcrypto_block_free_cipher(block); + qcrypto_ivgen_free(block->ivgen); + g_free(luks); return -1; } @@ -1406,8 +1407,7 @@ qcrypto_block_luks_decrypt(QCryptoBlock *block, { assert(QEMU_IS_ALIGNED(offset, QCRYPTO_BLOCK_LUKS_SECTOR_SIZE)); assert(QEMU_IS_ALIGNED(len, QCRYPTO_BLOCK_LUKS_SECTOR_SIZE)); - return qcrypto_block_decrypt_helper(block->cipher, - block->niv, block->ivgen, + return qcrypto_block_decrypt_helper(block, QCRYPTO_BLOCK_LUKS_SECTOR_SIZE, offset, buf, len, errp); } @@ -1422,8 +1422,7 @@ qcrypto_block_luks_encrypt(QCryptoBlock *block, { assert(QEMU_IS_ALIGNED(offset, QCRYPTO_BLOCK_LUKS_SECTOR_SIZE)); assert(QEMU_IS_ALIGNED(len, QCRYPTO_BLOCK_LUKS_SECTOR_SIZE)); - return qcrypto_block_encrypt_helper(block->cipher, - block->niv, block->ivgen, + return qcrypto_block_encrypt_helper(block, QCRYPTO_BLOCK_LUKS_SECTOR_SIZE, offset, buf, len, errp); } diff --git a/crypto/block-qcow.c b/crypto/block-qcow.c index 7606231e79..cefb3b2a7b 100644 --- a/crypto/block-qcow.c +++ b/crypto/block-qcow.c @@ -44,6 +44,7 @@ qcrypto_block_qcow_has_format(const uint8_t *buf G_GNUC_UNUSED, static int qcrypto_block_qcow_init(QCryptoBlock *block, const char *keysecret, + size_t n_threads, Error **errp) { char *password; @@ -71,11 +72,11 @@ qcrypto_block_qcow_init(QCryptoBlock *block, goto fail; } - block->cipher = qcrypto_cipher_new(QCRYPTO_CIPHER_ALG_AES_128, - QCRYPTO_CIPHER_MODE_CBC, - keybuf, G_N_ELEMENTS(keybuf), - errp); - if (!block->cipher) { + ret = qcrypto_block_init_cipher(block, QCRYPTO_CIPHER_ALG_AES_128, + QCRYPTO_CIPHER_MODE_CBC, + keybuf, G_N_ELEMENTS(keybuf), + n_threads, errp); + if (ret < 0) { ret = -ENOTSUP; goto fail; } @@ -86,7 +87,7 @@ qcrypto_block_qcow_init(QCryptoBlock *block, return 0; fail: - qcrypto_cipher_free(block->cipher); + qcrypto_block_free_cipher(block); qcrypto_ivgen_free(block->ivgen); return ret; } @@ -99,6 +100,7 @@ qcrypto_block_qcow_open(QCryptoBlock *block, QCryptoBlockReadFunc readfunc G_GNUC_UNUSED, void *opaque G_GNUC_UNUSED, unsigned int flags, + size_t n_threads, Error **errp) { if (flags & QCRYPTO_BLOCK_OPEN_NO_IO) { @@ -112,8 +114,8 @@ qcrypto_block_qcow_open(QCryptoBlock *block, optprefix ? optprefix : ""); return -1; } - return qcrypto_block_qcow_init(block, - options->u.qcow.key_secret, errp); + return qcrypto_block_qcow_init(block, options->u.qcow.key_secret, + n_threads, errp); } } @@ -133,7 +135,7 @@ qcrypto_block_qcow_create(QCryptoBlock *block, return -1; } /* QCow2 has no special header, since everything is hardwired */ - return qcrypto_block_qcow_init(block, options->u.qcow.key_secret, errp); + return qcrypto_block_qcow_init(block, options->u.qcow.key_secret, 1, errp); } @@ -152,8 +154,7 @@ qcrypto_block_qcow_decrypt(QCryptoBlock *block, { assert(QEMU_IS_ALIGNED(offset, QCRYPTO_BLOCK_QCOW_SECTOR_SIZE)); assert(QEMU_IS_ALIGNED(len, QCRYPTO_BLOCK_QCOW_SECTOR_SIZE)); - return qcrypto_block_decrypt_helper(block->cipher, - block->niv, block->ivgen, + return qcrypto_block_decrypt_helper(block, QCRYPTO_BLOCK_QCOW_SECTOR_SIZE, offset, buf, len, errp); } @@ -168,8 +169,7 @@ qcrypto_block_qcow_encrypt(QCryptoBlock *block, { assert(QEMU_IS_ALIGNED(offset, QCRYPTO_BLOCK_QCOW_SECTOR_SIZE)); assert(QEMU_IS_ALIGNED(len, QCRYPTO_BLOCK_QCOW_SECTOR_SIZE)); - return qcrypto_block_encrypt_helper(block->cipher, - block->niv, block->ivgen, + return qcrypto_block_encrypt_helper(block, QCRYPTO_BLOCK_QCOW_SECTOR_SIZE, offset, buf, len, errp); } diff --git a/crypto/block.c b/crypto/block.c index e59d1140fe..d70d401f87 100644 --- a/crypto/block.c +++ b/crypto/block.c @@ -52,6 +52,7 @@ QCryptoBlock *qcrypto_block_open(QCryptoBlockOpenOptions *options, QCryptoBlockReadFunc readfunc, void *opaque, unsigned int flags, + size_t n_threads, Error **errp) { QCryptoBlock *block = g_new0(QCryptoBlock, 1); @@ -69,11 +70,14 @@ QCryptoBlock *qcrypto_block_open(QCryptoBlockOpenOptions *options, block->driver = qcrypto_block_drivers[options->format]; if (block->driver->open(block, options, optprefix, - readfunc, opaque, flags, errp) < 0) { + readfunc, opaque, flags, n_threads, errp) < 0) + { g_free(block); return NULL; } + qemu_mutex_init(&block->mutex); + return block; } @@ -105,6 +109,8 @@ QCryptoBlock *qcrypto_block_create(QCryptoBlockCreateOptions *options, return NULL; } + qemu_mutex_init(&block->mutex); + return block; } @@ -148,12 +154,97 @@ int qcrypto_block_encrypt(QCryptoBlock *block, QCryptoCipher *qcrypto_block_get_cipher(QCryptoBlock *block) { - return block->cipher; + /* Ciphers should be accessed through pop/push method to be thread-safe. + * Better, they should not be accessed externally at all (note, that + * pop/push are static functions) + * This function is used only in test with one thread (it's safe to skip + * pop/push interface), so it's enough to assert it here: + */ + assert(block->n_ciphers <= 1); + return block->ciphers ? block->ciphers[0] : NULL; +} + + +static QCryptoCipher *qcrypto_block_pop_cipher(QCryptoBlock *block) +{ + QCryptoCipher *cipher; + + qemu_mutex_lock(&block->mutex); + + assert(block->n_free_ciphers > 0); + block->n_free_ciphers--; + cipher = block->ciphers[block->n_free_ciphers]; + + qemu_mutex_unlock(&block->mutex); + + return cipher; +} + + +static void qcrypto_block_push_cipher(QCryptoBlock *block, + QCryptoCipher *cipher) +{ + qemu_mutex_lock(&block->mutex); + + assert(block->n_free_ciphers < block->n_ciphers); + block->ciphers[block->n_free_ciphers] = cipher; + block->n_free_ciphers++; + + qemu_mutex_unlock(&block->mutex); } +int qcrypto_block_init_cipher(QCryptoBlock *block, + QCryptoCipherAlgorithm alg, + QCryptoCipherMode mode, + const uint8_t *key, size_t nkey, + size_t n_threads, Error **errp) +{ + size_t i; + + assert(!block->ciphers && !block->n_ciphers && !block->n_free_ciphers); + + block->ciphers = g_new0(QCryptoCipher *, n_threads); + + for (i = 0; i < n_threads; i++) { + block->ciphers[i] = qcrypto_cipher_new(alg, mode, key, nkey, errp); + if (!block->ciphers[i]) { + qcrypto_block_free_cipher(block); + return -1; + } + block->n_ciphers++; + block->n_free_ciphers++; + } + + return 0; +} + + +void qcrypto_block_free_cipher(QCryptoBlock *block) +{ + size_t i; + + if (!block->ciphers) { + return; + } + + assert(block->n_ciphers == block->n_free_ciphers); + + for (i = 0; i < block->n_ciphers; i++) { + qcrypto_cipher_free(block->ciphers[i]); + } + + g_free(block->ciphers); + block->ciphers = NULL; + block->n_ciphers = block->n_free_ciphers = 0; +} + QCryptoIVGen *qcrypto_block_get_ivgen(QCryptoBlock *block) { + /* ivgen should be accessed under mutex. However, this function is used only + * in test with one thread, so it's enough to assert it here: + */ + assert(block->n_ciphers <= 1); return block->ivgen; } @@ -184,20 +275,29 @@ void qcrypto_block_free(QCryptoBlock *block) block->driver->cleanup(block); - qcrypto_cipher_free(block->cipher); + qcrypto_block_free_cipher(block); qcrypto_ivgen_free(block->ivgen); + qemu_mutex_destroy(&block->mutex); g_free(block); } -int qcrypto_block_decrypt_helper(QCryptoCipher *cipher, - size_t niv, - QCryptoIVGen *ivgen, - int sectorsize, - uint64_t offset, - uint8_t *buf, - size_t len, - Error **errp) +typedef int (*QCryptoCipherEncDecFunc)(QCryptoCipher *cipher, + const void *in, + void *out, + size_t len, + Error **errp); + +static int do_qcrypto_block_cipher_encdec(QCryptoCipher *cipher, + size_t niv, + QCryptoIVGen *ivgen, + QemuMutex *ivgen_mutex, + int sectorsize, + uint64_t offset, + uint8_t *buf, + size_t len, + QCryptoCipherEncDecFunc func, + Error **errp) { uint8_t *iv; int ret = -1; @@ -211,10 +311,15 @@ int qcrypto_block_decrypt_helper(QCryptoCipher *cipher, while (len > 0) { size_t nbytes; if (niv) { - if (qcrypto_ivgen_calculate(ivgen, - startsector, - iv, niv, - errp) < 0) { + if (ivgen_mutex) { + qemu_mutex_lock(ivgen_mutex); + } + ret = qcrypto_ivgen_calculate(ivgen, startsector, iv, niv, errp); + if (ivgen_mutex) { + qemu_mutex_unlock(ivgen_mutex); + } + + if (ret < 0) { goto cleanup; } @@ -226,8 +331,7 @@ int qcrypto_block_decrypt_helper(QCryptoCipher *cipher, } nbytes = len > sectorsize ? sectorsize : len; - if (qcrypto_cipher_decrypt(cipher, buf, buf, - nbytes, errp) < 0) { + if (func(cipher, buf, buf, nbytes, errp) < 0) { goto cleanup; } @@ -243,54 +347,69 @@ int qcrypto_block_decrypt_helper(QCryptoCipher *cipher, } -int qcrypto_block_encrypt_helper(QCryptoCipher *cipher, - size_t niv, - QCryptoIVGen *ivgen, +int qcrypto_block_cipher_decrypt_helper(QCryptoCipher *cipher, + size_t niv, + QCryptoIVGen *ivgen, + int sectorsize, + uint64_t offset, + uint8_t *buf, + size_t len, + Error **errp) +{ + return do_qcrypto_block_cipher_encdec(cipher, niv, ivgen, NULL, sectorsize, + offset, buf, len, + qcrypto_cipher_decrypt, errp); +} + + +int qcrypto_block_cipher_encrypt_helper(QCryptoCipher *cipher, + size_t niv, + QCryptoIVGen *ivgen, + int sectorsize, + uint64_t offset, + uint8_t *buf, + size_t len, + Error **errp) +{ + return do_qcrypto_block_cipher_encdec(cipher, niv, ivgen, NULL, sectorsize, + offset, buf, len, + qcrypto_cipher_encrypt, errp); +} + +int qcrypto_block_decrypt_helper(QCryptoBlock *block, int sectorsize, uint64_t offset, uint8_t *buf, size_t len, Error **errp) { - uint8_t *iv; - int ret = -1; - uint64_t startsector = offset / sectorsize; + int ret; + QCryptoCipher *cipher = qcrypto_block_pop_cipher(block); - assert(QEMU_IS_ALIGNED(offset, sectorsize)); - assert(QEMU_IS_ALIGNED(len, sectorsize)); + ret = do_qcrypto_block_cipher_encdec(cipher, block->niv, block->ivgen, + &block->mutex, sectorsize, offset, buf, + len, qcrypto_cipher_decrypt, errp); - iv = niv ? g_new0(uint8_t, niv) : NULL; + qcrypto_block_push_cipher(block, cipher); - while (len > 0) { - size_t nbytes; - if (niv) { - if (qcrypto_ivgen_calculate(ivgen, - startsector, - iv, niv, - errp) < 0) { - goto cleanup; - } + return ret; +} - if (qcrypto_cipher_setiv(cipher, - iv, niv, - errp) < 0) { - goto cleanup; - } - } +int qcrypto_block_encrypt_helper(QCryptoBlock *block, + int sectorsize, + uint64_t offset, + uint8_t *buf, + size_t len, + Error **errp) +{ + int ret; + QCryptoCipher *cipher = qcrypto_block_pop_cipher(block); - nbytes = len > sectorsize ? sectorsize : len; - if (qcrypto_cipher_encrypt(cipher, buf, buf, - nbytes, errp) < 0) { - goto cleanup; - } + ret = do_qcrypto_block_cipher_encdec(cipher, block->niv, block->ivgen, + &block->mutex, sectorsize, offset, buf, + len, qcrypto_cipher_encrypt, errp); - startsector++; - buf += nbytes; - len -= nbytes; - } + qcrypto_block_push_cipher(block, cipher); - ret = 0; - cleanup: - g_free(iv); return ret; } diff --git a/crypto/blockpriv.h b/crypto/blockpriv.h index 41840abcec..5438e822fd 100644 --- a/crypto/blockpriv.h +++ b/crypto/blockpriv.h @@ -22,6 +22,7 @@ #define QCRYPTO_BLOCKPRIV_H #include "crypto/block.h" +#include "qemu/thread.h" typedef struct QCryptoBlockDriver QCryptoBlockDriver; @@ -31,8 +32,12 @@ struct QCryptoBlock { const QCryptoBlockDriver *driver; void *opaque; - QCryptoCipher *cipher; + QCryptoCipher **ciphers; + size_t n_ciphers; + size_t n_free_ciphers; QCryptoIVGen *ivgen; + QemuMutex mutex; + QCryptoHashAlgorithm kdfhash; size_t niv; uint64_t payload_offset; /* In bytes */ @@ -46,6 +51,7 @@ struct QCryptoBlockDriver { QCryptoBlockReadFunc readfunc, void *opaque, unsigned int flags, + size_t n_threads, Error **errp); int (*create)(QCryptoBlock *block, @@ -78,22 +84,44 @@ struct QCryptoBlockDriver { }; -int qcrypto_block_decrypt_helper(QCryptoCipher *cipher, - size_t niv, - QCryptoIVGen *ivgen, +int qcrypto_block_cipher_decrypt_helper(QCryptoCipher *cipher, + size_t niv, + QCryptoIVGen *ivgen, + int sectorsize, + uint64_t offset, + uint8_t *buf, + size_t len, + Error **errp); + +int qcrypto_block_cipher_encrypt_helper(QCryptoCipher *cipher, + size_t niv, + QCryptoIVGen *ivgen, + int sectorsize, + uint64_t offset, + uint8_t *buf, + size_t len, + Error **errp); + +int qcrypto_block_decrypt_helper(QCryptoBlock *block, int sectorsize, uint64_t offset, uint8_t *buf, size_t len, Error **errp); -int qcrypto_block_encrypt_helper(QCryptoCipher *cipher, - size_t niv, - QCryptoIVGen *ivgen, +int qcrypto_block_encrypt_helper(QCryptoBlock *block, int sectorsize, uint64_t offset, uint8_t *buf, size_t len, Error **errp); +int qcrypto_block_init_cipher(QCryptoBlock *block, + QCryptoCipherAlgorithm alg, + QCryptoCipherMode mode, + const uint8_t *key, size_t nkey, + size_t n_threads, Error **errp); + +void qcrypto_block_free_cipher(QCryptoBlock *block); + #endif /* QCRYPTO_BLOCKPRIV_H */ diff --git a/fsdev/qemu-fsdev.c b/fsdev/qemu-fsdev.c index 7a3b87cc9e..4536fd977d 100644 --- a/fsdev/qemu-fsdev.c +++ b/fsdev/qemu-fsdev.c @@ -23,9 +23,6 @@ static QTAILQ_HEAD(FsDriverEntry_head, FsDriverListEntry) fsdriver_entries = static FsDriverTable FsDrivers[] = { { .name = "local", .ops = &local_ops}, -#ifdef CONFIG_OPEN_BY_HANDLE - { .name = "handle", .ops = &handle_ops}, -#endif { .name = "synth", .ops = &synth_ops}, { .name = "proxy", .ops = &proxy_ops}, }; diff --git a/hw/9pfs/9p-handle.c b/hw/9pfs/9p-handle.c deleted file mode 100644 index 3465b1ef30..0000000000 --- a/hw/9pfs/9p-handle.c +++ /dev/null @@ -1,710 +0,0 @@ -/* - * 9p handle callback - * - * Copyright IBM, Corp. 2011 - * - * Authors: - * Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com> - * - * This work is licensed under the terms of the GNU GPL, version 2. See - * the COPYING file in the top-level directory. - * - */ - -#include "qemu/osdep.h" -#include "9p.h" -#include "9p-xattr.h" -#include <arpa/inet.h> -#include <pwd.h> -#include <grp.h> -#include <sys/socket.h> -#include <sys/un.h> -#include "qapi/error.h" -#include "qemu/xattr.h" -#include "qemu/cutils.h" -#include "qemu/error-report.h" -#include "qemu/option.h" -#include <linux/fs.h> -#ifdef CONFIG_LINUX_MAGIC_H -#include <linux/magic.h> -#endif -#include <sys/ioctl.h> - -#ifndef XFS_SUPER_MAGIC -#define XFS_SUPER_MAGIC 0x58465342 -#endif -#ifndef EXT2_SUPER_MAGIC -#define EXT2_SUPER_MAGIC 0xEF53 -#endif -#ifndef REISERFS_SUPER_MAGIC -#define REISERFS_SUPER_MAGIC 0x52654973 -#endif -#ifndef BTRFS_SUPER_MAGIC -#define BTRFS_SUPER_MAGIC 0x9123683E -#endif - -typedef struct HandleData { - int mountfd; - int handle_bytes; -} HandleData; - -static inline int name_to_handle(int dirfd, const char *name, - struct file_handle *fh, int *mnt_id, int flags) -{ - return name_to_handle_at(dirfd, name, fh, mnt_id, flags); -} - -static inline int open_by_handle(int mountfd, const char *fh, int flags) -{ - return open_by_handle_at(mountfd, (struct file_handle *)fh, flags); -} - -static int handle_update_file_cred(int dirfd, const char *name, FsCred *credp) -{ - int fd, ret; - fd = openat(dirfd, name, O_NONBLOCK | O_NOFOLLOW); - if (fd < 0) { - return fd; - } - ret = fchownat(fd, "", credp->fc_uid, credp->fc_gid, AT_EMPTY_PATH); - if (ret < 0) { - goto err_out; - } - ret = fchmod(fd, credp->fc_mode & 07777); -err_out: - close(fd); - return ret; -} - - -static int handle_lstat(FsContext *fs_ctx, V9fsPath *fs_path, - struct stat *stbuf) -{ - int fd, ret; - HandleData *data = (HandleData *) fs_ctx->private; - - fd = open_by_handle(data->mountfd, fs_path->data, O_PATH); - if (fd < 0) { - return fd; - } - ret = fstatat(fd, "", stbuf, AT_EMPTY_PATH); - close(fd); - return ret; -} - -static ssize_t handle_readlink(FsContext *fs_ctx, V9fsPath *fs_path, - char *buf, size_t bufsz) -{ - int fd, ret; - HandleData *data = (HandleData *) fs_ctx->private; - - fd = open_by_handle(data->mountfd, fs_path->data, O_PATH); - if (fd < 0) { - return fd; - } - ret = readlinkat(fd, "", buf, bufsz); - close(fd); - return ret; -} - -static int handle_close(FsContext *ctx, V9fsFidOpenState *fs) -{ - return close(fs->fd); -} - -static int handle_closedir(FsContext *ctx, V9fsFidOpenState *fs) -{ - return closedir(fs->dir.stream); -} - -static int handle_open(FsContext *ctx, V9fsPath *fs_path, - int flags, V9fsFidOpenState *fs) -{ - HandleData *data = (HandleData *) ctx->private; - - fs->fd = open_by_handle(data->mountfd, fs_path->data, flags); - return fs->fd; -} - -static int handle_opendir(FsContext *ctx, - V9fsPath *fs_path, V9fsFidOpenState *fs) -{ - int ret; - ret = handle_open(ctx, fs_path, O_DIRECTORY, fs); - if (ret < 0) { - return -1; - } - fs->dir.stream = fdopendir(ret); - if (!fs->dir.stream) { - return -1; - } - return 0; -} - -static void handle_rewinddir(FsContext *ctx, V9fsFidOpenState *fs) -{ - rewinddir(fs->dir.stream); -} - -static off_t handle_telldir(FsContext *ctx, V9fsFidOpenState *fs) -{ - return telldir(fs->dir.stream); -} - -static struct dirent *handle_readdir(FsContext *ctx, V9fsFidOpenState *fs) -{ - return readdir(fs->dir.stream); -} - -static void handle_seekdir(FsContext *ctx, V9fsFidOpenState *fs, off_t off) -{ - seekdir(fs->dir.stream, off); -} - -static ssize_t handle_preadv(FsContext *ctx, V9fsFidOpenState *fs, - const struct iovec *iov, - int iovcnt, off_t offset) -{ -#ifdef CONFIG_PREADV - return preadv(fs->fd, iov, iovcnt, offset); -#else - int err = lseek(fs->fd, offset, SEEK_SET); - if (err == -1) { - return err; - } else { - return readv(fs->fd, iov, iovcnt); - } -#endif -} - -static ssize_t handle_pwritev(FsContext *ctx, V9fsFidOpenState *fs, - const struct iovec *iov, - int iovcnt, off_t offset) -{ - ssize_t ret; -#ifdef CONFIG_PREADV - ret = pwritev(fs->fd, iov, iovcnt, offset); -#else - int err = lseek(fs->fd, offset, SEEK_SET); - if (err == -1) { - return err; - } else { - ret = writev(fs->fd, iov, iovcnt); - } -#endif -#ifdef CONFIG_SYNC_FILE_RANGE - if (ret > 0 && ctx->export_flags & V9FS_IMMEDIATE_WRITEOUT) { - /* - * Initiate a writeback. This is not a data integrity sync. - * We want to ensure that we don't leave dirty pages in the cache - * after write when writeout=immediate is sepcified. - */ - sync_file_range(fs->fd, offset, ret, - SYNC_FILE_RANGE_WAIT_BEFORE | SYNC_FILE_RANGE_WRITE); - } -#endif - return ret; -} - -static int handle_chmod(FsContext *fs_ctx, V9fsPath *fs_path, FsCred *credp) -{ - int fd, ret; - HandleData *data = (HandleData *) fs_ctx->private; - - fd = open_by_handle(data->mountfd, fs_path->data, O_NONBLOCK); - if (fd < 0) { - return fd; - } - ret = fchmod(fd, credp->fc_mode); - close(fd); - return ret; -} - -static int handle_mknod(FsContext *fs_ctx, V9fsPath *dir_path, - const char *name, FsCred *credp) -{ - int dirfd, ret; - HandleData *data = (HandleData *) fs_ctx->private; - - dirfd = open_by_handle(data->mountfd, dir_path->data, O_PATH); - if (dirfd < 0) { - return dirfd; - } - ret = mknodat(dirfd, name, credp->fc_mode, credp->fc_rdev); - if (!ret) { - ret = handle_update_file_cred(dirfd, name, credp); - } - close(dirfd); - return ret; -} - -static int handle_mkdir(FsContext *fs_ctx, V9fsPath *dir_path, - const char *name, FsCred *credp) -{ - int dirfd, ret; - HandleData *data = (HandleData *) fs_ctx->private; - - dirfd = open_by_handle(data->mountfd, dir_path->data, O_PATH); - if (dirfd < 0) { - return dirfd; - } - ret = mkdirat(dirfd, name, credp->fc_mode); - if (!ret) { - ret = handle_update_file_cred(dirfd, name, credp); - } - close(dirfd); - return ret; -} - -static int handle_fstat(FsContext *fs_ctx, int fid_type, - V9fsFidOpenState *fs, struct stat *stbuf) -{ - int fd; - - if (fid_type == P9_FID_DIR) { - fd = dirfd(fs->dir.stream); - } else { - fd = fs->fd; - } - return fstat(fd, stbuf); -} - -static int handle_open2(FsContext *fs_ctx, V9fsPath *dir_path, const char *name, - int flags, FsCred *credp, V9fsFidOpenState *fs) -{ - int ret; - int dirfd, fd; - HandleData *data = (HandleData *) fs_ctx->private; - - dirfd = open_by_handle(data->mountfd, dir_path->data, O_PATH); - if (dirfd < 0) { - return dirfd; - } - fd = openat(dirfd, name, flags | O_NOFOLLOW, credp->fc_mode); - if (fd >= 0) { - ret = handle_update_file_cred(dirfd, name, credp); - if (ret < 0) { - close(fd); - fd = ret; - } else { - fs->fd = fd; - } - } - close(dirfd); - return fd; -} - - -static int handle_symlink(FsContext *fs_ctx, const char *oldpath, - V9fsPath *dir_path, const char *name, FsCred *credp) -{ - int fd, dirfd, ret; - HandleData *data = (HandleData *) fs_ctx->private; - - dirfd = open_by_handle(data->mountfd, dir_path->data, O_PATH); - if (dirfd < 0) { - return dirfd; - } - ret = symlinkat(oldpath, dirfd, name); - if (!ret) { - fd = openat(dirfd, name, O_PATH | O_NOFOLLOW); - if (fd < 0) { - ret = fd; - goto err_out; - } - ret = fchownat(fd, "", credp->fc_uid, credp->fc_gid, AT_EMPTY_PATH); - close(fd); - } -err_out: - close(dirfd); - return ret; -} - -static int handle_link(FsContext *ctx, V9fsPath *oldpath, - V9fsPath *dirpath, const char *name) -{ - int oldfd, newdirfd, ret; - HandleData *data = (HandleData *) ctx->private; - - oldfd = open_by_handle(data->mountfd, oldpath->data, O_PATH); - if (oldfd < 0) { - return oldfd; - } - newdirfd = open_by_handle(data->mountfd, dirpath->data, O_PATH); - if (newdirfd < 0) { - close(oldfd); - return newdirfd; - } - ret = linkat(oldfd, "", newdirfd, name, AT_EMPTY_PATH); - close(newdirfd); - close(oldfd); - return ret; -} - -static int handle_truncate(FsContext *ctx, V9fsPath *fs_path, off_t size) -{ - int fd, ret; - HandleData *data = (HandleData *) ctx->private; - - fd = open_by_handle(data->mountfd, fs_path->data, O_NONBLOCK | O_WRONLY); - if (fd < 0) { - return fd; - } - ret = ftruncate(fd, size); - close(fd); - return ret; -} - -static int handle_rename(FsContext *ctx, const char *oldpath, - const char *newpath) -{ - errno = EOPNOTSUPP; - return -1; -} - -static int handle_chown(FsContext *fs_ctx, V9fsPath *fs_path, FsCred *credp) -{ - int fd, ret; - HandleData *data = (HandleData *) fs_ctx->private; - - fd = open_by_handle(data->mountfd, fs_path->data, O_PATH); - if (fd < 0) { - return fd; - } - ret = fchownat(fd, "", credp->fc_uid, credp->fc_gid, AT_EMPTY_PATH); - close(fd); - return ret; -} - -static int handle_utimensat(FsContext *ctx, V9fsPath *fs_path, - const struct timespec *buf) -{ - int ret; - int fd; - HandleData *data = (HandleData *) ctx->private; - - fd = open_by_handle(data->mountfd, fs_path->data, O_NONBLOCK); - if (fd < 0) { - return fd; - } - ret = futimens(fd, buf); - close(fd); - return ret; -} - -static int handle_remove(FsContext *ctx, const char *path) -{ - errno = EOPNOTSUPP; - return -1; -} - -static int handle_fsync(FsContext *ctx, int fid_type, - V9fsFidOpenState *fs, int datasync) -{ - int fd; - - if (fid_type == P9_FID_DIR) { - fd = dirfd(fs->dir.stream); - } else { - fd = fs->fd; - } - - if (datasync) { - return qemu_fdatasync(fd); - } else { - return fsync(fd); - } -} - -static int handle_statfs(FsContext *ctx, V9fsPath *fs_path, - struct statfs *stbuf) -{ - int fd, ret; - HandleData *data = (HandleData *) ctx->private; - - fd = open_by_handle(data->mountfd, fs_path->data, O_NONBLOCK); - if (fd < 0) { - return fd; - } - ret = fstatfs(fd, stbuf); - close(fd); - return ret; -} - -static ssize_t handle_lgetxattr(FsContext *ctx, V9fsPath *fs_path, - const char *name, void *value, size_t size) -{ - int fd, ret; - HandleData *data = (HandleData *) ctx->private; - - fd = open_by_handle(data->mountfd, fs_path->data, O_NONBLOCK); - if (fd < 0) { - return fd; - } - ret = fgetxattr(fd, name, value, size); - close(fd); - return ret; -} - -static ssize_t handle_llistxattr(FsContext *ctx, V9fsPath *fs_path, - void *value, size_t size) -{ - int fd, ret; - HandleData *data = (HandleData *) ctx->private; - - fd = open_by_handle(data->mountfd, fs_path->data, O_NONBLOCK); - if (fd < 0) { - return fd; - } - ret = flistxattr(fd, value, size); - close(fd); - return ret; -} - -static int handle_lsetxattr(FsContext *ctx, V9fsPath *fs_path, const char *name, - void *value, size_t size, int flags) -{ - int fd, ret; - HandleData *data = (HandleData *) ctx->private; - - fd = open_by_handle(data->mountfd, fs_path->data, O_NONBLOCK); - if (fd < 0) { - return fd; - } - ret = fsetxattr(fd, name, value, size, flags); - close(fd); - return ret; -} - -static int handle_lremovexattr(FsContext *ctx, V9fsPath *fs_path, - const char *name) -{ - int fd, ret; - HandleData *data = (HandleData *) ctx->private; - - fd = open_by_handle(data->mountfd, fs_path->data, O_NONBLOCK); - if (fd < 0) { - return fd; - } - ret = fremovexattr(fd, name); - close(fd); - return ret; -} - -static int handle_name_to_path(FsContext *ctx, V9fsPath *dir_path, - const char *name, V9fsPath *target) -{ - char *buffer; - struct file_handle *fh; - int dirfd, ret, mnt_id; - HandleData *data = (HandleData *) ctx->private; - - /* "." and ".." are not allowed */ - if (!strcmp(name, ".") || !strcmp(name, "..")) { - errno = EINVAL; - return -1; - - } - if (dir_path) { - dirfd = open_by_handle(data->mountfd, dir_path->data, O_PATH); - } else { - /* relative to export root */ - buffer = rpath(ctx, "."); - dirfd = open(buffer, O_DIRECTORY); - g_free(buffer); - } - if (dirfd < 0) { - return dirfd; - } - fh = g_malloc(sizeof(struct file_handle) + data->handle_bytes); - fh->handle_bytes = data->handle_bytes; - /* add a "./" at the beginning of the path */ - buffer = g_strdup_printf("./%s", name); - /* flag = 0 imply don't follow symlink */ - ret = name_to_handle(dirfd, buffer, fh, &mnt_id, 0); - if (!ret) { - target->data = (char *)fh; - target->size = sizeof(struct file_handle) + data->handle_bytes; - } else { - g_free(fh); - } - close(dirfd); - g_free(buffer); - return ret; -} - -static int handle_renameat(FsContext *ctx, V9fsPath *olddir, - const char *old_name, V9fsPath *newdir, - const char *new_name) -{ - int olddirfd, newdirfd, ret; - HandleData *data = (HandleData *) ctx->private; - - olddirfd = open_by_handle(data->mountfd, olddir->data, O_PATH); - if (olddirfd < 0) { - return olddirfd; - } - newdirfd = open_by_handle(data->mountfd, newdir->data, O_PATH); - if (newdirfd < 0) { - close(olddirfd); - return newdirfd; - } - ret = renameat(olddirfd, old_name, newdirfd, new_name); - close(newdirfd); - close(olddirfd); - return ret; -} - -static int handle_unlinkat(FsContext *ctx, V9fsPath *dir, - const char *name, int flags) -{ - int dirfd, ret; - HandleData *data = (HandleData *) ctx->private; - - dirfd = open_by_handle(data->mountfd, dir->data, O_PATH); - if (dirfd < 0) { - return dirfd; - } - - ret = unlinkat(dirfd, name, flags); - - close(dirfd); - return ret; -} - -static int handle_ioc_getversion(FsContext *ctx, V9fsPath *path, - mode_t st_mode, uint64_t *st_gen) -{ -#ifdef FS_IOC_GETVERSION - int err; - V9fsFidOpenState fid_open; - - /* - * Do not try to open special files like device nodes, fifos etc - * We can get fd for regular files and directories only - */ - if (!S_ISREG(st_mode) && !S_ISDIR(st_mode)) { - errno = ENOTTY; - return -1; - } - err = handle_open(ctx, path, O_RDONLY, &fid_open); - if (err < 0) { - return err; - } - err = ioctl(fid_open.fd, FS_IOC_GETVERSION, st_gen); - handle_close(ctx, &fid_open); - return err; -#else - errno = ENOTTY; - return -1; -#endif -} - -static int handle_init(FsContext *ctx, Error **errp) -{ - int ret, mnt_id; - struct statfs stbuf; - struct file_handle fh; - HandleData *data = g_malloc(sizeof(HandleData)); - - data->mountfd = open(ctx->fs_root, O_DIRECTORY); - if (data->mountfd < 0) { - ret = data->mountfd; - goto err_out; - } - ret = statfs(ctx->fs_root, &stbuf); - if (!ret) { - switch (stbuf.f_type) { - case EXT2_SUPER_MAGIC: - case BTRFS_SUPER_MAGIC: - case REISERFS_SUPER_MAGIC: - case XFS_SUPER_MAGIC: - ctx->exops.get_st_gen = handle_ioc_getversion; - break; - } - } - memset(&fh, 0, sizeof(struct file_handle)); - ret = name_to_handle(data->mountfd, ".", &fh, &mnt_id, 0); - if (ret && errno == EOVERFLOW) { - data->handle_bytes = fh.handle_bytes; - ctx->private = data; - ret = 0; - goto out; - } - /* we got 0 byte handle ? */ - ret = -1; - close(data->mountfd); -err_out: - g_free(data); -out: - return ret; -} - -static void handle_cleanup(FsContext *ctx) -{ - HandleData *data = ctx->private; - - close(data->mountfd); - g_free(data); -} - -static int handle_parse_opts(QemuOpts *opts, FsDriverEntry *fse, Error **errp) -{ - const char *sec_model = qemu_opt_get(opts, "security_model"); - const char *path = qemu_opt_get(opts, "path"); - - warn_report("handle backend is deprecated"); - - if (sec_model) { - error_setg(errp, - "Invalid argument security_model specified with handle fsdriver"); - return -1; - } - - if (!path) { - error_setg(errp, "fsdev: No path specified"); - return -1; - } - fse->path = g_strdup(path); - return 0; - -} - -FileOperations handle_ops = { - .parse_opts = handle_parse_opts, - .init = handle_init, - .cleanup = handle_cleanup, - .lstat = handle_lstat, - .readlink = handle_readlink, - .close = handle_close, - .closedir = handle_closedir, - .open = handle_open, - .opendir = handle_opendir, - .rewinddir = handle_rewinddir, - .telldir = handle_telldir, - .readdir = handle_readdir, - .seekdir = handle_seekdir, - .preadv = handle_preadv, - .pwritev = handle_pwritev, - .chmod = handle_chmod, - .mknod = handle_mknod, - .mkdir = handle_mkdir, - .fstat = handle_fstat, - .open2 = handle_open2, - .symlink = handle_symlink, - .link = handle_link, - .truncate = handle_truncate, - .rename = handle_rename, - .chown = handle_chown, - .utimensat = handle_utimensat, - .remove = handle_remove, - .fsync = handle_fsync, - .statfs = handle_statfs, - .lgetxattr = handle_lgetxattr, - .llistxattr = handle_llistxattr, - .lsetxattr = handle_lsetxattr, - .lremovexattr = handle_lremovexattr, - .name_to_path = handle_name_to_path, - .renameat = handle_renameat, - .unlinkat = handle_unlinkat, -}; diff --git a/hw/9pfs/9p.c b/hw/9pfs/9p.c index bdf7919abf..55821343e5 100644 --- a/hw/9pfs/9p.c +++ b/hw/9pfs/9p.c @@ -1331,8 +1331,8 @@ static void coroutine_fn v9fs_walk(void *opaque) trace_v9fs_walk(pdu->tag, pdu->id, fid, newfid, nwnames); if (nwnames && nwnames <= P9_MAXWELEM) { - wnames = g_malloc0(sizeof(wnames[0]) * nwnames); - qids = g_malloc0(sizeof(qids[0]) * nwnames); + wnames = g_new0(V9fsString, nwnames); + qids = g_new0(V9fsQID, nwnames); for (i = 0; i < nwnames; i++) { err = pdu_unmarshal(pdu, offset, "s", &wnames[i]); if (err < 0) { diff --git a/hw/9pfs/Makefile.objs b/hw/9pfs/Makefile.objs index e3fa673665..8ac04962bd 100644 --- a/hw/9pfs/Makefile.objs +++ b/hw/9pfs/Makefile.objs @@ -4,7 +4,6 @@ common-obj-y += 9p-local.o 9p-xattr.o common-obj-y += 9p-xattr-user.o 9p-posix-acl.o common-obj-y += coth.o cofs.o codir.o cofile.o common-obj-y += coxattr.o 9p-synth.o -common-obj-$(CONFIG_OPEN_BY_HANDLE) += 9p-handle.o common-obj-y += 9p-proxy.o endif diff --git a/hw/9pfs/xen-9p-backend.c b/hw/9pfs/xen-9p-backend.c index 3f54a21c76..9015fe7773 100644 --- a/hw/9pfs/xen-9p-backend.c +++ b/hw/9pfs/xen-9p-backend.c @@ -178,7 +178,7 @@ static void xen_9pfs_init_out_iov_from_pdu(V9fsPDU *pdu, g_free(ring->sg); - ring->sg = g_malloc0(sizeof(*ring->sg) * 2); + ring->sg = g_new0(struct iovec, 2); xen_9pfs_out_sg(ring, ring->sg, &num, pdu->idx); *piov = ring->sg; *pniov = num; @@ -196,7 +196,7 @@ static void xen_9pfs_init_in_iov_from_pdu(V9fsPDU *pdu, g_free(ring->sg); - ring->sg = g_malloc0(sizeof(*ring->sg) * 2); + ring->sg = g_new0(struct iovec, 2); xen_9pfs_in_sg(ring, ring->sg, &num, pdu->idx, size); buf_size = iov_size(ring->sg, num); @@ -368,7 +368,7 @@ static int xen_9pfs_connect(struct XenDevice *xendev) return -1; } - xen_9pdev->rings = g_malloc0(xen_9pdev->num_rings * sizeof(Xen9pfsRing)); + xen_9pdev->rings = g_new0(Xen9pfsRing, xen_9pdev->num_rings); for (i = 0; i < xen_9pdev->num_rings; i++) { char *str; int ring_order; diff --git a/hw/arm/boot.c b/hw/arm/boot.c index 586baa9b64..94fce12802 100644 --- a/hw/arm/boot.c +++ b/hw/arm/boot.c @@ -63,8 +63,10 @@ typedef enum { FIXUP_TERMINATOR, /* end of insns */ FIXUP_BOARDID, /* overwrite with board ID number */ FIXUP_BOARD_SETUP, /* overwrite with board specific setup code address */ - FIXUP_ARGPTR, /* overwrite with pointer to kernel args */ - FIXUP_ENTRYPOINT, /* overwrite with kernel entry point */ + FIXUP_ARGPTR_LO, /* overwrite with pointer to kernel args */ + FIXUP_ARGPTR_HI, /* overwrite with pointer to kernel args (high half) */ + FIXUP_ENTRYPOINT_LO, /* overwrite with kernel entry point */ + FIXUP_ENTRYPOINT_HI, /* overwrite with kernel entry point (high half) */ FIXUP_GIC_CPU_IF, /* overwrite with GIC CPU interface address */ FIXUP_BOOTREG, /* overwrite with boot register address */ FIXUP_DSB, /* overwrite with correct DSB insn for cpu */ @@ -83,10 +85,10 @@ static const ARMInsnFixup bootloader_aarch64[] = { { 0xaa1f03e3 }, /* mov x3, xzr */ { 0x58000084 }, /* ldr x4, entry ; Load the lower 32-bits of kernel entry */ { 0xd61f0080 }, /* br x4 ; Jump to the kernel entry point */ - { 0, FIXUP_ARGPTR }, /* arg: .word @DTB Lower 32-bits */ - { 0 }, /* .word @DTB Higher 32-bits */ - { 0, FIXUP_ENTRYPOINT }, /* entry: .word @Kernel Entry Lower 32-bits */ - { 0 }, /* .word @Kernel Entry Higher 32-bits */ + { 0, FIXUP_ARGPTR_LO }, /* arg: .word @DTB Lower 32-bits */ + { 0, FIXUP_ARGPTR_HI}, /* .word @DTB Higher 32-bits */ + { 0, FIXUP_ENTRYPOINT_LO }, /* entry: .word @Kernel Entry Lower 32-bits */ + { 0, FIXUP_ENTRYPOINT_HI }, /* .word @Kernel Entry Higher 32-bits */ { 0, FIXUP_TERMINATOR } }; @@ -106,8 +108,8 @@ static const ARMInsnFixup bootloader[] = { { 0xe59f2004 }, /* ldr r2, [pc, #4] */ { 0xe59ff004 }, /* ldr pc, [pc, #4] */ { 0, FIXUP_BOARDID }, - { 0, FIXUP_ARGPTR }, - { 0, FIXUP_ENTRYPOINT }, + { 0, FIXUP_ARGPTR_LO }, + { 0, FIXUP_ENTRYPOINT_LO }, { 0, FIXUP_TERMINATOR } }; @@ -174,8 +176,10 @@ static void write_bootloader(const char *name, hwaddr addr, break; case FIXUP_BOARDID: case FIXUP_BOARD_SETUP: - case FIXUP_ARGPTR: - case FIXUP_ENTRYPOINT: + case FIXUP_ARGPTR_LO: + case FIXUP_ARGPTR_HI: + case FIXUP_ENTRYPOINT_LO: + case FIXUP_ENTRYPOINT_HI: case FIXUP_GIC_CPU_IF: case FIXUP_BOOTREG: case FIXUP_DSB: @@ -1152,9 +1156,13 @@ void arm_load_kernel(ARMCPU *cpu, struct arm_boot_info *info) /* Place the DTB after the initrd in memory with alignment. */ info->dtb_start = QEMU_ALIGN_UP(info->initrd_start + initrd_size, align); - fixupcontext[FIXUP_ARGPTR] = info->dtb_start; + fixupcontext[FIXUP_ARGPTR_LO] = info->dtb_start; + fixupcontext[FIXUP_ARGPTR_HI] = info->dtb_start >> 32; } else { - fixupcontext[FIXUP_ARGPTR] = info->loader_start + KERNEL_ARGS_ADDR; + fixupcontext[FIXUP_ARGPTR_LO] = + info->loader_start + KERNEL_ARGS_ADDR; + fixupcontext[FIXUP_ARGPTR_HI] = + (info->loader_start + KERNEL_ARGS_ADDR) >> 32; if (info->ram_size >= (1ULL << 32)) { error_report("RAM size must be less than 4GB to boot" " Linux kernel using ATAGS (try passing a device tree" @@ -1162,7 +1170,8 @@ void arm_load_kernel(ARMCPU *cpu, struct arm_boot_info *info) exit(1); } } - fixupcontext[FIXUP_ENTRYPOINT] = entry; + fixupcontext[FIXUP_ENTRYPOINT_LO] = entry; + fixupcontext[FIXUP_ENTRYPOINT_HI] = entry >> 32; write_bootloader("bootloader", info->loader_start, primary_loader, fixupcontext, as); diff --git a/hw/arm/musicpal.c b/hw/arm/musicpal.c index 9648b3af44..d22532a11c 100644 --- a/hw/arm/musicpal.c +++ b/hw/arm/musicpal.c @@ -1147,14 +1147,13 @@ static const MemoryRegionOps mv88w8618_wlan_ops = { .endianness = DEVICE_NATIVE_ENDIAN, }; -static int mv88w8618_wlan_init(SysBusDevice *dev) +static void mv88w8618_wlan_realize(DeviceState *dev, Error **errp) { MemoryRegion *iomem = g_new(MemoryRegion, 1); memory_region_init_io(iomem, OBJECT(dev), &mv88w8618_wlan_ops, NULL, "musicpal-wlan", MP_WLAN_SIZE); - sysbus_init_mmio(dev, iomem); - return 0; + sysbus_init_mmio(SYS_BUS_DEVICE(dev), iomem); } /* GPIO register offsets */ @@ -1696,7 +1695,7 @@ static void musicpal_init(MachineState *machine) dev = qdev_create(NULL, TYPE_MV88W8618_AUDIO); s = SYS_BUS_DEVICE(dev); object_property_set_link(OBJECT(dev), OBJECT(wm8750_dev), - TYPE_WM8750, NULL); + "wm8750", NULL); qdev_init_nofail(dev); sysbus_mmio_map(s, 0, MP_AUDIO_BASE); sysbus_connect_irq(s, 0, pic[MP_AUDIO_IRQ]); @@ -1720,9 +1719,9 @@ DEFINE_MACHINE("musicpal", musicpal_machine_init) static void mv88w8618_wlan_class_init(ObjectClass *klass, void *data) { - SysBusDeviceClass *sdc = SYS_BUS_DEVICE_CLASS(klass); + DeviceClass *dc = DEVICE_CLASS(klass); - sdc->init = mv88w8618_wlan_init; + dc->realize = mv88w8618_wlan_realize; } static const TypeInfo mv88w8618_wlan_info = { diff --git a/hw/arm/xlnx-versal-virt.c b/hw/arm/xlnx-versal-virt.c index 1e31a3f442..c6feeac532 100644 --- a/hw/arm/xlnx-versal-virt.c +++ b/hw/arm/xlnx-versal-virt.c @@ -342,7 +342,7 @@ static void *versal_virt_get_dtb(const struct arm_boot_info *binfo, return board->fdt; } -#define NUM_VIRTIO_TRANSPORT 32 +#define NUM_VIRTIO_TRANSPORT 8 static void create_virtio_regions(VersalVirt *s) { int virtio_mmio_size = 0x200; @@ -351,7 +351,7 @@ static void create_virtio_regions(VersalVirt *s) for (i = 0; i < NUM_VIRTIO_TRANSPORT; i++) { char *name = g_strdup_printf("virtio%d", i);; hwaddr base = MM_TOP_RSVD + i * virtio_mmio_size; - int irq = VERSAL_RSVD_HIGH_IRQ_FIRST + i; + int irq = VERSAL_RSVD_IRQ_FIRST + i; MemoryRegion *mr; DeviceState *dev; qemu_irq pic_irq; @@ -364,12 +364,11 @@ static void create_virtio_regions(VersalVirt *s) sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, pic_irq); mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 0); memory_region_add_subregion(&s->soc.mr_ps, base, mr); - sysbus_create_simple("virtio-mmio", base, pic_irq); } for (i = 0; i < NUM_VIRTIO_TRANSPORT; i++) { hwaddr base = MM_TOP_RSVD + i * virtio_mmio_size; - int irq = VERSAL_RSVD_HIGH_IRQ_FIRST + i; + int irq = VERSAL_RSVD_IRQ_FIRST + i; char *name = g_strdup_printf("/virtio_mmio@%" PRIx64, base); qemu_fdt_add_subnode(s->fdt, name); diff --git a/hw/block/onenand.c b/hw/block/onenand.c index 2b48609776..f11118a687 100644 --- a/hw/block/onenand.c +++ b/hw/block/onenand.c @@ -772,9 +772,9 @@ static const MemoryRegionOps onenand_ops = { .endianness = DEVICE_NATIVE_ENDIAN, }; -static int onenand_initfn(SysBusDevice *sbd) +static void onenand_realize(DeviceState *dev, Error **errp) { - DeviceState *dev = DEVICE(sbd); + SysBusDevice *sbd = SYS_BUS_DEVICE(dev); OneNANDState *s = ONE_NAND(dev); uint32_t size = 1 << (24 + ((s->id.dev >> 4) & 7)); void *ram; @@ -794,14 +794,14 @@ static int onenand_initfn(SysBusDevice *sbd) 0xff, size + (size >> 5)); } else { if (blk_is_read_only(s->blk)) { - error_report("Can't use a read-only drive"); - return -1; + error_setg(errp, "Can't use a read-only drive"); + return; } blk_set_perm(s->blk, BLK_PERM_CONSISTENT_READ | BLK_PERM_WRITE, BLK_PERM_ALL, &local_err); if (local_err) { - error_report_err(local_err); - return -1; + error_propagate(errp, local_err); + return; } s->blk_cur = s->blk; } @@ -826,7 +826,6 @@ static int onenand_initfn(SysBusDevice *sbd) | ((s->id.dev & 0xff) << 8) | (s->id.ver & 0xff), &vmstate_onenand, s); - return 0; } static Property onenand_properties[] = { @@ -841,9 +840,8 @@ static Property onenand_properties[] = { static void onenand_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); - SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass); - k->init = onenand_initfn; + dc->realize = onenand_realize; dc->reset = onenand_system_reset; dc->props = onenand_properties; } diff --git a/hw/char/grlib_apbuart.c b/hw/char/grlib_apbuart.c index bac11bec58..e1d258b611 100644 --- a/hw/char/grlib_apbuart.c +++ b/hw/char/grlib_apbuart.c @@ -239,9 +239,10 @@ static const MemoryRegionOps grlib_apbuart_ops = { .endianness = DEVICE_NATIVE_ENDIAN, }; -static int grlib_apbuart_init(SysBusDevice *dev) +static void grlib_apbuart_realize(DeviceState *dev, Error **errp) { UART *uart = GRLIB_APB_UART(dev); + SysBusDevice *sbd = SYS_BUS_DEVICE(dev); qemu_chr_fe_set_handlers(&uart->chr, grlib_apbuart_can_receive, @@ -249,14 +250,12 @@ static int grlib_apbuart_init(SysBusDevice *dev) grlib_apbuart_event, NULL, uart, NULL, true); - sysbus_init_irq(dev, &uart->irq); + sysbus_init_irq(sbd, &uart->irq); memory_region_init_io(&uart->iomem, OBJECT(uart), &grlib_apbuart_ops, uart, "uart", UART_REG_SIZE); - sysbus_init_mmio(dev, &uart->iomem); - - return 0; + sysbus_init_mmio(sbd, &uart->iomem); } static void grlib_apbuart_reset(DeviceState *d) @@ -280,9 +279,8 @@ static Property grlib_apbuart_properties[] = { static void grlib_apbuart_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); - SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass); - k->init = grlib_apbuart_init; + dc->realize = grlib_apbuart_realize; dc->reset = grlib_apbuart_reset; dc->props = grlib_apbuart_properties; } diff --git a/hw/core/empty_slot.c b/hw/core/empty_slot.c index c1b9c2b104..239f78e2a7 100644 --- a/hw/core/empty_slot.c +++ b/hw/core/empty_slot.c @@ -71,21 +71,20 @@ void empty_slot_init(hwaddr addr, uint64_t slot_size) } } -static int empty_slot_init1(SysBusDevice *dev) +static void empty_slot_realize(DeviceState *dev, Error **errp) { EmptySlot *s = EMPTY_SLOT(dev); memory_region_init_io(&s->iomem, OBJECT(s), &empty_slot_ops, s, "empty-slot", s->size); - sysbus_init_mmio(dev, &s->iomem); - return 0; + sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->iomem); } static void empty_slot_class_init(ObjectClass *klass, void *data) { - SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass); + DeviceClass *dc = DEVICE_CLASS(klass); - k->init = empty_slot_init1; + dc->realize = empty_slot_realize; } static const TypeInfo empty_slot_info = { diff --git a/hw/core/sysbus.c b/hw/core/sysbus.c index 7ac36ad3e7..9f9edbcab9 100644 --- a/hw/core/sysbus.c +++ b/hw/core/sysbus.c @@ -201,18 +201,13 @@ void sysbus_init_ioports(SysBusDevice *dev, uint32_t ioport, uint32_t size) } } -/* TODO remove once all sysbus devices have been converted to realize */ +/* The purpose of preserving this empty realize function + * is to prevent the parent_realize field of some subclasses + * from being set to NULL to break the normal init/realize + * of some devices. + */ static void sysbus_realize(DeviceState *dev, Error **errp) { - SysBusDevice *sd = SYS_BUS_DEVICE(dev); - SysBusDeviceClass *sbc = SYS_BUS_DEVICE_GET_CLASS(sd); - - if (!sbc->init) { - return; - } - if (sbc->init(sd) < 0) { - error_setg(errp, "Device initialization failed"); - } } DeviceState *sysbus_create_varargs(const char *name, diff --git a/hw/display/g364fb.c b/hw/display/g364fb.c index 8ad7e5d824..3407adf98d 100644 --- a/hw/display/g364fb.c +++ b/hw/display/g364fb.c @@ -489,18 +489,16 @@ typedef struct { G364State g364; } G364SysBusState; -static int g364fb_sysbus_init(SysBusDevice *sbd) +static void g364fb_sysbus_realize(DeviceState *dev, Error **errp) { - DeviceState *dev = DEVICE(sbd); G364SysBusState *sbs = G364(dev); G364State *s = &sbs->g364; + SysBusDevice *sbd = SYS_BUS_DEVICE(dev); g364fb_init(dev, s); sysbus_init_irq(sbd, &s->irq); sysbus_init_mmio(sbd, &s->mem_ctrl); sysbus_init_mmio(sbd, &s->mem_vram); - - return 0; } static void g364fb_sysbus_reset(DeviceState *d) @@ -518,9 +516,8 @@ static Property g364fb_sysbus_properties[] = { static void g364fb_sysbus_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); - SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass); - k->init = g364fb_sysbus_init; + dc->realize = g364fb_sysbus_realize; set_bit(DEVICE_CATEGORY_DISPLAY, dc->categories); dc->desc = "G364 framebuffer"; dc->reset = g364fb_sysbus_reset; diff --git a/hw/dma/puv3_dma.c b/hw/dma/puv3_dma.c index b97a6c1767..c89eade029 100644 --- a/hw/dma/puv3_dma.c +++ b/hw/dma/puv3_dma.c @@ -76,7 +76,7 @@ static const MemoryRegionOps puv3_dma_ops = { .endianness = DEVICE_NATIVE_ENDIAN, }; -static int puv3_dma_init(SysBusDevice *dev) +static void puv3_dma_realize(DeviceState *dev, Error **errp) { PUV3DMAState *s = PUV3_DMA(dev); int i; @@ -87,16 +87,14 @@ static int puv3_dma_init(SysBusDevice *dev) memory_region_init_io(&s->iomem, OBJECT(s), &puv3_dma_ops, s, "puv3_dma", PUV3_REGS_OFFSET); - sysbus_init_mmio(dev, &s->iomem); - - return 0; + sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->iomem); } static void puv3_dma_class_init(ObjectClass *klass, void *data) { - SysBusDeviceClass *sdc = SYS_BUS_DEVICE_CLASS(klass); + DeviceClass *dc = DEVICE_CLASS(klass); - sdc->init = puv3_dma_init; + dc->realize = puv3_dma_realize; } static const TypeInfo puv3_dma_info = { diff --git a/hw/gpio/puv3_gpio.c b/hw/gpio/puv3_gpio.c index 445afccf9f..33241b8564 100644 --- a/hw/gpio/puv3_gpio.c +++ b/hw/gpio/puv3_gpio.c @@ -99,36 +99,35 @@ static const MemoryRegionOps puv3_gpio_ops = { .endianness = DEVICE_NATIVE_ENDIAN, }; -static int puv3_gpio_init(SysBusDevice *dev) +static void puv3_gpio_realize(DeviceState *dev, Error **errp) { PUV3GPIOState *s = PUV3_GPIO(dev); + SysBusDevice *sbd = SYS_BUS_DEVICE(dev); s->reg_GPLR = 0; s->reg_GPDR = 0; /* FIXME: these irqs not handled yet */ - sysbus_init_irq(dev, &s->irq[PUV3_IRQS_GPIOLOW0]); - sysbus_init_irq(dev, &s->irq[PUV3_IRQS_GPIOLOW1]); - sysbus_init_irq(dev, &s->irq[PUV3_IRQS_GPIOLOW2]); - sysbus_init_irq(dev, &s->irq[PUV3_IRQS_GPIOLOW3]); - sysbus_init_irq(dev, &s->irq[PUV3_IRQS_GPIOLOW4]); - sysbus_init_irq(dev, &s->irq[PUV3_IRQS_GPIOLOW5]); - sysbus_init_irq(dev, &s->irq[PUV3_IRQS_GPIOLOW6]); - sysbus_init_irq(dev, &s->irq[PUV3_IRQS_GPIOLOW7]); - sysbus_init_irq(dev, &s->irq[PUV3_IRQS_GPIOHIGH]); + sysbus_init_irq(sbd, &s->irq[PUV3_IRQS_GPIOLOW0]); + sysbus_init_irq(sbd, &s->irq[PUV3_IRQS_GPIOLOW1]); + sysbus_init_irq(sbd, &s->irq[PUV3_IRQS_GPIOLOW2]); + sysbus_init_irq(sbd, &s->irq[PUV3_IRQS_GPIOLOW3]); + sysbus_init_irq(sbd, &s->irq[PUV3_IRQS_GPIOLOW4]); + sysbus_init_irq(sbd, &s->irq[PUV3_IRQS_GPIOLOW5]); + sysbus_init_irq(sbd, &s->irq[PUV3_IRQS_GPIOLOW6]); + sysbus_init_irq(sbd, &s->irq[PUV3_IRQS_GPIOLOW7]); + sysbus_init_irq(sbd, &s->irq[PUV3_IRQS_GPIOHIGH]); memory_region_init_io(&s->iomem, OBJECT(s), &puv3_gpio_ops, s, "puv3_gpio", PUV3_REGS_OFFSET); - sysbus_init_mmio(dev, &s->iomem); - - return 0; + sysbus_init_mmio(sbd, &s->iomem); } static void puv3_gpio_class_init(ObjectClass *klass, void *data) { - SysBusDeviceClass *sdc = SYS_BUS_DEVICE_CLASS(klass); + DeviceClass *dc = DEVICE_CLASS(klass); - sdc->init = puv3_gpio_init; + dc->realize = puv3_gpio_realize; } static const TypeInfo puv3_gpio_info = { diff --git a/hw/i2c/bitbang_i2c.h b/hw/i2c/bitbang_i2c.h index 3a7126d5de..9443021710 100644 --- a/hw/i2c/bitbang_i2c.h +++ b/hw/i2c/bitbang_i2c.h @@ -3,8 +3,6 @@ #include "hw/i2c/i2c.h" -typedef struct bitbang_i2c_interface bitbang_i2c_interface; - #define BITBANG_I2C_SDA 0 #define BITBANG_I2C_SCL 1 diff --git a/hw/input/milkymist-softusb.c b/hw/input/milkymist-softusb.c index ef8f47cd83..8766a17d9e 100644 --- a/hw/input/milkymist-softusb.c +++ b/hw/input/milkymist-softusb.c @@ -245,32 +245,31 @@ static void milkymist_softusb_reset(DeviceState *d) s->regs[R_CTRL] = CTRL_RESET; } -static int milkymist_softusb_init(SysBusDevice *dev) +static void milkymist_softusb_realize(DeviceState *dev, Error **errp) { MilkymistSoftUsbState *s = MILKYMIST_SOFTUSB(dev); + SysBusDevice *sbd = SYS_BUS_DEVICE(dev); - sysbus_init_irq(dev, &s->irq); + sysbus_init_irq(sbd, &s->irq); memory_region_init_io(&s->regs_region, OBJECT(s), &softusb_mmio_ops, s, "milkymist-softusb", R_MAX * 4); - sysbus_init_mmio(dev, &s->regs_region); + sysbus_init_mmio(sbd, &s->regs_region); /* register pmem and dmem */ memory_region_init_ram_nomigrate(&s->pmem, OBJECT(s), "milkymist-softusb.pmem", s->pmem_size, &error_fatal); vmstate_register_ram_global(&s->pmem); s->pmem_ptr = memory_region_get_ram_ptr(&s->pmem); - sysbus_init_mmio(dev, &s->pmem); + sysbus_init_mmio(sbd, &s->pmem); memory_region_init_ram_nomigrate(&s->dmem, OBJECT(s), "milkymist-softusb.dmem", s->dmem_size, &error_fatal); vmstate_register_ram_global(&s->dmem); s->dmem_ptr = memory_region_get_ram_ptr(&s->dmem); - sysbus_init_mmio(dev, &s->dmem); + sysbus_init_mmio(sbd, &s->dmem); hid_init(&s->hid_kbd, HID_KEYBOARD, softusb_kbd_hid_datain); hid_init(&s->hid_mouse, HID_MOUSE, softusb_mouse_hid_datain); - - return 0; } static const VMStateDescription vmstate_milkymist_softusb = { @@ -296,9 +295,8 @@ static Property milkymist_softusb_properties[] = { static void milkymist_softusb_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); - SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass); - k->init = milkymist_softusb_init; + dc->realize = milkymist_softusb_realize; dc->reset = milkymist_softusb_reset; dc->vmsd = &vmstate_milkymist_softusb; dc->props = milkymist_softusb_properties; diff --git a/hw/input/pl050.c b/hw/input/pl050.c index be9cd57b17..15bffbfcad 100644 --- a/hw/input/pl050.c +++ b/hw/input/pl050.c @@ -139,19 +139,19 @@ static const MemoryRegionOps pl050_ops = { .endianness = DEVICE_NATIVE_ENDIAN, }; -static int pl050_initfn(SysBusDevice *dev) +static void pl050_realize(DeviceState *dev, Error **errp) { PL050State *s = PL050(dev); + SysBusDevice *sbd = SYS_BUS_DEVICE(dev); memory_region_init_io(&s->iomem, OBJECT(s), &pl050_ops, s, "pl050", 0x1000); - sysbus_init_mmio(dev, &s->iomem); - sysbus_init_irq(dev, &s->irq); + sysbus_init_mmio(sbd, &s->iomem); + sysbus_init_irq(sbd, &s->irq); if (s->is_mouse) { s->dev = ps2_mouse_init(pl050_update, s); } else { s->dev = ps2_kbd_init(pl050_update, s); } - return 0; } static void pl050_keyboard_init(Object *obj) @@ -183,9 +183,8 @@ static const TypeInfo pl050_mouse_info = { static void pl050_class_init(ObjectClass *oc, void *data) { DeviceClass *dc = DEVICE_CLASS(oc); - SysBusDeviceClass *sdc = SYS_BUS_DEVICE_CLASS(oc); - sdc->init = pl050_initfn; + dc->realize = pl050_realize; dc->vmsd = &vmstate_pl050; } diff --git a/hw/intc/arm_gicv3_cpuif.c b/hw/intc/arm_gicv3_cpuif.c index 068a8e8e9b..cbad6037f1 100644 --- a/hw/intc/arm_gicv3_cpuif.c +++ b/hw/intc/arm_gicv3_cpuif.c @@ -85,8 +85,8 @@ static bool icv_access(CPUARMState *env, int hcr_flags) * * access if NS EL1 and either IMO or FMO == 1: * CTLR, DIR, PMR, RPR */ - bool flagmatch = ((hcr_flags & HCR_IMO) && arm_hcr_el2_imo(env)) || - ((hcr_flags & HCR_FMO) && arm_hcr_el2_fmo(env)); + uint64_t hcr_el2 = arm_hcr_el2_eff(env); + bool flagmatch = hcr_el2 & hcr_flags & (HCR_IMO | HCR_FMO); return flagmatch && arm_current_el(env) == 1 && !arm_is_secure_below_el3(env); @@ -1552,8 +1552,9 @@ static void icc_dir_write(CPUARMState *env, const ARMCPRegInfo *ri, /* No need to include !IsSecure in route_*_to_el2 as it's only * tested in cases where we know !IsSecure is true. */ - route_fiq_to_el2 = arm_hcr_el2_fmo(env); - route_irq_to_el2 = arm_hcr_el2_imo(env); + uint64_t hcr_el2 = arm_hcr_el2_eff(env); + route_fiq_to_el2 = hcr_el2 & HCR_FMO; + route_irq_to_el2 = hcr_el2 & HCR_IMO; switch (arm_current_el(env)) { case 3: @@ -1895,8 +1896,8 @@ static CPAccessResult gicv3_irqfiq_access(CPUARMState *env, if ((env->cp15.scr_el3 & (SCR_FIQ | SCR_IRQ)) == (SCR_FIQ | SCR_IRQ)) { switch (el) { case 1: - if (arm_is_secure_below_el3(env) || - (arm_hcr_el2_imo(env) == 0 && arm_hcr_el2_fmo(env) == 0)) { + /* Note that arm_hcr_el2_eff takes secure state into account. */ + if ((arm_hcr_el2_eff(env) & (HCR_IMO | HCR_FMO)) == 0) { r = CP_ACCESS_TRAP_EL3; } break; @@ -1936,8 +1937,8 @@ static CPAccessResult gicv3_dir_access(CPUARMState *env, static CPAccessResult gicv3_sgi_access(CPUARMState *env, const ARMCPRegInfo *ri, bool isread) { - if ((arm_hcr_el2_imo(env) || arm_hcr_el2_fmo(env)) && - arm_current_el(env) == 1 && !arm_is_secure_below_el3(env)) { + if (arm_current_el(env) == 1 && + (arm_hcr_el2_eff(env) & (HCR_IMO | HCR_FMO)) != 0) { /* Takes priority over a possible EL3 trap */ return CP_ACCESS_TRAP_EL2; } @@ -1961,7 +1962,7 @@ static CPAccessResult gicv3_fiq_access(CPUARMState *env, if (env->cp15.scr_el3 & SCR_FIQ) { switch (el) { case 1: - if (arm_is_secure_below_el3(env) || !arm_hcr_el2_fmo(env)) { + if ((arm_hcr_el2_eff(env) & HCR_FMO) == 0) { r = CP_ACCESS_TRAP_EL3; } break; @@ -2000,7 +2001,7 @@ static CPAccessResult gicv3_irq_access(CPUARMState *env, if (env->cp15.scr_el3 & SCR_IRQ) { switch (el) { case 1: - if (arm_is_secure_below_el3(env) || !arm_hcr_el2_imo(env)) { + if ((arm_hcr_el2_eff(env) & HCR_IMO) == 0) { r = CP_ACCESS_TRAP_EL3; } break; diff --git a/hw/intc/puv3_intc.c b/hw/intc/puv3_intc.c index ef8488aacc..69ddc8c19a 100644 --- a/hw/intc/puv3_intc.c +++ b/hw/intc/puv3_intc.c @@ -101,10 +101,10 @@ static const MemoryRegionOps puv3_intc_ops = { .endianness = DEVICE_NATIVE_ENDIAN, }; -static int puv3_intc_init(SysBusDevice *sbd) +static void puv3_intc_realize(DeviceState *dev, Error **errp) { - DeviceState *dev = DEVICE(sbd); PUV3INTCState *s = PUV3_INTC(dev); + SysBusDevice *sbd = SYS_BUS_DEVICE(dev); qdev_init_gpio_in(dev, puv3_intc_handler, PUV3_IRQS_NR); sysbus_init_irq(sbd, &s->parent_irq); @@ -115,15 +115,12 @@ static int puv3_intc_init(SysBusDevice *sbd) memory_region_init_io(&s->iomem, OBJECT(s), &puv3_intc_ops, s, "puv3_intc", PUV3_REGS_OFFSET); sysbus_init_mmio(sbd, &s->iomem); - - return 0; } static void puv3_intc_class_init(ObjectClass *klass, void *data) { - SysBusDeviceClass *sdc = SYS_BUS_DEVICE_CLASS(klass); - - sdc->init = puv3_intc_init; + DeviceClass *dc = DEVICE_CLASS(klass); + dc->realize = puv3_intc_realize; } static const TypeInfo puv3_intc_info = { diff --git a/hw/misc/milkymist-hpdmc.c b/hw/misc/milkymist-hpdmc.c index e6140eec6b..44dc0698ec 100644 --- a/hw/misc/milkymist-hpdmc.c +++ b/hw/misc/milkymist-hpdmc.c @@ -129,15 +129,13 @@ static void milkymist_hpdmc_reset(DeviceState *d) | IODELAY_PLL2_LOCKED; } -static int milkymist_hpdmc_init(SysBusDevice *dev) +static void milkymist_hpdmc_realize(DeviceState *dev, Error **errp) { MilkymistHpdmcState *s = MILKYMIST_HPDMC(dev); memory_region_init_io(&s->regs_region, OBJECT(dev), &hpdmc_mmio_ops, s, "milkymist-hpdmc", R_MAX * 4); - sysbus_init_mmio(dev, &s->regs_region); - - return 0; + sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->regs_region); } static const VMStateDescription vmstate_milkymist_hpdmc = { @@ -153,9 +151,8 @@ static const VMStateDescription vmstate_milkymist_hpdmc = { static void milkymist_hpdmc_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); - SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass); - k->init = milkymist_hpdmc_init; + dc->realize = milkymist_hpdmc_realize; dc->reset = milkymist_hpdmc_reset; dc->vmsd = &vmstate_milkymist_hpdmc; } diff --git a/hw/misc/milkymist-pfpu.c b/hw/misc/milkymist-pfpu.c index 86f5e383b0..4a03c7ee63 100644 --- a/hw/misc/milkymist-pfpu.c +++ b/hw/misc/milkymist-pfpu.c @@ -497,17 +497,16 @@ static void milkymist_pfpu_reset(DeviceState *d) } } -static int milkymist_pfpu_init(SysBusDevice *dev) +static void milkymist_pfpu_realize(DeviceState *dev, Error **errp) { MilkymistPFPUState *s = MILKYMIST_PFPU(dev); + SysBusDevice *sbd = SYS_BUS_DEVICE(dev); - sysbus_init_irq(dev, &s->irq); + sysbus_init_irq(sbd, &s->irq); memory_region_init_io(&s->regs_region, OBJECT(dev), &pfpu_mmio_ops, s, "milkymist-pfpu", MICROCODE_END * 4); - sysbus_init_mmio(dev, &s->regs_region); - - return 0; + sysbus_init_mmio(sbd, &s->regs_region); } static const VMStateDescription vmstate_milkymist_pfpu = { @@ -527,9 +526,8 @@ static const VMStateDescription vmstate_milkymist_pfpu = { static void milkymist_pfpu_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); - SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass); - k->init = milkymist_pfpu_init; + dc->realize = milkymist_pfpu_realize; dc->reset = milkymist_pfpu_reset; dc->vmsd = &vmstate_milkymist_pfpu; } diff --git a/hw/misc/puv3_pm.c b/hw/misc/puv3_pm.c index 577cebaac7..afe191fbe1 100644 --- a/hw/misc/puv3_pm.c +++ b/hw/misc/puv3_pm.c @@ -119,7 +119,7 @@ static const MemoryRegionOps puv3_pm_ops = { .endianness = DEVICE_NATIVE_ENDIAN, }; -static int puv3_pm_init(SysBusDevice *dev) +static void puv3_pm_realize(DeviceState *dev, Error **errp) { PUV3PMState *s = PUV3_PM(dev); @@ -127,16 +127,14 @@ static int puv3_pm_init(SysBusDevice *dev) memory_region_init_io(&s->iomem, OBJECT(s), &puv3_pm_ops, s, "puv3_pm", PUV3_REGS_OFFSET); - sysbus_init_mmio(dev, &s->iomem); - - return 0; + sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->iomem); } static void puv3_pm_class_init(ObjectClass *klass, void *data) { - SysBusDeviceClass *sdc = SYS_BUS_DEVICE_CLASS(klass); + DeviceClass *dc = DEVICE_CLASS(klass); - sdc->init = puv3_pm_init; + dc->realize = puv3_pm_realize; } static const TypeInfo puv3_pm_info = { diff --git a/hw/nvram/ds1225y.c b/hw/nvram/ds1225y.c index ad7345f288..b6ef463db0 100644 --- a/hw/nvram/ds1225y.c +++ b/hw/nvram/ds1225y.c @@ -25,6 +25,7 @@ #include "qemu/osdep.h" #include "hw/sysbus.h" #include "trace.h" +#include "qemu/error-report.h" typedef struct { MemoryRegion iomem; @@ -113,7 +114,7 @@ typedef struct { NvRamState nvram; } SysBusNvRamState; -static int nvram_sysbus_initfn(SysBusDevice *dev) +static void nvram_sysbus_realize(DeviceState *dev, Error **errp) { SysBusNvRamState *sys = DS1225Y(dev); NvRamState *s = &sys->nvram; @@ -123,20 +124,18 @@ static int nvram_sysbus_initfn(SysBusDevice *dev) memory_region_init_io(&s->iomem, OBJECT(s), &nvram_ops, s, "nvram", s->chip_size); - sysbus_init_mmio(dev, &s->iomem); + sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->iomem); /* Read current file */ file = s->filename ? fopen(s->filename, "rb") : NULL; if (file) { /* Read nvram contents */ if (fread(s->contents, s->chip_size, 1, file) != 1) { - printf("nvram_sysbus_initfn: short read\n"); + error_report("nvram_sysbus_realize: short read"); } fclose(file); } nvram_post_load(s, 0); - - return 0; } static Property nvram_sysbus_properties[] = { @@ -148,9 +147,8 @@ static Property nvram_sysbus_properties[] = { static void nvram_sysbus_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); - SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass); - k->init = nvram_sysbus_initfn; + dc->realize = nvram_sysbus_realize; dc->vmsd = &vmstate_nvram; dc->props = nvram_sysbus_properties; } diff --git a/hw/pci-bridge/dec.c b/hw/pci-bridge/dec.c index 84492d5e5f..8484bfd434 100644 --- a/hw/pci-bridge/dec.c +++ b/hw/pci-bridge/dec.c @@ -98,9 +98,10 @@ PCIBus *pci_dec_21154_init(PCIBus *parent_bus, int devfn) return pci_bridge_get_sec_bus(br); } -static int pci_dec_21154_device_init(SysBusDevice *dev) +static void pci_dec_21154_device_realize(DeviceState *dev, Error **errp) { PCIHostState *phb; + SysBusDevice *sbd = SYS_BUS_DEVICE(dev); phb = PCI_HOST_BRIDGE(dev); @@ -108,9 +109,8 @@ static int pci_dec_21154_device_init(SysBusDevice *dev) dev, "pci-conf-idx", 0x1000); memory_region_init_io(&phb->data_mem, OBJECT(dev), &pci_host_data_le_ops, dev, "pci-data-idx", 0x1000); - sysbus_init_mmio(dev, &phb->conf_mem); - sysbus_init_mmio(dev, &phb->data_mem); - return 0; + sysbus_init_mmio(sbd, &phb->conf_mem); + sysbus_init_mmio(sbd, &phb->data_mem); } static void dec_21154_pci_host_realize(PCIDevice *d, Error **errp) @@ -150,9 +150,9 @@ static const TypeInfo dec_21154_pci_host_info = { static void pci_dec_21154_device_class_init(ObjectClass *klass, void *data) { - SysBusDeviceClass *sdc = SYS_BUS_DEVICE_CLASS(klass); + DeviceClass *dc = DEVICE_CLASS(klass); - sdc->init = pci_dec_21154_device_init; + dc->realize = pci_dec_21154_device_realize; } static const TypeInfo pci_dec_21154_device_info = { diff --git a/hw/timer/etraxfs_timer.c b/hw/timer/etraxfs_timer.c index d13bc30b2d..2280914b1d 100644 --- a/hw/timer/etraxfs_timer.c +++ b/hw/timer/etraxfs_timer.c @@ -315,9 +315,10 @@ static void etraxfs_timer_reset(void *opaque) qemu_irq_lower(t->irq); } -static int etraxfs_timer_init(SysBusDevice *dev) +static void etraxfs_timer_realize(DeviceState *dev, Error **errp) { ETRAXTimerState *t = ETRAX_TIMER(dev); + SysBusDevice *sbd = SYS_BUS_DEVICE(dev); t->bh_t0 = qemu_bh_new(timer0_hit, t); t->bh_t1 = qemu_bh_new(timer1_hit, t); @@ -326,21 +327,20 @@ static int etraxfs_timer_init(SysBusDevice *dev) t->ptimer_t1 = ptimer_init(t->bh_t1, PTIMER_POLICY_DEFAULT); t->ptimer_wd = ptimer_init(t->bh_wd, PTIMER_POLICY_DEFAULT); - sysbus_init_irq(dev, &t->irq); - sysbus_init_irq(dev, &t->nmi); + sysbus_init_irq(sbd, &t->irq); + sysbus_init_irq(sbd, &t->nmi); memory_region_init_io(&t->mmio, OBJECT(t), &timer_ops, t, "etraxfs-timer", 0x5c); - sysbus_init_mmio(dev, &t->mmio); + sysbus_init_mmio(sbd, &t->mmio); qemu_register_reset(etraxfs_timer_reset, t); - return 0; } static void etraxfs_timer_class_init(ObjectClass *klass, void *data) { - SysBusDeviceClass *sdc = SYS_BUS_DEVICE_CLASS(klass); + DeviceClass *dc = DEVICE_CLASS(klass); - sdc->init = etraxfs_timer_init; + dc->realize = etraxfs_timer_realize; } static const TypeInfo etraxfs_timer_info = { diff --git a/hw/timer/grlib_gptimer.c b/hw/timer/grlib_gptimer.c index 4ed96e970a..183eddc073 100644 --- a/hw/timer/grlib_gptimer.c +++ b/hw/timer/grlib_gptimer.c @@ -347,10 +347,11 @@ static void grlib_gptimer_reset(DeviceState *d) } } -static int grlib_gptimer_init(SysBusDevice *dev) +static void grlib_gptimer_realize(DeviceState *dev, Error **errp) { GPTimerUnit *unit = GRLIB_GPTIMER(dev); unsigned int i; + SysBusDevice *sbd = SYS_BUS_DEVICE(dev); assert(unit->nr_timers > 0); assert(unit->nr_timers <= GPTIMER_MAX_TIMERS); @@ -366,7 +367,7 @@ static int grlib_gptimer_init(SysBusDevice *dev) timer->id = i; /* One IRQ line for each timer */ - sysbus_init_irq(dev, &timer->irq); + sysbus_init_irq(sbd, &timer->irq); ptimer_set_freq(timer->ptimer, unit->freq_hz); } @@ -375,8 +376,7 @@ static int grlib_gptimer_init(SysBusDevice *dev) unit, "gptimer", UNIT_REG_SIZE + GPTIMER_REG_SIZE * unit->nr_timers); - sysbus_init_mmio(dev, &unit->iomem); - return 0; + sysbus_init_mmio(sbd, &unit->iomem); } static Property grlib_gptimer_properties[] = { @@ -389,9 +389,8 @@ static Property grlib_gptimer_properties[] = { static void grlib_gptimer_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); - SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass); - k->init = grlib_gptimer_init; + dc->realize = grlib_gptimer_realize; dc->reset = grlib_gptimer_reset; dc->props = grlib_gptimer_properties; } diff --git a/hw/timer/puv3_ost.c b/hw/timer/puv3_ost.c index 0b3d717e60..3be58c7fdd 100644 --- a/hw/timer/puv3_ost.c +++ b/hw/timer/puv3_ost.c @@ -113,16 +113,17 @@ static void puv3_ost_tick(void *opaque) } } -static int puv3_ost_init(SysBusDevice *dev) +static void puv3_ost_realize(DeviceState *dev, Error **errp) { PUV3OSTState *s = PUV3_OST(dev); + SysBusDevice *sbd = SYS_BUS_DEVICE(dev); s->reg_OIER = 0; s->reg_OSSR = 0; s->reg_OSMR0 = 0; s->reg_OSCR = 0; - sysbus_init_irq(dev, &s->irq); + sysbus_init_irq(sbd, &s->irq); s->bh = qemu_bh_new(puv3_ost_tick, s); s->ptimer = ptimer_init(s->bh, PTIMER_POLICY_DEFAULT); @@ -130,16 +131,14 @@ static int puv3_ost_init(SysBusDevice *dev) memory_region_init_io(&s->iomem, OBJECT(s), &puv3_ost_ops, s, "puv3_ost", PUV3_REGS_OFFSET); - sysbus_init_mmio(dev, &s->iomem); - - return 0; + sysbus_init_mmio(sbd, &s->iomem); } static void puv3_ost_class_init(ObjectClass *klass, void *data) { - SysBusDeviceClass *sdc = SYS_BUS_DEVICE_CLASS(klass); + DeviceClass *dc = DEVICE_CLASS(klass); - sdc->init = puv3_ost_init; + dc->realize = puv3_ost_realize; } static const TypeInfo puv3_ost_info = { diff --git a/hw/usb/tusb6010.c b/hw/usb/tusb6010.c index a2128024c1..501706e2b2 100644 --- a/hw/usb/tusb6010.c +++ b/hw/usb/tusb6010.c @@ -808,10 +808,10 @@ static void tusb6010_reset(DeviceState *dev) musb_reset(s->musb); } -static int tusb6010_init(SysBusDevice *sbd) +static void tusb6010_realize(DeviceState *dev, Error **errp) { - DeviceState *dev = DEVICE(sbd); TUSBState *s = TUSB(dev); + SysBusDevice *sbd = SYS_BUS_DEVICE(dev); s->otg_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, tusb_otg_tick, s); s->pwr_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, tusb_power_tick, s); @@ -822,15 +822,13 @@ static int tusb6010_init(SysBusDevice *sbd) sysbus_init_irq(sbd, &s->irq); qdev_init_gpio_in(dev, tusb6010_irq, musb_irq_max + 1); s->musb = musb_init(dev, 1); - return 0; } static void tusb6010_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); - SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass); - k->init = tusb6010_init; + dc->realize = tusb6010_realize; dc->reset = tusb6010_reset; } diff --git a/hw/xen/xen_backend.c b/hw/xen/xen_backend.c index 9a8e8771ec..0bc6b1de60 100644 --- a/hw/xen/xen_backend.c +++ b/hw/xen/xen_backend.c @@ -809,11 +809,6 @@ static const TypeInfo xensysbus_info = { } }; -static int xen_sysdev_init(SysBusDevice *dev) -{ - return 0; -} - static Property xen_sysdev_properties[] = { {/* end of property list */}, }; @@ -821,9 +816,7 @@ static Property xen_sysdev_properties[] = { static void xen_sysdev_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); - SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass); - k->init = xen_sysdev_init; dc->props = xen_sysdev_properties; dc->bus_type = TYPE_XENSYSBUS; } diff --git a/include/crypto/block.h b/include/crypto/block.h index cd18f46d56..e729d5bd66 100644 --- a/include/crypto/block.h +++ b/include/crypto/block.h @@ -75,6 +75,7 @@ typedef enum { * @readfunc: callback for reading data from the volume * @opaque: data to pass to @readfunc * @flags: bitmask of QCryptoBlockOpenFlags values + * @n_threads: allow concurrent I/O from up to @n_threads threads * @errp: pointer to a NULL-initialized error object * * Create a new block encryption object for an existing @@ -107,6 +108,7 @@ QCryptoBlock *qcrypto_block_open(QCryptoBlockOpenOptions *options, QCryptoBlockReadFunc readfunc, void *opaque, unsigned int flags, + size_t n_threads, Error **errp); /** diff --git a/include/hw/arm/xlnx-versal.h b/include/hw/arm/xlnx-versal.h index 9da621e4b6..ec7c859d08 100644 --- a/include/hw/arm/xlnx-versal.h +++ b/include/hw/arm/xlnx-versal.h @@ -22,7 +22,7 @@ #define XLNX_VERSAL_NR_ACPUS 2 #define XLNX_VERSAL_NR_UARTS 2 #define XLNX_VERSAL_NR_GEMS 2 -#define XLNX_VERSAL_NR_IRQS 256 +#define XLNX_VERSAL_NR_IRQS 192 typedef struct Versal { /*< private >*/ @@ -75,9 +75,9 @@ typedef struct Versal { #define VERSAL_GEM1_IRQ_0 58 #define VERSAL_GEM1_WAKE_IRQ_0 59 -/* Architecturally eserved IRQs suitable for virtualization. */ -#define VERSAL_RSVD_HIGH_IRQ_FIRST 160 -#define VERSAL_RSVD_HIGH_IRQ_LAST 255 +/* Architecturally reserved IRQs suitable for virtualization. */ +#define VERSAL_RSVD_IRQ_FIRST 111 +#define VERSAL_RSVD_IRQ_LAST 118 #define MM_TOP_RSVD 0xa0000000U #define MM_TOP_RSVD_SIZE 0x4000000 diff --git a/include/hw/i2c/i2c.h b/include/hw/i2c/i2c.h index 5dc166158b..cf4c45a98f 100644 --- a/include/hw/i2c/i2c.h +++ b/include/hw/i2c/i2c.h @@ -82,6 +82,8 @@ int i2c_recv(I2CBus *bus); DeviceState *i2c_create_slave(I2CBus *bus, const char *name, uint8_t addr); +typedef struct bitbang_i2c_interface bitbang_i2c_interface; + /* lm832x.c */ void lm832x_key_event(DeviceState *dev, int key, int state); diff --git a/include/hw/i2c/ppc4xx_i2c.h b/include/hw/i2c/ppc4xx_i2c.h index 0891a9c948..b3450bacf7 100644 --- a/include/hw/i2c/ppc4xx_i2c.h +++ b/include/hw/i2c/ppc4xx_i2c.h @@ -31,9 +31,6 @@ #include "hw/sysbus.h" #include "hw/i2c/i2c.h" -/* from hw/i2c/bitbang_i2c.h */ -typedef struct bitbang_i2c_interface bitbang_i2c_interface; - #define TYPE_PPC4xx_I2C "ppc4xx-i2c" #define PPC4xx_I2C(obj) OBJECT_CHECK(PPC4xxI2CState, (obj), TYPE_PPC4xx_I2C) diff --git a/include/hw/sysbus.h b/include/hw/sysbus.h index 0b59a3b8d6..1aedcf05c9 100644 --- a/include/hw/sysbus.h +++ b/include/hw/sysbus.h @@ -38,9 +38,6 @@ typedef struct SysBusDevice SysBusDevice; typedef struct SysBusDeviceClass { /*< private >*/ DeviceClass parent_class; - /*< public >*/ - - int (*init)(SysBusDevice *dev); /* * Let the sysbus device format its own non-PIO, non-MMIO unit address. diff --git a/include/qemu/compiler.h b/include/qemu/compiler.h index 6b92710487..261842beae 100644 --- a/include/qemu/compiler.h +++ b/include/qemu/compiler.h @@ -28,12 +28,6 @@ #define QEMU_SENTINEL __attribute__((sentinel)) -#if QEMU_GNUC_PREREQ(4, 3) -#define QEMU_ARTIFICIAL __attribute__((always_inline, artificial)) -#else -#define QEMU_ARTIFICIAL -#endif - #if defined(_WIN32) # define QEMU_PACKED __attribute__((gcc_struct, packed)) #else @@ -127,7 +121,7 @@ #define __has_builtin(x) 0 /* compatibility with non-clang compilers */ #endif -#if __has_builtin(__builtin_assume_aligned) || QEMU_GNUC_PREREQ(4, 7) +#if __has_builtin(__builtin_assume_aligned) || !defined(__clang__) #define HAS_ASSUME_ALIGNED #endif diff --git a/include/qemu/host-utils.h b/include/qemu/host-utils.h index 38da849be9..4cd170e6cd 100644 --- a/include/qemu/host-utils.h +++ b/include/qemu/host-utils.h @@ -207,7 +207,7 @@ static inline int cto64(uint64_t val) */ static inline int clrsb32(uint32_t val) { -#if QEMU_GNUC_PREREQ(4, 7) +#if __has_builtin(__builtin_clrsb) || !defined(__clang__) return __builtin_clrsb(val); #else return clz32(val ^ ((int32_t)val >> 1)) - 1; @@ -223,7 +223,7 @@ static inline int clrsb32(uint32_t val) */ static inline int clrsb64(uint64_t val) { -#if QEMU_GNUC_PREREQ(4, 7) +#if __has_builtin(__builtin_clrsbll) || !defined(__clang__) return __builtin_clrsbll(val); #else return clz64(val ^ ((int64_t)val >> 1)) - 1; diff --git a/qapi/crypto.json b/qapi/crypto.json index a51b434412..b2a4cff683 100644 --- a/qapi/crypto.json +++ b/qapi/crypto.json @@ -181,11 +181,11 @@ # The options that apply to LUKS encryption format initialization # # @cipher-alg: the cipher algorithm for data encryption -# Currently defaults to 'aes'. +# Currently defaults to 'aes-256'. # @cipher-mode: the cipher mode for data encryption -# Currently defaults to 'cbc' +# Currently defaults to 'xts' # @ivgen-alg: the initialization vector generator -# Currently defaults to 'essiv' +# Currently defaults to 'plain64' # @ivgen-hash-alg: the initialization vector generator hash # Currently defaults to 'sha256' # @hash-alg: the master key hash algorithm diff --git a/qemu-deprecated.texi b/qemu-deprecated.texi index 72b8191d60..e362d37225 100644 --- a/qemu-deprecated.texi +++ b/qemu-deprecated.texi @@ -46,14 +46,6 @@ would automatically enable USB support on the machine type. If using the new syntax, USB support must be explicitly enabled via the ``-machine usb=on'' argument. -@subsection -fsdev handle (since 2.12.0) - -The ``handle'' fsdev backend does not support symlinks and causes the 9p -filesystem in the guest to fail a fair amount of tests from the PJD POSIX -filesystem test suite. Also it requires the CAP_DAC_READ_SEARCH capability, -which is not the recommended way to run QEMU. This backend should not be -used and it will be removed with no replacement. - @subsection -no-frame (since 2.12.0) The @code{--no-frame} argument works with SDL 1.2 only. The other user diff --git a/qemu-options.hx b/qemu-options.hx index 269eda7a5d..df42116ecc 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -1019,7 +1019,7 @@ Define a new file system device. Valid options are: @table @option @item @var{fsdriver} This option specifies the fs driver backend to use. -Currently "local", "handle" and "proxy" file system drivers are supported. +Currently "local" and "proxy" file system drivers are supported. @item id=@var{id} Specifies identifier for this device @item path=@var{path} @@ -1037,7 +1037,7 @@ hidden .virtfs_metadata directory. Directories exported by this security model c interact with other unix tools. "none" security model is same as passthrough except the sever won't report failures if it fails to set file attributes like ownership. Security model is mandatory -only for local fsdriver. Other fsdrivers (like handle, proxy) don't take +only for local fsdriver. Other fsdrivers (like proxy) don't take security model as a parameter. @item writeout=@var{writeout} This is an optional argument. The only supported value is "immediate". @@ -1088,7 +1088,7 @@ The general form of a Virtual File system pass-through options are: @table @option @item @var{fsdriver} This option specifies the fs driver backend to use. -Currently "local", "handle" and "proxy" file system drivers are supported. +Currently "local" and "proxy" file system drivers are supported. @item id=@var{id} Specifies identifier for this device @item path=@var{path} @@ -1106,7 +1106,7 @@ hidden .virtfs_metadata directory. Directories exported by this security model c interact with other unix tools. "none" security model is same as passthrough except the sever won't report failures if it fails to set file attributes like ownership. Security model is mandatory only -for local fsdriver. Other fsdrivers (like handle, proxy) don't take security +for local fsdriver. Other fsdrivers (like proxy) don't take security model as a parameter. @item writeout=@var{writeout} This is an optional argument. The only supported value is "immediate". diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 60f6f89a27..a892a6cc7c 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -202,7 +202,6 @@ our $Attribute = qr{ QEMU_NORETURN| QEMU_WARN_UNUSED_RESULT| QEMU_SENTINEL| - QEMU_ARTIFICIAL| QEMU_PACKED| GCC_FMT_ATTR }x; diff --git a/scripts/cocci-macro-file.h b/scripts/cocci-macro-file.h index 9f2e72e7e1..7e200a1023 100644 --- a/scripts/cocci-macro-file.h +++ b/scripts/cocci-macro-file.h @@ -23,7 +23,6 @@ #define QEMU_NORETURN __attribute__ ((__noreturn__)) #define QEMU_WARN_UNUSED_RESULT __attribute__((warn_unused_result)) #define QEMU_SENTINEL __attribute__((sentinel)) -#define QEMU_ARTIFICIAL __attribute__((always_inline, artificial)) #define QEMU_PACKED __attribute__((gcc_struct, packed)) #define cat(x,y) x ## y diff --git a/scripts/tracetool/backend/log.py b/scripts/tracetool/backend/log.py index 6751f41bc5..33c95af8e9 100644 --- a/scripts/tracetool/backend/log.py +++ b/scripts/tracetool/backend/log.py @@ -39,7 +39,7 @@ def generate_h(event, group): ' struct timeval _now;', ' gettimeofday(&_now, NULL);', ' qemu_log("%%d@%%zu.%%06zu:%(name)s " %(fmt)s "\\n",', - ' getpid(),', + ' qemu_get_thread_id(),', ' (size_t)_now.tv_sec, (size_t)_now.tv_usec', ' %(argnames)s);', ' }', diff --git a/target/arm/cpu.c b/target/arm/cpu.c index 60411f6bfe..0b185f8d30 100644 --- a/target/arm/cpu.c +++ b/target/arm/cpu.c @@ -1932,6 +1932,10 @@ static void arm_max_initfn(Object *obj) t = cpu->isar.id_isar6; t = FIELD_DP32(t, ID_ISAR6, DP, 1); cpu->isar.id_isar6 = t; + + t = cpu->id_mmfr4; + t = FIELD_DP32(t, ID_MMFR4, HPDS, 1); /* AA32HPD */ + cpu->id_mmfr4 = t; } #endif } diff --git a/target/arm/cpu.h b/target/arm/cpu.h index 2a73fed9a0..c943f35dd9 100644 --- a/target/arm/cpu.h +++ b/target/arm/cpu.h @@ -818,6 +818,8 @@ struct ARMCPU { uint64_t id_aa64isar1; uint64_t id_aa64pfr0; uint64_t id_aa64pfr1; + uint64_t id_aa64mmfr0; + uint64_t id_aa64mmfr1; } isar; uint32_t midr; uint32_t revidr; @@ -839,8 +841,6 @@ struct ARMCPU { uint64_t id_aa64dfr1; uint64_t id_aa64afr0; uint64_t id_aa64afr1; - uint64_t id_aa64mmfr0; - uint64_t id_aa64mmfr1; uint32_t dbgdidr; uint32_t clidr; uint64_t mp_affinity; /* MP ID without feature bits */ @@ -1249,7 +1249,7 @@ static inline void xpsr_write(CPUARMState *env, uint32_t val, uint32_t mask) #define HCR_TIDCP (1ULL << 20) #define HCR_TACR (1ULL << 21) #define HCR_TSW (1ULL << 22) -#define HCR_TPC (1ULL << 23) +#define HCR_TPCP (1ULL << 23) #define HCR_TPU (1ULL << 24) #define HCR_TTLB (1ULL << 25) #define HCR_TVM (1ULL << 26) @@ -1261,6 +1261,26 @@ static inline void xpsr_write(CPUARMState *env, uint32_t val, uint32_t mask) #define HCR_CD (1ULL << 32) #define HCR_ID (1ULL << 33) #define HCR_E2H (1ULL << 34) +#define HCR_TLOR (1ULL << 35) +#define HCR_TERR (1ULL << 36) +#define HCR_TEA (1ULL << 37) +#define HCR_MIOCNCE (1ULL << 38) +#define HCR_APK (1ULL << 40) +#define HCR_API (1ULL << 41) +#define HCR_NV (1ULL << 42) +#define HCR_NV1 (1ULL << 43) +#define HCR_AT (1ULL << 44) +#define HCR_NV2 (1ULL << 45) +#define HCR_FWB (1ULL << 46) +#define HCR_FIEN (1ULL << 47) +#define HCR_TID4 (1ULL << 49) +#define HCR_TICAB (1ULL << 50) +#define HCR_TOCU (1ULL << 52) +#define HCR_TTLBIS (1ULL << 54) +#define HCR_TTLBOS (1ULL << 55) +#define HCR_ATA (1ULL << 56) +#define HCR_DCT (1ULL << 57) + /* * When we actually implement ARMv8.1-VHE we should add HCR_E2H to * HCR_MASK and then clear it again if the feature bit is not set in @@ -1282,8 +1302,16 @@ static inline void xpsr_write(CPUARMState *env, uint32_t val, uint32_t mask) #define SCR_ST (1U << 11) #define SCR_TWI (1U << 12) #define SCR_TWE (1U << 13) -#define SCR_AARCH32_MASK (0x3fff & ~(SCR_RW | SCR_ST)) -#define SCR_AARCH64_MASK (0x3fff & ~SCR_NET) +#define SCR_TLOR (1U << 14) +#define SCR_TERR (1U << 15) +#define SCR_APK (1U << 16) +#define SCR_API (1U << 17) +#define SCR_EEL2 (1U << 18) +#define SCR_EASE (1U << 19) +#define SCR_NMEA (1U << 20) +#define SCR_FIEN (1U << 21) +#define SCR_ENSCXT (1U << 25) +#define SCR_ATA (1U << 26) /* Return the current FPSCR value. */ uint32_t vfp_get_fpscr(CPUARMState *env); @@ -1520,6 +1548,15 @@ FIELD(ID_ISAR6, FHM, 8, 4) FIELD(ID_ISAR6, SB, 12, 4) FIELD(ID_ISAR6, SPECRES, 16, 4) +FIELD(ID_MMFR4, SPECSEI, 0, 4) +FIELD(ID_MMFR4, AC2, 4, 4) +FIELD(ID_MMFR4, XNX, 8, 4) +FIELD(ID_MMFR4, CNP, 12, 4) +FIELD(ID_MMFR4, HPDS, 16, 4) +FIELD(ID_MMFR4, LSM, 20, 4) +FIELD(ID_MMFR4, CCIDX, 24, 4) +FIELD(ID_MMFR4, EVT, 28, 4) + FIELD(ID_AA64ISAR0, AES, 4, 4) FIELD(ID_AA64ISAR0, SHA1, 8, 4) FIELD(ID_AA64ISAR0, SHA2, 12, 4) @@ -1557,6 +1594,28 @@ FIELD(ID_AA64PFR0, GIC, 24, 4) FIELD(ID_AA64PFR0, RAS, 28, 4) FIELD(ID_AA64PFR0, SVE, 32, 4) +FIELD(ID_AA64MMFR0, PARANGE, 0, 4) +FIELD(ID_AA64MMFR0, ASIDBITS, 4, 4) +FIELD(ID_AA64MMFR0, BIGEND, 8, 4) +FIELD(ID_AA64MMFR0, SNSMEM, 12, 4) +FIELD(ID_AA64MMFR0, BIGENDEL0, 16, 4) +FIELD(ID_AA64MMFR0, TGRAN16, 20, 4) +FIELD(ID_AA64MMFR0, TGRAN64, 24, 4) +FIELD(ID_AA64MMFR0, TGRAN4, 28, 4) +FIELD(ID_AA64MMFR0, TGRAN16_2, 32, 4) +FIELD(ID_AA64MMFR0, TGRAN64_2, 36, 4) +FIELD(ID_AA64MMFR0, TGRAN4_2, 40, 4) +FIELD(ID_AA64MMFR0, EXS, 44, 4) + +FIELD(ID_AA64MMFR1, HAFDBS, 0, 4) +FIELD(ID_AA64MMFR1, VMIDBITS, 4, 4) +FIELD(ID_AA64MMFR1, VH, 8, 4) +FIELD(ID_AA64MMFR1, HPDS, 12, 4) +FIELD(ID_AA64MMFR1, LO, 16, 4) +FIELD(ID_AA64MMFR1, PAN, 20, 4) +FIELD(ID_AA64MMFR1, SPECSEI, 24, 4) +FIELD(ID_AA64MMFR1, XNX, 28, 4) + QEMU_BUILD_BUG_ON(ARRAY_SIZE(((ARMCPU *)0)->ccsidr) <= R_V7M_CSSELR_INDEX_MASK); /* If adding a feature bit which corresponds to a Linux ELF @@ -1670,6 +1729,14 @@ static inline bool arm_is_secure(CPUARMState *env) } #endif +/** + * arm_hcr_el2_eff(): Return the effective value of HCR_EL2. + * E.g. when in secure state, fields in HCR_EL2 are suppressed, + * "for all purposes other than a direct read or write access of HCR_EL2." + * Not included here is HCR_RW. + */ +uint64_t arm_hcr_el2_eff(CPUARMState *env); + /* Return true if the specified exception level is running in AArch64 state. */ static inline bool arm_el_is_aa64(CPUARMState *env, int el) { @@ -2355,54 +2422,6 @@ bool write_cpustate_to_list(ARMCPU *cpu); # define TARGET_VIRT_ADDR_SPACE_BITS 32 #endif -/** - * arm_hcr_el2_imo(): Return the effective value of HCR_EL2.IMO. - * Depending on the values of HCR_EL2.E2H and TGE, this may be - * "behaves as 1 for all purposes other than direct read/write" or - * "behaves as 0 for all purposes other than direct read/write" - */ -static inline bool arm_hcr_el2_imo(CPUARMState *env) -{ - switch (env->cp15.hcr_el2 & (HCR_TGE | HCR_E2H)) { - case HCR_TGE: - return true; - case HCR_TGE | HCR_E2H: - return false; - default: - return env->cp15.hcr_el2 & HCR_IMO; - } -} - -/** - * arm_hcr_el2_fmo(): Return the effective value of HCR_EL2.FMO. - */ -static inline bool arm_hcr_el2_fmo(CPUARMState *env) -{ - switch (env->cp15.hcr_el2 & (HCR_TGE | HCR_E2H)) { - case HCR_TGE: - return true; - case HCR_TGE | HCR_E2H: - return false; - default: - return env->cp15.hcr_el2 & HCR_FMO; - } -} - -/** - * arm_hcr_el2_amo(): Return the effective value of HCR_EL2.AMO. - */ -static inline bool arm_hcr_el2_amo(CPUARMState *env) -{ - switch (env->cp15.hcr_el2 & (HCR_TGE | HCR_E2H)) { - case HCR_TGE: - return true; - case HCR_TGE | HCR_E2H: - return false; - default: - return env->cp15.hcr_el2 & HCR_AMO; - } -} - static inline bool arm_excp_unmasked(CPUState *cs, unsigned int excp_idx, unsigned int target_el) { @@ -2411,6 +2430,7 @@ static inline bool arm_excp_unmasked(CPUState *cs, unsigned int excp_idx, bool secure = arm_is_secure(env); bool pstate_unmasked; int8_t unmasked = 0; + uint64_t hcr_el2; /* Don't take exceptions if they target a lower EL. * This check should catch any exceptions that would not be taken but left @@ -2420,6 +2440,8 @@ static inline bool arm_excp_unmasked(CPUState *cs, unsigned int excp_idx, return false; } + hcr_el2 = arm_hcr_el2_eff(env); + switch (excp_idx) { case EXCP_FIQ: pstate_unmasked = !(env->daif & PSTATE_F); @@ -2430,13 +2452,13 @@ static inline bool arm_excp_unmasked(CPUState *cs, unsigned int excp_idx, break; case EXCP_VFIQ: - if (secure || !arm_hcr_el2_fmo(env) || (env->cp15.hcr_el2 & HCR_TGE)) { + if (secure || !(hcr_el2 & HCR_FMO) || (hcr_el2 & HCR_TGE)) { /* VFIQs are only taken when hypervized and non-secure. */ return false; } return !(env->daif & PSTATE_F); case EXCP_VIRQ: - if (secure || !arm_hcr_el2_imo(env) || (env->cp15.hcr_el2 & HCR_TGE)) { + if (secure || !(hcr_el2 & HCR_IMO) || (hcr_el2 & HCR_TGE)) { /* VIRQs are only taken when hypervized and non-secure. */ return false; } @@ -2475,7 +2497,7 @@ static inline bool arm_excp_unmasked(CPUState *cs, unsigned int excp_idx, * to the CPSR.F setting otherwise we further assess the state * below. */ - hcr = arm_hcr_el2_fmo(env); + hcr = hcr_el2 & HCR_FMO; scr = (env->cp15.scr_el3 & SCR_FIQ); /* When EL3 is 32-bit, the SCR.FW bit controls whether the @@ -2492,7 +2514,7 @@ static inline bool arm_excp_unmasked(CPUState *cs, unsigned int excp_idx, * when setting the target EL, so it does not have a further * affect here. */ - hcr = arm_hcr_el2_imo(env); + hcr = hcr_el2 & HCR_IMO; scr = false; break; default: @@ -3318,6 +3340,11 @@ static inline bool isar_feature_aa64_sve(const ARMISARegisters *id) return FIELD_EX64(id->id_aa64pfr0, ID_AA64PFR0, SVE) != 0; } +static inline bool isar_feature_aa64_lor(const ARMISARegisters *id) +{ + return FIELD_EX64(id->id_aa64mmfr1, ID_AA64MMFR1, LO) != 0; +} + /* * Forward to the above feature tests given an ARMCPU pointer. */ diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c index 873f059bf2..1d57be0c91 100644 --- a/target/arm/cpu64.c +++ b/target/arm/cpu64.c @@ -141,7 +141,7 @@ static void aarch64_a57_initfn(Object *obj) cpu->pmceid0 = 0x00000000; cpu->pmceid1 = 0x00000000; cpu->isar.id_aa64isar0 = 0x00011120; - cpu->id_aa64mmfr0 = 0x00001124; + cpu->isar.id_aa64mmfr0 = 0x00001124; cpu->dbgdidr = 0x3516d000; cpu->clidr = 0x0a200023; cpu->ccsidr[0] = 0x701fe00a; /* 32KB L1 dcache */ @@ -195,7 +195,7 @@ static void aarch64_a53_initfn(Object *obj) cpu->isar.id_aa64pfr0 = 0x00002222; cpu->id_aa64dfr0 = 0x10305106; cpu->isar.id_aa64isar0 = 0x00011120; - cpu->id_aa64mmfr0 = 0x00001122; /* 40 bit physical addr */ + cpu->isar.id_aa64mmfr0 = 0x00001122; /* 40 bit physical addr */ cpu->dbgdidr = 0x3516d000; cpu->clidr = 0x0a200023; cpu->ccsidr[0] = 0x700fe01a; /* 32KB L1 dcache */ @@ -249,7 +249,7 @@ static void aarch64_a72_initfn(Object *obj) cpu->pmceid0 = 0x00000000; cpu->pmceid1 = 0x00000000; cpu->isar.id_aa64isar0 = 0x00011120; - cpu->id_aa64mmfr0 = 0x00001124; + cpu->isar.id_aa64mmfr0 = 0x00001124; cpu->dbgdidr = 0x3516d000; cpu->clidr = 0x0a200023; cpu->ccsidr[0] = 0x701fe00a; /* 32KB L1 dcache */ @@ -324,6 +324,11 @@ static void aarch64_max_initfn(Object *obj) t = FIELD_DP64(t, ID_AA64PFR0, ADVSIMD, 1); cpu->isar.id_aa64pfr0 = t; + t = cpu->isar.id_aa64mmfr1; + t = FIELD_DP64(t, ID_AA64MMFR1, HPDS, 1); /* HPD */ + t = FIELD_DP64(t, ID_AA64MMFR1, LO, 1); + cpu->isar.id_aa64mmfr1 = t; + /* Replicate the same data to the 32-bit id registers. */ u = cpu->isar.id_isar5; u = FIELD_DP32(u, ID_ISAR5, AES, 2); /* AES + PMULL */ diff --git a/target/arm/helper.c b/target/arm/helper.c index 0da1424f72..644599b29d 100644 --- a/target/arm/helper.c +++ b/target/arm/helper.c @@ -448,7 +448,7 @@ static CPAccessResult access_tdosa(CPUARMState *env, const ARMCPRegInfo *ri, int el = arm_current_el(env); bool mdcr_el2_tdosa = (env->cp15.mdcr_el2 & MDCR_TDOSA) || (env->cp15.mdcr_el2 & MDCR_TDE) || - (env->cp15.hcr_el2 & HCR_TGE); + (arm_hcr_el2_eff(env) & HCR_TGE); if (el < 2 && mdcr_el2_tdosa && !arm_is_secure_below_el3(env)) { return CP_ACCESS_TRAP_EL2; @@ -468,7 +468,7 @@ static CPAccessResult access_tdra(CPUARMState *env, const ARMCPRegInfo *ri, int el = arm_current_el(env); bool mdcr_el2_tdra = (env->cp15.mdcr_el2 & MDCR_TDRA) || (env->cp15.mdcr_el2 & MDCR_TDE) || - (env->cp15.hcr_el2 & HCR_TGE); + (arm_hcr_el2_eff(env) & HCR_TGE); if (el < 2 && mdcr_el2_tdra && !arm_is_secure_below_el3(env)) { return CP_ACCESS_TRAP_EL2; @@ -488,7 +488,7 @@ static CPAccessResult access_tda(CPUARMState *env, const ARMCPRegInfo *ri, int el = arm_current_el(env); bool mdcr_el2_tda = (env->cp15.mdcr_el2 & MDCR_TDA) || (env->cp15.mdcr_el2 & MDCR_TDE) || - (env->cp15.hcr_el2 & HCR_TGE); + (arm_hcr_el2_eff(env) & HCR_TGE); if (el < 2 && mdcr_el2_tda && !arm_is_secure_below_el3(env)) { return CP_ACCESS_TRAP_EL2; @@ -1279,11 +1279,16 @@ static void vbar_write(CPUARMState *env, const ARMCPRegInfo *ri, static void scr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value) { - /* We only mask off bits that are RES0 both for AArch64 and AArch32. - * For bits that vary between AArch32/64, code needs to check the - * current execution mode before directly using the feature bit. - */ - uint32_t valid_mask = SCR_AARCH64_MASK | SCR_AARCH32_MASK; + /* Begin with base v8.0 state. */ + uint32_t valid_mask = 0x3fff; + ARMCPU *cpu = arm_env_get_cpu(env); + + if (arm_el_is_aa64(env, 3)) { + value |= SCR_FW | SCR_AW; /* these two bits are RES1. */ + valid_mask &= ~SCR_NET; + } else { + valid_mask &= ~(SCR_RW | SCR_ST); + } if (!arm_feature(env, ARM_FEATURE_EL2)) { valid_mask &= ~SCR_HCE; @@ -1299,6 +1304,9 @@ static void scr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value) valid_mask &= ~SCR_SMD; } } + if (cpu_isar_feature(aa64_lor, cpu)) { + valid_mask |= SCR_TLOR; + } /* Clear all-context RES0 bits. */ value &= valid_mask; @@ -1327,9 +1335,10 @@ static void csselr_write(CPUARMState *env, const ARMCPRegInfo *ri, static uint64_t isr_read(CPUARMState *env, const ARMCPRegInfo *ri) { CPUState *cs = ENV_GET_CPU(env); + uint64_t hcr_el2 = arm_hcr_el2_eff(env); uint64_t ret = 0; - if (arm_hcr_el2_imo(env)) { + if (hcr_el2 & HCR_IMO) { if (cs->interrupt_request & CPU_INTERRUPT_VIRQ) { ret |= CPSR_I; } @@ -1339,7 +1348,7 @@ static uint64_t isr_read(CPUARMState *env, const ARMCPRegInfo *ri) } } - if (arm_hcr_el2_fmo(env)) { + if (hcr_el2 & HCR_FMO) { if (cs->interrupt_request & CPU_INTERRUPT_VFIQ) { ret |= CPSR_F; } @@ -2724,6 +2733,7 @@ static void vmsa_ttbcr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value) { ARMCPU *cpu = arm_env_get_cpu(env); + TCR *tcr = raw_ptr(env, ri); if (arm_feature(env, ARM_FEATURE_LPAE)) { /* With LPAE the TTBCR could result in a change of ASID @@ -2731,6 +2741,8 @@ static void vmsa_ttbcr_write(CPUARMState *env, const ARMCPRegInfo *ri, */ tlb_flush(CPU(cpu)); } + /* Preserve the high half of TCR_EL1, set via TTBCR2. */ + value = deposit64(tcr->raw_tcr, 0, 32, value); vmsa_ttbcr_raw_write(env, ri, value); } @@ -2833,6 +2845,16 @@ static const ARMCPRegInfo vmsa_cp_reginfo[] = { REGINFO_SENTINEL }; +/* Note that unlike TTBCR, writing to TTBCR2 does not require flushing + * qemu tlbs nor adjusting cached masks. + */ +static const ARMCPRegInfo ttbcr2_reginfo = { + .name = "TTBCR2", .cp = 15, .opc1 = 0, .crn = 2, .crm = 0, .opc2 = 3, + .access = PL1_RW, .type = ARM_CP_ALIAS, + .bank_fieldoffsets = { offsetofhigh32(CPUARMState, cp15.tcr_el[3]), + offsetofhigh32(CPUARMState, cp15.tcr_el[1]) }, +}; + static void omap_ticonfig_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value) { @@ -3945,6 +3967,9 @@ static void hcr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value) */ valid_mask &= ~HCR_TSC; } + if (cpu_isar_feature(aa64_lor, cpu)) { + valid_mask |= HCR_TLOR; + } /* Clear RES0 bits. */ value &= valid_mask; @@ -3991,6 +4016,51 @@ static void hcr_writelow(CPUARMState *env, const ARMCPRegInfo *ri, hcr_write(env, NULL, value); } +/* + * Return the effective value of HCR_EL2. + * Bits that are not included here: + * RW (read from SCR_EL3.RW as needed) + */ +uint64_t arm_hcr_el2_eff(CPUARMState *env) +{ + uint64_t ret = env->cp15.hcr_el2; + + if (arm_is_secure_below_el3(env)) { + /* + * "This register has no effect if EL2 is not enabled in the + * current Security state". This is ARMv8.4-SecEL2 speak for + * !(SCR_EL3.NS==1 || SCR_EL3.EEL2==1). + * + * Prior to that, the language was "In an implementation that + * includes EL3, when the value of SCR_EL3.NS is 0 the PE behaves + * as if this field is 0 for all purposes other than a direct + * read or write access of HCR_EL2". With lots of enumeration + * on a per-field basis. In current QEMU, this is condition + * is arm_is_secure_below_el3. + * + * Since the v8.4 language applies to the entire register, and + * appears to be backward compatible, use that. + */ + ret = 0; + } else if (ret & HCR_TGE) { + /* These bits are up-to-date as of ARMv8.4. */ + if (ret & HCR_E2H) { + ret &= ~(HCR_VM | HCR_FMO | HCR_IMO | HCR_AMO | + HCR_BSU_MASK | HCR_DC | HCR_TWI | HCR_TWE | + HCR_TID0 | HCR_TID2 | HCR_TPCP | HCR_TPU | + HCR_TDZ | HCR_CD | HCR_ID | HCR_MIOCNCE); + } else { + ret |= HCR_FMO | HCR_IMO | HCR_AMO; + } + ret &= ~(HCR_SWIO | HCR_PTW | HCR_VF | HCR_VI | HCR_VSE | + HCR_FB | HCR_TID1 | HCR_TID3 | HCR_TSC | HCR_TACR | + HCR_TSW | HCR_TTLB | HCR_TVM | HCR_HCD | HCR_TRVM | + HCR_TLOR); + } + + return ret; +} + static const ARMCPRegInfo el2_cp_reginfo[] = { { .name = "HCR_EL2", .state = ARM_CP_STATE_AA64, .type = ARM_CP_IO, @@ -4503,8 +4573,7 @@ int sve_exception_el(CPUARMState *env, int el) if (disabled) { /* route_to_el2 */ return (arm_feature(env, ARM_FEATURE_EL2) - && !arm_is_secure(env) - && (env->cp15.hcr_el2 & HCR_TGE) ? 2 : 1); + && (arm_hcr_el2_eff(env) & HCR_TGE) ? 2 : 1); } /* Check CPACR.FPEN. */ @@ -4956,6 +5025,42 @@ static uint64_t id_aa64pfr0_read(CPUARMState *env, const ARMCPRegInfo *ri) return pfr0; } +/* Shared logic between LORID and the rest of the LOR* registers. + * Secure state has already been delt with. + */ +static CPAccessResult access_lor_ns(CPUARMState *env) +{ + int el = arm_current_el(env); + + if (el < 2 && (arm_hcr_el2_eff(env) & HCR_TLOR)) { + return CP_ACCESS_TRAP_EL2; + } + if (el < 3 && (env->cp15.scr_el3 & SCR_TLOR)) { + return CP_ACCESS_TRAP_EL3; + } + return CP_ACCESS_OK; +} + +static CPAccessResult access_lorid(CPUARMState *env, const ARMCPRegInfo *ri, + bool isread) +{ + if (arm_is_secure_below_el3(env)) { + /* Access ok in secure mode. */ + return CP_ACCESS_OK; + } + return access_lor_ns(env); +} + +static CPAccessResult access_lor_other(CPUARMState *env, + const ARMCPRegInfo *ri, bool isread) +{ + if (arm_is_secure_below_el3(env)) { + /* Access denied in secure mode. */ + return CP_ACCESS_TRAP; + } + return access_lor_ns(env); +} + void register_cp_regs_for_features(ARMCPU *cpu) { /* Register all the coprocessor registers based on feature bits */ @@ -5207,11 +5312,11 @@ void register_cp_regs_for_features(ARMCPU *cpu) { .name = "ID_AA64MMFR0_EL1", .state = ARM_CP_STATE_AA64, .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 7, .opc2 = 0, .access = PL1_R, .type = ARM_CP_CONST, - .resetvalue = cpu->id_aa64mmfr0 }, + .resetvalue = cpu->isar.id_aa64mmfr0 }, { .name = "ID_AA64MMFR1_EL1", .state = ARM_CP_STATE_AA64, .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 7, .opc2 = 1, .access = PL1_R, .type = ARM_CP_CONST, - .resetvalue = cpu->id_aa64mmfr1 }, + .resetvalue = cpu->isar.id_aa64mmfr1 }, { .name = "ID_AA64MMFR2_EL1_RESERVED", .state = ARM_CP_STATE_AA64, .opc0 = 3, .opc1 = 0, .crn = 0, .crm = 7, .opc2 = 2, .access = PL1_R, .type = ARM_CP_CONST, @@ -5433,6 +5538,10 @@ void register_cp_regs_for_features(ARMCPU *cpu) } else { define_arm_cp_regs(cpu, vmsa_pmsa_cp_reginfo); define_arm_cp_regs(cpu, vmsa_cp_reginfo); + /* TTCBR2 is introduced with ARMv8.2-A32HPD. */ + if (FIELD_EX32(cpu->id_mmfr4, ID_MMFR4, HPDS) != 0) { + define_one_arm_cp_reg(cpu, &ttbcr2_reginfo); + } } if (arm_feature(env, ARM_FEATURE_THUMB2EE)) { define_arm_cp_regs(cpu, t2ee_cp_reginfo); @@ -5693,6 +5802,38 @@ void register_cp_regs_for_features(ARMCPU *cpu) define_one_arm_cp_reg(cpu, &sctlr); } + if (cpu_isar_feature(aa64_lor, cpu)) { + /* + * A trivial implementation of ARMv8.1-LOR leaves all of these + * registers fixed at 0, which indicates that there are zero + * supported Limited Ordering regions. + */ + static const ARMCPRegInfo lor_reginfo[] = { + { .name = "LORSA_EL1", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 0, .crn = 10, .crm = 4, .opc2 = 0, + .access = PL1_RW, .accessfn = access_lor_other, + .type = ARM_CP_CONST, .resetvalue = 0 }, + { .name = "LOREA_EL1", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 0, .crn = 10, .crm = 4, .opc2 = 1, + .access = PL1_RW, .accessfn = access_lor_other, + .type = ARM_CP_CONST, .resetvalue = 0 }, + { .name = "LORN_EL1", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 0, .crn = 10, .crm = 4, .opc2 = 2, + .access = PL1_RW, .accessfn = access_lor_other, + .type = ARM_CP_CONST, .resetvalue = 0 }, + { .name = "LORC_EL1", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 0, .crn = 10, .crm = 4, .opc2 = 3, + .access = PL1_RW, .accessfn = access_lor_other, + .type = ARM_CP_CONST, .resetvalue = 0 }, + { .name = "LORID_EL1", .state = ARM_CP_STATE_AA64, + .opc0 = 3, .opc1 = 0, .crn = 10, .crm = 4, .opc2 = 7, + .access = PL1_R, .accessfn = access_lorid, + .type = ARM_CP_CONST, .resetvalue = 0 }, + REGINFO_SENTINEL + }; + define_arm_cp_regs(cpu, lor_reginfo); + } + if (cpu_isar_feature(aa64_sve, cpu)) { define_one_arm_cp_reg(cpu, &zcr_el1_reginfo); if (arm_feature(env, ARM_FEATURE_EL2)) { @@ -6149,9 +6290,8 @@ static int bad_mode_switch(CPUARMState *env, int mode, CPSRWriteType write_type) * and CPS are treated as illegal mode changes. */ if (write_type == CPSRWriteByInstr && - (env->cp15.hcr_el2 & HCR_TGE) && (env->uncached_cpsr & CPSR_M) == ARM_CPU_MODE_MON && - !arm_is_secure_below_el3(env)) { + (arm_hcr_el2_eff(env) & HCR_TGE)) { return 1; } return 0; @@ -6505,12 +6645,13 @@ uint32_t arm_phys_excp_target_el(CPUState *cs, uint32_t excp_idx, uint32_t cur_el, bool secure) { CPUARMState *env = cs->env_ptr; - int rw; - int scr; - int hcr; + bool rw; + bool scr; + bool hcr; int target_el; /* Is the highest EL AArch64? */ - int is64 = arm_feature(env, ARM_FEATURE_AARCH64); + bool is64 = arm_feature(env, ARM_FEATURE_AARCH64); + uint64_t hcr_el2; if (arm_feature(env, ARM_FEATURE_EL3)) { rw = ((env->cp15.scr_el3 & SCR_RW) == SCR_RW); @@ -6522,24 +6663,22 @@ uint32_t arm_phys_excp_target_el(CPUState *cs, uint32_t excp_idx, rw = is64; } + hcr_el2 = arm_hcr_el2_eff(env); switch (excp_idx) { case EXCP_IRQ: scr = ((env->cp15.scr_el3 & SCR_IRQ) == SCR_IRQ); - hcr = arm_hcr_el2_imo(env); + hcr = hcr_el2 & HCR_IMO; break; case EXCP_FIQ: scr = ((env->cp15.scr_el3 & SCR_FIQ) == SCR_FIQ); - hcr = arm_hcr_el2_fmo(env); + hcr = hcr_el2 & HCR_FMO; break; default: scr = ((env->cp15.scr_el3 & SCR_EA) == SCR_EA); - hcr = arm_hcr_el2_amo(env); + hcr = hcr_el2 & HCR_AMO; break; }; - /* If HCR.TGE is set then HCR is treated as being 1 */ - hcr |= ((env->cp15.hcr_el2 & HCR_TGE) == HCR_TGE); - /* Perform a table-lookup for the target EL given the current state */ target_el = target_el_table[is64][scr][rw][hcr][secure][cur_el]; @@ -9635,6 +9774,7 @@ static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address, bool ttbr1_valid = true; uint64_t descaddrmask; bool aarch64 = arm_el_is_aa64(env, el); + bool hpd = false; /* TODO: * This code does not handle the different format TCR for VTCR_EL2. @@ -9749,6 +9889,15 @@ static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address, if (tg == 2) { /* 16KB pages */ stride = 11; } + if (aarch64 && el > 1) { + hpd = extract64(tcr->raw_tcr, 24, 1); + } else { + hpd = extract64(tcr->raw_tcr, 41, 1); + } + if (!aarch64) { + /* For aarch32, hpd0 is not enabled without t2e as well. */ + hpd &= extract64(tcr->raw_tcr, 6, 1); + } } else { /* We should only be here if TTBR1 is valid */ assert(ttbr1_valid); @@ -9764,6 +9913,11 @@ static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address, if (tg == 1) { /* 16KB pages */ stride = 11; } + hpd = extract64(tcr->raw_tcr, 42, 1); + if (!aarch64) { + /* For aarch32, hpd1 is not enabled without t2e as well. */ + hpd &= extract64(tcr->raw_tcr, 6, 1); + } } /* Here we should have set up all the parameters for the translation: @@ -9857,7 +10011,7 @@ static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address, descaddr = descriptor & descaddrmask; if ((descriptor & 2) && (level < 3)) { - /* Table entry. The top five bits are attributes which may + /* Table entry. The top five bits are attributes which may * propagate down through lower levels of the table (and * which are all arranged so that 0 means "no effect", so * we can gather them up by ORing in the bits at each level). @@ -9882,15 +10036,17 @@ static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address, break; } /* Merge in attributes from table descriptors */ - attrs |= extract32(tableattrs, 0, 2) << 11; /* XN, PXN */ - attrs |= extract32(tableattrs, 3, 1) << 5; /* APTable[1] => AP[2] */ + attrs |= nstable << 3; /* NS */ + if (hpd) { + /* HPD disables all the table attributes except NSTable. */ + break; + } + attrs |= extract32(tableattrs, 0, 2) << 11; /* XN, PXN */ /* The sense of AP[1] vs APTable[0] is reversed, as APTable[0] == 1 * means "force PL1 access only", which means forcing AP[1] to 0. */ - if (extract32(tableattrs, 2, 1)) { - attrs &= ~(1 << 4); - } - attrs |= nstable << 3; /* NS */ + attrs &= ~(extract32(tableattrs, 2, 1) << 4); /* !APT[0] => AP[1] */ + attrs |= extract32(tableattrs, 3, 1) << 5; /* APT[1] => AP[2] */ break; } /* Here descaddr is the final physical address, and attributes diff --git a/target/arm/internals.h b/target/arm/internals.h index d208b70a64..78e026d6e9 100644 --- a/target/arm/internals.h +++ b/target/arm/internals.h @@ -229,7 +229,8 @@ static inline unsigned int arm_pamax(ARMCPU *cpu) [4] = 44, [5] = 48, }; - unsigned int parange = extract32(cpu->id_aa64mmfr0, 0, 4); + unsigned int parange = + FIELD_EX64(cpu->isar.id_aa64mmfr0, ID_AA64MMFR0, PARANGE); /* id_aa64mmfr0 is a read-only register so values outside of the * supported mappings can be considered an implementation error. */ diff --git a/target/arm/kvm64.c b/target/arm/kvm64.c index 0a502091e7..089af9c5f0 100644 --- a/target/arm/kvm64.c +++ b/target/arm/kvm64.c @@ -538,6 +538,10 @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf) ARM64_SYS_REG(3, 0, 0, 6, 0)); err |= read_sys_reg64(fdarray[2], &ahcf->isar.id_aa64isar1, ARM64_SYS_REG(3, 0, 0, 6, 1)); + err |= read_sys_reg64(fdarray[2], &ahcf->isar.id_aa64mmfr0, + ARM64_SYS_REG(3, 0, 0, 7, 0)); + err |= read_sys_reg64(fdarray[2], &ahcf->isar.id_aa64mmfr1, + ARM64_SYS_REG(3, 0, 0, 7, 1)); /* * Note that if AArch32 support is not present in the host, diff --git a/target/arm/op_helper.c b/target/arm/op_helper.c index 0d6e89e474..ef72361a36 100644 --- a/target/arm/op_helper.c +++ b/target/arm/op_helper.c @@ -33,8 +33,7 @@ void raise_exception(CPUARMState *env, uint32_t excp, { CPUState *cs = CPU(arm_env_get_cpu(env)); - if ((env->cp15.hcr_el2 & HCR_TGE) && - target_el == 1 && !arm_is_secure(env)) { + if (target_el == 1 && (arm_hcr_el2_eff(env) & HCR_TGE)) { /* * Redirect NS EL1 exceptions to NS EL2. These are reported with * their original syndrome register value, with the exception of @@ -428,9 +427,9 @@ static inline int check_wfx_trap(CPUARMState *env, bool is_wfe) * No need for ARM_FEATURE check as if HCR_EL2 doesn't exist the * bits will be zero indicating no trap. */ - if (cur_el < 2 && !arm_is_secure(env)) { - mask = (is_wfe) ? HCR_TWE : HCR_TWI; - if (env->cp15.hcr_el2 & mask) { + if (cur_el < 2) { + mask = is_wfe ? HCR_TWE : HCR_TWI; + if (arm_hcr_el2_eff(env) & mask) { return 2; } } @@ -995,7 +994,7 @@ void HELPER(pre_smc)(CPUARMState *env, uint32_t syndrome) exception_target_el(env)); } - if (!secure && cur_el == 1 && (env->cp15.hcr_el2 & HCR_TSC)) { + if (cur_el == 1 && (arm_hcr_el2_eff(env) & HCR_TSC)) { /* In NS EL1, HCR controlled routing to EL2 has priority over SMD. * We also want an EL2 guest to be able to forbid its EL1 from * making PSCI calls into QEMU's "firmware" via HCR.TSC. @@ -1098,8 +1097,7 @@ void HELPER(exception_return)(CPUARMState *env) goto illegal_return; } - if (new_el == 1 && (env->cp15.hcr_el2 & HCR_TGE) - && !arm_is_secure_below_el3(env)) { + if (new_el == 1 && (arm_hcr_el2_eff(env) & HCR_TGE)) { goto illegal_return; } diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c index fd36425f1a..e1da1e4d6f 100644 --- a/target/arm/translate-a64.c +++ b/target/arm/translate-a64.c @@ -2290,6 +2290,12 @@ static void disas_ldst_excl(DisasContext *s, uint32_t insn) } return; + case 0x8: /* STLLR */ + if (!dc_isar_feature(aa64_lor, s)) { + break; + } + /* StoreLORelease is the same as Store-Release for QEMU. */ + /* fall through */ case 0x9: /* STLR */ /* Generate ISS for non-exclusive accesses including LASR. */ if (rn == 31) { @@ -2301,6 +2307,12 @@ static void disas_ldst_excl(DisasContext *s, uint32_t insn) disas_ldst_compute_iss_sf(size, false, 0), is_lasr); return; + case 0xc: /* LDLAR */ + if (!dc_isar_feature(aa64_lor, s)) { + break; + } + /* LoadLOAcquire is the same as Load-Acquire for QEMU. */ + /* fall through */ case 0xd: /* LDAR */ /* Generate ISS for non-exclusive accesses including LASR. */ if (rn == 31) { @@ -230,11 +230,9 @@ typedef uint64_t tcg_insn_unit; #if defined CONFIG_DEBUG_TCG || defined QEMU_STATIC_ANALYSIS # define tcg_debug_assert(X) do { assert(X); } while (0) -#elif QEMU_GNUC_PREREQ(4, 5) +#else # define tcg_debug_assert(X) \ do { if (!(X)) { __builtin_unreachable(); } } while (0) -#else -# define tcg_debug_assert(X) do { (void)(X); } while (0) #endif typedef struct TCGRelocation { diff --git a/tests/test-crypto-block.c b/tests/test-crypto-block.c index fae4ffc453..d309d044ef 100644 --- a/tests/test-crypto-block.c +++ b/tests/test-crypto-block.c @@ -305,6 +305,7 @@ static void test_block(gconstpointer opaque) test_block_read_func, &header, 0, + 1, NULL); g_assert(blk == NULL); @@ -313,6 +314,7 @@ static void test_block(gconstpointer opaque) test_block_read_func, &header, QCRYPTO_BLOCK_OPEN_NO_IO, + 1, &error_abort); g_assert(qcrypto_block_get_cipher(blk) == NULL); @@ -327,6 +329,7 @@ static void test_block(gconstpointer opaque) test_block_read_func, &header, 0, + 1, &error_abort); g_assert(blk); diff --git a/trace/simple.c b/trace/simple.c index 701dec639c..ac904eca91 100644 --- a/trace/simple.c +++ b/trace/simple.c @@ -169,9 +169,9 @@ static gpointer writeout_thread(gpointer opaque) wait_for_trace_records_available(); if (g_atomic_int_get(&dropped_events)) { - dropped.rec.event = DROPPED_EVENT_ID, + dropped.rec.event = DROPPED_EVENT_ID; dropped.rec.timestamp_ns = get_clock(); - dropped.rec.length = sizeof(TraceRecord) + sizeof(uint64_t), + dropped.rec.length = sizeof(TraceRecord) + sizeof(uint64_t); dropped.rec.pid = trace_pid; do { dropped_count = g_atomic_int_get(&dropped_events); |