ia64/xen-unstable

changeset 12541:1d7d5d48fcdc

[XENOPROFILE] 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.

Signed-off-by: Isaku Yamahata <yamahata@valinux.co.jp>

Simplify the share function.

Signed-off-by: Keir Fraser <keir@xensource.com>
author kfraser@localhost.localdomain
date Wed Nov 22 10:09:28 2006 +0000 (2006-11-22)
parents 1ef9954a2668
children 60b60f75a221
files linux-2.6-xen-sparse/arch/i386/oprofile/xenoprof.c xen/arch/x86/oprofile/nmi_int.c xen/common/xenoprof.c xen/include/asm-x86/xenoprof.h xen/include/public/xenoprof.h xen/include/xen/xenoprof.h
line diff
     1.1 --- a/linux-2.6-xen-sparse/arch/i386/oprofile/xenoprof.c	Wed Nov 22 09:51:20 2006 +0000
     1.2 +++ b/linux-2.6-xen-sparse/arch/i386/oprofile/xenoprof.c	Wed Nov 22 10:09:28 2006 +0000
     1.3 @@ -93,7 +93,7 @@ int xenoprof_arch_map_shared_buffer(stru
     1.4  
     1.5  	if ( (ret = direct_kernel_remap_pfn_range(
     1.6  		      (unsigned long)area->addr,
     1.7 -		      get_buffer->buf_maddr >> PAGE_SHIFT,
     1.8 +		      get_buffer->buf_gmaddr >> PAGE_SHIFT,
     1.9  		      npages * PAGE_SIZE, __pgprot(_KERNPG_TABLE),
    1.10  		      DOMID_SELF)) ) {
    1.11  		vunmap(area->addr);
    1.12 @@ -127,7 +127,7 @@ int xenoprof_arch_set_passive(struct xen
    1.13  
    1.14  	ret = direct_kernel_remap_pfn_range(
    1.15  		(unsigned long)area->addr,
    1.16 -		pdomain->buf_maddr >> PAGE_SHIFT,
    1.17 +		pdomain->buf_gmaddr >> PAGE_SHIFT,
    1.18  		npages * PAGE_SIZE, prot, DOMID_SELF);
    1.19  	if (ret) {
    1.20  		vunmap(area->addr);
     2.1 --- a/xen/arch/x86/oprofile/nmi_int.c	Wed Nov 22 09:51:20 2006 +0000
     2.2 +++ b/xen/arch/x86/oprofile/nmi_int.c	Wed Nov 22 10:09:28 2006 +0000
     2.3 @@ -33,7 +33,6 @@ static unsigned long saved_lvtpc[NR_CPUS
     2.4  #define VIRQ_BITMASK_SIZE (MAX_OPROF_DOMAINS/32 + 1)
     2.5  extern int active_domains[MAX_OPROF_DOMAINS];
     2.6  extern unsigned int adomains;
     2.7 -extern struct domain *primary_profiler;
     2.8  extern struct domain *adomain_ptrs[MAX_OPROF_DOMAINS];
     2.9  extern unsigned long virq_ovf_pending[VIRQ_BITMASK_SIZE];
    2.10  extern int is_active(struct domain *d);
    2.11 @@ -339,10 +338,10 @@ int nmi_init(int *num_events, int *is_pr
    2.12  		return -ENODEV;
    2.13  	}
    2.14  
    2.15 -	if (primary_profiler == NULL) {
    2.16 +	if (xenoprof_primary_profiler == NULL) {
    2.17  		/* For now, only dom0 can be the primary profiler */
    2.18  		if (current->domain->domain_id == 0) {
    2.19 -			primary_profiler = current->domain;
    2.20 +			xenoprof_primary_profiler = current->domain;
    2.21  			prim = 1;
    2.22  		}
    2.23  	}
     3.1 --- a/xen/common/xenoprof.c	Wed Nov 22 09:51:20 2006 +0000
     3.2 +++ b/xen/common/xenoprof.c	Wed Nov 22 10:09:28 2006 +0000
     3.3 @@ -2,15 +2,17 @@
     3.4   * Copyright (C) 2005 Hewlett-Packard Co.
     3.5   * written by Aravind Menon & Jose Renato Santos
     3.6   *            (email: xenoprof@groups.hp.com)
     3.7 + *
     3.8 + * arch generic xenoprof and IA64 support.
     3.9 + * dynamic map/unmap xenoprof buffer support.
    3.10   * Copyright (c) 2006 Isaku Yamahata <yamahata at valinux co jp>
    3.11   *                    VA Linux Systems Japan K.K.
    3.12 - * arch generic xenoprof and IA64 support.
    3.13   */
    3.14  
    3.15  #include <xen/guest_access.h>
    3.16  #include <xen/sched.h>
    3.17  #include <public/xenoprof.h>
    3.18 -#include <asm/hvm/support.h>
    3.19 +#include <asm/shadow.h>
    3.20  
    3.21  /* Limit amount of pages used for shared buffer (per domain) */
    3.22  #define MAX_OPROF_SHARED_PAGES 32
    3.23 @@ -26,7 +28,7 @@ struct domain *passive_domains[MAX_OPROF
    3.24  unsigned int pdomains;
    3.25  
    3.26  unsigned int activated;
    3.27 -struct domain *primary_profiler;
    3.28 +struct domain *xenoprof_primary_profiler;
    3.29  int xenoprof_state = XENOPROF_IDLE;
    3.30  
    3.31  u64 total_samples;
    3.32 @@ -90,10 +92,46 @@ static void xenoprof_reset_buf(struct do
    3.33      }
    3.34  }
    3.35  
    3.36 -static char *alloc_xenoprof_buf(struct domain *d, int npages)
    3.37 +static void
    3.38 +share_xenoprof_page_with_guest(struct domain* d, unsigned long mfn, int npages)
    3.39 +{
    3.40 +    int i;
    3.41 +    
    3.42 +    for ( i = 0; i < npages; i++ )
    3.43 +        share_xen_page_with_guest(mfn_to_page(mfn + i), d, XENSHARE_writable);
    3.44 +}
    3.45 +
    3.46 +static void
    3.47 +unshare_xenoprof_page_with_guest(unsigned long mfn, int npages)
    3.48 +{
    3.49 +    int i;
    3.50 +
    3.51 +    for ( i = 0; i < npages; i++ )
    3.52 +    {
    3.53 +        struct page_info *page = mfn_to_page(mfn + i);
    3.54 +        BUG_ON(page_get_owner(page) != current->domain);
    3.55 +        if ( test_and_clear_bit(_PGC_allocated, &page->count_info) )
    3.56 +            put_page(page);
    3.57 +    }
    3.58 +}
    3.59 +
    3.60 +static void
    3.61 +xenoprof_shared_gmfn_with_guest(
    3.62 +    struct domain* d, unsigned long maddr, unsigned long gmaddr, int npages)
    3.63 +{
    3.64 +    int i;
    3.65 +    
    3.66 +    for ( i = 0; i < npages; i++, maddr += PAGE_SIZE, gmaddr += PAGE_SIZE )
    3.67 +    {
    3.68 +        BUG_ON(page_get_owner(maddr_to_page(maddr)) != d);
    3.69 +        xenoprof_shared_gmfn(d, gmaddr, maddr);
    3.70 +    }
    3.71 +}
    3.72 +
    3.73 +static char *alloc_xenoprof_buf(struct domain *d, int npages, uint64_t gmaddr)
    3.74  {
    3.75      char *rawbuf;
    3.76 -    int i, order;
    3.77 +    int order;
    3.78  
    3.79      /* allocate pages to store sample buffer shared with domain */
    3.80      order  = get_order_from_pages(npages);
    3.81 @@ -104,17 +142,11 @@ static char *alloc_xenoprof_buf(struct d
    3.82          return 0;
    3.83      }
    3.84  
    3.85 -    /* Share pages so that kernel can map it */
    3.86 -    for ( i = 0; i < npages; i++ )
    3.87 -        share_xen_page_with_guest(
    3.88 -            virt_to_page(rawbuf + i * PAGE_SIZE), 
    3.89 -            d, XENSHARE_writable);
    3.90 -
    3.91      return rawbuf;
    3.92  }
    3.93  
    3.94  static int alloc_xenoprof_struct(
    3.95 -    struct domain *d, int max_samples, int is_passive)
    3.96 +    struct domain *d, int max_samples, int is_passive, uint64_t gmaddr)
    3.97  {
    3.98      struct vcpu *v;
    3.99      int nvcpu, npages, bufsize, max_bufsize;
   3.100 @@ -147,7 +179,8 @@ static int alloc_xenoprof_struct(
   3.101          (max_samples - 1) * sizeof(struct event_log);
   3.102      npages = (nvcpu * bufsize - 1) / PAGE_SIZE + 1;
   3.103      
   3.104 -    d->xenoprof->rawbuf = alloc_xenoprof_buf(is_passive ? dom0 : d, npages);
   3.105 +    d->xenoprof->rawbuf = alloc_xenoprof_buf(is_passive ? dom0 : d, npages,
   3.106 +                                             gmaddr);
   3.107  
   3.108      if ( d->xenoprof->rawbuf == NULL )
   3.109      {
   3.110 @@ -269,6 +302,7 @@ static void reset_passive(struct domain 
   3.111      if ( x == NULL )
   3.112          return;
   3.113  
   3.114 +    unshare_xenoprof_page_with_guest(virt_to_mfn(x->rawbuf), x->npages);
   3.115      x->domain_type = XENOPROF_DOMAIN_IGNORED;
   3.116  }
   3.117  
   3.118 @@ -332,17 +366,30 @@ static int add_passive_list(XEN_GUEST_HA
   3.119      if ( d == NULL )
   3.120          return -EINVAL;
   3.121  
   3.122 -    if ( (d->xenoprof == NULL) && 
   3.123 -         ((ret = alloc_xenoprof_struct(d, passive.max_samples, 1)) < 0) )
   3.124 +    if ( d->xenoprof == NULL )
   3.125      {
   3.126 -        put_domain(d);
   3.127 -        return -ENOMEM;
   3.128 +        ret = alloc_xenoprof_struct(
   3.129 +            d, passive.max_samples, 1, passive.buf_gmaddr);
   3.130 +        if ( ret < 0 )
   3.131 +        {
   3.132 +            put_domain(d);
   3.133 +            return -ENOMEM;
   3.134 +        }
   3.135      }
   3.136  
   3.137 +    share_xenoprof_page_with_guest(
   3.138 +        current->domain, virt_to_mfn(d->xenoprof->rawbuf),
   3.139 +        d->xenoprof->npages);
   3.140 +
   3.141      d->xenoprof->domain_type = XENOPROF_DOMAIN_PASSIVE;
   3.142      passive.nbuf = d->xenoprof->nbuf;
   3.143      passive.bufsize = d->xenoprof->bufsize;
   3.144 -    passive.buf_maddr = __pa(d->xenoprof->rawbuf);
   3.145 +    if ( !shadow_mode_translate(d) )
   3.146 +        passive.buf_gmaddr = __pa(d->xenoprof->rawbuf);
   3.147 +    else
   3.148 +        xenoprof_shared_gmfn_with_guest(
   3.149 +            current->domain, __pa(d->xenoprof->rawbuf),
   3.150 +            passive.buf_gmaddr, d->xenoprof->npages);
   3.151  
   3.152      if ( copy_to_guest(arg, &passive, 1) )
   3.153      {
   3.154 @@ -442,7 +489,7 @@ static int xenoprof_op_init(XEN_GUEST_HA
   3.155          return -EFAULT;
   3.156  
   3.157      if ( xenoprof_init.is_primary )
   3.158 -        primary_profiler = current->domain;
   3.159 +        xenoprof_primary_profiler = current->domain;
   3.160  
   3.161      return 0;
   3.162  }
   3.163 @@ -462,20 +509,30 @@ static int xenoprof_op_get_buffer(XEN_GU
   3.164       */
   3.165      if ( d->xenoprof == NULL )
   3.166      {
   3.167 -        ret = alloc_xenoprof_struct(d, xenoprof_get_buffer.max_samples, 0);
   3.168 +        ret = alloc_xenoprof_struct(
   3.169 +            d, xenoprof_get_buffer.max_samples, 0,
   3.170 +            xenoprof_get_buffer.buf_gmaddr);
   3.171          if ( ret < 0 )
   3.172              return ret;
   3.173      }
   3.174  
   3.175 +    share_xenoprof_page_with_guest(
   3.176 +        d, virt_to_mfn(d->xenoprof->rawbuf), d->xenoprof->npages);
   3.177 +
   3.178      xenoprof_reset_buf(d);
   3.179  
   3.180      d->xenoprof->domain_type  = XENOPROF_DOMAIN_IGNORED;
   3.181      d->xenoprof->domain_ready = 0;
   3.182 -    d->xenoprof->is_primary   = (primary_profiler == current->domain);
   3.183 +    d->xenoprof->is_primary   = (xenoprof_primary_profiler == current->domain);
   3.184          
   3.185      xenoprof_get_buffer.nbuf = d->xenoprof->nbuf;
   3.186      xenoprof_get_buffer.bufsize = d->xenoprof->bufsize;
   3.187 -    xenoprof_get_buffer.buf_maddr = __pa(d->xenoprof->rawbuf);
   3.188 +    if ( !shadow_mode_translate(d) )
   3.189 +        xenoprof_get_buffer.buf_gmaddr = __pa(d->xenoprof->rawbuf);
   3.190 +    else
   3.191 +        xenoprof_shared_gmfn_with_guest(
   3.192 +            d, __pa(d->xenoprof->rawbuf), xenoprof_get_buffer.buf_gmaddr,
   3.193 +            d->xenoprof->npages);
   3.194  
   3.195      if ( copy_to_guest(arg, &xenoprof_get_buffer, 1) )
   3.196          return -EFAULT;
   3.197 @@ -499,7 +556,7 @@ int do_xenoprof_op(int op, XEN_GUEST_HAN
   3.198          return -EINVAL;
   3.199      }
   3.200  
   3.201 -    if ( !NONPRIV_OP(op) && (current->domain != primary_profiler) )
   3.202 +    if ( !NONPRIV_OP(op) && (current->domain != xenoprof_primary_profiler) )
   3.203      {
   3.204          printk("xenoprof: dom %d denied privileged operation %d\n",
   3.205                 current->domain->domain_id, op);
   3.206 @@ -592,7 +649,7 @@ int do_xenoprof_op(int op, XEN_GUEST_HAN
   3.207      case XENOPROF_enable_virq:
   3.208      {
   3.209          int i;
   3.210 -        if ( current->domain == primary_profiler )
   3.211 +        if ( current->domain == xenoprof_primary_profiler )
   3.212          {
   3.213              xenoprof_arch_enable_virq();
   3.214              xenoprof_reset_stat();
   3.215 @@ -609,7 +666,6 @@ int do_xenoprof_op(int op, XEN_GUEST_HAN
   3.216          if ( (xenoprof_state == XENOPROF_READY) &&
   3.217               (activated == adomains) )
   3.218              ret = xenoprof_arch_start();
   3.219 -
   3.220          if ( ret == 0 )
   3.221              xenoprof_state = XENOPROF_PROFILING;
   3.222          break;
   3.223 @@ -624,14 +680,20 @@ int do_xenoprof_op(int op, XEN_GUEST_HAN
   3.224          break;
   3.225  
   3.226      case XENOPROF_disable_virq:
   3.227 +    {
   3.228 +        struct xenoprof *x;
   3.229          if ( (xenoprof_state == XENOPROF_PROFILING) && 
   3.230               (is_active(current->domain)) )
   3.231          {
   3.232              ret = -EPERM;
   3.233              break;
   3.234          }
   3.235 -        ret = reset_active(current->domain);
   3.236 +        if ( (ret = reset_active(current->domain)) != 0 )
   3.237 +            break;
   3.238 +        x = current->domain->xenoprof;
   3.239 +        unshare_xenoprof_page_with_guest(virt_to_mfn(x->rawbuf), x->npages);
   3.240          break;
   3.241 +    }
   3.242  
   3.243      case XENOPROF_release_counters:
   3.244          ret = -EPERM;
   3.245 @@ -652,7 +714,7 @@ int do_xenoprof_op(int op, XEN_GUEST_HAN
   3.246          {
   3.247              activated = 0;
   3.248              adomains=0;
   3.249 -            primary_profiler = NULL;
   3.250 +            xenoprof_primary_profiler = NULL;
   3.251              ret = 0;
   3.252          }
   3.253          break;
     4.1 --- a/xen/include/asm-x86/xenoprof.h	Wed Nov 22 09:51:20 2006 +0000
     4.2 +++ b/xen/include/asm-x86/xenoprof.h	Wed Nov 22 10:09:28 2006 +0000
     4.3 @@ -44,6 +44,17 @@ void nmi_release_counters(void);
     4.4  
     4.5  int xenoprof_arch_counter(XEN_GUEST_HANDLE(void) arg);
     4.6  
     4.7 +struct vcpu;
     4.8 +struct cpu_user_regs;
     4.9 +int xenoprofile_get_mode(struct vcpu *v, struct cpu_user_regs * const regs);
    4.10 +#define xenoprof_shared_gmfn(d, gmaddr, maddr)                      \
    4.11 +    do {                                                            \
    4.12 +        (void)(maddr);                                              \
    4.13 +        gdprintk(XENLOG_WARNING,                                    \
    4.14 +                 "xenoprof/x86 with autotranslated mode enabled"    \
    4.15 +                 "isn't supported yet\n");                          \
    4.16 +    } while (0)
    4.17 +
    4.18  #endif /* __ASM_X86_XENOPROF_H__ */
    4.19  
    4.20  /*
     5.1 --- a/xen/include/public/xenoprof.h	Wed Nov 22 09:51:20 2006 +0000
     5.2 +++ b/xen/include/public/xenoprof.h	Wed Nov 22 10:09:28 2006 +0000
     5.3 @@ -87,7 +87,7 @@ struct xenoprof_get_buffer {
     5.4      int32_t  max_samples;
     5.5      int32_t  nbuf;
     5.6      int32_t  bufsize;
     5.7 -    uint64_t buf_maddr;
     5.8 +    uint64_t buf_gmaddr;
     5.9  };
    5.10  typedef struct xenoprof_get_buffer xenoprof_get_buffer_t;
    5.11  DEFINE_XEN_GUEST_HANDLE(xenoprof_get_buffer_t);
    5.12 @@ -110,7 +110,7 @@ typedef struct xenoprof_passive {
    5.13      int32_t  max_samples;
    5.14      int32_t  nbuf;
    5.15      int32_t  bufsize;
    5.16 -    uint64_t buf_maddr;
    5.17 +    uint64_t buf_gmaddr;
    5.18  } xenoprof_passive_t;
    5.19  DEFINE_XEN_GUEST_HANDLE(xenoprof_passive_t);
    5.20  
     6.1 --- a/xen/include/xen/xenoprof.h	Wed Nov 22 09:51:20 2006 +0000
     6.2 +++ b/xen/include/xen/xenoprof.h	Wed Nov 22 10:09:28 2006 +0000
     6.3 @@ -41,4 +41,8 @@ struct xenoprof {
     6.4  struct domain;
     6.5  void free_xenoprof_pages(struct domain *d);
     6.6  
     6.7 +int do_xenoprof_op(int op, XEN_GUEST_HANDLE(void) arg);
     6.8 +
     6.9 +extern struct domain *xenoprof_primary_profiler;
    6.10 +
    6.11  #endif  /* __XEN__XENOPROF_H__ */