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] p2m exposure. linux side part.

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

This patch introduce compile time option XEN_IA64_EXPOSE_P2M
to enable this feature and boot option xen_ia64_p2m_expose to
disable the functionality.
This patch also introduce XEN_IA64_EXPOSE_P2M_USE_DTR to map p2m table
with dtr and boot option xen_ia64_p2m_expose_use_dtr to disable it.

Signed-off-by: Isaku Yamahata <yamahata@xxxxxxxxxxxxx>
---
 linux-2.6-xen-sparse/arch/ia64/Kconfig            |   14 +
 linux-2.6-xen-sparse/arch/ia64/xen/hypervisor.c   |  279 ++++++++++++++++++++++
 linux-2.6-xen-sparse/include/asm-ia64/hypercall.h |   12 
 linux-2.6-xen-sparse/include/asm-ia64/maddr.h     |   15 +
 4 files changed, 320 insertions(+)

diff -r 0bb486157ff5 -r d1d9f3f6ca09 linux-2.6-xen-sparse/arch/ia64/Kconfig
--- a/linux-2.6-xen-sparse/arch/ia64/Kconfig    Wed Oct 04 22:12:25 2006 -0600
+++ b/linux-2.6-xen-sparse/arch/ia64/Kconfig    Wed Oct 04 22:12:29 2006 -0600
@@ -63,6 +63,20 @@ config XEN_IA64_VDSO_PARAVIRT
        default y
        help
          vDSO paravirtualization
+
+config XEN_IA64_EXPOSE_P2M
+       bool "Xen/IA64 exposure p2m table"
+       depends on XEN
+       default y
+       help
+         expose p2m from xen
+
+config XEN_IA64_EXPOSE_P2M_USE_DTR
+       bool "Xen/IA64 map p2m table with dtr"
+       depends on XEN_IA64_EXPOSE_P2M
+       default y
+       help
+         use dtr to map the exposed p2m table
 
 config SCHED_NO_NO_OMIT_FRAME_POINTER
        bool
diff -r 0bb486157ff5 -r d1d9f3f6ca09 
linux-2.6-xen-sparse/arch/ia64/xen/hypervisor.c
--- a/linux-2.6-xen-sparse/arch/ia64/xen/hypervisor.c   Wed Oct 04 22:12:25 
2006 -0600
+++ b/linux-2.6-xen-sparse/arch/ia64/xen/hypervisor.c   Wed Oct 04 22:12:29 
2006 -0600
@@ -39,6 +39,8 @@ EXPORT_SYMBOL(xen_start_info);
 
 int running_on_xen;
 EXPORT_SYMBOL(running_on_xen);
+
+static int p2m_expose_init(void);
 
 //XXX same as i386, x86_64 contiguous_bitmap_set(), contiguous_bitmap_clear()
 // move those to lib/contiguous_bitmap?
@@ -448,6 +450,10 @@ out:
               privcmd_resource_min, privcmd_resource_max, 
               (privcmd_resource_max - privcmd_resource_min) >> 20);
        BUG_ON(privcmd_resource_min >= privcmd_resource_max);
+
+       // XXX this should be somewhere appropriate
+       (void)p2m_expose_init();
+
        return 0;
 }
 late_initcall(xen_ia64_privcmd_init);
@@ -753,3 +759,276 @@ time_resume(void)
        /* Just trigger a tick.  */
        ia64_cpu_local_tick();
 }
