arch/powerpc/platforms/pseries/papr-phy-attest.c

Source file repositories/reference/linux-study-clean/arch/powerpc/platforms/pseries/papr-phy-attest.c

File Facts

System
Linux kernel
Corpus path
arch/powerpc/platforms/pseries/papr-phy-attest.c
Extension
.c
Size
8398 bytes
Lines
289
Domain
Architecture Layer
Bucket
arch/powerpc
Inferred role
Architecture Layer: operation-table or driver-model contract
Status
pattern implementation candidate

Why This File Exists

CPU and platform-specific kernel glue: boot entry, traps, syscall entry, interrupts, page tables, context switch, and low-level barriers.

Dependency Surface

Detected Declarations

Annotated Snippet

static const struct file_operations papr_phy_attest_handle_ops = {
	.read = papr_rtas_common_handle_read,
	.llseek = papr_rtas_common_handle_seek,
	.release = papr_rtas_common_handle_release,
};

/**
 * papr_phy_attest_create_handle() - Create a fd-based handle for
 * reading the response for the given attestation command.
 * @ulc: Attestation command in user memory; defines the scope of
 *       data for the attestation command to retrieve.
 *
 * Handler for PAPR_PHYSICAL_ATTESTATION_IOC_CREATE_HANDLE ioctl
 * command. Validates @ulc and instantiates an immutable response
 * "blob" for attestation command. The blob is attached to a file
 * descriptor for reading by user space. The memory backing the blob
 * is freed when the file is released.
 *
 * The entire requested response buffer for the attestation command
 * retrieved by this call and all necessary RTAS interactions are
 * performed before returning the fd to user space. This keeps the
 * read handler simple and ensures that kernel can prevent
 * interleaving ibm,physical-attestation call sequences.
 *
 * Return: The installed fd number if successful, -ve errno otherwise.
 */
static long papr_phy_attest_create_handle(struct papr_phy_attest_io_block __user *ulc)
{
	struct rtas_phy_attest_params *params;
	struct papr_rtas_sequence seq = {};
	int fd;

	/*
	 * Freed in phy_attest_sequence_end().
	 */
	params = kzalloc_obj(*params, GFP_KERNEL_ACCOUNT);
	if (!params)
		return -ENOMEM;

	if (copy_from_user(&params->cmd, ulc,
			sizeof(struct papr_phy_attest_io_block)))
		return -EFAULT;

	params->cmd_len = be32_to_cpu(params->cmd.length);
	seq = (struct papr_rtas_sequence) {
		.begin = phy_attest_sequence_begin,
		.end = phy_attest_sequence_end,
		.work = phy_attest_sequence_fill_work_area,
	};

	seq.params = (void *)params;

	fd = papr_rtas_setup_file_interface(&seq,
			&papr_phy_attest_handle_ops,
			"[papr-physical-attestation]");

	return fd;
}

/*
 * Top-level ioctl handler for /dev/papr-physical-attestation.
 */
static long papr_phy_attest_dev_ioctl(struct file *filp, unsigned int ioctl, unsigned long arg)
{
	void __user *argp = (__force void __user *)arg;
	long ret;

	switch (ioctl) {
	case PAPR_PHY_ATTEST_IOC_HANDLE:
		ret = papr_phy_attest_create_handle(argp);
		break;
	default:
		ret = -ENOIOCTLCMD;
		break;
	}
	return ret;
}

static const struct file_operations papr_phy_attest_ops = {
	.unlocked_ioctl = papr_phy_attest_dev_ioctl,
};

static struct miscdevice papr_phy_attest_dev = {
	.minor = MISC_DYNAMIC_MINOR,
	.name = "papr-physical-attestation",
	.fops = &papr_phy_attest_ops,
};

static __init int papr_phy_attest_init(void)
{

Annotation

Implementation Notes