drivers/virt/vmgenid.c

Source file repositories/reference/linux-study-clean/drivers/virt/vmgenid.c

File Facts

System
Linux kernel
Corpus path
drivers/virt/vmgenid.c
Extension
.c
Size
4498 bytes
Lines
182
Domain
Driver Families
Bucket
drivers/virt
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.

Dependency Surface

Detected Declarations

Annotated Snippet

struct vmgenid_state {
	u8 *next_id;
	u8 this_id[VMGENID_SIZE];
};

static void vmgenid_notify(struct device *device)
{
	struct vmgenid_state *state = device->driver_data;
	u8 old_id[VMGENID_SIZE];

	memcpy(old_id, state->this_id, sizeof(old_id));
	memcpy(state->this_id, state->next_id, sizeof(state->this_id));
	if (!memcmp(old_id, state->this_id, sizeof(old_id)))
		return;
	add_vmfork_randomness(state->this_id, sizeof(state->this_id));
}

static void setup_vmgenid_state(struct vmgenid_state *state, void *virt_addr)
{
	state->next_id = virt_addr;
	memcpy(state->this_id, state->next_id, sizeof(state->this_id));
	add_device_randomness(state->this_id, sizeof(state->this_id));
}

#ifdef CONFIG_ACPI
static void vmgenid_acpi_handler(acpi_handle __always_unused handle,
				 u32 __always_unused event, void *dev)
{
	vmgenid_notify(dev);
}

static int vmgenid_add_acpi(struct device *dev, struct vmgenid_state *state)
{
	struct acpi_device *device = ACPI_COMPANION(dev);
	struct acpi_buffer parsed = { ACPI_ALLOCATE_BUFFER };
	union acpi_object *obj;
	phys_addr_t phys_addr;
	acpi_status status;
	void *virt_addr;
	int ret = 0;

	status = acpi_evaluate_object(device->handle, "ADDR", NULL, &parsed);
	if (ACPI_FAILURE(status)) {
		ACPI_EXCEPTION((AE_INFO, status, "Evaluating ADDR"));
		return -ENODEV;
	}
	obj = parsed.pointer;
	if (!obj || obj->type != ACPI_TYPE_PACKAGE || obj->package.count != 2 ||
	    obj->package.elements[0].type != ACPI_TYPE_INTEGER ||
	    obj->package.elements[1].type != ACPI_TYPE_INTEGER) {
		ret = -EINVAL;
		goto out;
	}

	phys_addr = (obj->package.elements[0].integer.value << 0) |
		    (obj->package.elements[1].integer.value << 32);

	virt_addr = devm_memremap(&device->dev, phys_addr, VMGENID_SIZE, MEMREMAP_WB);
	if (IS_ERR(virt_addr)) {
		ret = PTR_ERR(virt_addr);
		goto out;
	}
	setup_vmgenid_state(state, virt_addr);

	status = acpi_install_notify_handler(device->handle, ACPI_DEVICE_NOTIFY,
					     vmgenid_acpi_handler, dev);
	if (ACPI_FAILURE(status)) {
		ret = -ENODEV;
		goto out;
	}

	dev->driver_data = state;
out:
	ACPI_FREE(parsed.pointer);
	return ret;
}
#else
static int vmgenid_add_acpi(struct device *dev, struct vmgenid_state *state)
{
	return -EINVAL;
}
#endif

static irqreturn_t vmgenid_of_irq_handler(int __always_unused irq, void *dev)
{
	vmgenid_notify(dev);
	return IRQ_HANDLED;
}

static int vmgenid_add_of(struct platform_device *pdev,

Annotation

Implementation Notes