+
+///////////////////////////////////////////////////////////////////////////
+// expose p2m table
+#ifdef CONFIG_XEN_IA64_EXPOSE_P2M
+#include <linux/cpu.h>
+#include <asm/uaccess.h>
+
+int p2m_initialized __read_mostly = 0;
+
+unsigned long p2m_min_low_pfn __read_mostly;
+unsigned long p2m_max_low_pfn __read_mostly;
+unsigned long p2m_convert_min_pfn __read_mostly;
+unsigned long p2m_convert_max_pfn __read_mostly;
+
+static struct resource p2m_resource = {
+       .name    = "Xen p2m table",
+       .flags   = IORESOURCE_MEM,
+};
+static unsigned long p2m_assign_start_pfn __read_mostly;
+static unsigned long p2m_assign_end_pfn __read_mostly;
+volatile const pte_t* p2m_pte __read_mostly;
+
+#define GRNULE_PFN     PTRS_PER_PTE
+static unsigned long p2m_granule_pfn __read_mostly = GRNULE_PFN;
+
+#define ROUNDDOWN(x, y)  ((x) & ~((y) - 1))
+#define ROUNDUP(x, y)    (((x) + (y) - 1) & ~((y) - 1))
+
+#define P2M_PREFIX     "Xen p2m: "
+
+static int xen_ia64_p2m_expose __read_mostly = 1;
+module_param(xen_ia64_p2m_expose, int, 0);
+MODULE_PARM_DESC(xen_ia64_p2m_expose,
+                 "enable/disable xen/ia64 p2m exposure optimization\n");
+
+#ifdef CONFIG_XEN_IA64_EXPOSE_P2M_USE_DTR
+static int xen_ia64_p2m_expose_use_dtr __read_mostly = 1;
+module_param(xen_ia64_p2m_expose_use_dtr, int, 0);
+MODULE_PARM_DESC(xen_ia64_p2m_expose_use_dtr,
+                 "use/unuse dtr to map exposed p2m table\n");
+
+static const int p2m_page_shifts[] = {
+       _PAGE_SIZE_4K,
+       _PAGE_SIZE_8K,
+       _PAGE_SIZE_16K,
+       _PAGE_SIZE_64K,
+       _PAGE_SIZE_256K,
+       _PAGE_SIZE_1M,
+       _PAGE_SIZE_4M,
+       _PAGE_SIZE_16M,
+       _PAGE_SIZE_64M,
+       _PAGE_SIZE_256M,
+};
+
+struct p2m_itr_arg {
+       unsigned long vaddr;
+       unsigned long pteval;
+       unsigned long log_page_size;
+};
+static struct p2m_itr_arg p2m_itr_arg __read_mostly;
+
+// This should be in asm-ia64/kregs.h
+#define IA64_TR_P2M_TABLE      3
+
+static void
+p2m_itr(void* info)
+{
+       struct p2m_itr_arg* arg = (struct p2m_itr_arg*)info;
+       ia64_itr(0x2, IA64_TR_P2M_TABLE,
+                arg->vaddr, arg->pteval, arg->log_page_size);
+       ia64_srlz_d();
+}
+
+static int
+p2m_expose_dtr_call(struct notifier_block *self,
+                    unsigned long event, void* ptr)
+{
+       unsigned int cpu = (unsigned int)(long)ptr;
+       if (event != CPU_ONLINE)
+               return 0;
+       if (!(p2m_initialized && xen_ia64_p2m_expose_use_dtr))
+               smp_call_function_single(cpu, &p2m_itr, &p2m_itr_arg, 1, 1);
+       return 0;
+}
+
+static struct notifier_block p2m_expose_dtr_hotplug_notifier = {
+       .notifier_call = p2m_expose_dtr_call,
+       .next          = NULL,
+       .priority      = 0
+};
+#endif
+
+static int
+p2m_expose_init(void)
+{
+       unsigned long num_pfn;
+       unsigned long size = 0;
+       unsigned long p2m_size = 0;
+       unsigned long align = ~0UL;
+       int error = 0;
+#ifdef CONFIG_XEN_IA64_EXPOSE_P2M_USE_DTR
+       int i;
+       unsigned long page_size;
+       unsigned long log_page_size = 0;
+#endif
+
+       if (!xen_ia64_p2m_expose)
+               return -ENOSYS;
+       if (p2m_initialized)
+               return 0;
+
+#ifdef CONFIG_XEN_IA64_EXPOSE_P2M_USE_DTR
+       error = register_cpu_notifier(&p2m_expose_dtr_hotplug_notifier);
+       if (error < 0)
+               return error;
+#endif
+
+       lock_cpu_hotplug();
+       if (p2m_initialized)
+               goto out;
+
+#ifdef CONFIG_DISCONTIGMEM
+       p2m_min_low_pfn = min_low_pfn;
+       p2m_max_low_pfn = max_low_pfn;
+#else
+       p2m_min_low_pfn = 0;
+       p2m_max_low_pfn = max_pfn;
+#endif
+
+#ifdef CONFIG_XEN_IA64_EXPOSE_P2M_USE_DTR
+       if (xen_ia64_p2m_expose_use_dtr) {
+               unsigned long granule_pfn = 0;
+               p2m_size = p2m_max_low_pfn - p2m_min_low_pfn;
+               for (i = 0;
+                    i < sizeof(p2m_page_shifts)/sizeof(p2m_page_shifts[0]);
+                    i++) {
+                       log_page_size = p2m_page_shifts[i];
+                       page_size = 1UL << log_page_size;
+                       if (page_size < p2m_size)
+                               continue;
+
+                       granule_pfn = max(page_size >> PAGE_SHIFT,
+                                         p2m_granule_pfn);
+                       p2m_convert_min_pfn = ROUNDDOWN(p2m_min_low_pfn,
+                                                       granule_pfn);
+                       p2m_convert_max_pfn = ROUNDUP(p2m_max_low_pfn,
+                                                     granule_pfn);
+                       num_pfn = p2m_convert_max_pfn - p2m_convert_min_pfn;
+                       size = num_pfn << PAGE_SHIFT;
+                       p2m_size = num_pfn / PTRS_PER_PTE;
+                       p2m_size = ROUNDUP(p2m_size, granule_pfn << PAGE_SHIFT);
+                       if (p2m_size == page_size)
+                               break;
+               }
+               if (p2m_size != page_size) {
+                       printk(KERN_ERR "p2m_size != page_size\n");
+                       error = -EINVAL;
+                       goto out;
+               }
+               align = max(privcmd_resource_align, granule_pfn << PAGE_SHIFT);
+       } else
+#endif
+       {
+               BUG_ON(p2m_granule_pfn & (p2m_granule_pfn - 1));
+               p2m_convert_min_pfn = ROUNDDOWN(p2m_min_low_pfn,
+                                               p2m_granule_pfn);
+               p2m_convert_max_pfn = ROUNDUP(p2m_max_low_pfn, p2m_granule_pfn);
+               num_pfn = p2m_convert_max_pfn - p2m_convert_min_pfn;
+               size = num_pfn << PAGE_SHIFT;
+               p2m_size = num_pfn / PTRS_PER_PTE;
+               p2m_size = ROUNDUP(p2m_size, p2m_granule_pfn << PAGE_SHIFT);
+               align = max(privcmd_resource_align,
+                           p2m_granule_pfn << PAGE_SHIFT);
+       }
+       
+       // use privcmd region
+       error = allocate_resource(&iomem_resource, &p2m_resource, p2m_size,
+                                 privcmd_resource_min, privcmd_resource_max,
+                                 align, NULL, NULL);
+       if (error) {
+               printk(KERN_ERR P2M_PREFIX
+                      "can't allocate region for p2m exposure "
+                      "[0x%016lx, 0x%016lx) 0x%016lx\n",
+                      p2m_convert_min_pfn, p2m_convert_max_pfn, p2m_size);
+               goto out;
+       }
+
+       p2m_assign_start_pfn = p2m_resource.start >> PAGE_SHIFT;
+       p2m_assign_end_pfn = p2m_resource.end >> PAGE_SHIFT;
+       
+       error = HYPERVISOR_expose_p2m(p2m_convert_min_pfn,
+                                     p2m_assign_start_pfn,
+                                     size, p2m_granule_pfn);
+       if (error) {
+               printk(KERN_ERR P2M_PREFIX "failed expose p2m hypercall %d\n",
+                      error);
+               printk(KERN_ERR P2M_PREFIX "conv 0x%016lx assign 0x%016lx "
+                      "size 0x%016lx granule 0x%016lx\n",
+                      p2m_convert_min_pfn, p2m_assign_start_pfn,
+                      size, p2m_granule_pfn);;
+               release_resource(&p2m_resource);
+               goto out;
+       }
+       p2m_pte = (volatile const pte_t*)pfn_to_kaddr(p2m_assign_start_pfn);
+#ifdef CONFIG_XEN_IA64_EXPOSE_P2M_USE_DTR
+       if (xen_ia64_p2m_expose_use_dtr) {
+               p2m_itr_arg.vaddr = (unsigned long)__va(p2m_assign_start_pfn
+                                                       << PAGE_SHIFT);
+               p2m_itr_arg.pteval = pte_val(pfn_pte(p2m_assign_start_pfn,
+                                                    PAGE_KERNEL));
+               p2m_itr_arg.log_page_size = log_page_size;
+               smp_mb();
+               smp_call_function(&p2m_itr, &p2m_itr_arg, 1, 1);
+               p2m_itr(&p2m_itr_arg);
+       }
+#endif 
+       smp_mb();
+       p2m_initialized = 1;
+       printk(P2M_PREFIX "assign p2m table of [0x%016lx, 0x%016lx)\n",
+              p2m_convert_min_pfn << PAGE_SHIFT,
+              p2m_convert_max_pfn << PAGE_SHIFT);
+       printk(P2M_PREFIX "to [0x%016lx, 0x%016lx) (%ld KBytes)\n",
+              p2m_assign_start_pfn << PAGE_SHIFT,
+              p2m_assign_end_pfn << PAGE_SHIFT,
+              p2m_size / 1024);
+out:
+       unlock_cpu_hotplug();
+       return error;
+}
+
+#ifdef notyet
+void
+p2m_expose_cleanup(void)
+{
+       BUG_ON(!p2m_initialized);
+#ifdef CONFIG_XEN_IA64_EXPOSE_P2M_USE_DTR
+       unregister_cpu_notifier(&p2m_expose_dtr_hotplug_notifier);
+#endif
+       release_resource(&p2m_resource);
+}
+#endif
+
+//XXX inlinize?
+unsigned long
+p2m_phystomach(unsigned long gpfn)
+{
+       volatile const pte_t* pte;
+       unsigned long mfn;
+       unsigned long pteval;
+       
+       if (!p2m_initialized ||
+           gpfn < p2m_min_low_pfn || gpfn > p2m_max_low_pfn
+           /* || !pfn_valid(gpfn) */)
+               return INVALID_MFN;
+       pte = p2m_pte + (gpfn - p2m_convert_min_pfn);
+
+       mfn = INVALID_MFN;
+       if (likely(__get_user(pteval, (unsigned long __user *)pte) == 0 &&
+                  pte_present(__pte(pteval)) &&
+                  pte_pfn(__pte(pteval)) != (INVALID_MFN >> PAGE_SHIFT)))
+               mfn = (pteval & _PFN_MASK) >> PAGE_SHIFT;
+
+       return mfn;
+}
+
+EXPORT_SYMBOL_GPL(p2m_initialized);
+EXPORT_SYMBOL_GPL(p2m_min_low_pfn);
+EXPORT_SYMBOL_GPL(p2m_max_low_pfn);
+EXPORT_SYMBOL_GPL(p2m_convert_min_pfn);
+EXPORT_SYMBOL_GPL(p2m_convert_max_pfn);
+EXPORT_SYMBOL_GPL(p2m_pte);
+EXPORT_SYMBOL_GPL(p2m_phystomach);
+#endif
diff -r 0bb486157ff5 -r d1d9f3f6ca09 
linux-2.6-xen-sparse/include/asm-ia64/hypercall.h
--- a/linux-2.6-xen-sparse/include/asm-ia64/hypercall.h Wed Oct 04 22:12:25 
2006 -0600
+++ b/linux-2.6-xen-sparse/include/asm-ia64/hypercall.h Wed Oct 04 22:12:29 
2006 -0600
@@ -377,6 +377,18 @@ HYPERVISOR_add_physmap(unsigned long gpf
        }
        return ret;
 }
