Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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>

authored by

Sudan Landge and committed by
Jason A. Donenfeld
e0760671 5eb4573e

+65 -34
+65 -34
drivers/virt/vmgenid.c
··· 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"); ··· 22 21 u8 this_id[VMGENID_SIZE]; 23 22 }; 24 23 25 - static int vmgenid_add(struct acpi_device *device) 24 + static void vmgenid_notify(struct device *device) 26 25 { 26 + struct vmgenid_state *state = device->driver_data; 27 + u8 old_id[VMGENID_SIZE]; 28 + 29 + memcpy(old_id, state->this_id, sizeof(old_id)); 30 + memcpy(state->this_id, state->next_id, sizeof(state->this_id)); 31 + if (!memcmp(old_id, state->this_id, sizeof(old_id))) 32 + return; 33 + add_vmfork_randomness(state->this_id, sizeof(state->this_id)); 34 + } 35 + 36 + static void setup_vmgenid_state(struct vmgenid_state *state, void *virt_addr) 37 + { 38 + state->next_id = virt_addr; 39 + memcpy(state->this_id, state->next_id, sizeof(state->this_id)); 40 + add_device_randomness(state->this_id, sizeof(state->this_id)); 41 + } 42 + 43 + static void vmgenid_acpi_handler(acpi_handle __always_unused handle, 44 + u32 __always_unused event, void *dev) 45 + { 46 + vmgenid_notify(dev); 47 + } 48 + 49 + static int vmgenid_add_acpi(struct device *dev, struct vmgenid_state *state) 50 + { 51 + struct acpi_device *device = ACPI_COMPANION(dev); 27 52 struct acpi_buffer parsed = { ACPI_ALLOCATE_BUFFER }; 28 - struct vmgenid_state *state; 29 53 union acpi_object *obj; 30 54 phys_addr_t phys_addr; 31 55 acpi_status status; 56 + void *virt_addr; 32 57 int ret = 0; 33 - 34 - state = devm_kmalloc(&device->dev, sizeof(*state), GFP_KERNEL); 35 - if (!state) 36 - return -ENOMEM; 37 58 38 59 status = acpi_evaluate_object(device->handle, "ADDR", NULL, &parsed); 39 60 if (ACPI_FAILURE(status)) { ··· 72 49 73 50 phys_addr = (obj->package.elements[0].integer.value << 0) | 74 51 (obj->package.elements[1].integer.value << 32); 75 - state->next_id = devm_memremap(&device->dev, phys_addr, VMGENID_SIZE, MEMREMAP_WB); 76 - if (IS_ERR(state->next_id)) { 77 - ret = PTR_ERR(state->next_id); 52 + 53 + virt_addr = devm_memremap(&device->dev, phys_addr, VMGENID_SIZE, MEMREMAP_WB); 54 + if (IS_ERR(virt_addr)) { 55 + ret = PTR_ERR(virt_addr); 56 + goto out; 57 + } 58 + setup_vmgenid_state(state, virt_addr); 59 + 60 + status = acpi_install_notify_handler(device->handle, ACPI_DEVICE_NOTIFY, 61 + vmgenid_acpi_handler, dev); 62 + if (ACPI_FAILURE(status)) { 63 + ret = -ENODEV; 78 64 goto out; 79 65 } 80 66 81 - memcpy(state->this_id, state->next_id, sizeof(state->this_id)); 82 - add_device_randomness(state->this_id, sizeof(state->this_id)); 83 - 84 - device->driver_data = state; 85 - 67 + dev->driver_data = state; 86 68 out: 87 69 ACPI_FREE(parsed.pointer); 88 70 return ret; 89 71 } 90 72 91 - static void vmgenid_notify(struct acpi_device *device, u32 event) 73 + static int vmgenid_add(struct platform_device *pdev) 92 74 { 93 - struct vmgenid_state *state = acpi_driver_data(device); 94 - u8 old_id[VMGENID_SIZE]; 75 + struct device *dev = &pdev->dev; 76 + struct vmgenid_state *state; 77 + int ret; 95 78 96 - memcpy(old_id, state->this_id, sizeof(old_id)); 97 - memcpy(state->this_id, state->next_id, sizeof(state->this_id)); 98 - if (!memcmp(old_id, state->this_id, sizeof(old_id))) 99 - return; 100 - add_vmfork_randomness(state->this_id, sizeof(state->this_id)); 79 + state = devm_kmalloc(dev, sizeof(*state), GFP_KERNEL); 80 + if (!state) 81 + return -ENOMEM; 82 + 83 + ret = vmgenid_add_acpi(dev, state); 84 + 85 + if (ret < 0) 86 + devm_kfree(dev, state); 87 + return ret; 101 88 } 102 89 103 - static const struct acpi_device_id vmgenid_ids[] = { 90 + static const struct acpi_device_id vmgenid_acpi_ids[] = { 104 91 { "VMGENCTR", 0 }, 105 92 { "VM_GEN_COUNTER", 0 }, 106 93 { } 107 94 }; 95 + MODULE_DEVICE_TABLE(acpi, vmgenid_acpi_ids); 108 96 109 - static struct acpi_driver vmgenid_driver = { 110 - .name = "vmgenid", 111 - .ids = vmgenid_ids, 112 - .owner = THIS_MODULE, 113 - .ops = { 114 - .add = vmgenid_add, 115 - .notify = vmgenid_notify 116 - } 97 + static struct platform_driver vmgenid_plaform_driver = { 98 + .probe = vmgenid_add, 99 + .driver = { 100 + .name = "vmgenid", 101 + .acpi_match_table = vmgenid_acpi_ids, 102 + }, 117 103 }; 118 104 119 - module_acpi_driver(vmgenid_driver); 105 + module_platform_driver(vmgenid_plaform_driver) 120 106 121 - MODULE_DEVICE_TABLE(acpi, vmgenid_ids); 122 107 MODULE_DESCRIPTION("Virtual Machine Generation ID"); 123 108 MODULE_LICENSE("GPL v2"); 124 109 MODULE_AUTHOR("Jason A. Donenfeld <Jason@zx2c4.com>");