diff mbox series

[RFC,1/2] hw/i386: -cpu model, -feature, +feature should enable feature

Message ID 20210119142207.3443123-2-david.edmondson@oracle.com (mailing list archive)
State New, archived
Headers show
Series x86 CPU feature +/- fiddling and +kvm-no-defaults | expand

Commit Message

David Edmondson Jan. 19, 2021, 2:22 p.m. UTC
"Minus" features are applied after "plus" features, so ensure that a
later "plus" feature causes an earlier "minus" feature to be removed.

This has no effect on the existing "-feature,feature=on" backward
compatibility code (which warns and turns the feature off).

Signed-off-by: David Edmondson <david.edmondson@oracle.com>
---
 target/i386/cpu.c                   | 33 +++++++++++++++++++++++------
 tests/qtest/test-x86-cpuid-compat.c |  8 +++----
 2 files changed, 30 insertions(+), 11 deletions(-)

Comments

Eduardo Habkost Jan. 19, 2021, 3:20 p.m. UTC | #1
Hi,

Thanks for the patch.  Getting rid of special -feature/+feature
behavior was in our TODO list for a long time.

On Tue, Jan 19, 2021 at 02:22:06PM +0000, David Edmondson wrote:
> "Minus" features are applied after "plus" features, so ensure that a
> later "plus" feature causes an earlier "minus" feature to be removed.
> 
> This has no effect on the existing "-feature,feature=on" backward
> compatibility code (which warns and turns the feature off).

If we are changing behavior, why not change behavior of
"-feature,feature=on" at the same time?  This would allow us to
get rid of plus_features/minus_features completely and just make
+feature/-feature synonyms to feature=on/feature=off.

> 
> Signed-off-by: David Edmondson <david.edmondson@oracle.com>
> ---
>  target/i386/cpu.c                   | 33 +++++++++++++++++++++++------
>  tests/qtest/test-x86-cpuid-compat.c |  8 +++----
>  2 files changed, 30 insertions(+), 11 deletions(-)
> 
> diff --git a/target/i386/cpu.c b/target/i386/cpu.c
> index 35459a38bb..13f58ef183 100644
> --- a/target/i386/cpu.c
> +++ b/target/i386/cpu.c
> @@ -4750,13 +4750,32 @@ static void x86_cpu_parse_featurestr(const char *typename, char *features,
>          GlobalProperty *prop;
>  
>          /* Compatibility syntax: */
> -        if (featurestr[0] == '+') {
> -            plus_features = g_list_append(plus_features,
> -                                          g_strdup(featurestr + 1));
> -            continue;
> -        } else if (featurestr[0] == '-') {
> -            minus_features = g_list_append(minus_features,
> -                                           g_strdup(featurestr + 1));
> +        if (featurestr[0] == '+' || featurestr[0] == '-') {
> +            const char *feat = featurestr + 1;
> +            GList **remove, **add;
> +            GList *val;
> +
> +            if (featurestr[0] == '+') {
> +                remove = &minus_features;
> +                add = &plus_features;
> +            } else {
> +                remove = &plus_features;
> +                add = &minus_features;
> +            }
> +
> +            val = g_list_find_custom(*remove, feat, compare_string);
> +            if (val) {
> +                char *data = val->data;
> +
> +                *remove = g_list_remove(*remove, data);
> +                g_free(data);
> +            }
> +
> +            val = g_list_find_custom(*add, feat, compare_string);
> +            if (!val) {
> +                *add = g_list_append(*add, g_strdup(feat));
> +            }

I believe we'll be able to get rid of plus_features/minus_features
completely if we remove compatibility of "-feature,feature=on".
But if we don't, wouldn't it be simpler to replace
plus_features/minus_features with a single list, appending items
in the order they appear?

> +
>              continue;
>          }
>  
> diff --git a/tests/qtest/test-x86-cpuid-compat.c b/tests/qtest/test-x86-cpuid-compat.c
> index 7ca1883a29..6824d2b13e 100644
> --- a/tests/qtest/test-x86-cpuid-compat.c
> +++ b/tests/qtest/test-x86-cpuid-compat.c
> @@ -171,18 +171,18 @@ static void test_plus_minus_subprocess(void)
>      char *path;
>  
>      /* Rules:
> -     * 1)"-foo" overrides "+foo"
> +     * 1) The later of "+foo" or "-foo" wins
>       * 2) "[+-]foo" overrides "foo=..."
>       * 3) Old feature names with underscores (e.g. "sse4_2")
>       *    should keep working
>       *
> -     * Note: rules 1 and 2 are planned to be removed soon, and
> -     * should generate a warning.
> +     * Note: rule 2 is planned to be removed soon, and should generate
> +     * a warning.
>       */
>      qtest_start("-cpu pentium,-fpu,+fpu,-mce,mce=on,+cx8,cx8=off,+sse4_1,sse4_2=on");
>      path = get_cpu0_qom_path();
>  
> -    g_assert_false(qom_get_bool(path, "fpu"));
> +    g_assert_true(qom_get_bool(path, "fpu"));
>      g_assert_false(qom_get_bool(path, "mce"));
>      g_assert_true(qom_get_bool(path, "cx8"));
>  
> -- 
> 2.29.2
>
David Edmondson Jan. 19, 2021, 4:27 p.m. UTC | #2
On Tuesday, 2021-01-19 at 10:20:56 -05, Eduardo Habkost wrote:

> Hi,
>
> Thanks for the patch.  Getting rid of special -feature/+feature
> behavior was in our TODO list for a long time.
>
> On Tue, Jan 19, 2021 at 02:22:06PM +0000, David Edmondson wrote:
>> "Minus" features are applied after "plus" features, so ensure that a
>> later "plus" feature causes an earlier "minus" feature to be removed.
>> 
>> This has no effect on the existing "-feature,feature=on" backward
>> compatibility code (which warns and turns the feature off).
>
> If we are changing behavior, why not change behavior of
> "-feature,feature=on" at the same time?  This would allow us to
> get rid of plus_features/minus_features completely and just make
> +feature/-feature synonyms to feature=on/feature=off.

Okay, I'll do that.

Given that there have been warnings associated with
"-feature,feature=on" for a while, changing that behaviour seems
acceptable.

Would the same be true for changing "-feature,+feature"? (i.e. what this
patch does) Really: can this just be changed, or does there have to be
some period where the behaviour stays the same with a warning?

>> 
>> Signed-off-by: David Edmondson <david.edmondson@oracle.com>
>> ---
>>  target/i386/cpu.c                   | 33 +++++++++++++++++++++++------
>>  tests/qtest/test-x86-cpuid-compat.c |  8 +++----
>>  2 files changed, 30 insertions(+), 11 deletions(-)
>> 
>> diff --git a/target/i386/cpu.c b/target/i386/cpu.c
>> index 35459a38bb..13f58ef183 100644
>> --- a/target/i386/cpu.c
>> +++ b/target/i386/cpu.c
>> @@ -4750,13 +4750,32 @@ static void x86_cpu_parse_featurestr(const char *typename, char *features,
>>          GlobalProperty *prop;
>>  
>>          /* Compatibility syntax: */
>> -        if (featurestr[0] == '+') {
>> -            plus_features = g_list_append(plus_features,
>> -                                          g_strdup(featurestr + 1));
>> -            continue;
>> -        } else if (featurestr[0] == '-') {
>> -            minus_features = g_list_append(minus_features,
>> -                                           g_strdup(featurestr + 1));
>> +        if (featurestr[0] == '+' || featurestr[0] == '-') {
>> +            const char *feat = featurestr + 1;
>> +            GList **remove, **add;
>> +            GList *val;
>> +
>> +            if (featurestr[0] == '+') {
>> +                remove = &minus_features;
>> +                add = &plus_features;
>> +            } else {
>> +                remove = &plus_features;
>> +                add = &minus_features;
>> +            }
>> +
>> +            val = g_list_find_custom(*remove, feat, compare_string);
>> +            if (val) {
>> +                char *data = val->data;
>> +
>> +                *remove = g_list_remove(*remove, data);
>> +                g_free(data);
>> +            }
>> +
>> +            val = g_list_find_custom(*add, feat, compare_string);
>> +            if (!val) {
>> +                *add = g_list_append(*add, g_strdup(feat));
>> +            }
>
> I believe we'll be able to get rid of plus_features/minus_features
> completely if we remove compatibility of "-feature,feature=on".
> But if we don't, wouldn't it be simpler to replace
> plus_features/minus_features with a single list, appending items
> in the order they appear?

Will investigate.

>> +
>>              continue;
>>          }
>>  
>> diff --git a/tests/qtest/test-x86-cpuid-compat.c b/tests/qtest/test-x86-cpuid-compat.c
>> index 7ca1883a29..6824d2b13e 100644
>> --- a/tests/qtest/test-x86-cpuid-compat.c
>> +++ b/tests/qtest/test-x86-cpuid-compat.c
>> @@ -171,18 +171,18 @@ static void test_plus_minus_subprocess(void)
>>      char *path;
>>  
>>      /* Rules:
>> -     * 1)"-foo" overrides "+foo"
>> +     * 1) The later of "+foo" or "-foo" wins
>>       * 2) "[+-]foo" overrides "foo=..."
>>       * 3) Old feature names with underscores (e.g. "sse4_2")
>>       *    should keep working
>>       *
>> -     * Note: rules 1 and 2 are planned to be removed soon, and
>> -     * should generate a warning.
>> +     * Note: rule 2 is planned to be removed soon, and should generate
>> +     * a warning.
>>       */
>>      qtest_start("-cpu pentium,-fpu,+fpu,-mce,mce=on,+cx8,cx8=off,+sse4_1,sse4_2=on");
>>      path = get_cpu0_qom_path();
>>  
>> -    g_assert_false(qom_get_bool(path, "fpu"));
>> +    g_assert_true(qom_get_bool(path, "fpu"));
>>      g_assert_false(qom_get_bool(path, "mce"));
>>      g_assert_true(qom_get_bool(path, "cx8"));
>>  
>> -- 
>> 2.29.2
>> 
>
> -- 
> Eduardo

dme.
Eduardo Habkost Jan. 19, 2021, 4:30 p.m. UTC | #3
On Tue, Jan 19, 2021 at 04:27:56PM +0000, David Edmondson wrote:
> On Tuesday, 2021-01-19 at 10:20:56 -05, Eduardo Habkost wrote:
> 
> > Hi,
> >
> > Thanks for the patch.  Getting rid of special -feature/+feature
> > behavior was in our TODO list for a long time.
> >
> > On Tue, Jan 19, 2021 at 02:22:06PM +0000, David Edmondson wrote:
> >> "Minus" features are applied after "plus" features, so ensure that a
> >> later "plus" feature causes an earlier "minus" feature to be removed.
> >> 
> >> This has no effect on the existing "-feature,feature=on" backward
> >> compatibility code (which warns and turns the feature off).
> >
> > If we are changing behavior, why not change behavior of
> > "-feature,feature=on" at the same time?  This would allow us to
> > get rid of plus_features/minus_features completely and just make
> > +feature/-feature synonyms to feature=on/feature=off.
> 
> Okay, I'll do that.
> 
> Given that there have been warnings associated with
> "-feature,feature=on" for a while, changing that behaviour seems
> acceptable.
> 
> Would the same be true for changing "-feature,+feature"? (i.e. what this
> patch does) Really: can this just be changed, or does there have to be
> some period where the behaviour stays the same with a warning?

I actually expected warnings to be triggered when using
"-feature,+feature" as well.  If we were not generating warnings
for that case, it will need more careful evaluation, just to be
sure it's safe.  Igor, do you remember the details here?
Igor Mammedov Jan. 20, 2021, 9:59 a.m. UTC | #4
On Tue, 19 Jan 2021 11:30:52 -0500
Eduardo Habkost <ehabkost@redhat.com> wrote:

> On Tue, Jan 19, 2021 at 04:27:56PM +0000, David Edmondson wrote:
> > On Tuesday, 2021-01-19 at 10:20:56 -05, Eduardo Habkost wrote:
> >   
> > > Hi,
> > >
> > > Thanks for the patch.  Getting rid of special -feature/+feature
> > > behavior was in our TODO list for a long time.
> > >
> > > On Tue, Jan 19, 2021 at 02:22:06PM +0000, David Edmondson wrote:  
> > >> "Minus" features are applied after "plus" features, so ensure that a
> > >> later "plus" feature causes an earlier "minus" feature to be removed.
> > >> 
> > >> This has no effect on the existing "-feature,feature=on" backward
> > >> compatibility code (which warns and turns the feature off).  
> > >
> > > If we are changing behavior, why not change behavior of
> > > "-feature,feature=on" at the same time?  This would allow us to
> > > get rid of plus_features/minus_features completely and just make
> > > +feature/-feature synonyms to feature=on/feature=off.  
> > 
> > Okay, I'll do that.
> > 
> > Given that there have been warnings associated with
> > "-feature,feature=on" for a while, changing that behaviour seems
> > acceptable.
> > 
> > Would the same be true for changing "-feature,+feature"? (i.e. what this
> > patch does) Really: can this just be changed, or does there have to be
> > some period where the behaviour stays the same with a warning?  
> 
> I actually expected warnings to be triggered when using
> "-feature,+feature" as well.  If we were not generating warnings
> for that case, it will need more careful evaluation, just to be
> sure it's safe.  Igor, do you remember the details here?
As part of preparation to define/create machines via QMP,
I plan to post patch(s) to deprecate +-features in 6.0
(including special casing for -feat behavior (affects x86/sparc only))
and drop support for +-feat in 2 releases.
So we should end up with canonical property behavior only like all other
CPUs and devices.
Daniel P. Berrangé Jan. 20, 2021, 10:08 a.m. UTC | #5
On Tue, Jan 19, 2021 at 11:30:52AM -0500, Eduardo Habkost wrote:
> On Tue, Jan 19, 2021 at 04:27:56PM +0000, David Edmondson wrote:
> > On Tuesday, 2021-01-19 at 10:20:56 -05, Eduardo Habkost wrote:
> > 
> > > Hi,
> > >
> > > Thanks for the patch.  Getting rid of special -feature/+feature
> > > behavior was in our TODO list for a long time.
> > >
> > > On Tue, Jan 19, 2021 at 02:22:06PM +0000, David Edmondson wrote:
> > >> "Minus" features are applied after "plus" features, so ensure that a
> > >> later "plus" feature causes an earlier "minus" feature to be removed.
> > >> 
> > >> This has no effect on the existing "-feature,feature=on" backward
> > >> compatibility code (which warns and turns the feature off).
> > >
> > > If we are changing behavior, why not change behavior of
> > > "-feature,feature=on" at the same time?  This would allow us to
> > > get rid of plus_features/minus_features completely and just make
> > > +feature/-feature synonyms to feature=on/feature=off.
> > 
> > Okay, I'll do that.
> > 
> > Given that there have been warnings associated with
> > "-feature,feature=on" for a while, changing that behaviour seems
> > acceptable.
> > 
> > Would the same be true for changing "-feature,+feature"? (i.e. what this
> > patch does) Really: can this just be changed, or does there have to be
> > some period where the behaviour stays the same with a warning?
> 
> I actually expected warnings to be triggered when using
> "-feature,+feature" as well.  If we were not generating warnings
> for that case, it will need more careful evaluation, just to be
> sure it's safe.  Igor, do you remember the details here?

Where are you expecting warnings ? I don't see any when launching QEMU

$ qemu-system-x86_64 -display none  -cpu Westmere,-vmx 

$ qemu-system-x86_64 -display none  -cpu Westmere,-vmx,sse=on

neither produces warnings, even with current git master.

I don't think we can change the parsing behaviour here without impacting
guest ABI, and that feels dangerous given that we've not been warning
people the syntax is undesirable.

IMHO just leave the parsing unchanged, deprecate it, and then delete
the code.  We don't need to "improve" usability semantics of something
that we want to delete anyway.

Regards,
Daniel
David Edmondson Jan. 20, 2021, 10:08 a.m. UTC | #6
On Wednesday, 2021-01-20 at 10:59:24 +01, Igor Mammedov wrote:

> On Tue, 19 Jan 2021 11:30:52 -0500
> Eduardo Habkost <ehabkost@redhat.com> wrote:
>
>> On Tue, Jan 19, 2021 at 04:27:56PM +0000, David Edmondson wrote:
>> > On Tuesday, 2021-01-19 at 10:20:56 -05, Eduardo Habkost wrote:
>> >   
>> > > Hi,
>> > >
>> > > Thanks for the patch.  Getting rid of special -feature/+feature
>> > > behavior was in our TODO list for a long time.
>> > >
>> > > On Tue, Jan 19, 2021 at 02:22:06PM +0000, David Edmondson wrote:  
>> > >> "Minus" features are applied after "plus" features, so ensure that a
>> > >> later "plus" feature causes an earlier "minus" feature to be removed.
>> > >> 
>> > >> This has no effect on the existing "-feature,feature=on" backward
>> > >> compatibility code (which warns and turns the feature off).  
>> > >
>> > > If we are changing behavior, why not change behavior of
>> > > "-feature,feature=on" at the same time?  This would allow us to
>> > > get rid of plus_features/minus_features completely and just make
>> > > +feature/-feature synonyms to feature=on/feature=off.  
>> > 
>> > Okay, I'll do that.
>> > 
>> > Given that there have been warnings associated with
>> > "-feature,feature=on" for a while, changing that behaviour seems
>> > acceptable.
>> > 
>> > Would the same be true for changing "-feature,+feature"? (i.e. what this
>> > patch does) Really: can this just be changed, or does there have to be
>> > some period where the behaviour stays the same with a warning?  
>> 
>> I actually expected warnings to be triggered when using
>> "-feature,+feature" as well.  If we were not generating warnings
>> for that case, it will need more careful evaluation, just to be
>> sure it's safe.  Igor, do you remember the details here?
> As part of preparation to define/create machines via QMP,
> I plan to post patch(s) to deprecate +-features in 6.0
> (including special casing for -feat behavior (affects x86/sparc only))
> and drop support for +-feat in 2 releases.
> So we should end up with canonical property behavior only like all other
> CPUs and devices.

In that case I will abandon this change and focus on getting my upstack
consumer to switch away from using +-.

Thanks.

dme.
David Edmondson Jan. 20, 2021, 10:17 a.m. UTC | #7
On Wednesday, 2021-01-20 at 10:08:03 GMT, Daniel P. Berrangé wrote:

> On Tue, Jan 19, 2021 at 11:30:52AM -0500, Eduardo Habkost wrote:
>> On Tue, Jan 19, 2021 at 04:27:56PM +0000, David Edmondson wrote:
>> > On Tuesday, 2021-01-19 at 10:20:56 -05, Eduardo Habkost wrote:
>> > 
>> > > Hi,
>> > >
>> > > Thanks for the patch.  Getting rid of special -feature/+feature
>> > > behavior was in our TODO list for a long time.
>> > >
>> > > On Tue, Jan 19, 2021 at 02:22:06PM +0000, David Edmondson wrote:
>> > >> "Minus" features are applied after "plus" features, so ensure that a
>> > >> later "plus" feature causes an earlier "minus" feature to be removed.
>> > >> 
>> > >> This has no effect on the existing "-feature,feature=on" backward
>> > >> compatibility code (which warns and turns the feature off).
>> > >
>> > > If we are changing behavior, why not change behavior of
>> > > "-feature,feature=on" at the same time?  This would allow us to
>> > > get rid of plus_features/minus_features completely and just make
>> > > +feature/-feature synonyms to feature=on/feature=off.
>> > 
>> > Okay, I'll do that.
>> > 
>> > Given that there have been warnings associated with
>> > "-feature,feature=on" for a while, changing that behaviour seems
>> > acceptable.
>> > 
>> > Would the same be true for changing "-feature,+feature"? (i.e. what this
>> > patch does) Really: can this just be changed, or does there have to be
>> > some period where the behaviour stays the same with a warning?
>> 
>> I actually expected warnings to be triggered when using
>> "-feature,+feature" as well.  If we were not generating warnings
>> for that case, it will need more careful evaluation, just to be
>> sure it's safe.  Igor, do you remember the details here?
>
> Where are you expecting warnings ? I don't see any when launching QEMU

qemu-system-x86_64 -display none -cpu Westmere,-vmx,+vmx

Warnings because the result of this is "-vmx".

> IMHO just leave the parsing unchanged, deprecate it, and then delete
> the code.  We don't need to "improve" usability semantics of something
> that we want to delete anyway.

/me nods.

dme.
Eduardo Habkost Jan. 20, 2021, 4:18 p.m. UTC | #8
On Wed, Jan 20, 2021 at 10:17:36AM +0000, David Edmondson wrote:
> On Wednesday, 2021-01-20 at 10:08:03 GMT, Daniel P. Berrangé wrote:
> 
> > On Tue, Jan 19, 2021 at 11:30:52AM -0500, Eduardo Habkost wrote:
> >> On Tue, Jan 19, 2021 at 04:27:56PM +0000, David Edmondson wrote:
> >> > On Tuesday, 2021-01-19 at 10:20:56 -05, Eduardo Habkost wrote:
> >> > 
> >> > > Hi,
> >> > >
> >> > > Thanks for the patch.  Getting rid of special -feature/+feature
> >> > > behavior was in our TODO list for a long time.
> >> > >
> >> > > On Tue, Jan 19, 2021 at 02:22:06PM +0000, David Edmondson wrote:
> >> > >> "Minus" features are applied after "plus" features, so ensure that a
> >> > >> later "plus" feature causes an earlier "minus" feature to be removed.
> >> > >> 
> >> > >> This has no effect on the existing "-feature,feature=on" backward
> >> > >> compatibility code (which warns and turns the feature off).
> >> > >
> >> > > If we are changing behavior, why not change behavior of
> >> > > "-feature,feature=on" at the same time?  This would allow us to
> >> > > get rid of plus_features/minus_features completely and just make
> >> > > +feature/-feature synonyms to feature=on/feature=off.
> >> > 
> >> > Okay, I'll do that.
> >> > 
> >> > Given that there have been warnings associated with
> >> > "-feature,feature=on" for a while, changing that behaviour seems
> >> > acceptable.
> >> > 
> >> > Would the same be true for changing "-feature,+feature"? (i.e. what this
> >> > patch does) Really: can this just be changed, or does there have to be
> >> > some period where the behaviour stays the same with a warning?
> >> 
> >> I actually expected warnings to be triggered when using
> >> "-feature,+feature" as well.  If we were not generating warnings
> >> for that case, it will need more careful evaluation, just to be
> >> sure it's safe.  Igor, do you remember the details here?
> >
> > Where are you expecting warnings ? I don't see any when launching QEMU
> 
> qemu-system-x86_64 -display none -cpu Westmere,-vmx,+vmx
> 
> Warnings because the result of this is "-vmx".
> 
> > IMHO just leave the parsing unchanged, deprecate it, and then delete
> > the code.  We don't need to "improve" usability semantics of something
> > that we want to delete anyway.
> 
> /me nods.

I agree, but I guess we need to convince Paolo:
https://lore.kernel.org/qemu-devel/1990888058.22417362.1465939000140.JavaMail.zimbra@redhat.com/
Igor Mammedov Jan. 20, 2021, 7:21 p.m. UTC | #9
On Wed, 20 Jan 2021 11:18:01 -0500
Eduardo Habkost <ehabkost@redhat.com> wrote:

> On Wed, Jan 20, 2021 at 10:17:36AM +0000, David Edmondson wrote:
> > On Wednesday, 2021-01-20 at 10:08:03 GMT, Daniel P. Berrangé wrote:
> >   
> > > On Tue, Jan 19, 2021 at 11:30:52AM -0500, Eduardo Habkost wrote:  
> > >> On Tue, Jan 19, 2021 at 04:27:56PM +0000, David Edmondson wrote:  
> > >> > On Tuesday, 2021-01-19 at 10:20:56 -05, Eduardo Habkost wrote:
> > >> >   
> > >> > > Hi,
> > >> > >
> > >> > > Thanks for the patch.  Getting rid of special -feature/+feature
> > >> > > behavior was in our TODO list for a long time.
> > >> > >
> > >> > > On Tue, Jan 19, 2021 at 02:22:06PM +0000, David Edmondson wrote:  
> > >> > >> "Minus" features are applied after "plus" features, so ensure that a
> > >> > >> later "plus" feature causes an earlier "minus" feature to be removed.
> > >> > >> 
> > >> > >> This has no effect on the existing "-feature,feature=on" backward
> > >> > >> compatibility code (which warns and turns the feature off).  
> > >> > >
> > >> > > If we are changing behavior, why not change behavior of
> > >> > > "-feature,feature=on" at the same time?  This would allow us to
> > >> > > get rid of plus_features/minus_features completely and just make
> > >> > > +feature/-feature synonyms to feature=on/feature=off.  
> > >> > 
> > >> > Okay, I'll do that.
> > >> > 
> > >> > Given that there have been warnings associated with
> > >> > "-feature,feature=on" for a while, changing that behaviour seems
> > >> > acceptable.
> > >> > 
> > >> > Would the same be true for changing "-feature,+feature"? (i.e. what this
> > >> > patch does) Really: can this just be changed, or does there have to be
> > >> > some period where the behaviour stays the same with a warning?  
> > >> 
> > >> I actually expected warnings to be triggered when using
> > >> "-feature,+feature" as well.  If we were not generating warnings
> > >> for that case, it will need more careful evaluation, just to be
> > >> sure it's safe.  Igor, do you remember the details here?  
> > >
> > > Where are you expecting warnings ? I don't see any when launching QEMU  
> > 
> > qemu-system-x86_64 -display none -cpu Westmere,-vmx,+vmx
> > 
> > Warnings because the result of this is "-vmx".
> >   
> > > IMHO just leave the parsing unchanged, deprecate it, and then delete
> > > the code.  We don't need to "improve" usability semantics of something
> > > that we want to delete anyway.  
> > 
> > /me nods.  
> 
> I agree, but I guess we need to convince Paolo:
> https://lore.kernel.org/qemu-devel/1990888058.22417362.1465939000140.JavaMail.zimbra@redhat.com/
that's ancient :)

He recently started this revolution himself :)
https://www.mail-archive.com/qemu-devel@nongnu.org/msg757280.html

That's why I have -cpu +/-foo deprecation on my not too far away TODO list.
diff mbox series

Patch

diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index 35459a38bb..13f58ef183 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -4750,13 +4750,32 @@  static void x86_cpu_parse_featurestr(const char *typename, char *features,
         GlobalProperty *prop;
 
         /* Compatibility syntax: */
-        if (featurestr[0] == '+') {
-            plus_features = g_list_append(plus_features,
-                                          g_strdup(featurestr + 1));
-            continue;
-        } else if (featurestr[0] == '-') {
-            minus_features = g_list_append(minus_features,
-                                           g_strdup(featurestr + 1));
+        if (featurestr[0] == '+' || featurestr[0] == '-') {
+            const char *feat = featurestr + 1;
+            GList **remove, **add;
+            GList *val;
+
+            if (featurestr[0] == '+') {
+                remove = &minus_features;
+                add = &plus_features;
+            } else {
+                remove = &plus_features;
+                add = &minus_features;
+            }
+
+            val = g_list_find_custom(*remove, feat, compare_string);
+            if (val) {
+                char *data = val->data;
+
+                *remove = g_list_remove(*remove, data);
+                g_free(data);
+            }
+
+            val = g_list_find_custom(*add, feat, compare_string);
+            if (!val) {
+                *add = g_list_append(*add, g_strdup(feat));
+            }
+
             continue;
         }
 
diff --git a/tests/qtest/test-x86-cpuid-compat.c b/tests/qtest/test-x86-cpuid-compat.c
index 7ca1883a29..6824d2b13e 100644
--- a/tests/qtest/test-x86-cpuid-compat.c
+++ b/tests/qtest/test-x86-cpuid-compat.c
@@ -171,18 +171,18 @@  static void test_plus_minus_subprocess(void)
     char *path;
 
     /* Rules:
-     * 1)"-foo" overrides "+foo"
+     * 1) The later of "+foo" or "-foo" wins
      * 2) "[+-]foo" overrides "foo=..."
      * 3) Old feature names with underscores (e.g. "sse4_2")
      *    should keep working
      *
-     * Note: rules 1 and 2 are planned to be removed soon, and
-     * should generate a warning.
+     * Note: rule 2 is planned to be removed soon, and should generate
+     * a warning.
      */
     qtest_start("-cpu pentium,-fpu,+fpu,-mce,mce=on,+cx8,cx8=off,+sse4_1,sse4_2=on");
     path = get_cpu0_qom_path();
 
-    g_assert_false(qom_get_bool(path, "fpu"));
+    g_assert_true(qom_get_bool(path, "fpu"));
     g_assert_false(qom_get_bool(path, "mce"));
     g_assert_true(qom_get_bool(path, "cx8"));