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
1516ACPI_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 ;
6391out :
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 );
99130MODULE_DESCRIPTION ("Virtual Machine Generation ID" );
100131MODULE_LICENSE ("GPL v2" );
101132MODULE_AUTHOR (
"Jason A. Donenfeld <[email protected] >" );
0 commit comments