From mboxrd@z Thu Jan 1 00:00:00 1970 From: "Jan Beulich" Subject: Re: [PATCH v10 15/20] x86/VPMU: Handle PMU interrupts for PV guests Date: Wed, 10 Sep 2014 16:30:26 +0100 Message-ID: <54108AB202000078000336A5@mail.emea.novell.com> References: <1409802080-6160-1-git-send-email-boris.ostrovsky@oracle.com> <1409802080-6160-16-git-send-email-boris.ostrovsky@oracle.com> Mime-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Return-path: In-Reply-To: <1409802080-6160-16-git-send-email-boris.ostrovsky@oracle.com> Content-Disposition: inline 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: tim@xen.org, kevin.tian@intel.com, keir@xen.org, suravee.suthikulpanit@amd.com, andrew.cooper3@citrix.com, eddie.dong@intel.com, xen-devel@lists.xen.org, Aravind.Gopalakrishnan@amd.com, jun.nakajima@intel.com List-Id: xen-devel@lists.xenproject.org >>> On 04.09.14 at 05:41, wrote: > int vpmu_do_interrupt(struct cpu_user_regs *regs) > { > - struct vcpu *v = current; > - struct vpmu_struct *vpmu = vcpu_vpmu(v); > + struct vcpu *sampled = current, *sampling; > + struct vpmu_struct *vpmu; > + > + /* dom0 will handle interrupt for special domains (e.g. idle domain) */ > + if ( sampled->domain->domain_id >= DOMID_FIRST_RESERVED ) > + { > + sampling = choose_hwdom_vcpu(); > + if ( !sampling ) > + return 0; > + } > + else > + sampling = sampled; > + > + vpmu = vcpu_vpmu(sampling); > + if ( !is_hvm_domain(sampling->domain) ) > + { > + /* PV(H) guest or dom0 is doing system profiling */ > + const struct cpu_user_regs *gregs; > + > + if ( !vpmu->xenpmu_data ) > + return 0; > + > + if ( vpmu->xenpmu_data->pmu_flags & PMU_CACHED ) > + return 1; > + > + if ( is_pvh_domain(sampled->domain) && > + !vpmu->arch_vpmu_ops->do_interrupt(regs) ) > + return 0; > + > + /* PV guest will be reading PMU MSRs from xenpmu_data */ > + vpmu_set(vpmu, VPMU_CONTEXT_SAVE | VPMU_CONTEXT_LOADED); > + vpmu->arch_vpmu_ops->arch_vpmu_save(sampling); > + vpmu_reset(vpmu, VPMU_CONTEXT_SAVE | VPMU_CONTEXT_LOADED); > + > + /* Store appropriate registers in xenpmu_data */ > + if ( is_pv_32bit_domain(sampled->domain) ) > + { > + /* > + * 32-bit dom0 cannot process Xen's addresses (which are 64 bit) > + * and therefore we treat it the same way as a non-priviledged > + * PV 32-bit domain. > + */ > + struct compat_cpu_user_regs *cmp; > + > + gregs = guest_cpu_user_regs(); > + > + cmp = (void *)&vpmu->xenpmu_data->pmu.r.regs; > + XLAT_cpu_user_regs(cmp, gregs); > + } > + else if ( !is_hardware_domain(sampled->domain) && > + !is_idle_vcpu(sampled) ) > + { > + /* PV(H) guest */ > + gregs = guest_cpu_user_regs(); > + vpmu->xenpmu_data->pmu.r.regs = *gregs; > + } > + else > + vpmu->xenpmu_data->pmu.r.regs = *regs; > + > + vpmu->xenpmu_data->domain_id = sampled->domain->domain_id; > + vpmu->xenpmu_data->vcpu_id = sampled->vcpu_id; > + vpmu->xenpmu_data->pcpu_id = smp_processor_id(); > + > + vpmu->xenpmu_data->pmu_flags |= PMU_CACHED; > + apic_write(APIC_LVTPC, vpmu->hw_lapic_lvtpc | APIC_LVT_MASKED); > + vpmu->hw_lapic_lvtpc |= APIC_LVT_MASKED; Would it be wrong to do the |= first and thus avoiding to do the same operation twice? > @@ -230,7 +353,9 @@ void vpmu_load(struct vcpu *v) > local_irq_enable(); > > /* Only when PMU is counting, we load PMU context immediately. */ > - if ( !vpmu_is_set(vpmu, VPMU_RUNNING) ) > + if ( !vpmu_is_set(vpmu, VPMU_RUNNING) || > + (!is_hvm_domain(v->domain) && > + vpmu->xenpmu_data->pmu_flags & PMU_CACHED) ) Please parenthesize & within &&. Jan