diff options
author | Joerg Roedel <joerg.roedel@amd.com> | 2010-11-30 17:03:56 (GMT) |
---|---|---|
committer | Avi Kivity <avi@redhat.com> | 2011-01-12 09:30:08 (GMT) |
commit | 384c636843971c8ebbffd1cc8881e3184cbd23e2 (patch) | |
tree | 72829294ce4e0a7e986deab41007f6796cd1829d | |
parent | fc3a9157d3148ab91039c75423da8ef97be3e105 (diff) | |
download | linux-384c636843971c8ebbffd1cc8881e3184cbd23e2.tar.xz |
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>
-rw-r--r-- | arch/x86/kvm/svm.c | 43 |
1 files changed, 26 insertions, 17 deletions
diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index 2ae94b5..74f89f0 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c @@ -192,6 +192,26 @@ static inline struct vcpu_svm *to_svm(struct kvm_vcpu *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) { 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 */ 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.int_vector = nested_vmcb->control.int_vector; 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(&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; enable_gif(svm); |