Skip to content

Commit e076067

Browse files
Sudan Landgezx2c4
authored andcommitted
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>
1 parent 5eb4573 commit e076067

File tree

1 file changed

+65
-34
lines changed

1 file changed

+65
-34
lines changed

drivers/virt/vmgenid.c

Lines changed: 65 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,10 @@
77
* information to random.c.
88
*/
99

10+
#include <linux/acpi.h>
1011
#include <linux/kernel.h>
1112
#include <linux/module.h>
12-
#include <linux/acpi.h>
13+
#include <linux/platform_device.h>
1314
#include <linux/random.h>
1415

1516
ACPI_MODULE_NAME("vmgenid");
@@ -21,19 +22,41 @@ struct vmgenid_state {
2122
u8 this_id[VMGENID_SIZE];
2223
};
2324

24-
static int vmgenid_add(struct acpi_device *device)
25+
static void vmgenid_notify(struct device *device)
26+
{
27+
struct vmgenid_state *state = device->driver_data;
28+
u8 old_id[VMGENID_SIZE];
29+
30+
memcpy(old_id, state->this_id, sizeof(old_id));
31+
memcpy(state->this_id, state->next_id, sizeof(state->this_id));
32+
if (!memcmp(old_id, state->this_id, sizeof(old_id)))
33+
return;
34+
add_vmfork_randomness(state->this_id, sizeof(state->this_id));
35+
}
36+
37+
static void setup_vmgenid_state(struct vmgenid_state *state, void *virt_addr)
2538
{
39+
state->next_id = virt_addr;
40+
memcpy(state->this_id, state->next_id, sizeof(state->this_id));
41+
add_device_randomness(state->this_id, sizeof(state->this_id));
42+
}
43+
44+
static void vmgenid_acpi_handler(acpi_handle __always_unused handle,
45+
u32 __always_unused event, void *dev)
46+
{
47+
vmgenid_notify(dev);
48+
}
49+
50+
static int vmgenid_add_acpi(struct device *dev, struct vmgenid_state *state)
51+
{
52+
struct acpi_device *device = ACPI_COMPANION(dev);
2653
struct acpi_buffer parsed = { ACPI_ALLOCATE_BUFFER };
27-
struct vmgenid_state *state;
2854
union acpi_object *obj;
2955
phys_addr_t phys_addr;
3056
acpi_status status;
57+
void *virt_addr;
3158
int ret = 0;
3259

33-
state = devm_kmalloc(&device->dev, sizeof(*state), GFP_KERNEL);
34-
if (!state)
35-
return -ENOMEM;
36-
3760
status = acpi_evaluate_object(device->handle, "ADDR", NULL, &parsed);
3861
if (ACPI_FAILURE(status)) {
3962
ACPI_EXCEPTION((AE_INFO, status, "Evaluating ADDR"));
@@ -49,53 +72,61 @@ static int vmgenid_add(struct acpi_device *device)
4972

5073
phys_addr = (obj->package.elements[0].integer.value << 0) |
5174
(obj->package.elements[1].integer.value << 32);
52-
state->next_id = devm_memremap(&device->dev, phys_addr, VMGENID_SIZE, MEMREMAP_WB);
53-
if (IS_ERR(state->next_id)) {
54-
ret = PTR_ERR(state->next_id);
75+
76+
virt_addr = devm_memremap(&device->dev, phys_addr, VMGENID_SIZE, MEMREMAP_WB);
77+
if (IS_ERR(virt_addr)) {
78+
ret = PTR_ERR(virt_addr);
5579
goto out;
5680
}
81+
setup_vmgenid_state(state, virt_addr);
5782

58-
memcpy(state->this_id, state->next_id, sizeof(state->this_id));
59-
add_device_randomness(state->this_id, sizeof(state->this_id));
60-
61-
device->driver_data = state;
83+
status = acpi_install_notify_handler(device->handle, ACPI_DEVICE_NOTIFY,
84+
vmgenid_acpi_handler, dev);
85+
if (ACPI_FAILURE(status)) {
86+
ret = -ENODEV;
87+
goto out;
88+
}
6289

90+
dev->driver_data = state;
6391
out:
6492
ACPI_FREE(parsed.pointer);
6593
return ret;
6694
}
6795

68-
static void vmgenid_notify(struct acpi_device *device, u32 event)
96+
static int vmgenid_add(struct platform_device *pdev)
6997
{
70-
struct vmgenid_state *state = acpi_driver_data(device);
71-
u8 old_id[VMGENID_SIZE];
98+
struct device *dev = &pdev->dev;
99+
struct vmgenid_state *state;
100+
int ret;
72101

73-
memcpy(old_id, state->this_id, sizeof(old_id));
74-
memcpy(state->this_id, state->next_id, sizeof(state->this_id));
75-
if (!memcmp(old_id, state->this_id, sizeof(old_id)))
76-
return;
77-
add_vmfork_randomness(state->this_id, sizeof(state->this_id));
102+
state = devm_kmalloc(dev, sizeof(*state), GFP_KERNEL);
103+
if (!state)
104+
return -ENOMEM;
105+
106+
ret = vmgenid_add_acpi(dev, state);
107+
108+
if (ret < 0)
109+
devm_kfree(dev, state);
110+
return ret;
78111
}
79112

80-
static const struct acpi_device_id vmgenid_ids[] = {
113+
static const struct acpi_device_id vmgenid_acpi_ids[] = {
81114
{ "VMGENCTR", 0 },
82115
{ "VM_GEN_COUNTER", 0 },
83116
{ }
84117
};
85-
86-
static struct acpi_driver vmgenid_driver = {
87-
.name = "vmgenid",
88-
.ids = vmgenid_ids,
89-
.owner = THIS_MODULE,
90-
.ops = {
91-
.add = vmgenid_add,
92-
.notify = vmgenid_notify
93-
}
118+
MODULE_DEVICE_TABLE(acpi, vmgenid_acpi_ids);
119+
120+
static struct platform_driver vmgenid_plaform_driver = {
121+
.probe = vmgenid_add,
122+
.driver = {
123+
.name = "vmgenid",
124+
.acpi_match_table = vmgenid_acpi_ids,
125+
},
94126
};
95127

96-
module_acpi_driver(vmgenid_driver);
128+
module_platform_driver(vmgenid_plaform_driver)
97129

98-
MODULE_DEVICE_TABLE(acpi, vmgenid_ids);
99130
MODULE_DESCRIPTION("Virtual Machine Generation ID");
100131
MODULE_LICENSE("GPL v2");
101132
MODULE_AUTHOR("Jason A. Donenfeld <Jason@zx2c4.com>");

0 commit comments

Comments
 (0)