Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
raspberrypi-kernel
提交
8077e8b0
R
raspberrypi-kernel
项目概览
openeuler
/
raspberrypi-kernel
通知
13
Star
1
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
raspberrypi-kernel
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
8077e8b0
编写于
11月 17, 2011
作者:
J
James Morris
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'for-james' of
git://github.com/srajiv/tpm
into next
上级
7845bc39
b9e3238a
变更
4
隐藏空白更改
内联
并排
Showing
4 changed file
with
152 addition
and
80 deletion
+152
-80
drivers/char/tpm/Kconfig
drivers/char/tpm/Kconfig
+2
-0
drivers/char/tpm/tpm.c
drivers/char/tpm/tpm.c
+117
-20
drivers/char/tpm/tpm.h
drivers/char/tpm/tpm.h
+6
-3
drivers/char/tpm/tpm_tis.c
drivers/char/tpm/tpm_tis.c
+27
-57
未找到文件。
drivers/char/tpm/Kconfig
浏览文件 @
8077e8b0
...
...
@@ -27,6 +27,7 @@ if TCG_TPM
config TCG_TIS
tristate "TPM Interface Specification 1.2 Interface"
depends on X86
---help---
If you have a TPM security chip that is compliant with the
TCG TIS 1.2 TPM specification say Yes and it will be accessible
...
...
@@ -35,6 +36,7 @@ config TCG_TIS
config TCG_NSC
tristate "National Semiconductor TPM Interface"
depends on X86
---help---
If you have a TPM security chip from National Semiconductor
say Yes and it will be accessible from within Linux. To
...
...
drivers/char/tpm/tpm.c
浏览文件 @
8077e8b0
...
...
@@ -27,6 +27,7 @@
#include <linux/slab.h>
#include <linux/mutex.h>
#include <linux/spinlock.h>
#include <linux/freezer.h>
#include "tpm.h"
...
...
@@ -440,7 +441,6 @@ static ssize_t tpm_transmit(struct tpm_chip *chip, const char *buf,
}
#define TPM_DIGEST_SIZE 20
#define TPM_ERROR_SIZE 10
#define TPM_RET_CODE_IDX 6
enum
tpm_capabilities
{
...
...
@@ -469,12 +469,14 @@ static ssize_t transmit_cmd(struct tpm_chip *chip, struct tpm_cmd_t *cmd,
len
=
tpm_transmit
(
chip
,(
u8
*
)
cmd
,
len
);
if
(
len
<
0
)
return
len
;
if
(
len
==
TPM_ERROR_SIZE
)
{
err
=
be32_to_cpu
(
cmd
->
header
.
out
.
return_code
);
dev_dbg
(
chip
->
dev
,
"A TPM error (%d) occurred %s
\n
"
,
err
,
desc
);
return
err
;
}
return
0
;
else
if
(
len
<
TPM_HEADER_SIZE
)
return
-
EFAULT
;
err
=
be32_to_cpu
(
cmd
->
header
.
out
.
return_code
);
if
(
err
!=
0
)
dev_err
(
chip
->
dev
,
"A TPM error (%d) occurred %s
\n
"
,
err
,
desc
);
return
err
;
}
#define TPM_INTERNAL_RESULT_SIZE 200
...
...
@@ -530,7 +532,7 @@ void tpm_gen_interrupt(struct tpm_chip *chip)
}
EXPORT_SYMBOL_GPL
(
tpm_gen_interrupt
);
void
tpm_get_timeouts
(
struct
tpm_chip
*
chip
)
int
tpm_get_timeouts
(
struct
tpm_chip
*
chip
)
{
struct
tpm_cmd_t
tpm_cmd
;
struct
timeout_t
*
timeout_cap
;
...
...
@@ -552,7 +554,7 @@ void tpm_get_timeouts(struct tpm_chip *chip)
if
(
be32_to_cpu
(
tpm_cmd
.
header
.
out
.
return_code
)
!=
0
||
be32_to_cpu
(
tpm_cmd
.
header
.
out
.
length
)
!=
sizeof
(
tpm_cmd
.
header
.
out
)
+
sizeof
(
u32
)
+
4
*
sizeof
(
u32
))
return
;
return
-
EINVAL
;
timeout_cap
=
&
tpm_cmd
.
params
.
getcap_out
.
cap
.
timeout
;
/* Don't overwrite default if value is 0 */
...
...
@@ -583,12 +585,12 @@ void tpm_get_timeouts(struct tpm_chip *chip)
rc
=
transmit_cmd
(
chip
,
&
tpm_cmd
,
TPM_INTERNAL_RESULT_SIZE
,
"attempting to determine the durations"
);
if
(
rc
)
return
;
return
rc
;
if
(
be32_to_cpu
(
tpm_cmd
.
header
.
out
.
return_code
)
!=
0
||
be32_to_cpu
(
tpm_cmd
.
header
.
out
.
length
)
!=
sizeof
(
tpm_cmd
.
header
.
out
)
+
sizeof
(
u32
)
+
3
*
sizeof
(
u32
))
return
;
return
-
EINVAL
;
duration_cap
=
&
tpm_cmd
.
params
.
getcap_out
.
cap
.
duration
;
chip
->
vendor
.
duration
[
TPM_SHORT
]
=
...
...
@@ -610,20 +612,36 @@ void tpm_get_timeouts(struct tpm_chip *chip)
chip
->
vendor
.
duration_adjusted
=
true
;
dev_info
(
chip
->
dev
,
"Adjusting TPM timeout parameters."
);
}
return
0
;
}
EXPORT_SYMBOL_GPL
(
tpm_get_timeouts
);
void
tpm_continue_selftest
(
struct
tpm_chip
*
chip
)
#define TPM_ORD_CONTINUE_SELFTEST 83
#define CONTINUE_SELFTEST_RESULT_SIZE 10
static
struct
tpm_input_header
continue_selftest_header
=
{
.
tag
=
TPM_TAG_RQU_COMMAND
,
.
length
=
cpu_to_be32
(
10
),
.
ordinal
=
cpu_to_be32
(
TPM_ORD_CONTINUE_SELFTEST
),
};
/**
* tpm_continue_selftest -- run TPM's selftest
* @chip: TPM chip to use
*
* Returns 0 on success, < 0 in case of fatal error or a value > 0 representing
* a TPM error code.
*/
static
int
tpm_continue_selftest
(
struct
tpm_chip
*
chip
)
{
u8
data
[]
=
{
0
,
193
,
/* TPM_TAG_RQU_COMMAND */
0
,
0
,
0
,
10
,
/* length */
0
,
0
,
0
,
83
,
/* TPM_ORD_ContinueSelfTest */
};
int
rc
;
struct
tpm_cmd_t
cmd
;
tpm_transmit
(
chip
,
data
,
sizeof
(
data
));
cmd
.
header
.
in
=
continue_selftest_header
;
rc
=
transmit_cmd
(
chip
,
&
cmd
,
CONTINUE_SELFTEST_RESULT_SIZE
,
"continue selftest"
);
return
rc
;
}
EXPORT_SYMBOL_GPL
(
tpm_continue_selftest
);
ssize_t
tpm_show_enabled
(
struct
device
*
dev
,
struct
device_attribute
*
attr
,
char
*
buf
)
...
...
@@ -718,7 +736,7 @@ static struct tpm_input_header pcrread_header = {
.
ordinal
=
TPM_ORDINAL_PCRREAD
};
int
__tpm_pcr_read
(
struct
tpm_chip
*
chip
,
int
pcr_idx
,
u8
*
res_buf
)
static
int
__tpm_pcr_read
(
struct
tpm_chip
*
chip
,
int
pcr_idx
,
u8
*
res_buf
)
{
int
rc
;
struct
tpm_cmd_t
cmd
;
...
...
@@ -798,6 +816,45 @@ int tpm_pcr_extend(u32 chip_num, int pcr_idx, const u8 *hash)
}
EXPORT_SYMBOL_GPL
(
tpm_pcr_extend
);
/**
* tpm_do_selftest - have the TPM continue its selftest and wait until it
* can receive further commands
* @chip: TPM chip to use
*
* Returns 0 on success, < 0 in case of fatal error or a value > 0 representing
* a TPM error code.
*/
int
tpm_do_selftest
(
struct
tpm_chip
*
chip
)
{
int
rc
;
u8
digest
[
TPM_DIGEST_SIZE
];
unsigned
int
loops
;
unsigned
int
delay_msec
=
1000
;
unsigned
long
duration
;
duration
=
tpm_calc_ordinal_duration
(
chip
,
TPM_ORD_CONTINUE_SELFTEST
);
loops
=
jiffies_to_msecs
(
duration
)
/
delay_msec
;
rc
=
tpm_continue_selftest
(
chip
);
/* This may fail if there was no TPM driver during a suspend/resume
* cycle; some may return 10 (BAD_ORDINAL), others 28 (FAILEDSELFTEST)
*/
if
(
rc
)
return
rc
;
do
{
rc
=
__tpm_pcr_read
(
chip
,
0
,
digest
);
if
(
rc
!=
TPM_WARN_DOING_SELFTEST
)
return
rc
;
msleep
(
delay_msec
);
}
while
(
--
loops
>
0
);
return
rc
;
}
EXPORT_SYMBOL_GPL
(
tpm_do_selftest
);
int
tpm_send
(
u32
chip_num
,
void
*
cmd
,
size_t
buflen
)
{
struct
tpm_chip
*
chip
;
...
...
@@ -1005,6 +1062,46 @@ ssize_t tpm_store_cancel(struct device *dev, struct device_attribute *attr,
}
EXPORT_SYMBOL_GPL
(
tpm_store_cancel
);
int
wait_for_tpm_stat
(
struct
tpm_chip
*
chip
,
u8
mask
,
unsigned
long
timeout
,
wait_queue_head_t
*
queue
)
{
unsigned
long
stop
;
long
rc
;
u8
status
;
/* check current status */
status
=
chip
->
vendor
.
status
(
chip
);
if
((
status
&
mask
)
==
mask
)
return
0
;
stop
=
jiffies
+
timeout
;
if
(
chip
->
vendor
.
irq
)
{
again:
timeout
=
stop
-
jiffies
;
if
((
long
)
timeout
<=
0
)
return
-
ETIME
;
rc
=
wait_event_interruptible_timeout
(
*
queue
,
((
chip
->
vendor
.
status
(
chip
)
&
mask
)
==
mask
),
timeout
);
if
(
rc
>
0
)
return
0
;
if
(
rc
==
-
ERESTARTSYS
&&
freezing
(
current
))
{
clear_thread_flag
(
TIF_SIGPENDING
);
goto
again
;
}
}
else
{
do
{
msleep
(
TPM_TIMEOUT
);
status
=
chip
->
vendor
.
status
(
chip
);
if
((
status
&
mask
)
==
mask
)
return
0
;
}
while
(
time_before
(
jiffies
,
stop
));
}
return
-
ETIME
;
}
EXPORT_SYMBOL_GPL
(
wait_for_tpm_stat
);
/*
* Device file system interface to the TPM
*
...
...
drivers/char/tpm/tpm.h
浏览文件 @
8077e8b0
...
...
@@ -38,6 +38,8 @@ enum tpm_addr {
TPM_ADDR
=
0x4E
,
};
#define TPM_WARN_DOING_SELFTEST 0x802
#define TPM_HEADER_SIZE 10
extern
ssize_t
tpm_show_pubek
(
struct
device
*
,
struct
device_attribute
*
attr
,
char
*
);
extern
ssize_t
tpm_show_pcrs
(
struct
device
*
,
struct
device_attribute
*
attr
,
...
...
@@ -279,9 +281,9 @@ struct tpm_cmd_t {
ssize_t
tpm_getcap
(
struct
device
*
,
__be32
,
cap_t
*
,
const
char
*
);
extern
void
tpm_get_timeouts
(
struct
tpm_chip
*
);
extern
int
tpm_get_timeouts
(
struct
tpm_chip
*
);
extern
void
tpm_gen_interrupt
(
struct
tpm_chip
*
);
extern
void
tpm_continue
_selftest
(
struct
tpm_chip
*
);
extern
int
tpm_do
_selftest
(
struct
tpm_chip
*
);
extern
unsigned
long
tpm_calc_ordinal_duration
(
struct
tpm_chip
*
,
u32
);
extern
struct
tpm_chip
*
tpm_register_hardware
(
struct
device
*
,
const
struct
tpm_vendor_specific
*
);
...
...
@@ -294,7 +296,8 @@ extern ssize_t tpm_read(struct file *, char __user *, size_t, loff_t *);
extern
void
tpm_remove_hardware
(
struct
device
*
);
extern
int
tpm_pm_suspend
(
struct
device
*
,
pm_message_t
);
extern
int
tpm_pm_resume
(
struct
device
*
);
extern
int
wait_for_tpm_stat
(
struct
tpm_chip
*
,
u8
,
unsigned
long
,
wait_queue_head_t
*
);
#ifdef CONFIG_ACPI
extern
struct
dentry
**
tpm_bios_log_setup
(
char
*
);
extern
void
tpm_bios_log_teardown
(
struct
dentry
**
);
...
...
drivers/char/tpm/tpm_tis.c
浏览文件 @
8077e8b0
...
...
@@ -29,8 +29,6 @@
#include <linux/freezer.h>
#include "tpm.h"
#define TPM_HEADER_SIZE 10
enum
tis_access
{
TPM_ACCESS_VALID
=
0x80
,
TPM_ACCESS_ACTIVE_LOCALITY
=
0x20
,
...
...
@@ -193,54 +191,14 @@ static int get_burstcount(struct tpm_chip *chip)
return
-
EBUSY
;
}
static
int
wait_for_stat
(
struct
tpm_chip
*
chip
,
u8
mask
,
unsigned
long
timeout
,
wait_queue_head_t
*
queue
)
{
unsigned
long
stop
;
long
rc
;
u8
status
;
/* check current status */
status
=
tpm_tis_status
(
chip
);
if
((
status
&
mask
)
==
mask
)
return
0
;
stop
=
jiffies
+
timeout
;
if
(
chip
->
vendor
.
irq
)
{
again:
timeout
=
stop
-
jiffies
;
if
((
long
)
timeout
<=
0
)
return
-
ETIME
;
rc
=
wait_event_interruptible_timeout
(
*
queue
,
((
tpm_tis_status
(
chip
)
&
mask
)
==
mask
),
timeout
);
if
(
rc
>
0
)
return
0
;
if
(
rc
==
-
ERESTARTSYS
&&
freezing
(
current
))
{
clear_thread_flag
(
TIF_SIGPENDING
);
goto
again
;
}
}
else
{
do
{
msleep
(
TPM_TIMEOUT
);
status
=
tpm_tis_status
(
chip
);
if
((
status
&
mask
)
==
mask
)
return
0
;
}
while
(
time_before
(
jiffies
,
stop
));
}
return
-
ETIME
;
}
static
int
recv_data
(
struct
tpm_chip
*
chip
,
u8
*
buf
,
size_t
count
)
{
int
size
=
0
,
burstcnt
;
while
(
size
<
count
&&
wait_for_stat
(
chip
,
TPM_STS_DATA_AVAIL
|
TPM_STS_VALID
,
chip
->
vendor
.
timeout_c
,
&
chip
->
vendor
.
read_queue
)
wait_for_
tpm_
stat
(
chip
,
TPM_STS_DATA_AVAIL
|
TPM_STS_VALID
,
chip
->
vendor
.
timeout_c
,
&
chip
->
vendor
.
read_queue
)
==
0
)
{
burstcnt
=
get_burstcount
(
chip
);
for
(;
burstcnt
>
0
&&
size
<
count
;
burstcnt
--
)
...
...
@@ -282,8 +240,8 @@ static int tpm_tis_recv(struct tpm_chip *chip, u8 *buf, size_t count)
goto
out
;
}
wait_for_stat
(
chip
,
TPM_STS_VALID
,
chip
->
vendor
.
timeout_c
,
&
chip
->
vendor
.
int_queue
);
wait_for_
tpm_
stat
(
chip
,
TPM_STS_VALID
,
chip
->
vendor
.
timeout_c
,
&
chip
->
vendor
.
int_queue
);
status
=
tpm_tis_status
(
chip
);
if
(
status
&
TPM_STS_DATA_AVAIL
)
{
/* retry? */
dev_err
(
chip
->
dev
,
"Error left over data
\n
"
);
...
...
@@ -317,7 +275,7 @@ static int tpm_tis_send_data(struct tpm_chip *chip, u8 *buf, size_t len)
status
=
tpm_tis_status
(
chip
);
if
((
status
&
TPM_STS_COMMAND_READY
)
==
0
)
{
tpm_tis_ready
(
chip
);
if
(
wait_for_stat
if
(
wait_for_
tpm_
stat
(
chip
,
TPM_STS_COMMAND_READY
,
chip
->
vendor
.
timeout_b
,
&
chip
->
vendor
.
int_queue
)
<
0
)
{
rc
=
-
ETIME
;
...
...
@@ -333,8 +291,8 @@ static int tpm_tis_send_data(struct tpm_chip *chip, u8 *buf, size_t len)
count
++
;
}
wait_for_stat
(
chip
,
TPM_STS_VALID
,
chip
->
vendor
.
timeout_c
,
&
chip
->
vendor
.
int_queue
);
wait_for_
tpm_
stat
(
chip
,
TPM_STS_VALID
,
chip
->
vendor
.
timeout_c
,
&
chip
->
vendor
.
int_queue
);
status
=
tpm_tis_status
(
chip
);
if
(
!
itpm
&&
(
status
&
TPM_STS_DATA_EXPECT
)
==
0
)
{
rc
=
-
EIO
;
...
...
@@ -345,8 +303,8 @@ static int tpm_tis_send_data(struct tpm_chip *chip, u8 *buf, size_t len)
/* write last byte */
iowrite8
(
buf
[
count
],
chip
->
vendor
.
iobase
+
TPM_DATA_FIFO
(
chip
->
vendor
.
locality
));
wait_for_stat
(
chip
,
TPM_STS_VALID
,
chip
->
vendor
.
timeout_c
,
&
chip
->
vendor
.
int_queue
);
wait_for_
tpm_
stat
(
chip
,
TPM_STS_VALID
,
chip
->
vendor
.
timeout_c
,
&
chip
->
vendor
.
int_queue
);
status
=
tpm_tis_status
(
chip
);
if
((
status
&
TPM_STS_DATA_EXPECT
)
!=
0
)
{
rc
=
-
EIO
;
...
...
@@ -381,7 +339,7 @@ static int tpm_tis_send(struct tpm_chip *chip, u8 *buf, size_t len)
if
(
chip
->
vendor
.
irq
)
{
ordinal
=
be32_to_cpu
(
*
((
__be32
*
)
(
buf
+
6
)));
if
(
wait_for_stat
if
(
wait_for_
tpm_
stat
(
chip
,
TPM_STS_DATA_AVAIL
|
TPM_STS_VALID
,
tpm_calc_ordinal_duration
(
chip
,
ordinal
),
&
chip
->
vendor
.
read_queue
)
<
0
)
{
...
...
@@ -432,6 +390,9 @@ static int probe_itpm(struct tpm_chip *chip)
out:
itpm
=
rem_itpm
;
tpm_tis_ready
(
chip
);
/* some TPMs need a break here otherwise they will not work
* correctly on the immediately subsequent command */
msleep
(
chip
->
vendor
.
timeout_b
);
release_locality
(
chip
,
chip
->
vendor
.
locality
,
0
);
return
rc
;
...
...
@@ -614,7 +575,17 @@ static int tpm_tis_init(struct device *dev, resource_size_t start,
dev_dbg
(
dev
,
"
\t
Data Avail Int Support
\n
"
);
/* get the timeouts before testing for irqs */
tpm_get_timeouts
(
chip
);
if
(
tpm_get_timeouts
(
chip
))
{
dev_err
(
dev
,
"Could not get TPM timeouts and durations
\n
"
);
rc
=
-
ENODEV
;
goto
out_err
;
}
if
(
tpm_do_selftest
(
chip
))
{
dev_err
(
dev
,
"TPM self test failed
\n
"
);
rc
=
-
ENODEV
;
goto
out_err
;
}
/* INTERRUPT Setup */
init_waitqueue_head
(
&
chip
->
vendor
.
read_queue
);
...
...
@@ -722,7 +693,6 @@ static int tpm_tis_init(struct device *dev, resource_size_t start,
list_add
(
&
chip
->
vendor
.
list
,
&
tis_chips
);
spin_unlock
(
&
tis_lock
);
tpm_continue_selftest
(
chip
);
return
0
;
out_err:
...
...
@@ -790,7 +760,7 @@ static int tpm_tis_pnp_resume(struct pnp_dev *dev)
ret
=
tpm_pm_resume
(
&
dev
->
dev
);
if
(
!
ret
)
tpm_
continue
_selftest
(
chip
);
tpm_
do
_selftest
(
chip
);
return
ret
;
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录