drivers/char/tpm/tpm_vtpm_proxy.c
Source file repositories/reference/linux-study-clean/drivers/char/tpm/tpm_vtpm_proxy.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/char/tpm/tpm_vtpm_proxy.c- Extension
.c- Size
- 16350 bytes
- Lines
- 719
- Domain
- Driver Families
- Bucket
- drivers/char
- Inferred role
- Driver Families: operation-table or driver-model contract
- Status
- pattern 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.
- Defines an operation table; this is where Linux turns generic core objects into subsystem-specific behavior.
- Touches user memory; correctness depends on fault-safe copying and privilege boundary handling.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- 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/types.hlinux/spinlock.hlinux/uaccess.hlinux/wait.hlinux/miscdevice.hlinux/vtpm_proxy.hlinux/file.hlinux/anon_inodes.hlinux/poll.hlinux/compat.htpm.h
Detected Declarations
struct proxy_devfunction vtpm_proxy_fops_readfunction vtpm_proxy_fops_writefunction vtpm_proxy_fops_pollfunction vtpm_proxy_fops_openfunction vtpm_proxy_fops_undo_openfunction vtpm_proxy_fops_releasefunction vtpm_proxy_tpm_op_recvfunction vtpm_proxy_is_driver_commandfunction vtpm_proxy_tpm_op_sendfunction vtpm_proxy_tpm_op_cancelfunction vtpm_proxy_tpm_req_canceledfunction vtpm_proxy_request_localityfunction vtpm_proxy_workfunction vtpm_proxy_work_stopfunction vtpm_proxy_work_startfunction vtpm_proxy_delete_proxy_devfunction vtpm_proxy_delete_devicefunction vtpmx_ioc_new_devfunction vtpmx_fops_ioctlfunction vtpm_module_initfunction vtpm_module_exitmodule init vtpm_module_init
Annotated Snippet
static const struct file_operations vtpm_proxy_fops = {
.owner = THIS_MODULE,
.read = vtpm_proxy_fops_read,
.write = vtpm_proxy_fops_write,
.poll = vtpm_proxy_fops_poll,
.release = vtpm_proxy_fops_release,
};
/*
* Functions invoked by the core TPM driver to send TPM commands to
* 'server side' and receive responses from there.
*/
/*
* Called when core TPM driver reads TPM responses from 'server side'
*
* @chip: tpm chip to use
* @buf: receive buffer
* @count: bytes to read
* Return:
* Number of TPM response bytes read, negative error value otherwise
*/
static int vtpm_proxy_tpm_op_recv(struct tpm_chip *chip, u8 *buf, size_t count)
{
struct proxy_dev *proxy_dev = dev_get_drvdata(&chip->dev);
size_t len;
/* process gone ? */
mutex_lock(&proxy_dev->buf_lock);
if (!(proxy_dev->state & STATE_OPENED_FLAG)) {
mutex_unlock(&proxy_dev->buf_lock);
return -EPIPE;
}
len = proxy_dev->resp_len;
if (count < len) {
dev_err(&chip->dev,
"Invalid size in recv: count=%zd, resp_len=%zd\n",
count, len);
len = -EIO;
goto out;
}
memcpy(buf, proxy_dev->buffer, len);
proxy_dev->resp_len = 0;
out:
mutex_unlock(&proxy_dev->buf_lock);
return len;
}
static int vtpm_proxy_is_driver_command(struct tpm_chip *chip,
u8 *buf, size_t count)
{
struct tpm_header *hdr = (struct tpm_header *)buf;
if (count < sizeof(struct tpm_header))
return 0;
if (chip->flags & TPM_CHIP_FLAG_TPM2) {
switch (be32_to_cpu(hdr->ordinal)) {
case TPM2_CC_SET_LOCALITY:
return 1;
}
} else {
switch (be32_to_cpu(hdr->ordinal)) {
case TPM_ORD_SET_LOCALITY:
return 1;
}
}
return 0;
}
/*
* Called when core TPM driver forwards TPM requests to 'server side'.
*
* @chip: tpm chip to use
* @buf: send buffer
* @bufsiz: size of the buffer
* @count: bytes to send
*
* Return:
* 0 in case of success, negative error value otherwise.
*/
static int vtpm_proxy_tpm_op_send(struct tpm_chip *chip, u8 *buf, size_t bufsiz,
size_t count)
{
struct proxy_dev *proxy_dev = dev_get_drvdata(&chip->dev);
Annotation
- Immediate include surface: `linux/types.h`, `linux/spinlock.h`, `linux/uaccess.h`, `linux/wait.h`, `linux/miscdevice.h`, `linux/vtpm_proxy.h`, `linux/file.h`, `linux/anon_inodes.h`.
- Detected declarations: `struct proxy_dev`, `function vtpm_proxy_fops_read`, `function vtpm_proxy_fops_write`, `function vtpm_proxy_fops_poll`, `function vtpm_proxy_fops_open`, `function vtpm_proxy_fops_undo_open`, `function vtpm_proxy_fops_release`, `function vtpm_proxy_tpm_op_recv`, `function vtpm_proxy_is_driver_command`, `function vtpm_proxy_tpm_op_send`.
- Atlas domain: Driver Families / drivers/char.
- Implementation status: pattern implementation candidate.
- This snippet crosses the user/kernel memory boundary; validate fault handling and access checks before translating the pattern.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
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.