>From: Tristan Gingold
>Sent: 2006年4月3日 21:38
>
>The other conflict is use. This is within ia64_page_fault, between
>vcpu_translate and vcpu_itc_no_srlz. This part of code is protected by
>a
>flag + counter: At entry the flag is set and the counter increment, at exit
>the flag is reset. Ptc.ga waits if the flag is set and retries if the
>counter has changes.
Agree with Alex to use seqlock here.
>
>+ /* Bit 0 must not be set. */
>+ BUG_ON (PSCBX(current, tlb_inuse) & 1);
>+ /* Set bit 0 and increment counter (from bit 1). */
>+ current->arch.tlb_inuse += 3;
>+
> fault = vcpu_translate(current,address,is_data,0,&pteval,&itir,&iha);
> if (fault == IA64_NO_FAULT) {
> pteval = translate_domain_pte(pteval,address,itir);
>
> vcpu_itc_no_srlz(current,is_data?2:1,address,pteval,-1UL,(itir>>2)
>&0x3f);
>+ /* Clear in_use flag. */
>+ current->arch.tlb_inuse--;
> return;
> }
>+ /* Clear in_use flag. */
>+ current->arch.tlb_inuse--;
>+
Seems you need current->arch.tlb_inuse -= 3 here.
>diff -r ddc279c91502 xen/arch/ia64/xen/vcpu.c
>--- a/xen/arch/ia64/xen/vcpu.c Fri Mar 31 21:04:16 2006
>+++ b/xen/arch/ia64/xen/vcpu.c Mon Apr 3 11:20:57 2006
>+ do {
>+ /* Wait until the tlb is not used. */
>+ while ((count = PSCBX(vcpu, tlb_inuse)) & 1)
>+ cpu_relax ();
>+
>+ /* Purge tc entries. */
>+ vcpu_purge_tr_entry(&PSCBX(vcpu,dtlb));
>+ vcpu_purge_tr_entry(&PSCBX(vcpu,itlb));
It's possible tlb_inuse is set again here, however for a new guest tlb entry
which means content of dtlb/itlb may change within this window. Then
the new tlb entry will be incorrectly purged in next loop.
>+
>+ /* Loop until the entry is not used. */
>+ } while (count != PSCBX(vcpu, tlb_inuse));
Thanks,
Kevin
_______________________________________________
Xen-ia64-devel mailing list
Xen-ia64-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-ia64-devel
|