[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [xen stable-4.2] x86: allow VCPUOP_register_vcpu_info to work again on PVHVM guests



commit 9b3db6d948f33043049d78029ef99baf5855d69e
Author:     Konrad Rzeszutek Wilk <konrad.wilk@xxxxxxxxxx>
AuthorDate: Thu May 23 10:05:27 2013 +0200
Commit:     Jan Beulich <jbeulich@xxxxxxxx>
CommitDate: Thu May 23 10:05:27 2013 +0200

    x86: allow VCPUOP_register_vcpu_info to work again on PVHVM guests
    
    For details on the hypercall please see commit
    c58ae69360ccf2495a19bf4ca107e21cf873c75b (VCPUOP_register_vcpu_info) and
    the c/s 23143 (git commit 6b063a4a6f44245a727aa04ef76408b2e00af9c7)
    (x86: move pv-only members of struct vcpu to struct pv_vcpu)
    that introduced the regression.
    
    The current code allows the PVHVM guest to make this hypercall.
    But for PVHVM guest it always returns -EINVAL (-22) for Xen 4.2
    and above. Xen 4.1 and earlier worked.
    
    The reason is that the check in map_vcpu_info would fail
    at:
    
      if ( v->arch.vcpu_info_mfn != INVALID_MFN )
    
    The reason is that the vcpu_info_mfn for PVHVM guests ends up by
    defualt with the value of zero (introduced by c/s 23143).
    
    The code in vcpu_initialise which initialized vcpu_info_mfn to a
    valid value (INVALID_MFN), would never be called for PVHVM:
    
        if ( is_hvm_domain(d) )
        {
            rc = hvm_vcpu_initialise(v);
            goto done;
        }
    
        v->arch.pv_vcpu.vcpu_info_mfn = INVALID_MFN;
    
    while previously it would be:
    
         v->arch.vcpu_info_mfn = INVALID_MFN;
    
    [right at the start of the function in Xen 4.1]
    
    This fixes the problem with Linux advertising this error:
    register_vcpu_info failed: err=-22
    
    Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@xxxxxxxxxx>
    
    x86: call unmap_vcpu_info() regardless of guest type
    
    This fixes a regression from 63753b3e ("x86: allow
    VCPUOP_register_vcpu_info to work again on PVHVM guests").
    
    Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx>
    Tested-by: Sander Eikelenboom <linux@xxxxxxxxxxxxxx>
    master commit: 63753b3e0dc56efb1acf94fa46f3fee7bc59281c
    master date: 2013-04-17 11:35:38 +0200
    master commit: 9626d1c1fafe2da5af6e59478c9e9db6d03144df
    master date: 2013-05-02 09:29:36 +0200
---
 xen/arch/x86/domain.c        |   17 +++++++++--------
 xen/include/asm-x86/domain.h |    6 +++---
 2 files changed, 12 insertions(+), 11 deletions(-)

diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c
index f76b362..1d5bcb5 100644
--- a/xen/arch/x86/domain.c
+++ b/xen/arch/x86/domain.c
@@ -429,13 +429,14 @@ int vcpu_initialise(struct vcpu *v)
 
     vmce_init_vcpu(v);
 
+    v->arch.vcpu_info_mfn = INVALID_MFN;
+
     if ( is_hvm_domain(d) )
     {
         rc = hvm_vcpu_initialise(v);
         goto done;
     }
 
-    v->arch.pv_vcpu.vcpu_info_mfn = INVALID_MFN;
 
     spin_lock_init(&v->arch.pv_vcpu.shadow_ldt_lock);
 
@@ -1084,14 +1085,14 @@ unmap_vcpu_info(struct vcpu *v)
 {
     unsigned long mfn;
 
-    if ( v->arch.pv_vcpu.vcpu_info_mfn == INVALID_MFN )
+    if ( v->arch.vcpu_info_mfn == INVALID_MFN )
         return;
 
-    mfn = v->arch.pv_vcpu.vcpu_info_mfn;
+    mfn = v->arch.vcpu_info_mfn;
     unmap_domain_page_global(v->vcpu_info);
 
     v->vcpu_info = &dummy_vcpu_info;
-    v->arch.pv_vcpu.vcpu_info_mfn = INVALID_MFN;
+    v->arch.vcpu_info_mfn = INVALID_MFN;
 
     put_page_and_type(mfn_to_page(mfn));
 }
@@ -1114,7 +1115,7 @@ map_vcpu_info(struct vcpu *v, unsigned long gfn, unsigned 
offset)
     if ( offset > (PAGE_SIZE - sizeof(vcpu_info_t)) )
         return -EINVAL;
 
-    if ( v->arch.pv_vcpu.vcpu_info_mfn != INVALID_MFN )
+    if ( v->arch.vcpu_info_mfn != INVALID_MFN )
         return -EINVAL;
 
     /* Run this command on yourself or on other offline VCPUS. */
@@ -1151,7 +1152,7 @@ map_vcpu_info(struct vcpu *v, unsigned long gfn, unsigned 
offset)
     }
 
     v->vcpu_info = new_info;
-    v->arch.pv_vcpu.vcpu_info_mfn = page_to_mfn(page);
+    v->arch.vcpu_info_mfn = page_to_mfn(page);
 
     /* Set new vcpu_info pointer /before/ setting pending flags. */
     wmb();
@@ -2098,6 +2099,8 @@ int domain_relinquish_resources(struct domain *d)
             ret = vcpu_destroy_pagetables(v);
             if ( ret )
                 return ret;
+
+            unmap_vcpu_info(v);
         }
 
         if ( !is_hvm_domain(d) )
@@ -2110,8 +2113,6 @@ int domain_relinquish_resources(struct domain *d)
                  * mappings.
                  */
                 destroy_gdt(v);
-
-                unmap_vcpu_info(v);
             }
 
             if ( d->arch.pv_domain.pirq_eoi_map != NULL )
diff --git a/xen/include/asm-x86/domain.h b/xen/include/asm-x86/domain.h
index 898f63a..a3235a5 100644
--- a/xen/include/asm-x86/domain.h
+++ b/xen/include/asm-x86/domain.h
@@ -420,9 +420,6 @@ struct pv_vcpu
     /* Current LDT details. */
     unsigned long shadow_ldt_mapcnt;
     spinlock_t shadow_ldt_lock;
-
-    /* Guest-specified relocation of vcpu_info. */
-    unsigned long vcpu_info_mfn;
 };
 
 struct arch_vcpu
@@ -495,6 +492,9 @@ struct arch_vcpu
     
     struct paging_vcpu paging;
 
+    /* Guest-specified relocation of vcpu_info. */
+    unsigned long vcpu_info_mfn;
+
 #ifdef CONFIG_X86_32
     /* map_domain_page() mapping cache. */
     struct mapcache_vcpu mapcache;
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.2

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.