+
+#ifdef CONFIG_XEN_IA64_EXPOSE_P2M
+static inline unsigned long
+HYPERVISOR_expose_p2m(unsigned long conv_start_gpfn,
+                      unsigned long assign_start_gpfn,
+                      unsigned long expose_size, unsigned long granule_pfn)
+{
+       return _hypercall5(unsigned long, ia64_dom0vp_op,
+                          IA64_DOM0VP_expose_p2m, conv_start_gpfn,
+                          assign_start_gpfn, expose_size, granule_pfn);
+}
+#endif
 
 // for balloon driver
 #define HYPERVISOR_update_va_mapping(va, new_val, flags) (0)
diff -r 0bb486157ff5 -r d1d9f3f6ca09 
linux-2.6-xen-sparse/include/asm-ia64/maddr.h
--- a/linux-2.6-xen-sparse/include/asm-ia64/maddr.h     Wed Oct 04 22:12:25 
2006 -0600
+++ b/linux-2.6-xen-sparse/include/asm-ia64/maddr.h     Wed Oct 04 22:12:29 
2006 -0600
@@ -10,11 +10,26 @@
 
 #define INVALID_P2M_ENTRY       (~0UL)
 
+#ifdef CONFIG_XEN_IA64_EXPOSE_P2M
+extern int p2m_initialized;
+extern unsigned long p2m_min_low_pfn;
+extern unsigned long p2m_max_low_pfn;
+extern unsigned long p2m_convert_min_pfn;
+extern unsigned long p2m_convert_max_pfn;
+extern volatile const pte_t* p2m_pte;
+unsigned long p2m_phystomach(unsigned long gpfn);
+#else
+#define p2m_initialized                (0)
+#define p2m_phystomach(gpfn)   INVALID_MFN
+#endif
+
 /* XXX xen page size != page size */
 static inline unsigned long
 pfn_to_mfn_for_dma(unsigned long pfn)
 {
        unsigned long mfn;
+       if (p2m_initialized)
+               return p2m_phystomach(pfn);
        mfn = HYPERVISOR_phystomach(pfn);
        BUG_ON(mfn == 0); // XXX
        BUG_ON(mfn == INVALID_P2M_ENTRY); // XXX

_______________________________________________
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] p2m exposure. linux side part., Xen patchbot-unstable <=