qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] Re: [patch uq/master 7/8] MCE: Relay UCR MCE to guest


From: Hidetoshi Seto
Subject: [Qemu-devel] Re: [patch uq/master 7/8] MCE: Relay UCR MCE to guest
Date: Wed, 06 Oct 2010 10:10:51 +0900
User-agent: Mozilla/5.0 (Windows; U; Windows NT 6.0; ja; rv:1.9.2.9) Gecko/20100915 Thunderbird/3.1.4

(2010/10/05 3:54), Marcelo Tosatti wrote:
> Port qemu-kvm's
> 
> commit 4b62fff1101a7ad77553147717a8bd3bf79df7ef
> Author: Huang Ying <address@hidden>
> Date:   Mon Sep 21 10:43:25 2009 +0800
> 
>     MCE: Relay UCR MCE to guest
>     
>     UCR (uncorrected recovery) MCE is supported in recent Intel CPUs,
>     where some hardware error such as some memory error can be reported
>     without PCC (processor context corrupted). To recover from such MCE,
>     the corresponding memory will be unmapped, and all processes accessing
>     the memory will be killed via SIGBUS.
>     
>     For KVM, if QEMU/KVM is killed, all guest processes will be killed
>     too. So we relay SIGBUS from host OS to guest system via a UCR MCE
>     injection. Then guest OS can isolate corresponding memory and kill
>     necessary guest processes only. SIGBUS sent to main thread (not VCPU
>     threads) will be broadcast to all VCPU threads as UCR MCE.
> 
> Signed-off-by: Marcelo Tosatti <address@hidden>
> 

(snip)

> +static void sigbus_handler(int n, struct qemu_signalfd_siginfo *siginfo,
> +                           void *ctx)
> +{
> +#if defined(TARGET_I386)
> +    if (kvm_on_sigbus_vcpu(siginfo->ssi_code, (void 
> *)(intptr_t)siginfo->ssi_addr))
> +#endif
> +        sigbus_reraise();
> +}
> +
>  static void qemu_kvm_eat_signal(CPUState *env, int timeout)
>  {
>      struct timespec ts;
>      int r, e;
>      siginfo_t siginfo;
>      sigset_t waitset;
> +    sigset_t chkset;
>  
>      ts.tv_sec = timeout / 1000;
>      ts.tv_nsec = (timeout % 1000) * 1000000;
>  
>      sigemptyset(&waitset);
>      sigaddset(&waitset, SIG_IPI);
> +    sigaddset(&waitset, SIGBUS);
>  
> -    qemu_mutex_unlock(&qemu_global_mutex);
> -    r = sigtimedwait(&waitset, &siginfo, &ts);
> -    e = errno;
> -    qemu_mutex_lock(&qemu_global_mutex);
> +    do {
> +        qemu_mutex_unlock(&qemu_global_mutex);
>  
> -    if (r == -1 && !(e == EAGAIN || e == EINTR)) {
> -        fprintf(stderr, "sigtimedwait: %s\n", strerror(e));
> -        exit(1);
> -    }
> +        r = sigtimedwait(&waitset, &siginfo, &ts);
> +        e = errno;
> +
> +        qemu_mutex_lock(&qemu_global_mutex);
> +
> +        if (r == -1 && !(e == EAGAIN || e == EINTR)) {
> +            fprintf(stderr, "sigtimedwait: %s\n", strerror(e));
> +            exit(1);
> +        }
> +
> +        switch (r) {
> +        case SIGBUS:
> +#ifdef TARGET_I386
> +            if (kvm_on_sigbus(env, siginfo.si_code, siginfo.si_addr))
> +#endif
> +                sigbus_reraise();
> +            break;
> +        default:
> +            break;
> +        }
> +
> +        r = sigpending(&chkset);
> +        if (r == -1) {
> +            fprintf(stderr, "sigpending: %s\n", strerror(e));
> +            exit(1);
> +        }
> +    } while (sigismember(&chkset, SIG_IPI) || sigismember(&chkset, SIGBUS));
>  }
>  
>  static void qemu_kvm_wait_io_event(CPUState *env)

(snip)

> Index: qemu/kvm.h
> ===================================================================
> --- qemu.orig/kvm.h
> +++ qemu/kvm.h
> @@ -110,6 +110,9 @@ int kvm_arch_init_vcpu(CPUState *env);
>  
>  void kvm_arch_reset_vcpu(CPUState *env);
>  
> +int kvm_on_sigbus(CPUState *env, int code, void *addr);
> +int kvm_on_sigbus_vcpu(int code, void *addr);
> +
>  struct kvm_guest_debug;
>  struct kvm_debug_exit_arch;
>  

So kvm_on_sigbus() is called from qemu_kvm_eat_signal() that is
called on vcpu thread, while kvm_on_sigbus_vcpu() is called via
sigbus_handler that invoked on iothread using signalfd.

... Inverse naming?


Thanks,
H.Seto




reply via email to

[Prev in Thread] Current Thread [Next in Thread]