KVM: SVM: Add function to recalculate intercept masks

This patch adds a function to recalculate the effective
intercepts masks when the vcpu is in guest-mode and either
the host or the guest intercept masks change.

Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
This commit is contained in:
Joerg Roedel 2010-11-30 18:03:56 +01:00 committed by Avi Kivity
parent fc3a9157d3
commit 384c636843

View file

@ -192,6 +192,26 @@ static inline struct vcpu_svm *to_svm(struct kvm_vcpu *vcpu)
return container_of(vcpu, struct vcpu_svm, vcpu); return container_of(vcpu, struct vcpu_svm, vcpu);
} }
static void recalc_intercepts(struct vcpu_svm *svm)
{
struct vmcb_control_area *c, *h;
struct nested_state *g;
if (!is_guest_mode(&svm->vcpu))
return;
c = &svm->vmcb->control;
h = &svm->nested.hsave->control;
g = &svm->nested;
c->intercept_cr_read = h->intercept_cr_read | g->intercept_cr_read;
c->intercept_cr_write = h->intercept_cr_write | g->intercept_cr_write;
c->intercept_dr_read = h->intercept_dr_read | g->intercept_dr_read;
c->intercept_dr_write = h->intercept_dr_write | g->intercept_dr_write;
c->intercept_exceptions = h->intercept_exceptions | g->intercept_exceptions;
c->intercept = h->intercept | g->intercept;
}
static inline void enable_gif(struct vcpu_svm *svm) static inline void enable_gif(struct vcpu_svm *svm)
{ {
svm->vcpu.arch.hflags |= HF_GIF_MASK; svm->vcpu.arch.hflags |= HF_GIF_MASK;
@ -2273,23 +2293,6 @@ static bool nested_svm_vmrun(struct vcpu_svm *svm)
/* We don't want to see VMMCALLs from a nested guest */ /* We don't want to see VMMCALLs from a nested guest */
svm->vmcb->control.intercept &= ~(1ULL << INTERCEPT_VMMCALL); svm->vmcb->control.intercept &= ~(1ULL << INTERCEPT_VMMCALL);
/*
* We don't want a nested guest to be more powerful than the guest, so
* all intercepts are ORed
*/
svm->vmcb->control.intercept_cr_read |=
nested_vmcb->control.intercept_cr_read;
svm->vmcb->control.intercept_cr_write |=
nested_vmcb->control.intercept_cr_write;
svm->vmcb->control.intercept_dr_read |=
nested_vmcb->control.intercept_dr_read;
svm->vmcb->control.intercept_dr_write |=
nested_vmcb->control.intercept_dr_write;
svm->vmcb->control.intercept_exceptions |=
nested_vmcb->control.intercept_exceptions;
svm->vmcb->control.intercept |= nested_vmcb->control.intercept;
svm->vmcb->control.lbr_ctl = nested_vmcb->control.lbr_ctl; svm->vmcb->control.lbr_ctl = nested_vmcb->control.lbr_ctl;
svm->vmcb->control.int_vector = nested_vmcb->control.int_vector; svm->vmcb->control.int_vector = nested_vmcb->control.int_vector;
svm->vmcb->control.int_state = nested_vmcb->control.int_state; svm->vmcb->control.int_state = nested_vmcb->control.int_state;
@ -2302,6 +2305,12 @@ static bool nested_svm_vmrun(struct vcpu_svm *svm)
/* Enter Guest-Mode */ /* Enter Guest-Mode */
enter_guest_mode(&svm->vcpu); enter_guest_mode(&svm->vcpu);
/*
* Merge guest and host intercepts - must be called with vcpu in
* guest-mode to take affect here
*/
recalc_intercepts(svm);
svm->nested.vmcb = vmcb_gpa; svm->nested.vmcb = vmcb_gpa;
enable_gif(svm); enable_gif(svm);