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

[Xen-devel] [PATCH] tools/xenbaked: fix bug of Segmentation fault



Run xenbaked will occur Segmentation fault, because
the method to get pointers of trace buffer metadata
is wrong. Fix this bug according to xentrace.

Signed-off-by: Yu Zhiguo <yuzg@xxxxxxxxxxxxxx>

diff --git a/tools/xenmon/xenbaked.c b/tools/xenmon/xenbaked.c
--- a/tools/xenmon/xenbaked.c
+++ b/tools/xenmon/xenbaked.c
@@ -83,6 +83,12 @@
     double cpu_freq;
 } settings_t;
 
+struct t_struct {
+    struct t_info *t_info;  /* Structure with information about individual 
buffers */
+    struct t_buf **meta;    /* Pointers to trace buffer metadata */
+    unsigned char **data;   /* Pointers to trace buffer data areas */
+};
+
 settings_t opts;
 
 int interrupted = 0; /* gets set if we get a SIGHUP */
@@ -356,96 +362,72 @@
  *
  * Maps the Xen trace buffers them into process address space.
  */
-static struct t_buf *map_tbufs(unsigned long tbufs_mfn, unsigned int num,
-                        unsigned long size)
+static struct t_struct *map_tbufs(unsigned long tbufs_mfn, unsigned int num,
+                                  unsigned long tinfo_size)
 {
     int xc_handle;
-    struct t_buf *tbufs_mapped;
+    static struct t_struct tbufs = { 0 };
+    int i;
 
     xc_handle = xc_interface_open();
-
     if ( xc_handle < 0 ) 
     {
         exit(EXIT_FAILURE);
     }
 
-    tbufs_mapped = xc_map_foreign_range(xc_handle, DOMID_XEN,
-                                        size * num, PROT_READ | PROT_WRITE,
+    /* Map t_info metadata structure */
+    tbufs.t_info = xc_map_foreign_range(xc_handle, DOMID_XEN,
+                                        tinfo_size, PROT_READ | PROT_WRITE,
                                         tbufs_mfn);
 
-    xc_interface_close(xc_handle);
-
-    if ( tbufs_mapped == 0 ) 
+    if ( tbufs.t_info == 0 ) 
     {
         PERROR("Failed to mmap trace buffers");
         exit(EXIT_FAILURE);
     }
 
-    return tbufs_mapped;
-}
+    if ( tbufs.t_info->tbuf_size == 0 )
+    {
+        fprintf(stderr, "%s: tbuf_size 0!\n", __func__);
+        exit(EXIT_FAILURE);
+    }
 
-/**
- * init_bufs_ptrs - initialises an array of pointers to the trace buffers
- * @bufs_mapped:    the userspace address where the trace buffers are mapped
- * @num:            number of trace buffers
- * @size:           trace buffer size
- *
- * Initialises an array of pointers to individual trace buffers within the
- * mapped region containing all trace buffers.
- */
-static struct t_buf **init_bufs_ptrs(void *bufs_mapped, unsigned int num,
-                              unsigned long size)
-{
-    int i;
-    struct t_buf **user_ptrs;
-
-    user_ptrs = (struct t_buf **)calloc(num, sizeof(struct t_buf *));
-    if ( user_ptrs == NULL )
+    /* Map per-cpu buffers */
+    tbufs.meta = (struct t_buf **)calloc(num, sizeof(struct t_buf *));
+    tbufs.data = (unsigned char **)calloc(num, sizeof(unsigned char *));
+    if ( tbufs.meta == NULL || tbufs.data == NULL )
     {
         PERROR( "Failed to allocate memory for buffer pointers\n");
         exit(EXIT_FAILURE);
     }
 
-    /* initialise pointers to the trace buffers - given the size of a trace
-     * buffer and the value of bufs_maped, we can easily calculate these */
-    for ( i = 0; i<num; i++ )
-        user_ptrs[i] = (struct t_buf *)((unsigned long)bufs_mapped + size * i);
+    for(i=0; i<num; i++)
+    {
+        
+        uint32_t *mfn_list = ((uint32_t *)tbufs.t_info) + 
tbufs.t_info->mfn_offset[i];
+        int j;
+        xen_pfn_t pfn_list[tbufs.t_info->tbuf_size];
 
-    return user_ptrs;
-}
+        for ( j=0; j<tbufs.t_info->tbuf_size; j++)
+            pfn_list[j] = (xen_pfn_t)mfn_list[j];
 
-
-/**
- * init_rec_ptrs - initialises data area pointers to locations in user space
- * @tbufs_mfn:     base mfn of the trace buffer area
- * @tbufs_mapped:  user virtual address of base of trace buffer area
- * @meta:          array of user-space pointers to struct t_buf's of metadata
- * @num:           number of trace buffers
- *
- * Initialises data area pointers to the locations that data areas have been
- * mapped in user space.  Note that the trace buffer metadata contains machine
- * pointers - the array returned allows more convenient access to them.
- */
-static struct t_rec **init_rec_ptrs(struct t_buf **meta, unsigned int num)
-{
-    int i;
-    struct t_rec **data;
-    
-    data = calloc(num, sizeof(struct t_rec *));
-    if ( data == NULL )
-    {
-        PERROR("Failed to allocate memory for data pointers\n");
-        exit(EXIT_FAILURE);
+        tbufs.meta[i] = xc_map_foreign_batch(xc_handle, DOMID_XEN,
+                                             PROT_READ | PROT_WRITE,
+                                             pfn_list,
+                                             tbufs.t_info->tbuf_size);
+        if ( tbufs.meta[i] == NULL )
+        {
+            PERROR("Failed to map cpu buffer!");
+            exit(EXIT_FAILURE);
+        }
+        tbufs.data[i] = (unsigned char *)(tbufs.meta[i]+1);
     }
 
-    for ( i = 0; i < num; i++ )
-        data[i] = (struct t_rec *)(meta[i] + 1);
+    xc_interface_close(xc_handle);
 
-    return data;
+    return &tbufs;
 }
 
-
-
 /**
  * get_num_cpus - get the number of logical CPUs
  */
@@ -470,55 +452,19 @@
 }
 
 /**
- * get_tbuf_size - get the size in pages of each trace buffer
- */
-uint16_t get_tbuf_size(unsigned long tbufs_mfn, unsigned long tinfo_size)
-{
-    struct t_info *t_info;
-    int xc_handle;
-
-    xc_handle = xc_interface_open();
-    if ( xc_handle < 0 ) 
-    {
-        exit(EXIT_FAILURE);
-    }
-
-    t_info = xc_map_foreign_range(xc_handle, DOMID_XEN,
-                    tinfo_size, PROT_READ | PROT_WRITE,
-                    tbufs_mfn);
-
-    if ( t_info == 0 ) 
-    {
-        PERROR("Failed to mmap trace buffers");
-        exit(EXIT_FAILURE);
-    }
-
-    if ( t_info->tbuf_size == 0 )
-    {
-        fprintf(stderr, "%s: tbuf_size 0!\n", __func__);
-        exit(EXIT_FAILURE);
-    }
-
-    xc_interface_close(xc_handle);
-
-    return t_info->tbuf_size;
-}
-
-/**
  * monitor_tbufs - monitor the contents of tbufs
  */
 static int monitor_tbufs(void)
 {
     int i;
 
-    void *tbufs_mapped;          /* pointer to where the tbufs are mapped    */
+    struct t_struct *tbufs;      /* Pointer to hypervisor maps */
     struct t_buf **meta;         /* pointers to the trace buffer metadata    */
-    char         **data;         /* pointers to the trace buffer data areas
+    unsigned char **data;        /* pointers to the trace buffer data areas
                                   * where they are mapped into user space.   */
     unsigned long tbufs_mfn;     /* mfn of the tbufs                         */
     unsigned int  num;           /* number of trace buffers / logical CPUS   */
     unsigned long tinfo_size;    /* size of t_info metadata map              */
-    uint16_t tbuf_size;          /* Size in pages of each trace buffer       */
     unsigned long size;          /* size of a single trace buffer            */
 
     unsigned long data_size, rec_size;
@@ -533,17 +479,14 @@
     
     /* setup access to trace buffers */
     get_tbufs(&tbufs_mfn, &tinfo_size);
+    tbufs = map_tbufs(tbufs_mfn, num, tinfo_size);
 
-    tbufs_mapped = map_tbufs(tbufs_mfn, num, tinfo_size);
-
-    tbuf_size = get_tbuf_size(tbufs_mfn, tinfo_size);
-    size = tbuf_size * XC_PAGE_SIZE;
+    size = tbufs->t_info->tbuf_size * XC_PAGE_SIZE;
 
     data_size = size - sizeof(struct t_buf);
 
-    /* build arrays of convenience ptrs */
-    meta  = init_bufs_ptrs (tbufs_mapped, num, size);
-    data  = (char **)init_rec_ptrs(meta, num);
+    meta = tbufs->meta;
+    data = tbufs->data;
 
     if ( eventchn_init() < 0 )
         fprintf(stderr, "Failed to initialize event channel; "


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


 


Rackspace

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