[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>
This commit is contained in:
kfraser@localhost.localdomain committed 2006-11-22 10:09:28 +00:00
1 parent b77e35477f
commit d41363d448
6 files changed
+110 -34

No files matched your search

@@ -93,7 +93,7 @@ int xenoprof_arch_map_shared_buffer(struct xenoprof_get_buffer * get_buffer,
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 xenoprof_passive * pdomain,
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);
+2 -3
View File
@@ -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_primary, char *cpu_type)
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;
}
}
+89 -27
View File
@@ -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;
+11
View File
@@ -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__ */
/*
+2 -2
View File
@@ -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);
+4
View File
@@ -41,4 +41,8 @@ struct xenoprof {
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__ */
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.