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] expose p2m table. xen side part.

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] [IA64] expose p2m table. xen side part.
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Thu, 26 Oct 2006 12:10:44 +0000
Delivery-date: Thu, 26 Oct 2006 05:14:24 -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 0bb486157ff5886c1593146169a17e91280f53e9
# Parent  7cfc7cb7cea7024352cc4ff9f185788e9f09920d
[IA64] expose p2m table. xen side part.

This patch introduces xen compile time option, xen_ia64_expose_p2m=y.
default is enabled.

Signed-off-by: Isaku Yamahata <yamahata@xxxxxxxxxxxxx>
---
 xen/arch/ia64/Rules.mk         |    4 +
 xen/arch/ia64/vmx/vmx_init.c   |    3 
 xen/arch/ia64/xen/dom0_ops.c   |    3 
 xen/arch/ia64/xen/mm.c         |  135 +++++++++++++++++++++++++++++++++++++++--
 xen/arch/ia64/xen/xensetup.c   |    2 
 xen/include/asm-ia64/mm.h      |    9 ++
 xen/include/public/arch-ia64.h |    3 
 7 files changed, 151 insertions(+), 8 deletions(-)

diff -r 7cfc7cb7cea7 -r 0bb486157ff5 xen/arch/ia64/Rules.mk
--- a/xen/arch/ia64/Rules.mk    Wed Oct 04 22:12:14 2006 -0600
+++ b/xen/arch/ia64/Rules.mk    Wed Oct 04 22:12:25 2006 -0600
@@ -5,6 +5,7 @@ HAS_VGA  := y
 HAS_VGA  := y
 VALIDATE_VT    ?= n
 no_warns ?= n
+xen_ia64_expose_p2m    ?= y
 
 ifneq ($(COMPILE_ARCH),$(TARGET_ARCH))
 CROSS_COMPILE ?= /usr/local/sp_env/v2.2.5/i686/bin/ia64-unknown-linux-
@@ -36,6 +37,9 @@ ifeq ($(VALIDATE_VT),y)
 ifeq ($(VALIDATE_VT),y)
 CFLAGS  += -DVALIDATE_VT
 endif
+ifeq ($(xen_ia64_expose_p2m),y)
+CFLAGS += -DCONFIG_XEN_IA64_EXPOSE_P2M
+endif
 ifeq ($(no_warns),y)
 CFLAGS += -Wa,--fatal-warnings -Werror -Wno-uninitialized
 endif
diff -r 7cfc7cb7cea7 -r 0bb486157ff5 xen/arch/ia64/vmx/vmx_init.c
--- a/xen/arch/ia64/vmx/vmx_init.c      Wed Oct 04 22:12:14 2006 -0600
+++ b/xen/arch/ia64/vmx/vmx_init.c      Wed Oct 04 22:12:25 2006 -0600
@@ -378,7 +378,8 @@ static void vmx_build_physmap_table(stru
            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_writable);
+               (void)__assign_domain_page(d, j, io_ranges[i].type,
+                                          ASSIGN_writable);
        }
 
        /* Map normal memory below 3G */
diff -r 7cfc7cb7cea7 -r 0bb486157ff5 xen/arch/ia64/xen/dom0_ops.c
--- a/xen/arch/ia64/xen/dom0_ops.c      Wed Oct 04 22:12:14 2006 -0600
+++ b/xen/arch/ia64/xen/dom0_ops.c      Wed Oct 04 22:12:25 2006 -0600
@@ -273,6 +273,9 @@ do_dom0vp_op(unsigned long cmd,
         ret = dom0vp_add_physmap(d, arg0, arg1, (unsigned int)arg2,
                                  (domid_t)arg3);
         break;
+    case IA64_DOM0VP_expose_p2m:
+        ret = dom0vp_expose_p2m(d, arg0, arg1, arg2, arg3);
+        break;
     default:
         ret = -1;
                printf("unknown dom0_vp_op 0x%lx\n", cmd);
diff -r 7cfc7cb7cea7 -r 0bb486157ff5 xen/arch/ia64/xen/mm.c
--- a/xen/arch/ia64/xen/mm.c    Wed Oct 04 22:12:14 2006 -0600
+++ b/xen/arch/ia64/xen/mm.c    Wed Oct 04 22:12:25 2006 -0600
@@ -806,7 +806,7 @@ flags_to_prot (unsigned long flags)
 // flags: currently only ASSIGN_readonly, ASSIGN_nocache
 // This is called by assign_domain_mmio_page().
 // So accessing to pte is racy.
-void
+int
 __assign_domain_page(struct domain *d,
                      unsigned long mpaddr, unsigned long physaddr,
                      unsigned long flags)
@@ -822,8 +822,11 @@ __assign_domain_page(struct domain *d,
     old_pte = __pte(0);
     new_pte = pfn_pte(physaddr >> PAGE_SHIFT, __pgprot(prot));
     ret_pte = ptep_cmpxchg_rel(&d->arch.mm, mpaddr, pte, old_pte, new_pte);
-    if (pte_val(ret_pte) == pte_val(old_pte))
+    if (pte_val(ret_pte) == pte_val(old_pte)) {
         smp_mb();
+        return 0;
+    }
+    return -EAGAIN;
 }
 
 /* get_page() and map a physical address to the specified metaphysical addr */
@@ -840,7 +843,7 @@ assign_domain_page(struct domain *d,
     set_gpfn_from_mfn(physaddr >> PAGE_SHIFT, mpaddr >> PAGE_SHIFT);
     // because __assign_domain_page() uses set_pte_rel() which has
     // release semantics, smp_mb() isn't needed.
-    __assign_domain_page(d, mpaddr, physaddr, ASSIGN_writable);
+    (void)__assign_domain_page(d, mpaddr, physaddr, ASSIGN_writable);
 }
 
 int
@@ -863,8 +866,8 @@ ioports_permit_access(struct domain *d, 
     lp_offset = PAGE_ALIGN(IO_SPACE_SPARSE_ENCODING(lp));
 
     for (off = fp_offset; off <= lp_offset; off += PAGE_SIZE)
-        __assign_domain_page(d, IO_PORTS_PADDR + off,
-                             __pa(ia64_iobase) + off, ASSIGN_nocache);
+        (void)__assign_domain_page(d, IO_PORTS_PADDR + off,
+                                   __pa(ia64_iobase) + off, ASSIGN_nocache);
 
     return 0;
 }
@@ -933,7 +936,7 @@ assign_domain_same_page(struct domain *d
     //XXX optimization
     unsigned long end = PAGE_ALIGN(mpaddr + size);
     for (mpaddr &= PAGE_MASK; mpaddr < end; mpaddr += PAGE_SIZE) {
-        __assign_domain_page(d, mpaddr, mpaddr, flags);
+        (void)__assign_domain_page(d, mpaddr, mpaddr, flags);
     }
 }
 
@@ -1255,6 +1258,126 @@ out1:
     put_domain(rd);
     return error;
 }
