Re: [Qemu-devel] [PATCH v5] i386, acpi: check acpi_memory_hotplug capacity in pre_plug

2019-02-28 Thread Wei Yang
On Thu, Feb 28, 2019 at 03:12:21PM +0100, Igor Mammedov wrote:
>On Thu, 28 Feb 2019 09:13:25 +0800
>Wei Yang  wrote:
>
>> On Wed, Feb 27, 2019 at 07:04:02PM +0100, Igor Mammedov wrote:
>> >On Mon, 25 Feb 2019 09:15:34 +0800
>> >Wei Yang  wrote:
>> >  
>> >> On Mon, Feb 25, 2019 at 09:07:08AM +0800, Wei Yang wrote:  
>> >> >Currently we do device realization like below:
>> >> >
>> >> >   hotplug_handler_pre_plug()
>> >> >   dc->realize()
>> >> >   hotplug_handler_plug()
>> >> >
>> >> >Before we do device realization and plug, we should allocate necessary
>> >> >resources and check if memory-hotplug-support property is enabled.
>> >> >
>> >> >At the piix4 and ich9, the memory-hotplug-support property is checked at
>> >> >plug stage. This means that device has been realized and mapped into 
>> >> >guest
>> >> >address space 'pc_dimm_plug()' by the time acpi plug handler is called,
>> >> >where it might fail and crash QEMU due to reaching g_assert_not_reached()
>> >> >(piix4) or error_abort (ich9).
>> >> >
>> >> >Fix it by checking if memory hotplug is enabled at pre_plug stage
>> >> >where we can gracefully abort hotplug request.
>> >> >
>> >> >Signed-off-by: Wei Yang 
>> >> >CC: Igor Mammedov 
>> >> >CC: Eric Blake 
>> >> >Signed-off-by: Wei Yang 
>> >> >
>> >> >---
>> >> >v5:
>> >> >   * rebase on latest upstream
>> >> >   * remove a comment before hotplug_handler_pre_plug
>> >> >   * fix alignment for ich9_pm_device_pre_plug_cb
>> >> >v4:
>> >> >   * fix code alignment of piix4_device_pre_plug_cb
>> >> >v3:
>> >> >   * replace acpi_memory_hotplug with memory-hotplug-support in changelog
>> >> >   * fix code alignment of ich9_pm_device_pre_plug_cb
>> >> >   * print which device type memory-hotplug-support is disabled in
>> >> > ich9_pm_device_pre_plug_cb and piix4_device_pre_plug_cb
>> >> >v2:
>> >> >   * (imamm...@redhat.com)
>> >> > - Almost the whole third paragraph
>> >> >   * apply this change to ich9
>> >> >   * use hotplug_handler_pre_plug() instead of open-coding check
>> >> >---
>> >> > hw/acpi/ich9.c | 15 +--
>> >> > hw/acpi/piix4.c| 13 ++---
>> >> > hw/i386/pc.c   |  2 ++
>> >> > hw/isa/lpc_ich9.c  |  1 +
>> >> > include/hw/acpi/ich9.h |  2 ++
>> >> > 5 files changed, 28 insertions(+), 5 deletions(-)
>> >> >
>> >> >diff --git a/hw/acpi/ich9.c b/hw/acpi/ich9.c
>> >> >index c5d8646abc..e53dfe1ee3 100644
>> >> >--- a/hw/acpi/ich9.c
>> >> >+++ b/hw/acpi/ich9.c
>> >> >@@ -483,13 +483,24 @@ void ich9_pm_add_properties(Object *obj, 
>> >> >ICH9LPCPMRegs *pm, Error **errp)
>> >> >  NULL);
>> >> > }
>> >> > 
>> >> >+void ich9_pm_device_pre_plug_cb(HotplugHandler *hotplug_dev, 
>> >> >DeviceState *dev,
>> >> >+Error **errp)
>> >> >+{
>> >> >+ICH9LPCState *lpc = ICH9_LPC_DEVICE(hotplug_dev);
>> >> >+
>> >> >+if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM) &&
>> >> >+!lpc->pm.acpi_memory_hotplug.is_enabled)
>> >> >+error_setg(errp,
>> >> >+   "memory hotplug is not enabled: 
>> >> >%s.memory-hotplug-support "
>> >> >+   "is not set", object_get_typename(OBJECT(lpc)));
>> >> >+}
>> >> >+
>> >> > void ich9_pm_device_plug_cb(HotplugHandler *hotplug_dev, DeviceState 
>> >> > *dev,
>> >> > Error **errp)
>> >> > {
>> >> > ICH9LPCState *lpc = ICH9_LPC_DEVICE(hotplug_dev);
>> >> > 
>> >> >-if (lpc->pm.acpi_memory_hotplug.is_enabled &&
>> >> >-object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
>> >> >+if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
>> >> > if (object_dynamic_cast(OBJECT(dev), TYPE_NVDIMM)) {
>> >> > nvdimm_acpi_plug_cb(hotplug_dev, dev);
>> >> > } else {
>> >> >diff --git a/hw/acpi/piix4.c b/hw/acpi/piix4.c
>> >> >index df8c0db909..8b9654e437 100644
>> >> >--- a/hw/acpi/piix4.c
>> >> >+++ b/hw/acpi/piix4.c
>> >> >@@ -374,9 +374,16 @@ static void piix4_pm_powerdown_req(Notifier *n, 
>> >> >void *opaque)
>> >> > static void piix4_device_pre_plug_cb(HotplugHandler *hotplug_dev,
>> >> > DeviceState *dev, Error **errp)
>> >> 
>> >> Hmm, I found one interesting thing.
>> >> 
>> >> This function is introduced in
>> >> 
>> >> commit ec266f408882fd38475f72c4e864ed576228643b
>> >> pci/pcihp: perform check for bus capability in pre_plug handler
>> >> 
>> >> This is just implemented in piix4, but don't has the counterpart in ich9.
>> >> 
>> >> So I suggest to have a follow up patch to create the counterpart for ich9 
>> >> and
>> >> then apply this patch on top of that.  
>> >not sure what do you mean, could you be more specific?
>> >  
>> 
>> Let me reply here.
>> 
>> Everything starts from device_set_realized().
>> 
>> device_set_realized()
>>hotplug_handler_pre_plug()
>>dc->realize()
>>hotplug_handler_plug()
>> 
>> There is two choice of HotplugHandler :
>> 
>> * dev's bus 

Re: [Qemu-devel] [PATCH v5] i386, acpi: check acpi_memory_hotplug capacity in pre_plug

2019-02-28 Thread Igor Mammedov
On Thu, 28 Feb 2019 09:13:25 +0800
Wei Yang  wrote:

> On Wed, Feb 27, 2019 at 07:04:02PM +0100, Igor Mammedov wrote:
> >On Mon, 25 Feb 2019 09:15:34 +0800
> >Wei Yang  wrote:
> >  
> >> On Mon, Feb 25, 2019 at 09:07:08AM +0800, Wei Yang wrote:  
> >> >Currently we do device realization like below:
> >> >
> >> >   hotplug_handler_pre_plug()
> >> >   dc->realize()
> >> >   hotplug_handler_plug()
> >> >
> >> >Before we do device realization and plug, we should allocate necessary
> >> >resources and check if memory-hotplug-support property is enabled.
> >> >
> >> >At the piix4 and ich9, the memory-hotplug-support property is checked at
> >> >plug stage. This means that device has been realized and mapped into guest
> >> >address space 'pc_dimm_plug()' by the time acpi plug handler is called,
> >> >where it might fail and crash QEMU due to reaching g_assert_not_reached()
> >> >(piix4) or error_abort (ich9).
> >> >
> >> >Fix it by checking if memory hotplug is enabled at pre_plug stage
> >> >where we can gracefully abort hotplug request.
> >> >
> >> >Signed-off-by: Wei Yang 
> >> >CC: Igor Mammedov 
> >> >CC: Eric Blake 
> >> >Signed-off-by: Wei Yang 
> >> >
> >> >---
> >> >v5:
> >> >   * rebase on latest upstream
> >> >   * remove a comment before hotplug_handler_pre_plug
> >> >   * fix alignment for ich9_pm_device_pre_plug_cb
> >> >v4:
> >> >   * fix code alignment of piix4_device_pre_plug_cb
> >> >v3:
> >> >   * replace acpi_memory_hotplug with memory-hotplug-support in changelog
> >> >   * fix code alignment of ich9_pm_device_pre_plug_cb
> >> >   * print which device type memory-hotplug-support is disabled in
> >> > ich9_pm_device_pre_plug_cb and piix4_device_pre_plug_cb
> >> >v2:
> >> >   * (imamm...@redhat.com)
> >> > - Almost the whole third paragraph
> >> >   * apply this change to ich9
> >> >   * use hotplug_handler_pre_plug() instead of open-coding check
> >> >---
> >> > hw/acpi/ich9.c | 15 +--
> >> > hw/acpi/piix4.c| 13 ++---
> >> > hw/i386/pc.c   |  2 ++
> >> > hw/isa/lpc_ich9.c  |  1 +
> >> > include/hw/acpi/ich9.h |  2 ++
> >> > 5 files changed, 28 insertions(+), 5 deletions(-)
> >> >
> >> >diff --git a/hw/acpi/ich9.c b/hw/acpi/ich9.c
> >> >index c5d8646abc..e53dfe1ee3 100644
> >> >--- a/hw/acpi/ich9.c
> >> >+++ b/hw/acpi/ich9.c
> >> >@@ -483,13 +483,24 @@ void ich9_pm_add_properties(Object *obj, 
> >> >ICH9LPCPMRegs *pm, Error **errp)
> >> >  NULL);
> >> > }
> >> > 
> >> >+void ich9_pm_device_pre_plug_cb(HotplugHandler *hotplug_dev, DeviceState 
> >> >*dev,
> >> >+Error **errp)
> >> >+{
> >> >+ICH9LPCState *lpc = ICH9_LPC_DEVICE(hotplug_dev);
> >> >+
> >> >+if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM) &&
> >> >+!lpc->pm.acpi_memory_hotplug.is_enabled)
> >> >+error_setg(errp,
> >> >+   "memory hotplug is not enabled: 
> >> >%s.memory-hotplug-support "
> >> >+   "is not set", object_get_typename(OBJECT(lpc)));
> >> >+}
> >> >+
> >> > void ich9_pm_device_plug_cb(HotplugHandler *hotplug_dev, DeviceState 
> >> > *dev,
> >> > Error **errp)
> >> > {
> >> > ICH9LPCState *lpc = ICH9_LPC_DEVICE(hotplug_dev);
> >> > 
> >> >-if (lpc->pm.acpi_memory_hotplug.is_enabled &&
> >> >-object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
> >> >+if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
> >> > if (object_dynamic_cast(OBJECT(dev), TYPE_NVDIMM)) {
> >> > nvdimm_acpi_plug_cb(hotplug_dev, dev);
> >> > } else {
> >> >diff --git a/hw/acpi/piix4.c b/hw/acpi/piix4.c
> >> >index df8c0db909..8b9654e437 100644
> >> >--- a/hw/acpi/piix4.c
> >> >+++ b/hw/acpi/piix4.c
> >> >@@ -374,9 +374,16 @@ static void piix4_pm_powerdown_req(Notifier *n, void 
> >> >*opaque)
> >> > static void piix4_device_pre_plug_cb(HotplugHandler *hotplug_dev,
> >> > DeviceState *dev, Error **errp)
> >> 
> >> Hmm, I found one interesting thing.
> >> 
> >> This function is introduced in
> >> 
> >> commit ec266f408882fd38475f72c4e864ed576228643b
> >> pci/pcihp: perform check for bus capability in pre_plug handler
> >> 
> >> This is just implemented in piix4, but don't has the counterpart in ich9.
> >> 
> >> So I suggest to have a follow up patch to create the counterpart for ich9 
> >> and
> >> then apply this patch on top of that.  
> >not sure what do you mean, could you be more specific?
> >  
> 
> Let me reply here.
> 
> Everything starts from device_set_realized().
> 
> device_set_realized()
>hotplug_handler_pre_plug()
>dc->realize()
>hotplug_handler_plug()
> 
> There is two choice of HotplugHandler :
> 
> * dev's bus hotplug_handler
> * machine_hotplug_handler
> 
> Take PIIX as an example, machine_hotplug_handler and pci_bus hotplug_handler
> is:
> 
> pc_machine_device_[pre_]plug_cb
> 

Re: [Qemu-devel] [PATCH v5] i386, acpi: check acpi_memory_hotplug capacity in pre_plug

2019-02-27 Thread Wei Yang
On Wed, Feb 27, 2019 at 07:04:02PM +0100, Igor Mammedov wrote:
>On Mon, 25 Feb 2019 09:15:34 +0800
>Wei Yang  wrote:
>
>> On Mon, Feb 25, 2019 at 09:07:08AM +0800, Wei Yang wrote:
>> >Currently we do device realization like below:
>> >
>> >   hotplug_handler_pre_plug()
>> >   dc->realize()
>> >   hotplug_handler_plug()
>> >
>> >Before we do device realization and plug, we should allocate necessary
>> >resources and check if memory-hotplug-support property is enabled.
>> >
>> >At the piix4 and ich9, the memory-hotplug-support property is checked at
>> >plug stage. This means that device has been realized and mapped into guest
>> >address space 'pc_dimm_plug()' by the time acpi plug handler is called,
>> >where it might fail and crash QEMU due to reaching g_assert_not_reached()
>> >(piix4) or error_abort (ich9).
>> >
>> >Fix it by checking if memory hotplug is enabled at pre_plug stage
>> >where we can gracefully abort hotplug request.
>> >
>> >Signed-off-by: Wei Yang 
>> >CC: Igor Mammedov 
>> >CC: Eric Blake 
>> >Signed-off-by: Wei Yang 
>> >
>> >---
>> >v5:
>> >   * rebase on latest upstream
>> >   * remove a comment before hotplug_handler_pre_plug
>> >   * fix alignment for ich9_pm_device_pre_plug_cb
>> >v4:
>> >   * fix code alignment of piix4_device_pre_plug_cb
>> >v3:
>> >   * replace acpi_memory_hotplug with memory-hotplug-support in changelog
>> >   * fix code alignment of ich9_pm_device_pre_plug_cb
>> >   * print which device type memory-hotplug-support is disabled in
>> > ich9_pm_device_pre_plug_cb and piix4_device_pre_plug_cb
>> >v2:
>> >   * (imamm...@redhat.com)
>> > - Almost the whole third paragraph
>> >   * apply this change to ich9
>> >   * use hotplug_handler_pre_plug() instead of open-coding check
>> >---
>> > hw/acpi/ich9.c | 15 +--
>> > hw/acpi/piix4.c| 13 ++---
>> > hw/i386/pc.c   |  2 ++
>> > hw/isa/lpc_ich9.c  |  1 +
>> > include/hw/acpi/ich9.h |  2 ++
>> > 5 files changed, 28 insertions(+), 5 deletions(-)
>> >
>> >diff --git a/hw/acpi/ich9.c b/hw/acpi/ich9.c
>> >index c5d8646abc..e53dfe1ee3 100644
>> >--- a/hw/acpi/ich9.c
>> >+++ b/hw/acpi/ich9.c
>> >@@ -483,13 +483,24 @@ void ich9_pm_add_properties(Object *obj, 
>> >ICH9LPCPMRegs *pm, Error **errp)
>> >  NULL);
>> > }
>> > 
>> >+void ich9_pm_device_pre_plug_cb(HotplugHandler *hotplug_dev, DeviceState 
>> >*dev,
>> >+Error **errp)
>> >+{
>> >+ICH9LPCState *lpc = ICH9_LPC_DEVICE(hotplug_dev);
>> >+
>> >+if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM) &&
>> >+!lpc->pm.acpi_memory_hotplug.is_enabled)
>> >+error_setg(errp,
>> >+   "memory hotplug is not enabled: 
>> >%s.memory-hotplug-support "
>> >+   "is not set", object_get_typename(OBJECT(lpc)));
>> >+}
>> >+
>> > void ich9_pm_device_plug_cb(HotplugHandler *hotplug_dev, DeviceState *dev,
>> > Error **errp)
>> > {
>> > ICH9LPCState *lpc = ICH9_LPC_DEVICE(hotplug_dev);
>> > 
>> >-if (lpc->pm.acpi_memory_hotplug.is_enabled &&
>> >-object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
>> >+if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
>> > if (object_dynamic_cast(OBJECT(dev), TYPE_NVDIMM)) {
>> > nvdimm_acpi_plug_cb(hotplug_dev, dev);
>> > } else {
>> >diff --git a/hw/acpi/piix4.c b/hw/acpi/piix4.c
>> >index df8c0db909..8b9654e437 100644
>> >--- a/hw/acpi/piix4.c
>> >+++ b/hw/acpi/piix4.c
>> >@@ -374,9 +374,16 @@ static void piix4_pm_powerdown_req(Notifier *n, void 
>> >*opaque)
>> > static void piix4_device_pre_plug_cb(HotplugHandler *hotplug_dev,
>> > DeviceState *dev, Error **errp)  
>> 
>> Hmm, I found one interesting thing.
>> 
>> This function is introduced in
>> 
>> commit ec266f408882fd38475f72c4e864ed576228643b
>> pci/pcihp: perform check for bus capability in pre_plug handler
>> 
>> This is just implemented in piix4, but don't has the counterpart in ich9.
>> 
>> So I suggest to have a follow up patch to create the counterpart for ich9 and
>> then apply this patch on top of that.
>not sure what do you mean, could you be more specific?
>

Let me reply here.

Everything starts from device_set_realized().

device_set_realized()
   hotplug_handler_pre_plug()
   dc->realize()
   hotplug_handler_plug()

There is two choice of HotplugHandler :

* dev's bus hotplug_handler
* machine_hotplug_handler

Take PIIX as an example, machine_hotplug_handler and pci_bus hotplug_handler
is:

pc_machine_device_[pre_]plug_cb
piix4_device_[pre_]plug_cb

if I am correct.

Now back to your question.

Commit ec266f408882 introduced piix4_device_pre_plug_cb() to move the check in
pre_plug handler for PIIX. Then I am wondering the counter part of ich9, But I
don't see something for PCI_DEVICE in ich9_pm_device_plug_cb(). So on ich9,
PCI_DEVICE is not pluggable? Maybe I am lost 

Re: [Qemu-devel] [PATCH v5] i386, acpi: check acpi_memory_hotplug capacity in pre_plug

2019-02-27 Thread Igor Mammedov
On Mon, 25 Feb 2019 09:15:34 +0800
Wei Yang  wrote:

> On Mon, Feb 25, 2019 at 09:07:08AM +0800, Wei Yang wrote:
> >Currently we do device realization like below:
> >
> >   hotplug_handler_pre_plug()
> >   dc->realize()
> >   hotplug_handler_plug()
> >
> >Before we do device realization and plug, we should allocate necessary
> >resources and check if memory-hotplug-support property is enabled.
> >
> >At the piix4 and ich9, the memory-hotplug-support property is checked at
> >plug stage. This means that device has been realized and mapped into guest
> >address space 'pc_dimm_plug()' by the time acpi plug handler is called,
> >where it might fail and crash QEMU due to reaching g_assert_not_reached()
> >(piix4) or error_abort (ich9).
> >
> >Fix it by checking if memory hotplug is enabled at pre_plug stage
> >where we can gracefully abort hotplug request.
> >
> >Signed-off-by: Wei Yang 
> >CC: Igor Mammedov 
> >CC: Eric Blake 
> >Signed-off-by: Wei Yang 
> >
> >---
> >v5:
> >   * rebase on latest upstream
> >   * remove a comment before hotplug_handler_pre_plug
> >   * fix alignment for ich9_pm_device_pre_plug_cb
> >v4:
> >   * fix code alignment of piix4_device_pre_plug_cb
> >v3:
> >   * replace acpi_memory_hotplug with memory-hotplug-support in changelog
> >   * fix code alignment of ich9_pm_device_pre_plug_cb
> >   * print which device type memory-hotplug-support is disabled in
> > ich9_pm_device_pre_plug_cb and piix4_device_pre_plug_cb
> >v2:
> >   * (imamm...@redhat.com)
> > - Almost the whole third paragraph
> >   * apply this change to ich9
> >   * use hotplug_handler_pre_plug() instead of open-coding check
> >---
> > hw/acpi/ich9.c | 15 +--
> > hw/acpi/piix4.c| 13 ++---
> > hw/i386/pc.c   |  2 ++
> > hw/isa/lpc_ich9.c  |  1 +
> > include/hw/acpi/ich9.h |  2 ++
> > 5 files changed, 28 insertions(+), 5 deletions(-)
> >
> >diff --git a/hw/acpi/ich9.c b/hw/acpi/ich9.c
> >index c5d8646abc..e53dfe1ee3 100644
> >--- a/hw/acpi/ich9.c
> >+++ b/hw/acpi/ich9.c
> >@@ -483,13 +483,24 @@ void ich9_pm_add_properties(Object *obj, ICH9LPCPMRegs 
> >*pm, Error **errp)
> >  NULL);
> > }
> > 
> >+void ich9_pm_device_pre_plug_cb(HotplugHandler *hotplug_dev, DeviceState 
> >*dev,
> >+Error **errp)
> >+{
> >+ICH9LPCState *lpc = ICH9_LPC_DEVICE(hotplug_dev);
> >+
> >+if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM) &&
> >+!lpc->pm.acpi_memory_hotplug.is_enabled)
> >+error_setg(errp,
> >+   "memory hotplug is not enabled: 
> >%s.memory-hotplug-support "
> >+   "is not set", object_get_typename(OBJECT(lpc)));
> >+}
> >+
> > void ich9_pm_device_plug_cb(HotplugHandler *hotplug_dev, DeviceState *dev,
> > Error **errp)
> > {
> > ICH9LPCState *lpc = ICH9_LPC_DEVICE(hotplug_dev);
> > 
> >-if (lpc->pm.acpi_memory_hotplug.is_enabled &&
> >-object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
> >+if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
> > if (object_dynamic_cast(OBJECT(dev), TYPE_NVDIMM)) {
> > nvdimm_acpi_plug_cb(hotplug_dev, dev);
> > } else {
> >diff --git a/hw/acpi/piix4.c b/hw/acpi/piix4.c
> >index df8c0db909..8b9654e437 100644
> >--- a/hw/acpi/piix4.c
> >+++ b/hw/acpi/piix4.c
> >@@ -374,9 +374,16 @@ static void piix4_pm_powerdown_req(Notifier *n, void 
> >*opaque)
> > static void piix4_device_pre_plug_cb(HotplugHandler *hotplug_dev,
> > DeviceState *dev, Error **errp)  
> 
> Hmm, I found one interesting thing.
> 
> This function is introduced in
> 
> commit ec266f408882fd38475f72c4e864ed576228643b
> pci/pcihp: perform check for bus capability in pre_plug handler
> 
> This is just implemented in piix4, but don't has the counterpart in ich9.
> 
> So I suggest to have a follow up patch to create the counterpart for ich9 and
> then apply this patch on top of that.
not sure what do you mean, could you be more specific?

> 
> Is my understanding correct?
> 
> > {
> >+PIIX4PMState *s = PIIX4_PM(hotplug_dev);
> >+
> > if (object_dynamic_cast(OBJECT(dev), TYPE_PCI_DEVICE)) {
> > acpi_pcihp_device_pre_plug_cb(hotplug_dev, dev, errp);
> >-} else if (!object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM) &&
> >+} else if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM) &&
> >+   !s->acpi_memory_hotplug.is_enabled) {
> >+error_setg(errp,
> >+   "memory hotplug is not enabled: 
> >%s.memory-hotplug-support "
> >+   "is not set", object_get_typename(OBJECT(s)));
> >+} else if (
> >!object_dynamic_cast(OBJECT(dev), TYPE_CPU)) {
> > error_setg(errp, "acpi: device pre plug request for not supported"
> >" device type: %s", object_get_typename(OBJECT(dev)));
> >@@ -388,8 +395,7 @@ static void piix4_device_plug_cb(HotplugHandler 
> 

Re: [Qemu-devel] [PATCH v5] i386, acpi: check acpi_memory_hotplug capacity in pre_plug

2019-02-27 Thread Igor Mammedov
On Tue, 26 Feb 2019 11:37:32 +0800
Wei Yang  wrote:

> On Mon, Feb 25, 2019 at 09:15:34AM +0800, Wei Yang wrote:
> >On Mon, Feb 25, 2019 at 09:07:08AM +0800, Wei Yang wrote:  
> >>Currently we do device realization like below:
> >>
> >>   hotplug_handler_pre_plug()
> >>   dc->realize()
> >>   hotplug_handler_plug()
> >>
> >>Before we do device realization and plug, we should allocate necessary
> >>resources and check if memory-hotplug-support property is enabled.
> >>
> >>At the piix4 and ich9, the memory-hotplug-support property is checked at
> >>plug stage. This means that device has been realized and mapped into guest
> >>address space 'pc_dimm_plug()' by the time acpi plug handler is called,
> >>where it might fail and crash QEMU due to reaching g_assert_not_reached()
> >>(piix4) or error_abort (ich9).
> >>
> >>Fix it by checking if memory hotplug is enabled at pre_plug stage
> >>where we can gracefully abort hotplug request.
> >>
> >>Signed-off-by: Wei Yang 
> >>CC: Igor Mammedov 
> >>CC: Eric Blake 
> >>Signed-off-by: Wei Yang 
> >>
> >>---
> >>v5:
> >>   * rebase on latest upstream
> >>   * remove a comment before hotplug_handler_pre_plug
> >>   * fix alignment for ich9_pm_device_pre_plug_cb
> >>v4:
> >>   * fix code alignment of piix4_device_pre_plug_cb
> >>v3:
> >>   * replace acpi_memory_hotplug with memory-hotplug-support in changelog
> >>   * fix code alignment of ich9_pm_device_pre_plug_cb
> >>   * print which device type memory-hotplug-support is disabled in
> >> ich9_pm_device_pre_plug_cb and piix4_device_pre_plug_cb
> >>v2:
> >>   * (imamm...@redhat.com)
> >> - Almost the whole third paragraph
> >>   * apply this change to ich9
> >>   * use hotplug_handler_pre_plug() instead of open-coding check
> >>---
> >> hw/acpi/ich9.c | 15 +--
> >> hw/acpi/piix4.c| 13 ++---
> >> hw/i386/pc.c   |  2 ++
> >> hw/isa/lpc_ich9.c  |  1 +
> >> include/hw/acpi/ich9.h |  2 ++
> >> 5 files changed, 28 insertions(+), 5 deletions(-)
> >>
> >>diff --git a/hw/acpi/ich9.c b/hw/acpi/ich9.c
> >>index c5d8646abc..e53dfe1ee3 100644
> >>--- a/hw/acpi/ich9.c
> >>+++ b/hw/acpi/ich9.c
> >>@@ -483,13 +483,24 @@ void ich9_pm_add_properties(Object *obj, 
> >>ICH9LPCPMRegs *pm, Error **errp)
> >>  NULL);
> >> }
> >> 
> >>+void ich9_pm_device_pre_plug_cb(HotplugHandler *hotplug_dev, DeviceState 
> >>*dev,
> >>+Error **errp)
> >>+{
> >>+ICH9LPCState *lpc = ICH9_LPC_DEVICE(hotplug_dev);
> >>+
> >>+if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM) &&
> >>+!lpc->pm.acpi_memory_hotplug.is_enabled)
> >>+error_setg(errp,
> >>+   "memory hotplug is not enabled: 
> >>%s.memory-hotplug-support "
> >>+   "is not set", object_get_typename(OBJECT(lpc)));
> >>+}
> >>+
> >> void ich9_pm_device_plug_cb(HotplugHandler *hotplug_dev, DeviceState *dev,
> >> Error **errp)
> >> {
> >> ICH9LPCState *lpc = ICH9_LPC_DEVICE(hotplug_dev);
> >> 
> >>-if (lpc->pm.acpi_memory_hotplug.is_enabled &&
> >>-object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
> >>+if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
> >> if (object_dynamic_cast(OBJECT(dev), TYPE_NVDIMM)) {
> >> nvdimm_acpi_plug_cb(hotplug_dev, dev);
> >> } else {
> >>diff --git a/hw/acpi/piix4.c b/hw/acpi/piix4.c
> >>index df8c0db909..8b9654e437 100644
> >>--- a/hw/acpi/piix4.c
> >>+++ b/hw/acpi/piix4.c
> >>@@ -374,9 +374,16 @@ static void piix4_pm_powerdown_req(Notifier *n, void 
> >>*opaque)
> >> static void piix4_device_pre_plug_cb(HotplugHandler *hotplug_dev,
> >> DeviceState *dev, Error **errp)  
> >  
> 
> Where will we invoke this check for pci devices?
> 
> pc_machine_device_pre_plug_cb() seems has no connection with this function. So
> how this pre_plug handler takes effect?
hotplug handler doesn't have to be machine, on contrary it's typically a bus 
owner
see hw/core/qdev.c: device_set_realized() and qdev_get_hotplug_handler()

you also might want to check relevant
 'PATCH v1 0/3] qdev: Hotplug handler chaining' thread
that's hopefully to be merged soon

> 
> Do I miss something?
> 
> 




Re: [Qemu-devel] [PATCH v5] i386, acpi: check acpi_memory_hotplug capacity in pre_plug

2019-02-25 Thread Wei Yang
On Mon, Feb 25, 2019 at 09:15:34AM +0800, Wei Yang wrote:
>On Mon, Feb 25, 2019 at 09:07:08AM +0800, Wei Yang wrote:
>>Currently we do device realization like below:
>>
>>   hotplug_handler_pre_plug()
>>   dc->realize()
>>   hotplug_handler_plug()
>>
>>Before we do device realization and plug, we should allocate necessary
>>resources and check if memory-hotplug-support property is enabled.
>>
>>At the piix4 and ich9, the memory-hotplug-support property is checked at
>>plug stage. This means that device has been realized and mapped into guest
>>address space 'pc_dimm_plug()' by the time acpi plug handler is called,
>>where it might fail and crash QEMU due to reaching g_assert_not_reached()
>>(piix4) or error_abort (ich9).
>>
>>Fix it by checking if memory hotplug is enabled at pre_plug stage
>>where we can gracefully abort hotplug request.
>>
>>Signed-off-by: Wei Yang 
>>CC: Igor Mammedov 
>>CC: Eric Blake 
>>Signed-off-by: Wei Yang 
>>
>>---
>>v5:
>>   * rebase on latest upstream
>>   * remove a comment before hotplug_handler_pre_plug
>>   * fix alignment for ich9_pm_device_pre_plug_cb
>>v4:
>>   * fix code alignment of piix4_device_pre_plug_cb
>>v3:
>>   * replace acpi_memory_hotplug with memory-hotplug-support in changelog
>>   * fix code alignment of ich9_pm_device_pre_plug_cb
>>   * print which device type memory-hotplug-support is disabled in
>> ich9_pm_device_pre_plug_cb and piix4_device_pre_plug_cb
>>v2:
>>   * (imamm...@redhat.com)
>> - Almost the whole third paragraph
>>   * apply this change to ich9
>>   * use hotplug_handler_pre_plug() instead of open-coding check
>>---
>> hw/acpi/ich9.c | 15 +--
>> hw/acpi/piix4.c| 13 ++---
>> hw/i386/pc.c   |  2 ++
>> hw/isa/lpc_ich9.c  |  1 +
>> include/hw/acpi/ich9.h |  2 ++
>> 5 files changed, 28 insertions(+), 5 deletions(-)
>>
>>diff --git a/hw/acpi/ich9.c b/hw/acpi/ich9.c
>>index c5d8646abc..e53dfe1ee3 100644
>>--- a/hw/acpi/ich9.c
>>+++ b/hw/acpi/ich9.c
>>@@ -483,13 +483,24 @@ void ich9_pm_add_properties(Object *obj, ICH9LPCPMRegs 
>>*pm, Error **errp)
>>  NULL);
>> }
>> 
>>+void ich9_pm_device_pre_plug_cb(HotplugHandler *hotplug_dev, DeviceState 
>>*dev,
>>+Error **errp)
>>+{
>>+ICH9LPCState *lpc = ICH9_LPC_DEVICE(hotplug_dev);
>>+
>>+if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM) &&
>>+!lpc->pm.acpi_memory_hotplug.is_enabled)
>>+error_setg(errp,
>>+   "memory hotplug is not enabled: %s.memory-hotplug-support 
>>"
>>+   "is not set", object_get_typename(OBJECT(lpc)));
>>+}
>>+
>> void ich9_pm_device_plug_cb(HotplugHandler *hotplug_dev, DeviceState *dev,
>> Error **errp)
>> {
>> ICH9LPCState *lpc = ICH9_LPC_DEVICE(hotplug_dev);
>> 
>>-if (lpc->pm.acpi_memory_hotplug.is_enabled &&
>>-object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
>>+if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
>> if (object_dynamic_cast(OBJECT(dev), TYPE_NVDIMM)) {
>> nvdimm_acpi_plug_cb(hotplug_dev, dev);
>> } else {
>>diff --git a/hw/acpi/piix4.c b/hw/acpi/piix4.c
>>index df8c0db909..8b9654e437 100644
>>--- a/hw/acpi/piix4.c
>>+++ b/hw/acpi/piix4.c
>>@@ -374,9 +374,16 @@ static void piix4_pm_powerdown_req(Notifier *n, void 
>>*opaque)
>> static void piix4_device_pre_plug_cb(HotplugHandler *hotplug_dev,
>> DeviceState *dev, Error **errp)
>

Where will we invoke this check for pci devices?

pc_machine_device_pre_plug_cb() seems has no connection with this function. So
how this pre_plug handler takes effect?

Do I miss something?


-- 
Wei Yang
Help you, Help me



Re: [Qemu-devel] [PATCH v5] i386, acpi: check acpi_memory_hotplug capacity in pre_plug

2019-02-24 Thread Wei Yang
On Mon, Feb 25, 2019 at 09:07:08AM +0800, Wei Yang wrote:
>Currently we do device realization like below:
>
>   hotplug_handler_pre_plug()
>   dc->realize()
>   hotplug_handler_plug()
>
>Before we do device realization and plug, we should allocate necessary
>resources and check if memory-hotplug-support property is enabled.
>
>At the piix4 and ich9, the memory-hotplug-support property is checked at
>plug stage. This means that device has been realized and mapped into guest
>address space 'pc_dimm_plug()' by the time acpi plug handler is called,
>where it might fail and crash QEMU due to reaching g_assert_not_reached()
>(piix4) or error_abort (ich9).
>
>Fix it by checking if memory hotplug is enabled at pre_plug stage
>where we can gracefully abort hotplug request.
>
>Signed-off-by: Wei Yang 
>CC: Igor Mammedov 
>CC: Eric Blake 
>Signed-off-by: Wei Yang 
>
>---
>v5:
>   * rebase on latest upstream
>   * remove a comment before hotplug_handler_pre_plug
>   * fix alignment for ich9_pm_device_pre_plug_cb
>v4:
>   * fix code alignment of piix4_device_pre_plug_cb
>v3:
>   * replace acpi_memory_hotplug with memory-hotplug-support in changelog
>   * fix code alignment of ich9_pm_device_pre_plug_cb
>   * print which device type memory-hotplug-support is disabled in
> ich9_pm_device_pre_plug_cb and piix4_device_pre_plug_cb
>v2:
>   * (imamm...@redhat.com)
> - Almost the whole third paragraph
>   * apply this change to ich9
>   * use hotplug_handler_pre_plug() instead of open-coding check
>---
> hw/acpi/ich9.c | 15 +--
> hw/acpi/piix4.c| 13 ++---
> hw/i386/pc.c   |  2 ++
> hw/isa/lpc_ich9.c  |  1 +
> include/hw/acpi/ich9.h |  2 ++
> 5 files changed, 28 insertions(+), 5 deletions(-)
>
>diff --git a/hw/acpi/ich9.c b/hw/acpi/ich9.c
>index c5d8646abc..e53dfe1ee3 100644
>--- a/hw/acpi/ich9.c
>+++ b/hw/acpi/ich9.c
>@@ -483,13 +483,24 @@ void ich9_pm_add_properties(Object *obj, ICH9LPCPMRegs 
>*pm, Error **errp)
>  NULL);
> }
> 
>+void ich9_pm_device_pre_plug_cb(HotplugHandler *hotplug_dev, DeviceState *dev,
>+Error **errp)
>+{
>+ICH9LPCState *lpc = ICH9_LPC_DEVICE(hotplug_dev);
>+
>+if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM) &&
>+!lpc->pm.acpi_memory_hotplug.is_enabled)
>+error_setg(errp,
>+   "memory hotplug is not enabled: %s.memory-hotplug-support "
>+   "is not set", object_get_typename(OBJECT(lpc)));
>+}
>+
> void ich9_pm_device_plug_cb(HotplugHandler *hotplug_dev, DeviceState *dev,
> Error **errp)
> {
> ICH9LPCState *lpc = ICH9_LPC_DEVICE(hotplug_dev);
> 
>-if (lpc->pm.acpi_memory_hotplug.is_enabled &&
>-object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
>+if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
> if (object_dynamic_cast(OBJECT(dev), TYPE_NVDIMM)) {
> nvdimm_acpi_plug_cb(hotplug_dev, dev);
> } else {
>diff --git a/hw/acpi/piix4.c b/hw/acpi/piix4.c
>index df8c0db909..8b9654e437 100644
>--- a/hw/acpi/piix4.c
>+++ b/hw/acpi/piix4.c
>@@ -374,9 +374,16 @@ static void piix4_pm_powerdown_req(Notifier *n, void 
>*opaque)
> static void piix4_device_pre_plug_cb(HotplugHandler *hotplug_dev,
> DeviceState *dev, Error **errp)

Hmm, I found one interesting thing.

This function is introduced in

commit ec266f408882fd38475f72c4e864ed576228643b
pci/pcihp: perform check for bus capability in pre_plug handler

This is just implemented in piix4, but don't has the counterpart in ich9.

So I suggest to have a follow up patch to create the counterpart for ich9 and
then apply this patch on top of that.

Is my understanding correct?

> {
>+PIIX4PMState *s = PIIX4_PM(hotplug_dev);
>+
> if (object_dynamic_cast(OBJECT(dev), TYPE_PCI_DEVICE)) {
> acpi_pcihp_device_pre_plug_cb(hotplug_dev, dev, errp);
>-} else if (!object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM) &&
>+} else if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM) &&
>+   !s->acpi_memory_hotplug.is_enabled) {
>+error_setg(errp,
>+   "memory hotplug is not enabled: %s.memory-hotplug-support "
>+   "is not set", object_get_typename(OBJECT(s)));
>+} else if (
>!object_dynamic_cast(OBJECT(dev), TYPE_CPU)) {
> error_setg(errp, "acpi: device pre plug request for not supported"
>" device type: %s", object_get_typename(OBJECT(dev)));
>@@ -388,8 +395,7 @@ static void piix4_device_plug_cb(HotplugHandler 
>*hotplug_dev,
> {
> PIIX4PMState *s = PIIX4_PM(hotplug_dev);
> 
>-if (s->acpi_memory_hotplug.is_enabled &&
>-object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
>+if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
> if (object_dynamic_cast(OBJECT(dev), TYPE_NVDIMM)) {
> nvdimm_acpi_plug_cb(hotplug_dev, dev);
> } else 

[Qemu-devel] [PATCH v5] i386, acpi: check acpi_memory_hotplug capacity in pre_plug

2019-02-24 Thread Wei Yang
Currently we do device realization like below:

   hotplug_handler_pre_plug()
   dc->realize()
   hotplug_handler_plug()

Before we do device realization and plug, we should allocate necessary
resources and check if memory-hotplug-support property is enabled.

At the piix4 and ich9, the memory-hotplug-support property is checked at
plug stage. This means that device has been realized and mapped into guest
address space 'pc_dimm_plug()' by the time acpi plug handler is called,
where it might fail and crash QEMU due to reaching g_assert_not_reached()
(piix4) or error_abort (ich9).

Fix it by checking if memory hotplug is enabled at pre_plug stage
where we can gracefully abort hotplug request.

Signed-off-by: Wei Yang 
CC: Igor Mammedov 
CC: Eric Blake 
Signed-off-by: Wei Yang 

---
v5:
   * rebase on latest upstream
   * remove a comment before hotplug_handler_pre_plug
   * fix alignment for ich9_pm_device_pre_plug_cb
v4:
   * fix code alignment of piix4_device_pre_plug_cb
v3:
   * replace acpi_memory_hotplug with memory-hotplug-support in changelog
   * fix code alignment of ich9_pm_device_pre_plug_cb
   * print which device type memory-hotplug-support is disabled in
 ich9_pm_device_pre_plug_cb and piix4_device_pre_plug_cb
v2:
   * (imamm...@redhat.com)
 - Almost the whole third paragraph
   * apply this change to ich9
   * use hotplug_handler_pre_plug() instead of open-coding check
---
 hw/acpi/ich9.c | 15 +--
 hw/acpi/piix4.c| 13 ++---
 hw/i386/pc.c   |  2 ++
 hw/isa/lpc_ich9.c  |  1 +
 include/hw/acpi/ich9.h |  2 ++
 5 files changed, 28 insertions(+), 5 deletions(-)

diff --git a/hw/acpi/ich9.c b/hw/acpi/ich9.c
index c5d8646abc..e53dfe1ee3 100644
--- a/hw/acpi/ich9.c
+++ b/hw/acpi/ich9.c
@@ -483,13 +483,24 @@ void ich9_pm_add_properties(Object *obj, ICH9LPCPMRegs 
*pm, Error **errp)
  NULL);
 }
 
+void ich9_pm_device_pre_plug_cb(HotplugHandler *hotplug_dev, DeviceState *dev,
+Error **errp)
+{
+ICH9LPCState *lpc = ICH9_LPC_DEVICE(hotplug_dev);
+
+if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM) &&
+!lpc->pm.acpi_memory_hotplug.is_enabled)
+error_setg(errp,
+   "memory hotplug is not enabled: %s.memory-hotplug-support "
+   "is not set", object_get_typename(OBJECT(lpc)));
+}
+
 void ich9_pm_device_plug_cb(HotplugHandler *hotplug_dev, DeviceState *dev,
 Error **errp)
 {
 ICH9LPCState *lpc = ICH9_LPC_DEVICE(hotplug_dev);
 
-if (lpc->pm.acpi_memory_hotplug.is_enabled &&
-object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
+if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
 if (object_dynamic_cast(OBJECT(dev), TYPE_NVDIMM)) {
 nvdimm_acpi_plug_cb(hotplug_dev, dev);
 } else {
diff --git a/hw/acpi/piix4.c b/hw/acpi/piix4.c
index df8c0db909..8b9654e437 100644
--- a/hw/acpi/piix4.c
+++ b/hw/acpi/piix4.c
@@ -374,9 +374,16 @@ static void piix4_pm_powerdown_req(Notifier *n, void 
*opaque)
 static void piix4_device_pre_plug_cb(HotplugHandler *hotplug_dev,
 DeviceState *dev, Error **errp)
 {
+PIIX4PMState *s = PIIX4_PM(hotplug_dev);
+
 if (object_dynamic_cast(OBJECT(dev), TYPE_PCI_DEVICE)) {
 acpi_pcihp_device_pre_plug_cb(hotplug_dev, dev, errp);
-} else if (!object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM) &&
+} else if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM) &&
+   !s->acpi_memory_hotplug.is_enabled) {
+error_setg(errp,
+   "memory hotplug is not enabled: %s.memory-hotplug-support "
+   "is not set", object_get_typename(OBJECT(s)));
+} else if (
!object_dynamic_cast(OBJECT(dev), TYPE_CPU)) {
 error_setg(errp, "acpi: device pre plug request for not supported"
" device type: %s", object_get_typename(OBJECT(dev)));
@@ -388,8 +395,7 @@ static void piix4_device_plug_cb(HotplugHandler 
*hotplug_dev,
 {
 PIIX4PMState *s = PIIX4_PM(hotplug_dev);
 
-if (s->acpi_memory_hotplug.is_enabled &&
-object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
+if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
 if (object_dynamic_cast(OBJECT(dev), TYPE_NVDIMM)) {
 nvdimm_acpi_plug_cb(hotplug_dev, dev);
 } else {
@@ -704,6 +710,7 @@ static void piix4_pm_class_init(ObjectClass *klass, void 
*data)
 dc->user_creatable = false;
 dc->hotpluggable = false;
 hc->pre_plug = piix4_device_pre_plug_cb;
+hc->pre_plug = piix4_device_pre_plug_cb;
 hc->plug = piix4_device_plug_cb;
 hc->unplug_request = piix4_device_unplug_request_cb;
 hc->unplug = piix4_device_unplug_cb;
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 578f772e7c..64d9e756fa 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -2083,6 +2083,8 @@ static void pc_memory_pre_plug(HotplugHandler 
*hotplug_dev,