Re: [Qemu-devel] [PATCH V3 4/7] pc: add cpu hotplug handler to PC_MACHINE

2014-09-28 Thread Gu Zheng
Hi Igor,
On 09/26/2014 09:06 PM, Igor Mammedov wrote:

> On Wed, 17 Sep 2014 09:24:00 +0800
> Gu Zheng  wrote:
> 
>> Add cpu hotplug handler to PC_MACHINE, which will perform the acpi
>> cpu hotplug callback via hotplug_handler API.
>>
>> v3:
>>  -deal with start up cpus in a more neat way as Igor suggested.
>> v2:
>>  -just rebase.
>>
>> Signed-off-by: Gu Zheng 
>> ---
>>  hw/i386/pc.c |   26 +-
>>  1 files changed, 25 insertions(+), 1 deletions(-)
>>
>> diff --git a/hw/i386/pc.c b/hw/i386/pc.c
>> index b6c9b61..e25e71b 100644
>> --- a/hw/i386/pc.c
>> +++ b/hw/i386/pc.c
>> @@ -1613,11 +1613,34 @@ out:
>>  error_propagate(errp, local_err);
>>  }
>>  
>> +static void pc_cpu_plug(HotplugHandler *hotplug_dev,
>> +DeviceState *dev, Error **errp)
>> +{
>> +HotplugHandlerClass *hhc;
>> +Error *local_err = NULL;
>> +PCMachineState *pcms = PC_MACHINE(hotplug_dev);
>> +
>> +if (!pcms->acpi_dev) {
>> +if (dev->hotplugged) {
>> +error_setg(&local_err,
>> +   "cpu hotplug is not enabled: missing acpi device");
>> +}
>> +goto out;
>> +}
>> +
>> +hhc = HOTPLUG_HANDLER_GET_CLASS(pcms->acpi_dev);
>> +hhc->plug(HOTPLUG_HANDLER(pcms->acpi_dev), dev, &local_err);
> above call this would rise SCI unconditionally whether CPU is hotplugged or 
> not.

Above precheck can avoid this, startup CPUs won't run into this: 
if (!pcms->acpi_dev) {
if (dev->hotplugged) {
error_setg(&local_err,
   "cpu hotplug is not enabled: missing acpi device");
}
goto out;
}

Thanks,
Gu

> perhaps checking for this in acpi_cpu_plug_cb() and rising IRQ only for 
> hotplugged
> CPUs would be better.
> 
>> +out:
>> +error_propagate(errp, local_err);
>> +}
>> +
>>  static void pc_machine_device_plug_cb(HotplugHandler *hotplug_dev,
>>DeviceState *dev, Error **errp)
>>  {
>>  if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
>>  pc_dimm_plug(hotplug_dev, dev, errp);
>> +} else if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) {
>> +pc_cpu_plug(hotplug_dev, dev, errp);
>>  }
>>  }
>>  
>> @@ -1626,7 +1649,8 @@ static HotplugHandler 
>> *pc_get_hotpug_handler(MachineState *machine,
>>  {
>>  PCMachineClass *pcmc = PC_MACHINE_GET_CLASS(machine);
>>  
>> -if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
>> +if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM) ||
>> +object_dynamic_cast(OBJECT(dev), TYPE_CPU)) {
>>  return HOTPLUG_HANDLER(machine);
>>  }
>>  
> 
> .
> 





Re: [Qemu-devel] [PATCH V3 5/7] pc: Update rtc_cmos in pc_cpu_plug

2014-09-28 Thread Gu Zheng
Hi Igor,
On 09/26/2014 09:23 PM, Igor Mammedov wrote:

> On Wed, 17 Sep 2014 09:24:01 +0800
> Gu Zheng  wrote:
> 
>> Update rtc_cmos in pc_cpu_plug directly instead of the notifier, with
>> this change, there will no user of CPU hot-plug notifier any more, so
>> remove it.
>>
>> Signed-off-by: Gu Zheng 
>> ---
>>  hw/i386/pc.c|   25 ++---
>>  include/sysemu/sysemu.h |3 ---
>>  qom/cpu.c   |   10 --
>>  3 files changed, 6 insertions(+), 32 deletions(-)
>>
>> diff --git a/hw/i386/pc.c b/hw/i386/pc.c
>> index e25e71b..8b887c7 100644
>> --- a/hw/i386/pc.c
>> +++ b/hw/i386/pc.c
>> @@ -353,20 +353,7 @@ static void pc_cmos_init_late(void *opaque)
>>  qemu_unregister_reset(pc_cmos_init_late, opaque);
>>  }
>>  
>> -typedef struct RTCCPUHotplugArg {
>> -Notifier cpu_added_notifier;
>> -ISADevice *rtc_state;
>> -} RTCCPUHotplugArg;
>> -
>> -static void rtc_notify_cpu_added(Notifier *notifier, void *data)
>> -{
>> -RTCCPUHotplugArg *arg = container_of(notifier, RTCCPUHotplugArg,
>> - cpu_added_notifier);
>> -ISADevice *s = arg->rtc_state;
>> -
>> -/* increment the number of CPUs */
>> -rtc_set_memory(s, 0x5f, rtc_get_memory(s, 0x5f) + 1);
>> -}
>> +static ISADevice *rtc_state;
> It's not recommended to use global variables.
> 
> Instead of make link property in PCMachine and use it pretty much like 
> acpi_dev
> is used in 4/7.

Right, this way is more reasonable and neat.

> 
>>  
>>  void pc_cmos_init(ram_addr_t ram_size, ram_addr_t above_4g_mem_size,
>>const char *boot_device,
>> @@ -376,7 +363,6 @@ void pc_cmos_init(ram_addr_t ram_size, ram_addr_t 
>> above_4g_mem_size,
>>  int val, nb, i;
>>  FDriveType fd_type[2] = { FDRIVE_DRV_NONE, FDRIVE_DRV_NONE };
>>  static pc_cmos_init_late_arg arg;
>> -static RTCCPUHotplugArg cpu_hotplug_cb;
>>  
>>  /* various important CMOS locations needed by PC/Bochs bios */
>>  
>> @@ -415,10 +401,8 @@ void pc_cmos_init(ram_addr_t ram_size, ram_addr_t 
>> above_4g_mem_size,
>>  
>>  /* set the number of CPU */
>>  rtc_set_memory(s, 0x5f, smp_cpus - 1);
>> -/* init CPU hotplug notifier */
>> -cpu_hotplug_cb.rtc_state = s;
>> -cpu_hotplug_cb.cpu_added_notifier.notify = rtc_notify_cpu_added;
>> -qemu_register_cpu_added_notifier(&cpu_hotplug_cb.cpu_added_notifier);
>> +
>> +rtc_state = s;
>>  
>>  if (set_boot_dev(s, boot_device)) {
>>  exit(1);
>> @@ -1630,6 +1614,9 @@ static void pc_cpu_plug(HotplugHandler *hotplug_dev,
>>  
>>  hhc = HOTPLUG_HANDLER_GET_CLASS(pcms->acpi_dev);
>>  hhc->plug(HOTPLUG_HANDLER(pcms->acpi_dev), dev, &local_err);
>> +
>> +/* increment the number of CPUs */
>> +rtc_set_memory(rtc_state, 0x5f, rtc_get_memory(rtc_state, 0x5f) + 1);
> looks wrong, what if error happens in plug() handler???

Ah, yes, we need to confirm the plug cb result before update rtc_state.

Thanks,
Gu

> 
>>  out:
>>  error_propagate(errp, local_err);
>>  }
>> diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h
>> index d8539fd..acfe494 100644
>> --- a/include/sysemu/sysemu.h
>> +++ b/include/sysemu/sysemu.h
>> @@ -183,9 +183,6 @@ void do_pci_device_hot_remove(Monitor *mon, const QDict 
>> *qdict);
>>  /* generic hotplug */
>>  void drive_hot_add(Monitor *mon, const QDict *qdict);
>>  
>> -/* CPU hotplug */
>> -void qemu_register_cpu_added_notifier(Notifier *notifier);
>> -
>>  /* pcie aer error injection */
>>  void pcie_aer_inject_error_print(Monitor *mon, const QObject *data);
>>  int do_pcie_aer_inject_error(Monitor *mon,
>> diff --git a/qom/cpu.c b/qom/cpu.c
>> index b32dd0a..19c5de5 100644
>> --- a/qom/cpu.c
>> +++ b/qom/cpu.c
>> @@ -107,15 +107,6 @@ static void cpu_common_get_memory_mapping(CPUState *cpu,
>>  error_setg(errp, "Obtaining memory mappings is unsupported on this 
>> CPU.");
>>  }
>>  
>> -/* CPU hot-plug notifiers */
>> -static NotifierList cpu_added_notifiers =
>> -NOTIFIER_LIST_INITIALIZER(cpu_add_notifiers);
>> -
>> -void qemu_register_cpu_added_notifier(Notifier *notifier)
>> -{
>> -notifier_list_add(&cpu_added_notifiers, notifier);
>> -}
>> -
>>  void cpu_reset_interrupt(CPUState *cpu, int mask)
>>  {
>>  cpu->interrupt_request &= ~mask;
>> @@ -303,7 +294,6 @@ static void cpu_common_realizefn(DeviceState *dev, Error 
>> **errp)
>>  
>>  if (dev->hotplugged) {
>>  cpu_synchronize_post_init(cpu);
>> -notifier_list_notify(&cpu_added_notifiers, dev);
>>  cpu_resume(cpu);
>>  }
>>  }
> 
> .
> 





Re: [Qemu-devel] [PATCH V3 7/7] acpi/cpu-hotplug: introduce help function to keep bit setting in one place

2014-09-29 Thread Gu Zheng
Hi Igor,
On 09/26/2014 09:37 PM, Igor Mammedov wrote:

> On Wed, 17 Sep 2014 09:24:03 +0800
> Gu Zheng  wrote:
> 
>> Introduce help function acpi_set_local_sts() to simplify acpi_cpu_plug_cb
>> and acpi_cpu_hotplug_init, so that we can keep bit setting in one place.
>>
>> Signed-off-by: Gu Zheng 
>> ---
>>  hw/acpi/cpu_hotplug.c |   22 +++---
>>  1 files changed, 15 insertions(+), 7 deletions(-)
>>
>> diff --git a/hw/acpi/cpu_hotplug.c b/hw/acpi/cpu_hotplug.c
>> index 7629686..d42c961 100644
>> --- a/hw/acpi/cpu_hotplug.c
>> +++ b/hw/acpi/cpu_hotplug.c
>> @@ -36,8 +36,8 @@ static const MemoryRegionOps AcpiCpuHotplug_ops = {
>>  },
>>  };
>>  
>> -void acpi_cpu_plug_cb(ACPIREGS *ar, qemu_irq irq,
>> -  AcpiCpuHotplug *g, CPUState *cpu, Error **errp)
>> +static void acpi_set_local_sts(AcpiCpuHotplug *g, CPUState *cpu,
>> +   Error **errp)
>>  {
>>  CPUClass *k = CPU_GET_CLASS(cpu);
>>  int64_t cpu_id;
>> @@ -48,9 +48,18 @@ void acpi_cpu_plug_cb(ACPIREGS *ar, qemu_irq irq,
>>  return;
>>  }
>>  
>> -ar->gpe.sts[0] |= ACPI_CPU_HOTPLUG_STATUS;
>>  g->sts[cpu_id / 8] |= (1 << (cpu_id % 8));
>> +}
>>  
>> +void acpi_cpu_plug_cb(ACPIREGS *ar, qemu_irq irq,
>> +  AcpiCpuHotplug *g, CPUState *cpu, Error **errp)
>> +{
>> +acpi_set_local_sts(g, cpu, errp);
>> +if (*errp != NULL) {
>> +return;
>> +}
>> +
> 
>> +ar->gpe.sts[0] |= ACPI_CPU_HOTPLUG_STATUS;
> ^^^ shouldn't be set for coldplugged CPUs along with IRQ below
> 
>>  acpi_update_sci(ar, irq);
>>  }
>>  
>> @@ -60,11 +69,10 @@ void acpi_cpu_hotplug_init(MemoryRegion *parent, Object 
>> *owner,
>>  CPUState *cpu;
>>  
>>  CPU_FOREACH(cpu) {
>> -CPUClass *cc = CPU_GET_CLASS(cpu);
>> -int64_t id = cc->get_arch_id(cpu);
>> +Error *local_err = NULL;
>>  
>> -g_assert((id / 8) < ACPI_GPE_PROC_LEN);
>> -gpe_cpu->sts[id / 8] |= (1 << (id % 8));
>> +acpi_set_local_sts(gpe_cpu, cpu, &local_err);
>> +g_assert(local_err == NULL);
> Wouldn't acpi_cpu_plug_cb() do everything this FOREACH does?
> I've suggest to drop CPU_FOREACH() altogether.

I got your meaning: Make acpi_cpu_plug_cb serve all CPUs (both startup and 
hotpluged)
, and only triggers sci irq for hotpluged ones, so that we can drop the 
duplicated
operations in acpi_cpu_hotplug_init.
But one problem is that pcms->acpi_dev was registered after startup CPUs set 
realized, so
acpi_cpu_plug_cb can not serve startup CPUs.
I tried to switch the order, but it failed, because there are some internal 
dependences.
Now, I'm trying to split the startup CPUs init into two steps (init and 
realize), and
register pcms->acpi_dev between the two steps.
What's your opinion?

Thanks,
Gu

> 
>>  }
>>  memory_region_init_io(&gpe_cpu->io, owner, &AcpiCpuHotplug_ops,
>>gpe_cpu, "acpi-cpu-hotplug", ACPI_GPE_PROC_LEN);
> 
> .
> 





Re: [Qemu-devel] [PATCH V3 7/7] acpi/cpu-hotplug: introduce help function to keep bit setting in one place

2014-09-29 Thread Gu Zheng
On 09/29/2014 05:47 PM, Igor Mammedov wrote:

> On Mon, 29 Sep 2014 17:22:08 +0800
> Gu Zheng  wrote:
> 
>> Hi Igor,
>> On 09/26/2014 09:37 PM, Igor Mammedov wrote:
>>
>>> On Wed, 17 Sep 2014 09:24:03 +0800
>>> Gu Zheng  wrote:
>>>
>>>> Introduce help function acpi_set_local_sts() to simplify
>>>> acpi_cpu_plug_cb and acpi_cpu_hotplug_init, so that we can keep
>>>> bit setting in one place.
>>>>
>>>> Signed-off-by: Gu Zheng 
>>>> ---
>>>>  hw/acpi/cpu_hotplug.c |   22 +++---
>>>>  1 files changed, 15 insertions(+), 7 deletions(-)
>>>>
>>>> diff --git a/hw/acpi/cpu_hotplug.c b/hw/acpi/cpu_hotplug.c
>>>> index 7629686..d42c961 100644
>>>> --- a/hw/acpi/cpu_hotplug.c
>>>> +++ b/hw/acpi/cpu_hotplug.c
>>>> @@ -36,8 +36,8 @@ static const MemoryRegionOps AcpiCpuHotplug_ops
>>>> = { },
>>>>  };
>>>>  
>>>> -void acpi_cpu_plug_cb(ACPIREGS *ar, qemu_irq irq,
>>>> -  AcpiCpuHotplug *g, CPUState *cpu, Error
>>>> **errp) +static void acpi_set_local_sts(AcpiCpuHotplug *g,
>>>> CPUState *cpu,
>>>> +   Error **errp)
>>>>  {
>>>>  CPUClass *k = CPU_GET_CLASS(cpu);
>>>>  int64_t cpu_id;
>>>> @@ -48,9 +48,18 @@ void acpi_cpu_plug_cb(ACPIREGS *ar, qemu_irq
>>>> irq, return;
>>>>  }
>>>>  
>>>> -ar->gpe.sts[0] |= ACPI_CPU_HOTPLUG_STATUS;
>>>>  g->sts[cpu_id / 8] |= (1 << (cpu_id % 8));
>>>> +}
>>>>  
>>>> +void acpi_cpu_plug_cb(ACPIREGS *ar, qemu_irq irq,
>>>> +  AcpiCpuHotplug *g, CPUState *cpu, Error
>>>> **errp) +{
>>>> +acpi_set_local_sts(g, cpu, errp);
>>>> +if (*errp != NULL) {
>>>> +return;
>>>> +}
>>>> +
>>>
>>>> +ar->gpe.sts[0] |= ACPI_CPU_HOTPLUG_STATUS;
>>> ^^^ shouldn't be set for coldplugged CPUs along with IRQ below
>>>
>>>>  acpi_update_sci(ar, irq);
>>>>  }
>>>>  
>>>> @@ -60,11 +69,10 @@ void acpi_cpu_hotplug_init(MemoryRegion
>>>> *parent, Object *owner, CPUState *cpu;
>>>>  
>>>>  CPU_FOREACH(cpu) {
>>>> -CPUClass *cc = CPU_GET_CLASS(cpu);
>>>> -int64_t id = cc->get_arch_id(cpu);
>>>> +Error *local_err = NULL;
>>>>  
>>>> -g_assert((id / 8) < ACPI_GPE_PROC_LEN);
>>>> -gpe_cpu->sts[id / 8] |= (1 << (id % 8));
>>>> +acpi_set_local_sts(gpe_cpu, cpu, &local_err);
>>>> +g_assert(local_err == NULL);
>>> Wouldn't acpi_cpu_plug_cb() do everything this FOREACH does?
>>> I've suggest to drop CPU_FOREACH() altogether.
>>
>> I got your meaning: Make acpi_cpu_plug_cb serve all CPUs (both
>> startup and hotpluged) , and only triggers sci irq for hotpluged
>> ones, so that we can drop the duplicated operations in
>> acpi_cpu_hotplug_init. But one problem is that pcms->acpi_dev was
>> registered after startup CPUs set realized, so acpi_cpu_plug_cb can
>> not serve startup CPUs. I tried to switch the order, but it failed,
>> because there are some internal dependences. Now, I'm trying to split
>> the startup CPUs init into two steps (init and realize), and register
>> pcms->acpi_dev between the two steps. What's your opinion?
> Could you point out what dependecies are there?

E.g.
Allocation smi_irq for PIIX4PMState dependents on the valid *first_cpu*.

smi_irq = qemu_allocate_irqs(pc_acpi_smi_interrupt, first_cpu, 1);
/* TODO: Populate SPD eeprom data.  */
smbus = piix4_pm_init(pci_bus, piix3_devfn + 3, 0xb100,
  gsi[9], *smi_irq,
  kvm_enabled(), fw_cfg, &piix4_pm);

Thanks,
Gu

> 
>>
>> Thanks,
>> Gu
>>
>>>
>>>>  }
>>>>  memory_region_init_io(&gpe_cpu->io, owner,
>>>> &AcpiCpuHotplug_ops, gpe_cpu, "acpi-cpu-hotplug",
>>>> ACPI_GPE_PROC_LEN);
>>>
>>> .
>>>
>>
>>
> 
> .
> 





[Qemu-devel] [PATCH V4 5/8] pc: Update rtc_cmos in pc_cpu_plug

2014-09-29 Thread Gu Zheng
Update rtc_cmos in pc_cpu_plug directly instead of the notifier.

v4:
 -Make link property in PCMachine rather than the global
  variables.
 -Split out the removal of unused notifier into separate patch.

Signed-off-by: Gu Zheng 
---
 hw/i386/pc.c |   37 -
 hw/i386/pc_piix.c|2 +-
 hw/i386/pc_q35.c |2 +-
 include/hw/i386/pc.h |3 ++-
 qom/cpu.c|1 -
 5 files changed, 20 insertions(+), 25 deletions(-)

diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index dcb9332..301e704 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -355,30 +355,15 @@ static void pc_cmos_init_late(void *opaque)
 qemu_unregister_reset(pc_cmos_init_late, opaque);
 }
 
-typedef struct RTCCPUHotplugArg {
-Notifier cpu_added_notifier;
-ISADevice *rtc_state;
-} RTCCPUHotplugArg;
-
-static void rtc_notify_cpu_added(Notifier *notifier, void *data)
-{
-RTCCPUHotplugArg *arg = container_of(notifier, RTCCPUHotplugArg,
- cpu_added_notifier);
-ISADevice *s = arg->rtc_state;
-
-/* increment the number of CPUs */
-rtc_set_memory(s, 0x5f, rtc_get_memory(s, 0x5f) + 1);
-}
-
 void pc_cmos_init(ram_addr_t ram_size, ram_addr_t above_4g_mem_size,
-  const char *boot_device,
+  const char *boot_device, MachineState *machine,
   ISADevice *floppy, BusState *idebus0, BusState *idebus1,
   ISADevice *s)
 {
 int val, nb, i;
 FDriveType fd_type[2] = { FDRIVE_DRV_NONE, FDRIVE_DRV_NONE };
 static pc_cmos_init_late_arg arg;
-static RTCCPUHotplugArg cpu_hotplug_cb;
+PCMachineState *pc_machine = PC_MACHINE(machine);
 
 /* various important CMOS locations needed by PC/Bochs bios */
 
@@ -417,10 +402,14 @@ void pc_cmos_init(ram_addr_t ram_size, ram_addr_t 
above_4g_mem_size,
 
 /* set the number of CPU */
 rtc_set_memory(s, 0x5f, smp_cpus - 1);
-/* init CPU hotplug notifier */
-cpu_hotplug_cb.rtc_state = s;
-cpu_hotplug_cb.cpu_added_notifier.notify = rtc_notify_cpu_added;
-qemu_register_cpu_added_notifier(&cpu_hotplug_cb.cpu_added_notifier);
+
+object_property_add_link(OBJECT(machine), "rtc_state",
+ TYPE_ISA_DEVICE,
+ (Object **)&pc_machine->rtc,
+ object_property_allow_set_link,
+ OBJ_PROP_LINK_UNREF_ON_RELEASE, &error_abort);
+object_property_set_link(OBJECT(machine), OBJECT(s),
+ "rtc_state", &error_abort);
 
 if (set_boot_dev(s, boot_device)) {
 exit(1);
@@ -1633,6 +1622,12 @@ static void pc_cpu_plug(HotplugHandler *hotplug_dev,
 
 hhc = HOTPLUG_HANDLER_GET_CLASS(pcms->acpi_dev);
 hhc->plug(HOTPLUG_HANDLER(pcms->acpi_dev), dev, &local_err);
+if (local_err) {
+goto out;
+}
+
+/* increment the number of CPUs */
+rtc_set_memory(pcms->rtc, 0x5f, rtc_get_memory(pcms->rtc, 0x5f) + 1);
 out:
 error_propagate(errp, local_err);
 }
diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index 103d756..2c8d4dc 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -266,7 +266,7 @@ static void pc_init1(MachineState *machine,
 }
 
 pc_cmos_init(below_4g_mem_size, above_4g_mem_size, machine->boot_order,
- floppy, idebus[0], idebus[1], rtc_state);
+ machine, floppy, idebus[0], idebus[1], rtc_state);
 
 if (pci_enabled && usb_enabled(false)) {
 pci_create_simple(pci_bus, piix3_devfn + 2, "piix3-usb-uhci");
diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c
index d4a907c..94ba98d 100644
--- a/hw/i386/pc_q35.c
+++ b/hw/i386/pc_q35.c
@@ -266,7 +266,7 @@ static void pc_q35_init(MachineState *machine)
   8, NULL, 0);
 
 pc_cmos_init(below_4g_mem_size, above_4g_mem_size, machine->boot_order,
- floppy, idebus[0], idebus[1], rtc_state);
+ machine, floppy, idebus[0], idebus[1], rtc_state);
 
 /* the rest devices to which pci devfn is automatically assigned */
 pc_vga_init(isa_bus, host_bus);
diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
index 77316d5..7a4bff4 100644
--- a/include/hw/i386/pc.h
+++ b/include/hw/i386/pc.h
@@ -33,6 +33,7 @@ struct PCMachineState {
 MemoryRegion hotplug_memory;
 
 HotplugHandler *acpi_dev;
+ISADevice *rtc;
 
 uint64_t max_ram_below_4g;
 };
@@ -210,7 +211,7 @@ void pc_basic_device_init(ISABus *isa_bus, qemu_irq *gsi,
   uint32 hpet_irqs);
 void pc_init_ne2k_isa(ISABus *bus, NICInfo *nd);
 void pc_cmos_init(ram_addr_t ram_size, ram_addr_t above_4g_mem_size,
-  const char *boot_device,
+  const char *boot_device, MachineState *machine,
   ISADevice *floppy, BusState *ide0, BusState *ide1,
   ISADevice *s);
 void pc

[Qemu-devel] [PATCH V4 1/8] acpi/cpu: add cpu hotplug callback function to match hotplug_handler API

2014-09-29 Thread Gu Zheng
v4:
 -convert CPUState *cpu to DeviceState *dev like it's done for other handlers
  and do cast to CPU inside.

v2:
 -add errp argument to catch error.
 -return error instead of aborting if cpu id is invalid.
 -make acpi_cpu_plug_cb as a wrapper around AcpiCpuHotplug_add.

Signed-off-by: Gu Zheng 
---
 hw/acpi/cpu_hotplug.c |   18 ++
 include/hw/acpi/cpu_hotplug.h |3 +++
 2 files changed, 21 insertions(+), 0 deletions(-)

diff --git a/hw/acpi/cpu_hotplug.c b/hw/acpi/cpu_hotplug.c
index 2ad83a0..06e9c61 100644
--- a/hw/acpi/cpu_hotplug.c
+++ b/hw/acpi/cpu_hotplug.c
@@ -36,6 +36,24 @@ static const MemoryRegionOps AcpiCpuHotplug_ops = {
 },
 };
 
+void acpi_cpu_plug_cb(ACPIREGS *ar, qemu_irq irq,
+  AcpiCpuHotplug *g, DeviceState *dev, Error **errp)
+{
+CPUState *cpu = CPU(dev);
+CPUClass *k = CPU_GET_CLASS(cpu);
+int64_t cpu_id;
+
+cpu_id = k->get_arch_id(cpu);
+if ((cpu_id / 8) >= ACPI_GPE_PROC_LEN) {
+error_setg(errp, "acpi: invalid cpu id: %" PRIi64, cpu_id);
+return;
+}
+
+AcpiCpuHotplug_add(&ar->gpe, g, cpu);
+
+acpi_update_sci(ar, irq);
+}
+
 void AcpiCpuHotplug_add(ACPIGPE *gpe, AcpiCpuHotplug *g, CPUState *cpu)
 {
 CPUClass *k = CPU_GET_CLASS(cpu);
diff --git a/include/hw/acpi/cpu_hotplug.h b/include/hw/acpi/cpu_hotplug.h
index 9e5d30c..5dca8d7 100644
--- a/include/hw/acpi/cpu_hotplug.h
+++ b/include/hw/acpi/cpu_hotplug.h
@@ -20,6 +20,9 @@ typedef struct AcpiCpuHotplug {
 uint8_t sts[ACPI_GPE_PROC_LEN];
 } AcpiCpuHotplug;
 
+void acpi_cpu_plug_cb(ACPIREGS *ar, qemu_irq irq,
+  AcpiCpuHotplug *g, DeviceState *dev, Error **errp);
+
 void AcpiCpuHotplug_add(ACPIGPE *gpe, AcpiCpuHotplug *g, CPUState *cpu);
 
 void AcpiCpuHotplug_init(MemoryRegion *parent, Object *owner,
-- 
1.7.7




[Qemu-devel] [PATCH V4 0/8] cpu/acpi: convert cpu hot plug to hotplug_handler API

2014-09-29 Thread Gu Zheng
Previously we use cpu_added_notifiers to register cpu hotplug notifier callback
which is not able to pass/handle errors, so we switch it to unified hotplug
handler API which allows to pass errors and would allow to cancel device_add
in case of error.
Thanks very much for Igor's review and suggestion.

v4:
 -split removal of CPU hotplug notifier into separate patch (Patch 6/8).
 Patch 1/7:
 -convert CPUState *cpu to DeviceState *dev like it's done for other handlers
  and do cast to CPU inside.
 Patch 5/7:
 -Make rtc_state as a link property in PCMachine rather than the global
  variables.
 -Split out the removal of unused notifier into separate patch.
 -Check the result of plug callback before update rtc_state.

v3:
 -deal with start-up cpus in pc_cpu_plug as Igor suggested.

v2:
 -Add 3 new patches(5/7,6/7,7/7), delete original patch 5/5.
  1/5-->1/7
  2/5-->2/7
  3/5-->3/7
  4/5-->4/7
 Patch 1/7:
 -add errp argument to catch error.
 -return error instead of aborting if cpu id is invalid.
 -make acpi_cpu_plug_cb as a wrapper around AcpiCpuHotplug_add.
 Patch 3/7:
 -remove unused AcpiCpuHotplug_add directly.
 Patch 5/7:
 -switch the last user of cpu hotplug notifier to hotplug handler API, and
  remove the unused cpu hotplug notify.
 Patch 6/7:
 -split the function rename (just cleanup) into single patch.
 Patch 7/7:
 -introduce help function acpi_set_local_sts to keep the bit setting in
  one place.

Gu Zheng (8):
  acpi/cpu: add cpu hotplug callback function to match hotplug_handler
API
  acpi:ich9: convert cpu hotplug handle to hotplug_handler API
  acpi:piix4: convert cpu hotplug handle to hotplug_handler API
  pc: add cpu hotplug handler to PC_MACHINE
  pc: Update rtc_cmos in pc_cpu_plug
  qom/cpu: remove the unused CPU hot-plug notifier
  cpu-hotplug: rename function for better readability
  acpi/cpu-hotplug: introduce help function to keep bit setting in one
place

 hw/acpi/cpu_hotplug.c |   35 --
 hw/acpi/ich9.c|   17 ++
 hw/acpi/piix4.c   |   18 ++-
 hw/i386/pc.c  |   63 ++--
 hw/i386/pc_piix.c |2 +-
 hw/i386/pc_q35.c  |2 +-
 include/hw/acpi/cpu_hotplug.h |7 ++--
 include/hw/acpi/ich9.h|1 -
 include/hw/i386/pc.h  |3 +-
 include/sysemu/sysemu.h   |3 --
 qom/cpu.c |   10 --
 11 files changed, 82 insertions(+), 79 deletions(-)

-- 
1.7.7




[Qemu-devel] [PATCH V4 2/8] acpi:ich9: convert cpu hotplug handle to hotplug_handler API

2014-09-29 Thread Gu Zheng
Convert notifier based hotplug handle to hotplug_handler API.

Signed-off-by: Gu Zheng 
---
 hw/acpi/ich9.c |   13 ++---
 include/hw/acpi/ich9.h |1 -
 2 files changed, 2 insertions(+), 12 deletions(-)

diff --git a/hw/acpi/ich9.c b/hw/acpi/ich9.c
index 7b14bbb..7585364 100644
--- a/hw/acpi/ich9.c
+++ b/hw/acpi/ich9.c
@@ -209,15 +209,6 @@ static void pm_powerdown_req(Notifier *n, void *opaque)
 acpi_pm1_evt_power_down(&pm->acpi_regs);
 }
 
-static void ich9_cpu_added_req(Notifier *n, void *opaque)
-{
-ICH9LPCPMRegs *pm = container_of(n, ICH9LPCPMRegs, cpu_added_notifier);
-
-assert(pm != NULL);
-AcpiCpuHotplug_add(&pm->acpi_regs.gpe, &pm->gpe_cpu, CPU(opaque));
-acpi_update_sci(&pm->acpi_regs, pm->irq);
-}
-
 void ich9_pm_init(PCIDevice *lpc_pci, ICH9LPCPMRegs *pm,
   qemu_irq sci_irq)
 {
@@ -246,8 +237,6 @@ void ich9_pm_init(PCIDevice *lpc_pci, ICH9LPCPMRegs *pm,
 
 AcpiCpuHotplug_init(pci_address_space_io(lpc_pci), OBJECT(lpc_pci),
 &pm->gpe_cpu, ICH9_CPU_HOTPLUG_IO_BASE);
-pm->cpu_added_notifier.notify = ich9_cpu_added_req;
-qemu_register_cpu_added_notifier(&pm->cpu_added_notifier);
 
 if (pm->acpi_memory_hotplug.is_enabled) {
 acpi_memory_hotplug_init(pci_address_space_io(lpc_pci), 
OBJECT(lpc_pci),
@@ -304,6 +293,8 @@ void ich9_pm_device_plug_cb(ICH9LPCPMRegs *pm, DeviceState 
*dev, Error **errp)
 object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
 acpi_memory_plug_cb(&pm->acpi_regs, pm->irq, &pm->acpi_memory_hotplug,
 dev, errp);
+} else if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) {
+acpi_cpu_plug_cb(&pm->acpi_regs, pm->irq, &pm->gpe_cpu, dev, errp);
 } else {
 error_setg(errp, "acpi: device plug request for not supported device"
" type: %s", object_get_typename(OBJECT(dev)));
diff --git a/include/hw/acpi/ich9.h b/include/hw/acpi/ich9.h
index 7e42448..fe975e6 100644
--- a/include/hw/acpi/ich9.h
+++ b/include/hw/acpi/ich9.h
@@ -47,7 +47,6 @@ typedef struct ICH9LPCPMRegs {
 Notifier powerdown_notifier;
 
 AcpiCpuHotplug gpe_cpu;
-Notifier cpu_added_notifier;
 
 MemHotplugState acpi_memory_hotplug;
 } ICH9LPCPMRegs;
-- 
1.7.7




[Qemu-devel] [PATCH V4 3/8] acpi:piix4: convert cpu hotplug handle to hotplug_handler API

2014-09-29 Thread Gu Zheng
Convert notifier based hotplug handle to hotplug_handler API,
and remove the unused AcpiCpuHotplug_add().

v2:
-remove the unused AcpiCpuHotplug_add().

Signed-off-by: Gu Zheng 
---
 hw/acpi/cpu_hotplug.c |   14 ++
 hw/acpi/piix4.c   |   14 ++
 include/hw/acpi/cpu_hotplug.h |2 --
 3 files changed, 4 insertions(+), 26 deletions(-)

diff --git a/hw/acpi/cpu_hotplug.c b/hw/acpi/cpu_hotplug.c
index 06e9c61..b69b16c 100644
--- a/hw/acpi/cpu_hotplug.c
+++ b/hw/acpi/cpu_hotplug.c
@@ -49,22 +49,12 @@ void acpi_cpu_plug_cb(ACPIREGS *ar, qemu_irq irq,
 return;
 }
 
-AcpiCpuHotplug_add(&ar->gpe, g, cpu);
+ar->gpe.sts[0] |= ACPI_CPU_HOTPLUG_STATUS;
+g->sts[cpu_id / 8] |= (1 << (cpu_id % 8));
 
 acpi_update_sci(ar, irq);
 }
 
-void AcpiCpuHotplug_add(ACPIGPE *gpe, AcpiCpuHotplug *g, CPUState *cpu)
-{
-CPUClass *k = CPU_GET_CLASS(cpu);
-int64_t cpu_id;
-
-*gpe->sts = *gpe->sts | ACPI_CPU_HOTPLUG_STATUS;
-cpu_id = k->get_arch_id(CPU(cpu));
-g_assert((cpu_id / 8) < ACPI_GPE_PROC_LEN);
-g->sts[cpu_id / 8] |= (1 << (cpu_id % 8));
-}
-
 void AcpiCpuHotplug_init(MemoryRegion *parent, Object *owner,
  AcpiCpuHotplug *gpe_cpu, uint16_t base)
 {
diff --git a/hw/acpi/piix4.c b/hw/acpi/piix4.c
index b72b34e..8320b18 100644
--- a/hw/acpi/piix4.c
+++ b/hw/acpi/piix4.c
@@ -83,7 +83,6 @@ typedef struct PIIX4PMState {
 uint8_t s4_val;
 
 AcpiCpuHotplug gpe_cpu;
-Notifier cpu_added_notifier;
 
 MemHotplugState acpi_memory_hotplug;
 } PIIX4PMState;
@@ -348,6 +347,8 @@ static void piix4_device_plug_cb(HotplugHandler 
*hotplug_dev,
 } else if (object_dynamic_cast(OBJECT(dev), TYPE_PCI_DEVICE)) {
 acpi_pcihp_device_plug_cb(&s->ar, s->irq, &s->acpi_pci_hotplug, dev,
   errp);
+} else if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) {
+acpi_cpu_plug_cb(&s->ar, s->irq, &s->gpe_cpu, dev, errp);
 } else {
 error_setg(errp, "acpi: device plug request for not supported device"
" type: %s", object_get_typename(OBJECT(dev)));
@@ -544,15 +545,6 @@ static const MemoryRegionOps piix4_gpe_ops = {
 .endianness = DEVICE_LITTLE_ENDIAN,
 };
 
-static void piix4_cpu_added_req(Notifier *n, void *opaque)
-{
-PIIX4PMState *s = container_of(n, PIIX4PMState, cpu_added_notifier);
-
-assert(s != NULL);
-AcpiCpuHotplug_add(&s->ar.gpe, &s->gpe_cpu, CPU(opaque));
-acpi_update_sci(&s->ar, s->irq);
-}
-
 static void piix4_acpi_system_hot_add_init(MemoryRegion *parent,
PCIBus *bus, PIIX4PMState *s)
 {
@@ -565,8 +557,6 @@ static void piix4_acpi_system_hot_add_init(MemoryRegion 
*parent,
 
 AcpiCpuHotplug_init(parent, OBJECT(s), &s->gpe_cpu,
 PIIX4_CPU_HOTPLUG_IO_BASE);
-s->cpu_added_notifier.notify = piix4_cpu_added_req;
-qemu_register_cpu_added_notifier(&s->cpu_added_notifier);
 
 if (s->acpi_memory_hotplug.is_enabled) {
 acpi_memory_hotplug_init(parent, OBJECT(s), &s->acpi_memory_hotplug);
diff --git a/include/hw/acpi/cpu_hotplug.h b/include/hw/acpi/cpu_hotplug.h
index 5dca8d7..4657e71 100644
--- a/include/hw/acpi/cpu_hotplug.h
+++ b/include/hw/acpi/cpu_hotplug.h
@@ -23,8 +23,6 @@ typedef struct AcpiCpuHotplug {
 void acpi_cpu_plug_cb(ACPIREGS *ar, qemu_irq irq,
   AcpiCpuHotplug *g, DeviceState *dev, Error **errp);
 
-void AcpiCpuHotplug_add(ACPIGPE *gpe, AcpiCpuHotplug *g, CPUState *cpu);
-
 void AcpiCpuHotplug_init(MemoryRegion *parent, Object *owner,
  AcpiCpuHotplug *gpe_cpu, uint16_t base);
 #endif
-- 
1.7.7




[Qemu-devel] [PATCH V4 8/8] acpi/cpu-hotplug: introduce help function to keep bit setting in one place

2014-09-29 Thread Gu Zheng
Introduce help function acpi_set_local_sts() to simplify acpi_cpu_plug_cb
and acpi_cpu_hotplug_init, so that we can keep bit setting in one place.

Signed-off-by: Gu Zheng 
---
 hw/acpi/cpu_hotplug.c |   23 +++
 1 files changed, 15 insertions(+), 8 deletions(-)

diff --git a/hw/acpi/cpu_hotplug.c b/hw/acpi/cpu_hotplug.c
index ae48b63..8ff8c4d 100644
--- a/hw/acpi/cpu_hotplug.c
+++ b/hw/acpi/cpu_hotplug.c
@@ -36,10 +36,9 @@ static const MemoryRegionOps AcpiCpuHotplug_ops = {
 },
 };
 
-void acpi_cpu_plug_cb(ACPIREGS *ar, qemu_irq irq,
-  AcpiCpuHotplug *g, DeviceState *dev, Error **errp)
+static void acpi_set_local_sts(AcpiCpuHotplug *g, CPUState *cpu,
+   Error **errp)
 {
-CPUState *cpu = CPU(dev);
 CPUClass *k = CPU_GET_CLASS(cpu);
 int64_t cpu_id;
 
@@ -49,9 +48,18 @@ void acpi_cpu_plug_cb(ACPIREGS *ar, qemu_irq irq,
 return;
 }
 
-ar->gpe.sts[0] |= ACPI_CPU_HOTPLUG_STATUS;
 g->sts[cpu_id / 8] |= (1 << (cpu_id % 8));
+}
 
+void acpi_cpu_plug_cb(ACPIREGS *ar, qemu_irq irq,
+  AcpiCpuHotplug *g, DeviceState *dev, Error **errp)
+{
+acpi_set_local_sts(g, CPU(dev), errp);
+if (*errp != NULL) {
+return;
+}
+
+ar->gpe.sts[0] |= ACPI_CPU_HOTPLUG_STATUS;
 acpi_update_sci(ar, irq);
 }
 
@@ -61,11 +69,10 @@ void acpi_cpu_hotplug_init(MemoryRegion *parent, Object 
*owner,
 CPUState *cpu;
 
 CPU_FOREACH(cpu) {
-CPUClass *cc = CPU_GET_CLASS(cpu);
-int64_t id = cc->get_arch_id(cpu);
+Error *local_err = NULL;
 
-g_assert((id / 8) < ACPI_GPE_PROC_LEN);
-gpe_cpu->sts[id / 8] |= (1 << (id % 8));
+acpi_set_local_sts(gpe_cpu, cpu, &local_err);
+g_assert(local_err == NULL);
 }
 memory_region_init_io(&gpe_cpu->io, owner, &AcpiCpuHotplug_ops,
   gpe_cpu, "acpi-cpu-hotplug", ACPI_GPE_PROC_LEN);
-- 
1.7.7




[Qemu-devel] [PATCH V4 7/8] cpu-hotplug: rename function for better readability

2014-09-29 Thread Gu Zheng
Rename:
AcpiCpuHotplug_init --> acpi_cpu_hotplug_init
AcpiCpuHotplug_ops --> acpi_cpu_hotplug_ops
for better readability, just cleanup.

Signed-off-by: Gu Zheng 
---
 hw/acpi/cpu_hotplug.c |4 ++--
 hw/acpi/ich9.c|4 ++--
 hw/acpi/piix4.c   |4 ++--
 include/hw/acpi/cpu_hotplug.h |4 ++--
 4 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/hw/acpi/cpu_hotplug.c b/hw/acpi/cpu_hotplug.c
index b69b16c..ae48b63 100644
--- a/hw/acpi/cpu_hotplug.c
+++ b/hw/acpi/cpu_hotplug.c
@@ -55,8 +55,8 @@ void acpi_cpu_plug_cb(ACPIREGS *ar, qemu_irq irq,
 acpi_update_sci(ar, irq);
 }
 
-void AcpiCpuHotplug_init(MemoryRegion *parent, Object *owner,
- AcpiCpuHotplug *gpe_cpu, uint16_t base)
+void acpi_cpu_hotplug_init(MemoryRegion *parent, Object *owner,
+   AcpiCpuHotplug *gpe_cpu, uint16_t base)
 {
 CPUState *cpu;
 
diff --git a/hw/acpi/ich9.c b/hw/acpi/ich9.c
index 7585364..ea991a3 100644
--- a/hw/acpi/ich9.c
+++ b/hw/acpi/ich9.c
@@ -235,8 +235,8 @@ void ich9_pm_init(PCIDevice *lpc_pci, ICH9LPCPMRegs *pm,
 pm->powerdown_notifier.notify = pm_powerdown_req;
 qemu_register_powerdown_notifier(&pm->powerdown_notifier);
 
-AcpiCpuHotplug_init(pci_address_space_io(lpc_pci), OBJECT(lpc_pci),
-&pm->gpe_cpu, ICH9_CPU_HOTPLUG_IO_BASE);
+acpi_cpu_hotplug_init(pci_address_space_io(lpc_pci), OBJECT(lpc_pci),
+  &pm->gpe_cpu, ICH9_CPU_HOTPLUG_IO_BASE);
 
 if (pm->acpi_memory_hotplug.is_enabled) {
 acpi_memory_hotplug_init(pci_address_space_io(lpc_pci), 
OBJECT(lpc_pci),
diff --git a/hw/acpi/piix4.c b/hw/acpi/piix4.c
index 8320b18..8fde808 100644
--- a/hw/acpi/piix4.c
+++ b/hw/acpi/piix4.c
@@ -555,8 +555,8 @@ static void piix4_acpi_system_hot_add_init(MemoryRegion 
*parent,
 acpi_pcihp_init(&s->acpi_pci_hotplug, bus, parent,
 s->use_acpi_pci_hotplug);
 
-AcpiCpuHotplug_init(parent, OBJECT(s), &s->gpe_cpu,
-PIIX4_CPU_HOTPLUG_IO_BASE);
+acpi_cpu_hotplug_init(parent, OBJECT(s), &s->gpe_cpu,
+  PIIX4_CPU_HOTPLUG_IO_BASE);
 
 if (s->acpi_memory_hotplug.is_enabled) {
 acpi_memory_hotplug_init(parent, OBJECT(s), &s->acpi_memory_hotplug);
diff --git a/include/hw/acpi/cpu_hotplug.h b/include/hw/acpi/cpu_hotplug.h
index 4657e71..f6d358d 100644
--- a/include/hw/acpi/cpu_hotplug.h
+++ b/include/hw/acpi/cpu_hotplug.h
@@ -23,6 +23,6 @@ typedef struct AcpiCpuHotplug {
 void acpi_cpu_plug_cb(ACPIREGS *ar, qemu_irq irq,
   AcpiCpuHotplug *g, DeviceState *dev, Error **errp);
 
-void AcpiCpuHotplug_init(MemoryRegion *parent, Object *owner,
- AcpiCpuHotplug *gpe_cpu, uint16_t base);
+void acpi_cpu_hotplug_init(MemoryRegion *parent, Object *owner,
+   AcpiCpuHotplug *gpe_cpu, uint16_t base);
 #endif
-- 
1.7.7




[Qemu-devel] [PATCH V4 6/8] qom/cpu: remove the unused CPU hot-plug notifier

2014-09-29 Thread Gu Zheng
Signed-off-by: Gu Zheng 
---
 include/sysemu/sysemu.h |3 ---
 qom/cpu.c   |9 -
 2 files changed, 0 insertions(+), 12 deletions(-)

diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h
index d8539fd..acfe494 100644
--- a/include/sysemu/sysemu.h
+++ b/include/sysemu/sysemu.h
@@ -183,9 +183,6 @@ void do_pci_device_hot_remove(Monitor *mon, const QDict 
*qdict);
 /* generic hotplug */
 void drive_hot_add(Monitor *mon, const QDict *qdict);
 
-/* CPU hotplug */
-void qemu_register_cpu_added_notifier(Notifier *notifier);
-
 /* pcie aer error injection */
 void pcie_aer_inject_error_print(Monitor *mon, const QObject *data);
 int do_pcie_aer_inject_error(Monitor *mon,
diff --git a/qom/cpu.c b/qom/cpu.c
index 09c7e41..83c3559 100644
--- a/qom/cpu.c
+++ b/qom/cpu.c
@@ -107,15 +107,6 @@ static void cpu_common_get_memory_mapping(CPUState *cpu,
 error_setg(errp, "Obtaining memory mappings is unsupported on this CPU.");
 }
 
-/* CPU hot-plug notifiers */
-static NotifierList cpu_added_notifiers =
-NOTIFIER_LIST_INITIALIZER(cpu_add_notifiers);
-
-void qemu_register_cpu_added_notifier(Notifier *notifier)
-{
-notifier_list_add(&cpu_added_notifiers, notifier);
-}
-
 void cpu_reset_interrupt(CPUState *cpu, int mask)
 {
 cpu->interrupt_request &= ~mask;
-- 
1.7.7




[Qemu-devel] [PATCH V4 4/8] pc: add cpu hotplug handler to PC_MACHINE

2014-09-29 Thread Gu Zheng
Add cpu hotplug handler to PC_MACHINE, which will perform the acpi
cpu hotplug callback via hotplug_handler API.

v3:
 -deal with start up cpus in a more neat way as Igor suggested.
v2:
 -just rebase.

Signed-off-by: Gu Zheng 
---
 hw/i386/pc.c |   26 +-
 1 files changed, 25 insertions(+), 1 deletions(-)

diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 82a7daa..dcb9332 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -1616,11 +1616,34 @@ out:
 error_propagate(errp, local_err);
 }
 
+static void pc_cpu_plug(HotplugHandler *hotplug_dev,
+DeviceState *dev, Error **errp)
+{
+HotplugHandlerClass *hhc;
+Error *local_err = NULL;
+PCMachineState *pcms = PC_MACHINE(hotplug_dev);
+
+if (!pcms->acpi_dev) {
+if (dev->hotplugged) {
+error_setg(&local_err,
+   "cpu hotplug is not enabled: missing acpi device");
+}
+goto out;
+}
+
+hhc = HOTPLUG_HANDLER_GET_CLASS(pcms->acpi_dev);
+hhc->plug(HOTPLUG_HANDLER(pcms->acpi_dev), dev, &local_err);
+out:
+error_propagate(errp, local_err);
+}
+
 static void pc_machine_device_plug_cb(HotplugHandler *hotplug_dev,
   DeviceState *dev, Error **errp)
 {
 if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
 pc_dimm_plug(hotplug_dev, dev, errp);
+} else if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) {
+pc_cpu_plug(hotplug_dev, dev, errp);
 }
 }
 
@@ -1629,7 +1652,8 @@ static HotplugHandler *pc_get_hotpug_handler(MachineState 
*machine,
 {
 PCMachineClass *pcmc = PC_MACHINE_GET_CLASS(machine);
 
-if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
+if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM) ||
+object_dynamic_cast(OBJECT(dev), TYPE_CPU)) {
 return HOTPLUG_HANDLER(machine);
 }
 
-- 
1.7.7




Re: [Qemu-devel] [PATCH V4 5/8] pc: Update rtc_cmos in pc_cpu_plug

2014-10-07 Thread Gu Zheng
Hi Igor,

On 10/07/2014 09:01 PM, Igor Mammedov wrote:

> On Mon, 29 Sep 2014 18:52:34 +0800
> Gu Zheng  wrote:
> 
>> Update rtc_cmos in pc_cpu_plug directly instead of the notifier.
>>
>> v4:
>>  -Make link property in PCMachine rather than the global
>>   variables.
>>  -Split out the removal of unused notifier into separate patch.
>>
>> Signed-off-by: Gu Zheng 
>> ---
>>  hw/i386/pc.c |   37 -
>>  hw/i386/pc_piix.c|2 +-
>>  hw/i386/pc_q35.c |2 +-
>>  include/hw/i386/pc.h |3 ++-
>>  qom/cpu.c|1 -
>>  5 files changed, 20 insertions(+), 25 deletions(-)
>>
>> diff --git a/hw/i386/pc.c b/hw/i386/pc.c
>> index dcb9332..301e704 100644
>> --- a/hw/i386/pc.c
>> +++ b/hw/i386/pc.c
>> @@ -355,30 +355,15 @@ static void pc_cmos_init_late(void *opaque)
>>  qemu_unregister_reset(pc_cmos_init_late, opaque);
>>  }
>>  
>> -typedef struct RTCCPUHotplugArg {
>> -Notifier cpu_added_notifier;
>> -ISADevice *rtc_state;
>> -} RTCCPUHotplugArg;
>> -
>> -static void rtc_notify_cpu_added(Notifier *notifier, void *data)
>> -{
>> -RTCCPUHotplugArg *arg = container_of(notifier, RTCCPUHotplugArg,
>> - cpu_added_notifier);
>> -ISADevice *s = arg->rtc_state;
>> -
>> -/* increment the number of CPUs */
>> -rtc_set_memory(s, 0x5f, rtc_get_memory(s, 0x5f) + 1);
>> -}
>> -
>>  void pc_cmos_init(ram_addr_t ram_size, ram_addr_t above_4g_mem_size,
>> -  const char *boot_device,
>> +  const char *boot_device, MachineState *machine,
>>ISADevice *floppy, BusState *idebus0, BusState *idebus1,
>>ISADevice *s)
>>  {
>>  int val, nb, i;
>>  FDriveType fd_type[2] = { FDRIVE_DRV_NONE, FDRIVE_DRV_NONE };
>>  static pc_cmos_init_late_arg arg;
>> -static RTCCPUHotplugArg cpu_hotplug_cb;
>> +PCMachineState *pc_machine = PC_MACHINE(machine);
>>  
>>  /* various important CMOS locations needed by PC/Bochs bios */
>>  
>> @@ -417,10 +402,14 @@ void pc_cmos_init(ram_addr_t ram_size, ram_addr_t 
>> above_4g_mem_size,
>>  
>>  /* set the number of CPU */
>>  rtc_set_memory(s, 0x5f, smp_cpus - 1);
>> -/* init CPU hotplug notifier */
>> -cpu_hotplug_cb.rtc_state = s;
>> -cpu_hotplug_cb.cpu_added_notifier.notify = rtc_notify_cpu_added;
>> -qemu_register_cpu_added_notifier(&cpu_hotplug_cb.cpu_added_notifier);
>> +
>> +object_property_add_link(OBJECT(machine), "rtc_state",
>> + TYPE_ISA_DEVICE,
>> + (Object **)&pc_machine->rtc,
>> + object_property_allow_set_link,
>> + OBJ_PROP_LINK_UNREF_ON_RELEASE, &error_abort);
>> +object_property_set_link(OBJECT(machine), OBJECT(s),
>> + "rtc_state", &error_abort);
>>  
>>  if (set_boot_dev(s, boot_device)) {
>>  exit(1);
>> @@ -1633,6 +1622,12 @@ static void pc_cpu_plug(HotplugHandler *hotplug_dev,
>>  
>>  hhc = HOTPLUG_HANDLER_GET_CLASS(pcms->acpi_dev);
>>  hhc->plug(HOTPLUG_HANDLER(pcms->acpi_dev), dev, &local_err);
>> +if (local_err) {
>> +goto out;
>> +}
>> +
>> +/* increment the number of CPUs */
>> +rtc_set_memory(pcms->rtc, 0x5f, rtc_get_memory(pcms->rtc, 0x5f) + 1);
>>  out:
>>  error_propagate(errp, local_err);
>>  }
>> diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
>> index 103d756..2c8d4dc 100644
>> --- a/hw/i386/pc_piix.c
>> +++ b/hw/i386/pc_piix.c
>> @@ -266,7 +266,7 @@ static void pc_init1(MachineState *machine,
>>  }
>>  
>>  pc_cmos_init(below_4g_mem_size, above_4g_mem_size, machine->boot_order,
>> - floppy, idebus[0], idebus[1], rtc_state);
>> + machine, floppy, idebus[0], idebus[1], rtc_state);
>>  
>>  if (pci_enabled && usb_enabled(false)) {
>>  pci_create_simple(pci_bus, piix3_devfn + 2, "piix3-usb-uhci");
>> diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c
>> index d4a907c..94ba98d 100644
>> --- a/hw/i386/pc_q35.c
>> +++ b/hw/i386/pc_q35.c
>> @@ -266,7 +266,7 @@ static void pc_q35_init(MachineState *machine)
>>8, NULL, 0);
>>  
>>  pc_cmos_init(b

Re: [Qemu-devel] [PATCH V4 5/8] pc: Update rtc_cmos in pc_cpu_plug

2014-10-08 Thread Gu Zheng
On 10/08/2014 08:25 PM, Igor Mammedov wrote:

> On Wed, 8 Oct 2014 09:12:11 +0800
> Gu Zheng  wrote:
> 
>> Hi Igor,
>>
>> On 10/07/2014 09:01 PM, Igor Mammedov wrote:
>>
>>> On Mon, 29 Sep 2014 18:52:34 +0800
>>> Gu Zheng  wrote:
>>>
>>>> Update rtc_cmos in pc_cpu_plug directly instead of the notifier.
>>>>
>>>> v4:
>>>>  -Make link property in PCMachine rather than the global
>>>>   variables.
>>>>  -Split out the removal of unused notifier into separate patch.
>>>>
>>>> Signed-off-by: Gu Zheng 
>>>> ---
>>>>  hw/i386/pc.c |   37 -
>>>>  hw/i386/pc_piix.c|2 +-
>>>>  hw/i386/pc_q35.c |2 +-
>>>>  include/hw/i386/pc.h |3 ++-
>>>>  qom/cpu.c|1 -
>>>>  5 files changed, 20 insertions(+), 25 deletions(-)
>>>>
>>>> diff --git a/hw/i386/pc.c b/hw/i386/pc.c
>>>> index dcb9332..301e704 100644
>>>> --- a/hw/i386/pc.c
>>>> +++ b/hw/i386/pc.c
>>>> @@ -355,30 +355,15 @@ static void pc_cmos_init_late(void *opaque)
>>>>  qemu_unregister_reset(pc_cmos_init_late, opaque);
>>>>  }
>>>>  
>>>> -typedef struct RTCCPUHotplugArg {
>>>> -Notifier cpu_added_notifier;
>>>> -ISADevice *rtc_state;
>>>> -} RTCCPUHotplugArg;
>>>> -
>>>> -static void rtc_notify_cpu_added(Notifier *notifier, void *data)
>>>> -{
>>>> -RTCCPUHotplugArg *arg = container_of(notifier, RTCCPUHotplugArg,
>>>> - cpu_added_notifier);
>>>> -ISADevice *s = arg->rtc_state;
>>>> -
>>>> -/* increment the number of CPUs */
>>>> -rtc_set_memory(s, 0x5f, rtc_get_memory(s, 0x5f) + 1);
>>>> -}
>>>> -
>>>>  void pc_cmos_init(ram_addr_t ram_size, ram_addr_t above_4g_mem_size,
>>>> -  const char *boot_device,
>>>> +  const char *boot_device, MachineState *machine,
>>>>ISADevice *floppy, BusState *idebus0, BusState *idebus1,
>>>>ISADevice *s)
>>>>  {
>>>>  int val, nb, i;
>>>>  FDriveType fd_type[2] = { FDRIVE_DRV_NONE, FDRIVE_DRV_NONE };
>>>>  static pc_cmos_init_late_arg arg;
>>>> -static RTCCPUHotplugArg cpu_hotplug_cb;
>>>> +PCMachineState *pc_machine = PC_MACHINE(machine);
>>>>  
>>>>  /* various important CMOS locations needed by PC/Bochs bios */
>>>>  
>>>> @@ -417,10 +402,14 @@ void pc_cmos_init(ram_addr_t ram_size, ram_addr_t 
>>>> above_4g_mem_size,
>>>>  
>>>>  /* set the number of CPU */
>>>>  rtc_set_memory(s, 0x5f, smp_cpus - 1);
>>>> -/* init CPU hotplug notifier */
>>>> -cpu_hotplug_cb.rtc_state = s;
>>>> -cpu_hotplug_cb.cpu_added_notifier.notify = rtc_notify_cpu_added;
>>>> -qemu_register_cpu_added_notifier(&cpu_hotplug_cb.cpu_added_notifier);
>>>> +
>>>> +object_property_add_link(OBJECT(machine), "rtc_state",
>>>> + TYPE_ISA_DEVICE,
>>>> + (Object **)&pc_machine->rtc,
>>>> + object_property_allow_set_link,
>>>> + OBJ_PROP_LINK_UNREF_ON_RELEASE, 
>>>> &error_abort);
>>>> +object_property_set_link(OBJECT(machine), OBJECT(s),
>>>> + "rtc_state", &error_abort);
>>>>  
>>>>  if (set_boot_dev(s, boot_device)) {
>>>>  exit(1);
>>>> @@ -1633,6 +1622,12 @@ static void pc_cpu_plug(HotplugHandler *hotplug_dev,
>>>>  
>>>>  hhc = HOTPLUG_HANDLER_GET_CLASS(pcms->acpi_dev);
>>>>  hhc->plug(HOTPLUG_HANDLER(pcms->acpi_dev), dev, &local_err);
>>>> +if (local_err) {
>>>> +goto out;
>>>> +}
>>>> +
>>>> +/* increment the number of CPUs */
>>>> +rtc_set_memory(pcms->rtc, 0x5f, rtc_get_memory(pcms->rtc, 0x5f) + 1);
>>>>  out:
>>>>  error_propagate(errp, local_err);
>>>>  }
>>>> diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
>>>> index 103d756..2c8d4dc 1

[Qemu-devel] [PATCH V5 0/8] cpu/acpi: convert cpu hot plug to hotplug_handler API

2014-10-09 Thread Gu Zheng
Previously we use cpu_added_notifiers to register cpu hotplug notifier callback
which is not able to pass/handle errors, so we switch it to unified hotplug
handler API which allows to pass errors and would allow to cancel device_add
in case of error.
Thanks very much for Igor's review and suggestion.

---
v5:
 -rebase on the latest upstream and fix some comments.
 Patch 4/8:
 -split the check out of acpi_dev block.
 Patch 5/8:
 -move CPU hot-plug notifier cleanup hunk into Patch 6/8.
 Patch 6/8:
 -delete the caller of notifier_list_notify() in this patch.
 Patch 8/8:
 -rename acpi_set_local_sts to acpi_set_cpu_present_bit for better readability.

v4:
 -split removal of CPU hotplug notifier into separate patch (Patch 6/8).
 Patch 1/7:
 -convert CPUState *cpu to DeviceState *dev like it's done for other handlers
  and do cast to CPU inside.
 Patch 5/7:
 -Make rtc_state as a link property in PCMachine rather than the global
  variables.
 -Split out the removal of unused notifier into separate patch.
 -Check the result of plug callback before update rtc_state.

v3:
 -deal with start-up cpus in pc_cpu_plug as Igor suggested.

v2:
 -Add 3 new patches(5/7,6/7,7/7), delete original patch 5/5.
  1/5-->1/7
  2/5-->2/7
  3/5-->3/7
  4/5-->4/7
 Patch 1/7:
 -add errp argument to catch error.
 -return error instead of aborting if cpu id is invalid.
 -make acpi_cpu_plug_cb as a wrapper around AcpiCpuHotplug_add.
 Patch 3/7:
 -remove unused AcpiCpuHotplug_add directly.
 Patch 5/7:
 -switch the last user of cpu hotplug notifier to hotplug handler API, and
  remove the unused cpu hotplug notify.
 Patch 6/7:
 -split the function rename (just cleanup) into single patch.
 Patch 7/7:
 -introduce help function acpi_set_local_sts to keep the bit setting in
  one place.
---

Gu Zheng (8):
  acpi/cpu: add cpu hotplug callback function to match hotplug_handler
API
  acpi:ich9: convert cpu hotplug to hotplug_handler API
  acpi:piix4: convert cpu hotplug to hotplug_handler API
  pc: add cpu hotplug handler to PC_MACHINE
  pc: Update rtc_cmos in pc_cpu_plug
  qom/cpu: remove the unused CPU hot-plug notifier
  cpu-hotplug: rename function for better readability
  acpi/cpu-hotplug: introduce help function to keep bit setting in one
place

 hw/acpi/cpu_hotplug.c |   35 --
 hw/acpi/ich9.c|   17 ++
 hw/acpi/piix4.c   |   18 ++-
 hw/i386/pc.c  |   65 +++--
 hw/i386/pc_piix.c |2 +-
 hw/i386/pc_q35.c  |2 +-
 include/hw/acpi/cpu_hotplug.h |7 ++--
 include/hw/acpi/ich9.h|1 -
 include/hw/i386/pc.h  |3 +-
 include/sysemu/sysemu.h   |3 --
 qom/cpu.c |   10 --
 11 files changed, 84 insertions(+), 79 deletions(-)

-- 
1.7.7




[Qemu-devel] [PATCH V5 1/8] acpi/cpu: add cpu hotplug callback function to match hotplug_handler API

2014-10-09 Thread Gu Zheng
Add cpu hotplug callback function (acpi_cpu_plug_cb) to match hotplug_handler 
API.

Signed-off-by: Gu Zheng 
---
v4:
 -convert CPUState *cpu to DeviceState *dev like it's done for other handlers
  and do cast to CPU inside.
v2:
 -add errp argument to catch error.
 -return error instead of aborting if cpu id is invalid.
 -make acpi_cpu_plug_cb as a wrapper around AcpiCpuHotplug_add.

 hw/acpi/cpu_hotplug.c |   18 ++
 include/hw/acpi/cpu_hotplug.h |3 +++
 2 files changed, 21 insertions(+), 0 deletions(-)

diff --git a/hw/acpi/cpu_hotplug.c b/hw/acpi/cpu_hotplug.c
index 2ad83a0..06e9c61 100644
--- a/hw/acpi/cpu_hotplug.c
+++ b/hw/acpi/cpu_hotplug.c
@@ -36,6 +36,24 @@ static const MemoryRegionOps AcpiCpuHotplug_ops = {
 },
 };
 
+void acpi_cpu_plug_cb(ACPIREGS *ar, qemu_irq irq,
+  AcpiCpuHotplug *g, DeviceState *dev, Error **errp)
+{
+CPUState *cpu = CPU(dev);
+CPUClass *k = CPU_GET_CLASS(cpu);
+int64_t cpu_id;
+
+cpu_id = k->get_arch_id(cpu);
+if ((cpu_id / 8) >= ACPI_GPE_PROC_LEN) {
+error_setg(errp, "acpi: invalid cpu id: %" PRIi64, cpu_id);
+return;
+}
+
+AcpiCpuHotplug_add(&ar->gpe, g, cpu);
+
+acpi_update_sci(ar, irq);
+}
+
 void AcpiCpuHotplug_add(ACPIGPE *gpe, AcpiCpuHotplug *g, CPUState *cpu)
 {
 CPUClass *k = CPU_GET_CLASS(cpu);
diff --git a/include/hw/acpi/cpu_hotplug.h b/include/hw/acpi/cpu_hotplug.h
index 9e5d30c..5dca8d7 100644
--- a/include/hw/acpi/cpu_hotplug.h
+++ b/include/hw/acpi/cpu_hotplug.h
@@ -20,6 +20,9 @@ typedef struct AcpiCpuHotplug {
 uint8_t sts[ACPI_GPE_PROC_LEN];
 } AcpiCpuHotplug;
 
+void acpi_cpu_plug_cb(ACPIREGS *ar, qemu_irq irq,
+  AcpiCpuHotplug *g, DeviceState *dev, Error **errp);
+
 void AcpiCpuHotplug_add(ACPIGPE *gpe, AcpiCpuHotplug *g, CPUState *cpu);
 
 void AcpiCpuHotplug_init(MemoryRegion *parent, Object *owner,
-- 
1.7.7




[Qemu-devel] [PATCH V5 2/8] acpi:ich9: convert cpu hotplug to hotplug_handler API

2014-10-09 Thread Gu Zheng
Convert notifier based hotplug to hotplug_handler API.

Signed-off-by: Gu Zheng 
---
v5:
 -drop 'handle' from the comment and subject.

 hw/acpi/ich9.c |   13 ++---
 include/hw/acpi/ich9.h |1 -
 2 files changed, 2 insertions(+), 12 deletions(-)

diff --git a/hw/acpi/ich9.c b/hw/acpi/ich9.c
index 7b14bbb..7585364 100644
--- a/hw/acpi/ich9.c
+++ b/hw/acpi/ich9.c
@@ -209,15 +209,6 @@ static void pm_powerdown_req(Notifier *n, void *opaque)
 acpi_pm1_evt_power_down(&pm->acpi_regs);
 }
 
-static void ich9_cpu_added_req(Notifier *n, void *opaque)
-{
-ICH9LPCPMRegs *pm = container_of(n, ICH9LPCPMRegs, cpu_added_notifier);
-
-assert(pm != NULL);
-AcpiCpuHotplug_add(&pm->acpi_regs.gpe, &pm->gpe_cpu, CPU(opaque));
-acpi_update_sci(&pm->acpi_regs, pm->irq);
-}
-
 void ich9_pm_init(PCIDevice *lpc_pci, ICH9LPCPMRegs *pm,
   qemu_irq sci_irq)
 {
@@ -246,8 +237,6 @@ void ich9_pm_init(PCIDevice *lpc_pci, ICH9LPCPMRegs *pm,
 
 AcpiCpuHotplug_init(pci_address_space_io(lpc_pci), OBJECT(lpc_pci),
 &pm->gpe_cpu, ICH9_CPU_HOTPLUG_IO_BASE);
-pm->cpu_added_notifier.notify = ich9_cpu_added_req;
-qemu_register_cpu_added_notifier(&pm->cpu_added_notifier);
 
 if (pm->acpi_memory_hotplug.is_enabled) {
 acpi_memory_hotplug_init(pci_address_space_io(lpc_pci), 
OBJECT(lpc_pci),
@@ -304,6 +293,8 @@ void ich9_pm_device_plug_cb(ICH9LPCPMRegs *pm, DeviceState 
*dev, Error **errp)
 object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
 acpi_memory_plug_cb(&pm->acpi_regs, pm->irq, &pm->acpi_memory_hotplug,
 dev, errp);
+} else if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) {
+acpi_cpu_plug_cb(&pm->acpi_regs, pm->irq, &pm->gpe_cpu, dev, errp);
 } else {
 error_setg(errp, "acpi: device plug request for not supported device"
" type: %s", object_get_typename(OBJECT(dev)));
diff --git a/include/hw/acpi/ich9.h b/include/hw/acpi/ich9.h
index 7e42448..fe975e6 100644
--- a/include/hw/acpi/ich9.h
+++ b/include/hw/acpi/ich9.h
@@ -47,7 +47,6 @@ typedef struct ICH9LPCPMRegs {
 Notifier powerdown_notifier;
 
 AcpiCpuHotplug gpe_cpu;
-Notifier cpu_added_notifier;
 
 MemHotplugState acpi_memory_hotplug;
 } ICH9LPCPMRegs;
-- 
1.7.7




[Qemu-devel] [PATCH V5 3/8] acpi:piix4: convert cpu hotplug to hotplug_handler API

2014-10-09 Thread Gu Zheng
Convert notifier based hotplug to hotplug_handler API,
and remove the unused AcpiCpuHotplug_add().

Signed-off-by: Gu Zheng 
---
v5:
 -drop 'handle' from the comment and subject.
v2:
 -remove the unused AcpiCpuHotplug_add().

 hw/acpi/cpu_hotplug.c |   14 ++
 hw/acpi/piix4.c   |   14 ++
 include/hw/acpi/cpu_hotplug.h |2 --
 3 files changed, 4 insertions(+), 26 deletions(-)

diff --git a/hw/acpi/cpu_hotplug.c b/hw/acpi/cpu_hotplug.c
index 06e9c61..b69b16c 100644
--- a/hw/acpi/cpu_hotplug.c
+++ b/hw/acpi/cpu_hotplug.c
@@ -49,22 +49,12 @@ void acpi_cpu_plug_cb(ACPIREGS *ar, qemu_irq irq,
 return;
 }
 
-AcpiCpuHotplug_add(&ar->gpe, g, cpu);
+ar->gpe.sts[0] |= ACPI_CPU_HOTPLUG_STATUS;
+g->sts[cpu_id / 8] |= (1 << (cpu_id % 8));
 
 acpi_update_sci(ar, irq);
 }
 
-void AcpiCpuHotplug_add(ACPIGPE *gpe, AcpiCpuHotplug *g, CPUState *cpu)
-{
-CPUClass *k = CPU_GET_CLASS(cpu);
-int64_t cpu_id;
-
-*gpe->sts = *gpe->sts | ACPI_CPU_HOTPLUG_STATUS;
-cpu_id = k->get_arch_id(CPU(cpu));
-g_assert((cpu_id / 8) < ACPI_GPE_PROC_LEN);
-g->sts[cpu_id / 8] |= (1 << (cpu_id % 8));
-}
-
 void AcpiCpuHotplug_init(MemoryRegion *parent, Object *owner,
  AcpiCpuHotplug *gpe_cpu, uint16_t base)
 {
diff --git a/hw/acpi/piix4.c b/hw/acpi/piix4.c
index b72b34e..8320b18 100644
--- a/hw/acpi/piix4.c
+++ b/hw/acpi/piix4.c
@@ -83,7 +83,6 @@ typedef struct PIIX4PMState {
 uint8_t s4_val;
 
 AcpiCpuHotplug gpe_cpu;
-Notifier cpu_added_notifier;
 
 MemHotplugState acpi_memory_hotplug;
 } PIIX4PMState;
@@ -348,6 +347,8 @@ static void piix4_device_plug_cb(HotplugHandler 
*hotplug_dev,
 } else if (object_dynamic_cast(OBJECT(dev), TYPE_PCI_DEVICE)) {
 acpi_pcihp_device_plug_cb(&s->ar, s->irq, &s->acpi_pci_hotplug, dev,
   errp);
+} else if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) {
+acpi_cpu_plug_cb(&s->ar, s->irq, &s->gpe_cpu, dev, errp);
 } else {
 error_setg(errp, "acpi: device plug request for not supported device"
" type: %s", object_get_typename(OBJECT(dev)));
@@ -544,15 +545,6 @@ static const MemoryRegionOps piix4_gpe_ops = {
 .endianness = DEVICE_LITTLE_ENDIAN,
 };
 
-static void piix4_cpu_added_req(Notifier *n, void *opaque)
-{
-PIIX4PMState *s = container_of(n, PIIX4PMState, cpu_added_notifier);
-
-assert(s != NULL);
-AcpiCpuHotplug_add(&s->ar.gpe, &s->gpe_cpu, CPU(opaque));
-acpi_update_sci(&s->ar, s->irq);
-}
-
 static void piix4_acpi_system_hot_add_init(MemoryRegion *parent,
PCIBus *bus, PIIX4PMState *s)
 {
@@ -565,8 +557,6 @@ static void piix4_acpi_system_hot_add_init(MemoryRegion 
*parent,
 
 AcpiCpuHotplug_init(parent, OBJECT(s), &s->gpe_cpu,
 PIIX4_CPU_HOTPLUG_IO_BASE);
-s->cpu_added_notifier.notify = piix4_cpu_added_req;
-qemu_register_cpu_added_notifier(&s->cpu_added_notifier);
 
 if (s->acpi_memory_hotplug.is_enabled) {
 acpi_memory_hotplug_init(parent, OBJECT(s), &s->acpi_memory_hotplug);
diff --git a/include/hw/acpi/cpu_hotplug.h b/include/hw/acpi/cpu_hotplug.h
index 5dca8d7..4657e71 100644
--- a/include/hw/acpi/cpu_hotplug.h
+++ b/include/hw/acpi/cpu_hotplug.h
@@ -23,8 +23,6 @@ typedef struct AcpiCpuHotplug {
 void acpi_cpu_plug_cb(ACPIREGS *ar, qemu_irq irq,
   AcpiCpuHotplug *g, DeviceState *dev, Error **errp);
 
-void AcpiCpuHotplug_add(ACPIGPE *gpe, AcpiCpuHotplug *g, CPUState *cpu);
-
 void AcpiCpuHotplug_init(MemoryRegion *parent, Object *owner,
  AcpiCpuHotplug *gpe_cpu, uint16_t base);
 #endif
-- 
1.7.7




[Qemu-devel] [PATCH V5 4/8] pc: add cpu hotplug handler to PC_MACHINE

2014-10-09 Thread Gu Zheng
Add cpu hotplug handler to PC_MACHINE, which will perform the acpi
cpu hotplug callback via hotplug_handler API.

Signed-off-by: Gu Zheng 
---
v5:
 -split the check out of acpi_dev block.
v3:
 -deal with start up cpus in a more neat way as Igor suggested.
v2:
 -just rebase.

 hw/i386/pc.c |   28 +++-
 1 files changed, 27 insertions(+), 1 deletions(-)

diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index d045e8b..eff19ef 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -1617,11 +1617,36 @@ out:
 error_propagate(errp, local_err);
 }
 
+static void pc_cpu_plug(HotplugHandler *hotplug_dev,
+DeviceState *dev, Error **errp)
+{
+HotplugHandlerClass *hhc;
+Error *local_err = NULL;
+PCMachineState *pcms = PC_MACHINE(hotplug_dev);
+
+if (!dev->hotplugged) {
+goto out;
+}
+
+if (!pcms->acpi_dev) {
+error_setg(&local_err,
+   "cpu hotplug is not enabled: missing acpi device");
+goto out;
+}
+
+hhc = HOTPLUG_HANDLER_GET_CLASS(pcms->acpi_dev);
+hhc->plug(HOTPLUG_HANDLER(pcms->acpi_dev), dev, &local_err);
+out:
+error_propagate(errp, local_err);
+}
+
 static void pc_machine_device_plug_cb(HotplugHandler *hotplug_dev,
   DeviceState *dev, Error **errp)
 {
 if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
 pc_dimm_plug(hotplug_dev, dev, errp);
+} else if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) {
+pc_cpu_plug(hotplug_dev, dev, errp);
 }
 }
 
@@ -1630,7 +1655,8 @@ static HotplugHandler *pc_get_hotpug_handler(MachineState 
*machine,
 {
 PCMachineClass *pcmc = PC_MACHINE_GET_CLASS(machine);
 
-if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
+if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM) ||
+object_dynamic_cast(OBJECT(dev), TYPE_CPU)) {
 return HOTPLUG_HANDLER(machine);
 }
 
-- 
1.7.7




[Qemu-devel] [PATCH V5 5/8] pc: Update rtc_cmos in pc_cpu_plug

2014-10-09 Thread Gu Zheng
Update rtc_cmos in pc_cpu_plug() directly, instead of the notifier.

Signed-off-by: Gu Zheng 
---
v5:
 -move CPU hot-plug notifier cleanup hunk into Patch 6/8.

v4:
 -Make link property in PCMachine rather than the global
  variables.
 -Split out the removal of unused notifier into separate patch.

 hw/i386/pc.c |   37 -
 hw/i386/pc_piix.c|2 +-
 hw/i386/pc_q35.c |2 +-
 include/hw/i386/pc.h |3 ++-
 4 files changed, 20 insertions(+), 24 deletions(-)

diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index eff19ef..0f10ec8 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -355,30 +355,15 @@ static void pc_cmos_init_late(void *opaque)
 qemu_unregister_reset(pc_cmos_init_late, opaque);
 }
 
-typedef struct RTCCPUHotplugArg {
-Notifier cpu_added_notifier;
-ISADevice *rtc_state;
-} RTCCPUHotplugArg;
-
-static void rtc_notify_cpu_added(Notifier *notifier, void *data)
-{
-RTCCPUHotplugArg *arg = container_of(notifier, RTCCPUHotplugArg,
- cpu_added_notifier);
-ISADevice *s = arg->rtc_state;
-
-/* increment the number of CPUs */
-rtc_set_memory(s, 0x5f, rtc_get_memory(s, 0x5f) + 1);
-}
-
 void pc_cmos_init(ram_addr_t ram_size, ram_addr_t above_4g_mem_size,
-  const char *boot_device,
+  const char *boot_device, MachineState *machine,
   ISADevice *floppy, BusState *idebus0, BusState *idebus1,
   ISADevice *s)
 {
 int val, nb, i;
 FDriveType fd_type[2] = { FDRIVE_DRV_NONE, FDRIVE_DRV_NONE };
 static pc_cmos_init_late_arg arg;
-static RTCCPUHotplugArg cpu_hotplug_cb;
+PCMachineState *pc_machine = PC_MACHINE(machine);
 
 /* various important CMOS locations needed by PC/Bochs bios */
 
@@ -417,10 +402,14 @@ void pc_cmos_init(ram_addr_t ram_size, ram_addr_t 
above_4g_mem_size,
 
 /* set the number of CPU */
 rtc_set_memory(s, 0x5f, smp_cpus - 1);
-/* init CPU hotplug notifier */
-cpu_hotplug_cb.rtc_state = s;
-cpu_hotplug_cb.cpu_added_notifier.notify = rtc_notify_cpu_added;
-qemu_register_cpu_added_notifier(&cpu_hotplug_cb.cpu_added_notifier);
+
+object_property_add_link(OBJECT(machine), "rtc_state",
+ TYPE_ISA_DEVICE,
+ (Object **)&pc_machine->rtc,
+ object_property_allow_set_link,
+ OBJ_PROP_LINK_UNREF_ON_RELEASE, &error_abort);
+object_property_set_link(OBJECT(machine), OBJECT(s),
+ "rtc_state", &error_abort);
 
 if (set_boot_dev(s, boot_device)) {
 exit(1);
@@ -1636,6 +1625,12 @@ static void pc_cpu_plug(HotplugHandler *hotplug_dev,
 
 hhc = HOTPLUG_HANDLER_GET_CLASS(pcms->acpi_dev);
 hhc->plug(HOTPLUG_HANDLER(pcms->acpi_dev), dev, &local_err);
+if (local_err) {
+goto out;
+}
+
+/* increment the number of CPUs */
+rtc_set_memory(pcms->rtc, 0x5f, rtc_get_memory(pcms->rtc, 0x5f) + 1);
 out:
 error_propagate(errp, local_err);
 }
diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index 4384633..2ff7e84 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -266,7 +266,7 @@ static void pc_init1(MachineState *machine,
 }
 
 pc_cmos_init(below_4g_mem_size, above_4g_mem_size, machine->boot_order,
- floppy, idebus[0], idebus[1], rtc_state);
+ machine, floppy, idebus[0], idebus[1], rtc_state);
 
 if (pci_enabled && usb_enabled(false)) {
 pci_create_simple(pci_bus, piix3_devfn + 2, "piix3-usb-uhci");
diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c
index bb0dc8e..7cab8e4 100644
--- a/hw/i386/pc_q35.c
+++ b/hw/i386/pc_q35.c
@@ -270,7 +270,7 @@ static void pc_q35_init(MachineState *machine)
   8, NULL, 0);
 
 pc_cmos_init(below_4g_mem_size, above_4g_mem_size, machine->boot_order,
- floppy, idebus[0], idebus[1], rtc_state);
+ machine, floppy, idebus[0], idebus[1], rtc_state);
 
 /* the rest devices to which pci devfn is automatically assigned */
 pc_vga_init(isa_bus, host_bus);
diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
index 77316d5..7a4bff4 100644
--- a/include/hw/i386/pc.h
+++ b/include/hw/i386/pc.h
@@ -33,6 +33,7 @@ struct PCMachineState {
 MemoryRegion hotplug_memory;
 
 HotplugHandler *acpi_dev;
+ISADevice *rtc;
 
 uint64_t max_ram_below_4g;
 };
@@ -210,7 +211,7 @@ void pc_basic_device_init(ISABus *isa_bus, qemu_irq *gsi,
   uint32 hpet_irqs);
 void pc_init_ne2k_isa(ISABus *bus, NICInfo *nd);
 void pc_cmos_init(ram_addr_t ram_size, ram_addr_t above_4g_mem_size,
-  const char *boot_device,
+  const char *boot_device, MachineState *machine,
   ISADevice *floppy, BusState *ide0, BusState *ide1,
   ISADevice *s);
 void pc_nic_init(ISABus *isa_bus, PCIBus *pci_bus);
-- 
1.7.7




[Qemu-devel] [PATCH V5 6/8] qom/cpu: remove the unused CPU hot-plug notifier

2014-10-09 Thread Gu Zheng
Remove the unused CPU hot-plug notifier.

Signed-off-by: Gu Zheng 
---
v5:
 -delete the caller of notifier_list_notify() in this patch.

 include/sysemu/sysemu.h |3 ---
 qom/cpu.c   |   10 --
 2 files changed, 0 insertions(+), 13 deletions(-)

diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h
index d8539fd..acfe494 100644
--- a/include/sysemu/sysemu.h
+++ b/include/sysemu/sysemu.h
@@ -183,9 +183,6 @@ void do_pci_device_hot_remove(Monitor *mon, const QDict 
*qdict);
 /* generic hotplug */
 void drive_hot_add(Monitor *mon, const QDict *qdict);
 
-/* CPU hotplug */
-void qemu_register_cpu_added_notifier(Notifier *notifier);
-
 /* pcie aer error injection */
 void pcie_aer_inject_error_print(Monitor *mon, const QObject *data);
 int do_pcie_aer_inject_error(Monitor *mon,
diff --git a/qom/cpu.c b/qom/cpu.c
index 0ec3337..79d2228 100644
--- a/qom/cpu.c
+++ b/qom/cpu.c
@@ -107,15 +107,6 @@ static void cpu_common_get_memory_mapping(CPUState *cpu,
 error_setg(errp, "Obtaining memory mappings is unsupported on this CPU.");
 }
 
-/* CPU hot-plug notifiers */
-static NotifierList cpu_added_notifiers =
-NOTIFIER_LIST_INITIALIZER(cpu_add_notifiers);
-
-void qemu_register_cpu_added_notifier(Notifier *notifier)
-{
-notifier_list_add(&cpu_added_notifiers, notifier);
-}
-
 void cpu_reset_interrupt(CPUState *cpu, int mask)
 {
 cpu->interrupt_request &= ~mask;
@@ -312,7 +303,6 @@ static void cpu_common_realizefn(DeviceState *dev, Error 
**errp)
 
 if (dev->hotplugged) {
 cpu_synchronize_post_init(cpu);
-notifier_list_notify(&cpu_added_notifiers, dev);
 cpu_resume(cpu);
 }
 }
-- 
1.7.7




[Qemu-devel] [PATCH V5 7/8] cpu-hotplug: rename function for better readability

2014-10-09 Thread Gu Zheng
Rename:
AcpiCpuHotplug_init --> acpi_cpu_hotplug_init
AcpiCpuHotplug_ops --> acpi_cpu_hotplug_ops
for better readability, just cleanup.

Signed-off-by: Gu Zheng 
---
 hw/acpi/cpu_hotplug.c |4 ++--
 hw/acpi/ich9.c|4 ++--
 hw/acpi/piix4.c   |4 ++--
 include/hw/acpi/cpu_hotplug.h |4 ++--
 4 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/hw/acpi/cpu_hotplug.c b/hw/acpi/cpu_hotplug.c
index b69b16c..ae48b63 100644
--- a/hw/acpi/cpu_hotplug.c
+++ b/hw/acpi/cpu_hotplug.c
@@ -55,8 +55,8 @@ void acpi_cpu_plug_cb(ACPIREGS *ar, qemu_irq irq,
 acpi_update_sci(ar, irq);
 }
 
-void AcpiCpuHotplug_init(MemoryRegion *parent, Object *owner,
- AcpiCpuHotplug *gpe_cpu, uint16_t base)
+void acpi_cpu_hotplug_init(MemoryRegion *parent, Object *owner,
+   AcpiCpuHotplug *gpe_cpu, uint16_t base)
 {
 CPUState *cpu;
 
diff --git a/hw/acpi/ich9.c b/hw/acpi/ich9.c
index 7585364..ea991a3 100644
--- a/hw/acpi/ich9.c
+++ b/hw/acpi/ich9.c
@@ -235,8 +235,8 @@ void ich9_pm_init(PCIDevice *lpc_pci, ICH9LPCPMRegs *pm,
 pm->powerdown_notifier.notify = pm_powerdown_req;
 qemu_register_powerdown_notifier(&pm->powerdown_notifier);
 
-AcpiCpuHotplug_init(pci_address_space_io(lpc_pci), OBJECT(lpc_pci),
-&pm->gpe_cpu, ICH9_CPU_HOTPLUG_IO_BASE);
+acpi_cpu_hotplug_init(pci_address_space_io(lpc_pci), OBJECT(lpc_pci),
+  &pm->gpe_cpu, ICH9_CPU_HOTPLUG_IO_BASE);
 
 if (pm->acpi_memory_hotplug.is_enabled) {
 acpi_memory_hotplug_init(pci_address_space_io(lpc_pci), 
OBJECT(lpc_pci),
diff --git a/hw/acpi/piix4.c b/hw/acpi/piix4.c
index 8320b18..8fde808 100644
--- a/hw/acpi/piix4.c
+++ b/hw/acpi/piix4.c
@@ -555,8 +555,8 @@ static void piix4_acpi_system_hot_add_init(MemoryRegion 
*parent,
 acpi_pcihp_init(&s->acpi_pci_hotplug, bus, parent,
 s->use_acpi_pci_hotplug);
 
-AcpiCpuHotplug_init(parent, OBJECT(s), &s->gpe_cpu,
-PIIX4_CPU_HOTPLUG_IO_BASE);
+acpi_cpu_hotplug_init(parent, OBJECT(s), &s->gpe_cpu,
+  PIIX4_CPU_HOTPLUG_IO_BASE);
 
 if (s->acpi_memory_hotplug.is_enabled) {
 acpi_memory_hotplug_init(parent, OBJECT(s), &s->acpi_memory_hotplug);
diff --git a/include/hw/acpi/cpu_hotplug.h b/include/hw/acpi/cpu_hotplug.h
index 4657e71..f6d358d 100644
--- a/include/hw/acpi/cpu_hotplug.h
+++ b/include/hw/acpi/cpu_hotplug.h
@@ -23,6 +23,6 @@ typedef struct AcpiCpuHotplug {
 void acpi_cpu_plug_cb(ACPIREGS *ar, qemu_irq irq,
   AcpiCpuHotplug *g, DeviceState *dev, Error **errp);
 
-void AcpiCpuHotplug_init(MemoryRegion *parent, Object *owner,
- AcpiCpuHotplug *gpe_cpu, uint16_t base);
+void acpi_cpu_hotplug_init(MemoryRegion *parent, Object *owner,
+   AcpiCpuHotplug *gpe_cpu, uint16_t base);
 #endif
-- 
1.7.7




[Qemu-devel] [PATCH V5 8/8] acpi/cpu-hotplug: introduce helper function to keep bit setting in one place

2014-10-09 Thread Gu Zheng
Introduce helper function acpi_set_cpu_present_bit() to simplify 
acpi_cpu_plug_cb
and acpi_cpu_hotplug_init, so that we can keep bit setting in one place.

Signed-off-by: Gu Zheng 
---
v5:
 -rename acpi_set_local_sts to acpi_set_cpu_present_bit for better readability.

 hw/acpi/cpu_hotplug.c |   23 +++
 1 files changed, 15 insertions(+), 8 deletions(-)

diff --git a/hw/acpi/cpu_hotplug.c b/hw/acpi/cpu_hotplug.c
index ae48b63..8b8d15a 100644
--- a/hw/acpi/cpu_hotplug.c
+++ b/hw/acpi/cpu_hotplug.c
@@ -36,10 +36,9 @@ static const MemoryRegionOps AcpiCpuHotplug_ops = {
 },
 };
 
-void acpi_cpu_plug_cb(ACPIREGS *ar, qemu_irq irq,
-  AcpiCpuHotplug *g, DeviceState *dev, Error **errp)
+static void acpi_set_cpu_present_bit(AcpiCpuHotplug *g, CPUState *cpu,
+ Error **errp)
 {
-CPUState *cpu = CPU(dev);
 CPUClass *k = CPU_GET_CLASS(cpu);
 int64_t cpu_id;
 
@@ -49,9 +48,18 @@ void acpi_cpu_plug_cb(ACPIREGS *ar, qemu_irq irq,
 return;
 }
 
-ar->gpe.sts[0] |= ACPI_CPU_HOTPLUG_STATUS;
 g->sts[cpu_id / 8] |= (1 << (cpu_id % 8));
+}
 
+void acpi_cpu_plug_cb(ACPIREGS *ar, qemu_irq irq,
+  AcpiCpuHotplug *g, DeviceState *dev, Error **errp)
+{
+acpi_set_cpu_present_bit(g, CPU(dev), errp);
+if (*errp != NULL) {
+return;
+}
+
+ar->gpe.sts[0] |= ACPI_CPU_HOTPLUG_STATUS;
 acpi_update_sci(ar, irq);
 }
 
@@ -61,11 +69,10 @@ void acpi_cpu_hotplug_init(MemoryRegion *parent, Object 
*owner,
 CPUState *cpu;
 
 CPU_FOREACH(cpu) {
-CPUClass *cc = CPU_GET_CLASS(cpu);
-int64_t id = cc->get_arch_id(cpu);
+Error *local_err = NULL;
 
-g_assert((id / 8) < ACPI_GPE_PROC_LEN);
-gpe_cpu->sts[id / 8] |= (1 << (id % 8));
+acpi_set_cpu_present_bit(gpe_cpu, cpu, &local_err);
+g_assert(local_err == NULL);
 }
 memory_region_init_io(&gpe_cpu->io, owner, &AcpiCpuHotplug_ops,
   gpe_cpu, "acpi-cpu-hotplug", ACPI_GPE_PROC_LEN);
-- 
1.7.7




Re: [Qemu-devel] [PATCH V5 0/8] cpu/acpi: convert cpu hot plug to hotplug_handler API

2014-10-16 Thread Gu Zheng
ping...

On 10/10/2014 10:15 AM, Gu Zheng wrote:

> Previously we use cpu_added_notifiers to register cpu hotplug notifier 
> callback
> which is not able to pass/handle errors, so we switch it to unified hotplug
> handler API which allows to pass errors and would allow to cancel device_add
> in case of error.
> Thanks very much for Igor's review and suggestion.
> 
> ---
> v5:
>  -rebase on the latest upstream and fix some comments.
>  Patch 4/8:
>  -split the check out of acpi_dev block.
>  Patch 5/8:
>  -move CPU hot-plug notifier cleanup hunk into Patch 6/8.
>  Patch 6/8:
>  -delete the caller of notifier_list_notify() in this patch.
>  Patch 8/8:
>  -rename acpi_set_local_sts to acpi_set_cpu_present_bit for better 
> readability.
> 
> v4:
>  -split removal of CPU hotplug notifier into separate patch (Patch 6/8).
>  Patch 1/7:
>  -convert CPUState *cpu to DeviceState *dev like it's done for other handlers
>   and do cast to CPU inside.
>  Patch 5/7:
>  -Make rtc_state as a link property in PCMachine rather than the global
>   variables.
>  -Split out the removal of unused notifier into separate patch.
>  -Check the result of plug callback before update rtc_state.
> 
> v3:
>  -deal with start-up cpus in pc_cpu_plug as Igor suggested.
> 
> v2:
>  -Add 3 new patches(5/7,6/7,7/7), delete original patch 5/5.
>   1/5-->1/7
>   2/5-->2/7
>   3/5-->3/7
>   4/5-->4/7
>  Patch 1/7:
>  -add errp argument to catch error.
>  -return error instead of aborting if cpu id is invalid.
>  -make acpi_cpu_plug_cb as a wrapper around AcpiCpuHotplug_add.
>  Patch 3/7:
>  -remove unused AcpiCpuHotplug_add directly.
>  Patch 5/7:
>  -switch the last user of cpu hotplug notifier to hotplug handler API, and
>   remove the unused cpu hotplug notify.
>  Patch 6/7:
>  -split the function rename (just cleanup) into single patch.
>  Patch 7/7:
>  -introduce help function acpi_set_local_sts to keep the bit setting in
>   one place.
> ---
> 
> Gu Zheng (8):
>   acpi/cpu: add cpu hotplug callback function to match hotplug_handler
> API
>   acpi:ich9: convert cpu hotplug to hotplug_handler API
>   acpi:piix4: convert cpu hotplug to hotplug_handler API
>   pc: add cpu hotplug handler to PC_MACHINE
>   pc: Update rtc_cmos in pc_cpu_plug
>   qom/cpu: remove the unused CPU hot-plug notifier
>   cpu-hotplug: rename function for better readability
>   acpi/cpu-hotplug: introduce help function to keep bit setting in one
> place
> 
>  hw/acpi/cpu_hotplug.c |   35 --
>  hw/acpi/ich9.c|   17 ++
>  hw/acpi/piix4.c   |   18 ++-
>  hw/i386/pc.c  |   65 
> +++--
>  hw/i386/pc_piix.c |2 +-
>  hw/i386/pc_q35.c  |2 +-
>  include/hw/acpi/cpu_hotplug.h |7 ++--
>  include/hw/acpi/ich9.h|1 -
>  include/hw/i386/pc.h  |3 +-
>  include/sysemu/sysemu.h   |3 --
>  qom/cpu.c |   10 --
>  11 files changed, 84 insertions(+), 79 deletions(-)
> 





Re: [Qemu-devel] [PATCH V5 0/8] cpu/acpi: convert cpu hot plug to hotplug_handler API

2014-10-20 Thread Gu Zheng
Hi Igor,
How about this version?

Regards,
Gu
On 10/10/2014 10:15 AM, Gu Zheng wrote:

> Previously we use cpu_added_notifiers to register cpu hotplug notifier 
> callback
> which is not able to pass/handle errors, so we switch it to unified hotplug
> handler API which allows to pass errors and would allow to cancel device_add
> in case of error.
> Thanks very much for Igor's review and suggestion.
> 
> ---
> v5:
>  -rebase on the latest upstream and fix some comments.
>  Patch 4/8:
>  -split the check out of acpi_dev block.
>  Patch 5/8:
>  -move CPU hot-plug notifier cleanup hunk into Patch 6/8.
>  Patch 6/8:
>  -delete the caller of notifier_list_notify() in this patch.
>  Patch 8/8:
>  -rename acpi_set_local_sts to acpi_set_cpu_present_bit for better 
> readability.
> 
> v4:
>  -split removal of CPU hotplug notifier into separate patch (Patch 6/8).
>  Patch 1/7:
>  -convert CPUState *cpu to DeviceState *dev like it's done for other handlers
>   and do cast to CPU inside.
>  Patch 5/7:
>  -Make rtc_state as a link property in PCMachine rather than the global
>   variables.
>  -Split out the removal of unused notifier into separate patch.
>  -Check the result of plug callback before update rtc_state.
> 
> v3:
>  -deal with start-up cpus in pc_cpu_plug as Igor suggested.
> 
> v2:
>  -Add 3 new patches(5/7,6/7,7/7), delete original patch 5/5.
>   1/5-->1/7
>   2/5-->2/7
>   3/5-->3/7
>   4/5-->4/7
>  Patch 1/7:
>  -add errp argument to catch error.
>  -return error instead of aborting if cpu id is invalid.
>  -make acpi_cpu_plug_cb as a wrapper around AcpiCpuHotplug_add.
>  Patch 3/7:
>  -remove unused AcpiCpuHotplug_add directly.
>  Patch 5/7:
>  -switch the last user of cpu hotplug notifier to hotplug handler API, and
>   remove the unused cpu hotplug notify.
>  Patch 6/7:
>  -split the function rename (just cleanup) into single patch.
>  Patch 7/7:
>  -introduce help function acpi_set_local_sts to keep the bit setting in
>   one place.
> ---
> 
> Gu Zheng (8):
>   acpi/cpu: add cpu hotplug callback function to match hotplug_handler
> API
>   acpi:ich9: convert cpu hotplug to hotplug_handler API
>   acpi:piix4: convert cpu hotplug to hotplug_handler API
>   pc: add cpu hotplug handler to PC_MACHINE
>   pc: Update rtc_cmos in pc_cpu_plug
>   qom/cpu: remove the unused CPU hot-plug notifier
>   cpu-hotplug: rename function for better readability
>   acpi/cpu-hotplug: introduce help function to keep bit setting in one
> place
> 
>  hw/acpi/cpu_hotplug.c |   35 --
>  hw/acpi/ich9.c|   17 ++
>  hw/acpi/piix4.c   |   18 ++-
>  hw/i386/pc.c  |   65 
> +++--
>  hw/i386/pc_piix.c |2 +-
>  hw/i386/pc_q35.c  |2 +-
>  include/hw/acpi/cpu_hotplug.h |7 ++--
>  include/hw/acpi/ich9.h|1 -
>  include/hw/i386/pc.h  |3 +-
>  include/sysemu/sysemu.h   |3 --
>  qom/cpu.c |   10 --
>  11 files changed, 84 insertions(+), 79 deletions(-)
> 





Re: [Qemu-devel] [PATCH V5 8/8] acpi/cpu-hotplug: introduce helper function to keep bit setting in one place

2014-10-20 Thread Gu Zheng
Hi Igor,
On 10/20/2014 11:09 PM, Igor Mammedov wrote:

> On Fri, 10 Oct 2014 10:16:07 +0800
> Gu Zheng  wrote:
> 
>> Introduce helper function acpi_set_cpu_present_bit() to simplify 
>> acpi_cpu_plug_cb
>> and acpi_cpu_hotplug_init, so that we can keep bit setting in one place.
>>
>> Signed-off-by: Gu Zheng 
>> ---
>> v5:
>>  -rename acpi_set_local_sts to acpi_set_cpu_present_bit for better 
>> readability.
>>
>>  hw/acpi/cpu_hotplug.c |   23 +++
>>  1 files changed, 15 insertions(+), 8 deletions(-)
>>
>> diff --git a/hw/acpi/cpu_hotplug.c b/hw/acpi/cpu_hotplug.c
>> index ae48b63..8b8d15a 100644
>> --- a/hw/acpi/cpu_hotplug.c
>> +++ b/hw/acpi/cpu_hotplug.c
>> @@ -36,10 +36,9 @@ static const MemoryRegionOps AcpiCpuHotplug_ops = {
>>  },
>>  };
>>  
>> -void acpi_cpu_plug_cb(ACPIREGS *ar, qemu_irq irq,
>> -  AcpiCpuHotplug *g, DeviceState *dev, Error **errp)
>> +static void acpi_set_cpu_present_bit(AcpiCpuHotplug *g, CPUState *cpu,
>> + Error **errp)
>>  {
>> -CPUState *cpu = CPU(dev);
>>  CPUClass *k = CPU_GET_CLASS(cpu);
>>  int64_t cpu_id;
>>  
>> @@ -49,9 +48,18 @@ void acpi_cpu_plug_cb(ACPIREGS *ar, qemu_irq irq,
>>  return;
>>  }
>>  
>> -ar->gpe.sts[0] |= ACPI_CPU_HOTPLUG_STATUS;
>>  g->sts[cpu_id / 8] |= (1 << (cpu_id % 8));
>> +}
>>  
>> +void acpi_cpu_plug_cb(ACPIREGS *ar, qemu_irq irq,
>> +  AcpiCpuHotplug *g, DeviceState *dev, Error **errp)
>> +{
>> +acpi_set_cpu_present_bit(g, CPU(dev), errp);
>> +if (*errp != NULL) {
>> +return;
>> +}
>> +
>> +ar->gpe.sts[0] |= ACPI_CPU_HOTPLUG_STATUS;
>>  acpi_update_sci(ar, irq);
>>  }
>>  
>> @@ -61,11 +69,10 @@ void acpi_cpu_hotplug_init(MemoryRegion *parent, Object 
>> *owner,
>>  CPUState *cpu;
>>  
>>  CPU_FOREACH(cpu) {
>> -CPUClass *cc = CPU_GET_CLASS(cpu);
>> -int64_t id = cc->get_arch_id(cpu);
>> +Error *local_err = NULL;
>>  
>> -g_assert((id / 8) < ACPI_GPE_PROC_LEN);
>> -gpe_cpu->sts[id / 8] |= (1 << (id % 8));
>> +acpi_set_cpu_present_bit(gpe_cpu, cpu, &local_err);
>> +g_assert(local_err == NULL);
> it would be nice to report error before dying,
> using error_abort instead of local_err will do that for you.

It would be nice. I'll fix it.
Thanks very for your review.

Best regards,
Gu

> 
>>  }
>>  memory_region_init_io(&gpe_cpu->io, owner, &AcpiCpuHotplug_ops,
>>gpe_cpu, "acpi-cpu-hotplug", ACPI_GPE_PROC_LEN);
> 
> .
> 





[Qemu-devel] [PATCH V6 0/8] cpu/acpi: convert cpu hot plug to hotplug_handler API

2014-10-21 Thread Gu Zheng
Previously we use cpu_added_notifiers to register cpu hotplug notifier callback
which is not able to pass/handle errors, so we switch it to unified hotplug
handler API which allows to pass errors and would allow to cancel device_add
in case of error.
Thanks very much for Igor's review and suggestion.

---
v6:
 Patch 8/8:
 -using error_abort instead of local_err, so that we can gain the error report
  before abort (suggested by Igor).

v5:
 -rebase on the latest upstream and fix some comments.
 Patch 4/8:
 -split the check out of acpi_dev block.
 Patch 5/8:
 -move CPU hot-plug notifier cleanup hunk into Patch 6/8.
 Patch 6/8:
 -delete the caller of notifier_list_notify() in this patch.
 Patch 8/8:
 -rename acpi_set_local_sts to acpi_set_cpu_present_bit for better readability.

v4:
 -split removal of CPU hotplug notifier into separate patch (Patch 6/8).
 Patch 1/7:
 -convert CPUState *cpu to DeviceState *dev like it's done for other handlers
  and do cast to CPU inside.
 Patch 5/7:
 -Make rtc_state as a link property in PCMachine rather than the global
  variables.
 -Split out the removal of unused notifier into separate patch.
 -Check the result of plug callback before update rtc_state.

v3:
 -deal with start-up cpus in pc_cpu_plug as Igor suggested.

v2:
 -Add 3 new patches(5/7,6/7,7/7), delete original patch 5/5.
  1/5-->1/7
  2/5-->2/7
  3/5-->3/7
  4/5-->4/7
 Patch 1/7:
 -add errp argument to catch error.
 -return error instead of aborting if cpu id is invalid.
 -make acpi_cpu_plug_cb as a wrapper around AcpiCpuHotplug_add.
 Patch 3/7:
 -remove unused AcpiCpuHotplug_add directly.
 Patch 5/7:
 -switch the last user of cpu hotplug notifier to hotplug handler API, and
  remove the unused cpu hotplug notify.
 Patch 6/7:
 -split the function rename (just cleanup) into single patch.
 Patch 7/7:
 -introduce help function acpi_set_local_sts to keep the bit setting in
  one place.
---

Gu Zheng (8):
  acpi/cpu: add cpu hotplug callback function to match hotplug_handler
API
  acpi:ich9: convert cpu hotplug to hotplug_handler API
  acpi:piix4: convert cpu hotplug to hotplug_handler API
  pc: add cpu hotplug handler to PC_MACHINE
  pc: Update rtc_cmos in pc_cpu_plug
  qom/cpu: remove the unused CPU hot-plug notifier
  cpu-hotplug: rename function for better readability
  acpi/cpu-hotplug: introduce helper function to keep bit setting in
one place

 hw/acpi/cpu_hotplug.c |   34 ++---
 hw/acpi/ich9.c|   17 ++
 hw/acpi/piix4.c   |   18 ++-
 hw/i386/pc.c  |   65 +++--
 hw/i386/pc_piix.c |2 +-
 hw/i386/pc_q35.c  |2 +-
 include/hw/acpi/cpu_hotplug.h |7 ++--
 include/hw/acpi/ich9.h|1 -
 include/hw/i386/pc.h  |3 +-
 include/sysemu/sysemu.h   |3 --
 qom/cpu.c |   10 --
 11 files changed, 82 insertions(+), 80 deletions(-)

-- 
1.7.7




[Qemu-devel] [PATCH V6 1/8] acpi/cpu: add cpu hotplug callback function to match hotplug_handler API

2014-10-21 Thread Gu Zheng
Add cpu hotplug callback function (acpi_cpu_plug_cb) to match hotplug_handler 
API.

Reviewed-by: Igor Mammedov 
Signed-off-by: Gu Zheng 
---
v4:
 -convert CPUState *cpu to DeviceState *dev like it's done for other handlers
  and do cast to CPU inside.
v2:
 -add errp argument to catch error.
 -return error instead of aborting if cpu id is invalid.
 -make acpi_cpu_plug_cb as a wrapper around AcpiCpuHotplug_add.

 hw/acpi/cpu_hotplug.c |   18 ++
 include/hw/acpi/cpu_hotplug.h |3 +++
 2 files changed, 21 insertions(+), 0 deletions(-)

diff --git a/hw/acpi/cpu_hotplug.c b/hw/acpi/cpu_hotplug.c
index 2ad83a0..06e9c61 100644
--- a/hw/acpi/cpu_hotplug.c
+++ b/hw/acpi/cpu_hotplug.c
@@ -36,6 +36,24 @@ static const MemoryRegionOps AcpiCpuHotplug_ops = {
 },
 };
 
+void acpi_cpu_plug_cb(ACPIREGS *ar, qemu_irq irq,
+  AcpiCpuHotplug *g, DeviceState *dev, Error **errp)
+{
+CPUState *cpu = CPU(dev);
+CPUClass *k = CPU_GET_CLASS(cpu);
+int64_t cpu_id;
+
+cpu_id = k->get_arch_id(cpu);
+if ((cpu_id / 8) >= ACPI_GPE_PROC_LEN) {
+error_setg(errp, "acpi: invalid cpu id: %" PRIi64, cpu_id);
+return;
+}
+
+AcpiCpuHotplug_add(&ar->gpe, g, cpu);
+
+acpi_update_sci(ar, irq);
+}
+
 void AcpiCpuHotplug_add(ACPIGPE *gpe, AcpiCpuHotplug *g, CPUState *cpu)
 {
 CPUClass *k = CPU_GET_CLASS(cpu);
diff --git a/include/hw/acpi/cpu_hotplug.h b/include/hw/acpi/cpu_hotplug.h
index 9e5d30c..5dca8d7 100644
--- a/include/hw/acpi/cpu_hotplug.h
+++ b/include/hw/acpi/cpu_hotplug.h
@@ -20,6 +20,9 @@ typedef struct AcpiCpuHotplug {
 uint8_t sts[ACPI_GPE_PROC_LEN];
 } AcpiCpuHotplug;
 
+void acpi_cpu_plug_cb(ACPIREGS *ar, qemu_irq irq,
+  AcpiCpuHotplug *g, DeviceState *dev, Error **errp);
+
 void AcpiCpuHotplug_add(ACPIGPE *gpe, AcpiCpuHotplug *g, CPUState *cpu);
 
 void AcpiCpuHotplug_init(MemoryRegion *parent, Object *owner,
-- 
1.7.7




[Qemu-devel] [PATCH V6 2/8] acpi:ich9: convert cpu hotplug to hotplug_handler API

2014-10-21 Thread Gu Zheng
Convert notifier based hotplug to hotplug_handler API.

Reviewed-by: Igor Mammedov 
Signed-off-by: Gu Zheng 
---
v5:
 -drop 'handle' from the comment and subject.

 hw/acpi/ich9.c |   13 ++---
 include/hw/acpi/ich9.h |1 -
 2 files changed, 2 insertions(+), 12 deletions(-)

diff --git a/hw/acpi/ich9.c b/hw/acpi/ich9.c
index 7b14bbb..7585364 100644
--- a/hw/acpi/ich9.c
+++ b/hw/acpi/ich9.c
@@ -209,15 +209,6 @@ static void pm_powerdown_req(Notifier *n, void *opaque)
 acpi_pm1_evt_power_down(&pm->acpi_regs);
 }
 
-static void ich9_cpu_added_req(Notifier *n, void *opaque)
-{
-ICH9LPCPMRegs *pm = container_of(n, ICH9LPCPMRegs, cpu_added_notifier);
-
-assert(pm != NULL);
-AcpiCpuHotplug_add(&pm->acpi_regs.gpe, &pm->gpe_cpu, CPU(opaque));
-acpi_update_sci(&pm->acpi_regs, pm->irq);
-}
-
 void ich9_pm_init(PCIDevice *lpc_pci, ICH9LPCPMRegs *pm,
   qemu_irq sci_irq)
 {
@@ -246,8 +237,6 @@ void ich9_pm_init(PCIDevice *lpc_pci, ICH9LPCPMRegs *pm,
 
 AcpiCpuHotplug_init(pci_address_space_io(lpc_pci), OBJECT(lpc_pci),
 &pm->gpe_cpu, ICH9_CPU_HOTPLUG_IO_BASE);
-pm->cpu_added_notifier.notify = ich9_cpu_added_req;
-qemu_register_cpu_added_notifier(&pm->cpu_added_notifier);
 
 if (pm->acpi_memory_hotplug.is_enabled) {
 acpi_memory_hotplug_init(pci_address_space_io(lpc_pci), 
OBJECT(lpc_pci),
@@ -304,6 +293,8 @@ void ich9_pm_device_plug_cb(ICH9LPCPMRegs *pm, DeviceState 
*dev, Error **errp)
 object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
 acpi_memory_plug_cb(&pm->acpi_regs, pm->irq, &pm->acpi_memory_hotplug,
 dev, errp);
+} else if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) {
+acpi_cpu_plug_cb(&pm->acpi_regs, pm->irq, &pm->gpe_cpu, dev, errp);
 } else {
 error_setg(errp, "acpi: device plug request for not supported device"
" type: %s", object_get_typename(OBJECT(dev)));
diff --git a/include/hw/acpi/ich9.h b/include/hw/acpi/ich9.h
index 7e42448..fe975e6 100644
--- a/include/hw/acpi/ich9.h
+++ b/include/hw/acpi/ich9.h
@@ -47,7 +47,6 @@ typedef struct ICH9LPCPMRegs {
 Notifier powerdown_notifier;
 
 AcpiCpuHotplug gpe_cpu;
-Notifier cpu_added_notifier;
 
 MemHotplugState acpi_memory_hotplug;
 } ICH9LPCPMRegs;
-- 
1.7.7




[Qemu-devel] [PATCH V6 3/8] acpi:piix4: convert cpu hotplug to hotplug_handler API

2014-10-21 Thread Gu Zheng
Convert notifier based hotplug to hotplug_handler API,
and remove the unused AcpiCpuHotplug_add().

Reviewed-by: Igor Mammedov 
Signed-off-by: Gu Zheng 
---
v5:
 -drop 'handle' from the comment and subject.
v2:
 -remove the unused AcpiCpuHotplug_add().

 hw/acpi/cpu_hotplug.c |   14 ++
 hw/acpi/piix4.c   |   14 ++
 include/hw/acpi/cpu_hotplug.h |2 --
 3 files changed, 4 insertions(+), 26 deletions(-)

diff --git a/hw/acpi/cpu_hotplug.c b/hw/acpi/cpu_hotplug.c
index 06e9c61..b69b16c 100644
--- a/hw/acpi/cpu_hotplug.c
+++ b/hw/acpi/cpu_hotplug.c
@@ -49,22 +49,12 @@ void acpi_cpu_plug_cb(ACPIREGS *ar, qemu_irq irq,
 return;
 }
 
-AcpiCpuHotplug_add(&ar->gpe, g, cpu);
+ar->gpe.sts[0] |= ACPI_CPU_HOTPLUG_STATUS;
+g->sts[cpu_id / 8] |= (1 << (cpu_id % 8));
 
 acpi_update_sci(ar, irq);
 }
 
-void AcpiCpuHotplug_add(ACPIGPE *gpe, AcpiCpuHotplug *g, CPUState *cpu)
-{
-CPUClass *k = CPU_GET_CLASS(cpu);
-int64_t cpu_id;
-
-*gpe->sts = *gpe->sts | ACPI_CPU_HOTPLUG_STATUS;
-cpu_id = k->get_arch_id(CPU(cpu));
-g_assert((cpu_id / 8) < ACPI_GPE_PROC_LEN);
-g->sts[cpu_id / 8] |= (1 << (cpu_id % 8));
-}
-
 void AcpiCpuHotplug_init(MemoryRegion *parent, Object *owner,
  AcpiCpuHotplug *gpe_cpu, uint16_t base)
 {
diff --git a/hw/acpi/piix4.c b/hw/acpi/piix4.c
index b72b34e..8320b18 100644
--- a/hw/acpi/piix4.c
+++ b/hw/acpi/piix4.c
@@ -83,7 +83,6 @@ typedef struct PIIX4PMState {
 uint8_t s4_val;
 
 AcpiCpuHotplug gpe_cpu;
-Notifier cpu_added_notifier;
 
 MemHotplugState acpi_memory_hotplug;
 } PIIX4PMState;
@@ -348,6 +347,8 @@ static void piix4_device_plug_cb(HotplugHandler 
*hotplug_dev,
 } else if (object_dynamic_cast(OBJECT(dev), TYPE_PCI_DEVICE)) {
 acpi_pcihp_device_plug_cb(&s->ar, s->irq, &s->acpi_pci_hotplug, dev,
   errp);
+} else if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) {
+acpi_cpu_plug_cb(&s->ar, s->irq, &s->gpe_cpu, dev, errp);
 } else {
 error_setg(errp, "acpi: device plug request for not supported device"
" type: %s", object_get_typename(OBJECT(dev)));
@@ -544,15 +545,6 @@ static const MemoryRegionOps piix4_gpe_ops = {
 .endianness = DEVICE_LITTLE_ENDIAN,
 };
 
-static void piix4_cpu_added_req(Notifier *n, void *opaque)
-{
-PIIX4PMState *s = container_of(n, PIIX4PMState, cpu_added_notifier);
-
-assert(s != NULL);
-AcpiCpuHotplug_add(&s->ar.gpe, &s->gpe_cpu, CPU(opaque));
-acpi_update_sci(&s->ar, s->irq);
-}
-
 static void piix4_acpi_system_hot_add_init(MemoryRegion *parent,
PCIBus *bus, PIIX4PMState *s)
 {
@@ -565,8 +557,6 @@ static void piix4_acpi_system_hot_add_init(MemoryRegion 
*parent,
 
 AcpiCpuHotplug_init(parent, OBJECT(s), &s->gpe_cpu,
 PIIX4_CPU_HOTPLUG_IO_BASE);
-s->cpu_added_notifier.notify = piix4_cpu_added_req;
-qemu_register_cpu_added_notifier(&s->cpu_added_notifier);
 
 if (s->acpi_memory_hotplug.is_enabled) {
 acpi_memory_hotplug_init(parent, OBJECT(s), &s->acpi_memory_hotplug);
diff --git a/include/hw/acpi/cpu_hotplug.h b/include/hw/acpi/cpu_hotplug.h
index 5dca8d7..4657e71 100644
--- a/include/hw/acpi/cpu_hotplug.h
+++ b/include/hw/acpi/cpu_hotplug.h
@@ -23,8 +23,6 @@ typedef struct AcpiCpuHotplug {
 void acpi_cpu_plug_cb(ACPIREGS *ar, qemu_irq irq,
   AcpiCpuHotplug *g, DeviceState *dev, Error **errp);
 
-void AcpiCpuHotplug_add(ACPIGPE *gpe, AcpiCpuHotplug *g, CPUState *cpu);
-
 void AcpiCpuHotplug_init(MemoryRegion *parent, Object *owner,
  AcpiCpuHotplug *gpe_cpu, uint16_t base);
 #endif
-- 
1.7.7




[Qemu-devel] [PATCH V6 4/8] pc: add cpu hotplug handler to PC_MACHINE

2014-10-21 Thread Gu Zheng
Add cpu hotplug handler to PC_MACHINE, which will perform the acpi
cpu hotplug callback via hotplug_handler API.

Reviewed-by: Igor Mammedov 
Signed-off-by: Gu Zheng 
---
v5:
 -split the check out of acpi_dev block.
v3:
 -deal with start up cpus in a more neat way as Igor suggested.
v2:
 -just rebase.

 hw/i386/pc.c |   28 +++-
 1 files changed, 27 insertions(+), 1 deletions(-)

diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index d045e8b..eff19ef 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -1617,11 +1617,36 @@ out:
 error_propagate(errp, local_err);
 }
 
+static void pc_cpu_plug(HotplugHandler *hotplug_dev,
+DeviceState *dev, Error **errp)
+{
+HotplugHandlerClass *hhc;
+Error *local_err = NULL;
+PCMachineState *pcms = PC_MACHINE(hotplug_dev);
+
+if (!dev->hotplugged) {
+goto out;
+}
+
+if (!pcms->acpi_dev) {
+error_setg(&local_err,
+   "cpu hotplug is not enabled: missing acpi device");
+goto out;
+}
+
+hhc = HOTPLUG_HANDLER_GET_CLASS(pcms->acpi_dev);
+hhc->plug(HOTPLUG_HANDLER(pcms->acpi_dev), dev, &local_err);
+out:
+error_propagate(errp, local_err);
+}
+
 static void pc_machine_device_plug_cb(HotplugHandler *hotplug_dev,
   DeviceState *dev, Error **errp)
 {
 if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
 pc_dimm_plug(hotplug_dev, dev, errp);
+} else if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) {
+pc_cpu_plug(hotplug_dev, dev, errp);
 }
 }
 
@@ -1630,7 +1655,8 @@ static HotplugHandler *pc_get_hotpug_handler(MachineState 
*machine,
 {
 PCMachineClass *pcmc = PC_MACHINE_GET_CLASS(machine);
 
-if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
+if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM) ||
+object_dynamic_cast(OBJECT(dev), TYPE_CPU)) {
 return HOTPLUG_HANDLER(machine);
 }
 
-- 
1.7.7




[Qemu-devel] [PATCH V6 5/8] pc: Update rtc_cmos in pc_cpu_plug

2014-10-21 Thread Gu Zheng
Update rtc_cmos in pc_cpu_plug() directly, instead of the notifier.

Reviewed-by: Igor Mammedov 
Signed-off-by: Gu Zheng 
---
v5:
 -move CPU hot-plug notifier cleanup hunk into Patch 6/8.

v4:
 -Make link property in PCMachine rather than the global
  variables.
 -Split out the removal of unused notifier into separate patch.

 hw/i386/pc.c |   37 -
 hw/i386/pc_piix.c|2 +-
 hw/i386/pc_q35.c |2 +-
 include/hw/i386/pc.h |3 ++-
 4 files changed, 20 insertions(+), 24 deletions(-)

diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index eff19ef..0f10ec8 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -355,30 +355,15 @@ static void pc_cmos_init_late(void *opaque)
 qemu_unregister_reset(pc_cmos_init_late, opaque);
 }
 
-typedef struct RTCCPUHotplugArg {
-Notifier cpu_added_notifier;
-ISADevice *rtc_state;
-} RTCCPUHotplugArg;
-
-static void rtc_notify_cpu_added(Notifier *notifier, void *data)
-{
-RTCCPUHotplugArg *arg = container_of(notifier, RTCCPUHotplugArg,
- cpu_added_notifier);
-ISADevice *s = arg->rtc_state;
-
-/* increment the number of CPUs */
-rtc_set_memory(s, 0x5f, rtc_get_memory(s, 0x5f) + 1);
-}
-
 void pc_cmos_init(ram_addr_t ram_size, ram_addr_t above_4g_mem_size,
-  const char *boot_device,
+  const char *boot_device, MachineState *machine,
   ISADevice *floppy, BusState *idebus0, BusState *idebus1,
   ISADevice *s)
 {
 int val, nb, i;
 FDriveType fd_type[2] = { FDRIVE_DRV_NONE, FDRIVE_DRV_NONE };
 static pc_cmos_init_late_arg arg;
-static RTCCPUHotplugArg cpu_hotplug_cb;
+PCMachineState *pc_machine = PC_MACHINE(machine);
 
 /* various important CMOS locations needed by PC/Bochs bios */
 
@@ -417,10 +402,14 @@ void pc_cmos_init(ram_addr_t ram_size, ram_addr_t 
above_4g_mem_size,
 
 /* set the number of CPU */
 rtc_set_memory(s, 0x5f, smp_cpus - 1);
-/* init CPU hotplug notifier */
-cpu_hotplug_cb.rtc_state = s;
-cpu_hotplug_cb.cpu_added_notifier.notify = rtc_notify_cpu_added;
-qemu_register_cpu_added_notifier(&cpu_hotplug_cb.cpu_added_notifier);
+
+object_property_add_link(OBJECT(machine), "rtc_state",
+ TYPE_ISA_DEVICE,
+ (Object **)&pc_machine->rtc,
+ object_property_allow_set_link,
+ OBJ_PROP_LINK_UNREF_ON_RELEASE, &error_abort);
+object_property_set_link(OBJECT(machine), OBJECT(s),
+ "rtc_state", &error_abort);
 
 if (set_boot_dev(s, boot_device)) {
 exit(1);
@@ -1636,6 +1625,12 @@ static void pc_cpu_plug(HotplugHandler *hotplug_dev,
 
 hhc = HOTPLUG_HANDLER_GET_CLASS(pcms->acpi_dev);
 hhc->plug(HOTPLUG_HANDLER(pcms->acpi_dev), dev, &local_err);
+if (local_err) {
+goto out;
+}
+
+/* increment the number of CPUs */
+rtc_set_memory(pcms->rtc, 0x5f, rtc_get_memory(pcms->rtc, 0x5f) + 1);
 out:
 error_propagate(errp, local_err);
 }
diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index 4384633..2ff7e84 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -266,7 +266,7 @@ static void pc_init1(MachineState *machine,
 }
 
 pc_cmos_init(below_4g_mem_size, above_4g_mem_size, machine->boot_order,
- floppy, idebus[0], idebus[1], rtc_state);
+ machine, floppy, idebus[0], idebus[1], rtc_state);
 
 if (pci_enabled && usb_enabled(false)) {
 pci_create_simple(pci_bus, piix3_devfn + 2, "piix3-usb-uhci");
diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c
index bb0dc8e..7cab8e4 100644
--- a/hw/i386/pc_q35.c
+++ b/hw/i386/pc_q35.c
@@ -270,7 +270,7 @@ static void pc_q35_init(MachineState *machine)
   8, NULL, 0);
 
 pc_cmos_init(below_4g_mem_size, above_4g_mem_size, machine->boot_order,
- floppy, idebus[0], idebus[1], rtc_state);
+ machine, floppy, idebus[0], idebus[1], rtc_state);
 
 /* the rest devices to which pci devfn is automatically assigned */
 pc_vga_init(isa_bus, host_bus);
diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
index 77316d5..7a4bff4 100644
--- a/include/hw/i386/pc.h
+++ b/include/hw/i386/pc.h
@@ -33,6 +33,7 @@ struct PCMachineState {
 MemoryRegion hotplug_memory;
 
 HotplugHandler *acpi_dev;
+ISADevice *rtc;
 
 uint64_t max_ram_below_4g;
 };
@@ -210,7 +211,7 @@ void pc_basic_device_init(ISABus *isa_bus, qemu_irq *gsi,
   uint32 hpet_irqs);
 void pc_init_ne2k_isa(ISABus *bus, NICInfo *nd);
 void pc_cmos_init(ram_addr_t ram_size, ram_addr_t above_4g_mem_size,
-  const char *boot_device,
+  const char *boot_device, MachineState *machine,
   ISADevice *floppy, BusState *ide0

[Qemu-devel] [PATCH V6 6/8] qom/cpu: remove the unused CPU hot-plug notifier

2014-10-21 Thread Gu Zheng
Remove the unused CPU hot-plug notifier.

Reviewed-by: Igor Mammedov 
Signed-off-by: Gu Zheng 
---
v5:
 -delete the caller of notifier_list_notify() in this patch.

 include/sysemu/sysemu.h |3 ---
 qom/cpu.c   |   10 --
 2 files changed, 0 insertions(+), 13 deletions(-)

diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h
index d8539fd..acfe494 100644
--- a/include/sysemu/sysemu.h
+++ b/include/sysemu/sysemu.h
@@ -183,9 +183,6 @@ void do_pci_device_hot_remove(Monitor *mon, const QDict 
*qdict);
 /* generic hotplug */
 void drive_hot_add(Monitor *mon, const QDict *qdict);
 
-/* CPU hotplug */
-void qemu_register_cpu_added_notifier(Notifier *notifier);
-
 /* pcie aer error injection */
 void pcie_aer_inject_error_print(Monitor *mon, const QObject *data);
 int do_pcie_aer_inject_error(Monitor *mon,
diff --git a/qom/cpu.c b/qom/cpu.c
index 0ec3337..79d2228 100644
--- a/qom/cpu.c
+++ b/qom/cpu.c
@@ -107,15 +107,6 @@ static void cpu_common_get_memory_mapping(CPUState *cpu,
 error_setg(errp, "Obtaining memory mappings is unsupported on this CPU.");
 }
 
-/* CPU hot-plug notifiers */
-static NotifierList cpu_added_notifiers =
-NOTIFIER_LIST_INITIALIZER(cpu_add_notifiers);
-
-void qemu_register_cpu_added_notifier(Notifier *notifier)
-{
-notifier_list_add(&cpu_added_notifiers, notifier);
-}
-
 void cpu_reset_interrupt(CPUState *cpu, int mask)
 {
 cpu->interrupt_request &= ~mask;
@@ -312,7 +303,6 @@ static void cpu_common_realizefn(DeviceState *dev, Error 
**errp)
 
 if (dev->hotplugged) {
 cpu_synchronize_post_init(cpu);
-notifier_list_notify(&cpu_added_notifiers, dev);
 cpu_resume(cpu);
 }
 }
-- 
1.7.7




[Qemu-devel] [PATCH V6 7/8] cpu-hotplug: rename function for better readability

2014-10-21 Thread Gu Zheng
Rename:
AcpiCpuHotplug_init --> acpi_cpu_hotplug_init
AcpiCpuHotplug_ops --> acpi_cpu_hotplug_ops
for better readability, just cleanup.

Reviewed-by: Igor Mammedov 
Signed-off-by: Gu Zheng 
---
 hw/acpi/cpu_hotplug.c |4 ++--
 hw/acpi/ich9.c|4 ++--
 hw/acpi/piix4.c   |4 ++--
 include/hw/acpi/cpu_hotplug.h |4 ++--
 4 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/hw/acpi/cpu_hotplug.c b/hw/acpi/cpu_hotplug.c
index b69b16c..ae48b63 100644
--- a/hw/acpi/cpu_hotplug.c
+++ b/hw/acpi/cpu_hotplug.c
@@ -55,8 +55,8 @@ void acpi_cpu_plug_cb(ACPIREGS *ar, qemu_irq irq,
 acpi_update_sci(ar, irq);
 }
 
-void AcpiCpuHotplug_init(MemoryRegion *parent, Object *owner,
- AcpiCpuHotplug *gpe_cpu, uint16_t base)
+void acpi_cpu_hotplug_init(MemoryRegion *parent, Object *owner,
+   AcpiCpuHotplug *gpe_cpu, uint16_t base)
 {
 CPUState *cpu;
 
diff --git a/hw/acpi/ich9.c b/hw/acpi/ich9.c
index 7585364..ea991a3 100644
--- a/hw/acpi/ich9.c
+++ b/hw/acpi/ich9.c
@@ -235,8 +235,8 @@ void ich9_pm_init(PCIDevice *lpc_pci, ICH9LPCPMRegs *pm,
 pm->powerdown_notifier.notify = pm_powerdown_req;
 qemu_register_powerdown_notifier(&pm->powerdown_notifier);
 
-AcpiCpuHotplug_init(pci_address_space_io(lpc_pci), OBJECT(lpc_pci),
-&pm->gpe_cpu, ICH9_CPU_HOTPLUG_IO_BASE);
+acpi_cpu_hotplug_init(pci_address_space_io(lpc_pci), OBJECT(lpc_pci),
+  &pm->gpe_cpu, ICH9_CPU_HOTPLUG_IO_BASE);
 
 if (pm->acpi_memory_hotplug.is_enabled) {
 acpi_memory_hotplug_init(pci_address_space_io(lpc_pci), 
OBJECT(lpc_pci),
diff --git a/hw/acpi/piix4.c b/hw/acpi/piix4.c
index 8320b18..8fde808 100644
--- a/hw/acpi/piix4.c
+++ b/hw/acpi/piix4.c
@@ -555,8 +555,8 @@ static void piix4_acpi_system_hot_add_init(MemoryRegion 
*parent,
 acpi_pcihp_init(&s->acpi_pci_hotplug, bus, parent,
 s->use_acpi_pci_hotplug);
 
-AcpiCpuHotplug_init(parent, OBJECT(s), &s->gpe_cpu,
-PIIX4_CPU_HOTPLUG_IO_BASE);
+acpi_cpu_hotplug_init(parent, OBJECT(s), &s->gpe_cpu,
+  PIIX4_CPU_HOTPLUG_IO_BASE);
 
 if (s->acpi_memory_hotplug.is_enabled) {
 acpi_memory_hotplug_init(parent, OBJECT(s), &s->acpi_memory_hotplug);
diff --git a/include/hw/acpi/cpu_hotplug.h b/include/hw/acpi/cpu_hotplug.h
index 4657e71..f6d358d 100644
--- a/include/hw/acpi/cpu_hotplug.h
+++ b/include/hw/acpi/cpu_hotplug.h
@@ -23,6 +23,6 @@ typedef struct AcpiCpuHotplug {
 void acpi_cpu_plug_cb(ACPIREGS *ar, qemu_irq irq,
   AcpiCpuHotplug *g, DeviceState *dev, Error **errp);
 
-void AcpiCpuHotplug_init(MemoryRegion *parent, Object *owner,
- AcpiCpuHotplug *gpe_cpu, uint16_t base);
+void acpi_cpu_hotplug_init(MemoryRegion *parent, Object *owner,
+   AcpiCpuHotplug *gpe_cpu, uint16_t base);
 #endif
-- 
1.7.7




[Qemu-devel] [PATCH V6 8/8] acpi/cpu-hotplug: introduce helper function to keep bit setting in one place

2014-10-21 Thread Gu Zheng
Introduce helper function acpi_set_cpu_present_bit() to simplify 
acpi_cpu_plug_cb
and acpi_cpu_hotplug_init, so that we can keep bit setting in one place.

Signed-off-by: Gu Zheng 
---
v6:
 -using error_abort instead of local_err, so that we can gain the error report
  before abort (suggested by Igor).
v5:
 -rename acpi_set_local_sts to acpi_set_cpu_present_bit for better readability.

 hw/acpi/cpu_hotplug.c |   22 +-
 1 files changed, 13 insertions(+), 9 deletions(-)

diff --git a/hw/acpi/cpu_hotplug.c b/hw/acpi/cpu_hotplug.c
index ae48b63..b8ebfad 100644
--- a/hw/acpi/cpu_hotplug.c
+++ b/hw/acpi/cpu_hotplug.c
@@ -36,10 +36,9 @@ static const MemoryRegionOps AcpiCpuHotplug_ops = {
 },
 };
 
-void acpi_cpu_plug_cb(ACPIREGS *ar, qemu_irq irq,
-  AcpiCpuHotplug *g, DeviceState *dev, Error **errp)
+static void acpi_set_cpu_present_bit(AcpiCpuHotplug *g, CPUState *cpu,
+ Error **errp)
 {
-CPUState *cpu = CPU(dev);
 CPUClass *k = CPU_GET_CLASS(cpu);
 int64_t cpu_id;
 
@@ -49,9 +48,18 @@ void acpi_cpu_plug_cb(ACPIREGS *ar, qemu_irq irq,
 return;
 }
 
-ar->gpe.sts[0] |= ACPI_CPU_HOTPLUG_STATUS;
 g->sts[cpu_id / 8] |= (1 << (cpu_id % 8));
+}
+
+void acpi_cpu_plug_cb(ACPIREGS *ar, qemu_irq irq,
+  AcpiCpuHotplug *g, DeviceState *dev, Error **errp)
+{
+acpi_set_cpu_present_bit(g, CPU(dev), errp);
+if (*errp != NULL) {
+return;
+}
 
+ar->gpe.sts[0] |= ACPI_CPU_HOTPLUG_STATUS;
 acpi_update_sci(ar, irq);
 }
 
@@ -61,11 +69,7 @@ void acpi_cpu_hotplug_init(MemoryRegion *parent, Object 
*owner,
 CPUState *cpu;
 
 CPU_FOREACH(cpu) {
-CPUClass *cc = CPU_GET_CLASS(cpu);
-int64_t id = cc->get_arch_id(cpu);
-
-g_assert((id / 8) < ACPI_GPE_PROC_LEN);
-gpe_cpu->sts[id / 8] |= (1 << (id % 8));
+acpi_set_cpu_present_bit(gpe_cpu, cpu, &error_abort);
 }
 memory_region_init_io(&gpe_cpu->io, owner, &AcpiCpuHotplug_ops,
   gpe_cpu, "acpi-cpu-hotplug", ACPI_GPE_PROC_LEN);
-- 
1.7.7




Re: [Qemu-devel] [PATCH V6 0/8] cpu/acpi: convert cpu hot plug to hotplug_handler API

2014-10-23 Thread Gu Zheng
Hi,
This series has been reviewed by Igor, could you please apply it?

Thanks,
Gu
On 10/22/2014 11:24 AM, Gu Zheng wrote:

> Previously we use cpu_added_notifiers to register cpu hotplug notifier 
> callback
> which is not able to pass/handle errors, so we switch it to unified hotplug
> handler API which allows to pass errors and would allow to cancel device_add
> in case of error.
> Thanks very much for Igor's review and suggestion.
> 
> ---
> v6:
>  Patch 8/8:
>  -using error_abort instead of local_err, so that we can gain the error report
>   before abort (suggested by Igor).
> 
> v5:
>  -rebase on the latest upstream and fix some comments.
>  Patch 4/8:
>  -split the check out of acpi_dev block.
>  Patch 5/8:
>  -move CPU hot-plug notifier cleanup hunk into Patch 6/8.
>  Patch 6/8:
>  -delete the caller of notifier_list_notify() in this patch.
>  Patch 8/8:
>  -rename acpi_set_local_sts to acpi_set_cpu_present_bit for better 
> readability.
> 
> v4:
>  -split removal of CPU hotplug notifier into separate patch (Patch 6/8).
>  Patch 1/7:
>  -convert CPUState *cpu to DeviceState *dev like it's done for other handlers
>   and do cast to CPU inside.
>  Patch 5/7:
>  -Make rtc_state as a link property in PCMachine rather than the global
>   variables.
>  -Split out the removal of unused notifier into separate patch.
>  -Check the result of plug callback before update rtc_state.
> 
> v3:
>  -deal with start-up cpus in pc_cpu_plug as Igor suggested.
> 
> v2:
>  -Add 3 new patches(5/7,6/7,7/7), delete original patch 5/5.
>   1/5-->1/7
>   2/5-->2/7
>   3/5-->3/7
>   4/5-->4/7
>  Patch 1/7:
>  -add errp argument to catch error.
>  -return error instead of aborting if cpu id is invalid.
>  -make acpi_cpu_plug_cb as a wrapper around AcpiCpuHotplug_add.
>  Patch 3/7:
>  -remove unused AcpiCpuHotplug_add directly.
>  Patch 5/7:
>  -switch the last user of cpu hotplug notifier to hotplug handler API, and
>   remove the unused cpu hotplug notify.
>  Patch 6/7:
>  -split the function rename (just cleanup) into single patch.
>  Patch 7/7:
>  -introduce help function acpi_set_local_sts to keep the bit setting in
>   one place.
> ---
> 
> Gu Zheng (8):
>   acpi/cpu: add cpu hotplug callback function to match hotplug_handler
> API
>   acpi:ich9: convert cpu hotplug to hotplug_handler API
>   acpi:piix4: convert cpu hotplug to hotplug_handler API
>   pc: add cpu hotplug handler to PC_MACHINE
>   pc: Update rtc_cmos in pc_cpu_plug
>   qom/cpu: remove the unused CPU hot-plug notifier
>   cpu-hotplug: rename function for better readability
>   acpi/cpu-hotplug: introduce helper function to keep bit setting in
> one place
> 
>  hw/acpi/cpu_hotplug.c |   34 ++---
>  hw/acpi/ich9.c|   17 ++
>  hw/acpi/piix4.c   |   18 ++-
>  hw/i386/pc.c  |   65 
> +++--
>  hw/i386/pc_piix.c |2 +-
>  hw/i386/pc_q35.c  |2 +-
>  include/hw/acpi/cpu_hotplug.h |7 ++--
>  include/hw/acpi/ich9.h|1 -
>  include/hw/i386/pc.h  |3 +-
>  include/sysemu/sysemu.h   |3 --
>  qom/cpu.c |   10 --
>  11 files changed, 82 insertions(+), 80 deletions(-)
> 





Re: [Qemu-devel] [RFC PATCH 0/7] i386: add cpu hot remove support

2014-07-21 Thread Gu Zheng
Hi Igor, Andreas,

How about this patchset? Could you please help to review it?
Any comment is welcome.

Regards,
Gu
On 07/11/2014 05:59 PM, Gu Zheng wrote:

> Via implementing ACPI standard methods _EJ0 in ACPI table, after Guest OS 
> remove
> one vCPU online, the fireware will store removed bitmap to QEMU, then QEMU 
> could
> know to notify the assigned vCPU of exiting. meanwhile, intruduce the QOM 
> command
> 'device_del' to remove vCPU from QEMU itself.
> 
> This job is based on Chen Fan's previous "cpu-del" patchset:
> https://lists.nongnu.org/archive/html/qemu-devel/2013-12/msg04266.html
> 
> And it depends on the previous "device_add foo-x86_64-cpu" patchset:
> https://lists.nongnu.org/archive/html/qemu-devel/2014-06/msg06690.html
> 
> Chen Fan (4):
>   x86: add x86_cpu_unrealizefn() for cpu apic remove
>   qom cpu: rename variable 'cpu_added_notifier' to
> 'cpu_hotplug_notifier'
>   i386: implement pc interface cpu_common_unrealizefn() in qom/cpu.c
>   cpu hotplug: implement function cpu_status_write() for vcpu ejection
> 
> Gu Zheng (3):
>   i386: add cpu device_del support
>   qom cpu: add UNPLUG cpu notify support
>   cpus: reclaim allocated vCPU objects
> 
>  cpus.c|   44 
>  hw/acpi/cpu_hotplug.c |   55 ---
>  hw/acpi/ich9.c|   13 ---
>  hw/acpi/piix4.c   |   21 +++-
>  hw/i386/acpi-dsdt-cpu-hotplug.dsl |6 +++-
>  hw/i386/kvm/apic.c|8 
>  hw/i386/pc.c  |2 +-
>  hw/intc/apic.c|   10 +
>  hw/intc/apic_common.c |   23 -
>  include/hw/acpi/cpu_hotplug.h |   14 +++-
>  include/hw/acpi/ich9.h|2 +-
>  include/hw/cpu/icc_bus.h  |1 +
>  include/hw/i386/apic_internal.h   |1 +
>  include/qom/cpu.h |9 +
>  include/sysemu/kvm.h  |1 +
>  include/sysemu/sysemu.h   |2 +-
>  kvm-all.c |   57 +++-
>  qom/cpu.c |   27 ---
>  target-i386/cpu-qom.h |1 +
>  target-i386/cpu.c |   66 
> +
>  20 files changed, 332 insertions(+), 31 deletions(-)
> 





Re: [Qemu-devel] [RFC PATCH 7/7] cpus: reclaim allocated vCPU objects

2014-07-31 Thread Gu Zheng
Hi Anshul,
Thanks for your test.
On 07/30/2014 10:31 PM, Anshul Makkar wrote:

> Hi,
> 
> I am testing the cpu-hotunplug  patches. I observed that after the
> deletion of the cpu with id = x, if I cpu-add the same cpu again id =
> x, then qemu exits with the error that file descriptor already exists.

Could you please offer the whole reproduce routine? In my test box, we
can add a removed cpu with the id. 

> 
> On debugging I found that if I give cpu-add , then
> qemu_kvm_cpu_thread_fn->kvm_init_vcpu is called which sends an IOCTL
> (KVM_CREATE_VCPU) to kvm to create a new fd. As the fd already exists
> in KVM as we never delete the fd from the kernel and just park it in
> separate list, it returns false and QEMU exits. In the above code
> flow, no where its being checked if we have the cpu with cpuid = x
> available in the parked list and we can reuse it.
> 
> Am I missing something or this bit is yet to be implmented.

Yes, it is implemented, in the same way as you mention above, please refer
to function kvm_get_vcpu().

Thanks,
Gu

> 
> Thanks
> Anshul Makkar
> 
> On Fri, Jul 18, 2014 at 4:09 AM, Gu Zheng  wrote:
>> Hi Anshul,
>> On 07/18/2014 12:24 AM, Anshul Makkar wrote:
>>
>>> Are we not going to introduce new command cpu_del for deleting the cpu ?
>>>
>>> I couldn't find any patch for addition of cpu_del command. Is this
>>> intentional and we intend to use device_del (and similarly device_add)
>>> for cpu hot(un)plug or just skipped to be added later. I have the
>>> patch for the same which I can release, if the intent is to add this
>>> command.
>>
>> The "device_add/device_del" interface is the approved way to support add/del 
>> cpu,
>> which is also more common and elegant than "cpu_add/del".
>> <http://wiki.qemu.org/Features/CPUHotplug>
>> so we intend to use device_del rather than the cpu_del.
>> And IMO, the cpu_add will be replaced by "device_add" sooner or later.
>>
>> Thanks,
>> Gu
>>
>>>
>>> Thanks
>>> Anshul Makkar
>>>
>>> On Fri, Jul 11, 2014 at 11:59 AM, Gu Zheng  wrote:
>>>> After ACPI get a signal to eject a vCPU, the vCPU must be
>>>> removed from CPU list,before the vCPU really removed,  then
>>>> release the all related vCPU objects.
>>>> But we do not close KVM vcpu fd, just record it into a list, in
>>>> order to reuse it.
>>>>
>>>> Signed-off-by: Chen Fan 
>>>> Signed-off-by: Gu Zheng 
>>>> ---
>>>>  cpus.c   |   37 
>>>>  include/sysemu/kvm.h |1 +
>>>>  kvm-all.c|   57 
>>>> +-
>>>>  3 files changed, 94 insertions(+), 1 deletions(-)
>>>>
>>>> diff --git a/cpus.c b/cpus.c
>>>> index 4dfb889..9a73407 100644
>>>> --- a/cpus.c
>>>> +++ b/cpus.c
>>>> @@ -786,6 +786,24 @@ void async_run_on_cpu(CPUState *cpu, void 
>>>> (*func)(void *data), void *data)
>>>>  qemu_cpu_kick(cpu);
>>>>  }
>>>>
>>>> +static void qemu_kvm_destroy_vcpu(CPUState *cpu)
>>>> +{
>>>> +CPU_REMOVE(cpu);
>>>> +
>>>> +if (kvm_destroy_vcpu(cpu) < 0) {
>>>> +fprintf(stderr, "kvm_destroy_vcpu failed.\n");
>>>> +exit(1);
>>>> +}
>>>> +
>>>> +object_unparent(OBJECT(cpu));
>>>> +}
>>>> +
>>>> +static void qemu_tcg_destroy_vcpu(CPUState *cpu)
>>>> +{
>>>> +CPU_REMOVE(cpu);
>>>> +object_unparent(OBJECT(cpu));
>>>> +}
>>>> +
>>>>  static void flush_queued_work(CPUState *cpu)
>>>>  {
>>>>  struct qemu_work_item *wi;
>>>> @@ -877,6 +895,11 @@ static void *qemu_kvm_cpu_thread_fn(void *arg)
>>>>  }
>>>>  }
>>>>  qemu_kvm_wait_io_event(cpu);
>>>> +if (cpu->exit && !cpu_can_run(cpu)) {
>>>> +qemu_kvm_destroy_vcpu(cpu);
>>>> +qemu_mutex_unlock(&qemu_global_mutex);
>>>> +return NULL;
>>>> +}
>>>>  }
>>>>
>>>>  return NULL;
>>>> @@ -929,6 +952,7 @@ static void tcg_exec_all(void);
>>>>  static void *qemu_tcg_cpu_thread_fn(void *arg)
>>>>  {
>>>>  CPU

Re: [Qemu-devel] [RFC PATCH 7/7] cpus: reclaim allocated vCPU objects

2014-08-06 Thread Gu Zheng
Hi Anshul,

I rebased these two parts on latest QEMU tree (no functional change), and
will send out later.
So if you like, please refer to the new one, it will be easy for you to
review and test.

Thanks,
Gu
On 08/01/2014 11:34 PM, Anshul Makkar wrote:

> Hi Gu,
> 
> Thanks for clarifying.
> 
> Ah I missed that bit of the patch. Sorry about that and for making noise.
> 
> Yes, now cpu-hotplug and unplug works fine. Next week I plan to run a
> series of automated and stress test. Will keep the group posted about
> the results.
> 
> Thanks
> Anshul Makkar
> 
> On Fri, Aug 1, 2014 at 6:42 AM, Gu Zheng  wrote:
>> Hi Anshul,
>> Thanks for your test.
>> On 07/30/2014 10:31 PM, Anshul Makkar wrote:
>>
>>> Hi,
>>>
>>> I am testing the cpu-hotunplug  patches. I observed that after the
>>> deletion of the cpu with id = x, if I cpu-add the same cpu again id =
>>> x, then qemu exits with the error that file descriptor already exists.
>>
>> Could you please offer the whole reproduce routine? In my test box, we
>> can add a removed cpu with the id.
>>
>>>
>>> On debugging I found that if I give cpu-add , then
>>> qemu_kvm_cpu_thread_fn->kvm_init_vcpu is called which sends an IOCTL
>>> (KVM_CREATE_VCPU) to kvm to create a new fd. As the fd already exists
>>> in KVM as we never delete the fd from the kernel and just park it in
>>> separate list, it returns false and QEMU exits. In the above code
>>> flow, no where its being checked if we have the cpu with cpuid = x
>>> available in the parked list and we can reuse it.
>>>
>>> Am I missing something or this bit is yet to be implmented.
>>
>> Yes, it is implemented, in the same way as you mention above, please refer
>> to function kvm_get_vcpu().
>>
>> Thanks,
>> Gu
>>
>>>
>>> Thanks
>>> Anshul Makkar
>>>
>>> On Fri, Jul 18, 2014 at 4:09 AM, Gu Zheng  wrote:
>>>> Hi Anshul,
>>>> On 07/18/2014 12:24 AM, Anshul Makkar wrote:
>>>>
>>>>> Are we not going to introduce new command cpu_del for deleting the cpu ?
>>>>>
>>>>> I couldn't find any patch for addition of cpu_del command. Is this
>>>>> intentional and we intend to use device_del (and similarly device_add)
>>>>> for cpu hot(un)plug or just skipped to be added later. I have the
>>>>> patch for the same which I can release, if the intent is to add this
>>>>> command.
>>>>
>>>> The "device_add/device_del" interface is the approved way to support 
>>>> add/del cpu,
>>>> which is also more common and elegant than "cpu_add/del".
>>>> <http://wiki.qemu.org/Features/CPUHotplug>
>>>> so we intend to use device_del rather than the cpu_del.
>>>> And IMO, the cpu_add will be replaced by "device_add" sooner or later.
>>>>
>>>> Thanks,
>>>> Gu
>>>>
>>>>>
>>>>> Thanks
>>>>> Anshul Makkar
>>>>>
>>>>> On Fri, Jul 11, 2014 at 11:59 AM, Gu Zheng  
>>>>> wrote:
>>>>>> After ACPI get a signal to eject a vCPU, the vCPU must be
>>>>>> removed from CPU list,before the vCPU really removed,  then
>>>>>> release the all related vCPU objects.
>>>>>> But we do not close KVM vcpu fd, just record it into a list, in
>>>>>> order to reuse it.
>>>>>>
>>>>>> Signed-off-by: Chen Fan 
>>>>>> Signed-off-by: Gu Zheng 
>>>>>> ---
>>>>>>  cpus.c   |   37 
>>>>>>  include/sysemu/kvm.h |1 +
>>>>>>  kvm-all.c|   57 
>>>>>> +-
>>>>>>  3 files changed, 94 insertions(+), 1 deletions(-)
>>>>>>
>>>>>> diff --git a/cpus.c b/cpus.c
>>>>>> index 4dfb889..9a73407 100644
>>>>>> --- a/cpus.c
>>>>>> +++ b/cpus.c
>>>>>> @@ -786,6 +786,24 @@ void async_run_on_cpu(CPUState *cpu, void 
>>>>>> (*func)(void *data), void *data)
>>>>>>  qemu_cpu_kick(cpu);
>>>>>>  }
>>>>>>
>>>>>> +static void qemu_kvm_destroy_vcpu(CPUState *cpu)
>>>>>> +{
>>>>>> +CPU_REMOVE(cpu);
>>>>>> 

[Qemu-devel] [RFC PATCH 00/10] cpu: add device_add foo-x86_64-cpu and i386 cpu hot remove support

2014-08-06 Thread Gu Zheng
This series is based on the previous patchset from Chen Fan:
https://lists.nongnu.org/archive/html/qemu-devel/2014-05/msg02360.html
https://lists.nongnu.org/archive/html/qemu-devel/2013-12/msg04266.html

Patch 1~3: add device_add foo-x86_64-cpu support
These three patches try to make cpu hotplug with device_add, and make
"-device foo-x86_64-cpu" available,also we can set apic-id
property with command line, if without setting apic-id property,
we offer the first unoccupied apic id as the default new apic id.
When hotplug cpu with device_add, additional check of APIC ID will be
done after cpu object initialization which was different from
'cpu_add' command that check 'ids' at the beginning.

Patch 4~10: add i386 cpu hot remove support
Via implementing ACPI standard methods _EJ0 in ACPI table, after Guest
OS remove one vCPU online, the fireware will store removed bitmap to
QEMU, then QEMU could know to notify the assigned vCPU of exiting.
Meanwhile, intruduce the QOM command 'device_del' to remove vCPU from
QEMU itself.

Chen Fan (6):
  cpu: introduce CpuTopoInfo structure for argument simplification
  cpu: add device_add foo-x86_64-cpu support
  x86: add x86_cpu_unrealizefn() for cpu apic remove
  qom cpu: rename variable 'cpu_added_notifier' to
'cpu_hotplug_notifier'
  i386: implement pc interface cpu_common_unrealizefn() in qom/cpu.c
  cpu hotplug: implement function cpu_status_write() for vcpu ejection

Gu Zheng (4):
  qom/cpu: move register_vmstate to common CPUClass.realizefn
  i386: add cpu device_del support
  qom cpu: add UNPLUG cpu notify support
  cpus: reclaim allocated vCPU objects

 cpus.c|   44 
 exec.c|   32 +
 hw/acpi/cpu_hotplug.c |   55 +--
 hw/acpi/ich9.c|   13 ++--
 hw/acpi/piix4.c   |   21 +++---
 hw/i386/acpi-dsdt-cpu-hotplug.dsl |6 ++-
 hw/i386/kvm/apic.c|8 ++
 hw/i386/pc.c  |2 +-
 hw/intc/apic.c|   10 +++
 hw/intc/apic_common.c |   26 ++-
 include/hw/acpi/cpu_hotplug.h |   14 -
 include/hw/acpi/ich9.h|2 +-
 include/hw/cpu/icc_bus.h  |1 +
 include/hw/i386/apic_internal.h   |3 +
 include/qom/cpu.h |   12 +++
 include/sysemu/kvm.h  |1 +
 include/sysemu/sysemu.h   |2 +-
 kvm-all.c |   57 +++-
 qdev-monitor.c|1 +
 qom/cpu.c |   29 +++--
 target-i386/cpu-qom.h |1 +
 target-i386/cpu.c |  138 -
 target-i386/topology.h|   51 +
 23 files changed, 464 insertions(+), 65 deletions(-)

-- 
1.7.7




[Qemu-devel] [RFC PATCH 01/10] cpu: introduce CpuTopoInfo structure for argument simplification

2014-08-06 Thread Gu Zheng
From: Chen Fan 

Reviewed-by: Eduardo Habkost 
Signed-off-by: Chen Fan 
Signed-off-by: Gu Zheng 
---
 target-i386/topology.h |   33 +
 1 files changed, 17 insertions(+), 16 deletions(-)

diff --git a/target-i386/topology.h b/target-i386/topology.h
index 07a6c5f..e9ff89c 100644
--- a/target-i386/topology.h
+++ b/target-i386/topology.h
@@ -47,6 +47,12 @@
  */
 typedef uint32_t apic_id_t;
 
+typedef struct X86CPUTopoInfo {
+unsigned pkg_id;
+unsigned core_id;
+unsigned smt_id;
+} X86CPUTopoInfo;
+
 /* Return the bit width needed for 'count' IDs
  */
 static unsigned apicid_bitwidth_for_count(unsigned count)
@@ -92,13 +98,11 @@ static inline unsigned apicid_pkg_offset(unsigned nr_cores, 
unsigned nr_threads)
  */
 static inline apic_id_t apicid_from_topo_ids(unsigned nr_cores,
  unsigned nr_threads,
- unsigned pkg_id,
- unsigned core_id,
- unsigned smt_id)
+ const X86CPUTopoInfo *topo)
 {
-return (pkg_id  << apicid_pkg_offset(nr_cores, nr_threads)) |
-   (core_id << apicid_core_offset(nr_cores, nr_threads)) |
-   smt_id;
+return (topo->pkg_id  << apicid_pkg_offset(nr_cores, nr_threads)) |
+   (topo->core_id << apicid_core_offset(nr_cores, nr_threads)) |
+   topo->smt_id;
 }
 
 /* Calculate thread/core/package IDs for a specific topology,
@@ -107,14 +111,12 @@ static inline apic_id_t apicid_from_topo_ids(unsigned 
nr_cores,
 static inline void x86_topo_ids_from_idx(unsigned nr_cores,
  unsigned nr_threads,
  unsigned cpu_index,
- unsigned *pkg_id,
- unsigned *core_id,
- unsigned *smt_id)
+ X86CPUTopoInfo *topo)
 {
 unsigned core_index = cpu_index / nr_threads;
-*smt_id = cpu_index % nr_threads;
-*core_id = core_index % nr_cores;
-*pkg_id = core_index / nr_cores;
+topo->smt_id = cpu_index % nr_threads;
+topo->core_id = core_index % nr_cores;
+topo->pkg_id = core_index / nr_cores;
 }
 
 /* Make APIC ID for the CPU 'cpu_index'
@@ -125,10 +127,9 @@ static inline apic_id_t x86_apicid_from_cpu_idx(unsigned 
nr_cores,
 unsigned nr_threads,
 unsigned cpu_index)
 {
-unsigned pkg_id, core_id, smt_id;
-x86_topo_ids_from_idx(nr_cores, nr_threads, cpu_index,
-  &pkg_id, &core_id, &smt_id);
-return apicid_from_topo_ids(nr_cores, nr_threads, pkg_id, core_id, smt_id);
+X86CPUTopoInfo topo;
+x86_topo_ids_from_idx(nr_cores, nr_threads, cpu_index, &topo);
+return apicid_from_topo_ids(nr_cores, nr_threads, &topo);
 }
 
 #endif /* TARGET_I386_TOPOLOGY_H */
-- 
1.7.7




[Qemu-devel] [RFC PATCH 02/10] qom/cpu: move register_vmstate to common CPUClass.realizefn

2014-08-06 Thread Gu Zheng
Move cpu vmstate register from cpu_exec_init into cpu_common_realizefn,
apic vmstate register into x86_cpu_apic_realize. And use the
cc->get_arch_id as the instance id that suggested by Igor to
fix the migration issue.

Signed-off-by: Gu Zheng 
---
 exec.c  |   32 +++-
 hw/intc/apic_common.c   |3 +--
 include/hw/i386/apic_internal.h |2 ++
 include/qom/cpu.h   |2 ++
 qom/cpu.c   |2 ++
 target-i386/cpu.c   |   10 --
 6 files changed, 34 insertions(+), 17 deletions(-)

diff --git a/exec.c b/exec.c
index 765bd94..3c88630 100644
--- a/exec.c
+++ b/exec.c
@@ -473,10 +473,28 @@ void tcg_cpu_address_space_init(CPUState *cpu, 
AddressSpace *as)
 }
 #endif
 
+void cpu_vmstate_register(CPUState *cpu)
+{
+CPUClass *cc = CPU_GET_CLASS(cpu);
+int cpu_index = cc->get_arch_id(cpu);
+
+if (qdev_get_vmsd(DEVICE(cpu)) == NULL) {
+vmstate_register(NULL, cpu_index, &vmstate_cpu_common, cpu);
+}
+#if defined(CPU_SAVE_VERSION) && !defined(CONFIG_USER_ONLY)
+register_savevm(NULL, "cpu", cpu_index, CPU_SAVE_VERSION,
+cpu_save, cpu_load, cpu->env_ptr);
+assert(cc->vmsd == NULL);
+assert(qdev_get_vmsd(DEVICE(cpu)) == NULL);
+#endif
+if (cc->vmsd != NULL) {
+vmstate_register(NULL, cpu_index, cc->vmsd, cpu);
+}
+}
+
 void cpu_exec_init(CPUArchState *env)
 {
 CPUState *cpu = ENV_GET_CPU(env);
-CPUClass *cc = CPU_GET_CLASS(cpu);
 CPUState *some_cpu;
 int cpu_index;
 
@@ -499,18 +517,6 @@ void cpu_exec_init(CPUArchState *env)
 #if defined(CONFIG_USER_ONLY)
 cpu_list_unlock();
 #endif
-if (qdev_get_vmsd(DEVICE(cpu)) == NULL) {
-vmstate_register(NULL, cpu_index, &vmstate_cpu_common, cpu);
-}
-#if defined(CPU_SAVE_VERSION) && !defined(CONFIG_USER_ONLY)
-register_savevm(NULL, "cpu", cpu_index, CPU_SAVE_VERSION,
-cpu_save, cpu_load, env);
-assert(cc->vmsd == NULL);
-assert(qdev_get_vmsd(DEVICE(cpu)) == NULL);
-#endif
-if (cc->vmsd != NULL) {
-vmstate_register(NULL, cpu_index, cc->vmsd, cpu);
-}
 }
 
 #if defined(TARGET_HAS_ICE)
diff --git a/hw/intc/apic_common.c b/hw/intc/apic_common.c
index ce3d903..029f67d 100644
--- a/hw/intc/apic_common.c
+++ b/hw/intc/apic_common.c
@@ -345,7 +345,7 @@ static int apic_dispatch_post_load(void *opaque, int 
version_id)
 return 0;
 }
 
-static const VMStateDescription vmstate_apic_common = {
+const VMStateDescription vmstate_apic_common = {
 .name = "apic",
 .version_id = 3,
 .minimum_version_id = 3,
@@ -391,7 +391,6 @@ static void apic_common_class_init(ObjectClass *klass, void 
*data)
 ICCDeviceClass *idc = ICC_DEVICE_CLASS(klass);
 DeviceClass *dc = DEVICE_CLASS(klass);
 
-dc->vmsd = &vmstate_apic_common;
 dc->reset = apic_reset_common;
 dc->props = apic_properties_common;
 idc->realize = apic_common_realize;
diff --git a/include/hw/i386/apic_internal.h b/include/hw/i386/apic_internal.h
index 83e2a42..2c91609 100644
--- a/include/hw/i386/apic_internal.h
+++ b/include/hw/i386/apic_internal.h
@@ -23,6 +23,7 @@
 #include "exec/memory.h"
 #include "hw/cpu/icc_bus.h"
 #include "qemu/timer.h"
+#include "migration/vmstate.h"
 
 /* APIC Local Vector Table */
 #define APIC_LVT_TIMER  0
@@ -136,6 +137,7 @@ typedef struct VAPICState {
 } QEMU_PACKED VAPICState;
 
 extern bool apic_report_tpr_access;
+extern const VMStateDescription vmstate_apic_common;
 
 void apic_report_irq_delivered(int delivered);
 bool apic_next_timer(APICCommonState *s, int64_t current_time);
diff --git a/include/qom/cpu.h b/include/qom/cpu.h
index 1aafbf5..bc32c9a 100644
--- a/include/qom/cpu.h
+++ b/include/qom/cpu.h
@@ -549,6 +549,8 @@ void cpu_interrupt(CPUState *cpu, int mask);
 
 #endif /* USER_ONLY */
 
+void cpu_vmstate_register(CPUState *cpu);
+
 #ifdef CONFIG_SOFTMMU
 static inline void cpu_unassigned_access(CPUState *cpu, hwaddr addr,
  bool is_write, bool is_exec,
diff --git a/qom/cpu.c b/qom/cpu.c
index b32dd0a..bf16590 100644
--- a/qom/cpu.c
+++ b/qom/cpu.c
@@ -301,6 +301,8 @@ static void cpu_common_realizefn(DeviceState *dev, Error 
**errp)
 {
 CPUState *cpu = CPU(dev);
 
+cpu_vmstate_register(cpu);
+
 if (dev->hotplugged) {
 cpu_synchronize_post_init(cpu);
 notifier_list_notify(&cpu_added_notifiers, dev);
diff --git a/target-i386/cpu.c b/target-i386/cpu.c
index 6d008ab..d381644 100644
--- a/target-i386/cpu.c
+++ b/target-i386/cpu.c
@@ -2662,11 +2662,17 @@ static void x86_cpu_apic_create(X86CPU *cpu, Error 
**errp)
 
 static void x86_cpu_apic_realize(X86CPU *cpu, Error **errp)
 {
-if (cpu->apic_state == NULL) {
+DeviceState *apic_state = cpu->apic_state;
+CPUClass *c

[Qemu-devel] [RFC PATCH 03/10] cpu: add device_add foo-x86_64-cpu support

2014-08-06 Thread Gu Zheng
From: Chen Fan 

Add support to device_add foo-x86_64-cpu, and additional checks of
apic id are added into x86_cpuid_set_apic_id() and x86_cpu_apic_create()
for duplicate. Besides, in order to support "device/device_add foo-x86_64-cpu"
which without specified apic id, we add a new function get_free_apic_id() to
provide the first free apid id each time to avoid apic id duplicate.

Signed-off-by: Chen Fan 
Signed-off-by: Gu Zheng 
---
 include/qom/cpu.h  |1 +
 qdev-monitor.c |1 +
 target-i386/cpu.c  |   61 +++-
 target-i386/topology.h |   18 ++
 4 files changed, 80 insertions(+), 1 deletions(-)

diff --git a/include/qom/cpu.h b/include/qom/cpu.h
index bc32c9a..2fc00ef 100644
--- a/include/qom/cpu.h
+++ b/include/qom/cpu.h
@@ -292,6 +292,7 @@ struct CPUState {
 QTAILQ_HEAD(CPUTailQ, CPUState);
 extern struct CPUTailQ cpus;
 #define CPU_NEXT(cpu) QTAILQ_NEXT(cpu, node)
+#define CPU_REMOVE(cpu) QTAILQ_REMOVE(&cpus, cpu, node)
 #define CPU_FOREACH(cpu) QTAILQ_FOREACH(cpu, &cpus, node)
 #define CPU_FOREACH_SAFE(cpu, next_cpu) \
 QTAILQ_FOREACH_SAFE(cpu, &cpus, node, next_cpu)
diff --git a/qdev-monitor.c b/qdev-monitor.c
index f87f3d8..48327c8 100644
--- a/qdev-monitor.c
+++ b/qdev-monitor.c
@@ -24,6 +24,7 @@
 #include "qmp-commands.h"
 #include "sysemu/arch_init.h"
 #include "qemu/config-file.h"
+#include "qom/object_interfaces.h"
 
 /*
  * Aliases were a bad idea from the start.  Let's keep them
diff --git a/target-i386/cpu.c b/target-i386/cpu.c
index d381644..4367bc0 100644
--- a/target-i386/cpu.c
+++ b/target-i386/cpu.c
@@ -49,6 +49,7 @@
 #include "hw/i386/apic_internal.h"
 #endif
 
+#include "qom/object_interfaces.h"
 
 /* Cache topology CPUID constants: */
 
@@ -1634,6 +1635,7 @@ static void x86_cpuid_set_apic_id(Object *obj, Visitor 
*v, void *opaque,
 const int64_t max = UINT32_MAX;
 Error *error = NULL;
 int64_t value;
+X86CPUTopoInfo topo;
 
 if (dev->realized) {
 error_setg(errp, "Attempt to set property '%s' on '%s' after "
@@ -1653,6 +1655,19 @@ static void x86_cpuid_set_apic_id(Object *obj, Visitor 
*v, void *opaque,
 return;
 }
 
+if (value > x86_cpu_apic_id_from_index(max_cpus - 1)) {
+error_setg(errp, "CPU with APIC ID %" PRIi64
+   " is more than MAX APIC ID limits", value);
+return;
+}
+
+x86_topo_ids_from_apic_id(smp_cores, smp_threads, value, &topo);
+if (topo.smt_id >= smp_threads || topo.core_id >= smp_cores) {
+error_setg(errp, "CPU with APIC ID %" PRIi64 " does not match "
+   "topology configuration.", value);
+return;
+}
+
 if ((value != cpu->env.cpuid_apic_id) && cpu_exists(value)) {
 error_setg(errp, "CPU with APIC ID %" PRIi64 " exists", value);
 return;
@@ -2096,12 +2111,21 @@ out:
 return cpu;
 }
 
+static void x86_cpu_cpudef_instance_init(Object *obj)
+{
+DeviceState *dev = DEVICE(obj);
+
+dev->hotplugged = true;
+}
+
 static void x86_cpu_cpudef_class_init(ObjectClass *oc, void *data)
 {
 X86CPUDefinition *cpudef = data;
 X86CPUClass *xcc = X86_CPU_CLASS(oc);
+DeviceClass *dc = DEVICE_CLASS(oc);
 
 xcc->cpu_def = cpudef;
+dc->cannot_instantiate_with_device_add_yet = false;
 }
 
 static void x86_register_cpudef_type(X86CPUDefinition *def)
@@ -2110,6 +2134,8 @@ static void x86_register_cpudef_type(X86CPUDefinition 
*def)
 TypeInfo ti = {
 .name = typename,
 .parent = TYPE_X86_CPU,
+.instance_size = sizeof(X86CPU),
+.instance_init = x86_cpu_cpudef_instance_init,
 .class_init = x86_cpu_cpudef_class_init,
 .class_data = def,
 };
@@ -2652,6 +2678,14 @@ static void x86_cpu_apic_create(X86CPU *cpu, Error 
**errp)
 return;
 }
 
+if (env->cpuid_apic_id > x86_cpu_apic_id_from_index(max_cpus - 1)) {
+error_setg(errp, "CPU with APIC ID %" PRIi32
+" is more than MAX APIC ID:%" PRIi32,
+env->cpuid_apic_id,
+x86_cpu_apic_id_from_index(max_cpus - 1));
+return;
+}
+
 object_property_add_child(OBJECT(cpu), "apic",
   OBJECT(cpu->apic_state), NULL);
 qdev_prop_set_uint8(cpu->apic_state, "id", env->cpuid_apic_id);
@@ -2777,6 +2811,21 @@ uint32_t x86_cpu_apic_id_from_index(unsigned int 
cpu_index)
 }
 }
 
+static uint32_t get_free_apic_id(void)
+{
+int i;
+
+for (i = 0; i < max_cpus; i++) {
+uint32_t id = x86_cpu_apic_id_from_index(i);
+
+if (!cpu_exists(id)) {
+return id;
+}
+}
+
+return x86_cpu_apic_id_from_index(max_cpus

[Qemu-devel] [RFC PATCH 04/10] x86: add x86_cpu_unrealizefn() for cpu apic remove

2014-08-06 Thread Gu Zheng
From: Chen Fan 

Implement x86_cpu_unrealizefn() for corresponding x86_cpu_realizefn(),
which is mostly used to clean the apic related allocation and vmstates
at here.

Signed-off-by: Chen Fan 
Signed-off-by: Gu Zheng 
---
 hw/i386/kvm/apic.c  |8 +++
 hw/intc/apic.c  |   10 
 hw/intc/apic_common.c   |   23 +++-
 include/hw/cpu/icc_bus.h|1 +
 include/hw/i386/apic_internal.h |1 +
 target-i386/cpu-qom.h   |1 +
 target-i386/cpu.c   |   45 +++
 7 files changed, 88 insertions(+), 1 deletions(-)

diff --git a/hw/i386/kvm/apic.c b/hw/i386/kvm/apic.c
index e873b50..593ca19 100644
--- a/hw/i386/kvm/apic.c
+++ b/hw/i386/kvm/apic.c
@@ -183,11 +183,19 @@ static void kvm_apic_realize(DeviceState *dev, Error 
**errp)
 }
 }
 
+static void kvm_apic_unrealize(DeviceState *dev, Error **errp)
+{
+APICCommonState *s = APIC_COMMON(dev);
+
+memory_region_destroy(&s->io_memory);
+}
+
 static void kvm_apic_class_init(ObjectClass *klass, void *data)
 {
 APICCommonClass *k = APIC_COMMON_CLASS(klass);
 
 k->realize = kvm_apic_realize;
+k->unrealize = kvm_apic_unrealize;
 k->set_base = kvm_apic_set_base;
 k->set_tpr = kvm_apic_set_tpr;
 k->get_tpr = kvm_apic_get_tpr;
diff --git a/hw/intc/apic.c b/hw/intc/apic.c
index ef19e55..efdbf5b 100644
--- a/hw/intc/apic.c
+++ b/hw/intc/apic.c
@@ -885,11 +885,21 @@ static void apic_realize(DeviceState *dev, Error **errp)
 msi_supported = true;
 }
 
+static void apic_unrealize(DeviceState *dev, Error **errp)
+{
+APICCommonState *s = APIC_COMMON(dev);
+
+memory_region_destroy(&s->io_memory);
+timer_free(s->timer);
+local_apics[s->idx] = NULL;
+}
+
 static void apic_class_init(ObjectClass *klass, void *data)
 {
 APICCommonClass *k = APIC_COMMON_CLASS(klass);
 
 k->realize = apic_realize;
+k->unrealize = apic_unrealize;
 k->set_base = apic_set_base;
 k->set_tpr = apic_set_tpr;
 k->get_tpr = apic_get_tpr;
diff --git a/hw/intc/apic_common.c b/hw/intc/apic_common.c
index 029f67d..8d17be1 100644
--- a/hw/intc/apic_common.c
+++ b/hw/intc/apic_common.c
@@ -289,12 +289,13 @@ static int apic_load_old(QEMUFile *f, void *opaque, int 
version_id)
 return 0;
 }
 
+static int apic_no;
+
 static void apic_common_realize(DeviceState *dev, Error **errp)
 {
 APICCommonState *s = APIC_COMMON(dev);
 APICCommonClass *info;
 static DeviceState *vapic;
-static int apic_no;
 static bool mmio_registered;
 
 if (apic_no >= MAX_APICS) {
@@ -324,6 +325,25 @@ static void apic_common_realize(DeviceState *dev, Error 
**errp)
 
 }
 
+static void apic_common_unrealize(DeviceState *dev, Error **errp)
+{
+APICCommonState *s = APIC_COMMON(dev);
+APICCommonClass *info = APIC_COMMON_GET_CLASS(s);
+
+if (apic_no <= 0) {
+error_setg(errp, "%s exit failed.",
+   object_get_typename(OBJECT(dev)));
+return;
+}
+apic_no--;
+
+info->unrealize(dev, errp);
+
+if (apic_report_tpr_access && info->enable_tpr_reporting) {
+info->enable_tpr_reporting(s, false);
+}
+}
+
 static void apic_dispatch_pre_save(void *opaque)
 {
 APICCommonState *s = APIC_COMMON(opaque);
@@ -394,6 +414,7 @@ static void apic_common_class_init(ObjectClass *klass, void 
*data)
 dc->reset = apic_reset_common;
 dc->props = apic_properties_common;
 idc->realize = apic_common_realize;
+idc->unrealize = apic_common_unrealize;
 /*
  * Reason: APIC and CPU need to be wired up by
  * x86_cpu_apic_create()
diff --git a/include/hw/cpu/icc_bus.h b/include/hw/cpu/icc_bus.h
index 98a979f..75ed309 100644
--- a/include/hw/cpu/icc_bus.h
+++ b/include/hw/cpu/icc_bus.h
@@ -67,6 +67,7 @@ typedef struct ICCDeviceClass {
 /*< public >*/
 
 DeviceRealize realize;
+DeviceUnrealize unrealize;
 } ICCDeviceClass;
 
 #define TYPE_ICC_DEVICE "icc-device"
diff --git a/include/hw/i386/apic_internal.h b/include/hw/i386/apic_internal.h
index 2c91609..6c9e390 100644
--- a/include/hw/i386/apic_internal.h
+++ b/include/hw/i386/apic_internal.h
@@ -82,6 +82,7 @@ typedef struct APICCommonClass
 ICCDeviceClass parent_class;
 
 DeviceRealize realize;
+DeviceUnrealize unrealize;
 void (*set_base)(APICCommonState *s, uint64_t val);
 void (*set_tpr)(APICCommonState *s, uint8_t val);
 uint8_t (*get_tpr)(APICCommonState *s);
diff --git a/target-i386/cpu-qom.h b/target-i386/cpu-qom.h
index 71a1b97..2239105 100644
--- a/target-i386/cpu-qom.h
+++ b/target-i386/cpu-qom.h
@@ -65,6 +65,7 @@ typedef struct X86CPUClass {
 bool kvm_required;
 
 DeviceRealize parent_realize;
+DeviceUnrealize parent_unrealize;
 void (*parent_reset)(CPUState *cpu);
 } X86CPUClass;
 
diff --git a/target-i386/cpu.c b/target-i386/cpu.c
in

[Qemu-devel] [RFC PATCH 05/10] i386: add cpu device_del support

2014-08-06 Thread Gu Zheng
In order to add cpu(i386) device_del support, introduce the cpu hot
unplug hanlde(x86_cpu_unplug) which will trigger the unrealize routine,
and just register it to the cpu class unplug handle.

Signed-off-by: Chen Fan 
Signed-off-by: Gu Zheng 
---
 target-i386/cpu.c |   22 ++
 1 files changed, 22 insertions(+), 0 deletions(-)

diff --git a/target-i386/cpu.c b/target-i386/cpu.c
index 21980ce..7401368 100644
--- a/target-i386/cpu.c
+++ b/target-i386/cpu.c
@@ -2993,6 +2993,27 @@ static Property x86_cpu_properties[] = {
 DEFINE_PROP_END_OF_LIST()
 };
 
+static int x86_cpu_unplug(DeviceState *dev)
+{
+CPUState *cpu = CPU(dev);
+X86CPUClass *xcc;
+Error *err = NULL;
+
+if (cpu == first_cpu) {
+error_report("Can not remove the first cpu!\n");
+return -1;
+}
+
+xcc = X86_CPU_GET_CLASS(DEVICE(cpu));
+xcc->parent_unrealize(DEVICE(cpu), &err);
+if (err != NULL) {
+error_report("%s", error_get_pretty(err));
+error_free(err);
+return -1;
+}
+return 0;
+}
+
 static void x86_cpu_common_class_init(ObjectClass *oc, void *data)
 {
 X86CPUClass *xcc = X86_CPU_CLASS(oc);
@@ -3005,6 +3026,7 @@ static void x86_cpu_common_class_init(ObjectClass *oc, 
void *data)
 dc->unrealize = x86_cpu_unrealizefn;
 dc->bus_type = TYPE_ICC_BUS;
 dc->props = x86_cpu_properties;
+dc->unplug = x86_cpu_unplug;
 
 xcc->parent_reset = cc->reset;
 cc->reset = x86_cpu_reset;
-- 
1.7.7




[Qemu-devel] [RFC PATCH 06/10] qom cpu: rename variable 'cpu_added_notifier' to 'cpu_hotplug_notifier'

2014-08-06 Thread Gu Zheng
From: Chen Fan 

Rename variable 'cpu_added_notifier' to 'cpu_hotplug_notifier' for
adding remove vcpu notifier support.

Signed-off-by: Chen Fan 
Signed-off-by: Gu Zheng 
---
 hw/acpi/ich9.c  |8 
 hw/acpi/piix4.c |   10 +-
 hw/i386/pc.c|2 +-
 include/hw/acpi/ich9.h  |2 +-
 include/sysemu/sysemu.h |2 +-
 qom/cpu.c   |   10 +-
 6 files changed, 17 insertions(+), 17 deletions(-)

diff --git a/hw/acpi/ich9.c b/hw/acpi/ich9.c
index 7b14bbb..804f774 100644
--- a/hw/acpi/ich9.c
+++ b/hw/acpi/ich9.c
@@ -209,9 +209,9 @@ static void pm_powerdown_req(Notifier *n, void *opaque)
 acpi_pm1_evt_power_down(&pm->acpi_regs);
 }
 
-static void ich9_cpu_added_req(Notifier *n, void *opaque)
+static void ich9_cpu_hotplug_req(Notifier *n, void *opaque)
 {
-ICH9LPCPMRegs *pm = container_of(n, ICH9LPCPMRegs, cpu_added_notifier);
+ICH9LPCPMRegs *pm = container_of(n, ICH9LPCPMRegs, cpu_hotplug_notifier);
 
 assert(pm != NULL);
 AcpiCpuHotplug_add(&pm->acpi_regs.gpe, &pm->gpe_cpu, CPU(opaque));
@@ -246,8 +246,8 @@ void ich9_pm_init(PCIDevice *lpc_pci, ICH9LPCPMRegs *pm,
 
 AcpiCpuHotplug_init(pci_address_space_io(lpc_pci), OBJECT(lpc_pci),
 &pm->gpe_cpu, ICH9_CPU_HOTPLUG_IO_BASE);
-pm->cpu_added_notifier.notify = ich9_cpu_added_req;
-qemu_register_cpu_added_notifier(&pm->cpu_added_notifier);
+pm->cpu_hotplug_notifier.notify = ich9_cpu_hotplug_req;
+qemu_register_cpu_hotplug_notifier(&pm->cpu_hotplug_notifier);
 
 if (pm->acpi_memory_hotplug.is_enabled) {
 acpi_memory_hotplug_init(pci_address_space_io(lpc_pci), 
OBJECT(lpc_pci),
diff --git a/hw/acpi/piix4.c b/hw/acpi/piix4.c
index b72b34e..5cd6300 100644
--- a/hw/acpi/piix4.c
+++ b/hw/acpi/piix4.c
@@ -83,7 +83,7 @@ typedef struct PIIX4PMState {
 uint8_t s4_val;
 
 AcpiCpuHotplug gpe_cpu;
-Notifier cpu_added_notifier;
+Notifier cpu_hotplug_notifier;
 
 MemHotplugState acpi_memory_hotplug;
 } PIIX4PMState;
@@ -544,9 +544,9 @@ static const MemoryRegionOps piix4_gpe_ops = {
 .endianness = DEVICE_LITTLE_ENDIAN,
 };
 
-static void piix4_cpu_added_req(Notifier *n, void *opaque)
+static void piix4_cpu_hotplug(Notifier *n, void *opaque)
 {
-PIIX4PMState *s = container_of(n, PIIX4PMState, cpu_added_notifier);
+PIIX4PMState *s = container_of(n, PIIX4PMState, cpu_hotplug_notifier);
 
 assert(s != NULL);
 AcpiCpuHotplug_add(&s->ar.gpe, &s->gpe_cpu, CPU(opaque));
@@ -565,8 +565,8 @@ static void piix4_acpi_system_hot_add_init(MemoryRegion 
*parent,
 
 AcpiCpuHotplug_init(parent, OBJECT(s), &s->gpe_cpu,
 PIIX4_CPU_HOTPLUG_IO_BASE);
-s->cpu_added_notifier.notify = piix4_cpu_added_req;
-qemu_register_cpu_added_notifier(&s->cpu_added_notifier);
+s->cpu_hotplug_notifier.notify = piix4_cpu_hotplug;
+qemu_register_cpu_hotplug_notifier(&s->cpu_hotplug_notifier);
 
 if (s->acpi_memory_hotplug.is_enabled) {
 acpi_memory_hotplug_init(parent, OBJECT(s), &s->acpi_memory_hotplug);
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 9e58982..9737ce3 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -413,7 +413,7 @@ void pc_cmos_init(ram_addr_t ram_size, ram_addr_t 
above_4g_mem_size,
 /* init CPU hotplug notifier */
 cpu_hotplug_cb.rtc_state = s;
 cpu_hotplug_cb.cpu_added_notifier.notify = rtc_notify_cpu_added;
-qemu_register_cpu_added_notifier(&cpu_hotplug_cb.cpu_added_notifier);
+qemu_register_cpu_hotplug_notifier(&cpu_hotplug_cb.cpu_added_notifier);
 
 if (set_boot_dev(s, boot_device)) {
 exit(1);
diff --git a/include/hw/acpi/ich9.h b/include/hw/acpi/ich9.h
index 7e42448..bbb5d2c 100644
--- a/include/hw/acpi/ich9.h
+++ b/include/hw/acpi/ich9.h
@@ -47,7 +47,7 @@ typedef struct ICH9LPCPMRegs {
 Notifier powerdown_notifier;
 
 AcpiCpuHotplug gpe_cpu;
-Notifier cpu_added_notifier;
+Notifier cpu_hotplug_notifier;
 
 MemHotplugState acpi_memory_hotplug;
 } ICH9LPCPMRegs;
diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h
index d8539fd..6810f70 100644
--- a/include/sysemu/sysemu.h
+++ b/include/sysemu/sysemu.h
@@ -184,7 +184,7 @@ void do_pci_device_hot_remove(Monitor *mon, const QDict 
*qdict);
 void drive_hot_add(Monitor *mon, const QDict *qdict);
 
 /* CPU hotplug */
-void qemu_register_cpu_added_notifier(Notifier *notifier);
+void qemu_register_cpu_hotplug_notifier(Notifier *notifier);
 
 /* pcie aer error injection */
 void pcie_aer_inject_error_print(Monitor *mon, const QObject *data);
diff --git a/qom/cpu.c b/qom/cpu.c
index bf16590..add92b1 100644
--- a/qom/cpu.c
+++ b/qom/cpu.c
@@ -108,12 +108,12 @@ static void cpu_common_get_memory_mapping(CPUState *cpu,
 }
 
 /* CPU hot-plug notifiers */
-static NotifierList cpu_added_notifiers =
-NOTIFIER_LIST_INITIALIZ

[Qemu-devel] [RFC PATCH 07/10] qom cpu: add UNPLUG cpu notify support

2014-08-06 Thread Gu Zheng
Introduce a common cpu hotplug notifier(CPUNotifier)
to support UNPLUG cpu notify.

Signed-off-by: Gu Zheng 
Signed-off-by: Chen Fan 
---
 hw/acpi/cpu_hotplug.c |   15 +++
 hw/acpi/ich9.c|5 -
 hw/acpi/piix4.c   |   11 +++
 include/hw/acpi/cpu_hotplug.h |   13 -
 qom/cpu.c |7 ++-
 5 files changed, 40 insertions(+), 11 deletions(-)

diff --git a/hw/acpi/cpu_hotplug.c b/hw/acpi/cpu_hotplug.c
index 2ad83a0..56cb316 100644
--- a/hw/acpi/cpu_hotplug.c
+++ b/hw/acpi/cpu_hotplug.c
@@ -36,15 +36,22 @@ static const MemoryRegionOps AcpiCpuHotplug_ops = {
 },
 };
 
-void AcpiCpuHotplug_add(ACPIGPE *gpe, AcpiCpuHotplug *g, CPUState *cpu)
+void AcpiCpuHotplug_handle(ACPIGPE *gpe, AcpiCpuHotplug *g,
+   CPUNotifier *notify)
 {
-CPUClass *k = CPU_GET_CLASS(cpu);
+CPUClass *k = CPU_GET_CLASS(notify->dev);
+HotplugEventType type = notify->type;
 int64_t cpu_id;
 
 *gpe->sts = *gpe->sts | ACPI_CPU_HOTPLUG_STATUS;
-cpu_id = k->get_arch_id(CPU(cpu));
+cpu_id = k->get_arch_id(CPU(notify->dev));
 g_assert((cpu_id / 8) < ACPI_GPE_PROC_LEN);
-g->sts[cpu_id / 8] |= (1 << (cpu_id % 8));
+
+if (type == PLUG) {
+g->sts[cpu_id / 8] |= (1 << (cpu_id % 8));
+} else {
+g->sts[cpu_id / 8] &= ~(1 << (cpu_id % 8));
+}
 }
 
 void AcpiCpuHotplug_init(MemoryRegion *parent, Object *owner,
diff --git a/hw/acpi/ich9.c b/hw/acpi/ich9.c
index 804f774..2db491d 100644
--- a/hw/acpi/ich9.c
+++ b/hw/acpi/ich9.c
@@ -212,9 +212,12 @@ static void pm_powerdown_req(Notifier *n, void *opaque)
 static void ich9_cpu_hotplug_req(Notifier *n, void *opaque)
 {
 ICH9LPCPMRegs *pm = container_of(n, ICH9LPCPMRegs, cpu_hotplug_notifier);
+CPUNotifier *notifier = (CPUNotifier *)opaque;
 
 assert(pm != NULL);
-AcpiCpuHotplug_add(&pm->acpi_regs.gpe, &pm->gpe_cpu, CPU(opaque));
+
+AcpiCpuHotplug_handle(&pm->acpi_regs.gpe, &pm->gpe_cpu, notifier);
+
 acpi_update_sci(&pm->acpi_regs, pm->irq);
 }
 
diff --git a/hw/acpi/piix4.c b/hw/acpi/piix4.c
index 5cd6300..cc15b60 100644
--- a/hw/acpi/piix4.c
+++ b/hw/acpi/piix4.c
@@ -93,7 +93,7 @@ typedef struct PIIX4PMState {
 #define PIIX4_PM(obj) \
 OBJECT_CHECK(PIIX4PMState, (obj), TYPE_PIIX4_PM)
 
-static void piix4_acpi_system_hot_add_init(MemoryRegion *parent,
+static void piix4_acpi_system_hotplug_init(MemoryRegion *parent,
PCIBus *bus, PIIX4PMState *s);
 
 #define ACPI_ENABLE 0xf1
@@ -465,7 +465,7 @@ static int piix4_pm_initfn(PCIDevice *dev)
 qemu_add_machine_init_done_notifier(&s->machine_ready);
 qemu_register_reset(piix4_reset, s);
 
-piix4_acpi_system_hot_add_init(pci_address_space_io(dev), dev->bus, s);
+piix4_acpi_system_hotplug_init(pci_address_space_io(dev), dev->bus, s);
 
 piix4_pm_add_propeties(s);
 return 0;
@@ -547,13 +547,16 @@ static const MemoryRegionOps piix4_gpe_ops = {
 static void piix4_cpu_hotplug(Notifier *n, void *opaque)
 {
 PIIX4PMState *s = container_of(n, PIIX4PMState, cpu_hotplug_notifier);
+CPUNotifier *notifier = (CPUNotifier *)opaque;
 
 assert(s != NULL);
-AcpiCpuHotplug_add(&s->ar.gpe, &s->gpe_cpu, CPU(opaque));
+
+AcpiCpuHotplug_handle(&s->ar.gpe, &s->gpe_cpu, notifier);
+
 acpi_update_sci(&s->ar, s->irq);
 }
 
-static void piix4_acpi_system_hot_add_init(MemoryRegion *parent,
+static void piix4_acpi_system_hotplug_init(MemoryRegion *parent,
PCIBus *bus, PIIX4PMState *s)
 {
 memory_region_init_io(&s->io_gpe, OBJECT(s), &piix4_gpe_ops, s,
diff --git a/include/hw/acpi/cpu_hotplug.h b/include/hw/acpi/cpu_hotplug.h
index 9e5d30c..4fe0066 100644
--- a/include/hw/acpi/cpu_hotplug.h
+++ b/include/hw/acpi/cpu_hotplug.h
@@ -15,12 +15,23 @@
 #include "hw/acpi/acpi.h"
 #include "hw/acpi/pc-hotplug.h"
 
+typedef enum {
+PLUG,
+UNPLUG,
+} HotplugEventType;
+
+typedef struct CPUNotifier {
+DeviceState *dev;
+HotplugEventType type;
+} CPUNotifier;
+
 typedef struct AcpiCpuHotplug {
 MemoryRegion io;
 uint8_t sts[ACPI_GPE_PROC_LEN];
 } AcpiCpuHotplug;
 
-void AcpiCpuHotplug_add(ACPIGPE *gpe, AcpiCpuHotplug *g, CPUState *cpu);
+void AcpiCpuHotplug_handle(ACPIGPE *gpe, AcpiCpuHotplug *g,
+   CPUNotifier *notify);
 
 void AcpiCpuHotplug_init(MemoryRegion *parent, Object *owner,
  AcpiCpuHotplug *gpe_cpu, uint16_t base);
diff --git a/qom/cpu.c b/qom/cpu.c
index add92b1..f921282 100644
--- a/qom/cpu.c
+++ b/qom/cpu.c
@@ -25,6 +25,7 @@
 #include "qemu/log.h"
 #include "qemu/error-report.h"
 #include "sysemu/sysemu.h"
+#include "hw/acpi/cpu_hotplug.h"
 
 bool cpu_exists(int

[Qemu-devel] [RFC PATCH 08/10] i386: implement pc interface cpu_common_unrealizefn() in qom/cpu.c

2014-08-06 Thread Gu Zheng
From: Chen Fan 

add interface cpu_common_unrealizefn() for emiting vcpu unplug
notifier to ACPI, then ACPI could send sci interrupt
to OS for hot-remove vcpu.

Signed-off-by: Chen Fan 
Signed-off-by: Gu Zheng 
---
 qom/cpu.c |   12 
 1 files changed, 12 insertions(+), 0 deletions(-)

diff --git a/qom/cpu.c b/qom/cpu.c
index f921282..8bb2b4f 100644
--- a/qom/cpu.c
+++ b/qom/cpu.c
@@ -315,6 +315,17 @@ static void cpu_common_realizefn(DeviceState *dev, Error 
**errp)
 }
 }
 
+static void cpu_common_unrealizefn(DeviceState *dev, Error **errp)
+{
+CPUNotifier notifier;
+
+notifier.dev = dev;
+notifier.type = UNPLUG;
+
+notifier_list_notify(&cpu_hotplug_notifiers, ¬ifier);
+}
+
+
 static void cpu_common_initfn(Object *obj)
 {
 CPUState *cpu = CPU(obj);
@@ -348,6 +359,7 @@ static void cpu_class_init(ObjectClass *klass, void *data)
 k->gdb_write_register = cpu_common_gdb_write_register;
 k->virtio_is_big_endian = cpu_common_virtio_is_big_endian;
 dc->realize = cpu_common_realizefn;
+dc->unrealize = cpu_common_unrealizefn;
 /*
  * Reason: CPUs still need special care by board code: wiring up
  * IRQs, adding reset handlers, halting non-first CPUs, ...
-- 
1.7.7




[Qemu-devel] [RFC PATCH 09/10] cpu hotplug: implement function cpu_status_write() for vcpu ejection

2014-08-06 Thread Gu Zheng
From: Chen Fan 

When OS ejected a vcpu (like: echo 1 > /sys/bus/acpi/devices/LNXCPUXX/eject),
it would call acpi EJ0 method, the firmware need to write the new cpumap, QEMU
would know which vcpu need to be ejected.

TODO:
-confirm the hotplug result via OST if guest support it.

Signed-off-by: Chen Fan 
Signed-off-by: Gu Zheng 
---
 cpus.c|7 ++
 hw/acpi/cpu_hotplug.c |   40 -
 hw/i386/acpi-dsdt-cpu-hotplug.dsl |6 -
 include/hw/acpi/cpu_hotplug.h |1 +
 include/qom/cpu.h |9 
 5 files changed, 61 insertions(+), 2 deletions(-)

diff --git a/cpus.c b/cpus.c
index 5e7f2cf..4dfb889 100644
--- a/cpus.c
+++ b/cpus.c
@@ -1117,6 +1117,13 @@ void resume_all_vcpus(void)
 }
 }
 
+void cpu_remove(CPUState *cpu)
+{
+cpu->stop = true;
+cpu->exit = true;
+qemu_cpu_kick(cpu);
+}
+
 /* For temporary buffers for forming a name */
 #define VCPU_THREAD_NAME_SIZE 16
 
diff --git a/hw/acpi/cpu_hotplug.c b/hw/acpi/cpu_hotplug.c
index 56cb316..7cbce69 100644
--- a/hw/acpi/cpu_hotplug.c
+++ b/hw/acpi/cpu_hotplug.c
@@ -20,10 +20,46 @@ static uint64_t cpu_status_read(void *opaque, hwaddr addr, 
unsigned int size)
 return val;
 }
 
+static void acpi_eject_vcpu(AcpiCpuHotplug *cpus_status, int64_t cpu_id)
+{
+CPUState *cpu;
+
+CPU_FOREACH(cpu) {
+CPUClass *cc = CPU_GET_CLASS(cpu);
+int64_t id = cc->get_arch_id(cpu);
+
+if (cpu_id == id) {
+cpus_status->old_sts[cpu_id / 8] &= ~(1 << (cpu_id % 8));
+cpus_status->sts[cpu_id / 8] &= ~(1 << (cpu_id % 8));
+cpu_remove(cpu);
+break;
+}
+}
+}
+
 static void cpu_status_write(void *opaque, hwaddr addr, uint64_t data,
  unsigned int size)
 {
-/* TODO: implement VCPU removal on guest signal that CPU can be removed */
+AcpiCpuHotplug *cpus = opaque;
+uint8_t val;
+int i;
+int64_t cpu_id = -1;
+
+val = cpus->old_sts[addr] ^ data;
+
+if (val == 0) {
+return;
+}
+
+for (i = 0; i < 8; i++) {
+if (val & 1 << i) {
+cpu_id = 8 * addr + i;
+}
+}
+
+if (cpu_id != -1) {
+acpi_eject_vcpu(cpus, cpu_id);
+}
 }
 
 static const MemoryRegionOps AcpiCpuHotplug_ops = {
@@ -49,6 +85,7 @@ void AcpiCpuHotplug_handle(ACPIGPE *gpe, AcpiCpuHotplug *g,
 
 if (type == PLUG) {
 g->sts[cpu_id / 8] |= (1 << (cpu_id % 8));
+g->old_sts[cpu_id / 8] |= (1 << (cpu_id % 8));
 } else {
 g->sts[cpu_id / 8] &= ~(1 << (cpu_id % 8));
 }
@@ -65,6 +102,7 @@ void AcpiCpuHotplug_init(MemoryRegion *parent, Object *owner,
 
 g_assert((id / 8) < ACPI_GPE_PROC_LEN);
 gpe_cpu->sts[id / 8] |= (1 << (id % 8));
+gpe_cpu->old_sts[id / 8] |= (1 << (id % 8));
 }
 memory_region_init_io(&gpe_cpu->io, owner, &AcpiCpuHotplug_ops,
   gpe_cpu, "acpi-cpu-hotplug", ACPI_GPE_PROC_LEN);
diff --git a/hw/i386/acpi-dsdt-cpu-hotplug.dsl 
b/hw/i386/acpi-dsdt-cpu-hotplug.dsl
index 34aab5a..9485f12 100644
--- a/hw/i386/acpi-dsdt-cpu-hotplug.dsl
+++ b/hw/i386/acpi-dsdt-cpu-hotplug.dsl
@@ -50,7 +50,11 @@ Scope(\_SB) {
 }
 Method(CPEJ, 2, NotSerialized) {
 // _EJ0 method - eject callback
-Sleep(200)
+Store(Zero, Index(CPON, ToInteger(Arg0)))
+Store(One, Local0)
+ShiftLeft(Local0, Arg0, Local0)
+Not(Local0, Local0)
+And(PRS, Local0, PRS)
 }
 
 #define CPU_STATUS_LEN ACPI_GPE_PROC_LEN
diff --git a/include/hw/acpi/cpu_hotplug.h b/include/hw/acpi/cpu_hotplug.h
index 4fe0066..3bffc69 100644
--- a/include/hw/acpi/cpu_hotplug.h
+++ b/include/hw/acpi/cpu_hotplug.h
@@ -28,6 +28,7 @@ typedef struct CPUNotifier {
 typedef struct AcpiCpuHotplug {
 MemoryRegion io;
 uint8_t sts[ACPI_GPE_PROC_LEN];
+uint8_t old_sts[ACPI_GPE_PROC_LEN];
 } AcpiCpuHotplug;
 
 void AcpiCpuHotplug_handle(ACPIGPE *gpe, AcpiCpuHotplug *g,
diff --git a/include/qom/cpu.h b/include/qom/cpu.h
index 2fc00ef..9108dc6 100644
--- a/include/qom/cpu.h
+++ b/include/qom/cpu.h
@@ -236,6 +236,7 @@ struct CPUState {
 bool created;
 bool stop;
 bool stopped;
+bool exit;
 volatile sig_atomic_t exit_request;
 uint32_t interrupt_request;
 int singlestep_enabled;
@@ -600,6 +601,14 @@ void cpu_exit(CPUState *cpu);
 void cpu_resume(CPUState *cpu);
 
 /**
+ * cpu_remove:
+ * @cpu: The vCPU to remove.
+ *
+ * Requests the CPU @cpu to be removed.
+ */
+void cpu_remove(CPUState *cpu);
+
+/**
  * qemu_init_vcpu:
  * @cpu: The vCPU to initialize.
  *
-- 
1.7.7




[Qemu-devel] [RFC PATCH 10/10] cpus: reclaim allocated vCPU objects

2014-08-06 Thread Gu Zheng
After ACPI get a signal to eject a vCPU, the vCPU must be
removed from CPU list,before the vCPU really removed,  then
release the all related vCPU objects.
But we do not close KVM vcpu fd, just record it into a list, in
order to reuse it.

Signed-off-by: Chen Fan 
Signed-off-by: Gu Zheng 
---
 cpus.c   |   37 
 include/sysemu/kvm.h |1 +
 kvm-all.c|   57 +-
 3 files changed, 94 insertions(+), 1 deletions(-)

diff --git a/cpus.c b/cpus.c
index 4dfb889..9a73407 100644
--- a/cpus.c
+++ b/cpus.c
@@ -786,6 +786,24 @@ void async_run_on_cpu(CPUState *cpu, void (*func)(void 
*data), void *data)
 qemu_cpu_kick(cpu);
 }
 
+static void qemu_kvm_destroy_vcpu(CPUState *cpu)
+{
+CPU_REMOVE(cpu);
+
+if (kvm_destroy_vcpu(cpu) < 0) {
+fprintf(stderr, "kvm_destroy_vcpu failed.\n");
+exit(1);
+}
+
+object_unparent(OBJECT(cpu));
+}
+
+static void qemu_tcg_destroy_vcpu(CPUState *cpu)
+{
+CPU_REMOVE(cpu);
+object_unparent(OBJECT(cpu));
+}
+
 static void flush_queued_work(CPUState *cpu)
 {
 struct qemu_work_item *wi;
@@ -877,6 +895,11 @@ static void *qemu_kvm_cpu_thread_fn(void *arg)
 }
 }
 qemu_kvm_wait_io_event(cpu);
+if (cpu->exit && !cpu_can_run(cpu)) {
+qemu_kvm_destroy_vcpu(cpu);
+qemu_mutex_unlock(&qemu_global_mutex);
+return NULL;
+}
 }
 
 return NULL;
@@ -929,6 +952,7 @@ static void tcg_exec_all(void);
 static void *qemu_tcg_cpu_thread_fn(void *arg)
 {
 CPUState *cpu = arg;
+CPUState *remove_cpu = NULL;
 
 qemu_tcg_init_cpu_signals();
 qemu_thread_get_self(cpu->thread);
@@ -961,6 +985,16 @@ static void *qemu_tcg_cpu_thread_fn(void *arg)
 }
 }
 qemu_tcg_wait_io_event();
+CPU_FOREACH(cpu) {
+if (cpu->exit && !cpu_can_run(cpu)) {
+remove_cpu = cpu;
+break;
+}
+}
+if (remove_cpu) {
+qemu_tcg_destroy_vcpu(remove_cpu);
+remove_cpu = NULL;
+}
 }
 
 return NULL;
@@ -1316,6 +1350,9 @@ static void tcg_exec_all(void)
 break;
 }
 } else if (cpu->stop || cpu->stopped) {
+if (cpu->exit) {
+next_cpu = CPU_NEXT(cpu);
+}
 break;
 }
 }
diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h
index 174ea36..88e2403 100644
--- a/include/sysemu/kvm.h
+++ b/include/sysemu/kvm.h
@@ -178,6 +178,7 @@ int kvm_has_intx_set_mask(void);
 
 int kvm_init_vcpu(CPUState *cpu);
 int kvm_cpu_exec(CPUState *cpu);
+int kvm_destroy_vcpu(CPUState *cpu);
 
 #ifdef NEED_CPU_H
 
diff --git a/kvm-all.c b/kvm-all.c
index 1402f4f..d0caeff 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -74,6 +74,12 @@ typedef struct KVMSlot
 
 typedef struct kvm_dirty_log KVMDirtyLog;
 
+struct KVMParkedVcpu {
+unsigned long vcpu_id;
+int kvm_fd;
+QLIST_ENTRY(KVMParkedVcpu) node;
+};
+
 struct KVMState
 {
 KVMSlot *slots;
@@ -108,6 +114,7 @@ struct KVMState
 QTAILQ_HEAD(msi_hashtab, KVMMSIRoute) msi_hashtab[KVM_MSI_HASHTAB_SIZE];
 bool direct_msi;
 #endif
+QLIST_HEAD(, KVMParkedVcpu) kvm_parked_vcpus;
 };
 
 KVMState *kvm_state;
@@ -226,6 +233,53 @@ static int kvm_set_user_memory_region(KVMState *s, KVMSlot 
*slot)
 return kvm_vm_ioctl(s, KVM_SET_USER_MEMORY_REGION, &mem);
 }
 
+int kvm_destroy_vcpu(CPUState *cpu)
+{
+KVMState *s = kvm_state;
+long mmap_size;
+struct KVMParkedVcpu *vcpu = NULL;
+int ret = 0;
+
+DPRINTF("kvm_destroy_vcpu\n");
+
+mmap_size = kvm_ioctl(s, KVM_GET_VCPU_MMAP_SIZE, 0);
+if (mmap_size < 0) {
+ret = mmap_size;
+DPRINTF("KVM_GET_VCPU_MMAP_SIZE failed\n");
+goto err;
+}
+
+ret = munmap(cpu->kvm_run, mmap_size);
+if (ret < 0) {
+goto err;
+}
+
+vcpu = g_malloc0(sizeof(*vcpu));
+vcpu->vcpu_id = kvm_arch_vcpu_id(cpu);
+vcpu->kvm_fd = cpu->kvm_fd;
+QLIST_INSERT_HEAD(&kvm_state->kvm_parked_vcpus, vcpu, node);
+err:
+return ret;
+}
+
+static int kvm_get_vcpu(KVMState *s, unsigned long vcpu_id)
+{
+struct KVMParkedVcpu *cpu;
+
+QLIST_FOREACH(cpu, &s->kvm_parked_vcpus, node) {
+if (cpu->vcpu_id == vcpu_id) {
+int kvm_fd;
+
+QLIST_REMOVE(cpu, node);
+kvm_fd = cpu->kvm_fd;
+g_free(cpu);
+return kvm_fd;
+}
+}
+
+return kvm_vm_ioctl(s, KVM_CREATE_VCPU, (void *)vcpu_id);
+}
+
 int kvm_init_vcpu(CPUState *cpu)
 {
 KVMState *s = kvm_state;
@@ -234,7 +288,7 @@ int kvm_init_vcpu(CPUState *cpu)
 
 DPRINTF("kvm_init_vcpu\n");
 
-ret = kvm_vm_ioctl(s, KVM_CREATE_VCPU, (void *)kvm_arch_vcpu_id(cpu));
+ret = kvm_get_vcpu(s, kvm_

Re: [Qemu-devel] [RFC PATCH 10/10] cpus: reclaim allocated vCPU objects

2014-08-07 Thread Gu Zheng
Hi Anshul,
On 08/07/2014 09:31 PM, Anshul Makkar wrote:

> Thanks Gu.. cpu-hotunplug is working fine in my  tests.

Thanks for your quick test.

> 
> For cpu-hotplug, I get inconsistent result if I delete arbitrary cpu
> and not just the last one.
> 
> for eg
> list of cpus: 1, 2 ,3
> device_add cpu 4
> device_add cpu 5
> device_add cpu 6

What type id do you use here? apic-id or device id?

> 
> device_del cpu 4
> device_del cpu 6

Could you please offer the detail reproduce info? the more the better.

> 
> now if I do device_add cpu6, then cpu 4 gets added and now if I try to
> do add cpu 4 or 6, it says cpu already exist.. Its a kind of vague
> behaviour.. Do, we follow any protocol here while adding and deleting
> cpus.

There is not strict restriction here. Does the following routine match
the condition you mentioned? It works fine in my box.

Original cpus:0,1 maxcpus:6
(qemu) device_add qemu64-x86_64-cpu,apic-id=2,id=cpu2
(qemu) device_add qemu64-x86_64-cpu,apic-id=3,id=cpu3
(qemu) device_add qemu64-x86_64-cpu,apic-id=4,id=cpu4

(qemu) device_del cpu2
(qemu) device_del cpu4

(qemu) device_add qemu64-x86_64-cpu,apic-id=4,id=cpu4
(qemu) device_add qemu64-x86_64-cpu,apic-id=2,id=cpu2

Thanks,
Gu

> 
> Thanks
> Anshul Makkar
> www.justkernel.com
> 
> On Thu, Aug 7, 2014 at 6:54 AM, Gu Zheng  wrote:
>> After ACPI get a signal to eject a vCPU, the vCPU must be
>> removed from CPU list,before the vCPU really removed,  then
>> release the all related vCPU objects.
>> But we do not close KVM vcpu fd, just record it into a list, in
>> order to reuse it.
>>
>> Signed-off-by: Chen Fan 
>> Signed-off-by: Gu Zheng 
>> ---
>>  cpus.c   |   37 
>>  include/sysemu/kvm.h |1 +
>>  kvm-all.c|   57 
>> +-
>>  3 files changed, 94 insertions(+), 1 deletions(-)
>>
>> diff --git a/cpus.c b/cpus.c
>> index 4dfb889..9a73407 100644
>> --- a/cpus.c
>> +++ b/cpus.c
>> @@ -786,6 +786,24 @@ void async_run_on_cpu(CPUState *cpu, void (*func)(void 
>> *data), void *data)
>>  qemu_cpu_kick(cpu);
>>  }
>>
>> +static void qemu_kvm_destroy_vcpu(CPUState *cpu)
>> +{
>> +CPU_REMOVE(cpu);
>> +
>> +if (kvm_destroy_vcpu(cpu) < 0) {
>> +fprintf(stderr, "kvm_destroy_vcpu failed.\n");
>> +exit(1);
>> +}
>> +
>> +object_unparent(OBJECT(cpu));
>> +}
>> +
>> +static void qemu_tcg_destroy_vcpu(CPUState *cpu)
>> +{
>> +CPU_REMOVE(cpu);
>> +object_unparent(OBJECT(cpu));
>> +}
>> +
>>  static void flush_queued_work(CPUState *cpu)
>>  {
>>  struct qemu_work_item *wi;
>> @@ -877,6 +895,11 @@ static void *qemu_kvm_cpu_thread_fn(void *arg)
>>  }
>>  }
>>  qemu_kvm_wait_io_event(cpu);
>> +if (cpu->exit && !cpu_can_run(cpu)) {
>> +qemu_kvm_destroy_vcpu(cpu);
>> +qemu_mutex_unlock(&qemu_global_mutex);
>> +return NULL;
>> +}
>>  }
>>
>>  return NULL;
>> @@ -929,6 +952,7 @@ static void tcg_exec_all(void);
>>  static void *qemu_tcg_cpu_thread_fn(void *arg)
>>  {
>>  CPUState *cpu = arg;
>> +CPUState *remove_cpu = NULL;
>>
>>  qemu_tcg_init_cpu_signals();
>>  qemu_thread_get_self(cpu->thread);
>> @@ -961,6 +985,16 @@ static void *qemu_tcg_cpu_thread_fn(void *arg)
>>  }
>>  }
>>  qemu_tcg_wait_io_event();
>> +CPU_FOREACH(cpu) {
>> +if (cpu->exit && !cpu_can_run(cpu)) {
>> +remove_cpu = cpu;
>> +break;
>> +}
>> +}
>> +if (remove_cpu) {
>> +qemu_tcg_destroy_vcpu(remove_cpu);
>> +remove_cpu = NULL;
>> +}
>>  }
>>
>>  return NULL;
>> @@ -1316,6 +1350,9 @@ static void tcg_exec_all(void)
>>  break;
>>  }
>>  } else if (cpu->stop || cpu->stopped) {
>> +if (cpu->exit) {
>> +next_cpu = CPU_NEXT(cpu);
>> +}
>>  break;
>>  }
>>  }
>> diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h
>> index 174ea36..88e2403 100644
>> --- a/include/sysemu/kvm.h
>> +++ b/include/sysemu/kvm.h
>> @@ -178,6 +178,7 @@ int kvm_has_intx_set_mask(void);
>>
>>  int kvm_init_vcpu(

Re: [Qemu-devel] [RFC V2 02/10] qom/cpu: move register_vmstate to common CPUClass.realizefn

2014-09-09 Thread Gu Zheng
Hi Igor,
On 09/09/2014 08:17 PM, Igor Mammedov wrote:

> On Thu, 28 Aug 2014 11:36:34 +0800
> Gu Zheng  wrote:
> 
>> Move cpu vmstate register from cpu_exec_init into cpu_common_realizefn,
>> apic vmstate register into x86_cpu_apic_realize. And use the
>> cc->get_arch_id as the instance id that suggested by Igor to
>> fix the migration issue.
>> Besides, also use cc->get_arch_id as the cpu index of HMP/QMP command output 
>> to
>> fix the index duplicated issue when hotadd a hot-removed cpu.
>>
>> v2:
>>  -fix the cpu index duplicated issue in the QMP/HMP command output.
>>
>> Signed-off-by: Gu Zheng 
> Please split CPU vmstate/APIC vmstate/QMP-monitor changes into separate 
> patches.

Got it, it does need to be restructured.

> 
>> ---
>>  cpus.c  |4 +++-
>>  exec.c  |   32 +++-
>>  hw/intc/apic_common.c   |3 +--
>>  include/hw/i386/apic_internal.h |2 ++
>>  include/qom/cpu.h   |2 ++
>>  monitor.c   |4 +++-
>>  qom/cpu.c   |2 ++
>>  target-i386/cpu.c   |   10 --
>>  8 files changed, 40 insertions(+), 19 deletions(-)
>>
>> diff --git a/cpus.c b/cpus.c
>> index 2b5c0bd..cce2744 100644
>> --- a/cpus.c
>> +++ b/cpus.c
>> @@ -1394,6 +1394,7 @@ CpuInfoList *qmp_query_cpus(Error **errp)
>>  {
>>  CpuInfoList *head = NULL, *cur_item = NULL;
>>  CPUState *cpu;
>> +CPUClass *cc;
>>  
>>  CPU_FOREACH(cpu) {
>>  CpuInfoList *info;
>> @@ -1411,11 +1412,12 @@ CpuInfoList *qmp_query_cpus(Error **errp)
>>  CPUMIPSState *env = &mips_cpu->env;
>>  #endif
>>  
>> +cc = CPU_GET_CLASS(cpu);
>>  cpu_synchronize_state(cpu);
>>  
>>  info = g_malloc0(sizeof(*info));
>>  info->value = g_malloc0(sizeof(*info->value));
>> -info->value->CPU = cpu->cpu_index;
>> +info->value->CPU = cc->get_arch_id(cpu);
>>  info->value->current = (cpu == first_cpu);
>>  info->value->halted = cpu->halted;
>>  info->value->thread_id = cpu->thread_id;
>> diff --git a/exec.c b/exec.c
>> index 5f9857c..c514492 100644
>> --- a/exec.c
>> +++ b/exec.c
>> @@ -473,10 +473,28 @@ void tcg_cpu_address_space_init(CPUState *cpu, 
>> AddressSpace *as)
>>  }
>>  #endif
>>  
>> +void cpu_vmstate_register(CPUState *cpu)
>> +{
>> +CPUClass *cc = CPU_GET_CLASS(cpu);
>> +int cpu_index = cc->get_arch_id(cpu);
>> +
>> +if (qdev_get_vmsd(DEVICE(cpu)) == NULL) {
>> +vmstate_register(NULL, cpu_index, &vmstate_cpu_common, cpu);
>> +}
>> +#if defined(CPU_SAVE_VERSION) && !defined(CONFIG_USER_ONLY)
>> +register_savevm(NULL, "cpu", cpu_index, CPU_SAVE_VERSION,
>> +cpu_save, cpu_load, cpu->env_ptr);
>> +assert(cc->vmsd == NULL);
>> +assert(qdev_get_vmsd(DEVICE(cpu)) == NULL);
>> +#endif
>> +if (cc->vmsd != NULL) {
>> +vmstate_register(NULL, cpu_index, cc->vmsd, cpu);
>> +}
>> +}
>> +
>>  void cpu_exec_init(CPUArchState *env)
>>  {
>>  CPUState *cpu = ENV_GET_CPU(env);
>> -CPUClass *cc = CPU_GET_CLASS(cpu);
>>  CPUState *some_cpu;
>>  int cpu_index;
>>  
>> @@ -499,18 +517,6 @@ void cpu_exec_init(CPUArchState *env)
>>  #if defined(CONFIG_USER_ONLY)
>>  cpu_list_unlock();
>>  #endif
>> -if (qdev_get_vmsd(DEVICE(cpu)) == NULL) {
>> -vmstate_register(NULL, cpu_index, &vmstate_cpu_common, cpu);
>> -}
>> -#if defined(CPU_SAVE_VERSION) && !defined(CONFIG_USER_ONLY)
>> -register_savevm(NULL, "cpu", cpu_index, CPU_SAVE_VERSION,
>> -cpu_save, cpu_load, env);
>> -assert(cc->vmsd == NULL);
>> -assert(qdev_get_vmsd(DEVICE(cpu)) == NULL);
>> -#endif
>> -if (cc->vmsd != NULL) {
>> -vmstate_register(NULL, cpu_index, cc->vmsd, cpu);
>> -}
>>  }
>>  
>>  #if defined(TARGET_HAS_ICE)
>> diff --git a/hw/intc/apic_common.c b/hw/intc/apic_common.c
>> index ce3d903..029f67d 100644
>> --- a/hw/intc/apic_common.c
>> +++ b/hw/intc/apic_common.c
>> @@ -345,7 +345,7 @@ static int apic_dispatch_post_load(void *opaque, int 
>> version_id)
>>  return 0;
>>  }
>>  
>>

Re: [Qemu-devel] [RFC V2 03/10] cpu: add device_add foo-x86_64-cpu support

2014-09-09 Thread Gu Zheng
Hi Igor,
On 09/09/2014 08:44 PM, Igor Mammedov wrote:

> On Thu, 28 Aug 2014 11:36:35 +0800
> Gu Zheng  wrote:
> 
>> From: Chen Fan 
>>
>> Add support to device_add foo-x86_64-cpu, and additional checks of
>> apic id are added into x86_cpuid_set_apic_id() and x86_cpu_apic_create()
>> for duplicate. Besides, in order to support "device/device_add 
>> foo-x86_64-cpu"
>> which without specified apic id, we add a new function get_free_apic_id() to
>> provide the first free apid id each time to avoid apic id duplicate.
>>
>> Signed-off-by: Chen Fan 
>> Signed-off-by: Gu Zheng 
>> ---
>>  include/qom/cpu.h  |1 +
>>  qdev-monitor.c |1 +
>>  target-i386/cpu.c  |   61 
>> +++-
>>  target-i386/topology.h |   18 ++
>>  4 files changed, 80 insertions(+), 1 deletions(-)
>>
>> diff --git a/include/qom/cpu.h b/include/qom/cpu.h
>> index bc32c9a..2fc00ef 100644
>> --- a/include/qom/cpu.h
>> +++ b/include/qom/cpu.h
>> @@ -292,6 +292,7 @@ struct CPUState {
>>  QTAILQ_HEAD(CPUTailQ, CPUState);
>>  extern struct CPUTailQ cpus;
>>  #define CPU_NEXT(cpu) QTAILQ_NEXT(cpu, node)
>> +#define CPU_REMOVE(cpu) QTAILQ_REMOVE(&cpus, cpu, node)
>>  #define CPU_FOREACH(cpu) QTAILQ_FOREACH(cpu, &cpus, node)
>>  #define CPU_FOREACH_SAFE(cpu, next_cpu) \
>>  QTAILQ_FOREACH_SAFE(cpu, &cpus, node, next_cpu)
>> diff --git a/qdev-monitor.c b/qdev-monitor.c
>> index fb9ee24..1aa446d 100644
>> --- a/qdev-monitor.c
>> +++ b/qdev-monitor.c
>> @@ -24,6 +24,7 @@
>>  #include "qmp-commands.h"
>>  #include "sysemu/arch_init.h"
>>  #include "qemu/config-file.h"
>> +#include "qom/object_interfaces.h"
>>  
>>  /*
>>   * Aliases were a bad idea from the start.  Let's keep them
>> diff --git a/target-i386/cpu.c b/target-i386/cpu.c
>> index 2aa2b31..5255ddb 100644
>> --- a/target-i386/cpu.c
>> +++ b/target-i386/cpu.c
>> @@ -49,6 +49,7 @@
>>  #include "hw/i386/apic_internal.h"
>>  #endif
>>  
>> +#include "qom/object_interfaces.h"
> This probably belongs to another patch.

Yes, It's a typo here.

> 
>>  
>>  /* Cache topology CPUID constants: */
>>  
>> @@ -1634,6 +1635,7 @@ static void x86_cpuid_set_apic_id(Object *obj, Visitor 
>> *v, void *opaque,
>>  const int64_t max = UINT32_MAX;
>>  Error *error = NULL;
>>  int64_t value;
>> +X86CPUTopoInfo topo;
>>  
>>  if (dev->realized) {
>>  error_setg(errp, "Attempt to set property '%s' on '%s' after "
>> @@ -1653,6 +1655,19 @@ static void x86_cpuid_set_apic_id(Object *obj, 
>> Visitor *v, void *opaque,
>>  return;
>>  }
>>  
>> +if (value > x86_cpu_apic_id_from_index(max_cpus - 1)) {
>> +error_setg(errp, "CPU with APIC ID %" PRIi64
>> +   " is more than MAX APIC ID limits", value);
>> +return;
>> +}
>> +
>> +x86_topo_ids_from_apic_id(smp_cores, smp_threads, value, &topo);
>> +if (topo.smt_id >= smp_threads || topo.core_id >= smp_cores) {
>> +error_setg(errp, "CPU with APIC ID %" PRIi64 " does not match "
>> +   "topology configuration.", value);
>> +return;
>> +}
>> +
>>  if ((value != cpu->env.cpuid_apic_id) && cpu_exists(value)) {
>>  error_setg(errp, "CPU with APIC ID %" PRIi64 " exists", value);
>>  return;
>> @@ -2096,12 +2111,21 @@ out:
>>  return cpu;
>>  }
>>  
>> +static void x86_cpu_cpudef_instance_init(Object *obj)
>> +{
>> +DeviceState *dev = DEVICE(obj);
>> +
>> +dev->hotplugged = true;
>> +}
> looks unnecessary, see device_initfn() which already does above.

You are right, we do not need the x86_cpu_cpudef_instance_init, device_initfn
will do the job for us.

> 
> 
>> +
>>  static void x86_cpu_cpudef_class_init(ObjectClass *oc, void *data)
>>  {
>>  X86CPUDefinition *cpudef = data;
>>  X86CPUClass *xcc = X86_CPU_CLASS(oc);
>> +DeviceClass *dc = DEVICE_CLASS(oc);
>>  
>>  xcc->cpu_def = cpudef;
>> +dc->cannot_instantiate_with_device_add_yet = false;
>>  }
>>  
>>  static void x86_register_cpudef_type(X86CPUDefinition *def)
>> @@ -2110,6 +2134,8 @@ static void

Re: [Qemu-devel] [RFC V2 10/10] cpus: reclaim allocated vCPU objects

2014-09-09 Thread Gu Zheng
Hi Igor,

On 09/09/2014 10:40 PM, Igor Mammedov wrote:

> On Thu, 28 Aug 2014 11:36:42 +0800
> Gu Zheng  wrote:
> 
>> After ACPI get a signal to eject a vCPU, the vCPU must be
>> removed from CPU list,before the vCPU really removed,  then
>> release the all related vCPU objects.
>> But we do not close KVM vcpu fd, just record it into a list, in
>> order to reuse it.
>>
>> Signed-off-by: Chen Fan 
>> Signed-off-by: Gu Zheng 
>> ---
>>  cpus.c   |   37 
>>  include/sysemu/kvm.h |1 +
>>  kvm-all.c|   57 
>> +-
>>  3 files changed, 94 insertions(+), 1 deletions(-)
>>
>> diff --git a/cpus.c b/cpus.c
>> index eee693b..0608b41 100644
>> --- a/cpus.c
>> +++ b/cpus.c
>> @@ -851,6 +851,24 @@ void async_run_on_cpu(CPUState *cpu, void (*func)(void 
>> *data), void *data)
>>  qemu_cpu_kick(cpu);
>>  }
>>  
>> +static void qemu_kvm_destroy_vcpu(CPUState *cpu)
>> +{
>> +CPU_REMOVE(cpu);
>> +
>> +if (kvm_destroy_vcpu(cpu) < 0) {
>> +fprintf(stderr, "kvm_destroy_vcpu failed.\n");
>> +exit(1);
>> +}
>> +
>> +object_unparent(OBJECT(cpu));
>> +}
>> +
>> +static void qemu_tcg_destroy_vcpu(CPUState *cpu)
>> +{
>> +CPU_REMOVE(cpu);
>> +object_unparent(OBJECT(cpu));
>> +}
>> +
>>  static void flush_queued_work(CPUState *cpu)
>>  {
>>  struct qemu_work_item *wi;
>> @@ -942,6 +960,11 @@ static void *qemu_kvm_cpu_thread_fn(void *arg)
>>  }
>>  }
>>  qemu_kvm_wait_io_event(cpu);
>> +if (cpu->exit && !cpu_can_run(cpu)) {
>> +qemu_kvm_destroy_vcpu(cpu);
>> +qemu_mutex_unlock(&qemu_global_mutex);
>> +return NULL;
>> +}
>>  }
>>  
>>  return NULL;
>> @@ -994,6 +1017,7 @@ static void tcg_exec_all(void);
>>  static void *qemu_tcg_cpu_thread_fn(void *arg)
>>  {
>>  CPUState *cpu = arg;
>> +CPUState *remove_cpu = NULL;
>>  
>>  qemu_tcg_init_cpu_signals();
>>  qemu_thread_get_self(cpu->thread);
>> @@ -1026,6 +1050,16 @@ static void *qemu_tcg_cpu_thread_fn(void *arg)
>>  }
>>  }
>>  qemu_tcg_wait_io_event();
>> +CPU_FOREACH(cpu) {
>> +if (cpu->exit && !cpu_can_run(cpu)) {
>> +remove_cpu = cpu;
>> +break;
>> +}
>> +}
>> +if (remove_cpu) {
>> +qemu_tcg_destroy_vcpu(remove_cpu);
>> +remove_cpu = NULL;
>> +}
>>  }
>>  
>>  return NULL;
>> @@ -1383,6 +1417,9 @@ static void tcg_exec_all(void)
>>  break;
>>  }
>>  } else if (cpu->stop || cpu->stopped) {
>> +if (cpu->exit) {
>> +next_cpu = CPU_NEXT(cpu);
>> +}
>>  break;
>>  }
>>  }
>> diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h
>> index 174ea36..88e2403 100644
>> --- a/include/sysemu/kvm.h
>> +++ b/include/sysemu/kvm.h
>> @@ -178,6 +178,7 @@ int kvm_has_intx_set_mask(void);
>>  
>>  int kvm_init_vcpu(CPUState *cpu);
>>  int kvm_cpu_exec(CPUState *cpu);
>> +int kvm_destroy_vcpu(CPUState *cpu);
>>  
>>  #ifdef NEED_CPU_H
>>  
>> diff --git a/kvm-all.c b/kvm-all.c
>> index 1402f4f..d0caeff 100644
>> --- a/kvm-all.c
>> +++ b/kvm-all.c
>> @@ -74,6 +74,12 @@ typedef struct KVMSlot
>>  
>>  typedef struct kvm_dirty_log KVMDirtyLog;
>>  
>> +struct KVMParkedVcpu {
>> +unsigned long vcpu_id;
>> +int kvm_fd;
>> +QLIST_ENTRY(KVMParkedVcpu) node;
>> +};
>> +
>>  struct KVMState
>>  {
>>  KVMSlot *slots;
>> @@ -108,6 +114,7 @@ struct KVMState
>>  QTAILQ_HEAD(msi_hashtab, KVMMSIRoute) msi_hashtab[KVM_MSI_HASHTAB_SIZE];
>>  bool direct_msi;
>>  #endif
>> +QLIST_HEAD(, KVMParkedVcpu) kvm_parked_vcpus;
>>  };
>>  
>>  KVMState *kvm_state;
>> @@ -226,6 +233,53 @@ static int kvm_set_user_memory_region(KVMState *s, 
>> KVMSlot *slot)
>>  return kvm_vm_ioctl(s, KVM_SET_USER_MEMORY_REGION, &mem);
>>  }
>>  
>> +int kvm_destroy_vcpu(CPUState *cpu)
>> +{
>> +KVMState *s = kvm_state;
>> +long mmap_

Re: [Qemu-devel] [PATCH 0/5] cpu/acpi: convert cpu hot plug to hotplug_handler API

2014-09-10 Thread Gu Zheng
Hi Igor,
Thanks very much for your review and suggestion.
On 09/10/2014 10:12 PM, Igor Mammedov wrote:

> On Wed,  3 Sep 2014 17:06:12 +0800
> Gu Zheng  wrote:
> 
>>
>> Gu Zheng (5):
>>   acpi/cpu: add cpu hotplug callback function to match hotplug_handler
>> API
>>   acpi:ich9: convert cpu hotplug handle to hotplug_handler API
>>   acpi:piix4: convert cpu hotplug handle to hotplug_handler API
>>   pc: add cpu hotplug handler to PC_MACHINE
>>   cpu/hotplug: remove the left unused cpu hotplug notifier function
>>
>>  hw/acpi/cpu_hotplug.c |   18 --
>>  hw/acpi/ich9.c|   15 +++
>>  hw/acpi/piix4.c   |   16 +++-
>>  hw/i386/pc.c  |   26 +-
>>  include/hw/acpi/cpu_hotplug.h |6 --
>>  include/hw/acpi/ich9.h|1 -
>>  qom/cpu.c |1 -
>>  7 files changed, 47 insertions(+), 36 deletions(-)
>>
> 
> Looks like right direction that would allow to drop cpu_added_notifiers
> which is not able to pass/handle errors and switch to unified hotplug handler
> API which allows to pass errors and would allow to cancel device_add in case 
> of
> error.

It seems the key value we can gain from above change, I'll follow your 
suggestion. 

> 
> PS:
> Gu Zheng,
> 
> Please grep for qemu_register_cpu_added_notifier(), you've missed to convert
> rtc usage of CPU notifier.

Thanks for your reminder.

> 
> I'd prefer this to go in before you device_add/add cpu series.

OK, I'll work on this series first.

Best regards,
Gu

> .
> 





Re: [Qemu-devel] [PATCH 1/5] acpi/cpu: add cpu hotplug callback function to match hotplug_handler API

2014-09-10 Thread Gu Zheng
Hi Igor,
On 09/10/2014 09:28 PM, Igor Mammedov wrote:

> On Wed,  3 Sep 2014 17:06:13 +0800
> Gu Zheng  wrote:
> 
>>
>> Signed-off-by: Gu Zheng 
>> ---
>>  hw/acpi/cpu_hotplug.c |   17 +
>>  include/hw/acpi/cpu_hotplug.h |3 +++
>>  2 files changed, 20 insertions(+), 0 deletions(-)
>>
>> diff --git a/hw/acpi/cpu_hotplug.c b/hw/acpi/cpu_hotplug.c
>> index 2ad83a0..92c189b 100644
>> --- a/hw/acpi/cpu_hotplug.c
>> +++ b/hw/acpi/cpu_hotplug.c
>> @@ -36,6 +36,23 @@ static const MemoryRegionOps AcpiCpuHotplug_ops = {
>>  },
>>  };
>>  
>> +void acpi_cpu_plug_cb(ACPIREGS *ar, qemu_irq irq,
>> +  AcpiCpuHotplug *g, DeviceState *dev)
> wrong indentation ^^^
> 
> it wouldn't hurt to add errp argument here ...
> 
>> +{
>> +CPUState *cpu = CPU(dev);
>> +CPUClass *k = CPU_GET_CLASS(cpu);
>> +int64_t cpu_id;
>> +
>> +ar->gpe.sts[0] |= ACPI_CPU_HOTPLUG_STATUS;
>> +cpu_id = k->get_arch_id(cpu);
>> +g_assert((cpu_id / 8) < ACPI_GPE_PROC_LEN);
> ... and return error from here instead of aborting

Got it.

> 
>> +g->sts[cpu_id / 8] |= (1 << (cpu_id % 8));
>> +
>> +acpi_update_sci(ar, irq);
>> +
>> +cpu_resume(cpu);
> Why are you adding cpu_resume() here?
> check cpu_common_realizefn() which already does it.

Because hot added callback is called after cpu_common_realizefn(), so I moved
cpu_resume(cpu) from cpu_common_realizefn() here to ensure the guest has already
hot added cpu before we resume it.

> 
>> +}
>> +
>>  void AcpiCpuHotplug_add(ACPIGPE *gpe, AcpiCpuHotplug *g, CPUState *cpu)
>>  {
>>  CPUClass *k = CPU_GET_CLASS(cpu);
>> diff --git a/include/hw/acpi/cpu_hotplug.h b/include/hw/acpi/cpu_hotplug.h
>> index 9e5d30c..d025731 100644
>> --- a/include/hw/acpi/cpu_hotplug.h
>> +++ b/include/hw/acpi/cpu_hotplug.h
>> @@ -20,6 +20,9 @@ typedef struct AcpiCpuHotplug {
>>  uint8_t sts[ACPI_GPE_PROC_LEN];
>>  } AcpiCpuHotplug;
>>  
>> +void acpi_cpu_plug_cb(ACPIREGS *ar, qemu_irq irq,
>> +  AcpiCpuHotplug *g, DeviceState *dev);
> wrong indentation ^^^

OK, will fix this too.

Thanks,
Gu

> 
>> +
>>  void AcpiCpuHotplug_add(ACPIGPE *gpe, AcpiCpuHotplug *g, CPUState *cpu);
>>  
>>  void AcpiCpuHotplug_init(MemoryRegion *parent, Object *owner,
> 
> 
> .
> 





Re: [Qemu-devel] [RFC V2 04/10] x86: add x86_cpu_unrealizefn() for cpu apic remove

2014-09-10 Thread Gu Zheng
Hi Igor,

On 09/09/2014 09:58 PM, Igor Mammedov wrote:

> On Thu, 28 Aug 2014 11:36:36 +0800
> Gu Zheng  wrote:
> 
>> From: Chen Fan 
>>
>> Implement x86_cpu_unrealizefn() for corresponding x86_cpu_realizefn(),
>> which is mostly used to clean the apic related allocation and vmstates
>> at here.
>>
>> Signed-off-by: Chen Fan 
>> Signed-off-by: Gu Zheng 
>> ---
>>  hw/i386/kvm/apic.c  |8 +++
>>  hw/intc/apic.c  |   10 
>>  hw/intc/apic_common.c   |   23 +++-
>>  include/hw/cpu/icc_bus.h|1 +
>>  include/hw/i386/apic_internal.h |1 +
>>  target-i386/cpu-qom.h   |1 +
>>  target-i386/cpu.c   |   45 
>> +++
>>  7 files changed, 88 insertions(+), 1 deletions(-)
>>
>> diff --git a/hw/i386/kvm/apic.c b/hw/i386/kvm/apic.c
>> index e873b50..c95fb8a 100644
>> --- a/hw/i386/kvm/apic.c
>> +++ b/hw/i386/kvm/apic.c
>> @@ -183,11 +183,19 @@ static void kvm_apic_realize(DeviceState *dev, Error 
>> **errp)
>>  }
>>  }
>>  
>> +static void kvm_apic_unrealize(DeviceState *dev, Error **errp)
>> +{
>> +APICCommonState *s = APIC_COMMON(dev);
>> +
>> +object_unparent(OBJECT(&s->io_memory));
>> +}
>> +
> what will disable/destroy in kernel APIC?

As we parked kvm cpu, is this step still seriously needed?

> 
>>  static void kvm_apic_class_init(ObjectClass *klass, void *data)
>>  {
>>  APICCommonClass *k = APIC_COMMON_CLASS(klass);
>>  
>>  k->realize = kvm_apic_realize;
>> +k->unrealize = kvm_apic_unrealize;
>>  k->set_base = kvm_apic_set_base;
>>  k->set_tpr = kvm_apic_set_tpr;
>>  k->get_tpr = kvm_apic_get_tpr;
>> diff --git a/hw/intc/apic.c b/hw/intc/apic.c
>> index 03ff9e9..6d38965 100644
>> --- a/hw/intc/apic.c
>> +++ b/hw/intc/apic.c
>> @@ -885,11 +885,21 @@ static void apic_realize(DeviceState *dev, Error 
>> **errp)
>>  msi_supported = true;
>>  }
>>  
>> +static void apic_unrealize(DeviceState *dev, Error **errp)
>> +{
>> +APICCommonState *s = APIC_COMMON(dev);
>> +
>> +object_unparent(OBJECT(&s->io_memory));
>> +timer_free(s->timer);
>> +local_apics[s->idx] = NULL;
>> +}
>> +
>>  static void apic_class_init(ObjectClass *klass, void *data)
>>  {
>>  APICCommonClass *k = APIC_COMMON_CLASS(klass);
>>  
>>  k->realize = apic_realize;
>> +k->unrealize = apic_unrealize;
>>  k->set_base = apic_set_base;
>>  k->set_tpr = apic_set_tpr;
>>  k->get_tpr = apic_get_tpr;
>> diff --git a/hw/intc/apic_common.c b/hw/intc/apic_common.c
>> index 029f67d..8d17be1 100644
>> --- a/hw/intc/apic_common.c
>> +++ b/hw/intc/apic_common.c
>> @@ -289,12 +289,13 @@ static int apic_load_old(QEMUFile *f, void *opaque, 
>> int version_id)
>>  return 0;
>>  }
>>  
>> +static int apic_no;
>> +
> some apic code still assumes that index in local_apics[] is APIC ID, so
> apic_no and related stuff won't work with arbitrary CPU hotadd (i.e. 
> arbitrary APIC ID)
> to make it work the APICCommonState.idx should be dropped altogether and
> replaced with apic_id.

If so, we absolutely need to change this. 

> 
> I addition intc/apic.c is designed for APIC ID 8-bit max, we probably should 
> add
> some assert there so it wouldn't break silently when APIC ID goes above this
> maximum.

OK.

> 
>>  static void apic_common_realize(DeviceState *dev, Error **errp)
>>  {
>>  APICCommonState *s = APIC_COMMON(dev);
>>  APICCommonClass *info;
>>  static DeviceState *vapic;
>> -static int apic_no;
>>  static bool mmio_registered;
>>  
>>  if (apic_no >= MAX_APICS) {
>> @@ -324,6 +325,25 @@ static void apic_common_realize(DeviceState *dev, Error 
>> **errp)
>>  
>>  }
>>  
>> +static void apic_common_unrealize(DeviceState *dev, Error **errp)
>> +{
>> +APICCommonState *s = APIC_COMMON(dev);
>> +APICCommonClass *info = APIC_COMMON_GET_CLASS(s);
>> +
>> +if (apic_no <= 0) {
>> +error_setg(errp, "%s exit failed.",
>> +   object_get_typename(OBJECT(dev)));
>> +return;
>> +}
>> +apic_no--;
>> +
>> +info->unrealize(dev, errp);
>> +
>> +if (apic_report_tpr_access && info->enable_tpr_report

Re: [Qemu-devel] [RFC V2 10/10] cpus: reclaim allocated vCPU objects

2014-09-11 Thread Gu Zheng
On 09/11/2014 05:35 PM, Bharata B Rao wrote:

> On Thu, Aug 28, 2014 at 9:06 AM, Gu Zheng  wrote:
>> After ACPI get a signal to eject a vCPU, the vCPU must be
>> removed from CPU list,before the vCPU really removed,  then
>> release the all related vCPU objects.
>> But we do not close KVM vcpu fd, just record it into a list, in
>> order to reuse it.
> 
> After I add and delete a CPU, "info cpus" from monitor still lists the
> removed CPU. Is this expected ?

No, neither from QEMU (e.g. monitor) nor guest side, you can not see the
removed cpu, but from the kernel side it is still there, just no one uses it
any more.

Thanks,
Gu

> 
> Regards,
> Bharata.
> .
> 





Re: [Qemu-devel] [RFC V2 10/10] cpus: reclaim allocated vCPU objects

2014-09-11 Thread Gu Zheng
On 09/11/2014 05:35 PM, Bharata B Rao wrote:

> On Thu, Aug 28, 2014 at 9:06 AM, Gu Zheng  wrote:
>> After ACPI get a signal to eject a vCPU, the vCPU must be
>> removed from CPU list,before the vCPU really removed,  then
>> release the all related vCPU objects.
>> But we do not close KVM vcpu fd, just record it into a list, in
>> order to reuse it.
> 
> After I add and delete a CPU, "info cpus" from monitor still lists the
> removed CPU. Is this expected ?

No, you can not see the removed cpu from QEMU (e.g. monitor) or guest side,
but from the kernel side it is still there, just no one uses it any more.

Thanks,
Gu

> 
> Regards,
> Bharata.
> .
> 





Re: [Qemu-devel] [RFC V2 10/10] cpus: reclaim allocated vCPU objects

2014-09-11 Thread Gu Zheng
Hi Bharata,

On 09/11/2014 08:37 PM, Bharata B Rao wrote:

> On Thu, Sep 11, 2014 at 3:23 PM, Gu Zheng  wrote:
>> On 09/11/2014 05:35 PM, Bharata B Rao wrote:
>>
>>> On Thu, Aug 28, 2014 at 9:06 AM, Gu Zheng  wrote:
>>>> After ACPI get a signal to eject a vCPU, the vCPU must be
>>>> removed from CPU list,before the vCPU really removed,  then
>>>> release the all related vCPU objects.
>>>> But we do not close KVM vcpu fd, just record it into a list, in
>>>> order to reuse it.
>>>
>>> After I add and delete a CPU, "info cpus" from monitor still lists the
>>> removed CPU. Is this expected ?
>>
>> No, you can not see the removed cpu from QEMU (e.g. monitor) or guest side,
>> but from the kernel side it is still there, just no one uses it any more.
> 
> I am trying your patches, but still see the removed CPU after deletion.
> 
> (qemu) info cpus
> * CPU #0: pc=0x8100b82c (halted) thread_id=7812
>   CPU #1: pc=0x8100b82c (halted) thread_id=7813
>   CPU #2: pc=0x8100b82c (halted) thread_id=7814
>   CPU #3: pc=0x8100b82c (halted) thread_id=7815
>   CPU #4: pc=0x8100b82c (halted) thread_id=7816
>   CPU #5: pc=0x8100b82c (halted) thread_id=7817
>   CPU #6: pc=0x8100b82c (halted) thread_id=7818
>   CPU #7: pc=0x8100b82c (halted) thread_id=7819
> (qemu) device_add qemu64-x86_64-cpu,id=cpu8
> (qemu) info cpus
> * CPU #0: pc=0x8100b82c (halted) thread_id=7812
>   CPU #1: pc=0x8100b82c (halted) thread_id=7813
>   CPU #2: pc=0x8100b82c (halted) thread_id=7814
>   CPU #3: pc=0x8100b82c (halted) thread_id=7815
>   CPU #4: pc=0x8100b82c (halted) thread_id=7816
>   CPU #5: pc=0x8100b82c (halted) thread_id=7817
>   CPU #6: pc=0x8100b82c (halted) thread_id=7818
>   CPU #7: pc=0x8100b82c (halted) thread_id=7819
>   CPU #8: pc=0x8100b82c (halted) thread_id=8041
> (qemu) device_del cpu8
> (qemu) info cpus
> * CPU #0: pc=0x8100b82c (halted) thread_id=7812
>   CPU #1: pc=0x8100b82c (halted) thread_id=7813
>   CPU #2: pc=0x8100b82c (halted) thread_id=7814
>   CPU #3: pc=0x8100b82c (halted) thread_id=7815
>   CPU #4: pc=0x8100b82c (halted) thread_id=7816
>   CPU #5: pc=0x8100b82c (halted) thread_id=7817
>   CPU #6: pc=0x8100b82c (halted) thread_id=7818
>   CPU #7: pc=0x8100b82c (halted) thread_id=7819
>   CPU #8: pc=0x81031722 (halted) thread_id=8041
> 
> I applied your patchset on commit 69f87f713069f1f70, may be I should
> try with latest QEMU ?

Is guest os enabled acpi cpu hotplug? What's the guest's cpu info?
Please try latest QEMU, and any feedback is welcome.

Thanks,
Gu

> 
> Regards,
> Bharata.
> .
> 





Re: [Qemu-devel] [PATCH 1/5] acpi/cpu: add cpu hotplug callback function to match hotplug_handler API

2014-09-11 Thread Gu Zheng
Hi Igor,
On 09/11/2014 06:12 PM, Igor Mammedov wrote:

> On Thu, 11 Sep 2014 11:04:10 +0800
> Gu Zheng  wrote:
> 
>> Hi Igor,
>> On 09/10/2014 09:28 PM, Igor Mammedov wrote:
>>
>>> On Wed,  3 Sep 2014 17:06:13 +0800
>>> Gu Zheng  wrote:
>>>
>>>>
>>>> Signed-off-by: Gu Zheng 
>>>> ---
>>>>  hw/acpi/cpu_hotplug.c |   17 +
>>>>  include/hw/acpi/cpu_hotplug.h |3 +++
>>>>  2 files changed, 20 insertions(+), 0 deletions(-)
>>>>
>>>> diff --git a/hw/acpi/cpu_hotplug.c b/hw/acpi/cpu_hotplug.c
>>>> index 2ad83a0..92c189b 100644
>>>> --- a/hw/acpi/cpu_hotplug.c
>>>> +++ b/hw/acpi/cpu_hotplug.c
>>>> @@ -36,6 +36,23 @@ static const MemoryRegionOps AcpiCpuHotplug_ops = {
>>>>  },
>>>>  };
>>>>  
>>>> +void acpi_cpu_plug_cb(ACPIREGS *ar, qemu_irq irq,
>>>> +  AcpiCpuHotplug *g, DeviceState *dev)
>>> wrong indentation ^^^
>>>
>>> it wouldn't hurt to add errp argument here ...
>>>
>>>> +{
>>>> +CPUState *cpu = CPU(dev);
>>>> +CPUClass *k = CPU_GET_CLASS(cpu);
>>>> +int64_t cpu_id;
>>>> +
>>>> +ar->gpe.sts[0] |= ACPI_CPU_HOTPLUG_STATUS;
>>>> +cpu_id = k->get_arch_id(cpu);
>>>> +g_assert((cpu_id / 8) < ACPI_GPE_PROC_LEN);
>>> ... and return error from here instead of aborting
>>
>> Got it.
>>
>>>
>>>> +g->sts[cpu_id / 8] |= (1 << (cpu_id % 8));
>>>> +
>>>> +acpi_update_sci(ar, irq);
>>>> +
>>>> +cpu_resume(cpu);
>>> Why are you adding cpu_resume() here?
>>> check cpu_common_realizefn() which already does it.
>>
>> Because hot added callback is called after cpu_common_realizefn(), so I moved
>> cpu_resume(cpu) from cpu_common_realizefn() here to ensure the guest has 
>> already
>> hot added cpu before we resume it.
> cpu.realize() should create a fully working CPU and moving CPU internals to 
> ACPI
> is not correct. CPU hot-add shouyld not depend on whether guest OS supports 
> it or not.
> 
> More over there is no need to resume CPU when guest OS hot-added it,
> cpu.realize() creates secondary CPU in RESET state, so it does nothing and 
> waits
> for INIT/SIPI sequence (i.e. when guest OS decides to online CPU).

Seems I had a misreading on this, thanks for your explanation.

Best regards,
Gu

> 
>>
>>>
>>>> +}
>>>> +
>>>>  void AcpiCpuHotplug_add(ACPIGPE *gpe, AcpiCpuHotplug *g, CPUState *cpu)
>>>>  {
>>>>  CPUClass *k = CPU_GET_CLASS(cpu);
>>>> diff --git a/include/hw/acpi/cpu_hotplug.h b/include/hw/acpi/cpu_hotplug.h
>>>> index 9e5d30c..d025731 100644
>>>> --- a/include/hw/acpi/cpu_hotplug.h
>>>> +++ b/include/hw/acpi/cpu_hotplug.h
>>>> @@ -20,6 +20,9 @@ typedef struct AcpiCpuHotplug {
>>>>  uint8_t sts[ACPI_GPE_PROC_LEN];
>>>>  } AcpiCpuHotplug;
>>>>  
>>>> +void acpi_cpu_plug_cb(ACPIREGS *ar, qemu_irq irq,
>>>> +  AcpiCpuHotplug *g, DeviceState *dev);
>>> wrong indentation ^^^
>>
>> OK, will fix this too.
>>
>> Thanks,
>> Gu
>>
>>>
>>>> +
>>>>  void AcpiCpuHotplug_add(ACPIGPE *gpe, AcpiCpuHotplug *g, CPUState *cpu);
>>>>  
>>>>  void AcpiCpuHotplug_init(MemoryRegion *parent, Object *owner,
>>>
>>>
>>> .
>>>
>>
>>
> 
> .
> 





Re: [Qemu-devel] [PATCH 4/5] pc: add cpu hotplug handler to PC_MACHINE

2014-09-11 Thread Gu Zheng
Hi Igor,
On 09/10/2014 09:55 PM, Igor Mammedov wrote:

> On Wed,  3 Sep 2014 17:06:16 +0800
> Gu Zheng  wrote:
> 
>> Add cpu hotplug handler to PC_MACHINE, which will perform the acpi
>> cpu hotplug callback via hotplug_handler API.
>>
>> Signed-off-by: Gu Zheng 
>> ---
>>  hw/i386/pc.c |   26 +-
>>  qom/cpu.c|1 -
>>  2 files changed, 25 insertions(+), 2 deletions(-)
>>
>> diff --git a/hw/i386/pc.c b/hw/i386/pc.c
>> index 8fa8d2f..c2956f9 100644
>> --- a/hw/i386/pc.c
>> +++ b/hw/i386/pc.c
>> @@ -1607,11 +1607,34 @@ out:
>>  error_propagate(errp, local_err);
>>  }
>>  
>> +static void pc_cpu_plug(HotplugHandler *hotplug_dev,
>> + DeviceState *dev, Error **errp)
>> +{
>> +HotplugHandlerClass *hhc;
>> +Error *local_err = NULL;
>> +PCMachineState *pcms = PC_MACHINE(hotplug_dev);
>> +
>> +if (dev->hotplugged) {
> for startup CPUs we set gpe_cpu status bits in AcpiCpuHotplug_init()
> and for hotpluged in AcpiCpuHotplug_add() which is duplicating
> essentially the same code.
> 
> Could you drop above check and make AcpiCpuHotplug_init() take care
> about startup CPUs as well, keeping bit setting in one place.

Yeah, with the above change, code will be more neat, but I think it is not
a serious problem.:)
And pcms->acpi_dev is set when PC hardware initialisation (e.g. pc_init1),
for start up cpus, the plug handler is not valid, so the check is needed
here to avoid trigger error by start cpu.

> 
>> +if (!pcms->acpi_dev) {
>> +error_setg(&local_err,
>> +   "cpu hotplug is not enabled: missing acpi device");
>> +goto out;
>> +}
>> +
>> +hhc = HOTPLUG_HANDLER_GET_CLASS(pcms->acpi_dev);
>> +hhc->plug(HOTPLUG_HANDLER(pcms->acpi_dev), dev, &local_err);
>> +out:
>> +error_propagate(errp, local_err);
>> +}
>> +}
>> +
>>  static void pc_machine_device_plug_cb(HotplugHandler *hotplug_dev,
>>DeviceState *dev, Error **errp)
>>  {
>>  if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
>>  pc_dimm_plug(hotplug_dev, dev, errp);
>> +} else if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) {
>> +pc_cpu_plug(hotplug_dev, dev, errp);
>>  }
>>  }
>>  
>> @@ -1620,7 +1643,8 @@ static HotplugHandler 
>> *pc_get_hotpug_handler(MachineState *machine,
>>  {
>>  PCMachineClass *pcmc = PC_MACHINE_GET_CLASS(machine);
>>  
>> -if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
>> +if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)
>> +|| object_dynamic_cast(OBJECT(dev), TYPE_CPU)) {
>>  return HOTPLUG_HANDLER(machine);
>>  }
>>  
>> diff --git a/qom/cpu.c b/qom/cpu.c
>> index b32dd0a..af8e83f 100644
>> --- a/qom/cpu.c
>> +++ b/qom/cpu.c
>> @@ -304,7 +304,6 @@ static void cpu_common_realizefn(DeviceState *dev, Error 
>> **errp)
>>  if (dev->hotplugged) {
>>  cpu_synchronize_post_init(cpu);
>>  notifier_list_notify(&cpu_added_notifiers, dev);
>> -cpu_resume(cpu);
>>  }
>>  }
>>  
> 
> I don't see what sets PCMachine as hotplug_handler for CPU,
> maybe series is missing a patch?

Previous memory hotplug has built the frame work, here just adding the case
to handle CPU.

 static void pc_machine_device_plug_cb(HotplugHandler *hotplug_dev,
   DeviceState *dev, Error **errp)
 {
 if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
 pc_dimm_plug(hotplug_dev, dev, errp);
+} else if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) {
+pc_cpu_plug(hotplug_dev, dev, errp);
 }

Thanks,
Gu

> 
> .
> 





[Qemu-devel] [PATCH V2 0/7] cpu/acpi: convert cpu hot plug to hotplug_handler API

2014-09-12 Thread Gu Zheng
Previously we use cpu_added_notifiers to register cpu hotplug notifier callback
which is not able to pass/handle errors, so we switch it to unified hotplug
handler API which allows to pass errors and would allow to cancel device_add
in case of error.
Thanks very much for Igor's review and suggestion.

v2:
 -Add 3 new patches(5/7,6/7,7/7), delete original patch 5/5.
  1/5-->1/7
  2/5-->2/7
  3/5-->3/7
  4/5-->4/7
 Patch 1/7:
 -add errp argument to catch error.
 -return error instead of aborting if cpu id is invalid.
 -make acpi_cpu_plug_cb as a wrapper around AcpiCpuHotplug_add.
 Patch 3/7:
 -remove unused AcpiCpuHotplug_add here directly.
 Patch 5/7:
 -switch the last user of cpu hotplug notifier to hotplug handler API, and
  remove the unused cpu hotplug notify.
 Patch 6/7:
 -split the function rename (just cleanup) into single patch.
 Patch 7/7:
 -introduce help function acpi_set_local_sts to keep the bit setting in
  one place.

Gu Zheng (7):
  acpi/cpu: add cpu hotplug callback function to match hotplug_handler
API
  acpi:ich9: convert cpu hotplug handle to hotplug_handler API
  acpi:piix4: convert cpu hotplug handle to hotplug_handler API
  pc: add cpu hotplug handler to PC_MACHINE
  pc: Update rtc_cmos in pc_cpu_plug
  cpu-hotplug: rename function for better readability
  acpi/cpu-hotplug: introduce help function to keep bit setting in one
place

 hw/acpi/cpu_hotplug.c |   35 
 hw/acpi/ich9.c|   18 --
 hw/acpi/piix4.c   |   18 +++---
 hw/i386/pc.c  |   51 +
 include/hw/acpi/cpu_hotplug.h |7 +++--
 include/hw/acpi/ich9.h|1 -
 include/sysemu/sysemu.h   |3 --
 qom/cpu.c |   10 
 8 files changed, 69 insertions(+), 74 deletions(-)

-- 
1.7.7




[Qemu-devel] [PATCH V2 1/7] acpi/cpu: add cpu hotplug callback function to match hotplug_handler API

2014-09-12 Thread Gu Zheng
---
v2:
 -add errp argument to catch error.
 -return error instead of aborting if cpu id is invalid.
 -make acpi_cpu_plug_cb as a wrapper around AcpiCpuHotplug_add.
---

Signed-off-by: Gu Zheng 
---
 hw/acpi/cpu_hotplug.c |   17 +
 include/hw/acpi/cpu_hotplug.h |3 +++
 2 files changed, 20 insertions(+), 0 deletions(-)

diff --git a/hw/acpi/cpu_hotplug.c b/hw/acpi/cpu_hotplug.c
index 2ad83a0..dfd6de5 100644
--- a/hw/acpi/cpu_hotplug.c
+++ b/hw/acpi/cpu_hotplug.c
@@ -36,6 +36,23 @@ static const MemoryRegionOps AcpiCpuHotplug_ops = {
 },
 };
 
+void acpi_cpu_plug_cb(ACPIREGS *ar, qemu_irq irq,
+  AcpiCpuHotplug *g, CPUState *cpu, Error **errp)
+{
+CPUClass *k = CPU_GET_CLASS(cpu);
+int64_t cpu_id;
+
+cpu_id = k->get_arch_id(cpu);
+if ((cpu_id / 8) >= ACPI_GPE_PROC_LEN) {
+error_setg(errp, "acpi: invalid cpu id: %" PRIi64, cpu_id);
+return;
+}
+
+AcpiCpuHotplug_add(&ar->gpe, g, cpu);
+
+acpi_update_sci(ar, irq);
+}
+
 void AcpiCpuHotplug_add(ACPIGPE *gpe, AcpiCpuHotplug *g, CPUState *cpu)
 {
 CPUClass *k = CPU_GET_CLASS(cpu);
diff --git a/include/hw/acpi/cpu_hotplug.h b/include/hw/acpi/cpu_hotplug.h
index 9e5d30c..166edb0 100644
--- a/include/hw/acpi/cpu_hotplug.h
+++ b/include/hw/acpi/cpu_hotplug.h
@@ -20,6 +20,9 @@ typedef struct AcpiCpuHotplug {
 uint8_t sts[ACPI_GPE_PROC_LEN];
 } AcpiCpuHotplug;
 
+void acpi_cpu_plug_cb(ACPIREGS *ar, qemu_irq irq,
+  AcpiCpuHotplug *g, CPUState *dev, Error **errp);
+
 void AcpiCpuHotplug_add(ACPIGPE *gpe, AcpiCpuHotplug *g, CPUState *cpu);
 
 void AcpiCpuHotplug_init(MemoryRegion *parent, Object *owner,
-- 
1.7.7




[Qemu-devel] [PATCH V2 2/7] acpi:ich9: convert cpu hotplug handle to hotplug_handler API

2014-09-12 Thread Gu Zheng
Convert notifier based hotplug handle to hotplug_handler API.

Signed-off-by: Gu Zheng 
---
 hw/acpi/ich9.c |   14 +++---
 include/hw/acpi/ich9.h |1 -
 2 files changed, 3 insertions(+), 12 deletions(-)

diff --git a/hw/acpi/ich9.c b/hw/acpi/ich9.c
index 7b14bbb..c53d4ab 100644
--- a/hw/acpi/ich9.c
+++ b/hw/acpi/ich9.c
@@ -209,15 +209,6 @@ static void pm_powerdown_req(Notifier *n, void *opaque)
 acpi_pm1_evt_power_down(&pm->acpi_regs);
 }
 
-static void ich9_cpu_added_req(Notifier *n, void *opaque)
-{
-ICH9LPCPMRegs *pm = container_of(n, ICH9LPCPMRegs, cpu_added_notifier);
-
-assert(pm != NULL);
-AcpiCpuHotplug_add(&pm->acpi_regs.gpe, &pm->gpe_cpu, CPU(opaque));
-acpi_update_sci(&pm->acpi_regs, pm->irq);
-}
-
 void ich9_pm_init(PCIDevice *lpc_pci, ICH9LPCPMRegs *pm,
   qemu_irq sci_irq)
 {
@@ -246,8 +237,6 @@ void ich9_pm_init(PCIDevice *lpc_pci, ICH9LPCPMRegs *pm,
 
 AcpiCpuHotplug_init(pci_address_space_io(lpc_pci), OBJECT(lpc_pci),
 &pm->gpe_cpu, ICH9_CPU_HOTPLUG_IO_BASE);
-pm->cpu_added_notifier.notify = ich9_cpu_added_req;
-qemu_register_cpu_added_notifier(&pm->cpu_added_notifier);
 
 if (pm->acpi_memory_hotplug.is_enabled) {
 acpi_memory_hotplug_init(pci_address_space_io(lpc_pci), 
OBJECT(lpc_pci),
@@ -304,6 +293,9 @@ void ich9_pm_device_plug_cb(ICH9LPCPMRegs *pm, DeviceState 
*dev, Error **errp)
 object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
 acpi_memory_plug_cb(&pm->acpi_regs, pm->irq, &pm->acpi_memory_hotplug,
 dev, errp);
+} else if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) {
+acpi_cpu_plug_cb(&pm->acpi_regs, pm->irq, &pm->gpe_cpu,
+ CPU(dev), errp);
 } else {
 error_setg(errp, "acpi: device plug request for not supported device"
" type: %s", object_get_typename(OBJECT(dev)));
diff --git a/include/hw/acpi/ich9.h b/include/hw/acpi/ich9.h
index 7e42448..fe975e6 100644
--- a/include/hw/acpi/ich9.h
+++ b/include/hw/acpi/ich9.h
@@ -47,7 +47,6 @@ typedef struct ICH9LPCPMRegs {
 Notifier powerdown_notifier;
 
 AcpiCpuHotplug gpe_cpu;
-Notifier cpu_added_notifier;
 
 MemHotplugState acpi_memory_hotplug;
 } ICH9LPCPMRegs;
-- 
1.7.7




[Qemu-devel] [PATCH V2 3/7] acpi:piix4: convert cpu hotplug handle to hotplug_handler API

2014-09-12 Thread Gu Zheng
Convert notifier based hotplug handle to hotplug_handler API,
and remove the unused AcpiCpuHotplug_add().

Signed-off-by: Gu Zheng 
---
 hw/acpi/cpu_hotplug.c |   14 ++
 hw/acpi/piix4.c   |   14 ++
 include/hw/acpi/cpu_hotplug.h |2 --
 3 files changed, 4 insertions(+), 26 deletions(-)

diff --git a/hw/acpi/cpu_hotplug.c b/hw/acpi/cpu_hotplug.c
index dfd6de5..0b9fa55 100644
--- a/hw/acpi/cpu_hotplug.c
+++ b/hw/acpi/cpu_hotplug.c
@@ -48,22 +48,12 @@ void acpi_cpu_plug_cb(ACPIREGS *ar, qemu_irq irq,
 return;
 }
 
-AcpiCpuHotplug_add(&ar->gpe, g, cpu);
+ar->gpe.sts[0] |= ACPI_CPU_HOTPLUG_STATUS;
+g->sts[cpu_id / 8] |= (1 << (cpu_id % 8));
 
 acpi_update_sci(ar, irq);
 }
 
-void AcpiCpuHotplug_add(ACPIGPE *gpe, AcpiCpuHotplug *g, CPUState *cpu)
-{
-CPUClass *k = CPU_GET_CLASS(cpu);
-int64_t cpu_id;
-
-*gpe->sts = *gpe->sts | ACPI_CPU_HOTPLUG_STATUS;
-cpu_id = k->get_arch_id(CPU(cpu));
-g_assert((cpu_id / 8) < ACPI_GPE_PROC_LEN);
-g->sts[cpu_id / 8] |= (1 << (cpu_id % 8));
-}
-
 void AcpiCpuHotplug_init(MemoryRegion *parent, Object *owner,
  AcpiCpuHotplug *gpe_cpu, uint16_t base)
 {
diff --git a/hw/acpi/piix4.c b/hw/acpi/piix4.c
index b72b34e..b046cd3 100644
--- a/hw/acpi/piix4.c
+++ b/hw/acpi/piix4.c
@@ -83,7 +83,6 @@ typedef struct PIIX4PMState {
 uint8_t s4_val;
 
 AcpiCpuHotplug gpe_cpu;
-Notifier cpu_added_notifier;
 
 MemHotplugState acpi_memory_hotplug;
 } PIIX4PMState;
@@ -348,6 +347,8 @@ static void piix4_device_plug_cb(HotplugHandler 
*hotplug_dev,
 } else if (object_dynamic_cast(OBJECT(dev), TYPE_PCI_DEVICE)) {
 acpi_pcihp_device_plug_cb(&s->ar, s->irq, &s->acpi_pci_hotplug, dev,
   errp);
+} else if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) {
+acpi_cpu_plug_cb(&s->ar, s->irq, &s->gpe_cpu, CPU(dev), errp);
 } else {
 error_setg(errp, "acpi: device plug request for not supported device"
" type: %s", object_get_typename(OBJECT(dev)));
@@ -544,15 +545,6 @@ static const MemoryRegionOps piix4_gpe_ops = {
 .endianness = DEVICE_LITTLE_ENDIAN,
 };
 
-static void piix4_cpu_added_req(Notifier *n, void *opaque)
-{
-PIIX4PMState *s = container_of(n, PIIX4PMState, cpu_added_notifier);
-
-assert(s != NULL);
-AcpiCpuHotplug_add(&s->ar.gpe, &s->gpe_cpu, CPU(opaque));
-acpi_update_sci(&s->ar, s->irq);
-}
-
 static void piix4_acpi_system_hot_add_init(MemoryRegion *parent,
PCIBus *bus, PIIX4PMState *s)
 {
@@ -565,8 +557,6 @@ static void piix4_acpi_system_hot_add_init(MemoryRegion 
*parent,
 
 AcpiCpuHotplug_init(parent, OBJECT(s), &s->gpe_cpu,
 PIIX4_CPU_HOTPLUG_IO_BASE);
-s->cpu_added_notifier.notify = piix4_cpu_added_req;
-qemu_register_cpu_added_notifier(&s->cpu_added_notifier);
 
 if (s->acpi_memory_hotplug.is_enabled) {
 acpi_memory_hotplug_init(parent, OBJECT(s), &s->acpi_memory_hotplug);
diff --git a/include/hw/acpi/cpu_hotplug.h b/include/hw/acpi/cpu_hotplug.h
index 166edb0..8188630 100644
--- a/include/hw/acpi/cpu_hotplug.h
+++ b/include/hw/acpi/cpu_hotplug.h
@@ -23,8 +23,6 @@ typedef struct AcpiCpuHotplug {
 void acpi_cpu_plug_cb(ACPIREGS *ar, qemu_irq irq,
   AcpiCpuHotplug *g, CPUState *dev, Error **errp);
 
-void AcpiCpuHotplug_add(ACPIGPE *gpe, AcpiCpuHotplug *g, CPUState *cpu);
-
 void AcpiCpuHotplug_init(MemoryRegion *parent, Object *owner,
  AcpiCpuHotplug *gpe_cpu, uint16_t base);
 #endif
-- 
1.7.7




[Qemu-devel] [PATCH V2 4/7] pc: add cpu hotplug handler to PC_MACHINE

2014-09-12 Thread Gu Zheng
Add cpu hotplug handler to PC_MACHINE, which will perform the acpi
cpu hotplug callback via hotplug_handler API.

Signed-off-by: Gu Zheng 
---
 hw/i386/pc.c |   26 +-
 1 files changed, 25 insertions(+), 1 deletions(-)

diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index b6c9b61..28fc66b 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -1613,11 +1613,34 @@ out:
 error_propagate(errp, local_err);
 }
 
+static void pc_cpu_plug(HotplugHandler *hotplug_dev,
+DeviceState *dev, Error **errp)
+{
+HotplugHandlerClass *hhc;
+Error *local_err = NULL;
+PCMachineState *pcms = PC_MACHINE(hotplug_dev);
+
+if (dev->hotplugged) {
+if (!pcms->acpi_dev) {
+error_setg(&local_err,
+   "cpu hotplug is not enabled: missing acpi device");
+goto out;
+}
+
+hhc = HOTPLUG_HANDLER_GET_CLASS(pcms->acpi_dev);
+hhc->plug(HOTPLUG_HANDLER(pcms->acpi_dev), dev, &local_err);
+out:
+error_propagate(errp, local_err);
+}
+}
+
 static void pc_machine_device_plug_cb(HotplugHandler *hotplug_dev,
   DeviceState *dev, Error **errp)
 {
 if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
 pc_dimm_plug(hotplug_dev, dev, errp);
+} else if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) {
+pc_cpu_plug(hotplug_dev, dev, errp);
 }
 }
 
@@ -1626,7 +1649,8 @@ static HotplugHandler *pc_get_hotpug_handler(MachineState 
*machine,
 {
 PCMachineClass *pcmc = PC_MACHINE_GET_CLASS(machine);
 
-if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
+if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM) ||
+object_dynamic_cast(OBJECT(dev), TYPE_CPU)) {
 return HOTPLUG_HANDLER(machine);
 }
 
-- 
1.7.7




[Qemu-devel] [PATCH V2 5/7] pc: Update rtc_cmos in pc_cpu_plug

2014-09-12 Thread Gu Zheng
Update rtc_cmos in pc_cpu_plug directly instead of the notifier, with
this change, there will no user of CPU hot-plug notifier any more, so
remove it.

Signed-off-by: Gu Zheng 
---
 hw/i386/pc.c|   25 ++---
 include/sysemu/sysemu.h |3 ---
 qom/cpu.c   |   10 --
 3 files changed, 6 insertions(+), 32 deletions(-)

diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 28fc66b..337d662 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -353,20 +353,7 @@ static void pc_cmos_init_late(void *opaque)
 qemu_unregister_reset(pc_cmos_init_late, opaque);
 }
 
-typedef struct RTCCPUHotplugArg {
-Notifier cpu_added_notifier;
-ISADevice *rtc_state;
-} RTCCPUHotplugArg;
-
-static void rtc_notify_cpu_added(Notifier *notifier, void *data)
-{
-RTCCPUHotplugArg *arg = container_of(notifier, RTCCPUHotplugArg,
- cpu_added_notifier);
-ISADevice *s = arg->rtc_state;
-
-/* increment the number of CPUs */
-rtc_set_memory(s, 0x5f, rtc_get_memory(s, 0x5f) + 1);
-}
+static ISADevice *rtc_state;
 
 void pc_cmos_init(ram_addr_t ram_size, ram_addr_t above_4g_mem_size,
   const char *boot_device,
@@ -376,7 +363,6 @@ void pc_cmos_init(ram_addr_t ram_size, ram_addr_t 
above_4g_mem_size,
 int val, nb, i;
 FDriveType fd_type[2] = { FDRIVE_DRV_NONE, FDRIVE_DRV_NONE };
 static pc_cmos_init_late_arg arg;
-static RTCCPUHotplugArg cpu_hotplug_cb;
 
 /* various important CMOS locations needed by PC/Bochs bios */
 
@@ -415,10 +401,8 @@ void pc_cmos_init(ram_addr_t ram_size, ram_addr_t 
above_4g_mem_size,
 
 /* set the number of CPU */
 rtc_set_memory(s, 0x5f, smp_cpus - 1);
-/* init CPU hotplug notifier */
-cpu_hotplug_cb.rtc_state = s;
-cpu_hotplug_cb.cpu_added_notifier.notify = rtc_notify_cpu_added;
-qemu_register_cpu_added_notifier(&cpu_hotplug_cb.cpu_added_notifier);
+
+rtc_state = s;
 
 if (set_boot_dev(s, boot_device)) {
 exit(1);
@@ -1629,6 +1613,9 @@ static void pc_cpu_plug(HotplugHandler *hotplug_dev,
 
 hhc = HOTPLUG_HANDLER_GET_CLASS(pcms->acpi_dev);
 hhc->plug(HOTPLUG_HANDLER(pcms->acpi_dev), dev, &local_err);
+
+/* increment the number of CPUs */
+rtc_set_memory(rtc_state, 0x5f, rtc_get_memory(rtc_state, 0x5f) + 1);
 out:
 error_propagate(errp, local_err);
 }
diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h
index d8539fd..acfe494 100644
--- a/include/sysemu/sysemu.h
+++ b/include/sysemu/sysemu.h
@@ -183,9 +183,6 @@ void do_pci_device_hot_remove(Monitor *mon, const QDict 
*qdict);
 /* generic hotplug */
 void drive_hot_add(Monitor *mon, const QDict *qdict);
 
-/* CPU hotplug */
-void qemu_register_cpu_added_notifier(Notifier *notifier);
-
 /* pcie aer error injection */
 void pcie_aer_inject_error_print(Monitor *mon, const QObject *data);
 int do_pcie_aer_inject_error(Monitor *mon,
diff --git a/qom/cpu.c b/qom/cpu.c
index b32dd0a..19c5de5 100644
--- a/qom/cpu.c
+++ b/qom/cpu.c
@@ -107,15 +107,6 @@ static void cpu_common_get_memory_mapping(CPUState *cpu,
 error_setg(errp, "Obtaining memory mappings is unsupported on this CPU.");
 }
 
-/* CPU hot-plug notifiers */
-static NotifierList cpu_added_notifiers =
-NOTIFIER_LIST_INITIALIZER(cpu_add_notifiers);
-
-void qemu_register_cpu_added_notifier(Notifier *notifier)
-{
-notifier_list_add(&cpu_added_notifiers, notifier);
-}
-
 void cpu_reset_interrupt(CPUState *cpu, int mask)
 {
 cpu->interrupt_request &= ~mask;
@@ -303,7 +294,6 @@ static void cpu_common_realizefn(DeviceState *dev, Error 
**errp)
 
 if (dev->hotplugged) {
 cpu_synchronize_post_init(cpu);
-notifier_list_notify(&cpu_added_notifiers, dev);
 cpu_resume(cpu);
 }
 }
-- 
1.7.7




[Qemu-devel] [PATCH V2 6/7] cpu-hotplug: rename function for better readability

2014-09-12 Thread Gu Zheng
Rename:
AcpiCpuHotplug_init --> acpi_cpu_hotplug_init
AcpiCpuHotplug_ops --> acpi_cpu_hotplug_ops
for better readability, just cleanup.

Signed-off-by: Gu Zheng 
---
 hw/acpi/cpu_hotplug.c |4 ++--
 hw/acpi/ich9.c|4 ++--
 hw/acpi/piix4.c   |4 ++--
 include/hw/acpi/cpu_hotplug.h |4 ++--
 4 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/hw/acpi/cpu_hotplug.c b/hw/acpi/cpu_hotplug.c
index 0b9fa55..7629686 100644
--- a/hw/acpi/cpu_hotplug.c
+++ b/hw/acpi/cpu_hotplug.c
@@ -54,8 +54,8 @@ void acpi_cpu_plug_cb(ACPIREGS *ar, qemu_irq irq,
 acpi_update_sci(ar, irq);
 }
 
-void AcpiCpuHotplug_init(MemoryRegion *parent, Object *owner,
- AcpiCpuHotplug *gpe_cpu, uint16_t base)
+void acpi_cpu_hotplug_init(MemoryRegion *parent, Object *owner,
+   AcpiCpuHotplug *gpe_cpu, uint16_t base)
 {
 CPUState *cpu;
 
diff --git a/hw/acpi/ich9.c b/hw/acpi/ich9.c
index c53d4ab..42cf8fa 100644
--- a/hw/acpi/ich9.c
+++ b/hw/acpi/ich9.c
@@ -235,8 +235,8 @@ void ich9_pm_init(PCIDevice *lpc_pci, ICH9LPCPMRegs *pm,
 pm->powerdown_notifier.notify = pm_powerdown_req;
 qemu_register_powerdown_notifier(&pm->powerdown_notifier);
 
-AcpiCpuHotplug_init(pci_address_space_io(lpc_pci), OBJECT(lpc_pci),
-&pm->gpe_cpu, ICH9_CPU_HOTPLUG_IO_BASE);
+acpi_cpu_hotplug_init(pci_address_space_io(lpc_pci), OBJECT(lpc_pci),
+  &pm->gpe_cpu, ICH9_CPU_HOTPLUG_IO_BASE);
 
 if (pm->acpi_memory_hotplug.is_enabled) {
 acpi_memory_hotplug_init(pci_address_space_io(lpc_pci), 
OBJECT(lpc_pci),
diff --git a/hw/acpi/piix4.c b/hw/acpi/piix4.c
index b046cd3..205ba66 100644
--- a/hw/acpi/piix4.c
+++ b/hw/acpi/piix4.c
@@ -555,8 +555,8 @@ static void piix4_acpi_system_hot_add_init(MemoryRegion 
*parent,
 acpi_pcihp_init(&s->acpi_pci_hotplug, bus, parent,
 s->use_acpi_pci_hotplug);
 
-AcpiCpuHotplug_init(parent, OBJECT(s), &s->gpe_cpu,
-PIIX4_CPU_HOTPLUG_IO_BASE);
+acpi_cpu_hotplug_init(parent, OBJECT(s), &s->gpe_cpu,
+  PIIX4_CPU_HOTPLUG_IO_BASE);
 
 if (s->acpi_memory_hotplug.is_enabled) {
 acpi_memory_hotplug_init(parent, OBJECT(s), &s->acpi_memory_hotplug);
diff --git a/include/hw/acpi/cpu_hotplug.h b/include/hw/acpi/cpu_hotplug.h
index 8188630..d015bef 100644
--- a/include/hw/acpi/cpu_hotplug.h
+++ b/include/hw/acpi/cpu_hotplug.h
@@ -23,6 +23,6 @@ typedef struct AcpiCpuHotplug {
 void acpi_cpu_plug_cb(ACPIREGS *ar, qemu_irq irq,
   AcpiCpuHotplug *g, CPUState *dev, Error **errp);
 
-void AcpiCpuHotplug_init(MemoryRegion *parent, Object *owner,
- AcpiCpuHotplug *gpe_cpu, uint16_t base);
+void acpi_cpu_hotplug_init(MemoryRegion *parent, Object *owner,
+   AcpiCpuHotplug *gpe_cpu, uint16_t base);
 #endif
-- 
1.7.7




[Qemu-devel] [PATCH V2 7/7] acpi/cpu-hotplug: introduce help function to keep bit setting in one place

2014-09-12 Thread Gu Zheng
Introduce help function acpi_set_local_sts() to simplify acpi_cpu_plug_cb
and acpi_cpu_hotplug_init, so that we can keep bit setting in one place.

Signed-off-by: Gu Zheng 
---
 hw/acpi/cpu_hotplug.c |   22 +++---
 1 files changed, 15 insertions(+), 7 deletions(-)

diff --git a/hw/acpi/cpu_hotplug.c b/hw/acpi/cpu_hotplug.c
index 7629686..5d62218 100644
--- a/hw/acpi/cpu_hotplug.c
+++ b/hw/acpi/cpu_hotplug.c
@@ -36,8 +36,8 @@ static const MemoryRegionOps AcpiCpuHotplug_ops = {
 },
 };
 
-void acpi_cpu_plug_cb(ACPIREGS *ar, qemu_irq irq,
-  AcpiCpuHotplug *g, CPUState *cpu, Error **errp)
+static void acpi_set_local_sts(AcpiCpuHotplug *g, CPUState *cpu,
+  Error **errp)
 {
 CPUClass *k = CPU_GET_CLASS(cpu);
 int64_t cpu_id;
@@ -48,9 +48,18 @@ void acpi_cpu_plug_cb(ACPIREGS *ar, qemu_irq irq,
 return;
 }
 
-ar->gpe.sts[0] |= ACPI_CPU_HOTPLUG_STATUS;
 g->sts[cpu_id / 8] |= (1 << (cpu_id % 8));
+}
 
+void acpi_cpu_plug_cb(ACPIREGS *ar, qemu_irq irq,
+  AcpiCpuHotplug *g, CPUState *cpu, Error **errp)
+{
+acpi_set_local_sts(g, cpu, errp);
+if (*errp != NULL) {
+return;
+}
+
+ar->gpe.sts[0] |= ACPI_CPU_HOTPLUG_STATUS;
 acpi_update_sci(ar, irq);
 }
 
@@ -60,11 +69,10 @@ void acpi_cpu_hotplug_init(MemoryRegion *parent, Object 
*owner,
 CPUState *cpu;
 
 CPU_FOREACH(cpu) {
-CPUClass *cc = CPU_GET_CLASS(cpu);
-int64_t id = cc->get_arch_id(cpu);
+Error *local_err = NULL;
 
-g_assert((id / 8) < ACPI_GPE_PROC_LEN);
-gpe_cpu->sts[id / 8] |= (1 << (id % 8));
+acpi_set_local_sts(gpe_cpu, cpu, &local_err);
+g_assert(local_err == NULL);
 }
 memory_region_init_io(&gpe_cpu->io, owner, &AcpiCpuHotplug_ops,
   gpe_cpu, "acpi-cpu-hotplug", ACPI_GPE_PROC_LEN);
-- 
1.7.7




Re: [Qemu-devel] [RFC V2 10/10] cpus: reclaim allocated vCPU objects

2014-09-12 Thread Gu Zheng
Hi Bharata,
On 09/12/2014 04:09 PM, Bharata B Rao wrote:

> On Fri, Sep 12, 2014 at 6:54 AM, Gu Zheng  wrote:
>> Is guest os enabled acpi cpu hotplug? What's the guest's cpu info?
>> Please try latest QEMU, and any feedback is welcome.
>>
> 
> Tried with latest QEMU git + your patchset and Fedora 20 guest, but
> QEMU monitor still shows the removed CPU.
> 
> Guest kernel messages during hotplug:
> 
> [root@localhost cpu]# echo 1 > cpu8/online
> [   72.936069] smpboot: Booting Node 0 Processor 8 APIC 0x8
> [0.003000] kvm-clock: cpu 8, msr 0:7ffc9201, secondary cpu clock
> [   72.950003] TSC synchronization [CPU#0 -> CPU#8]:
> [   72.950003] Measured 199886723309 cycles TSC warp between CPUs,
> turning off TSC clock.
> [   72.950003] tsc: Marking TSC unstable due to check_tsc_sync_source failed
> [   72.972976] KVM setup async PF for cpu 8
> [   72.973648] kvm-stealtime: cpu 8, msr 7d30df00
> [   72.974415] Will online and init hotplugged CPU: 8
> [   72.975307] microcode: CPU8 sig=0x663, pf=0x1, revision=0x1
> 
> Guest kernel messages during hotunplug:
> 
> [root@localhost cpu]# [   95.482172] Unregister pv shared memory for cpu 8
> [   95.487169] smpboot: CPU 8 is now offline
> [   95.488667] ACPI: Device does not support D3cold
> 
> 
> Guest cpuinfo (showing for the last CPU only after adding and removing CPU 8)
> 
> processor: 7
> vendor_id: GenuineIntel
> cpu family: 6
> model: 6
> model name: QEMU Virtual CPU version 2.1.50
> stepping: 3
> microcode: 0x1
> cpu MHz: 2899.998
> cache size: 4096 KB
> fpu: yes
> fpu_exception: yes
> cpuid level: 4
> wp: yes
> flags: fpu de pse tsc msr pae mce cx8 apic sep mtrr pge mca
> cmov pse36 clflush mmx fxsr sse sse2 syscall nx lm rep_good nopl pni
> cx16 x2apic popcnt hypervisor lahf_lm
> bogomips: 5799.99
> clflush size: 64
> cache_alignment: 64
> address sizes: 40 bits physical, 48 bits virtual
> power management:

Guest ejected CPU 8 successfully.
I confirmed it with the same environment as yours, it works well.
Could you please offer your QEMU config and the guest start cmd?
It may help me to investigate the issue.

Thanks,
Gu

> 
> [root@localhost boot]# grep -ir hot config-3.11.10-301.fc20.x86_64
> CONFIG_TICK_ONESHOT=y
> # CONFIG_MEMORY_HOTPLUG is not set
> CONFIG_HOTPLUG_CPU=y
> # CONFIG_BOOTPARAM_HOTPLUG_CPU0 is not set
> # CONFIG_DEBUG_HOTPLUG_CPU0 is not set
> CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
> CONFIG_ACPI_HOTPLUG_CPU=y
> CONFIG_HOTPLUG_PCI_PCIE=y
> CONFIG_HOTPLUG_PCI=y
> CONFIG_HOTPLUG_PCI_ACPI=y
> CONFIG_HOTPLUG_PCI_ACPI_IBM=m
> # CONFIG_HOTPLUG_PCI_CPCI is not set
> CONFIG_HOTPLUG_PCI_SHPC=m
> .
> 





Re: [Qemu-devel] [PATCH 4/5] pc: add cpu hotplug handler to PC_MACHINE

2014-09-14 Thread Gu Zheng
Hi Igor,

On 09/12/2014 10:28 PM, Igor Mammedov wrote:

> On Fri, 12 Sep 2014 11:02:09 +0800
> Gu Zheng  wrote:
> 
>> Hi Igor,
>> On 09/10/2014 09:55 PM, Igor Mammedov wrote:
>>
>>> On Wed,  3 Sep 2014 17:06:16 +0800
>>> Gu Zheng  wrote:
>>>
>>>> Add cpu hotplug handler to PC_MACHINE, which will perform the acpi
>>>> cpu hotplug callback via hotplug_handler API.
>>>>
>>>> Signed-off-by: Gu Zheng 
>>>> ---
>>>>  hw/i386/pc.c |   26 +-
>>>>  qom/cpu.c|1 -
>>>>  2 files changed, 25 insertions(+), 2 deletions(-)
>>>>
>>>> diff --git a/hw/i386/pc.c b/hw/i386/pc.c
>>>> index 8fa8d2f..c2956f9 100644
>>>> --- a/hw/i386/pc.c
>>>> +++ b/hw/i386/pc.c
>>>> @@ -1607,11 +1607,34 @@ out:
>>>>  error_propagate(errp, local_err);
>>>>  }
>>>>  
>>>> +static void pc_cpu_plug(HotplugHandler *hotplug_dev,
>>>> + DeviceState *dev, Error **errp)
>>>> +{
>>>> +HotplugHandlerClass *hhc;
>>>> +Error *local_err = NULL;
>>>> +PCMachineState *pcms = PC_MACHINE(hotplug_dev);
>>>> +
>>>> +if (dev->hotplugged) {
>>> for startup CPUs we set gpe_cpu status bits in AcpiCpuHotplug_init()
>>> and for hotpluged in AcpiCpuHotplug_add() which is duplicating
>>> essentially the same code.
>>>
>>> Could you drop above check and make AcpiCpuHotplug_init() take care
>>> about startup CPUs as well, keeping bit setting in one place.
>>
>> Yeah, with the above change, code will be more neat, but I think it is not
>> a serious problem.:)
>> And pcms->acpi_dev is set when PC hardware initialisation (e.g. pc_init1),
>> for start up cpus, the plug handler is not valid, so the check is needed
>> here to avoid trigger error by start cpu.
> 
> then check for !pcms->acpi_dev and exit if it not set (i.e. as pc_dimm_plug() 
> does)
> since there isn't acpi hardware to update for startup CPUs either.
> 
> may be something along this lines:
> 
> if (!pcms->acpi_dev) {
>   if (dev->hotplugged) error_setg(&local_err, "CPU hotplug is not supported 
> without ACPI");
>   goto out;
> }

This is more neat, thanks.

> 
>>
>>>
>>>> +if (!pcms->acpi_dev) {
>>>> +error_setg(&local_err,
>>>> +   "cpu hotplug is not enabled: missing acpi device");
>>>> +goto out;
>>>> +}
>>>> +
>>>> +hhc = HOTPLUG_HANDLER_GET_CLASS(pcms->acpi_dev);
>>>> +hhc->plug(HOTPLUG_HANDLER(pcms->acpi_dev), dev, &local_err);
>>>> +out:
>>>> +error_propagate(errp, local_err);
>>>> +}
>>>> +}
>>>> +
>>>>  static void pc_machine_device_plug_cb(HotplugHandler *hotplug_dev,
>>>>DeviceState *dev, Error **errp)
>>>>  {
>>>>  if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
>>>>  pc_dimm_plug(hotplug_dev, dev, errp);
>>>> +} else if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) {
>>>> +pc_cpu_plug(hotplug_dev, dev, errp);
>>>>  }
>>>>  }
>>>>  
>>>> @@ -1620,7 +1643,8 @@ static HotplugHandler 
>>>> *pc_get_hotpug_handler(MachineState *machine,
>>>>  {
>>>>  PCMachineClass *pcmc = PC_MACHINE_GET_CLASS(machine);
>>>>  
>>>> -if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
>>>> +if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)
>>>> +|| object_dynamic_cast(OBJECT(dev), TYPE_CPU)) {
>>>>  return HOTPLUG_HANDLER(machine);
>>>>  }
>>>>  
>>>> diff --git a/qom/cpu.c b/qom/cpu.c
>>>> index b32dd0a..af8e83f 100644
>>>> --- a/qom/cpu.c
>>>> +++ b/qom/cpu.c
>>>> @@ -304,7 +304,6 @@ static void cpu_common_realizefn(DeviceState *dev, 
>>>> Error **errp)
>>>>  if (dev->hotplugged) {
>>>>  cpu_synchronize_post_init(cpu);
>>>>  notifier_list_notify(&cpu_added_notifiers, dev);
>>>> -cpu_resume(cpu);
>>>>  }
>>>>  }
>>>>  
>>>
>>> I don't see what sets PCMachine as hotplug_handler for CPU,
>>> maybe series is missing a patch?
>>
>> Previous memory hotplug has built the frame work, here just adding the case
>> to handle CPU.
> You still need to set hotplug handler for CPU device or ICCBus
> grep for qbus_set_hotplug_handler()

Current implementation is the same as bus-less device's (e.g. memory), via the
machine's get_hotplug_handler method to discover a hotplug handler controller,
and it works fine.
Shall we still need to set hotplug handler ICCBus, which seems duplicated?
Or switch to set hotplug handler to ICCBus, and drop current implementation?

Thanks,
Gu

> 
>>
>>  static void pc_machine_device_plug_cb(HotplugHandler *hotplug_dev,
>>DeviceState *dev, Error **errp)
>>  {
>>  if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
>>  pc_dimm_plug(hotplug_dev, dev, errp);
>> +} else if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) {
>> +pc_cpu_plug(hotplug_dev, dev, errp);
>>  }
>>
>> Thanks,
>> Gu
>>
>>>
>>> .
>>>
>>
>>
> 
> .
> 





Re: [Qemu-devel] [RFC V2 10/10] cpus: reclaim allocated vCPU objects

2014-09-14 Thread Gu Zheng
Hi Igor,
On 09/12/2014 10:15 PM, Igor Mammedov wrote:

> On Thu, 28 Aug 2014 11:36:42 +0800
> Gu Zheng  wrote:
> 
>> After ACPI get a signal to eject a vCPU, the vCPU must be
>> removed from CPU list,before the vCPU really removed,  then
>> release the all related vCPU objects.
>> But we do not close KVM vcpu fd, just record it into a list, in
>> order to reuse it.
> An additional question,
>   Have you checked if migration works after CPU unplug?

Yes, migration works fine after CPU unplug.

Thanks,
Gu

> 
>>
>> Signed-off-by: Chen Fan 
>> Signed-off-by: Gu Zheng 
>> ---
>>  cpus.c   |   37 
>>  include/sysemu/kvm.h |1 +
>>  kvm-all.c|   57 
>> +-
>>  3 files changed, 94 insertions(+), 1 deletions(-)
>>
>> diff --git a/cpus.c b/cpus.c
>> index eee693b..0608b41 100644
>> --- a/cpus.c
>> +++ b/cpus.c
>> @@ -851,6 +851,24 @@ void async_run_on_cpu(CPUState *cpu, void (*func)(void 
>> *data), void *data)
>>  qemu_cpu_kick(cpu);
>>  }
>>  
>> +static void qemu_kvm_destroy_vcpu(CPUState *cpu)
>> +{
>> +CPU_REMOVE(cpu);
>> +
>> +if (kvm_destroy_vcpu(cpu) < 0) {
>> +fprintf(stderr, "kvm_destroy_vcpu failed.\n");
>> +exit(1);
>> +}
>> +
>> +object_unparent(OBJECT(cpu));
>> +}
>> +
>> +static void qemu_tcg_destroy_vcpu(CPUState *cpu)
>> +{
>> +CPU_REMOVE(cpu);
>> +object_unparent(OBJECT(cpu));
>> +}
>> +
>>  static void flush_queued_work(CPUState *cpu)
>>  {
>>  struct qemu_work_item *wi;
>> @@ -942,6 +960,11 @@ static void *qemu_kvm_cpu_thread_fn(void *arg)
>>  }
>>  }
>>  qemu_kvm_wait_io_event(cpu);
>> +if (cpu->exit && !cpu_can_run(cpu)) {
>> +qemu_kvm_destroy_vcpu(cpu);
>> +qemu_mutex_unlock(&qemu_global_mutex);
>> +return NULL;
>> +}
>>  }
>>  
>>  return NULL;
>> @@ -994,6 +1017,7 @@ static void tcg_exec_all(void);
>>  static void *qemu_tcg_cpu_thread_fn(void *arg)
>>  {
>>  CPUState *cpu = arg;
>> +CPUState *remove_cpu = NULL;
>>  
>>  qemu_tcg_init_cpu_signals();
>>  qemu_thread_get_self(cpu->thread);
>> @@ -1026,6 +1050,16 @@ static void *qemu_tcg_cpu_thread_fn(void *arg)
>>  }
>>  }
>>  qemu_tcg_wait_io_event();
>> +CPU_FOREACH(cpu) {
>> +if (cpu->exit && !cpu_can_run(cpu)) {
>> +remove_cpu = cpu;
>> +break;
>> +}
>> +}
>> +if (remove_cpu) {
>> +qemu_tcg_destroy_vcpu(remove_cpu);
>> +remove_cpu = NULL;
>> +}
>>  }
>>  
>>  return NULL;
>> @@ -1383,6 +1417,9 @@ static void tcg_exec_all(void)
>>  break;
>>  }
>>  } else if (cpu->stop || cpu->stopped) {
>> +if (cpu->exit) {
>> +next_cpu = CPU_NEXT(cpu);
>> +}
>>  break;
>>  }
>>  }
>> diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h
>> index 174ea36..88e2403 100644
>> --- a/include/sysemu/kvm.h
>> +++ b/include/sysemu/kvm.h
>> @@ -178,6 +178,7 @@ int kvm_has_intx_set_mask(void);
>>  
>>  int kvm_init_vcpu(CPUState *cpu);
>>  int kvm_cpu_exec(CPUState *cpu);
>> +int kvm_destroy_vcpu(CPUState *cpu);
>>  
>>  #ifdef NEED_CPU_H
>>  
>> diff --git a/kvm-all.c b/kvm-all.c
>> index 1402f4f..d0caeff 100644
>> --- a/kvm-all.c
>> +++ b/kvm-all.c
>> @@ -74,6 +74,12 @@ typedef struct KVMSlot
>>  
>>  typedef struct kvm_dirty_log KVMDirtyLog;
>>  
>> +struct KVMParkedVcpu {
>> +unsigned long vcpu_id;
>> +int kvm_fd;
>> +QLIST_ENTRY(KVMParkedVcpu) node;
>> +};
>> +
>>  struct KVMState
>>  {
>>  KVMSlot *slots;
>> @@ -108,6 +114,7 @@ struct KVMState
>>  QTAILQ_HEAD(msi_hashtab, KVMMSIRoute) msi_hashtab[KVM_MSI_HASHTAB_SIZE];
>>  bool direct_msi;
>>  #endif
>> +QLIST_HEAD(, KVMParkedVcpu) kvm_parked_vcpus;
>>  };
>>  
>>  KVMState *kvm_state;
>> @@ -226,6 +233,53 @@ static int kvm_set_user_memory_region(KVMState *s, 
>> KVMSlot *slot)
>>  return kvm_vm_ioctl(s, KVM_SET_USER_ME

Re: [Qemu-devel] [RFC V2 10/10] cpus: reclaim allocated vCPU objects

2014-09-14 Thread Gu Zheng
Hi Bharata,
On 09/12/2014 09:52 PM, Bharata B Rao wrote:

> On Fri, Sep 12, 2014 at 4:23 PM, Anshul Makkar
>  wrote:
>> During plugging we can see this event: echo 1 > cpu8/online.
>>
>> But during unplugging , we can't see the event echo 0 > cpu8/online.
> 
> That's because I didn't do that explicitly, was always trying to
> remove an online cpu from the monitor w/o explicitly offlining it from
> inside the guest. Either ways I still see the removed CPU being listed
> in QEMU monitor.
> 
> I don't ever hit any of the below code paths during CPU removal:

It seems that the guest OS did not call the "_EJ0" method.
Could you please dump the guest os' acpi dsdt, and check whether the "_EJ0"
method exists? 

> 
> cpus.c: qemu_kvm_destroy_vcpu()
> cpus.c: x86_cpu_finalizefn()
> 
> I see CPU_REMOVE() being called from above two routines.
> 
> And neither does hw/acpi/cpu_hotplug.c:cpu_status_write() gets called
> here. Does the message "ACPI: Device does not support D3cold" guest
> kernel throws during hot removal is causing this behaviour here ?
> Guest kernel is 3.11.10, should I be on latest kernel ?

I have tested the fedora 20 guest with the default kernel, it works well,
so the kernel should be fine.
One more question, is the guest kernel config the same as fedora 20's default 
one?

Thanks,
Gu

> 
> Regards,
> Bharata.
> .
> 





[Qemu-devel] [PATCH V3 0/7] cpu/acpi: convert cpu hot plug to hotplug_handler API

2014-09-16 Thread Gu Zheng
Previously we use cpu_added_notifiers to register cpu hotplug notifier callback
which is not able to pass/handle errors, so we switch it to unified hotplug
handler API which allows to pass errors and would allow to cancel device_add
in case of error.
Thanks very much for Igor's review and suggestion.

v3:
 -deal with start-up cpus in pc_cpu_plug as Igor suggested.

v2:
 -Add 3 new patches(5/7,6/7,7/7), delete original patch 5/5.
  1/5-->1/7
  2/5-->2/7
  3/5-->3/7
  4/5-->4/7
 Patch 1/7:
 -add errp argument to catch error.
 -return error instead of aborting if cpu id is invalid.
 -make acpi_cpu_plug_cb as a wrapper around AcpiCpuHotplug_add.
 Patch 3/7:
 -remove unused AcpiCpuHotplug_add directly.
 Patch 5/7:
 -switch the last user of cpu hotplug notifier to hotplug handler API, and
  remove the unused cpu hotplug notify.
 Patch 6/7:
 -split the function rename (just cleanup) into single patch.
 Patch 7/7:
 -introduce help function acpi_set_local_sts to keep the bit setting in
  one place.

Gu Zheng (7):
  acpi/cpu: add cpu hotplug callback function to match hotplug_handler
API
  acpi:ich9: convert cpu hotplug handle to hotplug_handler API
  acpi:piix4: convert cpu hotplug handle to hotplug_handler API
  pc: add cpu hotplug handler to PC_MACHINE
  pc: Update rtc_cmos in pc_cpu_plug
  cpu-hotplug: rename function for better readability
  acpi/cpu-hotplug: introduce help function to keep bit setting in one
place

 hw/acpi/cpu_hotplug.c |   35 
 hw/acpi/ich9.c|   18 --
 hw/acpi/piix4.c   |   18 +++---
 hw/i386/pc.c  |   51 +
 include/hw/acpi/cpu_hotplug.h |7 +++--
 include/hw/acpi/ich9.h|1 -
 include/sysemu/sysemu.h   |3 --
 qom/cpu.c |   10 
 8 files changed, 69 insertions(+), 74 deletions(-)

-- 
1.7.7




[Qemu-devel] [PATCH V3 1/7] acpi/cpu: add cpu hotplug callback function to match hotplug_handler API

2014-09-16 Thread Gu Zheng
---
v2:
 -add errp argument to catch error.
 -return error instead of aborting if cpu id is invalid.
 -make acpi_cpu_plug_cb as a wrapper around AcpiCpuHotplug_add.
---

Signed-off-by: Gu Zheng 
---
 hw/acpi/cpu_hotplug.c |   17 +
 include/hw/acpi/cpu_hotplug.h |3 +++
 2 files changed, 20 insertions(+), 0 deletions(-)

diff --git a/hw/acpi/cpu_hotplug.c b/hw/acpi/cpu_hotplug.c
index 2ad83a0..dfd6de5 100644
--- a/hw/acpi/cpu_hotplug.c
+++ b/hw/acpi/cpu_hotplug.c
@@ -36,6 +36,23 @@ static const MemoryRegionOps AcpiCpuHotplug_ops = {
 },
 };
 
+void acpi_cpu_plug_cb(ACPIREGS *ar, qemu_irq irq,
+  AcpiCpuHotplug *g, CPUState *cpu, Error **errp)
+{
+CPUClass *k = CPU_GET_CLASS(cpu);
+int64_t cpu_id;
+
+cpu_id = k->get_arch_id(cpu);
+if ((cpu_id / 8) >= ACPI_GPE_PROC_LEN) {
+error_setg(errp, "acpi: invalid cpu id: %" PRIi64, cpu_id);
+return;
+}
+
+AcpiCpuHotplug_add(&ar->gpe, g, cpu);
+
+acpi_update_sci(ar, irq);
+}
+
 void AcpiCpuHotplug_add(ACPIGPE *gpe, AcpiCpuHotplug *g, CPUState *cpu)
 {
 CPUClass *k = CPU_GET_CLASS(cpu);
diff --git a/include/hw/acpi/cpu_hotplug.h b/include/hw/acpi/cpu_hotplug.h
index 9e5d30c..166edb0 100644
--- a/include/hw/acpi/cpu_hotplug.h
+++ b/include/hw/acpi/cpu_hotplug.h
@@ -20,6 +20,9 @@ typedef struct AcpiCpuHotplug {
 uint8_t sts[ACPI_GPE_PROC_LEN];
 } AcpiCpuHotplug;
 
+void acpi_cpu_plug_cb(ACPIREGS *ar, qemu_irq irq,
+  AcpiCpuHotplug *g, CPUState *dev, Error **errp);
+
 void AcpiCpuHotplug_add(ACPIGPE *gpe, AcpiCpuHotplug *g, CPUState *cpu);
 
 void AcpiCpuHotplug_init(MemoryRegion *parent, Object *owner,
-- 
1.7.7




[Qemu-devel] [PATCH V3 2/7] acpi:ich9: convert cpu hotplug handle to hotplug_handler API

2014-09-16 Thread Gu Zheng
Convert notifier based hotplug handle to hotplug_handler API.

Signed-off-by: Gu Zheng 
---
 hw/acpi/ich9.c |   14 +++---
 include/hw/acpi/ich9.h |1 -
 2 files changed, 3 insertions(+), 12 deletions(-)

diff --git a/hw/acpi/ich9.c b/hw/acpi/ich9.c
index 7b14bbb..c53d4ab 100644
--- a/hw/acpi/ich9.c
+++ b/hw/acpi/ich9.c
@@ -209,15 +209,6 @@ static void pm_powerdown_req(Notifier *n, void *opaque)
 acpi_pm1_evt_power_down(&pm->acpi_regs);
 }
 
-static void ich9_cpu_added_req(Notifier *n, void *opaque)
-{
-ICH9LPCPMRegs *pm = container_of(n, ICH9LPCPMRegs, cpu_added_notifier);
-
-assert(pm != NULL);
-AcpiCpuHotplug_add(&pm->acpi_regs.gpe, &pm->gpe_cpu, CPU(opaque));
-acpi_update_sci(&pm->acpi_regs, pm->irq);
-}
-
 void ich9_pm_init(PCIDevice *lpc_pci, ICH9LPCPMRegs *pm,
   qemu_irq sci_irq)
 {
@@ -246,8 +237,6 @@ void ich9_pm_init(PCIDevice *lpc_pci, ICH9LPCPMRegs *pm,
 
 AcpiCpuHotplug_init(pci_address_space_io(lpc_pci), OBJECT(lpc_pci),
 &pm->gpe_cpu, ICH9_CPU_HOTPLUG_IO_BASE);
-pm->cpu_added_notifier.notify = ich9_cpu_added_req;
-qemu_register_cpu_added_notifier(&pm->cpu_added_notifier);
 
 if (pm->acpi_memory_hotplug.is_enabled) {
 acpi_memory_hotplug_init(pci_address_space_io(lpc_pci), 
OBJECT(lpc_pci),
@@ -304,6 +293,9 @@ void ich9_pm_device_plug_cb(ICH9LPCPMRegs *pm, DeviceState 
*dev, Error **errp)
 object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
 acpi_memory_plug_cb(&pm->acpi_regs, pm->irq, &pm->acpi_memory_hotplug,
 dev, errp);
+} else if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) {
+acpi_cpu_plug_cb(&pm->acpi_regs, pm->irq, &pm->gpe_cpu,
+ CPU(dev), errp);
 } else {
 error_setg(errp, "acpi: device plug request for not supported device"
" type: %s", object_get_typename(OBJECT(dev)));
diff --git a/include/hw/acpi/ich9.h b/include/hw/acpi/ich9.h
index 7e42448..fe975e6 100644
--- a/include/hw/acpi/ich9.h
+++ b/include/hw/acpi/ich9.h
@@ -47,7 +47,6 @@ typedef struct ICH9LPCPMRegs {
 Notifier powerdown_notifier;
 
 AcpiCpuHotplug gpe_cpu;
-Notifier cpu_added_notifier;
 
 MemHotplugState acpi_memory_hotplug;
 } ICH9LPCPMRegs;
-- 
1.7.7




[Qemu-devel] [PATCH V3 3/7] acpi:piix4: convert cpu hotplug handle to hotplug_handler API

2014-09-16 Thread Gu Zheng
Convert notifier based hotplug handle to hotplug_handler API,
and remove the unused AcpiCpuHotplug_add().

v2:
-remove the unused AcpiCpuHotplug_add().

Signed-off-by: Gu Zheng 
---
 hw/acpi/cpu_hotplug.c |   14 ++
 hw/acpi/piix4.c   |   14 ++
 include/hw/acpi/cpu_hotplug.h |2 --
 3 files changed, 4 insertions(+), 26 deletions(-)

diff --git a/hw/acpi/cpu_hotplug.c b/hw/acpi/cpu_hotplug.c
index dfd6de5..0b9fa55 100644
--- a/hw/acpi/cpu_hotplug.c
+++ b/hw/acpi/cpu_hotplug.c
@@ -48,22 +48,12 @@ void acpi_cpu_plug_cb(ACPIREGS *ar, qemu_irq irq,
 return;
 }
 
-AcpiCpuHotplug_add(&ar->gpe, g, cpu);
+ar->gpe.sts[0] |= ACPI_CPU_HOTPLUG_STATUS;
+g->sts[cpu_id / 8] |= (1 << (cpu_id % 8));
 
 acpi_update_sci(ar, irq);
 }
 
-void AcpiCpuHotplug_add(ACPIGPE *gpe, AcpiCpuHotplug *g, CPUState *cpu)
-{
-CPUClass *k = CPU_GET_CLASS(cpu);
-int64_t cpu_id;
-
-*gpe->sts = *gpe->sts | ACPI_CPU_HOTPLUG_STATUS;
-cpu_id = k->get_arch_id(CPU(cpu));
-g_assert((cpu_id / 8) < ACPI_GPE_PROC_LEN);
-g->sts[cpu_id / 8] |= (1 << (cpu_id % 8));
-}
-
 void AcpiCpuHotplug_init(MemoryRegion *parent, Object *owner,
  AcpiCpuHotplug *gpe_cpu, uint16_t base)
 {
diff --git a/hw/acpi/piix4.c b/hw/acpi/piix4.c
index b72b34e..b046cd3 100644
--- a/hw/acpi/piix4.c
+++ b/hw/acpi/piix4.c
@@ -83,7 +83,6 @@ typedef struct PIIX4PMState {
 uint8_t s4_val;
 
 AcpiCpuHotplug gpe_cpu;
-Notifier cpu_added_notifier;
 
 MemHotplugState acpi_memory_hotplug;
 } PIIX4PMState;
@@ -348,6 +347,8 @@ static void piix4_device_plug_cb(HotplugHandler 
*hotplug_dev,
 } else if (object_dynamic_cast(OBJECT(dev), TYPE_PCI_DEVICE)) {
 acpi_pcihp_device_plug_cb(&s->ar, s->irq, &s->acpi_pci_hotplug, dev,
   errp);
+} else if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) {
+acpi_cpu_plug_cb(&s->ar, s->irq, &s->gpe_cpu, CPU(dev), errp);
 } else {
 error_setg(errp, "acpi: device plug request for not supported device"
" type: %s", object_get_typename(OBJECT(dev)));
@@ -544,15 +545,6 @@ static const MemoryRegionOps piix4_gpe_ops = {
 .endianness = DEVICE_LITTLE_ENDIAN,
 };
 
-static void piix4_cpu_added_req(Notifier *n, void *opaque)
-{
-PIIX4PMState *s = container_of(n, PIIX4PMState, cpu_added_notifier);
-
-assert(s != NULL);
-AcpiCpuHotplug_add(&s->ar.gpe, &s->gpe_cpu, CPU(opaque));
-acpi_update_sci(&s->ar, s->irq);
-}
-
 static void piix4_acpi_system_hot_add_init(MemoryRegion *parent,
PCIBus *bus, PIIX4PMState *s)
 {
@@ -565,8 +557,6 @@ static void piix4_acpi_system_hot_add_init(MemoryRegion 
*parent,
 
 AcpiCpuHotplug_init(parent, OBJECT(s), &s->gpe_cpu,
 PIIX4_CPU_HOTPLUG_IO_BASE);
-s->cpu_added_notifier.notify = piix4_cpu_added_req;
-qemu_register_cpu_added_notifier(&s->cpu_added_notifier);
 
 if (s->acpi_memory_hotplug.is_enabled) {
 acpi_memory_hotplug_init(parent, OBJECT(s), &s->acpi_memory_hotplug);
diff --git a/include/hw/acpi/cpu_hotplug.h b/include/hw/acpi/cpu_hotplug.h
index 166edb0..8188630 100644
--- a/include/hw/acpi/cpu_hotplug.h
+++ b/include/hw/acpi/cpu_hotplug.h
@@ -23,8 +23,6 @@ typedef struct AcpiCpuHotplug {
 void acpi_cpu_plug_cb(ACPIREGS *ar, qemu_irq irq,
   AcpiCpuHotplug *g, CPUState *dev, Error **errp);
 
-void AcpiCpuHotplug_add(ACPIGPE *gpe, AcpiCpuHotplug *g, CPUState *cpu);
-
 void AcpiCpuHotplug_init(MemoryRegion *parent, Object *owner,
  AcpiCpuHotplug *gpe_cpu, uint16_t base);
 #endif
-- 
1.7.7




[Qemu-devel] [PATCH V3 4/7] pc: add cpu hotplug handler to PC_MACHINE

2014-09-16 Thread Gu Zheng
Add cpu hotplug handler to PC_MACHINE, which will perform the acpi
cpu hotplug callback via hotplug_handler API.

v3:
 -deal with start up cpus in a more neat way as Igor suggested.
v2:
 -just rebase.

Signed-off-by: Gu Zheng 
---
 hw/i386/pc.c |   26 +-
 1 files changed, 25 insertions(+), 1 deletions(-)

diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index b6c9b61..e25e71b 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -1613,11 +1613,34 @@ out:
 error_propagate(errp, local_err);
 }
 
+static void pc_cpu_plug(HotplugHandler *hotplug_dev,
+DeviceState *dev, Error **errp)
+{
+HotplugHandlerClass *hhc;
+Error *local_err = NULL;
+PCMachineState *pcms = PC_MACHINE(hotplug_dev);
+
+if (!pcms->acpi_dev) {
+if (dev->hotplugged) {
+error_setg(&local_err,
+   "cpu hotplug is not enabled: missing acpi device");
+}
+goto out;
+}
+
+hhc = HOTPLUG_HANDLER_GET_CLASS(pcms->acpi_dev);
+hhc->plug(HOTPLUG_HANDLER(pcms->acpi_dev), dev, &local_err);
+out:
+error_propagate(errp, local_err);
+}
+
 static void pc_machine_device_plug_cb(HotplugHandler *hotplug_dev,
   DeviceState *dev, Error **errp)
 {
 if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
 pc_dimm_plug(hotplug_dev, dev, errp);
+} else if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) {
+pc_cpu_plug(hotplug_dev, dev, errp);
 }
 }
 
@@ -1626,7 +1649,8 @@ static HotplugHandler *pc_get_hotpug_handler(MachineState 
*machine,
 {
 PCMachineClass *pcmc = PC_MACHINE_GET_CLASS(machine);
 
-if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
+if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM) ||
+object_dynamic_cast(OBJECT(dev), TYPE_CPU)) {
 return HOTPLUG_HANDLER(machine);
 }
 
-- 
1.7.7




[Qemu-devel] [PATCH V3 6/7] cpu-hotplug: rename function for better readability

2014-09-16 Thread Gu Zheng
Rename:
AcpiCpuHotplug_init --> acpi_cpu_hotplug_init
AcpiCpuHotplug_ops --> acpi_cpu_hotplug_ops
for better readability, just cleanup.

Signed-off-by: Gu Zheng 
---
 hw/acpi/cpu_hotplug.c |4 ++--
 hw/acpi/ich9.c|4 ++--
 hw/acpi/piix4.c   |4 ++--
 include/hw/acpi/cpu_hotplug.h |4 ++--
 4 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/hw/acpi/cpu_hotplug.c b/hw/acpi/cpu_hotplug.c
index 0b9fa55..7629686 100644
--- a/hw/acpi/cpu_hotplug.c
+++ b/hw/acpi/cpu_hotplug.c
@@ -54,8 +54,8 @@ void acpi_cpu_plug_cb(ACPIREGS *ar, qemu_irq irq,
 acpi_update_sci(ar, irq);
 }
 
-void AcpiCpuHotplug_init(MemoryRegion *parent, Object *owner,
- AcpiCpuHotplug *gpe_cpu, uint16_t base)
+void acpi_cpu_hotplug_init(MemoryRegion *parent, Object *owner,
+   AcpiCpuHotplug *gpe_cpu, uint16_t base)
 {
 CPUState *cpu;
 
diff --git a/hw/acpi/ich9.c b/hw/acpi/ich9.c
index c53d4ab..42cf8fa 100644
--- a/hw/acpi/ich9.c
+++ b/hw/acpi/ich9.c
@@ -235,8 +235,8 @@ void ich9_pm_init(PCIDevice *lpc_pci, ICH9LPCPMRegs *pm,
 pm->powerdown_notifier.notify = pm_powerdown_req;
 qemu_register_powerdown_notifier(&pm->powerdown_notifier);
 
-AcpiCpuHotplug_init(pci_address_space_io(lpc_pci), OBJECT(lpc_pci),
-&pm->gpe_cpu, ICH9_CPU_HOTPLUG_IO_BASE);
+acpi_cpu_hotplug_init(pci_address_space_io(lpc_pci), OBJECT(lpc_pci),
+  &pm->gpe_cpu, ICH9_CPU_HOTPLUG_IO_BASE);
 
 if (pm->acpi_memory_hotplug.is_enabled) {
 acpi_memory_hotplug_init(pci_address_space_io(lpc_pci), 
OBJECT(lpc_pci),
diff --git a/hw/acpi/piix4.c b/hw/acpi/piix4.c
index b046cd3..205ba66 100644
--- a/hw/acpi/piix4.c
+++ b/hw/acpi/piix4.c
@@ -555,8 +555,8 @@ static void piix4_acpi_system_hot_add_init(MemoryRegion 
*parent,
 acpi_pcihp_init(&s->acpi_pci_hotplug, bus, parent,
 s->use_acpi_pci_hotplug);
 
-AcpiCpuHotplug_init(parent, OBJECT(s), &s->gpe_cpu,
-PIIX4_CPU_HOTPLUG_IO_BASE);
+acpi_cpu_hotplug_init(parent, OBJECT(s), &s->gpe_cpu,
+  PIIX4_CPU_HOTPLUG_IO_BASE);
 
 if (s->acpi_memory_hotplug.is_enabled) {
 acpi_memory_hotplug_init(parent, OBJECT(s), &s->acpi_memory_hotplug);
diff --git a/include/hw/acpi/cpu_hotplug.h b/include/hw/acpi/cpu_hotplug.h
index 8188630..d015bef 100644
--- a/include/hw/acpi/cpu_hotplug.h
+++ b/include/hw/acpi/cpu_hotplug.h
@@ -23,6 +23,6 @@ typedef struct AcpiCpuHotplug {
 void acpi_cpu_plug_cb(ACPIREGS *ar, qemu_irq irq,
   AcpiCpuHotplug *g, CPUState *dev, Error **errp);
 
-void AcpiCpuHotplug_init(MemoryRegion *parent, Object *owner,
- AcpiCpuHotplug *gpe_cpu, uint16_t base);
+void acpi_cpu_hotplug_init(MemoryRegion *parent, Object *owner,
+   AcpiCpuHotplug *gpe_cpu, uint16_t base);
 #endif
-- 
1.7.7




[Qemu-devel] [PATCH V3 5/7] pc: Update rtc_cmos in pc_cpu_plug

2014-09-16 Thread Gu Zheng
Update rtc_cmos in pc_cpu_plug directly instead of the notifier, with
this change, there will no user of CPU hot-plug notifier any more, so
remove it.

Signed-off-by: Gu Zheng 
---
 hw/i386/pc.c|   25 ++---
 include/sysemu/sysemu.h |3 ---
 qom/cpu.c   |   10 --
 3 files changed, 6 insertions(+), 32 deletions(-)

diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index e25e71b..8b887c7 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -353,20 +353,7 @@ static void pc_cmos_init_late(void *opaque)
 qemu_unregister_reset(pc_cmos_init_late, opaque);
 }
 
-typedef struct RTCCPUHotplugArg {
-Notifier cpu_added_notifier;
-ISADevice *rtc_state;
-} RTCCPUHotplugArg;
-
-static void rtc_notify_cpu_added(Notifier *notifier, void *data)
-{
-RTCCPUHotplugArg *arg = container_of(notifier, RTCCPUHotplugArg,
- cpu_added_notifier);
-ISADevice *s = arg->rtc_state;
-
-/* increment the number of CPUs */
-rtc_set_memory(s, 0x5f, rtc_get_memory(s, 0x5f) + 1);
-}
+static ISADevice *rtc_state;
 
 void pc_cmos_init(ram_addr_t ram_size, ram_addr_t above_4g_mem_size,
   const char *boot_device,
@@ -376,7 +363,6 @@ void pc_cmos_init(ram_addr_t ram_size, ram_addr_t 
above_4g_mem_size,
 int val, nb, i;
 FDriveType fd_type[2] = { FDRIVE_DRV_NONE, FDRIVE_DRV_NONE };
 static pc_cmos_init_late_arg arg;
-static RTCCPUHotplugArg cpu_hotplug_cb;
 
 /* various important CMOS locations needed by PC/Bochs bios */
 
@@ -415,10 +401,8 @@ void pc_cmos_init(ram_addr_t ram_size, ram_addr_t 
above_4g_mem_size,
 
 /* set the number of CPU */
 rtc_set_memory(s, 0x5f, smp_cpus - 1);
-/* init CPU hotplug notifier */
-cpu_hotplug_cb.rtc_state = s;
-cpu_hotplug_cb.cpu_added_notifier.notify = rtc_notify_cpu_added;
-qemu_register_cpu_added_notifier(&cpu_hotplug_cb.cpu_added_notifier);
+
+rtc_state = s;
 
 if (set_boot_dev(s, boot_device)) {
 exit(1);
@@ -1630,6 +1614,9 @@ static void pc_cpu_plug(HotplugHandler *hotplug_dev,
 
 hhc = HOTPLUG_HANDLER_GET_CLASS(pcms->acpi_dev);
 hhc->plug(HOTPLUG_HANDLER(pcms->acpi_dev), dev, &local_err);
+
+/* increment the number of CPUs */
+rtc_set_memory(rtc_state, 0x5f, rtc_get_memory(rtc_state, 0x5f) + 1);
 out:
 error_propagate(errp, local_err);
 }
diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h
index d8539fd..acfe494 100644
--- a/include/sysemu/sysemu.h
+++ b/include/sysemu/sysemu.h
@@ -183,9 +183,6 @@ void do_pci_device_hot_remove(Monitor *mon, const QDict 
*qdict);
 /* generic hotplug */
 void drive_hot_add(Monitor *mon, const QDict *qdict);
 
-/* CPU hotplug */
-void qemu_register_cpu_added_notifier(Notifier *notifier);
-
 /* pcie aer error injection */
 void pcie_aer_inject_error_print(Monitor *mon, const QObject *data);
 int do_pcie_aer_inject_error(Monitor *mon,
diff --git a/qom/cpu.c b/qom/cpu.c
index b32dd0a..19c5de5 100644
--- a/qom/cpu.c
+++ b/qom/cpu.c
@@ -107,15 +107,6 @@ static void cpu_common_get_memory_mapping(CPUState *cpu,
 error_setg(errp, "Obtaining memory mappings is unsupported on this CPU.");
 }
 
-/* CPU hot-plug notifiers */
-static NotifierList cpu_added_notifiers =
-NOTIFIER_LIST_INITIALIZER(cpu_add_notifiers);
-
-void qemu_register_cpu_added_notifier(Notifier *notifier)
-{
-notifier_list_add(&cpu_added_notifiers, notifier);
-}
-
 void cpu_reset_interrupt(CPUState *cpu, int mask)
 {
 cpu->interrupt_request &= ~mask;
@@ -303,7 +294,6 @@ static void cpu_common_realizefn(DeviceState *dev, Error 
**errp)
 
 if (dev->hotplugged) {
 cpu_synchronize_post_init(cpu);
-notifier_list_notify(&cpu_added_notifiers, dev);
 cpu_resume(cpu);
 }
 }
-- 
1.7.7




[Qemu-devel] [PATCH V3 7/7] acpi/cpu-hotplug: introduce help function to keep bit setting in one place

2014-09-16 Thread Gu Zheng
Introduce help function acpi_set_local_sts() to simplify acpi_cpu_plug_cb
and acpi_cpu_hotplug_init, so that we can keep bit setting in one place.

Signed-off-by: Gu Zheng 
---
 hw/acpi/cpu_hotplug.c |   22 +++---
 1 files changed, 15 insertions(+), 7 deletions(-)

diff --git a/hw/acpi/cpu_hotplug.c b/hw/acpi/cpu_hotplug.c
index 7629686..d42c961 100644
--- a/hw/acpi/cpu_hotplug.c
+++ b/hw/acpi/cpu_hotplug.c
@@ -36,8 +36,8 @@ static const MemoryRegionOps AcpiCpuHotplug_ops = {
 },
 };
 
-void acpi_cpu_plug_cb(ACPIREGS *ar, qemu_irq irq,
-  AcpiCpuHotplug *g, CPUState *cpu, Error **errp)
+static void acpi_set_local_sts(AcpiCpuHotplug *g, CPUState *cpu,
+   Error **errp)
 {
 CPUClass *k = CPU_GET_CLASS(cpu);
 int64_t cpu_id;
@@ -48,9 +48,18 @@ void acpi_cpu_plug_cb(ACPIREGS *ar, qemu_irq irq,
 return;
 }
 
-ar->gpe.sts[0] |= ACPI_CPU_HOTPLUG_STATUS;
 g->sts[cpu_id / 8] |= (1 << (cpu_id % 8));
+}
 
+void acpi_cpu_plug_cb(ACPIREGS *ar, qemu_irq irq,
+  AcpiCpuHotplug *g, CPUState *cpu, Error **errp)
+{
+acpi_set_local_sts(g, cpu, errp);
+if (*errp != NULL) {
+return;
+}
+
+ar->gpe.sts[0] |= ACPI_CPU_HOTPLUG_STATUS;
 acpi_update_sci(ar, irq);
 }
 
@@ -60,11 +69,10 @@ void acpi_cpu_hotplug_init(MemoryRegion *parent, Object 
*owner,
 CPUState *cpu;
 
 CPU_FOREACH(cpu) {
-CPUClass *cc = CPU_GET_CLASS(cpu);
-int64_t id = cc->get_arch_id(cpu);
+Error *local_err = NULL;
 
-g_assert((id / 8) < ACPI_GPE_PROC_LEN);
-gpe_cpu->sts[id / 8] |= (1 << (id % 8));
+acpi_set_local_sts(gpe_cpu, cpu, &local_err);
+g_assert(local_err == NULL);
 }
 memory_region_init_io(&gpe_cpu->io, owner, &AcpiCpuHotplug_ops,
   gpe_cpu, "acpi-cpu-hotplug", ACPI_GPE_PROC_LEN);
-- 
1.7.7




Re: [Qemu-devel] [PATCH V3 0/7] cpu/acpi: convert cpu hot plug to hotplug_handler API

2014-09-18 Thread Gu Zheng
Hi Igor,
The issues you mentioned in previous comments are fixed in this version.
Could please help to review it?

Thanks,
Gu

On 09/17/2014 09:23 AM, Gu Zheng wrote:

> Previously we use cpu_added_notifiers to register cpu hotplug notifier 
> callback
> which is not able to pass/handle errors, so we switch it to unified hotplug
> handler API which allows to pass errors and would allow to cancel device_add
> in case of error.
> Thanks very much for Igor's review and suggestion.
> 
> v3:
>  -deal with start-up cpus in pc_cpu_plug as Igor suggested.
> 
> v2:
>  -Add 3 new patches(5/7,6/7,7/7), delete original patch 5/5.
>   1/5-->1/7
>   2/5-->2/7
>   3/5-->3/7
>   4/5-->4/7
>  Patch 1/7:
>  -add errp argument to catch error.
>  -return error instead of aborting if cpu id is invalid.
>  -make acpi_cpu_plug_cb as a wrapper around AcpiCpuHotplug_add.
>  Patch 3/7:
>  -remove unused AcpiCpuHotplug_add directly.
>  Patch 5/7:
>  -switch the last user of cpu hotplug notifier to hotplug handler API, and
>   remove the unused cpu hotplug notify.
>  Patch 6/7:
>  -split the function rename (just cleanup) into single patch.
>  Patch 7/7:
>  -introduce help function acpi_set_local_sts to keep the bit setting in
>   one place.
> 
> Gu Zheng (7):
>   acpi/cpu: add cpu hotplug callback function to match hotplug_handler
> API
>   acpi:ich9: convert cpu hotplug handle to hotplug_handler API
>   acpi:piix4: convert cpu hotplug handle to hotplug_handler API
>   pc: add cpu hotplug handler to PC_MACHINE
>   pc: Update rtc_cmos in pc_cpu_plug
>   cpu-hotplug: rename function for better readability
>   acpi/cpu-hotplug: introduce help function to keep bit setting in one
> place
> 
>  hw/acpi/cpu_hotplug.c |   35 
>  hw/acpi/ich9.c|   18 --
>  hw/acpi/piix4.c   |   18 +++---
>  hw/i386/pc.c  |   51 
> +
>  include/hw/acpi/cpu_hotplug.h |7 +++--
>  include/hw/acpi/ich9.h|1 -
>  include/sysemu/sysemu.h   |3 --
>  qom/cpu.c |   10 
>  8 files changed, 69 insertions(+), 74 deletions(-)
> 





Re: [Qemu-devel] [PATCH V3 0/7] cpu/acpi: convert cpu hot plug to hotplug_handler API

2014-09-23 Thread Gu Zheng
ping...

On 09/17/2014 09:23 AM, Gu Zheng wrote:

> Previously we use cpu_added_notifiers to register cpu hotplug notifier 
> callback
> which is not able to pass/handle errors, so we switch it to unified hotplug
> handler API which allows to pass errors and would allow to cancel device_add
> in case of error.
> Thanks very much for Igor's review and suggestion.
> 
> v3:
>  -deal with start-up cpus in pc_cpu_plug as Igor suggested.
> 
> v2:
>  -Add 3 new patches(5/7,6/7,7/7), delete original patch 5/5.
>   1/5-->1/7
>   2/5-->2/7
>   3/5-->3/7
>   4/5-->4/7
>  Patch 1/7:
>  -add errp argument to catch error.
>  -return error instead of aborting if cpu id is invalid.
>  -make acpi_cpu_plug_cb as a wrapper around AcpiCpuHotplug_add.
>  Patch 3/7:
>  -remove unused AcpiCpuHotplug_add directly.
>  Patch 5/7:
>  -switch the last user of cpu hotplug notifier to hotplug handler API, and
>   remove the unused cpu hotplug notify.
>  Patch 6/7:
>  -split the function rename (just cleanup) into single patch.
>  Patch 7/7:
>  -introduce help function acpi_set_local_sts to keep the bit setting in
>   one place.
> 
> Gu Zheng (7):
>   acpi/cpu: add cpu hotplug callback function to match hotplug_handler
> API
>   acpi:ich9: convert cpu hotplug handle to hotplug_handler API
>   acpi:piix4: convert cpu hotplug handle to hotplug_handler API
>   pc: add cpu hotplug handler to PC_MACHINE
>   pc: Update rtc_cmos in pc_cpu_plug
>   cpu-hotplug: rename function for better readability
>   acpi/cpu-hotplug: introduce help function to keep bit setting in one
> place
> 
>  hw/acpi/cpu_hotplug.c |   35 
>  hw/acpi/ich9.c|   18 --
>  hw/acpi/piix4.c   |   18 +++---
>  hw/i386/pc.c  |   51 
> +
>  include/hw/acpi/cpu_hotplug.h |7 +++--
>  include/hw/acpi/ich9.h|1 -
>  include/sysemu/sysemu.h   |3 --
>  qom/cpu.c |   10 
>  8 files changed, 69 insertions(+), 74 deletions(-)
> 





Re: [Qemu-devel] [RFC PATCH 00/10] cpu: add device_add foo-x86_64-cpu and i386 cpu hot remove support

2014-08-18 Thread Gu Zheng
Hi Igor, Andreas,
Could you please help to review this series? Any comment is welcome.

Regards,
Gu
On 08/07/2014 12:53 PM, Gu Zheng wrote:

> This series is based on the previous patchset from Chen Fan:
> https://lists.nongnu.org/archive/html/qemu-devel/2014-05/msg02360.html
> https://lists.nongnu.org/archive/html/qemu-devel/2013-12/msg04266.html
> 
> Patch 1~3: add device_add foo-x86_64-cpu support
> These three patches try to make cpu hotplug with device_add, and make
> "-device foo-x86_64-cpu" available,also we can set apic-id
> property with command line, if without setting apic-id property,
> we offer the first unoccupied apic id as the default new apic id.
> When hotplug cpu with device_add, additional check of APIC ID will be
> done after cpu object initialization which was different from
> 'cpu_add' command that check 'ids' at the beginning.
> 
> Patch 4~10: add i386 cpu hot remove support
> Via implementing ACPI standard methods _EJ0 in ACPI table, after Guest
> OS remove one vCPU online, the fireware will store removed bitmap to
> QEMU, then QEMU could know to notify the assigned vCPU of exiting.
> Meanwhile, intruduce the QOM command 'device_del' to remove vCPU from
> QEMU itself.
> 
> Chen Fan (6):
>   cpu: introduce CpuTopoInfo structure for argument simplification
>   cpu: add device_add foo-x86_64-cpu support
>   x86: add x86_cpu_unrealizefn() for cpu apic remove
>   qom cpu: rename variable 'cpu_added_notifier' to
> 'cpu_hotplug_notifier'
>   i386: implement pc interface cpu_common_unrealizefn() in qom/cpu.c
>   cpu hotplug: implement function cpu_status_write() for vcpu ejection
> 
> Gu Zheng (4):
>   qom/cpu: move register_vmstate to common CPUClass.realizefn
>   i386: add cpu device_del support
>   qom cpu: add UNPLUG cpu notify support
>   cpus: reclaim allocated vCPU objects
> 
>  cpus.c|   44 
>  exec.c|   32 +
>  hw/acpi/cpu_hotplug.c |   55 +--
>  hw/acpi/ich9.c|   13 ++--
>  hw/acpi/piix4.c   |   21 +++---
>  hw/i386/acpi-dsdt-cpu-hotplug.dsl |6 ++-
>  hw/i386/kvm/apic.c|8 ++
>  hw/i386/pc.c  |2 +-
>  hw/intc/apic.c|   10 +++
>  hw/intc/apic_common.c |   26 ++-
>  include/hw/acpi/cpu_hotplug.h |   14 -
>  include/hw/acpi/ich9.h|2 +-
>  include/hw/cpu/icc_bus.h  |1 +
>  include/hw/i386/apic_internal.h   |3 +
>  include/qom/cpu.h |   12 +++
>  include/sysemu/kvm.h  |1 +
>  include/sysemu/sysemu.h   |2 +-
>  kvm-all.c |   57 +++-
>  qdev-monitor.c|1 +
>  qom/cpu.c |   29 +++--
>  target-i386/cpu-qom.h |1 +
>  target-i386/cpu.c |  138 
> -
>  target-i386/topology.h|   51 +
>  23 files changed, 464 insertions(+), 65 deletions(-)
> 





[Qemu-devel] [RFC V2 00/10] cpu: add device_add foo-x86_64-cpu and i386 cpu hot remove support

2014-08-27 Thread Gu Zheng
This series is based on the previous patchset from Chen Fan:
https://lists.nongnu.org/archive/html/qemu-devel/2014-05/msg02360.html
https://lists.nongnu.org/archive/html/qemu-devel/2013-12/msg04266.html

Patch 1~3: add device_add foo-x86_64-cpu support
These three patches try to make cpu hotplug with device_add, and make
"-device foo-x86_64-cpu" available,also we can set apic-id
property with command line, if without setting apic-id property,
we offer the first unoccupied apic id as the default new apic id.
When hotplug cpu with device_add, additional check of APIC ID will be
done after cpu object initialization which was different from
'cpu_add' command that check 'ids' at the beginning.

Patch 4~10: add i386 cpu hot remove support
Via implementing ACPI standard methods _EJ0 in ACPI table, after Guest
OS remove one vCPU online, the fireware will store removed bitmap to
QEMU, then QEMU could know to notify the assigned vCPU of exiting.
Meanwhile, intruduce the QOM command 'device_del' to remove vCPU from
QEMU itself.

v2:
 -fix the cpu index duplicated issue in the QMP/HMP command output.

Chen Fan (6):
  cpu: introduce CpuTopoInfo structure for argument simplification
  cpu: add device_add foo-x86_64-cpu support
  x86: add x86_cpu_unrealizefn() for cpu apic remove
  qom cpu: rename variable 'cpu_added_notifier' to
'cpu_hotplug_notifier'
  i386: implement pc interface cpu_common_unrealizefn() in qom/cpu.c
  cpu hotplug: implement function cpu_status_write() for vcpu ejection

Gu Zheng (4):
  qom/cpu: move register_vmstate to common CPUClass.realizefn
  i386: add cpu device_del support
  qom cpu: add UNPLUG cpu notify support
  cpus: reclaim allocated vCPU objects

 cpus.c|   48 +-
 exec.c|   32 +
 hw/acpi/cpu_hotplug.c |   55 +--
 hw/acpi/ich9.c|   13 ++--
 hw/acpi/piix4.c   |   21 +++---
 hw/i386/acpi-dsdt-cpu-hotplug.dsl |6 ++-
 hw/i386/kvm/apic.c|8 ++
 hw/i386/pc.c  |2 +-
 hw/intc/apic.c|   10 +++
 hw/intc/apic_common.c |   26 ++-
 include/hw/acpi/cpu_hotplug.h |   14 -
 include/hw/acpi/ich9.h|2 +-
 include/hw/cpu/icc_bus.h  |1 +
 include/hw/i386/apic_internal.h   |3 +
 include/qom/cpu.h |   12 +++
 include/sysemu/kvm.h  |1 +
 include/sysemu/sysemu.h   |2 +-
 kvm-all.c |   57 +++-
 monitor.c |4 +-
 qdev-monitor.c|1 +
 qom/cpu.c |   29 +++--
 target-i386/cpu-qom.h |1 +
 target-i386/cpu.c |  138 -
 target-i386/topology.h|   51 +
 24 files changed, 470 insertions(+), 67 deletions(-)

-- 
1.7.7




[Qemu-devel] [RFC V2 01/10] cpu: introduce CpuTopoInfo structure for argument simplification

2014-08-27 Thread Gu Zheng
From: Chen Fan 

Reviewed-by: Eduardo Habkost 
Signed-off-by: Chen Fan 
Signed-off-by: Gu Zheng 
---
 target-i386/topology.h |   33 +
 1 files changed, 17 insertions(+), 16 deletions(-)

diff --git a/target-i386/topology.h b/target-i386/topology.h
index 07a6c5f..e9ff89c 100644
--- a/target-i386/topology.h
+++ b/target-i386/topology.h
@@ -47,6 +47,12 @@
  */
 typedef uint32_t apic_id_t;
 
+typedef struct X86CPUTopoInfo {
+unsigned pkg_id;
+unsigned core_id;
+unsigned smt_id;
+} X86CPUTopoInfo;
+
 /* Return the bit width needed for 'count' IDs
  */
 static unsigned apicid_bitwidth_for_count(unsigned count)
@@ -92,13 +98,11 @@ static inline unsigned apicid_pkg_offset(unsigned nr_cores, 
unsigned nr_threads)
  */
 static inline apic_id_t apicid_from_topo_ids(unsigned nr_cores,
  unsigned nr_threads,
- unsigned pkg_id,
- unsigned core_id,
- unsigned smt_id)
+ const X86CPUTopoInfo *topo)
 {
-return (pkg_id  << apicid_pkg_offset(nr_cores, nr_threads)) |
-   (core_id << apicid_core_offset(nr_cores, nr_threads)) |
-   smt_id;
+return (topo->pkg_id  << apicid_pkg_offset(nr_cores, nr_threads)) |
+   (topo->core_id << apicid_core_offset(nr_cores, nr_threads)) |
+   topo->smt_id;
 }
 
 /* Calculate thread/core/package IDs for a specific topology,
@@ -107,14 +111,12 @@ static inline apic_id_t apicid_from_topo_ids(unsigned 
nr_cores,
 static inline void x86_topo_ids_from_idx(unsigned nr_cores,
  unsigned nr_threads,
  unsigned cpu_index,
- unsigned *pkg_id,
- unsigned *core_id,
- unsigned *smt_id)
+ X86CPUTopoInfo *topo)
 {
 unsigned core_index = cpu_index / nr_threads;
-*smt_id = cpu_index % nr_threads;
-*core_id = core_index % nr_cores;
-*pkg_id = core_index / nr_cores;
+topo->smt_id = cpu_index % nr_threads;
+topo->core_id = core_index % nr_cores;
+topo->pkg_id = core_index / nr_cores;
 }
 
 /* Make APIC ID for the CPU 'cpu_index'
@@ -125,10 +127,9 @@ static inline apic_id_t x86_apicid_from_cpu_idx(unsigned 
nr_cores,
 unsigned nr_threads,
 unsigned cpu_index)
 {
-unsigned pkg_id, core_id, smt_id;
-x86_topo_ids_from_idx(nr_cores, nr_threads, cpu_index,
-  &pkg_id, &core_id, &smt_id);
-return apicid_from_topo_ids(nr_cores, nr_threads, pkg_id, core_id, smt_id);
+X86CPUTopoInfo topo;
+x86_topo_ids_from_idx(nr_cores, nr_threads, cpu_index, &topo);
+return apicid_from_topo_ids(nr_cores, nr_threads, &topo);
 }
 
 #endif /* TARGET_I386_TOPOLOGY_H */
-- 
1.7.7




[Qemu-devel] [RFC V2 05/10] i386: add cpu device_del support

2014-08-27 Thread Gu Zheng
In order to add cpu(i386) device_del support, introduce the cpu hot
unplug hanlde(x86_cpu_unplug) which will trigger the unrealize routine,
and just register it to the cpu class unplug handle.

Signed-off-by: Chen Fan 
Signed-off-by: Gu Zheng 
---
 target-i386/cpu.c |   22 ++
 1 files changed, 22 insertions(+), 0 deletions(-)

diff --git a/target-i386/cpu.c b/target-i386/cpu.c
index 72a94a6..dc5153e 100644
--- a/target-i386/cpu.c
+++ b/target-i386/cpu.c
@@ -2993,6 +2993,27 @@ static Property x86_cpu_properties[] = {
 DEFINE_PROP_END_OF_LIST()
 };
 
+static int x86_cpu_unplug(DeviceState *dev)
+{
+CPUState *cpu = CPU(dev);
+X86CPUClass *xcc;
+Error *err = NULL;
+
+if (cpu == first_cpu) {
+error_report("Can not remove the first cpu!\n");
+return -1;
+}
+
+xcc = X86_CPU_GET_CLASS(DEVICE(cpu));
+xcc->parent_unrealize(DEVICE(cpu), &err);
+if (err != NULL) {
+error_report("%s", error_get_pretty(err));
+error_free(err);
+return -1;
+}
+return 0;
+}
+
 static void x86_cpu_common_class_init(ObjectClass *oc, void *data)
 {
 X86CPUClass *xcc = X86_CPU_CLASS(oc);
@@ -3005,6 +3026,7 @@ static void x86_cpu_common_class_init(ObjectClass *oc, 
void *data)
 dc->unrealize = x86_cpu_unrealizefn;
 dc->bus_type = TYPE_ICC_BUS;
 dc->props = x86_cpu_properties;
+dc->unplug = x86_cpu_unplug;
 
 xcc->parent_reset = cc->reset;
 cc->reset = x86_cpu_reset;
-- 
1.7.7




[Qemu-devel] [RFC V2 06/10] qom cpu: rename variable 'cpu_added_notifier' to 'cpu_hotplug_notifier'

2014-08-27 Thread Gu Zheng
From: Chen Fan 

Rename variable 'cpu_added_notifier' to 'cpu_hotplug_notifier' for
adding remove vcpu notifier support.

Signed-off-by: Chen Fan 
Signed-off-by: Gu Zheng 
---
 hw/acpi/ich9.c  |8 
 hw/acpi/piix4.c |   10 +-
 hw/i386/pc.c|2 +-
 include/hw/acpi/ich9.h  |2 +-
 include/sysemu/sysemu.h |2 +-
 qom/cpu.c   |   10 +-
 6 files changed, 17 insertions(+), 17 deletions(-)

diff --git a/hw/acpi/ich9.c b/hw/acpi/ich9.c
index 7b14bbb..804f774 100644
--- a/hw/acpi/ich9.c
+++ b/hw/acpi/ich9.c
@@ -209,9 +209,9 @@ static void pm_powerdown_req(Notifier *n, void *opaque)
 acpi_pm1_evt_power_down(&pm->acpi_regs);
 }
 
-static void ich9_cpu_added_req(Notifier *n, void *opaque)
+static void ich9_cpu_hotplug_req(Notifier *n, void *opaque)
 {
-ICH9LPCPMRegs *pm = container_of(n, ICH9LPCPMRegs, cpu_added_notifier);
+ICH9LPCPMRegs *pm = container_of(n, ICH9LPCPMRegs, cpu_hotplug_notifier);
 
 assert(pm != NULL);
 AcpiCpuHotplug_add(&pm->acpi_regs.gpe, &pm->gpe_cpu, CPU(opaque));
@@ -246,8 +246,8 @@ void ich9_pm_init(PCIDevice *lpc_pci, ICH9LPCPMRegs *pm,
 
 AcpiCpuHotplug_init(pci_address_space_io(lpc_pci), OBJECT(lpc_pci),
 &pm->gpe_cpu, ICH9_CPU_HOTPLUG_IO_BASE);
-pm->cpu_added_notifier.notify = ich9_cpu_added_req;
-qemu_register_cpu_added_notifier(&pm->cpu_added_notifier);
+pm->cpu_hotplug_notifier.notify = ich9_cpu_hotplug_req;
+qemu_register_cpu_hotplug_notifier(&pm->cpu_hotplug_notifier);
 
 if (pm->acpi_memory_hotplug.is_enabled) {
 acpi_memory_hotplug_init(pci_address_space_io(lpc_pci), 
OBJECT(lpc_pci),
diff --git a/hw/acpi/piix4.c b/hw/acpi/piix4.c
index b72b34e..5cd6300 100644
--- a/hw/acpi/piix4.c
+++ b/hw/acpi/piix4.c
@@ -83,7 +83,7 @@ typedef struct PIIX4PMState {
 uint8_t s4_val;
 
 AcpiCpuHotplug gpe_cpu;
-Notifier cpu_added_notifier;
+Notifier cpu_hotplug_notifier;
 
 MemHotplugState acpi_memory_hotplug;
 } PIIX4PMState;
@@ -544,9 +544,9 @@ static const MemoryRegionOps piix4_gpe_ops = {
 .endianness = DEVICE_LITTLE_ENDIAN,
 };
 
-static void piix4_cpu_added_req(Notifier *n, void *opaque)
+static void piix4_cpu_hotplug(Notifier *n, void *opaque)
 {
-PIIX4PMState *s = container_of(n, PIIX4PMState, cpu_added_notifier);
+PIIX4PMState *s = container_of(n, PIIX4PMState, cpu_hotplug_notifier);
 
 assert(s != NULL);
 AcpiCpuHotplug_add(&s->ar.gpe, &s->gpe_cpu, CPU(opaque));
@@ -565,8 +565,8 @@ static void piix4_acpi_system_hot_add_init(MemoryRegion 
*parent,
 
 AcpiCpuHotplug_init(parent, OBJECT(s), &s->gpe_cpu,
 PIIX4_CPU_HOTPLUG_IO_BASE);
-s->cpu_added_notifier.notify = piix4_cpu_added_req;
-qemu_register_cpu_added_notifier(&s->cpu_added_notifier);
+s->cpu_hotplug_notifier.notify = piix4_cpu_hotplug;
+qemu_register_cpu_hotplug_notifier(&s->cpu_hotplug_notifier);
 
 if (s->acpi_memory_hotplug.is_enabled) {
 acpi_memory_hotplug_init(parent, OBJECT(s), &s->acpi_memory_hotplug);
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 8fa8d2f..1b26985 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -413,7 +413,7 @@ void pc_cmos_init(ram_addr_t ram_size, ram_addr_t 
above_4g_mem_size,
 /* init CPU hotplug notifier */
 cpu_hotplug_cb.rtc_state = s;
 cpu_hotplug_cb.cpu_added_notifier.notify = rtc_notify_cpu_added;
-qemu_register_cpu_added_notifier(&cpu_hotplug_cb.cpu_added_notifier);
+qemu_register_cpu_hotplug_notifier(&cpu_hotplug_cb.cpu_added_notifier);
 
 if (set_boot_dev(s, boot_device)) {
 exit(1);
diff --git a/include/hw/acpi/ich9.h b/include/hw/acpi/ich9.h
index 7e42448..bbb5d2c 100644
--- a/include/hw/acpi/ich9.h
+++ b/include/hw/acpi/ich9.h
@@ -47,7 +47,7 @@ typedef struct ICH9LPCPMRegs {
 Notifier powerdown_notifier;
 
 AcpiCpuHotplug gpe_cpu;
-Notifier cpu_added_notifier;
+Notifier cpu_hotplug_notifier;
 
 MemHotplugState acpi_memory_hotplug;
 } ICH9LPCPMRegs;
diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h
index d8539fd..6810f70 100644
--- a/include/sysemu/sysemu.h
+++ b/include/sysemu/sysemu.h
@@ -184,7 +184,7 @@ void do_pci_device_hot_remove(Monitor *mon, const QDict 
*qdict);
 void drive_hot_add(Monitor *mon, const QDict *qdict);
 
 /* CPU hotplug */
-void qemu_register_cpu_added_notifier(Notifier *notifier);
+void qemu_register_cpu_hotplug_notifier(Notifier *notifier);
 
 /* pcie aer error injection */
 void pcie_aer_inject_error_print(Monitor *mon, const QObject *data);
diff --git a/qom/cpu.c b/qom/cpu.c
index bf16590..add92b1 100644
--- a/qom/cpu.c
+++ b/qom/cpu.c
@@ -108,12 +108,12 @@ static void cpu_common_get_memory_mapping(CPUState *cpu,
 }
 
 /* CPU hot-plug notifiers */
-static NotifierList cpu_added_notifiers =
-NOTIFIER_LIST_INITIALIZ

[Qemu-devel] [RFC V2 04/10] x86: add x86_cpu_unrealizefn() for cpu apic remove

2014-08-27 Thread Gu Zheng
From: Chen Fan 

Implement x86_cpu_unrealizefn() for corresponding x86_cpu_realizefn(),
which is mostly used to clean the apic related allocation and vmstates
at here.

Signed-off-by: Chen Fan 
Signed-off-by: Gu Zheng 
---
 hw/i386/kvm/apic.c  |8 +++
 hw/intc/apic.c  |   10 
 hw/intc/apic_common.c   |   23 +++-
 include/hw/cpu/icc_bus.h|1 +
 include/hw/i386/apic_internal.h |1 +
 target-i386/cpu-qom.h   |1 +
 target-i386/cpu.c   |   45 +++
 7 files changed, 88 insertions(+), 1 deletions(-)

diff --git a/hw/i386/kvm/apic.c b/hw/i386/kvm/apic.c
index e873b50..c95fb8a 100644
--- a/hw/i386/kvm/apic.c
+++ b/hw/i386/kvm/apic.c
@@ -183,11 +183,19 @@ static void kvm_apic_realize(DeviceState *dev, Error 
**errp)
 }
 }
 
+static void kvm_apic_unrealize(DeviceState *dev, Error **errp)
+{
+APICCommonState *s = APIC_COMMON(dev);
+
+object_unparent(OBJECT(&s->io_memory));
+}
+
 static void kvm_apic_class_init(ObjectClass *klass, void *data)
 {
 APICCommonClass *k = APIC_COMMON_CLASS(klass);
 
 k->realize = kvm_apic_realize;
+k->unrealize = kvm_apic_unrealize;
 k->set_base = kvm_apic_set_base;
 k->set_tpr = kvm_apic_set_tpr;
 k->get_tpr = kvm_apic_get_tpr;
diff --git a/hw/intc/apic.c b/hw/intc/apic.c
index 03ff9e9..6d38965 100644
--- a/hw/intc/apic.c
+++ b/hw/intc/apic.c
@@ -885,11 +885,21 @@ static void apic_realize(DeviceState *dev, Error **errp)
 msi_supported = true;
 }
 
+static void apic_unrealize(DeviceState *dev, Error **errp)
+{
+APICCommonState *s = APIC_COMMON(dev);
+
+object_unparent(OBJECT(&s->io_memory));
+timer_free(s->timer);
+local_apics[s->idx] = NULL;
+}
+
 static void apic_class_init(ObjectClass *klass, void *data)
 {
 APICCommonClass *k = APIC_COMMON_CLASS(klass);
 
 k->realize = apic_realize;
+k->unrealize = apic_unrealize;
 k->set_base = apic_set_base;
 k->set_tpr = apic_set_tpr;
 k->get_tpr = apic_get_tpr;
diff --git a/hw/intc/apic_common.c b/hw/intc/apic_common.c
index 029f67d..8d17be1 100644
--- a/hw/intc/apic_common.c
+++ b/hw/intc/apic_common.c
@@ -289,12 +289,13 @@ static int apic_load_old(QEMUFile *f, void *opaque, int 
version_id)
 return 0;
 }
 
+static int apic_no;
+
 static void apic_common_realize(DeviceState *dev, Error **errp)
 {
 APICCommonState *s = APIC_COMMON(dev);
 APICCommonClass *info;
 static DeviceState *vapic;
-static int apic_no;
 static bool mmio_registered;
 
 if (apic_no >= MAX_APICS) {
@@ -324,6 +325,25 @@ static void apic_common_realize(DeviceState *dev, Error 
**errp)
 
 }
 
+static void apic_common_unrealize(DeviceState *dev, Error **errp)
+{
+APICCommonState *s = APIC_COMMON(dev);
+APICCommonClass *info = APIC_COMMON_GET_CLASS(s);
+
+if (apic_no <= 0) {
+error_setg(errp, "%s exit failed.",
+   object_get_typename(OBJECT(dev)));
+return;
+}
+apic_no--;
+
+info->unrealize(dev, errp);
+
+if (apic_report_tpr_access && info->enable_tpr_reporting) {
+info->enable_tpr_reporting(s, false);
+}
+}
+
 static void apic_dispatch_pre_save(void *opaque)
 {
 APICCommonState *s = APIC_COMMON(opaque);
@@ -394,6 +414,7 @@ static void apic_common_class_init(ObjectClass *klass, void 
*data)
 dc->reset = apic_reset_common;
 dc->props = apic_properties_common;
 idc->realize = apic_common_realize;
+idc->unrealize = apic_common_unrealize;
 /*
  * Reason: APIC and CPU need to be wired up by
  * x86_cpu_apic_create()
diff --git a/include/hw/cpu/icc_bus.h b/include/hw/cpu/icc_bus.h
index 98a979f..75ed309 100644
--- a/include/hw/cpu/icc_bus.h
+++ b/include/hw/cpu/icc_bus.h
@@ -67,6 +67,7 @@ typedef struct ICCDeviceClass {
 /*< public >*/
 
 DeviceRealize realize;
+DeviceUnrealize unrealize;
 } ICCDeviceClass;
 
 #define TYPE_ICC_DEVICE "icc-device"
diff --git a/include/hw/i386/apic_internal.h b/include/hw/i386/apic_internal.h
index 2c91609..6c9e390 100644
--- a/include/hw/i386/apic_internal.h
+++ b/include/hw/i386/apic_internal.h
@@ -82,6 +82,7 @@ typedef struct APICCommonClass
 ICCDeviceClass parent_class;
 
 DeviceRealize realize;
+DeviceUnrealize unrealize;
 void (*set_base)(APICCommonState *s, uint64_t val);
 void (*set_tpr)(APICCommonState *s, uint8_t val);
 uint8_t (*get_tpr)(APICCommonState *s);
diff --git a/target-i386/cpu-qom.h b/target-i386/cpu-qom.h
index 71a1b97..2239105 100644
--- a/target-i386/cpu-qom.h
+++ b/target-i386/cpu-qom.h
@@ -65,6 +65,7 @@ typedef struct X86CPUClass {
 bool kvm_required;
 
 DeviceRealize parent_realize;
+DeviceUnrealize parent_unrealize;
 void (*parent_reset)(CPUState *cpu);
 } X86CPUClass;
 
diff --git a/target-i386/cpu.c b/target-i386/cpu.c
in

[Qemu-devel] [RFC V2 07/10] qom cpu: add UNPLUG cpu notify support

2014-08-27 Thread Gu Zheng
Introduce a common cpu hotplug notifier(CPUNotifier)
to support UNPLUG cpu notify.

Signed-off-by: Gu Zheng 
Signed-off-by: Chen Fan 
---
 hw/acpi/cpu_hotplug.c |   15 +++
 hw/acpi/ich9.c|5 -
 hw/acpi/piix4.c   |   11 +++
 include/hw/acpi/cpu_hotplug.h |   13 -
 qom/cpu.c |7 ++-
 5 files changed, 40 insertions(+), 11 deletions(-)

diff --git a/hw/acpi/cpu_hotplug.c b/hw/acpi/cpu_hotplug.c
index 2ad83a0..56cb316 100644
--- a/hw/acpi/cpu_hotplug.c
+++ b/hw/acpi/cpu_hotplug.c
@@ -36,15 +36,22 @@ static const MemoryRegionOps AcpiCpuHotplug_ops = {
 },
 };
 
-void AcpiCpuHotplug_add(ACPIGPE *gpe, AcpiCpuHotplug *g, CPUState *cpu)
+void AcpiCpuHotplug_handle(ACPIGPE *gpe, AcpiCpuHotplug *g,
+   CPUNotifier *notify)
 {
-CPUClass *k = CPU_GET_CLASS(cpu);
+CPUClass *k = CPU_GET_CLASS(notify->dev);
+HotplugEventType type = notify->type;
 int64_t cpu_id;
 
 *gpe->sts = *gpe->sts | ACPI_CPU_HOTPLUG_STATUS;
-cpu_id = k->get_arch_id(CPU(cpu));
+cpu_id = k->get_arch_id(CPU(notify->dev));
 g_assert((cpu_id / 8) < ACPI_GPE_PROC_LEN);
-g->sts[cpu_id / 8] |= (1 << (cpu_id % 8));
+
+if (type == PLUG) {
+g->sts[cpu_id / 8] |= (1 << (cpu_id % 8));
+} else {
+g->sts[cpu_id / 8] &= ~(1 << (cpu_id % 8));
+}
 }
 
 void AcpiCpuHotplug_init(MemoryRegion *parent, Object *owner,
diff --git a/hw/acpi/ich9.c b/hw/acpi/ich9.c
index 804f774..2db491d 100644
--- a/hw/acpi/ich9.c
+++ b/hw/acpi/ich9.c
@@ -212,9 +212,12 @@ static void pm_powerdown_req(Notifier *n, void *opaque)
 static void ich9_cpu_hotplug_req(Notifier *n, void *opaque)
 {
 ICH9LPCPMRegs *pm = container_of(n, ICH9LPCPMRegs, cpu_hotplug_notifier);
+CPUNotifier *notifier = (CPUNotifier *)opaque;
 
 assert(pm != NULL);
-AcpiCpuHotplug_add(&pm->acpi_regs.gpe, &pm->gpe_cpu, CPU(opaque));
+
+AcpiCpuHotplug_handle(&pm->acpi_regs.gpe, &pm->gpe_cpu, notifier);
+
 acpi_update_sci(&pm->acpi_regs, pm->irq);
 }
 
diff --git a/hw/acpi/piix4.c b/hw/acpi/piix4.c
index 5cd6300..cc15b60 100644
--- a/hw/acpi/piix4.c
+++ b/hw/acpi/piix4.c
@@ -93,7 +93,7 @@ typedef struct PIIX4PMState {
 #define PIIX4_PM(obj) \
 OBJECT_CHECK(PIIX4PMState, (obj), TYPE_PIIX4_PM)
 
-static void piix4_acpi_system_hot_add_init(MemoryRegion *parent,
+static void piix4_acpi_system_hotplug_init(MemoryRegion *parent,
PCIBus *bus, PIIX4PMState *s);
 
 #define ACPI_ENABLE 0xf1
@@ -465,7 +465,7 @@ static int piix4_pm_initfn(PCIDevice *dev)
 qemu_add_machine_init_done_notifier(&s->machine_ready);
 qemu_register_reset(piix4_reset, s);
 
-piix4_acpi_system_hot_add_init(pci_address_space_io(dev), dev->bus, s);
+piix4_acpi_system_hotplug_init(pci_address_space_io(dev), dev->bus, s);
 
 piix4_pm_add_propeties(s);
 return 0;
@@ -547,13 +547,16 @@ static const MemoryRegionOps piix4_gpe_ops = {
 static void piix4_cpu_hotplug(Notifier *n, void *opaque)
 {
 PIIX4PMState *s = container_of(n, PIIX4PMState, cpu_hotplug_notifier);
+CPUNotifier *notifier = (CPUNotifier *)opaque;
 
 assert(s != NULL);
-AcpiCpuHotplug_add(&s->ar.gpe, &s->gpe_cpu, CPU(opaque));
+
+AcpiCpuHotplug_handle(&s->ar.gpe, &s->gpe_cpu, notifier);
+
 acpi_update_sci(&s->ar, s->irq);
 }
 
-static void piix4_acpi_system_hot_add_init(MemoryRegion *parent,
+static void piix4_acpi_system_hotplug_init(MemoryRegion *parent,
PCIBus *bus, PIIX4PMState *s)
 {
 memory_region_init_io(&s->io_gpe, OBJECT(s), &piix4_gpe_ops, s,
diff --git a/include/hw/acpi/cpu_hotplug.h b/include/hw/acpi/cpu_hotplug.h
index 9e5d30c..4fe0066 100644
--- a/include/hw/acpi/cpu_hotplug.h
+++ b/include/hw/acpi/cpu_hotplug.h
@@ -15,12 +15,23 @@
 #include "hw/acpi/acpi.h"
 #include "hw/acpi/pc-hotplug.h"
 
+typedef enum {
+PLUG,
+UNPLUG,
+} HotplugEventType;
+
+typedef struct CPUNotifier {
+DeviceState *dev;
+HotplugEventType type;
+} CPUNotifier;
+
 typedef struct AcpiCpuHotplug {
 MemoryRegion io;
 uint8_t sts[ACPI_GPE_PROC_LEN];
 } AcpiCpuHotplug;
 
-void AcpiCpuHotplug_add(ACPIGPE *gpe, AcpiCpuHotplug *g, CPUState *cpu);
+void AcpiCpuHotplug_handle(ACPIGPE *gpe, AcpiCpuHotplug *g,
+   CPUNotifier *notify);
 
 void AcpiCpuHotplug_init(MemoryRegion *parent, Object *owner,
  AcpiCpuHotplug *gpe_cpu, uint16_t base);
diff --git a/qom/cpu.c b/qom/cpu.c
index add92b1..f921282 100644
--- a/qom/cpu.c
+++ b/qom/cpu.c
@@ -25,6 +25,7 @@
 #include "qemu/log.h"
 #include "qemu/error-report.h"
 #include "sysemu/sysemu.h"
+#include "hw/acpi/cpu_hotplug.h"
 
 bool cpu_exists(int

[Qemu-devel] [RFC V2 03/10] cpu: add device_add foo-x86_64-cpu support

2014-08-27 Thread Gu Zheng
From: Chen Fan 

Add support to device_add foo-x86_64-cpu, and additional checks of
apic id are added into x86_cpuid_set_apic_id() and x86_cpu_apic_create()
for duplicate. Besides, in order to support "device/device_add foo-x86_64-cpu"
which without specified apic id, we add a new function get_free_apic_id() to
provide the first free apid id each time to avoid apic id duplicate.

Signed-off-by: Chen Fan 
Signed-off-by: Gu Zheng 
---
 include/qom/cpu.h  |1 +
 qdev-monitor.c |1 +
 target-i386/cpu.c  |   61 +++-
 target-i386/topology.h |   18 ++
 4 files changed, 80 insertions(+), 1 deletions(-)

diff --git a/include/qom/cpu.h b/include/qom/cpu.h
index bc32c9a..2fc00ef 100644
--- a/include/qom/cpu.h
+++ b/include/qom/cpu.h
@@ -292,6 +292,7 @@ struct CPUState {
 QTAILQ_HEAD(CPUTailQ, CPUState);
 extern struct CPUTailQ cpus;
 #define CPU_NEXT(cpu) QTAILQ_NEXT(cpu, node)
+#define CPU_REMOVE(cpu) QTAILQ_REMOVE(&cpus, cpu, node)
 #define CPU_FOREACH(cpu) QTAILQ_FOREACH(cpu, &cpus, node)
 #define CPU_FOREACH_SAFE(cpu, next_cpu) \
 QTAILQ_FOREACH_SAFE(cpu, &cpus, node, next_cpu)
diff --git a/qdev-monitor.c b/qdev-monitor.c
index fb9ee24..1aa446d 100644
--- a/qdev-monitor.c
+++ b/qdev-monitor.c
@@ -24,6 +24,7 @@
 #include "qmp-commands.h"
 #include "sysemu/arch_init.h"
 #include "qemu/config-file.h"
+#include "qom/object_interfaces.h"
 
 /*
  * Aliases were a bad idea from the start.  Let's keep them
diff --git a/target-i386/cpu.c b/target-i386/cpu.c
index 2aa2b31..5255ddb 100644
--- a/target-i386/cpu.c
+++ b/target-i386/cpu.c
@@ -49,6 +49,7 @@
 #include "hw/i386/apic_internal.h"
 #endif
 
+#include "qom/object_interfaces.h"
 
 /* Cache topology CPUID constants: */
 
@@ -1634,6 +1635,7 @@ static void x86_cpuid_set_apic_id(Object *obj, Visitor 
*v, void *opaque,
 const int64_t max = UINT32_MAX;
 Error *error = NULL;
 int64_t value;
+X86CPUTopoInfo topo;
 
 if (dev->realized) {
 error_setg(errp, "Attempt to set property '%s' on '%s' after "
@@ -1653,6 +1655,19 @@ static void x86_cpuid_set_apic_id(Object *obj, Visitor 
*v, void *opaque,
 return;
 }
 
+if (value > x86_cpu_apic_id_from_index(max_cpus - 1)) {
+error_setg(errp, "CPU with APIC ID %" PRIi64
+   " is more than MAX APIC ID limits", value);
+return;
+}
+
+x86_topo_ids_from_apic_id(smp_cores, smp_threads, value, &topo);
+if (topo.smt_id >= smp_threads || topo.core_id >= smp_cores) {
+error_setg(errp, "CPU with APIC ID %" PRIi64 " does not match "
+   "topology configuration.", value);
+return;
+}
+
 if ((value != cpu->env.cpuid_apic_id) && cpu_exists(value)) {
 error_setg(errp, "CPU with APIC ID %" PRIi64 " exists", value);
 return;
@@ -2096,12 +2111,21 @@ out:
 return cpu;
 }
 
+static void x86_cpu_cpudef_instance_init(Object *obj)
+{
+DeviceState *dev = DEVICE(obj);
+
+dev->hotplugged = true;
+}
+
 static void x86_cpu_cpudef_class_init(ObjectClass *oc, void *data)
 {
 X86CPUDefinition *cpudef = data;
 X86CPUClass *xcc = X86_CPU_CLASS(oc);
+DeviceClass *dc = DEVICE_CLASS(oc);
 
 xcc->cpu_def = cpudef;
+dc->cannot_instantiate_with_device_add_yet = false;
 }
 
 static void x86_register_cpudef_type(X86CPUDefinition *def)
@@ -2110,6 +2134,8 @@ static void x86_register_cpudef_type(X86CPUDefinition 
*def)
 TypeInfo ti = {
 .name = typename,
 .parent = TYPE_X86_CPU,
+.instance_size = sizeof(X86CPU),
+.instance_init = x86_cpu_cpudef_instance_init,
 .class_init = x86_cpu_cpudef_class_init,
 .class_data = def,
 };
@@ -2652,6 +2678,14 @@ static void x86_cpu_apic_create(X86CPU *cpu, Error 
**errp)
 return;
 }
 
+if (env->cpuid_apic_id > x86_cpu_apic_id_from_index(max_cpus - 1)) {
+error_setg(errp, "CPU with APIC ID %" PRIi32
+" is more than MAX APIC ID:%" PRIi32,
+env->cpuid_apic_id,
+x86_cpu_apic_id_from_index(max_cpus - 1));
+return;
+}
+
 object_property_add_child(OBJECT(cpu), "apic",
   OBJECT(cpu->apic_state), NULL);
 qdev_prop_set_uint8(cpu->apic_state, "id", env->cpuid_apic_id);
@@ -2777,6 +2811,21 @@ uint32_t x86_cpu_apic_id_from_index(unsigned int 
cpu_index)
 }
 }
 
+static uint32_t get_free_apic_id(void)
+{
+int i;
+
+for (i = 0; i < max_cpus; i++) {
+uint32_t id = x86_cpu_apic_id_from_index(i);
+
+if (!cpu_exists(id)) {
+return id;
+}
+}
+
+return x86_cpu_apic_id_from_index(max_cpus

[Qemu-devel] [RFC V2 08/10] i386: implement pc interface cpu_common_unrealizefn() in qom/cpu.c

2014-08-27 Thread Gu Zheng
From: Chen Fan 

add interface cpu_common_unrealizefn() for emiting vcpu unplug
notifier to ACPI, then ACPI could send sci interrupt
to OS for hot-remove vcpu.

Signed-off-by: Chen Fan 
Signed-off-by: Gu Zheng 
---
 qom/cpu.c |   12 
 1 files changed, 12 insertions(+), 0 deletions(-)

diff --git a/qom/cpu.c b/qom/cpu.c
index f921282..8bb2b4f 100644
--- a/qom/cpu.c
+++ b/qom/cpu.c
@@ -315,6 +315,17 @@ static void cpu_common_realizefn(DeviceState *dev, Error 
**errp)
 }
 }
 
+static void cpu_common_unrealizefn(DeviceState *dev, Error **errp)
+{
+CPUNotifier notifier;
+
+notifier.dev = dev;
+notifier.type = UNPLUG;
+
+notifier_list_notify(&cpu_hotplug_notifiers, ¬ifier);
+}
+
+
 static void cpu_common_initfn(Object *obj)
 {
 CPUState *cpu = CPU(obj);
@@ -348,6 +359,7 @@ static void cpu_class_init(ObjectClass *klass, void *data)
 k->gdb_write_register = cpu_common_gdb_write_register;
 k->virtio_is_big_endian = cpu_common_virtio_is_big_endian;
 dc->realize = cpu_common_realizefn;
+dc->unrealize = cpu_common_unrealizefn;
 /*
  * Reason: CPUs still need special care by board code: wiring up
  * IRQs, adding reset handlers, halting non-first CPUs, ...
-- 
1.7.7




[Qemu-devel] [RFC V2 09/10] cpu hotplug: implement function cpu_status_write() for vcpu ejection

2014-08-27 Thread Gu Zheng
From: Chen Fan 

When OS ejected a vcpu (like: echo 1 > /sys/bus/acpi/devices/LNXCPUXX/eject),
it would call acpi EJ0 method, the firmware need to write the new cpumap, QEMU
would know which vcpu need to be ejected.

TODO:
-confirm the hotplug result via OST if guest support it.

Signed-off-by: Chen Fan 
Signed-off-by: Gu Zheng 
---
 cpus.c|7 ++
 hw/acpi/cpu_hotplug.c |   40 -
 hw/i386/acpi-dsdt-cpu-hotplug.dsl |6 -
 include/hw/acpi/cpu_hotplug.h |1 +
 include/qom/cpu.h |9 
 5 files changed, 61 insertions(+), 2 deletions(-)

diff --git a/cpus.c b/cpus.c
index cce2744..eee693b 100644
--- a/cpus.c
+++ b/cpus.c
@@ -1182,6 +1182,13 @@ void resume_all_vcpus(void)
 }
 }
 
+void cpu_remove(CPUState *cpu)
+{
+cpu->stop = true;
+cpu->exit = true;
+qemu_cpu_kick(cpu);
+}
+
 /* For temporary buffers for forming a name */
 #define VCPU_THREAD_NAME_SIZE 16
 
diff --git a/hw/acpi/cpu_hotplug.c b/hw/acpi/cpu_hotplug.c
index 56cb316..7cbce69 100644
--- a/hw/acpi/cpu_hotplug.c
+++ b/hw/acpi/cpu_hotplug.c
@@ -20,10 +20,46 @@ static uint64_t cpu_status_read(void *opaque, hwaddr addr, 
unsigned int size)
 return val;
 }
 
+static void acpi_eject_vcpu(AcpiCpuHotplug *cpus_status, int64_t cpu_id)
+{
+CPUState *cpu;
+
+CPU_FOREACH(cpu) {
+CPUClass *cc = CPU_GET_CLASS(cpu);
+int64_t id = cc->get_arch_id(cpu);
+
+if (cpu_id == id) {
+cpus_status->old_sts[cpu_id / 8] &= ~(1 << (cpu_id % 8));
+cpus_status->sts[cpu_id / 8] &= ~(1 << (cpu_id % 8));
+cpu_remove(cpu);
+break;
+}
+}
+}
+
 static void cpu_status_write(void *opaque, hwaddr addr, uint64_t data,
  unsigned int size)
 {
-/* TODO: implement VCPU removal on guest signal that CPU can be removed */
+AcpiCpuHotplug *cpus = opaque;
+uint8_t val;
+int i;
+int64_t cpu_id = -1;
+
+val = cpus->old_sts[addr] ^ data;
+
+if (val == 0) {
+return;
+}
+
+for (i = 0; i < 8; i++) {
+if (val & 1 << i) {
+cpu_id = 8 * addr + i;
+}
+}
+
+if (cpu_id != -1) {
+acpi_eject_vcpu(cpus, cpu_id);
+}
 }
 
 static const MemoryRegionOps AcpiCpuHotplug_ops = {
@@ -49,6 +85,7 @@ void AcpiCpuHotplug_handle(ACPIGPE *gpe, AcpiCpuHotplug *g,
 
 if (type == PLUG) {
 g->sts[cpu_id / 8] |= (1 << (cpu_id % 8));
+g->old_sts[cpu_id / 8] |= (1 << (cpu_id % 8));
 } else {
 g->sts[cpu_id / 8] &= ~(1 << (cpu_id % 8));
 }
@@ -65,6 +102,7 @@ void AcpiCpuHotplug_init(MemoryRegion *parent, Object *owner,
 
 g_assert((id / 8) < ACPI_GPE_PROC_LEN);
 gpe_cpu->sts[id / 8] |= (1 << (id % 8));
+gpe_cpu->old_sts[id / 8] |= (1 << (id % 8));
 }
 memory_region_init_io(&gpe_cpu->io, owner, &AcpiCpuHotplug_ops,
   gpe_cpu, "acpi-cpu-hotplug", ACPI_GPE_PROC_LEN);
diff --git a/hw/i386/acpi-dsdt-cpu-hotplug.dsl 
b/hw/i386/acpi-dsdt-cpu-hotplug.dsl
index 34aab5a..9485f12 100644
--- a/hw/i386/acpi-dsdt-cpu-hotplug.dsl
+++ b/hw/i386/acpi-dsdt-cpu-hotplug.dsl
@@ -50,7 +50,11 @@ Scope(\_SB) {
 }
 Method(CPEJ, 2, NotSerialized) {
 // _EJ0 method - eject callback
-Sleep(200)
+Store(Zero, Index(CPON, ToInteger(Arg0)))
+Store(One, Local0)
+ShiftLeft(Local0, Arg0, Local0)
+Not(Local0, Local0)
+And(PRS, Local0, PRS)
 }
 
 #define CPU_STATUS_LEN ACPI_GPE_PROC_LEN
diff --git a/include/hw/acpi/cpu_hotplug.h b/include/hw/acpi/cpu_hotplug.h
index 4fe0066..3bffc69 100644
--- a/include/hw/acpi/cpu_hotplug.h
+++ b/include/hw/acpi/cpu_hotplug.h
@@ -28,6 +28,7 @@ typedef struct CPUNotifier {
 typedef struct AcpiCpuHotplug {
 MemoryRegion io;
 uint8_t sts[ACPI_GPE_PROC_LEN];
+uint8_t old_sts[ACPI_GPE_PROC_LEN];
 } AcpiCpuHotplug;
 
 void AcpiCpuHotplug_handle(ACPIGPE *gpe, AcpiCpuHotplug *g,
diff --git a/include/qom/cpu.h b/include/qom/cpu.h
index 2fc00ef..9108dc6 100644
--- a/include/qom/cpu.h
+++ b/include/qom/cpu.h
@@ -236,6 +236,7 @@ struct CPUState {
 bool created;
 bool stop;
 bool stopped;
+bool exit;
 volatile sig_atomic_t exit_request;
 uint32_t interrupt_request;
 int singlestep_enabled;
@@ -600,6 +601,14 @@ void cpu_exit(CPUState *cpu);
 void cpu_resume(CPUState *cpu);
 
 /**
+ * cpu_remove:
+ * @cpu: The vCPU to remove.
+ *
+ * Requests the CPU @cpu to be removed.
+ */
+void cpu_remove(CPUState *cpu);
+
+/**
  * qemu_init_vcpu:
  * @cpu: The vCPU to initialize.
  *
-- 
1.7.7




[Qemu-devel] [RFC V2 10/10] cpus: reclaim allocated vCPU objects

2014-08-27 Thread Gu Zheng
After ACPI get a signal to eject a vCPU, the vCPU must be
removed from CPU list,before the vCPU really removed,  then
release the all related vCPU objects.
But we do not close KVM vcpu fd, just record it into a list, in
order to reuse it.

Signed-off-by: Chen Fan 
Signed-off-by: Gu Zheng 
---
 cpus.c   |   37 
 include/sysemu/kvm.h |1 +
 kvm-all.c|   57 +-
 3 files changed, 94 insertions(+), 1 deletions(-)

diff --git a/cpus.c b/cpus.c
index eee693b..0608b41 100644
--- a/cpus.c
+++ b/cpus.c
@@ -851,6 +851,24 @@ void async_run_on_cpu(CPUState *cpu, void (*func)(void 
*data), void *data)
 qemu_cpu_kick(cpu);
 }
 
+static void qemu_kvm_destroy_vcpu(CPUState *cpu)
+{
+CPU_REMOVE(cpu);
+
+if (kvm_destroy_vcpu(cpu) < 0) {
+fprintf(stderr, "kvm_destroy_vcpu failed.\n");
+exit(1);
+}
+
+object_unparent(OBJECT(cpu));
+}
+
+static void qemu_tcg_destroy_vcpu(CPUState *cpu)
+{
+CPU_REMOVE(cpu);
+object_unparent(OBJECT(cpu));
+}
+
 static void flush_queued_work(CPUState *cpu)
 {
 struct qemu_work_item *wi;
@@ -942,6 +960,11 @@ static void *qemu_kvm_cpu_thread_fn(void *arg)
 }
 }
 qemu_kvm_wait_io_event(cpu);
+if (cpu->exit && !cpu_can_run(cpu)) {
+qemu_kvm_destroy_vcpu(cpu);
+qemu_mutex_unlock(&qemu_global_mutex);
+return NULL;
+}
 }
 
 return NULL;
@@ -994,6 +1017,7 @@ static void tcg_exec_all(void);
 static void *qemu_tcg_cpu_thread_fn(void *arg)
 {
 CPUState *cpu = arg;
+CPUState *remove_cpu = NULL;
 
 qemu_tcg_init_cpu_signals();
 qemu_thread_get_self(cpu->thread);
@@ -1026,6 +1050,16 @@ static void *qemu_tcg_cpu_thread_fn(void *arg)
 }
 }
 qemu_tcg_wait_io_event();
+CPU_FOREACH(cpu) {
+if (cpu->exit && !cpu_can_run(cpu)) {
+remove_cpu = cpu;
+break;
+}
+}
+if (remove_cpu) {
+qemu_tcg_destroy_vcpu(remove_cpu);
+remove_cpu = NULL;
+}
 }
 
 return NULL;
@@ -1383,6 +1417,9 @@ static void tcg_exec_all(void)
 break;
 }
 } else if (cpu->stop || cpu->stopped) {
+if (cpu->exit) {
+next_cpu = CPU_NEXT(cpu);
+}
 break;
 }
 }
diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h
index 174ea36..88e2403 100644
--- a/include/sysemu/kvm.h
+++ b/include/sysemu/kvm.h
@@ -178,6 +178,7 @@ int kvm_has_intx_set_mask(void);
 
 int kvm_init_vcpu(CPUState *cpu);
 int kvm_cpu_exec(CPUState *cpu);
+int kvm_destroy_vcpu(CPUState *cpu);
 
 #ifdef NEED_CPU_H
 
diff --git a/kvm-all.c b/kvm-all.c
index 1402f4f..d0caeff 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -74,6 +74,12 @@ typedef struct KVMSlot
 
 typedef struct kvm_dirty_log KVMDirtyLog;
 
+struct KVMParkedVcpu {
+unsigned long vcpu_id;
+int kvm_fd;
+QLIST_ENTRY(KVMParkedVcpu) node;
+};
+
 struct KVMState
 {
 KVMSlot *slots;
@@ -108,6 +114,7 @@ struct KVMState
 QTAILQ_HEAD(msi_hashtab, KVMMSIRoute) msi_hashtab[KVM_MSI_HASHTAB_SIZE];
 bool direct_msi;
 #endif
+QLIST_HEAD(, KVMParkedVcpu) kvm_parked_vcpus;
 };
 
 KVMState *kvm_state;
@@ -226,6 +233,53 @@ static int kvm_set_user_memory_region(KVMState *s, KVMSlot 
*slot)
 return kvm_vm_ioctl(s, KVM_SET_USER_MEMORY_REGION, &mem);
 }
 
+int kvm_destroy_vcpu(CPUState *cpu)
+{
+KVMState *s = kvm_state;
+long mmap_size;
+struct KVMParkedVcpu *vcpu = NULL;
+int ret = 0;
+
+DPRINTF("kvm_destroy_vcpu\n");
+
+mmap_size = kvm_ioctl(s, KVM_GET_VCPU_MMAP_SIZE, 0);
+if (mmap_size < 0) {
+ret = mmap_size;
+DPRINTF("KVM_GET_VCPU_MMAP_SIZE failed\n");
+goto err;
+}
+
+ret = munmap(cpu->kvm_run, mmap_size);
+if (ret < 0) {
+goto err;
+}
+
+vcpu = g_malloc0(sizeof(*vcpu));
+vcpu->vcpu_id = kvm_arch_vcpu_id(cpu);
+vcpu->kvm_fd = cpu->kvm_fd;
+QLIST_INSERT_HEAD(&kvm_state->kvm_parked_vcpus, vcpu, node);
+err:
+return ret;
+}
+
+static int kvm_get_vcpu(KVMState *s, unsigned long vcpu_id)
+{
+struct KVMParkedVcpu *cpu;
+
+QLIST_FOREACH(cpu, &s->kvm_parked_vcpus, node) {
+if (cpu->vcpu_id == vcpu_id) {
+int kvm_fd;
+
+QLIST_REMOVE(cpu, node);
+kvm_fd = cpu->kvm_fd;
+g_free(cpu);
+return kvm_fd;
+}
+}
+
+return kvm_vm_ioctl(s, KVM_CREATE_VCPU, (void *)vcpu_id);
+}
+
 int kvm_init_vcpu(CPUState *cpu)
 {
 KVMState *s = kvm_state;
@@ -234,7 +288,7 @@ int kvm_init_vcpu(CPUState *cpu)
 
 DPRINTF("kvm_init_vcpu\n");
 
-ret = kvm_vm_ioctl(s, KVM_CREATE_VCPU, (void *)kvm_arch_vcpu_id(cpu));
+ret = kvm_get_vcpu(s, kvm_

[Qemu-devel] [RFC V2 02/10] qom/cpu: move register_vmstate to common CPUClass.realizefn

2014-08-27 Thread Gu Zheng
Move cpu vmstate register from cpu_exec_init into cpu_common_realizefn,
apic vmstate register into x86_cpu_apic_realize. And use the
cc->get_arch_id as the instance id that suggested by Igor to
fix the migration issue.
Besides, also use cc->get_arch_id as the cpu index of HMP/QMP command output to
fix the index duplicated issue when hotadd a hot-removed cpu.

v2:
 -fix the cpu index duplicated issue in the QMP/HMP command output.

Signed-off-by: Gu Zheng 
---
 cpus.c  |4 +++-
 exec.c  |   32 +++-
 hw/intc/apic_common.c   |3 +--
 include/hw/i386/apic_internal.h |2 ++
 include/qom/cpu.h   |2 ++
 monitor.c   |4 +++-
 qom/cpu.c   |2 ++
 target-i386/cpu.c   |   10 --
 8 files changed, 40 insertions(+), 19 deletions(-)

diff --git a/cpus.c b/cpus.c
index 2b5c0bd..cce2744 100644
--- a/cpus.c
+++ b/cpus.c
@@ -1394,6 +1394,7 @@ CpuInfoList *qmp_query_cpus(Error **errp)
 {
 CpuInfoList *head = NULL, *cur_item = NULL;
 CPUState *cpu;
+CPUClass *cc;
 
 CPU_FOREACH(cpu) {
 CpuInfoList *info;
@@ -1411,11 +1412,12 @@ CpuInfoList *qmp_query_cpus(Error **errp)
 CPUMIPSState *env = &mips_cpu->env;
 #endif
 
+cc = CPU_GET_CLASS(cpu);
 cpu_synchronize_state(cpu);
 
 info = g_malloc0(sizeof(*info));
 info->value = g_malloc0(sizeof(*info->value));
-info->value->CPU = cpu->cpu_index;
+info->value->CPU = cc->get_arch_id(cpu);
 info->value->current = (cpu == first_cpu);
 info->value->halted = cpu->halted;
 info->value->thread_id = cpu->thread_id;
diff --git a/exec.c b/exec.c
index 5f9857c..c514492 100644
--- a/exec.c
+++ b/exec.c
@@ -473,10 +473,28 @@ void tcg_cpu_address_space_init(CPUState *cpu, 
AddressSpace *as)
 }
 #endif
 
+void cpu_vmstate_register(CPUState *cpu)
+{
+CPUClass *cc = CPU_GET_CLASS(cpu);
+int cpu_index = cc->get_arch_id(cpu);
+
+if (qdev_get_vmsd(DEVICE(cpu)) == NULL) {
+vmstate_register(NULL, cpu_index, &vmstate_cpu_common, cpu);
+}
+#if defined(CPU_SAVE_VERSION) && !defined(CONFIG_USER_ONLY)
+register_savevm(NULL, "cpu", cpu_index, CPU_SAVE_VERSION,
+cpu_save, cpu_load, cpu->env_ptr);
+assert(cc->vmsd == NULL);
+assert(qdev_get_vmsd(DEVICE(cpu)) == NULL);
+#endif
+if (cc->vmsd != NULL) {
+vmstate_register(NULL, cpu_index, cc->vmsd, cpu);
+}
+}
+
 void cpu_exec_init(CPUArchState *env)
 {
 CPUState *cpu = ENV_GET_CPU(env);
-CPUClass *cc = CPU_GET_CLASS(cpu);
 CPUState *some_cpu;
 int cpu_index;
 
@@ -499,18 +517,6 @@ void cpu_exec_init(CPUArchState *env)
 #if defined(CONFIG_USER_ONLY)
 cpu_list_unlock();
 #endif
-if (qdev_get_vmsd(DEVICE(cpu)) == NULL) {
-vmstate_register(NULL, cpu_index, &vmstate_cpu_common, cpu);
-}
-#if defined(CPU_SAVE_VERSION) && !defined(CONFIG_USER_ONLY)
-register_savevm(NULL, "cpu", cpu_index, CPU_SAVE_VERSION,
-cpu_save, cpu_load, env);
-assert(cc->vmsd == NULL);
-assert(qdev_get_vmsd(DEVICE(cpu)) == NULL);
-#endif
-if (cc->vmsd != NULL) {
-vmstate_register(NULL, cpu_index, cc->vmsd, cpu);
-}
 }
 
 #if defined(TARGET_HAS_ICE)
diff --git a/hw/intc/apic_common.c b/hw/intc/apic_common.c
index ce3d903..029f67d 100644
--- a/hw/intc/apic_common.c
+++ b/hw/intc/apic_common.c
@@ -345,7 +345,7 @@ static int apic_dispatch_post_load(void *opaque, int 
version_id)
 return 0;
 }
 
-static const VMStateDescription vmstate_apic_common = {
+const VMStateDescription vmstate_apic_common = {
 .name = "apic",
 .version_id = 3,
 .minimum_version_id = 3,
@@ -391,7 +391,6 @@ static void apic_common_class_init(ObjectClass *klass, void 
*data)
 ICCDeviceClass *idc = ICC_DEVICE_CLASS(klass);
 DeviceClass *dc = DEVICE_CLASS(klass);
 
-dc->vmsd = &vmstate_apic_common;
 dc->reset = apic_reset_common;
 dc->props = apic_properties_common;
 idc->realize = apic_common_realize;
diff --git a/include/hw/i386/apic_internal.h b/include/hw/i386/apic_internal.h
index 83e2a42..2c91609 100644
--- a/include/hw/i386/apic_internal.h
+++ b/include/hw/i386/apic_internal.h
@@ -23,6 +23,7 @@
 #include "exec/memory.h"
 #include "hw/cpu/icc_bus.h"
 #include "qemu/timer.h"
+#include "migration/vmstate.h"
 
 /* APIC Local Vector Table */
 #define APIC_LVT_TIMER  0
@@ -136,6 +137,7 @@ typedef struct VAPICState {
 } QEMU_PACKED VAPICState;
 
 extern bool apic_report_tpr_access;
+extern const VMStateDescription vmstate_apic_common;
 
 void apic_report_irq_delivered(int delivered);
 bool apic_next_timer(APICCommonState *s, int64_t current_time);
diff --g

[Qemu-devel] [PATCH 0/5] cpu/acpi: convert cpu hot plug to hotplug_handler API

2014-09-03 Thread Gu Zheng

Gu Zheng (5):
  acpi/cpu: add cpu hotplug callback function to match hotplug_handler
API
  acpi:ich9: convert cpu hotplug handle to hotplug_handler API
  acpi:piix4: convert cpu hotplug handle to hotplug_handler API
  pc: add cpu hotplug handler to PC_MACHINE
  cpu/hotplug: remove the left unused cpu hotplug notifier function

 hw/acpi/cpu_hotplug.c |   18 --
 hw/acpi/ich9.c|   15 +++
 hw/acpi/piix4.c   |   16 +++-
 hw/i386/pc.c  |   26 +-
 include/hw/acpi/cpu_hotplug.h |6 --
 include/hw/acpi/ich9.h|1 -
 qom/cpu.c |1 -
 7 files changed, 47 insertions(+), 36 deletions(-)

-- 
1.7.7




[Qemu-devel] [PATCH 1/5] acpi/cpu: add cpu hotplug callback function to match hotplug_handler API

2014-09-03 Thread Gu Zheng

Signed-off-by: Gu Zheng 
---
 hw/acpi/cpu_hotplug.c |   17 +
 include/hw/acpi/cpu_hotplug.h |3 +++
 2 files changed, 20 insertions(+), 0 deletions(-)

diff --git a/hw/acpi/cpu_hotplug.c b/hw/acpi/cpu_hotplug.c
index 2ad83a0..92c189b 100644
--- a/hw/acpi/cpu_hotplug.c
+++ b/hw/acpi/cpu_hotplug.c
@@ -36,6 +36,23 @@ static const MemoryRegionOps AcpiCpuHotplug_ops = {
 },
 };
 
+void acpi_cpu_plug_cb(ACPIREGS *ar, qemu_irq irq,
+  AcpiCpuHotplug *g, DeviceState *dev)
+{
+CPUState *cpu = CPU(dev);
+CPUClass *k = CPU_GET_CLASS(cpu);
+int64_t cpu_id;
+
+ar->gpe.sts[0] |= ACPI_CPU_HOTPLUG_STATUS;
+cpu_id = k->get_arch_id(cpu);
+g_assert((cpu_id / 8) < ACPI_GPE_PROC_LEN);
+g->sts[cpu_id / 8] |= (1 << (cpu_id % 8));
+
+acpi_update_sci(ar, irq);
+
+cpu_resume(cpu);
+}
+
 void AcpiCpuHotplug_add(ACPIGPE *gpe, AcpiCpuHotplug *g, CPUState *cpu)
 {
 CPUClass *k = CPU_GET_CLASS(cpu);
diff --git a/include/hw/acpi/cpu_hotplug.h b/include/hw/acpi/cpu_hotplug.h
index 9e5d30c..d025731 100644
--- a/include/hw/acpi/cpu_hotplug.h
+++ b/include/hw/acpi/cpu_hotplug.h
@@ -20,6 +20,9 @@ typedef struct AcpiCpuHotplug {
 uint8_t sts[ACPI_GPE_PROC_LEN];
 } AcpiCpuHotplug;
 
+void acpi_cpu_plug_cb(ACPIREGS *ar, qemu_irq irq,
+  AcpiCpuHotplug *g, DeviceState *dev);
+
 void AcpiCpuHotplug_add(ACPIGPE *gpe, AcpiCpuHotplug *g, CPUState *cpu);
 
 void AcpiCpuHotplug_init(MemoryRegion *parent, Object *owner,
-- 
1.7.7




[Qemu-devel] [PATCH 2/5] acpi:ich9: convert cpu hotplug handle to hotplug_handler API

2014-09-03 Thread Gu Zheng
Convert notifier based hotplug handle to hotplug_handler API.

Signed-off-by: Gu Zheng 
---
 hw/acpi/ich9.c |   13 ++---
 include/hw/acpi/ich9.h |1 -
 2 files changed, 2 insertions(+), 12 deletions(-)

diff --git a/hw/acpi/ich9.c b/hw/acpi/ich9.c
index 7b14bbb..89f97d7 100644
--- a/hw/acpi/ich9.c
+++ b/hw/acpi/ich9.c
@@ -209,15 +209,6 @@ static void pm_powerdown_req(Notifier *n, void *opaque)
 acpi_pm1_evt_power_down(&pm->acpi_regs);
 }
 
-static void ich9_cpu_added_req(Notifier *n, void *opaque)
-{
-ICH9LPCPMRegs *pm = container_of(n, ICH9LPCPMRegs, cpu_added_notifier);
-
-assert(pm != NULL);
-AcpiCpuHotplug_add(&pm->acpi_regs.gpe, &pm->gpe_cpu, CPU(opaque));
-acpi_update_sci(&pm->acpi_regs, pm->irq);
-}
-
 void ich9_pm_init(PCIDevice *lpc_pci, ICH9LPCPMRegs *pm,
   qemu_irq sci_irq)
 {
@@ -246,8 +237,6 @@ void ich9_pm_init(PCIDevice *lpc_pci, ICH9LPCPMRegs *pm,
 
 AcpiCpuHotplug_init(pci_address_space_io(lpc_pci), OBJECT(lpc_pci),
 &pm->gpe_cpu, ICH9_CPU_HOTPLUG_IO_BASE);
-pm->cpu_added_notifier.notify = ich9_cpu_added_req;
-qemu_register_cpu_added_notifier(&pm->cpu_added_notifier);
 
 if (pm->acpi_memory_hotplug.is_enabled) {
 acpi_memory_hotplug_init(pci_address_space_io(lpc_pci), 
OBJECT(lpc_pci),
@@ -304,6 +293,8 @@ void ich9_pm_device_plug_cb(ICH9LPCPMRegs *pm, DeviceState 
*dev, Error **errp)
 object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
 acpi_memory_plug_cb(&pm->acpi_regs, pm->irq, &pm->acpi_memory_hotplug,
 dev, errp);
+} else if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) {
+acpi_cpu_plug_cb(&pm->acpi_regs, pm->irq, &pm->gpe_cpu, dev);
 } else {
 error_setg(errp, "acpi: device plug request for not supported device"
" type: %s", object_get_typename(OBJECT(dev)));
diff --git a/include/hw/acpi/ich9.h b/include/hw/acpi/ich9.h
index 7e42448..fe975e6 100644
--- a/include/hw/acpi/ich9.h
+++ b/include/hw/acpi/ich9.h
@@ -47,7 +47,6 @@ typedef struct ICH9LPCPMRegs {
 Notifier powerdown_notifier;
 
 AcpiCpuHotplug gpe_cpu;
-Notifier cpu_added_notifier;
 
 MemHotplugState acpi_memory_hotplug;
 } ICH9LPCPMRegs;
-- 
1.7.7




  1   2   >