Skip to content

Commit

Permalink
i386: hvf: Reset IRQ inhibition after moving RIP
Browse files Browse the repository at this point in the history
The sequence of instructions exposes an issue:
  sti
  hlt

Interrupts cannot be delivered to hvf after hlt instruction cpu because
HF_INHIBIT_IRQ_MASK is set just before hlt is handled and never reset
after moving instruction pointer beyond hlt.

So, after hvf_vcpu_exec() returns, CPU thread gets locked up forever in
qemu_wait_io_event() (cpu_thread_is_idle() evaluates inhibition
flag and considers the CPU idle if the flag is set).

Cc: Cameron Esfahani <dirty@apple.com>
Signed-off-by: Roman Bolshakov <r.bolshakov@yadro.com>
Message-Id: <20200328174411.51491-1-r.bolshakov@yadro.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
  • Loading branch information
Roman Bolshakov authored and bonzini committed Apr 2, 2020
1 parent 622e99c commit ddd3173
Showing 1 changed file with 3 additions and 0 deletions.
3 changes: 3 additions & 0 deletions target/i386/hvf/vmx.h
Expand Up @@ -167,6 +167,8 @@ static inline void macvm_set_cr4(hv_vcpuid_t vcpu, uint64_t cr4)

static inline void macvm_set_rip(CPUState *cpu, uint64_t rip)
{
X86CPU *x86_cpu = X86_CPU(cpu);
CPUX86State *env = &x86_cpu->env;
uint64_t val;

/* BUG, should take considering overlap.. */
Expand All @@ -176,6 +178,7 @@ static inline void macvm_set_rip(CPUState *cpu, uint64_t rip)
val = rvmcs(cpu->hvf_fd, VMCS_GUEST_INTERRUPTIBILITY);
if (val & (VMCS_INTERRUPTIBILITY_STI_BLOCKING |
VMCS_INTERRUPTIBILITY_MOVSS_BLOCKING)) {
env->hflags &= ~HF_INHIBIT_IRQ_MASK;
wvmcs(cpu->hvf_fd, VMCS_GUEST_INTERRUPTIBILITY,
val & ~(VMCS_INTERRUPTIBILITY_STI_BLOCKING |
VMCS_INTERRUPTIBILITY_MOVSS_BLOCKING));
Expand Down

0 comments on commit ddd3173

Please sign in to comment.