WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

[Xen-changelog] [xen-unstable] [IA64] add get_page() to prevent from fre

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] [IA64] add get_page() to prevent from freeing page
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Mon, 03 Jul 2006 10:20:18 +0000
Delivery-date: Mon, 03 Jul 2006 03:24:57 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# 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

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] [xen-unstable] [IA64] add get_page() to prevent from freeing page, Xen patchbot-unstable <=