[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Xen-devel] [PATCH v2 08/10] x86: Introduce a function to check the value of RTIT_CTL



>>> On 30.05.18 at 15:28, <luwei.kang@xxxxxxxxx> wrote:
> Any attempt to modify IA32_RTIT_CTL while TraceEn is set will
> result in a #GP unless the same write also clears TraceEn.
> Writes to IA32_RTIT_CTL that do not modify any bits will not
> cause a #GP, even if TraceEn remains set.
> MSR write that attempts to change bits marked reserved, or
> utilize encodings marked reserved, will cause a #GP fault.

May I ask that you also add a similar code comment, perhaps ahead
of the function definition?

> --- a/xen/arch/x86/cpu/ipt.c
> +++ b/xen/arch/x86/cpu/ipt.c
> @@ -114,6 +114,114 @@ static int __init parse_ipt_params(const char *str)
>      return 0;
>  }
>  
> +static int rtit_ctl_check(uint64_t new, uint64_t old)

It looks as if again you mean the function to return boolean, so please
have it have bool return type.

> +{
> +    const struct cpuid_policy *p = current->domain->arch.cpuid;
> +    const struct ipt_desc *ipt_desc = current->arch.hvm_vmx.ipt_desc;
> +    uint64_t rtit_ctl_mask = ~((uint64_t)0);

Too many parentheses.

> +    unsigned int addr_range = ipt_cap(p->ipt.raw, IPT_CAP_addr_range);
> +    unsigned int val, i;
> +
> +    if  ( new == old )
> +        return 0;
> +
> +    /* Clear no dependency bits */
> +    rtit_ctl_mask = ~(RTIT_CTL_TRACEEN | RTIT_CTL_OS |
> +                RTIT_CTL_USR | RTIT_CTL_TSC_EN | RTIT_CTL_DIS_RETC);
> +
> +    /* If CPUID.(EAX=14H,ECX=0):EBX[0]=1 CR3Filter can be set */
> +    if ( ipt_cap(p->ipt.raw, IPT_CAP_cr3_filter) )
> +        rtit_ctl_mask &= ~RTIT_CTL_CR3_FILTER;
> +
> +    /*
> +     * If CPUID.(EAX=14H,ECX=0):EBX[1]=1 CYCEn, CycThresh and
> +     * PSBFreq can be set
> +     */
> +    if ( ipt_cap(p->ipt.raw, IPT_CAP_psb_cyc) )
> +        rtit_ctl_mask &= ~(RTIT_CTL_CYCEN |
> +                RTIT_CTL_CYC_THRESH | RTIT_CTL_PSB_FREQ);
> +    /*
> +     * If CPUID.(EAX=14H,ECX=0):EBX[3]=1 MTCEn BranchEn and
> +     * MTCFreq can be set
> +     */
> +    if ( ipt_cap(p->ipt.raw, IPT_CAP_mtc) )
> +        rtit_ctl_mask &= ~(RTIT_CTL_MTC_EN |
> +                RTIT_CTL_BRANCH_EN | RTIT_CTL_MTC_FREQ);
> +
> +    /* If CPUID.(EAX=14H,ECX=0):EBX[4]=1 FUPonPTW and PTWEn can be set */
> +    if ( ipt_cap(p->ipt.raw, IPT_CAP_ptwrite) )
> +        rtit_ctl_mask &= ~(RTIT_CTL_FUP_ON_PTW |
> +                                        RTIT_CTL_PTW_EN);
> +
> +    /* If CPUID.(EAX=14H,ECX=0):EBX[5]=1 PwrEvEn can be set */
> +    if ( ipt_cap(p->ipt.raw, IPT_CAP_power_event) )
> +        rtit_ctl_mask &= ~RTIT_CTL_PWR_EVT_EN;
> +
> +    /* If CPUID.(EAX=14H,ECX=0):ECX[0]=1 ToPA can be set */
> +    if ( ipt_cap(p->ipt.raw, IPT_CAP_topa_output) )
> +        rtit_ctl_mask &= ~RTIT_CTL_TOPA;
> +    /* If CPUID.(EAX=14H,ECX=0):ECX[3]=1 FabircEn can be set */
> +    if ( ipt_cap(p->ipt.raw, IPT_CAP_output_subsys))
> +        rtit_ctl_mask &= ~RTIT_CTL_FABRIC_EN;
> +    /* unmask address range configure area */
> +    for (i = 0; i < addr_range; i++)

Style.

> +        rtit_ctl_mask &= ~(0xf << (32 + i * 4));
> +
> +    /*
> +     * Any MSR write that attempts to change bits marked reserved will
> +     * case a #GP fault.

cause

> +     */
> +    if ( new & rtit_ctl_mask )
> +        return 1;
> +
> +    /*
> +     * Any attempt to modify IA32_RTIT_CTL while TraceEn is set will
> +     * result in a #GP unless the same write also clears TraceEn.
> +     */
> +    if ( (ipt_desc->ipt_guest.ctl & RTIT_CTL_TRACEEN) &&
> +        ((ipt_desc->ipt_guest.ctl ^ new) & ~RTIT_CTL_TRACEEN) )

Why the ^ ? You only need to check whether new has the bit clear.
Also please use "old" wherever possible, if you already have it passed
into the function. This way it'll become obvious that the "nothing
changed" case is already handled by the very first if().

> +        return 1;
> +
> +    /*
> +     * WRMSR to IA32_RTIT_CTL that sets TraceEn but clears this bit
> +     * and FabricEn would cause #GP, if
> +     * CPUID.(EAX=14H, ECX=0):ECX.SNGLRGNOUT[bit 2] = 0
> +     */
> +   if ( (new & RTIT_CTL_TRACEEN) && !(new & RTIT_CTL_TOPA) &&
> +        !(new & RTIT_CTL_FABRIC_EN) &&
> +        !ipt_cap(p->ipt.raw, IPT_CAP_single_range_output) )
> +        return 1;
> +    /*
> +     * MTCFreq, CycThresh and PSBFreq encodings check, any MSR write that
> +     * utilize encodings marked reserved will casue a #GP fault.
> +     */
> +    val = ipt_cap(p->ipt.raw, IPT_CAP_mtc_period);
> +    if ( ipt_cap(p->ipt.raw, IPT_CAP_mtc) &&
> +                !test_bit((new & RTIT_CTL_MTC_FREQ) >>
> +                RTIT_CTL_MTC_FREQ_OFFSET, &val) )

Indentation.

> @@ -171,6 +279,8 @@ int ipt_do_wrmsr(unsigned int msr, uint64_t msr_content)
>      switch ( msr )
>      {
>      case MSR_IA32_RTIT_CTL:
> +        if ( rtit_ctl_check(msr_content, ipt_desc->ipt_guest.ctl) )
> +            return 1;
>          ipt_desc->ipt_guest.ctl = msr_content;
>          __vmwrite(GUEST_IA32_RTIT_CTL, msr_content);
>          break;

Without this I don't see how the previous patch is complete.

Jan


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/xen-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.