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] Implement new memory_op() XENMEM_machphys_mfn_list. Repl

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] Implement new memory_op() XENMEM_machphys_mfn_list. Replaces old
From: Xen patchbot -unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Fri, 25 Nov 2005 19:42:07 +0000
Delivery-date: Fri, 25 Nov 2005 19:42:18 +0000
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
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 kaf24@xxxxxxxxxxxxxxxxxxxx
# Node ID c3cfc4ff3b08b01051e6fa0741e1e014a1307aea
# Parent  549130374cfad466e526bed31199c7a5eee5eb38
Implement new memory_op() XENMEM_machphys_mfn_list. Replaces old
privcmd Linux ioctl and includes an implementation for x86/64.

Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx>

diff -r 549130374cfa -r c3cfc4ff3b08 
linux-2.6-xen-sparse/drivers/xen/privcmd/privcmd.c
--- a/linux-2.6-xen-sparse/drivers/xen/privcmd/privcmd.c        Fri Nov 25 
16:58:36 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/privcmd/privcmd.c        Fri Nov 25 
17:43:35 2005
@@ -213,55 +213,6 @@
        break;
 #endif
 
-#ifndef __ia64__
-       case IOCTL_PRIVCMD_GET_MACH2PHYS_MFNS: {
-               pgd_t *pgd; 
-               pud_t *pud; 
-               pmd_t *pmd; 
-               unsigned long m2pv, m2p_mfn;    
-               privcmd_m2pmfns_t m; 
-               unsigned long __user *p;
-               int i; 
-
-#if defined (__x86_64__)
-               /* 
-               ** XXX SMH: the below procedure won't work for 64 since 
-               ** we don't have access to the memory which maps the M2P. 
-               ** A proper fix will probably involve moving this 
-               ** functionality to Xen - for now just return an error 
-               ** here rather than GPF'ing in the kernel. 
-               */
-               ret = -EINVAL; 
-               break; 
-#endif
-
-               if (copy_from_user(&m, udata, sizeof(m)))
-                       return -EFAULT;
-
-               m2pv = (unsigned long)machine_to_phys_mapping;
-
-               p = m.arr; 
-
-               for (i=0; i < m.num; i++) { 
-                       pgd = pgd_offset_k(m2pv);
-                       pud = pud_offset(pgd, m2pv);
-                       pmd = pmd_offset(pud, m2pv);
-                       m2p_mfn  = (*(uint64_t *)pmd >> PAGE_SHIFT)&0xFFFFFFFF;
-                       m2p_mfn += pte_index(m2pv);
-
-                       if (put_user(m2p_mfn, p + i))
-                               return -EFAULT;
-
-                       m2pv += (1 << 21); 
-               }
-
-               ret = 0; 
-               break; 
-
-       }
-       break;
-#endif
-
        default:
                ret = -EINVAL;
                break;
diff -r 549130374cfa -r c3cfc4ff3b08 
linux-2.6-xen-sparse/include/asm-xen/linux-public/privcmd.h
--- a/linux-2.6-xen-sparse/include/asm-xen/linux-public/privcmd.h       Fri Nov 
25 16:58:36 2005
+++ b/linux-2.6-xen-sparse/include/asm-xen/linux-public/privcmd.h       Fri Nov 
25 17:43:35 2005
@@ -59,11 +59,6 @@
        unsigned long __user *arr; /* array of mfns - top nibble set on err */
 } privcmd_mmapbatch_t; 
 
