From: David Windsor <dwindso3@jhu.edu>
To: kvm@vger.kernel.org
Subject: [RFC] allow userspace to set MSR no-ops
Date: Wed, 28 Oct 2009 14:06:18 -0400 [thread overview]
Message-ID: <f5a4be2d354c.4ae84fda@johnshopkins.edu> (raw)
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
next reply other threads:[~2009-10-28 19:06 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-10-28 18:06 David Windsor [this message]
-- strict thread matches above, loose matches on Subject: below --
2009-10-28 17:23 [RFC] allow userspace to set MSR no-ops David Windsor
2009-10-28 18:31 ` Richard Winthers
[not found] ` <944f46790910281128j345c13adre8d0dc533bc4abb1@mail.gmail.com>
2009-10-28 21:04 ` David Windsor
2009-11-03 15:12 ` Marcelo Tosatti
2009-11-04 9:10 ` Avi Kivity
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=f5a4be2d354c.4ae84fda@johnshopkins.edu \
--to=dwindso3@jhu.edu \
--cc=kvm@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox