tcg: synchronize cpu->exit_request and cpu->tcg_exit_req accesses

Backports commit ab096a75cd626dcd4ad34b2a11652df0269bee0d from qemu
This commit is contained in:
Paolo Bonzini 2018-02-15 13:09:37 -05:00 committed by Lioncash
parent 1cfd4190a7
commit 7f1d59bb83
No known key found for this signature in database
GPG key ID: 4E3C3CC1031BA9C7
2 changed files with 19 additions and 13 deletions

View file

@ -244,19 +244,23 @@ int cpu_exec(struct uc_struct *uc, CPUState *cpu)
cpu->current_tb = NULL; cpu->current_tb = NULL;
switch (next_tb & TB_EXIT_MASK) { switch (next_tb & TB_EXIT_MASK) {
case TB_EXIT_REQUESTED: case TB_EXIT_REQUESTED:
/* Something asked us to stop executing /* Something asked us to stop executing
* chained TBs; just continue round the main * chained TBs; just continue round the main
* loop. Whatever requested the exit will also * loop. Whatever requested the exit will also
* have set something else (eg exit_request or * have set something else (eg exit_request or
* interrupt_request) which we will handle * interrupt_request) which we will handle
* next time around the loop. * next time around the loop. But we need to
*/ * ensure the tcg_exit_req read in generated code
tb = (TranslationBlock *)(next_tb & ~TB_EXIT_MASK); * comes before the next read of cpu->exit_request
next_tb = 0; * or cpu->interrupt_request.
break; */
default: smp_rmb();
break; tb = (TranslationBlock *)(next_tb & ~TB_EXIT_MASK);
next_tb = 0;
break;
default:
break;
} }
} }
/* reset soft MMU for next block (it can currently /* reset soft MMU for next block (it can currently

View file

@ -107,6 +107,8 @@ void cpu_reset_interrupt(CPUState *cpu, int mask)
void cpu_exit(CPUState *cpu) void cpu_exit(CPUState *cpu)
{ {
cpu->exit_request = 1; cpu->exit_request = 1;
/* Ensure cpu_exec will see the exit request after TCG has exited. */
smp_wmb();
cpu->tcg_exit_req = 1; cpu->tcg_exit_req = 1;
} }