diff mbox

[06/11] target-i386: add socket/core/thread properties to X86CPU

Message ID 1466693669-139967-7-git-send-email-imammedo@redhat.com
State New
Headers show

Commit Message

Igor Mammedov June 23, 2016, 2:54 p.m. UTC
these properties will be used by as address where to plug
CPU with help -device/device_add commands.

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
---
 hw/i386/pc.c      | 12 ++++++++++++
 target-i386/cpu.c |  3 +++
 target-i386/cpu.h |  4 ++++
 3 files changed, 19 insertions(+)

Comments

Eduardo Habkost June 23, 2016, 5:44 p.m. UTC | #1
On Thu, Jun 23, 2016 at 04:54:24PM +0200, Igor Mammedov wrote:
> these properties will be used by as address where to plug
> CPU with help -device/device_add commands.
> 
> Signed-off-by: Igor Mammedov <imammedo@redhat.com>
> ---
>  hw/i386/pc.c      | 12 ++++++++++++
>  target-i386/cpu.c |  3 +++
>  target-i386/cpu.h |  4 ++++
>  3 files changed, 19 insertions(+)
> 
> diff --git a/hw/i386/pc.c b/hw/i386/pc.c
> index 6ba6343..87352ae 100644
> --- a/hw/i386/pc.c
> +++ b/hw/i386/pc.c
> @@ -1775,6 +1775,18 @@ static void pc_cpu_pre_plug(HotplugHandler *hotplug_dev,
>                     cpu->apic_id);
>          return;
>      }
> +
> +    /* set 'address' properties socket/core/thread for initial and cpu-add
> +     * added CPUs so that query_hotpluggable_cpus would show correct values
> +     */
> +    if (cpu->thread == -1 || cpu->core == -1 || cpu->socket == -1) {
> +        X86CPUTopoInfo topo;
> +
> +        x86_topo_ids_from_apicid(cpu->apic_id, smp_cores, smp_threads, &topo);
> +        cpu->thread = topo.smt_id;
> +        cpu->core = topo.core_id;
> +        cpu->socket = topo.pkg_id;
> +    }

What if both apic-id and socket/core/thread are set?

I suggest validating the properties, and setting them in case
they are not set:

    x86_topo_ids_from_apicid(cpu->apic_id, smp_cores, smp_threads, &topo);

    if (cpu->socket != -1 && cpu->socket != topo.socket_id) {
        error_setg(errp, "CPU socket ID mismatch: ...");
        return;
    }
    cpu->socket = topo.socket_id;

    if (cpu->core != -1 && cpu->core != topo.core_id) {
        error_setg(errp, "CPU core ID mismatch: ...");
        return;
    }
    cpu->core = topo.core_id;

    if (cpu->thread != -1 && cpu->thread != topo.smt_id) {
        error_setg(errp, "CPU thread ID mismatch: ...");
        return;
    }
    cpu->thread = topo.smt_id;

We could do that inside x86_cpu_realizefn(), so that
socket/core/thread would be always set in all CPUs.

