diff mbox

[RFC,2/5] KVM: add KVM_EXIT_MSR exit reason and capability.

Message ID 1439923615-10600-3-git-send-email-peterhornyack@google.com (mailing list archive)
State New, archived
Headers show

Commit Message

Peter Hornyack Aug. 18, 2015, 6:46 p.m. UTC
Define KVM_EXIT_MSR, a new exit reason for accesses to MSRs that kvm
does not handle. Define KVM_CAP_UNHANDLED_MSR_EXITS, a vm-wide
capability that guards the new exit reason and which can be enabled via
the KVM_ENABLE_CAP ioctl.

Signed-off-by: Peter Hornyack <peterhornyack@google.com>
---
 Documentation/virtual/kvm/api.txt | 48 +++++++++++++++++++++++++++++++++++++++
 include/uapi/linux/kvm.h          | 14 ++++++++++++
 2 files changed, 62 insertions(+)

Comments

Paolo Bonzini Dec. 18, 2015, 9:25 p.m. UTC | #1
On 18/08/2015 20:46, Peter Hornyack wrote:
> Define KVM_EXIT_MSR, a new exit reason for accesses to MSRs that kvm
> does not handle. Define KVM_CAP_UNHANDLED_MSR_EXITS, a vm-wide
> capability that guards the new exit reason and which can be enabled via
> the KVM_ENABLE_CAP ioctl.
> 
> Signed-off-by: Peter Hornyack <peterhornyack@google.com>
> ---
>  Documentation/virtual/kvm/api.txt | 48 +++++++++++++++++++++++++++++++++++++++
>  include/uapi/linux/kvm.h          | 14 ++++++++++++
>  2 files changed, 62 insertions(+)

Let's instead add:

- KVM_CAP_MSR_EXITS

- KVM_CAP_ENABLE_MSR_EXIT

- KVM_CAP_DISABLE_MSR_EXIT

and 3 kinds of exits: KVM_EXIT_MSR_READ, KVM_EXIT_MSR_WRITE,
KVM_EXIT_MSR_AFTER_WRITE.  The first two use four fields (type, msr,
data, handled) and #GP if handled=0 is zero on the next entry.  The last
one uses the first three fields and can be used for HyperV.

Paolo
--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Peter Hornyack Dec. 18, 2015, 11:56 p.m. UTC | #2
On Fri, Dec 18, 2015 at 1:25 PM, Paolo Bonzini <pbonzini@redhat.com> wrote:
>
>
> On 18/08/2015 20:46, Peter Hornyack wrote:
>> Define KVM_EXIT_MSR, a new exit reason for accesses to MSRs that kvm
>> does not handle. Define KVM_CAP_UNHANDLED_MSR_EXITS, a vm-wide
>> capability that guards the new exit reason and which can be enabled via
>> the KVM_ENABLE_CAP ioctl.
>>
>> Signed-off-by: Peter Hornyack <peterhornyack@google.com>
>> ---
>>  Documentation/virtual/kvm/api.txt | 48 +++++++++++++++++++++++++++++++++++++++
>>  include/uapi/linux/kvm.h          | 14 ++++++++++++
>>  2 files changed, 62 insertions(+)
>
> Let's instead add:
>
> - KVM_CAP_MSR_EXITS
>
> - KVM_CAP_ENABLE_MSR_EXIT
>
> - KVM_CAP_DISABLE_MSR_EXIT
>
> and 3 kinds of exits: KVM_EXIT_MSR_READ, KVM_EXIT_MSR_WRITE,
> KVM_EXIT_MSR_AFTER_WRITE.  The first two use four fields (type, msr,
> data, handled) and #GP if handled=0 is zero on the next entry.  The last
> one uses the first three fields and can be used for HyperV.
>
> Paolo

Ok. I'm working on these adjustments now, will send the updated
patchset on Monday.

Peter
--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/Documentation/virtual/kvm/api.txt b/Documentation/virtual/kvm/api.txt
index a4ebcb712375..bda540b3dd03 100644
--- a/Documentation/virtual/kvm/api.txt
+++ b/Documentation/virtual/kvm/api.txt
@@ -3302,6 +3302,36 @@  Valid values for 'type' are:
    to ignore the request, or to gather VM memory core dump and/or
    reset/shutdown of the VM.
 