-typedef struct privcmd_m2pmfns { 
-       int num;    /* max number of mfns to return */
-       unsigned long __user *arr; /* array of mfns */
-} privcmd_m2pmfns_t; 
-
 typedef struct privcmd_blkmsg
 {
        unsigned long op;
@@ -82,8 +77,6 @@
        _IOC(_IOC_NONE, 'P', 2, sizeof(privcmd_mmap_t))
 #define IOCTL_PRIVCMD_MMAPBATCH                                        \
        _IOC(_IOC_NONE, 'P', 3, sizeof(privcmd_mmapbatch_t))
-#define IOCTL_PRIVCMD_GET_MACH2PHYS_MFNS                       \
-       _IOC(_IOC_READ, 'P', 4, sizeof(unsigned long))
 
 #endif /* __LINUX_PUBLIC_PRIVCMD_H__ */
 
diff -r 549130374cfa -r c3cfc4ff3b08 tools/libxc/xc_linux_save.c
--- a/tools/libxc/xc_linux_save.c       Fri Nov 25 16:58:36 2005
+++ b/tools/libxc/xc_linux_save.c       Fri Nov 25 17:43:35 2005
@@ -502,7 +502,7 @@
                                  unsigned long max_mfn, 
                                  int prot) 
 { 
-    privcmd_m2pmfns_t m2p_mfns; 
+    struct xen_machphys_mfn_list xmml;
     privcmd_mmap_t ioctlx; 
     privcmd_mmap_entry_t *entries; 
     unsigned long m2p_chunks, m2p_size; 
@@ -512,50 +512,45 @@
     m2p_size   = M2P_SIZE(max_mfn); 
     m2p_chunks = M2P_CHUNKS(max_mfn); 
 
-
-    m2p_mfns.num = m2p_chunks; 
-
-    if(!(m2p_mfns.arr = malloc(m2p_chunks * sizeof(unsigned long)))) { 
+    xmml.max_extents = m2p_chunks;
+    if (!(xmml.extent_start = malloc(m2p_chunks * sizeof(unsigned long)))) { 
         ERR("failed to allocate space for m2p mfns!\n"); 
         return NULL; 
     } 
 
-    if (ioctl(xc_handle, IOCTL_PRIVCMD_GET_MACH2PHYS_MFNS, &m2p_mfns) < 0) {
+    if (xc_memory_op(xc_handle, XENMEM_machphys_mfn_list, &xmml) ||
+        (xmml.nr_extents != m2p_chunks)) {
         ERR("xc_get_m2p_mfns:"); 
         return NULL;
     }
 
-    if((m2p = mmap(NULL, m2p_size, prot, 
-                   MAP_SHARED, xc_handle, 0)) == MAP_FAILED) {
+    if ((m2p = mmap(NULL, m2p_size, prot, 
+                    MAP_SHARED, xc_handle, 0)) == MAP_FAILED) {
         ERR("failed to mmap m2p"); 
         return NULL; 
     } 
-    
-
-    if(!(entries = malloc(m2p_chunks * sizeof(privcmd_mmap_entry_t)))) { 
+
+    if (!(entries = malloc(m2p_chunks * sizeof(privcmd_mmap_entry_t)))) { 
         ERR("failed to allocate space for mmap entries!\n"); 
         return NULL; 
     } 
 
-
     ioctlx.num   = m2p_chunks;
     ioctlx.dom   = DOMID_XEN; 
     ioctlx.entry = entries; 
     
-    for(i=0; i < m2p_chunks; i++) { 
-        
+    for (i=0; i < m2p_chunks; i++) { 
         entries[i].va = (unsigned long)(((void *)m2p) + (i * M2P_CHUNK_SIZE)); 
-        entries[i].mfn = m2p_mfns.arr[i]; 
+        entries[i].mfn = xmml.extent_start[i];
         entries[i].npages = M2P_CHUNK_SIZE >> PAGE_SHIFT;
-
-    }
-
-    if((rc = ioctl(xc_handle, IOCTL_PRIVCMD_MMAP, &ioctlx)) < 0) {
+    }
+
+    if ((rc = ioctl(xc_handle, IOCTL_PRIVCMD_MMAP, &ioctlx)) < 0) {
         ERR("ioctl_mmap failed (rc = %d)", rc); 
         return NULL; 
     }
-        
-    free(m2p_mfns.arr); 
+
+    free(xmml.extent_start);
     free(entries); 
 
     return m2p; 
diff -r 549130374cfa -r c3cfc4ff3b08 tools/libxc/xc_private.c
--- a/tools/libxc/xc_private.c  Fri Nov 25 16:58:36 2005
+++ b/tools/libxc/xc_private.c  Fri Nov 25 17:43:35 2005
@@ -190,6 +190,7 @@
 {
     DECLARE_HYPERCALL;
     struct xen_memory_reservation *reservation = arg;
+    struct xen_machphys_mfn_list *xmml = arg;
     long ret = -EINVAL;
 
     hypercall.op     = __HYPERVISOR_memory_op;
@@ -214,6 +215,20 @@
             goto out1;
         }
         break;
+    case XENMEM_machphys_mfn_list:
+        if ( mlock(xmml, sizeof(*xmml)) != 0 )
+        {
+            PERROR("Could not mlock");
+            goto out1;
+        }
+        if ( mlock(xmml->extent_start,
+                   xmml->max_extents * sizeof(unsigned long)) != 0 )
+        {
+            PERROR("Could not mlock");
+            safe_munlock(xmml, sizeof(*xmml));
+            goto out1;
+        }
+        break;
     }
 
     ret = do_xen_hypercall(xc_handle, &hypercall);
@@ -226,6 +241,11 @@
         if ( reservation->extent_start != NULL )
             safe_munlock(reservation->extent_start,
                          reservation->nr_extents * sizeof(unsigned long));
+        break;
+    case XENMEM_machphys_mfn_list:
+        safe_munlock(xmml, sizeof(*xmml));
+        safe_munlock(xmml->extent_start,
+                     xmml->max_extents * sizeof(unsigned long));
         break;
     }
 
diff -r 549130374cfa -r c3cfc4ff3b08 xen/arch/x86/x86_32/mm.c
--- a/xen/arch/x86/x86_32/mm.c  Fri Nov 25 16:58:36 2005
+++ b/xen/arch/x86/x86_32/mm.c  Fri Nov 25 17:43:35 2005
@@ -27,6 +27,7 @@
 #include <asm/page.h>
 #include <asm/flushtlb.h>
 #include <asm/fixmap.h>
+#include <public/memory.h>
 
 extern l1_pgentry_t *mapcache;
 
@@ -184,6 +185,41 @@
     }
 }
 
+long arch_memory_op(int op, void *arg)
+{
+    struct xen_machphys_mfn_list xmml;
+    unsigned long mfn;
+    unsigned int i, max;
+    long rc = 0;
+
+    switch ( op )
+    {
+    case XENMEM_machphys_mfn_list:
+        if ( copy_from_user(&xmml, arg, sizeof(xmml)) )
+            return -EFAULT;
+
+        max = min_t(unsigned int, xmml.max_extents, mpt_size >> 21);
+
+        for ( i = 0; i < max; i++ )
+        {
+            mfn = l2e_get_pfn(idle_pg_table_l2[l2_linear_offset(
+                RDWR_MPT_VIRT_START + (i << 21))]) + l1_table_offset(i << 21);
+            if ( put_user(mfn, &xmml.extent_start[i]) )
+                return -EFAULT;
+        }
+
+        if ( put_user(i, &((struct xen_machphys_mfn_list *)arg)->nr_extents) )
+            return -EFAULT;
+
+        break;
+
+    default:
+        rc = -ENOSYS;
+        break;
+    }
+
+    return rc;
+}
 
 long do_stack_switch(unsigned long ss, unsigned long esp)
 {
diff -r 549130374cfa -r c3cfc4ff3b08 xen/arch/x86/x86_64/mm.c
--- a/xen/arch/x86/x86_64/mm.c  Fri Nov 25 16:58:36 2005
+++ b/xen/arch/x86/x86_64/mm.c  Fri Nov 25 17:43:35 2005
@@ -28,6 +28,7 @@
 #include <asm/flushtlb.h>
 #include <asm/fixmap.h>
 #include <asm/msr.h>
+#include <public/memory.h>
 
 struct pfn_info *alloc_xen_pagetable(void)
 {
@@ -172,6 +173,51 @@
             page_set_owner(&frame_table[m2p_start_mfn+i], dom_xen);
         }
     }
+}
+
+long arch_memory_op(int op, void *arg)
+{
+    struct xen_machphys_mfn_list xmml;
+    l3_pgentry_t l3e;
+    l2_pgentry_t l2e;
+    unsigned long mfn, v;
+    unsigned int i;
+    long rc = 0;
+
+    switch ( op )
+    {
+    case XENMEM_machphys_mfn_list:
+        if ( copy_from_user(&xmml, arg, sizeof(xmml)) )
+            return -EFAULT;
+
+        for ( v = RDWR_MPT_VIRT_START; v != RDWR_MPT_VIRT_END; v += 1 << 21 )
+        {
+            l3e = l4e_to_l3e(idle_pg_table[l4_table_offset(v)])[
+                l3_table_offset(v)];
+            if ( !(l3e_get_flags(l3e) & _PAGE_PRESENT) )
+                break;
+            l2e = l3e_to_l2e(l3e)[l2_table_offset(v)];
+            if ( !(l2e_get_flags(l2e) & _PAGE_PRESENT) )
+                break;
+            mfn = l2e_get_pfn(l2e) + l1_table_offset(v);
+            if ( i == xmml.max_extents )
+                break;
+            if ( put_user(mfn, &xmml.extent_start[i]) )
+                return -EFAULT;
+            i++;
+        }
+
+        if ( put_user(i, &((struct xen_machphys_mfn_list *)arg)->nr_extents) )
+            return -EFAULT;
+
+        break;
+
+    default:
+        rc = -ENOSYS;
+        break;
+    }
+
+    return rc;
 }
 
 long do_stack_switch(unsigned long ss, unsigned long esp)
diff -r 549130374cfa -r c3cfc4ff3b08 xen/common/memory.c
--- a/xen/common/memory.c       Fri Nov 25 16:58:36 2005
+++ b/xen/common/memory.c       Fri Nov 25 17:43:35 2005
@@ -215,7 +215,7 @@
         break;
 
     default:
-        rc = -ENOSYS;
+        rc = arch_memory_op(op, arg);
         break;
     }
 
