diff options
author | kfraser@localhost.localdomain <kfraser@localhost.localdomain> | 2006-11-22 10:09:28 +0000 |
---|---|---|
committer | kfraser@localhost.localdomain <kfraser@localhost.localdomain> | 2006-11-22 10:09:28 +0000 |
commit | d41363d448f3edb3d2a463cf3af50d55691dfbc2 (patch) | |
tree | 1e58522f74e514e9c0079849650d4f25e24a99d0 /xen/common/xenoprof.c | |
parent | b77e35477f2176cef15af7673316f31c633aa833 (diff) | |
download | xen-d41363d448f3edb3d2a463cf3af50d55691dfbc2.tar.gz xen-d41363d448f3edb3d2a463cf3af50d55691dfbc2.tar.bz2 xen-d41363d448f3edb3d2a463cf3af50d55691dfbc2.zip |
[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>
Diffstat (limited to 'xen/common/xenoprof.c')
-rw-r--r-- | xen/common/xenoprof.c | 116 |
1 files changed, 89 insertions, 27 deletions
diff --git a/xen/common/xenoprof.c b/xen/common/xenoprof.c index 476b2ce715..7950800ac9 100644 --- a/xen/common/xenoprof.c +++ b/xen/common/xenoprof.c @@ -2,15 +2,17 @@ * Copyright (C) 2005 Hewlett-Packard Co. * written by Aravind Menon & Jose Renato Santos * (email: xenoprof@groups.hp.com) + * + * 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 @@ struct domain *passive_domains[MAX_OPROF_DOMAINS]; 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,46 @@ static void xenoprof_reset_buf(struct domain *d) } } -static char *alloc_xenoprof_buf(struct domain *d, int npages) +static void +share_xenoprof_page_with_guest(struct domain* d, unsigned long mfn, int npages) +{ + int i; + + for ( i = 0; i < npages; i++ ) + share_xen_page_with_guest(mfn_to_page(mfn + i), d, XENSHARE_writable); +} + +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 +142,11 @@ static char *alloc_xenoprof_buf(struct domain *d, int npages) 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 +179,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 +302,7 @@ static void reset_passive(struct domain *d) if ( x == NULL ) return; + unshare_xenoprof_page_with_guest(virt_to_mfn(x->rawbuf), x->npages); x->domain_type = XENOPROF_DOMAIN_IGNORED; } @@ -332,17 +366,30 @@ static int add_passive_list(XEN_GUEST_HANDLE(void) arg) if ( d == NULL ) return -EINVAL; - if ( (d->xenoprof == NULL) && - ((ret = alloc_xenoprof_struct(d, passive.max_samples, 1)) < 0) ) + if ( d->xenoprof == NULL ) { - put_domain(d); - return -ENOMEM; + ret = alloc_xenoprof_struct( + d, passive.max_samples, 1, passive.buf_gmaddr); + if ( ret < 0 ) + { + put_domain(d); + return -ENOMEM; + } } + share_xenoprof_page_with_guest( + current->domain, virt_to_mfn(d->xenoprof->rawbuf), + d->xenoprof->npages); + 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) ) { @@ -442,7 +489,7 @@ static int xenoprof_op_init(XEN_GUEST_HANDLE(void) arg) return -EFAULT; if ( xenoprof_init.is_primary ) - primary_profiler = current->domain; + xenoprof_primary_profiler = current->domain; return 0; } @@ -462,20 +509,30 @@ static int xenoprof_op_get_buffer(XEN_GUEST_HANDLE(void) arg) */ if ( d->xenoprof == NULL ) { - ret = alloc_xenoprof_struct(d, xenoprof_get_buffer.max_samples, 0); + ret = alloc_xenoprof_struct( + d, xenoprof_get_buffer.max_samples, 0, + xenoprof_get_buffer.buf_gmaddr); if ( ret < 0 ) return ret; } + share_xenoprof_page_with_guest( + d, virt_to_mfn(d->xenoprof->rawbuf), d->xenoprof->npages); + xenoprof_reset_buf(d); d->xenoprof->domain_type = XENOPROF_DOMAIN_IGNORED; d->xenoprof->domain_ready = 0; - d->xenoprof->is_primary = (primary_profiler == current->domain); + d->xenoprof->is_primary = (xenoprof_primary_profiler == current->domain); 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; @@ -499,7 +556,7 @@ int do_xenoprof_op(int op, XEN_GUEST_HANDLE(void) arg) 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); @@ -592,7 +649,7 @@ int do_xenoprof_op(int op, XEN_GUEST_HANDLE(void) arg) case XENOPROF_enable_virq: { int i; - if ( current->domain == primary_profiler ) + if ( current->domain == xenoprof_primary_profiler ) { xenoprof_arch_enable_virq(); xenoprof_reset_stat(); @@ -609,7 +666,6 @@ int do_xenoprof_op(int op, XEN_GUEST_HANDLE(void) arg) if ( (xenoprof_state == XENOPROF_READY) && (activated == adomains) ) ret = xenoprof_arch_start(); - if ( ret == 0 ) xenoprof_state = XENOPROF_PROFILING; break; @@ -624,14 +680,20 @@ int do_xenoprof_op(int op, XEN_GUEST_HANDLE(void) arg) break; case XENOPROF_disable_virq: + { + struct xenoprof *x; if ( (xenoprof_state == XENOPROF_PROFILING) && (is_active(current->domain)) ) { ret = -EPERM; break; } - ret = reset_active(current->domain); + if ( (ret = reset_active(current->domain)) != 0 ) + break; + x = current->domain->xenoprof; + unshare_xenoprof_page_with_guest(virt_to_mfn(x->rawbuf), x->npages); break; + } case XENOPROF_release_counters: ret = -EPERM; @@ -652,7 +714,7 @@ int do_xenoprof_op(int op, XEN_GUEST_HANDLE(void) arg) { activated = 0; adomains=0; - primary_profiler = NULL; + xenoprof_primary_profiler = NULL; ret = 0; } break; |