@@ -1444,3 +1444,28 @@ register (see **KVMI_CONTROL_EVENTS**).
``kvmi_event``, the MSR number, the old value and the new value are
sent to the introspector. The *CONTINUE* action will set the ``new_val``.
+
+8. KVMI_EVENT_XSETBV
+--------------------
+
+:Architectures: x86
+:Versions: >= 1
+:Actions: CONTINUE, CRASH
+:Parameters:
+
+::
+
+ struct kvmi_event;
+
+:Returns:
+
+::
+
+ struct kvmi_vcpu_hdr;
+ struct kvmi_event_reply;
+
+This event is sent when the extended control register XCR0 is going
+to be changed and the introspection has been enabled for this event
+(see *KVMI_CONTROL_EVENTS*).
+
+``kvmi_event`` is sent to the introspector.
@@ -15,6 +15,7 @@ bool kvmi_msr_event(struct kvm_vcpu *vcpu, struct msr_data *msr);
bool kvmi_monitored_msr(struct kvm_vcpu *vcpu, u32 msr);
bool kvmi_cr_event(struct kvm_vcpu *vcpu, unsigned int cr,
unsigned long old_value, unsigned long *new_value);
+void kvmi_xsetbv_event(struct kvm_vcpu *vcpu);
#else /* CONFIG_KVM_INTROSPECTION */
@@ -35,6 +36,10 @@ static inline bool kvmi_cr_event(struct kvm_vcpu *vcpu, unsigned int cr,
return true;
}
+static inline void kvmi_xsetbv_event(struct kvm_vcpu *vcpu)
+{
+}
+
#endif /* CONFIG_KVM_INTROSPECTION */
#endif /* _ASM_X86_KVMI_HOST_H */
@@ -389,6 +389,45 @@ bool kvmi_cr_event(struct kvm_vcpu *vcpu, unsigned int cr,
return ret;
}
+static u32 kvmi_send_xsetbv(struct kvm_vcpu *vcpu)
+{
+ int err, action;
+
+ err = kvmi_send_event(vcpu, KVMI_EVENT_XSETBV, NULL, 0,
+ NULL, 0, &action);
+ if (err)
+ return KVMI_EVENT_ACTION_CONTINUE;
+
+ return action;
+}
+
+static void __kvmi_xsetbv_event(struct kvm_vcpu *vcpu)
+{
+ u32 action;
+
+ action = kvmi_send_xsetbv(vcpu);
+ switch (action) {
+ case KVMI_EVENT_ACTION_CONTINUE:
+ break;
+ default:
+ kvmi_handle_common_event_actions(vcpu, action, "XSETBV");
+ }
+}
+
+void kvmi_xsetbv_event(struct kvm_vcpu *vcpu)
+{
+ struct kvmi *ikvm;
+
+ ikvm = kvmi_get(vcpu->kvm);
+ if (!ikvm)
+ return;
+
+ if (is_event_enabled(vcpu, KVMI_EVENT_XSETBV))
+ __kvmi_xsetbv_event(vcpu);
+
+ kvmi_put(vcpu->kvm);
+}
+
bool kvmi_arch_pf_event(struct kvm_vcpu *vcpu, gpa_t gpa, gva_t gva,
u8 access)
{
@@ -868,6 +868,11 @@ static int __kvm_set_xcr(struct kvm_vcpu *vcpu, u32 index, u64 xcr)
int kvm_set_xcr(struct kvm_vcpu *vcpu, u32 index, u64 xcr)
{
+#ifdef CONFIG_KVM_INTROSPECTION
+ if (xcr != vcpu->arch.xcr0)
+ kvmi_xsetbv_event(vcpu);
+#endif /* CONFIG_KVM_INTROSPECTION */
+
if (kvm_x86_ops->get_cpl(vcpu) != 0 ||
__kvm_set_xcr(vcpu, index, xcr)) {
kvm_inject_gp(vcpu, 0);