diff options
author | Joerg Roedel <joerg.roedel@amd.com> | 2009-08-07 05:49:31 -0400 |
---|---|---|
committer | Avi Kivity <avi@redhat.com> | 2009-09-10 01:33:23 -0400 |
commit | 0460a979b4b7a564e59eaa8efbba6f5ae38c5b78 (patch) | |
tree | c4d559e7cf3f0ac74773835c6be50d2f8d48b9d8 /arch/x86 | |
parent | defbba5660fb9fcad186bd799a635e52994a4d1a (diff) |
KVM: SVM: copy only necessary parts of the control area on vmrun/vmexit
The vmcb control area contains more then 800 bytes of reserved fields
which are unnecessarily copied. Fix this by introducing a copy
function which only copies the relevant part and saves time.
Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
Acked-by: Alexander Graf <agraf@suse.de>
Signed-off-by: Avi Kivity <avi@redhat.com>
Diffstat (limited to 'arch/x86')
-rw-r--r-- | arch/x86/kvm/svm.c | 36 |
1 files changed, 34 insertions, 2 deletions
diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index f11f88005c29..df795bcebd22 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c | |||
@@ -1567,6 +1567,38 @@ static int nested_svm_exit_handled(struct vcpu_svm *svm, bool kvm_override) | |||
1567 | nested_svm_exit_handled_real); | 1567 | nested_svm_exit_handled_real); |
1568 | } | 1568 | } |
1569 | 1569 | ||
1570 | static inline void copy_vmcb_control_area(struct vmcb *dst_vmcb, struct vmcb *from_vmcb) | ||
1571 | { | ||
1572 | struct vmcb_control_area *dst = &dst_vmcb->control; | ||
1573 | struct vmcb_control_area *from = &from_vmcb->control; | ||
1574 | |||
1575 | dst->intercept_cr_read = from->intercept_cr_read; | ||
1576 | dst->intercept_cr_write = from->intercept_cr_write; | ||
1577 | dst->intercept_dr_read = from->intercept_dr_read; | ||
1578 | dst->intercept_dr_write = from->intercept_dr_write; | ||
1579 | dst->intercept_exceptions = from->intercept_exceptions; | ||
1580 | dst->intercept = from->intercept; | ||
1581 | dst->iopm_base_pa = from->iopm_base_pa; | ||
1582 | dst->msrpm_base_pa = from->msrpm_base_pa; | ||
1583 | dst->tsc_offset = from->tsc_offset; | ||
1584 | dst->asid = from->asid; | ||
1585 | dst->tlb_ctl = from->tlb_ctl; | ||
1586 | dst->int_ctl = from->int_ctl; | ||
1587 | dst->int_vector = from->int_vector; | ||
1588 | dst->int_state = from->int_state; | ||
1589 | dst->exit_code = from->exit_code; | ||
1590 | dst->exit_code_hi = from->exit_code_hi; | ||
1591 | dst->exit_info_1 = from->exit_info_1; | ||
1592 | dst->exit_info_2 = from->exit_info_2; | ||
1593 | dst->exit_int_info = from->exit_int_info; | ||
1594 | dst->exit_int_info_err = from->exit_int_info_err; | ||
1595 | dst->nested_ctl = from->nested_ctl; | ||
1596 | dst->event_inj = from->event_inj; | ||
1597 | dst->event_inj_err = from->event_inj_err; | ||
1598 | dst->nested_cr3 = from->nested_cr3; | ||
1599 | dst->lbr_ctl = from->lbr_ctl; | ||
1600 | } | ||
1601 | |||
1570 | static int nested_svm_vmexit_real(struct vcpu_svm *svm, void *arg1, | 1602 | static int nested_svm_vmexit_real(struct vcpu_svm *svm, void *arg1, |
1571 | void *arg2, void *opaque) | 1603 | void *arg2, void *opaque) |
1572 | { | 1604 | { |
@@ -1612,7 +1644,7 @@ static int nested_svm_vmexit_real(struct vcpu_svm *svm, void *arg1, | |||
1612 | nested_vmcb->control.int_ctl &= ~V_INTR_MASKING_MASK; | 1644 | nested_vmcb->control.int_ctl &= ~V_INTR_MASKING_MASK; |
1613 | 1645 | ||
1614 | /* Restore the original control entries */ | 1646 | /* Restore the original control entries */ |
1615 | svm->vmcb->control = hsave->control; | 1647 | copy_vmcb_control_area(vmcb, hsave); |
1616 | 1648 | ||
1617 | /* Kill any pending exceptions */ | 1649 | /* Kill any pending exceptions */ |
1618 | if (svm->vcpu.arch.exception.pending == true) | 1650 | if (svm->vcpu.arch.exception.pending == true) |
@@ -1710,7 +1742,7 @@ static int nested_svm_vmrun(struct vcpu_svm *svm, void *arg1, | |||
1710 | else | 1742 | else |
1711 | hsave->save.cr3 = svm->vcpu.arch.cr3; | 1743 | hsave->save.cr3 = svm->vcpu.arch.cr3; |
1712 | 1744 | ||
1713 | hsave->control = vmcb->control; | 1745 | copy_vmcb_control_area(hsave, vmcb); |
1714 | 1746 | ||
1715 | if (svm->vmcb->save.rflags & X86_EFLAGS_IF) | 1747 | if (svm->vmcb->save.rflags & X86_EFLAGS_IF) |
1716 | svm->vcpu.arch.hflags |= HF_HIF_MASK; | 1748 | svm->vcpu.arch.hflags |= HF_HIF_MASK; |