drivers/xen/privcmd.c

Source file repositories/reference/linux-study-clean/drivers/xen/privcmd.c

File Facts

System
Linux kernel
Corpus path
drivers/xen/privcmd.c
Extension
.c
Size
41631 bytes
Lines
1786
Domain
Driver Families
Bucket
drivers/xen
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

const struct file_operations xen_privcmd_fops = {
	.owner = THIS_MODULE,
	.unlocked_ioctl = privcmd_ioctl,
	.open = privcmd_open,
	.release = privcmd_release,
	.mmap = privcmd_mmap,
};
EXPORT_SYMBOL_GPL(xen_privcmd_fops);

static struct miscdevice privcmd_dev = {
	.minor = MISC_DYNAMIC_MINOR,
	.name = "xen/privcmd",
	.fops = &xen_privcmd_fops,
};

static int init_restrict(struct notifier_block *notifier,
			 unsigned long event,
			 void *data)
{
	char *target;
	unsigned int domid;

	/* Default to an guaranteed unused domain-id. */
	target_domain = DOMID_IDLE;

	target = xenbus_read(XBT_NIL, "target", "", NULL);
	if (IS_ERR(target) || kstrtouint(target, 10, &domid)) {
		pr_err("No target domain found, blocking all hypercalls\n");
		goto out;
	}

	target_domain = domid;

 out:
	if (!IS_ERR(target))
		kfree(target);

	restrict_wait = false;
	wake_up_all(&restrict_wait_wq);

	return NOTIFY_DONE;
}

static struct notifier_block xenstore_notifier = {
	.notifier_call = init_restrict,
};

static void __init restrict_driver(void)
{
	if (unrestricted) {
		if (security_locked_down(LOCKDOWN_XEN_USER_ACTIONS))
			pr_warn("Kernel is locked down, parameter \"unrestricted\" ignored\n");
		else
			return;
	}

	restrict_wait = true;

	register_xenstore_notifier(&xenstore_notifier);
}

static int __init privcmd_init(void)
{
	int err;

	if (!xen_domain())
		return -ENODEV;

	if (!xen_initial_domain())
		restrict_driver();

	err = misc_register(&privcmd_dev);
	if (err != 0) {
		pr_err("Could not register Xen privcmd device\n");
		return err;
	}

	err = misc_register(&xen_privcmdbuf_dev);
	if (err != 0) {
		pr_err("Could not register Xen hypercall-buf device\n");
		goto err_privcmdbuf;
	}

	err = privcmd_irqfd_init();
	if (err != 0) {
		pr_err("irqfd init failed\n");
		goto err_irqfd;
	}

	return 0;

Annotation

Implementation Notes