Merge tag 'pull-tcg-20260707' of https://gitlab.com/rth7680/qemu into staging

tcg/loongarch64: Fix cmp_vec with TCG_COND_NE
tcg/x86_64: declare MO_ATOM_WITHIN16 host atomicity support
accel/tcg: Make PageFlagsNodes' start and last immutable
accel/tcg: Use TLB_FORCE_SLOW not TLB_MMIO for user-only plugins

# -----BEGIN PGP SIGNATURE-----
#
# iQFRBAABCgA7FiEEekgeeIaLTbaoWgXAZN846K9+IV8FAmpNaDIdHHJpY2hhcmQu
# aGVuZGVyc29uQGxpbmFyby5vcmcACgkQZN846K9+IV8qlwgAqFBxRHQFzeNrivul
# 9u4jrEqsQS2wu2pL/rKfr7DTBTzmbibmzTT229yru8yahvpONrbYOantxjikAW6z
# tRgaKaLlFOw2Ll6VKbOxdu2OL+nemOAW3ehiHutuPLtxFSGWQsFtC38Qz51sC1K9
# nTX8vkuYkkIKyVU0Klinu2rjqZW3h1yIwKwC6tieh08y6YYeOODYoAfpEJ+hGus1
# 33hMlE1zEj9j4JVpsDR3Rl3zXUbnV3FMeikTd8Xkl9fBDeWs/aFVLVLXWQ0BYULC
# 62/ZOghnfbrM7p2osLAhkNSL020vn/G1c2O8ofSa0pXj+I7YM80H2m7zsyiBa685
# rm7IKg==
# =0LKf
# -----END PGP SIGNATURE-----
# gpg: Signature made Tue 07 Jul 2026 22:57:22 CEST
# gpg:                using RSA key 7A481E78868B4DB6A85A05C064DF38E8AF7E215F
# gpg:                issuer "richard.henderson@linaro.org"
# gpg: Good signature from "Richard Henderson <richard.henderson@linaro.org>" [full]
# Primary key fingerprint: 7A48 1E78 868B 4DB6 A85A  05C0 64DF 38E8 AF7E 215F

* tag 'pull-tcg-20260707' of https://gitlab.com/rth7680/qemu:
  tcg/loongarch64: Fix cmp_vec with TCG_COND_NE
  tcg/x86_64: declare MO_ATOM_WITHIN16 host atomicity support
  Revert "tests/tcg: skip the vma-pthread test on CI"
  tests/tcg/multiarch: Improve mutator randomness
  accel/tcg: Make PageFlagsNodes' start and last immutable
  accel/tcg: Use TLB_FORCE_SLOW not TLB_MMIO for user-only plugins

Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
This commit is contained in:
Stefan Hajnoczi
2026-07-08 16:00:20 +02:00
6 changed files with 59 additions and 44 deletions

View File

@@ -239,13 +239,16 @@ void page_dump(FILE *f)
int page_get_flags(vaddr address)
{
PageFlagsNode *p = pageflags_find(address, address);
PageFlagsNode *p;
RCU_READ_LOCK_GUARD();
/*
* See util/interval-tree.c re lockless lookups: no false positives but
* there are false negatives. If we find nothing, retry with the mmap
* lock acquired.
*/
p = pageflags_find(address, address);
if (p) {
return p->flags;
}
@@ -301,15 +304,15 @@ static void pageflags_create_merge(vaddr start, vaddr last, int flags)
if (prev) {
if (next) {
prev->itree.last = next->itree.last;
pageflags_create(prev->itree.start, next->itree.last, flags);
g_free_rcu(next, rcu);
} else {
prev->itree.last = last;
pageflags_create(prev->itree.start, last, flags);
}
interval_tree_insert(&prev->itree, &pageflags_root);
g_free_rcu(prev, rcu);
} else if (next) {
next->itree.start = start;
interval_tree_insert(&next->itree, &pageflags_root);
pageflags_create(start, next->itree.last, flags);
g_free_rcu(next, rcu);
} else {
pageflags_create(start, last, flags);
}
@@ -371,8 +374,8 @@ static bool pageflags_set_clear(vaddr start, vaddr last,
if (set_flags != merge_flags) {
if (p_start < start) {
interval_tree_remove(&p->itree, &pageflags_root);
p->itree.last = start - 1;
interval_tree_insert(&p->itree, &pageflags_root);
pageflags_create(p_start, start - 1, p_flags);
g_free_rcu(p, rcu);
if (last < p_last) {
if (merge_flags & PAGE_VALID) {
@@ -394,11 +397,11 @@ static bool pageflags_set_clear(vaddr start, vaddr last,
}
if (last < p_last) {
interval_tree_remove(&p->itree, &pageflags_root);
p->itree.start = last + 1;
interval_tree_insert(&p->itree, &pageflags_root);
pageflags_create(last + 1, p_last, p_flags);
if (merge_flags & PAGE_VALID) {
pageflags_create(start, last, merge_flags);
}
g_free_rcu(p, rcu);
} else {
if (merge_flags & PAGE_VALID) {
p->flags = merge_flags;
@@ -419,8 +422,8 @@ static bool pageflags_set_clear(vaddr start, vaddr last,
if (set_flags == p_flags) {
if (start < p_start) {
interval_tree_remove(&p->itree, &pageflags_root);
p->itree.start = start;
interval_tree_insert(&p->itree, &pageflags_root);
pageflags_create(start, p_last, p_flags);
g_free_rcu(p, rcu);
}
if (p_last < last) {
start = p_last + 1;
@@ -432,8 +435,8 @@ static bool pageflags_set_clear(vaddr start, vaddr last,
/* Maybe split out head and/or tail ranges with the original flags. */
interval_tree_remove(&p->itree, &pageflags_root);
if (p_start < start) {
p->itree.last = start - 1;
interval_tree_insert(&p->itree, &pageflags_root);
pageflags_create(p_start, start - 1, p_flags);
g_free_rcu(p, rcu);
if (p_last < last) {
goto restart;
@@ -442,8 +445,8 @@ static bool pageflags_set_clear(vaddr start, vaddr last,
pageflags_create(last + 1, p_last, p_flags);
}
} else if (last < p_last) {
p->itree.start = last + 1;
interval_tree_insert(&p->itree, &pageflags_root);
pageflags_create(last + 1, p_last, p_flags);
g_free_rcu(p, rcu);
} else {
g_free_rcu(p, rcu);
goto restart;
@@ -505,6 +508,8 @@ bool page_check_range(vaddr start, vaddr len, int flags)
return false; /* wrap around */
}
RCU_READ_LOCK_GUARD();
locked = have_mmap_lock();
while (true) {
PageFlagsNode *p = pageflags_find(start, last);
@@ -769,7 +774,7 @@ static int probe_access_internal(CPUArchState *env, vaddr addr,
if (page_flags & acc_flag) {
if (access_type != MMU_INST_FETCH
&& cpu_plugin_mem_cbs_enabled(env_cpu(env))) {
return TLB_MMIO;
return TLB_FORCE_SLOW;
}
return 0; /* success */
}
@@ -804,7 +809,7 @@ void *probe_access(CPUArchState *env, vaddr addr, int size,
g_assert(-(addr | TARGET_PAGE_MASK) >= size);
flags = probe_access_internal(env, addr, size, access_type, false, ra);
g_assert((flags & ~TLB_MMIO) == 0);
g_assert((flags & ~TLB_FORCE_SLOW) == 0);
return size ? g2h_vaddr(env_cpu(env), addr) : NULL;
}

View File

@@ -27,12 +27,13 @@
/*
* Allow some level of source compatibility with softmmu.
* Invalid is set when the page does not have requested permissions.
* MMIO is set when we want the target helper to use the functional
* INVALID is set when the page does not have requested permissions.
* FORCE_SLOW is set when we want the target helper to use the functional
* interface for load/store so that plugins see the access.
*/
#define TLB_INVALID_MASK (1 << 0)
#define TLB_MMIO (1 << 1)
#define TLB_FORCE_SLOW (1 << 1)
#define TLB_MMIO 0
#define TLB_WATCHPOINT 0
#else

View File

@@ -2371,19 +2371,36 @@ static void tcg_out_vec_op(TCGContext *s, TCGOpcode opc,
default:
g_assert_not_reached();
}
break;
}
insn = cmp_vec_insn[cond][lasx][vece];
if (insn == 0) {
TCGArg t;
t = a1, a1 = a2, a2 = t;
cond = tcg_swap_cond(cond);
insn = cmp_vec_insn[cond][lasx][vece];
tcg_debug_assert(insn != 0);
} else {
switch (cond) {
case TCG_COND_EQ:
case TCG_COND_LE:
case TCG_COND_LEU:
case TCG_COND_LT:
case TCG_COND_LTU:
insn = cmp_vec_insn[cond][lasx][vece];
tcg_out32(s, encode_vdvjvk_insn(insn, a0, a1, a2));
break;
case TCG_COND_GE:
case TCG_COND_GEU:
case TCG_COND_GT:
case TCG_COND_GTU:
insn = cmp_vec_insn[tcg_swap_cond(cond)][lasx][vece];
tcg_out32(s, encode_vdvjvk_insn(insn, a0, a2, a1));
break;
case TCG_COND_NE:
/* ne -> not(eq) */
insn = cmp_vec_insn[TCG_COND_EQ][lasx][vece];
tcg_out32(s, encode_vdvjvk_insn(insn, a0, a1, a2));
insn = lasx ? OPC_XVNOR_V : OPC_VNOR_V;
tcg_out32(s, encode_vdvjvk_insn(insn, a0, a0, a0));
break;
default:
g_assert_not_reached();
}
}
}
goto vdvjvk;
break;
case INDEX_op_add_vec:
tcg_out_addsub_vec(s, lasx, vece, a0, a1, a2, const_args[2], true);
break;

View File

@@ -1783,7 +1783,7 @@ bool tcg_target_has_memory_bswap(MemOp memop)
* Reject 16-byte memop with 16-byte atomicity, i.e. VMOVDQA,
* but do allow a pair of 64-bit operations, i.e. MOVBEQ.
*/
aa = atom_and_align_for_opc(tcg_ctx, memop, MO_ATOM_IFALIGN, true);
aa = atom_and_align_for_opc(tcg_ctx, memop, MO_ATOM_WITHIN16, true);
return aa.atom < MO_128;
}
@@ -1934,7 +1934,7 @@ static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, HostAddress *h,
*h = x86_guest_base;
}
h->base = addr;
h->aa = atom_and_align_for_opc(s, opc, MO_ATOM_IFALIGN, s_bits == MO_128);
h->aa = atom_and_align_for_opc(s, opc, MO_ATOM_WITHIN16, s_bits == MO_128);
a_mask = (1 << h->aa.align) - 1;
if (tcg_use_softmmu) {

View File

@@ -60,15 +60,6 @@ tb-link: LDFLAGS+=-lpthread
# code to work around the compiler.
sha1: CFLAGS+=-Wno-stringop-overread -Wno-unknown-warning-option
# The vma-pthread seems very sensitive on gitlab and we currently
# don't know if its exposing a real bug or the test is flaky.
ifneq ($(GITLAB_CI),)
run-vma-pthread: vma-pthread
$(call skip-test, $<, "flaky on CI?")
run-plugin-vma-pthread-with-%: vma-pthread
$(call skip-test, $<, "flaky on CI?")
endif
run-test-mmap: test-mmap
$(call run-test, test-mmap, $(QEMU) $<, $< (default))

View File

@@ -11,6 +11,7 @@
* pages, which are guaranteed to have the respective protection bit set.
* Two mutator threads change the non-fixed protection bits randomly.
*/
#define _GNU_SOURCE
#include <assert.h>
#include <fcntl.h>
#include <pthread.h>
@@ -121,7 +122,7 @@ static void *thread_mutate(void *arg)
unsigned int seed;
int prot, ret;
seed = (unsigned int)time(NULL);
seed = (unsigned int)time(NULL) + (unsigned int)gettid();
for (i = 0; i < 10000; i++) {
start_idx = rand_r(&seed) & PAGE_IDX_MASK;
end_idx = rand_r(&seed) & PAGE_IDX_MASK;