It is intended to be used only during startup, typically by a launcher that is aware which MSRs should be emulated as no-ops. On Wed, Oct 28, 2009 at 2:28 PM, Richard Winthers <rwinthers@xxxxxxxxx> wrote: > Is this interface supposed to support changing MSR handing at runtime or is > the ioctl only meant to be called prior to KVM_RUN? > Thanks, > Richard > On Wed, Oct 28, 2009 at 1:23 PM, David Windsor <dwindsor@xxxxxxxxx> wrote: >> >> Hi, >> >> I've encountered a situation in which I would like to allow userspace >> to set the MSRs which KVM should not emulate and instead implement >> these as no-ops. >> >> I have not seen any work in this space, furthermore there is an item >> on the KVM TODO that is very similar to what I'm trying to do. >> >> The userspace interface is an extension of kvm_vcpu_ioctl, adding the >> KVM_SET_MSRS_NOOP flag. It takes a struct kvm_msrs as a list of which >> MSRs should be no-ops and adds the field noop to struct kvm_msr_entry. >> This patch only affects vmx, but if the approach is sane, I can >> extend it to support svm as well. >> >> >> >> diff -purN linux-2.6.32-rc5/arch/x86/include/asm/kvm.h >> linux-2.6.32-rc5-kvm-msrs-noop/arch/x86/include/asm/kvm.h >> --- linux-2.6.32-rc5/arch/x86/include/asm/kvm.h 2009-10-15 >> 20:41:50.000000000 -0400 >> +++ linux-2.6.32-rc5-kvm-msrs-noop/arch/x86/include/asm/kvm.h 2009-10-27 >> 22:44:58.000000000 -0400 >> @@ -144,6 +144,7 @@ struct kvm_msr_entry { >> __u32 index; >> __u32 reserved; >> __u64 data; >> + __u8 noop; >> }; >> >> /* for KVM_GET_MSRS and KVM_SET_MSRS */ >> diff -purN linux-2.6.32-rc5/arch/x86/include/asm/kvm_host.h >> linux-2.6.32-rc5-kvm-msrs-noop/arch/x86/include/asm/kvm_host.h >> --- linux-2.6.32-rc5/arch/x86/include/asm/kvm_host.h 2009-10-15 >> 20:41:50.000000000 -0400 >> +++ linux-2.6.32-rc5-kvm-msrs-noop/arch/x86/include/asm/kvm_host.h >> 2009-10-27 >> 22:44:58.000000000 -0400 >> @@ -481,6 +481,7 @@ struct kvm_x86_ops { >> struct kvm_guest_debug *dbg); >> int (*get_msr)(struct kvm_vcpu *vcpu, u32 msr_index, u64 *pdata); >> int (*set_msr)(struct kvm_vcpu *vcpu, u32 msr_index, u64 data); >> + int (*set_msr_noop)(struct kvm_vcpu *vcpu, u32 msr_index); >> u64 (*get_segment_base)(struct kvm_vcpu *vcpu, int seg); >> void (*get_segment)(struct kvm_vcpu *vcpu, >> struct kvm_segment *var, int seg); >> diff -purN linux-2.6.32-rc5/arch/x86/kvm/vmx.c >> linux-2.6.32-rc5-kvm-msrs-noop/arch/x86/kvm/vmx.c >> --- linux-2.6.32-rc5/arch/x86/kvm/vmx.c 2009-10-15 20:41:50.000000000 >> -0400 >> +++ linux-2.6.32-rc5-kvm-msrs-noop/arch/x86/kvm/vmx.c 2009-10-27 >> 22:44:58.000000000 -0400 >> @@ -983,6 +983,13 @@ static int vmx_get_msr(struct kvm_vcpu * >> return -EINVAL; >> } >> >> + msr = find_msr_entry(to_vmx(vcpu), msr_index); >> + if (msr) { >> + if (msr->noop) { >> + return 0; >> + } >> + } >> + >> switch (msr_index) { >> #ifdef CONFIG_X86_64 >> case MSR_FS_BASE: >> @@ -1032,6 +1039,13 @@ static int vmx_set_msr(struct kvm_vcpu * >> u64 host_tsc; >> int ret = 0; >> >> + msr = find_msr_entry(to_vmx(vcpu), msr_index); >> + if (msr) { >> + if (msr->noop) { >> + return ret; >> + } >> + } >> + >> switch (msr_index) { >> case MSR_EFER: >> vmx_load_host_state(vmx); >> @@ -1078,6 +1092,21 @@ static int vmx_set_msr(struct kvm_vcpu * >> return ret; >> } >> >> +static int vmx_set_msr_noop(struct kvm_vcpu *vcpu, u32 msr) >> +{ >> + struct kvm_msr_entry *m; >> + >> + if (!vcpu) >> + return -1; >> + >> + m = find_msr_entry(to_vmx(vcpu), msr); >> + if (!m) >> + return -1; >> + >> + m->noop = 1; >> + return 0; >> +} >> + >> static void vmx_cache_reg(struct kvm_vcpu *vcpu, enum kvm_reg reg) >> { >> __set_bit(reg, (unsigned long *)&vcpu->arch.regs_avail); >> @@ -3942,6 +3971,7 @@ static struct kvm_x86_ops vmx_x86_ops = >> .set_guest_debug = set_guest_debug, >> .get_msr = vmx_get_msr, >> .set_msr = vmx_set_msr, >> + .set_msr_noop = vmx_set_msr_noop, >> .get_segment_base = vmx_get_segment_base, >> .get_segment = vmx_get_segment, >> .set_segment = vmx_set_segment, >> diff -purN linux-2.6.32-rc5/arch/x86/kvm/x86.c >> linux-2.6.32-rc5-kvm-msrs-noop/arch/x86/kvm/x86.c >> --- linux-2.6.32-rc5/arch/x86/kvm/x86.c 2009-10-15 20:41:50.000000000 >> -0400 >> +++ linux-2.6.32-rc5-kvm-msrs-noop/arch/x86/kvm/x86.c 2009-10-27 >> 22:44:58.000000000 -0400 >> @@ -975,6 +975,31 @@ int kvm_get_msr(struct kvm_vcpu *vcpu, u >> return kvm_x86_ops->get_msr(vcpu, msr_index, pdata); >> } >> >> +static int kvm_set_msrs_noop(struct kvm_vcpu *vcpu, struct kvm_msrs >> __user *user_msrs) >> +{ >> + int i, r; >> + int size; >> + struct kvm_msrs msrs; >> + struct kvm_msr_entry *entries; >> + >> + if (copy_from_user(&msrs, user_msrs, sizeof msrs)) >> + goto out; >> + >> + size = sizeof(struct kvm_msr_entry) * msrs.nmsrs; >> + if (copy_from_user(entries, user_msrs->entries, size)) >> + goto out; >> + >> + for (i = 0; i < msrs.nmsrs; i++) { >> + r = kvm_x86_ops->set_msr_noop(vcpu, entries[i].index); >> + if (r) >> + goto out; >> + } >> + >> + return 0; >> +out: >> + return -1; >> +} >> + >> static int get_msr_mtrr(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata) >> { >> u64 *p = (u64 *)&vcpu->arch.mtrr_state.fixed_ranges; >> @@ -1864,6 +1889,9 @@ long kvm_arch_vcpu_ioctl(struct file *fi >> case KVM_SET_MSRS: >> r = msr_io(vcpu, argp, do_set_msr, 0); >> break; >> + case KVM_SET_MSRS_NOOP: >> + r = kvm_set_msrs_noop(vcpu, argp); >> + break; >> case KVM_TPR_ACCESS_REPORTING: { >> struct kvm_tpr_access_ctl tac; >> >> diff -purN linux-2.6.32-rc5/include/linux/kvm.h >> linux-2.6.32-rc5-kvm-msrs-noop/include/linux/kvm.h >> --- linux-2.6.32-rc5/include/linux/kvm.h 2009-10-15 >> 20:41:50.000000000 -0400 >> +++ linux-2.6.32-rc5-kvm-msrs-noop/include/linux/kvm.h 2009-10-27 >> 22:46:36.000000000 -0400 >> @@ -593,6 +593,7 @@ struct kvm_irqfd { >> #define KVM_X86_SETUP_MCE _IOW(KVMIO, 0x9c, __u64) >> #define KVM_X86_GET_MCE_CAP_SUPPORTED _IOR(KVMIO, 0x9d, __u64) >> #define KVM_X86_SET_MCE _IOW(KVMIO, 0x9e, struct kvm_x86_mce) >> +#define KVM_SET_MSRS_NOOP _IOW(KVMIO, 0x9f, struct kvm_msrs) >> >> /* >> * Deprecated interfaces >> -- >> To unsubscribe from this list: send the line "unsubscribe kvm" in >> the body of a message to majordomo@xxxxxxxxxxxxxxx >> More majordomo info at http://vger.kernel.org/majordomo-info.html > > -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html