From: Joerg Roedel <[email protected]>

All state is keept in svm->host_vmcb so the hsave is not
necessary anymore, so remote it.

Signed-off-by: Joerg Roedel <[email protected]>
---
 arch/x86/kvm/svm.c |  151 ++++++++++++++--------------------------------------
 1 files changed, 41 insertions(+), 110 deletions(-)

diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
index 6dacf59..f2cca2c 100644
--- a/arch/x86/kvm/svm.c
+++ b/arch/x86/kvm/svm.c
@@ -82,7 +82,6 @@ static const u32 host_save_user_msrs[] = {
 struct kvm_vcpu;
 
 struct nested_state {
-       struct vmcb *hsave;
        u64 hsave_msr;
        u64 vm_cr_msr;
        u64 vmcb;
@@ -247,8 +246,8 @@ static void recalc_intercepts(struct vcpu_svm *svm)
        if (!is_guest_mode(&svm->vcpu))
                return;
 
-       c = &svm->vmcb->control;
-       h = &svm->nested.hsave->control;
+       c = &svm->nested.n_vmcb->control;
+       h = &svm->host_vmcb->control;
        g = &svm->nested;
 
        c->intercept_cr = h->intercept_cr | g->intercept_cr;
@@ -257,17 +256,9 @@ static void recalc_intercepts(struct vcpu_svm *svm)
        c->intercept = h->intercept | g->intercept;
 }
 
-static inline struct vmcb *get_host_vmcb(struct vcpu_svm *svm)
-{
-       if (is_guest_mode(&svm->vcpu))
-               return svm->nested.hsave;
-       else
-               return svm->vmcb;
-}
-
 static inline void set_cr_intercept(struct vcpu_svm *svm, int bit)
 {
-       struct vmcb *vmcb = get_host_vmcb(svm);
+       struct vmcb *vmcb = svm->host_vmcb;
 
        vmcb->control.intercept_cr |= (1U << bit);
 
@@ -276,7 +267,7 @@ static inline void set_cr_intercept(struct vcpu_svm *svm, 
int bit)
 
 static inline void clr_cr_intercept(struct vcpu_svm *svm, int bit)
 {
-       struct vmcb *vmcb = get_host_vmcb(svm);
+       struct vmcb *vmcb = svm->host_vmcb;
 
        vmcb->control.intercept_cr &= ~(1U << bit);
 
@@ -285,14 +276,14 @@ static inline void clr_cr_intercept(struct vcpu_svm *svm, 
int bit)
 
 static inline bool is_cr_intercept(struct vcpu_svm *svm, int bit)
 {
-       struct vmcb *vmcb = get_host_vmcb(svm);
+       struct vmcb *vmcb = svm->host_vmcb;
 
        return vmcb->control.intercept_cr & (1U << bit);
 }
 
 static inline void set_dr_intercept(struct vcpu_svm *svm, int bit)
 {
-       struct vmcb *vmcb = get_host_vmcb(svm);
+       struct vmcb *vmcb = svm->host_vmcb;
 
        vmcb->control.intercept_dr |= (1U << bit);
 
@@ -301,7 +292,7 @@ static inline void set_dr_intercept(struct vcpu_svm *svm, 
int bit)
 
 static inline void clr_dr_intercept(struct vcpu_svm *svm, int bit)
 {
-       struct vmcb *vmcb = get_host_vmcb(svm);
+       struct vmcb *vmcb = svm->host_vmcb;
 
        vmcb->control.intercept_dr &= ~(1U << bit);
 
@@ -310,7 +301,7 @@ static inline void clr_dr_intercept(struct vcpu_svm *svm, 
int bit)
 
 static inline void set_exception_intercept(struct vcpu_svm *svm, int bit)
 {
-       struct vmcb *vmcb = get_host_vmcb(svm);
+       struct vmcb *vmcb = svm->host_vmcb;
 
        vmcb->control.intercept_exceptions |= (1U << bit);
 
@@ -319,7 +310,7 @@ static inline void set_exception_intercept(struct vcpu_svm 
*svm, int bit)
 
 static inline void clr_exception_intercept(struct vcpu_svm *svm, int bit)
 {
-       struct vmcb *vmcb = get_host_vmcb(svm);
+       struct vmcb *vmcb = svm->host_vmcb;
 
        vmcb->control.intercept_exceptions &= ~(1U << bit);
 
@@ -328,7 +319,7 @@ static inline void clr_exception_intercept(struct vcpu_svm 
*svm, int bit)
 
 static inline void set_intercept(struct vcpu_svm *svm, int bit)
 {
-       struct vmcb *vmcb = get_host_vmcb(svm);
+       struct vmcb *vmcb = svm->host_vmcb;
 
        vmcb->control.intercept |= (1ULL << bit);
 
@@ -337,7 +328,7 @@ static inline void set_intercept(struct vcpu_svm *svm, int 
bit)
 
 static inline void clr_intercept(struct vcpu_svm *svm, int bit)
 {
-       struct vmcb *vmcb = get_host_vmcb(svm);
+       struct vmcb *vmcb = svm->host_vmcb;
 
        vmcb->control.intercept &= ~(1ULL << bit);
 
@@ -947,9 +938,9 @@ static void svm_write_tsc_offset(struct kvm_vcpu *vcpu, u64 
offset)
        u64 g_tsc_offset = 0;
 
        if (is_guest_mode(vcpu)) {
-               g_tsc_offset = svm->vmcb->control.tsc_offset -
-                              svm->nested.hsave->control.tsc_offset;
-               svm->nested.hsave->control.tsc_offset = offset;
+               g_tsc_offset = svm->host_vmcb->control.tsc_offset -
+                              svm->nested.n_vmcb->control.tsc_offset;
+               svm->nested.n_vmcb->control.tsc_offset = offset;
        }
 
        svm->vmcb->control.tsc_offset = offset + g_tsc_offset;
@@ -963,7 +954,7 @@ static void svm_adjust_tsc_offset(struct kvm_vcpu *vcpu, 
s64 adjustment)
 
        svm->vmcb->control.tsc_offset += adjustment;
        if (is_guest_mode(vcpu))
-               svm->nested.hsave->control.tsc_offset += adjustment;
+               svm->nested.n_vmcb->control.tsc_offset += adjustment;
        mark_dirty(svm->vmcb, VMCB_INTERCEPTS);
 }
 
@@ -1154,7 +1145,6 @@ static struct kvm_vcpu *svm_create_vcpu(struct kvm *kvm, 
unsigned int id)
        struct vcpu_svm *svm;
        struct page *page;
        struct page *msrpm_pages;
-       struct page *hsave_page;
        struct page *nested_msrpm_pages;
        int err;
 
@@ -1183,12 +1173,6 @@ static struct kvm_vcpu *svm_create_vcpu(struct kvm *kvm, 
unsigned int id)
        if (!nested_msrpm_pages)
                goto free_page2;
 
-       hsave_page = alloc_page(GFP_KERNEL);
-       if (!hsave_page)
-               goto free_page3;
-
-       svm->nested.hsave = page_address(hsave_page);
-
        svm->msrpm = page_address(msrpm_pages);
        svm_vcpu_init_msrpm(svm->msrpm);
 
@@ -1206,7 +1190,7 @@ static struct kvm_vcpu *svm_create_vcpu(struct kvm *kvm, 
unsigned int id)
 
        err = fx_init(&svm->vcpu);
        if (err)
-               goto free_page4;
+               goto free_page3;
 
        svm->vcpu.arch.apic_base = 0xfee00000 | MSR_IA32_APICBASE_ENABLE;
        if (kvm_vcpu_is_bsp(&svm->vcpu))
@@ -1214,8 +1198,6 @@ static struct kvm_vcpu *svm_create_vcpu(struct kvm *kvm, 
unsigned int id)
 
        return &svm->vcpu;
 
-free_page4:
-       __free_page(hsave_page);
 free_page3:
        __free_pages(nested_msrpm_pages, MSRPM_ALLOC_ORDER);
 free_page2:
@@ -1238,7 +1220,6 @@ static void svm_free_vcpu(struct kvm_vcpu *vcpu)
                __free_page(virt_to_page(svm->nested.n_vmcb));
        __free_page(pfn_to_page(svm->vmcb_pa >> PAGE_SHIFT));
        __free_pages(virt_to_page(svm->msrpm), MSRPM_ALLOC_ORDER);
-       __free_page(virt_to_page(svm->nested.hsave));
        __free_pages(virt_to_page(svm->nested.msrpm), MSRPM_ALLOC_ORDER);
        kvm_vcpu_uninit(vcpu);
        kmem_cache_free(kvm_vcpu_cache, svm);
@@ -2169,40 +2150,9 @@ static int nested_svm_exit_handled(struct vcpu_svm *svm)
        return vmexit;
 }
 
-static inline void copy_vmcb_control_area(struct vmcb *dst_vmcb, struct vmcb 
*from_vmcb)
-{
-       struct vmcb_control_area *dst  = &dst_vmcb->control;
-       struct vmcb_control_area *from = &from_vmcb->control;
-
-       dst->intercept_cr         = from->intercept_cr;
-       dst->intercept_dr         = from->intercept_dr;
-       dst->intercept_exceptions = from->intercept_exceptions;
-       dst->intercept            = from->intercept;
-       dst->iopm_base_pa         = from->iopm_base_pa;
-       dst->msrpm_base_pa        = from->msrpm_base_pa;
-       dst->tsc_offset           = from->tsc_offset;
-       dst->asid                 = from->asid;
-       dst->tlb_ctl              = from->tlb_ctl;
-       dst->int_ctl              = from->int_ctl;
-       dst->int_vector           = from->int_vector;
-       dst->int_state            = from->int_state;
-       dst->exit_code            = from->exit_code;
-       dst->exit_code_hi         = from->exit_code_hi;
-       dst->exit_info_1          = from->exit_info_1;
-       dst->exit_info_2          = from->exit_info_2;
-       dst->exit_int_info        = from->exit_int_info;
-       dst->exit_int_info_err    = from->exit_int_info_err;
-       dst->nested_ctl           = from->nested_ctl;
-       dst->event_inj            = from->event_inj;
-       dst->event_inj_err        = from->event_inj_err;
-       dst->nested_cr3           = from->nested_cr3;
-       dst->lbr_ctl              = from->lbr_ctl;
-}
-
 static int nested_svm_vmexit(struct vcpu_svm *svm)
 {
        struct vmcb *nested_vmcb;
-       struct vmcb *hsave = svm->nested.hsave;
        struct vmcb *vmcb = svm->nested.n_vmcb;
        struct page *page;
 
@@ -2280,38 +2230,30 @@ static int nested_svm_vmexit(struct vcpu_svm *svm)
        svm->vmcb = svm->host_vmcb;
        svm->vmcb_pa = __pa(svm->host_vmcb);
 
-       /* Restore the original control entries */
-       copy_vmcb_control_area(svm->host_vmcb, hsave);
-
        kvm_clear_exception_queue(&svm->vcpu);
        kvm_clear_interrupt_queue(&svm->vcpu);
 
        svm->nested.nested_cr3 = 0;
 
        /* Restore selected save entries */
-       svm->vmcb->save.es = hsave->save.es;
-       svm->vmcb->save.cs = hsave->save.cs;
-       svm->vmcb->save.ss = hsave->save.ss;
-       svm->vmcb->save.ds = hsave->save.ds;
-       svm->vmcb->save.gdtr = hsave->save.gdtr;
-       svm->vmcb->save.idtr = hsave->save.idtr;
-       kvm_set_rflags(&svm->vcpu, hsave->save.rflags);
-       svm_set_efer(&svm->vcpu, hsave->save.efer);
-       svm_set_cr0(&svm->vcpu, hsave->save.cr0 | X86_CR0_PE);
-       svm_set_cr4(&svm->vcpu, hsave->save.cr4);
-       if (npt_enabled) {
-               svm->vmcb->save.cr3 = hsave->save.cr3;
-               svm->vcpu.arch.cr3 = hsave->save.cr3;
-       } else {
-               (void)kvm_set_cr3(&svm->vcpu, hsave->save.cr3);
-       }
-       kvm_register_write(&svm->vcpu, VCPU_REGS_RAX, hsave->save.rax);
-       kvm_register_write(&svm->vcpu, VCPU_REGS_RSP, hsave->save.rsp);
-       kvm_register_write(&svm->vcpu, VCPU_REGS_RIP, hsave->save.rip);
+       kvm_set_rflags(&svm->vcpu, svm->host_vmcb->save.rflags);
+       svm_set_efer(&svm->vcpu, svm->host_vmcb->save.efer);
+       svm_set_cr0(&svm->vcpu, svm->host_vmcb->save.cr0 | X86_CR0_PE);
+       svm_set_cr4(&svm->vcpu, svm->host_vmcb->save.cr4);
+
+       if (npt_enabled)
+               svm->vcpu.arch.cr3 = svm->host_vmcb->save.cr3;
+       else
+               kvm_set_cr3(&svm->vcpu, svm->host_vmcb->save.cr3);
+
        svm->vmcb->save.dr7 = 0;
        svm->vmcb->save.cpl = 0;
        svm->vmcb->control.exit_int_info = 0;
 
+       kvm_register_write(&svm->vcpu, VCPU_REGS_RAX, svm->host_vmcb->save.rax);
+       kvm_register_write(&svm->vcpu, VCPU_REGS_RSP, svm->host_vmcb->save.rsp);
+       kvm_register_write(&svm->vcpu, VCPU_REGS_RIP, svm->host_vmcb->save.rip);
+
        mark_all_dirty(svm->vmcb);
 
        nested_svm_unmap(page);
@@ -2373,8 +2315,6 @@ static bool nested_vmcb_checks(struct vmcb *vmcb)
 static bool nested_svm_vmrun(struct vcpu_svm *svm)
 {
        struct vmcb *nested_vmcb;
-       struct vmcb *hsave = svm->nested.hsave;
-       struct vmcb *vmcb = svm->vmcb;
        struct page *page;
        u64 vmcb_gpa;
 
@@ -2414,25 +2354,16 @@ static bool nested_svm_vmrun(struct vcpu_svm *svm)
         * Save the old vmcb, so we don't need to pick what we save, but can
         * restore everything when a VMEXIT occurs
         */
-       hsave->save.es     = vmcb->save.es;
-       hsave->save.cs     = vmcb->save.cs;
-       hsave->save.ss     = vmcb->save.ss;
-       hsave->save.ds     = vmcb->save.ds;
-       hsave->save.gdtr   = vmcb->save.gdtr;
-       hsave->save.idtr   = vmcb->save.idtr;
-       hsave->save.efer   = svm->vcpu.arch.efer;
-       hsave->save.cr0    = kvm_read_cr0(&svm->vcpu);
-       hsave->save.cr4    = svm->vcpu.arch.cr4;
-       hsave->save.rflags = kvm_get_rflags(&svm->vcpu);
-       hsave->save.rip    = kvm_rip_read(&svm->vcpu);
-       hsave->save.rsp    = vmcb->save.rsp;
-       hsave->save.rax    = vmcb->save.rax;
-       if (npt_enabled)
-               hsave->save.cr3    = vmcb->save.cr3;
-       else
-               hsave->save.cr3    = kvm_read_cr3(&svm->vcpu);
+       svm->host_vmcb->save.efer   = svm->vcpu.arch.efer;
+       svm->host_vmcb->save.cr0    = kvm_read_cr0(&svm->vcpu);
+       svm->host_vmcb->save.cr4    = svm->vcpu.arch.cr4;
+       svm->host_vmcb->save.rflags = kvm_get_rflags(&svm->vcpu);
+       svm->host_vmcb->save.rax    = svm->vcpu.arch.regs[VCPU_REGS_RAX];
+       svm->host_vmcb->save.rsp    = svm->vcpu.arch.regs[VCPU_REGS_RSP];
+       svm->host_vmcb->save.rip    = svm->vcpu.arch.regs[VCPU_REGS_RIP];
 
-       copy_vmcb_control_area(hsave, vmcb);
+       if (!npt_enabled)
+               svm->host_vmcb->save.cr3 = kvm_read_cr3(&svm->vcpu);
 
        if (kvm_get_rflags(&svm->vcpu) & X86_EFLAGS_IF)
                svm->vcpu.arch.hflags |= HF_HIF_MASK;
@@ -2478,7 +2409,7 @@ static bool nested_svm_vmrun(struct vcpu_svm *svm)
                svm->vmcb->save.cr3 = nested_vmcb->save.cr3;
                svm->vcpu.arch.cr3 = nested_vmcb->save.cr3;
        } else
-               (void)kvm_set_cr3(&svm->vcpu, nested_vmcb->save.cr3);
+               kvm_set_cr3(&svm->vcpu, nested_vmcb->save.cr3);
 
        /* Guest paging mode is active - reset mmu */
        kvm_mmu_reset_context(&svm->vcpu);
@@ -2942,7 +2873,7 @@ static int svm_get_msr(struct kvm_vcpu *vcpu, unsigned 
ecx, u64 *data)
 
        switch (ecx) {
        case MSR_IA32_TSC: {
-               struct vmcb *vmcb = get_host_vmcb(svm);
+               struct vmcb *vmcb = svm->host_vmcb;
 
                *data = vmcb->control.tsc_offset +
                        svm_scale_tsc(vcpu, native_read_tsc());
-- 
1.7.4.1


--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to