[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-ia64-devel] [PATCH 1/3] [read-only mapping] GNTMAP_readonly support xen part


 1 / 3 
# HG changeset patch
# User yamahata@xxxxxxxxxxxxx
# Node ID d4879708b89968cb860c324c27b69c9d3955fda5
# Parent  e6a88b056e60120a6ce554613ccb0f6a2bd4114f
add grant table GNTMAP_readonly support.
PATCHNAME: grant_table_readonly

Signed-off-by: Isaku Yamahata <yamahata@xxxxxxxxxxxxx>

diff -r e6a88b056e60 -r d4879708b899 xen/arch/ia64/vmx/vmx_init.c
--- a/xen/arch/ia64/vmx/vmx_init.c	Tue May 16 13:25:41 2006 +0900
+++ b/xen/arch/ia64/vmx/vmx_init.c	Tue May 16 13:25:43 2006 +0900
@@ -346,7 +346,7 @@ int vmx_build_physmap_table(struct domai
 	    for (j = io_ranges[i].start;
 		 j < io_ranges[i].start + io_ranges[i].size;
 		 j += PAGE_SIZE)
-		__assign_domain_page(d, j, io_ranges[i].type);
+		__assign_domain_page(d, j, io_ranges[i].type, 0);
 	}
 
 	/* Map normal memory below 3G */
diff -r e6a88b056e60 -r d4879708b899 xen/arch/ia64/xen/domain.c
--- a/xen/arch/ia64/xen/domain.c	Tue May 16 13:25:41 2006 +0900
+++ b/xen/arch/ia64/xen/domain.c	Tue May 16 13:25:43 2006 +0900
@@ -707,6 +707,16 @@ not_present:
 }
 #endif
 
+static void
+assign_pte(pte_t* pte, unsigned long maddr, unsigned long readonly)
+{
+    unsigned long arflags = _PAGE_AR_RWX;
+    if (readonly)
+        arflags = _PAGE_AR_R;
+    set_pte(pte, pfn_pte(maddr >> PAGE_SHIFT,
+                         __pgprot(__DIRTY_BITS | _PAGE_PL_2 | arflags)));
+}
+
 /* Allocate a new page for domain and map it to the specified metaphysical 
    address.  */
 struct page_info *
