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 <peterhorny...@google.com>
---
 Documentation/virtual/kvm/api.txt | 48 +++++++++++++++++++++++++++++++++++++++
 include/uapi/linux/kvm.h          | 14 ++++++++++++
 2 files changed, 62 insertions(+)

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
 
-- 
2.5.0.276.gf5e568e

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

Reply via email to