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

Re: [PATCH] libx86: Introduce x86_cpu_policy_calculate_compatible() with MSR_ARCH_CAPS handling


  • To: Roger Pau Monné <roger.pau@xxxxxxxxxx>
  • From: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
  • Date: Wed, 5 May 2021 15:29:26 +0100
  • Arc-authentication-results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=citrix.com; dmarc=pass action=none header.from=citrix.com; dkim=pass header.d=citrix.com; arc=none
  • Arc-message-signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=r2mwY0Dq6XSJzaHvRvMrUpwEzdVWGP1uhjH1InxBqHQ=; b=ocMTrzanRj8KbG4/20IeTf8Sxhg+/DcAXdGqratTMvCoKyv8Vnk6ePuJqWJ0QnrxLkqO+NoMY3y60fsTXaCk2gJCQ1rnDYNA6MNSRzCf2ezbBuv4SjghekXP5U4xCNUvdqd4jiutnx1bZvbYF742df2GJ5xmrLU5IEzhgcQJ97dHuXCPuSuGOykRLA+vk6Sw3naaseC1OlR8pV7C2NRkLPq7wYimFv6wOECIX+efe8jbvycTzpLyZ7IY59G8waBGXlyoo6DTnTpjIIebyenl/z2SOTXJtLP6uzH73wAPINO9R29G7HgnR0xmMVyuweWTjyQ9Hii0Td6+Go1Y5Bsmmg==
  • Arc-seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=A0gnPzerL+8JDgnQQcIFV8e7yGC5Fvb+KGUmjTERKWGC1rqitXY7FxHbVHOV9Q7RI6jn8vH1y8e81K+U2cbXUI/fwxIx/xgtZlX6ewErJQc6JaaHVmje86kCxbYrKW/4eu9/RqeLZ8KY2yFZER1WXYNKmlwWV41qlOJeg3z16kj6V0txykGzO7SWkrRJnoMKPcvE3xj3u7H+ymMUMH2jg9rwo93y+kQA3ZEk3c63Zb+mukwAL29X0SgpgcFHSQR8fEB9t+2h+a1ENnJ+H9XNkP1dGTR0kAqKuJZFageURWzg6XbvvENzWtO6WtFKx+Wm1h7RHgYKGzC5K/IGMc7BKw==
  • Authentication-results: esa1.hc3370-68.iphmx.com; dkim=pass (signature verified) header.i=@citrix.onmicrosoft.com
  • Cc: Xen-devel <xen-devel@xxxxxxxxxxxxxxxxxxxx>, Jan Beulich <JBeulich@xxxxxxxx>, Wei Liu <wl@xxxxxxx>
  • Delivery-date: Wed, 05 May 2021 14:29:43 +0000
  • Ironport-hdrordr: A9a23:J8DDhK4gv3+NRqPoUgPXwRqBI+orLtY04lQ7vn1ZYQBJc8Ceis CllOka0xixszoKRHQ8g7m7VZWoa3m0z/5IyKMWOqqvWxSjhXuwIOhZnO/f6hDDOwm7zO5S0q 98b7NzYeebMXFWhdv3iTPWL/8O29+CmZrHuc7771NACT5ncLth6QARMHf/LmRTSBNdDZQ0UL qwj/A3xAaIQngcYsSlCnRtZYGqy+Hjr576fQUAQycu9Qjmt1iVwYTnGBuV1Ap2aUIs/Z4e9w H+8jDR1+GYnNyQjjTd0GLS6Jo+oqqd9vJzQPaip+JQBjHligODbJlsVbuYrFkO0Z2SwWdvqv bgiVMNONly9mPwcwiO0GTQ8jil6hkCwTvDzkKVmnTqq8CRfkNFN+Nxwbh3XzGczmhIhqAa7I t7m1i3mrASMDb72AP63NTMXwECrDvOnVMS1dQ9olYabZETc9Zq3Ooi1XIQKrgsNgTg5rsqFe F/Zfusnsp+QBehY3fVsnIH+q3UYl0DWhOPQk01sseIyTRhnHdg00sCxMAE901wjK4Adw==
  • Ironport-sdr: GEJoPujiSm4460pGyeTxd1p1KUUDWQTBRJPKx/LHEKTGHVBHYmwamMPPd/S77Qekjh0b7ZJmZ2 pwFtnf8AN6V3fLeimsRrg8QqUQnkSmFVYNxsik3gCUyafaDEcuYg/yPzoOjPNTsw1e1ZuoWM38 Gw9IGrk6jg3sEU7QwScDXfKrdHt0nJC/VuMWrkNgxqpwUe7SZaUUT+1FfdDSGrhDtHQKFR0EGd CAKPQyQ/hIkK+wYs5TXKDCrGKpb9NXewkUxWCbuS7KGbJ7b7fhNZ5sUhw8A3kTwDB/TGOpjqQQ vy8=
  • List-id: Xen developer discussion <xen-devel.lists.xenproject.org>

On 05/05/2021 14:02, Roger Pau Monné wrote:
> On Wed, May 05, 2021 at 01:37:48PM +0100, Andrew Cooper wrote:
>> On 05/05/2021 11:04, Roger Pau Monné wrote:
>>> On Tue, May 04, 2021 at 10:31:20PM +0100, Andrew Cooper wrote:
>>>> diff --git a/xen/lib/x86/policy.c b/xen/lib/x86/policy.c
>>>> index f6cea4e2f9..06039e8aa8 100644
>>>> --- a/xen/lib/x86/policy.c
>>>> +++ b/xen/lib/x86/policy.c
>>>> @@ -29,6 +29,9 @@ int x86_cpu_policies_are_compatible(const struct 
>>>> cpu_policy *host,
>>>>      if ( ~host->msr->platform_info.raw & guest->msr->platform_info.raw )
>>>>          FAIL_MSR(MSR_INTEL_PLATFORM_INFO);
>>>>  
>>>> +    if ( ~host->msr->arch_caps.raw & guest->msr->arch_caps.raw )
>>>> +        FAIL_MSR(MSR_ARCH_CAPABILITIES);
>>> It might be nice to expand test_is_compatible_{success,failure} to
>>> account for arch_caps being checked now.
>> At some point we're going to need to stop unit testing "does the AND
>> operator work", and limit testing to the interesting corner cases.
>>
>>> Shouldn't this check also take into account that host might not have
>>> RSBA set, but it's legit for a guest policy to have it?
>> When we expose this properly to guests, the max policies will have RSBA
>> set, and the default policies will have RSBA forwarded from hardware
>> and/or the model table.
>>
>> Therefore, we can accept any VM RSBA configuration, irrespective of the
>> particulars of this host, but if you e.g. have a pool of haswell's, the
>> default policy will have RSBA clear across the board, and the VM won't
>> see it.
>>
>>> if ( ~host->msr->arch_caps.raw & guest->msr->arch_caps.raw & ~POL_MASK )
>>>     FAIL_MSR(MSR_ARCH_CAPABILITIES);
>>>
>>> Maybe POL_MASK should be renamed and defined in a header so it's
>>> widely available?
>> No - this would be incorrect.  The polarity of certain bits only matters
>> for levelling calculations, not for "can this VM run on this host"
>> calculations.
>>
>> If the VM has seen RSBA, and Xen doesn't know about it, the VM cannot run.
> But then the logic relation between
> x86_cpu_policy_calculate_compatible and
> x86_cpu_policies_are_compatible is broken AFAICT.
>
> If you give x86_cpu_policy_calculate_compatible one policy with RSBA set
> and one without it will generate a compatible policy, yet that output
> will be regarded as not compatible if feed into
> x86_cpu_policies_are_compatible against the policy that doesn't have
> RSBA set.
>
> I think the output from x86_cpu_policy_calculate_compatible should
> strictly return true when checked against any of the inputs using
> x86_cpu_policies_are_compatible, or else we need to note it somewhere
> because I think it's not the expected behavior.

Welcome to the monumental complexity, and the reason why this isn't 5
minutes of work.  This is just the tip of the iceberg.

"Please create me a policy for a VM" is conducted across PV/HVM default
policies, and/or user settings, while "Can this VM run on this host" is
checked against the max policy.  This split is necessary to cope with
the corner cases.

So no - levelling max policies isn't expected to result in anything
useful, and calling is_compatible with a default (rather than max) host
setting also isn't going result in a useful answer.

And yes - for some changes, RSBA included, you're going to need to
update all your Xen's across the pool before migration is going to work,
but that's already the case now.


Tangentially, we haven't started yet on

struct irritating_corner_cases {
    bool vm_not_using_fcs_fds;
    bool vm_not_using_lbr;
    ...
};

which will require explicit user opt-in to override the "No - you can't
migration across the IvyBridge/Haswell, or pre-Zen/Zen boundary".

Technically, MCXSR_MASK is also a hard blocker to migration, but we
don't even have that data in a consumable form, and we just might be
extremely lucky and discover that it is restricted to non-64-bit CPUs.

Migration with a VM having turned on LBR is still a disaster.  For now,
we drop everything on the floor, and let the VM explode if the
LBR_FORMAT has changed, or if the number of stack entries changes (which
does change with Hyperthreading enabled/disabled in firmware).

>>>> +
>>>>  #undef FAIL_MSR
>>>>  #undef FAIL_CPUID
>>>>  #undef NA
>>>> @@ -43,6 +46,50 @@ int x86_cpu_policies_are_compatible(const struct 
>>>> cpu_policy *host,
>>>>      return ret;
>>>>  }
>>>>  
>>>> +int x86_cpu_policy_calculate_compatible(const struct cpu_policy *a,
>>>> +                                        const struct cpu_policy *b,
>>>> +                                        struct cpu_policy *out,
>>>> +                                        struct cpu_policy_errors *err)
>>> I think this should be in an #ifndef __XEN__ protected region?
>>>
>>> There's no need to expose this to the hypervisor, as I would expect it
>>> will never have to do compatible policy generation? (ie: it will
>>> always be done by the toolstack?)
>> As indicated previously, I still think we want this in Xen for the boot
>> paths, but I suppose the guard was my suggestion to you, so is only fair
>> at this point.
> TBH I replied before seeing your email that also had this suggestion.
> If it's indeed going to be used by Xen itself then that's fine, but I
> couldn't figure out why the hypervisor would need to generate
> compatible policies itself.
>
> Maybe it will be used to generate the initial policies?

Yes.

>
>>>> +{
>>>> +    const struct cpuid_policy *ap = a->cpuid, *bp = b->cpuid;
>>>> +    const struct msr_policy *am = a->msr, *bm = b->msr;
>>>> +    struct cpuid_policy *cp = out->cpuid;
>>>> +    struct msr_policy *mp = out->msr;
>>>> +
>>>> +    memset(cp, 0, sizeof(*cp));
>>>> +    memset(mp, 0, sizeof(*mp));
>>>> +
>>>> +    cp->basic.max_leaf = min(ap->basic.max_leaf, bp->basic.max_leaf);
>>>> +
>>>> +    if ( cp->basic.max_leaf >= 7 )
>>>> +    {
>>>> +        cp->feat.max_subleaf = min(ap->feat.max_subleaf, 
>>>> bp->feat.max_subleaf);
>>>> +
>>>> +        cp->feat.raw[0].b = ap->feat.raw[0].b & bp->feat.raw[0].b;
>>>> +        cp->feat.raw[0].c = ap->feat.raw[0].c & bp->feat.raw[0].c;
>>>> +        cp->feat.raw[0].d = ap->feat.raw[0].d & bp->feat.raw[0].d;
>>>> +    }
>>>> +
>>>> +    /* TODO: Far more. */
>>> Right, my proposed patch (07/13) went a bit further and also leveled
>>> 1c, 1d, Da1, e1c, e1d, e7d, e8b and e21a, and we also need to level
>>> a couple of max_leaf fields.
>>>
>>> I'm happy for this to go in first, and I can rebase the extra logic I
>>> have on top of this one.
>> There is a lot of work to do.
>>
>> One thing I haven't addressed yet is the fact is things which don't
>> level, e.g. vendor.  You've got to pick one, and there isn't a
>> mathematical relationship to use between a and b.
>>
>> I think for that, we ought to document that we strictly take from a. 
>> This makes the operation not commutative, and in particular, I don't
>> think we want to waste too much time/effort trying to make cross-vendor
>> cases work - it was a stunt a decade ago, with a huge number of sharp
>> corners, as well as creating a number of XSAs due to poor implementation.
>>
>> For v1, I suggest we firmly stick to the same-vendor case.  It's not as
>> if there is a lack of things to do to make this work.
> OK, so level all the feature fields and pick the non feature parts of
> cpuid strictly from one of the inputs.

The awkward part to address is that we've still got simultaneous
equations with feature handling.  I'm fairly certain that the simple
and's which both you and I did won't be sufficient in due course.

~Andrew




 


Rackspace

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