On 13.10.2015 03:13, Richard Henderson wrote:
> On 10/10/2015 12:34 AM, Sergey Fedorov wrote:
>>> @@ -2936,6 +2927,10 @@ static inline void
>>> gen_intermediate_code_internal(AlphaCPU *cpu,
>>> tcg_gen_insn_start(ctx.pc);
>>> num_insns++;
>>>
>>> + if (unlikely(cpu_breakpoint_test(cs, ctx.pc, BP_ANY))) {
>>> + gen_excp(&ctx, EXCP_DEBUG, 0);
>>> + break;
>>> + }
>>
>> Actually, control logic has changed here. The old code used a break
>> statement to exit from QTAILQ_FOREACH loop and continue with instruction
>> translation thus translating at least one instruction. The break
>> statement in the new code makes exit from the translation loop itself,
>> effectively producing zero-length TB which won't get invalidated when
>> clearing the breakpoint. Seems like we should remove the break statement
>> here and in similar cases below, right?
>
> Why do you believe that a zero-length TB won't be cleared?
> The TB still has a start address, which is contained within
> a given page, which is invalidated.
>
> Some target-*/translate.c takes care to advance the PC, but I believe
> that this is only required when the breakpoint instruction *itself*
> could span a page boundary. I.e. the TB needs to be marked to span
> two pages. This situation can never be true for many RISC targets.
>
> We did discuss this exact situation during review of the patch set,
> though it's probably true that there are outstanding errors in some
> translators.
I see your point, but what I am actually concerned about is the
following scenario.
Lets suppose we are going to remove a breakpoint. Eventually we can get
the following function call stack:
#0 tb_invalidate_phys_page_range()
#1 tb_invalidate_phys_addr()
#2 breakpoint_invalidate()
#3 cpu_breakpoint_remove_by_ref()
...
Then, if we come across a zero-sized TB then 'tb_start' would be equal
to 'tb_end'. That is not a big deal unless 'start' is not equal to
'tb_start'. Otherwise, "!(tb_end <= start || tb_start >= end)" condition
check will fail and that TB won't get invalidated as it should be. As I
can see this is a case when we try to remove a breakpoint which is
happened to be set at the very first instruction of a TB. So we either
need to change the condition in tb_invalidate_phys_page_range() or do
the PC advancement trick during translation, no matter can instructions
cross a page boundary or not.
Best regards,
Sergey