Merge tag 'pull-loongarch-20240320' of https://gitlab.com/gaosong/qemu into staging
pull-loongarch-20240320
# -----BEGIN PGP SIGNATURE-----
#
# iLMEAAEKAB0WIQS4/x2g0v3LLaCcbCxAov/yOSY+3wUCZfpIrAAKCRBAov/yOSY+
# 35awBADHgwP1HHS+fo4myPqDzcH2JMiGH9ra3ORSvEe036whqdttzx4tkxey7sTj
# 2QKd326tUJ1jBxnVabN9on0csM4xl6AGBBjRTmEEBaCFp0Nulu4W4tMxeTTdfkZK
# jUUs+1VVQLwmcFULGtbB91uiYF7RsJzVIBpAD5oVe/pF9046Hg==
# =Y6la
# -----END PGP SIGNATURE-----
# gpg: Signature made Wed 20 Mar 2024 02:23:40 GMT
# gpg: using RSA key B8FF1DA0D2FDCB2DA09C6C2C40A2FFF239263EDF
# gpg: Good signature from "Song Gao <m17746591750@163.com>" [unknown]
# gpg: WARNING: This key is not certified with a trusted signature!
# gpg: There is no indication that the signature belongs to the owner.
# Primary key fingerprint: B8FF 1DA0 D2FD CB2D A09C 6C2C 40A2 FFF2 3926 3EDF
* tag 'pull-loongarch-20240320' of https://gitlab.com/gaosong/qemu:
target/loongarch: Fix qemu-loongarch64 hang when executing 'll.d $t0, $t0, 0'
target/loongarch: Fix tlb huge page loading issue
hw/intc/loongarch_extioi: Fix interrupt routing update
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
diff --git a/chardev/char-io.c b/chardev/char-io.c
index 4451128..dab77b1 100644
--- a/chardev/char-io.c
+++ b/chardev/char-io.c
@@ -33,6 +33,7 @@
IOCanReadHandler *fd_can_read;
GSourceFunc fd_read;
void *opaque;
+ GMainContext *context;
} IOWatchPoll;
static IOWatchPoll *io_watch_poll_from_source(GSource *source)
@@ -50,28 +51,59 @@
return FALSE;
}
+ /*
+ * We do not register the QIOChannel watch as a child GSource.
+ * The 'prepare' function on the parent GSource will be
+ * skipped if a child GSource's 'prepare' function indicates
+ * readiness. We need this prepare function be guaranteed
+ * to run on *every* iteration of the main loop, because
+ * it is critical to ensure we remove the QIOChannel watch
+ * if 'fd_can_read' indicates the frontend cannot receive
+ * more data.
+ */
if (now_active) {
iwp->src = qio_channel_create_watch(
iwp->ioc, G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL);
g_source_set_callback(iwp->src, iwp->fd_read, iwp->opaque, NULL);
- g_source_add_child_source(source, iwp->src);
- g_source_unref(iwp->src);
+ g_source_attach(iwp->src, iwp->context);
} else {
- g_source_remove_child_source(source, iwp->src);
+ g_source_destroy(iwp->src);
+ g_source_unref(iwp->src);
iwp->src = NULL;
}
return FALSE;
}
+static gboolean io_watch_poll_check(GSource *source)
+{
+ return FALSE;
+}
+
static gboolean io_watch_poll_dispatch(GSource *source, GSourceFunc callback,
gpointer user_data)
{
- return G_SOURCE_CONTINUE;
+ abort();
+}
+
+static void io_watch_poll_finalize(GSource *source)
+{
+ /*
+ * Due to a glib bug, removing the last reference to a source
+ * inside a finalize callback causes recursive locking (and a
+ * deadlock). This is not a problem inside other callbacks,
+ * including dispatch callbacks, so we call io_remove_watch_poll
+ * to remove this source. At this point, iwp->src must
+ * be NULL, or we would leak it.
+ */
+ IOWatchPoll *iwp = io_watch_poll_from_source(source);
+ assert(iwp->src == NULL);
}
static GSourceFuncs io_watch_poll_funcs = {
.prepare = io_watch_poll_prepare,
+ .check = io_watch_poll_check,
.dispatch = io_watch_poll_dispatch,
+ .finalize = io_watch_poll_finalize,
};
GSource *io_add_watch_poll(Chardev *chr,
@@ -91,6 +123,7 @@
iwp->ioc = ioc;
iwp->fd_read = (GSourceFunc) fd_read;
iwp->src = NULL;
+ iwp->context = context;
name = g_strdup_printf("chardev-iowatch-%s", chr->label);
g_source_set_name((GSource *)iwp, name);
@@ -101,10 +134,23 @@
return (GSource *)iwp;
}
+static void io_remove_watch_poll(GSource *source)
+{
+ IOWatchPoll *iwp;
+
+ iwp = io_watch_poll_from_source(source);
+ if (iwp->src) {
+ g_source_destroy(iwp->src);
+ g_source_unref(iwp->src);
+ iwp->src = NULL;
+ }
+ g_source_destroy(&iwp->parent);
+}
+
void remove_fd_in_watch(Chardev *chr)
{
if (chr->gsource) {
- g_source_destroy(chr->gsource);
+ io_remove_watch_poll(chr->gsource);
chr->gsource = NULL;
}
}
diff --git a/chardev/char-socket.c b/chardev/char-socket.c
index 8a0406c..812d7aa 100644
--- a/chardev/char-socket.c
+++ b/chardev/char-socket.c
@@ -496,9 +496,9 @@
s->max_size <= 0) {
return TRUE;
}
- len = tcp_chr_read_poll(opaque);
- if (len > sizeof(buf)) {
- len = sizeof(buf);
+ len = sizeof(buf);
+ if (len > s->max_size) {
+ len = s->max_size;
}
size = tcp_chr_recv(chr, (void *)buf, len);
if (size == 0 || (size == -1 && errno != EAGAIN)) {
@@ -601,6 +601,22 @@
remove_hup_source(s);
s->hup_source = qio_channel_create_watch(s->ioc, G_IO_HUP);
+ /*
+ * poll() is liable to return POLLHUP even when there is
+ * still incoming data available to read on the FD. If
+ * we have the hup_source at the same priority as the
+ * main io_add_watch_poll GSource, then we might end up
+ * processing the POLLHUP event first, closing the FD,
+ * and as a result silently discard data we should have
+ * read.
+ *
+ * By setting the hup_source to G_PRIORITY_DEFAULT + 1,
+ * we ensure that io_add_watch_poll GSource will always
+ * be dispatched first, thus guaranteeing we will be
+ * able to process all incoming data before closing the
+ * FD
+ */
+ g_source_set_priority(s->hup_source, G_PRIORITY_DEFAULT + 1);
g_source_set_callback(s->hup_source, (GSourceFunc)tcp_chr_hup,
chr, NULL);
g_source_attach(s->hup_source, chr->gcontext);
diff --git a/crypto/cipher-gcrypt.c.inc b/crypto/cipher-gcrypt.c.inc
index 1377cba..4a83147 100644
--- a/crypto/cipher-gcrypt.c.inc
+++ b/crypto/cipher-gcrypt.c.inc
@@ -20,6 +20,56 @@
#include <gcrypt.h>
+static int qcrypto_cipher_alg_to_gcry_alg(QCryptoCipherAlgorithm alg)
+{
+ switch (alg) {
+ case QCRYPTO_CIPHER_ALG_DES:
+ return GCRY_CIPHER_DES;
+ case QCRYPTO_CIPHER_ALG_3DES:
+ return GCRY_CIPHER_3DES;
+ case QCRYPTO_CIPHER_ALG_AES_128:
+ return GCRY_CIPHER_AES128;
+ case QCRYPTO_CIPHER_ALG_AES_192:
+ return GCRY_CIPHER_AES192;
+ case QCRYPTO_CIPHER_ALG_AES_256:
+ return GCRY_CIPHER_AES256;
+ case QCRYPTO_CIPHER_ALG_CAST5_128:
+ return GCRY_CIPHER_CAST5;
+ case QCRYPTO_CIPHER_ALG_SERPENT_128:
+ return GCRY_CIPHER_SERPENT128;
+ case QCRYPTO_CIPHER_ALG_SERPENT_192:
+ return GCRY_CIPHER_SERPENT192;
+ case QCRYPTO_CIPHER_ALG_SERPENT_256:
+ return GCRY_CIPHER_SERPENT256;
+ case QCRYPTO_CIPHER_ALG_TWOFISH_128:
+ return GCRY_CIPHER_TWOFISH128;
+ case QCRYPTO_CIPHER_ALG_TWOFISH_256:
+ return GCRY_CIPHER_TWOFISH;
+#ifdef CONFIG_CRYPTO_SM4
+ case QCRYPTO_CIPHER_ALG_SM4:
+ return GCRY_CIPHER_SM4;
+#endif
+ default:
+ return GCRY_CIPHER_NONE;
+ }
+}
+
+static int qcrypto_cipher_mode_to_gcry_mode(QCryptoCipherMode mode)
+{
+ switch (mode) {
+ case QCRYPTO_CIPHER_MODE_ECB:
+ return GCRY_CIPHER_MODE_ECB;
+ case QCRYPTO_CIPHER_MODE_XTS:
+ return GCRY_CIPHER_MODE_XTS;
+ case QCRYPTO_CIPHER_MODE_CBC:
+ return GCRY_CIPHER_MODE_CBC;
+ case QCRYPTO_CIPHER_MODE_CTR:
+ return GCRY_CIPHER_MODE_CTR;
+ default:
+ return GCRY_CIPHER_MODE_NONE;
+ }
+}
+
bool qcrypto_cipher_supports(QCryptoCipherAlgorithm alg,
QCryptoCipherMode mode)
{
@@ -43,6 +93,11 @@
return false;
}
+ if (gcry_cipher_algo_info(qcrypto_cipher_alg_to_gcry_alg(alg),
+ GCRYCTL_TEST_ALGO, NULL, NULL) != 0) {
+ return false;
+ }
+
switch (mode) {
case QCRYPTO_CIPHER_MODE_ECB:
case QCRYPTO_CIPHER_MODE_CBC:
@@ -188,72 +243,26 @@
return NULL;
}
- switch (alg) {
- case QCRYPTO_CIPHER_ALG_DES:
- gcryalg = GCRY_CIPHER_DES;
- break;
- case QCRYPTO_CIPHER_ALG_3DES:
- gcryalg = GCRY_CIPHER_3DES;
- break;
- case QCRYPTO_CIPHER_ALG_AES_128:
- gcryalg = GCRY_CIPHER_AES128;
- break;
- case QCRYPTO_CIPHER_ALG_AES_192:
- gcryalg = GCRY_CIPHER_AES192;
- break;
- case QCRYPTO_CIPHER_ALG_AES_256:
- gcryalg = GCRY_CIPHER_AES256;
- break;
- case QCRYPTO_CIPHER_ALG_CAST5_128:
- gcryalg = GCRY_CIPHER_CAST5;
- break;
- case QCRYPTO_CIPHER_ALG_SERPENT_128:
- gcryalg = GCRY_CIPHER_SERPENT128;
- break;
- case QCRYPTO_CIPHER_ALG_SERPENT_192:
- gcryalg = GCRY_CIPHER_SERPENT192;
- break;
- case QCRYPTO_CIPHER_ALG_SERPENT_256:
- gcryalg = GCRY_CIPHER_SERPENT256;
- break;
- case QCRYPTO_CIPHER_ALG_TWOFISH_128:
- gcryalg = GCRY_CIPHER_TWOFISH128;
- break;
- case QCRYPTO_CIPHER_ALG_TWOFISH_256:
- gcryalg = GCRY_CIPHER_TWOFISH;
- break;
-#ifdef CONFIG_CRYPTO_SM4
- case QCRYPTO_CIPHER_ALG_SM4:
- gcryalg = GCRY_CIPHER_SM4;
- break;
-#endif
- default:
+ gcryalg = qcrypto_cipher_alg_to_gcry_alg(alg);
+ if (gcryalg == GCRY_CIPHER_NONE) {
error_setg(errp, "Unsupported cipher algorithm %s",
QCryptoCipherAlgorithm_str(alg));
return NULL;
}
- drv = &qcrypto_gcrypt_driver;
- switch (mode) {
- case QCRYPTO_CIPHER_MODE_ECB:
- gcrymode = GCRY_CIPHER_MODE_ECB;
- break;
- case QCRYPTO_CIPHER_MODE_XTS:
- gcrymode = GCRY_CIPHER_MODE_XTS;
- break;
- case QCRYPTO_CIPHER_MODE_CBC:
- gcrymode = GCRY_CIPHER_MODE_CBC;
- break;
- case QCRYPTO_CIPHER_MODE_CTR:
- drv = &qcrypto_gcrypt_ctr_driver;
- gcrymode = GCRY_CIPHER_MODE_CTR;
- break;
- default:
+ gcrymode = qcrypto_cipher_mode_to_gcry_mode(mode);
+ if (gcrymode == GCRY_CIPHER_MODE_NONE) {
error_setg(errp, "Unsupported cipher mode %s",
QCryptoCipherMode_str(mode));
return NULL;
}
+ if (mode == QCRYPTO_CIPHER_MODE_CTR) {
+ drv = &qcrypto_gcrypt_ctr_driver;
+ } else {
+ drv = &qcrypto_gcrypt_driver;
+ }
+
ctx = g_new0(QCryptoCipherGcrypt, 1);
ctx->base.driver = drv;
diff --git a/system/qemu-seccomp.c b/system/qemu-seccomp.c
index 4d7439e..98ffce0 100644
--- a/system/qemu-seccomp.c
+++ b/system/qemu-seccomp.c
@@ -74,7 +74,7 @@
#define RULE_CLONE_FLAG(flag) \
{ SCMP_SYS(clone), QEMU_SECCOMP_SET_SPAWN, \
- ARRAY_SIZE(clone_arg ## flag), clone_arg ## flag, SCMP_ACT_TRAP }
+ ARRAY_SIZE(clone_arg ## flag), clone_arg ## flag, SCMP_ACT_ERRNO(EPERM) }
/* If no CLONE_* flags are set, except CSIGNAL, deny */
const struct scmp_arg_cmp clone_arg_none[] = {
@@ -214,13 +214,13 @@
0, NULL, SCMP_ACT_TRAP },
/* spawn */
{ SCMP_SYS(fork), QEMU_SECCOMP_SET_SPAWN,
- 0, NULL, SCMP_ACT_TRAP },
+ 0, NULL, SCMP_ACT_ERRNO(EPERM) },
{ SCMP_SYS(vfork), QEMU_SECCOMP_SET_SPAWN,
- 0, NULL, SCMP_ACT_TRAP },
+ 0, NULL, SCMP_ACT_ERRNO(EPERM) },
{ SCMP_SYS(execve), QEMU_SECCOMP_SET_SPAWN,
- 0, NULL, SCMP_ACT_TRAP },
+ 0, NULL, SCMP_ACT_ERRNO(EPERM) },
{ SCMP_SYS(clone), QEMU_SECCOMP_SET_SPAWN,
- ARRAY_SIZE(clone_arg_none), clone_arg_none, SCMP_ACT_TRAP },
+ ARRAY_SIZE(clone_arg_none), clone_arg_none, SCMP_ACT_ERRNO(EPERM) },
RULE_CLONE_FLAG(CLONE_VM),
RULE_CLONE_FLAG(CLONE_FS),
RULE_CLONE_FLAG(CLONE_FILES),
diff --git a/target/hppa/insns.decode b/target/hppa/insns.decode
index f5a3f02..f58455d 100644
--- a/target/hppa/insns.decode
+++ b/target/hppa/insns.decode
@@ -24,16 +24,17 @@
%assemble_sr3 13:1 14:2
%assemble_sr3x 13:1 14:2 !function=expand_sr3x
-%assemble_11a 0:s1 4:10 !function=expand_shl3
+%assemble_11a 4:12 0:1 !function=expand_11a
%assemble_12 0:s1 2:1 3:10 !function=expand_shl2
-%assemble_12a 0:s1 3:11 !function=expand_shl2
+%assemble_12a 3:13 0:1 !function=expand_12a
+%assemble_16 0:16 !function=expand_16
%assemble_17 0:s1 16:5 2:1 3:10 !function=expand_shl2
%assemble_22 0:s1 16:10 2:1 3:10 !function=expand_shl2
+%assemble_sp 14:2 !function=sp0_if_wide
%assemble_21 0:s1 1:11 14:2 16:5 12:2 !function=expand_shl11
%lowsign_11 0:s1 1:10
-%lowsign_14 0:s1 1:13
%sm_imm 16:10 !function=expand_sm_imm
@@ -143,9 +144,9 @@
nop 000001 ----- ----- -- 11001010 0 ----- # fdc, disp
nop_addrx 000001 ..... ..... -- 01001010 . ----- @addrx # fdc, index
nop_addrx 000001 ..... ..... -- 01001011 . ----- @addrx # fdce
-nop_addrx 000001 ..... ..... --- 0001010 . ----- @addrx # fic 0x0a
-nop_addrx 000001 ..... ..... -- 01001111 . 00000 @addrx # fic 0x4f
-nop_addrx 000001 ..... ..... --- 0001011 . ----- @addrx # fice
+fic 000001 ..... ..... --- 0001010 . ----- @addrx # fic 0x0a
+fic 000001 ..... ..... -- 01001111 . 00000 @addrx # fic 0x4f
+fic 000001 ..... ..... --- 0001011 . ----- @addrx # fice
nop_addrx 000001 ..... ..... -- 01001110 . 00000 @addrx # pdc
probe 000001 b:5 ri:5 sp:2 imm:1 100011 write:1 0 t:5
@@ -221,7 +222,7 @@
ldil 001000 t:5 ..................... i=%assemble_21
addil 001010 r:5 ..................... i=%assemble_21
-ldo 001101 b:5 t:5 -- .............. i=%lowsign_14
+ldo 001101 b:5 t:5 ................ i=%assemble_16
addi 101101 ..... ..... .... 0 ........... @rri_cf
addi_tsv 101101 ..... ..... .... 1 ........... @rri_cf
@@ -304,14 +305,18 @@
# Offset Mem
####
-@ldstim11 ...... b:5 t:5 sp:2 .............. \
- &ldst disp=%assemble_11a m=%ma2_to_m x=0 scale=0 size=3
-@ldstim14 ...... b:5 t:5 sp:2 .............. \
- &ldst disp=%lowsign_14 x=0 scale=0 m=0
-@ldstim14m ...... b:5 t:5 sp:2 .............. \
- &ldst disp=%lowsign_14 x=0 scale=0 m=%neg_to_m
-@ldstim12m ...... b:5 t:5 sp:2 .............. \
- &ldst disp=%assemble_12a x=0 scale=0 m=%pos_to_m
+@ldstim11 ...... b:5 t:5 ................ \
+ &ldst sp=%assemble_sp disp=%assemble_11a \
+ m=%ma2_to_m x=0 scale=0 size=3
+@ldstim14 ...... b:5 t:5 ................ \
+ &ldst sp=%assemble_sp disp=%assemble_16 \
+ x=0 scale=0 m=0
+@ldstim14m ...... b:5 t:5 ................ \
+ &ldst sp=%assemble_sp disp=%assemble_16 \
+ x=0 scale=0 m=%neg_to_m
+@ldstim12m ...... b:5 t:5 ................ \
+ &ldst sp=%assemble_sp disp=%assemble_12a \
+ x=0 scale=0 m=%pos_to_m
# LDB, LDH, LDW, LDWM
ld 010000 ..... ..... .. .............. @ldstim14 size=0
@@ -327,15 +332,19 @@
st 011011 ..... ..... .. .............. @ldstim14m size=2
st 011111 ..... ..... .. ...........10. @ldstim12m size=2
-fldw 010110 b:5 ..... sp:2 .............. \
- &ldst disp=%assemble_12a t=%rm64 m=%a_to_m x=0 scale=0 size=2
-fldw 010111 b:5 ..... sp:2 ...........0.. \
- &ldst disp=%assemble_12a t=%rm64 m=0 x=0 scale=0 size=2
+fldw 010110 b:5 ..... ................ \
+ &ldst disp=%assemble_12a sp=%assemble_sp \
+ t=%rm64 m=%a_to_m x=0 scale=0 size=2
+fldw 010111 b:5 ..... .............0.. \
+ &ldst disp=%assemble_12a sp=%assemble_sp \
+ t=%rm64 m=0 x=0 scale=0 size=2
-fstw 011110 b:5 ..... sp:2 .............. \
- &ldst disp=%assemble_12a t=%rm64 m=%a_to_m x=0 scale=0 size=2
-fstw 011111 b:5 ..... sp:2 ...........0.. \
- &ldst disp=%assemble_12a t=%rm64 m=0 x=0 scale=0 size=2
+fstw 011110 b:5 ..... ................ \
+ &ldst disp=%assemble_12a sp=%assemble_sp \
+ t=%rm64 m=%a_to_m x=0 scale=0 size=2
+fstw 011111 b:5 ..... .............0.. \
+ &ldst disp=%assemble_12a sp=%assemble_sp \
+ t=%rm64 m=0 x=0 scale=0 size=2
ld 010100 ..... ..... .. ............0. @ldstim11
fldd 010100 ..... ..... .. ............1. @ldstim11
diff --git a/target/hppa/mem_helper.c b/target/hppa/mem_helper.c
index 80f51e7..84785b5 100644
--- a/target/hppa/mem_helper.c
+++ b/target/hppa/mem_helper.c
@@ -152,6 +152,49 @@
return ent;
}
+#define ACCESS_ID_MASK 0xffff
+
+/* Return the set of protections allowed by a PID match. */
+static int match_prot_id_1(uint32_t access_id, uint32_t prot_id)
+{
+ if (((access_id ^ (prot_id >> 1)) & ACCESS_ID_MASK) == 0) {
+ return (prot_id & 1
+ ? PAGE_EXEC | PAGE_READ
+ : PAGE_EXEC | PAGE_READ | PAGE_WRITE);
+ }
+ return 0;
+}
+
+static int match_prot_id32(CPUHPPAState *env, uint32_t access_id)
+{
+ int r, i;
+
+ for (i = CR_PID1; i <= CR_PID4; ++i) {
+ r = match_prot_id_1(access_id, env->cr[i]);
+ if (r) {
+ return r;
+ }
+ }
+ return 0;
+}
+
+static int match_prot_id64(CPUHPPAState *env, uint32_t access_id)
+{
+ int r, i;
+
+ for (i = CR_PID1; i <= CR_PID4; ++i) {
+ r = match_prot_id_1(access_id, env->cr[i]);
+ if (r) {
+ return r;
+ }
+ r = match_prot_id_1(access_id, env->cr[i] >> 32);
+ if (r) {
+ return r;
+ }
+ }
+ return 0;
+}
+
int hppa_get_physical_address(CPUHPPAState *env, vaddr addr, int mmu_idx,
int type, hwaddr *pphys, int *pprot,
HPPATLBEntry **tlb_entry)
@@ -224,29 +267,30 @@
break;
}
- /* access_id == 0 means public page and no check is performed */
- if (ent->access_id && MMU_IDX_TO_P(mmu_idx)) {
- /* If bits [31:1] match, and bit 0 is set, suppress write. */
- int match = ent->access_id * 2 + 1;
-
- if (match == env->cr[CR_PID1] || match == env->cr[CR_PID2] ||
- match == env->cr[CR_PID3] || match == env->cr[CR_PID4]) {
- prot &= PAGE_READ | PAGE_EXEC;
- if (type == PAGE_WRITE) {
- ret = EXCP_DMPI;
- goto egress;
- }
- }
- }
-
- /* No guest access type indicates a non-architectural access from
- within QEMU. Bypass checks for access, D, B and T bits. */
+ /*
+ * No guest access type indicates a non-architectural access from
+ * within QEMU. Bypass checks for access, D, B, P and T bits.
+ */
if (type == 0) {
goto egress;
}
+ /* access_id == 0 means public page and no check is performed */
+ if (ent->access_id && MMU_IDX_TO_P(mmu_idx)) {
+ int access_prot = (hppa_is_pa20(env)
+ ? match_prot_id64(env, ent->access_id)
+ : match_prot_id32(env, ent->access_id));
+ if (unlikely(!(type & access_prot))) {
+ /* Not allowed -- Inst/Data Memory Protection Id Fault. */
+ ret = type & PAGE_EXEC ? EXCP_IMP : EXCP_DMPI;
+ goto egress;
+ }
+ /* Otherwise exclude permissions not allowed (i.e WD). */
+ prot &= access_prot;
+ }
+
if (unlikely(!(prot & type))) {
- /* The access isn't allowed -- Inst/Data Memory Protection Fault. */
+ /* Not allowed -- Inst/Data Memory Access Rights Fault. */
ret = (type & PAGE_EXEC) ? EXCP_IMP : EXCP_DMAR;
goto egress;
}
diff --git a/target/hppa/op_helper.c b/target/hppa/op_helper.c
index 480fe80..6cf49f3 100644
--- a/target/hppa/op_helper.c
+++ b/target/hppa/op_helper.c
@@ -281,17 +281,17 @@
case 3:
/* The 3 byte store must appear atomic. */
if (parallel) {
- atomic_store_mask32(env, addr - 3, val, 0xffffff00u, ra);
+ atomic_store_mask32(env, addr - 3, val >> 32, 0xffffff00u, ra);
} else {
- cpu_stw_data_ra(env, addr - 3, val >> 16, ra);
- cpu_stb_data_ra(env, addr - 1, val >> 8, ra);
+ cpu_stw_data_ra(env, addr - 3, val >> 48, ra);
+ cpu_stb_data_ra(env, addr - 1, val >> 40, ra);
}
break;
case 2:
- cpu_stw_data_ra(env, addr - 2, val >> 16, ra);
+ cpu_stw_data_ra(env, addr - 2, val >> 48, ra);
break;
case 1:
- cpu_stb_data_ra(env, addr - 1, val >> 24, ra);
+ cpu_stb_data_ra(env, addr - 1, val >> 56, ra);
break;
default:
/* Nothing is stored, but protection is checked and the
diff --git a/target/hppa/translate.c b/target/hppa/translate.c
index eb2046c..19594f9 100644
--- a/target/hppa/translate.c
+++ b/target/hppa/translate.c
@@ -121,12 +121,6 @@
return val << 2;
}
-/* Used for fp memory ops. */
-static int expand_shl3(DisasContext *ctx, int val)
-{
- return val << 3;
-}
-
/* Used for assemble_21. */
static int expand_shl11(DisasContext *ctx, int val)
{
@@ -144,6 +138,62 @@
return (val ^ 31) + 1;
}
+/* Expander for assemble_16a(s,cat(im10a,0),i). */
+static int expand_11a(DisasContext *ctx, int val)
+{
+ /*
+ * @val is bit 0 and bits [4:15].
+ * Swizzle thing around depending on PSW.W.
+ */
+ int im10a = extract32(val, 1, 10);
+ int s = extract32(val, 11, 2);
+ int i = (-(val & 1) << 13) | (im10a << 3);
+
+ if (ctx->tb_flags & PSW_W) {
+ i ^= s << 13;
+ }
+ return i;
+}
+
+/* Expander for assemble_16a(s,im11a,i). */
+static int expand_12a(DisasContext *ctx, int val)
+{
+ /*
+ * @val is bit 0 and bits [3:15].
+ * Swizzle thing around depending on PSW.W.
+ */
+ int im11a = extract32(val, 1, 11);
+ int s = extract32(val, 12, 2);
+ int i = (-(val & 1) << 13) | (im11a << 2);
+
+ if (ctx->tb_flags & PSW_W) {
+ i ^= s << 13;
+ }
+ return i;
+}
+
+/* Expander for assemble_16(s,im14). */
+static int expand_16(DisasContext *ctx, int val)
+{
+ /*
+ * @val is bits [0:15], containing both im14 and s.
+ * Swizzle thing around depending on PSW.W.
+ */
+ int s = extract32(val, 14, 2);
+ int i = (-(val & 1) << 13) | extract32(val, 1, 13);
+
+ if (ctx->tb_flags & PSW_W) {
+ i ^= s << 13;
+ }
+ return i;
+}
+
+/* The sp field is only present with !PSW_W. */
+static int sp0_if_wide(DisasContext *ctx, int sp)
+{
+ return ctx->tb_flags & PSW_W ? 0 : sp;
+}
+
/* Translate CMPI doubleword conditions to standard. */
static int cmpbid_c(DisasContext *ctx, int val)
{
@@ -1961,7 +2011,7 @@
{
unsigned rt = a->t;
TCGv_i64 tmp = dest_gpr(ctx, rt);
- tcg_gen_movi_i64(tmp, ctx->iaoq_f);
+ tcg_gen_movi_i64(tmp, ctx->iaoq_f & ~3ULL);
save_gpr(ctx, rt, tmp);
cond_free(&ctx->null_cond);
@@ -2293,6 +2343,13 @@
return true;
}
+static bool trans_fic(DisasContext *ctx, arg_ldst *a)
+{
+ /* End TB for flush instruction cache, so we pick up new insns. */
+ ctx->base.is_jmp = DISAS_IAQ_N_STALE;
+ return trans_nop_addrx(ctx, a);
+}
+
static bool trans_probe(DisasContext *ctx, arg_probe *a)
{
TCGv_i64 dest, ofs;
@@ -3085,7 +3142,7 @@
dest = dest_gpr(ctx, a->t);
}
- form_gva(ctx, &addr, &ofs, a->b, a->x, a->scale ? a->size : 0,
+ form_gva(ctx, &addr, &ofs, a->b, a->x, a->scale ? 3 : 0,
a->disp, a->sp, a->m, MMU_DISABLED(ctx));
/*
@@ -3462,7 +3519,7 @@
/* Install the new nullification. */
cond_free(&ctx->null_cond);
if (a->c) {
- ctx->null_cond = do_sed_cond(ctx, a->c, false, dest);
+ ctx->null_cond = do_sed_cond(ctx, a->c, a->d, dest);
}
return nullify_end(ctx);
}
@@ -3505,7 +3562,7 @@
/* Install the new nullification. */
cond_free(&ctx->null_cond);
if (a->c) {
- ctx->null_cond = do_sed_cond(ctx, a->c, false, dest);
+ ctx->null_cond = do_sed_cond(ctx, a->c, a->d, dest);
}
return nullify_end(ctx);
}
diff --git a/tests/unit/test-crypto-cipher.c b/tests/unit/test-crypto-cipher.c
index 11ab1a5..f5152e5 100644
--- a/tests/unit/test-crypto-cipher.c
+++ b/tests/unit/test-crypto-cipher.c
@@ -676,9 +676,8 @@
cipher = qcrypto_cipher_new(
data->alg, data->mode,
key, nkey,
- &err);
+ data->plaintext ? &error_abort : &err);
if (data->plaintext) {
- g_assert(err == NULL);
g_assert(cipher != NULL);
} else {
error_free_or_abort(&err);
@@ -822,6 +821,10 @@
for (i = 0; i < G_N_ELEMENTS(test_data); i++) {
if (qcrypto_cipher_supports(test_data[i].alg, test_data[i].mode)) {
g_test_add_data_func(test_data[i].path, &test_data[i], test_cipher);
+ } else {
+ g_printerr("# skip unsupported %s:%s\n",
+ QCryptoCipherAlgorithm_str(test_data[i].alg),
+ QCryptoCipherMode_str(test_data[i].mode));
}
}