+
+#ifdef CONFIG_XEN_IA64_EXPOSE_P2M
+static struct page_info* p2m_pte_zero_page = NULL;
+
+void
+expose_p2m_init(void)
+{
+    pte_t* pte;
+
+    pte = pte_alloc_one_kernel(NULL, 0);
+    BUG_ON(pte == NULL);
+    smp_mb();// make contents of the page visible.
+    p2m_pte_zero_page = virt_to_page(pte);
+}
+
+static int
+expose_p2m_page(struct domain* d, unsigned long mpaddr, struct page_info* page)
+{
+    // we can't get_page(page) here.
+    // pte page is allocated form xen heap.(see pte_alloc_one_kernel().)
+    // so that the page has NULL page owner and it's reference count
+    // is useless.
+    // see also relinquish_pte()'s page_get_owner() == NULL check.
+    BUG_ON(page_get_owner(page) != NULL);
+
+    return __assign_domain_page(d, mpaddr, page_to_maddr(page),
+                                ASSIGN_readonly);
+}
+
+// It is possible to optimize loop, But this isn't performance critical.
+unsigned long
+dom0vp_expose_p2m(struct domain* d,
+                  unsigned long conv_start_gpfn,
+                  unsigned long assign_start_gpfn,
+                  unsigned long expose_size, unsigned long granule_pfn)
+{
+    unsigned long expose_num_pfn = expose_size >> PAGE_SHIFT;
+    unsigned long i;
+    volatile pte_t* conv_pte;
+    volatile pte_t* assign_pte;
+
+    if ((expose_size % PAGE_SIZE) != 0 ||
+        (granule_pfn % PTRS_PER_PTE) != 0 ||
+        (expose_num_pfn % PTRS_PER_PTE) != 0 ||
+        (conv_start_gpfn % granule_pfn) != 0 ||
+        (assign_start_gpfn % granule_pfn) != 0 ||
+        (expose_num_pfn % granule_pfn) != 0) {
+        DPRINTK("%s conv_start_gpfn 0x%016lx assign_start_gpfn 0x%016lx "
+                "expose_size 0x%016lx granulte_pfn 0x%016lx\n", __func__, 
+                conv_start_gpfn, assign_start_gpfn, expose_size, granule_pfn);
+        return -EINVAL;
+    }
+
+    if (granule_pfn != PTRS_PER_PTE) {
+        DPRINTK("%s granule_pfn 0x%016lx PTRS_PER_PTE 0x%016lx\n",
+                __func__, granule_pfn, PTRS_PER_PTE);
+        return -ENOSYS;
+    }
+
+    // allocate pgd, pmd.
+    i = conv_start_gpfn;
+    while (i < expose_num_pfn) {
+        conv_pte = lookup_noalloc_domain_pte(d, (conv_start_gpfn + i) <<
+                                             PAGE_SHIFT);
+        if (conv_pte == NULL) {
+            i++;
+            continue;
+        }
+        
+        assign_pte = lookup_alloc_domain_pte(d, (assign_start_gpfn <<
+                                             PAGE_SHIFT) + i * sizeof(pte_t));
+        if (assign_pte == NULL) {
+            DPRINTK("%s failed to allocate pte page\n", __func__);
+            return -ENOMEM;
+        }
+
+        // skip to next pte page
+        i += PTRS_PER_PTE;
+        i &= ~(PTRS_PER_PTE - 1);
+    }
+
+    // expose pte page
+    i = 0;
+    while (i < expose_num_pfn) {
+        conv_pte = lookup_noalloc_domain_pte(d, (conv_start_gpfn + i) <<
+                                             PAGE_SHIFT);
+        if (conv_pte == NULL) {
+            i++;
+            continue;
+        }
+
+        if (expose_p2m_page(d, (assign_start_gpfn << PAGE_SHIFT) +
+                            i * sizeof(pte_t), virt_to_page(conv_pte)) < 0) {
+            DPRINTK("%s failed to assign page\n", __func__);
+            return -EAGAIN;
+        }
+
+        // skip to next pte page
+        i += PTRS_PER_PTE;
+        i &= ~(PTRS_PER_PTE - 1);
+    }
+
+    // expose p2m_pte_zero_page 
+    for (i = 0; i < expose_num_pfn / PTRS_PER_PTE + 1; i++) {
+        assign_pte = lookup_noalloc_domain_pte(d, (assign_start_gpfn + i) <<
+                                               PAGE_SHIFT);
+        BUG_ON(assign_pte == NULL);
+        if (pte_present(*assign_pte)) {
+            continue;
+        }
+        if (expose_p2m_page(d, (assign_start_gpfn + i) << PAGE_SHIFT,
+                            p2m_pte_zero_page) < 0) {
+            DPRINTK("%s failed to assign zero-pte page\n", __func__);
+            return -EAGAIN;
+        }
+    }
+    
+    return 0;
+}
+#endif
 
 // grant table host mapping
 // mpaddr: host_addr: pseudo physical address
