提交 d32e9e95 编写于 作者: J Jacob Pan 提交者: Xie XiuQi

iommu: introduce bind_pasid_table API function

hulk inclusion
category: feature
bugzilla: 14369
CVE: NA
-------------------

Virtual IOMMU was proposed to support Shared Virtual Memory (SVM)
use in the guest:
https://lists.gnu.org/archive/html/qemu-devel/2016-11/msg05311.html

As part of the proposed architecture, when an SVM capable PCI
device is assigned to a guest, nested mode is turned on. Guest owns the
first level page tables (request with PASID) which performs GVA->GPA
translation. Second level page tables are owned by the host for GPA->HPA
translation for both request with and without PASID.

A new IOMMU driver interface is therefore needed to perform tasks as
follows:
* Enable nested translation and appropriate translation type
* Assign guest PASID table pointer (in GPA) and size to host IOMMU

This patch introduces new API functions to perform bind/unbind guest PASID
tables. Based on common data, model specific IOMMU drivers can be extended
to perform the specific steps for binding pasid table of assigned devices.
Signed-off-by: NJean-Philippe Brucker <jean-philippe.brucker@arm.com>
Signed-off-by: NLiu, Yi L <yi.l.liu@linux.intel.com>
Signed-off-by: NAshok Raj <ashok.raj@intel.com>
Signed-off-by: NJacob Pan <jacob.jun.pan@linux.intel.com>
[Backported to 4.19
-add SPDX-License-Identifier]
Signed-off-by: NFang Lijun <fanglijun3@huawei.com>
Reviewed-by: NHanjun Guo <guohanjun@huawei.com>
Reviewed-by: NZhen Lei <thunder.leizhen@huawei.com>
Signed-off-by: NYang Yingliang <yangyingliang@huawei.com>
上级 a382cc87
...@@ -1400,6 +1400,25 @@ int iommu_attach_device(struct iommu_domain *domain, struct device *dev) ...@@ -1400,6 +1400,25 @@ int iommu_attach_device(struct iommu_domain *domain, struct device *dev)
} }
EXPORT_SYMBOL_GPL(iommu_attach_device); EXPORT_SYMBOL_GPL(iommu_attach_device);
int iommu_bind_pasid_table(struct iommu_domain *domain, struct device *dev,
struct pasid_table_config *pasidt_binfo)
{
if (unlikely(!domain->ops->bind_pasid_table))
return -ENODEV;
return domain->ops->bind_pasid_table(domain, dev, pasidt_binfo);
}
EXPORT_SYMBOL_GPL(iommu_bind_pasid_table);
void iommu_unbind_pasid_table(struct iommu_domain *domain, struct device *dev)
{
if (unlikely(!domain->ops->unbind_pasid_table))
return;
domain->ops->unbind_pasid_table(domain, dev);
}
EXPORT_SYMBOL_GPL(iommu_unbind_pasid_table);
static void __iommu_detach_device(struct iommu_domain *domain, static void __iommu_detach_device(struct iommu_domain *domain,
struct device *dev) struct device *dev)
{ {
......
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
#include <linux/errno.h> #include <linux/errno.h>
#include <linux/err.h> #include <linux/err.h>
#include <linux/of.h> #include <linux/of.h>
#include <uapi/linux/iommu.h>
#define IOMMU_READ (1 << 0) #define IOMMU_READ (1 << 0)
#define IOMMU_WRITE (1 << 1) #define IOMMU_WRITE (1 << 1)
...@@ -186,6 +187,8 @@ struct iommu_resv_region { ...@@ -186,6 +187,8 @@ struct iommu_resv_region {
* @domain_get_windows: Return the number of windows for a domain * @domain_get_windows: Return the number of windows for a domain
* @of_xlate: add OF master IDs to iommu grouping * @of_xlate: add OF master IDs to iommu grouping
* @pgsize_bitmap: bitmap of all possible supported page sizes * @pgsize_bitmap: bitmap of all possible supported page sizes
* @bind_pasid_table: bind pasid table pointer for guest SVM
* @unbind_pasid_table: unbind pasid table pointer and restore defaults
*/ */
struct iommu_ops { struct iommu_ops {
bool (*capable)(enum iommu_cap); bool (*capable)(enum iommu_cap);
...@@ -230,8 +233,14 @@ struct iommu_ops { ...@@ -230,8 +233,14 @@ struct iommu_ops {
u32 (*domain_get_windows)(struct iommu_domain *domain); u32 (*domain_get_windows)(struct iommu_domain *domain);
int (*of_xlate)(struct device *dev, struct of_phandle_args *args); int (*of_xlate)(struct device *dev, struct of_phandle_args *args);
bool (*is_attach_deferred)(struct iommu_domain *domain, struct device *dev); bool (*is_attach_deferred)(struct iommu_domain *domain, struct device *dev);
int (*bind_pasid_table)(struct iommu_domain *domain, struct device *dev,
struct pasid_table_config *pasidt_binfo);
void (*unbind_pasid_table)(struct iommu_domain *domain,
struct device *dev);
unsigned long pgsize_bitmap; unsigned long pgsize_bitmap;
}; };
...@@ -293,6 +302,10 @@ extern int iommu_attach_device(struct iommu_domain *domain, ...@@ -293,6 +302,10 @@ extern int iommu_attach_device(struct iommu_domain *domain,
struct device *dev); struct device *dev);
extern void iommu_detach_device(struct iommu_domain *domain, extern void iommu_detach_device(struct iommu_domain *domain,
struct device *dev); struct device *dev);
extern int iommu_bind_pasid_table(struct iommu_domain *domain,
struct device *dev, struct pasid_table_config *pasidt_binfo);
extern void iommu_unbind_pasid_table(struct iommu_domain *domain,
struct device *dev);
extern struct iommu_domain *iommu_get_domain_for_dev(struct device *dev); extern struct iommu_domain *iommu_get_domain_for_dev(struct device *dev);
extern struct iommu_domain *iommu_get_dma_domain(struct device *dev); extern struct iommu_domain *iommu_get_dma_domain(struct device *dev);
extern int iommu_map(struct iommu_domain *domain, unsigned long iova, extern int iommu_map(struct iommu_domain *domain, unsigned long iova,
...@@ -700,6 +713,19 @@ struct iommu_domain *iommu_group_unshare_domain(struct iommu_group *group) ...@@ -700,6 +713,19 @@ struct iommu_domain *iommu_group_unshare_domain(struct iommu_group *group)
{ {
return NULL; return NULL;
} }
static inline
int iommu_bind_pasid_table(struct iommu_domain *domain, struct device *dev,
struct pasid_table_config *pasidt_binfo)
{
return -EINVAL;
}
static inline
void iommu_unbind_pasid_table(struct iommu_domain *domain, struct device *dev)
{
}
#endif /* CONFIG_IOMMU_API */ #endif /* CONFIG_IOMMU_API */
#ifdef CONFIG_IOMMU_DEBUGFS #ifdef CONFIG_IOMMU_DEBUGFS
......
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
/*
* IOMMU user API definitions
*
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#ifndef _UAPI_IOMMU_H
#define _UAPI_IOMMU_H
#include <linux/types.h>
/**
* PASID table data used to bind guest PASID table to the host IOMMU. This will
* enable guest managed first level page tables.
* @version: for future extensions and identification of the data format
* @bytes: size of this structure
* @base_ptr: PASID table pointer
* @pasid_bits: number of bits supported in the guest PASID table, must be less
* or equal than the host supported PASID size.
*/
struct pasid_table_config {
__u32 version;
#define PASID_TABLE_CFG_VERSION 1
__u32 bytes;
__u64 base_ptr;
__u8 pasid_bits;
};
#endif /* _UAPI_IOMMU_H */
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册