# HG changeset patch
# User kfraser@xxxxxxxxxxxxxxxxxxxxx
# Node ID 1d7d5d48fcdc2e73ce63e3aa8f6959e3669f9123
# Parent 1ef9954a26686b35b946d889726d4d35c283c2a0
[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@xxxxxxxxxxxxx>
Simplify the share function.
Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx>
---
linux-2.6-xen-sparse/arch/i386/oprofile/xenoprof.c | 4
xen/arch/x86/oprofile/nmi_int.c | 5
xen/common/xenoprof.c | 122 +++++++++++++++------
xen/include/asm-x86/xenoprof.h | 11 +
xen/include/public/xenoprof.h | 4
xen/include/xen/xenoprof.h | 4
6 files changed, 113 insertions(+), 37 deletions(-)
diff -r 1ef9954a2668 -r 1d7d5d48fcdc
linux-2.6-xen-sparse/arch/i386/oprofile/xenoprof.c
--- a/linux-2.6-xen-sparse/arch/i386/oprofile/xenoprof.c Wed Nov 22
09:51:20 2006 +0000
+++ b/linux-2.6-xen-sparse/arch/i386/oprofile/xenoprof.c Wed Nov 22
10:09:28 2006 +0000
@@ -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 1ef9954a2668 -r 1d7d5d48fcdc xen/arch/x86/oprofile/nmi_int.c
--- a/xen/arch/x86/oprofile/nmi_int.c Wed Nov 22 09:51:20 2006 +0000
+++ b/xen/arch/x86/oprofile/nmi_int.c Wed Nov 22 10:09:28 2006 +0000
@@ -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);
@@ -339,10 +338,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 1ef9954a2668 -r 1d7d5d48fcdc xen/common/xenoprof.c
--- a/xen/common/xenoprof.c Wed Nov 22 09:51:20 2006 +0000
+++ b/xen/common/xenoprof.c Wed Nov 22 10:09:28 2006 +0000
@@ -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,46 @@ static void xenoprof_reset_buf(struct do
}
}
-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 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 +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
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_HA
if ( d == NULL )
return -EINVAL;
- if ( (d->xenoprof == NULL) &&
- ((ret = alloc_xenoprof_struct(d, passive.max_samples, 1)) < 0) )
- {
- put_domain(d);
- return -ENOMEM;
- }
+ if ( d->xenoprof == NULL )
+ {
+ 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_HA
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_GU
*/
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_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);
@@ -592,7 +649,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();
@@ -609,7 +666,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;
@@ -624,14 +680,20 @@ int do_xenoprof_op(int op, XEN_GUEST_HAN
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);
- break;
+ 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_HAN
{
activated = 0;
adomains=0;
- primary_profiler = NULL;
+ xenoprof_primary_profiler = NULL;
ret = 0;
}
break;
diff -r 1ef9954a2668 -r 1d7d5d48fcdc xen/include/asm-x86/xenoprof.h
--- a/xen/include/asm-x86/xenoprof.h Wed Nov 22 09:51:20 2006 +0000
+++ b/xen/include/asm-x86/xenoprof.h Wed Nov 22 10:09:28 2006 +0000
@@ -44,6 +44,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_WARNING, \
+ "xenoprof/x86 with autotranslated mode enabled" \
+ "isn't supported yet\n"); \
+ } while (0)
+
#endif /* __ASM_X86_XENOPROF_H__ */
/*
diff -r 1ef9954a2668 -r 1d7d5d48fcdc xen/include/public/xenoprof.h
--- a/xen/include/public/xenoprof.h Wed Nov 22 09:51:20 2006 +0000
+++ b/xen/include/public/xenoprof.h Wed Nov 22 10:09:28 2006 +0000
@@ -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 1ef9954a2668 -r 1d7d5d48fcdc xen/include/xen/xenoprof.h
--- a/xen/include/xen/xenoprof.h Wed Nov 22 09:51:20 2006 +0000
+++ b/xen/include/xen/xenoprof.h Wed Nov 22 10:09:28 2006 +0000
@@ -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__ */
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|