mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2025-01-04 04:06:26 +00: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.
|
||||
*/
|
||||
|
||||
#include <linux/acpi.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/acpi.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/random.h>
|
||||
|
||||
ACPI_MODULE_NAME("vmgenid");
|
||||
@ -21,19 +22,41 @@ struct vmgenid_state {
|
||||
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 vmgenid_state *state;
|
||||
union acpi_object *obj;
|
||||
phys_addr_t phys_addr;
|
||||
acpi_status status;
|
||||
void *virt_addr;
|
||||
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);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
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) |
|
||||
(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)) {
|
||||
ret = PTR_ERR(state->next_id);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
memcpy(state->this_id, state->next_id, sizeof(state->this_id));
|
||||
add_device_randomness(state->this_id, sizeof(state->this_id));
|
||||
|
||||
device->driver_data = state;
|
||||
|
||||
dev->driver_data = state;
|
||||
out:
|
||||
ACPI_FREE(parsed.pointer);
|
||||
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);
|
||||
u8 old_id[VMGENID_SIZE];
|
||||
struct device *dev = &pdev->dev;
|
||||
struct vmgenid_state *state;
|
||||
int ret;
|
||||
|
||||
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));
|
||||
state = devm_kmalloc(dev, sizeof(*state), GFP_KERNEL);
|
||||
if (!state)
|
||||
return -ENOMEM;
|
||||
|
||||
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 },
|
||||
{ "VM_GEN_COUNTER", 0 },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(acpi, vmgenid_acpi_ids);
|
||||
|
||||
static struct acpi_driver vmgenid_driver = {
|
||||
.name = "vmgenid",
|
||||
.ids = vmgenid_ids,
|
||||
.owner = THIS_MODULE,
|
||||
.ops = {
|
||||
.add = vmgenid_add,
|
||||
.notify = vmgenid_notify
|
||||
}
|
||||
static struct platform_driver vmgenid_plaform_driver = {
|
||||
.probe = vmgenid_add,
|
||||
.driver = {
|
||||
.name = "vmgenid",
|
||||
.acpi_match_table = vmgenid_acpi_ids,
|
||||
},
|
||||
};
|
||||
|
||||
module_acpi_driver(vmgenid_driver);
|
||||
module_platform_driver(vmgenid_plaform_driver)
|
||||
|
||||
MODULE_DEVICE_TABLE(acpi, vmgenid_ids);
|
||||
MODULE_DESCRIPTION("Virtual Machine Generation ID");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
MODULE_AUTHOR("Jason A. Donenfeld <Jason@zx2c4.com>");
|
||||
|
Loading…
Reference in New Issue
Block a user