mirror of
https://github.com/torvalds/linux.git
synced 2026-11-07 06:17:02 +01:00
virt: vmgenid: change implementation to use a platform driver
Re-implement vmgenid as a platform driver in preparation for adding devicetree bindings support in next commits. Signed-off-by: Sudan Landge <sudanl@amazon.com> Reviewed-by: Alexander Graf <graf@amazon.com> Tested-by: Babis Chalios <bchalios@amazon.es> [Jason: - Small style cleanups and refactoring.] Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
This commit is contained in:
parent
5eb4573ea6
commit
e07606713a
|
|
@ -7,9 +7,10 @@
|
||||||
* information to random.c.
|
* information to random.c.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <linux/acpi.h>
|
||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
#include <linux/acpi.h>
|
#include <linux/platform_device.h>
|
||||||
#include <linux/random.h>
|
#include <linux/random.h>
|
||||||
|
|
||||||
ACPI_MODULE_NAME("vmgenid");
|
ACPI_MODULE_NAME("vmgenid");
|
||||||
|
|
@ -21,19 +22,41 @@ struct vmgenid_state {
|
||||||
u8 this_id[VMGENID_SIZE];
|
u8 this_id[VMGENID_SIZE];
|
||||||
};
|
};
|
||||||
|
|
||||||
static int vmgenid_add(struct acpi_device *device)
|
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));
|
||||||
|
}
|
||||||
|
|
||||||
|
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 };
|
struct acpi_buffer parsed = { ACPI_ALLOCATE_BUFFER };
|
||||||
struct vmgenid_state *state;
|
|
||||||
union acpi_object *obj;
|
union acpi_object *obj;
|
||||||
phys_addr_t phys_addr;
|
phys_addr_t phys_addr;
|
||||||
acpi_status status;
|
acpi_status status;
|
||||||
|
void *virt_addr;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
state = devm_kmalloc(&device->dev, sizeof(*state), GFP_KERNEL);
|
|
||||||
if (!state)
|
|
||||||
return -ENOMEM;
|
|
||||||
|
|
||||||
status = acpi_evaluate_object(device->handle, "ADDR", NULL, &parsed);
|
status = acpi_evaluate_object(device->handle, "ADDR", NULL, &parsed);
|
||||||
if (ACPI_FAILURE(status)) {
|
if (ACPI_FAILURE(status)) {
|
||||||
ACPI_EXCEPTION((AE_INFO, status, "Evaluating ADDR"));
|
ACPI_EXCEPTION((AE_INFO, status, "Evaluating ADDR"));
|
||||||
|
|
@ -49,53 +72,61 @@ static int vmgenid_add(struct acpi_device *device)
|
||||||
|
|
||||||
phys_addr = (obj->package.elements[0].integer.value << 0) |
|
phys_addr = (obj->package.elements[0].integer.value << 0) |
|
||||||
(obj->package.elements[1].integer.value << 32);
|
(obj->package.elements[1].integer.value << 32);
|
||||||
state->next_id = devm_memremap(&device->dev, phys_addr, VMGENID_SIZE, MEMREMAP_WB);
|
|
||||||
if (IS_ERR(state->next_id)) {
|
virt_addr = devm_memremap(&device->dev, phys_addr, VMGENID_SIZE, MEMREMAP_WB);
|
||||||
ret = PTR_ERR(state->next_id);
|
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;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(state->this_id, state->next_id, sizeof(state->this_id));
|
dev->driver_data = state;
|
||||||
add_device_randomness(state->this_id, sizeof(state->this_id));
|
|
||||||
|
|
||||||
device->driver_data = state;
|
|
||||||
|
|
||||||
out:
|
out:
|
||||||
ACPI_FREE(parsed.pointer);
|
ACPI_FREE(parsed.pointer);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void vmgenid_notify(struct acpi_device *device, u32 event)
|
static int vmgenid_add(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
struct vmgenid_state *state = acpi_driver_data(device);
|
struct device *dev = &pdev->dev;
|
||||||
u8 old_id[VMGENID_SIZE];
|
struct vmgenid_state *state;
|
||||||
|
int ret;
|
||||||
|
|
||||||
memcpy(old_id, state->this_id, sizeof(old_id));
|
state = devm_kmalloc(dev, sizeof(*state), GFP_KERNEL);
|
||||||
memcpy(state->this_id, state->next_id, sizeof(state->this_id));
|
if (!state)
|
||||||
if (!memcmp(old_id, state->this_id, sizeof(old_id)))
|
return -ENOMEM;
|
||||||
return;
|
|
||||||
add_vmfork_randomness(state->this_id, sizeof(state->this_id));
|
ret = vmgenid_add_acpi(dev, state);
|
||||||
|
|
||||||
|
if (ret < 0)
|
||||||
|
devm_kfree(dev, state);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct acpi_device_id vmgenid_ids[] = {
|
static const struct acpi_device_id vmgenid_acpi_ids[] = {
|
||||||
{ "VMGENCTR", 0 },
|
{ "VMGENCTR", 0 },
|
||||||
{ "VM_GEN_COUNTER", 0 },
|
{ "VM_GEN_COUNTER", 0 },
|
||||||
{ }
|
{ }
|
||||||
};
|
};
|
||||||
|
MODULE_DEVICE_TABLE(acpi, vmgenid_acpi_ids);
|
||||||
|
|
||||||
static struct acpi_driver vmgenid_driver = {
|
static struct platform_driver vmgenid_plaform_driver = {
|
||||||
.name = "vmgenid",
|
.probe = vmgenid_add,
|
||||||
.ids = vmgenid_ids,
|
.driver = {
|
||||||
.owner = THIS_MODULE,
|
.name = "vmgenid",
|
||||||
.ops = {
|
.acpi_match_table = vmgenid_acpi_ids,
|
||||||
.add = vmgenid_add,
|
},
|
||||||
.notify = vmgenid_notify
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
module_acpi_driver(vmgenid_driver);
|
module_platform_driver(vmgenid_plaform_driver)
|
||||||
|
|
||||||
MODULE_DEVICE_TABLE(acpi, vmgenid_ids);
|
|
||||||
MODULE_DESCRIPTION("Virtual Machine Generation ID");
|
MODULE_DESCRIPTION("Virtual Machine Generation ID");
|
||||||
MODULE_LICENSE("GPL v2");
|
MODULE_LICENSE("GPL v2");
|
||||||
MODULE_AUTHOR("Jason A. Donenfeld <Jason@zx2c4.com>");
|
MODULE_AUTHOR("Jason A. Donenfeld <Jason@zx2c4.com>");
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user