Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753591Ab3IWNSB (ORCPT ); Mon, 23 Sep 2013 09:18:01 -0400 Received: from aserp1040.oracle.com ([141.146.126.69]:32427 "EHLO aserp1040.oracle.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753456Ab3IWNSA (ORCPT ); Mon, 23 Sep 2013 09:18:00 -0400 Date: Mon, 23 Sep 2013 09:17:43 -0400 From: Konrad Rzeszutek Wilk To: Boris Ostrovsky Cc: xen-devel@lists.xen.org, david.vrabel@citrix.com, JBeulich@suse.com, linux-kernel@vger.kernel.org Subject: Re: [PATCH v1 2/5] xen/PMU: Sysfs interface for setting Xen PMU mode Message-ID: <20130923131743.GC3175@phenom.dumpdata.com> References: <1378827110-4192-1-git-send-email-boris.ostrovsky@oracle.com> <1378827110-4192-3-git-send-email-boris.ostrovsky@oracle.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1378827110-4192-3-git-send-email-boris.ostrovsky@oracle.com> User-Agent: Mutt/1.5.21 (2010-09-15) X-Source-IP: acsinet22.oracle.com [141.146.126.238] Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 7424 Lines: 272 On Tue, Sep 10, 2013 at 11:31:47AM -0400, Boris Ostrovsky wrote: > Set Xen's PMU mode via /sys/hypervisor/pmu/pmu_mode. Add XENPMU hypercall. > > Signed-off-by: Boris Ostrovsky > --- > arch/x86/include/asm/xen/hypercall.h | 6 ++ > arch/x86/xen/xen-head.S | 5 +- > drivers/xen/sys-hypervisor.c | 118 +++++++++++++++++++++++++++++++++++ > include/xen/interface/xen.h | 1 + > include/xen/interface/xenpmu.h | 44 +++++++++++++ > 5 files changed, 173 insertions(+), 1 deletion(-) > create mode 100644 include/xen/interface/xenpmu.h > > diff --git a/arch/x86/include/asm/xen/hypercall.h b/arch/x86/include/asm/xen/hypercall.h > index e709884..f022cef 100644 > --- a/arch/x86/include/asm/xen/hypercall.h > +++ b/arch/x86/include/asm/xen/hypercall.h > @@ -465,6 +465,12 @@ HYPERVISOR_tmem_op( > return _hypercall1(int, tmem_op, op); > } > > +static inline int > +HYPERVISOR_xenpmu_op(unsigned int op, void *arg) > +{ > + return _hypercall2(int, xenpmu_op, op, arg); > +} > + > static inline void > MULTI_fpu_taskswitch(struct multicall_entry *mcl, int set) > { > diff --git a/arch/x86/xen/xen-head.S b/arch/x86/xen/xen-head.S > index 7faed58..f2415e6 100644 > --- a/arch/x86/xen/xen-head.S > +++ b/arch/x86/xen/xen-head.S > @@ -73,8 +73,11 @@ NEXT_HYPERCALL(sysctl) > NEXT_HYPERCALL(domctl) > NEXT_HYPERCALL(kexec_op) > NEXT_HYPERCALL(tmem_op) /* 38 */ > +ENTRY(xenclient_rsvd) > + .skip 32 > +NEXT_HYPERCALL(xenpmu_op) /* 40 */ > ENTRY(xen_hypercall_rsvr) > - .skip 320 > + .skip 256 > NEXT_HYPERCALL(mca) /* 48 */ > NEXT_HYPERCALL(arch_1) > NEXT_HYPERCALL(arch_2) > diff --git a/drivers/xen/sys-hypervisor.c b/drivers/xen/sys-hypervisor.c > index 96453f8..2218154 100644 > --- a/drivers/xen/sys-hypervisor.c > +++ b/drivers/xen/sys-hypervisor.c > @@ -20,6 +20,7 @@ > #include > #include > #include > +#include > > #define HYPERVISOR_ATTR_RO(_name) \ > static struct hyp_sysfs_attr _name##_attr = __ATTR_RO(_name) > @@ -368,6 +369,115 @@ static void xen_properties_destroy(void) > sysfs_remove_group(hypervisor_kobj, &xen_properties_group); > } > > +struct pmu_mode { > + const char *name; > + uint32_t mode; > +}; > +struct pmu_mode pmu_modes[] = { > + {"enable", VPMU_ON}, > + {"priv_enable", VPMU_PRIV}, > + {"disable", 0} > +}; > +static ssize_t pmu_mode_store(struct hyp_sysfs_attr *attr, > + const char *buffer, size_t len) > +{ > + int ret; > + struct xenpmu_params xp; > + int i; > + > + for (i = 0; i < ARRAY_SIZE(pmu_modes); i++) { > + if (!strncmp(buffer, pmu_modes[i].name, > + strlen(pmu_modes[i].name))) { > + xp.control = pmu_modes[i].mode; > + break; > + } > + } > + > + if (i == ARRAY_SIZE(pmu_modes)) > + return -EINVAL; > + > + ret = HYPERVISOR_xenpmu_op(XENPMU_mode_set, &xp); > + if (ret) > + return ret; > + > + return len; > +} > + > +static ssize_t pmu_mode_show(struct hyp_sysfs_attr *attr, char *buffer) > +{ > + int ret; > + struct xenpmu_params xp; > + int i; > + uint32_t mode; > + > + ret = HYPERVISOR_xenpmu_op(XENPMU_mode_get, &xp); > + if (ret) > + return ret; > + > + mode = (uint32_t)xp.control & VPMU_MODE_MASK; > + for (i = 0; i < ARRAY_SIZE(pmu_modes); i++) { > + if (mode == pmu_modes[i].mode) > + return sprintf(buffer, "%s\n", pmu_modes[i].name); > + } > + > + return -EINVAL; > +} > +HYPERVISOR_ATTR_RW(pmu_mode); > + > + > +static ssize_t pmu_flags_store(struct hyp_sysfs_attr *attr, > + const char *buffer, size_t len) > +{ > + int ret; > + uint32_t flags; > + struct xenpmu_params xp; > + > + ret = kstrtou32(buffer, 0, &flags); > + if (ret) > + return ret; > + > + xp.control = flags; > + ret = HYPERVISOR_xenpmu_op(XENPMU_flags_set, &xp); > + if (ret) > + return ret; > + > + return len; > +} > + > +static ssize_t pmu_flags_show(struct hyp_sysfs_attr *attr, char *buffer) > +{ > + int ret; > + struct xenpmu_params xp; > + > + ret = HYPERVISOR_xenpmu_op(XENPMU_flags_get, &xp); > + if (ret) > + return ret; > + > + return sprintf(buffer, "0x%x\n", (uint32_t)xp.control); > +} > +HYPERVISOR_ATTR_RW(pmu_flags); > + > +static struct attribute *xen_pmu_attrs[] = { > + &pmu_mode_attr.attr, > + &pmu_flags_attr.attr, > + NULL > +}; > + > +static const struct attribute_group xen_pmu_group = { > + .name = "pmu", > + .attrs = xen_pmu_attrs, > +}; > + > +static int __init xen_pmu_init(void) > +{ > + return sysfs_create_group(hypervisor_kobj, &xen_pmu_group); > +} > + > +static void xen_pmu_destroy(void) > +{ > + sysfs_remove_group(hypervisor_kobj, &xen_pmu_group); > +} > + > static int __init hyper_sysfs_init(void) > { > int ret; > @@ -390,9 +500,16 @@ static int __init hyper_sysfs_init(void) > ret = xen_properties_init(); > if (ret) > goto prop_out; > + if (xen_initial_domain()) { > + ret = xen_pmu_init(); > + if (ret) > + goto pmu_out; > + } > > goto out; > > +pmu_out: > + xen_properties_destroy(); > prop_out: > xen_sysfs_uuid_destroy(); > uuid_out: > @@ -407,6 +524,7 @@ out: > > static void __exit hyper_sysfs_exit(void) > { > + xen_pmu_destroy(); > xen_properties_destroy(); > xen_compilation_destroy(); > xen_sysfs_uuid_destroy(); > diff --git a/include/xen/interface/xen.h b/include/xen/interface/xen.h > index 53ec416..c29d427 100644 > --- a/include/xen/interface/xen.h > +++ b/include/xen/interface/xen.h > @@ -58,6 +58,7 @@ > #define __HYPERVISOR_physdev_op 33 > #define __HYPERVISOR_hvm_op 34 > #define __HYPERVISOR_tmem_op 38 > +#define __HYPERVISOR_xenpmu_op 40 > > /* Architecture-specific hypercall definitions. */ > #define __HYPERVISOR_arch_0 48 > diff --git a/include/xen/interface/xenpmu.h b/include/xen/interface/xenpmu.h > new file mode 100644 > index 0000000..63c42b1 > --- /dev/null > +++ b/include/xen/interface/xenpmu.h > @@ -0,0 +1,44 @@ > +#ifndef __XEN_PUBLIC_XENPMU_H__ > +#define __XEN_PUBLIC_XENPMU_H__ > + > +#include > + > +#include "xen.h" > + > +#define XENPMU_VER_MAJ 0 > +#define XENPMU_VER_MIN 0 > + > +/* HYPERVISOR_xenpmu_op commands */ > +#define XENPMU_mode_get 0 > +#define XENPMU_mode_set 1 > +#define XENPMU_flags_get 2 > +#define XENPMU_flags_set 3 > + > +/* Parameter structure for HYPERVISOR_xenpmu_op call */ > +struct xenpmu_params { > + union { > + struct version { > + uint8_t maj; > + uint8_t min; > + } version; > + uint64_t pad; > + }; > + uint64_t control; > +}; > + > +/* VPMU modes */ > +#define VPMU_MODE_MASK 0xff > +#define VPMU_OFF 0 > +/* guests can profile themselves, (dom0 profiles itself and Xen) */ > +#define VPMU_ON (1<<0) > +/* > + * Only dom0 has access to VPMU and it profiles everyone: itself, > + * the hypervisor and the guests. > + */ > +#define VPMU_PRIV (1<<1) > + > +/* VPMU flags */ > +#define VPMU_FLAGS_MASK ((uint32_t)(~VPMU_MODE_MASK)) > +#define VPMU_INTEL_BTS (1<<8) /* Ignored on AMD */ > + > +#endif /* __XEN_PUBLIC_XENPMU_H__ */ Looks OK to me if there are no changes to the hypervisor ABI. > -- > 1.8.1.4 > -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/