mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 02:01:24 +01:00
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@suse.com> Acked-by: Roger Pau Monné <roger.pau@citrix.com>
This commit is contained in:
1 parent
f3759045b0
commit
15b90f90b4
4 files changed
+100
-132
No files matched your search
@@ -65,12 +65,6 @@ struct acpi_drhd_unit *ioapic_to_drhd(unsigned int apic_id);
|
||||
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);
|
||||
|
||||
@@ -251,8 +251,9 @@ static int __must_check dev_invalidate_sync(struct vtd_iommu *iommu,
|
||||
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_iommu *iommu, struct pci_dev *pdev,
|
||||
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)
|
||||
{
|
||||
|
||||
@@ -1,2 +1 @@
|
||||
obj-y += ats.o
|
||||
obj-y += vtd.o
|
||||
@@ -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@intel.com>
|
||||
*/
|
||||
|
||||
#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;
|
||||
}
|
||||