[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [PATCH v2] x86/vpmu: Fix race-condition in vpmu_load
On 29.09.2022 16:28, Tamas K Lengyel wrote: > On Thu, Sep 29, 2022 at 9:07 AM Jan Beulich <jbeulich@xxxxxxxx> wrote: > >> On 26.09.2022 16:22, Tamas K Lengyel wrote: >>> On Mon, Sep 26, 2022 at 10:12 AM Jan Beulich <jbeulich@xxxxxxxx> wrote: >>>> On 22.09.2022 22:48, Tamas K Lengyel wrote: >>>>> --- a/xen/arch/x86/cpu/vpmu.c >>>>> +++ b/xen/arch/x86/cpu/vpmu.c >>>>> @@ -376,57 +376,24 @@ void vpmu_save(struct vcpu *v) >>>>> vpmu->last_pcpu = pcpu; >>>>> per_cpu(last_vcpu, pcpu) = v; >>>>> >>>>> + vpmu_set(vpmu, VPMU_CONTEXT_SAVE); >>>>> + >>>>> if ( alternative_call(vpmu_ops.arch_vpmu_save, v, 0) ) >>>>> vpmu_reset(vpmu, VPMU_CONTEXT_LOADED); >>>>> >>>>> + vpmu_reset(vpmu, VPMU_CONTEXT_SAVE); >>>>> + >>>>> apic_write(APIC_LVTPC, PMU_APIC_VECTOR | APIC_LVT_MASKED); >>>>> } >>>>> >>>>> int vpmu_load(struct vcpu *v, bool_t from_guest) >>>>> { >>>>> struct vpmu_struct *vpmu = vcpu_vpmu(v); >>>>> - int pcpu = smp_processor_id(), ret; >>>>> - struct vcpu *prev = NULL; >>>>> + int ret; >>>>> >>>>> if ( !vpmu_is_set(vpmu, VPMU_CONTEXT_ALLOCATED) ) >>>>> return 0; >>>>> >>>>> - /* First time this VCPU is running here */ >>>>> - if ( vpmu->last_pcpu != pcpu ) >>>>> - { >>>>> - /* >>>>> - * Get the context from last pcpu that we ran on. Note that if >>>> another >>>>> - * VCPU is running there it must have saved this VPCU's >> context >>>> before >>>>> - * startig to run (see below). >>>>> - * There should be no race since remote pcpu will disable >>>> interrupts >>>>> - * before saving the context. >>>>> - */ >>>>> - if ( vpmu_is_set(vpmu, VPMU_CONTEXT_LOADED) ) >>>>> - { >>>>> - on_selected_cpus(cpumask_of(vpmu->last_pcpu), >>>>> - vpmu_save_force, (void *)v, 1); >>>>> - vpmu_reset(vpmu, VPMU_CONTEXT_LOADED); >>>>> - } >>>>> - } >>>>> - >>>>> - /* Prevent forced context save from remote CPU */ >>>>> - local_irq_disable(); >>>>> - >>>>> - prev = per_cpu(last_vcpu, pcpu); >>>>> - >>>>> - if ( prev != v && prev ) >>>>> - { >>>>> - vpmu = vcpu_vpmu(prev); >>>>> - >>>>> - /* Someone ran here before us */ >>>>> - vpmu_save_force(prev); >>>>> - vpmu_reset(vpmu, VPMU_CONTEXT_LOADED); >>>>> - >>>>> - vpmu = vcpu_vpmu(v); >>>>> - } >>>>> - >>>>> - local_irq_enable(); >>>>> - >>>>> /* Only when PMU is counting, we load PMU context immediately. */ >>>>> if ( !vpmu_is_set(vpmu, VPMU_RUNNING) || >>>>> (!has_vlapic(vpmu_vcpu(vpmu)->domain) && >>>> >>>> What about the other two uses of vpmu_save_force() in this file? I looks >>>> to me as if only the use in mem_sharing.c needs to be retained. >>> >>> I don't know, maybe. I rather focus this patch only on the issue and its >>> fix as I don't want to introduce unintended side effects by doing a >>> cleanup/consolidation at other code-paths when not strictly necessary. >> >> While I see your point, I'm afraid I don't think I can ack this >> change without knowing whether the other uses don't expose a similar >> issue. It would feel wrong to fix only one half of a problem. I may, >> somewhat hesitantly, give an ack if e.g. Boris offered his R-b. >> Else the only other option I see is that some other maintainer give >> their ack. >> > > I may have misunderstood what you are asking. I thought you were asking if > the other two remaining users of vpmu_save_force could be switched over to > vpmu_save as a generic cleanup, to which my answer is still maybe. From the > perspective of this particular bug those use-cases are safe. On is acting > on the current vcpu and doesn't try to run vpmu_save_force on a remote > vcpu, the other one is being called when the domain is being shut down so > the vcpu cannot be in a runnable state. Hmm, yes - I can accept that. Thanks for the clarification. Acked-by: Jan Beulich <jbeulich@xxxxxxxx> Jan
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |