drivers/char/tpm/tpm2-space.c
Source file repositories/reference/linux-study-clean/drivers/char/tpm/tpm2-space.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/char/tpm/tpm2-space.c- Extension
.c- Size
- 14933 bytes
- Lines
- 648
- Domain
- Driver Families
- Bucket
- drivers/char
- Inferred role
- Driver Families: implementation source
- Status
- source implementation candidate
Why This File Exists
Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/gfp.hlinux/unaligned.htpm.h
Detected Declarations
struct tpm2_contextstruct tpm2_cap_handlesenum tpm2_handle_typesfunction tpm2_flush_sessionsfunction tpm2_init_spacefunction tpm2_del_spacefunction tpm2_load_contextfunction tpm2_save_contextfunction tpm2_flush_spacefunction tpm2_load_spacefunction tpm2_map_to_phandlefunction tpm2_map_commandfunction tpm_find_and_validate_ccfunction tpm2_prepare_spacefunction tpm2_add_sessionfunction tpm2_map_to_vhandlefunction tpm2_map_response_headerfunction tpm2_map_response_bodyfunction tpm2_save_spacefunction tpm2_commit_spacefunction tpm_devs_releasefunction tpm_devs_removefunction tpm_devs_add
Annotated Snippet
struct tpm2_context {
__be64 sequence;
__be32 saved_handle;
__be32 hierarchy;
__be16 blob_size;
} __packed;
static void tpm2_flush_sessions(struct tpm_chip *chip, struct tpm_space *space)
{
int i;
for (i = 0; i < ARRAY_SIZE(space->session_tbl); i++) {
if (space->session_tbl[i])
tpm2_flush_context(chip, space->session_tbl[i]);
}
}
int tpm2_init_space(struct tpm_space *space, unsigned int buf_size)
{
space->context_buf = kzalloc(buf_size, GFP_KERNEL);
if (!space->context_buf)
return -ENOMEM;
space->session_buf = kzalloc(buf_size, GFP_KERNEL);
if (space->session_buf == NULL) {
kfree(space->context_buf);
/* Prevent caller getting a dangling pointer. */
space->context_buf = NULL;
return -ENOMEM;
}
space->buf_size = buf_size;
return 0;
}
void tpm2_del_space(struct tpm_chip *chip, struct tpm_space *space)
{
if (tpm_try_get_ops(chip) == 0) {
tpm2_flush_sessions(chip, space);
tpm_put_ops(chip);
}
kfree(space->context_buf);
kfree(space->session_buf);
}
int tpm2_load_context(struct tpm_chip *chip, u8 *buf,
unsigned int *offset, u32 *handle)
{
struct tpm_buf tbuf;
struct tpm2_context *ctx;
unsigned int body_size;
int rc;
rc = tpm_buf_init(&tbuf, TPM2_ST_NO_SESSIONS, TPM2_CC_CONTEXT_LOAD);
if (rc)
return rc;
ctx = (struct tpm2_context *)&buf[*offset];
body_size = sizeof(*ctx) + be16_to_cpu(ctx->blob_size);
tpm_buf_append(&tbuf, &buf[*offset], body_size);
rc = tpm_transmit_cmd(chip, &tbuf, 4, NULL);
if (rc < 0) {
dev_warn(&chip->dev, "%s: failed with a system error %d\n",
__func__, rc);
tpm_buf_destroy(&tbuf);
return -EFAULT;
} else if (tpm2_rc_value(rc) == TPM2_RC_HANDLE ||
rc == TPM2_RC_REFERENCE_H0) {
/*
* TPM_RC_HANDLE means that the session context can't
* be loaded because of an internal counter mismatch
* that makes the TPM think there might have been a
* replay. This might happen if the context was saved
* and loaded outside the space.
*
* TPM_RC_REFERENCE_H0 means the session has been
* flushed outside the space
*/
*handle = 0;
tpm_buf_destroy(&tbuf);
return -ENOENT;
} else if (tpm2_rc_value(rc) == TPM2_RC_INTEGRITY) {
tpm_buf_destroy(&tbuf);
return -EINVAL;
} else if (rc > 0) {
dev_warn(&chip->dev, "%s: failed with a TPM error 0x%04X\n",
__func__, rc);
Annotation
- Immediate include surface: `linux/gfp.h`, `linux/unaligned.h`, `tpm.h`.
- Detected declarations: `struct tpm2_context`, `struct tpm2_cap_handles`, `enum tpm2_handle_types`, `function tpm2_flush_sessions`, `function tpm2_init_space`, `function tpm2_del_space`, `function tpm2_load_context`, `function tpm2_save_context`, `function tpm2_flush_space`, `function tpm2_load_space`.
- Atlas domain: Driver Families / drivers/char.
- Implementation status: source implementation candidate.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.