mirror of https://github.com/xemu-project/xemu.git
target/i386: fix TF/RF handling for HLT
HLT uses DISAS_NORETURN because the corresponding helper calls cpu_loop_exit(). However, while gen_eob() clears HF_RF_MASK and synthesizes a #DB exception if single-step is active, none of this is done by HLT. Note that the single-step trap is generated after the halt is finished. Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
parent
3718523d01
commit
6dd7d8c649
|
@ -520,7 +520,7 @@ G_NORETURN void helper_hlt(CPUX86State *env)
|
||||||
{
|
{
|
||||||
CPUState *cs = env_cpu(env);
|
CPUState *cs = env_cpu(env);
|
||||||
|
|
||||||
env->hflags &= ~HF_INHIBIT_IRQ_MASK; /* needed if sti is just before */
|
do_end_instruction(env);
|
||||||
cs->halted = 1;
|
cs->halted = 1;
|
||||||
cs->exception_index = EXCP_HLT;
|
cs->exception_index = EXCP_HLT;
|
||||||
cpu_loop_exit(cs);
|
cpu_loop_exit(cs);
|
||||||
|
|
|
@ -130,15 +130,26 @@ void x86_cpu_do_interrupt(CPUState *cs)
|
||||||
|
|
||||||
bool x86_cpu_exec_halt(CPUState *cpu)
|
bool x86_cpu_exec_halt(CPUState *cpu)
|
||||||
{
|
{
|
||||||
if (cpu->interrupt_request & CPU_INTERRUPT_POLL) {
|
X86CPU *x86_cpu = X86_CPU(cpu);
|
||||||
X86CPU *x86_cpu = X86_CPU(cpu);
|
CPUX86State *env = &x86_cpu->env;
|
||||||
|
|
||||||
|
if (cpu->interrupt_request & CPU_INTERRUPT_POLL) {
|
||||||
bql_lock();
|
bql_lock();
|
||||||
apic_poll_irq(x86_cpu->apic_state);
|
apic_poll_irq(x86_cpu->apic_state);
|
||||||
cpu_reset_interrupt(cpu, CPU_INTERRUPT_POLL);
|
cpu_reset_interrupt(cpu, CPU_INTERRUPT_POLL);
|
||||||
bql_unlock();
|
bql_unlock();
|
||||||
}
|
}
|
||||||
return cpu_has_work(cpu);
|
|
||||||
|
if (!cpu_has_work(cpu)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Complete HLT instruction. */
|
||||||
|
if (env->eflags & TF_MASK) {
|
||||||
|
env->dr[6] |= DR6_BS;
|
||||||
|
do_interrupt_all(x86_cpu, EXCP01_DB, 0, 0, env->eip, 0);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool x86_need_replay_interrupt(int interrupt_request)
|
bool x86_need_replay_interrupt(int interrupt_request)
|
||||||
|
|
Loading…
Reference in New Issue