On 10/25/22 11:23, Claudio Fontana wrote:
> On 10/24/22 15:24, 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.hender...@linaro.org>
>> ---
>>  include/exec/exec-all.h   | 13 ++++++++
>>  accel/tcg/translate-all.c | 68 ++++++++++++++++++++++++++-------------
>>  2 files changed, 58 insertions(+), 23 deletions(-)
>>
>> diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h
>> index 300832bd0b..d49cf113dd 100644
>> --- a/include/exec/exec-all.h
>> +++ b/include/exec/exec-all.h
>> @@ -39,6 +39,19 @@ typedef ram_addr_t tb_page_addr_t;
>>  #define TB_PAGE_ADDR_FMT RAM_ADDR_FMT
>>  #endif
>>  
>> +/**
>> + * cpu_unwind_state_data:
>> + * @cpu: the vCPU state is to be restore to

"the vCPU state to be restored to" ?

>> + * @host_pc: the host PC the fault occurred at
>> + * @data: output data
>> + *
>> + * Attempt to load the the unwind state for a host pc occurring in
>> + * translated code.  If the searched_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
>> diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c
>> index e4386b3198..c772e3769c 100644
>> --- a/accel/tcg/translate-all.c
>> +++ b/accel/tcg/translate-all.c
>> @@ -320,29 +320,20 @@ 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.
>> - */
>> -static 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);
>>      }
> 
> It's not visible in this hunk, but what follows is:
> 
>     /* Reconstruct the stored insn data while looking for the point at        
>                                                               
>        which the end of the insn exceeds the searched_pc.  */
> 
> Should this comment be adapted, minimally with s,searched_pc,host_pc, ?
> 
> 
>> @@ -353,19 +344,40 @@ static int cpu_restore_state_from_tb(CPUState *cpu, 
>> TranslationBlock *tb,
>>          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.
>> + */
>> +static 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;
>> +    }
> 
> Is the -1 return value some error condition to do anything about, log, tcg 
> assert, or ...,
> under some DEBUG_* condition, or ignored as done here?
> 
> Thanks,
> 
> Claudio
> 
>>  
>> - 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);
>> @@ -375,7 +387,6 @@ static 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)
>> @@ -408,6 +419,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();
> 


Reply via email to