[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] [IA64] add get_page() to prevent from freeing page
# HG changeset patch # User awilliam@xxxxxxxxxxx # Node ID 535b466ee1ef431bbb82b0bdea1b3c90a85914b3 # Parent d60da6514d65c8bf577d136adc720b1dc6c28388 [IA64] add get_page() to prevent from freeing page get_page() when access a page of domain. pages can be removed from domain and freed by another cpu. To prevent accessing freeing page, use get_page() and put_page() Signed-off-by: Isaku Yamahata <yamahata@xxxxxxxxxxxxx> --- xen/arch/ia64/vmx/vmmu.c | 22 ++++++++++++++++++---- xen/arch/ia64/vmx/vmx_hypercall.c | 6 ++++++ xen/arch/ia64/xen/fw_emul.c | 35 +++++++++++++++++++++++++++++------ xen/arch/ia64/xen/vcpu.c | 23 ++++++++++++++++++++--- 4 files changed, 73 insertions(+), 13 deletions(-) diff -r d60da6514d65 -r 535b466ee1ef xen/arch/ia64/vmx/vmmu.c --- a/xen/arch/ia64/vmx/vmmu.c Mon Jun 19 13:00:37 2006 -0600 +++ b/xen/arch/ia64/vmx/vmmu.c Mon Jun 19 13:06:53 2006 -0600 @@ -313,7 +313,9 @@ fetch_code(VCPU *vcpu, u64 gip, u64 *cod u64 *vpa; thash_data_t *tlb; u64 mfn; - + struct page_info* page; + + again: if ( !(VCPU(vcpu, vpsr) & IA64_PSR_IT) ) { // I-side physical mode gpip = gip; } @@ -327,15 +329,27 @@ fetch_code(VCPU *vcpu, u64 gip, u64 *cod if( gpip){ mfn = gmfn_to_mfn(vcpu->domain, gpip >>PAGE_SHIFT); if( mfn == INVALID_MFN ) panic_domain(vcpu_regs(vcpu),"fetch_code: invalid memory\n"); - vpa =(u64 *)__va( (gip & (PAGE_SIZE-1)) | (mfn<<PAGE_SHIFT)); }else{ tlb = vhpt_lookup(gip); if( tlb == NULL) panic_domain(vcpu_regs(vcpu),"No entry found in ITLB and DTLB\n"); - vpa =(u64 *)__va((tlb->ppn>>(PAGE_SHIFT-ARCH_PAGE_SHIFT)<<PAGE_SHIFT)|(gip&(PAGE_SIZE-1))); - } + mfn = tlb->ppn >> (PAGE_SHIFT - ARCH_PAGE_SHIFT); + } + + page = mfn_to_page(mfn); + if (get_page(page, vcpu->domain) == 0) { + if (page_get_owner(page) != vcpu->domain) { + // This page might be a page granted by another domain. + panic_domain(NULL, "domain tries to execute foreign domain " + "page which might be mapped by grant table.\n"); + } + goto again; + } + vpa = (u64 *)__va((mfn << PAGE_SHIFT) | (gip & (PAGE_SIZE - 1))); + *code1 = *vpa++; *code2 = *vpa; + put_page(page); return 1; } diff -r d60da6514d65 -r 535b466ee1ef xen/arch/ia64/vmx/vmx_hypercall.c --- a/xen/arch/ia64/vmx/vmx_hypercall.c Mon Jun 19 13:00:37 2006 -0600 +++ b/xen/arch/ia64/vmx/vmx_hypercall.c Mon Jun 19 13:06:53 2006 -0600 @@ -160,10 +160,15 @@ static int do_set_shared_page(VCPU *vcpu u64 o_info; struct domain *d = vcpu->domain; struct vcpu *v; + struct page_info *page; if(vcpu->domain!=dom0) return -EPERM; o_info = (u64)vcpu->domain->shared_info; + again: d->shared_info= (shared_info_t *)domain_mpa_to_imva(vcpu->domain, gpa); + page = virt_to_page(d->shared_info); + if (get_page(page, d) == 0) + goto again; /* Copy existing shared info into new page */ if (o_info) { @@ -178,6 +183,7 @@ static int do_set_shared_page(VCPU *vcpu free_xenheap_page((void *)o_info); } else memset(d->shared_info, 0, PAGE_SIZE); + put_page(page); return 0; } diff -r d60da6514d65 -r 535b466ee1ef xen/arch/ia64/xen/fw_emul.c --- a/xen/arch/ia64/xen/fw_emul.c Mon Jun 19 13:00:37 2006 -0600 +++ b/xen/arch/ia64/xen/fw_emul.c Mon Jun 19 13:06:53 2006 -0600 @@ -359,18 +359,32 @@ xen_pal_emulator(unsigned long index, u6 // given a current domain (virtual or metaphysical) address, return the virtual address static unsigned long -efi_translate_domain_addr(unsigned long domain_addr, IA64FAULT *fault) +efi_translate_domain_addr(unsigned long domain_addr, IA64FAULT *fault, + struct page_info** page) { struct vcpu *v = current; unsigned long mpaddr = domain_addr; + unsigned long virt; *fault = IA64_NO_FAULT; +again: if (v->domain->arch.efi_virt_mode) { *fault = vcpu_tpa(v, domain_addr, &mpaddr); if (*fault != IA64_NO_FAULT) return 0; } - return ((unsigned long) __va(translate_domain_mpaddr(mpaddr, NULL))); + virt = domain_mpa_to_imva(v->domain, mpaddr); + *page = virt_to_page(virt); + if (get_page(*page, current->domain) == 0) { + if (page_get_owner(*page) != current->domain) { + // which code is appropriate? + *fault = IA64_FAULT; + return 0; + } + goto again; + } + + return virt; } static efi_status_t @@ -379,18 +393,27 @@ efi_emulate_get_time( IA64FAULT *fault) { unsigned long tv = 0, tc = 0; + struct page_info *tv_page = NULL; + struct page_info *tc_page = NULL; efi_status_t status; //printf("efi_get_time(%016lx,%016lx) called\n", tv_addr, tc_addr); - tv = efi_translate_domain_addr(tv_addr, fault); - if (*fault != IA64_NO_FAULT) return 0; + tv = efi_translate_domain_addr(tv_addr, fault, &tv_page); + if (*fault != IA64_NO_FAULT) + return 0; if (tc_addr) { - tc = efi_translate_domain_addr(tc_addr, fault); - if (*fault != IA64_NO_FAULT) return 0; + tc = efi_translate_domain_addr(tc_addr, fault, &tc_page); + if (*fault != IA64_NO_FAULT) { + put_page(tv_page); + return 0; + } } //printf("efi_get_time(%016lx,%016lx) translated to xen virtual address\n", tv, tc); status = (*efi.get_time)((efi_time_t *) tv, (efi_time_cap_t *) tc); //printf("efi_get_time returns %lx\n", status); + if (tc_page != NULL) + put_page(tc_page); + put_page(tv_page); return status; } diff -r d60da6514d65 -r 535b466ee1ef xen/arch/ia64/xen/vcpu.c --- a/xen/arch/ia64/xen/vcpu.c Mon Jun 19 13:00:37 2006 -0600 +++ b/xen/arch/ia64/xen/vcpu.c Mon Jun 19 13:06:53 2006 -0600 @@ -1408,7 +1408,10 @@ vcpu_get_domain_bundle(VCPU* vcpu, REGS* vcpu_get_domain_bundle(VCPU* vcpu, REGS* regs, UINT64 gip, IA64_BUNDLE* bundle) { UINT64 gpip;// guest pseudo phyiscal ip - + unsigned long vaddr; + struct page_info* page; + +again: #if 0 // Currently xen doesn't track psr.it bits. // it assumes always psr.it = 1. @@ -1471,8 +1474,22 @@ vcpu_get_domain_bundle(VCPU* vcpu, REGS* gpip = ((tr.pte.ppn >> (tr.ps - 12)) << tr.ps) | (gip & ((1 << tr.ps) - 1)); } - - *bundle = *((IA64_BUNDLE*)__va(__gpa_to_mpa(vcpu->domain, gpip))); + + vaddr = domain_mpa_to_imva(vcpu->domain, gpip); + page = virt_to_page(vaddr); + if (get_page(page, vcpu->domain) == 0) { + if (page_get_owner(page) != vcpu->domain) { + // This page might be a page granted by another + // domain. + panic_domain(regs, + "domain tries to execute foreign domain " + "page which might be mapped by grant " + "table.\n"); + } + goto again; + } + *bundle = *((IA64_BUNDLE*)vaddr); + put_page(page); return 1; } _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |