This patch adds a file named lazy_tscdeadline, in kvm debugfs vcpu directory to get the state. And also, if you write to it, it will trigger a lazy_tscdeadline kick forcily which can rescue the guest if the feature fall into bug. Signed-off-by: Wang Jianchao <jianchwa@xxxxxxxxxxx> --- arch/x86/kvm/debugfs.c | 80 +++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 79 insertions(+), 1 deletion(-) diff --git a/arch/x86/kvm/debugfs.c b/arch/x86/kvm/debugfs.c index ee8c4c3..fbd6552 100644 --- a/arch/x86/kvm/debugfs.c +++ b/arch/x86/kvm/debugfs.c @@ -56,6 +56,79 @@ static int vcpu_get_tsc_scaling_frac_bits(void *data, u64 *val) DEFINE_SIMPLE_ATTRIBUTE(vcpu_tsc_scaling_frac_fops, vcpu_get_tsc_scaling_frac_bits, NULL, "%llu\n"); +static int vcpu_lazy_tscddl_show(struct seq_file *m, void *v) +{ + struct kvm_vcpu *vcpu = m->private; + + if (vcpu->arch.pv_cpuid.features & (1UL << KVM_FEATURE_LAZY_TSCDEADLINE)) { + struct kvm_host_lazy_tscdeadline *hlt = &vcpu->arch.lazy_tscdeadline; + if (!(hlt->msr_val & KVM_MSR_ENABLED) || + !hlt->guest) + seq_printf(m, "not open in guest\n"); + else + seq_printf(m, "pending %llu armed %llu\n", + hlt->guest->pending, hlt->guest->armed); + } else { + seq_printf(m, "not enable in cpuid\n"); + } + + return 0; +} + +static int vcpu_lazy_tscdeadline_open(struct inode *inode, struct file *file) +{ + struct kvm_vcpu *vcpu = inode->i_private; + struct kvm *kvm = vcpu->kvm; + int ret; + + if (!kvm_get_kvm_safe(kvm)) + return -ENOENT; + + ret = single_open(file, vcpu_lazy_tscddl_show, vcpu); + if (ret < 0) + kvm_put_kvm(kvm); + + return 0; +} + +static ssize_t vcpu_lazy_tscdeadline_write(struct file *file, const char __user *buf, + size_t count, loff_t *ppos) +{ + struct seq_file *m = file->private_data; + struct kvm_vcpu *vcpu = m->private; + struct kvm_host_lazy_tscdeadline *hlt = &vcpu->arch.lazy_tscdeadline; + + if (!(hlt->msr_val & KVM_MSR_ENABLED) || + !hlt->guest) + goto out; + + /* + * Force to kick the tscdeadline timer to rescue the vcpu + */ + kvm_make_request(KVM_REQ_LAZY_TSCDEADLINE, vcpu); + kvm_vcpu_kick(vcpu); +out: + return count; +} + +static int vcpu_lazy_tscdeadline_release(struct inode *inode, struct file *file) +{ + struct kvm_vcpu *vcpu = inode->i_private; + struct kvm *kvm = vcpu->kvm; + + kvm_put_kvm(kvm); + + return 0; +} + +static const struct file_operations vcpu_lazy_tscdeadline_fops = { + .open = vcpu_lazy_tscdeadline_open, + .read = seq_read, + .write = vcpu_lazy_tscdeadline_write, + .llseek = seq_lseek, + .release = vcpu_lazy_tscdeadline_release, +}; + void kvm_arch_create_vcpu_debugfs(struct kvm_vcpu *vcpu, struct dentry *debugfs_dentry) { debugfs_create_file("guest_mode", 0444, debugfs_dentry, vcpu, @@ -63,11 +136,16 @@ void kvm_arch_create_vcpu_debugfs(struct kvm_vcpu *vcpu, struct dentry *debugfs_ debugfs_create_file("tsc-offset", 0444, debugfs_dentry, vcpu, &vcpu_tsc_offset_fops); - if (lapic_in_kernel(vcpu)) + if (lapic_in_kernel(vcpu)) { debugfs_create_file("lapic_timer_advance_ns", 0444, debugfs_dentry, vcpu, &vcpu_timer_advance_ns_fops); + debugfs_create_file("lazy_tscdeadline", 0644, + debugfs_dentry, vcpu, + &vcpu_lazy_tscdeadline_fops); + } + if (kvm_caps.has_tsc_control) { debugfs_create_file("tsc-scaling-ratio", 0444, debugfs_dentry, vcpu, -- 2.7.4