mirror of
https://github.com/qemu/qemu.git
synced 2026-07-08 17:46:10 +00:00
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:
@@ -239,13 +239,16 @@ void page_dump(FILE *f)
|
|||||||
|
|
||||||
int page_get_flags(vaddr address)
|
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
|
* See util/interval-tree.c re lockless lookups: no false positives but
|
||||||
* there are false negatives. If we find nothing, retry with the mmap
|
* there are false negatives. If we find nothing, retry with the mmap
|
||||||
* lock acquired.
|
* lock acquired.
|
||||||
*/
|
*/
|
||||||
|
p = pageflags_find(address, address);
|
||||||
if (p) {
|
if (p) {
|
||||||
return p->flags;
|
return p->flags;
|
||||||
}
|
}
|
||||||
@@ -301,15 +304,15 @@ static void pageflags_create_merge(vaddr start, vaddr last, int flags)
|
|||||||
|
|
||||||
if (prev) {
|
if (prev) {
|
||||||
if (next) {
|
if (next) {
|
||||||
prev->itree.last = next->itree.last;
|
pageflags_create(prev->itree.start, next->itree.last, flags);
|
||||||
g_free_rcu(next, rcu);
|
g_free_rcu(next, rcu);
|
||||||
} else {
|
} 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) {
|
} else if (next) {
|
||||||
next->itree.start = start;
|
pageflags_create(start, next->itree.last, flags);
|
||||||
interval_tree_insert(&next->itree, &pageflags_root);
|
g_free_rcu(next, rcu);
|
||||||
} else {
|
} else {
|
||||||
pageflags_create(start, last, flags);
|
pageflags_create(start, last, flags);
|
||||||
}
|
}
|
||||||
@@ -371,8 +374,8 @@ static bool pageflags_set_clear(vaddr start, vaddr last,
|
|||||||
if (set_flags != merge_flags) {
|
if (set_flags != merge_flags) {
|
||||||
if (p_start < start) {
|
if (p_start < start) {
|
||||||
interval_tree_remove(&p->itree, &pageflags_root);
|
interval_tree_remove(&p->itree, &pageflags_root);
|
||||||
p->itree.last = start - 1;
|
pageflags_create(p_start, start - 1, p_flags);
|
||||||
interval_tree_insert(&p->itree, &pageflags_root);
|
g_free_rcu(p, rcu);
|
||||||
|
|
||||||
if (last < p_last) {
|
if (last < p_last) {
|
||||||
if (merge_flags & PAGE_VALID) {
|
if (merge_flags & PAGE_VALID) {
|
||||||
@@ -394,11 +397,11 @@ static bool pageflags_set_clear(vaddr start, vaddr last,
|
|||||||
}
|
}
|
||||||
if (last < p_last) {
|
if (last < p_last) {
|
||||||
interval_tree_remove(&p->itree, &pageflags_root);
|
interval_tree_remove(&p->itree, &pageflags_root);
|
||||||
p->itree.start = last + 1;
|
pageflags_create(last + 1, p_last, p_flags);
|
||||||
interval_tree_insert(&p->itree, &pageflags_root);
|
|
||||||
if (merge_flags & PAGE_VALID) {
|
if (merge_flags & PAGE_VALID) {
|
||||||
pageflags_create(start, last, merge_flags);
|
pageflags_create(start, last, merge_flags);
|
||||||
}
|
}
|
||||||
|
g_free_rcu(p, rcu);
|
||||||
} else {
|
} else {
|
||||||
if (merge_flags & PAGE_VALID) {
|
if (merge_flags & PAGE_VALID) {
|
||||||
p->flags = merge_flags;
|
p->flags = merge_flags;
|
||||||
@@ -419,8 +422,8 @@ static bool pageflags_set_clear(vaddr start, vaddr last,
|
|||||||
if (set_flags == p_flags) {
|
if (set_flags == p_flags) {
|
||||||
if (start < p_start) {
|
if (start < p_start) {
|
||||||
interval_tree_remove(&p->itree, &pageflags_root);
|
interval_tree_remove(&p->itree, &pageflags_root);
|
||||||
p->itree.start = start;
|
pageflags_create(start, p_last, p_flags);
|
||||||
interval_tree_insert(&p->itree, &pageflags_root);
|
g_free_rcu(p, rcu);
|
||||||
}
|
}
|
||||||
if (p_last < last) {
|
if (p_last < last) {
|
||||||
start = p_last + 1;
|
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. */
|
/* Maybe split out head and/or tail ranges with the original flags. */
|
||||||
interval_tree_remove(&p->itree, &pageflags_root);
|
interval_tree_remove(&p->itree, &pageflags_root);
|
||||||
if (p_start < start) {
|
if (p_start < start) {
|
||||||
p->itree.last = start - 1;
|
pageflags_create(p_start, start - 1, p_flags);
|
||||||
interval_tree_insert(&p->itree, &pageflags_root);
|
g_free_rcu(p, rcu);
|
||||||
|
|
||||||
if (p_last < last) {
|
if (p_last < last) {
|
||||||
goto restart;
|
goto restart;
|
||||||
@@ -442,8 +445,8 @@ static bool pageflags_set_clear(vaddr start, vaddr last,
|
|||||||
pageflags_create(last + 1, p_last, p_flags);
|
pageflags_create(last + 1, p_last, p_flags);
|
||||||
}
|
}
|
||||||
} else if (last < p_last) {
|
} else if (last < p_last) {
|
||||||
p->itree.start = last + 1;
|
pageflags_create(last + 1, p_last, p_flags);
|
||||||
interval_tree_insert(&p->itree, &pageflags_root);
|
g_free_rcu(p, rcu);
|
||||||
} else {
|
} else {
|
||||||
g_free_rcu(p, rcu);
|
g_free_rcu(p, rcu);
|
||||||
goto restart;
|
goto restart;
|
||||||
@@ -505,6 +508,8 @@ bool page_check_range(vaddr start, vaddr len, int flags)
|
|||||||
return false; /* wrap around */
|
return false; /* wrap around */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RCU_READ_LOCK_GUARD();
|
||||||
|
|
||||||
locked = have_mmap_lock();
|
locked = have_mmap_lock();
|
||||||
while (true) {
|
while (true) {
|
||||||
PageFlagsNode *p = pageflags_find(start, last);
|
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 (page_flags & acc_flag) {
|
||||||
if (access_type != MMU_INST_FETCH
|
if (access_type != MMU_INST_FETCH
|
||||||
&& cpu_plugin_mem_cbs_enabled(env_cpu(env))) {
|
&& cpu_plugin_mem_cbs_enabled(env_cpu(env))) {
|
||||||
return TLB_MMIO;
|
return TLB_FORCE_SLOW;
|
||||||
}
|
}
|
||||||
return 0; /* success */
|
return 0; /* success */
|
||||||
}
|
}
|
||||||
@@ -804,7 +809,7 @@ void *probe_access(CPUArchState *env, vaddr addr, int size,
|
|||||||
|
|
||||||
g_assert(-(addr | TARGET_PAGE_MASK) >= size);
|
g_assert(-(addr | TARGET_PAGE_MASK) >= size);
|
||||||
flags = probe_access_internal(env, addr, size, access_type, false, ra);
|
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;
|
return size ? g2h_vaddr(env_cpu(env), addr) : NULL;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,12 +27,13 @@
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Allow some level of source compatibility with softmmu.
|
* Allow some level of source compatibility with softmmu.
|
||||||
* Invalid is set when the page does not have requested permissions.
|
* INVALID is set when the page does not have requested permissions.
|
||||||
* MMIO is set when we want the target helper to use the functional
|
* FORCE_SLOW is set when we want the target helper to use the functional
|
||||||
* interface for load/store so that plugins see the access.
|
* interface for load/store so that plugins see the access.
|
||||||
*/
|
*/
|
||||||
#define TLB_INVALID_MASK (1 << 0)
|
#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
|
#define TLB_WATCHPOINT 0
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|||||||
@@ -2371,19 +2371,36 @@ static void tcg_out_vec_op(TCGContext *s, TCGOpcode opc,
|
|||||||
default:
|
default:
|
||||||
g_assert_not_reached();
|
g_assert_not_reached();
|
||||||
}
|
}
|
||||||
break;
|
} else {
|
||||||
}
|
switch (cond) {
|
||||||
|
case TCG_COND_EQ:
|
||||||
insn = cmp_vec_insn[cond][lasx][vece];
|
case TCG_COND_LE:
|
||||||
if (insn == 0) {
|
case TCG_COND_LEU:
|
||||||
TCGArg t;
|
case TCG_COND_LT:
|
||||||
t = a1, a1 = a2, a2 = t;
|
case TCG_COND_LTU:
|
||||||
cond = tcg_swap_cond(cond);
|
insn = cmp_vec_insn[cond][lasx][vece];
|
||||||
insn = cmp_vec_insn[cond][lasx][vece];
|
tcg_out32(s, encode_vdvjvk_insn(insn, a0, a1, a2));
|
||||||
tcg_debug_assert(insn != 0);
|
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:
|
case INDEX_op_add_vec:
|
||||||
tcg_out_addsub_vec(s, lasx, vece, a0, a1, a2, const_args[2], true);
|
tcg_out_addsub_vec(s, lasx, vece, a0, a1, a2, const_args[2], true);
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -1783,7 +1783,7 @@ bool tcg_target_has_memory_bswap(MemOp memop)
|
|||||||
* Reject 16-byte memop with 16-byte atomicity, i.e. VMOVDQA,
|
* Reject 16-byte memop with 16-byte atomicity, i.e. VMOVDQA,
|
||||||
* but do allow a pair of 64-bit operations, i.e. MOVBEQ.
|
* 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;
|
return aa.atom < MO_128;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1934,7 +1934,7 @@ static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, HostAddress *h,
|
|||||||
*h = x86_guest_base;
|
*h = x86_guest_base;
|
||||||
}
|
}
|
||||||
h->base = addr;
|
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;
|
a_mask = (1 << h->aa.align) - 1;
|
||||||
|
|
||||||
if (tcg_use_softmmu) {
|
if (tcg_use_softmmu) {
|
||||||
|
|||||||
@@ -60,15 +60,6 @@ tb-link: LDFLAGS+=-lpthread
|
|||||||
# code to work around the compiler.
|
# code to work around the compiler.
|
||||||
sha1: CFLAGS+=-Wno-stringop-overread -Wno-unknown-warning-option
|
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
|
run-test-mmap: test-mmap
|
||||||
$(call run-test, test-mmap, $(QEMU) $<, $< (default))
|
$(call run-test, test-mmap, $(QEMU) $<, $< (default))
|
||||||
|
|
||||||
|
|||||||
@@ -11,6 +11,7 @@
|
|||||||
* pages, which are guaranteed to have the respective protection bit set.
|
* pages, which are guaranteed to have the respective protection bit set.
|
||||||
* Two mutator threads change the non-fixed protection bits randomly.
|
* Two mutator threads change the non-fixed protection bits randomly.
|
||||||
*/
|
*/
|
||||||
|
#define _GNU_SOURCE
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
@@ -121,7 +122,7 @@ static void *thread_mutate(void *arg)
|
|||||||
unsigned int seed;
|
unsigned int seed;
|
||||||
int prot, ret;
|
int prot, ret;
|
||||||
|
|
||||||
seed = (unsigned int)time(NULL);
|
seed = (unsigned int)time(NULL) + (unsigned int)gettid();
|
||||||
for (i = 0; i < 10000; i++) {
|
for (i = 0; i < 10000; i++) {
|
||||||
start_idx = rand_r(&seed) & PAGE_IDX_MASK;
|
start_idx = rand_r(&seed) & PAGE_IDX_MASK;
|
||||||
end_idx = rand_r(&seed) & PAGE_IDX_MASK;
|
end_idx = rand_r(&seed) & PAGE_IDX_MASK;
|
||||||
|
|||||||
Reference in New Issue
Block a user