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

[Xen-changelog] [xen-unstable] [IA64] expose p2m table. xen side part.



# 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


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.