diff -r 549130374cfa -r c3cfc4ff3b08 xen/include/asm-ia64/mm.h
--- a/xen/include/asm-ia64/mm.h Fri Nov 25 16:58:36 2005
+++ b/xen/include/asm-ia64/mm.h Fri Nov 25 17:43:35 2005
@@ -440,4 +440,7 @@
 #define __gpa_to_mpa(_d, gpa)   \
     ((__gpfn_to_mfn((_d),(gpa)>>PAGE_SHIFT)<<PAGE_SHIFT)|((gpa)&~PAGE_MASK))
 
+/* Arch-specific portion of memory_op hypercall. */
+#define arch_memory_op(op, arg) (-ENOSYS)
+
 #endif /* __ASM_IA64_MM_H__ */
diff -r 549130374cfa -r c3cfc4ff3b08 xen/include/asm-x86/mm.h
--- a/xen/include/asm-x86/mm.h  Fri Nov 25 16:58:36 2005
+++ b/xen/include/asm-x86/mm.h  Fri Nov 25 17:43:35 2005
@@ -379,6 +379,9 @@
 
 void propagate_page_fault(unsigned long addr, u16 error_code);
 
-extern int __sync_lazy_execstate(void);
+int __sync_lazy_execstate(void);
+
+/* Arch-specific portion of memory_op hypercall. */
+long arch_memory_op(int op, void *arg);
 
 #endif /* __ASM_X86_MM_H__ */
