i386/cpu: add crash-information QOM property
Windows reports BSOD parameters through Hyper-V crash MSRs. This information is very useful for initial crash analysis and thus it would be nice to have a way to fetch it. Signed-off-by: Anton Nefedov <anton.nefedov@virtuozzo.com> Signed-off-by: Denis V. Lunev <den@openvz.org> Message-Id: <1487053524-18674-2-git-send-email-den@openvz.org> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
		
							parent
							
								
									d9e73d32a8
								
							
						
					
					
						commit
						d187e08dc4
					
				@ -2000,6 +2000,7 @@ int kvm_cpu_exec(CPUState *cpu)
 | 
				
			|||||||
                ret = EXCP_INTERRUPT;
 | 
					                ret = EXCP_INTERRUPT;
 | 
				
			||||||
                break;
 | 
					                break;
 | 
				
			||||||
            case KVM_SYSTEM_EVENT_CRASH:
 | 
					            case KVM_SYSTEM_EVENT_CRASH:
 | 
				
			||||||
 | 
					                kvm_cpu_synchronize_state(cpu);
 | 
				
			||||||
                qemu_mutex_lock_iothread();
 | 
					                qemu_mutex_lock_iothread();
 | 
				
			||||||
                qemu_system_guest_panicked();
 | 
					                qemu_system_guest_panicked();
 | 
				
			||||||
                qemu_mutex_unlock_iothread();
 | 
					                qemu_mutex_unlock_iothread();
 | 
				
			||||||
 | 
				
			|||||||
@ -5870,6 +5870,30 @@
 | 
				
			|||||||
{ 'enum': 'GuestPanicAction',
 | 
					{ 'enum': 'GuestPanicAction',
 | 
				
			||||||
  'data': [ 'pause', 'poweroff' ] }
 | 
					  'data': [ 'pause', 'poweroff' ] }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					##
 | 
				
			||||||
 | 
					# @GuestPanicInformation:
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# Information about a guest panic
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# Since: 2.9
 | 
				
			||||||
 | 
					##
 | 
				
			||||||
 | 
					{'union': 'GuestPanicInformation',
 | 
				
			||||||
 | 
					 'data': { 'hyper-v': 'GuestPanicInformationHyperV' } }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					##
 | 
				
			||||||
 | 
					# @GuestPanicInformationHyperV:
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# Hyper-V specific guest panic information (HV crash MSRs)
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# Since: 2.9
 | 
				
			||||||
 | 
					##
 | 
				
			||||||
 | 
					{'struct': 'GuestPanicInformationHyperV',
 | 
				
			||||||
 | 
					 'data': { 'arg1': 'uint64',
 | 
				
			||||||
 | 
					           'arg2': 'uint64',
 | 
				
			||||||
 | 
					           'arg3': 'uint64',
 | 
				
			||||||
 | 
					           'arg4': 'uint64',
 | 
				
			||||||
 | 
					           'arg5': 'uint64' } }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
##
 | 
					##
 | 
				
			||||||
# @rtc-reset-reinjection:
 | 
					# @rtc-reset-reinjection:
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
 | 
				
			|||||||
@ -3495,6 +3495,53 @@ static void x86_cpu_register_feature_bit_props(X86CPU *cpu,
 | 
				
			|||||||
    x86_cpu_register_bit_prop(cpu, name, &cpu->env.features[w], bitnr);
 | 
					    x86_cpu_register_bit_prop(cpu, name, &cpu->env.features[w], bitnr);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static GuestPanicInformation *x86_cpu_get_crash_info(CPUState *cs)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    X86CPU *cpu = X86_CPU(cs);
 | 
				
			||||||
 | 
					    CPUX86State *env = &cpu->env;
 | 
				
			||||||
 | 
					    GuestPanicInformation *panic_info = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (env->features[FEAT_HYPERV_EDX] & HV_X64_GUEST_CRASH_MSR_AVAILABLE) {
 | 
				
			||||||
 | 
					        GuestPanicInformationHyperV *panic_info_hv =
 | 
				
			||||||
 | 
					            g_malloc0(sizeof(GuestPanicInformationHyperV));
 | 
				
			||||||
 | 
					        panic_info = g_malloc0(sizeof(GuestPanicInformation));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        panic_info->type = GUEST_PANIC_INFORMATION_KIND_HYPER_V;
 | 
				
			||||||
 | 
					        panic_info->u.hyper_v.data = panic_info_hv;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        assert(HV_X64_MSR_CRASH_PARAMS >= 5);
 | 
				
			||||||
 | 
					        panic_info_hv->arg1 = env->msr_hv_crash_params[0];
 | 
				
			||||||
 | 
					        panic_info_hv->arg2 = env->msr_hv_crash_params[1];
 | 
				
			||||||
 | 
					        panic_info_hv->arg3 = env->msr_hv_crash_params[2];
 | 
				
			||||||
 | 
					        panic_info_hv->arg4 = env->msr_hv_crash_params[3];
 | 
				
			||||||
 | 
					        panic_info_hv->arg5 = env->msr_hv_crash_params[4];
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return panic_info;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					static void x86_cpu_get_crash_info_qom(Object *obj, Visitor *v,
 | 
				
			||||||
 | 
					                                       const char *name, void *opaque,
 | 
				
			||||||
 | 
					                                       Error **errp)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    CPUState *cs = CPU(obj);
 | 
				
			||||||
 | 
					    GuestPanicInformation *panic_info;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (!cs->crash_occurred) {
 | 
				
			||||||
 | 
					        error_setg(errp, "No crash occured");
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    panic_info = x86_cpu_get_crash_info(cs);
 | 
				
			||||||
 | 
					    if (panic_info == NULL) {
 | 
				
			||||||
 | 
					        error_setg(errp, "No crash information");
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    visit_type_GuestPanicInformation(v, "crash-information", &panic_info,
 | 
				
			||||||
 | 
					                                     errp);
 | 
				
			||||||
 | 
					    qapi_free_GuestPanicInformation(panic_info);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void x86_cpu_initfn(Object *obj)
 | 
					static void x86_cpu_initfn(Object *obj)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    CPUState *cs = CPU(obj);
 | 
					    CPUState *cs = CPU(obj);
 | 
				
			||||||
@ -3530,6 +3577,9 @@ static void x86_cpu_initfn(Object *obj)
 | 
				
			|||||||
                        x86_cpu_get_feature_words,
 | 
					                        x86_cpu_get_feature_words,
 | 
				
			||||||
                        NULL, NULL, (void *)cpu->filtered_features, NULL);
 | 
					                        NULL, NULL, (void *)cpu->filtered_features, NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    object_property_add(obj, "crash-information", "GuestPanicInformation",
 | 
				
			||||||
 | 
					                        x86_cpu_get_crash_info_qom, NULL, NULL, NULL, NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    cpu->hyperv_spinlock_attempts = HYPERV_SPINLOCK_NEVER_RETRY;
 | 
					    cpu->hyperv_spinlock_attempts = HYPERV_SPINLOCK_NEVER_RETRY;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    for (w = 0; w < FEATURE_WORDS; w++) {
 | 
					    for (w = 0; w < FEATURE_WORDS; w++) {
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user