@@ -753,8 +763,7 @@ __assign_new_domain_page(struct domain *
 
     ret = get_page(p, d);
     BUG_ON(ret == 0);
-    set_pte(pte, pfn_pte(maddr >> PAGE_SHIFT,
-                         __pgprot(__DIRTY_BITS | _PAGE_PL_2 | _PAGE_AR_RWX)));
+    assign_pte(pte, maddr, 0);
 
     //XXX CONFIG_XEN_IA64_DOM0_VP
     //    TODO racy
@@ -804,16 +813,15 @@ assign_new_domain0_page(struct domain *d
 /* map a physical address to the specified metaphysical addr */
 void
 __assign_domain_page(struct domain *d,
-                     unsigned long mpaddr, unsigned long physaddr)
+                     unsigned long mpaddr, unsigned long physaddr,
+                     unsigned long readonly)
 {
     pte_t *pte;
 
     pte = lookup_alloc_domain_pte(d, mpaddr);
-    if (pte_none(*pte)) {
-        set_pte(pte,
-                pfn_pte(physaddr >> PAGE_SHIFT,
-                        __pgprot(__DIRTY_BITS | _PAGE_PL_2 | _PAGE_AR_RWX)));
-    } else
+    if (pte_none(*pte))
+        assign_pte(pte, physaddr, readonly);
+    else
         printk("%s: mpaddr %lx already mapped!\n", __func__, mpaddr);
 }
 
@@ -828,7 +836,7 @@ assign_domain_page(struct domain *d,
     BUG_ON((physaddr & GPFN_IO_MASK) != GPFN_MEM);
     ret = get_page(page, d);
     BUG_ON(ret == 0);
-    __assign_domain_page(d, mpaddr, physaddr);
+    __assign_domain_page(d, mpaddr, physaddr, 0);
 
     //XXX CONFIG_XEN_IA64_DOM0_VP
     //    TODO racy
@@ -843,7 +851,7 @@ assign_domain_same_page(struct domain *d
     //XXX optimization
     unsigned long end = mpaddr + size;
     for (; mpaddr < end; mpaddr += PAGE_SIZE) {
-        __assign_domain_page(d, mpaddr, mpaddr);
+        __assign_domain_page(d, mpaddr, mpaddr, 0);
     }
 }
 
@@ -1035,15 +1043,14 @@ unsigned long lookup_domain_mpa(struct d
 		}
 		pteval = pfn_pte(mpaddr >> PAGE_SHIFT,
 			__pgprot(__DIRTY_BITS | _PAGE_PL_2 | _PAGE_AR_RWX));
-		pte = &pteval;
-		return *(unsigned long *)pte;
+        return pte_val(pteval);
 	}
 #endif
 	pte = lookup_noalloc_domain_pte(d, mpaddr);
 	if (pte != NULL) {
 		if (pte_present(*pte)) {
 //printk("lookup_domain_page: found mapping for %lx, pte=%lx\n",mpaddr,pte_val(*pte));
-			return *(unsigned long *)pte;
+			return pte_val(*pte);
 		} else if (VMX_DOMAIN(d->vcpu[0]))
 			return GPFN_INV_MASK;
 	}
@@ -1083,7 +1090,7 @@ out:
 // caller must call set_gpfn_from_mfn().
 static void
 assign_domain_page_replace(struct domain *d, unsigned long mpaddr,
-                           unsigned long mfn, unsigned int flags)
+                           unsigned long mfn, unsigned int readonly)
 {
     struct mm_struct *mm = d->arch.mm;
     pte_t* pte;
@@ -1093,8 +1100,7 @@ assign_domain_page_replace(struct domain
 
     // update pte
     old_pte = ptep_get_and_clear(mm, mpaddr, pte);
-    set_pte(pte, pfn_pte(mfn,
-                         __pgprot(__DIRTY_BITS | _PAGE_PL_2 | _PAGE_AR_RWX)));
+    assign_pte(pte, mfn << PAGE_SHIFT, readonly);
     if (!pte_none(old_pte)) {
         unsigned long old_mfn;
         struct page_info* old_page;
@@ -1122,11 +1128,11 @@ assign_domain_page_replace(struct domain
 
 unsigned long
 dom0vp_add_physmap(struct domain* d, unsigned long gpfn, unsigned long mfn,
-                   unsigned int flags, domid_t domid)
+                   unsigned int readonly, domid_t domid)
 {
     int error = 0;
-
     struct domain* rd;
+
     rd = find_domain_by_id(domid);
     if (unlikely(rd == NULL)) {
         error = -EINVAL;
@@ -1141,7 +1147,7 @@ dom0vp_add_physmap(struct domain* d, uns
         goto out1;
     }
 
-    assign_domain_page_replace(d, gpfn << PAGE_SHIFT, mfn, 0/* flags:XXX */);
+    assign_domain_page_replace(d, gpfn << PAGE_SHIFT, mfn, readonly);
     //don't update p2m table because this page belongs to rd, not d.
 out1:
     put_domain(rd);
@@ -1161,22 +1167,16 @@ create_grant_host_mapping(unsigned long 
     struct page_info* page;
     int ret;
 
-    if (flags & (GNTMAP_application_map | GNTMAP_contains_pte)) {
+    if (flags & (GNTMAP_device_map | 
+                 GNTMAP_application_map | GNTMAP_contains_pte)) {
         DPRINTK("%s: flags 0x%x\n", __func__, flags);
         return GNTST_general_error;
-    }
-    if (flags & GNTMAP_readonly) {
-#if 0
-        DPRINTK("%s: GNTMAP_readonly is not implemented yet. flags %x\n",
-                __func__, flags);
-#endif
-        flags &= ~GNTMAP_readonly;
     }
 
     page = mfn_to_page(mfn);
     ret = get_page(page, page_get_owner(page));
     BUG_ON(ret == 0);
-    assign_domain_page_replace(d, gpaddr, mfn, flags);
+    assign_domain_page_replace(d, gpaddr, mfn, flags & GNTMAP_readonly);
 
     return GNTST_okay;
 }
@@ -1196,22 +1196,17 @@ destroy_grant_host_mapping(unsigned long
         DPRINTK("%s: flags 0x%x\n", __func__, flags);
         return GNTST_general_error;
     }
-    if (flags & GNTMAP_readonly) {
-#if 0
-        DPRINTK("%s: GNTMAP_readonly is not implemented yet. flags %x\n",
-                __func__, flags);
-#endif
-        flags &= ~GNTMAP_readonly;
-    }
 
     pte = lookup_noalloc_domain_pte(d, gpaddr);
     if (pte == NULL || !pte_present(*pte) || pte_pfn(*pte) != mfn)
-        return GNTST_general_error;//XXX GNTST_bad_pseudo_phys_addr
-
+        return GNTST_general_error;// GNTST_bad_pseudo_phys_addr?
+    
     // update pte
     old_pte = ptep_get_and_clear(d->arch.mm, gpaddr, pte);
     if (pte_present(old_pte)) {
-        old_mfn = pte_pfn(old_pte);//XXX
+        old_mfn = pte_pfn(old_pte);
+    } else {
+        return GNTST_general_error;// GNTST_bad_virt_addr?
     }
     domain_page_flush(d, gpaddr, old_mfn, INVALID_MFN);
 
@@ -1312,7 +1307,7 @@ guest_physmap_add_page(struct domain *d,
 
     ret = get_page(mfn_to_page(mfn), d);
     BUG_ON(ret == 0);
-    assign_domain_page_replace(d, gpfn << PAGE_SHIFT, mfn, 0/* XXX */);
+    assign_domain_page_replace(d, gpfn << PAGE_SHIFT, mfn, 0);
     set_gpfn_from_mfn(mfn, gpfn);//XXX SMP
 
     //BUG_ON(mfn != ((lookup_domain_mpa(d, gpfn << PAGE_SHIFT) & _PFN_MASK) >> PAGE_SHIFT));
diff -r e6a88b056e60 -r d4879708b899 xen/arch/ia64/xen/process.c
--- a/xen/arch/ia64/xen/process.c	Tue May 16 13:25:41 2006 +0900
+++ b/xen/arch/ia64/xen/process.c	Tue May 16 13:25:43 2006 +0900
@@ -85,6 +85,8 @@ u64 translate_domain_pte(u64 pteval, u64
 	struct domain *d = current->domain;
 	ia64_itir_t itir = {.itir = itir__};
 	u64 mask, mpaddr, pteval2;
+    u64 arflags;
+    u64 arflags2;
 
 	pteval &= ((1UL << 53) - 1);// ignore [63:53] bits
 
@@ -123,6 +125,18 @@ u64 translate_domain_pte(u64 pteval, u64
 	}
 #endif
 	pteval2 = lookup_domain_mpa(d,mpaddr);
+    arflags  = pteval  & _PAGE_AR_MASK;
+    arflags2 = pteval2 & _PAGE_AR_MASK;
+    if (arflags != _PAGE_AR_R && arflags2 == _PAGE_AR_R) {
+        DPRINTK("%s:%d "
+                "pteval 0x%lx arflag 0x%lx address 0x%lx itir 0x%lx "
+                "pteval2 0x%lx arflags2 0x%lx\n",
+                __func__, __LINE__,
+                pteval, arflags, address, itir__,
+                pteval2, arflags2);
+        pteval = (pteval & ~_PAGE_AR_MASK) | _PAGE_AR_R;
+    }
+
 	pteval2 &= _PAGE_PPN_MASK; // ignore non-addr bits
 	pteval2 |= (pteval & _PAGE_ED);
 	pteval2 |= _PAGE_PL_2; // force PL0->2 (PL3 is unaffected)
diff -r e6a88b056e60 -r d4879708b899 xen/include/asm-ia64/domain.h
--- a/xen/include/asm-ia64/domain.h	Tue May 16 13:25:41 2006 +0900
+++ b/xen/include/asm-ia64/domain.h	Tue May 16 13:25:43 2006 +0900
@@ -118,7 +118,7 @@ extern struct mm_struct init_mm;
 
 struct page_info * assign_new_domain_page(struct domain *d, unsigned long mpaddr);
 void assign_new_domain0_page(struct domain *d, unsigned long mpaddr);
-void __assign_domain_page(struct domain *d, unsigned long mpaddr, unsigned long physaddr);
+void __assign_domain_page(struct domain *d, unsigned long mpaddr, unsigned long physaddr, unsigned long readonly);
 void assign_domain_page(struct domain *d, unsigned long mpaddr, unsigned long physaddr);
 void assign_domain_io_page(struct domain *d, unsigned long mpaddr, unsigned long flags);
 #ifdef CONFIG_XEN_IA64_DOM0_VP
@@ -126,7 +126,7 @@ unsigned long assign_domain_mach_page(st
 unsigned long assign_domain_mach_page(struct domain *d, unsigned long mpaddr, unsigned long size);
 unsigned long do_dom0vp_op(unsigned long cmd, unsigned long arg0, unsigned long arg1, unsigned long arg2, unsigned long arg3);
 unsigned long dom0vp_zap_physmap(struct domain *d, unsigned long gpfn, unsigned int extent_order);
-unsigned long dom0vp_add_physmap(struct domain* d, unsigned long gpfn, unsigned long mfn, unsigned int flags, domid_t domid);
+unsigned long dom0vp_add_physmap(struct domain* d, unsigned long gpfn, unsigned long mfn, unsigned int readonly, domid_t domid);
 #endif
 
 #include <asm/uaccess.h> /* for KERNEL_DS */
_______________________________________________
Xen-ia64-devel mailing list
Xen-ia64-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-ia64-devel


This mailing list archive is a service of Copilotco.