diff -r 549130374cfa -r c3cfc4ff3b08 xen/include/public/memory.h
--- a/xen/include/public/memory.h       Fri Nov 25 16:58:36 2005
+++ b/xen/include/public/memory.h       Fri Nov 25 17:43:35 2005
@@ -60,6 +60,34 @@
 #define XENMEM_current_reservation  3
 #define XENMEM_maximum_reservation  4
 
+/*
+ * Returns a list of MFN bases of 2MB extents comprising the machine_to_phys
+ * mapping table. Architectures which do not have a m2p table do not implement
+ * this command.
+ * arg == addr of xen_machphys_mfn_list_t.
+ */
+#define XENMEM_machphys_mfn_list    5
+typedef struct xen_machphys_mfn_list {
+    /*
+     * Size of the 'extent_start' array. Fewer entries will be filled if the
+     * machphys table is smaller than max_extents * 2MB.
+     */
+    unsigned int max_extents;
+    
+    /*
+     * Pointer to buffer to fill with list of extent starts. If there are
+     * any large discontiguities in the machine address space, 2MB gaps in
+     * the machphys table will be represented by an MFN base of zero.
+     */
+    unsigned long *extent_start;
+
+    /*
+     * Number of extents written to the above array. This will be smaller
+     * than 'max_extents' if the machphys table is smaller than max_e * 2MB.
+     */
+    unsigned int nr_extents;
+} xen_machphys_mfn_list_t;
+
 #endif /* __XEN_PUBLIC_MEMORY_H__ */
 
 /*

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] Implement new memory_op() XENMEM_machphys_mfn_list. Replaces old, Xen patchbot -unstable <=