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:
Jan Beulich committed 2026-01-08 08:07:19 +01:00
1 parent f3759045b0
commit 15b90f90b4
4 files changed
+100 -132

No files matched your search

-6
View File
@@ -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);
+100 -2
View File
@@ -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
View File
@@ -1,2 +1 @@
obj-y += ats.o
obj-y += vtd.o
-123
View File
@@ -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;
}
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.