Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
cloud-kernel
提交
1208225c
cloud-kernel
项目概览
openanolis
/
cloud-kernel
接近 2 年 前同步成功
通知
169
Star
36
Fork
7
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
10
列表
看板
标记
里程碑
合并请求
2
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
cloud-kernel
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
10
Issue
10
列表
看板
标记
里程碑
合并请求
2
合并请求
2
Pages
分析
分析
仓库分析
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)
...
@@ -1086,6 +1086,11 @@ static void free_iommu(struct intel_iommu *iommu)
iommu_device_destroy
(
iommu
->
iommu_dev
);
iommu_device_destroy
(
iommu
->
iommu_dev
);
if
(
iommu
->
irq
)
{
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
);
free_irq
(
iommu
->
irq
,
iommu
);
dmar_free_hwirq
(
iommu
->
irq
);
dmar_free_hwirq
(
iommu
->
irq
);
iommu
->
irq
=
0
;
iommu
->
irq
=
0
;
...
@@ -1493,53 +1498,68 @@ static const char *dmar_get_fault_reason(u8 fault_reason, int *fault_type)
...
@@ -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
)
void
dmar_msi_unmask
(
struct
irq_data
*
data
)
{
{
struct
intel_iommu
*
iommu
=
irq_data_get_irq_handler_data
(
data
);
struct
intel_iommu
*
iommu
=
irq_data_get_irq_handler_data
(
data
);
int
reg
=
dmar_msi_reg
(
iommu
,
data
->
irq
);
unsigned
long
flag
;
unsigned
long
flag
;
/* unmask it */
/* unmask it */
raw_spin_lock_irqsave
(
&
iommu
->
register_lock
,
flag
);
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 */
/* 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
);
raw_spin_unlock_irqrestore
(
&
iommu
->
register_lock
,
flag
);
}
}
void
dmar_msi_mask
(
struct
irq_data
*
data
)
void
dmar_msi_mask
(
struct
irq_data
*
data
)
{
{
unsigned
long
flag
;
struct
intel_iommu
*
iommu
=
irq_data_get_irq_handler_data
(
data
);
struct
intel_iommu
*
iommu
=
irq_data_get_irq_handler_data
(
data
);
int
reg
=
dmar_msi_reg
(
iommu
,
data
->
irq
);
unsigned
long
flag
;
/* mask it */
/* mask it */
raw_spin_lock_irqsave
(
&
iommu
->
register_lock
,
flag
);
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 */
/* 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
);
raw_spin_unlock_irqrestore
(
&
iommu
->
register_lock
,
flag
);
}
}
void
dmar_msi_write
(
int
irq
,
struct
msi_msg
*
msg
)
void
dmar_msi_write
(
int
irq
,
struct
msi_msg
*
msg
)
{
{
struct
intel_iommu
*
iommu
=
irq_get_handler_data
(
irq
);
struct
intel_iommu
*
iommu
=
irq_get_handler_data
(
irq
);
int
reg
=
dmar_msi_reg
(
iommu
,
irq
);
unsigned
long
flag
;
unsigned
long
flag
;
raw_spin_lock_irqsave
(
&
iommu
->
register_lock
,
flag
);
raw_spin_lock_irqsave
(
&
iommu
->
register_lock
,
flag
);
writel
(
msg
->
data
,
iommu
->
reg
+
DMAR_FEDATA_REG
);
writel
(
msg
->
data
,
iommu
->
reg
+
reg
+
4
);
writel
(
msg
->
address_lo
,
iommu
->
reg
+
DMAR_FEADDR_REG
);
writel
(
msg
->
address_lo
,
iommu
->
reg
+
reg
+
8
);
writel
(
msg
->
address_hi
,
iommu
->
reg
+
DMAR_FEUADDR_REG
);
writel
(
msg
->
address_hi
,
iommu
->
reg
+
reg
+
12
);
raw_spin_unlock_irqrestore
(
&
iommu
->
register_lock
,
flag
);
raw_spin_unlock_irqrestore
(
&
iommu
->
register_lock
,
flag
);
}
}
void
dmar_msi_read
(
int
irq
,
struct
msi_msg
*
msg
)
void
dmar_msi_read
(
int
irq
,
struct
msi_msg
*
msg
)
{
{
struct
intel_iommu
*
iommu
=
irq_get_handler_data
(
irq
);
struct
intel_iommu
*
iommu
=
irq_get_handler_data
(
irq
);
int
reg
=
dmar_msi_reg
(
iommu
,
irq
);
unsigned
long
flag
;
unsigned
long
flag
;
raw_spin_lock_irqsave
(
&
iommu
->
register_lock
,
flag
);
raw_spin_lock_irqsave
(
&
iommu
->
register_lock
,
flag
);
msg
->
data
=
readl
(
iommu
->
reg
+
DMAR_FEDATA_REG
);
msg
->
data
=
readl
(
iommu
->
reg
+
reg
+
4
);
msg
->
address_lo
=
readl
(
iommu
->
reg
+
DMAR_FEADDR_REG
);
msg
->
address_lo
=
readl
(
iommu
->
reg
+
reg
+
8
);
msg
->
address_hi
=
readl
(
iommu
->
reg
+
DMAR_FEUADDR_REG
);
msg
->
address_hi
=
readl
(
iommu
->
reg
+
reg
+
12
);
raw_spin_unlock_irqrestore
(
&
iommu
->
register_lock
,
flag
);
raw_spin_unlock_irqrestore
(
&
iommu
->
register_lock
,
flag
);
}
}
...
...
include/linux/intel-iommu.h
浏览文件 @
1208225c
...
@@ -60,6 +60,14 @@
...
@@ -60,6 +60,14 @@
#define DMAR_IQA_REG 0x90
/* Invalidation queue addr register */
#define DMAR_IQA_REG 0x90
/* Invalidation queue addr register */
#define DMAR_ICS_REG 0x9c
/* Invalidation complete status register */
#define DMAR_ICS_REG 0x9c
/* Invalidation complete status register */
#define DMAR_IRTA_REG 0xb8
/* Interrupt remapping table addr 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)
#define OFFSET_STRIDE (9)
...
@@ -373,7 +381,7 @@ struct intel_iommu {
...
@@ -373,7 +381,7 @@ struct intel_iommu {
int
seq_id
;
/* sequence id of the iommu */
int
seq_id
;
/* sequence id of the iommu */
int
agaw
;
/* agaw of this iommu */
int
agaw
;
/* agaw of this iommu */
int
msagaw
;
/* max sagaw of this iommu */
int
msagaw
;
/* max sagaw of this iommu */
unsigned
int
irq
;
unsigned
int
irq
,
pr_irq
;
u16
segment
;
/* PCI segment# */
u16
segment
;
/* PCI segment# */
unsigned
char
name
[
13
];
/* Device Name */
unsigned
char
name
[
13
];
/* Device Name */
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录