|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [PATCH] xen/mem_sharing: support forks with active vPMU state
On 19/07/2022 18:18, Tamas K Lengyel wrote:
> diff --git a/xen/arch/x86/cpu/vpmu.c b/xen/arch/x86/cpu/vpmu.c
> index d2c03a1104..2b5d64a60d 100644
> --- a/xen/arch/x86/cpu/vpmu.c
> +++ b/xen/arch/x86/cpu/vpmu.c
> @@ -529,6 +529,16 @@ void vpmu_initialise(struct vcpu *v)
> put_vpmu(v);
> }
>
> +void vpmu_allocate_context(struct vcpu *v)
> +{
> + struct vpmu_struct *vpmu = vcpu_vpmu(v);
> +
> + if ( vpmu_is_set(vpmu, VPMU_CONTEXT_ALLOCATED) )
> + return;
> +
> + alternative_call(vpmu_ops.allocate_context, v);
You need to fill in an AMD pointer, or make this conditional.
All alternatives have NULL pointers turned into UDs.
Should be a two-liner on the AMD side.
> diff --git a/xen/arch/x86/cpu/vpmu_intel.c b/xen/arch/x86/cpu/vpmu_intel.c
> index 8612f46973..31dc0ee14b 100644
> --- a/xen/arch/x86/cpu/vpmu_intel.c
> +++ b/xen/arch/x86/cpu/vpmu_intel.c
> static int core2_vpmu_verify(struct vcpu *v)
> @@ -474,7 +485,11 @@ static int core2_vpmu_alloc_resource(struct vcpu *v)
> sizeof(uint64_t) * fixed_pmc_cnt;
>
> vpmu->context = core2_vpmu_cxt;
> + vpmu->context_size = sizeof(struct xen_pmu_intel_ctxt) +
> + fixed_pmc_cnt * sizeof(uint64_t) +
> + arch_pmc_cnt * sizeof(struct xen_pmu_cntr_pair);
This wants deduplicating with the earlier calculation, surely?
> vpmu->priv_context = p;
> + vpmu->priv_context_size = sizeof(uint64_t);
>
> if ( !has_vlapic(v->domain) )
> {
> @@ -882,6 +897,7 @@ static int cf_check vmx_vpmu_initialise(struct vcpu *v)
>
> static const struct arch_vpmu_ops __initconst_cf_clobber core2_vpmu_ops = {
> .initialise = vmx_vpmu_initialise,
> + .allocate_context = core2_vpmu_alloc_resource,
core2_vpmu_alloc_resource() needs to gain a cf_check to not explode on
TGL/SPR.
> .do_wrmsr = core2_vpmu_do_wrmsr,
> .do_rdmsr = core2_vpmu_do_rdmsr,
> .do_interrupt = core2_vpmu_do_interrupt,
> diff --git a/xen/arch/x86/include/asm/vpmu.h b/xen/arch/x86/include/asm/vpmu.h
> index e5709bd44a..14d0939247 100644
> --- a/xen/arch/x86/include/asm/vpmu.h
> +++ b/xen/arch/x86/include/asm/vpmu.h
> @@ -106,8 +109,10 @@ void vpmu_lvtpc_update(uint32_t val);
> int vpmu_do_msr(unsigned int msr, uint64_t *msr_content, bool is_write);
> void vpmu_do_interrupt(struct cpu_user_regs *regs);
> void vpmu_initialise(struct vcpu *v);
> +void vpmu_allocate_context(struct vcpu *v);
> void vpmu_destroy(struct vcpu *v);
> void vpmu_save(struct vcpu *v);
> +void vpmu_save_force(void *arg);
Needs the cf_check to compile.
> int vpmu_load(struct vcpu *v, bool_t from_guest);
> void vpmu_dump(struct vcpu *v);
>
> diff --git a/xen/arch/x86/mm/mem_sharing.c b/xen/arch/x86/mm/mem_sharing.c
> index 8f9d9ed9a9..39cd03abf7 100644
> --- a/xen/arch/x86/mm/mem_sharing.c
> +++ b/xen/arch/x86/mm/mem_sharing.c
> @@ -1653,6 +1653,50 @@ static void copy_vcpu_nonreg_state(struct vcpu
> *d_vcpu, struct vcpu *cd_vcpu)
> hvm_set_nonreg_state(cd_vcpu, &nrs);
> }
>
> +static int copy_vpmu(struct vcpu *d_vcpu, struct vcpu *cd_vcpu)
> +{
> + struct vpmu_struct *d_vpmu = vcpu_vpmu(d_vcpu);
> + struct vpmu_struct *cd_vpmu = vcpu_vpmu(cd_vcpu);
> +
> + if ( !vpmu_are_all_set(d_vpmu, VPMU_INITIALIZED |
> VPMU_CONTEXT_ALLOCATED) )
> + return 0;
> + if ( !vpmu_is_set(cd_vpmu, VPMU_CONTEXT_ALLOCATED) )
> + {
> + vpmu_allocate_context(cd_vcpu);
> + if ( !vpmu_is_set(cd_vpmu, VPMU_CONTEXT_ALLOCATED) )
> + return -ENOMEM;
vpmu_allocate_context() already checks VPMU_CONTEXT_ALLOCATED. But
isn't the double check here redundant?
The subsequent check looks like you want to pass the hook's return value
up through vpmu_allocate_context().
(And if you feel like turning it from bool-as-int to something more
sane, say -errno, that would also be great.)
Otherwise, looks plausible.
~Andrew
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |