Re: [Qemu-devel] [RFC PATCH v1 06/13] spapr: CPU hotplug support

2015-01-29 Thread Bharata B Rao
On Fri, Jan 23, 2015 at 01:41:38PM +0100, Igor Mammedov wrote:
 On Thu,  8 Jan 2015 11:40:13 +0530
 Bharata B Rao bhar...@linux.vnet.ibm.com wrote:
 
  Support CPU hotplug via device-add command. Use the exising EPOW event
  infrastructure to send CPU hotplug notification to the guest.
  
  Signed-off-by: Bharata B Rao bhar...@linux.vnet.ibm.com
  ---
   hw/ppc/spapr.c  | 205 
  +++-
   hw/ppc/spapr_events.c   |   8 +-
   target-ppc/translate_init.c |   6 ++
   3 files changed, 215 insertions(+), 4 deletions(-)
  
  diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
  index 515d770..a293a59 100644
  --- a/hw/ppc/spapr.c
  +++ b/hw/ppc/spapr.c
  @@ -330,6 +330,8 @@ static void add_str(GString *s, const gchar *s1)
   g_string_append_len(s, s1, strlen(s1) + 1);
   }
   
  +uint32_t cpus_per_socket;
 static ???

Sure.

  +
  +static void spapr_cpu_plug(HotplugHandler *hotplug_dev, DeviceState *dev,
  +Error **errp)
  +{
  +Error *local_err = NULL;
  +CPUState *cs = CPU(dev);
  +PowerPCCPU *cpu = POWERPC_CPU(cs);
  +sPAPRDRConnector *drc =
  +spapr_dr_connector_by_id(SPAPR_DR_CONNECTOR_TYPE_CPU, 
  cpu-cpu_dt_id);
 just rant: does this have any relation to hotplug_dev, the point here is to 
 get
 these data from hotplug_dev object/some child of it rather then via direct 
 adhoc call.

I see how hotplug_dev is being used to pass on the plug request to ACPI, but
have to check how hotplug_dev can be used more meaningfully here.

 
  +
  +/* TODO: Check if DR is enabled ? */
  +g_assert(drc);
  +
  +spapr_cpu_reset(POWERPC_CPU(CPU(dev)));
 reset probably should be don at realize time, see x86_cpu_realizefn() for 
 example.

Yes, can be done.

 
  +spapr_cpu_hotplug_add(dev, cs);
  +spapr_hotplug_req_add_event(drc);
  +error_propagate(errp, local_err);
  +return;
  +}
  +
  +static void spapr_machine_device_plug(HotplugHandler *hotplug_dev,
  +  DeviceState *dev, Error **errp)
  +{
  +if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) {
  +if (dev-hotplugged) {
  +spapr_cpu_plug(hotplug_dev, dev, errp);
 Would be nicer if this could do cold-plugged CPUs wiring too.

Yes, will check and see how intrusive change that would be.

  diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c
  index 9c642a5..cf9d8d3 100644
  --- a/target-ppc/translate_init.c
  +++ b/target-ppc/translate_init.c
  @@ -32,6 +32,7 @@
   #include hw/qdev-properties.h
   #include hw/ppc/spapr.h
   #include hw/ppc/ppc.h
  +#include sysemu/sysemu.h
   
   //#define PPC_DUMP_CPU
   //#define PPC_DEBUG_SPR
  @@ -8909,6 +8910,11 @@ static void ppc_cpu_realizefn(DeviceState *dev, 
  Error **errp)
   return;
   }
   
  +if (cs-cpu_index = max_cpus) {
 pls note that cpu_index is monotonically increases, so when you do unplug
 and then plug it will go above max_cpus or the same will happen if
 one device_add fails in the middle, the next CPU add will fail because of
 cs-cpu_index goes overboard.
 
 I'd suggest not to rely/use cpu_index for any purposes and use other means
 to identify where cpu is plugged in. On x68 we slowly getting rid of this
 dependency in favor of apic_id (topology information), eventually it could
 become:
   -device cpu_foo,socket=X,core=Y[,thread=Z][,node=N]
 
 you probably could do the same.
 It doesn't have to be in this series, just be aware of potential issues.

I see your point and this needs to be fixed as I see this causing problems
with CPU removal (from the middle) and subsequent addition (which makes
use of vcpu fd parking and reuse mechanism).

Thanks for your review.

Regards,
Bharata.




Re: [Qemu-devel] [RFC PATCH v1 06/13] spapr: CPU hotplug support

2015-01-28 Thread David Gibson
On Thu, Jan 08, 2015 at 11:40:13AM +0530, Bharata B Rao wrote:
 Support CPU hotplug via device-add command. Use the exising EPOW event
 infrastructure to send CPU hotplug notification to the guest.
 
 Signed-off-by: Bharata B Rao bhar...@linux.vnet.ibm.com
 ---
  hw/ppc/spapr.c  | 205 
 +++-
  hw/ppc/spapr_events.c   |   8 +-
  target-ppc/translate_init.c |   6 ++
  3 files changed, 215 insertions(+), 4 deletions(-)
 
 diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
 index 515d770..a293a59 100644
 --- a/hw/ppc/spapr.c
 +++ b/hw/ppc/spapr.c
 @@ -330,6 +330,8 @@ static void add_str(GString *s, const gchar *s1)
  g_string_append_len(s, s1, strlen(s1) + 1);
  }
  
 +uint32_t cpus_per_socket;
 +
  static void *spapr_create_fdt_skel(hwaddr initrd_base,
 hwaddr initrd_size,
 hwaddr kernel_size,
 @@ -350,9 +352,9 @@ static void *spapr_create_fdt_skel(hwaddr initrd_base,
  unsigned char vec5[] = {0x0, 0x0, 0x0, 0x0, 0x0, 0x80};
  QemuOpts *opts = qemu_opts_find(qemu_find_opts(smp-opts), NULL);
  unsigned sockets = opts ? qemu_opt_get_number(opts, sockets, 0) : 0;
 -uint32_t cpus_per_socket = sockets ? (smp_cpus / sockets) : 1;
  char *buf;
  
 +cpus_per_socket = sockets ? (smp_cpus / sockets) : 1;
  add_str(hypertas, hcall-pft);
  add_str(hypertas, hcall-term);
  add_str(hypertas, hcall-dabr);
 @@ -1744,12 +1746,209 @@ static void spapr_nmi(NMIState *n, int cpu_index, 
 Error **errp)
  }
  }
  
 +/* TODO: Duplicates code from spapr_create_fdt_skel(), Fix this */

Uh, yeah, you should fix this.  I think you probably want to move the
filling out of the cpu dt information from create_fdt_skel() to
finalize_fdt(), then you should be able to use a common helper function.

 +static void spapr_populate_cpu_dt(CPUState *cs, void *fdt, int offset,
 +int drc_index)
 +{
 +PowerPCCPU *cpu = POWERPC_CPU(cs);
 +CPUPPCState *env = cpu-env;
 +PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cs);
 +int index = ppc_get_vcpu_dt_id(cpu);
 +uint32_t segs[] = {cpu_to_be32(28), cpu_to_be32(40),
 +   0x, 0x};
 +uint32_t tbfreq = kvm_enabled() ? kvmppc_get_tbfreq() : TIMEBASE_FREQ;
 +uint32_t cpufreq = kvm_enabled() ? kvmppc_get_clockfreq() : 10;
 +uint32_t page_sizes_prop[64];
 +size_t page_sizes_prop_size;
 +int smpt = ppc_get_compat_smt_threads(cpu);
 +uint32_t servers_prop[smpt];
 +uint32_t gservers_prop[smpt * 2];
 +int i;
 +uint32_t pft_size_prop[] = {0, cpu_to_be32(spapr-htab_shift)};
 +uint32_t associativity[] = {cpu_to_be32(0x5),
 +cpu_to_be32(0x0),
 +cpu_to_be32(0x0),
 +cpu_to_be32(0x0),
 +cpu_to_be32(cs-numa_node),
 +cpu_to_be32(index)};
 +
 +_FDT((fdt_setprop_cell(fdt, offset, reg, index)));
 +_FDT((fdt_setprop_string(fdt, offset, device_type, cpu)));
 +
 +_FDT((fdt_setprop_cell(fdt, offset, cpu-version, env-spr[SPR_PVR])));
 +_FDT((fdt_setprop_cell(fdt, offset, d-cache-block-size,
 +env-dcache_line_size)));
 +_FDT((fdt_setprop_cell(fdt, offset, d-cache-line-size,
 +env-dcache_line_size)));
 +_FDT((fdt_setprop_cell(fdt, offset, i-cache-block-size,
 +env-icache_line_size)));
 +_FDT((fdt_setprop_cell(fdt, offset, i-cache-line-size,
 +env-icache_line_size)));
 +
 +if (pcc-l1_dcache_size) {
 +_FDT((fdt_setprop_cell(fdt, offset, d-cache-size,
 +pcc-l1_dcache_size)));
 +} else {
 +fprintf(stderr, Warning: Unknown L1 dcache size for cpu\n);
 +}
 +if (pcc-l1_icache_size) {
 +_FDT((fdt_setprop_cell(fdt, offset, i-cache-size,
 +pcc-l1_icache_size)));
 +} else {
 +fprintf(stderr, Warning: Unknown L1 icache size for cpu\n);
 +}
 +
 +_FDT((fdt_setprop_cell(fdt, offset, timebase-frequency, tbfreq)));
 +_FDT((fdt_setprop_cell(fdt, offset, clock-frequency, cpufreq)));
 +_FDT((fdt_setprop_cell(fdt, offset, ibm,slb-size, env-slb_nr)));
 +_FDT((fdt_setprop_string(fdt, offset, status, okay)));
 +_FDT((fdt_setprop(fdt, offset, 64-bit, NULL, 0)));
 +
 +if (env-spr_cb[SPR_PURR].oea_read) {
 +_FDT((fdt_setprop(fdt, offset, ibm,purr, NULL, 0)));
 +}
 +
 +if (env-mmu_model  POWERPC_MMU_1TSEG) {
 +_FDT((fdt_setprop(fdt, offset, ibm,processor-segment-sizes,
 +   segs, sizeof(segs;
 +}
 +
 +/* Advertise VMX/VSX (vector extensions) if available
 + *   0 / no property == no vector extensions
 + *   1   == VMX / Altivec available
 + *   2   == VSX available */
 +if (env-insns_flags  PPC_ALTIVEC) {
 + 

Re: [Qemu-devel] [RFC PATCH v1 06/13] spapr: CPU hotplug support

2015-01-27 Thread Bharata B Rao
On Thu, Jan 22, 2015 at 04:16:01PM -0600, Michael Roth wrote:
 Quoting Bharata B Rao (2015-01-08 00:10:13)
  +static void spapr_machine_device_plug(HotplugHandler *hotplug_dev,
  +  DeviceState *dev, Error **errp)
  +{
  +if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) {
  +if (dev-hotplugged) {
 
 Maybe just
 
if (dev-hotplugged  spapr-dr_cpu_enabled) {
...
 
 Would do it

This is a common -plug() handler and would be used for memory too. Hence
there is a need to identify the type of object (CPU or memory) and handle it
differently.

Regards,
Bharata.




Re: [Qemu-devel] [RFC PATCH v1 06/13] spapr: CPU hotplug support

2015-01-27 Thread Michael Roth
Quoting Bharata B Rao (2015-01-27 22:19:56)
 On Thu, Jan 22, 2015 at 04:16:01PM -0600, Michael Roth wrote:
  Quoting Bharata B Rao (2015-01-08 00:10:13)
   +static void spapr_machine_device_plug(HotplugHandler *hotplug_dev,
   +  DeviceState *dev, Error **errp)
   +{
   +if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) {
   +if (dev-hotplugged) {
  
  Maybe just
  
 if (dev-hotplugged  spapr-dr_cpu_enabled) {
 ...
  
  Would do it
 
 This is a common -plug() handler and would be used for memory too. Hence
 there is a need to identify the type of object (CPU or memory) and handle it
 differently.

I mean in terms of the /* TODO: Check if DR is enabled ? */. Adding this
check here, as well as during spapr_dr_connector_new(), should cover all
the cases where the value needs to be checked AFAICT.

 
 Regards,
 Bharata.




Re: [Qemu-devel] [RFC PATCH v1 06/13] spapr: CPU hotplug support

2015-01-23 Thread Igor Mammedov
On Thu,  8 Jan 2015 11:40:13 +0530
Bharata B Rao bhar...@linux.vnet.ibm.com wrote:

 Support CPU hotplug via device-add command. Use the exising EPOW event
 infrastructure to send CPU hotplug notification to the guest.
 
 Signed-off-by: Bharata B Rao bhar...@linux.vnet.ibm.com
 ---
  hw/ppc/spapr.c  | 205 
 +++-
  hw/ppc/spapr_events.c   |   8 +-
  target-ppc/translate_init.c |   6 ++
  3 files changed, 215 insertions(+), 4 deletions(-)
 
 diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
 index 515d770..a293a59 100644
 --- a/hw/ppc/spapr.c
 +++ b/hw/ppc/spapr.c
 @@ -330,6 +330,8 @@ static void add_str(GString *s, const gchar *s1)
  g_string_append_len(s, s1, strlen(s1) + 1);
  }
  
 +uint32_t cpus_per_socket;
static ???

 +
  static void *spapr_create_fdt_skel(hwaddr initrd_base,
 hwaddr initrd_size,
 hwaddr kernel_size,
 @@ -350,9 +352,9 @@ static void *spapr_create_fdt_skel(hwaddr initrd_base,
  unsigned char vec5[] = {0x0, 0x0, 0x0, 0x0, 0x0, 0x80};
  QemuOpts *opts = qemu_opts_find(qemu_find_opts(smp-opts), NULL);
  unsigned sockets = opts ? qemu_opt_get_number(opts, sockets, 0) : 0;
 -uint32_t cpus_per_socket = sockets ? (smp_cpus / sockets) : 1;
  char *buf;
  
 +cpus_per_socket = sockets ? (smp_cpus / sockets) : 1;
  add_str(hypertas, hcall-pft);
  add_str(hypertas, hcall-term);
  add_str(hypertas, hcall-dabr);
 @@ -1744,12 +1746,209 @@ static void spapr_nmi(NMIState *n, int cpu_index, 
 Error **errp)
  }
  }
  
 +/* TODO: Duplicates code from spapr_create_fdt_skel(), Fix this */
 +static void spapr_populate_cpu_dt(CPUState *cs, void *fdt, int offset,
 +int drc_index)
 +{
 +PowerPCCPU *cpu = POWERPC_CPU(cs);
 +CPUPPCState *env = cpu-env;
 +PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cs);
 +int index = ppc_get_vcpu_dt_id(cpu);
 +uint32_t segs[] = {cpu_to_be32(28), cpu_to_be32(40),
 +   0x, 0x};
 +uint32_t tbfreq = kvm_enabled() ? kvmppc_get_tbfreq() : TIMEBASE_FREQ;
 +uint32_t cpufreq = kvm_enabled() ? kvmppc_get_clockfreq() : 10;
 +uint32_t page_sizes_prop[64];
 +size_t page_sizes_prop_size;
 +int smpt = ppc_get_compat_smt_threads(cpu);
 +uint32_t servers_prop[smpt];
 +uint32_t gservers_prop[smpt * 2];
 +int i;
 +uint32_t pft_size_prop[] = {0, cpu_to_be32(spapr-htab_shift)};
 +uint32_t associativity[] = {cpu_to_be32(0x5),
 +cpu_to_be32(0x0),
 +cpu_to_be32(0x0),
 +cpu_to_be32(0x0),
 +cpu_to_be32(cs-numa_node),
 +cpu_to_be32(index)};
 +
 +_FDT((fdt_setprop_cell(fdt, offset, reg, index)));
 +_FDT((fdt_setprop_string(fdt, offset, device_type, cpu)));
 +
 +_FDT((fdt_setprop_cell(fdt, offset, cpu-version, env-spr[SPR_PVR])));
 +_FDT((fdt_setprop_cell(fdt, offset, d-cache-block-size,
 +env-dcache_line_size)));
 +_FDT((fdt_setprop_cell(fdt, offset, d-cache-line-size,
 +env-dcache_line_size)));
 +_FDT((fdt_setprop_cell(fdt, offset, i-cache-block-size,
 +env-icache_line_size)));
 +_FDT((fdt_setprop_cell(fdt, offset, i-cache-line-size,
 +env-icache_line_size)));
 +
 +if (pcc-l1_dcache_size) {
 +_FDT((fdt_setprop_cell(fdt, offset, d-cache-size,
 +pcc-l1_dcache_size)));
 +} else {
 +fprintf(stderr, Warning: Unknown L1 dcache size for cpu\n);
 +}
 +if (pcc-l1_icache_size) {
 +_FDT((fdt_setprop_cell(fdt, offset, i-cache-size,
 +pcc-l1_icache_size)));
 +} else {
 +fprintf(stderr, Warning: Unknown L1 icache size for cpu\n);
 +}
 +
 +_FDT((fdt_setprop_cell(fdt, offset, timebase-frequency, tbfreq)));
 +_FDT((fdt_setprop_cell(fdt, offset, clock-frequency, cpufreq)));
 +_FDT((fdt_setprop_cell(fdt, offset, ibm,slb-size, env-slb_nr)));
 +_FDT((fdt_setprop_string(fdt, offset, status, okay)));
 +_FDT((fdt_setprop(fdt, offset, 64-bit, NULL, 0)));
 +
 +if (env-spr_cb[SPR_PURR].oea_read) {
 +_FDT((fdt_setprop(fdt, offset, ibm,purr, NULL, 0)));
 +}
 +
 +if (env-mmu_model  POWERPC_MMU_1TSEG) {
 +_FDT((fdt_setprop(fdt, offset, ibm,processor-segment-sizes,
 +   segs, sizeof(segs;
 +}
 +
 +/* Advertise VMX/VSX (vector extensions) if available
 + *   0 / no property == no vector extensions
 + *   1   == VMX / Altivec available
 + *   2   == VSX available */
 +if (env-insns_flags  PPC_ALTIVEC) {
 +uint32_t vmx = (env-insns_flags2  PPC2_VSX) ? 2 : 1;
 +
 +_FDT((fdt_setprop_cell(fdt, offset, ibm,vmx, vmx)));
 +}
 +
 +/* Advertise DFP (Decimal 

Re: [Qemu-devel] [RFC PATCH v1 06/13] spapr: CPU hotplug support

2015-01-22 Thread Michael Roth
Quoting Bharata B Rao (2015-01-08 00:10:13)
 Support CPU hotplug via device-add command. Use the exising EPOW event
 infrastructure to send CPU hotplug notification to the guest.
 
 Signed-off-by: Bharata B Rao bhar...@linux.vnet.ibm.com
 ---
  hw/ppc/spapr.c  | 205 
 +++-
  hw/ppc/spapr_events.c   |   8 +-
  target-ppc/translate_init.c |   6 ++
  3 files changed, 215 insertions(+), 4 deletions(-)
 
 diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
 index 515d770..a293a59 100644
 --- a/hw/ppc/spapr.c
 +++ b/hw/ppc/spapr.c
 @@ -330,6 +330,8 @@ static void add_str(GString *s, const gchar *s1)
  g_string_append_len(s, s1, strlen(s1) + 1);
  }
 
 +uint32_t cpus_per_socket;
 +
  static void *spapr_create_fdt_skel(hwaddr initrd_base,
 hwaddr initrd_size,
 hwaddr kernel_size,
 @@ -350,9 +352,9 @@ static void *spapr_create_fdt_skel(hwaddr initrd_base,
  unsigned char vec5[] = {0x0, 0x0, 0x0, 0x0, 0x0, 0x80};
  QemuOpts *opts = qemu_opts_find(qemu_find_opts(smp-opts), NULL);
  unsigned sockets = opts ? qemu_opt_get_number(opts, sockets, 0) : 0;
 -uint32_t cpus_per_socket = sockets ? (smp_cpus / sockets) : 1;
  char *buf;
 
 +cpus_per_socket = sockets ? (smp_cpus / sockets) : 1;
  add_str(hypertas, hcall-pft);
  add_str(hypertas, hcall-term);
  add_str(hypertas, hcall-dabr);
 @@ -1744,12 +1746,209 @@ static void spapr_nmi(NMIState *n, int cpu_index, 
 Error **errp)
  }
  }
 
 +/* TODO: Duplicates code from spapr_create_fdt_skel(), Fix this */
 +static void spapr_populate_cpu_dt(CPUState *cs, void *fdt, int offset,
 +int drc_index)
 +{
 +PowerPCCPU *cpu = POWERPC_CPU(cs);
 +CPUPPCState *env = cpu-env;
 +PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cs);
 +int index = ppc_get_vcpu_dt_id(cpu);
 +uint32_t segs[] = {cpu_to_be32(28), cpu_to_be32(40),
 +   0x, 0x};
 +uint32_t tbfreq = kvm_enabled() ? kvmppc_get_tbfreq() : TIMEBASE_FREQ;
 +uint32_t cpufreq = kvm_enabled() ? kvmppc_get_clockfreq() : 10;
 +uint32_t page_sizes_prop[64];
 +size_t page_sizes_prop_size;
 +int smpt = ppc_get_compat_smt_threads(cpu);
 +uint32_t servers_prop[smpt];
 +uint32_t gservers_prop[smpt * 2];
 +int i;
 +uint32_t pft_size_prop[] = {0, cpu_to_be32(spapr-htab_shift)};
 +uint32_t associativity[] = {cpu_to_be32(0x5),
 +cpu_to_be32(0x0),
 +cpu_to_be32(0x0),
 +cpu_to_be32(0x0),
 +cpu_to_be32(cs-numa_node),
 +cpu_to_be32(index)};
 +
 +_FDT((fdt_setprop_cell(fdt, offset, reg, index)));
 +_FDT((fdt_setprop_string(fdt, offset, device_type, cpu)));
 +
 +_FDT((fdt_setprop_cell(fdt, offset, cpu-version, env-spr[SPR_PVR])));
 +_FDT((fdt_setprop_cell(fdt, offset, d-cache-block-size,
 +env-dcache_line_size)));
 +_FDT((fdt_setprop_cell(fdt, offset, d-cache-line-size,
 +env-dcache_line_size)));
 +_FDT((fdt_setprop_cell(fdt, offset, i-cache-block-size,
 +env-icache_line_size)));
 +_FDT((fdt_setprop_cell(fdt, offset, i-cache-line-size,
 +env-icache_line_size)));
 +
 +if (pcc-l1_dcache_size) {
 +_FDT((fdt_setprop_cell(fdt, offset, d-cache-size,
 +pcc-l1_dcache_size)));
 +} else {
 +fprintf(stderr, Warning: Unknown L1 dcache size for cpu\n);
 +}
 +if (pcc-l1_icache_size) {
 +_FDT((fdt_setprop_cell(fdt, offset, i-cache-size,
 +pcc-l1_icache_size)));
 +} else {
 +fprintf(stderr, Warning: Unknown L1 icache size for cpu\n);
 +}
 +
 +_FDT((fdt_setprop_cell(fdt, offset, timebase-frequency, tbfreq)));
 +_FDT((fdt_setprop_cell(fdt, offset, clock-frequency, cpufreq)));
 +_FDT((fdt_setprop_cell(fdt, offset, ibm,slb-size, env-slb_nr)));
 +_FDT((fdt_setprop_string(fdt, offset, status, okay)));
 +_FDT((fdt_setprop(fdt, offset, 64-bit, NULL, 0)));
 +
 +if (env-spr_cb[SPR_PURR].oea_read) {
 +_FDT((fdt_setprop(fdt, offset, ibm,purr, NULL, 0)));
 +}
 +
 +if (env-mmu_model  POWERPC_MMU_1TSEG) {
 +_FDT((fdt_setprop(fdt, offset, ibm,processor-segment-sizes,
 +   segs, sizeof(segs;
 +}
 +
 +/* Advertise VMX/VSX (vector extensions) if available
 + *   0 / no property == no vector extensions
 + *   1   == VMX / Altivec available
 + *   2   == VSX available */
 +if (env-insns_flags  PPC_ALTIVEC) {
 +uint32_t vmx = (env-insns_flags2  PPC2_VSX) ? 2 : 1;
 +
 +_FDT((fdt_setprop_cell(fdt, offset, ibm,vmx, vmx)));
 +}
 +
 +/* Advertise DFP (Decimal Floating Point) if available
 + *   0 / no property == no 

[Qemu-devel] [RFC PATCH v1 06/13] spapr: CPU hotplug support

2015-01-07 Thread Bharata B Rao
Support CPU hotplug via device-add command. Use the exising EPOW event
infrastructure to send CPU hotplug notification to the guest.

Signed-off-by: Bharata B Rao bhar...@linux.vnet.ibm.com
---
 hw/ppc/spapr.c  | 205 +++-
 hw/ppc/spapr_events.c   |   8 +-
 target-ppc/translate_init.c |   6 ++
 3 files changed, 215 insertions(+), 4 deletions(-)

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 515d770..a293a59 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -330,6 +330,8 @@ static void add_str(GString *s, const gchar *s1)
 g_string_append_len(s, s1, strlen(s1) + 1);
 }
 
+uint32_t cpus_per_socket;
+
 static void *spapr_create_fdt_skel(hwaddr initrd_base,
hwaddr initrd_size,
hwaddr kernel_size,
@@ -350,9 +352,9 @@ static void *spapr_create_fdt_skel(hwaddr initrd_base,
 unsigned char vec5[] = {0x0, 0x0, 0x0, 0x0, 0x0, 0x80};
 QemuOpts *opts = qemu_opts_find(qemu_find_opts(smp-opts), NULL);
 unsigned sockets = opts ? qemu_opt_get_number(opts, sockets, 0) : 0;
-uint32_t cpus_per_socket = sockets ? (smp_cpus / sockets) : 1;
 char *buf;
 
+cpus_per_socket = sockets ? (smp_cpus / sockets) : 1;
 add_str(hypertas, hcall-pft);
 add_str(hypertas, hcall-term);
 add_str(hypertas, hcall-dabr);
@@ -1744,12 +1746,209 @@ static void spapr_nmi(NMIState *n, int cpu_index, 
Error **errp)
 }
 }
 
+/* TODO: Duplicates code from spapr_create_fdt_skel(), Fix this */
+static void spapr_populate_cpu_dt(CPUState *cs, void *fdt, int offset,
+int drc_index)
+{
+PowerPCCPU *cpu = POWERPC_CPU(cs);
+CPUPPCState *env = cpu-env;
+PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cs);
+int index = ppc_get_vcpu_dt_id(cpu);
+uint32_t segs[] = {cpu_to_be32(28), cpu_to_be32(40),
+   0x, 0x};
+uint32_t tbfreq = kvm_enabled() ? kvmppc_get_tbfreq() : TIMEBASE_FREQ;
+uint32_t cpufreq = kvm_enabled() ? kvmppc_get_clockfreq() : 10;
+uint32_t page_sizes_prop[64];
+size_t page_sizes_prop_size;
+int smpt = ppc_get_compat_smt_threads(cpu);
+uint32_t servers_prop[smpt];
+uint32_t gservers_prop[smpt * 2];
+int i;
+uint32_t pft_size_prop[] = {0, cpu_to_be32(spapr-htab_shift)};
+uint32_t associativity[] = {cpu_to_be32(0x5),
+cpu_to_be32(0x0),
+cpu_to_be32(0x0),
+cpu_to_be32(0x0),
+cpu_to_be32(cs-numa_node),
+cpu_to_be32(index)};
+
+_FDT((fdt_setprop_cell(fdt, offset, reg, index)));
+_FDT((fdt_setprop_string(fdt, offset, device_type, cpu)));
+
+_FDT((fdt_setprop_cell(fdt, offset, cpu-version, env-spr[SPR_PVR])));
+_FDT((fdt_setprop_cell(fdt, offset, d-cache-block-size,
+env-dcache_line_size)));
+_FDT((fdt_setprop_cell(fdt, offset, d-cache-line-size,
+env-dcache_line_size)));
+_FDT((fdt_setprop_cell(fdt, offset, i-cache-block-size,
+env-icache_line_size)));
+_FDT((fdt_setprop_cell(fdt, offset, i-cache-line-size,
+env-icache_line_size)));
+
+if (pcc-l1_dcache_size) {
+_FDT((fdt_setprop_cell(fdt, offset, d-cache-size,
+pcc-l1_dcache_size)));
+} else {
+fprintf(stderr, Warning: Unknown L1 dcache size for cpu\n);
+}
+if (pcc-l1_icache_size) {
+_FDT((fdt_setprop_cell(fdt, offset, i-cache-size,
+pcc-l1_icache_size)));
+} else {
+fprintf(stderr, Warning: Unknown L1 icache size for cpu\n);
+}
+
+_FDT((fdt_setprop_cell(fdt, offset, timebase-frequency, tbfreq)));
+_FDT((fdt_setprop_cell(fdt, offset, clock-frequency, cpufreq)));
+_FDT((fdt_setprop_cell(fdt, offset, ibm,slb-size, env-slb_nr)));
+_FDT((fdt_setprop_string(fdt, offset, status, okay)));
+_FDT((fdt_setprop(fdt, offset, 64-bit, NULL, 0)));
+
+if (env-spr_cb[SPR_PURR].oea_read) {
+_FDT((fdt_setprop(fdt, offset, ibm,purr, NULL, 0)));
+}
+
+if (env-mmu_model  POWERPC_MMU_1TSEG) {
+_FDT((fdt_setprop(fdt, offset, ibm,processor-segment-sizes,
+   segs, sizeof(segs;
+}
+
+/* Advertise VMX/VSX (vector extensions) if available
+ *   0 / no property == no vector extensions
+ *   1   == VMX / Altivec available
+ *   2   == VSX available */
+if (env-insns_flags  PPC_ALTIVEC) {
+uint32_t vmx = (env-insns_flags2  PPC2_VSX) ? 2 : 1;
+
+_FDT((fdt_setprop_cell(fdt, offset, ibm,vmx, vmx)));
+}
+
+/* Advertise DFP (Decimal Floating Point) if available
+ *   0 / no property == no DFP
+ *   1   == DFP available */
+if (env-insns_flags2  PPC2_DFP) {
+_FDT((fdt_setprop_cell(fdt, offset, ibm,dfp, 1)));
+}
+
+