# HG changeset patch # User yamahata@xxxxxxxxxxxxx # Node ID c7cd1af74a38134e296dbafe449f3b54969419e8 # Parent c5c599141647ac705effa2c676e225ead6509539 vtlb, vhpt collision chain may have invalid entry. insert/purge function should be aware of it. PATCHNAME: vtlb_vhpt_collision_chain_may_have_invalid_entry Signed-off-by: Isaku Yamahata diff -r c5c599141647 -r c7cd1af74a38 xen/arch/ia64/vmx/vtlb.c --- a/xen/arch/ia64/vmx/vtlb.c Wed Jun 21 18:12:44 2006 +0900 +++ b/xen/arch/ia64/vmx/vtlb.c Wed Jun 21 18:16:06 2006 +0900 @@ -148,10 +148,18 @@ static void vmx_vhpt_insert(thash_cb_t * head = (thash_data_t *)ia64_thash(ifa); tag = ia64_ttag(ifa); - if( INVALID_VHPT(head) ) { - head->page_flags = pte; - head->etag = tag; - return; + for (cch = head; cch != NULL; cch = cch->next) { + if(INVALID_VHPT(cch)) { + local_irq_save(flags); + if (cch != head) { + cch->page_flags = head->page_flags; + cch->etag = head->etag; + } + head->page_flags = pte; + head->etag = tag; + local_irq_restore(flags); + return; + } } if(head->len>=MAX_CCN_DEPTH){ @@ -240,7 +248,6 @@ static void vtlb_purge(VCPU *v, u64 va, static void vtlb_purge(VCPU *v, u64 va, u64 ps) { thash_cb_t *hcb = &v->arch.vtlb; - thash_data_t *hash_table, *prev, *next; u64 start, end, size, tag, rid, def_size; ia64_rr vrr; vcpu_get_rr(v, va, &vrr.rrval); @@ -250,22 +257,12 @@ static void vtlb_purge(VCPU *v, u64 va, end = start + size; def_size = PSIZE(vrr.ps); while(start < end){ + thash_data_t *hash_table, *next; hash_table = vsa_thash(hcb->pta, start, vrr.rrval, &tag); - if(!INVALID_TLB(hash_table)){ - if(hash_table->etag == tag){ - hash_table->etag = 1UL<<63; - } - else{ - prev=hash_table; - next=prev->next; - while(next){ - if(next->etag == tag){ - next->etag = 1UL<<63; - break; - } - prev=next; - next=next->next; - } + for (next = hash_table; next != NULL; next = next->next) { + if (next->etag == tag) { + next->etag = 1UL<<63; + break; } } start += def_size; @@ -288,7 +285,6 @@ static void vhpt_purge(VCPU *v, u64 va, static void vhpt_purge(VCPU *v, u64 va, u64 ps) { //thash_cb_t *hcb = &v->arch.vhpt; - thash_data_t *hash_table, *prev, *next; u64 start, end, size, tag; size = PSIZE(ps); start = va & (-size); @@ -296,21 +292,13 @@ static void vhpt_purge(VCPU *v, u64 va, if (current != v) switch_rr7_and_pta(v); while(start < end){ + thash_data_t *hash_table, *next; hash_table = (thash_data_t *)ia64_thash(start); tag = ia64_ttag(start); - if(hash_table->etag == tag ){ - hash_table->etag = 1UL<<63; - } - else{ - prev=hash_table; - next=prev->next; - while(next){ - if(next->etag == tag){ - next->etag = 1UL<<63; - break; - } - prev=next; - next=next->next; + for (next = hash_table; next != NULL; next = next->next) { + if(next->etag == tag){ + next->etag = 1UL<<63; + break; } } start += PAGE_SIZE; @@ -379,12 +367,15 @@ void vtlb_insert(thash_cb_t *hcb, u64 pt } #endif hash_table = vsa_thash(hcb->pta, va, vrr.rrval, &tag); - if( INVALID_TLB(hash_table) ) { - hash_table->page_flags = pte; - hash_table->itir=itir; - hash_table->etag=tag; - return; - } + for (cch = hash_table; cch != NULL; cch = cch->next) { + if(INVALID_TLB(cch)) { + cch->page_flags = pte; + cch->itir=itir; + cch->etag=tag; + return; + } + } + if (hash_table->len>=MAX_CCN_DEPTH){ thash_recycle_cch(hcb, hash_table); cch = cch_alloc(hcb);