diff -r 7cfc7cb7cea7 -r 0bb486157ff5 xen/arch/ia64/xen/xensetup.c
--- a/xen/arch/ia64/xen/xensetup.c      Wed Oct 04 22:12:14 2006 -0600
+++ b/xen/arch/ia64/xen/xensetup.c      Wed Oct 04 22:12:25 2006 -0600
@@ -499,6 +499,8 @@ printk("num_online_cpus=%d, max_cpus=%d\
         efi.hcdp = NULL;
     }
 
+    expose_p2m_init();
+
     /* Create initial domain 0. */
     dom0 = domain_create(0);
     if ( (dom0 == NULL) || (alloc_vcpu(dom0, 0, 0) == NULL) )
diff -r 7cfc7cb7cea7 -r 0bb486157ff5 xen/include/asm-ia64/mm.h
--- a/xen/include/asm-ia64/mm.h Wed Oct 04 22:12:14 2006 -0600
+++ b/xen/include/asm-ia64/mm.h Wed Oct 04 22:12:25 2006 -0600
@@ -424,7 +424,7 @@ extern void relinquish_mm(struct domain*
 extern void relinquish_mm(struct domain* d);
 extern struct page_info * assign_new_domain_page(struct domain *d, unsigned 
long mpaddr);
 extern void assign_new_domain0_page(struct domain *d, unsigned long mpaddr);
-extern void __assign_domain_page(struct domain *d, unsigned long mpaddr, 
unsigned long physaddr, unsigned long flags);
+extern int __assign_domain_page(struct domain *d, unsigned long mpaddr, 
unsigned long physaddr, unsigned long flags);
 extern void assign_domain_page(struct domain *d, unsigned long mpaddr, 
unsigned long physaddr);
 extern void assign_domain_io_page(struct domain *d, unsigned long mpaddr, 
unsigned long flags);
 struct p2m_entry;
@@ -439,6 +439,13 @@ extern unsigned long do_dom0vp_op(unsign
 extern unsigned long do_dom0vp_op(unsigned long cmd, unsigned long arg0, 
unsigned long arg1, unsigned long arg2, unsigned long arg3);
 extern unsigned long dom0vp_zap_physmap(struct domain *d, unsigned long gpfn, 
unsigned int extent_order);
 extern unsigned long dom0vp_add_physmap(struct domain* d, unsigned long gpfn, 
unsigned long mfn, unsigned long flags, domid_t domid);
+#ifdef CONFIG_XEN_IA64_EXPOSE_P2M
+extern void expose_p2m_init(void);
+extern unsigned long dom0vp_expose_p2m(struct domain* d, unsigned long 
conv_start_gpfn, unsigned long assign_start_gpfn, unsigned long expose_size, 
unsigned long granule_pfn);
+#else
+#define expose_p2m_init()       do { } while (0)
+#define dom0vp_expose_p2m(d, conv_start_gpfn, assign_start_gpfn, expose_size, 
granule_pfn)     (-ENOSYS)
+#endif
 
 extern volatile unsigned long *mpt_table;
 extern unsigned long gmfn_to_mfn_foreign(struct domain *d, unsigned long gpfn);
diff -r 7cfc7cb7cea7 -r 0bb486157ff5 xen/include/public/arch-ia64.h
--- a/xen/include/public/arch-ia64.h    Wed Oct 04 22:12:14 2006 -0600
+++ b/xen/include/public/arch-ia64.h    Wed Oct 04 22:12:25 2006 -0600
@@ -348,6 +348,9 @@ DEFINE_XEN_GUEST_HANDLE(vcpu_guest_conte
 /* Assign machine page frame to dom0's pseudo physical address space.  */
 #define IA64_DOM0VP_add_physmap         6
 
+/* expose the p2m table into domain */
+#define IA64_DOM0VP_expose_p2m          7
+
 // flags for page assignement to pseudo physical address space
 #define _ASSIGN_readonly                0
 #define ASSIGN_readonly                 (1UL << _ASSIGN_readonly)

_______________________________________________
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] expose p2m table. xen side part., Xen patchbot-unstable <=