# HG changeset patch # User yamahata@xxxxxxxxxxxxx # Node ID c5c599141647ac705effa2c676e225ead6509539 # Parent 385580db95655f6b662df2e95ad1be158eca5149 vti-domain smp-related fix. add local_irq_save(), local_irq_restore() to protect vtlb, vhpt collision chain from IPI. PATCHNAME: local_irq_save_local_irq_restore Signed-off-by: Isaku Yamahata diff -r 385580db9565 -r c5c599141647 xen/arch/ia64/vmx/vmx_process.c --- a/xen/arch/ia64/vmx/vmx_process.c Wed Jun 21 18:06:04 2006 +0900 +++ b/xen/arch/ia64/vmx/vmx_process.c Wed Jun 21 18:12:44 2006 +0900 @@ -244,6 +244,7 @@ vmx_hpw_miss(u64 vadr , u64 vec, REGS* r // REGS *regs; thash_data_t *data; VCPU *v = current; + unsigned long flags; #ifdef VTLB_DEBUG check_vtlb_sanity(vtlb); dump_vtlb(vtlb); @@ -266,11 +267,12 @@ vmx_hpw_miss(u64 vadr , u64 vec, REGS* r else panic_domain(regs,"wrong vec:%lx\n",vec); // prepare_if_physical_mode(v); - + local_irq_save(flags); if((data=vtlb_lookup(v, vadr,type))!=0){ // gppa = (vadr&((1UL<ps)-1))+(data->ppn>>(data->ps-12)<ps); // if(v->domain!=dom0&&type==DSIDE_TLB && __gpfn_is_io(v->domain,gppa>>PAGE_SHIFT)){ if(v->domain!=dom0 && data->io && type==DSIDE_TLB ){ + local_irq_restore(flags); if(data->pl >= ((regs->cr_ipsr>>IA64_PSR_CPL0_BIT)&3)){ gppa = (vadr&((1UL<ps)-1))+(data->ppn>>(data->ps-12)<ps); emulate_io_inst(v, gppa, data->ma); @@ -282,8 +284,10 @@ vmx_hpw_miss(u64 vadr , u64 vec, REGS* r } thash_vhpt_insert(v,data->page_flags, data->itir ,vadr); + local_irq_restore(flags); }else if(type == DSIDE_TLB){ if(!vhpt_enabled(v, vadr, misr.rs?RSE_REF:DATA_REF)){ + local_irq_restore(flags); if(vpsr.ic){ vcpu_set_isr(v, misr.val); alt_dtlb(v, vadr); @@ -305,8 +309,10 @@ vmx_hpw_miss(u64 vadr , u64 vec, REGS* r vcpu_get_rr(v, vadr, &rr); itir = rr&(RR_RID_MASK | RR_PS_MASK); thash_purge_and_insert(v, pteval, itir , vadr); + local_irq_restore(flags); return IA64_NO_FAULT; } + local_irq_restore(flags); if(vpsr.ic){ vcpu_set_isr(v, misr.val); dtlb_fault(v, vadr); @@ -322,6 +328,7 @@ vmx_hpw_miss(u64 vadr , u64 vec, REGS* r } } }else{ + local_irq_restore(flags); if(vpsr.ic){ vcpu_set_isr(v, misr.val); dvhpt_fault(v, vadr); @@ -340,6 +347,7 @@ vmx_hpw_miss(u64 vadr , u64 vec, REGS* r } }else if(type == ISIDE_TLB){ if(!vhpt_enabled(v, vadr, misr.rs?RSE_REF:DATA_REF)){ + local_irq_restore(flags); if(!vpsr.ic){ misr.ni=1; } @@ -353,8 +361,10 @@ vmx_hpw_miss(u64 vadr , u64 vec, REGS* r vcpu_get_rr(v, vadr, &rr); itir = rr&(RR_RID_MASK | RR_PS_MASK); thash_purge_and_insert(v, pteval, itir , vadr); + local_irq_restore(flags); return IA64_NO_FAULT; } + local_irq_restore(flags); if(!vpsr.ic){ misr.ni=1; } diff -r 385580db9565 -r c5c599141647 xen/arch/ia64/vmx/vtlb.c --- a/xen/arch/ia64/vmx/vtlb.c Wed Jun 21 18:06:04 2006 +0900 +++ b/xen/arch/ia64/vmx/vtlb.c Wed Jun 21 18:12:44 2006 +0900 @@ -143,6 +143,7 @@ static void vmx_vhpt_insert(thash_cb_t * { u64 tag; thash_data_t *head, *cch; + unsigned long flags; pte = pte & ~PAGE_FLAGS_RV_MASK; head = (thash_data_t *)ia64_thash(ifa); @@ -160,6 +161,7 @@ static void vmx_vhpt_insert(thash_cb_t * else{ cch = __alloc_chain(hcb); } + local_irq_save(flags); cch->page_flags=head->page_flags; cch->etag=head->etag; cch->next=head->next; @@ -168,6 +170,7 @@ static void vmx_vhpt_insert(thash_cb_t * head->next = cch; head->len = cch->len+1; cch->len = 0; + local_irq_restore(flags); return; } @@ -194,6 +197,8 @@ thash_data_t * vhpt_lookup(u64 va) hash=hash->next; }while(hash); if(hash && hash!=head){ + unsigned long flags; + local_irq_save(flags); pte = hash->page_flags; hash->page_flags = head->page_flags; head->page_flags = pte; @@ -202,6 +207,7 @@ thash_data_t * vhpt_lookup(u64 va) head->etag = tag; head->len = hash->len; hash->len=0; + local_irq_restore(flags); return head; } return hash; @@ -362,6 +368,7 @@ void vtlb_insert(thash_cb_t *hcb, u64 pt ia64_rr vrr; /* u64 gppn, ppns, ppne; */ u64 tag; + unsigned long flags; vcpu_get_rr(current, va, &vrr.rrval); #ifdef VTLB_DEBUG if (vrr.ps != itir_ps(itir)) { @@ -385,6 +392,7 @@ void vtlb_insert(thash_cb_t *hcb, u64 pt else { cch = __alloc_chain(hcb); } + local_irq_save(flags); *cch = *hash_table; hash_table->page_flags = pte; hash_table->itir=itir; @@ -392,6 +400,7 @@ void vtlb_insert(thash_cb_t *hcb, u64 pt hash_table->next = cch; hash_table->len = cch->len + 1; cch->len = 0; + local_irq_restore(flags); return ; }