From patchwork Fri Jul 29 01:01:43 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Isaku Yamahata X-Patchwork-Id: 107316 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [140.186.70.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id EE4EBB6F6B for ; Fri, 29 Jul 2011 11:01:59 +1000 (EST) Received: from localhost ([::1]:56327 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QmbSc-0000fv-3N for incoming@patchwork.ozlabs.org; Thu, 28 Jul 2011 21:01:54 -0400 Received: from eggs.gnu.org ([140.186.70.92]:60065) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QmbSX-0000fe-5s for qemu-devel@nongnu.org; Thu, 28 Jul 2011 21:01:49 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1QmbSW-0005Dl-66 for qemu-devel@nongnu.org; Thu, 28 Jul 2011 21:01:49 -0400 Received: from mail.valinux.co.jp ([210.128.90.3]:53999) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QmbSV-0005DM-JM for qemu-devel@nongnu.org; Thu, 28 Jul 2011 21:01:48 -0400 Received: from ps.local.valinux.co.jp (vagw.valinux.co.jp [210.128.90.14]) by mail.valinux.co.jp (Postfix) with SMTP id 0E25148F41; Fri, 29 Jul 2011 10:01:44 +0900 (JST) Received: (nullmailer pid 12176 invoked by uid 1000); Fri, 29 Jul 2011 01:01:43 -0000 Date: Fri, 29 Jul 2011 10:01:43 +0900 From: Isaku Yamahata To: "Michael S\. Tsirkin" Message-ID: <20110729010143.GI14976@valinux.co.jp> References: <4E2858C2.5050909@siemens.com> <20110722052707.GA8241@redhat.com> <4E293D3D.8070904@siemens.com> <20110728072324.GF14976@valinux.co.jp> <20110728084020.GA4637@redhat.com> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <20110728084020.GA4637@redhat.com> User-Agent: Mutt/1.5.19 (2009-01-05) X-Virus-Scanned: clamav-milter 0.95.2 at va-mail.local.valinux.co.jp X-Virus-Status: Clean X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6 (newer, 3) X-Received-From: 210.128.90.3 Cc: Jan Kiszka , qemu-devel Subject: Re: [Qemu-devel] [PATCH v2] pci: Common overflow prevention 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 On Thu, Jul 28, 2011 at 11:40:21AM +0300, Michael S. Tsirkin wrote: > I don't see a problem with this, but could you please clarify when does > this happen? I think this is only possible for a pci device > behind an express root. If so, this belongs in pcie_host.c > > I'd also like this info to be recorded in the commit log. From 1dd598fd35d4e988dc51487829ed66208ca89021 Mon Sep 17 00:00:00 2001 Message-Id: <1dd598fd35d4e988dc51487829ed66208ca89021.1311901239.git.yamahata@valinux.co.jp> From: Isaku Yamahata Date: Fri, 29 Jul 2011 09:52:45 +0900 Subject: [PATCH] pcie_host: limit check of pcie_mmcfg_data_write/read This patch adds the check where the offset in the configuration space is in its configuration size. MMCFG area allows access of pcie configuration space to be in offset [0, 4K). At the same time, conventional pci devices whose configuration space size is 256 bytes can be behind pcie-to-pci bridge. The access whose offset is [256, 4K) should have no effect on the conventional pci device Add the limit check and ignore such accesses. Signed-off-by: Isaku Yamahata --- hw/pcie_host.c | 28 ++++++++++++++++++++++------ 1 files changed, 22 insertions(+), 6 deletions(-) diff --git a/hw/pcie_host.c b/hw/pcie_host.c index f0b3d13..f9fea3d 100644 --- a/hw/pcie_host.c +++ b/hw/pcie_host.c @@ -56,23 +56,39 @@ static void pcie_mmcfg_data_write(PCIBus *s, uint32_t mmcfg_addr, uint32_t val, int len) { PCIDevice *pci_dev = pcie_dev_find_by_mmcfg_addr(s, mmcfg_addr); + uint32_t addr; + uint32_t limit; if (!pci_dev) { return; } - pci_host_config_write_common(pci_dev, PCIE_MMCFG_CONFOFFSET(mmcfg_addr), - pci_config_size(pci_dev), val, len); + addr = PCIE_MMCFG_CONFOFFSET(mmcfg_addr); + limit = pci_config_size(pci_dev); + if (limit <= addr) { + /* conventional pci device can be behind pcie-to-pci bridge. + 256 <= addr < 4K has no effects. */ + return; + } + pci_host_config_write_common(pci_dev, addr, limit, val, len); } -static uint32_t pcie_mmcfg_data_read(PCIBus *s, uint32_t addr, int len) +static uint32_t pcie_mmcfg_data_read(PCIBus *s, uint32_t mmcfg_addr, int len) { - PCIDevice *pci_dev = pcie_dev_find_by_mmcfg_addr(s, addr); + PCIDevice *pci_dev = pcie_dev_find_by_mmcfg_addr(s, mmcfg_addr); + uint32_t addr; + uint32_t limit; if (!pci_dev) { return ~0x0; } - return pci_host_config_read_common(pci_dev, PCIE_MMCFG_CONFOFFSET(addr), - pci_config_size(pci_dev), len); + addr = PCIE_MMCFG_CONFOFFSET(mmcfg_addr); + limit = pci_config_size(pci_dev); + if (limit <= addr) { + /* conventional pci device can be behind pcie-to-pci bridge. + 256 <= addr < 4K has no effects. */ + return ~0x0; + } + return pci_host_config_read_common(pci_dev, addr, limit, len); } static void pcie_mmcfg_data_writeb(void *opaque,