[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [PATCH v2 09/12] VT-d: move dev_invalidate_iotlb() to the sole file it's used from
..., thus allowing it and qinval_device_iotlb_sync() to become static. There's nothing x86-specific about the function anyway. While moving, adjust types to better match ./CODING_STYLE (albeit use of fixed-width types for parameters is retained to limit the effective change). Append a UL to a constant while moving, to please Misra. Also insert blank lines in the switch(), between non-fall-through case blocks. Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx> Acked-by: Roger Pau Monné <roger.pau@xxxxxxxxxx> --- v2: Cosmetics. --- a/xen/drivers/passthrough/vtd/extern.h +++ b/xen/drivers/passthrough/vtd/extern.h @@ -65,13 +65,6 @@ struct acpi_drhd_unit *ioapic_to_drhd(un struct acpi_drhd_unit *hpet_to_drhd(unsigned int hpet_id); struct acpi_rhsa_unit *drhd_to_rhsa(const struct acpi_drhd_unit *drhd); -int dev_invalidate_iotlb(struct vtd_iommu *iommu, u16 did, - u64 addr, unsigned int size_order, u64 type); - -int __must_check qinval_device_iotlb_sync(struct vtd_iommu *iommu, - struct pci_dev *pdev, - u16 did, u16 size, u64 addr); - uint64_t alloc_pgtable_maddr(unsigned long npages, nodeid_t node); void free_pgtable_maddr(u64 maddr); void *map_vtd_domain_page(u64 maddr); --- a/xen/drivers/passthrough/vtd/qinval.c +++ b/xen/drivers/passthrough/vtd/qinval.c @@ -251,8 +251,9 @@ static int __must_check dev_invalidate_s return rc; } -int qinval_device_iotlb_sync(struct vtd_iommu *iommu, struct pci_dev *pdev, - u16 did, u16 size, u64 addr) +static int qinval_device_iotlb_sync(struct vtd_iommu *iommu, + struct pci_dev *pdev, uint16_t did, + uint16_t size, paddr_t addr) { unsigned long flags; unsigned int index; @@ -282,6 +283,103 @@ int qinval_device_iotlb_sync(struct vtd_ return dev_invalidate_sync(iommu, pdev, did); } +static bool device_in_domain(const struct vtd_iommu *iommu, + const struct pci_dev *pdev, uint16_t did) +{ + struct root_entry *root_entry; + struct context_entry *ctxt_entry = NULL; + unsigned int tt; + bool found = false; + + if ( unlikely(!iommu->root_maddr) ) + { + ASSERT_UNREACHABLE(); + return false; + } + + root_entry = map_vtd_domain_page(iommu->root_maddr); + if ( !root_present(root_entry[pdev->bus]) ) + goto out; + + ctxt_entry = map_vtd_domain_page(root_entry[pdev->bus].val); + if ( context_domain_id(ctxt_entry[pdev->devfn]) != did ) + goto out; + + tt = context_translation_type(ctxt_entry[pdev->devfn]); + if ( tt != CONTEXT_TT_DEV_IOTLB ) + goto out; + + found = true; + out: + if ( root_entry ) + unmap_vtd_domain_page(root_entry); + + if ( ctxt_entry ) + unmap_vtd_domain_page(ctxt_entry); + + return found; +} + +static int dev_invalidate_iotlb(struct vtd_iommu *iommu, uint16_t did, + paddr_t addr, unsigned int size_order, + uint64_t type) +{ + struct pci_dev *pdev, *temp; + int ret = 0; + + if ( !ecap_dev_iotlb(iommu->ecap) ) + return ret; + + list_for_each_entry_safe ( pdev, temp, &iommu->ats_devices, ats.list ) + { + bool sbit; + int rc = 0; + + switch ( type ) + { + case DMA_TLB_DSI_FLUSH: + if ( !device_in_domain(iommu, pdev, did) ) + break; + /* fall through if DSI condition met */ + case DMA_TLB_GLOBAL_FLUSH: + /* invalidate all translations: sbit=1,bit_63=0,bit[62:12]=1 */ + sbit = 1; + addr = (~0UL << PAGE_SHIFT_4K) & 0x7FFFFFFFFFFFFFFFUL; + rc = qinval_device_iotlb_sync(iommu, pdev, did, sbit, addr); + break; + + case DMA_TLB_PSI_FLUSH: + if ( !device_in_domain(iommu, pdev, did) ) + break; + + /* if size <= 4K, set sbit = 0, else set sbit = 1 */ + sbit = size_order ? 1 : 0; + + /* clear lower bits */ + addr &= ~0UL << PAGE_SHIFT_4K; + + /* if sbit == 1, zero out size_order bit and set lower bits to 1 */ + if ( sbit ) + { + addr &= ~((u64)PAGE_SIZE_4K << (size_order - 1)); + addr |= (((u64)1 << (size_order - 1)) - 1) << PAGE_SHIFT_4K; + } + + rc = qinval_device_iotlb_sync(iommu, pdev, did, sbit, addr); + break; + + default: + dprintk(XENLOG_WARNING VTDPREFIX, "invalid vt-d flush type\n"); + return -EOPNOTSUPP; + } + + if ( !ret ) + ret = rc; + } + + return ret; +} + static int __must_check queue_invalidate_iec_sync(struct vtd_iommu *iommu, u8 granu, u8 im, u16 iidx) { --- a/xen/drivers/passthrough/vtd/x86/Makefile +++ b/xen/drivers/passthrough/vtd/x86/Makefile @@ -1,2 +1 @@ -obj-y += ats.o obj-y += vtd.o --- a/xen/drivers/passthrough/vtd/x86/ats.c +++ /dev/null @@ -1,123 +0,0 @@ -/* - * Copyright (c) 2006, Intel Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; If not, see <http://www.gnu.org/licenses/>. - * - * Author: Allen Kay <allen.m.kay@xxxxxxxxx> - */ - -#include <xen/sched.h> -#include <xen/iommu.h> -#include <xen/time.h> -#include <xen/pci.h> -#include <xen/pci_regs.h> -#include <asm/msi.h> -#include "../iommu.h" -#include "../dmar.h" -#include "../vtd.h" -#include "../extern.h" -#include "../../ats.h" - -static bool device_in_domain(const struct vtd_iommu *iommu, - const struct pci_dev *pdev, uint16_t did) -{ - struct root_entry *root_entry; - struct context_entry *ctxt_entry = NULL; - unsigned int tt; - bool found = false; - - if ( unlikely(!iommu->root_maddr) ) - { - ASSERT_UNREACHABLE(); - return false; - } - - root_entry = map_vtd_domain_page(iommu->root_maddr); - if ( !root_present(root_entry[pdev->bus]) ) - goto out; - - ctxt_entry = map_vtd_domain_page(root_entry[pdev->bus].val); - if ( context_domain_id(ctxt_entry[pdev->devfn]) != did ) - goto out; - - tt = context_translation_type(ctxt_entry[pdev->devfn]); - if ( tt != CONTEXT_TT_DEV_IOTLB ) - goto out; - - found = true; -out: - if ( root_entry ) - unmap_vtd_domain_page(root_entry); - - if ( ctxt_entry ) - unmap_vtd_domain_page(ctxt_entry); - - return found; -} - -int dev_invalidate_iotlb(struct vtd_iommu *iommu, u16 did, - u64 addr, unsigned int size_order, u64 type) -{ - struct pci_dev *pdev, *temp; - int ret = 0; - - if ( !ecap_dev_iotlb(iommu->ecap) ) - return ret; - - list_for_each_entry_safe( pdev, temp, &iommu->ats_devices, ats.list ) - { - bool sbit; - int rc = 0; - - switch ( type ) - { - case DMA_TLB_DSI_FLUSH: - if ( !device_in_domain(iommu, pdev, did) ) - break; - /* fall through if DSI condition met */ - case DMA_TLB_GLOBAL_FLUSH: - /* invalidate all translations: sbit=1,bit_63=0,bit[62:12]=1 */ - sbit = 1; - addr = (~0UL << PAGE_SHIFT_4K) & 0x7FFFFFFFFFFFFFFF; - rc = qinval_device_iotlb_sync(iommu, pdev, did, sbit, addr); - break; - case DMA_TLB_PSI_FLUSH: - if ( !device_in_domain(iommu, pdev, did) ) - break; - - /* if size <= 4K, set sbit = 0, else set sbit = 1 */ - sbit = size_order ? 1 : 0; - - /* clear lower bits */ - addr &= ~0UL << PAGE_SHIFT_4K; - - /* if sbit == 1, zero out size_order bit and set lower bits to 1 */ - if ( sbit ) - { - addr &= ~((u64)PAGE_SIZE_4K << (size_order - 1)); - addr |= (((u64)1 << (size_order - 1)) - 1) << PAGE_SHIFT_4K; - } - - rc = qinval_device_iotlb_sync(iommu, pdev, did, sbit, addr); - break; - default: - dprintk(XENLOG_WARNING VTDPREFIX, "invalid vt-d flush type\n"); - return -EOPNOTSUPP; - } - - if ( !ret ) - ret = rc; - } - - return ret; -}
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |