[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 810b3f0491cef6f47496007366daccda57829d7d
# Parent  83c0449db67ac3c9b5e04c91ed042a0629ff48d8
add grant table GNTMAP_readonly support.
introduce ASSIGN_readonly flags for read only page assignment to
pseudo physical address space.
PATCHNAME: grant_table_readonly

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

diff -r 83c0449db67a -r 810b3f0491ce xen/arch/ia64/vmx/vmx_init.c
--- a/xen/arch/ia64/vmx/vmx_init.c	Tue May 23 17:05:27 2006 -0600
+++ b/xen/arch/ia64/vmx/vmx_init.c	Wed May 24 17:25:38 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, ASSIGN_writable);
 	}
 
 	/* Map normal memory below 3G */
diff -r 83c0449db67a -r 810b3f0491ce xen/arch/ia64/xen/domain.c
--- a/xen/arch/ia64/xen/domain.c	Tue May 23 17:05:27 2006 -0600
+++ b/xen/arch/ia64/xen/domain.c	Wed May 24 17:25:38 2006 +0900
@@ -793,17 +793,19 @@ assign_new_domain0_page(struct domain *d
 }
 
 /* map a physical address to the specified metaphysical addr */
+// flags: currently only ASSIGN_readonly
 void
 __assign_domain_page(struct domain *d,
-                     unsigned long mpaddr, unsigned long physaddr)
+                     unsigned long mpaddr, unsigned long physaddr,
+                     unsigned long flags)
 {
     pte_t *pte;
+    unsigned long arflags = (flags & ASSIGN_readonly)? _PAGE_AR_R: _PAGE_AR_RWX;
 
     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)));
+        set_pte(pte, pfn_pte(physaddr >> PAGE_SHIFT,
+                             __pgprot(__DIRTY_BITS | _PAGE_PL_2 | arflags)));
         mb ();
     } else
         printk("%s: mpaddr %lx already mapped!\n", __func__, mpaddr);
@@ -820,7 +822,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, ASSIGN_writable);
 
     //XXX CONFIG_XEN_IA64_DOM0_VP
     //    TODO racy
@@ -830,12 +832,12 @@ assign_domain_page(struct domain *d,
 #ifdef CONFIG_XEN_IA64_DOM0_VP
 static void
 assign_domain_same_page(struct domain *d,
-                          unsigned long mpaddr, unsigned long size)
+                        unsigned long mpaddr, unsigned long size)
 {
     //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, ASSIGN_writable);
     }
 }
 
@@ -1072,15 +1074,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;
 	}
@@ -1094,7 +1095,10 @@ unsigned long lookup_domain_mpa(struct d
 		printk("%s: bad mpa 0x%lx (=> 0x%lx)\n", __func__,
 		       mpaddr, (unsigned long)d->max_pages << PAGE_SHIFT);
 	mpafoo(mpaddr);
-	return 0;
+
+    //XXX This is a work around until the emulation memory access to a region
+    //    where memory or device are attached is implemented.
+    return pte_val(pfn_pte(0, __pgprot(__DIRTY_BITS | _PAGE_PL_2 | _PAGE_AR_RWX)));
 }
 
 #ifdef CONFIG_XEN_IA64_DOM0_VP
@@ -1118,19 +1122,21 @@ out:
 
 // caller must get_page(mfn_to_page(mfn)) before
 // caller must call set_gpfn_from_mfn().
+// flags: currently only ASSIGN_readonly
 static void
 assign_domain_page_replace(struct domain *d, unsigned long mpaddr,
-                           unsigned long mfn, unsigned int flags)
+                           unsigned long mfn, unsigned long flags)
 {
     struct mm_struct *mm = &d->arch.mm;
     pte_t* pte;
     pte_t old_pte;
     pte_t npte;
+    unsigned long arflags = (flags & ASSIGN_readonly)? _PAGE_AR_R: _PAGE_AR_RWX;
 
     pte = lookup_alloc_domain_pte(d, mpaddr);
 
     // update pte
-    npte = pfn_pte(mfn, __pgprot(__DIRTY_BITS | _PAGE_PL_2 | _PAGE_AR_RWX));
+    npte = pfn_pte(mfn, __pgprot(__DIRTY_BITS | _PAGE_PL_2 | arflags));
     old_pte = ptep_xchg(mm, mpaddr, pte, npte);
     if (!pte_none(old_pte)) {
         unsigned long old_mfn;
@@ -1159,11 +1165,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 long flags, domid_t domid)
 {
     int error = 0;
-
     struct domain* rd;
+
     rd = find_domain_by_id(domid);
     if (unlikely(rd == NULL)) {
         error = -EINVAL;
@@ -1178,7 +1184,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, flags);
     //don't update p2m table because this page belongs to rd, not d.
 out1:
     put_domain(rd);
@@ -1198,23 +1204,17 @@ 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)? ASSIGN_readonly: ASSIGN_writable);
     return GNTST_okay;
 }
 
@@ -1233,22 +1233,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;
 
     // 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;
     }
     domain_page_flush(d, gpaddr, old_mfn, INVALID_MFN);
 
@@ -1349,7 +1344,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, ASSIGN_writable);
     set_gpfn_from_mfn(mfn, gpfn);//XXX SMP
 
     //BUG_ON(mfn != ((lookup_domain_mpa(d, gpfn << PAGE_SHIFT) & _PFN_MASK) >> PAGE_SHIFT));
diff -r 83c0449db67a -r 810b3f0491ce xen/arch/ia64/xen/process.c
--- a/xen/arch/ia64/xen/process.c	Tue May 23 17:05:27 2006 -0600
+++ b/xen/arch/ia64/xen/process.c	Wed May 24 17:25:38 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,20 @@ 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) {
+#if 0
+        DPRINTK("%s:%d "
+                "pteval 0x%lx arflag 0x%lx address 0x%lx itir 0x%lx "
+                "pteval2 0x%lx arflags2 0x%lx mpaddr 0x%lx\n",
+                __func__, __LINE__,
+                pteval, arflags, address, itir__,
+                pteval2, arflags2, mpaddr);
+#endif
+        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 83c0449db67a -r 810b3f0491ce xen/include/asm-ia64/domain.h
--- a/xen/include/asm-ia64/domain.h	Tue May 23 17:05:27 2006 -0600
+++ b/xen/include/asm-ia64/domain.h	Wed May 24 17:25:38 2006 +0900
@@ -114,7 +114,7 @@ struct arch_vcpu {
 
 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 flags);
 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
@@ -122,7 +122,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 long flags, domid_t domid);
 #endif
 
 #include <asm/uaccess.h> /* for KERNEL_DS */
diff -r 83c0449db67a -r 810b3f0491ce xen/include/public/arch-ia64.h
--- a/xen/include/public/arch-ia64.h	Tue May 23 17:05:27 2006 -0600
+++ b/xen/include/public/arch-ia64.h	Wed May 24 17:25:38 2006 +0900
@@ -369,6 +369,10 @@ DEFINE_XEN_GUEST_HANDLE(vcpu_guest_conte
 #define IA64_DOM0VP_add_physmap         18      // assigne machine page frane
                                                 // to dom0's pseudo physical
                                                 // address space.
+// flags for page assignement to pseudo physical address space
+#define _ASSIGN_readonly                0
+#define ASSIGN_readonly                 (1UL << _ASSIGN_readonly)
+#define ASSIGN_writable                 (0UL << _ASSIGN_readonly) // dummy flag
 
 #endif /* !__ASSEMBLY__ */
 
_______________________________________________
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.