>  }
>  
>  static void pc_machine_device_pre_plug_cb(HotplugHandler *hotplug_dev,
> diff --git a/target-i386/cpu.c b/target-i386/cpu.c
> index 9294b3d..8c651f2 100644
> --- a/target-i386/cpu.c
> +++ b/target-i386/cpu.c
> @@ -3186,6 +3186,9 @@ static Property x86_cpu_properties[] = {
>      DEFINE_PROP_UINT32("xlevel2", X86CPU, env.cpuid_xlevel2, 0),
>      DEFINE_PROP_STRING("hv-vendor-id", X86CPU, hyperv_vendor_id),
>      DEFINE_PROP_BOOL("cpuid-0xb", X86CPU, enable_cpuid_0xb, true),
> +    DEFINE_PROP_INT32("thread", X86CPU, thread, -1),
> +    DEFINE_PROP_INT32("core", X86CPU, core, -1),
> +    DEFINE_PROP_INT32("socket", X86CPU, socket, -1),
>      DEFINE_PROP_END_OF_LIST()
>  };
>  
> diff --git a/target-i386/cpu.h b/target-i386/cpu.h
> index 8b09cfa..a04d334 100644
> --- a/target-i386/cpu.h
> +++ b/target-i386/cpu.h
> @@ -1190,6 +1190,10 @@ struct X86CPU {
>      Notifier machine_done;
>  
>      struct kvm_msrs *kvm_msr_buf;
> +
> +    int32_t socket;
> +    int32_t core;
> +    int32_t thread;
>  };
>  
>  static inline X86CPU *x86_env_get_cpu(CPUX86State *env)
> -- 
> 1.8.3.1
>
Igor Mammedov June 23, 2016, 7:18 p.m. UTC | #2
On Thu, 23 Jun 2016 14:44:53 -0300
Eduardo Habkost <ehabkost@redhat.com> wrote:

> On Thu, Jun 23, 2016 at 04:54:24PM +0200, Igor Mammedov wrote:
> > these properties will be used by as address where to plug
> > CPU with help -device/device_add commands.
> > 
> > Signed-off-by: Igor Mammedov <imammedo@redhat.com>
> > ---
> >  hw/i386/pc.c      | 12 ++++++++++++
> >  target-i386/cpu.c |  3 +++
> >  target-i386/cpu.h |  4 ++++
> >  3 files changed, 19 insertions(+)
> > 
> > diff --git a/hw/i386/pc.c b/hw/i386/pc.c
> > index 6ba6343..87352ae 100644
> > --- a/hw/i386/pc.c
> > +++ b/hw/i386/pc.c
> > @@ -1775,6 +1775,18 @@ static void pc_cpu_pre_plug(HotplugHandler
> > *hotplug_dev, cpu->apic_id);
> >          return;
> >      }
> > +
> > +    /* set 'address' properties socket/core/thread for initial and
> > cpu-add
> > +     * added CPUs so that query_hotpluggable_cpus would show
> > correct values
> > +     */
> > +    if (cpu->thread == -1 || cpu->core == -1 || cpu->socket == -1)
> > {
> > +        X86CPUTopoInfo topo;
> > +
> > +        x86_topo_ids_from_apicid(cpu->apic_id, smp_cores,
> > smp_threads, &topo);
> > +        cpu->thread = topo.smt_id;
> > +        cpu->core = topo.core_id;
> > +        cpu->socket = topo.pkg_id;
> > +    }
> 
> What if both apic-id and socket/core/thread are set?
they shouldn't since query_hotpluggable_cpus doesn't have apic_id
attribute so apic_id isn't supposed to be on user provided,
but of cause user could add it manually on device_add command to create
confusion, in that case apic_id would take precedence and
socket/core/thread ignored.

> 
> I suggest validating the properties, and setting them in case
> they are not set:
> 
>     x86_topo_ids_from_apicid(cpu->apic_id, smp_cores, smp_threads,
> &topo);
> 
>     if (cpu->socket != -1 && cpu->socket != topo.socket_id) {
>         error_setg(errp, "CPU socket ID mismatch: ...");
>         return;
>     }
>     cpu->socket = topo.socket_id;
> 
>     if (cpu->core != -1 && cpu->core != topo.core_id) {
>         error_setg(errp, "CPU core ID mismatch: ...");
>         return;
>     }
>     cpu->core = topo.core_id;
> 
>     if (cpu->thread != -1 && cpu->thread != topo.smt_id) {
>         error_setg(errp, "CPU thread ID mismatch: ...");
>         return;
>     }
>     cpu->thread = topo.smt_id;
> 
> We could do that inside x86_cpu_realizefn(), so that
> socket/core/thread would be always set in all CPUs.
all CPUs pass through pc_cpu_pre_plug() before cpu.relizefn()
so I'd rather do it here at board level responsible for
setting apic_id or socket/core/thread info is not set.


> 
> >  }
> >  
> >  static void pc_machine_device_pre_plug_cb(HotplugHandler
> > *hotplug_dev, diff --git a/target-i386/cpu.c b/target-i386/cpu.c
> > index 9294b3d..8c651f2 100644
> > --- a/target-i386/cpu.c
> > +++ b/target-i386/cpu.c
> > @@ -3186,6 +3186,9 @@ static Property x86_cpu_properties[] = {
> >      DEFINE_PROP_UINT32("xlevel2", X86CPU, env.cpuid_xlevel2, 0),
> >      DEFINE_PROP_STRING("hv-vendor-id", X86CPU, hyperv_vendor_id),
> >      DEFINE_PROP_BOOL("cpuid-0xb", X86CPU, enable_cpuid_0xb, true),
> > +    DEFINE_PROP_INT32("thread", X86CPU, thread, -1),
> > +    DEFINE_PROP_INT32("core", X86CPU, core, -1),
> > +    DEFINE_PROP_INT32("socket", X86CPU, socket, -1),
> >      DEFINE_PROP_END_OF_LIST()
> >  };
> >  
> > diff --git a/target-i386/cpu.h b/target-i386/cpu.h
> > index 8b09cfa..a04d334 100644
> > --- a/target-i386/cpu.h
> > +++ b/target-i386/cpu.h
> > @@ -1190,6 +1190,10 @@ struct X86CPU {
> >      Notifier machine_done;
> >  
> >      struct kvm_msrs *kvm_msr_buf;
> > +
> > +    int32_t socket;
> > +    int32_t core;
> > +    int32_t thread;
> >  };
> >  
> >  static inline X86CPU *x86_env_get_cpu(CPUX86State *env)
> > -- 
> > 1.8.3.1
> > 
>
Eduardo Habkost June 23, 2016, 8:18 p.m. UTC | #3
On Thu, Jun 23, 2016 at 09:18:38PM +0200, Igor Mammedov wrote:
> On Thu, 23 Jun 2016 14:44:53 -0300
> Eduardo Habkost <ehabkost@redhat.com> wrote:
> 
> > On Thu, Jun 23, 2016 at 04:54:24PM +0200, Igor Mammedov wrote:
> > > these properties will be used by as address where to plug
> > > CPU with help -device/device_add commands.
> > > 
> > > Signed-off-by: Igor Mammedov <imammedo@redhat.com>
> > > ---
> > >  hw/i386/pc.c      | 12 ++++++++++++
> > >  target-i386/cpu.c |  3 +++
> > >  target-i386/cpu.h |  4 ++++
> > >  3 files changed, 19 insertions(+)
> > > 
> > > diff --git a/hw/i386/pc.c b/hw/i386/pc.c
> > > index 6ba6343..87352ae 100644
> > > --- a/hw/i386/pc.c
> > > +++ b/hw/i386/pc.c
> > > @@ -1775,6 +1775,18 @@ static void pc_cpu_pre_plug(HotplugHandler
> > > *hotplug_dev, cpu->apic_id);
> > >          return;
> > >      }
> > > +
> > > +    /* set 'address' properties socket/core/thread for initial and
> > > cpu-add
> > > +     * added CPUs so that query_hotpluggable_cpus would show
> > > correct values
> > > +     */
> > > +    if (cpu->thread == -1 || cpu->core == -1 || cpu->socket == -1)
> > > {
> > > +        X86CPUTopoInfo topo;
> > > +
> > > +        x86_topo_ids_from_apicid(cpu->apic_id, smp_cores,
> > > smp_threads, &topo);
> > > +        cpu->thread = topo.smt_id;
> > > +        cpu->core = topo.core_id;
> > > +        cpu->socket = topo.pkg_id;
> > > +    }
> > 
> > What if both apic-id and socket/core/thread are set?
> they shouldn't since query_hotpluggable_cpus doesn't have apic_id
> attribute so apic_id isn't supposed to be on user provided,
> but of cause user could add it manually on device_add command to create
> confusion, in that case apic_id would take precedence and
> socket/core/thread ignored.

I would like to reject obviously invalid input instead of having
unclear precedence rules.

