From nobody Sat Apr 20 00:21:55 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1631570998588919.9524474520936; Mon, 13 Sep 2021 15:09:58 -0700 (PDT) Received: from localhost ([::1]:57516 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1mPu9F-0007kV-Cp for importer@patchew.org; Mon, 13 Sep 2021 18:09:57 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:34394) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mPu5Q-0001or-H1 for qemu-devel@nongnu.org; Mon, 13 Sep 2021 18:06:01 -0400 Received: from mail-pj1-x102d.google.com ([2607:f8b0:4864:20::102d]:54220) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1mPu5M-0007LK-Qr for qemu-devel@nongnu.org; Mon, 13 Sep 2021 18:05:59 -0400 Received: by mail-pj1-x102d.google.com with SMTP id j1so7403987pjv.3 for ; Mon, 13 Sep 2021 15:05:56 -0700 (PDT) Received: from localhost.localdomain ([71.212.134.125]) by smtp.gmail.com with ESMTPSA id 17sm7721404pfx.167.2021.09.13.15.05.54 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 13 Sep 2021 15:05:54 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=A2q/ulspIr5RbtYqF+D7jLOWB7Fh8193+fEA6igokXI=; b=mIlPs1cxMoeXKG76oNGdrcukbJOmiBVtKMBNGEI4YQjiKkuhgEMKqAbXKw5FjHSj1k WFwdoeqVo1H82rR2NXA+oXAyYleoHMA+0iKZ/IKxxEZHEUIMpjkAtdQ7wHM4+DSnyd4U J/3j9uD8QORv5hAsK1Fr2UNJ1NYqbTsjo50OnPdLDdpN7FzoTlSzA4TBDZMqQv5ok7vt 4c70qtgt+IuIGQoGKA7eKEJF2+2nix2s6YDeZ+p9m6iYJAJGKJRBvRKrhrmmGrydWQMS 2HCT1Z0Dh2LMgnVkjWUqmAH8vkXu8vh5EuW7WboDoMjqCR0/ZcX8kksn89YaPMW92L7m qx9g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=A2q/ulspIr5RbtYqF+D7jLOWB7Fh8193+fEA6igokXI=; b=AejH56RENgvnxs4KQFJUEKIjposuosYJKLVbe9zYjnItZwckZRzwdlOhTKrdcLGEX2 gk5ywLmR+ho6B3qrLi/BMBM/TGtivMIp9/ytcB9spkYzJcsDxMmAQD/YZm510TAT1T+R FGc3xSsQqreVqkAwgMpSasbXjLjnMiYGThcD6pQX5rCEUa7fYA89qUsjtVO3dG3a8Na5 Ba+P1rzjaudI7rpNRSgtZu6dq+1M/Sisn0oUXpf4IZnrELWZf0ZYrayFxwPXiDH7sNwa TGfRnLGdfZJ3/3T0hf2wlzUXsBdui6e8Ed93wZc2eyA1iUHYI3jHTcY6IstoO9CvFRWc 9W7g== X-Gm-Message-State: AOAM533cFAjOwuKD8SWUam0RT+h9+zx+VIdd5Z43r8uG8fYicy0oIr6O VU5Yx+Oei3NoT3l/uaCYJV6isu5ZiZTkXQ== X-Google-Smtp-Source: ABdhPJxdOab3r7owLfXgd4fKgrs0I/qp2SFCEPvu+eWeDk17Pn1PH6uUs2rEuqGhIEvwXL5WSGm8uA== X-Received: by 2002:a17:90b:4a84:: with SMTP id lp4mr1924112pjb.34.1631570755326; Mon, 13 Sep 2021 15:05:55 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Subject: [RFC PATCH 1/7] include/exec: Move cpu_signal_handler declaration Date: Mon, 13 Sep 2021 15:05:46 -0700 Message-Id: <20210913220552.604064-2-richard.henderson@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210913220552.604064-1-richard.henderson@linaro.org> References: <20210913220552.604064-1-richard.henderson@linaro.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=2607:f8b0:4864:20::102d; envelope-from=richard.henderson@linaro.org; helo=mail-pj1-x102d.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: peter.maydell@linaro.org, Alistair Francis , laurent@vivier.eu, imp@bsdimp.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1631570999815100001 Content-Type: text/plain; charset="utf-8" There is nothing target specific about this. The implementation is host specific, but the declaration is 100% common. Reviewed-by: Alistair Francis Signed-off-by: Richard Henderson Reviewed-By: Warner Losh Reviewed-by: Philippe Mathieu-Daud=C3=A9 --- include/exec/exec-all.h | 13 +++++++++++++ target/alpha/cpu.h | 6 ------ target/arm/cpu.h | 7 ------- target/avr/cpu.h | 2 -- target/cris/cpu.h | 8 -------- target/hexagon/cpu.h | 3 --- target/hppa/cpu.h | 3 --- target/i386/cpu.h | 7 ------- target/m68k/cpu.h | 8 -------- target/microblaze/cpu.h | 7 ------- target/mips/cpu.h | 3 --- target/mips/internal.h | 2 -- target/nios2/cpu.h | 2 -- target/openrisc/cpu.h | 2 -- target/ppc/cpu.h | 7 ------- target/riscv/cpu.h | 2 -- target/rx/cpu.h | 4 ---- target/s390x/cpu.h | 7 ------- target/sh4/cpu.h | 3 --- target/sparc/cpu.h | 2 -- target/tricore/cpu.h | 2 -- target/xtensa/cpu.h | 2 -- 22 files changed, 13 insertions(+), 89 deletions(-) diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h index 5d1b6d80fb..9d5987ba04 100644 --- a/include/exec/exec-all.h +++ b/include/exec/exec-all.h @@ -662,6 +662,19 @@ static inline tb_page_addr_t get_page_addr_code_hostp(= CPUArchState *env, } return addr; } + +/** + * cpu_signal_handler + * @signum: host signal number + * @pinfo: host siginfo_t + * @puc: host ucontext_t + * + * To be called from the SIGBUS and SIGSEGV signal handler to inform the + * virtual cpu of exceptions. Returns true if the signal was handled by + * the virtual CPU. + */ +int cpu_signal_handler(int signum, void *pinfo, void *puc); + #else static inline void mmap_lock(void) {} static inline void mmap_unlock(void) {} diff --git a/target/alpha/cpu.h b/target/alpha/cpu.h index 4e993bd15b..ce9ec32199 100644 --- a/target/alpha/cpu.h +++ b/target/alpha/cpu.h @@ -287,7 +287,6 @@ void alpha_cpu_do_unaligned_access(CPUState *cpu, vaddr= addr, int mmu_idx, uintptr_t retaddr); =20 #define cpu_list alpha_cpu_list -#define cpu_signal_handler cpu_alpha_signal_handler =20 typedef CPUAlphaState CPUArchState; typedef AlphaCPU ArchCPU; @@ -440,11 +439,6 @@ void alpha_translate_init(void); #define CPU_RESOLVING_TYPE TYPE_ALPHA_CPU =20 void alpha_cpu_list(void); -/* you can call this signal handler from your SIGBUS and SIGSEGV - signal handlers to inform the virtual CPU of exceptions. non zero - is returned if the signal was handled by the virtual CPU. */ -int cpu_alpha_signal_handler(int host_signum, void *pinfo, - void *puc); bool alpha_cpu_tlb_fill(CPUState *cs, vaddr address, int size, MMUAccessType access_type, int mmu_idx, bool probe, uintptr_t retaddr); diff --git a/target/arm/cpu.h b/target/arm/cpu.h index cfd755cff9..6c78957e54 100644 --- a/target/arm/cpu.h +++ b/target/arm/cpu.h @@ -1121,12 +1121,6 @@ static inline bool is_a64(CPUARMState *env) return env->aarch64; } =20 -/* you can call this signal handler from your SIGBUS and SIGSEGV - signal handlers to inform the virtual CPU of exceptions. non zero - is returned if the signal was handled by the virtual CPU. */ -int cpu_arm_signal_handler(int host_signum, void *pinfo, - void *puc); - /** * pmu_op_start/finish * @env: CPUARMState @@ -3015,7 +3009,6 @@ bool write_cpustate_to_list(ARMCPU *cpu, bool kvm_syn= c); #define ARM_CPU_TYPE_NAME(name) (name ARM_CPU_TYPE_SUFFIX) #define CPU_RESOLVING_TYPE TYPE_ARM_CPU =20 -#define cpu_signal_handler cpu_arm_signal_handler #define cpu_list arm_cpu_list =20 /* ARM has the following "translation regimes" (as the ARM ARM calls them): diff --git a/target/avr/cpu.h b/target/avr/cpu.h index 93e3faa0a9..dceacf3cd7 100644 --- a/target/avr/cpu.h +++ b/target/avr/cpu.h @@ -175,7 +175,6 @@ static inline void set_avr_feature(CPUAVRState *env, in= t feature) } =20 #define cpu_list avr_cpu_list -#define cpu_signal_handler cpu_avr_signal_handler #define cpu_mmu_index avr_cpu_mmu_index =20 static inline int avr_cpu_mmu_index(CPUAVRState *env, bool ifetch) @@ -187,7 +186,6 @@ void avr_cpu_tcg_init(void); =20 void avr_cpu_list(void); int cpu_avr_exec(CPUState *cpu); -int cpu_avr_signal_handler(int host_signum, void *pinfo, void *puc); int avr_cpu_memory_rw_debug(CPUState *cs, vaddr address, uint8_t *buf, int len, bool is_write); =20 diff --git a/target/cris/cpu.h b/target/cris/cpu.h index be021899ae..6603565f83 100644 --- a/target/cris/cpu.h +++ b/target/cris/cpu.h @@ -199,12 +199,6 @@ int crisv10_cpu_gdb_read_register(CPUState *cpu, GByte= Array *buf, int reg); int cris_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg); int cris_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg); =20 -/* you can call this signal handler from your SIGBUS and SIGSEGV - signal handlers to inform the virtual CPU of exceptions. non zero - is returned if the signal was handled by the virtual CPU. */ -int cpu_cris_signal_handler(int host_signum, void *pinfo, - void *puc); - void cris_initialize_tcg(void); void cris_initialize_crisv10_tcg(void); =20 @@ -250,8 +244,6 @@ enum { #define CRIS_CPU_TYPE_NAME(name) (name CRIS_CPU_TYPE_SUFFIX) #define CPU_RESOLVING_TYPE TYPE_CRIS_CPU =20 -#define cpu_signal_handler cpu_cris_signal_handler - /* MMU modes definitions */ #define MMU_USER_IDX 1 static inline int cpu_mmu_index (CPUCRISState *env, bool ifetch) diff --git a/target/hexagon/cpu.h b/target/hexagon/cpu.h index 2855dd3881..f7d043865b 100644 --- a/target/hexagon/cpu.h +++ b/target/hexagon/cpu.h @@ -129,9 +129,6 @@ typedef struct HexagonCPU { =20 #include "cpu_bits.h" =20 -#define cpu_signal_handler cpu_hexagon_signal_handler -int cpu_hexagon_signal_handler(int host_signum, void *pinfo, void *puc); - static inline void cpu_get_tb_cpu_state(CPUHexagonState *env, target_ulong= *pc, target_ulong *cs_base, uint32_t *f= lags) { diff --git a/target/hppa/cpu.h b/target/hppa/cpu.h index 7854675b90..d3cb7a279f 100644 --- a/target/hppa/cpu.h +++ b/target/hppa/cpu.h @@ -319,9 +319,6 @@ static inline void cpu_hppa_change_prot_id(CPUHPPAState= *env) { } void cpu_hppa_change_prot_id(CPUHPPAState *env); #endif =20 -#define cpu_signal_handler cpu_hppa_signal_handler - -int cpu_hppa_signal_handler(int host_signum, void *pinfo, void *puc); hwaddr hppa_cpu_get_phys_page_debug(CPUState *cs, vaddr addr); int hppa_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg); int hppa_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg); diff --git a/target/i386/cpu.h b/target/i386/cpu.h index 7dd664791a..c2954c71ea 100644 --- a/target/i386/cpu.h +++ b/target/i386/cpu.h @@ -1947,12 +1947,6 @@ void cpu_x86_frstor(CPUX86State *s, target_ulong ptr= , int data32); void cpu_x86_fxsave(CPUX86State *s, target_ulong ptr); void cpu_x86_fxrstor(CPUX86State *s, target_ulong ptr); =20 -/* you can call this signal handler from your SIGBUS and SIGSEGV - signal handlers to inform the virtual CPU of exceptions. non zero - is returned if the signal was handled by the virtual CPU. */ -int cpu_x86_signal_handler(int host_signum, void *pinfo, - void *puc); - /* cpu.c */ void x86_cpu_vendor_words2str(char *dst, uint32_t vendor1, uint32_t vendor2, uint32_t vendor3); @@ -2020,7 +2014,6 @@ uint64_t cpu_get_tsc(CPUX86State *env); #define TARGET_DEFAULT_CPU_TYPE X86_CPU_TYPE_NAME("qemu32") #endif =20 -#define cpu_signal_handler cpu_x86_signal_handler #define cpu_list x86_cpu_list =20 /* MMU modes definitions */ diff --git a/target/m68k/cpu.h b/target/m68k/cpu.h index 550eb028b6..a3423729ef 100644 --- a/target/m68k/cpu.h +++ b/target/m68k/cpu.h @@ -177,13 +177,6 @@ int m68k_cpu_gdb_write_register(CPUState *cpu, uint8_t= *buf, int reg); =20 void m68k_tcg_init(void); void m68k_cpu_init_gdb(M68kCPU *cpu); -/* - * you can call this signal handler from your SIGBUS and SIGSEGV - * signal handlers to inform the virtual CPU of exceptions. non zero - * is returned if the signal was handled by the virtual CPU. - */ -int cpu_m68k_signal_handler(int host_signum, void *pinfo, - void *puc); uint32_t cpu_m68k_get_ccr(CPUM68KState *env); void cpu_m68k_set_ccr(CPUM68KState *env, uint32_t); void cpu_m68k_set_sr(CPUM68KState *env, uint32_t); @@ -563,7 +556,6 @@ enum { #define M68K_CPU_TYPE_NAME(model) model M68K_CPU_TYPE_SUFFIX #define CPU_RESOLVING_TYPE TYPE_M68K_CPU =20 -#define cpu_signal_handler cpu_m68k_signal_handler #define cpu_list m68k_cpu_list =20 /* MMU modes definitions */ diff --git a/target/microblaze/cpu.h b/target/microblaze/cpu.h index 40401c33b7..13ed3cd4dd 100644 --- a/target/microblaze/cpu.h +++ b/target/microblaze/cpu.h @@ -385,16 +385,9 @@ static inline void mb_cpu_write_msr(CPUMBState *env, u= int32_t val) } =20 void mb_tcg_init(void); -/* you can call this signal handler from your SIGBUS and SIGSEGV - signal handlers to inform the virtual CPU of exceptions. non zero - is returned if the signal was handled by the virtual CPU. */ -int cpu_mb_signal_handler(int host_signum, void *pinfo, - void *puc); =20 #define CPU_RESOLVING_TYPE TYPE_MICROBLAZE_CPU =20 -#define cpu_signal_handler cpu_mb_signal_handler - /* MMU modes definitions */ #define MMU_NOMMU_IDX 0 #define MMU_KERNEL_IDX 1 diff --git a/target/mips/cpu.h b/target/mips/cpu.h index 1dfe69c6c0..56b1cbd091 100644 --- a/target/mips/cpu.h +++ b/target/mips/cpu.h @@ -1193,7 +1193,6 @@ struct MIPSCPU { =20 void mips_cpu_list(void); =20 -#define cpu_signal_handler cpu_mips_signal_handler #define cpu_list mips_cpu_list =20 extern void cpu_wrdsp(uint32_t rs, uint32_t mask_num, CPUMIPSState *env); @@ -1277,8 +1276,6 @@ enum { */ #define CPU_INTERRUPT_WAKE CPU_INTERRUPT_TGT_INT_0 =20 -int cpu_mips_signal_handler(int host_signum, void *pinfo, void *puc); - #define MIPS_CPU_TYPE_SUFFIX "-" TYPE_MIPS_CPU #define MIPS_CPU_TYPE_NAME(model) model MIPS_CPU_TYPE_SUFFIX #define CPU_RESOLVING_TYPE TYPE_MIPS_CPU diff --git a/target/mips/internal.h b/target/mips/internal.h index eecdd10116..daddb05fd4 100644 --- a/target/mips/internal.h +++ b/target/mips/internal.h @@ -156,8 +156,6 @@ extern const VMStateDescription vmstate_mips_cpu; =20 #endif /* !CONFIG_USER_ONLY */ =20 -#define cpu_signal_handler cpu_mips_signal_handler - static inline bool cpu_mips_hw_interrupts_enabled(CPUMIPSState *env) { return (env->CP0_Status & (1 << CP0St_IE)) && diff --git a/target/nios2/cpu.h b/target/nios2/cpu.h index 2ab82fdc71..88a511209c 100644 --- a/target/nios2/cpu.h +++ b/target/nios2/cpu.h @@ -193,7 +193,6 @@ struct Nios2CPU { =20 void nios2_tcg_init(void); void nios2_cpu_do_interrupt(CPUState *cs); -int cpu_nios2_signal_handler(int host_signum, void *pinfo, void *puc); void dump_mmu(CPUNios2State *env); void nios2_cpu_dump_state(CPUState *cpu, FILE *f, int flags); hwaddr nios2_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr); @@ -206,7 +205,6 @@ void do_nios2_semihosting(CPUNios2State *env); #define CPU_RESOLVING_TYPE TYPE_NIOS2_CPU =20 #define cpu_gen_code cpu_nios2_gen_code -#define cpu_signal_handler cpu_nios2_signal_handler =20 #define CPU_SAVE_VERSION 1 =20 diff --git a/target/openrisc/cpu.h b/target/openrisc/cpu.h index be6df81a81..187a4a114e 100644 --- a/target/openrisc/cpu.h +++ b/target/openrisc/cpu.h @@ -320,11 +320,9 @@ void openrisc_translate_init(void); bool openrisc_cpu_tlb_fill(CPUState *cs, vaddr address, int size, MMUAccessType access_type, int mmu_idx, bool probe, uintptr_t retaddr); -int cpu_openrisc_signal_handler(int host_signum, void *pinfo, void *puc); int print_insn_or1k(bfd_vma addr, disassemble_info *info); =20 #define cpu_list cpu_openrisc_list -#define cpu_signal_handler cpu_openrisc_signal_handler =20 #ifndef CONFIG_USER_ONLY extern const VMStateDescription vmstate_openrisc_cpu; diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h index 362e7c4c5c..01d3773bc7 100644 --- a/target/ppc/cpu.h +++ b/target/ppc/cpu.h @@ -1278,12 +1278,6 @@ extern const VMStateDescription vmstate_ppc_cpu; =20 /*************************************************************************= ****/ void ppc_translate_init(void); -/* - * you can call this signal handler from your SIGBUS and SIGSEGV - * signal handlers to inform the virtual CPU of exceptions. non zero - * is returned if the signal was handled by the virtual CPU. - */ -int cpu_ppc_signal_handler(int host_signum, void *pinfo, void *puc); bool ppc_cpu_tlb_fill(CPUState *cs, vaddr address, int size, MMUAccessType access_type, int mmu_idx, bool probe, uintptr_t retaddr); @@ -1371,7 +1365,6 @@ int ppc_dcr_write(ppc_dcr_t *dcr_env, int dcrn, uint3= 2_t val); #define POWERPC_CPU_TYPE_NAME(model) model POWERPC_CPU_TYPE_SUFFIX #define CPU_RESOLVING_TYPE TYPE_POWERPC_CPU =20 -#define cpu_signal_handler cpu_ppc_signal_handler #define cpu_list ppc_cpu_list =20 /* MMU modes definitions */ diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h index e735e53e26..465142616a 100644 --- a/target/riscv/cpu.h +++ b/target/riscv/cpu.h @@ -356,7 +356,6 @@ void riscv_cpu_do_transaction_failed(CPUState *cs, hwad= dr physaddr, char *riscv_isa_string(RISCVCPU *cpu); void riscv_cpu_list(void); =20 -#define cpu_signal_handler riscv_cpu_signal_handler #define cpu_list riscv_cpu_list #define cpu_mmu_index riscv_cpu_mmu_index =20 @@ -372,7 +371,6 @@ void riscv_cpu_set_rdtime_fn(CPURISCVState *env, uint64= _t (*fn)(uint32_t), void riscv_cpu_set_mode(CPURISCVState *env, target_ulong newpriv); =20 void riscv_translate_init(void); -int riscv_cpu_signal_handler(int host_signum, void *pinfo, void *puc); void QEMU_NORETURN riscv_raise_exception(CPURISCVState *env, uint32_t exception, uintptr_t pc); =20 diff --git a/target/rx/cpu.h b/target/rx/cpu.h index faa3606f52..4ac71aec37 100644 --- a/target/rx/cpu.h +++ b/target/rx/cpu.h @@ -134,13 +134,9 @@ int rx_cpu_gdb_write_register(CPUState *cpu, uint8_t *= buf, int reg); hwaddr rx_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr); =20 void rx_translate_init(void); -int cpu_rx_signal_handler(int host_signum, void *pinfo, - void *puc); - void rx_cpu_list(void); void rx_cpu_unpack_psw(CPURXState *env, uint32_t psw, int rte); =20 -#define cpu_signal_handler cpu_rx_signal_handler #define cpu_list rx_cpu_list =20 #include "exec/cpu-all.h" diff --git a/target/s390x/cpu.h b/target/s390x/cpu.h index b26ae8fff2..3153d053e9 100644 --- a/target/s390x/cpu.h +++ b/target/s390x/cpu.h @@ -809,13 +809,6 @@ void s390_set_qemu_cpu_model(uint16_t type, uint8_t ge= n, uint8_t ec_ga, #define S390_CPU_TYPE_NAME(name) (name S390_CPU_TYPE_SUFFIX) #define CPU_RESOLVING_TYPE TYPE_S390_CPU =20 -/* you can call this signal handler from your SIGBUS and SIGSEGV - signal handlers to inform the virtual CPU of exceptions. non zero - is returned if the signal was handled by the virtual CPU. */ -int cpu_s390x_signal_handler(int host_signum, void *pinfo, void *puc); -#define cpu_signal_handler cpu_s390x_signal_handler - - /* interrupt.c */ #define RA_IGNORED 0 void s390_program_interrupt(CPUS390XState *env, uint32_t code, uintptr_t r= a); diff --git a/target/sh4/cpu.h b/target/sh4/cpu.h index 017a770214..56f7c32df9 100644 --- a/target/sh4/cpu.h +++ b/target/sh4/cpu.h @@ -213,8 +213,6 @@ void superh_cpu_do_unaligned_access(CPUState *cpu, vadd= r addr, int mmu_idx, uintptr_t retaddr); =20 void sh4_translate_init(void); -int cpu_sh4_signal_handler(int host_signum, void *pinfo, - void *puc); bool superh_cpu_tlb_fill(CPUState *cs, vaddr address, int size, MMUAccessType access_type, int mmu_idx, bool probe, uintptr_t retaddr); @@ -250,7 +248,6 @@ void cpu_load_tlb(CPUSH4State * env); #define SUPERH_CPU_TYPE_NAME(model) model SUPERH_CPU_TYPE_SUFFIX #define CPU_RESOLVING_TYPE TYPE_SUPERH_CPU =20 -#define cpu_signal_handler cpu_sh4_signal_handler #define cpu_list sh4_cpu_list =20 /* MMU modes definitions */ diff --git a/target/sparc/cpu.h b/target/sparc/cpu.h index ff8ae73002..6b40d02237 100644 --- a/target/sparc/cpu.h +++ b/target/sparc/cpu.h @@ -649,13 +649,11 @@ hwaddr cpu_get_phys_page_nofault(CPUSPARCState *env, = target_ulong addr, int mmu_idx); #endif #endif -int cpu_sparc_signal_handler(int host_signum, void *pinfo, void *puc); =20 #define SPARC_CPU_TYPE_SUFFIX "-" TYPE_SPARC_CPU #define SPARC_CPU_TYPE_NAME(model) model SPARC_CPU_TYPE_SUFFIX #define CPU_RESOLVING_TYPE TYPE_SPARC_CPU =20 -#define cpu_signal_handler cpu_sparc_signal_handler #define cpu_list sparc_cpu_list =20 /* MMU modes definitions */ diff --git a/target/tricore/cpu.h b/target/tricore/cpu.h index 4b61a2c03f..c461387e71 100644 --- a/target/tricore/cpu.h +++ b/target/tricore/cpu.h @@ -362,7 +362,6 @@ void fpu_set_state(CPUTriCoreState *env); =20 void tricore_cpu_list(void); =20 -#define cpu_signal_handler cpu_tricore_signal_handler #define cpu_list tricore_cpu_list =20 static inline int cpu_mmu_index(CPUTriCoreState *env, bool ifetch) @@ -377,7 +376,6 @@ typedef TriCoreCPU ArchCPU; =20 void cpu_state_reset(CPUTriCoreState *s); void tricore_tcg_init(void); -int cpu_tricore_signal_handler(int host_signum, void *pinfo, void *puc); =20 static inline void cpu_get_tb_cpu_state(CPUTriCoreState *env, target_ulong= *pc, target_ulong *cs_base, uint32_t *f= lags) diff --git a/target/xtensa/cpu.h b/target/xtensa/cpu.h index cbb720e7cc..646965f379 100644 --- a/target/xtensa/cpu.h +++ b/target/xtensa/cpu.h @@ -584,7 +584,6 @@ void xtensa_cpu_do_unaligned_access(CPUState *cpu, vadd= r addr, MMUAccessType access_type, int mmu_idx, uintptr_t retaddr); =20 -#define cpu_signal_handler cpu_xtensa_signal_handler #define cpu_list xtensa_cpu_list =20 #define XTENSA_CPU_TYPE_SUFFIX "-" TYPE_XTENSA_CPU @@ -613,7 +612,6 @@ void check_interrupts(CPUXtensaState *s); void xtensa_irq_init(CPUXtensaState *env); qemu_irq *xtensa_get_extints(CPUXtensaState *env); qemu_irq xtensa_get_runstall(CPUXtensaState *env); -int cpu_xtensa_signal_handler(int host_signum, void *pinfo, void *puc); void xtensa_cpu_list(void); void xtensa_sync_window_from_phys(CPUXtensaState *env); void xtensa_sync_phys_from_window(CPUXtensaState *env); --=20 2.25.1 From nobody Sat Apr 20 00:21:55 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1631571299691935.7216446623213; Mon, 13 Sep 2021 15:14:59 -0700 (PDT) Received: from localhost ([::1]:40416 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1mPuE5-0006mU-Ea for importer@patchew.org; Mon, 13 Sep 2021 18:14:58 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:34396) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mPu5Q-0001os-HP for qemu-devel@nongnu.org; Mon, 13 Sep 2021 18:06:01 -0400 Received: from mail-pj1-x102d.google.com ([2607:f8b0:4864:20::102d]:34712) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1mPu5N-0007MR-H2 for qemu-devel@nongnu.org; Mon, 13 Sep 2021 18:05:59 -0400 Received: by mail-pj1-x102d.google.com with SMTP id on12-20020a17090b1d0c00b001997c60aa29so770088pjb.1 for ; Mon, 13 Sep 2021 15:05:57 -0700 (PDT) Received: from localhost.localdomain ([71.212.134.125]) by smtp.gmail.com with ESMTPSA id 17sm7721404pfx.167.2021.09.13.15.05.55 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 13 Sep 2021 15:05:55 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=HOihbZxbdSpTNEi6dYGIvfhNa3VVAsIH5ySEcJN4hRo=; b=ZLnxGjAtCr/fEBkb0eK+iwTmRE7XPQui9grmT2r+gAv7yrTB+p1QVAwcbh4TBTwSRW A+kvxnl4NF6qZOsftRoMA5/bd9VCkbXWQn0wokS9EUmKur2gKuMorKaWweay+YLw1+cP VjIaVuwnyEqzx/590boigjO24aolmHobmhdBobskh/4JPQ93MEVfGeWqWIj5tNCjgD5Y jUXG593olEJmZyrR20sRt5ayxGwtHPdv4V/zEN9wZPi4FqZnlXF5U/cl7vUV3kmen1sg 8yz7ZXbcyaChT9uXP7MJ+DG7uUA85d/YP/GG6kN6/w6fKE0sUBEGRK4A30RiyjJx9dCQ T3MA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=HOihbZxbdSpTNEi6dYGIvfhNa3VVAsIH5ySEcJN4hRo=; b=E3kOOFY6QAsAKK/eMHgxc8BuYotCn9uDwpeobViaPN6ATMbCyGx+4B3V2KABNB5GVY CULHC3iLyPTQIKHoQ+qnMRBL8Q59ppTsyif1zvmPLHmRc9V21sMfQVwjoJ7Sfww5yXv1 9F+8g6YR+MT8I8GPzPlC48TVxYu3mmpLsf4BG8/rQk7N7tZxR27WQTj3ul0sBwZkbVSm 8mk9/DliShzRHeJWr4EZt9lSpnZNAi5O6ay2TcnpklTyfD+I9z8UsyZC4DqlcmGmc47L Y+CT/q6xGvcJZZ0OUcwwcAhC9AMj7AY/SC4+a2B/juTF6+Kf+gJlwHP6znYfYVCZPvFK dnCg== X-Gm-Message-State: AOAM533nRfu3khF7UtLTx2ogv2YVd67fcvhtNAxR7pvkHcH2qbQzEKu7 Q7Me5HUhyH3Io7WSjcN4covlcrs4Zxafdg== X-Google-Smtp-Source: ABdhPJyyYkOQv0Iu3Ijbd6KXxfZC36lT0J8vCqUa8nEBv3a83gSyFSvSSa3ZQPAWPIRLcm5y2zkr8w== X-Received: by 2002:a17:902:d114:b0:13a:4dec:d590 with SMTP id w20-20020a170902d11400b0013a4decd590mr12350306plw.76.1631570756083; Mon, 13 Sep 2021 15:05:56 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Subject: [RFC PATCH 2/7] accel/tcg: Split out adjust_signal_pc Date: Mon, 13 Sep 2021 15:05:47 -0700 Message-Id: <20210913220552.604064-3-richard.henderson@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210913220552.604064-1-richard.henderson@linaro.org> References: <20210913220552.604064-1-richard.henderson@linaro.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=2607:f8b0:4864:20::102d; envelope-from=richard.henderson@linaro.org; helo=mail-pj1-x102d.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: peter.maydell@linaro.org, laurent@vivier.eu, imp@bsdimp.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1631571300546100001 Content-Type: text/plain; charset="utf-8" Split out a function to adjust the raw signal pc into a value that could be passed to cpu_restore_state. Signed-off-by: Richard Henderson Reviewed-by: Philippe Mathieu-Daud=C3=A9 --- include/exec/exec-all.h | 8 +++++++ accel/tcg/user-exec.c | 50 ++++++++++++++++++++++++++--------------- 2 files changed, 40 insertions(+), 18 deletions(-) diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h index 9d5987ba04..7207912306 100644 --- a/include/exec/exec-all.h +++ b/include/exec/exec-all.h @@ -663,6 +663,14 @@ static inline tb_page_addr_t get_page_addr_code_hostp(= CPUArchState *env, return addr; } =20 +/** + * adjust_signal_pc: + * @pc: raw pc from the host signal ucontext_t. + * + * Return the pc to pass to cpu_restore_state. + */ +uintptr_t adjust_signal_pc(uintptr_t pc); + /** * cpu_signal_handler * @signum: host signal number diff --git a/accel/tcg/user-exec.c b/accel/tcg/user-exec.c index 8fed542622..1f7b7a3692 100644 --- a/accel/tcg/user-exec.c +++ b/accel/tcg/user-exec.c @@ -57,18 +57,14 @@ static void QEMU_NORETURN cpu_exit_tb_from_sighandler(C= PUState *cpu, cpu_loop_exit_noexc(cpu); } =20 -/* 'pc' is the host PC at which the exception was raised. 'address' is - the effective address of the memory exception. 'is_write' is 1 if a - write caused the exception and otherwise 0'. 'old_set' is the - signal set which should be restored */ -static inline int handle_cpu_signal(uintptr_t pc, siginfo_t *info, - int is_write, sigset_t *old_set) +/** + * adjust_signal_pc: + * @pc: raw pc from the host signal ucontext_t. + * + * Return the pc to pass to cpu_restore_state. + */ +uintptr_t adjust_signal_pc(uintptr_t pc) { - CPUState *cpu =3D current_cpu; - CPUClass *cc; - unsigned long address =3D (unsigned long)info->si_addr; - MMUAccessType access_type =3D is_write ? MMU_DATA_STORE : MMU_DATA_LOA= D; - switch (helper_retaddr) { default: /* @@ -77,8 +73,7 @@ static inline int handle_cpu_signal(uintptr_t pc, siginfo= _t *info, * pointer into the generated code that will unwind to the * correct guest pc. */ - pc =3D helper_retaddr; - break; + return helper_retaddr; =20 case 0: /* @@ -97,8 +92,7 @@ static inline int handle_cpu_signal(uintptr_t pc, siginfo= _t *info, * Therefore, adjust to compensate for what will be done later * by cpu_restore_state_from_tb. */ - pc +=3D GETPC_ADJ; - break; + return pc + GETPC_ADJ; =20 case 1: /* @@ -113,11 +107,31 @@ static inline int handle_cpu_signal(uintptr_t pc, sig= info_t *info, * * Like tb_gen_code, release the memory lock before cpu_loop_exit. */ - pc =3D 0; - access_type =3D MMU_INST_FETCH; mmap_unlock(); - break; + return 0; } +} + +/* 'pc' is the host PC at which the exception was raised. 'address' is + the effective address of the memory exception. 'is_write' is 1 if a + write caused the exception and otherwise 0'. 'old_set' is the + signal set which should be restored */ +static inline int handle_cpu_signal(uintptr_t pc, siginfo_t *info, + int is_write, sigset_t *old_set) +{ + CPUState *cpu =3D current_cpu; + CPUClass *cc; + unsigned long address =3D (unsigned long)info->si_addr; + MMUAccessType access_type; + + if (is_write) { + access_type =3D MMU_DATA_STORE; + } else if (helper_retaddr =3D=3D 1) { + access_type =3D MMU_INST_FETCH; + } else { + access_type =3D MMU_DATA_LOAD; + } + pc =3D adjust_signal_pc(pc); =20 /* For synchronous signals we expect to be coming from the vCPU * thread (so current_cpu should be valid) and either from running --=20 2.25.1 From nobody Sat Apr 20 00:21:55 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1631571143621476.9244839519789; Mon, 13 Sep 2021 15:12:23 -0700 (PDT) Received: from localhost ([::1]:36196 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1mPuBa-0003yQ-Hk for importer@patchew.org; Mon, 13 Sep 2021 18:12:22 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:34392) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mPu5Q-0001oq-GG for qemu-devel@nongnu.org; Mon, 13 Sep 2021 18:06:01 -0400 Received: from mail-pj1-x1032.google.com ([2607:f8b0:4864:20::1032]:41782) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1mPu5O-0007N7-8X for qemu-devel@nongnu.org; Mon, 13 Sep 2021 18:05:59 -0400 Received: by mail-pj1-x1032.google.com with SMTP id m21-20020a17090a859500b00197688449c4so1182502pjn.0 for ; Mon, 13 Sep 2021 15:05:57 -0700 (PDT) Received: from localhost.localdomain ([71.212.134.125]) by smtp.gmail.com with ESMTPSA id 17sm7721404pfx.167.2021.09.13.15.05.56 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 13 Sep 2021 15:05:56 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=BSr8CpzMFsO2CignfsD0RiKPN4BnIAAHYciYbFsOhR4=; b=OLyHwgIS+D2qb8pv8ZfNrVtS7FJVPpae9zPZNIG7KPLgQyVeCSJuJiRjJ8ZrPgL77Q eV2PDH4/CvlSBZ2rLFUyAHsmfjr104fIeisnNuC1QUAzqKk35wOdE6G46RXDAZ8aKw2y v4VpZ8s4segcQ7O65w1t05dlcqffIsvUHFcKM9R+1uqFA4sxys+R4yKG0IQSXqqPhZrk tVC2PfQl8eI6Ufcrp8DmcBcH4K/buT7p91pF79mFSttGZZTgVpYQcPyte4r8kqNGyv9x 0bjbe6mQ4hqlwyp1Q6MdBDrIWz8ecPs3kQmj/VeGvU7fXWeTsyfbnmbPWTNGQW6kL7pd cOEw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=BSr8CpzMFsO2CignfsD0RiKPN4BnIAAHYciYbFsOhR4=; b=cyhIKfXKyZ+tHwMAyTR3cfmfgZll0UMPsN+/M7hLf9PdgnrBBH4xhvphQ/xFGz7hlA gTyxQKank5dEvQIVbk6kt5KJOwddF1+bjbDrXbvDHUbaN62HDR32HWbpL/2+OlghGLYd ngJMLlkV96xZ1XBwpQZZ42Ua9sd1rTiD2qJkfHn0GBxGe6QwLKIdalaMFnE4BUm4okop IG3QhaONkN+BWEqaYvcqLGF63kTLKFeHydnsrSEDZFljw53F6nGdezXpEvzbvEZDG2Oy NGgsPjH89GZnCeTuoVBHBntkCwnXy2s0jif7yVh5Wohl+y9Waf/4MkM0fuJ+GJWwKKaV 7QkA== X-Gm-Message-State: AOAM5334Kr+uyJ3A7UVHCAGghrwkLjOi8S3HsEFEm/Dgl5XLokteW5p1 NgPu6VhN14SORdA1FTvrY1l4KFoC0+4d2w== X-Google-Smtp-Source: ABdhPJwQoanx4+sMRxYa7hQqGu2isZTBjtH6bh3mWabbXhu0wYjlS8SjuxRqLthNaBA5JWfeacY6sA== X-Received: by 2002:a17:902:ba98:b0:139:93:7e26 with SMTP id k24-20020a170902ba9800b0013900937e26mr12290790pls.55.1631570756904; Mon, 13 Sep 2021 15:05:56 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Subject: [RFC PATCH 3/7] accel/tcg: Split out handle_sigsegv_accerr_write Date: Mon, 13 Sep 2021 15:05:48 -0700 Message-Id: <20210913220552.604064-4-richard.henderson@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210913220552.604064-1-richard.henderson@linaro.org> References: <20210913220552.604064-1-richard.henderson@linaro.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=2607:f8b0:4864:20::1032; envelope-from=richard.henderson@linaro.org; helo=mail-pj1-x1032.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: peter.maydell@linaro.org, laurent@vivier.eu, imp@bsdimp.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1631571144951100001 Content-Type: text/plain; charset="utf-8" This is the major portion of handle_cpu_signal which is specific to tcg, handling the page protections for the translations. Most of the rest will migrate to linux-user/ shortly. Signed-off-by: Richard Henderson Reviewed-by: Philippe Mathieu-Daud=C3=A9 --- include/exec/exec-all.h | 12 ++++++ accel/tcg/user-exec.c | 96 +++++++++++++++++++++++++---------------- 2 files changed, 72 insertions(+), 36 deletions(-) diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h index 7207912306..f582d3e688 100644 --- a/include/exec/exec-all.h +++ b/include/exec/exec-all.h @@ -671,6 +671,18 @@ static inline tb_page_addr_t get_page_addr_code_hostp(= CPUArchState *env, */ uintptr_t adjust_signal_pc(uintptr_t pc); =20 +/** + * handle_sigsegv_accerr_write: + * @cpu: the cpu context + * @old_set: the sigset_t from the signal ucontext_t + * @host_pc: the host pc, adjusted for the signal + * @host_addr: the host address of the fault + * + * Return true if the write fault has been handled, and should be re-tried. + */ +bool handle_sigsegv_accerr_write(CPUState *cpu, sigset_t *old_set, + uintptr_t host_pc, uintptr_t host_addr); + /** * cpu_signal_handler * @signum: host signal number diff --git a/accel/tcg/user-exec.c b/accel/tcg/user-exec.c index 1f7b7a3692..daef34a426 100644 --- a/accel/tcg/user-exec.c +++ b/accel/tcg/user-exec.c @@ -112,6 +112,60 @@ uintptr_t adjust_signal_pc(uintptr_t pc) } } =20 +/** + * handle_sigsegv_accerr_write: + * @cpu: the cpu context + * @old_set: the sigset_t from the signal ucontext_t + * @host_pc: the host pc, adjusted for the signal + * @host_addr: the host address of the fault + * + * Return true if the write fault has been handled, and should be re-tried. + * + * Note that it is important that we don't call page_unprotect() unless + * this is really a "write to nonwriteable page" fault, because + * page_unprotect() assumes that if it is called for an access to + * a page that's writeable this means we had two threads racing and + * another thread got there first and already made the page writeable; + * so we will retry the access. If we were to call page_unprotect() + * for some other kind of fault that should really be passed to the + * guest, we'd end up in an infinite loop of retrying the faulting access. + */ +bool handle_sigsegv_accerr_write(CPUState *cpu, sigset_t *old_set, + uintptr_t host_pc, uintptr_t host_addr) +{ + if (!h2g_valid(host_addr)) { + return false; + } + + switch (page_unprotect(h2g(host_addr), host_pc)) { + case 0: + /* + * Fault not caused by a page marked unwritable to protect + * cached translations, must be the guest binary's problem. + */ + return false; + case 1: + /* + * Fault caused by protection of cached translation; TBs + * invalidated, so resume execution. Retain helper_retaddr + * for a possible second fault. + */ + return true; + case 2: + /* + * Fault caused by protection of cached translation, and the + * currently executing TB was modified and must be exited + * immediately. Clear helper_retaddr for next execution. + */ + clear_helper_retaddr(); + cpu_exit_tb_from_sighandler(cpu, old_set); + /* NORETURN */ + + default: + g_assert_not_reached(); + } +} + /* 'pc' is the host PC at which the exception was raised. 'address' is the effective address of the memory exception. 'is_write' is 1 if a write caused the exception and otherwise 0'. 'old_set' is the @@ -150,43 +204,13 @@ static inline int handle_cpu_signal(uintptr_t pc, sig= info_t *info, printf("qemu: SIGSEGV pc=3D0x%08lx address=3D%08lx w=3D%d oldset=3D0x%= 08lx\n", pc, address, is_write, *(unsigned long *)old_set); #endif - /* XXX: locking issue */ - /* Note that it is important that we don't call page_unprotect() unless - * this is really a "write to nonwriteable page" fault, because - * page_unprotect() assumes that if it is called for an access to - * a page that's writeable this means we had two threads racing and - * another thread got there first and already made the page writeable; - * so we will retry the access. If we were to call page_unprotect() - * for some other kind of fault that should really be passed to the - * guest, we'd end up in an infinite loop of retrying the faulting - * access. - */ - if (is_write && info->si_signo =3D=3D SIGSEGV && info->si_code =3D=3D = SEGV_ACCERR && - h2g_valid(address)) { - switch (page_unprotect(h2g(address), pc)) { - case 0: - /* Fault not caused by a page marked unwritable to protect - * cached translations, must be the guest binary's problem. - */ - break; - case 1: - /* Fault caused by protection of cached translation; TBs - * invalidated, so resume execution. Retain helper_retaddr - * for a possible second fault. - */ - return 1; - case 2: - /* Fault caused by protection of cached translation, and the - * currently executing TB was modified and must be exited - * immediately. Clear helper_retaddr for next execution. - */ - clear_helper_retaddr(); - cpu_exit_tb_from_sighandler(cpu, old_set); - /* NORETURN */ =20 - default: - g_assert_not_reached(); - } + /* XXX: locking issue */ + if (is_write && + info->si_signo =3D=3D SIGSEGV && + info->si_code =3D=3D SEGV_ACCERR && + handle_sigsegv_accerr_write(cpu, old_set, pc, address)) { + return 1; } =20 /* Convert forcefully to guest address space, invalid addresses --=20 2.25.1 From nobody Sat Apr 20 00:21:55 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1631570875918587.1483993348764; Mon, 13 Sep 2021 15:07:55 -0700 (PDT) Received: from localhost ([::1]:53122 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1mPu7G-0004oC-64 for importer@patchew.org; Mon, 13 Sep 2021 18:07:54 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:34468) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mPu5T-0001tF-0j for qemu-devel@nongnu.org; Mon, 13 Sep 2021 18:06:04 -0400 Received: from mail-pf1-x431.google.com ([2607:f8b0:4864:20::431]:33619) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1mPu5P-0007O1-Gm for qemu-devel@nongnu.org; Mon, 13 Sep 2021 18:06:02 -0400 Received: by mail-pf1-x431.google.com with SMTP id q22so10216041pfu.0 for ; Mon, 13 Sep 2021 15:05:58 -0700 (PDT) Received: from localhost.localdomain ([71.212.134.125]) by smtp.gmail.com with ESMTPSA id 17sm7721404pfx.167.2021.09.13.15.05.57 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 13 Sep 2021 15:05:57 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=umKm8x6alVt7RG9Jn6P6NNWTmAl/oVeCyIb/D+Q+Mok=; b=U1mLbPyUisTneV51DA5y5ejNESCCW+py0H0deZKzMfZRWIyuUqgbrWhiJ7gWUlTw/4 HQPM++BiahAqvOnwSwa7sjgE8dWmHYfBi7+QXtnEBc0RNCsCXipGR/4rMCaHIHmct6ML dA5Ejw3m6dmIcQqNuaf+hZXb/qg/6206y6OD/MQdBXEKp2OPZY6P3bgtcd4fsgTBDxGo f0aiDyH0IlAi4hco3QoWPG+VNh3c43AEQh1FfiZf5HzYE3XM2VNbmuygC4yy2JmUzgMi 5xWiBLVVk85sdEWkZ/E0/emmSpYyhnWNtbVqEsvrN8JA08c0LcD0eSxIegwPKdQHXiZg WFCg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=umKm8x6alVt7RG9Jn6P6NNWTmAl/oVeCyIb/D+Q+Mok=; b=IpknZVAvaMTYibpRUBawy1OyZ7vCcbE2fvjUDMj5BYrDc9rnE26V0Qz7TE6YhG6Xul rsZ7jlrv0CtV0K7vZN4CJX8pxV6vh/3Kwf/I28BPYvsHkVR1qV5RieeyHLw4sHb1YBiP 4J92b8rDPY5l8rSJmnpghr50Gg5K9HK+8vEu8MMLIvWBdE+N281KjHLZHNfQ7gBzJZhR xadz8u9WhRSdY6zwqHw/co/BGWVZOGek4a0WLckavcdve7QZEOfmIwkpe8YEKew1qk8M nZuJ0SqWN2Yez2qTmFzwKYY2zXaGDfRHjcSYwW4NbqZOdLT+gZdyrz+AM3FlgjD1twE4 JixQ== X-Gm-Message-State: AOAM530Hutxus+CP6JwXwYzNqroV1X/iA1V9KX+F+F/5g6ZHu0wNVrIY gFQDCFZdAv7B6NJ6Wxs3QdqSx4nQoyi1Yg== X-Google-Smtp-Source: ABdhPJzuO6ABf5pw3M82TQmOZhhydfXIpILRsB1fY6kQNpBE3SLT7LteHD7rperq5PeI7yRTb47Zyg== X-Received: by 2002:a62:2703:0:b0:42b:5319:cbbc with SMTP id n3-20020a622703000000b0042b5319cbbcmr1480093pfn.66.1631570757676; Mon, 13 Sep 2021 15:05:57 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Subject: [RFC PATCH 4/7] accel/tcg: Move clear_helper_retaddr to cpu loop Date: Mon, 13 Sep 2021 15:05:49 -0700 Message-Id: <20210913220552.604064-5-richard.henderson@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210913220552.604064-1-richard.henderson@linaro.org> References: <20210913220552.604064-1-richard.henderson@linaro.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=2607:f8b0:4864:20::431; envelope-from=richard.henderson@linaro.org; helo=mail-pf1-x431.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: peter.maydell@linaro.org, laurent@vivier.eu, imp@bsdimp.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1631570877630100002 Content-Type: text/plain; charset="utf-8" Currently there are only two places that require we reset this value before exiting to the main loop, but that will change. Signed-off-by: Richard Henderson --- accel/tcg/cpu-exec.c | 3 ++- accel/tcg/user-exec.c | 2 -- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/accel/tcg/cpu-exec.c b/accel/tcg/cpu-exec.c index 75dbc1e4e3..13c4436e5d 100644 --- a/accel/tcg/cpu-exec.c +++ b/accel/tcg/cpu-exec.c @@ -451,6 +451,7 @@ void cpu_exec_step_atomic(CPUState *cpu) * memory. */ #ifndef CONFIG_SOFTMMU + clear_helper_retaddr(); tcg_debug_assert(!have_mmap_lock()); #endif if (qemu_mutex_iothread_locked()) { @@ -460,7 +461,6 @@ void cpu_exec_step_atomic(CPUState *cpu) qemu_plugin_disable_mem_helpers(cpu); } =20 - /* * As we start the exclusive region before codegen we must still * be in the region if we longjump out of either the codegen or @@ -903,6 +903,7 @@ int cpu_exec(CPUState *cpu) #endif =20 #ifndef CONFIG_SOFTMMU + clear_helper_retaddr(); tcg_debug_assert(!have_mmap_lock()); #endif if (qemu_mutex_iothread_locked()) { diff --git a/accel/tcg/user-exec.c b/accel/tcg/user-exec.c index daef34a426..83351db719 100644 --- a/accel/tcg/user-exec.c +++ b/accel/tcg/user-exec.c @@ -157,7 +157,6 @@ bool handle_sigsegv_accerr_write(CPUState *cpu, sigset_= t *old_set, * currently executing TB was modified and must be exited * immediately. Clear helper_retaddr for next execution. */ - clear_helper_retaddr(); cpu_exit_tb_from_sighandler(cpu, old_set); /* NORETURN */ =20 @@ -222,7 +221,6 @@ static inline int handle_cpu_signal(uintptr_t pc, sigin= fo_t *info, * an exception. Undo signal and retaddr state prior to longjmp. */ sigprocmask(SIG_SETMASK, old_set, NULL); - clear_helper_retaddr(); =20 cc =3D CPU_GET_CLASS(cpu); cc->tcg_ops->tlb_fill(cpu, address, 0, access_type, --=20 2.25.1 From nobody Sat Apr 20 00:21:55 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1631570875992105.55852034159909; Mon, 13 Sep 2021 15:07:55 -0700 (PDT) Received: from localhost ([::1]:53112 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1mPu7G-0004o1-MI for importer@patchew.org; Mon, 13 Sep 2021 18:07:54 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:34466) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mPu5S-0001t2-Td for qemu-devel@nongnu.org; Mon, 13 Sep 2021 18:06:04 -0400 Received: from mail-pj1-x1035.google.com ([2607:f8b0:4864:20::1035]:35355) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1mPu5Q-0007OR-64 for qemu-devel@nongnu.org; Mon, 13 Sep 2021 18:06:02 -0400 Received: by mail-pj1-x1035.google.com with SMTP id f3-20020a17090a638300b00199097ddf1aso589787pjj.0 for ; Mon, 13 Sep 2021 15:05:59 -0700 (PDT) Received: from localhost.localdomain ([71.212.134.125]) by smtp.gmail.com with ESMTPSA id 17sm7721404pfx.167.2021.09.13.15.05.58 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 13 Sep 2021 15:05:58 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=UEwGCVckIB8KvhnLN1rP6M7bfEXyZ0UAya2D2H0VVIs=; b=J8LDeKa3EDA8SSu5356+HpTlXWKwj50nhwERzzWrwr5A9AdfbKlmDsRJCULm3tFc10 pW/USukh5GQ/dlcCRz6XzWZuTtKOy5NjWjzhJFEfFO2mG9JI5ZEcHVky0C5bOtoHaz5l OMEGtDhqK62CDpahobQ+ZihQnT4ROWfqMc5xewBds3KAWKp4ijM/QwMtk7co/KxIai6G VcMPpJXhQhOBrRYrLAZ3CUtg5X5O3GQvNTyq5+oCuZquIyL+sd8vMdrI1eHyOZy1RvBz QmBrKNVrdsHwbI1yTXhQKFh24RmbElHupSDHrRAc47BWTKqhu3yxJzcTI61IhMbqcETa mURQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=UEwGCVckIB8KvhnLN1rP6M7bfEXyZ0UAya2D2H0VVIs=; b=5cZfyNSdf4cfbbW5zURmIbVD6snkiehNi6CsFUtQiRjhXLufrt3rsNwq8BBEsXXavr WUMmymfowYRvEn3Ss3xTzChH6xaQbZRE3b7/HrEGjsGWbIUz7x+7zT2r7R1mbfFOO1GB o1KBu264htJ7XhGiSVwudquZrg67M0bHKUdOpJnPU140kAsvu2C5Bt/EWgRKaQUsbtzn 2LDocK8U1XjYAj51pEPAw4tpQ/gX4CR2fQYQaVp3lKWsQlf+KkKCEJawKcWuRJlXl+JK r2V0cy2GO6XkPL83k8YFkFH14dx3EU7Y61iD4Sv/Me6/CMBH/jgopMYOazdQEpUcI/ZB ovSA== X-Gm-Message-State: AOAM533U3WiuQ9rFdaPHksoPHDjKUl2V0IDIAienylCuoZaB3cMks/Sv XUTRX1Bk7RRbDQFXymyIh8o9Or8DTc5G4g== X-Google-Smtp-Source: ABdhPJy3JAbqWQJVzATpkb1pIIgzSS18fQdjVmJ+SS6h1BA0B7LnJvzvOYoSXWTHC3u02W0s8IxmQw== X-Received: by 2002:a17:90a:5511:: with SMTP id b17mr1797527pji.222.1631570758512; Mon, 13 Sep 2021 15:05:58 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Subject: [RFC PATCH 5/7] accel/tcg: Fold cpu_exit_tb_from_sighandler into caller Date: Mon, 13 Sep 2021 15:05:50 -0700 Message-Id: <20210913220552.604064-6-richard.henderson@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210913220552.604064-1-richard.henderson@linaro.org> References: <20210913220552.604064-1-richard.henderson@linaro.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=2607:f8b0:4864:20::1035; envelope-from=richard.henderson@linaro.org; helo=mail-pj1-x1035.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: peter.maydell@linaro.org, laurent@vivier.eu, imp@bsdimp.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1631570877625100001 Content-Type: text/plain; charset="utf-8" Remove the comment about siglongjmp. We do use sigsetjmp in the main cpu loop, but we do not save the signal mask as most exits from the cpu loop do not require them. Signed-off-by: Richard Henderson --- accel/tcg/user-exec.c | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) diff --git a/accel/tcg/user-exec.c b/accel/tcg/user-exec.c index 83351db719..ad6b4f6abf 100644 --- a/accel/tcg/user-exec.c +++ b/accel/tcg/user-exec.c @@ -46,17 +46,6 @@ __thread uintptr_t helper_retaddr; =20 //#define DEBUG_SIGNAL =20 -/* exit the current TB from a signal handler. The host registers are - restored in a state compatible with the CPU emulator - */ -static void QEMU_NORETURN cpu_exit_tb_from_sighandler(CPUState *cpu, - sigset_t *old_set) -{ - /* XXX: use siglongjmp ? */ - sigprocmask(SIG_SETMASK, old_set, NULL); - cpu_loop_exit_noexc(cpu); -} - /** * adjust_signal_pc: * @pc: raw pc from the host signal ucontext_t. @@ -157,9 +146,9 @@ bool handle_sigsegv_accerr_write(CPUState *cpu, sigset_= t *old_set, * currently executing TB was modified and must be exited * immediately. Clear helper_retaddr for next execution. */ - cpu_exit_tb_from_sighandler(cpu, old_set); + sigprocmask(SIG_SETMASK, old_set, NULL); + cpu_loop_exit_noexc(cpu); /* NORETURN */ - default: g_assert_not_reached(); } --=20 2.25.1 From nobody Sat Apr 20 00:21:55 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1631571136396851.174877988665; Mon, 13 Sep 2021 15:12:16 -0700 (PDT) Received: from localhost ([::1]:35638 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1mPuBT-0003bu-Ef for importer@patchew.org; Mon, 13 Sep 2021 18:12:15 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:34482) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mPu5U-0001tS-7G for qemu-devel@nongnu.org; Mon, 13 Sep 2021 18:06:04 -0400 Received: from mail-pg1-x536.google.com ([2607:f8b0:4864:20::536]:41932) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1mPu5Q-0007Pj-Qa for qemu-devel@nongnu.org; Mon, 13 Sep 2021 18:06:04 -0400 Received: by mail-pg1-x536.google.com with SMTP id k24so10739769pgh.8 for ; Mon, 13 Sep 2021 15:06:00 -0700 (PDT) Received: from localhost.localdomain ([71.212.134.125]) by smtp.gmail.com with ESMTPSA id 17sm7721404pfx.167.2021.09.13.15.05.59 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 13 Sep 2021 15:05:59 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=TRxXO90HL6E2HYzdEuSi6drNP5S5IBktkL6st8qE9/A=; b=yZm2vNgcuDw2jZeuQW/ETNZm1dnH1tu2tq/k0OCqNuodirzbpNlnV7aiA1tiAFOp7P 5pby0WnCN4izscOerys2fRplceAYZjl/OKwSasgcvqr7TtfY0Vofp9ZhzLzob85KYyOl v4lYPMnueniczLLxSqfT80QLXxVzM5xq94Fc7T0Gfe6N4WZK4IQrbxHEp9S3hynE3Fud jek9oGifY1+DVVHlAjmWTYv6Kd6qehEgwLSQgsa6WWTvm7D1UhAInlzU/ITdoupzair/ u26DNFLBIPc5GKbbxUJT3WNBoSCr13CnBz0DoBkqn4K5Ake8shYD45XQEEQuPwPl08BV cTDQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=TRxXO90HL6E2HYzdEuSi6drNP5S5IBktkL6st8qE9/A=; b=iCWn05HX+0kZZ0dWBq3lEkmzSolQtA5atp492HVQa1mpJhtMhlPafJckZKbWZdnHVJ Ee31ciuDI9jl4hHILx0gff2H9zjKwE56yF6TQxpk4KdGZ4mOxtJ1V1tntmiZserZtiPG UFJKKvrxB0/BSTsqCl6qhg9XZHvy9F68ghKT2talWOP+RsciNsNCQfSu1z/ZTeNBtTvF aYkbA0MEFNuaoVtlY46JyL1sGccYvIMkZO0+XHfmuO1s1JJHPRQEBKr/i49v4e7yQVGX dmYITrTBGJDojlHv+GTwQSxoQWN4M/WD3vQH54dTChqb242P6C2zll+emDIFbPiri8+O ga+g== X-Gm-Message-State: AOAM533rfCdsXI2Q5v/SiBtx6E5u2eb98UITMg/wMOmmwHDlDdfeY69C MdgGebD5VZ0AsymTiO/GgZAiiPj2AO3x5A== X-Google-Smtp-Source: ABdhPJx6RFl4TOyxf/JqDBrmmf1qVmgXFa2ncEV+yxcBmkhEFBMbI3g6Ku9UqppbTsro0cBWeiyzDQ== X-Received: by 2002:a62:684:0:b0:40e:6fea:5188 with SMTP id 126-20020a620684000000b0040e6fea5188mr1484516pfg.58.1631570759535; Mon, 13 Sep 2021 15:05:59 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Subject: [RFC PATCH 6/7] linux-user: Handle SIGSEGV/SIGBUS in host_to_target_siginfo_noswap Date: Mon, 13 Sep 2021 15:05:51 -0700 Message-Id: <20210913220552.604064-7-richard.henderson@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210913220552.604064-1-richard.henderson@linaro.org> References: <20210913220552.604064-1-richard.henderson@linaro.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=2607:f8b0:4864:20::536; envelope-from=richard.henderson@linaro.org; helo=mail-pg1-x536.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: peter.maydell@linaro.org, laurent@vivier.eu, imp@bsdimp.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1631571137951100001 Content-Type: text/plain; charset="utf-8" Remap the faulting address from the host address space into the guest address space. Signed-off-by: Richard Henderson Reviewed-by: Warner Losh --- linux-user/signal.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/linux-user/signal.c b/linux-user/signal.c index a8faea6f09..73c0f9066b 100644 --- a/linux-user/signal.c +++ b/linux-user/signal.c @@ -405,6 +405,15 @@ static inline void host_to_target_siginfo_noswap(targe= t_siginfo_t *tinfo, tinfo->_sifields._sigpoll._fd =3D info->si_fd; si_type =3D QEMU_SI_POLL; break; + case TARGET_SIGSEGV: + case TARGET_SIGBUS: + /* + * Remap the host address into the target space. + * Even an invalid guest address is still valid for a fault. + */ + tinfo->_sifields._sigfault._addr =3D h2g_nocheck(info->si_addr= ); + si_type =3D QEMU_SI_FAULT; + break; default: /* Assume a sigqueue()/mq_notify()/rt_sigqueueinfo() source. */ tinfo->_sifields._rt._pid =3D info->si_pid; --=20 2.25.1 From nobody Sat Apr 20 00:21:55 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1631571098804818.136036309213; Mon, 13 Sep 2021 15:11:38 -0700 (PDT) Received: from localhost ([::1]:60836 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1mPuAr-0001bo-KL for importer@patchew.org; Mon, 13 Sep 2021 18:11:37 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:34500) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mPu5X-00020J-2O for qemu-devel@nongnu.org; Mon, 13 Sep 2021 18:06:07 -0400 Received: from mail-pl1-x62b.google.com ([2607:f8b0:4864:20::62b]:42700) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1mPu5S-0007S7-KN for qemu-devel@nongnu.org; Mon, 13 Sep 2021 18:06:06 -0400 Received: by mail-pl1-x62b.google.com with SMTP id n4so6782498plh.9 for ; Mon, 13 Sep 2021 15:06:02 -0700 (PDT) Received: from localhost.localdomain ([71.212.134.125]) by smtp.gmail.com with ESMTPSA id 17sm7721404pfx.167.2021.09.13.15.06.00 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 13 Sep 2021 15:06:00 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=6Zrc3XZ8w46E8d+W832DPrqrMLN8KgFdqW+sL6n38uY=; b=fmCtFKO9VKuUpwA/acCd7jtsu2jgvgu+/ZE9ghX8PJtPrXKI5y8e4Y0edetOonbWAq 2cAeXysLwws3oDQdtMztx2iCrsfabUxh2Avxty3IjGV48WUCSjJ1rqQfokH7uXVnHF7k z14GfxD78/5N/Jc8zGc04KGQunp1TMPB7WrzH3kcNlUiWh+463Od7MfKil9rnTn9OxIX 870U5kfknGhQANhk3PhVTpGGnEB8narNhROCFPw1pwXgTpt+zTGov5AM11EeztaAF+D2 PzaPc0Nd+7NV9pp8NwAwNeGH++5Z2hKYNpxYIaHK+fXCh9mm0idhNra7i5bWE2xyiWLx IoEw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=6Zrc3XZ8w46E8d+W832DPrqrMLN8KgFdqW+sL6n38uY=; b=Hqy/rPvGR2zM6SNeGaKWcPOoaivxQzH4UtPv5MBuN+RvRaYTRG/dSQVkHkIA1r58Qm Nf3pc3jMAgGEdZYuFLzqsW8J569mCk5zVyAAIwKSJQVlLqw1nU1ebwmoGwo40XWUnZif YaJZ/XaMz5a19cB1o9I5AchnF6Dh7owDpOJSl0Ed9z4t9kPGXvA7fAhMaiSoEha1hm/p eMRr9in2ZG80cHDEZUy2467PmDqnmRbXXRw2LzeYXyj21eLuulZtIJZ/Y/mgaW2SU6FX dbbqjuI62MH7tpRl8Z3eEGDk89yBhHXcTxeP/mz9fL9RkX3jpYHzY37dxnWnIkJZ93qJ suRA== X-Gm-Message-State: AOAM531rR9u7Y3r/AxzdSvqufJWo0OYf4qU/f4Cykh9E/dS4veAk64b6 yl0j0r4LwJPam3heRS1F0pEWNSYLHIA8wA== X-Google-Smtp-Source: ABdhPJw0hIY6rtSuSv+N78s9BzQSWEql63KEUH/nL0S0qeSZrNt34RDsN9/me6hvjXAlOZ9a5uhmNA== X-Received: by 2002:a17:90a:e2cb:: with SMTP id fr11mr1844135pjb.1.1631570760696; Mon, 13 Sep 2021 15:06:00 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Subject: [RFC PATCH 7/7] linux-user: Reorg cpu_signal_handler Date: Mon, 13 Sep 2021 15:05:52 -0700 Message-Id: <20210913220552.604064-8-richard.henderson@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210913220552.604064-1-richard.henderson@linaro.org> References: <20210913220552.604064-1-richard.henderson@linaro.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=2607:f8b0:4864:20::62b; envelope-from=richard.henderson@linaro.org; helo=mail-pl1-x62b.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: peter.maydell@linaro.org, laurent@vivier.eu, imp@bsdimp.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1631571099964100001 Content-Type: text/plain; charset="utf-8" Split out two functions into linux-user/host/arch/host-signal.h. Since linux-user requires a linux host, drop all of the BSD and Solaris ifdefs. These should be recreated under bsd-user/ when the current blanks there are filled. Fold the remnants of handle_cpu_signal into host_signal_handler. Drop the call to cc->tcg_ops->tlb_fill. This was simply an indirect method to raise SIGSEGV; it is far easier to pass the host siginfo_t along to the guest. This fixes all of the guest cpu_loop code that currently fails to properly fill in SEGV_MAPERR vs SEGV_ACCERR. Signed-off-by: Richard Henderson --- include/exec/exec-all.h | 12 - linux-user/host/aarch64/host-signal.h | 73 +++ linux-user/host/alpha/host-signal.h | 41 ++ linux-user/host/arm/host-signal.h | 30 ++ linux-user/host/i386/host-signal.h | 24 + linux-user/host/mips/host-signal.h | 61 +++ linux-user/host/ppc/host-signal.h | 24 + linux-user/host/ppc64/host-signal.h | 1 + linux-user/host/riscv32/host-signal.h | 57 +++ linux-user/host/riscv64/host-signal.h | 1 + linux-user/host/s390/host-signal.h | 92 ++++ linux-user/host/s390x/host-signal.h | 1 + linux-user/host/sparc/host-signal.h | 53 ++ linux-user/host/sparc64/host-signal.h | 1 + linux-user/host/x86_64/host-signal.h | 24 + accel/tcg/user-exec.c | 712 -------------------------- linux-user/signal.c | 93 ++-- 17 files changed, 543 insertions(+), 757 deletions(-) create mode 100644 linux-user/host/aarch64/host-signal.h create mode 100644 linux-user/host/alpha/host-signal.h create mode 100644 linux-user/host/arm/host-signal.h create mode 100644 linux-user/host/i386/host-signal.h create mode 100644 linux-user/host/mips/host-signal.h create mode 100644 linux-user/host/ppc/host-signal.h create mode 100644 linux-user/host/ppc64/host-signal.h create mode 100644 linux-user/host/riscv32/host-signal.h create mode 100644 linux-user/host/riscv64/host-signal.h create mode 100644 linux-user/host/s390/host-signal.h create mode 100644 linux-user/host/s390x/host-signal.h create mode 100644 linux-user/host/sparc/host-signal.h create mode 100644 linux-user/host/sparc64/host-signal.h create mode 100644 linux-user/host/x86_64/host-signal.h diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h index f582d3e688..addcec6381 100644 --- a/include/exec/exec-all.h +++ b/include/exec/exec-all.h @@ -683,18 +683,6 @@ uintptr_t adjust_signal_pc(uintptr_t pc); bool handle_sigsegv_accerr_write(CPUState *cpu, sigset_t *old_set, uintptr_t host_pc, uintptr_t host_addr); =20 -/** - * cpu_signal_handler - * @signum: host signal number - * @pinfo: host siginfo_t - * @puc: host ucontext_t - * - * To be called from the SIGBUS and SIGSEGV signal handler to inform the - * virtual cpu of exceptions. Returns true if the signal was handled by - * the virtual CPU. - */ -int cpu_signal_handler(int signum, void *pinfo, void *puc); - #else static inline void mmap_lock(void) {} static inline void mmap_unlock(void) {} diff --git a/linux-user/host/aarch64/host-signal.h b/linux-user/host/aarch6= 4/host-signal.h new file mode 100644 index 0000000000..818da17a21 --- /dev/null +++ b/linux-user/host/aarch64/host-signal.h @@ -0,0 +1,73 @@ +/* + * host-signal.h: signal info dependent on the host architecture + * + * Copyright (C) 2021 Linaro Limited + * + * This work is licensed under the terms of the GNU GPL, version 2 or late= r. + * See the COPYING file in the top-level directory. + */ + +#ifndef AARCH64_HOST_SIGNAL_H +#define AARCH64_HOST_SIGNAL_H + +/* Pre-3.16 kernel headers don't have these, so provide fallback definitio= ns */ +#ifndef ESR_MAGIC +#define ESR_MAGIC 0x45535201 +struct esr_context { + struct _aarch64_ctx head; + uint64_t esr; +}; +#endif + +static inline struct _aarch64_ctx *first_ctx(ucontext_t *uc) +{ + return (struct _aarch64_ctx *)&uc->uc_mcontext.__reserved; +} + +static inline struct _aarch64_ctx *next_ctx(struct _aarch64_ctx *hdr) +{ + return (struct _aarch64_ctx *)((char *)hdr + hdr->size); +} + +static inline uintptr_t host_signal_pc(ucontext_t *uc) +{ + return uc->uc_mcontext.pc; +} + +static inline bool host_sigsegv_write(siginfo_t *info, ucontext_t *uc) +{ + struct _aarch64_ctx *hdr; + uint32_t insn; + + /* Find the esr_context, which has the WnR bit in it */ + for (hdr =3D first_ctx(uc); hdr->magic; hdr =3D next_ctx(hdr)) { + if (hdr->magic =3D=3D ESR_MAGIC) { + struct esr_context const *esrctx =3D (struct esr_context const= *)hdr; + uint64_t esr =3D esrctx->esr; + + /* For data aborts ESR.EC is 0b10010x: then bit 6 is the WnR b= it */ + return extract32(esr, 27, 5) =3D=3D 0x12 && extract32(esr, 6, = 1) =3D=3D 1; + } + } + + /* + * Fall back to parsing instructions; will only be needed + * for really ancient (pre-3.16) kernels. + */ + insn =3D *(uint32_t *)host_signal_pc(uc); + + return (insn & 0xbfff0000) =3D=3D 0x0c000000 /* C3.3.1 */ + || (insn & 0xbfe00000) =3D=3D 0x0c800000 /* C3.3.2 */ + || (insn & 0xbfdf0000) =3D=3D 0x0d000000 /* C3.3.3 */ + || (insn & 0xbfc00000) =3D=3D 0x0d800000 /* C3.3.4 */ + || (insn & 0x3f400000) =3D=3D 0x08000000 /* C3.3.6 */ + || (insn & 0x3bc00000) =3D=3D 0x39000000 /* C3.3.13 */ + || (insn & 0x3fc00000) =3D=3D 0x3d800000 /* ... 128bit */ + /* Ignore bits 10, 11 & 21, controlling indexing. */ + || (insn & 0x3bc00000) =3D=3D 0x38000000 /* C3.3.8-12 */ + || (insn & 0x3fe00000) =3D=3D 0x3c800000 /* ... 128bit */ + /* Ignore bits 23 & 24, controlling indexing. */ + || (insn & 0x3a400000) =3D=3D 0x28000000; /* C3.3.7,14-16 */ +} + +#endif diff --git a/linux-user/host/alpha/host-signal.h b/linux-user/host/alpha/ho= st-signal.h new file mode 100644 index 0000000000..eaf83added --- /dev/null +++ b/linux-user/host/alpha/host-signal.h @@ -0,0 +1,41 @@ +/* + * host-signal.h: signal info dependent on the host architecture + * + * Copyright (C) 2021 Linaro Limited + * + * This work is licensed under the terms of the GNU GPL, version 2 or late= r. + * See the COPYING file in the top-level directory. + */ + +#ifndef ALPHA_HOST_SIGNAL_H +#define ALPHA_HOST_SIGNAL_H + +static inline uintptr_t host_signal_pc(ucontext_t *uc) +{ + return uc->uc_mcontext.sc_pc; +} + +static inline bool host_sigsegv_write(siginfo_t *info, ucontext_t *uc) +{ + uint32_t *pc =3D uc->uc_mcontext.sc_pc; + uint32_t insn =3D *pc; + + /* XXX: need kernel patch to get write flag faster */ + switch (insn >> 26) { + case 0x0d: /* stw */ + case 0x0e: /* stb */ + case 0x0f: /* stq_u */ + case 0x24: /* stf */ + case 0x25: /* stg */ + case 0x26: /* sts */ + case 0x27: /* stt */ + case 0x2c: /* stl */ + case 0x2d: /* stq */ + case 0x2e: /* stl_c */ + case 0x2f: /* stq_c */ + return true; + } + return false; +} + +#endif diff --git a/linux-user/host/arm/host-signal.h b/linux-user/host/arm/host-s= ignal.h new file mode 100644 index 0000000000..ae6bcde6c1 --- /dev/null +++ b/linux-user/host/arm/host-signal.h @@ -0,0 +1,30 @@ +/* + * host-signal.h: signal info dependent on the host architecture + * + * Copyright (C) 2021 Linaro Limited + * + * This work is licensed under the terms of the GNU GPL, version 2 or late= r. + * See the COPYING file in the top-level directory. + */ + +#ifndef ARM_HOST_SIGNAL_H +#define ARM_HOST_SIGNAL_H + +static inline uintptr_t host_signal_pc(ucontext_t *uc) +{ + return uc->uc_mcontext.gregs[R15]; +} + +static inline bool host_sigsegv_write(siginfo_t *info, ucontext_t *uc, + uintptr_t pc) +{ + /* + * In the FSR, bit 11 is WnR, assuming a v6 or + * later processor. On v5 we will always report + * this as a read, which will fail later. + */ + uint32_t fsr =3D uc->uc_mcontext.error_code; + return extract32(fsr, 11, 1); +} + +#endif diff --git a/linux-user/host/i386/host-signal.h b/linux-user/host/i386/host= -signal.h new file mode 100644 index 0000000000..a8ca5e4a89 --- /dev/null +++ b/linux-user/host/i386/host-signal.h @@ -0,0 +1,24 @@ +/* + * host-signal.h: signal info dependent on the host architecture + * + * Copyright (C) 2021 Linaro Limited + * + * This work is licensed under the terms of the GNU GPL, version 2 or late= r. + * See the COPYING file in the top-level directory. + */ + +#ifndef I386_HOST_SIGNAL_H +#define I386_HOST_SIGNAL_H + +static inline uintptr_t host_signal_pc(ucontext_t *uc) +{ + return uc->uc_mcontext.gregs[REG_EIP]; +} + +static inline bool host_sigsegv_write(siginfo_t *info, ucontext_t *uc) +{ + return uc->uc_mcontext.gregs[REG_TRAPNO] =3D=3D 0xe + && (uc->uc_mcontext.gregs[REG_ERR] & 0x2); +} + +#endif diff --git a/linux-user/host/mips/host-signal.h b/linux-user/host/mips/host= -signal.h new file mode 100644 index 0000000000..815bbd61fa --- /dev/null +++ b/linux-user/host/mips/host-signal.h @@ -0,0 +1,61 @@ +/* + * host-signal.h: signal info dependent on the host architecture + * + * Copyright (C) 2021 Linaro Limited + * + * This work is licensed under the terms of the GNU GPL, version 2 or late= r. + * See the COPYING file in the top-level directory. + */ + +#ifndef MIPS_HOST_SIGNAL_H +#define MIPS_HOST_SIGNAL_H + +static inline uintptr_t host_signal_pc(ucontext_t *uc) +{ + return uc->uc_mcontext.pc; +} + +#if defined(__misp16) || defined(__mips_micromips) +#error "Unsupported encoding" +#endif + +static inline bool host_sigsegv_write(siginfo_t *info, ucontext_t *uc) +{ + uint32_t *insn =3D *(uint32_t *)host_signal_pc(uc); + + /* Detect all store instructions at program counter. */ + switch ((insn >> 26) & 077) { + case 050: /* SB */ + case 051: /* SH */ + case 052: /* SWL */ + case 053: /* SW */ + case 054: /* SDL */ + case 055: /* SDR */ + case 056: /* SWR */ + case 070: /* SC */ + case 071: /* SWC1 */ + case 074: /* SCD */ + case 075: /* SDC1 */ + case 077: /* SD */ +#if !defined(__mips_isa_rev) || __mips_isa_rev < 6 + case 072: /* SWC2 */ + case 076: /* SDC2 */ +#endif + return true; + case 023: /* COP1X */ + /* + * Required in all versions of MIPS64 since + * MIPS64r1 and subsequent versions of MIPS32r2. + */ + switch (insn & 077) { + case 010: /* SWXC1 */ + case 011: /* SDXC1 */ + case 015: /* SUXC1 */ + return true; + } + break; + } + return false; +} + +#endif diff --git a/linux-user/host/ppc/host-signal.h b/linux-user/host/ppc/host-s= ignal.h new file mode 100644 index 0000000000..b8dce622b4 --- /dev/null +++ b/linux-user/host/ppc/host-signal.h @@ -0,0 +1,24 @@ +/* + * host-signal.h: signal info dependent on the host architecture + * + * Copyright (C) 2021 Linaro Limited + * + * This work is licensed under the terms of the GNU GPL, version 2 or late= r. + * See the COPYING file in the top-level directory. + */ + +#ifndef PPC_HOST_SIGNAL_H +#define PPC_HOST_SIGNAL_H + +static inline uintptr_t host_signal_pc(ucontext_t *uc) +{ + return uc->uc_mcontext.regs->nip; +} + +static inline bool host_sigsegv_write(siginfo_t *info, ucontext_t *uc) +{ + return uc->uc_mcontext.regs->trap !=3D 0x400 + && (uc->uc_mcontext.regs->dsisr & 0x02000000); +} + +#endif diff --git a/linux-user/host/ppc64/host-signal.h b/linux-user/host/ppc64/ho= st-signal.h new file mode 100644 index 0000000000..a353c22a90 --- /dev/null +++ b/linux-user/host/ppc64/host-signal.h @@ -0,0 +1 @@ +#include "../ppc/host-signal.h" diff --git a/linux-user/host/riscv32/host-signal.h b/linux-user/host/riscv3= 2/host-signal.h new file mode 100644 index 0000000000..f877412f96 --- /dev/null +++ b/linux-user/host/riscv32/host-signal.h @@ -0,0 +1,57 @@ +/* + * host-signal.h: signal info dependent on the host architecture + * + * Copyright (C) 2021 Linaro Limited + * + * This work is licensed under the terms of the GNU GPL, version 2 or late= r. + * See the COPYING file in the top-level directory. + */ + +#ifndef RISCV_HOST_SIGNAL_H +#define RISCV_HOST_SIGNAL_H + +static inline uintptr_t host_signal_pc(ucontext_t *uc) +{ + return uc->uc_mcontext.__gregs[REG_PC]; +} + +static inline bool host_sigsegv_write(siginfo_t *info, ucontext_t *uc) +{ + /* + * Detect store by reading the instruction at the program counter. + * Do not read more than 16 bits, because we have not yet determined + * the size of the instruction. + */ + const uint16_t *pinsn =3D (const uint16_t *)host_signal_pc(uc); + uint16_t insn =3D pinsn[0]; + + /* 16-bit instructions */ + switch (insn & 0xe003) { + case 0xa000: /* c.fsd */ + case 0xc000: /* c.sw */ + case 0xe000: /* c.sd (rv64) / c.fsw (rv32) */ + case 0xa002: /* c.fsdsp */ + case 0xc002: /* c.swsp */ + case 0xe002: /* c.sdsp (rv64) / c.fswsp (rv32) */ + return true; + } + + /* 32-bit instructions, major opcodes */ + switch (insn & 0x7f) { + case 0x23: /* store */ + case 0x27: /* store-fp */ + return true; + case 0x2f: /* amo */ + /* + * The AMO function code is in bits 25-31, unread as yet. + * The AMO functions are LR (read), SC (write), and the + * rest are all read-modify-write. + */ + insn =3D pinsn[1]; + return (insn >> 11) !=3D 2; /* LR */ + } + + return false; +} + +#endif diff --git a/linux-user/host/riscv64/host-signal.h b/linux-user/host/riscv6= 4/host-signal.h new file mode 100644 index 0000000000..6e27f725ab --- /dev/null +++ b/linux-user/host/riscv64/host-signal.h @@ -0,0 +1 @@ +#include "../riscv32/host-signal.h" diff --git a/linux-user/host/s390/host-signal.h b/linux-user/host/s390/host= -signal.h new file mode 100644 index 0000000000..8d34b32b9f --- /dev/null +++ b/linux-user/host/s390/host-signal.h @@ -0,0 +1,92 @@ +/* + * host-signal.h: signal info dependent on the host architecture + * + * Copyright (C) 2021 Linaro Limited + * + * This work is licensed under the terms of the GNU GPL, version 2 or late= r. + * See the COPYING file in the top-level directory. + */ + +#ifndef S390_HOST_SIGNAL_H +#define S390_HOST_SIGNAL_H + +static inline uintptr_t host_signal_pc(ucontext_t *uc) +{ + return uc->uc_mcontext.psw.addr; +} + +static inline bool host_sigsegv_write(siginfo_t *info, ucontext_t *uc) +{ + uint16_t *pinsn =3D (uint16_t *)host_signal_pc(uc); + + /* + * ??? On linux, the non-rt signal handler has 4 (!) arguments instead + * of the normal 2 arguments. The 4th argument contains the "Translat= ion- + * Exception Identification for DAT Exceptions" from the hardware (aka + * "int_parm_long"), which does in fact contain the is_write value. + * The rt signal handler, as far as I can tell, does not give this val= ue + * at all. Not that we could get to it from here even if it were. + * So fall back to parsing instructions. Treat read-modify-write ones= as + * writes, which is not fully correct, but for tracking self-modifying= code + * this is better than treating them as reads. Checking si_addr page = flags + * might be a viable improvement, albeit a racy one. + */ + /* ??? This is not even close to complete. */ + switch (pinsn[0] >> 8) { + case 0x50: /* ST */ + case 0x42: /* STC */ + case 0x40: /* STH */ + case 0xba: /* CS */ + case 0xbb: /* CDS */ + return true; + case 0xc4: /* RIL format insns */ + switch (pinsn[0] & 0xf) { + case 0xf: /* STRL */ + case 0xb: /* STGRL */ + case 0x7: /* STHRL */ + return true; + } + break; + case 0xc8: /* SSF format insns */ + switch (pinsn[0] & 0xf) { + case 0x2: /* CSST */ + return true; + } + break; + case 0xe3: /* RXY format insns */ + switch (pinsn[2] & 0xff) { + case 0x50: /* STY */ + case 0x24: /* STG */ + case 0x72: /* STCY */ + case 0x70: /* STHY */ + case 0x8e: /* STPQ */ + case 0x3f: /* STRVH */ + case 0x3e: /* STRV */ + case 0x2f: /* STRVG */ + return true; + } + break; + case 0xeb: /* RSY format insns */ + switch (pinsn[2] & 0xff) { + case 0x14: /* CSY */ + case 0x30: /* CSG */ + case 0x31: /* CDSY */ + case 0x3e: /* CDSG */ + case 0xe4: /* LANG */ + case 0xe6: /* LAOG */ + case 0xe7: /* LAXG */ + case 0xe8: /* LAAG */ + case 0xea: /* LAALG */ + case 0xf4: /* LAN */ + case 0xf6: /* LAO */ + case 0xf7: /* LAX */ + case 0xfa: /* LAAL */ + case 0xf8: /* LAA */ + return true; + } + break; + } + return false; +} + +#endif diff --git a/linux-user/host/s390x/host-signal.h b/linux-user/host/s390x/ho= st-signal.h new file mode 100644 index 0000000000..0e83f9358d --- /dev/null +++ b/linux-user/host/s390x/host-signal.h @@ -0,0 +1 @@ +#include "../s390/host-signal.h" diff --git a/linux-user/host/sparc/host-signal.h b/linux-user/host/sparc/ho= st-signal.h new file mode 100644 index 0000000000..47d3b1512e --- /dev/null +++ b/linux-user/host/sparc/host-signal.h @@ -0,0 +1,53 @@ +/* + * host-signal.h: signal info dependent on the host architecture + * + * Copyright (C) 2021 Linaro Limited + * + * This work is licensed under the terms of the GNU GPL, version 2 or late= r. + * See the COPYING file in the top-level directory. + */ + +#ifndef SPARC_HOST_SIGNAL_H +#define SPARC_HOST_SIGNAL_H + +static inline uintptr_t host_signal_pc(ucontext_t *uc) +{ +#ifdef __arch64__ + return uc->uc_mcontext.mc_gregs[MC_PC]; +#else + return uc->uc_mcontext.gregs[REG_PC]; +#endif +} + +static inline bool host_sigsegv_write(siginfo_t *info, ucontext_t *uc) +{ + uint32_t insn =3D *(uint32_t *)host_signal_pc(uc); + + if ((insn >> 30) =3D=3D 3) { + switch ((insn >> 19) & 0x3f) { + case 0x05: /* stb */ + case 0x15: /* stba */ + case 0x06: /* sth */ + case 0x16: /* stha */ + case 0x04: /* st */ + case 0x14: /* sta */ + case 0x07: /* std */ + case 0x17: /* stda */ + case 0x0e: /* stx */ + case 0x1e: /* stxa */ + case 0x24: /* stf */ + case 0x34: /* stfa */ + case 0x27: /* stdf */ + case 0x37: /* stdfa */ + case 0x26: /* stqf */ + case 0x36: /* stqfa */ + case 0x25: /* stfsr */ + case 0x3c: /* casa */ + case 0x3e: /* casxa */ + return true; + } + } + return false; +} + +#endif diff --git a/linux-user/host/sparc64/host-signal.h b/linux-user/host/sparc6= 4/host-signal.h new file mode 100644 index 0000000000..1191fe2d40 --- /dev/null +++ b/linux-user/host/sparc64/host-signal.h @@ -0,0 +1 @@ +#include "../sparc/host-signal.h" diff --git a/linux-user/host/x86_64/host-signal.h b/linux-user/host/x86_64/= host-signal.h new file mode 100644 index 0000000000..d5fb3e4484 --- /dev/null +++ b/linux-user/host/x86_64/host-signal.h @@ -0,0 +1,24 @@ +/* + * host-signal.h: signal info dependent on the host architecture + * + * Copyright (C) 2021 Linaro Limited + * + * This work is licensed under the terms of the GNU GPL, version 2 or late= r. + * See the COPYING file in the top-level directory. + */ + +#ifndef X86_64_HOST_SIGNAL_H +#define X86_64_HOST_SIGNAL_H + +static inline uintptr_t host_signal_pc(ucontext_t *uc) +{ + return uc->uc_mcontext.gregs[REG_RIP]; +} + +static inline bool host_sigsegv_write(siginfo_t *info, ucontext_t *uc) +{ + return uc->uc_mcontext.gregs[REG_TRAPNO] =3D=3D 0xe + && (uc->uc_mcontext.gregs[REG_ERR] & 0x2); +} + +#endif diff --git a/accel/tcg/user-exec.c b/accel/tcg/user-exec.c index ad6b4f6abf..39635cbea2 100644 --- a/accel/tcg/user-exec.c +++ b/accel/tcg/user-exec.c @@ -29,23 +29,8 @@ #include "trace/trace-root.h" #include "trace/mem.h" =20 -#undef EAX -#undef ECX -#undef EDX -#undef EBX -#undef ESP -#undef EBP -#undef ESI -#undef EDI -#undef EIP -#ifdef __linux__ -#include -#endif - __thread uintptr_t helper_retaddr; =20 -//#define DEBUG_SIGNAL - /** * adjust_signal_pc: * @pc: raw pc from the host signal ucontext_t. @@ -154,69 +139,6 @@ bool handle_sigsegv_accerr_write(CPUState *cpu, sigset= _t *old_set, } } =20 -/* 'pc' is the host PC at which the exception was raised. 'address' is - the effective address of the memory exception. 'is_write' is 1 if a - write caused the exception and otherwise 0'. 'old_set' is the - signal set which should be restored */ -static inline int handle_cpu_signal(uintptr_t pc, siginfo_t *info, - int is_write, sigset_t *old_set) -{ - CPUState *cpu =3D current_cpu; - CPUClass *cc; - unsigned long address =3D (unsigned long)info->si_addr; - MMUAccessType access_type; - - if (is_write) { - access_type =3D MMU_DATA_STORE; - } else if (helper_retaddr =3D=3D 1) { - access_type =3D MMU_INST_FETCH; - } else { - access_type =3D MMU_DATA_LOAD; - } - pc =3D adjust_signal_pc(pc); - - /* For synchronous signals we expect to be coming from the vCPU - * thread (so current_cpu should be valid) and either from running - * code or during translation which can fault as we cross pages. - * - * If neither is true then something has gone wrong and we should - * abort rather than try and restart the vCPU execution. - */ - if (!cpu || !cpu->running) { - printf("qemu:%s received signal outside vCPU context @ pc=3D0x%" - PRIxPTR "\n", __func__, pc); - abort(); - } - -#if defined(DEBUG_SIGNAL) - printf("qemu: SIGSEGV pc=3D0x%08lx address=3D%08lx w=3D%d oldset=3D0x%= 08lx\n", - pc, address, is_write, *(unsigned long *)old_set); -#endif - - /* XXX: locking issue */ - if (is_write && - info->si_signo =3D=3D SIGSEGV && - info->si_code =3D=3D SEGV_ACCERR && - handle_sigsegv_accerr_write(cpu, old_set, pc, address)) { - return 1; - } - - /* Convert forcefully to guest address space, invalid addresses - are still valid segv ones */ - address =3D h2g_nocheck(address); - - /* - * There is no way the target can handle this other than raising - * an exception. Undo signal and retaddr state prior to longjmp. - */ - sigprocmask(SIG_SETMASK, old_set, NULL); - - cc =3D CPU_GET_CLASS(cpu); - cc->tcg_ops->tlb_fill(cpu, address, 0, access_type, - MMU_USER_IDX, false, pc); - g_assert_not_reached(); -} - static int probe_access_internal(CPUArchState *env, target_ulong addr, int fault_size, MMUAccessType access_type, bool nonfault, uintptr_t ra) @@ -275,640 +197,6 @@ void *probe_access(CPUArchState *env, target_ulong ad= dr, int size, return size ? g2h(env_cpu(env), addr) : NULL; } =20 -#if defined(__i386__) - -#if defined(__NetBSD__) -#include -#include - -#define EIP_sig(context) ((context)->uc_mcontext.__gregs[_REG_EIP]) -#define TRAP_sig(context) ((context)->uc_mcontext.__gregs[_REG_TRAPNO]) -#define ERROR_sig(context) ((context)->uc_mcontext.__gregs[_REG_ERR]) -#define MASK_sig(context) ((context)->uc_sigmask) -#define PAGE_FAULT_TRAP T_PAGEFLT -#elif defined(__FreeBSD__) || defined(__DragonFly__) -#include -#include - -#define EIP_sig(context) (*((unsigned long *)&(context)->uc_mcontext.mc_e= ip)) -#define TRAP_sig(context) ((context)->uc_mcontext.mc_trapno) -#define ERROR_sig(context) ((context)->uc_mcontext.mc_err) -#define MASK_sig(context) ((context)->uc_sigmask) -#define PAGE_FAULT_TRAP T_PAGEFLT -#elif defined(__OpenBSD__) -#include -#define EIP_sig(context) ((context)->sc_eip) -#define TRAP_sig(context) ((context)->sc_trapno) -#define ERROR_sig(context) ((context)->sc_err) -#define MASK_sig(context) ((context)->sc_mask) -#define PAGE_FAULT_TRAP T_PAGEFLT -#else -#define EIP_sig(context) ((context)->uc_mcontext.gregs[REG_EIP]) -#define TRAP_sig(context) ((context)->uc_mcontext.gregs[REG_TRAPNO]) -#define ERROR_sig(context) ((context)->uc_mcontext.gregs[REG_ERR]) -#define MASK_sig(context) ((context)->uc_sigmask) -#define PAGE_FAULT_TRAP 0xe -#endif - -int cpu_signal_handler(int host_signum, void *pinfo, - void *puc) -{ - siginfo_t *info =3D pinfo; -#if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__DragonFly__) - ucontext_t *uc =3D puc; -#elif defined(__OpenBSD__) - struct sigcontext *uc =3D puc; -#else - ucontext_t *uc =3D puc; -#endif - unsigned long pc; - int trapno; - -#ifndef REG_EIP -/* for glibc 2.1 */ -#define REG_EIP EIP -#define REG_ERR ERR -#define REG_TRAPNO TRAPNO -#endif - pc =3D EIP_sig(uc); - trapno =3D TRAP_sig(uc); - return handle_cpu_signal(pc, info, - trapno =3D=3D PAGE_FAULT_TRAP ? - (ERROR_sig(uc) >> 1) & 1 : 0, - &MASK_sig(uc)); -} - -#elif defined(__x86_64__) - -#ifdef __NetBSD__ -#include -#define PC_sig(context) _UC_MACHINE_PC(context) -#define TRAP_sig(context) ((context)->uc_mcontext.__gregs[_REG_TRAPNO]) -#define ERROR_sig(context) ((context)->uc_mcontext.__gregs[_REG_ERR]) -#define MASK_sig(context) ((context)->uc_sigmask) -#define PAGE_FAULT_TRAP T_PAGEFLT -#elif defined(__OpenBSD__) -#include -#define PC_sig(context) ((context)->sc_rip) -#define TRAP_sig(context) ((context)->sc_trapno) -#define ERROR_sig(context) ((context)->sc_err) -#define MASK_sig(context) ((context)->sc_mask) -#define PAGE_FAULT_TRAP T_PAGEFLT -#elif defined(__FreeBSD__) || defined(__DragonFly__) -#include -#include - -#define PC_sig(context) (*((unsigned long *)&(context)->uc_mcontext.mc_ri= p)) -#define TRAP_sig(context) ((context)->uc_mcontext.mc_trapno) -#define ERROR_sig(context) ((context)->uc_mcontext.mc_err) -#define MASK_sig(context) ((context)->uc_sigmask) -#define PAGE_FAULT_TRAP T_PAGEFLT -#else -#define PC_sig(context) ((context)->uc_mcontext.gregs[REG_RIP]) -#define TRAP_sig(context) ((context)->uc_mcontext.gregs[REG_TRAPNO]) -#define ERROR_sig(context) ((context)->uc_mcontext.gregs[REG_ERR]) -#define MASK_sig(context) ((context)->uc_sigmask) -#define PAGE_FAULT_TRAP 0xe -#endif - -int cpu_signal_handler(int host_signum, void *pinfo, - void *puc) -{ - siginfo_t *info =3D pinfo; - unsigned long pc; -#if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__DragonFly__) - ucontext_t *uc =3D puc; -#elif defined(__OpenBSD__) - struct sigcontext *uc =3D puc; -#else - ucontext_t *uc =3D puc; -#endif - - pc =3D PC_sig(uc); - return handle_cpu_signal(pc, info, - TRAP_sig(uc) =3D=3D PAGE_FAULT_TRAP ? - (ERROR_sig(uc) >> 1) & 1 : 0, - &MASK_sig(uc)); -} - -#elif defined(_ARCH_PPC) - -/*********************************************************************** - * signal context platform-specific definitions - * From Wine - */ -#ifdef linux -/* All Registers access - only for local access */ -#define REG_sig(reg_name, context) \ - ((context)->uc_mcontext.regs->reg_name) -/* Gpr Registers access */ -#define GPR_sig(reg_num, context) REG_sig(gpr[reg_num], conte= xt) -/* Program counter */ -#define IAR_sig(context) REG_sig(nip, context) -/* Machine State Register (Supervisor) */ -#define MSR_sig(context) REG_sig(msr, context) -/* Count register */ -#define CTR_sig(context) REG_sig(ctr, context) -/* User's integer exception register */ -#define XER_sig(context) REG_sig(xer, context) -/* Link register */ -#define LR_sig(context) REG_sig(link, context) -/* Condition register */ -#define CR_sig(context) REG_sig(ccr, context) - -/* Float Registers access */ -#define FLOAT_sig(reg_num, context) \ - (((double *)((char *)((context)->uc_mcontext.regs + 48 * 4)))[reg_num]) -#define FPSCR_sig(context) \ - (*(int *)((char *)((context)->uc_mcontext.regs + (48 + 32 * 2) * 4))) -/* Exception Registers access */ -#define DAR_sig(context) REG_sig(dar, context) -#define DSISR_sig(context) REG_sig(dsisr, context) -#define TRAP_sig(context) REG_sig(trap, context) -#endif /* linux */ - -#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) -#include -#define IAR_sig(context) ((context)->uc_mcontext.mc_srr0) -#define MSR_sig(context) ((context)->uc_mcontext.mc_srr1) -#define CTR_sig(context) ((context)->uc_mcontext.mc_ctr) -#define XER_sig(context) ((context)->uc_mcontext.mc_xer) -#define LR_sig(context) ((context)->uc_mcontext.mc_lr) -#define CR_sig(context) ((context)->uc_mcontext.mc_cr) -/* Exception Registers access */ -#define DAR_sig(context) ((context)->uc_mcontext.mc_dar) -#define DSISR_sig(context) ((context)->uc_mcontext.mc_dsisr) -#define TRAP_sig(context) ((context)->uc_mcontext.mc_exc) -#endif /* __FreeBSD__|| __FreeBSD_kernel__ */ - -int cpu_signal_handler(int host_signum, void *pinfo, - void *puc) -{ - siginfo_t *info =3D pinfo; -#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) - ucontext_t *uc =3D puc; -#else - ucontext_t *uc =3D puc; -#endif - unsigned long pc; - int is_write; - - pc =3D IAR_sig(uc); - is_write =3D 0; -#if 0 - /* ppc 4xx case */ - if (DSISR_sig(uc) & 0x00800000) { - is_write =3D 1; - } -#else - if (TRAP_sig(uc) !=3D 0x400 && (DSISR_sig(uc) & 0x02000000)) { - is_write =3D 1; - } -#endif - return handle_cpu_signal(pc, info, is_write, &uc->uc_sigmask); -} - -#elif defined(__alpha__) - -int cpu_signal_handler(int host_signum, void *pinfo, - void *puc) -{ - siginfo_t *info =3D pinfo; - ucontext_t *uc =3D puc; - uint32_t *pc =3D uc->uc_mcontext.sc_pc; - uint32_t insn =3D *pc; - int is_write =3D 0; - - /* XXX: need kernel patch to get write flag faster */ - switch (insn >> 26) { - case 0x0d: /* stw */ - case 0x0e: /* stb */ - case 0x0f: /* stq_u */ - case 0x24: /* stf */ - case 0x25: /* stg */ - case 0x26: /* sts */ - case 0x27: /* stt */ - case 0x2c: /* stl */ - case 0x2d: /* stq */ - case 0x2e: /* stl_c */ - case 0x2f: /* stq_c */ - is_write =3D 1; - } - - return handle_cpu_signal(pc, info, is_write, &uc->uc_sigmask); -} -#elif defined(__sparc__) - -int cpu_signal_handler(int host_signum, void *pinfo, - void *puc) -{ - siginfo_t *info =3D pinfo; - int is_write; - uint32_t insn; -#if !defined(__arch64__) || defined(CONFIG_SOLARIS) - uint32_t *regs =3D (uint32_t *)(info + 1); - void *sigmask =3D (regs + 20); - /* XXX: is there a standard glibc define ? */ - unsigned long pc =3D regs[1]; -#else -#ifdef __linux__ - struct sigcontext *sc =3D puc; - unsigned long pc =3D sc->sigc_regs.tpc; - void *sigmask =3D (void *)sc->sigc_mask; -#elif defined(__OpenBSD__) - struct sigcontext *uc =3D puc; - unsigned long pc =3D uc->sc_pc; - void *sigmask =3D (void *)(long)uc->sc_mask; -#elif defined(__NetBSD__) - ucontext_t *uc =3D puc; - unsigned long pc =3D _UC_MACHINE_PC(uc); - void *sigmask =3D (void *)&uc->uc_sigmask; -#endif -#endif - - /* XXX: need kernel patch to get write flag faster */ - is_write =3D 0; - insn =3D *(uint32_t *)pc; - if ((insn >> 30) =3D=3D 3) { - switch ((insn >> 19) & 0x3f) { - case 0x05: /* stb */ - case 0x15: /* stba */ - case 0x06: /* sth */ - case 0x16: /* stha */ - case 0x04: /* st */ - case 0x14: /* sta */ - case 0x07: /* std */ - case 0x17: /* stda */ - case 0x0e: /* stx */ - case 0x1e: /* stxa */ - case 0x24: /* stf */ - case 0x34: /* stfa */ - case 0x27: /* stdf */ - case 0x37: /* stdfa */ - case 0x26: /* stqf */ - case 0x36: /* stqfa */ - case 0x25: /* stfsr */ - case 0x3c: /* casa */ - case 0x3e: /* casxa */ - is_write =3D 1; - break; - } - } - return handle_cpu_signal(pc, info, is_write, sigmask); -} - -#elif defined(__arm__) - -#if defined(__NetBSD__) -#include -#include -#endif - -int cpu_signal_handler(int host_signum, void *pinfo, - void *puc) -{ - siginfo_t *info =3D pinfo; -#if defined(__NetBSD__) - ucontext_t *uc =3D puc; - siginfo_t *si =3D pinfo; -#else - ucontext_t *uc =3D puc; -#endif - unsigned long pc; - uint32_t fsr; - int is_write; - -#if defined(__NetBSD__) - pc =3D uc->uc_mcontext.__gregs[_REG_R15]; -#elif defined(__GLIBC__) && (__GLIBC__ < 2 || (__GLIBC__ =3D=3D 2 && __GLI= BC_MINOR__ <=3D 3)) - pc =3D uc->uc_mcontext.gregs[R15]; -#else - pc =3D uc->uc_mcontext.arm_pc; -#endif - -#ifdef __NetBSD__ - fsr =3D si->si_trap; -#else - fsr =3D uc->uc_mcontext.error_code; -#endif - /* - * In the FSR, bit 11 is WnR, assuming a v6 or - * later processor. On v5 we will always report - * this as a read, which will fail later. - */ - is_write =3D extract32(fsr, 11, 1); - return handle_cpu_signal(pc, info, is_write, &uc->uc_sigmask); -} - -#elif defined(__aarch64__) - -#if defined(__NetBSD__) - -#include -#include - -int cpu_signal_handler(int host_signum, void *pinfo, void *puc) -{ - ucontext_t *uc =3D puc; - siginfo_t *si =3D pinfo; - unsigned long pc; - int is_write; - uint32_t esr; - - pc =3D uc->uc_mcontext.__gregs[_REG_PC]; - esr =3D si->si_trap; - - /* - * siginfo_t::si_trap is the ESR value, for data aborts ESR.EC - * is 0b10010x: then bit 6 is the WnR bit - */ - is_write =3D extract32(esr, 27, 5) =3D=3D 0x12 && extract32(esr, 6, 1)= =3D=3D 1; - return handle_cpu_signal(pc, si, is_write, &uc->uc_sigmask); -} - -#else - -#ifndef ESR_MAGIC -/* Pre-3.16 kernel headers don't have these, so provide fallback definitio= ns */ -#define ESR_MAGIC 0x45535201 -struct esr_context { - struct _aarch64_ctx head; - uint64_t esr; -}; -#endif - -static inline struct _aarch64_ctx *first_ctx(ucontext_t *uc) -{ - return (struct _aarch64_ctx *)&uc->uc_mcontext.__reserved; -} - -static inline struct _aarch64_ctx *next_ctx(struct _aarch64_ctx *hdr) -{ - return (struct _aarch64_ctx *)((char *)hdr + hdr->size); -} - -int cpu_signal_handler(int host_signum, void *pinfo, void *puc) -{ - siginfo_t *info =3D pinfo; - ucontext_t *uc =3D puc; - uintptr_t pc =3D uc->uc_mcontext.pc; - bool is_write; - struct _aarch64_ctx *hdr; - struct esr_context const *esrctx =3D NULL; - - /* Find the esr_context, which has the WnR bit in it */ - for (hdr =3D first_ctx(uc); hdr->magic; hdr =3D next_ctx(hdr)) { - if (hdr->magic =3D=3D ESR_MAGIC) { - esrctx =3D (struct esr_context const *)hdr; - break; - } - } - - if (esrctx) { - /* For data aborts ESR.EC is 0b10010x: then bit 6 is the WnR bit */ - uint64_t esr =3D esrctx->esr; - is_write =3D extract32(esr, 27, 5) =3D=3D 0x12 && extract32(esr, 6= , 1) =3D=3D 1; - } else { - /* - * Fall back to parsing instructions; will only be needed - * for really ancient (pre-3.16) kernels. - */ - uint32_t insn =3D *(uint32_t *)pc; - - is_write =3D ((insn & 0xbfff0000) =3D=3D 0x0c000000 /* C3.3.1 */ - || (insn & 0xbfe00000) =3D=3D 0x0c800000 /* C3.3.2 */ - || (insn & 0xbfdf0000) =3D=3D 0x0d000000 /* C3.3.3 */ - || (insn & 0xbfc00000) =3D=3D 0x0d800000 /* C3.3.4 */ - || (insn & 0x3f400000) =3D=3D 0x08000000 /* C3.3.6 */ - || (insn & 0x3bc00000) =3D=3D 0x39000000 /* C3.3.13 = */ - || (insn & 0x3fc00000) =3D=3D 0x3d800000 /* ... 128b= it */ - /* Ignore bits 10, 11 & 21, controlling indexing. */ - || (insn & 0x3bc00000) =3D=3D 0x38000000 /* C3.3.8-1= 2 */ - || (insn & 0x3fe00000) =3D=3D 0x3c800000 /* ... 128b= it */ - /* Ignore bits 23 & 24, controlling indexing. */ - || (insn & 0x3a400000) =3D=3D 0x28000000); /* C3.3.7,1= 4-16 */ - } - return handle_cpu_signal(pc, info, is_write, &uc->uc_sigmask); -} -#endif - -#elif defined(__s390__) - -int cpu_signal_handler(int host_signum, void *pinfo, - void *puc) -{ - siginfo_t *info =3D pinfo; - ucontext_t *uc =3D puc; - unsigned long pc; - uint16_t *pinsn; - int is_write =3D 0; - - pc =3D uc->uc_mcontext.psw.addr; - - /* - * ??? On linux, the non-rt signal handler has 4 (!) arguments instead - * of the normal 2 arguments. The 4th argument contains the "Translat= ion- - * Exception Identification for DAT Exceptions" from the hardware (aka - * "int_parm_long"), which does in fact contain the is_write value. - * The rt signal handler, as far as I can tell, does not give this val= ue - * at all. Not that we could get to it from here even if it were. - * So fall back to parsing instructions. Treat read-modify-write ones= as - * writes, which is not fully correct, but for tracking self-modifying= code - * this is better than treating them as reads. Checking si_addr page = flags - * might be a viable improvement, albeit a racy one. - */ - /* ??? This is not even close to complete. */ - pinsn =3D (uint16_t *)pc; - switch (pinsn[0] >> 8) { - case 0x50: /* ST */ - case 0x42: /* STC */ - case 0x40: /* STH */ - case 0xba: /* CS */ - case 0xbb: /* CDS */ - is_write =3D 1; - break; - case 0xc4: /* RIL format insns */ - switch (pinsn[0] & 0xf) { - case 0xf: /* STRL */ - case 0xb: /* STGRL */ - case 0x7: /* STHRL */ - is_write =3D 1; - } - break; - case 0xc8: /* SSF format insns */ - switch (pinsn[0] & 0xf) { - case 0x2: /* CSST */ - is_write =3D 1; - } - break; - case 0xe3: /* RXY format insns */ - switch (pinsn[2] & 0xff) { - case 0x50: /* STY */ - case 0x24: /* STG */ - case 0x72: /* STCY */ - case 0x70: /* STHY */ - case 0x8e: /* STPQ */ - case 0x3f: /* STRVH */ - case 0x3e: /* STRV */ - case 0x2f: /* STRVG */ - is_write =3D 1; - } - break; - case 0xeb: /* RSY format insns */ - switch (pinsn[2] & 0xff) { - case 0x14: /* CSY */ - case 0x30: /* CSG */ - case 0x31: /* CDSY */ - case 0x3e: /* CDSG */ - case 0xe4: /* LANG */ - case 0xe6: /* LAOG */ - case 0xe7: /* LAXG */ - case 0xe8: /* LAAG */ - case 0xea: /* LAALG */ - case 0xf4: /* LAN */ - case 0xf6: /* LAO */ - case 0xf7: /* LAX */ - case 0xfa: /* LAAL */ - case 0xf8: /* LAA */ - is_write =3D 1; - } - break; - } - - return handle_cpu_signal(pc, info, is_write, &uc->uc_sigmask); -} - -#elif defined(__mips__) - -#if defined(__misp16) || defined(__mips_micromips) -#error "Unsupported encoding" -#endif - -int cpu_signal_handler(int host_signum, void *pinfo, - void *puc) -{ - siginfo_t *info =3D pinfo; - ucontext_t *uc =3D puc; - uintptr_t pc =3D uc->uc_mcontext.pc; - uint32_t insn =3D *(uint32_t *)pc; - int is_write =3D 0; - - /* Detect all store instructions at program counter. */ - switch((insn >> 26) & 077) { - case 050: /* SB */ - case 051: /* SH */ - case 052: /* SWL */ - case 053: /* SW */ - case 054: /* SDL */ - case 055: /* SDR */ - case 056: /* SWR */ - case 070: /* SC */ - case 071: /* SWC1 */ - case 074: /* SCD */ - case 075: /* SDC1 */ - case 077: /* SD */ -#if !defined(__mips_isa_rev) || __mips_isa_rev < 6 - case 072: /* SWC2 */ - case 076: /* SDC2 */ -#endif - is_write =3D 1; - break; - case 023: /* COP1X */ - /* Required in all versions of MIPS64 since - MIPS64r1 and subsequent versions of MIPS32r2. */ - switch (insn & 077) { - case 010: /* SWXC1 */ - case 011: /* SDXC1 */ - case 015: /* SUXC1 */ - is_write =3D 1; - } - break; - } - - return handle_cpu_signal(pc, info, is_write, &uc->uc_sigmask); -} - -#elif defined(__riscv) - -int cpu_signal_handler(int host_signum, void *pinfo, - void *puc) -{ - siginfo_t *info =3D pinfo; - ucontext_t *uc =3D puc; - greg_t pc =3D uc->uc_mcontext.__gregs[REG_PC]; - uint32_t insn =3D *(uint32_t *)pc; - int is_write =3D 0; - - /* Detect store by reading the instruction at the program - counter. Note: we currently only generate 32-bit - instructions so we thus only detect 32-bit stores */ - switch (((insn >> 0) & 0b11)) { - case 3: - switch (((insn >> 2) & 0b11111)) { - case 8: - switch (((insn >> 12) & 0b111)) { - case 0: /* sb */ - case 1: /* sh */ - case 2: /* sw */ - case 3: /* sd */ - case 4: /* sq */ - is_write =3D 1; - break; - default: - break; - } - break; - case 9: - switch (((insn >> 12) & 0b111)) { - case 2: /* fsw */ - case 3: /* fsd */ - case 4: /* fsq */ - is_write =3D 1; - break; - default: - break; - } - break; - default: - break; - } - } - - /* Check for compressed instructions */ - switch (((insn >> 13) & 0b111)) { - case 7: - switch (insn & 0b11) { - case 0: /*c.sd */ - case 2: /* c.sdsp */ - is_write =3D 1; - break; - default: - break; - } - break; - case 6: - switch (insn & 0b11) { - case 0: /* c.sw */ - case 3: /* c.swsp */ - is_write =3D 1; - break; - default: - break; - } - break; - default: - break; - } - - return handle_cpu_signal(pc, info, is_write, &uc->uc_sigmask); -} - -#else - -#error host CPU specific signal handler needed - -#endif - /* The softmmu versions of these helpers are in cputlb.c. */ =20 uint32_t cpu_ldub_data(CPUArchState *env, abi_ptr ptr) diff --git a/linux-user/signal.c b/linux-user/signal.c index 73c0f9066b..509dad7850 100644 --- a/linux-user/signal.c +++ b/linux-user/signal.c @@ -24,6 +24,7 @@ #include "qemu.h" #include "trace.h" #include "signal-common.h" +#include "host-signal.h" =20 static struct target_sigaction sigact_table[TARGET_NSIG]; =20 @@ -753,59 +754,85 @@ static inline void rewind_if_in_safe_syscall(void *pu= c) } #endif =20 -static void host_signal_handler(int host_signum, siginfo_t *info, - void *puc) +static void host_signal_handler(int host_sig, siginfo_t *info, void *puc) { CPUArchState *env =3D thread_cpu->env_ptr; CPUState *cpu =3D env_cpu(env); TaskState *ts =3D cpu->opaque; - - int sig; + bool sync_sig =3D false; target_siginfo_t tinfo; ucontext_t *uc =3D puc; struct emulated_sigtable *k; + uintptr_t pc =3D 0; + int guest_sig; =20 - /* the CPU emulator uses some host signals to detect exceptions, - we forward to it some signals */ - if ((host_signum =3D=3D SIGSEGV || host_signum =3D=3D SIGBUS) - && info->si_code > 0) { - if (cpu_signal_handler(host_signum, info, puc)) + /* + * Non-spoofed SIGSEGV and SIGBUS are synchronous, and need special + * handling wrt signal blocking and unwinding. SIGSEGV may need to + * remove write-protection and restart the instruction. + */ + if ((host_sig =3D=3D SIGSEGV || host_sig =3D=3D SIGBUS) && info->si_co= de > 0) { + pc =3D adjust_signal_pc(host_signal_pc(uc)); + if (host_sig =3D=3D SIGSEGV && + info->si_code =3D=3D SEGV_ACCERR && + host_sigsegv_write(info, uc) && + handle_sigsegv_accerr_write(cpu, &uc->uc_sigmask, pc, + (uintptr_t)info->si_addr)) { return; + } + sync_sig =3D true; + } else { + rewind_if_in_safe_syscall(puc); + + /* + * Block host signals until target signal handler entered. + * We can't block SIGSEGV or SIGBUS while we're executing + * guest code in case the guest code provokes one in the + * window between now and it getting out to the main loop. + * Signals will be unblocked again in process_pending_signals(). + * + * WARNING: we cannot use sigfillset() here because the uc_sigmask + * field is a kernel sigset_t, which is much smaller than the + * libc sigset_t which sigfillset() operates on. Using sigfillset() + * would write 0xff bytes off the end of the structure and trash + * data on the struct. + * We can't use sizeof(uc->uc_sigmask) either, because the libc + * headers define the struct field with the wrong (too large) type. + */ + memset(&uc->uc_sigmask, 0xff, SIGSET_T_SIZE); + sigdelset(&uc->uc_sigmask, SIGSEGV); + sigdelset(&uc->uc_sigmask, SIGBUS); } =20 /* get target signal number */ - sig =3D host_to_target_signal(host_signum); - if (sig < 1 || sig > TARGET_NSIG) + guest_sig =3D host_to_target_signal(host_sig); + if (guest_sig < 1 || guest_sig > TARGET_NSIG) { return; - trace_user_host_signal(env, host_signum, sig); - - rewind_if_in_safe_syscall(puc); + } + trace_user_host_signal(env, host_sig, guest_sig); =20 host_to_target_siginfo_noswap(&tinfo, info); - k =3D &ts->sigtab[sig - 1]; + k =3D &ts->sigtab[guest_sig - 1]; k->info =3D tinfo; - k->pending =3D sig; + k->pending =3D guest_sig; ts->signal_pending =3D 1; =20 - /* Block host signals until target signal handler entered. We - * can't block SIGSEGV or SIGBUS while we're executing guest - * code in case the guest code provokes one in the window between - * now and it getting out to the main loop. Signals will be - * unblocked again in process_pending_signals(). - * - * WARNING: we cannot use sigfillset() here because the uc_sigmask - * field is a kernel sigset_t, which is much smaller than the - * libc sigset_t which sigfillset() operates on. Using sigfillset() - * would write 0xff bytes off the end of the structure and trash - * data on the struct. - * We can't use sizeof(uc->uc_sigmask) either, because the libc - * headers define the struct field with the wrong (too large) type. + /* + * For synchronous signals, unwind the cpu state to the faulting + * insn and then exit back to the main loop so that the signal + * is delivered immediately. */ - memset(&uc->uc_sigmask, 0xff, SIGSET_T_SIZE); - sigdelset(&uc->uc_sigmask, SIGSEGV); - sigdelset(&uc->uc_sigmask, SIGBUS); + if (sync_sig) { + clear_helper_retaddr(); + sigprocmask(SIG_SETMASK, &uc->uc_sigmask, NULL); + cpu->exception_index =3D EXCP_INTERRUPT; + cpu_loop_exit_restore(cpu, pc); + } =20 - /* interrupt the virtual CPU as soon as possible */ + /* + * Interrupt the virtual CPU as soon as possible, but for now + * return to continue with the current TB. + */ cpu_exit(thread_cpu); } =20 --=20 2.25.1