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-devel

[Xen-devel] [PATCH 5/5 TAKE 2] xenoprof: make xen xenoprof code arch-gen

To: xen-devel@xxxxxxxxxxxxxxxxxxx, Isaku Yamahata <yamahata@xxxxxxxxxxxxx>
Subject: [Xen-devel] [PATCH 5/5 TAKE 2] xenoprof: make xen xenoprof code arch-generic
From: Isaku Yamahata <yamahata@xxxxxxxxxxxxx>
Date: Tue, 14 Nov 2006 16:02:13 +0900
Cc: Isaku Yamahata <yamahata@xxxxxxxxxxxxx>, xen-ia64-devel@xxxxxxxxxxxxxxxxxxx
Delivery-date: Mon, 13 Nov 2006 23:05:11 -0800
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
In-reply-to: <20061114070138.9134.52656.sendpatchset@xxxxxxxxxxxxxxxxxxxxxx>
List-help: <mailto:xen-devel-request@lists.xensource.com?subject=help>
List-id: Xen developer discussion <xen-devel.lists.xensource.com>
List-post: <mailto:xen-devel@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=unsubscribe>
References: <20061114070138.9134.52656.sendpatchset@xxxxxxxxxxxxxxxxxxxxxx>
Sender: xen-devel-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User yamahata@xxxxxxxxxxxxx
# Date 1163486063 -32400
# Node ID 236b3f5ec6bfef2971864dd7bb16f286e5e83a83
# Parent  3bebc37b149280f5ff1e6091d578c7da73820f16
make xenoprof arch-generic with dynamic mapping/unmapping xenoprof buffer
support and auto translated mode support.
renamed xenoprof_get_buffer::buf_maddr, xenoprof_passive::buf_maddr to
xenoprof_get_buffer::buf_gmaddr, xenoprof_passive::buf_gmaddr
to support auto translated mode. With auto translated mode enabled,
it is gmaddr, not maddr.
PATCHNAME: make_xenoprof_of_xen_side_arch_generic

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

diff -r 3bebc37b1492 -r 236b3f5ec6bf 
linux-2.6-xen-sparse/arch/i386/oprofile/xenoprof.c
--- a/linux-2.6-xen-sparse/arch/i386/oprofile/xenoprof.c        Tue Nov 14 
15:34:22 2006 +0900
+++ b/linux-2.6-xen-sparse/arch/i386/oprofile/xenoprof.c        Tue Nov 14 
15:34:23 2006 +0900
@@ -93,7 +93,7 @@ int xenoprof_arch_map_shared_buffer(stru
 
        if ( (ret = direct_kernel_remap_pfn_range(
                      (unsigned long)area->addr,
-                     get_buffer->buf_maddr >> PAGE_SHIFT,
+                     get_buffer->buf_gmaddr >> PAGE_SHIFT,
                      npages * PAGE_SIZE, __pgprot(_KERNPG_TABLE),
                      DOMID_SELF)) ) {
                vunmap(area->addr);
@@ -127,7 +127,7 @@ int xenoprof_arch_set_passive(struct xen
 
        ret = direct_kernel_remap_pfn_range(
                (unsigned long)area->addr,
-               pdomain->buf_maddr >> PAGE_SHIFT,
+               pdomain->buf_gmaddr >> PAGE_SHIFT,
                npages * PAGE_SIZE, prot, DOMID_SELF);
        if (ret) {
                vunmap(area->addr);
diff -r 3bebc37b1492 -r 236b3f5ec6bf xen/arch/x86/oprofile/nmi_int.c
--- a/xen/arch/x86/oprofile/nmi_int.c   Tue Nov 14 15:34:22 2006 +0900
+++ b/xen/arch/x86/oprofile/nmi_int.c   Tue Nov 14 15:34:23 2006 +0900
@@ -33,7 +33,6 @@ static unsigned long saved_lvtpc[NR_CPUS
 #define VIRQ_BITMASK_SIZE (MAX_OPROF_DOMAINS/32 + 1)
 extern int active_domains[MAX_OPROF_DOMAINS];
 extern unsigned int adomains;
-extern struct domain *primary_profiler;
 extern struct domain *adomain_ptrs[MAX_OPROF_DOMAINS];
 extern unsigned long virq_ovf_pending[VIRQ_BITMASK_SIZE];
 extern int is_active(struct domain *d);
@@ -337,10 +336,10 @@ int nmi_init(int *num_events, int *is_pr
                return -ENODEV;
        }
 
-       if (primary_profiler == NULL) {
+       if (xenoprof_primary_profiler == NULL) {
                /* For now, only dom0 can be the primary profiler */
                if (current->domain->domain_id == 0) {
-                       primary_profiler = current->domain;
+                       xenoprof_primary_profiler = current->domain;
                        prim = 1;
                }
        }
diff -r 3bebc37b1492 -r 236b3f5ec6bf xen/common/xenoprof.c
--- a/xen/common/xenoprof.c     Tue Nov 14 15:34:22 2006 +0900
+++ b/xen/common/xenoprof.c     Tue Nov 14 15:34:23 2006 +0900
@@ -2,15 +2,17 @@
  * Copyright (C) 2005 Hewlett-Packard Co.
  * written by Aravind Menon & Jose Renato Santos
  *            (email: xenoprof@xxxxxxxxxxxxx)
+ *
+ * arch generic xenoprof and IA64 support.
+ * dynamic map/unmap xenoprof buffer support.
  * Copyright (c) 2006 Isaku Yamahata <yamahata at valinux co jp>
  *                    VA Linux Systems Japan K.K.
- * arch generic xenoprof and IA64 support.
  */
 
 #include <xen/guest_access.h>
 #include <xen/sched.h>
 #include <public/xenoprof.h>
-#include <asm/hvm/support.h>
+#include <asm/shadow.h>
 
 /* Limit amount of pages used for shared buffer (per domain) */
 #define MAX_OPROF_SHARED_PAGES 32
@@ -26,7 +28,7 @@ unsigned int pdomains;
 unsigned int pdomains;
 
 unsigned int activated;
-struct domain *primary_profiler;
+struct domain *xenoprof_primary_profiler;
 int xenoprof_state = XENOPROF_IDLE;
 
 u64 total_samples;
@@ -90,10 +92,58 @@ static void xenoprof_reset_buf(struct do
     }
 }
 
-static char *alloc_xenoprof_buf(struct domain *d, int npages)
+static int
+share_xenoprof_page_with_guest(struct domain* d, unsigned long mfn, int npages)
+{
+    int i;
+    
+    /* Share pages so that kernel can map it */
+    for (i = 0; i < npages; i++) {
+        struct page_info* page = mfn_to_page(mfn + i);
+        if ((page->count_info & (PGC_allocated|PGC_count_mask)) != 0) {
+            gdprintk(XENLOG_INFO, "%s: mfn 0x%lx page->count_info 0x%x\n",
+                     __func__, mfn + i, page->count_info);
+            return -EBUSY;
+        }
+        page->count_info = 0;
+        page_set_owner(page, NULL);
+    }
+
+    for (i = 0; i < npages; i++)
+        share_xen_page_with_guest(mfn_to_page(mfn + i), d, XENSHARE_writable);
+    return 0;
+}
+
+static void
+unshare_xenoprof_page_with_guest(unsigned long mfn, int npages)
+{
+    int i;
+
+    for (i = 0; i < npages; i++) {
+        struct page_info* page = mfn_to_page(mfn + i);
+        BUG_ON(page_get_owner(page) != current->domain);
+        if (test_and_clear_bit(_PGC_allocated, &page->count_info))
+            put_page(page);
+    }
+}
+
+static void
+xenoprof_shared_gmfn_with_guest(struct domain* d,
+                                unsigned long maddr, unsigned long gmaddr,
+                                int npages)
+{
+    int i;
+    
+    for (i = 0; i < npages; i++, maddr += PAGE_SIZE, gmaddr += PAGE_SIZE) {
+        BUG_ON(page_get_owner(maddr_to_page(maddr)) != d);
+        xenoprof_shared_gmfn(d, gmaddr, maddr);
+    }
+}
+
+static char *alloc_xenoprof_buf(struct domain *d, int npages, uint64_t gmaddr)
 {
     char *rawbuf;
-    int i, order;
+    int order;
 
     /* allocate pages to store sample buffer shared with domain */
     order  = get_order_from_pages(npages);
@@ -104,17 +154,11 @@ static char *alloc_xenoprof_buf(struct d
         return 0;
     }
 
-    /* Share pages so that kernel can map it */
-    for ( i = 0; i < npages; i++ )
-        share_xen_page_with_guest(
-            virt_to_page(rawbuf + i * PAGE_SIZE), 
-            d, XENSHARE_writable);
-
     return rawbuf;
 }
 
 static int alloc_xenoprof_struct(
-    struct domain *d, int max_samples, int is_passive)
+    struct domain *d, int max_samples, int is_passive, uint64_t gmaddr)
 {
     struct vcpu *v;
     int nvcpu, npages, bufsize, max_bufsize;
@@ -147,7 +191,8 @@ static int alloc_xenoprof_struct(
         (max_samples - 1) * sizeof(struct event_log);
     npages = (nvcpu * bufsize - 1) / PAGE_SIZE + 1;
     
-    d->xenoprof->rawbuf = alloc_xenoprof_buf(is_passive ? dom0 : d, npages);
+    d->xenoprof->rawbuf = alloc_xenoprof_buf(is_passive ? dom0 : d, npages,
+                                             gmaddr);
 
     if ( d->xenoprof->rawbuf == NULL )
     {
@@ -269,6 +314,7 @@ static void reset_passive(struct domain 
     if ( x == NULL )
         return;
 
+    unshare_xenoprof_page_with_guest(virt_to_mfn(x->rawbuf), x->npages);
     x->domain_type = XENOPROF_DOMAIN_IGNORED;
 
     return;
@@ -339,15 +385,26 @@ static int add_passive_list(XEN_GUEST_HA
         return -EINVAL;
 
     if ( (d->xenoprof == NULL) && 
-         ((ret = alloc_xenoprof_struct(d, passive.max_samples, 1)) < 0) ) {
+         ((ret = alloc_xenoprof_struct(d, passive.max_samples, 1,
+                                       passive.buf_gmaddr)) < 0) ) {
         put_domain(d);
         return -ENOMEM;
+    }
+
+    ret = share_xenoprof_page_with_guest(current->domain,
+                virt_to_mfn(d->xenoprof->rawbuf), d->xenoprof->npages);
+    if (ret) {
+        put_domain(d);
+        return ret;
     }
 
     d->xenoprof->domain_type = XENOPROF_DOMAIN_PASSIVE;
     passive.nbuf = d->xenoprof->nbuf;
     passive.bufsize = d->xenoprof->bufsize;
-    passive.buf_maddr = __pa(d->xenoprof->rawbuf);
+    if (!shadow_mode_translate(d)) 
+        passive.buf_gmaddr = __pa(d->xenoprof->rawbuf);
+    else
+        xenoprof_shared_gmfn_with_guest(current->domain, 
__pa(d->xenoprof->rawbuf), passive.buf_gmaddr, d->xenoprof->npages);
 
     if ( copy_to_guest(arg, &passive, 1) ) {
         put_domain(d);
@@ -446,7 +503,7 @@ static int xenoprof_op_init(XEN_GUEST_HA
         return -EFAULT;
 
     if ( xenoprof_init.is_primary )
-        primary_profiler = current->domain;
+        xenoprof_primary_profiler = current->domain;
 
     return 0;
 }
@@ -465,21 +522,32 @@ static int xenoprof_op_get_buffer(XEN_GU
      * is called. Memory is then kept until domain is destroyed.
      */
     if ( (d->xenoprof == NULL) &&
-         ((ret = alloc_xenoprof_struct(d, xenoprof_get_buffer.max_samples, 0)) 
< 0) )
+         ((ret = alloc_xenoprof_struct(d, xenoprof_get_buffer.max_samples, 0,
+                                       xenoprof_get_buffer.buf_gmaddr)) < 0) )
+        return ret;
+
+    ret = share_xenoprof_page_with_guest(d, virt_to_mfn(d->xenoprof->rawbuf),
+                                         d->xenoprof->npages);
+    if (ret)
         return ret;
 
     xenoprof_reset_buf(d);
 
     d->xenoprof->domain_type  = XENOPROF_DOMAIN_IGNORED;
     d->xenoprof->domain_ready = 0;
-    if ( primary_profiler == current->domain )
+    if ( xenoprof_primary_profiler == current->domain )
         d->xenoprof->is_primary = 1;
     else
         d->xenoprof->is_primary = 0;
         
     xenoprof_get_buffer.nbuf = d->xenoprof->nbuf;
     xenoprof_get_buffer.bufsize = d->xenoprof->bufsize;
-    xenoprof_get_buffer.buf_maddr = __pa(d->xenoprof->rawbuf);
+    if (!shadow_mode_translate(d))
+        xenoprof_get_buffer.buf_gmaddr = __pa(d->xenoprof->rawbuf);
+    else
+        xenoprof_shared_gmfn_with_guest(d, __pa(d->xenoprof->rawbuf),
+                                        xenoprof_get_buffer.buf_gmaddr,
+                                        d->xenoprof->npages);
 
     if ( copy_to_guest(arg, &xenoprof_get_buffer, 1) )
         return -EFAULT;
@@ -503,7 +571,7 @@ int do_xenoprof_op(int op, XEN_GUEST_HAN
         return -EINVAL;
     }
 
-    if ( !NONPRIV_OP(op) && (current->domain != primary_profiler) )
+    if ( !NONPRIV_OP(op) && (current->domain != xenoprof_primary_profiler) )
     {
         printk("xenoprof: dom %d denied privileged operation %d\n",
                current->domain->domain_id, op);
@@ -589,7 +657,7 @@ int do_xenoprof_op(int op, XEN_GUEST_HAN
     case XENOPROF_enable_virq:
     {
         int i;
-        if ( current->domain == primary_profiler )
+        if ( current->domain == xenoprof_primary_profiler )
         {
             xenoprof_arch_enable_virq();
             xenoprof_reset_stat();
@@ -607,7 +675,6 @@ int do_xenoprof_op(int op, XEN_GUEST_HAN
         if ( (xenoprof_state == XENOPROF_READY) &&
              (activated == adomains) )
             ret = xenoprof_arch_start();
-
         if ( ret == 0 )
             xenoprof_state = XENOPROF_PROFILING;
         break;
@@ -622,14 +689,20 @@ int do_xenoprof_op(int op, XEN_GUEST_HAN
         break;
 
     case XENOPROF_disable_virq:
+    {
+        struct xenoprof *x = current->domain->xenoprof;
         if ( (xenoprof_state == XENOPROF_PROFILING) && 
              (is_active(current->domain)) ) {
             ret = -EPERM;
             break;
         }
         ret = reset_active(current->domain);
-        break;
-
+        if (ret)
+            break;
+        x = current->domain->xenoprof; /*reset_active() guarantees x != NULL*/
+        unshare_xenoprof_page_with_guest(virt_to_mfn(x->rawbuf), x->npages);
+        break;
+    }
     case XENOPROF_release_counters:
         ret = -EPERM;
         if ( (xenoprof_state == XENOPROF_COUNTERS_RESERVED) ||
@@ -649,7 +722,7 @@ int do_xenoprof_op(int op, XEN_GUEST_HAN
         {
             activated = 0;
             adomains=0;
-            primary_profiler = NULL;
+            xenoprof_primary_profiler = NULL;
             ret = 0;
         }
         break;
diff -r 3bebc37b1492 -r 236b3f5ec6bf xen/include/asm-x86/xenoprof.h
--- a/xen/include/asm-x86/xenoprof.h    Tue Nov 14 15:34:22 2006 +0900
+++ b/xen/include/asm-x86/xenoprof.h    Tue Nov 14 15:34:23 2006 +0900
@@ -45,6 +45,17 @@ void nmi_release_counters(void);
 
 int xenoprof_arch_counter(XEN_GUEST_HANDLE(void) arg);
 
+struct vcpu;
+struct cpu_user_regs;
+int xenoprofile_get_mode(struct vcpu *v, struct cpu_user_regs * const regs);
+#define xenoprof_shared_gmfn(d, gmaddr, maddr)                      \
+    do {                                                            \
+        (void)(maddr);                                              \
+        gdprintk(XENLOG_ERR,                                        \
+                 "xenoprof/x86 with autotranslated mode enabled"    \
+                 "isn't supported yet\n");                          \
+    } while (0)
+
 #endif /* __ASM_XENOPROF_H__ */
 
 /*
diff -r 3bebc37b1492 -r 236b3f5ec6bf xen/include/public/xenoprof.h
--- a/xen/include/public/xenoprof.h     Tue Nov 14 15:34:22 2006 +0900
+++ b/xen/include/public/xenoprof.h     Tue Nov 14 15:34:23 2006 +0900
@@ -87,7 +87,7 @@ struct xenoprof_get_buffer {
     int32_t  max_samples;
     int32_t  nbuf;
     int32_t  bufsize;
-    uint64_t buf_maddr;
+    uint64_t buf_gmaddr;
 };
 typedef struct xenoprof_get_buffer xenoprof_get_buffer_t;
 DEFINE_XEN_GUEST_HANDLE(xenoprof_get_buffer_t);
@@ -110,7 +110,7 @@ typedef struct xenoprof_passive {
     int32_t  max_samples;
     int32_t  nbuf;
     int32_t  bufsize;
-    uint64_t buf_maddr;
+    uint64_t buf_gmaddr;
 } xenoprof_passive_t;
 DEFINE_XEN_GUEST_HANDLE(xenoprof_passive_t);
 
diff -r 3bebc37b1492 -r 236b3f5ec6bf xen/include/xen/xenoprof.h
--- a/xen/include/xen/xenoprof.h        Tue Nov 14 15:34:22 2006 +0900
+++ b/xen/include/xen/xenoprof.h        Tue Nov 14 15:34:23 2006 +0900
@@ -41,4 +41,8 @@ struct domain;
 struct domain;
 void free_xenoprof_pages(struct domain *d);
 
+int do_xenoprof_op(int op, XEN_GUEST_HANDLE(void) arg);
+
+extern struct domain *xenoprof_primary_profiler;
+
 #endif  /* __XEN__XENOPROF_H__ */
yamahata

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

<Prev in Thread] Current Thread [Next in Thread>