From patchwork Fri Oct 2 17:35:49 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Bonzini X-Patchwork-Id: 272166 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-12.5 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 71506C4363D for ; Fri, 2 Oct 2020 17:37:16 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id D779820758 for ; Fri, 2 Oct 2020 17:37:15 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="KwyE2jld" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org D779820758 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:32770 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kOOza-0001iB-NA for qemu-devel@archiver.kernel.org; Fri, 02 Oct 2020 13:37:14 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:44970) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kOOyS-0000Nj-Lj for qemu-devel@nongnu.org; Fri, 02 Oct 2020 13:36:04 -0400 Received: from mail-wr1-x441.google.com ([2a00:1450:4864:20::441]:37325) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1kOOyQ-0003Iz-Ly for qemu-devel@nongnu.org; Fri, 02 Oct 2020 13:36:04 -0400 Received: by mail-wr1-x441.google.com with SMTP id z4so2681670wrr.4 for ; Fri, 02 Oct 2020 10:36:02 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=n/8ETOZvvibYNeWstHPm4Svp3CtDHbXvNRVqHpTs9/k=; b=KwyE2jldr5QD4IC5sX3hUkfZSuZsrL5GHhBCsWMjgPFlj3fMCzohrd0pmM1QroqJSa TIgw9MHJwowqMG3o+cUYBJiEVY8/PAqYW452dVBPqIaa7rXFqPw11GwfpVJbquHy7DQX vUNZycp9ZwLbmwK+04vo/F+7/qvaAEDrBZ6uas4gMKldRaPEAhUBPQfSMxu+0StgFOaj eNWC5xbnQatpswqP7ergFEknTeFoRQf2aK3iPXt3iqg9Q0Dr3L7CiN0CyZ8i1a+8cC6Q U7dFu92qWUsiesD7COIX6FTFulu3D54eWfDrEZhsruVgG6PBVLIk2QOWCWC7+knqSp+N ZKyw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:subject:date:message-id :in-reply-to:references:mime-version:content-transfer-encoding; bh=n/8ETOZvvibYNeWstHPm4Svp3CtDHbXvNRVqHpTs9/k=; b=CfHyyruoO8e5yWpp2eBkTLWLk1HxXM0cGr7jPpZvGReM00GAa+eGaHWBQR271XMeHp hIFnJlzMblLMGf8Cgw484gJWYgsQ0FI5i3rwAwGa/SkVHq6Jg46w4n0/Y06xkX7t7JJt Uw/6aDSe+Pkkk7WaVsC7eF+eLM7Lr+t/d6j1ONH1YWU8uEKq82iNVjK6ZxPqglm9VGKc tTrbzclNWhh78lBZJTrCkoQl5GxGNTEa6GL9UwepeJQ8weNMspW824thvEGEtou/NysF UjlNVjZ4za8tZhl99/CYh2B7jyDoc64jno7dRlVubpbvaNhZNPH6WEJR1+OZkAUuOq5z UuZA== X-Gm-Message-State: AOAM531d5VvkY3t0rp01XFcVMMD49aMgock/n9Zllg385oisW+kYLiwo auV/0AL9aaEwvc65y+Co9pP0xSzRxvc= X-Google-Smtp-Source: ABdhPJx8gNEJDh1Ywe8L2zkjxl6pr7ZGXc3V8SwaOCKXOwsv6OBnsAYUFMrddLxLhcdc8xrsmnLBIA== X-Received: by 2002:adf:cd05:: with SMTP id w5mr4262387wrm.62.1601660160880; Fri, 02 Oct 2020 10:36:00 -0700 (PDT) Received: from donizetti.redhat.com ([2001:b07:6468:f312:47e0:e742:75ba:b84d]) by smtp.gmail.com with ESMTPSA id l8sm2516454wrx.22.2020.10.02.10.36.00 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 02 Oct 2020 10:36:00 -0700 (PDT) From: Paolo Bonzini To: qemu-devel@nongnu.org Subject: [PATCH v6 01/10] qdev: add "check if address free" callback for buses Date: Fri, 2 Oct 2020 19:35:49 +0200 Message-Id: <20201002173558.232960-2-pbonzini@redhat.com> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20201002173558.232960-1-pbonzini@redhat.com> References: <20201002173558.232960-1-pbonzini@redhat.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2a00:1450:4864:20::441; envelope-from=paolo.bonzini@gmail.com; helo=mail-wr1-x441.google.com X-detected-operating-system: by eggs.gnu.org: No matching host in p0f cache. That's all we know. X-Spam_score_int: -16 X-Spam_score: -1.7 X-Spam_bar: - X-Spam_report: (-1.7 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FORGED_FROMDOMAIN=0.001, FREEMAIL_FROM=0.001, HEADER_FROM_DIFFERENT_DOMAINS=0.25, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" Check if an address is free on the bus before plugging in the device. This makes it possible to do the check without any side effects, and to detect the problem early without having to do it in the realize callback. Signed-off-by: Paolo Bonzini --- hw/core/qdev.c | 17 +++++++++++++++-- hw/net/virtio-net.c | 2 +- hw/sd/core.c | 3 ++- include/hw/qdev-core.h | 13 ++++++++++++- 4 files changed, 30 insertions(+), 5 deletions(-) diff --git a/hw/core/qdev.c b/hw/core/qdev.c index 96772a15bd..74db78df36 100644 --- a/hw/core/qdev.c +++ b/hw/core/qdev.c @@ -94,13 +94,23 @@ static void bus_add_child(BusState *bus, DeviceState *child) 0); } -void qdev_set_parent_bus(DeviceState *dev, BusState *bus) +static bool bus_check_address(BusState *bus, DeviceState *child, Error **errp) +{ + BusClass *bc = BUS_GET_CLASS(bus); + return !bc->check_address || bc->check_address(bus, child, errp); +} + +bool qdev_set_parent_bus(DeviceState *dev, BusState *bus, Error **errp) { BusState *old_parent_bus = dev->parent_bus; DeviceClass *dc = DEVICE_GET_CLASS(dev); assert(dc->bus_type && object_dynamic_cast(OBJECT(bus), dc->bus_type)); + if (!bus_check_address(bus, dev, errp)) { + return false; + } + if (old_parent_bus) { trace_qdev_update_parent_bus(dev, object_get_typename(OBJECT(dev)), old_parent_bus, object_get_typename(OBJECT(old_parent_bus)), @@ -126,6 +136,7 @@ void qdev_set_parent_bus(DeviceState *dev, BusState *bus) object_unref(OBJECT(old_parent_bus)); object_unref(OBJECT(dev)); } + return true; } DeviceState *qdev_new(const char *name) @@ -371,7 +382,9 @@ bool qdev_realize(DeviceState *dev, BusState *bus, Error **errp) assert(!dev->realized && !dev->parent_bus); if (bus) { - qdev_set_parent_bus(dev, bus); + if (!qdev_set_parent_bus(dev, bus, errp)) { + return false; + } } else { assert(!DEVICE_GET_CLASS(dev)->bus_type); } diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c index 7bf27b9db7..268cecc498 100644 --- a/hw/net/virtio-net.c +++ b/hw/net/virtio-net.c @@ -3142,7 +3142,7 @@ static bool failover_replug_primary(VirtIONet *n, Error **errp) error_setg(errp, "virtio_net: couldn't find primary bus"); return false; } - qdev_set_parent_bus(n->primary_dev, n->primary_bus); + qdev_set_parent_bus(n->primary_dev, n->primary_bus, &error_abort); n->primary_should_be_hidden = false; if (!qemu_opt_set_bool(n->primary_device_opts, "partially_hotplugged", true, errp)) { diff --git a/hw/sd/core.c b/hw/sd/core.c index 957d116f1a..08c93b5903 100644 --- a/hw/sd/core.c +++ b/hw/sd/core.c @@ -23,6 +23,7 @@ #include "hw/qdev-core.h" #include "hw/sd/sd.h" #include "qemu/module.h" +#include "qapi/error.h" #include "trace.h" static inline const char *sdbus_name(SDBus *sdbus) @@ -240,7 +241,7 @@ void sdbus_reparent_card(SDBus *from, SDBus *to) readonly = sc->get_readonly(card); sdbus_set_inserted(from, false); - qdev_set_parent_bus(DEVICE(card), &to->qbus); + qdev_set_parent_bus(DEVICE(card), &to->qbus, &error_abort); sdbus_set_inserted(to, true); sdbus_set_readonly(to, readonly); } diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h index 72064f4dd4..14d476c587 100644 --- a/include/hw/qdev-core.h +++ b/include/hw/qdev-core.h @@ -210,13 +210,24 @@ struct BusClass { /* FIXME first arg should be BusState */ void (*print_dev)(Monitor *mon, DeviceState *dev, int indent); char *(*get_dev_path)(DeviceState *dev); + /* * This callback is used to create Open Firmware device path in accordance * with OF spec http://forthworks.com/standards/of1275.pdf. Individual bus * bindings can be found at http://playground.sun.com/1275/bindings/. */ char *(*get_fw_dev_path)(DeviceState *dev); + void (*reset)(BusState *bus); + + /* + * Return whether the device can be added to @bus, + * based on the address that was set (via device properties) + * before realize. If not, on return @errp contains the + * human-readable error message. + */ + bool (*check_address)(BusState *bus, DeviceState *dev, Error **errp); + BusRealize realize; BusUnrealize unrealize; @@ -788,7 +799,7 @@ const char *qdev_fw_name(DeviceState *dev); Object *qdev_get_machine(void); /* FIXME: make this a link<> */ -void qdev_set_parent_bus(DeviceState *dev, BusState *bus); +bool qdev_set_parent_bus(DeviceState *dev, BusState *bus, Error **errp); extern bool qdev_hotplug; extern bool qdev_hot_removed; From patchwork Fri Oct 2 17:35:50 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Bonzini X-Patchwork-Id: 303800 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-12.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 4C85BC47095 for ; Fri, 2 Oct 2020 17:40:56 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id BF18520758 for ; Fri, 2 Oct 2020 17:40:55 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="MNOEfMNr" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org BF18520758 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:38910 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kOP38-0004Xs-QR for qemu-devel@archiver.kernel.org; Fri, 02 Oct 2020 13:40:54 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:44986) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kOOyT-0000Ok-DT for qemu-devel@nongnu.org; Fri, 02 Oct 2020 13:36:05 -0400 Received: from mail-wr1-x42d.google.com ([2a00:1450:4864:20::42d]:46201) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1kOOyR-0003J9-FP for qemu-devel@nongnu.org; Fri, 02 Oct 2020 13:36:05 -0400 Received: by mail-wr1-x42d.google.com with SMTP id o5so2658235wrn.13 for ; Fri, 02 Oct 2020 10:36:03 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=7jnEPHNQolXrIggvM1boO0VCWcKwcGVqxDfZAb/xQC0=; b=MNOEfMNrHRG/VRSQki1fA3bHhSb5YxxMfhWtcTXxUkB0l4Fx+Yg3NOeC+RRNIE3xiC +GR4vWeSqdcBaATJFC32/nxuZTtr3MgR1sd4+V3jKULrWAePvSGdivWVYczFOh1ZzeEX gpJ/qsvjGSh6Dx8A4buL9ecoXiKZ/4qe71mw1Ku+dwg7cWGiDe+AxOO+WsoaG+d/Zcoa YSLowmp8GTGHcXwodM6NMEhiLPW3TZaSuXguwuAzUmI0Vr+MIRKrvut7d13nSeCtYJlm HlYU/S+SRUDj5Gdf2a6jHbfIoJ3loWyhNgL+5r4ihDAiuZWCg3fCkxXEperZW7AltsqU zKtA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:subject:date:message-id :in-reply-to:references:mime-version:content-transfer-encoding; bh=7jnEPHNQolXrIggvM1boO0VCWcKwcGVqxDfZAb/xQC0=; b=l0SLsWRVefroXUS0QlDl6qHaJDg680gkMZ0RwMRAyLnwVf6XsAvSC6oz2ozCy65Btx tKgqREQ8hm75YyFYyG1yuKY2yVVBxAEDiwSlpPOYe2cGRMhHK1xjM1Xr4RrCun8I6N5E 3DiX59zZI560yGpR1EoIHrfyNiTCzrtreNhxcCWtT4BmYbZumpo4JT4iKTXq1KbDfsTj vVP+MpKte3LDt9rUcZWpSkVaBNStBDBMg2TcRUtV+AwfUFVDXilHCFyUOzJhaugYOM3f NHc68y4dNQfBfIYO2W2Dhqq4SXpR8DUcxPM03xBDPAKJDo9U/DEHY/yZQPLHxGZ24uMB k4BA== X-Gm-Message-State: AOAM531Cm9bWt0w97l6y+kz75bTciTMIi8+uqu3IjQxMZR75BcAG7XBJ Ozhc7m8+UxiBLAHTdF7p2pVsPeqNa2U= X-Google-Smtp-Source: ABdhPJxlZzkfreGBj0je2cBHtA4UrHf0ggRr2S+ZSEgdxRZ9nKD6V5/w9PTGoXdeO8jNEfTywOS+FA== X-Received: by 2002:adf:df87:: with SMTP id z7mr4375399wrl.239.1601660161856; Fri, 02 Oct 2020 10:36:01 -0700 (PDT) Received: from donizetti.redhat.com ([2001:b07:6468:f312:47e0:e742:75ba:b84d]) by smtp.gmail.com with ESMTPSA id l8sm2516454wrx.22.2020.10.02.10.36.00 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 02 Oct 2020 10:36:01 -0700 (PDT) From: Paolo Bonzini To: qemu-devel@nongnu.org Subject: [PATCH v6 02/10] scsi: switch to bus->check_address Date: Fri, 2 Oct 2020 19:35:50 +0200 Message-Id: <20201002173558.232960-3-pbonzini@redhat.com> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20201002173558.232960-1-pbonzini@redhat.com> References: <20201002173558.232960-1-pbonzini@redhat.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2a00:1450:4864:20::42d; envelope-from=paolo.bonzini@gmail.com; helo=mail-wr1-x42d.google.com X-detected-operating-system: by eggs.gnu.org: No matching host in p0f cache. That's all we know. X-Spam_score_int: -16 X-Spam_score: -1.7 X-Spam_bar: - X-Spam_report: (-1.7 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FORGED_FROMDOMAIN=0.001, FREEMAIL_FROM=0.001, HEADER_FROM_DIFFERENT_DOMAINS=0.25, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" Signed-off-by: Paolo Bonzini --- hw/scsi/scsi-bus.c | 122 ++++++++++++++++++++++++++++----------------- 1 file changed, 75 insertions(+), 47 deletions(-) diff --git a/hw/scsi/scsi-bus.c b/hw/scsi/scsi-bus.c index 3284a5d1fb..94921c04b1 100644 --- a/hw/scsi/scsi-bus.c +++ b/hw/scsi/scsi-bus.c @@ -22,33 +22,6 @@ static void scsi_req_dequeue(SCSIRequest *req); static uint8_t *scsi_target_alloc_buf(SCSIRequest *req, size_t len); static void scsi_target_free_buf(SCSIRequest *req); -static Property scsi_props[] = { - DEFINE_PROP_UINT32("channel", SCSIDevice, channel, 0), - DEFINE_PROP_UINT32("scsi-id", SCSIDevice, id, -1), - DEFINE_PROP_UINT32("lun", SCSIDevice, lun, -1), - DEFINE_PROP_END_OF_LIST(), -}; - -static void scsi_bus_class_init(ObjectClass *klass, void *data) -{ - BusClass *k = BUS_CLASS(klass); - HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(klass); - - k->get_dev_path = scsibus_get_dev_path; - k->get_fw_dev_path = scsibus_get_fw_dev_path; - hc->unplug = qdev_simple_device_unplug_cb; -} - -static const TypeInfo scsi_bus_info = { - .name = TYPE_SCSI_BUS, - .parent = TYPE_BUS, - .instance_size = sizeof(SCSIBus), - .class_init = scsi_bus_class_init, - .interfaces = (InterfaceInfo[]) { - { TYPE_HOTPLUG_HANDLER }, - { } - } -}; static int next_scsi_bus; static void scsi_device_realize(SCSIDevice *s, Error **errp) @@ -160,35 +133,68 @@ static void scsi_dma_restart_cb(void *opaque, int running, RunState state) } } -static void scsi_qdev_realize(DeviceState *qdev, Error **errp) +static bool scsi_bus_is_address_free(SCSIBus *bus, + int channel, int target, int lun, + SCSIDevice **p_dev) +{ + SCSIDevice *d = scsi_device_find(bus, channel, target, lun); + if (d && d->lun == lun) { + if (p_dev) { + *p_dev = d; + } + return false; + } + if (p_dev) { + *p_dev = NULL; + } + return true; +} + +static bool scsi_bus_check_address(BusState *qbus, DeviceState *qdev, Error **errp) { SCSIDevice *dev = SCSI_DEVICE(qdev); - SCSIBus *bus = DO_UPCAST(SCSIBus, qbus, dev->qdev.parent_bus); - SCSIDevice *d; - Error *local_err = NULL; + SCSIBus *bus = SCSI_BUS(qbus); if (dev->channel > bus->info->max_channel) { error_setg(errp, "bad scsi channel id: %d", dev->channel); - return; + return false; } if (dev->id != -1 && dev->id > bus->info->max_target) { error_setg(errp, "bad scsi device id: %d", dev->id); - return; + return false; } if (dev->lun != -1 && dev->lun > bus->info->max_lun) { error_setg(errp, "bad scsi device lun: %d", dev->lun); - return; + return false; + } + + if (dev->id != -1 && dev->lun != -1) { + SCSIDevice *d; + if (!scsi_bus_is_address_free(bus, dev->channel, dev->id, dev->lun, &d)) { + error_setg(errp, "lun already used by '%s'", d->qdev.id); + return false; + } } + return true; +} + +static void scsi_qdev_realize(DeviceState *qdev, Error **errp) +{ + SCSIDevice *dev = SCSI_DEVICE(qdev); + SCSIBus *bus = DO_UPCAST(SCSIBus, qbus, dev->qdev.parent_bus); + bool is_free; + Error *local_err = NULL; + if (dev->id == -1) { int id = -1; if (dev->lun == -1) { dev->lun = 0; } do { - d = scsi_device_find(bus, dev->channel, ++id, dev->lun); - } while (d && d->lun == dev->lun && id < bus->info->max_target); - if (d && d->lun == dev->lun) { + is_free = scsi_bus_is_address_free(bus, dev->channel, ++id, dev->lun, NULL); + } while (!is_free && id < bus->info->max_target); + if (!is_free) { error_setg(errp, "no free target"); return; } @@ -196,20 +202,13 @@ static void scsi_qdev_realize(DeviceState *qdev, Error **errp) } else if (dev->lun == -1) { int lun = -1; do { - d = scsi_device_find(bus, dev->channel, dev->id, ++lun); - } while (d && d->lun == lun && lun < bus->info->max_lun); - if (d && d->lun == lun) { + is_free = scsi_bus_is_address_free(bus, dev->channel, dev->id, ++lun, NULL); + } while (!is_free && lun < bus->info->max_lun); + if (!is_free) { error_setg(errp, "no free lun"); return; } dev->lun = lun; - } else { - d = scsi_device_find(bus, dev->channel, dev->id, dev->lun); - assert(d); - if (d->lun == dev->lun && dev != d) { - error_setg(errp, "lun already used by '%s'", d->qdev.id); - return; - } } QTAILQ_INIT(&dev->requests); @@ -1709,6 +1708,13 @@ const VMStateDescription vmstate_scsi_device = { } }; +static Property scsi_props[] = { + DEFINE_PROP_UINT32("channel", SCSIDevice, channel, 0), + DEFINE_PROP_UINT32("scsi-id", SCSIDevice, id, -1), + DEFINE_PROP_UINT32("lun", SCSIDevice, lun, -1), + DEFINE_PROP_END_OF_LIST(), +}; + static void scsi_device_class_init(ObjectClass *klass, void *data) { DeviceClass *k = DEVICE_CLASS(klass); @@ -1739,6 +1745,28 @@ static const TypeInfo scsi_device_type_info = { .instance_init = scsi_dev_instance_init, }; +static void scsi_bus_class_init(ObjectClass *klass, void *data) +{ + BusClass *k = BUS_CLASS(klass); + HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(klass); + + k->get_dev_path = scsibus_get_dev_path; + k->get_fw_dev_path = scsibus_get_fw_dev_path; + k->check_address = scsi_bus_check_address; + hc->unplug = qdev_simple_device_unplug_cb; +} + +static const TypeInfo scsi_bus_info = { + .name = TYPE_SCSI_BUS, + .parent = TYPE_BUS, + .instance_size = sizeof(SCSIBus), + .class_init = scsi_bus_class_init, + .interfaces = (InterfaceInfo[]) { + { TYPE_HOTPLUG_HANDLER }, + { } + } +}; + static void scsi_register_types(void) { type_register_static(&scsi_bus_info); From patchwork Fri Oct 2 17:35:51 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Bonzini X-Patchwork-Id: 303799 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-12.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id EE274C4363C for ; Fri, 2 Oct 2020 17:43:56 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 7165E206A5 for ; Fri, 2 Oct 2020 17:43:56 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="G01H/Ecy" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 7165E206A5 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:45542 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kOP63-0007qj-IX for qemu-devel@archiver.kernel.org; Fri, 02 Oct 2020 13:43:55 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:44996) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kOOyT-0000PW-UP for qemu-devel@nongnu.org; Fri, 02 Oct 2020 13:36:05 -0400 Received: from mail-wm1-x32d.google.com ([2a00:1450:4864:20::32d]:54463) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1kOOyS-0003JE-EE for qemu-devel@nongnu.org; Fri, 02 Oct 2020 13:36:05 -0400 Received: by mail-wm1-x32d.google.com with SMTP id s13so2429761wmh.4 for ; Fri, 02 Oct 2020 10:36:04 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=hDip1TuoGE2uTB5vESfk4LG+Rb+6jGwMeV9JdwzMKi4=; b=G01H/EcyvqF2YmQZc5uOTabHzb3JS1Jc6ZdneEb/xlYwL+yDSZhNW/y+xqWGtesRzn 0q1syvn1/xfXhMoyDUH77NICImuGynHtEFB5ySQa8/q5lkoz/P76lRYXz2JDPg3DbOj1 gJ6oqUa5lH0H2JXn4Bi1oKJYsYow3qArKh+SdyIlG5yvEqgn55X1rdgPSN7gEYkOlDgb zmGwIBpvZ9OeixyGvHAxvVuQHmYXakueSthTRIvWtbGG4tXDc0BmAN9foRO0QX1c/Jvr u/RYwwLyojhYQn50AEU1mDOPIM1kPIZ/3de2wh+J78fOPOYe/d3o8dhfy5JAPCgpFlKd fw7g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references:mime-version:content-transfer-encoding; bh=hDip1TuoGE2uTB5vESfk4LG+Rb+6jGwMeV9JdwzMKi4=; b=cWy4g7AJz39QjOtJjwsFU6e0oUZlEFrAVprNFSANoMRzszrOdQW59EbQLmVIIX9p9v tu8GDj3ABBrSkBeCU+ZOa+gbPGDihKYGaKvI+Gv8FA/+rPBaVbMj9Td64o4++t1waU59 C3oMtQICoaX+5nitKaFuxAdqirjfA733gEKW4BbBPobjtCAf3YBc1l4bwlPMyowpNBnZ 8coJ92h57aEBJABWaAFqahq/2srn6Pg3WkNSHCkRoKs1EB8uc+UM1HGMTMtFgvMayeAt KVPe1gtPpl5K19WRb64Yhyqu2jrsJyEPqLgiQtkVuJ2H2lKfcfiLFJ1aFH++7uuRSDLW 0wXA== X-Gm-Message-State: AOAM533XT5KziJ2u5m79e8qS3YGYuZDxbc+GP9Qx3gTWZzGoXwRmYNLW q7+ez+hD8aHIfBdyLFaIZdAnyZJaMak= X-Google-Smtp-Source: ABdhPJwwZmc8UGnvwiBJtCM53oIJH/kIksxq0VUqQ0TIJXth3yanVdHe73NJ0y3rau+nKuhokhnM7g== X-Received: by 2002:a05:600c:2186:: with SMTP id e6mr4329959wme.189.1601660162749; Fri, 02 Oct 2020 10:36:02 -0700 (PDT) Received: from donizetti.redhat.com ([2001:b07:6468:f312:47e0:e742:75ba:b84d]) by smtp.gmail.com with ESMTPSA id l8sm2516454wrx.22.2020.10.02.10.36.01 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 02 Oct 2020 10:36:02 -0700 (PDT) From: Paolo Bonzini To: qemu-devel@nongnu.org Subject: [PATCH v6 03/10] scsi/scsi_bus: switch search direction in scsi_device_find Date: Fri, 2 Oct 2020 19:35:51 +0200 Message-Id: <20201002173558.232960-4-pbonzini@redhat.com> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20201002173558.232960-1-pbonzini@redhat.com> References: <20201002173558.232960-1-pbonzini@redhat.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2a00:1450:4864:20::32d; envelope-from=paolo.bonzini@gmail.com; helo=mail-wm1-x32d.google.com X-detected-operating-system: by eggs.gnu.org: No matching host in p0f cache. That's all we know. X-Spam_score_int: -16 X-Spam_score: -1.7 X-Spam_bar: - X-Spam_report: (-1.7 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FORGED_FROMDOMAIN=0.001, FREEMAIL_FROM=0.001, HEADER_FROM_DIFFERENT_DOMAINS=0.25, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Stefan Hajnoczi , Maxim Levitsky Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" From: Maxim Levitsky This change will allow us to convert the bus children list to RCU, while not changing the logic of this function Signed-off-by: Maxim Levitsky Reviewed-by: Stefan Hajnoczi Message-Id: <20200913160259.32145-2-mlevitsk@redhat.com> Signed-off-by: Paolo Bonzini --- hw/scsi/scsi-bus.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/hw/scsi/scsi-bus.c b/hw/scsi/scsi-bus.c index 94921c04b1..69d7c3f90c 100644 --- a/hw/scsi/scsi-bus.c +++ b/hw/scsi/scsi-bus.c @@ -1571,7 +1571,7 @@ SCSIDevice *scsi_device_find(SCSIBus *bus, int channel, int id, int lun) BusChild *kid; SCSIDevice *target_dev = NULL; - QTAILQ_FOREACH_REVERSE(kid, &bus->qbus.children, sibling) { + QTAILQ_FOREACH(kid, &bus->qbus.children, sibling) { DeviceState *qdev = kid->child; SCSIDevice *dev = SCSI_DEVICE(qdev); @@ -1579,7 +1579,15 @@ SCSIDevice *scsi_device_find(SCSIBus *bus, int channel, int id, int lun) if (dev->lun == lun) { return dev; } - target_dev = dev; + + /* + * If we don't find exact match (channel/bus/lun), + * we will return the first device which matches channel/bus + */ + + if (!target_dev) { + target_dev = dev; + } } } return target_dev; From patchwork Fri Oct 2 17:35:52 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Bonzini X-Patchwork-Id: 272165 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-12.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id D3883C4363D for ; Fri, 2 Oct 2020 17:40:55 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 7083A206CA for ; Fri, 2 Oct 2020 17:40:55 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="MUAL6xIf" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 7083A206CA Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:38880 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kOP38-0004X1-Bk for qemu-devel@archiver.kernel.org; Fri, 02 Oct 2020 13:40:54 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:45010) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kOOyU-0000RO-Oj for qemu-devel@nongnu.org; Fri, 02 Oct 2020 13:36:06 -0400 Received: from mail-wm1-x342.google.com ([2a00:1450:4864:20::342]:35539) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1kOOyT-0003JO-6f for qemu-devel@nongnu.org; Fri, 02 Oct 2020 13:36:06 -0400 Received: by mail-wm1-x342.google.com with SMTP id y15so2574391wmi.0 for ; Fri, 02 Oct 2020 10:36:04 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=xXdgD+CX1xaJz1RLqkztVK48fKpoJNRH36Jn29j2m3Q=; b=MUAL6xIf8PviJhDBefAPrh7PcVnrrIOEO099O8FQoxcQFWYJP15tXvdIMXZ4IIPkMf zg4dj+M4JzmME6yx0nmb/62DaPJhI8CM6EmxF6806IyZ6mg/vPhVbBqCRcO1gHGz6dKV IbJ2/qUJ4dAXhiTz87R6NCtW1w6eibvsY+0hk2T8wxx83WrjznW16XBzq6zOdCtQ3FrT sjBMTLCBlhkDj9fabM+tTniRITJk/FuNEXGLfFNV6ZGiQ9SMtejqyRpa2Ah2RAk7uG+O U7mydm3W1I81+5gIpcPjeR4GIIt7iR6Dg7lElHCiD28l15dKtSL97qNCOEsfmDSnYwCX pdZw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references:mime-version:content-transfer-encoding; bh=xXdgD+CX1xaJz1RLqkztVK48fKpoJNRH36Jn29j2m3Q=; b=SAeL9jAHG+v+wB4yRLIhofDnidCddBtZJzyQ13OByVpGaN8kOAoerpcH1TgO0UI3QX HpgeTim9mINgHwQJtQVec0Gm4/4m1CvAAnqtSGrxJBr70PsGPpQ3uRoA4j62L8/L0RaM JCTL+5LTjfuEbohVuvZcQjk0o9nQocNZtY7/WRwpYwgKb30glp6WTF87YxYoB/Wr8aHu krYg/5Xy/vSkDVnQoo3P0yPF0jG8S+s7NGPt6DlC5jIWCgne090vm9ff2jfg63+EHJvH XmCrQiAmWxeKGMioUwjbamADyP91TujrtbvcU+j1O1tpE8Ee9GubhmIwZp04Wq70SkSf 87yg== X-Gm-Message-State: AOAM531cjQMP4gPLcwud2Euqr9h7BrgwhqSN0XlFUetoIGbaVfbU+Hqr gD9vB270kkVn7vgxdnFXM7McJ8Ut6iQ= X-Google-Smtp-Source: ABdhPJwZIGQ7loiGEIqV6MjBkBBlJEQUsSH2w1n8BmoTx03WHcvUOW/SusLD/7zGLY/Qlox9/XKUnQ== X-Received: by 2002:a1c:bbc6:: with SMTP id l189mr4315191wmf.52.1601660163638; Fri, 02 Oct 2020 10:36:03 -0700 (PDT) Received: from donizetti.redhat.com ([2001:b07:6468:f312:47e0:e742:75ba:b84d]) by smtp.gmail.com with ESMTPSA id l8sm2516454wrx.22.2020.10.02.10.36.02 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 02 Oct 2020 10:36:03 -0700 (PDT) From: Paolo Bonzini To: qemu-devel@nongnu.org Subject: [PATCH v6 04/10] device_core: use drain_call_rcu in in qmp_device_add Date: Fri, 2 Oct 2020 19:35:52 +0200 Message-Id: <20201002173558.232960-5-pbonzini@redhat.com> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20201002173558.232960-1-pbonzini@redhat.com> References: <20201002173558.232960-1-pbonzini@redhat.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2a00:1450:4864:20::342; envelope-from=paolo.bonzini@gmail.com; helo=mail-wm1-x342.google.com X-detected-operating-system: by eggs.gnu.org: No matching host in p0f cache. That's all we know. X-Spam_score_int: -16 X-Spam_score: -1.7 X-Spam_bar: - X-Spam_report: (-1.7 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FORGED_FROMDOMAIN=0.001, FREEMAIL_FROM=0.001, HEADER_FROM_DIFFERENT_DOMAINS=0.25, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Stefan Hajnoczi , Stefan Hajnoczi , Maxim Levitsky Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" From: Maxim Levitsky Soon, a device removal might only happen on RCU callback execution. This is okay for device-del which provides a DEVICE_DELETED event, but not for the failure case of device-add. To avoid changing monitor semantics, just drain all pending RCU callbacks on error. Signed-off-by: Maxim Levitsky Suggested-by: Stefan Hajnoczi Reviewed-by: Stefan Hajnoczi Message-Id: <20200913160259.32145-4-mlevitsk@redhat.com> [Don't use it in qmp_device_del. - Paolo] Signed-off-by: Paolo Bonzini --- qdev-monitor.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/qdev-monitor.c b/qdev-monitor.c index e9b7228480..bcfb90a08f 100644 --- a/qdev-monitor.c +++ b/qdev-monitor.c @@ -803,6 +803,18 @@ void qmp_device_add(QDict *qdict, QObject **ret_data, Error **errp) return; } dev = qdev_device_add(opts, errp); + + /* + * Drain all pending RCU callbacks. This is done because + * some bus related operations can delay a device removal + * (in this case this can happen if device is added and then + * removed due to a configuration error) + * to a RCU callback, but user might expect that this interface + * will finish its job completely once qmp command returns result + * to the user + */ + drain_call_rcu(); + if (!dev) { qemu_opts_del(opts); return; From patchwork Fri Oct 2 17:35:53 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Bonzini X-Patchwork-Id: 272163 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-12.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 43A57C35257 for ; Fri, 2 Oct 2020 17:43:57 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id AA6DE20758 for ; Fri, 2 Oct 2020 17:43:56 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="N0GIfbyI" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org AA6DE20758 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:45536 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kOP63-0007qi-RK for qemu-devel@archiver.kernel.org; Fri, 02 Oct 2020 13:43:55 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:45028) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kOOyW-0000Ux-82 for qemu-devel@nongnu.org; Fri, 02 Oct 2020 13:36:08 -0400 Received: from mail-wm1-x344.google.com ([2a00:1450:4864:20::344]:52211) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1kOOyU-0003Jj-8v for qemu-devel@nongnu.org; Fri, 02 Oct 2020 13:36:07 -0400 Received: by mail-wm1-x344.google.com with SMTP id w2so2452893wmi.1 for ; Fri, 02 Oct 2020 10:36:05 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=vBU6G6EU3K8FuII/2jOnVZJBfwDDD7ouVQlKQ+GYXJE=; b=N0GIfbyI7/nweGJQHXHd8QxJIGriJlQQdKUHZHYvP2NhhbTvsMxwGo0Xn0WzkukK7X 30EaIf01UnmUB7fc1B/LVHCqviW8G0DpIO3Rxc5psdhzc+2PHblS52y0Y/aSOijvgN0M HPJJY+y+jwc/xBeSvw0uv+jurLOjXRgiJGLJL829cpugEqsGGyUmixtQVgrEqouEB7Yl WMjYK0Ac1PqQkeraBcFU/wu0ZzJcPyVY8zWAFmyKcOXPo2pAorPfWWnYySOj6CxmW4PV PehP9dIwyoD13g++HmZCk2q9jjKWZjm8K5MEmG2co38u2sukDOX3ofL0vAEWWiV01Tq+ 41wg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references:mime-version:content-transfer-encoding; bh=vBU6G6EU3K8FuII/2jOnVZJBfwDDD7ouVQlKQ+GYXJE=; b=X+xlMUSyUAf68/OxpbpHd73Op5i/GK+IUcRjPihEP/6HkZkRgm2MI+ZYcvEgNJ9GSL wBReSMtn2gLH0COfKkT35ThCAYrUrgU4YzTjHHLlpDPLopjzxM/UYnDR5fYcwSFX0bJS w7OVS+rPClEjkRgRaZ+dDDqxZG6tlmn0EkRunZzqupnYDEfDKk4zBpMfjDRhOOFY/tHZ og/Tnm8E+BlDxn/5GxSUzGyBmzEukqlev14D/i0EcSPdaBiusNFpHzQLwT3IA0GE2+E/ pGAq0i7JKTt7ABIDoiYS4icDxxtVK4/OcXJuPX4/r9jxfvcCCeeslVOaIi9c3mGpY3Ql 0BhA== X-Gm-Message-State: AOAM531Yk0Hci1jS8fg9nNd9axIzMXmO9LaqMlQTzYJ3WIQ+JKVm1H4O l0sgHNwLS9tgoYsK0bU60c1WCiJKEo8= X-Google-Smtp-Source: ABdhPJyTJmRwDUfcySw//UROlE7h1LhhQvPLoPxoW2d9KHHTWDvGcTL438SZsUR7vuSySJ0rN1fPtg== X-Received: by 2002:a1c:7912:: with SMTP id l18mr4045879wme.124.1601660164500; Fri, 02 Oct 2020 10:36:04 -0700 (PDT) Received: from donizetti.redhat.com ([2001:b07:6468:f312:47e0:e742:75ba:b84d]) by smtp.gmail.com with ESMTPSA id l8sm2516454wrx.22.2020.10.02.10.36.03 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 02 Oct 2020 10:36:03 -0700 (PDT) From: Paolo Bonzini To: qemu-devel@nongnu.org Subject: [PATCH v6 05/10] device-core: use RCU for list of children of a bus Date: Fri, 2 Oct 2020 19:35:53 +0200 Message-Id: <20201002173558.232960-6-pbonzini@redhat.com> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20201002173558.232960-1-pbonzini@redhat.com> References: <20201002173558.232960-1-pbonzini@redhat.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2a00:1450:4864:20::344; envelope-from=paolo.bonzini@gmail.com; helo=mail-wm1-x344.google.com X-detected-operating-system: by eggs.gnu.org: No matching host in p0f cache. That's all we know. X-Spam_score_int: -16 X-Spam_score: -1.7 X-Spam_bar: - X-Spam_report: (-1.7 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FORGED_FROMDOMAIN=0.001, FREEMAIL_FROM=0.001, HEADER_FROM_DIFFERENT_DOMAINS=0.25, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Stefan Hajnoczi , Maxim Levitsky Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" From: Maxim Levitsky This fixes the race between device emulation code that tries to find a child device to dispatch the request to (e.g a scsi disk), and hotplug of a new device to that bus. Note that this doesn't convert all the readers of the list but only these that might go over that list without BQL held. This is a very small first step to make this code thread safe. Suggested-by: Paolo Bonzini Signed-off-by: Maxim Levitsky Reviewed-by: Stefan Hajnoczi Message-Id: <20200913160259.32145-5-mlevitsk@redhat.com> [Use RCU_READ_LOCK_GUARD in more places, adjust testcase now that the delay in DEVICE_DELETED due to RCU is more consistent. - Paolo] Signed-off-by: Paolo Bonzini --- hw/core/bus.c | 28 ++++++++++++++++----------- hw/core/qdev.c | 37 ++++++++++++++++++++++-------------- hw/scsi/scsi-bus.c | 12 +++++++++--- hw/scsi/virtio-scsi.c | 6 +++++- include/hw/qdev-core.h | 9 +++++++++ tests/qtest/drive_del-test.c | 10 +++------- 6 files changed, 66 insertions(+), 36 deletions(-) diff --git a/hw/core/bus.c b/hw/core/bus.c index 6b987b6946..a0483859ae 100644 --- a/hw/core/bus.c +++ b/hw/core/bus.c @@ -49,12 +49,14 @@ int qbus_walk_children(BusState *bus, } } - QTAILQ_FOREACH(kid, &bus->children, sibling) { - err = qdev_walk_children(kid->child, - pre_devfn, pre_busfn, - post_devfn, post_busfn, opaque); - if (err < 0) { - return err; + WITH_RCU_READ_LOCK_GUARD() { + QTAILQ_FOREACH_RCU(kid, &bus->children, sibling) { + err = qdev_walk_children(kid->child, + pre_devfn, pre_busfn, + post_devfn, post_busfn, opaque); + if (err < 0) { + return err; + } } } @@ -90,8 +92,10 @@ static void bus_reset_child_foreach(Object *obj, ResettableChildCallback cb, BusState *bus = BUS(obj); BusChild *kid; - QTAILQ_FOREACH(kid, &bus->children, sibling) { - cb(OBJECT(kid->child), opaque, type); + WITH_RCU_READ_LOCK_GUARD() { + QTAILQ_FOREACH_RCU(kid, &bus->children, sibling) { + cb(OBJECT(kid->child), opaque, type); + } } } @@ -194,9 +198,11 @@ static void bus_set_realized(Object *obj, bool value, Error **errp) /* TODO: recursive realization */ } else if (!value && bus->realized) { - QTAILQ_FOREACH(kid, &bus->children, sibling) { - DeviceState *dev = kid->child; - qdev_unrealize(dev); + WITH_RCU_READ_LOCK_GUARD() { + QTAILQ_FOREACH_RCU(kid, &bus->children, sibling) { + DeviceState *dev = kid->child; + qdev_unrealize(dev); + } } if (bc->unrealize) { bc->unrealize(bus); diff --git a/hw/core/qdev.c b/hw/core/qdev.c index 74db78df36..59e5e710b7 100644 --- a/hw/core/qdev.c +++ b/hw/core/qdev.c @@ -51,6 +51,12 @@ const VMStateDescription *qdev_get_vmsd(DeviceState *dev) return dc->vmsd; } +static void bus_free_bus_child(BusChild *kid) +{ + object_unref(OBJECT(kid->child)); + g_free(kid); +} + static void bus_remove_child(BusState *bus, DeviceState *child) { BusChild *kid; @@ -60,15 +66,16 @@ static void bus_remove_child(BusState *bus, DeviceState *child) char name[32]; snprintf(name, sizeof(name), "child[%d]", kid->index); - QTAILQ_REMOVE(&bus->children, kid, sibling); + QTAILQ_REMOVE_RCU(&bus->children, kid, sibling); bus->num_children--; /* This gives back ownership of kid->child back to us. */ object_property_del(OBJECT(bus), name); - object_unref(OBJECT(kid->child)); - g_free(kid); - return; + + /* free the bus kid, when it is safe to do so*/ + call_rcu(kid, bus_free_bus_child, rcu); + break; } } } @@ -83,7 +90,7 @@ static void bus_add_child(BusState *bus, DeviceState *child) kid->child = child; object_ref(OBJECT(kid->child)); - QTAILQ_INSERT_HEAD(&bus->children, kid, sibling); + QTAILQ_INSERT_HEAD_RCU(&bus->children, kid, sibling); /* This transfers ownership of kid->child to the property. */ snprintf(name, sizeof(name), "child[%d]", kid->index); @@ -672,17 +679,19 @@ DeviceState *qdev_find_recursive(BusState *bus, const char *id) DeviceState *ret; BusState *child; - QTAILQ_FOREACH(kid, &bus->children, sibling) { - DeviceState *dev = kid->child; + WITH_RCU_READ_LOCK_GUARD() { + QTAILQ_FOREACH_RCU(kid, &bus->children, sibling) { + DeviceState *dev = kid->child; - if (dev->id && strcmp(dev->id, id) == 0) { - return dev; - } + if (dev->id && strcmp(dev->id, id) == 0) { + return dev; + } - QLIST_FOREACH(child, &dev->child_bus, sibling) { - ret = qdev_find_recursive(child, id); - if (ret) { - return ret; + QLIST_FOREACH(child, &dev->child_bus, sibling) { + ret = qdev_find_recursive(child, id); + if (ret) { + return ret; + } } } } diff --git a/hw/scsi/scsi-bus.c b/hw/scsi/scsi-bus.c index 69d7c3f90c..4ab9811cd8 100644 --- a/hw/scsi/scsi-bus.c +++ b/hw/scsi/scsi-bus.c @@ -399,7 +399,10 @@ static bool scsi_target_emulate_report_luns(SCSITargetReq *r) id = r->req.dev->id; found_lun0 = false; n = 0; - QTAILQ_FOREACH(kid, &r->req.bus->qbus.children, sibling) { + + RCU_READ_LOCK_GUARD(); + + QTAILQ_FOREACH_RCU(kid, &r->req.bus->qbus.children, sibling) { DeviceState *qdev = kid->child; SCSIDevice *dev = SCSI_DEVICE(qdev); @@ -420,7 +423,7 @@ static bool scsi_target_emulate_report_luns(SCSITargetReq *r) memset(r->buf, 0, len); stl_be_p(&r->buf[0], n); i = found_lun0 ? 8 : 16; - QTAILQ_FOREACH(kid, &r->req.bus->qbus.children, sibling) { + QTAILQ_FOREACH_RCU(kid, &r->req.bus->qbus.children, sibling) { DeviceState *qdev = kid->child; SCSIDevice *dev = SCSI_DEVICE(qdev); @@ -429,6 +432,7 @@ static bool scsi_target_emulate_report_luns(SCSITargetReq *r) i += 8; } } + assert(i == n + 8); r->len = len; return true; @@ -1571,7 +1575,8 @@ SCSIDevice *scsi_device_find(SCSIBus *bus, int channel, int id, int lun) BusChild *kid; SCSIDevice *target_dev = NULL; - QTAILQ_FOREACH(kid, &bus->qbus.children, sibling) { + RCU_READ_LOCK_GUARD(); + QTAILQ_FOREACH_RCU(kid, &bus->qbus.children, sibling) { DeviceState *qdev = kid->child; SCSIDevice *dev = SCSI_DEVICE(qdev); @@ -1590,6 +1595,7 @@ SCSIDevice *scsi_device_find(SCSIBus *bus, int channel, int id, int lun) } } } + return target_dev; } diff --git a/hw/scsi/virtio-scsi.c b/hw/scsi/virtio-scsi.c index 3a71ea7097..971afbb217 100644 --- a/hw/scsi/virtio-scsi.c +++ b/hw/scsi/virtio-scsi.c @@ -367,12 +367,16 @@ static int virtio_scsi_do_tmf(VirtIOSCSI *s, VirtIOSCSIReq *req) case VIRTIO_SCSI_T_TMF_I_T_NEXUS_RESET: target = req->req.tmf.lun[1]; s->resetting++; - QTAILQ_FOREACH(kid, &s->bus.qbus.children, sibling) { + + rcu_read_lock(); + QTAILQ_FOREACH_RCU(kid, &s->bus.qbus.children, sibling) { d = SCSI_DEVICE(kid->child); if (d->channel == 0 && d->id == target) { qdev_reset_all(&d->qdev); } } + rcu_read_unlock(); + s->resetting--; break; diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h index 14d476c587..2c6307e3ed 100644 --- a/include/hw/qdev-core.h +++ b/include/hw/qdev-core.h @@ -3,6 +3,8 @@ #include "qemu/queue.h" #include "qemu/bitmap.h" +#include "qemu/rcu.h" +#include "qemu/rcu_queue.h" #include "qom/object.h" #include "hw/hotplug.h" #include "hw/resettable.h" @@ -238,6 +240,7 @@ struct BusClass { }; typedef struct BusChild { + struct rcu_head rcu; DeviceState *child; int index; QTAILQ_ENTRY(BusChild) sibling; @@ -258,6 +261,12 @@ struct BusState { int max_index; bool realized; int num_children; + + /* + * children is a RCU QTAILQ, thus readers must use RCU to access it, + * and writers must hold the big qemu lock + */ + QTAILQ_HEAD(, BusChild) children; QLIST_ENTRY(BusState) sibling; ResettableState reset; diff --git a/tests/qtest/drive_del-test.c b/tests/qtest/drive_del-test.c index 2d765865ce..05184124a2 100644 --- a/tests/qtest/drive_del-test.c +++ b/tests/qtest/drive_del-test.c @@ -15,9 +15,6 @@ #include "libqos/virtio.h" #include "qapi/qmp/qdict.h" -/* TODO actually test the results and get rid of this */ -#define qmp_discard_response(q, ...) qobject_unref(qtest_qmp(q, __VA_ARGS__)) - static void drive_add(QTestState *qts) { char *resp = qtest_hmp(qts, "drive_add 0 if=none,id=drive0"); @@ -38,12 +35,11 @@ static void device_del(QTestState *qts) { QDict *response; - /* Complication: ignore DEVICE_DELETED event */ - qmp_discard_response(qts, "{'execute': 'device_del'," - " 'arguments': { 'id': 'dev0' } }"); - response = qtest_qmp_receive(qts); + response = qtest_qmp(qts, "{'execute': 'device_del'," + " 'arguments': { 'id': 'dev0' } }"); g_assert(response); g_assert(qdict_haskey(response, "return")); + qtest_qmp_eventwait(qts, "DEVICE_DELETED"); qobject_unref(response); } From patchwork Fri Oct 2 17:35:54 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Bonzini X-Patchwork-Id: 303798 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-12.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 94882C4363C for ; Fri, 2 Oct 2020 17:45:58 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 20241206A5 for ; Fri, 2 Oct 2020 17:45:58 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="OhYyxNjR" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 20241206A5 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:50086 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kOP80-0001M0-Ur for qemu-devel@archiver.kernel.org; Fri, 02 Oct 2020 13:45:57 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:45048) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kOOyX-0000Xb-9Q for qemu-devel@nongnu.org; Fri, 02 Oct 2020 13:36:09 -0400 Received: from mail-wr1-x441.google.com ([2a00:1450:4864:20::441]:44719) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1kOOyV-0003K4-32 for qemu-devel@nongnu.org; Fri, 02 Oct 2020 13:36:08 -0400 Received: by mail-wr1-x441.google.com with SMTP id s12so2661347wrw.11 for ; Fri, 02 Oct 2020 10:36:06 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=nBtGQHWCtBz1UuRn2EA9dhKJU3PmW9+7UuhXaOrWq6I=; b=OhYyxNjRLPiEoT83UGLbnp3gPXfjJ0Pfuc/rSTH0ivA07LOudVpCmrv1fbM4B20qQf 7nKeVSbtPRpyykiFFc8V/Tupj181FG/Fpj81dWRsn99njPnM9NdtfHGrv4SCrvboPuMW jgzLB/Yg8Sezfu0/9hbPro4Nukt5sWA9asrks/4TuoYNZJRWzz7pZbwEmyZjz+DFn7gG tUwTgLHnfTm7wBHSO064ttkut8s6a8MNIhS3qVgf6kILClD48CY5EmGdJ62pQEe+6JJA 2G/l87eh7JXsrHg/Mkjf9wv20BfRQtA1fOJMm56mZP/ib0DWbygP/dEKPlTQQc9A473a OB3A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references:mime-version:content-transfer-encoding; bh=nBtGQHWCtBz1UuRn2EA9dhKJU3PmW9+7UuhXaOrWq6I=; b=Jz4p5mnjMwapV/R2R4iTyKtZcKixydcOGqo91vSSGZt+dmJom9T3cb3nAnp31tPQqX r29Mb/qPGic9pSNUy25SZ0MqwvOc8FvKO3Y0V8JGvi6YdN3f+Ug1oftway3g59SWUlqQ C9rrvces9xtaae6ZlTos8A6fYspPxY8UOC0+MjoiG0cdytGzwfkFiHRg0kQbsiqzZ7+M L+8ZUJUxjmU5z5eyJrpkjCEyhxClbm0Tzw0Trk4ri30WIhfl6PIKnUawbLNAUlAw4v6d +p4+oTbqmxZ7ggR/HqhrL6wQEwOaCumNA848+LaQycRSm+qNs+5BVUtrwI67osbgHIQE rLDg== X-Gm-Message-State: AOAM533H0OiytmUf+D/QfJ6bqoRwNI7TID8lL40IR7THfZWIHOx3KNE9 S8PSQ8ouvVhICIF+BDZdkFwH+x425fk= X-Google-Smtp-Source: ABdhPJxAViXAdzabs5RKv6eu0Kq6o/5hBqjl+nVRGuJkCTVP/4YRUZRRjwWIO9KImhGGMMthLYFp8w== X-Received: by 2002:adf:e292:: with SMTP id v18mr4251306wri.256.1601660165528; Fri, 02 Oct 2020 10:36:05 -0700 (PDT) Received: from donizetti.redhat.com ([2001:b07:6468:f312:47e0:e742:75ba:b84d]) by smtp.gmail.com with ESMTPSA id l8sm2516454wrx.22.2020.10.02.10.36.04 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 02 Oct 2020 10:36:04 -0700 (PDT) From: Paolo Bonzini To: qemu-devel@nongnu.org Subject: [PATCH v6 06/10] device-core: use atomic_set on .realized property Date: Fri, 2 Oct 2020 19:35:54 +0200 Message-Id: <20201002173558.232960-7-pbonzini@redhat.com> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20201002173558.232960-1-pbonzini@redhat.com> References: <20201002173558.232960-1-pbonzini@redhat.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2a00:1450:4864:20::441; envelope-from=paolo.bonzini@gmail.com; helo=mail-wr1-x441.google.com X-detected-operating-system: by eggs.gnu.org: No matching host in p0f cache. That's all we know. X-Spam_score_int: -16 X-Spam_score: -1.7 X-Spam_bar: - X-Spam_report: (-1.7 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FORGED_FROMDOMAIN=0.001, FREEMAIL_FROM=0.001, HEADER_FROM_DIFFERENT_DOMAINS=0.25, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Stefan Hajnoczi , Maxim Levitsky Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" From: Maxim Levitsky Some code might race with placement of new devices on a bus. We currently first place a (unrealized) device on the bus and then realize it. As a workaround, users that scan the child device list, can check the realized property to see if it is safe to access such a device. Use an atomic write here too to aid with this. A separate discussion is what to do with devices that are unrealized: It looks like for this case we only call the hotplug handler's unplug callback and its up to it to unrealize the device. An atomic operation doesn't cause harm for this code path though. Signed-off-by: Maxim Levitsky Reviewed-by: Stefan Hajnoczi Message-Id: <20200913160259.32145-6-mlevitsk@redhat.com> Signed-off-by: Paolo Bonzini --- hw/core/qdev.c | 19 ++++++++++++++++++- include/hw/qdev-core.h | 2 ++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/hw/core/qdev.c b/hw/core/qdev.c index 59e5e710b7..fc4daa36fa 100644 --- a/hw/core/qdev.c +++ b/hw/core/qdev.c @@ -946,7 +946,25 @@ static void device_set_realized(Object *obj, bool value, Error **errp) } } + qatomic_store_release(&dev->realized, value); + } else if (!value && dev->realized) { + + /* + * Change the value so that any concurrent users are aware + * that the device is going to be unrealized + * + * TODO: change .realized property to enum that states + * each phase of the device realization/unrealization + */ + + qatomic_set(&dev->realized, value); + /* + * Ensure that concurrent users see this update prior to + * any other changes done by unrealize. + */ + smp_wmb(); + QLIST_FOREACH(bus, &dev->child_bus, sibling) { qbus_unrealize(bus); } @@ -961,7 +979,6 @@ static void device_set_realized(Object *obj, bool value, Error **errp) } assert(local_err == NULL); - dev->realized = value; return; child_realize_fail: diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h index 2c6307e3ed..868973319e 100644 --- a/include/hw/qdev-core.h +++ b/include/hw/qdev-core.h @@ -163,6 +163,8 @@ struct NamedClockList { /** * DeviceState: * @realized: Indicates whether the device has been fully constructed. + * When accessed outsize big qemu lock, must be accessed with + * atomic_load_acquire() * @reset: ResettableState for the device; handled by Resettable interface. * * This structure should not be accessed directly. We declare it here From patchwork Fri Oct 2 17:35:55 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Bonzini X-Patchwork-Id: 272162 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-12.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 7C461C4363D for ; Fri, 2 Oct 2020 17:45:59 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 1F38C206A5 for ; Fri, 2 Oct 2020 17:45:59 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="oOdc85EI" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 1F38C206A5 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:50146 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kOP82-0001Nw-7j for qemu-devel@archiver.kernel.org; Fri, 02 Oct 2020 13:45:58 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:45068) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kOOyY-0000Yi-3l for qemu-devel@nongnu.org; Fri, 02 Oct 2020 13:36:10 -0400 Received: from mail-wm1-x32f.google.com ([2a00:1450:4864:20::32f]:35657) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1kOOyW-0003KN-04 for qemu-devel@nongnu.org; Fri, 02 Oct 2020 13:36:09 -0400 Received: by mail-wm1-x32f.google.com with SMTP id y15so2574517wmi.0 for ; Fri, 02 Oct 2020 10:36:07 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=ZPbac6yldkPR9wbmEuvA0p1poWNownh7RtPwmzH/4gc=; b=oOdc85EI4W3FKST0yJcry7ZwPq6+GyCFzwdhbEYAbPTD7qBEFSQMh6v1exLLslLdws XXb7sPuZg36mEynvdTSHIIU6TUII2uK6rDAC0sEf712nptOtQpfuz6m9Qe0rEoneZi6n rbUyvRYOJM7iJ0wsy5G9sCRqhRCkPKPZit5K9yuLXgAnDiaXTbULfhA9USP597fIPZ64 McM4+xAmFf6ucANeQwYsWoahxosCLfK1Rz2q+oXgHRk873dCGd5oudMDvLTwlwcdcXQu dG5T97boaTktihbaf3C2Rmg8jWmhzuNeu5yU4c5Z823K7Vf9P+DfBqickqBiUhTsMljn k9tQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references:mime-version:content-transfer-encoding; bh=ZPbac6yldkPR9wbmEuvA0p1poWNownh7RtPwmzH/4gc=; b=UnKRb4tcEQ3gfYW84/pyedvZwE/073YYLD8M2zGpbi+qfaqGfehDZ6NJzb1Y7pCsPi tH2d4WZBw2b8mkKuZBP121xk6i1djEKQdIdhgesfDF1H29jLyzh/5Qf1FCcRiX1wz4Oh zIlmkTMrlzCZDEJ/CiCLz5ekmmn12qiYtM26JILVLGF+OK1+phf8VwQz7SAyWsKJIr+i egvEQwIX+9WpH5NEbo/5y7SHh/IRFiLee3cniyJCGbtBKAWMDNrnun5JFTCv8acRjI5m Ty86jBivPkSGjCRAqczQkuzk5/OfLUGd7Ody8nGU7CUXcrZpMGJzBX68JQj8QqUIK78A OWEg== X-Gm-Message-State: AOAM5323NBPhpwWh0DNJ9vmq5qtGC/m5D26uqOjjfh9pFAcyjDcnHooi oCQXPNkOCy7SKIW0zK2gJDHpV2ghbls= X-Google-Smtp-Source: ABdhPJzw6ONK159SmQaIfdjsJfS6cXvrlj2imZg/u7eq/eC/9ut8EDwVnWFwcye/do752nsplh2Wqg== X-Received: by 2002:a1c:9c8c:: with SMTP id f134mr4033591wme.27.1601660166396; Fri, 02 Oct 2020 10:36:06 -0700 (PDT) Received: from donizetti.redhat.com ([2001:b07:6468:f312:47e0:e742:75ba:b84d]) by smtp.gmail.com with ESMTPSA id l8sm2516454wrx.22.2020.10.02.10.36.05 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 02 Oct 2020 10:36:05 -0700 (PDT) From: Paolo Bonzini To: qemu-devel@nongnu.org Subject: [PATCH v6 07/10] scsi/scsi-bus: scsi_device_find: don't return unrealized devices Date: Fri, 2 Oct 2020 19:35:55 +0200 Message-Id: <20201002173558.232960-8-pbonzini@redhat.com> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20201002173558.232960-1-pbonzini@redhat.com> References: <20201002173558.232960-1-pbonzini@redhat.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2a00:1450:4864:20::32f; envelope-from=paolo.bonzini@gmail.com; helo=mail-wm1-x32f.google.com X-detected-operating-system: by eggs.gnu.org: No matching host in p0f cache. That's all we know. X-Spam_score_int: -16 X-Spam_score: -1.7 X-Spam_bar: - X-Spam_report: (-1.7 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FORGED_FROMDOMAIN=0.001, FREEMAIL_FROM=0.001, HEADER_FROM_DIFFERENT_DOMAINS=0.25, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Stefan Hajnoczi , Maxim Levitsky Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" The device core first places a device on the bus and then realizes it. Make scsi_device_find avoid returing such devices to avoid races in drivers that use an iothread (currently virtio-scsi) Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1812399 Suggested-by: Paolo Bonzini Signed-off-by: Maxim Levitsky Reviewed-by: Stefan Hajnoczi Message-Id: <20200913160259.32145-7-mlevitsk@redhat.com> Signed-off-by: Paolo Bonzini --- hw/scsi/scsi-bus.c | 83 +++++++++++++++++++++++++++++----------------- 1 file changed, 53 insertions(+), 30 deletions(-) diff --git a/hw/scsi/scsi-bus.c b/hw/scsi/scsi-bus.c index 4ab9811cd8..7599113efe 100644 --- a/hw/scsi/scsi-bus.c +++ b/hw/scsi/scsi-bus.c @@ -24,6 +24,55 @@ static void scsi_target_free_buf(SCSIRequest *req); static int next_scsi_bus; +static SCSIDevice *do_scsi_device_find(SCSIBus *bus, + int channel, int id, int lun, + bool include_unrealized) +{ + BusChild *kid; + SCSIDevice *retval = NULL; + + QTAILQ_FOREACH_RCU(kid, &bus->qbus.children, sibling) { + DeviceState *qdev = kid->child; + SCSIDevice *dev = SCSI_DEVICE(qdev); + + if (dev->channel == channel && dev->id == id) { + if (dev->lun == lun) { + retval = dev; + break; + } + + /* + * If we don't find exact match (channel/bus/lun), + * we will return the first device which matches channel/bus + */ + + if (!retval) { + retval = dev; + } + } + } + + /* + * This function might run on the IO thread and we might race against + * main thread hot-plugging the device. + * We assume that as soon as .realized is set to true we can let + * the user access the device. + */ + + if (retval && !include_unrealized && + !qatomic_load_acquire(&retval->qdev.realized)) { + retval = NULL; + } + + return retval; +} + +SCSIDevice *scsi_device_find(SCSIBus *bus, int channel, int id, int lun) +{ + RCU_READ_LOCK_GUARD(); + return do_scsi_device_find(bus, channel, id, lun, false); +} + static void scsi_device_realize(SCSIDevice *s, Error **errp) { SCSIDeviceClass *sc = SCSI_DEVICE_GET_CLASS(s); @@ -137,7 +186,10 @@ static bool scsi_bus_is_address_free(SCSIBus *bus, int channel, int target, int lun, SCSIDevice **p_dev) { - SCSIDevice *d = scsi_device_find(bus, channel, target, lun); + SCSIDevice *d; + + RCU_READ_LOCK_GUARD(); + d = do_scsi_device_find(bus, channel, target, lun, true); if (d && d->lun == lun) { if (p_dev) { *p_dev = d; @@ -1570,35 +1622,6 @@ static char *scsibus_get_fw_dev_path(DeviceState *dev) qdev_fw_name(dev), d->id, d->lun); } -SCSIDevice *scsi_device_find(SCSIBus *bus, int channel, int id, int lun) -{ - BusChild *kid; - SCSIDevice *target_dev = NULL; - - RCU_READ_LOCK_GUARD(); - QTAILQ_FOREACH_RCU(kid, &bus->qbus.children, sibling) { - DeviceState *qdev = kid->child; - SCSIDevice *dev = SCSI_DEVICE(qdev); - - if (dev->channel == channel && dev->id == id) { - if (dev->lun == lun) { - return dev; - } - - /* - * If we don't find exact match (channel/bus/lun), - * we will return the first device which matches channel/bus - */ - - if (!target_dev) { - target_dev = dev; - } - } - } - - return target_dev; -} - /* SCSI request list. For simplicity, pv points to the whole device */ static int put_scsi_requests(QEMUFile *f, void *pv, size_t size, From patchwork Fri Oct 2 17:35:56 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Bonzini X-Patchwork-Id: 303801 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-12.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id C69C6C4363C for ; Fri, 2 Oct 2020 17:38:04 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 49469206CA for ; Fri, 2 Oct 2020 17:38:04 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="WOySHyzd" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 49469206CA Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:35562 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kOP0N-0002zq-7b for qemu-devel@archiver.kernel.org; Fri, 02 Oct 2020 13:38:03 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:45076) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kOOyY-0000Yr-Ki for qemu-devel@nongnu.org; Fri, 02 Oct 2020 13:36:11 -0400 Received: from mail-wr1-x42f.google.com ([2a00:1450:4864:20::42f]:40367) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1kOOyW-0003KY-Qd for qemu-devel@nongnu.org; Fri, 02 Oct 2020 13:36:10 -0400 Received: by mail-wr1-x42f.google.com with SMTP id j2so2679193wrx.7 for ; Fri, 02 Oct 2020 10:36:08 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=CIHGBqIWtbWESa47zsQ9GTVFuyweiSkZ/Mu8fjQk2dY=; b=WOySHyzdBTPzAxMkdUinxkswZxWCvDA24tA1Pi0WqiH+vDyCXjHmhukNHMbCbauI3e sRc3y071UBrCadKjMWSh7j4mqmnIk9/0ETUSm0IJgPYRDmFuhhKtqdJNfnHggiEIPN+V VKGm/g3weLXDGjLaX0y5feC3IYwyE2Mch67tfImyJH0MvoEdU764Gv7YwbJvOs6hDhvS JbJL6fJcDFEzrvZCqFDNYlWT7wHoKhRk58jm2+9OV7RujI0KKGvEmFQgZUGOJdPH72tp IBz1IwrVu6Pw7ZZQ5PQ7RKAeEBU8MocqiTIzLc4xZ+PZzWH8Z4tSW0/fOOKbch//qmYh GZpw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references:mime-version:content-transfer-encoding; bh=CIHGBqIWtbWESa47zsQ9GTVFuyweiSkZ/Mu8fjQk2dY=; b=Qec6KYjAGSlpvyhdNHX2I7U+uZbp3oF09XL1p1vqHvbkRV+m12CBVXwN/HyXm4Odbd atbFx2xW4aqPl61delQTcPmYfHwCgECS9ZMDshCybKDvhpkmERC5s1e5fPQdgayCONnh 77woCxDQbt2QR8OJMi/I9a3URObp4kLnlb6IRWnAUBhbQY8PzkNt+GHpnAq0ma53WAQ3 Df/hP9yOYPoNrDyoJesvnBmTzI+DfNbQr6l/RULeZlvOC1KtJ7QVvikzqk05LBQt31FX vfMgk0mzLCztVZ85w1ky8clB23YDttsFNb0n1DVSt5vtWJRrWRfJeIB4Sa97tbYKSyru wneA== X-Gm-Message-State: AOAM532XFNuFwO12azL6aOe+bIWRNmYVrr9ws/ZvofmLdPPTafCgc7Iz yEfthRkR/OT3+xgYePElyrrd/6te+XU= X-Google-Smtp-Source: ABdhPJyebixF1wc6t8n3bjMcNqC12IhFcO1/iu4m+f7s+yxJl53leS7gW21hJz1Vl3YyFyKUm9/UUw== X-Received: by 2002:adf:f290:: with SMTP id k16mr4555422wro.124.1601660167266; Fri, 02 Oct 2020 10:36:07 -0700 (PDT) Received: from donizetti.redhat.com ([2001:b07:6468:f312:47e0:e742:75ba:b84d]) by smtp.gmail.com with ESMTPSA id l8sm2516454wrx.22.2020.10.02.10.36.06 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 02 Oct 2020 10:36:06 -0700 (PDT) From: Paolo Bonzini To: qemu-devel@nongnu.org Subject: [PATCH v6 08/10] scsi/scsi_bus: Add scsi_device_get Date: Fri, 2 Oct 2020 19:35:56 +0200 Message-Id: <20201002173558.232960-9-pbonzini@redhat.com> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20201002173558.232960-1-pbonzini@redhat.com> References: <20201002173558.232960-1-pbonzini@redhat.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2a00:1450:4864:20::42f; envelope-from=paolo.bonzini@gmail.com; helo=mail-wr1-x42f.google.com X-detected-operating-system: by eggs.gnu.org: No matching host in p0f cache. That's all we know. X-Spam_score_int: -16 X-Spam_score: -1.7 X-Spam_bar: - X-Spam_report: (-1.7 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FORGED_FROMDOMAIN=0.001, FREEMAIL_FROM=0.001, HEADER_FROM_DIFFERENT_DOMAINS=0.25, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Stefan Hajnoczi , Maxim Levitsky Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" From: Maxim Levitsky Add scsi_device_get which finds the scsi device and takes a reference to it. Suggested-by: Stefan Hajnoczi Signed-off-by: Maxim Levitsky Message-Id: <20200913160259.32145-8-mlevitsk@redhat.com> Signed-off-by: Paolo Bonzini --- hw/scsi/scsi-bus.c | 11 +++++++++++ include/hw/scsi/scsi.h | 1 + 2 files changed, 12 insertions(+) diff --git a/hw/scsi/scsi-bus.c b/hw/scsi/scsi-bus.c index 7599113efe..eda8cb7e70 100644 --- a/hw/scsi/scsi-bus.c +++ b/hw/scsi/scsi-bus.c @@ -73,6 +73,17 @@ SCSIDevice *scsi_device_find(SCSIBus *bus, int channel, int id, int lun) return do_scsi_device_find(bus, channel, id, lun, false); } +SCSIDevice *scsi_device_get(SCSIBus *bus, int channel, int id, int lun) +{ + SCSIDevice *d; + RCU_READ_LOCK_GUARD(); + d = do_scsi_device_find(bus, channel, id, lun, false); + if (d) { + object_ref(d); + } + return d; +} + static void scsi_device_realize(SCSIDevice *s, Error **errp) { SCSIDeviceClass *sc = SCSI_DEVICE_GET_CLASS(s); diff --git a/include/hw/scsi/scsi.h b/include/hw/scsi/scsi.h index 7a55cdbd74..09fa5c9d2a 100644 --- a/include/hw/scsi/scsi.h +++ b/include/hw/scsi/scsi.h @@ -190,6 +190,7 @@ int scsi_device_get_sense(SCSIDevice *dev, uint8_t *buf, int len, bool fixed); int scsi_SG_IO_FROM_DEV(BlockBackend *blk, uint8_t *cmd, uint8_t cmd_size, uint8_t *buf, uint8_t buf_size); SCSIDevice *scsi_device_find(SCSIBus *bus, int channel, int target, int lun); +SCSIDevice *scsi_device_get(SCSIBus *bus, int channel, int target, int lun); /* scsi-generic.c. */ extern const SCSIReqOps scsi_generic_req_ops; From patchwork Fri Oct 2 17:35:57 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Bonzini X-Patchwork-Id: 303797 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-12.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id D6F05C4363C for ; Fri, 2 Oct 2020 17:48:20 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 4B65C206DD for ; Fri, 2 Oct 2020 17:48:20 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="cvFEqyRD" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 4B65C206DD Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:54980 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kOPAJ-0003Ti-Cx for qemu-devel@archiver.kernel.org; Fri, 02 Oct 2020 13:48:19 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:45102) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kOOyZ-0000Z7-Ll for qemu-devel@nongnu.org; Fri, 02 Oct 2020 13:36:11 -0400 Received: from mail-wr1-x436.google.com ([2a00:1450:4864:20::436]:44702) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1kOOyX-0003Ko-Rd for qemu-devel@nongnu.org; Fri, 02 Oct 2020 13:36:11 -0400 Received: by mail-wr1-x436.google.com with SMTP id s12so2661477wrw.11 for ; Fri, 02 Oct 2020 10:36:09 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=Pt5SqnBPWAurqH7od5/LojSGd2ksGXHGLBemqG3ZaZc=; b=cvFEqyRD4TcbaogQkN/LkgTXJhdPZyidbuRUvFGdMM7lxGphRkkoNXliH95KLI5Xt1 PUM+Bkv6uHerNU08wF5eFrIGJWvkdpF5n1qgEW9CdQJhK2tKdMZHGMCo1ESGI9NNr4Ca 4AGjxXudctL5MsC9EG5CoLF8LFtr8eH6r1UqmoV0GYFQD7O5oySF0VY3ZSuIGGbCxtMt mIPmR5r6O8evaOXdN7LmbTyffi6TI8/XDR9e9fIBVYzPendKtkzJSvw3t7EUYey7KJvq 3JjbFVn5Z5+F2ZOAdLErt1afqKlgPUQqhgbxlZPdEhl+zTwcl9m5BY+An3FLSxajC9Gn nTVA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references:mime-version:content-transfer-encoding; bh=Pt5SqnBPWAurqH7od5/LojSGd2ksGXHGLBemqG3ZaZc=; b=DXa3BcPR2V+auSguvugb73wjTFB182wpe/Z4URTAeqSYZmSaJs9y2hLBhUsobHgH0o zeqWKXlzOGPaELjLHdzvoTMA9819yEECGHx7uL9nkpIccl5i7S/1fnDDz5K/io5mgtkb NnHzs9SE8tuh0AVUglO9VdDfVVwS6K8zCBwvEptLVIU/odbHedQhN/7l7kNHStOAESaT kg2QMuznPrUqu9dcWNbrpaJipiOWJ5tYPXyXRdRgOekLitSwyFnSvCKwcMUQdn+OSCNA nJxxTrU2sOMZr+qgKPR9rplo+CDShhD5gHn9jM+Z1/ich1qG7myn6u0zmGRan72O07e6 ZfqQ== X-Gm-Message-State: AOAM532epWi4CKAdEgn+airxowINlpGhlvbamKCZsLTn0lj1OqZyaoqc Qupi1VGC52RjyRx7cI34Ae2ZFIji7gQ= X-Google-Smtp-Source: ABdhPJwb3KtapC6Y727xtAZg64kSi8RuweGJeDIQMzesiHkSqz6cP0Qxdi0xmju1RNTPCIa6ubdz6Q== X-Received: by 2002:adf:e74d:: with SMTP id c13mr4139767wrn.45.1601660168090; Fri, 02 Oct 2020 10:36:08 -0700 (PDT) Received: from donizetti.redhat.com ([2001:b07:6468:f312:47e0:e742:75ba:b84d]) by smtp.gmail.com with ESMTPSA id l8sm2516454wrx.22.2020.10.02.10.36.07 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 02 Oct 2020 10:36:07 -0700 (PDT) From: Paolo Bonzini To: qemu-devel@nongnu.org Subject: [PATCH v6 09/10] virtio-scsi: use scsi_device_get Date: Fri, 2 Oct 2020 19:35:57 +0200 Message-Id: <20201002173558.232960-10-pbonzini@redhat.com> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20201002173558.232960-1-pbonzini@redhat.com> References: <20201002173558.232960-1-pbonzini@redhat.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2a00:1450:4864:20::436; envelope-from=paolo.bonzini@gmail.com; helo=mail-wr1-x436.google.com X-detected-operating-system: by eggs.gnu.org: No matching host in p0f cache. That's all we know. X-Spam_score_int: -16 X-Spam_score: -1.7 X-Spam_bar: - X-Spam_report: (-1.7 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FORGED_FROMDOMAIN=0.001, FREEMAIL_FROM=0.001, HEADER_FROM_DIFFERENT_DOMAINS=0.25, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Stefan Hajnoczi , Stefan Hajnoczi , Maxim Levitsky Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" From: Maxim Levitsky This will help us to avoid the scsi device disappearing after we took a reference to it. It doesn't by itself forbid case when we try to access an unrealized device Suggested-by: Stefan Hajnoczi Signed-off-by: Maxim Levitsky Reviewed-by: Stefan Hajnoczi Message-Id: <20200913160259.32145-9-mlevitsk@redhat.com> Signed-off-by: Paolo Bonzini --- hw/scsi/virtio-scsi.c | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/hw/scsi/virtio-scsi.c b/hw/scsi/virtio-scsi.c index 971afbb217..3db9a8aae9 100644 --- a/hw/scsi/virtio-scsi.c +++ b/hw/scsi/virtio-scsi.c @@ -33,7 +33,7 @@ static inline int virtio_scsi_get_lun(uint8_t *lun) return ((lun[2] << 8) | lun[3]) & 0x3FFF; } -static inline SCSIDevice *virtio_scsi_device_find(VirtIOSCSI *s, uint8_t *lun) +static inline SCSIDevice *virtio_scsi_device_get(VirtIOSCSI *s, uint8_t *lun) { if (lun[0] != 1) { return NULL; @@ -41,7 +41,7 @@ static inline SCSIDevice *virtio_scsi_device_find(VirtIOSCSI *s, uint8_t *lun) if (lun[2] != 0 && !(lun[2] >= 0x40 && lun[2] < 0x80)) { return NULL; } - return scsi_device_find(&s->bus, 0, lun[1], virtio_scsi_get_lun(lun)); + return scsi_device_get(&s->bus, 0, lun[1], virtio_scsi_get_lun(lun)); } void virtio_scsi_init_req(VirtIOSCSI *s, VirtQueue *vq, VirtIOSCSIReq *req) @@ -256,7 +256,7 @@ static inline void virtio_scsi_ctx_check(VirtIOSCSI *s, SCSIDevice *d) * case of async cancellation. */ static int virtio_scsi_do_tmf(VirtIOSCSI *s, VirtIOSCSIReq *req) { - SCSIDevice *d = virtio_scsi_device_find(s, req->req.tmf.lun); + SCSIDevice *d = virtio_scsi_device_get(s, req->req.tmf.lun); SCSIRequest *r, *next; BusChild *kid; int target; @@ -370,10 +370,10 @@ static int virtio_scsi_do_tmf(VirtIOSCSI *s, VirtIOSCSIReq *req) rcu_read_lock(); QTAILQ_FOREACH_RCU(kid, &s->bus.qbus.children, sibling) { - d = SCSI_DEVICE(kid->child); - if (d->channel == 0 && d->id == target) { - qdev_reset_all(&d->qdev); - } + SCSIDevice *d1 = SCSI_DEVICE(kid->child); + if (d1->channel == 0 && d1->id == target) { + qdev_reset_all(&d1->qdev); + } } rcu_read_unlock(); @@ -386,14 +386,17 @@ static int virtio_scsi_do_tmf(VirtIOSCSI *s, VirtIOSCSIReq *req) break; } + object_unref(OBJECT(d)); return ret; incorrect_lun: req->resp.tmf.response = VIRTIO_SCSI_S_INCORRECT_LUN; + object_unref(OBJECT(d)); return ret; fail: req->resp.tmf.response = VIRTIO_SCSI_S_BAD_TARGET; + object_unref(OBJECT(d)); return ret; } @@ -564,7 +567,7 @@ static int virtio_scsi_handle_cmd_req_prepare(VirtIOSCSI *s, VirtIOSCSIReq *req) } } - d = virtio_scsi_device_find(s, req->req.cmd.lun); + d = virtio_scsi_device_get(s, req->req.cmd.lun); if (!d) { req->resp.cmd.response = VIRTIO_SCSI_S_BAD_TARGET; virtio_scsi_complete_cmd_req(req); @@ -580,10 +583,12 @@ static int virtio_scsi_handle_cmd_req_prepare(VirtIOSCSI *s, VirtIOSCSIReq *req) req->sreq->cmd.xfer > req->qsgl.size)) { req->resp.cmd.response = VIRTIO_SCSI_S_OVERRUN; virtio_scsi_complete_cmd_req(req); + object_unref(OBJECT(d)); return -ENOBUFS; } scsi_req_ref(req->sreq); blk_io_plug(d->conf.blk); + object_unref(OBJECT(d)); return 0; } From patchwork Fri Oct 2 17:35:58 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Bonzini X-Patchwork-Id: 272164 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-12.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id A4F94C4363C for ; Fri, 2 Oct 2020 17:42:12 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 2A548206A5 for ; Fri, 2 Oct 2020 17:42:12 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="jM994VAw" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 2A548206A5 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:41690 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kOP4N-0005wt-2s for qemu-devel@archiver.kernel.org; Fri, 02 Oct 2020 13:42:11 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:45136) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kOOyc-0000a5-5C for qemu-devel@nongnu.org; Fri, 02 Oct 2020 13:36:15 -0400 Received: from mail-wm1-x343.google.com ([2a00:1450:4864:20::343]:34154) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1kOOyY-0003L3-Th for qemu-devel@nongnu.org; Fri, 02 Oct 2020 13:36:12 -0400 Received: by mail-wm1-x343.google.com with SMTP id l15so1578467wmh.1 for ; Fri, 02 Oct 2020 10:36:10 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=3dT+wfpw6iT83ImSmB/t0Y9AbcGGqtgwVgpoltnvTmU=; b=jM994VAwFUd4S6HLbQikrvILMHMn7E6vYTB7EcTD3IqNL9SHCAvCm46tfv1s9bpMwo +5ZdUDrE6OtbQtO4dQso6RfvNda5aB3jX35s1g5RiXR8UwBKEifsp1GmTpE5iimE58AT B7hc2eG3PjtKdDQlpdpK52QUs0z6TOFaVIDst7JTCw/mmR1oFf41scQo+0RI1FE+ErPq sc3K/hRugS49YU8kVSKTUC7IBxRQVGfH06Z5gCkduMWcirgJfiNiMg/9FD9TO7JGoUed 4aTB1XPnH/f/cWaxpUa2SNkN/tnnOwKUHDhCTwHBtlCMsKOUKOkie5AprHIypZRoGArd WZoA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references:mime-version:content-transfer-encoding; bh=3dT+wfpw6iT83ImSmB/t0Y9AbcGGqtgwVgpoltnvTmU=; b=GxR9r6k+/VNYEywFYgOfffjvpEDrnUjWCPNiOO+GWeH9MOd9ZCeCmxeZ5pU3HtnC1n xKYoaXhqv6f7WsUJauhVwyp+JrMvafZhTM0vfE75FcDAthV3+uJ4Xva0SIPGDA7S57Ea muaIIfZ1m+Ky09DHIiGD3nr1+tY2TH+z+ASeq7kCtNQtDAR1037LRwTvfHRcLOcnLSob ck22mIEYS26e29PGkgMLgnOm32/vxEryLESDxosvKbcoY4+GZknoFKARGnXj3q5VKpqP SXsBss7SuqU5iJR8uff1o2aaqN+VJlvmcX7eG8NdQPTvotQqL+CQr1BTqpwqj9dCEQjg 5Z9A== X-Gm-Message-State: AOAM530tmOZNbJBHb8KuD1LlFoofpRMaG8xYh0knTAe7jFDwCksUDeLO c6Nf138ETSpvZ2d2xrAzzJTOqM7GbvQ= X-Google-Smtp-Source: ABdhPJyYuF53zLkewCty6KI9zEMvxliH6sNtLoTafWZ/3+3Fs1FBMvnsO6IoycuRe8jY/qCTTesBxg== X-Received: by 2002:a1c:7405:: with SMTP id p5mr4042979wmc.35.1601660169085; Fri, 02 Oct 2020 10:36:09 -0700 (PDT) Received: from donizetti.redhat.com ([2001:b07:6468:f312:47e0:e742:75ba:b84d]) by smtp.gmail.com with ESMTPSA id l8sm2516454wrx.22.2020.10.02.10.36.08 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 02 Oct 2020 10:36:08 -0700 (PDT) From: Paolo Bonzini To: qemu-devel@nongnu.org Subject: [PATCH v6 10/10] scsi/scsi_bus: fix races in REPORT LUNS Date: Fri, 2 Oct 2020 19:35:58 +0200 Message-Id: <20201002173558.232960-11-pbonzini@redhat.com> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20201002173558.232960-1-pbonzini@redhat.com> References: <20201002173558.232960-1-pbonzini@redhat.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2a00:1450:4864:20::343; envelope-from=paolo.bonzini@gmail.com; helo=mail-wm1-x343.google.com X-detected-operating-system: by eggs.gnu.org: No matching host in p0f cache. That's all we know. X-Spam_score_int: -16 X-Spam_score: -1.7 X-Spam_bar: - X-Spam_report: (-1.7 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FORGED_FROMDOMAIN=0.001, FREEMAIL_FROM=0.001, HEADER_FROM_DIFFERENT_DOMAINS=0.25, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Stefan Hajnoczi , Maxim Levitsky Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" From: Maxim Levitsky Currently scsi_target_emulate_report_luns iterates over the child device list twice, and there is no guarantee that this list is the same in both iterations. The reason for iterating twice is that the first iteration calculates how much memory to allocate. However if we use a dynamic array we can avoid iterating twice, and therefore we avoid this race. Buglink: https://bugzilla.redhat.com/show_bug.cgi?id=1866707 Signed-off-by: Maxim Levitsky Reviewed-by: Stefan Hajnoczi Message-Id: <20200913160259.32145-10-mlevitsk@redhat.com> Signed-off-by: Paolo Bonzini --- hw/scsi/scsi-bus.c | 68 ++++++++++++++++++++++------------------------ 1 file changed, 33 insertions(+), 35 deletions(-) diff --git a/hw/scsi/scsi-bus.c b/hw/scsi/scsi-bus.c index eda8cb7e70..b901e701f0 100644 --- a/hw/scsi/scsi-bus.c +++ b/hw/scsi/scsi-bus.c @@ -438,19 +438,23 @@ struct SCSITargetReq { static void store_lun(uint8_t *outbuf, int lun) { if (lun < 256) { + /* Simple logical unit addressing method*/ + outbuf[0] = 0; outbuf[1] = lun; - return; + } else { + /* Flat space addressing method */ + outbuf[0] = 0x40 | (lun >> 8); + outbuf[1] = (lun & 255); } - outbuf[1] = (lun & 255); - outbuf[0] = (lun >> 8) | 0x40; } static bool scsi_target_emulate_report_luns(SCSITargetReq *r) { BusChild *kid; - int i, len, n; int channel, id; - bool found_lun0; + uint8_t tmp[8] = {0}; + int len = 0; + GByteArray *buf; if (r->req.cmd.xfer < 16) { return false; @@ -458,46 +462,40 @@ static bool scsi_target_emulate_report_luns(SCSITargetReq *r) if (r->req.cmd.buf[2] > 2) { return false; } + + /* reserve space for 63 LUNs*/ + buf = g_byte_array_sized_new(512); + channel = r->req.dev->channel; id = r->req.dev->id; - found_lun0 = false; - n = 0; - RCU_READ_LOCK_GUARD(); + /* add size (will be updated later to correct value */ + g_byte_array_append(buf, tmp, 8); + len += 8; - QTAILQ_FOREACH_RCU(kid, &r->req.bus->qbus.children, sibling) { - DeviceState *qdev = kid->child; - SCSIDevice *dev = SCSI_DEVICE(qdev); + /* add LUN0 */ + g_byte_array_append(buf, tmp, 8); + len += 8; - if (dev->channel == channel && dev->id == id) { - if (dev->lun == 0) { - found_lun0 = true; + WITH_RCU_READ_LOCK_GUARD() { + QTAILQ_FOREACH_RCU(kid, &r->req.bus->qbus.children, sibling) { + DeviceState *qdev = kid->child; + SCSIDevice *dev = SCSI_DEVICE(qdev); + + if (dev->channel == channel && dev->id == id && dev->lun != 0) { + store_lun(tmp, dev->lun); + g_byte_array_append(buf, tmp, 8); + len += 8; } - n += 8; } } - if (!found_lun0) { - n += 8; - } - - scsi_target_alloc_buf(&r->req, n + 8); - - len = MIN(n + 8, r->req.cmd.xfer & ~7); - memset(r->buf, 0, len); - stl_be_p(&r->buf[0], n); - i = found_lun0 ? 8 : 16; - QTAILQ_FOREACH_RCU(kid, &r->req.bus->qbus.children, sibling) { - DeviceState *qdev = kid->child; - SCSIDevice *dev = SCSI_DEVICE(qdev); - if (dev->channel == channel && dev->id == id) { - store_lun(&r->buf[i], dev->lun); - i += 8; - } - } + r->buf_len = len; + r->buf = g_byte_array_free(buf, FALSE); + r->len = MIN(len, r->req.cmd.xfer & ~7); - assert(i == n + 8); - r->len = len; + /* store the LUN list length */ + stl_be_p(&r->buf[0], len - 8); return true; }