cpu: ensure we don't call start_exclusive from cpu_exec
tcg: Allow top bit of SIMD_DATA_BITS to be set in simd_desc() accel/tcg: Fix user-only probe_access_internal plugin check linux-user: Fix setreuid and setregid to use direct syscalls linux-user: Tolerate CONFIG_LSM_MMAP_MIN_ADDR linux-user: Honor elf alignment when placing images linux-user/*: Reduce vdso alignment to 4k linux-user/arm: Select vdso for be8 and be32 modes -----BEGIN PGP SIGNATURE----- iQFRBAABCgA7FiEEekgeeIaLTbaoWgXAZN846K9+IV8FAmc4z/8dHHJpY2hhcmQu aGVuZGVyc29uQGxpbmFyby5vcmcACgkQZN846K9+IV/vWgf5Af8105enuWEdJ9c+ KiyTsOWQEOKXTUSlSUxPs9FEeEr2l/mccvqUhiD7ptZq7P5/40+3tB18KXc5YuiE 45CZGRAr/tjALGT5LidSYzm6RgljWXYlvWVShqKlQpOD2L0GP5k8a7KEKsT3SLtS 9l+SVvjNOE+Jv23FWSOVYq0K0e5dPKzS1gtviCg+obA56dsiSKiEwwg+a5ca6oRe 9SUKoRnudpUv3fiYo8yZaHPW0ADhsITAB20ncN+cI9t4li9q5AWUbPZ+ADP113+2 pWlco1VqR4pONK2UgbSmxDtjQf1GBi7E2MBFBjBMxTaiw/jXAZcZGIK4geZYKdHT NJj/0Q== =oKCm -----END PGP SIGNATURE----- Merge tag 'pull-tcg-20241116' of https://gitlab.com/rth7680/qemu into staging cpu: ensure we don't call start_exclusive from cpu_exec tcg: Allow top bit of SIMD_DATA_BITS to be set in simd_desc() accel/tcg: Fix user-only probe_access_internal plugin check linux-user: Fix setreuid and setregid to use direct syscalls linux-user: Tolerate CONFIG_LSM_MMAP_MIN_ADDR linux-user: Honor elf alignment when placing images linux-user/*: Reduce vdso alignment to 4k linux-user/arm: Select vdso for be8 and be32 modes # -----BEGIN PGP SIGNATURE----- # # iQFRBAABCgA7FiEEekgeeIaLTbaoWgXAZN846K9+IV8FAmc4z/8dHHJpY2hhcmQu # aGVuZGVyc29uQGxpbmFyby5vcmcACgkQZN846K9+IV/vWgf5Af8105enuWEdJ9c+ # KiyTsOWQEOKXTUSlSUxPs9FEeEr2l/mccvqUhiD7ptZq7P5/40+3tB18KXc5YuiE # 45CZGRAr/tjALGT5LidSYzm6RgljWXYlvWVShqKlQpOD2L0GP5k8a7KEKsT3SLtS # 9l+SVvjNOE+Jv23FWSOVYq0K0e5dPKzS1gtviCg+obA56dsiSKiEwwg+a5ca6oRe # 9SUKoRnudpUv3fiYo8yZaHPW0ADhsITAB20ncN+cI9t4li9q5AWUbPZ+ADP113+2 # pWlco1VqR4pONK2UgbSmxDtjQf1GBi7E2MBFBjBMxTaiw/jXAZcZGIK4geZYKdHT # NJj/0Q== # =oKCm # -----END PGP SIGNATURE----- # gpg: Signature made Sat 16 Nov 2024 17:01:51 GMT # 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-20241116' of https://gitlab.com/rth7680/qemu: tcg: Allow top bit of SIMD_DATA_BITS to be set in simd_desc() linux-user/arm: Select vdso for be8 and be32 modes linux-user/ppc: Reduce vdso alignment to 4k linux-user/loongarch64: Reduce vdso alignment to 4k linux-user/arm: Reduce vdso alignment to 4k linux-user/aarch64: Reduce vdso alignment to 4k linux-user: Drop image_info.alignment linux-user: Honor elf alignment when placing images cpu: ensure we don't call start_exclusive from cpu_exec target/i386: fix hang when using slow path for ptw_setl tests/tcg: Test that sigreturn() does not corrupt the signal mask linux-user: Tolerate CONFIG_LSM_MMAP_MIN_ADDR accel/tcg: Fix user-only probe_access_internal plugin check target/arm: Drop user-only special case in sve_stN_r linux-user: Fix setreuid and setregid to use direct syscalls Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
abb1565d3d
@ -800,7 +800,7 @@ static int probe_access_internal(CPUArchState *env, vaddr addr,
|
||||
if (guest_addr_valid_untagged(addr)) {
|
||||
int page_flags = page_get_flags(addr);
|
||||
if (page_flags & acc_flag) {
|
||||
if ((acc_flag == PAGE_READ || acc_flag == PAGE_WRITE)
|
||||
if (access_type != MMU_INST_FETCH
|
||||
&& cpu_plugin_mem_cbs_enabled(env_cpu(env))) {
|
||||
return TLB_MMIO;
|
||||
}
|
||||
|
@ -194,6 +194,9 @@ void start_exclusive(void)
|
||||
CPUState *other_cpu;
|
||||
int running_cpus;
|
||||
|
||||
/* Ensure we are not running, or start_exclusive will be blocked. */
|
||||
g_assert(!current_cpu->running);
|
||||
|
||||
if (current_cpu->exclusive_context_count) {
|
||||
current_cpu->exclusive_context_count++;
|
||||
return;
|
||||
|
@ -5,8 +5,9 @@ VPATH += $(SUBDIR)
|
||||
|
||||
all: $(SUBDIR)/vdso-be.so $(SUBDIR)/vdso-le.so
|
||||
|
||||
LDFLAGS = -nostdlib -shared -Wl,-h,linux-vdso.so.1 -Wl,--build-id=sha1 \
|
||||
-Wl,--hash-style=both -Wl,-T,$(SUBDIR)/vdso.ld
|
||||
LDFLAGS = -nostdlib -shared -Wl,-h,linux-vdso.so.1 \
|
||||
-Wl,--build-id=sha1 -Wl,--hash-style=both \
|
||||
-Wl,-z,max-page-size=4096 -Wl,-T,$(SUBDIR)/vdso.ld
|
||||
|
||||
$(SUBDIR)/vdso-be.so: vdso.S vdso.ld
|
||||
$(CC) -o $@ $(LDFLAGS) -mbig-endian $<
|
||||
|
Binary file not shown.
Binary file not shown.
@ -3,15 +3,18 @@ include $(BUILD_DIR)/tests/tcg/arm-linux-user/config-target.mak
|
||||
SUBDIR = $(SRC_PATH)/linux-user/arm
|
||||
VPATH += $(SUBDIR)
|
||||
|
||||
all: $(SUBDIR)/vdso-be.so $(SUBDIR)/vdso-le.so
|
||||
all: $(SUBDIR)/vdso-be8.so $(SUBDIR)/vdso-be32.so $(SUBDIR)/vdso-le.so
|
||||
|
||||
# Adding -use-blx disables unneeded interworking without actually using blx.
|
||||
LDFLAGS = -nostdlib -shared -Wl,-use-blx \
|
||||
LDFLAGS = -nostdlib -shared -Wl,-use-blx -Wl,-z,max-page-size=4096 \
|
||||
-Wl,-h,linux-vdso.so.1 -Wl,--build-id=sha1 \
|
||||
-Wl,--hash-style=both -Wl,-T,$(SUBDIR)/vdso.ld
|
||||
|
||||
$(SUBDIR)/vdso-be.so: vdso.S vdso.ld vdso-asmoffset.h
|
||||
$(CC) -o $@ $(LDFLAGS) -mbig-endian $<
|
||||
$(SUBDIR)/vdso-be8.so: vdso.S vdso.ld vdso-asmoffset.h
|
||||
$(CC) -o $@ $(LDFLAGS) -mbig-endian -mbe8 $<
|
||||
|
||||
$(SUBDIR)/vdso-be32.so: vdso.S vdso.ld vdso-asmoffset.h
|
||||
$(CC) -o $@ $(LDFLAGS) -mbig-endian -mbe32 $<
|
||||
|
||||
$(SUBDIR)/vdso-le.so: vdso.S vdso.ld vdso-asmoffset.h
|
||||
$(CC) -o $@ $(LDFLAGS) -mlittle-endian $<
|
||||
|
@ -10,10 +10,17 @@ syscall_nr_generators += {
|
||||
# is always true as far as source_set.apply() is concerned. Always build
|
||||
# both header files and include the right one via #if.
|
||||
|
||||
vdso_be_inc = gen_vdso.process('vdso-be.so',
|
||||
extra_args: ['-s', 'sigreturn_codes'])
|
||||
vdso_be8_inc = gen_vdso.process('vdso-be8.so',
|
||||
extra_args: ['-s', 'sigreturn_codes',
|
||||
'-p', 'vdso_be8'])
|
||||
|
||||
vdso_be32_inc = gen_vdso.process('vdso-be32.so',
|
||||
extra_args: ['-s', 'sigreturn_codes',
|
||||
'-p', 'vdso_be32'])
|
||||
|
||||
vdso_le_inc = gen_vdso.process('vdso-le.so',
|
||||
extra_args: ['-s', 'sigreturn_codes'])
|
||||
|
||||
linux_user_ss.add(when: 'TARGET_ARM', if_true: [vdso_be_inc, vdso_le_inc])
|
||||
linux_user_ss.add(when: 'TARGET_ARM', if_true: [
|
||||
vdso_be8_inc, vdso_be32_inc, vdso_le_inc
|
||||
])
|
||||
|
BIN
linux-user/arm/vdso-be32.so
Executable file
BIN
linux-user/arm/vdso-be32.so
Executable file
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -659,6 +659,23 @@ static const char *get_elf_platform(void)
|
||||
#undef END
|
||||
}
|
||||
|
||||
#if TARGET_BIG_ENDIAN
|
||||
#include "elf.h"
|
||||
#include "vdso-be8.c.inc"
|
||||
#include "vdso-be32.c.inc"
|
||||
|
||||
static const VdsoImageInfo *vdso_image_info(uint32_t elf_flags)
|
||||
{
|
||||
return (EF_ARM_EABI_VERSION(elf_flags) >= EF_ARM_EABI_VER4
|
||||
&& (elf_flags & EF_ARM_BE8)
|
||||
? &vdso_be8_image_info
|
||||
: &vdso_be32_image_info);
|
||||
}
|
||||
#define vdso_image_info vdso_image_info
|
||||
#else
|
||||
# define VDSO_HEADER "vdso-le.c.inc"
|
||||
#endif
|
||||
|
||||
#else
|
||||
/* 64 bit ARM definitions */
|
||||
|
||||
@ -958,14 +975,14 @@ const char *elf_hwcap2_str(uint32_t bit)
|
||||
|
||||
#undef GET_FEATURE_ID
|
||||
|
||||
#endif /* not TARGET_AARCH64 */
|
||||
|
||||
#if TARGET_BIG_ENDIAN
|
||||
# define VDSO_HEADER "vdso-be.c.inc"
|
||||
#else
|
||||
# define VDSO_HEADER "vdso-le.c.inc"
|
||||
#endif
|
||||
|
||||
#endif /* not TARGET_AARCH64 */
|
||||
|
||||
#endif /* TARGET_ARM */
|
||||
|
||||
#ifdef TARGET_SPARC
|
||||
@ -2898,7 +2915,7 @@ static uintptr_t pgb_try_itree(const PGBAddrs *ga, uintptr_t base,
|
||||
static uintptr_t pgb_find_itree(const PGBAddrs *ga, IntervalTreeRoot *root,
|
||||
uintptr_t align, uintptr_t brk)
|
||||
{
|
||||
uintptr_t last = mmap_min_addr;
|
||||
uintptr_t last = sizeof(uintptr_t) == 4 ? MiB : GiB;
|
||||
uintptr_t base, skip;
|
||||
|
||||
while (true) {
|
||||
@ -3179,7 +3196,8 @@ static void load_elf_image(const char *image_name, const ImageSource *src,
|
||||
char **pinterp_name)
|
||||
{
|
||||
g_autofree struct elf_phdr *phdr = NULL;
|
||||
abi_ulong load_addr, load_bias, loaddr, hiaddr, error;
|
||||
abi_ulong load_addr, load_bias, loaddr, hiaddr, error, align;
|
||||
size_t reserve_size, align_size;
|
||||
int i, prot_exec;
|
||||
Error *err = NULL;
|
||||
|
||||
@ -3219,7 +3237,7 @@ static void load_elf_image(const char *image_name, const ImageSource *src,
|
||||
* amount of memory to handle that. Locate the interpreter, if any.
|
||||
*/
|
||||
loaddr = -1, hiaddr = 0;
|
||||
info->alignment = 0;
|
||||
align = 0;
|
||||
info->exec_stack = EXSTACK_DEFAULT;
|
||||
for (i = 0; i < ehdr->e_phnum; ++i) {
|
||||
struct elf_phdr *eppnt = phdr + i;
|
||||
@ -3233,7 +3251,7 @@ static void load_elf_image(const char *image_name, const ImageSource *src,
|
||||
hiaddr = a;
|
||||
}
|
||||
++info->nsegs;
|
||||
info->alignment |= eppnt->p_align;
|
||||
align |= eppnt->p_align;
|
||||
} else if (eppnt->p_type == PT_INTERP && pinterp_name) {
|
||||
g_autofree char *interp_name = NULL;
|
||||
|
||||
@ -3263,6 +3281,8 @@ static void load_elf_image(const char *image_name, const ImageSource *src,
|
||||
|
||||
load_addr = loaddr;
|
||||
|
||||
align = pow2ceil(align);
|
||||
|
||||
if (pinterp_name != NULL) {
|
||||
if (ehdr->e_type == ET_EXEC) {
|
||||
/*
|
||||
@ -3271,8 +3291,6 @@ static void load_elf_image(const char *image_name, const ImageSource *src,
|
||||
*/
|
||||
probe_guest_base(image_name, loaddr, hiaddr);
|
||||
} else {
|
||||
abi_ulong align;
|
||||
|
||||
/*
|
||||
* The binary is dynamic, but we still need to
|
||||
* select guest_base. In this case we pass a size.
|
||||
@ -3290,10 +3308,7 @@ static void load_elf_image(const char *image_name, const ImageSource *src,
|
||||
* Since we do not have complete control over the guest
|
||||
* address space, we prefer the kernel to choose some address
|
||||
* rather than force the use of LOAD_ADDR via MAP_FIXED.
|
||||
* But without MAP_FIXED we cannot guarantee alignment,
|
||||
* only suggest it.
|
||||
*/
|
||||
align = pow2ceil(info->alignment);
|
||||
if (align) {
|
||||
load_addr &= -align;
|
||||
}
|
||||
@ -3317,13 +3332,35 @@ static void load_elf_image(const char *image_name, const ImageSource *src,
|
||||
* In both cases, we will overwrite pages in this range with mappings
|
||||
* from the executable.
|
||||
*/
|
||||
load_addr = target_mmap(load_addr, (size_t)hiaddr - loaddr + 1, PROT_NONE,
|
||||
reserve_size = (size_t)hiaddr - loaddr + 1;
|
||||
align_size = reserve_size;
|
||||
|
||||
if (ehdr->e_type != ET_EXEC && align > qemu_real_host_page_size()) {
|
||||
align_size += align - 1;
|
||||
}
|
||||
|
||||
load_addr = target_mmap(load_addr, align_size, PROT_NONE,
|
||||
MAP_PRIVATE | MAP_ANON | MAP_NORESERVE |
|
||||
(ehdr->e_type == ET_EXEC ? MAP_FIXED_NOREPLACE : 0),
|
||||
-1, 0);
|
||||
if (load_addr == -1) {
|
||||
goto exit_mmap;
|
||||
}
|
||||
|
||||
if (align_size != reserve_size) {
|
||||
abi_ulong align_addr = ROUND_UP(load_addr, align);
|
||||
abi_ulong align_end = align_addr + reserve_size;
|
||||
abi_ulong load_end = load_addr + align_size;
|
||||
|
||||
if (align_addr != load_addr) {
|
||||
target_munmap(load_addr, align_addr - load_addr);
|
||||
}
|
||||
if (align_end != load_end) {
|
||||
target_munmap(align_end, load_end - align_end);
|
||||
}
|
||||
load_addr = align_addr;
|
||||
}
|
||||
|
||||
load_bias = load_addr - loaddr;
|
||||
|
||||
if (elf_is_fdpic(ehdr)) {
|
||||
@ -3504,12 +3541,14 @@ static void load_elf_interp(const char *filename, struct image_info *info,
|
||||
load_elf_image(filename, &src, info, &ehdr, NULL);
|
||||
}
|
||||
|
||||
#ifndef vdso_image_info
|
||||
#ifdef VDSO_HEADER
|
||||
#include VDSO_HEADER
|
||||
#define vdso_image_info() &vdso_image_info
|
||||
#define vdso_image_info(flags) &vdso_image_info
|
||||
#else
|
||||
#define vdso_image_info() NULL
|
||||
#endif
|
||||
#define vdso_image_info(flags) NULL
|
||||
#endif /* VDSO_HEADER */
|
||||
#endif /* vdso_image_info */
|
||||
|
||||
static void load_elf_vdso(struct image_info *info, const VdsoImageInfo *vdso)
|
||||
{
|
||||
@ -3840,7 +3879,7 @@ int load_elf_binary(struct linux_binprm *bprm, struct image_info *info)
|
||||
* Load a vdso if available, which will amongst other things contain the
|
||||
* signal trampolines. Otherwise, allocate a separate page for them.
|
||||
*/
|
||||
const VdsoImageInfo *vdso = vdso_image_info();
|
||||
const VdsoImageInfo *vdso = vdso_image_info(info->elf_flags);
|
||||
if (vdso) {
|
||||
load_elf_vdso(&vdso_info, vdso);
|
||||
info->vdso = vdso_info.load_bias;
|
||||
|
@ -8,4 +8,5 @@ all: $(SUBDIR)/vdso.so
|
||||
$(SUBDIR)/vdso.so: vdso.S vdso.ld vdso-asmoffset.h
|
||||
$(CC) -o $@ -nostdlib -shared -fpic -Wl,-h,linux-vdso.so.1 \
|
||||
-Wl,--build-id=sha1 -Wl,--hash-style=both \
|
||||
-Wl,--no-warn-rwx-segments -Wl,-T,$(SUBDIR)/vdso.ld $<
|
||||
-Wl,--no-warn-rwx-segments -Wl,-z,max-page-size=4096 \
|
||||
-Wl,-T,$(SUBDIR)/vdso.ld $<
|
||||
|
Binary file not shown.
@ -6,9 +6,11 @@ VPATH += $(SUBDIR)
|
||||
all: $(SUBDIR)/vdso-32.so $(SUBDIR)/vdso-64.so $(SUBDIR)/vdso-64le.so
|
||||
|
||||
LDFLAGS32 = -nostdlib -shared -Wl,-T,$(SUBDIR)/vdso-32.ld \
|
||||
-Wl,-h,linux-vdso32.so.1 -Wl,--hash-style=both -Wl,--build-id=sha1
|
||||
-Wl,-h,linux-vdso32.so.1 -Wl,--hash-style=both \
|
||||
-Wl,--build-id=sha1 -Wl,-z,max-page-size=4096
|
||||
LDFLAGS64 = -nostdlib -shared -Wl,-T,$(SUBDIR)/vdso-64.ld \
|
||||
-Wl,-h,linux-vdso64.so.1 -Wl,--hash-style=both -Wl,--build-id=sha1
|
||||
-Wl,-h,linux-vdso64.so.1 -Wl,--hash-style=both \
|
||||
-Wl,--build-id=sha1 -Wl,-z,max-page-size=4096
|
||||
|
||||
$(SUBDIR)/vdso-32.so: vdso.S vdso-32.ld vdso-asmoffset.h
|
||||
$(CC) -o $@ $(LDFLAGS32) -m32 $<
|
||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -44,7 +44,6 @@ struct image_info {
|
||||
abi_ulong file_string;
|
||||
uint32_t elf_flags;
|
||||
int personality;
|
||||
abi_ulong alignment;
|
||||
bool exec_stack;
|
||||
|
||||
/* Generic semihosting knows about these pointers. */
|
||||
|
@ -7233,12 +7233,24 @@ static inline int tswapid(int id)
|
||||
#else
|
||||
#define __NR_sys_setgroups __NR_setgroups
|
||||
#endif
|
||||
#ifdef __NR_sys_setreuid32
|
||||
#define __NR_sys_setreuid __NR_setreuid32
|
||||
#else
|
||||
#define __NR_sys_setreuid __NR_setreuid
|
||||
#endif
|
||||
#ifdef __NR_sys_setregid32
|
||||
#define __NR_sys_setregid __NR_setregid32
|
||||
#else
|
||||
#define __NR_sys_setregid __NR_setregid
|
||||
#endif
|
||||
|
||||
_syscall1(int, sys_setuid, uid_t, uid)
|
||||
_syscall1(int, sys_setgid, gid_t, gid)
|
||||
_syscall3(int, sys_setresuid, uid_t, ruid, uid_t, euid, uid_t, suid)
|
||||
_syscall3(int, sys_setresgid, gid_t, rgid, gid_t, egid, gid_t, sgid)
|
||||
_syscall2(int, sys_setgroups, int, size, gid_t *, grouplist)
|
||||
_syscall2(int, sys_setreuid, uid_t, ruid, uid_t, euid);
|
||||
_syscall2(int, sys_setregid, gid_t, rgid, gid_t, egid);
|
||||
|
||||
void syscall_init(void)
|
||||
{
|
||||
@ -11932,9 +11944,9 @@ static abi_long do_syscall1(CPUArchState *cpu_env, int num, abi_long arg1,
|
||||
return get_errno(high2lowgid(getegid()));
|
||||
#endif
|
||||
case TARGET_NR_setreuid:
|
||||
return get_errno(setreuid(low2highuid(arg1), low2highuid(arg2)));
|
||||
return get_errno(sys_setreuid(low2highuid(arg1), low2highuid(arg2)));
|
||||
case TARGET_NR_setregid:
|
||||
return get_errno(setregid(low2highgid(arg1), low2highgid(arg2)));
|
||||
return get_errno(sys_setregid(low2highgid(arg1), low2highgid(arg2)));
|
||||
case TARGET_NR_getgroups:
|
||||
{ /* the same code as for TARGET_NR_getgroups32 */
|
||||
int gidsetsize = arg1;
|
||||
@ -12264,11 +12276,11 @@ static abi_long do_syscall1(CPUArchState *cpu_env, int num, abi_long arg1,
|
||||
#endif
|
||||
#ifdef TARGET_NR_setreuid32
|
||||
case TARGET_NR_setreuid32:
|
||||
return get_errno(setreuid(arg1, arg2));
|
||||
return get_errno(sys_setreuid(arg1, arg2));
|
||||
#endif
|
||||
#ifdef TARGET_NR_setregid32
|
||||
case TARGET_NR_setregid32:
|
||||
return get_errno(setregid(arg1, arg2));
|
||||
return get_errno(sys_setregid(arg1, arg2));
|
||||
#endif
|
||||
#ifdef TARGET_NR_getgroups32
|
||||
case TARGET_NR_getgroups32:
|
||||
|
@ -6317,9 +6317,6 @@ void sve_stN_r(CPUARMState *env, uint64_t *vg, target_ulong addr,
|
||||
|
||||
flags = info.page[0].flags | info.page[1].flags;
|
||||
if (unlikely(flags != 0)) {
|
||||
#ifdef CONFIG_USER_ONLY
|
||||
g_assert_not_reached();
|
||||
#else
|
||||
/*
|
||||
* At least one page includes MMIO.
|
||||
* Any bus operation can fail with cpu_transaction_failed,
|
||||
@ -6350,7 +6347,6 @@ void sve_stN_r(CPUARMState *env, uint64_t *vg, target_ulong addr,
|
||||
} while (reg_off & 63);
|
||||
} while (reg_off <= reg_last);
|
||||
return;
|
||||
#endif
|
||||
}
|
||||
|
||||
mem_off = info.mem_off_first[0];
|
||||
|
@ -107,6 +107,10 @@ static bool ptw_setl_slow(const PTETranslate *in, uint32_t old, uint32_t new)
|
||||
{
|
||||
uint32_t cmp;
|
||||
|
||||
CPUState *cpu = env_cpu(in->env);
|
||||
/* We are in cpu_exec, and start_exclusive can't be called directly.*/
|
||||
g_assert(cpu->running);
|
||||
cpu_exec_end(cpu);
|
||||
/* Does x86 really perform a rmw cycle on mmio for ptw? */
|
||||
start_exclusive();
|
||||
cmp = cpu_ldl_mmuidx_ra(in->env, in->gaddr, in->ptw_idx, 0);
|
||||
@ -114,6 +118,7 @@ static bool ptw_setl_slow(const PTETranslate *in, uint32_t old, uint32_t new)
|
||||
cpu_stl_mmuidx_ra(in->env, in->gaddr, new, in->ptw_idx, 0);
|
||||
}
|
||||
end_exclusive();
|
||||
cpu_exec_start(cpu);
|
||||
return cmp == old;
|
||||
}
|
||||
|
||||
|
@ -88,7 +88,20 @@ uint32_t simd_desc(uint32_t oprsz, uint32_t maxsz, int32_t data)
|
||||
uint32_t desc = 0;
|
||||
|
||||
check_size_align(oprsz, maxsz, 0);
|
||||
tcg_debug_assert(data == sextract32(data, 0, SIMD_DATA_BITS));
|
||||
|
||||
/*
|
||||
* We want to check that 'data' will fit into SIMD_DATA_BITS.
|
||||
* However, some callers want to treat the data as a signed
|
||||
* value (which they can later get back with simd_data())
|
||||
* and some want to treat it as an unsigned value.
|
||||
* So here we assert only that the data will fit into the
|
||||
* field in at least one way. This means that some invalid
|
||||
* values from the caller will not be detected, e.g. if the
|
||||
* caller wants to handle the value as a signed integer but
|
||||
* incorrectly passes us 1 << (SIMD_DATA_BITS - 1).
|
||||
*/
|
||||
tcg_debug_assert(data == sextract32(data, 0, SIMD_DATA_BITS) ||
|
||||
data == extract32(data, 0, SIMD_DATA_BITS));
|
||||
|
||||
oprsz = (oprsz / 8) - 1;
|
||||
maxsz = (maxsz / 8) - 1;
|
||||
|
@ -42,6 +42,9 @@ munmap-pthread: LDFLAGS+=-pthread
|
||||
vma-pthread: CFLAGS+=-pthread
|
||||
vma-pthread: LDFLAGS+=-pthread
|
||||
|
||||
sigreturn-sigmask: CFLAGS+=-pthread
|
||||
sigreturn-sigmask: LDFLAGS+=-pthread
|
||||
|
||||
# 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),)
|
||||
|
51
tests/tcg/multiarch/sigreturn-sigmask.c
Normal file
51
tests/tcg/multiarch/sigreturn-sigmask.c
Normal file
@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Test that sigreturn() does not corrupt the signal mask.
|
||||
* Block SIGUSR2 and handle SIGUSR1.
|
||||
* Then sigwait() SIGUSR2, which relies on it remaining blocked.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
*/
|
||||
#include <assert.h>
|
||||
#include <pthread.h>
|
||||
#include <signal.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
int seen_sig = -1;
|
||||
|
||||
static void signal_func(int sig)
|
||||
{
|
||||
seen_sig = sig;
|
||||
}
|
||||
|
||||
static void *thread_func(void *arg)
|
||||
{
|
||||
kill(getpid(), SIGUSR2);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
struct sigaction act = {
|
||||
.sa_handler = signal_func,
|
||||
};
|
||||
pthread_t thread;
|
||||
sigset_t set;
|
||||
int sig;
|
||||
|
||||
assert(sigaction(SIGUSR1, &act, NULL) == 0);
|
||||
|
||||
assert(sigemptyset(&set) == 0);
|
||||
assert(sigaddset(&set, SIGUSR2) == 0);
|
||||
assert(sigprocmask(SIG_BLOCK, &set, NULL) == 0);
|
||||
|
||||
kill(getpid(), SIGUSR1);
|
||||
assert(seen_sig == SIGUSR1);
|
||||
|
||||
assert(pthread_create(&thread, NULL, thread_func, NULL) == 0);
|
||||
assert(sigwait(&set, &sig) == 0);
|
||||
assert(sig == SIGUSR2);
|
||||
assert(pthread_join(thread, NULL) == 0);
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
Loading…
Reference in New Issue
Block a user