From patchwork Thu Apr 28 08:59:49 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jan Kiszka X-Patchwork-Id: 738761 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter1.kernel.org (8.14.4/8.14.3) with ESMTP id p3S90S50016855 for ; Thu, 28 Apr 2011 09:00:31 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1757828Ab1D1JAT (ORCPT ); Thu, 28 Apr 2011 05:00:19 -0400 Received: from david.siemens.de ([192.35.17.14]:27001 "EHLO david.siemens.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1757431Ab1D1JAF (ORCPT ); Thu, 28 Apr 2011 05:00:05 -0400 Received: from mail1.siemens.de (localhost [127.0.0.1]) by david.siemens.de (8.13.6/8.13.6) with ESMTP id p3S8xsex025126; Thu, 28 Apr 2011 10:59:54 +0200 Received: from mchn199C.mchp.siemens.de ([139.25.109.49]) by mail1.siemens.de (8.13.6/8.13.6) with ESMTP id p3S8xspW021662; Thu, 28 Apr 2011 10:59:54 +0200 From: Jan Kiszka To: Avi Kivity , Marcelo Tosatti Cc: kvm@vger.kernel.org, Alex Williamson Subject: [PATCH 1/5] pci-assign: Clean up assigned_dev_pci_read/write_config Date: Thu, 28 Apr 2011 10:59:49 +0200 Message-Id: X-Mailer: git-send-email 1.7.1 In-Reply-To: References: In-Reply-To: References: Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.6 (demeter1.kernel.org [140.211.167.41]); Thu, 28 Apr 2011 09:00:31 +0000 (UTC) Use rages_overlap and proper constants to match the access range against regions that need special handling. This also fixes yet uncaught high-byte write access to the command register. Moreover, use more constants instead of magic numbers. Signed-off-by: Jan Kiszka --- hw/device-assignment.c | 39 +++++++++++++++++++++++++++++---------- 1 files changed, 29 insertions(+), 10 deletions(-) diff --git a/hw/device-assignment.c b/hw/device-assignment.c index 606d725..3481c93 100644 --- a/hw/device-assignment.c +++ b/hw/device-assignment.c @@ -404,13 +404,20 @@ static void assigned_dev_pci_write_config(PCIDevice *d, uint32_t address, return assigned_device_pci_cap_write_config(d, address, val, len); } - if (address == 0x4) { + if (ranges_overlap(address, len, PCI_COMMAND, 2)) { pci_default_write_config(d, address, val, len); /* Continue to program the card */ } - if ((address >= 0x10 && address <= 0x24) || address == 0x30 || - address == 0x34 || address == 0x3c || address == 0x3d) { + /* + * Catch access to + * - base address registers + * - ROM base address & capability pointer + * - interrupt line & pin + */ + if (ranges_overlap(address, len, PCI_BASE_ADDRESS_0, 24) || + ranges_overlap(address, len, PCI_ROM_ADDRESS, 8) || + ranges_overlap(address, len, PCI_INTERRUPT_LINE, 2)) { /* used for update-mappings (BAR emulation) */ pci_default_write_config(d, address, val, len); return; @@ -450,9 +457,20 @@ static uint32_t assigned_dev_pci_read_config(PCIDevice *d, uint32_t address, return val; } - if (address < 0x4 || (pci_dev->need_emulate_cmd && address == 0x4) || - (address >= 0x10 && address <= 0x24) || address == 0x30 || - address == 0x34 || address == 0x3c || address == 0x3d) { + /* + * Catch access to + * - vendor & device ID + * - command register (if emulation needed) + * - base address registers + * - ROM base address & capability pointer + * - interrupt line & pin + */ + if (ranges_overlap(address, len, PCI_VENDOR_ID, 4) || + (pci_dev->need_emulate_cmd && + ranges_overlap(address, len, PCI_COMMAND, 2)) || + ranges_overlap(address, len, PCI_BASE_ADDRESS_0, 24) || + ranges_overlap(address, len, PCI_ROM_ADDRESS, 8) || + ranges_overlap(address, len, PCI_INTERRUPT_LINE, 2)) { val = pci_default_read_config(d, address, len); DEBUG("(%x.%x): address=%04x val=0x%08x len=%d\n", (d->devfn >> 3) & 0x1F, (d->devfn & 0x7), address, val, len); @@ -483,10 +501,11 @@ do_log: if (!pci_dev->cap.available) { /* kill the special capabilities */ - if (address == 4 && len == 4) - val &= ~0x100000; - else if (address == 6) - val &= ~0x10; + if (address == PCI_COMMAND && len == 4) { + val &= ~(PCI_STATUS_CAP_LIST << 16); + } else if (address == PCI_STATUS) { + val &= ~PCI_STATUS_CAP_LIST; + } } return val;