+		/* KVM_EXIT_MSR */
+		struct {
+#define KVM_EXIT_MSR_RDMSR             1
+#define KVM_EXIT_MSR_WRMSR             2
+#define KVM_EXIT_MSR_COMPLETION_FAILED 3
+			__u8 direction; /* out */
+#define KVM_EXIT_MSR_UNHANDLED 1
+#define KVM_EXIT_MSR_HANDLED   2
+			__u8 handled;   /* in */
+			__u32 index;    /* i.e. ecx; out */
+			__u64 data;     /* out (wrmsr) / in (rdmsr) */
+		} msr;
+
+If exit_reason is KVM_EXIT_MSR, then the vcpu has executed a rdmsr or wrmsr
+instruction which could not be satisfied by kvm. The msr struct is used for
+both output to and input from user space. direction indicates whether the
+instruction was rdmsr or wrmsr, and index is the target MSR number held in
+ecx. User space must not modify index. data holds the payload from a wrmsr or
+must be filled in with a payload on a rdmsr.
+
+On the return path into kvm, user space should set handled to
+KVM_EXIT_MSR_HANDLED if it successfully handled the MSR access; otherwise,
+handled should be set to KVM_EXIT_MSR_UNHANDLED, which will cause a general
+protection fault to be injected into the vcpu. If an error occurs during the
+return into kvm, the vcpu will not be run and another KVM_EXIT_MSR will be
+generated with direction KVM_EXIT_MSR_COMPLETION_FAILED.
+
+KVM_EXIT_MSR can only occur when KVM_CAP_UNHANDLED_MSR_EXITS has been enabled;
+a detailed description of this capability is below.
+
 		/* Fix the size of the union. */
 		char padding[256];
 	};
@@ -3620,6 +3650,24 @@  struct {
 
 KVM handlers should exit to userspace with rc = -EREMOTE.
 
+7.5 KVM_CAP_UNHANDLED_MSR_EXITS
+
+Architectures: x86 (vmx-only)
+Parameters: args[0] enables or disables unhandled MSR exits
+Returns: 0 on success; -1 on error
+
+This capability enables exits to user space on unhandled MSR accesses.
+
+When enabled (args[0] != 0), when the guest accesses an MSR that kvm does not
+handle kvm will exit to user space with the reason KVM_EXIT_MSR. When disabled
+(by default, or with args[0] == 0), when the guest accesses an MSR that kvm
+does not handle a GP fault is immediately injected into the guest.
+
+Currently only implemented for vmx; attempts to enable this capability on svm
+systems will return an error. Also, note that this capability is overridden if
+the kvm module's ignore_msrs flag is set, in which case unhandled MSR accesses
+are simply ignored and the guest is re-entered immediately.
+
 
 8. Other capabilities.
 ----------------------
diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h
index 0d831f94f8a8..43d2d1e15ac4 100644
--- a/include/uapi/linux/kvm.h
+++ b/include/uapi/linux/kvm.h
@@ -183,6 +183,7 @@  struct kvm_s390_skeys {
 #define KVM_EXIT_EPR              23
 #define KVM_EXIT_SYSTEM_EVENT     24
 #define KVM_EXIT_S390_STSI        25
+#define KVM_EXIT_MSR              26
 
 /* For KVM_EXIT_INTERNAL_ERROR */
 /* Emulate instruction failed. */
@@ -330,6 +331,18 @@  struct kvm_run {
 			__u8 sel1;
 			__u16 sel2;
 		} s390_stsi;
+		/* KVM_EXIT_MSR */
+		struct {
+#define KVM_EXIT_MSR_RDMSR             1
+#define KVM_EXIT_MSR_WRMSR             2
+#define KVM_EXIT_MSR_COMPLETION_FAILED 3
+			__u8 direction; /* out */
+#define KVM_EXIT_MSR_UNHANDLED 1
+#define KVM_EXIT_MSR_HANDLED   2
+			__u8 handled;   /* in */
+			__u32 index;    /* i.e. ecx; out */
+			__u64 data;     /* out (wrmsr) / in (rdmsr) */
+		} msr;
 		/* Fix the size of the union. */
 		char padding[256];
 	};
@@ -819,6 +832,7 @@  struct kvm_ppc_smmu_info {
 #define KVM_CAP_DISABLE_QUIRKS 116
 #define KVM_CAP_X86_SMM 117
 #define KVM_CAP_MULTI_ADDRESS_SPACE 118
+#define KVM_CAP_UNHANDLED_MSR_EXITS 119
 
 #ifdef KVM_CAP_IRQ_ROUTING