> 
> > 
> > I suggest validating the properties, and setting them in case
> > they are not set:
> > 
> >     x86_topo_ids_from_apicid(cpu->apic_id, smp_cores, smp_threads,
> > &topo);
> > 
> >     if (cpu->socket != -1 && cpu->socket != topo.socket_id) {
> >         error_setg(errp, "CPU socket ID mismatch: ...");
> >         return;
> >     }
> >     cpu->socket = topo.socket_id;
> > 
> >     if (cpu->core != -1 && cpu->core != topo.core_id) {
> >         error_setg(errp, "CPU core ID mismatch: ...");
> >         return;
> >     }
> >     cpu->core = topo.core_id;
> > 
> >     if (cpu->thread != -1 && cpu->thread != topo.smt_id) {
> >         error_setg(errp, "CPU thread ID mismatch: ...");
> >         return;
> >     }
> >     cpu->thread = topo.smt_id;
> > 
> > We could do that inside x86_cpu_realizefn(), so that
> > socket/core/thread would be always set in all CPUs.
> all CPUs pass through pc_cpu_pre_plug() before cpu.relizefn()
> so I'd rather do it here at board level responsible for
> setting apic_id or socket/core/thread info is not set.

Then *-user will be inconsistent, and will always have invalid
values in socket/core/thread. If one day we add any logic using
the socket/core/thread properties in cpu.c, it will break on
*-user.

All those properties are X86CPU properties, meaning they are
input to the X86CPU code. I don't see why we should move logic
related to them outside cpu.c unless really necessary.

(The apic-id calculation at patch 07/11, for example, is more
difficult to move to cpu.c, because the PC code needs the APIC ID
before calling realize. We could move it to the apic-id getter,
but I dislike having magic getter/setters and like that you made
it a static property.)
Igor Mammedov June 23, 2016, 8:46 p.m. UTC | #4
On Thu, 23 Jun 2016 17:18:46 -0300
Eduardo Habkost <ehabkost@redhat.com> wrote:

> On Thu, Jun 23, 2016 at 09:18:38PM +0200, Igor Mammedov wrote:
> > On Thu, 23 Jun 2016 14:44:53 -0300
> > Eduardo Habkost <ehabkost@redhat.com> wrote:
> > 
> > > On Thu, Jun 23, 2016 at 04:54:24PM +0200, Igor Mammedov wrote:
> > > > these properties will be used by as address where to plug
> > > > CPU with help -device/device_add commands.
> > > > 
> > > > Signed-off-by: Igor Mammedov <imammedo@redhat.com>
> > > > ---
> > > >  hw/i386/pc.c      | 12 ++++++++++++
> > > >  target-i386/cpu.c |  3 +++
> > > >  target-i386/cpu.h |  4 ++++
> > > >  3 files changed, 19 insertions(+)
> > > > 
> > > > diff --git a/hw/i386/pc.c b/hw/i386/pc.c
> > > > index 6ba6343..87352ae 100644
> > > > --- a/hw/i386/pc.c
> > > > +++ b/hw/i386/pc.c
> > > > @@ -1775,6 +1775,18 @@ static void
> > > > pc_cpu_pre_plug(HotplugHandler *hotplug_dev, cpu->apic_id);
> > > >          return;
> > > >      }
> > > > +
> > > > +    /* set 'address' properties socket/core/thread for initial
> > > > and cpu-add
> > > > +     * added CPUs so that query_hotpluggable_cpus would show
> > > > correct values
> > > > +     */
> > > > +    if (cpu->thread == -1 || cpu->core == -1 || cpu->socket ==
> > > > -1) {
> > > > +        X86CPUTopoInfo topo;
> > > > +
> > > > +        x86_topo_ids_from_apicid(cpu->apic_id, smp_cores,
> > > > smp_threads, &topo);
> > > > +        cpu->thread = topo.smt_id;
> > > > +        cpu->core = topo.core_id;
> > > > +        cpu->socket = topo.pkg_id;
> > > > +    }
> > > 
> > > What if both apic-id and socket/core/thread are set?
> > they shouldn't since query_hotpluggable_cpus doesn't have apic_id
> > attribute so apic_id isn't supposed to be on user provided,
> > but of cause user could add it manually on device_add command to
> > create confusion, in that case apic_id would take precedence and
> > socket/core/thread ignored.
> 
> I would like to reject obviously invalid input instead of having
> unclear precedence rules.
ok

