# HG changeset patch
# User Isaku Yamahata <yamahata@xxxxxxxxxxxxx>
# Date 1216696502 -32400
# Node ID 0b72d16e794b4182c641487ef0288151bd08e8f7
# Parent b2d2bc30a04bebae9f0762f24c970c0f9d197654
[IA64] kexec: Unpin the correct VHPT TR in ia64_do_tlb_purge
GET_VA_VCPU_VHPT_MADDR(r2,r3) does not give the value of the VHPT
pinned into the TLB. I believe that this is because
current is changed between pinning and calling play_dead,
though I am not sure of the exact scemantics.
In any case, by recording the pinned value in a percpu variable,
and unpinning this value, the TR entry is removed and all is well.
Cc: Isaku Yamahata <yamahata@xxxxxxxxxxxxx>
Signed-off-by: Simon Horman <horms@xxxxxxxxxxxx>
---
xen/arch/ia64/linux-xen/mca_asm.S | 11 ++++++++---
xen/arch/ia64/vmx/vmx_vcpu.c | 1 +
xen/arch/ia64/xen/regionreg.c | 6 ++++++
xen/include/asm-ia64/regionreg.h | 1 +
4 files changed, 16 insertions(+), 3 deletions(-)
diff -r b2d2bc30a04b -r 0b72d16e794b xen/arch/ia64/linux-xen/mca_asm.S
--- a/xen/arch/ia64/linux-xen/mca_asm.S Tue Jul 22 12:15:02 2008 +0900
+++ b/xen/arch/ia64/linux-xen/mca_asm.S Tue Jul 22 12:15:02 2008 +0900
@@ -321,8 +321,13 @@ 4:
;;
#ifdef XEN
// 5. VHPT
-#if VHPT_ENABLED
- GET_VA_VCPU_VHPT_MADDR(r2,r3);;
+ // GET_VA_VCPU_VHPT_MADDR() may not give the
+ // value of the VHPT currently pinned into the TLB
+ GET_THIS_PADDR(r2, inserted_vhpt);;
+ ;;
+ cmp.eq p7,p0=r2,r0
+ ;;
+(p7) br.cond.sptk .vhpt_not_mapped
dep r16=0,r2,0,IA64_GRANULE_SHIFT
mov r18=IA64_GRANULE_SHIFT<<2
;;
@@ -330,7 +335,7 @@ 4:
;;
srlz.d
;;
-#endif
+.vhpt_not_mapped:
#endif
// Now branch away to caller.
br.sptk.many b1
diff -r b2d2bc30a04b -r 0b72d16e794b xen/arch/ia64/vmx/vmx_vcpu.c
--- a/xen/arch/ia64/vmx/vmx_vcpu.c Tue Jul 22 12:15:02 2008 +0900
+++ b/xen/arch/ia64/vmx/vmx_vcpu.c Tue Jul 22 12:15:02 2008 +0900
@@ -199,6 +199,7 @@ void vmx_switch_rr7(unsigned long rid, v
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;
__vmx_switch_rr7(rid, guest_vhpt, pal_vaddr, shared_arch_info);
}
diff -r b2d2bc30a04b -r 0b72d16e794b xen/arch/ia64/xen/regionreg.c
--- a/xen/arch/ia64/xen/regionreg.c Tue Jul 22 12:15:02 2008 +0900
+++ b/xen/arch/ia64/xen/regionreg.c Tue Jul 22 12:15:02 2008 +0900
@@ -15,6 +15,7 @@
#include <asm/regionreg.h>
#include <asm/vhpt.h>
#include <asm/vcpu.h>
+#include <asm/percpu.h>
/* Defined in xemasm.S */
extern void ia64_new_rr7(unsigned long rid, void *shared_info, void
*shared_arch_info, unsigned long shared_info_va, unsigned long va_vhpt);
@@ -46,6 +47,8 @@ extern void ia64_new_rr7(unsigned long r
/* Default number of rid bits for domains. */
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);
#if 0
// following already defined in include/asm-ia64/gcc_intrin.h
@@ -260,6 +263,9 @@ int set_one_rr(unsigned long rr, unsigne
if (!PSCB(v,metaphysical_mode))
set_rr(rr,newrrv.rrval);
} else if (rreg == 7) {
+#if VHPT_ENABLED
+ __get_cpu_var(inserted_vhpt) = __va_ul(vcpu_vhpt_maddr(v));
+#endif
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)));
diff -r b2d2bc30a04b -r 0b72d16e794b xen/include/asm-ia64/regionreg.h
--- a/xen/include/asm-ia64/regionreg.h Tue Jul 22 12:15:02 2008 +0900
+++ b/xen/include/asm-ia64/regionreg.h Tue Jul 22 12:15:02 2008 +0900
@@ -36,6 +36,7 @@ typedef union ia64_rr {
#define RR_RID(arg) (((arg) & 0x0000000000ffffff) << 8)
#define RR_RID_MASK 0x00000000ffffff00L
+DECLARE_PER_CPU(unsigned long, inserted_vhpt);
int set_one_rr(unsigned long rr, unsigned long val);
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|