# HG changeset patch # User yamahata@xxxxxxxxxxxxx # Date 1161350234 -32400 # Node ID 2481c8a1b9e4612d5ee8b68daefa237d227bf21b # Parent d3c1544495321e67315d32d02a030b3684a4450d xenoprof for IA64. linux side PATCHNAME: xenoprof_ia64_linux_side Signed-off-by: Isaku Yamahata diff -r d3c154449532 -r 2481c8a1b9e4 linux-2.6-xen-sparse/arch/ia64/kernel/perfmon.c --- a/linux-2.6-xen-sparse/arch/ia64/kernel/perfmon.c Fri Oct 20 12:52:09 2006 +0900 +++ b/linux-2.6-xen-sparse/arch/ia64/kernel/perfmon.c Fri Oct 20 22:17:14 2006 +0900 @@ -53,6 +53,20 @@ #include #ifdef CONFIG_PERFMON +#ifdef CONFIG_XEN +#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 +1529,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 +2128,12 @@ doit: */ if (free_possible) pfm_context_free(ctx); + if (is_running_on_xen()) { + 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 +2757,11 @@ pfm_context_create(pfm_context_t *ctx, v */ pfm_reset_pmu_state(ctx); + if (is_running_on_xen()) { + ret = HYPERVISOR_perfmon_op(PFM_CREATE_CONTEXT, arg, 0); + if (ret) + goto buffer_error; + } return 0; buffer_error: @@ -2872,6 +2898,8 @@ 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()) + return HYPERVISOR_perfmon_op(PFM_WRITE_PMCS, arg, count); state = ctx->ctx_state; is_loaded = state == PFM_CTX_LOADED ? 1 : 0; is_system = ctx->ctx_fl_system; @@ -3112,6 +3140,8 @@ pfm_write_pmds(pfm_context_t *ctx, void int ret = -EINVAL; pfm_reg_check_t wr_func; + if (is_running_on_xen()) + return HYPERVISOR_perfmon_op(PFM_WRITE_PMDS, arg, count); state = ctx->ctx_state; is_loaded = state == PFM_CTX_LOADED ? 1 : 0; @@ -3309,6 +3339,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 +3591,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 +3741,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 +4012,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 +4024,9 @@ 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()) + return HYPERVISOR_perfmon_op(PFM_STOP, NULL, 0); state = ctx->ctx_state; is_system = ctx->ctx_fl_system; @@ -4078,6 +4116,8 @@ pfm_start(pfm_context_t *ctx, void *arg, struct pt_regs *tregs; int state, is_system; + if (is_running_on_xen()) + return HYPERVISOR_perfmon_op(PFM_START, NULL, 0); state = ctx->ctx_state; is_system = ctx->ctx_fl_system; @@ -4160,6 +4200,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 +4259,8 @@ pfm_context_load(pfm_context_t *ctx, voi int ret = 0; int state, is_system, set_dbregs = 0; + if (is_running_on_xen()) + return HYPERVISOR_perfmon_op(PFM_LOAD_CONTEXT, arg, 0); state = ctx->ctx_state; is_system = ctx->ctx_fl_system; /* @@ -4466,6 +4509,8 @@ pfm_context_unload(pfm_context_t *ctx, v int prev_state, is_system; int ret; + if (is_running_on_xen()) + return HYPERVISOR_perfmon_op(PFM_UNLOAD_CONTEXT, NULL, 0); DPRINT(("ctx_state=%d task [%d]\n", ctx->ctx_state, task ? task->pid : -1)); prev_state = ctx->ctx_state; diff -r d3c154449532 -r 2481c8a1b9e4 linux-2.6-xen-sparse/arch/ia64/oprofile/Makefile --- a/linux-2.6-xen-sparse/arch/ia64/oprofile/Makefile Fri Oct 20 12:52:09 2006 +0900 +++ b/linux-2.6-xen-sparse/arch/ia64/oprofile/Makefile Fri Oct 20 22:17:14 2006 +0900 @@ -8,3 +8,6 @@ DRIVER_OBJS := $(addprefix ../../../driv oprofile-y := $(DRIVER_OBJS) init.o backtrace.o oprofile-$(CONFIG_PERFMON) += perfmon.o +ifdef CONFIG_XEN +oprofile-$(CONFIG_PERFMON) += xenoprof.o +endif diff -r d3c154449532 -r 2481c8a1b9e4 linux-2.6-xen-sparse/arch/ia64/oprofile/init.c --- a/linux-2.6-xen-sparse/arch/ia64/oprofile/init.c Fri Oct 20 12:52:09 2006 +0900 +++ b/linux-2.6-xen-sparse/arch/ia64/oprofile/init.c Fri Oct 20 22:17:14 2006 +0900 @@ -16,9 +16,20 @@ 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 xenoprofile_arch_init(struct oprofile_operations * ops); +extern void xenoprofile_arch_exit(void); +#else +#define xenoprofile_arch_init() (-ENOSYS) +#define xenoprofile_arch_exit() do {} while (0) +#endif + int __init oprofile_arch_init(struct oprofile_operations * ops) { int ret = -ENODEV; + + if (is_running_on_xen()) + return xenoprofile_arch_init(ops); #ifdef CONFIG_PERFMON /* perfmon_init() can fail, but we have no way to report it */ @@ -32,6 +43,11 @@ int __init oprofile_arch_init(struct opr void oprofile_arch_exit(void) { + if (is_running_on_xen()) { + xenoprofile_arch_exit(); + return; + } + #ifdef CONFIG_PERFMON perfmon_exit(); #endif diff -r d3c154449532 -r 2481c8a1b9e4 linux-2.6-xen-sparse/arch/ia64/oprofile/perfmon.c --- a/linux-2.6-xen-sparse/arch/ia64/oprofile/perfmon.c Fri Oct 20 12:52:09 2006 +0900 +++ b/linux-2.6-xen-sparse/arch/ia64/oprofile/perfmon.c Fri Oct 20 22:17:14 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 d3c154449532 -r 2481c8a1b9e4 linux-2.6-xen-sparse/arch/ia64/oprofile/xenoprof.c --- a/linux-2.6-xen-sparse/arch/ia64/oprofile/xenoprof.c Fri Oct 20 12:52:09 2006 +0900 +++ b/linux-2.6-xen-sparse/arch/ia64/oprofile/xenoprof.c Fri Oct 20 22:17:14 2006 +0900 @@ -9,6 +9,10 @@ * Modified by Aravind Menon and Jose Renato Santos for Xen * These modifications are: * Copyright (C) 2005 Hewlett-Packard Co. + * + * Modified for Xen/IA64 + * Copyright (c) 2006 Isaku Yamahata + * VA Linux Systems Japan K.K. */ #include @@ -19,18 +23,46 @@ #include #include #include +#ifndef __ia64__ #include #include #include +#endif #include #include +#ifndef __ia64__ #include "op_counter.h" +#endif #include #include #include +#ifndef __ia64__ #include <../../../drivers/oprofile/cpu_buffer.h> #include <../../../drivers/oprofile/event_buffer.h> +#else +#include "../../../drivers/oprofile/cpu_buffer.h" +#include "../../../drivers/oprofile/event_buffer.h" +#include "oprofile_perfmon.h" +#include + +//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(). + bufsize = sizeof(struct xenoprof_buf) + + (max_samples - 1) * sizeof(struct event_log); + bufsize = PAGE_ALIGN(bufsize); + return xen_ia64_allocate_resource(bufsize); +} +#endif #define MAX_XENOPROF_SAMPLES 16 @@ -46,6 +78,9 @@ xenoprof_buf_t * xenoprof_buf[MAX_VIRT_C xenoprof_buf_t * xenoprof_buf[MAX_VIRT_CPUS]; /* Shared buffer area */ char * shared_buffer = NULL; +#ifdef __ia64__ +struct resource* shared_resource; +#endif /* Number of buffers in shared area (one per VCPU) */ int nbuf; /* Mappings of VIRQ_XENOPROF to irq number (per cpu) */ @@ -57,6 +92,9 @@ xenoprof_buf_t *p_xenoprof_buf[MAX_OPROF xenoprof_buf_t *p_xenoprof_buf[MAX_OPROF_DOMAINS][MAX_VIRT_CPUS]; /* Passive shared buffer area */ char *p_shared_buffer[MAX_OPROF_DOMAINS]; +#ifdef __ia64__ +struct resource* p_shared_resource[MAX_OPROF_DOMAINS]; +#endif #ifdef CONFIG_PM @@ -98,7 +136,7 @@ static int __init init_driverfs(void) } -static void __exit exit_driverfs(void) +static void /* __exit */ exit_driverfs(void) { sysdev_unregister(&device_oprofile); sysdev_class_unregister(&oprofile_sysclass); @@ -239,18 +277,37 @@ static int map_xenoprof_buffer(int max_s { struct xenoprof_get_buffer get_buffer; struct xenoprof_buf *buf; +#ifndef __ia64__ int npages, ret, i; struct vm_struct *area; +#else + int ret, i; + struct resource* res; +#endif if ( shared_buffer ) return 0; get_buffer.max_samples = max_samples; +#ifndef __ia64__ if ( (ret = HYPERVISOR_xenoprof_op(XENOPROF_get_buffer, &get_buffer)) ) return ret; +#else + res = xenoprof_ia64_allocate_resource(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) < get_buffer.bufsize); +#endif nbuf = get_buffer.nbuf; +#ifndef __ia64__ npages = (get_buffer.bufsize * nbuf - 1) / PAGE_SIZE + 1; area = alloc_vm_area(npages * PAGE_SIZE); @@ -266,6 +323,9 @@ static int map_xenoprof_buffer(int max_s } shared_buffer = area->addr; +#else + shared_buffer = __va(res->start); +#endif for (i=0; i< nbuf; i++) { buf = (struct xenoprof_buf*) &shared_buffer[i * get_buffer.bufsize]; @@ -280,7 +340,9 @@ static int xenoprof_setup(void) static int xenoprof_setup(void) { int ret; +#ifndef __ia64__ int i; +#endif if ( (ret = map_xenoprof_buffer(MAX_XENOPROF_SAMPLES)) ) return ret; @@ -289,7 +351,9 @@ static int xenoprof_setup(void) return ret; if (is_primary) { +#ifndef __ia64__ struct xenoprof_counter counter; +#endif /* Define dom0 as an active domain if not done yet */ if (!active_defined) { @@ -307,6 +371,7 @@ static int xenoprof_setup(void) ret = HYPERVISOR_xenoprof_op(XENOPROF_reserve_counters, NULL); if (ret) goto err; +#ifndef __ia64__ for (i=0; iaddr; +#else + res = xenoprof_ia64_allocate_resource( + passive_domains[i].max_samples); + if (IS_ERR(res)) { + ret = PTR_ERR(res); + goto out; + } + passive_domains[i].buf_gmaddr = res->start; + ret = HYPERVISOR_xenoprof_op(XENOPROF_set_passive, + &passive_domains[i]); + if (ret) { + xen_ia64_release_resource(res); + goto out; + } + BUG_ON((res->end - res->start) < passive_domains[i].bufsize); + + p_shared_buffer[i] = __va(res->start); + p_shared_resource[i] = res; +#endif for (j = 0; j < passive_domains[i].nbuf; j++) { buf = (struct xenoprof_buf *) @@ -474,13 +572,19 @@ static int xenoprof_set_passive(int * p_ out: for (j = 0; j < i; j++) { +#ifndef __ia64__ vunmap(p_shared_buffer[j]); +#else + xen_ia64_unmap_resource(p_shared_resource[j]); + p_shared_resource[j] = NULL; +#endif p_shared_buffer[j] = NULL; } return ret; } +#ifndef __ia64__ struct op_counter_config counter_config[OP_MAX_COUNTER]; static int xenoprof_create_files(struct super_block * sb, struct dentry * root) @@ -509,10 +613,13 @@ static int xenoprof_create_files(struct return 0; } +#endif struct oprofile_operations xenoprof_ops = { +#ifndef __ia64__ .create_files = xenoprof_create_files, +#endif .set_active = xenoprof_set_active, .set_passive = xenoprof_set_passive, .setup = xenoprof_setup, @@ -525,21 +632,32 @@ struct oprofile_operations xenoprof_ops /* in order to get driverfs right */ static int using_xenoprof; +#ifndef __ia64__ int __init oprofile_arch_init(struct oprofile_operations * ops) +#else +int __init xenoprofile_arch_init(struct oprofile_operations * ops) +#endif { struct xenoprof_init init; int ret, i; +#ifdef __ia64__ + ret = __perfmon_init(); + if (ret) + return ret; +#endif ret = HYPERVISOR_xenoprof_op(XENOPROF_init, &init); if (!ret) { num_events = init.num_events; is_primary = init.is_primary; +#ifndef __ia64__ /* just in case - make sure we do not overflow event list (i.e. counter_config list) */ if (num_events > OP_MAX_COUNTER) num_events = OP_MAX_COUNTER; +#endif /* cpu_type is detected by Xen */ cpu_type[XENOPROF_CPU_TYPE_SIZE-1] = 0; @@ -555,13 +673,22 @@ int __init oprofile_arch_init(struct opr active_defined = 0; } +#ifndef __ia64__ printk(KERN_INFO "oprofile_arch_init: ret %d, events %d, " "is_primary %d\n", ret, num_events, is_primary); +#else + printk(KERN_INFO "%s: ret %d, events %d, is_primary %d\n", + __func__, ret, num_events, is_primary); +#endif return ret; } -void __exit oprofile_arch_exit(void) +#ifndef __ia64__ +void /* __exit */ oprofile_arch_exit(void) +#else +void /* __exit */ xenoprofile_arch_exit(void) +#endif { int i; @@ -569,16 +696,29 @@ void __exit oprofile_arch_exit(void) exit_driverfs(); if (shared_buffer) { +#ifndef __ia64__ vunmap(shared_buffer); +#else + xen_ia64_unmap_resource(shared_resource); + shared_resource = NULL; +#endif shared_buffer = NULL; } if (is_primary) { for (i = 0; i < pdomains; i++) if (p_shared_buffer[i]) { +#ifndef __ia64__ vunmap(p_shared_buffer[i]); +#else + xen_ia64_unmap_resource(p_shared_resource[i]); + p_shared_resource[i] = NULL; +#endif p_shared_buffer[i] = NULL; } HYPERVISOR_xenoprof_op(XENOPROF_shutdown, NULL); } -} +#ifdef __ia64__ + __perfmon_exit(); +#endif +} diff -r d3c154449532 -r 2481c8a1b9e4 linux-2.6-xen-sparse/arch/ia64/xen/hypervisor.c --- a/linux-2.6-xen-sparse/arch/ia64/xen/hypervisor.c Fri Oct 20 12:52:09 2006 +0900 +++ b/linux-2.6-xen-sparse/arch/ia64/xen/hypervisor.c Fri Oct 20 22:17:14 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 d3c154449532 -r 2481c8a1b9e4 linux-2.6-xen-sparse/arch/ia64/xen/xcom_hcall.c --- a/linux-2.6-xen-sparse/arch/ia64/xen/xcom_hcall.c Fri Oct 20 12:52:09 2006 +0900 +++ b/linux-2.6-xen-sparse/arch/ia64/xen/xcom_hcall.c Fri Oct 20 22:17:14 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 d3c154449532 -r 2481c8a1b9e4 linux-2.6-xen-sparse/arch/ia64/xen/xcom_mini.c --- a/linux-2.6-xen-sparse/arch/ia64/xen/xcom_mini.c Fri Oct 20 12:52:09 2006 +0900 +++ b/linux-2.6-xen-sparse/arch/ia64/xen/xcom_mini.c Fri Oct 20 22:17:14 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 d3c154449532 -r 2481c8a1b9e4 linux-2.6-xen-sparse/include/asm-ia64/hypercall.h --- a/linux-2.6-xen-sparse/include/asm-ia64/hypercall.h Fri Oct 20 12:52:09 2006 +0900 +++ b/linux-2.6-xen-sparse/include/asm-ia64/hypercall.h Fri Oct 20 22:17:14 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 d3c154449532 -r 2481c8a1b9e4 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 Fri Oct 20 12:52:09 2006 +0900 +++ b/linux-2.6-xen-sparse/include/asm-ia64/xen/xcom_hcall.h Fri Oct 20 22:17:14 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 d3c154449532 -r 2481c8a1b9e4 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 Fri Oct 20 22:17:14 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 */