* [PATCH v2 0/6] tcg: Fix x86 TARGET_TB_PCREL (#1269) @ 2022-10-27 10:02 Richard Henderson 2022-10-27 10:02 ` [PATCH v2 1/6] accel/tcg: Introduce cpu_unwind_state_data Richard Henderson ` (6 more replies) 0 siblings, 7 replies; 17+ messages in thread From: Richard Henderson @ 2022-10-27 10:02 UTC (permalink / raw) To: qemu-devel; +Cc: cfontana As per #1269, this affects NetBSD installer boot. The problem is that one of the x86 acpi callbacks modifies env->eip during an mmio store, which means that the tracking that translate.c does is thrown out of whack. Introduce a method to extract unwind data without the writeback to env. This isn't a perfect abstraction, but I couldn't think of anything better. There's a couple of lines of code duplication, but probably less than any abstration that we might put on top Changes for v2: * Rebase on master, 23 patches merged. * Comments adjusted per review (claudio) r~ Richard Henderson (6): accel/tcg: Introduce cpu_unwind_state_data target/i386: Use cpu_unwind_state_data for tpr access target/openrisc: Always exit after mtspr npc target/openrisc: Use cpu_unwind_state_data for mfspr accel/tcg: Remove will_exit argument from cpu_restore_state accel/tcg: Remove reset_icount argument from cpu_restore_state_from_tb accel/tcg/internal.h | 4 +- include/exec/exec-all.h | 24 +++++--- accel/tcg/cpu-exec-common.c | 2 +- accel/tcg/tb-maint.c | 4 +- accel/tcg/translate-all.c | 91 +++++++++++++++++------------ target/alpha/helper.c | 2 +- target/alpha/mem_helper.c | 2 +- target/arm/op_helper.c | 2 +- target/arm/tlb_helper.c | 8 +-- target/cris/helper.c | 2 +- target/i386/helper.c | 21 ++++++- target/i386/tcg/sysemu/svm_helper.c | 2 +- target/m68k/op_helper.c | 4 +- target/microblaze/helper.c | 2 +- target/nios2/op_helper.c | 2 +- target/openrisc/sys_helper.c | 17 ++++-- target/ppc/excp_helper.c | 2 +- target/s390x/tcg/excp_helper.c | 2 +- target/tricore/op_helper.c | 2 +- target/xtensa/helper.c | 6 +- 20 files changed, 125 insertions(+), 76 deletions(-) -- 2.34.1 ^ permalink raw reply [flat|nested] 17+ messages in thread
* [PATCH v2 1/6] accel/tcg: Introduce cpu_unwind_state_data 2022-10-27 10:02 [PATCH v2 0/6] tcg: Fix x86 TARGET_TB_PCREL (#1269) Richard Henderson @ 2022-10-27 10:02 ` Richard Henderson 2022-10-27 10:40 ` Claudio Fontana 2022-10-27 10:02 ` [PATCH v2 2/6] target/i386: Use cpu_unwind_state_data for tpr access Richard Henderson ` (5 subsequent siblings) 6 siblings, 1 reply; 17+ messages in thread From: Richard Henderson @ 2022-10-27 10:02 UTC (permalink / raw) To: qemu-devel; +Cc: cfontana Add a way to examine the unwind data without actually restoring the data back into env. Signed-off-by: Richard Henderson <richard.henderson@linaro.org> --- accel/tcg/internal.h | 4 +-- include/exec/exec-all.h | 21 ++++++++--- accel/tcg/translate-all.c | 74 ++++++++++++++++++++++++++------------- 3 files changed, 68 insertions(+), 31 deletions(-) diff --git a/accel/tcg/internal.h b/accel/tcg/internal.h index 1227bb69bd..9c06b320b7 100644 --- a/accel/tcg/internal.h +++ b/accel/tcg/internal.h @@ -106,8 +106,8 @@ void tb_reset_jump(TranslationBlock *tb, int n); TranslationBlock *tb_link_page(TranslationBlock *tb, tb_page_addr_t phys_pc, tb_page_addr_t phys_page2); bool tb_invalidate_phys_page_unwind(tb_page_addr_t addr, uintptr_t pc); -int cpu_restore_state_from_tb(CPUState *cpu, TranslationBlock *tb, - uintptr_t searched_pc, bool reset_icount); +void cpu_restore_state_from_tb(CPUState *cpu, TranslationBlock *tb, + uintptr_t host_pc, bool reset_icount); /* Return the current PC from CPU, which may be cached in TB. */ static inline target_ulong log_pc(CPUState *cpu, const TranslationBlock *tb) diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h index e948992a80..7d851f5907 100644 --- a/include/exec/exec-all.h +++ b/include/exec/exec-all.h @@ -39,20 +39,33 @@ typedef ram_addr_t tb_page_addr_t; #define TB_PAGE_ADDR_FMT RAM_ADDR_FMT #endif +/** + * cpu_unwind_state_data: + * @cpu: the cpu context + * @host_pc: the host pc within the translation + * @data: output data + * + * Attempt to load the the unwind state for a host pc occurring in + * translated code. If @host_pc is not in translated code, the + * function returns false; otherwise @data is loaded. + * This is the same unwind info as given to restore_state_to_opc. + */ +bool cpu_unwind_state_data(CPUState *cpu, uintptr_t host_pc, uint64_t *data); + /** * cpu_restore_state: - * @cpu: the vCPU state is to be restore to - * @searched_pc: the host PC the fault occurred at + * @cpu: the cpu context + * @host_pc: the host pc within the translation * @will_exit: true if the TB executed will be interrupted after some cpu adjustments. Required for maintaining the correct icount valus * @return: true if state was restored, false otherwise * * Attempt to restore the state for a fault occurring in translated - * code. If the searched_pc is not in translated code no state is + * code. If @host_pc is not in translated code no state is * restored and the function returns false. */ -bool cpu_restore_state(CPUState *cpu, uintptr_t searched_pc, bool will_exit); +bool cpu_restore_state(CPUState *cpu, uintptr_t host_pc, bool will_exit); G_NORETURN void cpu_loop_exit_noexc(CPUState *cpu); G_NORETURN void cpu_loop_exit(CPUState *cpu); diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c index f185356a36..319becb698 100644 --- a/accel/tcg/translate-all.c +++ b/accel/tcg/translate-all.c @@ -247,52 +247,66 @@ static int encode_search(TranslationBlock *tb, uint8_t *block) return p - block; } -/* The cpu state corresponding to 'searched_pc' is restored. - * When reset_icount is true, current TB will be interrupted and - * icount should be recalculated. - */ -int cpu_restore_state_from_tb(CPUState *cpu, TranslationBlock *tb, - uintptr_t searched_pc, bool reset_icount) +static int cpu_unwind_data_from_tb(TranslationBlock *tb, uintptr_t host_pc, + uint64_t *data) { - uint64_t data[TARGET_INSN_START_WORDS]; - uintptr_t host_pc = (uintptr_t)tb->tc.ptr; + uintptr_t iter_pc = (uintptr_t)tb->tc.ptr; const uint8_t *p = tb->tc.ptr + tb->tc.size; int i, j, num_insns = tb->icount; -#ifdef CONFIG_PROFILER - TCGProfile *prof = &tcg_ctx->prof; - int64_t ti = profile_getclock(); -#endif - searched_pc -= GETPC_ADJ; + host_pc -= GETPC_ADJ; - if (searched_pc < host_pc) { + if (host_pc < iter_pc) { return -1; } - memset(data, 0, sizeof(data)); + memset(data, 0, sizeof(uint64_t) * TARGET_INSN_START_WORDS); if (!TARGET_TB_PCREL) { data[0] = tb_pc(tb); } - /* Reconstruct the stored insn data while looking for the point at - which the end of the insn exceeds the searched_pc. */ + /* + * Reconstruct the stored insn data while looking for the point + * at which the end of the insn exceeds host_pc. + */ for (i = 0; i < num_insns; ++i) { for (j = 0; j < TARGET_INSN_START_WORDS; ++j) { data[j] += decode_sleb128(&p); } - host_pc += decode_sleb128(&p); - if (host_pc > searched_pc) { - goto found; + iter_pc += decode_sleb128(&p); + if (iter_pc > host_pc) { + return num_insns - i; } } return -1; +} + +/* + * The cpu state corresponding to 'host_pc' is restored. + * When reset_icount is true, current TB will be interrupted and + * icount should be recalculated. + */ +void cpu_restore_state_from_tb(CPUState *cpu, TranslationBlock *tb, + uintptr_t host_pc, bool reset_icount) +{ + uint64_t data[TARGET_INSN_START_WORDS]; +#ifdef CONFIG_PROFILER + TCGProfile *prof = &tcg_ctx->prof; + int64_t ti = profile_getclock(); +#endif + int insns_left = cpu_unwind_data_from_tb(tb, host_pc, data); + + if (insns_left < 0) { + return; + } - found: if (reset_icount && (tb_cflags(tb) & CF_USE_ICOUNT)) { assert(icount_enabled()); - /* Reset the cycle counter to the start of the block - and shift if to the number of actually executed instructions */ - cpu_neg(cpu)->icount_decr.u16.low += num_insns - i; + /* + * Reset the cycle counter to the start of the block and + * shift if to the number of actually executed instructions. + */ + cpu_neg(cpu)->icount_decr.u16.low += insns_left; } cpu->cc->tcg_ops->restore_state_to_opc(cpu, tb, data); @@ -302,7 +316,6 @@ int cpu_restore_state_from_tb(CPUState *cpu, TranslationBlock *tb, prof->restore_time + profile_getclock() - ti); qatomic_set(&prof->restore_count, prof->restore_count + 1); #endif - return 0; } bool cpu_restore_state(CPUState *cpu, uintptr_t host_pc, bool will_exit) @@ -335,6 +348,17 @@ bool cpu_restore_state(CPUState *cpu, uintptr_t host_pc, bool will_exit) return false; } +bool cpu_unwind_state_data(CPUState *cpu, uintptr_t host_pc, uint64_t *data) +{ + if (in_code_gen_buffer((const void *)(host_pc - tcg_splitwx_diff))) { + TranslationBlock *tb = tcg_tb_lookup(host_pc); + if (tb) { + return cpu_unwind_data_from_tb(tb, host_pc, data) >= 0; + } + } + return false; +} + void page_init(void) { page_size_init(); -- 2.34.1 ^ permalink raw reply related [flat|nested] 17+ messages in thread
* Re: [PATCH v2 1/6] accel/tcg: Introduce cpu_unwind_state_data 2022-10-27 10:02 ` [PATCH v2 1/6] accel/tcg: Introduce cpu_unwind_state_data Richard Henderson @ 2022-10-27 10:40 ` Claudio Fontana 2022-10-27 11:30 ` Richard Henderson 0 siblings, 1 reply; 17+ messages in thread From: Claudio Fontana @ 2022-10-27 10:40 UTC (permalink / raw) To: Richard Henderson, qemu-devel On 10/27/22 12:02, Richard Henderson wrote: > Add a way to examine the unwind data without actually > restoring the data back into env. > > Signed-off-by: Richard Henderson <richard.henderson@linaro.org> > --- > accel/tcg/internal.h | 4 +-- > include/exec/exec-all.h | 21 ++++++++--- > accel/tcg/translate-all.c | 74 ++++++++++++++++++++++++++------------- > 3 files changed, 68 insertions(+), 31 deletions(-) > > diff --git a/accel/tcg/internal.h b/accel/tcg/internal.h > index 1227bb69bd..9c06b320b7 100644 > --- a/accel/tcg/internal.h > +++ b/accel/tcg/internal.h > @@ -106,8 +106,8 @@ void tb_reset_jump(TranslationBlock *tb, int n); > TranslationBlock *tb_link_page(TranslationBlock *tb, tb_page_addr_t phys_pc, > tb_page_addr_t phys_page2); > bool tb_invalidate_phys_page_unwind(tb_page_addr_t addr, uintptr_t pc); > -int cpu_restore_state_from_tb(CPUState *cpu, TranslationBlock *tb, > - uintptr_t searched_pc, bool reset_icount); > +void cpu_restore_state_from_tb(CPUState *cpu, TranslationBlock *tb, > + uintptr_t host_pc, bool reset_icount); > > /* Return the current PC from CPU, which may be cached in TB. */ > static inline target_ulong log_pc(CPUState *cpu, const TranslationBlock *tb) > diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h > index e948992a80..7d851f5907 100644 > --- a/include/exec/exec-all.h > +++ b/include/exec/exec-all.h > @@ -39,20 +39,33 @@ typedef ram_addr_t tb_page_addr_t; > #define TB_PAGE_ADDR_FMT RAM_ADDR_FMT > #endif > > +/** > + * cpu_unwind_state_data: > + * @cpu: the cpu context > + * @host_pc: the host pc within the translation > + * @data: output data > + * > + * Attempt to load the the unwind state for a host pc occurring in > + * translated code. If @host_pc is not in translated code, the > + * function returns false; otherwise @data is loaded. > + * This is the same unwind info as given to restore_state_to_opc. > + */ > +bool cpu_unwind_state_data(CPUState *cpu, uintptr_t host_pc, uint64_t *data); > + > /** > * cpu_restore_state: > - * @cpu: the vCPU state is to be restore to > - * @searched_pc: the host PC the fault occurred at > + * @cpu: the cpu context > + * @host_pc: the host pc within the translation > * @will_exit: true if the TB executed will be interrupted after some > cpu adjustments. Required for maintaining the correct > icount valus > * @return: true if state was restored, false otherwise > * > * Attempt to restore the state for a fault occurring in translated > - * code. If the searched_pc is not in translated code no state is > + * code. If @host_pc is not in translated code no state is > * restored and the function returns false. > */ > -bool cpu_restore_state(CPUState *cpu, uintptr_t searched_pc, bool will_exit); > +bool cpu_restore_state(CPUState *cpu, uintptr_t host_pc, bool will_exit); > > G_NORETURN void cpu_loop_exit_noexc(CPUState *cpu); > G_NORETURN void cpu_loop_exit(CPUState *cpu); > diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c > index f185356a36..319becb698 100644 > --- a/accel/tcg/translate-all.c > +++ b/accel/tcg/translate-all.c > @@ -247,52 +247,66 @@ static int encode_search(TranslationBlock *tb, uint8_t *block) > return p - block; > } > > -/* The cpu state corresponding to 'searched_pc' is restored. > - * When reset_icount is true, current TB will be interrupted and > - * icount should be recalculated. > - */ > -int cpu_restore_state_from_tb(CPUState *cpu, TranslationBlock *tb, > - uintptr_t searched_pc, bool reset_icount) Maybe add a small comment about what the return value of this static function means? It can be indirectly inferred from its point of use: + int insns_left = cpu_unwind_data_from_tb(tb, host_pc, data); But I find having the information about the meaning of a function and return value useful to be available there. IIUC for external functions the standard way is to document in the header files, but for the static functions I would think we can do it here. With that Reviewed-by: Claudio Fontana <cfontana@suse.de> > +static int cpu_unwind_data_from_tb(TranslationBlock *tb, uintptr_t host_pc, > + uint64_t *data) > { > - uint64_t data[TARGET_INSN_START_WORDS]; > - uintptr_t host_pc = (uintptr_t)tb->tc.ptr; > + uintptr_t iter_pc = (uintptr_t)tb->tc.ptr; > const uint8_t *p = tb->tc.ptr + tb->tc.size; > int i, j, num_insns = tb->icount; > -#ifdef CONFIG_PROFILER > - TCGProfile *prof = &tcg_ctx->prof; > - int64_t ti = profile_getclock(); > -#endif > > - searched_pc -= GETPC_ADJ; > + host_pc -= GETPC_ADJ; > > - if (searched_pc < host_pc) { > + if (host_pc < iter_pc) { > return -1; > } > > - memset(data, 0, sizeof(data)); > + memset(data, 0, sizeof(uint64_t) * TARGET_INSN_START_WORDS); > if (!TARGET_TB_PCREL) { > data[0] = tb_pc(tb); > } > > - /* Reconstruct the stored insn data while looking for the point at > - which the end of the insn exceeds the searched_pc. */ > + /* > + * Reconstruct the stored insn data while looking for the point > + * at which the end of the insn exceeds host_pc. > + */ > for (i = 0; i < num_insns; ++i) { > for (j = 0; j < TARGET_INSN_START_WORDS; ++j) { > data[j] += decode_sleb128(&p); > } > - host_pc += decode_sleb128(&p); > - if (host_pc > searched_pc) { > - goto found; > + iter_pc += decode_sleb128(&p); > + if (iter_pc > host_pc) { > + return num_insns - i; > } > } > return -1; > +} > + > +/* > + * The cpu state corresponding to 'host_pc' is restored. > + * When reset_icount is true, current TB will be interrupted and > + * icount should be recalculated. > + */ > +void cpu_restore_state_from_tb(CPUState *cpu, TranslationBlock *tb, > + uintptr_t host_pc, bool reset_icount) > +{ > + uint64_t data[TARGET_INSN_START_WORDS]; > +#ifdef CONFIG_PROFILER > + TCGProfile *prof = &tcg_ctx->prof; > + int64_t ti = profile_getclock(); > +#endif > + int insns_left = cpu_unwind_data_from_tb(tb, host_pc, data); > + > + if (insns_left < 0) { > + return; > + } > > - found: > if (reset_icount && (tb_cflags(tb) & CF_USE_ICOUNT)) { > assert(icount_enabled()); > - /* Reset the cycle counter to the start of the block > - and shift if to the number of actually executed instructions */ > - cpu_neg(cpu)->icount_decr.u16.low += num_insns - i; > + /* > + * Reset the cycle counter to the start of the block and > + * shift if to the number of actually executed instructions. > + */ > + cpu_neg(cpu)->icount_decr.u16.low += insns_left; > } > > cpu->cc->tcg_ops->restore_state_to_opc(cpu, tb, data); > @@ -302,7 +316,6 @@ int cpu_restore_state_from_tb(CPUState *cpu, TranslationBlock *tb, > prof->restore_time + profile_getclock() - ti); > qatomic_set(&prof->restore_count, prof->restore_count + 1); > #endif > - return 0; > } > > bool cpu_restore_state(CPUState *cpu, uintptr_t host_pc, bool will_exit) > @@ -335,6 +348,17 @@ bool cpu_restore_state(CPUState *cpu, uintptr_t host_pc, bool will_exit) > return false; > } > > +bool cpu_unwind_state_data(CPUState *cpu, uintptr_t host_pc, uint64_t *data) > +{ > + if (in_code_gen_buffer((const void *)(host_pc - tcg_splitwx_diff))) { > + TranslationBlock *tb = tcg_tb_lookup(host_pc); > + if (tb) { > + return cpu_unwind_data_from_tb(tb, host_pc, data) >= 0; > + } > + } > + return false; > +} > + > void page_init(void) > { > page_size_init(); ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH v2 1/6] accel/tcg: Introduce cpu_unwind_state_data 2022-10-27 10:40 ` Claudio Fontana @ 2022-10-27 11:30 ` Richard Henderson 2022-10-27 11:39 ` Claudio Fontana 0 siblings, 1 reply; 17+ messages in thread From: Richard Henderson @ 2022-10-27 11:30 UTC (permalink / raw) To: Claudio Fontana, qemu-devel On 10/27/22 20:40, Claudio Fontana wrote: > On 10/27/22 12:02, Richard Henderson wrote: >> Add a way to examine the unwind data without actually >> restoring the data back into env. >> >> Signed-off-by: Richard Henderson <richard.henderson@linaro.org> >> --- >> accel/tcg/internal.h | 4 +-- >> include/exec/exec-all.h | 21 ++++++++--- >> accel/tcg/translate-all.c | 74 ++++++++++++++++++++++++++------------- >> 3 files changed, 68 insertions(+), 31 deletions(-) >> >> diff --git a/accel/tcg/internal.h b/accel/tcg/internal.h >> index 1227bb69bd..9c06b320b7 100644 >> --- a/accel/tcg/internal.h >> +++ b/accel/tcg/internal.h >> @@ -106,8 +106,8 @@ void tb_reset_jump(TranslationBlock *tb, int n); >> TranslationBlock *tb_link_page(TranslationBlock *tb, tb_page_addr_t phys_pc, >> tb_page_addr_t phys_page2); >> bool tb_invalidate_phys_page_unwind(tb_page_addr_t addr, uintptr_t pc); >> -int cpu_restore_state_from_tb(CPUState *cpu, TranslationBlock *tb, >> - uintptr_t searched_pc, bool reset_icount); >> +void cpu_restore_state_from_tb(CPUState *cpu, TranslationBlock *tb, >> + uintptr_t host_pc, bool reset_icount); >> >> /* Return the current PC from CPU, which may be cached in TB. */ >> static inline target_ulong log_pc(CPUState *cpu, const TranslationBlock *tb) >> diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h >> index e948992a80..7d851f5907 100644 >> --- a/include/exec/exec-all.h >> +++ b/include/exec/exec-all.h >> @@ -39,20 +39,33 @@ typedef ram_addr_t tb_page_addr_t; >> #define TB_PAGE_ADDR_FMT RAM_ADDR_FMT >> #endif >> >> +/** >> + * cpu_unwind_state_data: >> + * @cpu: the cpu context >> + * @host_pc: the host pc within the translation >> + * @data: output data >> + * >> + * Attempt to load the the unwind state for a host pc occurring in >> + * translated code. If @host_pc is not in translated code, the >> + * function returns false; otherwise @data is loaded. >> + * This is the same unwind info as given to restore_state_to_opc. >> + */ >> +bool cpu_unwind_state_data(CPUState *cpu, uintptr_t host_pc, uint64_t *data); >> + >> /** >> * cpu_restore_state: >> - * @cpu: the vCPU state is to be restore to >> - * @searched_pc: the host PC the fault occurred at >> + * @cpu: the cpu context >> + * @host_pc: the host pc within the translation >> * @will_exit: true if the TB executed will be interrupted after some >> cpu adjustments. Required for maintaining the correct >> icount valus >> * @return: true if state was restored, false otherwise >> * >> * Attempt to restore the state for a fault occurring in translated >> - * code. If the searched_pc is not in translated code no state is >> + * code. If @host_pc is not in translated code no state is >> * restored and the function returns false. >> */ >> -bool cpu_restore_state(CPUState *cpu, uintptr_t searched_pc, bool will_exit); >> +bool cpu_restore_state(CPUState *cpu, uintptr_t host_pc, bool will_exit); >> >> G_NORETURN void cpu_loop_exit_noexc(CPUState *cpu); >> G_NORETURN void cpu_loop_exit(CPUState *cpu); >> diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c >> index f185356a36..319becb698 100644 >> --- a/accel/tcg/translate-all.c >> +++ b/accel/tcg/translate-all.c >> @@ -247,52 +247,66 @@ static int encode_search(TranslationBlock *tb, uint8_t *block) >> return p - block; >> } >> >> -/* The cpu state corresponding to 'searched_pc' is restored. >> - * When reset_icount is true, current TB will be interrupted and >> - * icount should be recalculated. >> - */ >> -int cpu_restore_state_from_tb(CPUState *cpu, TranslationBlock *tb, >> - uintptr_t searched_pc, bool reset_icount) > > > Maybe add a small comment about what the return value of this static function means? > It can be indirectly inferred from its point of use: > > + int insns_left = cpu_unwind_data_from_tb(tb, host_pc, data); > > But I find having the information about the meaning of a function and return value useful to be available there. > > IIUC for external functions the standard way is to document in the header files, but for the static functions I would think we can do it here. > > With that Reviewed-by: Claudio Fontana <cfontana@suse.de> I added +/** + * cpu_unwind_data_from_tb: Load unwind data for TB + * @tb: translation block + * @host_pc: the host pc within translation + * @data: output array + * + * Within @tb, locate the guest insn whose translation contains @host_pc, + * then load the unwind data created by INDEX_opc_start_insn for that + * guest insn. Return the number of guest insns which remain un-executed + * within @tb -- these must be credited back to the cpu's icount budget. + * + * If we could not determine which guest insn to which @host_pc belongs, + * return -1 and do not load unwind data. + * FIXME: Such a failure is likely to break the guest, as we were not + * expecting to unwind from such a location. This may be some sort of + * backend code generation problem. Consider asserting instead. */ Which I think captures some of your v1 comments as well. r~ ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH v2 1/6] accel/tcg: Introduce cpu_unwind_state_data 2022-10-27 11:30 ` Richard Henderson @ 2022-10-27 11:39 ` Claudio Fontana 0 siblings, 0 replies; 17+ messages in thread From: Claudio Fontana @ 2022-10-27 11:39 UTC (permalink / raw) To: Richard Henderson, qemu-devel On 10/27/22 13:30, Richard Henderson wrote: > On 10/27/22 20:40, Claudio Fontana wrote: >> On 10/27/22 12:02, Richard Henderson wrote: >>> Add a way to examine the unwind data without actually >>> restoring the data back into env. >>> >>> Signed-off-by: Richard Henderson <richard.henderson@linaro.org> >>> --- >>> accel/tcg/internal.h | 4 +-- >>> include/exec/exec-all.h | 21 ++++++++--- >>> accel/tcg/translate-all.c | 74 ++++++++++++++++++++++++++------------- >>> 3 files changed, 68 insertions(+), 31 deletions(-) >>> >>> diff --git a/accel/tcg/internal.h b/accel/tcg/internal.h >>> index 1227bb69bd..9c06b320b7 100644 >>> --- a/accel/tcg/internal.h >>> +++ b/accel/tcg/internal.h >>> @@ -106,8 +106,8 @@ void tb_reset_jump(TranslationBlock *tb, int n); >>> TranslationBlock *tb_link_page(TranslationBlock *tb, tb_page_addr_t phys_pc, >>> tb_page_addr_t phys_page2); >>> bool tb_invalidate_phys_page_unwind(tb_page_addr_t addr, uintptr_t pc); >>> -int cpu_restore_state_from_tb(CPUState *cpu, TranslationBlock *tb, >>> - uintptr_t searched_pc, bool reset_icount); >>> +void cpu_restore_state_from_tb(CPUState *cpu, TranslationBlock *tb, >>> + uintptr_t host_pc, bool reset_icount); >>> >>> /* Return the current PC from CPU, which may be cached in TB. */ >>> static inline target_ulong log_pc(CPUState *cpu, const TranslationBlock *tb) >>> diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h >>> index e948992a80..7d851f5907 100644 >>> --- a/include/exec/exec-all.h >>> +++ b/include/exec/exec-all.h >>> @@ -39,20 +39,33 @@ typedef ram_addr_t tb_page_addr_t; >>> #define TB_PAGE_ADDR_FMT RAM_ADDR_FMT >>> #endif >>> >>> +/** >>> + * cpu_unwind_state_data: >>> + * @cpu: the cpu context >>> + * @host_pc: the host pc within the translation >>> + * @data: output data >>> + * >>> + * Attempt to load the the unwind state for a host pc occurring in >>> + * translated code. If @host_pc is not in translated code, the >>> + * function returns false; otherwise @data is loaded. >>> + * This is the same unwind info as given to restore_state_to_opc. >>> + */ >>> +bool cpu_unwind_state_data(CPUState *cpu, uintptr_t host_pc, uint64_t *data); >>> + >>> /** >>> * cpu_restore_state: >>> - * @cpu: the vCPU state is to be restore to >>> - * @searched_pc: the host PC the fault occurred at >>> + * @cpu: the cpu context >>> + * @host_pc: the host pc within the translation >>> * @will_exit: true if the TB executed will be interrupted after some >>> cpu adjustments. Required for maintaining the correct >>> icount valus >>> * @return: true if state was restored, false otherwise >>> * >>> * Attempt to restore the state for a fault occurring in translated >>> - * code. If the searched_pc is not in translated code no state is >>> + * code. If @host_pc is not in translated code no state is >>> * restored and the function returns false. >>> */ >>> -bool cpu_restore_state(CPUState *cpu, uintptr_t searched_pc, bool will_exit); >>> +bool cpu_restore_state(CPUState *cpu, uintptr_t host_pc, bool will_exit); >>> >>> G_NORETURN void cpu_loop_exit_noexc(CPUState *cpu); >>> G_NORETURN void cpu_loop_exit(CPUState *cpu); >>> diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c >>> index f185356a36..319becb698 100644 >>> --- a/accel/tcg/translate-all.c >>> +++ b/accel/tcg/translate-all.c >>> @@ -247,52 +247,66 @@ static int encode_search(TranslationBlock *tb, uint8_t *block) >>> return p - block; >>> } >>> >>> -/* The cpu state corresponding to 'searched_pc' is restored. >>> - * When reset_icount is true, current TB will be interrupted and >>> - * icount should be recalculated. >>> - */ >>> -int cpu_restore_state_from_tb(CPUState *cpu, TranslationBlock *tb, >>> - uintptr_t searched_pc, bool reset_icount) >> >> >> Maybe add a small comment about what the return value of this static function means? >> It can be indirectly inferred from its point of use: >> >> + int insns_left = cpu_unwind_data_from_tb(tb, host_pc, data); >> >> But I find having the information about the meaning of a function and return value useful to be available there. >> >> IIUC for external functions the standard way is to document in the header files, but for the static functions I would think we can do it here. >> >> With that Reviewed-by: Claudio Fontana <cfontana@suse.de> > > > I added > > +/** > + * cpu_unwind_data_from_tb: Load unwind data for TB > + * @tb: translation block > + * @host_pc: the host pc within translation > + * @data: output array > + * > + * Within @tb, locate the guest insn whose translation contains @host_pc, > + * then load the unwind data created by INDEX_opc_start_insn for that > + * guest insn. Return the number of guest insns which remain un-executed > + * within @tb -- these must be credited back to the cpu's icount budget. > + * > + * If we could not determine which guest insn to which @host_pc belongs, > + * return -1 and do not load unwind data. > + * FIXME: Such a failure is likely to break the guest, as we were not > + * expecting to unwind from such a location. This may be some sort of > + * backend code generation problem. Consider asserting instead. > */ > > Which I think captures some of your v1 comments as well. > > > r~ > Very clear thanks, Reviewed-by: Claudio Fontana <cfontana@suse.de> ^ permalink raw reply [flat|nested] 17+ messages in thread
* [PATCH v2 2/6] target/i386: Use cpu_unwind_state_data for tpr access 2022-10-27 10:02 [PATCH v2 0/6] tcg: Fix x86 TARGET_TB_PCREL (#1269) Richard Henderson 2022-10-27 10:02 ` [PATCH v2 1/6] accel/tcg: Introduce cpu_unwind_state_data Richard Henderson @ 2022-10-27 10:02 ` Richard Henderson 2022-10-27 12:22 ` Claudio Fontana 2022-10-27 10:02 ` [PATCH v2 3/6] target/openrisc: Always exit after mtspr npc Richard Henderson ` (4 subsequent siblings) 6 siblings, 1 reply; 17+ messages in thread From: Richard Henderson @ 2022-10-27 10:02 UTC (permalink / raw) To: qemu-devel; +Cc: cfontana Avoid cpu_restore_state, and modifying env->eip out from underneath the translator with TARGET_TB_PCREL. There is some slight duplication from x86_restore_state_to_opc, but it's just a few lines. Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1269 Signed-off-by: Richard Henderson <richard.henderson@linaro.org> --- target/i386/helper.c | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/target/i386/helper.c b/target/i386/helper.c index b62a1e48e2..2cd1756f1a 100644 --- a/target/i386/helper.c +++ b/target/i386/helper.c @@ -509,6 +509,23 @@ void cpu_x86_inject_mce(Monitor *mon, X86CPU *cpu, int bank, } } +static target_ulong get_memio_eip(CPUX86State *env) +{ + uint64_t data[TARGET_INSN_START_WORDS]; + CPUState *cs = env_cpu(env); + + if (!cpu_unwind_state_data(cs, cs->mem_io_pc, data)) { + return env->eip; + } + + /* Per x86_restore_state_to_opc. */ + if (TARGET_TB_PCREL) { + return (env->eip & TARGET_PAGE_MASK) | data[0]; + } else { + return data[0] - env->segs[R_CS].base; + } +} + void cpu_report_tpr_access(CPUX86State *env, TPRAccess access) { X86CPU *cpu = env_archcpu(env); @@ -519,9 +536,9 @@ void cpu_report_tpr_access(CPUX86State *env, TPRAccess access) cpu_interrupt(cs, CPU_INTERRUPT_TPR); } else if (tcg_enabled()) { - cpu_restore_state(cs, cs->mem_io_pc, false); + target_ulong eip = get_memio_eip(env); - apic_handle_tpr_access_report(cpu->apic_state, env->eip, access); + apic_handle_tpr_access_report(cpu->apic_state, eip, access); } } #endif /* !CONFIG_USER_ONLY */ -- 2.34.1 ^ permalink raw reply related [flat|nested] 17+ messages in thread
* Re: [PATCH v2 2/6] target/i386: Use cpu_unwind_state_data for tpr access 2022-10-27 10:02 ` [PATCH v2 2/6] target/i386: Use cpu_unwind_state_data for tpr access Richard Henderson @ 2022-10-27 12:22 ` Claudio Fontana 2022-10-27 20:13 ` Richard Henderson 0 siblings, 1 reply; 17+ messages in thread From: Claudio Fontana @ 2022-10-27 12:22 UTC (permalink / raw) To: Richard Henderson, qemu-devel On 10/27/22 12:02, Richard Henderson wrote: > Avoid cpu_restore_state, and modifying env->eip out from > underneath the translator with TARGET_TB_PCREL. There is > some slight duplication from x86_restore_state_to_opc, > but it's just a few lines. > > Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1269 > Signed-off-by: Richard Henderson <richard.henderson@linaro.org> > --- > target/i386/helper.c | 21 +++++++++++++++++++-- > 1 file changed, 19 insertions(+), 2 deletions(-) > > diff --git a/target/i386/helper.c b/target/i386/helper.c > index b62a1e48e2..2cd1756f1a 100644 > --- a/target/i386/helper.c > +++ b/target/i386/helper.c > @@ -509,6 +509,23 @@ void cpu_x86_inject_mce(Monitor *mon, X86CPU *cpu, int bank, > } > } > > +static target_ulong get_memio_eip(CPUX86State *env) > +{ > + uint64_t data[TARGET_INSN_START_WORDS]; > + CPUState *cs = env_cpu(env); > + > + if (!cpu_unwind_state_data(cs, cs->mem_io_pc, data)) { > + return env->eip; > + } > + > + /* Per x86_restore_state_to_opc. */ > + if (TARGET_TB_PCREL) { > + return (env->eip & TARGET_PAGE_MASK) | data[0]; > + } else { > + return data[0] - env->segs[R_CS].base; here we switch from taking cs_base from the TranslationBlock to taking it from env-> . I traced the tb->cs_base use back to cpu_exec() and cpu_exec_step_atomic() and from there it seems ok, as the sequence is cpu_get_tb_cpu_state(cpu->env_ptr, &pc, &cs_base, &flags), which gets it from env, followed by tb_gen_code(...cs_base) which sets the TranslationBlock cs_base, and tb->cs_base does not seem to change again. I mention this in the case there can be some weird situation in which env and tb can end up not being consistent, does a TranslationBlock that is initialized with a certain cs_base from the env that contains user code to load / change the CS segment base potentially constitute a problem? Ciao, Claudio > + } > +} > + > void cpu_report_tpr_access(CPUX86State *env, TPRAccess access) > { > X86CPU *cpu = env_archcpu(env); > @@ -519,9 +536,9 @@ void cpu_report_tpr_access(CPUX86State *env, TPRAccess access) > > cpu_interrupt(cs, CPU_INTERRUPT_TPR); > } else if (tcg_enabled()) { > - cpu_restore_state(cs, cs->mem_io_pc, false); > + target_ulong eip = get_memio_eip(env); > > - apic_handle_tpr_access_report(cpu->apic_state, env->eip, access); > + apic_handle_tpr_access_report(cpu->apic_state, eip, access); > } > } > #endif /* !CONFIG_USER_ONLY */ ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH v2 2/6] target/i386: Use cpu_unwind_state_data for tpr access 2022-10-27 12:22 ` Claudio Fontana @ 2022-10-27 20:13 ` Richard Henderson 2022-10-28 8:10 ` Claudio Fontana 0 siblings, 1 reply; 17+ messages in thread From: Richard Henderson @ 2022-10-27 20:13 UTC (permalink / raw) To: Claudio Fontana, qemu-devel On 10/27/22 22:22, Claudio Fontana wrote: > On 10/27/22 12:02, Richard Henderson wrote: >> + /* Per x86_restore_state_to_opc. */ >> + if (TARGET_TB_PCREL) { >> + return (env->eip & TARGET_PAGE_MASK) | data[0]; >> + } else { >> + return data[0] - env->segs[R_CS].base; > > here we switch from taking cs_base from the TranslationBlock to taking it from env-> . > > I traced the tb->cs_base use back to > > cpu_exec() and cpu_exec_step_atomic() > > and from there it seems ok, as the sequence is > > cpu_get_tb_cpu_state(cpu->env_ptr, &pc, &cs_base, &flags), which gets it from env, > > followed by > > tb_gen_code(...cs_base) which sets the TranslationBlock cs_base, and tb->cs_base does > not seem to change again. Correct. I wondered if I'd made a mistake by not returning the TB located during the search, but it doesn't seem to have mattered for the two users. > I mention this in the case there can be some weird situation in which env and tb can > end up not being consistent, does a TranslationBlock that is initialized with a certain > cs_base from the env that contains user code to load / change the CS segment base > potentially constitute a problem? The only way to load/change a CS segment base is a branch instruction, which will of course end the TB. There should be no way to change CS that continues the TB. r~ ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH v2 2/6] target/i386: Use cpu_unwind_state_data for tpr access 2022-10-27 20:13 ` Richard Henderson @ 2022-10-28 8:10 ` Claudio Fontana 0 siblings, 0 replies; 17+ messages in thread From: Claudio Fontana @ 2022-10-28 8:10 UTC (permalink / raw) To: Richard Henderson, qemu-devel On 10/27/22 22:13, Richard Henderson wrote: > On 10/27/22 22:22, Claudio Fontana wrote: >> On 10/27/22 12:02, Richard Henderson wrote: >>> + /* Per x86_restore_state_to_opc. */ >>> + if (TARGET_TB_PCREL) { >>> + return (env->eip & TARGET_PAGE_MASK) | data[0]; >>> + } else { >>> + return data[0] - env->segs[R_CS].base; >> >> here we switch from taking cs_base from the TranslationBlock to taking it from env-> . >> >> I traced the tb->cs_base use back to >> >> cpu_exec() and cpu_exec_step_atomic() >> >> and from there it seems ok, as the sequence is >> >> cpu_get_tb_cpu_state(cpu->env_ptr, &pc, &cs_base, &flags), which gets it from env, >> >> followed by >> >> tb_gen_code(...cs_base) which sets the TranslationBlock cs_base, and tb->cs_base does >> not seem to change again. > Correct. I wondered if I'd made a mistake by not returning the TB located during the > search, but it doesn't seem to have mattered for the two users. > >> I mention this in the case there can be some weird situation in which env and tb can >> end up not being consistent, does a TranslationBlock that is initialized with a certain >> cs_base from the env that contains user code to load / change the CS segment base >> potentially constitute a problem? > The only way to load/change a CS segment base is a branch instruction, which will of > course end the TB. There should be no way to change CS that continues the TB. > > > r~ Reviewed-by: Claudio Fontana <cfontana@suse.de> ^ permalink raw reply [flat|nested] 17+ messages in thread
* [PATCH v2 3/6] target/openrisc: Always exit after mtspr npc 2022-10-27 10:02 [PATCH v2 0/6] tcg: Fix x86 TARGET_TB_PCREL (#1269) Richard Henderson 2022-10-27 10:02 ` [PATCH v2 1/6] accel/tcg: Introduce cpu_unwind_state_data Richard Henderson 2022-10-27 10:02 ` [PATCH v2 2/6] target/i386: Use cpu_unwind_state_data for tpr access Richard Henderson @ 2022-10-27 10:02 ` Richard Henderson 2022-10-27 10:49 ` Philippe Mathieu-Daudé 2022-10-27 10:02 ` [PATCH v2 4/6] target/openrisc: Use cpu_unwind_state_data for mfspr Richard Henderson ` (3 subsequent siblings) 6 siblings, 1 reply; 17+ messages in thread From: Richard Henderson @ 2022-10-27 10:02 UTC (permalink / raw) To: qemu-devel; +Cc: cfontana We have called cpu_restore_state asserting will_exit. Do not go back on that promise. This affects icount. Signed-off-by: Richard Henderson <richard.henderson@linaro.org> --- target/openrisc/sys_helper.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/target/openrisc/sys_helper.c b/target/openrisc/sys_helper.c index 09b3c97d7c..a3508e421d 100644 --- a/target/openrisc/sys_helper.c +++ b/target/openrisc/sys_helper.c @@ -51,8 +51,8 @@ void HELPER(mtspr)(CPUOpenRISCState *env, target_ulong spr, target_ulong rb) if (env->pc != rb) { env->pc = rb; env->dflag = 0; - cpu_loop_exit(cs); } + cpu_loop_exit(cs); break; case TO_SPR(0, 17): /* SR */ -- 2.34.1 ^ permalink raw reply related [flat|nested] 17+ messages in thread
* Re: [PATCH v2 3/6] target/openrisc: Always exit after mtspr npc 2022-10-27 10:02 ` [PATCH v2 3/6] target/openrisc: Always exit after mtspr npc Richard Henderson @ 2022-10-27 10:49 ` Philippe Mathieu-Daudé 0 siblings, 0 replies; 17+ messages in thread From: Philippe Mathieu-Daudé @ 2022-10-27 10:49 UTC (permalink / raw) To: Richard Henderson, qemu-devel; +Cc: cfontana On 27/10/22 12:02, Richard Henderson wrote: > We have called cpu_restore_state asserting will_exit. > Do not go back on that promise. This affects icount. > > Signed-off-by: Richard Henderson <richard.henderson@linaro.org> > --- > target/openrisc/sys_helper.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> ^ permalink raw reply [flat|nested] 17+ messages in thread
* [PATCH v2 4/6] target/openrisc: Use cpu_unwind_state_data for mfspr 2022-10-27 10:02 [PATCH v2 0/6] tcg: Fix x86 TARGET_TB_PCREL (#1269) Richard Henderson ` (2 preceding siblings ...) 2022-10-27 10:02 ` [PATCH v2 3/6] target/openrisc: Always exit after mtspr npc Richard Henderson @ 2022-10-27 10:02 ` Richard Henderson 2022-10-28 9:16 ` Claudio Fontana 2022-10-27 10:02 ` [PATCH v2 5/6] accel/tcg: Remove will_exit argument from cpu_restore_state Richard Henderson ` (2 subsequent siblings) 6 siblings, 1 reply; 17+ messages in thread From: Richard Henderson @ 2022-10-27 10:02 UTC (permalink / raw) To: qemu-devel; +Cc: cfontana Since we do not plan to exit, use cpu_unwind_state_data and extract exactly the data requested. Signed-off-by: Richard Henderson <richard.henderson@linaro.org> --- target/openrisc/sys_helper.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/target/openrisc/sys_helper.c b/target/openrisc/sys_helper.c index a3508e421d..dde2fa1623 100644 --- a/target/openrisc/sys_helper.c +++ b/target/openrisc/sys_helper.c @@ -199,6 +199,7 @@ target_ulong HELPER(mfspr)(CPUOpenRISCState *env, target_ulong rd, target_ulong spr) { #ifndef CONFIG_USER_ONLY + uint64_t data[TARGET_INSN_START_WORDS]; MachineState *ms = MACHINE(qdev_get_machine()); OpenRISCCPU *cpu = env_archcpu(env); CPUState *cs = env_cpu(env); @@ -232,14 +233,20 @@ target_ulong HELPER(mfspr)(CPUOpenRISCState *env, target_ulong rd, return env->evbar; case TO_SPR(0, 16): /* NPC (equals PC) */ - cpu_restore_state(cs, GETPC(), false); + if (cpu_unwind_state_data(cs, GETPC(), data)) { + return data[0]; + } return env->pc; case TO_SPR(0, 17): /* SR */ return cpu_get_sr(env); case TO_SPR(0, 18): /* PPC */ - cpu_restore_state(cs, GETPC(), false); + if (cpu_unwind_state_data(cs, GETPC(), data)) { + if (data[1] & 2) { + return data[0] - 4; + } + } return env->ppc; case TO_SPR(0, 32): /* EPCR */ -- 2.34.1 ^ permalink raw reply related [flat|nested] 17+ messages in thread
* Re: [PATCH v2 4/6] target/openrisc: Use cpu_unwind_state_data for mfspr 2022-10-27 10:02 ` [PATCH v2 4/6] target/openrisc: Use cpu_unwind_state_data for mfspr Richard Henderson @ 2022-10-28 9:16 ` Claudio Fontana 2022-10-28 18:46 ` Richard Henderson 0 siblings, 1 reply; 17+ messages in thread From: Claudio Fontana @ 2022-10-28 9:16 UTC (permalink / raw) To: Richard Henderson, Philippe Mathieu-Daudé; +Cc: qemu-devel On 10/27/22 12:02, Richard Henderson wrote: > Since we do not plan to exit, use cpu_unwind_state_data > and extract exactly the data requested. > > Signed-off-by: Richard Henderson <richard.henderson@linaro.org> > --- > target/openrisc/sys_helper.c | 11 +++++++++-- > 1 file changed, 9 insertions(+), 2 deletions(-) > > diff --git a/target/openrisc/sys_helper.c b/target/openrisc/sys_helper.c > index a3508e421d..dde2fa1623 100644 > --- a/target/openrisc/sys_helper.c > +++ b/target/openrisc/sys_helper.c > @@ -199,6 +199,7 @@ target_ulong HELPER(mfspr)(CPUOpenRISCState *env, target_ulong rd, > target_ulong spr) > { > #ifndef CONFIG_USER_ONLY > + uint64_t data[TARGET_INSN_START_WORDS]; > MachineState *ms = MACHINE(qdev_get_machine()); > OpenRISCCPU *cpu = env_archcpu(env); > CPUState *cs = env_cpu(env); > @@ -232,14 +233,20 @@ target_ulong HELPER(mfspr)(CPUOpenRISCState *env, target_ulong rd, > return env->evbar; > > case TO_SPR(0, 16): /* NPC (equals PC) */ > - cpu_restore_state(cs, GETPC(), false); > + if (cpu_unwind_state_data(cs, GETPC(), data)) { > + return data[0]; > + } > return env->pc; > > case TO_SPR(0, 17): /* SR */ > return cpu_get_sr(env); > > case TO_SPR(0, 18): /* PPC */ > - cpu_restore_state(cs, GETPC(), false); > + if (cpu_unwind_state_data(cs, GETPC(), data)) { > + if (data[1] & 2) { > + return data[0] - 4; > + } > + } > return env->ppc; > > case TO_SPR(0, 32): /* EPCR */ I am struggling to understand if the fact that we are not setting cpu->env.dflag anymore in the mfspr helper is fine; here I am unfamiliar with the arch, also Ccing Philippe in case he wants to step in to review this bit. Thanks, CLaudio ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH v2 4/6] target/openrisc: Use cpu_unwind_state_data for mfspr 2022-10-28 9:16 ` Claudio Fontana @ 2022-10-28 18:46 ` Richard Henderson 0 siblings, 0 replies; 17+ messages in thread From: Richard Henderson @ 2022-10-28 18:46 UTC (permalink / raw) To: Claudio Fontana, Philippe Mathieu-Daudé; +Cc: qemu-devel, Stafford Horne On 10/28/22 20:16, Claudio Fontana wrote: > On 10/27/22 12:02, Richard Henderson wrote: >> Since we do not plan to exit, use cpu_unwind_state_data >> and extract exactly the data requested. >> >> Signed-off-by: Richard Henderson <richard.henderson@linaro.org> >> --- >> target/openrisc/sys_helper.c | 11 +++++++++-- >> 1 file changed, 9 insertions(+), 2 deletions(-) >> >> diff --git a/target/openrisc/sys_helper.c b/target/openrisc/sys_helper.c >> index a3508e421d..dde2fa1623 100644 >> --- a/target/openrisc/sys_helper.c >> +++ b/target/openrisc/sys_helper.c >> @@ -199,6 +199,7 @@ target_ulong HELPER(mfspr)(CPUOpenRISCState *env, target_ulong rd, >> target_ulong spr) >> { >> #ifndef CONFIG_USER_ONLY >> + uint64_t data[TARGET_INSN_START_WORDS]; >> MachineState *ms = MACHINE(qdev_get_machine()); >> OpenRISCCPU *cpu = env_archcpu(env); >> CPUState *cs = env_cpu(env); >> @@ -232,14 +233,20 @@ target_ulong HELPER(mfspr)(CPUOpenRISCState *env, target_ulong rd, >> return env->evbar; >> >> case TO_SPR(0, 16): /* NPC (equals PC) */ >> - cpu_restore_state(cs, GETPC(), false); >> + if (cpu_unwind_state_data(cs, GETPC(), data)) { >> + return data[0]; >> + } >> return env->pc; >> >> case TO_SPR(0, 17): /* SR */ >> return cpu_get_sr(env); >> >> case TO_SPR(0, 18): /* PPC */ >> - cpu_restore_state(cs, GETPC(), false); >> + if (cpu_unwind_state_data(cs, GETPC(), data)) { >> + if (data[1] & 2) { >> + return data[0] - 4; >> + } >> + } >> return env->ppc; >> >> case TO_SPR(0, 32): /* EPCR */ > > I am struggling to understand if the fact that we are not setting cpu->env.dflag anymore in the mfspr helper is fine; That we might do so before was buggy. We manage dflag in openrisc_tr_tb_stop expecting a particular value. I should expand the patch comment on this. Consider: l.j L2 // branch l.mfspr r1, ppc // delay L1: boom L2: l.lwa r3, (r4) With "l.mfspr reg, ppc" executed in a delay slot, dflag would be set, but it would not be cleared by openrisc_tr_tb_stop on exiting the TB, because tb_stop thinks the value is already zero. The next TB begins at L2 with dflag set when it should not. If the load has a tlb miss, then the interrupt will be delivered with DSX set in the status register, and the pc decremented (openrisc implements restart after delay slot by re-executing the branch). This will cause the return from interrupt to go to L1, and boom! r~ ^ permalink raw reply [flat|nested] 17+ messages in thread
* [PATCH v2 5/6] accel/tcg: Remove will_exit argument from cpu_restore_state 2022-10-27 10:02 [PATCH v2 0/6] tcg: Fix x86 TARGET_TB_PCREL (#1269) Richard Henderson ` (3 preceding siblings ...) 2022-10-27 10:02 ` [PATCH v2 4/6] target/openrisc: Use cpu_unwind_state_data for mfspr Richard Henderson @ 2022-10-27 10:02 ` Richard Henderson 2022-10-27 10:02 ` [PATCH v2 6/6] accel/tcg: Remove reset_icount argument from cpu_restore_state_from_tb Richard Henderson 2022-10-31 0:40 ` [PATCH v2 0/6] tcg: Fix x86 TARGET_TB_PCREL (#1269) Richard Henderson 6 siblings, 0 replies; 17+ messages in thread From: Richard Henderson @ 2022-10-27 10:02 UTC (permalink / raw) To: qemu-devel; +Cc: cfontana The value passed is always true, and if the target's synchronize_from_tb hook is non-trivial, not exiting may be erroneous. Reviewed-by: Claudio Fontana <cfontana@suse.de> Signed-off-by: Richard Henderson <richard.henderson@linaro.org> --- include/exec/exec-all.h | 5 +---- accel/tcg/cpu-exec-common.c | 2 +- accel/tcg/translate-all.c | 12 ++---------- target/alpha/helper.c | 2 +- target/alpha/mem_helper.c | 2 +- target/arm/op_helper.c | 2 +- target/arm/tlb_helper.c | 8 ++++---- target/cris/helper.c | 2 +- target/i386/tcg/sysemu/svm_helper.c | 2 +- target/m68k/op_helper.c | 4 ++-- target/microblaze/helper.c | 2 +- target/nios2/op_helper.c | 2 +- target/openrisc/sys_helper.c | 4 ++-- target/ppc/excp_helper.c | 2 +- target/s390x/tcg/excp_helper.c | 2 +- target/tricore/op_helper.c | 2 +- target/xtensa/helper.c | 6 +++--- 17 files changed, 25 insertions(+), 36 deletions(-) diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h index 7d851f5907..9b7bfbf09a 100644 --- a/include/exec/exec-all.h +++ b/include/exec/exec-all.h @@ -56,16 +56,13 @@ bool cpu_unwind_state_data(CPUState *cpu, uintptr_t host_pc, uint64_t *data); * cpu_restore_state: * @cpu: the cpu context * @host_pc: the host pc within the translation - * @will_exit: true if the TB executed will be interrupted after some - cpu adjustments. Required for maintaining the correct - icount valus * @return: true if state was restored, false otherwise * * Attempt to restore the state for a fault occurring in translated * code. If @host_pc is not in translated code no state is * restored and the function returns false. */ -bool cpu_restore_state(CPUState *cpu, uintptr_t host_pc, bool will_exit); +bool cpu_restore_state(CPUState *cpu, uintptr_t host_pc); G_NORETURN void cpu_loop_exit_noexc(CPUState *cpu); G_NORETURN void cpu_loop_exit(CPUState *cpu); diff --git a/accel/tcg/cpu-exec-common.c b/accel/tcg/cpu-exec-common.c index be6fe45aa5..c7bc8c6efa 100644 --- a/accel/tcg/cpu-exec-common.c +++ b/accel/tcg/cpu-exec-common.c @@ -71,7 +71,7 @@ void cpu_loop_exit(CPUState *cpu) void cpu_loop_exit_restore(CPUState *cpu, uintptr_t pc) { if (pc) { - cpu_restore_state(cpu, pc, true); + cpu_restore_state(cpu, pc); } cpu_loop_exit(cpu); } diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c index 319becb698..90997fed47 100644 --- a/accel/tcg/translate-all.c +++ b/accel/tcg/translate-all.c @@ -318,16 +318,8 @@ void cpu_restore_state_from_tb(CPUState *cpu, TranslationBlock *tb, #endif } -bool cpu_restore_state(CPUState *cpu, uintptr_t host_pc, bool will_exit) +bool cpu_restore_state(CPUState *cpu, uintptr_t host_pc) { - /* - * The pc update associated with restore without exit will - * break the relative pc adjustments performed by TARGET_TB_PCREL. - */ - if (TARGET_TB_PCREL) { - assert(will_exit); - } - /* * The host_pc has to be in the rx region of the code buffer. * If it is not we will not be able to resolve it here. @@ -341,7 +333,7 @@ bool cpu_restore_state(CPUState *cpu, uintptr_t host_pc, bool will_exit) if (in_code_gen_buffer((const void *)(host_pc - tcg_splitwx_diff))) { TranslationBlock *tb = tcg_tb_lookup(host_pc); if (tb) { - cpu_restore_state_from_tb(cpu, tb, host_pc, will_exit); + cpu_restore_state_from_tb(cpu, tb, host_pc, true); return true; } } diff --git a/target/alpha/helper.c b/target/alpha/helper.c index a5a389b5a3..970c869771 100644 --- a/target/alpha/helper.c +++ b/target/alpha/helper.c @@ -532,7 +532,7 @@ G_NORETURN void dynamic_excp(CPUAlphaState *env, uintptr_t retaddr, cs->exception_index = excp; env->error_code = error; if (retaddr) { - cpu_restore_state(cs, retaddr, true); + cpu_restore_state(cs, retaddr); /* Floating-point exceptions (our only users) point to the next PC. */ env->pc += 4; } diff --git a/target/alpha/mem_helper.c b/target/alpha/mem_helper.c index 47283a0612..a39b52c5dd 100644 --- a/target/alpha/mem_helper.c +++ b/target/alpha/mem_helper.c @@ -28,7 +28,7 @@ static void do_unaligned_access(CPUAlphaState *env, vaddr addr, uintptr_t retadd uint64_t pc; uint32_t insn; - cpu_restore_state(env_cpu(env), retaddr, true); + cpu_restore_state(env_cpu(env), retaddr); pc = env->pc; insn = cpu_ldl_code(env, pc); diff --git a/target/arm/op_helper.c b/target/arm/op_helper.c index c5bde1cfcc..70672bcd9f 100644 --- a/target/arm/op_helper.c +++ b/target/arm/op_helper.c @@ -78,7 +78,7 @@ void raise_exception_ra(CPUARMState *env, uint32_t excp, uint32_t syndrome, * we must restore CPU state here before setting the syndrome * the caller passed us, and cannot use cpu_loop_exit_restore(). */ - cpu_restore_state(cs, ra, true); + cpu_restore_state(cs, ra); raise_exception(env, excp, syndrome, target_el); } diff --git a/target/arm/tlb_helper.c b/target/arm/tlb_helper.c index 69b0dc69df..0f4f4fc809 100644 --- a/target/arm/tlb_helper.c +++ b/target/arm/tlb_helper.c @@ -156,7 +156,7 @@ void arm_cpu_do_unaligned_access(CPUState *cs, vaddr vaddr, ARMMMUFaultInfo fi = {}; /* now we have a real cpu fault */ - cpu_restore_state(cs, retaddr, true); + cpu_restore_state(cs, retaddr); fi.type = ARMFault_Alignment; arm_deliver_fault(cpu, vaddr, access_type, mmu_idx, &fi); @@ -196,7 +196,7 @@ void arm_cpu_do_transaction_failed(CPUState *cs, hwaddr physaddr, ARMMMUFaultInfo fi = {}; /* now we have a real cpu fault */ - cpu_restore_state(cs, retaddr, true); + cpu_restore_state(cs, retaddr); fi.ea = arm_extabort_type(response); fi.type = ARMFault_SyncExternal; @@ -252,7 +252,7 @@ bool arm_cpu_tlb_fill(CPUState *cs, vaddr address, int size, return false; } else { /* now we have a real cpu fault */ - cpu_restore_state(cs, retaddr, true); + cpu_restore_state(cs, retaddr); arm_deliver_fault(cpu, address, access_type, mmu_idx, fi); } } @@ -271,7 +271,7 @@ void arm_cpu_record_sigsegv(CPUState *cs, vaddr addr, * We report both ESR and FAR to signal handlers. * For now, it's easiest to deliver the fault normally. */ - cpu_restore_state(cs, ra, true); + cpu_restore_state(cs, ra); arm_deliver_fault(cpu, addr, access_type, MMU_USER_IDX, &fi); } diff --git a/target/cris/helper.c b/target/cris/helper.c index 91e4aeb178..81a72699b5 100644 --- a/target/cris/helper.c +++ b/target/cris/helper.c @@ -87,7 +87,7 @@ bool cris_cpu_tlb_fill(CPUState *cs, vaddr address, int size, cs->exception_index = EXCP_BUSFAULT; env->fault_vector = res.bf_vec; if (retaddr) { - if (cpu_restore_state(cs, retaddr, true)) { + if (cpu_restore_state(cs, retaddr)) { /* Evaluate flags after retranslation. */ helper_top_evaluate_flags(env); } diff --git a/target/i386/tcg/sysemu/svm_helper.c b/target/i386/tcg/sysemu/svm_helper.c index 8e88567399..2d27731b60 100644 --- a/target/i386/tcg/sysemu/svm_helper.c +++ b/target/i386/tcg/sysemu/svm_helper.c @@ -704,7 +704,7 @@ void cpu_vmexit(CPUX86State *env, uint32_t exit_code, uint64_t exit_info_1, { CPUState *cs = env_cpu(env); - cpu_restore_state(cs, retaddr, true); + cpu_restore_state(cs, retaddr); qemu_log_mask(CPU_LOG_TB_IN_ASM, "vmexit(%08x, %016" PRIx64 ", %016" PRIx64 ", " TARGET_FMT_lx ")!\n", diff --git a/target/m68k/op_helper.c b/target/m68k/op_helper.c index 5da176d642..1ce850bbc5 100644 --- a/target/m68k/op_helper.c +++ b/target/m68k/op_helper.c @@ -460,7 +460,7 @@ void m68k_cpu_transaction_failed(CPUState *cs, hwaddr physaddr, vaddr addr, M68kCPU *cpu = M68K_CPU(cs); CPUM68KState *env = &cpu->env; - cpu_restore_state(cs, retaddr, true); + cpu_restore_state(cs, retaddr); if (m68k_feature(env, M68K_FEATURE_M68040)) { env->mmu.mmusr = 0; @@ -558,7 +558,7 @@ raise_exception_format2(CPUM68KState *env, int tt, int ilen, uintptr_t raddr) cs->exception_index = tt; /* Recover PC and CC_OP for the beginning of the insn. */ - cpu_restore_state(cs, raddr, true); + cpu_restore_state(cs, raddr); /* Flags are current in env->cc_*, or are undefined. */ env->cc_op = CC_OP_FLAGS; diff --git a/target/microblaze/helper.c b/target/microblaze/helper.c index a607fe68e5..98bdb82de8 100644 --- a/target/microblaze/helper.c +++ b/target/microblaze/helper.c @@ -277,7 +277,7 @@ void mb_cpu_do_unaligned_access(CPUState *cs, vaddr addr, uint32_t esr, iflags; /* Recover the pc and iflags from the corresponding insn_start. */ - cpu_restore_state(cs, retaddr, true); + cpu_restore_state(cs, retaddr); iflags = cpu->env.iflags; qemu_log_mask(CPU_LOG_INT, diff --git a/target/nios2/op_helper.c b/target/nios2/op_helper.c index 2e30d0a908..0aaf33ffc2 100644 --- a/target/nios2/op_helper.c +++ b/target/nios2/op_helper.c @@ -40,7 +40,7 @@ void nios2_cpu_loop_exit_advance(CPUNios2State *env, uintptr_t retaddr) * Do this here, rather than in restore_state_to_opc(), * lest we affect QEMU internal exceptions, like EXCP_DEBUG. */ - cpu_restore_state(cs, retaddr, true); + cpu_restore_state(cs, retaddr); env->pc += 4; cpu_loop_exit(cs); } diff --git a/target/openrisc/sys_helper.c b/target/openrisc/sys_helper.c index dde2fa1623..ec145960e3 100644 --- a/target/openrisc/sys_helper.c +++ b/target/openrisc/sys_helper.c @@ -45,7 +45,7 @@ void HELPER(mtspr)(CPUOpenRISCState *env, target_ulong spr, target_ulong rb) break; case TO_SPR(0, 16): /* NPC */ - cpu_restore_state(cs, GETPC(), true); + cpu_restore_state(cs, GETPC()); /* ??? Mirror or1ksim in not trashing delayed branch state when "jumping" to the current instruction. */ if (env->pc != rb) { @@ -131,7 +131,7 @@ void HELPER(mtspr)(CPUOpenRISCState *env, target_ulong spr, target_ulong rb) case TO_SPR(8, 0): /* PMR */ env->pmr = rb; if (env->pmr & PMR_DME || env->pmr & PMR_SME) { - cpu_restore_state(cs, GETPC(), true); + cpu_restore_state(cs, GETPC()); env->pc += 4; cs->halted = 1; raise_exception(cpu, EXCP_HALTED); diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c index 43f2480e94..3ded309265 100644 --- a/target/ppc/excp_helper.c +++ b/target/ppc/excp_helper.c @@ -2414,7 +2414,7 @@ void ppc_cpu_do_unaligned_access(CPUState *cs, vaddr vaddr, uint32_t insn; /* Restore state and reload the insn we executed, for filling in DSISR. */ - cpu_restore_state(cs, retaddr, true); + cpu_restore_state(cs, retaddr); insn = cpu_ldl_code(env, env->nip); switch (env->mmu_model) { diff --git a/target/s390x/tcg/excp_helper.c b/target/s390x/tcg/excp_helper.c index 29ccf70df1..2cd6d062b9 100644 --- a/target/s390x/tcg/excp_helper.c +++ b/target/s390x/tcg/excp_helper.c @@ -39,7 +39,7 @@ G_NORETURN void tcg_s390_program_interrupt(CPUS390XState *env, { CPUState *cs = env_cpu(env); - cpu_restore_state(cs, ra, true); + cpu_restore_state(cs, ra); qemu_log_mask(CPU_LOG_INT, "program interrupt at %#" PRIx64 "\n", env->psw.addr); trigger_pgm_exception(env, code); diff --git a/target/tricore/op_helper.c b/target/tricore/op_helper.c index a79c838a92..532ae6b74c 100644 --- a/target/tricore/op_helper.c +++ b/target/tricore/op_helper.c @@ -31,7 +31,7 @@ void raise_exception_sync_internal(CPUTriCoreState *env, uint32_t class, int tin { CPUState *cs = env_cpu(env); /* in case we come from a helper-call we need to restore the PC */ - cpu_restore_state(cs, pc, true); + cpu_restore_state(cs, pc); /* Tin is loaded into d[15] */ env->gpr_d[15] = tin; diff --git a/target/xtensa/helper.c b/target/xtensa/helper.c index e0a9caab4b..2aa9777a8e 100644 --- a/target/xtensa/helper.c +++ b/target/xtensa/helper.c @@ -253,7 +253,7 @@ void xtensa_cpu_do_unaligned_access(CPUState *cs, assert(xtensa_option_enabled(env->config, XTENSA_OPTION_UNALIGNED_EXCEPTION)); - cpu_restore_state(CPU(cpu), retaddr, true); + cpu_restore_state(CPU(cpu), retaddr); HELPER(exception_cause_vaddr)(env, env->pc, LOAD_STORE_ALIGNMENT_CAUSE, addr); @@ -284,7 +284,7 @@ bool xtensa_cpu_tlb_fill(CPUState *cs, vaddr address, int size, } else if (probe) { return false; } else { - cpu_restore_state(cs, retaddr, true); + cpu_restore_state(cs, retaddr); HELPER(exception_cause_vaddr)(env, env->pc, ret, address); } } @@ -297,7 +297,7 @@ void xtensa_cpu_do_transaction_failed(CPUState *cs, hwaddr physaddr, vaddr addr, XtensaCPU *cpu = XTENSA_CPU(cs); CPUXtensaState *env = &cpu->env; - cpu_restore_state(cs, retaddr, true); + cpu_restore_state(cs, retaddr); HELPER(exception_cause_vaddr)(env, env->pc, access_type == MMU_INST_FETCH ? INSTR_PIF_ADDR_ERROR_CAUSE : -- 2.34.1 ^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH v2 6/6] accel/tcg: Remove reset_icount argument from cpu_restore_state_from_tb 2022-10-27 10:02 [PATCH v2 0/6] tcg: Fix x86 TARGET_TB_PCREL (#1269) Richard Henderson ` (4 preceding siblings ...) 2022-10-27 10:02 ` [PATCH v2 5/6] accel/tcg: Remove will_exit argument from cpu_restore_state Richard Henderson @ 2022-10-27 10:02 ` Richard Henderson 2022-10-31 0:40 ` [PATCH v2 0/6] tcg: Fix x86 TARGET_TB_PCREL (#1269) Richard Henderson 6 siblings, 0 replies; 17+ messages in thread From: Richard Henderson @ 2022-10-27 10:02 UTC (permalink / raw) To: qemu-devel; +Cc: cfontana The value passed is always true. Reviewed-by: Claudio Fontana <cfontana@suse.de> Signed-off-by: Richard Henderson <richard.henderson@linaro.org> --- accel/tcg/internal.h | 2 +- accel/tcg/tb-maint.c | 4 ++-- accel/tcg/translate-all.c | 15 +++++++-------- 3 files changed, 10 insertions(+), 11 deletions(-) diff --git a/accel/tcg/internal.h b/accel/tcg/internal.h index 9c06b320b7..cb13bade4f 100644 --- a/accel/tcg/internal.h +++ b/accel/tcg/internal.h @@ -107,7 +107,7 @@ TranslationBlock *tb_link_page(TranslationBlock *tb, tb_page_addr_t phys_pc, tb_page_addr_t phys_page2); bool tb_invalidate_phys_page_unwind(tb_page_addr_t addr, uintptr_t pc); void cpu_restore_state_from_tb(CPUState *cpu, TranslationBlock *tb, - uintptr_t host_pc, bool reset_icount); + uintptr_t host_pc); /* Return the current PC from CPU, which may be cached in TB. */ static inline target_ulong log_pc(CPUState *cpu, const TranslationBlock *tb) diff --git a/accel/tcg/tb-maint.c b/accel/tcg/tb-maint.c index c8e921089d..0cdb35548c 100644 --- a/accel/tcg/tb-maint.c +++ b/accel/tcg/tb-maint.c @@ -536,7 +536,7 @@ tb_invalidate_phys_page_range__locked(struct page_collection *pages, * restore the CPU state. */ current_tb_modified = true; - cpu_restore_state_from_tb(cpu, current_tb, retaddr, true); + cpu_restore_state_from_tb(cpu, current_tb, retaddr); } #endif /* TARGET_HAS_PRECISE_SMC */ tb_phys_invalidate__locked(tb); @@ -685,7 +685,7 @@ bool tb_invalidate_phys_page_unwind(tb_page_addr_t addr, uintptr_t pc) * function to partially restore the CPU state. */ current_tb_modified = true; - cpu_restore_state_from_tb(cpu, current_tb, pc, true); + cpu_restore_state_from_tb(cpu, current_tb, pc); } #endif /* TARGET_HAS_PRECISE_SMC */ tb_phys_invalidate(tb, addr); diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c index 90997fed47..0089578f8f 100644 --- a/accel/tcg/translate-all.c +++ b/accel/tcg/translate-all.c @@ -282,12 +282,11 @@ static int cpu_unwind_data_from_tb(TranslationBlock *tb, uintptr_t host_pc, } /* - * The cpu state corresponding to 'host_pc' is restored. - * When reset_icount is true, current TB will be interrupted and - * icount should be recalculated. + * The cpu state corresponding to 'host_pc' is restored in + * preparation for exiting the TB. */ void cpu_restore_state_from_tb(CPUState *cpu, TranslationBlock *tb, - uintptr_t host_pc, bool reset_icount) + uintptr_t host_pc) { uint64_t data[TARGET_INSN_START_WORDS]; #ifdef CONFIG_PROFILER @@ -300,7 +299,7 @@ void cpu_restore_state_from_tb(CPUState *cpu, TranslationBlock *tb, return; } - if (reset_icount && (tb_cflags(tb) & CF_USE_ICOUNT)) { + if (tb_cflags(tb) & CF_USE_ICOUNT) { assert(icount_enabled()); /* * Reset the cycle counter to the start of the block and @@ -333,7 +332,7 @@ bool cpu_restore_state(CPUState *cpu, uintptr_t host_pc) if (in_code_gen_buffer((const void *)(host_pc - tcg_splitwx_diff))) { TranslationBlock *tb = tcg_tb_lookup(host_pc); if (tb) { - cpu_restore_state_from_tb(cpu, tb, host_pc, true); + cpu_restore_state_from_tb(cpu, tb, host_pc); return true; } } @@ -1032,7 +1031,7 @@ void tb_check_watchpoint(CPUState *cpu, uintptr_t retaddr) tb = tcg_tb_lookup(retaddr); if (tb) { /* We can use retranslation to find the PC. */ - cpu_restore_state_from_tb(cpu, tb, retaddr, true); + cpu_restore_state_from_tb(cpu, tb, retaddr); tb_phys_invalidate(tb, -1); } else { /* The exception probably happened in a helper. The CPU state should @@ -1068,7 +1067,7 @@ void cpu_io_recompile(CPUState *cpu, uintptr_t retaddr) cpu_abort(cpu, "cpu_io_recompile: could not find TB for pc=%p", (void *)retaddr); } - cpu_restore_state_from_tb(cpu, tb, retaddr, true); + cpu_restore_state_from_tb(cpu, tb, retaddr); /* * Some guests must re-execute the branch when re-executing a delay -- 2.34.1 ^ permalink raw reply related [flat|nested] 17+ messages in thread
* Re: [PATCH v2 0/6] tcg: Fix x86 TARGET_TB_PCREL (#1269) 2022-10-27 10:02 [PATCH v2 0/6] tcg: Fix x86 TARGET_TB_PCREL (#1269) Richard Henderson ` (5 preceding siblings ...) 2022-10-27 10:02 ` [PATCH v2 6/6] accel/tcg: Remove reset_icount argument from cpu_restore_state_from_tb Richard Henderson @ 2022-10-31 0:40 ` Richard Henderson 6 siblings, 0 replies; 17+ messages in thread From: Richard Henderson @ 2022-10-31 0:40 UTC (permalink / raw) To: qemu-devel; +Cc: cfontana On 10/27/22 21:02, Richard Henderson wrote: > As per #1269, this affects NetBSD installer boot. > > The problem is that one of the x86 acpi callbacks modifies > env->eip during an mmio store, which means that the tracking > that translate.c does is thrown out of whack. > > Introduce a method to extract unwind data without the > writeback to env. This isn't a perfect abstraction, but I > couldn't think of anything better. There's a couple of lines > of code duplication, but probably less than any abstration > that we might put on top > > Changes for v2: > * Rebase on master, 23 patches merged. > * Comments adjusted per review (claudio) > > > r~ Queuing to tcg-next. r~ ^ permalink raw reply [flat|nested] 17+ messages in thread
end of thread, other threads:[~2022-10-31 5:47 UTC | newest] Thread overview: 17+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2022-10-27 10:02 [PATCH v2 0/6] tcg: Fix x86 TARGET_TB_PCREL (#1269) Richard Henderson 2022-10-27 10:02 ` [PATCH v2 1/6] accel/tcg: Introduce cpu_unwind_state_data Richard Henderson 2022-10-27 10:40 ` Claudio Fontana 2022-10-27 11:30 ` Richard Henderson 2022-10-27 11:39 ` Claudio Fontana 2022-10-27 10:02 ` [PATCH v2 2/6] target/i386: Use cpu_unwind_state_data for tpr access Richard Henderson 2022-10-27 12:22 ` Claudio Fontana 2022-10-27 20:13 ` Richard Henderson 2022-10-28 8:10 ` Claudio Fontana 2022-10-27 10:02 ` [PATCH v2 3/6] target/openrisc: Always exit after mtspr npc Richard Henderson 2022-10-27 10:49 ` Philippe Mathieu-Daudé 2022-10-27 10:02 ` [PATCH v2 4/6] target/openrisc: Use cpu_unwind_state_data for mfspr Richard Henderson 2022-10-28 9:16 ` Claudio Fontana 2022-10-28 18:46 ` Richard Henderson 2022-10-27 10:02 ` [PATCH v2 5/6] accel/tcg: Remove will_exit argument from cpu_restore_state Richard Henderson 2022-10-27 10:02 ` [PATCH v2 6/6] accel/tcg: Remove reset_icount argument from cpu_restore_state_from_tb Richard Henderson 2022-10-31 0:40 ` [PATCH v2 0/6] tcg: Fix x86 TARGET_TB_PCREL (#1269) Richard Henderson
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.