From patchwork Wed Dec 2 14:33:21 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Shmulik Ladkani X-Patchwork-Id: 551388 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4555A140180 for ; Thu, 3 Dec 2015 01:33:11 +1100 (AEDT) Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=ravellosystems-com.20150623.gappssmtp.com header.i=@ravellosystems-com.20150623.gappssmtp.com header.b=zGYipKkc; dkim-atps=neutral Received: from localhost ([::1]:58545 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1a48Sz-0003qx-C7 for incoming@patchwork.ozlabs.org; Wed, 02 Dec 2015 09:33:09 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:58782) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1a48Sh-0003Oy-HI for qemu-devel@nongnu.org; Wed, 02 Dec 2015 09:32:52 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1a48Sd-0002IC-07 for qemu-devel@nongnu.org; Wed, 02 Dec 2015 09:32:51 -0500 Received: from mail-wm0-x235.google.com ([2a00:1450:400c:c09::235]:33647) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1a48Sc-0002Hb-Jm for qemu-devel@nongnu.org; Wed, 02 Dec 2015 09:32:46 -0500 Received: by wmec201 with SMTP id c201so256093295wme.0 for ; Wed, 02 Dec 2015 06:32:46 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ravellosystems-com.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id; bh=mvCGuoBtYL67iJgACK5cc0PCw1ytktkiV5jskAB5S70=; b=zGYipKkcO93pbYgxWpHQzF27ycuV3jfrlyBUbjHqNapZeT2YYol1vsWr78YF48DMrP 209y2wqADixL+DvIt416iBkwvTeGvMyjPkbBV7DI0ghqSG+N6VtiCbUdFzipZIafWidW iZ8fbOcKP77Yci0X6EdjjxppMKglO8W65G76iiuS3OxMWhDsscBU2DUs0oiXUqDZNSlS aeJyLXklPjbo5b1pRc6RrC+klF+Pvw9bciECIbSx73PV/LP2UoaxQ7+gpcP3rpPvdGFi fkRBebVrR0vwzUFDqo8WK2PK6JCh3AStQjliB1TC/WAEWVCNOCpm7eqaLmY1jeAUj+Nc Rhlg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=mvCGuoBtYL67iJgACK5cc0PCw1ytktkiV5jskAB5S70=; b=kBJnn9TICS0Cfoy9WxmLEQHvrMEPVC3JEG/BkZwOMhHokN5N1fzYrlatEB9Etq+E7q wZfN70XrKi0WPzUkSKM5FiKQljepvY5nguTri8/MDjBUGqoREdHrrHGqgtrvgnKZ4H2x csNeHcvlkxQ+5UtqyBAE6mYJc1E4j1Qo/zuPkDYlQKxio938SdbuEk1lRfeqAtjor+tQ 83E50dni16pOeNH9TYis6KVxjvlXDRFOw8p8Ld3Z4TQB2fl4j2PuwVMc6MEo25kKpqTR ibPp1Y6VrBAEyx9TtMc3m8XkybdHApQdym7xfC08kBQr2XRJuMKNXdLzaiJmDqV5Zwhy YK/g== X-Gm-Message-State: ALoCoQmpsRc9BM4rIWllx2ffVQV+zBbbRnG07ZrF4W+K7EZmJCqvO1KKh/QKtlalwbY0jtZbeTwL X-Received: by 10.194.20.2 with SMTP id j2mr5419086wje.46.1449066765880; Wed, 02 Dec 2015 06:32:45 -0800 (PST) Received: from honey.ravello.local ([213.57.127.2]) by smtp.gmail.com with ESMTPSA id d66sm31261715wma.21.2015.12.02.06.32.44 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 02 Dec 2015 06:32:45 -0800 (PST) From: Shmulik Ladkani To: "Michael S. Tsirkin" , Marcel Apfelbaum Date: Wed, 2 Dec 2015 16:33:21 +0200 Message-Id: <1449066801-3002-1-git-send-email-shmulik.ladkani@ravellosystems.com> X-Mailer: git-send-email 1.9.1 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 2a00:1450:400c:c09::235 Cc: qemu-devel@nongnu.org, Shmulik Ladkani Subject: [Qemu-devel] [PATCH v2 for-2.5] virtio-pci: Set the QEMU_PCI_CAP_EXPRESS capability early in its DeviceClass realize method X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org In 1811e64 'hw/virtio: Add PCIe capability to virtio devices', the QEMU_PCI_CAP_EXPRESS capability was added to virtio's pci_dev, within 'virtio_pci_realize' - the pci device object realization method. This occurs to late, as 'pci_qdev_realize' (DeviceClass.realize of TYPE_PCI_DEVICE) has already been called, without knowing that the device instance is indeed an "express" instance, thus allocating insufficient pci config space. As a result, device may crash upon attempt to write to the PCIE config space. Fix, by arming the QEMU_PCI_CAP_EXPRESS capability early in virtio-pci's own DeviceClass realize method. This also makes code cleaner, as 'virtio_pci_realize' may now access the 'pci_is_express' predicate when needed. Signed-off-by: Shmulik Ladkani Reviewed-by: Marcel Apfelbaum --- Since v1: naming change, as suggested by Marcel Apfelbaum hw/virtio/virtio-pci.c | 24 +++++++++++++++++++----- hw/virtio/virtio-pci.h | 1 + 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c index dd48562..67f4003 100644 --- a/hw/virtio/virtio-pci.c +++ b/hw/virtio/virtio-pci.c @@ -1814,13 +1814,10 @@ static void virtio_pci_realize(PCIDevice *pci_dev, Error **errp) address_space_init(&proxy->modern_as, &proxy->modern_cfg, "virtio-pci-cfg-as"); - if (!(proxy->flags & VIRTIO_PCI_FLAG_DISABLE_PCIE) - && !(proxy->flags & VIRTIO_PCI_FLAG_DISABLE_MODERN) - && pci_bus_is_express(pci_dev->bus) - && !pci_bus_is_root(pci_dev->bus)) { + if (pci_is_express(pci_dev) && pci_bus_is_express(pci_dev->bus) && + !pci_bus_is_root(pci_dev->bus)) { int pos; - pci_dev->cap_present |= QEMU_PCI_CAP_EXPRESS; pos = pcie_endpoint_cap_init(pci_dev, 0); assert(pos > 0); @@ -1879,10 +1876,25 @@ static Property virtio_pci_properties[] = { DEFINE_PROP_END_OF_LIST(), }; +static void virtio_pci_dc_realize(DeviceState *qdev, Error **errp) +{ + VirtioPCIClass *vpciklass = VIRTIO_PCI_GET_CLASS(qdev); + VirtIOPCIProxy *proxy = VIRTIO_PCI(qdev); + PCIDevice *pci_dev = &proxy->pci_dev; + + if (!(proxy->flags & VIRTIO_PCI_FLAG_DISABLE_PCIE) && + !(proxy->flags & VIRTIO_PCI_FLAG_DISABLE_MODERN)) { + pci_dev->cap_present |= QEMU_PCI_CAP_EXPRESS; + } + + vpciklass->parent_dc_realize(qdev, errp); +} + static void virtio_pci_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); + VirtioPCIClass *vpciklass = VIRTIO_PCI_CLASS(klass); dc->props = virtio_pci_properties; k->realize = virtio_pci_realize; @@ -1890,6 +1902,8 @@ static void virtio_pci_class_init(ObjectClass *klass, void *data) k->vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET; k->revision = VIRTIO_PCI_ABI_VERSION; k->class_id = PCI_CLASS_OTHERS; + vpciklass->parent_dc_realize = dc->realize; + dc->realize = virtio_pci_dc_realize; dc->reset = virtio_pci_reset; } diff --git a/hw/virtio/virtio-pci.h b/hw/virtio/virtio-pci.h index ffb74bb..a104ff2 100644 --- a/hw/virtio/virtio-pci.h +++ b/hw/virtio/virtio-pci.h @@ -105,6 +105,7 @@ typedef struct { typedef struct VirtioPCIClass { PCIDeviceClass parent_class; + DeviceRealize parent_dc_realize; void (*realize)(VirtIOPCIProxy *vpci_dev, Error **errp); } VirtioPCIClass;