Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
Kernel
提交
1208225c
K
Kernel
项目概览
openeuler
/
Kernel
1 年多 前同步成功
通知
8
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
K
Kernel
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
提交
1208225c
编写于
10月 07, 2015
作者:
D
David Woodhouse
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
iommu/vt-d: Generalise DMAR MSI setup to allow for page request events
Signed-off-by:
N
David Woodhouse
<
David.Woodhouse@intel.com
>
上级
907fea34
变更
2
隐藏空白更改
内联
并排
Showing
2 changed file
with
40 addition
and
12 deletion
+40
-12
drivers/iommu/dmar.c
drivers/iommu/dmar.c
+31
-11
include/linux/intel-iommu.h
include/linux/intel-iommu.h
+9
-1
未找到文件。
drivers/iommu/dmar.c
浏览文件 @
1208225c
...
...
@@ -1086,6 +1086,11 @@ static void free_iommu(struct intel_iommu *iommu)
iommu_device_destroy
(
iommu
->
iommu_dev
);
if
(
iommu
->
irq
)
{
if
(
iommu
->
pr_irq
)
{
free_irq
(
iommu
->
pr_irq
,
iommu
);
dmar_free_hwirq
(
iommu
->
pr_irq
);
iommu
->
pr_irq
=
0
;
}
free_irq
(
iommu
->
irq
,
iommu
);
dmar_free_hwirq
(
iommu
->
irq
);
iommu
->
irq
=
0
;
...
...
@@ -1493,53 +1498,68 @@ static const char *dmar_get_fault_reason(u8 fault_reason, int *fault_type)
}
}
static
inline
int
dmar_msi_reg
(
struct
intel_iommu
*
iommu
,
int
irq
)
{
if
(
iommu
->
irq
==
irq
)
return
DMAR_FECTL_REG
;
else
if
(
iommu
->
pr_irq
==
irq
)
return
DMAR_PECTL_REG
;
else
BUG
();
}
void
dmar_msi_unmask
(
struct
irq_data
*
data
)
{
struct
intel_iommu
*
iommu
=
irq_data_get_irq_handler_data
(
data
);
int
reg
=
dmar_msi_reg
(
iommu
,
data
->
irq
);
unsigned
long
flag
;
/* unmask it */
raw_spin_lock_irqsave
(
&
iommu
->
register_lock
,
flag
);
writel
(
0
,
iommu
->
reg
+
DMAR_FECTL_REG
);
writel
(
0
,
iommu
->
reg
+
reg
);
/* Read a reg to force flush the post write */
readl
(
iommu
->
reg
+
DMAR_FECTL_REG
);
readl
(
iommu
->
reg
+
reg
);
raw_spin_unlock_irqrestore
(
&
iommu
->
register_lock
,
flag
);
}
void
dmar_msi_mask
(
struct
irq_data
*
data
)
{
unsigned
long
flag
;
struct
intel_iommu
*
iommu
=
irq_data_get_irq_handler_data
(
data
);
int
reg
=
dmar_msi_reg
(
iommu
,
data
->
irq
);
unsigned
long
flag
;
/* mask it */
raw_spin_lock_irqsave
(
&
iommu
->
register_lock
,
flag
);
writel
(
DMA_FECTL_IM
,
iommu
->
reg
+
DMAR_FECTL_REG
);
writel
(
DMA_FECTL_IM
,
iommu
->
reg
+
reg
);
/* Read a reg to force flush the post write */
readl
(
iommu
->
reg
+
DMAR_FECTL_REG
);
readl
(
iommu
->
reg
+
reg
);
raw_spin_unlock_irqrestore
(
&
iommu
->
register_lock
,
flag
);
}
void
dmar_msi_write
(
int
irq
,
struct
msi_msg
*
msg
)
{
struct
intel_iommu
*
iommu
=
irq_get_handler_data
(
irq
);
int
reg
=
dmar_msi_reg
(
iommu
,
irq
);
unsigned
long
flag
;
raw_spin_lock_irqsave
(
&
iommu
->
register_lock
,
flag
);
writel
(
msg
->
data
,
iommu
->
reg
+
DMAR_FEDATA_REG
);
writel
(
msg
->
address_lo
,
iommu
->
reg
+
DMAR_FEADDR_REG
);
writel
(
msg
->
address_hi
,
iommu
->
reg
+
DMAR_FEUADDR_REG
);
writel
(
msg
->
data
,
iommu
->
reg
+
reg
+
4
);
writel
(
msg
->
address_lo
,
iommu
->
reg
+
reg
+
8
);
writel
(
msg
->
address_hi
,
iommu
->
reg
+
reg
+
12
);
raw_spin_unlock_irqrestore
(
&
iommu
->
register_lock
,
flag
);
}
void
dmar_msi_read
(
int
irq
,
struct
msi_msg
*
msg
)
{
struct
intel_iommu
*
iommu
=
irq_get_handler_data
(
irq
);
int
reg
=
dmar_msi_reg
(
iommu
,
irq
);
unsigned
long
flag
;
raw_spin_lock_irqsave
(
&
iommu
->
register_lock
,
flag
);
msg
->
data
=
readl
(
iommu
->
reg
+
DMAR_FEDATA_REG
);
msg
->
address_lo
=
readl
(
iommu
->
reg
+
DMAR_FEADDR_REG
);
msg
->
address_hi
=
readl
(
iommu
->
reg
+
DMAR_FEUADDR_REG
);
msg
->
data
=
readl
(
iommu
->
reg
+
reg
+
4
);
msg
->
address_lo
=
readl
(
iommu
->
reg
+
reg
+
8
);
msg
->
address_hi
=
readl
(
iommu
->
reg
+
reg
+
12
);
raw_spin_unlock_irqrestore
(
&
iommu
->
register_lock
,
flag
);
}
...
...
include/linux/intel-iommu.h
浏览文件 @
1208225c
...
...
@@ -60,6 +60,14 @@
#define DMAR_IQA_REG 0x90
/* Invalidation queue addr register */
#define DMAR_ICS_REG 0x9c
/* Invalidation complete status register */
#define DMAR_IRTA_REG 0xb8
/* Interrupt remapping table addr register */
#define DMAR_PQH_REG 0xc0
/* Page request queue head register */
#define DMAR_PQT_REG 0xc8
/* Page request queue tail register */
#define DMAR_PQA_REG 0xd0
/* Page request queue address register */
#define DMAR_PRS_REG 0xdc
/* Page request status register */
#define DMAR_PECTL_REG 0xe0
/* Page request event control register */
#define DMAR_PEDATA_REG 0xe4
/* Page request event interrupt data register */
#define DMAR_PEADDR_REG 0xe8
/* Page request event interrupt addr register */
#define DMAR_PEUADDR_REG 0xec
/* Page request event Upper address register */
#define OFFSET_STRIDE (9)
...
...
@@ -373,7 +381,7 @@ struct intel_iommu {
int
seq_id
;
/* sequence id of the iommu */
int
agaw
;
/* agaw of this iommu */
int
msagaw
;
/* max sagaw of this iommu */
unsigned
int
irq
;
unsigned
int
irq
,
pr_irq
;
u16
segment
;
/* PCI segment# */
unsigned
char
name
[
13
];
/* Device Name */
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录