7
7
* information to random.c.
8
8
*/
9
9
10
+ #include <linux/acpi.h>
10
11
#include <linux/kernel.h>
11
12
#include <linux/module.h>
12
- #include <linux/acpi .h>
13
+ #include <linux/platform_device .h>
13
14
#include <linux/random.h>
14
15
15
16
ACPI_MODULE_NAME ("vmgenid" );
@@ -21,19 +22,41 @@ struct vmgenid_state {
21
22
u8 this_id [VMGENID_SIZE ];
22
23
};
23
24
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 )
25
38
{
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 );
26
53
struct acpi_buffer parsed = { ACPI_ALLOCATE_BUFFER };
27
- struct vmgenid_state * state ;
28
54
union acpi_object * obj ;
29
55
phys_addr_t phys_addr ;
30
56
acpi_status status ;
57
+ void * virt_addr ;
31
58
int ret = 0 ;
32
59
33
- state = devm_kmalloc (& device -> dev , sizeof (* state ), GFP_KERNEL );
34
- if (!state )
35
- return - ENOMEM ;
36
-
37
60
status = acpi_evaluate_object (device -> handle , "ADDR" , NULL , & parsed );
38
61
if (ACPI_FAILURE (status )) {
39
62
ACPI_EXCEPTION ((AE_INFO , status , "Evaluating ADDR" ));
@@ -49,53 +72,61 @@ static int vmgenid_add(struct acpi_device *device)
49
72
50
73
phys_addr = (obj -> package .elements [0 ].integer .value << 0 ) |
51
74
(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 );
55
79
goto out ;
56
80
}
81
+ setup_vmgenid_state (state , virt_addr );
57
82
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
+ }
62
89
90
+ dev -> driver_data = state ;
63
91
out :
64
92
ACPI_FREE (parsed .pointer );
65
93
return ret ;
66
94
}
67
95
68
- static void vmgenid_notify (struct acpi_device * device , u32 event )
96
+ static int vmgenid_add (struct platform_device * pdev )
69
97
{
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 ;
72
101
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 ;
78
111
}
79
112
80
- static const struct acpi_device_id vmgenid_ids [] = {
113
+ static const struct acpi_device_id vmgenid_acpi_ids [] = {
81
114
{ "VMGENCTR" , 0 },
82
115
{ "VM_GEN_COUNTER" , 0 },
83
116
{ }
84
117
};
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
+ },
94
126
};
95
127
96
- module_acpi_driver ( vmgenid_driver );
128
+ module_platform_driver ( vmgenid_plaform_driver )
97
129
98
- MODULE_DEVICE_TABLE (acpi , vmgenid_ids );
99
130
MODULE_DESCRIPTION ("Virtual Machine Generation ID" );
100
131
MODULE_LICENSE ("GPL v2" );
101
132
MODULE_AUTHOR ("Jason A. Donenfeld <Jason@zx2c4.com>" );
0 commit comments