Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
gsplhtlxg
clone-Linux
提交
0204a496
C
clone-Linux
项目概览
gsplhtlxg
/
clone-Linux
通知
2
Star
0
Fork
1
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
C
clone-Linux
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
0204a496
编写于
10月 13, 2015
作者:
D
David Woodhouse
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
iommu/vt-d: Add callback to device driver on page faults
Signed-off-by:
N
David Woodhouse
<
David.Woodhouse@intel.com
>
上级
a222a7f0
变更
3
显示空白变更内容
内联
并排
Showing
3 changed file
with
46 addition
and
4 deletion
+46
-4
drivers/iommu/intel-svm.c
drivers/iommu/intel-svm.c
+25
-1
include/linux/intel-iommu.h
include/linux/intel-iommu.h
+3
-0
include/linux/intel-svm.h
include/linux/intel-svm.h
+18
-3
未找到文件。
drivers/iommu/intel-svm.c
浏览文件 @
0204a496
...
...
@@ -264,7 +264,7 @@ static const struct mmu_notifier_ops intel_mmuops = {
static
DEFINE_MUTEX
(
pasid_mutex
);
int
intel_svm_bind_mm
(
struct
device
*
dev
,
int
*
pasid
)
int
intel_svm_bind_mm
(
struct
device
*
dev
,
int
*
pasid
,
int
flags
,
struct
svm_dev_ops
*
ops
)
{
struct
intel_iommu
*
iommu
=
intel_svm_device_to_iommu
(
dev
);
struct
intel_svm_dev
*
sdev
;
...
...
@@ -302,6 +302,10 @@ int intel_svm_bind_mm(struct device *dev, int *pasid)
list_for_each_entry
(
sdev
,
&
svm
->
devs
,
list
)
{
if
(
dev
==
sdev
->
dev
)
{
if
(
sdev
->
ops
!=
ops
)
{
ret
=
-
EBUSY
;
goto
out
;
}
sdev
->
users
++
;
goto
success
;
}
...
...
@@ -327,6 +331,7 @@ int intel_svm_bind_mm(struct device *dev, int *pasid)
}
/* Finish the setup now we know we're keeping it */
sdev
->
users
=
1
;
sdev
->
ops
=
ops
;
init_rcu_head
(
&
sdev
->
rcu
);
if
(
!
svm
)
{
...
...
@@ -456,6 +461,7 @@ static irqreturn_t prq_event_thread(int irq, void *d)
tail
=
dmar_readq
(
iommu
->
reg
+
DMAR_PQT_REG
)
&
PRQ_RING_MASK
;
head
=
dmar_readq
(
iommu
->
reg
+
DMAR_PQH_REG
)
&
PRQ_RING_MASK
;
while
(
head
!=
tail
)
{
struct
intel_svm_dev
*
sdev
;
struct
vm_area_struct
*
vma
;
struct
page_req_dsc
*
req
;
struct
qi_desc
resp
;
...
...
@@ -507,6 +513,24 @@ static irqreturn_t prq_event_thread(int irq, void *d)
up_read
(
&
svm
->
mm
->
mmap_sem
);
bad_req:
/* Accounting for major/minor faults? */
rcu_read_lock
();
list_for_each_entry_rcu
(
sdev
,
&
svm
->
devs
,
list
)
{
if
(
sdev
->
sid
==
PCI_DEVID
(
req
->
bus
,
req
->
devfn
));
break
;
}
/* Other devices can go away, but the drivers are not permitted
* to unbind while any page faults might be in flight. So it's
* OK to drop the 'lock' here now we have it. */
rcu_read_unlock
();
if
(
WARN_ON
(
&
sdev
->
list
==
&
svm
->
devs
))
sdev
=
NULL
;
if
(
sdev
&&
sdev
->
ops
&&
sdev
->
ops
->
fault_cb
)
{
int
rwxp
=
(
req
->
rd_req
<<
3
)
|
(
req
->
wr_req
<<
2
)
|
(
req
->
wr_req
<<
1
)
|
(
req
->
exe_req
);
sdev
->
ops
->
fault_cb
(
sdev
->
dev
,
req
->
pasid
,
req
->
addr
,
req
->
private
,
rwxp
,
result
);
}
if
(
req
->
lpig
)
{
/* Page Group Response */
...
...
include/linux/intel-iommu.h
浏览文件 @
0204a496
...
...
@@ -472,10 +472,13 @@ extern int intel_svm_free_pasid_tables(struct intel_iommu *iommu);
extern
int
intel_svm_enable_prq
(
struct
intel_iommu
*
iommu
);
extern
int
intel_svm_finish_prq
(
struct
intel_iommu
*
iommu
);
struct
svm_dev_ops
;
struct
intel_svm_dev
{
struct
list_head
list
;
struct
rcu_head
rcu
;
struct
device
*
dev
;
struct
svm_dev_ops
*
ops
;
int
users
;
u16
did
;
u16
dev_iotlb
:
1
;
...
...
include/linux/intel-svm.h
浏览文件 @
0204a496
...
...
@@ -20,10 +20,23 @@
struct
device
;
struct
svm_dev_ops
{
void
(
*
fault_cb
)(
struct
device
*
dev
,
int
pasid
,
u64
address
,
u32
private
,
int
rwxp
,
int
response
);
};
/* Values for rxwp in fault_cb callback */
#define SVM_REQ_READ (1<<3)
#define SVM_REQ_WRITE (1<<2)
#define SVM_REQ_EXEC (1<<1)
#define SVM_REQ_PRIV (1<<0)
/**
* intel_svm_bind_mm() - Bind the current process to a PASID
* @dev: Device to be granted acccess
* @pasid: Address for allocated PASID
* @flags: Flags. Later for requesting supervisor mode, etc.
* @ops: Callbacks to device driver
*
* This function attempts to enable PASID support for the given device.
* If the @pasid argument is non-%NULL, a PASID is allocated for access
...
...
@@ -45,7 +58,8 @@ struct device;
* Multiple calls from the same process may result in the same PASID
* being re-used. A reference count is kept.
*/
extern
int
intel_svm_bind_mm
(
struct
device
*
dev
,
int
*
pasid
);
extern
int
intel_svm_bind_mm
(
struct
device
*
dev
,
int
*
pasid
,
int
flags
,
struct
svm_dev_ops
*
ops
);
/**
* intel_svm_unbind_mm() - Unbind a specified PASID
...
...
@@ -66,7 +80,8 @@ extern int intel_svm_unbind_mm(struct device *dev, int pasid);
#else
/* CONFIG_INTEL_IOMMU_SVM */
static
inline
int
intel_svm_bind_mm
(
struct
device
*
dev
,
int
*
pasid
)
static
inline
int
intel_svm_bind_mm
(
struct
device
*
dev
,
int
*
pasid
,
int
flags
,
struct
svm_dev_ops
*
ops
)
{
return
-
ENOSYS
;
}
...
...
@@ -77,6 +92,6 @@ static inline int intel_svm_unbind_mm(struct device *dev, int pasid)
}
#endif
/* CONFIG_INTEL_IOMMU_SVM */
#define intel_svm_available(dev) (!intel_svm_bind_mm((dev), NULL))
#define intel_svm_available(dev) (!intel_svm_bind_mm((dev), NULL
, 0, NULL
))
#endif
/* __INTEL_SVM_H__ */
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录