More KVM upstream cleanups, fixes, enhancements
cover More KVM upstream cleanups, fixes, enhancements
Nothing critical, see patches for details.
Jan Kiszka (6):
kvm: Fix coding style violations
kvm: Drop return value of kvm_cpu_exec
kvm: x86: Align kvm_arch_put_registers code with comment
kvm: Stop on all fatal exit reasons
kvm: Improve reporting of fatal errors
kvm: x86: Prepare kvm_get_mp_state for in-kernel irqchip
kvm-all.c | 171 ++++++++++++++++++++++++++++----------------------- kvm-stub.c | 4 +- kvm.h | 2 +- target-i386/cpu.h | 2 + target-i386/cpuid.c | 5 +- target-i386/kvm.c | 46 +++++++++++++- target-ppc/kvm.c | 4 + 7 files changed, 148 insertions(+), 86 deletions(-)
PATCH 1/6 kvm: Fix coding style violations
From: Jan Kiszka <[email protected]>
No functional changes.
--- kvm-all.c | 137 ++++++++++++++++++++++++++++++++++-------------------------- 1 files changed, 78 insertions(+), 59 deletions(-)
kvm-all.c +78 -59
@@ -82,10 +82,12 @@ static KVMSlot *kvm_alloc_slot(KVMState *s)for (i =0 ; i <ARRAY_SIZE (s->slots); i++) {/* KVM private memory slots */ -if (i >=8 && i <12 ) +if (i >=8 && i <12 ) {continue ; -if (s->slots[i].memory_size ==0 ) + } +if (s->slots[i].memory_size ==0 ) {return &s->slots[i]; + } }fprintf (stderr,"%s: no free slot available\n" , __func__);
@@ -220,9 +222,10 @@ int kvm_init_vcpu(CPUState *env) }#ifdef KVM_CAP_COALESCED_MMIO -if (s->coalesced_mmio && !s->coalesced_mmio_ring) - s->coalesced_mmio_ring = (void *) env->kvm_run + - s->coalesced_mmio *PAGE_SIZE ; +if (s->coalesced_mmio && !s->coalesced_mmio_ring) { + s->coalesced_mmio_ring = + (void *)env->kvm_run + s->coalesced_mmio *PAGE_SIZE ; + }#endif ret =kvm_arch_init_vcpu (env);
@@ -269,16 +272,14 @@ static int kvm_dirty_pages_log_change(target_phys_addr_t phys_addr,int kvm_log_start (target_phys_addr_t phys_addr,ram_addr_t size) { -return kvm_dirty_pages_log_change (phys_addr, size, -KVM_MEM_LOG_DIRTY_PAGES , -KVM_MEM_LOG_DIRTY_PAGES ); +return kvm_dirty_pages_log_change (phys_addr, size,KVM_MEM_LOG_DIRTY_PAGES , +KVM_MEM_LOG_DIRTY_PAGES ); }int kvm_log_stop (target_phys_addr_t phys_addr,ram_addr_t size) { -return kvm_dirty_pages_log_change (phys_addr, size, -0 , -KVM_MEM_LOG_DIRTY_PAGES ); +return kvm_dirty_pages_log_change (phys_addr, size,0 , +KVM_MEM_LOG_DIRTY_PAGES ); }static int kvm_set_migration_log (int enable)
@@ -441,9 +442,8 @@ int kvm_check_extension(KVMState *s, unsigned int extension)return ret; } -static void kvm_set_phys_mem (target_phys_addr_t start_addr, -ram_addr_t size, -ram_addr_t phys_offset) +static void kvm_set_phys_mem (target_phys_addr_t start_addr,ram_addr_t size, +ram_addr_t phys_offset) {KVMState *s = kvm_state;ram_addr_t flags = phys_offset & ~TARGET_PAGE_MASK ;
@@ -550,13 +550,13 @@ static void kvm_set_phys_mem(target_phys_addr_t start_addr, }/* in case the KVM bug workaround already "consumed" the new slot */ -if (!size) +if (!size) {return ; - + }/* KVM does not need to know about this memory */ -if (flags >=IO_MEM_UNASSIGNED ) +if (flags >=IO_MEM_UNASSIGNED ) {return ; - + } mem =kvm_alloc_slot (s); mem->memory_size = size; mem->start_addr = start_addr;
@@ -572,30 +572,29 @@ static void kvm_set_phys_mem(target_phys_addr_t start_addr, }static void kvm_client_set_memory (struct CPUPhysMemoryClient *client, -target_phys_addr_t start_addr, -ram_addr_t size, -ram_addr_t phys_offset) +target_phys_addr_t start_addr, +ram_addr_t size,ram_addr_t phys_offset) { -kvm_set_phys_mem (start_addr, size, phys_offset); +kvm_set_phys_mem (start_addr, size, phys_offset); }static int kvm_client_sync_dirty_bitmap (struct CPUPhysMemoryClient *client, -target_phys_addr_t start_addr, -target_phys_addr_t end_addr) +target_phys_addr_t start_addr, +target_phys_addr_t end_addr) { -return kvm_physical_sync_dirty_bitmap (start_addr, end_addr); +return kvm_physical_sync_dirty_bitmap (start_addr, end_addr); }static int kvm_client_migration_log (struct CPUPhysMemoryClient *client, -int enable) +int enable) { -return kvm_set_migration_log (enable); +return kvm_set_migration_log (enable); }static CPUPhysMemoryClient kvm_cpu_phys_memory_client = { - .set_memory = kvm_client_set_memory, - .sync_dirty_bitmap = kvm_client_sync_dirty_bitmap, - .migration_log = kvm_client_migration_log, + .set_memory = kvm_client_set_memory, + .sync_dirty_bitmap = kvm_client_sync_dirty_bitmap, + .migration_log = kvm_client_migration_log, };int kvm_init (int smp_cpus)
@@ -612,9 +611,9 @@ int kvm_init(int smp_cpus)#ifdef KVM_CAP_SET_GUEST_DEBUG QTAILQ_INIT (&s->kvm_sw_breakpoints);#endif -for (i =0 ; i <ARRAY_SIZE (s->slots); i++) +for (i =0 ; i <ARRAY_SIZE (s->slots); i++) { s->slots[i].slot = i; - + } s->vmfd =-1 ; s->fd =qemu_open ("/dev/kvm" ,O_RDWR );if (s->fd ==-1 ) {
@@ -625,8 +624,9 @@ int kvm_init(int smp_cpus) ret =kvm_ioctl (s,KVM_GET_API_VERSION ,0 );if (ret <KVM_API_VERSION ) { -if (ret >0 ) +if (ret >0 ) { ret = -EINVAL ; + }fprintf (stderr,"kvm version too old\n" ); goto err; }
@@ -711,8 +711,9 @@ int kvm_init(int smp_cpus)#endif ret =kvm_arch_init (s, smp_cpus); -if (ret <0 ) +if (ret <0 ) { goto err; + } kvm_state = s;cpu_register_phys_memory_client (&kvm_cpu_phys_memory_client);
@@ -721,10 +722,12 @@ int kvm_init(int smp_cpus) err:if (s) { -if (s->vmfd !=-1 ) +if (s->vmfd !=-1 ) {close (s->vmfd); -if (s->fd !=-1 ) + } +if (s->fd !=-1 ) {close (s->fd); + } }qemu_free (s);
@@ -788,8 +791,9 @@ static void kvm_handle_internal_error(CPUState *env, struct kvm_run *run)cpu_dump_state (env, stderr, fprintf,0 );if (run->internal.suberror ==KVM_INTERNAL_ERROR_EMULATION ) {fprintf (stderr,"emulation failure\n" ); -if (!kvm_arch_stop_on_emulation_error (env)) -return ; +if (!kvm_arch_stop_on_emulation_error (env)) { +return ; + } }/* FIXME: Should trigger a qmp message to let management know * something went wrong.
@@ -829,8 +833,9 @@ static void do_kvm_cpu_synchronize_state(void *_env)void kvm_cpu_synchronize_state (CPUState *env) { -if (!env->kvm_vcpu_dirty) +if (!env->kvm_vcpu_dirty) {run_on_cpu (env, do_kvm_cpu_synchronize_state, env); + } }void kvm_cpu_synchronize_post_reset (CPUState *env)
@@ -970,9 +975,9 @@ int kvm_ioctl(KVMState *s, int type, ...)va_end (ap); ret =ioctl (s->fd, type, arg); -if (ret ==-1 ) +if (ret ==-1 ) { ret = -errno; - + }return ret; }
@@ -987,9 +992,9 @@ int kvm_vm_ioctl(KVMState *s, int type, ...)va_end (ap); ret =ioctl (s->vmfd, type, arg); -if (ret ==-1 ) +if (ret ==-1 ) { ret = -errno; - + }return ret; }
@@ -1004,9 +1009,9 @@ int kvm_vcpu_ioctl(CPUState *env, int type, ...)va_end (ap); ret =ioctl (env->kvm_fd, type, arg); -if (ret ==-1 ) +if (ret ==-1 ) { ret = -errno; - + }return ret; }
@@ -1067,8 +1072,9 @@ struct kvm_sw_breakpoint *kvm_find_sw_breakpoint(CPUState *env,struct kvm_sw_breakpoint *bp; QTAILQ_FOREACH(bp, &env->kvm_state->kvm_sw_breakpoints, entry) { -if (bp->pc == pc) +if (bp->pc == pc) {return bp; + } }return NULL ; }
@@ -1123,8 +1129,9 @@ int kvm_insert_breakpoint(CPUState *current_env, target_ulong addr, } bp =qemu_malloc (sizeof (struct kvm_sw_breakpoint )); -if (!bp) +if (!bp) {return -ENOMEM ; + } bp->pc = addr; bp->use_count =1 ;
@@ -1138,14 +1145,16 @@ int kvm_insert_breakpoint(CPUState *current_env, target_ulong addr, bp, entry); }else { err =kvm_arch_insert_hw_breakpoint (addr, len, type); -if (err) +if (err) {return err; + } }for (env = first_cpu; env !=NULL ; env = env->next_cpu) { err =kvm_update_guest_debug (env,0 ); -if (err) +if (err) {return err; + } }return 0 ; }
@@ -1159,8 +1168,9 @@ int kvm_remove_breakpoint(CPUState *current_env, target_ulong addr,if (type ==GDB_BREAKPOINT_SW ) { bp =kvm_find_sw_breakpoint (current_env, addr); -if (!bp) +if (!bp) {return -ENOENT ; + }if (bp->use_count >1 ) { bp->use_count--;
@@ -1168,21 +1178,24 @@ int kvm_remove_breakpoint(CPUState *current_env, target_ulong addr, } err =kvm_arch_remove_sw_breakpoint (current_env, bp); -if (err) +if (err) {return err; + }QTAILQ_REMOVE (¤t_env->kvm_state->kvm_sw_breakpoints, bp, entry);qemu_free (bp); }else { err =kvm_arch_remove_hw_breakpoint (addr, len, type); -if (err) +if (err) {return err; + } }for (env = first_cpu; env !=NULL ; env = env->next_cpu) { err =kvm_update_guest_debug (env,0 ); -if (err) +if (err) {return err; + } }return 0 ; }
@@ -1197,15 +1210,17 @@ void kvm_remove_all_breakpoints(CPUState *current_env)if (kvm_arch_remove_sw_breakpoint (current_env, bp) !=0 ) {/* Try harder to find a CPU that currently sees the breakpoint. */ for (env = first_cpu; env !=NULL ; env = env->next_cpu) { -if (kvm_arch_remove_sw_breakpoint (env, bp) ==0 ) +if (kvm_arch_remove_sw_breakpoint (env, bp) ==0 ) {break ; + } } } }kvm_arch_remove_all_hw_breakpoints (); -for (env = first_cpu; env !=NULL ; env = env->next_cpu) +for (env = first_cpu; env !=NULL ; env = env->next_cpu) {kvm_update_guest_debug (env,0 ); + } }#else /* !KVM_CAP_SET_GUEST_DEBUG */
@@ -1237,8 +1252,9 @@ int kvm_set_signal_mask(CPUState *env, const sigset_t *sigset)struct kvm_signal_mask *sigmask;int r; -if (!sigset) +if (!sigset) {return kvm_vcpu_ioctl (env,KVM_SET_SIGNAL_MASK ,NULL ); + } sigmask =qemu_malloc (sizeof (*sigmask) +sizeof (*sigset));
@@ -1293,13 +1309,16 @@ int kvm_set_ioeventfd_pio_word(int fd, uint16_t addr, uint16_t val, bool assign) .fd = fd, };int r; -if (!kvm_enabled ()) +if (!kvm_enabled ()) {return -ENOSYS ; -if (!assign) + } +if (!assign) { kick.flags |=KVM_IOEVENTFD_FLAG_DEASSIGN ; + } r =kvm_vm_ioctl (kvm_state,KVM_IOEVENTFD , &kick); -if (r <0 ) +if (r <0 ) {return r; + }return 0 ;#else return -ENOSYS ;
Signature · 1 line
1.7.1
PATCH 2/6 kvm: Drop return value of kvm_cpu_exec
In reply to Jan KiszkaFrom: Jan Kiszka <[email protected]>
It is not used, it is not needed, so let's remove it.
--- kvm-all.c | 6 ++---- kvm-stub.c | 4 ++-- kvm.h | 2 +- 3 files changed, 5 insertions(+), 7 deletions(-)
kvm-all.c +2 -4
@@ -850,7 +850,7 @@ void kvm_cpu_synchronize_post_init(CPUState *env) env->kvm_vcpu_dirty =0 ; } -int kvm_cpu_exec (CPUState *env) +void kvm_cpu_exec (CPUState *env) {struct kvm_run *run = env->kvm_run;int ret;
@@ -943,7 +943,7 @@ int kvm_cpu_exec(CPUState *env)#ifdef KVM_CAP_SET_GUEST_DEBUG if (kvm_arch_debug (&run->debug.arch)) { env->exception_index =EXCP_DEBUG ; -return 0 ; +return ; }/* re-enter, this exception was guest-internal */ ret =1 ;
@@ -960,8 +960,6 @@ int kvm_cpu_exec(CPUState *env) env->exit_request =0 ; env->exception_index =EXCP_INTERRUPT ; } - -return ret; }int kvm_ioctl (KVMState *s,int type, ...)
kvm-stub.c +2 -2
@@ -79,9 +79,9 @@ void kvm_cpu_synchronize_post_init(CPUState *env) { } -int kvm_cpu_exec (CPUState *env) +void kvm_cpu_exec (CPUState *env) { -abort (); +abort (); }int kvm_has_sync_mmu (void )
kvm.h +1 -1
@@ -46,7 +46,7 @@ int kvm_has_xcrs(void);#ifdef NEED_CPU_H int kvm_init_vcpu (CPUState *env); -int kvm_cpu_exec (CPUState *env); +void kvm_cpu_exec (CPUState *env);#if !defined(CONFIG_USER_ONLY )int kvm_log_start (target_phys_addr_t phys_addr,ram_addr_t size);
Signature · 1 line
1.7.1
PATCH 3/6 kvm: x86: Align kvm_arch_put_registers code with comment
In reply to Jan KiszkaFrom: Jan Kiszka <[email protected]>
The ordering doesn't matter in this case, but better keep it consistent.
--- target-i386/kvm.c | 6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-)
target-i386/kvm.c +3 -3
@@ -1388,12 +1388,12 @@ int kvm_arch_put_registers(CPUState *env, int level)if (ret <0 ) {return ret; } -/* must be last */ - ret =kvm_guest_debug_workarounds (env); + ret =kvm_put_debugregs (env);if (ret <0 ) {return ret; } - ret =kvm_put_debugregs (env); +/* must be last */ + ret =kvm_guest_debug_workarounds (env);if (ret <0 ) {return ret; }
Signature · 1 line
1.7.1
PATCH 4/6 kvm: Stop on all fatal exit reasons
In reply to Jan KiszkaFrom: Jan Kiszka <[email protected]>
Ensure that we stop the guest whenever we face a fatal or unknown exit reason. If we stop, we also have to enforce a cpu loop exit.
--- kvm-all.c | 15 +++++++++++---- target-i386/kvm.c | 4 ++++ target-ppc/kvm.c | 4 ++++ 3 files changed, 19 insertions(+), 4 deletions(-)
kvm-all.c +11 -4
@@ -774,7 +774,7 @@ static int kvm_handle_io(uint16_t port, void *data, int direction, int size, }#ifdef KVM_CAP_INTERNAL_ERROR_DATA -static void kvm_handle_internal_error (CPUState *env,struct kvm_run *run) +static int kvm_handle_internal_error (CPUState *env,struct kvm_run *run) {if (kvm_check_extension (kvm_state,KVM_CAP_INTERNAL_ERROR_DATA )) {
@@ -792,13 +792,13 @@ static void kvm_handle_internal_error(CPUState *env, struct kvm_run *run)if (run->internal.suberror ==KVM_INTERNAL_ERROR_EMULATION ) {fprintf (stderr,"emulation failure\n" );if (!kvm_arch_stop_on_emulation_error (env)) { -return ; +return 0 ; } }/* FIXME: Should trigger a qmp message to let management know * something went wrong. */ - vm_stop(0); + return -1; }#endif
@@ -926,16 +926,19 @@ void kvm_cpu_exec(CPUState *env)break ;case KVM_EXIT_UNKNOWN :DPRINTF ("kvm_exit_unknown\n" ); + ret =-1 ;break ;case KVM_EXIT_FAIL_ENTRY :DPRINTF ("kvm_exit_fail_entry\n" ); + ret =-1 ;break ;case KVM_EXIT_EXCEPTION :DPRINTF ("kvm_exit_exception\n" ); + ret =-1 ;break ;#ifdef KVM_CAP_INTERNAL_ERROR_DATA case KVM_EXIT_INTERNAL_ERROR : -kvm_handle_internal_error (env, run); + ret =kvm_handle_internal_error (env, run);break ;#endif case KVM_EXIT_DEBUG :
@@ -956,6 +959,10 @@ void kvm_cpu_exec(CPUState *env) } }while (ret >0 ); +if (ret <0 ) { +vm_stop (0 ); + env->exit_request =1 ; + }if (env->exit_request) { env->exit_request =0 ; env->exception_index =EXCP_INTERRUPT ;
target-i386/kvm.c +4 -0
@@ -1534,6 +1534,10 @@ int kvm_arch_handle_exit(CPUState *env, struct kvm_run *run)DPRINTF ("handle_hlt\n" ); ret =kvm_handle_halt (env);break ; +default : +fprintf (stderr,"KVM: unknown exit reason %d\n" , run->exit_reason); + ret =-1 ; +break ; }return ret;
target-ppc/kvm.c +4 -0
@@ -307,6 +307,10 @@ int kvm_arch_handle_exit(CPUState *env, struct kvm_run *run)dprintf ("handle halt\n" ); ret =kvmppc_handle_halt (env);break ; +default : +fprintf (stderr,"KVM: unknown exit reason %d\n" , run->exit_reason); + ret =-1 ; +break ; }return ret;
Signature · 1 line
1.7.1
PATCH 5/6 kvm: Improve reporting of fatal errors
In reply to Jan KiszkaFrom: Jan Kiszka <[email protected]>
Report KVM_EXIT_UNKNOWN, KVM_EXIT_FAIL_ENTRY, and KVM_EXIT_EXCEPTION with more details to stderr. The latter two are so far x86-only, so move them into the arch-specific handler. Integrate the Intel real mode warning on KVM_EXIT_FAIL_ENTRY that qemu-kvm carries, but actually restrict it to Intel CPUs.
--- kvm-all.c | 19 ++++++------------- target-i386/cpu.h | 2 ++ target-i386/cpuid.c | 5 ++--- target-i386/kvm.c | 33 +++++++++++++++++++++++++++++++++ 4 files changed, 43 insertions(+), 16 deletions(-)
kvm-all.c +6 -13
@@ -776,17 +776,17 @@ static int kvm_handle_io(uint16_t port, void *data, int direction, int size,#ifdef KVM_CAP_INTERNAL_ERROR_DATA static int kvm_handle_internal_error (CPUState *env,struct kvm_run *run) { - +fprintf (stderr,"KVM internal error." );if (kvm_check_extension (kvm_state,KVM_CAP_INTERNAL_ERROR_DATA )) {int i; -fprintf (stderr,"KVM internal error. Suberror: %d\n" , - run->internal.suberror); - +fprintf (stderr," Suberror: %d\n" , run->internal.suberror);for (i =0 ; i < run->internal.ndata; ++i) {fprintf (stderr,"extra data[%d]: %" PRIx64"\n" , i, (uint64_t )run->internal.data[i]); } + }else { +fprintf (stderr,"\n" ); }cpu_dump_state (env, stderr, fprintf,0 );if (run->internal.suberror ==KVM_INTERNAL_ERROR_EMULATION ) {
@@ -925,15 +925,8 @@ void kvm_cpu_exec(CPUState *env) ret =1 ;break ;case KVM_EXIT_UNKNOWN : -DPRINTF ("kvm_exit_unknown\n" ); - ret =-1 ; -break ; -case KVM_EXIT_FAIL_ENTRY : -DPRINTF ("kvm_exit_fail_entry\n" ); - ret =-1 ; -break ; -case KVM_EXIT_EXCEPTION : -DPRINTF ("kvm_exit_exception\n" ); +fprintf (stderr,"KVM: unknown exit, hardware reason %" PRIx64"\n" , + (uint64_t )run->hw.hardware_exit_reason); ret =-1 ;break ;#ifdef KVM_CAP_INTERNAL_ERROR_DATA
target-i386/cpu.h +2 -0
@@ -874,6 +874,8 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count, uint32_t *ecx, uint32_t *edx);int cpu_x86_register (CPUX86State *env,const char *cpu_model);void cpu_clear_apic_feature (CPUX86State *env); +void host_cpuid (uint32_t function,uint32_t count, +uint32_t *eax,uint32_t *ebx,uint32_t *ecx,uint32_t *edx);/* helper.c */ int cpu_x86_handle_mmu_fault(CPUX86State *env, target_ulong addr,
target-i386/cpuid.c +2 -3
@@ -103,9 +103,8 @@ typedef struct model_features_t {int check_cpuid =0 ;int enforce_cpuid =0 ; -static void host_cpuid (uint32_t function,uint32_t count, -uint32_t *eax,uint32_t *ebx, -uint32_t *ecx,uint32_t *edx) +void host_cpuid (uint32_t function,uint32_t count, +uint32_t *eax,uint32_t *ebx,uint32_t *ecx,uint32_t *edx) {#if defined(CONFIG_KVM )uint32_t vec[4 ];
target-i386/kvm.c +33 -0
@@ -1525,8 +1525,19 @@ static int kvm_handle_halt(CPUState *env)return 1 ; } +static bool host_supports_vmx (void ) +{ +uint32_t ecx, unused; + +host_cpuid (1 ,0 , &unused, &unused, &ecx, &unused); +return ecx &CPUID_EXT_VMX ; +} + +#define VMX_INVALID_GUEST_STATE 0x80000021 +int kvm_arch_handle_exit (CPUState *env,struct kvm_run *run) { +uint64_t code;int ret =0 ;switch (run->exit_reason) {
@@ -1534,6 +1545,28 @@ int kvm_arch_handle_exit(CPUState *env, struct kvm_run *run)DPRINTF ("handle_hlt\n" ); ret =kvm_handle_halt (env);break ; +case KVM_EXIT_FAIL_ENTRY : + code = run->fail_entry.hardware_entry_failure_reason; +fprintf (stderr,"KVM: entry failed, hardware error 0x%" PRIx64"\n" , + code); +if (host_supports_vmx () && code ==VMX_INVALID_GUEST_STATE ) { +fprintf (stderr, +"\nIf you're runnning a guest on an Intel machine without " +"unrestricted mode\n" +"support, the failure can be most likely due to the guest " +"entering an invalid\n" +"state for Intel VT. For example, the guest maybe running " +"in big real mode\n" +"which is not supported on less recent Intel processors." +"\n\n" ); + } + ret =-1 ; +break ; +case KVM_EXIT_EXCEPTION : +fprintf (stderr,"KVM: exception %d exit (error code 0x%x)\n" , + run->ex.exception, run->ex.error_code); + ret =-1 ; +break ;default :fprintf (stderr,"KVM: unknown exit reason %d\n" , run->exit_reason); ret =-1 ;
Signature · 1 line
1.7.1
PATCH 6/6 kvm: x86: Prepare kvm_get_mp_state for in-kernel irqchip
In reply to Jan KiszkaFrom: Jan Kiszka <[email protected]>
This code path will not yet be taken as we still lack in-kernel irqchip support. But qemu-kvm can already make use of it and drop its own mp_state access services.
--- target-i386/kvm.c | 3 +++ 1 files changed, 3 insertions(+), 0 deletions(-)
target-i386/kvm.c +3 -0
@@ -1198,6 +1198,9 @@ static int kvm_get_mp_state(CPUState *env)return ret; } env->mp_state = mp_state.mp_state; +if (kvm_irqchip_in_kernel ()) { + env->halted = (mp_state.mp_state ==KVM_MP_STATE_HALTED ); + }return 0 ; }
Signature · 1 line
1.7.1