Re: [Xen-devel] [PATCH 2/6] libx86: Split x86_cpuid_policy_fill_native() out of calculate_raw_policy()

2018-11-12 Thread Jan Beulich
>>> On 09.11.18 at 17:24,  wrote:
> On 06/11/18 13:44, Jan Beulich wrote:
> On 05.11.18 at 12:21,  wrote:
>>> --- a/xen/include/xen/lib/x86/cpuid.h
>>> +++ b/xen/include/xen/lib/x86/cpuid.h
>>> @@ -20,6 +20,21 @@ struct cpuid_leaf
>>>  uint32_t a, b, c, d;
>>>  };
>>>  
>>> +static inline void cpuid_leaf(uint32_t leaf, struct cpuid_leaf *l)
>>> +{
>>> +asm volatile ( "cpuid"
>>> +   : "=a" (l->a), "=b" (l->b), "=c" (l->c), "=d" (l->d)
>>> +   : "a" (leaf) );
>>> +}
>>> +
>>> +static inline void cpuid_count_leaf(
>>> +uint32_t leaf, uint32_t subleaf, struct cpuid_leaf *l)
>>> +{
>>> +asm volatile ( "cpuid"
>>> +   : "=a" (l->a), "=b" (l->b), "=c" (l->c), "=d" (l->d)
>>> +   : "a" (leaf), "c" (subleaf) );
>>> +}
>> Especially with this now being library code (i.e. side effects like
>> serialization not being supposed to be of interest): Why
>> volatile?
> 
> Force of habit, I think.  I'll drop volatile here.
> 
> We should probably do the same for Xen, although there is one place in
> the Intel ucode handler which would need adjusting to cope.

And that construct would probably better get a name which
expresses the need for / purpose of the barrier.

>>> --- a/xen/lib/x86/cpuid.c
>>> +++ b/xen/lib/x86/cpuid.c
>>> @@ -2,6 +2,114 @@
>>>  
>>>  #include 
>>>  
>>> +void x86_cpuid_policy_fill_native(struct cpuid_policy *p)
>>> +{
>>> +unsigned int i;
>>> +
>>> +cpuid_leaf(0, >basic.raw[0]);
>>> +for ( i = 1; i < min(ARRAY_SIZE(p->basic.raw),
>>> + p->basic.max_leaf + 1ul); ++i )
>>> +{
>>> +switch ( i )
>>> +{
>>> +case 0x4: case 0x7: case 0xb: case 0xd:
>>> +/* Multi-invocation leaves.  Deferred. */
>>> +continue;
>>> +}
>>> +
>>> +cpuid_leaf(i, >basic.raw[i]);
>>> +}
>>> +
>>> +if ( p->basic.max_leaf >= 4 )
>>> +{
>>> +for ( i = 0; i < ARRAY_SIZE(p->cache.raw); ++i )
>>> +{
>>> +union {
>>> +struct cpuid_leaf l;
>>> +struct cpuid_cache_leaf c;
>>> +} u;
>>> +
>>> +cpuid_count_leaf(4, i, );
>>> +
>>> +if ( u.c.type == 0 )
>>> +break;
>>> +
>>> +p->cache.subleaf[i] = u.c;
>>> +}
>>> +
>>> +/*
>>> + * The choice of CPUID_GUEST_NR_CACHE is arbitrary.  It is expected
>>> + * that it will eventually need increasing for future hardware.
>>> + */
>>> +#ifdef __XEN__
>>> +if ( i == ARRAY_SIZE(p->cache.raw) )
>>> +printk(XENLOG_WARNING
>>> +   "CPUID: Insufficient Leaf 4 space for this hardware\n");
>>> +#endif
>> There being another similar instance further down, and possibly
>> new ones to appear later, plus such a warning potentially also
>> being of interest in the harness - would you mind abstracting
>> (could be as simple as making printk() and XENLOG_* available
>> where needed, provided there's no consumer which would
>> rather not want such logging) this so it can go without #ifdef-ary?
> 
> Well - it was this consideration which caused me to omit it.
> 
> Realistically, the first situation to hit this message will be someone
> booting Xen on a brand new piece of hardware, so I expect changes to the
> structure size to come from vendors.
> 
> One user is the AFL fuzzer, and that definitely doesn't want to be
> spitting out a warning on every fork().

It could still use a construct to spit out a warning exactly once.
Arguably this might be a little difficult to arrange for.

>  The other current user is the
> x86 instruction emulator, where this functionality isn't the interesting
> part.

But such a warning might be a helpful explanation of why some
test failed.

>  Furthermore, I don't expect the toolstack to be making use of
> this itself, so it won't be useful to attempt to plumb the message
> through there.

Sure. Overall I'm not going to insist on extending the logging as
suggested (albeit Roger iirc had asked for it too), so with the
volatile-s above dropped and with the expectation that you
wouldn't object to extending the logging down the road, should
it turn out useful to have outside of the hypervisor
Acked-by: Jan Beulich 

Jan


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

Re: [Xen-devel] [PATCH 2/6] libx86: Split x86_cpuid_policy_fill_native() out of calculate_raw_policy()

2018-11-09 Thread Andrew Cooper
On 06/11/18 16:31, Roger Pau Monné wrote:
> On Mon, Nov 05, 2018 at 11:21:03AM +, Andrew Cooper wrote:
>> This will shortly be wanted by the userspace emulator harnesses as well.
>>
>> Consolidate the cpuid{,_count}_leaf() helpers beside the structure 
>> definition,
>> rather than having them scattered throughout Xen.
>>
>> Signed-off-by: Andrew Cooper 
> Reviewed-by: Roger Pau Monné 
>
> I'm slightly worried about the _native prefix in the function name, if
> this is run on Dom0 userspace the _native part of this is dubious,
> since the policy returned is going to be provided by Xen, and thus
> might not match the host one. I don't have a better name
> recommendation, so I'm fine with this.

Well - it is a native instruction, whether or not there is a outer
hypervisor or masking/faulting configuration playing with the values seen.

I'll see about mentioning this in the function documentation.

~Andrew

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

[Xen-devel] [PATCH 2/6] libx86: Split x86_cpuid_policy_fill_native() out of calculate_raw_policy()

2018-11-09 Thread Andrew Cooper
On 06/11/18 13:44, Jan Beulich wrote:
 On 05.11.18 at 12:21,  wrote:
>> --- a/xen/include/xen/lib/x86/cpuid.h
>> +++ b/xen/include/xen/lib/x86/cpuid.h
>> @@ -20,6 +20,21 @@ struct cpuid_leaf
>>  uint32_t a, b, c, d;
>>  };
>>  
>> +static inline void cpuid_leaf(uint32_t leaf, struct cpuid_leaf *l)
>> +{
>> +asm volatile ( "cpuid"
>> +   : "=a" (l->a), "=b" (l->b), "=c" (l->c), "=d" (l->d)
>> +   : "a" (leaf) );
>> +}
>> +
>> +static inline void cpuid_count_leaf(
>> +uint32_t leaf, uint32_t subleaf, struct cpuid_leaf *l)
>> +{
>> +asm volatile ( "cpuid"
>> +   : "=a" (l->a), "=b" (l->b), "=c" (l->c), "=d" (l->d)
>> +   : "a" (leaf), "c" (subleaf) );
>> +}
> Especially with this now being library code (i.e. side effects like
> serialization not being supposed to be of interest): Why
> volatile?

Force of habit, I think.  I'll drop volatile here.

We should probably do the same for Xen, although there is one place in
the Intel ucode handler which would need adjusting to cope.

>> --- a/xen/lib/x86/cpuid.c
>> +++ b/xen/lib/x86/cpuid.c
>> @@ -2,6 +2,114 @@
>>  
>>  #include 
>>  
>> +void x86_cpuid_policy_fill_native(struct cpuid_policy *p)
>> +{
>> +unsigned int i;
>> +
>> +cpuid_leaf(0, >basic.raw[0]);
>> +for ( i = 1; i < min(ARRAY_SIZE(p->basic.raw),
>> + p->basic.max_leaf + 1ul); ++i )
>> +{
>> +switch ( i )
>> +{
>> +case 0x4: case 0x7: case 0xb: case 0xd:
>> +/* Multi-invocation leaves.  Deferred. */
>> +continue;
>> +}
>> +
>> +cpuid_leaf(i, >basic.raw[i]);
>> +}
>> +
>> +if ( p->basic.max_leaf >= 4 )
>> +{
>> +for ( i = 0; i < ARRAY_SIZE(p->cache.raw); ++i )
>> +{
>> +union {
>> +struct cpuid_leaf l;
>> +struct cpuid_cache_leaf c;
>> +} u;
>> +
>> +cpuid_count_leaf(4, i, );
>> +
>> +if ( u.c.type == 0 )
>> +break;
>> +
>> +p->cache.subleaf[i] = u.c;
>> +}
>> +
>> +/*
>> + * The choice of CPUID_GUEST_NR_CACHE is arbitrary.  It is expected
>> + * that it will eventually need increasing for future hardware.
>> + */
>> +#ifdef __XEN__
>> +if ( i == ARRAY_SIZE(p->cache.raw) )
>> +printk(XENLOG_WARNING
>> +   "CPUID: Insufficient Leaf 4 space for this hardware\n");
>> +#endif
> There being another similar instance further down, and possibly
> new ones to appear later, plus such a warning potentially also
> being of interest in the harness - would you mind abstracting
> (could be as simple as making printk() and XENLOG_* available
> where needed, provided there's no consumer which would
> rather not want such logging) this so it can go without #ifdef-ary?

Well - it was this consideration which caused me to omit it.

Realistically, the first situation to hit this message will be someone
booting Xen on a brand new piece of hardware, so I expect changes to the
structure size to come from vendors.

One user is the AFL fuzzer, and that definitely doesn't want to be
spitting out a warning on every fork().  The other current user is the
x86 instruction emulator, where this functionality isn't the interesting
part.  Furthermore, I don't expect the toolstack to be making use of
this itself, so it won't be useful to attempt to plumb the message
through there.

~Andrew
___
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

Re: [Xen-devel] [PATCH 2/6] libx86: Split x86_cpuid_policy_fill_native() out of calculate_raw_policy()

2018-11-06 Thread Roger Pau Monné
On Mon, Nov 05, 2018 at 11:21:03AM +, Andrew Cooper wrote:
> This will shortly be wanted by the userspace emulator harnesses as well.
> 
> Consolidate the cpuid{,_count}_leaf() helpers beside the structure definition,
> rather than having them scattered throughout Xen.
> 
> Signed-off-by: Andrew Cooper 

Reviewed-by: Roger Pau Monné 

I'm slightly worried about the _native prefix in the function name, if
this is run on Dom0 userspace the _native part of this is dubious,
since the policy returned is going to be provided by Xen, and thus
might not match the host one. I don't have a better name
recommendation, so I'm fine with this.

> diff --git a/xen/lib/x86/cpuid.c b/xen/lib/x86/cpuid.c
> index a63e42b..ddd3821 100644
> --- a/xen/lib/x86/cpuid.c
> +++ b/xen/lib/x86/cpuid.c
> @@ -2,6 +2,114 @@
>  
>  #include 
>  
> +void x86_cpuid_policy_fill_native(struct cpuid_policy *p)
> +{
> +unsigned int i;
> +
> +cpuid_leaf(0, >basic.raw[0]);
> +for ( i = 1; i < min(ARRAY_SIZE(p->basic.raw),
> + p->basic.max_leaf + 1ul); ++i )
> +{
> +switch ( i )
> +{
> +case 0x4: case 0x7: case 0xb: case 0xd:
> +/* Multi-invocation leaves.  Deferred. */
> +continue;
> +}
> +
> +cpuid_leaf(i, >basic.raw[i]);
> +}
> +
> +if ( p->basic.max_leaf >= 4 )
> +{
> +for ( i = 0; i < ARRAY_SIZE(p->cache.raw); ++i )
> +{
> +union {
> +struct cpuid_leaf l;
> +struct cpuid_cache_leaf c;
> +} u;
> +
> +cpuid_count_leaf(4, i, );
> +
> +if ( u.c.type == 0 )
> +break;
> +
> +p->cache.subleaf[i] = u.c;
> +}
> +
> +/*
> + * The choice of CPUID_GUEST_NR_CACHE is arbitrary.  It is expected
> + * that it will eventually need increasing for future hardware.
> + */
> +#ifdef __XEN__
> +if ( i == ARRAY_SIZE(p->cache.raw) )
> +printk(XENLOG_WARNING
> +   "CPUID: Insufficient Leaf 4 space for this hardware\n");

It would be good to provide some logging abstraction that can be used
by both the tools and Xen, ie:

printf(LIBX86_WARN, "...");

And then add a couple of defines for __XEN__ and __XEN_TOOLS__ as
required. Can be done in a followup patch IMO.

Thanks, Roger.

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

Re: [Xen-devel] [PATCH 2/6] libx86: Split x86_cpuid_policy_fill_native() out of calculate_raw_policy()

2018-11-06 Thread Jan Beulich
>>> On 05.11.18 at 12:21,  wrote:
> --- a/xen/include/xen/lib/x86/cpuid.h
> +++ b/xen/include/xen/lib/x86/cpuid.h
> @@ -20,6 +20,21 @@ struct cpuid_leaf
>  uint32_t a, b, c, d;
>  };
>  
> +static inline void cpuid_leaf(uint32_t leaf, struct cpuid_leaf *l)
> +{
> +asm volatile ( "cpuid"
> +   : "=a" (l->a), "=b" (l->b), "=c" (l->c), "=d" (l->d)
> +   : "a" (leaf) );
> +}
> +
> +static inline void cpuid_count_leaf(
> +uint32_t leaf, uint32_t subleaf, struct cpuid_leaf *l)
> +{
> +asm volatile ( "cpuid"
> +   : "=a" (l->a), "=b" (l->b), "=c" (l->c), "=d" (l->d)
> +   : "a" (leaf), "c" (subleaf) );
> +}

Especially with this now being library code (i.e. side effects like
serialization not being supposed to be of interest): Why
volatile?

> --- a/xen/lib/x86/cpuid.c
> +++ b/xen/lib/x86/cpuid.c
> @@ -2,6 +2,114 @@
>  
>  #include 
>  
> +void x86_cpuid_policy_fill_native(struct cpuid_policy *p)
> +{
> +unsigned int i;
> +
> +cpuid_leaf(0, >basic.raw[0]);
> +for ( i = 1; i < min(ARRAY_SIZE(p->basic.raw),
> + p->basic.max_leaf + 1ul); ++i )
> +{
> +switch ( i )
> +{
> +case 0x4: case 0x7: case 0xb: case 0xd:
> +/* Multi-invocation leaves.  Deferred. */
> +continue;
> +}
> +
> +cpuid_leaf(i, >basic.raw[i]);
> +}
> +
> +if ( p->basic.max_leaf >= 4 )
> +{
> +for ( i = 0; i < ARRAY_SIZE(p->cache.raw); ++i )
> +{
> +union {
> +struct cpuid_leaf l;
> +struct cpuid_cache_leaf c;
> +} u;
> +
> +cpuid_count_leaf(4, i, );
> +
> +if ( u.c.type == 0 )
> +break;
> +
> +p->cache.subleaf[i] = u.c;
> +}
> +
> +/*
> + * The choice of CPUID_GUEST_NR_CACHE is arbitrary.  It is expected
> + * that it will eventually need increasing for future hardware.
> + */
> +#ifdef __XEN__
> +if ( i == ARRAY_SIZE(p->cache.raw) )
> +printk(XENLOG_WARNING
> +   "CPUID: Insufficient Leaf 4 space for this hardware\n");
> +#endif

There being another similar instance further down, and possibly
new ones to appear later, plus such a warning potentially also
being of interest in the harness - would you mind abstracting
(could be as simple as making printk() and XENLOG_* available
where needed, provided there's no consumer which would
rather not want such logging) this so it can go without #ifdef-ary?

Jan



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

[Xen-devel] [PATCH 2/6] libx86: Split x86_cpuid_policy_fill_native() out of calculate_raw_policy()

2018-11-05 Thread Andrew Cooper
This will shortly be wanted by the userspace emulator harnesses as well.

Consolidate the cpuid{,_count}_leaf() helpers beside the structure definition,
rather than having them scattered throughout Xen.

Signed-off-by: Andrew Cooper 
---
CC: Jan Beulich 
CC: Wei Liu 
---
 xen/arch/x86/cpuid.c| 105 +-
 xen/include/asm-x86/processor.h |   6 ---
 xen/include/xen/lib/x86/cpuid.h |  18 +++
 xen/lib/x86/cpuid.c | 108 
 4 files changed, 127 insertions(+), 110 deletions(-)

diff --git a/xen/arch/x86/cpuid.c b/xen/arch/x86/cpuid.c
index d21e745..0591a7d 100644
--- a/xen/arch/x86/cpuid.c
+++ b/xen/arch/x86/cpuid.c
@@ -75,11 +75,6 @@ struct cpuid_policy __read_mostly raw_cpuid_policy,
 __read_mostly pv_max_cpuid_policy,
 __read_mostly hvm_max_cpuid_policy;
 
-static void cpuid_leaf(uint32_t leaf, struct cpuid_leaf *data)
-{
-cpuid(leaf, >a, >b, >c, >d);
-}
-
 static void sanitise_featureset(uint32_t *fs)
 {
 /* for_each_set_bit() uses unsigned longs.  Extend with zeroes. */
@@ -273,106 +268,8 @@ static void recalculate_misc(struct cpuid_policy *p)
 static void __init calculate_raw_policy(void)
 {
 struct cpuid_policy *p = _cpuid_policy;
-unsigned int i;
-
-cpuid_leaf(0, >basic.raw[0]);
-for ( i = 1; i < min(ARRAY_SIZE(p->basic.raw),
- p->basic.max_leaf + 1ul); ++i )
-{
-switch ( i )
-{
-case 0x4: case 0x7: case 0xb: case 0xd:
-/* Multi-invocation leaves.  Deferred. */
-continue;
-}
-
-cpuid_leaf(i, >basic.raw[i]);
-}
-
-if ( p->basic.max_leaf >= 4 )
-{
-for ( i = 0; i < ARRAY_SIZE(p->cache.raw); ++i )
-{
-union {
-struct cpuid_leaf l;
-struct cpuid_cache_leaf c;
-} u;
-
-cpuid_count_leaf(4, i, );
-
-if ( u.c.type == 0 )
-break;
-
-p->cache.subleaf[i] = u.c;
-}
-
-/*
- * The choice of CPUID_GUEST_NR_CACHE is arbitrary.  It is expected
- * that it will eventually need increasing for future hardware.
- */
-if ( i == ARRAY_SIZE(p->cache.raw) )
-printk(XENLOG_WARNING
-   "CPUID: Insufficient Leaf 4 space for this hardware\n");
-}
-
-if ( p->basic.max_leaf >= 7 )
-{
-cpuid_count_leaf(7, 0, >feat.raw[0]);
-
-for ( i = 1; i < min(ARRAY_SIZE(p->feat.raw),
- p->feat.max_subleaf + 1ul); ++i )
-cpuid_count_leaf(7, i, >feat.raw[i]);
-}
-
-if ( p->basic.max_leaf >= 0xb )
-{
-union {
-struct cpuid_leaf l;
-struct cpuid_topo_leaf t;
-} u;
-
-for ( i = 0; i < ARRAY_SIZE(p->topo.raw); ++i )
-{
-cpuid_count_leaf(0xb, i, );
-
-if ( u.t.type == 0 )
-break;
-
-p->topo.subleaf[i] = u.t;
-}
-
-/*
- * The choice of CPUID_GUEST_NR_TOPO is per the manual.  It may need
- * to grow for future hardware.
- */
-if ( i == ARRAY_SIZE(p->topo.raw) &&
- (cpuid_count_leaf(0xb, i, ), u.t.type != 0) )
-printk(XENLOG_WARNING
-   "CPUID: Insufficient Leaf 0xb space for this hardware\n");
-}
-
-if ( p->basic.max_leaf >= XSTATE_CPUID )
-{
-uint64_t xstates;
-
-cpuid_count_leaf(XSTATE_CPUID, 0, >xstate.raw[0]);
-cpuid_count_leaf(XSTATE_CPUID, 1, >xstate.raw[1]);
-
-xstates = ((uint64_t)(p->xstate.xcr0_high | p->xstate.xss_high) << 32) 
|
-(p->xstate.xcr0_low | p->xstate.xss_low);
-
-for ( i = 2; i < min(63ul, ARRAY_SIZE(p->xstate.raw)); ++i )
-{
-if ( xstates & (1ul << i) )
-cpuid_count_leaf(XSTATE_CPUID, i, >xstate.raw[i]);
-}
-}
 
-/* Extended leaves. */
-cpuid_leaf(0x8000, >extd.raw[0]);
-for ( i = 1; i < min(ARRAY_SIZE(p->extd.raw),
- p->extd.max_leaf + 1 - 0x8000ul); ++i )
-cpuid_leaf(0x8000 + i, >extd.raw[i]);
+x86_cpuid_policy_fill_native(p);
 
 p->x86_vendor = boot_cpu_data.x86_vendor;
 }
diff --git a/xen/include/asm-x86/processor.h b/xen/include/asm-x86/processor.h
index 03555e1..df01ae3 100644
--- a/xen/include/asm-x86/processor.h
+++ b/xen/include/asm-x86/processor.h
@@ -263,12 +263,6 @@ static always_inline unsigned int cpuid_count_ebx(
 return ebx;
 }
 
-static always_inline void cpuid_count_leaf(uint32_t leaf, uint32_t subleaf,
-   struct cpuid_leaf *data)
-{
-cpuid_count(leaf, subleaf, >a, >b, >c, >d);
-}
-
 static inline unsigned long read_cr0(void)
 {
 unsigned long cr0;
diff --git a/xen/include/xen/lib/x86/cpuid.h b/xen/include/xen/lib/x86/cpuid.h
index 93ada23..5e4ec09 100644
--- a/xen/include/xen/lib/x86/cpuid.h