diff mbox series

[v4,6/8] accel/tcg: Fix tb mis-matched problem when CF_PCREL is enabled

Message ID 20230331150609.114401-7-liweiwei@iscas.ac.cn (mailing list archive)
State New, archived
Headers show
Series target/riscv: Fix pointer mask related support | expand

Commit Message

Weiwei Li March 31, 2023, 3:06 p.m. UTC
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(+)

Comments

Richard Henderson April 1, 2023, 1:26 a.m. UTC | #1
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);
}


r~
Richard Henderson April 1, 2023, 1:52 a.m. UTC | #2
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~
diff mbox series

Patch

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);
+                }
             }
 
 #ifndef CONFIG_USER_ONLY