mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2025-01-20 20:47:25 +07:00
562831747f
This adds the system wide PASID name space for the PASID allocation. Currently we are using per IOMMU PASID name spaces which are not suitable for some use cases. For an example, one application (associated with a PASID) might talk to two physical devices simultaneously while the two devices could reside behind two different IOMMU units. Cc: Ashok Raj <ashok.raj@intel.com> Cc: Jacob Pan <jacob.jun.pan@linux.intel.com> Cc: Kevin Tian <kevin.tian@intel.com> Cc: Liu Yi L <yi.l.liu@intel.com> Suggested-by: Ashok Raj <ashok.raj@intel.com> Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com> Reviewed-by: Kevin Tian <kevin.tian@intel.com> Reviewed-by: Liu Yi L <yi.l.liu@intel.com> Reviewed-by: Peter Xu <peterx@redhat.com> Signed-off-by: Joerg Roedel <jroedel@suse.de>
61 lines
1.2 KiB
C
61 lines
1.2 KiB
C
// SPDX-License-Identifier: GPL-2.0
|
|
/**
|
|
* intel-pasid.c - PASID idr, table and entry manipulation
|
|
*
|
|
* Copyright (C) 2018 Intel Corporation
|
|
*
|
|
* Author: Lu Baolu <baolu.lu@linux.intel.com>
|
|
*/
|
|
|
|
#define pr_fmt(fmt) "DMAR: " fmt
|
|
|
|
#include <linux/dmar.h>
|
|
#include <linux/intel-iommu.h>
|
|
#include <linux/iommu.h>
|
|
#include <linux/memory.h>
|
|
#include <linux/spinlock.h>
|
|
|
|
#include "intel-pasid.h"
|
|
|
|
/*
|
|
* Intel IOMMU system wide PASID name space:
|
|
*/
|
|
static DEFINE_SPINLOCK(pasid_lock);
|
|
u32 intel_pasid_max_id = PASID_MAX;
|
|
static DEFINE_IDR(pasid_idr);
|
|
|
|
int intel_pasid_alloc_id(void *ptr, int start, int end, gfp_t gfp)
|
|
{
|
|
int ret, min, max;
|
|
|
|
min = max_t(int, start, PASID_MIN);
|
|
max = min_t(int, end, intel_pasid_max_id);
|
|
|
|
WARN_ON(in_interrupt());
|
|
idr_preload(gfp);
|
|
spin_lock(&pasid_lock);
|
|
ret = idr_alloc(&pasid_idr, ptr, min, max, GFP_ATOMIC);
|
|
spin_unlock(&pasid_lock);
|
|
idr_preload_end();
|
|
|
|
return ret;
|
|
}
|
|
|
|
void intel_pasid_free_id(int pasid)
|
|
{
|
|
spin_lock(&pasid_lock);
|
|
idr_remove(&pasid_idr, pasid);
|
|
spin_unlock(&pasid_lock);
|
|
}
|
|
|
|
void *intel_pasid_lookup_id(int pasid)
|
|
{
|
|
void *p;
|
|
|
|
spin_lock(&pasid_lock);
|
|
p = idr_find(&pasid_idr, pasid);
|
|
spin_unlock(&pasid_lock);
|
|
|
|
return p;
|
|
}
|