return false;
}
-void recalc_intercepts(struct vcpu_svm *svm)
+void nested_vmcb02_recalc_intercepts(struct vcpu_svm *svm)
{
struct vmcb_control_area *c, *h;
struct vmcb_ctrl_area_cached *g;
unsigned int i;
- vmcb_mark_dirty(svm->vmcb01.ptr, VMCB_INTERCEPTS);
-
- if (!is_guest_mode(&svm->vcpu))
- return;
-
vmcb_mark_dirty(svm->vmcb, VMCB_INTERCEPTS);
c = &svm->vmcb->control;
* Merge guest and host intercepts - must be called with vcpu in
* guest-mode to take effect.
*/
- recalc_intercepts(svm);
+ svm_mark_intercepts_dirty(svm);
}
static void nested_svm_copy_common_state(struct vmcb *from_vmcb, struct vmcb *to_vmcb)
vmcb_set_intercept(&vmcb->control, INTERCEPT_DR7_READ);
vmcb_set_intercept(&vmcb->control, INTERCEPT_DR7_WRITE);
- recalc_intercepts(svm);
+ svm_mark_intercepts_dirty(svm);
}
static void clr_dr_intercepts(struct vcpu_svm *svm)
vmcb->control.intercepts[INTERCEPT_DR] = 0;
- recalc_intercepts(svm);
+ svm_mark_intercepts_dirty(svm);
}
static bool msr_write_intercepted(struct kvm_vcpu *vcpu, u32 msr)
DECLARE_PER_CPU(struct svm_cpu_data, svm_data);
-void recalc_intercepts(struct vcpu_svm *svm);
-
static __always_inline struct kvm_svm *to_kvm_svm(struct kvm *kvm)
{
return container_of(kvm, struct kvm_svm, kvm);
return __vmcb_is_intercept((unsigned long *)&control->intercepts, bit);
}
+void nested_vmcb02_recalc_intercepts(struct vcpu_svm *svm);
+
+static inline void svm_mark_intercepts_dirty(struct vcpu_svm *svm)
+{
+ vmcb_mark_dirty(svm->vmcb01.ptr, VMCB_INTERCEPTS);
+
+ /*
+ * If L2 is active, recalculate the intercepts for vmcb02 to account
+ * for the changes made to vmcb01. All intercept configuration is done
+ * for vmcb01 and then propagated to vmcb02 to combine KVM's intercepts
+ * with L1's intercepts (from the vmcb12 snapshot).
+ */
+ if (is_guest_mode(&svm->vcpu))
+ nested_vmcb02_recalc_intercepts(svm);
+}
+
static inline void set_exception_intercept(struct vcpu_svm *svm, u32 bit)
{
struct vmcb *vmcb = svm->vmcb01.ptr;
WARN_ON_ONCE(bit >= 32);
vmcb_set_intercept(&vmcb->control, INTERCEPT_EXCEPTION_OFFSET + bit);
- recalc_intercepts(svm);
+ svm_mark_intercepts_dirty(svm);
}
static inline void clr_exception_intercept(struct vcpu_svm *svm, u32 bit)
WARN_ON_ONCE(bit >= 32);
vmcb_clr_intercept(&vmcb->control, INTERCEPT_EXCEPTION_OFFSET + bit);
- recalc_intercepts(svm);
+ svm_mark_intercepts_dirty(svm);
}
static inline void svm_set_intercept(struct vcpu_svm *svm, int bit)
vmcb_set_intercept(&vmcb->control, bit);
- recalc_intercepts(svm);
+ svm_mark_intercepts_dirty(svm);
}
static inline void svm_clr_intercept(struct vcpu_svm *svm, int bit)
vmcb_clr_intercept(&vmcb->control, bit);
- recalc_intercepts(svm);
+ svm_mark_intercepts_dirty(svm);
}
static inline bool svm_is_intercept(struct vcpu_svm *svm, int bit)