[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH v17 13/23] x86/VPMU: Interface for setting PMU mode and flags
>>> On 05.01.15 at 22:44, <boris.ostrovsky@xxxxxxxxxx> wrote: > +static long vpmu_unload_next(void *arg) > +{ > + struct vcpu *last; > + int ret; > + unsigned int thiscpu = smp_processor_id(); > + > + if ( thiscpu != vpmu_next_unload_cpu ) > + { > + /* Continuation thread may have been moved due to CPU hot-unplug */ > + vpmu_mode = (unsigned long)arg; > + vpmu_first_unload_cpu = VPMU_INVALID_CPU; > + return -EAGAIN; > + } > + > + local_irq_disable(); /* so that last_vcpu doesn't change under us. */ > + > + last = this_cpu(last_vcpu); > + if ( last ) > + { > + vpmu_unload(vcpu_vpmu(last)); > + this_cpu(last_vcpu) = NULL; > + } So you do this for last_vcpu here, but ... > +static int vpmu_unload_all(unsigned long old_mode) > +{ > + int ret = 0; > + > + vpmu_unload(vcpu_vpmu(current)); ... for current here, also without clearing this_cpu(last_vcpu). Is that really correct? > +long do_xenpmu_op(int op, XEN_GUEST_HANDLE_PARAM(xen_pmu_params_t) arg) > +{ > + int ret; > + struct xen_pmu_params pmu_params; > + > + ret = xsm_pmu_op(XSM_OTHER, current->domain, op); > + if ( ret ) > + return ret; > + > + switch ( op ) > + { > + case XENPMU_mode_set: > + { > + unsigned int old_mode; > + static DEFINE_SPINLOCK(xenpmu_mode_lock); > + > + if ( copy_from_guest(&pmu_params, arg, 1) ) > + return -EFAULT; > + > + if ( pmu_params.val & ~(XENPMU_MODE_SELF | XENPMU_MODE_HV) ) > + return -EINVAL; > + > + /* 32-bit dom0 can only sample itself. */ > + if ( is_pv_32bit_vcpu(current) && (pmu_params.val & XENPMU_MODE_HV) ) > + return -EINVAL; > + > + /* > + * Return error if someone else is in the middle of changing mode --- > + * this is most likely indication of two system administrators > + * working against each other. > + */ > + if ( !spin_trylock(&xenpmu_mode_lock) ) > + return -EAGAIN; > + if ( vpmu_first_unload_cpu != VPMU_INVALID_CPU ) > + { > + spin_unlock(&xenpmu_mode_lock); > + return -EAGAIN; > + } > + > + old_mode = vpmu_mode; > + vpmu_mode = pmu_params.val; > + > + if ( vpmu_mode == XENPMU_MODE_OFF ) > + { > + /* Make sure all (non-dom0) VCPUs have unloaded their VPMUs. */ > + ret = vpmu_unload_all(old_mode); > + if ( ret ) > + vpmu_mode = old_mode; > + } > + > + spin_unlock(&xenpmu_mode_lock); > + > + break; > + } > + > + case XENPMU_mode_get: > + memset(&pmu_params, 0, sizeof(pmu_params)); > + pmu_params.val = vpmu_mode; > + > + pmu_params.version.maj = XENPMU_VER_MAJ; > + pmu_params.version.min = XENPMU_VER_MIN; > + > + if ( copy_to_guest(arg, &pmu_params, 1) ) > + return -EFAULT; > + break; > + > + case XENPMU_feature_set: > + if ( copy_from_guest(&pmu_params, arg, 1) ) > + return -EFAULT; > + > + if ( pmu_params.val & ~XENPMU_FEATURE_INTEL_BTS ) > + return -EINVAL; > + > + vpmu_features = pmu_params.val; > + break; > + > + case XENPMU_feature_get: > + pmu_params.val = vpmu_features; > + if ( copy_field_to_guest(arg, &pmu_params, val) ) > + return -EFAULT; > + break; > + > + default: > + ret = -EINVAL; > + } > + > + return ret; > +} Throughout this function, the "pad" field isn't being checked to be zero (and XENPMU_feature_get also doesn't clear it, but that seems secondary, at least as long as it's being declared "IN" only). As I'm sure I said before - we ought to do this in order to be able to assign meaning to the field later on. Perhaps it would even better be renamed to e.g. "mbz". > @@ -144,6 +145,9 @@ do_tmem_op( > extern long > do_xenoprof_op(int op, XEN_GUEST_HANDLE_PARAM(void) arg); > > +extern long > +do_xenpmu_op(int op, XEN_GUEST_HANDLE_PARAM(xen_pmu_params_t) arg); Despite there being numerous bad examples - can "op" please be "unsigned int"? > --- a/xen/include/xsm/xsm.h > +++ b/xen/include/xsm/xsm.h > @@ -173,6 +173,7 @@ struct xsm_operations { > int (*unbind_pt_irq) (struct domain *d, struct xen_domctl_bind_pt_irq > *bind); > int (*ioport_permission) (struct domain *d, uint32_t s, uint32_t e, > uint8_t allow); > int (*ioport_mapping) (struct domain *d, uint32_t s, uint32_t e, uint8_t > allow); > + int (*pmu_op) (struct domain *d, int op); And then here too? Jan _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |