# HG changeset patch # User yamahata@xxxxxxxxxxxxx # Date 1161840570 -32400 # Node ID e18530631947979e15018a57facf7f3f01a2c7bd # Parent 0a16a1f7f4cbada65003e81f0526238c7394ac6b xenoprof linux/ia64 part PATCHNAME: xenoprof_ia64_linux_side Signed-off-by: Isaku Yamahata diff -r 0a16a1f7f4cb -r e18530631947 linux-2.6-xen-sparse/arch/ia64/kernel/perfmon.c --- a/linux-2.6-xen-sparse/arch/ia64/kernel/perfmon.c Thu Oct 26 14:29:00 2006 +0900 +++ b/linux-2.6-xen-sparse/arch/ia64/kernel/perfmon.c Thu Oct 26 14:29:30 2006 +0900 @@ -53,6 +53,21 @@ #include #ifdef CONFIG_PERFMON +#ifdef CONFIG_XEN +#include +#define XEN_NOT_SUPPORTED_YET \ + do { \ + if (is_running_on_xen()) { \ + printk("%s is not supported yet under xen.\n", \ + __func__); \ + return -ENOSYS; \ + } \ + } while (0) +#else +#define XEN_NOT_SUPPORTED_YET do { } while (0) +#define HYPERVISOR_perfmon_op(cmd, arg, count) do { } while (0) +#endif + /* * perfmon context state */ @@ -1515,6 +1530,7 @@ pfm_read(struct file *filp, char __user ssize_t ret; unsigned long flags; DECLARE_WAITQUEUE(wait, current); + XEN_NOT_SUPPORTED_YET; if (PFM_IS_FILE(filp) == 0) { printk(KERN_ERR "perfmon: pfm_poll: bad magic [%d]\n", current->pid); return -EINVAL; @@ -2113,6 +2129,16 @@ doit: */ if (free_possible) pfm_context_free(ctx); + if (is_running_on_xen()) { + if (is_xenoprof_primary()) { + int ret = HYPERVISOR_perfmon_op(PFM_DESTROY_CONTEXT, + NULL, 0); + if (ret) + printk("%s:%d PFM_DESTROY_CONTEXT hypercall " + "failed\n", + __func__, __LINE__); + } + } return 0; } @@ -2736,6 +2762,14 @@ pfm_context_create(pfm_context_t *ctx, v */ pfm_reset_pmu_state(ctx); + if (is_running_on_xen()) { + if (is_xenoprof_primary()) { + ret = HYPERVISOR_perfmon_op(PFM_CREATE_CONTEXT, + arg, 0); + if (ret) + goto buffer_error; + } + } return 0; buffer_error: @@ -2872,6 +2906,12 @@ pfm_write_pmcs(pfm_context_t *ctx, void pfm_reg_check_t wr_func; #define PFM_CHECK_PMC_PM(x, y, z) ((x)->ctx_fl_system ^ PMC_PM(y, z)) + if (is_running_on_xen()) { + if (is_xenoprof_primary()) + return HYPERVISOR_perfmon_op(PFM_WRITE_PMCS, + arg, count); + return 0; + } state = ctx->ctx_state; is_loaded = state == PFM_CTX_LOADED ? 1 : 0; is_system = ctx->ctx_fl_system; @@ -3112,6 +3152,12 @@ pfm_write_pmds(pfm_context_t *ctx, void int ret = -EINVAL; pfm_reg_check_t wr_func; + if (is_running_on_xen()) { + if (is_xenoprof_primary()) + return HYPERVISOR_perfmon_op(PFM_WRITE_PMDS, + arg, count); + return 0; + } state = ctx->ctx_state; is_loaded = state == PFM_CTX_LOADED ? 1 : 0; @@ -3309,6 +3355,7 @@ pfm_read_pmds(pfm_context_t *ctx, void * int is_loaded, is_system, is_counting, expert_mode; int ret = -EINVAL; pfm_reg_check_t rd_func; + XEN_NOT_SUPPORTED_YET; /* * access is possible when loaded only for @@ -3560,6 +3607,7 @@ pfm_restart(pfm_context_t *ctx, void *ar pfm_ovfl_ctrl_t rst_ctrl; int state, is_system; int ret = 0; + XEN_NOT_SUPPORTED_YET; state = ctx->ctx_state; fmt = ctx->ctx_buf_fmt; @@ -3709,6 +3757,7 @@ pfm_debug(pfm_context_t *ctx, void *arg, pfm_debug(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs) { unsigned int m = *(unsigned int *)arg; + XEN_NOT_SUPPORTED_YET; pfm_sysctl.debug = m == 0 ? 0 : 1; @@ -3979,6 +4028,8 @@ pfm_get_features(pfm_context_t *ctx, voi { pfarg_features_t *req = (pfarg_features_t *)arg; + if (is_running_on_xen()) + return HYPERVISOR_perfmon_op(PFM_GET_FEATURES, &arg, 0); req->ft_version = PFM_VERSION; return 0; } @@ -3989,6 +4040,12 @@ pfm_stop(pfm_context_t *ctx, void *arg, struct pt_regs *tregs; struct task_struct *task = PFM_CTX_TASK(ctx); int state, is_system; + + if (is_running_on_xen()) { + if (is_xenoprof_primary()) + return HYPERVISOR_perfmon_op(PFM_STOP, NULL, 0); + return 0; + } state = ctx->ctx_state; is_system = ctx->ctx_fl_system; @@ -4078,6 +4135,12 @@ pfm_start(pfm_context_t *ctx, void *arg, struct pt_regs *tregs; int state, is_system; + if (is_running_on_xen()) { + XENPERFMON_PRINTD("PFM_START\n"); + if (is_xenoprof_primary()) + return HYPERVISOR_perfmon_op(PFM_START, NULL, 0); + return 0; + } state = ctx->ctx_state; is_system = ctx->ctx_fl_system; @@ -4160,6 +4223,7 @@ pfm_get_pmc_reset(pfm_context_t *ctx, vo unsigned int cnum; int i; int ret = -EINVAL; + XEN_NOT_SUPPORTED_YET; for (i = 0; i < count; i++, req++) { @@ -4218,6 +4282,11 @@ pfm_context_load(pfm_context_t *ctx, voi int ret = 0; int state, is_system, set_dbregs = 0; + if (is_running_on_xen()) { + if (is_xenoprof_primary()) + return HYPERVISOR_perfmon_op(PFM_LOAD_CONTEXT, arg, 0); + return 0; + } state = ctx->ctx_state; is_system = ctx->ctx_fl_system; /* @@ -4466,6 +4535,12 @@ pfm_context_unload(pfm_context_t *ctx, v int prev_state, is_system; int ret; + if (is_running_on_xen()) { + if (is_xenoprof_primary()) + return HYPERVISOR_perfmon_op(PFM_UNLOAD_CONTEXT, + NULL, 0); + return 0; + } DPRINT(("ctx_state=%d task [%d]\n", ctx->ctx_state, task ? task->pid : -1)); prev_state = ctx->ctx_state; diff -r 0a16a1f7f4cb -r e18530631947 linux-2.6-xen-sparse/arch/ia64/oprofile/Makefile --- a/linux-2.6-xen-sparse/arch/ia64/oprofile/Makefile Thu Oct 26 14:29:00 2006 +0900 +++ b/linux-2.6-xen-sparse/arch/ia64/oprofile/Makefile Thu Oct 26 14:29:30 2006 +0900 @@ -8,3 +8,7 @@ DRIVER_OBJS := $(addprefix ../../../driv oprofile-y := $(DRIVER_OBJS) init.o backtrace.o oprofile-$(CONFIG_PERFMON) += perfmon.o +ifeq ($(CONFIG_XEN), y) +oprofile-$(CONFIG_PERFMON) += xenoprof.o \ + ../../../drivers/xen/xenoprof/xenoprofile.o +endif diff -r 0a16a1f7f4cb -r e18530631947 linux-2.6-xen-sparse/arch/ia64/oprofile/init.c --- a/linux-2.6-xen-sparse/arch/ia64/oprofile/init.c Thu Oct 26 14:29:00 2006 +0900 +++ b/linux-2.6-xen-sparse/arch/ia64/oprofile/init.c Thu Oct 26 14:29:30 2006 +0900 @@ -16,9 +16,28 @@ extern void perfmon_exit(void); extern void perfmon_exit(void); extern void ia64_backtrace(struct pt_regs * const regs, unsigned int depth); +#ifdef CONFIG_XEN +extern int __perfmon_init(void); +extern void __perfmon_exit(void); +extern int xenoprofile_init(struct oprofile_operations * ops); +extern void xenoprofile_exit(void); +#else +#define __perfmon_init() (-ENOSYS) +#define __perfmon_exit() do { } while (0) +#define xenoprofile_init() (-ENOSYS) +#define xenoprofile_exit() do {} while (0) +#endif + int __init oprofile_arch_init(struct oprofile_operations * ops) { int ret = -ENODEV; + + if (is_running_on_xen()) { + ret = __perfmon_init(); + if (ret) + return ret; + return xenoprofile_init(ops); + } #ifdef CONFIG_PERFMON /* perfmon_init() can fail, but we have no way to report it */ @@ -32,6 +51,12 @@ int __init oprofile_arch_init(struct opr void oprofile_arch_exit(void) { + if (is_running_on_xen()) { + xenoprofile_exit(); + __perfmon_exit(); + return; + } + #ifdef CONFIG_PERFMON perfmon_exit(); #endif diff -r 0a16a1f7f4cb -r e18530631947 linux-2.6-xen-sparse/arch/ia64/oprofile/perfmon.c --- a/linux-2.6-xen-sparse/arch/ia64/oprofile/perfmon.c Thu Oct 26 14:29:00 2006 +0900 +++ b/linux-2.6-xen-sparse/arch/ia64/oprofile/perfmon.c Thu Oct 26 14:29:30 2006 +0900 @@ -34,14 +34,20 @@ perfmon_handler(struct task_struct *task } -static int perfmon_start(void) +#ifndef CONFIG_XEN +static +#endif +int perfmon_start(void) { allow_ints = 1; return 0; } -static void perfmon_stop(void) +#ifndef CONFIG_XEN +static +#endif +void perfmon_stop(void) { allow_ints = 0; } @@ -76,16 +82,33 @@ static char * get_cpu_type(void) static int using_perfmon; +int __perfmon_init(void) +{ + int ret = pfm_register_buffer_fmt(&oprofile_fmt); + if (ret) + return -ENODEV; + + using_perfmon = 1; + return 0; +} + +void __perfmon_exit(void) +{ + if (!using_perfmon) + return; + + pfm_unregister_buffer_fmt(oprofile_fmt.fmt_uuid); +} + int perfmon_init(struct oprofile_operations * ops) { - int ret = pfm_register_buffer_fmt(&oprofile_fmt); + int ret = __perfmon_init(); if (ret) return -ENODEV; ops->cpu_type = get_cpu_type(); ops->start = perfmon_start; ops->stop = perfmon_stop; - using_perfmon = 1; printk(KERN_INFO "oprofile: using perfmon.\n"); return 0; } @@ -93,8 +116,5 @@ int perfmon_init(struct oprofile_operati void perfmon_exit(void) { - if (!using_perfmon) - return; - - pfm_unregister_buffer_fmt(oprofile_fmt.fmt_uuid); + __perfmon_exit(); } diff -r 0a16a1f7f4cb -r e18530631947 linux-2.6-xen-sparse/arch/ia64/xen/hypervisor.c --- a/linux-2.6-xen-sparse/arch/ia64/xen/hypervisor.c Thu Oct 26 14:29:00 2006 +0900 +++ b/linux-2.6-xen-sparse/arch/ia64/xen/hypervisor.c Thu Oct 26 14:29:30 2006 +0900 @@ -1050,3 +1050,53 @@ EXPORT_SYMBOL_GPL(p2m_pte); EXPORT_SYMBOL_GPL(p2m_pte); EXPORT_SYMBOL_GPL(p2m_phystomach); #endif + +/////////////////////////////////////////////////////////////////////////// +// for xenoprof + +struct resource* +xen_ia64_allocate_resource(unsigned long size) +{ + struct resource* res; + int error; + + res = kmalloc(sizeof(*res), GFP_KERNEL); + if (res == NULL) + return ERR_PTR(-ENOMEM); + + res->name = "Xen"; + res->flags = IORESOURCE_MEM; + error = allocate_resource(&iomem_resource, res, PAGE_ALIGN(size), + privcmd_resource_min, privcmd_resource_max, + IA64_GRANULE_SIZE, NULL, NULL); + if (error) { + kfree(res); + return ERR_PTR(error); + } + return res; +} + + +void +xen_ia64_release_resource(struct resource* res) +{ + release_resource(res); + kfree(res); +} + +void +xen_ia64_unmap_resource(struct resource* res) +{ + unsigned long gpfn = res->start >> PAGE_SHIFT; + unsigned long nr_pages = (res->end - res->start) >> PAGE_SHIFT; + unsigned long i; + + for (i = 0; i < nr_pages; i++) { + int error = HYPERVISOR_zap_physmap(gpfn + i, 0); + if (error) + printk(KERN_ERR + "%s:%d zap_phsymap failed %d gpfn %lx\n", + __func__, __LINE__, error, gpfn + i); + } + xen_ia64_release_resource(res); +} diff -r 0a16a1f7f4cb -r e18530631947 linux-2.6-xen-sparse/arch/ia64/xen/xcom_hcall.c --- a/linux-2.6-xen-sparse/arch/ia64/xen/xcom_hcall.c Thu Oct 26 14:29:00 2006 +0900 +++ b/linux-2.6-xen-sparse/arch/ia64/xen/xcom_hcall.c Thu Oct 26 14:29:30 2006 +0900 @@ -32,10 +32,12 @@ #include #include #include +#include #include #include #include #include +#include /* Xencomm notes: * This file defines hypercalls to be used by xencomm. The hypercalls simply @@ -271,3 +273,64 @@ xencomm_hypercall_suspend(unsigned long return xencomm_arch_hypercall_suspend(xencomm_create_inline(&arg)); } + +#ifdef CONFIG_OPROFILE +int +xencomm_hypercall_xenoprof_op(int op, void *arg) +{ + switch (op) { + case XENOPROF_init: + case XENOPROF_set_active: + case XENOPROF_set_passive: + case XENOPROF_counter: + case XENOPROF_get_buffer: + break; + + case XENOPROF_reset_active_list: + case XENOPROF_reset_passive_list: + case XENOPROF_reserve_counters: + case XENOPROF_setup_events: + case XENOPROF_enable_virq: + case XENOPROF_start: + case XENOPROF_stop: + case XENOPROF_disable_virq: + case XENOPROF_release_counters: + case XENOPROF_shutdown: + return xencomm_arch_hypercall_xenoprof_op(op, arg); + break; + + default: + printk("%s: op %d isn't supported\n", __func__, op); + return -ENOSYS; + } + return xencomm_arch_hypercall_xenoprof_op(op, + xencomm_create_inline(arg)); +} +#endif + +#ifdef CONFIG_PERFMON +int +xencomm_hypercall_perfmon_op(unsigned long cmd, void* arg, unsigned long count) +{ + switch (cmd) { + case PFM_GET_FEATURES: + case PFM_CREATE_CONTEXT: + case PFM_WRITE_PMCS: + case PFM_WRITE_PMDS: + case PFM_LOAD_CONTEXT: + break; + + case PFM_DESTROY_CONTEXT: + case PFM_UNLOAD_CONTEXT: + case PFM_START: + case PFM_STOP: + return xencomm_arch_hypercall_perfmon_op(cmd, arg, count); + + default: + printk("%s:%d cmd %ld isn't supported\n", __func__, __LINE__, cmd); + BUG(); + } + + return xencomm_arch_hypercall_perfmon_op(cmd, xencomm_create_inline(arg), count); +} +#endif diff -r 0a16a1f7f4cb -r e18530631947 linux-2.6-xen-sparse/arch/ia64/xen/xcom_mini.c --- a/linux-2.6-xen-sparse/arch/ia64/xen/xcom_mini.c Thu Oct 26 14:29:00 2006 +0900 +++ b/linux-2.6-xen-sparse/arch/ia64/xen/xcom_mini.c Thu Oct 26 14:29:30 2006 +0900 @@ -28,12 +28,14 @@ #include #include #include +#include #ifdef CONFIG_VMX_GUEST #include #else #include #endif #include +#include int xencomm_mini_hypercall_event_channel_op(int cmd, void *op) @@ -317,3 +319,98 @@ xencomm_mini_hypercall_xen_version(int c return xencomm_arch_hypercall_xen_version(cmd, desc); } EXPORT_SYMBOL(xencomm_mini_hypercall_xen_version); + +#ifdef CONFIG_OPROFILE +int +xencomm_mini_hypercall_xenoprof_op(int op, void *arg) +{ + unsigned int argsize; + struct xencomm_mini xc_area[2]; + int nbr_area = 2; + struct xencomm_handle *desc; + int rc; + + switch (op) { + case XENOPROF_init: + argsize = sizeof(xenoprof_init_t); + break; + case XENOPROF_set_active: + argsize = sizeof(domid_t); + break; + case XENOPROF_set_passive: + argsize = sizeof(xenoprof_passive_t); + break; + case XENOPROF_counter: + argsize = sizeof(xenoprof_counter_t); + break; + case XENOPROF_get_buffer: + argsize = sizeof(xenoprof_get_buffer_t); + break; + + case XENOPROF_reset_active_list: + case XENOPROF_reset_passive_list: + case XENOPROF_reserve_counters: + case XENOPROF_setup_events: + case XENOPROF_enable_virq: + case XENOPROF_start: + case XENOPROF_stop: + case XENOPROF_disable_virq: + case XENOPROF_release_counters: + case XENOPROF_shutdown: + return xencomm_arch_hypercall_xenoprof_op(op, arg); + + default: + printk("%s: op %d isn't supported\n", __func__, op); + return -ENOSYS; + } + rc = xencomm_create_mini(xc_area, &nbr_area, arg, argsize, &desc); + if (rc) + return rc; + return xencomm_arch_hypercall_xenoprof_op(op, desc); +} +EXPORT_SYMBOL_GPL(xencomm_mini_hypercall_xenoprof_op); +#endif + +#ifdef CONFIG_PERFMON +int +xencomm_mini_hypercall_perfmon_op(unsigned long cmd, void* arg, unsigned long count) +{ + unsigned int argsize; + struct xencomm_mini xc_area[2]; + int nbr_area = 2; + struct xencomm_handle *desc; + int rc; + + switch (cmd) { + case PFM_GET_FEATURES: + argsize = sizeof(pfarg_features_t); + break; + case PFM_CREATE_CONTEXT: + argsize = sizeof(pfarg_context_t); + break; + case PFM_LOAD_CONTEXT: + argsize = sizeof(pfarg_load_t); + break; + case PFM_WRITE_PMCS: + case PFM_WRITE_PMDS: + argsize = sizeof(pfarg_reg_t) * count; + break; + + case PFM_DESTROY_CONTEXT: + case PFM_UNLOAD_CONTEXT: + case PFM_START: + case PFM_STOP: + return xencomm_arch_hypercall_perfmon_op(cmd, arg, count); + + default: + printk("%s:%d cmd %ld isn't supported\n", __func__, __LINE__, cmd); + BUG(); + } + + rc = xencomm_create_mini(xc_area, &nbr_area, arg, argsize, &desc); + if (rc) + return rc; + return xencomm_arch_hypercall_perfmon_op(cmd, desc, count); +} +EXPORT_SYMBOL_GPL(xencomm_mini_hypercall_perfmon_op); +#endif diff -r 0a16a1f7f4cb -r e18530631947 linux-2.6-xen-sparse/include/asm-ia64/hypercall.h --- a/linux-2.6-xen-sparse/include/asm-ia64/hypercall.h Thu Oct 26 14:29:00 2006 +0900 +++ b/linux-2.6-xen-sparse/include/asm-ia64/hypercall.h Thu Oct 26 14:29:30 2006 +0900 @@ -271,6 +271,12 @@ HYPERVISOR_physdev_op(int cmd, void *arg } } +static inline int +xencomm_arch_hypercall_xenoprof_op(int op, struct xencomm_handle *arg) +{ + return _hypercall2(int, xenoprof_op, op, arg); +} + extern fastcall unsigned int __do_IRQ(unsigned int irq, struct pt_regs *regs); static inline void exit_idle(void) {} #define do_IRQ(irq, regs) ({ \ @@ -387,6 +393,15 @@ HYPERVISOR_expose_p2m(unsigned long conv return _hypercall5(unsigned long, ia64_dom0vp_op, IA64_DOM0VP_expose_p2m, conv_start_gpfn, assign_start_gpfn, expose_size, granule_pfn); +} +#endif + +#ifdef CONFIG_PERFMON +static inline int +xencomm_arch_hypercall_perfmon_op(unsigned long cmd, struct xencomm_handle *arg, unsigned long count) +{ + return _hypercall4(int, ia64_dom0vp_op, + IA64_DOM0VP_perfmon, cmd, arg, count); } #endif @@ -403,6 +418,8 @@ HYPERVISOR_expose_p2m(unsigned long conv #define HYPERVISOR_console_io xencomm_mini_hypercall_console_io #define HYPERVISOR_hvm_op xencomm_mini_hypercall_hvm_op #define HYPERVISOR_memory_op xencomm_mini_hypercall_memory_op +#define HYPERVISOR_xenoprof_op xencomm_mini_hypercall_xenoprof_op +#define HYPERVISOR_perfmon_op xencomm_mini_hypercall_perfmon_op #else #define HYPERVISOR_sched_op xencomm_hypercall_sched_op #define HYPERVISOR_event_channel_op xencomm_hypercall_event_channel_op @@ -412,6 +429,8 @@ HYPERVISOR_expose_p2m(unsigned long conv #define HYPERVISOR_console_io xencomm_hypercall_console_io #define HYPERVISOR_hvm_op xencomm_hypercall_hvm_op #define HYPERVISOR_memory_op xencomm_hypercall_memory_op +#define HYPERVISOR_xenoprof_op xencomm_hypercall_xenoprof_op +#define HYPERVISOR_perfmon_op xencomm_hypercall_perfmon_op #endif #define HYPERVISOR_suspend xencomm_hypercall_suspend diff -r 0a16a1f7f4cb -r e18530631947 linux-2.6-xen-sparse/include/asm-ia64/xen/xcom_hcall.h --- a/linux-2.6-xen-sparse/include/asm-ia64/xen/xcom_hcall.h Thu Oct 26 14:29:00 2006 +0900 +++ b/linux-2.6-xen-sparse/include/asm-ia64/xen/xcom_hcall.h Thu Oct 26 14:29:30 2006 +0900 @@ -46,6 +46,14 @@ extern unsigned long xencomm_hypercall_h extern int xencomm_hypercall_suspend(unsigned long srec); +#ifdef CONFIG_OPROFILE +extern int xencomm_hypercall_xenoprof_op(int op, void *arg); +#endif + +#ifdef CONFIG_PERFMON +extern int xencomm_hypercall_perfmon_op(unsigned long cmd, void* arg, unsigned long count); +#endif + /* Using mini xencomm. */ extern int xencomm_mini_hypercall_console_io(int cmd, int count, char *str); @@ -68,6 +76,14 @@ extern int xencomm_mini_hypercall_memory extern unsigned long xencomm_mini_hypercall_hvm_op(int cmd, void *arg); +#ifdef CONFIG_OPROFILE +extern int xencomm_mini_hypercall_xenoprof_op(int op, void *arg); +#endif + +#ifdef CONFIG_PERFMON +extern int xencomm_mini_hypercall_perfmon_op(unsigned long cmd, void* arg, unsigned long count); +#endif + /* For privcmd. Locally declare argument type to avoid include storm. Type coherency will be checked within privcmd.c */ struct privcmd_hypercall; diff -r 0a16a1f7f4cb -r e18530631947 linux-2.6-xen-sparse/arch/ia64/oprofile/oprofile_perfmon.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/linux-2.6-xen-sparse/arch/ia64/oprofile/oprofile_perfmon.h Thu Oct 26 14:29:30 2006 +0900 @@ -0,0 +1,12 @@ +#ifndef OPROFILE_PERFMON_H +#define OPROFILE_PERFMON_H + +#include +#ifdef CONFIG_XEN +int __perfmon_init(void); +void __perfmon_exit(void); +int perfmon_start(void); +void perfmon_stop(void); +#endif /* CONFIG_XEN */ + +#endif /* OPROFILE_PERFMON_H */ diff -r 0a16a1f7f4cb -r e18530631947 linux-2.6-xen-sparse/arch/ia64/oprofile/xenoprof.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/linux-2.6-xen-sparse/arch/ia64/oprofile/xenoprof.c Thu Oct 26 14:29:30 2006 +0900 @@ -0,0 +1,134 @@ +/****************************************************************************** + * xenoprof ia64 specific part + * + * Copyright (c) 2006 Isaku Yamahata + * VA Linux Systems Japan K.K. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +#include +#include +#include + +#include +#include +#include +#include + +#include "oprofile_perfmon.h" + +void __init xenoprof_arch_init_counter(struct xenoprof_init *init) +{ + init->num_events = 0; /* perfmon manages. */ +} + +void xenoprof_arch_counter(void) +{ + /* nothing. perfmon does. */ +} + +void xenoprof_arch_start(void) +{ + perfmon_start(); +} + +void xenoprof_arch_stop(void) +{ + perfmon_stop(); +} + +//XXX move them to an appropriate header file. +struct resource* xen_ia64_allocate_resource(unsigned long size); +void xen_ia64_release_resource(struct resource* res); +void xen_ia64_unmap_resource(struct resource* res); +struct resource* +xenoprof_ia64_allocate_resource(int32_t max_samples) +{ + unsigned long bufsize; + + //XXX add hypercall to get bufsize? + // this value is taken from alloc_xenoprof_struct(). +#if 0 + bufsize = NR_CPUS * (sizeof(struct xenoprof_buf) + + (max_samples - 1) * sizeof(struct event_log)); + bufsize = PAGE_ALIGN(bufsize) + PAGE_SIZE; +#else +#define MAX_OPROF_SHARED_PAGES 32 + bufsize = (MAX_OPROF_SHARED_PAGES + 1) * PAGE_SIZE; +#endif + return xen_ia64_allocate_resource(bufsize); +} + +void xenoprof_arch_unmap_shared_buffer(struct xenoprof_shared_buffer* sbuf) +{ + if (sbuf->buffer) { + xen_ia64_unmap_resource(sbuf->arch.res); + sbuf->buffer = NULL; + sbuf->arch.res = NULL; + } +} + +int xenoprof_arch_map_shared_buffer(struct xenoprof_get_buffer* get_buffer, struct xenoprof_shared_buffer* sbuf) +{ + int ret; + struct resource* res; + + sbuf->buffer = NULL; + sbuf->arch.res = NULL; + res = xenoprof_ia64_allocate_resource(get_buffer->max_samples); + if (IS_ERR(res)) + return PTR_ERR(res); + get_buffer->buf_gmaddr = res->start; + ret = HYPERVISOR_xenoprof_op(XENOPROF_get_buffer, get_buffer); + if (ret) { + xen_ia64_release_resource(res); + return ret; + } + BUG_ON((res->end - res->start + 1) < + get_buffer->bufsize * get_buffer->nbuf); + + sbuf->buffer = __va(res->start); + sbuf->arch.res = res; + return ret; +} + +int xenoprof_arch_set_passive(struct xenoprof_passive* pdomain, + struct xenoprof_shared_buffer* sbuf) +{ + int ret; + struct resource* res; + + sbuf->buffer = NULL; + sbuf->arch.res = NULL; + res = xenoprof_ia64_allocate_resource(pdomain->max_samples); + if (IS_ERR(res)) { + ret = PTR_ERR(res); + goto out; + } + pdomain->buf_gmaddr = res->start; + ret = HYPERVISOR_xenoprof_op(XENOPROF_set_passive, pdomain); + if (ret) { + xen_ia64_release_resource(res); + goto out; + } + BUG_ON((res->end - res->start + 1) < pdomain->bufsize * pdomain->nbuf); + + + sbuf->buffer = __va(res->start); + sbuf->arch.res = res; +out: + return ret; +} diff -r 0a16a1f7f4cb -r e18530631947 linux-2.6-xen-sparse/include/asm-ia64/xenoprof.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/linux-2.6-xen-sparse/include/asm-ia64/xenoprof.h Thu Oct 26 14:29:30 2006 +0900 @@ -0,0 +1,44 @@ +/****************************************************************************** + * asm-ia64/xenoprof.h + * + * Copyright (c) 2006 Isaku Yamahata + * VA Linux Systems Japan K.K. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +#ifndef __ASM_XENOPROF_H__ +#define __ASM_XENOPROF_H__ + +#undef HAVE_XENOPROF_CREATE_FILES + +struct xenoprof_init; +void xenoprof_arch_init_counter(struct xenoprof_init *init); +void xenoprof_arch_counter(void); +void xenoprof_arch_start(void); +void xenoprof_arch_stop(void); + +struct xenoprof_arch_shared_buffer { + struct resource* res; +}; + +struct xenoprof_shared_buffer; +void xenoprof_arch_unmap_shared_buffer(struct xenoprof_shared_buffer* sbuf); +struct xenoprof_get_buffer; +int xenoprof_arch_map_shared_buffer(struct xenoprof_get_buffer* get_buffer, struct xenoprof_shared_buffer* sbuf); +struct xenoprof_passive; +int xenoprof_arch_set_passive(struct xenoprof_passive* pdomain, struct xenoprof_shared_buffer* sbuf); + +#endif /* __ASM_XENOPROF_H__ */