On 30/04/2021 16:52, Roger Pau Monne wrote:
> @@ -822,3 +825,28 @@ int xc_cpu_policy_serialise(xc_interface *xch, const 
> xc_cpu_policy_t p,
>      errno = 0;
>      return 0;
>  }
> +
> +int xc_cpu_policy_get_cpuid(xc_interface *xch, const xc_cpu_policy_t policy,
> +                            uint32_t leaf, uint32_t subleaf,
> +                            xen_cpuid_leaf_t *out)
> +{
> +    unsigned int nr_leaves = ARRAY_SIZE(policy->leaves);
> +    xen_cpuid_leaf_t *tmp;
> +    int rc;
> +
> +    rc = xc_cpu_policy_serialise(xch, policy, policy->leaves, &nr_leaves,
> +                                 NULL, 0);
> +    if ( rc )
> +        return rc;

Sorry for not spotting this last time.

You don't need to serialise.  You can look up leaf/subleaf in O(1) time
from cpuid_policy, which was a design goal of the structure originally.

It is probably best to adapt most of the first switch statement in
guest_cpuid() to be a libx86 function.  The asserts aren't massively
interesting to keep, and instead of messing around with nospec, just
have the function return a pointer into the cpuid_policy (or NULL), and
have a single block_speculation() in Xen.  We'll also want a unit test
to go with this new function to check that out-of-range leaves don't
result in out-of-bounds reads.

~Andrew


Reply via email to