> > 
> > > 
> > > I suggest validating the properties, and setting them in case
> > > they are not set:
> > > 
> > >     x86_topo_ids_from_apicid(cpu->apic_id, smp_cores, smp_threads,
> > > &topo);
> > > 
> > >     if (cpu->socket != -1 && cpu->socket != topo.socket_id) {
> > >         error_setg(errp, "CPU socket ID mismatch: ...");
> > >         return;
> > >     }
> > >     cpu->socket = topo.socket_id;
> > > 
> > >     if (cpu->core != -1 && cpu->core != topo.core_id) {
> > >         error_setg(errp, "CPU core ID mismatch: ...");
> > >         return;
> > >     }
> > >     cpu->core = topo.core_id;
> > > 
> > >     if (cpu->thread != -1 && cpu->thread != topo.smt_id) {
> > >         error_setg(errp, "CPU thread ID mismatch: ...");
> > >         return;
> > >     }
> > >     cpu->thread = topo.smt_id;
> > > 
> > > We could do that inside x86_cpu_realizefn(), so that
> > > socket/core/thread would be always set in all CPUs.
> > all CPUs pass through pc_cpu_pre_plug() before cpu.relizefn()
> > so I'd rather do it here at board level responsible for
> > setting apic_id or socket/core/thread info is not set.
> 
> Then *-user will be inconsistent, and will always have invalid
> values in socket/core/thread. If one day we add any logic using
> the socket/core/thread properties in cpu.c, it will break on
> *-user.
> 
> All those properties are X86CPU properties, meaning they are
> input to the X86CPU code. I don't see why we should move logic
> related to them outside cpu.c unless really necessary.
> 
> (The apic-id calculation at patch 07/11, for example, is more
> difficult to move to cpu.c, because the PC code needs the APIC ID
> before calling realize. We could move it to the apic-id getter,
> but I dislike having magic getter/setters and like that you made
> it a static property.)
set of socket/core/thread is a synonym for apic_id and it's board that
manages and knows valid values for them. Putting above snippet into
cpu.relizefn() would make CPU access globals smp_cores, smp_threads
which are essentially machine_state and Drew working on moving them
there and eliminating globals. So suddenly CPU would need to poke into
machine object, and we return to the same state wrt *-user only with
hack in cpu.c.

I'd worry about -smp and *-user when it comes into that target as it
will probably need apic_id and maybe socket/core/thread as well.
Eduardo Habkost June 23, 2016, 9:43 p.m. UTC | #5
On Thu, Jun 23, 2016 at 10:46:36PM +0200, Igor Mammedov wrote:
> On Thu, 23 Jun 2016 17:18:46 -0300
> Eduardo Habkost <ehabkost@redhat.com> wrote:
[...]
> > > 
> > > > 
> > > > I suggest validating the properties, and setting them in case
> > > > they are not set:
> > > > 
> > > >     x86_topo_ids_from_apicid(cpu->apic_id, smp_cores, smp_threads,
> > > > &topo);
> > > > 
> > > >     if (cpu->socket != -1 && cpu->socket != topo.socket_id) {
> > > >         error_setg(errp, "CPU socket ID mismatch: ...");
> > > >         return;
> > > >     }
> > > >     cpu->socket = topo.socket_id;
> > > > 
> > > >     if (cpu->core != -1 && cpu->core != topo.core_id) {
> > > >         error_setg(errp, "CPU core ID mismatch: ...");
> > > >         return;
> > > >     }
> > > >     cpu->core = topo.core_id;
> > > > 
> > > >     if (cpu->thread != -1 && cpu->thread != topo.smt_id) {
> > > >         error_setg(errp, "CPU thread ID mismatch: ...");
> > > >         return;
> > > >     }
> > > >     cpu->thread = topo.smt_id;
> > > > 
> > > > We could do that inside x86_cpu_realizefn(), so that
> > > > socket/core/thread would be always set in all CPUs.
> > > all CPUs pass through pc_cpu_pre_plug() before cpu.relizefn()
> > > so I'd rather do it here at board level responsible for
> > > setting apic_id or socket/core/thread info is not set.
> > 
> > Then *-user will be inconsistent, and will always have invalid
> > values in socket/core/thread. If one day we add any logic using
> > the socket/core/thread properties in cpu.c, it will break on
> > *-user.
> > 
> > All those properties are X86CPU properties, meaning they are
> > input to the X86CPU code. I don't see why we should move logic
> > related to them outside cpu.c unless really necessary.
> > 
> > (The apic-id calculation at patch 07/11, for example, is more
> > difficult to move to cpu.c, because the PC code needs the APIC ID
> > before calling realize. We could move it to the apic-id getter,
> > but I dislike having magic getter/setters and like that you made
> > it a static property.)
> set of socket/core/thread is a synonym for apic_id and it's board that
> manages and knows valid values for them.

The CPU already knows exactly what the bits inside APIC ID mean,
because it has to report topology information through CPUID.

> Putting above snippet into
> cpu.relizefn() would make CPU access globals smp_cores, smp_threads
> which are essentially machine_state and Drew working on moving them
> there and eliminating globals. So suddenly CPU would need to poke into
> machine object, and we return to the same state wrt *-user only with
> hack in cpu.c.

After Drew's code is included, we can simply use
CPUState::nr_cores and CPUState::nr_threads.

> 
> I'd worry about -smp and *-user when it comes into that target as it
> will probably need apic_id and maybe socket/core/thread as well.

The point is to not even have to worry about *-user later, by
keeping both softmmu and *-user consistent. People reviewing
patches a few years from now probably wouldn't even notice that
code using the socket/core/thread fields will break in *-user.

I wouldn't mind about having the code in pc.c at all, if it
didn't make *-user inconsistent, or if the CPU object didn't had
all the required information yet. But I don't think it is
reasonable to intentionally leave X86CPU fields inconsistent in
*-user if we can easily fix it by moving initialization to
realizefn.

But if you are really strongly against that, I can propose that
as a follow-up later (after Drew's series is included).
Igor Mammedov June 24, 2016, 5:23 a.m. UTC | #6
On Thu, 23 Jun 2016 18:43:53 -0300
Eduardo Habkost <ehabkost@redhat.com> wrote:

> On Thu, Jun 23, 2016 at 10:46:36PM +0200, Igor Mammedov wrote:
> > On Thu, 23 Jun 2016 17:18:46 -0300
> > Eduardo Habkost <ehabkost@redhat.com> wrote:
> [...]
> > > > 
> > > > > 
> > > > > I suggest validating the properties, and setting them in case
> > > > > they are not set:
> > > > > 
> > > > >     x86_topo_ids_from_apicid(cpu->apic_id, smp_cores,
> > > > > smp_threads, &topo);
> > > > > 
> > > > >     if (cpu->socket != -1 && cpu->socket != topo.socket_id) {
> > > > >         error_setg(errp, "CPU socket ID mismatch: ...");
> > > > >         return;
> > > > >     }
> > > > >     cpu->socket = topo.socket_id;
> > > > > 
> > > > >     if (cpu->core != -1 && cpu->core != topo.core_id) {
> > > > >         error_setg(errp, "CPU core ID mismatch: ...");
> > > > >         return;
> > > > >     }
> > > > >     cpu->core = topo.core_id;
> > > > > 
> > > > >     if (cpu->thread != -1 && cpu->thread != topo.smt_id) {
> > > > >         error_setg(errp, "CPU thread ID mismatch: ...");
> > > > >         return;
> > > > >     }
> > > > >     cpu->thread = topo.smt_id;
> > > > > 
> > > > > We could do that inside x86_cpu_realizefn(), so that
> > > > > socket/core/thread would be always set in all CPUs.
> > > > all CPUs pass through pc_cpu_pre_plug() before cpu.relizefn()
> > > > so I'd rather do it here at board level responsible for
> > > > setting apic_id or socket/core/thread info is not set.
> > > 
> > > Then *-user will be inconsistent, and will always have invalid
> > > values in socket/core/thread. If one day we add any logic using
> > > the socket/core/thread properties in cpu.c, it will break on
> > > *-user.
> > > 
> > > All those properties are X86CPU properties, meaning they are
> > > input to the X86CPU code. I don't see why we should move logic
> > > related to them outside cpu.c unless really necessary.
> > > 
> > > (The apic-id calculation at patch 07/11, for example, is more
> > > difficult to move to cpu.c, because the PC code needs the APIC ID
> > > before calling realize. We could move it to the apic-id getter,
> > > but I dislike having magic getter/setters and like that you made
> > > it a static property.)
> > set of socket/core/thread is a synonym for apic_id and it's board
> > that manages and knows valid values for them.
> 
> The CPU already knows exactly what the bits inside APIC ID mean,
> because it has to report topology information through CPUID.
> 
> > Putting above snippet into
> > cpu.relizefn() would make CPU access globals smp_cores, smp_threads
> > which are essentially machine_state and Drew working on moving them
> > there and eliminating globals. So suddenly CPU would need to poke
> > into machine object, and we return to the same state wrt *-user
> > only with hack in cpu.c.
> 
> After Drew's code is included, we can simply use
> CPUState::nr_cores and CPUState::nr_threads.
> 
> > 
> > I'd worry about -smp and *-user when it comes into that target as it
> > will probably need apic_id and maybe socket/core/thread as well.
> 
> The point is to not even have to worry about *-user later, by
> keeping both softmmu and *-user consistent. People reviewing
> patches a few years from now probably wouldn't even notice that
> code using the socket/core/thread fields will break in *-user.
> 
> I wouldn't mind about having the code in pc.c at all, if it
> didn't make *-user inconsistent, or if the CPU object didn't had
> all the required information yet. But I don't think it is
> reasonable to intentionally leave X86CPU fields inconsistent in
> *-user if we can easily fix it by moving initialization to
> realizefn.
> 
> But if you are really strongly against that, I can propose that
> as a follow-up later (after Drew's series is included).
Lets do it as follow-up after Drew's -smp refactoring is in.
diff mbox

Patch

diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 6ba6343..87352ae 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -1775,6 +1775,18 @@  static void pc_cpu_pre_plug(HotplugHandler *hotplug_dev,
                    cpu->apic_id);
         return;
     }
+
+    /* set 'address' properties socket/core/thread for initial and cpu-add
+     * added CPUs so that query_hotpluggable_cpus would show correct values
+     */
+    if (cpu->thread == -1 || cpu->core == -1 || cpu->socket == -1) {
+        X86CPUTopoInfo topo;
+
+        x86_topo_ids_from_apicid(cpu->apic_id, smp_cores, smp_threads, &topo);
+        cpu->thread = topo.smt_id;
+        cpu->core = topo.core_id;
+        cpu->socket = topo.pkg_id;
+    }
 }
 
 static void pc_machine_device_pre_plug_cb(HotplugHandler *hotplug_dev,
diff --git a/target-i386/cpu.c b/target-i386/cpu.c
index 9294b3d..8c651f2 100644
--- a/target-i386/cpu.c
+++ b/target-i386/cpu.c
@@ -3186,6 +3186,9 @@  static Property x86_cpu_properties[] = {
     DEFINE_PROP_UINT32("xlevel2", X86CPU, env.cpuid_xlevel2, 0),
     DEFINE_PROP_STRING("hv-vendor-id", X86CPU, hyperv_vendor_id),
     DEFINE_PROP_BOOL("cpuid-0xb", X86CPU, enable_cpuid_0xb, true),
+    DEFINE_PROP_INT32("thread", X86CPU, thread, -1),
+    DEFINE_PROP_INT32("core", X86CPU, core, -1),
+    DEFINE_PROP_INT32("socket", X86CPU, socket, -1),
     DEFINE_PROP_END_OF_LIST()
 };
 
diff --git a/target-i386/cpu.h b/target-i386/cpu.h
index 8b09cfa..a04d334 100644
--- a/target-i386/cpu.h
+++ b/target-i386/cpu.h
@@ -1190,6 +1190,10 @@  struct X86CPU {
     Notifier machine_done;
 
     struct kvm_msrs *kvm_msr_buf;
+
+    int32_t socket;
+    int32_t core;
+    int32_t thread;
 };
 
 static inline X86CPU *x86_env_get_cpu(CPUX86State *env)