From patchwork Mon Dec 13 22:43:44 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Cam Macdonell X-Patchwork-Id: 75432 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [199.232.76.165]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 5C51C1007D1 for ; Tue, 14 Dec 2010 09:47:29 +1100 (EST) Received: from localhost ([127.0.0.1]:60443 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1PSHB0-0005sx-5q for incoming@patchwork.ozlabs.org; Mon, 13 Dec 2010 17:47:26 -0500 Received: from [140.186.70.92] (port=33629 helo=eggs.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1PSH8i-0004C3-Ig for qemu-devel@nongnu.org; Mon, 13 Dec 2010 17:45:06 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1PSH7v-0002Eb-B8 for qemu-devel@nongnu.org; Mon, 13 Dec 2010 17:44:16 -0500 Received: from smtp.srv.ualberta.ca ([129.128.5.19]:54388 helo=mail7.srv.ualberta.ca) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1PSH7v-0002Bs-5B for qemu-devel@nongnu.org; Mon, 13 Dec 2010 17:44:15 -0500 Received: from localhost.localdomain (st-brides.cs.ualberta.ca [129.128.23.21]) (authenticated bits=0) by mail7.srv.ualberta.ca (8.14.3/8.13.8) with ESMTP id oBDMhknZ024677 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NOT); Mon, 13 Dec 2010 15:44:01 -0700 (MST) From: Cam Macdonell To: qemu-devel@nongnu.org Date: Mon, 13 Dec 2010 15:43:44 -0700 Message-Id: <1292280224-5119-1-git-send-email-cam@cs.ualberta.ca> X-Mailer: git-send-email 1.7.0.4 X-detected-operating-system: by eggs.gnu.org: OpenBSD 3.0-3.9 Cc: Cam Macdonell , kvm@vger.kernel.org Subject: [Qemu-devel] [PATCH] RFC: delay pci_update_mappings for 64-bit BARs X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Do not call pci_update_mappings on the lower 32-bits of a 64-bit bar. Wait for the upper 32 or else Qemu will try to map on just the lower 32 which is probably going to corrupt memory. I was encountering crashes when mapping certain PCI region sizes. The problem turns out that pci_update_mappings is being called without all 64-bits in the BAR. For example when mapping to 0x180000000, once the lower 32-bits were written the remapping happened (mapping to 0x8000000) which would overwrite something. I'm not certain if this is completely correct, I'm simply testing the lower 4-bits to only be MEM_TYPE_64 flag. Upper 32-bit address parts can be values like 0xff which is tricky to test against. Cam --- hw/pci.c | 5 ++++- 1 files changed, 4 insertions(+), 1 deletions(-) diff --git a/hw/pci.c b/hw/pci.c index 438c0d1..3b81792 100644 --- a/hw/pci.c +++ b/hw/pci.c @@ -1000,6 +1000,9 @@ void pci_default_write_config(PCIDevice *d, uint32_t addr, uint32_t val, int l) { int i, was_irq_disabled = pci_irq_disabled(d); uint32_t config_size = pci_config_size(d); + int is_64 = 0; + + is_64 = ((val & 0xf) == PCI_BASE_ADDRESS_MEM_TYPE_64); for (i = 0; i < l && addr + i < config_size; val >>= 8, ++i) { uint8_t wmask = d->wmask[addr + i]; @@ -1008,7 +1011,7 @@ void pci_default_write_config(PCIDevice *d, uint32_t addr, uint32_t val, int l) d->config[addr + i] = (d->config[addr + i] & ~wmask) | (val & wmask); d->config[addr + i] &= ~(val & w1cmask); /* W1C: Write 1 to Clear */ } - if (ranges_overlap(addr, l, PCI_BASE_ADDRESS_0, 24) || + if ((ranges_overlap(addr, l, PCI_BASE_ADDRESS_0, 24) && (!is_64)) || ranges_overlap(addr, l, PCI_ROM_ADDRESS, 4) || ranges_overlap(addr, l, PCI_ROM_ADDRESS1, 4) || range_covers_byte(addr, l, PCI_COMMAND))