lkml.org 
[lkml]   [2010]   [Jul]   [1]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[182/200] KVM: SVM: Dont sync nested cr8 to lapic and back
    2.6.34-stable review patch.  If anyone has any objections, please let me know.

    ------------------

    From: Joerg Roedel <joerg.roedel@amd.com>

    This patch makes syncing of the guest tpr to the lapic
    conditional on !nested. Otherwise a nested guest using the
    TPR could freeze the guest.
    Another important change this patch introduces is that the
    cr8 intercept bits are no longer ORed at vmrun emulation if
    the guest sets VINTR_MASKING in its VMCB. The reason is that
    nested cr8 accesses need alway be handled by the nested
    hypervisor because they change the shadow version of the
    tpr.

    Cc: stable@kernel.org
    Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
    Signed-off-by: Avi Kivity <avi@redhat.com>
    Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>

    (Cherry-picked from commit 88ab24adc7142506c8583ac36a34fa388300b750)
    ---
    arch/x86/kvm/svm.c | 46 +++++++++++++++++++++++++++++++---------------
    1 file changed, 31 insertions(+), 15 deletions(-)

    --- a/arch/x86/kvm/svm.c
    +++ b/arch/x86/kvm/svm.c
    @@ -1830,21 +1830,6 @@ static bool nested_svm_vmrun(struct vcpu
    svm->vmcb->save.dr6 = nested_vmcb->save.dr6;
    svm->vmcb->save.cpl = nested_vmcb->save.cpl;

    - /* 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->nested.vmcb_msrpm = nested_vmcb->control.msrpm_base_pa;

    /* cache intercepts */
    @@ -1862,6 +1847,28 @@ static bool nested_svm_vmrun(struct vcpu
    else
    svm->vcpu.arch.hflags &= ~HF_VINTR_MASK;

    + if (svm->vcpu.arch.hflags & HF_VINTR_MASK) {
    + /* We only want the cr8 intercept bits of the guest */
    + svm->vmcb->control.intercept_cr_read &= ~INTERCEPT_CR8_MASK;
    + svm->vmcb->control.intercept_cr_write &= ~INTERCEPT_CR8_MASK;
    + }
    +
    + /* 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;
    svm->vmcb->control.tsc_offset += nested_vmcb->control.tsc_offset;
    @@ -2524,6 +2531,9 @@ static void update_cr8_intercept(struct
    {
    struct vcpu_svm *svm = to_svm(vcpu);

    + if (is_nested(svm) && (vcpu->arch.hflags & HF_VINTR_MASK))
    + return;
    +
    if (irr == -1)
    return;

    @@ -2627,6 +2637,9 @@ static inline void sync_cr8_to_lapic(str
    {
    struct vcpu_svm *svm = to_svm(vcpu);

    + if (is_nested(svm) && (vcpu->arch.hflags & HF_VINTR_MASK))
    + return;
    +
    if (!(svm->vmcb->control.intercept_cr_write & INTERCEPT_CR8_MASK)) {
    int cr8 = svm->vmcb->control.int_ctl & V_TPR_MASK;
    kvm_set_cr8(vcpu, cr8);
    @@ -2638,6 +2651,9 @@ static inline void sync_lapic_to_cr8(str
    struct vcpu_svm *svm = to_svm(vcpu);
    u64 cr8;

    + if (is_nested(svm) && (vcpu->arch.hflags & HF_VINTR_MASK))
    + return;
    +
    cr8 = kvm_get_cr8(vcpu);
    svm->vmcb->control.int_ctl &= ~V_TPR_MASK;
    svm->vmcb->control.int_ctl |= cr8 & V_TPR_MASK;



    \
     
     \ /
      Last update: 2010-07-01 23:33    [W:0.024 / U:29.660 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site