|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH v3 12/16] x86/VPMU: Handle PMU interrupts for PV guests
> @@ -82,7 +87,23 @@ int vpmu_do_wrmsr(unsigned int msr, uint64_t msr_content)
> struct vpmu_struct *vpmu = vcpu_vpmu(current);
>
> if ( vpmu->arch_vpmu_ops && vpmu->arch_vpmu_ops->do_wrmsr )
> - return vpmu->arch_vpmu_ops->do_wrmsr(msr, msr_content);
> + {
> + int val = vpmu->arch_vpmu_ops->do_wrmsr(msr, msr_content);
"val" is a misleading name here.
> +
> + /*
> + * We may have received a PMU interrupt during WRMSR handling
> + * and since do_wrmsr may load VPMU context we should save
> + * (and unload) it again.
> + */
> + if ( !is_hvm_domain(current->domain) &&
> + current->arch.vpmu.xenpmu_data->pmu_flags & PMU_CACHED )
I'd suggest parenthesizing the operands of &.
> + {
> + vpmu_set(vpmu, VPMU_CONTEXT_SAVE);
> + (void)vpmu->arch_vpmu_ops->arch_vpmu_save(current);
What's this cast good for?
> + vpmu_reset(vpmu, VPMU_CONTEXT_SAVE | VPMU_CONTEXT_LOADED);
> + }
> + return val;
> + }
> return 0;
> }
>
> @@ -91,16 +112,87 @@ int vpmu_do_rdmsr(unsigned int msr, uint64_t
> *msr_content)
> struct vpmu_struct *vpmu = vcpu_vpmu(current);
>
> if ( vpmu->arch_vpmu_ops && vpmu->arch_vpmu_ops->do_rdmsr )
> - return vpmu->arch_vpmu_ops->do_rdmsr(msr, msr_content);
> + {
> + int val = vpmu->arch_vpmu_ops->do_rdmsr(msr, msr_content);
> +
> + if ( !is_hvm_domain(current->domain) &&
> + current->arch.vpmu.xenpmu_data->pmu_flags)
Coding style (here and elsewhere).
> + /* dom0 will handle this interrupt */
> + if ( v->domain->domain_id >= DOMID_FIRST_RESERVED )
> + {
> + if ( smp_processor_id() >= dom0->max_vcpus )
> + return 0;
> + v = dom0->vcpu[smp_processor_id()];
> + }
Ugly new uses of "dom0". And the correlation between
smp_processor_id() and dom0->max_vcpus doesn't look sane
either.
> +
> + vpmu = vcpu_vpmu(v);
> + if ( !is_hvm_domain(v->domain) )
> + {
> + /* PV guest or dom0 is doing system profiling */
> + void *p;
> + struct cpu_user_regs *gregs;
const.
> + int err;
> +
> + if (v->arch.vpmu.xenpmu_data->pmu_flags & PMU_CACHED)
> + return 1;
> +
> + /* PV guest will be reading PMU MSRs from xenpmu_data */
> + vpmu_set(vpmu, VPMU_CONTEXT_SAVE | VPMU_CONTEXT_LOADED);
> + err = vpmu->arch_vpmu_ops->arch_vpmu_save(v);
> + vpmu_reset(vpmu, VPMU_CONTEXT_SAVE | VPMU_CONTEXT_LOADED);
> +
> + /* Store appropriate registers in xenpmu_data */
> + p = &v->arch.vpmu.xenpmu_data->pmu.regs;
This and the code below should be done in a type safe manner if
at all possible. I.e. p should not be void *, but a union of pointers
or a pointer to a union.
> + if ( is_pv_32bit_domain(current->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();
> + XLAT_cpu_user_regs(&cmp, gregs);
> + memcpy(p, &cmp, sizeof(struct compat_cpu_user_regs));
And then there would be no point in using an intermediate variable
here.
> + }
> + else if ( (current->domain != dom0) && !is_idle_vcpu(current) )
Did you perhaps mean !is_control_domain() or
!is_hardware_domain()?
Jan
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |