On Thu, May 14, 2020 at 04:30:51PM +0800, Like Xu wrote: > +static inline bool event_is_oncpu(struct perf_event *event) > +{ > + return event && event->oncpu != -1; > +} > +/* > + * It's safe to access LBR msrs from guest when they have not > + * been passthrough since the host would help restore or reset > + * the LBR msrs records when the guest LBR event is scheduled in. > + */ > +static bool intel_pmu_access_lbr_msr(struct kvm_vcpu *vcpu, > + struct msr_data *msr_info, bool read) > +{ > + struct kvm_pmu *pmu = vcpu_to_pmu(vcpu); > + u32 index = msr_info->index; > + > + if (!intel_is_valid_lbr_msr(vcpu, index)) > + return false; > + > + if (!msr_info->host_initiated && !pmu->lbr_event) > + intel_pmu_create_lbr_event(vcpu); > + > + /* > + * Disable irq to ensure the LBR feature doesn't get reclaimed by the > + * host at the time the value is read from the msr, and this avoids the > + * host LBR value to be leaked to the guest. If LBR has been reclaimed, > + * return 0 on guest reads. > + */ > + local_irq_disable(); > + if (event_is_oncpu(pmu->lbr_event)) { > + if (read) > + rdmsrl(index, msr_info->data); > + else > + wrmsrl(index, msr_info->data); > + } else if (read) > + msr_info->data = 0; > + local_irq_enable(); > + > + return true; > +} So this runs in the vCPU thread in host context to emulate the MSR access, right?