Commit 1c0b28c2 authored by Eric B Munson's avatar Eric B Munson Committed by Avi Kivity

KVM: x86: Add ioctl for KVM_KVMCLOCK_CTRL

Now that we have a flag that will tell the guest it was suspended, create an
interface for that communication using a KVM ioctl.
Signed-off-by: default avatarEric B Munson <emunson@mgebm.net>
Signed-off-by: default avatarMarcelo Tosatti <mtosatti@redhat.com>
Signed-off-by: default avatarAvi Kivity <avi@redhat.com>
parent 3b5d56b9
...@@ -1669,6 +1669,26 @@ at the memory location pointed to by "addr". ...@@ -1669,6 +1669,26 @@ at the memory location pointed to by "addr".
The list of registers accessible using this interface is identical to the The list of registers accessible using this interface is identical to the
list in 4.64. list in 4.64.
4.70 KVM_KVMCLOCK_CTRL
Capability: KVM_CAP_KVMCLOCK_CTRL
Architectures: Any that implement pvclocks (currently x86 only)
Type: vcpu ioctl
Parameters: None
Returns: 0 on success, -1 on error
This signals to the host kernel that the specified guest is being paused by
userspace. The host will set a flag in the pvclock structure that is checked
from the soft lockup watchdog. The flag is part of the pvclock structure that
is shared between guest and host, specifically the second bit of the flags
field of the pvclock_vcpu_time_info structure. It will be set exclusively by
the host and read/cleared exclusively by the guest. The guest operation of
checking and clearing the flag must an atomic operation so
load-link/store-conditional, or equivalent must be used. There are two cases
where the guest will clear the flag: when the soft lockup watchdog timer resets
itself or when a soft lockup is detected. This ioctl can be called any time
after pausing the vcpu, but before it is resumed.
5. The kvm_run structure 5. The kvm_run structure
Application code obtains a pointer to the kvm_run structure by Application code obtains a pointer to the kvm_run structure by
......
...@@ -108,6 +108,10 @@ MSR_KVM_SYSTEM_TIME_NEW: 0x4b564d01 ...@@ -108,6 +108,10 @@ MSR_KVM_SYSTEM_TIME_NEW: 0x4b564d01
| | time measures taken across | | time measures taken across
0 | 24 | multiple cpus are guaranteed to 0 | 24 | multiple cpus are guaranteed to
| | be monotonic | | be monotonic
-------------------------------------------------------------
| | guest vcpu has been paused by
1 | N/A | the host
| | See 4.70 in api.txt
------------------------------------------------------------- -------------------------------------------------------------
Availability of this MSR must be checked via bit 3 in 0x4000001 cpuid Availability of this MSR must be checked via bit 3 in 0x4000001 cpuid
......
...@@ -2147,6 +2147,7 @@ int kvm_dev_ioctl_check_extension(long ext) ...@@ -2147,6 +2147,7 @@ int kvm_dev_ioctl_check_extension(long ext)
case KVM_CAP_ASYNC_PF: case KVM_CAP_ASYNC_PF:
case KVM_CAP_GET_TSC_KHZ: case KVM_CAP_GET_TSC_KHZ:
case KVM_CAP_PCI_2_3: case KVM_CAP_PCI_2_3:
case KVM_CAP_KVMCLOCK_CTRL:
r = 1; r = 1;
break; break;
case KVM_CAP_COALESCED_MMIO: case KVM_CAP_COALESCED_MMIO:
...@@ -2597,6 +2598,23 @@ static int kvm_vcpu_ioctl_x86_set_xcrs(struct kvm_vcpu *vcpu, ...@@ -2597,6 +2598,23 @@ static int kvm_vcpu_ioctl_x86_set_xcrs(struct kvm_vcpu *vcpu,
return r; return r;
} }
/*
* kvm_set_guest_paused() indicates to the guest kernel that it has been
* stopped by the hypervisor. This function will be called from the host only.
* EINVAL is returned when the host attempts to set the flag for a guest that
* does not support pv clocks.
*/
static int kvm_set_guest_paused(struct kvm_vcpu *vcpu)
{
struct pvclock_vcpu_time_info *src = &vcpu->arch.hv_clock;
if (!vcpu->arch.time_page)
return -EINVAL;
src->flags |= PVCLOCK_GUEST_STOPPED;
mark_page_dirty(vcpu->kvm, vcpu->arch.time >> PAGE_SHIFT);
kvm_make_request(KVM_REQ_CLOCK_UPDATE, vcpu);
return 0;
}
long kvm_arch_vcpu_ioctl(struct file *filp, long kvm_arch_vcpu_ioctl(struct file *filp,
unsigned int ioctl, unsigned long arg) unsigned int ioctl, unsigned long arg)
{ {
...@@ -2873,6 +2891,10 @@ long kvm_arch_vcpu_ioctl(struct file *filp, ...@@ -2873,6 +2891,10 @@ long kvm_arch_vcpu_ioctl(struct file *filp,
r = vcpu->arch.virtual_tsc_khz; r = vcpu->arch.virtual_tsc_khz;
goto out; goto out;
} }
case KVM_KVMCLOCK_CTRL: {
r = kvm_set_guest_paused(vcpu);
goto out;
}
default: default:
r = -EINVAL; r = -EINVAL;
} }
......
...@@ -589,6 +589,7 @@ struct kvm_ppc_pvinfo { ...@@ -589,6 +589,7 @@ struct kvm_ppc_pvinfo {
#define KVM_CAP_S390_UCONTROL 73 #define KVM_CAP_S390_UCONTROL 73
#define KVM_CAP_SYNC_REGS 74 #define KVM_CAP_SYNC_REGS 74
#define KVM_CAP_PCI_2_3 75 #define KVM_CAP_PCI_2_3 75
#define KVM_CAP_KVMCLOCK_CTRL 76
#ifdef KVM_CAP_IRQ_ROUTING #ifdef KVM_CAP_IRQ_ROUTING
...@@ -859,6 +860,8 @@ struct kvm_s390_ucas_mapping { ...@@ -859,6 +860,8 @@ struct kvm_s390_ucas_mapping {
/* Available with KVM_CAP_ONE_REG */ /* Available with KVM_CAP_ONE_REG */
#define KVM_GET_ONE_REG _IOW(KVMIO, 0xab, struct kvm_one_reg) #define KVM_GET_ONE_REG _IOW(KVMIO, 0xab, struct kvm_one_reg)
#define KVM_SET_ONE_REG _IOW(KVMIO, 0xac, struct kvm_one_reg) #define KVM_SET_ONE_REG _IOW(KVMIO, 0xac, struct kvm_one_reg)
/* VM is being stopped by host */
#define KVM_KVMCLOCK_CTRL _IO(KVMIO, 0xad)
#define KVM_DEV_ASSIGN_ENABLE_IOMMU (1 << 0) #define KVM_DEV_ASSIGN_ENABLE_IOMMU (1 << 0)
#define KVM_DEV_ASSIGN_PCI_2_3 (1 << 1) #define KVM_DEV_ASSIGN_PCI_2_3 (1 << 1)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment