All of lore.kernel.org
 help / color / mirror / Atom feed
From: Boris Ostrovsky <boris.ostrovsky@oracle.com>
To: JBeulich@suse.com, kevin.tian@intel.com,
	suravee.suthikulpanit@amd.com, Aravind.Gopalakrishnan@amd.com,
	dietmar.hahn@ts.fujitsu.com, dgdegra@tycho.nsa.gov,
	andrew.cooper3@citrix.com
Cc: boris.ostrovsky@oracle.com, tim@xen.org, jun.nakajima@intel.com,
	xen-devel@lists.xen.org
Subject: [PATCH v20 06/13] x86/VPMU: Initialize PMU for PV(H) guests
Date: Thu,  9 Apr 2015 11:44:48 -0400	[thread overview]
Message-ID: <1428594295-2024-7-git-send-email-boris.ostrovsky@oracle.com> (raw)
In-Reply-To: <1428594295-2024-1-git-send-email-boris.ostrovsky@oracle.com>

Code for initializing/tearing down PMU for PV guests

Signed-off-by: Boris Ostrovsky <boris.ostrovsky@oracle.com>
Acked-by: Kevin Tian <kevin.tian@intel.com>
Acked-by: Daniel De Graaf <dgdegra@tycho.nsa.gov>
---
Changes in v20:
* Moved page freeing/unmapping from under vpmu_lock in pvpmu_init()/pvpmu_finish():
* Using is_hardware_domain() instead of open-coding
* Added comments to explain how vpmu_count is used.
* Don't test d->vcpu as it is covered by preceding d->max_vcpus check

 tools/flask/policy/policy/modules/xen/xen.te |   4 +
 xen/arch/x86/domain.c                        |   2 +
 xen/arch/x86/hvm/hvm.c                       |   1 +
 xen/arch/x86/hvm/svm/svm.c                   |   4 +-
 xen/arch/x86/hvm/svm/vpmu.c                  |  44 ++++++---
 xen/arch/x86/hvm/vmx/vmx.c                   |   4 +-
 xen/arch/x86/hvm/vmx/vpmu_core2.c            |  79 +++++++++++-----
 xen/arch/x86/hvm/vpmu.c                      | 131 ++++++++++++++++++++++++---
 xen/common/event_channel.c                   |   1 +
 xen/include/asm-x86/hvm/vpmu.h               |   2 +
 xen/include/public/pmu.h                     |   2 +
 xen/include/public/xen.h                     |   1 +
 xen/include/xsm/dummy.h                      |   3 +
 xen/xsm/flask/hooks.c                        |   4 +
 xen/xsm/flask/policy/access_vectors          |   2 +
 15 files changed, 232 insertions(+), 52 deletions(-)

diff --git a/tools/flask/policy/policy/modules/xen/xen.te b/tools/flask/policy/policy/modules/xen/xen.te
index 963ed44..c47369a 100644
--- a/tools/flask/policy/policy/modules/xen/xen.te
+++ b/tools/flask/policy/policy/modules/xen/xen.te
@@ -120,6 +120,10 @@ domain_comms(dom0_t, dom0_t)
 # Allow all domains to use (unprivileged parts of) the tmem hypercall
 allow domain_type xen_t:xen tmem_op;
 
+# Allow all domains to use PMU (but not to change its settings --- that's what
+# pmu_ctrl is for)
+allow domain_type xen_t:xen2 pmu_use;
+
 ###############################################################################
 #
 # Domain creation
diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c
index 9d5a527..dd10223 100644
--- a/xen/arch/x86/domain.c
+++ b/xen/arch/x86/domain.c
@@ -438,6 +438,8 @@ int vcpu_initialise(struct vcpu *v)
         vmce_init_vcpu(v);
     }
 
+    spin_lock_init(&v->arch.vpmu.vpmu_lock);
+
     if ( has_hvm_container_domain(d) )
     {
         rc = hvm_vcpu_initialise(v);
diff --git a/xen/arch/x86/hvm/hvm.c b/xen/arch/x86/hvm/hvm.c
index 3ff87c6..7fcbb3e 100644
--- a/xen/arch/x86/hvm/hvm.c
+++ b/xen/arch/x86/hvm/hvm.c
@@ -4914,6 +4914,7 @@ static hvm_hypercall_t *const pvh_hypercall64_table[NR_hypercalls] = {
     HYPERCALL(hvm_op),
     HYPERCALL(sysctl),
     HYPERCALL(domctl),
+    HYPERCALL(xenpmu_op),
     [ __HYPERVISOR_arch_1 ] = (hvm_hypercall_t *)paging_domctl_continuation
 };
 
diff --git a/xen/arch/x86/hvm/svm/svm.c b/xen/arch/x86/hvm/svm/svm.c
index b6e77cd..e523d12 100644
--- a/xen/arch/x86/hvm/svm/svm.c
+++ b/xen/arch/x86/hvm/svm/svm.c
@@ -1166,7 +1166,9 @@ static int svm_vcpu_initialise(struct vcpu *v)
         return rc;
     }
 
-    vpmu_initialise(v);
+    /* PVH's VPMU is initialized via hypercall */
+    if ( is_hvm_vcpu(v) )
+        vpmu_initialise(v);
 
     svm_guest_osvw_init(v);
 
diff --git a/xen/arch/x86/hvm/svm/vpmu.c b/xen/arch/x86/hvm/svm/vpmu.c
index b60ca40..58a0dc4 100644
--- a/xen/arch/x86/hvm/svm/vpmu.c
+++ b/xen/arch/x86/hvm/svm/vpmu.c
@@ -360,17 +360,19 @@ static void amd_vpmu_destroy(struct vcpu *v)
 {
     struct vpmu_struct *vpmu = vcpu_vpmu(v);
 
-    if ( has_hvm_container_vcpu(v) && is_msr_bitmap_on(vpmu) )
-        amd_vpmu_unset_msr_bitmap(v);
+    if ( has_hvm_container_vcpu(v) )
+    {
+        if ( is_msr_bitmap_on(vpmu) )
+            amd_vpmu_unset_msr_bitmap(v);
 
-    xfree(vpmu->context);
-    vpmu_reset(vpmu, VPMU_CONTEXT_ALLOCATED);
+        if ( is_hvm_vcpu(v) )
+            xfree(vpmu->context);
 
-    if ( vpmu_is_set(vpmu, VPMU_RUNNING) )
-    {
-        vpmu_reset(vpmu, VPMU_RUNNING);
         release_pmu_ownship(PMU_OWNER_HVM);
     }
+
+    vpmu->context = NULL;
+    vpmu_clear(vpmu);
 }
 
 /* VPMU part of the 'q' keyhandler */
@@ -435,15 +437,19 @@ int svm_vpmu_initialise(struct vcpu *v)
     if ( !counters )
         return -EINVAL;
 
-    ctxt = xzalloc_bytes(sizeof(*ctxt) +
-                         2 * sizeof(uint64_t) * num_counters);
-    if ( !ctxt )
+    if ( is_hvm_vcpu(v) )
     {
-        printk(XENLOG_G_WARNING "Insufficient memory for PMU, "
-               " PMU feature is unavailable on domain %d vcpu %d.\n",
-               v->vcpu_id, v->domain->domain_id);
-        return -ENOMEM;
+        ctxt = xzalloc_bytes(sizeof(*ctxt) +
+                             2 * sizeof(uint64_t) * num_counters);
+        if ( !ctxt )
+        {
+            printk(XENLOG_G_WARNING "%pv: Insufficient memory for PMU, "
+                   " PMU feature is unavailable\n", v);
+            return -ENOMEM;
+        }
     }
+    else
+        ctxt = &v->arch.vpmu.xenpmu_data->pmu.c.amd;
 
     ctxt->counters = sizeof(*ctxt);
     ctxt->ctrls = ctxt->counters + sizeof(uint64_t) * num_counters;
@@ -482,6 +488,16 @@ int __init amd_vpmu_init(void)
         return -EINVAL;
     }
 
+    if ( sizeof(struct xen_pmu_data) +
+         2 * sizeof(uint64_t) * num_counters > PAGE_SIZE )
+    {
+        printk(XENLOG_WARNING
+               "VPMU: Register bank does not fit into VPMU shared page\n");
+        counters = ctrls = NULL;
+        num_counters = 0;
+        return -ENOSPC;
+    }
+
     return 0;
 }
 
diff --git a/xen/arch/x86/hvm/vmx/vmx.c b/xen/arch/x86/hvm/vmx/vmx.c
index 2ac1492..d71aa07 100644
--- a/xen/arch/x86/hvm/vmx/vmx.c
+++ b/xen/arch/x86/hvm/vmx/vmx.c
@@ -116,7 +116,9 @@ static int vmx_vcpu_initialise(struct vcpu *v)
         return rc;
     }
 
-    vpmu_initialise(v);
+    /* PVH's VPMU is initialized via hypercall */
+    if ( is_hvm_vcpu(v) )
+        vpmu_initialise(v);
 
     vmx_install_vlapic_mapping(v);
 
diff --git a/xen/arch/x86/hvm/vmx/vpmu_core2.c b/xen/arch/x86/hvm/vmx/vpmu_core2.c
index 1d301a2..cdea510 100644
--- a/xen/arch/x86/hvm/vmx/vpmu_core2.c
+++ b/xen/arch/x86/hvm/vmx/vpmu_core2.c
@@ -362,24 +362,34 @@ static int core2_vpmu_alloc_resource(struct vcpu *v)
     struct xen_pmu_intel_ctxt *core2_vpmu_cxt = NULL;
     uint64_t *p = NULL;
 
-    if ( !acquire_pmu_ownership(PMU_OWNER_HVM) )
-        return 0;
-
-    wrmsrl(MSR_CORE_PERF_GLOBAL_CTRL, 0);
-    if ( vmx_add_host_load_msr(MSR_CORE_PERF_GLOBAL_CTRL) )
+    p = xzalloc(uint64_t);
+    if ( !p )
         goto out_err;
 
-    if ( vmx_add_guest_msr(MSR_CORE_PERF_GLOBAL_CTRL) )
-        goto out_err;
-    vmx_write_guest_msr(MSR_CORE_PERF_GLOBAL_CTRL, 0);
+    if ( has_hvm_container_vcpu(v) )
+    {
+        if ( is_hvm_vcpu(v) && !acquire_pmu_ownership(PMU_OWNER_HVM) )
+            goto out_err;
+
+        wrmsrl(MSR_CORE_PERF_GLOBAL_CTRL, 0);
+        if ( vmx_add_host_load_msr(MSR_CORE_PERF_GLOBAL_CTRL) )
+            goto out_err_hvm;
+        if ( vmx_add_guest_msr(MSR_CORE_PERF_GLOBAL_CTRL) )
+            goto out_err_hvm;
+        vmx_write_guest_msr(MSR_CORE_PERF_GLOBAL_CTRL, 0);
+    }
 
-    core2_vpmu_cxt = xzalloc_bytes(sizeof(*core2_vpmu_cxt) +
-                                   sizeof(uint64_t) * fixed_pmc_cnt +
-                                   sizeof(struct xen_pmu_cntr_pair) *
-                                   arch_pmc_cnt);
-    p = xzalloc(uint64_t);
-    if ( !core2_vpmu_cxt || !p )
-        goto out_err;
+    if ( is_hvm_vcpu(v) )
+    {
+        core2_vpmu_cxt = xzalloc_bytes(sizeof(*core2_vpmu_cxt) +
+                                       sizeof(uint64_t) * fixed_pmc_cnt +
+                                       sizeof(struct xen_pmu_cntr_pair) *
+                                       arch_pmc_cnt);
+        if ( !core2_vpmu_cxt )
+            goto out_err_hvm;
+    }
+    else
+        core2_vpmu_cxt = &v->arch.vpmu.xenpmu_data->pmu.c.intel;
 
     core2_vpmu_cxt->fixed_counters = sizeof(*core2_vpmu_cxt);
     core2_vpmu_cxt->arch_counters = core2_vpmu_cxt->fixed_counters +
@@ -392,10 +402,12 @@ static int core2_vpmu_alloc_resource(struct vcpu *v)
 
     return 1;
 
-out_err:
-    release_pmu_ownship(PMU_OWNER_HVM);
-
+ out_err_hvm:
     xfree(core2_vpmu_cxt);
+    if ( is_hvm_vcpu(v) )
+        release_pmu_ownship(PMU_OWNER_HVM);
+
+ out_err:
     xfree(p);
 
     printk("Failed to allocate VPMU resources for domain %u vcpu %u\n",
@@ -712,12 +724,20 @@ static void core2_vpmu_destroy(struct vcpu *v)
 {
     struct vpmu_struct *vpmu = vcpu_vpmu(v);
 
-    xfree(vpmu->context);
+    if ( has_hvm_container_vcpu(v) )
+    {
+        if ( cpu_has_vmx_msr_bitmap )
+            core2_vpmu_unset_msr_bitmap(v->arch.hvm_vmx.msr_bitmap);
+
+        if ( is_hvm_vcpu(v) )
+            xfree(vpmu->context);
+
+        release_pmu_ownship(PMU_OWNER_HVM);
+    }
+
     xfree(vpmu->priv_context);
-    if ( has_hvm_container_vcpu(v) && cpu_has_vmx_msr_bitmap )
-        core2_vpmu_unset_msr_bitmap(v->arch.hvm_vmx.msr_bitmap);
-    release_pmu_ownship(PMU_OWNER_HVM);
-    vpmu_reset(vpmu, VPMU_CONTEXT_ALLOCATED);
+    vpmu->context = NULL;
+    vpmu_clear(vpmu);
 }
 
 struct arch_vpmu_ops core2_vpmu_ops = {
@@ -827,6 +847,10 @@ int vmx_vpmu_initialise(struct vcpu *v)
     ds_warned = 1;
  func_out:
 
+    /* PV domains can allocate resources immediately */
+    if ( is_pv_vcpu(v) && !core2_vpmu_alloc_resource(v) )
+        return -EIO;
+
     vpmu->arch_vpmu_ops = &core2_vpmu_ops;
 
     return 0;
@@ -897,6 +921,15 @@ int __init core2_vpmu_init(void)
 
     check_pmc_quirk();
 
+    if ( sizeof(struct xen_pmu_data) + sizeof(uint64_t) * fixed_pmc_cnt +
+         sizeof(struct xen_pmu_cntr_pair) * arch_pmc_cnt > PAGE_SIZE )
+    {
+        printk(XENLOG_WARNING
+               "VPMU: Register bank does not fit into VPMU share page\n");
+        arch_pmc_cnt = fixed_pmc_cnt = 0;
+        return -ENOSPC;
+    }
+
     return 0;
 }
 
diff --git a/xen/arch/x86/hvm/vpmu.c b/xen/arch/x86/hvm/vpmu.c
index bb0b2e3..6dd142c 100644
--- a/xen/arch/x86/hvm/vpmu.c
+++ b/xen/arch/x86/hvm/vpmu.c
@@ -27,6 +27,7 @@
 #include <asm/types.h>
 #include <asm/msr.h>
 #include <asm/nmi.h>
+#include <asm/p2m.h>
 #include <asm/hvm/support.h>
 #include <asm/hvm/vmx/vmx.h>
 #include <asm/hvm/vmx/vmcs.h>
@@ -257,22 +258,25 @@ void vpmu_initialise(struct vcpu *v)
     struct vpmu_struct *vpmu = vcpu_vpmu(v);
     uint8_t vendor = current_cpu_data.x86_vendor;
     int ret;
+    bool_t is_priv_vpmu = is_hardware_domain(v->domain);
 
     BUILD_BUG_ON(sizeof(struct xen_pmu_intel_ctxt) > XENPMU_CTXT_PAD_SZ);
     BUILD_BUG_ON(sizeof(struct xen_pmu_amd_ctxt) > XENPMU_CTXT_PAD_SZ);
 
-    if ( is_pvh_vcpu(v) )
-        return;
-
     ASSERT(!vpmu->flags && !vpmu->context);
 
-    /*
-     * Count active VPMUs so that we won't try to change vpmu_mode while
-     * they are in use.
-     */
-    spin_lock(&vpmu_lock);
-    vpmu_count++;
-    spin_unlock(&vpmu_lock);
+    if ( !is_priv_vpmu )
+    {
+        /*
+         * Count active VPMUs so that we won't try to change vpmu_mode while
+         * they are in use.
+         * vpmu_mode can be safely updated while dom0's VPMUs are active and
+         * so we don't need to include it in the count.
+         */
+        spin_lock(&vpmu_lock);
+        vpmu_count++;
+        spin_unlock(&vpmu_lock);
+    }
 
     switch ( vendor )
     {
@@ -299,7 +303,7 @@ void vpmu_initialise(struct vcpu *v)
         printk(XENLOG_G_WARNING "VPMU: Initialization failed for %pv\n", v);
 
     /* Intel needs to initialize VPMU ops even if VPMU is not in use */
-    if ( ret || (vpmu_mode == XENPMU_MODE_OFF) )
+    if ( !is_priv_vpmu && (ret || (vpmu_mode == XENPMU_MODE_OFF)) )
     {
         spin_lock(&vpmu_lock);
         vpmu_count--;
@@ -332,13 +336,104 @@ void vpmu_destroy(struct vcpu *v)
                          vpmu_clear_last, v, 1);
 
     if ( vpmu->arch_vpmu_ops && vpmu->arch_vpmu_ops->arch_vpmu_destroy )
-        vpmu->arch_vpmu_ops->arch_vpmu_destroy(v);
+    {
+        /* Unload VPMU first. This will stop counters */
+        on_selected_cpus(cpumask_of(vcpu_vpmu(v)->last_pcpu),
+                         vpmu_save_force, v, 1);
+         vpmu->arch_vpmu_ops->arch_vpmu_destroy(v);
+    }
 
     spin_lock(&vpmu_lock);
-    vpmu_count--;
+    if ( !is_hardware_domain(v->domain) )
+        vpmu_count--;
     spin_unlock(&vpmu_lock);
 }
 
+static int pvpmu_init(struct domain *d, xen_pmu_params_t *params)
+{
+    struct vcpu *v;
+    struct vpmu_struct *vpmu;
+    struct page_info *page;
+    uint64_t gfn = params->val;
+
+    if ( vpmu_mode == XENPMU_MODE_OFF )
+        return -EINVAL;
+
+    if ( (params->vcpu >= d->max_vcpus) || (d->vcpu[params->vcpu] == NULL) )
+        return -EINVAL;
+
+    page = get_page_from_gfn(d, gfn, NULL, P2M_ALLOC);
+    if ( !page )
+        return -EINVAL;
+
+    if ( !get_page_type(page, PGT_writable_page) )
+    {
+        put_page(page);
+        return -EINVAL;
+    }
+
+    v = d->vcpu[params->vcpu];
+    vpmu = vcpu_vpmu(v);
+
+    spin_lock(&vpmu->vpmu_lock);
+
+    if ( v->arch.vpmu.xenpmu_data )
+    {
+        spin_unlock(&vpmu->vpmu_lock);
+        put_page_and_type(page);
+        return -EEXIST;
+    }
+
+    v->arch.vpmu.xenpmu_data = __map_domain_page_global(page);
+    if ( !v->arch.vpmu.xenpmu_data )
+    {
+        spin_unlock(&vpmu->vpmu_lock);
+        put_page_and_type(page);
+        return -ENOMEM;
+    }
+
+    vpmu_initialise(v);
+
+    spin_unlock(&vpmu->vpmu_lock);
+
+    return 0;
+}
+
+static void pvpmu_finish(struct domain *d, xen_pmu_params_t *params)
+{
+    struct vcpu *v;
+    struct vpmu_struct *vpmu;
+    uint64_t mfn;
+    void *xenpmu_data;
+
+    if ( (params->vcpu >= d->max_vcpus) || (d->vcpu[params->vcpu] == NULL) )
+        return;
+
+    v = d->vcpu[params->vcpu];
+    if ( v != current )
+        vcpu_pause(v);
+
+    vpmu = vcpu_vpmu(v);
+    spin_lock(&vpmu->vpmu_lock);
+
+    vpmu_destroy(v);
+    xenpmu_data = vpmu->xenpmu_data;
+    vpmu->xenpmu_data = NULL;
+
+    spin_unlock(&vpmu->vpmu_lock);
+
+    if ( xenpmu_data )
+    {
+        mfn = domain_page_map_to_mfn(xenpmu_data);
+        ASSERT(mfn != 0);
+        unmap_domain_page_global(xenpmu_data);
+        put_page_and_type(mfn_to_page(mfn));
+    }
+
+    if ( v != current )
+        vcpu_unpause(v);
+}
+
 /* Dump some vpmu informations on console. Used in keyhandler dump_domains(). */
 void vpmu_dump(struct vcpu *v)
 {
@@ -365,6 +460,8 @@ long do_xenpmu_op(unsigned int op, XEN_GUEST_HANDLE_PARAM(xen_pmu_params_t) arg)
     {
     case XENPMU_mode_set:
     case XENPMU_feature_set:
+    case XENPMU_init:
+    case XENPMU_finish:
         if ( copy_from_guest(&pmu_params, arg, 1) )
             return -EFAULT;
 
@@ -444,6 +541,14 @@ long do_xenpmu_op(unsigned int op, XEN_GUEST_HANDLE_PARAM(xen_pmu_params_t) arg)
 
         break;
 
+    case XENPMU_init:
+        ret = pvpmu_init(current->domain, &pmu_params);
+        break;
+
+    case XENPMU_finish:
+        pvpmu_finish(current->domain, &pmu_params);
+        break;
+
     default:
         ret = -EINVAL;
     }
diff --git a/xen/common/event_channel.c b/xen/common/event_channel.c
index fae242d..310f590 100644
--- a/xen/common/event_channel.c
+++ b/xen/common/event_channel.c
@@ -106,6 +106,7 @@ static int virq_is_global(uint32_t virq)
     case VIRQ_TIMER:
     case VIRQ_DEBUG:
     case VIRQ_XENOPROF:
+    case VIRQ_XENPMU:
         rc = 0;
         break;
     case VIRQ_ARCH_0 ... VIRQ_ARCH_7:
diff --git a/xen/include/asm-x86/hvm/vpmu.h b/xen/include/asm-x86/hvm/vpmu.h
index 96f7666..642a4b7 100644
--- a/xen/include/asm-x86/hvm/vpmu.h
+++ b/xen/include/asm-x86/hvm/vpmu.h
@@ -64,6 +64,8 @@ struct vpmu_struct {
     void *context;      /* May be shared with PV guest */
     void *priv_context; /* hypervisor-only */
     struct arch_vpmu_ops *arch_vpmu_ops;
+    struct xen_pmu_data *xenpmu_data;
+    spinlock_t vpmu_lock;
 };
 
 /* VPMU states */
diff --git a/xen/include/public/pmu.h b/xen/include/public/pmu.h
index 87cb325..81210d3 100644
--- a/xen/include/public/pmu.h
+++ b/xen/include/public/pmu.h
@@ -25,6 +25,8 @@
 #define XENPMU_mode_set        1
 #define XENPMU_feature_get     2
 #define XENPMU_feature_set     3
+#define XENPMU_init            4
+#define XENPMU_finish          5
 /* ` } */
 
 /* Parameters structure for HYPERVISOR_xenpmu_op call */
diff --git a/xen/include/public/xen.h b/xen/include/public/xen.h
index 7288ba6..c71529e 100644
--- a/xen/include/public/xen.h
+++ b/xen/include/public/xen.h
@@ -161,6 +161,7 @@ DEFINE_XEN_GUEST_HANDLE(xen_ulong_t);
 #define VIRQ_MEM_EVENT  10 /* G. (DOM0) A memory event has occured           */
 #define VIRQ_XC_RESERVED 11 /* G. Reserved for XenClient                     */
 #define VIRQ_ENOMEM     12 /* G. (DOM0) Low on heap memory       */
+#define VIRQ_XENPMU     13 /* V.  PMC interrupt                              */
 
 /* Architecture-specific VIRQ definitions. */
 #define VIRQ_ARCH_0    16
diff --git a/xen/include/xsm/dummy.h b/xen/include/xsm/dummy.h
index c637454..ae47135 100644
--- a/xen/include/xsm/dummy.h
+++ b/xen/include/xsm/dummy.h
@@ -665,6 +665,9 @@ static XSM_INLINE int xsm_pmu_op (XSM_DEFAULT_ARG struct domain *d, int op)
     case XENPMU_feature_set:
     case XENPMU_feature_get:
         return xsm_default_action(XSM_PRIV, d, current->domain);
+    case XENPMU_init:
+    case XENPMU_finish: 
+        return xsm_default_action(XSM_HOOK, d, current->domain);
     default:
         return -EPERM;
     }
diff --git a/xen/xsm/flask/hooks.c b/xen/xsm/flask/hooks.c
index c0354a5..8e85af3 100644
--- a/xen/xsm/flask/hooks.c
+++ b/xen/xsm/flask/hooks.c
@@ -1515,6 +1515,10 @@ static int flask_pmu_op (struct domain *d, unsigned int op)
     case XENPMU_feature_get:
         return avc_has_perm(dsid, SECINITSID_XEN, SECCLASS_XEN2,
                             XEN2__PMU_CTRL, NULL);
+    case XENPMU_init:
+    case XENPMU_finish:
+        return avc_has_perm(dsid, SECINITSID_XEN, SECCLASS_XEN2,
+                            XEN2__PMU_USE, NULL);
     default:
         return -EPERM;
     }
diff --git a/xen/xsm/flask/policy/access_vectors b/xen/xsm/flask/policy/access_vectors
index 6640acc..ca5e994 100644
--- a/xen/xsm/flask/policy/access_vectors
+++ b/xen/xsm/flask/policy/access_vectors
@@ -88,6 +88,8 @@ class xen2
     get_symbol
 # PMU control
     pmu_ctrl
+# PMU use (domains, including unprivileged ones, will be using this operation)
+    pmu_use
 }
 
 # Classes domain and domain2 consist of operations that a domain performs on
-- 
1.8.1.4

  parent reply	other threads:[~2015-04-09 15:44 UTC|newest]

Thread overview: 20+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-04-09 15:44 [PATCH v20 00/13] x86/PMU: Xen PMU PV(H) support Boris Ostrovsky
2015-04-09 15:44 ` [PATCH v20 01/13] common/symbols: Export hypervisor symbols to privileged guest Boris Ostrovsky
2015-04-09 15:44 ` [PATCH v20 02/13] x86/VPMU: Add public xenpmu.h Boris Ostrovsky
2015-04-20  8:50   ` Jan Beulich
2015-04-20 16:38     ` Boris Ostrovsky
2015-04-21  7:53       ` Jan Beulich
2015-04-21 13:38         ` Boris Ostrovsky
2015-04-21 14:03           ` Jan Beulich
2015-04-09 15:44 ` [PATCH v20 03/13] x86/VPMU: Make vpmu not HVM-specific Boris Ostrovsky
2015-04-09 15:44 ` [PATCH v20 04/13] x86/VPMU: Interface for setting PMU mode and flags Boris Ostrovsky
2015-04-09 15:44 ` [PATCH v20 05/13] x86/VPMU: Initialize VPMUs with __initcall Boris Ostrovsky
2015-04-09 15:44 ` Boris Ostrovsky [this message]
2015-04-20  9:00   ` [PATCH v20 06/13] x86/VPMU: Initialize PMU for PV(H) guests Jan Beulich
2015-04-09 15:44 ` [PATCH v20 07/13] x86/VPMU: Save VPMU state for PV guests during context switch Boris Ostrovsky
2015-04-09 15:44 ` [PATCH v20 08/13] x86/VPMU: When handling MSR accesses, leave fault injection to callers Boris Ostrovsky
2015-04-09 15:44 ` [PATCH v20 09/13] x86/VPMU: Add support for PMU register handling on PV guests Boris Ostrovsky
2015-04-09 15:44 ` [PATCH v20 10/13] x86/VPMU: Handle PMU interrupts for PV(H) guests Boris Ostrovsky
2015-04-09 15:44 ` [PATCH v20 11/13] x86/VPMU: Merge vpmu_rdmsr and vpmu_wrmsr Boris Ostrovsky
2015-04-09 15:44 ` [PATCH v20 12/13] x86/VPMU: Add privileged PMU mode Boris Ostrovsky
2015-04-09 15:44 ` [PATCH v20 13/13] x86/VPMU: Move VPMU files up from hvm/ directory Boris Ostrovsky

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1428594295-2024-7-git-send-email-boris.ostrovsky@oracle.com \
    --to=boris.ostrovsky@oracle.com \
    --cc=Aravind.Gopalakrishnan@amd.com \
    --cc=JBeulich@suse.com \
    --cc=andrew.cooper3@citrix.com \
    --cc=dgdegra@tycho.nsa.gov \
    --cc=dietmar.hahn@ts.fujitsu.com \
    --cc=jun.nakajima@intel.com \
    --cc=kevin.tian@intel.com \
    --cc=suravee.suthikulpanit@amd.com \
    --cc=tim@xen.org \
    --cc=xen-devel@lists.xen.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.