lkml.org 
[lkml]   [2007]   [Mar]   [11]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 13/15] KVM: Add guest mode signal mask
    Date
    Allow a special signal mask to be used while executing in guest mode.  This
    allows signals to be used to interrupt a vcpu without requiring signal
    delivery to a userspace handler, which is quite expensive. Userspace still
    receives -EINTR and can get the signal via sigwait().

    Signed-off-by: Avi Kivity <avi@qumranet.com>
    ---
    drivers/kvm/kvm.h | 3 +++
    drivers/kvm/kvm_main.c | 41 +++++++++++++++++++++++++++++++++++++++++
    include/linux/kvm.h | 7 +++++++
    3 files changed, 51 insertions(+), 0 deletions(-)

    diff --git a/drivers/kvm/kvm.h b/drivers/kvm/kvm.h
    index be3a0e7..1c4a581 100644
    --- a/drivers/kvm/kvm.h
    +++ b/drivers/kvm/kvm.h
    @@ -277,6 +277,9 @@ struct kvm_vcpu {
    gpa_t mmio_phys_addr;
    int pio_pending;

    + int sigset_active;
    + sigset_t sigset;
    +
    struct {
    int active;
    u8 save_iopl;
    diff --git a/drivers/kvm/kvm_main.c b/drivers/kvm/kvm_main.c
    index 0e28f58..ed95c9b 100644
    --- a/drivers/kvm/kvm_main.c
    +++ b/drivers/kvm/kvm_main.c
    @@ -1591,9 +1591,13 @@ static void complete_pio(struct kvm_vcpu *vcpu)
    static int kvm_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
    {
    int r;
    + sigset_t sigsaved;

    vcpu_load(vcpu);

    + if (vcpu->sigset_active)
    + sigprocmask(SIG_SETMASK, &vcpu->sigset, &sigsaved);
    +
    /* re-sync apic's tpr */
    vcpu->cr8 = kvm_run->cr8;

    @@ -1616,6 +1620,9 @@ static int kvm_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)

    r = kvm_arch_ops->run(vcpu, kvm_run);

    + if (vcpu->sigset_active)
    + sigprocmask(SIG_SETMASK, &sigsaved, NULL);
    +
    vcpu_put(vcpu);
    return r;
    }
    @@ -2142,6 +2149,17 @@ out:
    return r;
    }

    +static int kvm_vcpu_ioctl_set_sigmask(struct kvm_vcpu *vcpu, sigset_t *sigset)
    +{
    + if (sigset) {
    + sigdelsetmask(sigset, sigmask(SIGKILL)|sigmask(SIGSTOP));
    + vcpu->sigset_active = 1;
    + vcpu->sigset = *sigset;
    + } else
    + vcpu->sigset_active = 0;
    + return 0;
    +}
    +
    static long kvm_vcpu_ioctl(struct file *filp,
    unsigned int ioctl, unsigned long arg)
    {
    @@ -2260,6 +2278,29 @@ static long kvm_vcpu_ioctl(struct file *filp,
    goto out;
    break;
    }
    + case KVM_SET_SIGNAL_MASK: {
    + struct kvm_signal_mask __user *sigmask_arg = argp;
    + struct kvm_signal_mask kvm_sigmask;
    + sigset_t sigset, *p;
    +
    + p = NULL;
    + if (argp) {
    + r = -EFAULT;
    + if (copy_from_user(&kvm_sigmask, argp,
    + sizeof kvm_sigmask))
    + goto out;
    + r = -EINVAL;
    + if (kvm_sigmask.len != sizeof sigset)
    + goto out;
    + r = -EFAULT;
    + if (copy_from_user(&sigset, sigmask_arg->sigset,
    + sizeof sigset))
    + goto out;
    + p = &sigset;
    + }
    + r = kvm_vcpu_ioctl_set_sigmask(vcpu, &sigset);
    + break;
    + }
    default:
    ;
    }
    diff --git a/include/linux/kvm.h b/include/linux/kvm.h
    index b3af92e..c0d10cd 100644
    --- a/include/linux/kvm.h
    +++ b/include/linux/kvm.h
    @@ -234,6 +234,12 @@ struct kvm_cpuid {
    struct kvm_cpuid_entry entries[0];
    };

    +/* for KVM_SET_SIGNAL_MASK */
    +struct kvm_signal_mask {
    + __u32 len;
    + __u8 sigset[0];
    +};
    +
    #define KVMIO 0xAE

    /*
    @@ -273,5 +279,6 @@ struct kvm_cpuid {
    #define KVM_GET_MSRS _IOWR(KVMIO, 0x88, struct kvm_msrs)
    #define KVM_SET_MSRS _IOW(KVMIO, 0x89, struct kvm_msrs)
    #define KVM_SET_CPUID _IOW(KVMIO, 0x8a, struct kvm_cpuid)
    +#define KVM_SET_SIGNAL_MASK _IOW(KVMIO, 0x8b, struct kvm_signal_mask)

    #endif
    --
    1.5.0.2
    -
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

    \
     
     \ /
      Last update: 2007-03-11 14:59    [W:0.025 / U:90.776 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site