From mboxrd@z Thu Jan 1 00:00:00 1970 From: Boris Ostrovsky Subject: Re: [PATCH v18 07/16] x86/VPMU: Initialize PMU for PV(H) guests Date: Fri, 20 Feb 2015 11:55:15 -0500 Message-ID: <54E766F3.2070104@oracle.com> References: <1424125619-10851-1-git-send-email-boris.ostrovsky@oracle.com> <1424125619-10851-8-git-send-email-boris.ostrovsky@oracle.com> <54E754280200007800062148@mail.emea.novell.com> <54E75DB4.3090609@oracle.com> <54E76E7A0200007800062296@mail.emea.novell.com> Mime-Version: 1.0 Content-Type: text/plain; charset="us-ascii"; Format="flowed" Content-Transfer-Encoding: 7bit Return-path: In-Reply-To: <54E76E7A0200007800062296@mail.emea.novell.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: Jan Beulich Cc: kevin.tian@intel.com, suravee.suthikulpanit@amd.com, andrew.cooper3@citrix.com, tim@xen.org, dietmar.hahn@ts.fujitsu.com, xen-devel@lists.xen.org, Aravind.Gopalakrishnan@amd.com, jun.nakajima@intel.com, dgdegra@tycho.nsa.gov List-Id: xen-devel@lists.xenproject.org On 02/20/2015 11:27 AM, Jan Beulich wrote: >>>> On 20.02.15 at 17:15, wrote: >> On 02/20/2015 09:35 AM, Jan Beulich wrote: >>>>>> On 16.02.15 at 23:26, 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_...()? I could but I am not sure how it would allow me to move spin_lock_init() to vpmu_initialize(). We are protecting xenpmu_data and it is supposed to be set before we get into vpmu_initialize(). > >>>> +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. Right, I will move 'if (v->arch.vpmu.xenpmu_data )' under the lock (and clean up if it is non-NULL) -boris