On 3/31/23 18:26, Richard Henderson wrote:
> On 3/31/23 08:06, Weiwei Li wrote:
>> A corner case is triggered when tb block with first_pc = 0x80000008
>> and first_pc = 0x800000200 has the same jump cache hash, and share
>> the same tb entry with the same tb information except PC.
>> The executed sequence is as follows:
>> tb(0x80000008) -> tb(0x80000008)-> tb(0x800000200) -> tb(0x80000008)
>>
>> 1. At the first time tb for 0x80000008 is loaded, tb in jmp_cache is
>> filled, however pc is not updated.
>> 2. At the second time tb for 0x80000008 is looked up in tb_lookup(),
>> pc in jmp cache is set to 0x80000008.
>> 3. when tb for 0x800000200 is loaded, tb for jmp cache is updated to
>> this block, however pc is not updated, and remains to be 0x80000008.
>> 4. Finally at the last time tb for 0x80000008 is looked up, tb for
>> 0x800000200 is mismatched.
>>
>> Signed-off-by: Weiwei Li <liweiwei@iscas.ac.cn>
>> Signed-off-by: Junqiang Wang <wangjunqiang@iscas.ac.cn>
>> ---
>> accel/tcg/cpu-exec.c | 3 +++
>> 1 file changed, 3 insertions(+)
>>
>> diff --git a/accel/tcg/cpu-exec.c b/accel/tcg/cpu-exec.c
>> index c815f2dbfd..faff413f42 100644
>> --- a/accel/tcg/cpu-exec.c
>> +++ b/accel/tcg/cpu-exec.c
>> @@ -983,6 +983,9 @@ cpu_exec_loop(CPUState *cpu, SyncClocks *sc)
>> h = tb_jmp_cache_hash_func(pc);
>> /* Use the pc value already stored in tb->pc. */
>> qatomic_set(&cpu->tb_jmp_cache->array[h].tb, tb);
>> + if (cflags & CF_PCREL) {
>> + qatomic_set(&cpu->tb_jmp_cache->array[h].pc, pc);
>> + }
>
> Good catch on the bug, but incorrect fix. Need
>
> if (cflags & CF_PCREL) {
> qatomic_set(&cpu->tb_jmp_cache->array[h].pc, pc);
> qatomic_store_release(&cpu->tb_jmp_cache->array[h].tb, tb);
> } else {
> /* Use the pc value already stored in tb->pc. */
> qatomic_set(&cpu->tb_jmp_cache->array[h].tb, tb);
> }
Queuing the fix to tcg-next.
r~