All of lore.kernel.org
 help / color / mirror / Atom feed
From: Eduardo Habkost <ehabkost@redhat.com>
To: Thomas Huth <thuth@redhat.com>
Cc: Igor Mammedov <imammedo@redhat.com>,
	qemu-devel@nongnu.org, Paolo Bonzini <pbonzini@redhat.com>,
	Markus Armbruster <armbru@redhat.com>,
	"Dr. David Alan Gilbert" <dgilbert@redhat.com>,
	Peter Maydell <peter.maydell@linaro.org>
Subject: Re: [Qemu-devel] [PATCH] qdev: Check for the availability of a hotplug controller before adding a device
Date: Wed, 4 Oct 2017 18:21:16 -0300	[thread overview]
Message-ID: <20171004212116.GD4015@localhost.localdomain> (raw)
In-Reply-To: <591132a9-c4e5-47cd-bab9-f017a116c2ae@redhat.com>

On Wed, Oct 04, 2017 at 09:29:54PM +0200, Thomas Huth wrote:
> On 04.10.2017 13:36, Igor Mammedov wrote:
> > On Tue,  3 Oct 2017 18:46:02 +0200
> > Thomas Huth <thuth@redhat.com> wrote:
> > 
> >> The qdev_unplug() function contains a g_assert(hotplug_ctrl) statement,
> >> so QEMU crashes when the user tries to device_add + device_del a device
> >> that does not have a corresponding hotplug controller. This could be
> >> provoked for a couple of devices in the past (see commit 4c93950659487c7ad
> >> or 84ebd3e8c7d4fe955 for example). So devices clearly need a hotplug
> >> controller when they are suitable for device_add.
> >> The code in qdev_device_add() already checks whether the bus has a proper
> >> hotplug controller, but for devices that do not have a corresponding bus,
> >> there is no appropriate check available. In that case we should check
> >> whether the machine itself provides a suitable hotplug controller and
> >> refuse to plug the device if none is available.
> >>
> >> Signed-off-by: Thomas Huth <thuth@redhat.com>
> >> ---
> >>  This is the follow-up patch from my earlier try "hw/core/qdev: Do not
> >>  allow hot-plugging without hotplug controller" ... AFAICS the function
> >>  qdev_device_add() is now the right spot to do the check.
> >>
> >>  hw/core/qdev.c         | 28 ++++++++++++++++++++--------
> >>  include/hw/qdev-core.h |  1 +
> >>  qdev-monitor.c         |  9 +++++++++
> >>  3 files changed, 30 insertions(+), 8 deletions(-)
> >>
> >> diff --git a/hw/core/qdev.c b/hw/core/qdev.c
> >> index 606ab53..a953ec9 100644
> >> --- a/hw/core/qdev.c
> >> +++ b/hw/core/qdev.c
> >> @@ -253,19 +253,31 @@ void qdev_set_legacy_instance_id(DeviceState *dev, int alias_id,
> >>      dev->alias_required_for_version = required_for_version;
> >>  }
> >>  
> >> +HotplugHandler *qdev_get_machine_hotplug_handler(DeviceState *dev)
> >> +{
> >> +    MachineState *machine;
> >> +    MachineClass *mc;
> >> +    Object *m_obj = qdev_get_machine();
> >> +
> >> +    if (object_dynamic_cast(m_obj, TYPE_MACHINE)) {
> >> +        machine = MACHINE(m_obj);
> >> +        mc = MACHINE_GET_CLASS(machine);
> >> +        if (mc->get_hotplug_handler) {
> >> +            return mc->get_hotplug_handler(machine, dev);
> >> +        }
> >> +    }
> >> +
> >> +    return NULL;
> >> +}
> >> +
> >>  HotplugHandler *qdev_get_hotplug_handler(DeviceState *dev)
> >>  {
> >> -    HotplugHandler *hotplug_ctrl = NULL;
> >> +    HotplugHandler *hotplug_ctrl;
> >>  
> >>      if (dev->parent_bus && dev->parent_bus->hotplug_handler) {
> >>          hotplug_ctrl = dev->parent_bus->hotplug_handler;
> >> -    } else if (object_dynamic_cast(qdev_get_machine(), TYPE_MACHINE)) {
> >> -        MachineState *machine = MACHINE(qdev_get_machine());
> >> -        MachineClass *mc = MACHINE_GET_CLASS(machine);
> >> -
> >> -        if (mc->get_hotplug_handler) {
> >> -            hotplug_ctrl = mc->get_hotplug_handler(machine, dev);
> >> -        }
> >> +    } else {
> >> +        hotplug_ctrl = qdev_get_machine_hotplug_handler(dev);
> >>      }
> >>      return hotplug_ctrl;
> >>  }
> >> diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h
> >> index 0891461..5aa536d 100644
> >> --- a/include/hw/qdev-core.h
> >> +++ b/include/hw/qdev-core.h
> >> @@ -285,6 +285,7 @@ DeviceState *qdev_try_create(BusState *bus, const char *name);
> >>  void qdev_init_nofail(DeviceState *dev);
> >>  void qdev_set_legacy_instance_id(DeviceState *dev, int alias_id,
> >>                                   int required_for_version);
> >> +HotplugHandler *qdev_get_machine_hotplug_handler(DeviceState *dev);
> >>  HotplugHandler *qdev_get_hotplug_handler(DeviceState *dev);
> >>  void qdev_unplug(DeviceState *dev, Error **errp);
> >>  void qdev_simple_device_unplug_cb(HotplugHandler *hotplug_dev,
> >> diff --git a/qdev-monitor.c b/qdev-monitor.c
> >> index 8fd6df9..2891dde 100644
> >> --- a/qdev-monitor.c
> >> +++ b/qdev-monitor.c
> >> @@ -626,6 +626,15 @@ DeviceState *qdev_device_add(QemuOpts *opts, Error **errp)
> >>          return NULL;
> >>      }
> >>  
> >> +    /* In case we don't have a bus, there must be a machine hotplug handler */
> >> +    if (qdev_hotplug && !bus && !qdev_get_machine_hotplug_handler(dev)) {
> > current machine hotplug handler serves both cold and hot-plug so in reality it's
> > just  'plug' handler.
> > 
> > Is there a point -device/device_add devices on board that doesn't have 'hotplug'
> > handler that would wire device up properly?
> 
> Sorry, I did not get that question ... do you mean whether there's any
> code that uses qdev_device_add() to add a device without hotplug
> controller? I don't think so. It's currently only used by
> qmp_device_add() for the QMP/HMP command, in vl.c for -device and in the
> USB code for xen-usb host device. So this function currently really only
> makes sense for devices that have a hotplug controller.

I assume you are talking only about hotpluggable devices.  With
-device, qdev_device_add() is also used for devices that don't
have a hotplug controller, but this is supposed to be true only
for non-hotpluggable devices.

-- 
Eduardo

  reply	other threads:[~2017-10-04 21:21 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-10-03 16:46 [Qemu-devel] [PATCH] qdev: Check for the availability of a hotplug controller before adding a device Thomas Huth
2017-10-03 18:49 ` Eduardo Habkost
2017-10-05  8:36   ` Igor Mammedov
2017-10-05  9:00     ` Thomas Huth
2017-10-05  9:12       ` Igor Mammedov
2017-10-05  9:15         ` Igor Mammedov
2017-10-04 11:36 ` Igor Mammedov
2017-10-04 19:29   ` Thomas Huth
2017-10-04 21:21     ` Eduardo Habkost [this message]
2017-10-05  5:56       ` Thomas Huth

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20171004212116.GD4015@localhost.localdomain \
    --to=ehabkost@redhat.com \
    --cc=armbru@redhat.com \
    --cc=dgilbert@redhat.com \
    --cc=imammedo@redhat.com \
    --cc=pbonzini@redhat.com \
    --cc=peter.maydell@linaro.org \
    --cc=qemu-devel@nongnu.org \
    --cc=thuth@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.