qemu-devel
[Top][All Lists]
Advanced

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

Re: [Qemu-devel] [question] mask SIGBUS in qemu main thread


From: gengdongjiu
Subject: Re: [Qemu-devel] [question] mask SIGBUS in qemu main thread
Date: Mon, 20 Nov 2017 21:32:34 +0800
User-agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:52.0) Gecko/20100101 Thunderbird/52.3.0

On 2017/11/20 21:00, Peter Maydell wrote:
> On 20 November 2017 at 12:50, Alex Bennée <address@hidden> wrote:
>> What exactly do you expect the main thread to do with a SIGBUS signal?
> 
> For KVM, we (can) use SIGBUS for handling machine check exceptions:
> see qemu_init_sigbus() in cpus.c, where we use prctl(PR_MCE_KILL)
> to ask the host kernel to send us a SIGBUS if the memory used
> by the VM has memory corruption detected by the hardwar. This
> then lets us inform the guest (see kvm_mce_inject() in target/i386).
> (This will probably be coming to Arm KVM at some point, as part
> of the RAS extension support. See various threads in kvmarm list.)

thanks, yes, indeed.

when the RAS is enabled, if a guest memory address is corruption, host will 
unmap the stage2 mapping and try to find a Qemu thread to
deliver the SIGBUS signal[1]. when Qemu receive the signal, it will try to do 
some recovery for guest.
such as kvm_mce_inject() in target/i386.

In host kernel[1], if the flag  set MF_ACTION_REQUIRED, host will find current 
vcpu thread to deliver SIGBUS with si_code BUS_MCEERR_AR
Otherwise it will  find Qemu main thread to deliver the SIGBUS with si_code 
BUS_MCEERR_AO
For this case, Qemu will block this SIGBUS and this signal will be always 
pending.

For the KVM[2], it does not matter, because KVM will choose the current vcpu 
thread to deliver SIGBUS, not the main Qemu thread.


[1]
static int kill_proc(struct task_struct *t, unsigned long addr, int trapno,
                        unsigned long pfn, struct page *page, int flags)
        ..................
        if ((flags & MF_ACTION_REQUIRED) && t->mm == current->mm) {
                si.si_code = BUS_MCEERR_AR;
                ret = force_sig_info(SIGBUS, &si, current);
        } else {
                /*
                 * Don't use force here, it's convenient if the signal
                 * can be temporarily blocked.
                 * This could cause a loop when the user sets SIGBUS
                 * to SIG_IGN, but hopefully no one will do that?
                 */
                si.si_code = BUS_MCEERR_AO;
                ret = send_sig_info(SIGBUS, &si, t);  /* synchronous? */
        }
}


[2]
static void kvm_send_hwpoison_signal(unsigned long address,
                                     struct vm_area_struct *vma)
{
        siginfo_t info;

        info.si_signo   = SIGBUS;
        info.si_errno   = 0;
        info.si_code    = BUS_MCEERR_AR;
        info.si_addr    = (void __user *)address;

        if (is_vm_hugetlb_page(vma))
                info.si_addr_lsb = huge_page_shift(hstate_vma(vma));
        else
                info.si_addr_lsb = PAGE_SHIFT;

        send_sig_info(SIGBUS, &info, current);
}

> 
> Because asynchronous signals are a pain to deal with, for the
> main thread we handle all our signals via signalfd(), which is
> why the main thread shows SIGBUS as blocked. The main thread
> will pick the signal up via the fd at some point. For KVM vcpu
> threads, the signal arrives asynchronously. See sigbus_handler()
> in cpus.c.

thanks Pether's explanation.
yes, you are right.

> 
> thanks
> -- PMM
> 
> 




reply via email to

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