[PATCH v3 1/2] Introduce (x86) CPU model deprecation API

2020-09-16 Thread Robert Hoo
Complement versioned CPU model framework with the ability of marking some
versions deprecated. When that CPU model is chosen, get some warning. The
warning message is customized, e.g. telling in which future QEMU version will
it be obsoleted.
The deprecation message will also appear by x86_cpu_list_entry(), e.g. '-cpu
help'.
QMP 'query-cpu-definitions' will also return a bool value indicating the
deprecation status.

Signed-off-by: Robert Hoo 
---
Changelog
v3:
Make the deprecation implementation CPUClass generic.

v2:
Move deprecation check from parse_cpu_option() to machine_run_board_init(), so
that it can cover implicit cpu_type assignment cases.
Add qapi new member documentation. Thanks Eric for comment and guidance on qapi.

 hw/core/machine.c| 12 ++--
 include/hw/core/cpu.h|  6 ++
 qapi/machine-target.json |  7 ++-
 target/i386/cpu.c| 29 +++--
 4 files changed, 45 insertions(+), 9 deletions(-)

diff --git a/hw/core/machine.c b/hw/core/machine.c
index ea26d61..b41f88d 100644
--- a/hw/core/machine.c
+++ b/hw/core/machine.c
@@ -1095,6 +1095,8 @@ MemoryRegion *machine_consume_memdev(MachineState 
*machine,
 void machine_run_board_init(MachineState *machine)
 {
 MachineClass *machine_class = MACHINE_GET_CLASS(machine);
+ObjectClass *oc = object_class_by_name(machine->cpu_type);
+CPUClass *cc;
 
 if (machine->ram_memdev_id) {
 Object *o;
@@ -1114,11 +1116,10 @@ void machine_run_board_init(MachineState *machine)
  * specified a CPU with -cpu check here that the user CPU is supported.
  */
 if (machine_class->valid_cpu_types && machine->cpu_type) {
-ObjectClass *class = object_class_by_name(machine->cpu_type);
 int i;
 
 for (i = 0; machine_class->valid_cpu_types[i]; i++) {
-if (object_class_dynamic_cast(class,
+if (object_class_dynamic_cast(oc,
   machine_class->valid_cpu_types[i])) {
 /* The user specificed CPU is in the valid field, we are
  * good to go.
@@ -1141,6 +1142,13 @@ void machine_run_board_init(MachineState *machine)
 }
 }
 
+/* Check if CPU type is deprecated and warn if so */
+cc = CPU_CLASS(oc);
+if (cc->deprecated) {
+warn_report("CPU model %s is deprecated -- %s", machine->cpu_type,
+cc->deprecation_note);
+}
+
 machine_class->init(machine);
 }
 
diff --git a/include/hw/core/cpu.h b/include/hw/core/cpu.h
index 99dc33f..c4b17c8 100644
--- a/include/hw/core/cpu.h
+++ b/include/hw/core/cpu.h
@@ -155,6 +155,10 @@ struct TranslationBlock;
  * @disas_set_info: Setup architecture specific components of disassembly info
  * @adjust_watchpoint_address: Perform a target-specific adjustment to an
  * address before attempting to match it against watchpoints.
+ * @deprecated: True if this CPU model is deprecated (going to be removed in
+ *  near future).
+ * @deprecation_note: Message about the deprecation. e.g. Since which version
+ *will it be obsoleted.
  *
  * Represents a CPU family or model.
  */
@@ -221,6 +225,8 @@ struct CPUClass {
 vaddr (*adjust_watchpoint_address)(CPUState *cpu, vaddr addr, int len);
 void (*tcg_initialize)(void);
 
+bool deprecated;
+const char *deprecation_note;
 /* Keep non-pointer data at the end to minimize holes.  */
 int gdb_num_core_regs;
 bool gdb_stop_before_watchpoint;
diff --git a/qapi/machine-target.json b/qapi/machine-target.json
index 698850c..fec3bb8 100644
--- a/qapi/machine-target.json
+++ b/qapi/machine-target.json
@@ -286,6 +286,10 @@
 #in the VM configuration, because aliases may stop being
 #migration-safe in the future (since 4.1)
 #
+# @deprecated: If true, this CPU model is deprecated and may be removed in
+#  in some future version of QEMU according to the QEMU deprecation
+#  policy. (since 5.2)
+#
 # @unavailable-features is a list of QOM property names that
 # represent CPU model attributes that prevent the CPU from running.
 # If the QOM property is read-only, that means there's no known
@@ -310,7 +314,8 @@
 'static': 'bool',
 '*unavailable-features': [ 'str' ],
 'typename': 'str',
-'*alias-of' : 'str' },
+'*alias-of' : 'str',
+'deprecated' : 'bool' },
   'if': 'defined(TARGET_PPC) || defined(TARGET_ARM) || defined(TARGET_I386) || 
defined(TARGET_S390X) || defined(TARGET_MIPS)' }
 
 ##
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index 49d8958..9cb82b7 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -1716,6 +1716,7 @@ typedef struct X86CPUVersionDefinition {
 const char *alias;
 const char *note;
 PropValue *props;
+bool   deprecated;
 } X86CPUVersionDefinition;
 
 /* Base definition for a CPU

Re: [PATCH v2 1/2] Introduce (x86) CPU model deprecation API

2020-09-14 Thread Robert Hoo
On Mon, 2020-09-14 at 13:38 +, Eduardo Habkost wrote:
> On Mon, Sep 14, 2020 at 06:50:09PM +0800, Robert Hoo wrote:
> > On Fri, 2020-09-11 at 10:00 -0400, Eduardo Habkost wrote:
> > > On Fri, Sep 11, 2020 at 02:22:51PM +0800, Robert Hoo wrote:
> > > > On Wed, 2020-09-09 at 14:15 -0400, Eduardo Habkost wrote:
> 
> [...]
> > > > > > +static void x86_cpu_deprecation_check(ObjectClass *oc)
> > > > > > +{
> > > > > > +X86CPUClass *xcc = X86_CPU_CLASS(oc);
> > > > > > +X86CPUVersion effective_version;
> > > > > > +const X86CPUVersionDefinition *vdef;
> > > > > > +
> > > > > > +if (xcc->model == NULL) {
> > > > > > +return;
> > > > > > +}
> > > > > > +
> > > > > > +if (xcc->model->version == CPU_VERSION_LEGACY) {
> > > > > > +/* Treat legacy version as v1 */
> > > > > > +effective_version = 1;
> > > > > > +} else {
> > > > > > +effective_version =
> > > > > > x86_cpu_model_resolve_version(xcc-
> > > > > > > model);
> > > > > > 
> > > > > > +}
> > > > > > +
> > > > > > +vdef = xcc->model->cpudef->versions;
> > > > > > +
> > > > > > +if (vdef == NULL) {
> > > > > > +return;
> > > > > > +} else {
> > > > > > +if (vdef[effective_version - 1].deprecated) {
> > > > > > +warn_report("Effective CPU model '%s' -- %s",
> > > > > > +x86_cpu_versioned_model_name(xcc-
> > > > > > >model-
> > > > > > > cpudef,\
> > > > > > 
> > > > > > +effective_
> > > > > > vers
> > > > > > ion)
> > > > > > ,
> > > > > > +vdef[effective_version - 1].note);
> > > > > > +}
> > > > > > +}
> > > > > 
> > > > > Why do we need this extra logic?  Isn't it simpler to just
> > > > > add a
> > > > > bool CPUClass::deprecated field, and set:
> > > > > 
> > > > >cpu->deprecated = model->deprecated;
> > > > > 
> > > > > inside x86_cpu_cpudef_class_init()?
> > > > > 
> > > > 
> > > > All these are to fulfill the target you expected earlier:
> > > > 
> > > > "We need a proper CPU model deprecation API.  Deprecation info
> > > > should appear on query-cpu-definitions and should trigger a
> > > > warning when using the CPU model."
> > > > 
> > > > So I think each deprecated model shall have its own deprecation
> > > > message, e.g. by which version it's going to be deprecation,
> > > > etc.
> > > 
> > > There's nothing x86-specific about having deprecated CPU models,
> > > so I don't understand the reason for the x86-specific hook.
> > > 
> > > If the .note field is the reason you added the arch-specific
> > > hook, you can just add a CPUClass::deprecation_note field and
> > > make the feature generic.
> > > 
> > 
> > I tend to agree with you on this generalization requirement.
> > 
> > But then I find it still has some tricky thing, perhaps that's why
> > I
> > defined this x86 target specific hook:
> > 
> > 1) The versioned CPU model is x86 specific (at least at present)
> 
> I don't see why this would be an obstacle.  You just need to set
> CPUClass::deprecated and/or CPUClass::deprecation_note in the
> x86-specific class_init code.
> 
> > 
> > 2) Each x86 cpudef CPU model has 1 unversioned cpu_model_type then
> > its
> > versioned cpu_model_types. Refer to code in
> > x86_register_cpudef_types(). The unversioned model won't be marked
> > deprecated as it is unkown when registered. In
> > machine_run_board_init(), the cpu_model being checked is the
> > unversioned one, if I set -cpu to its general unversioned model.
> > In short, the unversioned cpudef CPU model would escape the
> > deprecation
> > check.
> 
> Why is that a problem?  If, for example, Model-v1 is deprecated
> and Model-v2 is not deprecated, we must never tell the user that
> "-cpu Model" is deprecated.  

Yes, that's why I cannot mark the unversioned one deprecated or not in
its init.

> Even if some machine types resolve
> "-cpu Model" to Model-v1.
> 
That's what I concerned. Say, if I named "-cpu Icelake-Client" and it's
resolved to Icelake-CPU-v1 (deprecated), shouldn't we warn user?
> --
> Eduardo
> 




Re: [PATCH v2 1/2] Introduce (x86) CPU model deprecation API

2020-09-14 Thread Robert Hoo
On Fri, 2020-09-11 at 10:00 -0400, Eduardo Habkost wrote:
> On Fri, Sep 11, 2020 at 02:22:51PM +0800, Robert Hoo wrote:
> > On Wed, 2020-09-09 at 14:15 -0400, Eduardo Habkost wrote:
> > > Hi,
> > > 
> > > 
> > > > @@ -1129,6 +1130,12 @@ void machine_run_board_init(MachineState
> > > > *machine)
> > > >  }
> > > >  }
> > > >  
> > > > +/* Check if CPU type is deprecated and warn if so */
> > > > +cc = CPU_CLASS(oc);
> > > > +if (cc->deprecation_check) {
> > > > +cc->deprecation_check(oc);
> > > > +}
> > > 
> > > Why do we need target-specific code here?  A CPUClass::deprecated
> > > field would be much simpler.
> > > 
> > 
> > Because the Warning message composing is target-specific, using
> > X86CPUVersionDefinition.note.
> > Other targets can have their own warning message composing
> > approaches.
> 
> I think I understand what you were trying to do, but having each
> target with a different warning message would be a bad thing, not
> a desirable feature.  The warning message can be generic.
> 
> > 
> > > > +
> > > >  machine_class->init(machine);
> > > >  }
> > > >  
> > > > diff --git a/include/hw/core/cpu.h b/include/hw/core/cpu.h
> > > > index 497600c..1ca47dc 100644
> > > > --- a/include/hw/core/cpu.h
> > > > +++ b/include/hw/core/cpu.h
> > > > @@ -218,6 +218,7 @@ typedef struct CPUClass {
> > > >  void (*disas_set_info)(CPUState *cpu, disassemble_info
> > > > *info);
> > > >  vaddr (*adjust_watchpoint_address)(CPUState *cpu, vaddr
> > > > addr,
> > > > int len);
> > > >  void (*tcg_initialize)(void);
> > > > +void (*deprecation_check)(ObjectClass *oc);
> > > >  
> > > >  /* Keep non-pointer data at the end to minimize holes.  */
> > > >  int gdb_num_core_regs;
> > > > diff --git a/qapi/machine-target.json b/qapi/machine-
> > > > target.json
> > > > index f2c8294..c24f506 100644
> > > > --- a/qapi/machine-target.json
> > > > +++ b/qapi/machine-target.json
> > > > @@ -285,6 +285,10 @@
> > > >  #in the VM configuration, because aliases may stop
> > > > being
> > > >  #migration-safe in the future (since 4.1)
> > > >  #
> > > > +# @deprecated: If true, this CPU model is deprecated and may
> > > > be
> > > > removed in
> > > > +#  in some future version of QEMU according to the
> > > > QEMU deprecation
> > > > +#  policy. (since 5.1)
> > > 
> > > Next version needs to say "since 5.2".
> > 
> > Sure.
> > > 
> > > > 
> > > >  
> > > >  /* Get full model name for CPU version */
> > > > @@ -4128,8 +4134,7 @@ static X86CPUVersion
> > > > x86_cpu_model_resolve_version(const X86CPUModel *model)
> > > >  X86CPUVersion v = model->version;
> > > >  if (v == CPU_VERSION_AUTO) {
> > > >  v = default_cpu_version;
> > > > -}
> > > > -if (v == CPU_VERSION_LATEST) {
> > > > +} else if (v == CPU_VERSION_LATEST) {
> > > 
> > > Why is this change necessary?
> > 
> > Just kind of compulsion of avoiding unnecessary if() :-). 'v' can
> > only
> > be one of CPU_VERSION_AUTO and CPU_VERSION_LATEST, unnecessary to
> > judge
> > twice.
> 
> I think this breaks the case where default_cpu_version is set to
> CPU_VERSION_LATEST
> 
OK, understand.
> > > 
> > > >  return x86_cpu_model_last_version(model);
> > > >  }
> > > >  return v;
> > > > @@ -4975,6 +4980,7 @@ static void
> > > > x86_cpu_definition_entry(gpointer
> > > > data, gpointer user_data)
> > > >  info->migration_safe = cc->migration_safe;
> > > >  info->has_migration_safe = true;
> > > >  info->q_static = cc->static_model;
> > > > +info->deprecated = cc->model ? cc->model->deprecated :
> > > > false;
> > > >  /*
> > > >   * Old machine types won't report aliases, so that alias
> > > > translation
> > > >   * doesn't break compatibility with previous QEMU
> > > 

Re: [PATCH v2 1/2] Introduce (x86) CPU model deprecation API

2020-09-11 Thread Robert Hoo
On Wed, 2020-09-09 at 14:15 -0400, Eduardo Habkost wrote:
> Hi,
> 
> Thanks for the patch, and sorry for taking so long to review
> this.  I'm finally getting to the patches that were postponed to
> 5.2.
> 
> Comments and questions below:
> 
> On Thu, Jun 11, 2020 at 10:47:55AM +0800, Robert Hoo wrote:
> > Complement versioned CPU model framework with the ability of
> > marking some
> > versions deprecated. When that CPU model is chosen, get some
> > warning. The
> > warning message is customized, e.g. telling in which future QEMU
> > version will
> > it be obsoleted.
> > The deprecation message will also appear by x86_cpu_list_entry(),
> > e.g. '-cpu
> > help'.
> > QMP 'query-cpu-definitions' will also return a bool value
> > indicating the
> > deprecation status.
> > 
> > Changes in v2:
> > Move deprecation check from parse_cpu_option() to
> > machine_run_board_init(), so
> > that it can cover implicit cpu_type assignment cases.
> > Add qapi new member documentation. Thanks Eric for comment and
> > guidance on qapi.
> > 
> > Signed-off-by: Robert Hoo 
> > ---
> >  hw/core/machine.c| 11 +--
> >  include/hw/core/cpu.h|  1 +
> >  qapi/machine-target.json |  7 ++-
> >  target/i386/cpu.c| 45
> > +++--
> >  4 files changed, 59 insertions(+), 5 deletions(-)
> > 
> > diff --git a/hw/core/machine.c b/hw/core/machine.c
> > index bb3a7b1..9318964 100644
> > --- a/hw/core/machine.c
> > +++ b/hw/core/machine.c
> > @@ -1083,6 +1083,8 @@ MemoryRegion
> > *machine_consume_memdev(MachineState *machine,
> >  void machine_run_board_init(MachineState *machine)
> >  {
> >  MachineClass *machine_class = MACHINE_GET_CLASS(machine);
> > +ObjectClass *oc = object_class_by_name(machine->cpu_type);
> > +CPUClass *cc;
> >  
> >  if (machine->ram_memdev_id) {
> >  Object *o;
> > @@ -1102,11 +1104,10 @@ void machine_run_board_init(MachineState
> > *machine)
> >   * specified a CPU with -cpu check here that the user CPU is
> > supported.
> >   */
> >  if (machine_class->valid_cpu_types && machine->cpu_type) {
> > -ObjectClass *class = object_class_by_name(machine-
> > >cpu_type);
> >  int i;
> >  
> >  for (i = 0; machine_class->valid_cpu_types[i]; i++) {
> > -if (object_class_dynamic_cast(class,
> > +if (object_class_dynamic_cast(oc,
> >machine_class-
> > >valid_cpu_types[i])) {
> >  /* The user specificed CPU is in the valid field,
> > we are
> >   * good to go.
> > @@ -1129,6 +1130,12 @@ void machine_run_board_init(MachineState
> > *machine)
> >  }
> >  }
> >  
> > +/* Check if CPU type is deprecated and warn if so */
> > +cc = CPU_CLASS(oc);
> > +if (cc->deprecation_check) {
> > +cc->deprecation_check(oc);
> > +}
> 
> Why do we need target-specific code here?  A CPUClass::deprecated
> field would be much simpler.
> 
Because the Warning message composing is target-specific, using
X86CPUVersionDefinition.note.
Other targets can have their own warning message composing approaches.

> > +
> >  machine_class->init(machine);
> >  }
> >  
> > diff --git a/include/hw/core/cpu.h b/include/hw/core/cpu.h
> > index 497600c..1ca47dc 100644
> > --- a/include/hw/core/cpu.h
> > +++ b/include/hw/core/cpu.h
> > @@ -218,6 +218,7 @@ typedef struct CPUClass {
> >  void (*disas_set_info)(CPUState *cpu, disassemble_info *info);
> >  vaddr (*adjust_watchpoint_address)(CPUState *cpu, vaddr addr,
> > int len);
> >  void (*tcg_initialize)(void);
> > +void (*deprecation_check)(ObjectClass *oc);
> >  
> >  /* Keep non-pointer data at the end to minimize holes.  */
> >  int gdb_num_core_regs;
> > diff --git a/qapi/machine-target.json b/qapi/machine-target.json
> > index f2c8294..c24f506 100644
> > --- a/qapi/machine-target.json
> > +++ b/qapi/machine-target.json
> > @@ -285,6 +285,10 @@
> >  #in the VM configuration, because aliases may stop
> > being
> >  #migration-safe in the future (since 4.1)
> >  #
> > +# @deprecated: If true, this CPU model is deprecated and may be
> > removed in
> > +#  in some future version of QEMU according to the
> > QEMU

Re: [PATCH v2 1/2] Introduce (x86) CPU model deprecation API

2020-06-28 Thread Robert Hoo
Hi, Ping for comments:)
On Thu, 2020-06-11 at 10:47 +0800, Robert Hoo wrote:
> Complement versioned CPU model framework with the ability of marking
> some
> versions deprecated. When that CPU model is chosen, get some warning.
> The
> warning message is customized, e.g. telling in which future QEMU
> version will
> it be obsoleted.
> The deprecation message will also appear by x86_cpu_list_entry(),
> e.g. '-cpu
> help'.
> QMP 'query-cpu-definitions' will also return a bool value indicating
> the
> deprecation status.
> 
> Changes in v2:
> Move deprecation check from parse_cpu_option() to
> machine_run_board_init(), so
> that it can cover implicit cpu_type assignment cases.
> Add qapi new member documentation. Thanks Eric for comment and
> guidance on qapi.
> 
> Signed-off-by: Robert Hoo 
> ---
>  hw/core/machine.c| 11 +--
>  include/hw/core/cpu.h|  1 +
>  qapi/machine-target.json |  7 ++-
>  target/i386/cpu.c| 45
> +++--
>  4 files changed, 59 insertions(+), 5 deletions(-)
> 
> diff --git a/hw/core/machine.c b/hw/core/machine.c
> index bb3a7b1..9318964 100644
> --- a/hw/core/machine.c
> +++ b/hw/core/machine.c
> @@ -1083,6 +1083,8 @@ MemoryRegion
> *machine_consume_memdev(MachineState *machine,
>  void machine_run_board_init(MachineState *machine)
>  {
>  MachineClass *machine_class = MACHINE_GET_CLASS(machine);
> +ObjectClass *oc = object_class_by_name(machine->cpu_type);
> +CPUClass *cc;
>  
>  if (machine->ram_memdev_id) {
>  Object *o;
> @@ -1102,11 +1104,10 @@ void machine_run_board_init(MachineState
> *machine)
>   * specified a CPU with -cpu check here that the user CPU is
> supported.
>   */
>  if (machine_class->valid_cpu_types && machine->cpu_type) {
> -ObjectClass *class = object_class_by_name(machine-
> >cpu_type);
>  int i;
>  
>  for (i = 0; machine_class->valid_cpu_types[i]; i++) {
> -if (object_class_dynamic_cast(class,
> +if (object_class_dynamic_cast(oc,
>machine_class-
> >valid_cpu_types[i])) {
>  /* The user specificed CPU is in the valid field, we
> are
>   * good to go.
> @@ -1129,6 +1130,12 @@ void machine_run_board_init(MachineState
> *machine)
>  }
>  }
>  
> +/* Check if CPU type is deprecated and warn if so */
> +cc = CPU_CLASS(oc);
> +if (cc->deprecation_check) {
> +cc->deprecation_check(oc);
> +}
> +
>  machine_class->init(machine);
>  }
>  
> diff --git a/include/hw/core/cpu.h b/include/hw/core/cpu.h
> index 497600c..1ca47dc 100644
> --- a/include/hw/core/cpu.h
> +++ b/include/hw/core/cpu.h
> @@ -218,6 +218,7 @@ typedef struct CPUClass {
>  void (*disas_set_info)(CPUState *cpu, disassemble_info *info);
>  vaddr (*adjust_watchpoint_address)(CPUState *cpu, vaddr addr,
> int len);
>  void (*tcg_initialize)(void);
> +void (*deprecation_check)(ObjectClass *oc);
>  
>  /* Keep non-pointer data at the end to minimize holes.  */
>  int gdb_num_core_regs;
> diff --git a/qapi/machine-target.json b/qapi/machine-target.json
> index f2c8294..c24f506 100644
> --- a/qapi/machine-target.json
> +++ b/qapi/machine-target.json
> @@ -285,6 +285,10 @@
>  #in the VM configuration, because aliases may stop being
>  #migration-safe in the future (since 4.1)
>  #
> +# @deprecated: If true, this CPU model is deprecated and may be
> removed in
> +#  in some future version of QEMU according to the QEMU
> deprecation
> +#  policy. (since 5.1)
> +#
>  # @unavailable-features is a list of QOM property names that
>  # represent CPU model attributes that prevent the CPU from running.
>  # If the QOM property is read-only, that means there's no known
> @@ -309,7 +313,8 @@
>  'static': 'bool',
>  '*unavailable-features': [ 'str' ],
>  'typename': 'str',
> -'*alias-of' : 'str' },
> +'*alias-of' : 'str',
> +'deprecated' : 'bool' },
>'if': 'defined(TARGET_PPC) || defined(TARGET_ARM) ||
> defined(TARGET_I386) || defined(TARGET_S390X) ||
> defined(TARGET_MIPS)' }
>  
>  ##
> diff --git a/target/i386/cpu.c b/target/i386/cpu.c
> index ba05da3..0d8638a 100644
> --- a/target/i386/cpu.c
> +++ b/target/i386/cpu.c
> @@ -1599,6 +1599,7 @@ typedef struct X86CPUVersionDefinition {
>  const char *alias;
>  const char *note;
>  PropValue *props;
> +bool   deprecated;
>  } X86CPU

[PATCH v2 2/2] Mark Icelake-Client CPU models deprecated

2020-06-10 Thread Robert Hoo
Going to obsolete Icelake-Client CPU models in the future.

(No changes in v2)

Signed-off-by: Robert Hoo 
---
 target/i386/cpu.c | 10 +-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index 0d8638a..47a11b5 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -3350,7 +3350,12 @@ static X86CPUDefinition builtin_x86_defs[] = {
 .xlevel = 0x8008,
 .model_id = "Intel Core Processor (Icelake)",
 .versions = (X86CPUVersionDefinition[]) {
-{ .version = 1 },
+{
+.version = 1,
+.deprecated = true,
+.note = "Deprecated. Will be obsoleted in v5.1. Please use "
+"'Icelake-Server-v1' CPU model",
+},
 {
 .version = 2,
 .alias = "Icelake-Client-noTSX",
@@ -3359,6 +3364,9 @@ static X86CPUDefinition builtin_x86_defs[] = {
 { "rtm", "off" },
 { /* end of list */ }
 },
+.deprecated = true,
+.note = "Deprecated. Will be obsoleted in v5.1. Please use "
+"'Icelake-Server-v2' CPU model",
 },
 { /* end of list */ }
 }
-- 
1.8.3.1




[PATCH v2 1/2] Introduce (x86) CPU model deprecation API

2020-06-10 Thread Robert Hoo
Complement versioned CPU model framework with the ability of marking some
versions deprecated. When that CPU model is chosen, get some warning. The
warning message is customized, e.g. telling in which future QEMU version will
it be obsoleted.
The deprecation message will also appear by x86_cpu_list_entry(), e.g. '-cpu
help'.
QMP 'query-cpu-definitions' will also return a bool value indicating the
deprecation status.

Changes in v2:
Move deprecation check from parse_cpu_option() to machine_run_board_init(), so
that it can cover implicit cpu_type assignment cases.
Add qapi new member documentation. Thanks Eric for comment and guidance on qapi.

Signed-off-by: Robert Hoo 
---
 hw/core/machine.c| 11 +--
 include/hw/core/cpu.h|  1 +
 qapi/machine-target.json |  7 ++-
 target/i386/cpu.c| 45 +++--
 4 files changed, 59 insertions(+), 5 deletions(-)

diff --git a/hw/core/machine.c b/hw/core/machine.c
index bb3a7b1..9318964 100644
--- a/hw/core/machine.c
+++ b/hw/core/machine.c
@@ -1083,6 +1083,8 @@ MemoryRegion *machine_consume_memdev(MachineState 
*machine,
 void machine_run_board_init(MachineState *machine)
 {
 MachineClass *machine_class = MACHINE_GET_CLASS(machine);
+ObjectClass *oc = object_class_by_name(machine->cpu_type);
+CPUClass *cc;
 
 if (machine->ram_memdev_id) {
 Object *o;
@@ -1102,11 +1104,10 @@ void machine_run_board_init(MachineState *machine)
  * specified a CPU with -cpu check here that the user CPU is supported.
  */
 if (machine_class->valid_cpu_types && machine->cpu_type) {
-ObjectClass *class = object_class_by_name(machine->cpu_type);
 int i;
 
 for (i = 0; machine_class->valid_cpu_types[i]; i++) {
-if (object_class_dynamic_cast(class,
+if (object_class_dynamic_cast(oc,
   machine_class->valid_cpu_types[i])) {
 /* The user specificed CPU is in the valid field, we are
  * good to go.
@@ -1129,6 +1130,12 @@ void machine_run_board_init(MachineState *machine)
 }
 }
 
+/* Check if CPU type is deprecated and warn if so */
+cc = CPU_CLASS(oc);
+if (cc->deprecation_check) {
+cc->deprecation_check(oc);
+}
+
 machine_class->init(machine);
 }
 
diff --git a/include/hw/core/cpu.h b/include/hw/core/cpu.h
index 497600c..1ca47dc 100644
--- a/include/hw/core/cpu.h
+++ b/include/hw/core/cpu.h
@@ -218,6 +218,7 @@ typedef struct CPUClass {
 void (*disas_set_info)(CPUState *cpu, disassemble_info *info);
 vaddr (*adjust_watchpoint_address)(CPUState *cpu, vaddr addr, int len);
 void (*tcg_initialize)(void);
+void (*deprecation_check)(ObjectClass *oc);
 
 /* Keep non-pointer data at the end to minimize holes.  */
 int gdb_num_core_regs;
diff --git a/qapi/machine-target.json b/qapi/machine-target.json
index f2c8294..c24f506 100644
--- a/qapi/machine-target.json
+++ b/qapi/machine-target.json
@@ -285,6 +285,10 @@
 #in the VM configuration, because aliases may stop being
 #migration-safe in the future (since 4.1)
 #
+# @deprecated: If true, this CPU model is deprecated and may be removed in
+#  in some future version of QEMU according to the QEMU deprecation
+#  policy. (since 5.1)
+#
 # @unavailable-features is a list of QOM property names that
 # represent CPU model attributes that prevent the CPU from running.
 # If the QOM property is read-only, that means there's no known
@@ -309,7 +313,8 @@
 'static': 'bool',
 '*unavailable-features': [ 'str' ],
 'typename': 'str',
-'*alias-of' : 'str' },
+'*alias-of' : 'str',
+'deprecated' : 'bool' },
   'if': 'defined(TARGET_PPC) || defined(TARGET_ARM) || defined(TARGET_I386) || 
defined(TARGET_S390X) || defined(TARGET_MIPS)' }
 
 ##
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index ba05da3..0d8638a 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -1599,6 +1599,7 @@ typedef struct X86CPUVersionDefinition {
 const char *alias;
 const char *note;
 PropValue *props;
+bool   deprecated;
 } X86CPUVersionDefinition;
 
 /* Base definition for a CPU model */
@@ -1638,6 +1639,11 @@ struct X86CPUModel {
  * This matters only for "-cpu help" and query-cpu-definitions
  */
 bool is_alias;
+/*
+ * If true, this model is deprecated, and may be removed in the future.
+ * Trying to use it now will cause a warning.
+ */
+bool deprecated;
 };
 
 /* Get full model name for CPU version */
@@ -4128,8 +4134,7 @@ static X86CPUVersion x86_cpu_model_resolve_version(const 
X86CPUModel *model)
 X86CPUVersion v = model->version;
 if (v == CPU_VERSION_AUTO) {
 v = default_cpu_version;
-}
-if (v == CPU_VERSION_LATEST) {
+} else if (v == CPU_VERSION_LATEST)

Re: [PATCH 1/2] Introduce (x86) CPU model deprecation API

2020-06-05 Thread Robert Hoo
On Fri, 2020-06-05 at 08:47 -0500, Eric Blake wrote:
> On 6/4/20 9:47 PM, Robert Hoo wrote:
> > On Thu, 2020-06-04 at 06:59 -0500, Eric Blake wrote:
> > > On 6/4/20 3:07 AM, Robert Hoo wrote:
> > > 
> > > > > > +++ b/qapi/machine-target.json
> > > > > > @@ -309,7 +309,8 @@
> > > > > > 'static': 'bool',
> > > > > > '*unavailable-features': [ 'str' ],
> > > > > > 'typename': 'str',
> > > > > > -'*alias-of' : 'str' },
> > > > > > +'*alias-of' : 'str',
> > > > > > +'deprecated' : 'bool' },
> > > > > 
> > > > > Missing documentation of the new member.  Should it be
> > > > > optional
> > > > > (present
> > > > > only when true)?
> > > > 
> > > > Which document do you mean?
> > 
> > Thanks Eric:)
> > 
> > > 
> > > A few lines earlier is '@alias-of: ...'; you'll need to add a
> > > similar
> > > line for '@deprecated', mentioning it is '(since 5.1)'.
> > > 
> > > > How to make it optional?
> > 
> > How about not making it optional? refer to Machineinfo::deprecated.
> 
> Always providing it doesn't hurt.  If there is precedence for not
> making 
> it optional, mentioning that precedence in the commit message can't
> hurt.

No specific precedence. Just feel a little weird that adding an
additional boolean, just for judging another boolean should present or
not. esp. given that Machineinfo::deprecated is not optional.
> 




Re: [PATCH 1/2] Introduce (x86) CPU model deprecation API

2020-06-04 Thread Robert Hoo
On Thu, 2020-06-04 at 06:59 -0500, Eric Blake wrote:
> On 6/4/20 3:07 AM, Robert Hoo wrote:
> 
> > > > +++ b/qapi/machine-target.json
> > > > @@ -309,7 +309,8 @@
> > > >'static': 'bool',
> > > >'*unavailable-features': [ 'str' ],
> > > >'typename': 'str',
> > > > -'*alias-of' : 'str' },
> > > > +'*alias-of' : 'str',
> > > > +'deprecated' : 'bool' },
> > > 
> > > Missing documentation of the new member.  Should it be optional
> > > (present
> > > only when true)?
> > 
> > Which document do you mean?

Thanks Eric:)

> 
> A few lines earlier is '@alias-of: ...'; you'll need to add a
> similar 
> line for '@deprecated', mentioning it is '(since 5.1)'.
> 
> > How to make it optional?

How about not making it optional? refer to Machineinfo::deprecated.
> 
> Name it '*deprecated', then deal with 'has_deprecated' in the C code
> for 
> the cases where the member should be output.
> 




Re: [PATCH 1/2] Introduce (x86) CPU model deprecation API

2020-06-04 Thread Robert Hoo
On Wed, 2020-06-03 at 09:11 -0500, Eric Blake wrote:
> On 6/3/20 6:47 AM, Robert Hoo wrote:
> > Complement versioned CPU model framework with the ability of
> > marking some
> > versions deprecated. When that CPU model is chosen, get some
> > warning. The
> > warning message is customized, e.g. telling in which future QEMU
> > version will
> > it be obsoleted.
> > The deprecation message will also appear by x86_cpu_list_entry(),
> > e.g. '-cpu
> > help'.
> > QMP 'query-cpu-definitions' will also return a bool value
> > indicating the
> > deprecation status.
> > 
> > Signed-off-by: Robert Hoo 
> > ---
> >   exec.c   |  3 +++
> >   include/hw/core/cpu.h|  1 +
> >   qapi/machine-target.json |  3 ++-
> >   target/i386/cpu.c| 45
> > +++--
> >   4 files changed, 49 insertions(+), 3 deletions(-)
> > +++ b/qapi/machine-target.json
> > @@ -309,7 +309,8 @@
> >   'static': 'bool',
> >   '*unavailable-features': [ 'str' ],
> >   'typename': 'str',
> > -'*alias-of' : 'str' },
> > +'*alias-of' : 'str',
> > +'deprecated' : 'bool' },
> 
> Missing documentation of the new member.  Should it be optional
> (present 
> only when true)?
Which document do you mean?
How to make it optional?
(Sorry, new to QMP)
> 
> > @@ -1638,6 +1639,11 @@ struct X86CPUModel {
> >* This matters only for "-cpu help" and query-cpu-
> > definitions
> >*/
> >   bool is_alias;
> > +/*
> > + * If true, this is deprecated and obsoleted in the future.
> > + * Trying to use deprecated CPU model shall be warned.
> 
> If true, this model is deprecated, and may be removed in the future. 
> Trying to use it now will cause a warning.
Thanks Eric:)
> 
> > + */
> > +bool deprecated;
> >   };
> >   
> 
> 




[PATCH 1/2] Introduce (x86) CPU model deprecation API

2020-06-03 Thread Robert Hoo
Complement versioned CPU model framework with the ability of marking some
versions deprecated. When that CPU model is chosen, get some warning. The
warning message is customized, e.g. telling in which future QEMU version will
it be obsoleted.
The deprecation message will also appear by x86_cpu_list_entry(), e.g. '-cpu
help'.
QMP 'query-cpu-definitions' will also return a bool value indicating the
deprecation status.

Signed-off-by: Robert Hoo 
---
 exec.c   |  3 +++
 include/hw/core/cpu.h|  1 +
 qapi/machine-target.json |  3 ++-
 target/i386/cpu.c| 45 +++--
 4 files changed, 49 insertions(+), 3 deletions(-)

diff --git a/exec.c b/exec.c
index 5162f0d..a403937 100644
--- a/exec.c
+++ b/exec.c
@@ -981,6 +981,9 @@ const char *parse_cpu_option(const char *cpu_option)
 cpu_type = object_class_get_name(oc);
 cc = CPU_CLASS(oc);
 cc->parse_features(cpu_type, model_pieces[1], _fatal);
+if (cc->deprecation_check) {
+cc->deprecation_check(oc);
+}
 g_strfreev(model_pieces);
 return cpu_type;
 }
diff --git a/include/hw/core/cpu.h b/include/hw/core/cpu.h
index 07f7698..b2df186 100644
--- a/include/hw/core/cpu.h
+++ b/include/hw/core/cpu.h
@@ -218,6 +218,7 @@ typedef struct CPUClass {
 void (*disas_set_info)(CPUState *cpu, disassemble_info *info);
 vaddr (*adjust_watchpoint_address)(CPUState *cpu, vaddr addr, int len);
 void (*tcg_initialize)(void);
+void (*deprecation_check)(ObjectClass *oc);
 
 /* Keep non-pointer data at the end to minimize holes.  */
 int gdb_num_core_regs;
diff --git a/qapi/machine-target.json b/qapi/machine-target.json
index f2c8294..2e7db97 100644
--- a/qapi/machine-target.json
+++ b/qapi/machine-target.json
@@ -309,7 +309,8 @@
 'static': 'bool',
 '*unavailable-features': [ 'str' ],
 'typename': 'str',
-'*alias-of' : 'str' },
+'*alias-of' : 'str',
+'deprecated' : 'bool' },
   'if': 'defined(TARGET_PPC) || defined(TARGET_ARM) || defined(TARGET_I386) || 
defined(TARGET_S390X) || defined(TARGET_MIPS)' }
 
 ##
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index 3733d9a..d7ac22f 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -1599,6 +1599,7 @@ typedef struct X86CPUVersionDefinition {
 const char *alias;
 const char *note;
 PropValue *props;
+bool   deprecated;
 } X86CPUVersionDefinition;
 
 /* Base definition for a CPU model */
@@ -1638,6 +1639,11 @@ struct X86CPUModel {
  * This matters only for "-cpu help" and query-cpu-definitions
  */
 bool is_alias;
+/*
+ * If true, this is deprecated and obsoleted in the future.
+ * Trying to use deprecated CPU model shall be warned.
+ */
+bool deprecated;
 };
 
 /* Get full model name for CPU version */
@@ -4128,8 +4134,7 @@ static X86CPUVersion x86_cpu_model_resolve_version(const 
X86CPUModel *model)
 X86CPUVersion v = model->version;
 if (v == CPU_VERSION_AUTO) {
 v = default_cpu_version;
-}
-if (v == CPU_VERSION_LATEST) {
+} else if (v == CPU_VERSION_LATEST) {
 return x86_cpu_model_last_version(model);
 }
 return v;
@@ -4975,6 +4980,7 @@ static void x86_cpu_definition_entry(gpointer data, 
gpointer user_data)
 info->migration_safe = cc->migration_safe;
 info->has_migration_safe = true;
 info->q_static = cc->static_model;
+info->deprecated = cc->model ? cc->model->deprecated : false;
 /*
  * Old machine types won't report aliases, so that alias translation
  * doesn't break compatibility with previous QEMU versions.
@@ -5411,6 +5417,7 @@ static void x86_register_cpudef_types(X86CPUDefinition 
*def)
 m->cpudef = def;
 m->version = vdef->version;
 m->note = vdef->note;
+m->deprecated = vdef->deprecated;
 x86_register_cpu_model_type(name, m);
 
 if (vdef->alias) {
@@ -5418,6 +5425,8 @@ static void x86_register_cpudef_types(X86CPUDefinition 
*def)
 am->cpudef = def;
 am->version = vdef->version;
 am->is_alias = true;
+am->note = vdef->note;
+am->deprecated = vdef->deprecated;
 x86_register_cpu_model_type(vdef->alias, am);
 }
 }
@@ -7229,6 +7238,37 @@ static Property x86_cpu_properties[] = {
 DEFINE_PROP_END_OF_LIST()
 };
 
+static void x86_cpu_deprecation_check(ObjectClass *oc)
+{
+X86CPUClass *xcc = X86_CPU_CLASS(oc);
+X86CPUVersion effective_version;
+const X86CPUVersionDefinition *vdef;
+
+if (xcc->model == NULL) {
+return;
+}
+
+if (xcc->model->version == CPU_VERSION_LEGACY) {
+/* Treat legacy version as v1 */
+effective_version = 1;
+} else {
+effective_version = x86_cpu_model_resolve_version(xcc->model);
+}
+
+

[PATCH 2/2] Mark Icelake-Client CPU models deprecated

2020-06-03 Thread Robert Hoo
Going to obsolete Icelake-Client CPU models in the future.

Signed-off-by: Robert Hoo 
---
 target/i386/cpu.c | 10 +-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index d7ac22f..6c34ea3 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -3350,7 +3350,12 @@ static X86CPUDefinition builtin_x86_defs[] = {
 .xlevel = 0x8008,
 .model_id = "Intel Core Processor (Icelake)",
 .versions = (X86CPUVersionDefinition[]) {
-{ .version = 1 },
+{
+.version = 1,
+.deprecated = true,
+.note = "Deprecated. Will be obsoleted in v5.1. Please use "
+"'Icelake-Server-v1' CPU model",
+},
 {
 .version = 2,
 .alias = "Icelake-Client-noTSX",
@@ -3359,6 +3364,9 @@ static X86CPUDefinition builtin_x86_defs[] = {
 { "rtm", "off" },
 { /* end of list */ }
 },
+.deprecated = true,
+.note = "Deprecated. Will be obsoleted in v5.1. Please use "
+"'Icelake-Server-v2' CPU model",
 },
 { /* end of list */ }
 }
-- 
1.8.3.1




Re: [PATCH v4 5/5] target/i386: remove Icelake-Client CPU model

2020-05-20 Thread Robert Hoo
On Wed, 2020-05-20 at 10:17 +0100, Daniel P. Berrangé wrote:
> On Wed, May 20, 2020 at 10:10:07AM +0800, Chenyi Qiang wrote:
> > There are no Icelake Desktop products in the market. Remove the
> > Icelake-Client CPU model.
> 
> QEMU has been shipping this CPU model for 2 years now. Regardless
> of what CPUs Intel are selling, it is possible for users to be
> running VMs with Icelake-Client CPU if their host satisfies the
> listed features. So I don't think it is valid to remove this.
> 
This 'Icelake-Client' actually doesn't exist. How do we define its
feature list? and who will be using it? If any special feature tailor
requirement, it can be simply achieved by '-cpu Icelake,+/-' features,
this is the correct way.

I think we should remove it. When we realize something's not correct,
we should fix it ASAP. Leaving it there will only cause more serious
issue in the future.

> Regards,
> Daniel




Re: [PATCH v2 3/4] target/i386: add the missing features for Icelake-Server CPU model

2020-03-31 Thread Robert Hoo
On Sat, 2020-03-28 at 11:06 +0800, Chenyi Qiang wrote:
> Add the SHA_NI and AVX512IFMA feature bits in FEAT_7_0_EBX, RDPID
> feature bit in FEAT_7_0_ECX and FSRM feature bit in FEAT_7_0_EDX.
> 
> Signed-off-by: Chenyi Qiang 
> ---
>  target/i386/cpu.c | 10 ++
>  1 file changed, 10 insertions(+)
> 
> diff --git a/target/i386/cpu.c b/target/i386/cpu.c
> index b01421c6bb..babb074abf 100644
> --- a/target/i386/cpu.c
> +++ b/target/i386/cpu.c
> @@ -3552,6 +3552,16 @@ static X86CPUDefinition builtin_x86_defs[] = {
>  { /* end of list */ }
>  },
>  },
> +{
> +.version = 3,
> +.props = (PropValue[]) {
> +{ "sha-ni", "on" },
> +{ "avx512ifma", "on" },
> +{ "rdpid", "on" },
> +{ "fsrm", "on" },
> +{ /* end of list */ }
> +},
> +},
>  { /* end of list */ }
I think these 4 new CPUIDs addition is to catch up latest 
https://software.intel.com/sites/default/files/managed/c5/15/architecture-instruction-set-extensions-programming-reference.pdf
 on updates.
This is actually fix to previous v1 definitions.
So my 2 cents:
1. add 1 more version: include v2's hle and rtm properties off
2. make the hle-rtm-disable inclusion version or this v3 default
version of icelake.
Anyway, v1 is not suitable for default choice.

Then questions comes to how to make non-v1 default.
Perhaps:

diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index 34b511f..d4eb3d6 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -5453,7 +5453,7 @@ static void
x86_register_cpudef_types(X86CPUDefinition *def)
 /* Unversioned model: */
 m = g_new0(X86CPUModel, 1);
 m->cpudef = def;
-m->version = CPU_VERSION_AUTO;
+m->version = CPU_VERSION_LATEST;
 m->is_alias = true;
 x86_register_cpu_model_type(def->name, m);

I think for builtin_x86_defs[] definitions, latest version is usually
preferable/suitable.
How would Paolo, Eduardo like it?
>  }
>  },




Re: [PATCH 2/2] util/bufferiszero: improve avx2 accelerator

2020-03-26 Thread Robert Hoo
On Thu, 2020-03-26 at 08:26 -0500, Eric Blake wrote:
> On 3/25/20 9:09 PM, Hu, Robert wrote:
> > (Don't know why my Linux-Evolution missed this mail.)
> > > -Original Message-
> > > Long line; it's nice to wrap commit messages around column 70 or
> > > so (because
> > > reading 'git log' in an 80-column window adds indentation).
> > > 
> > 
> > [Hu, Robert]
> > I think I set my vim on wrap. This probably escaped by paste.
> > I ran checkpatch.pl on the patches before sending. It escaped check
> > but didn't
> > escaped your eagle eye Thank you.
> 
> checkpatch doesn't flag commit message long lines.  Maybe it could
> be 
> patched to do so, but it's not at the top of my list to write that
> patch.
> 
> > 
> > > > I just fix a boudary case on his original patch.
> > > 
> > > boundary
> > 
> > [Hu, Robert]
> > Emm... again spell error. Usually I would paste descriptions into
> > some editors
> > with spell check, but forgot this time.
> > Vim doesn't have spell check I think. What editor would you suggest
> > me to
> > integrate with git editing?
> 
> I'm an emacs user, so I have no suggestions for vim, but I'd be very 
> surprised if there were not some vim expert online that could figure
> out 
> how to wire in a spell-checker to vim.  Google quickly finds: 
> https://www.ostechnix.com/use-spell-check-feature-vim-text-editor/
> 
nice, thanks:)




[PATCH 2/2] util/bufferiszero: improve avx2 accelerator

2020-03-25 Thread Robert Hoo
By increasing avx2 length_to_accel to 128, we can simplify its logic and reduce 
a
branch.

The authorship of this patch actually belongs to Richard Henderson 
,
I just fix a boudary case on his original patch.

Suggested-by: Richard Henderson 
Signed-off-by: Robert Hoo 
---
 util/bufferiszero.c | 26 +-
 1 file changed, 9 insertions(+), 17 deletions(-)

diff --git a/util/bufferiszero.c b/util/bufferiszero.c
index b801253..695bb4c 100644
--- a/util/bufferiszero.c
+++ b/util/bufferiszero.c
@@ -158,27 +158,19 @@ buffer_zero_avx2(const void *buf, size_t len)
 __m256i *p = (__m256i *)(((uintptr_t)buf + 5 * 32) & -32);
 __m256i *e = (__m256i *)(((uintptr_t)buf + len) & -32);
 
-if (likely(p <= e)) {
-/* Loop over 32-byte aligned blocks of 128.  */
-do {
-__builtin_prefetch(p);
-if (unlikely(!_mm256_testz_si256(t, t))) {
-return false;
-}
-t = p[-4] | p[-3] | p[-2] | p[-1];
-p += 4;
-} while (p <= e);
-} else {
-t |= _mm256_loadu_si256(buf + 32);
-if (len <= 128) {
-goto last2;
+/* Loop over 32-byte aligned blocks of 128.  */
+while (p <= e) {
+__builtin_prefetch(p);
+if (unlikely(!_mm256_testz_si256(t, t))) {
+return false;
 }
-}
+t = p[-4] | p[-3] | p[-2] | p[-1];
+p += 4;
+} ;
 
 /* Finish the last block of 128 unaligned.  */
 t |= _mm256_loadu_si256(buf + len - 4 * 32);
 t |= _mm256_loadu_si256(buf + len - 3 * 32);
- last2:
 t |= _mm256_loadu_si256(buf + len - 2 * 32);
 t |= _mm256_loadu_si256(buf + len - 1 * 32);
 
@@ -263,7 +255,7 @@ static void init_accel(unsigned cache)
 }
 if (cache & CACHE_AVX2) {
 fn = buffer_zero_avx2;
-length_to_accel = 64;
+length_to_accel = 128;
 }
 #endif
 #ifdef CONFIG_AVX512F_OPT
-- 
1.8.3.1




[PATCH 1/2] util/bufferiszero: assign length_to_accel value for each accelerator case

2020-03-25 Thread Robert Hoo
Because in unit test, init_accel() will be called several times, each with
different accelerator type.

Signed-off-by: Robert Hoo 
---
 util/bufferiszero.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/util/bufferiszero.c b/util/bufferiszero.c
index 6639035..b801253 100644
--- a/util/bufferiszero.c
+++ b/util/bufferiszero.c
@@ -254,13 +254,16 @@ static void init_accel(unsigned cache)
 bool (*fn)(const void *, size_t) = buffer_zero_int;
 if (cache & CACHE_SSE2) {
 fn = buffer_zero_sse2;
+length_to_accel = 64;
 }
 #ifdef CONFIG_AVX2_OPT
 if (cache & CACHE_SSE4) {
 fn = buffer_zero_sse4;
+length_to_accel = 64;
 }
 if (cache & CACHE_AVX2) {
 fn = buffer_zero_avx2;
+length_to_accel = 64;
 }
 #endif
 #ifdef CONFIG_AVX512F_OPT
-- 
1.8.3.1




[PATCH v4 1/2] configure: add configure option avx512f_opt

2020-02-29 Thread Robert Hoo
If it is enabled, config-host.mak will have CONFIG_AVX512F_OPT defined.

AVX512F instruction set is available since Intel Skylake, and can be enabled in
compiling with -mavx512f.
More info:
https://software.intel.com/sites/default/files/managed/c5/15/architecture-instruction-set-extensions-programming-reference.pdf

Signed-off-by: Robert Hoo 
Reviewed-by: Richard Henderson 
---
 configure | 41 +
 1 file changed, 41 insertions(+)

diff --git a/configure b/configure
index d57261e..a0b41ce 100755
--- a/configure
+++ b/configure
@@ -1395,6 +1395,11 @@ for opt do
   ;;
   --enable-avx2) avx2_opt="yes"
   ;;
+  --disable-avx512f) avx512f_opt="no"
+  ;;
+  --enable-avx512f) avx512f_opt="yes"
+  ;;
+
   --enable-glusterfs) glusterfs="yes"
   ;;
   --disable-virtio-blk-data-plane|--enable-virtio-blk-data-plane)
@@ -1825,6 +1830,7 @@ disabled with --disable-FEATURE, default is enabled if 
available:
   tcmalloctcmalloc support
   jemallocjemalloc support
   avx2AVX2 optimization support
+  avx512f AVX512F optimization support
   replication replication support
   opengl  opengl support
   virglrenderer   virgl rendering support
@@ -5518,6 +5524,36 @@ EOF
   fi
 fi
 
+##
+# avx512f optimization requirement check
+#
+# There is no point enabling this if cpuid.h is not usable,
+# since we won't be able to select the new routines.
+# by default, it is turned off.
+# if user explicitly want to enable it, check environment
+
+if test "$cpuid_h" = "yes" && test "$avx512f_opt" = "yes"; then
+  cat > $TMPC << EOF
+#pragma GCC push_options
+#pragma GCC target("avx512f")
+#include 
+#include 
+static int bar(void *a) {
+__m512i x = *(__m512i *)a;
+return _mm512_test_epi64_mask(x, x);
+}
+int main(int argc, char *argv[])
+{
+   return bar(argv[0]);
+}
+EOF
+  if ! compile_object "" ; then
+avx512f_opt="no"
+  fi
+else
+  avx512f_opt="no"
+fi
+
 
 # check if __[u]int128_t is usable.
 
@@ -6650,6 +6686,7 @@ echo "libxml2   $libxml2"
 echo "tcmalloc support  $tcmalloc"
 echo "jemalloc support  $jemalloc"
 echo "avx2 optimization $avx2_opt"
+echo "avx512f optimization $avx512f_opt"
 echo "replication support $replication"
 echo "VxHS block device $vxhs"
 echo "bochs support $bochs"
@@ -7200,6 +7237,10 @@ if test "$avx2_opt" = "yes" ; then
   echo "CONFIG_AVX2_OPT=y" >> $config_host_mak
 fi
 
+if test "$avx512f_opt" = "yes" ; then
+  echo "CONFIG_AVX512F_OPT=y" >> $config_host_mak
+fi
+
 if test "$lzo" = "yes" ; then
   echo "CONFIG_LZO=y" >> $config_host_mak
 fi
-- 
1.8.3.1




[PATCH v4 0/2] Add AVX512F optimization option and buffer_zero_avx512()

2020-02-29 Thread Robert Hoo
1) Introduce {enable,disable}-avx512f configure option

2) Implement new buffer_zero_avx512() with AVX512F instructions

Changes in v4:
In init_cpuid_cache(), stringently test AVX512F OS level enablement.

Changes in v3:
In init_accel(), init length_to_accel value in every accel case, because
in unit test, it will be invoked several times with different accel cases.
(Thanks Richard's careful review)

Changes in v2:
1. Fixes wrong definition of CACHE_SSE2 in v1.
2. Fixes not handle <256 length case in buffer_zero_avx512() implementaion.
(Follow Richard's suggestion: handle the case in select_accel_fn(), and have a
global variable alongside buffer_accel)
3. Changes avx512f configuration option's default status to disabled.
4. Ran 'make check-unit' on this patch, on both a Ivybridge machine and a
CascadeLake machine.


Robert Hoo (2):
  configure: add configure option avx512f_opt
  util: add util function buffer_zero_avx512()

 configure| 41 +
 include/qemu/cpuid.h |  3 +++
 util/bufferiszero.c  | 74 +---
 3 files changed, 108 insertions(+), 10 deletions(-)

-- 
1.8.3.1




[PATCH v4 2/2] util: add util function buffer_zero_avx512()

2020-02-29 Thread Robert Hoo
And intialize buffer_is_zero() with it, when Intel AVX512F is
available on host.

This function utilizes Intel AVX512 fundamental instructions which
is faster than its implementation with AVX2 (in my unit test, with
4K buffer, on CascadeLake SP, ~36% faster, buffer_zero_avx512() V.S.
buffer_zero_avx2()).

Signed-off-by: Robert Hoo 
---
 include/qemu/cpuid.h |  3 +++
 util/bufferiszero.c  | 74 +---
 2 files changed, 67 insertions(+), 10 deletions(-)

diff --git a/include/qemu/cpuid.h b/include/qemu/cpuid.h
index 6930170..09fc245 100644
--- a/include/qemu/cpuid.h
+++ b/include/qemu/cpuid.h
@@ -45,6 +45,9 @@
 #ifndef bit_AVX2
 #define bit_AVX2(1 << 5)
 #endif
+#ifndef bit_AVX512F
+#define bit_AVX512F(1 << 16)
+#endif
 #ifndef bit_BMI2
 #define bit_BMI2(1 << 8)
 #endif
diff --git a/util/bufferiszero.c b/util/bufferiszero.c
index bfb2605..b6eab0c 100644
--- a/util/bufferiszero.c
+++ b/util/bufferiszero.c
@@ -63,11 +63,11 @@ buffer_zero_int(const void *buf, size_t len)
 }
 }
 
-#if defined(CONFIG_AVX2_OPT) || defined(__SSE2__)
+#if defined(CONFIG_AVX512F_OPT) || defined(CONFIG_AVX2_OPT) || 
defined(__SSE2__)
 /* Do not use push_options pragmas unnecessarily, because clang
  * does not support them.
  */
-#ifdef CONFIG_AVX2_OPT
+#if defined(CONFIG_AVX512F_OPT) || defined(CONFIG_AVX2_OPT)
 #pragma GCC push_options
 #pragma GCC target("sse2")
 #endif
@@ -104,7 +104,7 @@ buffer_zero_sse2(const void *buf, size_t len)
 
 return _mm_movemask_epi8(_mm_cmpeq_epi8(t, zero)) == 0x;
 }
-#ifdef CONFIG_AVX2_OPT
+#if defined(CONFIG_AVX512F_OPT) || defined(CONFIG_AVX2_OPT)
 #pragma GCC pop_options
 #endif
 
@@ -187,18 +187,54 @@ buffer_zero_avx2(const void *buf, size_t len)
 #pragma GCC pop_options
 #endif /* CONFIG_AVX2_OPT */
 
+#ifdef CONFIG_AVX512F_OPT
+#pragma GCC push_options
+#pragma GCC target("avx512f")
+#include 
+
+static bool
+buffer_zero_avx512(const void *buf, size_t len)
+{
+/* Begin with an unaligned head of 64 bytes.  */
+__m512i t = _mm512_loadu_si512(buf);
+__m512i *p = (__m512i *)(((uintptr_t)buf + 5 * 64) & -64);
+__m512i *e = (__m512i *)(((uintptr_t)buf + len) & -64);
+
+/* Loop over 64-byte aligned blocks of 256.  */
+while (p <= e) {
+__builtin_prefetch(p);
+if (unlikely(_mm512_test_epi64_mask(t, t))) {
+return false;
+}
+t = p[-4] | p[-3] | p[-2] | p[-1];
+p += 4;
+}
+
+t |= _mm512_loadu_si512(buf + len - 4 * 64);
+t |= _mm512_loadu_si512(buf + len - 3 * 64);
+t |= _mm512_loadu_si512(buf + len - 2 * 64);
+t |= _mm512_loadu_si512(buf + len - 1 * 64);
+
+return !_mm512_test_epi64_mask(t, t);
+
+}
+#pragma GCC pop_options
+#endif
+
+
 /* Note that for test_buffer_is_zero_next_accel, the most preferred
  * ISA must have the least significant bit.
  */
-#define CACHE_AVX21
-#define CACHE_SSE42
-#define CACHE_SSE24
+#define CACHE_AVX512F 1
+#define CACHE_AVX22
+#define CACHE_SSE44
+#define CACHE_SSE28
 
 /* Make sure that these variables are appropriately initialized when
  * SSE2 is enabled on the compiler command-line, but the compiler is
  * too old to support CONFIG_AVX2_OPT.
  */
-#ifdef CONFIG_AVX2_OPT
+#if defined(CONFIG_AVX512F_OPT) || defined(CONFIG_AVX2_OPT)
 # define INIT_CACHE 0
 # define INIT_ACCEL buffer_zero_int
 #else
@@ -211,25 +247,35 @@ buffer_zero_avx2(const void *buf, size_t len)
 
 static unsigned cpuid_cache = INIT_CACHE;
 static bool (*buffer_accel)(const void *, size_t) = INIT_ACCEL;
+static int length_to_accel;
 
 static void init_accel(unsigned cache)
 {
 bool (*fn)(const void *, size_t) = buffer_zero_int;
 if (cache & CACHE_SSE2) {
 fn = buffer_zero_sse2;
+length_to_accel = 64;
 }
 #ifdef CONFIG_AVX2_OPT
 if (cache & CACHE_SSE4) {
 fn = buffer_zero_sse4;
+length_to_accel = 64;
 }
 if (cache & CACHE_AVX2) {
 fn = buffer_zero_avx2;
+length_to_accel = 64;
+}
+#endif
+#ifdef CONFIG_AVX512F_OPT
+if (cache & CACHE_AVX512F) {
+fn = buffer_zero_avx512;
+length_to_accel = 256;
 }
 #endif
 buffer_accel = fn;
 }
 
-#ifdef CONFIG_AVX2_OPT
+#if defined(CONFIG_AVX512F_OPT) || defined(CONFIG_AVX2_OPT)
 #include "qemu/cpuid.h"
 
 static void __attribute__((constructor)) init_cpuid_cache(void)
@@ -252,9 +298,17 @@ static void __attribute__((constructor)) 
init_cpuid_cache(void)
 int bv;
 __asm("xgetbv" : "=a"(bv), "=d"(d) : "c"(0));
 __cpuid_count(7, 0, a, b, c, d);
-if ((bv & 6) == 6 && (b & bit_AVX2)) {
+if ((bv & 0x6) == 0x6 && (b & bit_AVX2)) {
 cache |= CACHE_AVX2;
 }
+/* 0xe6:
+*  XCR0[7:5] = 111b (OPMASK state, upper 256-bi

Re: [PATCH v3 2/2] util: add util function buffer_zero_avx512()

2020-02-28 Thread Robert Hoo
On Fri, 2020-02-28 at 18:09 -0800, Richard Henderson wrote:
> On 2/27/20 6:24 PM, Robert Hoo wrote:
> >  if ((bv & 6) == 6 && (b & bit_AVX2)) {
> >  cache |= CACHE_AVX2;
> >  }
> > +if ((bv & 6) == 6 && (b & bit_AVX512F)) {
> > +cache |= CACHE_AVX512F;
> > +}
> 
> Oh, one more thing I missed -- we have to ensure that the 512-bit
> registers are
> enabled.  I believe the minimum is bits 6 and 7 enabled (ZMM_Hi256,
> Hi16_ZMM),
> since we don't know that the compiler won't allocate registers from
> zmm16-31.
> 
> So: (bv & 0xc6) == 0xc6.
> 
> You'd be right that some comments would be helpful on these
> lines.  :-P
> 
Oh, right, thank you very much for remind.

SDM's recommended detection on AVX512F support procedure is
1. Detect CPUID.1:ECX.OSXSAVE[bit 27] = 1 (XGETBV enabled for
application use).
2. Execute XGETBV and verify that XCR0[7:5] = 111b (OPMASK state, upper
256-bit of ZMM0-ZMM15 and ZMM16-ZMM31 state are enabled by OS) and that
XCR0[2:1] = 11b (XMM state and YMM state are enabled by OS).
3. Detect CPUID.0x7.0:EBX.AVX512F[bit 16] = 1.

I'm going to send v4 to address this.

> With that,
> Reviewed-by: Richard Henderson 
> 
> 
> r~




[PATCH v3 2/2] util: add util function buffer_zero_avx512()

2020-02-27 Thread Robert Hoo
And intialize buffer_is_zero() with it, when Intel AVX512F is
available on host.

This function utilizes Intel AVX512 fundamental instructions which
is faster than its implementation with AVX2 (in my unit test, with
4K buffer, on CascadeLake SP, ~36% faster, buffer_zero_avx512() V.S.
buffer_zero_avx2()).

Signed-off-by: Robert Hoo 
---
 include/qemu/cpuid.h |  3 +++
 util/bufferiszero.c  | 67 +---
 2 files changed, 61 insertions(+), 9 deletions(-)

diff --git a/include/qemu/cpuid.h b/include/qemu/cpuid.h
index 6930170..09fc245 100644
--- a/include/qemu/cpuid.h
+++ b/include/qemu/cpuid.h
@@ -45,6 +45,9 @@
 #ifndef bit_AVX2
 #define bit_AVX2(1 << 5)
 #endif
+#ifndef bit_AVX512F
+#define bit_AVX512F(1 << 16)
+#endif
 #ifndef bit_BMI2
 #define bit_BMI2(1 << 8)
 #endif
diff --git a/util/bufferiszero.c b/util/bufferiszero.c
index bfb2605..ce877b7 100644
--- a/util/bufferiszero.c
+++ b/util/bufferiszero.c
@@ -63,11 +63,11 @@ buffer_zero_int(const void *buf, size_t len)
 }
 }
 
-#if defined(CONFIG_AVX2_OPT) || defined(__SSE2__)
+#if defined(CONFIG_AVX512F_OPT) || defined(CONFIG_AVX2_OPT) || 
defined(__SSE2__)
 /* Do not use push_options pragmas unnecessarily, because clang
  * does not support them.
  */
-#ifdef CONFIG_AVX2_OPT
+#if defined(CONFIG_AVX512F_OPT) || defined(CONFIG_AVX2_OPT)
 #pragma GCC push_options
 #pragma GCC target("sse2")
 #endif
@@ -104,7 +104,7 @@ buffer_zero_sse2(const void *buf, size_t len)
 
 return _mm_movemask_epi8(_mm_cmpeq_epi8(t, zero)) == 0x;
 }
-#ifdef CONFIG_AVX2_OPT
+#if defined(CONFIG_AVX512F_OPT) || defined(CONFIG_AVX2_OPT)
 #pragma GCC pop_options
 #endif
 
@@ -187,18 +187,54 @@ buffer_zero_avx2(const void *buf, size_t len)
 #pragma GCC pop_options
 #endif /* CONFIG_AVX2_OPT */
 
+#ifdef CONFIG_AVX512F_OPT
+#pragma GCC push_options
+#pragma GCC target("avx512f")
+#include 
+
+static bool
+buffer_zero_avx512(const void *buf, size_t len)
+{
+/* Begin with an unaligned head of 64 bytes.  */
+__m512i t = _mm512_loadu_si512(buf);
+__m512i *p = (__m512i *)(((uintptr_t)buf + 5 * 64) & -64);
+__m512i *e = (__m512i *)(((uintptr_t)buf + len) & -64);
+
+/* Loop over 64-byte aligned blocks of 256.  */
+while (p <= e) {
+__builtin_prefetch(p);
+if (unlikely(_mm512_test_epi64_mask(t, t))) {
+return false;
+}
+t = p[-4] | p[-3] | p[-2] | p[-1];
+p += 4;
+}
+
+t |= _mm512_loadu_si512(buf + len - 4 * 64);
+t |= _mm512_loadu_si512(buf + len - 3 * 64);
+t |= _mm512_loadu_si512(buf + len - 2 * 64);
+t |= _mm512_loadu_si512(buf + len - 1 * 64);
+
+return !_mm512_test_epi64_mask(t, t);
+
+}
+#pragma GCC pop_options
+#endif
+
+
 /* Note that for test_buffer_is_zero_next_accel, the most preferred
  * ISA must have the least significant bit.
  */
-#define CACHE_AVX21
-#define CACHE_SSE42
-#define CACHE_SSE24
+#define CACHE_AVX512F 1
+#define CACHE_AVX22
+#define CACHE_SSE44
+#define CACHE_SSE28
 
 /* Make sure that these variables are appropriately initialized when
  * SSE2 is enabled on the compiler command-line, but the compiler is
  * too old to support CONFIG_AVX2_OPT.
  */
-#ifdef CONFIG_AVX2_OPT
+#if defined(CONFIG_AVX512F_OPT) || defined(CONFIG_AVX2_OPT)
 # define INIT_CACHE 0
 # define INIT_ACCEL buffer_zero_int
 #else
@@ -211,25 +247,35 @@ buffer_zero_avx2(const void *buf, size_t len)
 
 static unsigned cpuid_cache = INIT_CACHE;
 static bool (*buffer_accel)(const void *, size_t) = INIT_ACCEL;
+static int length_to_accel;
 
 static void init_accel(unsigned cache)
 {
 bool (*fn)(const void *, size_t) = buffer_zero_int;
 if (cache & CACHE_SSE2) {
 fn = buffer_zero_sse2;
+length_to_accel = 64;
 }
 #ifdef CONFIG_AVX2_OPT
 if (cache & CACHE_SSE4) {
 fn = buffer_zero_sse4;
+length_to_accel = 64;
 }
 if (cache & CACHE_AVX2) {
 fn = buffer_zero_avx2;
+length_to_accel = 64;
+}
+#endif
+#ifdef CONFIG_AVX512F_OPT
+if (cache & CACHE_AVX512F) {
+fn = buffer_zero_avx512;
+length_to_accel = 256;
 }
 #endif
 buffer_accel = fn;
 }
 
-#ifdef CONFIG_AVX2_OPT
+#if defined(CONFIG_AVX512F_OPT) || defined(CONFIG_AVX2_OPT)
 #include "qemu/cpuid.h"
 
 static void __attribute__((constructor)) init_cpuid_cache(void)
@@ -255,6 +301,9 @@ static void __attribute__((constructor)) 
init_cpuid_cache(void)
 if ((bv & 6) == 6 && (b & bit_AVX2)) {
 cache |= CACHE_AVX2;
 }
+if ((bv & 6) == 6 && (b & bit_AVX512F)) {
+cache |= CACHE_AVX512F;
+}
 }
 }
 cpuid_cache = cache;
@@ -277,7 +326,7 @@ bool test_buffer_is_zero_next_accel(void)
 
 static bool select_accel_fn(const void *buf, size_t len)
 {
-if (likely(len >

[PATCH v3 1/2] configure: add configure option avx512f_opt

2020-02-27 Thread Robert Hoo
If it is enabled, config-host.mak will have CONFIG_AVX512F_OPT defined.

AVX512F instruction set is available since Intel Skylake, and can be enabled in
compiling with -mavx512f.
More info:
https://software.intel.com/sites/default/files/managed/c5/15/architecture-instruction-set-extensions-programming-reference.pdf

Signed-off-by: Robert Hoo 
---
 configure | 41 +
 1 file changed, 41 insertions(+)

diff --git a/configure b/configure
index d57261e..a0b41ce 100755
--- a/configure
+++ b/configure
@@ -1395,6 +1395,11 @@ for opt do
   ;;
   --enable-avx2) avx2_opt="yes"
   ;;
+  --disable-avx512f) avx512f_opt="no"
+  ;;
+  --enable-avx512f) avx512f_opt="yes"
+  ;;
+
   --enable-glusterfs) glusterfs="yes"
   ;;
   --disable-virtio-blk-data-plane|--enable-virtio-blk-data-plane)
@@ -1825,6 +1830,7 @@ disabled with --disable-FEATURE, default is enabled if 
available:
   tcmalloctcmalloc support
   jemallocjemalloc support
   avx2AVX2 optimization support
+  avx512f AVX512F optimization support
   replication replication support
   opengl  opengl support
   virglrenderer   virgl rendering support
@@ -5518,6 +5524,36 @@ EOF
   fi
 fi
 
+##
+# avx512f optimization requirement check
+#
+# There is no point enabling this if cpuid.h is not usable,
+# since we won't be able to select the new routines.
+# by default, it is turned off.
+# if user explicitly want to enable it, check environment
+
+if test "$cpuid_h" = "yes" && test "$avx512f_opt" = "yes"; then
+  cat > $TMPC << EOF
+#pragma GCC push_options
+#pragma GCC target("avx512f")
+#include 
+#include 
+static int bar(void *a) {
+__m512i x = *(__m512i *)a;
+return _mm512_test_epi64_mask(x, x);
+}
+int main(int argc, char *argv[])
+{
+   return bar(argv[0]);
+}
+EOF
+  if ! compile_object "" ; then
+avx512f_opt="no"
+  fi
+else
+  avx512f_opt="no"
+fi
+
 
 # check if __[u]int128_t is usable.
 
@@ -6650,6 +6686,7 @@ echo "libxml2   $libxml2"
 echo "tcmalloc support  $tcmalloc"
 echo "jemalloc support  $jemalloc"
 echo "avx2 optimization $avx2_opt"
+echo "avx512f optimization $avx512f_opt"
 echo "replication support $replication"
 echo "VxHS block device $vxhs"
 echo "bochs support $bochs"
@@ -7200,6 +7237,10 @@ if test "$avx2_opt" = "yes" ; then
   echo "CONFIG_AVX2_OPT=y" >> $config_host_mak
 fi
 
+if test "$avx512f_opt" = "yes" ; then
+  echo "CONFIG_AVX512F_OPT=y" >> $config_host_mak
+fi
+
 if test "$lzo" = "yes" ; then
   echo "CONFIG_LZO=y" >> $config_host_mak
 fi
-- 
1.8.3.1




[PATCH v3 0/2] Add AVX512F optimization option and buffer_zero_avx512()

2020-02-27 Thread Robert Hoo
1) Introduce {enable,disable}-avx512f configure option

2) Implement new buffer_zero_avx512() with AVX512F instructions

Changes in v3:
In init_accel(), init length_to_accel value in every accel case, because
in unit test, it will be invoked several times with different accel cases.
(Thanks Richard's careful review)

Changes in v2:
1. Fixes wrong definition of CACHE_SSE2 in v1.
2. Fixes not handle <256 length case in buffer_zero_avx512() implementaion.
(Follow Richard's suggestion: handle the case in select_accel_fn(), and have a
global variable alongside buffer_accel)
3. Changes avx512f configuration option's default status to disabled.
4. Ran 'make check-unit' on this patch, on both a Ivybridge machine and a
CascadeLake machine.


Robert Hoo (2):
  configure: add configure option avx512f_opt
  util: add util function buffer_zero_avx512()

 configure| 41 
 include/qemu/cpuid.h |  3 +++
 util/bufferiszero.c  | 67 +---
 3 files changed, 102 insertions(+), 9 deletions(-)

-- 
1.8.3.1




[PATCH v2 2/2] util: add util function buffer_zero_avx512()

2020-02-25 Thread Robert Hoo
Intialize buffer_accel with this buffer_zero_avx512(), when Intel AVX512F is
available on host.

This function utilizes Intel AVX512 fundamental instructions which
is faster than its implementation with AVX2 (in my unit test, with
4K buffer, on CascadeLake SP, ~36% faster, buffer_zero_avx512() V.S.
buffer_zero_avx2()).

Signed-off-by: Robert Hoo 
---
 include/qemu/cpuid.h |  3 +++
 util/bufferiszero.c  | 64 
 2 files changed, 58 insertions(+), 9 deletions(-)

diff --git a/include/qemu/cpuid.h b/include/qemu/cpuid.h
index 6930170..09fc245 100644
--- a/include/qemu/cpuid.h
+++ b/include/qemu/cpuid.h
@@ -45,6 +45,9 @@
 #ifndef bit_AVX2
 #define bit_AVX2(1 << 5)
 #endif
+#ifndef bit_AVX512F
+#define bit_AVX512F(1 << 16)
+#endif
 #ifndef bit_BMI2
 #define bit_BMI2(1 << 8)
 #endif
diff --git a/util/bufferiszero.c b/util/bufferiszero.c
index bfb2605..2161628 100644
--- a/util/bufferiszero.c
+++ b/util/bufferiszero.c
@@ -63,11 +63,11 @@ buffer_zero_int(const void *buf, size_t len)
 }
 }
 
-#if defined(CONFIG_AVX2_OPT) || defined(__SSE2__)
+#if defined(CONFIG_AVX512F_OPT) || defined(CONFIG_AVX2_OPT) || 
defined(__SSE2__)
 /* Do not use push_options pragmas unnecessarily, because clang
  * does not support them.
  */
-#ifdef CONFIG_AVX2_OPT
+#if defined(CONFIG_AVX512F_OPT) || defined(CONFIG_AVX2_OPT)
 #pragma GCC push_options
 #pragma GCC target("sse2")
 #endif
@@ -104,7 +104,7 @@ buffer_zero_sse2(const void *buf, size_t len)
 
 return _mm_movemask_epi8(_mm_cmpeq_epi8(t, zero)) == 0x;
 }
-#ifdef CONFIG_AVX2_OPT
+#if defined(CONFIG_AVX512F_OPT) || defined(CONFIG_AVX2_OPT)
 #pragma GCC pop_options
 #endif
 
@@ -187,18 +187,54 @@ buffer_zero_avx2(const void *buf, size_t len)
 #pragma GCC pop_options
 #endif /* CONFIG_AVX2_OPT */
 
+#ifdef CONFIG_AVX512F_OPT
+#pragma GCC push_options
+#pragma GCC target("avx512f")
+#include 
+
+static bool
+buffer_zero_avx512(const void *buf, size_t len)
+{
+/* Begin with an unaligned head of 64 bytes.  */
+__m512i t = _mm512_loadu_si512(buf);
+__m512i *p = (__m512i *)(((uintptr_t)buf + 5 * 64) & -64);
+__m512i *e = (__m512i *)(((uintptr_t)buf + len) & -64);
+
+/* Loop over 64-byte aligned blocks of 256.  */
+while (p <= e) {
+__builtin_prefetch(p);
+if (unlikely(_mm512_test_epi64_mask(t, t))) {
+return false;
+}
+t = p[-4] | p[-3] | p[-2] | p[-1];
+p += 4;
+}
+
+t |= _mm512_loadu_si512(buf + len - 4 * 64);
+t |= _mm512_loadu_si512(buf + len - 3 * 64);
+t |= _mm512_loadu_si512(buf + len - 2 * 64);
+t |= _mm512_loadu_si512(buf + len - 1 * 64);
+
+return !_mm512_test_epi64_mask(t, t);
+
+}
+#pragma GCC pop_options
+#endif
+
+
 /* Note that for test_buffer_is_zero_next_accel, the most preferred
  * ISA must have the least significant bit.
  */
-#define CACHE_AVX21
-#define CACHE_SSE42
-#define CACHE_SSE24
+#define CACHE_AVX512F 1
+#define CACHE_AVX22
+#define CACHE_SSE44
+#define CACHE_SSE28
 
 /* Make sure that these variables are appropriately initialized when
  * SSE2 is enabled on the compiler command-line, but the compiler is
  * too old to support CONFIG_AVX2_OPT.
  */
-#ifdef CONFIG_AVX2_OPT
+#if defined(CONFIG_AVX512F_OPT) || defined(CONFIG_AVX2_OPT)
 # define INIT_CACHE 0
 # define INIT_ACCEL buffer_zero_int
 #else
@@ -211,6 +247,7 @@ buffer_zero_avx2(const void *buf, size_t len)
 
 static unsigned cpuid_cache = INIT_CACHE;
 static bool (*buffer_accel)(const void *, size_t) = INIT_ACCEL;
+static int length_to_accel = 64;
 
 static void init_accel(unsigned cache)
 {
@@ -226,10 +263,16 @@ static void init_accel(unsigned cache)
 fn = buffer_zero_avx2;
 }
 #endif
+#ifdef CONFIG_AVX512F_OPT
+if (cache & CACHE_AVX512F) {
+fn = buffer_zero_avx512;
+length_to_accel = 256;
+}
+#endif
 buffer_accel = fn;
 }
 
-#ifdef CONFIG_AVX2_OPT
+#if defined(CONFIG_AVX512F_OPT) || defined(CONFIG_AVX2_OPT)
 #include "qemu/cpuid.h"
 
 static void __attribute__((constructor)) init_cpuid_cache(void)
@@ -255,6 +298,9 @@ static void __attribute__((constructor)) 
init_cpuid_cache(void)
 if ((bv & 6) == 6 && (b & bit_AVX2)) {
 cache |= CACHE_AVX2;
 }
+if ((bv & 6) == 6 && (b & bit_AVX512F)) {
+cache |= CACHE_AVX512F;
+}
 }
 }
 cpuid_cache = cache;
@@ -277,7 +323,7 @@ bool test_buffer_is_zero_next_accel(void)
 
 static bool select_accel_fn(const void *buf, size_t len)
 {
-if (likely(len >= 64)) {
+if (likely(len >= length_to_accel)) {
 return buffer_accel(buf, len);
 }
 return buffer_zero_int(buf, len);
-- 
1.8.3.1




[PATCH v2 1/2] configure: introduce configure option avx512f

2020-02-25 Thread Robert Hoo
Introduce {enable,disable}-avx512f configure option. It is by default disabled.
Only when user explicitly enable-avx512f and compiling environment supports
AVX512F, CONFIG_AVX512F_OPT will be defined.

AVX512F instruction set is available since Intel Skylake.
More info:
https://software.intel.com/sites/default/files/managed/c5/15/architecture-instruction-set-extensions-programming-reference.pdf

Signed-off-by: Robert Hoo 
---
 configure | 41 +
 1 file changed, 41 insertions(+)

diff --git a/configure b/configure
index d57261e..a0b41ce 100755
--- a/configure
+++ b/configure
@@ -1395,6 +1395,11 @@ for opt do
   ;;
   --enable-avx2) avx2_opt="yes"
   ;;
+  --disable-avx512f) avx512f_opt="no"
+  ;;
+  --enable-avx512f) avx512f_opt="yes"
+  ;;
+
   --enable-glusterfs) glusterfs="yes"
   ;;
   --disable-virtio-blk-data-plane|--enable-virtio-blk-data-plane)
@@ -1825,6 +1830,7 @@ disabled with --disable-FEATURE, default is enabled if 
available:
   tcmalloctcmalloc support
   jemallocjemalloc support
   avx2AVX2 optimization support
+  avx512f AVX512F optimization support
   replication replication support
   opengl  opengl support
   virglrenderer   virgl rendering support
@@ -5518,6 +5524,36 @@ EOF
   fi
 fi
 
+##
+# avx512f optimization requirement check
+#
+# There is no point enabling this if cpuid.h is not usable,
+# since we won't be able to select the new routines.
+# by default, it is turned off.
+# if user explicitly want to enable it, check environment
+
+if test "$cpuid_h" = "yes" && test "$avx512f_opt" = "yes"; then
+  cat > $TMPC << EOF
+#pragma GCC push_options
+#pragma GCC target("avx512f")
+#include 
+#include 
+static int bar(void *a) {
+__m512i x = *(__m512i *)a;
+return _mm512_test_epi64_mask(x, x);
+}
+int main(int argc, char *argv[])
+{
+   return bar(argv[0]);
+}
+EOF
+  if ! compile_object "" ; then
+avx512f_opt="no"
+  fi
+else
+  avx512f_opt="no"
+fi
+
 
 # check if __[u]int128_t is usable.
 
@@ -6650,6 +6686,7 @@ echo "libxml2   $libxml2"
 echo "tcmalloc support  $tcmalloc"
 echo "jemalloc support  $jemalloc"
 echo "avx2 optimization $avx2_opt"
+echo "avx512f optimization $avx512f_opt"
 echo "replication support $replication"
 echo "VxHS block device $vxhs"
 echo "bochs support $bochs"
@@ -7200,6 +7237,10 @@ if test "$avx2_opt" = "yes" ; then
   echo "CONFIG_AVX2_OPT=y" >> $config_host_mak
 fi
 
+if test "$avx512f_opt" = "yes" ; then
+  echo "CONFIG_AVX512F_OPT=y" >> $config_host_mak
+fi
+
 if test "$lzo" = "yes" ; then
   echo "CONFIG_LZO=y" >> $config_host_mak
 fi
-- 
1.8.3.1




[PATCH v2 0/2] Add AVX512F optimization option and buffer_zero_avx512()

2020-02-25 Thread Robert Hoo
1) Introduce {enable,disable}-avx512f configure option

2) Implement new buffer_zero_avx512() with AVX512F instructions

Changes in v2:
1. Fixes wrong definition of CACHE_SSE2 in v1.
2. Fixes not handle <256 length case in buffer_zero_avx512() implementaion.
(Follow Richard's suggestion: handle the case in select_accel_fn(), and have a
global variable alongside buffer_accel)
3. Changes avx512f configuration option's default status to disabled.
4. Ran 'make check-unit' on this patch, on both a Ivybridge machine and a
CascadeLake machine.

Robert Hoo (2):
  configure: add configure option avx512f_opt
  util: add util function buffer_zero_avx512()

 configure| 41 +
 include/qemu/cpuid.h |  3 +++
 util/bufferiszero.c  | 64 
 3 files changed, 99 insertions(+), 9 deletions(-)

-- 
1.8.3.1




Re: [PATCH 2/2] util: add util function buffer_zero_avx512()

2020-02-24 Thread Robert Hoo
On Mon, 2020-02-24 at 08:13 -0800, Richard Henderson wrote:
> On 2/23/20 11:07 PM, Robert Hoo wrote:
> > Inspired by your suggestion, I'm thinking go further: use immediate
> > rather than a global variable, so that saves 1 memory(/cache)
> > access. 
> > 
> > #ifdef CONFIG_AVX512F_OPT   
> > #define OPTIMIZE_LEN256
> > #else
> > #define OPTIMIZE_LEN64
> > #endif
> 
> With that, the testing in tests/test-bufferiszero.c, looping through
> the
> implementations, is invalidated.  Because once you start compiling
> for avx512,
> you're no longer testing sse2 et al with the same inputs.
> 
Right. Thanks pointing out. I didn't noticed that.
More precisely, it would cause no longer testing sse2 et al with < 256
length.

> IF we want to change the length to suit avx512, we would want to
> change it
> unconditionally.  And then you could also tidy up avx2 to avoid the
> extra
> comparisons there.
Considering the length's dependency on sse2/sse4/avx2/avx512 and the
algorithms, as well as future's possible changes, additions, I'd rather
roll back to your original suggestion, use a companion variable with
each accel_fn(). How do you like it?

> 
> 
> r~




Re: [PATCH 2/2] util: add util function buffer_zero_avx512()

2020-02-23 Thread Robert Hoo
Thanks Richard:-)
Sorry for late reply.
On Thu, 2020-02-13 at 10:20 -0800, Richard Henderson wrote:
> On 2/12/20 11:52 PM, Robert Hoo wrote:
> > And initialize buffer_is_zero() with it, when Intel AVX512F is
> > available on host.
> > 
> > This function utilizes Intel AVX512 fundamental instructions which
> > perform over previous AVX2 instructions.
> 
> Is it not still true that any AVX512 insn will cause the entire cpu
> package,
> not just the current core, to drop frequency by 20%?
> 
> As far as I know one should only use the 512-bit instructions when
> you can
> overcome that frequency drop, which seems unlikely in this
> case.  That said...
> I don't think so. AVX512 has been applied in various places.
> > +if (unlikely(len < 64)) { /*buff less than 512 bits,
> > unlikely*/
> > +return buffer_zero_int(buf, len);
> > +}
> 
> First, len < 64 has been eliminated already in select_accel_fn.
> Second, len < 256 is not handled properly by the code below...
> 
Right. I'm going to fix this in v2.
> 
> > +/* Begin with an unaligned head of 64 bytes.  */
> > +t = _mm512_loadu_si512(buf);
> > +p = (__m512i *)(((uintptr_t)buf + 5 * 64) & -64);
> > +e = (__m512i *)(((uintptr_t)buf + len) & -64);
> > +
> > +/* Loop over 64-byte aligned blocks of 256.  */
> > +while (p < e) {
> > +__builtin_prefetch(p);
> > +if (unlikely(_mm512_test_epi64_mask(t, t))) {
> > +return false;
> > +}
> > +t = p[-4] | p[-3] | p[-2] | p[-1];
> > +p += 4;
> > +}
> > +
> > +t |= _mm512_loadu_si512(buf + len - 4 * 64);
> > +t |= _mm512_loadu_si512(buf + len - 3 * 64);
> > +t |= _mm512_loadu_si512(buf + len - 2 * 64);
> > +t |= _mm512_loadu_si512(buf + len - 1 * 64);
> 
> ... because this final sequence loads 256 bytes.
> 
> Rather than make a second test vs 256 in buffer_zero_avx512, I wonder
> if it
> would be better to have select_accel_fn do the job.  Have a global
> variable
> buffer_accel_size alongside buffer_accel so there's only one branch
> (mis)predict to worry about.
> 
Thanks Richard, very enlightening!
Inspired by your suggestion, I'm thinking go further: use immediate
rather than a global variable, so that saves 1 memory(/cache) access. 

#ifdef CONFIG_AVX512F_OPT   
#define OPTIMIZE_LEN256
#else
#define OPTIMIZE_LEN64
#endif
> FWIW, something that the compiler should do, but doesn't currently,
> is use
> vpternlogq to perform a 3-input OR.  Something like
> 
> /* 0xfe -> orABC */
> t = _mm512_ternarylogic_epi64(t, p[-4], p[-3], 0xfe);
> t = _mm512_ternarylogic_epi64(t, p[-2], p[-1], 0xfe);
> 
Very enlightening. Yes, seems compiler doesn't do this.
I tried explicitly use this, however, looks it will have more
instructions generated, and unit test shows it performs less than then
conventional code.
Let me keep the conventional code for this moment, will ask around and
dig further outside this patch.

> 
> r~




Re: [PATCH 2/2] util: add util function buffer_zero_avx512()

2020-02-13 Thread Robert Hoo
On Thu, 2020-02-13 at 11:30 +0100, Paolo Bonzini wrote:
> On 13/02/20 08:52, Robert Hoo wrote:
> > +
> > +}
> > +#pragma GCC pop_options
> > +#endif
> > +
> > +
> >  /* Note that for test_buffer_is_zero_next_accel, the most
> > preferred
> >   * ISA must have the least significant bit.
> >   */
> > -#define CACHE_AVX21
> > -#define CACHE_SSE42
> > -#define CACHE_SSE24
> > +#define CACHE_AVX512F 1
> > +#define CACHE_AVX22
> > +#define CACHE_SSE44
> > +#define CACHE_SSE26
> 
> This should be 8, not 6.
> 
> Paolo

Thanks Paolo, going to fix it in v2.
> 
> >  
> >  /* Make sure that these variables are appropriately initialized
> > when
> >   * SSE2 is enabled on the compiler command-line, but the compiler
> > is
> > @@ -226,6 +268,11 @@ static void init_accel(unsigned cache)
> >  fn = buffer_zero_avx2;
> >  }
> >  #endif
> > +#ifdef CONFIG_AVX512F_OPT
> > +if (cache & CACHE_AVX512F) {
> > +fn = buffer_zero_avx512;
> > +}
> > +#endif
> >  buffer_accel = fn;
> >  }
> >  
> > @@ -255,6 +302,9 @@ static void __attribute__((constructor))
> > init_cpuid_cache(void)
> >  if ((bv & 6) == 6 && (b & bit_AVX2)) {
> >  cache |= CACHE_AVX2;
> >  }
> > +if ((bv & 6) == 6 && (b & bit_AVX512F)) {
> > +cache |= CACHE_AVX512F;
> > +}
> >  }
> 
> 




[PATCH 1/2] configure: add configure option avx512f_opt

2020-02-12 Thread Robert Hoo
Like previous avx2_opt option, config-host.mak will have CONFIG_AVX512F_OPT
defined if compiling host has the ability.

AVX512F instruction set is available since Intel Skylake.
More info:
https://software.intel.com/sites/default/files/managed/c5/15/architecture-instruction-set-extensions-programming-reference.pdf

Signed-off-by: Robert Hoo 
---
 configure | 39 +++
 1 file changed, 39 insertions(+)

diff --git a/configure b/configure
index 115dc38..9bf8de0 100755
--- a/configure
+++ b/configure
@@ -1382,6 +1382,11 @@ for opt do
   ;;
   --enable-avx2) avx2_opt="yes"
   ;;
+  --disable-avx512f) avx512f_opt="no"
+  ;;
+  --enable-avx512f) avx512f_opt="yes"
+  ;;
+
   --enable-glusterfs) glusterfs="yes"
   ;;
   --disable-virtio-blk-data-plane|--enable-virtio-blk-data-plane)
@@ -1811,6 +1816,7 @@ disabled with --disable-FEATURE, default is enabled if 
available:
   tcmalloctcmalloc support
   jemallocjemalloc support
   avx2AVX2 optimization support
+  avx512f AVX512F optimization support
   replication replication support
   opengl  opengl support
   virglrenderer   virgl rendering support
@@ -5481,6 +5487,34 @@ EOF
   fi
 fi
 
+##
+# avx512f optimization requirement check
+#
+# There is no point enabling this if cpuid.h is not usable,
+# since we won't be able to select the new routines.
+
+if test "$cpuid_h" = "yes" && test "$avx512f_opt" != "no"; then
+  cat > $TMPC << EOF
+#pragma GCC push_options
+#pragma GCC target("avx512f")
+#include 
+#include 
+static int bar(void *a) {
+__m512i x = *(__m512i *)a;
+return _mm512_test_epi64_mask(x, x);
+}
+int main(int argc, char *argv[])
+{
+   return bar(argv[0]);
+}
+EOF
+  if compile_object "" ; then
+avx512f_opt="yes"
+  else
+avx512f_opt="no"
+  fi
+fi
+
 
 # check if __[u]int128_t is usable.
 
@@ -6605,6 +6639,7 @@ echo "libxml2   $libxml2"
 echo "tcmalloc support  $tcmalloc"
 echo "jemalloc support  $jemalloc"
 echo "avx2 optimization $avx2_opt"
+echo "avx512f optimization $avx512f_opt"
 echo "replication support $replication"
 echo "VxHS block device $vxhs"
 echo "bochs support $bochs"
@@ -7152,6 +7187,10 @@ if test "$avx2_opt" = "yes" ; then
   echo "CONFIG_AVX2_OPT=y" >> $config_host_mak
 fi
 
+if test "$avx512f_opt" = "yes" ; then
+  echo "CONFIG_AVX512F_OPT=y" >> $config_host_mak
+fi
+
 if test "$lzo" = "yes" ; then
   echo "CONFIG_LZO=y" >> $config_host_mak
 fi
-- 
1.8.3.1




[PATCH 2/2] util: add util function buffer_zero_avx512()

2020-02-12 Thread Robert Hoo
And initialize buffer_is_zero() with it, when Intel AVX512F is
available on host.

This function utilizes Intel AVX512 fundamental instructions which
perform over previous AVX2 instructions.

Signed-off-by: Robert Hoo 
---
 include/qemu/cpuid.h |  3 +++
 util/bufferiszero.c  | 56 +---
 2 files changed, 56 insertions(+), 3 deletions(-)

diff --git a/include/qemu/cpuid.h b/include/qemu/cpuid.h
index 6930170..09fc245 100644
--- a/include/qemu/cpuid.h
+++ b/include/qemu/cpuid.h
@@ -45,6 +45,9 @@
 #ifndef bit_AVX2
 #define bit_AVX2(1 << 5)
 #endif
+#ifndef bit_AVX512F
+#define bit_AVX512F(1 << 16)
+#endif
 #ifndef bit_BMI2
 #define bit_BMI2(1 << 8)
 #endif
diff --git a/util/bufferiszero.c b/util/bufferiszero.c
index bfb2605..cbb854a 100644
--- a/util/bufferiszero.c
+++ b/util/bufferiszero.c
@@ -187,12 +187,54 @@ buffer_zero_avx2(const void *buf, size_t len)
 #pragma GCC pop_options
 #endif /* CONFIG_AVX2_OPT */
 
+#ifdef CONFIG_AVX512F_OPT
+#pragma GCC push_options
+#pragma GCC target("avx512f")
+#include 
+
+static bool
+buffer_zero_avx512(const void *buf, size_t len)
+{
+__m512i t;
+__m512i *p, *e;
+
+if (unlikely(len < 64)) { /*buff less than 512 bits, unlikely*/
+return buffer_zero_int(buf, len);
+}
+/* Begin with an unaligned head of 64 bytes.  */
+t = _mm512_loadu_si512(buf);
+p = (__m512i *)(((uintptr_t)buf + 5 * 64) & -64);
+e = (__m512i *)(((uintptr_t)buf + len) & -64);
+
+/* Loop over 64-byte aligned blocks of 256.  */
+while (p < e) {
+__builtin_prefetch(p);
+if (unlikely(_mm512_test_epi64_mask(t, t))) {
+return false;
+}
+t = p[-4] | p[-3] | p[-2] | p[-1];
+p += 4;
+}
+
+t |= _mm512_loadu_si512(buf + len - 4 * 64);
+t |= _mm512_loadu_si512(buf + len - 3 * 64);
+t |= _mm512_loadu_si512(buf + len - 2 * 64);
+t |= _mm512_loadu_si512(buf + len - 1 * 64);
+
+return !_mm512_test_epi64_mask(t, t);
+
+}
+#pragma GCC pop_options
+#endif
+
+
 /* Note that for test_buffer_is_zero_next_accel, the most preferred
  * ISA must have the least significant bit.
  */
-#define CACHE_AVX21
-#define CACHE_SSE42
-#define CACHE_SSE24
+#define CACHE_AVX512F 1
+#define CACHE_AVX22
+#define CACHE_SSE44
+#define CACHE_SSE26
 
 /* Make sure that these variables are appropriately initialized when
  * SSE2 is enabled on the compiler command-line, but the compiler is
@@ -226,6 +268,11 @@ static void init_accel(unsigned cache)
 fn = buffer_zero_avx2;
 }
 #endif
+#ifdef CONFIG_AVX512F_OPT
+if (cache & CACHE_AVX512F) {
+fn = buffer_zero_avx512;
+}
+#endif
 buffer_accel = fn;
 }
 
@@ -255,6 +302,9 @@ static void __attribute__((constructor)) 
init_cpuid_cache(void)
 if ((bv & 6) == 6 && (b & bit_AVX2)) {
 cache |= CACHE_AVX2;
 }
+if ((bv & 6) == 6 && (b & bit_AVX512F)) {
+cache |= CACHE_AVX512F;
+}
 }
 }
 cpuid_cache = cache;
-- 
1.8.3.1




[PATCH 0/2] Add AVX512F optimization option and buffer_zero_avx512()

2020-02-12 Thread Robert Hoo
1. Add avx512_opt option and enable it when host has the ability

2. Implement new buffer_zero_avx512() with AVX512F instructions

Robert Hoo (2):
  configure: add configure option avx512f_opt
  util: add function buffer_zero_avx512()

 configure| 39 
 include/qemu/cpuid.h |  3 +++
 util/bufferiszero.c  | 56 +---
 3 files changed, 95 insertions(+), 3 deletions(-)

-- 
1.8.3.1




Re: [Qemu-devel] [PATCH] i386: Disable OSPKE on CPU model definitions

2019-03-22 Thread Robert Hoo
On Tue, 2019-03-19 at 17:05 -0300, Eduardo Habkost wrote:
> Currently, the Cascadelake-Server, Icelake-Client, and
> Icelake-Server are always generating the following warning:
> 
>   qemu-system-x86_64: warning: \
> host doesn't support requested feature: CPUID.07H:ECX [bit 4]
> 
> This happens because OSPKE was never returned by
> GET_SUPPORTED_CPUID or x86_cpu_get_supported_feature_word().
> OSPKE is a runtime flag automatically set by the KVM module or by
> TCG code, was always cleared by x86_cpu_filter_features(), and
> was not supposed to appear on the CPU model table.
> 
> Remove the OSPKE flag from the CPU model table entries, to avoid
> the bogus warning and avoid returning invalid feature data on
> query-cpu-* QMP commands.  As OSPKE was always cleared by
> x86_cpu_filter_features(), this won't have any guest-visible
> impact.
> 
> Include a test case that should detect the problem if we introduce
> a similar bug again.
> 
> Fixes: c7a88b52f62b ("i386: Add new model of Cascadelake-Server")
> Fixes: 8a11c62da914 ("i386: Add new CPU model Icelake-
> {Server,Client}")
> Cc: Tao Xu 
> Cc: Robert Hoo 
> Signed-off-by: Eduardo Habkost 
> ---
>  target/i386/cpu.c   |  6 +++---
>  tests/acceptance/cpu_queries.py | 33
> +
>  2 files changed, 36 insertions(+), 3 deletions(-)
>  create mode 100644 tests/acceptance/cpu_queries.py
> 
> diff --git a/target/i386/cpu.c b/target/i386/cpu.c
> index d90c01a059..38cfdec33b 100644
> --- a/target/i386/cpu.c
> +++ b/target/i386/cpu.c
> @@ -2533,7 +2533,7 @@ static X86CPUDefinition builtin_x86_defs[] = {
>  CPUID_7_0_EBX_AVX512BW | CPUID_7_0_EBX_AVX512CD |
>  CPUID_7_0_EBX_AVX512VL | CPUID_7_0_EBX_CLFLUSHOPT,
>  .features[FEAT_7_0_ECX] =
> -CPUID_7_0_ECX_PKU | CPUID_7_0_ECX_OSPKE |
> +CPUID_7_0_ECX_PKU |
>  CPUID_7_0_ECX_AVX512VNNI,
>  .features[FEAT_7_0_EDX] =
>  CPUID_7_0_EDX_SPEC_CTRL | CPUID_7_0_EDX_SPEC_CTRL_SSBD,
> @@ -2586,7 +2586,7 @@ static X86CPUDefinition builtin_x86_defs[] = {
>  CPUID_7_0_EBX_SMAP,
>  .features[FEAT_7_0_ECX] =
>  CPUID_7_0_ECX_VBMI | CPUID_7_0_ECX_UMIP |
> CPUID_7_0_ECX_PKU |
> -CPUID_7_0_ECX_OSPKE | CPUID_7_0_ECX_VBMI2 |
> CPUID_7_0_ECX_GFNI |
> +CPUID_7_0_ECX_VBMI2 | CPUID_7_0_ECX_GFNI |
>  CPUID_7_0_ECX_VAES | CPUID_7_0_ECX_VPCLMULQDQ |
>  CPUID_7_0_ECX_AVX512VNNI | CPUID_7_0_ECX_AVX512BITALG |
>  CPUID_7_0_ECX_AVX512_VPOPCNTDQ,
> @@ -2644,7 +2644,7 @@ static X86CPUDefinition builtin_x86_defs[] = {
>  CPUID_7_0_EBX_AVX512VL | CPUID_7_0_EBX_CLFLUSHOPT,
>  .features[FEAT_7_0_ECX] =
>  CPUID_7_0_ECX_VBMI | CPUID_7_0_ECX_UMIP |
> CPUID_7_0_ECX_PKU |
> -CPUID_7_0_ECX_OSPKE | CPUID_7_0_ECX_VBMI2 |
> CPUID_7_0_ECX_GFNI |
> +CPUID_7_0_ECX_VBMI2 | CPUID_7_0_ECX_GFNI |
>  CPUID_7_0_ECX_VAES | CPUID_7_0_ECX_VPCLMULQDQ |
>  CPUID_7_0_ECX_AVX512VNNI | CPUID_7_0_ECX_AVX512BITALG |
>  CPUID_7_0_ECX_AVX512_VPOPCNTDQ | CPUID_7_0_ECX_LA57,
> diff --git a/tests/acceptance/cpu_queries.py
> b/tests/acceptance/cpu_queries.py
> new file mode 100644
> index 00..e71edec39f
> --- /dev/null
> +++ b/tests/acceptance/cpu_queries.py
> @@ -0,0 +1,33 @@
> +# Sanity check of query-cpu-* results
> +#
> +# Copyright (c) 2019 Red Hat, Inc.
> +#
> +# Author:
> +#  Eduardo Habkost 
> +#
> +# This work is licensed under the terms of the GNU GPL, version 2 or
> +# later.  See the COPYING file in the top-level directory.
> +
> +import logging
> +
> +from avocado_qemu import Test
> +
> +class QueryCPUModelExpansion(Test):
> +"""
> +Run query-cpu-model-expansion for each CPU model, and validate
> results
> +"""
> +
> +def test(self):
> +self.vm.set_machine('none')
> +self.vm.add_args('-S')
> +self.vm.launch()
> +
> +cpus = self.vm.command('query-cpu-definitions')
> +for c in cpus:
> +        print(repr(c))
> +self.assertNotIn('', c['unavailable-features'],
> c['name'])
> +
> +for c in cpus:
> +model = {'name': c['name']}
> +e = self.vm.command('query-cpu-model-expansion',
> model=model, type='full')
> +self.assertEquals(e['model']['name'], c['name'])

Thanks for fix.

Reviewed-by: Robert Hoo 



Re: [Qemu-devel] [PATCH] i386: remove the 'INTEL_PT' CPUID bit from named CPU models

2018-12-23 Thread Robert Hoo
On Sat, 2018-12-22 at 10:13 +0100, Paolo Bonzini wrote:
> On 22/12/18 02:01, Robert Hoo wrote:
> > On Fri, 2018-12-21 at 16:27 +0100, Paolo Bonzini wrote:
> > > On 21/12/18 16:22, Philippe Mathieu-Daudé wrote:
> > > > Hi Paolo,
> > > > 
> > > > On 12/21/18 7:30 AM, Paolo Bonzini wrote:
> > > > > From: Robert Hoo 
> > > > > 
> > > > > Processor tracing is not yet implemented for KVM and it will
> > > > > be
> > > > > an
> > > > > opt in feature requiring a special module parameter.
> > > > > Disable it, because it is wrong to enable it by default and
> > > > > it is impossible that no one has ever used it.
> > > > > 
> > > > > Cc: qemu-sta...@nongnu.org
> > > > 
> > > > Does this patch misses Robert S-o-b?
> > > > Signed-off-by: Robert Hoo 
> > 
> > Paolo's right. It didn't come from me.
> > > 
> > > No, the author is wrong, it should be me.  "git commit -c"
> > > apparently
> > > copies the author from the original commit.
> > > 
> > > Paolo
> > 
> > Hi Paolo, would you hold on INTEL_PT removal for a moment? I think
> > I
> > need Luwei's double confirm.
> 
> I'm aware of Luwei's patches, they will be in 4.21.  As mentioned in
> the
> commit message, they will be an opt-in feature, not enabled by
> default;
> the default is system-wide tracing and no INTEL_PT CPUID bit
> available
> in the guest.
> 
OK, synced with Luwei, agree with you.

> Paolo



Re: [Qemu-devel] [PATCH] i386: remove the 'INTEL_PT' CPUID bit from named CPU models

2018-12-21 Thread Robert Hoo
On Fri, 2018-12-21 at 16:27 +0100, Paolo Bonzini wrote:
> On 21/12/18 16:22, Philippe Mathieu-Daudé wrote:
> > Hi Paolo,
> > 
> > On 12/21/18 7:30 AM, Paolo Bonzini wrote:
> > > From: Robert Hoo 
> > > 
> > > Processor tracing is not yet implemented for KVM and it will be
> > > an
> > > opt in feature requiring a special module parameter.
> > > Disable it, because it is wrong to enable it by default and
> > > it is impossible that no one has ever used it.
> > > 
> > > Cc: qemu-sta...@nongnu.org
> > 
> > Does this patch misses Robert S-o-b?
> > Signed-off-by: Robert Hoo 

Paolo's right. It didn't come from me.
> 
> No, the author is wrong, it should be me.  "git commit -c" apparently
> copies the author from the original commit.
> 
> Paolo

Hi Paolo, would you hold on INTEL_PT removal for a moment? I think I
need Luwei's double confirm.
(Added him in receiver list.)
> 
> > > Signed-off-by: Paolo Bonzini 
> > > ---
> > >  target/i386/cpu.c | 8 +++-
> > >  1 file changed, 3 insertions(+), 5 deletions(-)
> > > 
> > > diff --git a/target/i386/cpu.c b/target/i386/cpu.c
> > > index dae46f0319..9c54c41e7a 100644
> > > --- a/target/i386/cpu.c
> > > +++ b/target/i386/cpu.c
> > > @@ -2493,8 +2493,7 @@ static X86CPUDefinition builtin_x86_defs[]
> > > = {
> > >  CPUID_7_0_EBX_SMAP | CPUID_7_0_EBX_CLWB |
> > >  CPUID_7_0_EBX_AVX512F | CPUID_7_0_EBX_AVX512DQ |
> > >  CPUID_7_0_EBX_AVX512BW | CPUID_7_0_EBX_AVX512CD |
> > > -CPUID_7_0_EBX_AVX512VL | CPUID_7_0_EBX_CLFLUSHOPT |
> > > -CPUID_7_0_EBX_INTEL_PT,
> > > +CPUID_7_0_EBX_AVX512VL | CPUID_7_0_EBX_CLFLUSHOPT,
> > >  .features[FEAT_7_0_ECX] =
> > >  CPUID_7_0_ECX_PKU | CPUID_7_0_ECX_OSPKE |
> > >  CPUID_7_0_ECX_AVX512VNNI,
> > > @@ -2546,7 +2545,7 @@ static X86CPUDefinition builtin_x86_defs[]
> > > = {
> > >  CPUID_7_0_EBX_HLE | CPUID_7_0_EBX_AVX2 |
> > > CPUID_7_0_EBX_SMEP |
> > >  CPUID_7_0_EBX_BMI2 | CPUID_7_0_EBX_ERMS |
> > > CPUID_7_0_EBX_INVPCID |
> > >  CPUID_7_0_EBX_RTM | CPUID_7_0_EBX_RDSEED |
> > > CPUID_7_0_EBX_ADX |
> > > -CPUID_7_0_EBX_SMAP | CPUID_7_0_EBX_INTEL_PT,
> > > +CPUID_7_0_EBX_SMAP,
> > >  .features[FEAT_7_0_ECX] =
> > >  CPUID_7_0_ECX_VBMI | CPUID_7_0_ECX_UMIP |
> > > CPUID_7_0_ECX_PKU |
> > >  CPUID_7_0_ECX_OSPKE | CPUID_7_0_ECX_VBMI2 |
> > > CPUID_7_0_ECX_GFNI |
> > > @@ -2604,8 +2603,7 @@ static X86CPUDefinition builtin_x86_defs[]
> > > = {
> > >  CPUID_7_0_EBX_SMAP | CPUID_7_0_EBX_CLWB |
> > >  CPUID_7_0_EBX_AVX512F | CPUID_7_0_EBX_AVX512DQ |
> > >  CPUID_7_0_EBX_AVX512BW | CPUID_7_0_EBX_AVX512CD |
> > > -CPUID_7_0_EBX_AVX512VL | CPUID_7_0_EBX_CLFLUSHOPT |
> > > -CPUID_7_0_EBX_INTEL_PT,
> > > +CPUID_7_0_EBX_AVX512VL | CPUID_7_0_EBX_CLFLUSHOPT,
> > >  .features[FEAT_7_0_ECX] =
> > >  CPUID_7_0_ECX_VBMI | CPUID_7_0_ECX_UMIP |
> > > CPUID_7_0_ECX_PKU |
> > >  CPUID_7_0_ECX_OSPKE | CPUID_7_0_ECX_VBMI2 |
> > > CPUID_7_0_ECX_GFNI |
> > > 
> 
> 



Re: [Qemu-devel] [PATCH 1/2] i386: remove the new CPUID 'PCONFIG' from Icelake-Server CPU model

2018-12-21 Thread Robert Hoo
On Fri, 2018-12-21 at 16:03 +0100, Paolo Bonzini wrote:
> On 21/12/18 15:04, Robert Hoo wrote:
> > > So this series is correct and I will follow up with one for
> > > INTEL_PT;
> > > however, this begs the question of how the patches are being
> > > tested.
> > 
> > My apologies for carelessness.
> 
> No problem.  In the future please check that "-cpu Icelake-Client"
> doesn't have warnings such as
> 
> qemu-system-x86_64: warning: host doesn't support requested feature:
> CPUID.07H:EBX.intel-pt [bit 25]
> 
> when run on an Icelake-Client host.

Sure. I'm going to ask our validation team to add these in test
criteria.
> 
> > I've seen you patch for INTEL_PT. So am I going to resend these 2
> > patches and Cc qemu-stable? or simply reply these 2 patches adding
> > qemu-stable in Cc list?
> 
> I can take care of that, thanks.
> 
> Paolo
> 



Re: [Qemu-devel] [PATCH 1/2] i386: remove the new CPUID 'PCONFIG' from Icelake-Server CPU model

2018-12-21 Thread Robert Hoo
On Fri, 2018-12-21 at 07:27 +0100, Paolo Bonzini wrote:
> On 20/12/18 13:50, Robert Hoo wrote:
> > On Thu, 2018-12-20 at 13:38 +0100, Paolo Bonzini wrote:
> > > On 20/12/18 01:18, Robert Hoo wrote:
> > > > I think the sooner, the better. Take the time window that
> > > > Icelake
> > > > CPU
> > > > model has just shipped with QEMU 3.1.0 and is not
> > > > publicly/widely
> > > > used
> > > > yet.
> > > 
> > > We should still leave it in the 3.1 machine types.  I've just
> > > sent a
> > > patch to do the same with MPX.
> > > 
> > 
> > I took a look your patch of "Disable MPX support on named CPU
> > models".
> > Seems you do the same as I do to PCONFIG. So you agree with my
> > above
> > patch?:-)
> > 
> > I won't object that keep it in 3.1 machine type as you do to MPX.
> 
> Sorry Robert, I changed my mind.  If no hypervisor exists that
> enables
> PCONFIG for guests (using the PCONFIG_ENABLE processor control),
> effectively no one can ever have used it.  We should disable it in
> all
> machine types and Cc qemu-stable.

Thanks Paolo.
> 
> In fact, the same is true for INTEL_PT, which is not supported by any
> released kernel version and, even is going to be available only with
> a
> module parameter when it will be.

Add Luwei in judging this.
> 
> This is not the same as MPX, which did work even though nobody was
> probably using it.
> 
> So this series is correct and I will follow up with one for INTEL_PT;
> however, this begs the question of how the patches are being tested.
> 
My apologies for carelessness.

I've seen you patch for INTEL_PT. So am I going to resend these 2
patches and Cc qemu-stable? or simply reply these 2 patches adding
qemu-stable in Cc list?

> Paolo



Re: [Qemu-devel] [PATCH 1/2] i386: remove the new CPUID 'PCONFIG' from Icelake-Server CPU model

2018-12-20 Thread Robert Hoo
On Thu, 2018-12-20 at 13:38 +0100, Paolo Bonzini wrote:
> On 20/12/18 01:18, Robert Hoo wrote:
> > On Wed, 2018-12-19 at 14:01 +, Daniel P. Berrangé wrote:
> > > On Wed, Dec 19, 2018 at 09:44:40PM +0800, Robert Hoo wrote:
> > > > Signed-off-by: Robert Hoo 
> > > > ---
> > > >  target/i386/cpu.c | 3 +--
> > > >  1 file changed, 1 insertion(+), 2 deletions(-)
> > > > 
> > > > diff --git a/target/i386/cpu.c b/target/i386/cpu.c
> > > > index 677a3bd..b6113d0 100644
> > > > --- a/target/i386/cpu.c
> > > > +++ b/target/i386/cpu.c
> > > > @@ -2613,8 +2613,7 @@ static X86CPUDefinition
> > > > builtin_x86_defs[] =
> > > > {
> > > >  CPUID_7_0_ECX_AVX512VNNI |
> > > > CPUID_7_0_ECX_AVX512BITALG
> > > > > 
> > > > 
> > > >  CPUID_7_0_ECX_AVX512_VPOPCNTDQ |
> > > > CPUID_7_0_ECX_LA57,
> > > >  .features[FEAT_7_0_EDX] =
> > > > -CPUID_7_0_EDX_PCONFIG | CPUID_7_0_EDX_SPEC_CTRL |
> > > > -CPUID_7_0_EDX_SPEC_CTRL_SSBD,
> > > > +CPUID_7_0_EDX_SPEC_CTRL |
> > > > CPUID_7_0_EDX_SPEC_CTRL_SSBD,
> > > >  /* Missing: XSAVES (not supported by some Linux
> > > > versions,
> > > >  * including v4.1 to v4.12).
> > > >  * KVM doesn't yet expose any XSAVES state save
> > > > component,
> > > 
> > > This was shipped in QEMU 3.1.0, so I don't think we can
> > > unconditionally
> > > remove it like this without breaking CPU model migration compat. 
> > > 
> > 
> > I think the sooner, the better. Take the time window that Icelake
> > CPU
> > model has just shipped with QEMU 3.1.0 and is not publicly/widely
> > used
> > yet.
> 
> We should still leave it in the 3.1 machine types.  I've just sent a
> patch to do the same with MPX.
> 
I took a look your patch of "Disable MPX support on named CPU models".
Seems you do the same as I do to PCONFIG. So you agree with my above
patch?:-)

I won't object that keep it in 3.1 machine type as you do to MPX.

> Paolo
> 



Re: [Qemu-devel] [PATCH 1/2] i386: remove the new CPUID 'PCONFIG' from Icelake-Server CPU model

2018-12-19 Thread Robert Hoo
On Wed, 2018-12-19 at 14:01 +, Daniel P. Berrangé wrote:
> On Wed, Dec 19, 2018 at 09:44:40PM +0800, Robert Hoo wrote:
> > Signed-off-by: Robert Hoo 
> > ---
> >  target/i386/cpu.c | 3 +--
> >  1 file changed, 1 insertion(+), 2 deletions(-)
> > 
> > diff --git a/target/i386/cpu.c b/target/i386/cpu.c
> > index 677a3bd..b6113d0 100644
> > --- a/target/i386/cpu.c
> > +++ b/target/i386/cpu.c
> > @@ -2613,8 +2613,7 @@ static X86CPUDefinition builtin_x86_defs[] =
> > {
> >  CPUID_7_0_ECX_AVX512VNNI | CPUID_7_0_ECX_AVX512BITALG
> > |
> >  CPUID_7_0_ECX_AVX512_VPOPCNTDQ | CPUID_7_0_ECX_LA57,
> >  .features[FEAT_7_0_EDX] =
> > -CPUID_7_0_EDX_PCONFIG | CPUID_7_0_EDX_SPEC_CTRL |
> > -CPUID_7_0_EDX_SPEC_CTRL_SSBD,
> > +CPUID_7_0_EDX_SPEC_CTRL |
> > CPUID_7_0_EDX_SPEC_CTRL_SSBD,
> >  /* Missing: XSAVES (not supported by some Linux versions,
> >  * including v4.1 to v4.12).
> >  * KVM doesn't yet expose any XSAVES state save
> > component,
> 
> This was shipped in QEMU 3.1.0, so I don't think we can
> unconditionally
> remove it like this without breaking CPU model migration compat. 
> 
I think the sooner, the better. Take the time window that Icelake CPU
model has just shipped with QEMU 3.1.0 and is not publicly/widely used
yet.
> 
> Regards,
> Daniel



[Qemu-devel] [PATCH 2/2] Revert "i386: Add CPUID bit for PCONFIG"

2018-12-19 Thread Robert Hoo
This reverts commit 5131dc433df54b37e8e918d8fba7fe10344e7a7b.
For new instruction 'PCONFIG' will not be exposed to guest.

Signed-off-by: Robert Hoo 
---
 target/i386/cpu.c | 2 +-
 target/i386/cpu.h | 1 -
 2 files changed, 1 insertion(+), 2 deletions(-)

diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index b6113d0..08d4307 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -1040,7 +1040,7 @@ static FeatureWordInfo feature_word_info[FEATURE_WORDS] = 
{
 NULL, NULL, NULL, NULL,
 NULL, NULL, NULL, NULL,
 NULL, NULL, NULL, NULL,
-NULL, NULL, "pconfig", NULL,
+NULL, NULL, NULL, NULL,
 NULL, NULL, NULL, NULL,
 NULL, NULL, "spec-ctrl", "stibp",
 NULL, "arch-capabilities", NULL, "ssbd",
diff --git a/target/i386/cpu.h b/target/i386/cpu.h
index ef41a03..66707d7 100644
--- a/target/i386/cpu.h
+++ b/target/i386/cpu.h
@@ -692,7 +692,6 @@ typedef uint32_t FeatureWordArray[FEATURE_WORDS];
 
 #define CPUID_7_0_EDX_AVX512_4VNNIW (1U << 2) /* AVX512 Neural Network 
Instructions */
 #define CPUID_7_0_EDX_AVX512_4FMAPS (1U << 3) /* AVX512 Multiply Accumulation 
Single Precision */
-#define CPUID_7_0_EDX_PCONFIG (1U << 18)   /* Platform Configuration */
 #define CPUID_7_0_EDX_SPEC_CTRL (1U << 26) /* Speculation Control */
 #define CPUID_7_0_EDX_ARCH_CAPABILITIES (1U << 29)  /*Arch Capabilities*/
 #define CPUID_7_0_EDX_SPEC_CTRL_SSBD  (1U << 31) /* Speculative Store Bypass 
Disable */
-- 
1.8.3.1




[Qemu-devel] [PATCH 1/2] i386: remove the new CPUID 'PCONFIG' from Icelake-Server CPU model

2018-12-19 Thread Robert Hoo
Signed-off-by: Robert Hoo 
---
 target/i386/cpu.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index 677a3bd..b6113d0 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -2613,8 +2613,7 @@ static X86CPUDefinition builtin_x86_defs[] = {
 CPUID_7_0_ECX_AVX512VNNI | CPUID_7_0_ECX_AVX512BITALG |
 CPUID_7_0_ECX_AVX512_VPOPCNTDQ | CPUID_7_0_ECX_LA57,
 .features[FEAT_7_0_EDX] =
-CPUID_7_0_EDX_PCONFIG | CPUID_7_0_EDX_SPEC_CTRL |
-CPUID_7_0_EDX_SPEC_CTRL_SSBD,
+CPUID_7_0_EDX_SPEC_CTRL | CPUID_7_0_EDX_SPEC_CTRL_SSBD,
 /* Missing: XSAVES (not supported by some Linux versions,
 * including v4.1 to v4.12).
 * KVM doesn't yet expose any XSAVES state save component,
-- 
1.8.3.1




[Qemu-devel] [PATCH 0/2] Revert exposure of PCONFIG to guest

2018-12-19 Thread Robert Hoo
PCONFIG is not supposed to be exposed to guest. These 2 patches fix this.

Robert Hoo (2):
  i386: remove the new CPUID 'PCONFIG' from Icelake-Server CPU model
  Revert "i386: Add CPUID bit for PCONFIG"

 target/i386/cpu.c | 5 ++---
 target/i386/cpu.h | 1 -
 2 files changed, 2 insertions(+), 4 deletions(-)

-- 
1.8.3.1




[Qemu-devel] [PATCH v6 2/3] x86: Data structure changes to support MSR based features

2018-10-26 Thread Robert Hoo
Add FeatureWordType indicator in struct FeatureWordInfo.
Change feature_word_info[] accordingly.
Change existing functions that refer to feature_word_info[] accordingly.

Signed-off-by: Robert Hoo 
---
 target/i386/cpu.c | 205 --
 target/i386/cpu.h |   7 +-
 2 files changed, 159 insertions(+), 53 deletions(-)

diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index 1469a1b..0de21fa 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -770,17 +770,36 @@ static void x86_cpu_vendor_words2str(char *dst, uint32_t 
vendor1,
   /* missing:
   CPUID_XSAVE_XSAVEC, CPUID_XSAVE_XSAVES */
 
+typedef enum FeatureWordType {
+   CPUID_FEATURE_WORD,
+   MSR_FEATURE_WORD,
+} FeatureWordType;
+
 typedef struct FeatureWordInfo {
+FeatureWordType type;
 /* feature flags names are taken from "Intel Processor Identification and
  * the CPUID Instruction" and AMD's "CPUID Specification".
  * In cases of disagreement between feature naming conventions,
  * aliases may be added.
  */
 const char *feat_names[32];
-uint32_t cpuid_eax;   /* Input EAX for CPUID */
-bool cpuid_needs_ecx; /* CPUID instruction uses ECX as input */
-uint32_t cpuid_ecx;   /* Input ECX value for CPUID */
-int cpuid_reg;/* output register (R_* constant) */
+union {
+/* If type==CPUID_FEATURE_WORD */
+struct {
+uint32_t eax;   /* Input EAX for CPUID */
+bool needs_ecx; /* CPUID instruction uses ECX as input */
+uint32_t ecx;   /* Input ECX value for CPUID */
+int reg;/* output register (R_* constant) */
+} cpuid;
+/* If type==MSR_FEATURE_WORD */
+struct {
+uint32_t index;
+struct {   /*CPUID that enumerate this MSR*/
+FeatureWord cpuid_class;
+uint32_tcpuid_flag;
+} cpuid_dep;
+} msr;
+};
 uint32_t tcg_features; /* Feature flags supported by TCG */
 uint32_t unmigratable_flags; /* Feature flags known to be unmigratable */
 uint32_t migratable_flags; /* Feature flags known to be migratable */
@@ -790,6 +809,7 @@ typedef struct FeatureWordInfo {
 
 static FeatureWordInfo feature_word_info[FEATURE_WORDS] = {
 [FEAT_1_EDX] = {
+.type = CPUID_FEATURE_WORD,
 .feat_names = {
 "fpu", "vme", "de", "pse",
 "tsc", "msr", "pae", "mce",
@@ -800,10 +820,11 @@ static FeatureWordInfo feature_word_info[FEATURE_WORDS] = 
{
 "fxsr", "sse", "sse2", "ss",
 "ht" /* Intel htt */, "tm", "ia64", "pbe",
 },
-.cpuid_eax = 1, .cpuid_reg = R_EDX,
+.cpuid = {.eax = 1, .reg = R_EDX, },
 .tcg_features = TCG_FEATURES,
 },
 [FEAT_1_ECX] = {
+.type = CPUID_FEATURE_WORD,
 .feat_names = {
 "pni" /* Intel,AMD sse3 */, "pclmulqdq", "dtes64", "monitor",
 "ds-cpl", "vmx", "smx", "est",
@@ -814,7 +835,7 @@ static FeatureWordInfo feature_word_info[FEATURE_WORDS] = {
 "tsc-deadline", "aes", "xsave", NULL /* osxsave */,
 "avx", "f16c", "rdrand", "hypervisor",
 },
-.cpuid_eax = 1, .cpuid_reg = R_ECX,
+.cpuid = { .eax = 1, .reg = R_ECX, },
 .tcg_features = TCG_EXT_FEATURES,
 },
 /* Feature names that are already defined on feature_name[] but
@@ -823,6 +844,7 @@ static FeatureWordInfo feature_word_info[FEATURE_WORDS] = {
  * to features[FEAT_8000_0001_EDX] if and only if CPU vendor is AMD.
  */
 [FEAT_8000_0001_EDX] = {
+.type = CPUID_FEATURE_WORD,
 .feat_names = {
 NULL /* fpu */, NULL /* vme */, NULL /* de */, NULL /* pse */,
 NULL /* tsc */, NULL /* msr */, NULL /* pae */, NULL /* mce */,
@@ -833,10 +855,11 @@ static FeatureWordInfo feature_word_info[FEATURE_WORDS] = 
{
 NULL /* fxsr */, "fxsr-opt", "pdpe1gb", "rdtscp",
 NULL, "lm", "3dnowext", "3dnow",
 },
-.cpuid_eax = 0x8001, .cpuid_reg = R_EDX,
+.cpuid = { .eax = 0x8001, .reg = R_EDX, },
 .tcg_features = TCG_EXT2_FEATURES,
 },
 [FEAT_8000_0001_ECX] = {
+.type = CPUID_FEATURE_WORD,
 .feat_names = {
 "lahf-lm", "cmp-legacy", "svm", "extapic",
 "cr8legacy", "abm", "sse4a", "misalignsse",
@@ -847,7 +870,7 @@ static FeatureWordInfo feature_word_info[FEATURE_WORDS] = {
 "perfc

[Qemu-devel] [PATCH v6 0/3] x86: QEMU side support on MSR based features

2018-10-26 Thread Robert Hoo
KVM side has added the framework (kvm.git:d1d93fa90) to support MSR based 
features.
Here is the QEMU part, including data structure changes/expanding, referring
functions changes, and the implementations on 
KVM_GET_MSR_FEATURE_INDEX_LIST and KVM_GET_MSRS system ioctl.

Changelog:
v6: In cpu feature filtering, filter out MSR features whose CPUID feature
dependency is not there.
Check feature word type for other accelerator, like hvf, for otherwise 
it
would return bogus EAX/ECX values in x86_cpu_get_supported_feature_word().
v5: Re-order patches. Complement feature MSR set routines.
v4:
Re-organize patch set to conform to request of individually build pass.
Add KVM capability check for KVM_GET_MSR_INDEX_LIST before fetch.
Special treatment for MSR_IA32_ARCH_CAPABILITIES.RSBA.
Use more convenient glib wrapper (g_strdup_printf) instead of native
(sprintf).

v3: patch 2&3 in v2 are corrupted. Re-format patches.
v2: coding style changes to pass ./scripts/checkpatch.pl.

Robert Hoo (3):
  kvm: Add support to KVM_GET_MSR_FEATURE_INDEX_LIST and KVM_GET_MSRS
system ioctl
  x86: Data structure changes to support MSR based features
  x86: define a new MSR based feature word --
FEATURE_WORDS_ARCH_CAPABILITIES

 include/sysemu/kvm.h |   2 +
 target/i386/cpu.c| 234 +++
 target/i386/cpu.h|  15 +++-
 target/i386/kvm.c|  91 
 4 files changed, 289 insertions(+), 53 deletions(-)

-- 
1.8.3.1




[Qemu-devel] [PATCH v6 3/3] x86: define a new MSR based feature word -- FEATURE_WORDS_ARCH_CAPABILITIES

2018-10-26 Thread Robert Hoo
Note RSBA is specially treated -- no matter host support it or not, qemu
pretends it is supported.

Changes in v6: filter out MSR features whose dependent CPUID enumeration is not
there.

Signed-off-by: Robert Hoo 
Reviewed-by: Eduardo Habkost 
---
 target/i386/cpu.c | 31 ++-
 target/i386/cpu.h |  8 
 target/i386/kvm.c | 11 +++
 3 files changed, 49 insertions(+), 1 deletion(-)

diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index 0de21fa..6371722 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -1141,6 +1141,27 @@ static FeatureWordInfo feature_word_info[FEATURE_WORDS] 
= {
 },
 .tcg_features = ~0U,
 },
+/*Below are MSR exposed features*/
+[FEAT_ARCH_CAPABILITIES] = {
+.type = MSR_FEATURE_WORD,
+.feat_names = {
+"rdctl-no", "ibrs-all", "rsba", "skip-l1dfl-vmentry",
+"ssb-no", NULL, NULL, NULL,
+NULL, NULL, NULL, NULL,
+NULL, NULL, NULL, NULL,
+NULL, NULL, NULL, NULL,
+NULL, NULL, NULL, NULL,
+NULL, NULL, NULL, NULL,
+NULL, NULL, NULL, NULL,
+},
+.msr = {
+.index = MSR_IA32_ARCH_CAPABILITIES,
+.cpuid_dep = {
+FEAT_7_0_EDX,
+CPUID_7_0_EDX_ARCH_CAPABILITIES
+}
+},
+},
 };
 
 typedef struct X86RegisterInfo32 {
@@ -3696,7 +3717,15 @@ static uint32_t 
x86_cpu_get_supported_feature_word(FeatureWord w,
 wi->cpuid.reg);
 break;
 case MSR_FEATURE_WORD:
-r = kvm_arch_get_supported_msr_feature(kvm_state, wi->msr.index);
+/* Special case:
+ * No matter host status, IA32_ARCH_CAPABILITIES.RSBA [bit 2]
+ * is always supported in guest.
+ */
+if (wi->msr.index == MSR_IA32_ARCH_CAPABILITIES) {
+r = MSR_ARCH_CAP_RSBA;
+}
+r |= kvm_arch_get_supported_msr_feature(kvm_state,
+wi->msr.index);
 break;
 }
 } else if (hvf_enabled()) {
diff --git a/target/i386/cpu.h b/target/i386/cpu.h
index dd3de97..ff1ae32 100644
--- a/target/i386/cpu.h
+++ b/target/i386/cpu.h
@@ -507,6 +507,7 @@ typedef enum FeatureWord {
 FEAT_XSAVE_COMP_LO, /* CPUID[EAX=0xd,ECX=0].EAX */
 FEAT_XSAVE_COMP_HI, /* CPUID[EAX=0xd,ECX=0].EDX */
 MSR_FEATURE_WORD_BEGIN, /* Define MSR feature words below */
+FEAT_ARCH_CAPABILITIES = MSR_FEATURE_WORD_BEGIN,
 FEATURE_WORDS,
 } FeatureWord;
 
@@ -735,6 +736,13 @@ typedef uint32_t FeatureWordArray[FEATURE_WORDS];
 #define CPUID_TOPOLOGY_LEVEL_SMT  (1U << 8)
 #define CPUID_TOPOLOGY_LEVEL_CORE (2U << 8)
 
+/* MSR Feature Bits */
+#define MSR_ARCH_CAP_RDCL_NO(1U << 0)
+#define MSR_ARCH_CAP_IBRS_ALL   (1U << 1)
+#define MSR_ARCH_CAP_RSBA   (1U << 2)
+#define MSR_ARCH_CAP_SKIP_L1DFL_VMENTRY (1U << 3)
+#define MSR_ARCH_CAP_SSB_NO (1U << 4)
+
 #ifndef HYPERV_SPINLOCK_NEVER_RETRY
 #define HYPERV_SPINLOCK_NEVER_RETRY 0x
 #endif
diff --git a/target/i386/kvm.c b/target/i386/kvm.c
index 161fc38..796a049 100644
--- a/target/i386/kvm.c
+++ b/target/i386/kvm.c
@@ -1975,6 +1975,17 @@ static int kvm_put_msrs(X86CPU *cpu, int level)
 }
 #endif
 
+/* If host supports feature MSR, write down. */
+if (kvm_feature_msrs) {
+int i;
+for (i = 0; i < kvm_feature_msrs->nmsrs; i++)
+if (kvm_feature_msrs->indices[i] == MSR_IA32_ARCH_CAPABILITIES) {
+kvm_msr_entry_add(cpu, MSR_IA32_ARCH_CAPABILITIES,
+  env->features[FEAT_ARCH_CAPABILITIES]);
+break;
+}
+}
+
 /*
  * The following MSRs have side effects on the guest or are too heavy
  * for normal writeback. Limit them to reset or full state updates.
-- 
1.8.3.1




[Qemu-devel] [PATCH v6 1/3] kvm: Add support to KVM_GET_MSR_FEATURE_INDEX_LIST and KVM_GET_MSRS system ioctl

2018-10-26 Thread Robert Hoo
Add kvm_get_supported_feature_msrs() to get supported MSR feature index list.
Add kvm_arch_get_supported_msr_feature() to get each MSR features value.

Signed-off-by: Robert Hoo 
Reviewed-by: Eduardo Habkost 
---
 include/sysemu/kvm.h |  2 ++
 target/i386/kvm.c| 80 
 2 files changed, 82 insertions(+)

diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h
index 0b64b8e..97d8d9d 100644
--- a/include/sysemu/kvm.h
+++ b/include/sysemu/kvm.h
@@ -463,6 +463,8 @@ int kvm_vm_check_extension(KVMState *s, unsigned int 
extension);
 
 uint32_t kvm_arch_get_supported_cpuid(KVMState *env, uint32_t function,
   uint32_t index, int reg);
+uint32_t kvm_arch_get_supported_msr_feature(KVMState *s, uint32_t index);
+
 
 void kvm_set_sigmask_len(KVMState *s, unsigned int sigmask_len);
 
diff --git a/target/i386/kvm.c b/target/i386/kvm.c
index 115d8b4..161fc38 100644
--- a/target/i386/kvm.c
+++ b/target/i386/kvm.c
@@ -107,6 +107,7 @@ static int has_pit_state2;
 static bool has_msr_mcg_ext_ctl;
 
 static struct kvm_cpuid2 *cpuid_cache;
+static struct kvm_msr_list *kvm_feature_msrs;
 
 int kvm_has_pit_state2(void)
 {
@@ -420,6 +421,42 @@ uint32_t kvm_arch_get_supported_cpuid(KVMState *s, 
uint32_t function,
 return ret;
 }
 
+uint32_t kvm_arch_get_supported_msr_feature(KVMState *s, uint32_t index)
+{
+struct {
+struct kvm_msrs info;
+struct kvm_msr_entry entries[1];
+} msr_data;
+uint32_t ret;
+
+if (kvm_feature_msrs == NULL) { /* Host doesn't support feature MSRs */
+return 0;
+}
+
+/* Check if requested MSR is supported feature MSR */
+int i;
+for (i = 0; i < kvm_feature_msrs->nmsrs; i++)
+if (kvm_feature_msrs->indices[i] == index) {
+break;
+}
+if (i == kvm_feature_msrs->nmsrs) {
+return 0; /* if the feature MSR is not supported, simply return 0 */
+}
+
+msr_data.info.nmsrs = 1;
+msr_data.entries[0].index = index;
+
+ret = kvm_ioctl(s, KVM_GET_MSRS, _data);
+if (ret != 1) {
+error_report("KVM get MSR (index=0x%x) feature failed, %s",
+index, strerror(-ret));
+exit(1);
+}
+
+return msr_data.entries[0].data;
+}
+
+
 typedef struct HWPoisonPage {
 ram_addr_t ram_addr;
 QLIST_ENTRY(HWPoisonPage) list;
@@ -1286,6 +1323,47 @@ void kvm_arch_do_init_vcpu(X86CPU *cpu)
 }
 }
 
+static int kvm_get_supported_feature_msrs(KVMState *s)
+{
+int ret = 0;
+
+if (kvm_feature_msrs != NULL) {
+return 0;
+}
+
+if (!kvm_check_extension(s, KVM_CAP_GET_MSR_FEATURES)) {
+return 0;
+}
+
+struct kvm_msr_list msr_list;
+
+msr_list.nmsrs = 0;
+ret = kvm_ioctl(s, KVM_GET_MSR_FEATURE_INDEX_LIST, _list);
+if (ret < 0 && ret != -E2BIG) {
+error_report("Fetch KVM feature MSR list failed: %s",
+strerror(-ret));
+return ret;
+}
+
+assert(msr_list.nmsrs > 0);
+kvm_feature_msrs = (struct kvm_msr_list *) \
+g_malloc0(sizeof(msr_list) +
+ msr_list.nmsrs * sizeof(msr_list.indices[0]));
+
+kvm_feature_msrs->nmsrs = msr_list.nmsrs;
+ret = kvm_ioctl(s, KVM_GET_MSR_FEATURE_INDEX_LIST, kvm_feature_msrs);
+
+if (ret < 0) {
+error_report("Fetch KVM feature MSR list failed: %s",
+strerror(-ret));
+g_free(kvm_feature_msrs);
+kvm_feature_msrs = NULL;
+return ret;
+}
+
+return 0;
+}
+
 static int kvm_get_supported_msrs(KVMState *s)
 {
 static int kvm_supported_msrs;
@@ -1439,6 +1517,8 @@ int kvm_arch_init(MachineState *ms, KVMState *s)
 return ret;
 }
 
+kvm_get_supported_feature_msrs(s);
+
 uname();
 lm_capable_kernel = strcmp(utsname.machine, "x86_64") == 0;
 
-- 
1.8.3.1




Re: [Qemu-devel] [PATCH v5 3/3] x86: define a new MSR based feature word -- FEATURE_WORDS_ARCH_CAPABILITIES

2018-10-25 Thread Robert Hoo
On Wed, 2018-10-24 at 07:06 -0300, Eduardo Habkost wrote:
> On Mon, Oct 15, 2018 at 12:47:25PM +0800, Robert Hoo wrote:
> > Note RSBA is specially treated -- no matter host support it or not,
> > qemu
> > pretends it is supported.
> > 
> > Signed-off-by: Robert Hoo 
> 
> I am now wondering what else we need to be able to remove
> CPUID_7_0_EDX_ARCH_CAPABILITIES from
> feature_word_info[FEAT_7_0_EDX].unmigratable_flags.
> 
> This series is necessary for that, be I think we still can't let
> the VM be migrated if arch-capabilities is enabled and we're
> running on a host that doesn't have MSR_IA32_ARCH_CAPABILITIES on
> kvm_feature_msrs.
> 
> Reviewed-by: Eduardo Habkost 
> 
> > ---
> >  target/i386/cpu.c | 31 ++-
> >  target/i386/cpu.h |  8 
> >  target/i386/kvm.c | 11 +++
> >  3 files changed, 49 insertions(+), 1 deletion(-)
> > 
[...]
> >  
> >  typedef struct X86RegisterInfo32 {
> > @@ -3696,7 +3717,15 @@ static uint32_t
> > x86_cpu_get_supported_feature_word(FeatureWord w,
> >  wi-
> > >cpuid.reg);
> >  break;
> >  case MSR_FEATURE_WORD:
> > -r = kvm_arch_get_supported_msr_feature(kvm_state, wi-
> > >msr.index);
> > +/* Special case:
> > + * No matter host status, IA32_ARCH_CAPABILITIES.RSBA
> > [bit 2]
> > + * is always supported in guest.
> > + */
> > +if (wi->msr.index == MSR_IA32_ARCH_CAPABILITIES) {
> > +r = MSR_ARCH_CAP_RSBA;
> > +}
> > +r |= kvm_arch_get_supported_msr_feature(kvm_state,
> > +wi->msr.index);
> >  break;
After I add the filtering out MSR feature, whose CPUID dependency fails
, in x86_cpu_filter_features(), 1 issue comes out here: 

If running on an old platform that doesn't have ARCH_CAPABILITIES MSR,
but we still pretends it here, then qemu will always print out
"warning: host doesn't support requested feature: MSR(10AH).rsba [bit
2]", with -cpu 'host', which does not look comfortable.
How about remove this hunk for now? leave it to when we fully decide
how to handle ARCH_CAPABILITIES live-migration safely. 
> >  }
> >  } else if (hvf_enabled()) {
[...]



Re: [Qemu-devel] [PATCH v5 3/3] x86: define a new MSR based feature word -- FEATURE_WORDS_ARCH_CAPABILITIES

2018-10-24 Thread Robert Hoo
On Wed, 2018-10-24 at 07:06 -0300, Eduardo Habkost wrote:
> On Mon, Oct 15, 2018 at 12:47:25PM +0800, Robert Hoo wrote:
> > Note RSBA is specially treated -- no matter host support it or not,
> > qemu
> > pretends it is supported.
> > 
> > Signed-off-by: Robert Hoo 
> 
> I am now wondering what else we need to be able to remove
> CPUID_7_0_EDX_ARCH_CAPABILITIES from
> feature_word_info[FEAT_7_0_EDX].unmigratable_flags.

Let me know once some thought comes out to you.
> 
> This series is necessary for that, be I think we still can't let
> the VM be migrated if arch-capabilities is enabled and we're
> running on a host that doesn't have MSR_IA32_ARCH_CAPABILITIES on
> kvm_feature_msrs.

Agree. So I still keep CPUID_7_0_EDX_ARCH_CAPABILITIES in
feature_word_info[FEAT_7_0_EDX].unmigratable_flags for now.
> 
> Reviewed-by: Eduardo Habkost 
> 
> > ---
> >  target/i386/cpu.c | 31 ++-
> >  target/i386/cpu.h |  8 
> >  target/i386/kvm.c | 11 +++
> >  3 files changed, 49 insertions(+), 1 deletion(-)
> > 
> > diff --git a/target/i386/cpu.c b/target/i386/cpu.c
> > index d191b9c..51c8fd8 100644
> > --- a/target/i386/cpu.c
> > +++ b/target/i386/cpu.c
> > @@ -1141,6 +1141,27 @@ static FeatureWordInfo
> > feature_word_info[FEATURE_WORDS] = {
> >  },
> >  .tcg_features = ~0U,
> >  },
> > +/*Below are MSR exposed features*/
> > +[FEAT_ARCH_CAPABILITIES] = {
> > +.type = MSR_FEATURE_WORD,
> > +.feat_names = {
> > +"rdctl-no", "ibrs-all", "rsba", "skip-l1dfl-vmentry",
> > +"ssb-no", NULL, NULL, NULL,
> > +NULL, NULL, NULL, NULL,
> > +NULL, NULL, NULL, NULL,
> > +NULL, NULL, NULL, NULL,
> > +NULL, NULL, NULL, NULL,
> > +NULL, NULL, NULL, NULL,
> > +NULL, NULL, NULL, NULL,
> > +},
> > +.msr = {
> > +.index = MSR_IA32_ARCH_CAPABILITIES,
> > +.cpuid_dep = {
> > +FEAT_7_0_EDX,
> > +CPUID_7_0_EDX_ARCH_CAPABILITIES
> > +}
> > +},
> > +},
> >  };
> >  
> >  typedef struct X86RegisterInfo32 {
> > @@ -3696,7 +3717,15 @@ static uint32_t
> > x86_cpu_get_supported_feature_word(FeatureWord w,
> >  wi-
> > >cpuid.reg);
> >  break;
> >  case MSR_FEATURE_WORD:
> > -r = kvm_arch_get_supported_msr_feature(kvm_state, wi-
> > >msr.index);
> > +/* Special case:
> > + * No matter host status, IA32_ARCH_CAPABILITIES.RSBA
> > [bit 2]
> > + * is always supported in guest.
> > + */
> > +if (wi->msr.index == MSR_IA32_ARCH_CAPABILITIES) {
> > +r = MSR_ARCH_CAP_RSBA;
> > +}
> > +r |= kvm_arch_get_supported_msr_feature(kvm_state,
> > +wi->msr.index);
> >  break;
> >  }
> >  } else if (hvf_enabled()) {
> > diff --git a/target/i386/cpu.h b/target/i386/cpu.h
> > index 730c06f..52a52ec 100644
> > --- a/target/i386/cpu.h
> > +++ b/target/i386/cpu.h
> > @@ -502,6 +502,7 @@ typedef enum FeatureWord {
> >  FEAT_6_EAX, /* CPUID[6].EAX */
> >  FEAT_XSAVE_COMP_LO, /* CPUID[EAX=0xd,ECX=0].EAX */
> >  FEAT_XSAVE_COMP_HI, /* CPUID[EAX=0xd,ECX=0].EDX */
> > +FEAT_ARCH_CAPABILITIES,
> >  FEATURE_WORDS,
> >  } FeatureWord;
> >  
> > @@ -730,6 +731,13 @@ typedef uint32_t
> > FeatureWordArray[FEATURE_WORDS];
> >  #define CPUID_TOPOLOGY_LEVEL_SMT  (1U << 8)
> >  #define CPUID_TOPOLOGY_LEVEL_CORE (2U << 8)
> >  
> > +/* MSR Feature Bits */
> > +#define MSR_ARCH_CAP_RDCL_NO(1U << 0)
> > +#define MSR_ARCH_CAP_IBRS_ALL   (1U << 1)
> > +#define MSR_ARCH_CAP_RSBA   (1U << 2)
> > +#define MSR_ARCH_CAP_SKIP_L1DFL_VMENTRY (1U << 3)
> > +#define MSR_ARCH_CAP_SSB_NO (1U << 4)
> > +
> >  #ifndef HYPERV_SPINLOCK_NEVER_RETRY
> >  #define HYPERV_SPINLOCK_NEVER_RETRY 0x
> >  #endif
> > diff --git a/target/i386/kvm.c b/target/i386/kvm.c
> > index db79dad..2f7b40d 100644
> > --- a/target/i386/kvm.c
> > +++ b/target/i386/kvm.c
> > @@ -1928,6 +1928,17 @@ static int kvm_put_msrs(X86CPU *cpu, int
> > level)
> >  }
> >  #endif
> >  
> > +/* If host supports feature MSR, write down. */
> > +if (kvm_feature_msrs) {
> > +int i;
> > +for (i = 0; i < kvm_feature_msrs->nmsrs; i++)
> > +if (kvm_feature_msrs->indices[i] ==
> > MSR_IA32_ARCH_CAPABILITIES) {
> > +kvm_msr_entry_add(cpu, MSR_IA32_ARCH_CAPABILITIES,
> > +  env-
> > >features[FEAT_ARCH_CAPABILITIES]);
> > +break;
> > +}
> > +}
> > +
> >  /*
> >   * The following MSRs have side effects on the guest or are
> > too heavy
> >   * for normal writeback. Limit them to reset or full state
> > updates.
> > -- 
> > 1.8.3.1
> > 
> > 
> 
> 



Re: [Qemu-devel] [PATCH v5 2/3] x86: Data structure changes to support MSR based features

2018-10-24 Thread Robert Hoo
On Wed, 2018-10-24 at 07:16 -0300, Eduardo Habkost wrote:
> On Mon, Oct 15, 2018 at 12:47:24PM +0800, Robert Hoo wrote:
> > Add FeatureWordType indicator in struct FeatureWordInfo.
> > Change feature_word_info[] accordingly.
> > Change existing functions that refer to feature_word_info[]
> > accordingly.
> > 
> > Signed-off-by: Robert Hoo 
> > ---
> >  target/i386/cpu.c | 188 +++---
> > 
> >  1 file changed, 136 insertions(+), 52 deletions(-)
> > 
> > diff --git a/target/i386/cpu.c b/target/i386/cpu.c
> > index c88876d..d191b9c 100644
> > --- a/target/i386/cpu.c
> > +++ b/target/i386/cpu.c
> > @@ -770,17 +770,36 @@ static void x86_cpu_vendor_words2str(char
> > *dst, uint32_t vendor1,
> >    /* missing:
> >    CPUID_XSAVE_XSAVEC, CPUID_XSAVE_XSAVES */
> >  
> > +typedef enum FeatureWordType {
> > +   CPUID_FEATURE_WORD,
> > +   MSR_FEATURE_WORD,
> > +} FeatureWordType;
> > +
> >  typedef struct FeatureWordInfo {
> > +FeatureWordType type;
> >  /* feature flags names are taken from "Intel Processor
> > Identification and
> >   * the CPUID Instruction" and AMD's "CPUID Specification".
> >   * In cases of disagreement between feature naming
> > conventions,
> >   * aliases may be added.
> >   */
> >  const char *feat_names[32];
> > -uint32_t cpuid_eax;   /* Input EAX for CPUID */
> > -bool cpuid_needs_ecx; /* CPUID instruction uses ECX as input
> > */
> > -uint32_t cpuid_ecx;   /* Input ECX value for CPUID */
> > -int cpuid_reg;/* output register (R_* constant) */
> > +union {
> > +/* If type==CPUID_FEATURE_WORD */
> > +struct {
> > +uint32_t eax;   /* Input EAX for CPUID */
> > +bool needs_ecx; /* CPUID instruction uses ECX as input
> > */
> > +uint32_t ecx;   /* Input ECX value for CPUID */
> > +int reg;/* output register (R_* constant) */
> > +} cpuid;
> > +/* If type==MSR_FEATURE_WORD */
> > +struct {
> > +uint32_t index;
> > +struct {   /*CPUID that enumerate this MSR*/
> > +FeatureWord cpuid_class;
> > +uint32_tcpuid_flag;
> > +} cpuid_dep;
> 
> Aren't you going to use this field anywhere?  Probably we want to
> prevent the VM from starting if a bit is set in the feature world
> but the cpuid_dep bit is not set.
> 
> e.g.:
>   qemu-system-x86_64 -cpu Skylake-Client,-arch-capabilities,+rsba
> probably should fail to start.

How about in x86_cpu_filter_features() filters the MSR feature word, if
 its dependent CPUID feature bit is not set?
The filter results will be record in cpu->filtered_features, and print
out, like other filtered features.
> 
> > +} msr;
> > +};
> 
> [...]
> 



[Qemu-devel] [PATCH v5 2/3] x86: Data structure changes to support MSR based features

2018-10-14 Thread Robert Hoo
Add FeatureWordType indicator in struct FeatureWordInfo.
Change feature_word_info[] accordingly.
Change existing functions that refer to feature_word_info[] accordingly.

Signed-off-by: Robert Hoo 
---
 target/i386/cpu.c | 188 +++---
 1 file changed, 136 insertions(+), 52 deletions(-)

diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index c88876d..d191b9c 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -770,17 +770,36 @@ static void x86_cpu_vendor_words2str(char *dst, uint32_t 
vendor1,
   /* missing:
   CPUID_XSAVE_XSAVEC, CPUID_XSAVE_XSAVES */
 
+typedef enum FeatureWordType {
+   CPUID_FEATURE_WORD,
+   MSR_FEATURE_WORD,
+} FeatureWordType;
+
 typedef struct FeatureWordInfo {
+FeatureWordType type;
 /* feature flags names are taken from "Intel Processor Identification and
  * the CPUID Instruction" and AMD's "CPUID Specification".
  * In cases of disagreement between feature naming conventions,
  * aliases may be added.
  */
 const char *feat_names[32];
-uint32_t cpuid_eax;   /* Input EAX for CPUID */
-bool cpuid_needs_ecx; /* CPUID instruction uses ECX as input */
-uint32_t cpuid_ecx;   /* Input ECX value for CPUID */
-int cpuid_reg;/* output register (R_* constant) */
+union {
+/* If type==CPUID_FEATURE_WORD */
+struct {
+uint32_t eax;   /* Input EAX for CPUID */
+bool needs_ecx; /* CPUID instruction uses ECX as input */
+uint32_t ecx;   /* Input ECX value for CPUID */
+int reg;/* output register (R_* constant) */
+} cpuid;
+/* If type==MSR_FEATURE_WORD */
+struct {
+uint32_t index;
+struct {   /*CPUID that enumerate this MSR*/
+FeatureWord cpuid_class;
+uint32_tcpuid_flag;
+} cpuid_dep;
+} msr;
+};
 uint32_t tcg_features; /* Feature flags supported by TCG */
 uint32_t unmigratable_flags; /* Feature flags known to be unmigratable */
 uint32_t migratable_flags; /* Feature flags known to be migratable */
@@ -790,6 +809,7 @@ typedef struct FeatureWordInfo {
 
 static FeatureWordInfo feature_word_info[FEATURE_WORDS] = {
 [FEAT_1_EDX] = {
+.type = CPUID_FEATURE_WORD,
 .feat_names = {
 "fpu", "vme", "de", "pse",
 "tsc", "msr", "pae", "mce",
@@ -800,10 +820,11 @@ static FeatureWordInfo feature_word_info[FEATURE_WORDS] = 
{
 "fxsr", "sse", "sse2", "ss",
 "ht" /* Intel htt */, "tm", "ia64", "pbe",
 },
-.cpuid_eax = 1, .cpuid_reg = R_EDX,
+.cpuid = {.eax = 1, .reg = R_EDX, },
 .tcg_features = TCG_FEATURES,
 },
 [FEAT_1_ECX] = {
+.type = CPUID_FEATURE_WORD,
 .feat_names = {
 "pni" /* Intel,AMD sse3 */, "pclmulqdq", "dtes64", "monitor",
 "ds-cpl", "vmx", "smx", "est",
@@ -814,7 +835,7 @@ static FeatureWordInfo feature_word_info[FEATURE_WORDS] = {
 "tsc-deadline", "aes", "xsave", NULL /* osxsave */,
 "avx", "f16c", "rdrand", "hypervisor",
 },
-.cpuid_eax = 1, .cpuid_reg = R_ECX,
+.cpuid = { .eax = 1, .reg = R_ECX, },
 .tcg_features = TCG_EXT_FEATURES,
 },
 /* Feature names that are already defined on feature_name[] but
@@ -823,6 +844,7 @@ static FeatureWordInfo feature_word_info[FEATURE_WORDS] = {
  * to features[FEAT_8000_0001_EDX] if and only if CPU vendor is AMD.
  */
 [FEAT_8000_0001_EDX] = {
+.type = CPUID_FEATURE_WORD,
 .feat_names = {
 NULL /* fpu */, NULL /* vme */, NULL /* de */, NULL /* pse */,
 NULL /* tsc */, NULL /* msr */, NULL /* pae */, NULL /* mce */,
@@ -833,10 +855,11 @@ static FeatureWordInfo feature_word_info[FEATURE_WORDS] = 
{
 NULL /* fxsr */, "fxsr-opt", "pdpe1gb", "rdtscp",
 NULL, "lm", "3dnowext", "3dnow",
 },
-.cpuid_eax = 0x8001, .cpuid_reg = R_EDX,
+.cpuid = { .eax = 0x8001, .reg = R_EDX, },
 .tcg_features = TCG_EXT2_FEATURES,
 },
 [FEAT_8000_0001_ECX] = {
+.type = CPUID_FEATURE_WORD,
 .feat_names = {
 "lahf-lm", "cmp-legacy", "svm", "extapic",
 "cr8legacy", "abm", "sse4a", "misalignsse",
@@ -847,7 +870,7 @@ static FeatureWordInfo feature_word_info[FEATURE_WORDS] = {
 "perfctr-nb", NULL, NULL, NULL,
  

[Qemu-devel] [PATCH v5 3/3] x86: define a new MSR based feature word -- FEATURE_WORDS_ARCH_CAPABILITIES

2018-10-14 Thread Robert Hoo
Note RSBA is specially treated -- no matter host support it or not, qemu
pretends it is supported.

Signed-off-by: Robert Hoo 
---
 target/i386/cpu.c | 31 ++-
 target/i386/cpu.h |  8 
 target/i386/kvm.c | 11 +++
 3 files changed, 49 insertions(+), 1 deletion(-)

diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index d191b9c..51c8fd8 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -1141,6 +1141,27 @@ static FeatureWordInfo feature_word_info[FEATURE_WORDS] 
= {
 },
 .tcg_features = ~0U,
 },
+/*Below are MSR exposed features*/
+[FEAT_ARCH_CAPABILITIES] = {
+.type = MSR_FEATURE_WORD,
+.feat_names = {
+"rdctl-no", "ibrs-all", "rsba", "skip-l1dfl-vmentry",
+"ssb-no", NULL, NULL, NULL,
+NULL, NULL, NULL, NULL,
+NULL, NULL, NULL, NULL,
+NULL, NULL, NULL, NULL,
+NULL, NULL, NULL, NULL,
+NULL, NULL, NULL, NULL,
+NULL, NULL, NULL, NULL,
+},
+.msr = {
+.index = MSR_IA32_ARCH_CAPABILITIES,
+.cpuid_dep = {
+FEAT_7_0_EDX,
+CPUID_7_0_EDX_ARCH_CAPABILITIES
+}
+},
+},
 };
 
 typedef struct X86RegisterInfo32 {
@@ -3696,7 +3717,15 @@ static uint32_t 
x86_cpu_get_supported_feature_word(FeatureWord w,
 wi->cpuid.reg);
 break;
 case MSR_FEATURE_WORD:
-r = kvm_arch_get_supported_msr_feature(kvm_state, wi->msr.index);
+/* Special case:
+ * No matter host status, IA32_ARCH_CAPABILITIES.RSBA [bit 2]
+ * is always supported in guest.
+ */
+if (wi->msr.index == MSR_IA32_ARCH_CAPABILITIES) {
+r = MSR_ARCH_CAP_RSBA;
+}
+r |= kvm_arch_get_supported_msr_feature(kvm_state,
+wi->msr.index);
 break;
 }
 } else if (hvf_enabled()) {
diff --git a/target/i386/cpu.h b/target/i386/cpu.h
index 730c06f..52a52ec 100644
--- a/target/i386/cpu.h
+++ b/target/i386/cpu.h
@@ -502,6 +502,7 @@ typedef enum FeatureWord {
 FEAT_6_EAX, /* CPUID[6].EAX */
 FEAT_XSAVE_COMP_LO, /* CPUID[EAX=0xd,ECX=0].EAX */
 FEAT_XSAVE_COMP_HI, /* CPUID[EAX=0xd,ECX=0].EDX */
+FEAT_ARCH_CAPABILITIES,
 FEATURE_WORDS,
 } FeatureWord;
 
@@ -730,6 +731,13 @@ typedef uint32_t FeatureWordArray[FEATURE_WORDS];
 #define CPUID_TOPOLOGY_LEVEL_SMT  (1U << 8)
 #define CPUID_TOPOLOGY_LEVEL_CORE (2U << 8)
 
+/* MSR Feature Bits */
+#define MSR_ARCH_CAP_RDCL_NO(1U << 0)
+#define MSR_ARCH_CAP_IBRS_ALL   (1U << 1)
+#define MSR_ARCH_CAP_RSBA   (1U << 2)
+#define MSR_ARCH_CAP_SKIP_L1DFL_VMENTRY (1U << 3)
+#define MSR_ARCH_CAP_SSB_NO (1U << 4)
+
 #ifndef HYPERV_SPINLOCK_NEVER_RETRY
 #define HYPERV_SPINLOCK_NEVER_RETRY 0x
 #endif
diff --git a/target/i386/kvm.c b/target/i386/kvm.c
index db79dad..2f7b40d 100644
--- a/target/i386/kvm.c
+++ b/target/i386/kvm.c
@@ -1928,6 +1928,17 @@ static int kvm_put_msrs(X86CPU *cpu, int level)
 }
 #endif
 
+/* If host supports feature MSR, write down. */
+if (kvm_feature_msrs) {
+int i;
+for (i = 0; i < kvm_feature_msrs->nmsrs; i++)
+if (kvm_feature_msrs->indices[i] == MSR_IA32_ARCH_CAPABILITIES) {
+kvm_msr_entry_add(cpu, MSR_IA32_ARCH_CAPABILITIES,
+  env->features[FEAT_ARCH_CAPABILITIES]);
+break;
+}
+}
+
 /*
  * The following MSRs have side effects on the guest or are too heavy
  * for normal writeback. Limit them to reset or full state updates.
-- 
1.8.3.1




[Qemu-devel] [PATCH v5 1/3] kvm: Add support to KVM_GET_MSR_FEATURE_INDEX_LIST and KVM_GET_MSRS system ioctl

2018-10-14 Thread Robert Hoo
Add kvm_get_supported_feature_msrs() to get supported MSR feature index list.
Add kvm_arch_get_supported_msr_feature() to get each MSR features value.

Signed-off-by: Robert Hoo 
---
 include/sysemu/kvm.h |  2 ++
 target/i386/kvm.c| 80 
 2 files changed, 82 insertions(+)

diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h
index 0b64b8e..97d8d9d 100644
--- a/include/sysemu/kvm.h
+++ b/include/sysemu/kvm.h
@@ -463,6 +463,8 @@ int kvm_vm_check_extension(KVMState *s, unsigned int 
extension);
 
 uint32_t kvm_arch_get_supported_cpuid(KVMState *env, uint32_t function,
   uint32_t index, int reg);
+uint32_t kvm_arch_get_supported_msr_feature(KVMState *s, uint32_t index);
+
 
 void kvm_set_sigmask_len(KVMState *s, unsigned int sigmask_len);
 
diff --git a/target/i386/kvm.c b/target/i386/kvm.c
index dc4047b..db79dad 100644
--- a/target/i386/kvm.c
+++ b/target/i386/kvm.c
@@ -107,6 +107,7 @@ static int has_pit_state2;
 static bool has_msr_mcg_ext_ctl;
 
 static struct kvm_cpuid2 *cpuid_cache;
+static struct kvm_msr_list *kvm_feature_msrs;
 
 int kvm_has_pit_state2(void)
 {
@@ -420,6 +421,42 @@ uint32_t kvm_arch_get_supported_cpuid(KVMState *s, 
uint32_t function,
 return ret;
 }
 
+uint32_t kvm_arch_get_supported_msr_feature(KVMState *s, uint32_t index)
+{
+struct {
+struct kvm_msrs info;
+struct kvm_msr_entry entries[1];
+} msr_data;
+uint32_t ret;
+
+if (kvm_feature_msrs == NULL) { /* Host doesn't support feature MSRs */
+return 0;
+}
+
+/* Check if requested MSR is supported feature MSR */
+int i;
+for (i = 0; i < kvm_feature_msrs->nmsrs; i++)
+if (kvm_feature_msrs->indices[i] == index) {
+break;
+}
+if (i == kvm_feature_msrs->nmsrs) {
+return 0; /* if the feature MSR is not supported, simply return 0 */
+}
+
+msr_data.info.nmsrs = 1;
+msr_data.entries[0].index = index;
+
+ret = kvm_ioctl(s, KVM_GET_MSRS, _data);
+if (ret != 1) {
+error_report("KVM get MSR (index=0x%x) feature failed, %s",
+index, strerror(-ret));
+exit(1);
+}
+
+return msr_data.entries[0].data;
+}
+
+
 typedef struct HWPoisonPage {
 ram_addr_t ram_addr;
 QLIST_ENTRY(HWPoisonPage) list;
@@ -1239,6 +1276,47 @@ void kvm_arch_do_init_vcpu(X86CPU *cpu)
 }
 }
 
+static int kvm_get_supported_feature_msrs(KVMState *s)
+{
+int ret = 0;
+
+if (kvm_feature_msrs != NULL) {
+return 0;
+}
+
+if (!kvm_check_extension(s, KVM_CAP_GET_MSR_FEATURES)) {
+return 0;
+}
+
+struct kvm_msr_list msr_list;
+
+msr_list.nmsrs = 0;
+ret = kvm_ioctl(s, KVM_GET_MSR_FEATURE_INDEX_LIST, _list);
+if (ret < 0 && ret != -E2BIG) {
+error_report("Fetch KVM feature MSR list failed: %s",
+strerror(-ret));
+return ret;
+}
+
+assert(msr_list.nmsrs > 0);
+kvm_feature_msrs = (struct kvm_msr_list *) \
+g_malloc0(sizeof(msr_list) +
+ msr_list.nmsrs * sizeof(msr_list.indices[0]));
+
+kvm_feature_msrs->nmsrs = msr_list.nmsrs;
+ret = kvm_ioctl(s, KVM_GET_MSR_FEATURE_INDEX_LIST, kvm_feature_msrs);
+
+if (ret < 0) {
+error_report("Fetch KVM feature MSR list failed: %s",
+strerror(-ret));
+g_free(kvm_feature_msrs);
+kvm_feature_msrs = NULL;
+return ret;
+}
+
+return 0;
+}
+
 static int kvm_get_supported_msrs(KVMState *s)
 {
 static int kvm_supported_msrs;
@@ -1392,6 +1470,8 @@ int kvm_arch_init(MachineState *ms, KVMState *s)
 return ret;
 }
 
+kvm_get_supported_feature_msrs(s);
+
 uname();
 lm_capable_kernel = strcmp(utsname.machine, "x86_64") == 0;
 
-- 
1.8.3.1




[Qemu-devel] [PATCH v5 0/3] x86: QEMU side support on MSR based features

2018-10-14 Thread Robert Hoo
KVM side has added the framework (kvm.git:d1d93fa90) to support MSR based 
features.
Here is the QEMU part, including data structure changes/expanding, referring
functions changes, and the implementations on 
KVM_GET_MSR_FEATURE_INDEX_LIST and KVM_GET_MSRS system ioctl.

Changelog:
v5: Re-order patches. Complement feature MSR set routines.
v4:
Re-organize patch set to conform to request of individually build pass.
Add KVM capability check for KVM_GET_MSR_INDEX_LIST before fetch.
Special treatment for MSR_IA32_ARCH_CAPABILITIES.RSBA.
Use more convenient glib wrapper (g_strdup_printf) instead of native
(sprintf).

v3: patch 2&3 in v2 are corrupted. Re-format patches.
v2: coding style changes to pass ./scripts/checkpatch.pl.


Robert Hoo (3):
  kvm: Add support to KVM_GET_MSR_FEATURE_INDEX_LIST and KVM_GET_MSRS
system ioctl
  x86: Data structure changes to support MSR based features
  x86: define a new MSR based feature word --
FEATURE_WORDS_ARCH_CAPABILITIES

 include/sysemu/kvm.h |   2 +
 target/i386/cpu.c| 217 +++
 target/i386/cpu.h|   8 ++
 target/i386/kvm.c|  91 +
 4 files changed, 266 insertions(+), 52 deletions(-)

-- 
1.8.3.1




Re: [Qemu-devel] [PATCH v4 3/3] x86: define a new MSR based feature word -- FEATURE_WORDS_ARCH_CAPABILITIES

2018-09-20 Thread Robert Hoo
On Thu, 2018-09-20 at 14:18 -0300, Eduardo Habkost wrote:
> On Thu, Sep 20, 2018 at 05:55:48PM +0800, Robert Hoo wrote:
> > On Thu, 2018-09-20 at 00:13 -0300, Eduardo Habkost wrote:
> > > On Sun, Sep 02, 2018 at 07:46:07PM +0800, Robert Hoo wrote:
> > > > Note RSBA is specially treated -- no matter host support it or
> > > > not,
> > > > qemu
> > > > pretends it is supported.
> > > > 
> > > > Signed-off-by: Robert Hoo 
> > > > ---
> > > >  target/i386/cpu.c | 27 ++-
> > > >  target/i386/cpu.h | 12 
> > > >  2 files changed, 38 insertions(+), 1 deletion(-)
> > > > 
> > > > diff --git a/target/i386/cpu.c b/target/i386/cpu.c
> > > > index 0160e97..8ec9613 100644
> > > > --- a/target/i386/cpu.c
> > > > +++ b/target/i386/cpu.c
> > > > @@ -1129,6 +1129,24 @@ static FeatureWordInfo
> > > > feature_word_info[FEATURE_WORDS] = {
> > > >  .reg = R_EDX, },
> > > >  .tcg_features = ~0U,
> > > >  },
> > > > +/*Below are MSR exposed features*/
> > > > +[FEATURE_WORDS_ARCH_CAPABILITIES] = {
> > > > +.type = MSR_FEATURE_WORD,
> > > > +.feat_names = {
> > > > +"rdctl-no", "ibrs-all", "rsba", NULL,
> > > > +"ssb-no", NULL, NULL, NULL,
> > > > +NULL, NULL, NULL, NULL,
> > > > +NULL, NULL, NULL, NULL,
> > > > +NULL, NULL, NULL, NULL,
> > > > +NULL, NULL, NULL, NULL,
> > > > +NULL, NULL, NULL, NULL,
> > > > +NULL, NULL, NULL, NULL,
> > > > +},
> > > > +.msr = { .index = MSR_IA32_ARCH_CAPABILITIES,
> > > > +.cpuid_dep = { FEAT_7_0_EDX,
> > > > +CPUID_7_0_EDX_ARCH_CAPABILITIES }
> > > > +},
> > > > +},
> > > 
> > > One critical piece of the code seems to be missing: where exactly
> > > is the MSR value being set on the VCPU before it runs?
> > > 
> > 
> > I don't quite understand. Isn't such feature MSR read-only, like
> > CPUID,
> > simply to enumerate features?
> 
> The MSR is read-only for the guest, yes.  But QEMU needs to call
> KVM_SET_MSRS somewhere, to tell KVM what's the MSR value the
> guest should see.  I don't see any code doing that.
> 
I think: these feature MSRs are separated from other MSRs. Those MSRs
information are stored in X86CPU->kvm_msr_buf, they are set/get through
 vcpu ioctl KVM_SET_MSRS and KVM_GET_MSRS. While feature MSRs are
actually system ioctl, their return value are determined by KVM/Host,
i.e. not necessary set by guest, nor to be vcpu level.
> > [...]
> 
> 



Re: [Qemu-devel] [PATCH v4 2/3] kvm: Add support to KVM_GET_MSR_FEATURE_INDEX_LIST and KVM_GET_MSRS system ioctl

2018-09-20 Thread Robert Hoo
On Thu, 2018-09-20 at 14:22 -0300, Eduardo Habkost wrote:
> On Thu, Sep 20, 2018 at 03:45:42PM +0800, Robert Hoo wrote:
> [...]
> > > > diff --git a/target/i386/cpu.c b/target/i386/cpu.c
> > > > index a252c26..0160e97 100644
> > > > --- a/target/i386/cpu.c
> > > > +++ b/target/i386/cpu.c
> > > > @@ -3670,7 +3670,7 @@ static uint32_t
> > > > x86_cpu_get_supported_feature_word(FeatureWord w,
> > > > bool
> > > > migratable_only)
> > > >  {
> > > >  FeatureWordInfo *wi = _word_info[w];
> > > > -uint32_t r;
> > > > +uint32_t r = 0;
> > > >  
> > > >  if (kvm_enabled()) {
> > > >  switch (wi->type) {
> > > > @@ -3679,8 +3679,9 @@ static uint32_t
> > > > x86_cpu_get_supported_feature_word(FeatureWord w,
> > > >  wi->cpuid.ecx,
> > > >  wi-
> > > > >cpuid.reg);
> > > >  break;
> > > > -default:
> > > > -r = 0;
> > > > +case MSR_FEATURE_WORD:
> > > > +r = kvm_arch_get_supported_msr_feature(kvm_state,
> > > > +wi->msr.index);
> > > 
> > > If you move this patch before patch 1/3, this hunk could be part
> > > of patch 1/3.
> > > 
> > 
> > I'm afraid that if I moved this hunk, because of the dependency, I
> > would have to move the definition of
> > kvm_arch_get_supported_msr_feature() to patch 1/3, then in turn, it
> > used kvm_feature_msrs, I've to put its definition and
> > initialization
> > function kvm_get_supported_feature_msrs() to patch 1/3 as well.
> > Then
> > actually, this makes patch 1/3 and 2/3 merged into 1. Would you
> > like me
> > to do so?
> 
> I don't get it.  Why would you need to move the definition of
> kvm_arch_get_supported_cpuid() to patch 1/3, if we change the
> patch order and apply this patch before patch 1/3?
> 
OK, so you mean simply switch the 1/3 and 2/3 order, not move some
hunks of 2/3 into 1/3. Am I right?



Re: [Qemu-devel] [PATCH v4 3/3] x86: define a new MSR based feature word -- FEATURE_WORDS_ARCH_CAPABILITIES

2018-09-20 Thread Robert Hoo
On Thu, 2018-09-20 at 00:13 -0300, Eduardo Habkost wrote:
> On Sun, Sep 02, 2018 at 07:46:07PM +0800, Robert Hoo wrote:
> > Note RSBA is specially treated -- no matter host support it or not,
> > qemu
> > pretends it is supported.
> > 
> > Signed-off-by: Robert Hoo 
> > ---
> >  target/i386/cpu.c | 27 ++-
> >  target/i386/cpu.h | 12 
> >  2 files changed, 38 insertions(+), 1 deletion(-)
> > 
> > diff --git a/target/i386/cpu.c b/target/i386/cpu.c
> > index 0160e97..8ec9613 100644
> > --- a/target/i386/cpu.c
> > +++ b/target/i386/cpu.c
> > @@ -1129,6 +1129,24 @@ static FeatureWordInfo
> > feature_word_info[FEATURE_WORDS] = {
> >  .reg = R_EDX, },
> >  .tcg_features = ~0U,
> >  },
> > +/*Below are MSR exposed features*/
> > +[FEATURE_WORDS_ARCH_CAPABILITIES] = {
> > +.type = MSR_FEATURE_WORD,
> > +.feat_names = {
> > +"rdctl-no", "ibrs-all", "rsba", NULL,
> > +"ssb-no", NULL, NULL, NULL,
> > +NULL, NULL, NULL, NULL,
> > +NULL, NULL, NULL, NULL,
> > +NULL, NULL, NULL, NULL,
> > +NULL, NULL, NULL, NULL,
> > +NULL, NULL, NULL, NULL,
> > +NULL, NULL, NULL, NULL,
> > +},
> > +.msr = { .index = MSR_IA32_ARCH_CAPABILITIES,
> > +.cpuid_dep = { FEAT_7_0_EDX,
> > +CPUID_7_0_EDX_ARCH_CAPABILITIES }
> > +},
> > +},
> 
> One critical piece of the code seems to be missing: where exactly
> is the MSR value being set on the VCPU before it runs?
> 
I don't quite understand. Isn't such feature MSR read-only, like CPUID,
simply to enumerate features?
> 
> >  };
> >  
> >  typedef struct X86RegisterInfo32 {
> > @@ -3680,7 +3698,14 @@ static uint32_t
> > x86_cpu_get_supported_feature_word(FeatureWord w,
> >  wi->cpuid.reg);
> >  break;
> >  case MSR_FEATURE_WORD:
> > -r = kvm_arch_get_supported_msr_feature(kvm_state,
> > +/* Special case:
> > + * No matter host status, IA32_ARCH_CAPABILITIES.RSBA
> > [bit 2]
> > + * is always supported in guest.
> > + */
> > +if (wi->msr.index == MSR_IA32_ARCH_CAPABILITIES) {
> > +r = MSR_ARCH_CAP_RSBA;
> > +}
> > +r |= kvm_arch_get_supported_msr_feature(kvm_state,
> >  wi->msr.index);
> >  break;
> >  }
> > diff --git a/target/i386/cpu.h b/target/i386/cpu.h
> > index b572a8e..9662730 100644
> > --- a/target/i386/cpu.h
> > +++ b/target/i386/cpu.h
> > @@ -502,9 +502,14 @@ typedef enum FeatureWord {
> >  FEAT_6_EAX, /* CPUID[6].EAX */
> >  FEAT_XSAVE_COMP_LO, /* CPUID[EAX=0xd,ECX=0].EAX */
> >  FEAT_XSAVE_COMP_HI, /* CPUID[EAX=0xd,ECX=0].EDX */
> > +FEATURE_WORDS_NUM_CPUID,
> > +FEATURE_WORDS_FIRST_MSR = FEATURE_WORDS_NUM_CPUID,
> > +FEATURE_WORDS_ARCH_CAPABILITIES = FEATURE_WORDS_FIRST_MSR,
> >  FEATURE_WORDS,
> >  } FeatureWord;
> >  
> > +#define FEATURE_WORDS_NUM_MSRS (FEATURE_WORDS -
> > FEATURE_WORDS_FIRST_MSR)
> 
> I don't see FEATURE_WORDS_NUM_CPUID, FEATURE_WORDS_FIRST_MS and
> FEATURE_WORDS_NUM_MSRS being used anywhere.  Why are they being
> introduced?
> 
Get rid of them in v5.
> 
> > +
> >  typedef uint32_t FeatureWordArray[FEATURE_WORDS];
> >  
> >  /* cpuid_features bits */
> > @@ -730,6 +735,13 @@ typedef uint32_t
> > FeatureWordArray[FEATURE_WORDS];
> >  #define CPUID_TOPOLOGY_LEVEL_SMT  (1U << 8)
> >  #define CPUID_TOPOLOGY_LEVEL_CORE (2U << 8)
> >  
> > +/* MSR Feature Bits */
> > +#define MSR_ARCH_CAP_RDCL_NO(1U << 0)
> > +#define MSR_ARCH_CAP_IBRS_ALL   (1U << 1)
> > +#define MSR_ARCH_CAP_RSBA   (1U << 2)
> > +#define MSR_ARCH_CAP_SKIP_L1DFL_VMENTRY (1U << 3)
> > +#define MSR_ARCH_CAP_SSB_NO (1U << 4)
> > +
> >  #ifndef HYPERV_SPINLOCK_NEVER_RETRY
> >  #define HYPERV_SPINLOCK_NEVER_RETRY 0x
> >  #endif
> > -- 
> > 1.8.3.1
> > 
> > 
> 
> 



Re: [Qemu-devel] [PATCH v4 2/3] kvm: Add support to KVM_GET_MSR_FEATURE_INDEX_LIST and KVM_GET_MSRS system ioctl

2018-09-20 Thread Robert Hoo
On Thu, 2018-09-20 at 00:07 -0300, Eduardo Habkost wrote:
> Hi,
> 
> Thanks for the patch and sorry for taking so long to review it.

Never mind. I understand you're really busy. :-)
> 
> On Sun, Sep 02, 2018 at 07:46:06PM +0800, Robert Hoo wrote:
> > Add kvm_get_supported_feature_msrs() to get supported MSR feature
> > index list.
> > Add kvm_arch_get_supported_msr_feature() to get each MSR features
> > value.
> > 
> > Signed-off-by: Robert Hoo 
> > ---
> >  include/sysemu/kvm.h |  2 ++
> >  target/i386/cpu.c|  7 ++---
> >  target/i386/kvm.c| 72
> > 
> >  3 files changed, 78 insertions(+), 3 deletions(-)
> > 
> > diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h
> > index 0b64b8e..97d8d9d 100644
> > --- a/include/sysemu/kvm.h
> > +++ b/include/sysemu/kvm.h
> > @@ -463,6 +463,8 @@ int kvm_vm_check_extension(KVMState *s,
> > unsigned int extension);
> >  
> >  uint32_t kvm_arch_get_supported_cpuid(KVMState *env, uint32_t
> > function,
> >    uint32_t index, int reg);
> > +uint32_t kvm_arch_get_supported_msr_feature(KVMState *s, uint32_t
> > index);
> > +
> >  
> >  void kvm_set_sigmask_len(KVMState *s, unsigned int sigmask_len);
> >  
> > diff --git a/target/i386/cpu.c b/target/i386/cpu.c
> > index a252c26..0160e97 100644
> > --- a/target/i386/cpu.c
> > +++ b/target/i386/cpu.c
> > @@ -3670,7 +3670,7 @@ static uint32_t
> > x86_cpu_get_supported_feature_word(FeatureWord w,
> > bool
> > migratable_only)
> >  {
> >  FeatureWordInfo *wi = _word_info[w];
> > -uint32_t r;
> > +uint32_t r = 0;
> >  
> >  if (kvm_enabled()) {
> >  switch (wi->type) {
> > @@ -3679,8 +3679,9 @@ static uint32_t
> > x86_cpu_get_supported_feature_word(FeatureWord w,
> >  wi->cpuid.ecx,
> >  wi->cpuid.reg);
> >  break;
> > -default:
> > -r = 0;
> > +case MSR_FEATURE_WORD:
> > +r = kvm_arch_get_supported_msr_feature(kvm_state,
> > +wi->msr.index);
> 
> If you move this patch before patch 1/3, this hunk could be part
> of patch 1/3.
> 
I'm afraid that if I moved this hunk, because of the dependency, I
would have to move the definition of
kvm_arch_get_supported_msr_feature() to patch 1/3, then in turn, it
used kvm_feature_msrs, I've to put its definition and initialization
function kvm_get_supported_feature_msrs() to patch 1/3 as well. Then
actually, this makes patch 1/3 and 2/3 merged into 1. Would you like me
to do so?

> >  break;
> >  }
> >  } else if (hvf_enabled()) {
> > diff --git a/target/i386/kvm.c b/target/i386/kvm.c
> > index 0b2a07d..bfd8088 100644
> > --- a/target/i386/kvm.c
> > +++ b/target/i386/kvm.c
> > @@ -107,6 +107,7 @@ static int has_pit_state2;
> >  static bool has_msr_mcg_ext_ctl;
> >  
> >  static struct kvm_cpuid2 *cpuid_cache;
> > +static struct kvm_msr_list *kvm_feature_msrs;
> >  
> >  int kvm_has_pit_state2(void)
> >  {
> > @@ -420,6 +421,33 @@ uint32_t kvm_arch_get_supported_cpuid(KVMState
> > *s, uint32_t function,
> >  return ret;
> >  }
> >  
> > +uint32_t kvm_arch_get_supported_msr_feature(KVMState *s, uint32_t
> > index)
> > +{
> > +struct {
> > +struct kvm_msrs info;
> > +struct kvm_msr_entry entries[1];
> > +} msr_data;
> > +uint32_t ret;
> > +
> > +if (kvm_feature_msrs == NULL) { /*ARCH doesn't support feature
> > MSRs*/
> 
> Nit: normally comments have spaces after "/*" and before "*/".
> 
> Also: what do you mean by "ARCH"?  Do you mean "host kernel"?
> 
Going to say "Host".

> 
> > +return 0;
> > +}
> > +
> > +msr_data.info.nmsrs = 1;
> > +msr_data.entries[0].index = index;
> > +
> > +ret = kvm_ioctl(s, KVM_GET_MSRS, _data);
> > +
> > +if (ret != 1) {
> 
> If the MSR is not supported by the host kernel, it must not be a
> fatal error.  We should just return 0 on that case.
> 
> Probably the best way to ensure that is to check if the MSR is
> listed on kvm_feature_msrs before calling KVM_GET_MSRS (and
> return 0 if the MSR is not on the list).

Yes. Will do in this way in v5.

Re: [Qemu-devel] [PATCH v4 0/3] x86: QEMU side support on MSR based features

2018-09-11 Thread Robert Hoo
On Sun, 2018-09-02 at 19:46 +0800, Robert Hoo wrote:
Ping ... :-)
> KVM side has added the framework (kvm.git:d1d93fa90) to support MSR
> based features.
> Here is the QEMU part, including data structure changes/expanding,
> referring
> functions changes, and the implementations on 
> KVM_GET_MSR_FEATURE_INDEX_LIST and KVM_GET_MSRS system ioctl.
> 
> Changelog:
> v4:
>   Re-organize patch set to conform to request of individually
> build pass.
>   Add KVM capability check for KVM_GET_MSR_INDEX_LIST before
> fetch.
>   Special treatment for MSR_IA32_ARCH_CAPABILITIES.RSBA.
>   Use more convenient glib wrapper (g_strdup_printf) instead of
> native
> (sprintf).
>   
> v3: patch 2&3 in v2 are corrupted. Re-format patches.
> v2: coding style changes to pass ./scripts/checkpatch.pl.
> 
> Robert Hoo (3):
>   x86: Data structure changes to support MSR based features
>   kvm: Add support to KVM_GET_MSR_FEATURE_INDEX_LIST and 
> KVM_GET_MSRS system ioctl
>   x86: define a new MSR based feature word --
> FEATURE_WORDS_ARCH_CAPABILITIES
> 
>  include/sysemu/kvm.h |   2 +
>  target/i386/cpu.c| 200 +--
> 
>  target/i386/cpu.h|  12 
>  target/i386/kvm.c|  72 +++
>  4 files changed, 233 insertions(+), 53 deletions(-)
> 



Re: [Qemu-devel] [PATCH v3 3/3] Change other funcitons referring to feature_word_info[]

2018-09-10 Thread Robert Hoo
On Mon, 2018-09-10 at 14:38 -0300, Eduardo Habkost wrote:
> On Thu, Sep 06, 2018 at 06:00:29AM +, Hu, Robert wrote:
> > 
> > > 
> > > Yeah, since this type is used in the qom-get backdoor that evades
> > > introspection,
> > > it's even more important that you follow the backwards-
> > > compatibility rules and
> > > not rename or delete any previously-mandatory members, since
> > > libvirt CAN'T
> > > introspect if such changes have happened.
> > > 
> > 
> > [Robert Hoo] 
> > Oh, this is more complicated than my thought.
> > So, Eduardo, how about leave the QAPI expansion for MSR based
> > features to other
> > professional people?
> 
> I think it's now clear that we can't add MSR features to
> "feature-words" in a compatible way, so any mechanism to
> introspect MSR features will need a separate property or QMP
> command.
> 
> I also think "feature-words" needs to be replaced with something
> better.  Probably libvirt should be able to grab all information
> it needs by looking at the boolean QOM properties instead of the
> low-level info at "feature-words".
> 
> This means I agree to leave this functionality out of the MSR
> feature patch series for now.

Thanks Eduardo. Clear to me now.
> 



Re: [Qemu-devel] [PATCH v3 3/3] Change other funcitons referring to feature_word_info[]

2018-09-04 Thread Robert Hoo
On Fri, 2018-08-17 at 17:52 +0200, Paolo Bonzini wrote:
> On 10/08/2018 16:06, Robert Hoo wrote:
> > x86_cpu_get_feature_words(): limit to CPUID_FEATURE_WORD only.
> 
> This should also grow support for MSR feature words.
> 
> My suggestion is that you add another patch after patch 1 that expands
> the definition of X86CPUFeatureWordInfo like this, and adjusts
> x86_cpu_get_feature_words() to match the new C structs.  Then this
> patch can add MSR feature support somewhat easily.
> 
> The QAPI definitions would then look like this:
> 
> diff --git a/qapi/misc.json b/qapi/misc.json
> index d450cfef21..eae9243976 100644
> --- a/qapi/misc.json
> +++ b/qapi/misc.json
> @@ -2663,9 +2663,9 @@
>'data': [ 'EAX', 'EBX', 'ECX', 'EDX', 'ESP', 'EBP', 'ESI', 'EDI' ] }
>  
>  ##
> -# @X86CPUFeatureWordInfo:
> +# @X86CPUIDFeatureWordInfo:
>  #
> -# Information about a X86 CPU feature word
> +# Information about an X86 CPUID feature word
>  #
>  # @cpuid-input-eax: Input EAX value for CPUID instruction for that feature 
> word
>  #
> @@ -2678,12 +2690,45 @@
>  #
>  # Since: 1.5
>  ##
> -{ 'struct': 'X86CPUFeatureWordInfo',
> +{ 'struct': 'X86CPUIDFeatureWordInfo',
>'data': { 'cpuid-input-eax': 'int',
>  '*cpuid-input-ecx': 'int',
>  'cpuid-register': 'X86CPURegister32',
>  'features': 'int' } }
>  
> +##
> +# @X86MSRFeatureWordInfo:
> +#
> +# Information about an X86 MSR feature word
> +#
> +# @index: Index of the model specific register
> +#
> +# @cpuid-feature: CPUID feature name that communicates the existance of the 
> MSR
> +#
> +# @features: value of output register, containing the feature bits
> +#
> +# Since: 3.1
> +##
> +{ 'struct': 'X86MSRFeatureWordInfo',
> +  'data': { 'index': 'int',
> +'cpuid-feature': 'str',
> +'features': 'int' } }
> +
> +##
> +# @X86CPUFeatureWordInfo:
> +#
> +# A discriminated record of X86 CPU feature words
> +#
> +# Since: 3.1
> +##
> +
> +{ 'union': 'X86CPUFeatureWordInfo',
> +  'base': { 'type': 'X86CPUFeatureWordType' },
> +  'discriminator': 'type',
> +  'data': {
> +'cpuid': 'X86CPUIDFeatureWordInfo',
> +'msr': 'X86MSRFeatureWordInfo' }}
> +
>  ##
>  # @DummyForceArrays:
>  #

[root@robert-ivt qemu]# git diff qapi/misc.json
diff --git a/qapi/misc.json b/qapi/misc.json
index d450cfe..7351dc2 100644
--- a/qapi/misc.json
+++ b/qapi/misc.json
@@ -2663,25 +2663,25 @@
   'data': [ 'EAX', 'EBX', 'ECX', 'EDX', 'ESP', 'EBP', 'ESI', 'EDI' ] }
 
 ##
-# @X86CPUFeatureWordInfo:
+# @X86CPUIDFeatureWordInfo:
 #
-# Information about a X86 CPU feature word
+# Information about a X86 CPUID feature word
 #
-# @cpuid-input-eax: Input EAX value for CPUID instruction for that
feature word
+# @input-eax: Input EAX value for CPUID instruction for that feature
word
 #
-# @cpuid-input-ecx: Input ECX value for CPUID instruction for that
+# @input-ecx: Input ECX value for CPUID instruction for that
 #   feature word
 #
-# @cpuid-register: Output register containing the feature bits
+# @register: Output register containing the feature bits
 #
 # @features: value of output register, containing the feature bits
 #
 # Since: 1.5
 ##
-{ 'struct': 'X86CPUFeatureWordInfo',
-  'data': { 'cpuid-input-eax': 'int',
-'*cpuid-input-ecx': 'int',
-'cpuid-register': 'X86CPURegister32',
+{ 'struct': 'X86CPUIDFeatureWordInfo',
+  'data': { 'input-eax': 'int',
+'*input-ecx': 'int',
+'register': 'X86CPURegister32',
 'features': 'int' } }
 
 ##
@@ -2694,6 +2694,50 @@
 { 'struct': 'DummyForceArrays',
   'data': { 'unused': ['X86CPUFeatureWordInfo'] } }
 
+##
+# @X86MSRFeatureWordInfo:
+#
+# Information about an X86 MSR feature word
+#
+# @index: Index of the model specific register
+#
+# @cpuid-feature: CPUID feature name that communicates the existance of
the MSR
+#
+# @features: value of output register, containing the feature bits
+#
+# Since: 3.1
+##
+{ 'struct': 'X86MSRFeatureWordInfo',
+  'data': { 'index': 'int',
+'cpuid-feature': 'str',
+'features': 'int' } }
+
+##
+# @X86CPUFeatureWordType:
+#
+# Kinds of X86 CPU feature words
+#
+# @cpuid: A CPUID leaf
+#
+# @msr: An MSR
+##
+{ 'enum': 'X86CPUFeatureWordType',
+  'data': [ 'cpuid', 'msr' ] }
+
+##
+# @X86CPUFeatureWordInfo:
+#
+# A discriminated record of X86 CPU feature words
+#
+# Since: 3.1
+##
+{ 'union': 'X86CPUFeatureWordInfo',
+  'base': { 'type': 'X86CPUFeatureWordType' },
+  'discriminator': 'type',
+  'data': {
+'cpuid': 'X86CPUIDFeatureWordInfo',
+'msr': 'X86MSRFeatureWordInfo' }}
+
 
 ##
 # @NumaOptionsType:

Hi Paolo,

above is my draft change on the qapi json file. 1 question: 
struct X86MSRFeatureWordInfo {
int64_t index;
char *cpuid_feature;
int64_t features;
};
how to have a "const" prefix the "char *"?
> 
> I'm not sure if the cpuid-feature field is useful for libvirt and
> other management applications.  Eduardo, what do you think?
> 
> Thanks,
> 
> Paolo





[Qemu-devel] [PATCH v4 1/3] x86: Data structure changes to support MSR based features

2018-09-02 Thread Robert Hoo
Add FeatureWordType indicator in struct FeatureWordInfo.
Change feature_word_info[] accordingly.
Change existing functions that refer to feature_word_info[] accordingly.

Signed-off-by: Robert Hoo 
---
 target/i386/cpu.c | 172 +-
 1 file changed, 120 insertions(+), 52 deletions(-)

diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index f24295e..a252c26 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -770,17 +770,36 @@ static void x86_cpu_vendor_words2str(char *dst, uint32_t 
vendor1,
   /* missing:
   CPUID_XSAVE_XSAVEC, CPUID_XSAVE_XSAVES */
 
+typedef enum FeatureWordType {
+   CPUID_FEATURE_WORD,
+   MSR_FEATURE_WORD,
+} FeatureWordType;
+
 typedef struct FeatureWordInfo {
-/* feature flags names are taken from "Intel Processor Identification and
+FeatureWordType type;
+   /* feature flags names are taken from "Intel Processor Identification and
  * the CPUID Instruction" and AMD's "CPUID Specification".
  * In cases of disagreement between feature naming conventions,
  * aliases may be added.
  */
 const char *feat_names[32];
-uint32_t cpuid_eax;   /* Input EAX for CPUID */
-bool cpuid_needs_ecx; /* CPUID instruction uses ECX as input */
-uint32_t cpuid_ecx;   /* Input ECX value for CPUID */
-int cpuid_reg;/* output register (R_* constant) */
+union {
+/* If type==CPUID_FEATURE_WORD */
+struct {
+uint32_t eax;   /* Input EAX for CPUID */
+bool needs_ecx; /* CPUID instruction uses ECX as input */
+uint32_t ecx;   /* Input ECX value for CPUID */
+int reg;/* output register (R_* constant) */
+} cpuid;
+/* If type==MSR_FEATURE_WORD */
+struct {
+uint32_t index;
+struct {   /*CPUID that enumerate this MSR*/
+FeatureWord cpuid_class;
+uint32_tcpuid_flag;
+} cpuid_dep;
+} msr;
+};
 uint32_t tcg_features; /* Feature flags supported by TCG */
 uint32_t unmigratable_flags; /* Feature flags known to be unmigratable */
 uint32_t migratable_flags; /* Feature flags known to be migratable */
@@ -790,6 +809,7 @@ typedef struct FeatureWordInfo {
 
 static FeatureWordInfo feature_word_info[FEATURE_WORDS] = {
 [FEAT_1_EDX] = {
+.type = CPUID_FEATURE_WORD,
 .feat_names = {
 "fpu", "vme", "de", "pse",
 "tsc", "msr", "pae", "mce",
@@ -800,10 +820,11 @@ static FeatureWordInfo feature_word_info[FEATURE_WORDS] = 
{
 "fxsr", "sse", "sse2", "ss",
 "ht" /* Intel htt */, "tm", "ia64", "pbe",
 },
-.cpuid_eax = 1, .cpuid_reg = R_EDX,
+.cpuid = {.eax = 1, .reg = R_EDX, },
 .tcg_features = TCG_FEATURES,
 },
 [FEAT_1_ECX] = {
+.type = CPUID_FEATURE_WORD,
 .feat_names = {
 "pni" /* Intel,AMD sse3 */, "pclmulqdq", "dtes64", "monitor",
 "ds-cpl", "vmx", "smx", "est",
@@ -814,7 +835,7 @@ static FeatureWordInfo feature_word_info[FEATURE_WORDS] = {
 "tsc-deadline", "aes", "xsave", NULL /* osxsave */,
 "avx", "f16c", "rdrand", "hypervisor",
 },
-.cpuid_eax = 1, .cpuid_reg = R_ECX,
+.cpuid = { .eax = 1, .reg = R_ECX, },
 .tcg_features = TCG_EXT_FEATURES,
 },
 /* Feature names that are already defined on feature_name[] but
@@ -823,6 +844,7 @@ static FeatureWordInfo feature_word_info[FEATURE_WORDS] = {
  * to features[FEAT_8000_0001_EDX] if and only if CPU vendor is AMD.
  */
 [FEAT_8000_0001_EDX] = {
+.type = CPUID_FEATURE_WORD,
 .feat_names = {
 NULL /* fpu */, NULL /* vme */, NULL /* de */, NULL /* pse */,
 NULL /* tsc */, NULL /* msr */, NULL /* pae */, NULL /* mce */,
@@ -833,10 +855,11 @@ static FeatureWordInfo feature_word_info[FEATURE_WORDS] = 
{
 NULL /* fxsr */, "fxsr-opt", "pdpe1gb", "rdtscp",
 NULL, "lm", "3dnowext", "3dnow",
 },
-.cpuid_eax = 0x8001, .cpuid_reg = R_EDX,
+.cpuid = { .eax = 0x8001, .reg = R_EDX, },
 .tcg_features = TCG_EXT2_FEATURES,
 },
 [FEAT_8000_0001_ECX] = {
+.type = CPUID_FEATURE_WORD,
 .feat_names = {
 "lahf-lm", "cmp-legacy", "svm", "extapic",
 "cr8legacy", "abm", "sse4a", "misalignsse",
@@ -847,7 +870,7 @@ static FeatureWordInfo feature_word_info[FEAT

[Qemu-devel] [PATCH v4 3/3] x86: define a new MSR based feature word -- FEATURE_WORDS_ARCH_CAPABILITIES

2018-09-02 Thread Robert Hoo
Note RSBA is specially treated -- no matter host support it or not, qemu
pretends it is supported.

Signed-off-by: Robert Hoo 
---
 target/i386/cpu.c | 27 ++-
 target/i386/cpu.h | 12 
 2 files changed, 38 insertions(+), 1 deletion(-)

diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index 0160e97..8ec9613 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -1129,6 +1129,24 @@ static FeatureWordInfo feature_word_info[FEATURE_WORDS] 
= {
 .reg = R_EDX, },
 .tcg_features = ~0U,
 },
+/*Below are MSR exposed features*/
+[FEATURE_WORDS_ARCH_CAPABILITIES] = {
+.type = MSR_FEATURE_WORD,
+.feat_names = {
+"rdctl-no", "ibrs-all", "rsba", NULL,
+"ssb-no", NULL, NULL, NULL,
+NULL, NULL, NULL, NULL,
+NULL, NULL, NULL, NULL,
+NULL, NULL, NULL, NULL,
+NULL, NULL, NULL, NULL,
+NULL, NULL, NULL, NULL,
+NULL, NULL, NULL, NULL,
+},
+.msr = { .index = MSR_IA32_ARCH_CAPABILITIES,
+.cpuid_dep = { FEAT_7_0_EDX,
+CPUID_7_0_EDX_ARCH_CAPABILITIES }
+},
+},
 };
 
 typedef struct X86RegisterInfo32 {
@@ -3680,7 +3698,14 @@ static uint32_t 
x86_cpu_get_supported_feature_word(FeatureWord w,
 wi->cpuid.reg);
 break;
 case MSR_FEATURE_WORD:
-r = kvm_arch_get_supported_msr_feature(kvm_state,
+/* Special case:
+ * No matter host status, IA32_ARCH_CAPABILITIES.RSBA [bit 2]
+ * is always supported in guest.
+ */
+if (wi->msr.index == MSR_IA32_ARCH_CAPABILITIES) {
+r = MSR_ARCH_CAP_RSBA;
+}
+r |= kvm_arch_get_supported_msr_feature(kvm_state,
 wi->msr.index);
 break;
 }
diff --git a/target/i386/cpu.h b/target/i386/cpu.h
index b572a8e..9662730 100644
--- a/target/i386/cpu.h
+++ b/target/i386/cpu.h
@@ -502,9 +502,14 @@ typedef enum FeatureWord {
 FEAT_6_EAX, /* CPUID[6].EAX */
 FEAT_XSAVE_COMP_LO, /* CPUID[EAX=0xd,ECX=0].EAX */
 FEAT_XSAVE_COMP_HI, /* CPUID[EAX=0xd,ECX=0].EDX */
+FEATURE_WORDS_NUM_CPUID,
+FEATURE_WORDS_FIRST_MSR = FEATURE_WORDS_NUM_CPUID,
+FEATURE_WORDS_ARCH_CAPABILITIES = FEATURE_WORDS_FIRST_MSR,
 FEATURE_WORDS,
 } FeatureWord;
 
+#define FEATURE_WORDS_NUM_MSRS (FEATURE_WORDS - FEATURE_WORDS_FIRST_MSR)
+
 typedef uint32_t FeatureWordArray[FEATURE_WORDS];
 
 /* cpuid_features bits */
@@ -730,6 +735,13 @@ typedef uint32_t FeatureWordArray[FEATURE_WORDS];
 #define CPUID_TOPOLOGY_LEVEL_SMT  (1U << 8)
 #define CPUID_TOPOLOGY_LEVEL_CORE (2U << 8)
 
+/* MSR Feature Bits */
+#define MSR_ARCH_CAP_RDCL_NO(1U << 0)
+#define MSR_ARCH_CAP_IBRS_ALL   (1U << 1)
+#define MSR_ARCH_CAP_RSBA   (1U << 2)
+#define MSR_ARCH_CAP_SKIP_L1DFL_VMENTRY (1U << 3)
+#define MSR_ARCH_CAP_SSB_NO (1U << 4)
+
 #ifndef HYPERV_SPINLOCK_NEVER_RETRY
 #define HYPERV_SPINLOCK_NEVER_RETRY 0x
 #endif
-- 
1.8.3.1




[Qemu-devel] [PATCH v4 2/3] kvm: Add support to KVM_GET_MSR_FEATURE_INDEX_LIST and KVM_GET_MSRS system ioctl

2018-09-02 Thread Robert Hoo
Add kvm_get_supported_feature_msrs() to get supported MSR feature index list.
Add kvm_arch_get_supported_msr_feature() to get each MSR features value.

Signed-off-by: Robert Hoo 
---
 include/sysemu/kvm.h |  2 ++
 target/i386/cpu.c|  7 ++---
 target/i386/kvm.c| 72 
 3 files changed, 78 insertions(+), 3 deletions(-)

diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h
index 0b64b8e..97d8d9d 100644
--- a/include/sysemu/kvm.h
+++ b/include/sysemu/kvm.h
@@ -463,6 +463,8 @@ int kvm_vm_check_extension(KVMState *s, unsigned int 
extension);
 
 uint32_t kvm_arch_get_supported_cpuid(KVMState *env, uint32_t function,
   uint32_t index, int reg);
+uint32_t kvm_arch_get_supported_msr_feature(KVMState *s, uint32_t index);
+
 
 void kvm_set_sigmask_len(KVMState *s, unsigned int sigmask_len);
 
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index a252c26..0160e97 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -3670,7 +3670,7 @@ static uint32_t 
x86_cpu_get_supported_feature_word(FeatureWord w,
bool migratable_only)
 {
 FeatureWordInfo *wi = _word_info[w];
-uint32_t r;
+uint32_t r = 0;
 
 if (kvm_enabled()) {
 switch (wi->type) {
@@ -3679,8 +3679,9 @@ static uint32_t 
x86_cpu_get_supported_feature_word(FeatureWord w,
 wi->cpuid.ecx,
 wi->cpuid.reg);
 break;
-default:
-r = 0;
+case MSR_FEATURE_WORD:
+r = kvm_arch_get_supported_msr_feature(kvm_state,
+wi->msr.index);
 break;
 }
 } else if (hvf_enabled()) {
diff --git a/target/i386/kvm.c b/target/i386/kvm.c
index 0b2a07d..bfd8088 100644
--- a/target/i386/kvm.c
+++ b/target/i386/kvm.c
@@ -107,6 +107,7 @@ static int has_pit_state2;
 static bool has_msr_mcg_ext_ctl;
 
 static struct kvm_cpuid2 *cpuid_cache;
+static struct kvm_msr_list *kvm_feature_msrs;
 
 int kvm_has_pit_state2(void)
 {
@@ -420,6 +421,33 @@ uint32_t kvm_arch_get_supported_cpuid(KVMState *s, 
uint32_t function,
 return ret;
 }
 
+uint32_t kvm_arch_get_supported_msr_feature(KVMState *s, uint32_t index)
+{
+struct {
+struct kvm_msrs info;
+struct kvm_msr_entry entries[1];
+} msr_data;
+uint32_t ret;
+
+if (kvm_feature_msrs == NULL) { /*ARCH doesn't support feature MSRs*/
+return 0;
+}
+
+msr_data.info.nmsrs = 1;
+msr_data.entries[0].index = index;
+
+ret = kvm_ioctl(s, KVM_GET_MSRS, _data);
+
+if (ret != 1) {
+fprintf(stderr, "KVM get MSR (index=0x%x) feature failed, %s\n",
+index, strerror(-ret));
+exit(1);
+}
+
+return msr_data.entries[0].data;
+}
+
+
 typedef struct HWPoisonPage {
 ram_addr_t ram_addr;
 QLIST_ENTRY(HWPoisonPage) list;
@@ -1239,6 +1267,45 @@ void kvm_arch_do_init_vcpu(X86CPU *cpu)
 }
 }
 
+static int kvm_get_supported_feature_msrs(KVMState *s)
+{
+int ret = 0;
+
+if (kvm_feature_msrs != NULL) {
+return 0;
+}
+
+if (!kvm_check_extension(s, KVM_CAP_GET_MSR_FEATURES)) {
+return -1;
+}
+
+struct kvm_msr_list msr_list;
+
+msr_list.nmsrs = 0;
+ret = kvm_ioctl(s, KVM_GET_MSR_FEATURE_INDEX_LIST, _list);
+if (ret < 0 && ret != -E2BIG) {
+return ret;
+}
+
+assert(msr_list.nmsrs > 0);
+kvm_feature_msrs = (struct kvm_msr_list *) \
+g_malloc0(sizeof(msr_list) +
+ msr_list.nmsrs * sizeof(msr_list.indices[0]));
+
+kvm_feature_msrs->nmsrs = msr_list.nmsrs;
+ret = kvm_ioctl(s, KVM_GET_MSR_FEATURE_INDEX_LIST, kvm_feature_msrs);
+
+if (ret < 0) {
+fprintf(stderr, "Fetch KVM feature MSRs failed: %s\n",
+strerror(-ret));
+g_free(kvm_feature_msrs);
+kvm_feature_msrs = NULL;
+return ret;
+}
+
+return 0;
+}
+
 static int kvm_get_supported_msrs(KVMState *s)
 {
 static int kvm_supported_msrs;
@@ -1392,6 +1459,11 @@ int kvm_arch_init(MachineState *ms, KVMState *s)
 return ret;
 }
 
+ret = kvm_get_supported_feature_msrs(s);
+if (ret < 0) { /*if MSR based features aren't supported, ignore it.*/
+warn_report("Get supported feature MSRs failed.");
+}
+
 uname();
 lm_capable_kernel = strcmp(utsname.machine, "x86_64") == 0;
 
-- 
1.8.3.1




[Qemu-devel] [PATCH v4 0/3] x86: QEMU side support on MSR based features

2018-09-02 Thread Robert Hoo
KVM side has added the framework (kvm.git:d1d93fa90) to support MSR based 
features.
Here is the QEMU part, including data structure changes/expanding, referring
functions changes, and the implementations on 
KVM_GET_MSR_FEATURE_INDEX_LIST and KVM_GET_MSRS system ioctl.

Changelog:
v4:
Re-organize patch set to conform to request of individually build pass.
Add KVM capability check for KVM_GET_MSR_INDEX_LIST before fetch.
Special treatment for MSR_IA32_ARCH_CAPABILITIES.RSBA.
Use more convenient glib wrapper (g_strdup_printf) instead of native
(sprintf).

v3: patch 2&3 in v2 are corrupted. Re-format patches.
v2: coding style changes to pass ./scripts/checkpatch.pl.

Robert Hoo (3):
  x86: Data structure changes to support MSR based features
  kvm: Add support to KVM_GET_MSR_FEATURE_INDEX_LIST and 
KVM_GET_MSRS system ioctl
  x86: define a new MSR based feature word --
FEATURE_WORDS_ARCH_CAPABILITIES

 include/sysemu/kvm.h |   2 +
 target/i386/cpu.c| 200 +--
 target/i386/cpu.h|  12 
 target/i386/kvm.c|  72 +++
 4 files changed, 233 insertions(+), 53 deletions(-)

-- 
1.8.3.1




Re: [Qemu-devel] [PATCH v3 2/3] kvm: Add support to KVM_GET_MSR_FEATURE_INDEX_LIST and KVM_GET_MSRS system ioctl

2018-08-29 Thread Robert Hoo
On Thu, 2018-08-23 at 14:11 -0300, Eduardo Habkost wrote:
> On Thu, Aug 23, 2018 at 02:28:28PM +0800, Robert Hoo wrote:
> > On Sat, 2018-08-18 at 12:05 -0300, Eduardo Habkost wrote:
> [...]
> > > We don't want QEMU to refuse to run if the kernel doesn't have
> > > KVM_CAP_GET_MSR_FEATURES.  We can treat missing capability as
> > > equivalent to returning an empty list of MSRs.
> > Yes. I'll let caller (kvm_arch_init) ignore the return value but a
> > simple warning.
> 
> Warnings tend to be ignored and are generally a sign that QEMU
> isn't doing the right thing.  Sometimes we have no choice, but I
> don't think that's the case here.
> 
> As far as I can see, we have only two possibilities here:
> 1) The host can run a VM that behaves exactly as requested on the
>command-line (no warning required).
> 2) The host can't run the requested configuration (fatal error,
>not a warning).
> 
I mean the kvm_arch_init() --> kvm_get_supported_feature_msrs(), when
kvm_get_supported_feature_msrs() returns error, can we ignore it?
The cases of kvm_get_supported_feature_msrs() returning error:
1) underlying KVM doesn't support GET_MSR_FEATURES capability.
2) error in KVM_GET_MSR_FEATURE_INDEX_LIST.

given the principle you guided before, I think we can ignore above error
cases, and later kvm_arch_get_supported_msr_feature() would always
return 0 (of course, except those special cases like
IA32_ARCH_CAPABILITIES.RSBA)





Re: [Qemu-devel] [PATCH v3 2/3] kvm: Add support to KVM_GET_MSR_FEATURE_INDEX_LIST and KVM_GET_MSRS system ioctl

2018-08-23 Thread Robert Hoo
On Sat, 2018-08-18 at 12:05 -0300, Eduardo Habkost wrote:

> > > >  
> > > >  int kvm_has_pit_state2(void)
> > > >  {
> > > > @@ -420,6 +421,41 @@ uint32_t kvm_arch_get_supported_cpuid(KVMState *s, 
> > > > uint32_t function,
> > > >  return ret;
> > > >  }
> > > >  
> > > > +uint32_t kvm_arch_get_supported_msr_feature(KVMState *s, uint32_t 
> > > > index)
> > > > +{
> > > > +struct {
> > > > +struct kvm_msrs info;
> > > > +struct kvm_msr_entry entries[1];
> > > > +} msr_data;
> > > > +uint32_t ret;
> > > > +
> > > > +/*Check if the requested feature MSR is supported*/
> > > > +int i;
> > > > +for (i = 0; i < kvm_feature_msrs->nmsrs; i++) {
> > > > +if (index == kvm_feature_msrs->indices[i]) {
> > > > +break;
> > > > +}
> > > > +}
> > > 
> > > We are duplicating the logic that's already inside KVM (checking
> > > the list of supported MSRs and returning an error).  Can't we
> > > make this simpler and just remove this check?  If the MSR is not
> > > supported, KVM_GET_MSRS would just return 0.
> > 
> > Yes, seems dup. but if we remove this hunk, the
> > kvm_get_supported_feature_msrs() is unnecessary at all.
> 
> So maybe kvm_get_supported_feature_msrs() really is unnecessary?

I'll keep it, for 1) check KVM_CAP_GET_MSR_FEATURES capabilities; 2) get
kvm_feature_msrs, so later kvm_arch_get_supported_msr_feature() use it
to check if MSR features are supported.
> 
> We seem to have two alternatives:
> * calling KVM_GET_MSRS for all MSRs only once, at
>   kvm_get_supported_feature_msrs() (as I had suggested
>   previously);
> * calling KVM_GET_MSRS for one MSR unconditionally here, but
>   _not_ treating 0 as a fatal error.
> 
> I prefer the former, but I would be OK with both alternatives.
> Note that we need to check for KVM capabilities in both cases.
> 
> 
I'll choose the latter :).
> > > 
> > > > +if (i >= kvm_feature_msrs->nmsrs) {
> > > > +fprintf(stderr, "Requested MSR (index= %d) is not 
> > > > supported.\n", index);
> > > 
> > > This error message is meaningless for QEMU users.  Do we really
> > > need to print it?
> > > 
> > > > +return 0;
> > > 
> > > Returning 0 for MSRs that are not supported is probably OK, but
> > > we need to see this function being used, to be sure (I didn't
> > > look at all the patches in this series yet).
> > > 
> > > > +}
> > > > +
> > > > +msr_data.info.nmsrs = 1;
> > > > +msr_data.entries[0].index = index;
> > > > +
> > > > +ret = kvm_ioctl(s, KVM_GET_MSRS, _data);
> > > > +
> > > > +if (ret != 1) {
> > > > +fprintf(stderr, "KVM get MSR (index=0x%x) feature failed, 
> > > > %s\n",
> > > > +index, strerror(-ret));
> > > > +exit(1);
> > > 
> > > I'm not a fan of APIs that write to stdout/stderr or exit(),
> > > unless they are clearly just initialization functions that should
> > > never fail in normal circumstances.
> > > 
> > > But if you call KVM_GET_MSRS for all MSRs at
> > > kvm_get_supported_feature_msrs() below, this function would never
> > > need to report an error.
> > > 
> > > We are already going through the trouble of allocating
> > > kvm_feature_msrs in kvm_get_supported_feature_msrs() anyway.
> > 
> > I had looked into KVM KVM_GET_MSRS handling, though less likely, still
> > have changes copy_from/to_user() fail. Therefore I added the check and
> > warning here, in that seldom case happens.
> > 
> > exit() or not, I'm also not sure. Seems not necessary, while my usual
> > programming philosophy is never let wrong goes further. For in the case
> > of ioctl(KVM_GET_MSRS) returns failure, something goes wrong underlying,
> > I would prefer to let user know this, rather than let it pass and goes
> > further.
> 
> We probably have no option other than exiting if KVM_GET_MSRS
> returns an unexpected error.  It's just that I find the code
> harder to review, because we need to be sure this won't terminate
> QEMU under normal circumstances.
> 
> But if you demonstrate that all errors here are truly fatal and
> unexpected, calling exit() may be OK.  (See the
> KVM_CAP_GET_MSR_FEATURES comment below for one example where
> exiting is not going to be OK.)
> 
> Proper error reporting using Error** would be even better than
> exiting, but considering that none of the functions at i386/cpu.c
> return errors using Error**, I won't force you to do that.
> 
Thanks.
> 
> > > 
> [...]
> > > > +struct kvm_msr_list msr_list;
> > > > +
> > > > +kvm_supported_feature_msrs++;
> > > > +
> > > > +msr_list.nmsrs = 0;
> > > > +ret = kvm_ioctl(s, KVM_GET_MSR_FEATURE_INDEX_LIST, _list);
> > > > +if (ret < 0 && ret != -E2BIG) {
> > > > +return ret;
> > > 
> > > What if the host KVM version doesn't support
> > > KVM_GET_MSR_FEATURE_INDEX_LIST?
> > 
> > Going to add kvm_check_extension(s, KVM_CAP_GET_MSR_FEATURES) before
> > this ioctl. if not support, return -1. (Then the kvm_init will fail and

Re: [Qemu-devel] [PATCH v3 3/3] Change other funcitons referring to feature_word_info[]

2018-08-18 Thread Robert Hoo
On Fri, 2018-08-17 at 17:52 +0200, Paolo Bonzini wrote:
> On 10/08/2018 16:06, Robert Hoo wrote:
> > x86_cpu_get_feature_words(): limit to CPUID_FEATURE_WORD only.
> 
> This should also grow support for MSR feature words.
> 
> My suggestion is that you add another patch after patch 1 that expands
> the definition of X86CPUFeatureWordInfo like this, and adjusts
> x86_cpu_get_feature_words() to match the new C structs.  Then this
> patch can add MSR feature support somewhat easily.
> 
> The QAPI definitions would then look like this:

I'm not familiar with json language. Can someone else compose this part?
> 
> diff --git a/qapi/misc.json b/qapi/misc.json
> index d450cfef21..eae9243976 100644
> --- a/qapi/misc.json
> +++ b/qapi/misc.json
> @@ -2663,9 +2663,9 @@
>'data': [ 'EAX', 'EBX', 'ECX', 'EDX', 'ESP', 'EBP', 'ESI', 'EDI' ] }
>  
>  ##
> -# @X86CPUFeatureWordInfo:
> +# @X86CPUIDFeatureWordInfo:
>  #
> -# Information about a X86 CPU feature word
> +# Information about an X86 CPUID feature word
>  #
>  # @cpuid-input-eax: Input EAX value for CPUID instruction for that feature 
> word
>  #
> @@ -2678,12 +2690,45 @@
>  #
>  # Since: 1.5
>  ##
> -{ 'struct': 'X86CPUFeatureWordInfo',
> +{ 'struct': 'X86CPUIDFeatureWordInfo',
>'data': { 'cpuid-input-eax': 'int',
>  '*cpuid-input-ecx': 'int',
>  'cpuid-register': 'X86CPURegister32',
>  'features': 'int' } }
>  
> +##
> +# @X86MSRFeatureWordInfo:
> +#
> +# Information about an X86 MSR feature word
> +#
> +# @index: Index of the model specific register
> +#
> +# @cpuid-feature: CPUID feature name that communicates the existance of the 
> MSR
> +#
> +# @features: value of output register, containing the feature bits
> +#
> +# Since: 3.1
> +##
> +{ 'struct': 'X86MSRFeatureWordInfo',
> +  'data': { 'index': 'int',
> +'cpuid-feature': 'str',
> +'features': 'int' } }
> +
> +##
> +# @X86CPUFeatureWordInfo:
> +#
> +# A discriminated record of X86 CPU feature words
> +#
> +# Since: 3.1
> +##
> +
> +{ 'union': 'X86CPUFeatureWordInfo',
> +  'base': { 'type': 'X86CPUFeatureWordType' },
> +  'discriminator': 'type',
> +  'data': {
> +'cpuid': 'X86CPUIDFeatureWordInfo',
> +'msr': 'X86MSRFeatureWordInfo' }}
> +
>  ##
>  # @DummyForceArrays:
>  #
> 
> I'm not sure if the cpuid-feature field is useful for libvirt and
> other management applications.  Eduardo, what do you think?
> 
> Thanks,
> 
> Paolo





Re: [Qemu-devel] [PATCH v3 3/3] Change other funcitons referring to feature_word_info[]

2018-08-18 Thread Robert Hoo
On Fri, 2018-08-17 at 10:28 -0300, Eduardo Habkost wrote:
> On Fri, Aug 10, 2018 at 10:06:29PM +0800, Robert Hoo wrote:
> > Add an util function feature_word_description(), which help construct the 
> > string
> > describing the feature word (both CPUID and MSR types).
> > 
> > report_unavailable_features(): add MSR_FEATURE_WORD type support.
> > x86_cpu_get_feature_words(): limit to CPUID_FEATURE_WORD only.
> > x86_cpu_get_supported_feature_word(): add MSR_FEATURE_WORD type support.
> > x86_cpu_adjust_feat_level(): assert the requested feature must be
> > CPUID_FEATURE_WORD type.
> > 
> > Signed-off-by: Robert Hoo 
> > ---
> >  target/i386/cpu.c | 77 
> > +--
> >  1 file changed, 58 insertions(+), 19 deletions(-)
> > 
> > diff --git a/target/i386/cpu.c b/target/i386/cpu.c
> > index f7c70d9..21ed599 100644
> > --- a/target/i386/cpu.c
> > +++ b/target/i386/cpu.c
> > @@ -3024,21 +3024,51 @@ static const TypeInfo host_x86_cpu_type_info = {
> >  
> >  #endif
> >  
> > +/*
> > +*caller should have input str no less than 64 byte length.
> > +*/
> > +#define FEATURE_WORD_DESCPTION_LEN 64
> > +static int feature_word_description(char str[], FeatureWordInfo *f,
> > +uint32_t bit)
> 
> I agree with Eric: g_strup_printf() would be much simpler here.
> 
1 question: I think caller should g_free() the returned str after it
warn_report(), right?
> > +{
> > +int ret;
> > +
> > +assert(f->type == CPUID_FEATURE_WORD ||
> > +f->type == MSR_FEATURE_WORD);
> > +switch (f->type) {
> > +case CPUID_FEATURE_WORD:
> > +{
> > +const char *reg = get_register_name_32(f->cpuid.reg);
> > +assert(reg);
> > +ret = snprintf(str, FEATURE_WORD_DESCPTION_LEN,
> > +"CPUID.%02XH:%s%s%s [bit %d]",
> > +f->cpuid.eax, reg,
> > +f->feat_names[bit] ? "." : "",
> > +f->feat_names[bit] ? f->feat_names[bit] : "", bit);
> > +break;
> > +}
> > +case MSR_FEATURE_WORD:
> > +ret = snprintf(str, FEATURE_WORD_DESCPTION_LEN,
> > +"MSR(%xH).%s [bit %d]",
> > +f->msr.index,
> > +f->feat_names[bit] ? f->feat_names[bit] : "", bit);
> 
> What about leaving the (f->feat_names[bit] ? ... : ...) part
> in report_unavailable_features() and just make this function
> return "CPUID[...]" or "MSR[...]"?
> 
> 
> > +break;
> > +}
> > +return ret > 0;
> > +}
> > +
> >  static void report_unavailable_features(FeatureWord w, uint32_t mask)
> >  {
> >  FeatureWordInfo *f = _word_info[w];
> >  int i;
> > +char feat_word_dscrp_str[FEATURE_WORD_DESCPTION_LEN];
> >  
> >  for (i = 0; i < 32; ++i) {
> >  if ((1UL << i) & mask) {
> > -const char *reg = get_register_name_32(f->cpuid_reg);
> > -assert(reg);
> > -warn_report("%s doesn't support requested feature: "
> > -"CPUID.%02XH:%s%s%s [bit %d]",
> > +feature_word_description(feat_word_dscrp_str, f, i);
> > +warn_report("%s doesn't support requested feature: %s",
> >  accel_uses_host_cpuid() ? "host" : "TCG",
> > -f->cpuid_eax, reg,
> > -f->feat_names[i] ? "." : "",
> > -f->feat_names[i] ? f->feat_names[i] : "", i);
> > +feat_word_dscrp_str);
> >  }
> >  }
> >  }
> > @@ -3276,17 +3306,17 @@ static void x86_cpu_get_feature_words(Object *obj, 
> > Visitor *v,
> >  {
> >  uint32_t *array = (uint32_t *)opaque;
> >  FeatureWord w;
> > -X86CPUFeatureWordInfo word_infos[FEATURE_WORDS] = { };
> > -X86CPUFeatureWordInfoList list_entries[FEATURE_WORDS] = { };
> > +X86CPUFeatureWordInfo word_infos[FEATURE_WORDS_NUM_CPUID] = { };
> > +X86CPUFeatureWordInfoList list_entries[FEATURE_WORDS_NUM_CPUID] = { };
> >  X86CPUFeatureWordInfoList *list = NULL;
> >  
> > -for (w = 0; w < FEATURE_WORDS; w++) {
> > +for (w = 0; w < FEATURE_WORDS_NUM_CPUID; w++) {
> >   

Re: [Qemu-devel] [PATCH v3 2/3] kvm: Add support to KVM_GET_MSR_FEATURE_INDEX_LIST and KVM_GET_MSRS system ioctl

2018-08-18 Thread Robert Hoo
On Fri, 2018-08-17 at 10:18 -0300, Eduardo Habkost wrote:
> Thanks for the patch, comments below:
> 
> On Fri, Aug 10, 2018 at 10:06:28PM +0800, Robert Hoo wrote:
> > Add kvm_get_supported_feature_msrs() to get supported MSR feature index 
> > list.
> > Add kvm_arch_get_supported_msr_feature() to get each MSR features value.
> > 
> > kvm_get_supported_feature_msrs() is called in kvm_arch_init().
> > kvm_arch_get_supported_msr_feature() is called by
> > x86_cpu_get_supported_feature_word().
> > 
> > Signed-off-by: Robert Hoo 
> > ---
> >  include/sysemu/kvm.h |  2 ++
> >  target/i386/kvm.c| 79 
> > 
> >  2 files changed, 81 insertions(+)
> > 
> > diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h
> > index 0b64b8e..97d8d9d 100644
> > --- a/include/sysemu/kvm.h
> > +++ b/include/sysemu/kvm.h
> > @@ -463,6 +463,8 @@ int kvm_vm_check_extension(KVMState *s, unsigned int 
> > extension);
> >  
> >  uint32_t kvm_arch_get_supported_cpuid(KVMState *env, uint32_t function,
> >uint32_t index, int reg);
> > +uint32_t kvm_arch_get_supported_msr_feature(KVMState *s, uint32_t index);
> > +
> >  
> >  void kvm_set_sigmask_len(KVMState *s, unsigned int sigmask_len);
> >  
> > diff --git a/target/i386/kvm.c b/target/i386/kvm.c
> > index 9313602..70d8606 100644
> > --- a/target/i386/kvm.c
> > +++ b/target/i386/kvm.c
> > @@ -107,6 +107,7 @@ static int has_pit_state2;
> >  static bool has_msr_mcg_ext_ctl;
> >  
> >  static struct kvm_cpuid2 *cpuid_cache;
> > +static struct kvm_msr_list *kvm_feature_msrs;
> 
> I was going to suggest moving this to KVMState, but KVMState is a
> arch-independent struct.  I guess we'll have to live with this by
> now.
> 
> >  
> >  int kvm_has_pit_state2(void)
> >  {
> > @@ -420,6 +421,41 @@ uint32_t kvm_arch_get_supported_cpuid(KVMState *s, 
> > uint32_t function,
> >  return ret;
> >  }
> >  
> > +uint32_t kvm_arch_get_supported_msr_feature(KVMState *s, uint32_t index)
> > +{
> > +struct {
> > +struct kvm_msrs info;
> > +struct kvm_msr_entry entries[1];
> > +} msr_data;
> > +uint32_t ret;
> > +
> > +/*Check if the requested feature MSR is supported*/
> > +int i;
> > +for (i = 0; i < kvm_feature_msrs->nmsrs; i++) {
> > +if (index == kvm_feature_msrs->indices[i]) {
> > +break;
> > +}
> > +}
> 
> We are duplicating the logic that's already inside KVM (checking
> the list of supported MSRs and returning an error).  Can't we
> make this simpler and just remove this check?  If the MSR is not
> supported, KVM_GET_MSRS would just return 0.

Yes, seems dup. but if we remove this hunk, the
kvm_get_supported_feature_msrs() is unnecessary at all.
> 
> > +if (i >= kvm_feature_msrs->nmsrs) {
> > +fprintf(stderr, "Requested MSR (index= %d) is not supported.\n", 
> > index);
> 
> This error message is meaningless for QEMU users.  Do we really
> need to print it?
> 
> > +return 0;
> 
> Returning 0 for MSRs that are not supported is probably OK, but
> we need to see this function being used, to be sure (I didn't
> look at all the patches in this series yet).
> 
> > +}
> > +
> > +msr_data.info.nmsrs = 1;
> > +msr_data.entries[0].index = index;
> > +
> > +ret = kvm_ioctl(s, KVM_GET_MSRS, _data);
> > +
> > +if (ret != 1) {
> > +fprintf(stderr, "KVM get MSR (index=0x%x) feature failed, %s\n",
> > +index, strerror(-ret));
> > +exit(1);
> 
> I'm not a fan of APIs that write to stdout/stderr or exit(),
> unless they are clearly just initialization functions that should
> never fail in normal circumstances.
> 
> But if you call KVM_GET_MSRS for all MSRs at
> kvm_get_supported_feature_msrs() below, this function would never
> need to report an error.
> 
> We are already going through the trouble of allocating
> kvm_feature_msrs in kvm_get_supported_feature_msrs() anyway.

I had looked into KVM KVM_GET_MSRS handling, though less likely, still
have changes copy_from/to_user() fail. Therefore I added the check and
warning here, in that seldom case happens.

exit() or not, I'm also not sure. Seems not necessary, while my usual
programming philosophy is never let wrong goes further. For in the case
of ioctl(KVM_GET_MSRS) returns failure, something goes wrong underlying,
I would pre

Re: [Qemu-devel] [PATCH v3 1/3] x86: Data structure changes to support MSR based features

2018-08-17 Thread Robert Hoo
On Sat, 2018-08-18 at 11:10 +0800, Robert Hoo wrote:
> On Fri, 2018-08-17 at 00:10 -0300, Eduardo Habkost wrote:
> [trim...]
> > > +
> > >  typedef struct FeatureWordInfo {
> > > -/* feature flags names are taken from "Intel Processor 
> > > Identification and
> > > +FeatureWordType type;
> > > +   /* feature flags names are taken from "Intel Processor Identification 
> > > and
> > >   * the CPUID Instruction" and AMD's "CPUID Specification".
> > >   * In cases of disagreement between feature naming conventions,
> > >   * aliases may be added.
> > >   */
> > >  const char *feat_names[32];
> > > -uint32_t cpuid_eax;   /* Input EAX for CPUID */
> > > -bool cpuid_needs_ecx; /* CPUID instruction uses ECX as input */
> > > -uint32_t cpuid_ecx;   /* Input ECX value for CPUID */
> > > -int cpuid_reg;/* output register (R_* constant) */
> > > +union {
> > > +/* If type==CPUID_FEATURE_WORD */
> > > +struct {
> > > +uint32_t eax;   /* Input EAX for CPUID */
> > > +bool needs_ecx; /* CPUID instruction uses ECX as input */
> > > +uint32_t ecx;   /* Input ECX value for CPUID */
> > > +int reg;/* output register (R_* constant) */
> > > +} cpuid;
> > > +/* If type==MSR_FEATURE_WORD */
> > > +struct {
> > > +uint32_t index;
> > > +struct {   /*CPUID that enumerate this MSR*/
> > > +FeatureWord cpuid_class;
> > > +uint32_tcpuid_flag;
> > > +} cpuid_dep;
> > > +} msr;
> > > +};
> > >  uint32_t tcg_features; /* Feature flags supported by TCG */
> > >  uint32_t unmigratable_flags; /* Feature flags known to be 
> > > unmigratable */
> > >  uint32_t migratable_flags; /* Feature flags known to be migratable */
> > 
> > The data structure change looks good, but you are breaking the
> > build if you touch them without updating the existing code.  If
> > you break the build in your series, you break git-bisect.
> > 
> I had tested in my environment before send out, build has no even a
> warning. Is it because this patch is based on master + previous icelake
> cpu model set? I see you are pulling in previous icelake cpu model patch
> set. I will rebase this patch to then master. Will previous icelake cpu
> model patch set appear in master soon?

or you mean each single patch in a series should be individually built
pass? then it will a huge one here: data structure changes + reference
functions.
> > 
> > [...]
> > > +/*Below are MSR exposed features*/
> > > +[FEATURE_WORDS_ARCH_CAPABILITIES] = {
> > > +.type = MSR_FEATURE_WORD,
> > > +.feat_names = {
> > > +"rdctl-no", "ibrs-all", "rsba", NULL,
> > > +"ssb-no", NULL, NULL, NULL,
> > > +NULL, NULL, NULL, NULL,
> > > +NULL, NULL, NULL, NULL,
> > > +NULL, NULL, NULL, NULL,
> > > +NULL, NULL, NULL, NULL,
> > > +NULL, NULL, NULL, NULL,
> > > +NULL, NULL, NULL, NULL,
> > > +},
> > > +.msr = { .index = MSR_IA32_ARCH_CAPABILITIES,
> > > +.cpuid_dep = { FEAT_7_0_EDX,
> > > +CPUID_7_0_EDX_ARCH_CAPABILITIES }
> > > +},
> > > +},
> > 
> > I suggest moving this hunk to a separate patch: first we refactor
> > the existing code without changing behavior or adding new
> > features, then we add the new features.
> > 
> Sure.
> 
> > >  };
> > >  
> > >  typedef struct X86RegisterInfo32 {
> > > diff --git a/target/i386/cpu.h b/target/i386/cpu.h
> > > index cddf9d9..9e8879e 100644
> > > --- a/target/i386/cpu.h
> > > +++ b/target/i386/cpu.h
> > > @@ -502,9 +502,14 @@ typedef enum FeatureWord {
> > >  FEAT_6_EAX, /* CPUID[6].EAX */
> > >  FEAT_XSAVE_COMP_LO, /* CPUID[EAX=0xd,ECX=0].EAX */
> > >  FEAT_XSAVE_COMP_HI, /* CPUID[EAX=0xd,ECX=0].EDX */
> > > +FEATURE_WORDS_NUM_CPUID,
> > > +FEATURE_WORDS_FIRST_MSR = FEATURE_WORDS_NUM_CPUID,
> > > +FEATURE_WORDS_ARCH_CAPABILITIES = FEATURE_WORDS_FIRST_MSR,
> > >  FEATURE_WORDS,
> > >  } FeatureWord;
> > >  
> > > +#define FEATURE_WORDS_NUM_MSRS (FEATURE_WORDS - FEATURE_WORDS_FIRST_MSR)
> > > +
> > >  typedef uint32_t FeatureWordArray[FEATURE_WORDS];
> > >  
> > >  /* cpuid_features bits */
> > > -- 
> > > 1.8.3.1
> > > 
> > > 
> > 
> 
> 





Re: [Qemu-devel] [PATCH v3 1/3] x86: Data structure changes to support MSR based features

2018-08-17 Thread Robert Hoo
On Fri, 2018-08-17 at 00:10 -0300, Eduardo Habkost wrote:
[trim...]
> > +
> >  typedef struct FeatureWordInfo {
> > -/* feature flags names are taken from "Intel Processor Identification 
> > and
> > +FeatureWordType type;
> > +   /* feature flags names are taken from "Intel Processor Identification 
> > and
> >   * the CPUID Instruction" and AMD's "CPUID Specification".
> >   * In cases of disagreement between feature naming conventions,
> >   * aliases may be added.
> >   */
> >  const char *feat_names[32];
> > -uint32_t cpuid_eax;   /* Input EAX for CPUID */
> > -bool cpuid_needs_ecx; /* CPUID instruction uses ECX as input */
> > -uint32_t cpuid_ecx;   /* Input ECX value for CPUID */
> > -int cpuid_reg;/* output register (R_* constant) */
> > +union {
> > +/* If type==CPUID_FEATURE_WORD */
> > +struct {
> > +uint32_t eax;   /* Input EAX for CPUID */
> > +bool needs_ecx; /* CPUID instruction uses ECX as input */
> > +uint32_t ecx;   /* Input ECX value for CPUID */
> > +int reg;/* output register (R_* constant) */
> > +} cpuid;
> > +/* If type==MSR_FEATURE_WORD */
> > +struct {
> > +uint32_t index;
> > +struct {   /*CPUID that enumerate this MSR*/
> > +FeatureWord cpuid_class;
> > +uint32_tcpuid_flag;
> > +} cpuid_dep;
> > +} msr;
> > +};
> >  uint32_t tcg_features; /* Feature flags supported by TCG */
> >  uint32_t unmigratable_flags; /* Feature flags known to be unmigratable 
> > */
> >  uint32_t migratable_flags; /* Feature flags known to be migratable */
> 
> The data structure change looks good, but you are breaking the
> build if you touch them without updating the existing code.  If
> you break the build in your series, you break git-bisect.
> 
I had tested in my environment before send out, build has no even a
warning. Is it because this patch is based on master + previous icelake
cpu model set? I see you are pulling in previous icelake cpu model patch
set. I will rebase this patch to then master. Will previous icelake cpu
model patch set appear in master soon?
> 
> [...]
> > +/*Below are MSR exposed features*/
> > +[FEATURE_WORDS_ARCH_CAPABILITIES] = {
> > +.type = MSR_FEATURE_WORD,
> > +.feat_names = {
> > +"rdctl-no", "ibrs-all", "rsba", NULL,
> > +"ssb-no", NULL, NULL, NULL,
> > +NULL, NULL, NULL, NULL,
> > +NULL, NULL, NULL, NULL,
> > +NULL, NULL, NULL, NULL,
> > +NULL, NULL, NULL, NULL,
> > +NULL, NULL, NULL, NULL,
> > +NULL, NULL, NULL, NULL,
> > +},
> > +.msr = { .index = MSR_IA32_ARCH_CAPABILITIES,
> > +.cpuid_dep = { FEAT_7_0_EDX,
> > +CPUID_7_0_EDX_ARCH_CAPABILITIES }
> > +},
> > +},
> 
> I suggest moving this hunk to a separate patch: first we refactor
> the existing code without changing behavior or adding new
> features, then we add the new features.
> 
Sure.

> >  };
> >  
> >  typedef struct X86RegisterInfo32 {
> > diff --git a/target/i386/cpu.h b/target/i386/cpu.h
> > index cddf9d9..9e8879e 100644
> > --- a/target/i386/cpu.h
> > +++ b/target/i386/cpu.h
> > @@ -502,9 +502,14 @@ typedef enum FeatureWord {
> >  FEAT_6_EAX, /* CPUID[6].EAX */
> >  FEAT_XSAVE_COMP_LO, /* CPUID[EAX=0xd,ECX=0].EAX */
> >  FEAT_XSAVE_COMP_HI, /* CPUID[EAX=0xd,ECX=0].EDX */
> > +FEATURE_WORDS_NUM_CPUID,
> > +FEATURE_WORDS_FIRST_MSR = FEATURE_WORDS_NUM_CPUID,
> > +FEATURE_WORDS_ARCH_CAPABILITIES = FEATURE_WORDS_FIRST_MSR,
> >  FEATURE_WORDS,
> >  } FeatureWord;
> >  
> > +#define FEATURE_WORDS_NUM_MSRS (FEATURE_WORDS - FEATURE_WORDS_FIRST_MSR)
> > +
> >  typedef uint32_t FeatureWordArray[FEATURE_WORDS];
> >  
> >  /* cpuid_features bits */
> > -- 
> > 1.8.3.1
> > 
> > 
> 





Re: [Qemu-devel] [PATCH v3 3/3] Change other funcitons referring to feature_word_info[]

2018-08-14 Thread Robert Hoo
On Fri, 2018-08-10 at 10:17 -0500, Eric Blake wrote:
> On 08/10/2018 09:06 AM, Robert Hoo wrote:
> 
> In the subject: s/funcitons/functions/
> 
> Also, it may be worth using a topic prefix (most of our commit messages 
> resemble:
> 
> topic: Description of patch
> 
> to make it easier to spot patches by topic).
> 
> > Add an util function feature_word_description(), which help construct the 
> > string
> 
> s/an util/a util/
> s/help/helps/
> 
Thanks Eric, will fix these typos in v2.
> > describing the feature word (both CPUID and MSR types).
> > 
> > report_unavailable_features(): add MSR_FEATURE_WORD type support.
> > x86_cpu_get_feature_words(): limit to CPUID_FEATURE_WORD only.
> > x86_cpu_get_supported_feature_word(): add MSR_FEATURE_WORD type support.
> > x86_cpu_adjust_feat_level(): assert the requested feature must be
> > CPUID_FEATURE_WORD type.
> > 
> > Signed-off-by: Robert Hoo 
> > ---
> >   target/i386/cpu.c | 77 
> > +--
> >   1 file changed, 58 insertions(+), 19 deletions(-)
> > 
> > diff --git a/target/i386/cpu.c b/target/i386/cpu.c
> > index f7c70d9..21ed599 100644
> > --- a/target/i386/cpu.c
> > +++ b/target/i386/cpu.c
> > @@ -3024,21 +3024,51 @@ static const TypeInfo host_x86_cpu_type_info = {
> >   
> >   #endif
> >   
> > +/*
> > +*caller should have input str no less than 64 byte length.
> > +*/
> > +#define FEATURE_WORD_DESCPTION_LEN 64
> 
> s/DESCPTION/DESCRIPTION/
> 
> > +static int feature_word_description(char str[], FeatureWordInfo *f,
> > +uint32_t bit)
> > +{
> 
> Prone to buffer overflow if the caller doesn't pass in the length. 
> Would it be better to just g_strdup_printf() into a malloc'd result 
> instead of trying to snprintf()'ing into a buffer that you hope the 
> caller sized large enough?
> 
Oh, wasn't aware of such good util functions. Sure I'd like to use them.
Is there some web page introducing them?

Eduardo/Paolo, do you have more comments?
> > +int ret;
> > +
> > +assert(f->type == CPUID_FEATURE_WORD ||
> > +f->type == MSR_FEATURE_WORD);
> > +switch (f->type) {
> > +case CPUID_FEATURE_WORD:
> > +{
> > +const char *reg = get_register_name_32(f->cpuid.reg);
> > +assert(reg);
> > +ret = snprintf(str, FEATURE_WORD_DESCPTION_LEN,
> > +"CPUID.%02XH:%s%s%s [bit %d]",
> > +f->cpuid.eax, reg,
> > +f->feat_names[bit] ? "." : "",
> > +f->feat_names[bit] ? f->feat_names[bit] : "", bit);
> > +break;
> > +}
> > +case MSR_FEATURE_WORD:
> > +ret = snprintf(str, FEATURE_WORD_DESCPTION_LEN,
> > +"MSR(%xH).%s [bit %d]",
> > +f->msr.index,
> > +f->feat_names[bit] ? f->feat_names[bit] : "", bit);
> > +break;
> > +}
> 





[Qemu-devel] [PATCH v3 1/3] x86: Data structure changes to support MSR based features

2018-08-10 Thread Robert Hoo
Define FeatureWordType.
Expand FeatureWordInfo to support both CPUID type feature word as well as
MSR type's.
Change feature_word_info[] accordingly.

Signed-off-by: Robert Hoo 
---
 target/i386/cpu.c | 133 ++
 target/i386/cpu.h |   5 ++
 2 files changed, 99 insertions(+), 39 deletions(-)

diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index ba7abe5..f7c70d9 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -770,17 +770,36 @@ static void x86_cpu_vendor_words2str(char *dst, uint32_t 
vendor1,
   /* missing:
   CPUID_XSAVE_XSAVEC, CPUID_XSAVE_XSAVES */
 
+typedef enum FeatureWordType {
+   CPUID_FEATURE_WORD,
+   MSR_FEATURE_WORD,
+} FeatureWordType;
+
 typedef struct FeatureWordInfo {
-/* feature flags names are taken from "Intel Processor Identification and
+FeatureWordType type;
+   /* feature flags names are taken from "Intel Processor Identification and
  * the CPUID Instruction" and AMD's "CPUID Specification".
  * In cases of disagreement between feature naming conventions,
  * aliases may be added.
  */
 const char *feat_names[32];
-uint32_t cpuid_eax;   /* Input EAX for CPUID */
-bool cpuid_needs_ecx; /* CPUID instruction uses ECX as input */
-uint32_t cpuid_ecx;   /* Input ECX value for CPUID */
-int cpuid_reg;/* output register (R_* constant) */
+union {
+/* If type==CPUID_FEATURE_WORD */
+struct {
+uint32_t eax;   /* Input EAX for CPUID */
+bool needs_ecx; /* CPUID instruction uses ECX as input */
+uint32_t ecx;   /* Input ECX value for CPUID */
+int reg;/* output register (R_* constant) */
+} cpuid;
+/* If type==MSR_FEATURE_WORD */
+struct {
+uint32_t index;
+struct {   /*CPUID that enumerate this MSR*/
+FeatureWord cpuid_class;
+uint32_tcpuid_flag;
+} cpuid_dep;
+} msr;
+};
 uint32_t tcg_features; /* Feature flags supported by TCG */
 uint32_t unmigratable_flags; /* Feature flags known to be unmigratable */
 uint32_t migratable_flags; /* Feature flags known to be migratable */
@@ -790,6 +809,7 @@ typedef struct FeatureWordInfo {
 
 static FeatureWordInfo feature_word_info[FEATURE_WORDS] = {
 [FEAT_1_EDX] = {
+.type = CPUID_FEATURE_WORD,
 .feat_names = {
 "fpu", "vme", "de", "pse",
 "tsc", "msr", "pae", "mce",
@@ -800,10 +820,11 @@ static FeatureWordInfo feature_word_info[FEATURE_WORDS] = 
{
 "fxsr", "sse", "sse2", "ss",
 "ht" /* Intel htt */, "tm", "ia64", "pbe",
 },
-.cpuid_eax = 1, .cpuid_reg = R_EDX,
+.cpuid = {.eax = 1, .reg = R_EDX, },
 .tcg_features = TCG_FEATURES,
 },
 [FEAT_1_ECX] = {
+.type = CPUID_FEATURE_WORD,
 .feat_names = {
 "pni" /* Intel,AMD sse3 */, "pclmulqdq", "dtes64", "monitor",
 "ds-cpl", "vmx", "smx", "est",
@@ -814,7 +835,7 @@ static FeatureWordInfo feature_word_info[FEATURE_WORDS] = {
 "tsc-deadline", "aes", "xsave", NULL /* osxsave */,
 "avx", "f16c", "rdrand", "hypervisor",
 },
-.cpuid_eax = 1, .cpuid_reg = R_ECX,
+.cpuid = { .eax = 1, .reg = R_ECX, },
 .tcg_features = TCG_EXT_FEATURES,
 },
 /* Feature names that are already defined on feature_name[] but
@@ -823,6 +844,7 @@ static FeatureWordInfo feature_word_info[FEATURE_WORDS] = {
  * to features[FEAT_8000_0001_EDX] if and only if CPU vendor is AMD.
  */
 [FEAT_8000_0001_EDX] = {
+.type = CPUID_FEATURE_WORD,
 .feat_names = {
 NULL /* fpu */, NULL /* vme */, NULL /* de */, NULL /* pse */,
 NULL /* tsc */, NULL /* msr */, NULL /* pae */, NULL /* mce */,
@@ -833,10 +855,11 @@ static FeatureWordInfo feature_word_info[FEATURE_WORDS] = 
{
 NULL /* fxsr */, "fxsr-opt", "pdpe1gb", "rdtscp",
 NULL, "lm", "3dnowext", "3dnow",
 },
-.cpuid_eax = 0x8001, .cpuid_reg = R_EDX,
+.cpuid = { .eax = 0x8001, .reg = R_EDX, },
 .tcg_features = TCG_EXT2_FEATURES,
 },
 [FEAT_8000_0001_ECX] = {
+.type = CPUID_FEATURE_WORD,
 .feat_names = {
 "lahf-lm", "cmp-legacy", "svm", "extapic",
 "cr8legacy", "abm", "sse4a", "misalignsse",
@@ -847,10 +870,11 @@ static FeatureWordInfo feat

[Qemu-devel] [PATCH v3 0/3] x86: QEMU side support on MSR based features

2018-08-10 Thread Robert Hoo
KVM side has added the framework (kvm.git:d1d93fa90) to support MSR based 
features.
Here is the QEMU part, including data structure changes/expanding, referring
functions changes, and the implementations on 
KVM_GET_MSR_FEATURE_INDEX_LIST and KVM_GET_MSRS system ioctl.

Changelog:
v3: patch 2&3 in v2 are corrupted. Re-format patches.
v2: coding style changes to pass ./scripts/checkpatch.pl.
----
Robert Hoo (3):
  x86: Data structure changes to support MSR based features
  kvm: Add support to KVM_GET_MSR_FEATURE_INDEX_LIST and KVM_GET_MSRS
system ioctl
  Change other funcitons referring to feature_word_info[]

 include/sysemu/kvm.h |   2 +
 target/i386/cpu.c| 210 +--
 target/i386/cpu.h|   5 ++
 target/i386/kvm.c|  79 +++
 4 files changed, 238 insertions(+), 58 deletions(-)

-- 
1.8.3.1




[Qemu-devel] [PATCH v3 2/3] kvm: Add support to KVM_GET_MSR_FEATURE_INDEX_LIST and KVM_GET_MSRS system ioctl

2018-08-10 Thread Robert Hoo
Add kvm_get_supported_feature_msrs() to get supported MSR feature index list.
Add kvm_arch_get_supported_msr_feature() to get each MSR features value.

kvm_get_supported_feature_msrs() is called in kvm_arch_init().
kvm_arch_get_supported_msr_feature() is called by
x86_cpu_get_supported_feature_word().

Signed-off-by: Robert Hoo 
---
 include/sysemu/kvm.h |  2 ++
 target/i386/kvm.c| 79 
 2 files changed, 81 insertions(+)

diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h
index 0b64b8e..97d8d9d 100644
--- a/include/sysemu/kvm.h
+++ b/include/sysemu/kvm.h
@@ -463,6 +463,8 @@ int kvm_vm_check_extension(KVMState *s, unsigned int 
extension);
 
 uint32_t kvm_arch_get_supported_cpuid(KVMState *env, uint32_t function,
   uint32_t index, int reg);
+uint32_t kvm_arch_get_supported_msr_feature(KVMState *s, uint32_t index);
+
 
 void kvm_set_sigmask_len(KVMState *s, unsigned int sigmask_len);
 
diff --git a/target/i386/kvm.c b/target/i386/kvm.c
index 9313602..70d8606 100644
--- a/target/i386/kvm.c
+++ b/target/i386/kvm.c
@@ -107,6 +107,7 @@ static int has_pit_state2;
 static bool has_msr_mcg_ext_ctl;
 
 static struct kvm_cpuid2 *cpuid_cache;
+static struct kvm_msr_list *kvm_feature_msrs;
 
 int kvm_has_pit_state2(void)
 {
@@ -420,6 +421,41 @@ uint32_t kvm_arch_get_supported_cpuid(KVMState *s, 
uint32_t function,
 return ret;
 }
 
+uint32_t kvm_arch_get_supported_msr_feature(KVMState *s, uint32_t index)
+{
+struct {
+struct kvm_msrs info;
+struct kvm_msr_entry entries[1];
+} msr_data;
+uint32_t ret;
+
+/*Check if the requested feature MSR is supported*/
+int i;
+for (i = 0; i < kvm_feature_msrs->nmsrs; i++) {
+if (index == kvm_feature_msrs->indices[i]) {
+break;
+}
+}
+if (i >= kvm_feature_msrs->nmsrs) {
+fprintf(stderr, "Requested MSR (index= %d) is not supported.\n", 
index);
+return 0;
+}
+
+msr_data.info.nmsrs = 1;
+msr_data.entries[0].index = index;
+
+ret = kvm_ioctl(s, KVM_GET_MSRS, _data);
+
+if (ret != 1) {
+fprintf(stderr, "KVM get MSR (index=0x%x) feature failed, %s\n",
+index, strerror(-ret));
+exit(1);
+}
+
+return msr_data.entries[0].data;
+}
+
+
 typedef struct HWPoisonPage {
 ram_addr_t ram_addr;
 QLIST_ENTRY(HWPoisonPage) list;
@@ -1238,7 +1274,45 @@ void kvm_arch_do_init_vcpu(X86CPU *cpu)
 env->mp_state = KVM_MP_STATE_INIT_RECEIVED;
 }
 }
+static int kvm_get_supported_feature_msrs(KVMState *s)
+{
+static int kvm_supported_feature_msrs;
+int ret = 0;
+
+if (kvm_supported_feature_msrs == 0) {
+struct kvm_msr_list msr_list;
+
+kvm_supported_feature_msrs++;
+
+msr_list.nmsrs = 0;
+ret = kvm_ioctl(s, KVM_GET_MSR_FEATURE_INDEX_LIST, _list);
+if (ret < 0 && ret != -E2BIG) {
+return ret;
+}
+
+assert(msr_list.nmsrs > 0);
+kvm_feature_msrs = (struct kvm_msr_list *) \
+g_malloc0(sizeof(msr_list) +
+ msr_list.nmsrs * sizeof(msr_list.indices[0]));
+if (kvm_feature_msrs == NULL) {
+fprintf(stderr, "Failed to allocate space for KVM Feature MSRs"
+"which has %d MSRs\n", msr_list.nmsrs);
+return -1;
+}
+
+kvm_feature_msrs->nmsrs = msr_list.nmsrs;
+ret = kvm_ioctl(s, KVM_GET_MSR_FEATURE_INDEX_LIST, kvm_feature_msrs);
 
+if (ret < 0) {  /*ioctl failure*/
+fprintf(stderr, "Fetch KVM feature MSRs failed: %s\n",
+strerror(-ret));
+g_free(kvm_feature_msrs);
+return ret;
+}
+}
+
+return 0;
+}
 static int kvm_get_supported_msrs(KVMState *s)
 {
 static int kvm_supported_msrs;
@@ -1400,6 +1474,11 @@ int kvm_arch_init(MachineState *ms, KVMState *s)
 return ret;
 }
 
+ret = kvm_get_supported_feature_msrs(s);
+if (ret < 0) {
+return ret;
+}
+
 uname();
 lm_capable_kernel = strcmp(utsname.machine, "x86_64") == 0;
 
-- 
1.8.3.1




[Qemu-devel] [PATCH v3 3/3] Change other funcitons referring to feature_word_info[]

2018-08-10 Thread Robert Hoo
Add an util function feature_word_description(), which help construct the string
describing the feature word (both CPUID and MSR types).

report_unavailable_features(): add MSR_FEATURE_WORD type support.
x86_cpu_get_feature_words(): limit to CPUID_FEATURE_WORD only.
x86_cpu_get_supported_feature_word(): add MSR_FEATURE_WORD type support.
x86_cpu_adjust_feat_level(): assert the requested feature must be
CPUID_FEATURE_WORD type.

Signed-off-by: Robert Hoo 
---
 target/i386/cpu.c | 77 +--
 1 file changed, 58 insertions(+), 19 deletions(-)

diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index f7c70d9..21ed599 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -3024,21 +3024,51 @@ static const TypeInfo host_x86_cpu_type_info = {
 
 #endif
 
+/*
+*caller should have input str no less than 64 byte length.
+*/
+#define FEATURE_WORD_DESCPTION_LEN 64
+static int feature_word_description(char str[], FeatureWordInfo *f,
+uint32_t bit)
+{
+int ret;
+
+assert(f->type == CPUID_FEATURE_WORD ||
+f->type == MSR_FEATURE_WORD);
+switch (f->type) {
+case CPUID_FEATURE_WORD:
+{
+const char *reg = get_register_name_32(f->cpuid.reg);
+assert(reg);
+ret = snprintf(str, FEATURE_WORD_DESCPTION_LEN,
+"CPUID.%02XH:%s%s%s [bit %d]",
+f->cpuid.eax, reg,
+f->feat_names[bit] ? "." : "",
+f->feat_names[bit] ? f->feat_names[bit] : "", bit);
+break;
+}
+case MSR_FEATURE_WORD:
+ret = snprintf(str, FEATURE_WORD_DESCPTION_LEN,
+"MSR(%xH).%s [bit %d]",
+f->msr.index,
+f->feat_names[bit] ? f->feat_names[bit] : "", bit);
+break;
+}
+return ret > 0;
+}
+
 static void report_unavailable_features(FeatureWord w, uint32_t mask)
 {
 FeatureWordInfo *f = _word_info[w];
 int i;
+char feat_word_dscrp_str[FEATURE_WORD_DESCPTION_LEN];
 
 for (i = 0; i < 32; ++i) {
 if ((1UL << i) & mask) {
-const char *reg = get_register_name_32(f->cpuid_reg);
-assert(reg);
-warn_report("%s doesn't support requested feature: "
-"CPUID.%02XH:%s%s%s [bit %d]",
+feature_word_description(feat_word_dscrp_str, f, i);
+warn_report("%s doesn't support requested feature: %s",
 accel_uses_host_cpuid() ? "host" : "TCG",
-f->cpuid_eax, reg,
-f->feat_names[i] ? "." : "",
-f->feat_names[i] ? f->feat_names[i] : "", i);
+feat_word_dscrp_str);
 }
 }
 }
@@ -3276,17 +3306,17 @@ static void x86_cpu_get_feature_words(Object *obj, 
Visitor *v,
 {
 uint32_t *array = (uint32_t *)opaque;
 FeatureWord w;
-X86CPUFeatureWordInfo word_infos[FEATURE_WORDS] = { };
-X86CPUFeatureWordInfoList list_entries[FEATURE_WORDS] = { };
+X86CPUFeatureWordInfo word_infos[FEATURE_WORDS_NUM_CPUID] = { };
+X86CPUFeatureWordInfoList list_entries[FEATURE_WORDS_NUM_CPUID] = { };
 X86CPUFeatureWordInfoList *list = NULL;
 
-for (w = 0; w < FEATURE_WORDS; w++) {
+for (w = 0; w < FEATURE_WORDS_NUM_CPUID; w++) {
 FeatureWordInfo *wi = _word_info[w];
 X86CPUFeatureWordInfo *qwi = _infos[w];
-qwi->cpuid_input_eax = wi->cpuid_eax;
-qwi->has_cpuid_input_ecx = wi->cpuid_needs_ecx;
-qwi->cpuid_input_ecx = wi->cpuid_ecx;
-qwi->cpuid_register = x86_reg_info_32[wi->cpuid_reg].qapi_enum;
+qwi->cpuid_input_eax = wi->cpuid.eax;
+qwi->has_cpuid_input_ecx = wi->cpuid.needs_ecx;
+qwi->cpuid_input_ecx = wi->cpuid.ecx;
+qwi->cpuid_register = x86_reg_info_32[wi->cpuid.reg].qapi_enum;
 qwi->features = array[w];
 
 /* List will be in reverse order, but order shouldn't matter */
@@ -3659,12 +3689,20 @@ static uint32_t 
x86_cpu_get_supported_feature_word(FeatureWord w,
bool migratable_only)
 {
 FeatureWordInfo *wi = _word_info[w];
-uint32_t r;
+uint32_t r = 0;
 
 if (kvm_enabled()) {
-r = kvm_arch_get_supported_cpuid(kvm_state, wi->cpuid_eax,
-wi->cpuid_ecx,
-wi->cpuid_reg);
+switch (wi->type) {
+case CPUID_FEATURE_WORD:
+r = kvm_arch_get_supported_cpuid(kvm_state, wi->cpuid.eax,
+wi->cpuid.ecx,
+

[Qemu-devel] [PATCH v2 1/3] x86: Data structure changes to support MSR based features

2018-08-09 Thread Robert Hoo
Define FeatureWordType.
Expand FeatureWordInfo to support both CPUID type feature word as well as
MSR type's.
Change feature_word_info[] accordingly.

Signed-off-by: Robert Hoo 
---
 target/i386/cpu.c | 133 ++
 target/i386/cpu.h |   5 ++
 2 files changed, 99 insertions(+), 39 deletions(-)

diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index ba7abe5..77e1859 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -770,17 +770,36 @@ static void x86_cpu_vendor_words2str(char *dst, uint32_t 
vendor1,
   /* missing:
   CPUID_XSAVE_XSAVEC, CPUID_XSAVE_XSAVES */
 
+typedef enum FeatureWordType {
+   CPUID_FEATURE_WORD,
+   MSR_FEATURE_WORD,
+} FeatureWordType;
+
 typedef struct FeatureWordInfo {
-/* feature flags names are taken from "Intel Processor Identification and
+FeatureWordType type;
+   /* feature flags names are taken from "Intel Processor Identification and
  * the CPUID Instruction" and AMD's "CPUID Specification".
  * In cases of disagreement between feature naming conventions,
  * aliases may be added.
  */
 const char *feat_names[32];
-uint32_t cpuid_eax;   /* Input EAX for CPUID */
-bool cpuid_needs_ecx; /* CPUID instruction uses ECX as input */
-uint32_t cpuid_ecx;   /* Input ECX value for CPUID */
-int cpuid_reg;/* output register (R_* constant) */
+union {
+/* If type==CPUID_FEATURE_WORD */
+struct {
+uint32_t eax;   /* Input EAX for CPUID */
+bool needs_ecx; /* CPUID instruction uses ECX as input */
+uint32_t ecx;   /* Input ECX value for CPUID */
+int reg;/* output register (R_* constant) */
+} cpuid;
+/* If type==MSR_FEATURE_WORD */
+struct {
+uint32_t index;
+struct {   /*CPUID that enumerate this MSR*/
+FeatureWord cpuid_class;
+uint32_tcpuid_flag;
+} cpuid_dep;
+} msr;
+};
 uint32_t tcg_features; /* Feature flags supported by TCG */
 uint32_t unmigratable_flags; /* Feature flags known to be unmigratable */
 uint32_t migratable_flags; /* Feature flags known to be migratable */
@@ -790,6 +809,7 @@ typedef struct FeatureWordInfo {
 
 static FeatureWordInfo feature_word_info[FEATURE_WORDS] = {
 [FEAT_1_EDX] = {
+.type = CPUID_FEATURE_WORD,
 .feat_names = {
 "fpu", "vme", "de", "pse",
 "tsc", "msr", "pae", "mce",
@@ -800,10 +820,11 @@ static FeatureWordInfo feature_word_info[FEATURE_WORDS] = 
{
 "fxsr", "sse", "sse2", "ss",
 "ht" /* Intel htt */, "tm", "ia64", "pbe",
 },
-.cpuid_eax = 1, .cpuid_reg = R_EDX,
+.cpuid = {.eax = 1, .reg = R_EDX, },
 .tcg_features = TCG_FEATURES,
 },
 [FEAT_1_ECX] = {
+.type = CPUID_FEATURE_WORD,
 .feat_names = {
 "pni" /* Intel,AMD sse3 */, "pclmulqdq", "dtes64", "monitor",
 "ds-cpl", "vmx", "smx", "est",
@@ -814,7 +835,7 @@ static FeatureWordInfo feature_word_info[FEATURE_WORDS] = {
 "tsc-deadline", "aes", "xsave", NULL /* osxsave */,
 "avx", "f16c", "rdrand", "hypervisor",
 },
-.cpuid_eax = 1, .cpuid_reg = R_ECX,
+.cpuid = { .eax = 1, .reg = R_ECX, },
 .tcg_features = TCG_EXT_FEATURES,
 },
 /* Feature names that are already defined on feature_name[] but
@@ -823,6 +844,7 @@ static FeatureWordInfo feature_word_info[FEATURE_WORDS] = {
  * to features[FEAT_8000_0001_EDX] if and only if CPU vendor is AMD.
  */
 [FEAT_8000_0001_EDX] = {
+.type = CPUID_FEATURE_WORD,
 .feat_names = {
 NULL /* fpu */, NULL /* vme */, NULL /* de */, NULL /* pse */,
 NULL /* tsc */, NULL /* msr */, NULL /* pae */, NULL /* mce */,
@@ -833,10 +855,11 @@ static FeatureWordInfo feature_word_info[FEATURE_WORDS] = 
{
 NULL /* fxsr */, "fxsr-opt", "pdpe1gb", "rdtscp",
 NULL, "lm", "3dnowext", "3dnow",
 },
-.cpuid_eax = 0x8001, .cpuid_reg = R_EDX,
+.cpuid = { .eax = 0x8001, .reg = R_EDX, },
 .tcg_features = TCG_EXT2_FEATURES,
 },
 [FEAT_8000_0001_ECX] = {
+.type = CPUID_FEATURE_WORD,
 .feat_names = {
 "lahf-lm", "cmp-legacy", "svm", "extapic",
 "cr8legacy", "abm", "sse4a", "misalignsse",
@@ -847,10 +870,11 @@ static FeatureWordInfo feat

[Qemu-devel] [PATCH v2 0/3] x86: QEMU side support on MSR based features

2018-08-09 Thread Robert Hoo
KVM side has added the framework (kvm.git:d1d93fa90) to support MSR based 
features.
Here is the QEMU part, including data structure changes/expanding, referring
functions changes, and the implementations on 
KVM_GET_MSR_FEATURE_INDEX_LIST and KVM_GET_MSRS system ioctl.

Changelog:
v2: coding style changes to pass ./scripts/checkpatch.pl.

Robert Hoo (3):
  x86: Data structure changes to support MSR based features
  kvm: Add support to KVM_GET_MSR_FEATURE_INDEX_LIST and KVM_GET_MSRS
system ioctl
  Change other funcitons referring to feature_word_info[]

 include/sysemu/kvm.h |   2 +
 target/i386/cpu.c| 209 +--
 target/i386/cpu.h|   5 ++
 target/i386/kvm.c|  78 +++
 4 files changed, 236 insertions(+), 58 deletions(-)

-- 
1.8.3.1




[Qemu-devel] [PATCH v2 3/3] Change other funcitons referring to feature_word_info[]

2018-08-09 Thread Robert Hoo
Add an util function feature_word_description(), which help construct the string
describing the feature word (both CPUID and MSR types).

report_unavailable_features(): add MSR_FEATURE_WORD type support.
x86_cpu_get_feature_words(): limit to CPUID_FEATURE_WORD only.
x86_cpu_get_supported_feature_word(): add MSR_FEATURE_WORD type support.
x86_cpu_adjust_feat_level(): assert the requested feature must be
CPUID_FEATURE_WORD type.

Signed-off-by: Robert Hoo 
---
 target/i386/cpu.c | 76 +--
 1 file changed, 57 insertions(+), 19 deletions(-)

diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index 77e1859..51989e5 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -3024,21 +3024,50 @@ static const TypeInfo host_x86_cpu_type_info = {
 
 #endif
 
+/*
+*caller should have input str no less than 64 byte length.
+*/
+#define FEATURE_WORD_DESCPTION_LEN 64
+static int feature_word_description(char str[], FeatureWordInfo *f,
+uint32_t bit)
+{
+int ret;
+
+assert(f->type == CPUID_FEATURE_WORD ||
+f->type == MSR_FEATURE_WORD);
+switch (f->type) {
+case CPUID_FEATURE_WORD:
+{
+const char *reg = get_register_name_32(f->cpuid.reg);
+assert(reg);
+ret = snprintf(str, FEATURE_WORD_DESCPTION_LEN,
+"CPUID.%02XH:%s%s%s [bit %d]",
+f->cpuid.eax, reg,
+f->feat_names[bit] ? "." : "",
+f->feat_names[bit] ? f->feat_names[bit] : "", bit);
+break;
+}
+case MSR_FEATURE_WORD:
+ret = snprintf(str, FEATURE_WORD_DESCPTION_LEN,
+"MSR(%xH).%s [bit %d]",
+f->msr.index,
+f->feat_names[bit] ? f->feat_names[bit] : "", bit);
+break;
+}
+return ret > 0;
+}
+
 static void report_unavailable_features(FeatureWord w, uint32_t mask)
 {
 FeatureWordInfo *f = _word_info[w];
 int i;
+char feat_word_dscrp_str[FEATURE_WORD_DESCPTION_LEN];
 
 for (i = 0; i < 32; ++i) {
 if ((1UL << i) & mask) {
-const char *reg = get_register_name_32(f->cpuid_reg);
-assert(reg);
-warn_report("%s doesn't support requested feature: "
-"CPUID.%02XH:%s%s%s [bit %d]",
+feature_word_description(feat_word_dscrp_str, f, i);
+warn_report("%s doesn't support requested feature: %s",
 accel_uses_host_cpuid() ? "host" : "TCG",
-f->cpuid_eax, reg,
-f->feat_names[i] ? "." : "",
-f->feat_names[i] ? f->feat_names[i] : "", i);
+feat_word_dscrp_str);
 }
 }
 }
@@ -3276,17 +3305,17 @@ static void x86_cpu_get_feature_words(Object *obj, 
Visitor *v,
 {
 uint32_t *array = (uint32_t *)opaque;
 FeatureWord w;
-X86CPUFeatureWordInfo word_infos[FEATURE_WORDS] = { };
-X86CPUFeatureWordInfoList list_entries[FEATURE_WORDS] = { };
+X86CPUFeatureWordInfo word_infos[FEATURE_WORDS_NUM_CPUID] = { };
+X86CPUFeatureWordInfoList list_entries[FEATURE_WORDS_NUM_CPUID] = { };
 X86CPUFeatureWordInfoList *list = NULL;
 
-for (w = 0; w < FEATURE_WORDS; w++) {
+for (w = 0; w < FEATURE_WORDS_NUM_CPUID; w++) {
 FeatureWordInfo *wi = _word_info[w];
 X86CPUFeatureWordInfo *qwi = _infos[w];
-qwi->cpuid_input_eax = wi->cpuid_eax;
-qwi->has_cpuid_input_ecx = wi->cpuid_needs_ecx;
-qwi->cpuid_input_ecx = wi->cpuid_ecx;
-qwi->cpuid_register = x86_reg_info_32[wi->cpuid_reg].qapi_enum;
+qwi->cpuid_input_eax = wi->cpuid.eax;
+qwi->has_cpuid_input_ecx = wi->cpuid.needs_ecx;
+qwi->cpuid_input_ecx = wi->cpuid.ecx;
+qwi->cpuid_register = x86_reg_info_32[wi->cpuid.reg].qapi_enum;
 qwi->features = array[w];
 
 /* List will be in reverse order, but order shouldn't matter */
@@ -3659,12 +3688,20 @@ static uint32_t 
x86_cpu_get_supported_feature_word(FeatureWord w,
bool migratable_only)
 {
 FeatureWordInfo *wi = _word_info[w];
-uint32_t r;
+uint32_t r = 0;
 
 if (kvm_enabled()) {
-r = kvm_arch_get_supported_cpuid(kvm_state, wi->cpuid_eax,
-wi->cpuid_ecx,
-wi->cpuid_reg);
+switch (wi->type) {
+case CPUID_FEATURE_WORD:
+r = kvm_arch_get_supported_cpuid(kvm_state, wi->cpuid.eax,
+wi->cpuid.ecx,
+   

[Qemu-devel] [PATCH v2 2/3] kvm: Add support to KVM_GET_MSR_FEATURE_INDEX_LIST and KVM_GET_MSRS system ioctl

2018-08-09 Thread Robert Hoo
Add kvm_get_supported_feature_msrs() to get supported MSR feature index list.
Add kvm_arch_get_supported_msr_feature() to get each MSR features value.

kvm_get_supported_feature_msrs() is called in kvm_arch_init().
kvm_arch_get_supported_msr_feature() is called by
x86_cpu_get_supported_feature_word().

Signed-off-by: Robert Hoo 
---
 include/sysemu/kvm.h |  2 ++
 target/i386/kvm.c| 78 
 2 files changed, 80 insertions(+)

diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h
index 0b64b8e..0cf792f 100644
--- a/include/sysemu/kvm.h
+++ b/include/sysemu/kvm.h
@@ -463,6 +463,8 @@ int kvm_vm_check_extension(KVMState *s, unsigned int 
extension);
 
 uint32_t kvm_arch_get_supported_cpuid(KVMState *env, uint32_t function,
   uint32_t index, int reg);
+uint32_t kvm_arch_get_supported_msr_feature(KVMState *s, uint32_t index);
+
 
 void kvm_set_sigmask_len(KVMState *s, unsigned int sigmask_len);
 
diff --git a/target/i386/kvm.c b/target/i386/kvm.c
index 9313602..7268ab7 100644
--- a/target/i386/kvm.c
+++ b/target/i386/kvm.c
@@ -107,6 +107,7 @@ static int has_pit_state2;
 static bool has_msr_mcg_ext_ctl;
 
 static struct kvm_cpuid2 *cpuid_cache;
+static struct kvm_msr_list *kvm_feature_msrs;
 
 int kvm_has_pit_state2(void)
 {
@@ -420,6 +421,41 @@ uint32_t kvm_arch_get_supported_cpuid(KVMState *s, 
uint32_t function,
 return ret;
 }
 
+uint32_t kvm_arch_get_supported_msr_feature(KVMState *s, uint32_t index)
+{
+struct {
+struct kvm_msrs info;
+struct kvm_msr_entry entries[1];
+} msr_data;
+uint32_t ret;
+
+/*Check if the requested feature MSR is supported*/
+int i;
+for (i = 0; i < kvm_feature_msrs->nmsrs; i++) {
+if (index == kvm_feature_msrs->indices[i]) {
+break;
+}
+}
+if (i >= kvm_feature_msrs->nmsrs) {
+fprintf(stderr, "Requested MSR (index= %d) is not supported.\n", 
index);
+return 0;
+}
+
+msr_data.info.nmsrs = 1;
+msr_data.entries[0].index = index;
+
+ret = kvm_ioctl(s, KVM_GET_MSRS, _data);
+
+if (ret != 1) {
+fprintf(stderr, "KVM get MSR (index=0x%x) feature failed, %s\n",
+index, strerror(-ret));
+exit(1);
+}
+
+return msr_data.entries[0].data;
+}
+
+
 typedef struct HWPoisonPage {
 ram_addr_t ram_addr;
 QLIST_ENTRY(HWPoisonPage) list;
@@ -1238,7 +1274,44 @@ void kvm_arch_do_init_vcpu(X86CPU *cpu)
 env->mp_state = KVM_MP_STATE_INIT_RECEIVED;
 }
 }
+static int kvm_get_supported_feature_msrs(KVMState *s)
+{
+static int kvm_supported_feature_msrs;
+int ret = 0;
+
+if (kvm_supported_feature_msrs == 0) {
+struct kvm_msr_list msr_list;
+
+kvm_supported_feature_msrs++;
+
+msr_list.nmsrs = 0;
+ret = kvm_ioctl(s, KVM_GET_MSR_FEATURE_INDEX_LIST, _list);
+if (ret < 0 && ret != -E2BIG) {
+return ret;
+}
+
+assert(msr_list.nmsrs > 0);
+kvm_feature_msrs = (struct kvm_msr_list *) \
+g_malloc0(sizeof(msr_list) +
+ msr_list.nmsrs * sizeof(msr_list.indices[0]));
+if (kvm_feature_msrs == NULL) {
+fprintf(stderr, "Failed to allocate space for KVM Feature MSRs"
+"which has %d MSRs\n", msr_list.nmsrs);
+return -1;
+}
+
+kvm_feature_msrs->nmsrs = msr_list.nmsrs;
+ret = kvm_ioctl(s, KVM_GET_MSR_FEATURE_INDEX_LIST, kvm_feature_msrs);
 
+if (ret < 0) {  /*ioctl failure*/
+fprintf(stderr, "Fetch KVM feature MSRs failed: %s\n",
+strerror(-ret));
+g_free(kvm_feature_msrs);
+return ret;
+}
+}
+
+return 0;
+}
 static int kvm_get_supported_msrs(KVMState *s)
 {
 static int kvm_supported_msrs;
@@ -1400,6 +1473,11 @@ int kvm_arch_init(MachineState *ms, KVMState *s)
 return ret;
 }
 
+ret = kvm_get_supported_feature_msrs(s);
+if (ret < 0) {
+return ret;
+}
+
 uname();
 lm_capable_kernel = strcmp(utsname.machine, "x86_64") == 0;
 
-- 
1.8.3.1




[Qemu-devel] [PATCH v1 3/3] Change other funcitons referring to feature_word_info[]

2018-08-09 Thread Robert Hoo
Add an util function feature_word_description(), which help construct the string
describing the feature word (both CPUID and MSR types).

report_unavailable_features(): add MSR_FEATURE_WORD type support.
x86_cpu_get_feature_words(): limit to CPUID_FEATURE_WORD only.
x86_cpu_get_supported_feature_word(): add MSR_FEATURE_WORD type support.
x86_cpu_adjust_feat_level(): assert the requested feature must be
CPUID_FEATURE_WORD type.

Signed-off-by: Robert Hoo 
---
 target/i386/cpu.c | 76 +--
 1 file changed, 57 insertions(+), 19 deletions(-)

diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index 77e1859..51989e5 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -3024,21 +3024,50 @@ static const TypeInfo host_x86_cpu_type_info = {
 
 #endif
 
+/*
+*caller should have input str no less than 64 byte length.
+*/
+#define FEATURE_WORD_DESCPTION_LEN 64
+static int feature_word_description(char str[], FeatureWordInfo *f, uint32_t 
bit)
+{
+int ret;
+
+assert(f->type == CPUID_FEATURE_WORD ||
+f->type == MSR_FEATURE_WORD);
+switch (f->type) {
+case CPUID_FEATURE_WORD:
+{
+const char *reg = get_register_name_32(f->cpuid.reg);
+assert(reg);
+ret = snprintf(str, FEATURE_WORD_DESCPTION_LEN,
+"CPUID.%02XH:%s%s%s [bit %d]",
+f->cpuid.eax, reg,
+f->feat_names[bit] ? "." : "",
+f->feat_names[bit] ? f->feat_names[bit] : "", bit);
+break;
+}
+case MSR_FEATURE_WORD:
+ret = snprintf(str, FEATURE_WORD_DESCPTION_LEN,
+"MSR(%xH).%s [bit %d]",
+f->msr.index,
+f->feat_names[bit] ? f->feat_names[bit] : "", bit);
+break;
+}
+return ret > 0;
+}
+
 static void report_unavailable_features(FeatureWord w, uint32_t mask)
 {
 FeatureWordInfo *f = _word_info[w];
 int i;
+char feat_word_dscrp_str[FEATURE_WORD_DESCPTION_LEN];
 
 for (i = 0; i < 32; ++i) {
 if ((1UL << i) & mask) {
-const char *reg = get_register_name_32(f->cpuid_reg);
-assert(reg);
-warn_report("%s doesn't support requested feature: "
-"CPUID.%02XH:%s%s%s [bit %d]",
+feature_word_description(feat_word_dscrp_str, f, i);
+warn_report("%s doesn't support requested feature: %s",
 accel_uses_host_cpuid() ? "host" : "TCG",
-f->cpuid_eax, reg,
-f->feat_names[i] ? "." : "",
-f->feat_names[i] ? f->feat_names[i] : "", i);
+feat_word_dscrp_str);
 }
 }
 }
@@ -3276,17 +3305,17 @@ static void x86_cpu_get_feature_words(Object *obj, 
Visitor *v,
 {
 uint32_t *array = (uint32_t *)opaque;
 FeatureWord w;
-X86CPUFeatureWordInfo word_infos[FEATURE_WORDS] = { };
-X86CPUFeatureWordInfoList list_entries[FEATURE_WORDS] = { };
+X86CPUFeatureWordInfo word_infos[FEATURE_WORDS_NUM_CPUID] = { };
+X86CPUFeatureWordInfoList list_entries[FEATURE_WORDS_NUM_CPUID] = { };
 X86CPUFeatureWordInfoList *list = NULL;
 
-for (w = 0; w < FEATURE_WORDS; w++) {
+for (w = 0; w < FEATURE_WORDS_NUM_CPUID; w++) {
 FeatureWordInfo *wi = _word_info[w];
 X86CPUFeatureWordInfo *qwi = _infos[w];
-qwi->cpuid_input_eax = wi->cpuid_eax;
-qwi->has_cpuid_input_ecx = wi->cpuid_needs_ecx;
-qwi->cpuid_input_ecx = wi->cpuid_ecx;
-qwi->cpuid_register = x86_reg_info_32[wi->cpuid_reg].qapi_enum;
+qwi->cpuid_input_eax = wi->cpuid.eax;
+qwi->has_cpuid_input_ecx = wi->cpuid.needs_ecx;
+qwi->cpuid_input_ecx = wi->cpuid.ecx;
+qwi->cpuid_register = x86_reg_info_32[wi->cpuid.reg].qapi_enum;
 qwi->features = array[w];
 
 /* List will be in reverse order, but order shouldn't matter */
@@ -3659,12 +3688,20 @@ static uint32_t 
x86_cpu_get_supported_feature_word(FeatureWord w,
bool migratable_only)
 {
 FeatureWordInfo *wi = _word_info[w];
-uint32_t r;
+uint32_t r = 0;
 
 if (kvm_enabled()) {
-r = kvm_arch_get_supported_cpuid(kvm_state, wi->cpuid_eax,
-wi->cpuid_ecx,
-wi->cpuid_reg);
+switch (wi->type) {
+case CPUID_FEATURE_WORD:
+r = kvm_arch_get_supported_cpuid(kvm_state, wi->cpuid.eax,
+wi->cpuid.ecx,
+   

[Qemu-devel] [PATCH v1 0/3] x86: QEMU side support on MSR based features

2018-08-09 Thread Robert Hoo
KVM side has added the framework (kvm.git:d1d93fa90) to support MSR based 
features.
Here is the QEMU part, including data structure changes/expanding, referring
functions changes, and the implementations on 
KVM_GET_MSR_FEATURE_INDEX_LIST and KVM_GET_MSRS system ioctl.

Robert Hoo (3):
  x86: Data structure changes to support MSR based features
  kvm: Add support to KVM_GET_MSR_FEATURE_INDEX_LIST and KVM_GET_MSRS
system ioctl
  Change other funcitons referring to feature_word_info[]

 include/sysemu/kvm.h |   2 +
 target/i386/cpu.c| 209 +--
 target/i386/cpu.h|   5 ++
 target/i386/kvm.c|  78 +++
 4 files changed, 236 insertions(+), 58 deletions(-)

-- 
1.8.3.1




[Qemu-devel] [PATCH v1 2/3] kvm: Add support to KVM_GET_MSR_FEATURE_INDEX_LIST and KVM_GET_MSRS system ioctl

2018-08-09 Thread Robert Hoo
Add kvm_get_supported_feature_msrs() to get supported MSR feature index list.
Add kvm_arch_get_supported_msr_feature() to get each MSR features value.

kvm_get_supported_feature_msrs() is called in kvm_arch_init().
kvm_arch_get_supported_msr_feature() is called by
x86_cpu_get_supported_feature_word().

Signed-off-by: Robert Hoo 
---
 include/sysemu/kvm.h |  2 ++
 target/i386/kvm.c| 78 
 2 files changed, 80 insertions(+)

diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h
index 0b64b8e..0cf792f 100644
--- a/include/sysemu/kvm.h
+++ b/include/sysemu/kvm.h
@@ -463,6 +463,8 @@ int kvm_vm_check_extension(KVMState *s, unsigned int 
extension);
 
 uint32_t kvm_arch_get_supported_cpuid(KVMState *env, uint32_t function,
   uint32_t index, int reg);
+uint32_t kvm_arch_get_supported_msr_feature (KVMState *s, uint32_t index);
+
 
 void kvm_set_sigmask_len(KVMState *s, unsigned int sigmask_len);
 
diff --git a/target/i386/kvm.c b/target/i386/kvm.c
index 9313602..7268ab7 100644
--- a/target/i386/kvm.c
+++ b/target/i386/kvm.c
@@ -107,6 +107,7 @@ static int has_pit_state2;
 static bool has_msr_mcg_ext_ctl;
 
 static struct kvm_cpuid2 *cpuid_cache;
+static struct kvm_msr_list *kvm_feature_msrs;
 
 int kvm_has_pit_state2(void)
 {
@@ -420,6 +421,41 @@ uint32_t kvm_arch_get_supported_cpuid(KVMState *s, 
uint32_t function,
 return ret;
 }
 
+uint32_t kvm_arch_get_supported_msr_feature (KVMState *s, uint32_t index)
+{
+struct {
+struct kvm_msrs info;
+struct kvm_msr_entry entries[1];
+} msr_data;
+uint32_t ret;
+
+/*Check if the requested feature MSR is supported*/
+int i;
+for(i = 0; i < kvm_feature_msrs->nmsrs; i++)
+{
+if(index == kvm_feature_msrs->indices[i])
+break;
+}
+if(i >= kvm_feature_msrs->nmsrs) {
+fprintf(stderr, "Requested MSR (index= %d) is not supported.\n", 
index);
+return 0;
+}
+
+msr_data.info.nmsrs = 1;
+msr_data.entries[0].index = index;
+
+ret = kvm_ioctl(s, KVM_GET_MSRS, _data);
+
+if (ret != 1){
+fprintf(stderr, "KVM get MSR (index=0x%x) feature failed, %s\n",
+index, strerror(-ret));
+exit(1);
+}
+
+return msr_data.entries[0].data;
+}
+
+
 typedef struct HWPoisonPage {
 ram_addr_t ram_addr;
 QLIST_ENTRY(HWPoisonPage) list;
@@ -1238,7 +1274,44 @@ void kvm_arch_do_init_vcpu(X86CPU *cpu)
 env->mp_state = KVM_MP_STATE_INIT_RECEIVED;
 }
 }
+static int kvm_get_supported_feature_msrs(KVMState *s)
+{
+static int kvm_supported_feature_msrs;
+int ret = 0;
+
+if(kvm_supported_feature_msrs == 0){
+struct kvm_msr_list msr_list;
+
+kvm_supported_feature_msrs++;
+
+msr_list.nmsrs = 0;
+ret = kvm_ioctl(s, KVM_GET_MSR_FEATURE_INDEX_LIST, _list);
+if (ret < 0 && ret != -E2BIG) {
+return ret;
+}
+
+assert(msr_list.nmsrs > 0);
+kvm_feature_msrs = (struct kvm_msr_list *) \
+g_malloc0(sizeof(msr_list) +
+ msr_list.nmsrs * sizeof(msr_list.indices[0]));
+if(kvm_feature_msrs == NULL){
+fprintf(stderr, "Failed to allocate space for KVM Feature MSRs"
+"which has %d MSRs\n", msr_list.nmsrs);
+return -1;
+}
+
+kvm_feature_msrs->nmsrs = msr_list.nmsrs;
+ret = kvm_ioctl(s, KVM_GET_MSR_FEATURE_INDEX_LIST, kvm_feature_msrs);
 
+if(ret < 0) {  /*ioctl failure*/
+fprintf(stderr, "Fetch KVM feature MSRs failed: %s\n", 
strerror(-ret));
+g_free(kvm_feature_msrs);
+return ret;
+}
+}
+
+return 0;
+}
 static int kvm_get_supported_msrs(KVMState *s)
 {
 static int kvm_supported_msrs;
@@ -1400,6 +1473,11 @@ int kvm_arch_init(MachineState *ms, KVMState *s)
 return ret;
 }
 
+ret = kvm_get_supported_feature_msrs(s);
+if (ret < 0) {
+return ret;
+}
+
 uname();
 lm_capable_kernel = strcmp(utsname.machine, "x86_64") == 0;
 
-- 
1.8.3.1




[Qemu-devel] [PATCH v1 1/3] x86: Data structure changes to support MSR based features

2018-08-09 Thread Robert Hoo
Define FeatureWordType.
Expand FeatureWordInfo to support both CPUID type feature word as well as
MSR type's.
Change feature_word_info[] accordingly.

Signed-off-by: Robert Hoo 
---
 target/i386/cpu.c | 133 ++
 target/i386/cpu.h |   5 ++
 2 files changed, 99 insertions(+), 39 deletions(-)

diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index ba7abe5..77e1859 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -770,17 +770,36 @@ static void x86_cpu_vendor_words2str(char *dst, uint32_t 
vendor1,
   /* missing:
   CPUID_XSAVE_XSAVEC, CPUID_XSAVE_XSAVES */
 
+typedef enum FeatureWordType {
+   CPUID_FEATURE_WORD,
+   MSR_FEATURE_WORD,
+}FeatureWordType;
+
 typedef struct FeatureWordInfo {
-/* feature flags names are taken from "Intel Processor Identification and
+FeatureWordType type;
+   /* feature flags names are taken from "Intel Processor Identification and
  * the CPUID Instruction" and AMD's "CPUID Specification".
  * In cases of disagreement between feature naming conventions,
  * aliases may be added.
  */
 const char *feat_names[32];
-uint32_t cpuid_eax;   /* Input EAX for CPUID */
-bool cpuid_needs_ecx; /* CPUID instruction uses ECX as input */
-uint32_t cpuid_ecx;   /* Input ECX value for CPUID */
-int cpuid_reg;/* output register (R_* constant) */
+union {
+/* If type==CPUID_FEATURE_WORD */
+struct {
+uint32_t eax;   /* Input EAX for CPUID */
+bool needs_ecx; /* CPUID instruction uses ECX as input */
+uint32_t ecx;   /* Input ECX value for CPUID */
+int reg;/* output register (R_* constant) */
+} cpuid;
+/* If type==MSR_FEATURE_WORD */
+struct {
+uint32_t index;
+struct {   /*CPUID that enumerate this MSR*/
+FeatureWord cpuid_class;
+uint32_tcpuid_flag;
+} cpuid_dep;
+} msr;
+};
 uint32_t tcg_features; /* Feature flags supported by TCG */
 uint32_t unmigratable_flags; /* Feature flags known to be unmigratable */
 uint32_t migratable_flags; /* Feature flags known to be migratable */
@@ -790,6 +809,7 @@ typedef struct FeatureWordInfo {
 
 static FeatureWordInfo feature_word_info[FEATURE_WORDS] = {
 [FEAT_1_EDX] = {
+.type = CPUID_FEATURE_WORD,
 .feat_names = {
 "fpu", "vme", "de", "pse",
 "tsc", "msr", "pae", "mce",
@@ -800,10 +820,11 @@ static FeatureWordInfo feature_word_info[FEATURE_WORDS] = 
{
 "fxsr", "sse", "sse2", "ss",
 "ht" /* Intel htt */, "tm", "ia64", "pbe",
 },
-.cpuid_eax = 1, .cpuid_reg = R_EDX,
+.cpuid = {.eax = 1, .reg = R_EDX, },
 .tcg_features = TCG_FEATURES,
 },
 [FEAT_1_ECX] = {
+.type = CPUID_FEATURE_WORD,
 .feat_names = {
 "pni" /* Intel,AMD sse3 */, "pclmulqdq", "dtes64", "monitor",
 "ds-cpl", "vmx", "smx", "est",
@@ -814,7 +835,7 @@ static FeatureWordInfo feature_word_info[FEATURE_WORDS] = {
 "tsc-deadline", "aes", "xsave", NULL /* osxsave */,
 "avx", "f16c", "rdrand", "hypervisor",
 },
-.cpuid_eax = 1, .cpuid_reg = R_ECX,
+.cpuid = { .eax = 1, .reg = R_ECX, },
 .tcg_features = TCG_EXT_FEATURES,
 },
 /* Feature names that are already defined on feature_name[] but
@@ -823,6 +844,7 @@ static FeatureWordInfo feature_word_info[FEATURE_WORDS] = {
  * to features[FEAT_8000_0001_EDX] if and only if CPU vendor is AMD.
  */
 [FEAT_8000_0001_EDX] = {
+.type = CPUID_FEATURE_WORD,
 .feat_names = {
 NULL /* fpu */, NULL /* vme */, NULL /* de */, NULL /* pse */,
 NULL /* tsc */, NULL /* msr */, NULL /* pae */, NULL /* mce */,
@@ -833,10 +855,11 @@ static FeatureWordInfo feature_word_info[FEATURE_WORDS] = 
{
 NULL /* fxsr */, "fxsr-opt", "pdpe1gb", "rdtscp",
 NULL, "lm", "3dnowext", "3dnow",
 },
-.cpuid_eax = 0x8001, .cpuid_reg = R_EDX,
+.cpuid = { .eax = 0x8001, .reg = R_EDX, },
 .tcg_features = TCG_EXT2_FEATURES,
 },
 [FEAT_8000_0001_ECX] = {
+.type = CPUID_FEATURE_WORD,
 .feat_names = {
 "lahf-lm", "cmp-legacy", "svm", "extapic",
 "cr8legacy", "abm", "sse4a", "misalignsse",
@@ -847,10 +870,11 @@ static FeatureWordInfo feat

Re: [Qemu-devel] [PATCH v2 1/5] i386: Add support for IA32_PRED_CMD and IA32_ARCH_CAPABILITIES MSRs

2018-07-13 Thread Robert Hoo
On Fri, 2018-07-13 at 10:11 -0400, konrad.w...@oracle.com wrote:
> (Apologies if this comes out as HTML, using Thunderbird instead of mutt 
> here)..
> 
> > +uint64_t pred_cmd;
> > +uint64_t arch_capabilities;
> 
> Could this be 'arch_cap' ?
> 
> >   
> >   /* End of state preserved by INIT (dummy marker).  */
> >   struct {} end_init_save;
> > diff --git a/target/i386/kvm.c b/target/i386/kvm.c
> > index 2d174f3..3aab182 100644
> > --- a/target/i386/kvm.c
> > +++ b/target/i386/kvm.c
> > @@ -93,6 +93,8 @@ static bool has_msr_hv_reenlightenment;
> >   static bool has_msr_xss;
> >   static bool has_msr_spec_ctrl;
> >   static bool has_msr_virt_ssbd;
> > +static bool has_msr_pred_cmd;
> > +static bool has_msr_arch_capabilities;
> 
> Ditto here?
> 

Per Paolo and Eduardo's comments, the 2 fields/variables are gone in new
versions.





Re: [Qemu-devel] [PATCH v2 2/5] i386: Add CPUID bit and feature words for IA32_ARCH_CAPABILITIES MSR

2018-07-12 Thread Robert Hoo
On Tue, 2018-07-03 at 08:00 -0300, Eduardo Habkost wrote:
> On Tue, Jul 03, 2018 at 03:35:13PM +0800, Robert Hoo wrote:
> > On Thu, 2018-06-28 at 15:28 -0300, Eduardo Habkost wrote:
> > > On Wed, Jun 27, 2018 at 07:27:21PM +0800, Robert Hoo wrote:
> > > > Support of IA32_PRED_CMD MSR already be enumerated by same CPUID bit as
> > > > SPEC_CTRL.
> > > > 
> > > > Signed-off-by: Robert Hoo 
> > > 
> > > Based on kernel commit 1eaafe91, it looks like we must always set
> > > IA32_ARCH_CAPABILITIES.RSBA[bit 2] unless we're really sure the
> > > VM will not be migrated to a vulnerable processor.
> > > 
> > > Considering this, I'd like to make "+arch-capabilities" set
> > > IA32_ARCH_CAPABILITIES.RSBA by default, unless RSBA is explicitly
> > > disabled by management software.
> > > 
> > Agree. But this seems beyond Icelake CPU model scope. How about I think
> > about this carefully and compose another patch (set) for this?
> 
> This plan makes sense to me, as I don't want to make this
> decision block IceLake from being in QEMU 3.0.
> 
> However, enabling CPUID_7_0_EDX_ARCH_CAPABILITIES in IceLake but
> setting the MSR to 0 seems pointless.
> 
> I think we should add IceLake without
> CPUID_7_0_EDX_ARCH_CAPABILITIES first, and later (after deciding
> on a reasonable default value for MSR_IA32_ARCH_CAPABILITIES),
> enable the CPUID bit on IceLake (hopefully in time for QEMU 3.0).
> 
> 
> > And you'd like to set  IA32_ARCH_CAPABILITIES.RSBA by default in qemu or
> > kvm layer?
> 
> Probably we need to make this decision in QEMU.  If KVM set RSBA
> automatically on .get_msr_feature(), QEMU won't be able to
> differentiate a host with RSBA set from a host with RSBA unset.
> 
What's the default value for MSR IA32_ARCH_CAPABILITIES? is it clear
now?




[Qemu-devel] [PATCH v4 2/5] i386: Add CPUID bit and feature words for IA32_ARCH_CAPABILITIES MSR

2018-07-05 Thread Robert Hoo
Support of IA32_PRED_CMD MSR already be enumerated by same CPUID bit as
SPEC_CTRL.

At present, mark CPUID_7_0_EDX_ARCH_CAPABILITIES unmigratable, per Paolo's
comment.

Signed-off-by: Robert Hoo 
---
 target/i386/cpu.c | 3 ++-
 target/i386/cpu.h | 1 +
 2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index b0b87c3..878b1ce 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -1000,12 +1000,13 @@ static FeatureWordInfo feature_word_info[FEATURE_WORDS] 
= {
 NULL, NULL, NULL, NULL,
 NULL, NULL, NULL, NULL,
 NULL, NULL, "spec-ctrl", NULL,
-NULL, NULL, NULL, "ssbd",
+NULL, "arch-capabilities", NULL, "ssbd",
 },
 .cpuid_eax = 7,
 .cpuid_needs_ecx = true, .cpuid_ecx = 0,
 .cpuid_reg = R_EDX,
 .tcg_features = TCG_7_0_EDX_FEATURES,
+.unmigratable_flags = CPUID_7_0_EDX_ARCH_CAPABILITIES,
 },
 [FEAT_8000_0007_EDX] = {
 .feat_names = {
diff --git a/target/i386/cpu.h b/target/i386/cpu.h
index ae97005..c2b297b 100644
--- a/target/i386/cpu.h
+++ b/target/i386/cpu.h
@@ -690,6 +690,7 @@ typedef uint32_t FeatureWordArray[FEATURE_WORDS];
 #define CPUID_7_0_EDX_AVX512_4VNNIW (1U << 2) /* AVX512 Neural Network 
Instructions */
 #define CPUID_7_0_EDX_AVX512_4FMAPS (1U << 3) /* AVX512 Multiply Accumulation 
Single Precision */
 #define CPUID_7_0_EDX_SPEC_CTRL (1U << 26) /* Speculation Control */
+#define CPUID_7_0_EDX_ARCH_CAPABILITIES (1U << 29)  /*Arch Capabilities*/
 #define CPUID_7_0_EDX_SPEC_CTRL_SSBD  (1U << 31) /* Speculative Store Bypass 
Disable */
 
 #define CPUID_8000_0008_EBX_IBPB(1U << 12) /* Indirect Branch Prediction 
Barrier */
-- 
1.8.3.1




[Qemu-devel] [PATCH v4 0/5] Add Icelake CPU model

2018-07-05 Thread Robert Hoo
This patch set defines the new guest CPU models of Icelake.

The first patch defines new indices for IA32_PRED_CMD MSR (IBPB) and 
IA32_ARCH_CAPABILITIES MSR.
Other patches add CPUID bits feature words for new features, like PCONFIG,
WBNOINVD. The final patch defines Icelake-{Server,Client} CPU models.

Changelog:
v4
At present, mark CPUID_7_0_EDX_ARCH_CAPABILITIES unmigratable.
v3
Remove ARCH_CAPABILITIES from Icelake CPU model, at present. Going to
compose a separate patch to do 1) qemu set ARCH_CAPABILITES MSR with some 
default
value. 2) expand current CPU feature expression frame work from CPUID features
only to MSR bit included as well.
Fix some patch format error and update some trivial patch descrptions.
v2
Per Paolo's comment, remove unnecessary CPU vmstate check for 
write/read only
IA32_PRED_CMD and IA32_ARCH_CAPABILITIES MSRs.

Robert Hoo (5):
  i386: Add new MSR indices for IA32_PRED_CMD and IA32_ARCH_CAPABILITIES
  i386: Add CPUID bit and feature words for IA32_ARCH_CAPABILITIES MSR
  i386: Add CPUID bit for PCONFIG
  i386: Add CPUID bit for WBNOINVD
  i386: Add new CPU model Icelake-{Server,Client}

 target/i386/cpu.c | 122 --
 target/i386/cpu.h |   6 +++
 2 files changed, 125 insertions(+), 3 deletions(-)

-- 
1.8.3.1




[Qemu-devel] [PATCH v4 5/5] i386: Add new CPU model Icelake-{Server, Client}

2018-07-05 Thread Robert Hoo
New CPU models mostly inherit features from ancestor Skylake, while addin new
features: UMIP, New Instructions ( PCONIFIG (server only), WBNOINVD,
AVX512_VBMI2, GFNI, AVX512_VNNI, VPCLMULQDQ, VAES, AVX512_BITALG),
Intel PT and 5-level paging (Server only). As well as
IA32_PRED_CMD, SSBD support for speculative execution
side channel mitigations.

Note:
For 5-level paging, Guest physical address width can be configured, with
parameter "phys-bits". Unless explicitly specified, we still use its default
value, even for Icelake-Server cpu model.
At present, hold on expose IA32_ARCH_CAPABILITIES to guest, as 1) This MSR
actually presents more than 1 'feature', maintainers are considering expanding 
current
features presentation of only CPUIDs to MSR bits; 2) a reasonable default value
for MSR_IA32_ARCH_CAPABILITIES needs to settled first. These 2 are actully
beyond Icelake CPU model itself but fundamental. So split these work apart
and do it later.
https://lists.gnu.org/archive/html/qemu-devel/2018-07/msg00774.html
https://lists.gnu.org/archive/html/qemu-devel/2018-07/msg00796.html

Signed-off-by: Robert Hoo 
---
 target/i386/cpu.c | 115 ++
 1 file changed, 115 insertions(+)

diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index 8de15cb..0ec6ced 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -2381,6 +2381,121 @@ static X86CPUDefinition builtin_x86_defs[] = {
 .model_id = "Intel Xeon Processor (Skylake, IBRS)",
 },
 {
+.name = "Icelake-Client",
+.level = 0xd,
+.vendor = CPUID_VENDOR_INTEL,
+.family = 6,
+.model = 126,
+.stepping = 0,
+.features[FEAT_1_EDX] =
+CPUID_VME | CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
+CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
+CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
+CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
+CPUID_DE | CPUID_FP87,
+.features[FEAT_1_ECX] =
+CPUID_EXT_AVX | CPUID_EXT_XSAVE | CPUID_EXT_AES |
+CPUID_EXT_POPCNT | CPUID_EXT_X2APIC | CPUID_EXT_SSE42 |
+CPUID_EXT_SSE41 | CPUID_EXT_CX16 | CPUID_EXT_SSSE3 |
+CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSE3 |
+CPUID_EXT_TSC_DEADLINE_TIMER | CPUID_EXT_FMA | CPUID_EXT_MOVBE |
+CPUID_EXT_PCID | CPUID_EXT_F16C | CPUID_EXT_RDRAND,
+.features[FEAT_8000_0001_EDX] =
+CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_NX |
+CPUID_EXT2_SYSCALL,
+.features[FEAT_8000_0001_ECX] =
+CPUID_EXT3_ABM | CPUID_EXT3_LAHF_LM | CPUID_EXT3_3DNOWPREFETCH,
+.features[FEAT_8000_0008_EBX] =
+CPUID_8000_0008_EBX_WBNOINVD,
+.features[FEAT_7_0_EBX] =
+CPUID_7_0_EBX_FSGSBASE | CPUID_7_0_EBX_BMI1 |
+CPUID_7_0_EBX_HLE | CPUID_7_0_EBX_AVX2 | CPUID_7_0_EBX_SMEP |
+CPUID_7_0_EBX_BMI2 | CPUID_7_0_EBX_ERMS | CPUID_7_0_EBX_INVPCID |
+CPUID_7_0_EBX_RTM | CPUID_7_0_EBX_RDSEED | CPUID_7_0_EBX_ADX |
+CPUID_7_0_EBX_SMAP | CPUID_7_0_EBX_MPX | CPUID_7_0_EBX_INTEL_PT,
+.features[FEAT_7_0_ECX] =
+CPUID_7_0_ECX_VBMI | CPUID_7_0_ECX_UMIP | CPUID_7_0_ECX_PKU |
+CPUID_7_0_ECX_OSPKE | CPUID_7_0_ECX_VBMI2 | CPUID_7_0_ECX_GFNI |
+CPUID_7_0_ECX_VAES | CPUID_7_0_ECX_VPCLMULQDQ |
+CPUID_7_0_ECX_AVX512VNNI | CPUID_7_0_ECX_AVX512BITALG |
+CPUID_7_0_ECX_AVX512_VPOPCNTDQ,
+.features[FEAT_7_0_EDX] =
+CPUID_7_0_EDX_SPEC_CTRL | CPUID_7_0_EDX_SPEC_CTRL_SSBD,
+/* Missing: XSAVES (not supported by some Linux versions,
+* including v4.1 to v4.12).
+* KVM doesn't yet expose any XSAVES state save component,
+* and the only one defined in Skylake (processor tracing)
+* probably will block migration anyway.
+*/
+.features[FEAT_XSAVE] =
+CPUID_XSAVE_XSAVEOPT | CPUID_XSAVE_XSAVEC |
+CPUID_XSAVE_XGETBV1,
+.features[FEAT_6_EAX] =
+CPUID_6_EAX_ARAT,
+.xlevel = 0x8008,
+.model_id = "Intel Core Processor (Icelake)",
+},
+{
+.name = "Icelake-Server",
+.level = 0xd,
+.vendor = CPUID_VENDOR_INTEL,
+.family = 6,
+.model = 134,
+.stepping = 0,
+.features[FEAT_1_EDX] =
+CPUID_VME | CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
+CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
+CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
+CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
+CPUID_DE | CPUID_FP87,
+.features[FEAT_1_ECX] =
+CPUID_EXT_AVX | CPUID_EXT_XSA

[Qemu-devel] [PATCH v4 3/5] i386: Add CPUID bit for PCONFIG

2018-07-05 Thread Robert Hoo
PCONFIG: Platform configuration, enumerated by CPUID.(EAX=07H, ECX=0):
EDX[bit18].

Signed-off-by: Robert Hoo 
---
 target/i386/cpu.c | 2 +-
 target/i386/cpu.h | 1 +
 2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index 878b1ce..b83d0a9 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -997,7 +997,7 @@ static FeatureWordInfo feature_word_info[FEATURE_WORDS] = {
 NULL, NULL, NULL, NULL,
 NULL, NULL, NULL, NULL,
 NULL, NULL, NULL, NULL,
-NULL, NULL, NULL, NULL,
+NULL, NULL, "pconfig", NULL,
 NULL, NULL, NULL, NULL,
 NULL, NULL, "spec-ctrl", NULL,
 NULL, "arch-capabilities", NULL, "ssbd",
diff --git a/target/i386/cpu.h b/target/i386/cpu.h
index c2b297b..12a7e6c 100644
--- a/target/i386/cpu.h
+++ b/target/i386/cpu.h
@@ -689,6 +689,7 @@ typedef uint32_t FeatureWordArray[FEATURE_WORDS];
 
 #define CPUID_7_0_EDX_AVX512_4VNNIW (1U << 2) /* AVX512 Neural Network 
Instructions */
 #define CPUID_7_0_EDX_AVX512_4FMAPS (1U << 3) /* AVX512 Multiply Accumulation 
Single Precision */
+#define CPUID_7_0_EDX_PCONFIG (1U << 18)   /* Platform Configuration */
 #define CPUID_7_0_EDX_SPEC_CTRL (1U << 26) /* Speculation Control */
 #define CPUID_7_0_EDX_ARCH_CAPABILITIES (1U << 29)  /*Arch Capabilities*/
 #define CPUID_7_0_EDX_SPEC_CTRL_SSBD  (1U << 31) /* Speculative Store Bypass 
Disable */
-- 
1.8.3.1




[Qemu-devel] [PATCH v4 1/5] i386: Add new MSR indices for IA32_PRED_CMD and IA32_ARCH_CAPABILITIES

2018-07-05 Thread Robert Hoo
IA32_PRED_CMD MSR gives software a way to issue commands that affect the state
of indirect branch predictors. Enumerated by CPUID.(EAX=7H,ECX=0):EDX[26].
IA32_ARCH_CAPABILITIES MSR enumerates architectural features of RDCL_NO and
IBRS_ALL. Enumerated by CPUID.(EAX=07H, ECX=0):EDX[29].

https://software.intel.com/sites/default/files/managed/c5/63/336996-Speculative-Execution-Side-Channel-Mitigations.pdf

Signed-off-by: Robert Hoo 
---
 target/i386/cpu.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/target/i386/cpu.h b/target/i386/cpu.h
index 2c5a0d9..ae97005 100644
--- a/target/i386/cpu.h
+++ b/target/i386/cpu.h
@@ -354,6 +354,8 @@ typedef enum X86Seg {
 #define MSR_TSC_ADJUST  0x003b
 #define MSR_IA32_SPEC_CTRL  0x48
 #define MSR_VIRT_SSBD   0xc001011f
+#define MSR_IA32_PRED_CMD   0x49
+#define MSR_IA32_ARCH_CAPABILITIES  0x10a
 #define MSR_IA32_TSCDEADLINE0x6e0
 
 #define FEATURE_CONTROL_LOCKED(1<<0)
-- 
1.8.3.1




[Qemu-devel] [PATCH v4 4/5] i386: Add CPUID bit for WBNOINVD

2018-07-05 Thread Robert Hoo
WBNOINVD: Write back and do not invalidate cache, enumerated by
CPUID.(EAX=8008H, ECX=0):EBX[bit 9].

Signed-off-by: Robert Hoo 
---
 target/i386/cpu.c | 2 +-
 target/i386/cpu.h | 2 ++
 2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index b83d0a9..8de15cb 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -1028,7 +1028,7 @@ static FeatureWordInfo feature_word_info[FEATURE_WORDS] = 
{
 .feat_names = {
 NULL, NULL, NULL, NULL,
 NULL, NULL, NULL, NULL,
-NULL, NULL, NULL, NULL,
+NULL, "wbnoinvd", NULL, NULL,
 "ibpb", NULL, NULL, NULL,
 NULL, NULL, NULL, NULL,
 NULL, NULL, NULL, NULL,
diff --git a/target/i386/cpu.h b/target/i386/cpu.h
index 12a7e6c..265f428 100644
--- a/target/i386/cpu.h
+++ b/target/i386/cpu.h
@@ -694,6 +694,8 @@ typedef uint32_t FeatureWordArray[FEATURE_WORDS];
 #define CPUID_7_0_EDX_ARCH_CAPABILITIES (1U << 29)  /*Arch Capabilities*/
 #define CPUID_7_0_EDX_SPEC_CTRL_SSBD  (1U << 31) /* Speculative Store Bypass 
Disable */
 
+#define CPUID_8000_0008_EBX_WBNOINVD  (1U << 9)  /* Write back and
+ 
do not invalidate cache */
 #define CPUID_8000_0008_EBX_IBPB(1U << 12) /* Indirect Branch Prediction 
Barrier */
 
 #define CPUID_XSAVE_XSAVEOPT   (1U << 0)
-- 
1.8.3.1




[Qemu-devel] [PATCH v3 0/5] Add Icelake CPU model

2018-07-04 Thread Robert Hoo
This patch set defines the new guest CPU models of Icelake.

The first patch defines new indices for IA32_PRED_CMD MSR (IBPB) and 
IA32_ARCH_CAPABILITIES MSR.
Other patches add CPUID bits feature words for new features, like PCONFIG,
WBNOINVD. The final patch defines Icelake-{Server,Client} CPU models.

Changelog:
v3
Remove ARCH_CAPABILITIES from Icelake CPU model, at present. Going to
compose a separate patch to do 1) qemu set ARCH_CAPABILITES MSR with some 
default
value. 2) expand current CPU feature expression frame work from CPUID features
only to MSR bit included as well.
Fix some patch format error and update some trivial patch descrptions.
v2
Per Paolo's comment, remove unnecessary CPU vmstate check for 
write/read only
IA32_PRED_CMD and IA32_ARCH_CAPABILITIES MSRs.

Robert Hoo (5):
  i386: Add new MSR indices for IA32_PRED_CMD and IA32_ARCH_CAPABILITIES
  i386: Add CPUID bit and feature words for IA32_ARCH_CAPABILITIES MSR
  i386: Add CPUID bit for PCONFIG
  i386: Add CPUID bit for WBNOINVD
  i386: Add new CPU model Icelake-{Server,Client}

 target/i386/cpu.c | 121 --
 target/i386/cpu.h |   6 +++
 2 files changed, 124 insertions(+), 3 deletions(-)

-- 
1.8.3.1




[Qemu-devel] [PATCH v3 1/5] i386: Add new MSR indices for IA32_PRED_CMD and IA32_ARCH_CAPABILITIES

2018-07-04 Thread Robert Hoo
IA32_PRED_CMD MSR gives software a way to issue commands that affect the state
of indirect branch predictors. Enumerated by CPUID.(EAX=7H,ECX=0):EDX[26].
IA32_ARCH_CAPABILITIES MSR enumerates architectural features of RDCL_NO,
IBRS_ALL, RSBA, SSB_NO. Enumerated by CPUID.(EAX=07H, ECX=0):EDX[29].

https://software.intel.com/sites/default/files/managed/c5/63/336996-Speculative-Execution-Side-Channel-Mitigations.pdf

Signed-off-by: Robert Hoo 
---
 target/i386/cpu.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/target/i386/cpu.h b/target/i386/cpu.h
index 2c5a0d9..ae97005 100644
--- a/target/i386/cpu.h
+++ b/target/i386/cpu.h
@@ -354,6 +354,8 @@ typedef enum X86Seg {
 #define MSR_TSC_ADJUST  0x003b
 #define MSR_IA32_SPEC_CTRL  0x48
 #define MSR_VIRT_SSBD   0xc001011f
+#define MSR_IA32_PRED_CMD   0x49
+#define MSR_IA32_ARCH_CAPABILITIES  0x10a
 #define MSR_IA32_TSCDEADLINE0x6e0
 
 #define FEATURE_CONTROL_LOCKED(1<<0)
-- 
1.8.3.1




[Qemu-devel] [PATCH v3 5/5] i386: Add new CPU model Icelake-{Server, Client}

2018-07-04 Thread Robert Hoo
New CPU models mostly inherit features from ancestor Skylake, while addin new
features: UMIP, New Instructions ( PCONIFIG (server only), WBNOINVD,
AVX512_VBMI2, GFNI, AVX512_VNNI, VPCLMULQDQ, VAES, AVX512_BITALG),
Intel PT and 5-level paging (Server only). As well as
IA32_PRED_CMD, SSBD support for speculative execution
side channel mitigations.

Note:
For 5-level paging, Guest physical address width can be configured, with
parameter "phys-bits". Unless explicitly specified, we still use its default
value, even for Icelake-Server cpu model.
At present, hold on expose IA32_ARCH_CAPABILITIES to guest, as 1) This MSR
actually presents more than 1 'feature', maintainers are considering expanding 
current
features presentation of only CPUIDs to MSR bits; 2) a reasonable default value
for MSR_IA32_ARCH_CAPABILITIES needs to settled first. These 2 are actully
beyond Icelake CPU model itself but fundamental. So split these work apart
and do it later.
https://lists.gnu.org/archive/html/qemu-devel/2018-07/msg00774.html
https://lists.gnu.org/archive/html/qemu-devel/2018-07/msg00796.html

Signed-off-by: Robert Hoo 
---
 target/i386/cpu.c | 115 ++
 1 file changed, 115 insertions(+)

diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index 9ad3f93..924fafd 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -2380,6 +2380,121 @@ static X86CPUDefinition builtin_x86_defs[] = {
 .model_id = "Intel Xeon Processor (Skylake, IBRS)",
 },
 {
+.name = "Icelake-Client",
+.level = 0xd,
+.vendor = CPUID_VENDOR_INTEL,
+.family = 6,
+.model = 126,
+.stepping = 0,
+.features[FEAT_1_EDX] =
+CPUID_VME | CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
+CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
+CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
+CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
+CPUID_DE | CPUID_FP87,
+.features[FEAT_1_ECX] =
+CPUID_EXT_AVX | CPUID_EXT_XSAVE | CPUID_EXT_AES |
+CPUID_EXT_POPCNT | CPUID_EXT_X2APIC | CPUID_EXT_SSE42 |
+CPUID_EXT_SSE41 | CPUID_EXT_CX16 | CPUID_EXT_SSSE3 |
+CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSE3 |
+CPUID_EXT_TSC_DEADLINE_TIMER | CPUID_EXT_FMA | CPUID_EXT_MOVBE |
+CPUID_EXT_PCID | CPUID_EXT_F16C | CPUID_EXT_RDRAND,
+.features[FEAT_8000_0001_EDX] =
+CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_NX |
+CPUID_EXT2_SYSCALL,
+.features[FEAT_8000_0001_ECX] =
+CPUID_EXT3_ABM | CPUID_EXT3_LAHF_LM | CPUID_EXT3_3DNOWPREFETCH,
+.features[FEAT_8000_0008_EBX] =
+CPUID_8000_0008_EBX_WBNOINVD,
+.features[FEAT_7_0_EBX] =
+CPUID_7_0_EBX_FSGSBASE | CPUID_7_0_EBX_BMI1 |
+CPUID_7_0_EBX_HLE | CPUID_7_0_EBX_AVX2 | CPUID_7_0_EBX_SMEP |
+CPUID_7_0_EBX_BMI2 | CPUID_7_0_EBX_ERMS | CPUID_7_0_EBX_INVPCID |
+CPUID_7_0_EBX_RTM | CPUID_7_0_EBX_RDSEED | CPUID_7_0_EBX_ADX |
+CPUID_7_0_EBX_SMAP | CPUID_7_0_EBX_MPX | CPUID_7_0_EBX_INTEL_PT,
+.features[FEAT_7_0_ECX] =
+CPUID_7_0_ECX_VBMI | CPUID_7_0_ECX_UMIP | CPUID_7_0_ECX_PKU |
+CPUID_7_0_ECX_OSPKE | CPUID_7_0_ECX_VBMI2 | CPUID_7_0_ECX_GFNI |
+CPUID_7_0_ECX_VAES | CPUID_7_0_ECX_VPCLMULQDQ |
+CPUID_7_0_ECX_AVX512VNNI | CPUID_7_0_ECX_AVX512BITALG |
+CPUID_7_0_ECX_AVX512_VPOPCNTDQ,
+.features[FEAT_7_0_EDX] =
+CPUID_7_0_EDX_SPEC_CTRL | CPUID_7_0_EDX_SPEC_CTRL_SSBD,
+/* Missing: XSAVES (not supported by some Linux versions,
+* including v4.1 to v4.12).
+* KVM doesn't yet expose any XSAVES state save component,
+* and the only one defined in Skylake (processor tracing)
+* probably will block migration anyway.
+*/
+.features[FEAT_XSAVE] =
+CPUID_XSAVE_XSAVEOPT | CPUID_XSAVE_XSAVEC |
+CPUID_XSAVE_XGETBV1,
+.features[FEAT_6_EAX] =
+CPUID_6_EAX_ARAT,
+.xlevel = 0x8008,
+.model_id = "Intel Core Processor (Icelake)",
+},
+{
+.name = "Icelake-Server",
+.level = 0xd,
+.vendor = CPUID_VENDOR_INTEL,
+.family = 6,
+.model = 134,
+.stepping = 0,
+.features[FEAT_1_EDX] =
+CPUID_VME | CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
+CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
+CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
+CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
+CPUID_DE | CPUID_FP87,
+.features[FEAT_1_ECX] =
+CPUID_EXT_AVX | CPUID_EXT_XSA

[Qemu-devel] [PATCH v3 4/5] i386: Add CPUID bit for WBNOINVD

2018-07-04 Thread Robert Hoo
WBNOINVD: Write back and do not invalidate cache, enumerated by
CPUID.(EAX=8008H, ECX=0):EBX[bit 9].

Signed-off-by: Robert Hoo 
---
 target/i386/cpu.c | 2 +-
 target/i386/cpu.h | 2 ++
 2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index 9407071..9ad3f93 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -1027,7 +1027,7 @@ static FeatureWordInfo feature_word_info[FEATURE_WORDS] = 
{
 .feat_names = {
 NULL, NULL, NULL, NULL,
 NULL, NULL, NULL, NULL,
-NULL, NULL, NULL, NULL,
+NULL, "wbnoinvd", NULL, NULL,
 "ibpb", NULL, NULL, NULL,
 NULL, NULL, NULL, NULL,
 NULL, NULL, NULL, NULL,
diff --git a/target/i386/cpu.h b/target/i386/cpu.h
index 12a7e6c..265f428 100644
--- a/target/i386/cpu.h
+++ b/target/i386/cpu.h
@@ -694,6 +694,8 @@ typedef uint32_t FeatureWordArray[FEATURE_WORDS];
 #define CPUID_7_0_EDX_ARCH_CAPABILITIES (1U << 29)  /*Arch Capabilities*/
 #define CPUID_7_0_EDX_SPEC_CTRL_SSBD  (1U << 31) /* Speculative Store Bypass 
Disable */
 
+#define CPUID_8000_0008_EBX_WBNOINVD  (1U << 9)  /* Write back and
+  do not invalidate cache */
 #define CPUID_8000_0008_EBX_IBPB(1U << 12) /* Indirect Branch Prediction 
Barrier */
 
 #define CPUID_XSAVE_XSAVEOPT   (1U << 0)
-- 
1.8.3.1




[Qemu-devel] [PATCH v3 2/5] i386: Add CPUID bit and feature words for IA32_ARCH_CAPABILITIES MSR

2018-07-04 Thread Robert Hoo
Support of IA32_PRED_CMD MSR already be enumerated by same CPUID bit as
SPEC_CTRL.

Signed-off-by: Robert Hoo 
---
 target/i386/cpu.c | 2 +-
 target/i386/cpu.h | 1 +
 2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index b0b87c3..7f787ef 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -1000,7 +1000,7 @@ static FeatureWordInfo feature_word_info[FEATURE_WORDS] = 
{
 NULL, NULL, NULL, NULL,
 NULL, NULL, NULL, NULL,
 NULL, NULL, "spec-ctrl", NULL,
-NULL, NULL, NULL, "ssbd",
+NULL, "arch-capabilities", NULL, "ssbd",
 },
 .cpuid_eax = 7,
 .cpuid_needs_ecx = true, .cpuid_ecx = 0,
diff --git a/target/i386/cpu.h b/target/i386/cpu.h
index ae97005..c2b297b 100644
--- a/target/i386/cpu.h
+++ b/target/i386/cpu.h
@@ -690,6 +690,7 @@ typedef uint32_t FeatureWordArray[FEATURE_WORDS];
 #define CPUID_7_0_EDX_AVX512_4VNNIW (1U << 2) /* AVX512 Neural Network 
Instructions */
 #define CPUID_7_0_EDX_AVX512_4FMAPS (1U << 3) /* AVX512 Multiply Accumulation 
Single Precision */
 #define CPUID_7_0_EDX_SPEC_CTRL (1U << 26) /* Speculation Control */
+#define CPUID_7_0_EDX_ARCH_CAPABILITIES (1U << 29)  /*Arch Capabilities*/
 #define CPUID_7_0_EDX_SPEC_CTRL_SSBD  (1U << 31) /* Speculative Store Bypass 
Disable */
 
 #define CPUID_8000_0008_EBX_IBPB(1U << 12) /* Indirect Branch Prediction 
Barrier */
-- 
1.8.3.1




[Qemu-devel] [PATCH v3 3/5] i386: Add CPUID bit for PCONFIG

2018-07-04 Thread Robert Hoo
PCONFIG: Platform configuration, enumerated by CPUID.(EAX=07H, ECX=0):
EDX[bit18].

Signed-off-by: Robert Hoo 
---
 target/i386/cpu.c | 2 +-
 target/i386/cpu.h | 1 +
 2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index 7f787ef..9407071 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -997,7 +997,7 @@ static FeatureWordInfo feature_word_info[FEATURE_WORDS] = {
 NULL, NULL, NULL, NULL,
 NULL, NULL, NULL, NULL,
 NULL, NULL, NULL, NULL,
-NULL, NULL, NULL, NULL,
+NULL, NULL, "pconfig", NULL,
 NULL, NULL, NULL, NULL,
 NULL, NULL, "spec-ctrl", NULL,
 NULL, "arch-capabilities", NULL, "ssbd",
diff --git a/target/i386/cpu.h b/target/i386/cpu.h
index c2b297b..12a7e6c 100644
--- a/target/i386/cpu.h
+++ b/target/i386/cpu.h
@@ -689,6 +689,7 @@ typedef uint32_t FeatureWordArray[FEATURE_WORDS];
 
 #define CPUID_7_0_EDX_AVX512_4VNNIW (1U << 2) /* AVX512 Neural Network 
Instructions */
 #define CPUID_7_0_EDX_AVX512_4FMAPS (1U << 3) /* AVX512 Multiply Accumulation 
Single Precision */
+#define CPUID_7_0_EDX_PCONFIG (1U << 18)   /* Platform Configuration */
 #define CPUID_7_0_EDX_SPEC_CTRL (1U << 26) /* Speculation Control */
 #define CPUID_7_0_EDX_ARCH_CAPABILITIES (1U << 29)  /*Arch Capabilities*/
 #define CPUID_7_0_EDX_SPEC_CTRL_SSBD  (1U << 31) /* Speculative Store Bypass 
Disable */
-- 
1.8.3.1




Re: [Qemu-devel] [PATCH v2 1/5] i386: Add support for IA32_PRED_CMD and IA32_ARCH_CAPABILITIES MSRs

2018-07-04 Thread Robert Hoo
On Tue, 2018-07-03 at 15:38 +0200, Paolo Bonzini wrote:
> On 03/07/2018 13:07, Robert Hoo wrote:
> >>  FEAT_XSAVE_COMP_LO, /* CPUID[EAX=0xd,ECX=0].EAX */
> >>  FEAT_XSAVE_COMP_HI, /* CPUID[EAX=0xd,ECX=0].EDX */
> >> +FEATURE_WORDS_NUM_CPUID,
> >> +FEATURE_WORDS_FIRST_MSR = FEATURE_WORDS_NUM_CPUID,
> >> +FEAT_MSR_ARCH_CAPABILITIES = FEATURE_WORDS_FIRST_MSR,
> >>  FEATURE_WORDS,
> >> };
> >>
> >> #define FEATURE_WORDS_NUM_MSRS (FEATURE_WORDS - \
> >> FEATURE_WORDS_FIRST_MSR)
> >>
> >> Then the existing loops that use FeatureWordInfo can go up to
> >> FEATURE_WORDS_NUM_CPUID.
> > Emm... Understand your point now. It is a little risky, all references
> > to FEATURE_WORDS need to be updated carefully.
> > OK, let me try to think in this way.
> > Perhaps, I'll need to define a new 'struct FeautureWordMsrInfo' to
> > describe feature words from MSR, in parallel to current FeatureWordInfo
> > (or better rename it to FeatureWordCpuidInfo).
> 
> Yes, probably.  The plan seems fine.
> 

> > And, if I implemented ARCH_CAPABILITIES-bits features in
FeatureWord,
> > then no necessity of having it in kvm_msr_entries, right?
> 
Hi Paolo, would you confirm this? I mean your previous patch "KVM: VMX:
support MSR_IA32_ARCH_CAPABILITIES as a feature MSR" is not necessary
now?

> Paolo





<    1   2   3   >