mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-11-25 08:40:53 +07:00
KVM: Add guest mode signal mask
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>
This commit is contained in:
parent
6722c51c51
commit
1961d276c8
@ -277,6 +277,9 @@ struct kvm_vcpu {
|
|||||||
gpa_t mmio_phys_addr;
|
gpa_t mmio_phys_addr;
|
||||||
int pio_pending;
|
int pio_pending;
|
||||||
|
|
||||||
|
int sigset_active;
|
||||||
|
sigset_t sigset;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
int active;
|
int active;
|
||||||
u8 save_iopl;
|
u8 save_iopl;
|
||||||
|
@ -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)
|
static int kvm_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
|
||||||
{
|
{
|
||||||
int r;
|
int r;
|
||||||
|
sigset_t sigsaved;
|
||||||
|
|
||||||
vcpu_load(vcpu);
|
vcpu_load(vcpu);
|
||||||
|
|
||||||
|
if (vcpu->sigset_active)
|
||||||
|
sigprocmask(SIG_SETMASK, &vcpu->sigset, &sigsaved);
|
||||||
|
|
||||||
/* re-sync apic's tpr */
|
/* re-sync apic's tpr */
|
||||||
vcpu->cr8 = kvm_run->cr8;
|
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);
|
r = kvm_arch_ops->run(vcpu, kvm_run);
|
||||||
|
|
||||||
|
if (vcpu->sigset_active)
|
||||||
|
sigprocmask(SIG_SETMASK, &sigsaved, NULL);
|
||||||
|
|
||||||
vcpu_put(vcpu);
|
vcpu_put(vcpu);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
@ -2142,6 +2149,17 @@ static int kvm_vcpu_ioctl_set_cpuid(struct kvm_vcpu *vcpu,
|
|||||||
return r;
|
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,
|
static long kvm_vcpu_ioctl(struct file *filp,
|
||||||
unsigned int ioctl, unsigned long arg)
|
unsigned int ioctl, unsigned long arg)
|
||||||
{
|
{
|
||||||
@ -2260,6 +2278,29 @@ static long kvm_vcpu_ioctl(struct file *filp,
|
|||||||
goto out;
|
goto out;
|
||||||
break;
|
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:
|
default:
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
@ -234,6 +234,12 @@ struct kvm_cpuid {
|
|||||||
struct kvm_cpuid_entry entries[0];
|
struct kvm_cpuid_entry entries[0];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* for KVM_SET_SIGNAL_MASK */
|
||||||
|
struct kvm_signal_mask {
|
||||||
|
__u32 len;
|
||||||
|
__u8 sigset[0];
|
||||||
|
};
|
||||||
|
|
||||||
#define KVMIO 0xAE
|
#define KVMIO 0xAE
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -273,5 +279,6 @@ struct kvm_cpuid {
|
|||||||
#define KVM_GET_MSRS _IOWR(KVMIO, 0x88, struct kvm_msrs)
|
#define KVM_GET_MSRS _IOWR(KVMIO, 0x88, struct kvm_msrs)
|
||||||
#define KVM_SET_MSRS _IOW(KVMIO, 0x89, 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_CPUID _IOW(KVMIO, 0x8a, struct kvm_cpuid)
|
||||||
|
#define KVM_SET_SIGNAL_MASK _IOW(KVMIO, 0x8b, struct kvm_signal_mask)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user