From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([208.118.235.92]:50986) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UPAYN-0004DL-FW for qemu-devel@nongnu.org; Mon, 08 Apr 2013 07:48:11 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1UPAYG-0004lB-3E for qemu-devel@nongnu.org; Mon, 08 Apr 2013 07:48:03 -0400 Received: from mx1.redhat.com ([209.132.183.28]:29554) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UPAYF-0004l2-RJ for qemu-devel@nongnu.org; Mon, 08 Apr 2013 07:47:56 -0400 Date: Mon, 8 Apr 2013 13:47:43 +0200 From: Igor Mammedov Message-ID: <20130408134743.1c30029a@nial.usersys.redhat.com> In-Reply-To: <1365387890.5674.47.camel@liguang.fnst.cn.fujitsu.com> References: <1365172636-28628-1-git-send-email-imammedo@redhat.com> <1365172636-28628-14-git-send-email-imammedo@redhat.com> <1365387890.5674.47.camel@liguang.fnst.cn.fujitsu.com> Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable Subject: Re: [Qemu-devel] [PATCH 13/22] acpi_piix4: add infrastructure to send CPU hot-plug GPE to guest List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: li guang Cc: aliguori@us.ibm.com, ehabkost@redhat.com, claudio.fontana@huawei.com, qemu-devel@nongnu.org, aderumier@odiso.com, lcapitulino@redhat.com, jfrei@linux.vnet.ibm.com, yang.z.zhang@intel.com, pbonzini@redhat.com, afaerber@suse.de, rth@twiddle.net On Mon, 08 Apr 2013 10:24:50 +0800 li guang wrote: > =E5=9C=A8 2013-04-05=E4=BA=94=E7=9A=84 16:37 +0200=EF=BC=8CIgor Mammedov= =E5=86=99=E9=81=93=EF=BC=9A > > * introduce processor status bitmask visible to guest at 0xaf00 addr, > > where Seabios expects it > > * set bit corresponding to APIC ID in processor status bitmask on > > receiving CPU hot-plug notification > > * trigger CPU hot-plug SCI, expected by Seabios on receiving CPU > > hot-plug notification >=20 > expected by seabios? > IMHO, seems you are saying ACPI's asl code which > just wrapped in seabios. Yep, that's what ACPI asl code there expects. With current effort to move ACPI tables into it might be better to s/Seabios/ACPI/ here. > >=20 > > Signed-off-by: Igor Mammedov > > --- > > v2: > > * use CPUClass.get_firmware_id() to make code target independent > > * bump up vmstate_acpi version > > --- > > hw/acpi_piix4.c | 114 > > ++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, > > 111 insertions(+), 3 deletions(-) > >=20 > > diff --git a/hw/acpi_piix4.c b/hw/acpi_piix4.c > > index 48a32b5..ccfc028 100644 > > --- a/hw/acpi_piix4.c > > +++ b/hw/acpi_piix4.c > > @@ -48,19 +48,28 @@ > > #define PCI_EJ_BASE 0xae08 > > #define PCI_RMV_BASE 0xae0c > > =20 > > +#define PROC_BASE 0xaf00 > > +#define PROC_LEN 32 > > + > > #define PIIX4_PCI_HOTPLUG_STATUS 2 > > +#define PIIX4_CPU_HOTPLUG_STATUS 4 > > =20 > > struct pci_status { > > uint32_t up; /* deprecated, maintained for migration compatibility= */ > > uint32_t down; > > }; > > =20 > > +struct cpu_status { > > + uint8_t sts[PROC_LEN]; > > +}; > > + > > typedef struct PIIX4PMState { > > PCIDevice dev; > > =20 > > MemoryRegion io; > > MemoryRegion io_gpe; > > MemoryRegion io_pci; > > + MemoryRegion io_cpu; > > ACPIREGS ar; > > =20 > > APMState apm; > > @@ -82,6 +91,9 @@ typedef struct PIIX4PMState { > > uint8_t disable_s3; > > uint8_t disable_s4; > > uint8_t s4_val; > > + > > + struct cpu_status gpe_cpu; > > + Notifier cpu_add_notifier; >=20 > seems you named cpu_added_notifier at [PATCH 10/22], > should the notifer's name be unified? I'll fix it on next respin, thanks. >=20 > > } PIIX4PMState; > > =20 > > static void piix4_acpi_system_hot_add_init(MemoryRegion *parent, > > @@ -100,8 +112,8 @@ static void pm_update_sci(PIIX4PMState *s) > > ACPI_BITMASK_POWER_BUTTON_ENABLE | > > ACPI_BITMASK_GLOBAL_LOCK_ENABLE | > > ACPI_BITMASK_TIMER_ENABLE)) !=3D 0) || > > - (((s->ar.gpe.sts[0] & s->ar.gpe.en[0]) > > - & PIIX4_PCI_HOTPLUG_STATUS) !=3D 0); > > + (((s->ar.gpe.sts[0] & s->ar.gpe.en[0]) & > > + (PIIX4_PCI_HOTPLUG_STATUS | PIIX4_CPU_HOTPLUG_STATUS)) !=3D = 0); > > =20 > > qemu_set_irq(s->irq, sci_level); > > /* schedule a timer interruption if needed */ > > @@ -257,6 +269,17 @@ static int acpi_load_old(QEMUFile *f, void *opaque, > > int version_id) return ret; > > } > > =20 > > +#define VMSTATE_CPU_STATUS_ARRAY(_field, > > _state) \ > > + > > { = \ > > + .name =3D > > (stringify(_field)), \ > > + .version_id =3D > > 0, \ > > + .num =3D > > PROC_LEN, \ > > + .info =3D > > &vmstate_info_uint8, \ > > + .size =3D > > sizeof(uint8_t), \ > > + .flags =3D > > VMS_ARRAY, \ > > + .offset =3D vmstate_offset_array(_state, _field, uint8_t, > > PROC_LEN), \ > > + } > > + > > /* qemu-kvm 1.2 uses version 3 but advertised as 2 > > * To support incoming qemu-kvm 1.2 migration, change version_id > > * and minimum_version_id to 2 below (which breaks migration from > > @@ -265,7 +288,7 @@ static int acpi_load_old(QEMUFile *f, void *opaque, > > int version_id) */ > > static const VMStateDescription vmstate_acpi =3D { > > .name =3D "piix4_pm", > > - .version_id =3D 3, > > + .version_id =3D 4, > > .minimum_version_id =3D 3, > > .minimum_version_id_old =3D 1, > > .load_state_old =3D acpi_load_old, > > @@ -281,6 +304,7 @@ static const VMStateDescription vmstate_acpi =3D { > > VMSTATE_STRUCT(ar.gpe, PIIX4PMState, 2, vmstate_gpe, ACPIGPE), > > VMSTATE_STRUCT(pci0_status, PIIX4PMState, 2, vmstate_pci_statu= s, > > struct pci_status), > > + VMSTATE_CPU_STATUS_ARRAY(gpe_cpu.sts, PIIX4PMState), > > VMSTATE_END_OF_LIST() > > } > > }; > > @@ -585,6 +609,83 @@ static const MemoryRegionOps piix4_pci_ops =3D { > > }, > > }; > > =20 > > +static uint64_t cpu_status_read(void *opaque, hwaddr addr, unsigned > > width) +{ > > + PIIX4PMState *s =3D opaque; > > + struct cpu_status *cpus =3D &s->gpe_cpu; > > + uint64_t val =3D cpus->sts[addr]; > > + return val; > > +} > > + > > +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 */ +} > > + > > +static const MemoryRegionOps cpu_hotplug_ops =3D { > > + .read =3D cpu_status_read, > > + .write =3D cpu_status_write, > > + .endianness =3D DEVICE_LITTLE_ENDIAN, > > + .valid =3D { > > + .min_access_size =3D 1, > > + .max_access_size =3D 1, > > + }, > > +}; > > + > > +typedef enum { > > + PLUG, > > + UNPLUG, > > +} HotplugEventType; > > + > > +static void piix4_cpu_hotplug_req(PIIX4PMState *s, CPUState *cpu, > > + HotplugEventType action) > > +{ > > + struct cpu_status *g =3D &s->gpe_cpu; > > + ACPIGPE *gpe =3D &s->ar.gpe; > > + CPUClass *k =3D CPU_GET_CLASS(cpu); > > + int64_t cpu_id; > > + > > + assert(s !=3D NULL); > > + > > + *gpe->sts =3D *gpe->sts | PIIX4_CPU_HOTPLUG_STATUS; > > + cpu_id =3D k->get_firmware_id(CPU(cpu)); > > + if (action =3D=3D PLUG) { > > + g->sts[cpu_id / 8] |=3D (1 << (cpu_id % 8)); > > + } else { > > + g->sts[cpu_id / 8] &=3D ~(1 << (cpu_id % 8)); > > + } > > + pm_update_sci(s); > > +} > > + > > +static void piix4_cpu_add_req(Notifier *n, void *opaque) > > +{ > > + PIIX4PMState *s =3D container_of(n, PIIX4PMState, cpu_add_notifier= ); > > + piix4_cpu_hotplug_req(s, CPU(opaque), PLUG); > > +} > > + > > +static int piix4_init_cpu_status(Object *obj, void *opaque) > > +{ > > + struct cpu_status *g =3D (struct cpu_status *)opaque; > > + Object *cpu_obj =3D object_dynamic_cast(obj, TYPE_CPU); > > + > > + if (cpu_obj) { > > + struct Error *error =3D NULL; > > + CPUClass *k =3D CPU_GET_CLASS(cpu_obj); > > + int64_t id =3D k->get_firmware_id(CPU(cpu_obj)); > > + > > + if (error) { > > + fprintf(stderr, "failed to initilize CPU status for ACPI: > > %s\n", > > + error_get_pretty(error)); > > + error_free(error); > > + abort(); > > + } > > + g_assert((id / 8) < PROC_LEN); > > + g->sts[id / 8] |=3D (1 << (id % 8)); > > + } > > + return object_child_foreach(obj, piix4_init_cpu_status, opaque); > > +} > > + > > static int piix4_device_hotplug(DeviceState *qdev, PCIDevice *dev, > > PCIHotplugState state); > > =20 > > @@ -600,6 +701,13 @@ static void > > piix4_acpi_system_hot_add_init(MemoryRegion *parent, > > memory_region_add_subregion(parent, PCI_HOTPLUG_ADDR, &s->io_pci); > > pci_bus_hotplug(bus, piix4_device_hotplug, &s->dev.qdev); > > + > > + piix4_init_cpu_status(qdev_get_machine(), &s->gpe_cpu); > > + memory_region_init_io(&s->io_cpu, &cpu_hotplug_ops, s, > > "apci-cpu-hotplug", > > + PROC_LEN); > > + memory_region_add_subregion(parent, PROC_BASE, &s->io_cpu); > > + s->cpu_add_notifier.notify =3D piix4_cpu_add_req; > > + qemu_register_cpu_added_notifier(&s->cpu_add_notifier); > > } > > =20 > > static void enable_device(PIIX4PMState *s, int slot) >=20 >=20