[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Xen-devel] [PATCH v18 07/16] x86/VPMU: Initialize PMU for PV(H) guests



>>> On 20.02.15 at 17:15, <boris.ostrovsky@xxxxxxxxxx> wrote:

> On 02/20/2015 09:35 AM, Jan Beulich wrote:
>>>>> On 16.02.15 at 23:26, <boris.ostrovsky@xxxxxxxxxx> wrote:
>>> --- a/xen/arch/x86/domain.c
>>> +++ b/xen/arch/x86/domain.c
>>> @@ -437,6 +437,8 @@ int vcpu_initialise(struct vcpu *v)
>>>           vmce_init_vcpu(v);
>>>       }
>>>   
>>> +    spin_lock_init(&v->arch.vpmu.vpmu_lock);
>> This would rather seem to belong into vpmu_initialize().
> 
> vpmu_initialize() is called under this lock so we can't do this.

Yes, I saw that later on, but it still doesn't look well structured. Can't
you bail early from vpmu_initialize() the first time through for PV(H)
guests, rather than guarding the HVM invocations with is_hvm_...()?

>>> +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 == NULL) ||
>>> +         (d->vcpu[params->vcpu] == NULL) )
>>> +        return -EINVAL;
>>> +
>>> +    if ( v->arch.vpmu.xenpmu_data )
>>> +        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);
>>> +
>>> +    v->arch.vpmu.xenpmu_data = __map_domain_page_global(page);
>>> +    if ( !v->arch.vpmu.xenpmu_data )
>>> +    {
>>> +        put_page_and_type(page);
>>> +        spin_unlock(&vpmu->vpmu_lock);
>>> +        return -EINVAL;
>>> +    }
>>> +
>>> +    vpmu_initialise(v);
>>> +
>>> +    spin_unlock(&vpmu->vpmu_lock);
>> So what is this lock guarding against here? Certainly not overwriting
>> of a non-NULL v->arch.vpmu.xenpmu_data (and hence leaking a
>> page reference)...
> 
> This is trying to protect a race with pvmu_finish() that could clear 
> xenpmu_data.
> 
> (I actually think you were the one who suggested it).

But it should also protect against a second pvpmu_init() on another
pCPU.

Jan


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.