From ffeddd75798586bbebd20c8756d6ea28dc1874d6 Mon Sep 17 00:00:00 2001 From: mio Date: Thu, 17 Oct 2024 13:34:31 +0800 Subject: [PATCH] use qemu_memalign for all cpu structs Some structs, specically CPUARMState is 16-bytes aligned. This causes segment fault because gcc tends to vectorize the assignment of the struct with infamous movaps tricks. Without this patch, we fail on manylinux with 2.17 glibc in release mode in i686. qemu_memalign will ensure the alignment across platforms. --- qemu/target/arm/cpu.c | 4 +++- qemu/target/arm/cpu64.c | 4 +++- qemu/target/i386/cpu.c | 3 ++- qemu/target/m68k/cpu.c | 3 ++- qemu/target/mips/cpu.c | 3 ++- qemu/target/ppc/translate_init.inc.c | 2 +- qemu/target/riscv/cpu.c | 3 ++- qemu/target/s390x/cpu.c | 3 ++- qemu/target/sparc/cpu.c | 4 ++-- qemu/target/tricore/cpu.c | 3 ++- uc.c | 2 +- 11 files changed, 22 insertions(+), 12 deletions(-) diff --git a/qemu/target/arm/cpu.c b/qemu/target/arm/cpu.c index bbcbe83f..76133819 100644 --- a/qemu/target/arm/cpu.c +++ b/qemu/target/arm/cpu.c @@ -2102,10 +2102,12 @@ ARMCPU *cpu_arm_init(struct uc_struct *uc) CPUClass *cc; CPUARMState *env; - cpu = calloc(1, sizeof(*cpu)); + // cpu->env is 16 bytes aligned + cpu = qemu_memalign(16, sizeof(*cpu)); if (cpu == NULL) { return NULL; } + memset((void*)cpu, 0, sizeof(*cpu)); #if !defined(TARGET_AARCH64) if (uc->mode & UC_MODE_MCLASS) { diff --git a/qemu/target/arm/cpu64.c b/qemu/target/arm/cpu64.c index e6f01bb1..3c57a52a 100644 --- a/qemu/target/arm/cpu64.c +++ b/qemu/target/arm/cpu64.c @@ -325,10 +325,12 @@ ARMCPU *cpu_aarch64_init(struct uc_struct *uc) CPUClass *cc; CPUARMState *env; - cpu = calloc(1, sizeof(*cpu)); + // cpu->env is 16 bytes alignment + cpu = qemu_memalign(16, sizeof(*cpu)); if (cpu == NULL) { return NULL; } + memset((void*)cpu, 0, sizeof(*cpu)); if (uc->cpu_model == INT_MAX) { uc->cpu_model = UC_CPU_ARM64_A72; diff --git a/qemu/target/i386/cpu.c b/qemu/target/i386/cpu.c index 826a89f8..854aaa74 100644 --- a/qemu/target/i386/cpu.c +++ b/qemu/target/i386/cpu.c @@ -5076,10 +5076,11 @@ X86CPU *cpu_x86_init(struct uc_struct *uc) CPUClass *cc; X86CPUClass *xcc; - cpu = calloc(1, sizeof(*cpu)); + cpu = qemu_memalign(8, sizeof(*cpu)); if (cpu == NULL) { return NULL; } + memset((void*)cpu, 0, sizeof(*cpu)); if (uc->cpu_model == INT_MAX) { #ifdef TARGET_X86_64 diff --git a/qemu/target/m68k/cpu.c b/qemu/target/m68k/cpu.c index e3dc9484..6b636b80 100644 --- a/qemu/target/m68k/cpu.c +++ b/qemu/target/m68k/cpu.c @@ -265,10 +265,11 @@ M68kCPU *cpu_m68k_init(struct uc_struct *uc) CPUState *cs; CPUClass *cc; - cpu = calloc(1, sizeof(*cpu)); + cpu = qemu_memalign(8, sizeof(*cpu)); if (cpu == NULL) { return NULL; } + memset((void*)cpu, 0, sizeof(*cpu)); if (uc->cpu_model == INT_MAX) { uc->cpu_model = UC_CPU_M68K_CFV4E; // cfv4e diff --git a/qemu/target/mips/cpu.c b/qemu/target/mips/cpu.c index 27ad1199..640c8c9b 100644 --- a/qemu/target/mips/cpu.c +++ b/qemu/target/mips/cpu.c @@ -157,10 +157,11 @@ MIPSCPU *cpu_mips_init(struct uc_struct *uc) CPUClass *cc; CPUMIPSState *env; - cpu = calloc(1, sizeof(*cpu)); + cpu = qemu_memalign(8, sizeof(*cpu)); if (cpu == NULL) { return NULL; } + memset((void*)cpu, 0, sizeof(*cpu)); #ifdef TARGET_MIPS64 if (uc->cpu_model == INT_MAX) { diff --git a/qemu/target/ppc/translate_init.inc.c b/qemu/target/ppc/translate_init.inc.c index 782effaa..1f6d98b7 100644 --- a/qemu/target/ppc/translate_init.inc.c +++ b/qemu/target/ppc/translate_init.inc.c @@ -11016,7 +11016,7 @@ PowerPCCPU *cpu_ppc_init(struct uc_struct *uc) CPUClass *cc; PowerPCCPUClass *pcc; - cpu = malloc(sizeof(*cpu)); + cpu = qemu_memalign(8, sizeof(*cpu)); if (cpu == NULL) { return NULL; } diff --git a/qemu/target/riscv/cpu.c b/qemu/target/riscv/cpu.c index 6405abd4..2313cfc6 100644 --- a/qemu/target/riscv/cpu.c +++ b/qemu/target/riscv/cpu.c @@ -335,10 +335,11 @@ RISCVCPU *cpu_riscv_init(struct uc_struct *uc) CPUState *cs; CPUClass *cc; - cpu = calloc(1, sizeof(*cpu)); + cpu = qemu_memalign(8, sizeof(*cpu)); if (cpu == NULL) { return NULL; } + memset((void*)cpu, 0, sizeof(*cpu)); #ifdef TARGET_RISCV32 if (uc->cpu_model == INT_MAX) { diff --git a/qemu/target/s390x/cpu.c b/qemu/target/s390x/cpu.c index a9068715..036077a6 100644 --- a/qemu/target/s390x/cpu.c +++ b/qemu/target/s390x/cpu.c @@ -245,10 +245,11 @@ S390CPU *cpu_s390_init(struct uc_struct *uc, const char *cpu_model) CPUClass *cc; // int i; - cpu = calloc(1, sizeof(*cpu)); + cpu = qemu_memalign(8, sizeof(*cpu)); if (cpu == NULL) { return NULL; } + memset((void*)cpu, 0, sizeof(*cpu)); if (uc->cpu_model == INT_MAX) { uc->cpu_model = UC_CPU_S390X_QEMU; // qemu-s390x-cpu diff --git a/qemu/target/sparc/cpu.c b/qemu/target/sparc/cpu.c index e1386a15..e0e1962d 100644 --- a/qemu/target/sparc/cpu.c +++ b/qemu/target/sparc/cpu.c @@ -517,11 +517,11 @@ SPARCCPU *cpu_sparc_init(struct uc_struct *uc) CPUClass *cc; SPARCCPUClass *scc; - cpu = malloc(sizeof(*cpu)); + cpu = qemu_memalign(8, sizeof(*cpu)); if (cpu == NULL) { return NULL; } - memset(cpu, 0, sizeof(*cpu)); + memset((void*)cpu, 0, sizeof(*cpu)); if (uc->cpu_model == INT_MAX) { #ifdef TARGET_SPARC64 diff --git a/qemu/target/tricore/cpu.c b/qemu/target/tricore/cpu.c index 8a871f45..c980b505 100644 --- a/qemu/target/tricore/cpu.c +++ b/qemu/target/tricore/cpu.c @@ -165,10 +165,11 @@ TriCoreCPU *cpu_tricore_init(struct uc_struct *uc) CPUState *cs; CPUClass *cc; - cpu = calloc(1, sizeof(*cpu)); + cpu = qemu_memalign(8, sizeof(*cpu)); if (cpu == NULL) { return NULL; } + memset((void*)cpu, 0, sizeof(*cpu)); if (uc->cpu_model == INT_MAX) { uc->cpu_model = 2; // tc27x diff --git a/uc.c b/uc.c index 4ba27d8a..0ff4196f 100644 --- a/uc.c +++ b/uc.c @@ -515,7 +515,7 @@ uc_err uc_close(uc_engine *uc) g_free(uc->cpu->thread); /* cpu */ - free(uc->cpu); + qemu_vfree(uc->cpu); /* flatviews */ g_hash_table_destroy(uc->flat_views);