# HG changeset patch # User tristan.gingold@xxxxxxxx # Node ID 17c2876ba450eefe0a0336b201ac24a2240fcacc # Parent 986538da9be011ecceadbd400ef880e90254c798 vcpu_match_tr_entry moved from vcpu.h to vcpu.c. Range check fixed. ptc_ga: purge tr entry within the IPI function. Signed-off-by: Tristan Gingold diff -r 986538da9be0 -r 17c2876ba450 xen/arch/ia64/xen/vcpu.c --- a/xen/arch/ia64/xen/vcpu.c Wed Mar 29 19:41:33 2006 +++ b/xen/arch/ia64/xen/vcpu.c Thu Mar 30 09:38:23 2006 @@ -1273,6 +1273,14 @@ int warn_region0_address = 0; // FIXME later: tie to a boot parameter? +// FIXME: also need to check && (!trp->key || vcpu_pkr_match(trp->key)) +static inline int vcpu_match_tr_entry(TR_ENTRY *trp, UINT64 ifa, UINT64 rid) +{ + return trp->p && trp->rid == rid + && ifa >= trp->vadr + && ifa <= (trp->vadr + (1L << trp->ps) - 1); +} + IA64FAULT vcpu_translate(VCPU *vcpu, UINT64 address, BOOLEAN is_data, BOOLEAN in_tpa, UINT64 *pteval, UINT64 *itir, UINT64 *iha) { unsigned long region = address >> 61; @@ -1681,6 +1689,7 @@ VCPU translation register access routines **************************************************************************/ + static inline void vcpu_purge_tr_entry(TR_ENTRY *trp) { trp->p = 0; @@ -1692,9 +1701,9 @@ trp->itir = itir; trp->rid = VCPU(current,rrs[ifa>>61]) & RR_RID_MASK; - trp->p = 1; ps = trp->ps; trp->page_flags = pte; + trp->p = 1; if (trp->pl < 2) trp->pl = 2; trp->vadr = ifa & ~0xfff; if (ps > 12) { // "ignore" relevant low-order bits @@ -1865,16 +1874,28 @@ return IA64_ILLOP_FAULT; } -#if defined(CONFIG_XEN_SMP) && defined(VHPT_GLOBAL) +#if defined(CONFIG_XEN_SMP) struct ptc_ga_args { unsigned long vadr; unsigned long addr_range; + struct vcpu *v; }; static void ptc_ga_remote_func (void *varg) { struct ptc_ga_args *args = (struct ptc_ga_args *)varg; + + if (args->v->processor != smp_processor_id ()) { + /* Has been migrated. */ + return; + } +#ifdef VHPT_GLOBAL vhpt_flush_address (args->vadr, args->addr_range); +#endif + /* Purge tc. */ + vcpu_purge_tr_entry(&PSCBX(args->v,dtlb)); + vcpu_purge_tr_entry(&PSCBX(args->v,itlb)); + } #endif @@ -1892,6 +1913,7 @@ args.vadr = vadr; args.addr_range = addr_range; + args.v = vcpu; /* This method is very conservative and should be optimized: - maybe IPI calls can be avoided, @@ -1901,18 +1923,20 @@ */ for_each_vcpu (d, v) { if (v != vcpu) { - /* Purge tc entry. - Can we do this directly ? Well, this is just a - single atomic write. */ - vcpu_purge_tr_entry(&PSCBX(v,dtlb)); - vcpu_purge_tr_entry(&PSCBX(v,itlb)); -#ifdef VHPT_GLOBAL - /* Flush VHPT on remote processors. - FIXME: invalidate directly the entries? */ - smp_call_function_single - (v->processor, &ptc_ga_remote_func, - &args, 0, 1); -#endif + int proc; + + /* During the IPI, the VCPU can be migrated. To be + sure the right CPU is reached, we check processor + id after the IPI. */ + do { + proc = v->processor; + + /* Flush tlb and VHPT on remote processors. + FIXME: invalidate directly the entries? */ + smp_call_function_single + (v->processor, &ptc_ga_remote_func, + &args, 0, 1); + } while (unlikely (proc != v->processor)); } } #endif diff -r 986538da9be0 -r 17c2876ba450 xen/include/asm-ia64/vcpu.h --- a/xen/include/asm-ia64/vcpu.h Wed Mar 29 19:41:33 2006 +++ b/xen/include/asm-ia64/vcpu.h Thu Mar 30 09:38:23 2006 @@ -16,6 +16,7 @@ typedef cpu_user_regs_t REGS; +/* Note: PSCB stands for Privilegied State Communication Block. */ #define VCPU(_v,_x) (_v->arch.privregs->_x) #define PSCB(_v,_x) VCPU(_v,_x) #define PSCBX(_v,_x) (_v->arch._x) @@ -185,10 +186,5 @@ #define vcpu_quick_region_set(_tr_regions,_ifa) \ do {_tr_regions |= (1 << ((unsigned long)_ifa >> 61)); } while (0) -// FIXME: also need to check && (!trp->key || vcpu_pkr_match(trp->key)) -#define vcpu_match_tr_entry(_trp,_ifa,_rid) \ - ((_trp->p && (_trp->rid==_rid) && (_ifa >= _trp->vadr) && \ - (_ifa < (_trp->vadr + (1L<< _trp->ps)) - 1))) - #endif