[IA64] kexec: Unpin shared_info, mapped_regs and VPD TR in ia64_do_tlb_purge
authorIsaku Yamahata <yamahata@valinux.co.jp>
Tue, 22 Jul 2008 03:15:02 +0000 (12:15 +0900)
committerIsaku Yamahata <yamahata@valinux.co.jp>
Tue, 22 Jul 2008 03:15:02 +0000 (12:15 +0900)
Unpinning shared_info, mapped_regs and VPD seems to be missing
from ia64_do_tlb_purge and seems to be needed for kexec.

Like VHPT, the pinned value is recored in a percpu variable
so that the correct value can be unpinned.

Cc: Isaku Yamahata <yamahata@valinux.co.jp>
Signed-off-by: Simon Horman <horms@verge.net.au>
xen/arch/ia64/linux-xen/mca_asm.S
xen/arch/ia64/vmx/vmx_vcpu.c
xen/arch/ia64/xen/regionreg.c
xen/include/asm-ia64/regionreg.h

index f5ce6a136951319f2cd603a1a85f2f829ff71b5d..70ecc48eddf689124edda69a3c181ab3bf39a736 100644 (file)
@@ -26,6 +26,7 @@
 #include <asm/mca.h>
 #ifdef XEN
 #include <asm/vhpt.h>
+#include <public/arch-ia64.h>
 #endif
 
 /*
@@ -320,7 +321,44 @@ ia64_do_tlb_purge:
        srlz.i
        ;;
 #ifdef XEN
-       // 5. VHPT
+       // 5. shared_info
+       GET_THIS_PADDR(r2, inserted_shared_info);;
+       ld8 r16=[r2]
+       mov r18=XSI_SHIFT<<2
+       ;;
+       ptr.d r16,r18
+       ;;
+       srlz.d
+       ;;
+
+       // 6. mapped_regs
+       GET_THIS_PADDR(r2, inserted_mapped_regs);;
+       ld8 r16=[r2]
+       mov r18=XMAPPEDREGS_SHIFT<<2
+       ;;
+       ptr.d r16,r18
+       ;;
+       srlz.d
+       ;;
+
+       // 7. VPD
+       // The VPD will not be mapped in the case where
+       // a VMX domain hasn't been started since boot
+       GET_THIS_PADDR(r2, inserted_vpd);;
+       ld8 r16=[r2]
+       mov r18=XMAPPEDREGS_SHIFT<<2
+       ;;
+       cmp.eq p7,p0=r2,r0
+       ;;
+(p7)   br.cond.sptk .vpd_not_mapped
+       ;;
+       ptr.i r16,r18
+       ;;
+       srlz.i
+       ;;
+.vpd_not_mapped:
+
+       // 8. VHPT
        // GET_VA_VCPU_VHPT_MADDR() may not give the
        // value of the VHPT currently pinned into the TLB
        GET_THIS_PADDR(r2, inserted_vhpt);;
@@ -485,8 +523,9 @@ ia64_reload_tr:
 #ifdef XEN
 .reload_vhpt:
        // 5. VHPT
-#if VHPT_ENABLED
-       GET_VA_VCPU_VHPT_MADDR(r2,r3);;
+       GET_THIS_PADDR(r1, inserted_vhpt);;
+       cmp.eq p7,p0=r2,r0
+(p7)   br.cond.sptk    .overlap_vhpt   // vhpt isn't mapped.
 
        // avoid overlapping with stack TR
        shr.u r17=r2,IA64_GRANULE_SHIFT
@@ -516,7 +555,6 @@ ia64_reload_tr:
        srlz.d
        ;;
 .overlap_vhpt:
-#endif
 #endif
        br.sptk.many done_tlb_purge_and_reload
 err:
index 0b44bf936fd16ad366a5db66c761d3fcc9ac179b..8ef241926b93bd9493a9a789b546208cbe825e52 100644 (file)
@@ -200,6 +200,8 @@ void vmx_switch_rr7(unsigned long rid, void *guest_vhpt,
                     void *pal_vaddr, void *shared_arch_info)
 {
     __get_cpu_var(inserted_vhpt) = (unsigned long)guest_vhpt;
+    __get_cpu_var(inserted_vpd) = (unsigned long)shared_arch_info;
+    __get_cpu_var(inserted_mapped_regs) = (unsigned long)shared_arch_info;
     __vmx_switch_rr7(rid, guest_vhpt, pal_vaddr, shared_arch_info);
 }
 
index d7442d640390bd8b27c62a2f15cd8a7789288cac..d9843370f878214124efaeb22e07774c34d7c8dd 100644 (file)
@@ -49,6 +49,9 @@ static unsigned int domain_rid_bits_default = IA64_MIN_IMPL_RID_BITS;
 integer_param("dom_rid_bits", domain_rid_bits_default); 
 
 DEFINE_PER_CPU(unsigned long, inserted_vhpt);
+DEFINE_PER_CPU(unsigned long, inserted_shared_info);
+DEFINE_PER_CPU(unsigned long, inserted_mapped_regs);
+DEFINE_PER_CPU(unsigned long, inserted_vpd);
 
 #if 0
 // following already defined in include/asm-ia64/gcc_intrin.h
@@ -266,6 +269,11 @@ int set_one_rr(unsigned long rr, unsigned long val)
 #if VHPT_ENABLED
                __get_cpu_var(inserted_vhpt) = __va_ul(vcpu_vhpt_maddr(v));
 #endif
+               __get_cpu_var(inserted_shared_info) =
+                                       v->domain->arch.shared_info_va;
+               __get_cpu_var(inserted_mapped_regs) =
+                                       v->domain->arch.shared_info_va +
+                                       XMAPPEDREGS_OFS;
                ia64_new_rr7(vmMangleRID(newrrv.rrval),v->domain->shared_info,
                             v->arch.privregs, v->domain->arch.shared_info_va,
                             __va_ul(vcpu_vhpt_maddr(v)));
index 1d728235cd577de16be6572c187648657aa69856..49b9b3282649081abd16cc5a8b303e4656060fc5 100644 (file)
@@ -37,6 +37,9 @@ typedef union ia64_rr {
 #define RR_RID_MASK     0x00000000ffffff00L
 
 DECLARE_PER_CPU(unsigned long, inserted_vhpt);
+DECLARE_PER_CPU(unsigned long, inserted_shared_info);
+DECLARE_PER_CPU(unsigned long, inserted_mapped_regs);
+DECLARE_PER_CPU(unsigned long, inserted_vpd);
 
 int set_one_rr(unsigned long rr, unsigned long val);