drivers/crypto/ccp/sfs.c

Source file repositories/reference/linux-study-clean/drivers/crypto/ccp/sfs.c

File Facts

System
Linux kernel
Corpus path
drivers/crypto/ccp/sfs.c
Extension
.c
Size
8073 bytes
Lines
312
Domain
Driver Families
Bucket
drivers/crypto
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.

Dependency Surface

Detected Declarations

Annotated Snippet

static const struct file_operations sfs_fops = {
	.owner	= THIS_MODULE,
	.unlocked_ioctl = sfs_ioctl,
};

static void sfs_exit(struct kref *ref)
{
	misc_deregister(&misc_dev->misc);
	kfree(misc_dev);
	misc_dev = NULL;
}

void sfs_dev_destroy(struct psp_device *psp)
{
	struct sfs_device *sfs_dev = psp->sfs_data;

	if (!sfs_dev)
		return;

	/*
	 * Change SFS command buffer back to the default "Write-Back" type.
	 */
	set_memory_wb((unsigned long)sfs_dev->command_buf, SFS_NUM_PAGES_CMDBUF);

	snp_free_hv_fixed_pages(sfs_dev->page);

	if (sfs_dev->misc)
		kref_put(&misc_dev->refcount, sfs_exit);

	psp->sfs_data = NULL;
}

/* Based on sev_misc_init() */
static int sfs_misc_init(struct sfs_device *sfs)
{
	struct device *dev = sfs->dev;
	int ret;

	/*
	 * SFS feature support can be detected on multiple devices but the SFS
	 * FW commands must be issued on the master. During probe, we do not
	 * know the master hence we create /dev/sfs on the first device probe.
	 */
	if (!misc_dev) {
		struct miscdevice *misc;

		misc_dev = kzalloc_obj(*misc_dev);
		if (!misc_dev)
			return -ENOMEM;

		misc = &misc_dev->misc;
		misc->minor = MISC_DYNAMIC_MINOR;
		misc->name = "sfs";
		misc->fops = &sfs_fops;
		misc->mode = 0600;

		ret = misc_register(misc);
		if (ret)
			return ret;

		kref_init(&misc_dev->refcount);
	} else {
		kref_get(&misc_dev->refcount);
	}

	sfs->misc = misc_dev;
	dev_dbg(dev, "registered SFS device\n");

	return 0;
}

int sfs_dev_init(struct psp_device *psp)
{
	struct device *dev = psp->dev;
	struct sfs_device *sfs_dev;
	struct page *page;
	int ret = -ENOMEM;

	sfs_dev = devm_kzalloc(dev, sizeof(*sfs_dev), GFP_KERNEL);
	if (!sfs_dev)
		return -ENOMEM;

	/*
	 * Pre-allocate 2MB command buffer for all SFS commands using
	 * SNP HV_Fixed page allocator which also transitions the
	 * SFS command buffer to HV_Fixed page state if SNP is enabled.
	 */
	page = snp_alloc_hv_fixed_pages(SFS_NUM_2MB_PAGES_CMDBUF);
	if (!page) {
		dev_dbg(dev, "Command Buffer HV-Fixed page allocation failed\n");

Annotation

Implementation Notes