From mboxrd@z Thu Jan 1 00:00:00 1970 From: Konrad Rzeszutek Wilk Subject: Re: [PATCH v2 2/6] xen/PMU: Sysfs interface for setting Xen PMU mode Date: Fri, 6 Jun 2014 16:19:39 -0400 Message-ID: <20140606201939.GA7896@phenom.dumpdata.com> References: <1402076686-26586-1-git-send-email-boris.ostrovsky@oracle.com> <1402076686-26586-3-git-send-email-boris.ostrovsky@oracle.com> Mime-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Return-path: Content-Disposition: inline In-Reply-To: <1402076686-26586-3-git-send-email-boris.ostrovsky@oracle.com> List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Sender: xen-devel-bounces@lists.xen.org Errors-To: xen-devel-bounces@lists.xen.org To: Boris Ostrovsky Cc: kevin.tian@intel.com, dietmar.hahn@ts.fujitsu.com, david.vrabel@citrix.com, JBeulich@suse.com, xen-devel@lists.xen.org List-Id: xen-devel@lists.xenproject.org On Fri, Jun 06, 2014 at 01:44:42PM -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 | 119 +++++++++++++++++++++++++++++++++++ You probably need a Documentation patch as well. ..and some rather minor changes: > include/xen/interface/xen.h | 1 + > include/xen/interface/xenpmu.h | 49 +++++++++++++++ > 5 files changed, 179 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 485b695..628852f 100644 > --- a/arch/x86/xen/xen-head.S > +++ b/arch/x86/xen/xen-head.S > @@ -93,8 +93,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..b37ae2d 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,116 @@ 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", XENPMU_MODE_ON}, > + {"priv_enable", XENPMU_MODE_PRIV}, > + {"disable", 0} > +}; > + > +static ssize_t pmu_mode_store(struct hyp_sysfs_attr *attr, > + const char *buffer, size_t len) > +{ > + int ret; > + struct xen_pmu_params xp; > + int i; 'i' can be on the same line as 'ret' > + > + for (i = 0; i < ARRAY_SIZE(pmu_modes); i++) { > + if (!strncmp(buffer, pmu_modes[i].name, > + strlen(pmu_modes[i].name))) { > + xp.val = 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 xen_pmu_params xp; > + int i; 'i' can be on the same line as 'ret' > + uint32_t mode; > + > + ret = HYPERVISOR_xenpmu_op(XENPMU_mode_get, &xp); > + if (ret) > + return ret; > + > + mode = (uint32_t)xp.val; > + 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_features_store(struct hyp_sysfs_attr *attr, > + const char *buffer, size_t len) > +{ > + int ret; > + uint32_t features; > + struct xen_pmu_params xp; > + > + ret = kstrtou32(buffer, 0, &features); > + if (ret) > + return ret; > + > + xp.val = features; > + ret = HYPERVISOR_xenpmu_op(XENPMU_feature_set, &xp); > + if (ret) > + return ret; > + > + return len; > +} > + > +static ssize_t pmu_features_show(struct hyp_sysfs_attr *attr, char *buffer) > +{ > + int ret; > + struct xen_pmu_params xp; > + > + ret = HYPERVISOR_xenpmu_op(XENPMU_feature_get, &xp); > + if (ret) > + return ret; > + > + return sprintf(buffer, "0x%x\n", (uint32_t)xp.val); > +} > +HYPERVISOR_ATTR_RW(pmu_features); > + > +static struct attribute *xen_pmu_attrs[] = { > + &pmu_mode_attr.attr, > + &pmu_features_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 +501,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 +525,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 0cd5ca3..d071e4a 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..0d15d3a > --- /dev/null > +++ b/include/xen/interface/xenpmu.h > @@ -0,0 +1,49 @@ > +#ifndef __XEN_PUBLIC_XENPMU_H__ > +#define __XEN_PUBLIC_XENPMU_H__ > + > +#include "xen.h" > + > +#define XENPMU_VER_MAJ 0 > +#define XENPMU_VER_MIN 1 > + > +/* HYPERVISOR_xenpmu_op commands */ > +#define XENPMU_mode_get 0 > +#define XENPMU_mode_set 1 > +#define XENPMU_feature_get 2 > +#define XENPMU_feature_set 3 > + > +/* Parameter structure for HYPERVISOR_xenpmu_op call */ > +struct xen_pmu_params { > + union { > + struct version { > + uint8_t maj; > + uint8_t min; > + } version; > + uint64_t pad; > + }; > + union { > + uint64_t val; > + GUEST_HANDLE(void) valp; > + }; > +}; > + > +/* PMU modes: > + * - XENPMU_MODE_OFF: No PMU virtualization > + * - XENPMU_MODE_ON: Guests can profile themselves, dom0 profiles > + * itself and Xen > + * - XENPMU_MODE_PRIV: Only dom0 has access to VPMU and it profiles > + * everyone: itself, the hypervisor and the guests. > + */ > +#define XENPMU_MODE_OFF 0 > +#define XENPMU_MODE_ON (1<<0) > +#define XENPMU_MODE_PRIV (1<<1) > + > + > +/* > + * PMU features: > + * - XENPMU_FEATURE_INTEL_BTS: Intel BTS support (ignored on AMD) > + */ > +#define XENPMU_FEATURE_INTEL_BTS 1 > + > + > +#endif /* __XEN_PUBLIC_XENPMU_H__ */ > -- > 1.8.1.4 >